aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/setup.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-04 17:47:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-04 17:47:13 -0500
commit2dc10ad81fc017837037e60439662e1b16bdffb9 (patch)
treefc2f77874339b2f79499e3b34dc5ecb496b68dfc /arch/arm64/kernel/setup.c
parente627078a0cbdc0c391efeb5a2c4eb287328fd633 (diff)
parentf8f8bdc48851da979c6e0e4808b6031122e4af47 (diff)
Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 updates from Catalin Marinas: - "genirq: Introduce generic irq migration for cpu hotunplugged" patch merged from tip/irq/for-arm to allow the arm64-specific part to be upstreamed via the arm64 tree - CPU feature detection reworked to cope with heterogeneous systems where CPUs may not have exactly the same features. The features reported by the kernel via internal data structures or ELF_HWCAP are delayed until all the CPUs are up (and before user space starts) - Support for 16KB pages, with the additional bonus of a 36-bit VA space, though the latter only depending on EXPERT - Implement native {relaxed, acquire, release} atomics for arm64 - New ASID allocation algorithm which avoids IPI on roll-over, together with TLB invalidation optimisations (using local vs global where feasible) - KASan support for arm64 - EFI_STUB clean-up and isolation for the kernel proper (required by KASan) - copy_{to,from,in}_user optimisations (sharing the memcpy template) - perf: moving arm64 to the arm32/64 shared PMU framework - L1_CACHE_BYTES increased to 128 to accommodate Cavium hardware - Support for the contiguous PTE hint on kernel mapping (16 consecutive entries may be able to use a single TLB entry) - Generic CONFIG_HZ now used on arm64 - defconfig updates * tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (91 commits) arm64/efi: fix libstub build under CONFIG_MODVERSIONS ARM64: Enable multi-core scheduler support by default arm64/efi: move arm64 specific stub C code to libstub arm64: page-align sections for DEBUG_RODATA arm64: Fix build with CONFIG_ZONE_DMA=n arm64: Fix compat register mappings arm64: Increase the max granular size arm64: remove bogus TASK_SIZE_64 check arm64: make Timer Interrupt Frequency selectable arm64/mm: use PAGE_ALIGNED instead of IS_ALIGNED arm64: cachetype: fix definitions of ICACHEF_* flags arm64: cpufeature: declare enable_cpu_capabilities as static genirq: Make the cpuhotplug migration code less noisy arm64: Constify hwcap name string arrays arm64/kvm: Make use of the system wide safe values arm64/debug: Make use of the system wide safe value arm64: Move FP/ASIMD hwcap handling to common code arm64/HWCAP: Use system wide safe values arm64/capabilities: Make use of system wide safe value arm64: Delay cpu feature capability checks ...
Diffstat (limited to 'arch/arm64/kernel/setup.c')
-rw-r--r--arch/arm64/kernel/setup.c245
1 files changed, 6 insertions, 239 deletions
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 232247945b1c..8119479147db 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -28,7 +28,6 @@
28#include <linux/console.h> 28#include <linux/console.h>
29#include <linux/cache.h> 29#include <linux/cache.h>
30#include <linux/bootmem.h> 30#include <linux/bootmem.h>
31#include <linux/seq_file.h>
32#include <linux/screen_info.h> 31#include <linux/screen_info.h>
33#include <linux/init.h> 32#include <linux/init.h>
34#include <linux/kexec.h> 33#include <linux/kexec.h>
@@ -44,7 +43,6 @@
44#include <linux/of_fdt.h> 43#include <linux/of_fdt.h>
45#include <linux/of_platform.h> 44#include <linux/of_platform.h>
46#include <linux/efi.h> 45#include <linux/efi.h>
47#include <linux/personality.h>
48#include <linux/psci.h> 46#include <linux/psci.h>
49 47
50#include <asm/acpi.h> 48#include <asm/acpi.h>
@@ -54,6 +52,7 @@
54#include <asm/elf.h> 52#include <asm/elf.h>
55#include <asm/cpufeature.h> 53#include <asm/cpufeature.h>
56#include <asm/cpu_ops.h> 54#include <asm/cpu_ops.h>
55#include <asm/kasan.h>
57#include <asm/sections.h> 56#include <asm/sections.h>
58#include <asm/setup.h> 57#include <asm/setup.h>
59#include <asm/smp_plat.h> 58#include <asm/smp_plat.h>
@@ -64,23 +63,6 @@
64#include <asm/efi.h> 63#include <asm/efi.h>
65#include <asm/xen/hypervisor.h> 64#include <asm/xen/hypervisor.h>
66 65
67unsigned long elf_hwcap __read_mostly;
68EXPORT_SYMBOL_GPL(elf_hwcap);
69
70#ifdef CONFIG_COMPAT
71#define COMPAT_ELF_HWCAP_DEFAULT \
72 (COMPAT_HWCAP_HALF|COMPAT_HWCAP_THUMB|\
73 COMPAT_HWCAP_FAST_MULT|COMPAT_HWCAP_EDSP|\
74 COMPAT_HWCAP_TLS|COMPAT_HWCAP_VFP|\
75 COMPAT_HWCAP_VFPv3|COMPAT_HWCAP_VFPv4|\
76 COMPAT_HWCAP_NEON|COMPAT_HWCAP_IDIV|\
77 COMPAT_HWCAP_LPAE)
78unsigned int compat_elf_hwcap __read_mostly = COMPAT_ELF_HWCAP_DEFAULT;
79unsigned int compat_elf_hwcap2 __read_mostly;
80#endif
81
82DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
83
84phys_addr_t __fdt_pointer __initdata; 66phys_addr_t __fdt_pointer __initdata;
85 67
86/* 68/*
@@ -195,104 +177,6 @@ static void __init smp_build_mpidr_hash(void)
195 __flush_dcache_area(&mpidr_hash, sizeof(struct mpidr_hash)); 177 __flush_dcache_area(&mpidr_hash, sizeof(struct mpidr_hash));
196} 178}
197 179
198static void __init setup_processor(void)
199{
200 u64 features;
201 s64 block;
202 u32 cwg;
203 int cls;
204
205 printk("CPU: AArch64 Processor [%08x] revision %d\n",
206 read_cpuid_id(), read_cpuid_id() & 15);
207
208 sprintf(init_utsname()->machine, ELF_PLATFORM);
209 elf_hwcap = 0;
210
211 cpuinfo_store_boot_cpu();
212
213 /*
214 * Check for sane CTR_EL0.CWG value.
215 */
216 cwg = cache_type_cwg();
217 cls = cache_line_size();
218 if (!cwg)
219 pr_warn("No Cache Writeback Granule information, assuming cache line size %d\n",
220 cls);
221 if (L1_CACHE_BYTES < cls)
222 pr_warn("L1_CACHE_BYTES smaller than the Cache Writeback Granule (%d < %d)\n",
223 L1_CACHE_BYTES, cls);
224
225 /*
226 * ID_AA64ISAR0_EL1 contains 4-bit wide signed feature blocks.
227 * The blocks we test below represent incremental functionality
228 * for non-negative values. Negative values are reserved.
229 */
230 features = read_cpuid(ID_AA64ISAR0_EL1);
231 block = cpuid_feature_extract_field(features, 4);
232 if (block > 0) {
233 switch (block) {
234 default:
235 case 2:
236 elf_hwcap |= HWCAP_PMULL;
237 case 1:
238 elf_hwcap |= HWCAP_AES;
239 case 0:
240 break;
241 }
242 }
243
244 if (cpuid_feature_extract_field(features, 8) > 0)
245 elf_hwcap |= HWCAP_SHA1;
246
247 if (cpuid_feature_extract_field(features, 12) > 0)
248 elf_hwcap |= HWCAP_SHA2;
249
250 if (cpuid_feature_extract_field(features, 16) > 0)
251 elf_hwcap |= HWCAP_CRC32;
252
253 block = cpuid_feature_extract_field(features, 20);
254 if (block > 0) {
255 switch (block) {
256 default:
257 case 2:
258 elf_hwcap |= HWCAP_ATOMICS;
259 case 1:
260 /* RESERVED */
261 case 0:
262 break;
263 }
264 }
265
266#ifdef CONFIG_COMPAT
267 /*
268 * ID_ISAR5_EL1 carries similar information as above, but pertaining to
269 * the AArch32 32-bit execution state.
270 */
271 features = read_cpuid(ID_ISAR5_EL1);
272 block = cpuid_feature_extract_field(features, 4);
273 if (block > 0) {
274 switch (block) {
275 default:
276 case 2:
277 compat_elf_hwcap2 |= COMPAT_HWCAP2_PMULL;
278 case 1:
279 compat_elf_hwcap2 |= COMPAT_HWCAP2_AES;
280 case 0:
281 break;
282 }
283 }
284
285 if (cpuid_feature_extract_field(features, 8) > 0)
286 compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA1;
287
288 if (cpuid_feature_extract_field(features, 12) > 0)
289 compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA2;
290
291 if (cpuid_feature_extract_field(features, 16) > 0)
292 compat_elf_hwcap2 |= COMPAT_HWCAP2_CRC32;
293#endif
294}
295
296static void __init setup_machine_fdt(phys_addr_t dt_phys) 180static void __init setup_machine_fdt(phys_addr_t dt_phys)
297{ 181{
298 void *dt_virt = fixmap_remap_fdt(dt_phys); 182 void *dt_virt = fixmap_remap_fdt(dt_phys);
@@ -406,8 +290,9 @@ u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID };
406 290
407void __init setup_arch(char **cmdline_p) 291void __init setup_arch(char **cmdline_p)
408{ 292{
409 setup_processor(); 293 pr_info("Boot CPU: AArch64 Processor [%08x]\n", read_cpuid_id());
410 294
295 sprintf(init_utsname()->machine, ELF_PLATFORM);
411 init_mm.start_code = (unsigned long) _text; 296 init_mm.start_code = (unsigned long) _text;
412 init_mm.end_code = (unsigned long) _etext; 297 init_mm.end_code = (unsigned long) _etext;
413 init_mm.end_data = (unsigned long) _edata; 298 init_mm.end_data = (unsigned long) _edata;
@@ -436,6 +321,9 @@ void __init setup_arch(char **cmdline_p)
436 321
437 paging_init(); 322 paging_init();
438 relocate_initrd(); 323 relocate_initrd();
324
325 kasan_init();
326
439 request_standard_resources(); 327 request_standard_resources();
440 328
441 early_ioremap_reset(); 329 early_ioremap_reset();
@@ -493,124 +381,3 @@ static int __init topology_init(void)
493 return 0; 381 return 0;
494} 382}
495subsys_initcall(topology_init); 383subsys_initcall(topology_init);
496
497static const char *hwcap_str[] = {
498 "fp",
499 "asimd",
500 "evtstrm",
501 "aes",
502 "pmull",
503 "sha1",
504 "sha2",
505 "crc32",
506 "atomics",
507 NULL
508};
509
510#ifdef CONFIG_COMPAT
511static const char *compat_hwcap_str[] = {
512 "swp",
513 "half",
514 "thumb",
515 "26bit",
516 "fastmult",
517 "fpa",
518 "vfp",
519 "edsp",
520 "java",
521 "iwmmxt",
522 "crunch",
523 "thumbee",
524 "neon",
525 "vfpv3",
526 "vfpv3d16",
527 "tls",
528 "vfpv4",
529 "idiva",
530 "idivt",
531 "vfpd32",
532 "lpae",
533 "evtstrm"
534};
535
536static const char *compat_hwcap2_str[] = {
537 "aes",
538 "pmull",
539 "sha1",
540 "sha2",
541 "crc32",
542 NULL
543};
544#endif /* CONFIG_COMPAT */
545
546static int c_show(struct seq_file *m, void *v)
547{
548 int i, j;
549
550 for_each_online_cpu(i) {
551 struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
552 u32 midr = cpuinfo->reg_midr;
553
554 /*
555 * glibc reads /proc/cpuinfo to determine the number of
556 * online processors, looking for lines beginning with
557 * "processor". Give glibc what it expects.
558 */
559 seq_printf(m, "processor\t: %d\n", i);
560
561 /*
562 * Dump out the common processor features in a single line.
563 * Userspace should read the hwcaps with getauxval(AT_HWCAP)
564 * rather than attempting to parse this, but there's a body of
565 * software which does already (at least for 32-bit).
566 */
567 seq_puts(m, "Features\t:");
568 if (personality(current->personality) == PER_LINUX32) {
569#ifdef CONFIG_COMPAT
570 for (j = 0; compat_hwcap_str[j]; j++)
571 if (compat_elf_hwcap & (1 << j))
572 seq_printf(m, " %s", compat_hwcap_str[j]);
573
574 for (j = 0; compat_hwcap2_str[j]; j++)
575 if (compat_elf_hwcap2 & (1 << j))
576 seq_printf(m, " %s", compat_hwcap2_str[j]);
577#endif /* CONFIG_COMPAT */
578 } else {
579 for (j = 0; hwcap_str[j]; j++)
580 if (elf_hwcap & (1 << j))
581 seq_printf(m, " %s", hwcap_str[j]);
582 }
583 seq_puts(m, "\n");
584
585 seq_printf(m, "CPU implementer\t: 0x%02x\n",
586 MIDR_IMPLEMENTOR(midr));
587 seq_printf(m, "CPU architecture: 8\n");
588 seq_printf(m, "CPU variant\t: 0x%x\n", MIDR_VARIANT(midr));
589 seq_printf(m, "CPU part\t: 0x%03x\n", MIDR_PARTNUM(midr));
590 seq_printf(m, "CPU revision\t: %d\n\n", MIDR_REVISION(midr));
591 }
592
593 return 0;
594}
595
596static void *c_start(struct seq_file *m, loff_t *pos)
597{
598 return *pos < 1 ? (void *)1 : NULL;
599}
600
601static void *c_next(struct seq_file *m, void *v, loff_t *pos)
602{
603 ++*pos;
604 return NULL;
605}
606
607static void c_stop(struct seq_file *m, void *v)
608{
609}
610
611const struct seq_operations cpuinfo_op = {
612 .start = c_start,
613 .next = c_next,
614 .stop = c_stop,
615 .show = c_show
616};