X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fmm_virt.c;h=62ae08eb0da4ac198a3abad61a5d55259f59ae56;hb=f79073d5ab322eef0813f7b05af0d31174d2c9d6;hp=2a23d3f711fd20ca6d5778025ee2cd922ed17087;hpb=05a77640b59762adb12a71927ea4e003fd033102;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/mm_virt.c b/Kernel/arch/x86/mm_virt.c index 2a23d3f7..62ae08eb 100644 --- a/Kernel/arch/x86/mm_virt.c +++ b/Kernel/arch/x86/mm_virt.c @@ -55,6 +55,7 @@ #define PF_PRESENT 0x1 #define PF_WRITE 0x2 #define PF_USER 0x4 +#define PF_GLOBAL 0x80 #define PF_COW 0x200 #define PF_NOPAGE 0x400 @@ -78,6 +79,7 @@ void MM_PreinitVirtual(void); void MM_InstallVirtual(void); void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs); void MM_DumpTables(tVAddr Start, tVAddr End); +tVAddr MM_ClearUser(void); tPAddr MM_DuplicatePage(tVAddr VAddr); // === GLOBALS === @@ -183,8 +185,7 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs) //ENTER("xAddr bErrorCode", Addr, ErrorCode); // -- Check for COW -- - if( gaPageDir [Addr>>22] & PF_PRESENT - && gaPageTable[Addr>>12] & PF_PRESENT + if( gaPageDir [Addr>>22] & PF_PRESENT && gaPageTable[Addr>>12] & PF_PRESENT && gaPageTable[Addr>>12] & PF_COW ) { tPAddr paddr; @@ -203,7 +204,6 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs) } INVLPG( Addr & ~0xFFF ); - //LEAVE('-') return; } @@ -217,6 +217,9 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs) ); Warning("User Pagefault: Instruction at %04x:%08x accessed %p", Regs->cs, Regs->eip, Addr); __asm__ __volatile__ ("sti"); // Restart IRQs + #if 1 + Error_Backtrace(Regs->eip, Regs->ebp); + #endif Threads_SegFault(Addr); return ; } @@ -272,7 +275,7 @@ void MM_DumpTables(tVAddr Start, tVAddr End) tPAddr expected = 0; tVAddr curPos; Uint page; - const tPAddr MASK = ~0xF98; + const tPAddr MASK = ~0xF78; Start >>= 12; End >>= 12; @@ -302,14 +305,16 @@ void MM_DumpTables(tVAddr Start, tVAddr End) || (gaPageTable[page] & MASK) != expected) { if(expected) { - Log(" 0x%08x-0x%08x => 0x%08x-0x%08x (%s%s%s%s)", - rangeStart, curPos - 1, + Log(" 0x%08x => 0x%08x - 0x%08x (%s%s%s%s%s)", + rangeStart, gaPageTable[rangeStart>>12] & ~0xFFF, - (expected & ~0xFFF) - 1, - (expected & PF_PAGED ? "p" : "-"), + curPos - rangeStart, + (expected & PF_NOPAGE ? "P" : "-"), (expected & PF_COW ? "C" : "-"), + (expected & PF_GLOBAL ? "G" : "-"), (expected & PF_USER ? "U" : "-"), - (expected & PF_WRITE ? "W" : "-") + (expected & PF_WRITE ? "W" : "-"), + gaPageTable[page] & MASK, expected ); expected = 0; } @@ -323,11 +328,11 @@ void MM_DumpTables(tVAddr Start, tVAddr End) } if(expected) { - Log("0x%08x-0x%08x => 0x%08x-0x%08x (%s%s%s%s)", - rangeStart, curPos - 1, + Log("0x%08x => 0x%08x - 0x%08x (%s%s%s%s)", + rangeStart, gaPageTable[rangeStart>>12] & ~0xFFF, - (expected & ~0xFFF) - 1, - (expected & PF_PAGED ? "p" : "-"), + curPos - rangeStart, + (expected & PF_NOPAGE ? "p" : "-"), (expected & PF_COW ? "C" : "-"), (expected & PF_USER ? "U" : "-"), (expected & PF_WRITE ? "W" : "-") @@ -349,19 +354,16 @@ tPAddr MM_Allocate(tVAddr VAddr) { // Allocate directory paddr = MM_AllocPhys(); - //LOG("paddr = 0x%llx (new table)", paddr); if( paddr == 0 ) { Warning("MM_Allocate - Out of Memory (Called by %p)", __builtin_return_address(0)); //LEAVE('i',0); return 0; } - // Map + // Map and mark as user (if needed) gaPageDir[ VAddr >> 22 ] = paddr | 3; - // Mark as user if(VAddr < MM_USER_MAX) gaPageDir[ VAddr >> 22 ] |= PF_USER; INVLPG( &gaPageDir[ VAddr >> 22 ] ); - //LOG("Clearing new table"); memsetd( &gaPageTable[ (VAddr >> 12) & ~0x3FF ], 0, 1024 ); } // Check if the page is already allocated @@ -495,7 +497,6 @@ tVAddr MM_ClearUser(void) { Uint i, j; - // Copy Directories for( i = 0; i < (MM_USER_MAX>>22); i ++ ) { // Check if directory is not allocated @@ -504,7 +505,7 @@ tVAddr MM_ClearUser(void) continue; } - + // Deallocate tables for( j = 0; j < 1024; j ++ ) { if( gaPageTable[i*1024+j] & 1 ) @@ -512,6 +513,7 @@ tVAddr MM_ClearUser(void) gaPageTable[i*1024+j] = 0; } + // Deallocate directory MM_DerefPhys( gaPageDir[i] & ~0xFFF ); gaPageDir[i] = 0; INVLPG( &gaPageTable[i*1024] ); @@ -660,14 +662,28 @@ tVAddr MM_NewKStack(void) Uint i; for(base = KERNEL_STACKS; base < KERNEL_STACKS_END; base += KERNEL_STACK_SIZE) { + // Check if space is free if(MM_GetPhysAddr(base) != 0) continue; - for(i = 0; i < KERNEL_STACK_SIZE; i += 0x1000) { - MM_Allocate(base+i); + // Allocate + //for(i = KERNEL_STACK_SIZE; i -= 0x1000 ; ) + for(i = 0; i < KERNEL_STACK_SIZE; i += 0x1000 ) + { + if( MM_Allocate(base+i) == 0 ) + { + // On error, print a warning and return error + Warning("MM_NewKStack - Out of memory"); + // - Clean up + //for( i += 0x1000 ; i < KERNEL_STACK_SIZE; i += 0x1000 ) + // MM_Deallocate(base+i); + return 0; + } } + // Success Log("MM_NewKStack - Allocated %p", base + KERNEL_STACK_SIZE); return base+KERNEL_STACK_SIZE; } - Warning("MM_NewKStack - No address space left\n"); + // No stacks left + Warning("MM_NewKStack - No address space left"); return 0; }