Port-sgimips archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: mec and resets



martin%duskware.de@localhost 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


Home | Main Index | Thread Index | Old Index