summaryrefslogtreecommitdiff
path: root/assembly/trap-test
diff options
context:
space:
mode:
Diffstat (limited to 'assembly/trap-test')
-rw-r--r--assembly/trap-test/Makefile24
l---------assembly/trap-test/rvcontroller.ld1
-rw-r--r--assembly/trap-test/trap-test.S65
-rwxr-xr-xassembly/trap-test/trap-test.elfbin0 -> 5596 bytes
-rw-r--r--assembly/trap-test/trap-test.hex13
-rw-r--r--assembly/trap-test/trap-test.obin0 -> 1708 bytes
6 files changed, 103 insertions, 0 deletions
diff --git a/assembly/trap-test/Makefile b/assembly/trap-test/Makefile
new file mode 100644
index 0000000..8833502
--- /dev/null
+++ b/assembly/trap-test/Makefile
@@ -0,0 +1,24 @@
+MARCH ?= rv32imacbzicntr_zicond_zicsr_zifencei_zihintpause_zilsd_zclsd_zabha_zacas_zbkb_zbkx_zcb_zcmp_zcmt
+
+.PHONY: all dump load clean
+
+all: trap-test.hex
+
+trap-test.o: trap-test.S
+ riscv32-none-elf-as -I../rvcontroller-libraries -march=${MARCH} -o trap-test.o trap-test.S
+
+trap-test.elf: trap-test.o
+ riscv32-none-elf-ld -T rvcontroller.ld --no-warn-rwx-segments -o trap-test.elf trap-test.o
+
+dump: trap-test.elf
+ riscv32-none-elf-objdump -d trap-test.elf
+
+trap-test.hex: trap-test.elf
+ riscv32-none-elf-objcopy -O ihex trap-test.elf trap-test.hex
+
+load: trap-test.hex
+ bash -c "wl-copy < trap-test.hex"
+
+clean:
+ rm -f trap-test.hex trap-test.elf trap-test.o
+
diff --git a/assembly/trap-test/rvcontroller.ld b/assembly/trap-test/rvcontroller.ld
new file mode 120000
index 0000000..bc01402
--- /dev/null
+++ b/assembly/trap-test/rvcontroller.ld
@@ -0,0 +1 @@
+../../rvcontroller.ld \ No newline at end of file
diff --git a/assembly/trap-test/trap-test.S b/assembly/trap-test/trap-test.S
new file mode 100644
index 0000000..ec928a7
--- /dev/null
+++ b/assembly/trap-test/trap-test.S
@@ -0,0 +1,65 @@
+la t0,handler
+csrw mtvec,t0 # Set trap handler address and mode (0/direct)
+
+li t0,0xdeadbeef # No RAM here
+lw t1,0(t0) # This should give a load access fault, which should be handled
+
+li a7,4 # Print string
+la a0,readvalmsg # "Read value "
+ecall
+
+li a7,1 # Print integer
+mv a0,t1 # Get the value read earlier
+ecall
+
+li a7,11 # Print character
+li a0,'\n'
+ecall
+
+li a7,10 # Exit program
+ecall
+
+readvalmsg: .asciz "Read value "
+
+.balign 4
+handler:
+# IMPORTANT NOTE: This handler is for demonstration purposes only and clobbers a0/a1/a7/t1!
+# Its "handling" is also roughly the equivalent of Visual Basic's infamous "on error resume next"
+li a7,4 # Print string
+la a0,trapmsg # "Got trap "
+ecall
+
+li a7,1 # Print integer
+csrr a0,mcause # Read trap cause
+ecall
+
+li a7,11 # Print character
+li a0,'\n'
+ecall
+
+li a7,4 # Print string
+la a0,mepcmsg # "at "
+ecall
+
+li a7,1 # Print integer
+csrr a0,mepc # Read faulting address
+ecall
+
+li a7,11 # Print character
+li a0,'\n'
+ecall
+
+csrr a0,mepc # Read faulting address again
+lw a1,0(a0) # Read faulting instruction into a1
+li a7,0x00000003
+andn a1,a7,a1 # Invert it and AND with 0x3 (gives 0 if last two bits were 11, nonzero otherwise)
+addi a0,a0,2 # Move fault address 2 bytes forward (all instructions are at least this long)
+bnez a1,handler_compressed # If it was compressed, that's all the movement needed
+addi a0,a0,2 # Otherwise it needs to go two more bytes forward
+handler_compressed:
+csrw mepc,a0 # Write the adjusted return address back
+li t1,1234 # Fake the load having succeeded
+mret # And go back there
+
+trapmsg: .asciz "Got trap "
+mepcmsg: .asciz "at "
diff --git a/assembly/trap-test/trap-test.elf b/assembly/trap-test/trap-test.elf
new file mode 100755
index 0000000..aa5bda6
--- /dev/null
+++ b/assembly/trap-test/trap-test.elf
Binary files differ
diff --git a/assembly/trap-test/trap-test.hex b/assembly/trap-test/trap-test.hex
new file mode 100644
index 0000000..fe2b395
--- /dev/null
+++ b/assembly/trap-test/trap-test.hex
@@ -0,0 +1,13 @@
+:10000000970200009382820473905230B7C2ADDE33
+:100010009382F2EE03A30200914817050000130536
+:1000200025027300000085481A8573000000AD4862
+:10003000294573000000A9487300000052656164FF
+:100040002076616C75652000914817050000130546
+:10005000C505730000008548732520347300000037
+:10006000AD482945730000009148170500001305AD
+:100070006504730000008548732510347300000088
+:10008000AD48294573000000732510340C418D489C
+:10009000B3F5B840090591E1090573101534130350
+:1000A000204D73002030476F7420747261702000FF
+:0600B00061742000010054
+:00000001FF
diff --git a/assembly/trap-test/trap-test.o b/assembly/trap-test/trap-test.o
new file mode 100644
index 0000000..0796ad9
--- /dev/null
+++ b/assembly/trap-test/trap-test.o
Binary files differ