X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Farm7%2Fmm_virt.c;h=7abf4e74e0ed196d4f48b50a535132ce5162295e;hb=bc55dc5d60469521269a41928d3d15809e2c8134;hp=7b11237b3bc2b2608d7aa0073b5279f1c7dcc98a;hpb=ada42e7583b4fa07b30d5c1a3e813c9754ec5e0f;p=tpg%2Facess2.git diff --git a/Kernel/arch/arm7/mm_virt.c b/Kernel/arch/arm7/mm_virt.c index 7b11237b..7abf4e74 100644 --- a/Kernel/arch/arm7/mm_virt.c +++ b/Kernel/arch/arm7/mm_virt.c @@ -4,6 +4,7 @@ * ARM7 Virtual Memory Manager * - arch/arm7/mm_virt.c */ +#define DEBUG 0 #include #include #include @@ -13,6 +14,9 @@ #define AP_RW_BOTH 0x3 #define AP_RO_BOTH 0x6 +// === IMPORTS === +extern Uint32 kernel_table0[]; + // === TYPES === typedef struct { @@ -25,6 +29,10 @@ 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); @@ -42,7 +50,7 @@ int MM_InitialiseVirtual(void) void MM_int_GetTables(tVAddr VAddr, Uint32 **Table0, Uint32 **Table1) { if(VAddr & 0x80000000) { - *Table0 = (void*)MM_TABLE0KERN; // Level 0 + *Table0 = (void*)&kernel_table0; // Level 0 *Table1 = (void*)MM_TABLE1KERN; // Level 1 } else { @@ -56,17 +64,28 @@ 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 - desc = &table0[VAddr>>20]; + 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; } @@ -74,6 +93,7 @@ int MM_int_AllocateCoarse(tVAddr VAddr, int Domain) if( !paddr ) { // Error + LEAVE('i', 2); return 2; } @@ -82,8 +102,12 @@ int MM_int_AllocateCoarse(tVAddr VAddr, int Domain) desc[2] = desc[0] + 0x800; desc[3] = desc[0] + 0xC00; - table1[(VAddr>>20)*256] = paddr | 3; + FRACTAL(table1, VAddr) = paddr | 3; + + // TLBIALL + TLBIALL(); + LEAVE('i', 0); return 0; } @@ -92,25 +116,31 @@ 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 ) { 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; } @@ -120,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 { @@ -128,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))) ) @@ -140,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 @@ -148,14 +182,20 @@ 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; @@ -164,11 +204,15 @@ int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi) 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 @@ -184,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 @@ -203,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; @@ -241,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) @@ -300,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; }