Kernel - Cleaned up MM_AllocDMA/_MapHWPages/_GetPhysAddr
[tpg/acess2.git] / KernelLand / Kernel / arch / x86_64 / mm_virt.c
index 3d723e1..83e1d1f 100644 (file)
@@ -269,9 +269,9 @@ void MM_int_DumpTablesEnt(tVAddr RangeStart, size_t Length, tPAddr Expected)
        #define CANOICAL(addr)  ((addr)&0x800000000000?(addr)|0xFFFF000000000000:(addr))
        LogF("%016llx => ", CANOICAL(RangeStart));
 //     LogF("%6llx %6llx %6llx %016llx => ",
-//             MM_GetPhysAddr( (tVAddr)&PAGEDIRPTR(RangeStart>>30) ),
-//             MM_GetPhysAddr( (tVAddr)&PAGEDIR(RangeStart>>21) ),
-//             MM_GetPhysAddr( (tVAddr)&PAGETABLE(RangeStart>>12) ),
+//             MM_GetPhysAddr( &PAGEDIRPTR(RangeStart>>30) ),
+//             MM_GetPhysAddr( &PAGEDIR(RangeStart>>21) ),
+//             MM_GetPhysAddr( &PAGETABLE(RangeStart>>12) ),
 //             CANOICAL(RangeStart)
 //             );
        if( gMM_ZeroPage && (PAGETABLE(RangeStart>>12) & PADDR_MASK) == gMM_ZeroPage )
@@ -340,8 +340,8 @@ void MM_DumpTables(tVAddr Start, tVAddr End)
                                expected |= expected_pml4 & PF_NX;
                                expected |= expected_pdp  & PF_NX;
                                expected |= expected_pd   & PF_NX;
-                               Log("expected (pml4 = %x, pdp = %x, pd = %x)",
-                                       expected_pml4, expected_pdp, expected_pd);
+//                             Log("expected (pml4 = %x, pdp = %x, pd = %x)",
+//                                     expected_pml4, expected_pdp, expected_pd);
                                // Dump
                                MM_int_DumpTablesEnt( rangeStart, curPos - rangeStart, expected );
                                expected = CHANGEABLE_BITS;
