bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 4/4] ioapic: Use irq specific EOI properly when detected


From: Damien Zammit
Subject: [PATCH 4/4] ioapic: Use irq specific EOI properly when detected
Date: Mon, 5 Apr 2021 15:29:16 +1000

---
 i386/i386/apic.h     |  4 ++++
 i386/i386at/ioapic.c | 30 ++++++++++++++++++++++--------
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/i386/i386/apic.h b/i386/i386/apic.h
index d63dbfcc..add1b8cf 100644
--- a/i386/i386/apic.h
+++ b/i386/i386/apic.h
@@ -35,6 +35,8 @@ typedef struct ApicReg {
 typedef struct ApicIoUnit {
         ApicReg select;
         ApicReg window;
+        ApicReg unused[2];
+        ApicReg eoi; /* write the vector you wish to EOI to this reg */
 } ApicIoUnit;
 
 struct ioapic_route_entry {
@@ -175,6 +177,7 @@ extern inline void unmask_irq (unsigned int irq_nr);
 #define LAPIC_ENABLE                   0x100
 #define LAPIC_FOCUS                    0x200
 #define LAPIC_NMI                      0x400
+#define LAPIC_ENABLE_DIRECTED_EOI      0x1000
 #define LAPIC_DISABLE                  0x10000
 #define LAPIC_TIMER_PERIODIC           0x20000
 #define LAPIC_TIMER_DIVIDE_2           0
@@ -182,6 +185,7 @@ extern inline void unmask_irq (unsigned int irq_nr);
 #define LAPIC_TIMER_DIVIDE_8           2
 #define LAPIC_TIMER_DIVIDE_16          3
 #define LAPIC_TIMER_BASEDIV            0x100000
+#define LAPIC_HAS_DIRECTED_EOI         0x1000000
 
 #define NINTR                          24
 #define IOAPIC_FIXED                   0
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;
 
-- 
2.30.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]