aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2012-03-09 19:42:48 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2012-03-09 19:42:48 +0000
commitad47abd20c48a4d51adb39280ac8cd331977fd31 (patch)
treebf27eb31fac1ca30ea2152bdc3f12d14df7dd127 /sys
parent5e9fcac6f40ccbff89478aff1987a69eec5bdb60 (diff)
downloadsrc-ad47abd20c48a4d51adb39280ac8cd331977fd31.tar.gz
src-ad47abd20c48a4d51adb39280ac8cd331977fd31.zip
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
Notes
Notes: svn path=/head/; revision=232744
Diffstat (limited to 'sys')
-rw-r--r--sys/conf/files.amd642
-rw-r--r--sys/conf/files.i3864
-rw-r--r--sys/i386/i386/exception.s7
-rw-r--r--sys/i386/i386/intr_machdep.c34
-rw-r--r--sys/i386/i386/machdep.c29
-rw-r--r--sys/i386/include/intr_machdep.h3
6 files changed, 75 insertions, 4 deletions
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index 8ab1cbc70b76..b5c4fb4dccd4 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 5064f0d1eb92..54636c6d91b7 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 13562fa6e994..e969d324dd69 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 eb6bfa1b9e4a..20817576a13b 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 126b6189ad94..8d1ddd83ad46 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 bcff6c22e6e8..2fcbf32a351d 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);