Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 Feb 2008 14:00:29 GMT
From:      "Randall R. Stewart" <rrs@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 135957 for review
Message-ID:  <200802221400.m1ME0TB7007933@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=135957

Change 135957 by rrs@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);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200802221400.m1ME0TB7007933>