mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-23 18:02:05 -05:00
Kernel: ACPI code doesn't rely on identity mapping anymore
The problem was mostly in the initialization code, since in that stage the parser assumed that there is an identity mapping in the first 1MB of the address space. Now during initialization the parser will create the correct mappings to locate the required data.
This commit is contained in:
parent
325022cbd7
commit
60c32f44dd
2 changed files with 45 additions and 24 deletions
|
@ -212,19 +212,21 @@ void ACPIStaticParser::initialize_main_system_description_table()
|
|||
|
||||
void ACPIStaticParser::locate_main_system_description_table()
|
||||
{
|
||||
if (m_rsdp->base.revision == 0) {
|
||||
auto rsdp_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((u32)m_rsdp)), (PAGE_SIZE * 2), "ACPI Static Parser Initialization", Region::Access::Read, false, true);
|
||||
volatile auto* rsdp = (ACPI_RAW::RSDPDescriptor20*)rsdp_region->vaddr().offset(offset_in_page((u32)m_rsdp)).as_ptr();
|
||||
if (rsdp->base.revision == 0) {
|
||||
m_xsdt_supported = false;
|
||||
} else if (m_rsdp->base.revision >= 2) {
|
||||
if (m_rsdp->xsdt_ptr != (u64) nullptr) {
|
||||
} else if (rsdp->base.revision >= 2) {
|
||||
if (rsdp->xsdt_ptr != (u64) nullptr) {
|
||||
m_xsdt_supported = true;
|
||||
} else {
|
||||
m_xsdt_supported = false;
|
||||
}
|
||||
}
|
||||
if (!m_xsdt_supported) {
|
||||
m_main_system_description_table = (ACPI_RAW::SDTHeader*)m_rsdp->base.rsdt_ptr;
|
||||
m_main_system_description_table = (ACPI_RAW::SDTHeader*)rsdp->base.rsdt_ptr;
|
||||
} else {
|
||||
m_main_system_description_table = (ACPI_RAW::SDTHeader*)m_rsdp->xsdt_ptr;
|
||||
m_main_system_description_table = (ACPI_RAW::SDTHeader*)rsdp->xsdt_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,30 +267,47 @@ ACPIStaticParser::ACPIStaticParser()
|
|||
}
|
||||
}
|
||||
|
||||
ACPI_RAW::RSDPDescriptor20* ACPIStaticParser::search_rsdp_in_ebda(u16 ebda_segment)
|
||||
{
|
||||
auto rsdp_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((u32)(ebda_segment << 4))), PAGE_ROUND_UP(1024), "ACPI Static Parser RSDP Finding #1", Region::Access::Read, false, true);
|
||||
char* p_rsdp_str = (char*)(PhysicalAddress(ebda_segment << 4).as_ptr());
|
||||
for (char* rsdp_str = (char*)rsdp_region->vaddr().offset(offset_in_page((u32)(ebda_segment << 4))).as_ptr(); rsdp_str < (char*)(rsdp_region->vaddr().offset(offset_in_page((u32)(ebda_segment << 4))).get() + 1024); rsdp_str += 16) {
|
||||
#ifdef ACPI_DEBUG
|
||||
dbgprintf("ACPI: Looking for RSDP in EBDA @ V0x%x, P0x%x\n", rsdp_str, p_rsdp_str);
|
||||
#endif
|
||||
if (!strncmp("RSD PTR ", rsdp_str, strlen("RSD PTR ")))
|
||||
return (ACPI_RAW::RSDPDescriptor20*)p_rsdp_str;
|
||||
p_rsdp_str += 16;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ACPI_RAW::RSDPDescriptor20* ACPIStaticParser::search_rsdp_in_bios_area()
|
||||
{
|
||||
auto rsdp_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((u32)0xE0000)), PAGE_ROUND_UP(0xFFFFF - 0xE0000), "ACPI Static Parser RSDP Finding #2", Region::Access::Read, false, true);
|
||||
char* p_rsdp_str = (char*)(PhysicalAddress(0xE0000).as_ptr());
|
||||
for (char* rsdp_str = (char*)rsdp_region->vaddr().offset(offset_in_page((u32)(0xE0000))).as_ptr(); rsdp_str < (char*)(rsdp_region->vaddr().offset(offset_in_page((u32)(0xE0000))).get() + (0xFFFFF - 0xE0000)); rsdp_str += 16) {
|
||||
#ifdef ACPI_DEBUG
|
||||
dbgprintf("ACPI: Looking for RSDP in EBDA @ V0x%x, P0x%x\n", rsdp_str, p_rsdp_str);
|
||||
#endif
|
||||
if (!strncmp("RSD PTR ", rsdp_str, strlen("RSD PTR ")))
|
||||
return (ACPI_RAW::RSDPDescriptor20*)p_rsdp_str;
|
||||
p_rsdp_str += 16;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ACPI_RAW::RSDPDescriptor20* ACPIStaticParser::search_rsdp()
|
||||
{
|
||||
auto region = MM.allocate_kernel_region(PhysicalAddress((uintptr_t)0), PAGE_SIZE, "ACPI Static Parser RSDP Finding", Region::Access::Read);
|
||||
ACPI_RAW::RSDPDescriptor20* rsdp = nullptr;
|
||||
auto region = MM.allocate_kernel_region(PhysicalAddress(0), PAGE_SIZE, "ACPI Static Parser RSDP Finding", Region::Access::Read);
|
||||
u16 ebda_seg = (u16) * ((uint16_t*)((region->vaddr().get() & PAGE_MASK) + 0x40e));
|
||||
kprintf("ACPI: Probing EBDA, Segment 0x%x\n", ebda_seg);
|
||||
|
||||
// FIXME: Ensure that we always have identity mapping (identity paging) here! Don't rely on existing mapping...
|
||||
for (char* rsdp_str = (char*)(PhysicalAddress(ebda_seg << 4).as_ptr()); rsdp_str < (char*)((ebda_seg << 4) + 1024); rsdp_str += 16) {
|
||||
#ifdef ACPI_DEBUG
|
||||
dbgprintf("ACPI: Looking for RSDP in EBDA @ Px%x\n", rsdp_str);
|
||||
#endif
|
||||
if (!strncmp("RSD PTR ", rsdp_str, strlen("RSD PTR ")))
|
||||
return (ACPI_RAW::RSDPDescriptor20*)rsdp_str;
|
||||
}
|
||||
|
||||
// FIXME: Ensure that we always have identity mapping (identity paging) here! Don't rely on existing mapping...
|
||||
for (char* rsdp_str = (char*)(PhysicalAddress(0xE0000).as_ptr()); rsdp_str < (char*)0xFFFFF; rsdp_str += 16) {
|
||||
#ifdef ACPI_DEBUG
|
||||
dbgprintf("ACPI: Looking for RSDP in EBDA @ Px%x\n", rsdp_str);
|
||||
#endif
|
||||
if (!strncmp("RSD PTR ", rsdp_str, strlen("RSD PTR ")))
|
||||
return (ACPI_RAW::RSDPDescriptor20*)rsdp_str;
|
||||
}
|
||||
return nullptr;
|
||||
rsdp = search_rsdp_in_ebda(ebda_seg);
|
||||
if (rsdp != nullptr)
|
||||
return rsdp;
|
||||
return search_rsdp_in_bios_area();
|
||||
}
|
||||
|
||||
ACPIStaticParser::ACPIStaticParser(ACPI_RAW::RSDPDescriptor20& rsdp)
|
||||
|
|
|
@ -52,6 +52,8 @@ private:
|
|||
size_t get_table_size(ACPI_RAW::SDTHeader&);
|
||||
u8 get_table_revision(ACPI_RAW::SDTHeader&);
|
||||
void init_fadt();
|
||||
ACPI_RAW::RSDPDescriptor20* search_rsdp_in_ebda(u16 ebda_segment);
|
||||
ACPI_RAW::RSDPDescriptor20* search_rsdp_in_bios_area();
|
||||
ACPI_RAW::RSDPDescriptor20* search_rsdp();
|
||||
|
||||
// Early pointers that are needed really for initializtion only...
|
||||
|
|
Loading…
Add table
Reference in a new issue