[ros-diffs] [arty] 31953: Page fault, system calls, context switches debugged. Heaps, system calls, context switches all functional.

arty at svn.reactos.org arty at svn.reactos.org
Wed Jan 23 01:43:40 CET 2008


Author: arty
Date: Wed Jan 23 03:43:39 2008
New Revision: 31953

URL: http://svn.reactos.org/svn/reactos?rev=31953&view=rev
Log:
Page fault, system calls, context switches debugged.
Heaps, system calls, context switches all functional.

Modified:
    trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c
    trunk/reactos/include/psdk/intrin_ppc.h
    trunk/reactos/include/reactos/libs/ppcmmu/mmu.h
    trunk/reactos/lib/ppcmmu/devint.s
    trunk/reactos/lib/ppcmmu/gdblib.c
    trunk/reactos/lib/ppcmmu/mmuobject.c
    trunk/reactos/lib/rtl/powerpc/debug.c
    trunk/reactos/ntoskrnl/ke/powerpc/ctxhelp.S
    trunk/reactos/ntoskrnl/ke/powerpc/ctxswitch.c
    trunk/reactos/ntoskrnl/ke/powerpc/exp.c
    trunk/reactos/ntoskrnl/ke/powerpc/kiinit.c
    trunk/reactos/ntoskrnl/ke/powerpc/ppc_irq.c
    trunk/reactos/ntoskrnl/ke/powerpc/stubs.c
    trunk/reactos/ntoskrnl/ke/powerpc/thrdini.c
    trunk/reactos/ntoskrnl/mm/powerpc/page.c
    trunk/reactos/ntoskrnl/mm/powerpc/pfault.c
    trunk/reactos/tools/nci/ncitool.c

Modified: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c Wed Jan 23 03:43:39 2008
@@ -223,23 +223,8 @@
                     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 @@
         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++ ) {

Modified: trunk/reactos/include/psdk/intrin_ppc.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/intrin_ppc.h?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/reactos/include/psdk/intrin_ppc.h (original)
+++ trunk/reactos/include/psdk/intrin_ppc.h Wed Jan 23 03:43:39 2008
@@ -146,58 +146,63 @@
 
 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)
-{
-    return 0;
+PPC_QUAL long long _InterlockedCompareExchange64(volatile long long * const Target, const long long Exchange, const long long Comperand)
+{
+    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 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;
-}
-
-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;
+    return (void *)_InterlockedExchange((long *)Target, (long)Value);
+}
+
+#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 @@
 	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 @@
 	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);

Modified: trunk/reactos/include/reactos/libs/ppcmmu/mmu.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/ppcmmu/mmu.h?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/reactos/include/reactos/libs/ppcmmu/mmu.h (original)
+++ trunk/reactos/include/reactos/libs/ppcmmu/mmu.h Wed Jan 23 03:43:39 2008
@@ -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_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 @@
     PPCMMU(0x100, 0, 0, 0);
 }
 
-static inline void MmuMapPage(ppc_map_info_t *info, int count)
-{
-    PPCMMU(0x101, info, (void *)count, 0);
+static inline int MmuMapPage(ppc_map_info_t *info, int count)
+{
+    return PPCMMU(0x101, info, (void *)count, 0);
 }
 
 static inline void MmuUnmapPage(ppc_map_info_t *info, int count)
@@ -243,6 +249,21 @@
     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);

Modified: trunk/reactos/lib/ppcmmu/devint.s
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/ppcmmu/devint.s?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/reactos/lib/ppcmmu/devint.s (original)
+++ trunk/reactos/lib/ppcmmu/devint.s Wed Jan 23 03:43:39 2008
@@ -47,14 +47,12 @@
 	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 */
+	mfdar 0
 	stw 0,424(1)
-	mfdsisr 0
+        mfxer 0
 	stw 0,428(1)
-        mfdar 0
-        stw 0,432(1)
         addi 7,1,16
         lis 8,_mmumain at ha
         addi 8,8,_mmumain at l
@@ -151,14 +149,12 @@
 	stw 0,412(1)
 	mfctr 0
 	stw 0,416(1)
