[KMTESTS]
[reactos.git] / rostests / kmtests / ntos_ke / KeIrql.c
1 /*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Interrupt Request Level test
5 * PROGRAMMER: Thomas Faber <thfabba@gmx.de>
6 */
7
8 #ifndef _M_AMD64
9 __declspec(dllimport) void __stdcall KeRaiseIrql(unsigned char, unsigned char *);
10 __declspec(dllimport) void __stdcall KeLowerIrql(unsigned char);
11 #else
12 #define CLOCK1_LEVEL CLOCK_LEVEL
13 #define CLOCK2_LEVEL CLOCK_LEVEL
14 #endif
15
16 #include <kmt_test.h>
17
18 #define NDEBUG
19 #include <debug.h>
20
21 START_TEST(KeIrql)
22 {
23 KIRQL Irql, Irql2, PrevIrql, SynchIrql;
24
25 /* we should be called at PASSIVE_LEVEL */
26 ok_irql(PASSIVE_LEVEL);
27
28 PrevIrql = KeGetCurrentIrql();
29
30 /* SYNCH_LEVEL is different for UP/MP */
31 if (KmtIsMultiProcessorBuild)
32 SynchIrql = IPI_LEVEL - 2;
33 else
34 SynchIrql = DISPATCH_LEVEL;
35
36 /* some Irqls MUST work */
37 {
38 const KIRQL Irqls[] = { LOW_LEVEL, PASSIVE_LEVEL, APC_LEVEL, DISPATCH_LEVEL,
39 CMCI_LEVEL, CLOCK1_LEVEL, CLOCK2_LEVEL, CLOCK_LEVEL,
40 PROFILE_LEVEL, IPI_LEVEL, /*POWER_LEVEL,*/ SynchIrql, HIGH_LEVEL };
41 int i;
42 for (i = 0; i < sizeof Irqls / sizeof Irqls[0]; ++i)
43 {
44 KeRaiseIrql(Irqls[i], &Irql2);
45 ok_eq_uint(Irql2, PrevIrql);
46 ok_irql(Irqls[i]);
47 KeLowerIrql(Irql2);
48 ok_irql(PrevIrql);
49 }
50 }
51
52 /* raising/lowering to the current level should have no effect */
53 ok_irql(PASSIVE_LEVEL);
54 KeRaiseIrql(PASSIVE_LEVEL, &Irql);
55 ok_eq_uint(Irql, PASSIVE_LEVEL);
56 KeLowerIrql(PASSIVE_LEVEL);
57 ok_irql(PASSIVE_LEVEL);
58
59 /* try to raise to each Irql and back */
60 for (Irql = PASSIVE_LEVEL; Irql <= HIGH_LEVEL; ++Irql)
61 {
62 DPRINT("Raising to %u\n", Irql);
63 KeRaiseIrql(Irql, &Irql2);
64 ok_eq_uint(Irql2, PrevIrql);
65 KeLowerIrql(Irql2);
66 ok_irql(PrevIrql);
67 }
68
69 /* go through all Irqls in order, skip the ones that the system doesn't accept */
70 for (Irql = PASSIVE_LEVEL; Irql <= HIGH_LEVEL; ++Irql)
71 {
72 DPRINT("Raising to %u\n", Irql);
73 KeRaiseIrql(Irql, &Irql2);
74 ok_eq_uint(Irql2, PrevIrql);
75 Irql2 = KeGetCurrentIrql();
76 ok(Irql2 <= Irql, "New Irql is %u, expected <= requested value of %u\n", Irql2, Irql);
77 PrevIrql = Irql2;
78 }
79
80 ok_irql(HIGH_LEVEL);
81
82 /* now go back again, skipping the ones that don't work */
83 for (Irql = HIGH_LEVEL; Irql > PASSIVE_LEVEL;)
84 {
85 DPRINT("Lowering to %u\n", Irql - 1);
86 KeLowerIrql(Irql - 1);
87 Irql2 = KeGetCurrentIrql();
88 ok(Irql2 < Irql, "New Irql is %u, expected <= requested value of %u\n", Irql2, Irql - 1);
89 if (Irql2 < Irql)
90 Irql = Irql2;
91 else
92 --Irql;
93 }
94
95 DPRINT("Alive!\n");
96 /* on x86, you can raise to _any_ possible KIRQL value */
97 /* on x64, anything with more than the least significant 4 bits set bugchecked, last time I tried */
98 /* TODO: other platforms? */
99 #if defined _M_IX86
100 for (Irql = PASSIVE_LEVEL; Irql <= (KIRQL)-1; ++Irql)
101 {
102 DPRINT("Raising to %u\n", Irql);
103 KeRaiseIrql(Irql, &Irql2);
104 ok_eq_uint(Irql2, PrevIrql);
105 KeLowerIrql(Irql2);
106 ok_irql(PrevIrql);
107 }
108 #endif /* defined _M_IX86 */
109
110 /* test KeRaiseIrqlToDpcLevel */
111 ok_irql(PASSIVE_LEVEL);
112 Irql = KeRaiseIrqlToDpcLevel();
113 ok_irql(DISPATCH_LEVEL);
114 ok_eq_uint(Irql, PASSIVE_LEVEL);
115 Irql = KeRaiseIrqlToDpcLevel();
116 ok_irql(DISPATCH_LEVEL);
117 ok_eq_uint(Irql, DISPATCH_LEVEL);
118 KeLowerIrql(PASSIVE_LEVEL);
119
120 /* test KeRaiseIrqlToSynchLevel */
121 ok_irql(PASSIVE_LEVEL);
122 Irql = KeRaiseIrqlToSynchLevel();
123 ok_irql(SynchIrql);
124 ok_eq_uint(Irql, PASSIVE_LEVEL);
125 Irql = KeRaiseIrqlToSynchLevel();
126 ok_irql(SynchIrql);
127 ok_eq_uint(Irql, SynchIrql);
128 KeLowerIrql(PASSIVE_LEVEL);
129
130 /* these bugcheck on a checked build but run fine on free! */
131 if (!KmtIsCheckedBuild)
132 {
133 KeRaiseIrql(HIGH_LEVEL, &Irql);
134 KeRaiseIrql(APC_LEVEL, &Irql);
135 ok_irql(APC_LEVEL);
136 KeLowerIrql(HIGH_LEVEL);
137 ok_irql(HIGH_LEVEL);
138 KeLowerIrql(PASSIVE_LEVEL);
139 }
140
141 #ifndef _M_AMD64
142 /* try the actual exports, not only the fastcall versions */
143 ok_irql(PASSIVE_LEVEL);
144 (KeRaiseIrql)(HIGH_LEVEL, &Irql);
145 ok_irql(HIGH_LEVEL);
146 ok_eq_uint(Irql, PASSIVE_LEVEL);
147 (KeLowerIrql)(Irql);
148 ok_irql(PASSIVE_LEVEL);
149 #endif
150
151 /* make sure we exit gracefully */
152 ok_irql(PASSIVE_LEVEL);
153 KeLowerIrql(PASSIVE_LEVEL);
154 }