mirror of
https://github.com/plctlab/riscv-operating-system-mooc.git
synced 2025-12-26 17:19:04 +00:00
fixed bug for syscall example
The original logic of setting mstatus has problem. The or directive cannot set .MPP to 0. Optimize the original code and use csrs and csrc instead. Note we cannot assume the default value of mstatus is zero. rvos may not be the first one to run on the system/virt. It just so lucky that the initial value of mstatus is zero on QEMU/virt. Signed-off-by: Wang Chen <wangchen20@iscas.ac.cn>
This commit is contained in:
@@ -32,13 +32,12 @@ _start:
|
||||
|
||||
# At the end of start_kernel, schedule() will call MRET to switch
|
||||
# to the first task, so we parepare the mstatus here.
|
||||
# Notice: default mstatus is 0
|
||||
# Notice: It is best not to assume that the initial value of mstatus is
|
||||
# zero.
|
||||
# Set mstatus.MPP to 3, so we still run in Machine mode after MRET.
|
||||
# Set mstatus.MPIE to 1, so MRET will enable the interrupt.
|
||||
li t0, 3 << 11 | 1 << 7
|
||||
csrr a1, mstatus
|
||||
or t0, t0, a1
|
||||
csrw mstatus, t0
|
||||
csrs mstatus, t0
|
||||
|
||||
j start_kernel # hart 0 jump to c
|
||||
|
||||
|
||||
@@ -32,13 +32,12 @@ _start:
|
||||
|
||||
# At the end of start_kernel, schedule() will call MRET to switch
|
||||
# to the first task, so we parepare the mstatus here.
|
||||
# Notice: default mstatus is 0
|
||||
# Notice: It is best not to assume that the initial value of mstatus is
|
||||
# zero.
|
||||
# Set mstatus.MPP to 3, so we still run in Machine mode after MRET.
|
||||
# Set mstatus.MPIE to 1, so MRET will enable the interrupt.
|
||||
li t0, 3 << 11 | 1 << 7
|
||||
csrr a1, mstatus
|
||||
or t0, t0, a1
|
||||
csrw mstatus, t0
|
||||
csrs mstatus, t0
|
||||
|
||||
j start_kernel # hart 0 jump to c
|
||||
|
||||
|
||||
@@ -32,13 +32,12 @@ _start:
|
||||
|
||||
# At the end of start_kernel, schedule() will call MRET to switch
|
||||
# to the first task, so we parepare the mstatus here.
|
||||
# Notice: default mstatus is 0
|
||||
# Notice: It is best not to assume that the initial value of mstatus is
|
||||
# zero.
|
||||
# Set mstatus.MPP to 3, so we still run in Machine mode after MRET.
|
||||
# Set mstatus.MPIE to 1, so MRET will enable the interrupt.
|
||||
li t0, 3 << 11 | 1 << 7
|
||||
csrr a1, mstatus
|
||||
or t0, t0, a1
|
||||
csrw mstatus, t0
|
||||
csrs mstatus, t0
|
||||
|
||||
j start_kernel # hart 0 jump to c
|
||||
|
||||
|
||||
@@ -50,22 +50,21 @@ _start:
|
||||
|
||||
# At the end of start_kernel, schedule() will call MRET to switch
|
||||
# to the first task, so we parepare the mstatus here.
|
||||
# Notice: default mstatus is 0
|
||||
# Notice: It is best not to assume that the initial value of mstatus is
|
||||
# zero.
|
||||
#ifdef CONFIG_SYSCALL
|
||||
# Set mstatus.MPP as 0, so we will run in User mode after MRET.
|
||||
# No need to set mstatus.MPIE to 1 explicitly, because according to ISA
|
||||
# specification: interrupts for M-mode, which is higher than U-mode, are
|
||||
# always globally enabled regardless of the setting of the global MIE bit.
|
||||
# So finally we simply reset t0 to zero.
|
||||
li t0, 0
|
||||
li t0, 3 << 11
|
||||
csrc mstatus, t0
|
||||
#else
|
||||
# Set mstatus.MPP to 3, so we still run in Machine mode after MRET.
|
||||
# Set mstatus.MPIE to 1, so MRET will enable the interrupt.
|
||||
li t0, 3 << 11 | 1 << 7
|
||||
csrs mstatus, t0
|
||||
#endif
|
||||
csrr a1, mstatus
|
||||
or t0, t0, a1
|
||||
csrw mstatus, t0
|
||||
|
||||
j start_kernel # hart 0 jump to c
|
||||
|
||||
|
||||
Reference in New Issue
Block a user