From 2e07ac8d71cc7b61bba521711c902bf78a283778 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Tue, 11 Apr 2023 11:20:20 -0700 Subject: Add debug_defines.h to list of installed headers --- riscv/riscv.mk.in | 1 + 1 file changed, 1 insertion(+) diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in index f1b29aa..561e197 100644 --- a/riscv/riscv.mk.in +++ b/riscv/riscv.mk.in @@ -20,6 +20,7 @@ riscv_install_hdrs = \ cfg.h \ common.h \ csrs.h \ + debug_defines.h \ debug_module.h \ debug_rom_defines.h \ decode.h \ -- cgit v1.1 From cf5d11c98785a5c404f2303dbb243c6825cc98b7 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Tue, 11 Apr 2023 11:22:07 -0700 Subject: Unify fesvr/debug_defines.h and riscv/debug_defines.h * fesvr/debug_defines.h is removed --- fesvr/debug_defines.h | 1418 ------------------------------------------------- fesvr/dtm.cc | 120 ++--- 2 files changed, 60 insertions(+), 1478 deletions(-) delete mode 100644 fesvr/debug_defines.h diff --git a/fesvr/debug_defines.h b/fesvr/debug_defines.h deleted file mode 100644 index e5f9291..0000000 --- a/fesvr/debug_defines.h +++ /dev/null @@ -1,1418 +0,0 @@ -#define DTM_IDCODE 0x01 -/* -* Identifies the release version of this part. - */ -#define DTM_IDCODE_VERSION_OFFSET 28 -#define DTM_IDCODE_VERSION_LENGTH 4 -#define DTM_IDCODE_VERSION (0xf << DTM_IDCODE_VERSION_OFFSET) -/* -* Identifies the designer's part number of this part. - */ -#define DTM_IDCODE_PARTNUMBER_OFFSET 12 -#define DTM_IDCODE_PARTNUMBER_LENGTH 16 -#define DTM_IDCODE_PARTNUMBER (0xffff << DTM_IDCODE_PARTNUMBER_OFFSET) -/* -* Identifies the designer/manufacturer of this part. Bits 6:0 must be -* bits 6:0 of the designer/manufacturer's Identification Code as -* assigned by JEDEC Standard JEP106. Bits 10:7 contain the modulo-16 -* count of the number of continuation characters (0x7f) in that same -* Identification Code. - */ -#define DTM_IDCODE_MANUFID_OFFSET 1 -#define DTM_IDCODE_MANUFID_LENGTH 11 -#define DTM_IDCODE_MANUFID (0x7ff << DTM_IDCODE_MANUFID_OFFSET) -#define DTM_IDCODE_1_OFFSET 0 -#define DTM_IDCODE_1_LENGTH 1 -#define DTM_IDCODE_1 (0x1 << DTM_IDCODE_1_OFFSET) -#define DTM_DTMCS 0x10 -/* -* Writing 1 to this bit does a hard reset of the DTM, -* causing the DTM to forget about any outstanding DMI transactions. -* In general this should only be used when the Debugger has -* reason to expect that the outstanding DMI transaction will never -* complete (e.g. a reset condition caused an inflight DMI transaction to -* be cancelled). - */ -#define DTM_DTMCS_DMIHARDRESET_OFFSET 17 -#define DTM_DTMCS_DMIHARDRESET_LENGTH 1 -#define DTM_DTMCS_DMIHARDRESET (0x1 << DTM_DTMCS_DMIHARDRESET_OFFSET) -/* -* Writing 1 to this bit clears the sticky error state -* and allows the DTM to retry or complete the previous -* transaction. - */ -#define DTM_DTMCS_DMIRESET_OFFSET 16 -#define DTM_DTMCS_DMIRESET_LENGTH 1 -#define DTM_DTMCS_DMIRESET (0x1 << DTM_DTMCS_DMIRESET_OFFSET) -/* -* This is a hint to the debugger of the minimum number of -* cycles a debugger should spend in -* Run-Test/Idle after every DMI scan to avoid a `busy' -* return code (\Fdmistat of 3). A debugger must still -* check \Fdmistat when necessary. -* -* 0: It is not necessary to enter Run-Test/Idle at all. -* -* 1: Enter Run-Test/Idle and leave it immediately. -* -* 2: Enter Run-Test/Idle and stay there for 1 cycle before leaving. -* -* And so on. - */ -#define DTM_DTMCS_IDLE_OFFSET 12 -#define DTM_DTMCS_IDLE_LENGTH 3 -#define DTM_DTMCS_IDLE (0x7 << DTM_DTMCS_IDLE_OFFSET) -/* -* 0: No error. -* -* 1: Reserved. Interpret the same as 2. -* -* 2: An operation failed (resulted in \Fop of 2). -* -* 3: An operation was attempted while a DMI access was still in -* progress (resulted in \Fop of 3). - */ -#define DTM_DTMCS_DMISTAT_OFFSET 10 -#define DTM_DTMCS_DMISTAT_LENGTH 2 -#define DTM_DTMCS_DMISTAT (0x3 << DTM_DTMCS_DMISTAT_OFFSET) -/* -* The size of \Faddress in \Rdmi. - */ -#define DTM_DTMCS_ABITS_OFFSET 4 -#define DTM_DTMCS_ABITS_LENGTH 6 -#define DTM_DTMCS_ABITS (0x3f << DTM_DTMCS_ABITS_OFFSET) -/* -* 0: Version described in spec version 0.11. -* -* 1: Version described in spec version 0.13 (and later?), which -* reduces the DMI data width to 32 bits. -* -* Other values are reserved for future use. - */ -#define DTM_DTMCS_VERSION_OFFSET 0 -#define DTM_DTMCS_VERSION_LENGTH 4 -#define DTM_DTMCS_VERSION (0xf << DTM_DTMCS_VERSION_OFFSET) -#define DTM_DMI 0x11 -/* -* Address used for DMI access. In Update-DR this value is used -* to access the DM over the DMI. - */ -#define DTM_DMI_ADDRESS_OFFSET 34 -#define DTM_DMI_ADDRESS_LENGTH abits -#define DTM_DMI_ADDRESS (((1L< #include #include @@ -37,7 +37,7 @@ #define S1 9 #define AC_AR_REGNO(x) ((0x1000 | x) << AC_ACCESS_REGISTER_REGNO_OFFSET) -#define AC_AR_SIZE(x) (((x == 128)? 4 : (x == 64 ? 3 : 2)) << AC_ACCESS_REGISTER_SIZE_OFFSET) +#define AC_AR_SIZE(x) (((x == 128)? 4 : (x == 64 ? 3 : 2)) << AC_ACCESS_REGISTER_AARSIZE_OFFSET) #define WRITE 1 #define SET 2 @@ -75,22 +75,22 @@ void dtm_t::nop() } void dtm_t::select_hart(int hartsel) { - int dmcontrol = read(DMI_DMCONTROL); - write (DMI_DMCONTROL, set_field(dmcontrol, DMI_DMCONTROL_HARTSEL, hartsel)); + int dmcontrol = read(DM_DMCONTROL); + write (DM_DMCONTROL, set_field(dmcontrol, DM_DMCONTROL_HASEL, hartsel)); current_hart = hartsel; } int dtm_t::enumerate_harts() { - int max_hart = (1 << DMI_DMCONTROL_HARTSEL_LENGTH) - 1; - write(DMI_DMCONTROL, set_field(read(DMI_DMCONTROL), DMI_DMCONTROL_HARTSEL, max_hart)); - read(DMI_DMSTATUS); - max_hart = get_field(read(DMI_DMCONTROL), DMI_DMCONTROL_HARTSEL); + int max_hart = (1 << DM_DMCONTROL_HASEL_LENGTH) - 1; + write(DM_DMCONTROL, set_field(read(DM_DMCONTROL), DM_DMCONTROL_HASEL, max_hart)); + read(DM_DMSTATUS); + max_hart = get_field(read(DM_DMCONTROL), DM_DMCONTROL_HASEL); int hartsel; for (hartsel = 0; hartsel <= max_hart; hartsel++) { select_hart(hartsel); - int dmstatus = read(DMI_DMSTATUS); - if (get_field(dmstatus, DMI_DMSTATUS_ANYNONEXISTENT)) + int dmstatus = read(DM_DMSTATUS); + if (get_field(dmstatus, DM_DMSTATUS_ANYNONEXISTENT)) break; } return hartsel; @@ -99,44 +99,44 @@ int dtm_t::enumerate_harts() { void dtm_t::halt(int hartsel) { if (running) { - write(DMI_DMCONTROL, DMI_DMCONTROL_DMACTIVE); + write(DM_DMCONTROL, DM_DMCONTROL_DMACTIVE); // Read dmstatus to avoid back-to-back writes to dmcontrol. - read(DMI_DMSTATUS); + read(DM_DMSTATUS); } - int dmcontrol = DMI_DMCONTROL_HALTREQ | DMI_DMCONTROL_DMACTIVE; - dmcontrol = set_field(dmcontrol, DMI_DMCONTROL_HARTSEL, hartsel); - write(DMI_DMCONTROL, dmcontrol); + int dmcontrol = DM_DMCONTROL_HALTREQ | DM_DMCONTROL_DMACTIVE; + dmcontrol = set_field(dmcontrol, DM_DMCONTROL_HASEL, hartsel); + write(DM_DMCONTROL, dmcontrol); int dmstatus; do { - dmstatus = read(DMI_DMSTATUS); - } while(get_field(dmstatus, DMI_DMSTATUS_ALLHALTED) == 0); - dmcontrol &= ~DMI_DMCONTROL_HALTREQ; - write(DMI_DMCONTROL, dmcontrol); + dmstatus = read(DM_DMSTATUS); + } while(get_field(dmstatus, DM_DMSTATUS_ALLHALTED) == 0); + dmcontrol &= ~DM_DMCONTROL_HALTREQ; + write(DM_DMCONTROL, dmcontrol); // Read dmstatus to avoid back-to-back writes to dmcontrol. - read(DMI_DMSTATUS); + read(DM_DMSTATUS); current_hart = hartsel; } void dtm_t::resume(int hartsel) { - int dmcontrol = DMI_DMCONTROL_RESUMEREQ | DMI_DMCONTROL_DMACTIVE; - dmcontrol = set_field(dmcontrol, DMI_DMCONTROL_HARTSEL, hartsel); - write(DMI_DMCONTROL, dmcontrol); + int dmcontrol = DM_DMCONTROL_RESUMEREQ | DM_DMCONTROL_DMACTIVE; + dmcontrol = set_field(dmcontrol, DM_DMCONTROL_HASEL, hartsel); + write(DM_DMCONTROL, dmcontrol); int dmstatus; do { - dmstatus = read(DMI_DMSTATUS); - } while (get_field(dmstatus, DMI_DMSTATUS_ALLRESUMEACK) == 0); - dmcontrol &= ~DMI_DMCONTROL_RESUMEREQ; - write(DMI_DMCONTROL, dmcontrol); + dmstatus = read(DM_DMSTATUS); + } while (get_field(dmstatus, DM_DMSTATUS_ALLRESUMEACK) == 0); + dmcontrol &= ~DM_DMCONTROL_RESUMEREQ; + write(DM_DMCONTROL, dmcontrol); // Read dmstatus to avoid back-to-back writes to dmcontrol. - read(DMI_DMSTATUS); + read(DM_DMSTATUS); current_hart = hartsel; if (running) { - write(DMI_DMCONTROL, DMI_DMCONTROL_DMACTIVE); + write(DM_DMCONTROL, DM_DMCONTROL_DMACTIVE); // Read dmstatus to avoid back-to-back writes to dmcontrol. - read(DMI_DMSTATUS); + read(DM_DMSTATUS); } } @@ -178,32 +178,32 @@ uint32_t dtm_t::run_abstract_command(uint32_t command, assert(data_n <= data_words); for (size_t i = 0; i < program_n; i++) { - write(DMI_PROGBUF0 + i, program[i]); + write(DM_PROGBUF0 + i, program[i]); } if (get_field(command, AC_ACCESS_REGISTER_WRITE) && get_field(command, AC_ACCESS_REGISTER_TRANSFER)) { for (size_t i = 0; i < data_n; i++) { - write(DMI_DATA0 + i, data[i]); + write(DM_DATA0 + i, data[i]); } } - write(DMI_COMMAND, command); + write(DM_COMMAND, command); // Wait for not busy and then check for error. uint32_t abstractcs; do { - abstractcs = read(DMI_ABSTRACTCS); - } while (abstractcs & DMI_ABSTRACTCS_BUSY); + abstractcs = read(DM_ABSTRACTCS); + } while (abstractcs & DM_ABSTRACTCS_BUSY); if ((get_field(command, AC_ACCESS_REGISTER_WRITE) == 0) && get_field(command, AC_ACCESS_REGISTER_TRANSFER)) { for (size_t i = 0; i < data_n; i++){ - data[i] = read(DMI_DATA0 + i); + data[i] = read(DM_DATA0 + i); } } - return get_field(abstractcs, DMI_ABSTRACTCS_CMDERR); + return get_field(abstractcs, DM_ABSTRACTCS_CMDERR); } @@ -313,24 +313,24 @@ void dtm_t::write_chunk(uint64_t taddr, size_t len, const void* src) uint32_t abstractcs; for (size_t i = 1; i < (len * 8 / xlen); i++){ if (i == 1) { - write(DMI_ABSTRACTAUTO, 1 << DMI_ABSTRACTAUTO_AUTOEXECDATA_OFFSET); + write(DM_ABSTRACTAUTO, 1 << DM_ABSTRACTAUTO_AUTOEXECDATA_OFFSET); } memcpy(data, curr, xlen/8); curr += xlen/8; if (xlen == 64) { - write(DMI_DATA0 + 1, data[1]); + write(DM_DATA0 + 1, data[1]); } - write(DMI_DATA0, data[0]); //Triggers a command w/ autoexec. + write(DM_DATA0, data[0]); //Triggers a command w/ autoexec. do { - abstractcs = read(DMI_ABSTRACTCS); - } while (abstractcs & DMI_ABSTRACTCS_BUSY); - if ( get_field(abstractcs, DMI_ABSTRACTCS_CMDERR)) { - die(get_field(abstractcs, DMI_ABSTRACTCS_CMDERR)); + abstractcs = read(DM_ABSTRACTCS); + } while (abstractcs & DM_ABSTRACTCS_BUSY); + if ( get_field(abstractcs, DM_ABSTRACTCS_CMDERR)) { + die(get_field(abstractcs, DM_ABSTRACTCS_CMDERR)); } } if ((len * 8 / xlen) > 1) { - write(DMI_ABSTRACTAUTO, 0); + write(DM_ABSTRACTAUTO, 0); } restore_reg(S0, s0); @@ -356,7 +356,7 @@ void dtm_t::die(uint32_t cmderr) //throw std::runtime_error("Debug Abstract Command Error #" + std::to_string(cmderr) + "(" + msg + ")"); printf("ERROR: %s:%d, Debug Abstract Command Error #%d (%s)", __FILE__, __LINE__, cmderr, msg); printf("ERROR: %s:%d, Should die, but allowing simulation to continue and fail.", __FILE__, __LINE__); - write(DMI_ABSTRACTCS, DMI_ABSTRACTCS_CMDERR); + write(DM_ABSTRACTCS, DM_ABSTRACTCS_CMDERR); } @@ -454,9 +454,9 @@ uint64_t dtm_t::modify_csr(unsigned which, uint64_t data, uint32_t type) RUN_AC_OR_DIE(command, prog, sizeof(prog) / sizeof(*prog), adata, xlen/(4*8)); - uint64_t res = read(DMI_DATA0);//adata[0]; + uint64_t res = read(DM_DATA0);//adata[0]; if (xlen == 64) - res |= read(DMI_DATA0 + 1);//((uint64_t) adata[1]) << 32; + res |= read(DM_DATA0 + 1);//((uint64_t) adata[1]) << 32; resume(current_hart); return res; @@ -486,13 +486,13 @@ uint32_t dtm_t::get_xlen() abort(); return 128; } - write(DMI_ABSTRACTCS, DMI_ABSTRACTCS_CMDERR); + write(DM_ABSTRACTCS, DM_ABSTRACTCS_CMDERR); cmderr = run_abstract_command(command | AC_AR_SIZE(64), prog, 0, data, 0); if (cmderr == 0){ return 64; } - write(DMI_ABSTRACTCS, DMI_ABSTRACTCS_CMDERR); + write(DM_ABSTRACTCS, DM_ABSTRACTCS_CMDERR); cmderr = run_abstract_command(command | AC_AR_SIZE(32), prog, 0, data, 0); if (cmderr == 0){ @@ -541,7 +541,7 @@ void dtm_t::reset() // In theory any hart can handle the memory accesses, // this will enforce that hart 0 handles them. select_hart(0); - read(DMI_DMSTATUS); + read(DM_DMSTATUS); } void dtm_t::idle() @@ -556,23 +556,23 @@ void dtm_t::producer_thread() // depend on in this code. // Enable the debugger. - write(DMI_DMCONTROL, DMI_DMCONTROL_DMACTIVE); + write(DM_DMCONTROL, DM_DMCONTROL_DMACTIVE); // Poll until the debugger agrees it's enabled. - while ((read(DMI_DMCONTROL) & DMI_DMCONTROL_DMACTIVE) == 0) ; + while ((read(DM_DMCONTROL) & DM_DMCONTROL_DMACTIVE) == 0) ; // These are checked every time we run an abstract command. - uint32_t abstractcs = read(DMI_ABSTRACTCS); - ram_words = get_field(abstractcs, DMI_ABSTRACTCS_PROGSIZE); - data_words = get_field(abstractcs, DMI_ABSTRACTCS_DATACOUNT); + uint32_t abstractcs = read(DM_ABSTRACTCS); + ram_words = get_field(abstractcs, DM_ABSTRACTCS_PROGBUFSIZE); + data_words = get_field(abstractcs, DM_ABSTRACTCS_DATACOUNT); // These things are only needed for the 'modify_csr' function. // That could be re-written to not use these at some performance // overhead. - uint32_t hartinfo = read(DMI_HARTINFO); - assert(get_field(hartinfo, DMI_HARTINFO_NSCRATCH) > 0); - assert(get_field(hartinfo, DMI_HARTINFO_DATAACCESS)); + uint32_t hartinfo = read(DM_HARTINFO); + assert(get_field(hartinfo, DM_HARTINFO_NSCRATCH) > 0); + assert(get_field(hartinfo, DM_HARTINFO_DATAACCESS)); - data_base = get_field(hartinfo, DMI_HARTINFO_DATAADDR); + data_base = get_field(hartinfo, DM_HARTINFO_DATAADDR); num_harts = enumerate_harts(); halt(0); -- cgit v1.1 From 7470633c425c2385685f369a8ca9f2c3a629f494 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Wed, 12 Apr 2023 00:48:21 -0700 Subject: Make some dtm_t interfaces protected * This enables useful functionality in inheritors --- fesvr/dtm.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/fesvr/dtm.h b/fesvr/dtm.h index fbf161e..1f5ee3e 100644 --- a/fesvr/dtm.h +++ b/fesvr/dtm.h @@ -64,6 +64,16 @@ class dtm_t : public htif_t virtual void reset() override; virtual void idle() override; + uint32_t run_abstract_command(uint32_t command, const uint32_t program[], size_t program_n, + uint32_t data[], size_t data_n); + + void die(uint32_t cmderr); + void halt(int); + int enumerate_harts(); + void select_hart(int); + void resume(int); + uint32_t get_data_base() { return data_base; }; + private: context_t host; context_t* target; @@ -76,14 +86,6 @@ class dtm_t : public htif_t resp resp_buf; bool running; - uint32_t run_abstract_command(uint32_t command, const uint32_t program[], size_t program_n, - uint32_t data[], size_t data_n); - - void die(uint32_t cmderr); - void halt(int); - int enumerate_harts(); - void select_hart(int); - void resume(int); uint64_t save_reg(unsigned regno); void restore_reg(unsigned regno, uint64_t val); -- cgit v1.1