1 /* 2 * ARM64 Specific Low-Level ACPI Boot Support 3 * 4 * Copyright (C) 2013-2014, Linaro Ltd. 5 * Author: Al Stone <al.stone@linaro.org> 6 * Author: Graeme Gregory <graeme.gregory@linaro.org> 7 * Author: Hanjun Guo <hanjun.guo@linaro.org> 8 * Author: Tomasz Nowicki <tomasz.nowicki@linaro.org> 9 * Author: Naresh Bhat <naresh.bhat@linaro.org> 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License version 2 as 13 * published by the Free Software Foundation. 14 */ 15 16 #define pr_fmt(fmt) "ACPI: " fmt 17 18 #include <linux/acpi.h> 19 #include <linux/bootmem.h> 20 #include <linux/cpumask.h> 21 #include <linux/init.h> 22 #include <linux/irq.h> 23 #include <linux/irqdomain.h> 24 #include <linux/memblock.h> 25 #include <linux/of_fdt.h> 26 #include <linux/smp.h> 27 28 #include <asm/cputype.h> 29 #include <asm/cpu_ops.h> 30 #include <asm/smp_plat.h> 31 32 int acpi_noirq = 1; /* skip ACPI IRQ initialization */ 33 int acpi_disabled = 1; 34 EXPORT_SYMBOL(acpi_disabled); 35 36 int acpi_pci_disabled = 1; /* skip ACPI PCI scan and IRQ initialization */ 37 EXPORT_SYMBOL(acpi_pci_disabled); 38 39 /* Processors with enabled flag and sane MPIDR */ 40 static int enabled_cpus; 41 42 /* Boot CPU is valid or not in MADT */ 43 static bool bootcpu_valid __initdata; 44 45 static bool param_acpi_off __initdata; 46 static bool param_acpi_force __initdata; 47 48 static int __init parse_acpi(char *arg) 49 { 50 if (!arg) 51 return -EINVAL; 52 53 /* "acpi=off" disables both ACPI table parsing and interpreter */ 54 if (strcmp(arg, "off") == 0) 55 param_acpi_off = true; 56 else if (strcmp(arg, "force") == 0) /* force ACPI to be enabled */ 57 param_acpi_force = true; 58 else 59 return -EINVAL; /* Core will print when we return error */ 60 61 return 0; 62 } 63 early_param("acpi", parse_acpi); 64 65 static int __init dt_scan_depth1_nodes(unsigned long node, 66 const char *uname, int depth, 67 void *data) 68 { 69 /* 70 * Return 1 as soon as we encounter a node at depth 1 that is 71 * not the /chosen node. 72 */ 73 if (depth == 1 && (strcmp(uname, "chosen") != 0)) 74 return 1; 75 return 0; 76 } 77 78 /* 79 * __acpi_map_table() will be called before page_init(), so early_ioremap() 80 * or early_memremap() should be called here to for ACPI table mapping. 81 */ 82 char *__init __acpi_map_table(unsigned long phys, unsigned long size) 83 { 84 if (!size) 85 return NULL; 86 87 return early_memremap(phys, size); 88 } 89 90 void __init __acpi_unmap_table(char *map, unsigned long size) 91 { 92 if (!map || !size) 93 return; 94 95 early_memunmap(map, size); 96 } 97 98 /** 99 * acpi_map_gic_cpu_interface - generates a logical cpu number 100 * and map to MPIDR represented by GICC structure 101 * @mpidr: CPU's hardware id to register, MPIDR represented in MADT 102 * @enabled: this cpu is enabled or not 103 * 104 * Returns the logical cpu number which maps to MPIDR 105 */ 106 static int __init acpi_map_gic_cpu_interface(u64 mpidr, u8 enabled) 107 { 108 int i; 109 110 if (mpidr == INVALID_HWID) { 111 pr_info("Skip MADT cpu entry with invalid MPIDR\n"); 112 return -EINVAL; 113 } 114 115 total_cpus++; 116 if (!enabled) 117 return -EINVAL; 118 119 if (enabled_cpus >= NR_CPUS) { 120 pr_warn("NR_CPUS limit of %d reached, Processor %d/0x%llx ignored.\n", 121 NR_CPUS, total_cpus, mpidr); 122 return -EINVAL; 123 } 124 125 /* Check if GICC structure of boot CPU is available in the MADT */ 126 if (cpu_logical_map(0) == mpidr) { 127 if (bootcpu_valid) { 128 pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n", 129 mpidr); 130 return -EINVAL; 131 } 132 133 bootcpu_valid = true; 134 } 135 136 /* 137 * Duplicate MPIDRs are a recipe for disaster. Scan 138 * all initialized entries and check for 139 * duplicates. If any is found just ignore the CPU. 140 */ 141 for (i = 1; i < enabled_cpus; i++) { 142 if (cpu_logical_map(i) == mpidr) { 143 pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n", 144 mpidr); 145 return -EINVAL; 146 } 147 } 148 149 if (!acpi_psci_present()) 150 return -EOPNOTSUPP; 151 152 cpu_ops[enabled_cpus] = cpu_get_ops("psci"); 153 /* CPU 0 was already initialized */ 154 if (enabled_cpus) { 155 if (!cpu_ops[enabled_cpus]) 156 return -EINVAL; 157 158 if (cpu_ops[enabled_cpus]->cpu_init(NULL, enabled_cpus)) 159 return -EOPNOTSUPP; 160 161 /* map the logical cpu id to cpu MPIDR */ 162 cpu_logical_map(enabled_cpus) = mpidr; 163 } 164 165 enabled_cpus++; 166 return enabled_cpus; 167 } 168 169 static int __init 170 acpi_parse_gic_cpu_interface(struct acpi_subtable_header *header, 171 const unsigned long end) 172 { 173 struct acpi_madt_generic_interrupt *processor; 174 175 processor = (struct acpi_madt_generic_interrupt *)header; 176 177 if (BAD_MADT_ENTRY(processor, end)) 178 return -EINVAL; 179 180 acpi_table_print_madt_entry(header); 181 182 acpi_map_gic_cpu_interface(processor->arm_mpidr & MPIDR_HWID_BITMASK, 183 processor->flags & ACPI_MADT_ENABLED); 184 185 return 0; 186 } 187 188 /* Parse GIC cpu interface entries in MADT for SMP init */ 189 void __init acpi_init_cpus(void) 190 { 191 int count, i; 192 193 /* 194 * do a partial walk of MADT to determine how many CPUs 195 * we have including disabled CPUs, and get information 196 * we need for SMP init 197 */ 198 count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, 199 acpi_parse_gic_cpu_interface, 0); 200 201 if (!count) { 202 pr_err("No GIC CPU interface entries present\n"); 203 return; 204 } else if (count < 0) { 205 pr_err("Error parsing GIC CPU interface entry\n"); 206 return; 207 } 208 209 if (!bootcpu_valid) { 210 pr_err("MADT missing boot CPU MPIDR, not enabling secondaries\n"); 211 return; 212 } 213 214 for (i = 0; i < enabled_cpus; i++) 215 set_cpu_possible(i, true); 216 217 /* Make boot-up look pretty */ 218 pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus); 219 } 220 221 static int __init acpi_parse_fadt(struct acpi_table_header *table) 222 { 223 struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table; 224 225 /* 226 * Revision in table header is the FADT Major revision, and there 227 * is a minor revision of FADT which was introduced by ACPI 5.1, 228 * we only deal with ACPI 5.1 or newer revision to get GIC and SMP 229 * boot protocol configuration data, or we will disable ACPI. 230 */ 231 if (table->revision > 5 || 232 (table->revision == 5 && fadt->minor_revision >= 1)) { 233 /* 234 * ACPI 5.1 only has two explicit methods to boot up SMP, 235 * PSCI and Parking protocol, but the Parking protocol is 236 * only specified for ARMv7 now, so make PSCI as the only 237 * way for the SMP boot protocol before some updates for 238 * the Parking protocol spec. 239 */ 240 if (acpi_psci_present()) 241 return 0; 242 243 pr_warn("No PSCI support, will not bring up secondary CPUs\n"); 244 return -EOPNOTSUPP; 245 } 246 247 pr_warn("Unsupported FADT revision %d.%d, should be 5.1+, will disable ACPI\n", 248 table->revision, fadt->minor_revision); 249 disable_acpi(); 250 251 return -EINVAL; 252 } 253 254 /* 255 * acpi_boot_table_init() called from setup_arch(), always. 256 * 1. find RSDP and get its address, and then find XSDT 257 * 2. extract all tables and checksums them all 258 * 3. check ACPI FADT revision 259 * 260 * We can parse ACPI boot-time tables such as MADT after 261 * this function is called. 262 */ 263 void __init acpi_boot_table_init(void) 264 { 265 /* 266 * Enable ACPI instead of device tree unless 267 * - ACPI has been disabled explicitly (acpi=off), or 268 * - the device tree is not empty (it has more than just a /chosen node) 269 * and ACPI has not been force enabled (acpi=force) 270 */ 271 if (param_acpi_off || 272 (!param_acpi_force && of_scan_flat_dt(dt_scan_depth1_nodes, NULL))) 273 return; 274 275 enable_acpi(); 276 277 /* Initialize the ACPI boot-time table parser. */ 278 if (acpi_table_init()) { 279 disable_acpi(); 280 return; 281 } 282 283 if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt)) { 284 /* disable ACPI if no FADT is found */ 285 disable_acpi(); 286 pr_err("Can't find FADT\n"); 287 } 288 } 289