void __init cpu_read_bootcpu_ops(void) { struct device_node *dn = of_get_cpu_node(0, NULL); if (!dn) { pr_err("Failed to find device node for boot cpu\n"); return; } cpu_read_ops(dn, 0); }
/* * Initialize cpu operations for a logical cpu and * set it in the possible mask on success */ static int __init smp_cpu_setup(int cpu) { if (cpu_read_ops(cpu)) return -ENODEV; if (cpu_ops[cpu]->cpu_init(cpu)) return -ENODEV; set_cpu_possible(cpu, true); return 0; }
/* * Enumerate the possible CPU set from the device tree and build the * cpu logical map array containing MPIDR values related to logical * cpus. Assumes that cpu_logical_map(0) has already been initialized. */ void __init smp_init_cpus(void) { struct device_node *dn = NULL; unsigned int i, cpu = 1; bool bootcpu_valid = false; while ((dn = of_find_node_by_type(dn, "cpu"))) { const u32 *cell; u64 hwid; /* * A cpu node with missing "reg" property is * considered invalid to build a cpu_logical_map * entry. */ cell = of_get_property(dn, "reg", NULL); if (!cell) { pr_err("%s: missing reg property\n", dn->full_name); goto next; } hwid = of_read_number(cell, of_n_addr_cells(dn)); /* * Non affinity bits must be set to 0 in the DT */ if (hwid & ~MPIDR_HWID_BITMASK) { pr_err("%s: invalid reg property\n", dn->full_name); goto next; } /* * Duplicate MPIDRs are a recipe for disaster. Scan * all initialized entries and check for * duplicates. If any is found just ignore the cpu. * cpu_logical_map was initialized to INVALID_HWID to * avoid matching valid MPIDR values. */ for (i = 1; (i < cpu) && (i < NR_CPUS); i++) { if (cpu_logical_map(i) == hwid) { pr_err("%s: duplicate cpu reg properties in the DT\n", dn->full_name); goto next; } } /* * The numbering scheme requires that the boot CPU * must be assigned logical id 0. Record it so that * the logical map built from DT is validated and can * be used. */ if (hwid == cpu_logical_map(0)) { if (bootcpu_valid) { pr_err("%s: duplicate boot cpu reg property in DT\n", dn->full_name); goto next; } bootcpu_valid = true; /* * cpu_logical_map has already been * initialized and the boot cpu doesn't need * the enable-method so continue without * incrementing cpu. */ continue; } if (cpu >= NR_CPUS) goto next; if (cpu_read_ops(dn, cpu) != 0) goto next; if (cpu_ops[cpu]->cpu_init(dn, cpu)) goto next; pr_debug("cpu logical map 0x%llx\n", hwid); cpu_logical_map(cpu) = hwid; next: cpu++; } /* sanity check */ if (cpu > NR_CPUS) pr_warning("no. of cores (%d) greater than configured maximum of %d - clipping\n", cpu, NR_CPUS); if (!bootcpu_valid) { pr_err("DT missing boot CPU MPIDR, not enabling secondaries\n"); return; } /* * All the cpus that made it to the cpu_logical_map have been * validated so set them as possible cpus. */ for (i = 0; i < NR_CPUS; i++) if (cpu_logical_map(i) != INVALID_HWID) set_cpu_possible(i, true); }
void __init smp_init_cpus(void) { struct device_node *dn = NULL; unsigned int i, cpu = 1; bool bootcpu_valid = false; while ((dn = of_find_node_by_type(dn, "cpu"))) { const u32 *cell; u64 hwid; cell = of_get_property(dn, "reg", NULL); if (!cell) { pr_err("%s: missing reg property\n", dn->full_name); goto next; } hwid = of_read_number(cell, of_n_addr_cells(dn)); if (hwid & ~MPIDR_HWID_BITMASK) { pr_err("%s: invalid reg property\n", dn->full_name); goto next; } for (i = 1; (i < cpu) && (i < NR_CPUS); i++) { if (cpu_logical_map(i) == hwid) { pr_err("%s: duplicate cpu reg properties in the DT\n", dn->full_name); goto next; } } if (hwid == cpu_logical_map(0)) { if (bootcpu_valid) { pr_err("%s: duplicate boot cpu reg property in DT\n", dn->full_name); goto next; } bootcpu_valid = true; continue; } if (cpu >= NR_CPUS) goto next; if (cpu_read_ops(dn, cpu) != 0) goto next; if (cpu_ops[cpu]->cpu_init(dn, cpu)) goto next; pr_debug("cpu logical map 0x%llx\n", hwid); cpu_logical_map(cpu) = hwid; next: cpu++; } if (cpu > NR_CPUS) pr_warning("no. of cores (%d) greater than configured maximum of %d - clipping\n", cpu, NR_CPUS); if (!bootcpu_valid) { pr_err("DT missing boot CPU MPIDR, not enabling secondaries\n"); return; } for (i = 0; i < NR_CPUS; i++) if (cpu_logical_map(i) != INVALID_HWID) set_cpu_possible(i, true); }