summaryrefslogtreecommitdiff
path: root/sys/firmware/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'sys/firmware/acpi')
-rw-r--r--sys/firmware/acpi/acpi_subr.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/sys/firmware/acpi/acpi_subr.c b/sys/firmware/acpi/acpi_subr.c
index d9ea694..7212602 100644
--- a/sys/firmware/acpi/acpi_subr.c
+++ b/sys/firmware/acpi/acpi_subr.c
@@ -31,6 +31,8 @@
#include <firmware/acpi/acpi.h>
#include <firmware/acpi/tables.h>
+#include <vm/vm.h>
+#include <string.h>
bool
acpi_is_checksum_valid(struct acpi_header *hdr)
@@ -45,3 +47,37 @@ acpi_is_checksum_valid(struct acpi_header *hdr)
/* Sum of table (from header to end) must be zero!! */
return sum == 0;
}
+
+/*
+ * Looks up an ACPI table with a specific
+ * signature e.g "APIC" for MADT (if present).
+ *
+ * @query: The specific query to make e.g "APIC"
+ */
+void *
+acpi_query(const char *query)
+{
+ struct acpi_header *hdr;
+ struct acpi_root_sdt *root_sdt;
+ size_t root_sdt_len, signature_len;
+
+ root_sdt = acpi_get_root_sdt();
+ root_sdt_len = acpi_get_root_sdt_len();
+
+ /*
+ * XXX: Just a reminder, sizeof() is compile time.
+ * There will be no actual reading,
+ * so this is safe.
+ */
+ signature_len = sizeof(hdr->signature);
+
+ for (size_t i = 0; i < root_sdt_len; ++i) {
+ hdr = (struct acpi_header *)PHYS_TO_VIRT(root_sdt->tables[i]);
+
+ if (memcmp(hdr->signature, query, signature_len) == 0) {
+ return (void *)hdr;
+ }
+ }
+
+ return NULL;
+}