PERFORCE change 64883 for review
John Baldwin
jhb at FreeBSD.org
Thu Nov 11 09:47:36 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=64883
Change 64883 by jhb at jhb_slimer on 2004/11/11 17:47:05
- Provide a function to adjust the TPR for the current CPU.
- Shuffle the IPI and local interrupts a bit so that the handlers
that use spin locks (the ones related to clock) are all lower
than the IPI handlers that can safely be allowed to fire while
holding a spin lock. (More on this later.)
Affected files ...
.. //depot/projects/smpng/sys/i386/i386/local_apic.c#15 edit
.. //depot/projects/smpng/sys/i386/include/apicvar.h#7 edit
Differences ...
==== //depot/projects/smpng/sys/i386/i386/local_apic.c#15 (text+ko) ====
@@ -60,7 +60,8 @@
#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_CLOCK_INTS);
+CTASSERT(APIC_CLOCK_INTS == 240);
CTASSERT(IPI_STOP < APIC_SPURIOUS_INT);
/*
@@ -264,10 +265,8 @@
/* 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 +471,24 @@
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 +654,9 @@
#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)
{
==== //depot/projects/smpng/sys/i386/include/apicvar.h#7 (text+ko) ====
@@ -78,24 +78,38 @@
*/
#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_LOCAL_INTS 240
-#define APIC_TIMER_INT APIC_LOCAL_INTS
-#define APIC_ERROR_INT (APIC_LOCAL_INTS + 1)
-#define APIC_THERMAL_INT (APIC_LOCAL_INTS + 2)
+/* Clock interrupts are used for clock handling and drive hardclock, etc. */
+#define APIC_CLOCK_INTS (APIC_IO_INTS + APIC_NUM_IOINTS)
+#define APIC_TIMER_INT APIC_CLOCK_INTS
+#define IPI_HARDCLOCK (APIC_CLOCK_INTS + 1) /* Inter-CPU clock handling. */
+#define IPI_STATCLOCK (APIC_CLOCK_INTS + 2)
+
+/*
+ * These interrupt handlers are for IPIs and local interrupts whose handlers
+ * do not use any spin locks, so they may still be allowed when a spin lock
+ * is held.
+ */
+#define APIC_LOCK_SAFE_INTS (APIC_CLOCK_INTS + 3)
+
+/* Interrupts for local APIC LVT entries other than the timer. */
+#define APIC_LOCAL_INTS APIC_LOCK_SAFE_INTS
+#define APIC_ERROR_INT APIC_LOCAL_INTS
+#define APIC_THERMAL_INT (APIC_LOCAL_INTS + 1)
-#define APIC_IPI_INTS (APIC_LOCAL_INTS + 3)
+/* Spin lock safe IPIs. */
+#define APIC_IPI_INTS (APIC_LOCAL_INTS + 2)
#define IPI_AST APIC_IPI_INTS /* Generate software trap. */
#define IPI_INVLTLB (APIC_IPI_INTS + 1) /* TLB Shootdown IPIs */
#define IPI_INVLPG (APIC_IPI_INTS + 2)
#define IPI_INVLRNG (APIC_IPI_INTS + 3)
#define IPI_LAZYPMAP (APIC_IPI_INTS + 4) /* Lazy pmap release. */
-#define IPI_HARDCLOCK (APIC_IPI_INTS + 8) /* Inter-CPU clock handling. */
-#define IPI_STATCLOCK (APIC_IPI_INTS + 9)
-#define IPI_RENDEZVOUS (APIC_IPI_INTS + 10) /* Inter-CPU rendezvous. */
-#define IPI_STOP (APIC_IPI_INTS + 11) /* Stop CPU until restarted. */
+#define IPI_RENDEZVOUS (APIC_IPI_INTS + 5) /* Inter-CPU rendezvous. */
+#define IPI_STOP (APIC_IPI_INTS + 6) /* Stop CPU until restarted. */
#define APIC_SPURIOUS_INT 255
@@ -173,6 +187,7 @@
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 */
More information about the p4-projects
mailing list