diff --git a/Kernel/Bus/PCI/API.cpp b/Kernel/Bus/PCI/API.cpp index 7c50fbfe00..3bef4566e1 100644 --- a/Kernel/Bus/PCI/API.cpp +++ b/Kernel/Bus/PCI/API.cpp @@ -17,7 +17,7 @@ u8 read8(Address address, u32 field) { return Access::the().read8_field(address, 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 enumerate(Function callback) +void enumerate(Function callback) { Access::the().fast_enumerate(callback); } diff --git a/Kernel/Bus/PCI/API.h b/Kernel/Bus/PCI/API.h index 6d23a6e594..f68005705f 100644 --- a/Kernel/Bus/PCI/API.h +++ b/Kernel/Bus/PCI/API.h @@ -19,7 +19,7 @@ u32 read32(Address address, u32 field); ID get_id(PCI::Address); bool is_io_space_enabled(Address); -void enumerate(Function callback); +void enumerate(Function callback); void enable_interrupt_line(Address); void disable_interrupt_line(Address); u8 get_interrupt_line(Address); diff --git a/Kernel/Bus/PCI/Access.cpp b/Kernel/Bus/PCI/Access.cpp index d06aa5b49b..0941205cb9 100644 --- a/Kernel/Bus/PCI/Access.cpp +++ b/Kernel/Bus/PCI/Access.cpp @@ -381,7 +381,14 @@ UNMAP_AFTER_INIT void Access::enumerate_functions(int type, u8 bus, u8 device, u Address address(0, bus, device, function); auto read_type = (read8_field(address, PCI_CLASS) << 8u) | read8_field(address, PCI_SUBCLASS); if (type == -1 || type == read_type) { - m_physical_ids.append(PhysicalID { address, { read16_field(address, PCI_VENDOR_ID), read16_field(address, PCI_DEVICE_ID) }, get_capabilities(address) }); + PCI::ID 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); + m_physical_ids.append(PhysicalID { address, id, revision_id, class_code, subclass_code, prog_if, subsystem_id, subsystem_vendor_id, get_capabilities(address) }); } if (read_type == PCI_TYPE_BRIDGE && recursive && (!m_enumerated_buses.get(read8_field(address, PCI_SECONDARY_BUS)))) { @@ -416,12 +423,12 @@ UNMAP_AFTER_INIT void Access::enumerate_bus(int type, u8 bus, bool recursive) enumerate_device(type, bus, device, recursive); } -void Access::fast_enumerate(Function& callback) const +void Access::fast_enumerate(Function& callback) const { MutexLocker locker(m_scan_lock); VERIFY(!m_physical_ids.is_empty()); for (auto& physical_id : m_physical_ids) { - callback(physical_id.address(), physical_id.id()); + callback(physical_id.address(), physical_id); } } diff --git a/Kernel/Bus/PCI/Access.h b/Kernel/Bus/PCI/Access.h index c0993f927b..67a913d558 100644 --- a/Kernel/Bus/PCI/Access.h +++ b/Kernel/Bus/PCI/Access.h @@ -25,7 +25,7 @@ public: static bool initialize_for_memory_access(PhysicalAddress mcfg_table); static bool initialize_for_io_access(); - void fast_enumerate(Function&) const; + void fast_enumerate(Function&) const; void rescan_hardware(); static Access& the(); diff --git a/Kernel/Bus/PCI/Definitions.h b/Kernel/Bus/PCI/Definitions.h index cb2e67b119..03f1f8d97b 100644 --- a/Kernel/Bus/PCI/Definitions.h +++ b/Kernel/Bus/PCI/Definitions.h @@ -181,11 +181,25 @@ private: const u8 m_ptr; }; +TYPEDEF_DISTINCT_ORDERED_ID(u8, ClassCode); +TYPEDEF_DISTINCT_ORDERED_ID(u8, SubclassCode); +TYPEDEF_DISTINCT_ORDERED_ID(u8, ProgrammingInterface); +TYPEDEF_DISTINCT_ORDERED_ID(u8, RevisionID); +TYPEDEF_DISTINCT_ORDERED_ID(u16, SubsystemID); +TYPEDEF_DISTINCT_ORDERED_ID(u16, SubsystemVendorID); + +class Access; class PhysicalID { public: - PhysicalID(Address address, ID id, Vector capabilities) + PhysicalID(Address address, ID id, RevisionID revision_id, ClassCode class_code, SubclassCode subclass_code, ProgrammingInterface prog_if, SubsystemID subsystem_id, SubsystemVendorID subsystem_vendor_id, Vector capabilities) : m_address(address) , m_id(id) + , m_revision_id(revision_id) + , m_class_code(class_code) + , m_subclass_code(subclass_code) + , m_prog_if(prog_if) + , m_subsystem_id(subsystem_id) + , m_subsystem_vendor_id(subsystem_vendor_id) , m_capabilities(capabilities) { if constexpr (PCI_DEBUG) { @@ -198,13 +212,36 @@ public: const ID& id() const { return m_id; } const Address& address() const { return m_address; } + RevisionID revision_id() const { return m_revision_id; } + ClassCode class_code() const { return m_class_code; } + SubclassCode subclass_code() const { return m_subclass_code; } + ProgrammingInterface prog_if() const { return m_prog_if; } + SubsystemID subsystem_id() const { return m_subsystem_id; } + SubsystemVendorID subsystem_vendor_id() const { return m_subsystem_vendor_id; } + + void apply_subclass_code_change(Badge, SubclassCode new_subclass) + { + m_subclass_code = new_subclass; + } + void apply_prog_if_change(Badge, ProgrammingInterface new_progif) + { + m_prog_if = new_progif; + } + private: Address m_address; ID m_id; + + RevisionID m_revision_id; + ClassCode m_class_code; + SubclassCode m_subclass_code; + ProgrammingInterface m_prog_if; + SubsystemID m_subsystem_id; + SubsystemVendorID m_subsystem_vendor_id; + Vector m_capabilities; }; -class Access; class Domain; class Device; } diff --git a/Kernel/Bus/PCI/Initializer.cpp b/Kernel/Bus/PCI/Initializer.cpp index b23f005e14..e2da5b6c75 100644 --- a/Kernel/Bus/PCI/Initializer.cpp +++ b/Kernel/Bus/PCI/Initializer.cpp @@ -56,8 +56,8 @@ UNMAP_AFTER_INIT void initialize() PCI::PCIBusSysFSDirectory::initialize(); - PCI::enumerate([&](const Address& address, ID id) { - dmesgln("{} {}", address, id); + PCI::enumerate([&](const Address& address, PhysicalID const& physical_id) { + dmesgln("{} {}", address, physical_id.id()); }); } diff --git a/Kernel/Bus/PCI/SysFSPCI.cpp b/Kernel/Bus/PCI/SysFSPCI.cpp index df08f7bedf..f30fd4f79f 100644 --- a/Kernel/Bus/PCI/SysFSPCI.cpp +++ b/Kernel/Bus/PCI/SysFSPCI.cpp @@ -41,7 +41,7 @@ UNMAP_AFTER_INIT void PCIBusSysFSDirectory::initialize() UNMAP_AFTER_INIT PCIBusSysFSDirectory::PCIBusSysFSDirectory() : SysFSDirectory("pci", SysFSComponentRegistry::the().buses_directory()) { - PCI::enumerate([&](const Address& address, ID) { + PCI::enumerate([&](const Address& address, PhysicalID const&) { auto pci_device = PCI::PCIDeviceSysFSDirectory::create(*this, address); m_components.append(pci_device); }); diff --git a/Kernel/Bus/USB/USBManagement.cpp b/Kernel/Bus/USB/USBManagement.cpp index 2486abc200..741c140017 100644 --- a/Kernel/Bus/USB/USBManagement.cpp +++ b/Kernel/Bus/USB/USBManagement.cpp @@ -27,10 +27,10 @@ UNMAP_AFTER_INIT void USBManagement::enumerate_controllers() if (kernel_command_line().disable_usb()) return; - PCI::enumerate([this](PCI::Address const& address, PCI::ID) { - if (!(PCI::get_class(address) == 0xc && PCI::get_subclass(address) == 0x3)) + PCI::enumerate([this](PCI::Address const& address, PCI::PhysicalID const& physical_id) { + if (!(physical_id.class_code().value() == 0xc && physical_id.subclass_code().value() == 0x3)) return; - if (PCI::get_programming_interface(address) == 0x0) { + if (physical_id.prog_if().value() == 0x0) { if (kernel_command_line().disable_uhci_controller()) return; @@ -40,22 +40,22 @@ UNMAP_AFTER_INIT void USBManagement::enumerate_controllers() return; } - if (PCI::get_programming_interface(address) == 0x10) { + if (physical_id.prog_if().value() == 0x10) { dmesgln("USBManagement: OHCI controller found at {} is not currently supported.", address); return; } - if (PCI::get_programming_interface(address) == 0x20) { + if (physical_id.prog_if().value() == 0x20) { dmesgln("USBManagement: EHCI controller found at {} is not currently supported.", address); return; } - if (PCI::get_programming_interface(address) == 0x30) { + if (physical_id.prog_if().value() == 0x30) { dmesgln("USBManagement: xHCI controller found at {} is not currently supported.", address); return; } - dmesgln("USBManagement: Unknown/unsupported controller at {} with programming interface 0x{:02x}", address, PCI::get_programming_interface(address)); + dmesgln("USBManagement: Unknown/unsupported controller at {} with programming interface 0x{:02x}", address, physical_id.prog_if().value()); }); } diff --git a/Kernel/Bus/VirtIO/Device.cpp b/Kernel/Bus/VirtIO/Device.cpp index 3a24986a1f..e47cf07912 100644 --- a/Kernel/Bus/VirtIO/Device.cpp +++ b/Kernel/Bus/VirtIO/Device.cpp @@ -18,13 +18,13 @@ UNMAP_AFTER_INIT void detect() { if (kernel_command_line().disable_virtio()) return; - PCI::enumerate([&](const PCI::Address& address, PCI::ID id) { - if (address.is_null() || id.is_null()) + PCI::enumerate([&](const PCI::Address& address, PCI::PhysicalID const& physical_id) { + if (address.is_null() || physical_id.id().is_null()) return; // TODO: We should also be checking that the device_id is in between 0x1000 - 0x107F inclusive - if (id.vendor_id != PCI::VendorID::VirtIO) + if (physical_id.id().vendor_id != PCI::VendorID::VirtIO) return; - switch (id.device_id) { + switch (physical_id.id().device_id) { case PCI::DeviceID::VirtIOConsole: { auto& console = Console::must_create(address).leak_ref(); console.initialize(); @@ -40,7 +40,7 @@ UNMAP_AFTER_INIT void detect() break; } default: - dbgln_if(VIRTIO_DEBUG, "VirtIO: Unknown VirtIO device with ID: {}", id.device_id); + dbgln_if(VIRTIO_DEBUG, "VirtIO: Unknown VirtIO device with ID: {}", physical_id.id().device_id); break; } }); diff --git a/Kernel/Devices/PCISerialDevice.cpp b/Kernel/Devices/PCISerialDevice.cpp index 0dceb028b0..03057fad72 100644 --- a/Kernel/Devices/PCISerialDevice.cpp +++ b/Kernel/Devices/PCISerialDevice.cpp @@ -15,12 +15,12 @@ static SerialDevice* s_the = nullptr; UNMAP_AFTER_INIT void PCISerialDevice::detect() { size_t current_device_minor = 68; - PCI::enumerate([&](const PCI::Address& address, PCI::ID id) { + PCI::enumerate([&](const PCI::Address& address, PCI::PhysicalID const& physical_id) { if (address.is_null()) return; for (auto& board_definition : board_definitions) { - if (board_definition.device_id != id) + if (board_definition.device_id != physical_id.id()) continue; auto bar_base = PCI::get_BAR(address, board_definition.pci_bar) & ~1; diff --git a/Kernel/GlobalProcessExposed.cpp b/Kernel/GlobalProcessExposed.cpp index 5ee5930bf9..a9989f5585 100644 --- a/Kernel/GlobalProcessExposed.cpp +++ b/Kernel/GlobalProcessExposed.cpp @@ -614,19 +614,19 @@ private: virtual KResult try_generate(KBufferBuilder& builder) override { JsonArraySerializer array { builder }; - PCI::enumerate([&array](PCI::Address address, PCI::ID id) { + PCI::enumerate([&array](PCI::Address address, PCI::PhysicalID const& physical_id) { auto obj = array.add_object(); obj.add("domain", address.domain()); obj.add("bus", address.bus()); obj.add("device", address.device()); obj.add("function", address.function()); - obj.add("vendor_id", id.vendor_id); - obj.add("device_id", id.device_id); - obj.add("revision_id", PCI::get_revision_id(address)); - obj.add("subclass", PCI::get_subclass(address)); - obj.add("class", PCI::get_class(address)); - obj.add("subsystem_id", PCI::get_subsystem_id(address)); - obj.add("subsystem_vendor_id", PCI::get_subsystem_vendor_id(address)); + obj.add("vendor_id", physical_id.id().vendor_id); + obj.add("device_id", physical_id.id().device_id); + obj.add("revision_id", physical_id.revision_id().value()); + obj.add("subclass", physical_id.subclass_code().value()); + obj.add("class", physical_id.class_code().value()); + obj.add("subsystem_id", physical_id.subsystem_id().value()); + obj.add("subsystem_vendor_id", physical_id.subsystem_vendor_id().value()); }); array.finish(); return KSuccess; diff --git a/Kernel/Graphics/GraphicsManagement.cpp b/Kernel/Graphics/GraphicsManagement.cpp index d90af78e5e..f27533fd03 100644 --- a/Kernel/Graphics/GraphicsManagement.cpp +++ b/Kernel/Graphics/GraphicsManagement.cpp @@ -179,13 +179,13 @@ UNMAP_AFTER_INIT bool GraphicsManagement::initialize() dbgln("Forcing no initialization of framebuffer devices"); } - PCI::enumerate([&](const PCI::Address& address, PCI::ID id) { + PCI::enumerate([&](const PCI::Address& address, PCI::PhysicalID const& physical_id) { // Note: Each graphics controller will try to set its native screen resolution // upon creation. Later on, if we don't want to have framebuffer devices, a // framebuffer console will take the control instead. if (!is_vga_compatible_pci_device(address) && !is_display_controller_pci_device(address)) return; - determine_and_initialize_graphics_device(address, id); + determine_and_initialize_graphics_device(address, physical_id.id()); }); if (m_graphics_devices.is_empty()) { diff --git a/Kernel/Net/NetworkingManagement.cpp b/Kernel/Net/NetworkingManagement.cpp index efcaad102b..92cc562148 100644 --- a/Kernel/Net/NetworkingManagement.cpp +++ b/Kernel/Net/NetworkingManagement.cpp @@ -91,9 +91,9 @@ UNMAP_AFTER_INIT RefPtr NetworkingManagement::determine_network_ bool NetworkingManagement::initialize() { if (!kernel_command_line().is_physical_networking_disabled()) { - PCI::enumerate([&](const PCI::Address& address, PCI::ID) { + PCI::enumerate([&](const PCI::Address& address, PCI::PhysicalID const& physical_id) { // Note: PCI class 2 is the class of Network devices - if (PCI::get_class(address) != 0x02) + if (physical_id.class_code().value() != 0x02) return; if (auto adapter = determine_network_device(address); !adapter.is_null()) m_adapters.append(adapter.release_nonnull()); diff --git a/Kernel/Storage/StorageManagement.cpp b/Kernel/Storage/StorageManagement.cpp index 6777a74fc6..711132a02d 100644 --- a/Kernel/Storage/StorageManagement.cpp +++ b/Kernel/Storage/StorageManagement.cpp @@ -44,14 +44,14 @@ UNMAP_AFTER_INIT void StorageManagement::enumerate_controllers(bool force_pio) VERIFY(m_controllers.is_empty()); if (!kernel_command_line().disable_physical_storage()) { if (kernel_command_line().is_ide_enabled()) { - PCI::enumerate([&](const PCI::Address& address, PCI::ID) { - if (PCI::get_class(address) == PCI_MASS_STORAGE_CLASS_ID && PCI::get_subclass(address) == PCI_IDE_CTRL_SUBCLASS_ID) { + PCI::enumerate([&](const PCI::Address& address, PCI::PhysicalID const& physical_id) { + if (physical_id.class_code().value() == PCI_MASS_STORAGE_CLASS_ID && physical_id.subclass_code().value() == PCI_IDE_CTRL_SUBCLASS_ID) { m_controllers.append(IDEController::initialize(address, force_pio)); } }); } - PCI::enumerate([&](const PCI::Address& address, PCI::ID) { - if (PCI::get_class(address) == PCI_MASS_STORAGE_CLASS_ID && PCI::get_subclass(address) == PCI_SATA_CTRL_SUBCLASS_ID && PCI::get_programming_interface(address) == PCI_AHCI_IF_PROGIF) { + PCI::enumerate([&](const PCI::Address& address, PCI::PhysicalID const& physical_id) { + if (physical_id.class_code().value() == PCI_MASS_STORAGE_CLASS_ID && physical_id.subclass_code().value() == PCI_SATA_CTRL_SUBCLASS_ID && physical_id.prog_if().value() == PCI_AHCI_IF_PROGIF) { m_controllers.append(AHCIController::initialize(address)); } });