Peter Yuen has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/38955 )

Change subject: arch-riscv: CSR registers support in RISC-V remote GDB.
......................................................................

arch-riscv: CSR registers support in RISC-V remote GDB.

Note:
Some less frequently needed CSR registers (e.g. hpm and pmp registers)
are commented out on purpose. Instructions to add them back are
described in remote_gdb.hh comments. This is to avoid spamming the
remote GDB log when using `info reg all`.

Changes:
1. Added GDB XML files to the ext/ directory (mostly from QEMU)
2. Modified RiscvGdbRegCache
        - struct r: added CSR registers
        - getRegs, setRegs: reading / setting CSR registers
3. Modified RemoteGDB
        - availableFeatures: indicate support for XML registers
        - getXferFeaturesRead: return XML blobs

Change-Id: Ica03b63edb3f0c9b6a7789228b995891dbfb26b2
---
A ext/gdb-xml/riscv-64bit-cpu.xml
A ext/gdb-xml/riscv-64bit-csr.xml
A ext/gdb-xml/riscv-64bit-fpu.xml
A ext/gdb-xml/riscv.xml
M src/arch/riscv/SConscript
M src/arch/riscv/remote_gdb.cc
M src/arch/riscv/remote_gdb.hh
7 files changed, 733 insertions(+), 2 deletions(-)



