[PATCH RFC 02/13] ioapic: introduce hooks for some ioapic ops

From: Roger Pau Monne <roger.pau_at_citrix.com>
Date: Tue, 24 Dec 2013 12:20:51 +0100
Create some hooks for IO APIC operations that will diverge from bare
metal when implemented for Xen Dom0.

This patch should not introduce any changes in functionality, it's a
preparatory patch for the implementation of the Xen IO APIC hooks.
---
 sys/amd64/include/apicvar.h |   13 ++++++++
 sys/i386/include/apicvar.h  |   13 ++++++++
 sys/x86/include/apicreg.h   |   12 ++++++++
 sys/x86/x86/io_apic.c       |   65 ++++++++++++++++++++++---------------------
 4 files changed, 71 insertions(+), 32 deletions(-)

diff --git a/sys/amd64/include/apicvar.h b/sys/amd64/include/apicvar.h
index 84e01d4..a48a76b 100644
--- a/sys/amd64/include/apicvar.h
+++ b/sys/amd64/include/apicvar.h
_at__at_ -161,6 +161,19 _at__at_ struct apic_enumerator {
 	SLIST_ENTRY(apic_enumerator) apic_next;
 };
 
+struct ioapic_intsrc {
+	struct intsrc io_intsrc;
+	u_int io_irq;
+	u_int io_intpin:8;
+	u_int io_vector:8;
+	u_int io_cpu:8;
+	u_int io_activehi:1;
+	u_int io_edgetrigger:1;
+	u_int io_masked:1;
+	int io_bus:4;
+	uint32_t io_lowreg;
+};
+
 inthand_t
 	IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3),
 	IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6),
diff --git a/sys/i386/include/apicvar.h b/sys/i386/include/apicvar.h
index 24c99f0..c8ee9bc 100644
--- a/sys/i386/include/apicvar.h
+++ b/sys/i386/include/apicvar.h
_at__at_ -160,6 +160,19 _at__at_ struct apic_enumerator {
 	SLIST_ENTRY(apic_enumerator) apic_next;
 };
 
+struct ioapic_intsrc {
+	struct intsrc io_intsrc;
+	u_int io_irq;
+	u_int io_intpin:8;
+	u_int io_vector:8;
+	u_int io_cpu:8;
+	u_int io_activehi:1;
+	u_int io_edgetrigger:1;
+	u_int io_masked:1;
+	int io_bus:4;
+	uint32_t io_lowreg;
+};
+
 inthand_t
 	IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3),
 	IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6),
diff --git a/sys/x86/include/apicreg.h b/sys/x86/include/apicreg.h
index 283d50e..4629470 100644
--- a/sys/x86/include/apicreg.h
+++ b/sys/x86/include/apicreg.h
_at__at_ -204,6 +204,18 _at__at_ struct IOAPIC {
 
 typedef struct IOAPIC ioapic_t;
 
+struct ioapic_intsrc;
+/*
+ * Struct containing pointers to IO APIC management functions whose
+ * implementation is run time selectable.
+ */
+struct ioapic_ops {
+	u_int    (*read)(volatile ioapic_t *, int);
+	void     (*write)(volatile ioapic_t *, int, u_int);
+	void     (*register_intr)(struct ioapic_intsrc *);
+};
+extern struct ioapic_ops ioapic_ops;
+
 #undef PAD4
 #undef PAD3
 
diff --git a/sys/x86/x86/io_apic.c b/sys/x86/x86/io_apic.c
index 6d62b1e..125d06a 100644
--- a/sys/x86/x86/io_apic.c
+++ b/sys/x86/x86/io_apic.c
_at__at_ -81,19 +81,6 _at__at_ static MALLOC_DEFINE(M_IOAPIC, "io_apic", "I/O APIC structures");
  * ftp://download.intel.com/design/chipsets/datashts/29056601.pdf
  */
 
-struct ioapic_intsrc {
-	struct intsrc io_intsrc;
-	u_int io_irq;
-	u_int io_intpin:8;
-	u_int io_vector:8;
-	u_int io_cpu:8;
-	u_int io_activehi:1;
-	u_int io_edgetrigger:1;
-	u_int io_masked:1;
-	int io_bus:4;
-	uint32_t io_lowreg;
-};
-
 struct ioapic {
 	struct pic io_pic;
 	u_int io_id:8;			/* logical ID */
_at__at_ -106,8 +93,9 _at__at_ struct ioapic {
 	struct ioapic_intsrc io_pins[0];
 };
 
-static u_int	ioapic_read(volatile ioapic_t *apic, int reg);
-static void	ioapic_write(volatile ioapic_t *apic, int reg, u_int val);
+static u_int	native_ioapic_read(volatile ioapic_t *apic, int reg);
+static void	native_ioapic_write(volatile ioapic_t *apic, int reg, u_int val);
+static void	native_ioapic_register_intr(struct ioapic_intsrc *pin);
 static const char *ioapic_bus_string(int bus_type);
 static void	ioapic_print_irq(struct ioapic_intsrc *intpin);
 static void	ioapic_enable_source(struct intsrc *isrc);
_at__at_ -139,6 +127,13 _at__at_ SYSCTL_INT(_hw_apic, OID_AUTO, enable_extint, CTLFLAG_RDTUN, &enable_extint, 0,
     "Enable the ExtINT pin in the first I/O APIC");
 TUNABLE_INT("hw.apic.enable_extint", &enable_extint);
 
+/* Default ioapic_ops implementation. */
+struct ioapic_ops ioapic_ops = {
+	.read =			native_ioapic_read,
+	.write =		native_ioapic_write,
+	.register_intr =	native_ioapic_register_intr,
+};
+
 static __inline void
 _ioapic_eoi_source(struct intsrc *isrc)
 {
_at__at_ -146,7 +141,7 _at__at_ _ioapic_eoi_source(struct intsrc *isrc)
 }
 
 static u_int
-ioapic_read(volatile ioapic_t *apic, int reg)
+native_ioapic_read(volatile ioapic_t *apic, int reg)
 {
 
 	mtx_assert(&icu_lock, MA_OWNED);
_at__at_ -155,7 +150,7 _at__at_ ioapic_read(volatile ioapic_t *apic, int reg)
 }
 
 static void
-ioapic_write(volatile ioapic_t *apic, int reg, u_int val)
+native_ioapic_write(volatile ioapic_t *apic, int reg, u_int val)
 {
 
 	mtx_assert(&icu_lock, MA_OWNED);
_at__at_ -163,6 +158,12 _at__at_ ioapic_write(volatile ioapic_t *apic, int reg, u_int val)
 	apic->iowin = val;
 }
 
+static void
+native_ioapic_register_intr(struct ioapic_intsrc *pin)
+{
+	intr_register_source(&pin->io_intsrc);
+}
+
 static const char *
 ioapic_bus_string(int bus_type)
 {
_at__at_ -212,7 +213,7 _at__at_ ioapic_enable_source(struct intsrc *isrc)
 	mtx_lock_spin(&icu_lock);
 	if (intpin->io_masked) {
 		flags = intpin->io_lowreg & ~IOART_INTMASK;
-		ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin),
+		ioapic_ops.write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin),
 		    flags);
 		intpin->io_masked = 0;
 	}
_at__at_ -229,7 +230,7 _at__at_ ioapic_disable_source(struct intsrc *isrc, int eoi)
 	mtx_lock_spin(&icu_lock);
 	if (!intpin->io_masked && !intpin->io_edgetrigger) {
 		flags = intpin->io_lowreg | IOART_INTMSET;
-		ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin),
+		ioapic_ops.write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin),
 		    flags);
 		intpin->io_masked = 1;
 	}
_at__at_ -264,10 +265,10 _at__at_ ioapic_program_intpin(struct ioapic_intsrc *intpin)
 	mtx_assert(&icu_lock, MA_OWNED);
 	if (intpin->io_irq == IRQ_DISABLED || (intpin->io_irq < NUM_IO_INTS &&
 	    intpin->io_vector == 0)) {
-		low = ioapic_read(io->io_addr,
+		low = ioapic_ops.read(io->io_addr,
 		    IOAPIC_REDTBL_LO(intpin->io_intpin));
 		if ((low & IOART_INTMASK) == IOART_INTMCLR)
-			ioapic_write(io->io_addr,
+			ioapic_ops.write(io->io_addr,
 			    IOAPIC_REDTBL_LO(intpin->io_intpin),
 			    low | IOART_INTMSET);
 		return;
_at__at_ -311,12 +312,12 _at__at_ ioapic_program_intpin(struct ioapic_intsrc *intpin)
 	}
 
 	/* Write the values to the APIC. */
-	value = ioapic_read(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin));
+	value = ioapic_ops.read(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin));
 	value &= ~IOART_DEST;
 	value |= high;
