summaryrefslogtreecommitdiffstats
path: root/sys/sparc64/include
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2005-04-16 14:57:38 +0000
committermarius <marius@FreeBSD.org>2005-04-16 14:57:38 +0000
commitfe74973b3947717b73a1df5e1e8b073e53ff3d86 (patch)
tree91862a3a1c8f4523c5187cef8726bea0da9e1f6a /sys/sparc64/include
parentf6ff285bc8587aaf4f40794b74acb98f6222a997 (diff)
downloadFreeBSD-src-fe74973b3947717b73a1df5e1e8b073e53ff3d86.zip
FreeBSD-src-fe74973b3947717b73a1df5e1e8b073e53ff3d86.tar.gz
- Add a workaround for a bug in BlackBird CPUs (said to be part of the
SpitFire erratum #54) which can cause writes to the TICK_CMPR register to fail. This seems to fix the dying clocks problem reported by jhb@ and kris@. [1] - In tick_start() don't reset the tick counter of the boot processor to zero. It's initially reset in _start() and afterwards but _before_ tick_start() is called on the BSP the APs synchronise with the tick counter of the BSP in mp_startup(). Resetting the tick counter of the BSP in tick_start() probably also was the cause of problems seen when using the CPU tick counter as timecounter on SMP machines. Not resetting the tick counter of the BSP in mp_startup() makes the tick counters and tick interrupts between the BSP and APs be pretty much in sync as it's supposed to be. This also means there's no longer a real reason to have separate tick_start() and tick_start_ap() so merge them and zap tick_start_ap(). This is also a first step in simplifying the interface to the tick counters in preparation to use alternate clock hardware where available. - Switch to the algorithm used on FreeBSD/ia64 for updating the tick interrupt register and which compensates the clock drift caused by varying delays between when the tick interrupts actually trigger and when they are serviced. Not compensating the clock drift mainly hurts interactive performance especially when using WITNESS. [2] For further information about the algorithm also see the commit log of sys/ia64/ia64/interrupt.c rev. 1.38. On sparc64 the sysctls for monitoring the behaviour of the tick interrupts are machdep.tick.adjust_edges, machdep.tick.adjust_excess, machdep.tick.adjust_missed and machdep.tick.adjust_ticks. - In tick_init() just use tick_stop() for stopping the tick interrupts until a proper handler is set up later. This also stops the system tick interrupt on USIII systems earlier. - In tick_start() check for a rough upper limit of HZ. - Some minor changes, e.g. use FBSDID, remove unused headers, etc. Info obtained from: Linux [1] Ok'ed by: marcel [2] Additional testing by: kris (earlier version of the workaround), jhb X-MFC after: 3 days [1]
Diffstat (limited to 'sys/sparc64/include')
-rw-r--r--sys/sparc64/include/cpufunc.h17
-rw-r--r--sys/sparc64/include/pcpu.h2
-rw-r--r--sys/sparc64/include/tick.h9
3 files changed, 20 insertions, 8 deletions
diff --git a/sys/sparc64/include/cpufunc.h b/sys/sparc64/include/cpufunc.h
index 763741d..fc50e20 100644
--- a/sys/sparc64/include/cpufunc.h
+++ b/sys/sparc64/include/cpufunc.h
@@ -171,6 +171,23 @@ int fasword32(u_long asi, void *addr, uint32_t *val);
: : "r" (val), "rI" (xor)); \
} while (0)
+/*
+ * Macro intended to be used instead of wr(asr23, val, xor) for writing to
+ * the TICK_CMPR register in order to avoid a bug in BlackBird CPUs that
+ * can cause these writes to fail under certain condidtions which in turn
+ * causes the hardclock to stop. The workaround is to perform the write
+ * at the beginning of an I-Cache line directly followed by a dummy read.
+ */
+#define wrtickcmpr(val, xor) ({ \
+ __asm __volatile( \
+ " ba,pt %%xcc, 1f ; " \
+ " nop ; " \
+ " .align 64 ; " \
+ "1: wr %0, %1, %%asr23 ; " \
+ " rd %%asr23, %%g0 ; " \
+ : : "r" (val), "rI" (xor)); \
+})
+
static __inline void
breakpoint(void)
{
diff --git a/sys/sparc64/include/pcpu.h b/sys/sparc64/include/pcpu.h
index b854921..4e025c1 100644
--- a/sys/sparc64/include/pcpu.h
+++ b/sys/sparc64/include/pcpu.h
@@ -51,6 +51,8 @@ struct pmap;
struct intr_request *pc_irfree; \
struct pmap *pc_pmap; \
vm_offset_t pc_addr; \
+ u_long pc_tickref; \
+ u_long pc_tickadj; \
u_int pc_mid; \
u_int pc_node; \
u_int pc_tlb_ctx; \
diff --git a/sys/sparc64/include/tick.h b/sys/sparc64/include/tick.h
index e317bd8..8586a0d 100644
--- a/sys/sparc64/include/tick.h
+++ b/sys/sparc64/include/tick.h
@@ -29,15 +29,8 @@
#ifndef _MACHINE_TICK_H_
#define _MACHINE_TICK_H_
-typedef void tick_func_t(struct clockframe *);
-
void tick_init(u_long clock);
-void tick_start(tick_func_t *func);
-#ifdef SMP
-void tick_start_ap(void);
-#endif
+void tick_start(void);
void tick_stop(void);
-tick_func_t tick_hardclock;
-
#endif
OpenPOWER on IntegriCloud