User/Kernel - ARMv7 fixes (relocation of .text)
[tpg/acess2.git] / KernelLand / Kernel / arch / armv7 / mm_virt.c
index 90655b6..146caea 100644 (file)
@@ -10,6 +10,7 @@
 #include <hal_proc.h>
 
 #define TRACE_MAPS     0
+#define TRACE_COW      1
 
 #define AP_KRW_ONLY    1       // Kernel page
 #define AP_KRO_ONLY    5       // Kernel RO page
 #define AP_RO_USER     2       // User RO Page
 #define PADDR_MASK_LVL1        0xFFFFFC00
 
+const char * const caAPValueNames[] = {
+       "AP_NOACCESS", "AP_KRW_ONLY",
+       "AP_RO_USER", "AP_RW_BOTH",
+       "AP_???_4", "AP_KRO_ONLY",
+       "AP_???_6", "AP_RO_BOTH"
+};
+
 // === IMPORTS ===
 extern Uint32  kernel_table0[];
 
@@ -53,7 +61,7 @@ tPAddr        MM_Clone(void);
 tVAddr MM_NewKStack(int bGlobal);
 void   MM_int_DumpTableEnt(tVAddr Start, size_t Len, tMM_PageInfo *Info);
 //void MM_DumpTables(tVAddr Start, tVAddr End);
-void   MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch);
+void   MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch, Uint32 UserLR);
 
 // === GLOBALS ===
 tPAddr giMM_ZeroPage;
@@ -320,12 +328,12 @@ int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
 }
 
 // --- Exports ---
-tPAddr MM_GetPhysAddr(tVAddr VAddr)
+tPAddr MM_GetPhysAddr(const void *Ptr)
 {
        tMM_PageInfo    pi;
-       if( MM_int_GetPageInfo(VAddr, &pi) )
+       if( MM_int_GetPageInfo((tVAddr)Ptr, &pi) )
                return 0;
-       return pi.PhysAddr | (VAddr & ((1 << pi.Size)-1));
+       return pi.PhysAddr | ((tVAddr)Ptr & ((1 << pi.Size)-1));
 }
 
 Uint MM_GetFlags(tVAddr VAddr)
@@ -535,7 +543,7 @@ void MM_int_CloneTable(Uint32 *DestEnt, int Table)
 
        cur += 256*Table;
        
-       tmp_map = (void*)MM_MapTemp(table);
+       tmp_map = MM_MapTemp(table);
        
        for( i = 0; i < 1024; i ++ )
        {
@@ -559,10 +567,10 @@ void MM_int_CloneTable(Uint32 *DestEnt, int Table)
                                tPAddr  newpage;
                                newpage = MM_AllocPhys();
                                src = (void*)( (Table*256+i)*0x1000 );
-                               dst = (void*)MM_MapTemp(newpage);
+                               dst = MM_MapTemp(newpage);
 //                             Debug("Taking a copy of kernel page %p (%P)", src, cur[i] & ~0xFFF);
                                memcpy(dst, src, PAGE_SIZE);
-                               MM_FreeTemp( (tVAddr)dst );
+                               MM_FreeTemp( dst );
                                tmp_map[i] = newpage | (cur[i] & 0xFFF);
                        }
                        else
@@ -575,7 +583,7 @@ void MM_int_CloneTable(Uint32 *DestEnt, int Table)
                        break;
                }
        }
-       MM_FreeTemp( (tVAddr) tmp_map );
+       MM_FreeTemp( tmp_map );
 
        DestEnt[0] = table + 0*0x400 + 1;
        DestEnt[1] = table + 1*0x400 + 1;
@@ -595,8 +603,8 @@ tPAddr MM_Clone(void)
        ret = MM_AllocateRootTable();
 
        cur = (void*)MM_TABLE0USER;
-       new_lvl1_1 = (void*)MM_MapTemp(ret);
-       new_lvl1_2 = (void*)MM_MapTemp(ret+0x1000);
+       new_lvl1_1 = MM_MapTemp(ret);
+       new_lvl1_2 = MM_MapTemp(ret+0x1000);
        tmp_map = new_lvl1_1;
        for( i = 0; i < 0x800-4; i ++ )
        {
@@ -626,7 +634,7 @@ tPAddr MM_Clone(void)
        {
                 int    j, num;
                tPAddr  tmp = MM_AllocPhys();
-               Uint32  *table = (void*)MM_MapTemp(tmp);
+               Uint32  *table = MM_MapTemp(tmp);
                Uint32  sp;
                register Uint32 __SP asm("sp");
 
@@ -673,16 +681,16 @@ tPAddr MM_Clone(void)
 //                     Log("page = %P", page);
                        table[j] = page | 0x813;
 
-                       tmp_page = (void*)MM_MapTemp(page);
+                       tmp_page = MM_MapTemp(page);
                        memcpy(tmp_page, (void*)sp, 0x1000);
-                       MM_FreeTemp( (tVAddr) tmp_page );
+                       MM_FreeTemp( tmp_page );
                }
 
-               MM_FreeTemp( (tVAddr)table );
+               MM_FreeTemp( table );
        }
 
-       MM_FreeTemp( (tVAddr)new_lvl1_1 );
-       MM_FreeTemp( (tVAddr)new_lvl1_2 );
+       MM_FreeTemp( new_lvl1_1 );
+       MM_FreeTemp( new_lvl1_2 );
 
 //     Log("MM_Clone: ret = %P", ret);
 
@@ -764,7 +772,7 @@ void MM_ClearUser(void)
 //     MM_DumpTables(0, 0x80000000);
 }
 