+        mfdsisr 0
+	stw 0,420(1)
+        mfdar 0
+	stw 0,424(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,428(1)
-        mfdar 0
-        stw 0,432(1)
         bl 1f
 1:      mflr 5
         addi 4,1,16
@@ -216,11 +212,11 @@
         lwz 0,400(1)
         mtctr 0
         lwz 0,404(1)
+        mtdsisr 0
+        lwz 0,412(1)
+        mtdar 0
+        lwz 0,416(1)
         mtxer 0
-        lwz 0,412(1)
-        mtdsisr 0
-        lwz 0,416(1)
-        mtdar 0
         lwz 0,0(1)
 	lwz 1,4(1)
 	rfi

Modified: trunk/reactos/lib/ppcmmu/gdblib.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/ppcmmu/gdblib.c?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/reactos/lib/ppcmmu/gdblib.c (original)
+++ trunk/reactos/lib/ppcmmu/gdblib.c Wed Jan 23 03:43:39 2008
@@ -85,6 +85,8 @@
  ****************************************************************************/
 
 #include "ppcmmu/mmu.h"
+
+#define GDB_SAVE_SIZE 0x66
 
 typedef struct _BREAKPOINT {
     int OldCode;
@@ -137,7 +139,7 @@
 	/* 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 @@
     {
     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 @@
             Continue = 0;
             PacketWriteSignal(3);
         }
-        else if (ch == '-' || ch == '+')
+        else if (ch == '+')
         {
             /* Nothing */
         }

Modified: trunk/reactos/lib/ppcmmu/mmuobject.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/ppcmmu/mmuobject.c?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/reactos/lib/ppcmmu/mmuobject.c (original)
+++ trunk/reactos/lib/ppcmmu/mmuobject.c Wed Jan 23 03:43:39 2008
@@ -39,6 +39,8 @@
 10 alloc vsid
 11 revoke vsid
 */
+
+#define MMU_ADDR_RESERVED ((vaddr_t)-2)
 
 MmuTrapHandler callback[0x30];
 typedef struct _MmuFreePage {
@@ -56,7 +58,7 @@
     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 @@
 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 @@
     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 @@
     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 @@
     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 @@
      * 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,9 +205,30 @@
     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)
@@ -252,7 +290,7 @@
     {
 	RamSize = ramsize;
 	FirstUsablePage = (paddr_t)last_map;
-	NextPage = PPC_PAGE_NUMBER(FirstUsablePage);
+	NextPage = PPC_PAGE_NUMBER(FirstUsablePage) + 1;
     }
 }
 
@@ -301,7 +339,7 @@
     }
 
     /* Serial Interrupt */
-    callback[5] = SerialInterrupt;
+    callback[5] = 0; /* Do nothing until the user asks */
 
     /* Program Exception */
     callback[6] = (MmuTrapHandler)TakeException;
@@ -320,12 +358,40 @@
 {
     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;
+        }
     }
 }
 
@@ -437,6 +503,9 @@
 
     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 @@
 	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;
@@ -476,6 +554,13 @@
 	__asm__("tlbie %0\n\tsync\n\tisync" : : "r" (iva));
     }
     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)
@@ -553,9 +638,9 @@
 	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);
@@ -569,6 +654,12 @@
 	    }
 	}
     }
+}
+
+int mmuisfreepage(paddr_t pageno)
+{
+    ppc_map_t *PagePtr = PpcPageTable + pageno;
+    return !PagePtr->addr;
 }
 
 void mmusetvsid(int start, int end, int vsid)
@@ -603,6 +694,52 @@
     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;

Modified: trunk/reactos/lib/rtl/powerpc/debug.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/powerpc/debug.c?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/reactos/lib/rtl/powerpc/debug.c (original)
+++ trunk/reactos/lib/rtl/powerpc/debug.c Wed Jan 23 03:43:39 2008
@@ -15,12 +15,12 @@
 (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) :

Modified: trunk/reactos/ntoskrnl/ke/powerpc/ctxhelp.S
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/powerpc/ctxhelp.S?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/powerpc/ctxhelp.S (original)
+++ trunk/reactos/ntoskrnl/ke/powerpc/ctxhelp.S Wed Jan 23 03:43:39 2008
@@ -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 at ha
+	addi 1,1,KiSystemService1 at 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 at ha
-        addi 3,3,KiSystemService at 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 at ha
-        addi 1,1,_kernel_trap_stack at 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 @@
         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 at ha
-        addi 3,3,KiDecrementerTrap at l
+        lis 3,KiSystemService at ha
+        addi 3,3,KiSystemService at l
         mtctr 3
-        lis 3,KiDecrementerTrapFinish at ha
-        addi 3,3,KiDecrementerTrapFinish at 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 at ha
+        addi 1,1,KiDecrementerTrapUpper at 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)
+        .globl KiDecrementerTrapUpper
+        .align 8
+KiDecrementerTrapUpper:
+        lis 1,_kernel_trap_stack at ha
+        addi 1,1,_kernel_trap_stack at 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,0x114(1)
         mtsrr0 0
