diff options
author | jhb <jhb@FreeBSD.org> | 2012-03-09 19:42:48 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2012-03-09 19:42:48 +0000 |
commit | d6f48ea8cc824233cf311f52698aa98f62065584 (patch) | |
tree | bf27eb31fac1ca30ea2152bdc3f12d14df7dd127 | |
parent | 54d8cc97bcf8a99f389868615106ee6be57bdd11 (diff) | |
download | FreeBSD-src-d6f48ea8cc824233cf311f52698aa98f62065584.zip FreeBSD-src-d6f48ea8cc824233cf311f52698aa98f62065584.tar.gz |
Allow a native i386 kernel to be built with 'nodevice atpic'. Just as on
amd64, if 'device isa' is present quiesce the 8259A's during boot and
resume from suspend.
While here, be more selective on amd64 about which kernel configurations
need elcr.c.
MFC after: 2 weeks
-rw-r--r-- | sys/conf/files.amd64 | 2 | ||||
-rw-r--r-- | sys/conf/files.i386 | 4 | ||||
-rw-r--r-- | sys/i386/i386/exception.s | 7 | ||||
-rw-r--r-- | sys/i386/i386/intr_machdep.c | 34 | ||||
-rw-r--r-- | sys/i386/i386/machdep.c | 29 | ||||
-rw-r--r-- | sys/i386/include/intr_machdep.h | 3 |
6 files changed, 75 insertions, 4 deletions
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 8ab1cbc..b5c4fb4 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -466,7 +466,7 @@ x86/cpufreq/p4tcc.c optional cpufreq x86/isa/atpic.c optional atpic isa x86/isa/atrtc.c standard x86/isa/clock.c standard -x86/isa/elcr.c standard +x86/isa/elcr.c optional atpic isa | mptable x86/isa/isa.c standard x86/isa/isa_dma.c standard x86/isa/nmi.c standard diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 5064f0d..54636c6 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -516,9 +516,9 @@ x86/cpufreq/p4tcc.c optional cpufreq x86/cpufreq/powernow.c optional cpufreq x86/cpufreq/smist.c optional cpufreq x86/isa/atpic.c optional atpic -x86/isa/atrtc.c optional atpic +x86/isa/atrtc.c optional native x86/isa/clock.c optional native -x86/isa/elcr.c standard +x86/isa/elcr.c optional atpic | apic native x86/isa/isa.c optional isa x86/isa/isa_dma.c optional isa x86/isa/nmi.c standard diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s index 13562fa..e969d32 100644 --- a/sys/i386/i386/exception.s +++ b/sys/i386/i386/exception.s @@ -35,6 +35,7 @@ */ #include "opt_apic.h" +#include "opt_atpic.h" #include "opt_hwpmc_hooks.h" #include "opt_kdtrace.h" #include "opt_npx.h" @@ -299,14 +300,18 @@ ENTRY(fork_trampoline) SUPERALIGN_TEXT MCOUNT_LABEL(bintr) +#ifdef DEV_ATPIC #include <i386/i386/atpic_vector.s> +#endif -#ifdef DEV_APIC +#if defined(DEV_APIC) && defined(DEV_ATPIC) .data .p2align 4 .text SUPERALIGN_TEXT +#endif +#ifdef DEV_APIC #include <i386/i386/apic_vector.s> #endif diff --git a/sys/i386/i386/intr_machdep.c b/sys/i386/i386/intr_machdep.c index eb6bfa1..2081757 100644 --- a/sys/i386/i386/intr_machdep.c +++ b/sys/i386/i386/intr_machdep.c @@ -37,6 +37,7 @@ * that source. */ +#include "opt_atpic.h" #include "opt_ddb.h" #include <sys/param.h> @@ -57,6 +58,14 @@ #include <ddb/ddb.h> #endif +#ifndef DEV_ATPIC +#include <machine/segments.h> +#include <machine/frame.h> +#include <dev/ic/i8259.h> +#include <x86/isa/icu.h> +#include <x86/isa/isa.h> +#endif + #define MAX_STRAY_LOG 5 typedef void (*mask_fn)(void *); @@ -270,6 +279,9 @@ intr_resume(void) { struct pic *pic; +#ifndef DEV_ATPIC + atpic_reset(); +#endif mtx_lock(&intr_table_lock); STAILQ_FOREACH(pic, &pics, pics) { if (pic->pic_resume != NULL) @@ -371,6 +383,28 @@ intr_init(void *dummy __unused) } SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL); +#ifndef DEV_ATPIC +/* Initialize the two 8259A's to a known-good shutdown state. */ +void +atpic_reset(void) +{ + + outb(IO_ICU1, ICW1_RESET | ICW1_IC4); + outb(IO_ICU1 + ICU_IMR_OFFSET, IDT_IO_INTS); + outb(IO_ICU1 + ICU_IMR_OFFSET, 1 << 2); + outb(IO_ICU1 + ICU_IMR_OFFSET, ICW4_8086); + outb(IO_ICU1 + ICU_IMR_OFFSET, 0xff); + outb(IO_ICU1, OCW3_SEL | OCW3_RR); + + outb(IO_ICU2, ICW1_RESET | ICW1_IC4); + outb(IO_ICU2 + ICU_IMR_OFFSET, IDT_IO_INTS + 8); + outb(IO_ICU2 + ICU_IMR_OFFSET, 2); + outb(IO_ICU2 + ICU_IMR_OFFSET, ICW4_8086); + outb(IO_ICU2 + ICU_IMR_OFFSET, 0xff); + outb(IO_ICU2, OCW3_SEL | OCW3_RR); +} +#endif + /* Add a description to an active interrupt handler. */ int intr_describe(u_int vector, void *ih, const char *descr) diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 126b618..8d1ddd8 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include "opt_atalk.h" +#include "opt_atpic.h" #include "opt_compat.h" #include "opt_cpu.h" #include "opt_ddb.h" @@ -2712,8 +2713,22 @@ init386(first) printf("WARNING: loader(8) metadata is missing!\n"); #ifdef DEV_ISA +#ifdef DEV_ATPIC elcr_probe(); atpic_startup(); +#else + /* Reset and mask the atpics and leave them shut down. */ + atpic_reset(); + + /* + * Point the ICU spurious interrupt vectors at the APIC spurious + * interrupt handler. + */ + setidt(IDT_IO_INTS + 7, IDTVEC(spuriousint), SDT_SYS386IGT, SEL_KPL, + GSEL(GCODE_SEL, SEL_KPL)); + setidt(IDT_IO_INTS + 15, IDTVEC(spuriousint), SDT_SYS386IGT, SEL_KPL, + GSEL(GCODE_SEL, SEL_KPL)); +#endif #endif #ifdef DDB @@ -2971,8 +2986,22 @@ init386(first) printf("WARNING: loader(8) metadata is missing!\n"); #ifdef DEV_ISA +#ifdef DEV_ATPIC elcr_probe(); atpic_startup(); +#else + /* Reset and mask the atpics and leave them shut down. */ + atpic_reset(); + + /* + * Point the ICU spurious interrupt vectors at the APIC spurious + * interrupt handler. + */ + setidt(IDT_IO_INTS + 7, IDTVEC(spuriousint), SDT_SYS386IGT, SEL_KPL, + GSEL(GCODE_SEL, SEL_KPL)); + setidt(IDT_IO_INTS + 15, IDTVEC(spuriousint), SDT_SYS386IGT, SEL_KPL, + GSEL(GCODE_SEL, SEL_KPL)); +#endif #endif #ifdef DDB diff --git a/sys/i386/include/intr_machdep.h b/sys/i386/include/intr_machdep.h index bcff6c2..2fcbf32 100644 --- a/sys/i386/include/intr_machdep.h +++ b/sys/i386/include/intr_machdep.h @@ -123,6 +123,9 @@ struct trapframe; extern struct mtx icu_lock; extern int elcr_found; +#ifndef DEV_ATPIC +void atpic_reset(void); +#endif /* XXX: The elcr_* prototypes probably belong somewhere else. */ int elcr_probe(void); enum intr_trigger elcr_read_trigger(u_int irq); |