diff --git a/sw/cheri/common/asm.hh b/sw/cheri/common/asm.hh index 0f878e163..39588ddd4 100644 --- a/sw/cheri/common/asm.hh +++ b/sw/cheri/common/asm.hh @@ -25,22 +25,19 @@ struct Ibex { static void global_interrupt_set(bool enable) { uint32_t mstatus = READ_CSR("mstatus"); - mstatus &= ~(enable << 3); - mstatus |= enable << 3; + mstatus = (mstatus & ~8u) | (enable ? 8u : 0u); WRITE_CSR("mstatus", mstatus); } static void external_interrupt_set(bool enable) { uint32_t mie = READ_CSR("mie"); - mie &= ~(enable << 11); - mie |= enable << 11; + mie = (mie & ~0x800u) | (enable ? 0x800u : 0u); WRITE_CSR("mie", mie); } static void timer_interrupt_set(bool enable) { uint32_t mie = READ_CSR("mie"); - mie &= ~(enable << 7); - mie |= enable << 7; + mie = (mie & ~0x80u) | (enable ? 0x80u : 0u); WRITE_CSR("mie", mie); } }; diff --git a/sw/cheri/tests/plic_tests.hh b/sw/cheri/tests/plic_tests.hh index d225afef5..2973f2137 100644 --- a/sw/cheri/tests/plic_tests.hh +++ b/sw/cheri/tests/plic_tests.hh @@ -371,15 +371,19 @@ struct PlicTest { // Wait with timeout until an interrupt occurs, logging any mismatch. // Returns true iff the expected interrupt occurred within the timeout interval. inline bool irq_caught() { + // Enable the interrupt in the CPU whilst we wait... ASM::Ibex::global_interrupt_set(true); - ASM::Ibex::global_interrupt_set(false); if (!irq_fired) { reset_mcycle(); - const uint32_t end_mcycle = get_mcycle() + wfiTimeout; - while (get_mcycle() < end_mcycle && !irq_fired) { + const uint32_t start_mcycle = get_mcycle(); + // This expression of the comparison avoids issues with counter wraparound. + while ((get_mcycle() - start_mcycle) < wfiTimeout && !irq_fired) { asm volatile(""); } } + // We have our verdict; disable interrupts again before proceeding. + ASM::Ibex::global_interrupt_set(false); + if (!irq_fired) { error_count++; log(static_cast(0), 0, true);