Bri*_*son 8 arm linux-kernel xilinx zynq
我正在使用Xilinx Zynq平台,在可编程HW和ARM处理器之间共享一个内存区域.
我在内核命令行上使用memmap保留了这个内存,然后通过我的驱动程序中的mmap/io_remap_pfn_range调用将它暴露给用户空间.
我遇到的问题是,写入显示在DRAM中需要一些时间,我认为它存在于dcache中.有一堆flush_cache_*调用被定义,但没有一个被导出,这是我的一个线索,我正在咆哮错误的树...
作为试验,我在本地导出了flush_cache_mm,只是为了看看会发生什么,没有快乐.
简而言之,我怎样才能确定对这个mmap'd区域的任何写入都已提交给DRAM?
谢谢.
在ARM处理器通常同时具有I/d高速缓存和写缓存.写缓冲区的想法是将顺序写入组合在一起(非常适用于同步DRAM),并且不会延迟CPU等待写入完成.
要通用,您可以刷新d缓存和写缓冲区.以下是一些内联ARM汇编程序,它应该适用于许多体系结构和内存配置.
static inline void dcache_clean(void)
{
const int zero = 0;
/* clean entire D cache -> push to external memory. */
__asm volatile ("1: mrc p15, 0, r15, c7, c10, 3\n"
" bne 1b\n" ::: "cc");
/* drain the write buffer */
__asm volatile ("mcr 15, 0, %0, c7, c10, 4"::"r" (zero));
}
Run Code Online (Sandbox Code Playgroud)
如果您有L2缓存,则可能需要更多.
要在Linux上下文中回答,根据内存/ MMU配置甚至CPU勘误,有不同的CPU变体和不同的例程.例如,见
这些例程可以直接调用,也可以在cpu信息结构中查找,其中包含指向检测到的CPU和配置的相应例程的函数指针; 取决于内核是否是单个CPU专用或多功能像Ubuntu发行版.
要专门针对您的情况回答问题,我们需要了解L2缓存,写入缓冲内存,CPU架构细节; 可能包括勘误表的硅修订版.另一种策略是通过使用将内存标记为不可缓存且不可缓冲的dma_alloc_XXX()
例程来完全避免这种情况,以便立即从外部推送CPU写入.根据您的内存访问模式,任一解决方案都有效.如果只需要在某个检查点同步内存(vsync/*hsync*用于视频等),您可能希望缓存.