63 lines
1.6 KiB
C
63 lines
1.6 KiB
C
#include "tb_cxxrtl_io.h"
|
|
#include "hazard3_csr.h"
|
|
|
|
// Check load/stores which generate a bus fault generate an exception, and
|
|
// report the correct mcause and mepc.
|
|
|
|
/*EXPECTED-OUTPUT***************************************************************
|
|
|
|
-> exception, mcause = 7
|
|
exception instr: 0007a023
|
|
-> exception, mcause = 7
|
|
exception instr: 00079023
|
|
-> exception, mcause = 7
|
|
exception instr: 00078023
|
|
-> exception, mcause = 5
|
|
exception instr: 0007a003
|
|
-> exception, mcause = 5
|
|
exception instr: 00079003
|
|
-> exception, mcause = 5
|
|
exception instr: 0007d003
|
|
-> exception, mcause = 5
|
|
exception instr: 00078003
|
|
-> exception, mcause = 5
|
|
exception instr: 0007c003
|
|
Done.
|
|
|
|
*******************************************************************************/
|
|
|
|
int main() {
|
|
// Word-aligned address which generates an access fault. Constrained to a
|
|
// particular register, because the instructions appear in the test log to
|
|
// confirm mepc value.
|
|
register void *bad_addr asm ("a5") = (void*)0xcdef1234u;
|
|
|
|
asm volatile (
|
|
"sw zero, (%0)\n"
|
|
"sh zero, (%0)\n"
|
|
"sb zero, (%0)\n"
|
|
"lw zero, (%0)\n"
|
|
"lh zero, (%0)\n"
|
|
"lhu zero, (%0)\n"
|
|
"lb zero, (%0)\n"
|
|
"lbu zero, (%0)\n"
|
|
: : "r" (bad_addr)
|
|
);
|
|
tb_puts("Done.\n");
|
|
return 0;
|
|
}
|
|
|
|
void __attribute__((interrupt)) handle_exception() {
|
|
tb_printf("-> exception, mcause = %u\n", read_csr(mcause));
|
|
write_csr(mcause, 0);
|
|
uint32_t mepc = read_csr(mepc);
|
|
if ((*(uint16_t*)mepc & 0x3) == 0x3) {
|
|
tb_printf("exception instr: %04x%04x\n", *(uint16_t*)(mepc + 2), *(uint16_t*)mepc);
|
|
write_csr(mepc, mepc + 4);
|
|
}
|
|
else {
|
|
tb_printf("exception instr: %04x\n", *(uint16_t*)(mepc + 2), *(uint16_t*)mepc);
|
|
write_csr(mepc, mepc + 2);
|
|
}
|
|
}
|