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 <thomas.faber@reactos.org>
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 
START_TEST(KeIrql)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     /* test KeRaiseIrqlToDpcLevel */
96     ok_irql(PASSIVE_LEVEL);
97     Irql = KeRaiseIrqlToDpcLevel();
98     ok_irql(DISPATCH_LEVEL);
99     ok_eq_uint(Irql, PASSIVE_LEVEL);
100     Irql = KeRaiseIrqlToDpcLevel();
101     ok_irql(DISPATCH_LEVEL);
102     ok_eq_uint(Irql, DISPATCH_LEVEL);
103     KeLowerIrql(PASSIVE_LEVEL);
104 
105     /* test KeRaiseIrqlToSynchLevel */
106     ok_irql(PASSIVE_LEVEL);
107     Irql = KeRaiseIrqlToSynchLevel();
108     ok_irql(SynchIrql);
109     ok_eq_uint(Irql, PASSIVE_LEVEL);
110     Irql = KeRaiseIrqlToSynchLevel();
111     ok_irql(SynchIrql);
112     ok_eq_uint(Irql, SynchIrql);
113     KeLowerIrql(PASSIVE_LEVEL);
114 
115     /* these bugcheck on a checked build but run fine on free! */
116     if (!KmtIsCheckedBuild)
117     {
118         KeRaiseIrql(HIGH_LEVEL, &Irql);
119         KeRaiseIrql(APC_LEVEL, &Irql);
120         ok_irql(APC_LEVEL);
121         KeLowerIrql(HIGH_LEVEL);
122         ok_irql(HIGH_LEVEL);
123         KeLowerIrql(PASSIVE_LEVEL);
124     }
125 
126 #ifndef _M_AMD64
127     /* try the actual exports, not only the fastcall versions */
128     ok_irql(PASSIVE_LEVEL);
129     (KeRaiseIrql)(HIGH_LEVEL, &Irql);
130     ok_irql(HIGH_LEVEL);
131     ok_eq_uint(Irql, PASSIVE_LEVEL);
132     (KeLowerIrql)(Irql);
133     ok_irql(PASSIVE_LEVEL);
134 #endif
135 
136     /* make sure we exit gracefully */
137     ok_irql(PASSIVE_LEVEL);
138     KeLowerIrql(PASSIVE_LEVEL);
139 }
140