summaryrefslogtreecommitdiff
path: root/i386
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2023-09-30 06:30:51 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2023-09-30 10:44:52 +0200
commitb4c888624b40374213adce00d712930ef4d6d908 (patch)
treee37aae6ce70de8b5789282910a5a7299a3be1fa5 /i386
parentdc8b8ba82a33897cd5cf89a61f1b1599e9a30f8b (diff)
ioapic: Detect version of IOAPIC for correct EOI handling
Message-Id: <20230930063032.75232-2-damien@zamaudio.com>
Diffstat (limited to 'i386')
-rw-r--r--i386/i386at/ioapic.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/i386/i386at/ioapic.c b/i386/i386at/ioapic.c
index 218f9a51..57d18789 100644
--- a/i386/i386at/ioapic.c
+++ b/i386/i386at/ioapic.c
@@ -33,7 +33,7 @@
#include <kern/printf.h>
#include <kern/timer.h>
-static int has_irq_specific_eoi = 1; /* FIXME: Assume all machines have this */
+static int has_irq_specific_eoi = 0;
int timer_pin;
uint32_t lapic_timer_val = 0;
@@ -153,6 +153,12 @@ ioapic_toggle_entry(int apic, int pin, int mask)
ioapic_write(apic, APIC_IO_REDIR_LOW(pin), entry.lo);
}
+static int
+ioapic_version(int apic)
+{
+ return ioapic_read(apic, APIC_IO_VERSION) & 0xff;
+}
+
static void timer_expiry_callback(void *arg)
{
volatile int *done = arg;
@@ -305,6 +311,13 @@ ioapic_configure(void)
int gsi, apic = 0, bsp = 0, pin;
IrqOverrideData *irq_over;
int timer_gsi;
+ int version = ioapic_version(apic);
+
+ if (version >= 0x20) {
+ has_irq_specific_eoi = 1;
+ }
+
+ printf("IOAPIC version 0x%x\n", version);
/* Disable IOAPIC interrupts and set spurious interrupt */
lapic->spurious_vector.r = IOAPIC_SPURIOUS_BASE;