[KMTESTS:MM]
[reactos.git] / rostests / kmtests / ntos_io / IoInterrupt.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 test
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include <kmt_test.h>
9
10 #define NDEBUG
11 #include <debug.h>
12
13 #define CheckSpinLock(Lock, Locked) do \
14 { \
15 if (KmtIsMultiProcessorBuild) \
16 ok_eq_ulongptr(*(Lock), (Locked) != 0); \
17 else \
18 ok_eq_ulongptr(*(Lock), 0); \
19 } while (0)
20
21 typedef struct
22 {
23 BOOLEAN ReturnValue;
24 KIRQL ExpectedIrql;
25 PKINTERRUPT Interrupt;
26 } TEST_CONTEXT, *PTEST_CONTEXT;
27
28 static KSYNCHRONIZE_ROUTINE SynchronizeRoutine;
29
30 static
31 BOOLEAN
32 NTAPI
33 SynchronizeRoutine(
34 IN PVOID Context)
35 {
36 PTEST_CONTEXT TestContext = Context;
37
38 ok_irql(TestContext->ExpectedIrql);
39
40 CheckSpinLock(TestContext->Interrupt->ActualLock, TRUE);
41
42 return TestContext->ReturnValue;
43 }
44
45 static
46 VOID
47 TestSynchronizeExecution(VOID)
48 {
49 KINTERRUPT Interrupt;
50 TEST_CONTEXT TestContext;
51 KIRQL SynchIrql;
52 KIRQL OriginalIrql;
53 KIRQL Irql;
54 KSPIN_LOCK ActualLock;
55 BOOLEAN Ret;
56
57 RtlFillMemory(&Interrupt, sizeof Interrupt, 0x55);
58 Interrupt.ActualLock = &ActualLock;
59 KeInitializeSpinLock(Interrupt.ActualLock);
60 CheckSpinLock(Interrupt.ActualLock, FALSE);
61
62 TestContext.Interrupt = &Interrupt;
63 TestContext.ReturnValue = TRUE;
64
65 for (TestContext.ReturnValue = 0; TestContext.ReturnValue <= 2; ++TestContext.ReturnValue)
66 {
67 for (OriginalIrql = PASSIVE_LEVEL; OriginalIrql <= HIGH_LEVEL; ++OriginalIrql)
68 {
69 /* TODO: don't hardcode this :| */
70 if (OriginalIrql == 3 || (OriginalIrql >= 11 && OriginalIrql <= 26) || OriginalIrql == 30)
71 continue;
72 KeRaiseIrql(OriginalIrql, &Irql);
73 for (SynchIrql = max(DISPATCH_LEVEL, OriginalIrql); SynchIrql <= HIGH_LEVEL; ++SynchIrql)
74 {
75 if (SynchIrql == 3 || (SynchIrql >= 11 && SynchIrql <= 26) || SynchIrql == 30)
76 continue;
77 Interrupt.SynchronizeIrql = SynchIrql;
78 ok_irql(OriginalIrql);
79 CheckSpinLock(Interrupt.ActualLock, FALSE);
80 TestContext.ExpectedIrql = SynchIrql;
81 Ret = KeSynchronizeExecution(&Interrupt, SynchronizeRoutine, &TestContext);
82 ok_eq_int(Ret, TestContext.ReturnValue);
83 ok_irql(OriginalIrql);
84 CheckSpinLock(Interrupt.ActualLock, FALSE);
85 /* TODO: Check that all other fields of the interrupt are untouched */
86 }
87 KeLowerIrql(Irql);
88 }
89 }
90 }
91
92 START_TEST(IoInterrupt)
93 {
94 TestSynchronizeExecution();
95 }