1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 18:07:35 +00:00

Kernel: Remove an unnecessary layer of indirection in the PCI code

The PCI access layer was composed of a bunch of virtual functions that
did nothing but call other virtual functions. The first layer was never
overridden so there was no need for them to be virtual.

This patch removes the indirection and moves logic from PCI::Access
down into the various PCI::get_foo() helpers that were the sole users.
This commit is contained in:
Andreas Kling 2020-04-08 16:56:36 +02:00
parent e5a20697da
commit e1709a0904
4 changed files with 62 additions and 87 deletions

View file

@ -163,7 +163,7 @@ E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address address, u8 irq)
enable_bus_mastering(pci_address()); enable_bus_mastering(pci_address());
size_t mmio_base_size = PCI::get_BAR_Space_Size(pci_address(), 0); size_t mmio_base_size = PCI::get_BAR_space_size(pci_address(), 0);
m_mmio_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of(PCI::get_BAR0(pci_address()))), PAGE_ROUND_UP(mmio_base_size), "E1000 MMIO", Region::Access::Read | Region::Access::Write, false, false); m_mmio_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of(PCI::get_BAR0(pci_address()))), PAGE_ROUND_UP(mmio_base_size), "E1000 MMIO", Region::Access::Read | Region::Access::Write, false, false);
m_mmio_base = m_mmio_region->vaddr(); m_mmio_base = m_mmio_region->vaddr();
m_use_mmio = true; m_use_mmio = true;

View file

