diff options
author | Damien Zammit <damien@zamaudio.com> | 2021-04-05 15:29:16 +1000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2021-04-05 12:00:25 +0200 |
commit | 697d9a014506df49976251b2cc449bbe2a806d9a (patch) | |
tree | b4c75a44d6973de42193cdd20989a62557b8c15e /i386/i386at/ioapic.c | |
parent | 417f458488e4802cc3f2658c1b241a5e0053df46 (diff) | |
download | gnumach-697d9a014506df49976251b2cc449bbe2a806d9a.tar.gz gnumach-697d9a014506df49976251b2cc449bbe2a806d9a.tar.bz2 gnumach-697d9a014506df49976251b2cc449bbe2a806d9a.zip |
ioapic: Use irq specific EOI properly when detected
Message-Id: <20210405052916.174771-5-damien@zamaudio.com>
Diffstat (limited to 'i386/i386at/ioapic.c')
-rw-r--r-- | i386/i386at/ioapic.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/i386/i386at/ioapic.c b/i386/i386at/ioapic.c index 38d1b43c..30ae30e1 100644 --- a/i386/i386at/ioapic.c +++ b/i386/i386at/ioapic.c @@ -31,6 +31,7 @@ #include <mach/machine.h> #include <kern/printf.h> +static int has_irq_specific_eoi = 1; /* FIXME: Assume all machines have this */ static int timer_gsi; int timer_pin; @@ -244,16 +245,23 @@ ioapic_irq_eoi(int pin) int apic = 0; union ioapic_route_entry_union oldentry, entry; - /* Workaround for old IOAPICs with no specific EOI */ + if (!has_irq_specific_eoi) { + /* Workaround for old IOAPICs with no specific EOI */ - /* Mask the pin and change to edge triggered */ - oldentry.both = entry.both = ioapic_read_entry(apic, pin); - entry.both.mask = IOAPIC_MASK_DISABLED; - entry.both.trigger = IOAPIC_EDGE_TRIGGERED; - ioapic_write_entry(apic, pin, entry.both); + /* Mask the pin and change to edge triggered */ + oldentry.both = entry.both = ioapic_read_entry(apic, pin); + entry.both.mask = IOAPIC_MASK_DISABLED; + entry.both.trigger = IOAPIC_EDGE_TRIGGERED; + ioapic_write_entry(apic, pin, entry.both); + + /* Restore level entry */ + ioapic_write_entry(apic, pin, oldentry.both); + } else { + volatile ApicIoUnit *ioapic = apic_get_ioapic(apic)->ioapic; - /* Restore level entry */ - ioapic_write_entry(apic, pin, oldentry.both); + entry.both = ioapic_read_entry(apic, pin); + ioapic->eoi.r = entry.both.vector; + } } void @@ -382,6 +390,12 @@ ioapic_configure(void) /* Enable IOAPIC processor focus */ lapic->spurious_vector.r |= LAPIC_FOCUS; + /* Enable directed EOI if applicable */ + if (has_irq_specific_eoi || lapic->version.r & LAPIC_HAS_DIRECTED_EOI) { + has_irq_specific_eoi = 1; + lapic->spurious_vector.r |= LAPIC_ENABLE_DIRECTED_EOI; + } + /* Enable IOAPIC interrupts */ lapic->spurious_vector.r |= LAPIC_ENABLE; |