summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2007-11-16 16:20:56 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2007-11-16 16:20:56 +0000
commit2efdbb6d7b0119aac1d68d76bfaf2970511fa56f (patch)
tree4187190514cc6cc63edc44610a4bfa426bc4bec0 /sys/arch
parent32922227664108ea3bdf3840415d46ecd47b6c33 (diff)
UltraSPARC-IIIi CPUs are different and choose the BUSY/NACK pair based on the
target CPU ID. Make sure we check the right bits.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/sparc64/sparc64/ipifuncs.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/sys/arch/sparc64/sparc64/ipifuncs.c b/sys/arch/sparc64/sparc64/ipifuncs.c
index 2dec458c16d..75304a0aede 100644
--- a/sys/arch/sparc64/sparc64/ipifuncs.c
+++ b/sys/arch/sparc64/sparc64/ipifuncs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipifuncs.c,v 1.4 2007/10/20 16:54:52 miod Exp $ */
+/* $OpenBSD: ipifuncs.c,v 1.5 2007/11/16 16:20:55 kettenis Exp $ */
/* $NetBSD: ipifuncs.c,v 1.8 2006/10/07 18:11:36 rjs Exp $ */
/*-
@@ -62,11 +62,18 @@ void ipi_softint(void);
void
sparc64_send_ipi(int upaid, void (*func)(void), u_int64_t arg0, u_int64_t arg1)
{
- int i, j;
+ int i, j, shift = 0;
KASSERT((u_int64_t)func > MAXINTNUM);
- if (ldxa(0, ASR_IDSR) & IDSR_BUSY) {
+ /*
+ * UltraSPARC-IIIi CPUs select the BUSY/NACK pair based on the
+ * lower two bits of the target CPU ID.
+ */
+ if (((getver() & VER_IMPL) >> VER_IMPL_SHIFT) == IMPL_JALAPENO)
+ shift = (upaid & 0x3) * 2;
+
+ if (ldxa(0, ASR_IDSR) & (IDSR_BUSY << shift)) {
__asm __volatile("ta 1; nop");
}
@@ -81,7 +88,7 @@ sparc64_send_ipi(int upaid, void (*func)(void), u_int64_t arg0, u_int64_t arg1)
membar(Sync);
for (j = 0; j < 1000000; j++) {
- if (ldxa(0, ASR_IDSR) & IDSR_BUSY)
+ if (ldxa(0, ASR_IDSR) & (IDSR_BUSY << shift))
continue;
else
break;
@@ -91,7 +98,7 @@ sparc64_send_ipi(int upaid, void (*func)(void), u_int64_t arg0, u_int64_t arg1)
if (j == 1000000)
break;
- if ((ldxa(0, ASR_IDSR) & IDSR_NACK) == 0)
+ if ((ldxa(0, ASR_IDSR) & (IDSR_NACK << shift)) == 0)
return;
}