From 7b8d30aacda109fa3ab3eaf69461056f8f565493 Mon Sep 17 00:00:00 2001 From: apio Date: Fri, 23 Sep 2022 18:01:07 +0200 Subject: [PATCH] Add a Device class to PCI and a PCITypes file for string names for PCI device types --- kernel/include/io/PCI.h | 4 +- kernel/include/misc/PCITypes.h | 4 ++ kernel/src/io/PCI.cpp | 20 +++++++- kernel/src/main.cpp | 5 +- kernel/src/misc/PCITypes.cpp | 85 ++++++++++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 kernel/include/misc/PCITypes.h create mode 100644 kernel/src/misc/PCITypes.cpp diff --git a/kernel/include/io/PCI.h b/kernel/include/io/PCI.h index f300e629..e5bea2e6 100644 --- a/kernel/include/io/PCI.h +++ b/kernel/include/io/PCI.h @@ -78,11 +78,11 @@ namespace PCI Device(const Device& other); private: + DeviceID m_id; + DeviceType m_type; 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); diff --git a/kernel/include/misc/PCITypes.h b/kernel/include/misc/PCITypes.h new file mode 100644 index 00000000..4a537bf6 --- /dev/null +++ b/kernel/include/misc/PCITypes.h @@ -0,0 +1,4 @@ +#pragma once +#include "io/PCI.h" + +const char* pci_type_name(PCI::DeviceType type); \ No newline at end of file diff --git a/kernel/src/io/PCI.cpp b/kernel/src/io/PCI.cpp index 0840b805..97d909aa 100644 --- a/kernel/src/io/PCI.cpp +++ b/kernel/src/io/PCI.cpp @@ -98,7 +98,25 @@ static void pci_scan_bus(uint8_t bus, void (*callback)(PCI::Device&)) void PCI::scan(void (*callback)(PCI::Device&)) { pci_lock.acquire(); - pci_scan_bus(0, callback); + uint8_t function; + uint8_t bus; + + uint8_t header_type = PCI::raw_read8(0, 0, 0, PCI_HEADER_TYPE_FIELD); + if ((header_type & 0x80) == 0) + { + // Single PCI host controller + pci_scan_bus(0, callback); + } + else + { + // Multiple PCI host controllers + for (function = 0; function < 8; function++) + { + if (get_device_id(0, 0, function).vendor != 0xFFFF) break; + bus = function; + pci_scan_bus(bus, callback); + } + } pci_lock.release(); } diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 31e3c294..9328d449 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -19,6 +19,7 @@ #include "memory/MemoryMap.h" #include "memory/RangeAllocator.h" #include "memory/VMM.h" +#include "misc/PCITypes.h" #include "misc/reboot.h" #include "rand/Mersenne.h" #include "render/Framebuffer.h" @@ -150,9 +151,7 @@ extern "C" void _start() kinfoln("Interrupts enabled"); 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); + kinfoln("Found PCI device %x:%x, %s", dev.id().vendor, dev.id().device, pci_type_name(dev.type())); }); Scheduler::exit(); diff --git a/kernel/src/misc/PCITypes.cpp b/kernel/src/misc/PCITypes.cpp new file mode 100644 index 00000000..d8a49c5e --- /dev/null +++ b/kernel/src/misc/PCITypes.cpp @@ -0,0 +1,85 @@ +#include "misc/PCITypes.h" + +static const char* unclassified_device(PCI::DeviceType type) +{ + switch (type.dev_subclass) + { + case 0x0: return "Non-VGA-Compatible Unclassified Device"; + case 0x1: return "VGA-Compatible Unclassified Device"; + + default: return "Unclassified"; + } +} + +static const char* display_controller(PCI::DeviceType type) +{ + switch (type.dev_subclass) + { + case 0x0: return type.prog_if == 1 ? "8514-Compatible Controller" : "VGA Controller"; + case 0x1: return "XGA Controller"; + case 0x2: return "3D Controller (Not VGA-Compatible)"; + case 0x80: return "Display Controller"; + + default: return "Unknown Display Controller"; + } +} + +static const char* memory_controller(PCI::DeviceType type) +{ + switch (type.dev_subclass) + { + case 0x0: return "RAM Controller"; + case 0x1: return "Flash Controller"; + case 0x80: return "Memory Controller"; + + default: return "Unknown Memory Controller"; + } +} + +static const char* processor(PCI::DeviceType type) +{ + switch (type.dev_subclass) + { + case 0x0: return "Processor (386)"; + case 0x1: return "Processor (486)"; + case 0x2: return "Processor (Pentium)"; + case 0x3: return "Processor (Pentium Pro)"; + case 0x10: return "Processor (Alpha)"; + case 0x20: return "Processor (PowerPC)"; + case 0x30: return "Processor (MIPS)"; + case 0x40: return "Co-Processor"; + case 0x80: return "Processor"; + + default: return "Unknown Processor"; + } +} + +const char* pci_type_name(PCI::DeviceType type) +{ + switch (type.dev_class) + { + case 0x0: return unclassified_device(type); + case 0x1: return "Mass Storage Controller"; + case 0x2: return "Network Controller"; + case 0x3: return display_controller(type); + case 0x4: return "Multimedia Controller"; + case 0x5: return memory_controller(type); + case 0x6: return "Bridge"; + case 0x7: return "Simple Communication Controller"; + case 0x8: return "Base System Peripheral"; + case 0x9: return "Input Device Controller"; + case 0xA: return "Docking Station"; + case 0xB: return processor(type); + case 0xC: return "Serial Bus Controller"; + case 0xD: return "Wireless Controller"; + case 0xE: return "Intelligent Controller (I20)"; + case 0xF: return "Satellite Communication Controller"; + case 0x10: return "Encryption Controller"; + case 0x11: return "Signal Processing Controller"; + case 0x12: return "Processing Accelerator"; + case 0x13: return "Non-Essential Instrumentation"; + case 0x40: return "Co-Processor"; + + default: return "Unknown"; + } +} \ No newline at end of file