/* * We use PSCI 0.2+ when ACPI is deployed on ARM64 and it's * explicitly clarified in SBBR */ int __init psci_acpi_init(void) { if (!acpi_psci_present()) { pr_info("is not implemented in ACPI.\n"); return -EOPNOTSUPP; } pr_info("probing for conduit method from ACPI.\n"); if (acpi_psci_use_hvc()) invoke_psci_fn = __invoke_psci_fn_hvc; else invoke_psci_fn = __invoke_psci_fn_smc; return psci_probe(); }
/** * acpi_map_gic_cpu_interface - generates a logical cpu number * and map to MPIDR represented by GICC structure */ static void __init acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor) { int i; u64 mpidr = processor->arm_mpidr & MPIDR_HWID_BITMASK; bool enabled = !!(processor->flags & ACPI_MADT_ENABLED); if (mpidr == INVALID_HWID) { pr_info("Skip MADT cpu entry with invalid MPIDR\n"); return; } total_cpus++; if (!enabled) return; if (enabled_cpus >= NR_CPUS) { pr_warn("NR_CPUS limit of %d reached, Processor %d/0x%llx ignored.\n", NR_CPUS, total_cpus, mpidr); return; } /* Check if GICC structure of boot CPU is available in the MADT */ if (cpu_logical_map(0) == mpidr) { if (bootcpu_valid) { pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n", mpidr); return; } bootcpu_valid = true; } /* * Duplicate MPIDRs are a recipe for disaster. Scan * all initialized entries and check for * duplicates. If any is found just ignore the CPU. */ for (i = 1; i < enabled_cpus; i++) { if (cpu_logical_map(i) == mpidr) { pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n", mpidr); return; } } if (!acpi_psci_present()) return; cpu_ops[enabled_cpus] = cpu_get_ops("psci"); /* CPU 0 was already initialized */ if (enabled_cpus) { if (!cpu_ops[enabled_cpus]) return; if (cpu_ops[enabled_cpus]->cpu_init(NULL, enabled_cpus)) return; /* map the logical cpu id to cpu MPIDR */ cpu_logical_map(enabled_cpus) = mpidr; } enabled_cpus++; }