// === PROTOTYPES ===
void MM_InitPhys_Multiboot(tMBoot_Info *MBoot);
-tPAddr MM_AllocPhysRange(int Num, int Bits);
-tPAddr MM_AllocPhys(void);
-void MM_RefPhys(tPAddr PAddr);
-void MM_DerefPhys(tPAddr PAddr);
+//tPAddr MM_AllocPhysRange(int Num, int Bits);
+//tPAddr MM_AllocPhys(void);
+//void MM_RefPhys(tPAddr PAddr);
+//void MM_DerefPhys(tPAddr PAddr);
int MM_int_GetRangeID( tPAddr Addr );
// === GLOBALS ===
tMutex glPhysicalPages;
-Uint64 *gaSuperBitmap = (void*)MM_PAGE_SUPBMP; // 1 bit = 64 Pages, 16 MiB Per Word
+Uint64 *gaSuperBitmap = (void*)MM_PAGE_SUPBMP; // 1 bit = 64 Pages, 16 MiB per Word
Uint64 *gaMainBitmap = (void*)MM_PAGE_BITMAP; // 1 bit = 1 Page, 256 KiB per Word
Uint64 *gaMultiBitmap = (void*)MM_PAGE_DBLBMP; // Each bit means that the page is being used multiple times
Uint32 *gaiPageReferences = (void*)MM_PAGE_COUNTS; // Reference Counts
+void **gapPageNodes = (void*)MM_PAGE_NODES; // Reference Counts
tPAddr giFirstFreePage; // First possibly free page
Uint64 giPhysRangeFree[NUM_MM_PHYS_RANGES]; // Number of free pages in each range
Uint64 giPhysRangeFirst[NUM_MM_PHYS_RANGES]; // First free page in each range
if(base & 63) {
Uint64 val = -1LL << (base & 63);
gaSuperBitmap[base / 64] &= ~val;
- size -= (base & 63);
- base += 64 - (base & 63);
+// size -= (base & 63);
+// base += 64 - (base & 63);
}
}
{
// Oops. ok, let's do an expensive check (scan down the list
// until a free range is found)
- nFree = 1;
- addr = giPhysRangeLast[ rangeID ];
- // TODO
+// nFree = 1;
+// addr = giPhysRangeLast[ rangeID ];
+ // TODO: Expensive Check
Mutex_Release(&glPhysicalPages);
// TODO: Page out
// ATM. Just Warning
if( gaiStaticAllocPages[i] ) {
tPAddr ret = gaiStaticAllocPages[i];
gaiStaticAllocPages[i] = 0;
- Log("MM_AllocPhys: Return %x, static alloc %i", ret, i);
+ Log("MM_AllocPhys: Return %P, static alloc %i", ret, i);
return ret;
}
}
{
// Reference again
gaMultiBitmap[ page >> 6 ] |= 1LL << (page&63);
+ if( !MM_GetPhysAddr( ((tVAddr)&gaiPageReferences[ page ]) & ~0xFFF ) ) {
+ if( !MM_Allocate( ((tVAddr)&gaiPageReferences[ page ]) & ~0xFFF ) ) {
+ Log_Error("Arch", "Out of memory when allocating reference count page");
+ return ;
+ }
+ }
gaiPageReferences[ page ] ++;
}
else
}
}
+int MM_GetRefCount( tPAddr PAddr )
+{
+ PAddr >>= 12;
+
+ if( PAddr >> 12 > giMaxPhysPage ) return 0;
+
+ if( gaMultiBitmap[ PAddr >> 6 ] & (1LL << (PAddr&63)) ) {
+ return gaiPageReferences[PAddr];
+ }
+
+ if( gaMainBitmap[ PAddr >> 6 ] & (1LL << (PAddr&63)) )
+ {
+ return 1;
+ }
+ return 0;
+}
+
/**
* \brief Takes a physical address and returns the ID of its range
* \param Addr Physical address of page
else
return MM_PHYS_16BIT;
}
+
+int MM_SetPageNode(tPAddr PAddr, void *Node)
+{
+ tPAddr page = PAddr >> 12;
+ tVAddr node_page = ((tVAddr)&gapPageNodes[page]) & ~(PAGE_SIZE-1);
+
+// if( !MM_GetRefCount(PAddr) ) return 1;
+
+ if( !MM_GetPhysAddr(node_page) ) {
+ if( !MM_Allocate(node_page) )
+ return -1;
+ memset( (void*)node_page, 0, PAGE_SIZE );
+ }
+
+ gapPageNodes[page] = Node;
+ return 0;
+}
+
+int MM_GetPageNode(tPAddr PAddr, void **Node)
+{
+// if( !MM_GetRefCount(PAddr) ) return 1;
+ PAddr >>= 12;
+
+ if( !MM_GetPhysAddr( (tVAddr)&gapPageNodes[PAddr] ) ) {
+ *Node = NULL;
+ return 0;
+ }
+
+ *Node = gapPageNodes[PAddr];
+ return 0;
+}
+