diff --git a/ext/gdb-xml/riscv-64bit-cpu.xml b/ext/gdb-xml/riscv-64bit-cpu.xml
new file mode 100644
index 0000000..cd45b19
--- /dev/null
+++ b/ext/gdb-xml/riscv-64bit-cpu.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018-2019 Free Software Foundation, Inc.
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!-- Register numbers are hard-coded in order to maintain backward
+     compatibility with older versions of tools that didn't use xml
+     register descriptions.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.riscv.cpu">
+  <reg name="zero" bitsize="64" type="int" regnum="0"/>
+  <reg name="ra" bitsize="64" type="code_ptr"/>
+  <reg name="sp" bitsize="64" type="data_ptr"/>
+  <reg name="gp" bitsize="64" type="data_ptr"/>
+  <reg name="tp" bitsize="64" type="data_ptr"/>
+  <reg name="t0" bitsize="64" type="int"/>
+  <reg name="t1" bitsize="64" type="int"/>
+  <reg name="t2" bitsize="64" type="int"/>
+  <reg name="fp" bitsize="64" type="data_ptr"/>
+  <reg name="s1" bitsize="64" type="int"/>
+  <reg name="a0" bitsize="64" type="int"/>
+  <reg name="a1" bitsize="64" type="int"/>
+  <reg name="a2" bitsize="64" type="int"/>
+  <reg name="a3" bitsize="64" type="int"/>
+  <reg name="a4" bitsize="64" type="int"/>
+  <reg name="a5" bitsize="64" type="int"/>
+  <reg name="a6" bitsize="64" type="int"/>
+  <reg name="a7" bitsize="64" type="int"/>
+  <reg name="s2" bitsize="64" type="int"/>
+  <reg name="s3" bitsize="64" type="int"/>
+  <reg name="s4" bitsize="64" type="int"/>
+  <reg name="s5" bitsize="64" type="int"/>
+  <reg name="s6" bitsize="64" type="int"/>
+  <reg name="s7" bitsize="64" type="int"/>
+  <reg name="s8" bitsize="64" type="int"/>
+  <reg name="s9" bitsize="64" type="int"/>
+  <reg name="s10" bitsize="64" type="int"/>
+  <reg name="s11" bitsize="64" type="int"/>
+  <reg name="t3" bitsize="64" type="int"/>
+  <reg name="t4" bitsize="64" type="int"/>
+  <reg name="t5" bitsize="64" type="int"/>
+  <reg name="t6" bitsize="64" type="int"/>
+  <reg name="pc" bitsize="64" type="code_ptr"/>
+</feature>
\ No newline at end of file
diff --git a/ext/gdb-xml/riscv-64bit-csr.xml b/ext/gdb-xml/riscv-64bit-csr.xml
new file mode 100644
index 0000000..218397b
--- /dev/null
+++ b/ext/gdb-xml/riscv-64bit-csr.xml
@@ -0,0 +1,247 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018-2019 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.riscv.csr">
+  <reg name="cycle" bitsize="64"/>
+  <reg name="time" bitsize="64"/>
+  <reg name="ustatus" bitsize="64"/>
+  <reg name="uie" bitsize="64"/>
+  <reg name="utvec" bitsize="64"/>
+  <reg name="uscratch" bitsize="64"/>
+  <reg name="uepc" bitsize="64"/>
+  <reg name="ucause" bitsize="64"/>
+  <reg name="utval" bitsize="64"/>
+  <reg name="uip" bitsize="64"/>
+  <reg name="sstatus" bitsize="64"/>
+  <reg name="sedeleg" bitsize="64"/>
+  <reg name="sideleg" bitsize="64"/>
+  <reg name="sie" bitsize="64"/>
+  <reg name="stvec" bitsize="64"/>
+  <reg name="scounteren" bitsize="64"/>
+  <reg name="sscratch" bitsize="64"/>
+  <reg name="sepc" bitsize="64"/>
+  <reg name="scause" bitsize="64"/>
+  <reg name="stval" bitsize="64"/>
+  <reg name="sip" bitsize="64"/>
+  <reg name="satp" bitsize="64"/>
+  <reg name="mvendorid" bitsize="64"/>
+  <reg name="marchid" bitsize="64"/>
+  <reg name="mimpid" bitsize="64"/>
+  <reg name="mhartid" bitsize="64"/>
+  <reg name="mstatus" bitsize="64"/>
+  <reg name="misa" bitsize="64"/>
+  <reg name="medeleg" bitsize="64"/>
+  <reg name="mideleg" bitsize="64"/>
+  <reg name="mie" bitsize="64"/>
+  <reg name="mtvec" bitsize="64"/>
+  <reg name="mcounteren" bitsize="64"/>
+  <reg name="mscratch" bitsize="64"/>
+  <reg name="mepc" bitsize="64"/>
+  <reg name="mcause" bitsize="64"/>
+  <reg name="mtval" bitsize="64"/>
+  <reg name="mip" bitsize="64"/>
+  <reg name="hstatus" bitsize="64"/>
+  <reg name="hedeleg" bitsize="64"/>
+  <reg name="hideleg" bitsize="64"/>
+  <reg name="hie" bitsize="64"/>
+  <reg name="htvec" bitsize="64"/>
+  <reg name="hscratch" bitsize="64"/>
+  <reg name="hepc" bitsize="64"/>
+  <reg name="hcause" bitsize="64"/>
+  <reg name="hbadaddr" bitsize="64"/>
+  <reg name="hip" bitsize="64"/>
+  <!-- <reg name="instret" bitsize="64"/>
+  <reg name="hpmcounter3" bitsize="64"/>
+  <reg name="hpmcounter4" bitsize="64"/>
+  <reg name="hpmcounter5" bitsize="64"/>
+  <reg name="hpmcounter6" bitsize="64"/>
+  <reg name="hpmcounter7" bitsize="64"/>
+  <reg name="hpmcounter8" bitsize="64"/>
+  <reg name="hpmcounter9" bitsize="64"/>
+  <reg name="hpmcounter10" bitsize="64"/>
+  <reg name="hpmcounter11" bitsize="64"/>
+  <reg name="hpmcounter12" bitsize="64"/>
+  <reg name="hpmcounter13" bitsize="64"/>
+  <reg name="hpmcounter14" bitsize="64"/>
+  <reg name="hpmcounter15" bitsize="64"/>
+  <reg name="hpmcounter16" bitsize="64"/>
+  <reg name="hpmcounter17" bitsize="64"/>
+  <reg name="hpmcounter18" bitsize="64"/>
+  <reg name="hpmcounter19" bitsize="64"/>
+  <reg name="hpmcounter20" bitsize="64"/>
+  <reg name="hpmcounter21" bitsize="64"/>
+  <reg name="hpmcounter22" bitsize="64"/>
+  <reg name="hpmcounter23" bitsize="64"/>
+  <reg name="hpmcounter24" bitsize="64"/>
+  <reg name="hpmcounter25" bitsize="64"/>
+  <reg name="hpmcounter26" bitsize="64"/>
+  <reg name="hpmcounter27" bitsize="64"/>
+  <reg name="hpmcounter28" bitsize="64"/>
+  <reg name="hpmcounter29" bitsize="64"/>
+  <reg name="hpmcounter30" bitsize="64"/>
+  <reg name="hpmcounter31" bitsize="64"/>
+  <reg name="cycleh" bitsize="64"/>
+  <reg name="timeh" bitsize="64"/>
+  <reg name="instreth" bitsize="64"/>
+  <reg name="hpmcounter3h" bitsize="64"/>
+  <reg name="hpmcounter4h" bitsize="64"/>
+  <reg name="hpmcounter5h" bitsize="64"/>
+  <reg name="hpmcounter6h" bitsize="64"/>
+  <reg name="hpmcounter7h" bitsize="64"/>
+  <reg name="hpmcounter8h" bitsize="64"/>
+  <reg name="hpmcounter9h" bitsize="64"/>
+  <reg name="hpmcounter10h" bitsize="64"/>
+  <reg name="hpmcounter11h" bitsize="64"/>
+  <reg name="hpmcounter12h" bitsize="64"/>
+  <reg name="hpmcounter13h" bitsize="64"/>
+  <reg name="hpmcounter14h" bitsize="64"/>
+  <reg name="hpmcounter15h" bitsize="64"/>
+  <reg name="hpmcounter16h" bitsize="64"/>
+  <reg name="hpmcounter17h" bitsize="64"/>
+  <reg name="hpmcounter18h" bitsize="64"/>
+  <reg name="hpmcounter19h" bitsize="64"/>
+  <reg name="hpmcounter20h" bitsize="64"/>
+  <reg name="hpmcounter21h" bitsize="64"/>
+  <reg name="hpmcounter22h" bitsize="64"/>
+  <reg name="hpmcounter23h" bitsize="64"/>
+  <reg name="hpmcounter24h" bitsize="64"/>
+  <reg name="hpmcounter25h" bitsize="64"/>
+  <reg name="hpmcounter26h" bitsize="64"/>
+  <reg name="hpmcounter27h" bitsize="64"/>
+  <reg name="hpmcounter28h" bitsize="64"/>
+  <reg name="hpmcounter29h" bitsize="64"/>
+  <reg name="hpmcounter30h" bitsize="64"/>
+  <reg name="hpmcounter31h" bitsize="64"/>
+  <reg name="pmpcfg0" bitsize="64"/>
+  <reg name="pmpcfg1" bitsize="64"/>
+  <reg name="pmpcfg2" bitsize="64"/>
+  <reg name="pmpcfg3" bitsize="64"/>
+  <reg name="pmpaddr0" bitsize="64"/>
+  <reg name="pmpaddr1" bitsize="64"/>
+  <reg name="pmpaddr2" bitsize="64"/>
+  <reg name="pmpaddr3" bitsize="64"/>
+  <reg name="pmpaddr4" bitsize="64"/>
+  <reg name="pmpaddr5" bitsize="64"/>
+  <reg name="pmpaddr6" bitsize="64"/>
+  <reg name="pmpaddr7" bitsize="64"/>
+  <reg name="pmpaddr8" bitsize="64"/>
+  <reg name="pmpaddr9" bitsize="64"/>
+  <reg name="pmpaddr10" bitsize="64"/>
+  <reg name="pmpaddr11" bitsize="64"/>
+  <reg name="pmpaddr12" bitsize="64"/>
+  <reg name="pmpaddr13" bitsize="64"/>
+  <reg name="pmpaddr14" bitsize="64"/>
+  <reg name="pmpaddr15" bitsize="64"/>
+  <reg name="mcycle" bitsize="64"/>
+  <reg name="minstret" bitsize="64"/>
+  <reg name="mhpmcounter3" bitsize="64"/>
+  <reg name="mhpmcounter4" bitsize="64"/>
+  <reg name="mhpmcounter5" bitsize="64"/>
+  <reg name="mhpmcounter6" bitsize="64"/>
+  <reg name="mhpmcounter7" bitsize="64"/>
+  <reg name="mhpmcounter8" bitsize="64"/>
+  <reg name="mhpmcounter9" bitsize="64"/>
+  <reg name="mhpmcounter10" bitsize="64"/>
+  <reg name="mhpmcounter11" bitsize="64"/>
+  <reg name="mhpmcounter12" bitsize="64"/>
+  <reg name="mhpmcounter13" bitsize="64"/>
+  <reg name="mhpmcounter14" bitsize="64"/>
+  <reg name="mhpmcounter15" bitsize="64"/>
+  <reg name="mhpmcounter16" bitsize="64"/>
+  <reg name="mhpmcounter17" bitsize="64"/>
+  <reg name="mhpmcounter18" bitsize="64"/>
+  <reg name="mhpmcounter19" bitsize="64"/>
+  <reg name="mhpmcounter20" bitsize="64"/>
+  <reg name="mhpmcounter21" bitsize="64"/>
+  <reg name="mhpmcounter22" bitsize="64"/>
+  <reg name="mhpmcounter23" bitsize="64"/>
+  <reg name="mhpmcounter24" bitsize="64"/>
+  <reg name="mhpmcounter25" bitsize="64"/>
+  <reg name="mhpmcounter26" bitsize="64"/>
+  <reg name="mhpmcounter27" bitsize="64"/>
+  <reg name="mhpmcounter28" bitsize="64"/>
+  <reg name="mhpmcounter29" bitsize="64"/>
+  <reg name="mhpmcounter30" bitsize="64"/>
+  <reg name="mhpmcounter31" bitsize="64"/>
+  <reg name="mcycleh" bitsize="64"/>
+  <reg name="minstreth" bitsize="64"/>
+  <reg name="mhpmcounter3h" bitsize="64"/>
+  <reg name="mhpmcounter4h" bitsize="64"/>
+  <reg name="mhpmcounter5h" bitsize="64"/>
+  <reg name="mhpmcounter6h" bitsize="64"/>
+  <reg name="mhpmcounter7h" bitsize="64"/>
+  <reg name="mhpmcounter8h" bitsize="64"/>
+  <reg name="mhpmcounter9h" bitsize="64"/>
+  <reg name="mhpmcounter10h" bitsize="64"/>
+  <reg name="mhpmcounter11h" bitsize="64"/>
+  <reg name="mhpmcounter12h" bitsize="64"/>
+  <reg name="mhpmcounter13h" bitsize="64"/>
+  <reg name="mhpmcounter14h" bitsize="64"/>
+  <reg name="mhpmcounter15h" bitsize="64"/>
+  <reg name="mhpmcounter16h" bitsize="64"/>
+  <reg name="mhpmcounter17h" bitsize="64"/>
+  <reg name="mhpmcounter18h" bitsize="64"/>
+  <reg name="mhpmcounter19h" bitsize="64"/>
+  <reg name="mhpmcounter20h" bitsize="64"/>
+  <reg name="mhpmcounter21h" bitsize="64"/>
+  <reg name="mhpmcounter22h" bitsize="64"/>
+  <reg name="mhpmcounter23h" bitsize="64"/>
+  <reg name="mhpmcounter24h" bitsize="64"/>
+  <reg name="mhpmcounter25h" bitsize="64"/>
+  <reg name="mhpmcounter26h" bitsize="64"/>
+  <reg name="mhpmcounter27h" bitsize="64"/>
+  <reg name="mhpmcounter28h" bitsize="64"/>
+  <reg name="mhpmcounter29h" bitsize="64"/>
+  <reg name="mhpmcounter30h" bitsize="64"/>
+  <reg name="mhpmcounter31h" bitsize="64"/>
+  <reg name="mhpmevent3" bitsize="64"/>
+  <reg name="mhpmevent4" bitsize="64"/>
+  <reg name="mhpmevent5" bitsize="64"/>
+  <reg name="mhpmevent6" bitsize="64"/>
+  <reg name="mhpmevent7" bitsize="64"/>
+  <reg name="mhpmevent8" bitsize="64"/>
+  <reg name="mhpmevent9" bitsize="64"/>
+  <reg name="mhpmevent10" bitsize="64"/>
+  <reg name="mhpmevent11" bitsize="64"/>
+  <reg name="mhpmevent12" bitsize="64"/>
+  <reg name="mhpmevent13" bitsize="64"/>
+  <reg name="mhpmevent14" bitsize="64"/>
+  <reg name="mhpmevent15" bitsize="64"/>
+  <reg name="mhpmevent16" bitsize="64"/>
+  <reg name="mhpmevent17" bitsize="64"/>
+  <reg name="mhpmevent18" bitsize="64"/>
+  <reg name="mhpmevent19" bitsize="64"/>
+  <reg name="mhpmevent20" bitsize="64"/>
+  <reg name="mhpmevent21" bitsize="64"/>
+  <reg name="mhpmevent22" bitsize="64"/>
+  <reg name="mhpmevent23" bitsize="64"/>
+  <reg name="mhpmevent24" bitsize="64"/>
+  <reg name="mhpmevent25" bitsize="64"/>
+  <reg name="mhpmevent26" bitsize="64"/>
+  <reg name="mhpmevent27" bitsize="64"/>
+  <reg name="mhpmevent28" bitsize="64"/>
+  <reg name="mhpmevent29" bitsize="64"/>
+  <reg name="mhpmevent30" bitsize="64"/>
+  <reg name="mhpmevent31" bitsize="64"/>
+  <reg name="tselect" bitsize="64"/>
+  <reg name="tdata1" bitsize="64"/>
+  <reg name="tdata2" bitsize="64"/>
+  <reg name="tdata3" bitsize="64"/>
+  <reg name="dcsr" bitsize="64"/>
+  <reg name="dpc" bitsize="64"/>
+  <reg name="dscratch" bitsize="64"/>
+  <reg name="mbase" bitsize="64"/>
+  <reg name="mbound" bitsize="64"/>
+  <reg name="mibase" bitsize="64"/>
+  <reg name="mibound" bitsize="64"/>
+  <reg name="mdbase" bitsize="64"/>
+  <reg name="mdbound" bitsize="64"/>
+  <reg name="mucounteren" bitsize="64"/>
+  <reg name="mscounteren" bitsize="64"/>
+  <reg name="mhcounteren" bitsize="64"/> -->
+</feature>
\ No newline at end of file
diff --git a/ext/gdb-xml/riscv-64bit-fpu.xml b/ext/gdb-xml/riscv-64bit-fpu.xml
new file mode 100644
index 0000000..8342da9
--- /dev/null
+++ b/ext/gdb-xml/riscv-64bit-fpu.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018-2019 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!-- Register numbers are hard-coded in order to maintain backward
+     compatibility with older versions of tools that didn't use xml
+     register descriptions.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.riscv.fpu">
+
+  <union id="riscv_double">
+    <field name="float" type="ieee_single"/>
+    <field name="double" type="ieee_double"/>
+  </union>
+
+  <reg name="ft0" bitsize="64" type="riscv_double" regnum="33"/>
+  <reg name="ft1" bitsize="64" type="riscv_double"/>
+  <reg name="ft2" bitsize="64" type="riscv_double"/>
+  <reg name="ft3" bitsize="64" type="riscv_double"/>
+  <reg name="ft4" bitsize="64" type="riscv_double"/>
+  <reg name="ft5" bitsize="64" type="riscv_double"/>
+  <reg name="ft6" bitsize="64" type="riscv_double"/>
+  <reg name="ft7" bitsize="64" type="riscv_double"/>
+  <reg name="fs0" bitsize="64" type="riscv_double"/>
+  <reg name="fs1" bitsize="64" type="riscv_double"/>
+  <reg name="fa0" bitsize="64" type="riscv_double"/>
+  <reg name="fa1" bitsize="64" type="riscv_double"/>
+  <reg name="fa2" bitsize="64" type="riscv_double"/>
+  <reg name="fa3" bitsize="64" type="riscv_double"/>
+  <reg name="fa4" bitsize="64" type="riscv_double"/>
+  <reg name="fa5" bitsize="64" type="riscv_double"/>
+  <reg name="fa6" bitsize="64" type="riscv_double"/>
+  <reg name="fa7" bitsize="64" type="riscv_double"/>
+  <reg name="fs2" bitsize="64" type="riscv_double"/>
+  <reg name="fs3" bitsize="64" type="riscv_double"/>
+  <reg name="fs4" bitsize="64" type="riscv_double"/>
+  <reg name="fs5" bitsize="64" type="riscv_double"/>
+  <reg name="fs6" bitsize="64" type="riscv_double"/>
+  <reg name="fs7" bitsize="64" type="riscv_double"/>
+  <reg name="fs8" bitsize="64" type="riscv_double"/>
+  <reg name="fs9" bitsize="64" type="riscv_double"/>
+  <reg name="fs10" bitsize="64" type="riscv_double"/>
+  <reg name="fs11" bitsize="64" type="riscv_double"/>
+  <reg name="ft8" bitsize="64" type="riscv_double"/>
+  <reg name="ft9" bitsize="64" type="riscv_double"/>
+  <reg name="ft10" bitsize="64" type="riscv_double"/>
+  <reg name="ft11" bitsize="64" type="riscv_double"/>
+
+  <reg name="fflags" bitsize="32" type="int" regnum="66"/>
+  <reg name="frm" bitsize="32" type="int" regnum="67"/>
+  <reg name="fcsr" bitsize="32" type="int" regnum="68"/>
+  <reg name="placeholder" bitsize="32" type="int" regnum="69"/>
+</feature>
\ No newline at end of file
diff --git a/ext/gdb-xml/riscv.xml b/ext/gdb-xml/riscv.xml
new file mode 100644
index 0000000..731ef95
--- /dev/null
+++ b/ext/gdb-xml/riscv.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2009-2013 Free Software Foundation, Inc.
+     Contributed by ARM Ltd.
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>riscv</architecture>
+  <xi:include href="riscv-64bit-cpu.xml"/>
+  <xi:include href="riscv-64bit-fpu.xml"/>
+  <xi:include href="riscv-64bit-csr.xml"/>
+</target>
\ No newline at end of file
diff --git a/src/arch/riscv/SConscript b/src/arch/riscv/SConscript
index 3913be9..33a9841 100644
--- a/src/arch/riscv/SConscript
+++ b/src/arch/riscv/SConscript
@@ -73,3 +73,8 @@

     # Add in files generated by the ISA description.
     ISADesc('isa/main.isa')
