From: John Hodge Date: Thu, 25 Aug 2011 05:57:22 +0000 (+0800) Subject: Kernel/x86 - Implemented VFS node in PMM, debugging some other parts X-Git-Tag: rel0.11~123 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=c575e49ea4543b45ccd2a47d57ec590ca995e707;p=tpg%2Facess2.git Kernel/x86 - Implemented VFS node in PMM, debugging some other parts --- diff --git a/Kernel/arch/x86/errors.c b/Kernel/arch/x86/errors.c index dcedcd5c..3821281d 100644 --- a/Kernel/arch/x86/errors.c +++ b/Kernel/arch/x86/errors.c @@ -12,9 +12,10 @@ // === IMPORTS === extern void MM_PageFault(Uint Addr, Uint ErrorCode, tRegs *Regs); extern void VM8086_GPF(tRegs *Regs); -extern void Threads_Dump(void); +extern void Threads_Dump(void); extern void Threads_Fault(int Num); extern int GetCPUNum(void); +extern void MM_DumpTables(tVAddr, tVAddr); // === PROTOTYPES === void __stack_chk_fail(void); @@ -25,7 +26,7 @@ void StartupPrint(char *Str); // === GLOBALS === const char *csaERROR_NAMES[] = { "Divide By Zero", "Debug", "NMI Exception", "INT3", - "INTO", "Out of Bounds", "Invalid Opcode", "Coprocessor not avaliable", + "INTO Instr - Overflow", "BOUND Instr - Out of Bounds", "Invalid Opcode", "Coprocessor not avaliable", "Double Fault", "Coprocessor Segment Overrun", "Bad TSS", "Segment Not Present", "Stack Fault Exception", "GPF", "#PF", "Reserved", "Floating Point Exception", "Alignment Check Exception", "Machine Check Exception", "Reserved", @@ -94,6 +95,7 @@ void ErrorHandler(tRegs *Regs) csaERROR_NAMES[Regs->int_num], Regs->err_code); Log_Warning("Arch", "at CS:EIP %04x:%08x", Regs->cs, Regs->eip); + MM_DumpTables(0, KERNEL_BASE); switch( Regs->int_num ) { // Division by Zero diff --git a/Kernel/arch/x86/mm_phys.c b/Kernel/arch/x86/mm_phys.c index 78755d9b..fc71bd99 100644 --- a/Kernel/arch/x86/mm_phys.c +++ b/Kernel/arch/x86/mm_phys.c @@ -31,6 +31,7 @@ Uint64 giLastPossibleFree = 0; // Last possible free page (before all pages are Uint32 gaSuperBitmap[1024]; // Blocks of 1024 Pages Uint32 gaPageBitmap[1024*1024/32]; // Individual pages int *gaPageReferences; +void **gaPageNodes = (void*)MM_PAGENODE_BASE; #define REFENT_PER_PAGE (0x1000/sizeof(gaPageReferences[0])) // === CODE === @@ -471,6 +472,12 @@ void MM_DerefPhys(tPAddr PAddr) if(gaPageBitmap[ PAddr / 32 ] == 0) gaSuperBitmap[ PAddr >> 10 ] &= ~(1 << ((PAddr >> 5)&31)); } + + if( MM_GetPhysAddr( (tVAddr) &gaPageNodes[PAddr] ) ) + { + gaPageNodes[PAddr] = NULL; + // TODO: Free Node Page when fully unused + } // Release spinlock Mutex_Release( &glPhysAlloc ); @@ -494,3 +501,40 @@ int MM_GetRefCount(tPAddr PAddr) return gaPageReferences[ PAddr ]; } +int MM_SetPageNode(tPAddr PAddr, void *Node) +{ + tVAddr block_addr; + + if( MM_GetRefCount(PAddr) == 0 ) return 1; + + PAddr /= PAGE_SIZE; + + block_addr = (tVAddr) &gaPageNodes[PAddr]; + block_addr &= ~(PAGE_SIZE-1); + + if( !MM_GetPhysAddr( block_addr ) ) + { + if( !MM_Allocate( block_addr ) ) { + Log_Warning("PMem", "Unable to allocate Node page"); + return -1; + } + memset( (void*)block_addr, 0, PAGE_SIZE ); + } + + gaPageNodes[PAddr] = Node; + return 0; +} + +int MM_GetPageNode(tPAddr PAddr, void **Node) +{ + if( MM_GetRefCount(PAddr) == 0 ) { + return 1; + } + if( !MM_GetPhysAddr( (tVAddr) &gaPageNodes[PAddr] ) ) { + *Node = NULL; + return 0; + } + *Node = gaPageNodes[PAddr]; + return 0; +} + diff --git a/Kernel/arch/x86/mm_virt.c b/Kernel/arch/x86/mm_virt.c index f22de243..af3daa34 100644 --- a/Kernel/arch/x86/mm_virt.c +++ b/Kernel/arch/x86/mm_virt.c @@ -175,13 +175,15 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs) gaPageTable[Addr>>12] |= paddr|PF_PRESENT|PF_WRITE; } + Log_Debug("MMVirt", "COW for %p", Addr); + INVLPG( Addr & ~0xFFF ); return; } // If it was a user, tell the thread handler if(ErrorCode & 4) { - Warning("%s %s %s memory%s", + Log_Warning("MMVirt", "%s %s %s memory%s", (ErrorCode&4?"User":"Kernel"), (ErrorCode&2?"write to":"read from"), (ErrorCode&1?"bad/locked":"non-present"), @@ -277,15 +279,16 @@ void MM_DumpTables(tVAddr Start, tVAddr End) || (gaPageTable[page] & MASK) != expected) { if(expected) { + tPAddr orig = gaPageTable[rangeStart>>12]; Log(" 0x%08x => 0x%08x - 0x%08x (%s%s%s%s%s)", rangeStart, - gaPageTable[rangeStart>>12] & ~0xFFF, + orig & ~0xFFF, curPos - rangeStart, - (expected & PF_NOPAGE ? "P" : "-"), - (expected & PF_COW ? "C" : "-"), - (expected & PF_GLOBAL ? "G" : "-"), - (expected & PF_USER ? "U" : "-"), - (expected & PF_WRITE ? "W" : "-") + (orig & PF_NOPAGE ? "P" : "-"), + (orig & PF_COW ? "C" : "-"), + (orig & PF_GLOBAL ? "G" : "-"), + (orig & PF_USER ? "U" : "-"), + (orig & PF_WRITE ? "W" : "-") ); expected = 0; } @@ -427,7 +430,10 @@ int MM_Map(tVAddr VAddr, tPAddr PAddr) // Check if the directory is mapped if( gaPageDir[ VAddr >> 22 ] == 0 ) { - gaPageDir[ VAddr >> 22 ] = MM_AllocPhys() | 3; + tPAddr tmp = MM_AllocPhys(); + if( tmp == 0 ) + return 0; + gaPageDir[ VAddr >> 22 ] = tmp | 3; // Mark as user if(VAddr < MM_USER_MAX) gaPageDir[ VAddr >> 22 ] |= PF_USER; @@ -510,6 +516,10 @@ tPAddr MM_Clone(void) // Create Directory Table *gpTmpCR3 = MM_AllocPhys() | 3; + if( *gpTmpCR3 == 3 ) { + *gpTmpCR3 = 0; + return 0; + } INVLPG( gaTmpDir ); //LOG("Allocated Directory (%x)", *gpTmpCR3); memsetd( gaTmpDir, 0, 1024 ); @@ -861,6 +871,9 @@ tPAddr MM_DuplicatePage(tVAddr VAddr) // Allocate new page ret = MM_AllocPhys(); + if( !ret ) { + return 0; + } // Write-lock the page (to keep data constistent), saving its R/W state wasRO = (gaPageTable[VAddr >> 12] & PF_WRITE ? 0 : 1); @@ -997,6 +1010,10 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr) if(Pages == 1 && MaxBits >= PHYS_BITS) { phys = MM_AllocPhys(); + if( !phys ) { + *PhysAddr = 0; + LEAVE_RET('i', 0); + } *PhysAddr = phys; ret = MM_MapHWPages(phys, 1); if(ret == 0) { diff --git a/Kernel/arch/x86/vm8086.c b/Kernel/arch/x86/vm8086.c index 3c1bfed0..46daeefd 100644 --- a/Kernel/arch/x86/vm8086.c +++ b/Kernel/arch/x86/vm8086.c @@ -81,7 +81,6 @@ int VM8086_Install(char **Arguments) // Map ROM Area for(i=0xA0;i<0x100;i++) { MM_Map( i * 0x1000, i * 0x1000 ); - // MM_SetFlags( i * 0x1000, MM_PFLAG_RO, MM_PFLAG_RO ); // Set Read Only } Log_Debug("VM8086", "ROM area mapped"); MM_Map( 0, 0 ); // IVT / BDA @@ -90,7 +89,7 @@ int VM8086_Install(char **Arguments) for(i=1;i<0x9F;i++) { MM_Map( i * 0x1000, i * 0x1000 ); MM_DerefPhys( i * 0x1000 ); // Above - if(MM_GetRefCount(i*0x1000)) + while(MM_GetRefCount(i*0x1000)) MM_DerefPhys( i * 0x1000 ); // Phys setup } MM_Map( 0x9F000, 0x9F000 ); // Stack / EBDA @@ -422,6 +421,8 @@ void VM8086_Int(tVM8086 *State, Uint8 Interrupt) { State->IP = *(Uint16*)(KERNEL_BASE+4*Interrupt); State->CS = *(Uint16*)(KERNEL_BASE+4*Interrupt+2); + +// Log_Debug("VM8086", "Software interrupt %i to %04x:%04x", Interrupt, State->CS, State->IP); Mutex_Acquire( &glVM8086_Process );