X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fmm_phys.c;h=07318362da46ea7493ab5440cb9910eaaf9f708a;hb=b68b764267d33a45539b4c910db13fbdae48f193;hp=b5031b375222bccff12592d0b25cd64397652cc9;hpb=930fe819133ddb444bc6c22df09baf788183f6ad;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/mm_phys.c b/Kernel/arch/x86/mm_phys.c index b5031b37..07318362 100644 --- a/Kernel/arch/x86/mm_phys.c +++ b/Kernel/arch/x86/mm_phys.c @@ -13,6 +13,7 @@ // === IMPORTS === extern void gKernelEnd; +extern void Proc_PrintBacktrace(void); // === PROTOTYPES === void MM_Install(tMBoot_Info *MBoot); @@ -30,12 +31,9 @@ Uint64 giLastPossibleFree = 0; // Last possible free page (before all pages are Uint32 gaSuperBitmap[1024]; // Blocks of 1024 Pages Uint32 gaPageBitmap[1024*1024/32]; // Individual pages -struct sPageInfo { - int ReferenceCount; - void *Node; - Uint64 Offset; -} *gaPageInfo; -#define INFO_PER_PAGE (0x1000/sizeof(gaPageInfo[0])) + int *gaPageReferences; +void **gaPageNodes = (void*)MM_PAGENODE_BASE; +#define REFENT_PER_PAGE (0x1000/sizeof(gaPageReferences[0])) // === CODE === void MM_Install(tMBoot_Info *MBoot) @@ -109,7 +107,7 @@ void MM_Install(tMBoot_Info *MBoot) MM_RefPhys( (mods[i].Start & ~0xFFF) + (num<<12) ); } - gaPageInfo = (void*)MM_PAGEINFO_BASE; + gaPageReferences = (void*)MM_REFCOUNT_BASE; Log_Log("PMem", "Physical memory set up"); } @@ -240,8 +238,8 @@ tPAddr MM_AllocPhys(void) } // Mark page used - if( MM_GetPhysAddr( (tVAddr)&gaPageInfo[indx] ) ) - gaPageInfo[ indx ].ReferenceCount = 1; + if( MM_GetPhysAddr( (tVAddr)&gaPageReferences[indx] ) ) + gaPageReferences[indx] = 1; gaPageBitmap[ indx>>5 ] |= 1 << (indx&31); giPhysAlloc ++; @@ -259,7 +257,10 @@ tPAddr MM_AllocPhys(void) LEAVE('X', ret); #if TRACE_ALLOCS - Log_Debug("PMem", "MM_AllocPhys: RETURN 0x%llx (%i free)", ret, giPageCount-giPhysAlloc); + if( now() > 4000 ) { + Log_Debug("PMem", "MM_AllocPhys: RETURN %P (%i free)", ret, giPageCount-giPhysAlloc); + Proc_PrintBacktrace(); + } #endif return ret; } @@ -373,8 +374,8 @@ tPAddr MM_AllocPhysRange(int Pages, int MaxBits) // Mark pages used for( i = 0; i < Pages; i++ ) { - if( MM_GetPhysAddr( (tVAddr)&gaPageInfo[idx*32+sidx] ) ) - gaPageInfo[idx*32+sidx].ReferenceCount = 1; + if( MM_GetPhysAddr( (tVAddr)&gaPageReferences[idx*32+sidx] ) ) + gaPageReferences[idx*32+sidx] = 1; gaPageBitmap[ idx ] |= 1 << sidx; sidx ++; giPhysAlloc ++; @@ -413,19 +414,25 @@ void MM_RefPhys(tPAddr PAddr) Mutex_Acquire( &glPhysAlloc ); // Reference the page - if( gaPageInfo ) + if( gaPageReferences ) { - if( MM_GetPhysAddr( (tVAddr)&gaPageInfo[PAddr] ) == 0 ) { - tVAddr addr = ((tVAddr)&gaPageInfo[PAddr]) & ~0xFFF; - Log_Debug("PMem", "MM_RefPhys: Info not allocated %llx", PAddr); + if( MM_GetPhysAddr( (tVAddr)&gaPageReferences[PAddr] ) == 0 ) + { + int i, base; + tVAddr addr = ((tVAddr)&gaPageReferences[PAddr]) & ~0xFFF; +// Log_Debug("PMem", "MM_RefPhys: Allocating info for %X", PAddr); Mutex_Release( &glPhysAlloc ); if( MM_Allocate( addr ) == 0 ) { - Log_KernelPanic("PMem", "MM_RefPhys: Out of physical memory"); + Log_KernelPanic("PMem", "MM_RefPhys: Out of physical memory allocating info for %X", PAddr*PAGE_SIZE); } Mutex_Acquire( &glPhysAlloc ); - memset( (void*)addr, 0, 0x1000 ); + + base = PAddr & ~(1024-1); + for( i = 0; i < 1024; i ++ ) { + gaPageReferences[base + i] = (gaPageBitmap[(base+i)/32] & (1 << (base+i)%32)) ? 1 : 0; + } } - gaPageInfo[ PAddr ].ReferenceCount ++; + gaPageReferences[ PAddr ] ++; } // Mark as used @@ -464,18 +471,25 @@ void MM_DerefPhys(tPAddr PAddr) giLastPossibleFree = PAddr; // Dereference - if( !MM_GetPhysAddr( (tVAddr)&gaPageInfo[PAddr] ) || (-- gaPageInfo[PAddr].ReferenceCount) == 0 ) + if( !MM_GetPhysAddr( (tVAddr)&gaPageReferences[PAddr] ) || (-- gaPageReferences[PAddr]) == 0 ) { #if TRACE_ALLOCS - Log_Debug("PMem", "MM_DerefPhys: Free'd 0x%x (%i free)", PAddr, giPageCount-giPhysAlloc); + Log_Debug("PMem", "MM_DerefPhys: Free'd %P (%i free)", PAddr<<12, giPageCount-giPhysAlloc); + Proc_PrintBacktrace(); #endif //LOG("Freed 0x%x by %p\n", PAddr<<12, __builtin_return_address(0)); giPhysAlloc --; gaPageBitmap[ PAddr / 32 ] &= ~(1 << (PAddr&31)); if(gaPageBitmap[ PAddr / 32 ] == 0) gaSuperBitmap[ PAddr >> 10 ] &= ~(1 << ((PAddr >> 5)&31)); + + if( MM_GetPhysAddr( (tVAddr) &gaPageNodes[PAddr] ) ) + { + gaPageNodes[PAddr] = NULL; + // TODO: Free Node Page when fully unused + } } - + // Release spinlock Mutex_Release( &glPhysAlloc ); } @@ -491,61 +505,48 @@ int MM_GetRefCount(tPAddr PAddr) // We don't care about non-ram pages if(PAddr >= giPageCount) return -1; - if( MM_GetPhysAddr( (tVAddr)&gaPageInfo[PAddr] ) == 0 ) + if( MM_GetPhysAddr( (tVAddr)&gaPageReferences[PAddr] ) == 0 ) return (gaPageBitmap[PAddr / 32] & (1 << PAddr%32)) ? 1 : 0; // Check if it is freed - return gaPageInfo[ PAddr ].ReferenceCount; + return gaPageReferences[ PAddr ]; } -/** - * \brief Sets the node and offset associated with a page - */ -int MM_SetPageInfo(tPAddr PAddr, void *Node, Uint64 Offset) +int MM_SetPageNode(tPAddr PAddr, void *Node) { - PAddr >>= 12; + tVAddr block_addr; + + if( MM_GetRefCount(PAddr) == 0 ) return 1; + + PAddr /= PAGE_SIZE; - // Page doesn't exist - if( !(gaPageBitmap[PAddr / 32] & (1 << PAddr%32)) ) - return 1; - // Allocate info block - if( MM_GetPhysAddr( (tVAddr)&gaPageInfo[PAddr] ) == 0 ) + block_addr = (tVAddr) &gaPageNodes[PAddr]; + block_addr &= ~(PAGE_SIZE-1); + + if( !MM_GetPhysAddr( block_addr ) ) { - tVAddr addr = ((tVAddr)&gaPageInfo[PAddr]) & ~0xFFF; - Log_Debug("PMem", "MM_SetPageInfo: Info not allocated %llx", PAddr); - if( MM_Allocate( addr ) == 0 ) { - Log_KernelPanic("PMem", "MM_SetPageInfo: Out of physical memory"); + if( !MM_Allocate( block_addr ) ) { + Log_Warning("PMem", "Unable to allocate Node page"); + return -1; } - memset( (void*)addr, 0, 0x1000); + memset( (void*)block_addr, 0, PAGE_SIZE ); } - gaPageInfo[ PAddr ].Node = Node; - gaPageInfo[ PAddr ].Offset = Offset; - + gaPageNodes[PAddr] = Node; +// Log("gaPageNodes[0x%x] = %p", PAddr, Node); return 0; } -/** - * \brief Gets the Node/Offset of a page - */ -int MM_GetPageInfo(tPAddr PAddr, void **Node, Uint64 *Offset) +int MM_GetPageNode(tPAddr PAddr, void **Node) { - PAddr >>= 12; - - // Page doesn't exist - if( !(gaPageBitmap[PAddr / 32] & (1 << PAddr%32)) ) - return 1; - // Info is zero if block is not allocated - if( MM_GetPhysAddr( (tVAddr)&gaPageInfo[PAddr] ) == 0 ) - { - if(Node) *Node = NULL; - if(Offset) *Offset = 0; - } - else - { - if(Node) *Node = gaPageInfo[ PAddr ].Node; - if(Offset) *Offset = gaPageInfo[ PAddr ].Offset; + if( MM_GetRefCount(PAddr) == 0 ) return 1; + + PAddr /= PAGE_SIZE; + if( !MM_GetPhysAddr( (tVAddr) &gaPageNodes[PAddr] ) ) { + *Node = NULL; + return 0; } - + *Node = gaPageNodes[PAddr]; return 0; } +