# HG changeset patch
# User Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
# Node ID eb1e4f703b8032ae4c0f9b7aa81b73c88b2affb8
# Parent 6d8e315b3d57b28da32fc8c1dfa70a9900f83746
[POWERPC][XEN] Track the Hard CPUID as configured by the FW
This patch correctly implements and supports hard_smp_processor_id().
Signed-off-by: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
---
xen/arch/powerpc/boot_of.c | 146 +++++++++++++++------------
xen/arch/powerpc/powerpc64/ppc970.c | 2
xen/arch/powerpc/setup.c | 2
xen/include/asm-powerpc/powerpc64/procarea.h | 1
xen/include/asm-powerpc/processor.h | 2
xen/include/asm-powerpc/smp.h | 4
6 files changed, 90 insertions(+), 67 deletions(-)
diff -r 6d8e315b3d57 -r eb1e4f703b80 xen/arch/powerpc/boot_of.c
--- a/xen/arch/powerpc/boot_of.c Mon Sep 18 08:14:46 2006 -0400
+++ b/xen/arch/powerpc/boot_of.c Mon Sep 18 09:23:51 2006 -0400
@@ -957,21 +957,31 @@ static void boot_of_module(ulong r3, ulo
static int __init boot_of_cpus(void)
{
- int cpus;
- int cpu, bootcpu, logical;
+ int cpus_node;
+ int cpu_node, bootcpu_node, logical;
int result;
+ s32 cpuid;
u32 cpu_clock[2];
-
- cpus = of_finddevice("/cpus");
- cpu = of_getchild(cpus);
- result = of_getprop(cpu, "timebase-frequency", &timebase_freq,
+ extern uint cpu_hard_id[NR_CPUS];
+
+ /* Look up which CPU we are running on right now and get all info
+ * from there */
+ result = of_getprop(bof_chosen, "cpu",
+ &bootcpu_node, sizeof (bootcpu_node));
+ if (result == OF_FAILURE)
+ of_panic("Failed to look up boot cpu\n");
+
+ cpu_node = bootcpu_node;
+
+ result = of_getprop(cpu_node, "timebase-frequency", &timebase_freq,
sizeof(timebase_freq));
if (result == OF_FAILURE) {
of_panic("Couldn't get timebase frequency!\n");
}
of_printf("OF: timebase-frequency = %d Hz\n", timebase_freq);
- result = of_getprop(cpu, "clock-frequency", &cpu_clock, sizeof(cpu_clock));
+ result = of_getprop(cpu_node, "clock-frequency",
+ &cpu_clock, sizeof(cpu_clock));
if (result == OF_FAILURE || (result !=4 && result != 8)) {
of_panic("Couldn't get clock frequency!\n");
}
@@ -983,69 +993,79 @@ static int __init boot_of_cpus(void)
cpu_khz /= 1000;
of_printf("OF: clock-frequency = %ld KHz\n", cpu_khz);
- /* Look up which CPU we are running on right now. */
- result = of_getprop(bof_chosen, "cpu", &bootcpu, sizeof (bootcpu));
- if (result == OF_FAILURE)
- of_panic("Failed to look up boot cpu\n");
-
- cpu = of_getpeer(cpu);
-
- /* We want a continuous logical cpu number space. */
+ /* We want a continuous logical cpu number space and we'll make
+ * the booting CPU logical 0. */
cpu_set(0, cpu_present_map);
cpu_set(0, cpu_online_map);
cpu_set(0, cpu_possible_map);
- /* Spin up all CPUS, even if there are more than NR_CPUS, because
- * Open Firmware has them spinning on cache lines which will
- * eventually be scrubbed, which could lead to random CPU activation.
+ result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid));
+ cpu_hard_id[0] = cpuid;
+
+ /* Spin up all CPUS, even if there are more than NR_CPUS or we are
+ * runnign nosmp, because Open Firmware has them spinning on cache
+ * lines which will eventually be scrubbed, which could lead to
+ * random CPU activation.
*/
- for (logical = 1; cpu > 0; logical++) {
- unsigned int cpuid, ping, pong;
+
+ /* Find the base of the multi-CPU package node */
+ cpus_node = of_finddevice("/cpus");
+ if (cpus_node <= 0) {
+ of_printf("Single Processor System\n");
+ return 1;
+ }
+ /* Start with the first child */
+ cpu_node = of_getchild(cpus_node);
+
+ for (logical = 1; cpu_node > 0; logical++) {
+ unsigned int ping, pong;
unsigned long now, then, timeout;
-
- if (cpu == bootcpu) {
- of_printf("skipping boot cpu!\n");
- continue;
- }
-
- result = of_getprop(cpu, "reg", &cpuid, sizeof(cpuid));
- if (result == OF_FAILURE)
- of_panic("cpuid lookup failed\n");
-
- of_printf("spinning up secondary processor #%d: ", logical);
-
- __spin_ack = ~0x0;
- ping = __spin_ack;
- pong = __spin_ack;
- of_printf("ping = 0x%x: ", ping);
-
- mb();
- result = of_start_cpu(cpu, (ulong)spin_start, logical);
- if (result == OF_FAILURE)
- of_panic("start cpu failed\n");
-
- /* We will give the secondary processor five seconds to reply. */
- then = mftb();
- timeout = then + (5 * timebase_freq);
-
- do {
- now = mftb();
- if (now >= timeout) {
- of_printf("BROKEN: ");
- break;
+
+ if (cpu_node == bootcpu_node) {
+ /* same CPU as boot CPU shich we have already made 0 so
+ * reduce the logical count */
+ --logical;
+ } else {
+ result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid));
+ if (result == OF_FAILURE)
+ of_panic("cpuid lookup failed\n");
+
+ cpu_hard_id[logical] = cpuid;
+
+ of_printf("spinning up secondary processor #%d: ", logical);
+
+ __spin_ack = ~0x0;
+ ping = __spin_ack;
+ pong = __spin_ack;
+ of_printf("ping = 0x%x: ", ping);
+
+ mb();
+ result = of_start_cpu(cpu_node, (ulong)spin_start, logical);
+ if (result == OF_FAILURE)
+ of_panic("start cpu failed\n");
+
+ /* We will give the secondary processor five seconds to reply. */
+ then = mftb();
+ timeout = then + (5 * timebase_freq);
+
+ do {
+ now = mftb();
+ if (now >= timeout) {
+ of_printf("BROKEN: ");
+ break;
+ }
+
+ mb();
+ pong = __spin_ack;
+ } while (pong == ping);
+ of_printf("pong = 0x%x\n", pong);
+
+ if (pong != ping) {
+ cpu_set(logical, cpu_present_map);
+ cpu_set(logical, cpu_possible_map);
}
-
- mb();
- pong = __spin_ack;
- } while (pong == ping);
- of_printf("pong = 0x%x\n", pong);
-
- if (pong != ping) {
- cpu_set(logical, cpu_present_map);
- cpu_set(logical, cpu_possible_map);
- }
-
- cpu = of_getpeer(cpu);
+ }
+ cpu_node = of_getpeer(cpu_node);
}
return 1;
}
diff -r 6d8e315b3d57 -r eb1e4f703b80 xen/arch/powerpc/powerpc64/ppc970.c
--- a/xen/arch/powerpc/powerpc64/ppc970.c Mon Sep 18 08:14:46 2006 -0400
+++ b/xen/arch/powerpc/powerpc64/ppc970.c Mon Sep 18 09:23:51 2006 -0400
@@ -145,7 +145,7 @@ void cpu_initialize(int cpuid)
mthsprg0((ulong)parea); /* now ready for exceptions */
printk("CPU[PIR:%u IPI:%u Logical:%u] Hello World!\n",
- mfpir(), raw_smp_processor_id(), smp_processor_id());
+ mfpir(), hard_smp_processor_id(), smp_processor_id());
#ifdef DEBUG
{
diff -r 6d8e315b3d57 -r eb1e4f703b80 xen/arch/powerpc/setup.c
--- a/xen/arch/powerpc/setup.c Mon Sep 18 08:14:46 2006 -0400
+++ b/xen/arch/powerpc/setup.c Mon Sep 18 09:23:51 2006 -0400
@@ -74,6 +74,7 @@ ulong oftree_len;
ulong oftree_len;
ulong oftree_end;
+uint cpu_hard_id[NR_CPUS] __initdata;
cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
cpumask_t cpu_online_map; /* missing ifdef in schedule.c */
cpumask_t cpu_present_map;
@@ -227,6 +228,7 @@ static void init_parea(int cpuid)
__func__, STACK_ORDER, cpuid);
pa->whoami = cpuid;
+ pa->hard_id = cpu_hard_id[cpuid];
pa->hyp_stack_base = (void *)((ulong)stack + STACK_SIZE);
/* This store has the effect of invoking secondary_cpu_init. */
diff -r 6d8e315b3d57 -r eb1e4f703b80
xen/include/asm-powerpc/powerpc64/procarea.h
--- a/xen/include/asm-powerpc/powerpc64/procarea.h Mon Sep 18 08:14:46
2006 -0400
+++ b/xen/include/asm-powerpc/powerpc64/procarea.h Mon Sep 18 09:23:51
2006 -0400
@@ -29,6 +29,7 @@ struct processor_area
struct processor_area
{
unsigned int whoami;
+ unsigned int hard_id;
struct vcpu *cur_vcpu;
void *hyp_stack_base;
ulong saved_regs[2];
diff -r 6d8e315b3d57 -r eb1e4f703b80 xen/include/asm-powerpc/processor.h
--- a/xen/include/asm-powerpc/processor.h Mon Sep 18 08:14:46 2006 -0400
+++ b/xen/include/asm-powerpc/processor.h Mon Sep 18 09:23:51 2006 -0400
@@ -38,7 +38,7 @@ struct vcpu;
struct vcpu;
struct cpu_user_regs;
extern int cpu_machinecheck(struct cpu_user_regs *);
-extern int cpu_scom_init(void);
+extern void cpu_scom_init(void);
extern void show_registers(struct cpu_user_regs *);
extern void show_execution_state(struct cpu_user_regs *);
extern void show_backtrace(ulong sp, ulong lr, ulong pc);
diff -r 6d8e315b3d57 -r eb1e4f703b80 xen/include/asm-powerpc/smp.h
--- a/xen/include/asm-powerpc/smp.h Mon Sep 18 08:14:46 2006 -0400
+++ b/xen/include/asm-powerpc/smp.h Mon Sep 18 09:23:51 2006 -0400
@@ -28,9 +28,9 @@ extern int smp_num_siblings;
extern int smp_num_siblings;
/* revisit when we support SMP */
-#define get_hard_smp_processor_id(i) (global_cpu_table[i]->whoami)
#define raw_smp_processor_id() (parea->whoami)
-#define hard_smp_processor_id() raw_smp_processor_id()
+#define get_hard_smp_processor_id(i) (global_cpu_table[i]->hard_id)
+#define hard_smp_processor_id() (parea->hard_id)
extern cpumask_t cpu_sibling_map[];
extern cpumask_t cpu_core_map[];
extern void __devinit smp_generic_take_timebase(void);
_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel
|