-/* $OpenBSD: acpi_machdep.c,v 1.40 2010/07/06 06:25:56 deraadt Exp $ */
+/* $OpenBSD: acpi_machdep.c,v 1.41 2010/07/25 21:43:38 deraadt Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
#if NLAPIC > 0
lapic_enable();
- lapic_initclocks();
+ if (initclock_func == lapic_initclocks)
+ lapic_startclock();
lapic_set_lvt();
#endif
#if NIOAPIC > 0
ioapic_enable();
#endif
- initrtclock();
+ i8254_startclock();
+ if (initclock_func == i8254_initclocks)
+ rtcstart(); /* in i8254 mode, rtc is profclock */
inittodr(time_second);
return (0);
-/* $OpenBSD: autoconf.c,v 1.34 2010/07/01 00:24:27 thib Exp $ */
+/* $OpenBSD: autoconf.c,v 1.35 2010/07/25 21:43:38 deraadt Exp $ */
/* $NetBSD: autoconf.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */
/*-
x86_64_proc0_tss_ldt_init();
- startrtclock();
-
if (config_rootfound("mainbus", NULL) == NULL)
panic("configure: mainbus not configured");
-/* $OpenBSD: cpu.c,v 1.34 2010/06/26 23:24:43 guenther Exp $ */
+/* $OpenBSD: cpu.c,v 1.35 2010/07/25 21:43:38 deraadt Exp $ */
/* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */
/*-
ci->ci_flags |= CPUF_PRESENT;
lapic_enable();
- lapic_initclocks();
+ lapic_startclock();
while ((ci->ci_flags & CPUF_GO) == 0)
delay(10);
-/* $OpenBSD: lapic.c,v 1.25 2010/07/23 07:21:02 matthew Exp $ */
+/* $OpenBSD: lapic.c,v 1.26 2010/07/25 21:43:38 deraadt Exp $ */
/* $NetBSD: lapic.c,v 1.2 2003/05/08 01:04:35 fvdl Exp $ */
/*-
}
void
-lapic_initclocks(void)
+lapic_startclock(void)
{
/*
* Start local apic countdown timer running, in repeated mode.
i82489_writereg(LAPIC_LVTT, LAPIC_LVTT_TM|LAPIC_TIMER_VECTOR);
}
+void
+lapic_initclocks(void)
+{
+ lapic_startclock();
+
+ i8254_inittimecounter_simple();
+}
+
+
extern int gettick(void); /* XXX put in header file */
extern u_long rtclock_tval; /* XXX put in header file */
-extern void (*initclock_func)(void); /* XXX put in header file */
/*
* Calibrate the local apic count-down timer (which is running at
-/* $OpenBSD: machdep.c,v 1.117 2010/07/23 14:56:31 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.118 2010/07/25 21:43:38 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */
/*-
initmsgbuf((caddr_t)msgbuf_vaddr, round_page(MSGBUFSIZE));
printf("%s", version);
+ startclocks();
printf("real mem = %lu (%luMB)\n", ptoa((psize_t)physmem),
ptoa((psize_t)physmem)/1024/1024);
cpu_initclocks(void)
{
(*initclock_func)();
-
- if (initclock_func == i8254_initclocks)
- i8254_inittimecounter();
- else
- i8254_inittimecounter_simple();
}
void
-/* $OpenBSD: cpu.h,v 1.52 2010/07/21 14:08:09 kettenis Exp $ */
+/* $OpenBSD: cpu.h,v 1.53 2010/07/25 21:43:38 deraadt Exp $ */
/* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */
/*-
void child_trampoline(void);
/* clock.c */
-void initrtclock(void);
-void startrtclock(void);
+extern void (*initclock_func)(void);
+void startclocks(void);
+void rtcstart(void);
void i8254_delay(int);
void i8254_initclocks(void);
+void i8254_startclock(void);
void i8254_inittimecounter(void);
void i8254_inittimecounter_simple(void);
-/* $OpenBSD: i82489var.h,v 1.10 2009/06/09 02:56:38 krw Exp $ */
+/* $OpenBSD: i82489var.h,v 1.11 2010/07/25 21:43:38 deraadt Exp $ */
/* $NetBSD: i82489var.h,v 1.1 2003/02/26 21:26:10 fvdl Exp $ */
/*-
extern void lapic_set_lvt(void);
extern void lapic_enable(void);
extern void lapic_calibrate_timer(struct cpu_info *ci);
+extern void lapic_startclock(void);
extern void lapic_initclocks(void);
#endif
-/* $OpenBSD: clock.c,v 1.13 2007/08/02 16:40:27 deraadt Exp $ */
+/* $OpenBSD: clock.c,v 1.14 2010/07/25 21:43:38 deraadt Exp $ */
/* $NetBSD: clock.c,v 1.1 2003/04/26 18:39:50 fvdl Exp $ */
/*-
struct mutex timer_mutex = MUTEX_INITIALIZER(IPL_HIGH);
u_long rtclock_tval;
-int rtclock_init;
-/* minimal initialization, enough for delay() */
void
-initrtclock(void)
+startclocks(void)
{
- u_long tval;
-
- /*
- * Compute timer_count, the count-down count the timer will be
- * set to. Also, correctly round
- * this by carrying an extra bit through the division.
- */
- tval = (TIMER_FREQ * 2) / (u_long) hz;
- tval = (tval / 2) + (tval & 0x1);
+ int s;
mtx_enter(&timer_mutex);
- /* initialize 8253 clock */
- outb(IO_TIMER1+TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
-
- /* Correct rounding will buy us a better precision in timekeeping */
- outb(IO_TIMER1+TIMER_CNTR0, tval % 256);
- outb(IO_TIMER1+TIMER_CNTR0, tval / 256);
-
- rtclock_tval = tval;
- rtclock_init = 1;
+ rtclock_tval = TIMER_DIV(hz);
+ i8254_startclock();
mtx_leave(&timer_mutex);
-}
-
-void
-startrtclock(void)
-{
- int s;
-
- if (!rtclock_init)
- initrtclock();
/* Check diagnostic status */
if ((s = mc146818_read(NULL, NVRAM_DIAG)) != 0) /* XXX softc */
24, 25, 27, 28, 29, 30,
};
- /* allow DELAY() to be used before startrtclock() */
- if (!rtclock_init)
- initrtclock();
-
/*
* Read the counter first, so that the rest of the setup overhead is
* counted.
void
i8254_initclocks(void)
{
- static struct timeout rtcdrain_timeout;
-
stathz = 128;
profhz = 1024;
isa_intr_establish(NULL, 0, IST_PULSE, IPL_CLOCK, clockintr,
0, "clock");
- isa_intr_establish(NULL, 8, IST_PULSE, IPL_CLOCK, rtcintr, 0, "rtc");
+ isa_intr_establish(NULL, 8, IST_PULSE, IPL_CLOCK, rtcintr,
+ 0, "rtc");
+
+ rtcstart(); /* start the mc146818 clock */
+}
+
+void
+rtcstart(void)
+{
+ static struct timeout rtcdrain_timeout;
mc146818_write(NULL, MC_REGA, MC_BASE_32_KHz | MC_RATE_128_Hz);
mc146818_write(NULL, MC_REGB, MC_REGB_24HR | MC_REGB_PIE);
void
i8254_inittimecounter_simple(void)
{
- u_long tval = 0x8000;
-
i8254_timecounter.tc_get_timecount = i8254_simple_get_timecount;
i8254_timecounter.tc_counter_mask = 0x7fff;
-
i8254_timecounter.tc_frequency = TIMER_FREQ;
mtx_enter(&timer_mutex);
- outb(IO_TIMER1 + TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
- outb(IO_TIMER1 + TIMER_CNTR0, tval & 0xff);
- outb(IO_TIMER1 + TIMER_CNTR0, tval >> 8);
-
- rtclock_tval = tval;
- rtclock_init = 1;
+ rtclock_tval = 0x8000;
+ i8254_startclock();
mtx_leave(&timer_mutex);
tc_init(&i8254_timecounter);
}
+void
+i8254_startclock(void)
+{
+ u_long tval = rtclock_tval;
+
+ outb(IO_TIMER1 + TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
+ outb(IO_TIMER1 + TIMER_CNTR0, tval & 0xff);
+ outb(IO_TIMER1 + TIMER_CNTR0, tval >> 8);
+}
+
u_int
i8254_simple_get_timecount(struct timecounter *tc)
{
-/* $OpenBSD: acpi_machdep.c,v 1.34 2010/07/06 06:25:55 deraadt Exp $ */
+/* $OpenBSD: acpi_machdep.c,v 1.35 2010/07/25 21:43:35 deraadt Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
#if NLAPIC > 0
lapic_enable();
- lapic_initclocks();
+ if (initclock_func == lapic_initclocks)
+ lapic_startclock();
lapic_set_lvt();
#endif
#if NIOAPIC > 0
ioapic_enable();
#endif
- initrtclock();
+ i8254_startclock();
+ if (initclock_func == i8254_initclocks)
+ rtcstart(); /* in i8254 mode, rtc is profclock */
inittodr(time_second);
return (0);
-/* $OpenBSD: apm.c,v 1.87 2010/07/20 12:23:00 deraadt Exp $ */
+/* $OpenBSD: apm.c,v 1.88 2010/07/25 21:43:35 deraadt Exp $ */
/*-
* Copyright (c) 1998-2001 Michael Shalayeff. All rights reserved.
apm_resumes = APM_RESUME_HOLDOFF;
- /* they say that some machines may require reinitializing the clock */
- initrtclock();
+ /* they say that some machines may require reinitializing the clocks */
+ i8254_startclock();
+ if (initclock_func == i8254_initclocks)
+ rtcstart(); /* in i8254 mode, rtc is profclock */
inittodr(time_second);
/* lower bit in cx means pccard was powered down */
-/* $OpenBSD: autoconf.c,v 1.84 2010/06/28 22:20:12 deraadt Exp $ */
+/* $OpenBSD: autoconf.c,v 1.85 2010/07/25 21:43:35 deraadt Exp $ */
/* $NetBSD: autoconf.c,v 1.20 1996/05/03 19:41:56 christos Exp $ */
/*-
* architectures. This fact is used by the pcmcia irq line probing.
*/
- startrtclock();
-
gdt_init(); /* XXX - pcibios uses gdt stuff */
/* Set up proc0's TSS and LDT */
-/* $OpenBSD: cpu.c,v 1.40 2010/06/26 23:24:43 guenther Exp $ */
+/* $OpenBSD: cpu.c,v 1.41 2010/07/25 21:43:35 deraadt Exp $ */
/* $NetBSD: cpu.c,v 1.1.2.7 2000/06/26 02:04:05 sommerfeld Exp $ */
/*-
cpu_init_idt();
lapic_enable();
- lapic_initclocks();
+ lapic_startclock();
lapic_set_lvt();
gdt_init_cpu(ci);
cpu_init_ldt(ci);
-/* $OpenBSD: lapic.c,v 1.29 2010/07/23 07:21:02 matthew Exp $ */
+/* $OpenBSD: lapic.c,v 1.30 2010/07/25 21:43:35 deraadt Exp $ */
/* $NetBSD: lapic.c,v 1.1.2.8 2000/02/23 06:10:50 sommerfeld Exp $ */
/*-
}
void
-lapic_initclocks(void)
+lapic_startclock(void)
{
/*
* Start local apic countdown timer running, in repeated mode.
i82489_writereg(LAPIC_LVTT, LAPIC_LVTT_TM|LAPIC_TIMER_VECTOR);
}
+void
+lapic_initclocks(void)
+{
+ lapic_startclock();
+
+ i8254_inittimecounter_simple();
+}
+
extern int gettick(void); /* XXX put in header file */
-extern void (*initclock_func)(void); /* XXX put in header file */
/*
* Calibrate the local apic count-down timer (which is running at
-/* $OpenBSD: machdep.c,v 1.479 2010/07/23 14:56:31 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.480 2010/07/25 21:43:35 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */
/*-
initmsgbuf((caddr_t)msgbufp, round_page(MSGBUFSIZE));
printf("%s", version);
- startrtclock();
+ startclocks();
/*
* We need to call identifycpu here early, so users have at least some
void
cpu_initclocks(void)
{
- (*initclock_func)();
-
- if (initclock_func == i8254_initclocks)
- i8254_inittimecounter();
- else
- i8254_inittimecounter_simple();
+ (*initclock_func)(); /* lapic or i8254 */
}
void
-/* $OpenBSD: cpu.h,v 1.111 2010/07/21 14:08:09 kettenis Exp $ */
+/* $OpenBSD: cpu.h,v 1.112 2010/07/25 21:43:37 deraadt Exp $ */
/* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */
/*-
void proc_trampoline(void);
/* clock.c */
-void initrtclock(void);
-void startrtclock(void);
+extern void (*initclock_func)(void);
+void startclocks(void);
void rtcdrain(void *);
+void rtcstart(void);
void i8254_delay(int);
void i8254_initclocks(void);
+void i8254_startclock(void);
void i8254_inittimecounter(void);
void i8254_inittimecounter_simple(void);
-
#if !defined(SMALL_KERNEL)
/* est.c */
void est_init(const char *, int);
-/* $OpenBSD: i82489var.h,v 1.10 2009/06/03 00:49:12 art Exp $ */
+/* $OpenBSD: i82489var.h,v 1.11 2010/07/25 21:43:37 deraadt Exp $ */
/* $NetBSD: i82489var.h,v 1.1.2.2 2000/02/21 18:46:14 sommerfeld Exp $ */
/*-
struct cpu_info;
extern void lapic_boot_init(paddr_t);
+extern void lapic_startclock(void);
extern void lapic_initclocks(void);
extern void lapic_set_lvt(void);
extern void lapic_set_softvectors(void);
-/* $OpenBSD: clock.c,v 1.42 2009/01/29 13:36:17 kettenis Exp $ */
+/* $OpenBSD: clock.c,v 1.43 2010/07/25 21:43:37 deraadt Exp $ */
/* $NetBSD: clock.c,v 1.39 1996/05/12 23:11:54 mycroft Exp $ */
/*-
}
void
-startrtclock(void)
+startclocks(void)
{
int s;
- initrtclock();
+ mtx_enter(&timer_mutex);
+ rtclock_tval = TIMER_DIV(hz);
+ i8254_startclock();
+ mtx_leave(&timer_mutex);
/* Check diagnostic status */
if ((s = mc146818_read(NULL, NVRAM_DIAG)) != 0) /* XXX softc */
; /* Nothing. */
}
-void
-initrtclock(void)
-{
- mtx_enter(&timer_mutex);
-
- /* initialize 8253 clock */
- outb(IO_TIMER1 + TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
-
- /* Correct rounding will buy us a better precision in timekeeping */
- outb(IO_TIMER1, TIMER_DIV(hz) % 256);
- outb(IO_TIMER1, TIMER_DIV(hz) / 256);
-
- rtclock_tval = TIMER_DIV(hz);
- mtx_leave(&timer_mutex);
-}
-
int
clockintr(void *arg)
{
void
i8254_initclocks(void)
{
- static struct timeout rtcdrain_timeout;
+ /* When using i8254 for clock, we also use the rtc for profclock */
+ (void)isa_intr_establish(NULL, 0, IST_PULSE, IPL_CLOCK,
+ clockintr, 0, "clock");
+ (void)isa_intr_establish(NULL, 8, IST_PULSE, IPL_CLOCK,
+ rtcintr, 0, "rtc");
- /*
- * XXX If you're doing strange things with multiple clocks, you might
- * want to keep track of clock handlers.
- */
- (void)isa_intr_establish(NULL, 0, IST_PULSE, IPL_CLOCK, clockintr,
- 0, "clock");
- (void)isa_intr_establish(NULL, 8, IST_PULSE, IPL_CLOCK, rtcintr,
- 0, "rtc");
+ rtcstart(); /* start the mc146818 clock */
+
+ i8254_inittimecounter(); /* hook the interrupt-based i8254 tc */
+}
+
+void
+rtcstart(void)
+{
+ static struct timeout rtcdrain_timeout;
mc146818_write(NULL, MC_REGA, MC_BASE_32_KHz | MC_RATE_128_Hz);
mc146818_write(NULL, MC_REGB, MC_REGB_24HR | MC_REGB_PIE);
void
i8254_inittimecounter_simple(void)
{
- u_long tval = 0x8000;
-
i8254_timecounter.tc_get_timecount = i8254_simple_get_timecount;
i8254_timecounter.tc_counter_mask = 0x7fff;
-
i8254_timecounter.tc_frequency = TIMER_FREQ;
mtx_enter(&timer_mutex);
- outb(IO_TIMER1 + TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
- outb(IO_TIMER1, tval & 0xff);
- outb(IO_TIMER1, tval >> 8);
-
- rtclock_tval = tval;
+ rtclock_tval = 0x8000;
+ i8254_startclock();
mtx_leave(&timer_mutex);
tc_init(&i8254_timecounter);
}
+void
+i8254_startclock(void)
+{
+ u_long tval = rtclock_tval;
+
+ outb(IO_TIMER1 + TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
+ outb(IO_TIMER1 + TIMER_CNTR0, tval & 0xff);
+ outb(IO_TIMER1 + TIMER_CNTR0, tval >> 8);
+}
+
u_int
i8254_simple_get_timecount(struct timecounter *tc)
{