From 06c5ac0542d1c5bdf6b4495ed7f3943c3ef0568a Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 4 Nov 2007 12:09:37 +0000 Subject: [PATCH] Add the beginnings of context switch and decrementer exception handler. Move cruddy asm code for syscall trap to an ASM file. Factor out an i386 specific name. Add relevant registers to FX save. svn path=/trunk/; revision=30108 --- reactos/include/ndk/powerpc/ketypes.h | 7 +- reactos/ntoskrnl/include/internal/i386/ke.h | 2 + .../ntoskrnl/include/internal/powerpc/ke.h | 2 + reactos/ntoskrnl/ke/powerpc/ctxhelp.S | 195 ++++++++++++++++++ reactos/ntoskrnl/ke/powerpc/ctxswitch.c | 78 +++++++ reactos/ntoskrnl/ke/powerpc/kiinit.c | 38 +++- reactos/ntoskrnl/ke/powerpc/ppc_irq.c | 73 +------ reactos/ntoskrnl/ke/powerpc/stubs.c | 10 - reactos/ntoskrnl/ke/thrdobj.c | 14 +- reactos/ntoskrnl/ntoskrnl.rbuild | 3 + 10 files changed, 332 insertions(+), 90 deletions(-) create mode 100644 reactos/ntoskrnl/ke/powerpc/ctxhelp.S create mode 100644 reactos/ntoskrnl/ke/powerpc/ctxswitch.c 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