summaryrefslogtreecommitdiffstats
path: root/sys/alpha
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2005-12-22 22:16:09 +0000
committerjhb <jhb@FreeBSD.org>2005-12-22 22:16:09 +0000
commitcb0d490ebe9e4d2fdb160451bfb076856c76f155 (patch)
tree5d9826b3ac47ed5cf683fc0866e2dc25566d6a56 /sys/alpha
parentfdec22285a69d07ca0d4320e306828b89e06a8dd (diff)
downloadFreeBSD-src-cb0d490ebe9e4d2fdb160451bfb076856c76f155.zip
FreeBSD-src-cb0d490ebe9e4d2fdb160451bfb076856c76f155.tar.gz
Tweak how the MD code calls the fooclock() methods some. Instead of
passing a pointer to an opaque clockframe structure and requiring the MD code to supply CLKF_FOO() macros to extract needed values out of the opaque structure, just pass the needed values directly. In practice this means passing the pair (usermode, pc) to hardclock() and profclock() and passing the boolean (usermode) to hardclock_cpu() and hardclock_process(). Other details: - Axe clockframe and CLKF_FOO() macros on all architectures. Basically, all the archs were taking a trapframe and converting it into a clockframe one way or another. Now they can just extract the PC and usermode values directly out of the trapframe and pass it to fooclock(). - Renamed hardclock_process() to hardclock_cpu() as the latter is more accurate. - On Alpha, we now run profclock() at hz (profhz == hz) rather than at the slower stathz. - On Alpha, for the TurboLaser machines that don't have an 8254 timecounter, call hardclock() directly. This removes an extra conditional check from every clock interrupt on Alpha on the BSP. There is probably room for even further pruning here by changing Alpha to use the simplified timecounter we use on x86 with the lapic timer since we don't get interrupts from the 8254 on Alpha anyway. - On x86, clkintr() shouldn't ever be called now unless using_lapic_timer is false, so add a KASSERT() to that affect and remove a condition to slightly optimize the non-lapic case. - Change prototypeof arm_handler_execute() so that it's first arg is a trapframe pointer rather than a void pointer for clarity. - Use KCOUNT macro in profclock() to lookup the kernel profiling bucket. Tested on: alpha, amd64, arm, i386, ia64, sparc64 Reviewed by: bde (mostly)
Diffstat (limited to 'sys/alpha')
-rw-r--r--sys/alpha/alpha/clock.c43
-rw-r--r--sys/alpha/alpha/interrupt.c28
-rw-r--r--sys/alpha/include/cpu.h11
-rw-r--r--sys/alpha/include/cpuconf.h2
4 files changed, 34 insertions, 50 deletions
diff --git a/sys/alpha/alpha/clock.c b/sys/alpha/alpha/clock.c
index 59acaba..df31423 100644
--- a/sys/alpha/alpha/clock.c
+++ b/sys/alpha/alpha/clock.c
@@ -157,7 +157,7 @@ static u_int64_t scaled_ticks_per_cycle;
static u_int32_t max_cycles_per_tick;
static u_int32_t last_time;
-static void handleclock(void* arg);
+static void handleclock(int usermode, uintfptr_t pc);
static void calibrate_clocks(u_int32_t firmware_freq, u_int32_t *pcc,
u_int32_t *timer);
static void set_timer_freq(u_int freq, int intr_freq);
@@ -230,8 +230,7 @@ out:
*/
/*
- * Start the real-time and statistics clocks. Leave stathz 0 since there
- * are no other timers available.
+ * Start the real-time and statistics clocks.
*/
void
cpu_initclocks()
@@ -275,7 +274,9 @@ cpu_initclocks()
*/
if (hwrpb->rpb_type != ST_DEC_21000) {
tc_init(&i8254_timecounter);
- }
+ platform.clockintr = handleclock;
+ } else
+ platform.clockintr = hardclock;
if (ncpus == 1) {
alpha_timecounter.tc_frequency = freq;
@@ -283,7 +284,7 @@ cpu_initclocks()
}
stathz = hz / 8;
- platform.clockintr = (void (*)(void *)) handleclock;
+ profhz = hz;
/*
* Get the clock started.
@@ -424,27 +425,23 @@ set_timer_freq(u_int freq, int intr_freq)
}
static void
-handleclock(void *arg)
+handleclock(int usermode, uintfptr_t pc)
{
- /*
- * XXX: TurboLaser doesn't have an i8254 counter.
- * XXX: A replacement is needed, and another method
- * XXX: of determining this would be nice.
- */
- if (hwrpb->rpb_type != ST_DEC_21000) {
- if (timecounter->tc_get_timecount == i8254_get_timecount) {
- mtx_lock_spin(&clock_lock);
- if (i8254_ticked)
- i8254_ticked = 0;
- else {
- i8254_offset += timer0_max_count;
- i8254_lastcount = 0;
- }
- clkintr_pending = 0;
- mtx_unlock_spin(&clock_lock);
+
+ KASSERT(hwrpb->rpb_type != ST_DEC_21000,
+ ("custom clock handler called on TurboLaser"));
+ if (timecounter->tc_get_timecount == i8254_get_timecount) {
+ mtx_lock_spin(&clock_lock);
+ if (i8254_ticked)
+ i8254_ticked = 0;
+ else {
+ i8254_offset += timer0_max_count;
+ i8254_lastcount = 0;
}
+ clkintr_pending = 0;
+ mtx_unlock_spin(&clock_lock);
}
- hardclock(arg);
+ hardclock(usermode, pc);
}
void
diff --git a/sys/alpha/alpha/interrupt.c b/sys/alpha/alpha/interrupt.c
index b4a7500..0f5ff82 100644
--- a/sys/alpha/alpha/interrupt.c
+++ b/sys/alpha/alpha/interrupt.c
@@ -489,23 +489,21 @@ alpha_clock_interrupt(struct trapframe *framep)
*/
if (PCPU_GET(cpuid) == 0) {
#endif
- (*platform.clockintr)(framep);
- /* divide hz (1024) by 8 to get stathz (128) */
- if ((++schedclk2 & 0x7) == 0) {
- if (profprocs != 0)
- profclock((struct clockframe *)framep);
- statclock((struct clockframe *)framep);
- }
+ (*platform.clockintr)(TRAPF_USERMODE(framep),
+ TRAPF_PC(framep));
+
+ /* Bump stathz divider. */
+ schedclk2++;
#ifdef SMP
- } else {
- hardclock_process((struct clockframe *)framep);
- if ((schedclk2 & 0x7) == 0) {
- if (profprocs != 0)
- profclock((struct clockframe *)framep);
- statclock((struct clockframe *)framep);
- }
- }
+ } else
+ hardclock_cpu(TRAPF_USERMODE(framep));
#endif
+ if (profprocs != 0)
+ profclock(TRAPF_USERMODE(framep), TRAPF_PC(framep));
+
+ /* divide hz (1024) by 8 to get stathz (128) */
+ if ((schedclk2 & 0x7) == 0)
+ statclock(TRAPF_USERMODE(framep));
critical_exit();
}
}
diff --git a/sys/alpha/include/cpu.h b/sys/alpha/include/cpu.h
index 212ced0..a7a6a94 100644
--- a/sys/alpha/include/cpu.h
+++ b/sys/alpha/include/cpu.h
@@ -48,21 +48,10 @@
#include <machine/frame.h>
-/*
- * Arguments to hardclock and gatherstats encapsulate the previous
- * machine state in an opaque clockframe. One the Alpha, we use
- * what we push on an interrupt (a trapframe).
- */
-struct clockframe {
- struct trapframe cf_tf;
-};
#define TRAPF_USERMODE(framep) \
(((framep)->tf_regs[FRAME_PS] & ALPHA_PSL_USERMODE) != 0)
#define TRAPF_PC(framep) ((framep)->tf_regs[FRAME_PC])
-#define CLKF_USERMODE(framep) TRAPF_USERMODE(&(framep)->cf_tf)
-#define CLKF_PC(framep) TRAPF_PC(&(framep)->cf_tf)
-
/*
* CTL_MACHDEP definitions.
*/
diff --git a/sys/alpha/include/cpuconf.h b/sys/alpha/include/cpuconf.h
index 669ca6c..6f1ccc3 100644
--- a/sys/alpha/include/cpuconf.h
+++ b/sys/alpha/include/cpuconf.h
@@ -68,7 +68,7 @@ extern struct platform {
void (*cons_init)(void);
void (*device_register)(struct device *, void *);
void (*iointr)(void *, unsigned long);
- void (*clockintr)(void *);
+ void (*clockintr)(int, uintfptr_t);
void (*mcheck_handler)(unsigned long, struct trapframe *,
unsigned long, unsigned long);
void (*cpu_idle)(void);
OpenPOWER on IntegriCloud