Linux 3.10.69
[GitHub/mt8127/android_kernel_alcatel_ttab.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/export.h>
21 #include <linux/kernel.h>
22 #include <linux/stddef.h>
23 #include <linux/ioport.h>
24 #include <linux/delay.h>
25 #include <linux/utsname.h>
26 #include <linux/initrd.h>
27 #include <linux/console.h>
28 #include <linux/bootmem.h>
29 #include <linux/seq_file.h>
30 #include <linux/screen_info.h>
31 #include <linux/init.h>
32 #include <linux/kexec.h>
33 #include <linux/crash_dump.h>
34 #include <linux/root_dev.h>
35 #include <linux/clk-provider.h>
36 #include <linux/cpu.h>
37 #include <linux/interrupt.h>
38 #include <linux/smp.h>
39 #include <linux/fs.h>
40 #include <linux/proc_fs.h>
41 #include <linux/memblock.h>
42 #include <linux/of_fdt.h>
43 #include <linux/of_platform.h>
44 #include <linux/personality.h>
45
46 #include <asm/cputype.h>
47 #include <asm/elf.h>
48 #include <asm/cputable.h>
49 #include <asm/sections.h>
50 #include <asm/setup.h>
51 #include <asm/smp_plat.h>
52 #include <asm/cacheflush.h>
53 #include <asm/tlbflush.h>
54 #include <asm/traps.h>
55 #include <asm/memblock.h>
56 #include <asm/psci.h>
57
58 unsigned int processor_id;
59 EXPORT_SYMBOL(processor_id);
60
61 unsigned int elf_hwcap __read_mostly;
62 EXPORT_SYMBOL_GPL(elf_hwcap);
63
64 static const char *cpu_name;
65 static const char *machine_name;
66 phys_addr_t __fdt_pointer __initdata;
67
68 /*
69 * Standard memory resources
70 */
71 static struct resource mem_res[] = {
72 {
73 .name = "Kernel code",
74 .start = 0,
75 .end = 0,
76 .flags = IORESOURCE_MEM
77 },
78 {
79 .name = "Kernel data",
80 .start = 0,
81 .end = 0,
82 .flags = IORESOURCE_MEM
83 }
84 };
85
86 #define kernel_code mem_res[0]
87 #define kernel_data mem_res[1]
88
89 void __init early_print(const char *str, ...)
90 {
91 char buf[256];
92 va_list ap;
93
94 va_start(ap, str);
95 vsnprintf(buf, sizeof(buf), str, ap);
96 va_end(ap);
97
98 printk("%s", buf);
99 }
100
101 struct cpuinfo_arm64 {
102 struct cpu cpu;
103 u32 reg_midr;
104 };
105
106 static DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
107
108 void cpuinfo_store_cpu(void)
109 {
110 struct cpuinfo_arm64 *info = this_cpu_ptr(&cpu_data);
111 info->reg_midr = read_cpuid_id();
112 }
113
114 static void __init setup_processor(void)
115 {
116 struct cpu_info *cpu_info;
117
118 /*
119 * locate processor in the list of supported processor
120 * types. The linker builds this table for us from the
121 * entries in arch/arm/mm/proc.S
122 */
123 cpu_info = lookup_processor_type(read_cpuid_id());
124 if (!cpu_info) {
125 printk("CPU configuration botched (ID %08x), unable to continue.\n",
126 read_cpuid_id());
127 while (1);
128 }
129
130 cpu_name = cpu_info->cpu_name;
131
132 printk("CPU: %s [%08x] revision %d\n",
133 cpu_name, read_cpuid_id(), read_cpuid_id() & 15);
134
135 sprintf(init_utsname()->machine, "aarch64");
136 elf_hwcap = 0;
137 }
138
139 static void __init setup_machine_fdt(phys_addr_t dt_phys)
140 {
141 struct boot_param_header *devtree;
142 unsigned long dt_root;
143
144 cpuinfo_store_cpu();
145
146 /* Check we have a non-NULL DT pointer */
147 if (!dt_phys) {
148 early_print("\n"
149 "Error: NULL or invalid device tree blob\n"
150 "The dtb must be 8-byte aligned and passed in the first 512MB of memory\n"
151 "\nPlease check your bootloader.\n");
152
153 while (true)
154 cpu_relax();
155
156 }
157
158 devtree = phys_to_virt(dt_phys);
159
160 /* Check device tree validity */
161 if (be32_to_cpu(devtree->magic) != OF_DT_HEADER) {
162 early_print("\n"
163 "Error: invalid device tree blob at physical address 0x%p (virtual address 0x%p)\n"
164 "Expected 0x%x, found 0x%x\n"
165 "\nPlease check your bootloader.\n",
166 dt_phys, devtree, OF_DT_HEADER,
167 be32_to_cpu(devtree->magic));
168
169 while (true)
170 cpu_relax();
171 }
172
173 initial_boot_params = devtree;
174 dt_root = of_get_flat_dt_root();
175
176 machine_name = of_get_flat_dt_prop(dt_root, "model", NULL);
177 if (!machine_name)
178 machine_name = of_get_flat_dt_prop(dt_root, "compatible", NULL);
179 if (!machine_name)
180 machine_name = "<unknown>";
181 pr_info("Machine: %s\n", machine_name);
182
183 /* Retrieve various information from the /chosen node */
184 of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
185 /* Initialize {size,address}-cells info */
186 of_scan_flat_dt(early_init_dt_scan_root, NULL);
187 /* Setup memory, calling early_init_dt_add_memory_arch */
188 of_scan_flat_dt(early_init_dt_scan_memory, NULL);
189 }
190
191 void __init early_init_dt_add_memory_arch(u64 base, u64 size)
192 {
193 base &= PAGE_MASK;
194 size &= PAGE_MASK;
195 if (base + size < PHYS_OFFSET) {
196 pr_warning("Ignoring memory block 0x%llx - 0x%llx\n",
197 base, base + size);
198 return;
199 }
200 if (base < PHYS_OFFSET) {
201 pr_warning("Ignoring memory range 0x%llx - 0x%llx\n",
202 base, PHYS_OFFSET);
203 size -= PHYS_OFFSET - base;
204 base = PHYS_OFFSET;
205 }
206 memblock_add(base, size);
207 }
208
209 void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
210 {
211 return __va(memblock_alloc(size, align));
212 }
213
214 /*
215 * Limit the memory size that was specified via FDT.
216 */
217 static int __init early_mem(char *p)
218 {
219 phys_addr_t limit;
220
221 if (!p)
222 return 1;
223
224 limit = memparse(p, &p) & PAGE_MASK;
225 pr_notice("Memory limited to %lldMB\n", limit >> 20);
226
227 memblock_enforce_memory_limit(limit);
228
229 return 0;
230 }
231 early_param("mem", early_mem);
232
233 static void __init request_standard_resources(void)
234 {
235 struct memblock_region *region;
236 struct resource *res;
237
238 kernel_code.start = virt_to_phys(_text);
239 kernel_code.end = virt_to_phys(_etext - 1);
240 kernel_data.start = virt_to_phys(_sdata);
241 kernel_data.end = virt_to_phys(_end - 1);
242
243 for_each_memblock(memory, region) {
244 res = alloc_bootmem_low(sizeof(*res));
245 res->name = "System RAM";
246 res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
247 res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
248 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
249
250 request_resource(&iomem_resource, res);
251
252 if (kernel_code.start >= res->start &&
253 kernel_code.end <= res->end)
254 request_resource(res, &kernel_code);
255 if (kernel_data.start >= res->start &&
256 kernel_data.end <= res->end)
257 request_resource(res, &kernel_data);
258 }
259 }
260
261 u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID };
262
263 void __init setup_arch(char **cmdline_p)
264 {
265 setup_processor();
266
267 setup_machine_fdt(__fdt_pointer);
268
269 init_mm.start_code = (unsigned long) _text;
270 init_mm.end_code = (unsigned long) _etext;
271 init_mm.end_data = (unsigned long) _edata;
272 init_mm.brk = (unsigned long) _end;
273
274 *cmdline_p = boot_command_line;
275
276 parse_early_param();
277
278 arm64_memblock_init();
279
280 paging_init();
281 request_standard_resources();
282
283 unflatten_device_tree();
284
285 psci_init();
286
287 cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
288 #ifdef CONFIG_SMP
289 smp_init_cpus();
290 #endif
291
292 #ifdef CONFIG_VT
293 #if defined(CONFIG_VGA_CONSOLE)
294 conswitchp = &vga_con;
295 #elif defined(CONFIG_DUMMY_CONSOLE)
296 conswitchp = &dummy_con;
297 #endif
298 #endif
299 }
300
301 static int __init arm64_device_init(void)
302 {
303 of_clk_init(NULL);
304 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
305 return 0;
306 }
307 arch_initcall(arm64_device_init);
308
309 static int __init topology_init(void)
310 {
311 int i;
312
313 for_each_possible_cpu(i) {
314 struct cpu *cpu = &per_cpu(cpu_data.cpu, i);
315 cpu->hotpluggable = 1;
316 register_cpu(cpu, i);
317 }
318
319 return 0;
320 }
321 subsys_initcall(topology_init);
322
323 static const char *hwcap_str[] = {
324 "fp",
325 "asimd",
326 NULL
327 };
328
329 #ifdef CONFIG_COMPAT
330 static const char *compat_hwcap_str[] = {
331 "swp",
332 "half",
333 "thumb",
334 "26bit",
335 "fastmult",
336 "fpa",
337 "vfp",
338 "edsp",
339 "java",
340 "iwmmxt",
341 "crunch",
342 "thumbee",
343 "neon",
344 "vfpv3",
345 "vfpv3d16",
346 "tls",
347 "vfpv4",
348 "idiva",
349 "idivt",
350 "vfpd32",
351 "lpae",
352 "evtstrm"
353 };
354 #endif /* CONFIG_COMPAT */
355
356 static int c_show(struct seq_file *m, void *v)
357 {
358 int i, j;
359
360 for_each_online_cpu(i) {
361 struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
362 u32 midr = cpuinfo->reg_midr;
363
364 /*
365 * glibc reads /proc/cpuinfo to determine the number of
366 * online processors, looking for lines beginning with
367 * "processor". Give glibc what it expects.
368 */
369 #ifdef CONFIG_SMP
370 seq_printf(m, "processor\t: %d\n", i);
371 #endif
372 seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
373 loops_per_jiffy / (500000UL/HZ),
374 loops_per_jiffy / (5000UL/HZ) % 100);
375
376 /*
377 * Dump out the common processor features in a single line.
378 * Userspace should read the hwcaps with getauxval(AT_HWCAP)
379 * rather than attempting to parse this, but there's a body of
380 * software which does already (at least for 32-bit).
381 */
382 seq_puts(m, "Features\t:");
383 if (personality(current->personality) == PER_LINUX32) {
384 #ifdef CONFIG_COMPAT
385 for (j = 0; compat_hwcap_str[j]; j++)
386 if (COMPAT_ELF_HWCAP & (1 << j))
387 seq_printf(m, " %s", compat_hwcap_str[j]);
388 #endif /* CONFIG_COMPAT */
389 } else {
390 for (j = 0; hwcap_str[j]; j++)
391 if (elf_hwcap & (1 << j))
392 seq_printf(m, " %s", hwcap_str[j]);
393 }
394 seq_puts(m, "\n");
395
396 seq_printf(m, "CPU implementer\t: 0x%02x\n", (midr >> 24));
397 seq_printf(m, "CPU architecture: 8\n");
398 seq_printf(m, "CPU variant\t: 0x%x\n", ((midr >> 20) & 0xf));
399 seq_printf(m, "CPU part\t: 0x%03x\n", ((midr >> 4) & 0xfff));
400 seq_printf(m, "CPU revision\t: %d\n\n", (midr & 0xf));
401 }
402
403 return 0;
404 }
405
406 static void *c_start(struct seq_file *m, loff_t *pos)
407 {
408 return *pos < 1 ? (void *)1 : NULL;
409 }
410
411 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
412 {
413 ++*pos;
414 return NULL;
415 }
416
417 static void c_stop(struct seq_file *m, void *v)
418 {
419 }
420
421 const struct seq_operations cpuinfo_op = {
422 .start = c_start,
423 .next = c_next,
424 .stop = c_stop,
425 .show = c_show
426 };