Kernel/arm7 - Fiddling on process switching
[tpg/acess2.git] / Kernel / arch / arm7 / mm_virt.c
index 78f05c6..7abf4e7 100644 (file)
@@ -4,14 +4,19 @@
  * ARM7 Virtual Memory Manager
  * - arch/arm7/mm_virt.c
  */
+#define DEBUG  0
 #include <acess.h>
 #include <mm_virt.h>
+#include <hal_proc.h>
 
 #define AP_KRW_ONLY    0x1
 #define AP_KRO_ONLY    0x5
 #define AP_RW_BOTH     0x3
 #define AP_RO_BOTH     0x6
 
+// === IMPORTS ===
+extern Uint32  kernel_table0[];
+
 // === TYPES ===
 typedef struct
 {
@@ -24,7 +29,13 @@ typedef struct
         int    AP;
 } tMM_PageInfo;
 
+//#define FRACTAL(table1, addr)        ((table1)[ (0xFF8/4*1024) + ((addr)>>20)])
+#define FRACTAL(table1, addr)  ((table1)[ (0xFF8/4*1024) + ((addr)>>22)])
+#define TLBIALL()      __asm__ __volatile__ ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0))
+
 // === PROTOTYPES ===
+void   MM_int_GetTables(tVAddr VAddr, Uint32 **Table0, Uint32 **Table1);
+ int   MM_int_AllocateCoarse(tVAddr VAddr, int Domain);
  int   MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi);
  int   MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi);
 
@@ -36,42 +47,100 @@ int MM_InitialiseVirtual(void)
        return 0;
 }
 
