X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fmm_phys.c;h=81edcf2c3dbb08b6f5dfdebf197a6f7a5d374faa;hb=c5de7b08d4a82908a5acf6454fd7836bdab68715;hp=78755d9b809b588490e8346508069fe9f8b4db5f;hpb=eb98f1f2915446ef05120482a2fc353c76330b50;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/mm_phys.c b/Kernel/arch/x86/mm_phys.c index 78755d9b..81edcf2c 100644 --- a/Kernel/arch/x86/mm_phys.c +++ b/Kernel/arch/x86/mm_phys.c @@ -12,7 +12,8 @@ // === IMPORTS === -extern void gKernelEnd; +extern char gKernelEnd[]; +extern void Proc_PrintBacktrace(void); // === PROTOTYPES === void MM_Install(tMBoot_Info *MBoot); @@ -31,6 +32,7 @@ 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 int *gaPageReferences; +void **gaPageNodes = (void*)MM_PAGENODE_BASE; #define REFENT_PER_PAGE (0x1000/sizeof(gaPageReferences[0])) // === CODE === @@ -255,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; } @@ -411,15 +416,21 @@ void MM_RefPhys(tPAddr PAddr) // Reference the page if( gaPageReferences ) { - if( MM_GetPhysAddr( (tVAddr)&gaPageReferences[PAddr] ) == 0 ) { + 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); +// 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; + } } gaPageReferences[ PAddr ] ++; } @@ -463,15 +474,22 @@ void MM_DerefPhys(tPAddr PAddr) 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 ); } @@ -494,3 +512,41 @@ int MM_GetRefCount(tPAddr PAddr) return gaPageReferences[ PAddr ]; } +int MM_SetPageNode(tPAddr PAddr, void *Node) +{ + tVAddr block_addr; + + if( MM_GetRefCount(PAddr) == 0 ) return 1; + + PAddr /= PAGE_SIZE; + + block_addr = (tVAddr) &gaPageNodes[PAddr]; + block_addr &= ~(PAGE_SIZE-1); + + if( !MM_GetPhysAddr( block_addr ) ) + { + if( !MM_Allocate( block_addr ) ) { + Log_Warning("PMem", "Unable to allocate Node page"); + return -1; + } + memset( (void*)block_addr, 0, PAGE_SIZE ); + } + + gaPageNodes[PAddr] = Node; +// Log("gaPageNodes[0x%x] = %p", PAddr, Node); + return 0; +} + +int MM_GetPageNode(tPAddr PAddr, void **Node) +{ + 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; +} +