mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 20:27:35 +00:00
Kernel: Keep records of PCI::Address & PCI::ID pairs for enumeration
This commit is contained in:
parent
688dd9ea66
commit
65f939b55c
12 changed files with 49 additions and 13 deletions
|
@ -157,7 +157,7 @@ u32 BXVGADevice::find_framebuffer_address()
|
||||||
static const PCI::ID bochs_vga_id = { 0x1234, 0x1111 };
|
static const PCI::ID bochs_vga_id = { 0x1234, 0x1111 };
|
||||||
static const PCI::ID virtualbox_vga_id = { 0x80ee, 0xbeef };
|
static const PCI::ID virtualbox_vga_id = { 0x80ee, 0xbeef };
|
||||||
u32 framebuffer_address = 0;
|
u32 framebuffer_address = 0;
|
||||||
PCI::enumerate_all([&framebuffer_address](const PCI::Address& address, PCI::ID id) {
|
PCI::enumerate([&framebuffer_address](const PCI::Address& address, PCI::ID id) {
|
||||||
if (id == bochs_vga_id || id == virtualbox_vga_id) {
|
if (id == bochs_vga_id || id == virtualbox_vga_id) {
|
||||||
framebuffer_address = PCI::get_BAR0(address) & 0xfffffff0;
|
framebuffer_address = PCI::get_BAR0(address) & 0xfffffff0;
|
||||||
klog() << "BXVGA: framebuffer @ " << PhysicalAddress(framebuffer_address);
|
klog() << "BXVGA: framebuffer @ " << PhysicalAddress(framebuffer_address);
|
||||||
|
|
|
@ -118,7 +118,7 @@ static Lock& s_lock()
|
||||||
OwnPtr<PATAChannel> PATAChannel::create(ChannelType type, bool force_pio)
|
OwnPtr<PATAChannel> PATAChannel::create(ChannelType type, bool force_pio)
|
||||||
{
|
{
|
||||||
PCI::Address pci_address;
|
PCI::Address pci_address;
|
||||||
PCI::enumerate_all([&](const PCI::Address& address, PCI::ID id) {
|
PCI::enumerate([&](const PCI::Address& address, PCI::ID id) {
|
||||||
if (PCI::get_class(address) == PCI_Mass_Storage_Class && PCI::get_subclass(address) == PCI_IDE_Controller_Subclass) {
|
if (PCI::get_class(address) == PCI_Mass_Storage_Class && PCI::get_subclass(address) == PCI_IDE_Controller_Subclass) {
|
||||||
pci_address = address;
|
pci_address = address;
|
||||||
klog() << "PATAChannel: PATA Controller found, ID " << id;
|
klog() << "PATAChannel: PATA Controller found, ID " << id;
|
||||||
|
|
|
@ -338,7 +338,7 @@ Optional<KBuffer> procfs$pci(InodeIdentifier)
|
||||||
{
|
{
|
||||||
KBufferBuilder builder;
|
KBufferBuilder builder;
|
||||||
JsonArraySerializer array { builder };
|
JsonArraySerializer array { builder };
|
||||||
PCI::enumerate_all([&array](PCI::Address address, PCI::ID id) {
|
PCI::enumerate([&array](PCI::Address address, PCI::ID id) {
|
||||||
auto obj = array.add_object();
|
auto obj = array.add_object();
|
||||||
obj.add("seg", address.seg());
|
obj.add("seg", address.seg());
|
||||||
obj.add("bus", address.bus());
|
obj.add("bus", address.bus());
|
||||||
|
|
|
@ -98,9 +98,16 @@ void Access::enumerate_bus(int type, u8 bus, Function<void(Address, ID)>& callba
|
||||||
enumerate_slot(type, bus, slot, callback);
|
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)
|
void raw_access(Address address, u32 field, size_t access_size, u32 value)
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
|
#include <AK/Vector.h>
|
||||||
#include <Kernel/PCI/Definitions.h>
|
#include <Kernel/PCI/Definitions.h>
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
@ -38,7 +39,7 @@ public:
|
||||||
MMIO,
|
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_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);
|
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;
|
virtual u32 read32_field(Address address, u32 field) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual void enumerate_hardware(Function<void(Address, ID)>) = 0;
|
||||||
|
|
||||||
Access();
|
Access();
|
||||||
|
Vector<PhysicalID> m_physical_ids;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
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 enable_interrupt_line(Address);
|
||||||
void disable_interrupt_line(Address);
|
void disable_interrupt_line(Address);
|
||||||
u8 get_interrupt_line(Address);
|
u8 get_interrupt_line(Address);
|
||||||
|
|
|
@ -39,6 +39,9 @@ void IOAccess::initialize()
|
||||||
IOAccess::IOAccess()
|
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) {
|
||||||
|
m_physical_ids.append({ address, id });
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 IOAccess::read8_field(Address address, u32 field)
|
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);
|
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.
|
// Single PCI host controller.
|
||||||
if ((read8_field(Address(), PCI_HEADER_TYPE) & 0x80) == 0) {
|
if ((read8_field(Address(), PCI_HEADER_TYPE) & 0x80) == 0) {
|
||||||
|
|
|
@ -38,7 +38,7 @@ protected:
|
||||||
IOAccess();
|
IOAccess();
|
||||||
|
|
||||||
private:
|
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 const char* access_type() const override { return "IO-Access"; };
|
||||||
virtual uint32_t segment_count() const override { return 1; };
|
virtual uint32_t segment_count() const override { return 1; };
|
||||||
virtual void write8_field(Address address, u32, u8) override final;
|
virtual void write8_field(Address address, u32, u8) override final;
|
||||||
|
|
|
@ -59,7 +59,7 @@ void initialize()
|
||||||
else
|
else
|
||||||
IOAccess::initialize();
|
IOAccess::initialize();
|
||||||
|
|
||||||
enumerate_all([&](const Address& address, ID id) {
|
enumerate([&](const Address& address, ID id) {
|
||||||
klog() << address << " " << id;
|
klog() << address << " " << id;
|
||||||
E1000NetworkAdapter::detect(address);
|
E1000NetworkAdapter::detect(address);
|
||||||
RTL8139NetworkAdapter::detect(address);
|
RTL8139NetworkAdapter::detect(address);
|
||||||
|
|
|
@ -109,7 +109,9 @@ MMIOAccess::MMIOAccess(PhysicalAddress p_mcfg)
|
||||||
}
|
}
|
||||||
mcfg_region->unmap();
|
mcfg_region->unmap();
|
||||||
klog() << "PCI: MMIO segments - " << m_segments.size();
|
klog() << "PCI: MMIO segments - " << m_segments.size();
|
||||||
|
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
|
|
||||||
#ifdef PCI_DEBUG
|
#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()) << ")";
|
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
|
#endif
|
||||||
|
@ -117,6 +119,10 @@ MMIOAccess::MMIOAccess(PhysicalAddress p_mcfg)
|
||||||
#ifdef PCI_DEBUG
|
#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()) << ")";
|
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
|
#endif
|
||||||
|
|
||||||
|
enumerate_hardware([&](const Address& address, ID id) {
|
||||||
|
m_physical_ids.append({ address, id });
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMIOAccess::map_device(Address address)
|
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;
|
*((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++) {
|
for (u16 seg = 0; seg < m_segments.size(); seg++) {
|
||||||
#ifdef PCI_DEBUG
|
#ifdef PCI_DEBUG
|
||||||
|
|
|
@ -48,7 +48,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
virtual const char* access_type() const override { return "MMIO-Access"; };
|
virtual const char* access_type() const override { return "MMIO-Access"; };
|
||||||
virtual u32 segment_count() const override;
|
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 write8_field(Address address, u32, u8) override;
|
||||||
virtual void write16_field(Address address, u32, u16) override;
|
virtual void write16_field(Address address, u32, u16) override;
|
||||||
virtual void write32_field(Address address, u32, u32) override;
|
virtual void write32_field(Address address, u32, u32) override;
|
||||||
|
|
|
@ -170,7 +170,7 @@ void init_stage2()
|
||||||
dbg() << "Text mode enabled";
|
dbg() << "Text mode enabled";
|
||||||
} else {
|
} else {
|
||||||
bool bxvga_found = false;
|
bool bxvga_found = false;
|
||||||
PCI::enumerate_all([&](const PCI::Address&, PCI::ID id) {
|
PCI::enumerate([&](const PCI::Address&, PCI::ID id) {
|
||||||
if (id.vendor_id == 0x1234 && id.device_id == 0x1111)
|
if (id.vendor_id == 0x1234 && id.device_id == 0x1111)
|
||||||
bxvga_found = true;
|
bxvga_found = true;
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue