From fe992761cb4d3f06859f4ac66a431dcbc0153587 Mon Sep 17 00:00:00 2001
From: Sascha Wildner <saw@online.de>
Date: Wed, 5 Jan 2011 22:40:58 +0100
Subject: [PATCH] x86_64: Bring in sephe's recent APIC work from i386.

http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/8995ba1d97e8261b45d0fdc0d710068a55f4ccc4
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/6ab7c3afffd1bc2da613b1a9b4bf6d25a3dea437
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/84bf7d5ab73b7fe15b9d4ecdf3bf77bc33f65f19
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/e4a4c490ac95cb996ef93eb65aed1888bbb768df
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/507bf37b1e48f0e37b10b1dc71c3e75bdda2b8f0
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/072d9b3ebee1073865d6a0d42eb53965d9a0c7bb
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/7b32a0af6a190908fbddfd3f0028f45afb07f6ce
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/2ce3ae864d45679d46170d5723b8b31e1f97b1fb
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/26408d725697a6e1f0905095b4d6544624f61b87
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/87e3ca2d0df9dd172c993f817ac093ad1a09d965
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/90a567fb7ca1767171872ebb9573020f8607504b
---
 sys/bus/pci/x86_64/mptable_pci.c      |    5 ++
 sys/platform/pc64/apic/apic_abi.c     |    4 +-
 sys/platform/pc64/apic/apic_ipl.h     |    3 -
 sys/platform/pc64/apic/apicreg.h      |   30 --------
 sys/platform/pc64/apic/apicvar.h      |   51 --------------
 sys/platform/pc64/apic/mpapic.c       |    4 +-
 sys/platform/pc64/isa/intr_machdep.h  |  124 ++++++++++++++++----------------
 sys/platform/pc64/x86_64/mp_machdep.c |    2 +-
 8 files changed, 72 insertions(+), 151 deletions(-)

