aboutsummaryrefslogtreecommitdiff
path: root/sys/i386/i386/intr_machdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386/i386/intr_machdep.c')
-rw-r--r--sys/i386/i386/intr_machdep.c34
1 files changed, 34 insertions, 0 deletions
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)