소스 검색

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.
Liav A 2 년 전
부모
커밋
1596ee241f

+ 62 - 0
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);
+}
+
+}

+ 1 - 16
Kernel/Bus/PCI/Controller/HostBridge.h → 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&);
 };
 
 }

+ 5 - 2
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)
 {

+ 3 - 1
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();

+ 20 - 62
Kernel/Bus/PCI/Controller/HostBridge.cpp → 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));
-}
-
 }

+ 16 - 5
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;
 };
 
 }

+ 1 - 1
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)
 {
 }

+ 2 - 2
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);
 

+ 3 - 1
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