OAL User Mode Interrupt Tests (Compact 2013)
3/26/2014
The OAL Interrupt Tests assess the behavior of interrupt-related I/O controls (IOCTLs) in the OEM Adaptation Layer (OAL). The tests verify that the IOCTLs process parameters correctly and that the return values are correct.
The OAL Interrupt Tests exercise the following IOCTLs:
- IOCTL_HAL_REQUEST_SYSINTR
- IOCTL_HAL_RELEASE_SYSINTR
- IOCTL_HAL_REQUEST_IRQ
You can achieve good test coverage of interrupts using the following OAL tests:
- OAL Interrupt Tests
- OAL Timer Tests
- OAL KITL Tests
Note the following points regarding this test:
- Interrupt testing cannot be isolated from the device drivers that use these interrupts or from the timer routines that use the system tick.
- The allocation and release tests can run on any image. These tests must be signed so that they have low-level access to the interrupt IOCTL routines.
- IRQ ranges are used throughout the code. The default ranges are currently set from 0 to 1024. For some of the tests, the IRQ range can be set by the command-line arguments. All IRQ ranges are inclusive unless otherwise specified.
- The IOCTLs should only be called in kernel mode. In user mode, the kernel should prevent the OAL code from even being called. The test is run in user mode to confirm that none of the calls complete successfully.
- The IOCTL test code has numerous internal checks that confirm that the correct data is returned. Two important ones:
- Valid SYSINTRs: Valid SYSINTRs must be between [0, 71]. Anything else is an error.
- Number of free SYSINTRs before and after the test: The tests are designed to leave the system in the state in which they found it. This can be confirmed by comparing the number of free SYSINTRs before and after the test. This helps catch errors both on the tests and in the routines themselves.
- "Extended flag structure" allows the OAL_INTR_* flags to specify more actions to the IOCTLs.
- Since the interrupt routines control essential system behavior, trashed tables that map the IRQs to SYSINTRs generally lead to system instability and crashes. It is recommended that each test case be run individually to eliminate risk of adjacent test cases impacting test results. As part of the Windows Embedded Compact Test Kit (CTK), these tests are run in two passes: kernel mode and user mode (these require different command lines). A failure in the test normally causes all of the others to break. This should be noted by anyone looking at Windows Embedded Compact Test Kit (CTK) results.
Test Prerequisites
Your device must meet the following requirements before you run this test.
* The OAL must implement IOCTL_HAL_REQUEST_SYSINTR IOCTL.
The following table shows the software requirements for the test:
Requirement |
Description |
---|---|
Tux.exe |
Tux test harness, required for executing the test |
ktux.dll |
Required for running tests in kernel mode |
kato.dll |
Kato logging engine, required for logging test data |
oaltestinterrupts.dll |
Library that contains OAL interrupt tests |
Subtests
The following table lists the subtests included in this test.
SubTest ID |
Description |
---|---|
1000 |
Free SYSINTRs that should not be freed. Any SYSINTR less than 8 or greater than 71 is not valid. Freeing these should result in FALSE from the IOCTL and no change in the system. This test tries to release these SYSINTRs. Since releasing ~ 2^32 interrupts takes a long time, we hit the most likely values: * [0, 7] * [72, 256] * Boundaries of powers of two (plus/minus 1) * (-256, -1] (include SYSINTR_UNDEFINED = -1) * 10,000 random SYSINTR values between [72, 0xffff_ffff] |
12000 |
Single IRQ Allocations: Single IRQ Standard Alloc IRQ Range: Command line or default No allocations can be made from user mode. The user-mode versions of these tests fail if any allocations are successful. Since all cases should fail, we must exercise all possible - IRQ values. There is no "In Range" test, since this is a subset of the default range. |
12100 |
Single IRQ Allocations: Single IRQ Static Alloc IRQ Range: Command line or default No allocations can be made from user mode. The user-mode versions of these tests fail if any allocations are successful. Since all cases should fail, we must exercise all possible - IRQ values. There is no "In Range" test, since this is a subset of the default range. |
12200 |
Single IRQ Allocations: Single IRQ Dynamic Alloc IRQ Range: Command line or default No allocations can be made from user mode. The user mode versions of these tests fail if any allocations are successful. Since all cases should fail, we must exercise all possible - IRQ values. There is no "In Range" test, since this is a subset of the default range. |
14000 |
Multiple IRQ Allocations: Mult IRQ Static Alloc IRQ Range: Command line or default These test cases randomly generate a set of IRQs for a given call. The IRQs come from the IRQ range (see discussion below). The number of IRQs passed to the IOCTL varies from 1 to the maximum number allowed on the system, as determined by the test. The test tries 100 different allocations for each number of IRQs. In user mode, none of the allocations should succeed. Only the default range is offered, since the command line offers a subset of what should pass. |
14100 |
Multiple IRQ Allocations: Mult IRQ Dynamic Alloc IRQ Range: Command line or default These test cases randomly generate a set of IRQs for a given call. The IRQs come from the IRQ range (see discussion below). The number of IRQs passed to the IOCTL varies from 1 to the maximum number allowed on the system, as determined by the test. The test tries 100 different allocations for each number of IRQs. In user mode, none of the allocations should succeed. Only the default range is offered, since the command line offers a subset of what should pass. |
14200 |
Multiple IRQ Allocations: Mult IRQ Force-Static Alloc IRQ Range: Command line or default These test cases randomly generate a set of IRQs for a given call. The IRQs come from the IRQ range (see discussion below). The number of IRQs passed to the IOCTL varies from 1 to the maximum number allowed on the system, as determined by the test. The test tries 100 different allocations for each number of IRQs. In user mode, none of the allocations should succeed. Only the default range is offered, since the command line offers a subset of what should pass. |
20010 |
IOCTL_HAL_REQUEST_IRQ: Incorrect Parameter Checks: Bad Input Size IRQ Range: Command line or default Confirm that any size not = sizeof (DEVICE_LOCATION) causes a failure. |
20020 |
IOCTL_HAL_REQUEST_IRQ: Incorrect Parameter Checks: Bad Output Size IRQ Range: Command line or default This IOCTL supports multiple IRQs on output. Bad inputs consist of outputBufSize < 4 bytes. The test code uses random values for the inbound structures, which unfortunately does not provide ideal coverage, since these random values would fail anyway. |
30100 |
IOCTL_HAL_REQUEST_IRQ: Random Request IRQ Range: Command line or default IOCTL_HAL_REQUEST_IRQ is used to hardcode certain DEVICE_LOCATION values to certain IRQs in the platform. This appears to be used only in PCI and serial kitl. The input is a DEVICE_LOCATION structure. The fields in this structure are compared against special cased values in the OAL. The return value is an IRQ. The input space is very large. Every platform seems to use different fields and have different values for these fields. Furthermore, the constants range all over the map. We can’t put any range on them. The "Random Request" test randomly selects values for the fields of the DEVICE_LOCATION structure. The goal is not to find a set of values that work with the IOCTL; rather, it is to try to cause a crash/memory access violation by sending in bad input. To run the second test, call the test with test arguments: -dev IfcType BusNumber LogicalLoc Pin Note that the DEVICE_LOCATION structure also has a PhysicalLoc value. This is a PVOID and is reserved for future use, so is set to zero by the test. In user mode, this test should never succeed. Either test will fail if the IOCTL ever succeeds when run in user mode. |
30200 |
IOCTL_HAL_REQUEST_IRQ: User Specified Params (see test case 30100) The "User Specified Params" test allows the user to pass in values to the IOCTL. These values do not necessarily cause the IOCTL to succeed. This test always passes, since the test has no idea what the user expects to happen with these arguments. Call the test with test arguments: -dev IfcType BusNumber LogicalLoc Pin Note that the DEVICE_LOCATION structure also has a PhysicalLoc value. This is a PVOID and is reserved for future use, so is set to zero by the test. |
500 |
IOCTL_HAL_REQUEST_SYSINTR: Bad Input (Extended flag structure) - Incomplete Args IRQ Range: Command line or default Checks the following: * Null on both the in buffer and out buffer * Inbound size of two DWORDs (in this case no IRQs were provided) |
510 |
IOCTL_HAL_REQUEST_SYSINTR: Bad Input (Extended flag structure) - Bad Input Sizes IRQ Range: Command or default Inbound structure must be DWORDs, so length must always be a multiple of four. Furthermore, it must always be > 2 DWORDs, or 8 bytes. Confirm this up to an arbitrary 32 bytes. |
520 |
IOCTL_HAL_REQUEST_SYSINTR: Bad Input Size IRQ Range: Command line or default Confirm that anything except for 4 bytes causes a failure. |
530 |
IOCTL_HAL_REQUEST_SYSINTR: Bad Flags IRQ Range: Command line or default Test works from 0 to 256, skipping the valid flags (OAL_INTR_TRANSLATE, OAL_INTR_STATIC, OAL_INTR_DYNAMIC, OAL_INTR_FORCE_STATIC). |
540 |
IOCTL_HAL_REQUEST_SYSINTR: Bad Out Size (Extended flag structure) IRQ Range: Command line or default Any size less than 4 bytes causes failure. Note that only 4 bytes is needed for output. If given more, the IOCTL ignores it. |
550 |
IOCTL_HAL_REQUEST_SYSINTR: Bad Out Size IRQ Range: Command line or default Any size less than 4 bytes causes failure. Note that only 4 bytes is needed for output. If given more, the IOCTL ignores it. |
600 |
IOCTL_HAL_RELEASE_SYSINTR: Bad Input Size IRQ Range: Command line or default Confirm that anything other than 4 bytes causes an error. This IOCTL passes no output. In this case the code is supposed to completely ignore the output values, include lpBytesReturned. |
Setting Up the Test
This test has no additional requirements beyond the standard test environment setup.
Running the Test
The test performs the following during default execution:
Tux.exe -o -d oaltestinterrupts.dll -x500-1000,10000-19999,20000-20099,30000-39999
The following table shows the command-line parameters for the OAL Interrupt tests.
Command-line parameter |
Description |
---|---|
-irqEnd <n> |
Specifies the end of the inclusive IRQs on the device. Default is 1024. |
-irqBegin <n> |
Specifies the beginning of the inclusive range of IRQs on the device. Default is 0. |
-dev <values> |
Specifies the values for the DEVICE_LOCATION structure to pass to IOCTL_HAL_REQUEST_IRQ. Can be ignored unless specifically needed. For more information, see the test case descriptions. |
Verifying the Test
When the test completes running, verify that "PASS" appears in the test log for all subtests.
Troubleshooting the Test
- Verify you are running the test in kernel mode, with the "-n" parameter provided on the command line.
- Verify how SYSINTRs are allocated and if there may be a leak.
- Verify the implementation of the SYSINTR IOCTLs in the OAL.
- On larger images; more IRQs may be reserved or used which could interfere with the test. Although the test has been designed to work with many IRQ configurations, some tests may be affected. Therefore, if the test fails, you may want to re-run it on a smaller run-time image with fewer potential IRQs in use.
- Determine the point of failure and record the exact error message. Check that the setup steps were followed and that all pre-requisites were met. If the source code is available, examine the point of failure in code to see if any additional information can be gathered about the failure domain.