@ -49,6 +49,11 @@ PCI::Access::Access()
s_access = this; s_access = this;
} }
static u16 read_type(PCI::Address address)
{
return (PCI::Access::the().read8_field(address, PCI_CLASS) << 8u) | PCI::Access::the().read8_field(address, PCI_SUBCLASS);
}
void PCI::Access::enumerate_functions(int type, u8 bus, u8 slot, u8 function, Function<void(Address, ID)>& callback) void PCI::Access::enumerate_functions(int type, u8 bus, u8 slot, u8 function, Function<void(Address, ID)>& callback)
{ {
Address address(0, bus, slot, function); Address address(0, bus, slot, function);
@ -79,33 +84,12 @@ void PCI::Access::enumerate_slot(int type, u8 bus, u8 slot, Function<void(Addres
} }
} }
PCI::ID PCI::Access::get_id(Address address)
{
return { read16_field(address, PCI_VENDOR_ID), read16_field(address, PCI_DEVICE_ID) };
}
void PCI::Access::enumerate_bus(int type, u8 bus, Function<void(Address, ID)>& callback) void PCI::Access::enumerate_bus(int type, u8 bus, Function<void(Address, ID)>& callback)
{ {
for (u8 slot = 0; slot < 32; ++slot) for (u8 slot = 0; slot < 32; ++slot)
enumerate_slot(type, bus, slot, callback); enumerate_slot(type, bus, slot, callback);
} }
void PCI::Access::enable_bus_mastering(Address address)
{
auto value = read16_field(address, PCI_COMMAND);
value |= (1 << 2);
value |= (1 << 0);
write16_field(address, PCI_COMMAND, value);
}
void PCI::Access::disable_bus_mastering(Address address)
{
auto value = read16_field(address, PCI_COMMAND);
value &= ~(1 << 2);
value |= (1 << 0);
write16_field(address, PCI_COMMAND, value);
}
namespace PCI { namespace PCI {
void enumerate_all(Function<void(Address, ID)> callback) void enumerate_all(Function<void(Address, ID)> callback)
@ -133,77 +117,107 @@ void raw_access(Address address, u32 field, size_t access_size, u32 value)
ID get_id(Address address) ID get_id(Address address)
{ {
return PCI::Access::the().get_id(address); return { PCI::Access::the().read16_field(address, PCI_VENDOR_ID), PCI::Access::the().read16_field(address, PCI_DEVICE_ID) };
} }
void enable_interrupt_line(Address address) void enable_interrupt_line(Address address)
{ {
PCI::Access::the().enable_interrupt_line(address); PCI::Access::the().write16_field(address, PCI_COMMAND, PCI::Access::the().read16_field(address, PCI_COMMAND) & ~(1 << 10));
} }
void disable_interrupt_line(Address address) void disable_interrupt_line(Address address)
{ {
PCI::Access::the().disable_interrupt_line(address); PCI::Access::the().write16_field(address, PCI_COMMAND, PCI::Access::the().read16_field(address, PCI_COMMAND) | 1 << 10);
} }
u8 get_interrupt_line(Address address) u8 get_interrupt_line(Address address)
{ {
return PCI::Access::the().get_interrupt_line(address); return PCI::Access::the().read8_field(address, PCI_INTERRUPT_LINE);
} }
u32 get_BAR0(Address address) u32 get_BAR0(Address address)
{ {
return PCI::Access::the().get_BAR0(address); return PCI::Access::the().read32_field(address, PCI_BAR0);
} }
u32 get_BAR1(Address address) u32 get_BAR1(Address address)
{ {
return PCI::Access::the().get_BAR1(address); return PCI::Access::the().read32_field(address, PCI_BAR1);
} }
u32 get_BAR2(Address address) u32 get_BAR2(Address address)
{ {
return PCI::Access::the().get_BAR2(address); return PCI::Access::the().read32_field(address, PCI_BAR2);
} }
u32 get_BAR3(Address address) u32 get_BAR3(Address address)
{ {
return PCI::Access::the().get_BAR3(address); return PCI::Access::the().read32_field(address, PCI_BAR3);
} }
u32 get_BAR4(Address address) u32 get_BAR4(Address address)
{ {
return PCI::Access::the().get_BAR4(address); return PCI::Access::the().read32_field(address, PCI_BAR4);
} }
u32 get_BAR5(Address address) u32 get_BAR5(Address address)
{ {
return PCI::Access::the().get_BAR5(address); return PCI::Access::the().read32_field(address, PCI_BAR5);
} }
u8 get_revision_id(Address address) u8 get_revision_id(Address address)
{ {
return PCI::Access::the().get_revision_id(address); return PCI::Access::the().read8_field(address, PCI_REVISION_ID);
} }
u8 get_subclass(Address address) u8 get_subclass(Address address)
{ {
return PCI::Access::the().get_subclass(address); return PCI::Access::the().read8_field(address, PCI_SUBCLASS);
} }
u8 get_class(Address address) u8 get_class(Address address)
{ {
return PCI::Access::the().get_class(address); return PCI::Access::the().read8_field(address, PCI_CLASS);
} }
u16 get_subsystem_id(Address address) u16 get_subsystem_id(Address address)
{ {
return PCI::Access::the().get_subsystem_id(address); return PCI::Access::the().read16_field(address, PCI_SUBSYSTEM_ID);
} }
u16 get_subsystem_vendor_id(Address address) u16 get_subsystem_vendor_id(Address address)
{ {
return PCI::Access::the().get_subsystem_vendor_id(address); return PCI::Access::the().read16_field(address, PCI_SUBSYSTEM_VENDOR_ID);
} }
void enable_bus_mastering(Address address) void enable_bus_mastering(Address address)
{ {
PCI::Access::the().enable_bus_mastering(address); auto value = PCI::Access::the().read16_field(address, PCI_COMMAND);
value |= (1 << 2);
value |= (1 << 0);
PCI::Access::the().write16_field(address, PCI_COMMAND, value);
} }
void disable_bus_mastering(Address address) void disable_bus_mastering(Address address)
{ {
PCI::Access::the().disable_bus_mastering(address); auto value = PCI::Access::the().read16_field(address, PCI_COMMAND);
value &= ~(1 << 2);
value |= (1 << 0);
PCI::Access::the().write16_field(address, PCI_COMMAND, value);
} }
size_t get_BAR_Space_Size(Address address, u8 bar_number)
size_t get_BAR_space_size(Address address, u8 bar_number)
{ {
return PCI::Access::the().get_BAR_Space_Size(address, bar_number); // See PCI Spec 2.3, Page 222
ASSERT(bar_number < 6);
u8 field = (PCI_BAR0 + (bar_number << 2));
u32 bar_reserved = PCI::Access::the().read32_field(address, field);
PCI::Access::the().write32_field(address, field, 0xFFFFFFFF);
u32 space_size = PCI::Access::the().read32_field(address, field);
PCI::Access::the().write32_field(address, field, bar_reserved);
space_size &= 0xfffffff0;
space_size = (~space_size) + 1;
return space_size;
} }
} }

