summaryrefslogtreecommitdiff
path: root/kernel/drivers/acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers/acpi.c')
-rw-r--r--kernel/drivers/acpi.c166
1 files changed, 88 insertions, 78 deletions
diff --git a/kernel/drivers/acpi.c b/kernel/drivers/acpi.c
index a222523..b4bb805 100644
--- a/kernel/drivers/acpi.c
+++ b/kernel/drivers/acpi.c
@@ -53,7 +53,6 @@ struct xsdt {
uint64_t sdt_pointers[];
} __attribute__((packed));
-
// generic address structure
struct gas {
uint8_t address_space;
@@ -91,15 +90,15 @@ struct fadt {
uint32_t dsdt;
// field used in ACPI 1.0; no longer in use, for compatibility only
- uint8_t reserved;
+ uint8_t reserved;
- uint8_t preferred_power_management_profile;
+ uint8_t preferred_power_management_profile;
uint16_t sci_interrupt;
uint32_t smi_command_port;
- uint8_t acpi_enable;
- uint8_t acpi_disable;
- uint8_t s4bios_req;
- uint8_t pstate_control;
+ uint8_t acpi_enable;
+ uint8_t acpi_disable;
+ uint8_t s4bios_req;
+ uint8_t pstate_control;
uint32_t pm1_a_event_block;
uint32_t pm1_b_event_block;
uint32_t pm1_a_control_block;
@@ -108,35 +107,35 @@ struct fadt {
uint32_t pm_timer_block;
uint32_t gpe0_block;
uint32_t gpe1_block;
- uint8_t pm1_event_length;
- uint8_t pm1_control_length;
- uint8_t pm2_control_length;
- uint8_t pm_timer_length;
- uint8_t gpe0_length;
- uint8_t gpe1_length;
- uint8_t gpe1_base;
- uint8_t cstate_control;
+ uint8_t pm1_event_length;
+ uint8_t pm1_control_length;
+ uint8_t pm2_control_length;
+ uint8_t pm_timer_length;
+ uint8_t gpe0_length;
+ uint8_t gpe1_length;
+ uint8_t gpe1_base;
+ uint8_t cstate_control;
uint16_t worst_c2_latency;
uint16_t worst_c3_latency;
uint16_t flush_size;
uint16_t flush_stride;
- uint8_t duty_offset;
- uint8_t duty_width;
- uint8_t day_alarm;
- uint8_t month_alarm;
- uint8_t century;
+ uint8_t duty_offset;
+ uint8_t duty_width;
+ uint8_t day_alarm;
+ uint8_t month_alarm;
+ uint8_t century;
// reserved in ACPI 1.0; used since ACPI 2.0+
uint16_t boot_architecture_flags;
- uint8_t reserved_2;
+ uint8_t reserved_2;
uint32_t flags;
// 12 byte structure; see below for details
struct gas reset_reg;
- uint8_t reset_value;
- uint8_t reserved_3[3];
+ uint8_t reset_value;
+ uint8_t reserved_3[3];
// 64bit pointers - Available on ACPI 2.0+
uint64_t x_firmware_control;
@@ -173,14 +172,16 @@ struct acpi_state {
/* global state, idk a better way rn */
static struct acpi_state state;
-static bool checksum(uint8_t *data, size_t len) {
+static bool checksum(uint8_t *data, size_t len)
+{
unsigned char sum = 0;
for (size_t i = 0; i < len; i++)
sum += data[i];
return sum == 0;
}
-static int read_s5_addr(struct dsdt *dsdt) {
+static int read_s5_addr(struct dsdt *dsdt)
+{
char *s5_addr = dsdt->s5_addr;
int dsdt_len = dsdt->h.length - sizeof(struct acpi_header);
@@ -192,20 +193,22 @@ static int read_s5_addr(struct dsdt *dsdt) {
if (dsdt_len > 0) {
// check for valid AML structure
- if ( ( *(s5_addr-1) == 0x08 || ( *(s5_addr-2) == 0x08 && *(s5_addr-1) == '\\') ) && *(s5_addr+4) == 0x12 ) {
+ if ((*(s5_addr - 1) == 0x08 ||
+ (*(s5_addr - 2) == 0x08 && *(s5_addr - 1) == '\\')) &&
+ *(s5_addr + 4) == 0x12) {
s5_addr += 5;
- s5_addr += ((*s5_addr &0xC0)>>6) +2; // calculate PkgLength size
+ s5_addr += ((*s5_addr & 0xC0) >> 6) + 2; // calculate PkgLength size
if (*s5_addr == 0x0A)
- s5_addr++; // skip byteprefix
- state.SLP_TYPa = *(s5_addr)<<10;
+ s5_addr++; // skip byteprefix
+ state.SLP_TYPa = *(s5_addr) << 10;
s5_addr++;
if (*s5_addr == 0x0A)
- s5_addr++; // skip byteprefix
- state.SLP_TYPb = *(s5_addr)<<10;
+ s5_addr++; // skip byteprefix
+ state.SLP_TYPb = *(s5_addr) << 10;
- state.SLP_EN = 1<<13;
+ state.SLP_EN = 1 << 13;
state.SCI_EN = 1;
} else {
@@ -220,7 +223,8 @@ static int read_s5_addr(struct dsdt *dsdt) {
static void acpi_load_table(uint64_t addr);
-static void acpi_load_rsdt_tables(struct rsdt *rsdt) {
+static void acpi_load_rsdt_tables(struct rsdt *rsdt)
+{
int entries = (rsdt->h.length - sizeof(rsdt->h)) / 4;
for (int i = 0; i < entries; i++) {
uint32_t addr = rsdt->sdt_pointers[i];
@@ -228,7 +232,8 @@ static void acpi_load_rsdt_tables(struct rsdt *rsdt) {
}
}
-static void acpi_load_xsdt_tables(struct xsdt *xsdt) {
+static void acpi_load_xsdt_tables(struct xsdt *xsdt)
+{
int entries = (xsdt->h.length - sizeof(xsdt->h)) / 8;
for (int i = 0; i < entries; i++) {
uint64_t addr = xsdt->sdt_pointers[i];
@@ -236,65 +241,68 @@ static void acpi_load_xsdt_tables(struct xsdt *xsdt) {
}
}
-#define SIG_RSDT 0x54445352
-#define SIG_XSDT 0x54445358
-#define SIG_FACP 0x50434146
-#define SIG_DSDT 0x54445344
-#define SIG_APIC 0x43495041
-#define SIG_HEPT 0x54455048
-#define SIG_WAET 0x54454157
+#define SIG_RSDT 0x54445352
+#define SIG_XSDT 0x54445358
+#define SIG_FACP 0x50434146
+#define SIG_DSDT 0x54445344
+#define SIG_APIC 0x43495041
+#define SIG_HEPT 0x54455048
+#define SIG_WAET 0x54454157
-static void acpi_handle_table(struct acpi_header *header) {
+static void acpi_handle_table(struct acpi_header *header)
+{
switch (header->signature) {
- case SIG_RSDT:
- state.sdt.rsdt = (struct rsdt *) header;
- acpi_load_rsdt_tables(state.sdt.rsdt);
- break;
- case SIG_XSDT:
- state.sdt.xsdt = (struct xsdt *) header;
- acpi_load_xsdt_tables(state.sdt.xsdt);
- break;
- case SIG_FACP:
- state.fadt = (struct fadt *) header;
- acpi_load_table(state.fadt->dsdt);
- break;
- case SIG_DSDT:
- state.dsdt = (struct dsdt *) header;
- read_s5_addr(state.dsdt);
- break;
- case SIG_APIC:
- state.apic = (struct apic *) header;
- break;
- case SIG_HEPT:
- state.hept = (struct hept *) header;
- break;
- case SIG_WAET:
- state.waet = (struct waet *) header;
- break;
- default:
- break;
+ case SIG_RSDT:
+ state.sdt.rsdt = (struct rsdt *)header;
+ acpi_load_rsdt_tables(state.sdt.rsdt);
+ break;
+ case SIG_XSDT:
+ state.sdt.xsdt = (struct xsdt *)header;
+ acpi_load_xsdt_tables(state.sdt.xsdt);
+ break;
+ case SIG_FACP:
+ state.fadt = (struct fadt *)header;
+ acpi_load_table(state.fadt->dsdt);
+ break;
+ case SIG_DSDT:
+ state.dsdt = (struct dsdt *)header;
+ read_s5_addr(state.dsdt);
+ break;
+ case SIG_APIC:
+ state.apic = (struct apic *)header;
+ break;
+ case SIG_HEPT:
+ state.hept = (struct hept *)header;
+ break;
+ case SIG_WAET:
+ state.waet = (struct waet *)header;
+ break;
+ default:
+ break;
}
}
-static void acpi_load_table(uint64_t addr) {
+static void acpi_load_table(uint64_t addr)
+{
struct acpi_header *temp, *mapped;
uint32_t length;
- temp = (struct acpi_header * ) (uintptr_t) addr;
+ temp = (struct acpi_header *)(uintptr_t)addr;
mapped = kmapaddr(temp, sizeof(struct acpi_header));
length = mapped->length;
kunmapaddr(mapped);
mapped = kmapaddr(temp, length);
- if (!checksum((uint8_t *) mapped, mapped->length)) {
+ if (!checksum((uint8_t *)mapped, mapped->length)) {
kunmapaddr(mapped);
return;
}
- kprintf("%.*s: %#016lx\n", 4, (char*)&mapped->signature, (size_t)temp);
+ kprintf("%.*s: %#016lx\n", 4, (char *)&mapped->signature, (size_t)temp);
acpi_handle_table(mapped);
}
-void acpi_init(void *rootsdp) {
+void acpi_init(void *rootsdp)
+{
memset(&state, 0, sizeof(struct acpi_state));
- struct rsdp *rsdp = (struct rsdp *) rootsdp;
+ struct rsdp *rsdp = (struct rsdp *)rootsdp;
if (!checksum((uint8_t *)rsdp, sizeof(struct rsdp))) {
panic("invalid acpi rsdp checksum");
}
@@ -307,7 +315,7 @@ void acpi_init(void *rootsdp) {
acpi_load_table(rsdp->rsdt_addr);
} else if (rsdp->revision == 2) {
state.version = 2;
- struct xsdp *xsdp = (struct xsdp *) rsdp;
+ struct xsdp *xsdp = (struct xsdp *)rsdp;
kprintf("ACPI 2.0\n");
acpi_load_table(xsdp->xsdt_addr);
} else {
@@ -317,7 +325,9 @@ void acpi_init(void *rootsdp) {
outb(state.fadt->smi_command_port, state.fadt->acpi_enable);
}
-void acpi_shutdown(void) {
- outw((unsigned int) state.fadt->pm1_a_control_block, state.SLP_TYPb | state.SLP_EN);
+void acpi_shutdown(void)
+{
+ outw((unsigned int)state.fadt->pm1_a_control_block,
+ state.SLP_TYPb | state.SLP_EN);
panic("ACPI shutdown failed");
}