Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Jan 2006 03:47:40 GMT
From:      Kip Macy <kmacy@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 89485 for review
Message-ID:  <200601110347.k0B3le2N025056@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=89485

Change 89485 by kmacy@kmacy:freebsd7_xen3 on 2006/01/11 03:47:18

	add dom0 io apic support
	determination of ioapic_read / ioapic_write functions is made at runtime

Affected files ...

.. //depot/projects/xen3/src/sys/i386-xen/conf/XENCONF#2 edit
.. //depot/projects/xen3/src/sys/i386-xen/i386-xen/io_apic.c#1 add
.. //depot/projects/xen3/src/sys/i386-xen/i386-xen/machdep.c#5 edit
.. //depot/projects/xen3/src/sys/i386/i386/io_apic.c#3 edit
.. //depot/projects/xen3/src/sys/i386/i386/machdep.c#2 edit
.. //depot/projects/xen3/src/sys/i386/i386/mptable.c#2 edit

Differences ...

==== //depot/projects/xen3/src/sys/i386-xen/conf/XENCONF#2 (text+ko) ====

@@ -63,7 +63,7 @@
 
 # To make an SMP kernel, the next two are needed
 #options 	SMP		# Symmetric MultiProcessor Kernel
-#device		apic		# I/O APIC
+device		apic		# I/O APIC
 
 # SCSI peripherals
 device		scbus		# SCSI bus (required for SCSI)
@@ -75,16 +75,16 @@
 #device		ses		# SCSI Environmental Services (and SAF-TE)
 
 # atkbdc0 controls both the keyboard and the PS/2 mouse
-#device		atkbdc		# AT keyboard controller
-#device		atkbd		# AT keyboard
-#device		psm		# PS/2 mouse
+device		atkbdc		# AT keyboard controller
+device		atkbd		# AT keyboard
+device		psm		# PS/2 mouse
 
-# device		vga	# VGA video card driver
+device		vga	# VGA video card driver
 
 #device		splash		# Splash screen and screen saver support
 
 # syscons is the default console driver, resembling an SCO console
-#device		sc
+device		sc
 
 # Enable this for the pcvt (VT220 compatible) console driver
 #device		vt

==== //depot/projects/xen3/src/sys/i386-xen/i386-xen/machdep.c#5 (text+ko) ====

@@ -158,6 +158,7 @@
 extern trap_info_t trap_table[];
 struct proc_ldt default_proc_ldt;
 extern int init_first;
+int running_xen = 1;
 #endif
 
 /* Sanity check for __curthread() */

==== //depot/projects/xen3/src/sys/i386/i386/io_apic.c#3 (text+ko) ====

@@ -67,19 +67,6 @@
 
 static MALLOC_DEFINE(M_IOAPIC, "io_apic", "I/O APIC structures");
 
-
-
-#ifdef XEN_PHYSDEV_ACCESS
-#include <machine/xen-public/xen.h>
-#include <machine/xen-public/physdev.h>
-
-/* 
- * XXX determine how apic index maps to ioapic_t
- *
- */
-
-
-#endif
 /*
  * I/O APIC interrupt source driver.  Each pin is assigned an IRQ cookie
  * as laid out in the ACPI System Interrupt number model where each I/O
@@ -117,8 +104,16 @@
 	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);
+struct ioapic_access {
+	u_int (*apic_read)(struct ioapic *apic, int reg);
+	void  (*apic_write)(struct ioapic *apic, int reg, u_int val);
+};
+
+
+static u_int	ioapic_read(struct ioapic *apic, int reg);
+static void	ioapic_write(struct ioapic *apic, int reg, u_int val);
+static u_int	xen_ioapic_read(struct ioapic *apic, int reg);
+static void	xen_ioapic_write(struct ioapic *apic, int reg, u_int val);
 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);
@@ -140,7 +135,13 @@
 			       ioapic_vector, ioapic_source_pending,
 			       ioapic_suspend, ioapic_resume,
 			       ioapic_config_intr };
-	
+#ifdef XEN
+#include <i386-xen/i386-xen/io_apic.c>
+#endif
+static struct ioapic_access access;
+extern int running_xen;
+
+
 static int bsp_id, current_cluster, logical_clusters, next_ioapic_base;
 static u_int next_id, program_logical_dest;
 
@@ -156,55 +157,23 @@
 	lapic_eoi();
 }
 
-#ifdef XEN
-static inline unsigned int 
-xen_ioapic_read(unsigned int apic, unsigned int reg)
-{
-	physdev_op_t op;
-	int ret;
-
-	op.cmd = PHYSDEVOP_APIC_READ;
-	op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid;
-	op.u.apic_op.offset = reg;
-	ret = HYPERVISOR_physdev_op(&op);
-	if (ret)
-		return ret;
-	return op.u.apic_op.value;
-}
-
-static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
-{
-	physdev_op_t op;
-
-	op.cmd = PHYSDEVOP_APIC_WRITE;
-	op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid;
-	op.u.apic_op.offset = reg;
-	op.u.apic_op.value = value;
-	HYPERVISOR_physdev_op(&op);
-}
-
-#define ioapic_read(a,r)    xen_ioapic_read(a,r)
-#define ioapic_write(a,r,v) xen_ioapic_write(a,r,v)
-
-#else
 static u_int
-ioapic_read(volatile ioapic_t *apic, int reg)
+ioapic_read(struct ioapic *io, int reg)
 {
 
 	mtx_assert(&icu_lock, MA_OWNED);
-	apic->ioregsel = reg;
-	return (apic->iowin);
+	io->io_addr->ioregsel = reg;
+	return (io->io_addr->iowin);
 }
 
 static void
-ioapic_write(volatile ioapic_t *apic, int reg, u_int val)
+ioapic_write(struct ioapic *io, int reg, u_int val)
 {
 
 	mtx_assert(&icu_lock, MA_OWNED);
-	apic->ioregsel = reg;
-	apic->iowin = val;
+	io->io_addr->ioregsel = reg;
+	io->io_addr->iowin = val;
 }
-#endif
 
 static const char *
 ioapic_bus_string(int bus_type)
@@ -254,10 +223,10 @@
 
 	mtx_lock_spin(&icu_lock);
 	if (intpin->io_masked) {
-		flags = ioapic_read(io->io_addr,
+		flags = access.apic_read(io,
 		    IOAPIC_REDTBL_LO(intpin->io_intpin));
 		flags &= ~(IOART_INTMASK);
-		ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin),
+		access.apic_write(io, IOAPIC_REDTBL_LO(intpin->io_intpin),
 		    flags);
 		intpin->io_masked = 0;
 	}
@@ -273,10 +242,10 @@
 
 	mtx_lock_spin(&icu_lock);
 	if (!intpin->io_masked && !intpin->io_edgetrigger) {
-		flags = ioapic_read(io->io_addr,
+		flags = access.apic_read(io,
 		    IOAPIC_REDTBL_LO(intpin->io_intpin));
 		flags |= IOART_INTMSET;
-		ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin),
+		access.apic_write(io, IOAPIC_REDTBL_LO(intpin->io_intpin),
 		    flags);
 		intpin->io_masked = 1;
 	}
@@ -311,10 +280,10 @@
 	if (intpin->io_irq == IRQ_DISABLED || (intpin->io_irq < NUM_IO_INTS &&
 	    intpin->io_vector == 0)) {
 		mtx_lock_spin(&icu_lock);
-		low = ioapic_read(io->io_addr,
+		low = access.apic_read(io,
 		    IOAPIC_REDTBL_LO(intpin->io_intpin));
 		if ((low & IOART_INTMASK) == IOART_INTMCLR)
-			ioapic_write(io->io_addr,
+			access.apic_write(io,
 			    IOAPIC_REDTBL_LO(intpin->io_intpin),
 			    low | IOART_INTMSET);
 		mtx_unlock_spin(&icu_lock);
@@ -366,11 +335,11 @@
 
 	/* Write the values to the APIC. */
 	mtx_lock_spin(&icu_lock);
-	ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), low);
-	value = ioapic_read(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin));
+	access.apic_write(io, IOAPIC_REDTBL_LO(intpin->io_intpin), low);
+	value = access.apic_read(io, IOAPIC_REDTBL_HI(intpin->io_intpin));
 	value &= ~IOART_DEST;
 	value |= high;
-	ioapic_write(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin), value);
+	access.apic_write(io, IOAPIC_REDTBL_HI(intpin->io_intpin), value);
 	mtx_unlock_spin(&icu_lock);
 }
 