-	ioapic_write(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin), value);
+	ioapic_ops.write(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin), value);
 	intpin->io_lowreg = low;
-	ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), low);
+	ioapic_ops.write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), low);
 }
 
 static int
_at__at_ -357,7 +358,7 _at__at_ ioapic_assign_cpu(struct intsrc *isrc, u_int apic_id)
 	 */
 	mtx_lock_spin(&icu_lock);
 	if (!intpin->io_masked && !intpin->io_edgetrigger) {
-		ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin),
+		ioapic_ops.write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin),
 		    intpin->io_lowreg | IOART_INTMSET);
 		mtx_unlock_spin(&icu_lock);
 		DELAY(100);
_at__at_ -512,7 +513,7 _at__at_ ioapic_create(vm_paddr_t addr, int32_t apic_id, int intbase)
 	/* Map the register window so we can access the device. */
 	apic = pmap_mapdev(addr, IOAPIC_MEM_REGION);
 	mtx_lock_spin(&icu_lock);
-	value = ioapic_read(apic, IOAPIC_VER);
+	value = ioapic_ops.read(apic, IOAPIC_VER);
 	mtx_unlock_spin(&icu_lock);
 
 	/* If it's version register doesn't seem to work, punt. */
_at__at_ -528,9 +529,9 _at__at_ ioapic_create(vm_paddr_t addr, int32_t apic_id, int intbase)
 	io->io_pic = ioapic_template;
 	mtx_lock_spin(&icu_lock);
 	io->io_id = next_id++;
-	io->io_apic_id = ioapic_read(apic, IOAPIC_ID) >> APIC_ID_SHIFT;
+	io->io_apic_id = ioapic_ops.read(apic, IOAPIC_ID) >> APIC_ID_SHIFT;
 	if (apic_id != -1 && io->io_apic_id != apic_id) {
-		ioapic_write(apic, IOAPIC_ID, apic_id << APIC_ID_SHIFT);
+		ioapic_ops.write(apic, IOAPIC_ID, apic_id << APIC_ID_SHIFT);
 		mtx_unlock_spin(&icu_lock);
 		io->io_apic_id = apic_id;
 		printf("ioapic%u: Changing APIC ID to %d\n", io->io_id,
_at__at_ -586,8 +587,8 _at__at_ ioapic_create(vm_paddr_t addr, int32_t apic_id, int intbase)
 		 * be routed to other CPUs later after they are enabled.
 		 */
 		intpin->io_cpu = PCPU_GET(apic_id);
-		value = ioapic_read(apic, IOAPIC_REDTBL_LO(i));
-		ioapic_write(apic, IOAPIC_REDTBL_LO(i), value | IOART_INTMSET);
+		value = ioapic_ops.read(apic, IOAPIC_REDTBL_LO(i));
+		ioapic_ops.write(apic, IOAPIC_REDTBL_LO(i), value | IOART_INTMSET);
 	}
 	mtx_unlock_spin(&icu_lock);
 
_at__at_ -788,7 +789,7 _at__at_ ioapic_register(void *cookie)
 	io = (struct ioapic *)cookie;
 	apic = io->io_addr;
 	mtx_lock_spin(&icu_lock);
-	flags = ioapic_read(apic, IOAPIC_VER) & IOART_VER_VERSION;
+	flags = ioapic_ops.read(apic, IOAPIC_VER) & IOART_VER_VERSION;
 	STAILQ_INSERT_TAIL(&ioapic_list, io, io_next);
 	mtx_unlock_spin(&icu_lock);
 	printf("ioapic%u <Version %u.%u> irqs %u-%u on motherboard\n",
_at__at_ -799,7 +800,7 _at__at_ ioapic_register(void *cookie)
 	intr_register_pic(&io->io_pic);
 	for (i = 0, pin = io->io_pins; i < io->io_numintr; i++, pin++)
 		if (pin->io_irq < NUM_IO_INTS)
-			intr_register_source(&pin->io_intsrc);
+			ioapic_ops.register_intr(pin);
 }
 
 /* A simple new-bus driver to consume PCI I/O APIC devices. */
-- 
1.7.7.5 (Apple Git-26)
Received on Tue Dec 24 2013 - 10:22:38 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:45 UTC