-        lwz 0,128(1)
+        lwz 0,0x118(1)
         mtlr 0
-        lwz 0,136(1)
+        lwz 0,0x11c(1)
         mtctr 0
-        lwz 0,144(1)
-        mtsrr1 0
-        lwz 0,148(1)
-        mtdsisr 0
-        lwz 0,152(1)
-        mtdar 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

Modified: trunk/reactos/ntoskrnl/ke/powerpc/ctxswitch.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/powerpc/ctxswitch.c?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/powerpc/ctxswitch.c (original)
+++ trunk/reactos/ntoskrnl/ke/powerpc/ctxswitch.c Wed Jan 23 03:43:39 2008
@@ -13,6 +13,7 @@
 #include <ntoskrnl.h>
 #define NDEBUG
 #include <debug.h>
+#include <ppcmmu/mmu.h>
 
 /*++
  * KiThreadStartup
@@ -53,7 +54,7 @@
                 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 @@
 
 /* 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
 }

Modified: trunk/reactos/ntoskrnl/ke/powerpc/exp.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/powerpc/exp.c?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/powerpc/exp.c (original)
+++ trunk/reactos/ntoskrnl/ke/powerpc/exp.c Wed Jan 23 03:43:39 2008
@@ -13,6 +13,7 @@
 #include <ntoskrnl.h>
 #define NDEBUG
 #include <debug.h>
+#include <ppcmmu/mmu.h>
 
 /* FUNCTIONS *****************************************************************/
 
@@ -100,6 +101,10 @@
                     IN KPROCESSOR_MODE PreviousMode,
                     IN BOOLEAN FirstChance)
 {
+    DbgPrint("EXCEPTION! Record %08x Frame %08x\n", 
+             ExceptionRecord, ExceptionFrame);
+    MmuDumpMap();
+    KEBUGCHECK(0);
 }
 
 /*

Modified: trunk/reactos/ntoskrnl/ke/powerpc/kiinit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/powerpc/kiinit.c?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/powerpc/kiinit.c (original)
+++ trunk/reactos/ntoskrnl/ke/powerpc/kiinit.c Wed Jan 23 03:43:39 2008
@@ -11,7 +11,7 @@
 
 #include <ntoskrnl.h>
 
-#define NDEBUG
+//#define NDEBUG
 #include <debug.h>
 #include "ppcmmu/mmu.h"
 
@@ -30,28 +30,11 @@
 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 at ha\n\t"
-	"addi 1,1,KiSystemService1 at l\n\t"
-	"mfsrr0 0\n\t"
-	"mtsrr0 1\n\t"
-	"lis 1,_kernel_trap_stack at ha\n\t"
-	"addi 1,1,_kernel_trap_stack at 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 @@
         source++, handler_target += sizeof(int))
         SetPhys(handler_target, *source);
 
+    DPRINT("CurrentThread %08x IdleThread %08x\n",
+           KeGetCurrentThread(), KeGetCurrentPrcb()->IdleThread);
+
+    /* Kick decmrenter! */
+    __asm__("mtdec %0" : : "r" (0));
+
     /* Enable interrupts! */
     _enable();
-
-    /* Kick decmrenter! */
-    __asm__("mtdec %0" : : "r" (0));
 }
 
 VOID
@@ -111,6 +97,7 @@
     Pcr->PrcbData->BuildType = 0;
 #endif
     Pcr->PrcbData->DpcStack = DpcStack;
+    KeGetPcr()->Prcb = Pcr->PrcbData;
     KiProcessorBlock[ProcessorNumber] = Pcr->PrcbData;
 }
 
@@ -219,27 +206,22 @@
             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 @@
     /* Free Initial Memory */
     // MiFreeInitMemory();
 
-    DPRINT1("\n");
+    KfRaiseIrql(DISPATCH_LEVEL);
+    
+    KeSetPriorityThread(InitThread, 0);
     /* Setup decrementer exception */
     KiSetupDecrementerTrap();
 
-    DPRINT1("\n");
-    while (1)
-    {
-        LARGE_INTEGER Timeout;
-        Timeout.QuadPart = 0x7fffffffffffffffLL;
-        DPRINT1("\n");
-        KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
-    }
-}
-
-extern int KiPageFaultHandler(int trap, ppc_trap_frame_t *frame);
+    KfLowerIrql(PASSIVE_LEVEL);
+
+    /* Should not return */
+    while(1)
+    {
+        NtYieldExecution();
+    }
+}
+
+extern int KiPageFaultTrap();
+KTRAP_FRAME KiInitialTrapFrame;
 
 /* Use this for early boot additions to the page table */
 VOID
