summaryrefslogtreecommitdiff
path: root/Kernel/Bus/PCI
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2021-09-28 20:18:51 +0300
committerAndreas Kling <kling@serenityos.org>2021-09-29 11:24:33 +0200
commitef9b8ff0c7f5f5d7ae53a560218dd3c1a8fcbc49 (patch)
treee1833482c25510bd6039f2dc172efd07af5c4f95 /Kernel/Bus/PCI
parent9d9d57056ea1a9a9ce599d69309d0d78b8c27b8b (diff)
downloadserenity-ef9b8ff0c7f5f5d7ae53a560218dd3c1a8fcbc49.zip
Kernel/PCI: Remove all macros and replace them with enum classes
Diffstat (limited to 'Kernel/Bus/PCI')
-rw-r--r--Kernel/Bus/PCI/API.cpp83
-rw-r--r--Kernel/Bus/PCI/API.h12
-rw-r--r--Kernel/Bus/PCI/Access.cpp86
-rw-r--r--Kernel/Bus/PCI/Access.h3
-rw-r--r--Kernel/Bus/PCI/Definitions.h127
-rw-r--r--Kernel/Bus/PCI/Device.cpp4
-rw-r--r--Kernel/Bus/PCI/Initializer.cpp4
-rw-r--r--Kernel/Bus/PCI/SysFSPCI.cpp20
-rw-r--r--Kernel/Bus/PCI/SysFSPCI.h6
9 files changed, 201 insertions, 144 deletions
diff --git a/Kernel/Bus/PCI/API.cpp b/Kernel/Bus/PCI/API.cpp
index 551f13ebb8..c49e174025 100644
--- a/Kernel/Bus/PCI/API.cpp
+++ b/Kernel/Bus/PCI/API.cpp
@@ -10,12 +10,12 @@
namespace Kernel::PCI {
-void write8(Address address, u32 field, u8 value) { Access::the().write8_field(address, field, value); }
-void write16(Address address, u32 field, u16 value) { Access::the().write16_field(address, field, value); }
-void write32(Address address, u32 field, u32 value) { Access::the().write32_field(address, field, value); }
-u8 read8(Address address, u32 field) { return Access::the().read8_field(address, field); }
-u16 read16(Address address, u32 field) { return Access::the().read16_field(address, field); }
-u32 read32(Address address, u32 field) { return Access::the().read32_field(address, field); }
+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 enumerate(Function<void(DeviceIdentifier const&)> callback)
{
@@ -29,69 +29,69 @@ DeviceIdentifier get_device_identifier(Address address)
HardwareID get_hardware_id(Address address)
{
- return { read16(address, PCI_VENDOR_ID), read16(address, PCI_DEVICE_ID) };
+ return { read16(address, PCI::RegisterOffset::VENDOR_ID), read16(address, PCI::RegisterOffset::DEVICE_ID) };
}
void enable_io_space(Address address)
{
- write16(address, PCI_COMMAND, read16(address, PCI_COMMAND) | (1 << 0));
+ write16(address, PCI::RegisterOffset::COMMAND, read16(address, PCI::RegisterOffset::COMMAND) | (1 << 0));
}
void disable_io_space(Address address)
{
- write16(address, PCI_COMMAND, read16(address, PCI_COMMAND) & ~(1 << 0));
+ write16(address, PCI::RegisterOffset::COMMAND, read16(address, PCI::RegisterOffset::COMMAND) & ~(1 << 0));
}
void enable_memory_space(Address address)
{
- write16(address, PCI_COMMAND, read16(address, PCI_COMMAND) | (1 << 1));
+ write16(address, PCI::RegisterOffset::COMMAND, read16(address, PCI::RegisterOffset::COMMAND) | (1 << 1));
}
void disable_memory_space(Address address)
{
- write16(address, PCI_COMMAND, read16(address, PCI_COMMAND) & ~(1 << 1));
+ write16(address, PCI::RegisterOffset::COMMAND, read16(address, PCI::RegisterOffset::COMMAND) & ~(1 << 1));
}
bool is_io_space_enabled(Address address)
{
- return (read16(address, PCI_COMMAND) & 1) != 0;
+ return (read16(address, PCI::RegisterOffset::COMMAND) & 1) != 0;
}
void enable_interrupt_line(Address address)
{
- write16(address, PCI_COMMAND, read16(address, PCI_COMMAND) & ~(1 << 10));
+ write16(address, PCI::RegisterOffset::COMMAND, read16(address, PCI::RegisterOffset::COMMAND) & ~(1 << 10));
}
void disable_interrupt_line(Address address)
{
- write16(address, PCI_COMMAND, read16(address, PCI_COMMAND) | 1 << 10);
+ write16(address, PCI::RegisterOffset::COMMAND, read16(address, PCI::RegisterOffset::COMMAND) | 1 << 10);
}
u32 get_BAR0(Address address)
{
- return read32(address, PCI_BAR0);
+ return read32(address, PCI::RegisterOffset::BAR0);
}
u32 get_BAR1(Address address)
{
- return read32(address, PCI_BAR1);
+ return read32(address, PCI::RegisterOffset::BAR1);
}
u32 get_BAR2(Address address)
{
- return read32(address, PCI_BAR2);
+ return read32(address, PCI::RegisterOffset::BAR2);
}
u32 get_BAR3(Address address)
{
- return read16(address, PCI_BAR3);
+ return read16(address, PCI::RegisterOffset::BAR3);
}
u32 get_BAR4(Address address)
{
- return read32(address, PCI_BAR4);
+ return read32(address, PCI::RegisterOffset::BAR4);
}
u32 get_BAR5(Address address)
{
- return read32(address, PCI_BAR5);
+ return read32(address, PCI::RegisterOffset::BAR5);
}
u32 get_BAR(Address address, u8 bar)
@@ -117,29 +117,36 @@ u32 get_BAR(Address address, u8 bar)
void enable_bus_mastering(Address address)
{
- auto value = read16(address, PCI_COMMAND);
+ auto value = read16(address, PCI::RegisterOffset::COMMAND);
value |= (1 << 2);
value |= (1 << 0);
- write16(address, PCI_COMMAND, value);
+ write16(address, PCI::RegisterOffset::COMMAND, value);
}
void disable_bus_mastering(Address address)
{
- auto value = read16(address, PCI_COMMAND);
+ auto value = read16(address, PCI::RegisterOffset::COMMAND);
value &= ~(1 << 2);
value |= (1 << 0);
- write16(address, PCI_COMMAND, value);
+ write16(address, PCI::RegisterOffset::COMMAND, value);
}
+static void write8_offseted(Address address, u32 field, u8 value) { Access::the().write8_field(address, field, value); }
+static void write16_offseted(Address address, u32 field, u16 value) { Access::the().write16_field(address, field, value); }
+static void write32_offseted(Address address, u32 field, u32 value) { Access::the().write32_field(address, field, value); }
+static u8 read8_offseted(Address address, u32 field) { return Access::the().read8_field(address, field); }
+static u16 read16_offseted(Address address, u32 field) { return Access::the().read16_field(address, field); }
+static u32 read32_offseted(Address address, u32 field) { return Access::the().read32_field(address, field); }
+
size_t get_BAR_space_size(Address address, u8 bar_number)
{
// See PCI Spec 2.3, Page 222
VERIFY(bar_number < 6);
- u8 field = (PCI_BAR0 + (bar_number << 2));
- u32 bar_reserved = read32(address, field);
- write32(address, field, 0xFFFFFFFF);
- u32 space_size = read32(address, field);
- write32(address, field, bar_reserved);
+ u8 field = to_underlying(PCI::RegisterOffset::BAR0) + (bar_number << 2);
+ u32 bar_reserved = read32_offseted(address, field);
+ write32_offseted(address, field, 0xFFFFFFFF);
+ u32 space_size = read32_offseted(address, field);
+ write32_offseted(address, field, bar_reserved);
space_size &= 0xfffffff0;
space_size = (~space_size) + 1;
return space_size;
@@ -149,15 +156,15 @@ void raw_access(Address address, u32 field, size_t access_size, u32 value)
{
VERIFY(access_size != 0);
if (access_size == 1) {
- write8(address, field, value);
+ write8_offseted(address, field, value);
return;
}
if (access_size == 2) {
- write16(address, field, value);
+ write16_offseted(address, field, value);
return;
}
if (access_size == 4) {
- write32(address, field, value);
+ write32_offseted(address, field, value);
return;
}
VERIFY_NOT_REACHED();
@@ -165,32 +172,32 @@ void raw_access(Address address, u32 field, size_t access_size, u32 value)
u8 Capability::read8(u32 field) const
{
- return PCI::read8(m_address, m_ptr + field);
+ return read8_offseted(m_address, m_ptr + field);
}
u16 Capability::read16(u32 field) const
{
- return PCI::read16(m_address, m_ptr + field);
+ return read16_offseted(m_address, m_ptr + field);
}
u32 Capability::read32(u32 field) const
{
- return PCI::read32(m_address, m_ptr + field);
+ return read32_offseted(m_address, m_ptr + field);
}
void Capability::write8(u32 field, u8 value)
{
- PCI::write8(m_address, m_ptr + field, value);
+ write8_offseted(m_address, m_ptr + field, value);
}
void Capability::write16(u32 field, u16 value)
{
- PCI::write16(m_address, m_ptr + field, value);
+ write16_offseted(m_address, m_ptr + field, value);
}
void Capability::write32(u32 field, u32 value)
{
- PCI::write32(m_address, m_ptr + field, value);
+ write32_offseted(m_address, m_ptr + field, value);
}
}
diff --git a/Kernel/Bus/PCI/API.h b/Kernel/Bus/PCI/API.h
index 97cdcfd5db..198e55e1d9 100644
--- a/Kernel/Bus/PCI/API.h
+++ b/Kernel/Bus/PCI/API.h
@@ -10,12 +10,12 @@
namespace Kernel::PCI {
-void write8(Address address, u32 field, u8 value);
-void write16(Address address, u32 field, u16 value);
-void write32(Address address, u32 field, u32 value);
-u8 read8(Address address, u32 field);
-u16 read16(Address address, u32 field);
-u32 read32(Address address, u32 field);
+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);
HardwareID get_hardware_id(PCI::Address);
bool is_io_space_enabled(Address);
diff --git a/Kernel/Bus/PCI/Access.cpp b/Kernel/Bus/PCI/Access.cpp
index 7792c7517f..2ec981e852 100644
--- a/Kernel/Bus/PCI/Access.cpp
+++ b/Kernel/Bus/PCI/Access.cpp
@@ -18,7 +18,6 @@
namespace Kernel::PCI {
#define PCI_MMIO_CONFIG_SPACE_SIZE 4096
-#define MEMORY_RANGE_PER_BUS (PCI_MMIO_CONFIG_SPACE_SIZE * PCI_MAX_FUNCTIONS_PER_DEVICE * PCI_MAX_DEVICES_PER_BUS)
static Access* s_access;
@@ -109,7 +108,7 @@ Optional<PhysicalAddress> Access::determine_memory_mapped_bus_base_address(u32 d
return {};
if (!(chosen_domain.value().start_bus() <= bus && bus <= chosen_domain.value().end_bus()))
return {};
- return chosen_domain.value().paddr().offset(MEMORY_RANGE_PER_BUS * (bus - chosen_domain.value().start_bus()));
+ return chosen_domain.value().paddr().offset(memory_range_per_bus * (bus - chosen_domain.value().start_bus()));
}
void Access::map_bus_region(u32 domain, u8 bus)
@@ -121,7 +120,7 @@ void Access::map_bus_region(u32 domain, u8 bus)
// FIXME: Find a way to propagate error from here.
if (!bus_base_address.has_value())
VERIFY_NOT_REACHED();
- auto region_or_error = MM.allocate_kernel_region(bus_base_address.value(), MEMORY_RANGE_PER_BUS, "PCI ECAM", Memory::Region::Access::ReadWrite);
+ auto region_or_error = MM.allocate_kernel_region(bus_base_address.value(), memory_range_per_bus, "PCI ECAM", Memory::Region::Access::ReadWrite);
// FIXME: Find a way to propagate error from here.
if (region_or_error.is_error())
VERIFY_NOT_REACHED();
@@ -135,50 +134,50 @@ VirtualAddress Access::get_device_configuration_memory_mapped_space(Address addr
VERIFY(m_access_lock.is_locked());
dbgln_if(PCI_DEBUG, "PCI: Getting device configuration space for {}", address);
map_bus_region(address.domain(), address.bus());
- return m_mapped_bus_region->vaddr().offset(PCI_MMIO_CONFIG_SPACE_SIZE * address.function() + (PCI_MMIO_CONFIG_SPACE_SIZE * PCI_MAX_FUNCTIONS_PER_DEVICE) * address.device());
+ return m_mapped_bus_region->vaddr().offset(mmio_device_space_size * address.function() + (mmio_device_space_size * to_underlying(Limits::MaxFunctionsPerDevice)) * address.device());
}
u8 Access::io_read8_field(Address address, u32 field)
{
MutexLocker lock(m_access_lock);
dbgln_if(PCI_DEBUG, "PCI: IO Reading 8-bit field {:#08x} for {}", field, address);
- IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field));
- return IO::in8(PCI_VALUE_PORT + (field & 3));
+ IO::out32(PCI::address_port, address.io_address_for_field(field));
+ return IO::in8(PCI::value_port + (field & 3));
}
u16 Access::io_read16_field(Address address, u32 field)
{
MutexLocker lock(m_access_lock);
dbgln_if(PCI_DEBUG, "PCI: IO Reading 16-bit field {:#08x} for {}", field, address);
- IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field));
- return IO::in16(PCI_VALUE_PORT + (field & 2));
+ IO::out32(PCI::address_port, address.io_address_for_field(field));
+ return IO::in16(PCI::value_port + (field & 2));
}
u32 Access::io_read32_field(Address address, u32 field)
{
MutexLocker lock(m_access_lock);
dbgln_if(PCI_DEBUG, "PCI: IO Reading 32-bit field {:#08x} for {}", field, address);
- IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field));
- return IO::in32(PCI_VALUE_PORT);
+ IO::out32(PCI::address_port, address.io_address_for_field(field));
+ return IO::in32(PCI::value_port);
}
void Access::io_write8_field(Address address, u32 field, u8 value)
{
MutexLocker lock(m_access_lock);
dbgln_if(PCI_DEBUG, "PCI: IO Writing to 8-bit field {:#08x}, value={:#02x} for {}", field, value, address);
- IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field));
- IO::out8(PCI_VALUE_PORT + (field & 3), value);
+ IO::out32(PCI::address_port, address.io_address_for_field(field));
+ IO::out8(PCI::value_port + (field & 3), value);
}
void Access::io_write16_field(Address address, u32 field, u16 value)
{
MutexLocker lock(m_access_lock);
dbgln_if(PCI_DEBUG, "PCI: IO Writing to 16-bit field {:#08x}, value={:#02x} for {}", field, value, address);
- IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field));
- IO::out16(PCI_VALUE_PORT + (field & 2), value);
+ IO::out32(PCI::address_port, address.io_address_for_field(field));
+ IO::out16(PCI::value_port + (field & 2), value);
}
void Access::io_write32_field(Address address, u32 field, u32 value)
{
MutexLocker lock(m_access_lock);
dbgln_if(PCI_DEBUG, "PCI: IO Writing to 32-bit field {:#08x}, value={:#02x} for {}", field, value, address);
- IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field));
- IO::out32(PCI_VALUE_PORT, value);
+ IO::out32(PCI::address_port, address.io_address_for_field(field));
+ IO::out32(PCI::value_port, value);
}
u8 Access::memory_read8_field(Address address, u32 field)
@@ -265,6 +264,15 @@ void Access::write32_field(Address address, u32 field, u32 value)
VERIFY_NOT_REACHED();
}
+u8 Access::read8_field(Address address, RegisterOffset field)
+{
+ return read8_field(address, to_underlying(field));
+}
+u16 Access::read16_field(Address address, RegisterOffset field)
+{
+ return read16_field(address, to_underlying(field));
+}
+
u8 Access::read8_field(Address address, u32 field)
{
switch (m_access_type) {
@@ -311,11 +319,11 @@ UNMAP_AFTER_INIT void Access::rescan_hardware()
// Handle Multiple PCI host bridges on slot 0, device 0.
// If we happen to miss some PCI buses because they are not reachable through
// recursive PCI-to-PCI bridges starting from bus 0, we might find them here.
- if ((read8_field(Address(), PCI_HEADER_TYPE) & 0x80) != 0) {
+ if ((read8_field(Address(), PCI::RegisterOffset::HEADER_TYPE) & 0x80) != 0) {
for (int bus = 1; bus < 256; ++bus) {
- if (read16_field(Address(0, 0, 0, bus), PCI_VENDOR_ID) == PCI_NONE)
+ if (read16_field(Address(0, 0, 0, bus), PCI::RegisterOffset::VENDOR_ID) == PCI::none_value)
continue;
- if (read16_field(Address(0, 0, 0, bus), PCI_CLASS) != 0x6)
+ if (read16_field(Address(0, 0, 0, bus), PCI::RegisterOffset::CLASS) != 0x6)
continue;
if (m_enumerated_buses.get(bus))
continue;
@@ -330,14 +338,14 @@ UNMAP_AFTER_INIT void Access::rescan_hardware()
for (u32 domain = 0; domain < m_domains.size(); domain++) {
dbgln_if(PCI_DEBUG, "PCI: Scan memory mapped domain {}", domain);
// Single PCI host controller.
- if ((read8_field(Address(domain), PCI_HEADER_TYPE) & 0x80) == 0) {
+ if ((read8_field(Address(domain), PCI::RegisterOffset::HEADER_TYPE) & 0x80) == 0) {
enumerate_bus(-1, 0, true);
return;
}
// Multiple PCI host controllers.
for (u8 function = 0; function < 8; ++function) {
- if (read16_field(Address(domain, 0, 0, function), PCI_VENDOR_ID) == PCI_NONE)
+ if (read16_field(Address(domain, 0, 0, function), PCI::RegisterOffset::VENDOR_ID) == PCI::none_value)
break;
enumerate_bus(-1, function, false);
}
@@ -347,9 +355,9 @@ UNMAP_AFTER_INIT void Access::rescan_hardware()
UNMAP_AFTER_INIT Optional<u8> Access::get_capabilities_pointer(Address address)
{
dbgln_if(PCI_DEBUG, "PCI: Getting capabilities pointer for {}", address);
- if (read16_field(address, PCI_STATUS) & (1 << 4)) {
+ if (read16_field(address, PCI::RegisterOffset::STATUS) & (1 << 4)) {
dbgln_if(PCI_DEBUG, "PCI: Found capabilities pointer for {}", address);
- return read8_field(address, PCI_CAPABILITIES_POINTER);
+ return read8_field(address, PCI::RegisterOffset::CAPABILITIES_POINTER);
}
dbgln_if(PCI_DEBUG, "PCI: No capabilities pointer for {}", address);
return {};
@@ -379,22 +387,24 @@ UNMAP_AFTER_INIT void Access::enumerate_functions(int type, u8 bus, u8 device, u
{
dbgln_if(PCI_DEBUG, "PCI: Enumerating function type={}, bus={}, device={}, function={}", type, bus, device, function);
Address address(0, bus, device, function);
- auto read_type = (read8_field(address, PCI_CLASS) << 8u) | read8_field(address, PCI_SUBCLASS);
+ auto read_type = (read8_field(address, PCI::RegisterOffset::CLASS) << 8u) | read8_field(address, PCI::RegisterOffset::SUBCLASS);
if (type == -1 || type == read_type) {
- HardwareID id = { read16_field(address, PCI_VENDOR_ID), read16_field(address, PCI_DEVICE_ID) };
- ClassCode class_code = read8_field(address, PCI_CLASS);
- SubclassCode subclass_code = read8_field(address, PCI_SUBCLASS);
- ProgrammingInterface prog_if = read8_field(address, PCI_PROG_IF);
- RevisionID revision_id = read8_field(address, PCI_REVISION_ID);
- SubsystemID subsystem_id = read16_field(address, PCI_SUBSYSTEM_ID);
- SubsystemVendorID subsystem_vendor_id = read16_field(address, PCI_SUBSYSTEM_VENDOR_ID);
- InterruptLine interrupt_line = read8_field(address, PCI_INTERRUPT_LINE);
- InterruptPin interrupt_pin = read8_field(address, PCI_INTERRUPT_PIN);
+ HardwareID id = { read16_field(address, PCI::RegisterOffset::VENDOR_ID), read16_field(address, PCI::RegisterOffset::DEVICE_ID) };
+ ClassCode class_code = read8_field(address, PCI::RegisterOffset::CLASS);
+ SubclassCode subclass_code = read8_field(address, PCI::RegisterOffset::SUBCLASS);
+ ProgrammingInterface prog_if = read8_field(address, PCI::RegisterOffset::PROG_IF);
+ RevisionID revision_id = read8_field(address, PCI::RegisterOffset::REVISION_ID);
+ SubsystemID subsystem_id = read16_field(address, PCI::RegisterOffset::SUBSYSTEM_ID);
+ SubsystemVendorID subsystem_vendor_id = read16_field(address, PCI::RegisterOffset::SUBSYSTEM_VENDOR_ID);
+ InterruptLine interrupt_line = read8_field(address, PCI::RegisterOffset::INTERRUPT_LINE);
+ InterruptPin interrupt_pin = read8_field(address, PCI::RegisterOffset::INTERRUPT_PIN);
m_device_identifiers.append(DeviceIdentifier { address, id, revision_id, class_code, subclass_code, prog_if, subsystem_id, subsystem_vendor_id, interrupt_line, interrupt_pin, get_capabilities(address) });
}
- if (read_type == PCI_TYPE_BRIDGE && recursive && (!m_enumerated_buses.get(read8_field(address, PCI_SECONDARY_BUS)))) {
- u8 secondary_bus = read8_field(address, PCI_SECONDARY_BUS);
+ if (read_type == (to_underlying(PCI::ClassID::Bridge) << 8 | to_underlying(PCI::Bridge::SubclassID::PCI_TO_PCI))
+ && recursive
+ && (!m_enumerated_buses.get(read8_field(address, PCI::RegisterOffset::SECONDARY_BUS)))) {
+ u8 secondary_bus = read8_field(address, PCI::RegisterOffset::SECONDARY_BUS);
dbgln_if(PCI_DEBUG, "PCI: Found secondary bus: {}", secondary_bus);
VERIFY(secondary_bus != bus);
m_enumerated_buses.set(secondary_bus, true);
@@ -406,14 +416,14 @@ UNMAP_AFTER_INIT void Access::enumerate_device(int type, u8 bus, u8 device, bool
{
dbgln_if(PCI_DEBUG, "PCI: Enumerating device type={}, bus={}, device={}", type, bus, device);
Address address(0, bus, device, 0);
- if (read16_field(address, PCI_VENDOR_ID) == PCI_NONE)
+ if (read16_field(address, PCI::RegisterOffset::VENDOR_ID) == PCI::none_value)
return;
enumerate_functions(type, bus, device, 0, recursive);
- if (!(read8_field(address, PCI_HEADER_TYPE) & 0x80))
+ if (!(read8_field(address, PCI::RegisterOffset::HEADER_TYPE) & 0x80))
return;
for (u8 function = 1; function < 8; ++function) {
Address address(0, bus, device, function);
- if (read16_field(address, PCI_VENDOR_ID) != PCI_NONE)
+ if (read16_field(address, PCI::RegisterOffset::VENDOR_ID) != PCI::none_value)
enumerate_functions(type, bus, device, function, recursive);
}
}
diff --git a/Kernel/Bus/PCI/Access.h b/Kernel/Bus/PCI/Access.h
index 9d562b563c..530af0adf7 100644
--- a/Kernel/Bus/PCI/Access.h
+++ b/Kernel/Bus/PCI/Access.h
@@ -40,6 +40,9 @@ public:
DeviceIdentifier get_device_identifier(Address address) const;
private:
+ u8 read8_field(Address address, RegisterOffset field);
+ u16 read16_field(Address address, RegisterOffset field);
+
void enumerate_bus(int type, u8 bus, bool recursive);
void enumerate_functions(int type, u8 bus, u8 device, u8 function, bool recursive);
void enumerate_device(int type, u8 bus, u8 device, bool recursive);
diff --git a/Kernel/Bus/PCI/Definitions.h b/Kernel/Bus/PCI/Definitions.h
index 24bfa19a74..1118987f4a 100644
--- a/Kernel/Bus/PCI/Definitions.h
+++ b/Kernel/Bus/PCI/Definitions.h
@@ -14,52 +14,89 @@
namespace Kernel {
-#define PCI_VENDOR_ID 0x00 // word
-#define PCI_DEVICE_ID 0x02 // word
-#define PCI_COMMAND 0x04 // word
-#define PCI_STATUS 0x06 // word
-#define PCI_REVISION_ID 0x08 // byte
-#define PCI_PROG_IF 0x09 // byte
-#define PCI_SUBCLASS 0x0a // byte
-#define PCI_CLASS 0x0b // byte
-#define PCI_CACHE_LINE_SIZE 0x0c // byte
-#define PCI_LATENCY_TIMER 0x0d // byte
-#define PCI_HEADER_TYPE 0x0e // byte
-#define PCI_BIST 0x0f // byte
-#define PCI_BAR0 0x10 // u32
-#define PCI_BAR1 0x14 // u32
-#define PCI_BAR2 0x18 // u32
-#define PCI_BAR3 0x1C // u32
-#define PCI_BAR4 0x20 // u32
-#define PCI_BAR5 0x24 // u32
-#define PCI_SUBSYSTEM_VENDOR_ID 0x2C // u16
-#define PCI_SUBSYSTEM_ID 0x2E // u16
-#define PCI_CAPABILITIES_POINTER 0x34 // u8
-#define PCI_INTERRUPT_LINE 0x3C // byte
-#define PCI_INTERRUPT_PIN 0x3D // byte
-#define PCI_SECONDARY_BUS 0x19 // byte
-#define PCI_HEADER_TYPE_DEVICE 0
-#define PCI_HEADER_TYPE_BRIDGE 1
-#define PCI_TYPE_BRIDGE 0x0604
-#define PCI_ADDRESS_PORT 0xCF8
-#define PCI_VALUE_PORT 0xCFC
-#define PCI_NONE 0xFFFF
-#define PCI_MAX_DEVICES_PER_BUS 32
-#define PCI_MAX_BUSES 256
-#define PCI_MAX_FUNCTIONS_PER_DEVICE 8
-
-#define PCI_CAPABILITY_NULL 0x0
-#define PCI_CAPABILITY_MSI 0x5
-#define PCI_CAPABILITY_VENDOR_SPECIFIC 0x9
-#define PCI_CAPABILITY_MSIX 0x11
+namespace PCI {
+
+enum class HeaderType {
+ Device = 0,
+ Bridge = 1,
+};
+
+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
+};
+
+enum class Limits {
+ MaxDevicesPerBus = 32,
+ MaxBusesPerDomain = 256,
+ MaxFunctionsPerDevice = 8,
+};
+
+static constexpr u16 address_port = 0xcf8;
+static constexpr u16 value_port = 0xcfc;
+
+static constexpr size_t mmio_device_space_size = 4096;
+static constexpr u16 none_value = 0xffff;
+static constexpr size_t memory_range_per_bus = mmio_device_space_size * to_underlying(Limits::MaxFunctionsPerDevice) * to_underlying(Limits::MaxDevicesPerBus);
// Taken from https://pcisig.com/sites/default/files/files/PCI_Code-ID_r_1_11__v24_Jan_2019.pdf
-#define PCI_MASS_STORAGE_CLASS_ID 0x1
-#define PCI_IDE_CTRL_SUBCLASS_ID 0x1
-#define PCI_SATA_CTRL_SUBCLASS_ID 0x6
-#define PCI_AHCI_IF_PROGIF 0x1
+enum class ClassID {
+ MassStorage = 0x1,
+ Bridge = 0x6,
+};
+
+namespace MassStorage {
+
+enum class SubclassID {
+ IDEController = 0x1,
+ SATAController = 0x6,
+};
+enum class SATAProgIF {
+ AHCI = 0x1,
+};
+
+}
+
+namespace Bridge {
+
+enum class SubclassID {
+ PCI_TO_PCI = 0x4,
+};
+
+}
+
+TYPEDEF_DISTINCT_ORDERED_ID(u8, CapabilityID);
+namespace Capabilities {
+enum ID {
+ Null = 0x0,
+ MSI = 0x5,
+ VendorSpecific = 0x9,
+ MSIX = 0x11,
+};
+}
-namespace PCI {
struct HardwareID {
u16 vendor_id { 0 };
u16 device_id { 0 };
@@ -167,7 +204,7 @@ public:
{
}
- u8 id() const { return m_id; }
+ CapabilityID id() const { return m_id; }
u8 read8(u32) const;
u16 read16(u32) const;
@@ -178,7 +215,7 @@ public:
private:
Address m_address;
- const u8 m_id;
+ const CapabilityID m_id;
const u8 m_ptr;
};
diff --git a/Kernel/Bus/PCI/Device.cpp b/Kernel/Bus/PCI/Device.cpp
index b2c7862483..66239a426e 100644
--- a/Kernel/Bus/PCI/Device.cpp
+++ b/Kernel/Bus/PCI/Device.cpp
@@ -18,7 +18,7 @@ Device::Device(Address address)
bool Device::is_msi_capable() const
{
for (const auto& capability : PCI::get_device_identifier(pci_address()).capabilities()) {
- if (capability.id() == PCI_CAPABILITY_MSI)
+ if (capability.id().value() == PCI::Capabilities::ID::MSI)
return true;
}
return false;
@@ -26,7 +26,7 @@ bool Device::is_msi_capable() const
bool Device::is_msix_capable() const
{
for (const auto& capability : PCI::get_device_identifier(pci_address()).capabilities()) {
- if (capability.id() == PCI_CAPABILITY_MSIX)
+ if (capability.id().value() == PCI::Capabilities::ID::MSIX)
return true;
}
return false;
diff --git a/Kernel/Bus/PCI/Initializer.cpp b/Kernel/Bus/PCI/Initializer.cpp
index 7b0aa35d73..aff597fd36 100644
--- a/Kernel/Bus/PCI/Initializer.cpp
+++ b/Kernel/Bus/PCI/Initializer.cpp
@@ -65,8 +65,8 @@ UNMAP_AFTER_INIT bool test_pci_io()
{
dmesgln("Testing PCI via manual probing...");
u32 tmp = 0x80000000;
- IO::out32(PCI_ADDRESS_PORT, tmp);
- tmp = IO::in32(PCI_ADDRESS_PORT);
+ IO::out32(PCI::address_port, tmp);
+ tmp = IO::in32(PCI::address_port);
if (tmp == 0x80000000) {
dmesgln("PCI IO supported");
return true;
diff --git a/Kernel/Bus/PCI/SysFSPCI.cpp b/Kernel/Bus/PCI/SysFSPCI.cpp
index a336bc85c6..be114d1752 100644
--- a/Kernel/Bus/PCI/SysFSPCI.cpp
+++ b/Kernel/Bus/PCI/SysFSPCI.cpp
@@ -22,14 +22,14 @@ UNMAP_AFTER_INIT PCIDeviceSysFSDirectory::PCIDeviceSysFSDirectory(const SysFSDir
: SysFSDirectory(String::formatted("{:04x}:{:02x}:{:02x}.{}", address.domain(), address.bus(), address.device(), address.function()), parent_directory)
, m_address(address)
{
- m_components.append(PCIDeviceAttributeSysFSComponent::create("vendor", *this, PCI_VENDOR_ID, 2));
- m_components.append(PCIDeviceAttributeSysFSComponent::create("device_id", *this, PCI_DEVICE_ID, 2));
- m_components.append(PCIDeviceAttributeSysFSComponent::create("class", *this, PCI_CLASS, 1));
- m_components.append(PCIDeviceAttributeSysFSComponent::create("subclass", *this, PCI_SUBCLASS, 1));
- m_components.append(PCIDeviceAttributeSysFSComponent::create("revision", *this, PCI_REVISION_ID, 1));
- m_components.append(PCIDeviceAttributeSysFSComponent::create("progif", *this, PCI_PROG_IF, 1));
- m_components.append(PCIDeviceAttributeSysFSComponent::create("subsystem_vendor", *this, PCI_SUBSYSTEM_VENDOR_ID, 2));
- m_components.append(PCIDeviceAttributeSysFSComponent::create("subsystem_id", *this, PCI_SUBSYSTEM_ID, 2));
+ m_components.append(PCIDeviceAttributeSysFSComponent::create("vendor", *this, PCI::RegisterOffset::VENDOR_ID, 2));
+ m_components.append(PCIDeviceAttributeSysFSComponent::create("device_id", *this, PCI::RegisterOffset::DEVICE_ID, 2));
+ m_components.append(PCIDeviceAttributeSysFSComponent::create("class", *this, PCI::RegisterOffset::CLASS, 1));
+ m_components.append(PCIDeviceAttributeSysFSComponent::create("subclass", *this, PCI::RegisterOffset::SUBCLASS, 1));
+ m_components.append(PCIDeviceAttributeSysFSComponent::create("revision", *this, PCI::RegisterOffset::REVISION_ID, 1));
+ m_components.append(PCIDeviceAttributeSysFSComponent::create("progif", *this, PCI::RegisterOffset::PROG_IF, 1));
+ m_components.append(PCIDeviceAttributeSysFSComponent::create("subsystem_vendor", *this, PCI::RegisterOffset::SUBSYSTEM_VENDOR_ID, 2));
+ m_components.append(PCIDeviceAttributeSysFSComponent::create("subsystem_id", *this, PCI::RegisterOffset::SUBSYSTEM_ID, 2));
}
UNMAP_AFTER_INIT void PCIBusSysFSDirectory::initialize()
@@ -47,12 +47,12 @@ UNMAP_AFTER_INIT PCIBusSysFSDirectory::PCIBusSysFSDirectory()
});
}
-NonnullRefPtr<PCIDeviceAttributeSysFSComponent> PCIDeviceAttributeSysFSComponent::create(String name, const PCIDeviceSysFSDirectory& device, size_t offset, size_t field_bytes_width)
+NonnullRefPtr<PCIDeviceAttributeSysFSComponent> PCIDeviceAttributeSysFSComponent::create(String name, const PCIDeviceSysFSDirectory& device, PCI::RegisterOffset offset, size_t field_bytes_width)
{
return adopt_ref(*new (nothrow) PCIDeviceAttributeSysFSComponent(name, device, offset, field_bytes_width));
}
-PCIDeviceAttributeSysFSComponent::PCIDeviceAttributeSysFSComponent(String name, const PCIDeviceSysFSDirectory& device, size_t offset, size_t field_bytes_width)
+PCIDeviceAttributeSysFSComponent::PCIDeviceAttributeSysFSComponent(String name, const PCIDeviceSysFSDirectory& device, PCI::RegisterOffset offset, size_t field_bytes_width)
: SysFSComponent(name)
, m_device(device)
, m_offset(offset)
diff --git a/Kernel/Bus/PCI/SysFSPCI.h b/Kernel/Bus/PCI/SysFSPCI.h
index 9a3bc47f9f..4286150eaf 100644
--- a/Kernel/Bus/PCI/SysFSPCI.h
+++ b/Kernel/Bus/PCI/SysFSPCI.h
@@ -35,16 +35,16 @@ private:
class PCIDeviceAttributeSysFSComponent : public SysFSComponent {
public:
- static NonnullRefPtr<PCIDeviceAttributeSysFSComponent> create(String name, const PCIDeviceSysFSDirectory& device, size_t offset, size_t field_bytes_width);
+ static NonnullRefPtr<PCIDeviceAttributeSysFSComponent> create(String name, const PCIDeviceSysFSDirectory& device, PCI::RegisterOffset offset, size_t field_bytes_width);
virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const override;
virtual ~PCIDeviceAttributeSysFSComponent() {};
protected:
KResultOr<NonnullOwnPtr<KBuffer>> try_to_generate_buffer() const;
- PCIDeviceAttributeSysFSComponent(String name, const PCIDeviceSysFSDirectory& device, size_t offset, size_t field_bytes_width);
+ PCIDeviceAttributeSysFSComponent(String name, const PCIDeviceSysFSDirectory& device, PCI::RegisterOffset offset, size_t field_bytes_width);
NonnullRefPtr<PCIDeviceSysFSDirectory> m_device;
- size_t m_offset;
+ PCI::RegisterOffset m_offset;
size_t m_field_bytes_width;
};