Sync to trunk revision 61757.
[reactos.git] / ntoskrnl / ke / powerpc / thrdini.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ke/powerpc/thread.c
5 * PURPOSE: i386 Thread Context Creation
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
7 * arty (ppc adaptation)
8 */
9
10 /* INCLUDES ******************************************************************/
11
12 #include <ntoskrnl.h>
13 //#define NDEBUG
14 #include <debug.h>
15 #include <ndk/powerpc/ketypes.h>
16 #include <ppcmmu/mmu.h>
17
18 typedef struct _KSWITCHFRAME
19 {
20 PVOID ExceptionList;
21 BOOLEAN ApcBypassDisable;
22 PVOID RetAddr;
23 } KSWITCHFRAME, *PKSWITCHFRAME;
24
25 typedef struct _KSTART_FRAME
26 {
27 PKSYSTEM_ROUTINE SystemRoutine;
28 PKSTART_ROUTINE StartRoutine;
29 PVOID StartContext;
30 BOOLEAN UserThread;
31 } KSTART_FRAME, *PKSTART_FRAME;
32
33 typedef struct _KUINIT_FRAME
34 {
35 KSWITCHFRAME CtxSwitchFrame;
36 KSTART_FRAME StartFrame;
37 KTRAP_FRAME TrapFrame;
38 FX_SAVE_AREA FxSaveArea;
39 } KUINIT_FRAME, *PKUINIT_FRAME;
40
41 typedef struct _KKINIT_FRAME
42 {
43 KSWITCHFRAME CtxSwitchFrame;
44 KSTART_FRAME StartFrame;
45 KTRAP_FRAME TrapFrame;
46 FX_SAVE_AREA FxSaveArea;
47 } KKINIT_FRAME, *PKKINIT_FRAME;
48
49 /* FUNCTIONS *****************************************************************/
50
51 VOID
52 NTAPI
53 KiInitializeContextThread(IN PKTHREAD Thread,
54 IN PKSYSTEM_ROUTINE SystemRoutine,
55 IN PKSTART_ROUTINE StartRoutine,
56 IN PVOID StartContext,
57 IN PCONTEXT ContextPointer)
58 {
59 PFX_SAVE_AREA FxSaveArea;
60 PKSTART_FRAME StartFrame;
61 PKSWITCHFRAME CtxSwitchFrame;
62 PKTRAP_FRAME TrapFrame;
63 CONTEXT LocalContext;
64 PCONTEXT Context = NULL;
65 ppc_map_info_t pagemap[16];
66 PETHREAD EThread = (PETHREAD)Thread;
67 PEPROCESS Process = EThread->ThreadsProcess;
68 ULONG ContextFlags, i, pmsize = sizeof(pagemap) / sizeof(pagemap[0]);
69
70 DPRINT("Thread: %08x ContextPointer: %08x SystemRoutine: %08x StartRoutine: %08x StartContext: %08x\n",
71 Thread,
72 ContextPointer,
73 SystemRoutine,
74 StartRoutine,
75 StartContext);
76
77 /* Check if this is a With-Context Thread */
78 if (ContextPointer)
79 {
80 /* Set up the Initial Frame */
81 PKUINIT_FRAME InitFrame;
82 InitFrame = (PKUINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
83 sizeof(KUINIT_FRAME));
84
85 /* Copy over the context we got */
86 RtlCopyMemory(&LocalContext, ContextPointer, sizeof(CONTEXT));
87 Context = &LocalContext;
88 ContextFlags = CONTEXT_CONTROL;
89
90 /* Zero out the trap frame and save area */
91 RtlZeroMemory(&InitFrame->TrapFrame,
92 KTRAP_FRAME_LENGTH + sizeof(FX_SAVE_AREA));
93
94 /* Setup the Fx Area */
95 FxSaveArea = &InitFrame->FxSaveArea;
96
97 /* Disable any debug regiseters */
98 Context->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS;
99
100 /* Setup the Trap Frame */
101 TrapFrame = &InitFrame->TrapFrame;
102
103 /* Set up a trap frame from the context. */
104 KeContextToTrapFrame(Context,
105 NULL,
106 TrapFrame,
107 Context->ContextFlags | ContextFlags,
108 UserMode);
109
110 /* Set the previous mode as user */
111 TrapFrame->PreviousMode = UserMode;
112
113 /* Terminate the Exception Handler List */
114 RtlZeroMemory(TrapFrame->ExceptionRecord, sizeof(TrapFrame->ExceptionRecord));
115
116 /* Setup the Stack for KiThreadStartup and Context Switching */
117 StartFrame = &InitFrame->StartFrame;
118 CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
119
120 /* Tell the thread it will run in User Mode */
121 Thread->PreviousMode = UserMode;
122
123 /* Tell KiThreadStartup of that too */
124 StartFrame->UserThread = TRUE;
125
126 Thread->TrapFrame = TrapFrame;
127
128 DPRINT("Thread %08x Iar %08x Msr %08x Gpr1 %08x Gpr3 %08x\n",
129 Thread,
130 TrapFrame->Iar,
131 TrapFrame->Msr,
132 TrapFrame->Gpr1,
133 TrapFrame->Gpr3);
134 }
135 else
136 {
137 /* Set up the Initial Frame for the system thread */
138 PKKINIT_FRAME InitFrame;
139 InitFrame = (PKKINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
140 sizeof(KKINIT_FRAME));
141
142 /* Setup the Fx Area */
143 FxSaveArea = &InitFrame->FxSaveArea;
144 RtlZeroMemory(FxSaveArea, sizeof(FX_SAVE_AREA));
145
146 /* Setup the Stack for KiThreadStartup and Context Switching */
147 StartFrame = &InitFrame->StartFrame;
148 CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
149
150 /* Tell the thread it will run in Kernel Mode */
151 Thread->PreviousMode = KernelMode;
152
153 /* Tell KiThreadStartup of that too */
154 StartFrame->UserThread = FALSE;
155
156 /* Setup the Trap Frame */
157 TrapFrame = &InitFrame->TrapFrame;
158 Thread->TrapFrame = TrapFrame;
159
160 TrapFrame->OldIrql = PASSIVE_LEVEL;
161 TrapFrame->Iar = (ULONG)SystemRoutine;
162 TrapFrame->Msr = 0xb030;
163 TrapFrame->Gpr1 = ((ULONG)&InitFrame->StartFrame) - 0x200;
164 TrapFrame->Gpr3 = (ULONG)StartRoutine;
165 TrapFrame->Gpr4 = (ULONG)StartContext;
166 __asm__("mr %0,13" : "=r" (((PULONG)&TrapFrame->Gpr0)[13]));
167
168 DPRINT("Thread %08x Iar %08x Msr %08x Gpr1 %08x Gpr3 %08x\n",
169 Thread,
170 TrapFrame->Iar,
171 TrapFrame->Msr,
172 TrapFrame->Gpr1,
173 TrapFrame->Gpr3);
174 }
175
176 /* Now setup the remaining data for KiThreadStartup */
177 StartFrame->StartContext = StartContext;
178 StartFrame->StartRoutine = StartRoutine;
179 StartFrame->SystemRoutine = SystemRoutine;
180
181 /* And set up the Context Switch Frame */
182 CtxSwitchFrame->RetAddr = KiThreadStartup;
183 CtxSwitchFrame->ApcBypassDisable = TRUE;
184 CtxSwitchFrame->ExceptionList = EXCEPTION_CHAIN_END;
185
186 /* Save back the new value of the kernel stack. */
187 Thread->KernelStack = (PVOID)CtxSwitchFrame;
188
189 /* If we're the first thread of the new process, copy the top 16 pages
190 * from process 0 */
191 if (Process && IsListEmpty(&Process->ThreadListHead))
192 {
193 DPRINT("First Thread in Process %x\n", Process);
194 MmuAllocVsid((ULONG)Process->UniqueProcessId, 0xff);
195
196 for (i = 0; i < pmsize; i++)
197 {
198 pagemap[i].proc = 0;
199 pagemap[i].addr = 0x7fff0000 + (i * PAGE_SIZE);
200 }
201
202 MmuInqPage(pagemap, pmsize);
203
204 for (i = 0; i < pmsize; i++)
205 {
206 if (pagemap[i].phys)
207 {
208 pagemap[i].proc = (ULONG)Process->UniqueProcessId;
209 pagemap[i].phys = 0;
210 MmuMapPage(&pagemap[i], 1);
211 DPRINT("Added map to the new process: P %08x A %08x\n",
212 pagemap[i].proc, pagemap[i].addr);
213 }
214 }
215
216 DPRINT("Did additional aspace setup in the new process\n");
217 }
218 }
219
220 /* EOF */
221
222