1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 02:27:43 +00:00

Kernel/PCI: Cache more details about PCI devices when enumerating them

There's no good reason to fetch these values each time we need them.
This commit is contained in:
Liav A 2021-09-23 09:05:34 +03:00 committed by Andreas Kling
parent e22d9dc360
commit 82bb08a15c
14 changed files with 85 additions and 41 deletions

View file

@ -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<void(Address, ID)> callback)
void enumerate(Function<void(Address, PhysicalID const&)> callback)
{
Access::the().fast_enumerate(callback);
}

View file

@ -19,7 +19,7 @@ u32 read32(Address address, u32 field);
ID get_id(PCI::Address);
bool is_io_space_enabled(Address);
void enumerate(Function<void(Address, ID)> callback);
void enumerate(Function<void(Address, PhysicalID const&)> callback);
void enable_interrupt_line(Address);
void disable_interrupt_line(Address);
u8 get_interrupt_line(Address);

View file

@ -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<void(Address, ID)>& callback) const
void Access::fast_enumerate(Function<void(Address, PhysicalID const&)>& 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);
}
}

View file

@ -25,7 +25,7 @@ public:
static bool initialize_for_memory_access(PhysicalAddress mcfg_table);
static bool initialize_for_io_access();
void fast_enumerate(Function<void(Address, ID)>&) const;
void fast_enumerate(Function<void(Address, PhysicalID const&)>&) const;
void rescan_hardware();
static Access& the();

View file

@ -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<Capability> 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<Capability> 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<Access>, SubclassCode new_subclass)
{
m_subclass_code = new_subclass;
}
void apply_prog_if_change(Badge<Access>, 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<Capability> m_capabilities;
};
class Access;
class Domain;
class Device;
}

View file

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

View file

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