Memory-mapped I/O (mmio.h)

The API is defined in the header file sysroot-*-kos/include/coresrv/io/mmio.h from the KasperskyOS SDK.

The API is intended for working with MMIO memory. MMIO memory consists of physical addresses that are mapped to registers and memory of devices. (Portions of one physical address space are used for physical memory addressing and access to registers and memory of devices.)

Information about API functions is provided in the table below.

Using the API

The standard scenario for API usage includes the following steps:

  1. The MMIO memory region corresponding to the relevant device is registered.

    To complete this step, call the KnRegisterPhyMem() function. If the same MMIO memory region needs to be registered multiple times, the MMIO_U_SHARED flag must be specified in the flags parameter during each registration of this region. If the registered MMIO memory region is used by the kernel code, the MMIO_K_SHARED flag must be specified. If these flags are not specified, only the code that requests this access first (this can be either the kernel code or the code that is executed in user mode) will have access to the MMIO memory region. All subsequent registration attempts by calling the KnRegisterPhyMem() function will end with the rcAlreadyExists error, and messages regarding the problem with shared access to the MMIO memory region will be added to the diagnostic output. If the kernel fails to access the MMIO memory region because this region is already registered by the code being executed in user mode, a message regarding the problem with shared access to the MMIO memory region will also be added to the diagnostic output.

    The handle of an MMIO memory region can be transferred to another process via IPC.

  2. Mapping the MMIO memory region to the memory of a process.

    An MMIO memory region can only be mapped to one virtual memory region of only one process at one time. (However, an MMIO memory region may be mapped to the virtual memory of different processes that own the handle of this region at different times.) Mapping allows the process to receive read-and/or-write access to the MMIO memory region.

    To reserve a virtual memory region and map the MMIO memory region to it, call the KnIoMapMem() function.

    A handle received when calling the KnIoMapMem() function cannot be transferred to another process via IPC.

  3. Reading data from the MMIO memory region and writing data to it via process memory.

    The 8-, 16- and 32-bit words that are read from the MMIO memory region or written to it are values of device registers or contents of device memory.

    To complete this step, use the IoReadMmReg8|16|32() and IoWriteMmReg8|16|32() functions.

The API includes the auxiliary functions named KnIoMemHandlesClear() and KnIoMemHandlesClose(). The KnIoMemHandlesClear() function initializes the structure for storing the handles that are created at steps 1 and 2. The KnIoMemHandlesClose() function closes the handles stored in this structure (by calling the KnHandleClose() function from the handle_api.h API) and initializes it. When the KnIoMemHandlesClose() function is called, the absence of all or one handle in the structure does not result in an error, and the available handle will be closed. The KnIoMemHandlesClear() and KnIoMemHandlesClose() functions can be used as follows. Before performing step 1, initialize the structure for storing handles by calling the KnIoMemHandlesClear() function. Then store the handles in this structure when performing steps 1 and 2. This will allow you to subsequently close all created handles with a single call of the KnIoMemHandlesClose() function.

Deregistering an MMIO memory region

To deregister an MMIO memory region, complete the following steps:

  1. Free the virtual memory region that was allocated when the KnIoMapMem() function was called.

    To perform this step, you must close the handle that was obtained when calling the KnIoMapMem() function.

  2. Close or revoke each handle of the MMIO memory region in all processes that own those handles.

You can use the KnIoMemHandlesClose() function to close the handles when performing these steps.

Information about API functions

mmio.h functions

Function(s)

Information about the function(s)

KnRegisterPhyMem()

Purpose

Registers an MMIO memory region.

Parameters

  • [in] addr – page-aligned base address of the MMIO memory region.
  • [in] size – size (in bytes) of the MMIO memory region. It must be a multiple of the memory page size.
  • [in,optional] flags – flags that specify the MMIO memory region parameters, or 0 if these parameters are not required. The flags are defined in the header file sysroot-*-kos/include/io/io_mmio.h from the KasperskyOS SDK.
  • [out] outRid – pointer to the handle of the MMIO memory region.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

Additional information

In the flags parameter, you can specify the following flags:

  • MMIO_K_SHARED – shared access with the kernel.
  • MMIO_U_SHARED – shared access with multiple registrations.

KnIoMapMem()

Purpose

Reserves the virtual memory region and maps the MMIO memory region to it.

Parameters

  • [in] rid – handle of the MMIO memory region.
  • [in] prot – flags defining the access rights to the virtual memory region. The flags are defined in the header file sysroot-*-kos/include/vmm/flags.h from the KasperskyOS SDK.
  • [in] attr – flags defining the cache settings. The flags are defined in the header file sysroot-*-kos/include/vmm/flags.h from the KasperskyOS SDK.
  • [out] addr – pointer to the base address of the virtual memory region.
  • [out] handle – pointer to the handle that is used to free the virtual memory region.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

Additional information

In the prot parameter, you can specify the following flags:

  • VMM_FLAG_READ – read access.
  • VMM_FLAG_WRITE – write access.

In the attr parameter, you can specify the following flags:

  • VMM_FLAG_WRITE_BACK, VMM_FLAG_WRITE_THROUGH, VMM_FLAG_WRITE_COMBINE, VMM_FLAG_CACHE_DISABLE – cache management.

    It is recommended to specify the VMM_FLAG_CACHE_DISABLE flag.

IoReadMmReg8()

IoReadMmReg16()

IoReadMmReg32()

Purpose

Get an 8-, 16- or 32-bit word from an MMIO memory region.

Parameters

  • [in] reg – virtual address for reading the word.

Returned values

8-, 16- or 32-bit word from the MMIO memory region.

IoWriteMmReg8()

IoWriteMmReg16()

IoWriteMmReg32()

Purpose

Write an 8-, 16- or 32-bit word to an MMIO memory region.

Parameters

  • [in] reg – virtual address for writing the word.
  • [in] data – word to write.

Returned values

N/A

KnIoMemHandlesClear()

Purpose

Initializes a structure for storing the handles of resources allocated for MMIO provisioning.

Parameters

  • [out] handles – pointer to the structure for storing handles.

Returned values

N/A

Additional information

After initialization, the structure fields take the INVALID_HANDLE value.

KnIoMemHandlesClose()

Purpose

Closes the handles of resources allocated for MMIO provisioning and initializes the structure in which these handles were stored.

Parameters

  • [in, out] handles – pointer to a structure for storing handles.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

Additional information

After initialization, the structure fields take the INVALID_HANDLE value.

Page top