ibex icon indicating copy to clipboard operation
ibex copied to clipboard

Writing `mseccfg`=0x1 will jump to `_vectors_start`

Open ha0lyu opened this issue 1 year ago • 6 comments

Observed Behavior

When write 0x01 to mseccfg(0x747), some unknown behavior happened: ibex jump to _vectors_start. I have tested some values, when we write 0x4 or 0x8, ibex is normal, any other value will jump to _vectors_start. See trace file for more information.

Expected Behavior

Ibex has supported Smepmp extension at PMP Enhancements. I have checked this extension, all mseccfg field, including mseccfg.MML and mseccfg.MMWP are WARL.

Steps to reproduce the issue

#include "simple_system_common.h"

int main(void){
    asm volatile("li t0, 0x1");
    asm volatile("csrw 0x747, t0");
    asm volatile("nop");
    asm volatile("nop");
    asm volatile("nop");
    asm volatile("csrr a0, 0x747");
    return 0;
}

Build this test code like "hello_test.c", run build/lowrisc_ibex_ibex_simple_system_0/sim-verilator/Vibex_simple_system --meminit=ram,./PATH/TO/test.elf -c 300

My Environment

  • build ibex: fusesoc --cores-root=. run --target=sim --setup --build \ lowrisc:ibex:ibex_simple_system $(util/ibex_config.py opentitan fusesoc_opts)

EDA tool and version: Verilator 4.210 2021-07-07 rev v4.210

Operating system:

Ubuntu Linux 18.04

Version of the Ibex source code:

  • ibex version: 8f4c75c5e

ha0lyu avatar Jan 02 '25 15:01 ha0lyu

I learned how to view waveform diagrams and discovered that when pc=0x1003cc, an exception occurred, and the program jumped to pc=0x100000, which is the location of _vectors_start. Image

According to the disassembly information, a write operation to the mseccfg register occurred at pc=0x1003cc, which triggered an exception. This exception violated the rules of the Smepmp extension because "All mseccfg fields defined in this proposal are WARL." Image

ha0lyu avatar Jan 03 '25 14:01 ha0lyu

0x1 switches on MML which alters the interpretation of PMPs, maybe you haven't configured PMPs properly so now the instruction memory is unaccessible?

nbdd0121 avatar Jan 06 '25 11:01 nbdd0121

Hi @nbdd0121, thanks for your reply. Actually, the test case shown in the picture above is a part of another test case. When I set PMP correctly, I want to change msecfg.MML to 0x1, a trap occurred and the mcause is zero. I have tested other values, such 0b110, 0b10, etc. All failed. I think the root cause is mseccfg is not writable in ibex.

ha0lyu avatar Jan 07 '25 05:01 ha0lyu

Here is the full test code, you can comment csrw 0x747, a0 to test before/after setting pmpcfg.

.section .text
.global mseccfg_test

mseccfg_test:
    # Load the address of test_data
    la t1, lower_bound          # t1 = address of lower_bound
    la t2, upper_bound          # t2 = address of upper_bound

    srli t1, t1, 2            # t1 = lower_bound >> 2
    srli t2, t2, 2            # t2 = upper_bound >> 2

    csrw pmpaddr0, t1         # Set pmpaddr0 = lower bound
    csrw pmpaddr1, t2         # Set pmpaddr1 = upper bound
    csrr t0, 0x747        # mseccfg = 0x747

    #  Test mseccfg before setting pmpcfg0  
    li a0, 0x01
    csrw 0x747, a0

    # Configure pmpcfg0 --> pmp1cfg.L = 1, pmp1cfg.A = 1 (TOR mode)
    li t3, 0x8800
    csrw pmpcfg0, t3

    #  Test mseccfg after setting pmpcfg0                     
    li a0, 0x01
    csrw 0x747, a0

    li a0, 0x10
    ret

.section .data
lower_bound:
    .word 0x12345678        
    .word 0x00000000       
upper_bound:
    .word 0x00000000   

ha0lyu avatar Jan 08 '25 04:01 ha0lyu

I think you also need to setup PMP to cover executable code.

nbdd0121 avatar Jan 08 '25 11:01 nbdd0121

Well, you can try this test code:

.section .text
.global mseccfg_test

mseccfg_test:
    li t1, 0x00100000     #  ram ORIGIN = 0x00100000
    li t2, 0x00140000     # stack = 0x00130000
   
    csrw pmpaddr0, t1
    csrw pmpaddr1, t2    

    #  Test mseccfg before setting pmpcfg0  
    li a0, 0x01
    csrw 0x747, a0

    li t3, 0x8800
    csrw pmpcfg0, t3

    #  Test mseccfg after setting pmpcfg0                     
    li a0, 0x01
    csrw 0x747, a0

    li a0, 0x10
    ret

.section .data
lower_bound:
    .word 0x12345678        
    .word 0x00000000       
upper_bound:
    .word 0x00000000   

Trace file, test.elf, test.dis and sim.fst in test.zip If you still think there's something to be done, please provide me with the test case that you believe is correct. Thanks.

ha0lyu avatar Jan 08 '25 13:01 ha0lyu