From 8a93c53277f02a689758067675fcf0af99416a8b Mon Sep 17 00:00:00 2001 From: apio Date: Fri, 23 Sep 2022 17:24:45 +0200 Subject: [PATCH] Add a Device class to PCI --- kernel/include/io/PCI.h | 72 +++++++++++++++++++++++++++++++- kernel/src/io/PCI.cpp | 92 +++++++++++++++++++++++++++++++++++------ kernel/src/main.cpp | 7 ++-- 3 files changed, 155 insertions(+), 16 deletions(-) diff --git a/kernel/include/io/PCI.h b/kernel/include/io/PCI.h index f4981f5e..f300e629 100644 --- a/kernel/include/io/PCI.h +++ b/kernel/include/io/PCI.h @@ -1,6 +1,21 @@ #pragma once #include +#define PCI_VENDOR_FIELD 0x0 +#define PCI_DEVICE_FIELD 0x2 +#define PCI_SUBCLASS_FIELD 0xa +#define PCI_CLASS_FIELD 0xb +#define PCI_REVISION_ID_FIELD 0x8 +#define PCI_PROG_IF_FIELD 0x9 +#define PCI_HEADER_TYPE_FIELD 0xe +#define PCI_SECONDARY_BUS_NUMBER_FIELD 0x19 +#define PCI_BAR0_FIELD 0x10 +#define PCI_BAR1_FIELD 0x14 +#define PCI_BAR2_FIELD 0x18 +#define PCI_BAR3_FIELD 0x1C +#define PCI_BAR4_FIELD 0x20 +#define PCI_BAR5_FIELD 0x24 + namespace PCI { struct DeviceID @@ -8,6 +23,7 @@ namespace PCI uint16_t vendor; uint16_t device; }; + struct DeviceType { uint8_t dev_class; @@ -15,6 +31,60 @@ namespace PCI uint8_t prog_if; uint8_t revision; }; + + struct Device + { + void write8(int32_t offset, uint8_t value); + void write16(int32_t offset, uint16_t value); + void write32(int32_t offset, uint32_t value); + uint8_t read8(int32_t offset); + uint16_t read16(int32_t offset); + uint32_t read32(int32_t offset); + + uint32_t getBAR0(); + uint32_t getBAR1(); + uint32_t getBAR2(); + uint32_t getBAR3(); + uint32_t getBAR4(); + uint32_t getBAR5(); + + uint8_t bus() + { + return m_bus; + } + + uint8_t slot() + { + return m_slot; + } + + uint8_t function() + { + return m_function; + } + + DeviceID id() + { + return m_id; + } + + DeviceType type() + { + return m_type; + } + + Device(DeviceID id, DeviceType type, uint8_t bus, uint8_t slot, uint8_t function); + Device(uint8_t bus, uint8_t slot, uint8_t function); + Device(const Device& other); + + private: + uint8_t m_bus; + uint8_t m_slot; + uint8_t m_function; + DeviceID m_id; + DeviceType m_type; + }; + uint32_t raw_address(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset); void raw_write8(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset, uint8_t value); void raw_write16(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset, uint16_t value); @@ -24,5 +94,5 @@ namespace PCI uint32_t raw_read32(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset); DeviceID get_device_id(uint32_t bus, uint32_t slot, uint32_t function); DeviceType get_device_type(uint32_t bus, uint32_t slot, uint32_t function); - void scan(void (*callback)(PCI::DeviceID&, PCI::DeviceType&)); + void scan(void (*callback)(PCI::Device&)); } \ No newline at end of file diff --git a/kernel/src/io/PCI.cpp b/kernel/src/io/PCI.cpp index cb72d84a..0840b805 100644 --- a/kernel/src/io/PCI.cpp +++ b/kernel/src/io/PCI.cpp @@ -8,15 +8,6 @@ #define PCI_ADDRESS 0xCF8 #define PCI_VALUE 0xCFC -#define PCI_VENDOR_FIELD 0x0 -#define PCI_DEVICE_FIELD 0x2 -#define PCI_SUBCLASS_FIELD 0xa -#define PCI_CLASS_FIELD 0xb -#define PCI_REVISION_ID_FIELD 0x8 -#define PCI_PROG_IF_FIELD 0x9 -#define PCI_HEADER_TYPE_FIELD 0xe -#define PCI_SECONDARY_BUS_NUMBER_FIELD 0x19 - Spinlock pci_lock; uint32_t PCI::raw_address(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset) @@ -76,7 +67,7 @@ PCI::DeviceType PCI::get_device_type(uint32_t bus, uint32_t slot, uint32_t funct return {dev_class, dev_subclass, prog_if, revision}; } -static void pci_scan_bus(uint8_t bus, void (*callback)(PCI::DeviceID&, PCI::DeviceType&)) +static void pci_scan_bus(uint8_t bus, void (*callback)(PCI::Device&)) { for (uint8_t slot = 0; slot < 32; slot++) { @@ -96,16 +87,93 @@ static void pci_scan_bus(uint8_t bus, void (*callback)(PCI::DeviceID&, PCI::Devi uint8_t sub_bus = PCI::raw_read8(bus, slot, function, PCI_SECONDARY_BUS_NUMBER_FIELD); pci_scan_bus(sub_bus, callback); } + PCI::Device device{device_id, device_type, bus, slot, function}; pci_lock.release(); - callback(device_id, device_type); + callback(device); pci_lock.acquire(); } } } -void PCI::scan(void (*callback)(PCI::DeviceID&, PCI::DeviceType&)) +void PCI::scan(void (*callback)(PCI::Device&)) { pci_lock.acquire(); pci_scan_bus(0, callback); pci_lock.release(); +} + +PCI::Device::Device(const Device& other) + : m_id(other.m_id), m_type(other.m_type), m_bus(other.m_bus), m_slot(other.m_slot), m_function(other.m_function) +{ +} + +PCI::Device::Device(uint8_t bus, uint8_t slot, uint8_t function) : m_bus(bus), m_slot(slot), m_function(function) +{ + m_id = get_device_id(m_bus, m_slot, m_function); + m_type = get_device_type(m_bus, m_slot, m_function); +} + +PCI::Device::Device(DeviceID id, DeviceType type, uint8_t bus, uint8_t slot, uint8_t function) + : m_id(id), m_type(type), m_bus(bus), m_slot(slot), m_function(function) +{ +} + +void PCI::Device::write8(int32_t offset, uint8_t value) +{ + PCI::raw_write8(m_bus, m_slot, m_function, offset, value); +} + +void PCI::Device::write16(int32_t offset, uint16_t value) +{ + PCI::raw_write16(m_bus, m_slot, m_function, offset, value); +} + +void PCI::Device::write32(int32_t offset, uint32_t value) +{ + PCI::raw_write32(m_bus, m_slot, m_function, offset, value); +} + +uint8_t PCI::Device::read8(int32_t offset) +{ + return PCI::raw_read8(m_bus, m_slot, m_function, offset); +} + +uint16_t PCI::Device::read16(int32_t offset) +{ + return PCI::raw_read16(m_bus, m_slot, m_function, offset); +} + +uint32_t PCI::Device::read32(int32_t offset) +{ + return PCI::raw_read32(m_bus, m_slot, m_function, offset); +} + +uint32_t PCI::Device::getBAR0() +{ + return read32(PCI_BAR0_FIELD); +} + +uint32_t PCI::Device::getBAR1() +{ + return read32(PCI_BAR1_FIELD); +} + +uint32_t PCI::Device::getBAR2() +{ + return read32(PCI_BAR2_FIELD); +} + +uint32_t PCI::Device::getBAR3() +{ + return read32(PCI_BAR3_FIELD); +} + +uint32_t PCI::Device::getBAR4() +{ + return read32(PCI_BAR4_FIELD); +} + +uint32_t PCI::Device::getBAR5() +{ + return read32(PCI_BAR5_FIELD); } \ No newline at end of file diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index ae72a948..31e3c294 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -149,9 +149,10 @@ extern "C" void _start() kinfoln("Interrupts enabled"); - PCI::scan([](PCI::DeviceID& dev_id, PCI::DeviceType& dev_type) { - kinfoln("Found PCI device %x:%x, class %x, subclass %x, prog if %x, revision %d", dev_id.vendor, dev_id.device, - dev_type.dev_class, dev_type.dev_subclass, dev_type.prog_if, dev_type.revision); + PCI::scan([](PCI::Device& dev) { + kinfoln("Found PCI device %x:%x, class %x, subclass %x, prog if %x, revision %d", dev.id().vendor, + dev.id().device, dev.type().dev_class, dev.type().dev_subclass, dev.type().prog_if, + dev.type().revision); }); Scheduler::exit();