Share via


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.

See Also

Other Resources

OAL - Interrupt Tests