Branch data Line data Source code
1 : : /*
2 : : * linux/arch/arm/kernel/setup.c
3 : : *
4 : : * Copyright (C) 1995-2001 Russell King
5 : : *
6 : : * This program is free software; you can redistribute it and/or modify
7 : : * it under the terms of the GNU General Public License version 2 as
8 : : * published by the Free Software Foundation.
9 : : */
10 : : #include <linux/export.h>
11 : : #include <linux/kernel.h>
12 : : #include <linux/stddef.h>
13 : : #include <linux/ioport.h>
14 : : #include <linux/delay.h>
15 : : #include <linux/utsname.h>
16 : : #include <linux/initrd.h>
17 : : #include <linux/console.h>
18 : : #include <linux/bootmem.h>
19 : : #include <linux/seq_file.h>
20 : : #include <linux/screen_info.h>
21 : : #include <linux/of_platform.h>
22 : : #include <linux/init.h>
23 : : #include <linux/kexec.h>
24 : : #include <linux/of_fdt.h>
25 : : #include <linux/cpu.h>
26 : : #include <linux/interrupt.h>
27 : : #include <linux/smp.h>
28 : : #include <linux/proc_fs.h>
29 : : #include <linux/memblock.h>
30 : : #include <linux/bug.h>
31 : : #include <linux/compiler.h>
32 : : #include <linux/sort.h>
33 : :
34 : : #include <asm/unified.h>
35 : : #include <asm/cp15.h>
36 : : #include <asm/cpu.h>
37 : : #include <asm/cputype.h>
38 : : #include <asm/elf.h>
39 : : #include <asm/procinfo.h>
40 : : #include <asm/psci.h>
41 : : #include <asm/sections.h>
42 : : #include <asm/setup.h>
43 : : #include <asm/smp_plat.h>
44 : : #include <asm/mach-types.h>
45 : : #include <asm/cacheflush.h>
46 : : #include <asm/cachetype.h>
47 : : #include <asm/tlbflush.h>
48 : :
49 : : #include <asm/prom.h>
50 : : #include <asm/mach/arch.h>
51 : : #include <asm/mach/irq.h>
52 : : #include <asm/mach/time.h>
53 : : #include <asm/system_info.h>
54 : : #include <asm/system_misc.h>
55 : : #include <asm/traps.h>
56 : : #include <asm/unwind.h>
57 : : #include <asm/memblock.h>
58 : : #include <asm/virt.h>
59 : :
60 : : #include "atags.h"
61 : :
62 : :
63 : : #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
64 : : char fpe_type[8];
65 : :
66 : : static int __init fpe_setup(char *line)
67 : : {
68 : : memcpy(fpe_type, line, 8);
69 : : return 1;
70 : : }
71 : :
72 : : __setup("fpe=", fpe_setup);
73 : : #endif
74 : :
75 : : extern void paging_init(const struct machine_desc *desc);
76 : : extern void early_paging_init(const struct machine_desc *,
77 : : struct proc_info_list *);
78 : : extern void sanity_check_meminfo(void);
79 : : extern enum reboot_mode reboot_mode;
80 : : extern void setup_dma_zone(const struct machine_desc *desc);
81 : :
82 : : unsigned int processor_id;
83 : : EXPORT_SYMBOL(processor_id);
84 : : unsigned int __machine_arch_type __read_mostly;
85 : : EXPORT_SYMBOL(__machine_arch_type);
86 : : unsigned int cacheid __read_mostly;
87 : : EXPORT_SYMBOL(cacheid);
88 : :
89 : : unsigned int __atags_pointer __initdata;
90 : :
91 : : unsigned int system_rev;
92 : : EXPORT_SYMBOL(system_rev);
93 : :
94 : : unsigned int system_serial_low;
95 : : EXPORT_SYMBOL(system_serial_low);
96 : :
97 : : unsigned int system_serial_high;
98 : : EXPORT_SYMBOL(system_serial_high);
99 : :
100 : : unsigned int elf_hwcap __read_mostly;
101 : : EXPORT_SYMBOL(elf_hwcap);
102 : :
103 : :
104 : : #ifdef MULTI_CPU
105 : : struct processor processor __read_mostly;
106 : : #endif
107 : : #ifdef MULTI_TLB
108 : : struct cpu_tlb_fns cpu_tlb __read_mostly;
109 : : #endif
110 : : #ifdef MULTI_USER
111 : : struct cpu_user_fns cpu_user __read_mostly;
112 : : #endif
113 : : #ifdef MULTI_CACHE
114 : : struct cpu_cache_fns cpu_cache __read_mostly;
115 : : #endif
116 : : #ifdef CONFIG_OUTER_CACHE
117 : : struct outer_cache_fns outer_cache __read_mostly;
118 : : EXPORT_SYMBOL(outer_cache);
119 : : #endif
120 : :
121 : : /*
122 : : * Cached cpu_architecture() result for use by assembler code.
123 : : * C code should use the cpu_architecture() function instead of accessing this
124 : : * variable directly.
125 : : */
126 : : int __cpu_architecture __read_mostly = CPU_ARCH_UNKNOWN;
127 : :
128 : : struct stack {
129 : : u32 irq[3];
130 : : u32 abt[3];
131 : : u32 und[3];
132 : : } ____cacheline_aligned;
133 : :
134 : : #ifndef CONFIG_CPU_V7M
135 : : static struct stack stacks[NR_CPUS];
136 : : #endif
137 : :
138 : : char elf_platform[ELF_PLATFORM_SIZE];
139 : : EXPORT_SYMBOL(elf_platform);
140 : :
141 : : static const char *cpu_name;
142 : : static const char *machine_name;
143 : : static char __initdata cmd_line[COMMAND_LINE_SIZE];
144 : : const struct machine_desc *machine_desc __initdata;
145 : :
146 : : static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
147 : : #define ENDIANNESS ((char)endian_test.l)
148 : :
149 : : DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data);
150 : :
151 : : /*
152 : : * Standard memory resources
153 : : */
154 : : static struct resource mem_res[] = {
155 : : {
156 : : .name = "Video RAM",
157 : : .start = 0,
158 : : .end = 0,
159 : : .flags = IORESOURCE_MEM
160 : : },
161 : : {
162 : : .name = "Kernel code",
163 : : .start = 0,
164 : : .end = 0,
165 : : .flags = IORESOURCE_MEM
166 : : },
167 : : {
168 : : .name = "Kernel data",
169 : : .start = 0,
170 : : .end = 0,
171 : : .flags = IORESOURCE_MEM
172 : : }
173 : : };
174 : :
175 : : #define video_ram mem_res[0]
176 : : #define kernel_code mem_res[1]
177 : : #define kernel_data mem_res[2]
178 : :
179 : : static struct resource io_res[] = {
180 : : {
181 : : .name = "reserved",
182 : : .start = 0x3bc,
183 : : .end = 0x3be,
184 : : .flags = IORESOURCE_IO | IORESOURCE_BUSY
185 : : },
186 : : {
187 : : .name = "reserved",
188 : : .start = 0x378,
189 : : .end = 0x37f,
190 : : .flags = IORESOURCE_IO | IORESOURCE_BUSY
191 : : },
192 : : {
193 : : .name = "reserved",
194 : : .start = 0x278,
195 : : .end = 0x27f,
196 : : .flags = IORESOURCE_IO | IORESOURCE_BUSY
197 : : }
198 : : };
199 : :
200 : : #define lp0 io_res[0]
201 : : #define lp1 io_res[1]
202 : : #define lp2 io_res[2]
203 : :
204 : : static const char *proc_arch[] = {
205 : : "undefined/unknown",
206 : : "3",
207 : : "4",
208 : : "4T",
209 : : "5",
210 : : "5T",
211 : : "5TE",
212 : : "5TEJ",
213 : : "6TEJ",
214 : : "7",
215 : : "7M",
216 : : "?(12)",
217 : : "?(13)",
218 : : "?(14)",
219 : : "?(15)",
220 : : "?(16)",
221 : : "?(17)",
222 : : };
223 : :
224 : : #ifdef CONFIG_CPU_V7M
225 : : static int __get_cpu_architecture(void)
226 : : {
227 : : return CPU_ARCH_ARMv7M;
228 : : }
229 : : #else
230 : 0 : static int __get_cpu_architecture(void)
231 : : {
232 : : int cpu_arch;
233 : :
234 [ # # ]: 0 : if ((read_cpuid_id() & 0x0008f000) == 0) {
235 : : cpu_arch = CPU_ARCH_UNKNOWN;
236 [ # # ]: 0 : } else if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
237 [ # # ]: 0 : cpu_arch = (read_cpuid_id() & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
238 [ # # ]: 0 : } else if ((read_cpuid_id() & 0x00080000) == 0x00000000) {
239 : 0 : cpu_arch = (read_cpuid_id() >> 16) & 7;
240 [ # # ]: 0 : if (cpu_arch)
241 : 0 : cpu_arch += CPU_ARCH_ARMv3;
242 [ # # ]: 0 : } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
243 : : unsigned int mmfr0;
244 : :
245 : : /* Revised CPUID format. Read the Memory Model Feature
246 : : * Register 0 and check for VMSAv7 or PMSAv7 */
247 : 0 : asm("mrc p15, 0, %0, c0, c1, 4"
248 : : : "=r" (mmfr0));
249 [ # # ][ # # ]: 0 : if ((mmfr0 & 0x0000000f) >= 0x00000003 ||
250 : 0 : (mmfr0 & 0x000000f0) >= 0x00000030)
251 : : cpu_arch = CPU_ARCH_ARMv7;
252 [ # # ][ # # ]: 0 : else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
253 : : (mmfr0 & 0x000000f0) == 0x00000020)
254 : : cpu_arch = CPU_ARCH_ARMv6;
255 : : else
256 : : cpu_arch = CPU_ARCH_UNKNOWN;
257 : : } else
258 : : cpu_arch = CPU_ARCH_UNKNOWN;
259 : :
260 : 0 : return cpu_arch;
261 : : }
262 : : #endif
263 : :
264 : 0 : int __pure cpu_architecture(void)
265 : : {
266 [ - + ][ # # ]: 27290 : BUG_ON(__cpu_architecture == CPU_ARCH_UNKNOWN);
[ # # ][ # # ]
[ - + ]
267 : :
268 : 27244 : return __cpu_architecture;
269 : : }
270 : :
271 : 0 : static int cpu_has_aliasing_icache(unsigned int arch)
272 : : {
273 : : int aliasing_icache;
274 : : unsigned int id_reg, num_sets, line_size;
275 : :
276 : : #ifdef CONFIG_BIG_LITTLE
277 : : /*
278 : : * We expect a combination of Cortex-A15 and Cortex-A7 cores.
279 : : * A7 = VIPT aliasing I-cache
280 : : * A15 = PIPT (non-aliasing) I-cache
281 : : * To cater for this discrepancy, let's assume aliasing I-cache
282 : : * all the time. This means unneeded extra work on the A15 but
283 : : * only ptrace is affected which is not performance critical.
284 : : */
285 [ # # ]: 0 : if ((read_cpuid_id() & 0xff0ffff0) == 0x410fc0f0)
286 : : return 1;
287 : : #endif
288 : :
289 : : /* PIPT caches never alias. */
290 [ # # ]: 0 : if (icache_is_pipt())
291 : : return 0;
292 : :
293 : : /* arch specifies the register format */
294 [ # # # ]: 0 : switch (arch) {
295 : : case CPU_ARCH_ARMv7:
296 : 0 : asm("mcr p15, 2, %0, c0, c0, 0 @ set CSSELR"
297 : : : /* No output operands */
298 : : : "r" (1));
299 : 0 : isb();
300 : 0 : asm("mrc p15, 1, %0, c0, c0, 0 @ read CCSIDR"
301 : : : "=r" (id_reg));
302 : 0 : line_size = 4 << ((id_reg & 0x7) + 2);
303 : 0 : num_sets = ((id_reg >> 13) & 0x7fff) + 1;
304 : 0 : aliasing_icache = (line_size * num_sets) > PAGE_SIZE;
305 : 0 : break;
306 : : case CPU_ARCH_ARMv6:
307 : 0 : aliasing_icache = read_cpuid_cachetype() & (1 << 11);
308 : 0 : break;
309 : : default:
310 : : /* I-cache aliases will be handled by D-cache aliasing code */
311 : : aliasing_icache = 0;
312 : : }
313 : :
314 : 0 : return aliasing_icache;
315 : : }
316 : :
317 : 0 : static void __init cacheid_init(void)
318 : : {
319 : 0 : unsigned int arch = cpu_architecture();
320 : :
321 [ # # ]: 0 : if (arch == CPU_ARCH_ARMv7M) {
322 : 0 : cacheid = 0;
323 [ # # ]: 0 : } else if (arch >= CPU_ARCH_ARMv6) {
324 : : unsigned int cachetype = read_cpuid_cachetype();
325 [ # # ]: 0 : if ((cachetype & (7 << 29)) == 4 << 29) {
326 : : /* ARMv7 register format */
327 : : arch = CPU_ARCH_ARMv7;
328 : 0 : cacheid = CACHEID_VIPT_NONALIASING;
329 [ # # # ]: 0 : switch (cachetype & (3 << 14)) {
330 : : case (1 << 14):
331 : 0 : cacheid |= CACHEID_ASID_TAGGED;
332 : 0 : break;
333 : : case (3 << 14):
334 : 0 : cacheid |= CACHEID_PIPT;
335 : 0 : break;
336 : : }
337 : : } else {
338 : : arch = CPU_ARCH_ARMv6;
339 [ # # ]: 0 : if (cachetype & (1 << 23))
340 : 0 : cacheid = CACHEID_VIPT_ALIASING;
341 : : else
342 : 0 : cacheid = CACHEID_VIPT_NONALIASING;
343 : : }
344 [ # # ]: 0 : if (cpu_has_aliasing_icache(arch))
345 : 0 : cacheid |= CACHEID_VIPT_I_ALIASING;
346 : : } else {
347 : 0 : cacheid = CACHEID_VIVT;
348 : : }
349 : :
350 [ # # ][ # # ]: 0 : pr_info("CPU: %s data cache, %s instruction cache\n",
[ # # ][ # # ]
[ # # ]
351 : : cache_is_vivt() ? "VIVT" :
352 : : cache_is_vipt_aliasing() ? "VIPT aliasing" :
353 : : cache_is_vipt_nonaliasing() ? "PIPT / VIPT nonaliasing" : "unknown",
354 : : cache_is_vivt() ? "VIVT" :
355 : : icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
356 : : icache_is_vipt_aliasing() ? "VIPT aliasing" :
357 : : icache_is_pipt() ? "PIPT" :
358 : : cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
359 : 0 : }
360 : :
361 : : /*
362 : : * These functions re-use the assembly code in head.S, which
363 : : * already provide the required functionality.
364 : : */
365 : : extern struct proc_info_list *lookup_processor_type(unsigned int);
366 : :
367 : 0 : void __init early_print(const char *str, ...)
368 : : {
369 : : extern void printascii(const char *);
370 : : char buf[256];
371 : : va_list ap;
372 : :
373 : 0 : va_start(ap, str);
374 : 0 : vsnprintf(buf, sizeof(buf), str, ap);
375 : 0 : va_end(ap);
376 : :
377 : : #ifdef CONFIG_DEBUG_LL
378 : : printascii(buf);
379 : : #endif
380 : 0 : printk("%s", buf);
381 : 0 : }
382 : :
383 : 0 : static void __init cpuid_init_hwcaps(void)
384 : : {
385 : : unsigned int divide_instrs, vmsa;
386 : :
387 [ # # ]: 0 : if (cpu_architecture() < CPU_ARCH_ARMv7)
388 : 0 : return;
389 : :
390 : 0 : divide_instrs = (read_cpuid_ext(CPUID_EXT_ISAR0) & 0x0f000000) >> 24;
391 : :
392 [ # # # ]: 0 : switch (divide_instrs) {
393 : : case 2:
394 : 0 : elf_hwcap |= HWCAP_IDIVA;
395 : : case 1:
396 : 0 : elf_hwcap |= HWCAP_IDIVT;
397 : : }
398 : :
399 : : /* LPAE implies atomic ldrd/strd instructions */
400 : 0 : vmsa = (read_cpuid_ext(CPUID_EXT_MMFR0) & 0xf) >> 0;
401 [ # # ]: 0 : if (vmsa >= 5)
402 : 0 : elf_hwcap |= HWCAP_LPAE;
403 : : }
404 : :
405 : 0 : static void __init feat_v6_fixup(void)
406 : : {
407 : 0 : int id = read_cpuid_id();
408 : :
409 [ # # ]: 0 : if ((id & 0xff0f0000) != 0x41070000)
410 : 0 : return;
411 : :
412 : : /*
413 : : * HWCAP_TLS is available only on 1136 r1p0 and later,
414 : : * see also kuser_get_tls_init.
415 : : */
416 [ # # ][ # # ]: 0 : if ((((id >> 4) & 0xfff) == 0xb36) && (((id >> 20) & 3) == 0))
417 : 0 : elf_hwcap &= ~HWCAP_TLS;
418 : : }
419 : :
420 : : /*
421 : : * cpu_init - initialise one CPU.
422 : : *
423 : : * cpu_init sets up the per-CPU stacks.
424 : : */
425 : 0 : void notrace cpu_init(void)
426 : : {
427 : : #ifndef CONFIG_CPU_V7M
428 : 4292899 : unsigned int cpu = smp_processor_id();
429 : 4292899 : struct stack *stk = &stacks[cpu];
430 : :
431 [ - + ]: 4292899 : if (cpu >= NR_CPUS) {
432 : 0 : pr_crit("CPU%u: bad primary CPU number\n", cpu);
433 : 0 : BUG();
434 : : }
435 : :
436 : : /*
437 : : * This only works on resume and secondary cores. For booting on the
438 : : * boot cpu, smp_prepare_boot_cpu is called after percpu area setup.
439 : : */
440 : 4292899 : set_my_cpu_offset(per_cpu_offset(cpu));
441 : :
442 : 4704700 : cpu_proc_init();
443 : :
444 : : /*
445 : : * Define the placement constraint for the inline asm directive below.
446 : : * In Thumb-2, msr with an immediate value is not allowed.
447 : : */
448 : : #ifdef CONFIG_THUMB2_KERNEL
449 : : #define PLC "r"
450 : : #else
451 : : #define PLC "I"
452 : : #endif
453 : :
454 : : /*
455 : : * setup stacks for re-entrant exception handlers
456 : : */
457 : 4517922 : __asm__ (
458 : : "msr cpsr_c, %1\n\t"
459 : : "add r14, %0, %2\n\t"
460 : : "mov sp, r14\n\t"
461 : : "msr cpsr_c, %3\n\t"
462 : : "add r14, %0, %4\n\t"
463 : : "mov sp, r14\n\t"
464 : : "msr cpsr_c, %5\n\t"
465 : : "add r14, %0, %6\n\t"
466 : : "mov sp, r14\n\t"
467 : : "msr cpsr_c, %7"
468 : : :
469 : : : "r" (stk),
470 : : PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
471 : : "I" (offsetof(struct stack, irq[0])),
472 : : PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
473 : : "I" (offsetof(struct stack, abt[0])),
474 : : PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE),
475 : : "I" (offsetof(struct stack, und[0])),
476 : : PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
477 : : : "r14");
478 : : #endif
479 : 4737370 : }
480 : :
481 : : u32 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = MPIDR_INVALID };
482 : :
483 : 0 : void __init smp_setup_processor_id(void)
484 : : {
485 : : int i;
486 [ # # ]: 0 : u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;
487 : 0 : u32 cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
488 : :
489 : 0 : cpu_logical_map(0) = cpu;
490 [ # # ]: 0 : for (i = 1; i < nr_cpu_ids; ++i)
491 [ # # ]: 0 : cpu_logical_map(i) = i == cpu ? 0 : i;
492 : :
493 : : /*
494 : : * clear __my_cpu_offset on boot CPU to avoid hang caused by
495 : : * using percpu variable early, for example, lockdep will
496 : : * access percpu variable inside lock_release
497 : : */
498 : : set_my_cpu_offset(0);
499 : :
500 : 0 : pr_info("Booting Linux on physical CPU 0x%x\n", mpidr);
501 : 0 : }
502 : :
503 : : struct mpidr_hash mpidr_hash;
504 : : #ifdef CONFIG_SMP
505 : : /**
506 : : * smp_build_mpidr_hash - Pre-compute shifts required at each affinity
507 : : * level in order to build a linear index from an
508 : : * MPIDR value. Resulting algorithm is a collision
509 : : * free hash carried out through shifting and ORing
510 : : */
511 : 0 : static void __init smp_build_mpidr_hash(void)
512 : : {
513 : : u32 i, affinity;
514 : : u32 fs[3], bits[3], ls, mask = 0;
515 : : /*
516 : : * Pre-scan the list of MPIDRS and filter out bits that do
517 : : * not contribute to affinity levels, ie they never toggle.
518 : : */
519 [ # # ]: 0 : for_each_possible_cpu(i)
520 : 0 : mask |= (cpu_logical_map(i) ^ cpu_logical_map(0));
521 : : pr_debug("mask of set bits 0x%x\n", mask);
522 : : /*
523 : : * Find and stash the last and first bit set at all affinity levels to
524 : : * check how many bits are required to represent them.
525 : : */
526 [ # # ]: 0 : for (i = 0; i < 3; i++) {
527 : 0 : affinity = MPIDR_AFFINITY_LEVEL(mask, i);
528 : : /*
529 : : * Find the MSB bit and LSB bits position
530 : : * to determine how many bits are required
531 : : * to express the affinity level.
532 : : */
533 : 0 : ls = fls(affinity);
534 [ # # ]: 0 : fs[i] = affinity ? ffs(affinity) - 1 : 0;
535 : 0 : bits[i] = ls - fs[i];
536 : : }
537 : : /*
538 : : * An index can be created from the MPIDR by isolating the
539 : : * significant bits at each affinity level and by shifting
540 : : * them in order to compress the 24 bits values space to a
541 : : * compressed set of values. This is equivalent to hashing
542 : : * the MPIDR through shifting and ORing. It is a collision free
543 : : * hash though not minimal since some levels might contain a number
544 : : * of CPUs that is not an exact power of 2 and their bit
545 : : * representation might contain holes, eg MPIDR[7:0] = {0x2, 0x80}.
546 : : */
547 : 0 : mpidr_hash.shift_aff[0] = fs[0];
548 : 0 : mpidr_hash.shift_aff[1] = MPIDR_LEVEL_BITS + fs[1] - bits[0];
549 : 0 : mpidr_hash.shift_aff[2] = 2*MPIDR_LEVEL_BITS + fs[2] -
550 : 0 : (bits[1] + bits[0]);
551 : 0 : mpidr_hash.mask = mask;
552 : 0 : mpidr_hash.bits = bits[2] + bits[1] + bits[0];
553 : : pr_debug("MPIDR hash: aff0[%u] aff1[%u] aff2[%u] mask[0x%x] bits[%u]\n",
554 : : mpidr_hash.shift_aff[0],
555 : : mpidr_hash.shift_aff[1],
556 : : mpidr_hash.shift_aff[2],
557 : : mpidr_hash.mask,
558 : : mpidr_hash.bits);
559 : : /*
560 : : * 4x is an arbitrary value used to warn on a hash table much bigger
561 : : * than expected on most systems.
562 : : */
563 [ # # ]: 0 : if (mpidr_hash_size() > 4 * num_possible_cpus())
564 : 0 : pr_warn("Large number of MPIDR hash buckets detected\n");
565 : : sync_cache_w(&mpidr_hash);
566 : 0 : }
567 : : #endif
568 : :
569 : 0 : static void __init setup_processor(void)
570 : : {
571 : : struct proc_info_list *list;
572 : :
573 : : /*
574 : : * locate processor in the list of supported processor
575 : : * types. The linker builds this table for us from the
576 : : * entries in arch/arm/mm/proc-*.S
577 : : */
578 : 0 : list = lookup_processor_type(read_cpuid_id());
579 [ # # ]: 0 : if (!list) {
580 : 0 : pr_err("CPU configuration botched (ID %08x), unable to continue.\n",
581 : : read_cpuid_id());
582 : : while (1);
583 : : }
584 : :
585 : 0 : cpu_name = list->cpu_name;
586 : 0 : __cpu_architecture = __get_cpu_architecture();
587 : :
588 : : #ifdef MULTI_CPU
589 : : processor = *list->proc;
590 : : #endif
591 : : #ifdef MULTI_TLB
592 : 0 : cpu_tlb = *list->tlb;
593 : : #endif
594 : : #ifdef MULTI_USER
595 : 0 : cpu_user = *list->user;
596 : : #endif
597 : : #ifdef MULTI_CACHE
598 : : cpu_cache = *list->cache;
599 : : #endif
600 : :
601 : 0 : pr_info("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n",
602 : : cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
603 : : proc_arch[cpu_architecture()], cr_alignment);
604 : :
605 : 0 : snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c",
606 : 0 : list->arch_name, ENDIANNESS);
607 : 0 : snprintf(elf_platform, ELF_PLATFORM_SIZE, "%s%c",
608 : 0 : list->elf_name, ENDIANNESS);
609 : 0 : elf_hwcap = list->elf_hwcap;
610 : :
611 : 0 : cpuid_init_hwcaps();
612 : :
613 : : #ifndef CONFIG_ARM_THUMB
614 : : elf_hwcap &= ~(HWCAP_THUMB | HWCAP_IDIVT);
615 : : #endif
616 : :
617 : : erratum_a15_798181_init();
618 : :
619 : 0 : feat_v6_fixup();
620 : :
621 : 0 : cacheid_init();
622 : 0 : cpu_init();
623 : 0 : }
624 : :
625 : 0 : void __init dump_machine_table(void)
626 : : {
627 : : const struct machine_desc *p;
628 : :
629 : 0 : early_print("Available machine support:\n\nID (hex)\tNAME\n");
630 [ # # ]: 0 : for_each_machine_desc(p)
631 : 0 : early_print("%08x\t%s\n", p->nr, p->name);
632 : :
633 : 0 : early_print("\nPlease check your kernel config and/or bootloader.\n");
634 : :
635 : : while (true)
636 : 0 : /* can't use cpu_relax() here as it may require MMU setup */;
637 : : }
638 : :
639 : 0 : int __init arm_add_memory(u64 start, u64 size)
640 : : {
641 : 0 : struct membank *bank = &meminfo.bank[meminfo.nr_banks];
642 : : u64 aligned_start;
643 : :
644 [ # # ]: 0 : if (meminfo.nr_banks >= NR_BANKS) {
645 : 0 : pr_crit("NR_BANKS too low, ignoring memory at 0x%08llx\n",
646 : : (long long)start);
647 : 0 : return -EINVAL;
648 : : }
649 : :
650 : : /*
651 : : * Ensure that start/size are aligned to a page boundary.
652 : : * Size is appropriately rounded down, start is rounded up.
653 : : */
654 : 0 : size -= start & ~PAGE_MASK;
655 : 0 : aligned_start = PAGE_ALIGN(start);
656 : :
657 : : #ifndef CONFIG_ARCH_PHYS_ADDR_T_64BIT
658 [ # # ]: 0 : if (aligned_start > ULONG_MAX) {
659 : 0 : pr_crit("Ignoring memory at 0x%08llx outside 32-bit physical address space\n",
660 : : (long long)start);
661 : 0 : return -EINVAL;
662 : : }
663 : :
664 [ # # ]: 0 : if (aligned_start + size > ULONG_MAX) {
665 : 0 : pr_crit("Truncating memory at 0x%08llx to fit in 32-bit physical address space\n",
666 : : (long long)start);
667 : : /*
668 : : * To ensure bank->start + bank->size is representable in
669 : : * 32 bits, we use ULONG_MAX as the upper limit rather than 4GB.
670 : : * This means we lose a page after masking.
671 : : */
672 : 0 : size = ULONG_MAX - aligned_start;
673 : : }
674 : : #endif
675 : :
676 [ # # ]: 0 : if (aligned_start < PHYS_OFFSET) {
677 [ # # ]: 0 : if (aligned_start + size <= PHYS_OFFSET) {
678 : 0 : pr_info("Ignoring memory below PHYS_OFFSET: 0x%08llx-0x%08llx\n",
679 : : aligned_start, aligned_start + size);
680 : 0 : return -EINVAL;
681 : : }
682 : :
683 : 0 : pr_info("Ignoring memory below PHYS_OFFSET: 0x%08llx-0x%08llx\n",
684 : : aligned_start, (u64)PHYS_OFFSET);
685 : :
686 : 0 : size -= PHYS_OFFSET - aligned_start;
687 : : aligned_start = PHYS_OFFSET;
688 : : }
689 : :
690 : 0 : bank->start = aligned_start;
691 : 0 : bank->size = size & ~(phys_addr_t)(PAGE_SIZE - 1);
692 : :
693 : : /*
694 : : * Check whether this memory region has non-zero size or
695 : : * invalid node number.
696 : : */
697 [ # # ]: 0 : if (bank->size == 0)
698 : : return -EINVAL;
699 : :
700 : 0 : meminfo.nr_banks++;
701 : 0 : return 0;
702 : : }
703 : :
704 : : /*
705 : : * Pick out the memory size. We look for mem=size@start,
706 : : * where start and size are "size[KkMm]"
707 : : */
708 : 0 : static int __init early_mem(char *p)
709 : : {
710 : : static int usermem __initdata = 0;
711 : : u64 size;
712 : : u64 start;
713 : : char *endp;
714 : :
715 : : /*
716 : : * If the user specifies memory size, we
717 : : * blow away any automatically generated
718 : : * size.
719 : : */
720 [ # # ]: 0 : if (usermem == 0) {
721 : 0 : usermem = 1;
722 : 0 : meminfo.nr_banks = 0;
723 : : }
724 : :
725 : 0 : start = PHYS_OFFSET;
726 : 0 : size = memparse(p, &endp);
727 [ # # ]: 0 : if (*endp == '@')
728 : 0 : start = memparse(endp + 1, NULL);
729 : :
730 : 0 : arm_add_memory(start, size);
731 : :
732 : 0 : return 0;
733 : : }
734 : : early_param("mem", early_mem);
735 : :
736 : 0 : static void __init request_standard_resources(const struct machine_desc *mdesc)
737 : : {
738 : 0 : struct memblock_region *region;
739 : : struct resource *res;
740 : :
741 : 0 : kernel_code.start = virt_to_phys(_text);
742 : 0 : kernel_code.end = virt_to_phys(_etext - 1);
743 : 0 : kernel_data.start = virt_to_phys(_sdata);
744 : 0 : kernel_data.end = virt_to_phys(_end - 1);
745 : :
746 [ # # ]: 0 : for_each_memblock(memory, region) {
747 : : res = memblock_virt_alloc(sizeof(*res), 0);
748 : 0 : res->name = "System RAM";
749 : 0 : res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
750 : 0 : res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
751 : 0 : res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
752 : :
753 : 0 : request_resource(&iomem_resource, res);
754 : :
755 [ # # ][ # # ]: 0 : if (kernel_code.start >= res->start &&
756 : 0 : kernel_code.end <= res->end)
757 : 0 : request_resource(res, &kernel_code);
758 [ # # ][ # # ]: 0 : if (kernel_data.start >= res->start &&
759 : 0 : kernel_data.end <= res->end)
760 : 0 : request_resource(res, &kernel_data);
761 : : }
762 : :
763 [ # # ]: 0 : if (mdesc->video_start) {
764 : 0 : video_ram.start = mdesc->video_start;
765 : 0 : video_ram.end = mdesc->video_end;
766 : 0 : request_resource(&iomem_resource, &video_ram);
767 : : }
768 : :
769 : : /*
770 : : * Some machines don't have the possibility of ever
771 : : * possessing lp0, lp1 or lp2
772 : : */
773 [ # # ]: 0 : if (mdesc->reserve_lp0)
774 : 0 : request_resource(&ioport_resource, &lp0);
775 [ # # ]: 0 : if (mdesc->reserve_lp1)
776 : 0 : request_resource(&ioport_resource, &lp1);
777 [ # # ]: 0 : if (mdesc->reserve_lp2)
778 : 0 : request_resource(&ioport_resource, &lp2);
779 : 0 : }
780 : :
781 : : #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
782 : : struct screen_info screen_info = {
783 : : .orig_video_lines = 30,
784 : : .orig_video_cols = 80,
785 : : .orig_video_mode = 0,
786 : : .orig_video_ega_bx = 0,
787 : : .orig_video_isVGA = 1,
788 : : .orig_video_points = 8
789 : : };
790 : : #endif
791 : :
792 : 0 : static int __init customize_machine(void)
793 : : {
794 : : /*
795 : : * customizes platform devices, or adds new ones
796 : : * On DT based machines, we fall back to populating the
797 : : * machine from the device tree, if no callback is provided,
798 : : * otherwise we would always need an init_machine callback.
799 : : */
800 [ # # ]: 0 : if (machine_desc->init_machine)
801 : 0 : machine_desc->init_machine();
802 : : #ifdef CONFIG_OF
803 : : else
804 : 0 : of_platform_populate(NULL, of_default_bus_match_table,
805 : : NULL, NULL);
806 : : #endif
807 : 0 : return 0;
808 : : }
809 : : arch_initcall(customize_machine);
810 : :
811 : 0 : static int __init init_machine_late(void)
812 : : {
813 [ # # ]: 0 : if (machine_desc->init_late)
814 : 0 : machine_desc->init_late();
815 : 0 : return 0;
816 : : }
817 : : late_initcall(init_machine_late);
818 : :
819 : : #ifdef CONFIG_KEXEC
820 : : static inline unsigned long long get_total_mem(void)
821 : : {
822 : : unsigned long total;
823 : :
824 : : total = max_low_pfn - min_low_pfn;
825 : : return total << PAGE_SHIFT;
826 : : }
827 : :
828 : : /**
829 : : * reserve_crashkernel() - reserves memory are for crash kernel
830 : : *
831 : : * This function reserves memory area given in "crashkernel=" kernel command
832 : : * line parameter. The memory reserved is used by a dump capture kernel when
833 : : * primary kernel is crashing.
834 : : */
835 : : static void __init reserve_crashkernel(void)
836 : : {
837 : : unsigned long long crash_size, crash_base;
838 : : unsigned long long total_mem;
839 : : int ret;
840 : :
841 : : total_mem = get_total_mem();
842 : : ret = parse_crashkernel(boot_command_line, total_mem,
843 : : &crash_size, &crash_base);
844 : : if (ret)
845 : : return;
846 : :
847 : : ret = memblock_reserve(crash_base, crash_size);
848 : : if (ret < 0) {
849 : : pr_warn("crashkernel reservation failed - memory is in use (0x%lx)\n",
850 : : (unsigned long)crash_base);
851 : : return;
852 : : }
853 : :
854 : : pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
855 : : (unsigned long)(crash_size >> 20),
856 : : (unsigned long)(crash_base >> 20),
857 : : (unsigned long)(total_mem >> 20));
858 : :
859 : : crashk_res.start = crash_base;
860 : : crashk_res.end = crash_base + crash_size - 1;
861 : : insert_resource(&iomem_resource, &crashk_res);
862 : : }
863 : : #else
864 : : static inline void reserve_crashkernel(void) {}
865 : : #endif /* CONFIG_KEXEC */
866 : :
867 : 0 : static int __init meminfo_cmp(const void *_a, const void *_b)
868 : : {
869 : : const struct membank *a = _a, *b = _b;
870 : 0 : long cmp = bank_pfn_start(a) - bank_pfn_start(b);
871 [ # # ]: 0 : return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
872 : : }
873 : :
874 : 0 : void __init hyp_mode_check(void)
875 : : {
876 : : #ifdef CONFIG_ARM_VIRT_EXT
877 : : sync_boot_mode();
878 : :
879 [ # # ]: 0 : if (is_hyp_mode_available()) {
880 : 0 : pr_info("CPU: All CPU(s) started in HYP mode.\n");
881 : 0 : pr_info("CPU: Virtualization extensions available.\n");
882 [ # # ]: 0 : } else if (is_hyp_mode_mismatched()) {
883 : 0 : pr_warn("CPU: WARNING: CPU(s) started in wrong/inconsistent modes (primary CPU mode 0x%x)\n",
884 : : __boot_cpu_mode & MODE_MASK);
885 : 0 : pr_warn("CPU: This may indicate a broken bootloader or firmware.\n");
886 : : } else
887 : 0 : pr_info("CPU: All CPU(s) started in SVC mode.\n");
888 : : #endif
889 : 0 : }
890 : :
891 : 0 : void __init setup_arch(char **cmdline_p)
892 : : {
893 : : const struct machine_desc *mdesc;
894 : :
895 : 0 : setup_processor();
896 : 0 : mdesc = setup_machine_fdt(__atags_pointer);
897 [ # # ]: 0 : if (!mdesc)
898 : 0 : mdesc = setup_machine_tags(__atags_pointer, __machine_arch_type);
899 : 0 : machine_desc = mdesc;
900 : 0 : machine_name = mdesc->name;
901 : :
902 [ # # ]: 0 : if (mdesc->reboot_mode != REBOOT_HARD)
903 : 0 : reboot_mode = mdesc->reboot_mode;
904 : :
905 : 0 : init_mm.start_code = (unsigned long) _text;
906 : 0 : init_mm.end_code = (unsigned long) _etext;
907 : 0 : init_mm.end_data = (unsigned long) _edata;
908 : 0 : init_mm.brk = (unsigned long) _end;
909 : :
910 : : /* populate cmd_line too for later use, preserving boot_command_line */
911 : 0 : strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
912 : 0 : *cmdline_p = cmd_line;
913 : :
914 : 0 : parse_early_param();
915 : :
916 : 0 : sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
917 : :
918 : 0 : early_paging_init(mdesc, lookup_processor_type(read_cpuid_id()));
919 : 0 : setup_dma_zone(mdesc);
920 : 0 : sanity_check_meminfo();
921 : 0 : arm_memblock_init(&meminfo, mdesc);
922 : :
923 : 0 : paging_init(mdesc);
924 : 0 : request_standard_resources(mdesc);
925 : :
926 [ # # ]: 0 : if (mdesc->restart)
927 : 0 : arm_pm_restart = mdesc->restart;
928 : :
929 : 0 : unflatten_device_tree();
930 : :
931 : 0 : arm_dt_init_cpu_maps();
932 : 0 : psci_init();
933 : : #ifdef CONFIG_SMP
934 [ # # ]: 0 : if (is_smp()) {
935 [ # # ][ # # ]: 0 : if (!mdesc->smp_init || !mdesc->smp_init()) {
936 [ # # ]: 0 : if (psci_smp_available())
937 : 0 : smp_set_ops(&psci_smp_ops);
938 [ # # ]: 0 : else if (mdesc->smp)
939 : 0 : smp_set_ops(mdesc->smp);
940 : : }
941 : 0 : smp_init_cpus();
942 : 0 : smp_build_mpidr_hash();
943 : : }
944 : : #endif
945 : :
946 [ # # ]: 0 : if (!is_smp())
947 : 0 : hyp_mode_check();
948 : :
949 : : reserve_crashkernel();
950 : :
951 : : #ifdef CONFIG_MULTI_IRQ_HANDLER
952 : 0 : handle_arch_irq = mdesc->handle_irq;
953 : : #endif
954 : :
955 : : #ifdef CONFIG_VT
956 : : #if defined(CONFIG_VGA_CONSOLE)
957 : : conswitchp = &vga_con;
958 : : #elif defined(CONFIG_DUMMY_CONSOLE)
959 : 0 : conswitchp = &dummy_con;
960 : : #endif
961 : : #endif
962 : :
963 [ # # ]: 0 : if (mdesc->init_early)
964 : 0 : mdesc->init_early();
965 : 0 : }
966 : :
967 : :
968 : 0 : static int __init topology_init(void)
969 : : {
970 : : int cpu;
971 : :
972 [ # # ]: 0 : for_each_possible_cpu(cpu) {
973 : 0 : struct cpuinfo_arm *cpuinfo = &per_cpu(cpu_data, cpu);
974 : 0 : cpuinfo->cpu.hotpluggable = 1;
975 : 0 : register_cpu(&cpuinfo->cpu, cpu);
976 : : }
977 : :
978 : 0 : return 0;
979 : : }
980 : : subsys_initcall(topology_init);
981 : :
982 : : #ifdef CONFIG_HAVE_PROC_CPU
983 : 0 : static int __init proc_cpu_init(void)
984 : : {
985 : : struct proc_dir_entry *res;
986 : :
987 : 0 : res = proc_mkdir("cpu", NULL);
988 [ # # ]: 0 : if (!res)
989 : : return -ENOMEM;
990 : 0 : return 0;
991 : : }
992 : : fs_initcall(proc_cpu_init);
993 : : #endif
994 : :
995 : : static const char *hwcap_str[] = {
996 : : "swp",
997 : : "half",
998 : : "thumb",
999 : : "26bit",
1000 : : "fastmult",
1001 : : "fpa",
1002 : : "vfp",
1003 : : "edsp",
1004 : : "java",
1005 : : "iwmmxt",
1006 : : "crunch",
1007 : : "thumbee",
1008 : : "neon",
1009 : : "vfpv3",
1010 : : "vfpv3d16",
1011 : : "tls",
1012 : : "vfpv4",
1013 : : "idiva",
1014 : : "idivt",
1015 : : "vfpd32",
1016 : : "lpae",
1017 : : "evtstrm",
1018 : : NULL
1019 : : };
1020 : :
1021 : 0 : static int c_show(struct seq_file *m, void *v)
1022 : : {
1023 : : int i, j;
1024 : : u32 cpuid;
1025 : :
1026 [ + + ]: 66 : for_each_online_cpu(i) {
1027 : : /*
1028 : : * glibc reads /proc/cpuinfo to determine the number of
1029 : : * online processors, looking for lines beginning with
1030 : : * "processor". Give glibc what it expects.
1031 : : */
1032 : 46 : seq_printf(m, "processor\t: %d\n", i);
1033 [ + - ]: 46 : cpuid = is_smp() ? per_cpu(cpu_data, i).cpuid : read_cpuid_id();
1034 : 46 : seq_printf(m, "model name\t: %s rev %d (%s)\n",
1035 : : cpu_name, cpuid & 15, elf_platform);
1036 : :
1037 : : /* dump out the processor features */
1038 : 46 : seq_puts(m, "Features\t: ");
1039 : :
1040 [ + + ]: 1058 : for (j = 0; hwcap_str[j]; j++)
1041 [ + + ]: 1012 : if (elf_hwcap & (1 << j))
1042 : 690 : seq_printf(m, "%s ", hwcap_str[j]);
1043 : :
1044 : 46 : seq_printf(m, "\nCPU implementer\t: 0x%02x\n", cpuid >> 24);
1045 : 46 : seq_printf(m, "CPU architecture: %s\n",
1046 : : proc_arch[cpu_architecture()]);
1047 : :
1048 [ - + ]: 56 : if ((cpuid & 0x0008f000) == 0x00000000) {
1049 : : /* pre-ARM7 */
1050 : 0 : seq_printf(m, "CPU part\t: %07x\n", cpuid >> 4);
1051 : : } else {
1052 [ - + ]: 46 : if ((cpuid & 0x0008f000) == 0x00007000) {
1053 : : /* ARM7 */
1054 : 0 : seq_printf(m, "CPU variant\t: 0x%02x\n",
1055 : 0 : (cpuid >> 16) & 127);
1056 : : } else {
1057 : : /* post-ARM7 */
1058 : 46 : seq_printf(m, "CPU variant\t: 0x%x\n",
1059 : 46 : (cpuid >> 20) & 15);
1060 : : }
1061 : 46 : seq_printf(m, "CPU part\t: 0x%03x\n",
1062 : 46 : (cpuid >> 4) & 0xfff);
1063 : : }
1064 : 46 : seq_printf(m, "CPU revision\t: %d\n\n", cpuid & 15);
1065 : : }
1066 : :
1067 : 10 : seq_printf(m, "Hardware\t: %s\n", machine_name);
1068 : 10 : seq_printf(m, "Revision\t: %04x\n", system_rev);
1069 : 10 : seq_printf(m, "Serial\t\t: %08x%08x\n",
1070 : : system_serial_high, system_serial_low);
1071 : :
1072 : 10 : return 0;
1073 : : }
1074 : :
1075 : 0 : static void *c_start(struct seq_file *m, loff_t *pos)
1076 : : {
1077 [ + + ]: 21 : return *pos < 1 ? (void *)1 : NULL;
1078 : : }
1079 : :
1080 : 0 : static void *c_next(struct seq_file *m, void *v, loff_t *pos)
1081 : : {
1082 : 9 : ++*pos;
1083 : 9 : return NULL;
1084 : : }
1085 : :
1086 : 0 : static void c_stop(struct seq_file *m, void *v)
1087 : : {
1088 : 21 : }
1089 : :
1090 : : const struct seq_operations cpuinfo_op = {
1091 : : .start = c_start,
1092 : : .next = c_next,
1093 : : .stop = c_stop,
1094 : : .show = c_show
1095 : : };
|