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
This commit is contained in:
Art Yerkes 2007-11-04 12:09:37 +00:00
parent 6243c9c750
commit 06c5ac0542
10 changed files with 332 additions and 90 deletions

View file

@ -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;

View file

@ -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

View file

@ -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 */

View file

@ -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

View file

@ -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 <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
/*++
* 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
}

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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() { }

View file

@ -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;

View file

@ -64,6 +64,9 @@
<file>ppc_irq.c</file>
<file>stubs.c</file>
<file>systimer.c</file>
<file>thrdini.c</file>
<file>ctxswitch.c</file>
<file>ctxhelp.S</file>
</directory>
</if>
<file>apc.c</file>