diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2008-03-15 22:05:52 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2008-03-15 22:05:52 +0000 |
commit | 1242880058859866013326194c53687136409597 (patch) | |
tree | eba0f6a196a0f89d1c0964945545644ac5c8c6b4 | |
parent | 50316be7bf1b3797fd1196f7cdac27a1a2fa905c (diff) |
Make GENERIC.MP work on the e10k. The e10k is a bit funky since UPA only
supports 32 ports, and a machine with up to 64 CPUs obviously needs more.
So the machine has a special ASIC that does port translation, and because
of that we need to distinguish between port ID's and interrupt target ID's.
-rw-r--r-- | sys/arch/sparc64/include/cpu.h | 7 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/cpu.c | 29 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/ipifuncs.c | 16 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/pmap.c | 4 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/vm_machdep.c | 4 |
5 files changed, 45 insertions, 15 deletions
diff --git a/sys/arch/sparc64/include/cpu.h b/sys/arch/sparc64/include/cpu.h index a78e72b34c8..424d67ed523 100644 --- a/sys/arch/sparc64/include/cpu.h +++ b/sys/arch/sparc64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.55 2008/02/20 09:44:47 robert Exp $ */ +/* $OpenBSD: cpu.h,v 1.56 2008/03/15 22:05:51 kettenis Exp $ */ /* $NetBSD: cpu.h,v 1.28 2001/06/14 22:56:58 thorpej Exp $ */ /* @@ -115,6 +115,9 @@ struct cpu_info { int ci_number; int ci_flags; int ci_upaid; +#ifdef MULTIPROCESSOR + int ci_itid; +#endif int ci_node; struct schedstate_percpu ci_schedstate; /* scheduler state */ @@ -213,6 +216,8 @@ extern void need_resched(struct cpu_info *); void signotify(struct proc *); +/* cpu.c */ +int cpu_myid(void); /* machdep.c */ int ldcontrolb(caddr_t); void dumpconf(void); diff --git a/sys/arch/sparc64/sparc64/cpu.c b/sys/arch/sparc64/sparc64/cpu.c index d96930d149d..4944d57f1a5 100644 --- a/sys/arch/sparc64/sparc64/cpu.c +++ b/sys/arch/sparc64/sparc64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.33 2007/12/21 12:15:36 kettenis Exp $ */ +/* $OpenBSD: cpu.c,v 1.34 2008/03/15 22:05:51 kettenis Exp $ */ /* $NetBSD: cpu.c,v 1.13 2001/05/26 21:27:15 chs Exp $ */ /* @@ -363,6 +363,18 @@ cpu_attach(parent, dev, aux) } } +int +cpu_myid(void) +{ + char buf[32]; + + if (OF_getprop(findroot(), "name", buf, sizeof(buf)) > 0 && + strcmp(buf, "SUNW,Ultra-Enterprise-10000") == 0) + return lduwa(0x1fff40000d0UL, ASI_PHYS_NON_CACHED); + else + return CPU_UPAID; +} + struct cfdriver cpu_cd = { NULL, "cpu", DV_DULL }; @@ -370,14 +382,27 @@ struct cfdriver cpu_cd = { #ifdef MULTIPROCESSOR void cpu_mp_startup(void); +#define STARFIRE_UPAID2HWMID(upaid) \ + (((upaid & 0x3c) << 1) | ((upaid & 0x40) >> 4) | (upaid & 0x3)) + void cpu_boot_secondary_processors(void) { struct cpu_info *ci; int cpuid, i; + char buf[32]; + + if (OF_getprop(findroot(), "name", buf, sizeof(buf)) > 0 && + strcmp(buf, "SUNW,Ultra-Enterprise-10000") == 0) { + for (ci = cpus; ci != NULL; ci = ci->ci_next) + ci->ci_itid = STARFIRE_UPAID2HWMID(ci->ci_upaid); + } else { + for (ci = cpus; ci != NULL; ci = ci->ci_next) + ci->ci_itid = ci->ci_upaid; + } for (ci = cpus; ci != NULL; ci = ci->ci_next) { - if (ci->ci_upaid == CPU_UPAID) + if (ci->ci_upaid == cpu_myid()) continue; cpuid = getpropint(ci->ci_node, "cpuid", -1); diff --git a/sys/arch/sparc64/sparc64/ipifuncs.c b/sys/arch/sparc64/sparc64/ipifuncs.c index 5e48180231e..cddbcac4d8f 100644 --- a/sys/arch/sparc64/sparc64/ipifuncs.c +++ b/sys/arch/sparc64/sparc64/ipifuncs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipifuncs.c,v 1.6 2007/11/27 19:00:26 kettenis Exp $ */ +/* $OpenBSD: ipifuncs.c,v 1.7 2008/03/15 22:05:51 kettenis Exp $ */ /* $NetBSD: ipifuncs.c,v 1.8 2006/10/07 18:11:36 rjs Exp $ */ /*- @@ -60,7 +60,7 @@ void ipi_softint(void); * Send an interprocessor interrupt. */ void -sparc64_send_ipi(int upaid, void (*func)(void), u_int64_t arg0, u_int64_t arg1) +sparc64_send_ipi(int itid, void (*func)(void), u_int64_t arg0, u_int64_t arg1) { int i, j, shift = 0; @@ -68,10 +68,10 @@ sparc64_send_ipi(int upaid, void (*func)(void), u_int64_t arg0, u_int64_t arg1) /* * UltraSPARC-IIIi CPUs select the BUSY/NACK pair based on the - * lower two bits of the target CPU ID. + * lower two bits of the ITID. */ if (((getver() & VER_IMPL) >> VER_IMPL_SHIFT) == IMPL_JALAPENO) - shift = (upaid & 0x3) * 2; + shift = (itid & 0x3) * 2; if (ldxa(0, ASR_IDSR) & (IDSR_BUSY << shift)) { __asm __volatile("ta 1; nop"); @@ -84,7 +84,7 @@ sparc64_send_ipi(int upaid, void (*func)(void), u_int64_t arg0, u_int64_t arg1) stxa(IDDR_0H, ASI_INTERRUPT_DISPATCH, (u_int64_t)func); stxa(IDDR_1H, ASI_INTERRUPT_DISPATCH, arg0); stxa(IDDR_2H, ASI_INTERRUPT_DISPATCH, arg1); - stxa(IDCR(upaid), ASI_INTERRUPT_DISPATCH, 0); + stxa(IDCR(itid), ASI_INTERRUPT_DISPATCH, 0); membar(Sync); for (j = 0; j < 1000000; j++) { @@ -104,7 +104,7 @@ sparc64_send_ipi(int upaid, void (*func)(void), u_int64_t arg0, u_int64_t arg1) #if 1 if (db_active || panicstr != NULL) - printf("ipi_send: couldn't send ipi to module %u\n", upaid); + printf("ipi_send: couldn't send ipi to module %u\n", itid); else panic("ipi_send: couldn't send ipi"); #else @@ -125,7 +125,7 @@ sparc64_broadcast_ipi(void (*func)(void), u_int64_t arg0, u_int64_t arg1) continue; if ((ci->ci_flags & CPUF_RUNNING) == 0) continue; - sparc64_send_ipi(ci->ci_upaid, func, arg0, arg1); + sparc64_send_ipi(ci->ci_itid, func, arg0, arg1); } } @@ -157,5 +157,5 @@ smp_signotify(struct proc *p) if (db_active) return; - sparc64_send_ipi(p->p_cpu->ci_upaid, ipi_softint, 1 << IPL_NONE, 0UL); + sparc64_send_ipi(p->p_cpu->ci_itid, ipi_softint, 1 << IPL_NONE, 0UL); } diff --git a/sys/arch/sparc64/sparc64/pmap.c b/sys/arch/sparc64/sparc64/pmap.c index de7f0c7bca6..96e1685be8c 100644 --- a/sys/arch/sparc64/sparc64/pmap.c +++ b/sys/arch/sparc64/sparc64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.50 2008/01/10 20:37:14 marco Exp $ */ +/* $OpenBSD: pmap.c,v 1.51 2008/03/15 22:05:51 kettenis Exp $ */ /* $NetBSD: pmap.c,v 1.107 2001/08/31 16:47:41 eeh Exp $ */ #undef NO_VCACHE /* Don't forget the locked TLB in dostart */ /* @@ -1376,7 +1376,7 @@ remap_data: cpus->ci_next = NULL; /* Redundant, I know. */ cpus->ci_curproc = &proc0; cpus->ci_cpcb = (struct pcb *)u0[0]; /* Need better source */ - cpus->ci_upaid = CPU_UPAID; + cpus->ci_upaid = cpu_myid(); cpus->ci_number = 0; cpus->ci_flags = CPUF_RUNNING; cpus->ci_fpproc = NULL; diff --git a/sys/arch/sparc64/sparc64/vm_machdep.c b/sys/arch/sparc64/sparc64/vm_machdep.c index 7437fb50ae2..4e940cd1bde 100644 --- a/sys/arch/sparc64/sparc64/vm_machdep.c +++ b/sys/arch/sparc64/sparc64/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.23 2008/01/04 00:40:38 kettenis Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.24 2008/03/15 22:05:51 kettenis Exp $ */ /* $NetBSD: vm_machdep.c,v 1.38 2001/06/30 00:02:20 eeh Exp $ */ /* @@ -348,7 +348,7 @@ fpusave_proc(struct proc *p, int save) continue; if (ci->ci_fpproc != p) continue; - sparc64_send_ipi(ci->ci_upaid, + sparc64_send_ipi(ci->ci_itid, save ? ipi_save_fpstate : ipi_drop_fpstate, (vaddr_t)p, 0); while(ci->ci_fpproc == p) { spincount++; |