summaryrefslogtreecommitdiff
path: root/assembly/multitask/multitask.S
diff options
context:
space:
mode:
Diffstat (limited to 'assembly/multitask/multitask.S')
-rw-r--r--assembly/multitask/multitask.S61
1 files changed, 61 insertions, 0 deletions
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: