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

Kernel: Keep records of PCI::Address & PCI::ID pairs for enumeration

This commit is contained in:
Liav A 2020-04-10 20:25:03 +03:00 committed by Andreas Kling
parent 688dd9ea66
commit 65f939b55c
12 changed files with 49 additions and 13 deletions

View file

@ -98,9 +98,16 @@ void Access::enumerate_bus(int type, u8 bus, Function<void(Address, ID)>& callba
enumerate_slot(type, bus, slot, callback);
}
void enumerate_all(Function<void(Address, ID)> callback)
void Access::enumerate(Function<void(Address, ID)>& callback) const
{
Access::the().enumerate_all(callback);
for (auto& physical_id : m_physical_ids) {
callback(physical_id.address(), physical_id.id());
}
}
void enumerate(Function<void(Address, ID)> callback)
{
Access::the().enumerate(callback);
}
void raw_access(Address address, u32 field, size_t access_size, u32 value)

View file

@ -27,6 +27,7 @@
#pragma once
#include <AK/String.h>
#include <AK/Vector.h>
#include <Kernel/PCI/Definitions.h>
namespace Kernel {
@ -38,7 +39,7 @@ public:
MMIO,
};
virtual void enumerate_all(Function<void(Address, ID)>&) = 0;
void enumerate(Function<void(Address, ID)>&) const;
void enumerate_bus(int type, u8 bus, Function<void(Address, ID)>&);
void enumerate_functions(int type, u8 bus, u8 slot, u8 function, Function<void(Address, ID)>& callback);
@ -60,7 +61,10 @@ public:
virtual u32 read32_field(Address address, u32 field) = 0;
protected:
virtual void enumerate_hardware(Function<void(Address, ID)>) = 0;
Access();
Vector<PhysicalID> m_physical_ids;
};
}

View file

@ -172,8 +172,24 @@ struct ChangeableAddress : public Address {
}
};
class PhysicalID {
public:
PhysicalID(Address address, ID id)
: m_address(address)
, m_id(id)
{
}
const ID& id() const { return m_id; }
const Address& address() const { return m_address; }
private:
Address m_address;
ID m_id;
};
ID get_id(PCI::Address);
void enumerate_all(Function<void(Address, ID)> callback);
void enumerate(Function<void(Address, ID)> callback);
void enable_interrupt_line(Address);
void disable_interrupt_line(Address);
u8 get_interrupt_line(Address);

View file

@ -39,6 +39,9 @@ void IOAccess::initialize()
IOAccess::IOAccess()
{
klog() << "PCI: Using I/O instructions for PCI configuration space access";
enumerate_hardware([&](const Address& address, ID id) {
m_physical_ids.append({ address, id });
});
}
u8 IOAccess::read8_field(Address address, u32 field)
@ -75,7 +78,7 @@ void IOAccess::write32_field(Address address, u32 field, u32 value)
IO::out32(PCI_VALUE_PORT, value);
}
void IOAccess::enumerate_all(Function<void(Address, ID)>& callback)
void IOAccess::enumerate_hardware(Function<void(Address, ID)> callback)
{
// Single PCI host controller.
if ((read8_field(Address(), PCI_HEADER_TYPE) & 0x80) == 0) {

View file

@ -38,7 +38,7 @@ protected:
IOAccess();
private:
virtual void enumerate_all(Function<void(Address, ID)>&) override;
virtual void enumerate_hardware(Function<void(Address, ID)>) override;
virtual const char* access_type() const override { return "IO-Access"; };
virtual uint32_t segment_count() const override { return 1; };
virtual void write8_field(Address address, u32, u8) override final;

View file

@ -59,7 +59,7 @@ void initialize()
else
IOAccess::initialize();
enumerate_all([&](const Address& address, ID id) {
enumerate([&](const Address& address, ID id) {
klog() << address << " " << id;
E1000NetworkAdapter::detect(address);
RTL8139NetworkAdapter::detect(address);

View file

@ -109,7 +109,9 @@ MMIOAccess::MMIOAccess(PhysicalAddress p_mcfg)
}
mcfg_region->unmap();
klog() << "PCI: MMIO segments - " << m_segments.size();
InterruptDisabler disabler;
#ifdef PCI_DEBUG
dbg() << "PCI: mapped address (" << String::format("%w", m_mapped_address.seg()) << ":" << String::format("%b", m_mapped_address.bus()) << ":" << String::format("%b", m_mapped_address.slot()) << "." << String::format("%b", m_mapped_address.function()) << ")";
#endif
@ -117,6 +119,10 @@ MMIOAccess::MMIOAccess(PhysicalAddress p_mcfg)
#ifdef PCI_DEBUG
dbg() << "PCI: Default mapped address (" << String::format("%w", m_mapped_address.seg()) << ":" << String::format("%b", m_mapped_address.bus()) << ":" << String::format("%b", m_mapped_address.slot()) << "." << String::format("%b", m_mapped_address.function()) << ")";
#endif
enumerate_hardware([&](const Address& address, ID id) {
m_physical_ids.append({ address, id });
});
}
void MMIOAccess::map_device(Address address)
@ -204,7 +210,7 @@ void MMIOAccess::write32_field(Address address, u32 field, u32 value)
*((u32*)(m_mmio_window_region->vaddr().get() + (field & 0xfff))) = value;
}
void MMIOAccess::enumerate_all(Function<void(Address, ID)>& callback)
void MMIOAccess::enumerate_hardware(Function<void(Address, ID)> callback)
{
for (u16 seg = 0; seg < m_segments.size(); seg++) {
#ifdef PCI_DEBUG

View file

@ -48,7 +48,7 @@ protected:
private:
virtual const char* access_type() const override { return "MMIO-Access"; };
virtual u32 segment_count() const override;
virtual void enumerate_all(Function<void(Address, ID)>&) override;
virtual void enumerate_hardware(Function<void(Address, ID)>) override;
virtual void write8_field(Address address, u32, u8) override;
virtual void write16_field(Address address, u32, u16) override;
virtual void write32_field(Address address, u32, u32) override;