ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

thrdini.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.