KasperskyOS Community Edition 1.1
[Topic libkos_dma]

DmaInfo

The structure describing the DMA buffer is declared in the io/io_dma.h file.

typedef struct {

/** DMA flags (attributes). */

DmaAttr flags;

/** Minimum order of DMA blocks in the buffer. */

rtl_size_t orderMin;

/** DMA buffer size. */

rtl_size_t size;

/** Number of DMA blocks (less than or equal to DMA_FRAMES_COUNT_MAX).

* It may be equal to 0 if a DMA buffer is not available for the device. */

rtl_size_t count;

/** Array of DMA block descriptors. */

union DmaFrameDescriptor {

struct {

/** Order of the DMA block. The number of pages in a block is equal to two

* to the power of the specified order. */

DmaAddr order: DMA_FRAME_ORDER_BITS;

/** Physical or IOMMU address of the DMA block. */

DmaAddr frame: DMA_FRAME_BASE_BITS;

};

/** DMA block descriptor */

DmaAddr raw;

} descriptors[1];

} DmaInfo;

Page top
[Topic dma_info]

DMA flags

DMA flags (attributes) are declared in the io/io_dma.h file.

  • DMA_DIR_TO_DEVICE allows transactions from the main memory to the device memory.
  • DMA_DIR_FROM_DEVICE allows transactions from the device memory to the main memory.
  • DMA_DIR_BIDIR allows transactions from the main memory to the device memory, and vice versa.
  • DMA_ZONE_DMA32 allows the use of only the first 4 GB of memory for the buffer.
  • DMA_ATTR_WRITE_BACK, DMA_ATTR_WRITE_THROUGH, DMA_ATTR_CACHE_DISABLE, and DMA_ATTR_WRITE_COMBINE are for managing the cache of memory pages.
Page top
[Topic dma_attr]

KnIoDmaBegin()

This function is declared in the coresrv/io/dma.h file.

Retcode KnIoDmaBegin(Handle rid, Handle *handle);

Allows the device to access the DMA buffer with the handle rid.

Output parameter handle contains the handle of this permission.

If successful, the function returns rcOk.

For a usage example, see KnIoDmaCreate().

To prevent a device from accessing the DMA buffer, you need to call the KnIoClose() function while passing the specified handle of the permission in this function.

Page top
[Topic kn_io_dma_begin]

KnIoDmaCreate()

This function is declared in the coresrv/io/dma.h file.

Retcode KnIoDmaCreate(rtl_uint32_t order, rtl_size_t size, DmaAttr flags,

Handle *outRid);

This function registers and allocates a physical DMA buffer.

Input parameters:

  • order is the minimum permissible order of DMA block allocation; the actual order of each block in the DMA buffer is chosen by the kernel (but will not be less than the specified order) and is indicated in the block handle; the order of a block determines the number of pages in it. For example, a block with an order of N consists of 2^N pages.
  • size refers to the size of the DMA buffer, in bytes (must be a multiple of the page size); the sum of all sizes of allocated DMA blocks will be no less than the specified size.
  • flags refers to DMA flags.

Output parameter outRid contains the handle of the allocated DMA buffer.

If successful, the function returns rcOk.

If a DMA buffer is no longer being used, it must be freed by using the KnIoClose() function.

Example

Retcode RegisterDmaMem(rtl_size_t size,

DmaAttr attr,

Handle *handle,

Handle *dmaHandle,

Handle *mappingHandle,

void **addr)

{

Retcode ret;

*handle = INVALID_HANDLE;

*dmaHandle = INVALID_HANDLE;

*mappingHandle = INVALID_HANDLE;

ret = KnIoDmaCreate(rtl_roundup_order(size >> PAGE_SHIFT),

size,

attr,

handle);

if (ret == rcOk) {

ret = KnIoDmaBegin(*handle, dmaHandle);

}

if (ret == rcOk) {

ret = KnIoDmaMap(*handle,

0,

size,

RTL_NULL,

VMM_FLAG_READ | VMM_FLAG_WRITE,

addr,

mappingHandle);

}

if (ret != rcOk) {

if (*mappingHandle != INVALID_HANDLE)

KnHandleClose(*mappingHandle);

if (*dmaHandle != INVALID_HANDLE)

KnHandleClose(*dmaHandle);

if (*handle != INVALID_HANDLE)

KnHandleClose(*handle);

}

return ret;

}

Page top
[Topic kn_io_dma_create]

KnIoDmaGetInfo()

This function is declared in the coresrv/io/dma.h file.

Retcode KnIoDmaGetInfo(Handle rid, DmaInfo **outInfo);

This function gets information about the DMA buffer with the handle rid.

Output parameter outInfo contains information about the DMA buffer.

If successful, the function returns rcOk.

In contrast to KnIoDmaGetPhysInfo(), the outInfo parameter contains IOMMU addresses of DMA blocks instead of physical addresses.

Page top
[Topic kn_io_dma_get_info]

KnIoDmaGetPhysInfo()

This function is declared in the coresrv/io/dma.h file.

Retcode KnIoDmaGetPhysInfo(Handle rid, DmaInfo **outInfo);

This function gets information about the DMA buffer with the handle rid.

Output parameter outInfo contains information about the DMA buffer.

If successful, the function returns rcOk.

In contrast to KnIoDmaGetInfo(), the outInfo parameter contains physical addresses of DMA blocks instead of IOMMU addresses.

Page top
[Topic kn_io_dma_get_phys_info]

KnIoDmaMap()

This function is declared in the coresrv/io/dma.h file.

Retcode KnIoDmaMap(Handle rid, rtl_size_t offset, rtl_size_t length, void *hint,

int vmflags, void **addr, Handle *handle);

This function maps a DMA buffer area to the address space of a process.

Input parameters:

  • rid is the handle of the DMA buffer allocated using KnIoDmaCreate().
  • offset refers to the page-aligned offset of the start of the area from the start of the buffer, indicated in bytes.
  • length refers to the size of the area; it must be a multiple of the page size and must not exceed <buffer size - offset>.
  • hint is the virtual address of the start of mapping; if it is equal to 0, the address is selected by the kernel.
  • vmflags refers to allocation flags.

In the vmflags parameter, you can use the following allocation flags (vmm/flags.h):

  • VMM_FLAG_READ and VMM_FLAG_WRITE are memory protection attributes.
  • VMM_FLAG_LOW_GUARD and VMM_FLAG_HIGH_GUARD add a protective page before and after the allocated memory, respectively.

Permissible combinations of memory protection attributes:

  • VMM_FLAG_READ allows reading page contents.
  • VMM_FLAG_WRITE allows modification of page contents.
  • VMM_FLAG_READ | VMM_FLAG_WRITE allows reading and modifying page contents.

Output parameters:

  • addr is the pointer to the virtual address of the start of the mapped area.
  • handle refers to the handle of the created mapping.

If successful, the function returns rcOk.

For a usage example, see KnIoDmaCreate().

To delete a created mapping, you must call the KnIoClose() function and pass the specified mapping handle in this function.

Page top
[Topic kn_io_dma_map]