X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fmm_phys.c;h=cc6857d150c559e6e3389e8ba6e7190be4c07c6c;hb=717454930aa0e255517c68c837927deac49bd78e;hp=faef2b3e5c69699ed96bf2a18af0ab4da2416a56;hpb=e5e272c426a28f2f9e69ed2232469575c7409af1;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/mm_phys.c b/Kernel/arch/x86/mm_phys.c index faef2b3e..cc6857d1 100644 --- a/Kernel/arch/x86/mm_phys.c +++ b/Kernel/arch/x86/mm_phys.c @@ -16,10 +16,12 @@ extern void gKernelEnd; // === PROTOTYPES === -tPAddr MM_AllocPhys(void); -tPAddr MM_AllocPhysRange(int Pages, int MaxBits); -void MM_RefPhys(tPAddr PAddr); -void MM_DerefPhys(tPAddr PAddr); +void MM_Install(tMBoot_Info *MBoot); +//tPAddr MM_AllocPhys(void); +//tPAddr MM_AllocPhysRange(int Pages, int MaxBits); +//void MM_RefPhys(tPAddr PAddr); +//void MM_DerefPhys(tPAddr PAddr); +// int MM_GetRefCount(tPAddr PAddr); // === GLOBALS === tMutex glPhysAlloc; @@ -131,16 +133,64 @@ void MM_Install(tMBoot_Info *MBoot) tPAddr MM_AllocPhys(void) { // int a, b, c; - int indx; + int indx = -1; tPAddr ret; ENTER(""); Mutex_Acquire( &glPhysAlloc ); + // Classful scan + #if 1 + { + const int addrClasses[] = {0,16,20,24,32,64}; + const int numAddrClasses = sizeof(addrClasses)/sizeof(addrClasses[0]); + int i; + int first, last; + for( i = numAddrClasses; i -- > 1; ) + { +// Log("Scanning %i (%i bits)", i, addrClasses[i]); + first = 1 << (addrClasses[i-1] - 12); + last = (1 << (addrClasses[i] - 12)) - 1; + // Range is above the last free page + if( first > giLastPossibleFree ) + continue; + // Last possible free page is in the range + if( last > giLastPossibleFree ) + last = giLastPossibleFree; + +// Log(" first=%i,max=%i", first, last); + // Scan the range + for( indx = first; indx < last; ) + { +// Log("indx = %i (< %i?)", indx, last); + if( gaSuperBitmap[indx>>10] == -1 ) { + indx += 1024; + continue; + } + + if( gaPageBitmap[indx>>5] == -1 ) { + indx += 32; + continue; + } + + if( gaPageBitmap[indx>>5] & (1 << (indx&31)) ) { + indx ++; + continue; + } + break; + } + if( indx < last ) break; + + giLastPossibleFree = first; // Well, we couldn't find any in this range + } + // Out of memory? + if( i <= 1 ) indx = -1; +// Log("indx = %i", indx); + } + #elif 0 // Find free page // Scan downwards - #if 1 LOG("giLastPossibleFree = %i", giLastPossibleFree); for( indx = giLastPossibleFree; indx >= 0; ) { @@ -160,6 +210,8 @@ tPAddr MM_AllocPhys(void) } break; } + if( indx >= 0 ) + giLastPossibleFree = indx; LOG("indx = %i", indx); #else c = giLastPossibleFree % 32; @@ -179,6 +231,8 @@ tPAddr MM_AllocPhys(void) for( ; gaPageBitmap[a*32+b] & (1<= 0 ) + giLastPossibleFree = indx; #endif if( indx < 0 ) { @@ -194,6 +248,13 @@ tPAddr MM_AllocPhys(void) Panic("The fuck? Too many pages! (indx = 0x%x)", indx); } + if( indx >= giPageCount ) { + Mutex_Release( &glPhysAlloc ); + Log_Error("PMem", "MM_AllocPhys - indx(%i) > giPageCount(%i)", indx, giPageCount); + LEAVE('i', 0); + return 0; + } + // Mark page used if(gaPageReferences) gaPageReferences[ indx ] = 1; @@ -203,11 +264,11 @@ tPAddr MM_AllocPhys(void) // Get address ret = indx << 12; - giLastPossibleFree = indx; // Mark used block - if(gaPageBitmap[ indx>>5 ] == -1) + if(gaPageBitmap[ indx>>5 ] == -1) { gaSuperBitmap[indx>>10] |= 1 << ((indx>>5)&31); + } // Release Spinlock Mutex_Release( &glPhysAlloc ); @@ -429,14 +490,14 @@ void MM_DerefPhys(tPAddr PAddr) /** * \fn int MM_GetRefCount(tPAddr Addr) */ -int MM_GetRefCount(tPAddr Addr) +int MM_GetRefCount(tPAddr PAddr) { // Get page number - Addr >>= 12; + PAddr >>= 12; // We don't care about non-ram pages - if(Addr >= giPageCount) return -1; + if(PAddr >= giPageCount) return -1; // Check if it is freed - return gaPageReferences[ Addr ]; + return gaPageReferences[ PAddr ]; }