mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:17:34 +00:00
PCI: Add list of capabilities for each device during first enumeration
This commit is contained in:
parent
9d10eb473d
commit
85b4256d10
4 changed files with 44 additions and 3 deletions
|
@ -129,6 +129,30 @@ void enumerate(Function<void(Address, ID)> callback)
|
||||||
Access::the().enumerate(callback);
|
Access::the().enumerate(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Optional<u8> get_capabilities_pointer(Address address)
|
||||||
|
{
|
||||||
|
if (PCI::read16(address, PCI_STATUS) & (1 << 4)) {
|
||||||
|
return PCI::read8(address, PCI_CAPABILITIES_POINTER);
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<Capability> get_capabilities(Address address)
|
||||||
|
{
|
||||||
|
auto capabilities_pointer = PCI::get_capabilities_pointer(address);
|
||||||
|
if (!capabilities_pointer.has_value())
|
||||||
|
return {};
|
||||||
|
Vector<Capability> capabilities;
|
||||||
|
auto capability_pointer = capabilities_pointer.value();
|
||||||
|
while (capability_pointer != 0) {
|
||||||
|
u16 capability_header = PCI::read16(address, capability_pointer);
|
||||||
|
u8 capability_id = capability_header & 0xff;
|
||||||
|
capability_pointer = capability_header >> 8;
|
||||||
|
capabilities.append({ capability_id, capability_pointer });
|
||||||
|
}
|
||||||
|
return capabilities;
|
||||||
|
}
|
||||||
|
|
||||||
void raw_access(Address address, u32 field, size_t access_size, u32 value)
|
void raw_access(Address address, u32 field, size_t access_size, u32 value)
|
||||||
{
|
{
|
||||||
ASSERT(access_size != 0);
|
ASSERT(access_size != 0);
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <AK/LogStream.h>
|
#include <AK/LogStream.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
|
#include <AK/Vector.h>
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
@ -180,20 +181,33 @@ struct ChangeableAddress : public Address {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Capability {
|
||||||
|
u8 m_id;
|
||||||
|
u8 m_next_pointer;
|
||||||
|
};
|
||||||
|
|
||||||
class PhysicalID {
|
class PhysicalID {
|
||||||
public:
|
public:
|
||||||
PhysicalID(Address address, ID id)
|
PhysicalID(Address address, ID id, Vector<Capability> capabilities)
|
||||||
: m_address(address)
|
: m_address(address)
|
||||||
, m_id(id)
|
, m_id(id)
|
||||||
|
, m_capabilities(capabilities)
|
||||||
{
|
{
|
||||||
|
#ifdef PCI_DEBUG
|
||||||
|
for (auto capability : capabilities) {
|
||||||
|
dbg() << address << " has capbility " << capability.m_id;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector<Capability> capabilities() const { return m_capabilities; }
|
||||||
const ID& id() const { return m_id; }
|
const ID& id() const { return m_id; }
|
||||||
const Address& address() const { return m_address; }
|
const Address& address() const { return m_address; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Address m_address;
|
Address m_address;
|
||||||
ID m_id;
|
ID m_id;
|
||||||
|
Vector<Capability> m_capabilities;
|
||||||
};
|
};
|
||||||
|
|
||||||
ID get_id(PCI::Address);
|
ID get_id(PCI::Address);
|
||||||
|
@ -215,8 +229,11 @@ u8 get_class(Address);
|
||||||
u16 get_subsystem_id(Address);
|
u16 get_subsystem_id(Address);
|
||||||
u16 get_subsystem_vendor_id(Address);
|
u16 get_subsystem_vendor_id(Address);
|
||||||
size_t get_BAR_space_size(Address, u8);
|
size_t get_BAR_space_size(Address, u8);
|
||||||
|
Optional<u8> get_capabilities_pointer(Address);
|
||||||
|
Vector<Capability> get_capabilities(Address);
|
||||||
void enable_bus_mastering(Address);
|
void enable_bus_mastering(Address);
|
||||||
void disable_bus_mastering(Address);
|
void disable_bus_mastering(Address);
|
||||||
|
PhysicalID get_physical_id(Address address);
|
||||||
|
|
||||||
class Access;
|
class Access;
|
||||||
class MMIOAccess;
|
class MMIOAccess;
|
||||||
|
|
|
@ -40,7 +40,7 @@ IOAccess::IOAccess()
|
||||||
{
|
{
|
||||||
klog() << "PCI: Using I/O instructions for PCI configuration space access";
|
klog() << "PCI: Using I/O instructions for PCI configuration space access";
|
||||||
enumerate_hardware([&](const Address& address, ID id) {
|
enumerate_hardware([&](const Address& address, ID id) {
|
||||||
m_physical_ids.append({ address, id });
|
m_physical_ids.append({ address, id, get_capabilities(address) });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,7 @@ MMIOAccess::MMIOAccess(PhysicalAddress p_mcfg)
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
|
|
||||||
enumerate_hardware([&](const Address& address, ID id) {
|
enumerate_hardware([&](const Address& address, ID id) {
|
||||||
m_physical_ids.append({ address, id });
|
m_physical_ids.append({ address, id, get_capabilities(address) });
|
||||||
m_mapped_device_regions.append(make<DeviceConfigurationSpaceMapping>(address, m_segments.get(address.seg()).value()));
|
m_mapped_device_regions.append(make<DeviceConfigurationSpaceMapping>(address, m_segments.get(address.seg()).value()));
|
||||||
#ifdef PCI_DEBUG
|
#ifdef PCI_DEBUG
|
||||||
dbg() << "PCI: Mapping device @ pci (" << String::format("%w", address.seg()) << ":" << String::format("%b", address.bus()) << ":" << String::format("%b", address.slot()) << "." << String::format("%b", address.function()) << ")"
|
dbg() << "PCI: Mapping device @ pci (" << String::format("%w", address.seg()) << ":" << String::format("%b", address.bus()) << ":" << String::format("%b", address.slot()) << "." << String::format("%b", address.function()) << ")"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue