summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2003-08-04 05:13:18 +0000
committermarcel <marcel@FreeBSD.org>2003-08-04 05:13:18 +0000
commitd5a33e59d13687ecea3a42a2b0b563e2b45dfaa2 (patch)
tree53c0285dd78b50088e45353c7f9f616322b81ed4 /sys
parent321771d2627fb7dfe7408a8f7a6bc6dd85ddac97 (diff)
downloadFreeBSD-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.c330
-rw-r--r--sys/ia64/ia64/interrupt.c119
-rw-r--r--sys/ia64/ia64/machdep.c26
-rw-r--r--sys/ia64/ia64/mp_machdep.c7
-rw-r--r--sys/ia64/ia64/timerreg.h110
-rw-r--r--sys/ia64/include/clock.h14
-rw-r--r--sys/ia64/include/cpu.h19
-rw-r--r--sys/ia64/include/pcpu.h8
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_ */
OpenPOWER on IntegriCloud