summaryrefslogtreecommitdiff
path: root/src/sys/arch/amd64/mainbus
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-09-15 11:46:39 -0400
committerIan Moffett <ian@osmora.org>2025-09-15 11:46:39 -0400
commit3505969b3dffe2133d34c41076caa068ca2411b0 (patch)
treec9ab7937cd764e53a75ee7494b35b2115d3bd3fc /src/sys/arch/amd64/mainbus
parent82b2371744f22d4a080040429e9f9f172f712728 (diff)
kern/amd64: ioapic: Add IRQ to vector routing
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'src/sys/arch/amd64/mainbus')
-rw-r--r--src/sys/arch/amd64/mainbus/ioapic.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/src/sys/arch/amd64/mainbus/ioapic.c b/src/sys/arch/amd64/mainbus/ioapic.c
index 360bd14..95ef55a 100644
--- a/src/sys/arch/amd64/mainbus/ioapic.c
+++ b/src/sys/arch/amd64/mainbus/ioapic.c
@@ -38,6 +38,7 @@
static struct ioapic *ioapic = NULL;
static struct acpi_madt *madt = NULL;
+static struct apic_header *override = NULL;
/*
* Write a single 32-bit value to a specific
@@ -181,6 +182,20 @@ __ioapic_callback(struct apic_header *hdr, size_t arg)
return 0;
}
+/*
+ * Convert an IRQ to a GSI
+ */
+static int
+__irq_to_gsi(struct apic_header *hdr, size_t irq)
+{
+ struct interrupt_override *override;
+
+ override = (struct interrupt_override *)hdr;
+ if (override->source == irq) {
+ return override->interrupt;
+ }
+
+ return -1;
}
/*
@@ -192,7 +207,27 @@ ioapic_gsi_mask(uint8_t gsi, uint8_t mask)
union ioapic_redentry redent;
ioapic_read_redentry(&redent, gsi);
- redent.interrupt_mask = gsi & 1;
+ redent.interrupt_mask = mask & 1;
+ ioapic_write_redentry(&redent, gsi);
+}
+
+/*
+ * Map a GSI to a system interrupt vector
+ */
+void
+ioapic_route_vec(uint8_t irq, uint8_t vector)
+{
+ union ioapic_redentry redent;
+ int gsi;
+
+ gsi = ioapic_read_madt(
+ APIC_TYPE_INTERRUPT_OVERRIDE,
+ __irq_to_gsi,
+ irq
+ );
+
+ ioapic_read_redentry(&redent, gsi);
+ redent.vector = vector;
ioapic_write_redentry(&redent, gsi);
}