Author: arty
Date: Sat Oct 6 12:34:33 2007
New Revision: 29410
URL:
http://svn.reactos.org/svn/reactos?rev=29410&view=rev
Log:
Added to trunk.
Added:
trunk/reactos/lib/ppcmmu/
trunk/reactos/lib/ppcmmu/dummy.c
trunk/reactos/lib/ppcmmu/ldscript
trunk/reactos/lib/ppcmmu/mmuobject.c
trunk/reactos/lib/ppcmmu/mmuobject.h
trunk/reactos/lib/ppcmmu/mmutest.c
trunk/reactos/lib/ppcmmu/mmuutil.c
trunk/reactos/lib/ppcmmu/ppcmmu.mak
trunk/reactos/lib/ppcmmu/ppcmmu.rbuild
Added: trunk/reactos/lib/ppcmmu/dummy.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/ppcmmu/dummy.c?rev=294…
==============================================================================
(empty)
Added: trunk/reactos/lib/ppcmmu/ldscript
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/ppcmmu/ldscript?rev=29…
==============================================================================
--- trunk/reactos/lib/ppcmmu/ldscript (added)
+++ trunk/reactos/lib/ppcmmu/ldscript Sat Oct 6 12:34:33 2007
@@ -1,0 +1,8 @@
+OUTPUT_FORMAT(elf32-powerpc);
+
+SECTIONS
+{
+ .text : { *(.text) }
+ .data : { *(.data) *(.rodata) }
+ .bss : { *(.sbss) *(.bss) *(COMMON) }
+}
Added: trunk/reactos/lib/ppcmmu/mmuobject.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/ppcmmu/mmuobject.c?rev…
==============================================================================
--- trunk/reactos/lib/ppcmmu/mmuobject.c (added)
+++ trunk/reactos/lib/ppcmmu/mmuobject.c Sat Oct 6 12:34:33 2007
@@ -1,0 +1,661 @@
+#include <stdarg.h>
+#include "ppcmmu/mmu.h"
+#include "ppcmmu/mmuutil.h"
+#include "mmuobject.h"
+#include "helper.h"
+
+typedef unsigned long ULONG;
+
+/*
+
+The MMU Object:
+0x00300 -- Data miss
+0x00400 -- Instruction miss
+0x10000 -- Entry point
+... Code
+0x20000 -- Physical map (PTE + Process Ptr + Address : 16 bytes)
+
+4096 / 16 bytes = 256 entries per page
+256 pages = 1Megabyte = 1 page table page
+
+Setup by freeldr and used to build the kernel map, then used by the kernel
+
+Calling:
+
+r3 -- Action
+r4 .. r6 -- Args
+
+Actions:
+00 Init
+01 Map pages
+02 erase pages
+03 set segment vsid
+04 page miss callback
+05 inquire page
+06 unit test
+07 alloc page
+08 set memory size
+09 get first usable page
+10 alloc vsid
+11 revoke vsid
+*/
+
+MmuPageCallback callback;
+typedef struct _MmuFreePage {
+ int page;
+ struct _MmuFreePage *next;
+} MmuFreePage;
+typedef struct _MmuFreeTree {
+ struct _MmuFreeTree *next;
+} MmuFreeTree;
+typedef struct _MmuVsidTree {
+ ppc_map_t *leaves[256];
+} MmuVsidTree;
+typedef struct _MmuVsidInfo {
+ int vsid;
+ struct _MmuVsidInfo *next;
+ MmuVsidTree *tree[256];
+} MmuVsidInfo;
+MmuFreePage *FreeList;
+// Pages are allocated one by one until NextPage == RamSize >> PPC_PAGE_SHIFT
+// Then we take only from the free list
+int Clock = 0, TreeAlloc = 0;
+paddr_t RamSize, FirstUsablePage, NextPage;
+MmuVsidTree *NextTreePage = 0;
+MmuFreeTree *FreeTree;
+MmuVsidInfo *Segs[16], *VsidHead = 0;
+
+extern void fmtout(const char *fmt, ...);
+int ptegreload(ppc_trap_frame_t *frame, vaddr_t addr);
+
+__asm__(".text\n\t"
+ ".globl mmumain\n\t"
+ ".globl _mmumain\n\t"
+ ".globl oldstack\n\t"
+ "mmumain:\n\t"
+ "lis 7,oldstack@ha\n\t"
+ "addi 7,7,oldstack@l\n\t"
+ "mflr 0\n\t"
+ "stw 1,0(7)\n\t"
+ "lis 1,2\n\t"
+ "subi 1,1,16\n\t"
+ "stw 0,0(1)\n\t"
+ "bl _mmumain\n\t"
+ "lis 7,oldstack@ha\n\t"
+ "addi 7,7,oldstack@l\n\t"
+ "lwz 0,0(1)\n\t"
+ "lwz 1,0(7)\n\t"
+ "mtlr 0\n\t"
+ "blr\n"
+ "oldstack:\n\t"
+ ".long 0\n\t");
+
+__asm__(".text\n\t"
+ ".globl data_miss_finish_start\n"
+ "data_miss_finish_start:\n\t"
+ "lwz 2,8(1)\n\t"
+ "lwz 3,12(1)\n\t"
+ "lwz 4,16(1)\n\t"
+ "lwz 5,20(1)\n\t"
+ "lwz 6,24(1)\n\t"
+ "lwz 7,28(1)\n\t"
+ "lwz 8,32(1)\n\t"
+ "lwz 9,36(1)\n\t"
+ "lwz 10,40(1)\n\t"
+ "lwz 11,44(1)\n\t"
+ "lwz 12,48(1)\n\t"
+ "lwz 13,52(1)\n\t"
+ "lwz 14,56(1)\n\t"
+ "lwz 15,60(1)\n\t"
+ "lwz 16,64(1)\n\t"
+ "lwz 17,68(1)\n\t"
+ "lwz 18,72(1)\n\t"
+ "lwz 19,76(1)\n\t"
+ "lwz 20,80(1)\n\t"
+ "lwz 21,84(1)\n\t"
+ "lwz 22,88(1)\n\t"
+ "lwz 23,92(1)\n\t"
+ "lwz 24,96(1)\n\t"
+ "lwz 25,100(1)\n\t"
+ "lwz 26,104(1)\n\t"
+ "lwz 27,108(1)\n\t"
+ "lwz 28,112(1)\n\t"
+ "lwz 29,116(1)\n\t"
+ "lwz 30,120(1)\n\t"
+ "lwz 31,124(1)\n\t"
+ "lwz 0,128(1)\n\t"
+ "mtlr 0\n\t"
+ "lwz 0,132(1)\n\t"
+ "mtcr 0\n\t"
+ "lwz 0,136(1)\n\t"
+ "mtctr 0\n\t"
+ "lwz 0,0(1)\n\t"
+ "mfsprg1 1\n\t"
+ "rfi\n\t");
+
+/*
+ * Trap frame:
+ * r0 .. r32
+ * lr, ctr, srr0, srr1, dsisr
+ */
+__asm__(".text\n\t"
+ ".globl data_miss_start\n\t"
+ ".globl data_miss_end\n\t"
+ "data_miss_start:\n\t"
+ "mtsprg1 1\n\t"
+ "lis 1,2\n\t"
+ "subi 1,1,256\n\t"
+ "stw 0,0(1)\n\t"
+ "mfsprg1 0\n\t"
+ "stw 0,4(1)\n\t"
+ "stw 2,8(1)\n\t"
+ "stw 3,12(1)\n\t"
+ "stw 4,16(1)\n\t"
+ "stw 5,20(1)\n\t"
+ "stw 6,24(1)\n\t"
+ "stw 7,28(1)\n\t"
+ "stw 8,32(1)\n\t"
+ "stw 9,36(1)\n\t"
+ "stw 10,40(1)\n\t"
+ "stw 11,44(1)\n\t"
+ "stw 12,48(1)\n\t"
+ "stw 13,52(1)\n\t"
+ "stw 14,56(1)\n\t"
+ "stw 15,60(1)\n\t"
+ "stw 16,64(1)\n\t"
+ "stw 17,68(1)\n\t"
+ "stw 18,72(1)\n\t"
+ "stw 19,76(1)\n\t"
+ "stw 20,80(1)\n\t"
+ "stw 21,84(1)\n\t"
+ "stw 22,88(1)\n\t"
+ "stw 23,92(1)\n\t"
+ "stw 24,96(1)\n\t"
+ "stw 25,100(1)\n\t"
+ "stw 26,104(1)\n\t"
+ "stw 27,108(1)\n\t"
+ "stw 28,112(1)\n\t"
+ "stw 29,116(1)\n\t"
+ "stw 30,120(1)\n\t"
+ "stw 31,124(1)\n\t"
+ "mflr 0\n\t"
+ "stw 0,128(1)\n\t"
+ "mfcr 0\n\t"
+ "stw 0,132(1)\n\t"
+ "mfctr 0\n\t"
+ "stw 0,136(1)\n\t"
+ "mfsrr0 0\n\t"
+ "stw 0,140(1)\n\t"
+ "mfsrr1 0\n\t"
+ "stw 0,144(1)\n\t"
+ "mfdsisr 0\n\t"
+ "stw 0,148(1)\n\t"
+ "mfdar 0\n\t"
+ "stw 0,152(1)\n\t"
+ "mfxer 0\n\t"
+ "stw 0,156(1)\n\t"
+ "li 3,100\n\t"
+ "mr 4,1\n\t"
+ "lis 5,data_miss_finish_start@ha\n\t"
+ "addi 5,5,data_miss_finish_start@l\n\t"
+ "mtlr 5\n\t"
+ "lis 5,_mmumain@ha\n\t"
+ "addi 5,5,_mmumain@l\n\t"
+ "mtctr 5\n\t"
+ "bctr\n"
+ "data_miss_end:\n\t"
+ ".space 4");
+
+extern int data_miss_end, data_miss_start;
+
+int _mmumain(int action, void *arg1, void *arg2, void *arg3)
+{
+ void (*fun)(void *) = arg1;
+ ppc_trap_frame_t *trap_frame = arg1;
+ int ret = 0;
+
+ switch(action)
+ {
+ case 0:
+ initme();
+ break;
+ case 1:
+ ret = mmuaddpage(arg1, (int)arg2);
+ break;
+ case 2:
+ mmudelpage(arg1, (int)arg2);
+ break;
+ case 3:
+ mmusetvsid((int)arg1, (int)arg2, (int)arg3);
+ break;
+ case 4:
+ /* Miss callback = arg1 */
+ ret = (int)callback;
+ callback = arg1;
+ break;
+ case 5:
+ mmugetpage(arg1, (int)arg2);
+ break;
+ case 6:
+ ret = mmunitest();
+ break;
+ case 7:
+ __asm__("mfmsr 3\n\t"
+ "ori 3,3,0x30\n\t"
+ "mtmsr 3\n\t"
+ "mtsdr1 %0\n\t"
+ "mr 0,%2\n\t"
+ "mtctr 0\n\t"
+ "mr 3,%1\n\t"
+ "bctrl\n\t"
+ : : "r" (HTABORG), "r" (arg2), "r" (fun));
+ /* BYE ! */
+ break;
+ case 8:
+ mmusetramsize((paddr_t)arg1);
+ break;
+ case 9:
+ return FirstUsablePage;
+ case 10:
+ mmuallocvsid((int)arg1, (int)arg2);
+ break;
+ case 11:
+ mmufreevsid((int)arg1, (int)arg2);
+ break;
+ case 100:
+ if(!ptegreload(trap_frame, trap_frame->dar))
+ {
+ __asm__("mfmsr 3\n\tori 3,3,0x30\n\tmtmsr 3\n\t");
+ callback(0,arg1);
+ }
+ break;
+ case 101:
+ if(!ptegreload(trap_frame, trap_frame->srr0))
+ {
+ __asm__("mfmsr 3\n\tori 3,3,0x30\n\tmtmsr 3\n\t");
+ callback(1,arg1);
+ }
+ break;
+ default:
+ while(1);
+ }
+
+ return ret;
+}
+
+void outchar(char c)
+{
+ SetPhysByte(0x800003f8, c);
+}
+
+void outstr(const char *str)
+{
+ while(*str) outchar(*str);
+}
+
+void outdig(int dig)
+{
+ if(dig < 10) outchar(dig + '0');
+ else outchar(dig - 10 + 'A');
+}
+
+void outnum(unsigned long num)
+{
+ int i;
+ for( i = 0; i < 8; i++ )
+ {
+ outdig(num >> 28);
+ num <<= 4;
+ }
+}
+
+void fmtout(const char *str, ...)
+{
+ va_list ap;
+ va_start(ap, str);
+ while(*str)
+ {
+ if(*str == '%')
+ {
+ if(str[1] == '%')
+ {
+ outchar('%');
+ }
+ else if(str[1] == 's')
+ {
+ outstr(va_arg(ap, const char *));
+ }
+ else
+ {
+ outnum(va_arg(ap, int));
+ }
+ str++;
+ }
+ else
+ {
+ outchar(*str);
+ }
+ str++;
+ }
+ va_end(ap);
+}
+
+void mmusetramsize(paddr_t ramsize)
+{
+ ppc_map_t *last_map = &PpcPageTable[PPC_PAGE_NUMBER(ramsize)];
+ if(!RamSize)
+ {
+ RamSize = ramsize;
+ FirstUsablePage = (paddr_t)last_map;
+ NextPage = PPC_PAGE_NUMBER(FirstUsablePage);
+ }
+}
+
+void initme()
+{
+ int i;
+ int *target, *start;
+
+ for(i = 0; i < HTABSIZ / sizeof(int); i++)
+ {
+ ((int *)HTABORG)[i] = 0;
+ }
+
+ for(target = (int *)0x300, start = &data_miss_start; start <
&data_miss_end; start++, target++)
+ {
+ SetPhys((paddr_t)target, *start);
+ }
+
+ (&data_miss_start)[50]++;
+
+ for(target = (int *)0x400, start = &data_miss_start; start <
&data_miss_end; start++, target++)
+ {
+ SetPhys((paddr_t)target, *start);
+ }
+}
+
+ppc_map_t *allocpage()
+{
+ MmuFreePage *FreePage = 0;
+
+ if(NextPage < PPC_PAGE_NUMBER(RamSize)) {
+ return &PpcPageTable[NextPage++];
+ } else {
+ FreePage = FreeList;
+ FreeList = FreeList->next;
+ return ((ppc_map_t*)FreePage);
+ }
+}
+
+void freepage(ppc_map_t *PagePtr)
+{
+ MmuFreePage *FreePage = (MmuFreePage*)PagePtr;
+ PagePtr->proc = PagePtr->addr = 0;
+ FreePage->next = FreeList;
+ FreeList = FreePage;
+}
+
+MmuVsidTree *allocvsidtree()
+{
+ if(FreeTree)
+ {
+ MmuVsidTree *result = (MmuVsidTree*)FreeTree;
+ FreeTree = FreeTree->next;
+ return result;
+ }
+ else if(TreeAlloc >= 3 || !NextTreePage)
+ {
+ ppc_map_t *map = allocpage();
+ NextTreePage = (MmuVsidTree*)PPC_PAGE_ADDR((map - PpcPageTable));
+ TreeAlloc = 1;
+ return NextTreePage;
+ }
+ else
+ {
+ return &NextTreePage[TreeAlloc++];
+ }
+}
+
+void freevsidtree(MmuVsidTree *tree)
+{
+ int i;
+ for(i = 0; i < 256; i++)
+ if(tree->leaves[i])
+ freepage(tree->leaves[i]);
+ MmuFreeTree *NextFreeTree = (MmuFreeTree *)tree;
+ NextFreeTree->next = FreeTree;
+ FreeTree = NextFreeTree;
+}
+
+void *allocvsid(int vsid)
+{
+ ppc_map_t *map = allocpage();
+ MmuVsidInfo *info;
+ if(!map) return 0;
+ map->pte.pteh = map->pte.ptel = 0;
+ info = (MmuVsidInfo*)PPC_PAGE_ADDR((map - PpcPageTable));
+ info->vsid = vsid;
+ info->next = VsidHead;
+ VsidHead = info;
+ return info;
+}
+
+void mmuallocvsid(int vsid, int mask)
+{
+ int i;
+ for(i = 0; i < 16; i++)
+ {
+ if(mask & (1 << i))
+ allocvsid((vsid << 4) + i);
+ }
+}
+
+MmuVsidInfo *findvsid(int vsid)
+{
+ MmuVsidInfo *info;
+ for(info = VsidHead; info; info = info->next)
+ {
+ if(info->vsid == vsid) return info;
+ }
+ return 0;
+}
+
+void freevsid(int vsid)
+{
+ int i;
+ MmuVsidInfo *info = findvsid(vsid);
+ if(!info) return;
+ ppc_map_t *map = &PpcPageTable[PPC_PAGE_NUMBER((paddr_t)info)];
+ for(i = 0; i < 256; i++)
+ {
+ if(info->tree[i])
+ freevsidtree(info->tree[i]);
+ }
+ freepage(map);
+}
+
+void mmufreevsid(int vsid, int mask)
+{
+ int i;
+ for(i = 0; i < 16; i++)
+ {
+ if(mask & (1 << i))
+ allocvsid((vsid << 4) + i);
+ }
+}
+
+int mmuaddpage(ppc_map_info_t *info, int count)
+{
+ int i, iva = 0, vsid, phys, virt;
+ int ptehi;
+ int ptelo, vsid_table_hi, vsid_table_lo;
+ ppc_map_t *PagePtr;
+ MmuVsidInfo *VsidInfo;
+ MmuVsidTree *VsidTree;
+
+ for(i = 0; i < count; i++)
+ {
+ virt = info[i].addr;
+ vsid = ((info[i].addr >> 28) & 15) | (info[i].proc << 4);
+ VsidInfo = findvsid(vsid);
+
+ if(!VsidInfo) return -1;
+
+ ptehi = (1 << 31) | (vsid << 7) | ((virt >> 22) & 0x3f);
+
+ if(info[i].phys) {
+ PagePtr = &PpcPageTable[PPC_PAGE_NUMBER(info[i].phys)];
+ } else {
+ PagePtr = allocpage();
+ if(!PagePtr)
+ {
+ return 0;
+ }
+ }
+
+ phys = PPC_PAGE_ADDR((PagePtr - PpcPageTable));
+ ptelo = phys & ~PPC_PAGE_MASK;
+
+ /* Update page data */
+ PagePtr->pte.pteh = ptehi;
+ PagePtr->pte.ptel = ptelo;
+ PagePtr->proc = info[i].proc;
+ PagePtr->addr = virt;
+
+ vsid_table_hi = virt >> 20 & 255;
+ vsid_table_lo = virt >> 12 & 255;
+
+ if(!VsidInfo->tree[vsid_table_hi])
+ VsidInfo->tree[vsid_table_hi] = allocvsidtree();
+ VsidTree = VsidInfo->tree[vsid_table_hi];
+ if(!VsidTree) return 0;
+ VsidTree->leaves[vsid_table_lo] = PagePtr;
+
+ __asm__("tlbie %0\n\tsync\n\tisync" : : "r" (iva));
+ }
+ return 1;
+}
+
+ppc_pteg_t *PtegFromPage(ppc_map_t *map, int hfun)
+{
+ if(!map->proc && !map->addr) return 0;
+ return &PpcHashedPTE[PtegNumber(map->addr, hfun)];
+}
+
+int PageMatch(vaddr_t addr, ppc_pte_t pte)
+{
+ int vsid_pte = (pte.pteh >> 7) & 15, api_pte = pte.pteh & 63;
+ return
+ (((addr >> 28) & 15) == vsid_pte) &&
+ (((addr >> 22) & 63) == api_pte);
+}
+
+ppc_map_t *mmuvirtmap(vaddr_t addr, int vsid)
+{
+ int seg = (addr >> 28) & 15;
+ MmuVsidInfo *seginfo = Segs[seg];
+ MmuVsidTree *segtree = 0;
+ if(!seginfo) return 0;
+ segtree = seginfo->tree[(addr >> 20) & 255];
+ if(!segtree) return 0;
+ return segtree->leaves[(addr >> 12) & 255];
+}
+
+void mmudelpage(ppc_map_info_t *info, int count)
+{
+ int i, j, k, ipa;
+ ppc_map_t *PagePtr;
+ ppc_pteg_t *PageEntry;
+ ppc_pte_t ZeroPte = { 0 };
+
+ for(i = 0; i < count; i++)
+ {
+ if (info[i].phys)
+ {
+ ipa = info[i].phys;
+ PagePtr = &PpcPageTable[ipa];
+ info[i].proc = PagePtr->proc;
+ info[i].addr = PagePtr->addr;
+ }
+ else
+ {
+ PagePtr = mmuvirtmap(info[i].proc, info[i].addr);
+ ipa = PPC_PAGE_ADDR(PagePtr - PpcPageTable);
+ }
+
+ for(j = 0; j < 2; j++)
+ {
+ PageEntry = PtegFromPage(PagePtr, j);
+ for(k = 0; k < 8; k++)
+ {
+ if(PageMatch(ipa, PageEntry->block[k]))
+ {
+ if(PageEntry->block[k].ptel & 0x100)
+ info[i].flags |= MMU_PAGE_DIRTY;
+ PageEntry->block[k] = ZeroPte;
+ }
+ }
+ }
+ freepage(PagePtr);
+ __asm__("tlbie %0\n\tsync\n\tisync" : : "r" (info[i].addr));
+ }
+}
+
+void mmugetpage(ppc_map_info_t *info, int count)
+{
+ int i;
+ ppc_map_t *PagePtr;
+
+ for( i = 0; i < count; i++ )
+ {
+ if(!info[i].addr && !info[i].proc)
+ {
+ PagePtr = &((ppc_map_t*)PAGETAB)[info[i].phys];
+ info[i].proc = PagePtr->proc;
+ info[i].addr = PagePtr->addr;
+ info[i].flags = MMU_ALL_RW;
+ } else {
+ vaddr_t addr = info[i].addr;
+ int vsid = ((addr >> 28) & 15) | (info[i].proc << 4);
+ PagePtr = mmuvirtmap(info[i].addr, vsid);
+ if(!PagePtr)
+ info[i].phys = 0;
+ else
+ {
+ info[i].phys = PPC_PAGE_ADDR(PagePtr - PpcPageTable);
+ info[i].flags = MMU_ALL_RW; // HACK
+ }
+ }
+ }
+}
+
+void mmusetvsid(int start, int end, int vsid)
+{
+ int i, sr, s_vsid;
+ for(i = start; i < end; i++)
+ {
+ s_vsid = (vsid << 4) | (i & 15);
+ sr = (GetSR(i) & ~PPC_VSID_MASK) | s_vsid;
+ SetSR(i, sr);
+ Segs[i] = findvsid(s_vsid);
+ }
+}
+
+int ptegreload(ppc_trap_frame_t *frame, vaddr_t addr)
+{
+ int hfun = (Clock >> 3) & 1, ptegnum = PtegNumber(addr, hfun);
+ int vsid = GetSR((addr >> 28) & 15) & PPC_VSID_MASK;
+ ppc_map_t *map = mmuvirtmap(addr, vsid);
+ if(!map) return 0;
+ map->pte.pteh = (map->pte.pteh & ~64) | (hfun << 6);
+ PpcHashedPTE[ptegnum].block[Clock & 7] = map->pte;
+#if 0
+ fmtout("Reloading addr %x (phys %x) at %x[%x] (%x:%x)\r\n",
+ addr, PPC_PAGE_ADDR(map - PpcPageTable), ptegnum, Clock & 15,
+ PpcHashedPTE[ptegnum].block[Clock&7].pteh,
+ PpcHashedPTE[ptegnum].block[Clock&7].ptel);
+#endif
+ Clock++;
+ __asm__("tlbie %0\n\tsync\n\tisync" : : "r" (addr));
+ return 1;
+}
Added: trunk/reactos/lib/ppcmmu/mmuobject.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/ppcmmu/mmuobject.h?rev…
==============================================================================
--- trunk/reactos/lib/ppcmmu/mmuobject.h (added)
+++ trunk/reactos/lib/ppcmmu/mmuobject.h Sat Oct 6 12:34:33 2007
@@ -1,0 +1,17 @@
+#ifndef _LIBMMU_MMUOBJECT_H
+#define _LIBMMU_MMUOBJECT_H
+
+MmuPageCallback callback;
+void initme();
+void mmusetramsize(paddr_t size);
+int mmuaddpage(ppc_map_info_t *info, int count);
+void mmudelpage(ppc_map_info_t *info, int count);
+void mmugetpage(ppc_map_info_t *info, int count);
+void mmusetvsid(int start, int end, int vsid);
+void *allocvsid(int);
+void mmuallocvsid(int vsid, int mask);
+void freevsid(int);
+void mmufreevsid(int vsid, int mask);
+int mmunitest();
+
+#endif/*_LIBMMU_MMUOBJECT_H*/
Added: trunk/reactos/lib/ppcmmu/mmutest.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/ppcmmu/mmutest.c?rev=2…
==============================================================================
--- trunk/reactos/lib/ppcmmu/mmutest.c (added)
+++ trunk/reactos/lib/ppcmmu/mmutest.c Sat Oct 6 12:34:33 2007
@@ -1,0 +1,23 @@
+#include "ppcmmu/mmu.h"
+#include "ppcmmu/mmuutil.h"
+#include "mmuobject.h"
+
+int mmunitest()
+{
+ int ret;
+ int (*fun)(int ret) = (void *)0x80000000;
+ ppc_map_info_t info = { 0 };
+ volatile int oldmsr, msr = 0x2030;
+ __asm__("mfmsr 0\n\tstw 0,0(%0)" : : "r" (&oldmsr));
+ mmusetvsid(8, 9, 0);
+ info.flags = MMU_ALL_RW;
+ info.proc = 0;
+ info.addr = (vaddr_t)fun;
+ mmuaddpage(&info, 1);
+ __asm__("mtmsr %0" : : "r" (msr));
+ __asm__("mtsdr1 %0" : : "r" (HTABORG));
+ *((int *)fun) = 0x4e800020;
+ ret = fun(3);
+ __asm__("mtmsr %0" : : "r" (oldmsr));
+ return ret != 3;
+}
Added: trunk/reactos/lib/ppcmmu/mmuutil.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/ppcmmu/mmuutil.c?rev=2…
==============================================================================
--- trunk/reactos/lib/ppcmmu/mmuutil.c (added)
+++ trunk/reactos/lib/ppcmmu/mmuutil.c Sat Oct 6 12:34:33 2007
@@ -1,0 +1,411 @@
+#include "ppcmmu/mmu.h"
+#include "ppcmmu/mmuutil.h"
+
+inline int GetMSR() {
+ register int res asm ("r3");
+ __asm__("mfmsr 3");
+ return res;
+}
+
+inline int GetDEC() {
+ register int res asm ("r3");
+ __asm__("mfdec 3");
+ return res;
+}
+
+__asm__("\t.globl GetPhys\n"
+ "GetPhys:\t\n"
+ "mflr 0\n\t"
+ "stwu 0,-16(1)\n\t"
+ "mfmsr 5\n\t"
+ "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
+ "mtmsr 6\n\t"
+ "isync\n\t"
+ "sync\n\t"
+ "lwz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
+ "mtmsr 5\n\t"
+ "isync\n\t"
+ "sync\n\t"
+ "lwz 0,0(1)\n\t"
+ "addi 1,1,16\n\t"
+ "mtlr 0\n\t"
+ "blr"
+ );
+
+__asm__("\t.globl GetPhysHalf\n"
+ "GetPhysHalf:\t\n"
+ "mflr 0\n\t"
+ "stwu 0,-16(1)\n\t"
+ "mfmsr 5\n\t"
+ "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
+ "mtmsr 6\n\t"
+ "isync\n\t"
+ "sync\n\t"
+ "lhz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
+ "mtmsr 5\n\t"
+ "isync\n\t"
+ "sync\n\t"
+ "lwz 0,0(1)\n\t"
+ "addi 1,1,16\n\t"
+ "mtlr 0\n\t"
+ "blr"
+ );
+
+__asm__("\t.globl GetPhysByte\n"
+ "GetPhysByte:\t\n"
+ "mflr 0\n\t"
+ "stwu 0,-16(1)\n\t"
+ "mfmsr 5\n\t"
+ "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
+ "mtmsr 6\n\t"
+ "isync\n\t"
+ "sync\n\t"
+ "lbz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
+ "mtmsr 5\n\t"
+ "isync\n\t"
+ "sync\n\t"
+ "lwz 0,0(1)\n\t"
+ "addi 1,1,16\n\t"
+ "mtlr 0\n\t"
+ "blr"
+ );
+
+__asm__("\t.globl SetPhys\n"
+ "SetPhys:\t\n"
+ "mflr 0\n\t"
+ "stwu 0,-16(1)\n\t"
+ "mfmsr 5\n\t"
+ "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
+ "mtmsr 6\n\t"
+ "sync\n\t"
+ "eieio\n\t"
+ "stw 4,0(3)\n\t" /* Set actual value at phys addr r3 */
+ "dcbst 0,3\n\t"
+ "mtmsr 5\n\t"
+ "sync\n\t"
+ "eieio\n\t"
+ "mr 3,4\n\t"
+ "lwz 0,0(1)\n\t"
+ "addi 1,1,16\n\t"
+ "mtlr 0\n\t"
+ "blr"
+ );
+
+__asm__("\t.globl SetPhysHalf\n"
+ "SetPhysHalf:\t\n"
+ "mflr 0\n\t"
+ "stwu 0,-16(1)\n\t"
+ "mfmsr 5\n\t"
+ "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
+ "mtmsr 6\n\t"
+ "sync\n\t"
+ "eieio\n\t"
+ "sth 4,0(3)\n\t" /* Set actual value at phys addr r3 */
+ "dcbst 0,3\n\t"
+ "mtmsr 5\n\t"
+ "sync\n\t"
+ "eieio\n\t"
+ "mr 3,4\n\t"
+ "lwz 0,0(1)\n\t"
+ "addi 1,1,16\n\t"
+ "mtlr 0\n\t"
+ "blr"
+ );
+
+__asm__("\t.globl SetPhysByte\n"
+ "SetPhysByte:\t\n"
+ "mflr 0\n\t"
+ "stwu 0,-16(1)\n\t"
+ "mfmsr 5\n\t"
+ "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
+ "mtmsr 6\n\t"
+ "sync\n\t"
+ "eieio\n\t"
+ "stb 4,0(3)\n\t" /* Set actual value at phys addr r3 */
+ "dcbst 0,3\n\t"
+ "mtmsr 5\n\t"
+ "sync\n\t"
+ "eieio\n\t"
+ "mr 3,4\n\t"
+ "lwz 0,0(1)\n\t"
+ "addi 1,1,16\n\t"
+ "mtlr 0\n\t"
+ "blr"
+ );
+
+inline int GetSR(int n) {
+ register int res = 0;
+ switch( n ) {
+ case 0:
+ __asm__("mfsr %0,0" : "=r" (res));
+ break;
+ case 1:
+ __asm__("mfsr %0,1" : "=r" (res));
+ break;
+ case 2:
+ __asm__("mfsr %0,2" : "=r" (res));
+ break;
+ case 3:
+ __asm__("mfsr %0,3" : "=r" (res));
+ break;
+ case 4:
+ __asm__("mfsr %0,4" : "=r" (res));
+ break;
+ case 5:
+ __asm__("mfsr %0,5" : "=r" (res));
+ break;
+ case 6:
+ __asm__("mfsr %0,6" : "=r" (res));
+ break;
+ case 7:
+ __asm__("mfsr %0,7" : "=r" (res));
+ break;
+ case 8:
+ __asm__("mfsr %0,8" : "=r" (res));
+ break;
+ case 9:
+ __asm__("mfsr %0,9" : "=r" (res));
+ break;
+ case 10:
+ __asm__("mfsr %0,10" : "=r" (res));
+ break;
+ case 11:
+ __asm__("mfsr %0,11" : "=r" (res));
+ break;
+ case 12:
+ __asm__("mfsr %0,12" : "=r" (res));
+ break;
+ case 13:
+ __asm__("mfsr %0,13" : "=r" (res));
+ break;
+ case 14:
+ __asm__("mfsr %0,14" : "=r" (res));
+ break;
+ case 15:
+ __asm__("mfsr %0,15" : "=r" (res));
+ break;
+ }
+ return res;
+}
+
+inline void SetSR(int n, int val) {
+ switch( n ) {
+ case 0:
+ __asm__("mtsr 0,%0" : : "r" (val));
+ break;
+ case 1:
+ __asm__("mtsr 1,%0" : : "r" (val));
+ break;
+ case 2:
+ __asm__("mtsr 2,%0" : : "r" (val));
+ break;
+ case 3:
+ __asm__("mtsr 3,%0" : : "r" (val));
+ break;
+ case 4:
+ __asm__("mtsr 4,%0" : : "r" (val));
+ break;
+ case 5:
+ __asm__("mtsr 5,%0" : : "r" (val));
+ break;
+ case 6:
+ __asm__("mtsr 6,%0" : : "r" (val));
+ break;
+ case 7:
+ __asm__("mtsr 7,%0" : : "r" (val));
+ break;
+ case 8:
+ __asm__("mtsr 8,%0" : : "r" (val));
+ break;
+ case 9:
+ __asm__("mtsr 9,%0" : : "r" (val));
+ break;
+ case 10:
+ __asm__("mtsr 10,%0" : : "r" (val));
+ break;
+ case 11:
+ __asm__("mtsr 11,%0" : : "r" (val));
+ break;
+ case 12:
+ __asm__("mtsr 12,%0" : : "r" (val));
+ break;
+ case 13:
+ __asm__("mtsr 13,%0" : : "r" (val));
+ break;
+ case 14:
+ __asm__("mtsr 14,%0" : : "r" (val));
+ break;
+ case 15:
+ __asm__("mtsr 15,%0" : : "r" (val));
+ break;
+ }
+}
+
+void GetBat( int bat, int inst, int *batHi, int *batLo ) {
+ register int bh asm("r3"), bl asm("r4");
+ if( inst ) {
+ switch( bat ) {
+ case 0:
+ __asm__("mfibatu 3,0");
+ __asm__("mfibatl 4,0");
+ break;
+ case 1:
+ __asm__("mfibatu 3,1");
+ __asm__("mfibatl 4,1");
+ break;
+ case 2:
+ __asm__("mfibatu 3,2");
+ __asm__("mfibatl 4,2");
+ break;
+ case 3:
+ __asm__("mfibatu 3,3");
+ __asm__("mfibatl 4,3");
+ break;
+ }
+ } else {
+ switch( bat ) {
+ case 0:
+ __asm__("mfdbatu 3,0");
+ __asm__("mfdbatl 4,0");
+ break;
+ case 1:
+ __asm__("mfdbatu 3,1");
+ __asm__("mfdbatl 4,1");
+ break;
+ case 2:
+ __asm__("mfdbatu 3,2");
+ __asm__("mfdbatl 4,2");
+ break;
+ case 3:
+ __asm__("mfdbatu 3,3");
+ __asm__("mfdbatl 4,3");
+ break;
+ }
+ }
+ *batHi = bh;
+ *batLo = bl;
+}
+
+#define BATSET(n,t) \
+ case n: __asm__("mt" #t "batu " #n ",%0\n\tmt" #t
"batl " #n ",%1" \
+ : : "r" (batHi), "r" (batLo)); break;
+
+void SetBat( int bat, int inst, int batHi, int batLo ) {
+ if( inst ) {
+ switch( bat ) {
+ BATSET(0,i);
+ BATSET(1,i);
+ BATSET(2,i);
+ BATSET(3,i);
+ }
+ } else {
+ switch( bat ) {
+ BATSET(0,d);
+ BATSET(1,d);
+ BATSET(2,d);
+ BATSET(3,d);
+ }
+ }
+ __asm__("isync\n\tsync");
+}
+
+inline int GetSDR1() {
+ register int res asm("r3");
+ __asm__("mfsdr1 3");
+ return res;
+}
+
+inline void SetSDR1( int sdr ) {
+ int i,j;
+ __asm__("mtsdr1 3");
+ __asm__("sync");
+ __asm__("isync");
+
+ for( i = 0; i < 256; i++ ) {
+ j = i << 12;
+ __asm__("tlbie %0,0" : : "r" (j));
+ }
+ __asm__("eieio");
+ __asm__("tlbsync");
+ __asm__("ptesync");
+}
+
+inline int BatTranslate( int batu, int batl, int virt ) {
+ int mask;
+ if(batu & 0x3fc)
+ {
+ mask = ~(0x1ffff | ((batu & 0x3fc)>>2)<<17);
+ if((batu & 2) && ((batu & mask) == (virt & mask)))
+ return (batl & mask) | (virt & ~mask);
+ } else {
+ mask = ~(0x1ffff | (batl << 17));
+ if(!(batl & 0x40) || ((batu & mask) != (virt & mask)))
+ return (batl & mask) | (virt & ~mask);
+ }
+ return -1;
+}
+
+inline int BatHit( int batu, int batl, int virt ) {
+ return BatTranslate( batu, batl, virt ) != -1;
+}
+
+/* translate address */
+int PpcVirt2phys( vaddr_t virt, int inst ) {
+ int msr = GetMSR();
+ int txmask = inst ? 0x20 : 0x10;
+ int i, bath, batl, sr, sdr1, physbase, vahi, valo;
+ int npteg, hash, hashmask, ptehi, ptelo, ptegaddr;
+ int vsid, pteh, ptevsid, pteapi;
+
+ if( msr & txmask ) {
+ sr = GetSR( virt >> 28 );
+ vsid = sr & 0xfffffff;
+ vahi = vsid >> 4;
+ valo = (vsid << 28) | (virt & 0xfffffff);
+ if( sr & 0x80000000 ) {
+ return valo;
+ }
+
+ for( i = 0; i < 4; i++ ) {
+ GetBat( i, inst, &bath, &batl );
+ if( BatHit( bath, batl, virt ) ) {
+ return BatTranslate( bath, batl, virt );
+ }
+ }
+
+ sdr1 = GetSDR1();
+
+ physbase = sdr1 & ~0xffff;
+ hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff;
+ hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff);
+ npteg = hashmask + 1;
+
+ for( pteh = 0; pteh < 0x80; pteh += 64, hash ^= 0x7ffff ) {
+ ptegaddr = ((hashmask & hash) * 64) + physbase;
+
+ for( i = 0; i < 8; i++ ) {
+ ptehi = GetPhys( ptegaddr + (i * 8) );
+ ptelo = GetPhys( ptegaddr + (i * 8) + 4 );
+
+ ptevsid = (ptehi >> 7) & 0xffffff;
+ pteapi = ptehi & 0x3f;
+
+ if( (ptehi & 64) != pteh ) continue;
+ if( ptevsid != (vsid & 0xffffff) ) continue;
+ if( pteapi != ((virt >> 22) & 0x3f) ) continue;
+
+ return (ptelo & 0xfffff000) | (virt & 0xfff);
+ }
+ }
+ return -1;
+ } else {
+ return virt;
+ }
+}
+
+int PtegNumber(vaddr_t virt, int hfun)
+{
+ int sr = GetSR( (virt >> 28) & 0xf );
+ int vsid = sr & PPC_VSID_MASK;
+ return ((((vsid & 0x7ffff) ^ ((virt >> 12) & 0xffff)) ^ (hfun ? -1 :
0)) & ((HTABSIZ - 1) >> 3) & 0x3ff);
+}
Added: trunk/reactos/lib/ppcmmu/ppcmmu.mak
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/ppcmmu/ppcmmu.mak?rev=…
==============================================================================
--- trunk/reactos/lib/ppcmmu/ppcmmu.mak (added)
+++ trunk/reactos/lib/ppcmmu/ppcmmu.mak Sat Oct 6 12:34:33 2007
@@ -1,0 +1,26 @@
+O=$(INTERMEDIATE)/lib/ppcmmu
+S=lib/ppcmmu
+CC=powerpc-unknown-elf-gcc -I$T/include/reactos/ppcmmu
+AR=powerpc-unknown-elf-ar
+OBJCOPY=powerpc-unknown-elf-objcopy
+LDSCRIPT=-Wl,-T,$S/ldscript
+PPCMMU_TARGETS=$O/libppcmmu_code.a
+
+$O/mmuutil_object.o: $S/mmuutil.c | $O
+ $(CC) -Iinclude/reactos/libs -g -c -o $@ $S/mmuutil.c
+
+$O/libppcmmu_code.a: $O/mmuobject.o $O/mmuutil_object.o $O/mmutest.o | $O
+ $(CC) -Wl,-N -nostartfiles -nostdlib -o $O/mmuobject -Ttext=0x10000 $(LDSCRIPT)
-Wl,-u,mmumain -Wl,-u,data_miss_start -Wl,-u,data_miss_end $O/mmuobject.o
$O/mmuutil_object.o $O/mmutest.o
+ $(OBJCOPY) -O binary $O/mmuobject mmucode
+ $(OBJCOPY) -I binary -O elf32-powerpc -B powerpc:common mmucode $O/mmucode.o
+ mkdir -p `dirname $@`
+ $(AR) cr $@ $O/mmucode.o
+
+$O/mmuobject.o: $S/mmuobject.c $S/mmuobject.h | $O
+ $(CC) -Iinclude/reactos -Iinclude/reactos/libs -g -c -o $@ $S/mmuobject.c
+
+$O/mmutest.o: $S/mmutest.c $S/mmuobject.h | $O
+ $(CC) -Iinclude/reactos/libs -g -c -o $@ $S/mmutest.c
+
+ppcmmuobject_clean:
+ rm -f $O/*.o $O/*.a mmucode $O/mmuobject
Added: trunk/reactos/lib/ppcmmu/ppcmmu.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/ppcmmu/ppcmmu.rbuild?r…
==============================================================================
--- trunk/reactos/lib/ppcmmu/ppcmmu.rbuild (added)
+++ trunk/reactos/lib/ppcmmu/ppcmmu.rbuild Sat Oct 6 12:34:33 2007
@@ -1,0 +1,10 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../tools/rbuild/project.dtd">
+<module name="ppcmmu" type="staticlibrary">
+ <include base="ppcmmu">.</include>
+ <define name="__NO_CTYPE_INLINES" />
+ <if property="ARCH" value="powerpc">
+ <file>mmuutil.c</file>
+ </if>
+ <file>dummy.c</file>
+</module>