diff --git a/sys/arm/arm/cpufunc.c b/sys/arm/arm/cpufunc.c index 8e69c5405ed3..65a2bca18813 100644 --- a/sys/arm/arm/cpufunc.c +++ b/sys/arm/arm/cpufunc.c @@ -837,6 +837,11 @@ u_int cpu_reset_needs_v4_MMU_disable; /* flag used in locore.s */ defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \ defined(CPU_CORTEXA) || defined(CPU_KRAIT) +/* Global cache line sizes, use 32 as default */ +int arm_dcache_min_line_size = 32; +int arm_icache_min_line_size = 32; +int arm_idcache_min_line_size = 32; + static void get_cachetype_cp15(void); /* Additional cache information local to this file. Log2 of some of the @@ -868,6 +873,12 @@ get_cachetype_cp15() goto out; if (CPU_CT_FORMAT(ctype) == CPU_CT_ARMV7) { + /* Resolve minimal cache line sizes */ + arm_dcache_min_line_size = 1 << (CPU_CT_DMINLINE(ctype) + 2); + arm_icache_min_line_size = 1 << (CPU_CT_IMINLINE(ctype) + 2); + arm_idcache_min_line_size = + min(arm_icache_min_line_size, arm_dcache_min_line_size); + __asm __volatile("mrc p15, 1, %0, c0, c0, 1" : "=r" (clevel)); arm_cache_level = clevel; diff --git a/sys/arm/arm/cpufunc_asm_armv7.S b/sys/arm/arm/cpufunc_asm_armv7.S index 9fe6aa5c90d7..5dcc17147065 100644 --- a/sys/arm/arm/cpufunc_asm_armv7.S +++ b/sys/arm/arm/cpufunc_asm_armv7.S @@ -41,6 +41,12 @@ __FBSDID("$FreeBSD$"); .word _C_LABEL(arm_cache_loc) .Lcache_type: .word _C_LABEL(arm_cache_type) +.Larmv7_dcache_line_size: + .word _C_LABEL(arm_dcache_min_line_size) +.Larmv7_icache_line_size: + .word _C_LABEL(arm_icache_min_line_size) +.Larmv7_idcache_line_size: + .word _C_LABEL(arm_idcache_min_line_size) .Lway_mask: .word 0x3ff .Lmax_index: @@ -180,14 +186,9 @@ ENTRY(armv7_idcache_wbinv_all) RET END(armv7_idcache_wbinv_all) -/* XXX Temporary set it to 32 for MV cores, however this value should be - * get from Cache Type register - */ -.Larmv7_line_size: - .word 32 - ENTRY(armv7_dcache_wb_range) - ldr ip, .Larmv7_line_size + ldr ip, .Larmv7_dcache_line_size + ldr ip, [ip] sub r3, ip, #1 and r2, r0, r3 add r1, r1, r2 @@ -202,7 +203,8 @@ ENTRY(armv7_dcache_wb_range) END(armv7_dcache_wb_range) ENTRY(armv7_dcache_wbinv_range) - ldr ip, .Larmv7_line_size + ldr ip, .Larmv7_dcache_line_size + ldr ip, [ip] sub r3, ip, #1 and r2, r0, r3 add r1, r1, r2 @@ -221,7 +223,8 @@ END(armv7_dcache_wbinv_range) * must use wb-inv of the entire cache. */ ENTRY(armv7_dcache_inv_range) - ldr ip, .Larmv7_line_size + ldr ip, .Larmv7_dcache_line_size + ldr ip, [ip] sub r3, ip, #1 and r2, r0, r3 add r1, r1, r2 @@ -236,7 +239,8 @@ ENTRY(armv7_dcache_inv_range) END(armv7_dcache_inv_range) ENTRY(armv7_idcache_wbinv_range) - ldr ip, .Larmv7_line_size + ldr ip, .Larmv7_idcache_line_size + ldr ip, [ip] sub r3, ip, #1 and r2, r0, r3 add r1, r1, r2 @@ -264,7 +268,8 @@ ENTRY_NP(armv7_icache_sync_all) END(armv7_icache_sync_all) ENTRY_NP(armv7_icache_sync_range) - ldr ip, .Larmv7_line_size + ldr ip, .Larmv7_icache_line_size + ldr ip, [ip] .Larmv7_sync_next: mcr CP15_ICIMVAU(r0) mcr CP15_DCCMVAC(r0) diff --git a/sys/arm/arm/elf_trampoline.c b/sys/arm/arm/elf_trampoline.c index 559b99212be0..24b30118b206 100644 --- a/sys/arm/arm/elf_trampoline.c +++ b/sys/arm/arm/elf_trampoline.c @@ -115,6 +115,10 @@ int arm_pcache_unified; int arm_dcache_align; int arm_dcache_align_mask; +int arm_dcache_min_line_size = 32; +int arm_icache_min_line_size = 32; +int arm_idcache_min_line_size = 32; + u_int arm_cache_level; u_int arm_cache_type[14]; u_int arm_cache_loc; @@ -277,6 +281,13 @@ get_cachetype_cp15() goto out; if (CPU_CT_FORMAT(ctype) == CPU_CT_ARMV7) { + /* Resolve minimal cache line sizes */ + arm_dcache_min_line_size = 1 << (CPU_CT_DMINLINE(ctype) + 2); + arm_icache_min_line_size = 1 << (CPU_CT_IMINLINE(ctype) + 2); + arm_idcache_min_line_size = + (arm_dcache_min_line_size > arm_icache_min_line_size ? + arm_icache_min_line_size : arm_dcache_min_line_size); + __asm __volatile("mrc p15, 1, %0, c0, c0, 1" : "=r" (clevel)); arm_cache_level = clevel; diff --git a/sys/arm/include/armreg.h b/sys/arm/include/armreg.h index 4d0078cce853..3163ba5bf46d 100644 --- a/sys/arm/include/armreg.h +++ b/sys/arm/include/armreg.h @@ -320,6 +320,9 @@ #define CPU_CT_S (1U << 24) /* split cache */ #define CPU_CT_CTYPE(x) (((x) >> 25) & 0xf) /* cache type */ #define CPU_CT_FORMAT(x) ((x) >> 29) +/* Cache type register definitions for ARM v7 */ +#define CPU_CT_IMINLINE(x) ((x) & 0xf) /* I$ min line size */ +#define CPU_CT_DMINLINE(x) (((x) >> 16) & 0xf) /* D$ min line size */ #define CPU_CT_CTYPE_WT 0 /* write-through */ #define CPU_CT_CTYPE_WB1 1 /* write-back, clean w/ read */