From: Tim Newsome Date: Thu, 16 Feb 2017 03:05:20 +0000 (-0800) Subject: Implement autoexec. DMI op 2 is just write now. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f88504000a7c7a16685dc59bdbb9be314a35d0b2;p=riscv-isa-sim.git Implement autoexec. DMI op 2 is just write now. Now passing MemTest{8,16,32,64} --- diff --git a/riscv/debug_module.cc b/riscv/debug_module.cc index df3f1f9..8d93e9e 100644 --- a/riscv/debug_module.cc +++ b/riscv/debug_module.cc @@ -218,7 +218,23 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value) uint32_t result = 0; D(fprintf(stderr, "dmi_read(0x%x) -> ", address)); if (address >= DMI_DATA0 && address < DMI_DATA0 + abstractcs.datacount) { - result = dmdata.read32(4 * (address - DMI_DATA0)); + unsigned i = address - DMI_DATA0; + result = dmdata.read32(4 * i); + + bool autoexec = false; + switch (i) { + case 0: autoexec = abstractcs.autoexec0; break; + case 1: autoexec = abstractcs.autoexec1; break; + case 2: autoexec = abstractcs.autoexec2; break; + case 3: autoexec = abstractcs.autoexec3; break; + case 4: autoexec = abstractcs.autoexec4; break; + case 5: autoexec = abstractcs.autoexec5; break; + case 6: autoexec = abstractcs.autoexec6; break; + case 7: autoexec = abstractcs.autoexec7; break; + } + if (autoexec) { + perform_abstract_command(); + } } else if (address >= DMI_IBUF0 && address < DMI_IBUF0 + progsize) { result = read32(program_buffer, address - DMI_IBUF0); } else { @@ -276,7 +292,7 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value) return true; } -bool debug_module_t::perform_abstract_command(uint32_t command) +bool debug_module_t::perform_abstract_command() { if (abstractcs.cmderr != abstractcs.CMDERR_NONE) return true; @@ -357,8 +373,25 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value) { D(fprintf(stderr, "dmi_write(0x%x, 0x%x)\n", address, value)); if (address >= DMI_DATA0 && address < DMI_DATA0 + abstractcs.datacount) { - dmdata.write32(4 * (address - DMI_DATA0), value); + unsigned i = address - DMI_DATA0; + dmdata.write32(4 * i, value); + + bool autoexec = false; + switch (i) { + case 0: autoexec = abstractcs.autoexec0; break; + case 1: autoexec = abstractcs.autoexec1; break; + case 2: autoexec = abstractcs.autoexec2; break; + case 3: autoexec = abstractcs.autoexec3; break; + case 4: autoexec = abstractcs.autoexec4; break; + case 5: autoexec = abstractcs.autoexec5; break; + case 6: autoexec = abstractcs.autoexec6; break; + case 7: autoexec = abstractcs.autoexec7; break; + } + if (autoexec) { + perform_abstract_command(); + } return true; + } else if (address >= DMI_IBUF0 && address < DMI_IBUF0 + progsize) { write32(program_buffer, address - DMI_IBUF0, value); return true; @@ -389,7 +422,8 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value) return true; case DMI_COMMAND: - return perform_abstract_command(value); + command = value; + return perform_abstract_command(); case DMI_ABSTRACTCS: abstractcs.autoexec7 = get_field(value, DMI_ABSTRACTCS_AUTOEXEC7); diff --git a/riscv/debug_module.h b/riscv/debug_module.h index 7d9b3aa..76bcf01 100644 --- a/riscv/debug_module.h +++ b/riscv/debug_module.h @@ -126,10 +126,11 @@ class debug_module_t : public abstract_device_t dmcontrol_t dmcontrol; abstractcs_t abstractcs; + uint32_t command; processor_t *current_proc() const; void reset(); - bool perform_abstract_command(uint32_t command); + bool perform_abstract_command(); }; #endif diff --git a/riscv/jtag_dtm.cc b/riscv/jtag_dtm.cc index 84f13f8..84182bb 100644 --- a/riscv/jtag_dtm.cc +++ b/riscv/jtag_dtm.cc @@ -34,8 +34,8 @@ enum { #define DMI_OP_NOP 0 #define DMI_OP_READ 1 -#define DMI_OP_READ_WRITE 2 -#define DMI_OP_RESERVED 3 +#define DMI_OP_WRITE 2 +#define DMI_OP_RESERVED 3 jtag_dtm_t::jtag_dtm_t(debug_module_t *dm) : dm(dm), @@ -159,15 +159,14 @@ void jtag_dtm_t::update_dr() dmi = dr; bool success = true; - if (op == DMI_OP_READ || op == DMI_OP_READ_WRITE) { + if (op == DMI_OP_READ) { uint32_t value; if (dm->dmi_read(address, &value)) { dmi = set_field(dmi, DMI_DATA, value); } else { success = false; } - } - if (success && op == DMI_OP_READ_WRITE) { + } else if (op == DMI_OP_WRITE) { success = dm->dmi_write(address, data); }