+
+    GdbXml('riscv.xml', 'gdb_xml_riscv_target')
+    GdbXml('riscv-64bit-cpu.xml', 'gdb_xml_riscv_cpu')
+    GdbXml('riscv-64bit-fpu.xml', 'gdb_xml_riscv_fpu')
+    GdbXml('riscv-64bit-csr.xml', 'gdb_xml_riscv_csr')
diff --git a/src/arch/riscv/remote_gdb.cc b/src/arch/riscv/remote_gdb.cc
index 0e4c544..aa871c6 100644
--- a/src/arch/riscv/remote_gdb.cc
+++ b/src/arch/riscv/remote_gdb.cc
@@ -137,6 +137,11 @@
 #include "arch/riscv/mmu.hh"
 #include "arch/riscv/pagetable_walker.hh"
 #include "arch/riscv/registers.hh"
+#include "arch/riscv/tlb.hh"
+#include "blobs/gdb_xml_riscv_cpu.hh"
+#include "blobs/gdb_xml_riscv_csr.hh"
+#include "blobs/gdb_xml_riscv_fpu.hh"
+#include "blobs/gdb_xml_riscv_target.hh"
 #include "cpu/thread_state.hh"
 #include "debug/GDBAcc.hh"
 #include "mem/page_table.hh"
