OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /neorv32/trunk/sw/example/processor_check
    from Rev 63 to Rev 64
    Reverse comparison

Rev 63 → Rev 64

/check.sh File deleted
/main.c
50,7 → 50,9
/** UART BAUD rate */
#define BAUD_RATE (19200)
//** Reachable unaligned address */
#define ADDR_UNALIGNED (0x00000002)
#define ADDR_UNALIGNED_1 (0x00000001)
//** Reachable unaligned address */
#define ADDR_UNALIGNED_2 (0x00000002)
//** Unreachable word-aligned address */
#define ADDR_UNREACHABLE (IO_BASE_ADDRESS-4)
//** external memory base address */
115,10 → 117,12
register uint32_t tmp_a, tmp_b;
uint8_t id;
 
// disable global interrupts
neorv32_cpu_dint();
 
// init UARTs at default baud rate, no parity bits, no hw flow control
neorv32_uart0_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
UART1_CT = UART0_CT; // copy configuration to initialize UART1
NEORV32_UART1.CTRL = NEORV32_UART0.CTRL; // copy configuration to initialize UART1
 
#ifdef SUPPRESS_OPTIONAL_UART_PRINT
neorv32_uart0_disable(); // do not generate any UART0 output
157,10 → 161,9
neorv32_cpu_csr_write(CSR_MCOUNTINHIBIT, 0); // enable performance counter auto increment (ALL counters)
neorv32_cpu_csr_write(CSR_MCOUNTEREN, 7); // allow access from user-mode code to standard counters only
 
// set CMP of machine system timer MTIME to max to prevent an IRQ
neorv32_mtime_set_timecmp(-1);
neorv32_mtime_set_time(0);
// set CMP of machine system timer MTIME to max to prevent an IRQ
uint64_t mtime_cmp_max = 0xffffffffffffffffULL;
neorv32_mtime_set_timecmp(mtime_cmp_max);
 
 
// fancy intro
190,12 → 193,12
return 1;
}
 
// enable interrupt sources
neorv32_cpu_irq_enable(CSR_MIE_MSIE); // machine software interrupt
neorv32_cpu_irq_enable(CSR_MIE_MTIE); // machine timer interrupt
neorv32_cpu_irq_enable(CSR_MIE_MEIE); // machine external interrupt
// enable FAST IRQ sources only where actually needed
// clear testbench IRQ triggers
sim_irq_trigger(0);
 
// clear all interrupt enables, enable only where needed
neorv32_cpu_csr_write(CSR_MIE, 0);
 
// test intro
PRINT_STANDARD("\nStarting tests...\n\n");
 
341,40 → 344,28
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] mcounteren.cy CSR: ", cnt_test);
 
// skip if U-mode is not implemented
if (neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_U)) {
cnt_test++;
cnt_test++;
 
// do not allow user-level code to access cycle[h] CSRs
tmp_a = neorv32_cpu_csr_read(CSR_MCOUNTEREN);
tmp_a &= ~(1<<CSR_MCOUNTEREN_CY); // clear access right
neorv32_cpu_csr_write(CSR_MCOUNTEREN, tmp_a);
// do not allow user-level code to access cycle[h] CSRs
tmp_a = neorv32_cpu_csr_read(CSR_MCOUNTEREN);
tmp_a &= ~(1<<CSR_MCOUNTEREN_CY); // clear access right
neorv32_cpu_csr_write(CSR_MCOUNTEREN, tmp_a);
 
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
// access to cycle CSR is no longer allowed
tmp_a = neorv32_cpu_csr_read(CSR_CYCLE);
}
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
// access to cycle CSR is no longer allowed
tmp_a = neorv32_cpu_csr_read(CSR_CYCLE);
}
 
