--- src/kernel/sel4/include/plat/pc99/plat/machine/acpi.h +++ src/kernel/sel4/include/plat/pc99/plat/machine/acpi.h @@ -15,6 +15,11 @@ #include #include +enum acpi_size { + ACPI_V1_SIZE = 20, + ACPI_V2_SIZE = 36 +}; + /* Generic System Descriptor Table Header */ typedef struct acpi_header { char signature[4]; @@ -40,7 +45,7 @@ typedef struct acpi_rsdp { uint8_t extended_checksum; char reserved[3]; } PACKED acpi_rsdp_t; -compile_assert(acpi_rsdp_packed, sizeof(acpi_rsdp_t) == 36) +compile_assert(acpi_rsdp_packed, sizeof(acpi_rsdp_t) == ACPI_V2_SIZE) /* Root System Descriptor Table */ typedef struct acpi_rsdt { --- src/kernel/sel4/src/arch/x86/kernel/boot_sys.c +++ src/kernel/sel4/src/arch/x86/kernel/boot_sys.c @@ -651,12 +651,14 @@ try_boot_sys_mbi2( if (tag->type == MULTIBOOT2_TAG_CMDLINE) { char const * const cmdline = (char const * const)(behind_tag); cmdline_parse(cmdline, &cmdline_opt); - } else if (tag->type == MULTIBOOT2_TAG_ACPI) { - if (sizeof(boot_state.acpi_rsdp) != tag->size - sizeof(*tag)) { - printf("sizeof ACPI RSDP unexpected %ld!=%lu\n", (long)sizeof(boot_state.acpi_rsdp), (long)tag->size - sizeof(*tag)); - return false; + } else if (tag->type == MULTIBOOT2_TAG_ACPI_1) { + if (ACPI_V1_SIZE == tag->size - sizeof(*tag)) { + memcpy(&boot_state.acpi_rsdp, (void *)behind_tag, tag->size - sizeof(*tag)); + } + } else if (tag->type == MULTIBOOT2_TAG_ACPI_2) { + if (sizeof(boot_state.acpi_rsdp) == tag->size - sizeof(*tag)) { + memcpy(&boot_state.acpi_rsdp, (void *)behind_tag, sizeof(boot_state.acpi_rsdp)); } - memcpy(&boot_state.acpi_rsdp, (void *)behind_tag, sizeof(boot_state.acpi_rsdp)); } else if (tag->type == MULTIBOOT2_TAG_MODULE) { multiboot2_module_t const * module = (multiboot2_module_t const *)behind_tag; printf( --- src/kernel/sel4/src/plat/pc99/machine/acpi.c +++ src/kernel/sel4/src/plat/pc99/machine/acpi.c @@ -182,7 +182,7 @@ acpi_get_rsdp(void) for (addr = (char*)BIOS_PADDR_START; addr < (char*)BIOS_PADDR_END; addr += 16) { if (strncmp(addr, acpi_str_rsd, 8) == 0) { - if (acpi_calc_checksum(addr, 20) == 0) { + if (acpi_calc_checksum(addr, ACPI_V1_SIZE) == 0) { return (acpi_rsdp_t*)addr; } } @@ -255,8 +255,13 @@ acpi_validate_rsdp(acpi_rsdp_t *acpi_rsdp) acpi_rsdt_t* acpi_rsdt; acpi_rsdt_t* acpi_rsdt_mapped; - if (acpi_calc_checksum((char*)acpi_rsdp, 20) != 0) { - printf("BIOS: ACPI information corrupt\n"); + if (acpi_calc_checksum((char*)acpi_rsdp, ACPI_V1_SIZE) != 0) { + printf("BIOS: ACPIv1 information corrupt\n"); + return false; + } + + if (acpi_rsdp->revision > 0 && acpi_calc_checksum((char*)acpi_rsdp, sizeof(*acpi_rsdp)) != 0) { + printf("BIOS: ACPIv2 information corrupt\n"); return false; } --- src/kernel/sel4/include/arch/x86/arch/kernel/multiboot2.h +++ src/kernel/sel4/include/arch/x86/arch/kernel/multiboot2.h @@ -43,7 +43,8 @@ enum multiboot2_tags { MULTIBOOT2_TAG_CMDLINE = 1, MULTIBOOT2_TAG_MODULE = 3, MULTIBOOT2_TAG_MEMORY = 6, - MULTIBOOT2_TAG_ACPI = 15, + MULTIBOOT2_TAG_ACPI_1 = 14, + MULTIBOOT2_TAG_ACPI_2 = 15, }; #endif