@@ -165,7 +170,7 @@
             satp.mode != AddrXlateMode::BARE) {
             Walker *walker = mmu->getDataWalker();
             Fault fault = walker->startFunctional(
-                    context(), paddr, logBytes, BaseTLB::Read);
+                context(), paddr, logBytes, BaseTLB::Read);
             if (fault != NoFault)
                 return false;
         }
@@ -179,21 +184,304 @@
 RemoteGDB::RiscvGdbRegCache::getRegs(ThreadContext *context)
 {
     DPRINTF(GDBAcc, "getregs in remotegdb, size %lu\n", size());
+
+    // General registers
     for (int i = 0; i < NumIntArchRegs; i++)
+    {
         r.gpr[i] = context->readIntReg(i);
+    }
     r.pc = context->pcState().pc();
+
+    // Floating point registers
+    for (int i = 0; i < NumFloatRegs; i++)
+        r.fpu[i] = context->readFloatReg(i);
+    r.fflags = context->readMiscRegNoEffect(
+        CSRData.at(CSR_FFLAGS).physIndex) & CSRMasks.at(CSR_FFLAGS);
+    r.frm = context->readMiscRegNoEffect(
+        CSRData.at(CSR_FRM).physIndex) & CSRMasks.at(CSR_FRM);
+    r.fcsr = context->readMiscRegNoEffect(
+        CSRData.at(CSR_FCSR).physIndex) & CSRMasks.at(CSR_FCSR);
+
+    // CSR registers
+    r.cycle = context->readMiscRegNoEffect(
+        CSRData.at(CSR_CYCLE).physIndex);
+    r.time = context->readMiscRegNoEffect(
+        CSRData.at(CSR_TIME).physIndex);
+
+    // U mode CSR
+    r.ustatus = context->readMiscRegNoEffect(
+        CSRData.at(CSR_USTATUS).physIndex) & CSRMasks.at(CSR_USTATUS);
+    r.uie = context->readMiscRegNoEffect(
+        CSRData.at(CSR_UIE).physIndex) & CSRMasks.at(CSR_UIE);
+    r.utvec = context->readMiscRegNoEffect(
+        CSRData.at(CSR_UTVEC).physIndex);
+    r.uscratch = context->readMiscRegNoEffect(
+        CSRData.at(CSR_USCRATCH).physIndex);
+    r.uepc = context->readMiscRegNoEffect(
+        CSRData.at(CSR_UEPC).physIndex);
+    r.ucause = context->readMiscRegNoEffect(
+        CSRData.at(CSR_UCAUSE).physIndex);
+    r.utval = context->readMiscRegNoEffect(
+        CSRData.at(CSR_UTVAL).physIndex);
+    r.uip = context->readMiscRegNoEffect(
+        CSRData.at(CSR_UIP).physIndex) & CSRMasks.at(CSR_UIP);
+
+    // S mode CSR
+    r.sstatus = context->readMiscRegNoEffect(
+        CSRData.at(CSR_SSTATUS).physIndex) & CSRMasks.at(CSR_SSTATUS);
+    r.sedeleg = context->readMiscRegNoEffect(
+        CSRData.at(CSR_SEDELEG).physIndex);
+    r.sideleg = context->readMiscRegNoEffect(
+        CSRData.at(CSR_SIDELEG).physIndex);
+    r.sie = context->readMiscRegNoEffect(
+        CSRData.at(CSR_SIE).physIndex) & CSRMasks.at(CSR_SIE);
+    r.stvec = context->readMiscRegNoEffect(
+        CSRData.at(CSR_STVEC).physIndex);
+    r.scounteren = context->readMiscRegNoEffect(
+        CSRData.at(CSR_SCOUNTEREN).physIndex);
+    r.sscratch = context->readMiscRegNoEffect(
+        CSRData.at(CSR_SSCRATCH).physIndex);
+    r.sepc = context->readMiscRegNoEffect(
+        CSRData.at(CSR_SEPC).physIndex);
+    r.scause = context->readMiscRegNoEffect(
+        CSRData.at(CSR_SCAUSE).physIndex);
+    r.stval = context->readMiscRegNoEffect(
+        CSRData.at(CSR_STVAL).physIndex);
+    r.sip = context->readMiscRegNoEffect(
+        CSRData.at(CSR_SIP).physIndex) & CSRMasks.at(CSR_SIP);
+    r.satp = context->readMiscRegNoEffect(
+        CSRData.at(CSR_SATP).physIndex);
+
+    // M mode CSR
+    r.mvendorid = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MVENDORID).physIndex);
+    r.marchid = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MARCHID).physIndex);
+    r.mimpid = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MIMPID).physIndex);
+    r.mhartid = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MHARTID).physIndex);
+    r.mstatus = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MSTATUS).physIndex) & CSRMasks.at(CSR_MSTATUS);
+    r.misa = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MISA).physIndex) & CSRMasks.at(CSR_MISA);
+    r.medeleg = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MEDELEG).physIndex);
+    r.mideleg = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MIDELEG).physIndex);
+    r.mie = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MIE).physIndex) & CSRMasks.at(CSR_MIE);
+    r.mtvec = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MTVEC).physIndex);
+    r.mcounteren = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MCOUNTEREN).physIndex);
+    r.mscratch = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MSCRATCH).physIndex);
+    r.mepc = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MEPC).physIndex);
+    r.mcause = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MCAUSE).physIndex);
+    r.mtval = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MTVAL).physIndex);
+    r.mip = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MIP).physIndex) & CSRMasks.at(CSR_MIP);
+
+    // H mode CSR (to be implemented)
 }

 void
 RemoteGDB::RiscvGdbRegCache::setRegs(ThreadContext *context) const
 {
+    // NOTE: no error will be reported for attempting to set masked bits.
+    RegVal oldVal;
+    int mask;
+    RegVal newVal;
+
     DPRINTF(GDBAcc, "setregs in remotegdb \n");
     for (int i = 0; i < NumIntArchRegs; i++)
         context->setIntReg(i, r.gpr[i]);
     context->pcState(r.pc);
+
+    // Floating point registers
+    for (int i = 0; i < NumFloatRegs; i++)
+        context->setFloatReg(i, r.fpu[i]);
+
+    oldVal = context->readMiscRegNoEffect(
+        CSRData.at(CSR_FFLAGS).physIndex);
+    mask = CSRMasks.at(CSR_FFLAGS);
+    newVal = (oldVal & ~mask) | (r.fflags & mask);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_FFLAGS).physIndex, newVal);
+
+    oldVal = context->readMiscRegNoEffect(
+        CSRData.at(CSR_FRM).physIndex);
+    mask = CSRMasks.at(CSR_FRM);
+    newVal = (oldVal & ~mask) | (r.frm & mask);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_FRM).physIndex, newVal);
+
+    oldVal = context->readMiscRegNoEffect(
+        CSRData.at(CSR_FCSR).physIndex);
+    mask = CSRMasks.at(CSR_FCSR);
+    newVal = (oldVal & ~mask) | (r.fcsr & mask);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_FCSR).physIndex, newVal);
+
+    // CSR registers
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_CYCLE).physIndex, r.cycle);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_TIME).physIndex, r.time);
+
+    // U mode CSR
+    oldVal = context->readMiscRegNoEffect(
+        CSRData.at(CSR_USTATUS).physIndex);
+    mask = CSRMasks.at(CSR_USTATUS);
+    newVal = (oldVal & ~mask) | (r.ustatus & mask);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_USTATUS).physIndex, newVal);
+    oldVal = context->readMiscRegNoEffect(
+        CSRData.at(CSR_UIE).physIndex);
+    mask = CSRMasks.at(CSR_UIE);
+    newVal = (oldVal & ~mask) | (r.uie & mask);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_UIE).physIndex, newVal);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_UTVEC).physIndex, r.utvec);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_USCRATCH).physIndex, r.uscratch);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_UEPC).physIndex, r.uepc);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_UCAUSE).physIndex, r.ucause);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_UTVAL).physIndex, r.utval);
+    oldVal = context->readMiscRegNoEffect(
+        CSRData.at(CSR_UIP).physIndex);
+    mask = CSRMasks.at(CSR_UIP);
+    newVal = (oldVal & ~mask) | (r.uip & mask);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_UIP).physIndex, newVal);
+
+    // S mode CSR
+    oldVal = context->readMiscRegNoEffect(
+        CSRData.at(CSR_SSTATUS).physIndex);
+    mask = CSRMasks.at(CSR_SSTATUS);
+    newVal = (oldVal & ~mask) | (r.sstatus & mask);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_SSTATUS).physIndex, newVal);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_SEDELEG).physIndex, r.sedeleg);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_SIDELEG).physIndex, r.sideleg);
+    oldVal = context->readMiscRegNoEffect(
+        CSRData.at(CSR_SIE).physIndex);
+    mask = CSRMasks.at(CSR_SIE);
+    newVal = (oldVal & ~mask) | (r.sie & mask);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_SIE).physIndex, newVal);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_STVEC).physIndex, r.stvec);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_SCOUNTEREN).physIndex, r.scounteren);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_SSCRATCH).physIndex, r.sscratch);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_SEPC).physIndex, r.sepc);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_SCAUSE).physIndex, r.scause);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_STVAL).physIndex, r.stval);
+    oldVal = context->readMiscRegNoEffect(
+        CSRData.at(CSR_SIP).physIndex);
+    mask = CSRMasks.at(CSR_SIP);
+    newVal = (oldVal & ~mask) | (r.sip & mask);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_SIP).physIndex, newVal);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_SATP).physIndex, r.satp);
+
+    // M mode CSR
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_MVENDORID).physIndex, r.mvendorid);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_MARCHID).physIndex, r.marchid);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_MIMPID).physIndex, r.mimpid);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_MHARTID).physIndex, r.mhartid);
+    oldVal = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MSTATUS).physIndex);
+    mask = CSRMasks.at(CSR_MSTATUS);
+    newVal = (oldVal & ~mask) | (r.mstatus & mask);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_MSTATUS).physIndex, newVal);
+    oldVal = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MISA).physIndex);
+    mask = CSRMasks.at(CSR_MISA);
+    newVal = (oldVal & ~mask) | (r.misa & mask);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_MISA).physIndex, newVal);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_MEDELEG).physIndex, r.medeleg);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_MIDELEG).physIndex, r.mideleg);
+    oldVal = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MIE).physIndex);
+    mask = CSRMasks.at(CSR_MIE);
+    newVal = (oldVal & ~mask) | (r.mie & mask);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_MIE).physIndex, newVal);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_MTVEC).physIndex, r.mtvec);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_MCOUNTEREN).physIndex, r.mcounteren);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_MSCRATCH).physIndex, r.mscratch);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_MEPC).physIndex, r.mepc);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_MCAUSE).physIndex, r.mcause);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_MTVAL).physIndex, r.mtval);
+    oldVal = context->readMiscRegNoEffect(
+        CSRData.at(CSR_MIP).physIndex);
+    mask = CSRMasks.at(CSR_MIP);
+    newVal = (oldVal & ~mask) | (r.mip & mask);
+    context->setMiscRegNoEffect(
+        CSRData.at(CSR_MIP).physIndex, newVal);
+
+    // H mode CSR (to be implemented)
 }

