diff --git a/kernel/inc/drivers/acpi/rsdp.h b/kernel/inc/drivers/acpi/rsdp.h index e9e8044..6e60f0c 100644 --- a/kernel/inc/drivers/acpi/rsdp.h +++ b/kernel/inc/drivers/acpi/rsdp.h @@ -21,4 +21,7 @@ typedef struct { uint8_t reserved [3]; } __attribute__((packed)) rsdp_descriptor_v2_T; +bool rsdp_descriptor_v1_verify(rsdp_descriptor_v1_T* descriptor); +bool rsdp_descriptor_v2_verify(rsdp_descriptor_v2_T* descriptor); + #endif //NOX_RSDP_H diff --git a/kernel/src/drivers/acpi/acpi.c b/kernel/src/drivers/acpi/acpi.c index dde12e3..a5b2a3e 100644 --- a/kernel/src/drivers/acpi/acpi.c +++ b/kernel/src/drivers/acpi/acpi.c @@ -1,8 +1,30 @@ // This file is part of noxos and licensed under the MIT open source license #include "drivers/acpi/acpi.h" +#include "drivers/acpi/rsdp.h" #include "utils/logger.h" void acpi_init(boot_info_T* boot_info) { - log(LOG_DEBUG, "Initializing ACPI - RSDP: 0x%x", boot_info->rsdp); + log(LOG_INFO, "Initializing ACPI - RSDP: 0x%x", boot_info->rsdp); + rsdp_descriptor_v1_T* rsdp = boot_info->rsdp; + switch (rsdp->revision) { + case 0: { + log(LOG_INFO, " Version: 1.0"); + if (!rsdp_descriptor_v1_verify(boot_info->rsdp)) { + log(LOG_WARNING, " RSDP header verification failed"); + } + break; + } + case 2: { + log(LOG_INFO, " Version: 2.0+"); + if (!rsdp_descriptor_v2_verify(boot_info->rsdp)) { + log(LOG_WARNING, " RSDP header verification failed"); + } + break; + } + default: { + log(LOG_ERROR, " failed to parse RSDP table (invalid revision)"); + break; + } + } } \ No newline at end of file diff --git a/kernel/src/drivers/acpi/rsdp.c b/kernel/src/drivers/acpi/rsdp.c index b92bff6..fd73a18 100644 --- a/kernel/src/drivers/acpi/rsdp.c +++ b/kernel/src/drivers/acpi/rsdp.c @@ -1 +1,29 @@ // This file is part of noxos and licensed under the MIT open source license + +#include "drivers/acpi/rsdp.h" + +bool rsdp_descriptor_v1_verify(rsdp_descriptor_v1_T* descriptor) { + uint8_t* data = (uint8_t*)descriptor; + uint32_t num = 0; + + for (uint8_t i = 0; i < sizeof(rsdp_descriptor_v1_T); i++) { + num += data[i]; + } + + return ((num & 0xFF) == 0); +} + +bool rsdp_descriptor_v2_verify(rsdp_descriptor_v2_T* descriptor) { + if (!rsdp_descriptor_v1_verify(&descriptor->descriptor_v1)) { + return false; + } + + uint8_t* data = (uint8_t*)descriptor + sizeof(rsdp_descriptor_v1_T); + uint32_t num = 0; + + for (uint8_t i = 0; i < sizeof(rsdp_descriptor_v2_T) - sizeof(rsdp_descriptor_v1_T); i++) { + num += data[i]; + } + + return ((num & 0xFF) == 0); +}