// make sure there was an illegal instruction trap
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
if (tmp_a == 0) { // make sure user-level code CANNOT read locked CSR content!
test_ok();
}
else {
test_fail();
}
}
else {
test_fail();
}
// make sure there was an illegal instruction trap
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
}
else {
PRINT_STANDARD("skipped (n.a.)\n");
else {
test_fail();
}
 
 
// re-allow user-level code to access cycle[h] CSRs
tmp_a = neorv32_cpu_csr_read(CSR_MCOUNTEREN);
tmp_a |= (1<<CSR_MCOUNTEREN_CY); // re-allow access right
381,61 → 372,25
neorv32_cpu_csr_write(CSR_MCOUNTEREN, tmp_a);
 
 
/*
// ----------------------------------------------------------
// Execute DRET in M-mode (has to trap!)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] DRET in M-mode: ", cnt_test);
 
// skip if U-mode is not implemented
if (neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_U)) {
 
cnt_test++;
 
asm volatile("dret");
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
}
else {
test_fail();
}
 
}
else {
PRINT_STANDARD("skipped (n.a. without U-ext)\n");
}
*/
 
 
// ----------------------------------------------------------
// Execute MRET in U-mode (has to trap!)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] MRET in U-mode: ", cnt_test);
 
// skip if U-mode is not implemented
if (SYSINFO_CPU & (1<<SYSINFO_CPU_DEBUGMODE)) {
cnt_test++;
 
cnt_test++;
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
asm volatile ("mret");
}
 
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
asm volatile("mret");
}
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
}
else {
test_fail();
}
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
}
else {
PRINT_STANDARD("skipped (n.a. without U-ext)\n");
test_fail();
}
 
 
445,7 → 400,7
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] External memory access (@ 0x%x): ", cnt_test, (uint32_t)EXT_MEM_BASE);
 
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT)) {
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_MEM_EXT)) {
cnt_test++;
 
// create test program in RAM
512,10 → 467,6
 
tmp_a = neorv32_cpu_csr_read(0xfff); // CSR 0xfff not implemented
 
if (tmp_a != 0) {
PRINT_CRITICAL("%c[1m<SECURITY FAILURE> %c[0m\n", 27, 27);
}
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
}
563,40 → 514,6
 
 
// ----------------------------------------------------------
// Test pending interrupt
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] Pending IRQ test (MTIME): ", cnt_test);
 
cnt_test++;
 
// disable global interrupts
neorv32_cpu_dint();
 
// prepare MTIME IRQ
neorv32_mtime_set_time(0x00000000FFFFFFF8ULL); // prepare overflow
neorv32_mtime_set_timecmp(0x0000000100000000ULL); // IRQ on overflow
 
// wait some time for the IRQ to arrive the CPU
asm volatile("nop");
asm volatile("nop");
 
// no more mtime interrupts
neorv32_mtime_set_timecmp(-1);
 
// re-enable global interrupts
neorv32_cpu_eint();
 
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MTI) {
test_ok();
}
else {
test_fail();
}
 
 
// ----------------------------------------------------------
// Unaligned instruction address
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
608,16 → 525,16
cnt_test++;
 
