X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86_64%2Fmm_phys.c;h=3535fbca44a6d1643c54c95409263d970c75ee2f;hb=e7d03978fb7c0c6ab1250e56e73afba9ffb89923;hp=c64e1e03acea7dd0139a17039caac2d94324a7d4;hpb=33bcf4b3feb0e5e4548548bf3d2a50c52ffb6115;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86_64/mm_phys.c b/Kernel/arch/x86_64/mm_phys.c index c64e1e03..3535fbca 100644 --- a/Kernel/arch/x86_64/mm_phys.c +++ b/Kernel/arch/x86_64/mm_phys.c @@ -19,11 +19,13 @@ enum eMMPhys_Ranges // === GLOBALS === tSpinlock glPhysicalPages; Uint64 *gaSuperBitmap; // 1 bit = 64 Pages -Uint64 *gaPrimaryBitmap; // 1 bit = 1 Page +Uint64 *gaPrimaryBitmap; // 1 bit = 64 Pages +Uint32 *gaiPageReferences; // 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 Uint64 giPhysRangeLast[NUM_MM_PHYS_RANGES]; // Last free page in each range +Uint64 giMaxPhysPage = 0; // Maximum Physical page // === CODE === void MM_InitPhys() @@ -92,14 +94,14 @@ tPAddr MM_AllocPhysRange(int Num, int Bits) continue; } // Check page block (64 pages) - if( gaPrimaryBitmap[addr >> 6] == -1) { + if( gaSuperBitmap[addr >> (6+6)] & (1 << (addr>>6)&63)) { nFree = 0; addr += 1 << (12+6); addr &= (1 << (12+6)) - 1; continue; } // Check individual page - if( gaPrimaryBitmap[addr >> 6] & (1 << (addr&63)) ) { + if( gaiPageReferences[addr] ) { nFree = 0; addr ++; continue; @@ -134,6 +136,7 @@ tPAddr MM_AllocPhysRange(int Num, int Bits) addr -= Num; for( i = 0; i < Num; i++ ) { + gaiPageReferences[addr] = 1; gaPrimaryBitmap[addr>>6] |= 1 << (addr & 63); if( gaPrimaryBitmap[addr>>6] == -1 ) gaSuperBitmap[addr>>12] |= 1 << ((addr >> 6) & 64); @@ -158,3 +161,24 @@ tPAddr MM_AllocPhys(void) { return MM_AllocPhysRange(1, -1); } + +void MM_RefPhys(tPAddr PAddr) +{ + if( PAddr > giMaxPhysPage ) return ; + gaiPageReferences[ PAddr >> 12 ] ++; + + gaPrimaryBitmap[PAddr >> 18] |= 1 << ((PAddr>>12) & 63); + if( gaPrimaryBitmap[PAddr >> 18] == -1 ) + gaSuperBitmap[PAddr >> 24] |= 1 << ((PAddr >> 18) & 64); +} + +void MM_DerefPhys(tPAddr PAddr) +{ + if( PAddr > giMaxPhysPage ) return ; + gaiPageReferences[ PAddr >> 12 ] --; + if( gaiPageReferences[ PAddr >> 12 ] ) + { + gaPrimaryBitmap[PAddr >> 18] &= ~(1 << ((PAddr >> 12) & 63)); + gaSuperBitmap[PAddr >> 24] &= ~(1 << ((PAddr >> 18) & 64)); + } +}