summaryrefslogtreecommitdiff
path: root/i386/i386
diff options
context:
space:
mode:
Diffstat (limited to 'i386/i386')
-rw-r--r--i386/i386/fpu.c2
-rw-r--r--i386/i386/irq.c9
-rw-r--r--i386/i386/irq.h6
-rw-r--r--i386/i386/locore.S15
-rw-r--r--i386/i386/pic.h6
-rw-r--r--i386/i386/pit.c41
-rw-r--r--i386/i386/pit.h4
7 files changed, 75 insertions, 8 deletions
diff --git a/i386/i386/fpu.c b/i386/i386/fpu.c
index a8459d65..cdfe264b 100644
--- a/i386/i386/fpu.c
+++ b/i386/i386/fpu.c
@@ -51,7 +51,7 @@
#include <i386/thread.h>
#include <i386/fpu.h>
#include <i386/pio.h>
-#include <i386/pic.h>
+#include <i386/irq.h>
#include <i386/locore.h>
#include <i386/trap.h>
#include "cpu_number.h"
diff --git a/i386/i386/irq.c b/i386/i386/irq.c
index 35681191..42921617 100644
--- a/i386/i386/irq.c
+++ b/i386/i386/irq.c
@@ -29,7 +29,10 @@ extern queue_head_t main_intr_queue;
static void
irq_eoi (struct irqdev *dev, int id)
{
- /* TODO EOI(dev->irq[id]) */
+#ifdef APIC
+ ioapic_irq_eoi (dev->irq[id]);
+ lapic_eoi ();
+#endif
}
static unsigned int ndisabled_irq[NINTR];
@@ -62,6 +65,10 @@ __enable_irq (irq_t irq_nr)
struct irqdev irqtab = {
"irq", irq_eoi, &main_intr_queue, 0,
+#ifdef APIC
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23},
+#else
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
+#endif
};
diff --git a/i386/i386/irq.h b/i386/i386/irq.h
index d48a8e92..72bbe57b 100644
--- a/i386/i386/irq.h
+++ b/i386/i386/irq.h
@@ -15,7 +15,11 @@
#ifndef _I386_IRQ_H
#define _I386_IRQ_H
-#include <i386/pic.h>
+#ifdef APIC
+# include <i386/apic.h>
+#else
+# include <i386/pic.h>
+#endif
typedef unsigned int irq_t;
diff --git a/i386/i386/locore.S b/i386/i386/locore.S
index bee3630c..8a1054a6 100644
--- a/i386/i386/locore.S
+++ b/i386/i386/locore.S
@@ -607,6 +607,7 @@ ENTRY(call_continuation)
jmp *%eax /* goto continuation */
+/* IOAPIC has 24 interrupts, put spurious in the same array */
#define INTERRUPT(n) \
.data 2 ;\
@@ -621,6 +622,7 @@ ENTRY(call_continuation)
.data 2
DATA(int_entry_table)
.text
+/* Legacy APIC interrupts or PIC interrupts */
INTERRUPT(0)
INTERRUPT(1)
INTERRUPT(2)
@@ -637,6 +639,19 @@ INTERRUPT(12)
INTERRUPT(13)
INTERRUPT(14)
INTERRUPT(15)
+#ifdef APIC
+/* APIC PCI interrupts PIRQ A-H */
+INTERRUPT(16)
+INTERRUPT(17)
+INTERRUPT(18)
+INTERRUPT(19)
+INTERRUPT(20)
+INTERRUPT(21)
+INTERRUPT(22)
+INTERRUPT(23)
+/* Spurious interrupt, set irq number to vect number */
+INTERRUPT(255)
+#endif
/* XXX handle NMI - at least print a warning like Linux does. */
diff --git a/i386/i386/pic.h b/i386/i386/pic.h
index b3365ed9..3ded9aba 100644
--- a/i386/i386/pic.h
+++ b/i386/i386/pic.h
@@ -52,7 +52,9 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#ifndef _I386_PIC_H_
#define _I386_PIC_H_
+#ifndef APIC
#define NINTR 0x10
+#endif
#define NPICS 0x02
/*
@@ -176,7 +178,9 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define READ_IR_ONRD 0x00
#define READ_IS_ONRD 0x01
-#ifndef __ASSEMBLER__
+#define PIC_MASK_ZERO 0x00
+
+#if !defined(__ASSEMBLER__) && !defined(APIC)
extern void picinit (void);
extern int curr_pic_mask;
extern void intnull(int unit);
diff --git a/i386/i386/pit.c b/i386/i386/pit.c
index 4e3feeec..0ead8c9b 100644
--- a/i386/i386/pit.c
+++ b/i386/i386/pit.c
@@ -51,7 +51,7 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kern/mach_clock.h>
#include <i386/ipl.h>
-#include <i386/pic.h>
+#include <machine/irq.h>
#include <i386/pit.h>
#include <i386/pio.h>
#include <kern/cpu_number.h>
@@ -66,14 +66,47 @@ int pit0_mode = PIT_C0|PIT_SQUAREMODE|PIT_READMODE ;
unsigned int clknumb = CLKNUM; /* interrupt interval for timer 0 */
void
-clkstart(void)
+pit_prepare_sleep(int hz)
{
- unsigned char byte;
- unsigned long s;
+ /* Prepare to sleep for 1/hz seconds */
+ int val = 0;
+ int lsb, msb;
+
+ val = inb(PITAUX_PORT);
+ val &= ~PITAUX_OUT2;
+ val |= PITAUX_GATE2;
+ outb (PITAUX_PORT, val);
+ outb (PITCTL_PORT, PIT_C2 | PIT_LOADMODE | PIT_RATEMODE);
+ val = CLKNUM / hz;
+ lsb = val & 0xff;
+ msb = val >> 8;
+ outb (PITCTR2_PORT, lsb);
+ val = inb(POST_PORT); /* ~1us i/o delay */
+ outb (PITCTR2_PORT, msb);
+ /* Start counting down */
+ val = inb(PITAUX_PORT);
+ val &= ~PITAUX_GATE2;
+ outb (PITAUX_PORT, val); /* Gate low */
+ val |= PITAUX_GATE2;
+ outb (PITAUX_PORT, val); /* Gate high */
+}
+
+void
+pit_sleep(void)
+{
+ /* Wait until counter reaches zero */
+ while ((inb(PITAUX_PORT) & PITAUX_VAL) == 0);
+}
+
+void
+clkstart(void)
+{
if (cpu_number() != 0)
/* Only one PIT initialization is needed */
return;
+ unsigned char byte;
+ unsigned long s;
s = sploff(); /* disable interrupts */
diff --git a/i386/i386/pit.h b/i386/i386/pit.h
index cf0b74cc..bac4e985 100644
--- a/i386/i386/pit.h
+++ b/i386/i386/pit.h
@@ -78,6 +78,8 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* Used for Timer 2. */
#define PIT_C2 0x80 /* select counter 2 */
+#define POST_PORT 0x80 /* used for tiny i/o delay */
+
/*
* Clock speed for the timer in hz divided by the constant HZ
* (defined in param.h)
@@ -87,5 +89,7 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#endif /* AT386 */
extern void clkstart(void);
+extern void pit_prepare_sleep(int hz);
+extern void pit_sleep(void);
#endif /* _I386_PIT_H_ */