X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=riscv%2Fdebug_module.cc;h=1d184781495c3a94db14546d3a9f3c6f9ee8e775;hb=d3d3681f3468c633bc93a727a35bc07348245440;hp=cbc8c48f5f994af07ef0da4be3ef494a42b6ac45;hpb=46a67860915391458d7cc8cb93248059df20b8f2;p=riscv-isa-sim.git diff --git a/riscv/debug_module.cc b/riscv/debug_module.cc index cbc8c48..1d18478 100644 --- a/riscv/debug_module.cc +++ b/riscv/debug_module.cc @@ -16,37 +16,31 @@ ///////////////////////// debug_module_t -debug_module_t::debug_module_t(sim_t *sim, unsigned progsize) : - progsize(progsize), - program_buffer_bytes(4 + 4*progsize), +debug_module_t::debug_module_t(sim_t *sim, unsigned progbufsize) : + progbufsize(progbufsize), + program_buffer_bytes(4 + 4*progbufsize), debug_progbuf_start(debug_data_start - program_buffer_bytes), debug_abstract_start(debug_progbuf_start - debug_abstract_size*4), sim(sim) { - dmcontrol = {0}; - - dmstatus = {0}; - dmstatus.authenticated = 1; - dmstatus.versionlo = 2; - - abstractcs = {0}; - abstractcs.progsize = progsize; - - abstractauto = {0}; - program_buffer = new uint8_t[program_buffer_bytes]; memset(halted, 0, sizeof(halted)); memset(debug_rom_flags, 0, sizeof(debug_rom_flags)); memset(resumeack, 0, sizeof(resumeack)); memset(program_buffer, 0, program_buffer_bytes); - program_buffer[progsize] = ebreak(); + program_buffer[4*progbufsize] = ebreak(); + program_buffer[4*progbufsize+1] = ebreak() >> 8; + program_buffer[4*progbufsize+2] = ebreak() >> 16; + program_buffer[4*progbufsize+3] = ebreak() >> 24; memset(dmdata, 0, sizeof(dmdata)); write32(debug_rom_whereto, 0, jal(ZERO, debug_abstract_start - DEBUG_ROM_WHERETO)); memset(debug_abstract, 0, sizeof(debug_abstract)); + + reset(); } debug_module_t::~debug_module_t() @@ -65,14 +59,23 @@ void debug_module_t::reset() dmcontrol = {0}; dmstatus = {0}; + dmstatus.impebreak = true; dmstatus.authenticated = 1; - dmstatus.versionlo = 2; + dmstatus.version = 2; abstractcs = {0}; abstractcs.datacount = sizeof(dmdata) / 4; - abstractcs.progsize = progsize; + abstractcs.progbufsize = progbufsize; abstractauto = {0}; + + sbcs = {0}; + sbcs.version = 1; + sbcs.access64 = true; + sbcs.access32 = true; + sbcs.access16 = true; + sbcs.access8 = true; + sbcs.asize = sizeof(reg_t) * 8; } void debug_module_t::add_device(bus_t *bus) { @@ -223,6 +226,87 @@ processor_t *debug_module_t::current_proc() const return proc; } +unsigned debug_module_t::sb_access_bits() +{ + return 8 << sbcs.sbaccess; +} + +void debug_module_t::sb_autoincrement() +{ + if (!sbcs.autoincrement) + return; + + uint64_t value = sbaddress[0] + sb_access_bits() / 8; + sbaddress[0] = value; + uint32_t carry = value >> 32; + + value = sbaddress[1] + carry; + sbaddress[1] = value; + carry = value >> 32; + + value = sbaddress[2] + carry; + sbaddress[2] = value; + carry = value >> 32; + + sbaddress[3] += carry; +} + +void debug_module_t::sb_read() +{ + reg_t address = ((uint64_t) sbaddress[1] << 32) | sbaddress[0]; + D(fprintf(stderr, "sb_read() @ 0x%lx\n", address)); + try { + switch (sbcs.sbaccess) { + case 0: + sbdata[0] = sim->debug_mmu->load_uint8(address); + break; + case 1: + sbdata[0] = sim->debug_mmu->load_uint16(address); + break; + case 2: + sbdata[0] = sim->debug_mmu->load_uint32(address); + D(fprintf(stderr, " -> 0x%x\n", sbdata[0])); + break; + case 3: + { + uint64_t value = sim->debug_mmu->load_uint32(address); + sbdata[0] = value; + sbdata[1] = value >> 32; + break; + } + default: + sbcs.error = 3; + break; + } + } catch (trap_load_access_fault& t) { + sbcs.error = 2; + } +} + +void debug_module_t::sb_write() +{ + reg_t address = ((uint64_t) sbaddress[1] << 32) | sbaddress[0]; + D(fprintf(stderr, "sb_write() 0x%x @ 0x%lx\n", sbdata[0], address)); + switch (sbcs.sbaccess) { + case 0: + sim->debug_mmu->store_uint8(address, sbdata[0]); + break; + case 1: + sim->debug_mmu->store_uint16(address, sbdata[0]); + break; + case 2: + sim->debug_mmu->store_uint32(address, sbdata[0]); + break; + case 3: + sim->debug_mmu->store_uint64(address, + (((uint64_t) sbdata[1]) << 32) | sbdata[0]); + break; + default: + sbcs.error = 3; + break; + } +} + bool debug_module_t::dmi_read(unsigned address, uint32_t *value) { uint32_t result = 0; @@ -242,7 +326,7 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value) if (!abstractcs.busy && ((abstractauto.autoexecdata >> i) & 1)) { perform_abstract_command(); } - } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + progsize) { + } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + progbufsize) { unsigned i = address - DMI_PROGBUF0; result = read32(program_buffer, i); if (abstractcs.busy) { @@ -263,7 +347,8 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value) result = set_field(result, DMI_DMCONTROL_HALTREQ, dmcontrol.haltreq); result = set_field(result, DMI_DMCONTROL_RESUMEREQ, dmcontrol.resumereq); - result = set_field(result, DMI_DMCONTROL_HARTSEL, dmcontrol.hartsel); + result = set_field(result, ((1L<= DMI_PROGBUF0 && address < DMI_PROGBUF0 + progsize) { + } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + progbufsize) { unsigned i = address - DMI_PROGBUF0; if (!abstractcs.busy) @@ -455,15 +586,16 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value) switch (address) { case DMI_DMCONTROL: { + if (!dmcontrol.dmactive && get_field(value, DMI_DMCONTROL_DMACTIVE)) + reset(); 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.hartreset = get_field(value, DMI_DMCONTROL_HARTRESET); dmcontrol.ndmreset = get_field(value, DMI_DMCONTROL_NDMRESET); - dmcontrol.hartsel = get_field(value, DMI_DMCONTROL_HARTSEL); - } else { - reset(); + dmcontrol.hartsel = get_field(value, ((1L<