mirror of
https://github.com/SerenityOS/serenity.git
synced 2026-11-07 04:29:30 -10:00
This makes it not as easy to forgot to handle OOMs in the kernel. This commit replaces most usages of this function with `try_append(...).release_value_but_fixme_should_propagate_errors()`. But in some cases, using the `TRY` macro or `unchecked_append()` is already possible. In places where allocations should not fail or an OOM would be fatal anyways, `MUST(try_append(...))` should be used explicitly.
64 lines
2.3 KiB
C++
64 lines
2.3 KiB
C++
/*
|
|
* Copyright (c) 2023, Liav A. <[email protected]>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <Kernel/Arch/x86_64/Firmware/ACPI.h>
|
|
#include <Kernel/Arch/x86_64/Firmware/PCBIOS/Mapper.h>
|
|
#include <Kernel/Memory/MemoryManager.h>
|
|
|
|
namespace Kernel::ACPI::StaticParsing {
|
|
|
|
// https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html#finding-the-rsdp-on-ia-pc-systems
|
|
Optional<PhysicalAddress> find_rsdp_in_ia_pc_specific_memory_locations()
|
|
{
|
|
constexpr auto signature = "RSD PTR "sv;
|
|
auto ebda_or_error = map_ebda();
|
|
if (!ebda_or_error.is_error()) {
|
|
auto rsdp = ebda_or_error.value().find_chunk_starting_with(signature, 16);
|
|
if (rsdp.has_value())
|
|
return rsdp;
|
|
}
|
|
auto bios_or_error = map_bios();
|
|
if (!bios_or_error.is_error()) {
|
|
auto rsdp = bios_or_error.value().find_chunk_starting_with(signature, 16);
|
|
if (rsdp.has_value())
|
|
return rsdp;
|
|
}
|
|
|
|
// On some systems the RSDP may be located in ACPI NVS or reclaimable memory regions
|
|
Vector<Memory::PhysicalMemoryRange> potential_ranges;
|
|
MM.for_each_physical_memory_range([&](auto& memory_range) {
|
|
if (!(memory_range.type == Memory::PhysicalMemoryRangeType::ACPI_NVS || memory_range.type == Memory::PhysicalMemoryRangeType::ACPI_Reclaimable))
|
|
return IterationDecision::Continue;
|
|
|
|
potential_ranges.try_append(memory_range).release_value_but_fixme_should_propagate_errors();
|
|
return IterationDecision::Continue;
|
|
});
|
|
|
|
for (auto const& memory_range : potential_ranges) {
|
|
auto region_size_or_error = Memory::page_round_up(memory_range.length);
|
|
if (region_size_or_error.is_error())
|
|
continue;
|
|
|
|
auto region_or_error = MM.allocate_mmio_kernel_region(memory_range.start, region_size_or_error.value(), {}, Memory::Region::Access::Read);
|
|
if (region_or_error.is_error())
|
|
continue;
|
|
|
|
Memory::MappedROM mapping;
|
|
mapping.region = region_or_error.release_value();
|
|
mapping.offset = memory_range.start.offset_in_page();
|
|
mapping.size = memory_range.length;
|
|
mapping.paddr = memory_range.start;
|
|
|
|
auto rsdp = mapping.find_chunk_starting_with(signature, 16);
|
|
if (rsdp.has_value())
|
|
return rsdp;
|
|
}
|
|
|
|
return {};
|
|
}
|
|
|
|
}
|