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
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/38955
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Peter Yuen
2021-01-12 00:38:23 +08:00
parent 9c7cc711bc
commit d1933d9ce7
7 changed files with 740 additions and 2 deletions

View File

@@ -0,0 +1,48 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2018-2019 Free Software Foundation, Inc.
Contributed by Huawei International
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>

View File

@@ -0,0 +1,248 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2018-2019 Free Software Foundation, Inc.
Contributed by Huawei International
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>

View File

@@ -0,0 +1,58 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2018-2019 Free Software Foundation, Inc.
Contributed by Huawei International
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>

13
ext/gdb-xml/riscv.xml Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2009-2013 Free Software Foundation, Inc.
Contributed by Huawei International
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>

View File

@@ -3,6 +3,7 @@
# Copyright (c) 2013 ARM Limited
# Copyright (c) 2014 Sven Karlsson
# Copyright (c) 2020 Barkhausen Institut
# Copyright (c) 2021 Huawei International
# All rights reserved
#
# The license below extends only to copyright in the software and shall
@@ -73,3 +74,8 @@ if env['TARGET_ISA'] == 'riscv':
# 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')

View File

@@ -1,4 +1,5 @@
/*
* Copyright (c) 2021 Huawei International
* Copyright 2015 LabWare
* Copyright 2014 Google, Inc.
* Copyright (c) 2010 ARM Limited
@@ -137,6 +138,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 +171,7 @@ RemoteGDB::acc(Addr va, size_t len)
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 +185,304 @@ void
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;

View File

@@ -1,4 +1,5 @@
/*
* Copyright (c) 2021 Huawei International
* Copyright (c) 2017 The University of Virginia
* Copyright 2015 LabWare
* Copyright 2014 Google, Inc.
@@ -57,9 +58,71 @@ class RemoteGDB : public BaseRemoteGDB
{
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 +142,19 @@ class RemoteGDB : public BaseRemoteGDB
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