Chicken and egg problem, solved
authorJohn Hodge <[email protected]>
Sat, 29 May 2010 03:19:25 +0000 (11:19 +0800)
committerJohn Hodge <[email protected]>
Sat, 29 May 2010 03:19:25 +0000 (11:19 +0800)
Kernel/Makefile.BuildNum
Kernel/arch/x86_64/errors.c
Kernel/arch/x86_64/include/mm_virt.h
Kernel/arch/x86_64/mm_phys.c
Kernel/arch/x86_64/mm_virt.c

index 74050b6..e1fa0fb 100644 (file)
@@ -1 +1 @@
-BUILD_NUM = 2277
+BUILD_NUM = 2287
index e66d550..1c68b18 100644 (file)
@@ -33,12 +33,14 @@ void Error_Handler(tRegs *Regs)
        Log(" SS:RSP = 0x%04x:%016x", Regs->SS, Regs->RSP);
        Log(" RFLAGS = 0x%016x", Regs->RFlags);
        
-       Log(" EAX %016x ECX %016x EDX %016x EBX %016x",
+       Log(" RAX %016x RCX %016x RDX %016x RBX %016x",
                Regs->RAX, Regs->RCX, Regs->RDX, Regs->RBX);
-       Log(" ESP %016x EBP %016x ESI %016x EDI %016x",
+       Log(" RSP %016x RBP %016x RSI %016x RDI %016x",
                Regs->RSP, Regs->RBP, Regs->RSP, Regs->RDI);
        Log(" R8  %016x R9  %016x R10 %016x R11 %016x",
                Regs->R8, Regs->R9, Regs->R10, Regs->R11);
+       Log(" R12 %016x R13 %016x R14 %016x R15 %016x",
+               Regs->R12, Regs->R13, Regs->R14, Regs->R15);
        Log(" FS %04x GS %04x", Regs->FS, Regs->GS);
        
        
index baade6e..5221e51 100644 (file)
  */
 
 #define        MM_USER_MIN     0x00000000##00010000
-#define USER_LIB_MAX   0x00008000##00000000
+#define USER_LIB_MAX   0x00007000##00000000
 #define USER_STACK_SZ  0x00000000##00020000    // 64 KiB
-#define USER_STACK_TOP 0x00008FFF##FFFFF000
-#define        MM_USER_MAX     0x00008FFF##FFFFF000
-//#define      KERNEL_BASE     0xFFF8000##00000000
+#define USER_STACK_TOP 0x00007FFF##FFFFF000
+#define        MM_USER_MAX     0x00007FFF##FFFFF000
+//#define      KERNEL_BASE     0xFFFF8000##00000000
 #define MM_KHEAP_BASE  (KERNEL_BASE|(0x8000##80000000))
 #define MM_KHEAP_MAX   (KERNEL_BASE|(0x9000##00000000))
 #define MM_MODULE_MIN  (KERNEL_BASE|(0x9000##00000000))
index 47fea40..3f5df37 100644 (file)
@@ -32,6 +32,11 @@ Uint64       giPhysRangeFree[NUM_MM_PHYS_RANGES];    // Number of free pages in each rang
 Uint64 giPhysRangeFirst[NUM_MM_PHYS_RANGES];   // First free page in each range
 Uint64 giPhysRangeLast[NUM_MM_PHYS_RANGES];    // Last free page in each range
 Uint64 giMaxPhysPage = 0;      // Maximum Physical page
+// Only used in init, allows the init code to provide pages for use by
+// the allocator before the bitmaps exist.
+// 3 entries because the are three calls to MM_AllocPhys in MM_Map
+#define NUM_STATIC_ALLOC       3
+tPAddr gaiStaticAllocPages[NUM_STATIC_ALLOC] = {0};
 
 // === CODE ===
 /**
@@ -46,7 +51,7 @@ void MM_InitPhys_Multiboot(tMBoot_Info *MBoot)
         int    i;
        Uint64  base, size;
        tVAddr  vaddr;
-       tPAddr  paddr;
+       tPAddr  paddr, firstFreePage;
        
        Log("MM_InitPhys_Multiboot: (MBoot=%p)", MBoot);
        
@@ -91,40 +96,38 @@ void MM_InitPhys_Multiboot(tMBoot_Info *MBoot)
                numPages, superPages);
        if(maxAddr == 0)
        {
-                int    todo = numPages;
+                int    todo = numPages*2 + superPages;
                // Ok, naieve allocation, just put it after the kernel
                // - Allocated Bitmap
                vaddr = MM_PAGE_BITMAP;
                paddr = (tPAddr)&gKernelEnd - KERNEL_BASE;
-               while(todo --)
+               while(todo )
                {
+                       // Allocate statics
+                       for( i = 0; i < NUM_STATIC_ALLOC; i++) {
+                               if(gaiStaticAllocPages[i] != 0) continue;
+                               gaiStaticAllocPages[i] = paddr;
+                               paddr += 0x1000;
+                       }
+                       
                        MM_Map(vaddr, paddr);
                        vaddr += 0x1000;
                        paddr += 0x1000;
-               }
-               // - Multi-Alloc Bitmap
-               vaddr = MM_PAGE_DBLBMP;
-               todo = numPages;
-               while(todo --) {
-                       MM_Map(vaddr, paddr);
-                       vaddr += 0x1000;
-                       paddr += 0x1000;
-               }
-               // - Super Bitmap
-               vaddr = MM_PAGE_SUPBMP;
-               todo = superPages;
-               while(todo --) {
-                       MM_Map(vaddr, paddr);
-                       vaddr += 0x1000;
-                       paddr += 0x1000;
+                       
+                       todo --;
+                       
+                       if( todo == numPages + superPages )
+                               vaddr = MM_PAGE_DBLBMP;
+                       if( todo == superPages )
+                               vaddr = MM_PAGE_SUPBMP;
                }
        }
        // Scan for a nice range
        else
        {
                 int    todo = numPages*2 + superPages;
-               tPAddr  paddr = 0;
-               tVAddr  vaddr = MM_PAGE_BITMAP;
+               paddr = 0;
+               vaddr = MM_PAGE_BITMAP;
                // Scan!
                for(
                        ent = mmapStart;
@@ -133,7 +136,6 @@ void MM_InitPhys_Multiboot(tMBoot_Info *MBoot)
                        )
                {
                         int    avail;
-                        int    i, max;
                        
                        // RAM only please
                        if( ent->Type != 1 )
@@ -161,13 +163,23 @@ void MM_InitPhys_Multiboot(tMBoot_Info *MBoot)
                        Log(" MM_InitPhys_Multiboot: paddr=0x%x, avail=%i", paddr, avail);
                        
                        // Map
-                       max = todo < avail ? todo : avail;
-                       for( i = 0; i < max; i ++ )
+                       while( todo && avail --)
                        {
+                               // Static Allocations
+                               for( i = 0; i < NUM_STATIC_ALLOC && avail; i++) {
+                                       if(gaiStaticAllocPages[i] != 0) continue;
+                                       gaiStaticAllocPages[i] = paddr;
+                                       paddr += 0x1000;
+                                       avail --;
+                               }
+                               if(!avail)      break;
+                               
+                               // Map
                                MM_Map(vaddr, paddr);
                                todo --;
                                vaddr += 0x1000;
                                paddr += 0x1000;
+                               
                                // Alter the destination address when needed
                                if(todo == superPages+numPages)
                                        vaddr = MM_PAGE_DBLBMP;
@@ -179,8 +191,10 @@ void MM_InitPhys_Multiboot(tMBoot_Info *MBoot)
                        if( !todo )             break;
                }
        }
+       // Save the current value of paddr to simplify the allocation later
+       firstFreePage = paddr;
        
-       Log(" MM_InitPhys_Multiboot: Cearing multi bitmap");
+       Log(" MM_InitPhys_Multiboot: Clearing multi bitmap");
        // Fill the bitmaps
        memset(gaMultiBitmap, 0, numPages<<12);
        // - initialise to one, then clear the avaliable areas
@@ -228,35 +242,20 @@ void MM_InitPhys_Multiboot(tMBoot_Info *MBoot)
        }
        
        // Reference the used pages
-       // - Kernel
-       Log(" MM_InitPhys_Multiboot: Setting kernel area");
        base = (tPAddr)&gKernelBase >> 12;
-       size = ((tPAddr)&gKernelEnd - KERNEL_BASE - base) >> 12;
+       size = firstFreePage >> 12;
        memset( &gaMainBitmap[base / 64], -1, size/8 );
        if( size & 7 ) {
                Uint64  val = -1 << (size & 7);
                val <<= (size/8)&7;
                gaMainBitmap[base / 64] |= val;
        }
-       // - Bitmaps
-       Log(" MM_InitPhys_Multiboot: Setting bitmaps' memory");
-       vaddr = MM_PAGE_BITMAP;
-       for( i = 0; i < numPages; i++, vaddr ++ )
-       {
-               paddr = MM_GetPhysAddr(vaddr) >> 12;
-               gaMainBitmap[paddr >> 6] |= 1 << (paddr&63);
-       }
-       vaddr = MM_PAGE_DBLBMP;
-       for( i = 0; i < numPages; i++, vaddr += 0x1000 )
-       {
-               paddr = MM_GetPhysAddr(vaddr) >> 12;
-               gaMainBitmap[paddr >> 6] |= 1 << (paddr&63);
-       }
-       vaddr = MM_PAGE_SUPBMP;
-       for( i = 0; i < superPages; i++, vaddr += 0x1000 )
-       {
-               paddr = MM_GetPhysAddr(vaddr) >> 12;
-               gaMainBitmap[paddr >> 6] |= 1 << (paddr&63);
+       // Free the unused static allocs
+       for( i = 0; i < NUM_STATIC_ALLOC; i++) {
+               if(gaiStaticAllocPages[i] != 0)
+                       continue;
+               gaMainBitmap[ gaiStaticAllocPages[i] >> (12+6) ]
+                       &= ~(1 << ((gaiStaticAllocPages[i]>>12)&63));
        }
        
        // Fill the super bitmap
@@ -412,6 +411,17 @@ tPAddr MM_AllocPhysRange(int Num, int Bits)
  */
 tPAddr MM_AllocPhys(void)
 {
+        int    i;
+       
+       // Hack to allow allocation during setup
+       for(i = 0; i < NUM_STATIC_ALLOC; i++) {
+               if( gaiStaticAllocPages[i] ) {
+                       tPAddr  ret = gaiStaticAllocPages[i];
+                       gaiStaticAllocPages[i] = 0;
+                       return ret;
+               }
+       }
+       
        return MM_AllocPhysRange(1, -1);
 }
 
index cf00f6e..be539db 100644 (file)
 #define PTAB_SHIFT     12
 
 #define        PADDR_MASK      0x7FFFFFFF##FFFFF000
+#define PAGE_MASK      (((Uint)1 << 36)-1)
+#define TABLE_MASK     (((Uint)1 << 27)-1)
+#define PDP_MASK       (((Uint)1 << 18)-1)
+#define PML4_MASK      (((Uint)1 << 9)-1)
 
 #define        PF_PRESENT      0x1
 #define        PF_WRITE        0x2
 #define        PF_NX           0x80000000##00000000
 
 // === MACROS ===
-#define PAGETABLE(idx) (*((tPAddr*)MM_FRACTAL_BASE+(idx)))
-#define PAGEDIR(idx)   PAGETABLE((MM_FRACTAL_BASE>>12)+((idx)&0x7FFFFFF))
-#define PAGEDIRPTR(idx)        PAGEDIR((MM_FRACTAL_BASE>>21)+((idx)&0x3FFFF))
-#define PAGEMAPLVL4(idx)       PAGEDIRPTR((MM_FRACTAL_BASE>>30)+((idx)&0x1FF))
+#define PAGETABLE(idx) (*((tPAddr*)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))
 
 // === GLOBALS ===
 
@@ -50,6 +54,11 @@ int MM_Map(tVAddr VAddr, tPAddr PAddr)
        Log("MM_Map: (VAddr=0x%x, PAddr=0x%x)", VAddr, PAddr);
        
        // Check PML4
+       Log(" MM_Map: &PAGEMAPLVL4(%x) = %x", VAddr >> 39, &PAGEMAPLVL4(VAddr >> 39));
+       Log(" MM_Map: &PAGEDIRPTR(%x) = %x", VAddr >> 30, &PAGEDIRPTR(VAddr >> 30));
+       Log(" MM_Map: &PAGEDIR(%x) = %x", VAddr >> 21, &PAGEDIR(VAddr >> 21));
+       Log(" MM_Map: &PAGETABLE(%x) = %x", VAddr >> 12, &PAGETABLE(VAddr >> 12));
+       Log(" MM_Map: &PAGETABLE(0) = %x", &PAGETABLE(0));
        if( !(PAGEMAPLVL4(VAddr >> 39) & 1) )
        {
                tmp = MM_AllocPhys();
@@ -77,10 +86,10 @@ int MM_Map(tVAddr VAddr, tPAddr PAddr)
        }
        
        // Check if this virtual address is already mapped
-       if( PAGETABLE(VAddr >> 12) & 1 )
+       if( PAGETABLE(VAddr >> PTAB_SHIFT) & 1 )
                return 0;
        
-       PAGETABLE(VAddr >> 12) = PAddr | 3;
+       PAGETABLE(VAddr >> PTAB_SHIFT) = PAddr | 3;
        
        return 1;
 }
@@ -97,7 +106,7 @@ void MM_Unmap(tVAddr VAddr)
        // Check Page Dir
        if( !(PAGEDIR(VAddr >> 21) & 1) )       return ;
        
-       PAGETABLE(VAddr >> 12) = 0;
+       PAGETABLE(VAddr >> PTAB_SHIFT) = 0;
 }
 
 /**
@@ -150,11 +159,11 @@ tPAddr MM_GetPhysAddr(tVAddr Addr)
        if( !(PAGEDIR(Addr >> 21) & 1) )
                return 0;
        Log(" MM_GetPhysAddr: PT Valid");
-       if( !(PAGETABLE(Addr >> 12) & 1) )
+       if( !(PAGETABLE(Addr >> PTAB_SHIFT) & 1) )
                return 0;
        Log(" MM_GetPhysAddr: Page Valid");
        
-       return (PAGETABLE(Addr >> 12) & ~0xFFF) | (Addr & 0xFFF);
+       return (PAGETABLE(Addr >> PTAB_SHIFT) & ~0xFFF) | (Addr & 0xFFF);
 }
 
 /**

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