diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2010-05-19 13:10:25 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2010-05-19 13:10:25 +0000 |
commit | b55cd01222e32683cdbcdc39fad006e485e69535 (patch) | |
tree | 2c029e5c9d7b805eb91432322c23a693bd1399a1 /sys | |
parent | a5b90350387baa303cd9c624c294afc310b07e50 (diff) |
Spin up secondary CPUs on hppa multiprocessor kernels. At this stage we
enable clock interrupts, however do not allow processes to be scheduled
onto the secondary CPUs - hopefully we can change this shortly...
ok kettenis@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/hppa/dev/cpu.c | 111 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/genassym.cf | 3 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/locore.S | 136 | ||||
-rw-r--r-- | sys/arch/hppa/include/cpu.h | 10 |
4 files changed, 252 insertions, 8 deletions
diff --git a/sys/arch/hppa/dev/cpu.c b/sys/arch/hppa/dev/cpu.c index 932da910220..262b8a989b1 100644 --- a/sys/arch/hppa/dev/cpu.c +++ b/sys/arch/hppa/dev/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.33 2010/05/06 14:51:30 jsing Exp $ */ +/* $OpenBSD: cpu.c,v 1.34 2010/05/19 13:10:24 jsing Exp $ */ /* * Copyright (c) 1998-2003 Michael Shalayeff @@ -31,6 +31,8 @@ #include <sys/device.h> #include <sys/reboot.h> +#include <uvm/uvm_extern.h> + #include <machine/cpufunc.h> #include <machine/pdc.h> #include <machine/reg.h> @@ -41,10 +43,13 @@ struct cpu_softc { struct device sc_dev; - - hppa_hpa_t sc_hpa; }; +#ifdef MULTIPROCESSOR +struct cpu_info *cpu_hatch_info; +static volatile int start_secondary_cpu; +#endif + int cpumatch(struct device *, void *, void *); void cpuattach(struct device *, struct device *, void *); @@ -160,5 +165,105 @@ cpuattach(struct device *parent, struct device *self, void *aux) void cpu_boot_secondary_processors(void) { + struct cpu_info *ci; + struct iomod *cpu; + struct pglist mlist; + struct vm_page *m; + int error, i, j; + + /* Initialise primary CPU. */ + ci = curcpu(); + ci->ci_flags |= CPUF_RUNNING; + + for (i = 0; i < HPPA_MAXCPUS; i++) { + + ci = &cpu_info[i]; + if (ci->ci_cpuid == 0) + continue; + + ci->ci_randseed = random(); + +#ifdef notyet + sched_init_cpu(ci); +#endif + + /* Allocate spinup stack. */ + TAILQ_INIT(&mlist); + error = uvm_pglistalloc(PAGE_SIZE, 0, -1L, 0, 0, &mlist, 1, + UVM_PLA_NOWAIT); + if (error) { + printf("unable to allocate spinup stack!\n"); + return; + } + m = TAILQ_FIRST(&mlist); + ci->ci_spinup_stack = VM_PAGE_TO_PHYS(m); + + /* Release the specified CPU by triggering an EIR{0}. */ + cpu_hatch_info = ci; + cpu = (struct iomod *)(ci->ci_hpa); + cpu->io_eir = 0; + asm volatile ("sync" ::: "memory"); + + /* Wait for CPU to wake up... */ + j = 0; + while (!(ci->ci_flags & CPUF_RUNNING) && j++ < 10000) + delay(1000); + if (!(ci->ci_flags & CPUF_RUNNING)) + printf("failed to hatch cpu %i!\n", ci->ci_cpuid); + } + + /* Release secondary CPUs. */ + start_secondary_cpu = 1; + asm volatile ("sync" ::: "memory"); +} + +void +cpu_hw_init(void) +{ + struct cpu_info *ci = curcpu(); + + /* Purge TLB and flush caches. */ + ptlball(); + ficacheall(); + fdcacheall(); + + /* Enable address translations. */ + ci->ci_psw = PSL_I | PSL_Q | PSL_P | PSL_C | PSL_D; + ci->ci_psw |= (cpu_info[0].ci_psw & PSL_O); +} + +void +cpu_hatch(void) +{ + struct cpu_info *ci = curcpu(); + extern u_long cpu_hzticks; + u_long itmr; + + /* Initialise clock. */ + mtctl((1 << 31), CR_EIRR); + mfctl(CR_ITMR, itmr); + ci->ci_itmr = itmr; + itmr += cpu_hzticks; + mtctl(itmr, CR_ITMR); + ci->ci_mask |= (1 << 31); + + /* Enable interrupts. */ + mtctl(ci->ci_mask, CR_EIEM); + +#ifdef notyet + ncpus++; +#endif + ci->ci_flags |= CPUF_RUNNING; + + /* Wait for additional CPUs to spinup. */ + while (!start_secondary_cpu) + ; + + for (;;) ; + +#ifdef notyet + SCHED_LOCK(s); + cpu_switchto(NULL, sched_chooseproc()); +#endif } #endif diff --git a/sys/arch/hppa/hppa/genassym.cf b/sys/arch/hppa/hppa/genassym.cf index e875dea0d54..1f4617ac2be 100644 --- a/sys/arch/hppa/hppa/genassym.cf +++ b/sys/arch/hppa/hppa/genassym.cf @@ -1,4 +1,4 @@ -# $OpenBSD: genassym.cf,v 1.37 2010/05/16 14:54:43 jsing Exp $ +# $OpenBSD: genassym.cf,v 1.38 2010/05/19 13:10:24 jsing Exp $ # # Copyright (c) 1982, 1990, 1993 @@ -158,6 +158,7 @@ member fpswtch struct cpu_info member ci_curproc +member ci_spinup_stack member ci_psw member ci_cpl member ci_ipending diff --git a/sys/arch/hppa/hppa/locore.S b/sys/arch/hppa/hppa/locore.S index faec9089ef0..f8d87cba87b 100644 --- a/sys/arch/hppa/hppa/locore.S +++ b/sys/arch/hppa/hppa/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.169 2010/05/16 14:54:43 jsing Exp $ */ +/* $OpenBSD: locore.S,v 1.170 2010/05/19 13:10:24 jsing Exp $ */ /* * Copyright (c) 1998-2004 Michael Shalayeff @@ -213,6 +213,14 @@ $start_zero_tf ldo R%cpu_info(r1), r1 mtctl r1, cr29 +#ifdef MULTIPROCESSOR + /* Setup SMP rendezvous address. */ + ldil L%hw_cpu_spinup_trampoline, r1 + ldo R%hw_cpu_spinup_trampoline(r1), r1 + stw r1, 0x10(0) /* MEM_RENDEZ */ + stw r0, 0x28(0) /* MEM_RENDEZ */ +#endif + copy sp, arg1 ldil L%$qisnowon, rp ldo R%$qisnowon(rp), rp @@ -2914,6 +2922,132 @@ ENTRY(switch_trampoline,0) ldw P_MD_REGS(t2), t3 EXIT(switch_trampoline) +#ifdef MULTIPROCESSOR +/* + * Trampoline to spin up secondary processors. + */ +ENTRY(hw_cpu_spinup_trampoline, 0) + + /* + * disable interrupts and turn off all bits in the psw so that + * we start in a known state. + */ + rsm RESET_PSL, r0 + nop ! nop ! nop ! nop ! nop ! nop + + /* get things ready for the kernel to run in virtual mode */ + ldi HPPA_PID_KERNEL, r1 + mtctl r1, pidr1 + mtctl r1, pidr2 +#if pbably_not_worth_it + mtctl r0, pidr3 + mtctl r0, pidr4 +#endif + mtsp r0, sr0 + mtsp r0, sr1 + mtsp r0, sr2 + mtsp r0, sr3 + mtsp r0, sr4 + mtsp r0, sr5 + mtsp r0, sr6 + mtsp r0, sr7 + + /* + * disable all coprocessors + */ + mtctl r0, ccr + + /* + * to keep the spl() routines consistent we need to put the correct + * spl level into eiem, and reset any pending interrupts + */ + ldi -1, r1 + mtctl r0, eiem + mtctl r1, eirr + + /* + * load address of interrupt vector table + */ + ldil L%$ivaaddr, t2 + ldo R%$ivaaddr(t2), t2 + mtctl t2, iva + + /* + * set up the dp pointer so that we can do quick references off of it + */ + ldil L%$global$,dp + ldo R%$global$(dp),dp + + /* + * Store address of cpu_info in CR29. + */ + ldil L%cpu_hatch_info, r3 + ldw R%cpu_hatch_info(r3), r3 + mtctl r3, cr29 + + /* + * Setup the stack frame for us to call C with and mark this as the + * first frame on the stack. + */ + ldw CI_SPINUP_STACK(r3), sp + stw,ma r0, HPPA_FRAME_SIZE(sp) + stw r0, HPPA_FRAME_CRP(sp) + stw r0, HPPA_FRAME_PSP(sp) + + /* Provide CPU with page tables. */ + ldil L%hppa_vtop, t1 + ldw R%hppa_vtop(t1), t1 + mtctl t1, CR_VTOP + + /* Turn on the Q bit so that we can handle TLB traps. */ + ldil L%$q_enabled, t1 + ldo R%$q_enabled(t1), t1 + mtctl r0, pcsq + mtctl r0, pcsq + mtctl t1, pcoq + ldo 4(t1), t1 + mtctl t1, pcoq + ldi PSL_Q|PSL_I, t2 + mtctl t2, ipsw + rfi + nop + +$q_enabled + + /* Call C routine to setup CPU. */ + ldil L%cpu_hw_init, r1 + ldo R%cpu_hw_init(r1), r1 + .import cpu_hw_init, code + .call + blr r0, rp + bv,n (r1) + nop + + /* Switch CPU mode. */ + ldil L%$cpu_spinup_vm, t1 + ldo R%$cpu_spinup_vm(t1), t1 + mtctl r0, pcsq + mtctl r0, pcsq + mtctl t1, pcoq + ldo 4(t1), t1 + mtctl t1, pcoq + mfctl cr29, t2 + ldw CI_PSW(t2), t2 + mtctl t2, ipsw + rfi + nop + +$cpu_spinup_vm + + /* + * Okay, time to return to the land of C. + */ + b cpu_hatch + nop + +EXIT(hw_cpu_spinup_trampoline) +#endif + /* * Signal "trampoline" code. Invoked from RTE setup by sendsig(). */ diff --git a/sys/arch/hppa/include/cpu.h b/sys/arch/hppa/include/cpu.h index 40b3af0414b..c404b0bf859 100644 --- a/sys/arch/hppa/include/cpu.h +++ b/sys/arch/hppa/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.70 2010/05/16 14:54:43 jsing Exp $ */ +/* $OpenBSD: cpu.h,v 1.71 2010/05/19 13:10:24 jsing Exp $ */ /* * Copyright (c) 2000-2004 Michael Shalayeff @@ -79,8 +79,10 @@ struct cpu_info { struct device *ci_dev; int ci_cpuid; hppa_hpa_t ci_hpa; + volatile int ci_flags; struct proc *ci_curproc; + paddr_t ci_spinup_stack; register_t ci_psw; /* Processor Status Word. */ volatile int ci_cpl; @@ -94,10 +96,12 @@ struct cpu_info { u_int32_t ci_randseed; } __attribute__((__aligned__(64))); +#define CPUF_RUNNING 0x0001 /* CPU is running. */ + #ifdef MULTIPROCESSOR -#define HPPA_MAXCPUS 1 +#define HPPA_MAXCPUS 4 #else -#define HPPA_MAXCPUS 4 +#define HPPA_MAXCPUS 1 #endif extern struct cpu_info cpu_info[HPPA_MAXCPUS]; |