Browse Source

Implement resume (untested).

pull/94/head
Tim Newsome 9 years ago
parent
commit
4df7f6d279
  1. 75
      riscv/debug_defines.h
  2. 15
      riscv/debug_module.cc
  3. 1
      riscv/debug_module.h
  4. 3
      riscv/opcodes.h

75
riscv/debug_defines.h

@ -28,11 +28,11 @@
#define AC_ACCESS_REGISTER_POSTEXEC_LENGTH 1
#define AC_ACCESS_REGISTER_POSTEXEC (0x1 << AC_ACCESS_REGISTER_POSTEXEC_OFFSET)
/*
* 0: Copy data from \Rdatazero into the specified register.
* 0: Copy data from {\tt arg0} portion of {\tt data} into the
* specified register.
*
* 1: Copy data from the specified register into \Rdatazero.
*
* (If XLEN is greater than 32, more {\tt data} registers are involved.)
* 1: Copy data from the specified register into {\tt arg0} portion
* of {\tt data}.
*/
#define AC_ACCESS_REGISTER_WRITE_OFFSET 16
#define AC_ACCESS_REGISTER_WRITE_LENGTH 1
@ -169,37 +169,25 @@
#define CSR_PRIV_PRV (0x3 << CSR_PRIV_PRV_OFFSET)
#define DMI_DMCONTROL 0x00
/*
* Halt request signal for the hart selected by \Fhartsel. Writes
* apply to the new value of \Fhartsel.
* Halt request signal for the hart selected by \Fhartsel. When 1, the
* hart will halt if it's not currently halted.
* Setting both \Fhaltreq and \Fresumereq leads to undefined behavior.
*
* Writes apply to the new value of \Fhartsel.
*/
#define DMI_DMCONTROL_HALTREQ_OFFSET 31
#define DMI_DMCONTROL_HALTREQ_LENGTH 1
#define DMI_DMCONTROL_HALTREQ (0x1 << DMI_DMCONTROL_HALTREQ_OFFSET)
/*
* This bit controls the reset signal from the DM to the rest of the
* system. To perform a reset the debugger writes 1, and then writes 0
* to deassert the reset.
*/
#define DMI_DMCONTROL_RESET_OFFSET 30
#define DMI_DMCONTROL_RESET_LENGTH 1
#define DMI_DMCONTROL_RESET (0x1 << DMI_DMCONTROL_RESET_OFFSET)
/*
* This bit serves as a reset signal for the Debug Module itself.
* When 0, the module is held in reset. When 1, it functions normally.
* No other mechanism should exist that may result in resetting the
* Debug Module after power up, including the platform's system reset
* or Debug Transport reset signals.
*
* A debugger should pulse this bit low to ensure that the Debug
* Module is fully reset and ready to use.
* Resume request signal for the hart selected by \Fhartsel. When 1,
* the hart will resume if it's currently halted.
* Setting both \Fhaltreq and \Fresumereq leads to undefined behavior.
*
* Implementations may use this bit to aid debugging, for example by
* preventing the Debug Module from being power gated while debugging
* is active.
* Writes apply to the new value of \Fhartsel.
*/
#define DMI_DMCONTROL_DMACTIVE_OFFSET 29
#define DMI_DMCONTROL_DMACTIVE_LENGTH 1
#define DMI_DMCONTROL_DMACTIVE (0x1 << DMI_DMCONTROL_DMACTIVE_OFFSET)
#define DMI_DMCONTROL_RESUMEREQ_OFFSET 30
#define DMI_DMCONTROL_RESUMEREQ_LENGTH 1
#define DMI_DMCONTROL_RESUMEREQ (0x1 << DMI_DMCONTROL_RESUMEREQ_OFFSET)
/*
* The status of the currently selected hart.
*
@ -221,6 +209,31 @@
#define DMI_DMCONTROL_HARTSEL_LENGTH 10
#define DMI_DMCONTROL_HARTSEL (0x3ff << DMI_DMCONTROL_HARTSEL_OFFSET)
/*
* This bit serves as a reset signal for the Debug Module itself.
* When 0, the module is held in reset. When 1, it functions normally.
* No other mechanism should exist that may result in resetting the
* Debug Module after power up, including the platform's system reset
* or Debug Transport reset signals.
*
* A debugger should pulse this bit low to ensure that the Debug
* Module is fully reset and ready to use.
*
* Implementations may use this bit to aid debugging, for example by
* preventing the Debug Module from being power gated while debugging
* is active.
*/
#define DMI_DMCONTROL_DMACTIVE_OFFSET 9
#define DMI_DMCONTROL_DMACTIVE_LENGTH 1
#define DMI_DMCONTROL_DMACTIVE (0x1 << DMI_DMCONTROL_DMACTIVE_OFFSET)
/*
* This bit controls the reset signal from the DM to the rest of the
* system. To perform a reset the debugger writes 1, and then writes 0
* to deassert the reset.
*/
#define DMI_DMCONTROL_RESET_OFFSET 8
#define DMI_DMCONTROL_RESET_LENGTH 1
#define DMI_DMCONTROL_RESET (0x1 << DMI_DMCONTROL_RESET_OFFSET)
/*
* 0 when authentication is required before using the DM. 1 when the
* authentication check has passed. On components that don't implement
* authentication, this bit must be preset as 1.
@ -450,8 +463,10 @@
*
* 3: There was some other error (eg. alignment).
*
* 4: The system bus master was busy when a one of the {\tt sbaddress} or
* {\tt sbdata} registers was written.
* 4: The system bus master was busy when a one of the
* {\tt sbaddress} or {\tt sbdata} registers was written,
* or the {\tt sbdata} register was read when it had
* stale data.
*/
#define DMI_SBCS_SBERROR_OFFSET 12
#define DMI_SBCS_SBERROR_LENGTH 3

