diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2008-04-15 22:39:27 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2008-04-15 22:39:27 +0000 |
commit | 0da6aaa8f71ce409bea7f0ede1f94c5e7aae31bf (patch) | |
tree | b264adf54fb2da2a3251ed2659882f7e15be9e30 /sys | |
parent | 2176dc4df557ec535a076a6d5d16bf294f08b5df (diff) |
Add workaround for UltraSPARC-II errata, where writes to %tick_cmpr would
sometimes fail, which would result in the periodic clock interrupts on a CPU
stop.
Spotted in a NetBSD commit message, loosely based on code in OpenSolaris.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/sparc64/include/ctlreg.h | 4 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/clock.c | 4 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/locore.s | 15 |
3 files changed, 18 insertions, 5 deletions
diff --git a/sys/arch/sparc64/include/ctlreg.h b/sys/arch/sparc64/include/ctlreg.h index 311eae03e47..e94320a8c8c 100644 --- a/sys/arch/sparc64/include/ctlreg.h +++ b/sys/arch/sparc64/include/ctlreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ctlreg.h,v 1.16 2008/03/08 19:46:59 kettenis Exp $ */ +/* $OpenBSD: ctlreg.h,v 1.17 2008/04/15 22:39:26 kettenis Exp $ */ /* $NetBSD: ctlreg.h,v 1.28 2001/08/06 23:55:34 eeh Exp $ */ /* @@ -718,7 +718,7 @@ void flush(void *p) /* read 64-bit %tick register */ #define tick() (sparc_rdpr(tick) & TICK_TICKS) -extern void next_tick(long); +extern void tickcmpr_set(u_int64_t); #endif /* _LOCORE */ #endif /* _SPARC64_CTLREG_ */ diff --git a/sys/arch/sparc64/sparc64/clock.c b/sys/arch/sparc64/sparc64/clock.c index 135edb0e9ac..a49332cdd02 100644 --- a/sys/arch/sparc64/sparc64/clock.c +++ b/sys/arch/sparc64/sparc64/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.39 2008/03/29 20:07:36 kettenis Exp $ */ +/* $OpenBSD: clock.c,v 1.40 2008/04/15 22:39:26 kettenis Exp $ */ /* $NetBSD: clock.c,v 1.41 2001/07/24 19:29:25 eeh Exp $ */ /* @@ -727,7 +727,7 @@ tickintr(cap) */ s = intr_disable(); base = sparc_rdpr(tick); - sparc_wr(tick_cmpr, (base + tick_increment) & TICK_TICKS, 0); + tickcmpr_set((base + tick_increment) & TICK_TICKS); level0.ih_count.ec_count++; intr_restore(s); diff --git a/sys/arch/sparc64/sparc64/locore.s b/sys/arch/sparc64/sparc64/locore.s index fd2ee1fdca1..014757e2b02 100644 --- a/sys/arch/sparc64/sparc64/locore.s +++ b/sys/arch/sparc64/sparc64/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.133 2008/04/14 21:04:56 kettenis Exp $ */ +/* $OpenBSD: locore.s,v 1.134 2008/04/15 22:39:26 kettenis Exp $ */ /* $NetBSD: locore.s,v 1.137 2001/08/13 06:10:10 jdolecek Exp $ */ /* @@ -8939,6 +8939,19 @@ _C_LABEL(cpu_clockrate): .text /* + * On Blackbird (UltraSPARC-II) CPUs, writes to %tick_cmpr may fail. + * The workaround is to do a read immediately after the write and make + * sure the same cache line. + */ +ENTRY(tickcmpr_set) + ba,a 1f + .align 64 +1: wr %o0, 0, %tick_cmpr + rd %tick_cmpr, %g0 + retl + nop + +/* * delay function * * void delay(N) -- delay N microseconds |