Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenthrdini.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS kernel 00004 * FILE: ntoskrnl/ke/i386/thread.c 00005 * PURPOSE: amd64 Thread Context Creation 00006 * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org) 00007 * Alex Ionescu (alex@relsoft.net) 00008 */ 00009 00010 /* INCLUDES ******************************************************************/ 00011 00012 #include <ntoskrnl.h> 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 typedef struct _KUINIT_FRAME 00017 { 00018 KSWITCH_FRAME CtxSwitchFrame; 00019 KSTART_FRAME StartFrame; 00020 KEXCEPTION_FRAME ExceptionFrame; 00021 KTRAP_FRAME TrapFrame; 00022 //FX_SAVE_AREA FxSaveArea; 00023 } KUINIT_FRAME, *PKUINIT_FRAME; 00024 00025 typedef struct _KKINIT_FRAME 00026 { 00027 KSWITCH_FRAME CtxSwitchFrame; 00028 KSTART_FRAME StartFrame; 00029 //FX_SAVE_AREA FxSaveArea; 00030 } KKINIT_FRAME, *PKKINIT_FRAME; 00031 00032 /* FUNCTIONS *****************************************************************/ 00033 00034 VOID 00035 NTAPI 00036 KiInitializeContextThread(IN PKTHREAD Thread, 00037 IN PKSYSTEM_ROUTINE SystemRoutine, 00038 IN PKSTART_ROUTINE StartRoutine, 00039 IN PVOID StartContext, 00040 IN PCONTEXT Context) 00041 { 00042 //PFX_SAVE_AREA FxSaveArea; 00043 //PFXSAVE_FORMAT FxSaveFormat; 00044 PKSTART_FRAME StartFrame; 00045 PKSWITCH_FRAME CtxSwitchFrame; 00046 PKTRAP_FRAME TrapFrame; 00047 ULONG ContextFlags; 00048 00049 /* Check if this is a With-Context Thread */ 00050 if (Context) 00051 { 00052 PKUINIT_FRAME InitFrame; 00053 00054 /* Set up the Initial Frame */ 00055 InitFrame = ((PKUINIT_FRAME)Thread->InitialStack) - 1; 00056 StartFrame = &InitFrame->StartFrame; 00057 CtxSwitchFrame = &InitFrame->CtxSwitchFrame; 00058 00059 /* Save back the new value of the kernel stack. */ 00060 Thread->KernelStack = (PVOID)InitFrame; 00061 00062 /* Tell the thread it will run in User Mode */ 00063 Thread->PreviousMode = UserMode; 00064 00065 // FIXME Setup the Fx Area 00066 00067 /* Set the Thread's NPX State */ 00068 Thread->NpxState = 0xA; 00069 Thread->Header.NpxIrql = PASSIVE_LEVEL; 00070 00071 /* Make sure, we have control registers, disable debug registers */ 00072 ASSERT((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL); 00073 ContextFlags = Context->ContextFlags & ~CONTEXT_DEBUG_REGISTERS; 00074 00075 /* Setup the Trap Frame */ 00076 TrapFrame = &InitFrame->TrapFrame; 00077 00078 /* Zero out the trap frame */ 00079 RtlZeroMemory(TrapFrame, sizeof(KTRAP_FRAME)); 00080 00081 /* Set up a trap frame from the context. */ 00082 KeContextToTrapFrame(Context, 00083 NULL, 00084 TrapFrame, 00085 CONTEXT_AMD64 | ContextFlags, 00086 UserMode); 00087 00088 /* Set SS, DS, ES's RPL Mask properly */ 00089 TrapFrame->SegSs |= RPL_MASK; 00090 TrapFrame->SegDs |= RPL_MASK; 00091 TrapFrame->SegEs |= RPL_MASK; 00092 TrapFrame->Dr7 = 0; 00093 00094 /* Set the previous mode as user */ 00095 TrapFrame->PreviousMode = UserMode; 00096 00097 /* Terminate the Exception Handler List */ 00098 TrapFrame->ExceptionFrame = 0; 00099 00100 /* We return to ... */ 00101 StartFrame->Return = (ULONG64)KiServiceExit2; 00102 } 00103 else 00104 { 00105 PKKINIT_FRAME InitFrame; 00106 00107 /* Set up the Initial Frame for the system thread */ 00108 InitFrame = ((PKKINIT_FRAME)Thread->InitialStack) - 1; 00109 StartFrame = &InitFrame->StartFrame; 00110 CtxSwitchFrame = &InitFrame->CtxSwitchFrame; 00111 00112 /* Save back the new value of the kernel stack. */ 00113 Thread->KernelStack = (PVOID)InitFrame; 00114 00115 /* Tell the thread it will run in Kernel Mode */ 00116 Thread->PreviousMode = KernelMode; 00117 00118 // FIXME Setup the Fx Area 00119 00120 /* No NPX State */ 00121 Thread->NpxState = 0xA; 00122 00123 /* We have no return address! */ 00124 StartFrame->Return = 0; 00125 } 00126 00127 /* Set up the Context Switch Frame */ 00128 CtxSwitchFrame->Return = (ULONG64)KiThreadStartup; 00129 CtxSwitchFrame->ApcBypass = FALSE; 00130 00131 StartFrame->P1Home = (ULONG64)StartRoutine; 00132 StartFrame->P2Home = (ULONG64)StartContext; 00133 StartFrame->P3Home = 0; 00134 StartFrame->P4Home = (ULONG64)SystemRoutine; 00135 StartFrame->P5Home = 0; 00136 00137 } 00138 00139 BOOLEAN 00140 KiSwapContextResume( 00141 IN PKTHREAD NewThread, 00142 IN PKTHREAD OldThread, 00143 IN BOOLEAN ApcBypass) 00144 { 00145 PKIPCR Pcr = (PKIPCR)KeGetPcr(); 00146 PKPROCESS OldProcess, NewProcess; 00147 00148 /* Setup ring 0 stack pointer */ 00149 Pcr->TssBase->Rsp0 = (ULONG64)NewThread->InitialStack; // FIXME: NPX save area? 00150 Pcr->Prcb.RspBase = Pcr->TssBase->Rsp0; 00151 00152 /* Now we are the new thread. Check if it's in a new process */ 00153 OldProcess = OldThread->ApcState.Process; 00154 NewProcess = NewThread->ApcState.Process; 00155 if (OldProcess != NewProcess) 00156 { 00157 /* Switch address space and flush TLB */ 00158 __writecr3(NewProcess->DirectoryTableBase[0]); 00159 00160 /* Set new TSS fields */ 00161 //Pcr->TssBase->IoMapBase = NewProcess->IopmOffset; 00162 } 00163 00164 /* Set TEB pointer and GS base */ 00165 Pcr->NtTib.Self = (PVOID)NewThread->Teb; 00166 if (NewThread->Teb) 00167 { 00168 /* This will switch the usermode gs */ 00169 __writemsr(MSR_GS_SWAP, (ULONG64)NewThread->Teb); 00170 } 00171 00172 /* Increase context switch count */ 00173 Pcr->ContextSwitches++; 00174 NewThread->ContextSwitches++; 00175 00176 /* DPCs shouldn't be active */ 00177 if (Pcr->Prcb.DpcRoutineActive) 00178 { 00179 /* Crash the machine */ 00180 KeBugCheckEx(ATTEMPTED_SWITCH_FROM_DPC, 00181 (ULONG_PTR)OldThread, 00182 (ULONG_PTR)NewThread, 00183 (ULONG_PTR)OldThread->InitialStack, 00184 0); 00185 } 00186 00187 /* Kernel APCs may be pending */ 00188 if (NewThread->ApcState.KernelApcPending) 00189 { 00190 /* Are APCs enabled? */ 00191 if (!NewThread->SpecialApcDisable) 00192 { 00193 /* Request APC delivery */ 00194 if (!ApcBypass) 00195 HalRequestSoftwareInterrupt(APC_LEVEL); 00196 else 00197 return TRUE; 00198 } 00199 } 00200 00201 /* Return stating that no kernel APCs are pending*/ 00202 return FALSE; 00203 } 00204 00205 /* EOF */ 00206 00207 Generated on Sun May 27 2012 04:37:30 for ReactOS by
1.7.6.1
|