From b1142ee1eef9eef6dc96da7a90ce1f79ec5b894c Mon Sep 17 00:00:00 2001 From: Mihai Parparita Date: Tue, 13 Oct 2026 22:26:20 -0700 Subject: [PATCH] grandcentral: Keep interrupt events and CPU IRQ state consistent Two correctness fixes, based on the Grand Central ERS: - Reevaluate the CPU interrupt when the mask changes, releasing it if no pending events remain enabled (section 6.1). - Keep events latched until software writes InterruptClear, even if a device deasserts its interrupt line or repeats an assertion (section 6.2.1). This fixes occasional freezes on BeOS (especially in realtime mode). Previously, the CPU interrupt could remain asserted with no enabled events, trapping BeOS in its interrupt handler. --- devices/ioctrl/grandcentral.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/devices/ioctrl/grandcentral.cpp b/devices/ioctrl/grandcentral.cpp index 5d5d55dce1..e9da77b6b8 100644 --- a/devices/ioctrl/grandcentral.cpp +++ b/devices/ioctrl/grandcentral.cpp @@ -433,6 +433,7 @@ void GrandCentral::write(uint32_t rgn_start, uint32_t offset, uint32_t value, in switch (offset) { case MIO_INT_MASK1: this->int_mask = BYTESWAP_32(value); + this->clear_cpu_int(); this->signal_cpu_int(); break; case MIO_INT_CLEAR1: @@ -529,9 +530,8 @@ void GrandCentral::ack_int_common(uint64_t irq_id, uint8_t irq_line_state) { if ((this->int_mask & MACIO_INT_MODE) || (irq_line_state && !(this->int_levels & irq_id))) { this->int_events |= (uint32_t)irq_id; - } else { - this->int_events &= ~(uint32_t)irq_id; } + // Events remain latched until software writes InterruptClear. // update IRQ line state if (irq_line_state) {