From ea74b568883eb4e995c547fbc7a3ceadaa090554 Mon Sep 17 00:00:00 2001 From: David Donofrio Date: Thu, 7 Dec 2023 23:44:47 -0800 Subject: [PATCH 1/5] first prototype rdb --- build/.gitignore | 1 - include/RDB.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ include/RevCPU.h | 4 ++++ include/RevProc.h | 3 +++ src/CMakeLists.txt | 1 + src/RDB.cc | 34 ++++++++++++++++++++++++++++++++++ src/RevCPU.cc | 25 ++++++++++++++++++++++++- 7 files changed, 110 insertions(+), 2 deletions(-) delete mode 100644 build/.gitignore create mode 100644 include/RDB.h create mode 100644 src/RDB.cc diff --git a/build/.gitignore b/build/.gitignore deleted file mode 100644 index 72e8ffc0d..000000000 --- a/build/.gitignore +++ /dev/null @@ -1 +0,0 @@ -* diff --git a/include/RDB.h b/include/RDB.h new file mode 100644 index 000000000..a2244a5ae --- /dev/null +++ b/include/RDB.h @@ -0,0 +1,44 @@ +// +// _RDB_h_ +// +// Copyright (C) 2017-2023 Tactical Computing Laboratories, LLC +// All Rights Reserved +// contact@tactcomplabs.com +// +// See LICENSE in the top level directory for licensing details +// + +#ifndef __REV_RDB_H__ +#define __REV_RDB_H__ + +#include + +// -- SST Headers +#include "SST.h" + +//Rev Headers +#include "RevProc.h" + +namespace SST::RevCPU{ +class RevProc; + +class RDB { + public: + RDB(SST::Cycle_t firstBreak); + ~RDB(); + + void GetCommand(); + SST::Cycle_t GetNextBreakpoint(){return breakCycle;}; + void SetNextBreakpoint(SST::Cycle_t breakCycle){ breakCycle = breakCycle;} + + void SetProcToDebug(RevProc* proc){proc = proc;}; + + protected: + SST::Cycle_t breakCycle; + RevProc* proc; +}; + +}; + + +#endif \ No newline at end of file diff --git a/include/RevCPU.h b/include/RevCPU.h index 9227af63d..e58f25a92 100644 --- a/include/RevCPU.h +++ b/include/RevCPU.h @@ -39,6 +39,7 @@ #include "RevNIC.h" #include "RevCoProc.h" #include "RevRand.h" +#include "RDB.h" namespace SST::RevCPU{ @@ -112,6 +113,7 @@ class RevCPU : public SST::Component{ {"trcStartCycle", "Starting tracer cycle (disables trcOp)", "0"}, {"splash", "Display the splash logo", "0"}, {"independentCoprocClock", "Enables each coprocessor to register its own clock handler", "0"}, + {"breakAtCycle", "Break execution and drop into debugger at cycle", "0"}, ) // ------------------------------------------------------- @@ -210,6 +212,7 @@ class RevCPU : public SST::Component{ unsigned RDMAPerCycle; ///< RevCPU: number of RDMA messages per cycle to inject into PAN network unsigned testStage; ///< RevCPU: controls the PAN Test harness staging unsigned testIters; ///< RevCPU: the number of message iters for each PAN Test + SST::Cycle_t breakAtCycle; ///< RevCPU: The clock cycle to drop into the debugger - RDB std::string Exe; ///< RevCPU: binary executable std::string Args; ///< RevCPU: argument list RevOpts *Opts; ///< RevCPU: Simulation options object @@ -292,6 +295,7 @@ class RevCPU : public SST::Component{ std::vector CoProcs; ///< RevCPU: CoProcessor attached to Rev SST::Clock::Handler* ClockHandler; ///< RevCPU: Clock Handler + RDB rdb; std::queue> ZeroRqst; ///< RevCPU: tracks incoming zero address put requests; pair std::list> TrackTags; ///< RevCPU: tracks the outgoing messages; pair diff --git a/include/RevProc.h b/include/RevProc.h index 9414ff51e..ebdbe71d1 100644 --- a/include/RevProc.h +++ b/include/RevProc.h @@ -50,6 +50,7 @@ #include "RevRand.h" #include "RevProcPasskey.h" #include "RevHart.h" +#include "RDB.h" #define SYSCALL_TYPES_ONLY #include "../common/syscalls/syscalls.h" #include "../common/include/RevCommon.h" @@ -66,6 +67,8 @@ class RevProc{ /// RevProc: standard destructor ~RevProc() = default; + friend class RDB; + /// RevProc: per-processor clock function bool ClockTick( SST::Cycle_t currentCycle ); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4fd889cce..d3857d7a1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,6 +22,7 @@ set(RevCPUSrcs RevCoProc.cc RevRegFile.cc RevThread.cc + RDB.cc ) add_subdirectory(../common common) diff --git a/src/RDB.cc b/src/RDB.cc new file mode 100644 index 000000000..49c9c0f4b --- /dev/null +++ b/src/RDB.cc @@ -0,0 +1,34 @@ + +// +// _RDB_cc_ +// +// Copyright (C) 2017-2023 Tactical Computing Laboratories, LLC +// All Rights Reserved +// contact@tactcomplabs.com +// +// See LICENSE in the top level directory for licensing details +// + +#include "RDB.h" + + +namespace SST::RevCPU{ +RDB::RDB(SST::Cycle_t firstBreak): + breakCycle(firstBreak) { + + proc = nullptr; + +} + +RDB::~RDB(){ + +} + +void RDB::GetCommand(){ + + std::cout << "Core 0 PC: " << "rdb% "; + std::cin >> breakCycle; + +} + +} \ No newline at end of file diff --git a/src/RevCPU.cc b/src/RevCPU.cc index 47b73f027..5ff68b16f 100644 --- a/src/RevCPU.cc +++ b/src/RevCPU.cc @@ -33,7 +33,7 @@ const char splash_msg[] = "\ RevCPU::RevCPU( SST::ComponentId_t id, const SST::Params& params ) : SST::Component(id), testStage(0), PrivTag(0), address(-1), EnableMemH(false), - DisableCoprocClock(false), Nic(nullptr), Ctrl(nullptr), ClockHandler(nullptr) { + DisableCoprocClock(false), Nic(nullptr), Ctrl(nullptr), ClockHandler(nullptr), rdb(0){ const int Verbosity = params.find("verbose", 0); @@ -169,6 +169,10 @@ RevCPU::RevCPU( SST::ComponentId_t id, const SST::Params& params ) const uint64_t maxHeapSize = params.find("maxHeapSize", memSize/4); Mem->SetMaxHeapSize(maxHeapSize); + // Set Breakpoint + breakAtCycle = params.find("breakAtCycle", 0); + rdb.SetNextBreakpoint(breakAtCycle); + // Load the binary into memory // TODO: Use std::nothrow to return null instead of throwing std::bad_alloc Loader = new RevLoader( Exe, Args, Mem, &output ); @@ -589,9 +593,28 @@ bool RevCPU::clockTick( SST::Cycle_t currentCycle ){ output.verbose(CALL_INFO, 8, 0, "Cycle: %" PRIu64 "\n", currentCycle); + //RDB Control + bool dbgBreak = false; + bool singleStep = false; + + if(breakAtCycle && (breakAtCycle == currentCycle)){ + dbgBreak = true; + output.verbose(CALL_INFO, 1, 0, "Breakpoint found at Cycle: %" PRIu64 "\n", currentCycle); + } + // Execute each enabled core for( size_t i=0; iDebugReadReg(10, &r); + std::cout << "Proc x10 =" << std::hex << r << std::dec << std::endl; + rdb.GetCommand(); + breakAtCycle = rdb.GetNextBreakpoint(); + continue; + } UpdateThreadAssignments(i); if( Enabled[i] ){ if( !Procs[i]->ClockTick(currentCycle) ){ From a0a198d1c5d5ad8a39fb75337a0882a218461009 Mon Sep 17 00:00:00 2001 From: David Donofrio Date: Fri, 8 Dec 2023 14:29:08 -0800 Subject: [PATCH 2/5] basic dbg commands work --- include/RDB.h | 12 ++++++-- include/RevProc.h | 4 +-- src/RDB.cc | 78 +++++++++++++++++++++++++++++++++++++++-------- src/RevCPU.cc | 6 +--- src/RevProc.cc | 6 ++-- 5 files changed, 81 insertions(+), 25 deletions(-) diff --git a/include/RDB.h b/include/RDB.h index a2244a5ae..c68f5ed27 100644 --- a/include/RDB.h +++ b/include/RDB.h @@ -27,15 +27,21 @@ class RDB { RDB(SST::Cycle_t firstBreak); ~RDB(); - void GetCommand(); + bool GetCommand(); SST::Cycle_t GetNextBreakpoint(){return breakCycle;}; - void SetNextBreakpoint(SST::Cycle_t breakCycle){ breakCycle = breakCycle;} + void SetNextBreakpoint(SST::Cycle_t cycle){ breakCycle = cycle;} - void SetProcToDebug(RevProc* proc){proc = proc;}; + void SetProcToDebug(RevProc* p){proc = p;}; protected: SST::Cycle_t breakCycle; RevProc* proc; + std::vector cmdLine; + + void PrintRegister(); + void Step(); + void PrintHelp(); + }; }; diff --git a/include/RevProc.h b/include/RevProc.h index ebdbe71d1..7967c4ddf 100644 --- a/include/RevProc.h +++ b/include/RevProc.h @@ -85,13 +85,13 @@ class RevProc{ bool SingleStepHart(); /// RevProc: retrieve the local PC for the correct feature set - uint64_t GetPC() const { return RegFile->GetPC(); } + uint64_t GetPC() const { return RegFile ? RegFile->GetPC() : 0; } /// RevProc: set time converter for RTC void SetTimeConverter(TimeConverter* tc) { timeConverter = tc; } /// RevProc: Debug mode read a register - bool DebugReadReg(unsigned Idx, uint64_t *Value) const; + bool DebugReadReg(unsigned Idx, uint64_t *Value, unsigned hartID) const; /// RevProc: Debug mode write a register bool DebugWriteReg(unsigned Idx, uint64_t Value) const; diff --git a/src/RDB.cc b/src/RDB.cc index 49c9c0f4b..dcb3e95d3 100644 --- a/src/RDB.cc +++ b/src/RDB.cc @@ -13,22 +13,76 @@ namespace SST::RevCPU{ -RDB::RDB(SST::Cycle_t firstBreak): - breakCycle(firstBreak) { + RDB::RDB(SST::Cycle_t firstBreak): + breakCycle(firstBreak), cmdLine() { - proc = nullptr; - -} + proc = nullptr; + cmdLine.clear(); + + } -RDB::~RDB(){ + RDB::~RDB(){ -} + } -void RDB::GetCommand(){ + void RDB::PrintHelp(){ + std::cout << "Supported commands:" << std::endl; + std::cout << "\treg //Print Register value" << std::endl; + std::cout << "\ts //Step forward num cycles - default is one cycle" << std::endl; + } - std::cout << "Core 0 PC: " << "rdb% "; - std::cin >> breakCycle; + bool RDB::GetCommand(){ -} + //Supported commands: + // reg //Print Register value + // s //Step forward num cycles - default is one cycle -} \ No newline at end of file + std::string input; + std::stringstream line; + std::string field; + bool rtn = true; + std::cout << "Core " << proc->id << " PC: " << std::hex << proc->GetPC() << std::dec << " rdb% "; + std::getline(std::cin, input); + line.str(input); + for(field; std::getline(line, field, ' ');){ + cmdLine.push_back(field); + } + + if(cmdLine[0] == "reg"){ + PrintRegister(); + rtn = true; + }else if(cmdLine[0] == "s"){ + Step(); + rtn = false; + }else{ + std::cout << "INVALID COMMAND" << std::endl; + PrintHelp(); + rtn = true; + } + + cmdLine.clear(); + return rtn; + } + + void RDB::Step(){ + int stepCount = 1; + if(cmdLine.size() > 1){ + stepCount = std::stoi(cmdLine[1]); + } + breakCycle += stepCount; + } + + void RDB::PrintRegister(){ + uint64_t val = 0; + int reg = std::stoi(cmdLine[2]); + int hart = std::stoi(cmdLine[1]); + if(reg < _REV_NUM_REGS_){ + proc->DebugReadReg(reg, &val, hart); + std::cout << "Core " << proc->id << ":" << hart << " x" << reg << " = " << std::hex << val << std::dec << std::endl; + }else{ + std::cout << "Core " << proc->id << " x" << reg << " is out of range" << std::endl; + if(proc->RegFile) {std::cout << *(proc->RegFile);} + } + } + +} //namespace diff --git a/src/RevCPU.cc b/src/RevCPU.cc index 5ff68b16f..1dcc86c71 100644 --- a/src/RevCPU.cc +++ b/src/RevCPU.cc @@ -608,12 +608,8 @@ bool RevCPU::clockTick( SST::Cycle_t currentCycle ){ if(dbgBreak || singleStep){ RevProc* p = Procs[i]; rdb.SetProcToDebug(p); - uint64_t r; - p->DebugReadReg(10, &r); - std::cout << "Proc x10 =" << std::hex << r << std::dec << std::endl; - rdb.GetCommand(); + while(rdb.GetCommand()){}; breakAtCycle = rdb.GetNextBreakpoint(); - continue; } UpdateThreadAssignments(i); if( Enabled[i] ){ diff --git a/src/RevProc.cc b/src/RevProc.cc index 9186d2f27..36c3d6ba5 100644 --- a/src/RevProc.cc +++ b/src/RevProc.cc @@ -1270,13 +1270,13 @@ RevInst RevProc::DecodeR4Inst(uint32_t Inst, unsigned Entry) const { return DInst; } -bool RevProc::DebugReadReg(unsigned Idx, uint64_t *Value) const { +bool RevProc::DebugReadReg(unsigned Idx, uint64_t *Value, unsigned hartID) const { if( !Halted ) return false; - if( Idx >= _REV_NUM_REGS_ ){ + if( (Idx >= _REV_NUM_REGS_) || (hartID > Harts.size() ) ){ return false; } - RevRegFile* regFile = GetRegFile(HartToExecID); + RevRegFile* regFile = GetRegFile(hartID); *Value = regFile->GetX(Idx); return true; } From aeeab27b19dfc5e461e67ce171b1220c295dba4e Mon Sep 17 00:00:00 2001 From: David Donofrio Date: Fri, 8 Dec 2023 16:05:55 -0800 Subject: [PATCH 3/5] initial commands complete --- include/RDB.h | 3 +++ include/RevProc.h | 3 +++ src/RDB.cc | 28 ++++++++++++++++++++-------- src/RevCPU.cc | 12 +++++++++--- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/include/RDB.h b/include/RDB.h index c68f5ed27..698e82fe7 100644 --- a/include/RDB.h +++ b/include/RDB.h @@ -29,18 +29,21 @@ class RDB { bool GetCommand(); SST::Cycle_t GetNextBreakpoint(){return breakCycle;}; + uint64_t GetPCBreakpoint(){return breakPC;} void SetNextBreakpoint(SST::Cycle_t cycle){ breakCycle = cycle;} void SetProcToDebug(RevProc* p){proc = p;}; protected: SST::Cycle_t breakCycle; + uint64_t breakPC; RevProc* proc; std::vector cmdLine; void PrintRegister(); void Step(); void PrintHelp(); + void PC(); }; diff --git a/include/RevProc.h b/include/RevProc.h index 7967c4ddf..e0e42a96b 100644 --- a/include/RevProc.h +++ b/include/RevProc.h @@ -87,6 +87,9 @@ class RevProc{ /// RevProc: retrieve the local PC for the correct feature set uint64_t GetPC() const { return RegFile ? RegFile->GetPC() : 0; } + /// RevProc: retrieve the local PC for the correct feature set + uint64_t GetPC(unsigned hartID) const { return IdleHarts[hartID] ? 0 : Harts[hartID]->RegFile->GetPC(); } + /// RevProc: set time converter for RTC void SetTimeConverter(TimeConverter* tc) { timeConverter = tc; } diff --git a/src/RDB.cc b/src/RDB.cc index dcb3e95d3..96e443cad 100644 --- a/src/RDB.cc +++ b/src/RDB.cc @@ -14,11 +14,9 @@ namespace SST::RevCPU{ RDB::RDB(SST::Cycle_t firstBreak): - breakCycle(firstBreak), cmdLine() { + breakCycle(firstBreak), breakPC(0), proc(nullptr), cmdLine() { - proc = nullptr; cmdLine.clear(); - } RDB::~RDB(){ @@ -27,16 +25,20 @@ namespace SST::RevCPU{ void RDB::PrintHelp(){ std::cout << "Supported commands:" << std::endl; - std::cout << "\treg //Print Register value" << std::endl; - std::cout << "\ts //Step forward num cycles - default is one cycle" << std::endl; + std::cout << "\treg // Print Register value. num >= 32 will print all regs" << std::endl; + std::cout << "\ts // Step forward num cycles - default is one cycle" << std::endl; + std::cout << "\tpc // Execute until hart reaches pc == num" << std::endl; + std::cout << "\tc // Continue (exit debugger)" << std::endl; } bool RDB::GetCommand(){ //Supported commands: - // reg //Print Register value - // s //Step forward num cycles - default is one cycle - + // reg // Print Register value + // s // Step forward num cycles - default is one cycle + // pc // Execute until hart reaches pc == num. num must be in hex + // c // Continue (exit debugger) + std::string input; std::stringstream line; std::string field; @@ -54,6 +56,12 @@ namespace SST::RevCPU{ }else if(cmdLine[0] == "s"){ Step(); rtn = false; + }else if(cmdLine[0] == "pc"){ + PC(); + rtn = true; + }else if(cmdLine[0] == "c"){ + breakCycle = 0; + rtn = false; }else{ std::cout << "INVALID COMMAND" << std::endl; PrintHelp(); @@ -85,4 +93,8 @@ namespace SST::RevCPU{ } } + void RDB::PC(){ + breakPC = std::stoi(cmdLine[2], nullptr, 16); + } + } //namespace diff --git a/src/RevCPU.cc b/src/RevCPU.cc index 1dcc86c71..ffa560dab 100644 --- a/src/RevCPU.cc +++ b/src/RevCPU.cc @@ -595,9 +595,8 @@ bool RevCPU::clockTick( SST::Cycle_t currentCycle ){ //RDB Control bool dbgBreak = false; - bool singleStep = false; - if(breakAtCycle && (breakAtCycle == currentCycle)){ + if(currentCycle && (rdb.GetNextBreakpoint() == currentCycle)){ dbgBreak = true; output.verbose(CALL_INFO, 1, 0, "Breakpoint found at Cycle: %" PRIu64 "\n", currentCycle); } @@ -605,12 +604,19 @@ bool RevCPU::clockTick( SST::Cycle_t currentCycle ){ // Execute each enabled core for( size_t i=0; iGetPC(0) && (Procs[i]->GetPC(0) == rdb.GetPCBreakpoint())){ + output.verbose(CALL_INFO, 1, 0, "Breakpoint found at PC: %" PRIx64 "\n", Procs[i]->GetPC(0)); + rdb.SetProcToDebug(Procs[i]); + while(rdb.GetCommand()){}; + breakAtCycle = rdb.GetNextBreakpoint(); + } UpdateThreadAssignments(i); if( Enabled[i] ){ if( !Procs[i]->ClockTick(currentCycle) ){ From f504e258b8f0059679a14cc0b16f5bd9dcae47cd Mon Sep 17 00:00:00 2001 From: David Donofrio Date: Fri, 8 Dec 2023 16:07:25 -0800 Subject: [PATCH 4/5] Adding config --- test/rev-model-options-config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/rev-model-options-config.py b/test/rev-model-options-config.py index 7d51be4ef..42419062d 100644 --- a/test/rev-model-options-config.py +++ b/test/rev-model-options-config.py @@ -56,6 +56,7 @@ "startSymbol" : args.startSymbol, "enable_memH" : args.enableMemH, "args": args.args, + "breakAtCycle" : 13, "splash" : 1 }) From 77602e46c1604f076de34b8c83bd73b358e57ffc Mon Sep 17 00:00:00 2001 From: David Donofrio Date: Fri, 8 Dec 2023 16:21:56 -0800 Subject: [PATCH 5/5] code tweak --- include/RDB.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/RDB.h b/include/RDB.h index 698e82fe7..33b8e0e3b 100644 --- a/include/RDB.h +++ b/include/RDB.h @@ -28,8 +28,8 @@ class RDB { ~RDB(); bool GetCommand(); - SST::Cycle_t GetNextBreakpoint(){return breakCycle;}; - uint64_t GetPCBreakpoint(){return breakPC;} + SST::Cycle_t GetNextBreakpoint() const {return breakCycle;}; + uint64_t GetPCBreakpoint() const {return breakPC;} void SetNextBreakpoint(SST::Cycle_t cycle){ breakCycle = cycle;} void SetProcToDebug(RevProc* p){proc = p;};