From 33e4744d1c73c9f5512abb4010e4cc81763ab3a2 Mon Sep 17 00:00:00 2001 From: cheapie Date: Fri, 19 Jun 2026 22:38:28 -0500 Subject: Add machine timer interrupt --- assembly/multitask/Makefile | 24 ++++++++++++++ assembly/multitask/multitask.S | 61 ++++++++++++++++++++++++++++++++++++ assembly/multitask/multitask.elf | Bin 0 -> 5608 bytes assembly/multitask/multitask.hex | 12 +++++++ assembly/multitask/multitask.o | Bin 0 -> 1812 bytes assembly/multitask/rvcontroller.ld | 1 + assembly/timer-test/Makefile | 24 ++++++++++++++ assembly/timer-test/rvcontroller.ld | 1 + assembly/timer-test/timer-test.S | 36 +++++++++++++++++++++ assembly/timer-test/timer-test.elf | Bin 0 -> 5352 bytes assembly/timer-test/timer-test.hex | 7 +++++ assembly/timer-test/timer-test.o | Bin 0 -> 1324 bytes 12 files changed, 166 insertions(+) create mode 100644 assembly/multitask/Makefile create mode 100644 assembly/multitask/multitask.S create mode 100755 assembly/multitask/multitask.elf create mode 100644 assembly/multitask/multitask.hex create mode 100644 assembly/multitask/multitask.o create mode 120000 assembly/multitask/rvcontroller.ld create mode 100644 assembly/timer-test/Makefile create mode 120000 assembly/timer-test/rvcontroller.ld create mode 100644 assembly/timer-test/timer-test.S create mode 100755 assembly/timer-test/timer-test.elf create mode 100644 assembly/timer-test/timer-test.hex create mode 100644 assembly/timer-test/timer-test.o (limited to 'assembly') diff --git a/assembly/multitask/Makefile b/assembly/multitask/Makefile new file mode 100644 index 0000000..bb51bce --- /dev/null +++ b/assembly/multitask/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: multitask.hex + +multitask.o: multitask.S + riscv32-none-elf-as -I../rvcontroller-libraries -march=${MARCH} -o multitask.o multitask.S + +multitask.elf: multitask.o + riscv32-none-elf-ld -T rvcontroller.ld --no-warn-rwx-segments -o multitask.elf multitask.o + +dump: multitask.elf + riscv32-none-elf-objdump -d multitask.elf + +multitask.hex: multitask.elf + riscv32-none-elf-objcopy -O ihex multitask.elf multitask.hex + +load: multitask.hex + bash -c "wl-copy < multitask.hex" + +clean: + rm -f multitask.hex multitask.elf multitask.o + diff --git a/assembly/multitask/multitask.S b/assembly/multitask/multitask.S new file mode 100644 index 0000000..d34bf5f --- /dev/null +++ b/assembly/multitask/multitask.S @@ -0,0 +1,61 @@ +la t0,handler +csrw mtvec,t0 # Set trap handler address and mode (0/direct) +li t0,0x400 +csrc mstatush,t0 # Enable trap handler +li t0,0x80 +csrw mie,t0 # Enable machine timer interrupt and disable others +la t1,mmio +csrw 0x801,t1 # Set MMIO base address +lw t0,2(t1) # Load current mtime +addi t0,t0,1 +sw t0,10(t1) # Set mtimecmp for 1 second in the future +csrsi mstatus,8 # Enable interrupts globally +li t0,0x80 +csrs mstatus,t0 # Make sure MPIE is set too + + + +task1: +li a0,1 +li a7,1 +ecall +j task1 + +task2: +li a0,2 +li a7,1 +ecall +j task2 + + +.balign 4 +handler: +lw t0,2(t1) # Load current mtime +addi t0,t0,1 +sw t0,10(t1) # Set mtimecmp for 1 second in the future +la t0,currenttask +lw t2,0(t0) # Get current task number +addi t2,t2,1 # Flip to the other task +andi t2,t2,1 +sw t2,0(t0) # Write the number back +beqz t2,handler_return1 +j handler_return2 + +handler_return1: +la a0,task1 +csrw mepc,a0 # Set return address to start of task 1 +li t0,0x400 +csrc mstatush,t0 +mret + +handler_return2: +la a0,task2 +csrw mepc,a0 # Set return address to start of task 2 +li t0,0x400 +csrc mstatush,t0 +mret + + +currenttask: .word 1 + +mmio: diff --git a/assembly/multitask/multitask.elf b/assembly/multitask/multitask.elf new file mode 100755 index 0000000..dafe381 Binary files /dev/null and b/assembly/multitask/multitask.elf differ diff --git a/assembly/multitask/multitask.hex b/assembly/multitask/multitask.hex new file mode 100644 index 0000000..7495df7 --- /dev/null +++ b/assembly/multitask/multitask.hex @@ -0,0 +1,12 @@ +:1000000097020000938242057390523093020040A1 +:1000100073B002319302000873904230170300005E +:1000200013032309731013808322230085022325E1 +:100030005300736004309302000873A0023005453A +:10004000854873000000E5BF09458548730000003E +:10005000E5BF010083222300850223255300970278 +:1000600000009382C20483A30200850393F313006C +:1000700023A072006383030029A81705000013055D +:1000800045FC731015349302004073B002317300C5 +:10009000203017050000130565FB7310153493021B +:1000A000004073B0023173002030010000000100F5 +:00000001FF diff --git a/assembly/multitask/multitask.o b/assembly/multitask/multitask.o new file mode 100644 index 0000000..6a94422 Binary files /dev/null and b/assembly/multitask/multitask.o differ diff --git a/assembly/multitask/rvcontroller.ld b/assembly/multitask/rvcontroller.ld new file mode 120000 index 0000000..bc01402 --- /dev/null +++ b/assembly/multitask/rvcontroller.ld @@ -0,0 +1 @@ +../../rvcontroller.ld \ No newline at end of file diff --git a/assembly/timer-test/Makefile b/assembly/timer-test/Makefile new file mode 100644 index 0000000..7989624 --- /dev/null +++ b/assembly/timer-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: timer-test.hex + +timer-test.o: timer-test.S + riscv32-none-elf-as -I../rvcontroller-libraries -march=${MARCH} -o timer-test.o timer-test.S + +timer-test.elf: timer-test.o + riscv32-none-elf-ld -T rvcontroller.ld --no-warn-rwx-segments -o timer-test.elf timer-test.o + +dump: timer-test.elf + riscv32-none-elf-objdump -d timer-test.elf + +timer-test.hex: timer-test.elf + riscv32-none-elf-objcopy -O ihex timer-test.elf timer-test.hex + +load: timer-test.hex + bash -c "wl-copy < timer-test.hex" + +clean: + rm -f timer-test.hex timer-test.elf timer-test.o + diff --git a/assembly/timer-test/rvcontroller.ld b/assembly/timer-test/rvcontroller.ld new file mode 120000 index 0000000..bc01402 --- /dev/null +++ b/assembly/timer-test/rvcontroller.ld @@ -0,0 +1 @@ +../../rvcontroller.ld \ No newline at end of file diff --git a/assembly/timer-test/timer-test.S b/assembly/timer-test/timer-test.S new file mode 100644 index 0000000..e114f3f --- /dev/null +++ b/assembly/timer-test/timer-test.S @@ -0,0 +1,36 @@ +la t0,handler +csrw mtvec,t0 # Set trap handler address and mode (0/direct) +li t0,0x400 +csrc mstatush,t0 # Enable trap handler +li t0,0x80 +csrw mie,t0 # Enable machine timer interrupt and disable others + +la t0,mmio +csrw 0x801,t0 # Set up MMIO base address + +lw t1,2(t0) # Read current time +addi t1,t1,5 +sw t1,10(t0) # Set mtimecmp to 5 seconds in the future + +csrsi mstatus,8 # Enable interrupts globally + +wfi # Wait for the interrupt to trigger + +li a7,10 # Exit program +ecall + +.balign 4 +handler: +li t1,-1 +sw t1,10(t0) # Set mtimecmp to the distant future +csrr a0,mcause +li a7,1 # Print integer +ecall + +li a0,'\n' +li a7,11 # Print character +ecall + +mret + +mmio: diff --git a/assembly/timer-test/timer-test.elf b/assembly/timer-test/timer-test.elf new file mode 100755 index 0000000..729cb45 Binary files /dev/null and b/assembly/timer-test/timer-test.elf differ diff --git a/assembly/timer-test/timer-test.hex b/assembly/timer-test/timer-test.hex new file mode 100644 index 0000000..c909eb4 --- /dev/null +++ b/assembly/timer-test/timer-test.hex @@ -0,0 +1,7 @@ +:1000000097020000938202047390523093020040E2 +:1000100073B00231930200087390423097020000DF +:10002000938202047390128003A32200150323A578 +:1000300062007360043073005010A9487300000020 +:100040007D5323A56200732520348548730000008A +:0E0050002945AD487300000073002030010008 +:00000001FF diff --git a/assembly/timer-test/timer-test.o b/assembly/timer-test/timer-test.o new file mode 100644 index 0000000..3f2e505 Binary files /dev/null and b/assembly/timer-test/timer-test.o differ -- cgit v1.2.3