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