| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * linux/arch/arm/kernel/setup.c |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * 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 | 6 | */ |
|---|
| 10 | 7 | #include <linux/efi.h> |
|---|
| 11 | 8 | #include <linux/export.h> |
|---|
| .. | .. |
|---|
| 16 | 13 | #include <linux/utsname.h> |
|---|
| 17 | 14 | #include <linux/initrd.h> |
|---|
| 18 | 15 | #include <linux/console.h> |
|---|
| 19 | | -#include <linux/bootmem.h> |
|---|
| 20 | 16 | #include <linux/seq_file.h> |
|---|
| 21 | 17 | #include <linux/screen_info.h> |
|---|
| 22 | 18 | #include <linux/of_platform.h> |
|---|
| 23 | 19 | #include <linux/init.h> |
|---|
| 24 | 20 | #include <linux/kexec.h> |
|---|
| 21 | +#include <linux/libfdt.h> |
|---|
| 25 | 22 | #include <linux/of_fdt.h> |
|---|
| 26 | 23 | #include <linux/cpu.h> |
|---|
| 27 | 24 | #include <linux/interrupt.h> |
|---|
| .. | .. |
|---|
| 112 | 109 | unsigned int elf_hwcap2 __read_mostly; |
|---|
| 113 | 110 | EXPORT_SYMBOL(elf_hwcap2); |
|---|
| 114 | 111 | |
|---|
| 115 | | - |
|---|
| 116 | | -char* (*arch_read_hardware_id)(void); |
|---|
| 117 | | -EXPORT_SYMBOL(arch_read_hardware_id); |
|---|
| 118 | | - |
|---|
| 119 | | -/* Vendor stub */ |
|---|
| 120 | | -unsigned int boot_reason; |
|---|
| 121 | | -EXPORT_SYMBOL_GPL(boot_reason); |
|---|
| 122 | | - |
|---|
| 123 | | -/* Vendor stub */ |
|---|
| 124 | | -unsigned int cold_boot; |
|---|
| 125 | | -EXPORT_SYMBOL_GPL(cold_boot); |
|---|
| 126 | 112 | |
|---|
| 127 | 113 | #ifdef MULTI_CPU |
|---|
| 128 | 114 | struct processor processor __ro_after_init; |
|---|
| .. | .. |
|---|
| 860 | 846 | |
|---|
| 861 | 847 | static void __init request_standard_resources(const struct machine_desc *mdesc) |
|---|
| 862 | 848 | { |
|---|
| 863 | | - struct memblock_region *region; |
|---|
| 849 | + phys_addr_t start, end, res_end; |
|---|
| 864 | 850 | struct resource *res; |
|---|
| 851 | + u64 i; |
|---|
| 865 | 852 | |
|---|
| 866 | 853 | kernel_code.start = virt_to_phys(_text); |
|---|
| 867 | 854 | kernel_code.end = virt_to_phys(__init_begin - 1); |
|---|
| 868 | 855 | kernel_data.start = virt_to_phys(_sdata); |
|---|
| 869 | 856 | kernel_data.end = virt_to_phys(_end - 1); |
|---|
| 870 | 857 | |
|---|
| 871 | | - for_each_memblock(memory, region) { |
|---|
| 872 | | - phys_addr_t start = __pfn_to_phys(memblock_region_memory_base_pfn(region)); |
|---|
| 873 | | - phys_addr_t end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1; |
|---|
| 858 | + for_each_mem_range(i, &start, &end) { |
|---|
| 874 | 859 | unsigned long boot_alias_start; |
|---|
| 860 | + |
|---|
| 861 | + /* |
|---|
| 862 | + * In memblock, end points to the first byte after the |
|---|
| 863 | + * range while in resourses, end points to the last byte in |
|---|
| 864 | + * the range. |
|---|
| 865 | + */ |
|---|
| 866 | + res_end = end - 1; |
|---|
| 875 | 867 | |
|---|
| 876 | 868 | /* |
|---|
| 877 | 869 | * Some systems have a special memory alias which is only |
|---|
| .. | .. |
|---|
| 880 | 872 | */ |
|---|
| 881 | 873 | boot_alias_start = phys_to_idmap(start); |
|---|
| 882 | 874 | if (arm_has_idmap_alias() && boot_alias_start != IDMAP_INVALID_ADDR) { |
|---|
| 883 | | - res = memblock_virt_alloc(sizeof(*res), 0); |
|---|
| 875 | + res = memblock_alloc(sizeof(*res), SMP_CACHE_BYTES); |
|---|
| 876 | + if (!res) |
|---|
| 877 | + panic("%s: Failed to allocate %zu bytes\n", |
|---|
| 878 | + __func__, sizeof(*res)); |
|---|
| 884 | 879 | res->name = "System RAM (boot alias)"; |
|---|
| 885 | 880 | res->start = boot_alias_start; |
|---|
| 886 | | - res->end = phys_to_idmap(end); |
|---|
| 881 | + res->end = phys_to_idmap(res_end); |
|---|
| 887 | 882 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; |
|---|
| 888 | 883 | request_resource(&iomem_resource, res); |
|---|
| 889 | 884 | } |
|---|
| 890 | 885 | |
|---|
| 891 | | - res = memblock_virt_alloc(sizeof(*res), 0); |
|---|
| 886 | + res = memblock_alloc(sizeof(*res), SMP_CACHE_BYTES); |
|---|
| 887 | + if (!res) |
|---|
| 888 | + panic("%s: Failed to allocate %zu bytes\n", __func__, |
|---|
| 889 | + sizeof(*res)); |
|---|
| 892 | 890 | res->name = "System RAM"; |
|---|
| 893 | 891 | res->start = start; |
|---|
| 894 | | - res->end = end; |
|---|
| 892 | + res->end = res_end; |
|---|
| 895 | 893 | res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; |
|---|
| 896 | 894 | |
|---|
| 897 | 895 | request_resource(&iomem_resource, res); |
|---|
| .. | .. |
|---|
| 1084 | 1082 | #endif |
|---|
| 1085 | 1083 | } |
|---|
| 1086 | 1084 | |
|---|
| 1085 | +static void (*__arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd); |
|---|
| 1086 | + |
|---|
| 1087 | +static int arm_restart(struct notifier_block *nb, unsigned long action, |
|---|
| 1088 | + void *data) |
|---|
| 1089 | +{ |
|---|
| 1090 | + __arm_pm_restart(action, data); |
|---|
| 1091 | + return NOTIFY_DONE; |
|---|
| 1092 | +} |
|---|
| 1093 | + |
|---|
| 1094 | +static struct notifier_block arm_restart_nb = { |
|---|
| 1095 | + .notifier_call = arm_restart, |
|---|
| 1096 | + .priority = 128, |
|---|
| 1097 | +}; |
|---|
| 1098 | + |
|---|
| 1087 | 1099 | void __init setup_arch(char **cmdline_p) |
|---|
| 1088 | 1100 | { |
|---|
| 1089 | | - const struct machine_desc *mdesc; |
|---|
| 1101 | + const struct machine_desc *mdesc = NULL; |
|---|
| 1102 | + void *atags_vaddr = NULL; |
|---|
| 1103 | + |
|---|
| 1104 | + if (__atags_pointer) |
|---|
| 1105 | + atags_vaddr = FDT_VIRT_BASE(__atags_pointer); |
|---|
| 1090 | 1106 | |
|---|
| 1091 | 1107 | setup_processor(); |
|---|
| 1092 | | - mdesc = setup_machine_fdt(__atags_pointer); |
|---|
| 1108 | + if (atags_vaddr) { |
|---|
| 1109 | + mdesc = setup_machine_fdt(atags_vaddr); |
|---|
| 1110 | + if (mdesc) |
|---|
| 1111 | + memblock_reserve(__atags_pointer, |
|---|
| 1112 | + fdt_totalsize(atags_vaddr)); |
|---|
| 1113 | + } |
|---|
| 1093 | 1114 | if (!mdesc) |
|---|
| 1094 | | - mdesc = setup_machine_tags(__atags_pointer, __machine_arch_type); |
|---|
| 1115 | + mdesc = setup_machine_tags(atags_vaddr, __machine_arch_type); |
|---|
| 1095 | 1116 | if (!mdesc) { |
|---|
| 1096 | 1117 | early_print("\nError: invalid dtb and unrecognized/unsupported machine ID\n"); |
|---|
| 1097 | 1118 | early_print(" r1=0x%08x, r2=0x%08x\n", __machine_arch_type, |
|---|
| 1098 | 1119 | __atags_pointer); |
|---|
| 1099 | 1120 | if (__atags_pointer) |
|---|
| 1100 | | - early_print(" r2[]=%*ph\n", 16, |
|---|
| 1101 | | - phys_to_virt(__atags_pointer)); |
|---|
| 1121 | + early_print(" r2[]=%*ph\n", 16, atags_vaddr); |
|---|
| 1102 | 1122 | dump_machine_table(); |
|---|
| 1103 | 1123 | } |
|---|
| 1104 | 1124 | |
|---|
| .. | .. |
|---|
| 1143 | 1163 | paging_init(mdesc); |
|---|
| 1144 | 1164 | request_standard_resources(mdesc); |
|---|
| 1145 | 1165 | |
|---|
| 1146 | | - if (mdesc->restart) |
|---|
| 1147 | | - arm_pm_restart = mdesc->restart; |
|---|
| 1166 | + if (mdesc->restart) { |
|---|
| 1167 | + __arm_pm_restart = mdesc->restart; |
|---|
| 1168 | + register_restart_handler(&arm_restart_nb); |
|---|
| 1169 | + } |
|---|
| 1148 | 1170 | |
|---|
| 1149 | 1171 | unflatten_device_tree(); |
|---|
| 1150 | 1172 | |
|---|
| .. | .. |
|---|
| 1175 | 1197 | #ifdef CONFIG_VT |
|---|
| 1176 | 1198 | #if defined(CONFIG_VGA_CONSOLE) |
|---|
| 1177 | 1199 | conswitchp = &vga_con; |
|---|
| 1178 | | -#elif defined(CONFIG_DUMMY_CONSOLE) |
|---|
| 1179 | | - conswitchp = &dummy_con; |
|---|
| 1180 | 1200 | #endif |
|---|
| 1181 | 1201 | #endif |
|---|
| 1182 | 1202 | |
|---|
| .. | .. |
|---|
| 1306 | 1326 | seq_printf(m, "CPU revision\t: %d\n\n", cpuid & 15); |
|---|
| 1307 | 1327 | } |
|---|
| 1308 | 1328 | |
|---|
| 1309 | | - if (!arch_read_hardware_id) |
|---|
| 1310 | | - seq_printf(m, "Hardware\t: %s\n", machine_name); |
|---|
| 1311 | | - else |
|---|
| 1312 | | - seq_printf(m, "Hardware\t: %s\n", arch_read_hardware_id()); |
|---|
| 1329 | + seq_printf(m, "Hardware\t: %s\n", machine_name); |
|---|
| 1313 | 1330 | seq_printf(m, "Revision\t: %04x\n", system_rev); |
|---|
| 1314 | 1331 | seq_printf(m, "Serial\t\t: %s\n", system_serial); |
|---|
| 1315 | 1332 | |
|---|