@@ -539,34 +508,42 @@
 void *
 ioapic_create(uintptr_t addr, int32_t apic_id, int intbase)
 {
-	struct ioapic *io;
+	struct ioapic *io, tio;
 	struct ioapic_intsrc *intpin;
-	volatile ioapic_t *apic;
 	u_int numintr, i;
 	uint32_t value;
 
+	io = &tio;
+	/* XXX should xen just ignore this? */
 	/* Map the register window so we can access the device. */
-	apic = (ioapic_t *)pmap_mapdev(addr, IOAPIC_MEM_REGION);
+	io->io_addr = (ioapic_t *)pmap_mapdev(addr, IOAPIC_MEM_REGION);
+
+	/* set the nominal apic_id for the initial read */
+	io->io_apic_id = apic_id;
+
 	mtx_lock_spin(&icu_lock);
-	value = ioapic_read(apic, IOAPIC_VER);
+	/* fetch the APIC id in case we're running under xen */
+	io->io_apic_id = access.apic_read(io, IOAPIC_ID) >> APIC_ID_SHIFT;
+	value = access.apic_read(io, IOAPIC_VER);
 	mtx_unlock_spin(&icu_lock);
 
 	/* If it's version register doesn't seem to work, punt. */
 	if (value == 0xffffffff) {
-		pmap_unmapdev((vm_offset_t)apic, IOAPIC_MEM_REGION);
+		pmap_unmapdev((vm_offset_t)io->io_addr, IOAPIC_MEM_REGION);
+		free(io, M_IOAPIC);
 		return (NULL);
 	}
 
-	/* Determine the number of vectors and set the APIC ID. */
 	numintr = ((value & IOART_VER_MAXREDIR) >> MAXREDIRSHIFT) + 1;
 	io = malloc(sizeof(struct ioapic) +
 	    numintr * sizeof(struct ioapic_intsrc), M_IOAPIC, M_WAITOK);
 	io->io_pic = ioapic_template;
+	io->io_addr = tio.io_addr;
 	mtx_lock_spin(&icu_lock);
 	io->io_id = next_id++;
-	io->io_apic_id = ioapic_read(apic, IOAPIC_ID) >> APIC_ID_SHIFT;	
+	/* XXX not sure how xen feels about apic id re-mapping */
 	if (apic_id != -1 && io->io_apic_id != apic_id) {
-		ioapic_write(apic, IOAPIC_ID, apic_id << APIC_ID_SHIFT);
+		access.apic_write(io, 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,
@@ -583,7 +560,6 @@
 	io->io_intbase = intbase;
 	next_ioapic_base = intbase + numintr;
 	io->io_numintr = numintr;
-	io->io_addr = apic;
 
 	/*
 	 * Initialize pins.  Start off with interrupts disabled.  Default
@@ -629,8 +605,8 @@
 			    "edge" : "level", intpin->io_activehi ? "high" :
 			    "low");
 		}
-		value = ioapic_read(apic, IOAPIC_REDTBL_LO(i));
-		ioapic_write(apic, IOAPIC_REDTBL_LO(i), value | IOART_INTMSET);
+		value = access.apic_read(io, IOAPIC_REDTBL_LO(i));
+		access.apic_write(io, IOAPIC_REDTBL_LO(i), value | IOART_INTMSET);
 	}
 	mtx_unlock_spin(&icu_lock);
 
@@ -814,14 +790,12 @@
 {
 	struct ioapic_intsrc *pin;
 	struct ioapic *io;
-	volatile ioapic_t *apic;
 	uint32_t flags;
 	int i;
 
 	io = (struct ioapic *)cookie;
-	apic = io->io_addr;
 	mtx_lock_spin(&icu_lock);
-	flags = ioapic_read(apic, IOAPIC_VER) & IOART_VER_VERSION;
+	flags = access.apic_read(io, 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",
@@ -844,7 +818,7 @@
 {
 	struct ioapic *io;
 	int i;
-
+	
 	program_logical_dest = 1;
 	STAILQ_FOREACH(io, &ioapic_list, io_next)
 	    for (i = 0; i < io->io_numintr; i++)
@@ -853,3 +827,18 @@
 }
 SYSINIT(ioapic_destinations, SI_SUB_SMP, SI_ORDER_SECOND,
     ioapic_set_logical_destinations, NULL)
+
+
+static void
+ioapic_init_access(void *arg __unused)
+{
+	if (running_xen) {
+		access.apic_read = xen_ioapic_read;
+		access.apic_write = xen_ioapic_write;
+	} else {
+		access.apic_read = ioapic_read;
+		access.apic_write = ioapic_write;
+	}
+}
+SYSINIT(ioapic_access, SI_SUB_CONFIGURE, SI_ORDER_FIRST,
+    ioapic_init_access, NULL)

==== //depot/projects/xen3/src/sys/i386/i386/machdep.c#2 (text+ko) ====

@@ -177,6 +177,7 @@
 u_int	basemem;
 
 int cold = 1;
+int running_xen = 0;
 
 #ifdef COMPAT_43
 static void osendsig(sig_t catcher, ksiginfo_t *, sigset_t *mask);

==== //depot/projects/xen3/src/sys/i386/i386/mptable.c#2 (text+ko) ====

@@ -146,6 +146,7 @@
 static bus_datum *busses;
 static int mptable_nioapics, mptable_nbusses, mptable_maxbusid;
 static int pci0 = -1;
+extern int running_xen;
 
 static MALLOC_DEFINE(M_MPTABLE, "mptable", "MP Table Items");
 
@@ -227,6 +228,10 @@
 	u_long  segment;
 	u_int32_t target;
 
+	/* ignore SMP support for now */
+	if (running_xen)
+		return (ENXIO);
+	
 	/* see if EBDA exists */
 	if ((segment = (u_long) * (u_short *) (KERNBASE + 0x40e)) != 0) {
 		/* search first 1K of EBDA */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200601110347.k0B3le2N025056>