Version 14 (modified by 10 years ago) (diff) | ,
---|
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).
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 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.