Alec Roelke has uploaded this change for review. ( https://gem5-review.googlesource.com/2302

Change subject: riscv: Add support for remote debugging via gdb
......................................................................

riscv: Add support for remote debugging via gdb

This patch adds support for remote debugging via GDB to RISC-V.  GDB is
included along with the rest of the RISC-V GCC toolchain found at
http://github.com/ucb-bar/riscv-tools.  Currently only the Newlib
toolchain (riscv64-unknown-elf-*) is supported.

Change-Id: I16b9951bcd90ffdcdd3f237803ae76b1f9cd63bc
---
M src/arch/riscv/isa.cc
M src/arch/riscv/isa.hh
M src/arch/riscv/registers.hh
M src/arch/riscv/remote_gdb.cc
M src/arch/riscv/remote_gdb.hh
5 files changed, 195 insertions(+), 115 deletions(-)



diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc
index c9505f5..d99954b 100644
--- a/src/arch/riscv/isa.cc
+++ b/src/arch/riscv/isa.cc
@@ -32,6 +32,7 @@

 #include <ctime>
 #include <set>
+#include <sstream>

 #include "arch/riscv/registers.hh"
 #include "base/bitfield.hh"
@@ -44,79 +45,114 @@
 namespace RiscvISA
 {

-std::map<int, std::string> ISA::miscRegNames = {
-    {MISCREG_FFLAGS, "fflags"},
-    {MISCREG_FRM, "frm"},
-    {MISCREG_FCSR, "fcsr"},
-    {MISCREG_CYCLE, "cycle"},
-    {MISCREG_TIME, "time"},
-    {MISCREG_INSTRET, "instret"},
-    {MISCREG_CYCLEH, "cycleh"},
-    {MISCREG_TIMEH, "timeh"},
-    {MISCREG_INSTRETH, "instreth"},
-
-    {MISCREG_SSTATUS, "sstatus"},
-    {MISCREG_STVEC, "stvec"},
-    {MISCREG_SIE, "sie"},
-    {MISCREG_STIMECMP, "stimecmp"},
-    {MISCREG_STIME, "stime"},
-    {MISCREG_STIMEH, "stimeh"},
-    {MISCREG_SSCRATCH, "sscratch"},
-    {MISCREG_SEPC, "sepc"},
-    {MISCREG_SCAUSE, "scause"},
-    {MISCREG_SBADADDR, "sbadaddr"},
-    {MISCREG_SIP, "sip"},
-    {MISCREG_SPTBR, "sptbr"},
-    {MISCREG_SASID, "sasid"},
-    {MISCREG_CYCLEW, "cyclew"},
-    {MISCREG_TIMEW, "timew"},
-    {MISCREG_INSTRETW, "instretw"},
-    {MISCREG_CYCLEHW, "cyclehw"},
-    {MISCREG_TIMEHW, "timehw"},
-    {MISCREG_INSTRETHW, "instrethw"},
-
-    {MISCREG_HSTATUS, "hstatus"},
-    {MISCREG_HTVEC, "htvec"},
-    {MISCREG_HTDELEG, "htdeleg"},
-    {MISCREG_HTIMECMP, "htimecmp"},
-    {MISCREG_HTIME, "htime"},
-    {MISCREG_HTIMEH, "htimeh"},
-    {MISCREG_HSCRATCH, "hscratch"},
-    {MISCREG_HEPC, "hepc"},
-    {MISCREG_HCAUSE, "hcause"},
-    {MISCREG_HBADADDR, "hbadaddr"},
-    {MISCREG_STIMEW, "stimew"},
-    {MISCREG_STIMEHW, "stimehw"},
-
-    {MISCREG_MCPUID, "mcpuid"},
-    {MISCREG_MIMPID, "mimpid"},
-    {MISCREG_MHARTID, "mhartid"},
-    {MISCREG_MSTATUS, "mstatus"},
-    {MISCREG_MTVEC, "mtvec"},
-    {MISCREG_MTDELEG, "mtdeleg"},
-    {MISCREG_MIE, "mie"},
-    {MISCREG_MTIMECMP, "mtimecmp"},
-    {MISCREG_MTIME, "mtime"},
-    {MISCREG_MTIMEH, "mtimeh"},
-    {MISCREG_MSCRATCH, "mscratch"},
-    {MISCREG_MEPC, "mepc"},
-    {MISCREG_MCAUSE, "mcause"},
-    {MISCREG_MBADADDR, "mbadaddr"},
-    {MISCREG_MIP, "mip"},
-    {MISCREG_MBASE, "mbase"},
-    {MISCREG_MBOUND, "mbound"},
-    {MISCREG_MIBASE, "mibase"},
-    {MISCREG_MIBOUND, "mibound"},
-    {MISCREG_MDBASE, "mdbase"},
-    {MISCREG_MDBOUND, "mdbound"},
-    {MISCREG_HTIMEW, "htimew"},
-    {MISCREG_HTIMEHW, "htimehw"},
-    {MISCREG_MTOHOST, "mtohost"},
-    {MISCREG_MFROMHOST, "mfromhost"}
-};
-
 ISA::ISA(Params *p) : SimObject(p)
 {
+    miscRegNames = {
+        {MISCREG_USTATUS, "ustatus"},
+        {MISCREG_UIE, "uie"},
+        {MISCREG_UTVEC, "utvec"},
+        {MISCREG_USCRATCH, "uscratch"},
+        {MISCREG_UEPC, "uepc"},
+        {MISCREG_UCAUSE, "ucause"},
+        {MISCREG_UBADADDR, "ubadaddr"},
+        {MISCREG_UIP, "uip"},
+        {MISCREG_FFLAGS, "fflags"},
+        {MISCREG_FRM, "frm"},
+        {MISCREG_FCSR, "fcsr"},
+        {MISCREG_CYCLE, "cycle"},
+        {MISCREG_TIME, "time"},
+        {MISCREG_INSTRET, "instret"},
+        {MISCREG_CYCLEH, "cycleh"},
+        {MISCREG_TIMEH, "timeh"},
+        {MISCREG_INSTRETH, "instreth"},
+
+        {MISCREG_SSTATUS, "sstatus"},
+        {MISCREG_SEDELEG, "sedeleg"},
+        {MISCREG_SIDELEG, "sideleg"},
+        {MISCREG_SIE, "sie"},
+        {MISCREG_STVEC, "stvec"},
+        {MISCREG_SSCRATCH, "sscratch"},
+        {MISCREG_SEPC, "sepc"},
+        {MISCREG_SCAUSE, "scause"},
+        {MISCREG_SBADADDR, "sbadaddr"},
+        {MISCREG_SIP, "sip"},
+        {MISCREG_SPTBR, "sptbr"},
+
+        {MISCREG_HSTATUS, "hstatus"},
+        {MISCREG_HEDELEG, "hedeleg"},
+        {MISCREG_HIDELEG, "hideleg"},
+        {MISCREG_HIE, "hie"},
+        {MISCREG_HTVEC, "htvec"},
+        {MISCREG_HSCRATCH, "hscratch"},
+        {MISCREG_HEPC, "hepc"},
+        {MISCREG_HCAUSE, "hcause"},
+        {MISCREG_HBADADDR, "hbadaddr"},
+        {MISCREG_HIP, "hip"},
+
+        {MISCREG_MVENDORID, "mvendorid"},
+        {MISCREG_MARCHID, "marchid"},
+        {MISCREG_MIMPID, "mimpid"},
+        {MISCREG_MHARTID, "mhartid"},
+        {MISCREG_MSTATUS, "mstatus"},
+        {MISCREG_MISA, "misa"},
+        {MISCREG_MEDELEG, "medeleg"},
+        {MISCREG_MIDELEG, "mideleg"},
+        {MISCREG_MIE, "mie"},
+        {MISCREG_MTVEC, "mtvec"},
+        {MISCREG_MSCRATCH, "mscratch"},
+        {MISCREG_MEPC, "mepc"},
+        {MISCREG_MCAUSE, "mcause"},
+        {MISCREG_MBADADDR, "mbadaddr"},
+        {MISCREG_MIP, "mip"},
+        {MISCREG_MBASE, "mbase"},
+        {MISCREG_MBOUND, "mbound"},
+        {MISCREG_MIBASE, "mibase"},
+        {MISCREG_MIBOUND, "mibound"},
+        {MISCREG_MDBASE, "mdbase"},
+        {MISCREG_MDBOUND, "mdbound"},
+        {MISCREG_MCYCLE, "mcycle"},
+        {MISCREG_MINSTRET, "minstret"},
+        {MISCREG_MUCOUNTEREN, "mucounteren"},
+        {MISCREG_MSCOUNTEREN, "mscounteren"},
+        {MISCREG_MHCOUNTEREN, "mhcounteren"},
+
+        {MISCREG_TSELECT, "tselect"},
+        {MISCREG_TDATA1, "tdata1"},
+        {MISCREG_TDATA2, "tdata2"},
+        {MISCREG_TDATA3, "tdata3"},
+        {MISCREG_DCSR, "dcsr"},
+        {MISCREG_DPC, "dpc"},
+        {MISCREG_DSCRATCH, "dscratch"}
+    };
+    for (int i = 0; i < NumHpmcounter; i++)
+    {
+        int hpmcounter = MISCREG_HPMCOUNTER_BASE + i;
+        std::stringstream ss;
+        ss << "hpmcounter" << hpmcounter;
+        miscRegNames[hpmcounter] = ss.str();
+    }
+    for (int i = 0; i < NumHpmcounterh; i++)
+    {
+        int hpmcounterh = MISCREG_HPMCOUNTERH_BASE + i;
+        std::stringstream ss;
+        ss << "hpmcounterh" << hpmcounterh;
+        miscRegNames[hpmcounterh] = ss.str();
+    }
+    for (int i = 0; i < NumMhpmcounter; i++)
+    {
+        int mhpmcounter = MISCREG_MHPMCOUNTER_BASE + i;
+        std::stringstream ss;
+        ss << "mhpmcounter" << mhpmcounter;
+        miscRegNames[mhpmcounter] = ss.str();
+    }
+    for (int i = 0; i < NumMhpmevent; i++)
+    {
+        int mhpmevent = MISCREG_MHPMEVENT_BASE + i;
+        std::stringstream ss;
+        ss << "mhpmcounterh" << mhpmevent;
+        miscRegNames[mhpmevent] = ss.str();
+    }
+
     miscRegFile.resize(NumMiscRegs);
     clear();
 }
@@ -130,14 +166,19 @@
 void ISA::clear()
 {
     std::fill(miscRegFile.begin(), miscRegFile.end(), 0);
+
+    miscRegFile[MISCREG_MVENDORID] = 0;
+    miscRegFile[MISCREG_MARCHID] = 0;
+    miscRegFile[MISCREG_MIMPID] = 0;
+    miscRegFile[MISCREG_MISA] = 0x8000000000101129ULL;
 }


 MiscReg
 ISA::readMiscRegNoEffect(int misc_reg) const
 {
- DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n", miscRegNames[misc_reg],
-        miscRegFile[misc_reg]);
+    DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n",
+        miscRegNames.at(misc_reg), miscRegFile[misc_reg]);
     switch (misc_reg) {
       case MISCREG_FFLAGS:
         return bits(miscRegFile[MISCREG_FCSR], 4, 0);
@@ -160,6 +201,9 @@
         return std::time(nullptr) >> 32;
       case MISCREG_INSTRETH:
         warn("Use readMiscReg to read the instreth CSR.");
+        return 0;
+      case MISCREG_MHARTID:
+        warn("Use readMiscReg to read the mhartid CSR.");
         return 0;
       default:
         return miscRegFile[misc_reg];
@@ -186,6 +230,8 @@
         DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n",
             miscRegNames[misc_reg], miscRegFile[misc_reg]);
         return tc->getCpuPtr()->curCycle() >> 32;
+      case MISCREG_MHARTID:
+        return 0; // TODO: make this the hardware thread or cpu id
       default:
         return readMiscRegNoEffect(misc_reg);
     }