@@ -278,8 +262,8 @@
     __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 @@
 
     /* Set us as the current process */
     KiInitialThread.Tcb.ApcState.Process = &KiInitialProcess.Pcb;
+    KiInitialThread.Tcb.TrapFrame = &KiInitialTrapFrame;
 
     /* Setup CPU-related fields */
 AppCpuInit:

Modified: trunk/reactos/ntoskrnl/ke/powerpc/ppc_irq.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/powerpc/ppc_irq.c?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/powerpc/ppc_irq.c (original)
+++ trunk/reactos/ntoskrnl/ke/powerpc/ppc_irq.c Wed Jan 23 03:43:39 2008
@@ -751,14 +751,18 @@
 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;
-
-    switch(trap_frame->gpr[8])
+    PSYSCALL_FUN SyscallFunction;
+
+    switch(trap_frame->gpr[0])
     {
     case 0x10000: /* DebugService */
 	for( i = 0; i < trap_frame->gpr[5]; i++ )
@@ -777,6 +781,24 @@
         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;
     }
 }
 

Modified: trunk/reactos/ntoskrnl/ke/powerpc/stubs.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/powerpc/stubs.c?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/powerpc/stubs.c (original)
+++ trunk/reactos/ntoskrnl/ke/powerpc/stubs.c Wed Jan 23 03:43:39 2008
@@ -11,6 +11,7 @@
 #include <ntoskrnl.h>
 #define NDEBUG
 #include <debug.h>
+#include <ppcmmu/mmu.h>
 
 NTSTATUS
 NTAPI
@@ -137,13 +138,17 @@
 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

Modified: trunk/reactos/ntoskrnl/ke/powerpc/thrdini.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/powerpc/thrdini.c?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/powerpc/thrdini.c (original)
+++ trunk/reactos/ntoskrnl/ke/powerpc/thrdini.c Wed Jan 23 03:43:39 2008
@@ -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 @@
 {
     KSWITCHFRAME CtxSwitchFrame;
     KSTART_FRAME StartFrame;
+    KTRAP_FRAME TrapFrame;
     FX_SAVE_AREA FxSaveArea;
 } KKINIT_FRAME, *PKKINIT_FRAME;
 
@@ -60,7 +62,17 @@
     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 @@
 
         /* 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 @@
 
         /* 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 @@
 
     /* 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 */

Modified: trunk/reactos/ntoskrnl/mm/powerpc/page.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/powerpc/page.c?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/powerpc/page.c (original)
+++ trunk/reactos/ntoskrnl/mm/powerpc/page.c Wed Jan 23 03:43:39 2008
@@ -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 @@
 {
     PEPROCESS CurrentProcess = PsGetCurrentProcess();
 
-    if(!CurrentProcess) return;
-
-    MmuRevokeVsid((paddr_t)Process->UniqueProcessId, -1);
+    DPRINT1("DeletePageTable: Process: %x CurrentProcess %x\n", 
+            Process, CurrentProcess);
+
+    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 @@
     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 @@
     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 @@
 {
 }
 
+/* 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 */

Modified: trunk/reactos/ntoskrnl/mm/powerpc/pfault.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/powerpc/pfault.c?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/powerpc/pfault.c (original)
+++ trunk/reactos/ntoskrnl/mm/powerpc/pfault.c Wed Jan 23 03:43:39 2008
@@ -33,14 +33,23 @@
     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 @@
 	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 @@
     }
 
     if (NT_SUCCESS(Status))
-	return 1;
+    {
+        MmuCallbackRet();
+    }
 
     if (KeGetCurrentThread()->ApcState.UserApcPending)
     {
@@ -95,6 +107,6 @@
     Er.ExceptionFlags = 0;
 
     KiDispatchException(&Er, 0, &Tf, Mode, TRUE);
-    return 1;
+    MmuCallbackRet();
 }
 

Modified: trunk/reactos/tools/nci/ncitool.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/nci/ncitool.c?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/reactos/tools/nci/ncitool.c (original)
+++ trunk/reactos/tools/nci/ncitool.c Wed Jan 23 03:43:39 2008
@@ -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 <ndk/asm.h>\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 <ndk/asm.h>\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 <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 <ndk/asm.h>\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 <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 <ndk/asm.h>\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], 
+
+    /* 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, 
+                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);
-}
+                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);
+}




More information about the Ros-diffs mailing list