mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 23:50:19 +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:
parent
e5a20697da
commit
e1709a0904
Notes:
sideshowbarker
2024-07-19 07:48:14 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/e1709a0904c
4 changed files with 62 additions and 87 deletions
|
@ -163,7 +163,7 @@ E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address address, u8 irq)
|
|||
|
||||
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_base = m_mmio_region->vaddr();
|
||||
m_use_mmio = true;
|
||||
|
|
|
@ -49,6 +49,11 @@ PCI::Access::Access()
|
|||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
for (u8 slot = 0; slot < 32; ++slot)
|
||||
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 {
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return PCI::Access::the().get_interrupt_line(address);
|
||||
return PCI::Access::the().read8_field(address, PCI_INTERRUPT_LINE);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return PCI::Access::the().get_BAR1(address);
|
||||
return PCI::Access::the().read32_field(address, PCI_BAR1);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return PCI::Access::the().get_BAR3(address);
|
||||
return PCI::Access::the().read32_field(address, PCI_BAR3);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return PCI::Access::the().get_BAR5(address);
|
||||
return PCI::Access::the().read32_field(address, PCI_BAR5);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return PCI::Access::the().get_subclass(address);
|
||||
return PCI::Access::the().read8_field(address, PCI_SUBCLASS);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,49 +34,10 @@ namespace Kernel {
|
|||
class PCI::Access {
|
||||
public:
|
||||
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)
|
||||
{
|
||||
// See PCI Spec 2.3, Page 222
|
||||
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;
|
||||
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_slot(int type, u8 bus, u8 slot, Function<void(Address, ID)>& callback);
|
||||
|
||||
static Access& the();
|
||||
static bool is_initialized();
|
||||
|
@ -89,12 +50,12 @@ public:
|
|||
virtual void write16_field(Address address, u32 field, u16 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 u16 read16_field(Address address, u32 field) = 0;
|
||||
virtual u32 read32_field(Address address, u32 field) = 0;
|
||||
|
||||
protected:
|
||||
Access();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -186,7 +186,7 @@ u8 get_subclass(Address);
|
|||
u8 get_class(Address);
|
||||
u16 get_subsystem_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 disable_bus_mastering(Address);
|
||||
|
||||
|
|
Loading…
Reference in a new issue