= GIET-VM / CMA Driver = [[PageOutline]] The [source:soft/giet_vm/giet_drivers/cma_driver.c cma_driver.c] and [source:soft/giet_vm/giet_drivers/cma_driver.h cma_driver.h] files define the CMA driver. It supports the SOCLIB ''vci_chbuf_dma'' component, that is a multi channels, chained buffer DMA controller. This component can be used in conjonction with the SOCLIB ''vci_frame_buffer'' to display images, or with the SOCLIB ''vci_multi_nic'' controller to transfer RX or TX packets between NIC buffers and memory buffers. A single CMA channel transfers a stream of data from a set of chained buffers (source ''chbuf'') to another set of chained buffers (destination ''chbuf''). This controller implements two modes to scan the source and destination chbufs: * '''IN_ORDER''' : The chained buffers are handled as a software FIFO: The buffers are read and written in strict order, with a blocking polling policy to access both the expected source buffer and the expected destination buffer. The waiting delay between two accesses is defined, for each channel, by the CHBUF_PERIOD addressable register, and must be non zero to activate this mode. * '''OUT OF ORDER''' : The controller scan all the source buffers, and the first full buffer found is read. Similarly, the controller scan all the destination buffers, and the first empty buffer found is written, with a round robin priority for the search. This mode is activated when the CHBUF_PERIOD value is zero (default value). A ''chbuf'' descriptor is a variable size circular array of 64 bits entries. Each entry is a single buffer descriptor, and contains a 48 bits physical address (PADDR) and a valid bit V that is 0 when the buffer is empty. ||1|| 15 || 48 || ||V|| unused || ------- PADDR --------- || The SEG_CMA_BASE address must be defined in the hard_config.h file. The addressable registers map is defined [source:soft/giet_vm/giet_drivers/cma_driver.h here]. == Access Functions == === 1) unsigned int '''_cma_get_register'''( unsigned int channel, unsigned int index ) === This low_level function returns the value contained in register (index). === 2) void '''_cma_set_register'''( unsigned int channel, unsigned int index, unsigned int value ) === This low_level function returns the value contained in register (index). === 3) void '''_cma_channel_start'''( unsigned int channel, unsigned long long src_paddr, unsigned int src_nbufs, unsigned long long dst_paddr, unsigned int dst_nbufs, unsigned int buf_length )__ === This function activates a chained buffer DMA channel. * channel : CMA channel index. * src_paddr : physical address of the source chbuf. * src_nbufs : number of buffers in the source chbuf. * dst_paddr : physical address of the destination chbuf. * dst_nbufs : number of buffers in the destination chbuf. * buf_length : single buffer length (bytes) === 4) void '''_cma_channel_stop'''( unsigned int channel ) === This function desactivates a chained buffer DMA channel. * channel : CMA channel index. == Interrupt Service Routine == === 5) void '''_cma_isr'''( unsigned int irq_type, unsigned int irq_id, unsigned int channel ) === A CMA IRQ is activated in case of memory access error for a specific CMA channel: * SRC_DESC_ERROR : error accessing source chbuf descriptor * SRC_DATA_ERROR : error accessing source data buffer * DST_DESC_ERROR : error accessing destination chbuf descriptor * DST_DATA_ERROR : error accessing destination data buffer The Interrupt Service Routine displays a message on TTY0 and desactivates the CMA channel to acknowledge IRQ.