-BaseGdbRegCache*
+bool
+RemoteGDB::getXferFeaturesRead(const std::string &annex, std::string &output)
+{
+    /**
+     * Blobs e.g. gdb_xml_riscv_target are generated by adding
+     * GdbXml(<xml_file_name>, <blob_name>) to src/arch/riscv/Sconscript.
+     *
+     * Import using #include blobs/<blob_name>.hh
+     */
+#define GDB_XML(x, s)                                            \
+    {                                                            \
+        x, std::string(reinterpret_cast<const char *>(Blobs::s), \
+                       Blobs::s##_len)                           \
+    }
+    static const std::map<std::string, std::string> annexMap{
+        GDB_XML("target.xml", gdb_xml_riscv_target),
+        GDB_XML("riscv-64bit-cpu.xml", gdb_xml_riscv_cpu),
+        GDB_XML("riscv-64bit-fpu.xml", gdb_xml_riscv_fpu),
+        GDB_XML("riscv-64bit-csr.xml", gdb_xml_riscv_csr)};
+#undef GDB_XML
+    auto it = annexMap.find(annex);
+    if (it == annexMap.end())
+        return false;
+    output = it->second;
+    return true;
+}
+
+BaseGdbRegCache *
 RemoteGDB::gdbRegs()
 {
     return &regCache;
diff --git a/src/arch/riscv/remote_gdb.hh b/src/arch/riscv/remote_gdb.hh
index a9d3b0c..f6aa3cb 100644
--- a/src/arch/riscv/remote_gdb.hh
+++ b/src/arch/riscv/remote_gdb.hh
@@ -57,9 +57,71 @@
     {
       using BaseGdbRegCache::BaseGdbRegCache;
       private:
+        /**
+         * RISC-V Register Cache
+         * Order and sizes of registers found in ext/gdb-xml/riscv.xml
+         * To add support for more CSRs:
+         * 1. Uncomment relevant lines in ext/gdb-xml/riscv-64bit-csr.xml
+         * 2. Add register to struct below
+         * 3. Modify RiscvGdbRegCache::getRegs and setRegs
+         */
         struct {
             uint64_t gpr[NumIntArchRegs];
             uint64_t pc;
+            uint64_t fpu[NumFloatRegs];
+            uint32_t fflags;
+            uint32_t frm;
+            uint32_t fcsr;
+            // Placeholder for byte alignment
+            uint32_t placeholder;
+            uint64_t cycle;
+            uint64_t time;
+            uint64_t ustatus;
+            uint64_t uie;
+            uint64_t utvec;
+            uint64_t uscratch;
+            uint64_t uepc;
+            uint64_t ucause;
+            uint64_t utval;
+            uint64_t uip;
+            uint64_t sstatus;
+            uint64_t sedeleg;
+            uint64_t sideleg;
+            uint64_t sie;
+            uint64_t stvec;
+            uint64_t scounteren;
+            uint64_t sscratch;
+            uint64_t sepc;
+            uint64_t scause;
+            uint64_t stval;
+            uint64_t sip;
+            uint64_t satp;
+            uint64_t mvendorid;
+            uint64_t marchid;
+            uint64_t mimpid;
+            uint64_t mhartid;
+            uint64_t mstatus;
+            uint64_t misa;
+            uint64_t medeleg;
+            uint64_t mideleg;
+            uint64_t mie;
+            uint64_t mtvec;
+            uint64_t mcounteren;
+            uint64_t mscratch;
+            uint64_t mepc;
+            uint64_t mcause;
+            uint64_t mtval;
+            uint64_t mip;
+            uint64_t hstatus;
+            uint64_t hedeleg;
+            uint64_t hideleg;
+            uint64_t hie;
+            uint64_t htvec;
+            uint64_t hscratch;
+            uint64_t hepc;
+            uint64_t hcause;
+            uint64_t hbadaddr;
+            uint64_t hip;
         } r;
       public:
         char *data() const { return (char *)&r; }
@@ -79,6 +141,19 @@
   public:
     RemoteGDB(System *_system, ThreadContext *tc, int _port);
     BaseGdbRegCache *gdbRegs() override;
+    /**
+     * Informs GDB remote serial protocol that XML features are supported
+     * GDB then queries for xml blobs using qXfer:features:read:xxx.xml
+     */
+    std::vector<std::string>
+    availableFeatures() const
+    {
+        return {"qXfer:features:read+"};
+    };
+    /**
+     * Reply to qXfer:features:read:xxx.xml qeuries
+     */
+ bool getXferFeaturesRead(const std::string &annex, std::string &output);
 };

 } // namespace RiscvISA

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/38955
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Ica03b63edb3f0c9b6a7789228b995891dbfb26b2
Gerrit-Change-Number: 38955
Gerrit-PatchSet: 1
Gerrit-Owner: Peter Yuen <ppeetteer...@gmail.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to