chipsalliance / dromajo

RISC-V RV64GC emulator designed for RTL co-simulation
Apache License 2.0
210 stars 63 forks source link

When interrupt races the exception, first instruction of exception is dropped #78

Open zephray opened 1 year ago

zephray commented 1 year ago

Seems to be doing this by design:

https://github.com/chipsalliance/dromajo/blob/master/src/dromajo_cosim.cpp#L251

This line executes the first instruction of the exception handler, thus it no longer shows up later when exception handling starts in the DUT.

I was luckly/ unlucky enough to actually reproduce this while running Linux:

hartid=0 priv: 0 exception user_ecall, epc 0x0000003fa17a4938
hartid=0            tval 0x0000000000000000
0 0x0000003fa17a4938 (0x00000073)                        ecall
[DEBUG] DUT raised exception 8
[DEBUG] DUT raised interrupt 7
[DEBUG] DUT also raised exception 8
[DEBUG] Interrupt: MIP <- 7: Now MIP = 80
get_irq_mask: mip=0x80 mie=0x2aa mideleg=0x222
raise_interrupt: irq=7 priv=1 pc=ffffffff80002ed0 hartid=0
hartid=0: exception interrupt #7, epc 0xffffffff80002ed0
3 0x0000000080000004 (0x34011173) x2  0x000000008000bec0 csrrw   sp, mscratch, sp
3 0x0000000080000008 (0x1a010863)                        beqz    sp, pc + 432
3 0x000000008000000c (0x04a13823)                        sd      a0, 80(sp)
3 0x0000000080000010 (0x04b13c23)                        sd      a1, 88(sp)
3 0x0000000080000014 (0x342025f3) x11 0x8000000000000007 csrr    a1, mcause
3 0x0000000080000018 (0x0805d263)                        bgez    a1, pc + 132
3 0x000000008000001c (0x00159593) x11 0x000000000000000e slli    a1, a1, 1
3 0x0000000080000020 (0x00e00513) x10 0x000000000000000e li      a0, 14
3 0x0000000080000024 (0x02b51263)                        bne     a0, a1, pc + 36
3 0x0000000080000028 (0x08000513) x10 0x0000000000000080 li      a0, 128
3 0x000000008000002c (0x30453073)                        csrc    mie, a0
3 0x0000000080000030 (0x02000513) x10 0x0000000000000020 li      a0, 32
3 0x0000000080000034 (0x34452073)                        csrs    mip, a0
3 0x0000000080000038 (0x05013503) x10 0x0000002ad48fe000 ld      a0, 80(sp)
3 0x000000008000003c (0x05813583) x11 0x0000003fa180a930 ld      a1, 88(sp)
3 0x0000000080000040 (0x34011173) x2  0x0000003fef66ae50 csrrw   sp, mscratch, sp
3 0x0000000080000044 (0x30200073)                        mret
1 0xffffffff80002ed0 (0x00021f63)                        bnez    tp, pc + 30
[error] EMU PC ffffffff80002ed0, DUT PC ffffffff80002ecc
[error] EMU INSN 00021f63, DUT INSN 14021273
[error] EMU MSTATUS 8000000a000060a0, DUT MSTATUS 00000000
[error] DUT pending exception -1 pending interrupt -1

The DUT tried to start execute the 1st instruction of the exception handler after mret, which is at 80002ecc. However the dromajo has already at the 2nd instruction into the handler, at 80002ed0. This matches the observation in the code where the 1st instruction of the exception handler is already executed.