Kernel/x86 - Implemented VFS node in PMM, debugging some other parts
authorJohn Hodge <[email protected]>
Thu, 25 Aug 2011 05:57:22 +0000 (13:57 +0800)
committerJohn Hodge <[email protected]>
Thu, 25 Aug 2011 05:57:22 +0000 (13:57 +0800)
Kernel/arch/x86/errors.c
Kernel/arch/x86/mm_phys.c
Kernel/arch/x86/mm_virt.c
Kernel/arch/x86/vm8086.c

index dcedcd5..3821281 100644 (file)
 // === 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
index 78755d9..fc71bd9 100644 (file)
@@ -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;
+}
+
index f22de24..af3daa3 100644 (file)
@@ -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) {
index 3c1bfed..46daeef 100644 (file)
@@ -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 );
        

UCC git Repository :: git.ucc.asn.au