[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Domain0 identifies IOAPIC by physical base address rather than BIOS-assigned identifier.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID fab6deef7e87a8b980de81311f34d91fcf550a6c # Parent 8aa45d7713e3c81cdd2305df125b82c9fe7bb202 Domain0 identifies IOAPIC by physical base address rather than BIOS-assigned identifier. This seems a more reliable method since it seems that we always trust the base address and we don't need to work around renumbering/rebasing as we do with APICIDs. This is an alternative to the Yonah networking patch from Allen Kay at Intel. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r 8aa45d7713e3 -r fab6deef7e87 linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c Fri Mar 3 13:10:35 2006 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c Fri Mar 3 14:05:25 2006 @@ -61,8 +61,8 @@ int ret; op.cmd = PHYSDEVOP_APIC_READ; - op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid; - op.u.apic_op.offset = reg; + op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr; + op.u.apic_op.reg = reg; ret = HYPERVISOR_physdev_op(&op); if (ret) return ret; @@ -74,8 +74,8 @@ 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.apic_physbase = mp_ioapics[apic].mpc_apicaddr; + op.u.apic_op.reg = reg; op.u.apic_op.value = value; HYPERVISOR_physdev_op(&op); } diff -r 8aa45d7713e3 -r fab6deef7e87 linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c Fri Mar 3 13:10:35 2006 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c Fri Mar 3 14:05:25 2006 @@ -108,8 +108,8 @@ int ret; op.cmd = PHYSDEVOP_APIC_READ; - op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid; - op.u.apic_op.offset = reg; + op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr; + op.u.apic_op.reg = reg; ret = HYPERVISOR_physdev_op(&op); if (ret) return ret; @@ -121,8 +121,8 @@ 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.apic_physbase = mp_ioapics[apic].mpc_apicaddr; + op.u.apic_op.reg = reg; op.u.apic_op.value = value; HYPERVISOR_physdev_op(&op); } diff -r 8aa45d7713e3 -r fab6deef7e87 xen/arch/x86/io_apic.c --- a/xen/arch/x86/io_apic.c Fri Mar 3 13:10:35 2006 +++ b/xen/arch/x86/io_apic.c Fri Mar 3 14:05:25 2006 @@ -1634,16 +1634,6 @@ "report. Then try booting with the 'noapic' option"); } -#define NR_IOAPIC_BIOSIDS 256 -static u8 ioapic_biosid_to_apic_enum[NR_IOAPIC_BIOSIDS]; -static void store_ioapic_biosid_mapping(void) -{ - u8 apic; - memset(ioapic_biosid_to_apic_enum, ~0, NR_IOAPIC_BIOSIDS); - for ( apic = 0; apic < nr_ioapics; apic++ ) - ioapic_biosid_to_apic_enum[mp_ioapics[apic].mpc_apicid] = apic; -} - /* * * IRQ's that are handled by the PIC in the MPS IOAPIC case. @@ -1655,8 +1645,6 @@ void __init setup_IO_APIC(void) { - store_ioapic_biosid_mapping(); - enable_IO_APIC(); if (acpi_ioapic) @@ -1840,50 +1828,45 @@ #endif /*CONFIG_ACPI_BOOT*/ - -int ioapic_guest_read(int apicid, int address, u32 *pval) -{ - u32 val; - int apicenum; - union IO_APIC_reg_00 reg_00; +static int ioapic_physbase_to_id(unsigned long physbase) +{ + int apic; + for ( apic = 0; apic < nr_ioapics; apic++ ) + if ( mp_ioapics[apic].mpc_apicaddr == physbase ) + return apic; + return -EINVAL; +} + +int ioapic_guest_read(unsigned long physbase, unsigned int reg, u32 *pval) +{ + int apic; unsigned long flags; - if ( (apicid >= NR_IOAPIC_BIOSIDS) || - ((apicenum = ioapic_biosid_to_apic_enum[apicid]) >= nr_ioapics) ) - return -EINVAL; + if ( (apic = ioapic_physbase_to_id(physbase)) < 0 ) + return apic; spin_lock_irqsave(&ioapic_lock, flags); - val = io_apic_read(apicenum, address); + *pval = io_apic_read(apic, reg); spin_unlock_irqrestore(&ioapic_lock, flags); - /* Rewrite APIC ID to what the BIOS originally specified. */ - if ( address == 0 ) - { - reg_00.raw = val; - reg_00.bits.ID = apicid; - val = reg_00.raw; - } - - *pval = val; return 0; } -int ioapic_guest_write(int apicid, int address, u32 val) -{ - int apicenum, pin, irq; +int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val) +{ + int apic, pin, irq; struct IO_APIC_route_entry rte = { 0 }; struct irq_pin_list *entry; unsigned long flags; - if ( (apicid >= NR_IOAPIC_BIOSIDS) || - ((apicenum = ioapic_biosid_to_apic_enum[apicid]) >= nr_ioapics) ) - return -EINVAL; + if ( (apic = ioapic_physbase_to_id(physbase)) < 0 ) + return apic; /* Only write to the first half of a route entry. */ - if ( (address < 0x10) || (address & 1) ) + if ( (reg < 0x10) || (reg & 1) ) return 0; - pin = (address - 0x10) >> 1; + pin = (reg - 0x10) >> 1; *(u32 *)&rte = val; rte.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); @@ -1899,7 +1882,7 @@ if ( rte.delivery_mode > dest_LowestPrio ) { printk("ERROR: Attempt to write weird IOAPIC destination mode!\n"); - printk(" APIC=%d/%d, lo-reg=%x\n", apicid, pin, val); + printk(" APIC=%d/%d, lo-reg=%x\n", apic, pin, val); return -EINVAL; } @@ -1924,19 +1907,19 @@ /* Record the pin<->irq mapping. */ for ( entry = &irq_2_pin[irq]; ; entry = &irq_2_pin[entry->next] ) { - if ( (entry->apic == apicenum) && (entry->pin == pin) ) + if ( (entry->apic == apic) && (entry->pin == pin) ) break; if ( !entry->next ) { - add_pin_to_irq(irq, apicenum, pin); + add_pin_to_irq(irq, apic, pin); break; } } } spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(apicenum, 0x10 + 2 * pin, *(((int *)&rte) + 0)); - io_apic_write(apicenum, 0x11 + 2 * pin, *(((int *)&rte) + 1)); + io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&rte) + 0)); + io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&rte) + 1)); spin_unlock_irqrestore(&ioapic_lock, flags); return 0; diff -r 8aa45d7713e3 -r fab6deef7e87 xen/arch/x86/physdev.c --- a/xen/arch/x86/physdev.c Fri Mar 3 13:10:35 2006 +++ b/xen/arch/x86/physdev.c Fri Mar 3 14:05:25 2006 @@ -11,8 +11,12 @@ #include <public/xen.h> #include <public/physdev.h> -extern int ioapic_guest_read(int apicid, int address, u32 *pval); -extern int ioapic_guest_write(int apicid, int address, u32 pval); +extern int +ioapic_guest_read( + unsigned long physbase, unsigned int reg, u32 *pval); +extern int +ioapic_guest_write( + unsigned long physbase, unsigned int reg, u32 pval); /* * Demuxing hypercall. @@ -49,7 +53,9 @@ if ( !IS_PRIV(current->domain) ) break; ret = ioapic_guest_read( - op.u.apic_op.apic, op.u.apic_op.offset, &op.u.apic_op.value); + op.u.apic_op.apic_physbase, + op.u.apic_op.reg, + &op.u.apic_op.value); break; case PHYSDEVOP_APIC_WRITE: @@ -57,7 +63,9 @@ if ( !IS_PRIV(current->domain) ) break; ret = ioapic_guest_write( - op.u.apic_op.apic, op.u.apic_op.offset, op.u.apic_op.value); + op.u.apic_op.apic_physbase, + op.u.apic_op.reg, + op.u.apic_op.value); break; case PHYSDEVOP_ASSIGN_VECTOR: diff -r 8aa45d7713e3 -r fab6deef7e87 xen/include/public/physdev.h --- a/xen/include/public/physdev.h Fri Mar 3 13:10:35 2006 +++ b/xen/include/public/physdev.h Fri Mar 3 14:05:25 2006 @@ -33,8 +33,8 @@ typedef struct physdevop_apic { /* IN */ - uint32_t apic; - uint32_t offset; + unsigned long apic_physbase; + uint32_t reg; /* IN or OUT */ uint32_t value; } physdevop_apic_t; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |