From 9dc65bb296643892573c435f3ad1302cc81bcc07 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Wed, 23 Jan 2008 00:43:39 +0000 Subject: [PATCH] Page fault, system calls, context switches debugged. Heaps, system calls, context switches all functional. svn path=/trunk/; revision=31953 --- .../boot/freeldr/freeldr/arch/powerpc/mboot.c | 19 +- reactos/include/psdk/intrin_ppc.h | 287 +--- reactos/include/reactos/libs/ppcmmu/mmu.h | 27 +- reactos/lib/ppcmmu/devint.s | 26 +- reactos/lib/ppcmmu/gdblib.c | 8 +- reactos/lib/ppcmmu/mmuobject.c | 185 ++- reactos/lib/rtl/powerpc/debug.c | 4 +- reactos/ntoskrnl/ke/powerpc/ctxhelp.S | 315 +++-- reactos/ntoskrnl/ke/powerpc/ctxswitch.c | 52 +- reactos/ntoskrnl/ke/powerpc/exp.c | 5 + reactos/ntoskrnl/ke/powerpc/kiinit.c | 55 +- reactos/ntoskrnl/ke/powerpc/ppc_irq.c | 24 +- reactos/ntoskrnl/ke/powerpc/stubs.c | 7 +- reactos/ntoskrnl/ke/powerpc/thrdini.c | 74 +- reactos/ntoskrnl/mm/powerpc/page.c | 49 +- reactos/ntoskrnl/mm/powerpc/pfault.c | 28 +- reactos/tools/nci/ncitool.c | 1214 ++++++++--------- 17 files changed, 1305 insertions(+), 1074 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c index 1470d4bd60c..7e1ccd2f13a 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c @@ -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++ ) { diff --git a/reactos/include/psdk/intrin_ppc.h b/reactos/include/psdk/intrin_ppc.h index 7713277b01d..efa9d4eed14 100644 --- a/reactos/include/psdk/intrin_ppc.h +++ b/reactos/include/psdk/intrin_ppc.h @@ -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<> 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; diff --git a/reactos/lib/rtl/powerpc/debug.c b/reactos/lib/rtl/powerpc/debug.c index 7fcb94f4b1e..9b13bd5186a 100644 --- a/reactos/lib/rtl/powerpc/debug.c +++ b/reactos/lib/rtl/powerpc/debug.c @@ -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) : diff --git a/reactos/ntoskrnl/ke/powerpc/ctxhelp.S b/reactos/ntoskrnl/ke/powerpc/ctxhelp.S index b470a4282f8..6c792d55550 100644 --- a/reactos/ntoskrnl/ke/powerpc/ctxhelp.S +++ b/reactos/ntoskrnl/ke/powerpc/ctxhelp.S @@ -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 diff --git a/reactos/ntoskrnl/ke/powerpc/ctxswitch.c b/reactos/ntoskrnl/ke/powerpc/ctxswitch.c index 665e58d0fc7..497dd7b2e90 100644 --- a/reactos/ntoskrnl/ke/powerpc/ctxswitch.c +++ b/reactos/ntoskrnl/ke/powerpc/ctxswitch.c @@ -13,6 +13,7 @@ #include #define NDEBUG #include +#include /*++ * 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 } diff --git a/reactos/ntoskrnl/ke/powerpc/exp.c b/reactos/ntoskrnl/ke/powerpc/exp.c index 627958405ae..3d9a04459e2 100644 --- a/reactos/ntoskrnl/ke/powerpc/exp.c +++ b/reactos/ntoskrnl/ke/powerpc/exp.c @@ -13,6 +13,7 @@ #include #define NDEBUG #include +#include /* 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); } /* diff --git a/reactos/ntoskrnl/ke/powerpc/kiinit.c b/reactos/ntoskrnl/ke/powerpc/kiinit.c index 22fdaed0768..c41feaf110e 100644 --- a/reactos/ntoskrnl/ke/powerpc/kiinit.c +++ b/reactos/ntoskrnl/ke/powerpc/kiinit.c @@ -11,7 +11,7 @@ #include -#define NDEBUG +//#define NDEBUG #include #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: diff --git a/reactos/ntoskrnl/ke/powerpc/ppc_irq.c b/reactos/ntoskrnl/ke/powerpc/ppc_irq.c index 3fef82530c0..9f1a8e4f4e5 100644 --- a/reactos/ntoskrnl/ke/powerpc/ppc_irq.c +++ b/reactos/ntoskrnl/ke/powerpc/ppc_irq.c @@ -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; } } diff --git a/reactos/ntoskrnl/ke/powerpc/stubs.c b/reactos/ntoskrnl/ke/powerpc/stubs.c index 341e031eb83..7c7389b183c 100644 --- a/reactos/ntoskrnl/ke/powerpc/stubs.c +++ b/reactos/ntoskrnl/ke/powerpc/stubs.c @@ -11,6 +11,7 @@ #include #define NDEBUG #include +#include 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 diff --git a/reactos/ntoskrnl/ke/powerpc/thrdini.c b/reactos/ntoskrnl/ke/powerpc/thrdini.c index 74a48011300..d88b5a16722 100644 --- a/reactos/ntoskrnl/ke/powerpc/thrdini.c +++ b/reactos/ntoskrnl/ke/powerpc/thrdini.c @@ -10,9 +10,10 @@ /* INCLUDES ******************************************************************/ #include -#define NDEBUG +//#define NDEBUG #include #include +#include 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 */ diff --git a/reactos/ntoskrnl/mm/powerpc/page.c b/reactos/ntoskrnl/mm/powerpc/page.c index d1ef507deea..c2c8bb59922 100644 --- a/reactos/ntoskrnl/mm/powerpc/page.c +++ b/reactos/ntoskrnl/mm/powerpc/page.c @@ -13,7 +13,7 @@ #include #include -#define NDEBUG +//#define NDEBUG #include #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 */ diff --git a/reactos/ntoskrnl/mm/powerpc/pfault.c b/reactos/ntoskrnl/mm/powerpc/pfault.c index 7efd7139793..ffcdc40c33c 100644 --- a/reactos/ntoskrnl/mm/powerpc/pfault.c +++ b/reactos/ntoskrnl/mm/powerpc/pfault.c @@ -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(); } diff --git a/reactos/tools/nci/ncitool.c b/reactos/tools/nci/ncitool.c index fe1d2ff5d7b..aab45f2f72a 100644 --- a/reactos/tools/nci/ncitool.c +++ b/reactos/tools/nci/ncitool.c @@ -20,618 +20,618 @@ /* DEFINES ****************************************************************/ -#define INPUT_BUFFER_SIZE 255 +#define INPUT_BUFFER_SIZE 255 #define Arguments 7 - -/******* Table Indexes ************/ -#define MAIN_INDEX 0x0 -#define WIN32K_INDEX 0x1000 - -/******* Argument List ************/ -/* First, define the Databases */ -#define NativeSystemDb 0 -#define NativeGuiDb 1 - -/* Now the Service Tables */ -#define NtosServiceTable 2 -#define Win32kServiceTable 3 - -/* And finally, the stub files. */ -#define NtosUserStubs 4 -#define NtosKernelStubs 5 + +/******* Table Indexes ************/ +#define MAIN_INDEX 0x0 +#define WIN32K_INDEX 0x1000 + +/******* Argument List ************/ +/* First, define the Databases */ +#define NativeSystemDb 0 +#define NativeGuiDb 1 + +/* Now the Service Tables */ +#define NtosServiceTable 2 +#define Win32kServiceTable 3 + +/* And finally, the stub files. */ +#define NtosUserStubs 4 +#define NtosKernelStubs 5 #define Win32kStubs 6 - -/********** Stub Code ************/ - -/* - * This stubs calls into KUSER_SHARED_DATA where either a - * sysenter or interrupt is performed, depending on CPU support. - */ -#if defined(__GNUC__) -#define UserModeStub_x86 " movl $0x%x, %%eax\n" \ - " movl $KUSER_SHARED_SYSCALL, %%ecx\n" \ - " call *(%%ecx)\n" \ - " ret $0x%x\n\n" - -#define UserModeStub_ppc " mflr 0\n" \ - " addi 1,1,-16\n" \ - " li 0,%x\n" \ - " stw 0,1(0)\n" \ - " sc\n" \ - " lwz 0,1(0)\n" \ - " mtlr 0\n" \ - " addi 1,1,16\n" \ - " blr\n" - -#define UserModeStub_mips " li $8, KUSER_SHARED_SYSCALL\n" \ - " lw $8,0($8)\n" \ - " j $8\n" \ - " nop\n" - -#elif defined(_MSC_VER) -#define UserModeStub_x86 " asm { \n" \ - " mov eax, %xh\n" \ - " mov ecx, KUSER_SHARED_SYSCALL\n" \ - " call [ecx]\n" \ - " ret %xh\n" \ - " }\n" -#else -#error Unknown compiler for inline assembler -#endif - -/* - * This stub calls KiSystemService directly with a fake INT2E stack. - * Because EIP is pushed during the call, the handler will return here. - */ -#if defined(__GNUC__) -#define KernelModeStub_x86 " movl $0x%x, %%eax\n" \ - " leal 4(%%esp), %%edx\n" \ - " pushfl\n" \ - " pushl $KGDT_R0_CODE\n" \ - " call _KiSystemService\n" \ - " ret $0x%x\n\n" - -#define KernelModeStub_ppc " bl KiSystemService\n" \ - " rfi\n" - -#define KernelModeStub_mips " j KiSystemService\n" \ - " nop\n" - -#elif defined(_MSC_VER) -#define KernelModeStub_x86 " asm { \n" \ - " mov eax, %xh\n" \ - " lea edx, [esp+4]\n" \ - " pushf\n" \ - " push KGDT_R0_CODE\n" \ - " call _KiSystemService\n" \ - " ret %xh\n" \ - " }\n" -#else -#error Unknown compiler for inline assembler -#endif - -/***** Arch Dependent Stuff ******/ -struct ncitool_data_t { - const char *arch; - int args_to_bytes; - const char *km_stub; - const char *um_stub; - const char *global_header; - const char *declaration; -}; - -struct ncitool_data_t ncitool_data[] = { - { "i386", 4, KernelModeStub_x86, UserModeStub_x86, - ".global _%s@%d\n", "_%s@%d:\n" }, - { "powerpc", 4, KernelModeStub_ppc, UserModeStub_ppc, - "\t.globl %s\n", "%s:\n" }, - { "mips", 4, KernelModeStub_mips, UserModeStub_mips, - "\t.globl %s\n", "%s:\n" }, - { 0, } -}; -int arch_sel = 0; -#define ARGS_TO_BYTES(x) (x)*(ncitool_data[arch_sel].args_to_bytes) -#define UserModeStub ncitool_data[arch_sel].um_stub -#define KernelModeStub ncitool_data[arch_sel].km_stub -#define GlobalHeader ncitool_data[arch_sel].global_header -#define Declaration ncitool_data[arch_sel].declaration - -/* FUNCTIONS ****************************************************************/ - -/*++ - * WriteFileHeader - * - * Prints out the File Header for a Stub File. - * - * Params: - * StubFile - Stub File to which to write the header. - * - * FileDescription - Description of the Stub file to which to write the header. - * - * FileLocation - Name of the Stub file to which to write the header. - * - * Returns: - * None. - * - * Remarks: - * FileLocation is only used for printing the header. - * - *--*/ -void -WriteFileHeader(FILE * StubFile, - char* FileDescription, - char* FileLocation) -{ - /* This prints out the file header */ - fprintf(StubFile, - "/* FILE: %s\n" - " * COPYRIGHT: See COPYING in the top level directory\n" - " * PURPOSE: %s\n" - " * PROGRAMMER: Computer Generated File. See tools/nci/ncitool.c\n" - " * REMARK: DO NOT EDIT OR COMMIT MODIFICATIONS TO THIS FILE\n" - " */\n\n\n" - "#include \n\n", - FileDescription, - FileLocation); -} - -/*++ - * WriteFileHeader - * - * Prints out the File Header for a Stub File. - * - * Params: - * StubFile - Stub File to which to write the header. - * - * FileDescription - Description of the Stub file to which to write the header. - * - * FileLocation - Name of the Stub file to which to write the header. - * - * Returns: - * None. - * - * Remarks: - * FileLocation is only used for printing the header. - * - *--*/ -void -WriteStubHeader(FILE* StubFile, - char* SyscallName, - unsigned StackBytes) -{ - /* Export the function */ - fprintf(StubFile, GlobalHeader, SyscallName, StackBytes); - - /* Define it */ - fprintf(StubFile, Declaration, SyscallName, StackBytes); -} - - -/*++ - * WriteKernelModeStub - * - * Prints out the Kernel Mode Stub for a System Call. - * - * Params: - * StubFile - Stub File to which to write the header. - * - * SyscallName - Name of System Call for which to add the stub. - * - * StackBytes - Number of bytes on the stack to return after doing the system call. - * - * SyscallId - Service Descriptor Table ID for this System Call. - * - * Returns: - * None. - * - * Remarks: - * On i386, StackBytes is the number of arguments x 4. - * - *--*/ -void -WriteKernelModeStub(FILE* StubFile, - char* SyscallName, - unsigned StackBytes, - unsigned int SyscallId) -{ - /* Write the Stub Header and export the Function */ - WriteStubHeader(StubFile, SyscallName, StackBytes); - - /* Write the Stub Code */ - fprintf(StubFile, KernelModeStub, SyscallId, StackBytes); -} - -/*++ - * WriteUserModeStub - * - * Prints out the User Mode Stub for a System Call. - * - * Params: - * StubFile - Stub File to which to write the header. - * - * SyscallName - Name of System Call for which to add the stub. - * - * StackBytes - Number of bytes on the stack to return after doing the system call. - * - * SyscallId - Service Descriptor Table ID for this System Call. - * - * Returns: - * None. - * - * Remarks: - * On i386, StackBytes is the number of arguments x 4. - * - *--*/ -void -WriteUserModeStub(FILE* StubFile, - char* SyscallName, - unsigned StackBytes, - unsigned int SyscallId) -{ - /* Write the Stub Header and export the Function */ - WriteStubHeader(StubFile, SyscallName, StackBytes); - - /* Write the Stub Code */ - fprintf(StubFile, UserModeStub, SyscallId, StackBytes); -} - -/*++ - * GetNameAndArgumentsFromDb - * - * Parses an entry from a System Call Database, extracting - * the function's name and arguments that it takes. - * - * Params: - * Line - Entry from the Database to parse. - * - * NtSyscallName - Output string to which to save the Function Name - * - * SyscallArguments - Output string to which to save the number of - * arguments that the function takes. - * - * Returns: - * None. - * - * Remarks: - * On i386, StackBytes is the number of arguments x 4. - * - *--*/ -void -GetNameAndArgumentsFromDb(char Line[], - char ** NtSyscallName, - char ** SyscallArguments) -{ - char *s; - char *stmp; - - /* Remove new line */ - if ((s = (char *) strchr(Line,'\r')) != NULL) { - *s = '\0'; - } - - /* Skip comments (#) and empty lines */ - s = &Line[0]; - if ((*s) != '#' && (*s) != '\0') { - - /* Extract the NtXXX name */ - *NtSyscallName = (char *)strtok(s," \t"); - - /* Extract the argument count */ - *SyscallArguments = (char *)strtok(NULL," \t"); - - /* Remove, if present, the trailing LF */ - if ((stmp = strchr(*SyscallArguments, '\n')) != NULL) { - *stmp = '\0'; - } - - } else { - - /* Skip this entry */ - *NtSyscallName = NULL; - *SyscallArguments = NULL; - } -} - -/*++ - * CreateStubs - * - * Parses a System Call Database and creates stubs for all the entries. - * - * Params: - * SyscallDb - System Call Database to parse. - * - * UserModeFiles - Array of Usermode Stub Files to which to write the stubs. - * - * KernelModeFile - Kernelmode Stub Files to which to write the stubs. - * + +/********** Stub Code ************/ + +/* + * This stubs calls into KUSER_SHARED_DATA where either a + * sysenter or interrupt is performed, depending on CPU support. + */ +#if defined(__GNUC__) +#define UserModeStub_x86 " movl $0x%x, %%eax\n" \ + " movl $KUSER_SHARED_SYSCALL, %%ecx\n" \ + " call *(%%ecx)\n" \ + " ret $0x%x\n\n" + +#define UserModeStub_ppc " stwu 1,-16(1)\n" \ + " mflr 0\n\t" \ + " stw 0,0(1)\n" \ + " li 0,0x%x\n" \ + " sc\n" \ + " lwz 0,0(1)\n" \ + " mtlr 0\n" \ + " addi 1,1,16\n" \ + " blr\n" + +#define UserModeStub_mips " li $8, KUSER_SHARED_SYSCALL\n" \ + " lw $8,0($8)\n" \ + " j $8\n" \ + " nop\n" + +#elif defined(_MSC_VER) +#define UserModeStub_x86 " asm { \n" \ + " mov eax, %xh\n" \ + " mov ecx, KUSER_SHARED_SYSCALL\n" \ + " call [ecx]\n" \ + " ret %xh\n" \ + " }\n" +#else +#error Unknown compiler for inline assembler +#endif + +/* + * This stub calls KiSystemService directly with a fake INT2E stack. + * Because EIP is pushed during the call, the handler will return here. + */ +#if defined(__GNUC__) +#define KernelModeStub_x86 " movl $0x%x, %%eax\n" \ + " leal 4(%%esp), %%edx\n" \ + " pushfl\n" \ + " pushl $KGDT_R0_CODE\n" \ + " call _KiSystemService\n" \ + " ret $0x%x\n\n" + +/* For now, use the usermode stub. We'll optimize later */ +#define KernelModeStub_ppc UserModeStub_ppc + +#define KernelModeStub_mips " j KiSystemService\n" \ + " nop\n" + +#elif defined(_MSC_VER) +#define KernelModeStub_x86 " asm { \n" \ + " mov eax, %xh\n" \ + " lea edx, [esp+4]\n" \ + " pushf\n" \ + " push KGDT_R0_CODE\n" \ + " call _KiSystemService\n" \ + " ret %xh\n" \ + " }\n" +#else +#error Unknown compiler for inline assembler +#endif + +/***** Arch Dependent Stuff ******/ +struct ncitool_data_t { + const char *arch; + int args_to_bytes; + const char *km_stub; + const char *um_stub; + const char *global_header; + const char *declaration; +}; + +struct ncitool_data_t ncitool_data[] = { + { "i386", 4, KernelModeStub_x86, UserModeStub_x86, + ".global _%s@%d\n", "_%s@%d:\n" }, + { "powerpc", 4, KernelModeStub_ppc, UserModeStub_ppc, + "\t.globl %s\n", "%s:\n" }, + { "mips", 4, KernelModeStub_mips, UserModeStub_mips, + "\t.globl %s\n", "%s:\n" }, + { 0, } +}; +int arch_sel = 0; +#define ARGS_TO_BYTES(x) (x)*(ncitool_data[arch_sel].args_to_bytes) +#define UserModeStub ncitool_data[arch_sel].um_stub +#define KernelModeStub ncitool_data[arch_sel].km_stub +#define GlobalHeader ncitool_data[arch_sel].global_header +#define Declaration ncitool_data[arch_sel].declaration + +/* FUNCTIONS ****************************************************************/ + +/*++ + * WriteFileHeader + * + * Prints out the File Header for a Stub File. + * + * Params: + * StubFile - Stub File to which to write the header. + * + * FileDescription - Description of the Stub file to which to write the header. + * + * FileLocation - Name of the Stub file to which to write the header. + * + * Returns: + * None. + * + * Remarks: + * FileLocation is only used for printing the header. + * + *--*/ +void +WriteFileHeader(FILE * StubFile, + char* FileDescription, + char* FileLocation) +{ + /* This prints out the file header */ + fprintf(StubFile, + "/* FILE: %s\n" + " * COPYRIGHT: See COPYING in the top level directory\n" + " * PURPOSE: %s\n" + " * PROGRAMMER: Computer Generated File. See tools/nci/ncitool.c\n" + " * REMARK: DO NOT EDIT OR COMMIT MODIFICATIONS TO THIS FILE\n" + " */\n\n\n" + "#include \n\n", + FileDescription, + FileLocation); +} + +/*++ + * WriteFileHeader + * + * Prints out the File Header for a Stub File. + * + * Params: + * StubFile - Stub File to which to write the header. + * + * FileDescription - Description of the Stub file to which to write the header. + * + * FileLocation - Name of the Stub file to which to write the header. + * + * Returns: + * None. + * + * Remarks: + * FileLocation is only used for printing the header. + * + *--*/ +void +WriteStubHeader(FILE* StubFile, + char* SyscallName, + unsigned StackBytes) +{ + /* Export the function */ + fprintf(StubFile, GlobalHeader, SyscallName, StackBytes); + + /* Define it */ + fprintf(StubFile, Declaration, SyscallName, StackBytes); +} + + +/*++ + * WriteKernelModeStub + * + * Prints out the Kernel Mode Stub for a System Call. + * + * Params: + * StubFile - Stub File to which to write the header. + * + * SyscallName - Name of System Call for which to add the stub. + * + * StackBytes - Number of bytes on the stack to return after doing the system call. + * + * SyscallId - Service Descriptor Table ID for this System Call. + * + * Returns: + * None. + * + * Remarks: + * On i386, StackBytes is the number of arguments x 4. + * + *--*/ +void +WriteKernelModeStub(FILE* StubFile, + char* SyscallName, + unsigned StackBytes, + unsigned int SyscallId) +{ + /* Write the Stub Header and export the Function */ + WriteStubHeader(StubFile, SyscallName, StackBytes); + + /* Write the Stub Code */ + fprintf(StubFile, KernelModeStub, SyscallId, StackBytes); +} + +/*++ + * WriteUserModeStub + * + * Prints out the User Mode Stub for a System Call. + * + * Params: + * StubFile - Stub File to which to write the header. + * + * SyscallName - Name of System Call for which to add the stub. + * + * StackBytes - Number of bytes on the stack to return after doing the system call. + * + * SyscallId - Service Descriptor Table ID for this System Call. + * + * Returns: + * None. + * + * Remarks: + * On i386, StackBytes is the number of arguments x 4. + * + *--*/ +void +WriteUserModeStub(FILE* StubFile, + char* SyscallName, + unsigned StackBytes, + unsigned int SyscallId) +{ + /* Write the Stub Header and export the Function */ + WriteStubHeader(StubFile, SyscallName, StackBytes); + + /* Write the Stub Code */ + fprintf(StubFile, UserModeStub, SyscallId, StackBytes); +} + +/*++ + * GetNameAndArgumentsFromDb + * + * Parses an entry from a System Call Database, extracting + * the function's name and arguments that it takes. + * + * Params: + * Line - Entry from the Database to parse. + * + * NtSyscallName - Output string to which to save the Function Name + * + * SyscallArguments - Output string to which to save the number of + * arguments that the function takes. + * + * Returns: + * None. + * + * Remarks: + * On i386, StackBytes is the number of arguments x 4. + * + *--*/ +void +GetNameAndArgumentsFromDb(char Line[], + char ** NtSyscallName, + char ** SyscallArguments) +{ + char *s; + char *stmp; + + /* Remove new line */ + if ((s = (char *) strchr(Line,'\r')) != NULL) { + *s = '\0'; + } + + /* Skip comments (#) and empty lines */ + s = &Line[0]; + if ((*s) != '#' && (*s) != '\0') { + + /* Extract the NtXXX name */ + *NtSyscallName = (char *)strtok(s," \t"); + + /* Extract the argument count */ + *SyscallArguments = (char *)strtok(NULL," \t"); + + /* Remove, if present, the trailing LF */ + if ((stmp = strchr(*SyscallArguments, '\n')) != NULL) { + *stmp = '\0'; + } + + } else { + + /* Skip this entry */ + *NtSyscallName = NULL; + *SyscallArguments = NULL; + } +} + +/*++ + * CreateStubs + * + * Parses a System Call Database and creates stubs for all the entries. + * + * Params: + * SyscallDb - System Call Database to parse. + * + * UserModeFiles - Array of Usermode Stub Files to which to write the stubs. + * + * KernelModeFile - Kernelmode Stub Files to which to write the stubs. + * * Index - Number of first syscall - * + * * UserFiles - Number of Usermode Stub Files to create - * + * * NeedsZw - Write Zw prefix? - * - * Returns: - * None. - * - * Remarks: - * None. - * - *--*/ -void -CreateStubs(FILE * SyscallDb, - FILE * UserModeFiles[], - FILE * KernelModeFile, - unsigned Index, - unsigned UserFiles, - unsigned NeedsZw) -{ - char Line[INPUT_BUFFER_SIZE]; - char *NtSyscallName; - char *SyscallArguments; - int SyscallId; - unsigned StackBytes; - - /* We loop, incrementing the System Call Index, until the end of the file */ - for (SyscallId = 0; ((!feof(SyscallDb)) && (fgets(Line, sizeof(Line), SyscallDb) != NULL));) { - - /* Extract the Name and Arguments */ - GetNameAndArgumentsFromDb(Line, &NtSyscallName, &SyscallArguments); - if (SyscallArguments != NULL) - StackBytes = ARGS_TO_BYTES(strtoul(SyscallArguments, NULL, 0)); - else - StackBytes = 0; - - /* Make sure we really extracted something */ - if (NtSyscallName) { - - /* Create Usermode Stubs for Nt/Zw syscalls in each Usermode file */ - int i; - for (i= 0; i < UserFiles; i++) { - - /* Write the Nt Version */ - WriteUserModeStub(UserModeFiles[i], - NtSyscallName, - StackBytes, - SyscallId | Index); - - /* If a Zw Version is needed (was specified), write it too */ - if (NeedsZw) { - - NtSyscallName[0] = 'Z'; - NtSyscallName[1] = 'w'; - WriteUserModeStub(UserModeFiles[i], - NtSyscallName, - StackBytes, - SyscallId | Index); - } - - } - - /* Create the Kernel coutnerparts (only Zw*, Nt* are the real functions!) */ - if (KernelModeFile) { - - NtSyscallName[0] = 'Z'; - NtSyscallName[1] = 'w'; - WriteKernelModeStub(KernelModeFile, - NtSyscallName, - StackBytes, - SyscallId | Index); - } - - /* Only increase if we actually added something */ - SyscallId++; - } - } -} - -/*++ - * CreateSystemServiceTable - * - * Parses a System Call Database and creates a System Call Service Table for it. - * - * Params: - * SyscallDb - System Call Database to parse. - * - * SyscallTable - File in where to create System Call Service Table. - * - * Name - Name of the Service Table. - * - * FileLocation - Filename containing the Table. - * - * Returns: - * None. - * - * Remarks: - * FileLocation is only used for the header generation. - * - *--*/ -void -CreateSystemServiceTable(FILE *SyscallDb, - FILE *SyscallTable, - char * Name, - char * FileLocation) -{ - char Line[INPUT_BUFFER_SIZE]; - char *NtSyscallName; - char *SyscallArguments; - int SyscallId; - - /* Print the Header */ - WriteFileHeader(SyscallTable, "System Call Table for Native API", FileLocation); - - /* First we build the SSDT */ - fprintf(SyscallTable,"\n\n\n"); - fprintf(SyscallTable,"ULONG_PTR %sSSDT[] = {\n", Name); - - /* We loop, incrementing the System Call Index, until the end of the file */ - for (SyscallId = 0; ((!feof(SyscallDb)) && (fgets(Line, sizeof(Line), SyscallDb) != NULL));) { - - /* Extract the Name and Arguments */ - GetNameAndArgumentsFromDb(Line, &NtSyscallName, &SyscallArguments); - - /* Make sure we really extracted something */ - if (NtSyscallName) { - - /* Add a new line */ - if (SyscallId > 0) fprintf(SyscallTable,",\n"); - - /* Write the syscall name in the service table. */ - fprintf(SyscallTable,"\t\t(ULONG_PTR)%s", NtSyscallName); - - /* Only increase if we actually added something */ - SyscallId++; - } - } - - /* Close the service table (C syntax) */ - fprintf(SyscallTable,"\n};\n"); - - /* Now we build the SSPT */ - rewind(SyscallDb); - fprintf(SyscallTable,"\n\n\n"); - fprintf(SyscallTable,"UCHAR %sSSPT[] = {\n", Name); - - for (SyscallId = 0; ((!feof(SyscallDb)) && (fgets(Line, sizeof(Line), SyscallDb) != NULL));) { - - /* Extract the Name and Arguments */ - GetNameAndArgumentsFromDb(Line, &NtSyscallName, &SyscallArguments); - - /* Make sure we really extracted something */ - if (NtSyscallName) { - - /* Add a new line */ - if (SyscallId > 0) fprintf(SyscallTable,",\n"); - - /* Write the syscall arguments in the argument table. */ - if (SyscallArguments != NULL) - fprintf(SyscallTable,"\t\t%lu * sizeof(void *)",strtoul(SyscallArguments, NULL, 0)); - else - fprintf(SyscallTable,"\t\t0"); - - /* Only increase if we actually added something */ - SyscallId++; - } - } - - /* Close the service table (C syntax) */ - fprintf(SyscallTable,"\n};\n"); - - /* - * We write some useful defines - */ - fprintf(SyscallTable, "\n\n#define MIN_SYSCALL_NUMBER 0\n"); - fprintf(SyscallTable, "#define MAX_SYSCALL_NUMBER %d\n", SyscallId - 1); - fprintf(SyscallTable, "#define NUMBER_OF_SYSCALLS %d\n", SyscallId); - fprintf(SyscallTable, "ULONG %sNumberOfSysCalls = %d;\n", Name, SyscallId); -} - -void usage(char * argv0) -{ - printf("Usage: %s [-arch ] sysfuncs.lst w32ksvc.db napi.h ssdt.h napi.S zw.S win32k.S win32k.S\n" - " sysfuncs.lst native system functions database\n" - " w32ksvc.db native graphic functions database\n" - " napi.h NTOSKRNL service table\n" - " ssdt.h WIN32K service table\n" - " napi.S NTDLL stubs\n" - " zw.S NTOSKRNL Zw stubs\n" - " win32k.S GDI32 stubs\n" - " win32k.S USER32 stubs\n" - " -arch is optional, default is %s\n", - argv0, - ncitool_data[0].arch - ); -} - -int main(int argc, char* argv[]) -{ - FILE * Files[Arguments] = { }; - int FileNumber, ArgOffset = 1; - char * OpenType = "r"; - - /* Catch architecture argument */ - if (argc > 3 && !strcmp(argv[1],"-arch")) { - for( arch_sel = 0; ncitool_data[arch_sel].arch; arch_sel++ ) - if (strcmp(argv[2],ncitool_data[arch_sel].arch) == 0) - break; - if (!ncitool_data[arch_sel].arch) { - printf("Invalid arch '%s'\n", argv[2]); - usage(argv[0]); - return 1; - } - ArgOffset = 3; - } - /* Make sure all arguments all there */ - if (argc != Arguments + ArgOffset) { - usage(argv[0]); - return(1); - } - - /* Open all Output and bail out if any fail */ - for (FileNumber = 0; FileNumber < Arguments; FileNumber++) { - - /* Open the File */ - if (FileNumber == 2) OpenType = "wb"; - Files[FileNumber] = fopen(argv[FileNumber + ArgOffset], OpenType); - - /* Check for failure and error out if so */ - if (!Files[FileNumber]) { - perror(argv[FileNumber + ArgOffset]); - return (1); - } - } - - /* Write the File Headers */ - WriteFileHeader(Files[NtosUserStubs], - "System Call Stubs for Native API", - argv[NtosUserStubs + ArgOffset]); - - WriteFileHeader(Files[NtosKernelStubs], - "System Call Stubs for Native API", - argv[NtosKernelStubs + ArgOffset]); - fputs("#include \n\n", Files[NtosKernelStubs]); - + * + * Returns: + * None. + * + * Remarks: + * None. + * + *--*/ +void +CreateStubs(FILE * SyscallDb, + FILE * UserModeFiles[], + FILE * KernelModeFile, + unsigned Index, + unsigned UserFiles, + unsigned NeedsZw) +{ + char Line[INPUT_BUFFER_SIZE]; + char *NtSyscallName; + char *SyscallArguments; + int SyscallId; + unsigned StackBytes; + + /* We loop, incrementing the System Call Index, until the end of the file */ + for (SyscallId = 0; ((!feof(SyscallDb)) && (fgets(Line, sizeof(Line), SyscallDb) != NULL));) { + + /* Extract the Name and Arguments */ + GetNameAndArgumentsFromDb(Line, &NtSyscallName, &SyscallArguments); + if (SyscallArguments != NULL) + StackBytes = ARGS_TO_BYTES(strtoul(SyscallArguments, NULL, 0)); + else + StackBytes = 0; + + /* Make sure we really extracted something */ + if (NtSyscallName) { + + /* Create Usermode Stubs for Nt/Zw syscalls in each Usermode file */ + int i; + for (i= 0; i < UserFiles; i++) { + + /* Write the Nt Version */ + WriteUserModeStub(UserModeFiles[i], + NtSyscallName, + StackBytes, + SyscallId | Index); + + /* If a Zw Version is needed (was specified), write it too */ + if (NeedsZw) { + + NtSyscallName[0] = 'Z'; + NtSyscallName[1] = 'w'; + WriteUserModeStub(UserModeFiles[i], + NtSyscallName, + StackBytes, + SyscallId | Index); + } + + } + + /* Create the Kernel coutnerparts (only Zw*, Nt* are the real functions!) */ + if (KernelModeFile) { + + NtSyscallName[0] = 'Z'; + NtSyscallName[1] = 'w'; + WriteKernelModeStub(KernelModeFile, + NtSyscallName, + StackBytes, + SyscallId | Index); + } + + /* Only increase if we actually added something */ + SyscallId++; + } + } +} + +/*++ + * CreateSystemServiceTable + * + * Parses a System Call Database and creates a System Call Service Table for it. + * + * Params: + * SyscallDb - System Call Database to parse. + * + * SyscallTable - File in where to create System Call Service Table. + * + * Name - Name of the Service Table. + * + * FileLocation - Filename containing the Table. + * + * Returns: + * None. + * + * Remarks: + * FileLocation is only used for the header generation. + * + *--*/ +void +CreateSystemServiceTable(FILE *SyscallDb, + FILE *SyscallTable, + char * Name, + char * FileLocation) +{ + char Line[INPUT_BUFFER_SIZE]; + char *NtSyscallName; + char *SyscallArguments; + int SyscallId; + + /* Print the Header */ + WriteFileHeader(SyscallTable, "System Call Table for Native API", FileLocation); + + /* First we build the SSDT */ + fprintf(SyscallTable,"\n\n\n"); + fprintf(SyscallTable,"ULONG_PTR %sSSDT[] = {\n", Name); + + /* We loop, incrementing the System Call Index, until the end of the file */ + for (SyscallId = 0; ((!feof(SyscallDb)) && (fgets(Line, sizeof(Line), SyscallDb) != NULL));) { + + /* Extract the Name and Arguments */ + GetNameAndArgumentsFromDb(Line, &NtSyscallName, &SyscallArguments); + + /* Make sure we really extracted something */ + if (NtSyscallName) { + + /* Add a new line */ + if (SyscallId > 0) fprintf(SyscallTable,",\n"); + + /* Write the syscall name in the service table. */ + fprintf(SyscallTable,"\t\t(ULONG_PTR)%s", NtSyscallName); + + /* Only increase if we actually added something */ + SyscallId++; + } + } + + /* Close the service table (C syntax) */ + fprintf(SyscallTable,"\n};\n"); + + /* Now we build the SSPT */ + rewind(SyscallDb); + fprintf(SyscallTable,"\n\n\n"); + fprintf(SyscallTable,"UCHAR %sSSPT[] = {\n", Name); + + for (SyscallId = 0; ((!feof(SyscallDb)) && (fgets(Line, sizeof(Line), SyscallDb) != NULL));) { + + /* Extract the Name and Arguments */ + GetNameAndArgumentsFromDb(Line, &NtSyscallName, &SyscallArguments); + + /* Make sure we really extracted something */ + if (NtSyscallName) { + + /* Add a new line */ + if (SyscallId > 0) fprintf(SyscallTable,",\n"); + + /* Write the syscall arguments in the argument table. */ + if (SyscallArguments != NULL) + fprintf(SyscallTable,"\t\t%lu * sizeof(void *)",strtoul(SyscallArguments, NULL, 0)); + else + fprintf(SyscallTable,"\t\t0"); + + /* Only increase if we actually added something */ + SyscallId++; + } + } + + /* Close the service table (C syntax) */ + fprintf(SyscallTable,"\n};\n"); + + /* + * We write some useful defines + */ + fprintf(SyscallTable, "\n\n#define MIN_SYSCALL_NUMBER 0\n"); + fprintf(SyscallTable, "#define MAX_SYSCALL_NUMBER %d\n", SyscallId - 1); + fprintf(SyscallTable, "#define NUMBER_OF_SYSCALLS %d\n", SyscallId); + fprintf(SyscallTable, "ULONG %sNumberOfSysCalls = %d;\n", Name, SyscallId); +} + +void usage(char * argv0) +{ + printf("Usage: %s [-arch ] sysfuncs.lst w32ksvc.db napi.h ssdt.h napi.S zw.S win32k.S win32k.S\n" + " sysfuncs.lst native system functions database\n" + " w32ksvc.db native graphic functions database\n" + " napi.h NTOSKRNL service table\n" + " ssdt.h WIN32K service table\n" + " napi.S NTDLL stubs\n" + " zw.S NTOSKRNL Zw stubs\n" + " win32k.S GDI32 stubs\n" + " win32k.S USER32 stubs\n" + " -arch is optional, default is %s\n", + argv0, + ncitool_data[0].arch + ); +} + +int main(int argc, char* argv[]) +{ + FILE * Files[Arguments] = { }; + int FileNumber, ArgOffset = 1; + char * OpenType = "r"; + + /* Catch architecture argument */ + if (argc > 3 && !strcmp(argv[1],"-arch")) { + for( arch_sel = 0; ncitool_data[arch_sel].arch; arch_sel++ ) + if (strcmp(argv[2],ncitool_data[arch_sel].arch) == 0) + break; + if (!ncitool_data[arch_sel].arch) { + printf("Invalid arch '%s'\n", argv[2]); + usage(argv[0]); + return 1; + } + ArgOffset = 3; + } + /* Make sure all arguments all there */ + if (argc != Arguments + ArgOffset) { + usage(argv[0]); + return(1); + } + + /* Open all Output and bail out if any fail */ + for (FileNumber = 0; FileNumber < Arguments; FileNumber++) { + + /* Open the File */ + if (FileNumber == 2) OpenType = "wb"; + Files[FileNumber] = fopen(argv[FileNumber + ArgOffset], OpenType); + + /* Check for failure and error out if so */ + if (!Files[FileNumber]) { + perror(argv[FileNumber + ArgOffset]); + return (1); + } + } + + /* Write the File Headers */ + WriteFileHeader(Files[NtosUserStubs], + "System Call Stubs for Native API", + argv[NtosUserStubs + ArgOffset]); + + WriteFileHeader(Files[NtosKernelStubs], + "System Call Stubs for Native API", + argv[NtosKernelStubs + ArgOffset]); + fputs("#include \n\n", Files[NtosKernelStubs]); + WriteFileHeader(Files[Win32kStubs], - "System Call Stubs for Native API", + "System Call Stubs for Native API", argv[Win32kStubs + ArgOffset]); - - /* Create the System Stubs */ - CreateStubs(Files[NativeSystemDb], - &Files[NtosUserStubs], - Files[NtosKernelStubs], - MAIN_INDEX, - 1, - 1); - - /* Create the Graphics Stubs */ - CreateStubs(Files[NativeGuiDb], - &Files[Win32kStubs], - NULL, - WIN32K_INDEX, + + /* Create the System Stubs */ + CreateStubs(Files[NativeSystemDb], + &Files[NtosUserStubs], + Files[NtosKernelStubs], + MAIN_INDEX, 1, - 0); - - /* Rewind the databases */ - rewind(Files[NativeSystemDb]); - rewind(Files[NativeGuiDb]); - - /* Create the Service Tables */ - CreateSystemServiceTable(Files[NativeSystemDb], - Files[NtosServiceTable], - "Main", - argv[NtosServiceTable + ArgOffset]); - - CreateSystemServiceTable(Files[NativeGuiDb], - Files[Win32kServiceTable], - "Win32k", - argv[Win32kServiceTable + ArgOffset]); - - /* Close all files */ - for (FileNumber = 0; FileNumber < Arguments-ArgOffset; FileNumber++) { - - /* Close the File */ - fclose(Files[FileNumber]); - - } - - return(0); -} + 1); + + /* Create the Graphics Stubs */ + CreateStubs(Files[NativeGuiDb], + &Files[Win32kStubs], + NULL, + WIN32K_INDEX, + 1, + 0); + + /* Rewind the databases */ + rewind(Files[NativeSystemDb]); + rewind(Files[NativeGuiDb]); + + /* Create the Service Tables */ + CreateSystemServiceTable(Files[NativeSystemDb], + Files[NtosServiceTable], + "Main", + argv[NtosServiceTable + ArgOffset]); + + CreateSystemServiceTable(Files[NativeGuiDb], + Files[Win32kServiceTable], + "Win32k", + argv[Win32kServiceTable + ArgOffset]); + + /* Close all files */ + for (FileNumber = 0; FileNumber < Arguments-ArgOffset; FileNumber++) { + + /* Close the File */ + fclose(Files[FileNumber]); + + } + + return(0); +}