summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/i386/i386/local_apic.c33
-rw-r--r--sys/i386/include/apicvar.h24
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 */
OpenPOWER on IntegriCloud