From 6c59bf4203409d120e42579125d0bf667bdf9766 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Wed, 24 Aug 2022 14:14:42 +0200 Subject: [PATCH] heathrow: fix interrupt processing. --- devices/ioctrl/heathrow.cpp | 19 ++++++++++++++++++- devices/ioctrl/macio.h | 20 +++++++++++--------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/devices/ioctrl/heathrow.cpp b/devices/ioctrl/heathrow.cpp index 186b17e..078388c 100644 --- a/devices/ioctrl/heathrow.cpp +++ b/devices/ioctrl/heathrow.cpp @@ -262,6 +262,7 @@ void HeathrowIC::mio_ctrl_write(uint32_t offset, uint32_t value, int size) { case MIO_INT_CLEAR2: if (value & MACIO_INT_CLR) { this->int_events2 = 0; + clear_cpu_int(); } else { this->int_events2 &= BYTESWAP_32(value); } @@ -274,6 +275,7 @@ void HeathrowIC::mio_ctrl_write(uint32_t offset, uint32_t value, int size) { case MIO_INT_CLEAR1: if (value & MACIO_INT_CLR) { this->int_events1 = 0; + clear_cpu_int(); } else { this->int_events1 &= BYTESWAP_32(value); } @@ -353,7 +355,13 @@ void HeathrowIC::ack_int(uint32_t irq_id, uint8_t irq_line_state) } // signal CPU interrupt if (this->int_events1 || this->int_events2) { - ppc_ext_int(); + if (!this->cpu_int_latch) { + this->cpu_int_latch = true; + ppc_assert_int(); + LOG_F(5, "Heathrow: CPU INT asserted, source: %d", irq_id); + } else { + LOG_F(5, "Heathrow: CPU INT already latched"); + } } } else { ABORT_F("Heathrow: native interrupt mode not implemented"); @@ -364,6 +372,15 @@ void HeathrowIC::ack_dma_int(uint32_t irq_id, uint8_t irq_line_state) { } +void HeathrowIC::clear_cpu_int() +{ + if (!this->int_events1 && !this->int_events2) { + this->cpu_int_latch = false; + ppc_release_int(); + LOG_F(5, "Heathrow: CPU INT latch cleared"); + } +} + static const vector Heathrow_Subdevices = { "NVRAM", "ViaCuda", "Mesh", "Escc", "Swim3" }; diff --git a/devices/ioctrl/macio.h b/devices/ioctrl/macio.h index 16247c5..6c81152 100644 --- a/devices/ioctrl/macio.h +++ b/devices/ioctrl/macio.h @@ -202,17 +202,19 @@ protected: void notify_bar_change(int bar_num); void feature_control(const uint32_t value); + void clear_cpu_int(); private: - uint32_t base_addr = 0; - uint32_t int_events2 = 0; - uint32_t int_mask2 = 0; - uint32_t int_levels2 = 0; - uint32_t int_events1 = 0; - uint32_t int_mask1 = 0; - uint32_t int_levels1 = 0; - uint32_t feat_ctrl = 0; // features control register - uint32_t aux_ctrl = 0; // aux features control register + uint32_t base_addr = 0; + uint32_t int_events2 = 0; + uint32_t int_mask2 = 0; + uint32_t int_levels2 = 0; + uint32_t int_events1 = 0; + uint32_t int_mask1 = 0; + uint32_t int_levels1 = 0; + uint32_t feat_ctrl = 0; // features control register + uint32_t aux_ctrl = 0; // aux features control register + bool cpu_int_latch = false; uint8_t cpu_id = 0xE0; // CPUID field (LSB of the MIO_HEAT_ID) uint8_t mb_id = 0x70; // Media Bay ID (bits 15:8 of the MIO_HEAT_ID)