15
riscv/debug_module.cc

@ -111,7 +111,7 @@ void debug_module_t::add_device(bus_t *bus) {
bool debug_module_t::load(reg_t addr, size_t len, uint8_t* bytes)
{
D(fprintf(stderr, "load 0x%lx bytes at 0x%lx\n",
D(fprintf(stderr, "debug_module_t load 0x%lx bytes at 0x%lx\n",
len, addr));
addr = DEBUG_START + addr;
@ -140,6 +140,12 @@ bool debug_module_t::load(reg_t addr, size_t len, uint8_t* bytes)
if (addr >= DEBUG_ROM_CODE &&
addr < DEBUG_ROM_CODE + DEBUG_ROM_CODE_SIZE) {
if (read32(debug_rom_code, 0) == dret()) {
abstractcs.busy = false;
halted[dmcontrol.hartsel] = false;
}
memcpy(bytes, debug_rom_code + addr - DEBUG_ROM_CODE, len);
return true;
}
@ -363,6 +369,7 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value)
dmcontrol.dmactive = get_field(value, DMI_DMCONTROL_DMACTIVE);
if (dmcontrol.dmactive) {
dmcontrol.haltreq = get_field(value, DMI_DMCONTROL_HALTREQ);
dmcontrol.resumereq = get_field(value, DMI_DMCONTROL_RESUMEREQ);
dmcontrol.reset = get_field(value, DMI_DMCONTROL_RESET);
dmcontrol.hartsel = get_field(value, DMI_DMCONTROL_HARTSEL);
} else {
@ -371,6 +378,12 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value)
processor_t *proc = current_proc();
if (proc) {
proc->halt_request = dmcontrol.haltreq;
if (dmcontrol.resumereq) {
write32(debug_rom_code, 0, dret());
write32(debug_rom_entry, dmcontrol.hartsel,
jal(ZERO, DEBUG_ROM_CODE - (DEBUG_ROM_ENTRY + 4 * dmcontrol.hartsel)));
abstractcs.busy = true;
}
}
}
return true;

1
riscv/debug_module.h

@ -10,6 +10,7 @@ class sim_t;
typedef struct {
bool haltreq;
bool resumereq;
bool reset;
bool dmactive;
enum {

3
riscv/opcodes.h

@ -168,6 +168,9 @@ static uint32_t ebreak(void) { return MATCH_EBREAK; }
static uint32_t ebreak_c(void) __attribute__ ((unused));
static uint32_t ebreak_c(void) { return MATCH_C_EBREAK; }
static uint32_t dret(void) __attribute__ ((unused));
static uint32_t dret(void) { return MATCH_DRET; }
static uint32_t fence_i(void) __attribute__ ((unused));
static uint32_t fence_i(void)
{

Loading…
Cancel
Save