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

Synchronous debug reasons handled before taking interrupt enabled via instruction #665

Closed
Silabs-ArjanB opened this issue Sep 8, 2022 · 0 comments
Labels
Component:RTL For issues in the RTL (e.g. for files in the rtl directory) Type:Bug For bugs in any content (RTL, Documentation, etc.)

Comments

@Silabs-ArjanB
Copy link
Contributor

When an mret instruction or CSR write globally (re-)enables a locally enabled and pending interrupt, a following ebreak instruction can cause debug mode entry although it should have been cancelled by the interrupt. This is basically the same issue as #325, but that issue had only been fixed for load/store instructions following re-enabling of interrupts.

We should reconsider the implementation of all synchronous debug entry reasons (not only ebreak). We currently have all debug entry reasons prioritized above all (non-NMI) interrupt entry reasons. We need to double check if that was an arbitrary choice or whether that is implied by some RISC-V spec.

Possible fixes include:

  • Detecting synchronous debug entry cases after re-enable/disable of IRQs and cause stall cycle such that interrupt can be taken before debug entry reason enters WB.
  • Change priority between IRQs and synchronous debug entry reasons in main FSM (if not specified otherwise by RISC-V)
  1. mstatus.ie=0 and we execute an mret instruction 2. Interrupts are
    already pending (MSWInterrupt) and the target address of the
    interrupt is 0x0000_000c (j 0x6b2e) 3. mepc=0x0000_5fea (c.ebreak)

So should the processor execute the jump at 0xc having taken the
interrupt, or the c.ebreak at target fetch address of 0x5fea

the REF model executes the pending interrupt, once enabled after executing the mret the RTL executes the c.ebreak and goes into debug mode.

before execution of mret
MEPC=0x00005FEA (0x5fea: 9002 c.ebreak)
MIP=0x4E3C0088
MSTATUS=0x0001880 (mpie=1)

after execution of mret
MSTATUS=0x0001888 (mie=0->1)

So I would expect the pending interrupt mip[3] to be taken, not the c.ebreak at the next fetch address of the mepc This looks very much like the issue we saw with Loads/Stores executing before an interrupt being taken after executing an mret which re-enabled the interrupts

@Silabs-ArjanB Silabs-ArjanB added Component:RTL For issues in the RTL (e.g. for files in the rtl directory) Type:Bug For bugs in any content (RTL, Documentation, etc.) labels Sep 8, 2022
silabs-oysteink added a commit to silabs-oysteink/cv32e40x that referenced this issue Dec 8, 2022
silabs-oysteink added a commit to silabs-oysteink/cv32e40x that referenced this issue Dec 8, 2022
…ritized below interrupts.

Signed-off-by: Oystein Knauserud <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component:RTL For issues in the RTL (e.g. for files in the rtl directory) Type:Bug For bugs in any content (RTL, Documentation, etc.)
Projects
None yet
Development

No branches or pull requests

1 participant