Date: Thu, 9 Jul 2015 11:32:30 +0000 (UTC) From: Zbigniew Bodek <zbb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r285311 - in head/sys/arm64: arm64 include Message-ID: <201507091132.t69BWU3Z094067@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: zbb Date: Thu Jul 9 11:32:29 2015 New Revision: 285311 URL: https://svnweb.freebsd.org/changeset/base/285311 Log: Rework CPU identification on ARM64 This commit reworks the code responsible for identification of the CPUs during runtime. It is necessary to provide a way for workarounds and erratums to be applied only for certain HW versions. The copy of MIDR is now stored in pcpu to provide a fast and convenient way for assambly code to read it (pcpu is used quite often so there is a chance it's inside the cache). The MIDR is also better way of identification than using user-friendly cpu_desc structure, because it can be compiled into comparision of single u32 with only one access to the memory - this is crucial for some erratums which are called from performance-critical places. Changes in cpu_identify makes this function safe to be called on non-boot CPUs. New function CPU_MATCH was implemented which returns boolean value based on mathing masked MIDR with chip identification. Example of usage: printf("is thunder: %d\n", CPU_MATCH(CPU_IMPL_MASK | CPU_PART_MASK, CPU_IMPL_CAVIUM, CPU_PART_THUNDER, 0, 0)); printf("is generic: %d\n", CPU_MATCH(CPU_IMPL_MASK | CPU_PART_MASK, CPU_IMPL_ARM, CPU_PART_FOUNDATION, 0, 0)); Reviewed by: andrew Obtained from: Semihalf Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D3030 Modified: head/sys/arm64/arm64/identcpu.c head/sys/arm64/include/cpu.h head/sys/arm64/include/pcpu.h Modified: head/sys/arm64/arm64/identcpu.c ============================================================================== --- head/sys/arm64/arm64/identcpu.c Thu Jul 9 09:22:21 2015 (r285310) +++ head/sys/arm64/arm64/identcpu.c Thu Jul 9 11:32:29 2015 (r285311) @@ -48,7 +48,7 @@ SYSCTL_STRING(_hw, HW_MACHINE, machine, /* * Per-CPU affinity as provided in MPIDR_EL1 * Indexed by CPU number in logical order selected by the system. - * Relevant fields can be extracetd using CPU_AFFn macros, + * Relevant fields can be extracted using CPU_AFFn macros, * Aff3.Aff2.Aff1.Aff0 construct a unique CPU address in the system. * * Fields used by us: @@ -57,28 +57,6 @@ SYSCTL_STRING(_hw, HW_MACHINE, machine, */ uint64_t __cpu_affinity[MAXCPU]; -#define CPU_IMPL_ARM 0x41 -#define CPU_IMPL_BROADCOM 0x42 -#define CPU_IMPL_CAVIUM 0x43 -#define CPU_IMPL_DEC 0x44 -#define CPU_IMPL_INFINEON 0x49 -#define CPU_IMPL_FREESCALE 0x4D -#define CPU_IMPL_NVIDIA 0x4E -#define CPU_IMPL_APM 0x50 -#define CPU_IMPL_QUALCOMM 0x51 -#define CPU_IMPL_MARVELL 0x56 -#define CPU_IMPL_INTEL 0x69 - -#define CPU_PART_THUNDER 0x0A1 -#define CPU_PART_FOUNDATION 0xD00 -#define CPU_PART_CORTEX_A53 0xD03 -#define CPU_PART_CORTEX_A57 0xD07 - -#define CPU_IMPL(midr) (((midr) >> 24) & 0xff) -#define CPU_PART(midr) (((midr) >> 4) & 0xfff) -#define CPU_VAR(midr) (((midr) >> 20) & 0xf) -#define CPU_REV(midr) (((midr) >> 0) & 0xf) - struct cpu_desc { u_int cpu_impl; u_int cpu_part_num; @@ -112,14 +90,14 @@ struct cpu_implementers { */ /* ARM Ltd. */ static const struct cpu_parts cpu_parts_arm[] = { - { 0xD00, "Foundation-Model" }, - { 0xD03, "Cortex-A53" }, - { 0xD07, "Cortex-A57" }, + { CPU_PART_FOUNDATION, "Foundation-Model" }, + { CPU_PART_CORTEX_A53, "Cortex-A53" }, + { CPU_PART_CORTEX_A57, "Cortex-A57" }, CPU_PART_NONE, }; /* Cavium */ static const struct cpu_parts cpu_parts_cavium[] = { - { 0x0A1, "Thunder" }, + { CPU_PART_THUNDER, "Thunder" }, CPU_PART_NONE, }; @@ -162,6 +140,12 @@ identify_cpu(void) cpu = PCPU_GET(cpuid); midr = get_midr(); + /* + * Store midr to pcpu to allow fast reading + * from EL0, EL1 and assembly code. + */ + PCPU_SET(midr, midr); + impl_id = CPU_IMPL(midr); for (i = 0; i < nitems(cpu_implementers); i++) { if (impl_id == cpu_implementers[i].impl_id || @@ -183,15 +167,21 @@ identify_cpu(void) } } - printf("CPU: %s %s r%dp%d\n", cpu_desc[cpu].cpu_impl_name, - cpu_desc[cpu].cpu_part_name, CPU_VAR(midr), CPU_REV(midr)); + cpu_desc[cpu].cpu_revision = CPU_REV(midr); + cpu_desc[cpu].cpu_variant = CPU_VAR(midr); - /* - * Save affinity for the boot CPU. - * (CPU0 in the internal system enumeration. - */ + /* Save affinity for current CPU */ mpidr = get_mpidr(); - CPU_AFFINITY(0) = mpidr & CPU_AFF_MASK; + CPU_AFFINITY(cpu) = mpidr & CPU_AFF_MASK; + + /* Print details for boot CPU or if we want verbose output */ + if (cpu == 0 || bootverbose) { + printf("CPU(%d): %s %s r%dp%d\n", cpu, + cpu_desc[cpu].cpu_impl_name, + cpu_desc[cpu].cpu_part_name, + cpu_desc[cpu].cpu_variant, + cpu_desc[cpu].cpu_revision); + } if (bootverbose) printf("CPU%u affinity: %u.%u.%u.%u\n", 0, CPU_AFF0(mpidr), Modified: head/sys/arm64/include/cpu.h ============================================================================== --- head/sys/arm64/include/cpu.h Thu Jul 9 09:22:21 2015 (r285310) +++ head/sys/arm64/include/cpu.h Thu Jul 9 11:32:29 2015 (r285311) @@ -60,6 +60,43 @@ #ifdef _KERNEL +#define CPU_IMPL_ARM 0x41 +#define CPU_IMPL_BROADCOM 0x42 +#define CPU_IMPL_CAVIUM 0x43 +#define CPU_IMPL_DEC 0x44 +#define CPU_IMPL_INFINEON 0x49 +#define CPU_IMPL_FREESCALE 0x4D +#define CPU_IMPL_NVIDIA 0x4E +#define CPU_IMPL_APM 0x50 +#define CPU_IMPL_QUALCOMM 0x51 +#define CPU_IMPL_MARVELL 0x56 +#define CPU_IMPL_INTEL 0x69 + +#define CPU_PART_THUNDER 0x0A1 +#define CPU_PART_FOUNDATION 0xD00 +#define CPU_PART_CORTEX_A53 0xD03 +#define CPU_PART_CORTEX_A57 0xD07 + +#define CPU_IMPL(midr) (((midr) >> 24) & 0xff) +#define CPU_PART(midr) (((midr) >> 4) & 0xfff) +#define CPU_VAR(midr) (((midr) >> 20) & 0xf) +#define CPU_REV(midr) (((midr) >> 0) & 0xf) + +#define CPU_IMPL_TO_MIDR(val) (((val) & 0xff) << 24) +#define CPU_PART_TO_MIDR(val) (((val) & 0xfff) << 4) +#define CPU_VAR_TO_MIDR(val) (((val) & 0xf) << 20) +#define CPU_REV_TO_MIDR(val) (((val) & 0xf) << 0) + +#define CPU_IMPL_MASK (0xff << 24) +#define CPU_PART_MASK (0xfff << 4) +#define CPU_VAR_MASK (0xf << 20) +#define CPU_REV_MASK (0xf << 0) + +#define CPU_MATCH(mask, impl, part, var, rev) \ + (((mask) & PCPU_GET(midr)) == (CPU_IMPL_TO_MIDR((impl)) | \ + CPU_PART_TO_MIDR((part)) | CPU_VAR_TO_MIDR((var)) | \ + CPU_REV_TO_MIDR((rev)))) + extern char btext[]; extern char etext[]; Modified: head/sys/arm64/include/pcpu.h ============================================================================== --- head/sys/arm64/include/pcpu.h Thu Jul 9 09:22:21 2015 (r285310) +++ head/sys/arm64/include/pcpu.h Thu Jul 9 11:32:29 2015 (r285311) @@ -36,8 +36,9 @@ #define ALT_STACK_SIZE 128 #define PCPU_MD_FIELDS \ - u_int pc_acpi_id; /* ACPI CPU id */ \ - char __pad[125] + u_int pc_acpi_id; /* ACPI CPU id */ \ + u_int pc_midr; /* stored MIDR value */ \ + char __pad[121] #ifdef _KERNEL
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201507091132.t69BWU3Z094067>