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
