]> xenbits.xensource.com Git - xen.git/blob
c1f2d1b89d43
[xen.git] /
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * xen/arch/arm/setup.c
4  *
5  * Early bringup code for an ARMv7-A with virt extensions.
6  *
7  * Tim Deegan <tim@xen.org>
8  * Copyright (c) 2011 Citrix Systems.
9  */
10
11 #include <xen/compile.h>
12 #include <xen/device_tree.h>
13 #include <xen/domain_page.h>
14 #include <xen/grant_table.h>
15 #include <xen/llc-coloring.h>
16 #include <xen/types.h>
17 #include <xen/string.h>
18 #include <xen/serial.h>
19 #include <xen/sched.h>
20 #include <xen/console.h>
21 #include <xen/err.h>
22 #include <xen/init.h>
23 #include <xen/irq.h>
24 #include <xen/mm.h>
25 #include <xen/param.h>
26 #include <xen/softirq.h>
27 #include <xen/keyhandler.h>
28 #include <xen/cpu.h>
29 #include <xen/pfn.h>
30 #include <xen/virtual_region.h>
31 #include <xen/version.h>
32 #include <xen/vmap.h>
33 #include <xen/trace.h>
34 #include <xen/libfdt/libfdt-xen.h>
35 #include <xen/acpi.h>
36 #include <xen/warning.h>
37 #include <xen/hypercall.h>
38 #include <asm/alternative.h>
39 #include <asm/dom0less-build.h>
40 #include <asm/page.h>
41 #include <asm/static-evtchn.h>
42 #include <asm/current.h>
43 #include <asm/setup.h>
44 #include <asm/gic.h>
45 #include <asm/cpuerrata.h>
46 #include <asm/cpufeature.h>
47 #include <asm/platform.h>
48 #include <asm/procinfo.h>
49 #include <asm/setup.h>
50 #include <xsm/xsm.h>
51 #include <asm/acpi.h>
52
53 /*
54  * Sanitized version of cpuinfo containing only features available on all
55  * cores (only on arm64 as there is no sanitization support on arm32).
56  */
57 struct cpuinfo_arm __read_mostly system_cpuinfo;
58
59 #ifdef CONFIG_ACPI
60 bool __read_mostly acpi_disabled;
61 #endif
62
63 domid_t __read_mostly max_init_domid;
64
65 static __used void init_done(void)
66 {
67     int rc;
68
69     /* Must be done past setting system_state. */
70     unregister_init_virtual_region();
71
72     free_init_memory();
73
74     /*
75      * We have finished booting. Mark the section .data.ro_after_init
76      * read-only.
77      */
78     rc = modify_xen_mappings((unsigned long)&__ro_after_init_start,
79                              (unsigned long)&__ro_after_init_end,
80                              PAGE_HYPERVISOR_RO);
81     if ( rc )
82         panic("Unable to mark the .data.ro_after_init section read-only (rc = %d)\n",
83               rc);
84
85     startup_cpu_idle_loop();
86 }
87
88 static void __init init_idle_domain(void)
89 {
90     scheduler_init();
91     set_current(idle_vcpu[0]);
92     /* TODO: setup_idle_pagetable(); */
93 }
94
95 static const char * __initdata processor_implementers[] = {
96     ['A'] = "ARM Limited",
97     ['B'] = "Broadcom Corporation",
98     ['C'] = "Cavium Inc.",
99     ['D'] = "Digital Equipment Corp",
100     ['M'] = "Motorola, Freescale Semiconductor Inc.",
101     ['P'] = "Applied Micro",
102     ['Q'] = "Qualcomm Inc.",
103     ['V'] = "Marvell Semiconductor Inc.",
104     ['i'] = "Intel Corporation",
105 };
106
107 static void __init processor_id(void)
108 {
109     const char *implementer = "Unknown";
110     struct cpuinfo_arm *c = &system_cpuinfo;
111
112     identify_cpu(c);
113     current_cpu_data = *c;
114
115     if ( c->midr.implementer < ARRAY_SIZE(processor_implementers) &&
116          processor_implementers[c->midr.implementer] )
117         implementer = processor_implementers[c->midr.implementer];
118
119     if ( c->midr.architecture != 0xf )
120         printk("Huh, cpu architecture %x, expected 0xf (defined by cpuid)\n",
121                c->midr.architecture);
122
123     printk("Processor: %"PRIregister": \"%s\", variant: 0x%x, part 0x%03x,"
124            "rev 0x%x\n", c->midr.bits, implementer,
125            c->midr.variant, c->midr.part_number, c->midr.revision);
126
127 #if defined(CONFIG_ARM_64)
128     printk("64-bit Execution:\n");
129     printk("  Processor Features: %016"PRIx64" %016"PRIx64"\n",
130            system_cpuinfo.pfr64.bits[0], system_cpuinfo.pfr64.bits[1]);
131     printk("    Exception Levels: EL3:%s EL2:%s EL1:%s EL0:%s\n",
132            cpu_has_el3_32 ? "64+32" : cpu_has_el3_64 ? "64" : "No",
133            cpu_has_el2_32 ? "64+32" : cpu_has_el2_64 ? "64" : "No",
134            cpu_has_el1_32 ? "64+32" : cpu_has_el1_64 ? "64" : "No",
135            cpu_has_el0_32 ? "64+32" : cpu_has_el0_64 ? "64" : "No");
136     printk("    Extensions:%s%s%s%s\n",
137            cpu_has_fp ? " FloatingPoint" : "",
138            cpu_has_simd ? " AdvancedSIMD" : "",
139            cpu_has_gicv3 ? " GICv3-SysReg" : "",
140            cpu_has_sve ? " SVE" : "");
141
142     /* Warn user if we find unknown floating-point features */
143     if ( cpu_has_fp && (boot_cpu_feature64(fp) >= 2) )
144         printk(XENLOG_WARNING "WARNING: Unknown Floating-point ID:%d, "
145                "this may result in corruption on the platform\n",
146                boot_cpu_feature64(fp));
147
148     /* Warn user if we find unknown AdvancedSIMD features */
149     if ( cpu_has_simd && (boot_cpu_feature64(simd) >= 2) )
150         printk(XENLOG_WARNING "WARNING: Unknown AdvancedSIMD ID:%d, "
151                "this may result in corruption on the platform\n",
152                boot_cpu_feature64(simd));
153
154     printk("  Debug Features: %016"PRIx64" %016"PRIx64"\n",
155            system_cpuinfo.dbg64.bits[0], system_cpuinfo.dbg64.bits[1]);
156     printk("  Auxiliary Features: %016"PRIx64" %016"PRIx64"\n",
157            system_cpuinfo.aux64.bits[0], system_cpuinfo.aux64.bits[1]);
158     printk("  Memory Model Features: %016"PRIx64" %016"PRIx64"\n",
159            system_cpuinfo.mm64.bits[0], system_cpuinfo.mm64.bits[1]);
160     printk("  ISA Features:  %016"PRIx64" %016"PRIx64"\n",
161            system_cpuinfo.isa64.bits[0], system_cpuinfo.isa64.bits[1]);
162 #endif
163
164     /*
165      * On AArch64 these refer to the capabilities when running in
166      * AArch32 mode.
167      */
168     if ( cpu_has_aarch32 )
169     {
170         printk("32-bit Execution:\n");
171         printk("  Processor Features: %"PRIregister":%"PRIregister"\n",
172                system_cpuinfo.pfr32.bits[0], system_cpuinfo.pfr32.bits[1]);
173         printk("    Instruction Sets:%s%s%s%s%s%s\n",
174                cpu_has_aarch32 ? " AArch32" : "",
175                cpu_has_arm ? " A32" : "",
176                cpu_has_thumb ? " Thumb" : "",
177                cpu_has_thumb2 ? " Thumb-2" : "",
178                cpu_has_thumbee ? " ThumbEE" : "",
179                cpu_has_jazelle ? " Jazelle" : "");
180         printk("    Extensions:%s%s\n",
181                cpu_has_gentimer ? " GenericTimer" : "",
182                cpu_has_security ? " Security" : "");
183
184         printk("  Debug Features: %"PRIregister"\n",
185                system_cpuinfo.dbg32.bits[0]);
186         printk("  Auxiliary Features: %"PRIregister"\n",
187                system_cpuinfo.aux32.bits[0]);
188         printk("  Memory Model Features: %"PRIregister" %"PRIregister"\n"
189                "                         %"PRIregister" %"PRIregister"\n",
190                system_cpuinfo.mm32.bits[0], system_cpuinfo.mm32.bits[1],
191                system_cpuinfo.mm32.bits[2], system_cpuinfo.mm32.bits[3]);
192         printk("  ISA Features: %"PRIregister" %"PRIregister" %"PRIregister"\n"
193                "                %"PRIregister" %"PRIregister" %"PRIregister"\n",
194                system_cpuinfo.isa32.bits[0], system_cpuinfo.isa32.bits[1],
195                system_cpuinfo.isa32.bits[2], system_cpuinfo.isa32.bits[3],
196                system_cpuinfo.isa32.bits[4], system_cpuinfo.isa32.bits[5]);
197     }
198     else
199     {
200         printk("32-bit Execution: Unsupported\n");
201     }
202
203     processor_setup();
204 }
205
206 void __init discard_initial_modules(void)
207 {
208     struct bootmodules *mi = &bootinfo.modules;
209     int i;
210
211     /*
212      * When using static heap feature, don't give bootmodules memory back to
213      * the heap allocator
214      */
215     if ( using_static_heap )
216         goto out;
217
218     for ( i = 0; i < mi->nr_mods; i++ )
219     {
220         paddr_t s = mi->module[i].start;
221         paddr_t e = s + PAGE_ALIGN(mi->module[i].size);
222
223         if ( mi->module[i].kind == BOOTMOD_XEN )
224             continue;
225
226         if ( !mfn_valid(maddr_to_mfn(s)) ||
227              !mfn_valid(maddr_to_mfn(e)) )
228             continue;
229
230         fw_unreserved_regions(s, e, init_domheap_pages, 0);
231     }
232
233     mi->nr_mods = 0;
234
235  out:
236     remove_early_mappings();
237 }
238
239 /* Relocate the FDT in Xen heap */
240 static void * __init relocate_fdt(paddr_t dtb_paddr, size_t dtb_size)
241 {
242     void *fdt = xmalloc_bytes(dtb_size);
243
244     if ( !fdt )
245         panic("Unable to allocate memory for relocating the Device-Tree.\n");
246
247     copy_from_paddr(fdt, dtb_paddr, dtb_size);
248
249     return fdt;
250 }
251
252 void __init init_pdx(void)
253 {
254     const struct membanks *mem = bootinfo_get_mem();
255     paddr_t bank_start, bank_size, bank_end;
256
257     /*
258      * Arm does not have any restrictions on the bits to compress. Pass 0 to
259      * let the common code further restrict the mask.
260      *
261      * If the logic changes in pfn_pdx_hole_setup we might have to
262      * update this function too.
263      */
264     uint64_t mask = pdx_init_mask(0x0);
265     int bank;
266
267     for ( bank = 0 ; bank < mem->nr_banks; bank++ )
268     {
269         bank_start = mem->bank[bank].start;
270         bank_size = mem->bank[bank].size;
271
272         mask |= bank_start | pdx_region_mask(bank_start, bank_size);
273     }
274
275     for ( bank = 0 ; bank < mem->nr_banks; bank++ )
276     {
277         bank_start = mem->bank[bank].start;
278         bank_size = mem->bank[bank].size;
279
280         if (~mask & pdx_region_mask(bank_start, bank_size))
281             mask = 0;
282     }
283
284     pfn_pdx_hole_setup(mask >> PAGE_SHIFT);
285
286     for ( bank = 0 ; bank < mem->nr_banks; bank++ )
287     {
288         bank_start = mem->bank[bank].start;
289         bank_size = mem->bank[bank].size;
290         bank_end = bank_start + bank_size;
291
292         set_pdx_range(paddr_to_pfn(bank_start),
293                       paddr_to_pfn(bank_end));
294     }
295 }
296
297 size_t __read_mostly dcache_line_bytes;
298
299 /* C entry point for boot CPU */
300 void asmlinkage __init start_xen(unsigned long fdt_paddr)
301 {
302     size_t fdt_size;
303     const char *cmdline;
304     struct bootmodule *xen_bootmodule;
305     struct domain *d;
306     int rc, i;
307
308     dcache_line_bytes = read_dcache_line_bytes();
309
310     percpu_init_areas();
311     set_processor_id(0); /* needed early, for smp_processor_id() */
312
313     /* Initialize traps early allow us to get backtrace when an error occurred */
314     init_traps();
315
316     smp_clear_cpu_maps();
317
318     device_tree_flattened = early_fdt_map(fdt_paddr);
319     if ( !device_tree_flattened )
320         panic("Invalid device tree blob at physical address %#lx.\n"
321               "The DTB must be 8-byte aligned and must not exceed 2 MB in size.\n\n"
322               "Please check your bootloader.\n",
323               fdt_paddr);
324
325     /* Register Xen's load address as a boot module. */
326     xen_bootmodule = add_boot_module(BOOTMOD_XEN,
327                              virt_to_maddr(_start),
328                              (paddr_t)(uintptr_t)(_end - _start), false);
329     BUG_ON(!xen_bootmodule);
330
331     fdt_size = boot_fdt_info(device_tree_flattened, fdt_paddr);
332
333     cmdline = boot_fdt_cmdline(device_tree_flattened);
334     printk("Command line: %s\n", cmdline);
335     cmdline_parse(cmdline);
336
337     llc_coloring_init();
338
339     /*
340      * Page tables must be setup after LLC coloring initialization because
341      * coloring info are required in order to create colored mappings
342      */
343     setup_pagetables();
344     /* Device-tree was mapped in boot page tables, remap it in the new tables */
345     device_tree_flattened = early_fdt_map(fdt_paddr);
346
347     setup_mm();
348
349     vm_init();
350
351     /* Parse the ACPI tables for possible boot-time configuration */
352     acpi_boot_table_init();
353
354     end_boot_allocator();
355
356     /*
357      * The memory subsystem has been initialized, we can now switch from
358      * early_boot -> boot.
359      */
360     system_state = SYS_STATE_boot;
361
362     if ( acpi_disabled )
363     {
364         printk("Booting using Device Tree\n");
365         device_tree_flattened = relocate_fdt(fdt_paddr, fdt_size);
366         dt_unflatten_host_device_tree();
367     }
368     else
369     {
370         printk("Booting using ACPI\n");
371         device_tree_flattened = NULL;
372     }
373
374     init_IRQ();
375
376     platform_init();
377
378     preinit_xen_time();
379
380     gic_preinit();
381
382     uart_init();
383     console_init_preirq();
384     console_init_ring();
385
386     processor_id();
387
388     smp_init_cpus();
389     nr_cpu_ids = smp_get_max_cpus();
390     printk(XENLOG_INFO "SMP: Allowing %u CPUs\n", nr_cpu_ids);
391
392     /*
393      * Some errata relies on SMCCC version which is detected by psci_init()
394      * (called from smp_init_cpus()).
395      */
396     check_local_cpu_errata();
397
398     check_local_cpu_features();
399
400     init_xen_time();
401
402     gic_init();
403
404     tasklet_subsys_init();
405
406     if ( xsm_dt_init() != 1 )
407         warning_add("WARNING: SILO mode is not enabled.\n"
408                     "It has implications on the security of the system,\n"
409                     "unless the communications have been forbidden between\n"
410                     "untrusted domains.\n");
411
412     init_maintenance_interrupt();
413     init_timer_interrupt();
414
415     timer_init();
416
417     init_idle_domain();
418
419     rcu_init();
420
421     setup_system_domains();
422
423     local_irq_enable();
424     local_abort_enable();
425
426     smp_prepare_cpus();
427
428     initialize_keytable();
429
430     console_init_postirq();
431
432     do_presmp_initcalls();
433
434     for_each_present_cpu ( i )
435     {
436         if ( (num_online_cpus() < nr_cpu_ids) && !cpu_online(i) )
437         {
438             int ret = cpu_up(i);
439             if ( ret != 0 )
440                 printk("Failed to bring up CPU %u (error %d)\n", i, ret);
441         }
442     }
443
444     printk("Brought up %ld CPUs\n", (long)num_online_cpus());
445     /* TODO: smp_cpus_done(); */
446
447     /* This should be done in a vpmu driver but we do not have one yet. */
448     vpmu_is_available = cpu_has_pmu;
449
450     /*
451      * The IOMMU subsystem must be initialized before P2M as we need
452      * to gather requirements regarding the maximum IPA bits supported by
453      * each IOMMU device.
454      */
455     rc = iommu_setup();
456     if ( !iommu_enabled && rc != -ENODEV )
457         panic("Couldn't configure correctly all the IOMMUs.\n");
458
459     setup_virt_paging();
460
461     do_initcalls();
462
463     /*
464      * It needs to be called after do_initcalls to be able to use
465      * stop_machine (tasklets initialized via an initcall).
466      */
467 #ifdef CONFIG_HAS_ALTERNATIVE
468     apply_alternatives_all();
469 #endif
470     enable_errata_workarounds();
471     enable_cpu_features();
472
473     /* Create initial domain 0. */
474     if ( !is_dom0less_mode() )
475         create_dom0();
476     else
477         printk(XENLOG_INFO "Xen dom0less mode detected\n");
478
479     if ( acpi_disabled )
480     {
481         create_domUs();
482         alloc_static_evtchn();
483     }
484
485     /*
486      * This needs to be called **before** heap_init_late() so modules
487      * will be scrubbed (unless suppressed).
488      */
489     discard_initial_modules();
490
491     heap_init_late();
492
493     init_trace_bufs();
494
495     init_constructors();
496
497     console_endboot();
498
499     /* Hide UART from DOM0 if we're using it */
500     serial_endboot();
501
502     if ( (rc = xsm_set_system_active()) != 0 )
503         panic("xsm: unable to switch to SYSTEM_ACTIVE privilege: %d\n", rc);
504
505     system_state = SYS_STATE_active;
506
507     for_each_domain( d )
508         domain_unpause_by_systemcontroller(d);
509
510     /* Switch on to the dynamically allocated stack for the idle vcpu
511      * since the static one we're running on is about to be freed. */
512     memcpy(idle_vcpu[0]->arch.cpu_info, get_cpu_info(),
513            sizeof(struct cpu_info));
514     switch_stack_and_jump(idle_vcpu[0]->arch.cpu_info, init_done);
515 }
516
517 static int __init init_xen_cap_info(void)
518 {
519     /* Interface name is always xen-3.0-* for Xen-3.x. */
520
521 #ifdef CONFIG_ARM_64
522     safe_strcat(xen_cap_info, "xen-3.0-aarch64 ");
523 #endif
524     if ( cpu_has_aarch32 )
525         safe_strcat(xen_cap_info, "xen-3.0-armv7l ");
526
527     return 0;
528 }
529 __initcall(init_xen_cap_info);
530
531 /*
532  * Local variables:
533  * mode: C
534  * c-file-style: "BSD"
535  * c-basic-offset: 4
536  * indent-tabs-mode: nil
537  * End:
538  */