From c1ebca273a0aa617050737ccb311f3d94af3e186 Mon Sep 17 00:00:00 2001 From: SpookyDervish Date: Thu, 29 Jan 2026 17:38:44 +1100 Subject: [PATCH] enumerate pci devices --- kernel/Makefile | 2 +- kernel/src/acpi.h | 8 +++ kernel/src/kernel.cpp | 6 +++ kernel/src/kernelUtil.cpp | 18 ++++--- kernel/src/kernelUtil.h | 1 + kernel/src/paging/PageTableManager.cpp | 4 +- kernel/src/paging/PageTableManager.h | 6 ++- kernel/src/pci.cpp | 67 +++++++++++++++++++++++++- kernel/src/pci.h | 26 +++++++++- 9 files changed, 127 insertions(+), 11 deletions(-) diff --git a/kernel/Makefile b/kernel/Makefile index 890a384..7f5a72d 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -61,4 +61,4 @@ buildimg: mcopy -i $(BUILDDIR)/$(OSNAME).img $(BUILDDIR)/zap-light18.psf :: run: - qemu-system-x86_64 -machine q35 -drive file=$(BUILDDIR)/$(OSNAME).img -m 256M -cpu qemu64 -drive if=pflash,format=raw,unit=0,file="$(OVMFDIR)/OVMF_CODE-pure-efi.fd",readonly=on -drive if=pflash,format=raw,unit=1,file="$(OVMFDIR)/OVMF_VARS-pure-efi.fd" -net none + qemu-system-x86_64 -machine q35 -drive file=$(BUILDDIR)/$(OSNAME).img -m 42M -cpu qemu64 -drive if=pflash,format=raw,unit=0,file="$(OVMFDIR)/OVMF_CODE-pure-efi.fd",readonly=on -drive if=pflash,format=raw,unit=1,file="$(OVMFDIR)/OVMF_VARS-pure-efi.fd" -net none \ No newline at end of file diff --git a/kernel/src/acpi.h b/kernel/src/acpi.h index 7b7668e..6a35f1b 100644 --- a/kernel/src/acpi.h +++ b/kernel/src/acpi.h @@ -31,5 +31,13 @@ namespace ACPI { uint64_t Reserved; }__attribute__((packed)); + struct DeviceConfig { + uint64_t BaseAddress; + uint16_t PCISegGroup; + uint8_t StartBus; + uint8_t EndBus; + uint32_t Reserved; + }__attribute__((packed)); + void* FindTable(SDTHeader* sdtHeader, char* signature); }; \ No newline at end of file diff --git a/kernel/src/kernel.cpp b/kernel/src/kernel.cpp index d95d1d6..d39f77b 100644 --- a/kernel/src/kernel.cpp +++ b/kernel/src/kernel.cpp @@ -2,6 +2,12 @@ extern "C" void _start(BootInfo* bootInfo) { KernelInfo kernelInfo = InitializeKernel(bootInfo); + + int x = 0; + for (int i = 0; i < 100000; i++) { + x += i; + } + PageTableManager* pageTableManager = kernelInfo.pageTableManager; while (true) { diff --git a/kernel/src/kernelUtil.cpp b/kernel/src/kernelUtil.cpp index 1d172c3..7c64565 100644 --- a/kernel/src/kernelUtil.cpp +++ b/kernel/src/kernelUtil.cpp @@ -11,7 +11,7 @@ extern "C" void __stack_chk_fail(void) { #include "IO.h" KernelInfo kernelInfo; -PageTableManager pageTableManager = NULL; + void PrepareMemory(BootInfo* bootInfo){ GlobalRenderer->Print("Preparing memory..."); GlobalRenderer->Next(); @@ -25,28 +25,28 @@ void PrepareMemory(BootInfo* bootInfo){ GlobalAllocator.LockPages(&_KernelStart, kernelPages); - /*GlobalRenderer->Print(" - Setting up page table manager..."); + GlobalRenderer->Print(" - Setting up page table manager..."); GlobalRenderer->Next(); PageTable* PML4 = (PageTable*)GlobalAllocator.RequestPage(); memset(PML4, 0, 0x1000); - pageTableManager = PageTableManager(PML4); + GlobalPTM = PageTableManager(PML4); for (uint64_t t = 0; t < GetMemorySize(bootInfo->mMap, mMapEntries, bootInfo->mMapDescriptorSize); t+= 0x1000){ - pageTableManager.MapMemory((void*)t, (void*)t); + GlobalPTM.MapMemory((void*)t, (void*)t); } uint64_t fbBase = (uint64_t)bootInfo->framebuffer->BaseAddress; uint64_t fbSize = (uint64_t)bootInfo->framebuffer->BufferSize + 0x1000; GlobalAllocator.LockPages((void*)fbBase, fbSize/ 0x1000 + 1); for (uint64_t t = fbBase; t < fbBase + fbSize; t += 4096){ - pageTableManager.MapMemory((void*)t, (void*)t); + GlobalPTM.MapMemory((void*)t, (void*)t); } asm ("mov %0, %%cr3" : : "r" (PML4)); - kernelInfo.pageTableManager = &pageTableManager;*/ + kernelInfo.pageTableManager = &GlobalPTM; } IDTR idtr; @@ -80,6 +80,12 @@ void PrepareACPI(BootInfo* bootInfo) { GlobalRenderer->Print("MCFG header location: 0x"); GlobalRenderer->Print(to_hstring((uint64_t)mcfg)); GlobalRenderer->Next(); + + GlobalRenderer->Print("Enumerating PCI devices..."); + GlobalRenderer->Next(); + PCI::EnumeratePCI(mcfg); + + GlobalRenderer->Print("Done enumerating devices!"); GlobalRenderer->Next(); } diff --git a/kernel/src/kernelUtil.h b/kernel/src/kernelUtil.h index 5c9d102..c4468f7 100644 --- a/kernel/src/kernelUtil.h +++ b/kernel/src/kernelUtil.h @@ -13,6 +13,7 @@ #include "paging/PageTableManager.h" #include "userinput/mouse.h" #include "acpi.h" +#include "pci.h" struct BootInfo { Framebuffer* framebuffer; diff --git a/kernel/src/paging/PageTableManager.cpp b/kernel/src/paging/PageTableManager.cpp index b3dbd9e..26b3543 100644 --- a/kernel/src/paging/PageTableManager.cpp +++ b/kernel/src/paging/PageTableManager.cpp @@ -3,6 +3,9 @@ #include #include "PageFrameAllocator.h" #include "../memory.h" +#include "../BasicRenderer.h" + +PageTableManager GlobalPTM = NULL; PageTableManager::PageTableManager(PageTable* PML4Address) { this->PML4 = PML4Address; @@ -27,7 +30,6 @@ void PageTableManager::MapMemory(void* virtualMemory, void* physicalMemory){ PDP = (PageTable*)((uint64_t)PDE.GetAddress() << 12); } - PDE = PDP->entries[indexer.PD_i]; PageTable* PD; if (!PDE.GetFlag(PT_Flag::Present)){ diff --git a/kernel/src/paging/PageTableManager.h b/kernel/src/paging/PageTableManager.h index 7e9bea2..b2063fc 100644 --- a/kernel/src/paging/PageTableManager.h +++ b/kernel/src/paging/PageTableManager.h @@ -1,9 +1,13 @@ #pragma once #include "paging.h" + + class PageTableManager { public: PageTableManager(PageTable* PML4Address); PageTable* PML4; void MapMemory(void* virtualMemory, void* physicalMemory); -}; \ No newline at end of file +}; + +extern PageTableManager GlobalPTM; \ No newline at end of file diff --git a/kernel/src/pci.cpp b/kernel/src/pci.cpp index ec1ff88..f039ab4 100644 --- a/kernel/src/pci.cpp +++ b/kernel/src/pci.cpp @@ -1 +1,66 @@ -#include "pci.h" \ No newline at end of file +#include "pci.h" + +namespace PCI { + + void EnumerateFunction(uint64_t deviceAddress, uint64_t function) { + uint64_t offset = function << 12; + + uint64_t functionAddress = deviceAddress + offset; + GlobalPTM.MapMemory((void*)functionAddress, (void*)functionAddress); + + PCIDeviceHeader* pciDeviceHeader = (PCIDeviceHeader*)functionAddress; + + if (pciDeviceHeader->DeviceID == 0) return; // device is not valid + if (pciDeviceHeader->DeviceID == 0xFFFF) return; // device is not valid + + GlobalRenderer->Print("vendor id = 0x"); + GlobalRenderer->Print(to_hstring(pciDeviceHeader->VendorID)); + GlobalRenderer->Print(", device id = 0x"); + GlobalRenderer->Print(to_hstring(pciDeviceHeader->DeviceID)); + GlobalRenderer->Next(); + + } + + void EnumerateDevice(uint64_t busAddress, uint64_t device) { + uint64_t offset = device << 15; + + uint64_t deviceAddress = busAddress + offset; + GlobalPTM.MapMemory((void*)deviceAddress, (void*)deviceAddress); + + PCIDeviceHeader* pciDeviceHeader = (PCIDeviceHeader*)deviceAddress; + + if (pciDeviceHeader->DeviceID == 0) return; // device is not valid + if (pciDeviceHeader->DeviceID == 0xFFFF) return; // device is not valid + + for (uint64_t function = 0; function < 8; function++) { + EnumerateFunction(deviceAddress, function); + } + } + + void EnumerateBus(uint64_t baseAddress, uint64_t bus) { + uint64_t offset = bus << 20; + + uint64_t busAddress = baseAddress + offset; + GlobalPTM.MapMemory((void*)busAddress, (void*)busAddress); + + PCIDeviceHeader* pciDeviceHeader = (PCIDeviceHeader*)busAddress; + + if (pciDeviceHeader->DeviceID == 0) return; // device is not valid + if (pciDeviceHeader->DeviceID == 0xFFFF) return; // device is not valid + + for (uint64_t device = 0; device < 32; device++) { + EnumerateDevice(busAddress, device); + } + } + + void EnumeratePCI(ACPI::MCFGHeader* mcfg) { + int entries = ((mcfg->Header.Length) - sizeof(ACPI::MCFGHeader)) / sizeof(ACPI::DeviceConfig); + + for (int t = 0; t < entries; t++) { + ACPI::DeviceConfig* newDeviceConfig = (ACPI::DeviceConfig*)((uint64_t)mcfg + sizeof(ACPI::MCFGHeader) + (sizeof(ACPI::DeviceConfig) * t)); + for (uint64_t bus = newDeviceConfig->StartBus; bus < newDeviceConfig->EndBus; bus++) { + EnumerateBus(newDeviceConfig->BaseAddress, bus); + } + } + } +}; \ No newline at end of file diff --git a/kernel/src/pci.h b/kernel/src/pci.h index 7b9637e..a3c0c25 100644 --- a/kernel/src/pci.h +++ b/kernel/src/pci.h @@ -1 +1,25 @@ -#pragma once \ No newline at end of file +#pragma once +#include +#include "acpi.h" +#include "paging/PageTableManager.h" +#include "BasicRenderer.h" +#include "cstr.h" + +namespace PCI { + struct PCIDeviceHeader { + uint16_t VendorID; + uint16_t DeviceID; + uint16_t Command; + uint16_t Status; + uint8_t RevisionID; + uint8_t ProgIF; + uint8_t Subclass; + uint8_t Class; + uint8_t CacheLineSize; + uint8_t LatencyTimer; + uint8_t HeaderType; + uint8_t BIST; + }; + + void EnumeratePCI(ACPI::MCFGHeader* mcfg); +}; \ No newline at end of file