diff options
author | Liav A <liavalb@gmail.com> | 2021-09-28 20:18:51 +0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-09-29 11:24:33 +0200 |
commit | ef9b8ff0c7f5f5d7ae53a560218dd3c1a8fcbc49 (patch) | |
tree | e1833482c25510bd6039f2dc172efd07af5c4f95 /Kernel/Bus/PCI | |
parent | 9d9d57056ea1a9a9ce599d69309d0d78b8c27b8b (diff) | |
download | serenity-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.cpp | 83 | ||||
-rw-r--r-- | Kernel/Bus/PCI/API.h | 12 | ||||
-rw-r--r-- | Kernel/Bus/PCI/Access.cpp | 86 | ||||
-rw-r--r-- | Kernel/Bus/PCI/Access.h | 3 | ||||
-rw-r--r-- | Kernel/Bus/PCI/Definitions.h | 127 | ||||
-rw-r--r-- | Kernel/Bus/PCI/Device.cpp | 4 | ||||
-rw-r--r-- | Kernel/Bus/PCI/Initializer.cpp | 4 | ||||
-rw-r--r-- | Kernel/Bus/PCI/SysFSPCI.cpp | 20 | ||||
-rw-r--r-- | Kernel/Bus/PCI/SysFSPCI.h | 6 |
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; }; |