diff --git a/sys/arch/algor/algor/algor_p4032_intr.c b/sys/arch/algor/algor/algor_p4032_intr.c index a69251027500..8e74faf23ba8 100644 --- a/sys/arch/algor/algor/algor_p4032_intr.c +++ b/sys/arch/algor/algor/algor_p4032_intr.c @@ -1,4 +1,4 @@ -/* $NetBSD: algor_p4032_intr.c,v 1.14 2007/12/03 15:33:03 ad Exp $ */ +/* $NetBSD: algor_p4032_intr.c,v 1.15 2008/01/09 14:46:48 tsutsui Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -45,7 +45,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: algor_p4032_intr.c,v 1.14 2007/12/03 15:33:03 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: algor_p4032_intr.c,v 1.15 2008/01/09 14:46:48 tsutsui Exp $"); #include "opt_ddb.h" @@ -55,6 +55,7 @@ __KERNEL_RCSID(0, "$NetBSD: algor_p4032_intr.c,v 1.14 2007/12/03 15:33:03 ad Exp #include #include #include +#include #include #include @@ -326,21 +327,24 @@ algor_p4032_cal_timer(bus_space_tag_t st, bus_space_handle_t sh) REGVAL(P4032_IRR0) = 0; - /* Compute the number of cycles per second. */ + /* Update CPU frequency values */ cps = ((ctrdiff[2] + ctrdiff[3]) / 2) * 16; - - /* Compute the number of ticks for hz. */ - cycles_per_hz = cps / hz; - - /* Compute the delay divisor. */ - delay_divisor = (cps / 1000000) / 2; + curcpu()->ci_cpu_freq = cps; + curcpu()->ci_cycles_per_hz = (curcpu()->ci_cpu_freq + hz / 2) / hz; + curcpu()->ci_divisor_delay = + ((curcpu()->ci_cpu_freq + (1000000 / 2)) / 1000000); + /* XXX mips_cpu_flags isn't set here; assume CPU_MIPS_DOUBLE_COUNT */ + curcpu()->ci_cycles_per_hz /= 2; + curcpu()->ci_divisor_delay /= 2; + MIPS_SET_CI_RECIPRICAL(curcpu()); printf("Timer calibration: %lu cycles/sec [(%lu, %lu) * 16]\n", - cps, ctrdiff[2], ctrdiff[3]); + curcpu()->ci_cpu_freq, ctrdiff[2], ctrdiff[3]); printf("CPU clock speed = %lu.%02luMHz " - "(hz cycles = %lu, delay divisor = %u)\n", - cps / 1000000, (cps % 1000000) / 10000, - cycles_per_hz, delay_divisor); + "(hz cycles = %lu, delay divisor = %lu)\n", + curcpu()->ci_cpu_freq / 1000000, + (curcpu()->ci_cpu_freq % 1000000) / 10000, + curcpu()->ci_cycles_per_hz, curcpu()->ci_divisor_delay); } void * diff --git a/sys/arch/algor/algor/algor_p5064_intr.c b/sys/arch/algor/algor/algor_p5064_intr.c index 4f8c3e205751..429e733b7486 100644 --- a/sys/arch/algor/algor/algor_p5064_intr.c +++ b/sys/arch/algor/algor/algor_p5064_intr.c @@ -1,4 +1,4 @@ -/* $NetBSD: algor_p5064_intr.c,v 1.17 2007/12/03 15:33:03 ad Exp $ */ +/* $NetBSD: algor_p5064_intr.c,v 1.18 2008/01/09 14:46:49 tsutsui Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -45,7 +45,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: algor_p5064_intr.c,v 1.17 2007/12/03 15:33:03 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: algor_p5064_intr.c,v 1.18 2008/01/09 14:46:49 tsutsui Exp $"); #include "opt_ddb.h" @@ -55,6 +55,7 @@ __KERNEL_RCSID(0, "$NetBSD: algor_p5064_intr.c,v 1.17 2007/12/03 15:33:03 ad Exp #include #include #include +#include #include #include @@ -412,21 +413,31 @@ algor_p5064_cal_timer(bus_space_tag_t st, bus_space_handle_t sh) REGVAL(P5064_LOCINT) = 0; - /* Compute the number of cycles per second. */ + /* Update CPU frequency values */ cps = ((ctrdiff[2] + ctrdiff[3]) / 2) * 16; - - /* Compute the number of ticks for hz. */ - cycles_per_hz = cps / hz; - - /* Compute the delay divisor. */ - delay_divisor = (cps / 1000000) / 2; +#if 1 + /* XXX for unaccurate emulators */ + if (cps < 10 * 1000 * 1000) { + /* unlikely, use a reasonable value */ + cps = 150 * 1000 * 1000; + } +#endif + curcpu()->ci_cpu_freq = cps; + curcpu()->ci_cycles_per_hz = (curcpu()->ci_cpu_freq + hz / 2) / hz; + curcpu()->ci_divisor_delay = + ((curcpu()->ci_cpu_freq + (1000000 / 2)) / 1000000); + /* XXX mips_cpu_flags isn't set here; assume CPU_MIPS_DOUBLE_COUNT */ + curcpu()->ci_cycles_per_hz /= 2; + curcpu()->ci_divisor_delay /= 2; + MIPS_SET_CI_RECIPRICAL(curcpu()); printf("Timer calibration: %lu cycles/sec [(%lu, %lu) * 16]\n", - cps, ctrdiff[2], ctrdiff[3]); + curcpu()->ci_cpu_freq, ctrdiff[2], ctrdiff[3]); printf("CPU clock speed = %lu.%02luMHz " - "(hz cycles = %lu, delay divisor = %u)\n", - cps / 1000000, (cps % 1000000) / 10000, - cycles_per_hz, delay_divisor); + "(hz cycles = %lu, delay divisor = %lu)\n", + curcpu()->ci_cpu_freq / 1000000, + (curcpu()->ci_cpu_freq % 1000000) / 10000, + curcpu()->ci_cycles_per_hz, curcpu()->ci_divisor_delay); } void * diff --git a/sys/arch/algor/algor/algor_p6032_intr.c b/sys/arch/algor/algor/algor_p6032_intr.c index 20a4ecca735f..a258bda67e74 100644 --- a/sys/arch/algor/algor/algor_p6032_intr.c +++ b/sys/arch/algor/algor/algor_p6032_intr.c @@ -1,4 +1,4 @@ -/* $NetBSD: algor_p6032_intr.c,v 1.11 2007/12/03 15:33:03 ad Exp $ */ +/* $NetBSD: algor_p6032_intr.c,v 1.12 2008/01/09 14:46:49 tsutsui Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -44,7 +44,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: algor_p6032_intr.c,v 1.11 2007/12/03 15:33:03 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: algor_p6032_intr.c,v 1.12 2008/01/09 14:46:49 tsutsui Exp $"); #include "opt_ddb.h" @@ -54,6 +54,7 @@ __KERNEL_RCSID(0, "$NetBSD: algor_p6032_intr.c,v 1.11 2007/12/03 15:33:03 ad Exp #include #include #include +#include #include #include @@ -287,21 +288,24 @@ algor_p6032_cal_timer(bus_space_tag_t st, bus_space_handle_t sh) ctrdiff[i] = endctr - startctr; } - /* Compute the number of cycles per second. */ + /* Update CPU frequency values */ cps = ((ctrdiff[2] + ctrdiff[3]) / 2) * 16; - - /* Compute the number of ticks for hz. */ - cycles_per_hz = cps / hz; - - /* Compute the delay divisor. */ - delay_divisor = (cps / 1000000) / 2; + curcpu()->ci_cpu_freq = cps; + curcpu()->ci_cycles_per_hz = (curcpu()->ci_cpu_freq + hz / 2) / hz; + curcpu()->ci_divisor_delay = + ((curcpu()->ci_cpu_freq + (1000000 / 2)) / 1000000); + /* XXX mips_cpu_flags isn't set here; assume CPU_MIPS_DOUBLE_COUNT */ + curcpu()->ci_cycles_per_hz /= 2; + curcpu()->ci_divisor_delay /= 2; + MIPS_SET_CI_RECIPRICAL(curcpu()); printf("Timer calibration: %lu cycles/sec [(%lu, %lu) * 16]\n", - cps, ctrdiff[2], ctrdiff[3]); + curcpu()->ci_cpu_freq, ctrdiff[2], ctrdiff[3]); printf("CPU clock speed = %lu.%02luMHz " - "(hz cycles = %lu, delay divisor = %u)\n", - cps / 1000000, (cps % 1000000) / 10000, - cycles_per_hz, delay_divisor); + "(hz cycles = %lu, delay divisor = %lu)\n", + curcpu()->ci_cpu_freq / 1000000, + (curcpu()->ci_cpu_freq % 1000000) / 10000, + curcpu()->ci_cycles_per_hz, curcpu()->ci_divisor_delay); } void * diff --git a/sys/arch/algor/algor/locore_machdep.S b/sys/arch/algor/algor/locore_machdep.S index efab2d3a164f..778095bbc893 100644 --- a/sys/arch/algor/algor/locore_machdep.S +++ b/sys/arch/algor/algor/locore_machdep.S @@ -1,72 +1,3 @@ -/* $NetBSD: locore_machdep.S,v 1.3 2005/12/11 12:16:08 christos Exp $ */ +/* $NetBSD: locore_machdep.S,v 1.4 2008/01/09 14:46:49 tsutsui Exp $ */ -/*- - * Copyright (c) 2001 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jason R. Thorpe. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - - .set noreorder - -/* - * _delay(u_int N) - * - * Delay for at least (N/256) microseconds. - * This routine depends on the variable: delay_divisor, - * which should be set based on the CPU clock rate. - */ -LEAF_NOPROFILE(_delay) - /* a0 = (usecs << 8) */ - /* v0 = delay_divisor */ - la v0, _C_LABEL(delay_divisor) - lw v0, 0(v0) - b 1f /* jump into the loop! */ - nop - - /* Align the branch target to ~cache line. */ - .align 5 -1: bgtz a0, 1b - subu a0, a0, v0 - j ra - nop -END(_delay) - - .data - - .globl _C_LABEL(delay_divisor) - .align 2 -_C_LABEL(delay_divisor): - .word 0 +/* This file intentionally left blank. */ diff --git a/sys/arch/mips/mips/mips3_clock.c b/sys/arch/mips/mips/mips3_clock.c index 5425d2cad3e9..8d125a4c75b5 100644 --- a/sys/arch/mips/mips/mips3_clock.c +++ b/sys/arch/mips/mips/mips3_clock.c @@ -1,4 +1,4 @@ -/* $NetBSD: mips3_clock.c,v 1.7 2008/01/08 14:46:28 joerg Exp $ */ +/* $NetBSD: mips3_clock.c,v 1.8 2008/01/09 14:46:49 tsutsui Exp $ */ /* * Copyright (c) 1992, 1993 @@ -78,10 +78,11 @@ #include /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: mips3_clock.c,v 1.7 2008/01/08 14:46:28 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mips3_clock.c,v 1.8 2008/01/09 14:46:49 tsutsui Exp $"); #include #include +#include #include #include @@ -96,25 +97,40 @@ __KERNEL_RCSID(0, "$NetBSD: mips3_clock.c,v 1.7 2008/01/08 14:46:28 joerg Exp $" void mips3_delay(int n) { + u_long cycles_per_hz, divisor_delay; uint32_t cur, last, delta, usecs; last = mips3_cp0_count_read(); delta = usecs = 0; + if (curcpu()->ci_cpu_freq == 0) { + /* + * Frequency values in curcpu() are not initialized. + * Assume faster frequency since longer delays are harmless. + * Note CPU_MIPS_DOUBLE_COUNT is ignored here. + */ +#define FAST_FREQ (300 * 1000 * 1000) /* fast enough? */ + cycles_per_hz = FAST_FREQ / hz; + divisor_delay = FAST_FREQ / (1000 * 1000); + } else { + cycles_per_hz = curcpu()->ci_cycles_per_hz; + divisor_delay = curcpu()->ci_divisor_delay; + } + while (n > usecs) { cur = mips3_cp0_count_read(); /* Check to see if the timer has wrapped around. */ if (cur < last) - delta += ((curcpu()->ci_cycles_per_hz - last) + cur); + delta += ((cycles_per_hz - last) + cur); else delta += (cur - last); last = cur; - if (delta >= curcpu()->ci_divisor_delay) { - usecs += delta / curcpu()->ci_divisor_delay; - delta %= curcpu()->ci_divisor_delay; + if (delta >= divisor_delay) { + usecs += delta / divisor_delay; + delta %= divisor_delay; } } }