#include <mboot.h>
#include <mm_virt.h>
-#define USE_STACK 1
+//#define USE_STACK 1
+#define TRACE_ALLOCS 0 // Print trace messages on AllocPhys/DerefPhys
#define REFERENCE_BASE 0xE0400000
void MM_DerefPhys(tPAddr PAddr);
// === GLOBALS ===
+tMutex glPhysAlloc;
Uint64 giPhysAlloc = 0; // Number of allocated pages
Uint64 giPageCount = 0; // Total number of pages
Uint64 giLastPossibleFree = 0; // Last possible free page (before all pages are used)
ENTER("");
- LOCK( &giPhysAlloc );
+ Mutex_Acquire( &glPhysAlloc );
// Find free page
// Scan downwards
indx -= 1024;
continue;
}
+
if( gaPageBitmap[indx>>5] == -1 ) {
indx -= 32;
continue;
LOG("a=%i,b=%i,c=%i", a, b, c);
for( ; gaSuperBitmap[a] == -1 && a >= 0; a-- );
if(a < 0) {
- RELEASE( &giPhysAlloc );
- Warning("MM_AllocPhys - OUT OF MEMORY (Called by %p)", __builtin_return_address(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;
}
indx = (a << 10) | (b << 5) | c;
#endif
+ if( indx < 0 ) {
+ Mutex_Release( &glPhysAlloc );
+ Warning("MM_AllocPhys - OUT OF MEMORY (Called by %p) - %lli/%lli used (indx = %x)",
+ __builtin_return_address(0), giPhysAlloc, giPageCount, indx);
+ Log_Debug("PMem", "giLastPossibleFree = %lli", giLastPossibleFree);
+ LEAVE('i', 0);
+ return 0;
+ }
+
+ if( indx > 0xFFFFF ) {
+ Panic("The fuck? Too many pages! (indx = 0x%x)", indx);
+ }
+
// Mark page used
if(gaPageReferences)
gaPageReferences[ indx ] = 1;
gaPageBitmap[ indx>>5 ] |= 1 << (indx&31);
+ giPhysAlloc ++;
// Get address
ret = indx << 12;
gaSuperBitmap[indx>>10] |= 1 << ((indx>>5)&31);
// Release Spinlock
- RELEASE( &giPhysAlloc );
+ Mutex_Release( &glPhysAlloc );
LEAVE('X', ret);
- //Log("MM_AllocPhys: RETURN 0x%x", ret);
+ #if TRACE_ALLOCS
+ Log_Debug("PMem", "MM_AllocPhys: RETURN 0x%llx (%i free)", ret, giPageCount-giPhysAlloc);
+ #endif
return ret;
}
if(MaxBits > PHYS_BITS) MaxBits = PHYS_BITS;
// Lock
- LOCK( &giPhysAlloc );
+ Mutex_Acquire( &glPhysAlloc );
// Set up search state
if( giLastPossibleFree > ((tPAddr)1 << (MaxBits-12)) ) {
// Find free page
for( ; gaSuperBitmap[a] == -1 && a --; ) b = 31;
if(a < 0) {
- RELEASE( &giPhysAlloc );
+ Mutex_Release( &glPhysAlloc );
Warning("MM_AllocPhysRange - OUT OF MEMORY (Called by %p)", __builtin_return_address(0));
LEAVE('i', 0);
return 0;
// Check if an address was found
if( idx < 0 ) {
- RELEASE( &giPhysAlloc );
+ Mutex_Release( &glPhysAlloc );
Warning("MM_AllocPhysRange - OUT OF MEMORY (Called by %p)", __builtin_return_address(0));
LEAVE('i', 0);
return 0;
gaPageReferences[idx*32+sidx] = 1;
gaPageBitmap[ idx ] |= 1 << sidx;
sidx ++;
+ giPhysAlloc ++;
if(sidx == 32) { sidx = 0; idx ++; }
}
if(gaPageBitmap[ idx ] == -1) gaSuperBitmap[idx/32] |= 1 << (idx%32);
// Release Spinlock
- RELEASE( &giPhysAlloc );
+ Mutex_Release( &glPhysAlloc );
LEAVE('X', ret);
+ #if TRACE_ALLOCS
+ Log_Debug("PMem", "MM_AllocPhysRange: RETURN 0x%llx-0x%llx (%i free)",
+ ret, ret + (1<<Pages)-1, giPageCount-giPhysAlloc);
+ #endif
return ret;
}
if(PAddr >= giPageCount) return;
// Lock Structures
- LOCK( &giPhysAlloc );
+ Mutex_Acquire( &glPhysAlloc );
// Reference the page
if(gaPageReferences)
gaSuperBitmap[PAddr/1024] |= 1 << ((PAddr/32)&31);
// Release Spinlock
- RELEASE( &giPhysAlloc );
+ Mutex_Release( &glPhysAlloc );
}
/**
}
// Lock Structures
- LOCK( &giPhysAlloc );
+ Mutex_Acquire( &glPhysAlloc );
if( giLastPossibleFree < PAddr )
giLastPossibleFree = PAddr;
// Mark as free in bitmaps
if( gaPageReferences[ PAddr ] == 0 )
{
+ #if TRACE_ALLOCS
+ Log_Debug("PMem", "MM_DerefPhys: Free'd 0x%x (%i free)", PAddr, giPageCount-giPhysAlloc);
+ #endif
//LOG("Freed 0x%x by %p\n", PAddr<<12, __builtin_return_address(0));
+ giPhysAlloc --;
gaPageBitmap[ PAddr / 32 ] &= ~(1 << (PAddr&31));
if(gaPageReferences[ PAddr ] == 0)
gaSuperBitmap[ PAddr >> 10 ] &= ~(1 << ((PAddr >> 5)&31));
}
// Release spinlock
- RELEASE( &giPhysAlloc );
+ Mutex_Release( &glPhysAlloc );
}
/**