summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2012-11-07 16:31:04 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2012-11-07 16:31:04 +0000
commitac5c96089423c8d16cf4ef2364772f2ae2a332d6 (patch)
tree9f77cfb67337d63b3ff27bccf6488d0eb65490fe /sys/arch
parent538928de389c7c17af8cb6d465004e6e014899aa (diff)
Enable %tick access for userland on sun4u systems (sun4v systems already have
this enabled). ok pirofti@, mikeb@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/sparc64/include/ctlreg.h4
-rw-r--r--sys/arch/sparc64/sparc64/cpu.c8
-rw-r--r--sys/arch/sparc64/sparc64/locore.s30
3 files changed, 38 insertions, 4 deletions
diff --git a/sys/arch/sparc64/include/ctlreg.h b/sys/arch/sparc64/include/ctlreg.h
index a451e2ce00f..c1cd7411f16 100644
--- a/sys/arch/sparc64/include/ctlreg.h
+++ b/sys/arch/sparc64/include/ctlreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ctlreg.h,v 1.24 2012/08/29 20:33:16 kettenis Exp $ */
+/* $OpenBSD: ctlreg.h,v 1.25 2012/11/07 16:31:03 kettenis Exp $ */
/* $NetBSD: ctlreg.h,v 1.28 2001/08/06 23:55:34 eeh Exp $ */
/*
@@ -738,6 +738,8 @@ void flush(void *p)
#define sys_tick() (sparc_rd(sys_tick) & TICK_TICKS)
extern u_int64_t stick(void);
+extern void tick_enable(void);
+
extern void tickcmpr_set(u_int64_t);
extern void sys_tickcmpr_set(u_int64_t);
extern void stickcmpr_set(u_int64_t);
diff --git a/sys/arch/sparc64/sparc64/cpu.c b/sys/arch/sparc64/sparc64/cpu.c
index 29ee24bb25d..be40e9ff51e 100644
--- a/sys/arch/sparc64/sparc64/cpu.c
+++ b/sys/arch/sparc64/sparc64/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.57 2012/09/08 20:58:50 kettenis Exp $ */
+/* $OpenBSD: cpu.c,v 1.58 2012/11/07 16:31:03 kettenis Exp $ */
/* $NetBSD: cpu.c,v 1.13 2001/05/26 21:27:15 chs Exp $ */
/*
@@ -431,10 +431,14 @@ cpu_init(struct cpu_info *ci)
#ifdef SUN4V
paddr_t pa = ci->ci_paddr;
int err;
+#endif
- if (CPU_ISSUN4U || CPU_ISSUN4US)
+ if (CPU_ISSUN4U || CPU_ISSUN4US) {
+ tick_enable();
return;
+ }
+#ifdef SUN4V
#define MONDO_QUEUE_SIZE 32
#define QUEUE_ENTRY_SIZE 64
diff --git a/sys/arch/sparc64/sparc64/locore.s b/sys/arch/sparc64/sparc64/locore.s
index a65518e3f67..2d8531f7196 100644
--- a/sys/arch/sparc64/sparc64/locore.s
+++ b/sys/arch/sparc64/sparc64/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.167 2012/11/06 21:39:02 kettenis Exp $ */
+/* $OpenBSD: locore.s,v 1.168 2012/11/07 16:31:03 kettenis Exp $ */
/* $NetBSD: locore.s,v 1.137 2001/08/13 06:10:10 jdolecek Exp $ */
/*
@@ -8916,6 +8916,34 @@ ENTRY(write_user_windows)
nop
/*
+ * Clear the Nonpriviliged Trap (NPT( bit of %tick such that it can be
+ * read from userland. This requires us to read the current value and
+ * write it back with the bit cleared. As a result we will lose a
+ * couple of ticks. In order to limit the number of lost ticks, we
+ * block interrupts and make sure the instructions to read and write
+ * %tick live in the same cache line. We tag on an extra read to work
+ * around a Blackbird (UltraSPARC-II) errata (see below).
+ */
+ENTRY(tick_enable)
+ rdpr %pstate, %o0
+ andn %o0, PSTATE_IE, %o1
+ wrpr %o1, 0, %pstate ! disable interrupts
+ rdpr %tick, %o2
+ brgez,pn %o2, 1f
+ clr %o1
+ mov 1, %o1
+ sllx %o1, 63, %o1
+ ba,pt %xcc, 1f
+ nop
+ .align 64
+1: rdpr %tick, %o2
+ wrpr %o2, %o1, %tick
+ rdpr %tick, %g0
+
+ retl
+ wrpr %o0, 0, %pstate ! restore interrupts
+
+/*
* 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 those two instructions are in the same cache line.