migrate substitution keywords to SVN
[reactos.git] / reactos / ntoskrnl / ps / i386 / continue.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ps/i386/continue.c
6 * PURPOSE: i386 implementation of NtContinue()
7 * PROGRAMMER: Royce Mitchell III, kjk_hyperion
8 * REVISION HISTORY:
9 * 29/06/04: Created
10 */
11
12 /* INCLUDES ****************************************************************/
13
14 #include <ntoskrnl.h>
15 #define NDEBUG
16 #include <internal/debug.h>
17
18 VOID
19 FASTCALL
20 KeRosTrapReturn ( PKTRAP_FRAME TrapFrame, PKTRAP_FRAME PrevTrapFrame );
21
22 VOID STDCALL
23 KeRosDumpStackFrames ( PULONG Frame, ULONG FrameCount );
24
25 /*
26 * @implemented
27 */
28 NTSTATUS STDCALL
29 NtContinue (
30 IN PCONTEXT Context,
31 IN BOOLEAN TestAlert)
32 {
33 PKTRAP_FRAME TrapFrame = KeGetCurrentThread()->TrapFrame;
34 PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
35 PFX_SAVE_AREA FxSaveArea;
36 KIRQL oldIrql;
37
38 DPRINT("NtContinue: Context: Eip=0x%x, Esp=0x%x\n", Context->Eip, Context->Esp );
39 PULONG Frame = 0;
40 __asm__("mov %%ebp, %%ebx" : "=b" (Frame) : );
41 DPRINT( "NtContinue(): Ebp=%x, prev/TF=%x/%x\n", Frame, Frame[0], TrapFrame );
42 #ifndef NDEBUG
43 KeRosDumpStackFrames(NULL,5);
44 #endif
45
46 if ( Context == NULL )
47 {
48 DPRINT1("NtContinue called with NULL Context\n");
49 return STATUS_INVALID_PARAMETER;
50 }
51
52 if ( TrapFrame == NULL )
53 {
54 CPRINT("NtContinue called but TrapFrame was NULL\n");
55 KEBUGCHECK(0);
56 }
57
58 /*
59 * Copy the supplied context over the register information that was saved
60 * on entry to kernel mode, it will then be restored on exit
61 * FIXME: Validate the context
62 */
63 KeContextToTrapFrame ( Context, TrapFrame );
64
65 /* Put the floating point context into the thread's FX_SAVE_AREA
66 * and make sure it is reloaded when needed.
67 */
68 FxSaveArea = (PFX_SAVE_AREA)((ULONG_PTR)KeGetCurrentThread()->InitialStack - sizeof(FX_SAVE_AREA));
69 if (KiContextToFxSaveArea(FxSaveArea, Context))
70 {
71 KeGetCurrentThread()->NpxState = NPX_STATE_VALID;
72 KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
73 if (KeGetCurrentKPCR()->PrcbData.NpxThread == KeGetCurrentThread())
74 {
75 KeGetCurrentKPCR()->PrcbData.NpxThread = NULL;
76 Ke386SetCr0(Ke386GetCr0() | X86_CR0_TS);
77 }
78 else
79 {
80 ASSERT((Ke386GetCr0() & X86_CR0_TS) == X86_CR0_TS);
81 }
82 KeLowerIrql(oldIrql);
83 }
84
85 KeRosTrapReturn ( TrapFrame, PrevTrapFrame );
86
87 return STATUS_SUCCESS; /* this doesn't actually happen b/c KeRosTrapReturn() won't return */
88 }