PERFORCE change 89485 for review
Kip Macy
kmacy at FreeBSD.org
Tue Jan 10 19:47:42 PST 2006
http://perforce.freebsd.org/chv.cgi?CH=89485
Change 89485 by kmacy at 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 */
More information about the p4-projects
mailing list