From 5bc7ec5b79984eed01d6514c785e7195766e3999 Mon Sep 17 00:00:00 2001 From: Curle Date: Sat, 13 Mar 2021 21:24:30 +0000 Subject: [PATCH] Delete paging. Time for an overhaul. --- build.json | 17 +- chroma.bxrc | 18 +- chroma/inc/kernel/system/memory.h | 1 + chroma/kernel.c | 4 +- chroma/system/memory/legacypaging.c | 310 ------------- chroma/system/memory/legacyphysmem.c | 53 --- chroma/system/memory/paging.c | 415 ------------------ .../system/memory/temp_storage/legacypaging.c | 310 ------------- chroma/system/memory/temp_storage/paging.c | 379 ---------------- 9 files changed, 24 insertions(+), 1483 deletions(-) delete mode 100644 chroma/system/memory/legacypaging.c delete mode 100644 chroma/system/memory/legacyphysmem.c delete mode 100644 chroma/system/memory/paging.c delete mode 100644 chroma/system/memory/temp_storage/legacypaging.c delete mode 100644 chroma/system/memory/temp_storage/paging.c diff --git a/build.json b/build.json index 4820b78..0ea61b5 100644 --- a/build.json +++ b/build.json @@ -32,7 +32,6 @@ "$root/chroma/system/serial.c", "$root/chroma/system/pci.c", "$root/chroma/system/memory/stack.c", - "$root/chroma/system/memory/paging.c", "$root/chroma/system/memory/abstract_allocator.c", "$root/chroma/system/memory/physmem.c", "$root/chroma/system/drivers/keyboard.c", @@ -56,17 +55,21 @@ }, "build": { - "compile-no-sse": [ - "-I$inc -ffreestanding -O0 -Wall -Wextra -Wall -Werror -pedantic -fPIC -fno-exceptions -fno-omit-frame-pointer -mno-red-zone -fno-stack-protector -ggdb3 -mgeneral-regs-only", - "$no-sse" - ], "compile-main": [ "-I$inc -ffreestanding -O0 -Wall -Wextra -Wall -Werror -pedantic -fPIC -fno-exceptions -fno-omit-frame-pointer -mno-red-zone -fno-stack-protector -ggdb3", "$preamble", "$main", "$lib", - "$font", + "$font" + ], + + "compile-no-sse": [ + "-I$inc -ffreestanding -O0 -Wall -Wextra -Wall -Werror -pedantic -fPIC -fno-exceptions -fno-omit-frame-pointer -mno-red-zone -fno-stack-protector -ggdb3 -mgeneral-regs-only", + "$no-sse" + ], + + "compile-last": [ "$epilogue" ], @@ -76,7 +79,7 @@ ], "output": [ - "Chroma.elf" + "kernel" ] } } \ No newline at end of file diff --git a/chroma.bxrc b/chroma.bxrc index 2ae2c26..7430f06 100644 --- a/chroma.bxrc +++ b/chroma.bxrc @@ -1,7 +1,7 @@ # configuration file generated by Bochs -plugin_ctrl: unmapped=true, biosdev=true, speaker=true, extfpuirq=true, parallel=true, serial=true, gameport=true +plugin_ctrl: unmapped=true, biosdev=true, speaker=true, extfpuirq=true, parallel=true, serial=true, gameport=true, iodebug=true config_interface: win32config -display_library: win32 +display_library: win32, options="gui_debug" memory: host=128, guest=128 romimage: file="C:\Program Files\Bochs-2.6.11/BIOS-bochs-latest", address=0x00000000, options=none vgaromimage: file="C:\Program Files\Bochs-2.6.11/VGABIOS-lgpl-latest" @@ -10,7 +10,7 @@ floppy_bootsig_check: disabled=0 # no floppya # no floppyb ata0: enabled=true, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 -ata0-master: type=disk, path="C:/Users/tcrl/Documents/Coding/chroma/chroma.img", cylinders=615, heads=6, spt=17, sect_size=512, model="ChromaDrive", biosdetect=auto, translation=auto +ata0-master: type=disk, path="C:\Users\Owner\Desktop\Codings\chroma\chroma.img", mode=flat, cylinders=615, heads=6, spt=17, sect_size=512, model="ChromaDrive", biosdetect=auto, translation=auto ata0-slave: type=none ata1: enabled=true, ioaddr1=0x170, ioaddr2=0x370, irq=15 ata1-master: type=none @@ -27,13 +27,15 @@ optramimage3: file=none optramimage4: file=none pci: enabled=1, chipset=i440fx vga: extension=vbe, update_freq=5, realtime=1 -cpu: count=1, ips=4000000, model=bx_generic, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0 +cpu: count=1:1:1, ips=400000000, quantum=16, model=bx_generic, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0 cpuid: level=6, stepping=3, model=3, family=6, vendor_string="GenuineIntel", brand_string=" Intel(R) Pentium(R) 4 CPU " cpuid: mmx=true, apic=xapic, simd=sse2, sse4a=false, misaligned_sse=false, sep=true -cpuid: movbe=false, adx=false, aes=false, sha=false, xsave=false, xsaveopt=false, x86_64=true -cpuid: 1g_pages=false, pcid=false, fsgsbase=false, smep=false, smap=false, mwait=true -cpuid: vmx=1 +cpuid: movbe=false, adx=false, aes=false, sha=false, xsave=false, xsaveopt=false, avx_f16c=false +cpuid: avx_fma=false, bmi=0, xop=false, fma4=false, tbm=false, x86_64=true, 1g_pages=false +cpuid: pcid=false, fsgsbase=false, smep=false, smap=false, mwait=true print_timestamps: enabled=0 +debugger_log: - +magic_break: enabled=0 port_e9_hack: enabled=1 private_colormap: enabled=0 clock: sync=none, time0=local, rtc_sync=0 @@ -50,7 +52,7 @@ sound: waveoutdrv=win, waveout=none, waveindrv=win, wavein=none, midioutdrv=win, speaker: enabled=true, mode=sound parport1: enabled=true, file=none parport2: enabled=false -com1: enabled=true, mode=file, dev="C:\Users\tcrl\Documents\Coding\chroma\serial.txt" +com1: enabled=true, mode=file, dev=".\serial.txt" com2: enabled=false com3: enabled=false com4: enabled=false diff --git a/chroma/inc/kernel/system/memory.h b/chroma/inc/kernel/system/memory.h index f621b78..306868b 100644 --- a/chroma/inc/kernel/system/memory.h +++ b/chroma/inc/kernel/system/memory.h @@ -116,6 +116,7 @@ #define KERNEL_PHYSICAL KernelLocation // The located kernel from the bootstrap process #define KERNEL_END KernelLocation + (KernelEnd - KernelAddr) +#define KERNEL_OFFSET 0x0000000000039000ull // KERNEL_PHYSICAL -> KERNEL_PHYSICAL + KERNEL_OFFSET + KERNEL_REGION #define CODE_STACK_PHYSICAL 0x0000000000006C00ull // The base of the stack running the C code we enter with #define CODE_STACK_END 0x0000000000007C00ull diff --git a/chroma/kernel.c b/chroma/kernel.c index 4aa0cdb..d66ba2b 100644 --- a/chroma/kernel.c +++ b/chroma/kernel.c @@ -18,6 +18,8 @@ size_t KernelEnd = (size_t) &end; address_space_t KernelAddressSpace; +size_t KernelLocation; + int Main(void) { KernelAddressSpace = (address_space_t) {0}; @@ -46,7 +48,7 @@ int Main(void) { //DrawSplash(); - InitPaging(); + //InitPaging(); for(;;) { } diff --git a/chroma/system/memory/legacypaging.c b/chroma/system/memory/legacypaging.c deleted file mode 100644 index 8c97a0e..0000000 --- a/chroma/system/memory/legacypaging.c +++ /dev/null @@ -1,310 +0,0 @@ - -void InitPagingT() { - - size_t* PML4 = (size_t*) 0xFFA000; // Layer 4 - size_t* PDPE_RAM = (size_t*) 0xFFE000; // Layer 3, contains map for the first 4GB of RAM - size_t* PDE_RAM = (size_t*) 0xFFF000; - - size_t* PDPE_KERNEL = (size_t*) 0xFFB000; // Layer 3, contains map for the Kernel and everything it needs to run. - size_t* PDE_KERNEL_FB = (size_t*) 0xFFC000; // Layer 2, contains map for the linear framebuffer. - - size_t* PT_KERNEL = (size_t*) 0xFFD000; // Layer 1, the page table for the kernel itself. - - size_t fb_ptr = (size_t) &fb; - - SET_ADDRESS(PML4, PDPE_RAM); // 3rd Layer entry for RAM - SET_ADDRESS(PML4 + LAST_ENTRY, PDPE_KERNEL); // 3rd Layer entry for Kernel - - SET_ADDRESS(PDPE_KERNEL + LAST_ENTRY, PDE_KERNEL_FB); // 2nd Layer entry for the framebuffer - - // Set the 480th entry (PDE_KERNEL_FB + (480 * 8)) - // To the framebuffer + flags - SET_ADDRESS(PDE_KERNEL_FB + 3840, USERWRITEABLE_FLAGS(fb_ptr)); - - // In 4 byte increments, we're gonna map 3840 (the framebuffer) - // Up to (4096 - 8) in the PDE_KERNEL_FB with 2MB paging. - size_t MappingIterations = 1; - for(size_t i = 3844; i < 4088; i += 4) { - SET_ADDRESS(PDE_KERNEL_FB + i, USERWRITEABLE_FLAGS(fb_ptr) + (MappingIterations * (2 * MiB))); - MappingIterations++; - } - - // Now we map the last entry of PDE_KERNEL_FB to our Page Table - SET_ADDRESS(PDE_KERNEL_FB + LAST_ENTRY, PT_KERNEL); - - // Mapping the kernel into the page tables.... - - SET_ADDRESS(PT_KERNEL, 0xFF8001); // bootldr, bootinfo - SET_ADDRESS(PT_KERNEL + 8, 0xFF9001); // environment - - // Map the kernel itself - SET_ADDRESS(PT_KERNEL + 16, KernelAddr + 1); - - // Iterate through the pages, identity mapping each one - MappingIterations = 1; - size_t MappingOffset = 0x14; - for(size_t i = 0; i < ((KernelEnd - KernelAddr) >> 12); i++) { - // Page Table + (0x10 increasing by 0x04 each time) = x * 4KiB - SET_ADDRESS(PT_KERNEL + MappingOffset, (MappingIterations * (4 * KiB))); - MappingOffset += 4; - MappingIterations++; - } - - // Now we need to map the core stacks. Top-down, from 0xDFF8 - // There's always at least one core, so we do that one fixed. - // TODO: Account for 0-core CPUs - SET_ADDRESS(PT_KERNEL + LAST_ENTRY, 0xF14003); - MappingIterations = 1; - // For every core: - for(size_t i = 0; i < (bootldr.numcores + 3U) >> 2; i++) { - // PT_KERNEL[512 - (iterations + 1)] = 0x14003 + (iterations * page-width) - SET_ADDRESS(PT_KERNEL + LAST_ENTRY - (MappingIterations * 8), 0xF14003 + (4096 * MappingIterations)); - MappingIterations++; - } - - SET_ADDRESS(PDPE_RAM, PDE_RAM + PAGE_PRESENT + PAGE_RW); - SET_ADDRESS(PDPE_RAM + 8, 0xF10000 + PAGE_PRESENT + PAGE_RW); - SET_ADDRESS(PDPE_RAM + 16, 0xF11000 + PAGE_PRESENT + PAGE_RW); - SET_ADDRESS(PDPE_RAM + 24, 0xF12000 + PAGE_PRESENT + PAGE_RW); - - // Identity map 4GB of ram - // Each page table can only hold 512 entries, but we - // just set up 4 of them - overflowing PDE_RAM (0xF000) - // will take us into 0x10000, into 0x11000, into 0x120000. - for(size_t i = 0; i < 512 * 4/*GB*/; i++) { - // add PDE_RAM, 4 - // mov eax, 0x83 - // add eax, 2*1024*1024 - SET_ADDRESS(PDE_RAM + (i * 4), USERWRITEABLE_FLAGS(i * (2 * MiB))); - } - - // Map first 2MB of memory - SET_ADDRESS(PDE_RAM, 0xF13000 + PAGE_PRESENT + PAGE_RW); - - for(size_t i = 0; i < 512; i++) { - SET_ADDRESS(0xF13000 + i * 4, i * (4 * KiB) + PAGE_PRESENT + PAGE_RW); - } - - // 0xA000 should now contain our memory map. - -} - -void TraversePageTables() { - -} - - -void InitPagingOldImpl() { - - // Disable paging so that we can work with the pagetable - //size_t registerTemp = ReadControlRegister(0); - //UNSET_PGBIT(registerTemp); - //WriteControlRegister(0, registerTemp); - - // Clear space for our pagetable - size_t PagetableDest = 0x1000; - memset((char*)PagetableDest, 0, 4096); - - // Start setting pagetable indexes - *((size_t*)PagetableDest) = 0x2003; // PDP at 0x2000, present & r/w - *((size_t*)PagetableDest + 0x1000) = 0x3003; // PDT at 0x3000, present & r/w - *((size_t*)PagetableDest + 0x2000) = 0x4003; // PT at 0x4000, present & r/w - - size_t value = 0x3; - size_t offset = 8; - for(size_t i = 0; i < 512; i++) { // 512 iterations (entries into the page table) - *((size_t*) PagetableDest + offset) = value; // We're setting 512 bytes with x003 - // (identity mapping the first 4 megabytes of memory) - // (mapping the page table to itself) - value += 4096; // Point to start of next page - offset += 8; // + 8 bytes (next entry in list) - } - - // Enable PAE paging - size_t reg = ReadControlRegister(4); - SET_PAEBIT(reg); - WriteControlRegister(4, reg); - - WriteControlRegister(3, PagetableDest); - -} - - -/* size_t registerTemp = ReadControlRegister(4); - if(registerTemp & (1 << 7)) { - TOGGLE_PGEBIT(registerTemp); - WriteControlRegister(4, registerTemp); - } - - if(registerTemp & (1 << 7)) - WriteControlRegister(4, registerTemp ^ (1 << 7)); - - size_t CPUIDReturn; - asm volatile("cpuid" : "=d" (CPUIDReturn) : "a" (0x80000001) : "%rbx", "%rcx"); - - if(CPUIDReturn & (1 << 26)) { - SerialPrintf("System supports 1GB pages.\r\n"); - - if(registerTemp & (1 << 12)) { - SerialPrintf("PML5 paging available - using that instead.\r\n"); - - if(MemorySize > (1ULL << 57)) - SerialPrintf("System has over 128Petabytes of RAM. Please consider upgrading the OS on your supercomputer.\r\n"); - - size_t MaxPML5 = 1; - size_t MaxPML4 = 1; - size_t MaxPDP = 512; - - size_t LastPML4Entry = 512; - size_t LastPDPEntry = 512; - - size_t MemorySearchDepth = MemorySize; - - while(MemorySearchDepth > (256ULL << 30)) { - MaxPML5++; - MemorySearchDepth -= (256ULL << 30); - } - - if(MaxPML5 > 512) - MaxPML5 = 512; - - if(MemorySearchDepth) { - LastPDPEntry = ( (MemorySearchDepth + ((1 << 30) - 1)) & (~0ULL << 30)) >> 30; - - if(MaxPML5 > 512) - MaxPML5 = 512; - - } - - size_t PML4Size = PAGETABLE_SIZE * MaxPML5; - size_t PDPSize = PML4Size * MaxPML4; - - size_t PML4Base = AllocatePagetable(PML4Size + PDPSize); - size_t PDPBase = PML4Base + PML4Size; - - for(size_t PML5Entry = 0; PML5Entry < MaxPML5; PML5Entry++) { - Pagetable[PML5Entry] = PML4Base + (PML5Entry << 12); - - if(PML5Entry == (MaxPML5 - 1)) - MaxPML4 = LastPML4Entry; - - for(size_t PML4Entry = 0; PML4Entry < MaxPML4; PML4Entry++) { - - ((size_t*) Pagetable[PML5Entry])[PML4Entry] = PDPBase + (((PML5Entry << 9) + PML5Entry) << 12); - - if( (PML5Entry == (MaxPML5 - 1)) && (PML4Entry == (MaxPML4 -1)) ) - MaxPDP = LastPDPEntry; - - for(size_t PDPEntry = 0; PDPEntry < MaxPDP; PDPEntry++) { - ((size_t* ) ((size_t* ) Pagetable[PML5Entry])[PML4Entry])[PDPEntry] = ( ((PML5Entry << 18) + (PML4Entry << 9) + PDPEntry) << 30) | (0x83); - } - - ((size_t* ) Pagetable[PML5Entry])[PML4Entry] |= 0x3; - } - - Pagetable[PML5Entry] |= 0x3; - } - } else { - SerialPrintf("PML4 available - using that instead.\r\n"); - size_t MemorySearchDepth = MemorySize; - - if(MemorySearchDepth > (1ULL << 48)) - SerialPrintf("RAM limited to 256TB.\r\n"); - - size_t MaxPML4 = 1; - size_t MaxPDP = 512; - - size_t LastPDPEntry = 512; - - while(MemorySearchDepth > (512ULL << 30)) { - MaxPML4++; - MemorySearchDepth -= (512ULL << 30); - } - - if(MaxPML4 > 512) - MaxPML4 = 512; - - if(MemorySearchDepth) { - LastPDPEntry = ( (MemorySearchDepth + ((1 << 30) - 1)) & (~0ULL << 30)) >> 30; - - if(LastPDPEntry > 512) - LastPDPEntry = 512; - } - - size_t PDPSize = PAGETABLE_SIZE * MaxPML4; - size_t PDPBase = AllocatePagetable(PDPSize); - - for(size_t PML4Entry = 0; PML4Entry < MaxPML4; PML4Entry++) { - Pagetable[PML4Entry] = PDPBase + (PML4Entry << 12); - - if(PML4Entry == (MaxPML4 - 1)) { - MaxPDP = LastPDPEntry; - } - - for(size_t PDPEntry = 0; PDPEntry < MaxPDP; PDPEntry++) { - ((size_t* ) Pagetable[PML4Entry])[PDPEntry] = (((PML4Entry << 9) + PDPEntry) << 30) | 0x83; - } - - Pagetable[PML4Entry] |= 0x3; - } - } - } else { - SerialPrintf("System does not support 1GB pages - using 2MiB paging instead.\r\n"); - - size_t MemorySearchDepth = MemorySize; - - if(MemorySearchDepth > (1ULL << 48)) { - SerialPrintf("Usable RAM is limited to 256TB, and the page table alone will use 1GB of space in memory.\r\n"); - } - - size_t MaxPML4 = 1, MaxPDP = 512, MaxPD = 512, LastPDPEntry = 1; - - while(MemorySearchDepth > (512ULL << 30)) { - MaxPML4++; - MemorySearchDepth -= (512ULL << 30); - } - - if(MaxPML4 > 512) - MaxPML4 = 512; - - if(MemorySearchDepth) { - LastPDPEntry = ((MemorySearchDepth + ((1 << 30) - 1)) & (~0ULL << 30)) >> 30; - - if(LastPDPEntry > 512) - LastPDPEntry = 512; - } - - size_t PDPSize = PAGETABLE_SIZE * MaxPML4; - size_t PDSize = PDPSize * MaxPDP; - - size_t PDPBase = AllocatePagetable(PDPSize + PDSize); - size_t PDBase = PDPBase + PDSize; - - for(size_t PML4Entry = 0; PML4Entry < MaxPML4; PML4Entry++) { - Pagetable[PML4Entry] = PDBase + (PML4Entry << 12); - - if(PML4Entry == (MaxPML4 - 1)) { - MaxPDP = LastPDPEntry; - } - - for(size_t PDPEntry = 0; PDPEntry < MaxPDP; PDPEntry++) { - ( (size_t* ) Pagetable[PML4Entry])[PDPEntry] = PDBase + (((PML4Entry << 9) + PDPEntry) << 12); - - for(size_t PDEntry = 0; PDEntry < MaxPD; PDEntry++) { - ( (size_t* ) ((size_t*) Pagetable[PML4Entry])[PDPEntry])[PDEntry] = (( (PML4Entry << 18) + (PDPEntry << 9) + PDPEntry) << 21) | 0x83; - } - - ( (size_t* ) Pagetable[PML4Entry])[PDPEntry] |= 0x3; - } - - Pagetable[PML4Entry] |= 0x3; - } - } - - WriteControlRegister(3, Pagetable); - - registerTemp = ReadControlRegister(4); - if(!(registerTemp & (1 << 7))) { - TOGGLE_PGEBIT(registerTemp); - WriteControlRegister(4, registerTemp); - }*/ \ No newline at end of file diff --git a/chroma/system/memory/legacyphysmem.c b/chroma/system/memory/legacyphysmem.c deleted file mode 100644 index 9b4004c..0000000 --- a/chroma/system/memory/legacyphysmem.c +++ /dev/null @@ -1,53 +0,0 @@ - -size_t AllocateFrame() { - size_t FreePage = SeekFrame(); - SET_BIT(FreePage); - return FreePage; -} - -void FreeFrame(size_t Frame) { - UNSET_BIT(Frame); -} - -size_t SeekFrame() { - for(size_t i = 0; i < MemoryPages; i++) { - if(!READ_BIT(i)) - return i; - } - - SerialPrintf("Memory manager: Critical!\r\n"); - return (size_t) -1; -} - -void MemoryTest() { - SerialPrintf("Initializing basic memory test..\r\n"); - bool Passed = true; - size_t FirstPage = SeekFrame(); - /*(void* FirstPageAlloc = (void*)*/ AllocateFrame(); - size_t SecondPage = SeekFrame(); - /*void* SecondPageAlloc = (void*)*/ AllocateFrame(); - - if(!(FirstPage == 0 && SecondPage == 1)) { - Passed = false; - SerialPrintf("First iteration: Failed, First page %x, Second page %x.\r\n", FirstPage, SecondPage); - } - - FreeFrame(SecondPage); - SecondPage = SeekFrame(); - - if(SecondPage != 1) - Passed = false; - - FreeFrame(FirstPage); - FirstPage = SeekFrame(); - - if(FirstPage != 0) - Passed = false; - - if(Passed) - SerialPrintf("Memory test passed.\r\n"); - else { - SerialPrintf("Memory test failed.\r\n"); - SerialPrintf("First page %x, Second page %x.\r\n", FirstPage, SecondPage); - } -} diff --git a/chroma/system/memory/paging.c b/chroma/system/memory/paging.c deleted file mode 100644 index 96eb6bf..0000000 --- a/chroma/system/memory/paging.c +++ /dev/null @@ -1,415 +0,0 @@ -#include -#include - -/************************ - *** Team Kitty, 2020 *** - *** Chroma *** - ***********************/ - -/**************************************** - * W O R K I N P R O G R E S S * - **************************************** - * - * This file contains functions for virtual memory management. - * - * Virtual Memory Management is still a work in progress. - * The functions here are hold-offs from old versions of the software implemented here, as well as from the EFI version of Chroma, called Sync. - * - * There, these functions worked, but here, under BIOS, it's a lot more difficult. - * It will take some time to get these functions working. - * - * The general plan, being that the BOOTBOOT loader has given us static addresses for all of our doodads, - * is to keep the core kernel where it is (FFFFFFFFFFE00000) and load in modules and libraries around it. - * - * We start in the higher half, so we'll dedicate the lower half (7FFFFFFFFFFF and below) to userspace. - * - * That means we have about 3 terabytes of RAM for the kernel. - * This will be identity mapped, always. - * - * Handily, since most modern processors ignore the highest 2 bytes of a virtual address, and the kernel - * is mapped to 0x80000000000 and above, we can use the nomenclature: - * * 0x00007FFFFFFFFFFF and below is user space. - * * 0xFFFF800000000000 and above is kernel space. - * The processor will ignore the first 4 chars, and this provides a great deal of readability for the - * future of the kernel. - * - * We'll have a kernel heap mapped into this kernel space, as well as a kernel stack (for task switching and error tracing). - * These will be 1GB each. - * We may have to increase this in the future, once Helix is fully integrated. - * Helix will take a lot of memory, as it is a fully featured 3D engine. We may have to implement things like - * texture streaming and mipmapping. Minimising RAM usage is NOT a priority for me, but it would be nice - * to have a minimum requirement above 32GB. - * - * // TODO: Expand Kernel Heap - * - * - * //TODO: there are lots of calls to AllocateFrame here, those need to be separated out into AllocateZeroFrame if necessary. - * - * - */ - -//extern size_t _kernel_text_start; -extern size_t _kernel_rodata_start; -extern size_t _kernel_data_start; - -size_t KernelLocation; - -//__attribute__((aligned(4096))) static size_t Pagetable[512] = {0}; - -#define LAST_ENTRY 0xFF8 - -#define SET_ADDRESS(a,b) ((*(size_t*) (a)) = (size_t) b) - -/* - * It turns out it's useful to have macros for the standard - * data size units. - * - * Who would've thoguht? - */ - -#define KiB 1 * 1024 -#define MiB 1 * 1024 * KiB - - -#define PAGE_PRESENT 1 -#define PAGE_RW 2 -#define PAGE_USER 4 -#define PAGE_GLOBAL 8 - - -#define USERWRITEABLE_FLAGS(a) ((a & 0xFFFFFF00) + 0x83) - -// The AbstractAllocator control struct -static allocator_t Allocator = NULL; -// The AbstractAllocator Ticketlock. -static ticketlock_t AllocatorLock = {0}; - -// Entries to help allocate the Kernel Stack -static list_entry_t StackFreeList; -static ticketlock_t StackLock = {0}; -static void* StackPointer = (void*) KERNEL_STACK_REGION; - -// A temporary itoa function for better debugging.. -const char* IntToAscii(int In) { - char* OutputBuffer = " "; - - size_t Temp, i = 0, j = 0; - - do { - Temp = In % 10; - OutputBuffer[i++] = (Temp < 10) ? (Temp + '0') : (Temp + 'a' - 10); - } while (In /= 10); - - OutputBuffer[i--] = 0; - - for(j = 0; j < i; j++, i--) { - Temp = OutputBuffer[j]; - OutputBuffer[j] = OutputBuffer[i]; - OutputBuffer[i] = Temp; - } - - return OutputBuffer; - -} - -static void GetPageFromTables(address_space_t* AddressSpace, size_t VirtualAddress, size_t** Page) { - - //ASSERT(Page != NULL); - //ASSERT(AddressSpace != NULL); - - size_t* Pagetable = AddressSpace->PML4; - for(int Level = 4; Level > 1; Level--) { - size_t* Entry = &Pagetable[(VirtualAddress >> (12u + 9u * (Level - 1))) & 0x1FFU]; - - ASSERT(*Entry & PAGE_PRESENT, "Page not present during retrieval"); - SerialPrintf("[ mem] Retrieval of level %d:%d of 0x%p is 0x%p\r\n", Level, (12u + 9u * (Level - 1)), VirtualAddress, (size_t) Entry); - - Pagetable = (size_t*)((char*)(*Entry & 0x7ffffffffffff000ull) + DIRECT_REGION); - } - - ASSERT(Pagetable[(VirtualAddress >> 12U) & 0x1FFU] & PAGE_PRESENT, "PDPE not present during retrieval"); - *Page = &Pagetable[(VirtualAddress >> 12U) & 0x1FFU]; - -} - - -void InitPaging() { - StackFreeList = (list_entry_t) { &StackFreeList, &StackFreeList }; - - size_t Size = AlignUpwards(AllocatorSize(), PAGE_SIZE); - Allocator = PhysAllocateZeroMem(Size); - Allocator = CreateAllocatorWithPool(Allocator, Size); - - SerialPrintf("[ Mem] Everything preallocated for paging.\n"); - - KernelAddressSpace = (address_space_t) { - .Lock = {0}, - .PML4 = PhysAllocateZeroMem(PAGE_SIZE) - }; - - //address_space_t InitialPaging = (address_space_t) { - // .Lock = {0}, - // .PML4 = (size_t*) ReadControlRegister(3) - //}; - - size_t* Pagetable = KernelAddressSpace.PML4; - //SerialPrintf("[ Mem] About to identity map the higher half.\n"); - // Identity map the higher half - for(int i = 256; i < 512; i++) { - Pagetable[i] = (size_t)PhysAllocateZeroMem(PAGE_SIZE); - Pagetable[i] = (size_t)(((char*)Pagetable[i]) - DIRECT_REGION); - Pagetable[i] |= (PAGE_PRESENT | PAGE_RW); - //SerialPrintf("%d", i - 256); - } - - SerialPrintf("[ Mem] Identity mapping higher half complete.\n"); - - MMapEnt* TopEntry = (MMapEnt*)(((size_t) (&bootldr) + bootldr.size) - sizeof(MMapEnt)); - size_t LargestAddress = TopEntry->ptr + TopEntry->size; - - SerialPrintf("[ Mem] About to map lower memory into the Direct Region. Highest address = 0x%p\n", AlignUpwards(LargestAddress, PAGE_SIZE)); - for(size_t Address = 0; Address < AlignUpwards(LargestAddress, PAGE_SIZE); Address += PAGE_SIZE) { - MapVirtualMemory(&KernelAddressSpace, (size_t*)(((char*)Address) + DIRECT_REGION), Address, MAP_WRITE); - } - SerialPrintf("[ Mem] Lower half mapping complete.\n"); - - SerialPrintf("[ Mem] Mapping kernel into new memory map.\r\n"); - - //TODO: Disallow execution of rodata and data, and bootldr/environment - for(void* Address = CAST(void*, KERNEL_PHYSICAL + KERNEL_TEXT); - Address < CAST(void*, KERNEL_END); - Address = CAST(void*, CAST(char*, Address) + PAGE_SIZE)) { - SerialPrintf("[ mem] Mapping 0x%p to 0x%p, relative to kernel at 0x%p\r\n", CAST(size_t, Address), CAST(size_t, (CAST(size_t, Address) - KERNEL_PHYSICAL) + KERNEL_REGION), CAST(size_t, Address) - KERNEL_PHYSICAL); - MapVirtualMemory(&KernelAddressSpace, CAST(void*, (CAST(size_t, Address) - KERNEL_PHYSICAL) + KERNEL_REGION), CAST(size_t, Address), MAP_EXEC); - } - - /*for(void* Address = CAST(void*, KERNEL_REGION + 0x2000); - Address < CAST(void*, KERNEL_REGION + 0x12000); // Higher half of kernel - Address = CAST(void*, CAST(char*, Address) + PAGE_SIZE)) { - MapVirtualMemory(&KernelAddressSpace, Address, (CAST(size_t, Address) - KERNEL_REGION) + KERNEL_PHYSICAL_2, MAP_EXEC); - }*/ - SerialPrintf("[ mem] Framebuffer at 0x%p, is 0x%p long. Mapping to 0x%p.\r\n", bootldr.fb_ptr, bootldr.fb_size, FB_REGION); - for(void* Address = CAST(void*, FB_PHYSICAL); - Address < CAST(void*, bootldr.fb_size + FB_PHYSICAL); - Address = CAST(void*, CAST(char*, Address) + PAGE_SIZE)) { - MapVirtualMemory(&KernelAddressSpace, CAST(void*, (CAST(size_t, Address) - FB_PHYSICAL) + FB_REGION), CAST(size_t, Address), MAP_WRITE); - } - - SerialPrintf("[ mem] Stack at 0x%p, mapping to UNKNOWN, top reaching UNKNOWN\r\n", CODE_STACK_PHYSICAL); - SerialPrintf("[ mem] Core 1 stack at 0x%p, mapping to 0x%p : 0x%p\r\n", CORE_STACK_PHYSICAL, STACK_TOP, MEM_CEILING); - for(void* Address = CAST(void*, CORE_STACK_PHYSICAL); - Address < CAST(void*, CORE_STACK_END); - Address = CAST(void*, CAST(char*, Address) + PAGE_SIZE)) { - MapVirtualMemory(&KernelAddressSpace, CAST(void*, STACK_TOP + (CAST(size_t, Address) - CORE_STACK_PHYSICAL)), CAST(size_t, Address), MAP_WRITE); - } - - SerialPrintf("[ Mem] Kernel mapped into pagetables. New PML4 at 0x%p / 0x%p\r\n", (size_t) KernelAddressSpace.PML4, (size_t) Pagetable); - SerialPrintf("[ Mem] About to move into our own pagetables.\r\n"); - - /*size_t pml4e = (0xffffffffffe021ba >> 39) & 0b111111111; - size_t pdpte = (0xffffffffffe021ba >> 30) & 0b111111111; - size_t pde = (0xffffffffffe021ba >> 21) & 0b111111111; - size_t pte = (0xffffffffffe021ba >> 12) & 0b111111111; - size_t offset = (0xffffffffffe021ba & 0b111111111111);*/ - size_t* selfQuery; - GetPageFromTables(&KernelAddressSpace, 0xffffffffffe021ba, &selfQuery); - // This ^ returns the start of the page where the address is located, which includes flags. - // So we mask them off and add the offset later to retrieve the physical address V - size_t selfQueryRes = *((volatile size_t*)(selfQuery)) & 0x7ffffffffffff000ull; - size_t* initialQueryRes = 0; // TODO: Unstable! - //GetPageFromTables(&InitialPaging, 0xffffffffffe021ba, &initialQueryRes); - - size_t targetAddr = 0xffffffffffe021ba; - SerialPrintf("[ Mem] Sanity check: Virtual Addr 0x%p maps to physical addr 0x%po vs 0x%pb\r\n", targetAddr, (size_t) selfQueryRes + (targetAddr & 0x1FF), (size_t) initialQueryRes); - WriteControlRegister(3, (size_t) KernelAddressSpace.PML4); - SerialPrintf("[ Mem] We survived!\r\n"); - //ASSERT(Allocator != NULL); -} - -static size_t GetCachingAttribute(pagecache_t Cache) { - switch (Cache) { - case CACHE_WRITE_BACK: return 0; - case CACHE_WRITE_THROUGH: return 1 << 2; - case CACHE_NONE: return 1 << 3; - case CACHE_WRITE_COMBINING: return 1 << 6; - } - - return 1 << 3; -} - -static bool ExpandAllocator(size_t NewSize) { - size_t AllocSize = AlignUpwards(AllocatorPoolOverhead() + sizeof(size_t) * 5 + NewSize, PAGE_SIZE); - void* Pool = PhysAllocateMem(AllocSize); - return AddPoolToAllocator(Allocator, Pool, AllocSize) != NULL; -} - - -void SetAddressSpace(address_space_t* AddressSpace) { - //ASSERT(AddressSpace != NULL); - - if((size_t)((char*)ReadControlRegister(3) + DIRECT_REGION) != (size_t) &AddressSpace->PML4) { - WriteControlRegister(3, CAST(size_t, &AddressSpace->PML4)); - } -} - -void MapVirtualMemory(address_space_t* AddressSpace, void* VirtualAddress, size_t PhysicalAddress, mapflags_t Flag) { - - //bool MapGlobally = false; - size_t Virtual = (size_t)VirtualAddress; - - //ASSERT(AddressSpace != NULL); - TicketAttemptLock(&AddressSpace->Lock); - - size_t Flags = PAGE_PRESENT; - - if(Flag & MAP_WRITE) - Flags |= MAP_WRITE; - - if(Virtual < USER_REGION) - Flags |= PAGE_USER; - //TODO: Global mapping - - size_t* Pagetable = AddressSpace->PML4; - for(int Level = 4; Level > 1; Level--) { - size_t* Entry = &Pagetable[(Virtual >> (12u + 9u * (Level - 1))) & 0x1FFu]; - - if(!(*Entry & PAGE_PRESENT)) { - directptr_t Pointer = PhysAllocateZeroMem(PAGE_SIZE); - *Entry = (size_t)(((char*)Pointer) - DIRECT_REGION); - } - - *Entry |= Flags; - - Pagetable = (size_t*)(((char*)(*Entry & 0x7ffffffffffff000ull) + DIRECT_REGION)); - } - - size_t* Entry = &Pagetable[(Virtual >> 12u) & 0x1FFu]; - *Entry = Flags | PhysicalAddress; - - - if(AddressSpace != NULL) { - TicketUnlock(&AddressSpace->Lock); - } - -} - -void UnmapVirtualMemory(address_space_t* AddressSpace, void* VirtualAddress){ - //ASSERT(AddressSpace != NULL); - - TicketAttemptLock(&AddressSpace->Lock); - - size_t* Entry; - GetPageFromTables(AddressSpace, (size_t)VirtualAddress, &Entry); - - *Entry = 0; - InvalidatePage((size_t)VirtualAddress); - - if(AddressSpace != NULL) { - TicketUnlock(&AddressSpace->Lock); - } - -} - -void CacheVirtualMemory(address_space_t* AddressSpace, void* VirtualAddress, pagecache_t Cache) { - - //ASSERT(AddressSpace != NULL); - - TicketAttemptLock(&AddressSpace->Lock); - - size_t* Entry; - - GetPageFromTables(AddressSpace, (size_t)VirtualAddress, &Entry); - - *Entry &= ~((1 << 6) | (1 << 2) | (1 << 3)); - *Entry |= GetCachingAttribute(Cache); - - InvalidatePage((size_t)VirtualAddress); - - if(AddressSpace != NULL) { - TicketUnlock(&AddressSpace->Lock); - } -} - - -void* AllocateMemory(size_t Bits) { - TicketAttemptLock(&AllocatorLock); - - void* Result = AllocatorMalloc(Allocator, Bits); - - if(Result == NULL) { - if(!ExpandAllocator(Bits)) { - TicketUnlock(&AllocatorLock); - return 0ULL; - } - - Result = AllocatorMalloc(Allocator, Bits); - } - - if(Result != NULL) { - memset(Result, 0, Bits); - } - - TicketUnlock(&AllocatorLock); - return Result; - -} - -void* ReallocateMemory(void* Address, size_t NewSize) { - TicketAttemptLock(&AllocatorLock); - void* Result = AllocatorRealloc(Allocator, Address, NewSize); - - if(Result == NULL) { - if(!ExpandAllocator(NewSize)) { - TicketUnlock(&AllocatorLock); - return 0ULL; - } - - Result = AllocatorRealloc(Allocator, Address, NewSize); - } - - TicketUnlock(&AllocatorLock); - return Result; - -} - -void FreeMemory(void* Address) { - TicketAttemptLock(&AllocatorLock); - AllocatorFree(Allocator, Address); - TicketUnlock(&AllocatorLock); -} - -void* AllocateKernelStack() { - void* StackAddress = NULL; - size_t StackSize = PAGE_SIZE * 4; - - TicketAttemptLock(&StackLock); - if(ListIsEmpty(&StackFreeList)) { - StackAddress = StackPointer; - StackPointer = (void*)(((char*)StackPointer) + (4*KiB) + StackSize); - - for(size_t i = 0; i < (StackSize / PAGE_SIZE); i++) { - directptr_t NewStack; - NewStack = PhysAllocateZeroMem(PAGE_SIZE); - MapVirtualMemory(&KernelAddressSpace, (void*)((size_t)StackAddress + i * PAGE_SIZE), (size_t)((char*)NewStack) - DIRECT_REGION, MAP_WRITE); - } - } else { - list_entry_t* StackEntry = StackFreeList.Next; - ListRemove(StackEntry); - memset(StackEntry, 0, StackSize); - StackAddress = (void*)StackEntry; - } - - TicketUnlock(&StackLock); - - StackAddress = (void*)((size_t)StackAddress + StackSize); - StackAddress = (void*)((size_t)StackAddress - sizeof(size_t) * 2); - - return StackAddress; -} - -void FreeKernelStack(void* StackAddress) { - TicketAttemptLock(&StackLock); - list_entry_t* ListEntry = (list_entry_t*)(((size_t)(StackAddress) + (sizeof(size_t) * 2)) - (PAGE_SIZE * 4)); - ListAdd(&StackFreeList, ListEntry); - TicketUnlock(&StackLock); -} diff --git a/chroma/system/memory/temp_storage/legacypaging.c b/chroma/system/memory/temp_storage/legacypaging.c deleted file mode 100644 index 8c97a0e..0000000 --- a/chroma/system/memory/temp_storage/legacypaging.c +++ /dev/null @@ -1,310 +0,0 @@ - -void InitPagingT() { - - size_t* PML4 = (size_t*) 0xFFA000; // Layer 4 - size_t* PDPE_RAM = (size_t*) 0xFFE000; // Layer 3, contains map for the first 4GB of RAM - size_t* PDE_RAM = (size_t*) 0xFFF000; - - size_t* PDPE_KERNEL = (size_t*) 0xFFB000; // Layer 3, contains map for the Kernel and everything it needs to run. - size_t* PDE_KERNEL_FB = (size_t*) 0xFFC000; // Layer 2, contains map for the linear framebuffer. - - size_t* PT_KERNEL = (size_t*) 0xFFD000; // Layer 1, the page table for the kernel itself. - - size_t fb_ptr = (size_t) &fb; - - SET_ADDRESS(PML4, PDPE_RAM); // 3rd Layer entry for RAM - SET_ADDRESS(PML4 + LAST_ENTRY, PDPE_KERNEL); // 3rd Layer entry for Kernel - - SET_ADDRESS(PDPE_KERNEL + LAST_ENTRY, PDE_KERNEL_FB); // 2nd Layer entry for the framebuffer - - // Set the 480th entry (PDE_KERNEL_FB + (480 * 8)) - // To the framebuffer + flags - SET_ADDRESS(PDE_KERNEL_FB + 3840, USERWRITEABLE_FLAGS(fb_ptr)); - - // In 4 byte increments, we're gonna map 3840 (the framebuffer) - // Up to (4096 - 8) in the PDE_KERNEL_FB with 2MB paging. - size_t MappingIterations = 1; - for(size_t i = 3844; i < 4088; i += 4) { - SET_ADDRESS(PDE_KERNEL_FB + i, USERWRITEABLE_FLAGS(fb_ptr) + (MappingIterations * (2 * MiB))); - MappingIterations++; - } - - // Now we map the last entry of PDE_KERNEL_FB to our Page Table - SET_ADDRESS(PDE_KERNEL_FB + LAST_ENTRY, PT_KERNEL); - - // Mapping the kernel into the page tables.... - - SET_ADDRESS(PT_KERNEL, 0xFF8001); // bootldr, bootinfo - SET_ADDRESS(PT_KERNEL + 8, 0xFF9001); // environment - - // Map the kernel itself - SET_ADDRESS(PT_KERNEL + 16, KernelAddr + 1); - - // Iterate through the pages, identity mapping each one - MappingIterations = 1; - size_t MappingOffset = 0x14; - for(size_t i = 0; i < ((KernelEnd - KernelAddr) >> 12); i++) { - // Page Table + (0x10 increasing by 0x04 each time) = x * 4KiB - SET_ADDRESS(PT_KERNEL + MappingOffset, (MappingIterations * (4 * KiB))); - MappingOffset += 4; - MappingIterations++; - } - - // Now we need to map the core stacks. Top-down, from 0xDFF8 - // There's always at least one core, so we do that one fixed. - // TODO: Account for 0-core CPUs - SET_ADDRESS(PT_KERNEL + LAST_ENTRY, 0xF14003); - MappingIterations = 1; - // For every core: - for(size_t i = 0; i < (bootldr.numcores + 3U) >> 2; i++) { - // PT_KERNEL[512 - (iterations + 1)] = 0x14003 + (iterations * page-width) - SET_ADDRESS(PT_KERNEL + LAST_ENTRY - (MappingIterations * 8), 0xF14003 + (4096 * MappingIterations)); - MappingIterations++; - } - - SET_ADDRESS(PDPE_RAM, PDE_RAM + PAGE_PRESENT + PAGE_RW); - SET_ADDRESS(PDPE_RAM + 8, 0xF10000 + PAGE_PRESENT + PAGE_RW); - SET_ADDRESS(PDPE_RAM + 16, 0xF11000 + PAGE_PRESENT + PAGE_RW); - SET_ADDRESS(PDPE_RAM + 24, 0xF12000 + PAGE_PRESENT + PAGE_RW); - - // Identity map 4GB of ram - // Each page table can only hold 512 entries, but we - // just set up 4 of them - overflowing PDE_RAM (0xF000) - // will take us into 0x10000, into 0x11000, into 0x120000. - for(size_t i = 0; i < 512 * 4/*GB*/; i++) { - // add PDE_RAM, 4 - // mov eax, 0x83 - // add eax, 2*1024*1024 - SET_ADDRESS(PDE_RAM + (i * 4), USERWRITEABLE_FLAGS(i * (2 * MiB))); - } - - // Map first 2MB of memory - SET_ADDRESS(PDE_RAM, 0xF13000 + PAGE_PRESENT + PAGE_RW); - - for(size_t i = 0; i < 512; i++) { - SET_ADDRESS(0xF13000 + i * 4, i * (4 * KiB) + PAGE_PRESENT + PAGE_RW); - } - - // 0xA000 should now contain our memory map. - -} - -void TraversePageTables() { - -} - - -void InitPagingOldImpl() { - - // Disable paging so that we can work with the pagetable - //size_t registerTemp = ReadControlRegister(0); - //UNSET_PGBIT(registerTemp); - //WriteControlRegister(0, registerTemp); - - // Clear space for our pagetable - size_t PagetableDest = 0x1000; - memset((char*)PagetableDest, 0, 4096); - - // Start setting pagetable indexes - *((size_t*)PagetableDest) = 0x2003; // PDP at 0x2000, present & r/w - *((size_t*)PagetableDest + 0x1000) = 0x3003; // PDT at 0x3000, present & r/w - *((size_t*)PagetableDest + 0x2000) = 0x4003; // PT at 0x4000, present & r/w - - size_t value = 0x3; - size_t offset = 8; - for(size_t i = 0; i < 512; i++) { // 512 iterations (entries into the page table) - *((size_t*) PagetableDest + offset) = value; // We're setting 512 bytes with x003 - // (identity mapping the first 4 megabytes of memory) - // (mapping the page table to itself) - value += 4096; // Point to start of next page - offset += 8; // + 8 bytes (next entry in list) - } - - // Enable PAE paging - size_t reg = ReadControlRegister(4); - SET_PAEBIT(reg); - WriteControlRegister(4, reg); - - WriteControlRegister(3, PagetableDest); - -} - - -/* size_t registerTemp = ReadControlRegister(4); - if(registerTemp & (1 << 7)) { - TOGGLE_PGEBIT(registerTemp); - WriteControlRegister(4, registerTemp); - } - - if(registerTemp & (1 << 7)) - WriteControlRegister(4, registerTemp ^ (1 << 7)); - - size_t CPUIDReturn; - asm volatile("cpuid" : "=d" (CPUIDReturn) : "a" (0x80000001) : "%rbx", "%rcx"); - - if(CPUIDReturn & (1 << 26)) { - SerialPrintf("System supports 1GB pages.\r\n"); - - if(registerTemp & (1 << 12)) { - SerialPrintf("PML5 paging available - using that instead.\r\n"); - - if(MemorySize > (1ULL << 57)) - SerialPrintf("System has over 128Petabytes of RAM. Please consider upgrading the OS on your supercomputer.\r\n"); - - size_t MaxPML5 = 1; - size_t MaxPML4 = 1; - size_t MaxPDP = 512; - - size_t LastPML4Entry = 512; - size_t LastPDPEntry = 512; - - size_t MemorySearchDepth = MemorySize; - - while(MemorySearchDepth > (256ULL << 30)) { - MaxPML5++; - MemorySearchDepth -= (256ULL << 30); - } - - if(MaxPML5 > 512) - MaxPML5 = 512; - - if(MemorySearchDepth) { - LastPDPEntry = ( (MemorySearchDepth + ((1 << 30) - 1)) & (~0ULL << 30)) >> 30; - - if(MaxPML5 > 512) - MaxPML5 = 512; - - } - - size_t PML4Size = PAGETABLE_SIZE * MaxPML5; - size_t PDPSize = PML4Size * MaxPML4; - - size_t PML4Base = AllocatePagetable(PML4Size + PDPSize); - size_t PDPBase = PML4Base + PML4Size; - - for(size_t PML5Entry = 0; PML5Entry < MaxPML5; PML5Entry++) { - Pagetable[PML5Entry] = PML4Base + (PML5Entry << 12); - - if(PML5Entry == (MaxPML5 - 1)) - MaxPML4 = LastPML4Entry; - - for(size_t PML4Entry = 0; PML4Entry < MaxPML4; PML4Entry++) { - - ((size_t*) Pagetable[PML5Entry])[PML4Entry] = PDPBase + (((PML5Entry << 9) + PML5Entry) << 12); - - if( (PML5Entry == (MaxPML5 - 1)) && (PML4Entry == (MaxPML4 -1)) ) - MaxPDP = LastPDPEntry; - - for(size_t PDPEntry = 0; PDPEntry < MaxPDP; PDPEntry++) { - ((size_t* ) ((size_t* ) Pagetable[PML5Entry])[PML4Entry])[PDPEntry] = ( ((PML5Entry << 18) + (PML4Entry << 9) + PDPEntry) << 30) | (0x83); - } - - ((size_t* ) Pagetable[PML5Entry])[PML4Entry] |= 0x3; - } - - Pagetable[PML5Entry] |= 0x3; - } - } else { - SerialPrintf("PML4 available - using that instead.\r\n"); - size_t MemorySearchDepth = MemorySize; - - if(MemorySearchDepth > (1ULL << 48)) - SerialPrintf("RAM limited to 256TB.\r\n"); - - size_t MaxPML4 = 1; - size_t MaxPDP = 512; - - size_t LastPDPEntry = 512; - - while(MemorySearchDepth > (512ULL << 30)) { - MaxPML4++; - MemorySearchDepth -= (512ULL << 30); - } - - if(MaxPML4 > 512) - MaxPML4 = 512; - - if(MemorySearchDepth) { - LastPDPEntry = ( (MemorySearchDepth + ((1 << 30) - 1)) & (~0ULL << 30)) >> 30; - - if(LastPDPEntry > 512) - LastPDPEntry = 512; - } - - size_t PDPSize = PAGETABLE_SIZE * MaxPML4; - size_t PDPBase = AllocatePagetable(PDPSize); - - for(size_t PML4Entry = 0; PML4Entry < MaxPML4; PML4Entry++) { - Pagetable[PML4Entry] = PDPBase + (PML4Entry << 12); - - if(PML4Entry == (MaxPML4 - 1)) { - MaxPDP = LastPDPEntry; - } - - for(size_t PDPEntry = 0; PDPEntry < MaxPDP; PDPEntry++) { - ((size_t* ) Pagetable[PML4Entry])[PDPEntry] = (((PML4Entry << 9) + PDPEntry) << 30) | 0x83; - } - - Pagetable[PML4Entry] |= 0x3; - } - } - } else { - SerialPrintf("System does not support 1GB pages - using 2MiB paging instead.\r\n"); - - size_t MemorySearchDepth = MemorySize; - - if(MemorySearchDepth > (1ULL << 48)) { - SerialPrintf("Usable RAM is limited to 256TB, and the page table alone will use 1GB of space in memory.\r\n"); - } - - size_t MaxPML4 = 1, MaxPDP = 512, MaxPD = 512, LastPDPEntry = 1; - - while(MemorySearchDepth > (512ULL << 30)) { - MaxPML4++; - MemorySearchDepth -= (512ULL << 30); - } - - if(MaxPML4 > 512) - MaxPML4 = 512; - - if(MemorySearchDepth) { - LastPDPEntry = ((MemorySearchDepth + ((1 << 30) - 1)) & (~0ULL << 30)) >> 30; - - if(LastPDPEntry > 512) - LastPDPEntry = 512; - } - - size_t PDPSize = PAGETABLE_SIZE * MaxPML4; - size_t PDSize = PDPSize * MaxPDP; - - size_t PDPBase = AllocatePagetable(PDPSize + PDSize); - size_t PDBase = PDPBase + PDSize; - - for(size_t PML4Entry = 0; PML4Entry < MaxPML4; PML4Entry++) { - Pagetable[PML4Entry] = PDBase + (PML4Entry << 12); - - if(PML4Entry == (MaxPML4 - 1)) { - MaxPDP = LastPDPEntry; - } - - for(size_t PDPEntry = 0; PDPEntry < MaxPDP; PDPEntry++) { - ( (size_t* ) Pagetable[PML4Entry])[PDPEntry] = PDBase + (((PML4Entry << 9) + PDPEntry) << 12); - - for(size_t PDEntry = 0; PDEntry < MaxPD; PDEntry++) { - ( (size_t* ) ((size_t*) Pagetable[PML4Entry])[PDPEntry])[PDEntry] = (( (PML4Entry << 18) + (PDPEntry << 9) + PDPEntry) << 21) | 0x83; - } - - ( (size_t* ) Pagetable[PML4Entry])[PDPEntry] |= 0x3; - } - - Pagetable[PML4Entry] |= 0x3; - } - } - - WriteControlRegister(3, Pagetable); - - registerTemp = ReadControlRegister(4); - if(!(registerTemp & (1 << 7))) { - TOGGLE_PGEBIT(registerTemp); - WriteControlRegister(4, registerTemp); - }*/ \ No newline at end of file diff --git a/chroma/system/memory/temp_storage/paging.c b/chroma/system/memory/temp_storage/paging.c deleted file mode 100644 index c66ee7f..0000000 --- a/chroma/system/memory/temp_storage/paging.c +++ /dev/null @@ -1,379 +0,0 @@ -#include -#include - -/************************ - *** Team Kitty, 2020 *** - *** Chroma *** - ***********************/ - -/**************************************** - * W O R K I N P R O G R E S S * - **************************************** - * - * This file contains functions for virtual memory management. - * - * Virtual Memory Management is still a work in progress. - * The functions here are hold-offs from old versions of the software implemented here, as well as from the EFI version of Chroma, called Sync. - * - * There, these functions worked, but here, under BIOS, it's a lot more difficult. - * It will take some time to get these functions working. - * - * The general plan, being that the BOOTBOOT loader has given us static addresses for all of our doodads, - * is to keep the core kernel where it is (FFFFFFFFFFE00000) and load in modules and libraries around it. - * - * We start in the higher half, so we'll dedicate the lower half (7FFFFFFFFFFF and below) to userspace. - * - * That means we have about 3 terabytes of RAM for the kernel. - * This will be identity mapped, always. - * - * Handily, since most modern processors ignore the highest 2 bytes of a virtual address, and the kernel - * is mapped to 0x80000000000 and above, we can use the nomenclature: - * * 0x00007FFFFFFFFFFF and below is user space. - * * 0xFFFF800000000000 and above is kernel space. - * The processor will ignore the first 4 chars, and this provides a great deal of readability for the - * future of the kernel. - * - * We'll have a kernel heap mapped into this kernel space, as well as a kernel stack (for task switching and error tracing). - * These will be 1GB each. - * We may have to increase this in the future, once Helix is fully integrated. - * Helix will take a lot of memory, as it is a fully featured 3D engine. We may have to implement things like - * texture streaming and mipmapping. Minimising RAM usage is NOT a priority for me, but it would be nice - * to have a minimum requirement above 32GB. - * - * // TODO: Expand Kernel Heap - * - * - * //TODO: there are lots of calls to AllocateFrame here, those need to be separated out into AllocateZeroFrame if necessary. - * - * - */ - -extern size_t _kernel_text_start; -extern size_t _kernel_rodata_start; -extern size_t _kernel_data_start; - -//__attribute__((aligned(4096))) static size_t Pagetable[512] = {0}; - -#define LAST_ENTRY 0xFF8 - -#define SET_ADDRESS(a,b) ((*(size_t*) (a)) = (size_t) b) - -/* - * It turns out it's useful to have macros for the standard - * data size units. - * - * Who would've thoguht? - */ - -#define KiB 1 * 1024 -#define MiB 1 * 1024 * KiB - - -#define PAGE_PRESENT 1 -#define PAGE_RW 2 -#define PAGE_USER 4 -#define PAGE_GLOBAL 8 - - -#define USERWRITEABLE_FLAGS(a) ((a & 0xFFFFFF00) + 0x83) - -// The AbstractAllocator control struct -static allocator_t Allocator = NULL; -// The AbstractAllocator Ticketlock. -static ticketlock_t AllocatorLock = {0}; - -// Entries to help allocate the Kernel Stack -static list_entry_t StackFreeList; -static ticketlock_t StackLock = {0}; -static void* StackPointer = (void*) KERNEL_STACK_REGION; - -// A temporary itoa function for better debugging.. -const char* IntToAscii(int In) { - char* OutputBuffer = " "; - - size_t Temp, i = 0, j = 0; - - do { - Temp = In % 10; - OutputBuffer[i++] = (Temp < 10) ? (Temp + '0') : (Temp + 'a' - 10); - } while (In /= 10); - - OutputBuffer[i--] = 0; - - for(j = 0; j < i; j++, i--) { - Temp = OutputBuffer[j]; - OutputBuffer[j] = OutputBuffer[i]; - OutputBuffer[i] = Temp; - } - - return OutputBuffer; - -} - - -void InitPaging() { - StackFreeList = (list_entry_t) { &StackFreeList, &StackFreeList }; - - size_t Size = AlignUpwards(AllocatorSize(), PAGE_SIZE); - Allocator = PhysAllocateZeroMem(Size); - Allocator = CreateAllocatorWithPool(Allocator, Size); - - SerialPrintf("[ Mem] Everything preallocated for paging.\n"); - - KernelAddressSpace = (address_space_t) { - .Lock = {0}, - .PML4 = PhysAllocateZeroMem(PAGE_SIZE) - }; - - size_t* Pagetable = KernelAddressSpace.PML4; - - //SerialPrintf("[ Mem] About to identity map the higher half.\n"); - // Identity map the higher half - for(int i = 256; i < 512; i++) { - Pagetable[i] = (size_t)PhysAllocateZeroMem(PAGE_SIZE); - Pagetable[i] = (size_t)(((char*)Pagetable[i]) - DIRECT_REGION); - Pagetable[i] |= (PAGE_PRESENT | PAGE_RW); - //SerialPrintf("%d", i - 256); - } - - SerialPrintf("[ Mem] Identity mapping higher half complete.\n"); - - MMapEnt* TopEntry = (MMapEnt*)(((&bootldr) + bootldr.size) - sizeof(MMapEnt)); - size_t LargestAddress = TopEntry->ptr + TopEntry->size; - - SerialPrintf("[ Mem] About to map lower memory into the Direct Region.\n"); - for(size_t Address = 0; Address < AlignUpwards(LargestAddress, PAGE_SIZE); Address += PAGE_SIZE) { - MapVirtualMemory(&KernelAddressSpace, (size_t*)(((char*)Address) + DIRECT_REGION), Address, MAP_WRITE); - } - SerialPrintf("[ Mem] Lower half mapping complete.\n"); - - SerialPrintf("[ Mem] Mapping kernel into new memory map.\r\n"); - - //TODO: Disallow execution of rodata and data, and bootldr/environment - for(void* Address = CAST(void*, KERNEL_REGION); - Address < CAST(void*, KERNEL_REGION + 0x2000); // Lower half of Kernel - Address = CAST(void*, CAST(char*, Address) + PAGE_SIZE)) { - MapVirtualMemory(&KernelAddressSpace, Address, (CAST(size_t, Address) - KERNEL_REGION) + KERNEL_PHYSICAL, MAP_EXEC); - } - - for(void* Address = CAST(void*, KERNEL_REGION + 0x2000); - Address < CAST(void*, KERNEL_REGION + 0x12000); // Higher half of kernel - Address = CAST(void*, CAST(char*, Address) + PAGE_SIZE)) { - MapVirtualMemory(&KernelAddressSpace, Address, (CAST(size_t, Address) - KERNEL_REGION) + KERNEL_PHYSICAL_2, MAP_EXEC); - } - - for(void* Address = CAST(void*, FB_REGION); - Address < CAST(void*, 0x200000); // TODO: Turn this into a calculation with bootldr.fb_size - Address = CAST(void*, CAST(char*, Address) + PAGE_SIZE)) { - MapVirtualMemory(&KernelAddressSpace, Address, (CAST(size_t, Address) - FB_REGION) + FB_PHYSICAL, MAP_WRITE); - } - - SerialPrintf("[ Mem] Kernel mapped into pagetables. New PML4 at 0x%p\r\n", KernelAddressSpace.PML4); - //ASSERT(Allocator != NULL); -} - -static size_t GetCachingAttribute(pagecache_t Cache) { - switch (Cache) { - case CACHE_WRITE_BACK: return 0; - case CACHE_WRITE_THROUGH: return 1 << 2; - case CACHE_NONE: return 1 << 3; - case CACHE_WRITE_COMBINING: return 1 << 6; - } - - return 1 << 3; -} - -static bool ExpandAllocator(size_t NewSize) { - size_t AllocSize = AlignUpwards(AllocatorPoolOverhead() + sizeof(size_t) * 5 + NewSize, PAGE_SIZE); - void* Pool = PhysAllocateMem(AllocSize); - return AddPoolToAllocator(Allocator, Pool, AllocSize) != NULL; -} - -static void GetPageFromTables(address_space_t* AddressSpace, size_t VirtualAddress, size_t** Page) { - - //ASSERT(Page != NULL); - //ASSERT(AddressSpace != NULL); - - size_t* Pagetable = AddressSpace->PML4; - for(int Level = 4; Level > 1; Level--) { - size_t* Entry = &Pagetable[(VirtualAddress >> (12u + 9u * (Level - 1))) & 0x1FFU]; - - ASSERT(*Entry & PAGE_PRESENT, "Page not present during retrieval"); - - Pagetable = (size_t*)((char*)(*Entry & 0x7ffffffffffff000ull) + DIRECT_REGION); - } - - ASSERT(Pagetable[(VirtualAddress >> 12U) & 0x1FFU] & PAGE_PRESENT, "PDPE not present during retrieval"); - *Page = &Pagetable[(VirtualAddress >> 12U) & 0x1FFU]; - -} - -void SetAddressSpace(address_space_t* AddressSpace) { - //ASSERT(AddressSpace != NULL); - - if((size_t)((char*)ReadControlRegister(3) + DIRECT_REGION) != (size_t) &AddressSpace->PML4) { - WriteControlRegister(3, CAST(size_t, &AddressSpace->PML4)); - } -} - -void MapVirtualMemory(address_space_t* AddressSpace, void* VirtualAddress, size_t PhysicalAddress, mapflags_t Flag) { - - //bool MapGlobally = false; - size_t Virtual = (size_t)VirtualAddress; - - //ASSERT(AddressSpace != NULL); - TicketAttemptLock(&AddressSpace->Lock); - - size_t Flags = PAGE_PRESENT; - - if(Flag & MAP_WRITE) - Flags |= MAP_WRITE; - - if(Virtual < USER_REGION) - Flags |= PAGE_USER; - //TODO: Global mapping - - size_t* Pagetable = AddressSpace->PML4; - for(int Level = 4; Level > 1; Level--) { - size_t* Entry = &Pagetable[(Virtual >> (12u + 9u * (Level - 1))) & 0x1FFu]; - - if(!(*Entry & PAGE_PRESENT)) { - directptr_t Pointer = PhysAllocateZeroMem(PAGE_SIZE); - *Entry = (size_t)(((char*)Pointer) + DIRECT_REGION); - } - - *Entry |= Flags; - - Pagetable = (size_t*)(((char*)(*Entry & 0x7ffffffffffff000ull) + DIRECT_REGION)); - } - - size_t* Entry = &Pagetable[(Virtual >> 12u) & 0x1FFu]; - *Entry = Flags | PhysicalAddress; - - - if(AddressSpace != NULL) { - TicketUnlock(&AddressSpace->Lock); - } - -} - -void UnmapVirtualMemory(address_space_t* AddressSpace, void* VirtualAddress){ - //ASSERT(AddressSpace != NULL); - - TicketAttemptLock(&AddressSpace->Lock); - - size_t* Entry; - GetPageFromTables(AddressSpace, (size_t)VirtualAddress, &Entry); - - *Entry = 0; - InvalidatePage((size_t)VirtualAddress); - - if(AddressSpace != NULL) { - TicketUnlock(&AddressSpace->Lock); - } - -} - -void CacheVirtualMemory(address_space_t* AddressSpace, void* VirtualAddress, pagecache_t Cache) { - - //ASSERT(AddressSpace != NULL); - - TicketAttemptLock(&AddressSpace->Lock); - - size_t* Entry; - - GetPageFromTables(AddressSpace, (size_t)VirtualAddress, &Entry); - - *Entry &= ~((1 << 6) | (1 << 2) | (1 << 3)); - *Entry |= GetCachingAttribute(Cache); - - InvalidatePage((size_t)VirtualAddress); - - if(AddressSpace != NULL) { - TicketUnlock(&AddressSpace->Lock); - } -} - - -void* AllocateMemory(size_t Bits) { - TicketAttemptLock(&AllocatorLock); - - void* Result = AllocatorMalloc(Allocator, Bits); - - if(Result == NULL) { - if(!ExpandAllocator(Bits)) { - TicketUnlock(&AllocatorLock); - return 0ULL; - } - - Result = AllocatorMalloc(Allocator, Bits); - } - - if(Result != NULL) { - memset(Result, 0, Bits); - } - - TicketUnlock(&AllocatorLock); - return Result; - -} - -void* ReallocateMemory(void* Address, size_t NewSize) { - TicketAttemptLock(&AllocatorLock); - void* Result = AllocatorRealloc(Allocator, Address, NewSize); - - if(Result == NULL) { - if(!ExpandAllocator(NewSize)) { - TicketUnlock(&AllocatorLock); - return 0ULL; - } - - Result = AllocatorRealloc(Allocator, Address, NewSize); - } - - TicketUnlock(&AllocatorLock); - return Result; - -} - -void FreeMemory(void* Address) { - TicketAttemptLock(&AllocatorLock); - AllocatorFree(Allocator, Address); - TicketUnlock(&AllocatorLock); -} - -void* AllocateKernelStack() { - void* StackAddress = NULL; - size_t StackSize = PAGE_SIZE * 4; - - TicketAttemptLock(&StackLock); - if(ListIsEmpty(&StackFreeList)) { - StackAddress = StackPointer; - StackPointer = (void*)(((char*)StackPointer) + (4*KiB) + StackSize); - - for(size_t i = 0; i < (StackSize / PAGE_SIZE); i++) { - directptr_t NewStack; - NewStack = PhysAllocateZeroMem(PAGE_SIZE); - MapVirtualMemory(&KernelAddressSpace, (void*)((size_t)StackAddress + i * PAGE_SIZE), (size_t)((char*)NewStack) - DIRECT_REGION, MAP_WRITE); - } - } else { - list_entry_t* StackEntry = StackFreeList.Next; - ListRemove(StackEntry); - memset(StackEntry, 0, StackSize); - StackAddress = (void*)StackEntry; - } - - TicketUnlock(&StackLock); - - StackAddress = (void*)((size_t)StackAddress + StackSize); - StackAddress = (void*)((size_t)StackAddress - sizeof(size_t) * 2); - - return StackAddress; -} - -void FreeKernelStack(void* StackAddress) { - TicketAttemptLock(&StackLock); - list_entry_t* ListEntry = (list_entry_t*)(((size_t)(StackAddress) + (sizeof(size_t) * 2)) - (PAGE_SIZE * 4)); - ListAdd(&StackFreeList, ListEntry); - TicketUnlock(&StackLock); -}