X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Farch%2Fx86%2Fmm_phys.c;h=eb422c96cfa73a63033c3dd19dd8bc1853f1d588;hb=2cf950e5ea8ce43f45019db21b2b811cfa583e17;hp=a3318176854b68de369a9ef78b4f4143a18bfdf6;hpb=3d85d14c564e245c00d31b1adf9c4ee7c2d9754a;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/arch/x86/mm_phys.c b/KernelLand/Kernel/arch/x86/mm_phys.c index a3318176..eb422c96 100644 --- a/KernelLand/Kernel/arch/x86/mm_phys.c +++ b/KernelLand/Kernel/arch/x86/mm_phys.c @@ -7,6 +7,7 @@ #include #include #include +#include //#define USE_STACK 1 #define TRACE_ALLOCS 0 // Print trace messages on AllocPhys/DerefPhys @@ -41,11 +42,10 @@ void **gaPageNodes = (void*)MM_PAGENODE_BASE; // === CODE === void MM_Install(int NPMemRanges, tPMemMapEnt *PMemRanges) { - Uint i; Uint64 maxAddr = 0; // --- Find largest address - for( i = 0; i < NPMemRanges; i ++ ) + for( Uint i = 0; i < NPMemRanges; i ++ ) { tPMemMapEnt *ent = &PMemRanges[i]; // If entry is RAM and is above `maxAddr`, change `maxAddr` @@ -56,20 +56,33 @@ void MM_Install(int NPMemRanges, tPMemMapEnt *PMemRanges) giTotalMemorySize += ent->Length >> 12; } } + LOG("giTotalMemorySize = %lli KiB", giTotalMemorySize*4); + LOG("maxAddr = 0x%X", maxAddr); + + // Clip to 32-bits + if( maxAddr > (1ULL << 32) ) { + maxAddr = (1ULL << 32); + } giPageCount = maxAddr >> 12; giLastPossibleFree = giPageCount - 1; - memsetd(gaPageBitmap, 0xFFFFFFFF, giPageCount/32); // Set up allocateable space - for( i = 0; i < NPMemRanges; i ++ ) + for( Uint i = 0; i < NPMemRanges; i ++ ) { tPMemMapEnt *ent = &PMemRanges[i]; if( ent->Type == PMEMTYPE_FREE ) { Uint64 startpg = ent->Start / PAGE_SIZE; Uint64 pgcount = ent->Length / PAGE_SIZE; + // Ignore start addresses >32 bits + if( startpg > (1 << 20) ) + continue ; + // Clip lengths to 32-bit address space + if( startpg + pgcount > (1<<20) ) + pgcount = (1<<20) - startpg; + while( startpg % 32 && pgcount ) { gaPageBitmap[startpg/32] &= ~(1U << (startpg%32)); startpg ++; @@ -86,13 +99,14 @@ void MM_Install(int NPMemRanges, tPMemMapEnt *PMemRanges) } else if( ent->Type == PMEMTYPE_USED ) { + // TODO: Clip? giPhysAlloc += ent->Length / PAGE_SIZE; } } // Fill Superpage bitmap // - A set bit means that there are no free pages in this block of 32 - for( i = 0; i < (giPageCount+31)/32; i ++ ) + for( Uint i = 0; i < (giPageCount+31)/32; i ++ ) { if( gaPageBitmap[i] + 1 == 0 ) { gaSuperBitmap[i/32] |= (1 << i%32); @@ -101,6 +115,7 @@ void MM_Install(int NPMemRanges, tPMemMapEnt *PMemRanges) gaPageReferences = (void*)MM_REFCOUNT_BASE; + Log_Debug("PMem", "maxAddr = %P", maxAddr); Log_Log("PMem", "Physical memory set up (%lli pages of ~%lli MiB used)", giPhysAlloc, (giTotalMemorySize*PAGE_SIZE)/(1024*1024) ); @@ -152,7 +167,6 @@ void MM_DumpStatistics(void) */ tPAddr MM_AllocPhys(void) { - // int a, b, c; int indx = -1; tPAddr ret; @@ -161,7 +175,6 @@ tPAddr MM_AllocPhys(void) Mutex_Acquire( &glPhysAlloc ); // Classful scan - #if 1 { int i; int first, last; @@ -202,52 +215,6 @@ tPAddr MM_AllocPhys(void) // Out of memory? if( i <= 1 ) indx = -1; } - #elif 0 - // Find free page - // Scan downwards - LOG("giLastPossibleFree = %i", giLastPossibleFree); - for( indx = giLastPossibleFree; indx >= 0; ) - { - 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 >= 0 ) - giLastPossibleFree = indx; - LOG("indx = %i", indx); - #else - c = giLastPossibleFree % 32; - b = (giLastPossibleFree / 32) % 32; - a = giLastPossibleFree / 1024; - - LOG("a=%i,b=%i,c=%i", a, b, c); - for( ; gaSuperBitmap[a] == -1 && a >= 0; a-- ); - if(a < 0) { - Mutex_Release( &glPhysAlloc ); - Warning("MM_AllocPhys - OUT OF MEMORY (Called by %p) - %lli/%lli used", - __builtin_return_address(0), giPhysAlloc, giPageCount); - LEAVE('i', 0); - return 0; - } - for( ; gaSuperBitmap[a] & (1<= 0 ) - giLastPossibleFree = indx; - #endif if( indx < 0 ) { Mutex_Release( &glPhysAlloc ); @@ -270,7 +237,7 @@ tPAddr MM_AllocPhys(void) } // Mark page used - if( MM_GetPhysAddr( (tVAddr)&gaPageReferences[indx] ) ) + if( MM_GetPhysAddr( &gaPageReferences[indx] ) ) gaPageReferences[indx] = 1; gaPageBitmap[ indx>>5 ] |= 1 << (indx&31); @@ -286,8 +253,8 @@ tPAddr MM_AllocPhys(void) // Release Spinlock Mutex_Release( &glPhysAlloc ); - - LEAVE('X', ret); + LEAVE('P', ret); + #if TRACE_ALLOCS if( now() > 4000 ) { Log_Debug("PMem", "MM_AllocPhys: RETURN %P (%i free)", ret, giPageCount-giPhysAlloc); @@ -305,7 +272,6 @@ tPAddr MM_AllocPhys(void) */ tPAddr MM_AllocPhysRange(int Pages, int MaxBits) { - int a, b; int i, idx, sidx; tPAddr ret; @@ -330,31 +296,6 @@ tPAddr MM_AllocPhysRange(int Pages, int MaxBits) } idx = sidx / 32; sidx %= 32; - b = idx % 32; - a = idx / 32; - - #if 0 - LOG("a=%i, b=%i, idx=%i, sidx=%i", a, b, idx, sidx); - - // Find free page - for( ; gaSuperBitmap[a] == -1 && a --; ) b = 31; - if(a < 0) { - Mutex_Release( &glPhysAlloc ); - Warning("MM_AllocPhysRange - OUT OF MEMORY (Called by %p)", __builtin_return_address(0)); - LEAVE('i', 0); - return 0; - } - LOG("a = %i", a); - for( ; gaSuperBitmap[a] & (1 << b); b-- ) sidx = 31; - LOG("b = %i", b); - idx = a * 32 + b; - for( ; gaPageBitmap[idx] & (1 << sidx); sidx-- ) - LOG("gaPageBitmap[%i] = 0x%08x", idx, gaPageBitmap[idx]); - - LOG("idx = %i, sidx = %i", idx, sidx); - #else - - #endif // Check if the gap is large enough while( idx >= 0 ) @@ -406,7 +347,7 @@ tPAddr MM_AllocPhysRange(int Pages, int MaxBits) // Mark pages used for( i = 0; i < Pages; i++ ) { - if( MM_GetPhysAddr( (tVAddr)&gaPageReferences[idx*32+sidx] ) ) + if( MM_GetPhysAddr( &gaPageReferences[idx*32+sidx] ) ) gaPageReferences[idx*32+sidx] = 1; gaPageBitmap[ idx ] |= 1 << sidx; sidx ++; @@ -448,7 +389,7 @@ void MM_RefPhys(tPAddr PAddr) // Reference the page if( gaPageReferences ) { - if( MM_GetPhysAddr( (tVAddr)&gaPageReferences[PAddr] ) == 0 ) + if( MM_GetPhysAddr( &gaPageReferences[PAddr] ) == 0 ) { int i, base; tVAddr addr = ((tVAddr)&gaPageReferences[PAddr]) & ~0xFFF; @@ -510,7 +451,7 @@ void MM_DerefPhys(tPAddr PAddr) giLastPossibleFree = PAddr; // Dereference - if( !MM_GetPhysAddr( (tVAddr)&gaPageReferences[PAddr] ) || (-- gaPageReferences[PAddr]) == 0 ) + if( !MM_GetPhysAddr( &gaPageReferences[PAddr] ) || (-- gaPageReferences[PAddr]) == 0 ) { #if TRACE_ALLOCS Log_Debug("PMem", "MM_DerefPhys: Free'd %P (%i free)", PAddr<<12, giPageCount-giPhysAlloc); @@ -522,7 +463,7 @@ void MM_DerefPhys(tPAddr PAddr) if(gaPageBitmap[ PAddr / 32 ] == 0) gaSuperBitmap[ PAddr >> 10 ] &= ~(1 << ((PAddr >> 5)&31)); - if( MM_GetPhysAddr( (tVAddr) &gaPageNodes[PAddr] ) ) + if( MM_GetPhysAddr( &gaPageNodes[PAddr] ) ) { gaPageNodes[PAddr] = NULL; // TODO: Free Node Page when fully unused @@ -544,7 +485,7 @@ int MM_GetRefCount(tPAddr PAddr) // We don't care about non-ram pages if(PAddr >= giPageCount) return -1; - if( MM_GetPhysAddr( (tVAddr)&gaPageReferences[PAddr] ) == 0 ) + if( MM_GetPhysAddr( &gaPageReferences[PAddr] ) == 0 ) return (gaPageBitmap[PAddr / 32] & (1 << PAddr%32)) ? 1 : 0; // Check if it is freed @@ -562,7 +503,7 @@ int MM_SetPageNode(tPAddr PAddr, void *Node) block_addr = (tVAddr) &gaPageNodes[PAddr]; block_addr &= ~(PAGE_SIZE-1); - if( !MM_GetPhysAddr( block_addr ) ) + if( !MM_GetPhysAddr( (void*)block_addr ) ) { if( !MM_Allocate( block_addr ) ) { Log_Warning("PMem", "Unable to allocate Node page"); @@ -581,7 +522,7 @@ int MM_GetPageNode(tPAddr PAddr, void **Node) if( MM_GetRefCount(PAddr) == 0 ) return 1; PAddr /= PAGE_SIZE; - if( !MM_GetPhysAddr( (tVAddr) &gaPageNodes[PAddr] ) ) { + if( !MM_GetPhysAddr( &gaPageNodes[PAddr] ) ) { *Node = NULL; return 0; }