diff options
-rw-r--r-- | sys/i386/i386/local_apic.c | 33 | ||||
-rw-r--r-- | sys/i386/include/apicvar.h | 24 |
2 files changed, 39 insertions, 18 deletions
diff --git a/sys/i386/i386/local_apic.c b/sys/i386/i386/local_apic.c index 9c3d97b..f7e5d28 100644 --- a/sys/i386/i386/local_apic.c +++ b/sys/i386/i386/local_apic.c @@ -60,7 +60,9 @@ __FBSDID("$FreeBSD$"); #define MAX_APICID 16 /* Sanity checks on IDT vectors. */ -CTASSERT(APIC_IO_INTS + APIC_NUM_IOINTS <= APIC_LOCAL_INTS); +CTASSERT(APIC_IO_INTS + APIC_NUM_IOINTS == APIC_TIMER_INT); +CTASSERT(APIC_TIMER_INT < APIC_LOCAL_INTS); +CTASSERT(APIC_LOCAL_INTS == 240); CTASSERT(IPI_STOP < APIC_SPURIOUS_INT); /* @@ -264,10 +266,8 @@ lapic_setup(void) /* XXX: more LVT entries */ - /* Clear the TPR. */ - value = lapic->tpr; - value &= ~APIC_TPR_PRIO; - lapic->tpr = value; + /* Initialize the TPR to allow all interrupts. */ + lapic_set_tpr(0); /* Use the cluster model for logical IDs. */ value = lapic->dfr; @@ -472,6 +472,24 @@ lapic_set_lvt_triggermode(u_int apic_id, u_int pin, enum intr_trigger trigger) return (0); } +/* + * Adjust the TPR of the current CPU so that it blocks all interrupts below + * the passed in vector. + */ +void +lapic_set_tpr(u_int vector) +{ +#ifdef CHEAP_TPR + lapic->tpr = vector; +#else + u_int32_t tpr; + + tpr = lapic->tpr & ~APIC_TPR_PRIO; + tpr |= vector; + lapic->tpr = tpr; +#endif +} + void lapic_eoi(void) { @@ -637,10 +655,9 @@ SYSINIT(apic_setup_io, SI_SUB_INTR, SI_ORDER_SECOND, apic_setup_io, NULL) #ifdef SMP /* * Inter Processor Interrupt functions. The lapic_ipi_*() functions are - * private the sys/i386 code. The public interface for the rest of the + * private to the sys/i386 code. The public interface for the rest of the * kernel is defined in mp_machdep.c. */ - int lapic_ipi_wait(int delay) { @@ -745,7 +762,7 @@ lapic_ipi_vectored(u_int vector, int dest) * the failure with the check above when the next IPI is * sent. * - * We could skiip this wait entirely, EXCEPT it probably + * We could skip this wait entirely, EXCEPT it probably * protects us from other routines that assume that the * message was delivered and acted upon when this function * returns. diff --git a/sys/i386/include/apicvar.h b/sys/i386/include/apicvar.h index a680b0d..a0f06ba 100644 --- a/sys/i386/include/apicvar.h +++ b/sys/i386/include/apicvar.h @@ -42,7 +42,7 @@ * 0xff (255) +-------------+ * | | 15 (Spurious / IPIs / Local Interrupts) * 0xf0 (240) +-------------+ - * | | 14 (I/O Interrupts) + * | | 14 (I/O Interrupts / Timer) * 0xe0 (224) +-------------+ * | | 13 (I/O Interrupts) * 0xd0 (208) +-------------+ @@ -78,8 +78,13 @@ */ #define APIC_ID_ALL 0xff + +/* I/O Interrupts are used for external devices such as ISA, PCI, etc. */ #define APIC_IO_INTS (IDT_IO_INTS + 16) -#define APIC_NUM_IOINTS 192 +#define APIC_NUM_IOINTS 191 + +/* The timer interrupt is used for clock handling and drives hardclock, etc. */ +#define APIC_TIMER_INT (APIC_IO_INTS + APIC_NUM_IOINTS) /* ********************* !!! WARNING !!! ****************************** @@ -101,15 +106,12 @@ * other deadlocks caused by IPI_STOP. */ +/* Interrupts for local APIC LVT entries other than the timer. */ #define APIC_LOCAL_INTS 240 +#define APIC_ERROR_INT APIC_LOCAL_INTS +#define APIC_THERMAL_INT (APIC_LOCAL_INTS + 1) -#if 0 -#define APIC_TIMER_INT (APIC_LOCAL_INTS + X) -#define APIC_ERROR_INT (APIC_LOCAL_INTS + X) -#define APIC_THERMAL_INT (APIC_LOCAL_INTS + X) -#endif - -#define APIC_IPI_INTS (APIC_LOCAL_INTS + 0) +#define APIC_IPI_INTS (APIC_LOCAL_INTS + 2) #define IPI_RENDEZVOUS (APIC_IPI_INTS) /* Inter-CPU rendezvous. */ #define IPI_INVLTLB (APIC_IPI_INTS + 1) /* TLB Shootdown IPIs */ #define IPI_INVLPG (APIC_IPI_INTS + 2) @@ -127,7 +129,8 @@ #define IPI_STOP (APIC_IPI_INTS + 6) /* Stop CPU until restarted. */ -/* The spurious interrupt can share the priority class with the IPIs since +/* + * The spurious interrupt can share the priority class with the IPIs since * it is not a normal interrupt. (Does not use the APIC's interrupt fifo) */ #define APIC_SPURIOUS_INT 255 @@ -206,6 +209,7 @@ int lapic_set_lvt_polarity(u_int apic_id, u_int lvt, enum intr_polarity pol); int lapic_set_lvt_triggermode(u_int apic_id, u_int lvt, enum intr_trigger trigger); +void lapic_set_tpr(u_int vector); void lapic_setup(void); #endif /* !LOCORE */ |