xref: /reactos/ntoskrnl/ke/freeze.c (revision d6eebaa4)
1 /*
2  * PROJECT:         ReactOS Kernel
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * FILE:            ntoskrnl/ke/freeze.c
5  * PURPOSE:         Routines for freezing and unfreezing processors for
6  *                  kernel debugger synchronization.
7  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
8  */
9 
10 /* INCLUDES *******************************************************************/
11 
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* GLOBALS ********************************************************************/
17 
18 /* Freeze data */
19 KIRQL KiOldIrql;
20 ULONG KiFreezeFlag;
21 
22 /* FUNCTIONS ******************************************************************/
23 
24 BOOLEAN
25 NTAPI
26 KeFreezeExecution(IN PKTRAP_FRAME TrapFrame,
27                   IN PKEXCEPTION_FRAME ExceptionFrame)
28 {
29     BOOLEAN Enable;
30     KIRQL OldIrql;
31 
32 #ifndef CONFIG_SMP
33     UNREFERENCED_PARAMETER(TrapFrame);
34     UNREFERENCED_PARAMETER(ExceptionFrame);
35 #endif
36 
37     /* Disable interrupts, get previous state and set the freeze flag */
38     Enable = KeDisableInterrupts();
39     KiFreezeFlag = 4;
40 
41 #ifndef CONFIG_SMP
42     /* Raise IRQL if we have to */
43     OldIrql = KeGetCurrentIrql();
44     if (OldIrql < DISPATCH_LEVEL)
45         OldIrql = KeRaiseIrqlToDpcLevel();
46 #else
47     /* Raise IRQL to HIGH_LEVEL */
48     KeRaiseIrql(HIGH_LEVEL, &OldIrql);
49 #endif
50 
51 #ifdef CONFIG_SMP
52     /* Architecture specific freeze code */
53     KxFreezeExecution();
54 #endif
55 
56     /* Save the old IRQL to be restored on unfreeze */
57     KiOldIrql = OldIrql;
58 
59     /* Return whether interrupts were enabled */
60     return Enable;
61 }
62 
63 VOID
64 NTAPI
65 KeThawExecution(IN BOOLEAN Enable)
66 {
67 #ifdef CONFIG_SMP
68     /* Architecture specific thaw code */
69     KxThawExecution();
70 #endif
71 
72     /* Clear the freeze flag */
73     KiFreezeFlag = 0;
74 
75     /* Cleanup CPU caches */
76     KeFlushCurrentTb();
77 
78     /* Restore the old IRQL */
79 #ifndef CONFIG_SMP
80     if (KiOldIrql < DISPATCH_LEVEL)
81 #endif
82     KeLowerIrql(KiOldIrql);
83 
84     /* Re-enable interrupts */
85     KeRestoreInterrupts(Enable);
86 }
87