x86_64 starts without erroring, reaches high mem and full 64-bit
[tpg/acess2.git] / Kernel / arch / x86 / mm_virt.c
index 958b9f1..aaec06e 100644 (file)
@@ -9,9 +9,10 @@
  * 0xFE - Unused
  * 0xFF - System Calls / Kernel's User Code
  */
-#define DEBUG  1
+#define DEBUG  0
 #define SANITY 1
 #include <acess.h>
+#include <mm_virt.h>
 #include <mm_phys.h>
 #include <proc.h>
 
@@ -66,6 +67,7 @@ typedef Uint32        tTabEnt;
 #endif
 
 // === IMPORTS ===
+extern void    _UsertextEnd, _UsertextBase;
 extern Uint32  gaInitPageDir[1024];
 extern Uint32  gaInitPageTable[1024];
 extern void    Threads_SegFault(tVAddr Addr);
@@ -153,6 +155,12 @@ void MM_InstallVirtual()
                memset( &gaPageTable[i*1024], 0, 0x1000 );
        }
        #endif
+       
+       // Unset kernel on the User Text pages
+       for( i = ((tVAddr)&_UsertextEnd-(tVAddr)&_UsertextBase+0xFFF)/4096; i--; ) {
+               Log("MM_SetFlags( 0x%08x, 0, MM_PFLAG_KERNEL)", (tVAddr)&_UsertextBase + i*4096);
+               MM_SetFlags( (tVAddr)&_UsertextBase + i*4096, 0, MM_PFLAG_KERNEL );
+       }
 }
 
 /**
@@ -208,12 +216,14 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs)
                        (ErrorCode&1?"bad/locked":"non-present"),
                        (ErrorCode&16?" (Instruction Fetch)":"")
                        );
-               Warning("User Pagefault: Instruction at %p accessed %p", Regs->eip, Addr);
+               Warning("User Pagefault: Instruction at %04x:%08x accessed %p", Regs->cs, Regs->eip, Addr);
                __asm__ __volatile__ ("sti");   // Restart IRQs
                Threads_SegFault(Addr);
                return ;
        }
        
+       Debug_KernelPanic();
+       
        // -- Check Error Code --
        if(ErrorCode & 8)
                Warning("Reserved Bits Trashed!");
@@ -403,27 +413,11 @@ tPAddr MM_GetPhysAddr(tVAddr Addr)
        return (gaPageTable[Addr >> 12] & ~0xFFF) | (Addr & 0xFFF);
 }
 
-
-/**
- * \fn int MM_IsUser(tVAddr VAddr)
- * \brief Checks if a page is user accessable
- */
-int MM_IsUser(tVAddr VAddr)
-{
-       if( !(gaPageDir[VAddr >> 22] & 1) )
-               return 0;
-       if( !(gaPageTable[VAddr >> 12] & 1) )
-               return 0;
-       if( !(gaPageTable[VAddr >> 12] & PF_USER) )
-               return 0;
-       return 1;
-}
-
 /**
- * \fn void MM_SetCR3(tPAddr CR3)
+ * \fn void MM_SetCR3(Uint CR3)
  * \brief Sets the current process space
  */
-void MM_SetCR3(tPAddr CR3)
+void MM_SetCR3(Uint CR3)
 {
        __asm__ __volatile__ ("mov %0, %%cr3"::"r"(CR3));
 }
@@ -779,15 +773,25 @@ void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask)
        // Read-Only
        if( Mask & MM_PFLAG_RO )
        {
-               if( Flags & MM_PFLAG_RO )       *ent &= ~PF_WRITE;
-               else    *ent |= PF_WRITE;
+               if( Flags & MM_PFLAG_RO ) {
+                       *ent &= ~PF_WRITE;
+               }
+               else {
+                       gaPageDir[VAddr >> 22] |= PF_WRITE;
+                       *ent |= PF_WRITE;
+               }
        }
        
        // Kernel
        if( Mask & MM_PFLAG_KERNEL )
        {
-               if( Flags & MM_PFLAG_KERNEL )   *ent &= ~PF_USER;
-               else    *ent |= PF_USER;
+               if( Flags & MM_PFLAG_KERNEL ) {
+                       *ent &= ~PF_USER;
+               }
+               else {
+                       gaPageDir[VAddr >> 22] |= PF_USER;
+                       *ent |= PF_USER;
+               }
        }
        
        // Copy-On-Write
