summaryrefslogtreecommitdiffstats
path: root/sys/amd64/isa/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/amd64/isa/clock.c')
-rw-r--r--sys/amd64/isa/clock.c52
1 files changed, 22 insertions, 30 deletions
diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c
index a11afb4..a2e751e 100644
--- a/sys/amd64/isa/clock.c
+++ b/sys/amd64/isa/clock.c
@@ -69,8 +69,12 @@ __FBSDID("$FreeBSD$");
#include <machine/clock.h>
#include <machine/frame.h>
+#include <machine/intr_machdep.h>
#include <machine/md_var.h>
#include <machine/psl.h>
+#ifdef SMP
+#include <machine/smp.h>
+#endif
#include <machine/specialreg.h>
#include <amd64/isa/icu.h>
@@ -81,8 +85,6 @@ __FBSDID("$FreeBSD$");
#endif
#include <amd64/isa/timerreg.h>
-#include <amd64/isa/intr_machdep.h>
-
/*
* 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.
@@ -112,6 +114,7 @@ static u_int hardclock_max_count;
static u_int32_t i8254_lastcount;
static u_int32_t i8254_offset;
static int i8254_ticked;
+static struct intsrc *i8254_intsrc;
static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
@@ -122,7 +125,6 @@ static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
#define ACQUIRE_PENDING 3
static u_char timer2_state;
-static void (*timer_func)(struct clockframe *frame) = hardclock;
static unsigned i8254_get_timecount(struct timecounter *tc);
static void set_timer_freq(u_int freq, int intr_freq);
@@ -137,7 +139,7 @@ static struct timecounter i8254_timecounter = {
};
static void
-clkintr(struct clockframe frame)
+clkintr(struct clockframe *frame)
{
if (timecounter->tc_get_timecount == i8254_get_timecount) {
@@ -151,7 +153,10 @@ clkintr(struct clockframe frame)
clkintr_pending = 0;
mtx_unlock_spin(&clock_lock);
}
- timer_func(&frame);
+ hardclock(frame);
+#ifdef SMP
+ forward_hardclock();
+#endif
}
int
@@ -207,16 +212,19 @@ release_timer2()
* in the statistics, but the stat clock will no longer stop.
*/
static void
-rtcintr(struct clockframe frame)
+rtcintr(struct clockframe *frame)
{
while (rtcin(RTC_INTR) & RTCIR_PERIOD) {
if (profprocs != 0) {
if (--pscnt == 0)
pscnt = psdiv;
- profclock(&frame);
+ profclock(frame);
}
if (pscnt == psdiv)
- statclock(&frame);
+ statclock(frame);
+#ifdef SMP
+ forward_statclock();
+#endif
}
}
@@ -719,7 +727,6 @@ void
cpu_initclocks()
{
int diag;
- register_t crit;
if (statclock_disable) {
/*
@@ -735,19 +742,9 @@ cpu_initclocks()
profhz = RTC_PROFRATE;
}
- /* Finish initializing 8253 timer 0. */
- /*
- * XXX Check the priority of this interrupt handler. I
- * couldn't find anything suitable in the BSD/OS code (grog,
- * 19 July 2000).
- */
- inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL,
+ /* Finish initializing 8254 timer 0. */
+ intr_add_handler("clk", 0, (driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
- crit = intr_disable();
- mtx_lock_spin(&icu_lock);
- INTREN(IRQ0);
- mtx_unlock_spin(&icu_lock);
- intr_restore(crit);
/* Initialize RTC. */
writertc(RTC_STATUSA, rtc_statusa);
@@ -760,14 +757,9 @@ cpu_initclocks()
if (diag != 0)
printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
- inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL,
+ intr_add_handler("rtc", 8, (driver_intr_t *)rtcintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
-
- crit = intr_disable();
- mtx_lock_spin(&icu_lock);
- INTREN(IRQ8);
- mtx_unlock_spin(&icu_lock);
- intr_restore(crit);
+ i8254_intsrc = intr_lookup_source(8);
writertc(RTC_STATUSB, rtc_statusb);
@@ -833,8 +825,8 @@ i8254_get_timecount(struct timecounter *tc)
if (count < i8254_lastcount ||
(!i8254_ticked && (clkintr_pending ||
((count < 20 || (!(rflags & PSL_I) && count < timer0_max_count / 2u)) &&
- (inb(IO_ICU1) & 1)))
- )) {
+ i8254_intsrc != NULL &&
+ i8254_intsrc->is_pic->pic_source_pending(i8254_intsrc))))) {
i8254_ticked = 1;
i8254_offset += timer0_max_count;
}
OpenPOWER on IntegriCloud