Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Dec 2002 16:15:52 -0800 (PST)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 22175 for review
Message-ID:  <200212120015.gBC0Fqvv061047@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=22175

Change 22175 by peter@peter_daintree on 2002/12/11 16:15:43

	tidy up, fill in missing bits to aid understanding.

Affected files ...

.. //depot/projects/hammer/sys/x86_64/isa/icu.h#4 edit
.. //depot/projects/hammer/sys/x86_64/isa/icu_vector.s#3 edit
.. //depot/projects/hammer/sys/x86_64/isa/intr_machdep.c#7 edit

Differences ...

==== //depot/projects/hammer/sys/x86_64/isa/icu.h#4 (text+ko) ====

@@ -84,18 +84,68 @@
 #define	IRQ6		0x0040
 #define	IRQ7		0x0080		/* lowest - parallel printer */
 
+/* Initialization control word 1. Written to even address. */
+#define	ICW1_IC4	0x01		/* ICW4 present */
+#define	ICW1_SNGL	0x02		/* 1 = single, 0 = cascaded */
+#define	ICW1_ADI	0x04		/* 1 = 4, 0 = 8 byte vectors */
+#define	ICW1_LTIM	0x08		/* 1 = level trigger, 0 = edge */
+#define	ICW1_RESET	0x10		/* must be 1 */
+/* 0x20 - 0x80 - in 8080/8085 mode only */
+
+/* Initialization control word 2. Written to the odd address. */
+/* No definitions, it is the base vector of the IDT for 8086 mode */
+
+/* Initialization control word 3. Written to the odd address. */
+/* For a master PIC, bitfield indicating a slave 8259 on given input */
+/* For slave, lower 3 bits are the slave's ID binary id on master */
+
+/* Initialization control word 4. Written to the odd address. */
+#define	ICW4_8086	0x01		/* 1 = 8086, 0 = 8080 */
+#define	ICW4_AEOI	0x02		/* 1 = Auto EOI */
+#define	ICW4_MS		0x04		/* 1 = buffered master, 0 = slave */
+#define	ICW4_BUF	0x08		/* 1 = enable buffer mode */
+#define	ICW4_SFNM	0x10		/* 1 = special fully nested mode */
+
+/* Operation control words.  Written after initialization. */
+
+/* Operation control word type 1 */
+/*
+ * No definitions.  Written to the odd address.  Bitmask for interrupts.
+ * 1 = disabled.
+ */
+
+/* Operation control word type 2.  Bit 3 (0x08) must be zero. Even address. */
+#define	OCW2_L0		0x01		/* Level */
+#define	OCW2_L1		0x02
+#define	OCW2_L2		0x04
+/* 0x08 must be 0 to select OCW2 vs OCW3 */
+/* 0x10 must be 0 to select OCW2 vs ICW1 */
+#define	OCW2_EOI	0x20		/* 1 = EOI */
+#define	OCW2_SL		0x40		/* EOI mode */
+#define	OCW2_R		0x80		/* EOI mode */
+
+/* Operation control word type 3.  Bit 3 (0x08) must be set. Even address. */
+#define	OCW3_RIS	0x01
+#define	OCW3_RR		0x02
+#define	OCW3_P		0x04
+/* 0x08 must be 1 to select OCW3 vs OCW2 */
+#define	OCW3_SEL	0x08		/* must be 1 */
+/* 0x10 must be 0 to select OCW3 vs ICW1 */
+#define	OCW3_SMM	0x20		/* special mode mask */
+#define	OCW3_ESMM	0x40		/* enable SMM */
+
 /*
  * Interrupt Control offset into Interrupt descriptor table (IDT)
  */
 #define	ICU_OFFSET	32		/* 0-31 are processor exceptions */
+#define	ICU_LEN		16		/* 32-47 are ISA interrupts */
+#define	HWI_MASK	0xffff		/* bits for h/w interrupts */
+#define	NHWI		16
 
 #define	ICU_IMR_OFFSET	1
 #define	ICU_SLAVEID	2
-#define	ICU_EOI		0x20
-
-#define	ICU_LEN		16		/* 32-47 are ISA interrupts */
-#define	HWI_MASK	0xffff		/* bits for h/w interrupts */
-#define	NHWI		16
+#define	ICU_EOI		(OCW2_EOI)	/* non-specific EOI */
+#define	ICU_SETPRI	(OCW2_R | OCW2_SL) /* set rotation priority */
 
 #define	INTRCNT_COUNT	(1 + ICU_LEN + 2 * ICU_LEN)
 

==== //depot/projects/hammer/sys/x86_64/isa/icu_vector.s#3 (text+ko) ====

@@ -6,36 +6,15 @@
 #define	IRQ_BIT(irq_num)	(1 << ((irq_num) % 8))
 #define	IRQ_BYTE(irq_num)	((irq_num) >> 3)
 
-#ifdef AUTO_EOI_1
-
-#define	ENABLE_ICU1		/* use auto-EOI to reduce i/o */
-#define	OUTB_ICU1
-
-#else
-
 #define	ENABLE_ICU1							\
 	movb	$ICU_EOI,%al ;	/* as soon as possible send EOI ... */	\
-	OUTB_ICU1		/* ... to clear in service bit */
-
-#define	OUTB_ICU1							\
-	outb	%al,$IO_ICU1
+	outb	%al,$IO_ICU1	/* ... to clear in service bit */
 
