wiki:dma_driver

Version 5 (modified by alain, 10 years ago) (diff)

--

GIET-VM / DMA Driver

The dma_driver.c and dma_driver.h files define the DMA driver.

This vci_multi_dma component is a multi-channels DMA controller, that can replicated in all clusters (internal peripheral).

There is (NB_CLUSTERS * NB_DMA_CHANNELS) channels, indexed by a global index:

dma_id = cluster_xy * NB_DMA_CHANNELS + local_index

A DMA channel is a private ressource allocated to a given processor. It is exclusively used by the kernet to speedup data transfers, and there is no lock protecting exclusive access to the channel. As the kernel uses a polling policy on the DMA_STATUS register to detect transfer completion, the DMA IRQ is not used.

The virtual base address of the segment associated to a channel is:

vbase = SEG_DMA_BASE + cluster_xy * PERI_CLUSTER_INCREMENT + DMA_SPAN * local_index

The SEG_DMA_BASE virtual address and PERI_CLUSTER_INCREMENT values must be defined in the hard_config.h file.

The addressable registers map, and the status possible values are defined here.

Low level access functions

unsigned int _dma_init( unsigned int cluster_xy, unsigned int channel_id )

This function disables interrupts for one DMA channel in one cluster.As the GIET-VM uses a polling policy to detect DMA transfer completion, the DMA component initialisation must disable interrupts. Returns 0 if success, returns > 0 if error.

unsigned int _dma_reset( unsigned int cluster_xy, unsigned int channel_id )

This function re-initialises one DMA channel in one cluster after transfer completion. It actually forces the channel to return in IDLE state.

unsigned int _dma_get_status( unsigned int cluster_xy, unsigned int channel_id );

This function returns the status of a DMA channel in a given cluster.

void _dma_start_transfer( unsigned int cluster_xy, unsigned int channel_id, unsigned long long dst_paddr, unsigned long long src_paddr, unsigned int size )

This function sets the physical address (including 64 bits extension) of the source and destination buffers for a DMA channel in a given cluster, and sets the transfer size to lauch the transfer.

High level access functions

void _dma_copy( unsigned int cluster_xy, unsigned int channel_id, unsigned int dst_vaddr, unsigned int src_vaddr, unsigned int size )

This function copies a source memory buffer to a destination memory buffer, using virtual addresses. This requires a virtual to physical address translation. This blocking function is supposed to be used by the kernel only, and uses a polling policy on DMA_STATUS register to detect completion. Therefore, the DMA_IRQ is NOT used. The source and destination buffers base addresses must be word aligned, and the buffer's size must be multiple of 4. In case of error (buffer unmapped, unaligned, or DMA_STATUS error), an error message is displayed on TTY0, and system crash.

void _dma_physical_copy( unsigned int cluster_xy, unsigned int channel_id, unsigned long long dst_paddr, unsigned long long src_paddr, unsigned int size )

This function copies a source memory buffer to a destination memory buffer, using physical addresses. This blocking function is supposed to be used by the kernel only, and uses a polling policy on DMA_STATUS register to detect completion. Therefore, the DMA_IRQ is NOT used. The source and destination buffers base addresses must be word aligned, and the buffer's size must be multiple of 4. In case of error (buffer unmapped, unaligned, or DMA_STATUS error), an error message is displayed on TTY0, and system crash.

void _dma_isr( unsigned int irq_type, unsigned int irq_id, unsigned int channel )

This Interrupt Service Routine should not be used by the GIET_VM, because the DMA is only used by the kernel in the boot phase, with a polling strategy.