summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-09-15 11:27:01 -0400
committerIan Moffett <ian@osmora.org>2025-09-15 11:27:01 -0400
commit82b2371744f22d4a080040429e9f9f172f712728 (patch)
treeb7c0eb5df1b30cd0287dea606b150de9ca5779d2
parent2ecb4ab1ff39b32452c5b0e82ca6580a0ea09b99 (diff)
kern/amd64: Improve ioapic_read_madt() scalability
This commit improves the scalability of ioapic_read_madt() while retaining as much simplicity as possible. - Add callback argument - Add optional argument to callback ioapic_read_madt() now returns the value given back by a callback. Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r--src/sys/arch/amd64/mainbus/ioapic.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/src/sys/arch/amd64/mainbus/ioapic.c b/src/sys/arch/amd64/mainbus/ioapic.c
index bcd7025..360bd14 100644
--- a/src/sys/arch/amd64/mainbus/ioapic.c
+++ b/src/sys/arch/amd64/mainbus/ioapic.c
@@ -128,11 +128,18 @@ ioapic_write_redentry(const union ioapic_redentry *entry, uint8_t index)
* Read a MADT entry
*
* @type: Type that we should scan for
+ * @cb: Callback (returns 0 if entry is found)
+ * @arg: Optional argument
+ *
+ * Returns the callback return value, on success,
+ * otherwise a less than zero value on failure.
*/
-static struct apic_header *
-ioapic_read_madt(uint32_t type)
+static int
+ioapic_read_madt(uint32_t type, int(*cb)(struct apic_header *, size_t arg),
+ size_t arg)
{
uint8_t *cur, *end;
+ int retval = -1;
struct apic_header *apichdr;
/* Try to read the MADT table */
@@ -146,29 +153,34 @@ ioapic_read_madt(uint32_t type)
while (cur < end) {
apichdr = (void *)cur;
if (apichdr->type == type) {
- return apichdr;
+ retval = cb(apichdr, arg);
+ }
+
+ /* If the entry was found, stop */
+ if (retval >= 0) {
+ return retval;
}
cur += apichdr->length;
}
- return NULL;
+ return -1;
}
/*
* Set the I/O APIC MMIO base address
*/
-static void
-ioapic_set_base(void)
+static int
+__ioapic_callback(struct apic_header *hdr, size_t arg)
{
- struct apic_header *hdr;
-
- hdr = ioapic_read_madt(APIC_TYPE_IO_APIC);
- if (hdr == NULL) {
- panic("ioapic_set_base: could not read APIC_TYPE_IO_APIC\n");
+ if (ioapic != NULL) {
+ return 0;
}
ioapic = (struct ioapic *)hdr;
+ return 0;
+}
+
}
/*
@@ -195,7 +207,11 @@ ioapic_init(void)
uint8_t ver, nredir;
if (ioapic == NULL) {
- ioapic_set_base();
+ ioapic_read_madt(
+ APIC_TYPE_IO_APIC,
+ __ioapic_callback,
+ 0
+ );
}
/* Read the IOAPIC version register */