2b94016b88567a623606bf556f2c02b61967bb56
[reactos.git] / reactos / ntoskrnl / ke / arm / thrdini.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/ke/arm/thrdini.c
5 * PURPOSE: Implements thread context setup and startup for ARM machines
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 /* GLOBALS ********************************************************************/
16
17 typedef struct _KUINIT_FRAME
18 {
19 KEXCEPTION_FRAME CtxSwitchFrame;
20 KEXCEPTION_FRAME ExceptionFrame;
21 KTRAP_FRAME TrapFrame;
22 } KUINIT_FRAME, *PKUINIT_FRAME;
23
24 typedef struct _KKINIT_FRAME
25 {
26 KEXCEPTION_FRAME CtxSwitchFrame;
27 } KKINIT_FRAME, *PKKINIT_FRAME;
28
29 /* FUNCTIONS ******************************************************************/
30
31 VOID
32 NTAPI
33 KiThreadStartup(VOID);
34
35 VOID
36 NTAPI
37 KeArmInitThreadWithContext(IN PKTHREAD Thread,
38 IN PKSYSTEM_ROUTINE SystemRoutine,
39 IN PKSTART_ROUTINE StartRoutine,
40 IN PVOID StartContext,
41 IN PCONTEXT ContextPointer)
42 {
43 PKTRAP_FRAME TrapFrame;
44 PKEXCEPTION_FRAME ExceptionFrame = NULL, CtxSwitchFrame;
45
46 //
47 // Check if this is a user thread
48 //
49 if (ContextPointer)
50 {
51 //
52 // Setup the initial frame
53 //
54 PKUINIT_FRAME InitFrame;
55 InitFrame = (PKUINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
56 sizeof(KUINIT_FRAME));
57
58 //
59 // Setup the Trap Frame and Exception frame
60 //
61 TrapFrame = &InitFrame->TrapFrame;
62 ExceptionFrame = &InitFrame->ExceptionFrame;
63
64 ///
65 // Zero out the trap frame and exception frame
66 //
67 RtlZeroMemory(TrapFrame, sizeof(KTRAP_FRAME));
68 RtlZeroMemory(ExceptionFrame, sizeof(KEXCEPTION_FRAME));
69
70 //
71 // Set up a trap frame from the context
72 //
73 KeContextToTrapFrame(ContextPointer,
74 ExceptionFrame,
75 TrapFrame,
76 ContextPointer->ContextFlags | CONTEXT_CONTROL,
77 UserMode);
78
79 //
80 // Set the previous mode as user
81 //
82 //TrapFrame->PreviousMode = UserMode;
83 Thread->PreviousMode = UserMode;
84
85 //
86 // Clear the return address
87 //
88 ExceptionFrame->Lr = 0;
89
90 //
91 // Context switch frame to setup below
92 //
93 CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
94 }
95 else
96 {
97 //
98 // Set up the Initial Frame for the system thread
99 //
100 PKKINIT_FRAME InitFrame;
101 InitFrame = (PKKINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
102 sizeof(KKINIT_FRAME));
103
104 //
105 // Set the previous mode as kernel
106 //
107 Thread->PreviousMode = KernelMode;
108
109 //
110 // Context switch frame to setup below
111 //
112 CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
113 }
114
115 //
116 // Now setup the context switch frame
117 //
118 CtxSwitchFrame->Lr = (ULONG)KiThreadStartup;
119 CtxSwitchFrame->R11 = (ULONG)(ExceptionFrame ? ExceptionFrame : CtxSwitchFrame);
120
121 //
122 // Set the parameters
123 //
124 CtxSwitchFrame->R4 = (ULONG)ContextPointer;
125 CtxSwitchFrame->R5 = (ULONG)StartContext;
126 CtxSwitchFrame->R6 = (ULONG)StartRoutine;
127 CtxSwitchFrame->R7 = (ULONG)SystemRoutine;
128
129 //
130 // Save back the new value of the kernel stack
131 //
132 Thread->KernelStack = (PVOID)CtxSwitchFrame;
133 DPRINT1("NEW THREAD %p WITH EX FRAME AT: %p\n", Thread, Thread->KernelStack);
134 }