diff --git a/core_debug.vhdl b/core_debug.vhdl index 9efaa7c..09e3e48 100644 --- a/core_debug.vhdl +++ b/core_debug.vhdl @@ -91,6 +91,7 @@ architecture behave of core_debug is -- Log buffer address and data registers constant DBG_CORE_LOG_ADDR : std_ulogic_vector(3 downto 0) := "0110"; constant DBG_CORE_LOG_DATA : std_ulogic_vector(3 downto 0) := "0111"; + constant DBG_CORE_LOG_TRIGGER : std_ulogic_vector(3 downto 0) := "1000"; constant LOG_INDEX_BITS : natural := log2(LOG_LENGTH); @@ -108,6 +109,8 @@ architecture behave of core_debug is signal log_dmi_addr : std_ulogic_vector(31 downto 0) := (others => '0'); signal log_dmi_data : std_ulogic_vector(63 downto 0) := (others => '0'); + signal log_dmi_trigger : std_ulogic_vector(63 downto 0) := (others => '0'); + signal do_log_trigger : std_ulogic := '0'; signal do_dmi_log_rd : std_ulogic; signal dmi_read_log_data : std_ulogic; signal dmi_read_log_data_1 : std_ulogic; @@ -133,6 +136,7 @@ begin dbg_gpr_data when DBG_CORE_GSPR_DATA, log_write_addr & log_dmi_addr when DBG_CORE_LOG_ADDR, log_dmi_data when DBG_CORE_LOG_DATA, + log_dmi_trigger when DBG_CORE_LOG_TRIGGER, (others => '0') when others; -- DMI writes @@ -149,6 +153,9 @@ begin stopping <= '0'; terminated <= '0'; else + if do_log_trigger = '1' then + log_dmi_trigger(1) <= '1'; + end if; -- Edge detect on dmi_req for 1-shot pulses dmi_req_1 <= dmi_req; if dmi_req = '1' and dmi_req_1 = '0' then @@ -180,6 +187,8 @@ begin elsif dmi_addr = DBG_CORE_LOG_ADDR then log_dmi_addr <= dmi_din(31 downto 0); do_dmi_log_rd <= '1'; + elsif dmi_addr = DBG_CORE_LOG_TRIGGER then + log_dmi_trigger <= dmi_din; end if; else report("DMI read from " & to_string(dmi_addr)); @@ -246,7 +255,7 @@ begin begin -- Use MSB of read addresses to stop the logging - log_wr_enable <= not (log_read_addr(31) or log_dmi_addr(31)); + log_wr_enable <= not (log_read_addr(31) or log_dmi_addr(31) or log_dmi_trigger(1)); log_ram: process(clk) begin @@ -285,6 +294,12 @@ begin end if; log_dmi_read_done <= log_dmi_reading; log_dmi_reading <= do_dmi_log_rd; + do_log_trigger <= '0'; + if log_data(42) = log_dmi_trigger(63) and + log_data(41 downto 0) = log_dmi_trigger(43 downto 2) and + log_dmi_trigger(0) = '1' then + do_log_trigger <= '1'; + end if; end if; end process; log_write_addr(LOG_INDEX_BITS - 1 downto 0) <= std_ulogic_vector(log_wr_ptr); diff --git a/scripts/mw_debug/mw_debug.c b/scripts/mw_debug/mw_debug.c index d03e61c..4179264 100644 --- a/scripts/mw_debug/mw_debug.c +++ b/scripts/mw_debug/mw_debug.c @@ -44,6 +44,7 @@ #define DBG_LOG_ADDR 0x16 #define DBG_LOG_DATA 0x17 +#define DBG_LOG_TRIGGER 0x18 static bool debug; @@ -466,8 +467,11 @@ static void gpr_read(uint64_t reg, uint64_t count) static void mem_read(uint64_t addr, uint64_t count) { - uint64_t data; - int i, rc; + union { + uint64_t data; + unsigned char c[8]; + } u; + int i, j, rc; rc = dmi_write(DBG_WB_CTRL, 0x7ff); if (rc < 0) @@ -476,12 +480,15 @@ static void mem_read(uint64_t addr, uint64_t count) if (rc < 0) return; for (i = 0; i < count; i++) { - rc = dmi_read(DBG_WB_DATA, &data); + rc = dmi_read(DBG_WB_DATA, &u.data); if (rc < 0) return; - printf("%016llx: %016llx\n", + printf("%016llx: %016llx ", (unsigned long long)addr, - (unsigned long long)data); + (unsigned long long)u.data); + for (j = 0; j < 8; ++j) + putchar(u.c[j] >= 0x20 && u.c[j] < 0x7f? u.c[j]: '.'); + putchar('\n'); addr += 8; } } @@ -622,6 +629,28 @@ static void log_dump(const char *filename) check(dmi_write(DBG_LOG_ADDR, orig_laddr), "writing LOG_ADDR"); } +static void ltrig_show(void) +{ + uint64_t trig; + + check(dmi_read(DBG_LOG_TRIGGER, &trig), "reading LOG_TRIGGER"); + if (trig & 1) + printf("log stop trigger at %" PRIx64, trig & ~3); + else + printf("log stop trigger disabled"); + printf(", %striggered\n", (trig & 2? "": "not ")); +} + +static void ltrig_off(void) +{ + check(dmi_write(DBG_LOG_TRIGGER, 0), "writing LOG_TRIGGER"); +} + +static void ltrig_set(uint64_t addr) +{ + check(dmi_write(DBG_LOG_TRIGGER, (addr & ~(uint64_t)2) | 1), "writing LOG_TRIGGER"); +} + static void usage(const char *cmd) { fprintf(stderr, "Usage: %s -b \n", cmd); @@ -651,6 +680,9 @@ static void usage(const char *cmd) fprintf(stderr, " lstart start logging\n"); fprintf(stderr, " lstop stop logging\n"); fprintf(stderr, " ldump dump log to file\n"); + fprintf(stderr, " ltrig show logging stop trigger status\n"); + fprintf(stderr, " ltrig off clear logging stop trigger address\n"); + fprintf(stderr, " ltrig set logging stop trigger address\n"); fprintf(stderr, "\n"); fprintf(stderr, " JTAG:\n"); @@ -801,9 +833,20 @@ int main(int argc, char *argv[]) usage(argv[0]); filename = argv[++i]; log_dump(filename); + } else if (strcmp(argv[i], "ltrig") == 0) { + uint64_t addr; + + if ((i+1) >= argc) + ltrig_show(); + else if (strcmp(argv[++i], "off") == 0) + ltrig_off(); + else { + addr = strtoul(argv[i], NULL, 16); + ltrig_set(addr); + } } else { fprintf(stderr, "Unknown command %s\n", argv[i]); - exit(1); + usage(argv[0]); } } core_status();