- Invert CONFIG_SMP defines as requested by Hartmut
[reactos.git] / reactos / ntoskrnl / include / internal / ke.h
1 #ifndef __NTOSKRNL_INCLUDE_INTERNAL_KE_H
2 #define __NTOSKRNL_INCLUDE_INTERNAL_KE_H
3
4 /* INCLUDES *****************************************************************/
5
6 #include "arch/ke.h"
7
8 /* INTERNAL KERNEL TYPES ****************************************************/
9
10 typedef struct _WOW64_PROCESS
11 {
12 PVOID Wow64;
13 } WOW64_PROCESS, *PWOW64_PROCESS;
14
15 typedef struct _KPROFILE_SOURCE_OBJECT
16 {
17 KPROFILE_SOURCE Source;
18 LIST_ENTRY ListEntry;
19 } KPROFILE_SOURCE_OBJECT, *PKPROFILE_SOURCE_OBJECT;
20
21 /* Cached modules from the loader block */
22 typedef enum _CACHED_MODULE_TYPE
23 {
24 AnsiCodepage,
25 OemCodepage,
26 UnicodeCasemap,
27 SystemRegistry,
28 HardwareRegistry,
29 MaximumCachedModuleType,
30 } CACHED_MODULE_TYPE, *PCACHED_MODULE_TYPE;
31 extern PLOADER_MODULE CachedModules[MaximumCachedModuleType];
32
33 struct _KIRQ_TRAPFRAME;
34 struct _KPCR;
35 struct _KPRCB;
36 struct _KEXCEPTION_FRAME;
37
38 extern PVOID KeUserApcDispatcher;
39 extern PVOID KeUserCallbackDispatcher;
40 extern PVOID KeUserExceptionDispatcher;
41 extern PVOID KeRaiseUserExceptionDispatcher;
42 extern LARGE_INTEGER SystemBootTime;
43 extern ULONG_PTR KERNEL_BASE;
44
45 /* MACROS *************************************************************************/
46
47 /*
48 * On UP machines, we don't actually have a spinlock, we merely raise
49 * IRQL to DPC level.
50 */
51 #ifdef CONFIG_SMP
52 #define KeInitializeDispatcher() KeInitializeSpinLock(&DispatcherDatabaseLock);
53 #define KeAcquireDispatcherDatabaseLock() KfAcquireSpinLock(&DispatcherDatabaseLock);
54 #define KeAcquireDispatcherDatabaseLockAtDpcLevel() \
55 KeAcquireSpinLockAtDpcLevel (&DispatcherDatabaseLock);
56 #define KeReleaseDispatcherDatabaseLockFromDpcLevel() \
57 KeReleaseSpinLockFromDpcLevel(&DispatcherDatabaseLock);
58 #define KeReleaseDispatcherDatabaseLock(OldIrql) \
59 KeReleaseSpinLockFromDpcLevel(&DispatcherDatabaseLock); \
60 KiExitDispatcher(OldIrql);
61 #else
62 #define KeInitializeDispatcher()
63 #define KeAcquireDispatcherDatabaseLock() KeRaiseIrqlToDpcLevel();
64 #define KeReleaseDispatcherDatabaseLock(OldIrql) KiExitDispatcher(OldIrql);
65 #define KeAcquireDispatcherDatabaseLockAtDpcLevel()
66 #define KeReleaseDispatcherDatabaseLockFromDpcLevel()
67 #endif
68
69 /* The following macro initializes a dispatcher object's header */
70 #define KeInitializeDispatcherHeader(Header, t, s, State) \
71 { \
72 (Header)->Type = t; \
73 (Header)->Absolute = 0; \
74 (Header)->Inserted = 0; \
75 (Header)->Size = s; \
76 (Header)->SignalState = State; \
77 InitializeListHead(&((Header)->WaitListHead)); \
78 }
79
80 /* The following macro satisfies the wait of any dispatcher object */
81 #define KiSatisfyObjectWait(Object, Thread) \
82 { \
83 /* Special case for Mutants */ \
84 if ((Object)->Header.Type == MutantObject) \
85 { \
86 /* Decrease the Signal State */ \
87 (Object)->Header.SignalState--; \
88 \
89 /* Check if it's now non-signaled */ \
90 if (!(Object)->Header.SignalState) \
91 { \
92 /* Set the Owner Thread */ \
93 (Object)->OwnerThread = Thread; \
94 \
95 /* Disable APCs if needed */ \
96 Thread->KernelApcDisable -= (Object)->ApcDisable; \
97 \
98 /* Check if it's abandoned */ \
99 if ((Object)->Abandoned) \
100 { \
101 /* Unabandon it */ \
102 (Object)->Abandoned = FALSE; \
103 \
104 /* Return Status */ \
105 Thread->WaitStatus = STATUS_ABANDONED; \
106 } \
107 \
108 /* Insert it into the Mutant List */ \
109 InsertHeadList(&Thread->MutantListHead, \
110 &(Object)->MutantListEntry); \
111 } \
112 } \
113 else if (((Object)->Header.Type & TIMER_OR_EVENT_TYPE) == \
114 EventSynchronizationObject) \
115 { \
116 /* Synchronization Timers and Events just get un-signaled */ \
117 (Object)->Header.SignalState = 0; \
118 } \
119 else if ((Object)->Header.Type == SemaphoreObject) \
120 { \
121 /* These ones can have multiple states, so we only decrease it */ \
122 (Object)->Header.SignalState--; \
123 } \
124 }
125
126 /* The following macro satisfies the wait of a mutant dispatcher object */
127 #define KiSatisfyMutantWait(Object, Thread) \
128 { \
129 /* Decrease the Signal State */ \
130 (Object)->Header.SignalState--; \
131 \
132 /* Check if it's now non-signaled */ \
133 if (!(Object)->Header.SignalState) \
134 { \
135 /* Set the Owner Thread */ \
136 (Object)->OwnerThread = Thread; \
137 \
138 /* Disable APCs if needed */ \
139 Thread->KernelApcDisable -= (Object)->ApcDisable; \
140 \
141 /* Check if it's abandoned */ \
142 if ((Object)->Abandoned) \
143 { \
144 /* Unabandon it */ \
145 (Object)->Abandoned = FALSE; \
146 \
147 /* Return Status */ \
148 Thread->WaitStatus = STATUS_ABANDONED; \
149 } \
150 \
151 /* Insert it into the Mutant List */ \
152 InsertHeadList(&Thread->MutantListHead, \
153 &(Object)->MutantListEntry); \
154 } \
155 }
156
157 /* The following macro satisfies the wait of any nonmutant dispatcher object */
158 #define KiSatisfyNonMutantWait(Object, Thread) \
159 { \
160 if (((Object)->Header.Type & TIMER_OR_EVENT_TYPE) == \
161 EventSynchronizationObject) \
162 { \
163 /* Synchronization Timers and Events just get un-signaled */ \
164 (Object)->Header.SignalState = 0; \
165 } \
166 else if ((Object)->Header.Type == SemaphoreObject) \
167 { \
168 /* These ones can have multiple states, so we only decrease it */ \
169 (Object)->Header.SignalState--; \
170 } \
171 }
172
173 /* The following macro satisfies multiple objects in a wait state */
174 #define KiSatisifyMultipleObjectWaits(FirstBlock) \
175 { \
176 PKWAIT_BLOCK WaitBlock = FirstBlock; \
177 PKTHREAD WaitThread = WaitBlock->Thread; \
178 \
179 /* Loop through all the Wait Blocks, and wake each Object */ \
180 do \
181 { \
182 /* Make sure it hasn't timed out */ \
183 if (WaitBlock->WaitKey != STATUS_TIMEOUT) \
184 { \
185 /* Wake the Object */ \
186 KiSatisfyObjectWait((PKMUTANT)WaitBlock->Object, WaitThread); \
187 } \
188 \
189 /* Move to the next block */ \
190 WaitBlock = WaitBlock->NextWaitBlock; \
191 } while (WaitBlock != FirstBlock); \
192 }
193
194 extern KSPIN_LOCK DispatcherDatabaseLock;
195
196 #define KeEnterCriticalRegion() \
197 { \
198 PKTHREAD _Thread = KeGetCurrentThread(); \
199 if (_Thread) _Thread->KernelApcDisable--; \
200 }
201
202 #define KeLeaveCriticalRegion() \
203 { \
204 PKTHREAD _Thread = KeGetCurrentThread(); \
205 if((_Thread) && (++_Thread->KernelApcDisable == 0)) \
206 { \
207 if (!IsListEmpty(&_Thread->ApcState.ApcListHead[KernelMode]) && \
208 (_Thread->SpecialApcDisable == 0)) \
209 { \
210 KiCheckForKernelApcDelivery(); \
211 } \
212 } \
213 }
214
215 #define KEBUGCHECKWITHTF(a,b,c,d,e,f) \
216 DbgPrint("KeBugCheckWithTf at %s:%i\n",__FILE__,__LINE__), \
217 KeBugCheckWithTf(a,b,c,d,e,f)
218
219 /* INTERNAL KERNEL FUNCTIONS ************************************************/
220
221 /* threadsch.c ********************************************************************/
222
223 /* Thread Scheduler Functions */
224
225 /* Readies a Thread for Execution. */
226 VOID
227 STDCALL
228 KiDispatchThreadNoLock(ULONG NewThreadStatus);
229
230 /* Readies a Thread for Execution. */
231 VOID
232 STDCALL
233 KiDispatchThread(ULONG NewThreadStatus);
234
235 /* Finds a new thread to run */
236 NTSTATUS
237 NTAPI
238 KiSwapThread(
239 VOID
240 );
241
242 /* Removes a thread out of a block state. */
243 VOID
244 STDCALL
245 KiUnblockThread(
246 PKTHREAD Thread,
247 PNTSTATUS WaitStatus,
248 KPRIORITY Increment
249 );
250
251 NTSTATUS
252 STDCALL
253 KeSuspendThread(PKTHREAD Thread);
254
255 NTSTATUS
256 FASTCALL
257 KiSwapContext(PKTHREAD NewThread);
258
259 VOID
260 STDCALL
261 KiAdjustQuantumThread(IN PKTHREAD Thread);
262
263 VOID
264 FASTCALL
265 KiExitDispatcher(KIRQL OldIrql);
266
267 /* gmutex.c ********************************************************************/
268
269 VOID
270 FASTCALL
271 KiAcquireGuardedMutexContented(PKGUARDED_MUTEX GuardedMutex);
272
273 /* gate.c **********************************************************************/
274
275 VOID
276 FASTCALL
277 KeInitializeGate(PKGATE Gate);
278
279 VOID
280 FASTCALL
281 KeSignalGateBoostPriority(PKGATE Gate);
282
283 VOID
284 FASTCALL
285 KeWaitForGate(
286 PKGATE Gate,
287 KWAIT_REASON WaitReason,
288 KPROCESSOR_MODE WaitMode
289 );
290
291 /* ipi.c ********************************************************************/
292
293 BOOLEAN
294 STDCALL
295 KiIpiServiceRoutine(
296 IN PKTRAP_FRAME TrapFrame,
297 IN struct _KEXCEPTION_FRAME* ExceptionFrame
298 );
299
300 VOID
301 NTAPI
302 KiIpiSendRequest(
303 KAFFINITY TargetSet,
304 ULONG IpiRequest
305 );
306
307 VOID
308 NTAPI
309 KeIpiGenericCall(
310 VOID (STDCALL *WorkerRoutine)(PVOID),
311 PVOID Argument
312 );
313
314 /* next file ***************************************************************/
315
316 VOID
317 STDCALL
318 DbgBreakPointNoBugCheck(VOID);
319
320 VOID
321 STDCALL
322 KeInitializeProfile(
323 struct _KPROFILE* Profile,
324 struct _KPROCESS* Process,
325 PVOID ImageBase,
326 ULONG ImageSize,
327 ULONG BucketSize,
328 KPROFILE_SOURCE ProfileSource,
329 KAFFINITY Affinity
330 );
331
332 VOID
333 STDCALL
334 KeStartProfile(
335 struct _KPROFILE* Profile,
336 PVOID Buffer
337 );
338
339 BOOLEAN
340 STDCALL
341 KeStopProfile(struct _KPROFILE* Profile);
342
343 ULONG
344 STDCALL
345 KeQueryIntervalProfile(KPROFILE_SOURCE ProfileSource);
346
347 VOID
348 STDCALL
349 KeSetIntervalProfile(
350 KPROFILE_SOURCE ProfileSource,
351 ULONG Interval
352 );
353
354 VOID
355 STDCALL
356 KeProfileInterrupt(
357 PKTRAP_FRAME TrapFrame
358 );
359
360 VOID
361 STDCALL
362 KeProfileInterruptWithSource(
363 IN PKTRAP_FRAME TrapFrame,
364 IN KPROFILE_SOURCE Source
365 );
366
367 BOOLEAN
368 STDCALL
369 KiRosPrintAddress(PVOID Address);
370
371 VOID
372 STDCALL
373 KeUpdateSystemTime(
374 PKTRAP_FRAME TrapFrame,
375 KIRQL Irql
376 );
377
378 VOID
379 STDCALL
380 KeUpdateRunTime(
381 PKTRAP_FRAME TrapFrame,
382 KIRQL Irql
383 );
384
385 VOID
386 STDCALL
387 KiExpireTimers(
388 PKDPC Dpc,
389 PVOID DeferredContext,
390 PVOID SystemArgument1,
391 PVOID SystemArgument2
392 );
393
394 VOID
395 STDCALL
396 KeInitializeThread(
397 struct _KPROCESS* Process,
398 PKTHREAD Thread,
399 PKSYSTEM_ROUTINE SystemRoutine,
400 PKSTART_ROUTINE StartRoutine,
401 PVOID StartContext,
402 PCONTEXT Context,
403 PVOID Teb,
404 PVOID KernelStack
405 );
406
407 VOID
408 STDCALL
409 KeRundownThread(VOID);
410
411 NTSTATUS
412 NTAPI
413 KeReleaseThread(PKTHREAD Thread);
414
415 LONG
416 STDCALL
417 KeQueryBasePriorityThread(IN PKTHREAD Thread);
418
419 VOID
420 STDCALL
421 KiSetPriorityThread(
422 PKTHREAD Thread,
423 KPRIORITY Priority,
424 PBOOLEAN Released
425 );
426
427 BOOLEAN
428 NTAPI
429 KiDispatcherObjectWake(
430 DISPATCHER_HEADER* hdr,
431 KPRIORITY increment
432 );
433
434 VOID
435 STDCALL
436 KeExpireTimers(
437 PKDPC Apc,
438 PVOID Arg1,
439 PVOID Arg2,
440 PVOID Arg3
441 );
442
443 VOID
444 NTAPI
445 KeDumpStackFrames(PULONG Frame);
446
447 BOOLEAN
448 NTAPI
449 KiTestAlert(VOID);
450
451 VOID
452 FASTCALL
453 KiAbortWaitThread(
454 PKTHREAD Thread,
455 NTSTATUS WaitStatus,
456 KPRIORITY Increment
457 );
458
459 VOID
460 STDCALL
461 KeInitializeProcess(
462 struct _KPROCESS *Process,
463 KPRIORITY Priority,
464 KAFFINITY Affinity,
465 LARGE_INTEGER DirectoryTableBase
466 );
467
468 ULONG
469 STDCALL
470 KeForceResumeThread(IN PKTHREAD Thread);
471
472 BOOLEAN
473 STDCALL
474 KeDisableThreadApcQueueing(IN PKTHREAD Thread);
475
476 BOOLEAN
477 STDCALL
478 KiInsertTimer(
479 PKTIMER Timer,
480 LARGE_INTEGER DueTime
481 );
482
483 BOOLEAN
484 __inline
485 FASTCALL
486 KiIsObjectSignaled(
487 PDISPATCHER_HEADER Object,
488 PKTHREAD Thread
489 );
490
491 VOID
492 FASTCALL
493 KiWaitTest(
494 PVOID Object,
495 KPRIORITY Increment
496 );
497
498 PULONG
499 NTAPI
500 KeGetStackTopThread(struct _ETHREAD* Thread);
501
502 BOOLEAN
503 STDCALL
504 KeContextToTrapFrame(
505 PCONTEXT Context,
506 PKEXCEPTION_FRAME ExeptionFrame,
507 PKTRAP_FRAME TrapFrame,
508 KPROCESSOR_MODE PreviousMode
509 );
510
511 VOID
512 STDCALL
513 KiDeliverApc(
514 KPROCESSOR_MODE PreviousMode,
515 PVOID Reserved,
516 PKTRAP_FRAME TrapFrame
517 );
518
519 VOID
520 STDCALL
521 KiCheckForKernelApcDelivery(VOID);
522
523 LONG
524 STDCALL
525 KiInsertQueue(
526 IN PKQUEUE Queue,
527 IN PLIST_ENTRY Entry,
528 BOOLEAN Head
529 );
530
531 ULONG
532 STDCALL
533 KeSetProcess(
534 struct _KPROCESS* Process,
535 KPRIORITY Increment
536 );
537
538 VOID
539 STDCALL
540 KeInitializeEventPair(PKEVENT_PAIR EventPair);
541
542 VOID
543 STDCALL
544 KiInitializeUserApc(
545 IN PKEXCEPTION_FRAME Reserved,
546 IN PKTRAP_FRAME TrapFrame,
547 IN PKNORMAL_ROUTINE NormalRoutine,
548 IN PVOID NormalContext,
549 IN PVOID SystemArgument1,
550 IN PVOID SystemArgument2
551 );
552
553 PLIST_ENTRY
554 STDCALL
555 KeFlushQueueApc(
556 IN PKTHREAD Thread,
557 IN KPROCESSOR_MODE PreviousMode
558 );
559
560 VOID
561 STDCALL
562 KiAttachProcess(
563 struct _KTHREAD *Thread,
564 struct _KPROCESS *Process,
565 KIRQL ApcLock,
566 struct _KAPC_STATE *SavedApcState
567 );
568
569 VOID
570 STDCALL
571 KiSwapProcess(
572 struct _KPROCESS *NewProcess,
573 struct _KPROCESS *OldProcess
574 );
575
576 BOOLEAN
577 STDCALL
578 KeTestAlertThread(IN KPROCESSOR_MODE AlertMode);
579
580 BOOLEAN
581 STDCALL
582 KeRemoveQueueApc(PKAPC Apc);
583
584 VOID
585 FASTCALL
586 KiWakeQueue(IN PKQUEUE Queue);
587
588 PLIST_ENTRY
589 STDCALL
590 KeRundownQueue(IN PKQUEUE Queue);
591
592 /* INITIALIZATION FUNCTIONS *************************************************/
593
594 VOID
595 NTAPI
596 KeInitExceptions(VOID);
597
598 VOID
599 NTAPI
600 KeInitInterrupts(VOID);
601
602 VOID
603 NTAPI
604 KeInitTimer(VOID);
605
606 VOID
607 NTAPI
608 KeInitDpc(struct _KPRCB* Prcb);
609
610 VOID
611 NTAPI
612 KeInitDispatcher(VOID);
613
614 VOID
615 NTAPI
616 KiInitializeSystemClock(VOID);
617
618 VOID
619 NTAPI
620 KiInitializeBugCheck(VOID);
621
622 VOID
623 NTAPI
624 Phase1Initialization(PVOID Context);
625
626 VOID
627 NTAPI
628 KeInit1(
629 PCHAR CommandLine,
630 PULONG LastKernelAddress
631 );
632
633 VOID
634 NTAPI
635 KeInit2(VOID);
636
637 BOOLEAN
638 NTAPI
639 KiDeliverUserApc(PKTRAP_FRAME TrapFrame);
640
641 VOID
642 STDCALL
643 KiMoveApcState(
644 PKAPC_STATE OldState,
645 PKAPC_STATE NewState
646 );
647
648 VOID
649 NTAPI
650 KiAddProfileEvent(
651 KPROFILE_SOURCE Source,
652 ULONG Pc
653 );
654
655 VOID
656 NTAPI
657 KiDispatchException(
658 PEXCEPTION_RECORD ExceptionRecord,
659 PKEXCEPTION_FRAME ExceptionFrame,
660 PKTRAP_FRAME Tf,
661 KPROCESSOR_MODE PreviousMode,
662 BOOLEAN SearchFrames
663 );
664
665 VOID
666 NTAPI
667 KeTrapFrameToContext(
668 IN PKTRAP_FRAME TrapFrame,
669 IN PKEXCEPTION_FRAME ExceptionFrame,
670 IN OUT PCONTEXT Context
671 );
672
673 VOID
674 NTAPI
675 KeApplicationProcessorInit(VOID);
676
677 VOID
678 NTAPI
679 KePrepareForApplicationProcessorInit(ULONG id);
680
681 ULONG
682 NTAPI
683 KiUserTrapHandler(
684 PKTRAP_FRAME Tf,
685 ULONG ExceptionNr,
686 PVOID Cr2
687 );
688
689 VOID
690 STDCALL
691 KePushAndStackSwitchAndSysRet(
692 ULONG Push,
693 PVOID NewStack
694 );
695
696 VOID
697 STDCALL
698 KeStackSwitchAndRet(PVOID NewStack);
699
700 VOID
701 STDCALL
702 KeBugCheckWithTf(
703 ULONG BugCheckCode,
704 ULONG BugCheckParameter1,
705 ULONG BugCheckParameter2,
706 ULONG BugCheckParameter3,
707 ULONG BugCheckParameter4,
708 PKTRAP_FRAME Tf
709 );
710
711 VOID
712 STDCALL
713 KiDumpTrapFrame(
714 PKTRAP_FRAME Tf,
715 ULONG ExceptionNr,
716 ULONG cr2
717 );
718
719 VOID
720 STDCALL
721 KeFlushCurrentTb(VOID);
722
723 VOID
724 STDCALL
725 KeRosDumpStackFrames(
726 PULONG Frame,
727 ULONG FrameCount
728 );
729
730 ULONG
731 STDCALL
732 KeRosGetStackFrames(
733 PULONG Frames,
734 ULONG FrameCount
735 );
736
737 VOID
738 NTAPI
739 KiSetSystemTime(PLARGE_INTEGER NewSystemTime);
740
741 NTSTATUS
742 STDCALL
743 Ke386CallBios(
744 UCHAR Int,
745 PKV86M_REGISTERS Regs
746 );
747
748 ULONG
749 NTAPI
750 KeV86Exception(
751 ULONG ExceptionNr,
752 PKTRAP_FRAME Tf,
753 ULONG address
754 );
755
756 #endif /* __NTOSKRNL_INCLUDE_INTERNAL_KE_H */