diff options
Diffstat (limited to 'Kernel/PCI')
-rw-r--r-- | Kernel/PCI/Access.cpp | 94 | ||||
-rw-r--r-- | Kernel/PCI/Access.h | 51 | ||||
-rw-r--r-- | Kernel/PCI/Definitions.h | 2 |
3 files changed, 61 insertions, 86 deletions
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<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; } } 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<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(); }; } 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); |