diff --git a/sys/bus/pci/x86_64/mptable_pci.c b/sys/bus/pci/x86_64/mptable_pci.c
index bf6d915..8f8bde8 100644
--- a/sys/bus/pci/x86_64/mptable_pci.c
+++ b/sys/bus/pci/x86_64/mptable_pci.c
@@ -89,6 +89,8 @@ mptable_pci_route_interrupt(device_t pcib, device_t dev, int pin)
 static int
 mptable_hostb_probe(device_t dev)
 {
+	if (!apic_io_enable)
+		return (ENXIO);
 
 	if (pci_cfgregopen() == 0)
 		return (ENXIO);
@@ -184,6 +186,9 @@ mptable_pcib_probe(device_t dev)
 {
 	int bus;
 
+	if (!apic_io_enable)
+		return (ENXIO);
+
 	if ((pci_get_class(dev) != PCIC_BRIDGE) ||
 	    (pci_get_subclass(dev) != PCIS_BRIDGE_PCI))
 		return (ENXIO);
diff --git a/sys/platform/pc64/apic/apic_abi.c b/sys/platform/pc64/apic/apic_abi.c
index 44768ec..23d266a 100644
--- a/sys/platform/pc64/apic/apic_abi.c
+++ b/sys/platform/pc64/apic/apic_abi.c
@@ -217,7 +217,7 @@ apic_vectorctl(int op, int intr, int flags)
 
     switch(op) {
     case MACHINTR_VECTOR_SETUP:
-	vector = TPR_FAST_INTS + intr;
+	vector = IDT_OFFSET + intr;
 	setidt(vector, apic_fastintr[intr], SDT_SYSIGT, SEL_KPL, 0);
 
 	/*
@@ -246,7 +246,7 @@ apic_vectorctl(int op, int intr, int flags)
 	 * installed in the cpu's IDT, but make sure.
 	 */
 	machintr_intrdis(intr);
-	vector = TPR_FAST_INTS + intr;
+	vector = IDT_OFFSET + intr;
 	setidt(vector, apic_fastintr[intr], SDT_SYSIGT, SEL_KPL, 0);
 
 	/*
diff --git a/sys/platform/pc64/apic/apic_ipl.h b/sys/platform/pc64/apic/apic_ipl.h
index 91976c7..ce9bb72 100644
--- a/sys/platform/pc64/apic/apic_ipl.h
+++ b/sys/platform/pc64/apic/apic_ipl.h
@@ -32,9 +32,6 @@
 
 #ifdef SMP /* APIC-IO */
 
-/* IDT vector base for regular (aka. slow) and fast interrupts */
-#define TPR_FAST_INTS	0x60
-
 #define APIC_HWI_VECTORS 24
 #define	APIC_HWI_MASK	((1 << APIC_HWI_VECTORS) - 1)
 
diff --git a/sys/platform/pc64/apic/apicreg.h b/sys/platform/pc64/apic/apicreg.h
index 1f7a4c6..9fc5b23 100644
--- a/sys/platform/pc64/apic/apicreg.h
+++ b/sys/platform/pc64/apic/apicreg.h
@@ -714,36 +714,6 @@ typedef struct IOAPIC ioapic_t;
 #define APIC_TDCR_128		0x0a
 #define APIC_TDCR_1		0x0b
 
-/*
- * fields in IRR
- * ISA INTerrupts are in bits 16-31 of the 1st IRR register.
- * these masks DON'T EQUAL the isa IRQs of the same name.
- */
-#define APIC_IRQ0		0
-#define APIC_IRQ1		1
-#define APIC_IRQ2		2
-#define APIC_IRQ3		3
-#define APIC_IRQ4		4
-#define APIC_IRQ5		5
-#define APIC_IRQ6		6
-#define APIC_IRQ7		7
-#define APIC_IRQ8		8
-#define APIC_IRQ9		9
-#define APIC_IRQ10		10
-#define APIC_IRQ11		11
-#define APIC_IRQ12		12
-#define APIC_IRQ13		13
-#define APIC_IRQ14		14
-#define APIC_IRQ15		15
-#define APIC_IRQ16		16
-#define APIC_IRQ17		17
-#define APIC_IRQ18		18
-#define APIC_IRQ19		19
-#define APIC_IRQ20		20
-#define APIC_IRQ21		21
-#define APIC_IRQ22		22
-#define APIC_IRQ23		23
-
 /******************************************************************************
  * I/O APIC defines
  */
diff --git a/sys/platform/pc64/apic/apicvar.h b/sys/platform/pc64/apic/apicvar.h
index 4329a40..c10e8eb 100644
--- a/sys/platform/pc64/apic/apicvar.h
+++ b/sys/platform/pc64/apic/apicvar.h
@@ -38,57 +38,6 @@
  * Local && I/O APIC variable definitions.
  */
 
-/*
- * Layout of local APIC interrupt vectors:
- *
- *	0xff (255)  +-------------+
- *                  |             | 15 (Spurious / IPIs / Local Interrupts)
- *	0xf0 (240)  +-------------+
- *                  |             | 14 (I/O Interrupts)
- *	0xe0 (224)  +-------------+
- *                  |             | 13 (I/O Interrupts)
- *	0xd0 (208)  +-------------+
- *                  |             | 12 (I/O Interrupts)
- *	0xc0 (192)  +-------------+
- *                  |             | 11 (I/O Interrupts)
- *	0xb0 (176)  +-------------+
- *                  |             | 10 (I/O Interrupts)
- *	0xa0 (160)  +-------------+
- *                  |             | 9 (I/O Interrupts)
- *	0x90 (144)  +-------------+
- *                  |             | 8 (I/O Interrupts / System Calls)
- *	0x80 (128)  +-------------+
- *                  |             | 7 (I/O Interrupts)
- *	0x70 (112)  +-------------+
- *                  |             | 6 (I/O Interrupts)
- *	0x60 (96)   +-------------+
- *                  |             | 5 (I/O Interrupts)
- *	0x50 (80)   +-------------+
- *                  |             | 4 (I/O Interrupts)
- *	0x40 (64)   +-------------+
- *                  |             | 3 (I/O Interrupts)
- *	0x30 (48)   +-------------+
- *                  |             | 2 (ATPIC Interrupts)
- *	0x20 (32)   +-------------+
- *                  |             | 1 (Exceptions, traps, faults, etc.)
- *	0x10 (16)   +-------------+
- *                  |             | 0 (Exceptions, traps, faults, etc.)
- *	0x00 (0)    +-------------+
- *
- * Note: 0x80 needs to be handled specially and not allocated to an
- * I/O device!
- */
-
-#define	APIC_ID_ALL	0xff
-#define	APIC_IO_INTS	(IDT_IO_INTS + 16)
-#define	APIC_NUM_IOINTS	192
-
-#define	APIC_LOCAL_INTS	240
-
-/* XXX put APIC interrupt and IPI assignments here */
-
-#define	APIC_SPURIOUS_INT 255
-
 #define	LVT_LINT0	0
 #define	LVT_LINT1	1
 #define	LVT_TIMER	2
diff --git a/sys/platform/pc64/apic/mpapic.c b/sys/platform/pc64/apic/mpapic.c
index 5dae512..4377e40 100644
--- a/sys/platform/pc64/apic/mpapic.c
+++ b/sys/platform/pc64/apic/mpapic.c
@@ -156,7 +156,7 @@ apic_initialize(boolean_t bsp)
 	 * Set the Task Priority Register as needed.   At the moment allow
 	 * interrupts on all cpus (the APs will remain CLId until they are
 	 * ready to deal).  We could disable all but IPIs by setting
-	 * temp |= TPR_IPI_ONLY for cpu != 0.
+	 * temp |= TPR_IPI for cpu != 0.
 	 */
 	temp = lapic->tpr;
 	temp &= ~APIC_TPR_PRIO;		/* clear priority field */
@@ -167,7 +167,7 @@ if (!apic_io_enable) {
  	 * If we are NOT running the IO APICs, the LAPIC will only be used
 	 * for IPIs.  Set the TPR to prevent any unintentional interrupts.
  	 */
-	temp |= TPR_IPI_ONLY;
+	temp |= TPR_IPI;
 #ifdef SMP /* APIC-IO */
 }
 #endif
diff --git a/sys/platform/pc64/isa/intr_machdep.h b/sys/platform/pc64/isa/intr_machdep.h
index 4495939..06ccaa8 100644
--- a/sys/platform/pc64/isa/intr_machdep.h
+++ b/sys/platform/pc64/isa/intr_machdep.h
@@ -53,84 +53,86 @@
 
 #ifdef _KERNEL
 
-#define IDT_OFFSET	32
+#define IDT_OFFSET		0x20
+#define IDT_OFFSET_IPI		0xe0
 
 #if defined(SMP)
-/*
- * XXX FIXME: rethink location for all IPI vectors.
- */
 
 /*
-    APIC TPR priority vector levels:
-
-	0xff (255) +-------------+
-		   |             | 15 (IPIs: Xspuriousint)
-	0xf0 (240) +-------------+
-		   |             | 14
-	0xe0 (224) +-------------+
-		   |             | 13
-	0xd0 (208) +-------------+
-		   |             | 12
-	0xc0 (192) +-------------+
-		   |             | 11
-	0xb0 (176) +-------------+
-		   |             | 10 (IPIs: Xcpustop)
-	0xa0 (160) +-------------+
-		   |             |  9 (IPIs: Xinvltlb)
-	0x90 (144) +-------------+
-		   |             |  8 (linux/BSD syscall, IGNORE FAST HW INTS)
-	0x80 (128) +-------------+
-		   |             |  7 (FAST_INTR 16-23)
-	0x70 (112) +-------------+
-		   |             |  6 (FAST_INTR 0-15)
-	0x60 (96)  +-------------+
-		   |             |  5 (IGNORE HW INTS)
-	0x50 (80)  +-------------+
-		   |             |  4 (2nd IO APIC)
-	0x40 (64)  +------+------+
-		   |      |      |  3 (upper APIC hardware INTs: PCI)
-	0x30 (48)  +------+------+
-		   |             |  2 (start of hardware INTs: ISA)
-	0x20 (32)  +-------------+
-		   |             |  1 (exceptions, traps, etc.)
-	0x10 (16)  +-------------+
-		   |             |  0 (exceptions, traps, etc.)
-	0x00 (0)   +-------------+
+ * Local APIC TPR priority vector levels:
+ *
+ *	0xff (255) +-------------+
+ *		   |             | 15 (IPIs: Xcpustop, Xspuriousint)
+ *	0xf0 (240) +-------------+
+ *		   |             | 14 (IPIs: Xinvltlb, Xipiq, Xtimer)
+ *	0xe0 (224) +-------------+
+ *		   |             | 13
+ *	0xd0 (208) +-------------+
+ *		   |             | 12
+ *	0xc0 (192) +-------------+
+ *		   |             | 11
+ *	0xb0 (176) +-------------+
+ *		   |             | 10
+ *	0xa0 (160) +-------------+
+ *		   |             |  9
+ *	0x90 (144) +-------------+
+ *		   |             |  8 (syscall at 0x80)
+ *	0x80 (128) +-------------+
+ *		   |             |  7
+ *	0x70 (112) +-------------+
+ *		   |             |  6
+ *	0x60 (96)  +-------------+
+ *		   |             |  5
+ *	0x50 (80)  +-------------+
+ *		   |             |  4
+ *	0x40 (64)  +-------------+
+ *		   |             |  3
+ *	0x30 (48)  +-------------+
+ *		   |             |  2 (hardware INTs)
+ *	0x20 (32)  +-------------+
+ *		   |             |  1 (exceptions, traps, etc.)
+ *	0x10 (16)  +-------------+
+ *		   |             |  0 (exceptions, traps, etc.)
+ *	0x00 (0)   +-------------+
  */
+#define TPR_STEP		0x10
 
-/* blocking values for local APIC Task Priority Register */
-#define TPR_BLOCK_HWI		0x4f		/* hardware INTs */
-#define TPR_IGNORE_HWI		0x5f		/* ignore INTs */
-#define TPR_BLOCK_FHWI		0x7f		/* hardware FAST INTs */
-#define TPR_IGNORE_FHWI		0x8f		/* ignore FAST INTs */
-#define TPR_IPI_ONLY		0x8f		/* ignore FAST INTs */
-#define TPR_BLOCK_XINVLTLB	0x9f		/*  */
-#define TPR_BLOCK_XCPUSTOP	0xaf		/*  */
-#define TPR_BLOCK_ALL		0xff		/* all INTs */
+/* Local APIC Task Priority Register */
+#define TPR_IPI			(IDT_OFFSET_IPI - 1)
 
 
-/* TLB shootdowns */
-#define XINVLTLB_OFFSET		(IDT_OFFSET + 112)
+/*
+ * IPI group1
+ */
+#define IDT_OFFSET_IPIG1	IDT_OFFSET_IPI
 
-/* unused/open (was inter-cpu clock handling) */
-#define XUNUSED113_OFFSET	(IDT_OFFSET + 113)
+/* TLB shootdowns */
+#define XINVLTLB_OFFSET		(IDT_OFFSET_IPIG1 + 0)
 
-/* inter-CPU rendezvous */
-#define XUNUSED114_OFFSET	(IDT_OFFSET + 114)
+/* IPI group1 1: unused (was inter-cpu clock handling) */
+/* IPI group1 2: unused (was inter-cpu rendezvous) */
 
 /* IPIQ rendezvous */
-#define XIPIQ_OFFSET		(IDT_OFFSET + 115)
+#define XIPIQ_OFFSET		(IDT_OFFSET_IPIG1 + 3)
 
 /* TIMER rendezvous */
-#define XTIMER_OFFSET		(IDT_OFFSET + 116)
+#define XTIMER_OFFSET		(IDT_OFFSET_IPIG1 + 4)
+
+/* IPI group1 5 ~ 15: unused */
 
-/* IPI to signal CPUs to stop and wait for another CPU to restart them */
-#define XCPUSTOP_OFFSET		(IDT_OFFSET + 128)
 
 /*
- * Note: this vector MUST be xxxx1111, 32 + 223 = 255 = 0xff:
+ * IPI group2
  */
-#define XSPURIOUSINT_OFFSET	(IDT_OFFSET + 223)
+#define IDT_OFFSET_IPIG2	(IDT_OFFSET_IPIG1 + TPR_STEP)
+
+/* IPI to signal CPUs to stop and wait for another CPU to restart them */
+#define XCPUSTOP_OFFSET		(IDT_OFFSET_IPIG2 + 0)
+
+/* IPI group2 1 ~ 14: unused */
+
+/* NOTE: this vector MUST be xxxx1111 */
+#define XSPURIOUSINT_OFFSET	(IDT_OFFSET_IPIG2 + 15)
 
 #endif /* SMP */
 
@@ -142,7 +144,6 @@
 #ifndef JG_defined_inthand_t
 #define JG_defined_inthand_t
 typedef void inthand_t(u_int cs, u_int ef, u_int esp, u_int ss);
-typedef void unpendhand_t(void);
 #endif
 
 #define	IDTVEC(name)	__CONCAT(X,name)
@@ -158,7 +159,6 @@ inthand_t
 	Xipiq;		/* handle lwkt_send_ipiq() requests */
 #endif /* SMP */
 
-void	call_fast_unpend(int irq);
 void	isa_defaultirq (void);
 int	isa_nmi (int cd);
 void	icu_reinit (void);
diff --git a/sys/platform/pc64/x86_64/mp_machdep.c b/sys/platform/pc64/x86_64/mp_machdep.c
index 19c39dc..17797b3 100644
--- a/sys/platform/pc64/x86_64/mp_machdep.c
+++ b/sys/platform/pc64/x86_64/mp_machdep.c
@@ -993,7 +993,7 @@ mptable_pass2(struct mptable_pos *mpt)
 		bus_data[x].bus_id = 0xff;
 
 	/* clear IO APIC INT table */
-	for (x = 0; x < (nintrs + 1); ++x) {
+	for (x = 0; x < nintrs + FIXUP_EXTRA_APIC_INTS; ++x) {
 		io_apic_ints[x].int_type = 0xff;
 		io_apic_ints[x].int_vector = 0xff;
 	}
-- 
1.6.6.1

