From owner-svn-src-stable@freebsd.org Wed Mar 1 22:45:14 2017 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2B10FCF3C22; Wed, 1 Mar 2017 22:45:14 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id EC567CC0; Wed, 1 Mar 2017 22:45:13 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v21MjDNk054983; Wed, 1 Mar 2017 22:45:13 GMT (envelope-from ian@FreeBSD.org) Received: (from ian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v21MjCkC054978; Wed, 1 Mar 2017 22:45:12 GMT (envelope-from ian@FreeBSD.org) Message-Id: <201703012245.v21MjCkC054978@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ian set sender to ian@FreeBSD.org using -f From: Ian Lepore Date: Wed, 1 Mar 2017 22:45:12 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r314525 - in stable/11/sys: arm/arm arm/include conf X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 01 Mar 2017 22:45:14 -0000 Author: ian Date: Wed Mar 1 22:45:12 2017 New Revision: 314525 URL: https://svnweb.freebsd.org/changeset/base/314525 Log: MFC r306901: ARM: Split identify_arm_cpu() into ARMv4 and ARMv6 variant. On ARMv6, be more verbose about supported CPU features and/or optional instructions. Added: stable/11/sys/arm/arm/identcpu-v4.c - copied unchanged from r306901, head/sys/arm/arm/identcpu-v4.c stable/11/sys/arm/arm/identcpu-v6.c - copied unchanged from r306901, head/sys/arm/arm/identcpu-v6.c Deleted: stable/11/sys/arm/arm/identcpu.c Modified: stable/11/sys/arm/arm/cpuinfo.c stable/11/sys/arm/include/cpuinfo.h stable/11/sys/conf/files.arm Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/arm/arm/cpuinfo.c ============================================================================== --- stable/11/sys/arm/arm/cpuinfo.c Wed Mar 1 21:58:26 2017 (r314524) +++ stable/11/sys/arm/arm/cpuinfo.c Wed Mar 1 22:45:12 2017 (r314525) @@ -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 *act 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: Copied: stable/11/sys/arm/arm/identcpu-v4.c (from r306901, head/sys/arm/arm/identcpu-v4.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/11/sys/arm/arm/identcpu-v4.c Wed Mar 1 22:45:12 2017 (r314525, copy of r306901, head/sys/arm/arm/identcpu-v4.c) @@ -0,0 +1,386 @@ +/* $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 +__FBSDID("$FreeBSD$"); +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +char machine[] = "arm"; + +SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, + machine, 0, "Machine class"); + +static const char * const generic_steppings[16] = { + "rev 0", "rev 1", "rev 2", "rev 3", + "rev 4", "rev 5", "rev 6", "rev 7", + "rev 8", "rev 9", "rev 10", "rev 11", + "rev 12", "rev 13", "rev 14", "rev 15", +}; + +static const char * const xscale_steppings[16] = { + "step A-0", "step A-1", "step B-0", "step C-0", + "step D-0", "rev 5", "rev 6", "rev 7", + "rev 8", "rev 9", "rev 10", "rev 11", + "rev 12", "rev 13", "rev 14", "rev 15", +}; + +static const char * const i80219_steppings[16] = { + "step A-0", "rev 1", "rev 2", "rev 3", + "rev 4", "rev 5", "rev 6", "rev 7", + "rev 8", "rev 9", "rev 10", "rev 11", + "rev 12", "rev 13", "rev 14", "rev 15", +}; + +static const char * const i80321_steppings[16] = { + "step A-0", "step B-0", "rev 2", "rev 3", + "rev 4", "rev 5", "rev 6", "rev 7", + "rev 8", "rev 9", "rev 10", "rev 11", + "rev 12", "rev 13", "rev 14", "rev 15", +}; + +static const char * const i81342_steppings[16] = { + "step A-0", "rev 1", "rev 2", "rev 3", + "rev 4", "rev 5", "rev 6", "rev 7", + "rev 8", "rev 9", "rev 10", "rev 11", + "rev 12", "rev 13", "rev 14", "rev 15", +}; + +/* Steppings for PXA2[15]0 */ +static const char * const pxa2x0_steppings[16] = { + "step A-0", "step A-1", "step B-0", "step B-1", + "step B-2", "step C-0", "rev 6", "rev 7", + "rev 8", "rev 9", "rev 10", "rev 11", + "rev 12", "rev 13", "rev 14", "rev 15", +}; + +/* Steppings for PXA255/26x. + * rev 5: PXA26x B0, rev 6: PXA255 A0 + */ +static const char * const pxa255_steppings[16] = { + "rev 0", "rev 1", "rev 2", "step A-0", + "rev 4", "step B-0", "step A-0", "rev 7", + "rev 8", "rev 9", "rev 10", "rev 11", + "rev 12", "rev 13", "rev 14", "rev 15", +}; + +/* Stepping for PXA27x */ +static const char * const pxa27x_steppings[16] = { + "step A-0", "step A-1", "step B-0", "step B-1", + "step C-0", "rev 5", "rev 6", "rev 7", + "rev 8", "rev 9", "rev 10", "rev 11", + "rev 12", "rev 13", "rev 14", "rev 15", +}; + +static const char * const ixp425_steppings[16] = { + "step 0 (A0)", "rev 1 (ARMv5TE)", "rev 2", "rev 3", + "rev 4", "rev 5", "rev 6", "rev 7", + "rev 8", "rev 9", "rev 10", "rev 11", + "rev 12", "rev 13", "rev 14", "rev 15", +}; + +struct cpuidtab { + u_int32_t cpuid; + enum cpu_class cpu_class; + const char *cpu_name; + const char * const *cpu_steppings; +}; + +const struct cpuidtab cpuids[] = { + { CPU_ID_ARM920T, CPU_CLASS_ARM9TDMI, "ARM920T", + generic_steppings }, + { CPU_ID_ARM920T_ALT, CPU_CLASS_ARM9TDMI, "ARM920T", + generic_steppings }, + { CPU_ID_ARM922T, CPU_CLASS_ARM9TDMI, "ARM922T", + generic_steppings }, + { CPU_ID_ARM926EJS, CPU_CLASS_ARM9EJS, "ARM926EJ-S", + generic_steppings }, + { CPU_ID_ARM940T, CPU_CLASS_ARM9TDMI, "ARM940T", + generic_steppings }, + { CPU_ID_ARM946ES, CPU_CLASS_ARM9ES, "ARM946E-S", + generic_steppings }, + { CPU_ID_ARM966ES, CPU_CLASS_ARM9ES, "ARM966E-S", + generic_steppings }, + { CPU_ID_ARM966ESR1, CPU_CLASS_ARM9ES, "ARM966E-S", + generic_steppings }, + { CPU_ID_FA526, CPU_CLASS_ARM9TDMI, "FA526", + generic_steppings }, + { CPU_ID_FA626TE, CPU_CLASS_ARM9ES, "FA626TE", + generic_steppings }, + + { CPU_ID_TI925T, CPU_CLASS_ARM9TDMI, "TI ARM925T", + generic_steppings }, + + { CPU_ID_ARM1020E, CPU_CLASS_ARM10E, "ARM1020E", + generic_steppings }, + { CPU_ID_ARM1022ES, CPU_CLASS_ARM10E, "ARM1022E-S", + generic_steppings }, + { CPU_ID_ARM1026EJS, CPU_CLASS_ARM10EJ, "ARM1026EJ-S", + generic_steppings }, + + { CPU_ID_80200, CPU_CLASS_XSCALE, "i80200", + xscale_steppings }, + + { CPU_ID_80321_400, CPU_CLASS_XSCALE, "i80321 400MHz", + i80321_steppings }, + { CPU_ID_80321_600, CPU_CLASS_XSCALE, "i80321 600MHz", + i80321_steppings }, + { CPU_ID_80321_400_B0, CPU_CLASS_XSCALE, "i80321 400MHz", + i80321_steppings }, + { CPU_ID_80321_600_B0, CPU_CLASS_XSCALE, "i80321 600MHz", + i80321_steppings }, + + { CPU_ID_81342, CPU_CLASS_XSCALE, "i81342", + i81342_steppings }, + + { CPU_ID_80219_400, CPU_CLASS_XSCALE, "i80219 400MHz", + i80219_steppings }, + { CPU_ID_80219_600, CPU_CLASS_XSCALE, "i80219 600MHz", + i80219_steppings }, + + { CPU_ID_PXA27X, CPU_CLASS_XSCALE, "PXA27x", + pxa27x_steppings }, + { CPU_ID_PXA250A, CPU_CLASS_XSCALE, "PXA250", + pxa2x0_steppings }, + { CPU_ID_PXA210A, CPU_CLASS_XSCALE, "PXA210", + pxa2x0_steppings }, + { CPU_ID_PXA250B, CPU_CLASS_XSCALE, "PXA250", + pxa2x0_steppings }, + { CPU_ID_PXA210B, CPU_CLASS_XSCALE, "PXA210", + pxa2x0_steppings }, + { CPU_ID_PXA250C, CPU_CLASS_XSCALE, "PXA255", + pxa255_steppings }, + { CPU_ID_PXA210C, CPU_CLASS_XSCALE, "PXA210", + pxa2x0_steppings }, + + { CPU_ID_IXP425_533, CPU_CLASS_XSCALE, "IXP425 533MHz", + ixp425_steppings }, + { CPU_ID_IXP425_400, CPU_CLASS_XSCALE, "IXP425 400MHz", + ixp425_steppings }, + { CPU_ID_IXP425_266, CPU_CLASS_XSCALE, "IXP425 266MHz", + ixp425_steppings }, + + /* XXX ixp435 steppings? */ + { CPU_ID_IXP435, CPU_CLASS_XSCALE, "IXP435", + ixp425_steppings }, + + { CPU_ID_MV88FR131, CPU_CLASS_MARVELL, "Feroceon 88FR131", + generic_steppings }, + + { CPU_ID_MV88FR571_VD, CPU_CLASS_MARVELL, "Feroceon 88FR571-VD", + generic_steppings }, + + { 0, CPU_CLASS_NONE, NULL, NULL } +}; + +struct cpu_classtab { + const char *class_name; + const char *class_option; +}; + +const struct cpu_classtab cpu_classes[] = { + { "unknown", NULL }, /* CPU_CLASS_NONE */ + { "ARM9TDMI", "CPU_ARM9TDMI" }, /* CPU_CLASS_ARM9TDMI */ + { "ARM9E-S", "CPU_ARM9E" }, /* CPU_CLASS_ARM9ES */ + { "ARM9EJ-S", "CPU_ARM9E" }, /* CPU_CLASS_ARM9EJS */ + { "ARM10E", "CPU_ARM10" }, /* CPU_CLASS_ARM10E */ + { "ARM10EJ", "CPU_ARM10" }, /* CPU_CLASS_ARM10EJ */ + { "XScale", "CPU_XSCALE_..." }, /* CPU_CLASS_XSCALE */ + { "Marvell", "CPU_MARVELL" }, /* CPU_CLASS_MARVELL */ +}; + +/* + * Report the type of the specified arm processor. This uses the generic and + * arm specific information in the cpu structure to identify the processor. + * The remaining fields in the cpu structure are filled in appropriately. + */ + +static const char * const 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**", + "write-back-locking-C", + "**unknown 15**", +}; + +static void +print_enadis(int enadis, char *s) +{ + + printf(" %s %sabled", s, (enadis == 0) ? "dis" : "en"); +} + +enum cpu_class cpu_class = CPU_CLASS_NONE; + +u_int cpu_pfr(int num) +{ + u_int feat; + + switch (num) { + case 0: + __asm __volatile("mrc p15, 0, %0, c0, c1, 0" + : "=r" (feat)); + break; + case 1: + __asm __volatile("mrc p15, 0, %0, c0, c1, 1" + : "=r" (feat)); + break; + default: + panic("Processor Feature Register %d not implemented", num); + break; + } + + return (feat); +} + +void +identify_arm_cpu(void) +{ + u_int cpuid; + u_int8_t ctrl; + int i; + + ctrl = cpu_get_control(); + cpuid = cpu_ident(); + + if (cpuid == 0) { + printf("Processor failed probe - no CPU ID\n"); + return; + } + + for (i = 0; cpuids[i].cpuid != 0; i++) + if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) { + cpu_class = cpuids[i].cpu_class; + printf("CPU: %s %s (%s core)\n", + cpuids[i].cpu_name, + cpuids[i].cpu_steppings[cpuid & + CPU_ID_REVISION_MASK], + cpu_classes[cpu_class].class_name); + break; + } + if (cpuids[i].cpuid == 0) + printf("unknown CPU (ID = 0x%x)\n", cpuid); + + printf(" "); + + 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"); +#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 "); +#endif + break; + default: + break; + } + + print_enadis(ctrl & CPU_CONTROL_WBUF_ENABLE, "WB"); + if (ctrl & CPU_CONTROL_LABT_ENABLE) + printf(" LABT"); + else + printf(" EABT"); + + print_enadis(ctrl & CPU_CONTROL_BPRD_ENABLE, "branch prediction"); + printf("\n"); + + /* 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]); + } +} Copied: stable/11/sys/arm/arm/identcpu-v6.c (from r306901, head/sys/arm/arm/identcpu-v6.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/11/sys/arm/arm/identcpu-v6.c Wed Mar 1 22:45:12 2017 (r314525, copy of r306901, head/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 +__FBSDID("$FreeBSD$"); +#include +#include +#include +#include +#include +#include +#include + +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(); +} Modified: stable/11/sys/arm/include/cpuinfo.h ============================================================================== --- stable/11/sys/arm/include/cpuinfo.h Wed Mar 1 21:58:26 2017 (r314524) +++ stable/11/sys/arm/include/cpuinfo.h Wed Mar 1 22:45:12 2017 (r314525) @@ -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; Modified: stable/11/sys/conf/files.arm ============================================================================== --- stable/11/sys/conf/files.arm Wed Mar 1 21:58:26 2017 (r314524) +++ stable/11/sys/conf/files.arm Wed Mar 1 22:45:12 2017 (r314525) @@ -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