[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [XenPPC] [PATCH/RFC] Run C code that inits HID registers from secondary procs
This patch gets things to the point that each secondary processor can call the same C routine that the primary processor did to invalidate the segment table and initialize the HID registers. It prints the following and boots up to nfsroot on a JS21 blade: (XEN) CPU #1 is waiting for a stack ... (XEN) CPU #1: Hello World! (XEN) CPU #1: stack is here: 000000000376c000 (XEN) CPU #1: hid0: 0x0051118180000000 (XEN) CPU #2 is waiting for a stack ... (XEN) CPU #2: Hello World! (XEN) CPU #2: stack is here: 0000000000070000 (XEN) CPU #2: hid0: 0x0051118180000000 (XEN) CPU #3 is waiting for a stack ... (XEN) CPU #3: Hello World! (XEN) CPU #3: stack is here: 000000000006c000 (XEN) CPU #3: hid0: 0x0051118180000000 The logic needs a lot of cleanup, but right now I am worrying about whether we need one idle domain per processor. We surely can't do this from more than one processor ... set_current(idle_domain->vcpu[0]); idle_vcpu[0] = current; Any comments would be appreciated. --- arch/powerpc/boot_of.c | 70 ++++++++++++++++++++++++++++++++---- arch/powerpc/of-devtree.h | 7 +++ arch/powerpc/powerpc64/exceptions.S | 38 +++++++++++++++++++ arch/powerpc/powerpc64/ppc970.c | 7 ++- arch/powerpc/setup.c | 35 +++++++++++++++++- include/asm-powerpc/config.h | 2 - include/asm-powerpc/processor.h | 2 - 7 files changed, 149 insertions(+), 12 deletions(-) diff -r bb510c274af8 xen/arch/powerpc/boot_of.c --- a/xen/arch/powerpc/boot_of.c Fri Aug 11 13:30:48 2006 -0400 +++ b/xen/arch/powerpc/boot_of.c Fri Aug 11 21:58:19 2006 -0400 @@ -30,6 +30,9 @@ #include <asm/io.h> #include "exceptions.h" #include "of-devtree.h" + +/* Secondary processors index into this by their processor id. */ +volatile struct per_cpu __per_cpu_init[NR_CPUS]; static ulong of_vec; static ulong of_msr; @@ -926,8 +929,8 @@ static void boot_of_module(ulong r3, ulo static int __init boot_of_cpus(void) { - int cpus; - int cpu; + int i, cpus; + int cpu, bootcpu; int result; u32 cpu_clock[2]; @@ -952,10 +955,53 @@ static int __init boot_of_cpus(void) cpu_khz /= 1000; of_printf("OF: clock-frequency = %ld KHz\n", cpu_khz); - /* FIXME: should not depend on the boot CPU bring the first child */ - cpu = of_getpeer(cpu); - while (cpu > 0) { - of_start_cpu(cpu, (ulong)spin_start, 0); + /* 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"); + + for (i = 0, cpu = of_getpeer(cpu); i < NR_CPUS && cpu > 0; i++) { + unsigned int cpuid, 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: ", cpuid); + + __per_cpu_init[cpuid].sp = 0x0; + __per_cpu_init[cpuid].id = ~0x0; + ping = __per_cpu_init[cpuid].id; + pong = __per_cpu_init[cpuid].id; + of_printf("ping = 0x%x: ", ping); + + mb(); + result = of_start_cpu(cpu, (ulong)spin_start, cpuid); + 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 = __per_cpu_init[cpuid].id; + } while (pong == ping); + of_printf("pong = 0x%x\n", pong); + cpu = of_getpeer(cpu); } return 1; @@ -1003,9 +1049,21 @@ multiboot_info_t __init *boot_of_init( boot_of_rtas(); /* end of OF */ + of_printf("Quiescing Open Firmware ...\n"); of_call("quiesce", 0, 0, NULL); return &mbi; +} + +int secondary_cpu_init(int cpuid); + +int secondary_cpu_init(int cpuid) +{ + printk("CPU #%d: Hello World!\n", cpuid); + + cpu_initialize(cpuid); + + return 0; } /* diff -r bb510c274af8 xen/arch/powerpc/of-devtree.h --- a/xen/arch/powerpc/of-devtree.h Fri Aug 11 13:30:48 2006 -0400 +++ b/xen/arch/powerpc/of-devtree.h Fri Aug 11 19:55:51 2006 -0400 @@ -23,6 +23,13 @@ #include <xen/types.h> #include <public/xen.h> + +/* Data structure used by secondary processors to discover their stack. */ +struct per_cpu { + int id; + void *sp; + void *toc; +}; enum { OF_FAILURE = -1, diff -r bb510c274af8 xen/arch/powerpc/powerpc64/exceptions.S --- a/xen/arch/powerpc/powerpc64/exceptions.S Fri Aug 11 13:30:48 2006 -0400 +++ b/xen/arch/powerpc/powerpc64/exceptions.S Fri Aug 11 21:11:00 2006 -0400 @@ -514,6 +514,44 @@ _GLOBAL(sleep) mtmsrd r3 blr +/* Get these from asm-offsets, talk to Jimi about int->long alignment hole. */ +#define ID_OFFSET 0 +#define SP_OFFSET 8 +#define TC_OFFSET 16 +#define PER_CPU_SIZE 24 + +/* Firmware is told to spin up secondary processors at this address. We + * only need a function entry point instead of a descriptor since this is + * never called from C code. + */ .globl spin_start spin_start: + /* Our physical cpu number is passed in r3, so index into array. */ + muli r5, r3, PER_CPU_SIZE + LOADADDR(r27, __per_cpu_init) + add r27, r27, r5 + stw r3, ID_OFFSET(r27) + sync + /* At some point these should go in different cache lines. */ +1: ld r6, SP_OFFSET(r27) + cmpldi r6, 0 + beq 1b + /* The primary cpu has an allocator now and wants our attention. */ + li r6, 0x0 + std r6, SP_OFFSET(r27) + sync + /* Wait for the primary cpu to give us our stack address. */ +2: ld r6, SP_OFFSET(r27) + cmpldi r6, 0 + beq 2b + /* The primary cpu has allocated a stack for us, so rock and roll. */ + mr r1, r6 + ld r2, TC_OFFSET(r27) + LOADADDR(r8, .secondary_cpu_init) + mtctr r8 + bctrl + /* For now, the primary processor is waiting for us to return from C. */ + li r3, 0 + std r3, SP_OFFSET(r27) + sync b . diff -r bb510c274af8 xen/arch/powerpc/powerpc64/ppc970.c --- a/xen/arch/powerpc/powerpc64/ppc970.c Fri Aug 11 13:30:48 2006 -0400 +++ b/xen/arch/powerpc/powerpc64/ppc970.c Fri Aug 11 21:56:15 2006 -0400 @@ -37,10 +37,11 @@ unsigned int cpu_rma_order(void) return 14; /* 1<<14<<PAGE_SIZE = 64M */ } -void cpu_initialize(void) +void cpu_initialize(int cpuid) { ulong stack; + /* This is SMP safe because the compiler must use r13 for it. */ parea = xmalloc(struct processor_area); ASSERT(parea != NULL); @@ -48,7 +49,7 @@ void cpu_initialize(void) ASSERT(stack != 0); parea->hyp_stack_base = (void *)(stack + STACK_SIZE); - printk("stack is here: %p\n", parea->hyp_stack_base); + printk("CPU #%d: stack is here: %p\n", cpuid, parea->hyp_stack_base); mthsprg0((ulong)parea); /* now ready for exceptions */ @@ -78,7 +79,7 @@ void cpu_initialize(void) s |= 1UL << (63-3); /* ser-gp */ hid0.word |= s; #endif - printk("hid0: 0x%016lx\n", hid0.word); + printk("CPU #%d: hid0: 0x%016lx\n", cpuid, hid0.word); mthid0(hid0.word); union hid1 hid1; diff -r bb510c274af8 xen/arch/powerpc/setup.c --- a/xen/arch/powerpc/setup.c Fri Aug 11 13:30:48 2006 -0400 +++ b/xen/arch/powerpc/setup.c Fri Aug 11 21:55:40 2006 -0400 @@ -75,6 +75,8 @@ extern void idle_loop(void); /* move us to a header file */ extern void initialize_keytable(void); +extern volatile struct per_cpu __per_cpu_init[]; + int is_kernel_text(unsigned long addr) { if (addr >= (unsigned long) &_start && @@ -314,7 +316,7 @@ static void __init __start_xen(multiboot printk("Xen heap: %luMB (%lukB)\n", heap_size >> 20, heap_size >> 10); - cpu_initialize(); + cpu_initialize(0); #ifdef CONFIG_GDB initialise_gdb(); @@ -323,6 +325,37 @@ static void __init __start_xen(multiboot #endif start_of_day(); + + { + int i; + + for (i = 1; i <= NR_CPUS; i++) { + void *stack, *toc; + void *syn = (void *)~0x0; + + if (__per_cpu_init[i].id > 0) { + printk("CPU #%d is waiting for a stack ...\n", i); + + __per_cpu_init[i].sp = syn; + do { + mb(); + } while (__per_cpu_init[i].sp == syn); + + stack = xmalloc_bytes(STACK_SIZE); + if (stack == NULL) + panic("failed to allocate stack\n"); + + __per_cpu_init[i].sp = stack; + asm("mr %0, 2" : "=r" (toc)); + __per_cpu_init[i].toc = toc; + mb(); + + do { + mb(); + } while (__per_cpu_init[i].sp != 0x0); + } + } + } /* Create initial domain 0. */ dom0 = domain_create(0); diff -r bb510c274af8 xen/include/asm-powerpc/config.h --- a/xen/include/asm-powerpc/config.h Fri Aug 11 13:30:48 2006 -0400 +++ b/xen/include/asm-powerpc/config.h Fri Aug 11 16:56:58 2006 -0400 @@ -51,7 +51,7 @@ extern char __bss_start[]; #define CONFIG_GDB 1 #define CONFIG_SMP 1 #define CONFIG_PCI 1 -#define NR_CPUS 1 +#define NR_CPUS 6 #ifndef ELFSIZE #define ELFSIZE 64 diff -r bb510c274af8 xen/include/asm-powerpc/processor.h --- a/xen/include/asm-powerpc/processor.h Fri Aug 11 13:30:48 2006 -0400 +++ b/xen/include/asm-powerpc/processor.h Fri Aug 11 21:54:51 2006 -0400 @@ -40,7 +40,7 @@ extern void show_registers(struct cpu_us extern void show_registers(struct cpu_user_regs *); extern void show_execution_state(struct cpu_user_regs *); extern unsigned int cpu_rma_order(void); -extern void cpu_initialize(void); +extern void cpu_initialize(int cpuid); extern void cpu_init_vcpu(struct vcpu *); extern void save_cpu_sprs(struct vcpu *); extern void load_cpu_sprs(struct vcpu *); _______________________________________________ Xen-ppc-devel mailing list Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-ppc-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |