= 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_FIFO''' : The chained buffers are read and write in strict order, with a blocking polling policy to access both the expected source chbuf and the expected destination chbuf. 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 the source buffers, and the first full buffer found is read. Similarly, the controller scan 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.