Re: mec and resets

Izumi Tsutsui <[email protected]>
Newsgroups gmane.os.netbsd.ports.sgimips
Message-ID <[email protected]>
[email protected] wrote:

> On Sat, Aug 02, 2008 at 11:43:14PM +0900, Izumi Tsutsui wrote:
> > What timecounter "mips3_cp0_counter" line in dmesg says?
> > Maybe we need CPU_MIPS_DOUBLE_COUNT on R10K too?
> 
> timecounter: Timecounter "mips3_cp0_counter" frequency 150257600 Hz quality 100
> 
> This matches hinv output:
> 
> > hinv                                              
>                    System: IP32
>                 Processor: 150 Mhz R10000, with FPU

Maybe the problem is caused by the following reasons:
- sys/arch/mips/mips/mips_machdep.c doesn't set CPU_MIPS_DOUBLE_COUNT
  in mips_cpu_flags for R10k CPUs
- sys/arch/sgimips/dev/crime.c assumes CPU_MIPS_DOUBLE_COUNT on all CPUs
  and doesn't check mips_cpu_flags
  (so ci_cpu_freq and ci_cycles_per_hz used by hardclock(9) are set correctly)
- sys/arch/mips/mips/mips3_clock.c checks CPU_MIPS_DOUBLE_COUNT
  in mips_cpu_flags
  (then system time runs at half speed (counts 75MHz CP0 counter as 150MHz))

Could you try the attached patch?
(this also fixes some mysterious magic numbers in crime.c)

---
Index: mips/mips/mips_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/mips_machdep.c,v
retrieving revision 1.201
diff -u -r1.201 mips_machdep.c
--- mips/mips/mips_machdep.c	28 Apr 2008 20:23:28 -0000	1.201
+++ mips/mips/mips_machdep.c	2 Aug 2008 17:02:50 -0000
@@ -296,11 +296,14 @@
 	{ 0, MIPS_R8000, -1, -1,		CPU_ARCH_MIPS4, 384,
 	  MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU,	"MIPS R8000 Blackbird/TFP CPU" },
 	{ 0, MIPS_R10000, -1, -1,		CPU_ARCH_MIPS4, 64,
-	  MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU,	"MIPS R10000 CPU"	},
+	  CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT,
+						"MIPS R10000 CPU"	},
 	{ 0, MIPS_R12000, -1, -1,		CPU_ARCH_MIPS4, 64,
-	  MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU,	"MIPS R12000 CPU"	},
+	  CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT,
+						"MIPS R12000 CPU"	},
 	{ 0, MIPS_R14000, -1, -1,		CPU_ARCH_MIPS4, 64,
-	  MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU,	"MIPS R14000 CPU"	},
+	  CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT,
+						"MIPS R14000 CPU"	},
 
 	/* XXX
 	 * If the Processor Revision ID of the 4650 isn't 0, the following
Index: sgimips/dev/crime.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/dev/crime.c,v
retrieving revision 1.29
diff -u -r1.29 crime.c
--- sgimips/dev/crime.c	26 May 2008 15:59:30 -0000	1.29
+++ sgimips/dev/crime.c	2 Aug 2008 17:02:50 -0000
@@ -101,8 +101,8 @@
 {
 	struct mainbus_attach_args *ma = aux;
 	u_int64_t crm_id;
-	u_int64_t baseline;
-	u_int32_t cps;
+	u_int64_t baseline, endline;
+	u_int32_t startctr, endctr, cps;
 
 	crm_iot = SGIMIPS_BUS_SPACE_CRIME;
 
@@ -145,19 +145,25 @@
 	bus_space_write_8(crm_iot, crm_ioh, CRIME_WATCHDOG, 0);
 	bus_space_write_8(crm_iot, crm_ioh, CRIME_CONTROL, 0);
 
-	baseline = bus_space_read_8(crm_iot, crm_ioh, CRIME_TIME) & CRIME_TIME_MASK;
-	cps = mips3_cp0_count_read();
+#define CRIME_TIMER_FREQ	66666666	/* crime clock is 66.7MHz */
 
-	while (((bus_space_read_8(crm_iot, crm_ioh, CRIME_TIME) & CRIME_TIME_MASK)
-		- baseline) < 50 * 1000000 / 15)
-		continue;
-	cps = mips3_cp0_count_read() - cps;
-	cps = cps / 5;
-
-	/* Counter on R4k/R4400/R4600/R5k counts at half the CPU frequency */
-	curcpu()->ci_cpu_freq = cps * 2 * hz;
-	curcpu()->ci_cycles_per_hz = curcpu()->ci_cpu_freq / (2 * hz);
-	curcpu()->ci_divisor_delay = curcpu()->ci_cpu_freq / (2 * 1000000);
+	baseline = bus_space_read_8(crm_iot, crm_ioh, CRIME_TIME)
+	    & CRIME_TIME_MASK;
+	startctr = mips3_cp0_count_read();
+
+	/* read both cp0 and crime counters for 100ms */
+	do {
+		endline = bus_space_read_8(crm_iot, crm_ioh, CRIME_TIME)
+		    & CRIME_TIME_MASK;
+		endctr = mips3_cp0_count_read();
+	} while (endline - baseline < (CRIME_TIMER_FREQ / 10));
+
+	cps = (endctr - startctr) * 10;
+	curcpu()->ci_cpu_freq = cps;
+	if (mips_cpu_flags & CPU_MIPS_DOUBLE_COUNT)
+		curcpu()->ci_cpu_freq *= 2;
+	curcpu()->ci_cycles_per_hz = (cps + (hz / 2)) / hz;
+	curcpu()->ci_divisor_delay = (cps + (1000000 / 2)) / 1000000;
 
 	/* Turn on memory error and crime error interrupts.
 	   All others turned on as devices are registered. */
---
Izumi Tsutsui
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.