diff options
-rw-r--r-- | src/kernel/acpi/acpi.c | 75 | ||||
-rw-r--r-- | src/kernel/acpi/acpi.h | 4 | ||||
-rw-r--r-- | src/kernel/cmos/rtc.c | 4 |
3 files changed, 41 insertions, 42 deletions
diff --git a/src/kernel/acpi/acpi.c b/src/kernel/acpi/acpi.c index 1cf5ca6..bb4bdac 100644 --- a/src/kernel/acpi/acpi.c +++ b/src/kernel/acpi/acpi.c @@ -1,3 +1,6 @@ +// Important specification: https://uefi.org/sites/default/files/resources/ACPI_6_2.pdf +// HPET: https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/software-developers-hpet-spec-1-0a.pdf + #include <kernel/io/io.h> #include <kernel/lib/lib.h> #include <kernel/timer/timer.h> @@ -5,7 +8,7 @@ #include <stddef.h> #include <kernel/system.h> -struct FACP *facp; +struct FADT *fadt; uint32_t *SMI_CMD; char ACPI_ENABLE; char ACPI_DISABLE; @@ -61,21 +64,6 @@ unsigned int *acpi_get_rsd_ptr() { return NULL; } -int acpi_check_header(unsigned int *ptr, char *sig) { - if (memcmp(ptr, sig, 4) == 0) { - char *checkPtr = (char *) ptr; - int len = *(ptr + 1); - char check = 0; - while (0 < len--) { - check += *checkPtr; - checkPtr++; - } - if (check == 0) - return 0; - } - return -1; -} - int acpi_enable() { if ((receive_w((unsigned int) PM1a_CNT) & SCI_EN) == 0) { if (SMI_CMD != 0 && ACPI_ENABLE != 0) { @@ -96,12 +84,15 @@ int acpi_enable() { if (i < 300) { return 0; // Successfully enabled ACPI } else { + serial_write("ACPI couldn't be enabled!\n"); return -1; // ACPI couldn't be enabled } } else { + serial_write("ACPI is not supported!\n"); return -1; // ACPI is not supported } } else { + serial_write("ACPI was already enabled!\n"); return 0; // ACPI was already enabled } } @@ -109,24 +100,26 @@ int acpi_enable() { int acpi_install() { unsigned int *ptr = acpi_get_rsd_ptr(); - if (ptr != NULL && acpi_check_header(ptr, "RSDT") == 0) { - int entrys = *(ptr + 1); - entrys = (entrys - 36) / 4; + int success = 0; + + if (ptr != NULL && memcmp(ptr, "RSDT", 4) == 0) { + int entries = *(ptr + 1); + entries = (entries - 36) / 4; ptr += 36 / 4; - while (0 < entrys--) { - if (acpi_check_header((unsigned int *) *ptr, "FACP") == 0) { - entrys = -2; - facp = (struct FACP *) *ptr; - if (acpi_check_header((unsigned int *) facp->DSDT, "DSDT") == 0) { - char *S5Addr = (char *) facp->DSDT + 36; - int dsdt_length = *(facp->DSDT + 1) - 36; + while (0 < entries--) { + if (memcmp((unsigned int *) *ptr, "FACP", 4) == 0) { + fadt = (struct FADT *) *ptr; + if (memcmp((unsigned int *) fadt->DSDT, "DSDT", 4) == 0) { + char *S5Addr = (char *) fadt->DSDT + 36; + int dsdt_length = *(fadt->DSDT + 1) - 36; while (0 < dsdt_length--) { if (memcmp(S5Addr, "_S5_", 4) == 0) break; S5Addr++; } if (dsdt_length > 0) { + // TODO: Implement device detection via DSDT ACPI (p199 -> AML) if ((*(S5Addr - 1) == 0x08 || (*(S5Addr - 2) == 0x08 && *(S5Addr - 1) == '\\')) && *(S5Addr + 4) == 0x12) { S5Addr += 5; @@ -141,36 +134,42 @@ int acpi_install() { S5Addr++; SLP_TYPb = *(S5Addr) << 10; - SMI_CMD = facp->SMI_CMD; + SMI_CMD = fadt->SMI_CMD; - ACPI_ENABLE = facp->ACPI_ENABLE; - ACPI_DISABLE = facp->ACPI_DISABLE; + ACPI_ENABLE = fadt->ACPI_ENABLE; + ACPI_DISABLE = fadt->ACPI_DISABLE; - PM1a_CNT = facp->PM1a_CNT_BLK; - PM1b_CNT = facp->PM1b_CNT_BLK; + PM1a_CNT = fadt->PM1a_CNT_BLK; + PM1b_CNT = fadt->PM1b_CNT_BLK; - PM1_CNT_LEN = facp->PM1_CNT_LEN; + PM1_CNT_LEN = fadt->PM1_CNT_LEN; SLP_EN = 1 << 13; SCI_EN = 1; - vga_log("Installed ACPI", 5); acpi_enable(); + vga_log("Installed ACPI", 5); - return 0; + success = 1; } // Else: \_S5 parse error } // Else: \_S5 not present } // Else: DSDT invalid } + if (memcmp((unsigned int *) *ptr, "HPET", 4) == 0) { + serial_write("WHOA - found HPET!!!\n"); + } ptr++; - } // Else: no valid FACP present - } // Else: No ACPI available - return -1; + } // Else: no valid FADT present + } else { + serial_write("ACPI is not supported!\n"); + } + + return success == 1 ? 0 : -1; } void acpi_poweroff() { if (SCI_EN == 0) { - serial_write("ACPI shutdown is not supported\n"); + warn("ACPI shutdown is not supported\n"); return; } diff --git a/src/kernel/acpi/acpi.h b/src/kernel/acpi/acpi.h index 1d18182..f4dd049 100644 --- a/src/kernel/acpi/acpi.h +++ b/src/kernel/acpi/acpi.h @@ -25,7 +25,7 @@ struct RSDPtr { uint32_t *rsdt_address; }; -struct FACP { +struct FADT { char Signature[4]; uint32_t Length; char unneded1[40 - 8]; @@ -43,6 +43,6 @@ struct FACP { char century; }; -extern struct FACP *facp; +extern struct FADT *fadt; #endif diff --git a/src/kernel/cmos/rtc.c b/src/kernel/cmos/rtc.c index ed7c494..20e1b50 100644 --- a/src/kernel/cmos/rtc.c +++ b/src/kernel/cmos/rtc.c @@ -37,7 +37,7 @@ void read_rtc() { day = get_rtc_register(0x07); month = get_rtc_register(0x08); year = get_rtc_register(0x09); - century = get_rtc_register(facp->century); + century = get_rtc_register(fadt->century); // Try until the values are the same (fix for RTC updates) do { @@ -56,7 +56,7 @@ void read_rtc() { day = get_rtc_register(0x07); month = get_rtc_register(0x08); year = get_rtc_register(0x09); - century = get_rtc_register(facp->century); + century = get_rtc_register(fadt->century); } while ((last_second != second) || (last_minute != minute) || (last_hour != hour) || (last_day != day) || (last_month != month) || (last_year != year) || (last_century != century)); |