@@ -195,7 +241,7 @@
 ISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
 {
     DPRINTF(RiscvMisc, "Setting CSR %s to 0x%016llx.\n",
-        miscRegNames[misc_reg], miscRegNames[misc_reg], val);
+        miscRegNames[misc_reg], val);
     switch (misc_reg) {
       case MISCREG_FFLAGS:
         miscRegFile[MISCREG_FCSR] &= ~0x1F;
diff --git a/src/arch/riscv/isa.hh b/src/arch/riscv/isa.hh
index 421f792..d2f38b1 100644
--- a/src/arch/riscv/isa.hh
+++ b/src/arch/riscv/isa.hh
@@ -58,10 +58,10 @@
 {
   protected:
     std::vector<MiscReg> miscRegFile;
+    std::map<int, std::string> miscRegNames;

   public:
     typedef RiscvISAParams Params;
-    static std::map<int, std::string> miscRegNames;

     void
     clear();
diff --git a/src/arch/riscv/registers.hh b/src/arch/riscv/registers.hh
index d897703..812409d 100644
--- a/src/arch/riscv/registers.hh
+++ b/src/arch/riscv/registers.hh
@@ -106,60 +106,64 @@
     ArgumentRegs[2], ArgumentRegs[3]};
 const int SyscallPseudoReturnReg = ReturnValueRegs[0];

+const int NumHpmcounter = 29;
+const int NumHpmcounterh = 29;
+const int NumMhpmcounter = 29;
+const int NumMhpmevent = 29;
 enum MiscRegIndex {
+    MISCREG_USTATUS = 0x000,
+    MISCREG_UIE = 0x004,
+    MISCREG_UTVEC = 0x005,
+    MISCREG_USCRATCH = 0x040,
+    MISCREG_UEPC = 0x041,
+    MISCREG_UCAUSE = 0x042,
+    MISCREG_UBADADDR = 0x043,
+    MISCREG_UIP = 0x044,
     MISCREG_FFLAGS = 0x001,
     MISCREG_FRM = 0x002,
     MISCREG_FCSR = 0x003,
     MISCREG_CYCLE = 0xC00,
     MISCREG_TIME = 0xC01,
     MISCREG_INSTRET = 0xC02,
+    MISCREG_HPMCOUNTER_BASE = 0xC03,
     MISCREG_CYCLEH = 0xC80,
     MISCREG_TIMEH = 0xC81,
     MISCREG_INSTRETH = 0xC82,
+    MISCREG_HPMCOUNTERH_BASE = 0xC83,

     MISCREG_SSTATUS = 0x100,
-    MISCREG_STVEC = 0x101,
+    MISCREG_SEDELEG = 0x102,
+    MISCREG_SIDELEG = 0x103,
     MISCREG_SIE = 0x104,
-    MISCREG_STIMECMP = 0x121,
-    MISCREG_STIME = 0xD01,
-    MISCREG_STIMEH = 0xD81,
+    MISCREG_STVEC = 0x105,
     MISCREG_SSCRATCH = 0x140,
     MISCREG_SEPC = 0x141,
-    MISCREG_SCAUSE = 0xD42,
-    MISCREG_SBADADDR = 0xD43,
+    MISCREG_SCAUSE = 0x142,
+    MISCREG_SBADADDR = 0x143,
     MISCREG_SIP = 0x144,
     MISCREG_SPTBR = 0x180,
-    MISCREG_SASID = 0x181,
-    MISCREG_CYCLEW = 0x900,
-    MISCREG_TIMEW = 0x901,
-    MISCREG_INSTRETW = 0x902,
-    MISCREG_CYCLEHW = 0x980,
-    MISCREG_TIMEHW = 0x981,
-    MISCREG_INSTRETHW = 0x982,

     MISCREG_HSTATUS = 0x200,
-    MISCREG_HTVEC = 0x201,
-    MISCREG_HTDELEG = 0x202,
-    MISCREG_HTIMECMP = 0x221,
-    MISCREG_HTIME = 0xE01,
-    MISCREG_HTIMEH = 0xE81,
+    MISCREG_HEDELEG = 0x202,
+    MISCREG_HIDELEG = 0x203,
+    MISCREG_HIE = 0x204,
+    MISCREG_HTVEC = 0x205,
     MISCREG_HSCRATCH = 0x240,
     MISCREG_HEPC = 0x241,
     MISCREG_HCAUSE = 0x242,
     MISCREG_HBADADDR = 0x243,
-    MISCREG_STIMEW = 0xA01,
-    MISCREG_STIMEHW = 0xA81,
+    MISCREG_HIP = 0x244,

-    MISCREG_MCPUID = 0xF00,
-    MISCREG_MIMPID = 0xF01,
-    MISCREG_MHARTID = 0xF10,
+    MISCREG_MVENDORID = 0xF11,
+    MISCREG_MARCHID = 0xF12,
+    MISCREG_MIMPID = 0xF13,
+    MISCREG_MHARTID = 0xF14,
     MISCREG_MSTATUS = 0x300,
-    MISCREG_MTVEC = 0x301,
-    MISCREG_MTDELEG = 0x302,
+    MISCREG_MISA = 0x301,
+    MISCREG_MEDELEG = 0x302,
+    MISCREG_MIDELEG = 0x303,
     MISCREG_MIE = 0x304,
-    MISCREG_MTIMECMP = 0x321,
-    MISCREG_MTIME = 0x701,
-    MISCREG_MTIMEH = 0x741,
+    MISCREG_MTVEC = 0x305,
     MISCREG_MSCRATCH = 0x340,
     MISCREG_MEPC = 0x341,
     MISCREG_MCAUSE = 0x342,
@@ -171,10 +175,21 @@
     MISCREG_MIBOUND = 0x383,
     MISCREG_MDBASE = 0x384,
     MISCREG_MDBOUND = 0x385,
-    MISCREG_HTIMEW = 0xB01,
-    MISCREG_HTIMEHW = 0xB81,
-    MISCREG_MTOHOST = 0x780,
-    MISCREG_MFROMHOST = 0x781
+    MISCREG_MCYCLE = 0xB00,
+    MISCREG_MINSTRET = 0xB02,
+    MISCREG_MHPMCOUNTER_BASE = 0xB03,
+    MISCREG_MUCOUNTEREN = 0x320,
+    MISCREG_MSCOUNTEREN = 0x321,
+    MISCREG_MHCOUNTEREN = 0x322,
+    MISCREG_MHPMEVENT_BASE = 0x323,
+
+    MISCREG_TSELECT = 0x7A0,
+    MISCREG_TDATA1 = 0x7A1,
+    MISCREG_TDATA2 = 0x7A2,
+    MISCREG_TDATA3 = 0x7A3,
+    MISCREG_DCSR = 0x7B0,
+    MISCREG_DPC = 0x7B1,
+    MISCREG_DSCRATCH = 0x7B2
 };

 }
