diff --git a/Kernel/Include/VM/PMM.h b/Kernel/Include/VM/PMM.h index 6beddd3..6704e4c 100644 --- a/Kernel/Include/VM/PMM.h +++ b/Kernel/Include/VM/PMM.h @@ -16,4 +16,8 @@ typedef struct { VMMemoryRegion totalRAM; VMMemoryRegion reserved[kVMMaxReservedRegions]; UInt32 reservedCount; -} VMBootMemoryMap; \ No newline at end of file +} VMBootMemoryMap; + +void PMMInitialize(VMBootMemoryMap* bootMap); +Pointer PMMAllocatePage(); +void PMMFreePage(Address address); \ No newline at end of file diff --git a/Kernel/Source/Arch/DTB.c b/Kernel/Source/Arch/DTB.c index 69c4f7e..6808a68 100644 --- a/Kernel/Source/Arch/DTB.c +++ b/Kernel/Source/Arch/DTB.c @@ -1,3 +1,4 @@ +#include "Types.h" #include #include #include @@ -12,6 +13,11 @@ void DTBParse(Pointer dtb, VMBootMemoryMap* bootMap) { OSPanic("Invalid DTB magic"); } + UInt32 index = bootMap->reservedCount; + bootMap->reserved[index].base = (Address)dtb; + bootMap->reserved[index].size = BytesSwap32(header->totalSize); + bootMap->reservedCount++; + UInt32 offStruct = BytesSwap32(header->offDtStruct); UInt32 offStrings = BytesSwap32(header->offDtStrings); @@ -51,23 +57,21 @@ void DTBParse(Pointer dtb, VMBootMemoryMap* bootMap) { if (StringCompare(propertyName, "reg") == 0) { if (StringStartsWith(currentNode, "memory")) { UInt32* cells = (UInt32*)structs; - UInt64 base = Merge32To64(BytesSwap32(cells[1]), BytesSwap32(cells[0])); - UInt64 size = Merge32To64(BytesSwap32(cells[3]), BytesSwap32(cells[2])); - OSLog("Main Memory: base=0x%x, size=0x%x\n", base, size); + Address base = Merge32To64(BytesSwap32(cells[1]), BytesSwap32(cells[0])); + Size size = Merge32To64(BytesSwap32(cells[3]), BytesSwap32(cells[2])); + bootMap->totalRAM.base = base; bootMap->totalRAM.size = size; } else if (inReservedMemory && currentDepth > reservedMemoryDepth) { UInt32* cells = (UInt32*)structs; - UInt64 base = Merge32To64(BytesSwap32(cells[1]), BytesSwap32(cells[0])); - UInt64 size = Merge32To64(BytesSwap32(cells[3]), BytesSwap32(cells[2])); + Address base = Merge32To64(BytesSwap32(cells[1]), BytesSwap32(cells[0])); + Size size = Merge32To64(BytesSwap32(cells[3]), BytesSwap32(cells[2])); UInt32 index = bootMap->reservedCount; bootMap->reserved[index].base = base; bootMap->reserved[index].size = size; bootMap->reservedCount++; - - OSLog("Reserved Region (%s): base=0x%x, size=0x%x\n", currentNode, base, size); } } diff --git a/Kernel/Source/KernelMain.c b/Kernel/Source/KernelMain.c index a0fb291..efe5aa1 100644 --- a/Kernel/Source/KernelMain.c +++ b/Kernel/Source/KernelMain.c @@ -13,5 +13,5 @@ void KernelMain(Bootinfo* bootinfo) { VMBootMemoryMap bootMap = {0}; bootMap.reservedCount = 0; DTBParse(bootinfo->dtb, &bootMap); - OSLog("Meow...\n"); + PMMInitialize(&bootMap); } \ No newline at end of file diff --git a/Kernel/Source/VM/PMM.c b/Kernel/Source/VM/PMM.c index 280983a..e15d06e 100644 --- a/Kernel/Source/VM/PMM.c +++ b/Kernel/Source/VM/PMM.c @@ -1,4 +1,8 @@ #include +#include + +extern char _kernelStart[]; +extern char _kernelEnd[]; static inline Size BitmapGetByteIndex(Address address) { return (address / kVMPageSize) / kVMBlocksPerByte; @@ -20,3 +24,60 @@ static inline void BitmapUnset(MemoryPointer bitmap, Address address) { bitmap[BitmapGetByteIndex(address)] &= ~(1U << BitmapGetBitOffset(address)); } +static MemoryPointer sPMMBitmap; +static Size sPMMBitmapSize; +static Size sPMMTotalPages; + +void PMMInitialize(VMBootMemoryMap* bootMap) { + UInt32 vIndex = bootMap->reservedCount; + bootMap->reserved[vIndex].base = 0x0; + bootMap->reserved[vIndex].size = bootMap->totalRAM.base; + bootMap->reservedCount++; + + UInt32 kIndex = bootMap->reservedCount; + bootMap->reserved[kIndex].base = (Address)_kernelStart; + bootMap->reserved[kIndex].size = (Address)_kernelEnd - (Address)_kernelStart; + bootMap->reservedCount++; + + sPMMTotalPages = bootMap->totalRAM.size / kVMPageSize; + sPMMBitmapSize = sPMMTotalPages / kVMBlocksPerByte; + sPMMBitmap = (MemoryPointer)_kernelEnd; + + StringSet(sPMMBitmap, 0, sPMMBitmapSize); + + UInt32 bIndex = bootMap->reservedCount; + bootMap->reserved[bIndex].base = (Address)sPMMBitmap; + bootMap->reserved[bIndex].size = sPMMBitmapSize; + bootMap->reservedCount++; + + for (Size i = 0; i < bootMap->reservedCount; i++) { + Address regionBase = bootMap->reserved[i].base; + Size regionSize = bootMap->reserved[i].size; + + Size pagesToReserve = (regionSize + kVMPageSize - 1) / kVMPageSize; + + for (Size p = 0; p < pagesToReserve; p++) { + Address pageAdress = regionBase + (p * kVMPageSize); + BitmapSet(sPMMBitmap, pageAdress); + } + } +} + +Pointer PMMAllocatePage() { + for (Size i = 0; i < sPMMBitmapSize; i++) { + if (sPMMBitmap[i] == 0xFF) continue; + for (Size bit = 0; bit < kVMBlocksPerByte; bit++) { + if ((sPMMBitmap[i] & (1 << bit)) == 0) { + Address address = (i * kVMBlocksPerByte + bit) * kVMPageSize; + BitmapSet(sPMMBitmap, address); + return (Pointer)address; + } + } + } + + return nullptr; +} + +void PMMFreePage(Address address) { + BitmapUnset(sPMMBitmap, address); +} \ No newline at end of file