.. | .. |
---|
| 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 | |
---|