mirror of
https://github.com/limine-bootloader/limine
synced 2025-01-05 20:34:33 +03:00
multiboot2: add the ACPI old tag
Signed-off-by: Andy-Python-Programmer <andypythonappdeveloper@gmail.com>
This commit is contained in:
parent
cce7fa4e1e
commit
725393b26b
@ -34,6 +34,21 @@ void *acpi_get_rsdp(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// Returns the RSDP v1 pointer if avaliable or else NULL.
|
||||
void *acpi_get_rsdp_v1(void) {
|
||||
// In BIOS according to the ACPI spec (see ACPI 6.2 section
|
||||
// 5.2.5.1 'Finding the RSDP on IA-PC Systems') it either contains
|
||||
// the RSDP or the XSDP and it cannot contain both. So, we directly
|
||||
// use acpi_get_rsdp function to find the RSDP and if it has the correct
|
||||
// revision, return it.
|
||||
struct rsdp *rsdp = acpi_get_rsdp();
|
||||
|
||||
if (rsdp != NULL && rsdp->rev == 1)
|
||||
return rsdp;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void acpi_get_smbios(void **smbios32, void **smbios64) {
|
||||
*smbios32 = NULL;
|
||||
*smbios64 = NULL;
|
||||
@ -67,18 +82,56 @@ void *acpi_get_rsdp(void) {
|
||||
EFI_GUID acpi_2_guid = ACPI_20_TABLE_GUID;
|
||||
EFI_GUID acpi_1_guid = ACPI_TABLE_GUID;
|
||||
|
||||
void *rsdp = NULL;
|
||||
|
||||
for (size_t i = 0; i < gST->NumberOfTableEntries; i++) {
|
||||
EFI_CONFIGURATION_TABLE *cur_table = &gST->ConfigurationTable[i];
|
||||
|
||||
if (memcmp(&cur_table->VendorGuid, &acpi_2_guid, sizeof(EFI_GUID)) != 0 || // XSDP
|
||||
memcmp(&cur_table->VendorGuid, &acpi_1_guid, sizeof(EFI_GUID)) != 0) // RSDP
|
||||
bool is_xsdp = memcmp(&cur_table->VendorGuid, &acpi_2_guid, sizeof(EFI_GUID)) == 0;
|
||||
bool is_rsdp = memcmp(&cur_table->VendorGuid, &acpi_1_guid, sizeof(EFI_GUID)) == 0;
|
||||
|
||||
if (!is_xsdp && !is_rsdp)
|
||||
continue;
|
||||
|
||||
if ((is_xsdp && acpi_checksum(cur_table->VendorTable, sizeof(struct rsdp)) != 0) || // XSDP is 36 bytes wide
|
||||
(is_rsdp && acpi_checksum(cur_table->VendorTable, 20) != 0)) // RSDP is 20 bytes wide
|
||||
continue;
|
||||
|
||||
if (acpi_checksum(cur_table->VendorTable, sizeof(struct rsdp)) != 0 || // XSDP is 36 bytes wide
|
||||
acpi_checksum(cur_table->VendorTable, 20) != 0) // RSDP is 20 bytes wide
|
||||
continue;
|
||||
printv("acpi: Found %s at %X\n", is_xsdp ? "XSDP" : "RSDP", cur_table->VendorTable);
|
||||
|
||||
printv("acpi: Found RSDP at %X\n", cur_table->VendorTable);
|
||||
// We want to return the XSDP if it exists rather then returning
|
||||
// the RSDP. We need to add a check for that since the table entries
|
||||
// are not in the same order for all EFI systems since it might be the
|
||||
// case where the RSDP ocurs before the XSDP.
|
||||
if (rsdp != NULL && is_xsdp) {
|
||||
rsdp = (void *)cur_table->VendorTable;
|
||||
break; // Found it!.
|
||||
} else {
|
||||
// Found the RSDP but we continue to loop since we might
|
||||
// find the XSDP.
|
||||
rsdp = (void *)cur_table->VendorTable;
|
||||
}
|
||||
}
|
||||
|
||||
return rsdp;
|
||||
}
|
||||
|
||||
/// Returns the RSDP v1 pointer if avaliable or else NULL.
|
||||
void *acpi_get_rsdp_v1(void) {
|
||||
// To maintain GRUB compatibility we will need to probe for the RSDP
|
||||
// again since UEFI can contain both XSDP and RSDP (see ACPI 6.2 section
|
||||
// 5.2.5.2 'Finding the RSDP on UEFI Enabled Systems') and in the acpi_get_rsdp
|
||||
// function we look for the RSDP with the latest revision.
|
||||
EFI_GUID acpi_1_guid = ACPI_TABLE_GUID;
|
||||
|
||||
for (size_t i = 0; i < gST->NumberOfTableEntries; i++) {
|
||||
EFI_CONFIGURATION_TABLE *cur_table = &gST->ConfigurationTable[i];
|
||||
|
||||
if (memcmp(&cur_table->VendorGuid, &acpi_1_guid, sizeof(EFI_GUID)) != 0)
|
||||
continue;
|
||||
|
||||
if (acpi_checksum(cur_table->VendorTable, 20) != 0)
|
||||
continue;
|
||||
|
||||
return (void *)cur_table->VendorTable;
|
||||
}
|
||||
@ -129,6 +182,18 @@ void acpi_get_smbios(void **smbios32, void **smbios64) {
|
||||
|
||||
#endif
|
||||
|
||||
/// Returns the RSDP v2 pointer if avaliable or else NULL.
|
||||
void *acpi_get_rsdp_v2(void) {
|
||||
// Since the acpi_get_rsdp function already looks for the XSDP we can
|
||||
// just check if it has the correct revision and return the pointer :^)
|
||||
struct rsdp *rsdp = acpi_get_rsdp();
|
||||
|
||||
if (rsdp != NULL && rsdp->rev >= 2)
|
||||
return rsdp;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *acpi_get_table(const char *signature, int index) {
|
||||
int cnt = 0;
|
||||
|
||||
|
@ -38,6 +38,10 @@ struct rsdt {
|
||||
|
||||
uint8_t acpi_checksum(void *ptr, size_t size);
|
||||
void *acpi_get_rsdp(void);
|
||||
|
||||
void *acpi_get_rsdp_v1(void);
|
||||
void *acpi_get_rsdp_v2(void);
|
||||
|
||||
void *acpi_get_table(const char *signature, int index);
|
||||
void acpi_get_smbios(void **smbios32, void **smbios64);
|
||||
|
||||
|
@ -55,7 +55,8 @@ static size_t get_multiboot2_info_size(
|
||||
ALIGN_UP(strlen(cmdline) + 1 + offsetof(struct multiboot_tag_string, string), MULTIBOOT_TAG_ALIGN) + // cmdline
|
||||
ALIGN_UP(8 + offsetof(struct multiboot_tag_string, string), MULTIBOOT_TAG_ALIGN) + // bootloader brand
|
||||
ALIGN_UP(sizeof(struct multiboot_tag_framebuffer), MULTIBOOT_TAG_ALIGN) + // framebuffer
|
||||
ALIGN_UP(sizeof(struct multiboot_tag_new_acpi) + 36, MULTIBOOT_TAG_ALIGN) + // new ACPI info
|
||||
ALIGN_UP(sizeof(struct multiboot_tag_new_acpi) + sizeof(struct rsdp), MULTIBOOT_TAG_ALIGN) + // new ACPI info
|
||||
ALIGN_UP(sizeof(struct multiboot_tag_old_acpi) + 20, MULTIBOOT_TAG_ALIGN) + // old ACPI info
|
||||
ALIGN_UP(sizeof(struct multiboot_tag_elf_sections) + section_hdr_size, MULTIBOOT_TAG_ALIGN) + // ELF info
|
||||
ALIGN_UP(modules_size, MULTIBOOT_TAG_ALIGN) + // modules
|
||||
ALIGN_UP(sizeof(struct multiboot_tag_mmap) + sizeof(struct multiboot_mmap_entry) * 256, MULTIBOOT_TAG_ALIGN) + // MMAP
|
||||
@ -91,7 +92,10 @@ void multiboot2_load(char *config, char* cmdline) {
|
||||
|
||||
struct multiboot_header_tag_address *addresstag = NULL;
|
||||
struct multiboot_header_tag_framebuffer *fbtag = NULL;
|
||||
|
||||
bool is_new_acpi_required = false;
|
||||
bool is_old_acpi_required = false;
|
||||
|
||||
bool is_elf_info_requested = false;
|
||||
|
||||
uint32_t entry_point = 0xffffffff;
|
||||
@ -129,6 +133,9 @@ void multiboot2_load(char *config, char* cmdline) {
|
||||
case MULTIBOOT_TAG_TYPE_ACPI_NEW:
|
||||
is_new_acpi_required = is_required;
|
||||
break;
|
||||
case MULTIBOOT_TAG_TYPE_ACPI_OLD:
|
||||
is_old_acpi_required = is_required;
|
||||
break;
|
||||
case MULTIBOOT_TAG_TYPE_ELF_SECTIONS:
|
||||
is_elf_info_requested = is_required;
|
||||
break;
|
||||
@ -426,15 +433,35 @@ void multiboot2_load(char *config, char* cmdline) {
|
||||
void *new_rsdp = acpi_get_rsdp();
|
||||
|
||||
if (new_rsdp != NULL) {
|
||||
uint32_t size = sizeof(struct multiboot_tag_new_acpi) + 36; // XSDP is 36 bytes wide
|
||||
uint32_t size = sizeof(struct multiboot_tag_new_acpi) + sizeof(struct rsdp); // XSDP is 36 bytes wide
|
||||
struct multiboot_tag_new_acpi *tag = (struct multiboot_tag_new_acpi *)(mb2_info + info_idx);
|
||||
|
||||
tag->type = MULTIBOOT_TAG_TYPE_ACPI_NEW;
|
||||
tag->size = size;
|
||||
|
||||
memcpy(tag->rsdp, new_rsdp, 36);
|
||||
memcpy(tag->rsdp, new_rsdp, sizeof(struct rsdp));
|
||||
append_tag(info_idx, tag);
|
||||
} else if (is_new_acpi_required) {
|
||||
panic("multiboot2: XSDP requested but not found");
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// Create old ACPI info tag
|
||||
//////////////////////////////////////////////
|
||||
{
|
||||
void *old_rsdp = acpi_get_rsdp_v1();
|
||||
|
||||
if (old_rsdp != NULL) {
|
||||
uint32_t size = sizeof(struct multiboot_tag_old_acpi) + 20; // RSDP is 20 bytes wide
|
||||
struct multiboot_tag_old_acpi *tag = (struct multiboot_tag_old_acpi *)(mb2_info + info_idx);
|
||||
|
||||
tag->type = MULTIBOOT_TAG_TYPE_ACPI_OLD;
|
||||
tag->size = size;
|
||||
|
||||
memcpy(tag->rsdp, old_rsdp, 20);
|
||||
append_tag(info_idx, tag);
|
||||
} else if (is_old_acpi_required) {
|
||||
panic("multiboot2: RSDP requested but not found");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user