From 9d541c267d601dc1ce25286d553b254aae0f882b Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 22 Oct 2020 22:45:27 -0300 Subject: [PATCH] Temporary hack to allow ACPI SCI to share an IRQ with PCI devices --- src/acpi.c | 4 +-- src/pci.c | 72 ++++++++++++++++++++++++++++++++---------------------- 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/src/acpi.c b/src/acpi.c index ad95604b2..75225daaf 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -70,12 +70,12 @@ acpi_update_irq(void *priv) if (dev->irq_mode == 1) pci_set_irq(dev->slot, dev->irq_pin); else - picintlevel(1 << dev->irq_line); + pci_set_mirq(0xf0 | dev->irq_line, 1); } else { if (dev->irq_mode == 1) pci_clear_irq(dev->slot, dev->irq_pin); else - picintc(1 << dev->irq_line); + pci_clear_mirq(0xf0 | dev->irq_line, 1); } } diff --git a/src/pci.c b/src/pci.c index aeea66ba8..d7d2f70e2 100644 --- a/src/pci.c +++ b/src/pci.c @@ -331,21 +331,28 @@ void pci_set_mirq(uint8_t mirq, int level) { uint8_t irq_line = 0; + uint8_t irq_bit; - if (! pci_mirqs[mirq].enabled) { - pci_log("pci_set_mirq(%02X): MIRQ0 disabled\n", mirq); - return; + if (mirq >= 0xf0) { + irq_line = mirq & 0x0f; + irq_bit = 0x1D; + } else { + if (! pci_mirqs[mirq].enabled) { + pci_log("pci_set_mirq(%02X): MIRQ0 disabled\n", mirq); + return; + } + + if (pci_mirqs[mirq].irq_line > 0x0f) { + pci_log("pci_set_mirq(%02X): IRQ line is disabled\n", mirq); + return; + } + + irq_line = pci_mirqs[mirq].irq_line; + irq_bit = (0x1E + mirq); } - - if (pci_mirqs[mirq].irq_line > 0x0f) { - pci_log("pci_set_mirq(%02X): IRQ line is disabled\n", mirq); - return; - } - - irq_line = pci_mirqs[mirq].irq_line; pci_log("pci_set_mirq(%02X): Using IRQ %i\n", mirq, irq_line); - if (level && (pci_irq_hold[irq_line] & (1ULL << (0x1E + mirq)))) { + if (level && (pci_irq_hold[irq_line] & (1ULL << irq_bit))) { /* IRQ already held, do nothing. */ pci_log("pci_set_mirq(%02X): MIRQ is already holding the IRQ\n", mirq); return; @@ -367,7 +374,7 @@ pci_set_mirq(uint8_t mirq, int level) /* If the IRQ is level-triggered, mark that this MIRQ is holding it. */ if (level) { pci_log("pci_set_mirq(%02X): Marking that this card is holding the IRQ\n", mirq); - pci_irq_hold[irq_line] |= (1ULL << (0x1E + mirq)); + pci_irq_hold[irq_line] |= (1ULL << irq_bit); } pci_log("pci_set_mirq(%02X): Edge-triggered interrupt, not marking\n", mirq); @@ -450,26 +457,33 @@ void pci_clear_mirq(uint8_t mirq, int level) { uint8_t irq_line = 0; + uint8_t irq_bit; - if (mirq > 1) { - pci_log("pci_clear_mirq(%02X): Invalid MIRQ\n", mirq); - return; + if (mirq >= 0xf0) { + irq_line = mirq & 0x0f; + irq_bit = 0x1D; + } else { + if (mirq > 1) { + pci_log("pci_clear_mirq(%02X): Invalid MIRQ\n", mirq); + return; + } + + if (! pci_mirqs[mirq].enabled) { + pci_log("pci_clear_mirq(%02X): MIRQ0 disabled\n", mirq); + return; + } + + if (pci_mirqs[mirq].irq_line > 0x0f) { + pci_log("pci_clear_mirq(%02X): IRQ line is disabled\n", mirq); + return; + } + + irq_line = pci_mirqs[mirq].irq_line; + irq_bit = (0x1E + mirq); } - - if (! pci_mirqs[mirq].enabled) { - pci_log("pci_clear_mirq(%02X): MIRQ0 disabled\n", mirq); - return; - } - - if (pci_mirqs[mirq].irq_line > 0x0f) { - pci_log("pci_clear_mirq(%02X): IRQ line is disabled\n", mirq); - return; - } - - irq_line = pci_mirqs[mirq].irq_line; pci_log("pci_clear_mirq(%02X): Using IRQ %i\n", mirq, irq_line); - if (level && !(pci_irq_hold[irq_line] & (1ULL << (0x1E + mirq)))) { + if (level && !(pci_irq_hold[irq_line] & (1ULL << irq_bit))) { /* IRQ not held, do nothing. */ pci_log("pci_clear_mirq(%02X): MIRQ is not holding the IRQ\n", mirq); return; @@ -477,7 +491,7 @@ pci_clear_mirq(uint8_t mirq, int level) if (level) { pci_log("pci_clear_mirq(%02X): Releasing this MIRQ's hold on the IRQ\n", mirq); - pci_irq_hold[irq_line] &= ~(1 << (0x1E + mirq)); + pci_irq_hold[irq_line] &= ~(1 << irq_bit); if (! pci_irq_hold[irq_line]) { pci_log("pci_clear_mirq(%02X): IRQ no longer held by any card, clearing it\n", mirq);