X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Farch%2Fx86%2Fmm_phys.c;h=2b2a76491f559a3011725dd015923792e7585b86;hb=479d0634670b58da044bc58149662adba0ad1d0b;hp=49d7a1a7635ff115d5eb0e498b5df7eedcf5b2c9;hpb=3878dff5a723481be5e01f24c0e1bbeee4de738c;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/arch/x86/mm_phys.c b/KernelLand/Kernel/arch/x86/mm_phys.c index 49d7a1a7..2b2a7649 100644 --- a/KernelLand/Kernel/arch/x86/mm_phys.c +++ b/KernelLand/Kernel/arch/x86/mm_phys.c @@ -4,8 +4,9 @@ */ #define DEBUG 0 #include -#include #include +#include +#include //#define USE_STACK 1 #define TRACE_ALLOCS 0 // Print trace messages on AllocPhys/DerefPhys @@ -14,11 +15,10 @@ static const int addrClasses[] = {0,16,20,24,32,64}; static const int numAddrClasses = sizeof(addrClasses)/sizeof(addrClasses[0]); // === IMPORTS === -extern char gKernelEnd[]; extern void Proc_PrintBacktrace(void); // === PROTOTYPES === -void MM_Install(tMBoot_Info *MBoot); +void MM_Install(int NPMemRanges, tPMemMapEnt *PMemRanges); //tPAddr MM_AllocPhys(void); //tPAddr MM_AllocPhysRange(int Pages, int MaxBits); //void MM_RefPhys(tPAddr PAddr); @@ -39,86 +39,71 @@ void **gaPageNodes = (void*)MM_PAGENODE_BASE; #define REFENT_PER_PAGE (0x1000/sizeof(gaPageReferences[0])) // === CODE === -void MM_Install(tMBoot_Info *MBoot) +void MM_Install(int NPMemRanges, tPMemMapEnt *PMemRanges) { - Uint kernelPages, num; Uint i; Uint64 maxAddr = 0; - tMBoot_Module *mods; - tMBoot_MMapEnt *ent; // --- Find largest address - MBoot->MMapAddr |= KERNEL_BASE; - ent = (void *)( MBoot->MMapAddr ); - while( (Uint)ent < MBoot->MMapAddr + MBoot->MMapLength ) + for( i = 0; i < NPMemRanges; i ++ ) { - // Adjust for size - ent->Size += 4; - + tPMemMapEnt *ent = &PMemRanges[i]; // If entry is RAM and is above `maxAddr`, change `maxAddr` - if(ent->Type == 1) + if(ent->Type == PMEMTYPE_FREE || ent->Type == PMEMTYPE_USED) { - if(ent->Base + ent->Length > maxAddr) - maxAddr = ent->Base + ent->Length; + if(ent->Start + ent->Length > maxAddr) + maxAddr = ent->Start + ent->Length; giTotalMemorySize += ent->Length >> 12; } - // Go to next entry - ent = (tMBoot_MMapEnt *)( (Uint)ent + ent->Size ); } - if(maxAddr == 0) { - giPageCount = (MBoot->HighMem >> 2) + 256; // HighMem is a kByte value - } - else { - giPageCount = maxAddr >> 12; - } + giPageCount = maxAddr >> 12; giLastPossibleFree = giPageCount - 1; memsetd(gaPageBitmap, 0xFFFFFFFF, giPageCount/32); // Set up allocateable space - ent = (void *)( MBoot->MMapAddr ); - while( (Uint)ent < MBoot->MMapAddr + MBoot->MMapLength ) - { - memsetd( &gaPageBitmap[ent->Base/(4096*32)], 0, ent->Length/(4096*32) ); - ent = (tMBoot_MMapEnt *)( (Uint)ent + ent->Size ); + for( 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; + while( startpg % 32 && pgcount ) { + gaPageBitmap[startpg/32] &= ~(1U << (startpg%32)); + startpg ++; + pgcount --; + } + memsetd( &gaPageBitmap[startpg/32], 0, pgcount/32 ); + startpg += pgcount - pgcount%32; + pgcount -= pgcount - pgcount%32; + while(pgcount) { + gaPageBitmap[startpg/32] &= ~(1U << (startpg%32)); + startpg ++; + pgcount --; + } + } + else if( ent->Type == PMEMTYPE_USED ) + { + giPhysAlloc += ent->Length / PAGE_SIZE; + } } - - // Get used page count (Kernel) - kernelPages = (Uint)&gKernelEnd - KERNEL_BASE - 0x100000; - kernelPages += 0xFFF; // Page Align - kernelPages >>= 12; - giPhysAlloc += kernelPages; // Add to used count - // Fill page bitmap - num = kernelPages/32; - memsetd( &gaPageBitmap[0x100000/(4096*32)], -1, num ); - gaPageBitmap[ 0x100000/(4096*32) + num ] = (1 << (kernelPages & 31)) - 1; - // Fill Superpage bitmap - num = kernelPages/(32*32); - memsetd( &gaSuperBitmap[0x100000/(4096*32*32)], -1, num ); - gaSuperBitmap[ 0x100000/(4096*32*32) + num ] = (1 << ((kernelPages / 32) & 31)) - 1; - - // Mark Multiboot's pages as taken - // - Structure - MM_RefPhys( (Uint)MBoot - KERNEL_BASE ); - // - Module List - for(i = (MBoot->ModuleCount*sizeof(tMBoot_Module)+0xFFF)>12; i--; ) - MM_RefPhys( MBoot->Modules + (i << 12) ); - // - Modules - mods = (void*)(MBoot->Modules + KERNEL_BASE); - for(i = 0; i < MBoot->ModuleCount; i++) + // - A set bit means that there are no free pages in this block of 32 + for( i = 0; i < (giPageCount+31)/32; i ++ ) { - num = (mods[i].End - mods[i].Start + 0xFFF) >> 12; - while(num--) - MM_RefPhys( (mods[i].Start & ~0xFFF) + (num<<12) ); + if( gaPageBitmap[i] + 1 == 0 ) { + gaSuperBitmap[i/32] |= (1 << i%32); + } } - + 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*4)/1024 + giPhysAlloc, (giTotalMemorySize*PAGE_SIZE)/(1024*1024) ); } @@ -168,7 +153,6 @@ void MM_DumpStatistics(void) */ tPAddr MM_AllocPhys(void) { - // int a, b, c; int indx = -1; tPAddr ret; @@ -177,7 +161,6 @@ tPAddr MM_AllocPhys(void) Mutex_Acquire( &glPhysAlloc ); // Classful scan - #if 1 { int i; int first, last; @@ -218,52 +201,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 ); @@ -286,7 +223,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); @@ -304,6 +241,8 @@ tPAddr MM_AllocPhys(void) Mutex_Release( &glPhysAlloc ); LEAVE('X', ret); + if( ret == 0x17FFE000 ) + LogF("TRIP!\n"); #if TRACE_ALLOCS if( now() > 4000 ) { Log_Debug("PMem", "MM_AllocPhys: RETURN %P (%i free)", ret, giPageCount-giPhysAlloc); @@ -321,7 +260,6 @@ tPAddr MM_AllocPhys(void) */ tPAddr MM_AllocPhysRange(int Pages, int MaxBits) { - int a, b; int i, idx, sidx; tPAddr ret; @@ -346,31 +284,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 ) @@ -422,7 +335,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 ++; @@ -464,7 +377,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; @@ -526,7 +439,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); @@ -538,7 +451,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 @@ -560,7 +473,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 @@ -578,7 +491,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"); @@ -597,7 +510,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; }