@@ -576,7 +576,7 @@ void MM_Deallocate(tVAddr VAddr)
 {
        tPAddr  phys;
        
-       phys = MM_GetPhysAddr(VAddr);
+       phys = MM_GetPhysAddr( (void*)VAddr );
        if(!phys)       return ;
        
        MM_Unmap(VAddr);
@@ -609,8 +609,9 @@ int MM_GetPageEntry(tVAddr Addr, tPAddr *Phys, Uint *Flags)
 /**
  * \brief Get the physical address of a virtual location
  */
-tPAddr MM_GetPhysAddr(tVAddr Addr)
+tPAddr MM_GetPhysAddr(volatile const void *Ptr)
 {
+       tVAddr  Addr = (tVAddr)Ptr;
        tPAddr  *ptr;
         int    ret;
        
@@ -721,43 +722,73 @@ int MM_IsValidBuffer(tVAddr Addr, size_t Size)
 
        Size += Addr & (PAGE_SIZE-1);
        Addr &= ~(PAGE_SIZE-1);
-       Addr &= ((1UL << 48)-1);        // Clap to address space
+       // NC addr
+       if( ((Addr >> 47) & 1) != ((Addr>>48) == 0xFFFF))
+               return 0;
+       Addr &= ((1UL << 48)-1);        // Clamp to address space
 
        pml4 = Addr >> 39;
        pdp = Addr >> 30;
        dir = Addr >> 21;
        tab = Addr >> 12;
 
-       if( !(PAGEMAPLVL4(pml4) & 1) )  return 0;
-       if( !(PAGEDIRPTR(pdp) & 1) )    return 0;
-       if( !(PAGEDIR(dir) & 1) )       return 0;
-       if( !(PAGETABLE(tab) & 1) )     return 0;
+       if( !(PAGEMAPLVL4(pml4) & 1) ) {
+               Log_Debug("MMVirt", "PML4E %i NP", pml4);
+               return 0;
+       }
+       if( !(PAGEDIRPTR(pdp) & 1) ) {
+               Log_Debug("MMVirt", "PDPE %i NP", pdp);
+               return 0;
+       }
+       if( !(PAGEDIR(dir) & 1) ) {
+               Log_Debug("MMVirt", "PDE %i NP", dir);
+               return 0;
+       }
+       if( !(PAGETABLE(tab) & 1) ) {
+               Log_Debug("MMVirt", "PTE %i NP", tab);
+               return 0;
+       }
        
        bIsUser = !!(PAGETABLE(tab) & PF_USER);
 
        while( Size >= PAGE_SIZE )
        {
+               tab ++;
+               Size -= PAGE_SIZE;
+               
                if( (tab & 511) == 0 )
                {
                        dir ++;
-                       if( ((dir >> 9) & 511) == 0 )
+                       if( (dir & 511) == 0 )
                        {
                                pdp ++;
-                               if( ((pdp >> 18) & 511) == 0 )
+                               if( (pdp & 511) == 0 )
                                {
                                        pml4 ++;
-                                       if( !(PAGEMAPLVL4(pml4) & 1) )  return 0;
+                                       if( !(PAGEMAPLVL4(pml4) & 1) ) {
+                                               Log_Debug("MMVirt", "IsValidBuffer - PML4E %x NP, Size=%x", pml4, Size);
+                                               return 0;
+                                       }
+                               }
+                               if( !(PAGEDIRPTR(pdp) & 1) ) {
+                                       Log_Debug("MMVirt", "IsValidBuffer - PDPE %x NP", pdp);
+                                       return 0;
                                }
-                               if( !(PAGEDIRPTR(pdp) & 1) )    return 0;
                        }
-                       if( !(PAGEDIR(dir) & 1) )       return 0;
+                       if( !(PAGEDIR(dir) & 1) ) {
+                               Log_Debug("MMVirt", "IsValidBuffer - PDE %x NP", dir);
+                               return 0;
+                       }
                }
                
-               if( !(PAGETABLE(tab) & 1) )   return 0;
-               if( bIsUser && !(PAGETABLE(tab) & PF_USER) )    return 0;
-
-               tab ++;
-               Size -= PAGE_SIZE;
+               if( !(PAGETABLE(tab) & 1) ) {
+                       Log_Debug("MMVirt", "IsValidBuffer - PTE %x NP", tab);
+                       return 0;
+               }
+               if( bIsUser && !(PAGETABLE(tab) & PF_USER) ) {
+                       Log_Debug("MMVirt", "IsValidBuffer - PTE %x Not user", tab);
+                       return 0;
+               }
        }
        return 1;
 }
@@ -766,7 +797,7 @@ int MM_IsValidBuffer(tVAddr Addr, size_t Size)
 /**
  * \brief Map a range of hardware pages
  */
-tVAddr MM_MapHWPages(tPAddr PAddr, Uint Number)
+void *MM_MapHWPages(tPAddr PAddr, Uint Number)
 {
        tVAddr  ret;
         int    num;
@@ -776,7 +807,8 @@ tVAddr MM_MapHWPages(tPAddr PAddr, Uint Number)
        {
                for( num = Number; num -- && ret < MM_HWMAP_TOP; ret += 0x1000 )
                {
-                       if( MM_GetPhysAddr(ret) != 0 )  break;
+                       if( MM_GetPhysAddr( (void*)ret ) != 0 )
+                               break;
                }
                if( num >= 0 )  continue;
                
@@ -792,7 +824,7 @@ tVAddr MM_MapHWPages(tPAddr PAddr, Uint Number)
                        MM_RefPhys(PAddr);
                }
                
-               return ret;
+               return (void*)ret;
        }
        
        Log_Error("MM", "MM_MapHWPages - No space for %i pages", Number);
@@ -807,7 +839,7 @@ void MM_UnmapHWPages(tVAddr VAddr, Uint Number)
 //     Log_KernelPanic("MM", "TODO: Implement MM_UnmapHWPages");
        while( Number -- )
        {
-               MM_DerefPhys( MM_GetPhysAddr(VAddr) );
+               MM_DerefPhys( MM_GetPhysAddr((void*)VAddr) );
                MM_Unmap(VAddr);
                VAddr += 0x1000;
        }
@@ -822,10 +854,10 @@ void MM_UnmapHWPages(tVAddr VAddr, Uint Number)
  * \param PhysAddr     Pointer to the location to place the physical address allocated
  * \return Virtual address allocate
  */
-tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
+void *MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
 {
        tPAddr  phys;
-       tVAddr  ret;
+       void    *ret;
        
        // Sanity Check
        if(MaxBits < 12 || !PhysAddr)   return 0;
@@ -847,6 +879,7 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
        
        // Allocated successfully, now map
        ret = MM_MapHWPages(phys, Pages);
+       *PhysAddr = phys;
        // MapHWPages references the pages, so deref them back down to 1
        for(;Pages--;phys+=0x1000)
                MM_DerefPhys(phys);
@@ -855,7 +888,6 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
                return 0;
        }
        
-       *PhysAddr = phys;
        return ret;
 }
 
