#define TEMP_MAP_ADDR 0xFEFF0000 // Allows 16 "temp" pages
#define NUM_TEMP_PAGES 16
-#define USE_COW 1
-
#define PF_PRESENT 0x1
#define PF_WRITE 0x2
#define PF_USER 0x4
&& gaPageTable[Addr>>12] & PF_COW )
{
tPAddr paddr;
- paddr = MM_DuplicatePage( Addr );
- MM_DerefPhys( gaPageTable[Addr>>12] & ~0xFFF );
- gaPageTable[Addr>>12] &= PF_USER;
- gaPageTable[Addr>>12] |= paddr|PF_PRESENT|PF_WRITE;
+ if(MM_GetRefCount( gaPageTable[Addr>>12] & ~0xFFF ) == 0)
+ {
+ gaPageTable[Addr>>12] &= ~PF_COW;
+ gaPageTable[Addr>>12] |= PF_PRESENT|PF_WRITE;
+ }
+ else
+ {
+ paddr = MM_DuplicatePage( Addr );
+ MM_DerefPhys( gaPageTable[Addr>>12] & ~0xFFF );
+ gaPageTable[Addr>>12] &= PF_USER;
+ gaPageTable[Addr>>12] |= paddr|PF_PRESENT|PF_WRITE;
+ }
INVLPG( Addr & ~0xFFF );
//LEAVE('-')
return;
*/
tPAddr MM_Allocate(Uint VAddr)
{
+ tPAddr paddr;
// Check if the directory is mapped
if( gaPageDir[ VAddr >> 22 ] == 0 )
{
// Allocate directory
- gaPageDir[ VAddr >> 22 ] = MM_AllocPhys() | 3;
+ paddr = MM_AllocPhys();
+ if( paddr == 0 ) {
+ Warning("MM_Allocate - Out of Memory (Called by %p)", __builtin_return_address(0));
+ return 0;
+ }
+ // Map
+ gaPageDir[ VAddr >> 22 ] = paddr | 3;
// Mark as user
if(VAddr < MM_USER_MAX) gaPageDir[ VAddr >> 22 ] |= PF_USER;
}
// Check if the page is already allocated
else if( gaPageTable[ VAddr >> 12 ] != 0 ) {
- Warning("MM_Allocate - Allocating to used address");
+ Warning("MM_Allocate - Allocating to used address (%p)", VAddr);
return gaPageTable[ VAddr >> 12 ] & ~0xFFF;
}
// Allocate
- gaPageTable[ VAddr >> 12 ] = MM_AllocPhys() | 3;
+ paddr = MM_AllocPhys();
+ if( paddr == 0 ) {
+ Warning("MM_Allocate - Out of Memory (Called by %p)", __builtin_return_address(0));
+ return 0;
+ }
+ // Map
+ gaPageTable[ VAddr >> 12 ] = paddr | 3;
// Mark as user
if(VAddr < MM_USER_MAX) gaPageTable[ VAddr >> 12 ] |= PF_USER;
// Invalidate Cache for address
INVLPG( VAddr & ~0xFFF );
- return gaPageTable[ VAddr >> 12 ] & ~0xFFF;
+ return paddr;
}
/**
continue;
}
- #if USE_COW
// Refrence old page
MM_RefPhys( gaPageTable[i*1024+j] & ~0xFFF );
// Add to new table
}
else
gaTmpTable[i*1024+j] = gaPageTable[i*1024+j];
- LOG("gaTmpTable[0x%x] = 0x%x", i*1024+j, gaTmpTable[i*1024+j]);
- #else
- gaTmpTable[i*1024+j] = MM_DuplicatePage( (i*1024+j)<<12 ) | (gaPageTable[i*1024+j]&7);
- #endif
}
}