-#endif
-
-#ifdef AUTO_EOI_2
-/*
- * The data sheet says no auto-EOI on slave, but it sometimes works.
- */
-#define	ENABLE_ICU1_AND_2	ENABLE_ICU1
-
-#else
-
 #define	ENABLE_ICU1_AND_2						\
 	movb	$ICU_EOI,%al ;	/* as above */				\
 	outb	%al,$IO_ICU2 ;	/* but do second icu first ... */	\
-	OUTB_ICU1		/* ... then first icu (if !AUTO_EOI_1) */
+	outb	%al,$IO_ICU1	/* ... then first icu */
 
-#endif
 
 /*
  * Macros for interrupt interrupt entry, call to handler, and exit.

==== //depot/projects/hammer/sys/x86_64/isa/intr_machdep.c#7 (text+ko) ====

@@ -243,30 +243,22 @@
 static void init_i8259()
 {
 
-	outb(IO_ICU1, 0x11);		/* reset; program device, four bytes */
+	outb(IO_ICU1, ICW1_RESET | ICW1_IC4);	/* reset; program device, four bytes */
 
 	outb(IO_ICU1+ICU_IMR_OFFSET, NRSVIDT);	/* starting at this vector index */
-	outb(IO_ICU1+ICU_IMR_OFFSET, IRQ_SLAVE);		/* slave on line 7 */
-#ifdef AUTO_EOI_1
-	outb(IO_ICU1+ICU_IMR_OFFSET, 2 | 1);		/* auto EOI, 8086 mode */
-#else
-	outb(IO_ICU1+ICU_IMR_OFFSET, 1);		/* 8086 mode */
-#endif
-	outb(IO_ICU1+ICU_IMR_OFFSET, 0xff);		/* leave interrupts masked */
-	outb(IO_ICU1, 0x0a);		/* default to IRR on read */
-	outb(IO_ICU1, 0xc0 | (3 - 1));	/* pri order 3-7, 0-2 (com2 first) */
+	outb(IO_ICU1+ICU_IMR_OFFSET, IRQ_SLAVE);/* slave on line 2 */
+	outb(IO_ICU1+ICU_IMR_OFFSET, ICW4_8086);/* 8086 mode */
+	outb(IO_ICU1+ICU_IMR_OFFSET, 0xff);	/* leave interrupts masked */
+	outb(IO_ICU1, OCW3_SEL | OCW3_RIS);	/* default to IRR on read */
+	outb(IO_ICU1, ICU_SETPRI | 0x2);/* pri order 3-7, 0-2 (com2 first) */
 
-	outb(IO_ICU2, 0x11);		/* reset; program device, four bytes */
+	outb(IO_ICU2, ICW1_RESET | ICW1_IC4);	/* reset; program device, four bytes */
 
 	outb(IO_ICU2+ICU_IMR_OFFSET, NRSVIDT+8); /* staring at this vector index */
-	outb(IO_ICU2+ICU_IMR_OFFSET, ICU_SLAVEID);         /* my slave id is 7 */
-#ifdef AUTO_EOI_2
-	outb(IO_ICU2+ICU_IMR_OFFSET, 2 | 1);		/* auto EOI, 8086 mode */
-#else
-	outb(IO_ICU2+ICU_IMR_OFFSET,1);		/* 8086 mode */
-#endif
-	outb(IO_ICU2+ICU_IMR_OFFSET, 0xff);          /* leave interrupts masked */
-	outb(IO_ICU2, 0x0a);		/* default to IRR on read */
+	outb(IO_ICU2+ICU_IMR_OFFSET, ICU_SLAVEID); /* my slave id is 2 */
+	outb(IO_ICU2+ICU_IMR_OFFSET, ICW4_8086); /* 8086 mode */
+	outb(IO_ICU2+ICU_IMR_OFFSET, 0xff);     /* leave interrupts masked */
+	outb(IO_ICU2, OCW3_SEL | OCW3_RIS);	/* default to IRR on read */
 }
 
 /*
@@ -277,14 +269,29 @@
 	void *vcookiep;
 {
 	int intr = (void **)vcookiep - &intr_unit[0];
+	int isr;
 
-	/*
-	 * XXX TODO print a different message for #7 if it is for a
-	 * glitch.  Glitches can be distinguished from real #7's by
-	 * testing that the in-service bit is _not_ set.  The test
-	 * must be done before sending an EOI so it can't be done if
-	 * we are using AUTO_EOI_1.
-	 */
+	/* Determine if it is a stray interrupt or simply a glitch */
+	if (intr == 7) {
+		outb(IO_ICU1, OCW3_SEL);	/* select IS register */
+		isr = inb(IO_ICU1);
+		outb(IO_ICU1, OCW3_SEL | OCW3_RIS); /* reselect IIR */
+		if ((isr & 0x80) == 0) {
+			/* Remove debugging message below */
+			log(LOG_ERR, "glitch on irq 7\n");
+			return;
+		}
+	}
+	if (intr == 15) {
+		outb(IO_ICU2, OCW3_SEL);	/* select IS register */
+		isr = inb(IO_ICU2);
+		outb(IO_ICU2, OCW3_SEL | OCW3_RIS); /* reselect IIR */
+		if ((isr & 0x80) == 0) {
+			/* Remove debugging message below */
+			log(LOG_ERR, "glitch on irq 15\n");
+			return;
+		}
+	}
 	if (intrcnt[1 + intr] <= 5)
 		log(LOG_ERR, "stray irq %d\n", intr);
 	if (intrcnt[1 + intr] == 5)

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe p4-projects" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200212120015.gBC0Fqvv061047>