mirror of
https://github.com/reactos/reactos.git
synced 2025-05-16 15:50:24 +00:00
Added to trunk.
svn path=/trunk/; revision=29410
This commit is contained in:
parent
a21398057a
commit
289ae6c346
8 changed files with 1156 additions and 0 deletions
0
reactos/lib/ppcmmu/dummy.c
Normal file
0
reactos/lib/ppcmmu/dummy.c
Normal file
8
reactos/lib/ppcmmu/ldscript
Normal file
8
reactos/lib/ppcmmu/ldscript
Normal file
|
@ -0,0 +1,8 @@
|
|||
OUTPUT_FORMAT(elf32-powerpc);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : { *(.text) }
|
||||
.data : { *(.data) *(.rodata) }
|
||||
.bss : { *(.sbss) *(.bss) *(COMMON) }
|
||||
}
|
661
reactos/lib/ppcmmu/mmuobject.c
Normal file
661
reactos/lib/ppcmmu/mmuobject.c
Normal file
|
@ -0,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;
|
||||
}
|
17
reactos/lib/ppcmmu/mmuobject.h
Normal file
17
reactos/lib/ppcmmu/mmuobject.h
Normal file
|
@ -0,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*/
|
23
reactos/lib/ppcmmu/mmutest.c
Normal file
23
reactos/lib/ppcmmu/mmutest.c
Normal file
|
@ -0,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;
|
||||
}
|
411
reactos/lib/ppcmmu/mmuutil.c
Normal file
411
reactos/lib/ppcmmu/mmuutil.c
Normal file
|
@ -0,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);
|
||||
}
|
26
reactos/lib/ppcmmu/ppcmmu.mak
Normal file
26
reactos/lib/ppcmmu/ppcmmu.mak
Normal file
|
@ -0,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
|
10
reactos/lib/ppcmmu/ppcmmu.rbuild
Normal file
10
reactos/lib/ppcmmu/ppcmmu.rbuild
Normal file
|
@ -0,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>
|
Loading…
Reference in a new issue