-tVAddr MM_MapTemp(tPAddr PAddr)
+void *MM_MapTemp(tPAddr PAddr)
 {
        tVAddr  ret;
        tMM_PageInfo    pi;
@@ -778,14 +786,15 @@ tVAddr MM_MapTemp(tPAddr PAddr)
                MM_RefPhys(PAddr);      // Counter the MM_Deallocate in FreeTemp
                MM_Map(ret, PAddr);
                
-               return ret;
+               return (void*)ret;
        }
        Log_Warning("MMVirt", "MM_MapTemp: All slots taken");
        return 0;
 }
 
-void MM_FreeTemp(tVAddr VAddr)
+void MM_FreeTemp(void *Ptr)
 {
+       tVAddr  VAddr = (tVAddr)Ptr;
        if( VAddr < MM_TMPMAP_BASE || VAddr >= MM_TMPMAP_END ) {
                Log_Warning("MMVirt", "MM_FreeTemp: Passed an addr not from MM_MapTemp (%p)", VAddr);
                return ;
@@ -901,7 +910,7 @@ tVAddr MM_NewUserStack(void)
        tVAddr  addr, ofs;
 
        addr = USER_STACK_TOP - USER_STACK_SIZE;
-       if( MM_GetPhysAddr(addr + PAGE_SIZE) ) {
+       if( MM_GetPhysAddr( (void*)(addr + PAGE_SIZE) ) ) {
                Log_Error("MMVirt", "Unable to create initial user stack, addr %p taken",
                        addr + PAGE_SIZE
                        );
@@ -937,18 +946,20 @@ void MM_int_DumpTableEnt(tVAddr Start, size_t Len, tMM_PageInfo *Info)
 {
        if( giMM_ZeroPage && Info->PhysAddr == giMM_ZeroPage )
        {
-               Debug("%p => %8s - 0x%7x %i %x %s",
+               Debug("%p => %8s - 0x%7x D%i %x %s %s",
                        Start, "ZERO", Len,
                        Info->Domain, Info->AP,
-                       Info->bGlobal ? "G" : "nG"
+                       Info->bExecutable ? " X" : "nX",
+                       Info->bGlobal ? " G" : "nG"
                        );
        }
        else
        {
-               Debug("%p => %8x - 0x%7x %i %x %s",
+               Debug("%p => %8x - 0x%7x D%i %x %s %s",
                        Start, Info->PhysAddr-Len, Len,
                        Info->Domain, Info->AP,
-                       Info->bGlobal ? "G" : "nG"
+                       Info->bExecutable ? " X" : "nX",
+                       Info->bGlobal ? " G" : "nG"
                        );
        }
 }
@@ -995,7 +1006,7 @@ void MM_DumpTables(tVAddr Start, tVAddr End)
 }
 
 // NOTE: Runs in abort context, not much difference, just a smaller stack
-void MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch)
+void MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch, Uint32 UserLR)
 {
         int    rv;
        tMM_PageInfo    pi;
@@ -1040,10 +1051,10 @@ void MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch)
                                Log_Error("MMVirt", "Unable to allocate new page for COW");
                                for(;;);
                        }
-                       dst = (void*)MM_MapTemp(newpage);
+                       dst = MM_MapTemp(newpage);
                        src = (void*)(Addr & ~(PAGE_SIZE-1));
                        memcpy( dst, src, PAGE_SIZE );
-                       MM_FreeTemp( (tVAddr)dst );
+                       MM_FreeTemp( dst );
                        
                        #if TRACE_COW
                        Log_Notice("MMVirt", "COW %p caused by %p, %P duped to %P (RefCnt(%i)--)", Addr, PC,
@@ -1069,6 +1080,33 @@ void MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch)
        Log_Error("MMVirt", "Code at %p accessed %p (DFSR = 0x%x)%s", PC, Addr, DFSR,
                (bPrefetch ? " - Prefetch" : "")
                );
+       Log_Error("MMVirt", "- User LR = 0x%x", UserLR);
+       const char * const dfsr_errors[] = {
+               /* 00000 */ "-", "Alignment Fault",
+               /* 00010 */ "Debug event", "Access Flag (Section)",
+               /* 00100 */ "Instr Cache Maint", "Translation (Section)",
+               /* 00110 */ "Access Flag (Page)", "Translation (Page)",
+               /* 01000 */ "Sync. External abort", "Domain (Section)",
+               /* 01010 */ "-", "Domain (Page)",
+               /* 01100 */ "Table Walk sync ext (lvl 1)", "Permission (Section)",
+               /* 01110 */ "Table Walk sync ext (lvl 2)", "Permission (Page)",
+               // 0b10000
+               /* 10000 */ "-", "-",
+               /* 10010 */ "-", "-",
+               /* 10100 */ "IMPL (Lockdown)", "-",
+               /* 10110 */ "Async. Extern. Abort", "-",
+               /* 11000 */ "Mem. access async pairity error", "Mem. access async pairity error",
+               /* 11010 */ "IMPL (Coprocessor abort)", "-",
+               /* 11100 */ "Table Walk Sync parity (lvl 1)", "-",
+               /* 11110 */ "Table Walk Sync parity (lvl 2)", "-"
+               };
+        int    errcode = (DFSR & 0xF) | (((DFSR >> 10) & 1) << 4);
+       Log_Error("MMVirt", "- Errcode 0b%05b", errcode);
+       Log_Error("MMVirt", "- Dom %i %s %s",
+               (DFSR >> 4) & 0xF, (DFSR & 0x800 ? "Write": "Read"),
+               dfsr_errors[errcode]
+               );
+       Log_Error("MMVirt", "- AP=%i(%s) %s", pi.AP, caAPValueNames[pi.AP], pi.bExecutable ? " Executable":"");
        if( Addr < 0x80000000 )
                MM_DumpTables(0, 0x80000000);
        else

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