- 开启 ACTLR.SMP
- TLB entry dcache 模式设置为 WRITE-BACK.
一次调试 rk3128 u-boot, 偶然发现 memcpy 很慢, 不到 24MB/s. 分析了 u-boot 代码, 没看出问题. 查看 cortex-a7 mpcore 手册, 发现协处理器 ACTLR.SMP 位没开启, SCTLR.C 位不起效:
cache 开关的代码:
void cache_on(bool on ){ u32 * tlb = (u32 *)gd->arch.tlb_addr; u32 i; #define set_entry_cache_type(entry,val) tlb[entry] = ((entry)<<20) + (3<<10) + (val) if(on) { u32 fb = (u32)gd->fb_base; u32 malloc_start = gd->relocaddr - TOTAL_MALLOC_LEN; u32 malloc_end = gd->relocaddr ; for (i = ((u32)CONFIG_RAM_PHY_START >> 20); i < (((u32)CONFIG_RAM_PHY_START + SZ_512M) >> 20); ++i) { set_entry_cache_type(i, DCACHE_WRITEBACK); } for (i = (fb >> 20); i < ((fb + SZ_4M) >> 20); i++) { set_entry_cache_type(i, DCACHE_OFF); } for (i = (malloc_start >> 20); i < (malloc_end >> 20); i++) { set_entry_cache_type(i, DCACHE_WRITETHROUGH); } asm volatile( "mrc p15, 0, r0, c1, c0, 1 @ACTLR Enabling SMP bit in ACTLR\n" "orr r0, r0, #(1 << 6) \n" "mcr p15, 0, r0, c1, c0, 1 \n" // flush tlb "mov r0,#0 \n" "mcr p15, 0, r0, c8, c7, 0\n" ); } else { unsigned int actlr; asm volatile("mrc p15, 0, %0, c1, c0, 1":"=r"(actlr)); if (actlr & (1<<6)) { set_cr(get_cr() & ~(CR_M | CR_D)); } }}注:
不能直接修改 cache-cp15.c 中的 mmu_setup(), 因为 rk 的 u-boot 开机初始化对 cache 支持不完善, 真正开启 cache 会导致死机, 笔者是在 board_late_init() 中开启.
rk 的 dma, sd 驱动对 cache 支持不完善, 所以上面的代码将 malloc 内存区域设置为 DCACHE_WRITETHROUGH; 也可以关闭 sd dma , 屏蔽 CONFIG_RK_MMC_DMA 配置, 但 mmc 读取速度会降低.
framebuffer 区域开启 cache 后, 屏幕画面会有一点不正常, 因此设置为 DCACHE_OFF
进 USB 烧写模式时, 需要关闭 cache, 即在 do_rockusb() 调用前关闭 cache, 否则烧写的数据有可能会出错
本文介绍RK3128平台U-Boot中缓存设置的优化过程,通过调整TLB条目的缓存模式为WRITE-BACK,显著提升了memcpy函数的性能,并详细解释了相关代码实现。
1409

被折叠的 条评论
为什么被折叠?