// call unaligned address
((void (*)(void))ADDR_UNALIGNED)();
((void (*)(void))ADDR_UNALIGNED_2)();
asm volatile("nop");
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_MISALIGNED) {
PRINT_STANDARD("ok\n");
cnt_ok++;
test_ok();
}
else {
PRINT_STANDARD("fail\n");
cnt_fail++;
test_fail();
}
 
}
else {
PRINT_STANDARD("skipped (n.a. with C-ext)\n");
650,14 → 567,14
 
cnt_test++;
 
// invalid instruction: using x0=x0 OP x0 with invalid opcode
CUSTOM_INSTR_R2_TYPE(0b0000000, x0, x0, 0b000, x0, 0b1111111);
// not allowed outside of debug mode
asm volatile ("dret");
 
// make sure this has cause an illegal exception
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
// make sure this is really the instruction that caused the exception
// for illegal instructions mtval contains the actual instruction word
if (neorv32_cpu_csr_read(CSR_MTVAL) == 0x0000007f) {
// -> for illegal instructions mtval contains the failing instruction word
if (neorv32_cpu_csr_read(CSR_MTVAL) == 0x7b200073) {
test_ok();
}
else {
676,7 → 593,7
PRINT_STANDARD("[%i] CI_ILLEG (illegal compr. instr.) EXC: ", cnt_test);
 
// skip if C-mode is not implemented
if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_C)) != 0) {
if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_C))) {
 
cnt_test++;
 
726,7 → 643,7
cnt_test++;
 
// load from unaligned address
neorv32_cpu_load_unsigned_word(ADDR_UNALIGNED);
neorv32_cpu_load_unsigned_word(ADDR_UNALIGNED_1);
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_L_MISALIGNED) {
test_ok();
762,7 → 679,7
cnt_test++;
 
// store to unaligned address
asm volatile ("sw zero, %[input_i](zero)" : : [input_i] "i" (ADDR_UNALIGNED));
neorv32_cpu_store_unsigned_word(ADDR_UNALIGNED_2, 0);
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_S_MISALIGNED) {
test_ok();
813,27 → 730,19
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] ENVCALL (ecall instr.) from U-mode EXC: ", cnt_test);
 
// skip if U-mode is not implemented
if (neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_U)) {
cnt_test++;
 
cnt_test++;
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
asm volatile("ECALL");
}
 
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
asm volatile("ECALL");
}
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_UENV_CALL) {
test_ok();
}
else {
test_fail();
}
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_UENV_CALL) {
test_ok();
}
else {
PRINT_STANDARD("skipped (n.a. without U-ext)\n");
test_fail();
}
 
 
845,21 → 754,22
 
cnt_test++;
 
// configure MTIME IRQ (and check overflow form low owrd to high word)
// configure MTIME IRQ (and check overflow from low word to high word)
neorv32_mtime_set_timecmp(-1);
neorv32_mtime_set_time(0);
 
neorv32_cpu_csr_write(CSR_MIP, 0); // clear all pending IRQs
 
// enable interrupt
neorv32_mtime_set_timecmp(0x0000000100000000ULL);
neorv32_mtime_set_time( 0x00000000FFFFFFFEULL);
neorv32_cpu_irq_enable(CSR_MIE_MTIE);
 
// wait some time for the IRQ to trigger and arrive the CPU
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
 
// disable interrupt
neorv32_cpu_irq_disable(CSR_MIE_MTIE);
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MTI) {
test_ok();
}
879,6 → 789,9
 
cnt_test++;
 
// enable interrupt
neorv32_cpu_irq_enable(CSR_MIE_MSIE);
 
// trigger IRQ
sim_irq_trigger(1 << CSR_MIE_MSIE);
 
886,6 → 799,9
asm volatile("nop");
asm volatile("nop");
 
// disable interrupt
neorv32_cpu_irq_disable(CSR_MIE_MSIE);
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MSI) {
test_ok();
}
902,6 → 818,9
 
cnt_test++;
 
// enable interrupt
neorv32_cpu_irq_enable(CSR_MIE_MEIE);
 
// trigger IRQ
sim_irq_trigger(1 << CSR_MIE_MEIE);
 
909,6 → 828,9
asm volatile("nop");
asm volatile("nop");
 
// enable interrupt
neorv32_cpu_irq_disable(CSR_MIE_MEIE);
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MEI) {
test_ok();
}
918,21 → 840,73
 
 
// ----------------------------------------------------------
// Non-maskable interrupt (NMI) via testbench
// Permanent IRQ (make sure interrupted program advances)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] NMI (via testbench): ", cnt_test);
PRINT_STANDARD("[%i] Permanent IRQ (MTIME): ", cnt_test);
 
cnt_test++;
 
// trigger IRQ
sim_irq_trigger(1 << 0);
// fire MTIME IRQ
neorv32_cpu_irq_enable(CSR_MIE_MTIE);
neorv32_mtime_set_time(1); // prepare overflow
neorv32_mtime_set_timecmp(0); // IRQ on overflow
 
