openocd tb: report AHB error response when processor accesses outside of RAM/IO
This commit is contained in:
parent
5deff12f95
commit
8014239d47
|
@ -17,6 +17,7 @@ static const unsigned int MEM_SIZE = 16 * 1024 * 1024;
|
||||||
uint8_t mem[MEM_SIZE];
|
uint8_t mem[MEM_SIZE];
|
||||||
|
|
||||||
static const unsigned int IO_BASE = 0x80000000;
|
static const unsigned int IO_BASE = 0x80000000;
|
||||||
|
static const unsigned int IO_MASK = 0xffffff00;
|
||||||
enum {
|
enum {
|
||||||
IO_PRINT_CHAR = 0,
|
IO_PRINT_CHAR = 0,
|
||||||
IO_PRINT_U32 = 4,
|
IO_PRINT_U32 = 4,
|
||||||
|
@ -219,56 +220,91 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle current data phase, then move current address phase to data phase
|
if (top.p_d__hready.get<bool>()) {
|
||||||
uint32_t rdata = 0;
|
// Clear bus error by default
|
||||||
if (bus_trans && bus_write) {
|
top.p_d__hresp.set<bool>(false);
|
||||||
uint32_t wdata = top.p_d__hwdata.get<uint32_t>();
|
// Handle current data phase
|
||||||
if (bus_addr <= MEM_SIZE) {
|
uint32_t rdata = 0;
|
||||||
unsigned int n_bytes = 1u << bus_size;
|
bool bus_err = false;
|
||||||
// Note we are relying on hazard3's byte lane replication
|
if (bus_trans && bus_write) {
|
||||||
for (unsigned int i = 0; i < n_bytes; ++i) {
|
uint32_t wdata = top.p_d__hwdata.get<uint32_t>();
|
||||||
mem[bus_addr + i] = wdata >> (8 * i) & 0xffu;
|
if (bus_addr <= MEM_SIZE - 4u) {
|
||||||
|
unsigned int n_bytes = 1u << bus_size;
|
||||||
|
// Note we are relying on hazard3's byte lane replication
|
||||||
|
for (unsigned int i = 0; i < n_bytes; ++i) {
|
||||||
|
mem[bus_addr + i] = wdata >> (8 * i) & 0xffu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (bus_addr == IO_BASE + IO_PRINT_CHAR) {
|
||||||
|
putchar(wdata);
|
||||||
|
}
|
||||||
|
else if (bus_addr == IO_BASE + IO_PRINT_U32) {
|
||||||
|
printf("%08x\n", wdata);
|
||||||
|
}
|
||||||
|
else if (bus_addr == IO_BASE + IO_EXIT) {
|
||||||
|
printf("CPU requested halt. Exit code %d\n", wdata);
|
||||||
|
printf("Ran for %ld cycles\n", cycle + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bus_err = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (bus_addr == IO_BASE + IO_PRINT_CHAR) {
|
else if (bus_trans && !bus_write) {
|
||||||
putchar(wdata);
|
if (bus_addr <= MEM_SIZE) {
|
||||||
|
bus_addr &= ~0x3u;
|
||||||
|
rdata =
|
||||||
|
(uint32_t)mem[bus_addr] |
|
||||||
|
mem[bus_addr + 1] << 8 |
|
||||||
|
mem[bus_addr + 2] << 16 |
|
||||||
|
mem[bus_addr + 3] << 24;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bus_err = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (bus_addr == IO_BASE + IO_PRINT_U32) {
|
if (bus_err) {
|
||||||
printf("%08x\n", wdata);
|
// Phase 1 of error response
|
||||||
}
|
top.p_d__hready.set<bool>(false);
|
||||||
else if (bus_addr == IO_BASE + IO_EXIT) {
|
top.p_d__hresp.set<bool>(true);
|
||||||
printf("CPU requested halt. Exit code %d\n", wdata);
|
|
||||||
printf("Ran for %ld cycles\n", cycle + 1);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
top.p_d__hrdata.set<uint32_t>(rdata);
|
||||||
|
|
||||||
|
// Progress current address phase to data phase
|
||||||
|
bus_trans = top.p_d__htrans.get<uint8_t>() >> 1;
|
||||||
|
bus_write = top.p_d__hwrite.get<bool>();
|
||||||
|
bus_size = top.p_d__hsize.get<uint8_t>();
|
||||||
|
bus_addr = top.p_d__haddr.get<uint32_t>();
|
||||||
}
|
}
|
||||||
else if (bus_trans && !bus_write) {
|
else {
|
||||||
if (bus_addr <= MEM_SIZE) {
|
// hready=0. Currently this only happens when we're in the first
|
||||||
bus_addr &= ~0x3u;
|
// phase of an error response, so go to phase 2.
|
||||||
rdata =
|
top.p_d__hready.set<bool>(true);
|
||||||
(uint32_t)mem[bus_addr] |
|
|
||||||
mem[bus_addr + 1] << 8 |
|
|
||||||
mem[bus_addr + 2] << 16 |
|
|
||||||
mem[bus_addr + 3] << 24;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
top.p_d__hrdata.set<uint32_t>(rdata);
|
|
||||||
if (bus_trans_i) {
|
|
||||||
bus_addr_i &= ~0x3u;
|
|
||||||
top.p_i__hrdata.set<uint32_t>(
|
|
||||||
(uint32_t)mem[bus_addr_i] |
|
|
||||||
mem[bus_addr_i + 1] << 8 |
|
|
||||||
mem[bus_addr_i + 2] << 16 |
|
|
||||||
mem[bus_addr_i + 3] << 24
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bus_trans = top.p_d__htrans.get<uint8_t>() >> 1;
|
if (top.p_i__hready.get<bool>()) {
|
||||||
bus_write = top.p_d__hwrite.get<bool>();
|
top.p_i__hresp.set<bool>(false);
|
||||||
bus_size = top.p_d__hsize.get<uint8_t>();
|
if (bus_trans_i) {
|
||||||
bus_addr = top.p_d__haddr.get<uint32_t>();
|
bus_addr_i &= ~0x3u;
|
||||||
bus_trans_i = top.p_i__htrans.get<uint8_t>() >> 1;
|
if (bus_addr_i <= MEM_SIZE - 4u) {
|
||||||
bus_addr_i = top.p_i__haddr.get<uint32_t>();
|
top.p_i__hrdata.set<uint32_t>(
|
||||||
|
(uint32_t)mem[bus_addr_i] |
|
||||||
|
mem[bus_addr_i + 1] << 8 |
|
||||||
|
mem[bus_addr_i + 2] << 16 |
|
||||||
|
mem[bus_addr_i + 3] << 24
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
top.p_i__hready.set<bool>(false);
|
||||||
|
top.p_i__hresp.set<bool>(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bus_trans_i = top.p_i__htrans.get<uint8_t>() >> 1;
|
||||||
|
bus_addr_i = top.p_i__haddr.get<uint32_t>();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
top.p_i__hready.set<bool>(true);
|
||||||
|
}
|
||||||
|
|
||||||
if (dump_waves) {
|
if (dump_waves) {
|
||||||
// The extra step() is just here to get the bus responses to line up nicely
|
// The extra step() is just here to get the bus responses to line up nicely
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
[*]
|
[*]
|
||||||
[*] GTKWave Analyzer v3.3.103 (w)1999-2019 BSI
|
[*] GTKWave Analyzer v3.3.103 (w)1999-2019 BSI
|
||||||
[*] Mon Jul 12 17:15:59 2021
|
[*] Sat Jul 17 18:13:53 2021
|
||||||
[*]
|
[*]
|
||||||
[dumpfile] "/home/luke/proj/hazard3/test/sim/debug_openocd_bitbang/waves.vcd"
|
[dumpfile] "/home/luke/proj/hazard3/test/sim/openocd/waves.vcd"
|
||||||
[dumpfile_mtime] "Mon Jul 12 17:11:32 2021"
|
[dumpfile_mtime] "Sat Jul 17 18:07:33 2021"
|
||||||
[dumpfile_size] 2961061
|
[dumpfile_size] 6782392
|
||||||
[savefile] "/home/luke/proj/hazard3/test/sim/debug_openocd_bitbang/waves.gtkw"
|
[savefile] "/home/luke/proj/hazard3/test/sim/openocd/waves.gtkw"
|
||||||
[timestart] 0
|
[timestart] 140588
|
||||||
[size] 1920 1043
|
[size] 1920 1043
|
||||||
[pos] -1 -1
|
[pos] -1 -1
|
||||||
*-13.000000 18597 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
*-3.000000 140615 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
||||||
|
[treeopen] cpu.
|
||||||
|
[treeopen] cpu.core.
|
||||||
[treeopen] inst_hazard3_jtag_dtm.
|
[treeopen] inst_hazard3_jtag_dtm.
|
||||||
[sst_width] 233
|
[sst_width] 233
|
||||||
[signals_width] 222
|
[signals_width] 222
|
||||||
|
@ -21,7 +23,6 @@ trst_n
|
||||||
rst_n_dmi
|
rst_n_dmi
|
||||||
@200
|
@200
|
||||||
-
|
-
|
||||||
@201
|
|
||||||
-DTM
|
-DTM
|
||||||
@28
|
@28
|
||||||
tck
|
tck
|
||||||
|
@ -63,5 +64,32 @@ cpu.dbg_halted
|
||||||
cpu.dbg_running
|
cpu.dbg_running
|
||||||
@200
|
@200
|
||||||
-
|
-
|
||||||
|
-Trap stuff
|
||||||
|
@22
|
||||||
|
cpu.core.inst_hazard3_csr.trap_addr[31:0]
|
||||||
|
@28
|
||||||
|
cpu.core.inst_hazard3_csr.trap_enter_rdy
|
||||||
|
cpu.core.inst_hazard3_csr.trap_enter_vld
|
||||||
|
cpu.core.inst_hazard3_csr.trap_is_irq
|
||||||
|
@22
|
||||||
|
cpu.core.inst_hazard3_csr.except[3:0]
|
||||||
|
@28
|
||||||
|
cpu.core.m_stall
|
||||||
|
@29
|
||||||
|
cpu.core.bus_dph_err_d
|
||||||
|
@200
|
||||||
|
-
|
||||||
|
-D Bus
|
||||||
|
@22
|
||||||
|
d_haddr[31:0]
|
||||||
|
@28
|
||||||
|
d_htrans[1:0]
|
||||||
|
d_hwrite
|
||||||
|
d_hsize[2:0]
|
||||||
|
d_hready
|
||||||
|
d_hresp
|
||||||
|
@22
|
||||||
|
d_hwdata[31:0]
|
||||||
|
d_hrdata[31:0]
|
||||||
[pattern_trace] 1
|
[pattern_trace] 1
|
||||||
[pattern_trace] 0
|
[pattern_trace] 0
|
||||||
|
|
Loading…
Reference in New Issue