Exemple #1
0
/*
 * Enumerate the possible CPU set from the device tree.
 */
void __init smp_init_cpus(void)
{
	const char *enable_method;
	struct device_node *dn = NULL;
	int cpu = 0;

	while ((dn = of_find_node_by_type(dn, "cpu"))) {
		if (cpu >= NR_CPUS)
			goto next;

		/*
		 * We currently support only the "spin-table" enable-method.
		 */
		enable_method = of_get_property(dn, "enable-method", NULL);
		if (!enable_method) {
			pr_err("CPU %d: missing enable-method property\n", cpu);
			goto next;
		}

		smp_enable_ops[cpu] = smp_get_enable_ops(enable_method);

		if (!smp_enable_ops[cpu]) {
			pr_err("CPU %d: invalid enable-method property: %s\n",
			       cpu, enable_method);
			goto next;
		}

		if (smp_enable_ops[cpu]->init_cpu(dn, cpu))
			goto next;

		set_cpu_possible(cpu, true);
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);
}
Exemple #2
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)
{
	const char *enable_method;
	struct device_node *dn = NULL;
	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;

		/*
		 * We currently support only the "spin-table" enable-method.
		 */
		enable_method = of_get_property(dn, "enable-method", NULL);
		if (!enable_method) {
			pr_err("%s: missing enable-method property\n",
				dn->full_name);
			goto next;
		}

		smp_enable_ops[cpu] = smp_get_enable_ops(enable_method);

		if (!smp_enable_ops[cpu]) {
			pr_err("%s: invalid enable-method property: %s\n",
			       dn->full_name, enable_method);
			goto next;
		}

		if (smp_enable_ops[cpu]->init_cpu(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);
}