test: ppc/thredini.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# thredini.c File Reference

`#include "ki.h"`

Go to the source code of this file.

## Defines

#define | ASSERT_PROCESS(E)
#define | ASSERT_THREAD(E)

## Functions

VOID | KiInitializeContextThread (IN PKTHREAD Thread, IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext OPTIONAL, IN PCONTEXT ContextRecord OPTIONAL)
BOOLEAN | KeSetAutoAlignmentProcess (IN PKPROCESS Process, IN BOOLEAN Enable)
BOOLEAN | KeSetAutoAlignmentThread (IN PKTHREAD Thread, IN BOOLEAN Enable)

## Define Documentation

#define ASSERT_PROCESS | ( | E |  | ) |

Value:

    {                    \
        ASSERT((E)->Header.Type == ProcessObject); \
    }

Definition at line 35 of file ppc/thredini.c.

#define ASSERT_THREAD | ( | E |  | ) |

Value:

    {                    \
        ASSERT((E)->Header.Type == ThreadObject); \
    }

Definition at line 39 of file ppc/thredini.c.

## Function Documentation

BOOLEAN KeSetAutoAlignmentProcess | ( | IN PKPROCESS | Process,
|  | IN BOOLEAN | Enable
| ) |

Definition at line 223 of file ppc/thredini.c.

References ASSERT_PROCESS, KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

Referenced by NtSetInformationProcess().

    00230                    :
    00231
    00232     This function sets the data alignment handling mode for the specified
    00233     process and returns the previous data alignment handling mode.
    00234
    00235 Arguments:
    00236
    00237     Process  - Supplies a pointer to a dispatcher object of type process.
    00238
    00239     Enable - Supplies a boolean value that determines the handling of data
    00240         alignment exceptions for the process. A value of TRUE causes all
    00241         data alignment exceptions to be automatically handled by the kernel.
    00242         A value of FALSE causes all data alignment exceptions to be actually
    00243         raised as exceptions.
    00244
    00245 Return Value:
    00246
    00247     A value of TRUE is returned if data alignment exceptions were
    00248     previously automatically handled by the kernel. Otherwise, a value
    00249     of FALSE is returned.
    00250
    00251 --*/
    00252
    00253 {
    00254
    00255     KIRQL OldIrql;
    00256     BOOLEAN Previous;
    00257
    00258     ASSERT_PROCESS(Process);
    00259
    00260     //
    00261     // Raise IRQL to dispatcher level and lock dispatcher database.
    00262     //
    00263
    00264     KiLockDispatcherDatabase(&OldIrql);
    00265
    00266     //
    00267     // Capture the previous data alignment handling mode and set the
    00268     // specified data alignment mode.
    00269     //
    00270
    00271     Previous = Process->AutoAlignment;
    00272     Process->AutoAlignment = Enable;
    00273
    00274     //
    00275     // Unlock dispatcher database, lower IRQL to its previous value, and
    00276     // return the previous data alignment mode.
    00277     //
    00278
    00279     KiUnlockDispatcherDatabase(OldIrql);
    00280     return Previous;
    00281 }

BOOLEAN KeSetAutoAlignmentThread | ( | IN PKTHREAD | Thread,
|  | IN BOOLEAN | Enable
| ) |

Definition at line 284 of file ppc/thredini.c.

References ASSERT_THREAD, KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

Referenced by NtSetInformationThread().

    00291                    :
    00292
    00293     This function sets the data alignment handling mode for the specified
    00294     thread and returns the previous data alignment handling mode.
    00295
    00296 Arguments:
    00297
    00298     Thread  - Supplies a pointer to a dispatcher object of type thread.
    00299
    00300     Enable - Supplies a boolean value that determines the handling of data
    00301         alignment exceptions for the thread. A value of TRUE causes all
    00302         data alignment exceptions to be automatically handled by the kernel.
    00303         A value of FALSE causes all data alignment exceptions to be actually
    00304         raised as exceptions.
    00305
    00306 Return Value:
    00307
    00308     A value of TRUE is returned if data alignment exceptions were
    00309     previously automatically handled by the kernel. Otherwise, a value
    00310     of FALSE is returned.
    00311
    00312 --*/
    00313
    00314 {
    00315
    00316     KIRQL OldIrql;
    00317     BOOLEAN Previous;
    00318
    00319     ASSERT_THREAD( Thread );
    00320
    00321     //
    00322     // Raise IRQL to dispatcher level and lock dispatcher database.
    00323     //
    00324
    00325     KiLockDispatcherDatabase(&OldIrql);
    00326
    00327     //
    00328     // Capture the previous data alignment handling mode and set the
    00329     // specified data alignment mode.
    00330     //
    00331
    00332     Previous = Thread->AutoAlignment;
    00333     Thread->AutoAlignment = Enable;
    00334
    00335     //
    00336     // Unlock dispatcher database, lower IRQL to its previous value, and
    00337     // return the previous data alignment mode.
    00338     //
    00339
    00340     KiUnlockDispatcherDatabase(OldIrql);
    00341     return Previous;
    00342 }
    }

VOID KiInitializeContextThread | ( | IN PKTHREAD | Thread,
|  | IN PKSYSTEM_ROUTINE | SystemRoutine,
|  | IN PKSTART_ROUTINE StartRoutine | OPTIONAL,
|  | IN PVOID StartContext | OPTIONAL,
|  | IN PCONTEXT ContextRecord | OPTIONAL
| ) |

Definition at line 45 of file ppc/thredini.c.

References ASSERT, CONTEXT_CONTROL, KeContextToKframes(), KernelMode, KiThreadStartup(), NULL, and UserMode.

Referenced by KeInitializeThread().

    00055                    :
    00056
    00057     This function initializes the machine dependent context of a thread object.
    00058
    00059     Actually, what it does is to lay out the stack for the thread so that
    00060     it contains a stack frame that will be picked up by SwapContext and
    00061     returned thru, resulting in a transfer of control to KiThreadStartup.
    00062     In otherwords, we lay out a stack with a stack frame that looks as if
    00063     SwapContext had been called just before the first instruction in
    00064     KiThreadStartup.
    00065
    00066     N.B. This function does not check the accessibility of the context record.
    00067          It is assumed the the caller of this routine is either prepared to
    00068          handle access violations or has probed and copied the context record
    00069          as appropriate.
    00070
    00071     N.B. Arguments to the new thread are passed in the Swap Frame gprs
    00072          16 thru 20 which will be loaded into the thread's gprs when
    00073          execution begins.
    00074
    00075     WARNING: If the thread has a user mode context the Top of stack MUST
    00076              be laid out identically to the top of stack laid out when an
    00077              interrupt or system call from user mode occurs.
    00078
    00079 Arguments:
    00080
    00081     Thread - Supplies a pointer to a dispatcher object of type thread.
    00082
    00083     SystemRoutine - Supplies a pointer to the system function that is to be
    00084         called when the thread is first scheduled for execution.
    00085
    00086     StartRoutine - Supplies an optional pointer to a function that is to be
    00087         called after the system has finished initializing the thread. This
    00088         parameter is specified if the thread is a system thread and will
    00089         execute totally in kernel mode.
    00090
    00091     StartContext - Supplies an optional pointer to an arbitrary data structure
    00092         which will be passed to the StartRoutine as a parameter. This
    00093         parameter is specified if the thread is a system thread and will
    00094         execute totally in kernel mode.
    00095
    00096     ContextRecord - Supplies an optional pointer a context frame which contains
    00097         the initial user mode state of the thread. This parameter is specified
    00098         if the thread is a user thread and will execute in user mode. If this
    00099         parameter is not specified, then the Teb parameter is ignored.
    00100
    00101 Return Value:
    00102
    00103     None.
    00104
    00105 --*/
    00106
    00107 {
    00108
    00109     PKEXCEPTION_FRAME ExFrame;
    00110     ULONG InitialStack;
    00111     PKTRAP_FRAME TrFrame;
    00112     PKSWAP_FRAME SwFrame;
    00113     PSTACK_FRAME_HEADER StkFrame, ResumeFrame;
    00114
    00115     //
    00116     // If the initial stack address is in KSEG0, then the stack is not mapped
    00117     // and the kernel stack PTEs are set to zero. Otherwise, capture the PTEs
    00118     // that map the kernel stack.
    00119     //
    00120
    00121     InitialStack = (LONG)Thread->InitialStack;
    00122
    00123     //
    00124     // If a context frame is specified, then initialize a trap frame and
    00125     // and an exception frame with the specified user mode context.
    00126     //
    00127
    00128     if (ARGUMENT_PRESENT(ContextRecord)) {
    00129         ExFrame = (PKEXCEPTION_FRAME)(InitialStack - 8 -
    00130                   sizeof(KEXCEPTION_FRAME));
    00131         TrFrame = (PKTRAP_FRAME)((ULONG)ExFrame -  sizeof(KTRAP_FRAME));
    00132         StkFrame = (PSTACK_FRAME_HEADER)((ULONG)TrFrame - (8 * sizeof(ULONG)) -
    00133                   sizeof(STACK_FRAME_HEADER));
    00134
    00135         //
    00136         // Zero the exception and trap frames and copy information from the
    00137         // specified context frame to the trap and exception frames.
    00138         //
    00139
    00140         RtlZeroMemory((PVOID)ExFrame, sizeof(KEXCEPTION_FRAME));
    00141         RtlZeroMemory((PVOID)TrFrame, sizeof(KTRAP_FRAME));
    00142         KeContextToKframes(TrFrame, ExFrame,
    00143                            ContextRecord,
    00144                            ContextRecord->ContextFlags | CONTEXT_CONTROL,
    00145                            UserMode);
    00146
    00147         //
    00148         // Set the saved previous processor mode in the trap frame and the
    00149         // previous processor mode in the thread object to user mode.
    00150         //
    00151
    00152         TrFrame->PreviousMode = UserMode;
    00153         Thread->PreviousMode = UserMode;
    00154
    00155     } else {
    00156
    00157         StkFrame = (PSTACK_FRAME_HEADER)((InitialStack -
    00158                   sizeof(STACK_FRAME_HEADER)) & 0xfffffff0);
    00159         ExFrame = NULL;
    00160         TrFrame = NULL;
    00161
    00162         //
    00163         // Set the previous mode in thread object to kernel.
    00164         //
    00165
    00166         Thread->PreviousMode = KernelMode;
    00167     }
    00168
    00169     StkFrame->BackChain = (ULONG)0;
    00170
    00171     //
    00172     // Initialize the Swap Frame that swap context will use to
    00173     // initiate execution of this thread.
    00174     //
    00175
    00176     SwFrame = (PKSWAP_FRAME)(((ULONG)StkFrame -
    00177               sizeof(KSWAP_FRAME)) & 0xfffffff0);
    00178
    00179     //
    00180     // Initialize stack frame and set thread start up parameters.
    00181     //
    00182
    00183     if (ExFrame == NULL) {
    00184         SwFrame->ExceptionFrame.Gpr20 = (ULONG)ExFrame;
    00185     } else {
    00186         SwFrame->ExceptionFrame.Gpr20 = (ULONG)TrFrame;
    00187     }
    00188
    00189     SwFrame->ExceptionFrame.Gpr16 = (ULONG)ContextRecord;
    00190     SwFrame->ExceptionFrame.Gpr17 = (ULONG)StartContext;
    00191     SwFrame->ExceptionFrame.Gpr18 = (ULONG)StartRoutine;
    00192
    00193     //
    00194     // Pass the actual entry point addresses rather than the function
    00195     // descriptor's address.
    00196     //
    00197
    00198     SwFrame->ExceptionFrame.Gpr19 = *(ULONG *)SystemRoutine;
    00199
    00200     SwFrame->SwapReturn = *(ULONG *)KiThreadStartup;
    00201     SwFrame->ConditionRegister = 0;
    00202
    00203     //
    00204     // Buy a stack frame so we have the stack frame that will be
    00205     // current when SwapContext is running when we resume this
    00206     // thread.
    00207
    00208
    00209     ResumeFrame = ((PSTACK_FRAME_HEADER)SwFrame) - 1;
    00210
    00211     ResumeFrame->BackChain = (ULONG)StkFrame;
    00212
    00213     //
    00214     // Set the initial kernel stack pointer.
    00215     //
    00216
    00217     Thread->KernelStack = (PVOID)ResumeFrame;
    00218     ASSERT(!((ULONG)ResumeFrame & 0x7));        // ensure stack is align 8
    00219     return;
    00220 }