Kernel: Don't map main bios area in page table initialization

This is only needed for RSDP lookup so it can be done with fast pages
This commit is contained in:
Bananymous 2024-10-14 11:31:40 +03:00
parent 55fbd09e45
commit 3edc1af560
3 changed files with 32 additions and 31 deletions

View File

@ -150,14 +150,6 @@ namespace Kernel
prepare_fast_page(); prepare_fast_page();
// Map main bios area below 1 MiB
map_range_at(
0x000E0000,
P2V(0x000E0000),
0x00100000 - 0x000E0000,
PageTable::Flags::Present
);
// Map (phys_kernel_start -> phys_kernel_end) to (virt_kernel_start -> virt_kernel_end) // Map (phys_kernel_start -> phys_kernel_end) to (virt_kernel_start -> virt_kernel_end)
ASSERT((vaddr_t)g_kernel_start % PAGE_SIZE == 0); ASSERT((vaddr_t)g_kernel_start % PAGE_SIZE == 0);
map_range_at( map_range_at(

View File

@ -168,14 +168,6 @@ namespace Kernel
prepare_fast_page(); prepare_fast_page();
// Map main bios area below 1 MiB
map_range_at(
0x000E0000,
P2V(0x000E0000),
0x00100000 - 0x000E0000,
PageTable::Flags::Present
);
// Map (phys_kernel_start -> phys_kernel_end) to (virt_kernel_start -> virt_kernel_end) // Map (phys_kernel_start -> phys_kernel_end) to (virt_kernel_start -> virt_kernel_end)
ASSERT((vaddr_t)g_kernel_start % PAGE_SIZE == 0); ASSERT((vaddr_t)g_kernel_start % PAGE_SIZE == 0);
map_range_at( map_range_at(

View File

@ -281,16 +281,32 @@ acpi_release_global_lock:
return true; return true;
} }
static const RSDP* locate_rsdp() static BAN::Optional<RSDP> locate_rsdp()
{ {
if (g_boot_info.rsdp.length) if (g_boot_info.rsdp.length)
return &g_boot_info.rsdp; return g_boot_info.rsdp;
// Look in main BIOS area below 1 MB // Look in main BIOS area below 1 MB
for (vaddr_t addr = 0x000E0000 + KERNEL_OFFSET; addr < 0x000FFFFF + KERNEL_OFFSET; addr += 16) for (paddr_t paddr = 0x000E0000; paddr < 0x00100000; paddr += PAGE_SIZE)
if (is_rsdp(addr)) {
return reinterpret_cast<const RSDP*>(addr); BAN::Optional<RSDP> rsdp;
return nullptr;
PageTable::with_fast_page(paddr, [&rsdp] {
for (size_t offset = 0; offset + sizeof(RSDP) <= PAGE_SIZE; offset += 16)
{
if (is_rsdp(PageTable::fast_page() + offset))
{
rsdp = PageTable::fast_page_as<RSDP>(offset);
break;
}
}
});
if (rsdp.has_value())
return rsdp.release_value();
}
return {};
} }
static bool is_valid_std_header(const SDTHeader* header) static bool is_valid_std_header(const SDTHeader* header)
@ -303,24 +319,25 @@ acpi_release_global_lock:
BAN::ErrorOr<void> ACPI::initialize_impl() BAN::ErrorOr<void> ACPI::initialize_impl()
{ {
const RSDP* rsdp = locate_rsdp(); auto opt_rsdp = locate_rsdp();
if (rsdp == nullptr) if (!opt_rsdp.has_value())
return BAN::Error::from_error_code(ErrorCode::ACPI_NoRootSDT); return BAN::Error::from_error_code(ErrorCode::ACPI_NoRootSDT);
const RSDP rsdp = opt_rsdp.release_value();
uint32_t root_entry_count = 0; uint32_t root_entry_count = 0;
if (rsdp->revision >= 2) if (rsdp.revision >= 2)
{ {
TRY(PageTable::with_fast_page(rsdp->xsdt_address & PAGE_ADDR_MASK, TRY(PageTable::with_fast_page(rsdp.xsdt_address & PAGE_ADDR_MASK,
[&]() -> BAN::ErrorOr<void> [&]() -> BAN::ErrorOr<void>
{ {
auto& xsdt = PageTable::fast_page_as<const XSDT>(rsdp->xsdt_address % PAGE_SIZE); auto& xsdt = PageTable::fast_page_as<const XSDT>(rsdp.xsdt_address % PAGE_SIZE);
if (memcmp(xsdt.signature, "XSDT", 4) != 0) if (memcmp(xsdt.signature, "XSDT", 4) != 0)
return BAN::Error::from_error_code(ErrorCode::ACPI_RootInvalid); return BAN::Error::from_error_code(ErrorCode::ACPI_RootInvalid);
if (!is_valid_std_header(&xsdt)) if (!is_valid_std_header(&xsdt))
return BAN::Error::from_error_code(ErrorCode::ACPI_RootInvalid); return BAN::Error::from_error_code(ErrorCode::ACPI_RootInvalid);
m_header_table_paddr = rsdp->xsdt_address + offsetof(XSDT, entries); m_header_table_paddr = rsdp.xsdt_address + offsetof(XSDT, entries);
m_entry_size = 8; m_entry_size = 8;
root_entry_count = (xsdt.length - sizeof(SDTHeader)) / 8; root_entry_count = (xsdt.length - sizeof(SDTHeader)) / 8;
return {}; return {};
@ -329,16 +346,16 @@ acpi_release_global_lock:
} }
else else
{ {
TRY(PageTable::with_fast_page(rsdp->rsdt_address & PAGE_ADDR_MASK, TRY(PageTable::with_fast_page(rsdp.rsdt_address & PAGE_ADDR_MASK,
[&]() -> BAN::ErrorOr<void> [&]() -> BAN::ErrorOr<void>
{ {
auto& rsdt = PageTable::fast_page_as<const RSDT>(rsdp->rsdt_address % PAGE_SIZE); auto& rsdt = PageTable::fast_page_as<const RSDT>(rsdp.rsdt_address % PAGE_SIZE);
if (memcmp(rsdt.signature, "RSDT", 4) != 0) if (memcmp(rsdt.signature, "RSDT", 4) != 0)
return BAN::Error::from_error_code(ErrorCode::ACPI_RootInvalid); return BAN::Error::from_error_code(ErrorCode::ACPI_RootInvalid);
if (!is_valid_std_header(&rsdt)) if (!is_valid_std_header(&rsdt))
return BAN::Error::from_error_code(ErrorCode::ACPI_RootInvalid); return BAN::Error::from_error_code(ErrorCode::ACPI_RootInvalid);
m_header_table_paddr = rsdp->rsdt_address + offsetof(RSDT, entries); m_header_table_paddr = rsdp.rsdt_address + offsetof(RSDT, entries);
m_entry_size = 4; m_entry_size = 4;
root_entry_count = (rsdt.length - sizeof(SDTHeader)) / 4; root_entry_count = (rsdt.length - sizeof(SDTHeader)) / 4;
return {}; return {};