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>