From 2ebf89999759fc9d1ece6f98dfd439170995bb28 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 8 Sep 2011 08:17:05 +0800 Subject: [PATCH] Kernel/x86-64 - Updated and debug - Updated PMM to implement MM_GetPageNode etc - Known bug in VMM where PTEs aren't actually set/mapped, even though MM_DumpTables shows them --- Kernel/arch/x86_64/errors.c | 5 ++--- Kernel/arch/x86_64/include/arch.h | 2 +- Kernel/arch/x86_64/include/mm_virt.h | 18 ++++++++------- Kernel/arch/x86_64/main.c | 13 +++++------ Kernel/arch/x86_64/mm_phys.c | 33 ++++++++++++++++++++++++++++ Kernel/arch/x86_64/mm_virt.c | 19 ++++++++-------- 6 files changed, 61 insertions(+), 29 deletions(-) diff --git a/Kernel/arch/x86_64/errors.c b/Kernel/arch/x86_64/errors.c index 711846c8..0d5ede6f 100644 --- a/Kernel/arch/x86_64/errors.c +++ b/Kernel/arch/x86_64/errors.c @@ -98,8 +98,7 @@ void Error_Backtrace(Uint IP, Uint BP) // return; //} - if( IP > MM_USER_MAX - && IP < MM_KERNEL_CODE + if( IP > MM_USER_MAX && IP < MM_KERNEL_CODE && (MM_MODULE_MIN > IP || IP > MM_MODULE_MAX) ) { @@ -119,7 +118,7 @@ void Error_Backtrace(Uint IP, Uint BP) } - while( MM_GetPhysAddr(BP) && i < MAX_BACKTRACE ) + while( MM_GetPhysAddr(BP) && MM_GetPhysAddr(BP+8+7) && i < MAX_BACKTRACE ) { //str = Debug_GetSymbol(*(Uint*)(ebp+4), &delta); //if(str == NULL) diff --git a/Kernel/arch/x86_64/include/arch.h b/Kernel/arch/x86_64/include/arch.h index c2c622e5..d8b1124d 100644 --- a/Kernel/arch/x86_64/include/arch.h +++ b/Kernel/arch/x86_64/include/arch.h @@ -6,9 +6,9 @@ #define _ARCH_H_ //#include -//#define KERNEL_BASE 0xFFFF8000##00000000 #define KERNEL_BASE 0xFFFFFFFF##80000000 #define BITS 64 +#define PAGE_SIZE 0x1000 #define STACKED_LOCKS 2 // 0: No, 1: Per-CPU, 2: Per-Thread #define LOCK_DISABLE_INTS 0 diff --git a/Kernel/arch/x86_64/include/mm_virt.h b/Kernel/arch/x86_64/include/mm_virt.h index 1a7484cd..1af7bd52 100644 --- a/Kernel/arch/x86_64/include/mm_virt.h +++ b/Kernel/arch/x86_64/include/mm_virt.h @@ -31,10 +31,11 @@ * D000 00000000 - D080 00000000 39 512 GiB Per-Process Data * D080 00000000 - D100 00000000 39 512 GiB Kernel Supplied User Code * ---- GAP ---- 15 TiB - * E000 00000000 - E400 00000000 42 4 TiB Physical Page Reference Counts (2**40 = 2**52 bytes) - * E400 00000000 - E480 00000000 39 512 GiB Physical Page Bitmap (1 page per bit) - * E480 00000000 - E500 00000000 39 512 GiB Physical Page DblAlloc Bitmap (1 page per bit) - * E500 00000000 - E500 80000000 31 2 GiB Physical Page Super Bitmap (64 pages per bit) + * E000 00000000 - E800 00000000 43 8 TiB Physical Page Nodes (2**40 pages * 8 bytes) + * E800 00000000 - EC00 00000000 42 4 TiB Physical Page Reference Counts (2**40 pg * 4 bytes) + * EC00 00000000 - EC80 00000000 39 512 GiB Physical Page Bitmap (1 page per bit) + * EC80 00000000 - ED00 00000000 39 512 GiB Physical Page DblAlloc Bitmap (1 page per bit) + * ED00 00000000 - ED00 80000000 31 2 GiB Physical Page Super Bitmap (64 pages per bit) * ---- GAP ---- 9 TiB * FE00 00000000 - FE80 00000000 39 512 GiB Fractal Mapping (PML4 508) * FE80 00000000 - FF00 00000000 39 512 GiB Temp Fractal Mapping @@ -66,10 +67,11 @@ #define MM_PPD_HANDLES (MM_KERNEL_RANGE|(0xD008##00000000)) #define MM_USER_CODE (MM_KERNEL_RANGE|(0xD080##00000000)) -#define MM_PAGE_COUNTS (MM_KERNEL_RANGE|(0xE000##00000000)) -#define MM_PAGE_BITMAP (MM_KERNEL_RANGE|(0xE400##00000000)) -#define MM_PAGE_DBLBMP (MM_KERNEL_RANGE|(0xE480##00000000)) -#define MM_PAGE_SUPBMP (MM_KERNEL_RANGE|(0xE500##00000000)) +#define MM_PAGE_NODES (MM_KERNEL_RANGE|(0xE000##00000000)) +#define MM_PAGE_COUNTS (MM_KERNEL_RANGE|(0xE800##00000000)) +#define MM_PAGE_BITMAP (MM_KERNEL_RANGE|(0xEC00##00000000)) +#define MM_PAGE_DBLBMP (MM_KERNEL_RANGE|(0xEC00##00000000)) +#define MM_PAGE_SUPBMP (MM_KERNEL_RANGE|(0xED00##00000000)) #define MM_FRACTAL_BASE (MM_KERNEL_RANGE|(0xFE00##00000000)) #define MM_TMPFRAC_BASE (MM_KERNEL_RANGE|(0xFE80##00000000)) diff --git a/Kernel/arch/x86_64/main.c b/Kernel/arch/x86_64/main.c index af231eea..044330a0 100644 --- a/Kernel/arch/x86_64/main.c +++ b/Kernel/arch/x86_64/main.c @@ -29,7 +29,7 @@ void kmain(Uint MbMagic, void *MbInfoPtr) Desctab_Init(); MM_InitVirt(); - *(Uint16*)(0xB8000) = 0x1F00|'C'; + *(Uint16*)(KERNEL_BASE|0xB8000) = 0x1F00|'C'; switch(MbMagic) { @@ -50,24 +50,21 @@ void kmain(Uint MbMagic, void *MbInfoPtr) Log("gsBootCmdLine = '%s'", gsBootCmdLine); - *(Uint16*)(0xB8000) = 0x1F00|'D'; + *(Uint16*)(KERNEL_BASE|0xB8000) = 0x1F00|'D'; Heap_Install(); - *(Uint16*)(0xB8000) = 0x1F00|'E'; + *(Uint16*)(KERNEL_BASE|0xB8000) = 0x1F00|'E'; Log_Log("Arch", "Starting threading..."); Threads_Init(); Time_Setup(); - *(Uint16*)(0xB8000) = 0x1F00|'F'; + *(Uint16*)(KERNEL_BASE|0xB8000) = 0x1F00|'F'; Log_Log("Arch", "Starting VFS..."); // Load Virtual Filesystem VFS_Init(); - *(Uint16*)(0xB8000) = 0x1F00|'Z'; - *(Uint16*)(0xB8002) = 0x1F00|'Z'; - *(Uint16*)(0xB8004) = 0x1F00|'Z'; - *(Uint16*)(0xB8006) = 0x1F00|'Z'; + *(Uint16*)(KERNEL_BASE|0xB8000) = 0x1F00|'Z'; // Pass on to Independent Loader Log_Log("Arch", "Starting system"); diff --git a/Kernel/arch/x86_64/mm_phys.c b/Kernel/arch/x86_64/mm_phys.c index fcc85473..eb495b33 100644 --- a/Kernel/arch/x86_64/mm_phys.c +++ b/Kernel/arch/x86_64/mm_phys.c @@ -36,6 +36,7 @@ Uint64 *gaSuperBitmap = (void*)MM_PAGE_SUPBMP; // 1 bit = 64 Pages, 16 MiB per W Uint64 *gaMainBitmap = (void*)MM_PAGE_BITMAP; // 1 bit = 1 Page, 256 KiB per Word Uint64 *gaMultiBitmap = (void*)MM_PAGE_DBLBMP; // Each bit means that the page is being used multiple times Uint32 *gaiPageReferences = (void*)MM_PAGE_COUNTS; // Reference Counts +void **gapPageNodes = (void*)MM_PAGE_NODES; // Reference Counts tPAddr giFirstFreePage; // First possibly free page Uint64 giPhysRangeFree[NUM_MM_PHYS_RANGES]; // Number of free pages in each range Uint64 giPhysRangeFirst[NUM_MM_PHYS_RANGES]; // First free page in each range @@ -553,3 +554,35 @@ int MM_int_GetRangeID( tPAddr Addr ) else return MM_PHYS_16BIT; } + +int MM_SetPageNode(tPAddr PAddr, void *Node) +{ + tPAddr page = PAddr >> 12; + tVAddr node_page = ((tVAddr)&gapPageNodes[page]) & ~(PAGE_SIZE-1); + +// if( !MM_GetRefCount(PAddr) ) return 1; + + if( !MM_GetPhysAddr(node_page) ) { + if( !MM_Allocate(node_page) ) + return -1; + memset( (void*)node_page, 0, PAGE_SIZE ); + } + + gapPageNodes[page] = Node; + return 0; +} + +int MM_GetPageNode(tPAddr PAddr, void **Node) +{ +// if( !MM_GetRefCount(PAddr) ) return 1; + PAddr >>= 12; + + if( !MM_GetPhysAddr( (tVAddr)&gapPageNodes[PAddr] ) ) { + *Node = NULL; + return 0; + } + + *Node = gapPageNodes[PAddr]; + return 0; +} + diff --git a/Kernel/arch/x86_64/mm_virt.c b/Kernel/arch/x86_64/mm_virt.c index 0b856573..40d4eb17 100644 --- a/Kernel/arch/x86_64/mm_virt.c +++ b/Kernel/arch/x86_64/mm_virt.c @@ -32,13 +32,13 @@ #define PF_NX 0x80000000##00000000 // === MACROS === -#define PAGETABLE(idx) (*((tPAddr*)MM_FRACTAL_BASE+((idx)&PAGE_MASK))) +#define PAGETABLE(idx) (*((Uint64*)MM_FRACTAL_BASE+((idx)&PAGE_MASK))) #define PAGEDIR(idx) PAGETABLE((MM_FRACTAL_BASE>>12)+((idx)&TABLE_MASK)) #define PAGEDIRPTR(idx) PAGEDIR((MM_FRACTAL_BASE>>21)+((idx)&PDP_MASK)) #define PAGEMAPLVL4(idx) PAGEDIRPTR((MM_FRACTAL_BASE>>30)+((idx)&PML4_MASK)) #define TMPCR3() PAGEMAPLVL4(MM_TMPFRAC_BASE>>39) -#define TMPTABLE(idx) (*((tPAddr*)MM_TMPFRAC_BASE+((idx)&PAGE_MASK))) +#define TMPTABLE(idx) (*((Uint64*)MM_TMPFRAC_BASE+((idx)&PAGE_MASK))) #define TMPDIR(idx) PAGETABLE((MM_TMPFRAC_BASE>>12)+((idx)&TABLE_MASK)) #define TMPDIRPTR(idx) PAGEDIR((MM_TMPFRAC_BASE>>21)+((idx)&PDP_MASK)) #define TMPMAPLVL4(idx) PAGEDIRPTR((MM_TMPFRAC_BASE>>30)+((idx)&PML4_MASK)) @@ -158,7 +158,7 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs) void MM_DumpTables(tVAddr Start, tVAddr End) { #define CANOICAL(addr) ((addr)&0x800000000000?(addr)|0xFFFF000000000000:(addr)) - const tPAddr CHANGEABLE_BITS = 0xFF8; + const tPAddr CHANGEABLE_BITS = ~(PF_PRESENT|PF_WRITE|PF_USER|PF_COW|PF_PAGED) & 0xFFF; const tPAddr MASK = ~CHANGEABLE_BITS; // Physical address and access bits tVAddr rangeStart = 0; tPAddr expected = CHANGEABLE_BITS; // CHANGEABLE_BITS is used because it's not a vaild value @@ -184,12 +184,11 @@ void MM_DumpTables(tVAddr Start, tVAddr End) //Debug("&PAGETABLE(%i page) = %p", page, &PAGETABLE(page)); // End of a range - if( - !(PAGEMAPLVL4(page>>27) & PF_PRESENT) - || !(PAGEDIRPTR(page>>18) & PF_PRESENT) - || !(PAGEDIR(page>>9) & PF_PRESENT) - || !(PAGETABLE(page) & PF_PRESENT) - || (PAGETABLE(page) & MASK) != expected) + if(!(PAGEMAPLVL4(page>>27) & PF_PRESENT) + || !(PAGEDIRPTR(page>>18) & PF_PRESENT) + || !(PAGEDIR(page>>9) & PF_PRESENT) + || !(PAGETABLE(page) & PF_PRESENT) + || (PAGETABLE(page) & MASK) != expected) { if(expected != CHANGEABLE_BITS) { Log("%016llx => %013llx : 0x%6llx (%c%c%c%c)", @@ -446,6 +445,8 @@ tPAddr MM_GetPhysAddr(tVAddr Addr) ret = MM_GetPageEntryPtr(Addr, 0, 0, 0, &ptr); if( ret < 0 ) return 0; + if( !(*ptr & 1) ) return 0; + return (*ptr & PADDR_MASK) | (Addr & 0xFFF); } -- 2.20.1