Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion build/.gitignore

This file was deleted.

53 changes: 53 additions & 0 deletions include/RDB.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//
// _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 <iostream>

// -- SST Headers
#include "SST.h"

//Rev Headers
#include "RevProc.h"

namespace SST::RevCPU{
class RevProc;

class RDB {
public:
RDB(SST::Cycle_t firstBreak);
~RDB();

bool GetCommand();
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;};

protected:
SST::Cycle_t breakCycle;
uint64_t breakPC;
RevProc* proc;
std::vector<std::string> cmdLine;

void PrintRegister();
void Step();
void PrintHelp();
void PC();

};

};


#endif
4 changes: 4 additions & 0 deletions include/RevCPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "RevNIC.h"
#include "RevCoProc.h"
#include "RevRand.h"
#include "RDB.h"

namespace SST::RevCPU{

Expand Down Expand Up @@ -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"},
)

// -------------------------------------------------------
Expand Down Expand Up @@ -212,6 +214,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
Expand Down Expand Up @@ -294,6 +297,7 @@ class RevCPU : public SST::Component{
std::vector<RevCoProc*> CoProcs; ///< RevCPU: CoProcessor attached to Rev

SST::Clock::Handler<RevCPU>* ClockHandler; ///< RevCPU: Clock Handler
RDB rdb;

std::queue<std::pair<uint32_t, char *>> ZeroRqst; ///< RevCPU: tracks incoming zero address put requests; pair<Size, Data>
std::list<std::pair<uint8_t, int>> TrackTags; ///< RevCPU: tracks the outgoing messages; pair<Tag, Dest>
Expand Down
10 changes: 8 additions & 2 deletions include/RevProc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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 );

Expand All @@ -82,13 +85,16 @@ 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: 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; }

/// 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;
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ set(RevCPUSrcs
RevCoProc.cc
RevRegFile.cc
RevThread.cc
RDB.cc
)

add_subdirectory(../common common)
Expand Down
100 changes: 100 additions & 0 deletions src/RDB.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@

//
// _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), breakPC(0), proc(nullptr), cmdLine() {

cmdLine.clear();
}

RDB::~RDB(){

}

void RDB::PrintHelp(){
std::cout << "Supported commands:" << std::endl;
std::cout << "\treg <hart> <num> // Print Register value. num >= 32 will print all regs" << std::endl;
std::cout << "\ts <num> // Step forward num cycles - default is one cycle" << std::endl;
std::cout << "\tpc <hart> <num> // Execute until hart reaches pc == num" << std::endl;
std::cout << "\tc // Continue (exit debugger)" << std::endl;
}

bool RDB::GetCommand(){

//Supported commands:
// reg <hart> <num> // Print Register value
// s <num> // Step forward num cycles - default is one cycle
// pc <hart> <num> // Execute until hart reaches pc == num. num must be in hex
// c // Continue (exit debugger)

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 if(cmdLine[0] == "pc"){
PC();
rtn = true;
}else if(cmdLine[0] == "c"){
breakCycle = 0;
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);}
}
}

void RDB::PC(){
breakPC = std::stoi(cmdLine[2], nullptr, 16);
}

} //namespace
27 changes: 26 additions & 1 deletion src/RevCPU.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<int>("verbose", 0);

Expand Down Expand Up @@ -169,6 +169,10 @@ RevCPU::RevCPU( SST::ComponentId_t id, const SST::Params& params )
const uint64_t maxHeapSize = params.find<unsigned long>("maxHeapSize", memSize/4);
Mem->SetMaxHeapSize(maxHeapSize);

// Set Breakpoint
breakAtCycle = params.find<SST::Cycle_t>("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 );
Expand Down Expand Up @@ -586,9 +590,30 @@ bool RevCPU::clockTick( SST::Cycle_t currentCycle ){

output.verbose(CALL_INFO, 8, 0, "Cycle: %" PRIu64 "\n", currentCycle);

//RDB Control
bool dbgBreak = false;

if(currentCycle && (rdb.GetNextBreakpoint() == 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; i<Procs.size(); i++ ){
// Check if we have more work to assign and places to put it
if(dbgBreak){
RevProc* p = Procs[i];
rdb.SetProcToDebug(p);
while(rdb.GetCommand()){};
breakAtCycle = rdb.GetNextBreakpoint();
}

if(Procs[i]->GetPC(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) ){
Expand Down
6 changes: 3 additions & 3 deletions src/RevProc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint64_t>(Idx);
return true;
}
Expand Down
1 change: 1 addition & 0 deletions test/rev-model-options-config.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"startSymbol" : args.startSymbol,
"enable_memH" : args.enableMemH,
"args": args.args,
"breakAtCycle" : 13,
"splash" : 1
})

Expand Down