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