CX2388x Architecture

The CX2388x is a multifunction PCI interface, and provides the following functions as separate devices on the PCI bus:

These functions enumerate as separate devices on the PCI bus, but share 32K of onboard SRAM, which is used for DMA control structures and driver-configurable DMA FIFOs. Each function uses at least one DMA channel, sometimes more (e.g. the Video function has separate channels for Y, U, and V video planes, and for VBI (CC/teletext) data). Much like the old Brooktree 878 chip, the CX2388x uses propriety RISC assembly instruction format for DMA programming. Drivers are responsible for generating DMA programs as sequences of RISC instructions that control (among other things) the locations in physical memory to/from which data is transferred. While this DMA programming mechanism is very complex, it is also very powerful and well-suited for efficient A/V streaming. DMA buffers can be of arbitrary complexity, meaning that they are not required to be physically contiguous in memory.

The biggest limitation of the CX2388x, as far as modern systems are concerned, is that its DMA program format only allows for 32-bit physical memory addresses. This means that on 64-bit systems with large amounts of memory, the operating system will need to translate out-of-range physical addresses into 32-bit physical addresses that the CX2388x DMA engine can understand. The cx88 driver uses the BSD bus_dma framework, which handles this behind the scenes. This translation can impose a performance penalty, especially on amd64 systems where low-memory copy buffers ("bounce buffers") are used as intermediaries between high-memory buffers and 32-bit hardware devices. Some 64-bit architectures (sparc64, sun4v) have I/O MMUs, which are address translation hardware which FreeBSD uses to eliminate the need for bounce buffers. The newest amd64 chipsets also have I/O MMUs, but FreeBSD does not (yet) use them.

Driver Architecture

Common Layer

This is the foundation of the cx88 driver, and consists of the cx88.ko kernel module, which is built from the sources under the common/ subdirectory. The common layer mainly contains the core logic that client drivers need to use for basic device control (attachment/detachment) and DMA. Drivers for specific CX2388x functions (video, audio, MPEG TS, etc.) will claim cx88.ko as a dependency, and will use it for the following:

The common layer uses FreeBSD's kobj mechanism to allow drivers for sibling CX2388x functions to communicate with each other to optimize allocation of the onboard SRAM. This maximizes the FIFO space that can be used for DMA, which improves resistance to bus contention. Additionally, if there is enough SRAM space, DMA programs may be stored entirely in the SRAM, which eliminates the need to fetch DMA program instructions from host memory. The common layer exports functions that allow client drivers to easily generate powerful DMA programs, and allows for DMA data buffers to either be allocated in the kernel and mmap'ed to user applications, or allocated by user applications and passed to the kernel via ioctl(2) calls.

I2C Layer

Client Drivers

User Applications