register int test_cnt = 0;
while(test_cnt < 2) {
test_cnt++;
}
 
// end MTIME IRQ
neorv32_cpu_irq_disable(CSR_MIE_MTIE);
neorv32_mtime_set_timecmp(-1);
 
if (test_cnt == 2) {
test_ok();
}
else {
test_fail();
}
 
 
// ----------------------------------------------------------
// Test pending interrupt
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] Pending IRQ test (MTIME): ", cnt_test);
 
cnt_test++;
 
// enable interrupt
neorv32_cpu_irq_enable(CSR_MIE_MTIE);
 
// disable global interrupts
neorv32_cpu_dint();
 
// fire MTIME IRQ
neorv32_mtime_set_time(1); // prepare overflow
neorv32_mtime_set_timecmp(0); // IRQ on overflow
 
// wait some time for the IRQ to arrive the CPU
asm volatile("nop");
asm volatile("nop");
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_NMI) {
int was_pending = 0;
if (neorv32_cpu_csr_read(CSR_MIP) & (1 << CSR_MIP_MTIP)) { // should be pending now
was_pending = 1;
}
 
// clear pending MTI
neorv32_mtime_set_timecmp(-1);
 
int is_pending = 0;
if (neorv32_cpu_csr_read(CSR_MIP) & (1 << CSR_MIP_MTIP)) { // should NOT be pending anymore
is_pending = 1;
}
 
neorv32_cpu_irq_disable(CSR_MIE_MTIE);
 
if ((was_pending == 1) && (is_pending == 0)) {
test_ok();
}
else {
939,7 → 913,10
test_fail();
}
 
// re-enable global interrupts
neorv32_cpu_eint();
 
 
// ----------------------------------------------------------
// Fast interrupt channel 0 (WDT)
// ----------------------------------------------------------
954,7 → 931,7
 
// configure WDT
neorv32_wdt_setup(CLK_PRSC_4096, 0, 1); // highest clock prescaler, trigger IRQ on timeout, lock access
WDT_CT = 0; // try to deactivate WDT (should fail as access is loced)
NEORV32_WDT.CTRL = 0; // try to deactivate WDT (should fail as access is loced)
neorv32_wdt_force(); // force watchdog into action
 
// wait some time for the IRQ to arrive the CPU
968,11 → 945,11
test_fail();
}
 
// disable fast interrupt
neorv32_cpu_irq_disable(CSR_MIE_FIRQ0E);
 
// no more WDT interrupts
neorv32_wdt_disable();
 
// disable fast interrupt
neorv32_cpu_irq_disable(CSR_MIE_FIRQ0E);
}
 
 
980,7 → 957,7
// Fast interrupt channel 1 (CFS)
// ----------------------------------------------------------
PRINT_STANDARD("[%i] FIRQ1 test (via CFS): ", cnt_test);
PRINT_STANDARD("skipped (n.a.)\n");
PRINT_STANDARD("skipped \n");
 
 
// ----------------------------------------------------------
999,12 → 976,12
while(neorv32_uart0_tx_busy());
 
// backup current UART0 configuration
tmp_a = UART0_CT;
tmp_a = NEORV32_UART0.CTRL;
 
// make sure UART is enabled
UART0_CT |= (1 << UART_CT_EN);
NEORV32_UART0.CTRL |= (1 << UART_CTRL_EN);
// make sure sim mode is disabled
UART0_CT &= ~(1 << UART_CT_SIM_MODE);
NEORV32_UART0.CTRL &= ~(1 << UART_CTRL_SIM_MODE);
 
// trigger UART0 RX IRQ
neorv32_uart0_putc(0);
1017,7 → 994,7
asm volatile("nop");
 
// restore original configuration
UART0_CT = tmp_a;
NEORV32_UART0.CTRL = tmp_a;
 
