diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-gpio-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-gpio-01.reference_output index e6fd4d7ff..73f898ca0 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-gpio-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-gpio-01.reference_output @@ -5,7 +5,19 @@ A5A5A5A5 # test output pins 00000000 # test input enables 5A5A0000 A55A0000 # test XOR -# A55A0000 # test interrupt pins -# 5AA5FFFF -# 00000000 -# 00000000 +A55A0000 # Test interrupt pending bits: high_ip +5AA5FFFF # low_ip +00000000 # rise_ip +00000000 # fall_ip +A4AA0000 # input_val +A5FA0000 # high_ip +5BF50000 # low_ip +00A00000 # rise_ip +01500000 # fall_ip +00000000 # MEIP +00000000 # Test interrupts can be enabled without being triggered: MIP = 0 +00000000 # MIP = 0 +00000000 # MIP = 0 +00000000 # MIP = 0 +00000800 # Test interrupts can be enabled and triggered: MEIP set +00000000 # MEIP = 0 diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-TEST-LIB-32.h b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-TEST-LIB-32.h index a72ae385a..0caad5d0b 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-TEST-LIB-32.h +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-TEST-LIB-32.h @@ -827,6 +827,28 @@ trap_handler_end_\MODE\(): // place to jump to so we can skip the trap handler a addi a6, a6, 4 .endm +// Place this macro in peripheral tests to setup all the PLIC registers to generate external interrupts +.macro SETUP_PLIC + # Setup PLIC with a series of register writes + + .equ PLIC_INTPRI_GPIO, 0x0C00000C # GPIO is interrupt 3 + .equ PLIC_INTPRI_UART, 0x0C000028 # UART is interrupt 10 + .equ PLIC_INTPENDING0, 0x0C001000 # intPending0 register + .equ PLIC_INTEN00, 0x0C002000 # interrupt enables for context 0 (machine mode) sources 31:1 + .equ PLIC_INTEN10, 0x0C002080 # interrupt enables for context 1 (supervisor mode) sources 31:1 + .equ PLIC_THRESH0, 0x0C200000 # Priority threshold for context 0 (machine mode) + .equ PLIC_CLAIM0, 0x0C200004 # Claim/Complete register for context 0 + .equ PLIC_THRESH1, 0x0C201000 # Priority threshold for context 1 (supervisor mode) + .equ PLIC_CLAIM1, 0x0C201004 # Claim/Complete register for context 1 + + .4byte PLIC_THRESH0, 0, write32_test # Set PLIC machine mode interrupt threshold to 0 to accept all interrupts + .4byte PLIC_THRESH1, 7, write32_test # Set PLIC supervisor mode interrupt threshold to 7 to accept no interrupts + .4byte PLIC_INTPRI_GPIO, 7, write32_test # Set GPIO to high priority + .4byte PLIC_INTPRI_UART, 7, write32_test # Set UART to high priority + .4byte PLIC_INTEN00, 0xFFFFFFFF, write32_test # Enable all interrupt sources for machine mode + .4byte PLIC_INTEN10, 0x00000000, write32_test # Disable all interrupt sources for supervisor mode +.endm + .macro END_TESTS // invokes one final ecall to return to machine mode then terminates this program, so the output is // 0x8: termination called from U mode @@ -937,6 +959,20 @@ read08_test: addi a6, a6, 4 j test_loop // go to next test case +readmip_test: // read the MIP into the signature + csrr t2, mip + sw t2, 0(t1) + addi t1, t1, 4 + addi a6, a6, 4 + j test_loop // go to next test case + +readsip_test: // read the MIP into the signature + csrr t2, sip + sw t2, 0(t1) + addi t1, t1, 4 + addi a6, a6, 4 + j test_loop // go to next test case + goto_s_mode: // return to address in t3, li a0, 3 // Trap handler behavior (go to supervisor mode) diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-gpio-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-gpio-01.S index 38bc533b1..b8a751c55 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-gpio-01.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-gpio-01.S @@ -72,6 +72,7 @@ test_cases: .4byte input_val, 0x00000000, read32_test # input_val reset to zero .4byte input_en, 0x00000000, read32_test # input_en reset to zero +# *** add more # =========== Test output and input pins =========== @@ -86,36 +87,49 @@ test_cases: .4byte input_en, 0x00000000, write32_test # disable all input pins .4byte input_val, 0x00000000, read32_test # read 0 since input pins are disabled .4byte input_en, 0xFFFF0000, write32_test # enable a few input pins -.4byte input_val, 0x5A5A0000, read32_test # read part of pattern set above. +.4byte input_val, 0x5A5A0000, read32_test # read part of pattern set above. # =========== Test XOR functionality =========== .4byte out_xor, 0xFF00FF00, write32_test # invert certain pin values -.4byte input_val, 0xA55A0000, read32_test # read inverted pins and verify input enable is working +.4byte input_val, 0xA55A0000, read32_test # read inverted pins and verify input enable is working -# =========== End of functioning tests =========== -# # =========== Test Interrupt Pending bits =========== +# =========== Test Interrupt Pending bits =========== -# .4byte low_ip, 0xFFFFFFFF, write32_test # clear pending low interrupts -# .4byte high_ip, 0xFFFFFFFF, write32_test # clear pending high interrupts -# .4byte rise_ip, 0xFFFFFFFF, write32_test # clear pending rise interrupts -# .4byte fall_ip, 0xFFFFFFFF, write32_test # clear pending fall interrupts -# .4byte high_ip, 0xA55A0000, read32_test # check pending high interrupts -# .4byte low_ip, 0x5AA5FFFF, read32_test # check pending low interrupts -# .4byte rise_ip, 0x00000000, read32_test # check pending rise interrupts -# .4byte fall_ip, 0x00000000, read32_test # check pending fall interrupts -# .4byte output_val, 0x5BAA000F, write32_test # change output pattern to check rise/fall interrupts -# .4byte input_val, 0xA4AA0000, read32_test # check new output matches expected output -# .4byte high_ip, 0xA5FA00000, read32_test # high interrupt pending *** (is this correct?) -# .4byte low_ip, 0x5BF50000, read32_test # low interrupt pending should be opposite high for enabled pins -# .4byte rise_ip, 0x00A00000, read32_test # check for changed bits (rising) -# .4byte fall_ip, 0x01500000, read32_test # check for changed bits (falling) +SETUP_PLIC -# # =========== Test Interrupt Enable without interrupts =========== +.4byte low_ip, 0xFFFFFFFF, write32_test # clear pending low interrupts +.4byte high_ip, 0xFFFFFFFF, write32_test # clear pending high interrupts +.4byte rise_ip, 0xFFFFFFFF, write32_test # clear pending rise interrupts +.4byte fall_ip, 0xFFFFFFFF, write32_test # clear pending fall interrupts +.4byte high_ip, 0xA55A0000, read32_test # check pending high interrupts +.4byte low_ip, 0x5AA5FFFF, read32_test # check pending low interrupts +.4byte rise_ip, 0x00000000, read32_test # check pending rise interrupts +.4byte fall_ip, 0x00000000, read32_test # check pending fall interrupts +.4byte output_val, 0x5BAA000F, write32_test # change output pattern to check rise/fall interrupts +.4byte input_val, 0xA4AA0000, read32_test # check new output matches expected output +.4byte high_ip, 0xA5FA00000, read32_test # high interrupt pending *** (is this correct?) +.4byte low_ip, 0x5BF50000, read32_test # low interrupt pending should be opposite high for enabled pins +.4byte rise_ip, 0x00A00000, read32_test # check for changed bits (rising) +.4byte fall_ip, 0x01500000, read32_test # check for changed bits (falling) +.4byte 0x0, 0x00000000, readmip_test # Check no external interrupt has been generated -# .4byte high_ie, 0x00010000, write32_test # enable high interrupt on bit 16, no pending interrupt -# .4byte high_ip, 0xA5FA0000, read32_test # read to show no interrupt has happened -# .4byte low_ie, 0x00020000, write32_test # enable low interrupt on bit 17, no pending interrupt -# .4byte low_ip, 5BF50000, read32_test # read to show no interrupt has happened +# =========== Test interrupts can be enabled without being triggered =========== + +.4byte high_ie, 0x00010000, write32_test # enable high interrupt on bit 16, no pending interrupt +.4byte 0x0, 0x00000000, readmip_test # No external interrupt should be pending +.4byte low_ie, 0x00020000, write32_test # enable low interrupt on bit 17, no pending interrupt +.4byte 0x0, 0x00000000, readmip_test # No external interrupt should be pending +.4byte rise_ie, 0x00010000, write32_test # enable rise interrupt on bit 16, no pending interrupt +.4byte 0x0, 0x00000000, readmip_test # No external interrupt should be pending +.4byte fall_ie, 0x00010000, write32_test # enable fall interrupt on bit 16, no pending interrupt +.4byte 0x0, 0x00000000, readmip_test # No external interrupt should be pending + +# =========== Test interrupts can be enabled and triggered + +.4byte high_ie, 0x00020000, write32_test # enable high interrupt on bit 17, which is pending +.4byte 0x0, 0x00000800, readmip_test # MEIP should be raised +.4byte low_ie, 0x00000000, write32_test # disable high interrupt on bit 17, which is pending +.4byte 0x0, 0x00000000, readmip_test # MEIP should be released .4byte 0x0, 0x0, terminate_test # terminate tests