diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index 47fae75cbb..43f53d1247 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -157,6 +157,7 @@ #include "mem/translating_port_proxy.hh" #include "sim/full_system.hh" #include "sim/process.hh" +#include "sim/sim_events.hh" #include "sim/system.hh" namespace gem5 @@ -241,7 +242,7 @@ hex2c(char c0,char c1) //this function will be used in a future patch //convert a encoded string to a string -[[maybe_unused]] std::string +std::string hexS2string(std::string hex_in) { std::string out=""; @@ -554,7 +555,6 @@ BaseRemoteGDB::trap(ContextID id, GDBSignal sig,const std::string& stopReason) return; if (tc->contextId() != id) { - //prevent thread switch when single stepping if (singleStepEvent.scheduled()){ return; @@ -564,11 +564,14 @@ BaseRemoteGDB::trap(ContextID id, GDBSignal sig,const std::string& stopReason) return; } + DPRINTF(GDBMisc, "trap: PC=%s\n", tc->pcState()); clearSingleStep(); - - if (threadSwitching) { + if (stopReason=="monitor_return"){ + //should wnot send any Tpacket here + send("OK"); + }else if (threadSwitching) { threadSwitching = false; // Tell GDB the thread switch has completed. send("OK"); @@ -1326,6 +1329,7 @@ splitAt(std::string str, const char * const delim) std::map BaseRemoteGDB::queryMap = { { "C", { &BaseRemoteGDB::queryC } }, + { "Rcmd", { &BaseRemoteGDB::queryRcmd} }, { "Attached", { &BaseRemoteGDB::queryAttached} }, { "Supported", { &BaseRemoteGDB::querySupported, ";" } }, { "Xfer", { &BaseRemoteGDB::queryXfer } }, @@ -1416,6 +1420,38 @@ BaseRemoteGDB::queryAttached(QuerySetCommand::Context &ctx) return true; } +class MonitorCallEvent : public GlobalSimLoopExitEvent +{ + BaseRemoteGDB& gdb; + ContextID id; + public: + MonitorCallEvent(BaseRemoteGDB& gdb,ContextID id,const std::string &_cause, + int code): + GlobalSimLoopExitEvent(_cause,code), gdb(gdb),id(id) + {}; + void process() override{ + GlobalSimLoopExitEvent::process(); + } + void clean() override{ + //trapping now + //this is the only point in time when we can call trap + //before any breakpoint triggers + gdb.trap(id,GDBSignal::ZERO,"monitor_return"); + delete this; + } + ~MonitorCallEvent(){ + DPRINTF(Event,"MonitorCallEvent destructed\n");; + } +}; + +bool +BaseRemoteGDB::queryRcmd(QuerySetCommand::Context &ctx){ + std::string message=hexS2string(ctx.args[0]); + DPRINTF(GDBMisc, "Rcmd Query: %s => %s\n", ctx.args[0],message); + //Tick when = curTick(); + new MonitorCallEvent(*this,tc->contextId(),"GDB_MONITOR:"+ message, 0); + return false; +} bool BaseRemoteGDB::queryFThreadInfo(QuerySetCommand::Context &ctx) @@ -1444,7 +1480,7 @@ BaseRemoteGDB::cmdQueryVar(GdbCommand::Context &ctx) { // The query command goes until the first ':', or the end of the string. std::string s(ctx.data, ctx.len); - auto query_split = splitAt({ ctx.data, (size_t)ctx.len }, ":"); + auto query_split = splitAt({ ctx.data, (size_t)ctx.len }, ":,"); const auto &query_str = query_split.first; // Look up the query command, and report if it isn't found. diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh index c23b4ac95e..1c5cd9c7af 100644 --- a/src/base/remote_gdb.hh +++ b/src/base/remote_gdb.hh @@ -433,6 +433,7 @@ class BaseRemoteGDB bool querySupported(QuerySetCommand::Context &ctx); bool queryXfer(QuerySetCommand::Context &ctx); bool querySymbol(QuerySetCommand::Context &ctx); + bool queryRcmd(QuerySetCommand::Context &ctx); bool queryAttached(QuerySetCommand::Context &ctx); size_t threadInfoIdx = 0; diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index a7226ffead..cd5d285f93 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -46,6 +46,7 @@ #include "base/debug.hh" #include "base/flags.hh" +#include "base/trace.hh" #include "base/types.hh" #include "base/uncontended_mutex.hh" #include "debug/Event.hh" diff --git a/src/sim/sim_events.hh b/src/sim/sim_events.hh index 06a8e6548d..a1ffc7b34a 100644 --- a/src/sim/sim_events.hh +++ b/src/sim/sim_events.hh @@ -68,8 +68,11 @@ class GlobalSimLoopExitEvent : public GlobalEvent const std::string getCause() const { return cause; } int getCode() const { return code; } - void process(); // process event - + virtual void process();// process event + virtual void clean(){};//cleaning event + ~GlobalSimLoopExitEvent (){ + DPRINTF(Event,"GlobalSimLoopExitEvent destructed\n"); + }; virtual const char *description() const; }; diff --git a/src/sim/simulate.cc b/src/sim/simulate.cc index c5d07942ef..0c30f10570 100644 --- a/src/sim/simulate.cc +++ b/src/sim/simulate.cc @@ -184,9 +184,12 @@ struct DescheduleDeleter * terminate the loop. Exported to Python. * @return The SimLoopExitEvent that caused the loop to exit. */ +GlobalSimLoopExitEvent *global_exit_event= nullptr; GlobalSimLoopExitEvent * simulate(Tick num_cycles) { + if (global_exit_event)//cleaning last global exit event + global_exit_event->clean(); std::unique_ptr quantum_event; const Tick exit_tick = num_cycles < MaxTick - curTick() ? curTick() + num_cycles : MaxTick; @@ -224,7 +227,7 @@ simulate(Tick num_cycles) BaseGlobalEvent *global_event = local_event->globalEvent(); assert(global_event); - GlobalSimLoopExitEvent *global_exit_event = + global_exit_event = dynamic_cast(global_event); assert(global_exit_event);