// disable fast interrupt
neorv32_cpu_irq_disable(CSR_MIE_FIRQ2E);
1047,12 → 1024,12
while(neorv32_uart0_tx_busy());
 
// backup current UART0 configuration
tmp_a = UART0_CT;
tmp_a = NEORV32_UART0.CTRL;
 
// make sure UART is enabled
UART0_CT |= (1 << UART_CT_EN);
NEORV32_UART0.CTRL |= (1 << UART_CTRL_EN);
// make sure sim mode is disabled
UART0_CT &= ~(1 << UART_CT_SIM_MODE);
NEORV32_UART0.CTRL &= ~(1 << UART_CTRL_SIM_MODE);
 
// trigger UART0 TX IRQ
neorv32_uart0_putc(0);
1065,7 → 1042,7
asm volatile("nop");
 
// restore original configuration
UART0_CT = tmp_a;
NEORV32_UART0.CTRL = tmp_a;
 
neorv32_cpu_irq_disable(CSR_MIE_FIRQ3E);
 
1091,12 → 1068,12
neorv32_cpu_irq_enable(CSR_MIE_FIRQ4E);
 
// backup current UART1 configuration
tmp_a = UART1_CT;
tmp_a = NEORV32_UART1.CTRL;
 
// make sure UART is enabled
UART1_CT |= (1 << UART_CT_EN);
NEORV32_UART1.CTRL |= (1 << UART_CTRL_EN);
// make sure sim mode is disabled
UART1_CT &= ~(1 << UART_CT_SIM_MODE);
NEORV32_UART1.CTRL &= ~(1 << UART_CTRL_SIM_MODE);
 
// trigger UART1 RX IRQ
neorv32_uart1_putc(0);
1109,7 → 1086,7
asm volatile("nop");
 
// restore original configuration
UART1_CT = tmp_a;
NEORV32_UART1.CTRL = tmp_a;
 
// disable fast interrupt
neorv32_cpu_irq_disable(CSR_MIE_FIRQ4E);
1136,12 → 1113,12
neorv32_cpu_irq_enable(CSR_MIE_FIRQ5E);
 
// backup current UART1 configuration
tmp_a = UART1_CT;
tmp_a = NEORV32_UART1.CTRL;
 
// make sure UART is enabled
UART1_CT |= (1 << UART_CT_EN);
NEORV32_UART1.CTRL |= (1 << UART_CTRL_EN);
// make sure sim mode is disabled
UART1_CT &= ~(1 << UART_CT_SIM_MODE);
NEORV32_UART1.CTRL &= ~(1 << UART_CTRL_SIM_MODE);
 
// trigger UART1 TX IRQ
neorv32_uart1_putc(0);
1154,7 → 1131,7
asm volatile("nop");
 
// restore original configuration
UART1_CT = tmp_a;
NEORV32_UART1.CTRL = tmp_a;
 
// disable fast interrupt
neorv32_cpu_irq_disable(CSR_MIE_FIRQ5E);
1258,7 → 1235,8
xirq_err_cnt += neorv32_xirq_install(0, xirq_trap_handler0); // install XIRQ IRQ handler channel 0
xirq_err_cnt += neorv32_xirq_install(1, xirq_trap_handler1); // install XIRQ IRQ handler channel 1
 
neorv32_xirq_global_enable(); // enable XIRQ FIRQ
// enable XIRQ FIRQ
neorv32_cpu_irq_enable(CSR_MIE_FIRQ8E);
 
// trigger XIRQ channel 1 and 0
neorv32_gpio_port_set(3);
1277,9 → 1255,9
test_fail();
}
 
neorv32_xirq_global_disable();
XIRQ_IER = 0;
XIRQ_IPR = -1;
neorv32_cpu_irq_disable(CSR_MIE_FIRQ8E);
NEORV32_XIRQ.IER = 0;
NEORV32_XIRQ.IPR = -1;
}
 
 
1296,6 → 1274,8
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] FIRQ10 & 11 (SLINK): ", cnt_test);
 
