// === IMPORTS ===
extern void gKernelEnd;
+extern void Proc_PrintBacktrace(void);
// === PROTOTYPES ===
void MM_Install(tMBoot_Info *MBoot);
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 ===
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;
}
// 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 ] ++;
}
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 );
}
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;
+}
+