GIET-VM / CMA Driver
The cma_driver.c and 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).
The state of each buffer must be defined in a variable called status. Each “status” occupies 64 bytes, but only the last bit is useful (1 if the buffer is full, 0 if it is empty). A buffer and its status physical addresses must be 64 bytes aligned and must have the same extension (identical bits[43:32]).
A chbuf descriptor is a variable size circular array of 64 bits entries. Each entry is a single buffer descriptor and contains the physical addresses (PADDR) of the buffer and the status variable :
- The 12 MSB bits contain the common extension of the buffer address and the buffer status address
- The 26 following bits contain the bits [31:6] of the buffer address
- The 26 LSB bits contain the bits [31:6] of the buffer status address
12 | 26 | 26 |
buffer_paddr[43:32] = status_paddr[43:32] | buffer_paddr[31:6] | status_paddr[31:6] |
The SEG_CMA_BASE address must be defined in the hard_config.h file.
The addressable registers map is defined 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).
Interrupt Service Routine
3) 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. There is 4 types of errors:
- SRC_DESC_ERROR : error accessing source chbuf descriptor
- SRC_STATUS_ERROR : error accessing source buffer status
- DST_DESC_ERROR : error accessing destination chbuf descriptor
- DST_STATUS_ERROR : error accessing destination buffer status
- DATA_ERROR : error accessing source or destination data buffer
The Interrupt Service Routine displays a message on TTY0 and desactivates the CMA channel to acknowledge IRQ.