diff options
author | Liav A <liavalb@gmail.com> | 2022-09-02 13:41:48 +0300 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-09-20 18:43:05 +0100 |
commit | 1596ee241ffcbdbabf77f93b5132a782ae730923 (patch) | |
tree | 75a91a52c01243b3c59b905cbc863369eb2c9a6d | |
parent | a02c9c956926bfacd8973624b52573606e9b5341 (diff) | |
download | serenity-1596ee241ffcbdbabf77f93b5132a782ae730923.zip |
Kernel/PCI: Move IO based HostBridge code to x86 arch-specific directory
The simple PCI::HostBridge class implements access to the PCI
configuration space by using x86 IO instructions. Therefore, it should
be put in the Arch/x86/PCI directory so it can be easily omitted for
non-x86 builds.
-rw-r--r-- | Kernel/Arch/x86/PCI/Controller/HostBridge.cpp | 62 | ||||
-rw-r--r-- | Kernel/Arch/x86/PCI/Controller/HostBridge.h (renamed from Kernel/Bus/PCI/Controller/HostBridge.h) | 17 | ||||
-rw-r--r-- | Kernel/Bus/PCI/Access.cpp | 7 | ||||
-rw-r--r-- | Kernel/Bus/PCI/Access.h | 4 | ||||
-rw-r--r-- | Kernel/Bus/PCI/Controller/HostController.cpp (renamed from Kernel/Bus/PCI/Controller/HostBridge.cpp) | 82 | ||||
-rw-r--r-- | Kernel/Bus/PCI/Controller/HostController.h | 21 | ||||
-rw-r--r-- | Kernel/Bus/PCI/Controller/MemoryBackedHostBridge.cpp | 2 | ||||
-rw-r--r-- | Kernel/Bus/PCI/Controller/MemoryBackedHostBridge.h | 4 | ||||
-rw-r--r-- | Kernel/CMakeLists.txt | 4 |
9 files changed, 113 insertions, 90 deletions
diff --git a/Kernel/Arch/x86/PCI/Controller/HostBridge.cpp b/Kernel/Arch/x86/PCI/Controller/HostBridge.cpp new file mode 100644 index 0000000000..81c7e34444 --- /dev/null +++ b/Kernel/Arch/x86/PCI/Controller/HostBridge.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <Kernel/Arch/x86/IO.h> +#include <Kernel/Arch/x86/PCI/Controller/HostBridge.h> +#include <Kernel/Bus/PCI/Access.h> +#include <Kernel/Sections.h> + +namespace Kernel::PCI { + +NonnullOwnPtr<HostBridge> HostBridge::must_create_with_io_access() +{ + PCI::Domain domain { 0, 0, 0xff }; + return adopt_own_if_nonnull(new (nothrow) HostBridge(domain)).release_nonnull(); +} + +HostBridge::HostBridge(PCI::Domain const& domain) + : HostController(domain) +{ +} + +static u32 io_address_for_pci_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u8 field) +{ + return 0x80000000u | (bus.value() << 16u) | (device.value() << 11u) | (function.value() << 8u) | (field & 0xfc); +} + +void HostBridge::write8_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field, u8 value) +{ + IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field)); + IO::out8(PCI::value_port + (field & 3), value); +} +void HostBridge::write16_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field, u16 value) +{ + IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field)); + IO::out16(PCI::value_port + (field & 2), value); +} +void HostBridge::write32_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field, u32 value) +{ + IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field)); + IO::out32(PCI::value_port, value); +} + +u8 HostBridge::read8_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field) +{ + IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field)); + return IO::in8(PCI::value_port + (field & 3)); +} +u16 HostBridge::read16_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field) +{ + IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field)); + return IO::in16(PCI::value_port + (field & 2)); +} +u32 HostBridge::read32_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field) +{ + IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field)); + return IO::in32(PCI::value_port); +} + +} diff --git a/Kernel/Bus/PCI/Controller/HostBridge.h b/Kernel/Arch/x86/PCI/Controller/HostBridge.h index 2ba235ba89..32705ea565 100644 --- a/Kernel/Bus/PCI/Controller/HostBridge.h +++ b/Kernel/Arch/x86/PCI/Controller/HostBridge.h @@ -27,23 +27,8 @@ public: virtual u16 read16_field(BusNumber, DeviceNumber, FunctionNumber, u32 field) override; virtual u32 read32_field(BusNumber, DeviceNumber, FunctionNumber, u32 field) override; -protected: - explicit HostBridge(PCI::Domain const&); - private: - virtual void enumerate_attached_devices(Function<IterationDecision(DeviceIdentifier)> callback) override; - - Bitmap m_enumerated_buses; - - u8 read8_field(BusNumber, DeviceNumber, FunctionNumber, RegisterOffset field); - u16 read16_field(BusNumber, DeviceNumber, FunctionNumber, RegisterOffset field); - - Optional<u8> get_capabilities_pointer_for_function(BusNumber, DeviceNumber, FunctionNumber); - Vector<Capability> get_capabilities_for_function(BusNumber, DeviceNumber, FunctionNumber); - - void enumerate_bus(Function<IterationDecision(DeviceIdentifier)> const& callback, BusNumber, bool recursive); - void enumerate_functions(Function<IterationDecision(DeviceIdentifier)> const& callback, BusNumber, DeviceNumber, FunctionNumber, bool recursive); - void enumerate_device(Function<IterationDecision(DeviceIdentifier)> const& callback, BusNumber bus, DeviceNumber device, bool recursive); + explicit HostBridge(PCI::Domain const&); }; } diff --git a/Kernel/Bus/PCI/Access.cpp b/Kernel/Bus/PCI/Access.cpp index 22b2ff1ea2..4c89d5c6b3 100644 --- a/Kernel/Bus/PCI/Access.cpp +++ b/Kernel/Bus/PCI/Access.cpp @@ -7,9 +7,10 @@ #include <AK/ByteReader.h> #include <AK/Error.h> #include <AK/HashTable.h> -#include <Kernel/Arch/x86/IO.h> +#if ARCH(I386) || ARCH(X86_64) +# include <Kernel/Arch/x86/PCI/Controller/HostBridge.h> +#endif #include <Kernel/Bus/PCI/Access.h> -#include <Kernel/Bus/PCI/Controller/HostBridge.h> #include <Kernel/Bus/PCI/Controller/MemoryBackedHostBridge.h> #include <Kernel/Bus/PCI/Initializer.h> #include <Kernel/Debug.h> @@ -104,6 +105,7 @@ UNMAP_AFTER_INIT bool Access::initialize_for_multiple_pci_domains(PhysicalAddres return true; } +#if ARCH(I386) || ARCH(X86_64) UNMAP_AFTER_INIT bool Access::initialize_for_one_pci_domain() { VERIFY(!Access::is_initialized()); @@ -114,6 +116,7 @@ UNMAP_AFTER_INIT bool Access::initialize_for_one_pci_domain() dbgln_if(PCI_DEBUG, "PCI: access for one PCI domain initialised."); return true; } +#endif ErrorOr<void> Access::add_host_controller_and_enumerate_attached_devices(NonnullOwnPtr<HostController> controller, Function<void(DeviceIdentifier const&)> callback) { diff --git a/Kernel/Bus/PCI/Access.h b/Kernel/Bus/PCI/Access.h index 14b0d40123..7f91d50e4e 100644 --- a/Kernel/Bus/PCI/Access.h +++ b/Kernel/Bus/PCI/Access.h @@ -16,11 +16,13 @@ namespace Kernel::PCI { -class HostBridge; class Access { public: static bool initialize_for_multiple_pci_domains(PhysicalAddress mcfg_table); + +#if ARCH(I386) || ARCH(X86_64) static bool initialize_for_one_pci_domain(); +#endif ErrorOr<void> fast_enumerate(Function<void(DeviceIdentifier const&)>&) const; void rescan_hardware(); diff --git a/Kernel/Bus/PCI/Controller/HostBridge.cpp b/Kernel/Bus/PCI/Controller/HostController.cpp index 6767967262..81754c2cc5 100644 --- a/Kernel/Bus/PCI/Controller/HostBridge.cpp +++ b/Kernel/Bus/PCI/Controller/HostController.cpp @@ -4,26 +4,21 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include <Kernel/Arch/x86/IO.h> +#include <AK/Format.h> #include <Kernel/Bus/PCI/Access.h> -#include <Kernel/Bus/PCI/Controller/HostBridge.h> +#include <Kernel/Bus/PCI/Controller/HostController.h> +#include <Kernel/Bus/PCI/Definitions.h> #include <Kernel/Sections.h> namespace Kernel::PCI { -NonnullOwnPtr<HostBridge> HostBridge::must_create_with_io_access() -{ - PCI::Domain domain { 0, 0, 0xff }; - return adopt_own_if_nonnull(new (nothrow) HostBridge(domain)).release_nonnull(); -} - -HostBridge::HostBridge(PCI::Domain const& domain) - : HostController(domain) +HostController::HostController(PCI::Domain const& domain) + : m_domain(domain) , m_enumerated_buses(Bitmap::try_create(256, false).release_value_but_fixme_should_propagate_errors()) { } -UNMAP_AFTER_INIT Optional<u8> HostBridge::get_capabilities_pointer_for_function(BusNumber bus, DeviceNumber device, FunctionNumber function) +UNMAP_AFTER_INIT Optional<u8> HostController::get_capabilities_pointer_for_function(BusNumber bus, DeviceNumber device, FunctionNumber function) { if (read16_field(bus, device, function, PCI::RegisterOffset::STATUS) & (1 << 4)) { return read8_field(bus, device, function, PCI::RegisterOffset::CAPABILITIES_POINTER); @@ -31,7 +26,7 @@ UNMAP_AFTER_INIT Optional<u8> HostBridge::get_capabilities_pointer_for_function( return {}; } -UNMAP_AFTER_INIT Vector<Capability> HostBridge::get_capabilities_for_function(BusNumber bus, DeviceNumber device, FunctionNumber function) +UNMAP_AFTER_INIT Vector<Capability> HostController::get_capabilities_for_function(BusNumber bus, DeviceNumber device, FunctionNumber function) { auto capabilities_pointer = get_capabilities_pointer_for_function(bus, device, function); if (!capabilities_pointer.has_value()) { @@ -50,7 +45,16 @@ UNMAP_AFTER_INIT Vector<Capability> HostBridge::get_capabilities_for_function(Bu return capabilities; } -UNMAP_AFTER_INIT void HostBridge::enumerate_functions(Function<IterationDecision(DeviceIdentifier)> const& callback, BusNumber bus, DeviceNumber device, FunctionNumber function, bool recursive_search_into_bridges) +u8 HostController::read8_field(BusNumber bus, DeviceNumber device, FunctionNumber function, PCI::RegisterOffset field) +{ + return read8_field(bus, device, function, to_underlying(field)); +} +u16 HostController::read16_field(BusNumber bus, DeviceNumber device, FunctionNumber function, PCI::RegisterOffset field) +{ + return read16_field(bus, device, function, to_underlying(field)); +} + +UNMAP_AFTER_INIT void HostController::enumerate_functions(Function<IterationDecision(DeviceIdentifier)> 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()); @@ -79,7 +83,7 @@ UNMAP_AFTER_INIT void HostBridge::enumerate_functions(Function<IterationDecision } } -UNMAP_AFTER_INIT void HostBridge::enumerate_device(Function<IterationDecision(DeviceIdentifier)> const& callback, BusNumber bus, DeviceNumber device, bool recursive_search_into_bridges) +UNMAP_AFTER_INIT void HostController::enumerate_device(Function<IterationDecision(DeviceIdentifier)> 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) @@ -93,14 +97,14 @@ UNMAP_AFTER_INIT void HostBridge::enumerate_device(Function<IterationDecision(De } } -UNMAP_AFTER_INIT void HostBridge::enumerate_bus(Function<IterationDecision(DeviceIdentifier)> const& callback, BusNumber bus, bool recursive_search_into_bridges) +UNMAP_AFTER_INIT void HostController::enumerate_bus(Function<IterationDecision(DeviceIdentifier)> 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 HostBridge::enumerate_attached_devices(Function<IterationDecision(DeviceIdentifier)> callback) +UNMAP_AFTER_INIT void HostController::enumerate_attached_devices(Function<IterationDecision(DeviceIdentifier)> callback) { VERIFY(Access::the().access_lock().is_locked()); VERIFY(Access::the().scan_lock().is_locked()); @@ -129,50 +133,4 @@ UNMAP_AFTER_INIT void HostBridge::enumerate_attached_devices(Function<IterationD } } -static u32 io_address_for_pci_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u8 field) -{ - return 0x80000000u | (bus.value() << 16u) | (device.value() << 11u) | (function.value() << 8u) | (field & 0xfc); -} - -void HostBridge::write8_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field, u8 value) -{ - IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field)); - IO::out8(PCI::value_port + (field & 3), value); -} -void HostBridge::write16_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field, u16 value) -{ - IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field)); - IO::out16(PCI::value_port + (field & 2), value); -} -void HostBridge::write32_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field, u32 value) -{ - IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field)); - IO::out32(PCI::value_port, value); -} - -u8 HostBridge::read8_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field) -{ - IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field)); - return IO::in8(PCI::value_port + (field & 3)); -} -u16 HostBridge::read16_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field) -{ - IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field)); - return IO::in16(PCI::value_port + (field & 2)); -} -u32 HostBridge::read32_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field) -{ - IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field)); - return IO::in32(PCI::value_port); -} - -u8 HostBridge::read8_field(BusNumber bus, DeviceNumber device, FunctionNumber function, PCI::RegisterOffset field) -{ - return read8_field(bus, device, function, to_underlying(field)); -} -u16 HostBridge::read16_field(BusNumber bus, DeviceNumber device, FunctionNumber function, PCI::RegisterOffset field) -{ - return read16_field(bus, device, function, to_underlying(field)); -} - } diff --git a/Kernel/Bus/PCI/Controller/HostController.h b/Kernel/Bus/PCI/Controller/HostController.h index 512e08e446..e21596c14f 100644 --- a/Kernel/Bus/PCI/Controller/HostController.h +++ b/Kernel/Bus/PCI/Controller/HostController.h @@ -31,15 +31,26 @@ public: u32 domain_number() const { return m_domain.domain_number(); } - virtual void enumerate_attached_devices(Function<IterationDecision(DeviceIdentifier)> callback) = 0; + void enumerate_attached_devices(Function<IterationDecision(DeviceIdentifier)> callback); + +private: + void enumerate_bus(Function<IterationDecision(DeviceIdentifier)> const& callback, BusNumber, bool recursive); + void enumerate_functions(Function<IterationDecision(DeviceIdentifier)> const& callback, BusNumber, DeviceNumber, FunctionNumber, bool recursive); + void enumerate_device(Function<IterationDecision(DeviceIdentifier)> const& callback, BusNumber bus, DeviceNumber device, bool recursive); + + u8 read8_field(BusNumber, DeviceNumber, FunctionNumber, RegisterOffset field); + u16 read16_field(BusNumber, DeviceNumber, FunctionNumber, RegisterOffset field); + + Optional<u8> get_capabilities_pointer_for_function(BusNumber, DeviceNumber, FunctionNumber); + Vector<Capability> get_capabilities_for_function(BusNumber, DeviceNumber, FunctionNumber); protected: - explicit HostController(PCI::Domain const& domain) - : m_domain(domain) - { - } + explicit HostController(PCI::Domain const& domain); const PCI::Domain m_domain; + +private: + Bitmap m_enumerated_buses; }; } diff --git a/Kernel/Bus/PCI/Controller/MemoryBackedHostBridge.cpp b/Kernel/Bus/PCI/Controller/MemoryBackedHostBridge.cpp index 41bb7991df..8fd4a3c979 100644 --- a/Kernel/Bus/PCI/Controller/MemoryBackedHostBridge.cpp +++ b/Kernel/Bus/PCI/Controller/MemoryBackedHostBridge.cpp @@ -17,7 +17,7 @@ NonnullOwnPtr<MemoryBackedHostBridge> MemoryBackedHostBridge::must_create(Domain } MemoryBackedHostBridge::MemoryBackedHostBridge(PCI::Domain const& domain, PhysicalAddress start_address) - : HostBridge(domain) + : HostController(domain) , m_start_address(start_address) { } diff --git a/Kernel/Bus/PCI/Controller/MemoryBackedHostBridge.h b/Kernel/Bus/PCI/Controller/MemoryBackedHostBridge.h index 1d0edebd7e..182d82308d 100644 --- a/Kernel/Bus/PCI/Controller/MemoryBackedHostBridge.h +++ b/Kernel/Bus/PCI/Controller/MemoryBackedHostBridge.h @@ -8,12 +8,12 @@ #include <AK/Bitmap.h> #include <AK/Vector.h> -#include <Kernel/Bus/PCI/Controller/HostBridge.h> +#include <Kernel/Bus/PCI/Controller/HostController.h> #include <Kernel/Locking/Spinlock.h> namespace Kernel::PCI { -class MemoryBackedHostBridge : public HostBridge { +class MemoryBackedHostBridge : public HostController { public: static NonnullOwnPtr<MemoryBackedHostBridge> must_create(Domain const&, PhysicalAddress); diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index bdb935fc84..d297ab6a90 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -19,7 +19,7 @@ set(KERNEL_HEAP_SOURCES set(KERNEL_SOURCES AddressSanitizer.cpp - Bus/PCI/Controller/HostBridge.cpp + Bus/PCI/Controller/HostController.cpp Bus/PCI/Controller/MemoryBackedHostBridge.cpp Bus/PCI/Controller/VolumeManagementDevice.cpp Bus/PCI/Access.cpp @@ -339,6 +339,8 @@ if ("${SERENITY_ARCH}" STREQUAL "i686" OR "${SERENITY_ARCH}" STREQUAL "x86_64") Arch/x86/common/ScopedCritical.cpp Arch/x86/common/SmapDisabler.cpp Arch/x86/common/Shutdown.cpp + + Arch/x86/PCI/Controller/HostBridge.cpp ) set(KERNEL_SOURCES |