mirror of
https://github.com/plctlab/riscv-operating-system-mooc.git
synced 2025-12-28 01:50:55 +00:00
initial versioin
This commit is contained in:
106
code/os/04-multitask/entry.S
Normal file
106
code/os/04-multitask/entry.S
Normal file
@@ -0,0 +1,106 @@
|
||||
# save all General-Purpose(GP) registers to context
|
||||
# struct context *base = &ctx_task;
|
||||
# base->ra = ra;
|
||||
# ......
|
||||
.macro reg_save base
|
||||
sw ra, 0(\base)
|
||||
sw sp, 4(\base)
|
||||
sw gp, 8(\base)
|
||||
sw tp, 12(\base)
|
||||
sw t0, 16(\base)
|
||||
sw t1, 20(\base)
|
||||
sw t2, 24(\base)
|
||||
sw s0, 28(\base)
|
||||
sw s1, 32(\base)
|
||||
sw a0, 36(\base)
|
||||
sw a1, 40(\base)
|
||||
sw a2, 44(\base)
|
||||
sw a3, 48(\base)
|
||||
sw a4, 52(\base)
|
||||
sw a5, 56(\base)
|
||||
sw a6, 60(\base)
|
||||
sw a7, 64(\base)
|
||||
sw s2, 68(\base)
|
||||
sw s3, 72(\base)
|
||||
sw s4, 76(\base)
|
||||
sw s5, 80(\base)
|
||||
sw s6, 84(\base)
|
||||
sw s7, 88(\base)
|
||||
sw s8, 92(\base)
|
||||
sw s9, 96(\base)
|
||||
sw s10, 100(\base)
|
||||
sw s11, 104(\base)
|
||||
sw t3, 108(\base)
|
||||
sw t4, 112(\base)
|
||||
sw t5, 116(\base)
|
||||
sw t6, 120(\base)
|
||||
.endm
|
||||
|
||||
# restore all General-Purpose(GP) registers from the context
|
||||
# struct context *base = &ctx_task;
|
||||
# ra = base->ra;
|
||||
# ......
|
||||
.macro reg_restore base
|
||||
lw ra, 0(\base)
|
||||
lw sp, 4(\base)
|
||||
lw gp, 8(\base)
|
||||
lw tp, 12(\base)
|
||||
lw t0, 16(\base)
|
||||
lw t1, 20(\base)
|
||||
lw t2, 24(\base)
|
||||
lw s0, 28(\base)
|
||||
lw s1, 32(\base)
|
||||
lw a0, 36(\base)
|
||||
lw a1, 40(\base)
|
||||
lw a2, 44(\base)
|
||||
lw a3, 48(\base)
|
||||
lw a4, 52(\base)
|
||||
lw a5, 56(\base)
|
||||
lw a6, 60(\base)
|
||||
lw a7, 64(\base)
|
||||
lw s2, 68(\base)
|
||||
lw s3, 72(\base)
|
||||
lw s4, 76(\base)
|
||||
lw s5, 80(\base)
|
||||
lw s6, 84(\base)
|
||||
lw s7, 88(\base)
|
||||
lw s8, 92(\base)
|
||||
lw s9, 96(\base)
|
||||
lw s10, 100(\base)
|
||||
lw s11, 104(\base)
|
||||
lw t3, 108(\base)
|
||||
lw t4, 112(\base)
|
||||
lw t5, 116(\base)
|
||||
lw t6, 120(\base)
|
||||
.endm
|
||||
|
||||
# Something to note about save/restore:
|
||||
# - We use mscratch to hold a pointer to context of previous task
|
||||
# - We use t6 as the 'base' for reg_save/reg_restore, because it is the
|
||||
# very bottom register (x31) and would not be overwritten during loading.
|
||||
|
||||
.text
|
||||
|
||||
# void switch_to(struct context *next);
|
||||
# a0: pointer to the context of the next task
|
||||
.globl switch_to
|
||||
.align 4
|
||||
switch_to:
|
||||
csrrw t6, mscratch, t6 # swap t6 and mscratch
|
||||
beqz t6, 1f # Notice: previous task may be NULL
|
||||
reg_save t6 # save context of prev task
|
||||
|
||||
1:
|
||||
# switch mscratch to point to the context of the next task
|
||||
csrw mscratch, a0
|
||||
|
||||
# Restore all GP registers
|
||||
# Use t6 to point to the context of the new task
|
||||
mv t6, a0
|
||||
reg_restore t6
|
||||
|
||||
# Do actual context switching.
|
||||
ret
|
||||
|
||||
.end
|
||||
|
||||
Reference in New Issue
Block a user