Hi there,
I’m trying to switch to S-mode on the CV1800B (I’m using the Milk V Duo, creating the FIP image with fiptool
, and running it directly without OpenSBI).
The program launches in M-mode. Then, in my loader.S
file, i do this:
.section .text.init,"ax",@progbits
.globl _start
_start:
csrw mie, x0
// setup machine trap handler
la t0, machine_trap_handler
csrw mtvec, t0
// setup supervisor trap handler
la t0, supervisor_trap_handler
csrw stvec, t0
# // disable address translation
csrw satp, zero
// Enable supervisor timer interrupts and delegate handling
// of the timer interrupt to 'supervisor' mode.
li t0, DELEG_ALL
csrw mie, t0
# csrw mideleg, t0
li t0, ((1 << 9) | (1 << 5) | (1 << 1)) // External (9) and Timer (5) interrupts
csrw mideleg, t0
// Handle exceptions due to page faults, syscalls and illegal
// instructions in the 'supervisor' mode.
li t0, CSR_MEDELEG_MASK
csrw medeleg, t0
li t0, CSR_MSTATUS_MPP_S
csrs mstatus, t0
la sp, _start
la a2, __DATA_LMA_START__
la a3, __DATA_START__
la a4, __DATA_SIZE__
data_cpy:
beqz a4, skip_data_cpy # Skip if DATA_SIZE is 0
ld a5, 0(a2)
sd a5, 0(a3)
addi a2, a2, 8
addi a3, a3, 8
addi a4, a4, -8
bnez a4, data_cpy
skip_data_cpy:
la a3, __BSS_START__
la a4, __BSS_SIZE__
data_clear:
beqz a4, skip_data_clear # Skip if BSS_SIZE is 0
sd x0, 0(a3)
addi a3, a3, 8
addi a4, a4, -8
bnez a4, data_clear
skip_data_clear:
# Stay in M-mode but delegate interrupts
li t0, (1 << 9) | (1 << 5) # External (9) and Timer (5) interrupts
csrw mideleg, t0
# Delegate exceptions
li t0, (1 << 8) | (1 << 9) | (1 << 2) # U-mode ecall, S-mode ecall, illegal instruction
csrw medeleg, t0
la ra, main
csrw mepc, ra
mret
j .
where CSR_MSTATUS_MPP_S = (1 << 11) = 0x800
.
Then in main
, i try to query mstatus
and sstatus
. These return 0 and 1 respectively. If the process were in S-Mode, reading of mstatus
would NOT be possible, right?
Am I doing something wrong?
Thanks so much for any help!