/////////////////////////////////////////// // WALLY-PERIPH.S // 64 bit version // // Ben Bracker (bbracker@hmc.edu) // // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University // Adapted from Imperas RISCV-TEST_SUITE // // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software // is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT // OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /////////////////////////////////////////// #include "model_test.h" #include "arch_test.h" RVTEST_ISA("RV64I") .section .text.init .globl rvtest_entry_point rvtest_entry_point: RVMODEL_BOOT RVTEST_CODE_BEGIN # --------------------------------------------------------------------------------------------- j main_code # Thanks to MTVEC[1:0], trap handler addresses need to be aligned to a 4-byte boundary .align 2 ################### ################### trap_handler: ##### ################### ################### # save registers addi sp, sp, 0x28 sw t0, 0x00(sp) sw t1, 0x08(sp) sw t2, 0x10(sp) sw t3, 0x18(sp) sw t4, 0x20(sp) # =================================== # ===== Signature Output Format ===== # =================================== # # Base address = +0x40* # Use sigout-translator.py for help with this! # # : # 0x00: test ID = 0xBEEF # 0x04: mcause (low) = 0x0000000B (MEIP) or 0x00000009 (SEIP) # 0x08: mcause (high) = 0x80000000 # ----- If GPIO ----- # 0x0C: claim ID = 3 # 0x10: input_val # 0x14: output_val # 0x18: incoming rise_ip # 0x1C: serviced rise_ip = 0 # 0x20: incoming fall_ip # 0x24: serviced fall_ip = 0 # 0x28: incoming high_ip # 0x2C: serviced high_ip = 0 # 0x30: incoming low_ip # 0x34: serviced low_ip = 0 # ----- If UART ----- # 0x0C: claim ID = 0xA # 0x10: IIR # 0x14: LSR # 0x18: LSR (after reading LSR) # 0x1C: RBR # 0x20: LSR (after reading RBR too) # 0x24: IIR (after reading everything else) # 0x28: SCR # 0x00: test ID = 0xBEEF la t0, wally_signature sub t0, s0, t0 # sigout offset srli t0, t0, 6 # intr_num add t0, t0, a1 sw t0, 0x00(s0) # 0x04: mcause (low) = 0x0000000B (MEIP) or 0x00000009 (SEIP) # 0x08: mcause (high) = 0x80000000 csrrc t0, mcause, x0 andi t1, t0, 0x7FF sw t0, 0x04(s0) srli t0,t0,32 sw t0, 0x08(s0) # MEIP or SEIP? # MEIP is on context 0 li t4, 0x0C200004 li t0, 0xB beq t1, t0, meip # SEIP is on context 1 li t4, 0x0C201004 meip: # 0x0C: claim ID # 3: GPIO # A: UART mv t0, t4 lw t1, 0(t0) sw t1, 0x0C(s0) li t2, 0xA beq t1, t2, uart_handler li t2, 3 bne t1, t2, trap_handler_end gpio_handler: # 0x10: input_val li t0, 0x10060000 lw t1, 0x00(t0) sw t1, 0x10(s0) # 0x14: output_val lw t1, 0x0C(t0) sw t1, 0x14(s0) # 0x18: incoming rise_ip lw t1, 0x1C(t0) sw t1, 0x18(s0) # 0x1C: serviced rise_ip = 0 sw t1, 0x1C(t0) lw t1, 0x1C(t0) sw t1, 0x1C(s0) # 0x20: incoming fall_ip lw t1, 0x24(t0) sw t1, 0x20(s0) # 0x24: serviced fall_ip = 0 sw t1, 0x24(t0) lw t1, 0x24(t0) sw t1, 0x24(s0) # 0x28: incoming high_ip lw t1, 0x2C(t0) sw t1, 0x28(s0) # 0x2C: serviced high_ip = 0 sw t1, 0x2C(t0) lw t1, 0x2C(t0) sw t1, 0x2C(s0) # 0x30: incoming low_ip lw t1, 0x34(t0) sw t1, 0x30(s0) # 0x34: serviced low_ip = 0 sw t1, 0x34(t0) lw t1, 0x34(t0) sw t1, 0x34(s0) # disable high_ie and low_ie so interrupt # is not taken again immediately li t1, 0 sw t1, 0x28(t0) sw t1, 0x30(t0) # signal to main code that gpio was serviced ori a0, a0, 0b00001000 # signal to plic that gpio was serviced mv t0, t4 li t1, 3 sw t1, 0(t0) j trap_handler_end uart_handler: # 0x10: IIR li t0, 0x10000000 lbu t1, 2(t0) sw t1, 0x10(s0) # 0x14: LSR lbu t1, 5(t0) sw t1, 0x14(s0) # 0x18: LSR (after reading LSR) lbu t1, 5(t0) sw t1, 0x18(s0) # 0x1C: RBR lbu t1, 0(t0) sw t1, 0x1C(s0) # 0x20: LSR (after reading RBR) lbu t1, 5(t0) sw t1, 0x20(s0) # 0x24: IIR (after reading everything else) lbu t1, 2(t0) sw t1, 0x24(s0) # 0x28: SCR lbu t1, 7(t0) sw t1, 0x28(s0) # signal to main code that uart was serviced ori a0, a0, 0b00010000 # signal to plic that uart was serviced mv t0, t4 li t1, 0xA sw t1, 0(t0) trap_handler_end: # increment signature pointer addi s0,s0,0x40 # restore vars ld t0, 0x00(sp) ld t1, 0x08(sp) ld t2, 0x10(sp) ld t3, 0x18(sp) ld t4, 0x20(sp) addi sp, sp, SEXT_IMM(-0x28) mret ################ ################ main_code: ##### ################ ################ ########################## ##### Initialization ##### ########################## # ========== Global Vars ========== la s0, wally_signature # signature output base adr la sp, stack # stack pointer li a0, 0 # interrupt complete flag # ========== Configure Privileged Unit ========== # load address of trap handler la t0, trap_handler csrrw x0, mtvec, t0 # delegate all external interrupts to machine mode li t0, 0xD00 csrrc x0, mideleg, t0 # set MIE li t0, 0x8 csrrs x0, mstatus, t0 ################################## ##### Test 1 - Signs of Life ##### ################################## li a1, 0x01beef00 # group ID # clear MEIE (good to turn off while configuring peripherals) li t0, 0x800 csrrc x0, mie, t0 # ========== Configure PLIC ========== # priority threshold = 0 li t0, 0xC200000 li t1, 0 sw t1, 0(t0) # source 3 (GPIO) priority = 6 li t0, 0xC000000 li t1, 6 sw t1, 0x0C(t0) # source 0xA (UART) priority = 7 li t1, 7 sw t1, 0x28(t0) # enable sources 3,0xA li t0, 0x0C002000 li t1, 0b10000001000 sw t1, 0(t0) # ========== Configure UART ========== # MCR: Loop = 1 li t0, 0x10000000 li t1, 0b10000 sb t1, 4(t0) # LCR: Use 8 data bits plus odd parity bit li t1, 0b00001011 sb t1, 3(t0) # IER: Enable Received Data Available Interrupt li t1, 0x01 sb t1, 1(t0) # ========== Configure GPIO ========== # raise all input_en li t0, 0x10060000 li t1, 0xFFFFFFFF sw t1, 0x04(t0) # raise all output_en sw t1, 0x08(t0) # raise all rise_en sw t1, 0x18(t0) # ========== Execute Test ========== # set MEIE li t0, 0x800 csrrs x0, mie, t0 Intr01BEEF00: # UART TX 'h' li t0, 0x10000000 li t1, 'h' sb t1, 0(t0) # wait to finish li t1, 0b00010000 1: bne t1,a0,1b li a0, 0 Intr01BEEF01: # GPIO raise pin 19 li t0, 0x10060000 li t1, 0x00080000 sw t1, 0x0C(t0) # wait to finish li t1, 0b00001000 1: bne t1,a0,1b li a0, 0 # Now let's go bonkers and trigger both! Intr01BEEF02: # TX 'e' li t0, 0x10000000 li t1, 'e' sb t1, 0(t0) Intr01BEEF03: # GPIO lower pin 19 raise pin 0 li t0, 0x10060000 li t1, 0x00000001 sw t1, 0x0C(t0) # wait to finish li t1, 0b00011000 1: bne t1,a0,1b li a0, 0 ################################## ##### Test 2 - GPIO Testing ##### ################################## li a1, 0x02beef00 # group ID # clear MEIE li t0, 0x800 csrrc x0, mie, t0 # ========== Configure PLIC ========== # priority threshold = 0 li t0, 0xC200000 li t1, 0 sw t1, 0(t0) # source 3 (GPIO) priority = 1 li t0, 0xC000000 li t1, 1 sw t1, 0x0C(t0) # enable source 3 li t0, 0x0C002000 li t1, 0b1000 sw t1, 0(t0) # ========== Input Enables ========== # Note that this inherits # a bit of state from the previous test. # Namely output_val = 0x00000001 # # enable some inputs li t0, 0x10060000 li t1, 0x0000FFFF sw t1, 0x04(t0) # enable all outputs li t1, 0xFFFFFFFF sw t1, 0x08(t0) # enable all rising edge interrupts sw t1, 0x18(t0) # set MEIE li t1, 0x800 csrrs x0, mie, t1 # raise some input-disabled pins # interrupt should not happen li t1, 0xF0F00001 sw t1, 0x0C(t0) Intr02BEEF04: # change some input-enabled pins # interrupt should happen li t1, 0x3030F0F0 sw t1, 0x0C(t0) # wait to finish li t1, 0b00001000 1: bne t1,a0,1b li a0, 0 Intr02BEEF05: # enable some different inputs # this itself will cause some rise interrupts li t1, 0xFFFF0000 sw t1, 0x04(t0) # wait to finish li t1, 0b00001000 1: bne t1,a0,1b li a0, 0 # ========== Output Enables ========== # enable all fall interrupts li t1, 0xFFFFFFFF sw t1, 0x20(t0) Intr02BEEF06: # disable some outputs # should affect input value but not output val register itself # this itself will cause some fall interrupts li t1, 0xFF0000FF sw t1, 0x08(t0) # wait to finish li t1, 0b00001000 1: bne t1,a0,1b li a0, 0 # change pins whose inputs and/or outputs are disabled # should not cause any rise or fall interrupts li t1, 0x300F0F0F sw t1, 0x0C(t0) Intr02BEEF07: # change pins whose inputs and outputs are enabled li t1, 0x0F0F0F0F sw t1, 0x0C(t0) # wait to finish li t1, 0b00001000 1: bne t1,a0,1b li a0, 0 # ========== Clear GPIO State ========== # (I've gotten a little annoyed with tests depending # upon the results of previous tests). # disable all interrupts sw x0, 0x18(t0) sw x0, 0x20(t0) sw x0, 0x28(t0) sw x0, 0x30(t0) # enable all inputs li t1, 0xFFFFFFFF sw t1, 0x04(t0) # enable all outputs li t1, 0xFFFFFFFF sw t1, 0x08(t0) # set initial output state sw x0, 0x0C(t0) # clear all pending interrupts li t1, 0xFFFFFFFF sw t1, 0x1C(t0) sw t1, 0x24(t0) sw t1, 0x2C(t0) sw t1, 0x34(t0) # ========== Rise Interrupt Enables ========== # enable some rising edge interrupts li t1, 0x0000FFFF sw t1, 0x18(t0) Intr02BEEF08: # raise some pins li t1, 0x00FFFF00 sw t1, 0x0C(t0) # wait to finish li t1, 0b00001000 1: bne t1,a0,1b li a0, 0 Intr02BEEF09: # raise pins whose rise IEs are disabled # should not cause an interrupt li t1, 0x33FFFF00 sw t1, 0x0C(t0) # raise pins whose rise IEs are enabled li t1, 0x33FFFF33 sw t1, 0x0C(t0) # wait to finish li t1, 0b00001000 1: bne t1,a0,1b li a0, 0 # =========== Fall Interrupts =========== # (admittedly these are already used elsewhere) # disable all rising edge interrupts li t1, 0 sw t1, 0x18(t0) # enable some falling edge interrupts li t1, 0x0000FFFF sw t1, 0x20(t0) Intr02BEEF0A: # lower some pins li t1, 0x33000033 sw t1, 0x0C(t0) # wait to finish li t1, 0b00001000 1: bne t1,a0,1b li a0, 0 # lower pins whose fall IEs are disabled # and raise a bunch of other pins # should not cause an interrupt li t1, 0x00CCCC33 sw t1, 0x0C(t0) Intr02BEEF0B: # lower pins whose fall IEs are enabled li t1, 0x00CCCC00 sw t1, 0x0C(t0) # wait to finish li t1, 0b00001000 1: bne t1,a0,1b li a0, 0 # =========== High Interrupts =========== # disable all falling edge interrupts li t1, 0 sw t1, 0x20(t0) # enable some high_ie's for low pins # should not cause an interrupt li t1, 0xFF0000FF sw t1, 0x28(t0) Intr02BEEF0C: # enable some high_ie's for high pins li t1, 0x0000FFFF sw t1, 0x28(t0) # wait to finish li t1, 0b00001000 1: bne t1,a0,1b li a0, 0 # lower all pins li t1, 0 sw t1, 0x0C(t0) # lower any existing high_ip's li t1, 0xFFFFFFFF sw t1, 0x2C(t0) # re-enable some high_ie's li t1, 0xFFFF0000 sw t1, 0x28(t0) # raise some pins whose high_ie's are disabled li t1, 0x0000CCCC sw t1, 0x0C(t0) # disable some inputs li t1, 0xFF00FFFF sw t1, 0x04(t0) # raise some pins whose inputs are disabled li t1, 0x00CCCCCC sw t1, 0x0C(t0) Intr02BEEF0D: # raise some pins whose high_ie's and inputs are enabled li t1, 0xCCCCCCCC sw t1, 0x0C(t0) # wait to finish li t1, 0b00001000 1: bne t1,a0,1b li a0, 0 # =========== Low Interrupts =========== # disable all high interrupts li t1, 0 sw t1, 0x28(t0) # enable all inputs li t1, 0xFFFFFFFF sw t1, 0x04(t0) # enable some low_ie's for high pins # should not cause an interrupt li t1, 0xCC0000CC sw t1, 0x30(t0) Intr02BEEF0E: # enable some low_ie's for low pins li t1, 0xCCCCFFFF sw t1, 0x30(t0) # wait to finish li t1, 0b00001000 1: bne t1,a0,1b li a0, 0 # raise all pins li t1, 0xFFFFFFFF sw t1, 0x0C(t0) # lower any existing low_ip's # actually takes a little time for vals # to propagate through synchronizer # so this extra load is a nop effectively li t1, 0xFFFFFFFF sw t1, 0x34(t0) # re-enable some low_ie's li t1, 0xFF0000FF sw t1, 0x30(t0) # lower some pins whose low_ie's are disabled li t1, 0xFF1111FF sw t1, 0x0C(t0) Intr02BEEF0F: # disable some inputs of pins whose low_ie's are enabled li t1, 0x0000FFFF sw t1, 0x04(t0) # wait to finish li t1, 0b00001000 1: bne t1,a0,1b li a0, 0 # ========== Clear GPIO State ========== # disable all interrupts sw x0, 0x18(t0) sw x0, 0x20(t0) sw x0, 0x28(t0) sw x0, 0x30(t0) # enable all inputs li t1, 0xFFFFFFFF sw t1, 0x04(t0) # enable all outputs li t1, 0xFFFFFFFF sw t1, 0x08(t0) # set initial output state sw x0, 0x0C(t0) # clear all pending interrupts li t1, 0xFFFFFFFF sw t1, 0x1C(t0) sw t1, 0x24(t0) sw t1, 0x2C(t0) sw t1, 0x34(t0) # ========== Output XOR Test ========== # enable some inputs li t1, 0x0000FFFF sw t1, 0x04(t0) # enable some outputs li t1, 0xFF0000FF sw t1, 0x08(t0) # enable all rising and falling edge interrupts li t1, 0xFFFFFFFF sw t1, 0x18(t0) sw t1, 0x20(t0) Intr02BEEF10: # XOR all outputs li t1, 0xFFFFFFFF sw t1, 0x40(t0) # wait to finish li t1, 0b00001000 1: bne t1,a0,1b li a0, 0 Intr02BEEF11: # XOR some outputs li t1, 0x33333333 sw t1, 0x40(t0) # wait to finish li t1, 0b00001000 1: bne t1,a0,1b li a0, 0 # ========== Clear GPIO State ========== # disable all interrupts sw x0, 0x18(t0) sw x0, 0x20(t0) sw x0, 0x28(t0) sw x0, 0x30(t0) # enable all inputs li t1, 0xFFFFFFFF sw t1, 0x04(t0) # enable all outputs li t1, 0xFFFFFFFF sw t1, 0x08(t0) # set initial output state sw x0, 0x0C(t0) # clear XOR li t1, 0x00000000 sw t1, 0x40(t0) # clear all pending interrupts li t1, 0xFFFFFFFF sw t1, 0x1C(t0) sw t1, 0x24(t0) sw t1, 0x2C(t0) sw t1, 0x34(t0) ################################## ##### Test 3 - UART Testing ##### ################################## li a1, 0x03beef00 # group ID # clear MEIE li t0, 0x800 csrrc x0, mie, t0 # ========== Configure PLIC ========== # priority threshold = 0 li t0, 0xC200000 li t1, 0 sw t1, 0(t0) # source 0xA (UART) priority = 1 li t0, 0xC000000 li t1, 1 sw t1, 0x28(t0) # enable source 0xA li t0, 0x0C002000 li t1, 0b10000000000 sw t1, 0(t0) # ========== Transmitter Holding Register Empty Interrupt (THRE) ========== # MCR: Loop = 1 li t0, 0x10000000 li t1, 0b00010000 sb t1, 4(t0) # LCR: Use 8 data bits plus odd parity bit li t1, 0b00001011 sb t1, 3(t0) # IER: Disable all interrupts for now li t1, 0x0 sb t1, 1(t0) # set MEIE li t1, 0x800 csrrs x0, mie, t1 # THR: TX 'l' li t1, 'l' sb t1, 0(t0) # wait directly on UART for completion li t1, 0b01100001 1: lb t2, 5(t0) bne t1, t2, 1b Intr03BEEF12: # IER: enable THR empty intr (ETBEI) li t1, 0b00000010 sb t1, 1(t0) # wait to finish li t1, 0b00010000 1: bne t1,a0,1b li a0, 0 # IER: disable THR empty intr (ETBEI) sb x0, 1(t0) # THR: TX 'l' li t1, 'l' sb t1, 0(t0) # THR: TX 'o' li t1, 'o' sb t1, 0(t0) Intr03BEEF13: # IER: enable THR empty intr (ETBEI) li t1, 0b00000010 sb t1, 1(t0) # This will take a few cycles before UART finishes TX'ing # If we see SCR modifications in output, it means UART probably # did wait until empty THR before triggering the interrupt. sb t1, 7(t0) # wait to finish li t1, 0b00010000 1: bne t1,a0,1b li a0, 0 # ========== Received Data Available Intrrupt (ERBFI) & Loop Mode ========== # Clear SCR sb x0, 7(t0) Intr03BEEF14: # IER: enable RBR ready intr ERBFI li t1, 0x1 sb t1, 1(t0) # wait to finish li t1, 0b00010000 1: bne t1,a0,1b li a0, 0 Intr03BEEF15: # THR: TX ' ' li t1, 0x20 sb t1, 0(t0) # This will take a few cycles before UART finishes RX'ing # If we see SCR modifications in output, it means UART probably # did wait until received data available before triggering the interrupt. li t1, 3 sb t1, 7(t0) # wait to finish li t1, 0b00010000 1: bne t1,a0,1b li a0, 0 Intr03BEEF16: # THR: TX 't' li t1, 't' sb t1, 0(t0) # Same shenanigans as before, only now we also confirm # that you can read the RBR before new data is available # without messing up the receive interrupt. lb t1, 0(t0) sb t1, 7(t0) # wait to finish li t1, 0b00010000 1: bne t1,a0,1b li a0, 0 # MCR: Loop = 0 li t1, 0b00000000 sb t1, 4(t0) # Clear SCR sb x0, 7(t0) # THR: TX 'h' # should TX but not not trigger interrupt li t1, 'h' sb t1, 0(t0) # wait directly on UART for completion li t1, 0b01100000 1: lb t2, 5(t0) bne t1, t2, 1b # Can use THRE test from before to verify we are transmitting # THR: TX 'e' li t1, 'e' sb t1, 0(t0) # THR: TX 'r' li t1, 'r' sb t1, 0(t0) Intr03BEEF17: # IER: enable THR empty intr (ETBEI) and RBR ready intr (ERBFI) li t1, 0b00000011 sb t1, 1(t0) sb t1, 7(t0) # wait to finish li t1, 0b00010000 1: bne t1,a0,1b li a0, 0 # manually wait until transmitter finishes before enabling loop mode li t1, 0b01100000 1: lb t2, 5(t0) bne t1, t2, 1b # MCR: Loop = 1 li t1, 0b00010000 sb t1, 4(t0) Intr03BEEF18: Intr03BEEF19: # THR: TX 'e' li t1, 'e' sb t1, 0(t0) # wait to finish li t1, 0b00010000 1: bne t1,a0,1b li a0, 0 # wait to finish again li t1, 0b00010000 1: bne t1,a0,1b li a0, 0 # ========== Receiver Line Status Intr (ELSI) & Overrun Error (OE) ========== # IER: Enable Receiver Line Status Intr (ELSI) li t1, 0b00000100 sb t1, 1(t0) li t1, 0xFF sb t1, 7(t0) # We can't cause all kinds of interesting errors, but at least we can # cause an overrun error by transmitting twice without reading. Intr03BEEF1A: # THR: TX '\n' li t1, 0xD sb t1, 0(t0) # THR: TX 'G' li t1, 'G' sb t1, 0(t0) # wait to finish li t1, 0b00010000 1: bne t1,a0,1b li a0, 0 #################################################### ##### Test 4 - Signs of Life on PLIC Context 1 ##### #################################################### li a1, 0x04beef00 # group ID # clear MEIE (good to turn off while configuring peripherals) li t0, 0x800 csrrc x0, mie, t0 # ========== Configure PLIC ========== # priority threshold = 0 li t0, 0xC200000 li t1, 0 sw t1, 0(t0) # source 3 (GPIO) priority = 6 li t0, 0xC000000 li t1, 6 sw t1, 0x0C(t0) # source 0xA (UART) priority = 7 li t1, 7 sw t1, 0x28(t0) # disable sources 3,0xA on context 0 li t0, 0x0C002000 li t1, 0 sw t1, 0(t0) # enable sources 3,0xA on context 1 li t0, 0x0C002080 li t1, 0b10000001000 sw t1, 0(t0) # ========== Configure UART ========== # MCR: Loop = 1 li t0, 0x10000000 li t1, 0b10000 sb t1, 4(t0) # LCR: Use 8 data bits plus odd parity bit li t1, 0b00001011 sb t1, 3(t0) # IER: Enable Received Data Available Interrupt li t1, 0x01 sb t1, 1(t0) # ========== Configure GPIO ========== # raise all input_en li t0, 0x10060000 li t1, 0xFFFFFFFF sw t1, 0x04(t0) # raise all output_en sw t1, 0x08(t0) # raise all rise_en sw t1, 0x18(t0) # ========== Execute Test ========== # set MEIE and SEIE li t0, 0xA00 csrrs x0, mie, t0 Intr04BEEF1B: # UART TX 'e' li t0, 0x10000000 li t1, 'e' sb t1, 0(t0) # wait to finish li t1, 0b00010000 1: bne t1,a0,1b li a0, 0 Intr04BEEF1C: # GPIO raise pin 19 li t0, 0x10060000 li t1, 0x00080000 sw t1, 0x0C(t0) # wait to finish li t1, 0b00001000 1: bne t1,a0,1b li a0, 0 # Now let's go bonkers and trigger both! Intr04BEEF1D: # TX 'n' li t0, 0x10000000 li t1, 'n' sb t1, 0(t0) Intr04BEEF1E: # GPIO lower pin 19 raise pin 0 li t0, 0x10060000 li t1, 0x00000001 sw t1, 0x0C(t0) # wait to finish li t1, 0b00011000 1: bne t1,a0,1b li a0, 0 # --------------------------------------------------------------------------------------------- //terminate_test: // li a0, 2 // Trap handler behavior (go to machine mode) // ecall // writes mcause to the output. // csrw mtvec, x4 // restore original trap handler to halt program RVTEST_CODE_END RVMODEL_HALT RVTEST_DATA_BEGIN # stack memory (size 16 words) .align 3 stack: .fill 16, 8, 0xdeadbeef #ifdef rvtest_mtrap_routine mtrap_sigptr: .fill 64*(XLEN/32),4,0xdeadbeef #endif #ifdef rvtest_gpr_save gpr_save: .fill 32*(XLEN/32),4,0xdeadbeef #endif RVTEST_DATA_END RVMODEL_DATA_BEGIN # signature output wally_signature: .fill 0x200, 8, 0x00000000 RVMODEL_DATA_END