KasperskyOS Community Edition 1.1
[Topic libkos_dma]

DmaInfo

Структура, описывающая DMA-буфер, объявлена в файле io/io_dma.h.

typedef struct {

/** DMA-флаги (атрибуты). */

DmaAttr flags;

/** Минимальный порядок DMA-блоков в буфере. */

rtl_size_t orderMin;

/** Размер DMA-буфера. */

rtl_size_t size;

/** Число DMA-блоков (меньше или равно DMA_FRAMES_COUNT_MAX).

* Может быть равно 0, если DMA-буфер недоступен для устройства. */

rtl_size_t count;

/** Массив описателей DMA-блоков. */

union DmaFrameDescriptor {

struct {

/** Порядок (order) DMA-блока. Число страниц в блоке равно двум

* в степени order. */

DmaAddr order: DMA_FRAME_ORDER_BITS;

/** Физический или IOMMU-адрес DMA-блока. */

DmaAddr frame: DMA_FRAME_BASE_BITS;

};

/** Описатель DMA-блока */

DmaAddr raw;

} descriptors[1];

} DmaInfo;

В начало
[Topic dma_info]

DMA-флаги

DMA-флаги (атрибуты) объявлены в файле io/io_dma.h.

  • DMA_DIR_TO_DEVICE – разрешены транзакции из основной памяти в память устройства;
  • DMA_DIR_FROM_DEVICE – разрешены транзакции из памяти устройства в основную память;
  • DMA_DIR_BIDIR – разрешены транзакции из основной памяти в память устройства и наоборот;
  • DMA_ZONE_DMA32 – под буфер разрешено использовать только первые 4 Гб памяти;
  • DMA_ATTR_WRITE_BACK, DMA_ATTR_WRITE_THROUGH, DMA_ATTR_CACHE_DISABLE, DMA_ATTR_WRITE_COMBINE – управление кэшированием страниц памяти.
В начало
[Topic dma_attr]

KnIoDmaBegin()

Функция объявлена в файле coresrv/io/dma.h.

Retcode KnIoDmaBegin(Handle rid, Handle *handle);

Функция разрешает устройству доступ к DMA-буферу с дескриптором rid.

Выходной параметр handle содержит дескриптор данного разрешения.

В случае успеха функция возвращает rcOk.

Пример использования – см. KnIoDmaCreate().

Чтобы запретить устройству доступ к DMA-буферу, необходимо вызвать функцию KnIoClose(), передав в нее дескриптор разрешения handle.

В начало
[Topic kn_io_dma_begin]

KnIoDmaCreate()

Функция объявлена в файле coresrv/io/dma.h.

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

Handle *outRid);

Функция регистрирует и выделяет физический DMA-буфер.

Входные параметры:

  • order – минимальный допустимый порядок выделения DMA-блоков; фактический порядок каждого блока в DMA-буфере выбирается ядром (но не будет меньше order) и помещается в дескриптор блока; порядок блока определяет число страниц в нем: блок с порядком N состоит из 2^N страниц;
  • size – размер DMA-буфера в байтах (должен быть кратен размеру страницы); сумма размеров выделенных DMA-блоков будет не меньше size;
  • flagsDMA-флаги.

Выходной параметр outRid содержит дескриптор выделенного DMA-буфера.

В случае успеха функция возвращает rcOk.

Если DMA-буфер больше не используется, его необходимо освободить с помощью функции KnIoClose().

Пример

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;

}

В начало
[Topic kn_io_dma_create]

KnIoDmaGetInfo()

Функция объявлена в файле coresrv/io/dma.h.

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

Функция получает информацию о DMA-буфере с дескриптором rid.

Выходной параметр outInfo содержит информацию о DMA-буфере.

В случае успеха функция возвращает rcOk.

В отличие от KnIoDmaGetPhysInfo(), параметр outInfo содержит не физические, а IOMMU-адреса DMA-блоков.

В начало
[Topic kn_io_dma_get_info]

KnIoDmaGetPhysInfo()

Функция объявлена в файле coresrv/io/dma.h.

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

Функция получает информацию о DMA-буфере с дескриптором rid.

Выходной параметр outInfo содержит информацию о DMA-буфере.

В случае успеха функция возвращает rcOk.

В отличие от KnIoDmaGetInfo(), параметр outInfo содержит не IOMMU-адреса, а физические адреса DMA-блоков.

В начало
[Topic kn_io_dma_get_phys_info]

KnIoDmaMap()

Функция объявлена в файле coresrv/io/dma.h.

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

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

Функция отображает участок DMA-буфера на адресное пространство процесса.

Входные параметры:

  • rid – дескриптор выделенного с помощью KnIoDmaCreate() DMA-буфера;
  • offset – странично-выровненное смещение начала участка от начала буфера в байтах;
  • length – размер участка; должен быть кратен размеру страницы и не превышать <размер буфера - offset>;
  • hint – виртуальный адрес начала отображения; если он равен 0, адрес выберет ядро;
  • vmflags – флаги аллокации.

В параметре vmflags можно использовать следующие флаги аллокации (vmm/flags.h):

  • VMM_FLAG_READ и VMM_FLAG_WRITE – атрибуты защиты памяти;
  • VMM_FLAG_LOW_GUARD и VMM_FLAG_HIGH_GUARD – добавление защитной страницы перед и после выделенной памяти соответственно.

Допустимые комбинации атрибутов защиты памяти:

  • VMM_FLAG_READ – разрешено чтение содержимого страницы;
  • VMM_FLAG_WRITE – разрешено изменение содержимого страницы;
  • VMM_FLAG_READ | VMM_FLAG_WRITE – разрешено чтение и изменение содержимого страницы.

Выходные параметры:

  • addr – указатель на виртуальный адрес начала отображенного участка;
  • handle – дескриптор созданного отображения.

В случае успеха функция возвращает rcOk.

Пример использования – см. KnIoDmaCreate().

Чтобы удалить созданное отображение, необходимо вызвать функцию KnIoClose(), передав в нее дескриптор отображения handle.

В начало
[Topic kn_io_dma_map]