diff --git a/reactos/include/ndk/powerpc/ketypes.h b/reactos/include/ndk/powerpc/ketypes.h index 4d870b34b8d..f8f29a407f5 100644 --- a/reactos/include/ndk/powerpc/ketypes.h +++ b/reactos/include/ndk/powerpc/ketypes.h @@ -46,7 +46,12 @@ typedef double DOUBLE; typedef struct _FX_SAVE_AREA { ULONG Fr[32]; -} FX_SAVE_AREA; +} FX_SAVE_AREA, *PFX_SAVE_AREA; + +typedef struct _FXSAVE_FORMAT +{ + ULONG Xer,Fpscr; +} FXSAVE_FORMAT, *PFXSAVE_FORMAT; typedef struct _LDT_ENTRY { USHORT LimitLow; diff --git a/reactos/ntoskrnl/include/internal/i386/ke.h b/reactos/ntoskrnl/include/internal/i386/ke.h index a8feb0d99d7..0f09dd192f1 100644 --- a/reactos/ntoskrnl/include/internal/i386/ke.h +++ b/reactos/ntoskrnl/include/internal/i386/ke.h @@ -133,6 +133,8 @@ Ke386InitThreadWithContext(PKTHREAD Thread, PKSTART_ROUTINE StartRoutine, PVOID StartContext, PCONTEXT Context); +#define KeArchInitThreadWithContext(Thread,SystemRoutine,StartRoutine,StartContext,Context) \ + Ke386InitThreadWithContext(Thread,SystemRoutine,StartRoutine,StartContext,Context) #ifdef _NTOSKRNL_ /* FIXME: Move flags above to NDK instead of here */ VOID diff --git a/reactos/ntoskrnl/include/internal/powerpc/ke.h b/reactos/ntoskrnl/include/internal/powerpc/ke.h index d05ce0263b8..da52ed85ca9 100644 --- a/reactos/ntoskrnl/include/internal/powerpc/ke.h +++ b/reactos/ntoskrnl/include/internal/powerpc/ke.h @@ -181,6 +181,8 @@ KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState); #define KeArchFnInit() KePPCFnInit() #define KeArchHaltProcessor() KePPCHaltProcessor() +#define KeArchInitThreadWithContext(Thread,SystemRoutine,StartRoutine,StartContext,Context) \ + KePPCInitThreadWithContext(Thread,SystemRoutine,StartRoutine,StartContext,Context) #endif /* __NTOSKRNL_INCLUDE_INTERNAL_POWERPC_KE_H */ diff --git a/reactos/ntoskrnl/ke/powerpc/ctxhelp.S b/reactos/ntoskrnl/ke/powerpc/ctxhelp.S new file mode 100644 index 00000000000..b470a4282f8 --- /dev/null +++ b/reactos/ntoskrnl/ke/powerpc/ctxhelp.S @@ -0,0 +1,195 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/ke/i386/ctxswitch.S + * PURPOSE: Thread Context Switching + * + * PROGRAMMERS: arty + (i386 implementation by Alex Ionescu) + */ + +/* INCLUDES ******************************************************************/ + + .globl KiSystemService + .globl KiSystemService1 + .globl kiss_proceed + .globl kiss_end +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 + 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 2,8(1) + 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 + 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,KiDecrementerTrap@ha + addi 3,3,KiDecrementerTrap@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 */ +KiDecrementerTrapHandlerEnd: + .long 0 + + /* Decrementer needs to restore the full CPU state */ + .globl KiDecrementerTrapFinish +KiDecrementerTrapFinish: + addi 1,1,0x100 + lwz 2,8(1) + lwz 3,12(1) + lwz 4,16(1) + lwz 5,20(1) + lwz 6,24(1) + lwz 7,28(1) + lwz 8,32(1) + lwz 9,36(1) + lwz 10,40(1) + lwz 11,44(1) + lwz 12,48(1) + lwz 13,52(1) + lwz 14,56(1) + lwz 15,60(1) + lwz 16,64(1) + lwz 17,68(1) + lwz 18,72(1) + lwz 19,76(1) + lwz 20,80(1) + lwz 21,84(1) + lwz 22,88(1) + lwz 23,92(1) + lwz 24,96(1) + lwz 25,100(1) + lwz 26,104(1) + lwz 27,108(1) + lwz 28,112(1) + lwz 29,116(1) + lwz 30,120(1) + lwz 31,124(1) + lwz 0,140(1) + mtsrr0 0 + lwz 0,128(1) + mtlr 0 + lwz 0,136(1) + mtctr 0 + lwz 0,144(1) + 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) + // Bye!!1 + rfi diff --git a/reactos/ntoskrnl/ke/powerpc/ctxswitch.c b/reactos/ntoskrnl/ke/powerpc/ctxswitch.c new file mode 100644 index 00000000000..665e58d0fc7 --- /dev/null +++ b/reactos/ntoskrnl/ke/powerpc/ctxswitch.c @@ -0,0 +1,78 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/ke/i386/ctxswitch.S + * PURPOSE: Thread Context Switching + * + * PROGRAMMERS: arty + (i386 implementation by Alex Ionescu) + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/*++ + * KiThreadStartup + * + * The KiThreadStartup routine is the beginning of any thread. + * + * Params: + * SystemRoutine - Pointer to the System Startup Routine. Either + * PspUserThreadStartup or PspSystemThreadStartup + * + * StartRoutine - For Kernel Threads only, specifies the starting execution + * point of the new thread. + * + * StartContext - For Kernel Threads only, specifies a pointer to variable + * context data to be sent to the StartRoutine above. + * + * UserThread - Indicates whether or not this is a user thread. This tells + * us if the thread has a context or not. + * + * TrapFrame - Pointer to the KTHREAD to which the caller wishes to + * switch from. + * + * Returns: + * Should never return for a system thread. Returns through the System Call + * Exit Dispatcher for a user thread. + * + * Remarks: + * If a return from a system thread is detected, a bug check will occur. + * + *--*/ + +VOID +STDCALL +KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine, + PKSTART_ROUTINE StartRoutine, + PVOID StartContext, + BOOLEAN UserThread, + KTRAP_FRAME TrapFrame) +{ + KeLowerIrql(APC_LEVEL); + __asm__("mr 8,%0\n\t" + "mr 3,%1\n\t" + "mr 4,%2\n\t" + "mr 5,%3\n\t" + "mr 6,%4\n\t" + "sc" : : + "r" (0xf0000), /* Thread start function */ + "r" (SystemRoutine), + "r" (StartRoutine), + "r" (StartContext), + "r" (UserThread)); + PspTerminateThreadByPointer(PsGetCurrentThread(), STATUS_THREAD_IS_TERMINATING, TRUE); +} + +/* Take a decrementer trap, and prepare the given trap frame, swapping + * process and thread context as appropriate. */ +VOID +STDCALL +KiDecrementerTrap(PKTRAP_FRAME TrapFrame) +{ + DbgPrint("Decrementer Trap!\n"); + __asm__("mtdec %0" : : "r" (0x10000)); // Reset the trap +} diff --git a/reactos/ntoskrnl/ke/powerpc/kiinit.c b/reactos/ntoskrnl/ke/powerpc/kiinit.c index 84e132156ae..cec9806a201 100644 --- a/reactos/ntoskrnl/ke/powerpc/kiinit.c +++ b/reactos/ntoskrnl/ke/powerpc/kiinit.c @@ -52,7 +52,8 @@ __asm__(".text\n\t" "syscall_end:\n\t" ".space 4"); -extern int syscall_start[], syscall_end; +extern int syscall_start[], syscall_end, KiDecrementerTrapHandler[], + KiDecrementerTrapHandlerEnd; VOID NTAPI @@ -66,6 +67,28 @@ KiSetupSyscallHandler() SetPhys(handler_target, *source); } +VOID +NTAPI +KiSetupDecrementerTrap() +{ + paddr_t handler_target; + int *source; + + /* Turn off EE bit while redefining dec trap */ + _disable(); + + for(source = KiDecrementerTrapHandler, handler_target = 0x900; + source != &KiDecrementerTrapHandlerEnd; + source++, handler_target += sizeof(int)) + SetPhys(handler_target, *source); + + /* Enable interrupts! */ + _enable(); + + /* Kick decmrenter! */ + __asm__("mtdec %0" : : "r" (0)); +} + VOID NTAPI KiInitializePcr(IN ULONG ProcessorNumber, @@ -106,6 +129,12 @@ KiInitializeKernel(IN PKPROCESS InitProcess, ULONG FeatureBits; LARGE_INTEGER PageDirectory; PVOID DpcStack; + boot_infos_t *BootInfo = ((boot_infos_t *)LoaderBlock->ArchExtra); + +#ifdef _M_PPC + /* Set the machine type in LoaderBlock for HAL */ + KeLoaderBlock->u.PowerPC.MachineType = BootInfo->machineType; +#endif /* Detect and set the CPU Type */ KiSetProcessorType(); @@ -209,16 +238,15 @@ KiInitializeKernel(IN PKPROCESS InitProcess, /* Free Initial Memory */ // MiFreeInitMemory(); + /* Setup decrementer exception */ + KiSetupDecrementerTrap(); + while (1) { LARGE_INTEGER Timeout; Timeout.QuadPart = 0x7fffffffffffffffLL; KeDelayExecutionThread(KernelMode, FALSE, &Timeout); } - - /* Bug Check and loop forever if anything failed */ - KEBUGCHECK(0); - for(;;); } extern int KiPageFaultHandler(int trap, ppc_trap_frame_t *frame); diff --git a/reactos/ntoskrnl/ke/powerpc/ppc_irq.c b/reactos/ntoskrnl/ke/powerpc/ppc_irq.c index 47c53bef2c8..363a829576e 100644 --- a/reactos/ntoskrnl/ke/powerpc/ppc_irq.c +++ b/reactos/ntoskrnl/ke/powerpc/ppc_irq.c @@ -754,76 +754,13 @@ ULONG NTAPI KdpServiceDispatcher(ULONG Service, PCHAR Buffer, ULONG Length); -__asm__(".globl KiSystemService\n\t" - ".globl KiSystemService1\n\t" - ".globl kiss_proceed\n\t" - ".globl kiss_end\n" - "KiSystemService1:\n\t" - "stw 2,4(1)\n\t" // r1 - "stw 3,12(1)\n\t" - "stw 4,16(1)\n\t" - "stw 5,20(1)\n\t" - "stw 6,24(1)\n\t" - "stw 7,28(1)\n\t" - "stw 8,32(1)\n\t" - "stw 9,36(1)\n\t" - "stw 10,40(1)\n\t" - "stw 11,44(1)\n\t" - "stw 12,48(1)\n\t" - "stw 13,52(1)\n\t" - "stw 14,56(1)\n\t" - "stw 15,60(1)\n\t" - "stw 16,64(1)\n\t" - "stw 17,68(1)\n\t" - "stw 18,72(1)\n\t" - "stw 19,76(1)\n\t" - "stw 20,80(1)\n\t" - "stw 21,84(1)\n\t" - "stw 22,88(1)\n\t" - "stw 23,92(1)\n\t" - "stw 24,96(1)\n\t" - "stw 25,100(1)\n\t" - "stw 26,104(1)\n\t" - "stw 27,108(1)\n\t" - "stw 28,112(1)\n\t" - "stw 29,116(1)\n\t" - "stw 30,120(1)\n\t" - "stw 31,124(1)\n\t" - /* This save is important */ - "stw 0,140(1)\n\t" // srr0 - "mflr 0\n\t" - "stw 0,128(1)\n\t" - "mfctr 0\n\t" - "stw 0,136(1)\n\t" - "mfsrr1 0\n\t" - "stw 0,144(1)\n\t" - "mfdsisr 0\n\t" - "stw 0,148(1)\n\t" - "mfdar 0\n\t" - "stw 0,152(1)\n\t" - "lis 3,KiSystemService@ha\n\t" - "addi 3,3,KiSystemService@l\n\t" - "mtctr 3\n\t" - "mr 3,1\n\t" - "subi 1,1,0x100\n\t" - "bctrl\n\t" - "addi 1,1,0x100\n\t" - /* Return from kernel */ - "lwz 3,12(1)\n\t" /* Result */ - "lwz 0,128(1)\n\t" - "mtlr 0\n\t" - "lwz 0,140(1)\n\t" - "mtsrr0 0\n\t" - "lwz 0,144(1)\n\t" - "mtsrr1 0\n\t" - "lwz 1,4(1)\n" /* Stack */ - "rfi\n"); - VOID NTAPI KiSystemService(ppc_trap_frame_t *trap_frame) { int i; + PKSYSTEM_ROUTINE SystemRoutine; + switch(trap_frame->gpr[8]) { case 0x10000: /* DebugService */ @@ -835,6 +772,12 @@ KiSystemService(ppc_trap_frame_t *trap_frame) (PCHAR)trap_frame->gpr[4], trap_frame->gpr[5]); break; + case 0xf0000: /* Thread startup */ + /* XXX how to use UserThread (gpr[6]) */ + SystemRoutine = (PKSYSTEM_ROUTINE)trap_frame->gpr[3]; + SystemRoutine((PKSTART_ROUTINE)trap_frame->gpr[4], + (PVOID)trap_frame->gpr[5]); + break; } } diff --git a/reactos/ntoskrnl/ke/powerpc/stubs.c b/reactos/ntoskrnl/ke/powerpc/stubs.c index a8b154d9686..341e031eb83 100644 --- a/reactos/ntoskrnl/ke/powerpc/stubs.c +++ b/reactos/ntoskrnl/ke/powerpc/stubs.c @@ -199,16 +199,6 @@ NtRaiseException return STATUS_UNSUCCESSFUL; } -VOID -STDCALL -KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine, - PKSTART_ROUTINE StartRoutine, - PVOID StartContext, - BOOLEAN UserThread, - KTRAP_FRAME TrapFrame) -{ -} - void _alldiv() { } void _alldvrm() { } diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index d4041370818..0309a14e942 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -816,17 +816,16 @@ KeInitThread(IN OUT PKTHREAD Thread, KERNEL_STACK_SIZE); MiSyncThreadProcessViews(Process, Thread, sizeof(ETHREAD)); -#if defined(_M_IX86) /* Enter SEH to avoid crashes due to user mode */ Status = STATUS_SUCCESS; _SEH_TRY { /* Initalize the Thread Context */ - Ke386InitThreadWithContext(Thread, - SystemRoutine, - StartRoutine, - StartContext, - Context); + KeArchInitThreadWithContext(Thread, + SystemRoutine, + StartRoutine, + StartContext, + Context); } _SEH_HANDLE { @@ -842,9 +841,6 @@ KeInitThread(IN OUT PKTHREAD Thread, } } _SEH_END; -#else - Status = STATUS_SUCCESS; -#endif /* Set the Thread to initalized */ Thread->State = Initialized; diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 691c54f6f00..fff2890a0c3 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -64,6 +64,9 @@ ppc_irq.c stubs.c systimer.c + thrdini.c + ctxswitch.c + ctxhelp.S apc.c