diff --git a/Kernel/Arch/x86_64/PCI/IDELegacyModeController.cpp b/Kernel/Arch/x86_64/PCI/IDELegacyModeController.cpp index f5260ea1dcc..080ac29518c 100644 --- a/Kernel/Arch/x86_64/PCI/IDELegacyModeController.cpp +++ b/Kernel/Arch/x86_64/PCI/IDELegacyModeController.cpp @@ -18,9 +18,9 @@ namespace Kernel { UNMAP_AFTER_INIT ErrorOr> PCIIDELegacyModeController::initialize(PCI::DeviceIdentifier const& device_identifier, bool force_pio) { auto controller = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) PCIIDELegacyModeController(device_identifier))); - PCI::enable_io_space(device_identifier.address()); - PCI::enable_memory_space(device_identifier.address()); - PCI::enable_bus_mastering(device_identifier.address()); + PCI::enable_io_space(device_identifier); + PCI::enable_memory_space(device_identifier); + PCI::enable_bus_mastering(device_identifier); ArmedScopeGuard disable_interrupts_on_failure([&] { controller->disable_pin_based_interrupts(); }); @@ -31,7 +31,7 @@ UNMAP_AFTER_INIT ErrorOr> PCIIDELe } UNMAP_AFTER_INIT PCIIDELegacyModeController::PCIIDELegacyModeController(PCI::DeviceIdentifier const& device_identifier) - : PCI::Device(device_identifier.address()) + : PCI::Device(const_cast(device_identifier)) , m_prog_if(device_identifier.prog_if()) , m_interrupt_line(device_identifier.interrupt_line()) { @@ -84,11 +84,11 @@ static char const* detect_controller_type(u8 programming_value) UNMAP_AFTER_INIT ErrorOr PCIIDELegacyModeController::initialize_and_enumerate_channels(bool force_pio) { - dbgln("IDE controller @ {}: interrupt line was set to {}", pci_address(), m_interrupt_line.value()); - dbgln("IDE controller @ {}: {}", pci_address(), detect_controller_type(m_prog_if.value())); + dbgln("IDE controller @ {}: interrupt line was set to {}", device_identifier().address(), m_interrupt_line.value()); + dbgln("IDE controller @ {}: {}", device_identifier().address(), detect_controller_type(m_prog_if.value())); { - auto bus_master_base = IOAddress(PCI::get_BAR4(pci_address()) & (~1)); - dbgln("IDE controller @ {}: bus master base was set to {}", pci_address(), bus_master_base); + auto bus_master_base = IOAddress(PCI::get_BAR4(device_identifier()) & (~1)); + dbgln("IDE controller @ {}: bus master base was set to {}", device_identifier().address(), bus_master_base); } auto initialize_and_enumerate = [&force_pio](IDEChannel& channel) -> ErrorOr { @@ -106,8 +106,8 @@ UNMAP_AFTER_INIT ErrorOr PCIIDELegacyModeController::initialize_and_enumer primary_base_io_window = TRY(IOWindow::create_for_io_space(IOAddress(0x1F0), 8)); primary_control_io_window = TRY(IOWindow::create_for_io_space(IOAddress(0x3F6), 4)); } else { - auto primary_base_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR0)); - auto pci_primary_control_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR1)); + auto primary_base_io_window = TRY(IOWindow::create_for_pci_device_bar(device_identifier(), PCI::HeaderType0BaseRegister::BAR0)); + auto pci_primary_control_io_window = TRY(IOWindow::create_for_pci_device_bar(device_identifier(), PCI::HeaderType0BaseRegister::BAR1)); // Note: the PCI IDE specification says we should access the IO address with an offset of 2 // on native PCI IDE controllers. primary_control_io_window = TRY(pci_primary_control_io_window->create_from_io_window_with_offset(2, 4)); @@ -123,8 +123,8 @@ UNMAP_AFTER_INIT ErrorOr PCIIDELegacyModeController::initialize_and_enumer secondary_base_io_window = TRY(IOWindow::create_for_io_space(IOAddress(0x170), 8)); secondary_control_io_window = TRY(IOWindow::create_for_io_space(IOAddress(0x376), 4)); } else { - secondary_base_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR2)); - auto pci_secondary_control_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR3)); + secondary_base_io_window = TRY(IOWindow::create_for_pci_device_bar(device_identifier(), PCI::HeaderType0BaseRegister::BAR2)); + auto pci_secondary_control_io_window = TRY(IOWindow::create_for_pci_device_bar(device_identifier(), PCI::HeaderType0BaseRegister::BAR3)); // Note: the PCI IDE specification says we should access the IO address with an offset of 2 // on native PCI IDE controllers. secondary_control_io_window = TRY(pci_secondary_control_io_window->create_from_io_window_with_offset(2, 4)); @@ -132,7 +132,7 @@ UNMAP_AFTER_INIT ErrorOr PCIIDELegacyModeController::initialize_and_enumer VERIFY(secondary_base_io_window); VERIFY(secondary_control_io_window); - auto primary_bus_master_io = TRY(IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR4, 16)); + auto primary_bus_master_io = TRY(IOWindow::create_for_pci_device_bar(device_identifier(), PCI::HeaderType0BaseRegister::BAR4, 16)); auto secondary_bus_master_io = TRY(primary_bus_master_io->create_from_io_window_with_offset(8)); // FIXME: On IOAPIC based system, this value might be completely wrong diff --git a/Kernel/Bus/PCI/API.cpp b/Kernel/Bus/PCI/API.cpp index 1539c5960f5..5ea9b5245a1 100644 --- a/Kernel/Bus/PCI/API.cpp +++ b/Kernel/Bus/PCI/API.cpp @@ -10,106 +10,141 @@ namespace Kernel::PCI { -void write8(Address address, PCI::RegisterOffset field, u8 value) { Access::the().write8_field(address, to_underlying(field), value); } -void write16(Address address, PCI::RegisterOffset field, u16 value) { Access::the().write16_field(address, to_underlying(field), value); } -void write32(Address address, PCI::RegisterOffset field, u32 value) { Access::the().write32_field(address, to_underlying(field), value); } -u8 read8(Address address, PCI::RegisterOffset field) { return Access::the().read8_field(address, to_underlying(field)); } -u16 read16(Address address, PCI::RegisterOffset field) { return Access::the().read16_field(address, to_underlying(field)); } -u32 read32(Address address, PCI::RegisterOffset field) { return Access::the().read32_field(address, to_underlying(field)); } +void write8_locked(DeviceIdentifier const& identifier, PCI::RegisterOffset field, u8 value) +{ + VERIFY(identifier.operation_lock().is_locked()); + Access::the().write8_field(identifier, to_underlying(field), value); +} +void write16_locked(DeviceIdentifier const& identifier, PCI::RegisterOffset field, u16 value) +{ + VERIFY(identifier.operation_lock().is_locked()); + Access::the().write16_field(identifier, to_underlying(field), value); +} +void write32_locked(DeviceIdentifier const& identifier, PCI::RegisterOffset field, u32 value) +{ + VERIFY(identifier.operation_lock().is_locked()); + Access::the().write32_field(identifier, to_underlying(field), value); +} + +u8 read8_locked(DeviceIdentifier const& identifier, PCI::RegisterOffset field) +{ + VERIFY(identifier.operation_lock().is_locked()); + return Access::the().read8_field(identifier, to_underlying(field)); +} +u16 read16_locked(DeviceIdentifier const& identifier, PCI::RegisterOffset field) +{ + VERIFY(identifier.operation_lock().is_locked()); + return Access::the().read16_field(identifier, to_underlying(field)); +} +u32 read32_locked(DeviceIdentifier const& identifier, PCI::RegisterOffset field) +{ + VERIFY(identifier.operation_lock().is_locked()); + return Access::the().read32_field(identifier, to_underlying(field)); +} ErrorOr enumerate(Function callback) { return Access::the().fast_enumerate(callback); } -DeviceIdentifier get_device_identifier(Address address) +HardwareID get_hardware_id(DeviceIdentifier const& identifier) { - return Access::the().get_device_identifier(address); + SpinlockLocker locker(identifier.operation_lock()); + return { read16_locked(identifier, PCI::RegisterOffset::VENDOR_ID), read16_locked(identifier, PCI::RegisterOffset::DEVICE_ID) }; } -HardwareID get_hardware_id(Address address) +void enable_io_space(DeviceIdentifier const& identifier) { - return { read16(address, PCI::RegisterOffset::VENDOR_ID), read16(address, PCI::RegisterOffset::DEVICE_ID) }; + SpinlockLocker locker(identifier.operation_lock()); + write16_locked(identifier, PCI::RegisterOffset::COMMAND, read16_locked(identifier, PCI::RegisterOffset::COMMAND) | (1 << 0)); +} +void disable_io_space(DeviceIdentifier const& identifier) +{ + SpinlockLocker locker(identifier.operation_lock()); + write16_locked(identifier, PCI::RegisterOffset::COMMAND, read16_locked(identifier, PCI::RegisterOffset::COMMAND) & ~(1 << 0)); } -void enable_io_space(Address address) +void enable_memory_space(DeviceIdentifier const& identifier) { - write16(address, PCI::RegisterOffset::COMMAND, read16(address, PCI::RegisterOffset::COMMAND) | (1 << 0)); + SpinlockLocker locker(identifier.operation_lock()); + write16_locked(identifier, PCI::RegisterOffset::COMMAND, read16_locked(identifier, PCI::RegisterOffset::COMMAND) | (1 << 1)); } -void disable_io_space(Address address) +void disable_memory_space(DeviceIdentifier const& identifier) { - write16(address, PCI::RegisterOffset::COMMAND, read16(address, PCI::RegisterOffset::COMMAND) & ~(1 << 0)); + SpinlockLocker locker(identifier.operation_lock()); + write16_locked(identifier, PCI::RegisterOffset::COMMAND, read16_locked(identifier, PCI::RegisterOffset::COMMAND) & ~(1 << 1)); } -void enable_memory_space(Address address) +bool is_io_space_enabled(DeviceIdentifier const& identifier) { - write16(address, PCI::RegisterOffset::COMMAND, read16(address, PCI::RegisterOffset::COMMAND) | (1 << 1)); -} -void disable_memory_space(Address address) -{ - write16(address, PCI::RegisterOffset::COMMAND, read16(address, PCI::RegisterOffset::COMMAND) & ~(1 << 1)); -} -bool is_io_space_enabled(Address address) -{ - return (read16(address, PCI::RegisterOffset::COMMAND) & 1) != 0; + SpinlockLocker locker(identifier.operation_lock()); + return (read16_locked(identifier, PCI::RegisterOffset::COMMAND) & 1) != 0; } -void enable_interrupt_line(Address address) +void enable_interrupt_line(DeviceIdentifier const& identifier) { - write16(address, PCI::RegisterOffset::COMMAND, read16(address, PCI::RegisterOffset::COMMAND) & ~(1 << 10)); + SpinlockLocker locker(identifier.operation_lock()); + write16_locked(identifier, PCI::RegisterOffset::COMMAND, read16_locked(identifier, PCI::RegisterOffset::COMMAND) & ~(1 << 10)); } -void disable_interrupt_line(Address address) +void disable_interrupt_line(DeviceIdentifier const& identifier) { - write16(address, PCI::RegisterOffset::COMMAND, read16(address, PCI::RegisterOffset::COMMAND) | 1 << 10); + SpinlockLocker locker(identifier.operation_lock()); + write16_locked(identifier, PCI::RegisterOffset::COMMAND, read16_locked(identifier, PCI::RegisterOffset::COMMAND) | 1 << 10); } -u32 get_BAR0(Address address) +u32 get_BAR0(DeviceIdentifier const& identifier) { - return read32(address, PCI::RegisterOffset::BAR0); + SpinlockLocker locker(identifier.operation_lock()); + return read32_locked(identifier, PCI::RegisterOffset::BAR0); } -u32 get_BAR1(Address address) +u32 get_BAR1(DeviceIdentifier const& identifier) { - return read32(address, PCI::RegisterOffset::BAR1); + SpinlockLocker locker(identifier.operation_lock()); + return read32_locked(identifier, PCI::RegisterOffset::BAR1); } -u32 get_BAR2(Address address) +u32 get_BAR2(DeviceIdentifier const& identifier) { - return read32(address, PCI::RegisterOffset::BAR2); + SpinlockLocker locker(identifier.operation_lock()); + return read32_locked(identifier, PCI::RegisterOffset::BAR2); } -u32 get_BAR3(Address address) +u32 get_BAR3(DeviceIdentifier const& identifier) { - return read16(address, PCI::RegisterOffset::BAR3); + SpinlockLocker locker(identifier.operation_lock()); + return read32_locked(identifier, PCI::RegisterOffset::BAR3); } -u32 get_BAR4(Address address) +u32 get_BAR4(DeviceIdentifier const& identifier) { - return read32(address, PCI::RegisterOffset::BAR4); + SpinlockLocker locker(identifier.operation_lock()); + return read32_locked(identifier, PCI::RegisterOffset::BAR4); } -u32 get_BAR5(Address address) +u32 get_BAR5(DeviceIdentifier const& identifier) { - return read32(address, PCI::RegisterOffset::BAR5); + SpinlockLocker locker(identifier.operation_lock()); + return read32_locked(identifier, PCI::RegisterOffset::BAR5); } -u32 get_BAR(Address address, HeaderType0BaseRegister pci_bar) +u32 get_BAR(DeviceIdentifier const& identifier, HeaderType0BaseRegister pci_bar) { VERIFY(to_underlying(pci_bar) <= 5); switch (to_underlying(pci_bar)) { case 0: - return get_BAR0(address); + return get_BAR0(identifier); case 1: - return get_BAR1(address); + return get_BAR1(identifier); case 2: - return get_BAR2(address); + return get_BAR2(identifier); case 3: - return get_BAR3(address); + return get_BAR3(identifier); case 4: - return get_BAR4(address); + return get_BAR4(identifier); case 5: - return get_BAR5(address); + return get_BAR5(identifier); default: VERIFY_NOT_REACHED(); } @@ -133,89 +168,113 @@ BARSpaceType get_BAR_space_type(u32 pci_bar_value) } } -void enable_bus_mastering(Address address) +void enable_bus_mastering(DeviceIdentifier const& identifier) { - auto value = read16(address, PCI::RegisterOffset::COMMAND); + SpinlockLocker locker(identifier.operation_lock()); + auto value = read16_locked(identifier, PCI::RegisterOffset::COMMAND); value |= (1 << 2); value |= (1 << 0); - write16(address, PCI::RegisterOffset::COMMAND, value); + write16_locked(identifier, PCI::RegisterOffset::COMMAND, value); } -void disable_bus_mastering(Address address) +void disable_bus_mastering(DeviceIdentifier const& identifier) { - auto value = read16(address, PCI::RegisterOffset::COMMAND); + SpinlockLocker locker(identifier.operation_lock()); + auto value = read16_locked(identifier, PCI::RegisterOffset::COMMAND); value &= ~(1 << 2); value |= (1 << 0); - write16(address, PCI::RegisterOffset::COMMAND, value); + write16_locked(identifier, PCI::RegisterOffset::COMMAND, value); } -static void write8_offsetted(Address address, u32 field, u8 value) { Access::the().write8_field(address, field, value); } -static void write16_offsetted(Address address, u32 field, u16 value) { Access::the().write16_field(address, field, value); } -static void write32_offsetted(Address address, u32 field, u32 value) { Access::the().write32_field(address, field, value); } -static u8 read8_offsetted(Address address, u32 field) { return Access::the().read8_field(address, field); } -static u16 read16_offsetted(Address address, u32 field) { return Access::the().read16_field(address, field); } -static u32 read32_offsetted(Address address, u32 field) { return Access::the().read32_field(address, field); } - -size_t get_BAR_space_size(Address address, HeaderType0BaseRegister pci_bar) +static void write8_offsetted(DeviceIdentifier const& identifier, u32 field, u8 value) { + VERIFY(identifier.operation_lock().is_locked()); + Access::the().write8_field(identifier, field, value); +} +static void write16_offsetted(DeviceIdentifier const& identifier, u32 field, u16 value) +{ + VERIFY(identifier.operation_lock().is_locked()); + Access::the().write16_field(identifier, field, value); +} +static void write32_offsetted(DeviceIdentifier const& identifier, u32 field, u32 value) +{ + VERIFY(identifier.operation_lock().is_locked()); + Access::the().write32_field(identifier, field, value); +} +static u8 read8_offsetted(DeviceIdentifier const& identifier, u32 field) +{ + VERIFY(identifier.operation_lock().is_locked()); + return Access::the().read8_field(identifier, field); +} +static u16 read16_offsetted(DeviceIdentifier const& identifier, u32 field) +{ + VERIFY(identifier.operation_lock().is_locked()); + return Access::the().read16_field(identifier, field); +} +static u32 read32_offsetted(DeviceIdentifier const& identifier, u32 field) +{ + VERIFY(identifier.operation_lock().is_locked()); + return Access::the().read32_field(identifier, field); +} + +size_t get_BAR_space_size(DeviceIdentifier const& identifier, HeaderType0BaseRegister pci_bar) +{ + SpinlockLocker locker(identifier.operation_lock()); // See PCI Spec 2.3, Page 222 VERIFY(to_underlying(pci_bar) < 6); u8 field = to_underlying(PCI::RegisterOffset::BAR0) + (to_underlying(pci_bar) << 2); - u32 bar_reserved = read32_offsetted(address, field); - write32_offsetted(address, field, 0xFFFFFFFF); - u32 space_size = read32_offsetted(address, field); - write32_offsetted(address, field, bar_reserved); + u32 bar_reserved = read32_offsetted(identifier, field); + write32_offsetted(identifier, field, 0xFFFFFFFF); + u32 space_size = read32_offsetted(identifier, field); + write32_offsetted(identifier, field, bar_reserved); space_size &= 0xfffffff0; space_size = (~space_size) + 1; return space_size; } -void raw_access(Address address, u32 field, size_t access_size, u32 value) +void raw_access(DeviceIdentifier const& identifier, u32 field, size_t access_size, u32 value) { + SpinlockLocker locker(identifier.operation_lock()); VERIFY(access_size != 0); if (access_size == 1) { - write8_offsetted(address, field, value); + write8_offsetted(identifier, field, value); return; } if (access_size == 2) { - write16_offsetted(address, field, value); + write16_offsetted(identifier, field, value); return; } if (access_size == 4) { - write32_offsetted(address, field, value); + write32_offsetted(identifier, field, value); return; } VERIFY_NOT_REACHED(); } -u8 Capability::read8(u32 field) const +u8 Capability::read8(size_t offset) const { - return read8_offsetted(m_address, m_ptr + field); + auto& identifier = get_device_identifier(m_address); + SpinlockLocker locker(identifier.operation_lock()); + return read8_offsetted(identifier, m_ptr + offset); } -u16 Capability::read16(u32 field) const +u16 Capability::read16(size_t offset) const { - return read16_offsetted(m_address, m_ptr + field); + auto& identifier = get_device_identifier(m_address); + SpinlockLocker locker(identifier.operation_lock()); + return read16_offsetted(identifier, m_ptr + offset); } -u32 Capability::read32(u32 field) const +u32 Capability::read32(size_t offset) const { - return read32_offsetted(m_address, m_ptr + field); + auto& identifier = get_device_identifier(m_address); + SpinlockLocker locker(identifier.operation_lock()); + return read32_offsetted(identifier, m_ptr + offset); } -void Capability::write8(u32 field, u8 value) +DeviceIdentifier const& get_device_identifier(Address address) { - write8_offsetted(m_address, m_ptr + field, value); -} - -void Capability::write16(u32 field, u16 value) -{ - write16_offsetted(m_address, m_ptr + field, value); -} - -void Capability::write32(u32 field, u32 value) -{ - write32_offsetted(m_address, m_ptr + field, value); + return Access::the().get_device_identifier(address); } } diff --git a/Kernel/Bus/PCI/API.h b/Kernel/Bus/PCI/API.h index 545942deb6b..1b7c641c2eb 100644 --- a/Kernel/Bus/PCI/API.h +++ b/Kernel/Bus/PCI/API.h @@ -12,34 +12,37 @@ namespace Kernel::PCI { -void write8(Address address, PCI::RegisterOffset field, u8 value); -void write16(Address address, PCI::RegisterOffset field, u16 value); -void write32(Address address, PCI::RegisterOffset field, u32 value); -u8 read8(Address address, PCI::RegisterOffset field); -u16 read16(Address address, PCI::RegisterOffset field); -u32 read32(Address address, PCI::RegisterOffset field); +void write8_locked(DeviceIdentifier const&, PCI::RegisterOffset field, u8 value); +void write16_locked(DeviceIdentifier const&, PCI::RegisterOffset field, u16 value); +void write32_locked(DeviceIdentifier const&, PCI::RegisterOffset field, u32 value); +u8 read8_locked(DeviceIdentifier const&, PCI::RegisterOffset field); +u16 read16_locked(DeviceIdentifier const&, PCI::RegisterOffset field); +u32 read32_locked(DeviceIdentifier const&, PCI::RegisterOffset field); -HardwareID get_hardware_id(PCI::Address); -bool is_io_space_enabled(Address); +HardwareID get_hardware_id(DeviceIdentifier const&); +bool is_io_space_enabled(DeviceIdentifier const&); ErrorOr enumerate(Function callback); -void enable_interrupt_line(Address); -void disable_interrupt_line(Address); -void raw_access(Address, u32, size_t, u32); -u32 get_BAR0(Address); -u32 get_BAR1(Address); -u32 get_BAR2(Address); -u32 get_BAR3(Address); -u32 get_BAR4(Address); -u32 get_BAR5(Address); -u32 get_BAR(Address address, HeaderType0BaseRegister); -size_t get_BAR_space_size(Address, HeaderType0BaseRegister); -BARSpaceType get_BAR_space_type(u32 pci_bar_value); -void enable_bus_mastering(Address); -void disable_bus_mastering(Address); -void enable_io_space(Address); -void disable_io_space(Address); -void enable_memory_space(Address); -void disable_memory_space(Address); -DeviceIdentifier get_device_identifier(Address address); +void enable_interrupt_line(DeviceIdentifier const&); +void disable_interrupt_line(DeviceIdentifier const&); +void raw_access(DeviceIdentifier const&, u32, size_t, u32); +u32 get_BAR0(DeviceIdentifier const&); +u32 get_BAR1(DeviceIdentifier const&); +u32 get_BAR2(DeviceIdentifier const&); +u32 get_BAR3(DeviceIdentifier const&); +u32 get_BAR4(DeviceIdentifier const&); +u32 get_BAR5(DeviceIdentifier const&); +u32 get_BAR(DeviceIdentifier const&, HeaderType0BaseRegister); +size_t get_BAR_space_size(DeviceIdentifier const&, HeaderType0BaseRegister); +BARSpaceType get_BAR_space_type(u32 pci_bar_value); +void enable_bus_mastering(DeviceIdentifier const&); +void disable_bus_mastering(DeviceIdentifier const&); +void enable_io_space(DeviceIdentifier const&); +void disable_io_space(DeviceIdentifier const&); +void enable_memory_space(DeviceIdentifier const&); +void disable_memory_space(DeviceIdentifier const&); + +// FIXME: Remove this once we can use PCI::Capability with inline buffer +// so we don't need this method +DeviceIdentifier const& get_device_identifier(Address address); } diff --git a/Kernel/Bus/PCI/Access.cpp b/Kernel/Bus/PCI/Access.cpp index 460d9ece8a8..4a78f43b99d 100644 --- a/Kernel/Bus/PCI/Access.cpp +++ b/Kernel/Bus/PCI/Access.cpp @@ -123,38 +123,26 @@ UNMAP_AFTER_INIT bool Access::initialize_for_one_pci_domain() } #endif -ErrorOr Access::add_host_controller_and_enumerate_attached_devices(NonnullOwnPtr controller, Function callback) +ErrorOr Access::add_host_controller_and_scan_for_devices(NonnullOwnPtr controller) { - // Note: We hold the spinlocks for a moment just to ensure we append the - // device identifiers safely. Afterwards, enumeration goes lockless to allow - // IRQs to be fired if necessary. - Vector device_identifiers_behind_host_controller; - { - SpinlockLocker locker(m_access_lock); - SpinlockLocker scan_locker(m_scan_lock); - auto domain_number = controller->domain_number(); + SpinlockLocker locker(m_access_lock); + SpinlockLocker scan_locker(m_scan_lock); + auto domain_number = controller->domain_number(); - VERIFY(!m_host_controllers.contains(domain_number)); - // Note: We need to register the new controller as soon as possible, and - // definitely before enumerating devices behind that. - m_host_controllers.set(domain_number, move(controller)); - ErrorOr expansion_result; - m_host_controllers.get(domain_number).value()->enumerate_attached_devices([&](DeviceIdentifier const& device_identifier) -> IterationDecision { - m_device_identifiers.append(device_identifier); - auto result = device_identifiers_behind_host_controller.try_append(device_identifier); - if (result.is_error()) { - expansion_result = result; - return IterationDecision::Break; - } - return IterationDecision::Continue; - }); - if (expansion_result.is_error()) - return expansion_result; - } - - for (auto const& device_identifier : device_identifiers_behind_host_controller) { - callback(device_identifier); - } + VERIFY(!m_host_controllers.contains(domain_number)); + // Note: We need to register the new controller as soon as possible, and + // definitely before enumerating devices behind that. + m_host_controllers.set(domain_number, move(controller)); + ErrorOr error_or_void {}; + m_host_controllers.get(domain_number).value()->enumerate_attached_devices([&](EnumerableDeviceIdentifier const& device_identifier) -> IterationDecision { + auto device_identifier_or_error = DeviceIdentifier::from_enumerable_identifier(device_identifier); + if (device_identifier_or_error.is_error()) { + error_or_void = device_identifier_or_error.error(); + return IterationDecision::Break; + } + m_device_identifiers.append(device_identifier_or_error.release_value()); + return IterationDecision::Continue; + }); return {}; } @@ -174,19 +162,29 @@ UNMAP_AFTER_INIT void Access::rescan_hardware() SpinlockLocker locker(m_access_lock); SpinlockLocker scan_locker(m_scan_lock); VERIFY(m_device_identifiers.is_empty()); + ErrorOr error_or_void {}; for (auto it = m_host_controllers.begin(); it != m_host_controllers.end(); ++it) { - (*it).value->enumerate_attached_devices([this](DeviceIdentifier device_identifier) -> IterationDecision { - m_device_identifiers.append(device_identifier); + (*it).value->enumerate_attached_devices([this, &error_or_void](EnumerableDeviceIdentifier device_identifier) -> IterationDecision { + auto device_identifier_or_error = DeviceIdentifier::from_enumerable_identifier(device_identifier); + if (device_identifier_or_error.is_error()) { + error_or_void = device_identifier_or_error.error(); + return IterationDecision::Break; + } + m_device_identifiers.append(device_identifier_or_error.release_value()); return IterationDecision::Continue; }); } + if (error_or_void.is_error()) { + dmesgln("Failed during PCI Access::rescan_hardware due to {}", error_or_void.error()); + VERIFY_NOT_REACHED(); + } } ErrorOr Access::fast_enumerate(Function& callback) const { // Note: We hold the m_access_lock for a brief moment just to ensure we get // a complete Vector in case someone wants to mutate it. - Vector device_identifiers; + NonnullRefPtrVector device_identifiers; { SpinlockLocker locker(m_access_lock); VERIFY(!m_device_identifiers.is_empty()); @@ -198,9 +196,9 @@ ErrorOr Access::fast_enumerate(Function& ca return {}; } -DeviceIdentifier Access::get_device_identifier(Address address) const +DeviceIdentifier const& Access::get_device_identifier(Address address) const { - for (auto device_identifier : m_device_identifiers) { + for (auto& device_identifier : m_device_identifiers) { if (device_identifier.address().domain() == address.domain() && device_identifier.address().bus() == address.bus() && device_identifier.address().device() == address.device() @@ -211,57 +209,65 @@ DeviceIdentifier Access::get_device_identifier(Address address) const VERIFY_NOT_REACHED(); } -void Access::write8_field(Address address, u32 field, u8 value) +void Access::write8_field(DeviceIdentifier const& identifier, u32 field, u8 value) { + VERIFY(identifier.operation_lock().is_locked()); SpinlockLocker locker(m_access_lock); - VERIFY(m_host_controllers.contains(address.domain())); - auto& controller = *m_host_controllers.get(address.domain()).value(); - controller.write8_field(address.bus(), address.device(), address.function(), field, value); + VERIFY(m_host_controllers.contains(identifier.address().domain())); + auto& controller = *m_host_controllers.get(identifier.address().domain()).value(); + controller.write8_field(identifier.address().bus(), identifier.address().device(), identifier.address().function(), field, value); } -void Access::write16_field(Address address, u32 field, u16 value) +void Access::write16_field(DeviceIdentifier const& identifier, u32 field, u16 value) { + VERIFY(identifier.operation_lock().is_locked()); SpinlockLocker locker(m_access_lock); - VERIFY(m_host_controllers.contains(address.domain())); - auto& controller = *m_host_controllers.get(address.domain()).value(); - controller.write16_field(address.bus(), address.device(), address.function(), field, value); + VERIFY(m_host_controllers.contains(identifier.address().domain())); + auto& controller = *m_host_controllers.get(identifier.address().domain()).value(); + controller.write16_field(identifier.address().bus(), identifier.address().device(), identifier.address().function(), field, value); } -void Access::write32_field(Address address, u32 field, u32 value) +void Access::write32_field(DeviceIdentifier const& identifier, u32 field, u32 value) { + VERIFY(identifier.operation_lock().is_locked()); SpinlockLocker locker(m_access_lock); - VERIFY(m_host_controllers.contains(address.domain())); - auto& controller = *m_host_controllers.get(address.domain()).value(); - controller.write32_field(address.bus(), address.device(), address.function(), field, value); + VERIFY(m_host_controllers.contains(identifier.address().domain())); + auto& controller = *m_host_controllers.get(identifier.address().domain()).value(); + controller.write32_field(identifier.address().bus(), identifier.address().device(), identifier.address().function(), field, value); } -u8 Access::read8_field(Address address, RegisterOffset field) +u8 Access::read8_field(DeviceIdentifier const& identifier, RegisterOffset field) { - return read8_field(address, to_underlying(field)); + VERIFY(identifier.operation_lock().is_locked()); + return read8_field(identifier, to_underlying(field)); } -u16 Access::read16_field(Address address, RegisterOffset field) +u16 Access::read16_field(DeviceIdentifier const& identifier, RegisterOffset field) { - return read16_field(address, to_underlying(field)); + VERIFY(identifier.operation_lock().is_locked()); + return read16_field(identifier, to_underlying(field)); } -u8 Access::read8_field(Address address, u32 field) +u8 Access::read8_field(DeviceIdentifier const& identifier, u32 field) { + VERIFY(identifier.operation_lock().is_locked()); SpinlockLocker locker(m_access_lock); - VERIFY(m_host_controllers.contains(address.domain())); - auto& controller = *m_host_controllers.get(address.domain()).value(); - return controller.read8_field(address.bus(), address.device(), address.function(), field); + VERIFY(m_host_controllers.contains(identifier.address().domain())); + auto& controller = *m_host_controllers.get(identifier.address().domain()).value(); + return controller.read8_field(identifier.address().bus(), identifier.address().device(), identifier.address().function(), field); } -u16 Access::read16_field(Address address, u32 field) +u16 Access::read16_field(DeviceIdentifier const& identifier, u32 field) { + VERIFY(identifier.operation_lock().is_locked()); SpinlockLocker locker(m_access_lock); - VERIFY(m_host_controllers.contains(address.domain())); - auto& controller = *m_host_controllers.get(address.domain()).value(); - return controller.read16_field(address.bus(), address.device(), address.function(), field); + VERIFY(m_host_controllers.contains(identifier.address().domain())); + auto& controller = *m_host_controllers.get(identifier.address().domain()).value(); + return controller.read16_field(identifier.address().bus(), identifier.address().device(), identifier.address().function(), field); } -u32 Access::read32_field(Address address, u32 field) +u32 Access::read32_field(DeviceIdentifier const& identifier, u32 field) { + VERIFY(identifier.operation_lock().is_locked()); SpinlockLocker locker(m_access_lock); - VERIFY(m_host_controllers.contains(address.domain())); - auto& controller = *m_host_controllers.get(address.domain()).value(); - return controller.read32_field(address.bus(), address.device(), address.function(), field); + VERIFY(m_host_controllers.contains(identifier.address().domain())); + auto& controller = *m_host_controllers.get(identifier.address().domain()).value(); + return controller.read32_field(identifier.address().bus(), identifier.address().device(), identifier.address().function(), field); } } diff --git a/Kernel/Bus/PCI/Access.h b/Kernel/Bus/PCI/Access.h index e0fd8a924b4..8c5b5fcab9c 100644 --- a/Kernel/Bus/PCI/Access.h +++ b/Kernel/Bus/PCI/Access.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -33,22 +34,25 @@ public: static bool is_disabled(); static bool is_hardware_disabled(); - void write8_field(Address address, u32 field, u8 value); - void write16_field(Address address, u32 field, u16 value); - void write32_field(Address address, u32 field, u32 value); - u8 read8_field(Address address, u32 field); - u16 read16_field(Address address, u32 field); - u32 read32_field(Address address, u32 field); - DeviceIdentifier get_device_identifier(Address address) const; + void write8_field(DeviceIdentifier const&, u32 field, u8 value); + void write16_field(DeviceIdentifier const&, u32 field, u16 value); + void write32_field(DeviceIdentifier const&, u32 field, u32 value); + u8 read8_field(DeviceIdentifier const&, u32 field); + u16 read16_field(DeviceIdentifier const&, u32 field); + u32 read32_field(DeviceIdentifier const&, u32 field); + + // FIXME: Remove this once we can use PCI::Capability with inline buffer + // so we don't need this method + DeviceIdentifier const& get_device_identifier(Address address) const; Spinlock const& scan_lock() const { return m_scan_lock; } RecursiveSpinlock const& access_lock() const { return m_access_lock; } - ErrorOr add_host_controller_and_enumerate_attached_devices(NonnullOwnPtr, Function callback); + ErrorOr add_host_controller_and_scan_for_devices(NonnullOwnPtr); private: - u8 read8_field(Address address, RegisterOffset field); - u16 read16_field(Address address, RegisterOffset field); + u8 read8_field(DeviceIdentifier const&, RegisterOffset field); + u16 read16_field(DeviceIdentifier const&, RegisterOffset field); void add_host_controller(NonnullOwnPtr); bool find_and_register_pci_host_bridges_from_acpi_mcfg_table(PhysicalAddress mcfg); @@ -61,6 +65,6 @@ private: mutable Spinlock m_scan_lock {}; HashMap> m_host_controllers; - Vector m_device_identifiers; + NonnullRefPtrVector m_device_identifiers; }; } diff --git a/Kernel/Bus/PCI/Controller/HostController.cpp b/Kernel/Bus/PCI/Controller/HostController.cpp index 22cd93de5cf..ba97d1ee7e2 100644 --- a/Kernel/Bus/PCI/Controller/HostController.cpp +++ b/Kernel/Bus/PCI/Controller/HostController.cpp @@ -54,7 +54,7 @@ u16 HostController::read16_field(BusNumber bus, DeviceNumber device, FunctionNum return read16_field(bus, device, function, to_underlying(field)); } -UNMAP_AFTER_INIT void HostController::enumerate_functions(Function const& callback, BusNumber bus, DeviceNumber device, FunctionNumber function, bool recursive_search_into_bridges) +UNMAP_AFTER_INIT void HostController::enumerate_functions(Function const& callback, BusNumber bus, DeviceNumber device, FunctionNumber function, bool recursive_search_into_bridges) { dbgln_if(PCI_DEBUG, "PCI: Enumerating function, bus={}, device={}, function={}", bus, device, function); Address address(domain_number(), bus.value(), device.value(), function.value()); @@ -70,7 +70,7 @@ UNMAP_AFTER_INIT void HostController::enumerate_functions(Function const& callback, BusNumber bus, DeviceNumber device, bool recursive_search_into_bridges) +UNMAP_AFTER_INIT void HostController::enumerate_device(Function const& callback, BusNumber bus, DeviceNumber device, bool recursive_search_into_bridges) { dbgln_if(PCI_DEBUG, "PCI: Enumerating device in bus={}, device={}", bus, device); if (read16_field(bus, device, 0, PCI::RegisterOffset::VENDOR_ID) == PCI::none_value) @@ -97,14 +97,14 @@ UNMAP_AFTER_INIT void HostController::enumerate_device(Function const& callback, BusNumber bus, bool recursive_search_into_bridges) +UNMAP_AFTER_INIT void HostController::enumerate_bus(Function const& callback, BusNumber bus, bool recursive_search_into_bridges) { dbgln_if(PCI_DEBUG, "PCI: Enumerating bus {}", bus); for (u8 device = 0; device < 32; ++device) enumerate_device(callback, bus, device, recursive_search_into_bridges); } -UNMAP_AFTER_INIT void HostController::enumerate_attached_devices(Function callback) +UNMAP_AFTER_INIT void HostController::enumerate_attached_devices(Function callback) { VERIFY(Access::the().access_lock().is_locked()); VERIFY(Access::the().scan_lock().is_locked()); diff --git a/Kernel/Bus/PCI/Controller/HostController.h b/Kernel/Bus/PCI/Controller/HostController.h index e21596c14fa..9efa1bd8d3c 100644 --- a/Kernel/Bus/PCI/Controller/HostController.h +++ b/Kernel/Bus/PCI/Controller/HostController.h @@ -31,12 +31,12 @@ public: u32 domain_number() const { return m_domain.domain_number(); } - void enumerate_attached_devices(Function callback); + void enumerate_attached_devices(Function callback); private: - void enumerate_bus(Function const& callback, BusNumber, bool recursive); - void enumerate_functions(Function const& callback, BusNumber, DeviceNumber, FunctionNumber, bool recursive); - void enumerate_device(Function const& callback, BusNumber bus, DeviceNumber device, bool recursive); + void enumerate_bus(Function const& callback, BusNumber, bool recursive); + void enumerate_functions(Function const& callback, BusNumber, DeviceNumber, FunctionNumber, bool recursive); + void enumerate_device(Function const& callback, BusNumber bus, DeviceNumber device, bool recursive); u8 read8_field(BusNumber, DeviceNumber, FunctionNumber, RegisterOffset field); u16 read16_field(BusNumber, DeviceNumber, FunctionNumber, RegisterOffset field); diff --git a/Kernel/Bus/PCI/Controller/VolumeManagementDevice.cpp b/Kernel/Bus/PCI/Controller/VolumeManagementDevice.cpp index 4c8d4d7be7e..3ae63cf2dd2 100644 --- a/Kernel/Bus/PCI/Controller/VolumeManagementDevice.cpp +++ b/Kernel/Bus/PCI/Controller/VolumeManagementDevice.cpp @@ -15,8 +15,9 @@ static Atomic s_vmd_pci_domain_number = 0x10000; NonnullOwnPtr VolumeManagementDevice::must_create(PCI::DeviceIdentifier const& device_identifier) { + SpinlockLocker locker(device_identifier.operation_lock()); u8 start_bus = 0; - switch ((PCI::read16(device_identifier.address(), static_cast(0x44)) >> 8) & 0x3) { + switch ((PCI::read16_locked(device_identifier, static_cast(0x44)) >> 8) & 0x3) { case 0: break; case 1: @@ -27,7 +28,7 @@ NonnullOwnPtr VolumeManagementDevice::must_create(PCI::D break; default: dbgln("VMD @ {}: Unknown bus offset option was set to {}", device_identifier.address(), - ((PCI::read16(device_identifier.address(), static_cast(0x44)) >> 8) & 0x3)); + ((PCI::read16_locked(device_identifier, static_cast(0x44)) >> 8) & 0x3)); VERIFY_NOT_REACHED(); } @@ -35,7 +36,7 @@ NonnullOwnPtr VolumeManagementDevice::must_create(PCI::D // resource size of BAR0. dbgln("VMD Host bridge @ {}: Start bus at {}, end bus {}", device_identifier.address(), start_bus, 0xff); PCI::Domain domain { s_vmd_pci_domain_number++, start_bus, 0xff }; - auto start_address = PhysicalAddress(PCI::get_BAR0(device_identifier.address())).page_base(); + auto start_address = PhysicalAddress(PCI::get_BAR0(device_identifier)).page_base(); return adopt_own_if_nonnull(new (nothrow) VolumeManagementDevice(domain, start_address)).release_nonnull(); } diff --git a/Kernel/Bus/PCI/Definitions.h b/Kernel/Bus/PCI/Definitions.h index 9a2437ed18e..9dec250a8d8 100644 --- a/Kernel/Bus/PCI/Definitions.h +++ b/Kernel/Bus/PCI/Definitions.h @@ -12,6 +12,7 @@ #include #include #include +#include #include namespace Kernel::PCI { @@ -38,30 +39,31 @@ enum class BARSpaceType { }; enum class RegisterOffset { - VENDOR_ID = 0x00, // word - DEVICE_ID = 0x02, // word - COMMAND = 0x04, // word - STATUS = 0x06, // word - REVISION_ID = 0x08, // byte - PROG_IF = 0x09, // byte - SUBCLASS = 0x0a, // byte - CLASS = 0x0b, // byte - CACHE_LINE_SIZE = 0x0c, // byte - LATENCY_TIMER = 0x0d, // byte - HEADER_TYPE = 0x0e, // byte - BIST = 0x0f, // byte - BAR0 = 0x10, // u32 - BAR1 = 0x14, // u32 - BAR2 = 0x18, // u32 - SECONDARY_BUS = 0x19, // byte - BAR3 = 0x1C, // u32 - BAR4 = 0x20, // u32 - BAR5 = 0x24, // u32 - SUBSYSTEM_VENDOR_ID = 0x2C, // u16 - SUBSYSTEM_ID = 0x2E, // u16 - CAPABILITIES_POINTER = 0x34, // u8 - INTERRUPT_LINE = 0x3C, // byte - INTERRUPT_PIN = 0x3D, // byte + VENDOR_ID = 0x00, // word + DEVICE_ID = 0x02, // word + COMMAND = 0x04, // word + STATUS = 0x06, // word + REVISION_ID = 0x08, // byte + PROG_IF = 0x09, // byte + SUBCLASS = 0x0a, // byte + CLASS = 0x0b, // byte + CACHE_LINE_SIZE = 0x0c, // byte + LATENCY_TIMER = 0x0d, // byte + HEADER_TYPE = 0x0e, // byte + BIST = 0x0f, // byte + BAR0 = 0x10, // u32 + BAR1 = 0x14, // u32 + BAR2 = 0x18, // u32 + SECONDARY_BUS = 0x19, // byte + BAR3 = 0x1C, // u32 + BAR4 = 0x20, // u32 + BAR5 = 0x24, // u32 + SUBSYSTEM_VENDOR_ID = 0x2C, // u16 + SUBSYSTEM_ID = 0x2E, // u16 + EXPANSION_ROM_POINTER = 0x30, // u32 + CAPABILITIES_POINTER = 0x34, // u8 + INTERRUPT_LINE = 0x3C, // byte + INTERRUPT_PIN = 0x3D, // byte }; enum class Limits { @@ -213,7 +215,7 @@ private: class Capability { public: - Capability(Address const& address, u8 id, u8 ptr) + Capability(Address address, u8 id, u8 ptr) : m_address(address) , m_id(id) , m_ptr(ptr) @@ -222,15 +224,12 @@ public: CapabilityID id() const { return m_id; } - u8 read8(u32) const; - u16 read16(u32) const; - u32 read32(u32) const; - void write8(u32, u8); - void write16(u32, u16); - void write32(u32, u32); + u8 read8(size_t offset) const; + u16 read16(size_t offset) const; + u32 read32(size_t offset) const; private: - Address m_address; + const Address m_address; const CapabilityID m_id; const u8 m_ptr; }; @@ -245,9 +244,9 @@ AK_TYPEDEF_DISTINCT_ORDERED_ID(u8, InterruptLine); AK_TYPEDEF_DISTINCT_ORDERED_ID(u8, InterruptPin); class Access; -class DeviceIdentifier { +class EnumerableDeviceIdentifier { public: - DeviceIdentifier(Address address, HardwareID hardware_id, RevisionID revision_id, ClassCode class_code, SubclassCode subclass_code, ProgrammingInterface prog_if, SubsystemID subsystem_id, SubsystemVendorID subsystem_vendor_id, InterruptLine interrupt_line, InterruptPin interrupt_pin, Vector const& capabilities) + EnumerableDeviceIdentifier(Address address, HardwareID hardware_id, RevisionID revision_id, ClassCode class_code, SubclassCode subclass_code, ProgrammingInterface prog_if, SubsystemID subsystem_id, SubsystemVendorID subsystem_vendor_id, InterruptLine interrupt_line, InterruptPin interrupt_pin, Vector const& capabilities) : m_address(address) , m_hardware_id(hardware_id) , m_revision_id(revision_id) @@ -289,7 +288,7 @@ public: m_prog_if = new_progif; } -private: +protected: Address m_address; HardwareID m_hardware_id; @@ -306,6 +305,38 @@ private: Vector m_capabilities; }; +class DeviceIdentifier + : public RefCounted + , public EnumerableDeviceIdentifier { + AK_MAKE_NONCOPYABLE(DeviceIdentifier); + +public: + static ErrorOr> from_enumerable_identifier(EnumerableDeviceIdentifier const& other_identifier); + + Spinlock& operation_lock() { return m_operation_lock; } + Spinlock& operation_lock() const { return m_operation_lock; } + + virtual ~DeviceIdentifier() = default; + +private: + DeviceIdentifier(EnumerableDeviceIdentifier const& other_identifier) + : EnumerableDeviceIdentifier(other_identifier.address(), + other_identifier.hardware_id(), + other_identifier.revision_id(), + other_identifier.class_code(), + other_identifier.subclass_code(), + other_identifier.prog_if(), + other_identifier.subsystem_id(), + other_identifier.subsystem_vendor_id(), + other_identifier.interrupt_line(), + other_identifier.interrupt_pin(), + other_identifier.capabilities()) + { + } + + mutable Spinlock m_operation_lock; +}; + class Domain; class Device; diff --git a/Kernel/Bus/PCI/Device.cpp b/Kernel/Bus/PCI/Device.cpp index 19cc4b04818..6f0149d177c 100644 --- a/Kernel/Bus/PCI/Device.cpp +++ b/Kernel/Bus/PCI/Device.cpp @@ -10,31 +10,31 @@ namespace Kernel::PCI { -Device::Device(Address address) - : m_pci_address(address) +Device::Device(DeviceIdentifier const& pci_identifier) + : m_pci_identifier(pci_identifier) { } bool Device::is_msi_capable() const { return AK::any_of( - PCI::get_device_identifier(pci_address()).capabilities(), + m_pci_identifier->capabilities(), [](auto const& capability) { return capability.id().value() == PCI::Capabilities::ID::MSI; }); } bool Device::is_msix_capable() const { return AK::any_of( - PCI::get_device_identifier(pci_address()).capabilities(), + m_pci_identifier->capabilities(), [](auto const& capability) { return capability.id().value() == PCI::Capabilities::ID::MSIX; }); } void Device::enable_pin_based_interrupts() const { - PCI::enable_interrupt_line(pci_address()); + PCI::enable_interrupt_line(m_pci_identifier); } void Device::disable_pin_based_interrupts() const { - PCI::disable_interrupt_line(pci_address()); + PCI::disable_interrupt_line(m_pci_identifier); } void Device::enable_message_signalled_interrupts() diff --git a/Kernel/Bus/PCI/Device.h b/Kernel/Bus/PCI/Device.h index 61a713b6642..418c3ae3d96 100644 --- a/Kernel/Bus/PCI/Device.h +++ b/Kernel/Bus/PCI/Device.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include #include #include @@ -15,7 +16,7 @@ namespace Kernel::PCI { class Device { public: - Address pci_address() const { return m_pci_address; }; + DeviceIdentifier& device_identifier() const { return *m_pci_identifier; }; virtual ~Device() = default; @@ -34,10 +35,10 @@ public: void disable_extended_message_signalled_interrupts(); protected: - explicit Device(Address pci_address); + explicit Device(DeviceIdentifier const& pci_identifier); private: - Address m_pci_address; + NonnullRefPtr m_pci_identifier; }; template @@ -48,7 +49,7 @@ void dmesgln_pci(Device const& device, AK::CheckedFormatString&& return; if (builder.try_append(fmt.view()).is_error()) return; - AK::VariadicFormatParams variadic_format_params { device.device_name(), device.pci_address(), parameters... }; + AK::VariadicFormatParams variadic_format_params { device.device_name(), device.device_identifier().address(), parameters... }; vdmesgln(builder.string_view(), variadic_format_params); } diff --git a/Kernel/Bus/PCI/DeviceIdentifier.cpp b/Kernel/Bus/PCI/DeviceIdentifier.cpp new file mode 100644 index 00000000000..785dfebff8b --- /dev/null +++ b/Kernel/Bus/PCI/DeviceIdentifier.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2020, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +namespace Kernel::PCI { + +ErrorOr> DeviceIdentifier::from_enumerable_identifier(EnumerableDeviceIdentifier const& other_identifier) +{ + return adopt_nonnull_ref_or_enomem(new (nothrow) DeviceIdentifier(other_identifier)); +} + +} diff --git a/Kernel/Bus/USB/UHCI/UHCIController.cpp b/Kernel/Bus/USB/UHCI/UHCIController.cpp index 78e62ca29d2..c058f8fb4ce 100644 --- a/Kernel/Bus/USB/UHCI/UHCIController.cpp +++ b/Kernel/Bus/USB/UHCI/UHCIController.cpp @@ -75,7 +75,7 @@ ErrorOr> UHCIController::try_to_initialize(PCI ErrorOr UHCIController::initialize() { - dmesgln_pci(*this, "Controller found {} @ {}", PCI::get_hardware_id(pci_address()), pci_address()); + dmesgln_pci(*this, "Controller found {} @ {}", PCI::get_hardware_id(device_identifier()), device_identifier().address()); dmesgln_pci(*this, "I/O base {}", m_registers_io_window); dmesgln_pci(*this, "Interrupt line: {}", interrupt_number()); @@ -87,7 +87,7 @@ ErrorOr UHCIController::initialize() } UNMAP_AFTER_INIT UHCIController::UHCIController(PCI::DeviceIdentifier const& pci_device_identifier, NonnullOwnPtr registers_io_window) - : PCI::Device(pci_device_identifier.address()) + : PCI::Device(const_cast(pci_device_identifier)) , IRQHandler(pci_device_identifier.interrupt_line().value()) , m_registers_io_window(move(registers_io_window)) { diff --git a/Kernel/Bus/VirtIO/Device.cpp b/Kernel/Bus/VirtIO/Device.cpp index 722b6098c12..7f4c1838a97 100644 --- a/Kernel/Bus/VirtIO/Device.cpp +++ b/Kernel/Bus/VirtIO/Device.cpp @@ -88,10 +88,9 @@ static StringView determine_device_class(PCI::DeviceIdentifier const& device_ide UNMAP_AFTER_INIT void Device::initialize() { - auto address = pci_address(); - enable_bus_mastering(pci_address()); + enable_bus_mastering(device_identifier()); - auto capabilities = PCI::get_device_identifier(address).capabilities(); + auto capabilities = device_identifier().capabilities(); for (auto& capability : capabilities) { if (capability.id().value() == PCI::Capabilities::ID::VendorSpecific) { // We have a virtio_pci_cap @@ -126,21 +125,21 @@ UNMAP_AFTER_INIT void Device::initialize() if (m_use_mmio) { for (auto& cfg : m_configs) { - auto mapping_io_window = IOWindow::create_for_pci_device_bar(pci_address(), static_cast(cfg.bar)).release_value_but_fixme_should_propagate_errors(); + auto mapping_io_window = IOWindow::create_for_pci_device_bar(device_identifier(), static_cast(cfg.bar)).release_value_but_fixme_should_propagate_errors(); m_register_bases[cfg.bar] = move(mapping_io_window); } m_common_cfg = get_config(ConfigurationType::Common, 0); m_notify_cfg = get_config(ConfigurationType::Notify, 0); m_isr_cfg = get_config(ConfigurationType::ISR, 0); } else { - auto mapping_io_window = IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR0).release_value_but_fixme_should_propagate_errors(); + auto mapping_io_window = IOWindow::create_for_pci_device_bar(device_identifier(), PCI::HeaderType0BaseRegister::BAR0).release_value_but_fixme_should_propagate_errors(); m_register_bases[0] = move(mapping_io_window); } // Note: We enable interrupts at least after the m_register_bases[0] ptr is // assigned with an IOWindow, to ensure that in case of getting an interrupt // we can access registers from that IO window range. - PCI::enable_interrupt_line(pci_address()); + PCI::enable_interrupt_line(device_identifier()); enable_irq(); reset_device(); @@ -150,11 +149,11 @@ UNMAP_AFTER_INIT void Device::initialize() } UNMAP_AFTER_INIT VirtIO::Device::Device(PCI::DeviceIdentifier const& device_identifier) - : PCI::Device(device_identifier.address()) + : PCI::Device(const_cast(device_identifier)) , IRQHandler(device_identifier.interrupt_line().value()) , m_class_name(VirtIO::determine_device_class(device_identifier)) { - dbgln("{}: Found @ {}", m_class_name, pci_address()); + dbgln("{}: Found @ {}", m_class_name, device_identifier.address()); } void Device::notify_queue(u16 queue_index) diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index 9be59818322..b52696809d1 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -23,6 +23,7 @@ set(KERNEL_SOURCES Bus/PCI/Access.cpp Bus/PCI/API.cpp Bus/PCI/Device.cpp + Bus/PCI/DeviceIdentifier.cpp Bus/USB/UHCI/UHCIController.cpp Bus/USB/UHCI/UHCIRootHub.cpp Bus/USB/USBConfiguration.cpp diff --git a/Kernel/Devices/Audio/AC97.cpp b/Kernel/Devices/Audio/AC97.cpp index a9dff931b09..ab80e4f6112 100644 --- a/Kernel/Devices/Audio/AC97.cpp +++ b/Kernel/Devices/Audio/AC97.cpp @@ -37,7 +37,7 @@ UNMAP_AFTER_INIT ErrorOr> AC97::try_create(PCI::DeviceId } UNMAP_AFTER_INIT AC97::AC97(PCI::DeviceIdentifier const& pci_device_identifier, NonnullOwnPtr pcm_out_channel, NonnullOwnPtr mixer_io_window, NonnullOwnPtr bus_io_window) - : PCI::Device(pci_device_identifier.address()) + : PCI::Device(const_cast(pci_device_identifier)) , IRQHandler(pci_device_identifier.interrupt_line().value()) , m_mixer_io_window(move(mixer_io_window)) , m_bus_io_window(move(bus_io_window)) @@ -50,7 +50,7 @@ UNMAP_AFTER_INIT AC97::~AC97() = default; bool AC97::handle_irq(RegisterState const&) { auto pcm_out_status = m_pcm_out_channel->io_window().read16(AC97Channel::Register::Status); - dbgln_if(AC97_DEBUG, "AC97 @ {}: interrupt received - status: {:#05b}", pci_address(), pcm_out_status); + dbgln_if(AC97_DEBUG, "AC97 @ {}: interrupt received - status: {:#05b}", device_identifier().address(), pcm_out_status); bool is_dma_halted = (pcm_out_status & AudioStatusRegisterFlag::DMAControllerHalted) > 0; bool current_equals_last_valid = (pcm_out_status & AudioStatusRegisterFlag::CurrentEqualsLastValid) > 0; @@ -81,13 +81,13 @@ bool AC97::handle_irq(RegisterState const&) UNMAP_AFTER_INIT ErrorOr AC97::initialize() { - dbgln_if(AC97_DEBUG, "AC97 @ {}: mixer base: {:#04x}", pci_address(), m_mixer_io_window); - dbgln_if(AC97_DEBUG, "AC97 @ {}: bus base: {:#04x}", pci_address(), m_bus_io_window); + dbgln_if(AC97_DEBUG, "AC97 @ {}: mixer base: {:#04x}", device_identifier().address(), m_mixer_io_window); + dbgln_if(AC97_DEBUG, "AC97 @ {}: bus base: {:#04x}", device_identifier().address(), m_bus_io_window); // Read out AC'97 codec revision and vendor auto extended_audio_id = m_mixer_io_window->read16(NativeAudioMixerRegister::ExtendedAudioID); m_codec_revision = static_cast(((extended_audio_id & ExtendedAudioMask::Revision) >> 10) & 0b11); - dbgln_if(AC97_DEBUG, "AC97 @ {}: codec revision {:#02b}", pci_address(), to_underlying(m_codec_revision)); + dbgln_if(AC97_DEBUG, "AC97 @ {}: codec revision {:#02b}", device_identifier().address(), to_underlying(m_codec_revision)); if (m_codec_revision == AC97Revision::Reserved) return ENOTSUP; @@ -97,7 +97,7 @@ UNMAP_AFTER_INIT ErrorOr AC97::initialize() // Bus cold reset, enable interrupts enable_pin_based_interrupts(); - PCI::enable_bus_mastering(pci_address()); + PCI::enable_bus_mastering(device_identifier()); auto control = m_bus_io_window->read32(NativeAudioBusRegister::GlobalControl); control |= GlobalControlFlag::GPIInterruptEnable; control |= GlobalControlFlag::AC97ColdReset; @@ -251,7 +251,7 @@ ErrorOr AC97::write_single_buffer(UserOrKernelBuffer const& data, size_t o if (head_distance < m_output_buffer_page_count) break; - dbgln_if(AC97_DEBUG, "AC97 @ {}: waiting on interrupt - status: {:#05b} CI: {} LVI: {}", pci_address(), pcm_out_status, current_index, last_valid_index); + dbgln_if(AC97_DEBUG, "AC97 @ {}: waiting on interrupt - status: {:#05b} CI: {} LVI: {}", device_identifier().address(), pcm_out_status, current_index, last_valid_index); m_irq_queue.wait_forever("AC97"sv); } while (m_pcm_out_channel->dma_running()); } diff --git a/Kernel/FileSystem/SysFS/Subsystems/Bus/PCI/BusDirectory.cpp b/Kernel/FileSystem/SysFS/Subsystems/Bus/PCI/BusDirectory.cpp index 6d7a883f8e4..a720731bd14 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/Bus/PCI/BusDirectory.cpp +++ b/Kernel/FileSystem/SysFS/Subsystems/Bus/PCI/BusDirectory.cpp @@ -24,7 +24,7 @@ UNMAP_AFTER_INIT PCIBusSysFSDirectory::PCIBusSysFSDirectory() { MUST(m_child_components.with([&](auto& list) -> ErrorOr { MUST(PCI::enumerate([&](PCI::DeviceIdentifier const& device_identifier) { - auto pci_device = PCIDeviceSysFSDirectory::create(*this, device_identifier.address()); + auto pci_device = PCIDeviceSysFSDirectory::create(*this, device_identifier); list.append(pci_device); })); return {}; diff --git a/Kernel/FileSystem/SysFS/Subsystems/Bus/PCI/DeviceAttribute.cpp b/Kernel/FileSystem/SysFS/Subsystems/Bus/PCI/DeviceAttribute.cpp index 5db829d44a1..e238ae84e29 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/Bus/PCI/DeviceAttribute.cpp +++ b/Kernel/FileSystem/SysFS/Subsystems/Bus/PCI/DeviceAttribute.cpp @@ -75,15 +75,16 @@ ErrorOr PCIDeviceAttributeSysFSComponent::read_bytes(off_t offset, size_ ErrorOr> PCIDeviceAttributeSysFSComponent::try_to_generate_buffer() const { OwnPtr value; + SpinlockLocker locker(m_device->device_identifier().operation_lock()); switch (m_field_bytes_width) { case 1: - value = TRY(KString::formatted("{:#x}", PCI::read8(m_device->address(), m_offset))); + value = TRY(KString::formatted("{:#x}", PCI::read8_locked(m_device->device_identifier(), m_offset))); break; case 2: - value = TRY(KString::formatted("{:#x}", PCI::read16(m_device->address(), m_offset))); + value = TRY(KString::formatted("{:#x}", PCI::read16_locked(m_device->device_identifier(), m_offset))); break; case 4: - value = TRY(KString::formatted("{:#x}", PCI::read32(m_device->address(), m_offset))); + value = TRY(KString::formatted("{:#x}", PCI::read32_locked(m_device->device_identifier(), m_offset))); break; default: VERIFY_NOT_REACHED(); diff --git a/Kernel/FileSystem/SysFS/Subsystems/Bus/PCI/DeviceDirectory.cpp b/Kernel/FileSystem/SysFS/Subsystems/Bus/PCI/DeviceDirectory.cpp index 90d0235bee7..111825a6fad 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/Bus/PCI/DeviceDirectory.cpp +++ b/Kernel/FileSystem/SysFS/Subsystems/Bus/PCI/DeviceDirectory.cpp @@ -12,11 +12,12 @@ namespace Kernel { -UNMAP_AFTER_INIT NonnullLockRefPtr PCIDeviceSysFSDirectory::create(SysFSDirectory const& parent_directory, PCI::Address address) +UNMAP_AFTER_INIT NonnullLockRefPtr PCIDeviceSysFSDirectory::create(SysFSDirectory const& parent_directory, PCI::DeviceIdentifier const& device_identifier) { // FIXME: Handle allocation failure gracefully + auto& address = device_identifier.address(); auto device_name = MUST(KString::formatted("{:04x}:{:02x}:{:02x}.{}", address.domain(), address.bus(), address.device(), address.function())); - auto directory = adopt_lock_ref(*new (nothrow) PCIDeviceSysFSDirectory(move(device_name), parent_directory, address)); + auto directory = adopt_lock_ref(*new (nothrow) PCIDeviceSysFSDirectory(move(device_name), parent_directory, device_identifier)); MUST(directory->m_child_components.with([&](auto& list) -> ErrorOr { list.append(PCIDeviceAttributeSysFSComponent::create(*directory, PCI::RegisterOffset::VENDOR_ID, 2)); list.append(PCIDeviceAttributeSysFSComponent::create(*directory, PCI::RegisterOffset::DEVICE_ID, 2)); @@ -38,9 +39,9 @@ UNMAP_AFTER_INIT NonnullLockRefPtr PCIDeviceSysFSDirect return directory; } -UNMAP_AFTER_INIT PCIDeviceSysFSDirectory::PCIDeviceSysFSDirectory(NonnullOwnPtr device_directory_name, SysFSDirectory const& parent_directory, PCI::Address address) +UNMAP_AFTER_INIT PCIDeviceSysFSDirectory::PCIDeviceSysFSDirectory(NonnullOwnPtr device_directory_name, SysFSDirectory const& parent_directory, PCI::DeviceIdentifier const& device_identifier) : SysFSDirectory(parent_directory) - , m_address(address) + , m_device_identifier(device_identifier) , m_device_directory_name(move(device_directory_name)) { } diff --git a/Kernel/FileSystem/SysFS/Subsystems/Bus/PCI/DeviceDirectory.h b/Kernel/FileSystem/SysFS/Subsystems/Bus/PCI/DeviceDirectory.h index 14a7fafff16..c02361d8ef6 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/Bus/PCI/DeviceDirectory.h +++ b/Kernel/FileSystem/SysFS/Subsystems/Bus/PCI/DeviceDirectory.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include #include @@ -14,15 +15,15 @@ namespace Kernel { class PCIDeviceSysFSDirectory final : public SysFSDirectory { public: - static NonnullLockRefPtr create(SysFSDirectory const&, PCI::Address); - PCI::Address const& address() const { return m_address; } + static NonnullLockRefPtr create(SysFSDirectory const&, PCI::DeviceIdentifier const&); + PCI::DeviceIdentifier& device_identifier() const { return *m_device_identifier; } virtual StringView name() const override { return m_device_directory_name->view(); } private: - PCIDeviceSysFSDirectory(NonnullOwnPtr device_directory_name, SysFSDirectory const&, PCI::Address); + PCIDeviceSysFSDirectory(NonnullOwnPtr device_directory_name, SysFSDirectory const&, PCI::DeviceIdentifier const&); - PCI::Address m_address; + NonnullRefPtr m_device_identifier; NonnullOwnPtr m_device_directory_name; }; diff --git a/Kernel/Firmware/ACPI/Parser.cpp b/Kernel/Firmware/ACPI/Parser.cpp index d9045a5e771..21524df6175 100644 --- a/Kernel/Firmware/ACPI/Parser.cpp +++ b/Kernel/Firmware/ACPI/Parser.cpp @@ -290,7 +290,8 @@ void Parser::access_generic_address(Structures::GenericAddressStructure const& s VERIFY_NOT_REACHED(); } VERIFY(structure.access_size != (u8)GenericAddressStructure::AccessSize::Undefined); - PCI::raw_access(pci_address, offset_in_pci_address, (1 << (structure.access_size - 1)), value); + auto& pci_device_identifier = PCI::get_device_identifier(pci_address); + PCI::raw_access(pci_device_identifier, offset_in_pci_address, (1 << (structure.access_size - 1)), value); return; } default: diff --git a/Kernel/Graphics/Bochs/GraphicsAdapter.cpp b/Kernel/Graphics/Bochs/GraphicsAdapter.cpp index 2494c6f4488..3616ba78474 100644 --- a/Kernel/Graphics/Bochs/GraphicsAdapter.cpp +++ b/Kernel/Graphics/Bochs/GraphicsAdapter.cpp @@ -34,13 +34,13 @@ UNMAP_AFTER_INIT ErrorOr BochsGraphicsAdapter::probe(PCI::DeviceIdentifier UNMAP_AFTER_INIT ErrorOr> BochsGraphicsAdapter::create(PCI::DeviceIdentifier const& pci_device_identifier) { - auto adapter = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) BochsGraphicsAdapter(pci_device_identifier.address()))); + auto adapter = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) BochsGraphicsAdapter(pci_device_identifier))); MUST(adapter->initialize_adapter(pci_device_identifier)); return adapter; } -UNMAP_AFTER_INIT BochsGraphicsAdapter::BochsGraphicsAdapter(PCI::Address const& address) - : PCI::Device(address) +UNMAP_AFTER_INIT BochsGraphicsAdapter::BochsGraphicsAdapter(PCI::DeviceIdentifier const& device_identifier) + : PCI::Device(const_cast(device_identifier)) { } @@ -52,20 +52,20 @@ UNMAP_AFTER_INIT ErrorOr BochsGraphicsAdapter::initialize_adapter(PCI::Dev // Note: In non x86-builds, we should never encounter VirtualBox hardware nor Pure Bochs VBE graphics, // so just assume we can use the QEMU BochsVBE-compatible graphics adapter only. - auto bar0_space_size = PCI::get_BAR_space_size(pci_device_identifier.address(), PCI::HeaderType0BaseRegister::BAR0); + auto bar0_space_size = PCI::get_BAR_space_size(pci_device_identifier, PCI::HeaderType0BaseRegister::BAR0); #if ARCH(X86_64) bool virtual_box_hardware = (pci_device_identifier.hardware_id().vendor_id == 0x80ee && pci_device_identifier.hardware_id().device_id == 0xbeef); if (pci_device_identifier.revision_id().value() == 0x0 || virtual_box_hardware) { - m_display_connector = BochsDisplayConnector::must_create(PhysicalAddress(PCI::get_BAR0(pci_device_identifier.address()) & 0xfffffff0), bar0_space_size, virtual_box_hardware); + m_display_connector = BochsDisplayConnector::must_create(PhysicalAddress(PCI::get_BAR0(pci_device_identifier) & 0xfffffff0), bar0_space_size, virtual_box_hardware); } else { - auto registers_mapping = TRY(Memory::map_typed_writable(PhysicalAddress(PCI::get_BAR2(pci_device_identifier.address()) & 0xfffffff0))); + auto registers_mapping = TRY(Memory::map_typed_writable(PhysicalAddress(PCI::get_BAR2(pci_device_identifier) & 0xfffffff0))); VERIFY(registers_mapping.region); - m_display_connector = QEMUDisplayConnector::must_create(PhysicalAddress(PCI::get_BAR0(pci_device_identifier.address()) & 0xfffffff0), bar0_space_size, move(registers_mapping)); + m_display_connector = QEMUDisplayConnector::must_create(PhysicalAddress(PCI::get_BAR0(pci_device_identifier) & 0xfffffff0), bar0_space_size, move(registers_mapping)); } #else auto registers_mapping = TRY(Memory::map_typed_writable(PhysicalAddress(PCI::get_BAR2(pci_device_identifier.address()) & 0xfffffff0))); VERIFY(registers_mapping.region); - m_display_connector = QEMUDisplayConnector::must_create(PhysicalAddress(PCI::get_BAR0(pci_device_identifier.address()) & 0xfffffff0), bar0_space_size, move(registers_mapping)); + m_display_connector = QEMUDisplayConnector::must_create(PhysicalAddress(PCI::get_BAR0(pci_device_identifier) & 0xfffffff0), bar0_space_size, move(registers_mapping)); #endif // Note: According to Gerd Hoffmann - "The linux driver simply does diff --git a/Kernel/Graphics/Bochs/GraphicsAdapter.h b/Kernel/Graphics/Bochs/GraphicsAdapter.h index b865c405538..866070bcf6f 100644 --- a/Kernel/Graphics/Bochs/GraphicsAdapter.h +++ b/Kernel/Graphics/Bochs/GraphicsAdapter.h @@ -32,7 +32,7 @@ public: private: ErrorOr initialize_adapter(PCI::DeviceIdentifier const&); - explicit BochsGraphicsAdapter(PCI::Address const&); + explicit BochsGraphicsAdapter(PCI::DeviceIdentifier const&); LockRefPtr m_display_connector; }; diff --git a/Kernel/Graphics/Intel/NativeGraphicsAdapter.cpp b/Kernel/Graphics/Intel/NativeGraphicsAdapter.cpp index 6e583a0d58e..40e07bd3be4 100644 --- a/Kernel/Graphics/Intel/NativeGraphicsAdapter.cpp +++ b/Kernel/Graphics/Intel/NativeGraphicsAdapter.cpp @@ -33,29 +33,28 @@ ErrorOr IntelNativeGraphicsAdapter::probe(PCI::DeviceIdentifier const& pci ErrorOr> IntelNativeGraphicsAdapter::create(PCI::DeviceIdentifier const& pci_device_identifier) { - auto adapter = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) IntelNativeGraphicsAdapter(pci_device_identifier.address()))); + auto adapter = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) IntelNativeGraphicsAdapter(pci_device_identifier))); TRY(adapter->initialize_adapter()); return adapter; } ErrorOr IntelNativeGraphicsAdapter::initialize_adapter() { - auto address = pci_address(); - dbgln_if(INTEL_GRAPHICS_DEBUG, "Intel Native Graphics Adapter @ {}", address); - auto bar0_space_size = PCI::get_BAR_space_size(address, PCI::HeaderType0BaseRegister::BAR0); + dbgln_if(INTEL_GRAPHICS_DEBUG, "Intel Native Graphics Adapter @ {}", device_identifier().address()); + auto bar0_space_size = PCI::get_BAR_space_size(device_identifier(), PCI::HeaderType0BaseRegister::BAR0); VERIFY(bar0_space_size == 0x80000); - auto bar2_space_size = PCI::get_BAR_space_size(address, PCI::HeaderType0BaseRegister::BAR2); - dmesgln_pci(*this, "MMIO @ {}, space size is {:x} bytes", PhysicalAddress(PCI::get_BAR0(address)), bar0_space_size); - dmesgln_pci(*this, "framebuffer @ {}", PhysicalAddress(PCI::get_BAR2(address))); - PCI::enable_bus_mastering(address); + auto bar2_space_size = PCI::get_BAR_space_size(device_identifier(), PCI::HeaderType0BaseRegister::BAR2); + dmesgln_pci(*this, "MMIO @ {}, space size is {:x} bytes", PhysicalAddress(PCI::get_BAR0(device_identifier())), bar0_space_size); + dmesgln_pci(*this, "framebuffer @ {}", PhysicalAddress(PCI::get_BAR2(device_identifier()))); + PCI::enable_bus_mastering(device_identifier()); - m_display_connector = TRY(IntelNativeDisplayConnector::try_create(PhysicalAddress(PCI::get_BAR2(address) & 0xfffffff0), bar2_space_size, PhysicalAddress(PCI::get_BAR0(address) & 0xfffffff0), bar0_space_size)); + m_display_connector = TRY(IntelNativeDisplayConnector::try_create(PhysicalAddress(PCI::get_BAR2(device_identifier()) & 0xfffffff0), bar2_space_size, PhysicalAddress(PCI::get_BAR0(device_identifier()) & 0xfffffff0), bar0_space_size)); return {}; } -IntelNativeGraphicsAdapter::IntelNativeGraphicsAdapter(PCI::Address address) +IntelNativeGraphicsAdapter::IntelNativeGraphicsAdapter(PCI::DeviceIdentifier const& pci_device_identifier) : GenericGraphicsAdapter() - , PCI::Device(address) + , PCI::Device(const_cast(pci_device_identifier)) { } diff --git a/Kernel/Graphics/Intel/NativeGraphicsAdapter.h b/Kernel/Graphics/Intel/NativeGraphicsAdapter.h index 3cdb170bbc5..0219c637380 100644 --- a/Kernel/Graphics/Intel/NativeGraphicsAdapter.h +++ b/Kernel/Graphics/Intel/NativeGraphicsAdapter.h @@ -30,7 +30,7 @@ public: private: ErrorOr initialize_adapter(); - explicit IntelNativeGraphicsAdapter(PCI::Address); + explicit IntelNativeGraphicsAdapter(PCI::DeviceIdentifier const&); LockRefPtr m_display_connector; }; diff --git a/Kernel/Graphics/VMWare/GraphicsAdapter.cpp b/Kernel/Graphics/VMWare/GraphicsAdapter.cpp index 43f00f3222a..e79c62586ba 100644 --- a/Kernel/Graphics/VMWare/GraphicsAdapter.cpp +++ b/Kernel/Graphics/VMWare/GraphicsAdapter.cpp @@ -36,7 +36,7 @@ ErrorOr> VMWareGraphicsAdapter::create } UNMAP_AFTER_INIT VMWareGraphicsAdapter::VMWareGraphicsAdapter(PCI::DeviceIdentifier const& pci_device_identifier, NonnullOwnPtr registers_io_window) - : PCI::Device(pci_device_identifier.address()) + : PCI::Device(const_cast(pci_device_identifier)) , m_registers_io_window(move(registers_io_window)) { dbgln("VMWare SVGA @ {}, {}", pci_device_identifier.address(), m_registers_io_window); @@ -59,7 +59,7 @@ UNMAP_AFTER_INIT ErrorOr VMWareGraphicsAdapter::negotiate_device_version() { write_io_register(VMWareDisplayRegistersOffset::ID, vmware_svga_version_2_id); auto accepted_version = read_io_register(VMWareDisplayRegistersOffset::ID); - dbgln("VMWare SVGA @ {}: Accepted version {}", pci_address(), accepted_version); + dbgln("VMWare SVGA @ {}: Accepted version {}", device_identifier().address(), accepted_version); if (read_io_register(VMWareDisplayRegistersOffset::ID) == vmware_svga_version_2_id) return {}; return Error::from_errno(ENOTSUP); @@ -69,11 +69,11 @@ UNMAP_AFTER_INIT ErrorOr VMWareGraphicsAdapter::initialize_fifo_registers( { auto framebuffer_size = read_io_register(VMWareDisplayRegistersOffset::FB_SIZE); auto fifo_size = read_io_register(VMWareDisplayRegistersOffset::MEM_SIZE); - auto fifo_physical_address = PhysicalAddress(PCI::get_BAR2(pci_address()) & 0xfffffff0); + auto fifo_physical_address = PhysicalAddress(PCI::get_BAR2(device_identifier()) & 0xfffffff0); - dbgln("VMWare SVGA @ {}: framebuffer size {} bytes, FIFO size {} bytes @ {}", pci_address(), framebuffer_size, fifo_size, fifo_physical_address); + dbgln("VMWare SVGA @ {}: framebuffer size {} bytes, FIFO size {} bytes @ {}", device_identifier().address(), framebuffer_size, fifo_size, fifo_physical_address); if (framebuffer_size < 0x100000 || fifo_size < 0x10000) { - dbgln("VMWare SVGA @ {}: invalid framebuffer or fifo size", pci_address()); + dbgln("VMWare SVGA @ {}: invalid framebuffer or fifo size", device_identifier().address()); return Error::from_errno(ENOTSUP); } @@ -183,9 +183,9 @@ UNMAP_AFTER_INIT ErrorOr VMWareGraphicsAdapter::initialize_adapter() // Note: enable the device by modesetting the primary screen resolution modeset_primary_screen_resolution(640, 480); - auto bar1_space_size = PCI::get_BAR_space_size(pci_address(), PCI::HeaderType0BaseRegister::BAR1); + auto bar1_space_size = PCI::get_BAR_space_size(device_identifier(), PCI::HeaderType0BaseRegister::BAR1); - m_display_connector = VMWareDisplayConnector::must_create(*this, PhysicalAddress(PCI::get_BAR1(pci_address()) & 0xfffffff0), bar1_space_size); + m_display_connector = VMWareDisplayConnector::must_create(*this, PhysicalAddress(PCI::get_BAR1(device_identifier()) & 0xfffffff0), bar1_space_size); TRY(m_display_connector->set_safe_mode_setting()); return {}; } diff --git a/Kernel/IOWindow.cpp b/Kernel/IOWindow.cpp index ef755220db1..d6dda730ae8 100644 --- a/Kernel/IOWindow.cpp +++ b/Kernel/IOWindow.cpp @@ -64,9 +64,9 @@ ErrorOr> IOWindow::create_from_io_window_with_offset(u64 return create_from_io_window_with_offset(offset, m_memory_mapped_range->length - offset); } -ErrorOr> IOWindow::create_for_pci_device_bar(PCI::Address const& pci_address, PCI::HeaderType0BaseRegister pci_bar, u64 space_length) +ErrorOr> IOWindow::create_for_pci_device_bar(PCI::DeviceIdentifier const& pci_device_identifier, PCI::HeaderType0BaseRegister pci_bar, u64 space_length) { - u64 pci_bar_value = PCI::get_BAR(pci_address, pci_bar); + u64 pci_bar_value = PCI::get_BAR(pci_device_identifier, pci_bar); auto pci_bar_space_type = PCI::get_BAR_space_type(pci_bar_value); if (pci_bar_space_type == PCI::BARSpaceType::Memory64BitSpace) { // FIXME: In theory, BAR5 cannot be assigned to 64 bit as it is the last one... @@ -75,11 +75,11 @@ ErrorOr> IOWindow::create_for_pci_device_bar(PCI::Addres if (pci_bar == PCI::HeaderType0BaseRegister::BAR5) { return Error::from_errno(EINVAL); } - u64 next_pci_bar_value = PCI::get_BAR(pci_address, static_cast(to_underlying(pci_bar) + 1)); + u64 next_pci_bar_value = PCI::get_BAR(pci_device_identifier, static_cast(to_underlying(pci_bar) + 1)); pci_bar_value |= next_pci_bar_value << 32; } - auto pci_bar_space_size = PCI::get_BAR_space_size(pci_address, pci_bar); + auto pci_bar_space_size = PCI::get_BAR_space_size(pci_device_identifier, pci_bar); if (pci_bar_space_size < space_length) return Error::from_errno(EIO); @@ -105,21 +105,10 @@ ErrorOr> IOWindow::create_for_pci_device_bar(PCI::Addres return TRY(adopt_nonnull_own_or_enomem(new (nothrow) IOWindow(move(memory_mapped_range)))); } -ErrorOr> IOWindow::create_for_pci_device_bar(PCI::Address const& pci_address, PCI::HeaderType0BaseRegister pci_bar) -{ - u64 pci_bar_space_size = PCI::get_BAR_space_size(pci_address, pci_bar); - return create_for_pci_device_bar(pci_address, pci_bar, pci_bar_space_size); -} - ErrorOr> IOWindow::create_for_pci_device_bar(PCI::DeviceIdentifier const& pci_device_identifier, PCI::HeaderType0BaseRegister pci_bar) { - u64 pci_bar_space_size = PCI::get_BAR_space_size(pci_device_identifier.address(), pci_bar); - return create_for_pci_device_bar(pci_device_identifier.address(), pci_bar, pci_bar_space_size); -} - -ErrorOr> IOWindow::create_for_pci_device_bar(PCI::DeviceIdentifier const& pci_device_identifier, PCI::HeaderType0BaseRegister pci_bar, u64 space_length) -{ - return create_for_pci_device_bar(pci_device_identifier.address(), pci_bar, space_length); + u64 pci_bar_space_size = PCI::get_BAR_space_size(pci_device_identifier, pci_bar); + return create_for_pci_device_bar(pci_device_identifier, pci_bar, pci_bar_space_size); } IOWindow::IOWindow(NonnullOwnPtr> memory_mapped_range) diff --git a/Kernel/IOWindow.h b/Kernel/IOWindow.h index 9dc911f958d..cce8d4a2054 100644 --- a/Kernel/IOWindow.h +++ b/Kernel/IOWindow.h @@ -38,9 +38,6 @@ public: static ErrorOr> create_for_pci_device_bar(PCI::DeviceIdentifier const&, PCI::HeaderType0BaseRegister, u64 space_length); static ErrorOr> create_for_pci_device_bar(PCI::DeviceIdentifier const&, PCI::HeaderType0BaseRegister); - static ErrorOr> create_for_pci_device_bar(PCI::Address const&, PCI::HeaderType0BaseRegister, u64 space_length); - static ErrorOr> create_for_pci_device_bar(PCI::Address const&, PCI::HeaderType0BaseRegister); - ErrorOr> create_from_io_window_with_offset(u64 offset, u64 space_length); ErrorOr> create_from_io_window_with_offset(u64 offset); diff --git a/Kernel/Net/Intel/E1000ENetworkAdapter.cpp b/Kernel/Net/Intel/E1000ENetworkAdapter.cpp index 8c39d0e1334..1c5519fef66 100644 --- a/Kernel/Net/Intel/E1000ENetworkAdapter.cpp +++ b/Kernel/Net/Intel/E1000ENetworkAdapter.cpp @@ -199,7 +199,7 @@ UNMAP_AFTER_INIT ErrorOr> E1000ENetworkAdapter auto rx_descriptors_region = TRY(MM.allocate_contiguous_kernel_region(TRY(Memory::page_round_up(sizeof(e1000_rx_desc) * number_of_rx_descriptors)), "E1000 RX Descriptors"sv, Memory::Region::Access::ReadWrite)); auto tx_descriptors_region = TRY(MM.allocate_contiguous_kernel_region(TRY(Memory::page_round_up(sizeof(e1000_tx_desc) * number_of_tx_descriptors)), "E1000 TX Descriptors"sv, Memory::Region::Access::ReadWrite)); - return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) E1000ENetworkAdapter(pci_device_identifier.address(), + return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) E1000ENetworkAdapter(pci_device_identifier, irq, move(registers_io_window), move(rx_buffer_region), move(tx_buffer_region), @@ -210,8 +210,8 @@ UNMAP_AFTER_INIT ErrorOr> E1000ENetworkAdapter UNMAP_AFTER_INIT ErrorOr E1000ENetworkAdapter::initialize(Badge) { - dmesgln("E1000e: Found @ {}", pci_address()); - enable_bus_mastering(pci_address()); + dmesgln("E1000e: Found @ {}", device_identifier().address()); + enable_bus_mastering(device_identifier()); dmesgln("E1000e: IO base: {}", m_registers_io_window); dmesgln("E1000e: Interrupt line: {}", interrupt_number()); @@ -229,11 +229,11 @@ UNMAP_AFTER_INIT ErrorOr E1000ENetworkAdapter::initialize(Badge registers_io_window, NonnullOwnPtr rx_buffer_region, NonnullOwnPtr tx_buffer_region, NonnullOwnPtr rx_descriptors_region, NonnullOwnPtr tx_descriptors_region, NonnullOwnPtr interface_name) - : E1000NetworkAdapter(address, irq, move(registers_io_window), + : E1000NetworkAdapter(device_identifier, irq, move(registers_io_window), move(rx_buffer_region), move(tx_buffer_region), move(rx_descriptors_region), diff --git a/Kernel/Net/Intel/E1000ENetworkAdapter.h b/Kernel/Net/Intel/E1000ENetworkAdapter.h index 3b902058645..b5d3ae3266c 100644 --- a/Kernel/Net/Intel/E1000ENetworkAdapter.h +++ b/Kernel/Net/Intel/E1000ENetworkAdapter.h @@ -30,7 +30,7 @@ public: virtual StringView purpose() const override { return class_name(); } private: - E1000ENetworkAdapter(PCI::Address, u8 irq, + E1000ENetworkAdapter(PCI::DeviceIdentifier const&, u8 irq, NonnullOwnPtr registers_io_window, NonnullOwnPtr rx_buffer_region, NonnullOwnPtr tx_buffer_region, NonnullOwnPtr rx_descriptors_region, NonnullOwnPtr tx_descriptors_region, NonnullOwnPtr); diff --git a/Kernel/Net/Intel/E1000NetworkAdapter.cpp b/Kernel/Net/Intel/E1000NetworkAdapter.cpp index a256db16f88..af3c8309426 100644 --- a/Kernel/Net/Intel/E1000NetworkAdapter.cpp +++ b/Kernel/Net/Intel/E1000NetworkAdapter.cpp @@ -177,7 +177,7 @@ UNMAP_AFTER_INIT ErrorOr> E1000NetworkAdapter: auto rx_descriptors_region = TRY(MM.allocate_contiguous_kernel_region(TRY(Memory::page_round_up(sizeof(e1000_rx_desc) * number_of_rx_descriptors)), "E1000 RX Descriptors"sv, Memory::Region::Access::ReadWrite)); auto tx_descriptors_region = TRY(MM.allocate_contiguous_kernel_region(TRY(Memory::page_round_up(sizeof(e1000_tx_desc) * number_of_tx_descriptors)), "E1000 TX Descriptors"sv, Memory::Region::Access::ReadWrite)); - return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) E1000NetworkAdapter(pci_device_identifier.address(), + return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) E1000NetworkAdapter(pci_device_identifier, irq, move(registers_io_window), move(rx_buffer_region), move(tx_buffer_region), @@ -188,9 +188,9 @@ UNMAP_AFTER_INIT ErrorOr> E1000NetworkAdapter: UNMAP_AFTER_INIT ErrorOr E1000NetworkAdapter::initialize(Badge) { - dmesgln_pci(*this, "Found @ {}", pci_address()); + dmesgln_pci(*this, "Found @ {}", device_identifier().address()); - enable_bus_mastering(pci_address()); + enable_bus_mastering(device_identifier()); dmesgln_pci(*this, "IO base: {}", m_registers_io_window); dmesgln_pci(*this, "Interrupt line: {}", interrupt_number()); @@ -225,12 +225,12 @@ UNMAP_AFTER_INIT void E1000NetworkAdapter::setup_interrupts() enable_irq(); } -UNMAP_AFTER_INIT E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address address, u8 irq, +UNMAP_AFTER_INIT E1000NetworkAdapter::E1000NetworkAdapter(PCI::DeviceIdentifier const& device_identifier, u8 irq, NonnullOwnPtr registers_io_window, NonnullOwnPtr rx_buffer_region, NonnullOwnPtr tx_buffer_region, NonnullOwnPtr rx_descriptors_region, NonnullOwnPtr tx_descriptors_region, NonnullOwnPtr interface_name) : NetworkAdapter(move(interface_name)) - , PCI::Device(address) + , PCI::Device(device_identifier) , IRQHandler(irq) , m_registers_io_window(move(registers_io_window)) , m_rx_descriptors_region(move(rx_descriptors_region)) diff --git a/Kernel/Net/Intel/E1000NetworkAdapter.h b/Kernel/Net/Intel/E1000NetworkAdapter.h index e5b4e4a305d..a83a0bb0e89 100644 --- a/Kernel/Net/Intel/E1000NetworkAdapter.h +++ b/Kernel/Net/Intel/E1000NetworkAdapter.h @@ -42,7 +42,7 @@ protected: void setup_interrupts(); void setup_link(); - E1000NetworkAdapter(PCI::Address, u8 irq, + E1000NetworkAdapter(PCI::DeviceIdentifier const&, u8 irq, NonnullOwnPtr registers_io_window, NonnullOwnPtr rx_buffer_region, NonnullOwnPtr tx_buffer_region, NonnullOwnPtr rx_descriptors_region, NonnullOwnPtr tx_descriptors_region, NonnullOwnPtr); diff --git a/Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp b/Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp index 92dc5a97c26..4d74da54d8e 100644 --- a/Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp +++ b/Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp @@ -196,7 +196,7 @@ UNMAP_AFTER_INIT ErrorOr> RTL8168NetworkAdapte u8 irq = pci_device_identifier.interrupt_line().value(); auto interface_name = TRY(NetworkingManagement::generate_interface_name_from_pci_address(pci_device_identifier)); auto registers_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_device_identifier, PCI::HeaderType0BaseRegister::BAR0)); - return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) RTL8168NetworkAdapter(pci_device_identifier.address(), irq, move(registers_io_window), move(interface_name)))); + return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) RTL8168NetworkAdapter(pci_device_identifier, irq, move(registers_io_window), move(interface_name)))); } bool RTL8168NetworkAdapter::determine_supported_version() const @@ -244,15 +244,15 @@ bool RTL8168NetworkAdapter::determine_supported_version() const } } -UNMAP_AFTER_INIT RTL8168NetworkAdapter::RTL8168NetworkAdapter(PCI::Address address, u8 irq, NonnullOwnPtr registers_io_window, NonnullOwnPtr interface_name) +UNMAP_AFTER_INIT RTL8168NetworkAdapter::RTL8168NetworkAdapter(PCI::DeviceIdentifier const& device_identifier, u8 irq, NonnullOwnPtr registers_io_window, NonnullOwnPtr interface_name) : NetworkAdapter(move(interface_name)) - , PCI::Device(address) + , PCI::Device(device_identifier) , IRQHandler(irq) , m_registers_io_window(move(registers_io_window)) , m_rx_descriptors_region(MM.allocate_contiguous_kernel_region(Memory::page_round_up(sizeof(TXDescriptor) * (number_of_rx_descriptors + 1)).release_value_but_fixme_should_propagate_errors(), "RTL8168 RX"sv, Memory::Region::Access::ReadWrite).release_value()) , m_tx_descriptors_region(MM.allocate_contiguous_kernel_region(Memory::page_round_up(sizeof(RXDescriptor) * (number_of_tx_descriptors + 1)).release_value_but_fixme_should_propagate_errors(), "RTL8168 TX"sv, Memory::Region::Access::ReadWrite).release_value()) { - dmesgln_pci(*this, "Found @ {}", pci_address()); + dmesgln_pci(*this, "Found @ {}", device_identifier.address()); dmesgln_pci(*this, "I/O port base: {}", m_registers_io_window); } @@ -330,7 +330,7 @@ UNMAP_AFTER_INIT ErrorOr RTL8168NetworkAdapter::initialize(Badge registers_io_window, NonnullOwnPtr); + RTL8168NetworkAdapter(PCI::DeviceIdentifier const&, u8 irq, NonnullOwnPtr registers_io_window, NonnullOwnPtr); virtual bool handle_irq(RegisterState const&) override; virtual StringView class_name() const override { return "RTL8168NetworkAdapter"sv; } diff --git a/Kernel/Storage/ATA/AHCI/Controller.cpp b/Kernel/Storage/ATA/AHCI/Controller.cpp index d9866ff6630..13f8ef066c7 100644 --- a/Kernel/Storage/ATA/AHCI/Controller.cpp +++ b/Kernel/Storage/ATA/AHCI/Controller.cpp @@ -27,12 +27,12 @@ UNMAP_AFTER_INIT NonnullLockRefPtr AHCIController::initialize(PC bool AHCIController::reset() { - dmesgln_pci(*this, "{}: AHCI controller reset", pci_address()); + dmesgln_pci(*this, "{}: AHCI controller reset", device_identifier().address()); { SpinlockLocker locker(m_hba_control_lock); hba().control_regs.ghc = 1; - dbgln_if(AHCI_DEBUG, "{}: AHCI Controller reset", pci_address()); + dbgln_if(AHCI_DEBUG, "{}: AHCI Controller reset", device_identifier().address()); full_memory_barrier(); size_t retry = 0; @@ -111,7 +111,7 @@ volatile AHCI::HBA& AHCIController::hba() const UNMAP_AFTER_INIT AHCIController::AHCIController(PCI::DeviceIdentifier const& pci_device_identifier) : ATAController() - , PCI::Device(pci_device_identifier.address()) + , PCI::Device(const_cast(pci_device_identifier)) , m_hba_region(default_hba_region()) , m_hba_capabilities(capabilities()) { @@ -122,7 +122,7 @@ AHCI::HBADefinedCapabilities AHCIController::capabilities() const u32 capabilities = hba().control_regs.cap; u32 extended_capabilities = hba().control_regs.cap2; - dbgln_if(AHCI_DEBUG, "{}: AHCI Controller Capabilities = {:#08x}, Extended Capabilities = {:#08x}", pci_address(), capabilities, extended_capabilities); + dbgln_if(AHCI_DEBUG, "{}: AHCI Controller Capabilities = {:#08x}, Extended Capabilities = {:#08x}", device_identifier().address(), capabilities, extended_capabilities); return (AHCI::HBADefinedCapabilities) { (capabilities & 0b11111) + 1, @@ -156,7 +156,7 @@ AHCI::HBADefinedCapabilities AHCIController::capabilities() const UNMAP_AFTER_INIT NonnullOwnPtr AHCIController::default_hba_region() const { - return MM.allocate_kernel_region(PhysicalAddress(PCI::get_BAR5(pci_address())).page_base(), Memory::page_round_up(sizeof(AHCI::HBA)).release_value_but_fixme_should_propagate_errors(), "AHCI HBA"sv, Memory::Region::Access::ReadWrite).release_value(); + return MM.allocate_kernel_region(PhysicalAddress(PCI::get_BAR5(device_identifier())).page_base(), Memory::page_round_up(sizeof(AHCI::HBA)).release_value_but_fixme_should_propagate_errors(), "AHCI HBA"sv, Memory::Region::Access::ReadWrite).release_value(); } AHCIController::~AHCIController() = default; @@ -166,15 +166,15 @@ UNMAP_AFTER_INIT void AHCIController::initialize_hba(PCI::DeviceIdentifier const u32 version = hba().control_regs.version; hba().control_regs.ghc = 0x80000000; // Ensure that HBA knows we are AHCI aware. - PCI::enable_interrupt_line(pci_address()); - PCI::enable_bus_mastering(pci_address()); + PCI::enable_interrupt_line(device_identifier()); + PCI::enable_bus_mastering(device_identifier()); enable_global_interrupts(); auto implemented_ports = AHCI::MaskedBitField((u32 volatile&)(hba().control_regs.pi)); m_irq_handler = AHCIInterruptHandler::create(*this, pci_device_identifier.interrupt_line().value(), implemented_ports).release_value_but_fixme_should_propagate_errors(); reset(); - dbgln_if(AHCI_DEBUG, "{}: AHCI Controller Version = {:#08x}", pci_address(), version); - dbgln("{}: AHCI command list entries count - {}", pci_address(), m_hba_capabilities.max_command_list_entries_count); + dbgln_if(AHCI_DEBUG, "{}: AHCI Controller Version = {:#08x}", device_identifier().address(), version); + dbgln("{}: AHCI command list entries count - {}", device_identifier().address(), m_hba_capabilities.max_command_list_entries_count); } void AHCIController::handle_interrupt_for_port(Badge, u32 port_index) const diff --git a/Kernel/Storage/ATA/AHCI/Port.cpp b/Kernel/Storage/ATA/AHCI/Port.cpp index 776d1d125e5..042ea248adf 100644 --- a/Kernel/Storage/ATA/AHCI/Port.cpp +++ b/Kernel/Storage/ATA/AHCI/Port.cpp @@ -187,8 +187,8 @@ void AHCIPort::recover_from_fatal_error() return; } - dmesgln("{}: AHCI Port {} fatal error, shutting down!", controller->pci_address(), representative_port_index()); - dmesgln("{}: AHCI Port {} fatal error, SError {}", controller->pci_address(), representative_port_index(), (u32)m_port_registers.serr); + dmesgln("{}: AHCI Port {} fatal error, shutting down!", controller->device_identifier().address(), representative_port_index()); + dmesgln("{}: AHCI Port {} fatal error, SError {}", controller->device_identifier().address(), representative_port_index(), (u32)m_port_registers.serr); stop_command_list_processing(); stop_fis_receiving(); m_interrupt_enable.clear(); diff --git a/Kernel/Storage/NVMe/NVMeController.cpp b/Kernel/Storage/NVMe/NVMeController.cpp index e1151f57256..e5752380af5 100644 --- a/Kernel/Storage/NVMe/NVMeController.cpp +++ b/Kernel/Storage/NVMe/NVMeController.cpp @@ -27,9 +27,8 @@ UNMAP_AFTER_INIT ErrorOr> NVMeController::try_ } UNMAP_AFTER_INIT NVMeController::NVMeController(const PCI::DeviceIdentifier& device_identifier, u32 hardware_relative_controller_id) - : PCI::Device(device_identifier.address()) + : PCI::Device(const_cast(device_identifier)) , StorageController(hardware_relative_controller_id) - , m_pci_device_id(device_identifier) { } @@ -37,11 +36,11 @@ UNMAP_AFTER_INIT ErrorOr NVMeController::initialize(bool is_queue_polled) { // Nr of queues = one queue per core auto nr_of_queues = Processor::count(); - auto irq = is_queue_polled ? Optional {} : m_pci_device_id.interrupt_line().value(); + auto irq = is_queue_polled ? Optional {} : device_identifier().interrupt_line().value(); - PCI::enable_memory_space(m_pci_device_id.address()); - PCI::enable_bus_mastering(m_pci_device_id.address()); - m_bar = PCI::get_BAR0(m_pci_device_id.address()) & BAR_ADDR_MASK; + PCI::enable_memory_space(device_identifier()); + PCI::enable_bus_mastering(device_identifier()); + m_bar = PCI::get_BAR0(device_identifier()) & BAR_ADDR_MASK; static_assert(sizeof(ControllerRegister) == REG_SQ0TDBL_START); static_assert(sizeof(NVMeSubmission) == (1 << SQ_WIDTH)); diff --git a/Kernel/Storage/NVMe/NVMeController.h b/Kernel/Storage/NVMe/NVMeController.h index 39087dc5278..8c51bf438d4 100644 --- a/Kernel/Storage/NVMe/NVMeController.h +++ b/Kernel/Storage/NVMe/NVMeController.h @@ -69,7 +69,6 @@ private: bool wait_for_ready(bool); private: - PCI::DeviceIdentifier m_pci_device_id; LockRefPtr m_admin_queue; NonnullLockRefPtrVector m_queues; NonnullLockRefPtrVector m_namespaces; diff --git a/Kernel/Storage/StorageManagement.cpp b/Kernel/Storage/StorageManagement.cpp index 03aee4c8fa5..55b444f7fd6 100644 --- a/Kernel/Storage/StorageManagement.cpp +++ b/Kernel/Storage/StorageManagement.cpp @@ -77,30 +77,21 @@ UNMAP_AFTER_INIT void StorageManagement::enumerate_pci_controllers(bool force_pi using SubclassID = PCI::MassStorage::SubclassID; if (!kernel_command_line().disable_physical_storage()) { + // NOTE: Search for VMD devices before actually searching for storage controllers + // because the VMD device is only a bridge to such (NVMe) controllers. + MUST(PCI::enumerate([&](PCI::DeviceIdentifier const& device_identifier) -> void { + constexpr PCI::HardwareID vmd_device = { 0x8086, 0x9a0b }; + if (device_identifier.hardware_id() == vmd_device) { + auto controller = PCI::VolumeManagementDevice::must_create(device_identifier); + MUST(PCI::Access::the().add_host_controller_and_scan_for_devices(move(controller))); + } + })); MUST(PCI::enumerate([&](PCI::DeviceIdentifier const& device_identifier) -> void { if (device_identifier.class_code().value() != to_underlying(PCI::ClassID::MassStorage)) { return; } - { - constexpr PCI::HardwareID vmd_device = { 0x8086, 0x9a0b }; - if (device_identifier.hardware_id() == vmd_device) { - auto controller = PCI::VolumeManagementDevice::must_create(device_identifier); - MUST(PCI::Access::the().add_host_controller_and_enumerate_attached_devices(move(controller), [this, nvme_poll](PCI::DeviceIdentifier const& device_identifier) -> void { - auto subclass_code = static_cast(device_identifier.subclass_code().value()); - if (subclass_code == SubclassID::NVMeController) { - auto controller = NVMeController::try_initialize(device_identifier, nvme_poll); - if (controller.is_error()) { - dmesgln("Unable to initialize NVMe controller: {}", controller.error()); - } else { - m_controllers.append(controller.release_value()); - } - } - })); - } - } - auto subclass_code = static_cast(device_identifier.subclass_code().value()); #if ARCH(X86_64) if (subclass_code == SubclassID::IDEController && kernel_command_line().is_ide_enabled()) {