enumerate pci devices

This commit is contained in:
2026-01-29 17:38:44 +11:00
parent 6c8c97a67a
commit c1ebca273a
9 changed files with 127 additions and 11 deletions

View File

@@ -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

View File

@@ -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);
};

View File

@@ -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) {

View File

@@ -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();
}

View File

@@ -13,6 +13,7 @@
#include "paging/PageTableManager.h"
#include "userinput/mouse.h"
#include "acpi.h"
#include "pci.h"
struct BootInfo {
Framebuffer* framebuffer;

View File

@@ -3,6 +3,9 @@
#include <stdint.h>
#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)){

View File

@@ -1,9 +1,13 @@
#pragma once
#include "paging.h"
class PageTableManager {
public:
PageTableManager(PageTable* PML4Address);
PageTable* PML4;
void MapMemory(void* virtualMemory, void* physicalMemory);
};
extern PageTableManager GlobalPTM;

View File

@@ -1 +1,66 @@
#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);
}
}
}
};

View File

@@ -1 +1,25 @@
#pragma once
#include <stdint.h>
#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);
};