Skip to content

Commit 89e60a6

Browse files
committed
Corrections to interrupt handling in plic_tests
Fix the disabling of interrupts in the `_interrupt_set` functions; these were previously incapable of clearing the mie|mstatus bit. Modify the interrupt timeout loop in plic_tests.hh accordingly. Re-express mcycle 'wfiTimeout' check to be robust against counter wraparound (this takes only about 100 seconds of run time on the Sonata board at 40MHz).
1 parent 549b92a commit 89e60a6

File tree

2 files changed

+10
-9
lines changed

2 files changed

+10
-9
lines changed

sw/cheri/common/asm.hh

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,19 @@ struct Ibex {
2525

2626
static void global_interrupt_set(bool enable) {
2727
uint32_t mstatus = READ_CSR("mstatus");
28-
mstatus &= ~(enable << 3);
29-
mstatus |= enable << 3;
28+
mstatus = (mstatus & ~8u) | (enable ? 8u : 0u);
3029
WRITE_CSR("mstatus", mstatus);
3130
}
3231

3332
static void external_interrupt_set(bool enable) {
3433
uint32_t mie = READ_CSR("mie");
35-
mie &= ~(enable << 11);
36-
mie |= enable << 11;
34+
mie = (mie & ~0x800u) | (enable ? 0x800u : 0u);
3735
WRITE_CSR("mie", mie);
3836
}
3937

4038
static void timer_interrupt_set(bool enable) {
4139
uint32_t mie = READ_CSR("mie");
42-
mie &= ~(enable << 7);
43-
mie |= enable << 7;
40+
mie = (mie & ~0x80u) | (enable ? 0x80u : 0u);
4441
WRITE_CSR("mie", mie);
4542
}
4643
};

sw/cheri/tests/plic_tests.hh

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,15 +371,19 @@ struct PlicTest {
371371
// Wait with timeout until an interrupt occurs, logging any mismatch.
372372
// Returns true iff the expected interrupt occurred within the timeout interval.
373373
inline bool irq_caught() {
374+
// Enable the interrupt in the CPU whilst we wait...
374375
ASM::Ibex::global_interrupt_set(true);
375-
ASM::Ibex::global_interrupt_set(false);
376376
if (!irq_fired) {
377377
reset_mcycle();
378-
const uint32_t end_mcycle = get_mcycle() + wfiTimeout;
379-
while (get_mcycle() < end_mcycle && !irq_fired) {
378+
const uint32_t start_mcycle = get_mcycle();
379+
// This expression of the comparison avoids issues with counter wraparound.
380+
while ((get_mcycle() - start_mcycle) < wfiTimeout && !irq_fired) {
380381
asm volatile("");
381382
}
382383
}
384+
// We have our verdict; disable interrupts again before proceeding.
385+
ASM::Ibex::global_interrupt_set(false);
386+
383387
if (!irq_fired) {
384388
error_count++;
385389
log(static_cast<PLIC::Interrupts>(0), 0, true);

0 commit comments

Comments
 (0)