diff options
Diffstat (limited to 'i386/i386')
-rw-r--r-- | i386/i386/fpu.c | 2 | ||||
-rw-r--r-- | i386/i386/irq.c | 9 | ||||
-rw-r--r-- | i386/i386/irq.h | 6 | ||||
-rw-r--r-- | i386/i386/locore.S | 15 | ||||
-rw-r--r-- | i386/i386/pic.h | 6 | ||||
-rw-r--r-- | i386/i386/pit.c | 41 | ||||
-rw-r--r-- | i386/i386/pit.h | 4 |
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_ */ |