1 linux arm linux-device-driver linux-kernel dma
在https://www.kernel.org/doc/Documentation/DMA-API.txt上的文字后面几个内联问题
Part Ia - Using large dma-coherent buffers
------------------------------------------
void *
dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
Consistent memory is memory for which a write by either the device or
the processor can immediately be read by the processor or device
without having to worry about caching effects. (You may however need
to make sure to flush the processor's write buffers before telling
devices to read that memory.)
Run Code Online (Sandbox Code Playgroud)
Q1.假设分配的区域是可缓存的是否安全?作为需要冲洗的最后一行状态
Q1A.此API是否从较低的16MB分配内存,这被认为是DMA安全的.
dma_addr_t
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
enum dma_data_direction direction)
Maps a piece of processor virtual memory so it can be accessed by the
device and returns the physical handle of the memory.
The direction for both api's may be converted freely by casting.
However the dma_ API uses a strongly typed enumerator for its
direction:
DMA_NONE no direction (used for debugging)
DMA_TO_DEVICE data is going from the memory to the device
DMA_FROM_DEVICE data is coming from the device to the memory
DMA_BIDIRECTIONAL direction isn't known
Run Code Online (Sandbox Code Playgroud)
Q2.DMA_XXX选项是否直接更改VA => PA映射的页面属性.假设DMA_TO_DEVICE会将该区域标记为不可缓存?
它说"不必担心缓存效应".这意味着dma_alloc_coherent()返回不可缓存的内存,除非该体系结构具有缓存一致的DMA硬件,因此缓存没有区别.但是,未缓存并不意味着写入不会通过CPU写缓冲区(即不是每个存储器访问都会立即执行或执行与它们在代码中出现的顺序相同).当你告诉设备读取它时,确保你写入内存的所有内容都存在,你必须wmb()至少执行一次.有关更多信息,请参阅Documentation/memory-barriers.txt.
dma_alloc_coherent()不从低16 MB返回内存,它返回设备可在指定的可寻址区域内访问的内存dma_set_coherent_mask().您必须将其作为设备初始化的一部分进行调用.
可缓存性与dma_map_*()功能无关.它们确保设备在返回的DMA地址可以访问给定的内存区域.DMA完成后dma_unmap_*()调用.对于DMA_TO_DEVICE,序列是"将数据写入内存,map(),启动DMA,unmap()完成后",对于DMA_FROM_DEVICE"map(),启动DMA,unmap()完成后,从内存中读取数据".
缓存没有区别,因为通常您在映射时不会写入或读取缓冲区.如果你真的必须这样做,你必须dma_sync_*()在读取之前或写入缓冲区之后明确地记忆.