Fetch cache info from the Cache Type register on ARM7TDMI and "greater"
processors. Report this when the processor is attached.
This commit is contained in:
parent
9058fce64e
commit
959181a8b2
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cpufunc.c,v 1.18 2001/11/26 22:26:44 thorpej Exp $ */
|
||||
/* $NetBSD: cpufunc.c,v 1.19 2001/11/29 02:24:58 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* arm7tdmi support code Copyright (c) 2001 John Fremlin
|
||||
@ -58,6 +58,21 @@
|
||||
|
||||
#include <arm/cpufunc.h>
|
||||
|
||||
/* PRIMARY CACHE VARIABLES */
|
||||
int arm_picache_size;
|
||||
int arm_picache_line_size;
|
||||
int arm_picache_ways;
|
||||
|
||||
int arm_pdcache_size; /* and unified */
|
||||
int arm_pdcache_line_size;
|
||||
int arm_pdcache_ways;
|
||||
|
||||
int arm_pcache_type;
|
||||
int arm_pcache_unified;
|
||||
|
||||
int arm_dcache_align;
|
||||
int arm_dcache_align_mask;
|
||||
|
||||
#ifdef CPU_ARM3
|
||||
struct cpu_functions arm3_cpufuncs = {
|
||||
/* CPU functions */
|
||||
@ -703,6 +718,70 @@ struct cpu_functions cpufuncs;
|
||||
u_int cputype;
|
||||
u_int cpu_reset_needs_v4_MMU_disable; /* flag used in locore.s */
|
||||
|
||||
static void
|
||||
get_cachetype()
|
||||
{
|
||||
u_int ctype, isize, dsize;
|
||||
u_int multiplier;
|
||||
|
||||
__asm __volatile("mrc p15, 0, %0, c0, c0, 1"
|
||||
: "=r" (ctype));
|
||||
|
||||
/*
|
||||
* ...and thus spake the ARM ARM:
|
||||
*
|
||||
* If an <opcode2> value corresponding to an unimplemented or
|
||||
* reserved ID register is encountered, the System Control
|
||||
* processor returns the value of the main ID register.
|
||||
*/
|
||||
if (ctype == cpufunc_id())
|
||||
goto out;
|
||||
|
||||
if ((ctype & CPU_CT_S) == 0)
|
||||
arm_pcache_unified = 1;
|
||||
|
||||
/*
|
||||
* If you want to know how this code works, go read the ARM ARM.
|
||||
*/
|
||||
|
||||
arm_pcache_type = CPU_CT_CTYPE(ctype);
|
||||
|
||||
if (arm_pcache_unified == 0) {
|
||||
isize = CPU_CT_ISIZE(ctype);
|
||||
multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2;
|
||||
arm_picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3);
|
||||
if (CPU_CT_xSIZE_ASSOC(isize) == 0) {
|
||||
if (isize & CPU_CT_xSIZE_M)
|
||||
arm_picache_line_size = 0; /* not present */
|
||||
else
|
||||
arm_picache_ways = 1;
|
||||
} else {
|
||||
arm_picache_ways = multiplier <<
|
||||
(CPU_CT_xSIZE_ASSOC(isize) - 1);
|
||||
}
|
||||
arm_picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8);
|
||||
}
|
||||
|
||||
dsize = CPU_CT_DSIZE(ctype);
|
||||
multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2;
|
||||
arm_pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3);
|
||||
if (CPU_CT_xSIZE_ASSOC(dsize) == 0) {
|
||||
if (dsize & CPU_CT_xSIZE_M)
|
||||
arm_pdcache_line_size = 0; /* not present */
|
||||
else
|
||||
arm_pdcache_ways = 0;
|
||||
} else {
|
||||
arm_pdcache_ways = multiplier <<
|
||||
(CPU_CT_xSIZE_ASSOC(dsize) - 1);
|
||||
}
|
||||
arm_pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8);
|
||||
|
||||
arm_dcache_align = arm_pdcache_line_size;
|
||||
|
||||
out:
|
||||
arm_dcache_align_mask = arm_dcache_align - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cannot panic here as we may not have a console yet ...
|
||||
*/
|
||||
@ -719,6 +798,8 @@ set_cpufuncs()
|
||||
(cputype & 0x00000f00) == 0x00000300) {
|
||||
cpufuncs = arm3_cpufuncs;
|
||||
cpu_reset_needs_v4_MMU_disable = 0;
|
||||
/* XXX Cache info? */
|
||||
arm_dcache_align_mask = -1;
|
||||
return 0;
|
||||
}
|
||||
#endif /* CPU_ARM3 */
|
||||
@ -727,6 +808,8 @@ set_cpufuncs()
|
||||
(cputype & 0x00000f00) == 0x00000600) {
|
||||
cpufuncs = arm6_cpufuncs;
|
||||
cpu_reset_needs_v4_MMU_disable = 0;
|
||||
/* XXX Cache info? */
|
||||
arm_dcache_align_mask = -1;
|
||||
return 0;
|
||||
}
|
||||
#endif /* CPU_ARM6 */
|
||||
@ -736,6 +819,8 @@ set_cpufuncs()
|
||||
(cputype & CPU_ID_7ARCH_MASK) == CPU_ID_7ARCH_V3) {
|
||||
cpufuncs = arm7_cpufuncs;
|
||||
cpu_reset_needs_v4_MMU_disable = 0;
|
||||
/* XXX Cache info? */
|
||||
arm_dcache_align_mask = -1;
|
||||
return 0;
|
||||
}
|
||||
#endif /* CPU_ARM7 */
|
||||
@ -745,6 +830,7 @@ set_cpufuncs()
|
||||
(cputype & CPU_ID_7ARCH_MASK) == CPU_ID_7ARCH_V4T) {
|
||||
cpufuncs = arm7tdmi_cpufuncs;
|
||||
cpu_reset_needs_v4_MMU_disable = 0;
|
||||
get_cachetype();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -753,6 +839,7 @@ set_cpufuncs()
|
||||
(cputype & 0x0000f000) == 0x00008000) {
|
||||
cpufuncs = arm8_cpufuncs;
|
||||
cpu_reset_needs_v4_MMU_disable = 0; /* XXX correct? */
|
||||
get_cachetype();
|
||||
return 0;
|
||||
}
|
||||
#endif /* CPU_ARM8 */
|
||||
@ -761,6 +848,7 @@ set_cpufuncs()
|
||||
pte_cache_mode = PT_C; /* Select write-through cacheing. */
|
||||
cpufuncs = arm9_cpufuncs;
|
||||
cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */
|
||||
get_cachetype();
|
||||
return 0;
|
||||
}
|
||||
#endif /* CPU_ARM9 */
|
||||
@ -769,6 +857,7 @@ set_cpufuncs()
|
||||
cputype == CPU_ID_SA1110) {
|
||||
cpufuncs = sa110_cpufuncs;
|
||||
cpu_reset_needs_v4_MMU_disable = 1; /* SA needs it */
|
||||
get_cachetype();
|
||||
return 0;
|
||||
}
|
||||
#endif /* CPU_SA110 */
|
||||
@ -777,6 +866,7 @@ set_cpufuncs()
|
||||
pte_cache_mode = PT_C; /* Select write-through cacheing. */
|
||||
cpufuncs = xscale_writethrough_cpufuncs;
|
||||
cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */
|
||||
get_cachetype();
|
||||
return 0;
|
||||
}
|
||||
#endif /* CPU_XSCALE */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cpu.c,v 1.11 2001/11/24 01:26:24 thorpej Exp $ */
|
||||
/* $NetBSD: cpu.c,v 1.12 2001/11/29 02:24:58 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Mark Brinicombe.
|
||||
@ -311,6 +311,25 @@ const struct cpu_classtab cpu_classes[] = {
|
||||
* The remaining fields in the cpu structure are filled in appropriately.
|
||||
*/
|
||||
|
||||
static const char *wtnames[] = {
|
||||
"write-through",
|
||||
"write-back",
|
||||
"write-back",
|
||||
"**unknown 3**",
|
||||
"**unknown 4**",
|
||||
"write-back-locking", /* XXX XScale-specific? */
|
||||
"write-back-locking-A",
|
||||
"write-back-locking-B",
|
||||
"**unknown 8**",
|
||||
"**unknown 9**",
|
||||
"**unknown 10**",
|
||||
"**unknown 11**",
|
||||
"**unknown 12**",
|
||||
"**unknown 13**",
|
||||
"**unknown 14**",
|
||||
"**unknown 15**",
|
||||
};
|
||||
|
||||
void
|
||||
identify_arm_cpu(dv, cpu_number)
|
||||
struct device *dv;
|
||||
@ -377,9 +396,29 @@ identify_arm_cpu(dv, cpu_number)
|
||||
strcat(cpu->cpu_model, " branch prediction enabled");
|
||||
|
||||
/* Print the info */
|
||||
|
||||
printf(": %s\n", cpu->cpu_model);
|
||||
|
||||
/* Print cache info. */
|
||||
if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0)
|
||||
goto skip_pcache;
|
||||
|
||||
if (arm_pcache_unified) {
|
||||
printf("%s: %dKB/%dB %d-way %s unified cache\n",
|
||||
dv->dv_xname, arm_pdcache_size / 1024,
|
||||
arm_pdcache_line_size, arm_pdcache_ways,
|
||||
wtnames[arm_pcache_type]);
|
||||
} else {
|
||||
printf("%s: %dKB/%dB %d-way Instruction cache\n",
|
||||
dv->dv_xname, arm_picache_size / 1024,
|
||||
arm_picache_line_size, arm_picache_ways);
|
||||
printf("%s: %dKB/%dB %d-way %s Data cache\n",
|
||||
dv->dv_xname, arm_pdcache_size / 1024,
|
||||
arm_pdcache_line_size, arm_pdcache_ways,
|
||||
wtnames[arm_pcache_type]);
|
||||
}
|
||||
|
||||
skip_pcache:
|
||||
|
||||
switch (cpu->cpu_class) {
|
||||
#ifdef CPU_ARM2
|
||||
case CPU_CLASS_ARM2:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: armreg.h,v 1.8 2001/07/18 16:31:17 rjs Exp $ */
|
||||
/* $NetBSD: armreg.h,v 1.9 2001/11/29 02:24:59 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2001 Ben Harris
|
||||
@ -224,17 +224,21 @@
|
||||
#define CPU_CONTROL_IDC_ENABLE CPU_CONTROL_DC_ENABLE
|
||||
|
||||
/* Cache type register definitions */
|
||||
#define CPU_CT_IINFO_MASK 0x00000fff
|
||||
#define CPU_CT_IINFO_SHIFT 0
|
||||
#define CPU_CT_DINFO_MASK 0x00fff000
|
||||
#define CPU_CT_DINFO_SHIFT 12
|
||||
#define CPU_CT_HARVARD 0x01000000
|
||||
#define CPU_CT_TYPE_MASK 0x1e000000
|
||||
/* "Info" subfields -- see ARM ARM for meanings. */
|
||||
#define CPU_CT_LINE_MASK 0x00000003
|
||||
#define CPU_CT_M_BIT 0x00000004
|
||||
#define CPU_CT_ASSOC_MASK 0x00000038
|
||||
#define CPU_CT_SIZE_MASK 0x000001c0
|
||||
#define CPU_CT_ISIZE(x) ((x) & 0xfff) /* I$ info */
|
||||
#define CPU_CT_DSIZE(x) (((x) >> 12) & 0xfff) /* D$ info */
|
||||
#define CPU_CT_S (1U << 24) /* split cache */
|
||||
#define CPU_CT_CTYPE(x) (((x) >> 25) & 0xf) /* cache type */
|
||||
|
||||
#define CPU_CT_CTYPE_WT 0 /* write-through */
|
||||
#define CPU_CT_CTYPE_WB1 1 /* write-back, clean w/ read */
|
||||
#define CPU_CT_CTYPE_WB2 2 /* w/b, clean w/ cp15,7 */
|
||||
#define CPU_CT_CTYPE_WB6 6 /* w/b, cp15,7, lockdown fmt A */
|
||||
#define CPU_CT_CTYPE_WB7 7 /* w/b, cp15,7, lockdown fmt B */
|
||||
|
||||
#define CPU_CT_xSIZE_LEN(x) ((x) & 0x3) /* line size */
|
||||
#define CPU_CT_xSIZE_M (1U << 2) /* multiplier */
|
||||
#define CPU_CT_xSIZE_ASSOC(x) (((x) >> 3) & 0x7) /* associativity */
|
||||
#define CPU_CT_xSIZE_SIZE(x) (((x) >> 6) & 0x7) /* size */
|
||||
|
||||
/* Fault status register definitions */
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cpufunc.h,v 1.13 2001/11/28 00:18:46 thorpej Exp $ */
|
||||
/* $NetBSD: cpufunc.h,v 1.14 2001/11/29 02:24:59 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 Mark Brinicombe.
|
||||
@ -396,6 +396,25 @@ int get_pc_str_offset __P((void));
|
||||
|
||||
void cpu_reset __P((void)) __attribute__((__noreturn__));
|
||||
|
||||
/*
|
||||
* Cache info variables.
|
||||
*/
|
||||
|
||||
/* PRIMARY CACHE VARIABLES */
|
||||
int arm_picache_size;
|
||||
int arm_picache_line_size;
|
||||
int arm_picache_ways;
|
||||
|
||||
int arm_pdcache_size; /* and unified */
|
||||
int arm_pdcache_line_size;
|
||||
int arm_pdcache_ways;
|
||||
|
||||
int arm_pcache_type;
|
||||
int arm_pcache_unified;
|
||||
|
||||
int arm_dcache_align;
|
||||
int arm_dcache_align_mask;
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#endif /* _ARM32_CPUFUNC_H_ */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user