diff options
-rw-r--r-- | sys/arm/arm/cpuinfo.c | 5 | ||||
-rw-r--r-- | sys/arm/arm/identcpu-v4.c (renamed from sys/arm/arm/identcpu.c) | 240 | ||||
-rw-r--r-- | sys/arm/arm/identcpu-v6.c | 360 | ||||
-rw-r--r-- | sys/arm/include/cpuinfo.h | 7 | ||||
-rw-r--r-- | sys/conf/files.arm | 3 |
5 files changed, 418 insertions, 197 deletions
diff --git a/sys/arm/arm/cpuinfo.c b/sys/arm/arm/cpuinfo.c index 2b734f4..8099882 100644 --- a/sys/arm/arm/cpuinfo.c +++ b/sys/arm/arm/cpuinfo.c @@ -111,6 +111,10 @@ cpuinfo_init(void) /* Not yet - CBAR only exist on ARM SMP Cortex A CPUs cpuinfo.cbar = cp15_cbar_get(); */ + if (CPU_CT_FORMAT(cpuinfo.ctr) == CPU_CT_ARMV7) { + cpuinfo.ccsidr = cp15_ccsidr_get(); + cpuinfo.clidr = cp15_clidr_get(); + } /* Test if revidr is implemented */ if (cpuinfo.revidr == cpuinfo.midr) @@ -163,6 +167,7 @@ cpuinfo_get_actlr_modifier(uint32_t *actlr_mask, uint32_t *actlr_set) if (cpuinfo.implementer == CPU_IMPLEMENTER_ARM) { switch (cpuinfo.part_number) { + case CPU_ARCH_CORTEX_A73: case CPU_ARCH_CORTEX_A72: case CPU_ARCH_CORTEX_A57: case CPU_ARCH_CORTEX_A53: diff --git a/sys/arm/arm/identcpu.c b/sys/arm/arm/identcpu-v4.c index 2b7fec4..46f4843 100644 --- a/sys/arm/arm/identcpu.c +++ b/sys/arm/arm/identcpu-v4.c @@ -45,9 +45,6 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <sys/param.h> -#include <sys/malloc.h> -#include <sys/time.h> -#include <sys/proc.h> #include <sys/conf.h> #include <sys/kernel.h> #include <sys/sysctl.h> @@ -169,39 +166,6 @@ const struct cpuidtab cpuids[] = { { CPU_ID_ARM1026EJS, CPU_CLASS_ARM10EJ, "ARM1026EJ-S", generic_steppings }, - { CPU_ID_CORTEXA5, CPU_CLASS_CORTEXA, "Cortex A5", - generic_steppings }, - { CPU_ID_CORTEXA7, CPU_CLASS_CORTEXA, "Cortex A7", - generic_steppings }, - { CPU_ID_CORTEXA8R1, CPU_CLASS_CORTEXA, "Cortex A8-r1", - generic_steppings }, - { CPU_ID_CORTEXA8R2, CPU_CLASS_CORTEXA, "Cortex A8-r2", - generic_steppings }, - { CPU_ID_CORTEXA8R3, CPU_CLASS_CORTEXA, "Cortex A8-r3", - generic_steppings }, - { CPU_ID_CORTEXA9R1, CPU_CLASS_CORTEXA, "Cortex A9-r1", - generic_steppings }, - { CPU_ID_CORTEXA9R2, CPU_CLASS_CORTEXA, "Cortex A9-r2", - generic_steppings }, - { CPU_ID_CORTEXA9R3, CPU_CLASS_CORTEXA, "Cortex A9-r3", - generic_steppings }, - { CPU_ID_CORTEXA9R4, CPU_CLASS_CORTEXA, "Cortex A9-r4", - generic_steppings }, - { CPU_ID_CORTEXA12R0, CPU_CLASS_CORTEXA, "Cortex A12-r0", - generic_steppings }, - { CPU_ID_CORTEXA15R0, CPU_CLASS_CORTEXA, "Cortex A15-r0", - generic_steppings }, - { CPU_ID_CORTEXA15R1, CPU_CLASS_CORTEXA, "Cortex A15-r1", - generic_steppings }, - { CPU_ID_CORTEXA15R2, CPU_CLASS_CORTEXA, "Cortex A15-r2", - generic_steppings }, - { CPU_ID_CORTEXA15R3, CPU_CLASS_CORTEXA, "Cortex A15-r3", - generic_steppings }, - { CPU_ID_KRAIT300R0, CPU_CLASS_KRAIT, "Krait 300-r0", - generic_steppings }, - { CPU_ID_KRAIT300R1, CPU_CLASS_KRAIT, "Krait 300-r1", - generic_steppings }, - { CPU_ID_80200, CPU_CLASS_XSCALE, "i80200", xscale_steppings }, @@ -248,24 +212,11 @@ const struct cpuidtab cpuids[] = { { CPU_ID_IXP435, CPU_CLASS_XSCALE, "IXP435", ixp425_steppings }, - { CPU_ID_ARM1136JS, CPU_CLASS_ARM11J, "ARM1136J-S", - generic_steppings }, - { CPU_ID_ARM1136JSR1, CPU_CLASS_ARM11J, "ARM1136J-S R1", - generic_steppings }, - { CPU_ID_ARM1176JZS, CPU_CLASS_ARM11J, "ARM1176JZ-S", - generic_steppings }, - { CPU_ID_MV88FR131, CPU_CLASS_MARVELL, "Feroceon 88FR131", generic_steppings }, { CPU_ID_MV88FR571_VD, CPU_CLASS_MARVELL, "Feroceon 88FR571-VD", generic_steppings }, - { CPU_ID_MV88SV581X_V7, CPU_CLASS_MARVELL, "Sheeva 88SV581x", - generic_steppings }, - { CPU_ID_ARM_88SV581X_V7, CPU_CLASS_MARVELL, "Sheeva 88SV581x", - generic_steppings }, - { CPU_ID_MV88SV584X_V7, CPU_CLASS_MARVELL, "Sheeva 88SV584x", - generic_steppings }, { 0, CPU_CLASS_NONE, NULL, NULL } }; @@ -282,10 +233,7 @@ const struct cpu_classtab cpu_classes[] = { { "ARM9EJ-S", "CPU_ARM9E" }, /* CPU_CLASS_ARM9EJS */ { "ARM10E", "CPU_ARM10" }, /* CPU_CLASS_ARM10E */ { "ARM10EJ", "CPU_ARM10" }, /* CPU_CLASS_ARM10EJ */ - { "Cortex-A", "CPU_CORTEXA" }, /* CPU_CLASS_CORTEXA */ - { "Krait", "CPU_KRAIT" }, /* CPU_CLASS_KRAIT */ { "XScale", "CPU_XSCALE_..." }, /* CPU_CLASS_XSCALE */ - { "ARM11J", "CPU_ARM11" }, /* CPU_CLASS_ARM11J */ { "Marvell", "CPU_MARVELL" }, /* CPU_CLASS_MARVELL */ }; @@ -344,50 +292,11 @@ u_int cpu_pfr(int num) return (feat); } -static -void identify_armv7(void) -{ - u_int feature; - - printf("Supported features:"); - /* Get Processor Feature Register 0 */ - feature = cpu_pfr(0); - - if (feature & ARM_PFR0_ARM_ISA_MASK) - printf(" ARM_ISA"); - - if (feature & ARM_PFR0_THUMB2) - printf(" THUMB2"); - else if (feature & ARM_PFR0_THUMB) - printf(" THUMB"); - - if (feature & ARM_PFR0_JAZELLE_MASK) - printf(" JAZELLE"); - - if (feature & ARM_PFR0_THUMBEE_MASK) - printf(" THUMBEE"); - - - /* Get Processor Feature Register 1 */ - feature = cpu_pfr(1); - - if (feature & ARM_PFR1_ARMV4_MASK) - printf(" ARMv4"); - - if (feature & ARM_PFR1_SEC_EXT_MASK) - printf(" Security_Ext"); - - if (feature & ARM_PFR1_MICROCTRL_MASK) - printf(" M_profile"); - - printf("\n"); -} - void identify_arm_cpu(void) { - u_int cpuid, reg, size, sets, ways; - u_int8_t type, linesize, ctrl; + u_int cpuid; + u_int8_t ctrl; int i; ctrl = cpu_get_control(); @@ -413,43 +322,38 @@ identify_arm_cpu(void) printf(" "); - if ((cpuid & CPU_ID_ARCH_MASK) == CPU_ID_CPUID_SCHEME) { - identify_armv7(); - } else { - if (ctrl & CPU_CONTROL_BEND_ENABLE) - printf(" Big-endian"); - else - printf(" Little-endian"); - - switch (cpu_class) { - case CPU_CLASS_ARM9TDMI: - case CPU_CLASS_ARM9ES: - case CPU_CLASS_ARM9EJS: - case CPU_CLASS_ARM10E: - case CPU_CLASS_ARM10EJ: - case CPU_CLASS_XSCALE: - case CPU_CLASS_ARM11J: - case CPU_CLASS_MARVELL: - print_enadis(ctrl & CPU_CONTROL_DC_ENABLE, "DC"); - print_enadis(ctrl & CPU_CONTROL_IC_ENABLE, "IC"); + if (ctrl & CPU_CONTROL_BEND_ENABLE) + printf(" Big-endian"); + else + printf(" Little-endian"); + + switch (cpu_class) { + case CPU_CLASS_ARM9TDMI: + case CPU_CLASS_ARM9ES: + case CPU_CLASS_ARM9EJS: + case CPU_CLASS_ARM10E: + case CPU_CLASS_ARM10EJ: + case CPU_CLASS_XSCALE: + case CPU_CLASS_MARVELL: + print_enadis(ctrl & CPU_CONTROL_DC_ENABLE, "DC"); + print_enadis(ctrl & CPU_CONTROL_IC_ENABLE, "IC"); #ifdef CPU_XSCALE_81342 - print_enadis(ctrl & CPU_CONTROL_L2_ENABLE, "L2"); + print_enadis(ctrl & CPU_CONTROL_L2_ENABLE, "L2"); #endif #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY) - i = sheeva_control_ext(0, 0); - print_enadis(i & MV_WA_ENABLE, "WA"); - print_enadis(i & MV_DC_STREAM_ENABLE, "DC streaming"); - printf("\n "); - print_enadis((i & MV_BTB_DISABLE) == 0, "BTB"); - print_enadis(i & MV_L2_ENABLE, "L2"); - print_enadis((i & MV_L2_PREFETCH_DISABLE) == 0, - "L2 prefetch"); - printf("\n "); + i = sheeva_control_ext(0, 0); + print_enadis(i & MV_WA_ENABLE, "WA"); + print_enadis(i & MV_DC_STREAM_ENABLE, "DC streaming"); + printf("\n "); + print_enadis((i & MV_BTB_DISABLE) == 0, "BTB"); + print_enadis(i & MV_L2_ENABLE, "L2"); + print_enadis((i & MV_L2_PREFETCH_DISABLE) == 0, + "L2 prefetch"); + printf("\n "); #endif - break; - default: - break; - } + break; + default: + break; } print_enadis(ctrl & CPU_CONTROL_WBUF_ENABLE, "WB"); @@ -461,74 +365,22 @@ identify_arm_cpu(void) print_enadis(ctrl & CPU_CONTROL_BPRD_ENABLE, "branch prediction"); printf("\n"); - if (arm_cache_level) { - printf("LoUU:%d LoC:%d LoUIS:%d \n", CPU_CLIDR_LOUU(arm_cache_level) + 1, - arm_cache_loc + 1, CPU_CLIDR_LOUIS(arm_cache_level) + 1); - i = 0; - while (((type = CPU_CLIDR_CTYPE(arm_cache_level, i)) != 0) && i < 7) { - printf("Cache level %d: \n", i + 1); - if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE || - type == CACHE_SEP_CACHE) { - reg = arm_cache_type[2 * i]; - ways = CPUV7_CT_xSIZE_ASSOC(reg) + 1; - sets = CPUV7_CT_xSIZE_SET(reg) + 1; - linesize = 1 << (CPUV7_CT_xSIZE_LEN(reg) + 4); - size = (ways * sets * linesize) / 1024; - - if (type == CACHE_UNI_CACHE) - printf(" %dKB/%dB %d-way unified cache", size, linesize,ways); - else - printf(" %dKB/%dB %d-way data cache", size, linesize, ways); - if (reg & CPUV7_CT_CTYPE_WT) - printf(" WT"); - if (reg & CPUV7_CT_CTYPE_WB) - printf(" WB"); - if (reg & CPUV7_CT_CTYPE_RA) - printf(" Read-Alloc"); - if (reg & CPUV7_CT_CTYPE_WA) - printf(" Write-Alloc"); - printf("\n"); - } - - if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) { - reg = arm_cache_type[(2 * i) + 1]; - - ways = CPUV7_CT_xSIZE_ASSOC(reg) + 1; - sets = CPUV7_CT_xSIZE_SET(reg) + 1; - linesize = 1 << (CPUV7_CT_xSIZE_LEN(reg) + 4); - size = (ways * sets * linesize) / 1024; - - printf(" %dKB/%dB %d-way instruction cache", size, linesize, ways); - if (reg & CPUV7_CT_CTYPE_WT) - printf(" WT"); - if (reg & CPUV7_CT_CTYPE_WB) - printf(" WB"); - if (reg & CPUV7_CT_CTYPE_RA) - printf(" Read-Alloc"); - if (reg & CPUV7_CT_CTYPE_WA) - printf(" Write-Alloc"); - printf("\n"); - } - i++; - } + /* Print cache info. */ + if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0) + return; + + if (arm_pcache_unified) { + printf(" %dKB/%dB %d-way %s unified cache\n", + arm_pdcache_size / 1024, + arm_pdcache_line_size, arm_pdcache_ways, + wtnames[arm_pcache_type]); } else { - /* Print cache info. */ - if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0) - return; - - if (arm_pcache_unified) { - printf(" %dKB/%dB %d-way %s unified cache\n", - arm_pdcache_size / 1024, - arm_pdcache_line_size, arm_pdcache_ways, - wtnames[arm_pcache_type]); - } else { - printf(" %dKB/%dB %d-way instruction cache\n", - arm_picache_size / 1024, - arm_picache_line_size, arm_picache_ways); - printf(" %dKB/%dB %d-way %s data cache\n", - arm_pdcache_size / 1024, - arm_pdcache_line_size, arm_pdcache_ways, - wtnames[arm_pcache_type]); - } + printf(" %dKB/%dB %d-way instruction cache\n", + arm_picache_size / 1024, + arm_picache_line_size, arm_picache_ways); + printf(" %dKB/%dB %d-way %s data cache\n", + arm_pdcache_size / 1024, + arm_pdcache_line_size, arm_pdcache_ways, + wtnames[arm_pcache_type]); } } diff --git a/sys/arm/arm/identcpu-v6.c b/sys/arm/arm/identcpu-v6.c new file mode 100644 index 0000000..55d331c --- /dev/null +++ b/sys/arm/arm/identcpu-v6.c @@ -0,0 +1,360 @@ +/* $NetBSD: cpu.c,v 1.55 2004/02/13 11:36:10 wiz Exp $ */ + +/*- + * Copyright (c) 1995 Mark Brinicombe. + * Copyright (c) 1995 Brini. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Brini. + * 4. The name of the company nor the name of the author may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RiscBSD kernel project + * + * cpu.c + * + * Probing and configuration for the master CPU + * + * Created : 10/10/95 + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); +#include <sys/systm.h> +#include <sys/param.h> +#include <sys/conf.h> +#include <sys/kernel.h> +#include <sys/sysctl.h> +#include <machine/cpu.h> +#include <machine/md_var.h> + +char machine[] = "arm"; + +SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, + machine, 0, "Machine class"); + +static char hw_buf[81]; +static int hw_buf_idx; +static bool hw_buf_newline; + +static struct { + int implementer; + int part_number; + char *impl_name; + char *core_name; +} cpu_names[] = { + {CPU_IMPLEMENTER_ARM, CPU_ARCH_ARM1176, "ARM", "ARM1176"}, + {CPU_IMPLEMENTER_ARM, CPU_ARCH_CORTEX_A5 , "ARM", "Cortex-A5"}, + {CPU_IMPLEMENTER_ARM, CPU_ARCH_CORTEX_A7 , "ARM", "Cortex-A7"}, + {CPU_IMPLEMENTER_ARM, CPU_ARCH_CORTEX_A8 , "ARM", "Cortex-A8"}, + {CPU_IMPLEMENTER_ARM, CPU_ARCH_CORTEX_A9 , "ARM", "Cortex-A9"}, + {CPU_IMPLEMENTER_ARM, CPU_ARCH_CORTEX_A12, "ARM", "Cortex-A12"}, + {CPU_IMPLEMENTER_ARM, CPU_ARCH_CORTEX_A15, "ARM", "Cortex-A15"}, + {CPU_IMPLEMENTER_ARM, CPU_ARCH_CORTEX_A17, "ARM", "Cortex-A17"}, + {CPU_IMPLEMENTER_ARM, CPU_ARCH_CORTEX_A53, "ARM", "Cortex-A53"}, + {CPU_IMPLEMENTER_ARM, CPU_ARCH_CORTEX_A57, "ARM", "Cortex-A57"}, + {CPU_IMPLEMENTER_ARM, CPU_ARCH_CORTEX_A72, "ARM", "Cortex-A72"}, + {CPU_IMPLEMENTER_ARM, CPU_ARCH_CORTEX_A73, "ARM", "Cortex-A73"}, + + {CPU_IMPLEMENTER_MRVL, CPU_ARCH_SHEEVA_581, "Marwell", "PJ4 v7"}, + {CPU_IMPLEMENTER_MRVL, CPU_ARCH_SHEEVA_584, "Marwell", "PJ4MP v7"}, + + {CPU_IMPLEMENTER_QCOM, CPU_ARCH_KRAIT_300, "Qualcomm", "Krait 300"}, +}; + + +static void +print_v5_cache(void) +{ + uint32_t isize, dsize; + uint32_t multiplier; + int pcache_type; + int pcache_unified; + int picache_size; + int picache_line_size; + int picache_ways; + int pdcache_size; + int pdcache_line_size; + int pdcache_ways; + + pcache_unified = 0; + picache_size = 0 ; + picache_line_size = 0 ; + picache_ways = 0 ; + pdcache_size = 0; + pdcache_line_size = 0; + pdcache_ways = 0; + + if ((cpuinfo.ctr & CPU_CT_S) == 0) + pcache_unified = 1; + + /* + * If you want to know how this code works, go read the ARM ARM. + */ + pcache_type = CPU_CT_CTYPE(cpuinfo.ctr); + + if (pcache_unified == 0) { + isize = CPU_CT_ISIZE(cpuinfo.ctr); + multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2; + picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3); + if (CPU_CT_xSIZE_ASSOC(isize) == 0) { + if (isize & CPU_CT_xSIZE_M) + picache_line_size = 0; /* not present */ + else + picache_ways = 1; + } else { + picache_ways = multiplier << + (CPU_CT_xSIZE_ASSOC(isize) - 1); + } + picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8); + } + + dsize = CPU_CT_DSIZE(cpuinfo.ctr); + multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2; + pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3); + if (CPU_CT_xSIZE_ASSOC(dsize) == 0) { + if (dsize & CPU_CT_xSIZE_M) + pdcache_line_size = 0; /* not present */ + else + pdcache_ways = 1; + } else { + pdcache_ways = multiplier << + (CPU_CT_xSIZE_ASSOC(dsize) - 1); + } + pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8); + + + /* Print cache info. */ + if (picache_line_size == 0 && pdcache_line_size == 0) + return; + + if (pcache_unified) { + printf(" %dKB/%dB %d-way %s unified cache\n", + pdcache_size / 1024, + pdcache_line_size, pdcache_ways, + pcache_type == 0 ? "WT" : "WB"); + } else { + printf(" %dKB/%dB %d-way instruction cache\n", + picache_size / 1024, + picache_line_size, picache_ways); + printf(" %dKB/%dB %d-way %s data cache\n", + pdcache_size / 1024, + pdcache_line_size, pdcache_ways, + pcache_type == 0 ? "WT" : "WB"); + } +} + +static void +print_v7_cache(void ) +{ + uint32_t type, val, size, sets, ways, linesize; + int i; + + printf("LoUU:%d LoC:%d LoUIS:%d \n", + CPU_CLIDR_LOUU(cpuinfo.clidr) + 1, + CPU_CLIDR_LOC(cpuinfo.clidr) + 1, + CPU_CLIDR_LOUIS(cpuinfo.clidr) + 1); + + for (i = 0; i < 7; i++) { + type = CPU_CLIDR_CTYPE(cpuinfo.clidr, i); + if (type == 0) + break; + printf("Cache level %d:\n", i + 1); + if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE || + type == CACHE_SEP_CACHE) { + cp15_csselr_set(i << 1); + val = cp15_ccsidr_get(); + ways = CPUV7_CT_xSIZE_ASSOC(val) + 1; + sets = CPUV7_CT_xSIZE_SET(val) + 1; + linesize = 1 << (CPUV7_CT_xSIZE_LEN(val) + 4); + size = (ways * sets * linesize) / 1024; + + if (type == CACHE_UNI_CACHE) + printf(" %dKB/%dB %d-way unified cache", + size, linesize,ways); + else + printf(" %dKB/%dB %d-way data cache", + size, linesize, ways); + if (val & CPUV7_CT_CTYPE_WT) + printf(" WT"); + if (val & CPUV7_CT_CTYPE_WB) + printf(" WB"); + if (val & CPUV7_CT_CTYPE_RA) + printf(" Read-Alloc"); + if (val & CPUV7_CT_CTYPE_WA) + printf(" Write-Alloc"); + printf("\n"); + } + + if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) { + cp15_csselr_set(i << 1 | 1); + val = cp15_ccsidr_get(); + ways = CPUV7_CT_xSIZE_ASSOC(val) + 1; + sets = CPUV7_CT_xSIZE_SET(val) + 1; + linesize = 1 << (CPUV7_CT_xSIZE_LEN(val) + 4); + size = (ways * sets * linesize) / 1024; + printf(" %dKB/%dB %d-way instruction cache", + size, linesize, ways); + if (val & CPUV7_CT_CTYPE_WT) + printf(" WT"); + if (val & CPUV7_CT_CTYPE_WB) + printf(" WB"); + if (val & CPUV7_CT_CTYPE_RA) + printf(" Read-Alloc"); + if (val & CPUV7_CT_CTYPE_WA) + printf(" Write-Alloc"); + printf("\n"); + } + } + cp15_csselr_set(0); +} + +static void +add_cap(char *cap) +{ + int len; + + len = strlen(cap); + + if ((hw_buf_idx + len + 2) >= 79) { + printf("%s,\n", hw_buf); + hw_buf_idx = 0; + hw_buf_newline = true; + } + if (hw_buf_newline) + hw_buf_idx += sprintf(hw_buf + hw_buf_idx, " "); + else + hw_buf_idx += sprintf(hw_buf + hw_buf_idx, ", "); + hw_buf_newline = false; + + + hw_buf_idx += sprintf(hw_buf + hw_buf_idx, "%s", cap); +} + +void +identify_arm_cpu(void) +{ + int i; + u_int val; + + /* + * CPU + */ + for(i = 0; i < nitems(cpu_names); i++) { + if (cpu_names[i].implementer == cpuinfo.implementer && + cpu_names[i].part_number == cpuinfo.part_number) { + printf("CPU: %s %s r%dp%d (ECO: 0x%08X)\n", + cpu_names[i].impl_name, cpu_names[i].core_name, + cpuinfo.revision, cpuinfo.patch, + cpuinfo.midr != cpuinfo.revidr ? + cpuinfo.revidr : 0); + break; + } + + } + if (i >= nitems(cpu_names)) + printf("unknown CPU (ID = 0x%x)\n", cpuinfo.midr); + + printf("CPU Features: \n"); + hw_buf_idx = 0; + hw_buf_newline = true; + + val = (cpuinfo.mpidr >> 4)& 0xF; + if (cpuinfo.mpidr & (1 << 31U)) + add_cap("Multiprocessing"); + val = (cpuinfo.id_pfr0 >> 4)& 0xF; + if (val == 1) + add_cap("Thumb"); + else if (val == 3) + add_cap("Thumb2"); + + val = (cpuinfo.id_pfr1 >> 4)& 0xF; + if (val == 1 || val == 2) + add_cap("Security"); + + val = (cpuinfo.id_pfr1 >> 12)& 0xF; + if (val == 1) + add_cap("Virtualization"); + + val = (cpuinfo.id_pfr1 >> 16)& 0xF; + if (val == 1) + add_cap("Generic Timer"); + + val = (cpuinfo.id_mmfr0 >> 0)& 0xF; + if (val == 2) { + add_cap("VMSAv6"); + } else if (val >= 3) { + add_cap("VMSAv7"); + if (val >= 4) + add_cap("PXN"); + if (val >= 5) + add_cap("LPAE"); + } + + val = (cpuinfo.id_mmfr3 >> 20)& 0xF; + if (val == 1) + add_cap("Coherent Walk"); + + if (hw_buf_idx != 0) + printf("%s\n", hw_buf); + + printf("Optional instructions: \n"); + hw_buf_idx = 0; + hw_buf_newline = true; + val = (cpuinfo.id_isar0 >> 24)& 0xF; + if (val == 1) + add_cap("SDIV/UDIV (Thumb)"); + else if (val == 2) + add_cap("SDIV/UDIV"); + + val = (cpuinfo.id_isar2 >> 20)& 0xF; + if (val == 1 || val == 2) + add_cap("UMULL"); + + val = (cpuinfo.id_isar2 >> 16)& 0xF; + if (val == 1 || val == 2 || val == 3) + add_cap("SMULL"); + + val = (cpuinfo.id_isar2 >> 12)& 0xF; + if (val == 1) + add_cap("MLA"); + + val = (cpuinfo.id_isar3 >> 4)& 0xF; + if (val == 1) + add_cap("SIMD"); + else if (val == 3) + add_cap("SIMD(ext)"); + if (hw_buf_idx != 0) + printf("%s\n", hw_buf); + + /* + * Cache + */ + if (CPU_CT_FORMAT(cpuinfo.ctr) == CPU_CT_ARMV7) + print_v7_cache(); + else + print_v5_cache(); +} diff --git a/sys/arm/include/cpuinfo.h b/sys/arm/include/cpuinfo.h index f4db021..41b5e6d 100644 --- a/sys/arm/include/cpuinfo.h +++ b/sys/arm/include/cpuinfo.h @@ -48,13 +48,14 @@ #define CPU_ARCH_CORTEX_A53 0xD03 #define CPU_ARCH_CORTEX_A57 0xD07 #define CPU_ARCH_CORTEX_A72 0xD08 +#define CPU_ARCH_CORTEX_A73 0xD09 /* QCOM */ #define CPU_ARCH_KRAIT_300 0x06F /* MRVL */ -#define CPU_ARCH_SHEEVA_851 0x581 /* PJ4/PJ4B */ +#define CPU_ARCH_SHEEVA_581 0x581 /* PJ4/PJ4B */ #define CPU_ARCH_SHEEVA_584 0x584 /* PJ4B-MP/PJ4C */ struct cpuinfo { @@ -80,8 +81,10 @@ struct cpuinfo { uint32_t id_isar4; uint32_t id_isar5; uint32_t cbar; + uint32_t ccsidr; + uint32_t clidr; - /* Parsed bits of above registers... */ + /* Parsed bits of above registers... */ /* midr */ int implementer; diff --git a/sys/conf/files.arm b/sys/conf/files.arm index d6bd843..a5657bc 100644 --- a/sys/conf/files.arm +++ b/sys/conf/files.arm @@ -53,7 +53,8 @@ arm/arm/gdb_machdep.c optional gdb arm/arm/generic_timer.c optional generic_timer arm/arm/gic.c optional gic arm/arm/hdmi_if.m optional hdmi -arm/arm/identcpu.c standard +arm/arm/identcpu-v4.c optional !armv6 +arm/arm/identcpu-v6.c optional armv6 arm/arm/in_cksum.c optional inet | inet6 arm/arm/in_cksum_arm.S optional inet | inet6 arm/arm/intr.c optional !intrng |