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)
10 /* INCLUDES ******************************************************************/
15 #include <ndk/powerpc/ketypes.h>
16 #include <ppcmmu/mmu.h>
18 typedef struct _KSWITCHFRAME
21 BOOLEAN ApcBypassDisable
;
23 } KSWITCHFRAME
, *PKSWITCHFRAME
;
25 typedef struct _KSTART_FRAME
27 PKSYSTEM_ROUTINE SystemRoutine
;
28 PKSTART_ROUTINE StartRoutine
;
31 } KSTART_FRAME
, *PKSTART_FRAME
;
33 typedef struct _KUINIT_FRAME
35 KSWITCHFRAME CtxSwitchFrame
;
36 KSTART_FRAME StartFrame
;
37 KTRAP_FRAME TrapFrame
;
38 FX_SAVE_AREA FxSaveArea
;
39 } KUINIT_FRAME
, *PKUINIT_FRAME
;
41 typedef struct _KKINIT_FRAME
43 KSWITCHFRAME CtxSwitchFrame
;
44 KSTART_FRAME StartFrame
;
45 KTRAP_FRAME TrapFrame
;
46 FX_SAVE_AREA FxSaveArea
;
47 } KKINIT_FRAME
, *PKKINIT_FRAME
;
49 /* FUNCTIONS *****************************************************************/
53 KiInitializeContextThread(IN PKTHREAD Thread
,
54 IN PKSYSTEM_ROUTINE SystemRoutine
,
55 IN PKSTART_ROUTINE StartRoutine
,
56 IN PVOID StartContext
,
57 IN PCONTEXT ContextPointer
)
59 PFX_SAVE_AREA FxSaveArea
;
60 PKSTART_FRAME StartFrame
;
61 PKSWITCHFRAME CtxSwitchFrame
;
62 PKTRAP_FRAME TrapFrame
;
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]);
70 DPRINT("Thread: %08x ContextPointer: %08x SystemRoutine: %08x StartRoutine: %08x StartContext: %08x\n",
77 /* Check if this is a With-Context Thread */
80 /* Set up the Initial Frame */
81 PKUINIT_FRAME InitFrame
;
82 InitFrame
= (PKUINIT_FRAME
)((ULONG_PTR
)Thread
->InitialStack
-
83 sizeof(KUINIT_FRAME
));
85 /* Copy over the context we got */
86 RtlCopyMemory(&LocalContext
, ContextPointer
, sizeof(CONTEXT
));
87 Context
= &LocalContext
;
88 ContextFlags
= CONTEXT_CONTROL
;
90 /* Zero out the trap frame and save area */
91 RtlZeroMemory(&InitFrame
->TrapFrame
,
92 KTRAP_FRAME_LENGTH
+ sizeof(FX_SAVE_AREA
));
94 /* Setup the Fx Area */
95 FxSaveArea
= &InitFrame
->FxSaveArea
;
97 /* Disable any debug regiseters */
98 Context
->ContextFlags
&= ~CONTEXT_DEBUG_REGISTERS
;
100 /* Setup the Trap Frame */
101 TrapFrame
= &InitFrame
->TrapFrame
;
103 /* Set up a trap frame from the context. */
104 KeContextToTrapFrame(Context
,
107 Context
->ContextFlags
| ContextFlags
,
110 /* Set the previous mode as user */
111 TrapFrame
->PreviousMode
= UserMode
;
113 /* Terminate the Exception Handler List */
114 RtlZeroMemory(TrapFrame
->ExceptionRecord
, sizeof(TrapFrame
->ExceptionRecord
));
116 /* Setup the Stack for KiThreadStartup and Context Switching */
117 StartFrame
= &InitFrame
->StartFrame
;
118 CtxSwitchFrame
= &InitFrame
->CtxSwitchFrame
;
120 /* Tell the thread it will run in User Mode */
121 Thread
->PreviousMode
= UserMode
;
123 /* Tell KiThreadStartup of that too */
124 StartFrame
->UserThread
= TRUE
;
126 Thread
->TrapFrame
= TrapFrame
;
128 DPRINT("Thread %08x Iar %08x Msr %08x Gpr1 %08x Gpr3 %08x\n",
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
));
142 /* Setup the Fx Area */
143 FxSaveArea
= &InitFrame
->FxSaveArea
;
144 RtlZeroMemory(FxSaveArea
, sizeof(FX_SAVE_AREA
));
146 /* Setup the Stack for KiThreadStartup and Context Switching */
147 StartFrame
= &InitFrame
->StartFrame
;
148 CtxSwitchFrame
= &InitFrame
->CtxSwitchFrame
;
150 /* Tell the thread it will run in Kernel Mode */
151 Thread
->PreviousMode
= KernelMode
;
153 /* Tell KiThreadStartup of that too */
154 StartFrame
->UserThread
= FALSE
;
156 /* Setup the Trap Frame */
157 TrapFrame
= &InitFrame
->TrapFrame
;
158 Thread
->TrapFrame
= TrapFrame
;
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]));
168 DPRINT("Thread %08x Iar %08x Msr %08x Gpr1 %08x Gpr3 %08x\n",
176 /* Now setup the remaining data for KiThreadStartup */
177 StartFrame
->StartContext
= StartContext
;
178 StartFrame
->StartRoutine
= StartRoutine
;
179 StartFrame
->SystemRoutine
= SystemRoutine
;
181 /* And set up the Context Switch Frame */
182 CtxSwitchFrame
->RetAddr
= KiThreadStartup
;
183 CtxSwitchFrame
->ApcBypassDisable
= TRUE
;
184 CtxSwitchFrame
->ExceptionList
= EXCEPTION_CHAIN_END
;
186 /* Save back the new value of the kernel stack. */
187 Thread
->KernelStack
= (PVOID
)CtxSwitchFrame
;
189 /* If we're the first thread of the new process, copy the top 16 pages
191 if (Process
&& IsListEmpty(&Process
->ThreadListHead
))
193 DPRINT("First Thread in Process %x\n", Process
);
194 MmuAllocVsid((ULONG
)Process
->UniqueProcessId
, 0xff);
196 for (i
= 0; i
< pmsize
; i
++)
199 pagemap
[i
].addr
= 0x7fff0000 + (i
* PAGE_SIZE
);
202 MmuInqPage(pagemap
, pmsize
);
204 for (i
= 0; i
< pmsize
; i
++)
208 pagemap
[i
].proc
= (ULONG
)Process
->UniqueProcessId
;
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
);
216 DPRINT("Did additional aspace setup in the new process\n");