wiki:cma_driver

Version 13 (modified by alain, 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_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 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.