-int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
+void MM_int_GetTables(tVAddr VAddr, Uint32 **Table0, Uint32 **Table1)
+{
+       if(VAddr & 0x80000000) {
+               *Table0 = (void*)&kernel_table0;        // Level 0
+               *Table1 = (void*)MM_TABLE1KERN; // Level 1
+       }
+       else {
+               *Table0 = (void*)MM_TABLE0USER;
+               *Table1 = (void*)MM_TABLE1USER;
+       }
+}
+
+int MM_int_AllocateCoarse(tVAddr VAddr, int Domain)
 {
        Uint32  *table0, *table1;
        Uint32  *desc;
+       tPAddr  paddr;
+       
+       ENTER("xVAddr iDomain", VAddr, Domain);
+
+       MM_int_GetTables(VAddr, &table0, &table1);
+
+       VAddr &= ~(0x400000-1); // 4MiB per "block", 1 Page
 
-       if(VAddr & 0x80000000 ) {
-               table0 = (void*)MM_TABLE0KERN;  // Level 0
-               table1 = (void*)MM_TABLE1KERN;  // Level 1
+       desc = &table0[ VAddr>>20];
+       LOG("desc = %p", desc);
+       
+       // table0: 4 bytes = 1 MiB
+
+       LOG("desc[0] = %x", desc[0]);
+       LOG("desc[1] = %x", desc[1]);
+       LOG("desc[2] = %x", desc[2]);
+       LOG("desc[3] = %x", desc[3]);
+
+       if( (desc[0] & 3) != 0 || (desc[1] & 3) != 0
+        || (desc[2] & 3) != 0 || (desc[3] & 3) != 0 )
+       {
+               // Error?
+               LEAVE('i', 1);
+               return 1;
        }
-       else {
-               table0 = (void*)MM_TABLE0USER;
-               table1 = (void*)MM_TABLE1USER;
+
+       paddr = MM_AllocPhys();
+       if( !paddr )
+       {
+               // Error
+               LEAVE('i', 2);
+               return 2;
        }
-       VAddr &= 0x7FFFFFFF;
+       
+       *desc = paddr | (Domain << 5) | 1;
+       desc[1] = desc[0] + 0x400;
+       desc[2] = desc[0] + 0x800;
+       desc[3] = desc[0] + 0xC00;
+
+       FRACTAL(table1, VAddr) = paddr | 3;
+
+       // TLBIALL 
+       TLBIALL();      
+
+       LEAVE('i', 0);
+       return 0;
+}      
+
+int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
+{
+       Uint32  *table0, *table1;
+       Uint32  *desc;
+
+       ENTER("pVADdr ppi", VAddr, pi);
+
+       MM_int_GetTables(VAddr, &table0, &table1);
 
        desc = &table0[ VAddr >> 20 ];
+       LOG("desc = %p", desc);
 
        switch(pi->Size)
        {
        case 12:        // Small Page
        case 16:        // Large Page
+               LOG("Page");
                if( (*desc & 3) == 0 ) {
-                       if( pi->PhysAddr == 0 ) return 0;
-                       // Allocate
-                       *desc = MM_AllocPhys();
-                       *desc |= pi->Domain << 5;
-                       *desc |= 1;
+                       MM_int_AllocateCoarse( VAddr, pi->Domain );
                }
                desc = &table1[ VAddr >> 12 ];
+               LOG("desc (2) = %p", desc);
                if( pi->Size == 12 )
                {
                        // Small page
                        // - Error if overwriting a large page
-                       if( (*desc & 3) == 1 )  return 1;
+                       if( (*desc & 3) == 1 )  LEAVE_RET('i', 1);
                        if( pi->PhysAddr == 0 ) {
                                *desc = 0;
+                               LEAVE('i', 0);
                                return 0;
                        }
 
@@ -81,6 +150,8 @@ int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
                        if( pi->bShared)        *desc |= 1 << 10;       // S
                        *desc |= (pi->AP & 3) << 4;     // AP
                        *desc |= ((pi->AP >> 2) & 1) << 9;      // APX
+                       LEAVE('i', 0);
+                       return 0;
                }
                else
                {
@@ -89,11 +160,12 @@ int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
                }
                break;
        case 20:        // Section or unmapped
-               Log_Warning("MM", "TODO: Implement sections");
+               Warning("TODO: Implement sections");
                break;
        case 24:        // Supersection
                // Error if not aligned
                if( VAddr & 0xFFFFFF ) {
+                       LEAVE('i', 1);
                        return 1;
                }
                if( (*desc & 3) == 0 || ((*desc & 3) == 2 && (*desc & (1 << 18)))  )
@@ -101,6 +173,7 @@ int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
                        if( pi->PhysAddr == 0 ) {
                                *desc = 0;
                                // TODO: Apply to all entries
+                               LEAVE('i', 0);
                                return 0;
                        }
                        // Apply
@@ -109,35 +182,37 @@ int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
 //                     *desc |= ((pi->PhysAddr >> 36) & 0x7) << 5;
                        *desc |= 2 | (1 << 18);
                        // TODO: Apply to all entries
+                       LEAVE('i', 0);
                        return 0;
                }
+               // TODO: What here?
+               LEAVE('i', 1);
                return 1;
        }
 
+       LEAVE('i', 1);
        return 1;
 }
 
+extern tShortSpinlock  glDebug_Lock;
+
 int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
 {
        Uint32  *table0, *table1;
        Uint32  desc;
-
-       if(VAddr & 0x80000000 ) {
-               table0 = (void*)MM_TABLE0KERN;  // Level 0
-               table1 = (void*)MM_TABLE1KERN;  // Level 1
-       }
-       else {
-               table0 = (void*)MM_TABLE0USER;
-               table1 = (void*)MM_TABLE1USER;
-       }
-       VAddr &= 0x7FFFFFFF;
+       
+       MM_int_GetTables(VAddr, &table0, &table1);
 
        desc = table0[ VAddr >> 20 ];
+
+//     if( VAddr > 0x90000000)
+//             LOG("table0 desc(%p) = %x", &table0[ VAddr >> 20 ], desc);
        
        pi->bExecutable = 1;
        pi->bGlobal = 0;
        pi->bShared = 0;
 
+
        switch( (desc & 3) )
        {
        // 0: Unmapped
@@ -153,6 +228,7 @@ int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
                pi->Domain = (desc >> 5) & 7;
                // Get next level
                desc = table1[ VAddr >> 12 ];
+//             LOG("table1 desc(%p) = %x", &table1[ VAddr >> 12 ], desc);
                switch( desc & 3 )
                {
                // 0: Unmapped
@@ -172,7 +248,7 @@ int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
                        pi->bExecutable = desc & 1;
                        pi->bGlobal = !(desc >> 11);
                        pi->bShared = (desc >> 10) & 1;
-                       return 1;
+                       return 0;
                }
                return 1;
        
@@ -210,7 +286,7 @@ tPAddr MM_GetPhysAddr(tVAddr VAddr)
        tMM_PageInfo    pi;
        if( MM_int_GetPageInfo(VAddr, &pi) )
                return 0;
-       return pi.PhysAddr;
+       return pi.PhysAddr | (VAddr & ((1 << pi.Size)-1));
 }
 
 Uint MM_GetFlags(tVAddr VAddr)
@@ -269,16 +345,20 @@ int MM_Map(tVAddr VAddr, tPAddr PAddr)
 tPAddr MM_Allocate(tVAddr VAddr)
 {
        tMM_PageInfo    pi = {0};
+       
+       ENTER("pVAddr", VAddr);
 
        pi.PhysAddr = MM_AllocPhys();
-       if( pi.PhysAddr == 0 )  return 0;
+       if( pi.PhysAddr == 0 )  LEAVE_RET('i', 0);
        pi.Size = 12;
        pi.AP = AP_KRW_ONLY;    // Kernel Read/Write
        pi.bExecutable = 1;
        if( MM_int_SetPageInfo(VAddr, &pi) ) {
                MM_DerefPhys(pi.PhysAddr);
+               LEAVE('i', 0);
                return 0;
        }
+       LEAVE('x', pi.PhysAddr);
        return pi.PhysAddr;
 }
 
@@ -296,3 +376,26 @@ void MM_Deallocate(tVAddr VAddr)
        pi.bExecutable = 0;
        MM_int_SetPageInfo(VAddr, &pi);
 }
+
+tPAddr MM_ClearUser(void)
+{
+       // TODO: Implement ClearUser
+       return 0;
+}
+
+tVAddr MM_MapTemp(tPAddr PAddr)
+{
+       // TODO: Implement MapTemp
+       return 0;
+}
+
+void MM_FreeTemp(tVAddr VAddr)
+{
+       // TODO: Implement FreeTemp
+}
+
+void MM_DumpTables(tVAddr Start, tVAddr End)
+{
+       
+}
+

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