Managing interrupt processing (irq.h)
The API is defined in the header file sysroot-*-kos/include/coresrv/io/irq.h
from the KasperskyOS SDK.
The API manages the handling of hardware interrupts. A hardware interrupt is a signal sent from a device to direct the processor to immediately pause execution of the current program and instead handle an event related to this device. For example, pressing a key on the keyboard invokes a hardware interrupt that ensures the required response to this pressed key (for example, input of a character).
A hardware interrupt occurs when the device queries the interrupt controller. This query can be transmitted through a hardware interrupt line between the device and the interrupt controller or through MMIO memory. In the second case, the device writes to MMIO memory by calling the Message Signaled Interrupt (MSI).
At present, no functions for managing the handling of MSI interrupts have been implemented.
Each hardware interrupt line corresponds to one interrupt with a unique number.
Information about API functions is provided in the table below.
Using the API
To attach an interrupt to its handler, complete the following steps:
- Registering an interrupt by calling the
KnRegisterIrq()
function.One interrupt can be registered multiple times in one or more processes.
The handle of an interrupt can be transferred to another process via IPC.
- Attaching a thread to an interrupt by calling the
KnIoAttachIrq()
function.This step is performed by the thread in whose context the interrupt will be handled.
When using the handle received from the
KnRegisterIrq()
function call, you can attach only one thread to an interrupt. To attach multiple threads in one or more processes to an interrupt, use different handles for this interrupt received from separateKnRegisterIrq()
function calls. In this case, theKnIoAttachIrq()
function must be called with the same flags in theflags
parameter.A handle received when calling the
KnIoAttachIrq()
function cannot be transferred to another process via IPC.
To deny (mask) an interrupt, call the KnIoDisableIrq()
function. To allow (unmask) an interrupt, call the KnIoEnableIrq()
function. Even though these functions receive an interrupt handle that is used to attach only one thread to the interrupt, their action is applied to all threads that are attached to this interrupt. These functions must be called outside of the threads attached to the interrupt. After an interrupt is registered and a thread is attached to it, this interrupt does not require unmasking.
To initiate detachment of a thread from an interrupt, call the KnIoDetachIrq()
function outside of the thread that is attached to the interrupt. Detachment is performed by the thread attached to the interrupt by calling the KnThreadDetachIrq()
function declared in the header file sysroot-*-kos/include/coresrv/thread/thread_api.h
from the KasperskyOS SDK.
Handling an interrupt
After attaching to an interrupt, a thread calls the Call()
function declared in the header file sysroot-*-kos/include/coresrv/syscalls.h
from the KasperskyOS SDK. The thread is locked as a result of this call. When an interrupt occurs or the KnIoDetachIrq()
function is called, the KasperskyOS kernel sends an IPC message to the process that contains this thread. This IPC message contains a request to handle the interrupt or a request to detach the thread from the interrupt. When a process receives an IPC message, the Call()
function in the thread attached to the interrupt returns control and provides the contents of the IPC message to the thread. The thread extracts the request from the IPC message and either processes the interrupt or detaches from the interrupt. If the interrupt is processed, information about its failure or success upon completion is added to the response IPC message that is sent to the kernel by the next Call()
function call in the loop.
When processing an interrupt, use the IoGetIrqRequest()
and IoSetIrqAnswer()
functions that are declared in the header file sysroot-*-kos/include/io/io_irq.h
from the KasperskyOS SDK. These functions let you extract data from IPC messages and add data to IPC messages for data exchange between the kernel and the thread attached to the interrupt.
The standard interrupt processing loop includes the following steps:
- Adding information about the failure or success of interrupt processing to an IPC message by calling the
IoSetIrqAnswer()
function. - Sending the IPC message to the kernel and receiving an IPC message from the kernel.
To complete this step, call the
Call()
functions. In thehandle
parameter, you must specify the handle that was received when theKnIoAttachIrq()
function was called. You must use themsgOut
parameter to define the IPC message that will be sent to the kernel, and use themsgIn
parameter to define the IPC message that will be received from the kernel. - Extracting a request from the IPC message received from the kernel by calling the
IoGetIrqRequest()
function. - Processing the interrupt or detaching from the interrupt depending on the request.
If the request requires detachment from the interrupt, exit the interrupt processing loop and call the
KnThreadDetachIrq()
function.
Deregistering an interrupt
To deregister an interrupt, complete the following steps:
- Detach the thread from the interrupt.
To complete this step, call the
KnThreadDetachIrq()
function. - Close the handle that was received when the
KnIoAttachIrq()
function was called.To complete this step, call the
KnHandleClose()
function. (TheKnHandleClose()
function is declared in the header filesysroot-*-kos/include/coresrv/handle/handle_api.h
from the KasperskyOS SDK.) - Close or revoke each interrupt handle in all processes that own these handles.
To complete this step, use the
KnHandleClose()
and/orKnHandleRevoke()
functions that are declared in the header filesysroot-*-kos/include/coresrv/handle/handle_api.h
from the KasperskyOS SDK.
One interrupt can be registered multiple times, but completion of these steps cancels only one registration. The other registrations will remain active. Each registration of one interrupt must be canceled separately.
Information about API functions
irq.h functions
Function |
Information about the function |
---|---|
|
Purpose Registers an interrupt. Parameters
Returned values If successful, the function returns |
|
Purpose Attaches the calling thread to an interrupt. Parameters
Returned values If successful, the function returns Additional information In the
|
|
Purpose Sends a request to a thread. When this request is fulfilled, the thread must detach from the interrupt. Parameters
Returned values If successful, the function returns |
|
Purpose Allows (unmasks) an interrupt. Parameters
Returned values If successful, the function returns |
|
Purpose Denies (masks) an interrupt. Parameters
Returned values If successful, the function returns |