Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Writing mseccfg=0x1 will jump to _vectors_start #2237

Open
ha0lyu opened this issue Jan 2, 2025 · 6 comments
Open

Writing mseccfg=0x1 will jump to _vectors_start #2237

ha0lyu opened this issue Jan 2, 2025 · 6 comments
Labels

Comments

@ha0lyu
Copy link

ha0lyu commented Jan 2, 2025

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:

@ha0lyu ha0lyu added the Type:Bug Bugs label Jan 2, 2025
@ha0lyu
Copy link
Author

ha0lyu commented Jan 3, 2025

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

@nbdd0121
Copy link
Contributor

nbdd0121 commented Jan 6, 2025

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

@ha0lyu
Copy link
Author

ha0lyu commented Jan 7, 2025

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
Copy link
Author

ha0lyu commented Jan 8, 2025

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   

@nbdd0121
Copy link
Contributor

nbdd0121 commented Jan 8, 2025

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

@ha0lyu
Copy link
Author

ha0lyu commented Jan 8, 2025

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants