Added Intel MultiProcessor Specification support
[reactos.git] / reactos / ntoskrnl / include / internal / ps.h
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2000 David Welch <welch@cwcom.net>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /*
20 * FILE: ntoskrnl/ke/kthread.c
21 * PURPOSE: Process manager definitions
22 * PROGRAMMER: David Welch (welch@cwcom.net)
23 * UPDATE HISTORY:
24 * Created 22/05/98
25 */
26
27 #ifndef __INCLUDE_INTERNAL_PS_H
28 #define __INCLUDE_INTERNAL_PS_H
29
30 /*
31 * Defines for accessing KPCR and KTHREAD structure members
32 */
33 #define KTHREAD_INITIAL_STACK 0x18
34 #define KTHREAD_TEB 0x20
35 #define KTHREAD_KERNEL_STACK 0x28
36 #define KTHREAD_PREVIOUS_MODE 0x137
37 #define KTHREAD_TRAP_FRAME 0x128
38
39 #define ETHREAD_THREADS_PROCESS 0x258
40
41 #define KPROCESS_PAGE_TABLE_DIRECTORY 0x10
42
43 #define KPCR_BASE 0xFF000000
44
45 #define KPCR_EXCEPTION_LIST 0x0
46 #define KPCR_SELF 0x18
47 #define KPCR_CURRENT_THREAD 0x124
48
49 #ifndef __ASM__
50
51 #include <internal/mm.h>
52
53 struct _KTHREAD;
54 struct _KTRAPFRAME;
55
56 /* FIXME: This does not work if we have more than 24 IRQs (ie. more than one I/O APIC) */
57 #define VECTOR2IRQ(vector) (((vector) - 0x31) / 8)
58 #define VECTOR2IRQL(vector) (4 + VECTOR2IRQ(vector))
59
60 /*
61 * Processor Control Region
62 */
63 typedef struct _KPCR
64 {
65 PVOID ExceptionList; /* 00 */
66 PVOID StackBase; /* 04 */
67 PVOID StackLimit; /* 08 */
68 PVOID SubSystemTib; /* 0C */
69 PVOID Reserved1; /* 10 */
70 PVOID ArbitraryUserPointer; /* 14 */
71 struct _KPCR* Self; /* 18 */
72 UCHAR ProcessorNumber; /* 1C */
73 KIRQL Irql; /* 1D */
74 UCHAR Reserved2[0x2]; /* 1E */
75 PUSHORT IDT; /* 20 */
76 PUSHORT GDT; /* 24 */
77 UCHAR Reserved3[0xFC]; /* 28 */
78 struct _KTHREAD* CurrentThread; /* 124 */
79 } __attribute__((packed)) KPCR, *PKPCR;
80
81 static inline PKPCR KeGetCurrentKPCR(VOID)
82 {
83 ULONG value;
84
85 __asm__ __volatile__ ("movl %%fs:0x18, %0\n\t"
86 : "=r" (value)
87 : /* no inputs */
88 );
89 return((PKPCR)value);
90 }
91
92 #define CURRENT_KPCR KeGetCurrentKPCR()
93
94 #define KeGetCurrentProcessorNumber (KeGetCurrentKPCR()->ProcessorNumber)
95
96 extern HANDLE SystemProcessHandle;
97
98 typedef struct _KAPC_STATE
99 {
100 LIST_ENTRY ApcListHead[2];
101 struct _KPROCESS* Process;
102 UCHAR KernelApcInProgress;
103 UCHAR KernelApcPending;
104 USHORT UserApcPending;
105 } __attribute__((packed)) KAPC_STATE, *PKAPC_STATE;
106
107 typedef struct _KTHREAD
108 {
109 /* For waiting on thread exit */
110 DISPATCHER_HEADER DispatcherHeader; /* 00 */
111
112 /* List of mutants owned by the thread */
113 LIST_ENTRY MutantListHead; /* 10 */
114 PVOID InitialStack; /* 18 */
115 ULONG StackLimit; /* 1C */
116
117 /* Pointer to the thread's environment block in user memory */
118 NT_TEB* Teb; /* 20 */
119
120 /* Pointer to the thread's TLS array */
121 PVOID TlsArray; /* 24 */
122 PVOID KernelStack; /* 28 */
123 UCHAR DebugActive; /* 2C */
124
125 /* Thread state (one of THREAD_STATE_xxx constants below) */
126 UCHAR State; /* 2D */
127 UCHAR Alerted[2]; /* 2E */
128 UCHAR Iopl; /* 30 */
129 UCHAR NpxState; /* 31 */
130 UCHAR Saturation; /* 32 */
131 CHAR Priority; /* 33 */
132 KAPC_STATE ApcState; /* 34 */
133 ULONG ContextSwitches; /* 4C */
134 ULONG WaitStatus; /* 50 */
135 KIRQL WaitIrql; /* 54 */
136 UCHAR WaitMode; /* 55 */
137 UCHAR WaitNext; /* 56 */
138 UCHAR WaitReason; /* 57 */
139 PKWAIT_BLOCK WaitBlockList; /* 58 */
140 LIST_ENTRY WaitListEntry; /* 5C */
141 ULONG WaitTime; /* 64 */
142 CHAR BasePriority; /* 68 */
143 UCHAR DecrementCount; /* 69 */
144 UCHAR PriorityDecrement; /* 6A */
145 UCHAR Quantum; /* 6B */
146 KWAIT_BLOCK WaitBlock[4]; /* 6C */
147 PVOID LegoData; /* CC */
148 LONG KernelApcDisable; /* D0 */
149 KAFFINITY UserAffinity; /* D4 */
150 UCHAR SystemAffinityActive;/* D8 */
151 UCHAR Pad[7]; /* D9 */
152 PKQUEUE Queue; /* E0 */
153 KSPIN_LOCK ApcQueueLock; /* E4 */
154 KTIMER Timer; /* E8 */
155 LIST_ENTRY QueueListEntry; /* 110 */
156 KAFFINITY Affinity; /* 118 */
157 UCHAR Preempted; /* 11C */
158 UCHAR ProcessReadyQueue; /* 11D */
159 UCHAR KernelStackResident; /* 11E */
160 UCHAR NextProcessor; /* 11F */
161 PVOID CallbackStack; /* 120 */
162 BOOL Win32Thread; /* 124 */
163 struct _KTRAP_FRAME* TrapFrame; /* 128 */
164 PVOID ApcStatePointer[2]; /* 12C */
165 UCHAR EnableStackSwap; /* 134 */
166 UCHAR LargeStack; /* 135 */
167 UCHAR ResourceIndex; /* 136 */
168 UCHAR PreviousMode; /* 137 */
169 ULONG KernelTime; /* 138 */
170 ULONG UserTime; /* 13C */
171 KAPC_STATE SavedApcState; /* 140 */
172 UCHAR Alertable; /* 158 */
173 UCHAR ApcStateIndex; /* 159 */
174 UCHAR ApcQueueable; /* 15A */
175 UCHAR AutoAlignment; /* 15B */
176 PVOID StackBase; /* 15C */
177 KAPC SuspendApc; /* 160 */
178 KSEMAPHORE SuspendSemaphore; /* 190 */
179 LIST_ENTRY ThreadListEntry; /* 1A4 */
180 CHAR FreezeCount; /* 1AC */
181 UCHAR SuspendCount; /* 1AD */
182 UCHAR IdealProcessor; /* 1AE */
183 UCHAR DisableBoost; /* 1AF */
184
185 /*
186 * Below here are thread structure members that are specific to ReactOS
187 */
188
189 /* Added by Phillip Susi for list of threads in a process */
190 LIST_ENTRY ProcessThreadListEntry; /* 1B0 */
191
192 /* Added by Phillip Susi for internal KeAddThreadTimeout() implementation */
193 KDPC TimerDpc; /* 1B8 */
194
195 /* Record the last EIP value when the thread is suspended */
196 ULONG LastEip; /* 1D8 */
197 } __attribute__((packed)) KTHREAD, *PKTHREAD;
198
199 // According to documentation the stack should have a commited [ 1 page ] and
200 // a reserved part [ 1 M ] but can be specified otherwise in the image file.
201
202
203
204
205
206
207
208 // TopLevelIrp can be one of the following values:
209 // FIXME I belong somewhere else
210
211 #define FSRTL_FSP_TOP_LEVEL_IRP (0x01)
212 #define FSRTL_CACHE_TOP_LEVEL_IRP (0x02)
213 #define FSRTL_MOD_WRITE_TOP_LEVEL_IRP (0x03)
214 #define FSRTL_FAST_IO_TOP_LEVEL_IRP (0x04)
215 #define FSRTL_MAX_TOP_LEVEL_IRP_FLAG (0x04)
216
217 typedef struct _TOP_LEVEL_IRP
218 {
219 PIRP TopLevelIrp;
220 ULONG TopLevelIrpConst;
221 } TOP_LEVEL_IRP;
222
223 typedef struct
224 {
225 PACCESS_TOKEN Token; // 0x0
226 UCHAR Unknown1; // 0x4
227 UCHAR Unknown2; // 0x5
228 UCHAR Pad[2]; // 0x6
229 SECURITY_IMPERSONATION_LEVEL Level; // 0x8
230 } PS_IMPERSONATION_INFO, *PPS_IMPERSONATION_INFO;
231
232 struct _WIN32THREADDATA;
233
234 typedef struct _ETHREAD
235 {
236 KTHREAD Tcb; /* 000 */
237 TIME CreateTime; /* 1B0/1DC */
238 union
239 {
240 TIME ExitTime; /* 1B8/1E4 */
241 LIST_ENTRY LpcReplyChain; /* 1B8/1E4 */
242 } u1;
243 NTSTATUS ExitStatus; /* 1C0/1EC */
244 LIST_ENTRY PostBlockList; /* 1C4/1F0 */
245 LIST_ENTRY TerminationPortList; /* 1CC/1F8 */
246 KSPIN_LOCK ActiveTimerListLock; /* 1D4/200 */
247 LIST_ENTRY ActiveTimerListHead; /* 1D8/204 */
248 CLIENT_ID Cid; /* 1E0/20C */
249 KSEMAPHORE LpcReplySemaphore; /* 1E8/214 */
250 PVOID LpcReplyMessage; /* 1FC/228 */
251 PLARGE_INTEGER LpcReplyMessageId; /* 200/22C */
252 ULONG PerformanceCounterLow; /* 204/230 */
253 PPS_IMPERSONATION_INFO ImpersonationInfo; /* 208/234 */
254 LIST_ENTRY IrpList; /* 20C/238 */
255 TOP_LEVEL_IRP* TopLevelIrp; /* 214/240 */
256 PDEVICE_OBJECT DeviceToVerify; /* 218/244 */
257 ULONG ReadClusterSize; /* 21C/248 */
258 UCHAR ForwardClusterOnly; /* 220/24C */
259 UCHAR DisablePageFaultClustering; /* 221/24D */
260 UCHAR DeadThread; /* 222/24E */
261 UCHAR HasTerminated; /* 223/24F */
262 PVOID EventPair; /* 224/250 */
263 ACCESS_MASK GrantedAccess; /* 228/254 */
264 struct _EPROCESS* ThreadsProcess; /* 22C/258 */
265 PKSTART_ROUTINE StartAddress; /* 230/25C */
266 union
267 {
268 LPTHREAD_START_ROUTINE Win32StartAddress; /* 234/260 */
269 ULONG LpcReceiveMessageId; /* 234/260 */
270 } u2;
271 UCHAR LpcExitThreadCalled; /* 238/264 */
272 UCHAR HardErrorsAreDisabled; /* 239/265 */
273 UCHAR LpcReceivedMsgIdValid; /* 23A/266 */
274 UCHAR ActiveImpersonationInfo; /* 23B/267 */
275 ULONG PerformanceCountHigh; /* 23C/268 */
276
277 /*
278 * Added by David Welch (welch@cwcom.net)
279 */
280 struct _EPROCESS* OldProcess; /* 240/26C */
281 struct _WIN32THREADDATA *Win32ThreadData; // Pointer to win32 private thread data
282
283 } __attribute__((packed)) ETHREAD, *PETHREAD;
284
285
286 typedef struct _KPROCESS
287 {
288 DISPATCHER_HEADER DispatcherHeader; /* 000 */
289 PVOID PageTableDirectory; /* 010 */
290 TIME ElapsedTime;
291 TIME KernelTime;
292 TIME UserTime;
293 LIST_ENTRY InMemoryList;
294 LIST_ENTRY SwappedOutList;
295 KSPIN_LOCK SpinLock;
296 KAFFINITY Affinity;
297 ULONG StackCount;
298 KPRIORITY BasePriority;
299 ULONG DefaultThreadQuantum;
300 UCHAR ProcessState;
301 ULONG ThreadSeed;
302 UCHAR DisableBoost;
303 } KPROCESS, *PKPROCESS;
304
305 struct _WIN32PROCESSDATA;
306
307 typedef struct _EPROCESS
308 {
309 KPROCESS Pcb;
310 NTSTATUS ExitStatus;
311 KEVENT LockEvent;
312 ULONG LockCount;
313 TIME CreateTime;
314 TIME ExitTime;
315 PVOID LockOwner;
316 ULONG UniqueProcessId;
317 LIST_ENTRY ActiveProcessLinks;
318 ULONG QuotaPeakPoolUsage[2];
319 ULONG QuotaPoolUsage[2];
320 ULONG PagefileUsage;
321 ULONG CommitCharge;
322 ULONG PeakPagefileUsage;
323 ULONG PeakVirtualUsage;
324 LARGE_INTEGER VirtualSize;
325 PVOID Vm; // Actually 48 bytes
326 PVOID LastProtoPteFault;
327 struct _EPORT* DebugPort;
328 struct _EPORT* ExceptionPort;
329 PVOID ObjectTable;
330 PVOID Token;
331 KMUTEX WorkingSetLock;
332 PVOID WorkingSetPage;
333 UCHAR ProcessOutswapEnabled;
334 UCHAR ProcessOutswapped;
335 UCHAR AddressSpaceInitialized;
336 UCHAR AddressSpaceDeleted;
337 KMUTEX AddressCreationLock;
338 PVOID ForkInProgress;
339 PVOID VmOperation;
340 PKEVENT VmOperationEvent;
341 PVOID PageDirectoryPte;
342 LARGE_INTEGER LastFaultCount;
343 PVOID VadRoot;
344 PVOID VadHint;
345 PVOID CloneRoot;
346 ULONG NumberOfPrivatePages;
347 ULONG NumberOfLockedPages;
348 UCHAR ForkWasSuccessFul;
349 UCHAR ExitProcessCalled;
350 UCHAR CreateProcessReported;
351 HANDLE SectionHandle;
352 PPEB Peb;
353 PVOID SectionBaseAddress;
354 PVOID QuotaBlock;
355 NTSTATUS LastThreadExitStatus;
356 LARGE_INTEGER WorkingSetWatch; //
357 ULONG InheritedFromUniqueProcessId;
358 ACCESS_MASK GrantedAccess;
359 ULONG DefaultHardErrorProcessing;
360 PVOID LdtInformation;
361 ULONG VadFreeHint;
362 PVOID VdmObjects;
363 KMUTANT ProcessMutant;
364 CHAR ImageFileName[16];
365 LARGE_INTEGER VmTrimFaultValue;
366 struct _WIN32PROCESSDATA *Win32Process;
367
368 /*
369 * Added by David Welch (welch@mcmail.com)
370 */
371 MADDRESS_SPACE AddressSpace;
372 HANDLE_TABLE HandleTable;
373 LIST_ENTRY ProcessListEntry;
374
375 /*
376 * Added by Philip Susi for list of threads in process
377 */
378 LIST_ENTRY ThreadListHead;
379 } EPROCESS, *PEPROCESS;
380
381 #define PROCESS_STATE_TERMINATED (1)
382 #define PROCESS_STATE_ACTIVE (2)
383
384 VOID PiInitProcessManager(VOID);
385 VOID PiShutdownProcessManager(VOID);
386 VOID PsInitThreadManagment(VOID);
387 VOID PsInitProcessManagment(VOID);
388 VOID PsInitIdleThread(VOID);
389 VOID PsDispatchThread(ULONG NewThreadStatus);
390 VOID PsDispatchThreadNoLock(ULONG NewThreadStatus);
391 VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus);
392 VOID PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus);
393 VOID PsReleaseThread(PETHREAD Thread);
394 VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext);
395 VOID PsBeginThreadWithContextInternal(VOID);
396 VOID PiKillMostProcesses(VOID);
397 NTSTATUS STDCALL PiTerminateProcess(PEPROCESS Process, NTSTATUS ExitStatus);
398 ULONG PsUnfreezeThread(PETHREAD Thread, PNTSTATUS WaitStatus);
399 ULONG PsFreezeThread(PETHREAD Thread, PNTSTATUS WaitStatus,
400 UCHAR Alertable, ULONG WaitMode);
401 VOID PiInitApcManagement(VOID);
402 VOID PiDeleteThread(PVOID ObjectBody);
403 VOID PiCloseThread(PVOID ObjectBody, ULONG HandleCount);
404 VOID PsReapThreads(VOID);
405 NTSTATUS
406 PsInitializeThread(HANDLE ProcessHandle,
407 PETHREAD* ThreadPtr,
408 PHANDLE ThreadHandle,
409 ACCESS_MASK DesiredAccess,
410 POBJECT_ATTRIBUTES ObjectAttributes,
411 BOOLEAN First);
412
413 PACCESS_TOKEN PsReferenceEffectiveToken(PETHREAD Thread,
414 PTOKEN_TYPE TokenType,
415 PUCHAR b,
416 PSECURITY_IMPERSONATION_LEVEL Level);
417
418 NTSTATUS PsOpenTokenOfProcess(HANDLE ProcessHandle,
419 PACCESS_TOKEN* Token);
420
421 NTSTATUS PsSuspendThread(PETHREAD Thread, PULONG PreviousCount);
422 NTSTATUS PsResumeThread(PETHREAD Thread, PULONG PreviousCount);
423
424
425 #define THREAD_STATE_INVALID (0)
426 #define THREAD_STATE_RUNNABLE (1)
427 #define THREAD_STATE_RUNNING (2)
428 #define THREAD_STATE_SUSPENDED (3)
429 #define THREAD_STATE_FROZEN (4)
430 #define THREAD_STATE_TERMINATED_1 (5)
431 #define THREAD_STATE_TERMINATED_2 (6)
432 #define THREAD_STATE_BLOCKED (7)
433 #define THREAD_STATE_MAX (8)
434
435
436 /*
437 * Internal thread priorities, added by Phillip Susi
438 * TODO: rebalence these to make use of all priorities... the ones above 16 can not all be used right now
439 */
440
441 #define PROCESS_PRIO_IDLE 3
442 #define PROCESS_PRIO_NORMAL 8
443 #define PROCESS_PRIO_HIGH 13
444 #define PROCESS_PRIO_RT 18
445
446
447 VOID
448 KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First);
449
450 VOID HalInitFirstTask(PETHREAD thread);
451 NTSTATUS
452 Ke386InitThread(PKTHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext);
453 VOID HalTaskSwitch(PKTHREAD thread);
454 NTSTATUS
455 Ke386InitThreadWithContext(PKTHREAD Thread, PCONTEXT Context);
456 NTSTATUS HalReleaseTask(PETHREAD Thread);
457 VOID PiDeleteProcess(PVOID ObjectBody);
458 VOID PsReapThreads(VOID);
459 VOID PsUnfreezeOtherThread(PETHREAD Thread);
460 VOID PsFreezeOtherThread(PETHREAD Thread);
461 VOID PsFreezeProcessThreads(PEPROCESS Process);
462 VOID PsUnfreezeProcessThreads(PEPROCESS Process);
463 PEPROCESS PsGetNextProcess(PEPROCESS OldProcess);
464 VOID
465 Ki386ContextSwitch(PKTHREAD NewThread, PKTHREAD OldThread);
466 VOID
467 PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
468 BOOLEAN DispatcherLock, KIRQL WaitIrql);
469 VOID
470 PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus);
471
472 #endif /* ASSEMBLER */
473
474 #endif /* __INCLUDE_INTERNAL_PS_H */