summaryrefslogtreecommitdiffstats
path: root/sys/pc98/cbus/pcrtc.c
diff options
context:
space:
mode:
authornyan <nyan@FreeBSD.org>2003-11-04 13:15:12 +0000
committernyan <nyan@FreeBSD.org>2003-11-04 13:15:12 +0000
commit2e3e36d4ab1ff895d8da29b9db277579957a4921 (patch)
tree0f50befbb8be577429e3cbc6eda967dd61d7a831 /sys/pc98/cbus/pcrtc.c
parentea0509b82b4458edf64f322e02b445156acca525 (diff)
downloadFreeBSD-src-2e3e36d4ab1ff895d8da29b9db277579957a4921.zip
FreeBSD-src-2e3e36d4ab1ff895d8da29b9db277579957a4921.tar.gz
MFi386: revision 1.206
Diffstat (limited to 'sys/pc98/cbus/pcrtc.c')
-rw-r--r--sys/pc98/cbus/pcrtc.c179
1 files changed, 13 insertions, 166 deletions
diff --git a/sys/pc98/cbus/pcrtc.c b/sys/pc98/cbus/pcrtc.c
index 3724de0..f919393 100644
--- a/sys/pc98/cbus/pcrtc.c
+++ b/sys/pc98/cbus/pcrtc.c
@@ -73,14 +73,13 @@
#include <machine/clock.h>
#include <machine/cputypes.h>
#include <machine/frame.h>
+#include <machine/intr_machdep.h>
#include <machine/md_var.h>
#include <machine/psl.h>
-#ifdef APIC_IO
-#include <machine/segments.h>
-#endif
-#if defined(SMP) || defined(APIC_IO)
+
+#if defined(SMP)
#include <machine/smp.h>
-#endif /* SMP || APIC_IO */
+#endif
#include <machine/specialreg.h>
#include <i386/isa/icu.h>
@@ -92,16 +91,6 @@
#endif
#include <i386/isa/timerreg.h>
-#include <i386/isa/intr_machdep.h>
-
-#ifdef APIC_IO
-#include <i386/isa/intr_machdep.h>
-/* The interrupt triggered by the 8254 (timer) chip */
-int apic_8254_intr;
-static u_long read_intr_count(int vec);
-static void setup_8254_mixed_mode(void);
-#endif
-
/*
* 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.
@@ -149,6 +138,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;
#ifndef BURN_BRIDGES
/*
* XXX new_function and timer_func should not handle clockframes, but
@@ -189,7 +179,7 @@ static struct timecounter i8254_timecounter = {
};
static void
-clkintr(struct clockframe frame)
+clkintr(struct clockframe *frame)
{
if (timecounter->tc_get_timecount == i8254_get_timecount) {
@@ -203,7 +193,7 @@ clkintr(struct clockframe frame)
clkintr_pending = 0;
mtx_unlock_spin(&clock_lock);
}
- timer_func(&frame);
+ timer_func(frame);
#ifdef SMP
if (timer_func == hardclock)
forward_hardclock();
@@ -218,7 +208,7 @@ clkintr(struct clockframe frame)
if ((timer0_prescaler_count += timer0_max_count)
>= hardclock_max_count) {
timer0_prescaler_count -= hardclock_max_count;
- hardclock(&frame);
+ hardclock(frame);
#ifdef SMP
forward_hardclock();
#endif
@@ -253,7 +243,7 @@ clkintr(struct clockframe frame)
timer0_prescaler_count = 0;
timer_func = hardclock;
timer0_state = RELEASED;
- hardclock(&frame);
+ hardclock(frame);
#ifdef SMP
forward_hardclock();
#endif
@@ -910,151 +900,14 @@ resettodr()
void
cpu_initclocks()
{
-#ifdef APIC_IO
- int apic_8254_trial;
- void *clkdesc;
-#endif /* APIC_IO */
- register_t crit;
-
-
- /* Finish initializing 8253 timer 0. */
-#ifdef APIC_IO
- apic_8254_intr = isa_apic_irq(0);
- apic_8254_trial = 0;
- if (apic_8254_intr >= 0 ) {
- if (apic_int_type(0, 0) == 3)
- apic_8254_trial = 1;
- } else {
- /* look for ExtInt on pin 0 */
- if (apic_int_type(0, 0) == 3) {
- apic_8254_intr = apic_irq(0, 0);
- setup_8254_mixed_mode();
- } else
- panic("APIC_IO: Cannot route 8254 interrupt to CPU");
- }
-
- inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL,
- INTR_TYPE_CLK | INTR_FAST, &clkdesc);
- crit = intr_disable();
- mtx_lock_spin(&icu_lock);
- INTREN(1 << apic_8254_intr);
- mtx_unlock_spin(&icu_lock);
- intr_restore(crit);
-
-#else /* APIC_IO */
-
- /*
- * 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);
-
-#endif /* APIC_IO */
-
-
-
-#ifdef APIC_IO
- if (apic_8254_trial) {
- printf("APIC_IO: Testing 8254 interrupt delivery\n");
- while (read_intr_count(8) < 6)
- ; /* nothing */
- if (read_intr_count(apic_8254_intr) < 3) {
- /*
- * The MP table is broken.
- * The 8254 was not connected to the specified pin
- * on the IO APIC.
- * Workaround: Limited variant of mixed mode.
- */
-
- crit = intr_disable();
- mtx_lock_spin(&icu_lock);
- INTRDIS(1 << apic_8254_intr);
- mtx_unlock_spin(&icu_lock);
- intr_restore(crit);
- inthand_remove(clkdesc);
- printf("APIC_IO: Broken MP table detected: "
- "8254 is not connected to "
- "IOAPIC #%d intpin %d\n",
- int_to_apicintpin[apic_8254_intr].ioapic,
- int_to_apicintpin[apic_8254_intr].int_pin);
- /*
- * Revoke current ISA IRQ 0 assignment and
- * configure a fallback interrupt routing from
- * the 8254 Timer via the 8259 PIC to the
- * an ExtInt interrupt line on IOAPIC #0 intpin 0.
- * We reuse the low level interrupt handler number.
- */
- if (apic_irq(0, 0) < 0) {
- revoke_apic_irq(apic_8254_intr);
- assign_apic_irq(0, 0, apic_8254_intr);
- }
- apic_8254_intr = apic_irq(0, 0);
- setup_8254_mixed_mode();
- inthand_add("clk", apic_8254_intr,
- (driver_intr_t *)clkintr, NULL,
- INTR_TYPE_CLK | INTR_FAST, NULL);
- crit = intr_disable();
- mtx_lock_spin(&icu_lock);
- INTREN(1 << apic_8254_intr);
- mtx_unlock_spin(&icu_lock);
- intr_restore(crit);
- }
-
- }
- if (apic_int_type(0, 0) != 3 ||
- int_to_apicintpin[apic_8254_intr].ioapic != 0 ||
- int_to_apicintpin[apic_8254_intr].int_pin != 0)
- printf("APIC_IO: routing 8254 via IOAPIC #%d intpin %d\n",
- int_to_apicintpin[apic_8254_intr].ioapic,
- int_to_apicintpin[apic_8254_intr].int_pin);
- else
- printf("APIC_IO: "
- "routing 8254 via 8259 and IOAPIC #0 intpin 0\n");
-#endif
-
init_TSC_tc();
}
-#ifdef APIC_IO
-static u_long
-read_intr_count(int vec)
-{
- u_long *up;
- up = intr_countp[vec];
- if (up)
- return *up;
- return 0UL;
-}
-
-static void
-setup_8254_mixed_mode()
-{
- /*
- * Allow 8254 timer to INTerrupt 8259:
- * re-initialize master 8259:
- * reset; prog 4 bytes, single ICU, edge triggered
- */
- outb(IO_ICU1, 0x13);
- outb(IO_ICU1 + 2, NRSVIDT); /* start vector (unused) */
- outb(IO_ICU1 + 2, 0x00); /* ignore slave */
- outb(IO_ICU1 + 2, 0x03); /* auto EOI, 8086 */
- outb(IO_ICU1 + 2, 0xfe); /* unmask INT0 */
-
- /* program IO APIC for type 3 INT on INT0 */
- if (ext_int_setup(0, 0) < 0)
- panic("8254 redirect via APIC pin0 impossible!");
-}
-#endif
-
void
cpu_startprofclock(void)
{
@@ -1110,14 +963,8 @@ i8254_get_timecount(struct timecounter *tc)
if (count < i8254_lastcount ||
(!i8254_ticked && (clkintr_pending ||
((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) &&
-#ifdef APIC_IO
-#define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */
- /* XXX this assumes that apic_8254_intr is < 24. */
- (lapic_irr1 & (1 << apic_8254_intr))))
-#else
- (inb(IO_ICU1) & 1)))
-#endif
- )) {
+ i8254_intsrc != NULL &&
+ i8254_intsrc->is_pic->pic_source_pending(i8254_intsrc))))) {
i8254_ticked = 1;
i8254_offset += timer0_max_count;
}
OpenPOWER on IntegriCloud