BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / 53a772a74dcbec1afdda913da790696f3c78bc4b / kernel / acpi

// Related

Nucleus

Barry ACPI DSDT + PCI 53a772a (3 years, 3 months ago)
diff --git a/kernel/acpi/acpi.c b/kernel/acpi/acpi.c
index 2774dbe..431d471 100644
--- a/kernel/acpi/acpi.c
+++ b/kernel/acpi/acpi.c
@@ -1,5 +1,6 @@
 /*
- * This file controls the ACPI.
+ * This file controls ACPI.  It finds the ACPI Root System Descriptor Table then
+ * searches it for more tables, which can be initialised separately.
  */
 
 #include <stdint.h>
@@ -18,24 +19,42 @@ struct RSDPDesc {
 } __attribute__((packed));
 
 void init_apic(struct SDTHeader *);
+void init_fadt(struct SDTHeader *);
+void init_dsdt(struct SDTHeader *);
 
 /* Table handlers */
 struct TableHandler {
 	char *sig;
 	void (*handler)(struct SDTHeader *);
 } handlers[] = {
-	{"APIC", init_apic},
+	{ "APIC", init_apic },
+	{ "FACP", init_fadt },
+	{ "DSDT", init_dsdt },
 };
 
-/* Calculate the ACPI checksum */
-static uint32_t
-checksum(struct SDTHeader *header)
+/* Match a signature to a handler */
+void
+init_table(struct SDTHeader *table)
 {
-	char *byte = (void *) header;
 	uint32_t i, check = 0;
-	for (i = 0; i < header->length; i++)
+	char *byte = (void *) table;
+
+	set_page((uintptr_t) table, PAGE_ADDR((uintptr_t) table) |
+	         PTE_PRESENT | PTE_WRITE);
+	flush_tlb((uintptr_t) table);
+
+	/* Checksum */
+	for (i = 0; i < table->length; i++)
 		check += byte[i];
-	return ((check % 0x100) == 0);
+	if (check % 0x100)
+		return;
+
+	/* Match handler */
+	for (i = 0; i < sizeof(handlers) / sizeof(handlers[0]); i++) {
+		if (memcmp(table->signature, handlers[i].sig, 4))
+			continue;
+		handlers[i].handler(table);
+	}
 }
 
 /* Initialise ACPI */
@@ -65,14 +84,6 @@ init_acpi(void *ebda)
 	set_page((uintptr_t) rsdt, PAGE_ADDR((uintptr_t) rsdt) |
 	         PTE_PRESENT | PTE_WRITE);
 	flush_tlb((uintptr_t) rsdt);
-	for (i = 0; i < (rsdt->length - sizeof(struct SDTHeader)) / 4; i++) {
-		if (!checksum(table[i]))
-			continue;
-		/* Try to match to a handler */
-		for (j = 0; j < sizeof(handlers)/sizeof(handlers[0]); j++) {
-			if (memcmp(table[i]->signature, handlers[j].sig, 4))
-				continue;
-			handlers[j].handler(table[i]);
-		}
-	}
+	for (i = 0; i < (rsdt->length - sizeof(struct SDTHeader)) / 4; i++)
+		init_table(table[i]);
 }
diff --git a/kernel/acpi/acpi.h b/kernel/acpi/acpi.h
index 9821960..0c39b19 100644
--- a/kernel/acpi/acpi.h
+++ b/kernel/acpi/acpi.h
@@ -14,6 +14,7 @@ struct SDTHeader {
 	uint32_t creatorRevision;
 };
 
+void init_table(struct SDTHeader *table);
 void init_acpi(void *ebda);
 
 #endif
diff --git a/kernel/acpi/apic.c b/kernel/acpi/apic.c
index 423d815..4d969f5 100644
--- a/kernel/acpi/apic.c
+++ b/kernel/acpi/apic.c
@@ -122,7 +122,7 @@ apic_start_timer(void)
 	c++;
 }
 
-/* Initialise SMP (RSDT method) */
+/* Initialise SMP */
 void
 init_apic(struct SDTHeader *header)
 {
diff --git a/kernel/acpi/dsdt.c b/kernel/acpi/dsdt.c
new file mode 100644
index 0000000..23b8178
--- /dev/null
+++ b/kernel/acpi/dsdt.c
@@ -0,0 +1,16 @@
+/*
+ * This file contains the Differentated System Descriptor Table initialisation
+ * code.  The DSDT describes the peripherals attached to a machine, holding
+ * information on IO ports, IRQs, memory mappings and power management.
+ */
+
+#include <nucleus/panic.h>
+#include <io.h>
+#include "acpi.h"
+
+/* Parse the DSDT for information */
+void
+init_dsdt(struct SDTHeader *header)
+{
+	return;
+}
diff --git a/kernel/acpi/fadt.c b/kernel/acpi/fadt.c
new file mode 100644
index 0000000..92ce4c1
--- /dev/null
+++ b/kernel/acpi/fadt.c
@@ -0,0 +1,40 @@
+/*
+ * This file contains the code for handling the Fixed ACPI Description Table.
+ * The FADT describes the ACPI fixed register blocks related to power
+ * management.  It should also contain a pointer to the Differentiated System
+ * Description Table.
+ */
+
+#include <io.h>
+#include "acpi.h"
+
+/* Preferred Power Management Profile */
+enum PMProfile {
+	PM_UNSPECIFIED,
+	PM_DESKTOP,
+	PM_MOBILE,
+	PM_WORKSTATION,
+	PM_ENTERPRISE_SERVER,
+	PM_SOHO_SERVER,
+	PM_APPLIANCE_PC,
+	PM_PERFORMANCE_SERVER,
+};
+
+/* Structure of the FADT */
+struct FADTable {
+	uint32_t firmwareCtrl;
+	uint32_t dsdt;
+	uint8_t reserved;
+	uint8_t prefPMProfile;
+	uint16_t sciInterrupt;
+	uint32_t smiCommandPort;
+	/* Bunch more boring stuff */
+};
+
+/* Parse FADT for information */
+void
+init_fadt(struct SDTHeader *header)
+{
+	struct FADTable *fadt = (struct FADTable *) (header + 1);
+	init_table((void *) fadt->dsdt);
+}