CV1800B switch to Supervisor mode

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!