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.
This commit is contained in:
Idan Horowitz 2022-01-13 18:20:22 +02:00 committed by Andreas Kling
parent e2e5d4da16
commit fb3e46e930
14 changed files with 80 additions and 57 deletions

View file

@ -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;
}

View file

@ -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));

View file

@ -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)

View file

@ -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))

View file

@ -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;

View file

@ -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;

View file

@ -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));

View file

@ -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;

View file

@ -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)

View file

@ -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) {

View file

@ -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);
}

View file

@ -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)) {

View file

@ -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();

View file

@ -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);