+static int initialized = 0;
+static int paging_enb = 0;
+static unsigned long *pd;
+
+extern int _bss, _bssend, _end;
+
+static unsigned long curmapped = 0xFFFFFFFF;
+
+unsigned long v2p(void *virt)
+{
+ unsigned long _virt = (unsigned long)virt;
+
+ if (!paging_enb)
+ return _virt;
+
+ unsigned long pde = ((unsigned long *)p2v((unsigned long)pd))[PDE_FOR(_virt)];
+ unsigned long pte;
+
+ if (!(pde & PTE_PRESENT))
+ return 0xFFFFFFFF;
+
+ if (pde & PDE_PAGE_SIZE)
+ return ADDR_12_MASK(pde) + (_virt & 0x3FFFFF);
+
+ pte = ((unsigned long *)p2v(ADDR_12_MASK(pde)))[PTE_FOR(_virt)];
+ if (!(pte & PTE_PRESENT))
+ return 0xFFFFFFFF;
+ return (pte & ~0xFFF) + (_virt & 0xFFF);
+}
+
+void *p2v(unsigned long phys)
+{
+ if (!paging_enb)
+ return (void*)phys;
+
+ if (phys >= 0xA0000 && phys < 0xC0000)
+ return (void*)phys;
+ if (phys >= 0x1FF82000 && phys < 0x20000000)
+ return (void*)(phys - 0x1FF82000 + 0x200000);
+ if (phys >= 0x1FF80000 && phys < 0x1FF82000)
+ return (void*)(phys - 0x1FF80000 + 0x1F0000);
+
+ if ((phys & ~0xFFF) != curmapped) /* If it's not mapped, map it in. */
+ {
+ curmapped = phys & ~0xFFF;
+ addmap(0x4000, curmapped);
+ asm volatile("invlpg 0x4000");
+ }
+ return (void*)(0x4000 + (phys & 0xFFF));
+}
+
+int addmap(unsigned long vaddr, unsigned long paddr)
+{
+ unsigned long pde = ((unsigned long *)p2v((unsigned long)pd))[PDE_FOR(vaddr)];
+ unsigned long *pt;
+
+ if (!(pde & PTE_PRESENT))
+ return -1;
+
+ pt = (unsigned long *)p2v(ADDR_12_MASK(pde));
+ pt[PTE_FOR(vaddr)] = paddr | PTE_PRESENT | PTE_READ_WRITE;
+
+ return 0;
+}
+
+int addmap_4m(unsigned long vaddr, unsigned long paddr)
+{
+ /* PDE_PAGE_SIZE = (1 << 7) */
+ ((unsigned long *)p2v((unsigned long)pd))[PDE_FOR(vaddr)] =
+ paddr | PDE_PRESENT | PDE_READ_WRITE | PDE_PAGE_SIZE;
+
+ return 0;
+}
+
+void *demap(unsigned long client_pd, unsigned long vaddr)
+{
+ unsigned long pde = ((unsigned long *)p2v(client_pd))[PDE_FOR(vaddr)];
+ unsigned long pte;
+
+ if (!(pde & PTE_PRESENT))
+ return (void*)0x0;
+ pte = ((unsigned long *)p2v(ADDR_12_MASK(pde)))[PTE_FOR(vaddr)];
+ if (!(pte & PTE_PRESENT))
+ return (void*)0x0;
+ return p2v((pte & ~0xFFF) + (vaddr & 0xFFF));
+}
+
+static void pt_setup(int tseg_start, int tseg_size) {