[ros-diffs] [arty] 29410: Added to trunk.

arty at svn.reactos.org arty at svn.reactos.org
Sat Oct 6 10:34:34 CEST 2007


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=29410&view=auto
==============================================================================
    (empty)

Added: trunk/reactos/lib/ppcmmu/ldscript
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/ppcmmu/ldscript?rev=29410&view=auto
==============================================================================
--- 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=29410&view=auto
==============================================================================
--- 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 at ha\n\t"
+	"addi 7,7,oldstack at 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 at ha\n\t"
+	"addi 7,7,oldstack at 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 at ha\n\t"
+	"addi 5,5,data_miss_finish_start at l\n\t"
+	"mtlr 5\n\t"
+	"lis 5,_mmumain at ha\n\t"
+	"addi 5,5,_mmumain at 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=29410&view=auto
==============================================================================
--- 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=29410&view=auto
==============================================================================
--- 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=29410&view=auto
==============================================================================
--- 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=29410&view=auto
==============================================================================
--- 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?rev=29410&view=auto
==============================================================================
--- 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>




More information about the Ros-diffs mailing list