// NOTE: this test requires FIFO sizes = 1
 
cnt_test++;
 
// enable SLINK
1334,6 → 1314,8
 
// shutdown SLINK
neorv32_slink_disable();
neorv32_cpu_irq_disable(CSR_MIE_FIRQ10E);
neorv32_cpu_irq_disable(CSR_MIE_FIRQ11E);
}
 
 
1352,14 → 1334,17
 
cnt_test++;
 
// program wake-up timer
neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + 1000);
 
// clear timeout wait flag
tmp_a = neorv32_cpu_csr_read(CSR_MSTATUS);
tmp_a &= ~(1 << CSR_MSTATUS_TW);
neorv32_cpu_csr_write(CSR_MSTATUS, tmp_a);
 
// program wake-up timer
neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + 500);
 
// enable interrupt
neorv32_cpu_irq_enable(CSR_MIE_MTIE);
 
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
1367,6 → 1352,10
asm volatile ("wfi"); // put CPU into sleep mode
}
 
// no more mtime interrupts
neorv32_cpu_irq_disable(CSR_MIE_MTIE);
neorv32_mtime_set_timecmp(-1);
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_MTI) {
test_fail();
}
1374,10 → 1363,7
test_ok();
}
 
// no more mtime interrupts
neorv32_mtime_set_timecmp(-1);
 
 
// ----------------------------------------------------------
// Test invalid CSR access in user mode
// ----------------------------------------------------------
1384,32 → 1370,20
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] Invalid CSR access (mstatus) from user mode: ", cnt_test);
 
// skip if U-mode is not implemented
if (neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_U)) {
cnt_test++;
 
cnt_test++;
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
// access to misa not allowed for user-level programs
tmp_a = neorv32_cpu_csr_read(CSR_MISA);
}
 
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
// access to misa not allowed for user-level programs
tmp_a = neorv32_cpu_csr_read(CSR_MISA);
}
 
if (tmp_a != 0) {
PRINT_CRITICAL("%c[1m<SECURITY FAILURE> %c[0m\n", 27, 27);
}
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
}
else {
test_fail();
}
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
}
else {
PRINT_STANDARD("skipped (n.a. without U-ext)\n");
test_fail();
}
 
 
1456,7 → 1430,7
// find out minimal region size (granularity)
tmp_b = neorv32_cpu_pmp_get_granularity();
 
tmp_a = SYSINFO_DSPACE_BASE; // base address of protected region
tmp_a = NEORV32_SYSINFO.DSPACE_BASE; // base address of protected region
PRINT_STANDARD("Creating protected page (NAPOT, [!X,!W,!R], %u bytes) @ 0x%x: ", tmp_b, tmp_a);
 
// configure
1502,6 → 1476,7
 
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
tmp_b = 0;
{
tmp_b = neorv32_cpu_load_unsigned_word(tmp_a); // load access -> should fail
}
1732,6 → 1707,8
void sim_irq_trigger(uint32_t sel) {
 
*(IO_REG32 (0xFF000000)) = sel;
asm volatile("nop"); // interrupt should kick in here (latest)
*(IO_REG32 (0xFF000000)) = 0;
}
 
 
1792,9 → 1769,9
int __neorv32_crt0_after_main(int32_t return_code) {
 
// make sure sim mode is disabled and UARTs are actually enabled
UART0_CT |= (1 << UART_CT_EN);
UART0_CT &= ~(1 << UART_CT_SIM_MODE);
UART1_CT = UART0_CT;
NEORV32_UART0.CTRL |= (1 << UART_CTRL_EN);
NEORV32_UART0.CTRL &= ~(1 << UART_CTRL_SIM_MODE);
NEORV32_UART1.CTRL = NEORV32_UART0.CTRL;
 
// minimal result report
PRINT_CRITICAL("%u/%u\n", (uint32_t)return_code, (uint32_t)cnt_test);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.