mirror of
https://github.com/stnolting/neorv32.git
synced 2025-04-23 21:57:33 -04:00
[sim,sw] add trigger module test case
This commit is contained in:
parent
2578fd9da8
commit
741805ec53
2 changed files with 93 additions and 27 deletions
|
@ -184,7 +184,7 @@ begin
|
|||
if ci_mode then
|
||||
-- No need to send the full expectation in one big chunk
|
||||
check_uart(net, uart1_rx_handle, nul & nul);
|
||||
check_uart(net, uart1_rx_handle, "0/57" & cr & lf);
|
||||
check_uart(net, uart1_rx_handle, "0/58" & cr & lf);
|
||||
end if;
|
||||
|
||||
-- Wait until all expected data has been received
|
||||
|
|
|
@ -88,6 +88,8 @@ void rte_service_handler(void);
|
|||
void vectored_irq_table(void) __attribute__((naked, aligned(128)));
|
||||
void vectored_global_handler(void) __attribute__((interrupt("machine")));
|
||||
void vectored_mei_handler(void) __attribute__((interrupt("machine")));
|
||||
void __attribute__ ((interrupt)) hw_breakpoint_handler(void);
|
||||
void __attribute__ ((noinline)) trigger_module_dummy(void);
|
||||
void xirq_trap_handler0(void);
|
||||
void xirq_trap_handler1(void);
|
||||
void test_ok(void);
|
||||
|
@ -96,31 +98,21 @@ void test_fail(void);
|
|||
// MCAUSE value that will be NEVER set by the hardware
|
||||
const uint32_t mcause_never_c = 0x80000000UL; // = reserved
|
||||
|
||||
// Global variables (also test initialization of global vars here)
|
||||
/// Global counter for failing tests
|
||||
int cnt_fail = 0;
|
||||
/// Global counter for successful tests
|
||||
int cnt_ok = 0;
|
||||
/// Global counter for total number of tests
|
||||
int cnt_test = 0;
|
||||
/// Global number of available HPMs
|
||||
uint32_t num_hpm_cnts_global = 0;
|
||||
/// Vectored MEI trap handler acknowledge
|
||||
volatile int vectored_mei_handler_ack = 0;
|
||||
/// XIRQ trap handler acknowledge
|
||||
uint32_t xirq_trap_handler_ack = 0;
|
||||
/// DMA source & destination data
|
||||
volatile uint32_t dma_src;
|
||||
/// Variable to test store accesses
|
||||
volatile uint32_t store_access_addr[2];
|
||||
/// Variable for testing atomic memory accesses
|
||||
volatile uint32_t amo_var;
|
||||
/// Variable to test PMP
|
||||
volatile uint32_t __attribute__((aligned(4))) pmp_access[2];
|
||||
/// Number of triggered traps
|
||||
volatile uint32_t trap_cnt;
|
||||
/// Number of implemented PMP regions
|
||||
uint32_t pmp_num_regions;
|
||||
// Global variables
|
||||
volatile int cnt_fail = 0; // global counter for failing tests
|
||||
volatile int cnt_ok = 0; // global counter for successful tests
|
||||
volatile int cnt_test = 0; // global counter for total number of tests
|
||||
volatile uint32_t num_hpm_cnts_global = 0; // global number of available hpms
|
||||
volatile int vectored_mei_handler_ack = 0; // vectored mei trap handler acknowledge
|
||||
volatile uint32_t xirq_trap_handler_ack = 0; // xirq trap handler acknowledge
|
||||
volatile uint32_t hw_brk_mscratch_ok = 0; // set when mepc was correct in trap handler
|
||||
|
||||
volatile uint32_t dma_src; // dma source & destination data
|
||||
volatile uint32_t store_access_addr[2]; // variable to test store accesses
|
||||
volatile uint32_t amo_var; // variable for testing atomic memory accesses
|
||||
volatile uint32_t __attribute__((aligned(4))) pmp_access[2]; // variable to test pmp
|
||||
volatile uint32_t trap_cnt; // number of triggered traps
|
||||
volatile uint32_t pmp_num_regions; // number of implemented pmp regions
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
|
@ -1877,6 +1869,55 @@ int main() {
|
|||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Test trigger module (hardware breakpoint)
|
||||
// ----------------------------------------------------------
|
||||
neorv32_cpu_csr_write(CSR_MCAUSE, mcause_never_c);
|
||||
PRINT_STANDARD("[%i] Trigger module (HW breakpoint) ", cnt_test);
|
||||
|
||||
if (neorv32_cpu_csr_read(CSR_MXISA) & (1 << CSR_MXISA_SDTRIG)) {
|
||||
cnt_test++;
|
||||
|
||||
// back-up RTE
|
||||
uint32_t rte_bak = neorv32_cpu_csr_read(CSR_MTVEC);
|
||||
|
||||
// install hardware-breakpoint handler
|
||||
neorv32_cpu_csr_write(CSR_MTVEC, (uint32_t)&hw_breakpoint_handler);
|
||||
|
||||
// setup test registers
|
||||
neorv32_cpu_csr_write(CSR_MSCRATCH, 0);
|
||||
hw_brk_mscratch_ok = 0;
|
||||
|
||||
// setup hardware breakpoint
|
||||
neorv32_cpu_csr_write(CSR_TDATA2, (uint32_t)(&trigger_module_dummy)); // triggering address
|
||||
neorv32_cpu_csr_write(CSR_TDATA1, (1 << 2) | // exe = 1: enable trigger module execution
|
||||
(0 << 12)); // action = 0: breakpoint exception, do not enter debug-mode
|
||||
|
||||
// call the hw-breakpoint triggering function
|
||||
trigger_module_dummy();
|
||||
|
||||
if ((neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_BREAKPOINT) && // correct exception cause
|
||||
(neorv32_cpu_csr_read(CSR_MSCRATCH) == 4) && // breakpoint-triggering function was finally executed
|
||||
(neorv32_cpu_csr_read(CSR_MEPC) == neorv32_cpu_csr_read(CSR_TDATA2)) && // mepc has to be set to the triggering instruction address
|
||||
(neorv32_cpu_csr_read(CSR_TDATA1) & (1 << 22)) && // trigger has fired
|
||||
(hw_brk_mscratch_ok == 1)) { // make sure mepc was correct in trap handler
|
||||
test_ok();
|
||||
}
|
||||
else {
|
||||
test_fail();
|
||||
}
|
||||
|
||||
// shut-down and reset trigger
|
||||
neorv32_cpu_csr_write(CSR_TDATA1, 0);
|
||||
|
||||
// restore RTE
|
||||
neorv32_cpu_csr_write(CSR_MTVEC, rte_bak);
|
||||
}
|
||||
else {
|
||||
PRINT_STANDARD("[n.a.]\n");
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Test atomic lr/sc memory access - failing access
|
||||
// ----------------------------------------------------------
|
||||
|
@ -2232,7 +2273,7 @@ void rte_service_handler(void) {
|
|||
if (arg0 == 127) {
|
||||
neorv32_rte_context_put(10, arg1 + arg2); // service result in a0
|
||||
}
|
||||
|
||||
|
||||
// hack: return in MACHINE MODE
|
||||
neorv32_cpu_csr_set(CSR_MSTATUS, (1<<CSR_MSTATUS_MPP_H) | (1<<CSR_MSTATUS_MPP_L));
|
||||
}
|
||||
|
@ -2293,6 +2334,31 @@ void vectored_mei_handler(void) {
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Hardware-breakpoint trap handler
|
||||
**************************************************************************/
|
||||
void __attribute__ ((interrupt)) hw_breakpoint_handler(void) {
|
||||
|
||||
// make sure mscratch has not been updated yet
|
||||
if (neorv32_cpu_csr_read(CSR_MSCRATCH) == 0) {
|
||||
hw_brk_mscratch_ok += 1;
|
||||
}
|
||||
|
||||
// [NOTE] do not update MEPC here as hardware-breakpoint exceptions will set
|
||||
// MEPC to the address of the instruction thats has NOT BEEN EXECUTED yet
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Test function for the trigger module
|
||||
**************************************************************************/
|
||||
void __attribute__ ((noinline,naked)) trigger_module_dummy(void) {
|
||||
|
||||
asm volatile ("csrwi mscratch, 4 \n" // hardware breakpoint should trigger before executing this
|
||||
"ret \n");
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* XIRQ handler channel 0.
|
||||
**************************************************************************/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue