Page fault, system calls, context switches debugged.

Heaps, system calls, context switches all functional.

svn path=/trunk/; revision=31953
This commit is contained in:
Art Yerkes 2008-01-23 00:43:39 +00:00
parent 887d6dd76e
commit 9dc65bb296
17 changed files with 1305 additions and 1074 deletions

View file

@ -223,23 +223,8 @@ FrLdrStartup(ULONG Magic)
LdrPEFixupImports
((PVOID)reactos_modules[i].ModStart,
(PCHAR)reactos_modules[i].String);
else
{
printf("Module header for %s was [%x:%x]\n",
reactos_modules[i].String,
reactos_modules[i].ModStart,
reactos_modules[i].ModEnd);
reactos_modules[i].ModStart +=
(KernelBase & 0xffffff) - (ULONG_PTR)KernelMemory;
reactos_modules[i].ModEnd +=
(KernelBase & 0xffffff) - (ULONG_PTR)KernelMemory;
printf("Module header for %s now [%x:%x]\n",
reactos_modules[i].String,
reactos_modules[i].ModStart,
reactos_modules[i].ModEnd);
}
}
}
}
}
printf("Starting mmu\n");
@ -263,7 +248,7 @@ FrLdrStartup(ULONG Magic)
FrLdrAddPageMapping(&memmap, 1, i, 0);
}
printf("Mapping %d Heap Pages\n", i);
printf("KernelBase %x\n", KernelBase);
/* Heap pages -- this gets the entire freeldr heap */
for( i = 0; i < NumberOfEntries; i++ ) {

View file

@ -146,58 +146,63 @@ PPC_QUAL long _InterlockedXor(volatile long * const value, const long mask)
PPC_QUAL char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
{
char retval = Comperand;
volatile long retval __asm__("r8") = 0;
__asm__ __volatile__ (
"sync\n"
"1: lbarx %0,0,%1\n"
" subf. %0,%2,%0\n"
" bne 2f\n"
" stbcx. %3,0,%1\n"
"1: lbarx %0,0,%1\n"
: "=r" (retval) : "r" (Destination));
__asm__ __volatile__ (
" cmpw %3,%1\n"
" bne- 2f\n"
" stbcx. %2,0,%0\n"
" bne- 1b\n"
"2: isync"
: "=b" (retval)
: "b" (Destination), "r" (Comperand), "r" (Exchange)
: "cr0", "memory");
:
: "r" (Destination), "r" (Comperand), "r" (Exchange), "r" (retval));
return retval;
}
PPC_QUAL short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)
{
short retval = Comperand;
volatile long retval __asm__("r8") = 0;
__asm__ __volatile__ (
"sync\n"
"1: lharx %0,0,%1\n"
" subf. %0,%2,%0\n"
" bne 2f\n"
" sthcx. %3,0,%1\n"
"1: lharx %0,0,%1\n"
: "=&r" (retval) : "r" (Destination));
__asm__ __volatile__ (
" cmpw %3,%1\n"
" bne- 2f\n"
" sthcx. %2,0,%0\n"
" bne- 1b\n"
"2: isync"
: "=r" (retval)
: "r" (Destination), "r" (Comperand), "r" (Exchange)
: "memory");
:
: "r" (Destination), "r" (Comperand), "r" (Exchange), "r" (retval));
return retval;
}
PPC_QUAL long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)
{
short retval = Comperand;
volatile long retval __asm__("r8") = 0;
__asm__ __volatile__ (
"sync\n"
"1: lwarx %0,0,%1\n"
" subf. %0,%2,%0\n"
" bne 2f\n"
" stwcx. %3,0,%1\n"
"1: lwarx %0,0,%1\n"
: "=&r" (retval) : "r" (Destination));
__asm__ __volatile__ (
" cmpw %3,%1\n"
" bne- 2f\n"
" stwcx. %2,0,%0\n"
" bne- 1b\n"
"2: isync"
: "=r" (retval)
: "r" (Destination), "r" (Comperand), "r" (Exchange)
: "memory");
:
: "r" (Destination), "r" (Comperand), "r" (Exchange), "r" (retval));
return retval;
}
PPC_QUAL long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand)
PPC_QUAL long long _InterlockedCompareExchange64(volatile long long * const Target, const long long Exchange, const long long Comperand)
{
return 0;
long long capture = *Target;
if (*Target == Comperand) *Target = Exchange;
return capture;
}
PPC_QUAL void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)
@ -208,199 +213,36 @@ PPC_QUAL void * _InterlockedCompareExchangePointer(void * volatile * const Desti
PPC_QUAL long _InterlockedExchange(volatile long * const Target, const long Value)
{
long retval;
__asm__ __volatile__ (
"sync\n"
"1: lwarx %0,0,%1\n"
" stwcx. %2,0,%1\n"
" bne- 1b\n"
: "=b" (retval)
: "b" (Target), "b" (Value)
: "cr0", "memory");
return retval;
long retval __asm__("r8");
__asm__ __volatile__ (
"sync\n"
"1: lwarx 8,0,3\n"
" stwcx. 4,0,3\n"
" bne- 1b\n"
" mr 3,8\n"
: "=b" (retval)
: "b" (Target), "b" (Value)
: "cr0", "memory");
return retval;
}
PPC_QUAL void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)
{
void * retval;
__asm__ __volatile__ (
"sync\n"
"1: lwarx %0,0,%1\n"
" stwcx. %2,0,%1\n"
" bne- 1b\n"
: "=b" (retval)
: "b" (Target), "b" (Value)
: "cr0", "memory");
return retval;
return (void *)_InterlockedExchange((long *)Target, (long)Value);
}
PPC_QUAL long _InterlockedExchangeAdd(volatile long * const Addend, const long Value)
{
long x;
long y = *Addend;
long addend = y;
do
{
x = y;
y = _InterlockedCompareExchange(Addend, addend + Value, x);
}
while(y != x);
return y;
}
PPC_QUAL char _InterlockedAnd8(volatile char * const value, const char mask)
{
char x;
char y;
y = *value;
do
{
x = y;
y = _InterlockedCompareExchange8(value, x & mask, x);
}
while(y != x);
return y;
}
PPC_QUAL short _InterlockedAnd16(volatile short * const value, const short mask)
{
short x;
short y;
y = *value;
do
{
x = y;
y = _InterlockedCompareExchange16(value, x & mask, x);
}
while(y != x);
return y;
}
PPC_QUAL long _InterlockedAnd(volatile long * const value, const long mask)
{
long x;
long y;
y = *value;
do
{
x = y;
y = _InterlockedCompareExchange(value, x & mask, x);
}
while(y != x);
return y;
}
PPC_QUAL char _InterlockedOr8(volatile char * const value, const char mask)
{
char x;
char y;
y = *value;
do
{
x = y;
y = _InterlockedCompareExchange8(value, x | mask, x);
}
while(y != x);
return y;
}
PPC_QUAL short _InterlockedOr16(volatile short * const value, const short mask)
{
short x;
short y;
y = *value;
do
{
x = y;
y = _InterlockedCompareExchange16(value, x | mask, x);
}
while(y != x);
return y;
}
PPC_QUAL long _InterlockedOr(volatile long * const value, const long mask)
{
long x;
long y;
y = *value;
do
{
x = y;
y = _InterlockedCompareExchange(value, x | mask, x);
}
while(y != x);
return y;
}
PPC_QUAL char _InterlockedXor8(volatile char * const value, const char mask)
{
char x;
char y;
y = *value;
do
{
x = y;
y = _InterlockedCompareExchange8(value, x ^ mask, x);
}
while(y != x);
return y;
}
PPC_QUAL short _InterlockedXor16(volatile short * const value, const short mask)
{
short x;
short y;
y = *value;
do
{
x = y;
y = _InterlockedCompareExchange16(value, x ^ mask, x);
}
while(y != x);
return y;
}
PPC_QUAL long _InterlockedXor(volatile long * const value, const long mask)
{
long x;
long y;
y = *value;
do
{
x = y;
y = _InterlockedCompareExchange(value, x ^ mask, x);
}
while(y != x);
return y;
#define PPC_MakeInterlockedFunction(type,name,op,proto) \
PPC_QUAL type name proto \
{ \
long addend, y; \
do \
{ \
addend = *value; \
y = _InterlockedCompareExchange(value, addend op modify, addend); \
} \
while(y != addend); \
\
return y; \
}
PPC_QUAL unsigned char _interlockedbittestandreset(volatile long * const a, const long b)
@ -409,11 +251,9 @@ PPC_QUAL unsigned char _interlockedbittestandreset(volatile long * const a, cons
long y;
long mask = ~(1<<b);
y = *a;
do
{
x = y;
x = *a;
y = _InterlockedCompareExchange(a, x & mask, x);
}
while(y != x);
@ -421,17 +261,26 @@ PPC_QUAL unsigned char _interlockedbittestandreset(volatile long * const a, cons
return (y & ~mask) != 0;
}
PPC_MakeInterlockedFunction(long,_InterlockedExchangeAdd,+,(volatile long * const value, const long modify))
PPC_MakeInterlockedFunction(char,_InterlockedAnd8,&,(volatile char * const value, const char modify))
PPC_MakeInterlockedFunction(short,_InterlockedAnd16,&,(volatile short * const value, const short modify))
PPC_MakeInterlockedFunction(long,_InterlockedAnd,&,(volatile long * const value, const long modify))
PPC_MakeInterlockedFunction(char,_InterlockedOr8,|,(volatile char * const value, const char modify))
PPC_MakeInterlockedFunction(short,_InterlockedOr16,|,(volatile short * const value, const short modify))
PPC_MakeInterlockedFunction(long,_InterlockedOr,|,(volatile long * const value, const long modify))
PPC_MakeInterlockedFunction(char,_InterlockedXor8,^,(volatile char * const value, const char modify))
PPC_MakeInterlockedFunction(short,_InterlockedXor16,^,(volatile short * const value, const short modify))
PPC_MakeInterlockedFunction(long,_InterlockedXor,^,(volatile long * const value, const long modify))
PPC_QUAL unsigned char _interlockedbittestandset(volatile long * const a, const long b)
{
long x;
long y;
long mask = 1<<b;
y = *a;
do
{
x = y;
x = *a;
y = _InterlockedCompareExchange(a, x | mask, x);
}
while(y != x);

View file

@ -38,6 +38,12 @@
* 106 -- Unit Test
* 107 -- Turn on paging
* 108 -- Unmap process
* 109 -- Get lowest unallocated page
* 10a -- Alloc vsid
* 10b -- Revoke vsid
* 10c -- Allocate a page and return it
* 10d -- Return from trap callback
* 10e -- Dump Map
*
* 2** -- Debug Stub and Interrupt Vectoring
*
@ -106,7 +112,7 @@ typedef struct _ppc_map_info_t {
typedef struct _ppc_trap_frame_t {
unsigned long gpr[32];
unsigned long long fpr[32];
unsigned long srr0, srr1, cr, lr, ctr, xer, mq, dsisr, dar;
unsigned long srr0, srr1, cr, lr, ctr, dsisr, dar, xer;
} ppc_trap_frame_t;
typedef int (*MmuTrapHandler)(int trapid, ppc_trap_frame_t *trap);
@ -188,9 +194,9 @@ static inline void _MmuInit(void *_start, void *_end)
PPCMMU(0x100, 0, 0, 0);
}
static inline void MmuMapPage(ppc_map_info_t *info, int count)
static inline int MmuMapPage(ppc_map_info_t *info, int count)
{
PPCMMU(0x101, info, (void *)count, 0);
return PPCMMU(0x101, info, (void *)count, 0);
}
static inline void MmuUnmapPage(ppc_map_info_t *info, int count)
@ -243,6 +249,21 @@ static inline void MmuRevokeVsid(int vsid, int mask)
PPCMMU(0x10b, (void *)vsid, (void *)mask, 0);
}
static inline paddr_t MmuGetPage()
{
return PPCMMU(0x10c, 0,0,0);
}
static inline void MmuCallbackRet()
{
PPCMMU(0x10d, 0,0,0);
}
static inline void MmuDumpMap()
{
PPCMMU(0x10e, 0,0,0);
}
static inline void MmuDbgInit(int deviceType, int devicePort)
{
PPCMMU(0x200, (void *)deviceType, (void *)devicePort, 0);

View file

@ -47,14 +47,12 @@ mmumain:
stw 0,412(1)
mfctr 0
stw 0,416(1)
mfxer 0
stw 0,420(1)
/* xor 0,0,0 -- We can omit this since PPC doesn't have MQ */
stw 0,424(1)
mfdsisr 0
stw 0,420(1)
mfdar 0
stw 0,424(1)
mfxer 0
stw 0,428(1)
mfdar 0
stw 0,432(1)
addi 7,1,16
lis 8,_mmumain@ha
addi 8,8,_mmumain@l
@ -151,14 +149,12 @@ trap_start:
stw 0,412(1)
mfctr 0
stw 0,416(1)
mfxer 0
mfdsisr 0
stw 0,420(1)
/* xor 0,0,0 -- We can omit this since PPC doesn't have MQ */
stw 0,424(1)
mfdsisr 0
stw 0,428(1)
mfdar 0
stw 0,432(1)
stw 0,424(1)
mfxer 0
stw 0,428(1)
bl 1f
1: mflr 5
addi 4,1,16
@ -216,11 +212,11 @@ trap_finish_start:
lwz 0,400(1)
mtctr 0
lwz 0,404(1)
mtxer 0
lwz 0,412(1)
mtdsisr 0
lwz 0,416(1)
lwz 0,412(1)
mtdar 0
lwz 0,416(1)
mtxer 0
lwz 0,0(1)
lwz 1,4(1)
rfi

View file

@ -86,6 +86,8 @@
#include "ppcmmu/mmu.h"
#define GDB_SAVE_SIZE 0x66
typedef struct _BREAKPOINT {
int OldCode;
int *Address;
@ -137,7 +139,7 @@ inline void send(char *serport, char c) {
/* Wait for Clear to Send */
while( !(GetPhysByte((paddr_t)serport+LSR) & 0x20) ) sync();
SetPhysByte(serport+THR, c);
SetPhysByte((paddr_t)serport+THR, c);
sync();
}
@ -313,7 +315,7 @@ void GotPacket()
{
case 'g':
PacketStart();
for (i = 0; i < sizeof(*RegisterSaveArea) / sizeof(int); i++)
for (i = 0; i < GDB_SAVE_SIZE; i++)
{
PacketWriteHexNumber(((int *)RegisterSaveArea)[i], 8);
}
@ -410,7 +412,7 @@ int SerialInterrupt(int signal, ppc_trap_frame_t *tf)
Continue = 0;
PacketWriteSignal(3);
}
else if (ch == '-' || ch == '+')
else if (ch == '+')
{
/* Nothing */
}

View file

@ -40,6 +40,8 @@ Actions:
11 revoke vsid
*/
#define MMU_ADDR_RESERVED ((vaddr_t)-2)
MmuTrapHandler callback[0x30];
typedef struct _MmuFreePage {
int page;
@ -56,7 +58,7 @@ typedef struct _MmuVsidInfo {
struct _MmuVsidInfo *next;
MmuVsidTree *tree[256];
} MmuVsidInfo;
MmuFreePage *FreeList;
MmuFreePage *FreeList = 0;
// 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, GdbAttach = 0, Booted = 0, Vsid[16];
@ -66,15 +68,21 @@ MmuFreeTree *FreeTree;
MmuVsidInfo *Segs[16], *VsidHead = 0;
extern void fmtout(const char *fmt, ...);
extern char *serport;
int ptegreload(ppc_trap_frame_t *frame, vaddr_t addr);
void SerialSetUp(int deviceType, void *deviceAddr, int baud);
int SerialInterrupt(int n, ppc_trap_frame_t *tf);
void TakeException(int n, ppc_trap_frame_t *tf);
int mmuisfreepage(paddr_t pageno);
void copy(void *t, void *s, int b);
paddr_t mmunewpage();
void dumpmap();
void trapcallback(int action, ppc_trap_frame_t *trap_frame);
int _mmumain(int action, void *arg1, void *arg2, void *arg3, void *tf)
{
ppc_trap_frame_t *trap_frame = (action >= 0x100) ? tf : arg1;
int ret = 0, tmp;
int ret = 0, tmp, i;
switch(action)
{
@ -82,26 +90,24 @@ int _mmumain(int action, void *arg1, void *arg2, void *arg3, void *tf)
case 3:
if(!ptegreload(trap_frame, trap_frame->dar))
{
__asm__("mfmsr 3\n\tori 3,3,0x30\n\tmtmsr 3\n\t");
if (!callback[action](action,trap_frame)) TakeException(action, trap_frame);
}
trapcallback(action, trap_frame);
}
break;
case 4:
if(!ptegreload(trap_frame, trap_frame->srr0))
{
__asm__("mfmsr 3\n\tori 3,3,0x30\n\tmtmsr 3\n\t");
if (!callback[action](action,trap_frame)) TakeException(action, trap_frame);
}
{
trapcallback(action, trap_frame);
}
break;
case 5:
/* EE -- Try to get a serial interrupt if debugging enabled, then fall
* back to primary handler
*/
if (!SerialInterrupt(action, trap_frame))
callback[action](action, trap_frame);
else
trap_frame->srr1 |= 0x8000;
if (!SerialInterrupt(action, trap_frame) && callback[action])
{
trapcallback(action, trap_frame);
}
break;
case 0:
case 2:
@ -112,7 +118,7 @@ int _mmumain(int action, void *arg1, void *arg2, void *arg3, void *tf)
case 0xa:
case 0xc:
case 0x20:
if (!callback[action](action,trap_frame)) TakeException(action, trap_frame);
trapcallback(action, trap_frame);
break;
/* MMU Functions */
@ -153,6 +159,17 @@ int _mmumain(int action, void *arg1, void *arg2, void *arg3, void *tf)
case 0x10b:
mmufreevsid((int)arg1, (int)arg2);
break;
case 0x10c:
ret = mmunewpage();
break;
case 0x10d:
copy(trap_frame, (void *)0xf040, sizeof(*trap_frame));
__asm__("mr 1,%0\n\tb trap_finish_start" : : "r"
(((int)trap_frame) - 16));
break;
case 0x10e:
dumpmap();
break;
case 0x200:
SerialSetUp((int)arg1, arg2, 9600);
@ -172,9 +189,9 @@ int _mmumain(int action, void *arg1, void *arg2, void *arg3, void *tf)
* We turn off mapping, restore bats, then let rfi switch us back to where
* we came.
*/
if (action >= 0x100) {
int i;
if (action >= 0x100)
{
__asm__("mfmsr %0" : "=r" (tmp));
tmp &= ~0x30;
__asm__("mtmsr %0" : : "r" (tmp));
@ -188,11 +205,32 @@ int _mmumain(int action, void *arg1, void *arg2, void *arg3, void *tf)
return ret;
}
void trapcallback(int action, ppc_trap_frame_t *trap_frame)
{
if ((paddr_t)callback[action] < PAGETAB)
callback[action](action, trap_frame);
else
{
int framecopy = 0xf040;
copy((void *)framecopy, trap_frame, sizeof(*trap_frame));
trap_frame->srr0 = (int)callback[action];
trap_frame->srr1 &= 0x7fff;
trap_frame->gpr[3] = action;
trap_frame->gpr[4] = framecopy;
__asm__("mr 1,%0\n\tsubi 1,1,16\n\tb trap_finish_start" : : "r" (trap_frame));
}
}
void outchar(char c)
{
SetPhysByte(0x800003f8, c);
}
void copy(void *target, void *src, int bytes)
{
while(bytes--) *((char *)target++) = *((char *)src++);
}
void outstr(const char *str)
{
while(*str) outchar(*str);
@ -252,7 +290,7 @@ void mmusetramsize(paddr_t ramsize)
{
RamSize = ramsize;
FirstUsablePage = (paddr_t)last_map;
NextPage = PPC_PAGE_NUMBER(FirstUsablePage);
NextPage = PPC_PAGE_NUMBER(FirstUsablePage) + 1;
}
}
@ -301,7 +339,7 @@ void initme()
}
/* Serial Interrupt */
callback[5] = SerialInterrupt;
callback[5] = 0; /* Do nothing until the user asks */
/* Program Exception */
callback[6] = (MmuTrapHandler)TakeException;
@ -320,13 +358,41 @@ ppc_map_t *allocpage()
{
MmuFreePage *FreePage = 0;
if(NextPage < PPC_PAGE_NUMBER(RamSize)) {
return &PpcPageTable[NextPage++];
} else {
if (FreeList)
{
if ((void *)FreeList == (void *)PpcPageTable)
{
fmtout("Problem! FreeList: page 0 is free\n");
while(1);
}
FreePage = FreeList;
FreeList = FreeList->next;
((ppc_map_t*)FreePage)->addr = MMU_ADDR_RESERVED;
return ((ppc_map_t*)FreePage);
}
else
{
while(!mmuisfreepage(NextPage) && NextPage < PPC_PAGE_NUMBER(RamSize))
{
NextPage++;
}
if (NextPage < PPC_PAGE_NUMBER(RamSize))
{
if (NextPage < 0x30)
{
fmtout("Problem! NextPage is low (%x)\n", NextPage);
while(1);
}
PpcPageTable[NextPage].addr = MMU_ADDR_RESERVED;
return &PpcPageTable[NextPage++];
}
else
{
return NULL;
}
}
}
void freepage(ppc_map_t *PagePtr)
@ -437,6 +503,9 @@ int mmuaddpage(ppc_map_info_t *info, int count)
for(i = 0; i < count; i++)
{
info[i].phys &= ~PPC_PAGE_MASK;
info[i].addr &= ~PPC_PAGE_MASK;
virt = info[i].addr;
vsid = ((info[i].addr >> 28) & 15) | (info[i].proc << 4);
VsidInfo = findvsid(vsid);
@ -458,6 +527,15 @@ int mmuaddpage(ppc_map_info_t *info, int count)
phys = PPC_PAGE_ADDR((PagePtr - PpcPageTable));
ptelo = phys & ~PPC_PAGE_MASK;
if (phys < 0x30000)
{
/* Should not be allocating physical */
fmtout("Allocated physical: %x, logical %x\n", phys, virt);
fmtout("PagePtr %x (page %d)\n", PagePtr, i);
fmtout("info [ %x %x %x %x ]\n", info[i].proc, info[i].addr, info[i].flags, info[i].phys);
while(1);
}
/* Update page data */
PagePtr->pte.pteh = ptehi;
PagePtr->pte.ptel = ptelo;
@ -478,6 +556,13 @@ int mmuaddpage(ppc_map_info_t *info, int count)
return 1;
}
paddr_t mmunewpage()
{
ppc_map_t *PagePtr = allocpage();
if (!PagePtr) return 0;
return PPC_PAGE_ADDR(PagePtr - PpcPageTable);
}
ppc_pteg_t *PtegFromPage(ppc_map_t *map, int hfun)
{
if(!map->proc && !map->addr) return 0;
@ -553,9 +638,9 @@ void mmugetpage(ppc_map_info_t *info, int count)
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;
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);
@ -571,6 +656,12 @@ void mmugetpage(ppc_map_info_t *info, int count)
}
}
int mmuisfreepage(paddr_t pageno)
{
ppc_map_t *PagePtr = PpcPageTable + pageno;
return !PagePtr->addr;
}
void mmusetvsid(int start, int end, int vsid)
{
int i, sr, s_vsid;
@ -603,6 +694,52 @@ int ptegreload(ppc_trap_frame_t *frame, vaddr_t addr)
return 1;
}
void printmap(vaddr_t vaddr, ppc_map_t *map)
{
fmtout("%x: proc %x addr %x\n",
PPC_PAGE_ADDR(map - PpcPageTable),
map->proc, vaddr);
}
void dumptree(vaddr_t vaddr, MmuVsidTree *tree)
{
int j;
for (j = 0; j < 256; j++)
{
if (tree->leaves[j])
{
printmap(vaddr | (j << 12), tree->leaves[j]);
}
}
}
void dumpvsid(MmuVsidInfo *vsid)
{
int i;
fmtout("vsid %d (%x):\n", vsid->vsid>>4, vsid->vsid<<28);
for (i = 0; i < 256; i++)
{
if (vsid->tree[i])
{
dumptree((vsid->vsid<<28) | i << 20, vsid->tree[i]);
}
}
}
void dumpmap()
{
int i,j;
ppc_map_t *map;
MmuVsidInfo *vsid;
fmtout("Address spaces:\n");
for (vsid = VsidHead; vsid; vsid = vsid->next)
{
dumpvsid(vsid);
}
}
void callkernel(void *fun_ptr, void *arg)
{
int i;

View file

@ -15,12 +15,12 @@ DebugService
(ULONG Service, const void *Buffer, ULONG Length, PVOID Arg1, PVOID Arg2)
{
NTSTATUS Result;
__asm__("mr 3,%2\n\t"
__asm__("mr 0,%1\n\t"
"mr 3,%2\n\t"
"mr 4,%3\n\t"
"mr 5,%4\n\t"
"mr 6,%5\n\t"
"mr 7,%6\n\t"
"mr 8,%1\n\t"
"sc\n\t"
"mr %0,3\n\t" :
"=r" (Result) :

View file

@ -10,83 +10,42 @@
/* INCLUDES ******************************************************************/
.text
.globl syscall_start
.globl syscall_end
.globl KiSystemService
syscall_start:
mtsprg0 0
mtsprg1 1
/* Save and modify srr0 */
/* Make a place to store the old srr0 and srr1 ... we may fault
* getting KiSystemService1 which will clobber them. */
lis 1,1
mfsrr0 0
stw 0,-16(1)
mfsrr1 0
stw 0,-12(1)
/* Load the target address */
lis 1,KiSystemService1@ha
addi 1,1,KiSystemService1@l
mtsrr0 1
mfsprg0 0
mfsprg1 1
rfi
syscall_end:
.space 4
.globl KiSystemService
.globl KiSystemService1
.globl kiss_proceed
.globl kiss_end
.align 8
KiSystemService1:
stw 2,4(1) // r1
stw 3,12(1)
stw 4,16(1)
stw 5,20(1)
stw 6,24(1)
stw 7,28(1)
stw 8,32(1)
stw 9,36(1)
stw 10,40(1)
stw 11,44(1)
stw 12,48(1)
stw 13,52(1)
stw 14,56(1)
stw 15,60(1)
stw 16,64(1)
stw 17,68(1)
stw 18,72(1)
stw 19,76(1)
stw 20,80(1)
stw 21,84(1)
stw 22,88(1)
stw 23,92(1)
stw 24,96(1)
stw 25,100(1)
stw 26,104(1)
stw 27,108(1)
stw 28,112(1)
stw 29,116(1)
stw 30,120(1)
stw 31,124(1)
/* This save is important */
stw 0,140(1) // srr0
stwu 1,-256(1)
stw 0,16(1)
mflr 0
stw 0,128(1)
mfctr 0
stw 0,136(1)
mfsrr1 0
stw 0,144(1)
mfdsisr 0
stw 0,148(1)
mfdar 0
stw 0,152(1)
lis 3,KiSystemService@ha
addi 3,3,KiSystemService@l
mtctr 3
mr 3,1
subi 1,1,0x100
bctrl
addi 1,1,0x100
/* Return from kernel */
lwz 3,12(1) /* Result */
lwz 0,128(1)
mtlr 0
lwz 0,140(1)
mtsrr0 0
lwz 0,144(1)
mtsrr1 0
lwz 1,4(1) /* Stack */
rfi
.globl KiDecrementerTrapHandler
.globl KiDecrementerTrapHandlerEnd
.globl KiDecrementerTrap
KiDecrementerTrapHandler:
// switch to trap stack until we figure out where to go
mtsprg0 1
lis 1,_kernel_trap_stack@ha
addi 1,1,_kernel_trap_stack@l
subi 1,1,0x100
stw 0,0(1)
mfsprg0 0
stw 0,4(1)
stw 0,264(1)
addi 1,1,16
stw 2,8(1)
stw 3,12(1)
stw 4,16(1)
@ -117,79 +76,177 @@ KiDecrementerTrapHandler:
stw 29,116(1)
stw 30,120(1)
stw 31,124(1)
/* This save is important */
stw 0,140(1) // srr0
mflr 0
stw 0,128(1)
mfctr 0
stw 0,136(1)
mfsrr1 0
stw 0,144(1)
mfmsr 0
andi. 0,0,0xffef
mtmsr 0
lis 2,1
lwz 30,-12(2)
lwz 31,-16(2)
mfmsr 0
ori 0,0,0x10
mtmsr 0
stw 31,140(1)
stw 30,144(1)
mfdsisr 0
stw 0,148(1)
mfdar 0
stw 0,152(1)
lis 3,KiDecrementerTrap@ha
addi 3,3,KiDecrementerTrap@l
lis 3,KiSystemService@ha
addi 3,3,KiSystemService@l
mtctr 3
lis 3,KiDecrementerTrapFinish@ha
addi 3,3,KiDecrementerTrapFinish@l
mtlr 3
mr 3,1
subi 1,1,0x100
bctr
/* We don't return here */
subi 1,1,16
bctrl
addi 1,1,16
/* Return from kernel */
lwz 3,32(1) /* Result */
lwz 0,128(1)
mtlr 0
lwz 0,140(1)
mtsrr0 0
lwz 0,144(1)
mtsrr1 0
addi 1,1,0x100 - 16
rfi
.globl KiDecrementerTrapHandler
.globl KiDecrementerTrapHandlerEnd
.globl KiDecrementerTrap
KiDecrementerTrapHandler:
mtsprg0 0
mtsprg1 1
/* Save and modify srr0 */
/* Make a place to store the old srr0 and srr1 ... we may fault
* getting KiSystemService1 which will clobber them. */
lis 1,1
mfsprg1 0
stw 0,-24(1)
mfsrr1 0
stw 0,-28(1)
mfsrr0 0
stw 0,-32(1)
/* Load the target address */
lis 1,KiDecrementerTrapUpper@ha
addi 1,1,KiDecrementerTrapUpper@l
mtsrr0 1
mfsprg0 0
mfsprg1 1
rfi
KiDecrementerTrapHandlerEnd:
.long 0
/* Decrementer needs to restore the full CPU state */
.globl KiDecrementerTrapFinish
KiDecrementerTrapFinish:
addi 1,1,0x100
lwz 2,8(1)
lwz 3,12(1)
lwz 4,16(1)
lwz 5,20(1)
lwz 6,24(1)
lwz 7,28(1)
lwz 8,32(1)
lwz 9,36(1)
lwz 10,40(1)
lwz 11,44(1)
lwz 12,48(1)
lwz 13,52(1)
lwz 14,56(1)
lwz 15,60(1)
lwz 16,64(1)
lwz 17,68(1)
lwz 18,72(1)
lwz 19,76(1)
lwz 20,80(1)
lwz 21,84(1)
lwz 22,88(1)
lwz 23,92(1)
lwz 24,96(1)
lwz 25,100(1)
lwz 26,104(1)
lwz 27,108(1)
lwz 28,112(1)
lwz 29,116(1)
lwz 30,120(1)
lwz 31,124(1)
lwz 0,140(1)
mtsrr0 0
lwz 0,128(1)
mtlr 0
lwz 0,136(1)
mtctr 0
lwz 0,144(1)
.globl KiDecrementerTrapUpper
.align 8
KiDecrementerTrapUpper:
lis 1,_kernel_trap_stack@ha
addi 1,1,_kernel_trap_stack@l
subi 1,1,0x200
stw 0,0x5c(1)
/* Stack handled a bit later */
stw 2,0x64(1)
stw 3,0x68(1)
stw 4,0x6c(1)
stw 5,0x70(1)
stw 6,0x74(1)
stw 7,0x78(1)
stw 8,0x7c(1)
stw 9,0x80(1)
stw 10,0x84(1)
stw 11,0x88(1)
stw 12,0x8c(1)
stw 13,0x90(1)
stw 14,0x94(1)
stw 15,0x98(1)
stw 16,0x9c(1)
stw 17,0xa0(1)
stw 18,0xa4(1)
stw 19,0xa8(1)
stw 20,0xac(1)
stw 21,0xb0(1)
stw 22,0xb4(1)
stw 23,0xb8(1)
stw 24,0xbc(1)
stw 25,0xc0(1)
stw 26,0xc4(1)
stw 27,0xc8(1)
stw 28,0xcc(1)
stw 29,0xd0(1)
stw 30,0xd4(1)
stw 31,0xd8(1)
mfcr 0
stw 0,0x108(1)
mfxer 0
stw 0,0x10c(1)
mflr 0
stw 0,0x118(1)
mfctr 0
stw 0,0x11c(1)
mfmsr 0
andi. 0,0,0x7fef
mtmsr 0
lis 2,1
lwz 29,-24(2) // Stack
lwz 30,-28(2) // srr1
lwz 31,-32(2) // srr0
mfmsr 0
ori 0,0,0x30
mtmsr 0
stw 29,0x60(1) // Stack
stw 30,0x110(1) // srr1
stw 31,0x114(1) // srr0
mr 3,1
subi 1,1,16
bl KiDecrementerTrap
addi 1,1,16
lwz 2,0x64(1)
lwz 3,0x68(1)
lwz 4,0x6c(1)
lwz 5,0x70(1)
lwz 6,0x74(1)
lwz 7,0x78(1)
lwz 8,0x7c(1)
lwz 9,0x80(1)
lwz 10,0x84(1)
lwz 11,0x88(1)
lwz 12,0x8c(1)
lwz 13,0x90(1)
lwz 14,0x94(1)
lwz 15,0x98(1)
lwz 16,0x9c(1)
lwz 17,0xa0(1)
lwz 18,0xa4(1)
lwz 19,0xa8(1)
lwz 20,0xac(1)
lwz 21,0xb0(1)
lwz 22,0xb4(1)
lwz 23,0xb8(1)
lwz 24,0xbc(1)
lwz 25,0xc0(1)
lwz 26,0xc4(1)
lwz 27,0xc8(1)
lwz 28,0xcc(1)
lwz 29,0xd0(1)
lwz 30,0xd4(1)
lwz 31,0xd8(1)
lwz 0,0x108(1)
mtcr 0
lwz 0,0x10c(1)
mtxer 0
lwz 0,0x110(1)
mtsrr1 0
lwz 0,148(1)
mtdsisr 0
lwz 0,152(1)
mtdar 0
lwz 0,0x114(1)
mtsrr0 0
lwz 0,0x118(1)
mtlr 0
lwz 0,0x11c(1)
mtctr 0
// back out r0 and r1
lwz 0,0(1)
lwz 1,4(1)
lwz 0,0x5c(1)
lwz 1,0x60(1)
// Bye!!1
rfi

View file

@ -13,6 +13,7 @@
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
#include <ppcmmu/mmu.h>
/*++
* KiThreadStartup
@ -53,7 +54,7 @@ KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
KTRAP_FRAME TrapFrame)
{
KeLowerIrql(APC_LEVEL);
__asm__("mr 8,%0\n\t"
__asm__("mr 0,%0\n\t"
"mr 3,%1\n\t"
"mr 4,%2\n\t"
"mr 5,%3\n\t"
@ -69,10 +70,55 @@ KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
/* Take a decrementer trap, and prepare the given trap frame, swapping
* process and thread context as appropriate. */
VOID KiDecrementerTrapFinish(PKTRAP_FRAME TrapFrame);
VOID
FASTCALL
KiQueueReadyThread(IN PKTHREAD Thread,
IN PKPRCB Prcb);
PKTHREAD KiLastThread = NULL;
PKTRAP_FRAME KiLastThreadTrapFrame = NULL;
VOID
STDCALL
KiDecrementerTrap(PKTRAP_FRAME TrapFrame)
{
DbgPrint("Decrementer Trap!\n");
__asm__("mtdec %0" : : "r" (0x10000)); // Reset the trap
KIRQL Irql;
PKPRCB Prcb = KeGetPcr()->Prcb;
if (!KiLastThread)
KiLastThread = KeGetCurrentThread();
if (KiLastThread->State == Running)
KiQueueReadyThread(KiLastThread, Prcb);
if (!KiLastThreadTrapFrame)
KiLastThreadTrapFrame = Prcb->IdleThread->TrapFrame;
TrapFrame->OldIrql = KeGetCurrentIrql();
*KiLastThreadTrapFrame = *TrapFrame;
if (Prcb->NextThread)
{
Prcb->CurrentThread = Prcb->NextThread;
Prcb->NextThread = NULL;
}
else
Prcb->CurrentThread = Prcb->IdleThread;
Prcb->CurrentThread->State = Running;
KiLastThreadTrapFrame = Prcb->CurrentThread->TrapFrame;
KiLastThread = Prcb->CurrentThread;
*TrapFrame = *KiLastThreadTrapFrame;
Irql = KeGetCurrentIrql();
if (Irql > TrapFrame->OldIrql)
KfRaiseIrql(Irql);
else if (Irql < TrapFrame->OldIrql)
KfLowerIrql(Irql);
/* When we return, we'll go through rfi and be in new thread land */
__asm__("mtdec %0" : : "r" (0x1000000)); // Reset the trap
}

View file

@ -13,6 +13,7 @@
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
#include <ppcmmu/mmu.h>
/* FUNCTIONS *****************************************************************/
@ -100,6 +101,10 @@ KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
IN KPROCESSOR_MODE PreviousMode,
IN BOOLEAN FirstChance)
{
DbgPrint("EXCEPTION! Record %08x Frame %08x\n",
ExceptionRecord, ExceptionFrame);
MmuDumpMap();
KEBUGCHECK(0);
}
/*

View file

@ -11,7 +11,7 @@
#include <ntoskrnl.h>
#define NDEBUG
//#define NDEBUG
#include <debug.h>
#include "ppcmmu/mmu.h"
@ -30,28 +30,11 @@ extern ULONG KeMemoryMapRangeCount;
extern ADDRESS_RANGE KeMemoryMap[64];
/* FUNCTIONS *****************************************************************/
/*
* Trap frame:
* r0 .. r32
* lr, ctr, srr0, srr1, dsisr
*/
__asm__(".text\n\t"
".globl syscall_start\n\t"
".globl syscall_end\n\t"
".globl KiSystemService\n\t"
"syscall_start:\n\t"
"mr 2,1\n\t"
"lis 1,KiSystemService1@ha\n\t"
"addi 1,1,KiSystemService1@l\n\t"
"mfsrr0 0\n\t"
"mtsrr0 1\n\t"
"lis 1,_kernel_trap_stack@ha\n\t"
"addi 1,1,_kernel_trap_stack@l\n\t"
"subi 1,1,0x100\n\t"
"rfi\n\t"
"syscall_end:\n\t"
".space 4");
extern int syscall_start[], syscall_end, KiDecrementerTrapHandler[],
KiDecrementerTrapHandlerEnd;
@ -83,11 +66,14 @@ KiSetupDecrementerTrap()
source++, handler_target += sizeof(int))
SetPhys(handler_target, *source);
/* Enable interrupts! */
_enable();
DPRINT("CurrentThread %08x IdleThread %08x\n",
KeGetCurrentThread(), KeGetCurrentPrcb()->IdleThread);
/* Kick decmrenter! */
__asm__("mtdec %0" : : "r" (0));
/* Enable interrupts! */
_enable();
}
VOID
@ -111,6 +97,7 @@ KiInitializePcr(IN ULONG ProcessorNumber,
Pcr->PrcbData->BuildType = 0;
#endif
Pcr->PrcbData->DpcStack = DpcStack;
KeGetPcr()->Prcb = Pcr->PrcbData;
KiProcessorBlock[ProcessorNumber] = Pcr->PrcbData;
}
@ -219,27 +206,22 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
KeMemoryMapRangeCount,
4096);
DPRINT1("\n");
/* Initialize the Kernel Executive */
ExpInitializeExecutive(0, LoaderBlock);
DPRINT1("\n");
/* Only do this on the boot CPU */
if (!Number)
{
DPRINT1("\n");
/* Calculate the time reciprocal */
KiTimeIncrementReciprocal =
KiComputeReciprocal(KeMaximumIncrement,
&KiTimeIncrementShiftCount);
DPRINT1("\n");
/* Update DPC Values in case they got updated by the executive */
Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
Prcb->MinimumDpcRate = KiMinimumDpcRate;
Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
DPRINT1("\n");
/* Allocate the DPC Stack */
DpcStack = MmCreateKernelStack(FALSE, 0);
if (!DpcStack) KeBugCheckEx(NO_PAGES_AVAILABLE, 1, 0, 0, 0);
@ -249,21 +231,23 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
/* Free Initial Memory */
// MiFreeInitMemory();
DPRINT1("\n");
KfRaiseIrql(DISPATCH_LEVEL);
KeSetPriorityThread(InitThread, 0);
/* Setup decrementer exception */
KiSetupDecrementerTrap();
DPRINT1("\n");
while (1)
KfLowerIrql(PASSIVE_LEVEL);
/* Should not return */
while(1)
{
LARGE_INTEGER Timeout;
Timeout.QuadPart = 0x7fffffffffffffffLL;
DPRINT1("\n");
KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
NtYieldExecution();
}
}
extern int KiPageFaultHandler(int trap, ppc_trap_frame_t *frame);
extern int KiPageFaultTrap();
KTRAP_FRAME KiInitialTrapFrame;
/* Use this for early boot additions to the page table */
VOID
@ -278,8 +262,8 @@ KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
__asm__("mr 13,%0" : : "r" (KPCR_BASE));
/* Set the page fault handler to the kernel */
MmuSetTrapHandler(3,KiPageFaultHandler);
MmuSetTrapHandler(4,KiPageFaultHandler);
MmuSetTrapHandler(3,KiPageFaultTrap);
MmuSetTrapHandler(4,KiPageFaultTrap);
// Make 0xf... special
MmuAllocVsid(2, 0x8000);
@ -323,6 +307,7 @@ KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
/* Set us as the current process */
KiInitialThread.Tcb.ApcState.Process = &KiInitialProcess.Pcb;
KiInitialThread.Tcb.TrapFrame = &KiInitialTrapFrame;
/* Setup CPU-related fields */
AppCpuInit:

View file

@ -751,14 +751,18 @@ ULONG
NTAPI
KdpServiceDispatcher(ULONG Service, PCHAR Buffer, ULONG Length);
typedef ULONG (*PSYSCALL_FUN)
(ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG);
VOID
NTAPI
KiSystemService(ppc_trap_frame_t *trap_frame)
{
int i;
PKSYSTEM_ROUTINE SystemRoutine;
PSYSCALL_FUN SyscallFunction;
switch(trap_frame->gpr[8])
switch(trap_frame->gpr[0])
{
case 0x10000: /* DebugService */
for( i = 0; i < trap_frame->gpr[5]; i++ )
@ -777,6 +781,24 @@ KiSystemService(ppc_trap_frame_t *trap_frame)
SystemRoutine((PKSTART_ROUTINE)trap_frame->gpr[4],
(PVOID)trap_frame->gpr[5]);
break;
/* Handle a normal system call */
default:
SyscallFunction =
((PSYSCALL_FUN*)KeServiceDescriptorTable
[trap_frame->gpr[0] >> 12].Base)[trap_frame->gpr[0] & 0xfff];
trap_frame->gpr[3] = SyscallFunction
(trap_frame->gpr[3],
trap_frame->gpr[4],
trap_frame->gpr[5],
trap_frame->gpr[6],
trap_frame->gpr[7],
trap_frame->gpr[8],
trap_frame->gpr[9],
trap_frame->gpr[10],
trap_frame->gpr[11],
trap_frame->gpr[12]);
break;
}
}

View file

@ -11,6 +11,7 @@
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
#include <ppcmmu/mmu.h>
NTSTATUS
NTAPI
@ -137,13 +138,17 @@ VOID
NTAPI
KiSwapProcess(struct _KPROCESS *NewProcess, struct _KPROCESS *OldProcess)
{
PEPROCESS EProcess = (PEPROCESS)NewProcess;
MmuSetVsid(0, 8, EProcess ? (ULONG)EProcess->UniqueProcessId : 0);
}
BOOLEAN
NTAPI
KiSwapContext(PKTHREAD CurrentThread, PKTHREAD NewThread)
{
return FALSE;
KeGetPcr()->Prcb->NextThread = NewThread;
__asm__("mtdec %0" : : "r" (1));
return TRUE;
}
NTSTATUS

View file

@ -10,9 +10,10 @@
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
//#define NDEBUG
#include <debug.h>
#include <ndk/powerpc/ketypes.h>
#include <ppcmmu/mmu.h>
typedef struct _KSWITCHFRAME
{
@ -41,6 +42,7 @@ typedef struct _KKINIT_FRAME
{
KSWITCHFRAME CtxSwitchFrame;
KSTART_FRAME StartFrame;
KTRAP_FRAME TrapFrame;
FX_SAVE_AREA FxSaveArea;
} KKINIT_FRAME, *PKKINIT_FRAME;
@ -60,7 +62,17 @@ KePPCInitThreadWithContext(IN PKTHREAD Thread,
PKTRAP_FRAME TrapFrame;
CONTEXT LocalContext;
PCONTEXT Context = NULL;
ULONG ContextFlags;
ppc_map_info_t pagemap[16];
PETHREAD EThread = (PETHREAD)Thread;
PEPROCESS Process = EThread->ThreadsProcess;
ULONG ContextFlags, i, pmsize = sizeof(pagemap) / sizeof(pagemap[0]);
DPRINT("Thread: %08x ContextPointer: %08x SystemRoutine: %08x StartRoutine: %08x StartContext: %08x\n",
Thread,
ContextPointer,
SystemRoutine,
StartRoutine,
StartContext);
/* Check if this is a With-Context Thread */
if (ContextPointer)
@ -110,6 +122,15 @@ KePPCInitThreadWithContext(IN PKTHREAD Thread,
/* Tell KiThreadStartup of that too */
StartFrame->UserThread = TRUE;
Thread->TrapFrame = TrapFrame;
DPRINT("Thread %08x Iar %08x Msr %08x Gpr1 %08x Gpr3 %08x\n",
Thread,
TrapFrame->Iar,
TrapFrame->Msr,
TrapFrame->Gpr1,
TrapFrame->Gpr3);
}
else
{
@ -131,6 +152,25 @@ KePPCInitThreadWithContext(IN PKTHREAD Thread,
/* Tell KiThreadStartup of that too */
StartFrame->UserThread = FALSE;
/* Setup the Trap Frame */
TrapFrame = &InitFrame->TrapFrame;
Thread->TrapFrame = TrapFrame;
TrapFrame->OldIrql = PASSIVE_LEVEL;
TrapFrame->Iar = (ULONG)SystemRoutine;
TrapFrame->Msr = 0xb030;
TrapFrame->Gpr1 = ((ULONG)&InitFrame->StartFrame) - 0x200;
TrapFrame->Gpr3 = (ULONG)StartRoutine;
TrapFrame->Gpr4 = (ULONG)StartContext;
__asm__("mr %0,13" : "=r" (((PULONG)&TrapFrame->Gpr0)[13]));
DPRINT("Thread %08x Iar %08x Msr %08x Gpr1 %08x Gpr3 %08x\n",
Thread,
TrapFrame->Iar,
TrapFrame->Msr,
TrapFrame->Gpr1,
TrapFrame->Gpr3);
}
/* Now setup the remaining data for KiThreadStartup */
@ -145,6 +185,36 @@ KePPCInitThreadWithContext(IN PKTHREAD Thread,
/* Save back the new value of the kernel stack. */
Thread->KernelStack = (PVOID)CtxSwitchFrame;
/* If we're the first thread of the new process, copy the top 16 pages
* from process 0 */
if (Process && IsListEmpty(&Process->ThreadListHead))
{
DPRINT("First Thread in Process %x\n", Process);
MmuAllocVsid((ULONG)Process->UniqueProcessId, 0xff);
for (i = 0; i < pmsize; i++)
{
pagemap[i].proc = 0;
pagemap[i].addr = 0x7fff0000 + (i * PAGE_SIZE);
}
MmuInqPage(pagemap, pmsize);
for (i = 0; i < pmsize; i++)
{
if (pagemap[i].phys)
{
pagemap[i].proc = (ULONG)Process->UniqueProcessId;
pagemap[i].phys = 0;
MmuMapPage(&pagemap[i], 1);
DPRINT("Added map to the new process: P %08x A %08x\n",
pagemap[i].proc, pagemap[i].addr);
}
}
DPRINT("Did additional aspace setup in the new process\n");
}
}
/* EOF */

View file

@ -13,7 +13,7 @@
#include <ntoskrnl.h>
#include <ppcmmu/mmu.h>
#define NDEBUG
//#define NDEBUG
#include <internal/debug.h>
#if defined (ALLOC_PRAGMA)
@ -136,9 +136,28 @@ MmDeletePageTable(PEPROCESS Process, PVOID Address)
{
PEPROCESS CurrentProcess = PsGetCurrentProcess();
if(!CurrentProcess) return;
DPRINT1("DeletePageTable: Process: %x CurrentProcess %x\n",
Process, CurrentProcess);
MmuRevokeVsid((paddr_t)Process->UniqueProcessId, -1);
if (Process != NULL && Process != CurrentProcess)
{
KeAttachProcess(&Process->Pcb);
}
if (Process)
{
DPRINT1("Revoking VSID %d\n", (paddr_t)Process->UniqueProcessId);
MmuRevokeVsid((paddr_t)Process->UniqueProcessId, -1);
}
else
{
DPRINT1("No vsid to revoke\n");
}
if (Process != NULL && Process != CurrentProcess)
{
KeDetachProcess();
}
}
VOID
@ -412,7 +431,7 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
ULONG Attributes;
PVOID Addr;
ULONG i;
ppc_map_info_t info;
ppc_map_info_t info = { 0 };
DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n",
Process, Address, flProtect, Pages, *Pages, PageCount);
@ -453,7 +472,8 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE))
{
Process = PsGetCurrentProcess();
info.proc = Process ? (int)Process->UniqueProcessId : 0;
info.proc = ((Addr < MmSystemRangeStart) && Process) ?
(int)Process->UniqueProcessId : 0;
info.addr = (vaddr_t)Addr;
info.flags = Attributes;
MmuMapPage(&info, 1);
@ -627,4 +647,23 @@ MmUpdatePageDir(PEPROCESS Process, PVOID Address, ULONG Size)
{
}
/* Create a simple, primitive mapping at the specified address on a new page */
NTSTATUS MmPPCCreatePrimitiveMapping(ULONG_PTR PageAddr)
{
NTSTATUS result;
ppc_map_info_t info = { 0 };
info.flags = MMU_KRW;
info.addr = (vaddr_t)PageAddr;
result = MmuMapPage(&info, 1) ? STATUS_SUCCESS : STATUS_NO_MEMORY;
return result;
}
/* Use our primitive allocator */
PFN_TYPE MmPPCPrimitiveAllocPage()
{
paddr_t Result = MmuGetPage();
DbgPrint("Got Page %x\n", Result);
return Result / PAGE_SIZE;
}
/* EOF */

View file

@ -33,14 +33,23 @@ VOID MmpPpcTrapFrameToTrapFrame(ppc_trap_frame_t *frame, PKTRAP_FRAME Tf)
Tf->Cr = frame->cr;
Tf->Ctr = frame->ctr;
Tf->Xer = frame->xer;
Tf->Iar = frame->srr0;
Tf->Msr = frame->srr1 & 0xffff;
Tf->Dr0 = frame->srr0;
Tf->Dr1 = frame->srr1;
Tf->Dr2 = frame->dar;
Tf->Dr3 = frame->dsisr;
Tf->Dr0 = frame->dar;
Tf->Dr1 = frame->dsisr;
}
int KiPageFaultHandler(int trap, ppc_trap_frame_t *frame)
void CopyFrame(int *oldframe, int *ourframe)
{
int i;
for (i = 0; i < sizeof(ppc_trap_frame_t) / sizeof(int); i++)
{
ourframe[i] = GetPhys((int)&oldframe[i]);
}
}
void KiPageFaultHandler(int trap, ppc_trap_frame_t *frame)
{
NTSTATUS Status = STATUS_SUCCESS;
KPROCESSOR_MODE Mode;
@ -57,7 +66,8 @@ int KiPageFaultHandler(int trap, ppc_trap_frame_t *frame)
VirtualAddr = frame->dar;
/* MSR_PR */
Mode = frame->srr1 & 0x4000 ? KernelMode : UserMode;
Mode = frame->srr1 & 0x4000 ? UserMode : KernelMode;
DPRINT("Page Fault at %08x\n", frame->srr0);
/* handle the fault */
if (AccessFault)
@ -70,7 +80,9 @@ int KiPageFaultHandler(int trap, ppc_trap_frame_t *frame)
}
if (NT_SUCCESS(Status))
return 1;
{
MmuCallbackRet();
}
if (KeGetCurrentThread()->ApcState.UserApcPending)
{
@ -95,6 +107,6 @@ int KiPageFaultHandler(int trap, ppc_trap_frame_t *frame)
Er.ExceptionFlags = 0;
KiDispatchException(&Er, 0, &Tf, Mode, TRUE);
return 1;
MmuCallbackRet();
}

File diff suppressed because it is too large Load diff