Skip to content

Commit

Permalink
sparc64: Refactor OBP cpu scanning code using an iterator.
Browse files Browse the repository at this point in the history
With feedback from Sam Ravnborg.

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jun 16, 2009
1 parent 8249778 commit 9bab541
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 109 deletions.
1 change: 1 addition & 0 deletions arch/sparc/include/asm/prom.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ extern int of_node_to_nid(struct device_node *dp);
#endif

extern void prom_build_devicetree(void);
extern void of_populate_present_mask(void);

/* Dummy ref counting routines - to be implemented later */
static inline struct device_node *of_node_get(struct device_node *node)
Expand Down
233 changes: 124 additions & 109 deletions arch/sparc/kernel/prom_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,155 +374,170 @@ 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 "
">= NR_CPUS (%d)\n",
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();
}

Expand Down

0 comments on commit 9bab541

Please sign in to comment.