From be45a5f6e0d7438d6b67551d4860fc0610d6fe7d Mon Sep 17 00:00:00 2001 From: linzhida Date: Thu, 2 Jan 2025 21:43:32 +0800 Subject: [PATCH] fix(raise_intr): fix raise_intr to allow clearing values in mip. For external and timer interrupts, we choose to let the DUT inform the REF when there is a pending interrupt and trigger it. For these types of interrupts, we set the corresponding bit in `mip` to 1 to trigger the interrupt. Moreover, we cannot modify these bits in `mip` using the `csrrw` instruction. Therefore, after triggering the interrupt, we should also clear the corresponding bit in `mip`; otherwise, it will persist in `mip` indefinitely. --- difftest/difftest.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/difftest/difftest.cc b/difftest/difftest.cc index f42ad614b..f76676dc6 100644 --- a/difftest/difftest.cc +++ b/difftest/difftest.cc @@ -391,11 +391,14 @@ void DifftestRef::raise_intr(uint64_t no) { // 0x1e00: 9 (Supervisor), 10 (Virtual supervisor), 11 (Machine), 12 (Supervisor guest) bool from_outside = !(mip_bit & state->mip->read()); bool external_set = (is_timer_interrupt || is_external_interrupt) && from_outside; + p->check_interrupt = true; if (external_set) { state->mip->backdoor_write_with_mask(mip_bit, mip_bit); + step(1); + state->mip->backdoor_write_with_mask(mip_bit, ~mip_bit); + } else { + step(1); } - p->check_interrupt = true; - step(1); p->check_interrupt = false; } }