summaryrefslogtreecommitdiffstats
path: root/sys/x86
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2010-06-22 19:42:27 +0000
committermav <mav@FreeBSD.org>2010-06-22 19:42:27 +0000
commit53ba2d6cf389865ec998d1c32f68a9e83e0a0f13 (patch)
treea4a0e64c2b9b08481cd4dd8fb84674dc9f7f92d4 /sys/x86
parent79968169e934b9ecf6c8e3a1a3225f0589c8fdf4 (diff)
downloadFreeBSD-src-53ba2d6cf389865ec998d1c32f68a9e83e0a0f13.zip
FreeBSD-src-53ba2d6cf389865ec998d1c32f68a9e83e0a0f13.tar.gz
Add "legacy route" support to HPET driver. When enabled, this mode makes
HPET to steal IRQ0 from i8254 and IRQ8 from RTC timers. It can be suitable for HPETs without FSB interrupts support, as it gives them two unshared IRQs. It allows them to provide one per-CPU event timer on dual-CPU system, that should be suitable for further tickless kernels. To enable it, such lines may be added to /boot/loader.conf: hint.atrtc.0.clock=0 hint.attimer.0.clock=0 hint.hpet.0.legacy_route=1
Diffstat (limited to 'sys/x86')
-rw-r--r--sys/x86/isa/atrtc.c31
-rw-r--r--sys/x86/isa/clock.c29
2 files changed, 32 insertions, 28 deletions
diff --git a/sys/x86/isa/atrtc.c b/sys/x86/isa/atrtc.c
index fe2a876..dc0a89b 100644
--- a/sys/x86/isa/atrtc.c
+++ b/sys/x86/isa/atrtc.c
@@ -244,34 +244,35 @@ static int
atrtc_attach(device_t dev)
{
struct atrtc_softc *sc;
- int i, diag, haveirq = 0;
+ int i, diag;
sc = device_get_softc(dev);
if (!(sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT,
&sc->port_rid, IO_RTC, IO_RTC + 1, 2, RF_ACTIVE)))
device_printf(dev,"Warning: Couldn't map I/O.\n");
- if (!(sc->intr_res = bus_alloc_resource(dev, SYS_RES_IRQ,
- &sc->intr_rid, 8, 8, 1, RF_ACTIVE)))
- device_printf(dev,"Couldn't map Interrupt.\n");
- else if ((bus_setup_intr(dev, sc->intr_res,
- INTR_MPSAFE | INTR_TYPE_CLK, (driver_filter_t *)rtc_intr, NULL,
- sc, &sc->intr_handler))) {
- device_printf(dev, "Can't setup interrupt.\n");
- } else {
- haveirq = 1;
- /* Bind IRQ to BSP to avoid live migration. */
- bus_bind_intr(dev, sc->intr_res, 0);
- }
diag = rtcin(RTC_DIAG);
if (diag != 0)
printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
atrtc_start();
clock_register(dev, 1000000);
bzero(&sc->et, sizeof(struct eventtimer));
- if (haveirq &&
- !atrtcclock_disable &&
+ if (!atrtcclock_disable &&
(resource_int_value(device_get_name(dev), device_get_unit(dev),
"clock", &i) != 0 || i != 0)) {
+ if (!(sc->intr_res = bus_alloc_resource(dev, SYS_RES_IRQ,
+ &sc->intr_rid, 8, 8, 1, RF_ACTIVE))) {
+ device_printf(dev,"Can't map interrupt.\n");
+ return (0);
+ } else if ((bus_setup_intr(dev, sc->intr_res,
+ INTR_MPSAFE | INTR_TYPE_CLK,
+ (driver_filter_t *)rtc_intr, NULL,
+ sc, &sc->intr_handler))) {
+ device_printf(dev, "Can't setup interrupt.\n");
+ return (0);
+ } else {
+ /* Bind IRQ to BSP to avoid live migration. */
+ bus_bind_intr(dev, sc->intr_res, 0);
+ }
sc->et.et_name = "RTC";
sc->et.et_flags = ET_FLAGS_PERIODIC;
sc->et.et_quality = 0;
diff --git a/sys/x86/isa/clock.c b/sys/x86/isa/clock.c
index 5929f5b..69327d0 100644
--- a/sys/x86/isa/clock.c
+++ b/sys/x86/isa/clock.c
@@ -522,9 +522,6 @@ attimer_attach(device_t dev)
attimer_sc = sc = device_get_softc(dev);
bzero(sc, sizeof(struct attimer_softc));
- if (!(sc->intr_res = bus_alloc_resource(dev, SYS_RES_IRQ,
- &sc->intr_rid, 0, 0, 1, RF_ACTIVE)))
- device_printf(dev,"Warning: Couldn't map Interrupt.\n");
i8254_intsrc = intr_lookup_source(0);
if (i8254_intsrc != NULL)
i8254_pending = i8254_intsrc->is_pic->pic_source_pending;
@@ -538,6 +535,11 @@ attimer_attach(device_t dev)
tc_init(&sc->tc);
if (resource_int_value(device_get_name(dev), device_get_unit(dev),
"clock", &i) != 0 || i != 0) {
+ if (!(sc->intr_res = bus_alloc_resource(dev, SYS_RES_IRQ,
+ &sc->intr_rid, 0, 0, 1, RF_ACTIVE))) {
+ device_printf(dev,"Can't map interrupt.\n");
+ return (0);
+ }
/* Dirty hack, to make bus_setup_intr to not enable source. */
i8254_intsrc->is_handlers++;
if ((bus_setup_intr(dev, sc->intr_res,
@@ -545,18 +547,19 @@ attimer_attach(device_t dev)
(driver_filter_t *)clkintr, NULL,
sc, &sc->intr_handler))) {
device_printf(dev, "Can't setup interrupt.\n");
- } else {
- i8254_intsrc->is_pic->pic_enable_intr(i8254_intsrc);
- sc->et.et_name = "i8254";
- sc->et.et_flags = ET_FLAGS_PERIODIC;
- sc->et.et_quality = 100;
- sc->et.et_frequency = i8254_freq;
- sc->et.et_start = attimer_start;
- sc->et.et_stop = attimer_stop;
- sc->et.et_priv = dev;
- et_register(&sc->et);
+ i8254_intsrc->is_handlers--;
+ return (0);
}
i8254_intsrc->is_handlers--;
+ i8254_intsrc->is_pic->pic_enable_intr(i8254_intsrc);
+ sc->et.et_name = "i8254";
+ sc->et.et_flags = ET_FLAGS_PERIODIC;
+ sc->et.et_quality = 100;
+ sc->et.et_frequency = i8254_freq;
+ sc->et.et_start = attimer_start;
+ sc->et.et_stop = attimer_stop;
+ sc->et.et_priv = dev;
+ et_register(&sc->et);
}
return(0);
}
OpenPOWER on IntegriCloud