diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2007-11-16 16:20:56 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2007-11-16 16:20:56 +0000 |
commit | 2efdbb6d7b0119aac1d68d76bfaf2970511fa56f (patch) | |
tree | 4187190514cc6cc63edc44610a4bfa426bc4bec0 /sys/arch | |
parent | 32922227664108ea3bdf3840415d46ecd47b6c33 (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.c | 17 |
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; } |