enumerate pci devices
This commit is contained in:
@@ -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
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "paging/PageTableManager.h"
|
||||
#include "userinput/mouse.h"
|
||||
#include "acpi.h"
|
||||
#include "pci.h"
|
||||
|
||||
struct BootInfo {
|
||||
Framebuffer* framebuffer;
|
||||
|
||||
@@ -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)){
|
||||
|
||||
@@ -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;
|
||||
@@ -1 +1,66 @@
|
||||
#include "pci.h"
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1 +1,25 @@
|
||||
#pragma once
|
||||
#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);
|
||||
};
|
||||
Reference in New Issue
Block a user