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