diff --git a/src/arch/riscv/remote_gdb.cc b/src/arch/riscv/remote_gdb.cc
index 96a6a9f..2b50876 100644
--- a/src/arch/riscv/remote_gdb.cc
+++ b/src/arch/riscv/remote_gdb.cc
@@ -166,25 +166,37 @@
 void
 RemoteGDB::RiscvGdbRegCache::getRegs(ThreadContext *context)
 {
-    DPRINTF(GDBAcc, "getregs in remotegdb \n");
-    r.pc = context->pcState().pc();
+    DPRINTF(GDBAcc, "getregs in remotegdb, size %lu\n", size());
     for (int i = 0; i < NumIntArchRegs; i++)
         r.gpr[i] = context->readIntReg(i);
-    r.amo = context->readIntReg(NumIntArchRegs);
+    r.pc = context->pcState().pc();
     for (int i = 0; i < NumFloatRegs; i++)
         r.fpr[i] = context->readFloatRegBits(i);
+
+    r.csr_base = context->readMiscReg(0);
+    r.fflags = context->readMiscReg(MISCREG_FFLAGS);
+    r.frm = context->readMiscReg(MISCREG_FRM);
+    r.fcsr = context->readMiscReg(MISCREG_FCSR);
+    for (int i = ExplicitCSRs; i < NumMiscRegs; i++)
+        r.csr[i - ExplicitCSRs] = context->readMiscReg(i);
 }

 void
 RemoteGDB::RiscvGdbRegCache::setRegs(ThreadContext *context) const
 {
     DPRINTF(GDBAcc, "setregs in remotegdb \n");
-    context->pcState(r.pc);
     for (int i = 0; i < NumIntArchRegs; i++)
         context->setIntReg(i, r.gpr[i]);
-    context->setIntReg(NumIntArchRegs, r.amo);
+    context->pcState(r.pc);
     for (int i = 0; i < NumFloatRegs; i++)
         context->setFloatRegBits(i, r.fpr[i]);
+
+    context->setMiscReg(0, r.csr_base);
+    context->setMiscReg(MISCREG_FFLAGS, r.fflags);
+    context->setMiscReg(MISCREG_FRM, r.frm);
+    context->setMiscReg(MISCREG_FCSR, r.fcsr);
+    for (int i = ExplicitCSRs; i < NumMiscRegs; i++)
+        context->setMiscReg(i, r.csr[i - ExplicitCSRs]);
 }

 RemoteGDB::BaseGdbRegCache*
