-- 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);
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;
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
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
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));
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
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);
#define DBG_LOG_ADDR 0x16
#define DBG_LOG_DATA 0x17
+#define DBG_LOG_TRIGGER 0x18
static bool debug;
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)
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;
}
}
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 <jtag|sim> <command> <args>\n", cmd);
fprintf(stderr, " lstart start logging\n");
fprintf(stderr, " lstop stop logging\n");
fprintf(stderr, " ldump <file> 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 <addr> set logging stop trigger address\n");
fprintf(stderr, "\n");
fprintf(stderr, " JTAG:\n");
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();