diff options
author | sigsegv7 <ian@vegaa.systems> | 2023-09-14 03:37:37 -0400 |
---|---|---|
committer | sigsegv7 <ian@vegaa.systems> | 2023-09-14 03:37:37 -0400 |
commit | 6fa3db464e3bbe60232169195713902113900806 (patch) | |
tree | eecb18d0230e963135730418345fffe61a918185 /sys | |
parent | 3a72a201448fe16657a14cfc5916b672df94acf0 (diff) |
kernel: acpi: Add IRQ to GSI function
Signed-off-by: sigsegv7 <ian@vegaa.systems>
Diffstat (limited to 'sys')
-rw-r--r-- | sys/firmware/acpi/acpi_madt.c | 34 | ||||
-rw-r--r-- | sys/include/firmware/acpi/acpi.h | 1 |
2 files changed, 35 insertions, 0 deletions
diff --git a/sys/firmware/acpi/acpi_madt.c b/sys/firmware/acpi/acpi_madt.c index fde5dde..bf3007b 100644 --- a/sys/firmware/acpi/acpi_madt.c +++ b/sys/firmware/acpi/acpi_madt.c @@ -84,6 +84,40 @@ do_parse(void) } } +/* + * Converts IRQ numbers to its corresponding + * Global System Interrupt (GSI) number. + * + * @irq: IRQ number. + */ +uint32_t +irq_to_gsi(uint8_t irq) +{ + struct apic_header *hdr = NULL; + struct interrupt_override *override = NULL; + uint8_t *cur = NULL; + uint8_t *end = NULL; + + cur = (uint8_t *)(madt + 1); + end = (uint8_t *)madt + madt->hdr.length; + + while (cur < end) { + hdr = (void *)cur; + + switch (hdr->type) { + case APIC_TYPE_INTERRUPT_OVERRIDE: + override = (struct interrupt_override *)cur; + if (override->source == irq) { + return override->interrupt; + } + } + + cur += hdr->length; + } + + return irq; +} + void acpi_parse_madt(void) { diff --git a/sys/include/firmware/acpi/acpi.h b/sys/include/firmware/acpi/acpi.h index 049ea58..a3882e2 100644 --- a/sys/include/firmware/acpi/acpi.h +++ b/sys/include/firmware/acpi/acpi.h @@ -34,6 +34,7 @@ #include <sys/types.h> void acpi_init(void); +uint32_t irq_to_gsi(uint8_t irq); void *acpi_query(const char *query); bool acpi_is_checksum_valid(struct acpi_header *hdr); struct acpi_root_sdt *acpi_get_root_sdt(void); |