diff options
-rw-r--r-- | sys/alpha/alpha/clock.c | 67 | ||||
-rw-r--r-- | sys/alpha/alpha/clock_if.m | 7 | ||||
-rw-r--r-- | sys/alpha/isa/mcclock_isa.c | 3 | ||||
-rw-r--r-- | sys/dev/dec/mcclock.c | 28 | ||||
-rw-r--r-- | sys/dev/dec/mcclockvar.h | 1 |
5 files changed, 99 insertions, 7 deletions
diff --git a/sys/alpha/alpha/clock.c b/sys/alpha/alpha/clock.c index f2a8a53..0884881 100644 --- a/sys/alpha/alpha/clock.c +++ b/sys/alpha/alpha/clock.c @@ -1,4 +1,4 @@ -/* $Id: clock.c,v 1.7 1999/04/23 19:53:37 dt Exp $ */ +/* $Id: clock.c,v 1.8 1999/04/25 10:45:59 dt Exp $ */ /* $NetBSD: clock.c,v 1.20 1998/01/31 10:32:47 ross Exp $ */ /* @@ -114,6 +114,7 @@ static u_int32_t max_cycles_per_tick; static u_int32_t last_time; static void handleclock(void* arg); +static u_int32_t calibrate_clocks(u_int32_t firmware_freq); void clockattach(device_t dev) @@ -125,6 +126,7 @@ clockattach(device_t dev) if (clockdev) panic("clockattach: multiple clocks"); clockdev = dev; + cycles_per_sec = calibrate_clocks(cycles_per_sec); #ifdef EVCNT_COUNTERS evcnt_attach(dev, "intr", &clock_intr_evcnt); #endif @@ -150,6 +152,8 @@ clockattach(device_t dev) void cpu_initclocks() { + u_int32_t freq; + if (clockdev == NULL) panic("cpu_initclocks: no clock attached"); @@ -175,11 +179,12 @@ cpu_initclocks() * hardclock, which would then fall over because p->p_stats * isn't set at that time. */ + freq = cycles_per_sec; last_time = alpha_rpcc(); - scaled_ticks_per_cycle = ((u_int64_t)hz << FIX_SHIFT) / cycles_per_sec; - max_cycles_per_tick = 2*cycles_per_sec / hz; + scaled_ticks_per_cycle = ((u_int64_t)hz << FIX_SHIFT) / freq; + max_cycles_per_tick = 2*freq / hz; - alpha_timecounter.tc_frequency = cycles_per_sec; + alpha_timecounter.tc_frequency = freq; init_timecounter(&alpha_timecounter); platform.clockintr = (void (*) __P((void *))) handleclock; @@ -190,6 +195,60 @@ cpu_initclocks() CLOCK_INIT(clockdev); } +static u_int32_t +calibrate_clocks(u_int32_t firmware_freq) +{ + u_int32_t start_pcc, stop_pcc; + int sec, start_sec; + + if (bootverbose) + printf("Calibrating clock(s) ... "); + + /* Read the mc146818A seconds counter. */ + if (CLOCK_GETSECS(clockdev, &sec)) + goto fail; + + /* Wait for the mC146818A seconds counter to change. */ + start_sec = sec; + for (;;) { + if (CLOCK_GETSECS(clockdev, &sec)) + goto fail; + if (sec != start_sec) + break; + } + + /* Start keeping track of the PCC. */ + start_pcc = alpha_rpcc(); + + /* + * Wait for the mc146818A seconds counter to change. + */ + start_sec = sec; + for (;;) { + if (CLOCK_GETSECS(clockdev, &sec)) + goto fail; + if (sec != start_sec) + break; + } + + /* + * Read the PCC again to work out frequency. + */ + stop_pcc = alpha_rpcc(); + + if (bootverbose) { + printf("PCC clock: %u Hz (firmware %u Hz)\n", + stop_pcc - start_pcc, firmware_freq); + } + return (stop_pcc - start_pcc); + +fail: + if (bootverbose) + printf("failed, using firmware default of %u Hz\n", + firmware_freq); + return (firmware_freq); +} + static void handleclock(void* arg) { diff --git a/sys/alpha/alpha/clock_if.m b/sys/alpha/alpha/clock_if.m index 75cb78f..95a2e09 100644 --- a/sys/alpha/alpha/clock_if.m +++ b/sys/alpha/alpha/clock_if.m @@ -23,7 +23,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# $Id: clock_if.m,v 1.1 1998/06/14 13:52:33 dfr Exp $ +# $Id: clock_if.m,v 1.2 1998/11/08 18:35:51 nsouch Exp $ # #include <machine/clockvar.h> @@ -44,3 +44,8 @@ METHOD void set { device_t dev; struct clocktime *ct; }; + +METHOD int getsecs { + device_t dev; + int *secp; +}; diff --git a/sys/alpha/isa/mcclock_isa.c b/sys/alpha/isa/mcclock_isa.c index 3c6ca80..71b22a0 100644 --- a/sys/alpha/isa/mcclock_isa.c +++ b/sys/alpha/isa/mcclock_isa.c @@ -1,4 +1,4 @@ -/* $Id: mcclock_isa.c,v 1.3 1998/07/31 09:20:35 dfr Exp $ */ +/* $Id: mcclock_isa.c,v 1.4 1999/05/08 21:58:38 dfr Exp $ */ /* $NetBSD: mcclock_tlsb.c,v 1.8 1998/05/13 02:50:29 thorpej Exp $ */ /* @@ -61,6 +61,7 @@ static device_method_t mcclock_isa_methods[] = { DEVMETHOD(clock_init, mcclock_init), DEVMETHOD(clock_get, mcclock_get), DEVMETHOD(clock_set, mcclock_set), + DEVMETHOD(clock_getsecs, mcclock_getsecs), { 0, 0 } }; diff --git a/sys/dev/dec/mcclock.c b/sys/dev/dec/mcclock.c index 3aada8b..fc06f82 100644 --- a/sys/dev/dec/mcclock.c +++ b/sys/dev/dec/mcclock.c @@ -1,4 +1,4 @@ -/* $Id: mcclock.c,v 1.1 1998/06/10 10:56:23 dfr Exp $ */ +/* $Id: mcclock.c,v 1.2 1998/06/14 13:45:41 dfr Exp $ */ /* $NetBSD: mcclock.c,v 1.11 1998/04/19 07:50:25 jonathan Exp $ */ /* @@ -111,3 +111,29 @@ mcclock_set(device_t dev, struct clocktime *ct) MC146818_PUTTOD(dev, ®s); splx(s); } + +int +mcclock_getsecs(device_t dev, int *secp) +{ + int timeout = 100000000; + int sec; + int s; + + s = splclock(); + for (;;) { + if (!(MCCLOCK_READ(dev, MC_REGA) & MC_REGA_UIP)) { + sec = MCCLOCK_READ(dev, MC_SEC); + break; + } + if (--timeout == 0) + goto fail; + } + + splx(s); + *secp = sec; + return 0; + + fail: + splx(s); + return ETIMEDOUT; +} diff --git a/sys/dev/dec/mcclockvar.h b/sys/dev/dec/mcclockvar.h index 0c9f5df..a38f632 100644 --- a/sys/dev/dec/mcclockvar.h +++ b/sys/dev/dec/mcclockvar.h @@ -33,3 +33,4 @@ void mcclock_attach(device_t dev); void mcclock_init(device_t); void mcclock_get(device_t, time_t, struct clocktime *); void mcclock_set(device_t, struct clocktime *); +int mcclock_getsecs(device_t dev, int *secp); |