View file

@ -34,49 +34,10 @@ namespace Kernel {
class PCI::Access { class PCI::Access {
public: public:
virtual void enumerate_all(Function<void(Address, ID)>&) = 0; virtual void enumerate_all(Function<void(Address, ID)>&) = 0;
virtual u8 get_interrupt_line(Address address) { return read8_field(address, PCI_INTERRUPT_LINE); }
virtual u32 get_BAR0(Address address) { return read32_field(address, PCI_BAR0); }
virtual u32 get_BAR1(Address address) { return read32_field(address, PCI_BAR1); }
virtual u32 get_BAR2(Address address) { return read32_field(address, PCI_BAR2); }
virtual u32 get_BAR3(Address address) { return read32_field(address, PCI_BAR3); }
virtual u32 get_BAR4(Address address) { return read32_field(address, PCI_BAR4); }
virtual u32 get_BAR5(Address address) { return read32_field(address, PCI_BAR5); }
virtual size_t get_BAR_Space_Size(Address address, u8 bar_number) 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);
// See PCI Spec 2.3, Page 222 void enumerate_slot(int type, u8 bus, u8 slot, Function<void(Address, ID)>& callback);
ASSERT(bar_number < 6);
u8 field = (PCI_BAR0 + (bar_number << 2));
u32 bar_reserved = read32_field(address, field);
write32_field(address, field, 0xFFFFFFFF);
u32 space_size = read32_field(address, field);
write32_field(address, field, bar_reserved);
space_size &= 0xfffffff0;
space_size = (~space_size) + 1;
return space_size;
}
virtual ID get_id(Address address) final;
virtual void enable_interrupt_line(Address address) final
{
write16_field(address, PCI_COMMAND, read16_field(address, PCI_COMMAND) & ~(1 << 10));
}
virtual void disable_interrupt_line(Address address) final
{
write16_field(address, PCI_COMMAND, read16_field(address, PCI_COMMAND) | 1 << 10);
}
virtual u8 get_revision_id(Address address) { return read8_field(address, PCI_REVISION_ID); }
virtual u8 get_subclass(Address address) { return read8_field(address, PCI_SUBCLASS); }
virtual u8 get_class(Address address) { return read8_field(address, PCI_CLASS); }
virtual u16 get_subsystem_id(Address address) { return read16_field(address, PCI_SUBSYSTEM_ID); }
virtual u16 get_subsystem_vendor_id(Address address) { return read16_field(address, PCI_SUBSYSTEM_VENDOR_ID); }
virtual u16 read_type(Address address) { return (read8_field(address, PCI_CLASS) << 8u) | read8_field(address, PCI_SUBCLASS); }
virtual void enable_bus_mastering(Address) final;
virtual void disable_bus_mastering(Address) final;
virtual void enumerate_bus(int type, u8 bus, Function<void(Address, ID)>&) final;
virtual void enumerate_functions(int type, u8 bus, u8 slot, u8 function, Function<void(Address, ID)>& callback) final;
virtual void enumerate_slot(int type, u8 bus, u8 slot, Function<void(Address, ID)>& callback) final;
static Access& the(); static Access& the();
static bool is_initialized(); static bool is_initialized();
@ -89,12 +50,12 @@ public:
virtual void write16_field(Address address, u32 field, u16 value) = 0; virtual void write16_field(Address address, u32 field, u16 value) = 0;
virtual void write32_field(Address address, u32 field, u32 value) = 0; virtual void write32_field(Address address, u32 field, u32 value) = 0;
protected:
Access();
virtual u8 read8_field(Address address, u32 field) = 0; virtual u8 read8_field(Address address, u32 field) = 0;
virtual u16 read16_field(Address address, u32 field) = 0; virtual u16 read16_field(Address address, u32 field) = 0;
virtual u32 read32_field(Address address, u32 field) = 0; virtual u32 read32_field(Address address, u32 field) = 0;
protected:
Access();
}; };
} }

View file

@ -186,7 +186,7 @@ u8 get_subclass(Address);
u8 get_class(Address); 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);
void enable_bus_mastering(Address); void enable_bus_mastering(Address);
void disable_bus_mastering(Address); void disable_bus_mastering(Address);