From e1709a0904cfe6238035315247bbdaf620d2e7e2 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 8 Apr 2020 16:56:36 +0200 Subject: 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. --- Kernel/Net/E1000NetworkAdapter.cpp | 2 +- Kernel/PCI/Access.cpp | 94 ++++++++++++++++++++++---------------- Kernel/PCI/Access.h | 51 +++------------------ Kernel/PCI/Definitions.h | 2 +- 4 files changed, 62 insertions(+), 87 deletions(-) diff --git a/Kernel/Net/E1000NetworkAdapter.cpp b/Kernel/Net/E1000NetworkAdapter.cpp index bfcdd8cf4c..b83beb62b7 100644 --- a/Kernel/Net/E1000NetworkAdapter.cpp +++ b/Kernel/Net/E1000NetworkAdapter.cpp @@ -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; diff --git a/Kernel/PCI/Access.cpp b/Kernel/PCI/Access.cpp index 4a11948fb5..95507344b6 100644 --- a/Kernel/PCI/Access.cpp +++ b/Kernel/PCI/Access.cpp @@ -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& callback) { Address address(0, bus, slot, function); @@ -79,33 +84,12 @@ void PCI::Access::enumerate_slot(int type, u8 bus, u8 slot, Function& 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 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; } } diff --git a/Kernel/PCI/Access.h b/Kernel/PCI/Access.h index 05cb50e49b..40f8d37495 100644 --- a/Kernel/PCI/Access.h +++ b/Kernel/PCI/Access.h @@ -34,49 +34,10 @@ namespace Kernel { class PCI::Access { public: virtual void enumerate_all(Function&) = 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&) final; - virtual void enumerate_functions(int type, u8 bus, u8 slot, u8 function, Function& callback) final; - virtual void enumerate_slot(int type, u8 bus, u8 slot, Function& callback) final; + void enumerate_bus(int type, u8 bus, Function&); + void enumerate_functions(int type, u8 bus, u8 slot, u8 function, Function& callback); + void enumerate_slot(int type, u8 bus, u8 slot, Function& 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(); }; } diff --git a/Kernel/PCI/Definitions.h b/Kernel/PCI/Definitions.h index 0b2aead57d..cb440a21a7 100644 --- a/Kernel/PCI/Definitions.h +++ b/Kernel/PCI/Definitions.h @@ -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); -- cgit v1.2.3