Kernel/arm7 - Still working on it
[tpg/acess2.git] / Kernel / arch / arm7 / mm_virt.c
diff --git a/Kernel/arch/arm7/mm_virt.c b/Kernel/arch/arm7/mm_virt.c
new file mode 100644 (file)
index 0000000..218dc85
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Acess2
+ * 
+ * ARM7 Virtual Memory Manager
+ * - arch/arm7/mm_virt.c
+ */
+#include <mm_virt.h>
+
+// === TYPES ===
+typedef struct
+{
+       tPAddr  PhysAddr;
+       Uint8   Size;
+       Uint8   Domain;
+} tMM_PageInfo;
+
+// === GLOBALS ===
+Uint32 *gMM_KernelTable0 = (void*)MM_TABLE0KERN;
+Uint32 *gMM_KernelTable1 = (void*)MM_TABLE1KERN;
+
+// === CODE ===
+int MM_InitialiseVirtual(void)
+{
+}
+
+int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
+{
+       Uint32  *table0, table1;
+       Uint32  desc;
+
+       if(VAddr & 0x80000000 ) {
+               table0 = MM_TABLE0KERN;
+               table1 = MM_TABLE1KERN;
+       }
+       else {
+               table0 = MM_TABLE0USER;
+               table1 = MM_TABLE1USER;
+       }
+       VAddr & 0x7FFFFFFF;
+
+       desc = table0[ VAddr >> 20 ];
+
+       switch( (desc & 3) )
+       {
+       // 0: Unmapped
+       case 0:
+               pi->PhysAddr = 0;
+               pi->Size = 20;
+               pi->Domain = 0;
+               return 1;
+
+       // 1: Coarse page table
+       case 1:
+               // Domain from top level table
+               pi->Domain = (desc >> 5) & 7;
+               // Get next level
+               desc = table1[ VAddr >> 12 ];
+               switch( desc & 3 )
+               {
+               // 0: Unmapped
+               case 0: 
+                       pi->Size = 12;
+                       return 1;
+               // 1: Large Page (64KiB)
+               case 1:
+                       pi->Size = 16;
+                       pi->PhysAddr = desc & 0xFFFF0000;
+                       return 0;
+               // 2/3: Small page
+               case 2:
+               case 3:
+                       pi->Size = 12;
+                       pi->PhysAddr = desc & 0xFFFFF000;
+                       pi->bExecutable = desc & 1;
+                       pi->bGlobal = !(desc >> 11);
+                       pi->bSharec = (desc >> 10) & 1;
+                       return 1;
+               }
+               return 1;
+       
+       // 2: Section (or Supersection)
+       case 2:
+               if( desc & (1 << 18) ) {
+                       // Supersection
+                       pi->PhysAddr = desc & 0xFF000000;
+                       pi->PhysAddr |= ((desc >> 20) & 0xF) << 32;
+                       pi->PhysAddr |= ((desc >> 5) & 0x7) << 36;
+                       pi->Size = 24;
+                       pi->Domain = 0; // Superpages default to zero
+                       return 0;
+               }
+               
+               // Section
+               pi->PhysAddr = desc & 0xFFF80000;
+               pi->Size = 20;
+               pi->Domain = (desc >> 5) & 7;
+               return 0;
+
+       // 3: Reserved (invalid)
+       case 3:
+               pi->PhysAddr = 0;
+               pi->Size = 20;
+               pi->Domain = 0;
+               return 2;
+       }
+}
+
+// --- Exports ---
+tPAddr MM_GetPhysAddr(tVAddr VAddr)
+{
+       tMM_PageInfo    pi;
+       if( MM_int_GetPageInfo(VAddr, &pi) )
+               return 0;
+       return pi.PhysAddr;
+}

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