|
@@ -374,75 +374,26 @@ static const char *get_mid_prop(void)
|
|
|
return (tlb_type == spitfire ? "upa-portid" : "portid");
|
|
|
}
|
|
|
|
|
|
-struct device_node *of_find_node_by_cpuid(int cpuid)
|
|
|
-{
|
|
|
- struct device_node *dp;
|
|
|
- const char *mid_prop = get_mid_prop();
|
|
|
-
|
|
|
- for_each_node_by_type(dp, "cpu") {
|
|
|
- int id = of_getintprop_default(dp, mid_prop, -1);
|
|
|
- const char *this_mid_prop = mid_prop;
|
|
|
-
|
|
|
- if (id < 0) {
|
|
|
- this_mid_prop = "cpuid";
|
|
|
- id = of_getintprop_default(dp, this_mid_prop, -1);
|
|
|
- }
|
|
|
-
|
|
|
- if (id < 0) {
|
|
|
- prom_printf("OF: Serious problem, cpu lacks "
|
|
|
- "%s property", this_mid_prop);
|
|
|
- prom_halt();
|
|
|
- }
|
|
|
- if (cpuid == id)
|
|
|
- return dp;
|
|
|
- }
|
|
|
- return NULL;
|
|
|
-}
|
|
|
-
|
|
|
-void __init of_fill_in_cpu_data(void)
|
|
|
+static void *of_iterate_over_cpus(void *(*func)(struct device_node *, int, int), int arg)
|
|
|
{
|
|
|
struct device_node *dp;
|
|
|
const char *mid_prop;
|
|
|
|
|
|
- if (tlb_type == hypervisor)
|
|
|
- return;
|
|
|
-
|
|
|
mid_prop = get_mid_prop();
|
|
|
- ncpus_probed = 0;
|
|
|
for_each_node_by_type(dp, "cpu") {
|
|
|
int cpuid = of_getintprop_default(dp, mid_prop, -1);
|
|
|
const char *this_mid_prop = mid_prop;
|
|
|
- struct device_node *portid_parent;
|
|
|
- int portid = -1;
|
|
|
+ void *ret;
|
|
|
|
|
|
- portid_parent = NULL;
|
|
|
if (cpuid < 0) {
|
|
|
this_mid_prop = "cpuid";
|
|
|
cpuid = of_getintprop_default(dp, this_mid_prop, -1);
|
|
|
- if (cpuid >= 0) {
|
|
|
- int limit = 2;
|
|
|
-
|
|
|
- portid_parent = dp;
|
|
|
- while (limit--) {
|
|
|
- portid_parent = portid_parent->parent;
|
|
|
- if (!portid_parent)
|
|
|
- break;
|
|
|
- portid = of_getintprop_default(portid_parent,
|
|
|
- "portid", -1);
|
|
|
- if (portid >= 0)
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
-
|
|
|
if (cpuid < 0) {
|
|
|
prom_printf("OF: Serious problem, cpu lacks "
|
|
|
"%s property", this_mid_prop);
|
|
|
prom_halt();
|
|
|
}
|
|
|
-
|
|
|
- ncpus_probed++;
|
|
|
-
|
|
|
#ifdef CONFIG_SMP
|
|
|
if (cpuid >= NR_CPUS) {
|
|
|
printk(KERN_WARNING "Ignoring CPU %d which is "
|
|
@@ -450,79 +401,143 @@ void __init of_fill_in_cpu_data(void)
|
|
|
cpuid, NR_CPUS);
|
|
|
continue;
|
|
|
}
|
|
|
-#else
|
|
|
- /* On uniprocessor we only want the values for the
|
|
|
- * real physical cpu the kernel booted onto, however
|
|
|
- * cpu_data() only has one entry at index 0.
|
|
|
- */
|
|
|
- if (cpuid != real_hard_smp_processor_id())
|
|
|
- continue;
|
|
|
- cpuid = 0;
|
|
|
#endif
|
|
|
+ ret = func(dp, cpuid, arg);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
|
|
|
- cpu_data(cpuid).clock_tick =
|
|
|
- of_getintprop_default(dp, "clock-frequency", 0);
|
|
|
-
|
|
|
- if (portid_parent) {
|
|
|
- cpu_data(cpuid).dcache_size =
|
|
|
- of_getintprop_default(dp, "l1-dcache-size",
|
|
|
- 16 * 1024);
|
|
|
- cpu_data(cpuid).dcache_line_size =
|
|
|
- of_getintprop_default(dp, "l1-dcache-line-size",
|
|
|
- 32);
|
|
|
- cpu_data(cpuid).icache_size =
|
|
|
- of_getintprop_default(dp, "l1-icache-size",
|
|
|
- 8 * 1024);
|
|
|
- cpu_data(cpuid).icache_line_size =
|
|
|
- of_getintprop_default(dp, "l1-icache-line-size",
|
|
|
- 32);
|
|
|
- cpu_data(cpuid).ecache_size =
|
|
|
- of_getintprop_default(dp, "l2-cache-size", 0);
|
|
|
- cpu_data(cpuid).ecache_line_size =
|
|
|
- of_getintprop_default(dp, "l2-cache-line-size", 0);
|
|
|
- if (!cpu_data(cpuid).ecache_size ||
|
|
|
- !cpu_data(cpuid).ecache_line_size) {
|
|
|
- cpu_data(cpuid).ecache_size =
|
|
|
- of_getintprop_default(portid_parent,
|
|
|
- "l2-cache-size",
|
|
|
- (4 * 1024 * 1024));
|
|
|
- cpu_data(cpuid).ecache_line_size =
|
|
|
- of_getintprop_default(portid_parent,
|
|
|
- "l2-cache-line-size", 64);
|
|
|
- }
|
|
|
-
|
|
|
- cpu_data(cpuid).core_id = portid + 1;
|
|
|
- cpu_data(cpuid).proc_id = portid;
|
|
|
+static void *check_cpu_node(struct device_node *dp, int cpuid, int id)
|
|
|
+{
|
|
|
+ if (id == cpuid)
|
|
|
+ return dp;
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+struct device_node *of_find_node_by_cpuid(int cpuid)
|
|
|
+{
|
|
|
+ return of_iterate_over_cpus(check_cpu_node, cpuid);
|
|
|
+}
|
|
|
+
|
|
|
+static void *record_one_cpu(struct device_node *dp, int cpuid, int arg)
|
|
|
+{
|
|
|
+ ncpus_probed++;
|
|
|
#ifdef CONFIG_SMP
|
|
|
- sparc64_multi_core = 1;
|
|
|
+ set_cpu_present(cpuid, true);
|
|
|
+ set_cpu_possible(cpuid, true);
|
|
|
#endif
|
|
|
- } else {
|
|
|
- cpu_data(cpuid).dcache_size =
|
|
|
- of_getintprop_default(dp, "dcache-size", 16 * 1024);
|
|
|
- cpu_data(cpuid).dcache_line_size =
|
|
|
- of_getintprop_default(dp, "dcache-line-size", 32);
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
|
|
|
- cpu_data(cpuid).icache_size =
|
|
|
- of_getintprop_default(dp, "icache-size", 16 * 1024);
|
|
|
- cpu_data(cpuid).icache_line_size =
|
|
|
- of_getintprop_default(dp, "icache-line-size", 32);
|
|
|
+void __init of_populate_present_mask(void)
|
|
|
+{
|
|
|
+ if (tlb_type == hypervisor)
|
|
|
+ return;
|
|
|
+
|
|
|
+ ncpus_probed = 0;
|
|
|
+ of_iterate_over_cpus(record_one_cpu, 0);
|
|
|
+}
|
|
|
|
|
|
+static void *fill_in_one_cpu(struct device_node *dp, int cpuid, int arg)
|
|
|
+{
|
|
|
+ struct device_node *portid_parent = NULL;
|
|
|
+ int portid = -1;
|
|
|
+
|
|
|
+ if (of_find_property(dp, "cpuid", NULL)) {
|
|
|
+ int limit = 2;
|
|
|
+
|
|
|
+ portid_parent = dp;
|
|
|
+ while (limit--) {
|
|
|
+ portid_parent = portid_parent->parent;
|
|
|
+ if (!portid_parent)
|
|
|
+ break;
|
|
|
+ portid = of_getintprop_default(portid_parent,
|
|
|
+ "portid", -1);
|
|
|
+ if (portid >= 0)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+#ifndef CONFIG_SMP
|
|
|
+ /* On uniprocessor we only want the values for the
|
|
|
+ * real physical cpu the kernel booted onto, however
|
|
|
+ * cpu_data() only has one entry at index 0.
|
|
|
+ */
|
|
|
+ if (cpuid != real_hard_smp_processor_id())
|
|
|
+ return NULL;
|
|
|
+ cpuid = 0;
|
|
|
+#endif
|
|
|
+
|
|
|
+ cpu_data(cpuid).clock_tick =
|
|
|
+ of_getintprop_default(dp, "clock-frequency", 0);
|
|
|
+
|
|
|
+ if (portid_parent) {
|
|
|
+ cpu_data(cpuid).dcache_size =
|
|
|
+ of_getintprop_default(dp, "l1-dcache-size",
|
|
|
+ 16 * 1024);
|
|
|
+ cpu_data(cpuid).dcache_line_size =
|
|
|
+ of_getintprop_default(dp, "l1-dcache-line-size",
|
|
|
+ 32);
|
|
|
+ cpu_data(cpuid).icache_size =
|
|
|
+ of_getintprop_default(dp, "l1-icache-size",
|
|
|
+ 8 * 1024);
|
|
|
+ cpu_data(cpuid).icache_line_size =
|
|
|
+ of_getintprop_default(dp, "l1-icache-line-size",
|
|
|
+ 32);
|
|
|
+ cpu_data(cpuid).ecache_size =
|
|
|
+ of_getintprop_default(dp, "l2-cache-size", 0);
|
|
|
+ cpu_data(cpuid).ecache_line_size =
|
|
|
+ of_getintprop_default(dp, "l2-cache-line-size", 0);
|
|
|
+ if (!cpu_data(cpuid).ecache_size ||
|
|
|
+ !cpu_data(cpuid).ecache_line_size) {
|
|
|
cpu_data(cpuid).ecache_size =
|
|
|
- of_getintprop_default(dp, "ecache-size",
|
|
|
+ of_getintprop_default(portid_parent,
|
|
|
+ "l2-cache-size",
|
|
|
(4 * 1024 * 1024));
|
|
|
cpu_data(cpuid).ecache_line_size =
|
|
|
- of_getintprop_default(dp, "ecache-line-size", 64);
|
|
|
-
|
|
|
- cpu_data(cpuid).core_id = 0;
|
|
|
- cpu_data(cpuid).proc_id = -1;
|
|
|
+ of_getintprop_default(portid_parent,
|
|
|
+ "l2-cache-line-size", 64);
|
|
|
}
|
|
|
|
|
|
+ cpu_data(cpuid).core_id = portid + 1;
|
|
|
+ cpu_data(cpuid).proc_id = portid;
|
|
|
#ifdef CONFIG_SMP
|
|
|
- set_cpu_present(cpuid, true);
|
|
|
- set_cpu_possible(cpuid, true);
|
|
|
+ sparc64_multi_core = 1;
|
|
|
#endif
|
|
|
+ } else {
|
|
|
+ cpu_data(cpuid).dcache_size =
|
|
|
+ of_getintprop_default(dp, "dcache-size", 16 * 1024);
|
|
|
+ cpu_data(cpuid).dcache_line_size =
|
|
|
+ of_getintprop_default(dp, "dcache-line-size", 32);
|
|
|
+
|
|
|
+ cpu_data(cpuid).icache_size =
|
|
|
+ of_getintprop_default(dp, "icache-size", 16 * 1024);
|
|
|
+ cpu_data(cpuid).icache_line_size =
|
|
|
+ of_getintprop_default(dp, "icache-line-size", 32);
|
|
|
+
|
|
|
+ cpu_data(cpuid).ecache_size =
|
|
|
+ of_getintprop_default(dp, "ecache-size",
|
|
|
+ (4 * 1024 * 1024));
|
|
|
+ cpu_data(cpuid).ecache_line_size =
|
|
|
+ of_getintprop_default(dp, "ecache-line-size", 64);
|
|
|
+
|
|
|
+ cpu_data(cpuid).core_id = 0;
|
|
|
+ cpu_data(cpuid).proc_id = -1;
|
|
|
}
|
|
|
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+void __init of_fill_in_cpu_data(void)
|
|
|
+{
|
|
|
+ if (tlb_type == hypervisor)
|
|
|
+ return;
|
|
|
+
|
|
|
+ of_populate_present_mask();
|
|
|
+ of_iterate_over_cpus(fill_in_one_cpu, 0);
|
|
|
+
|
|
|
smp_fill_in_sib_core_maps();
|
|
|
}
|
|
|
|