aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorsigsegv7 <ian@vegaa.systems>2023-09-14 03:37:37 -0400
committersigsegv7 <ian@vegaa.systems>2023-09-14 03:37:37 -0400
commit6fa3db464e3bbe60232169195713902113900806 (patch)
treeeecb18d0230e963135730418345fffe61a918185 /sys
parent3a72a201448fe16657a14cfc5916b672df94acf0 (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.c34
-rw-r--r--sys/include/firmware/acpi/acpi.h1
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);