diff --git a/src/arch/riscv/remote_gdb.hh b/src/arch/riscv/remote_gdb.hh
index 78d40f6..735faae 100644
--- a/src/arch/riscv/remote_gdb.hh
+++ b/src/arch/riscv/remote_gdb.hh
@@ -50,6 +50,8 @@
 class RemoteGDB : public BaseRemoteGDB
 {
   protected:
+    static const int ExplicitCSRs = 4;
+
     bool acc(Addr addr, size_t len);

     class RiscvGdbRegCache : public BaseGdbRegCache
@@ -57,11 +59,16 @@
       using BaseGdbRegCache::BaseGdbRegCache;
       private:
         struct {
-            IntReg pc;
             IntReg gpr[NumIntArchRegs];
-            IntReg amo;
+            IntReg pc;
             FloatRegBits fpr[NumFloatRegs];
-        } r;
+
+            MiscReg csr_base;
+            uint32_t fflags;
+            uint32_t frm;
+            uint32_t fcsr;
+            MiscReg csr[NumMiscRegs - ExplicitCSRs];
+        } __attribute__((__packed__)) r;
       public:
         char *data() const { return (char *)&r; }
         size_t size() const { return sizeof(r); }

--
To view, visit https://gem5-review.googlesource.com/2302
To unsubscribe, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I16b9951bcd90ffdcdd3f237803ae76b1f9cd63bc
Gerrit-Change-Number: 2302
Gerrit-PatchSet: 1
Gerrit-Owner: Alec Roelke <[email protected]>
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to