diff options
author | Idan Horowitz <idan.horowitz@gmail.com> | 2022-01-13 17:38:09 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-01-13 22:40:25 +0100 |
commit | e2e5d4da164aad9b4a77ce5f2c7bfad3dafb9a86 (patch) | |
tree | 2c4327d217882080da6e4a1f605720ba248df14b | |
parent | ae5f5a4d50f2ac4d1f0a6316385275030bdeccec (diff) | |
download | serenity-e2e5d4da164aad9b4a77ce5f2c7bfad3dafb9a86.zip |
Kernel: Make map_bios() and map_ebda() fallible using ErrorOr
-rw-r--r-- | Kernel/Firmware/ACPI/Parser.cpp | 29 | ||||
-rw-r--r-- | Kernel/Firmware/BIOS.cpp | 20 | ||||
-rw-r--r-- | Kernel/Firmware/BIOS.h | 4 | ||||
-rw-r--r-- | Kernel/Firmware/MultiProcessor/Parser.cpp | 16 |
4 files changed, 48 insertions, 21 deletions
diff --git a/Kernel/Firmware/ACPI/Parser.cpp b/Kernel/Firmware/ACPI/Parser.cpp index 6960596075..505a313def 100644 --- a/Kernel/Firmware/ACPI/Parser.cpp +++ b/Kernel/Firmware/ACPI/Parser.cpp @@ -384,21 +384,34 @@ static bool validate_table(const Structures::SDTHeader& v_header, size_t length) // https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#finding-the-rsdp-on-ia-pc-systems UNMAP_AFTER_INIT Optional<PhysicalAddress> StaticParsing::find_rsdp() { - StringView signature("RSD PTR "); - auto rsdp = map_ebda().find_chunk_starting_with(signature, 16); - if (rsdp.has_value()) - return rsdp; - rsdp = map_bios().find_chunk_starting_with(signature, 16); - if (rsdp.has_value()) - return rsdp; + static 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 + Optional<PhysicalAddress> rsdp; 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; Memory::MappedROM mapping; - mapping.region = MM.allocate_kernel_region(memory_range.start, Memory::page_round_up(memory_range.length).release_value_but_fixme_should_propagate_errors(), {}, Memory::Region::Access::Read).release_value(); + auto region_size_or_error = Memory::page_round_up(memory_range.length); + if (region_size_or_error.is_error()) + return IterationDecision::Continue; + auto region_or_error = MM.allocate_kernel_region(memory_range.start, region_size_or_error.value(), {}, Memory::Region::Access::Read); + if (region_or_error.is_error()) + return IterationDecision::Continue; + 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; diff --git a/Kernel/Firmware/BIOS.cpp b/Kernel/Firmware/BIOS.cpp index 65741330c5..4161178fb7 100644 --- a/Kernel/Firmware/BIOS.cpp +++ b/Kernel/Firmware/BIOS.cpp @@ -143,24 +143,31 @@ UNMAP_AFTER_INIT BIOSSysFSDirectory::BIOSSysFSDirectory(FirmwareSysFSDirectory& UNMAP_AFTER_INIT Optional<PhysicalAddress> BIOSSysFSDirectory::find_dmi_entry64bit_point() { - return map_bios().find_chunk_starting_with("_SM3_", 16); + auto bios_or_error = map_bios(); + if (bios_or_error.is_error()) + return {}; + return bios_or_error.value().find_chunk_starting_with("_SM3_", 16); } UNMAP_AFTER_INIT Optional<PhysicalAddress> BIOSSysFSDirectory::find_dmi_entry32bit_point() { - return map_bios().find_chunk_starting_with("_SM_", 16); + auto bios_or_error = map_bios(); + if (bios_or_error.is_error()) + return {}; + return bios_or_error.value().find_chunk_starting_with("_SM_", 16); } -Memory::MappedROM map_bios() +ErrorOr<Memory::MappedROM> map_bios() { Memory::MappedROM mapping; mapping.size = 128 * KiB; mapping.paddr = PhysicalAddress(0xe0000); - mapping.region = MM.allocate_kernel_region(mapping.paddr, Memory::page_round_up(mapping.size).release_value_but_fixme_should_propagate_errors(), {}, Memory::Region::Access::Read).release_value(); + auto region_size = TRY(Memory::page_round_up(mapping.size)); + mapping.region = TRY(MM.allocate_kernel_region(mapping.paddr, region_size, {}, Memory::Region::Access::Read)); return mapping; } -Memory::MappedROM map_ebda() +ErrorOr<Memory::MappedROM> map_ebda() { auto ebda_segment_ptr = Memory::map_typed<u16>(PhysicalAddress(0x40e)); PhysicalAddress ebda_paddr(PhysicalAddress(*ebda_segment_ptr).get() << 4); @@ -169,7 +176,8 @@ Memory::MappedROM map_ebda() ebda_size *= 1024; Memory::MappedROM mapping; - mapping.region = MM.allocate_kernel_region(ebda_paddr.page_base(), Memory::page_round_up(ebda_size).release_value_but_fixme_should_propagate_errors(), {}, Memory::Region::Access::Read).release_value(); + auto region_size = TRY(Memory::page_round_up(ebda_size)); + mapping.region = TRY(MM.allocate_kernel_region(ebda_paddr.page_base(), region_size, {}, Memory::Region::Access::Read)); mapping.offset = ebda_paddr.offset_in_page(); mapping.size = ebda_size; mapping.paddr = ebda_paddr; diff --git a/Kernel/Firmware/BIOS.h b/Kernel/Firmware/BIOS.h index 297f590215..982d290cd3 100644 --- a/Kernel/Firmware/BIOS.h +++ b/Kernel/Firmware/BIOS.h @@ -57,8 +57,8 @@ struct [[gnu::packed]] EntryPoint64bit { namespace Kernel { -Memory::MappedROM map_bios(); -Memory::MappedROM map_ebda(); +ErrorOr<Memory::MappedROM> map_bios(); +ErrorOr<Memory::MappedROM> map_ebda(); class BIOSSysFSComponent : public SysFSComponent { public: diff --git a/Kernel/Firmware/MultiProcessor/Parser.cpp b/Kernel/Firmware/MultiProcessor/Parser.cpp index 8cca971e3f..becba9e13b 100644 --- a/Kernel/Firmware/MultiProcessor/Parser.cpp +++ b/Kernel/Firmware/MultiProcessor/Parser.cpp @@ -86,11 +86,17 @@ UNMAP_AFTER_INIT void MultiProcessorParser::parse_configuration_table() UNMAP_AFTER_INIT Optional<PhysicalAddress> MultiProcessorParser::find_floating_pointer() { - StringView signature("_MP_"); - auto mp_floating_pointer = map_ebda().find_chunk_starting_with(signature, 16); - if (mp_floating_pointer.has_value()) - return mp_floating_pointer; - return map_bios().find_chunk_starting_with(signature, 16); + static constexpr auto signature = "_MP_"sv; + auto ebda_or_error = map_ebda(); + if (!ebda_or_error.is_error()) { + auto mp_floating_pointer = ebda_or_error.value().find_chunk_starting_with(signature, 16); + if (mp_floating_pointer.has_value()) + return mp_floating_pointer; + } + auto bios_or_error = map_bios(); + if (bios_or_error.is_error()) + return {}; + return bios_or_error.value().find_chunk_starting_with(signature, 16); } UNMAP_AFTER_INIT Vector<u8> MultiProcessorParser::get_pci_bus_ids() const |