]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - arch/arm64/kernel/setup.c
arm64: elf: use cpuid_feature_extract_field for hwcap detection
[karo-tx-linux.git] / arch / arm64 / kernel / setup.c
1 /*
2  * Based on arch/arm/kernel/setup.c
3  *
4  * Copyright (C) 1995-2001 Russell King
5  * Copyright (C) 2012 ARM Ltd.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <linux/acpi.h>
21 #include <linux/export.h>
22 #include <linux/kernel.h>
23 #include <linux/stddef.h>
24 #include <linux/ioport.h>
25 #include <linux/delay.h>
26 #include <linux/utsname.h>
27 #include <linux/initrd.h>
28 #include <linux/console.h>
29 #include <linux/cache.h>
30 #include <linux/bootmem.h>
31 #include <linux/seq_file.h>
32 #include <linux/screen_info.h>
33 #include <linux/init.h>
34 #include <linux/kexec.h>
35 #include <linux/crash_dump.h>
36 #include <linux/root_dev.h>
37 #include <linux/clk-provider.h>
38 #include <linux/cpu.h>
39 #include <linux/interrupt.h>
40 #include <linux/smp.h>
41 #include <linux/fs.h>
42 #include <linux/proc_fs.h>
43 #include <linux/memblock.h>
44 #include <linux/of_iommu.h>
45 #include <linux/of_fdt.h>
46 #include <linux/of_platform.h>
47 #include <linux/efi.h>
48 #include <linux/personality.h>
49
50 #include <asm/acpi.h>
51 #include <asm/fixmap.h>
52 #include <asm/cpu.h>
53 #include <asm/cputype.h>
54 #include <asm/elf.h>
55 #include <asm/cpufeature.h>
56 #include <asm/cpu_ops.h>
57 #include <asm/sections.h>
58 #include <asm/setup.h>
59 #include <asm/smp_plat.h>
60 #include <asm/cacheflush.h>
61 #include <asm/tlbflush.h>
62 #include <asm/traps.h>
63 #include <asm/memblock.h>
64 #include <asm/psci.h>
65 #include <asm/efi.h>
66 #include <asm/virt.h>
67 #include <asm/xen/hypervisor.h>
68
69 unsigned long elf_hwcap __read_mostly;
70 EXPORT_SYMBOL_GPL(elf_hwcap);
71
72 #ifdef CONFIG_COMPAT
73 #define COMPAT_ELF_HWCAP_DEFAULT        \
74                                 (COMPAT_HWCAP_HALF|COMPAT_HWCAP_THUMB|\
75                                  COMPAT_HWCAP_FAST_MULT|COMPAT_HWCAP_EDSP|\
76                                  COMPAT_HWCAP_TLS|COMPAT_HWCAP_VFP|\
77                                  COMPAT_HWCAP_VFPv3|COMPAT_HWCAP_VFPv4|\
78                                  COMPAT_HWCAP_NEON|COMPAT_HWCAP_IDIV|\
79                                  COMPAT_HWCAP_LPAE)
80 unsigned int compat_elf_hwcap __read_mostly = COMPAT_ELF_HWCAP_DEFAULT;
81 unsigned int compat_elf_hwcap2 __read_mostly;
82 #endif
83
84 DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
85
86 phys_addr_t __fdt_pointer __initdata;
87
88 /*
89  * Standard memory resources
90  */
91 static struct resource mem_res[] = {
92         {
93                 .name = "Kernel code",
94                 .start = 0,
95                 .end = 0,
96                 .flags = IORESOURCE_MEM
97         },
98         {
99                 .name = "Kernel data",
100                 .start = 0,
101                 .end = 0,
102                 .flags = IORESOURCE_MEM
103         }
104 };
105
106 #define kernel_code mem_res[0]
107 #define kernel_data mem_res[1]
108
109 /*
110  * The recorded values of x0 .. x3 upon kernel entry.
111  */
112 u64 __cacheline_aligned boot_args[4];
113
114 void __init smp_setup_processor_id(void)
115 {
116         u64 mpidr = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
117         cpu_logical_map(0) = mpidr;
118
119         /*
120          * clear __my_cpu_offset on boot CPU to avoid hang caused by
121          * using percpu variable early, for example, lockdep will
122          * access percpu variable inside lock_release
123          */
124         set_my_cpu_offset(0);
125         pr_info("Booting Linux on physical CPU 0x%lx\n", (unsigned long)mpidr);
126 }
127
128 bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
129 {
130         return phys_id == cpu_logical_map(cpu);
131 }
132
133 struct mpidr_hash mpidr_hash;
134 /**
135  * smp_build_mpidr_hash - Pre-compute shifts required at each affinity
136  *                        level in order to build a linear index from an
137  *                        MPIDR value. Resulting algorithm is a collision
138  *                        free hash carried out through shifting and ORing
139  */
140 static void __init smp_build_mpidr_hash(void)
141 {
142         u32 i, affinity, fs[4], bits[4], ls;
143         u64 mask = 0;
144         /*
145          * Pre-scan the list of MPIDRS and filter out bits that do
146          * not contribute to affinity levels, ie they never toggle.
147          */
148         for_each_possible_cpu(i)
149                 mask |= (cpu_logical_map(i) ^ cpu_logical_map(0));
150         pr_debug("mask of set bits %#llx\n", mask);
151         /*
152          * Find and stash the last and first bit set at all affinity levels to
153          * check how many bits are required to represent them.
154          */
155         for (i = 0; i < 4; i++) {
156                 affinity = MPIDR_AFFINITY_LEVEL(mask, i);
157                 /*
158                  * Find the MSB bit and LSB bits position
159                  * to determine how many bits are required
160                  * to express the affinity level.
161                  */
162                 ls = fls(affinity);
163                 fs[i] = affinity ? ffs(affinity) - 1 : 0;
164                 bits[i] = ls - fs[i];
165         }
166         /*
167          * An index can be created from the MPIDR_EL1 by isolating the
168          * significant bits at each affinity level and by shifting
169          * them in order to compress the 32 bits values space to a
170          * compressed set of values. This is equivalent to hashing
171          * the MPIDR_EL1 through shifting and ORing. It is a collision free
172          * hash though not minimal since some levels might contain a number
173          * of CPUs that is not an exact power of 2 and their bit
174          * representation might contain holes, eg MPIDR_EL1[7:0] = {0x2, 0x80}.
175          */
176         mpidr_hash.shift_aff[0] = MPIDR_LEVEL_SHIFT(0) + fs[0];
177         mpidr_hash.shift_aff[1] = MPIDR_LEVEL_SHIFT(1) + fs[1] - bits[0];
178         mpidr_hash.shift_aff[2] = MPIDR_LEVEL_SHIFT(2) + fs[2] -
179                                                 (bits[1] + bits[0]);
180         mpidr_hash.shift_aff[3] = MPIDR_LEVEL_SHIFT(3) +
181                                   fs[3] - (bits[2] + bits[1] + bits[0]);
182         mpidr_hash.mask = mask;
183         mpidr_hash.bits = bits[3] + bits[2] + bits[1] + bits[0];
184         pr_debug("MPIDR hash: aff0[%u] aff1[%u] aff2[%u] aff3[%u] mask[%#llx] bits[%u]\n",
185                 mpidr_hash.shift_aff[0],
186                 mpidr_hash.shift_aff[1],
187                 mpidr_hash.shift_aff[2],
188                 mpidr_hash.shift_aff[3],
189                 mpidr_hash.mask,
190                 mpidr_hash.bits);
191         /*
192          * 4x is an arbitrary value used to warn on a hash table much bigger
193          * than expected on most systems.
194          */
195         if (mpidr_hash_size() > 4 * num_possible_cpus())
196                 pr_warn("Large number of MPIDR hash buckets detected\n");
197         __flush_dcache_area(&mpidr_hash, sizeof(struct mpidr_hash));
198 }
199
200 static void __init hyp_mode_check(void)
201 {
202         if (is_hyp_mode_available())
203                 pr_info("CPU: All CPU(s) started at EL2\n");
204         else if (is_hyp_mode_mismatched())
205                 WARN_TAINT(1, TAINT_CPU_OUT_OF_SPEC,
206                            "CPU: CPUs started in inconsistent modes");
207         else
208                 pr_info("CPU: All CPU(s) started at EL1\n");
209 }
210
211 void __init do_post_cpus_up_work(void)
212 {
213         hyp_mode_check();
214         apply_alternatives_all();
215 }
216
217 #ifdef CONFIG_UP_LATE_INIT
218 void __init up_late_init(void)
219 {
220         do_post_cpus_up_work();
221 }
222 #endif /* CONFIG_UP_LATE_INIT */
223
224 static void __init setup_processor(void)
225 {
226         u64 features;
227         s64 block;
228         u32 cwg;
229         int cls;
230
231         printk("CPU: AArch64 Processor [%08x] revision %d\n",
232                read_cpuid_id(), read_cpuid_id() & 15);
233
234         sprintf(init_utsname()->machine, ELF_PLATFORM);
235         elf_hwcap = 0;
236
237         cpuinfo_store_boot_cpu();
238
239         /*
240          * Check for sane CTR_EL0.CWG value.
241          */
242         cwg = cache_type_cwg();
243         cls = cache_line_size();
244         if (!cwg)
245                 pr_warn("No Cache Writeback Granule information, assuming cache line size %d\n",
246                         cls);
247         if (L1_CACHE_BYTES < cls)
248                 pr_warn("L1_CACHE_BYTES smaller than the Cache Writeback Granule (%d < %d)\n",
249                         L1_CACHE_BYTES, cls);
250
251         /*
252          * ID_AA64ISAR0_EL1 contains 4-bit wide signed feature blocks.
253          * The blocks we test below represent incremental functionality
254          * for non-negative values. Negative values are reserved.
255          */
256         features = read_cpuid(ID_AA64ISAR0_EL1);
257         block = cpuid_feature_extract_field(features, 4);
258         if (block > 0) {
259                 switch (block) {
260                 default:
261                 case 2:
262                         elf_hwcap |= HWCAP_PMULL;
263                 case 1:
264                         elf_hwcap |= HWCAP_AES;
265                 case 0:
266                         break;
267                 }
268         }
269
270         if (cpuid_feature_extract_field(features, 8) > 0)
271                 elf_hwcap |= HWCAP_SHA1;
272
273         if (cpuid_feature_extract_field(features, 12) > 0)
274                 elf_hwcap |= HWCAP_SHA2;
275
276         if (cpuid_feature_extract_field(features, 16) > 0)
277                 elf_hwcap |= HWCAP_CRC32;
278
279         block = cpuid_feature_extract_field(features, 20);
280         if (block > 0) {
281                 switch (block) {
282                 default:
283                 case 2:
284                         elf_hwcap |= HWCAP_ATOMICS;
285                 case 1:
286                         /* RESERVED */
287                 case 0:
288                         break;
289                 }
290         }
291
292 #ifdef CONFIG_COMPAT
293         /*
294          * ID_ISAR5_EL1 carries similar information as above, but pertaining to
295          * the AArch32 32-bit execution state.
296          */
297         features = read_cpuid(ID_ISAR5_EL1);
298         block = cpuid_feature_extract_field(features, 4);
299         if (block > 0) {
300                 switch (block) {
301                 default:
302                 case 2:
303                         compat_elf_hwcap2 |= COMPAT_HWCAP2_PMULL;
304                 case 1:
305                         compat_elf_hwcap2 |= COMPAT_HWCAP2_AES;
306                 case 0:
307                         break;
308                 }
309         }
310
311         if (cpuid_feature_extract_field(features, 8) > 0)
312                 compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA1;
313
314         if (cpuid_feature_extract_field(features, 12) > 0)
315                 compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA2;
316
317         if (cpuid_feature_extract_field(features, 16) > 0)
318                 compat_elf_hwcap2 |= COMPAT_HWCAP2_CRC32;
319 #endif
320 }
321
322 static void __init setup_machine_fdt(phys_addr_t dt_phys)
323 {
324         void *dt_virt = fixmap_remap_fdt(dt_phys);
325
326         if (!dt_virt || !early_init_dt_scan(dt_virt)) {
327                 pr_crit("\n"
328                         "Error: invalid device tree blob at physical address %pa (virtual address 0x%p)\n"
329                         "The dtb must be 8-byte aligned and must not exceed 2 MB in size\n"
330                         "\nPlease check your bootloader.",
331                         &dt_phys, dt_virt);
332
333                 while (true)
334                         cpu_relax();
335         }
336
337         dump_stack_set_arch_desc("%s (DT)", of_flat_dt_get_machine_name());
338 }
339
340 static void __init request_standard_resources(void)
341 {
342         struct memblock_region *region;
343         struct resource *res;
344
345         kernel_code.start   = virt_to_phys(_text);
346         kernel_code.end     = virt_to_phys(_etext - 1);
347         kernel_data.start   = virt_to_phys(_sdata);
348         kernel_data.end     = virt_to_phys(_end - 1);
349
350         for_each_memblock(memory, region) {
351                 res = alloc_bootmem_low(sizeof(*res));
352                 res->name  = "System RAM";
353                 res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
354                 res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
355                 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
356
357                 request_resource(&iomem_resource, res);
358
359                 if (kernel_code.start >= res->start &&
360                     kernel_code.end <= res->end)
361                         request_resource(res, &kernel_code);
362                 if (kernel_data.start >= res->start &&
363                     kernel_data.end <= res->end)
364                         request_resource(res, &kernel_data);
365         }
366 }
367
368 u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID };
369
370 void __init setup_arch(char **cmdline_p)
371 {
372         setup_processor();
373
374         init_mm.start_code = (unsigned long) _text;
375         init_mm.end_code   = (unsigned long) _etext;
376         init_mm.end_data   = (unsigned long) _edata;
377         init_mm.brk        = (unsigned long) _end;
378
379         *cmdline_p = boot_command_line;
380
381         early_fixmap_init();
382         early_ioremap_init();
383
384         setup_machine_fdt(__fdt_pointer);
385
386         parse_early_param();
387
388         /*
389          *  Unmask asynchronous aborts after bringing up possible earlycon.
390          * (Report possible System Errors once we can report this occurred)
391          */
392         local_async_enable();
393
394         efi_init();
395         arm64_memblock_init();
396
397         /* Parse the ACPI tables for possible boot-time configuration */
398         acpi_boot_table_init();
399
400         paging_init();
401         request_standard_resources();
402
403         early_ioremap_reset();
404
405         if (acpi_disabled) {
406                 unflatten_device_tree();
407                 psci_dt_init();
408         } else {
409                 psci_acpi_init();
410         }
411         xen_early_init();
412
413         cpu_read_bootcpu_ops();
414         smp_init_cpus();
415         smp_build_mpidr_hash();
416
417 #ifdef CONFIG_VT
418 #if defined(CONFIG_VGA_CONSOLE)
419         conswitchp = &vga_con;
420 #elif defined(CONFIG_DUMMY_CONSOLE)
421         conswitchp = &dummy_con;
422 #endif
423 #endif
424         if (boot_args[1] || boot_args[2] || boot_args[3]) {
425                 pr_err("WARNING: x1-x3 nonzero in violation of boot protocol:\n"
426                         "\tx1: %016llx\n\tx2: %016llx\n\tx3: %016llx\n"
427                         "This indicates a broken bootloader or old kernel\n",
428                         boot_args[1], boot_args[2], boot_args[3]);
429         }
430 }
431
432 static int __init arm64_device_init(void)
433 {
434         if (of_have_populated_dt()) {
435                 of_iommu_init();
436                 of_platform_populate(NULL, of_default_bus_match_table,
437                                      NULL, NULL);
438         } else if (acpi_disabled) {
439                 pr_crit("Device tree not populated\n");
440         }
441         return 0;
442 }
443 arch_initcall_sync(arm64_device_init);
444
445 static int __init topology_init(void)
446 {
447         int i;
448
449         for_each_possible_cpu(i) {
450                 struct cpu *cpu = &per_cpu(cpu_data.cpu, i);
451                 cpu->hotpluggable = 1;
452                 register_cpu(cpu, i);
453         }
454
455         return 0;
456 }
457 subsys_initcall(topology_init);
458
459 static const char *hwcap_str[] = {
460         "fp",
461         "asimd",
462         "evtstrm",
463         "aes",
464         "pmull",
465         "sha1",
466         "sha2",
467         "crc32",
468         "atomics",
469         NULL
470 };
471
472 #ifdef CONFIG_COMPAT
473 static const char *compat_hwcap_str[] = {
474         "swp",
475         "half",
476         "thumb",
477         "26bit",
478         "fastmult",
479         "fpa",
480         "vfp",
481         "edsp",
482         "java",
483         "iwmmxt",
484         "crunch",
485         "thumbee",
486         "neon",
487         "vfpv3",
488         "vfpv3d16",
489         "tls",
490         "vfpv4",
491         "idiva",
492         "idivt",
493         "vfpd32",
494         "lpae",
495         "evtstrm"
496 };
497
498 static const char *compat_hwcap2_str[] = {
499         "aes",
500         "pmull",
501         "sha1",
502         "sha2",
503         "crc32",
504         NULL
505 };
506 #endif /* CONFIG_COMPAT */
507
508 static int c_show(struct seq_file *m, void *v)
509 {
510         int i, j;
511
512         for_each_online_cpu(i) {
513                 struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
514                 u32 midr = cpuinfo->reg_midr;
515
516                 /*
517                  * glibc reads /proc/cpuinfo to determine the number of
518                  * online processors, looking for lines beginning with
519                  * "processor".  Give glibc what it expects.
520                  */
521                 seq_printf(m, "processor\t: %d\n", i);
522
523                 /*
524                  * Dump out the common processor features in a single line.
525                  * Userspace should read the hwcaps with getauxval(AT_HWCAP)
526                  * rather than attempting to parse this, but there's a body of
527                  * software which does already (at least for 32-bit).
528                  */
529                 seq_puts(m, "Features\t:");
530                 if (personality(current->personality) == PER_LINUX32) {
531 #ifdef CONFIG_COMPAT
532                         for (j = 0; compat_hwcap_str[j]; j++)
533                                 if (compat_elf_hwcap & (1 << j))
534                                         seq_printf(m, " %s", compat_hwcap_str[j]);
535
536                         for (j = 0; compat_hwcap2_str[j]; j++)
537                                 if (compat_elf_hwcap2 & (1 << j))
538                                         seq_printf(m, " %s", compat_hwcap2_str[j]);
539 #endif /* CONFIG_COMPAT */
540                 } else {
541                         for (j = 0; hwcap_str[j]; j++)
542                                 if (elf_hwcap & (1 << j))
543                                         seq_printf(m, " %s", hwcap_str[j]);
544                 }
545                 seq_puts(m, "\n");
546
547                 seq_printf(m, "CPU implementer\t: 0x%02x\n",
548                            MIDR_IMPLEMENTOR(midr));
549                 seq_printf(m, "CPU architecture: 8\n");
550                 seq_printf(m, "CPU variant\t: 0x%x\n", MIDR_VARIANT(midr));
551                 seq_printf(m, "CPU part\t: 0x%03x\n", MIDR_PARTNUM(midr));
552                 seq_printf(m, "CPU revision\t: %d\n\n", MIDR_REVISION(midr));
553         }
554
555         return 0;
556 }
557
558 static void *c_start(struct seq_file *m, loff_t *pos)
559 {
560         return *pos < 1 ? (void *)1 : NULL;
561 }
562
563 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
564 {
565         ++*pos;
566         return NULL;
567 }
568
569 static void c_stop(struct seq_file *m, void *v)
570 {
571 }
572
573 const struct seq_operations cpuinfo_op = {
574         .start  = c_start,
575         .next   = c_next,
576         .stop   = c_stop,
577         .show   = c_show
578 };