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 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