More memory management functions implemented, other fixes too
authorJohn Hodge <[email protected]>
Thu, 13 May 2010 23:55:36 +0000 (07:55 +0800)
committerJohn Hodge <[email protected]>
Thu, 13 May 2010 23:55:36 +0000 (07:55 +0800)
Kernel/arch/x86_64/mm_phys.c
Kernel/arch/x86_64/proc.c
Kernel/arch/x86_64/start32.asm
Kernel/arch/x86_64/start64.asm

index c64e1e0..3535fbc 100644 (file)
@@ -19,11 +19,13 @@ enum eMMPhys_Ranges
 // === GLOBALS ===
 tSpinlock      glPhysicalPages;
 Uint64 *gaSuperBitmap; // 1 bit = 64 Pages
-Uint64 *gaPrimaryBitmap;       // 1 bit = 1 Page
+Uint64 *gaPrimaryBitmap;       // 1 bit = 64 Pages
+Uint32 *gaiPageReferences;     // 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
 Uint64 giPhysRangeLast[NUM_MM_PHYS_RANGES];    // Last free page in each range
+Uint64 giMaxPhysPage = 0;      // Maximum Physical page
 
 // === CODE ===
 void MM_InitPhys()
@@ -92,14 +94,14 @@ tPAddr MM_AllocPhysRange(int Num, int Bits)
                                continue;
                        }
                        // Check page block (64 pages)
-                       if( gaPrimaryBitmap[addr >> 6] == -1) {
+                       if( gaSuperBitmap[addr >> (6+6)] & (1 << (addr>>6)&63)) {
                                nFree = 0;
                                addr += 1 << (12+6);
                                addr &= (1 << (12+6)) - 1;
                                continue;
                        }
                        // Check individual page
-                       if( gaPrimaryBitmap[addr >> 6] & (1 << (addr&63)) ) {
+                       if( gaiPageReferences[addr] ) {
                                nFree = 0;
                                addr ++;
                                continue;
@@ -134,6 +136,7 @@ tPAddr MM_AllocPhysRange(int Num, int Bits)
        addr -= Num;
        for( i = 0; i < Num; i++ )
        {
+               gaiPageReferences[addr] = 1;
                gaPrimaryBitmap[addr>>6] |= 1 << (addr & 63);
                if( gaPrimaryBitmap[addr>>6] == -1 )
                        gaSuperBitmap[addr>>12] |= 1 << ((addr >> 6) & 64);
@@ -158,3 +161,24 @@ tPAddr MM_AllocPhys(void)
 {
        return MM_AllocPhysRange(1, -1);
 }
+
+void MM_RefPhys(tPAddr PAddr)
+{
+       if( PAddr > giMaxPhysPage )     return ;
+       gaiPageReferences[ PAddr >> 12 ] ++;
+       
+       gaPrimaryBitmap[PAddr >> 18] |= 1 << ((PAddr>>12) & 63);
+       if( gaPrimaryBitmap[PAddr >> 18] == -1 )
+               gaSuperBitmap[PAddr >> 24] |= 1 << ((PAddr >> 18) & 64);
+}
+
+void MM_DerefPhys(tPAddr PAddr)
+{
+       if( PAddr > giMaxPhysPage )     return ;
+       gaiPageReferences[ PAddr >> 12 ] --;
+       if( gaiPageReferences[ PAddr >> 12 ] )
+       {
+               gaPrimaryBitmap[PAddr >> 18] &= ~(1 << ((PAddr >> 12) & 63));
+               gaSuperBitmap[PAddr >> 24] &= ~(1 << ((PAddr >> 18) & 64));
+       }
+}
index 5bb66af..b30eb22 100644 (file)
@@ -24,8 +24,8 @@
 extern tGDT    gGDT[];
 extern void APStartup();       // 16-bit AP startup code
 extern Uint    GetRIP();       // start.asm
-extern Uint64  gaInitPML4[512];        // start.asm
-extern void    Kernel_Stack_Top;
+extern Uint64  gInitialPML4[512];      // start.asm
+extern void    gInitialKernelStack;
 extern tSpinlock       glThreadListLock;
 extern int     giNumCPUs;
 extern int     giNextTID;
@@ -288,7 +288,7 @@ void ArchThreads_Init()
        gCurrentThread = &gThreadZero;
        #endif
        
-       gThreadZero.MemState.CR3 = (Uint)gaInitPML4 - KERNEL_BASE;
+       gThreadZero.MemState.CR3 = (Uint)gInitialPML4 - KERNEL_BASE;
        
        // Set timer frequency
        outb(0x43, 0x34);       // Set Channel 0, Low/High, Rate Generator
@@ -376,7 +376,7 @@ void Proc_ChangeStack()
                return;
        }
 
-       curBase = (Uint)&Kernel_Stack_Top;
+       curBase = (Uint)&gInitialKernelStack;
        
        LOG("curBase = 0x%x, newBase = 0x%x", curBase, newBase);
 
index 248fa8d..1163b31 100644 (file)
@@ -19,7 +19,7 @@ start:
        mov cr4, eax
 
        ; Load PDP4
-       mov eax, gInitialPML4
+       mov eax, gInitialPML4 - KERNEL_BASE
        mov cr3, eax
 
        ; Enable long/compatability mode
@@ -34,7 +34,7 @@ start:
        mov cr0, eax
 
        ; Load GDT
-       lgdt [gGDTPtr]
+       lgdt [gGDTPtr - KERNEL_BASE]
        mov ax, 0x10
        mov ss, ax
        mov ds, ax
@@ -45,6 +45,7 @@ start:
        jmp 0x08:start64 - KERNEL_BASE
 
 [section .data]
+[global gGDT]
 gGDT:
        dd      0,0
        dd      0x00000000, 0x00209800  ; 0x08: 64-bit Code
@@ -56,10 +57,11 @@ gGDT:
        times MAX_CPUS  dd      0, 0, 0, 0      ; 0x38+16*n: TSS 0
 gGDTPtr:
        dw      $-gGDT-1
-       dd      gGDT
+       dd      gGDT-KERNEL_BASE
        dd      0
 
 [section .padata]
+[global gInitialPML4]
 gInitialPML4:  ; Covers 256 TiB (Full 48-bit Virtual Address Space)
        dd      gInitialPDP - KERNEL_BASE + 3, 0        ; Identity Map Low 4Mb
        times 256-1 dq  0
index bf7293b..beb22e5 100644 (file)
@@ -3,6 +3,7 @@
 ;
 [bits 64]
 
+[section .text]
 [global start64]
 start64:
        ; Set kernel stack
@@ -13,3 +14,8 @@ start64:
 GetRIP:
        mov rax, [rsp]
        ret
+
+[section .bss]
+[global gInitialKernelStack]
+       resd    1024*1  ; 1 Page
+gInitialKernelStack:

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