#ifndef _MM_VIRT_H
#define _MM_VIRT_H
+// NOTES:
+// - 1PD is 0x400000
// - Memory Layout
#define MM_USER_MIN 0x00200000
#define USER_STACK_TOP 0x00800000
#define USER_LIB_MAX 0xBC000000
#define MM_USER_MAX 0xBC000000 // Top load address for user libraries
-#define MM_PPD_MIN 0xBC000000 // Per-Process Data
-#define MM_PPD_VFS 0xBC000000 //
-#define MM_PPD_CFG 0xBFFFF000 //
+#define MM_PPD_MIN 0xBC000000 // Per-Process Data base
+#define MM_PPD_HANDLES 0xBC000000 // - VFS Handles (Practically unlimited)
+#define MM_PPD_MMAP 0xBD000000 // - MMap Entries (24b each = 0x2AAAA max)
+#define MM_PPD_UNALLOC 0xBE000000 //
+#define MM_PPD_CFG 0xBFFFF000 // - Per-process config entries
#define MM_PPD_MAX 0xC0000000 //
#define MM_KHEAP_BASE 0xC0400000 // C+4MiB
#define MM_KUSER_CODE 0xCFFF0000 // 16 Pages
#define MM_MODULE_MIN 0xD0000000 // Lowest Module Address
#define MM_MODULE_MAX 0xE0000000 // 128 MiB
-// Needs (2^36/2^12*8 bytes)
-// - 2^27 bytes max = 128 MiB = 0x10000000
-// 2^12/2^3 items per page
-// - 2^9 = 512
-#define MM_PAGEINFO_BASE 0xE0000000
+
+// Page Info (Which VFS node owns each physical page)
+// 2^32/2^12*16
+// = 2^24 = 16 MiB = 0x4000000
+// 256 items per page
+#define MM_PAGENODE_BASE 0xE0000000
+
+// Needs (2^32/2^12*4 bytes)
+// - 2^22 bytes max = 4 MiB = 0x1000000
+// 1024 items per page
+#define MM_REFCOUNT_BASE 0xE4000000
// === FUNCTIONS ===
extern void MM_FinishVirtualInit(void);
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;
+#define REFENT_PER_PAGE (0x1000/sizeof(gaPageReferences[0]))
// === CODE ===
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");
}
}
// 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 ++;
// 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 ++;
Mutex_Acquire( &glPhysAlloc );
// Reference the page
- if( gaPageInfo )
+ if( gaPageReferences )
{
- if( MM_GetPhysAddr( (tVAddr)&gaPageInfo[PAddr] ) == 0 ) {
- tVAddr addr = ((tVAddr)&gaPageInfo[PAddr]) & ~0xFFF;
+ if( MM_GetPhysAddr( (tVAddr)&gaPageReferences[PAddr] ) == 0 ) {
+ tVAddr addr = ((tVAddr)&gaPageReferences[PAddr]) & ~0xFFF;
Log_Debug("PMem", "MM_RefPhys: Info not allocated %llx", PAddr);
Mutex_Release( &glPhysAlloc );
if( MM_Allocate( addr ) == 0 ) {
Mutex_Acquire( &glPhysAlloc );
memset( (void*)addr, 0, 0x1000 );
}
- gaPageInfo[ PAddr ].ReferenceCount ++;
+ gaPageReferences[ PAddr ] ++;
}
// Mark as used
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);
// 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)
-{
- PAddr >>= 12;
-
- // Page doesn't exist
- if( !(gaPageBitmap[PAddr / 32] & (1 << PAddr%32)) )
- return 1;
- // Allocate info block
- if( MM_GetPhysAddr( (tVAddr)&gaPageInfo[PAddr] ) == 0 )
- {
- 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");
- }
- memset( (void*)addr, 0, 0x1000);
- }
-
- gaPageInfo[ PAddr ].Node = Node;
- gaPageInfo[ PAddr ].Offset = Offset;
-
- return 0;
-}
-
-/**
- * \brief Gets the Node/Offset of a page
- */
-int MM_GetPageInfo(tPAddr PAddr, void **Node, Uint64 *Offset)
-{
- 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;
- }
-
- return 0;
-}