diff options
author | marcel <marcel@FreeBSD.org> | 2003-08-04 05:13:18 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2003-08-04 05:13:18 +0000 |
commit | d5a33e59d13687ecea3a42a2b0b563e2b45dfaa2 (patch) | |
tree | 53c0285dd78b50088e45353c7f9f616322b81ed4 /sys | |
parent | 321771d2627fb7dfe7408a8f7a6bc6dd85ddac97 (diff) | |
download | FreeBSD-src-d5a33e59d13687ecea3a42a2b0b563e2b45dfaa2.zip FreeBSD-src-d5a33e59d13687ecea3a42a2b0b563e2b45dfaa2.tar.gz |
Cleanup the clock code. This includes:
o Remove alpha specific timer code (mc146818A) and compiled-out
calibration of said timer.
o Remove i386 inherited timer code (i8253) and related acquire and
release functions.
o Move sysbeep() from clock.c to machdep.c and have it return
ENODEV. Console beeps should be implemented using ACPI or if no
such device is described, using the sound driver.
o Move the sysctls related to adjkerntz, disable_rtc_set and
wall_cmos_clock from machdep.c to clock.c, where the variables
are.
o Don't hardcode a hz value of 1024 in cpu_initclocks() and don't
bother faking a stathz that's 1/8 of that. Keep it simple: hz
defaults to HZ and stathz equals hz. This is also how it's done
for sparc64.
o Keep a per-CPU ITC counter (pc_clock) and adjustment (pc_clockadj)
to calculate ITC skew and corrections. On average, we adjust the
ITC match register once every ~1500 interrupts for a duration of
2 consequtive interruprs. This is to correct the non-deterministic
behaviour of the ITC interrupt (there's a delay between the match
and the raising of the interrupt).
o Add 4 debugging sysctls to monitor clock behaviour. Those are
debug.clock_adjust_edges, debug.clock_adjust_excess,
debug.clock_adjust_lost and debug.clock_adjust_ticks. The first
counts the individual adjustment cycles (when the skew first
crosses the threshold), the second counts the number of times the
adjustment was excessive (any non-zero value is to be considered
a bug), the third counts lost clock interrupts and the last counts
the number of interrupts for which we applied an adjustment
(debug.clock_adjust_ticks / debug.clock_adjust_edges gives the
avarage duration of an individual adjustment -- should be ~2).
While here, remove some nearby (trivial) left-overs from alpha and
other cleanups.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/ia64/ia64/clock.c | 330 | ||||
-rw-r--r-- | sys/ia64/ia64/interrupt.c | 119 | ||||
-rw-r--r-- | sys/ia64/ia64/machdep.c | 26 | ||||
-rw-r--r-- | sys/ia64/ia64/mp_machdep.c | 7 | ||||
-rw-r--r-- | sys/ia64/ia64/timerreg.h | 110 | ||||
-rw-r--r-- | sys/ia64/include/clock.h | 14 | ||||
-rw-r--r-- | sys/ia64/include/cpu.h | 19 | ||||
-rw-r--r-- | sys/ia64/include/pcpu.h | 8 |
8 files changed, 174 insertions, 459 deletions
diff --git a/sys/ia64/ia64/clock.c b/sys/ia64/ia64/clock.c index aaa9e92..e6c32b9 100644 --- a/sys/ia64/ia64/clock.c +++ b/sys/ia64/ia64/clock.c @@ -1,6 +1,3 @@ -/* $FreeBSD$ */ -/* $NetBSD: clock.c,v 1.20 1998/01/31 10:32:47 ross Exp $ */ - /* * Copyright (c) 1988 University of Utah. * Copyright (c) 1992, 1993 @@ -42,8 +39,10 @@ * * @(#)clock.c 8.1 (Berkeley) 6/10/93 */ +/* $NetBSD: clock.c,v 1.20 1998/01/31 10:32:47 ross Exp $ */ -#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/kernel.h> @@ -52,13 +51,11 @@ #include <sys/systm.h> #include <sys/bus.h> #include <sys/timetc.h> +#include <sys/pcpu.h> -#include <machine/pal.h> -#include <machine/sal.h> #include <machine/clock.h> #include <machine/clockvar.h> -#include <isa/isareg.h> -#include <ia64/ia64/timerreg.h> +#include <machine/cpu.h> #define SECMIN ((unsigned)60) /* seconds per minute */ #define SECHOUR ((unsigned)(60*SECMIN)) /* seconds per hour */ @@ -68,197 +65,106 @@ /* * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we * can use a simple formula for leap years. + * XXX time_t is 64-bits on ia64. */ #define LEAPYEAR(y) (((y) % 4) == 0) -kobj_t clockdev; -int clockinitted; -int tickfix; -int tickfixinterval; +static int sysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS); + +int disable_rtc_set; /* disable resettodr() if != 0 */ +SYSCTL_INT(_machdep, CPU_DISRTCSET, disable_rtc_set, + CTLFLAG_RW, &disable_rtc_set, 0, ""); + +int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ +SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, + CTLFLAG_RW, &wall_cmos_clock, 0, ""); + int adjkerntz; /* local offset from GMT in seconds */ -int disable_rtc_set; /* disable resettodr() if != 0 */ -int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ -u_int64_t itm_reload; /* reload ticks for clock */ -static int beeping = 0; +SYSCTL_PROC(_machdep, CPU_ADJKERNTZ, adjkerntz, CTLTYPE_INT|CTLFLAG_RW, + &adjkerntz, 0, sysctl_machdep_adjkerntz, "I", ""); + +kobj_t clockdev; +int todr_initialized; + +uint64_t ia64_clock_reload; #ifndef SMP -static timecounter_get_t ia64_get_timecount; +static timecounter_get_t ia64_get_timecount; static struct timecounter ia64_timecounter = { ia64_get_timecount, /* get_timecount */ 0, /* no poll_pps */ - ~0u, /* counter_mask */ + ~0u, /* counter_mask */ 0, /* frequency */ "ITC" /* name */ }; +static unsigned +ia64_get_timecount(struct timecounter* tc) +{ + return ia64_get_itc(); +} #endif -/* Values for timerX_state: */ -#define RELEASED 0 -#define RELEASE_PENDING 1 -#define ACQUIRED 2 -#define ACQUIRE_PENDING 3 - -/* static u_char timer0_state; */ -static u_char timer2_state; - -/* - * Algorithm for missed clock ticks from Linux/alpha. - */ - -/* - * Shift amount by which scaled_ticks_per_cycle is scaled. Shifting - * by 48 gives us 16 bits for HZ while keeping the accuracy good even - * for large CPU clock rates. - */ -#define FIX_SHIFT 48 - -static u_int64_t scaled_ticks_per_cycle; -static u_int32_t max_cycles_per_tick; -static u_int32_t last_time; +static int +sysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS) +{ + int error; -#if 0 /* not used yet */ -static u_int32_t calibrate_clocks(u_int32_t firmware_freq); -#endif + error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req); + if (!error && req->newptr) + resettodr(); + return (error); +} void clockattach(kobj_t dev) { - /* - * Just bookkeeping. - */ if (clockdev) panic("clockattach: multiple clocks"); + clockdev = dev; + #ifdef EVCNT_COUNTERS evcnt_attach(dev, "intr", &clock_intr_evcnt); #endif - /* - * Get the clock started. - */ + /* Get the clock started. */ CLOCK_INIT(clockdev); } -/* - * Machine-dependent clock routines. - * - * Startrtclock restarts the real-time clock, which provides - * hardclock interrupts to kern_clock.c. - * - * Inittodr initializes the time of day hardware which provides - * date functions. Its primary function is to use some file - * system information in case the hardare clock lost state. - * - * Resettodr restores the time of day hardware after a time change. - */ +void +pcpu_initclock(void) +{ + + PCPU_SET(clockadj, 0); + PCPU_SET(clock, ia64_get_itc()); + ia64_set_itm(PCPU_GET(clock) + ia64_clock_reload); + ia64_set_itv(CLOCK_VECTOR); /* highest priority class */ +} /* - * Start the real-time and statistics clocks. Leave stathz 0 since there - * are no other timers available. + * Start the real-time and statistics clocks. We use cr.itc and cr.itm + * to implement a 1000hz clock. */ void cpu_initclocks() { - u_int32_t freq; - - /* - * We use cr.itc and cr.itm to implement a 1024hz clock. - */ - hz = 1024; - tick = 1000000 / hz; /* number of microseconds between interrupts */ - tickfix = 1000000 - (hz * tick); - if (tickfix) { - int ftp; - - ftp = min(ffs(tickfix), ffs(hz)); - tickfix >>= (ftp - 1); - tickfixinterval = hz >> (ftp - 1); - } - - if (!itc_frequency) + + if (itc_frequency == 0) panic("Unknown clock frequency"); - freq = itc_frequency; - last_time = ia64_get_itc(); - scaled_ticks_per_cycle = ((u_int64_t)hz << FIX_SHIFT) / freq; - max_cycles_per_tick = 2*freq / hz; + stathz = hz; + ia64_clock_reload = (itc_frequency + hz/2) / hz; #ifndef SMP - ia64_timecounter.tc_frequency = freq; + ia64_timecounter.tc_frequency = itc_frequency; tc_init(&ia64_timecounter); #endif - itm_reload = (itc_frequency + hz/2) / hz; - ia64_set_itm(ia64_get_itc() + itm_reload); - ia64_set_itv(CLOCK_VECTOR); /* highest priority class */ - - stathz = 128; -} - -#if 0 /* not used yet */ -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 = ia64_get_itc(); - - /* - * 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 = ia64_get_itc(); - - 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); + pcpu_initclock(); } -#endif - -/* - * We assume newhz is either stathz or profhz, and that neither will - * change after being set up above. Could recalculate intervals here - * but that would be a drag. - */ void cpu_startprofclock(void) @@ -283,20 +189,17 @@ static short dayyr[12] = { }; /* - * Initialze the time of day register, based on the time base which is, e.g. - * from a filesystem. Base provides the time to within six months, + * Initialize the time of day register, based on the time base which is, + * e.g. from a filesystem. Base provides the time to within six months, * and the time of year clock (if any) provides the rest. */ void -inittodr(base) - time_t base; +inittodr(time_t base) { - register int days, yr; struct clocktime ct; - time_t deltat; - int badbase; - int s; struct timespec ts; + time_t deltat; + int badbase, days, s, yr; if (base < 5*SECYR) { printf("WARNING: preposterous time in filesystem"); @@ -307,7 +210,7 @@ inittodr(base) badbase = 0; CLOCK_GET(clockdev, base, &ct); - clockinitted = 1; + todr_initialized = 1; /* simple sanity checks */ if (ct.year < 70 || ct.mon < 1 || ct.mon > 12 || ct.day < 1 || @@ -333,12 +236,13 @@ inittodr(base) days += dayyr[ct.mon - 1] + ct.day - 1; if (LEAPYEAR(yr) && ct.mon > 2) days++; + /* now have days since Jan 1, 1970; the rest is easy... */ s = splclock(); - ts.tv_sec = + ts.tv_sec = days * SECDAY + ct.hour * SECHOUR + ct.min * SECMIN + ct.sec; if (wall_cmos_clock) - ts.tv_sec += adjkerntz; + ts.tv_sec += adjkerntz; ts.tv_nsec = 0; tc_setclock(&ts); splx(s); @@ -361,29 +265,26 @@ bad: } /* - * Reset the TODR based on the time value; used when the TODR - * has a preposterous value and also when the time is reset - * by the stime system call. Also called when the TODR goes past + * Reset the TODR based on the time value; used when the TODR has a + * preposterous value and also when the time is reset by the stime + * system call. Also called when the TODR goes past * TODRZERO + 100*(SECYEAR+2*SECDAY) (e.g. on Jan 2 just after midnight) * to wrap the TODR around. */ void resettodr() { - register int t, t2, s; struct clocktime ct; - unsigned long tm; + unsigned long tm; + int s, t, t2; - if (disable_rtc_set) + if (!todr_initialized || disable_rtc_set) return; s = splclock(); tm = time_second; splx(s); - if (!clockinitted) - return; - /* Calculate local time to put in RTC */ tm -= (wall_cmos_clock ? adjkerntz : 0); @@ -419,86 +320,3 @@ resettodr() CLOCK_SET(clockdev, &ct); } - -#ifndef SMP -static unsigned -ia64_get_timecount(struct timecounter* tc) -{ - return ia64_get_itc(); -} -#endif - -int -acquire_timer2(int mode) -{ - - if (timer2_state != RELEASED) - return (-1); - timer2_state = ACQUIRED; - - /* - * This access to the timer registers is as atomic as possible - * because it is a single instruction. We could do better if we - * knew the rate. Use of splclock() limits glitches to 10-100us, - * and this is probably good enough for timer2, so we aren't as - * careful with it as with timer0. - */ - outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f)); - - return (0); -} - -int -release_timer2() -{ - - if (timer2_state != ACQUIRED) - return (-1); - timer2_state = RELEASED; - outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT); - return (0); -} - -static void -sysbeepstop(void *chan) -{ - outb(IO_PPI, inb(IO_PPI)&0xFC); /* disable counter2 output to speaker */ - release_timer2(); - beeping = 0; -} - -/* - * Frequency of all three count-down timers; (TIMER_FREQ/freq) is the - * appropriate count to generate a frequency of freq hz. - */ -#ifndef TIMER_FREQ -#define TIMER_FREQ 1193182 -#endif -#define TIMER_DIV(x) ((TIMER_FREQ+(x)/2)/(x)) - -int -sysbeep(int pitch, int period) -{ - int x = splhigh(); - - if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT)) - if (!beeping) { - /* Something else owns it. */ - splx(x); - return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ - } - - if (pitch) pitch = TIMER_DIV(pitch); - - outb(TIMER_CNTR2, pitch); - outb(TIMER_CNTR2, (pitch>>8)); - if (!beeping) { - /* enable counter2 output to speaker */ - if (pitch) outb(IO_PPI, inb(IO_PPI) | 3); - beeping = period; - timeout(sysbeepstop, (void *)NULL, period); - } - splx(x); - return (0); -} - diff --git a/sys/ia64/ia64/interrupt.c b/sys/ia64/ia64/interrupt.c index a9539a9..6ee3070 100644 --- a/sys/ia64/ia64/interrupt.c +++ b/sys/ia64/ia64/interrupt.c @@ -85,21 +85,51 @@ dummy_perf(unsigned long vector, struct trapframe *framep) void (*perf_irq)(unsigned long, struct trapframe *) = dummy_perf; static unsigned int ints[MAXCPU]; +SYSCTL_OPAQUE(_debug, OID_AUTO, ints, CTLFLAG_RW, &ints, sizeof(ints), "IU", + ""); + static unsigned int clks[MAXCPU]; +#ifdef SMP +SYSCTL_OPAQUE(_debug, OID_AUTO, clks, CTLFLAG_RW, &clks, sizeof(clks), "IU", + ""); +#else +SYSCTL_INT(_debug, OID_AUTO, clks, CTLFLAG_RW, clks, 0, ""); +#endif + +#ifdef SMP static unsigned int asts[MAXCPU]; +SYSCTL_OPAQUE(_debug, OID_AUTO, asts, CTLFLAG_RW, &asts, sizeof(asts), "IU", + ""); + static unsigned int rdvs[MAXCPU]; -SYSCTL_OPAQUE(_debug, OID_AUTO, ints, CTLFLAG_RW, &ints, sizeof(ints), "IU",""); -SYSCTL_OPAQUE(_debug, OID_AUTO, clks, CTLFLAG_RW, &clks, sizeof(clks), "IU",""); -SYSCTL_OPAQUE(_debug, OID_AUTO, asts, CTLFLAG_RW, &asts, sizeof(asts), "IU",""); -SYSCTL_OPAQUE(_debug, OID_AUTO, rdvs, CTLFLAG_RW, &rdvs, sizeof(rdvs), "IU",""); +SYSCTL_OPAQUE(_debug, OID_AUTO, rdvs, CTLFLAG_RW, &rdvs, sizeof(rdvs), "IU", + ""); +#endif -static u_int schedclk2; +static int adjust_edges = 0; +SYSCTL_INT(_debug, OID_AUTO, clock_adjust_edges, CTLFLAG_RW, + &adjust_edges, 0, "Number of times ITC got more than 12.5% behind"); + +static int adjust_excess = 0; +SYSCTL_INT(_debug, OID_AUTO, clock_adjust_excess, CTLFLAG_RW, + &adjust_excess, 0, "Total number of ignored ITC interrupts"); + +static int adjust_lost = 0; +SYSCTL_INT(_debug, OID_AUTO, clock_adjust_lost, CTLFLAG_RW, + &adjust_lost, 0, "Total number of lost ITC interrupts"); + +static int adjust_ticks = 0; +SYSCTL_INT(_debug, OID_AUTO, clock_adjust_ticks, CTLFLAG_RW, + &adjust_ticks, 0, "Total number of ITC interrupts with adjustment"); void interrupt(u_int64_t vector, struct trapframe *framep) { struct thread *td; volatile struct ia64_interrupt_block *ib = IA64_INTERRUPT_BLOCK; + uint64_t adj, clk, itc; + int64_t delta; + int count; td = curthread; atomic_add_int(&td->td_intr_nesting_level, 1); @@ -115,39 +145,55 @@ interrupt(u_int64_t vector, struct trapframe *framep) if (vector == CLOCK_VECTOR) {/* clock interrupt */ /* CTR0(KTR_INTR, "clock interrupt"); */ - + cnt.v_intr++; #ifdef EVCNT_COUNTERS clock_intr_evcnt.ev_count++; #else intrcnt[INTRCNT_CLOCK]++; #endif - critical_enter(); - /* Rearm so we get the next clock interrupt */ - ia64_set_itm(ia64_get_itc() + itm_reload); -#ifdef SMP clks[PCPU_GET(cpuid)]++; - /* Only the BSP runs the real clock */ - if (PCPU_GET(cpuid) == 0) { -#endif - hardclock((struct clockframe *)framep); - /* divide hz (1024) by 8 to get stathz (128) */ - if ((++schedclk2 & 0x7) == 0) { - if (profprocs != 0) - profclock((struct clockframe *)framep); - statclock((struct clockframe *)framep); - } -#ifdef SMP + + critical_enter(); + + adj = PCPU_GET(clockadj); + itc = ia64_get_itc(); + ia64_set_itm(itc + ia64_clock_reload - adj); + clk = PCPU_GET(clock); + delta = itc - clk; + count = 0; + while (delta >= ia64_clock_reload) { + /* Only the BSP runs the real clock */ + if (PCPU_GET(cpuid) == 0) + hardclock((struct clockframe *)framep); + else + hardclock_process((struct clockframe *)framep); + if (profprocs != 0) + profclock((struct clockframe *)framep); + statclock((struct clockframe *)framep); + delta -= ia64_clock_reload; + clk += ia64_clock_reload; + if (adj != 0) + adjust_ticks++; + count++; + } + if (count > 0) { + adjust_lost += count - 1; + if (delta > (ia64_clock_reload >> 3)) { + if (adj == 0) + adjust_edges++; + adj = ia64_clock_reload >> 4; + } else if (delta < (ia64_clock_reload >> 3)) + adj = 0; } else { - hardclock_process((struct clockframe *)framep); - if ((schedclk2 & 0x7) == 0) { - if (profprocs != 0) - profclock((struct clockframe *)framep); - statclock((struct clockframe *)framep); - } + adj = 0; + adjust_excess++; } -#endif + PCPU_SET(clock, clk); + PCPU_SET(clockadj, adj); + critical_exit(); + #ifdef SMP } else if (vector == ipi_vector[IPI_AST]) { asts[PCPU_GET(cpuid)]++; @@ -186,23 +232,6 @@ interrupt(u_int64_t vector, struct trapframe *framep) atomic_subtract_int(&td->td_intr_nesting_level, 1); } -int -badaddr(addr, size) - void *addr; - size_t size; -{ - return(badaddr_read(addr, size, NULL)); -} - -int -badaddr_read(addr, size, rptr) - void *addr; - size_t size; - void *rptr; -{ - return (1); /* XXX implement */ -} - /* * Hardware irqs have vectors starting at this offset. */ diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index e9affcd..b466523 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -1357,26 +1357,6 @@ Debugger(const char *msg) } #endif /* no DDB */ -static int -sysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS) -{ - int error; - error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, - req); - if (!error && req->newptr) - resettodr(); - return (error); -} - -SYSCTL_PROC(_machdep, CPU_ADJKERNTZ, adjkerntz, CTLTYPE_INT|CTLFLAG_RW, - &adjkerntz, 0, sysctl_machdep_adjkerntz, "I", ""); - -SYSCTL_INT(_machdep, CPU_DISRTCSET, disable_rtc_set, - CTLFLAG_RW, &disable_rtc_set, 0, ""); - -SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, - CTLFLAG_RW, &wall_cmos_clock, 0, ""); - /* * Utility functions for manipulating instruction bundles. */ @@ -1400,3 +1380,9 @@ ia64_pack_bundle(u_int64_t *lowp, u_int64_t *highp, *lowp = low; *highp = high; } + +int +sysbeep(int pitch, int period) +{ + return (ENODEV); +} diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c index 1284e8e..eeab986 100644 --- a/sys/ia64/ia64/mp_machdep.c +++ b/sys/ia64/ia64/mp_machdep.c @@ -123,10 +123,11 @@ ia64_ap_startup(void) mtx_lock_spin(&sched_lock); - /* kick off the clock on this AP */ - ia64_set_itm(ia64_get_itc() + itm_reload); - ia64_set_itv(CLOCK_VECTOR); ia64_set_tpr(0); + + /* kick off the clock on this AP */ + pcpu_initclock(); + cpu_throw(NULL, choosethread()); /* NOTREACHED */ } diff --git a/sys/ia64/ia64/timerreg.h b/sys/ia64/ia64/timerreg.h deleted file mode 100644 index 0bfd7fc..0000000 --- a/sys/ia64/ia64/timerreg.h +++ /dev/null @@ -1,110 +0,0 @@ -/*- - * Copyright (c) 1993 The Regents of the University of California. - * All rights reserved. - * - * 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 University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * from: Header: timerreg.h,v 1.2 93/02/28 15:08:58 mccanne Exp - * $FreeBSD$ - */ - -/* - * - * Register definitions for the Intel 8253 Programmable Interval Timer. - * - * This chip has three independent 16-bit down counters that can be - * read on the fly. There are three mode registers and three countdown - * registers. The countdown registers are addressed directly, via the - * first three I/O ports. The three mode registers are accessed via - * the fourth I/O port, with two bits in the mode byte indicating the - * register. (Why are hardware interfaces always so braindead?). - * - * To write a value into the countdown register, the mode register - * is first programmed with a command indicating the which byte of - * the two byte register is to be modified. The three possibilities - * are load msb (TMR_MR_MSB), load lsb (TMR_MR_LSB), or load lsb then - * msb (TMR_MR_BOTH). - * - * To read the current value ("on the fly") from the countdown register, - * you write a "latch" command into the mode register, then read the stable - * value from the corresponding I/O port. For example, you write - * TMR_MR_LATCH into the corresponding mode register. Presumably, - * after doing this, a write operation to the I/O port would result - * in undefined behavior (but hopefully not fry the chip). - * Reading in this manner has no side effects. - * - * [IBM-PC] - * The outputs of the three timers are connected as follows: - * - * timer 0 -> irq 0 - * timer 1 -> dma chan 0 (for dram refresh) - * timer 2 -> speaker (via keyboard controller) - * - * Timer 0 is used to call hardclock. - * Timer 2 is used to generate console beeps. - * - * [PC-9801] - * The outputs of the three timers are connected as follows: - * - * timer 0 -> irq 0 - * timer 1 -> speaker (via keyboard controller) - * timer 2 -> RS232C - * - * Timer 0 is used to call hardclock. - * Timer 1 is used to generate console beeps. - */ - -/* - * Macros for specifying values to be written into a mode register. - */ -#define TIMER_CNTR0 (IO_TIMER1 + 0) /* timer 0 counter port */ -#ifdef PC98 -#define TIMER_CNTR1 0x3fdb /* timer 1 counter port */ -#define TIMER_CNTR2 (IO_TIMER1 + 4) /* timer 2 counter port */ -#define TIMER_MODE (IO_TIMER1 + 6) /* timer mode port */ -#else -#define TIMER_CNTR1 (IO_TIMER1 + 1) /* timer 1 counter port */ -#define TIMER_CNTR2 (IO_TIMER1 + 2) /* timer 2 counter port */ -#define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */ -#endif -#define TIMER_SEL0 0x00 /* select counter 0 */ -#define TIMER_SEL1 0x40 /* select counter 1 */ -#define TIMER_SEL2 0x80 /* select counter 2 */ -#define TIMER_INTTC 0x00 /* mode 0, intr on terminal cnt */ -#define TIMER_ONESHOT 0x02 /* mode 1, one shot */ -#define TIMER_RATEGEN 0x04 /* mode 2, rate generator */ -#define TIMER_SQWAVE 0x06 /* mode 3, square wave */ -#define TIMER_SWSTROBE 0x08 /* mode 4, s/w triggered strobe */ -#define TIMER_HWSTROBE 0x0a /* mode 5, h/w triggered strobe */ -#define TIMER_LATCH 0x00 /* latch counter for reading */ -#define TIMER_LSB 0x10 /* r/w counter LSB */ -#define TIMER_MSB 0x20 /* r/w counter MSB */ -#define TIMER_16BIT 0x30 /* r/w counter 16 bits, LSB first */ -#define TIMER_BCD 0x01 /* count in BCD */ - diff --git a/sys/ia64/include/clock.h b/sys/ia64/include/clock.h index 41e3bf6..ef76769 100644 --- a/sys/ia64/include/clock.h +++ b/sys/ia64/include/clock.h @@ -13,16 +13,14 @@ #define CLOCK_VECTOR 254 -extern int disable_rtc_set; -extern int wall_cmos_clock; -extern int adjkerntz; +extern int adjkerntz; +extern int disable_rtc_set; +extern int wall_cmos_clock; -extern u_int64_t itc_frequency; -extern u_int64_t itm_reload; +extern uint64_t ia64_clock_reload; +extern uint64_t itc_frequency; -int sysbeep(int pitch, int period); -int acquire_timer2(int mode); -int release_timer2(void); +int sysbeep(int pitch, int period); #endif diff --git a/sys/ia64/include/cpu.h b/sys/ia64/include/cpu.h index da64afe..e31968d 100644 --- a/sys/ia64/include/cpu.h +++ b/sys/ia64/include/cpu.h @@ -75,18 +75,14 @@ struct clockframe { * CTL_MACHDEP definitions. */ #define CPU_CONSDEV 1 /* dev_t: console terminal device */ -#define CPU_ROOT_DEVICE 2 /* string: root device name */ -#define CPU_BOOTED_KERNEL 3 /* string: booted kernel name */ -#define CPU_ADJKERNTZ 4 /* int: timezone offset (seconds) */ -#define CPU_DISRTCSET 5 /* int: disable resettodr() call */ -#define CPU_WALLCLOCK 6 /* int: indicates wall CMOS clock */ -#define CPU_MAXID 7 /* valid machdep IDs */ +#define CPU_ADJKERNTZ 2 /* int: timezone offset (seconds) */ +#define CPU_DISRTCSET 3 /* int: disable resettodr() call */ +#define CPU_WALLCLOCK 4 /* int: indicates wall CMOS clock */ +#define CPU_MAXID 5 /* valid machdep IDs */ #define CTL_MACHDEP_NAMES { \ { 0, 0 }, \ { "console_device", CTLTYPE_STRUCT }, \ - { "root_device", CTLTYPE_STRING }, \ - { "booted_kernel", CTLTYPE_STRING }, \ { "adjkerntz", CTLTYPE_INT }, \ { "disable_rtc_set", CTLTYPE_INT }, \ { "wall_cmos_clock", CTLTYPE_INT }, \ @@ -100,11 +96,6 @@ struct reg; struct rpb; struct trapframe; -extern struct rpb *hwrpb; -extern volatile int mc_expected, mc_received; - -int badaddr(void *, size_t); -int badaddr_read(void *, size_t, void *); u_int64_t console_restart(u_int64_t, u_int64_t, u_int64_t); int do_ast(struct trapframe *); void dumpconf(void); @@ -118,8 +109,6 @@ void init_prom_interface(struct rpb*); void interrupt(u_int64_t, struct trapframe *); void machine_check(unsigned long, struct trapframe *, unsigned long, unsigned long); -u_int64_t hwrpb_checksum(void); -void hwrpb_restart_setup(void); void regdump(struct trapframe *); void regtoframe(struct reg *, struct trapframe *); void set_iointr(void (*)(void *, unsigned long)); diff --git a/sys/ia64/include/pcpu.h b/sys/ia64/include/pcpu.h index 46b47ce..38475fb 100644 --- a/sys/ia64/include/pcpu.h +++ b/sys/ia64/include/pcpu.h @@ -35,8 +35,10 @@ #define PCPU_MD_FIELDS \ struct pcb *pc_pcb; /* Used by IPI_STOP */ \ struct pmap *pc_current_pmap; /* active pmap */ \ - u_int64_t pc_lid; /* local CPU ID */ \ - u_int32_t pc_awake:1; /* CPU is awake? */ + uint64_t pc_lid; /* local CPU ID */ \ + uint32_t pc_awake:1; /* CPU is awake? */ \ + uint64_t pc_clock; /* Clock counter. */ \ + uint64_t pc_clockadj; /* Clock adjust. */ struct pcpu; @@ -46,6 +48,8 @@ register struct pcpu *pcpup __asm__("r13"); #define PCPU_PTR(member) (&pcpup->pc_ ## member) #define PCPU_SET(member,value) (pcpup->pc_ ## member = (value)) +void pcpu_initclock(void); + #endif /* _KERNEL */ #endif /* !_MACHINE_PCPU_H_ */ |