@@ -892,7 +924,7 @@ void MM_FreeTemp(void *Ptr)
 
 
 // --- Address Space Clone --
-tPAddr MM_Clone(void)
+tPAddr MM_Clone(int bNoUserCopy)
 {
        tPAddr  ret;
         int    i;
@@ -908,7 +940,7 @@ tPAddr MM_Clone(void)
        INVLPG_ALL();
        
        // #3 Set Copy-On-Write to all user pages
-       if( Threads_GetPID() != 0 )
+       if( Threads_GetPID() != 0 && !bNoUserCopy )
        {
                for( i = 0; i < 256; i ++)
                {
@@ -970,7 +1002,7 @@ tPAddr MM_Clone(void)
                MM_MapEx(kstackbase+i*0x1000, phys, 1, 0);
                
                tmpmapping = MM_MapTemp(phys);
-               if( MM_GetPhysAddr( kstackbase+i*0x1000 ) )
+               if( MM_GetPhysAddr( (void*)(kstackbase+i*0x1000) ) )
                        memcpy(tmpmapping, (void*)(kstackbase+i*0x1000), 0x1000);
                else
                        memset(tmpmapping, 0, 0x1000);
@@ -1068,8 +1100,6 @@ tVAddr MM_NewWorkerStack(void *StackData, size_t StackSize)
                tmp_addr = MM_MapTemp(phys);
                dest = (char*)tmp_addr + (0x1000 - StackSize);
                memcpy( dest, StackData, StackSize );
-               Log_Debug("MM", "MM_NewWorkerStack: %p->%p %i bytes (i=%i)", StackData, dest, StackSize, i);
-               Log_Debug("MM", "MM_NewWorkerStack: ret = %p", ret);
                MM_FreeTemp(tmp_addr);
        }
 
@@ -1088,7 +1118,7 @@ tVAddr MM_NewKStack(void)
        Uint    i;
        for( ; base < MM_KSTACK_TOP; base += KERNEL_STACK_SIZE )
        {
-               if(MM_GetPhysAddr(base+KERNEL_STACK_SIZE-0x1000) != 0)
+               if(MM_GetPhysAddr( (void*)(base+KERNEL_STACK_SIZE-0x1000) ) != 0)
                        continue;
                
                //Log("MM_NewKStack: Found one at %p", base + KERNEL_STACK_SIZE);

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