@@ -802,6 +806,33 @@ void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask)
                        *ent |= PF_WRITE;
                }
        }
+       
+       //Log("MM_SetFlags: *ent = 0x%08x, gaPageDir[%i] = 0x%08x",
+       //      *ent, VAddr >> 22, gaPageDir[VAddr >> 22]);
+}
+
+/**
+ * \brief Get the flags on a page
+ */
+Uint MM_GetFlags(tVAddr VAddr)
+{
+       tTabEnt *ent;
+       Uint    ret = 0;
+       
+       // Validity Check
+       if( !(gaPageDir[VAddr >> 22] & 1) )     return 0;
+       if( !(gaPageTable[VAddr >> 12] & 1) )   return 0;
+       
+       ent = &gaPageTable[VAddr >> 12];
+       
+       // Read-Only
+       if( !(*ent & PF_WRITE) )        ret |= MM_PFLAG_RO;
+       // Kernel
+       if( !(*ent & PF_USER) ) ret |= MM_PFLAG_KERNEL;
+       // Copy-On-Write
+       if( *ent & PF_COW )     ret |= MM_PFLAG_COW;
+       
+       return ret;
 }
 
 /**
@@ -895,10 +926,10 @@ void MM_FreeTemp(tVAddr VAddr)
 }
 
 /**
- * \fn tVAddr MM_MapHWPage(tPAddr PAddr, Uint Number)
+ * \fn tVAddr MM_MapHWPages(tPAddr PAddr, Uint Number)
  * \brief Allocates a contigous number of pages
  */
-tVAddr MM_MapHWPage(tPAddr PAddr, Uint Number)
+tVAddr MM_MapHWPages(tPAddr PAddr, Uint Number)
 {
         int    i, j;
        
@@ -962,7 +993,7 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
        {
                phys = MM_AllocPhys();
                *PhysAddr = phys;
-               ret = MM_MapHWPage(phys, 1);
+               ret = MM_MapHWPages(phys, 1);
                if(ret == 0) {
                        MM_DerefPhys(phys);
                        LEAVE('i', 0);
@@ -981,7 +1012,7 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
        }
        
        // Allocated successfully, now map
-       ret = MM_MapHWPage(phys, Pages);
+       ret = MM_MapHWPages(phys, Pages);
        if( ret == 0 ) {
                // If it didn't map, free then return 0
                for(;Pages--;phys+=0x1000)
@@ -996,23 +1027,27 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
 }
 
 /**
- * \fn void MM_UnmapHWPage(tVAddr VAddr, Uint Number)
+ * \fn void MM_UnmapHWPages(tVAddr VAddr, Uint Number)
  * \brief Unmap a hardware page
  */
-void MM_UnmapHWPage(tVAddr VAddr, Uint Number)
+void MM_UnmapHWPages(tVAddr VAddr, Uint Number)
 {
         int    i, j;
+       
+       //Log_Debug("VirtMem", "MM_UnmapHWPages: (VAddr=0x%08x, Number=%i)", VAddr, Number);
+       
        // Sanity Check
-       if(VAddr < HW_MAP_ADDR || VAddr-Number*0x1000 > HW_MAP_MAX)     return;
+       if(VAddr < HW_MAP_ADDR || VAddr+Number*0x1000 > HW_MAP_MAX)     return;
        
        i = VAddr >> 12;
        
        LOCK( &gilTempMappings );       // Temp and HW share a directory, so they share a lock
        
+       
        for( j = 0; j < Number; j++ )
        {
-               MM_DerefPhys( gaPageTable[ (HW_MAP_ADDR >> 12) + i + j ] );
-               gaPageTable[ (HW_MAP_ADDR >> 12) + i + j ] = 0;
+               MM_DerefPhys( gaPageTable[ i + j ] & ~0xFFF );
+               gaPageTable[ i + j ] = 0;
        }
        
        RELEASE( &gilTempMappings );
@@ -1022,6 +1057,6 @@ void MM_UnmapHWPage(tVAddr VAddr, Uint Number)
 EXPORT(MM_GetPhysAddr);
 EXPORT(MM_Map);
 //EXPORT(MM_Unmap);
-EXPORT(MM_MapHWPage);
+EXPORT(MM_MapHWPages);
 EXPORT(MM_AllocDMA);
-EXPORT(MM_UnmapHWPage);
+EXPORT(MM_UnmapHWPages);

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