Resolve cache line size from CP15

Switch the cache line size during invalidations/flushes
to be read from CP15 cache type register.

Submitted by:  Wojciech Macek <wma@semihalf.com>
Reviewed by:   ian, imp
Obtained from: Semihalf
This commit is contained in:
zbb 2015-02-10 14:11:23 +00:00
parent cfe0de95f1
commit d12ce3b931
4 changed files with 41 additions and 11 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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 */