:: commit 4bda00b6cc1775ab256a9d835fd2a4d971feac58

mintsuki <mintsuki@protonmail.com> — 2020-09-17 12:37

parents: a909fd821c

Implement acpi_get_table()

diff --git a/stage2/Makefile b/stage2/Makefile
index ef8d88fa..addfae79 100644
--- a/stage2/Makefile
+++ b/stage2/Makefile
@@ -5,7 +5,8 @@ OBJCOPY = ../toolchain/bin/i386-elf-objcopy
 CFLAGS = -flto -Os -pipe -Wall -Wextra
 
 INTERNAL_CFLAGS =  \
-	-std=gnu99 \
+	-std=gnu11 \
+	-fplan9-extensions \
 	-ffreestanding \
 	-fno-stack-protector \
 	-fno-pic \
diff --git a/stage2/lib/acpi.c b/stage2/lib/acpi.c
index 661182c7..49c050af 100644
--- a/stage2/lib/acpi.c
+++ b/stage2/lib/acpi.c
@@ -1,4 +1,6 @@
 #include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
 #include <lib/acpi.h>
 #include <lib/blib.h>
 #include <lib/libc.h>
@@ -29,3 +31,39 @@ void *acpi_get_rsdp(void) {
 
     return NULL;
 }
+
+void *acpi_get_table(const char *signature, int index) {
+    int cnt = 0;
+
+    struct rsdp_rev2 *rsdp = acpi_get_rsdp();
+    if (rsdp == NULL)
+        return NULL;
+
+    bool use_xsdt = false;
+    if (rsdp->rev >= 2 && rsdp->xsdt_addr)
+        use_xsdt = true;
+
+    struct rsdt *rsdt;
+    if (use_xsdt)
+        rsdt = (struct rsdt *)(size_t)rsdp->xsdt_addr;
+    else
+        rsdt = (struct rsdt *)rsdp->rsdt_addr;
+
+    for (size_t i = 0; i < rsdt->length - sizeof(struct sdt); i++) {
+        struct sdt *ptr;
+        if (use_xsdt)
+            ptr = (struct sdt *)(size_t)((uint64_t *)rsdt->ptrs_start)[i];
+        else
+            ptr = (struct sdt *)((uint32_t *)rsdt->ptrs_start)[i];
+
+        if (!memcmp(ptr->signature, signature, 4)
+         && !acpi_checksum(ptr, ptr->length)
+         && cnt++ == index) {
+            print("acpi: Found \"%s\" at %X\n", signature, ptr);
+            return ptr;
+        }
+    }
+
+    print("acpi: \"%s\" not found\n", signature);
+    return NULL;
+}
diff --git a/stage2/lib/acpi.h b/stage2/lib/acpi.h
index ddbf7f1b..ba065135 100644
--- a/stage2/lib/acpi.h
+++ b/stage2/lib/acpi.h
@@ -27,7 +27,7 @@ struct rsdp {
 } __attribute__((packed));
 
 struct rsdp_rev2 {
-    struct rsdp rsdp;
+    struct rsdp;
     uint32_t length;
     uint64_t xsdt_addr;
     uint8_t  ext_checksum;
@@ -35,12 +35,12 @@ struct rsdp_rev2 {
 } __attribute__((packed));
 
 struct rsdt {
-    struct sdt sdt;
-    char       ptrs_start[];
+    struct sdt;
+    char ptrs_start[];
 } __attribute__((packed));
 
 uint8_t acpi_checksum(void *ptr, size_t size);
 void   *acpi_get_rsdp(void);
-void   *acpi_get_table(const char *signature);
+void   *acpi_get_table(const char *signature, int index);
 
 #endif
tab: 248 wrap: offon