Kernel/vfs - Fixed bug in VFS_ParsePath
[tpg/acess2.git] / Kernel / arch / x86_64 / mm_phys.c
index 670beb9..893fb5b 100644 (file)
@@ -36,6 +36,7 @@ Uint64        *gaSuperBitmap = (void*)MM_PAGE_SUPBMP; // 1 bit = 64 Pages, 16 MiB per W
 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
@@ -249,8 +250,8 @@ void MM_InitPhys_Multiboot(tMBoot_Info *MBoot)
                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);
                }
        }
        
@@ -403,9 +404,9 @@ tPAddr MM_AllocPhysRange(int Pages, int MaxBits)
        {
                // 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
@@ -460,7 +461,7 @@ tPAddr MM_AllocPhys(void)
                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;
                }
        }
@@ -481,6 +482,12 @@ void MM_RefPhys(tPAddr PAddr)
        {
                // 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
@@ -529,6 +536,23 @@ void MM_DerefPhys(tPAddr PAddr)
        }
 }
 
+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
@@ -547,3 +571,35 @@ int MM_int_GetRangeID( tPAddr Addr )
        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;
+}
+

UCC git Repository :: git.ucc.asn.au