Цепочечный DMA трансфер большого объема

Тема в разделе "WASM.WIN32", создана пользователем Drakon Rider, 18 авг 2005.

  1. Drakon Rider

    Drakon Rider New Member

    Публикаций:
    0
    Регистрация:
    15 окт 2002
    Сообщения:
    21
    Адрес:
    Russia
    есть железяка, которая умеет делать цепочечные ДМА трансферы т.е. ей дается адрес первой структуры с параметрами трансфера (адреса источника и приемника и размер передачи), в конце которой может быть указатель на следующую структуру и т.д. ...



    задача: передавать в эту железяку чересстрочную информацию, размер одной строки 702*4 байт, количество строк на передачу - 288, но расположены "через одну"... имхо это уже плохо т.к. не кратно размеру страницы в 4 кб и больше ее половины ... скорость передачи - 50 таких блоков в секунду...



    вопрос: в ДДК указано, что объем одного трансфера ограничен произведением PAGE_SIZE, которая в хедерах строго 4096 байт и количества маппирующих регистров ДМА контроллера (которое отдается в IoGetDmaAdapter( IN OUT PULONG NumberOfMapRegisters) ), если железяка умеет цепочечные трансферы, то работает ли это ограничение ?



    пока что удалось выяснить - ограничение похоже где-то в нутрях Вынь:



    даже если успешно работает создание девайса :
    Код (Text):
    1.  
    2. RtlZeroMemory(&deviceDescription, sizeof(deviceDescription));
    3. deviceDescription.Version= DEVICE_DESCRIPTION_VERSION;
    4. deviceDescription.Master= TRUE;
    5. deviceDescription.ScatterGather= FALSE;
    6. deviceDescription.BusNumber= pDeviceExt->DDPool[0].ulBus;
    7. deviceDescription.InterfaceType= PCIBus;
    8. deviceDescription.Dma32BitAddresses= TRUE;
    9. deviceDescription.MaximumLength= (1024 * 1024 - 1) * sizeof(ULONG);
    10.  
    11. pDeviceExt->DmaOp.ulMaxMapRegisters = 256;
    12. pDeviceExt->DmaOp.pDmaAdapter = (PDMA_ADAPTER)HalGetAdapter(&deviceDescription,
    13. &pDeviceExt->DmaOp.ulMaxMapRegisters);
    14.  


    с заявленными 256 мапными регистрами (в исходном варианте драйвера было 8) и соотв 4 Мб максимальным трансфером (deviceDescription.MaximumLength), то потом когда перед трансфером получается физ адрес источника :
    Код (Text):
    1.  
    2. physAddr = pDevExt->DmaOp.pDmaAdapter->DmaOperations->MapTransfer(pDevExt->DmaOp.pDmaAdapter,
    3. pDevExt->DmaOp.pirpDmaTransfer->MdlAddress,
    4. pDevExt->DmaOp.pMapRegisterBase,
    5. pDevExt->DmaOp.CurrentVa,
    6. &pDevExt->DmaOp.Length,
    7. TRUE);
    8.  


    маздайка скидывает &pDevExt->DmaOp.Length до PAGE_SIZE*8 т.е. до 8 мапных регистров :dntknw: ...



    если я после этого вручную опять скручиваю &pDevExt->DmaOp.Length до например PAGE_SIZE*16, то в трансференных данных половина нормальная, а вторая половина - "мусор" т.е. что-то похоже с мапными регистрами таки связано и когда ДМА контроллер начинает читать дальше PAGE_SIZE*8 ему откуда-то подсовывают какую-то фигню...



    где-бы почитать как работает ДМА в х86 ? пока что после некоторого медитирования с ДДК показалось, что ДМА контроллер девайса после того, как ему дали параметры трансфера (физический адрес начала трансфера в основной памяти) начинает спрашивать данные у наплатного ДМА х86 контроллера, а у того "страничная" организация по 4 кб и ему на каждую страницу надо держать "маппирующие регистры" которых немного (т.е. 8) и соотв когда у маздайки заказывают параметры трансфера она проверяет какой на самом деле стоит контроллер основной платы и ограничивает размер трансфера 8 страницами...



    пока что не понятно - почему если заказывается физический адрес, то всеравно используется "страничность" ?



    при создании ДМА контроллера есть флаг scatter/gather support - это и есть указание, что девайс умеет цепочечные трансферы делать ? а как тогда решается вопрос сколько на каждый трансфер в цепочке "маппирующих регистров" уйдет и когда они будут обновляться если количество трансферов в цепочке не ограничено и размер каждого трансфера вообщем тоже...
     
  2. TarasCo

    TarasCo New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2005
    Сообщения:
    106
    Вы разберитесь, нужен ли Вам DMA контроллер. Например, PCI bus masters не используют его, и при обнаружении устройства windows не рапортует о DMA каналах (можно порытся в менеджере устройств, посмотреть ресурсы, используемые различным оборудованием). Настройка DMA происходит через регистры платы. Например, PCI плата А поддерживает scatter/gather передачу на 16 буферов. У этой платы будет скоре всего 16 регистров, куда нужно записать физические адреса кусков буферов. Дальше в управляющий регистр какой нибудь битик "поехали". По окнчанию цикла - прерывание. Из устройств, использующих DMA контроллер, могу вспомнить только FDD и LPT порт. К тому же стандартный DMA контроллер - 16 битный.
     
  3. Kola

    Kola New Member

    Публикаций:
    0
    Регистрация:
    23 июн 2004
    Сообщения:
    69
    а на какой шине плата?

    scatter/gather support - это возможность железки передавать данные на фрагментированную (как правило кусочки, размером PAGE_SIZE) физ. память.
     
  4. Drakon Rider

    Drakon Rider New Member

    Публикаций:
    0
    Регистрация:
    15 окт 2002
    Сообщения:
    21
    Адрес:
    Russia
    >Вы разберитесь, нужен ли Вам DMA контроллер.



    я про тот ДМА, который на доп плате стоит - он работает мостом между PCI и нутряной памятью платы...



    >Например, PCI плата А поддерживает scatter/gather передачу на 16 буферов. У этой платы будет скоре всего 16 регистров, куда нужно записать физические адреса кусков буферов. Дальше в управляющий регистр какой нибудь битик "поехали". По окнчанию цикла - прерывание.



    тут побольше возможностей - в регистры контроллера можно прописать только параметры первого трансфера, и адрес следующего дескриптора, который хранится в ОЗУ, а ОЗУ может быть много Мб :) ... но тут никакие мапные регистры не используются...



    >а на какой шине плата?



    честно как и указано :

    deviceDescription.InterfaceType= PCIBus;

    deviceDescription.Dma32BitAddresses= TRUE;



    вообщем погуглив немного нашел объяснение глюков и продолжение пути : в маздайке непрерывный исходный буфер в виртуальных 4 Гб памяти на самом деле состоит из мелких кусов по PAGE_SIZE*8 (не более ?), которые раскиданы по всей физ ОЗУ... и соотв у ДМА контроллера один непрерывный трансфер и ограничен этим значением... но по слухам эту траблу можно пофиксить выделив непрерывный и неперемещаемый кусок физ памяти из драйвера - этим и займусь пока...
     
  5. Kola

    Kola New Member

    Публикаций:
    0
    Регистрация:
    23 июн 2004
    Сообщения:
    69


    говорит о том что Ваше устройство использует BusMaster DMA, а встроенный в системной плате ДМА конроллер вообще курит, тк не может использоваться PCI устройством (...хотя вообще-то может, но только через одно место)





    Скорее так, непрерывный исходный буфер виртальной памяти может состять из фрагментов(а), размером, кратным PAGE_SIZE.

    Кстати, возможность железки передавать данные в такую фрагментированную память и зовется Scatter/Gather.



    Советую почитать вот эту статью:

    http://www.microsoft.com/whdc/driver/kernel/dma.mspx