summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIdan Horowitz <idan.horowitz@gmail.com>2022-01-13 18:20:22 +0200
committerAndreas Kling <kling@serenityos.org>2022-01-13 22:40:25 +0100
commitfb3e46e930aaf03fa1caec0cdf18ba48b12e1b0e (patch)
tree5bb7c83a09bedcdb2d5431837bcedb61799d7de8
parente2e5d4da164aad9b4a77ce5f2c7bfad3dafb9a86 (diff)
downloadserenity-fb3e46e930aaf03fa1caec0cdf18ba48b12e1b0e.zip
Kernel: Make map_typed() & map_typed_writable() fallible using ErrorOr
This mostly just moved the problem, as a lot of the callers are not capable of propagating the errors themselves, but it's a step in the right direction.
-rw-r--r--Kernel/Bus/PCI/Access.cpp7
-rw-r--r--Kernel/Devices/MemoryDevice.cpp2
-rw-r--r--Kernel/Firmware/ACPI/Initialize.cpp6
-rw-r--r--Kernel/Firmware/ACPI/Parser.cpp48
-rw-r--r--Kernel/Firmware/BIOS.cpp12
-rw-r--r--Kernel/Firmware/MultiProcessor/Parser.cpp6
-rw-r--r--Kernel/Graphics/Bochs/GraphicsAdapter.cpp2
-rw-r--r--Kernel/Interrupts/APIC.cpp7
-rw-r--r--Kernel/Interrupts/IOAPIC.cpp2
-rw-r--r--Kernel/Interrupts/InterruptManagement.cpp2
-rw-r--r--Kernel/Memory/TypedMapping.h13
-rw-r--r--Kernel/Storage/ATA/AHCIPort.cpp2
-rw-r--r--Kernel/Storage/NVMe/NVMeController.cpp6
-rw-r--r--Kernel/Time/HPET.cpp22
14 files changed, 80 insertions, 57 deletions
diff --git a/Kernel/Bus/PCI/Access.cpp b/Kernel/Bus/PCI/Access.cpp
index 0959bed47d..d7a837b66a 100644
--- a/Kernel/Bus/PCI/Access.cpp
+++ b/Kernel/Bus/PCI/Access.cpp
@@ -42,7 +42,12 @@ UNMAP_AFTER_INIT bool Access::find_and_register_pci_host_bridges_from_acpi_mcfg_
u32 length = 0;
u8 revision = 0;
{
- auto mapped_mcfg_table = Memory::map_typed<ACPI::Structures::SDTHeader>(mcfg_table);
+ auto mapped_mcfg_table_or_error = Memory::map_typed<ACPI::Structures::SDTHeader>(mcfg_table);
+ if (mapped_mcfg_table_or_error.is_error()) {
+ dbgln("Failed to map MCFG table");
+ return false;
+ }
+ auto mapped_mcfg_table = mapped_mcfg_table_or_error.release_value();
length = mapped_mcfg_table->length;
revision = mapped_mcfg_table->revision;
}
diff --git a/Kernel/Devices/MemoryDevice.cpp b/Kernel/Devices/MemoryDevice.cpp
index 30367eed6a..6396f07b5d 100644
--- a/Kernel/Devices/MemoryDevice.cpp
+++ b/Kernel/Devices/MemoryDevice.cpp
@@ -38,7 +38,7 @@ ErrorOr<size_t> MemoryDevice::read(OpenFileDescription&, u64 offset, UserOrKerne
dbgln("MemoryDevice: Trying to read physical memory at {} for range of {} bytes failed due to violation of access", PhysicalAddress(offset), length);
return EINVAL;
}
- auto mapping = Memory::map_typed<u8>(PhysicalAddress(offset), length);
+ auto mapping = TRY(Memory::map_typed<u8>(PhysicalAddress(offset), length));
auto bytes = ReadonlyBytes { mapping.ptr(), length };
TRY(buffer.write(bytes));
diff --git a/Kernel/Firmware/ACPI/Initialize.cpp b/Kernel/Firmware/ACPI/Initialize.cpp
index 07ae24e4bb..890bed30f6 100644
--- a/Kernel/Firmware/ACPI/Initialize.cpp
+++ b/Kernel/Firmware/ACPI/Initialize.cpp
@@ -25,8 +25,10 @@ UNMAP_AFTER_INIT void initialize()
auto facp = StaticParsing::find_table(rsdp.value(), "FACP");
if (!facp.has_value())
return;
- auto facp_table = Memory::map_typed<Structures::FADT>(facp.value());
- u8 irq_line = facp_table->sci_int;
+ auto facp_table_or_error = Memory::map_typed<Structures::FADT>(facp.value());
+ if (facp_table_or_error.is_error())
+ return;
+ u8 irq_line = facp_table_or_error.value()->sci_int;
Parser::must_initialize(rsdp.value(), facp.value(), irq_line);
if (kernel_command_line().acpi_feature_level() == AcpiFeatureLevel::Enabled)
diff --git a/Kernel/Firmware/ACPI/Parser.cpp b/Kernel/Firmware/ACPI/Parser.cpp
index 505a313def..aed9950dc3 100644
--- a/Kernel/Firmware/ACPI/Parser.cpp
+++ b/Kernel/Firmware/ACPI/Parser.cpp
@@ -55,7 +55,7 @@ ErrorOr<size_t> ACPISysFSComponent::read_bytes(off_t offset, size_t count, UserO
ErrorOr<NonnullOwnPtr<KBuffer>> ACPISysFSComponent::try_to_generate_buffer() const
{
- auto acpi_blob = Memory::map_typed<u8>((m_paddr), m_length);
+ auto acpi_blob = TRY(Memory::map_typed<u8>((m_paddr), m_length));
return KBuffer::try_create_with_bytes(Span<u8> { acpi_blob.ptr(), m_length });
}
@@ -81,10 +81,10 @@ UNMAP_AFTER_INIT void ACPISysFSDirectory::find_tables_and_register_them_as_compo
});
m_components = components;
- auto rsdp = Memory::map_typed<Structures::RSDPDescriptor20>(ACPI::Parser::the()->rsdp());
+ auto rsdp = Memory::map_typed<Structures::RSDPDescriptor20>(ACPI::Parser::the()->rsdp()).release_value_but_fixme_should_propagate_errors();
m_components.append(ACPISysFSComponent::create("RSDP", ACPI::Parser::the()->rsdp(), rsdp->base.revision == 0 ? sizeof(Structures::RSDPDescriptor) : rsdp->length));
- auto main_system_description_table = Memory::map_typed<Structures::SDTHeader>(ACPI::Parser::the()->main_system_description_table());
+ auto main_system_description_table = Memory::map_typed<Structures::SDTHeader>(ACPI::Parser::the()->main_system_description_table()).release_value_but_fixme_should_propagate_errors();
if (ACPI::Parser::the()->is_xsdt_supported()) {
m_components.append(ACPISysFSComponent::create("XSDT", ACPI::Parser::the()->main_system_description_table(), main_system_description_table->length));
} else {
@@ -107,7 +107,7 @@ UNMAP_AFTER_INIT ACPISysFSDirectory::ACPISysFSDirectory(FirmwareSysFSDirectory&
void Parser::enumerate_static_tables(Function<void(StringView, PhysicalAddress, size_t)> callback)
{
for (auto& p_table : m_sdt_pointers) {
- auto table = Memory::map_typed<Structures::SDTHeader>(p_table);
+ auto table = Memory::map_typed<Structures::SDTHeader>(p_table).release_value_but_fixme_should_propagate_errors();
callback({ table->sig, 4 }, p_table, table->length);
}
}
@@ -128,9 +128,13 @@ UNMAP_AFTER_INIT Optional<PhysicalAddress> Parser::find_table(StringView signatu
{
dbgln_if(ACPI_DEBUG, "ACPI: Calling Find Table method!");
for (auto p_sdt : m_sdt_pointers) {
- auto sdt = Memory::map_typed<Structures::SDTHeader>(p_sdt);
+ auto sdt_or_error = Memory::map_typed<Structures::SDTHeader>(p_sdt);
+ if (sdt_or_error.is_error()) {
+ dbgln_if(ACPI_DEBUG, "ACPI: Failed mapping Table @ {}", p_sdt);
+ continue;
+ }
dbgln_if(ACPI_DEBUG, "ACPI: Examining Table @ {}", p_sdt);
- if (!strncmp(sdt->sig, signature.characters_without_null_termination(), 4)) {
+ if (!strncmp(sdt_or_error.value()->sig, signature.characters_without_null_termination(), 4)) {
dbgln_if(ACPI_DEBUG, "ACPI: Found Table @ {}", p_sdt);
return p_sdt;
}
@@ -156,7 +160,7 @@ UNMAP_AFTER_INIT void Parser::process_fadt_data()
VERIFY(!m_fadt.is_null());
dbgln_if(ACPI_DEBUG, "ACPI: FADT @ {}", m_fadt);
- auto sdt = Memory::map_typed<Structures::FADT>(m_fadt);
+ auto sdt = Memory::map_typed<Structures::FADT>(m_fadt).release_value_but_fixme_should_propagate_errors();
dmesgln("ACPI: Fixed ACPI data, Revision {}, length: {} bytes", (size_t)sdt->h.revision, (size_t)sdt->h.length);
dmesgln("ACPI: DSDT {}", PhysicalAddress(sdt->dsdt_ptr));
m_x86_specific_flags.cmos_rtc_not_present = (sdt->ia_pc_boot_arch_flags & (u8)FADTFlags::IA_PC_Flags::CMOS_RTC_Not_Present);
@@ -195,7 +199,7 @@ UNMAP_AFTER_INIT void Parser::process_fadt_data()
bool Parser::can_reboot()
{
- auto fadt = Memory::map_typed<Structures::FADT>(m_fadt);
+ auto fadt = Memory::map_typed<Structures::FADT>(m_fadt).release_value_but_fixme_should_propagate_errors();
if (fadt->h.revision < 2)
return false;
return m_hardware_flags.reset_register_supported;
@@ -231,16 +235,16 @@ void Parser::access_generic_address(const Structures::GenericAddressStructure& s
dbgln("ACPI: Sending value {:x} to {}", value, PhysicalAddress(structure.address));
switch ((GenericAddressStructure::AccessSize)structure.access_size) {
case GenericAddressStructure::AccessSize::Byte:
- *Memory::map_typed<u8>(PhysicalAddress(structure.address)) = value;
+ *Memory::map_typed<u8>(PhysicalAddress(structure.address)).release_value_but_fixme_should_propagate_errors() = value;
break;
case GenericAddressStructure::AccessSize::Word:
- *Memory::map_typed<u16>(PhysicalAddress(structure.address)) = value;
+ *Memory::map_typed<u16>(PhysicalAddress(structure.address)).release_value_but_fixme_should_propagate_errors() = value;
break;
case GenericAddressStructure::AccessSize::DWord:
- *Memory::map_typed<u32>(PhysicalAddress(structure.address)) = value;
+ *Memory::map_typed<u32>(PhysicalAddress(structure.address)).release_value_but_fixme_should_propagate_errors() = value;
break;
case GenericAddressStructure::AccessSize::QWord: {
- *Memory::map_typed<u64>(PhysicalAddress(structure.address)) = value;
+ *Memory::map_typed<u64>(PhysicalAddress(structure.address)).release_value_but_fixme_should_propagate_errors() = value;
break;
}
default:
@@ -272,7 +276,7 @@ bool Parser::validate_reset_register()
{
// According to https://uefi.org/specs/ACPI/6.4/04_ACPI_Hardware_Specification/ACPI_Hardware_Specification.html#reset-register,
// the reset register can only be located in I/O bus, PCI bus or memory-mapped.
- auto fadt = Memory::map_typed<Structures::FADT>(m_fadt);
+ auto fadt = Memory::map_typed<Structures::FADT>(m_fadt).release_value_but_fixme_should_propagate_errors();
return (fadt->reset_reg.address_space == (u8)GenericAddressStructure::AddressSpace::PCIConfigurationSpace || fadt->reset_reg.address_space == (u8)GenericAddressStructure::AddressSpace::SystemMemory || fadt->reset_reg.address_space == (u8)GenericAddressStructure::AddressSpace::SystemIO);
}
@@ -285,7 +289,7 @@ void Parser::try_acpi_reboot()
}
dbgln_if(ACPI_DEBUG, "ACPI: Rebooting, probing FADT ({})", m_fadt);
- auto fadt = Memory::map_typed<Structures::FADT>(m_fadt);
+ auto fadt = Memory::map_typed<Structures::FADT>(m_fadt).release_value_but_fixme_should_propagate_errors();
VERIFY(validate_reset_register());
access_generic_address(fadt->reset_reg, fadt->reset_value);
Processor::halt();
@@ -300,14 +304,14 @@ size_t Parser::get_table_size(PhysicalAddress table_header)
{
InterruptDisabler disabler;
dbgln_if(ACPI_DEBUG, "ACPI: Checking SDT Length");
- return Memory::map_typed<Structures::SDTHeader>(table_header)->length;
+ return Memory::map_typed<Structures::SDTHeader>(table_header).release_value_but_fixme_should_propagate_errors()->length;
}
u8 Parser::get_table_revision(PhysicalAddress table_header)
{
InterruptDisabler disabler;
dbgln_if(ACPI_DEBUG, "ACPI: Checking SDT Revision");
- return Memory::map_typed<Structures::SDTHeader>(table_header)->revision;
+ return Memory::map_typed<Structures::SDTHeader>(table_header).release_value_but_fixme_should_propagate_errors()->revision;
}
UNMAP_AFTER_INIT void Parser::initialize_main_system_description_table()
@@ -317,7 +321,7 @@ UNMAP_AFTER_INIT void Parser::initialize_main_system_description_table()
auto length = get_table_size(m_main_system_description_table);
auto revision = get_table_revision(m_main_system_description_table);
- auto sdt = Memory::map_typed<Structures::SDTHeader>(m_main_system_description_table, length);
+ auto sdt = Memory::map_typed<Structures::SDTHeader>(m_main_system_description_table, length).release_value_but_fixme_should_propagate_errors();
dmesgln("ACPI: Main Description Table valid? {}", validate_table(*sdt, length));
@@ -344,7 +348,7 @@ UNMAP_AFTER_INIT void Parser::initialize_main_system_description_table()
UNMAP_AFTER_INIT void Parser::locate_main_system_description_table()
{
- auto rsdp = Memory::map_typed<Structures::RSDPDescriptor20>(m_rsdp);
+ auto rsdp = Memory::map_typed<Structures::RSDPDescriptor20>(m_rsdp).release_value_but_fixme_should_propagate_errors();
if (rsdp->base.revision == 0) {
m_xsdt_supported = false;
} else if (rsdp->base.revision >= 2) {
@@ -430,7 +434,7 @@ UNMAP_AFTER_INIT Optional<PhysicalAddress> StaticParsing::find_table(PhysicalAdd
// FIXME: There's no validation of ACPI tables here. Use the checksum to validate the tables.
VERIFY(signature.length() == 4);
- auto rsdp = Memory::map_typed<Structures::RSDPDescriptor20>(rsdp_address);
+ auto rsdp = Memory::map_typed<Structures::RSDPDescriptor20>(rsdp_address).release_value_but_fixme_should_propagate_errors();
if (rsdp->base.revision == 0)
return search_table_in_rsdt(PhysicalAddress(rsdp->base.rsdt_ptr), signature);
@@ -448,7 +452,7 @@ UNMAP_AFTER_INIT static Optional<PhysicalAddress> search_table_in_xsdt(PhysicalA
// FIXME: There's no validation of ACPI tables here. Use the checksum to validate the tables.
VERIFY(signature.length() == 4);
- auto xsdt = Memory::map_typed<Structures::XSDT>(xsdt_address);
+ auto xsdt = Memory::map_typed<Structures::XSDT>(xsdt_address).release_value_but_fixme_should_propagate_errors();
for (size_t i = 0; i < ((xsdt->h.length - sizeof(Structures::SDTHeader)) / sizeof(u64)); ++i) {
if (match_table_signature(PhysicalAddress((PhysicalPtr)xsdt->table_ptrs[i]), signature))
@@ -462,7 +466,7 @@ static bool match_table_signature(PhysicalAddress table_header, StringView signa
// FIXME: There's no validation of ACPI tables here. Use the checksum to validate the tables.
VERIFY(signature.length() == 4);
- auto table = Memory::map_typed<Structures::RSDT>(table_header);
+ auto table = Memory::map_typed<Structures::RSDT>(table_header).release_value_but_fixme_should_propagate_errors();
return !strncmp(table->h.sig, signature.characters_without_null_termination(), 4);
}
@@ -471,7 +475,7 @@ UNMAP_AFTER_INIT static Optional<PhysicalAddress> search_table_in_rsdt(PhysicalA
// FIXME: There's no validation of ACPI tables here. Use the checksum to validate the tables.
VERIFY(signature.length() == 4);
- auto rsdt = Memory::map_typed<Structures::RSDT>(rsdt_address);
+ auto rsdt = Memory::map_typed<Structures::RSDT>(rsdt_address).release_value_but_fixme_should_propagate_errors();
for (u32 i = 0; i < ((rsdt->h.length - sizeof(Structures::SDTHeader)) / sizeof(u32)); i++) {
if (match_table_signature(PhysicalAddress((PhysicalPtr)rsdt->table_ptrs[i]), signature))
diff --git a/Kernel/Firmware/BIOS.cpp b/Kernel/Firmware/BIOS.cpp
index 4161178fb7..e63b8b4c5c 100644
--- a/Kernel/Firmware/BIOS.cpp
+++ b/Kernel/Firmware/BIOS.cpp
@@ -49,7 +49,7 @@ UNMAP_AFTER_INIT DMIEntryPointExposedBlob::DMIEntryPointExposedBlob(PhysicalAddr
ErrorOr<NonnullOwnPtr<KBuffer>> DMIEntryPointExposedBlob::try_to_generate_buffer() const
{
- auto dmi_blob = Memory::map_typed<u8>((m_dmi_entry_point), m_dmi_entry_point_length);
+ auto dmi_blob = TRY(Memory::map_typed<u8>((m_dmi_entry_point), m_dmi_entry_point_length));
return KBuffer::try_create_with_bytes(Span<u8> { dmi_blob.ptr(), m_dmi_entry_point_length });
}
@@ -67,14 +67,14 @@ UNMAP_AFTER_INIT SMBIOSExposedTable::SMBIOSExposedTable(PhysicalAddress smbios_s
ErrorOr<NonnullOwnPtr<KBuffer>> SMBIOSExposedTable::try_to_generate_buffer() const
{
- auto dmi_blob = Memory::map_typed<u8>((m_smbios_structure_table), m_smbios_structure_table_length);
+ auto dmi_blob = TRY(Memory::map_typed<u8>((m_smbios_structure_table), m_smbios_structure_table_length));
return KBuffer::try_create_with_bytes(Span<u8> { dmi_blob.ptr(), m_smbios_structure_table_length });
}
UNMAP_AFTER_INIT void BIOSSysFSDirectory::set_dmi_64_bit_entry_initialization_values()
{
dbgln("BIOSSysFSDirectory: SMBIOS 64bit Entry point @ {}", m_dmi_entry_point);
- auto smbios_entry = Memory::map_typed<SMBIOS::EntryPoint64bit>(m_dmi_entry_point, SMBIOS_SEARCH_AREA_SIZE);
+ auto smbios_entry = Memory::map_typed<SMBIOS::EntryPoint64bit>(m_dmi_entry_point, SMBIOS_SEARCH_AREA_SIZE).release_value_but_fixme_should_propagate_errors();
m_smbios_structure_table = PhysicalAddress(smbios_entry.ptr()->table_ptr);
m_dmi_entry_point_length = smbios_entry.ptr()->length;
m_smbios_structure_table_length = smbios_entry.ptr()->table_maximum_size;
@@ -83,7 +83,7 @@ UNMAP_AFTER_INIT void BIOSSysFSDirectory::set_dmi_64_bit_entry_initialization_va
UNMAP_AFTER_INIT void BIOSSysFSDirectory::set_dmi_32_bit_entry_initialization_values()
{
dbgln("BIOSSysFSDirectory: SMBIOS 32bit Entry point @ {}", m_dmi_entry_point);
- auto smbios_entry = Memory::map_typed<SMBIOS::EntryPoint32bit>(m_dmi_entry_point, SMBIOS_SEARCH_AREA_SIZE);
+ auto smbios_entry = Memory::map_typed<SMBIOS::EntryPoint32bit>(m_dmi_entry_point, SMBIOS_SEARCH_AREA_SIZE).release_value_but_fixme_should_propagate_errors();
m_smbios_structure_table = PhysicalAddress(smbios_entry.ptr()->legacy_structure.smbios_table_ptr);
m_dmi_entry_point_length = smbios_entry.ptr()->length;
m_smbios_structure_table_length = smbios_entry.ptr()->legacy_structure.smbios_table_length;
@@ -169,10 +169,10 @@ ErrorOr<Memory::MappedROM> map_bios()
ErrorOr<Memory::MappedROM> map_ebda()
{
- auto ebda_segment_ptr = Memory::map_typed<u16>(PhysicalAddress(0x40e));
+ auto ebda_segment_ptr = TRY(Memory::map_typed<u16>(PhysicalAddress(0x40e)));
PhysicalAddress ebda_paddr(PhysicalAddress(*ebda_segment_ptr).get() << 4);
// The EBDA size is stored in the first byte of the EBDA in 1K units
- size_t ebda_size = *Memory::map_typed<u8>(ebda_paddr);
+ size_t ebda_size = *TRY(Memory::map_typed<u8>(ebda_paddr));
ebda_size *= 1024;
Memory::MappedROM mapping;
diff --git a/Kernel/Firmware/MultiProcessor/Parser.cpp b/Kernel/Firmware/MultiProcessor/Parser.cpp
index becba9e13b..c0dc1a7d80 100644
--- a/Kernel/Firmware/MultiProcessor/Parser.cpp
+++ b/Kernel/Firmware/MultiProcessor/Parser.cpp
@@ -36,15 +36,15 @@ UNMAP_AFTER_INIT MultiProcessorParser::MultiProcessorParser(PhysicalAddress floa
UNMAP_AFTER_INIT void MultiProcessorParser::parse_floating_pointer_data()
{
- auto floating_pointer = Memory::map_typed<MultiProcessor::FloatingPointer>(m_floating_pointer);
+ auto floating_pointer = Memory::map_typed<MultiProcessor::FloatingPointer>(m_floating_pointer).release_value_but_fixme_should_propagate_errors();
m_configuration_table = PhysicalAddress(floating_pointer->physical_address_ptr);
dbgln("Features {}, IMCR? {}", floating_pointer->feature_info[0], (floating_pointer->feature_info[0] & (1 << 7)));
}
UNMAP_AFTER_INIT void MultiProcessorParser::parse_configuration_table()
{
- auto configuration_table_length = Memory::map_typed<MultiProcessor::ConfigurationTableHeader>(m_configuration_table)->length;
- auto config_table = Memory::map_typed<MultiProcessor::ConfigurationTableHeader>(m_configuration_table, configuration_table_length);
+ auto configuration_table_length = Memory::map_typed<MultiProcessor::ConfigurationTableHeader>(m_configuration_table).release_value_but_fixme_should_propagate_errors()->length;
+ auto config_table = Memory::map_typed<MultiProcessor::ConfigurationTableHeader>(m_configuration_table, configuration_table_length).release_value_but_fixme_should_propagate_errors();
size_t entry_count = config_table->entry_count;
auto* entry = config_table->entries;
diff --git a/Kernel/Graphics/Bochs/GraphicsAdapter.cpp b/Kernel/Graphics/Bochs/GraphicsAdapter.cpp
index f781024111..732445e22b 100644
--- a/Kernel/Graphics/Bochs/GraphicsAdapter.cpp
+++ b/Kernel/Graphics/Bochs/GraphicsAdapter.cpp
@@ -103,7 +103,7 @@ void BochsGraphicsAdapter::set_framebuffer_to_little_endian_format()
UNMAP_AFTER_INIT BochsGraphicsAdapter::BochsGraphicsAdapter(PCI::DeviceIdentifier const& pci_device_identifier)
: PCI::Device(pci_device_identifier.address())
, m_mmio_registers(PCI::get_BAR2(pci_device_identifier.address()) & 0xfffffff0)
- , m_registers(Memory::map_typed_writable<BochsDisplayMMIORegisters volatile>(m_mmio_registers))
+ , m_registers(Memory::map_typed_writable<BochsDisplayMMIORegisters volatile>(m_mmio_registers).release_value_but_fixme_should_propagate_errors())
{
// We assume safe resolution is 1024x768x32
m_framebuffer_console = Graphics::ContiguousFramebufferConsole::initialize(PhysicalAddress(PCI::get_BAR0(pci_device_identifier.address()) & 0xfffffff0), 1024, 768, 1024 * sizeof(u32));
diff --git a/Kernel/Interrupts/APIC.cpp b/Kernel/Interrupts/APIC.cpp
index 83a21e1055..ddae5cbbc5 100644
--- a/Kernel/Interrupts/APIC.cpp
+++ b/Kernel/Interrupts/APIC.cpp
@@ -271,7 +271,12 @@ UNMAP_AFTER_INIT bool APIC::init_bsp()
}
if (kernel_command_line().is_smp_enabled()) {
- auto madt = Memory::map_typed<ACPI::Structures::MADT>(madt_address.value());
+ auto madt_or_error = Memory::map_typed<ACPI::Structures::MADT>(madt_address.value());
+ if (madt_or_error.is_error()) {
+ dbgln("APIC: Failed to map MADT table");
+ return false;
+ }
+ auto madt = madt_or_error.release_value();
size_t entry_index = 0;
size_t entries_length = madt->h.length - sizeof(ACPI::Structures::MADT);
auto* madt_entry = madt->entries;
diff --git a/Kernel/Interrupts/IOAPIC.cpp b/Kernel/Interrupts/IOAPIC.cpp
index f90433e068..abc052ccd0 100644
--- a/Kernel/Interrupts/IOAPIC.cpp
+++ b/Kernel/Interrupts/IOAPIC.cpp
@@ -25,7 +25,7 @@ enum DeliveryMode {
UNMAP_AFTER_INIT IOAPIC::IOAPIC(PhysicalAddress address, u32 gsi_base)
: m_address(address)
- , m_regs(Memory::map_typed_writable<ioapic_mmio_regs>(m_address))
+ , m_regs(Memory::map_typed_writable<ioapic_mmio_regs>(m_address).release_value_but_fixme_should_propagate_errors())
, m_gsi_base(gsi_base)
, m_id((read_register(0x0) >> 24) & 0xFF)
, m_version(read_register(0x1) & 0xFF)
diff --git a/Kernel/Interrupts/InterruptManagement.cpp b/Kernel/Interrupts/InterruptManagement.cpp
index 8da1f98910..56cf188706 100644
--- a/Kernel/Interrupts/InterruptManagement.cpp
+++ b/Kernel/Interrupts/InterruptManagement.cpp
@@ -189,7 +189,7 @@ UNMAP_AFTER_INIT void InterruptManagement::switch_to_ioapic_mode()
UNMAP_AFTER_INIT void InterruptManagement::locate_apic_data()
{
VERIFY(!m_madt.is_null());
- auto madt = Memory::map_typed<ACPI::Structures::MADT>(m_madt);
+ auto madt = Memory::map_typed<ACPI::Structures::MADT>(m_madt).release_value_but_fixme_should_propagate_errors();
int irq_controller_count = 0;
if (madt->flags & PCAT_COMPAT_FLAG) {
diff --git a/Kernel/Memory/TypedMapping.h b/Kernel/Memory/TypedMapping.h
index 133dd058fe..10dbd9ecf2 100644
--- a/Kernel/Memory/TypedMapping.h
+++ b/Kernel/Memory/TypedMapping.h
@@ -24,26 +24,23 @@ struct TypedMapping {
};
template<typename T>
-static TypedMapping<T> map_typed(PhysicalAddress paddr, size_t length, Region::Access access = Region::Access::Read)
+static ErrorOr<TypedMapping<T>> map_typed(PhysicalAddress paddr, size_t length, Region::Access access = Region::Access::Read)
{
TypedMapping<T> table;
- size_t mapping_length = page_round_up(paddr.offset_in_page() + length).release_value_but_fixme_should_propagate_errors();
- auto region_or_error = MM.allocate_kernel_region(paddr.page_base(), mapping_length, {}, access);
- if (region_or_error.is_error())
- TODO();
- table.region = region_or_error.release_value();
+ auto mapping_length = TRY(page_round_up(paddr.offset_in_page() + length));
+ table.region = TRY(MM.allocate_kernel_region(paddr.page_base(), mapping_length, {}, access));
table.offset = paddr.offset_in_page();
return table;
}
template<typename T>
-static TypedMapping<T> map_typed(PhysicalAddress paddr)
+static ErrorOr<TypedMapping<T>> map_typed(PhysicalAddress paddr)
{
return map_typed<T>(paddr, sizeof(T));
}
template<typename T>
-static TypedMapping<T> map_typed_writable(PhysicalAddress paddr)
+static ErrorOr<TypedMapping<T>> map_typed_writable(PhysicalAddress paddr)
{
return map_typed<T>(paddr, sizeof(T), Region::Access::Read | Region::Access::Write);
}
diff --git a/Kernel/Storage/ATA/AHCIPort.cpp b/Kernel/Storage/ATA/AHCIPort.cpp
index ef8f426351..a950b5b819 100644
--- a/Kernel/Storage/ATA/AHCIPort.cpp
+++ b/Kernel/Storage/ATA/AHCIPort.cpp
@@ -292,7 +292,7 @@ bool AHCIPort::initialize()
size_t physical_sector_size = 512;
u64 max_addressable_sector = 0;
if (identify_device()) {
- auto identify_block = Memory::map_typed<ATAIdentifyBlock>(m_parent_handler->get_identify_metadata_physical_region(m_port_index));
+ auto identify_block = Memory::map_typed<ATAIdentifyBlock>(m_parent_handler->get_identify_metadata_physical_region(m_port_index)).release_value_but_fixme_should_propagate_errors();
// Check if word 106 is valid before using it!
if ((identify_block->physical_sector_size_to_logical_sector_size >> 14) == 1) {
if (identify_block->physical_sector_size_to_logical_sector_size & (1 << 12)) {
diff --git a/Kernel/Storage/NVMe/NVMeController.cpp b/Kernel/Storage/NVMe/NVMeController.cpp
index 681fbbfc77..91bdbaf8c6 100644
--- a/Kernel/Storage/NVMe/NVMeController.cpp
+++ b/Kernel/Storage/NVMe/NVMeController.cpp
@@ -45,7 +45,7 @@ ErrorOr<void> NVMeController::initialize()
// Map only until doorbell register for the controller
// Queues will individually map the doorbell register respectively
- m_controller_regs = Memory::map_typed_writable<volatile ControllerRegister>(PhysicalAddress(m_bar));
+ m_controller_regs = TRY(Memory::map_typed_writable<volatile ControllerRegister>(PhysicalAddress(m_bar)));
calculate_doorbell_stride();
TRY(create_admin_queue(irq));
@@ -250,7 +250,7 @@ ErrorOr<void> NVMeController::create_admin_queue(u8 irq)
auto buffer = TRY(MM.allocate_dma_buffer_pages(sq_size, "Admin SQ queue", Memory::Region::Access::ReadWrite, sq_dma_pages));
sq_dma_region = move(buffer);
}
- auto doorbell_regs = Memory::map_typed_writable<volatile DoorbellRegister>(PhysicalAddress(m_bar + REG_SQ0TDBL_START));
+ auto doorbell_regs = TRY(Memory::map_typed_writable<volatile DoorbellRegister>(PhysicalAddress(m_bar + REG_SQ0TDBL_START)));
m_admin_queue = TRY(NVMeQueue::try_create(0, irq, qdepth, move(cq_dma_region), cq_dma_pages, move(sq_dma_region), sq_dma_pages, move(doorbell_regs)));
@@ -317,7 +317,7 @@ ErrorOr<void> NVMeController::create_io_queue(u8 irq, u8 qid)
}
auto queue_doorbell_offset = REG_SQ0TDBL_START + ((2 * qid) * (4 << m_dbl_stride));
- auto doorbell_regs = Memory::map_typed_writable<volatile DoorbellRegister>(PhysicalAddress(m_bar + queue_doorbell_offset));
+ auto doorbell_regs = TRY(Memory::map_typed_writable<volatile DoorbellRegister>(PhysicalAddress(m_bar + queue_doorbell_offset)));
m_queues.append(TRY(NVMeQueue::try_create(qid, irq, IO_QUEUE_SIZE, move(cq_dma_region), cq_dma_pages, move(sq_dma_region), sq_dma_pages, move(doorbell_regs))));
m_queues.last().enable_interrupts();
diff --git a/Kernel/Time/HPET.cpp b/Kernel/Time/HPET.cpp
index 990661611d..708dd2500f 100644
--- a/Kernel/Time/HPET.cpp
+++ b/Kernel/Time/HPET.cpp
@@ -133,10 +133,14 @@ UNMAP_AFTER_INIT bool HPET::test_and_initialize()
return false;
dmesgln("HPET @ {}", hpet_table.value());
- auto sdt = Memory::map_typed<ACPI::Structures::HPET>(hpet_table.value());
+ auto sdt_or_error = Memory::map_typed<ACPI::Structures::HPET>(hpet_table.value());
+ if (sdt_or_error.is_error()) {
+ dbgln("Failed mapping HPET table");
+ return false;
+ }
// Note: HPET is only usable from System Memory
- VERIFY(sdt->event_timer_block.address_space == (u8)ACPI::GenericAddressStructure::AddressSpace::SystemMemory);
+ VERIFY(sdt_or_error.value()->event_timer_block.address_space == (u8)ACPI::GenericAddressStructure::AddressSpace::SystemMemory);
if (TimeManagement::is_hpet_periodic_mode_allowed()) {
if (!check_for_exisiting_periodic_timers()) {
@@ -154,9 +158,15 @@ UNMAP_AFTER_INIT bool HPET::check_for_exisiting_periodic_timers()
if (!hpet_table.has_value())
return false;
- auto sdt = Memory::map_typed<ACPI::Structures::HPET>(hpet_table.value());
+ auto sdt_or_error = Memory::map_typed<ACPI::Structures::HPET>(hpet_table.value());
+ if (sdt_or_error.is_error())
+ return false;
+ auto sdt = sdt_or_error.release_value();
VERIFY(sdt->event_timer_block.address_space == 0);
- auto registers = Memory::map_typed<HPETRegistersBlock>(PhysicalAddress(sdt->event_timer_block.address));
+ auto registers_or_error = Memory::map_typed<HPETRegistersBlock>(PhysicalAddress(sdt->event_timer_block.address));
+ if (registers_or_error.is_error())
+ return false;
+ auto registers = registers_or_error.release_value();
size_t timers_count = ((registers->capabilities.attributes >> 8) & 0x1f) + 1;
for (size_t index = 0; index < timers_count; index++) {
@@ -393,7 +403,7 @@ void HPET::set_comparators_to_optimal_interrupt_state(size_t)
PhysicalAddress HPET::find_acpi_hpet_registers_block()
{
- auto sdt = Memory::map_typed<const volatile ACPI::Structures::HPET>(m_physical_acpi_hpet_table);
+ auto sdt = Memory::map_typed<const volatile ACPI::Structures::HPET>(m_physical_acpi_hpet_table).release_value_but_fixme_should_propagate_errors();
VERIFY(sdt->event_timer_block.address_space == (u8)ACPI::GenericAddressStructure::AddressSpace::SystemMemory);
return PhysicalAddress(sdt->event_timer_block.address);
}
@@ -426,7 +436,7 @@ UNMAP_AFTER_INIT HPET::HPET(PhysicalAddress acpi_hpet)
{
s_hpet = this; // Make available as soon as possible so that IRQs can use it
- auto sdt = Memory::map_typed<const volatile ACPI::Structures::HPET>(m_physical_acpi_hpet_table);
+ auto sdt = Memory::map_typed<const volatile ACPI::Structures::HPET>(m_physical_acpi_hpet_table).release_value_but_fixme_should_propagate_errors();
m_vendor_id = sdt->pci_vendor_id;
m_minimum_tick = sdt->mininum_clock_tick;
dmesgln("HPET: Minimum clock tick - {}", m_minimum_tick);