PERFORCE change 135957 for review
Randall R. Stewart
rrs at FreeBSD.org
Fri Feb 22 14:00:30 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=135957
Change 135957 by rrs at rrs-mips2-jnpr on 2008/02/22 14:00:09
Fix up ticks properly
Affected files ...
.. //depot/projects/mips2-jnpr/src/sys/mips/mips/tick.c#6 edit
Differences ...
==== //depot/projects/mips2-jnpr/src/sys/mips/mips/tick.c#6 (text+ko) ====
@@ -50,13 +50,25 @@
#include <machine/md_var.h>
uint64_t counter_freq;
-uint64_t counts_per_hz;
-uint32_t counts_per_usec;
-int counter_is_broken=0;
-u_int counter_present;
+uint64_t cycles_per_tick;
+uint32_t cycles_per_usec;
+uint32_t cycles_per_sec;
+uint32_t cycles_per_hz;
+
u_int32_t counter_upper = 0;
u_int32_t counter_lower_last = 0;
-int clock_started = 0;
+int tick_started = 0;
+
+struct clk_ticks {
+ u_long hard_ticks;
+ u_long stat_ticks;
+ u_long prof_ticks;
+ /*
+ * pad for cache line alignment of pcpu info
+ * cache-line-size - number of used bytes
+ */
+ char pad[32-(3*sizeof (u_long))];
+} static pcpu_ticks[MAXCPU];
/*
* Device methods
@@ -83,16 +95,16 @@
{
/* Cavium early init code */
counter_freq = clock_hz;
- counts_per_usec = (clock_hz / (1000 * 1000));
+ cycles_per_usec = (clock_hz / (1000 * 1000));
}
void
cpu_initclocks(void)
{
- if (!clock_started) {
+ if (!tick_started) {
tc_init(&counter_timecounter);
- clock_started++;
+ tick_started++;
}
}
@@ -128,23 +140,33 @@
*/
counter_freq = platform_counter_freq;
- counts_per_hz = counter_freq / hz;
- counts_per_usec = counter_freq / (1 * 1000 * 1000);
+ cycles_per_tick = counter_freq / 1000;
+ if(double_count)
+ cycles_per_tick *=2;
+
+ cycles_per_hz = counter_freq / hz;
+
+ cycles_per_usec = counter_freq / (1 * 1000 * 1000);
+ cycles_per_sec = counter_freq / (1 * 1000);
+
counter_timecounter.tc_frequency = counter_freq;
/*
* XXX: Some MIPS32 cores update the Count register only every two
* pipeline cycles.
*/
if (double_count != 0) {
- counts_per_hz /= 2;
- counts_per_usec /= 2;
+ cycles_per_hz /= 2;
+ cycles_per_usec /= 2;
+ cycles_per_sec /= 2;
}
- printf("hz=%d counts_per_hz:%jd counts_per_usec:%d freq:%jd\n",
+ printf("hz=%d counts_per_hz:%jd counts_per_usec:%d freq:%jd cycles_per_hz:%d cycles_per_sec:%d\n",
hz,
- counts_per_hz,
- counts_per_usec,
- counter_freq
+ cycles_per_tick,
+ cycles_per_usec,
+ counter_freq,
+ cycles_per_hz,
+ cycles_per_sec
);
set_cputicker(tick_ticker, counter_freq, 1);
}
@@ -209,15 +231,15 @@
/* Check to see if the timer has wrapped around. */
if (cur < last)
- delta += (cur + (counts_per_hz - last));
+ delta += (cur + (cycles_per_hz - last));
else
delta += (cur - last);
last = cur;
- if (delta >= counts_per_usec) {
- usecs += delta / counts_per_usec;
- delta %= counts_per_usec;
+ if (delta >= cycles_per_usec) {
+ usecs += delta / cycles_per_usec;
+ delta %= cycles_per_usec;
}
}
}
@@ -233,7 +255,6 @@
#ifdef TARGET_OCTEON
int wheel_run = 0;
-#define OCTEON_TICK_COUNT 100
void octeon_led_run_wheel(void);
#endif
@@ -243,40 +264,62 @@
static int
clock_intr(void *arg)
{
+ struct clk_ticks *cpu_ticks;
struct trapframe *tf;
- register_t usermode, pc;
uint32_t ltick;
-
+ uint8_t a=0, b=0, c=0, d=0;
/*
* Set next clock edge.
*/
ltick = mips_rd_count();
mips_wr_compare(ltick + counter_freq / hz);
+ cpu_ticks = &pcpu_ticks[PCPU_GET(cpuid)];
critical_enter();
if (ltick < counter_lower_last) {
counter_upper++;
counter_lower_last = ltick;
+ a = 1;
}
- critical_exit();
/*
* Magic. Setting up with an arg of NULL means we get passed tf.
- * XXX this comment and the code don't match.
*/
- tf = arg;
- usermode = tf->sr & MIPS_SR_KSU_USER;
- pc = tf->pc;
+ tf = (struct trapframe *)arg;
+
+ /* Fire hardclock at hz. */
+ cpu_ticks->hard_ticks += cycles_per_tick;
+ if (cpu_ticks->hard_ticks >= cycles_per_hz) {
+ b = 1;
+ cpu_ticks->hard_ticks -= cycles_per_hz;
+ if (PCPU_GET(cpuid) == 0)
+ hardclock(USERMODE(tf->sr), tf->pc);
+ else
+ hardclock_cpu(USERMODE(tf->sr));
+ }
+ /* Fire statclock at stathz. */
+ cpu_ticks->stat_ticks += stathz;
+ if (cpu_ticks->stat_ticks >= cycles_per_hz) {
+ c = 1;
+ cpu_ticks->stat_ticks -= cycles_per_hz;
+ statclock(USERMODE(tf->sr));
+ }
+ /* Fire profclock at profhz, but only when needed. */
+ cpu_ticks->prof_ticks += profhz;
+ if (cpu_ticks->prof_ticks >= cycles_per_hz) {
+ d = 1;
+ cpu_ticks->prof_ticks -= cycles_per_hz;
+ if (profprocs != 0)
+ profclock(USERMODE(tf->sr), tf->pc);
+ }
+ critical_exit();
#ifdef TARGET_OCTEON
- /* Run the FreeBSD display once every N ticks */
- wheel_run++;
- if (wheel_run >= OCTEON_TICK_COUNT) {
+ /* Run the FreeBSD display once every hz ticks */
+ wheel_run += cycles_per_tick;
+ if (wheel_run >= cycles_per_sec) {
wheel_run = 0;
octeon_led_run_wheel();
}
#endif
- if (clocks_running) {
- hardclock(usermode, pc);
- }
return (FILTER_HANDLED);
}
More information about the p4-projects
mailing list