summaryrefslogtreecommitdiff
path: root/sys/arch/sparc64
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2008-03-15 22:05:52 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2008-03-15 22:05:52 +0000
commit1242880058859866013326194c53687136409597 (patch)
treeeba0f6a196a0f89d1c0964945545644ac5c8c6b4 /sys/arch/sparc64
parent50316be7bf1b3797fd1196f7cdac27a1a2fa905c (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.
Diffstat (limited to 'sys/arch/sparc64')
-rw-r--r--sys/arch/sparc64/include/cpu.h7
-rw-r--r--sys/arch/sparc64/sparc64/cpu.c29
-rw-r--r--sys/arch/sparc64/sparc64/ipifuncs.c16
-rw-r--r--sys/arch/sparc64/sparc64/pmap.c4
-rw-r--r--sys/arch/sparc64/sparc64/vm_machdep.c4
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++;