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/…
==============================================================================
--- 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?…
==============================================================================
--- 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/ppcmm…
==============================================================================
--- 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=31…
==============================================================================
--- 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@ha
addi 8,8,_mmumain@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=31…
==============================================================================
--- 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…
==============================================================================
--- 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?re…
==============================================================================
--- 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/ctxhel…
==============================================================================
--- 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@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 @@
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)
+ .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,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/ctxswi…
==============================================================================
--- 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?…
==============================================================================
--- 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…
==============================================================================
--- 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@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 @@
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_ir…
==============================================================================
--- 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.…
==============================================================================
--- 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/thrdin…
==============================================================================
--- 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…
==============================================================================
--- 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…
==============================================================================
--- 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=31…
==============================================================================
--- 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);
+}