2012-02-21 20 views
6

ci sto lavorando conducente FPGA per il kernel Linux. Il codice sembra funzionare bene su x86, ma su x86_64 ho alcuni problemi. Ho implementato lo streaming DMA. Così va comestreaming DMA in PCIE driver del kernel linux

get_user_pages(...); 
for (...) { 
    sg_set_page(); 
} 
pci_map_sg(); 

Ma pci_map_sg restituito indirizzi come 0xbd285800, che non sono allineati con PAGE_SIZE, quindi non può inviare prima pagina, perché le specifiche PCIE dice

"Le richieste non devono specificare una combinazione Indirizzo/Lunghezza che consente a un accesso allo spazio di memoria per superare un limite di 4 KB. "

C'è un modo per ottenere indirizzi allineati o mi sono perso qualcosa di importante?

Source code of DMA.

+0

Puoi includere il codice dalla fonte reale? Non ce n'è abbastanza per individuare il bug. –

+0

Sì, certo. Allegato al post originale. – soh

+0

@soh: Qualche piano per rilasciarlo al pubblico? Stavo cercando un driver aperto e non sono riuscito a trovarne uno buono. Essendo troppo pigro per scrivere il mio, sarei più che felice di contribuire e aiutare con i test. –

risposta

3

La prima possibilità che viene in mente è che il buffer utente in arrivo non si avvia in un limite di pagina. Se l'indirizzo di avvio è 0x800 byte attraverso una pagina, l'offset della prima chiamata sg_set_page sarà 0x800. Questo produrrà un indirizzo DMA che termina con 0x800. Questa è una cosa normale e non un bug.

Come pci_map_sg fonde pagine, questo primo segmento può essere più grande di una pagina. La cosa importante è che pci_map_sg produce blocchi contigui di memoria indirizzabile DMA, ma non produce un elenco di transazioni PCIe di basso livello. Su x64 hai maggiori probabilità di ottenere una regione di grandi dimensioni, perché la maggior parte delle piattaforme x64 ha un IOMMU.

Molti dispositivi mi occupo hanno motori DMA che mi permettono di specificare una lunghezza di trasferimento logica di diversi megabyte. Normalmente l'implementazione DMA nell'endpoint PCIe è responsabile dell'avvio di una nuova transazione PCIe a ciascun limite di 4 KB e il programmatore può ignorare tale vincolo. Se le risorse nell'FPGA sono troppo limitate per gestirle, puoi considerare di scrivere il codice del driver per convertire l'elenco dei blocchi di memoria Linux in un elenco (molto più lungo) di transazioni PCIe.

+0

Grazie mille. Il buffer utente era ok, ma il core PCIE FPGA non gestisce i buffer lunghi. – soh