[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] More upgrades of Xen code to linux-2.6.16-rc2.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 07a892f1260933c584f781f2262dfa59a5ba8d70 # Parent b9b411b505878f7600871c68de989d33c1994cf7 More upgrades of Xen code to linux-2.6.16-rc2. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r b9b411b50587 -r 07a892f12609 xen/arch/x86/acpi/boot.c --- a/xen/arch/x86/acpi/boot.c Tue Feb 14 15:23:43 2006 +++ b/xen/arch/x86/acpi/boot.c Tue Feb 14 17:25:10 2006 @@ -28,6 +28,7 @@ #include <xen/init.h> #include <xen/acpi.h> #include <xen/irq.h> +#include <xen/dmi.h> #include <asm/fixmap.h> #include <asm/page.h> #include <asm/apic.h> @@ -75,7 +76,7 @@ #define MAX_MADT_ENTRIES 256 u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] = - { [0 ... MAX_MADT_ENTRIES-1] = 0xff }; + {[0 ... MAX_MADT_ENTRIES - 1] = 0xff }; EXPORT_SYMBOL(x86_acpiid_to_apicid); /* -------------------------------------------------------------------------- @@ -105,7 +106,7 @@ unsigned long base, offset, mapped_size; int idx; - if (phys + size < 8*1024*1024) + if (phys + size < 8 * 1024 * 1024) return __va(phys); offset = phys & (PAGE_SIZE - 1); @@ -128,45 +129,15 @@ return ((char *) base + offset); } -#ifdef CONFIG_PCI_MMCONFIG -static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) -{ - struct acpi_table_mcfg *mcfg; +#ifdef CONFIG_X86_LOCAL_APIC +static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) +{ + struct acpi_table_madt *madt = NULL; if (!phys_addr || !size) return -EINVAL; - mcfg = (struct acpi_table_mcfg *) __acpi_map_table(phys_addr, size); - if (!mcfg) { - printk(KERN_WARNING PREFIX "Unable to map MCFG\n"); - return -ENODEV; - } - - if (mcfg->base_reserved) { - printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); - return -ENODEV; - } - - pci_mmcfg_base_addr = mcfg->base_address; - - return 0; -} -#else -#define acpi_parse_mcfg NULL -#endif /* !CONFIG_PCI_MMCONFIG */ - -#ifdef CONFIG_X86_LOCAL_APIC -static int __init -acpi_parse_madt ( - unsigned long phys_addr, - unsigned long size) -{ - struct acpi_table_madt *madt = NULL; - - if (!phys_addr || !size) - return -EINVAL; - - madt = (struct acpi_table_madt *) __acpi_map_table(phys_addr, size); + madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); if (!madt) { printk(KERN_WARNING PREFIX "Unable to map MADT\n"); return -ENODEV; @@ -184,40 +155,35 @@ return 0; } - static int __init -acpi_parse_lapic ( - acpi_table_entry_header *header, const unsigned long end) +acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end) { struct acpi_table_lapic *processor = NULL; - processor = (struct acpi_table_lapic*) header; + processor = (struct acpi_table_lapic *)header; if (BAD_MADT_ENTRY(processor, end)) return -EINVAL; acpi_table_print_madt_entry(header); - /* no utility in registering a disabled processor */ - if (processor->flags.enabled == 0) - return 0; + /* Register even disabled CPUs for cpu hotplug */ x86_acpiid_to_apicid[processor->acpi_id] = processor->id; - mp_register_lapic ( - processor->id, /* APIC ID */ - processor->flags.enabled); /* Enabled? */ + mp_register_lapic(processor->id, /* APIC ID */ + processor->flags.enabled); /* Enabled? */ return 0; } static int __init -acpi_parse_lapic_addr_ovr ( - acpi_table_entry_header *header, const unsigned long end) +acpi_parse_lapic_addr_ovr(acpi_table_entry_header * header, + const unsigned long end) { struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL; - lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr*) header; + lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr *)header; if (BAD_MADT_ENTRY(lapic_addr_ovr, end)) return -EINVAL; @@ -228,12 +194,11 @@ } static int __init -acpi_parse_lapic_nmi ( - acpi_table_entry_header *header, const unsigned long end) +acpi_parse_lapic_nmi(acpi_table_entry_header * header, const unsigned long end) { struct acpi_table_lapic_nmi *lapic_nmi = NULL; - lapic_nmi = (struct acpi_table_lapic_nmi*) header; + lapic_nmi = (struct acpi_table_lapic_nmi *)header; if (BAD_MADT_ENTRY(lapic_nmi, end)) return -EINVAL; @@ -246,39 +211,35 @@ return 0; } - -#endif /*CONFIG_X86_LOCAL_APIC*/ +#endif /*CONFIG_X86_LOCAL_APIC */ #if defined(CONFIG_X86_IO_APIC) /*&& defined(CONFIG_ACPI_INTERPRETER)*/ static int __init -acpi_parse_ioapic ( - acpi_table_entry_header *header, const unsigned long end) +acpi_parse_ioapic(acpi_table_entry_header * header, const unsigned long end) { struct acpi_table_ioapic *ioapic = NULL; - ioapic = (struct acpi_table_ioapic*) header; + ioapic = (struct acpi_table_ioapic *)header; if (BAD_MADT_ENTRY(ioapic, end)) return -EINVAL; acpi_table_print_madt_entry(header); - mp_register_ioapic ( - ioapic->id, - ioapic->address, - ioapic->global_irq_base); - + mp_register_ioapic(ioapic->id, + ioapic->address, ioapic->global_irq_base); + return 0; } static int __init -acpi_parse_int_src_ovr ( - acpi_table_entry_header *header, const unsigned long end) +acpi_parse_int_src_ovr(acpi_table_entry_header * header, + const unsigned long end) { struct acpi_table_int_src_ovr *intsrc = NULL; - intsrc = (struct acpi_table_int_src_ovr*) header; + intsrc = (struct acpi_table_int_src_ovr *)header; if (BAD_MADT_ENTRY(intsrc, end)) return -EINVAL; @@ -291,23 +252,19 @@ return 0; } - mp_override_legacy_irq ( - intsrc->bus_irq, - intsrc->flags.polarity, - intsrc->flags.trigger, - intsrc->global_irq); - - return 0; -} - + mp_override_legacy_irq(intsrc->bus_irq, + intsrc->flags.polarity, + intsrc->flags.trigger, intsrc->global_irq); + + return 0; +} static int __init -acpi_parse_nmi_src ( - acpi_table_entry_header *header, const unsigned long end) +acpi_parse_nmi_src(acpi_table_entry_header * header, const unsigned long end) { struct acpi_table_nmi_src *nmi_src = NULL; - nmi_src = (struct acpi_table_nmi_src*) header; + nmi_src = (struct acpi_table_nmi_src *)header; if (BAD_MADT_ENTRY(nmi_src, end)) return -EINVAL; @@ -322,9 +279,7 @@ #endif /* CONFIG_X86_IO_APIC */ static unsigned long __init -acpi_scan_rsdp ( - unsigned long start, - unsigned long length) +acpi_scan_rsdp(unsigned long start, unsigned long length) { unsigned long offset = 0; unsigned long sig_len = sizeof("RSD PTR ") - 1; @@ -334,7 +289,7 @@ * RSDP signature. */ for (offset = 0; offset < length; offset += 16) { - if (strncmp((char *) (start + offset), "RSD PTR ", sig_len)) + if (strncmp((char *)(start + offset), "RSD PTR ", sig_len)) continue; return (start + offset); } @@ -349,7 +304,7 @@ if (!phys_addr || !size) return -EINVAL; - sb = (struct acpi_table_sbf *) __acpi_map_table(phys_addr, size); + sb = (struct acpi_table_sbf *)__acpi_map_table(phys_addr, size); if (!sb) { printk(KERN_WARNING PREFIX "Unable to map SBF\n"); return -ENODEV; @@ -370,7 +325,7 @@ if (!phys || !size) return -EINVAL; - hpet_tbl = (struct acpi_table_hpet *) __acpi_map_table(phys, size); + hpet_tbl = (struct acpi_table_hpet *)__acpi_map_table(phys, size); if (!hpet_tbl) { printk(KERN_WARNING PREFIX "Unable to map HPET\n"); return -ENODEV; @@ -412,8 +367,8 @@ { struct fadt_descriptor_rev2 *fadt = NULL; - fadt = (struct fadt_descriptor_rev2*) __acpi_map_table(phys,size); - if(!fadt) { + fadt = (struct fadt_descriptor_rev2 *)__acpi_map_table(phys, size); + if (!fadt) { printk(KERN_WARNING PREFIX "Unable to map FADT\n"); return 0; } @@ -421,29 +376,42 @@ #ifdef CONFIG_ACPI_INTERPRETER /* initialize sci_int early for INT_SRC_OVR MADT parsing */ acpi_fadt.sci_int = fadt->sci_int; + + /* initialize rev and apic_phys_dest_mode for x86_64 genapic */ + acpi_fadt.revision = fadt->revision; + acpi_fadt.force_apic_physical_destination_mode = + fadt->force_apic_physical_destination_mode; #endif #ifdef CONFIG_X86_PM_TIMER /* detect the location of the ACPI PM Timer */ if (fadt->revision >= FADT2_REVISION_ID) { /* FADT rev. 2 */ - if (fadt->xpm_tmr_blk.address_space_id != ACPI_ADR_SPACE_SYSTEM_IO) + if (fadt->xpm_tmr_blk.address_space_id != + ACPI_ADR_SPACE_SYSTEM_IO) return 0; pmtmr_ioport = fadt->xpm_tmr_blk.address; + /* + * "X" fields are optional extensions to the original V1.0 + * fields, so we must selectively expand V1.0 fields if the + * corresponding X field is zero. + */ + if (!pmtmr_ioport) + pmtmr_ioport = fadt->V1_pm_tmr_blk; } else { /* FADT rev. 1 */ pmtmr_ioport = fadt->V1_pm_tmr_blk; } if (pmtmr_ioport) - printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", pmtmr_ioport); -#endif - return 0; -} - - -unsigned long __init -acpi_find_rsdp (void) + printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", + pmtmr_ioport); +#endif + return 0; +} + + +unsigned long __init acpi_find_rsdp(void) { unsigned long rsdp_phys = 0; @@ -459,9 +427,9 @@ * Scan memory looking for the RSDP signature. First search EBDA (low * memory) paragraphs and then search upper memory (E0000-FFFFF). */ - rsdp_phys = acpi_scan_rsdp (0, 0x400); + rsdp_phys = acpi_scan_rsdp(0, 0x400); if (!rsdp_phys) - rsdp_phys = acpi_scan_rsdp (0xE0000, 0x20000); + rsdp_phys = acpi_scan_rsdp(0xE0000, 0x20000); return rsdp_phys; } @@ -471,8 +439,7 @@ * Parse LAPIC entries in MADT * returns 0 on success, < 0 on error */ -static int __init -acpi_parse_madt_lapic_entries(void) +static int __init acpi_parse_madt_lapic_entries(void) { int count; @@ -481,9 +448,12 @@ * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). */ - count = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0); + count = + acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, + acpi_parse_lapic_addr_ovr, 0); if (count < 0) { - printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); + printk(KERN_ERR PREFIX + "Error parsing LAPIC address override entry\n"); return count; } @@ -495,14 +465,14 @@ printk(KERN_ERR PREFIX "No LAPIC entries present\n"); /* TBD: Cleanup to allow fallback to MPS */ return -ENODEV; - } - else if (count < 0) { + } else if (count < 0) { printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); /* TBD: Cleanup to allow fallback to MPS */ return count; } - count = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0); + count = + acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0); if (count < 0) { printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); /* TBD: Cleanup to allow fallback to MPS */ @@ -517,8 +487,7 @@ * Parse IOAPIC related entries in MADT * returns 0 on success, < 0 on error */ -static int __init -acpi_parse_madt_ioapic_entries(void) +static int __init acpi_parse_madt_ioapic_entries(void) { int count; @@ -541,19 +510,23 @@ return -ENODEV; } - count = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, MAX_IO_APICS); + count = + acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, + MAX_IO_APICS); if (!count) { printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); return -ENODEV; - } - else if (count < 0) { + } else if (count < 0) { printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n"); return count; } - count = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS); + count = + acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, + NR_IRQ_VECTORS); if (count < 0) { - printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); + printk(KERN_ERR PREFIX + "Error parsing interrupt source overrides entry\n"); /* TBD: Cleanup to allow fallback to MPS */ return count; } @@ -570,7 +543,9 @@ /* Fill in identity legacy mapings where no override */ mp_config_acpi_legacy_irqs(); - count = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, NR_IRQ_VECTORS); + count = + acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, + NR_IRQ_VECTORS); if (count < 0) { printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); /* TBD: Cleanup to allow fallback to MPS */ @@ -587,8 +562,7 @@ #endif /* !(CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER) */ -static void __init -acpi_process_madt(void) +static void __init acpi_process_madt(void) { #ifdef CONFIG_X86_LOCAL_APIC int count, error; @@ -621,13 +595,226 @@ /* * Dell Precision Workstation 410, 610 come here. */ - printk(KERN_ERR PREFIX "Invalid BIOS MADT, disabling ACPI\n"); + printk(KERN_ERR PREFIX + "Invalid BIOS MADT, disabling ACPI\n"); disable_acpi(); } } #endif return; } + +extern int acpi_force; + +#ifdef __i386__ + +static int __init disable_acpi_irq(struct dmi_system_id *d) +{ + if (!acpi_force) { + printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n", + d->ident); + acpi_noirq_set(); + } + return 0; +} + +static int __init disable_acpi_pci(struct dmi_system_id *d) +{ + if (!acpi_force) { + printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", + d->ident); + /*acpi_disable_pci();*/ + } + return 0; +} + +static int __init dmi_disable_acpi(struct dmi_system_id *d) +{ + if (!acpi_force) { + printk(KERN_NOTICE "%s detected: acpi off\n", d->ident); + disable_acpi(); + } else { + printk(KERN_NOTICE + "Warning: DMI blacklist says broken, but acpi forced\n"); + } + return 0; +} + +/* + * Limit ACPI to CPU enumeration for HT + */ +static int __init force_acpi_ht(struct dmi_system_id *d) +{ + if (!acpi_force) { + printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", + d->ident); + disable_acpi(); + acpi_ht = 1; + } else { + printk(KERN_NOTICE + "Warning: acpi=force overrules DMI blacklist: acpi=ht\n"); + } + return 0; +} + +/* + * If your system is blacklisted here, but you find that acpi=force + * works for you, please contact acpi-devel@xxxxxxxxxxxxxxx + */ +static struct dmi_system_id __initdata acpi_dmi_table[] = { + /* + * Boxes that need ACPI disabled + */ + { + .callback = dmi_disable_acpi, + .ident = "IBM Thinkpad", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), + DMI_MATCH(DMI_BOARD_NAME, "2629H1G"), + }, + }, + + /* + * Boxes that need acpi=ht + */ + { + .callback = force_acpi_ht, + .ident = "FSC Primergy T850", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"), + }, + }, + { + .callback = force_acpi_ht, + .ident = "DELL GX240", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"), + }, + }, + { + .callback = force_acpi_ht, + .ident = "HP VISUALIZE NT Workstation", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"), + }, + }, + { + .callback = force_acpi_ht, + .ident = "Compaq Workstation W8000", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), + DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"), + }, + }, + { + .callback = force_acpi_ht, + .ident = "ASUS P4B266", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "P4B266"), + }, + }, + { + .callback = force_acpi_ht, + .ident = "ASUS P2B-DS", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"), + }, + }, + { + .callback = force_acpi_ht, + .ident = "ASUS CUR-DLS", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"), + }, + }, + { + .callback = force_acpi_ht, + .ident = "ABIT i440BX-W83977", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"), + DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"), + }, + }, + { + .callback = force_acpi_ht, + .ident = "IBM Bladecenter", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), + DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"), + }, + }, + { + .callback = force_acpi_ht, + .ident = "IBM eServer xSeries 360", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), + DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"), + }, + }, + { + .callback = force_acpi_ht, + .ident = "IBM eserver xSeries 330", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), + DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"), + }, + }, + { + .callback = force_acpi_ht, + .ident = "IBM eserver xSeries 440", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), + DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"), + }, + }, + + /* + * Boxes that need ACPI PCI IRQ routing disabled + */ + { + .callback = disable_acpi_irq, + .ident = "ASUS A7V", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"), + DMI_MATCH(DMI_BOARD_NAME, "<A7V>"), + /* newer BIOS, Revision 1011, does work */ + DMI_MATCH(DMI_BIOS_VERSION, + "ASUS A7V ACPI BIOS Revision 1007"), + }, + }, + + /* + * Boxes that need ACPI PCI IRQ routing and PCI scan disabled + */ + { /* _BBN 0 bug */ + .callback = disable_acpi_pci, + .ident = "ASUS PR-DLS", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "PR-DLS"), + DMI_MATCH(DMI_BIOS_VERSION, + "ASUS PR-DLS ACPI BIOS Revision 1010"), + DMI_MATCH(DMI_BIOS_DATE, "03/21/2003") + }, + }, + { + .callback = disable_acpi_pci, + .ident = "Acer TravelMate 36x Laptop", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), + }, + }, + {} +}; + +#endif /* __i386__ */ /* * acpi_boot_table_init() and acpi_boot_init() @@ -652,10 +839,13 @@ * !0: failure */ -int __init -acpi_boot_table_init(void) +int __init acpi_boot_table_init(void) { int error; + +#ifdef __i386__ + dmi_check_system(acpi_dmi_table); +#endif /* * If acpi_disabled, bail out @@ -717,8 +907,7 @@ acpi_process_madt(); acpi_table_parse(ACPI_HPET, acpi_parse_hpet); - acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); - - return 0; -} - + + return 0; +} + diff -r b9b411b50587 -r 07a892f12609 xen/arch/x86/apic.c --- a/xen/arch/x86/apic.c Tue Feb 14 15:23:43 2006 +++ b/xen/arch/x86/apic.c Tue Feb 14 17:25:10 2006 @@ -38,9 +38,53 @@ #include <io_ports.h> /* + * Knob to control our willingness to enable the local APIC. + */ +int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ + +/* * Debug level */ int apic_verbosity; + + +static void apic_pm_activate(void); + +/* + * 'what should we do if we get a hw irq event on an illegal vector'. + * each architecture has to answer this themselves. + */ +void ack_bad_irq(unsigned int irq) +{ + printk("unexpected IRQ trap at vector %02x\n", irq); + /* + * Currently unexpected vectors happen only on SMP and APIC. + * We _must_ ack these because every local APIC has only N + * irq slots per priority level, and a 'hanging, unacked' IRQ + * holds up an irq slot - in excessive cases (when multiple + * unexpected vectors occur) that might lock up the APIC + * completely. + */ + ack_APIC_irq(); +} + +void __init apic_intr_init(void) +{ +#ifdef CONFIG_SMP + smp_intr_init(); +#endif + /* self generated IPI for local APIC timer */ + set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); + + /* IPI vectors for APIC spurious and error interrupts */ + set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); + set_intr_gate(ERROR_APIC_VECTOR, error_interrupt); + + /* thermal monitor LVT interrupt */ +#ifdef CONFIG_X86_MCE_P4THERMAL + set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); +#endif +} /* Using APIC to generate smp_local_timer_interrupt? */ int using_apic_timer = 0; @@ -148,7 +192,7 @@ enable_apic_mode(); } -void disconnect_bsp_APIC(void) +void disconnect_bsp_APIC(int virt_wire_setup) { if (pic_mode) { /* @@ -162,6 +206,42 @@ outb(0x70, 0x22); outb(0x00, 0x23); } + else { + /* Go back to Virtual Wire compatibility mode */ + unsigned long value; + + /* For the spurious interrupt use vector F, and enable it */ + value = apic_read(APIC_SPIV); + value &= ~APIC_VECTOR_MASK; + value |= APIC_SPIV_APIC_ENABLED; + value |= 0xf; + apic_write_around(APIC_SPIV, value); + + if (!virt_wire_setup) { + /* For LVT0 make it edge triggered, active high, external and enabled */ + value = apic_read(APIC_LVT0); + value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | + APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | + APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED ); + value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; + value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT); + apic_write_around(APIC_LVT0, value); + } + else { + /* Disable LVT0 */ + apic_write_around(APIC_LVT0, APIC_LVT_MASKED); + } + + /* For LVT1 make it edge triggered, active high, nmi and enabled */ + value = apic_read(APIC_LVT1); + value &= ~( + APIC_MODE_MASK | APIC_SEND_PENDING | + APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | + APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); + value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; + value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI); + apic_write_around(APIC_LVT1, value); + } } void disable_local_APIC(void) @@ -306,7 +386,7 @@ apic_write_around(APIC_LVT1, value); } -void __init setup_local_APIC (void) +void __devinit setup_local_APIC(void) { unsigned long oldvalue, value, ver, maxlvt; @@ -453,17 +533,15 @@ if (nmi_watchdog == NMI_LOCAL_APIC) setup_apic_nmi_watchdog(); -} + apic_pm_activate(); +} + +static void apic_pm_activate(void) { } /* * Detect and enable local APICs on non-SMP boards. * Original code written by Keir Fraser. */ - -/* - * Knob to control our willingness to enable the local APIC. - */ -int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ static void __init lapic_disable(char *str) { @@ -497,9 +575,6 @@ /* Disabled by kernel option? */ if (enable_local_apic < 0) return -1; - - /* Workaround for us being called before identify_cpu(). */ - /*get_cpu_vendor(&boot_cpu_data); Not for Xen */ switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_AMD: @@ -564,6 +639,8 @@ printk("Found and enabled local APIC!\n"); + apic_pm_activate(); + return 0; no_apic: @@ -824,26 +901,27 @@ void __init setup_boot_APIC_clock(void) { + unsigned long flags; apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"); using_apic_timer = 1; - local_irq_disable(); - + local_irq_save(flags); + calibration_result = calibrate_APIC_clock(); /* * Now set up the timer for real. */ setup_APIC_timer(calibration_result); - local_irq_enable(); -} - -void __init setup_secondary_APIC_clock(void) + local_irq_restore(flags); +} + +void __devinit setup_secondary_APIC_clock(void) { setup_APIC_timer(calibration_result); } -void __init disable_APIC_timer(void) +void disable_APIC_timer(void) { if (using_apic_timer) { unsigned long v; @@ -941,6 +1019,7 @@ { unsigned long v; + irq_enter(); /* * Check if this really is a spurious interrupt and ACK it * if it is a vectored one. Just in case... @@ -953,6 +1032,7 @@ /* see sw-dev-man vol 3, chapter 7.4.13.5 */ printk(KERN_INFO "spurious APIC interrupt on CPU#%d, should never happen.\n", smp_processor_id()); + irq_exit(); } /* @@ -963,6 +1043,7 @@ { unsigned long v, v1; + irq_enter(); /* First tickle the hardware, only then report what went on. -- REW */ v = apic_read(APIC_ESR); apic_write(APIC_ESR, 0); @@ -982,6 +1063,7 @@ */ printk (KERN_DEBUG "APIC error on CPU%d: %02lx(%02lx)\n", smp_processor_id(), v , v1); + irq_exit(); } /* diff -r b9b411b50587 -r 07a892f12609 xen/arch/x86/cpu/mcheck/p4.c --- a/xen/arch/x86/cpu/mcheck/p4.c Tue Feb 14 15:23:43 2006 +++ b/xen/arch/x86/cpu/mcheck/p4.c Tue Feb 14 17:25:10 2006 @@ -71,9 +71,9 @@ fastcall void smp_thermal_interrupt(struct cpu_user_regs *regs) { - irq_enter(smp_processor_id()); + irq_enter(); vendor_thermal_interrupt(regs); - irq_exit(smp_processor_id()); + irq_exit(); } /* P4/Xeon Thermal regulation detect and init */ diff -r b9b411b50587 -r 07a892f12609 xen/arch/x86/i8259.c --- a/xen/arch/x86/i8259.c Tue Feb 14 15:23:43 2006 +++ b/xen/arch/x86/i8259.c Tue Feb 14 17:25:10 2006 @@ -374,25 +374,7 @@ irq_desc[LEGACY_VECTOR(i)].handler = &i8259A_irq_type; } - /* - * IRQ0 must be given a fixed assignment and initialized, - * because it's used before the IO-APIC is set up. - */ - irq_vector[0] = FIRST_DEVICE_VECTOR; - vector_irq[FIRST_DEVICE_VECTOR] = 0; - - /* Various IPI functions. */ - set_intr_gate(EVENT_CHECK_VECTOR, event_check_interrupt); - set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt); - set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); - - /* Self-generated IPI for local APIC timer. */ - set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); - - /* IPI vectors for APIC spurious and error interrupts. */ - set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); - set_intr_gate(ERROR_APIC_VECTOR, error_interrupt); - set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); + apic_intr_init(); /* Set the clock to HZ Hz */ #define CLOCK_TICK_RATE 1193180 /* crystal freq (Hz) */ diff -r b9b411b50587 -r 07a892f12609 xen/arch/x86/io_apic.c --- a/xen/arch/x86/io_apic.c Tue Feb 14 15:23:43 2006 +++ b/xen/arch/x86/io_apic.c Tue Feb 14 17:25:10 2006 @@ -35,11 +35,18 @@ #include <mach_apic.h> #include <io_ports.h> +#define set_irq_info(irq, mask) ((void)0) +#define set_native_irq_info(irq, mask) ((void)0) + +/* Different to Linux: our implementation can be simpler. */ #define make_8259A_irq(irq) (io_apic_irqs &= ~(1<<(irq))) int (*ioapic_renumber_irq)(int ioapic, int irq); atomic_t irq_mis_count; +/* Where if anywhere is the i8259 connect in external int mode */ +static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; + static DEFINE_SPINLOCK(ioapic_lock); int skip_ioapic_setup; @@ -48,6 +55,8 @@ * # of IRQ routing registers */ int nr_ioapic_registers[MAX_IO_APICS]; + +int disable_timer_pin_1 __initdata; /* * Rough estimation of how many shared IRQs there are, can @@ -67,7 +76,7 @@ int apic, pin, next; } irq_2_pin[PIN_MAP_SIZE]; -int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; +int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1}; /* * The common case is 1:1 IRQ<->pin mappings. Sometimes there are @@ -173,7 +182,7 @@ spin_unlock_irqrestore(&ioapic_lock, flags); } -void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) +static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) { struct IO_APIC_route_entry entry; unsigned long flags; @@ -206,13 +215,21 @@ clear_IO_APIC_pin(apic, pin); } +#ifdef CONFIG_SMP static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) { unsigned long flags; int pin; struct irq_pin_list *entry = irq_2_pin + irq; unsigned int apicid_value; + cpumask_t tmp; + cpus_and(tmp, cpumask, cpu_online_map); + if (cpus_empty(tmp)) + tmp = TARGET_CPUS; + + cpus_and(cpumask, tmp, CPU_MASK_ALL); + apicid_value = cpu_mask_to_apicid(cpumask); /* Prepare to do the io_apic_write */ apicid_value = apicid_value << 24; @@ -226,8 +243,10 @@ break; entry = irq_2_pin + entry->next; } + set_irq_info(irq, cpumask); spin_unlock_irqrestore(&ioapic_lock, flags); } +#endif /* CONFIG_SMP */ /* * Find the IRQ entry number of a certain pin. @@ -249,7 +268,7 @@ /* * Find the pin to which IRQ[irq] (ISA) is connected */ -static int find_isa_irq_pin(int irq, int type) +static int __init find_isa_irq_pin(int irq, int type) { int i; @@ -269,6 +288,33 @@ return -1; } +static int __init find_isa_irq_apic(int irq, int type) +{ + int i; + + for (i = 0; i < mp_irq_entries; i++) { + int lbus = mp_irqs[i].mpc_srcbus; + + if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || + mp_bus_id_to_type[lbus] == MP_BUS_EISA || + mp_bus_id_to_type[lbus] == MP_BUS_MCA || + mp_bus_id_to_type[lbus] == MP_BUS_NEC98 + ) && + (mp_irqs[i].mpc_irqtype == type) && + (mp_irqs[i].mpc_srcbusirq == irq)) + break; + } + if (i < mp_irq_entries) { + int apic; + for(apic = 0; apic < nr_ioapics; apic++) { + if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic) + return apic; + } + } + + return -1; +} + /* * Find a specific PCI IRQ entry. * Not an __init, possibly needed by modules @@ -276,10 +322,11 @@ static int pin_2_irq(int idx, int apic, int pin); /* - * This function currently is only a helper for the i386 smp boot process where - * we need to reprogram the ioredtbls to cater for the cpus which have come - * online so mask in all cases should simply be TARGET_CPUS - */ + * This function currently is only a helper for the i386 smp boot process where + * we need to reprogram the ioredtbls to cater for the cpus which have come online + * so mask in all cases should simply be TARGET_CPUS + */ +#ifdef CONFIG_SMP void __init setup_ioapic_dest(void) { int pin, ioapic, irq, irq_entry; @@ -298,6 +345,7 @@ } } +#endif /* * EISA Edge/Level control register, ELCR @@ -571,7 +619,7 @@ } /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ -u8 irq_vector[NR_IRQ_VECTORS]; +u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; int assign_irq_vector(int irq) { @@ -580,7 +628,7 @@ BUG_ON(irq >= NR_IRQ_VECTORS); if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) return IO_APIC_VECTOR(irq); - next: +next: current_vector += 8; /* Skip the hypercall vector. */ @@ -621,7 +669,7 @@ irq_desc[vector].handler = &ioapic_edge_type; } -void __init setup_IO_APIC_irqs(void) +static void __init setup_IO_APIC_irqs(void) { struct IO_APIC_route_entry entry; int apic, pin, idx, irq, first_notcon = 1, vector; @@ -689,6 +737,7 @@ spin_lock_irqsave(&ioapic_lock, flags); io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); + set_native_irq_info(entry.vector, TARGET_CPUS); spin_unlock_irqrestore(&ioapic_lock, flags); } } @@ -700,7 +749,7 @@ /* * Set up the 8259A-master output pin: */ -void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector) +static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, int vector) { struct IO_APIC_route_entry entry; unsigned long flags; @@ -734,8 +783,8 @@ * Add it to the IO-APIC irq-routing table: */ spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1)); - io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0)); + io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); + io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); spin_unlock_irqrestore(&ioapic_lock, flags); enable_8259A_irq(0); @@ -901,7 +950,8 @@ static void __init enable_IO_APIC(void) { union IO_APIC_reg_01 reg_01; - int i; + int i8259_apic, i8259_pin; + int i, apic; unsigned long flags; for (i = 0; i < PIN_MAP_SIZE; i++) { @@ -912,11 +962,52 @@ /* * The number of IO-APIC IRQ registers (== #pins): */ - for (i = 0; i < nr_ioapics; i++) { + for (apic = 0; apic < nr_ioapics; apic++) { spin_lock_irqsave(&ioapic_lock, flags); - reg_01.raw = io_apic_read(i, 1); + reg_01.raw = io_apic_read(apic, 1); spin_unlock_irqrestore(&ioapic_lock, flags); - nr_ioapic_registers[i] = reg_01.bits.entries+1; + nr_ioapic_registers[apic] = reg_01.bits.entries+1; + } + for(apic = 0; apic < nr_ioapics; apic++) { + int pin; + /* See if any of the pins is in ExtINT mode */ + for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { + struct IO_APIC_route_entry entry; + spin_lock_irqsave(&ioapic_lock, flags); + *(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); + *(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); + spin_unlock_irqrestore(&ioapic_lock, flags); + + + /* If the interrupt line is enabled and in ExtInt mode + * I have found the pin where the i8259 is connected. + */ + if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) { + ioapic_i8259.apic = apic; + ioapic_i8259.pin = pin; + goto found_i8259; + } + } + } + found_i8259: + /* Look to see what if the MP table has reported the ExtINT */ + /* If we could not find the appropriate pin by looking at the ioapic + * the i8259 probably is not connected the ioapic but give the + * mptable a chance anyway. + */ + i8259_pin = find_isa_irq_pin(0, mp_ExtINT); + i8259_apic = find_isa_irq_apic(0, mp_ExtINT); + /* Trust the MP table if nothing is setup in the hardware */ + if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) { + printk(KERN_WARNING "ExtINT not setup in hardware but reported by MP table\n"); + ioapic_i8259.pin = i8259_pin; + ioapic_i8259.apic = i8259_apic; + } + /* Complain if the MP table and the hardware disagree */ + if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) && + (i8259_pin >= 0) && (ioapic_i8259.pin >= 0)) + { + printk(KERN_WARNING "ExtINT in hardware and MP table differ\n"); } /* @@ -932,10 +1023,41 @@ { /* * Clear the IO-APIC before rebooting: - */ + */ clear_IO_APIC(); - disconnect_bsp_APIC(); + /* + * If the i8259 is routed through an IOAPIC + * Put that IOAPIC in virtual wire mode + * so legacy interrupts can be delivered. + */ + if (ioapic_i8259.pin != -1) { + struct IO_APIC_route_entry entry; + unsigned long flags; + + memset(&entry, 0, sizeof(entry)); + entry.mask = 0; /* Enabled */ + entry.trigger = 0; /* Edge */ + entry.irr = 0; + entry.polarity = 0; /* High */ + entry.delivery_status = 0; + entry.dest_mode = 0; /* Physical */ + entry.delivery_mode = dest_ExtINT; /* ExtInt */ + entry.vector = 0; + entry.dest.physical.physical_dest = + GET_APIC_ID(apic_read(APIC_ID)); + + /* + * Add it to the IO-APIC irq-routing table: + */ + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin, + *(((int *)&entry)+1)); + io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin, + *(((int *)&entry)+0)); + spin_unlock_irqrestore(&ioapic_lock, flags); + } + disconnect_bsp_APIC(ioapic_i8259.pin != -1); } /* @@ -1248,6 +1370,8 @@ unsigned int vector, cpumask_t cpu_mask) { int irq = vector_to_irq(vector); + + set_native_irq_info(vector, cpu_mask); set_ioapic_affinity_irq(irq, cpu_mask); } @@ -1292,6 +1416,7 @@ static inline void init_IO_APIC_traps(void) { int irq; + /* Xen: This is way simpler than the Linux implementation. */ for (irq = 0; irq < 16 ; irq++) if (IO_APIC_IRQ(irq) && !IO_APIC_VECTOR(irq)) make_8259A_irq(irq); @@ -1339,20 +1464,21 @@ */ static inline void unlock_ExtINT_logic(void) { - int pin, i; + int apic, pin, i; struct IO_APIC_route_entry entry0, entry1; unsigned char save_control, save_freq_select; unsigned long flags; pin = find_isa_irq_pin(8, mp_INT); + apic = find_isa_irq_apic(8, mp_INT); if (pin == -1) return; spin_lock_irqsave(&ioapic_lock, flags); - *(((int *)&entry0) + 1) = io_apic_read(0, 0x11 + 2 * pin); - *(((int *)&entry0) + 0) = io_apic_read(0, 0x10 + 2 * pin); + *(((int *)&entry0) + 1) = io_apic_read(apic, 0x11 + 2 * pin); + *(((int *)&entry0) + 0) = io_apic_read(apic, 0x10 + 2 * pin); spin_unlock_irqrestore(&ioapic_lock, flags); - clear_IO_APIC_pin(0, pin); + clear_IO_APIC_pin(apic, pin); memset(&entry1, 0, sizeof(entry1)); @@ -1365,8 +1491,8 @@ entry1.vector = 0; spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry1) + 1)); - io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry1) + 0)); + io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry1) + 1)); + io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry1) + 0)); spin_unlock_irqrestore(&ioapic_lock, flags); save_control = CMOS_READ(RTC_CONTROL); @@ -1384,11 +1510,11 @@ CMOS_WRITE(save_control, RTC_CONTROL); CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); - clear_IO_APIC_pin(0, pin); + clear_IO_APIC_pin(apic, pin); spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry0) + 1)); - io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry0) + 0)); + io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry0) + 1)); + io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry0) + 0)); spin_unlock_irqrestore(&ioapic_lock, flags); } @@ -1400,7 +1526,7 @@ */ static inline void check_timer(void) { - int pin1, pin2; + int apic1, pin1, apic2, pin2; int vector; /* @@ -1425,10 +1551,13 @@ timer_ack = 1; enable_8259A_irq(0); - pin1 = find_isa_irq_pin(0, mp_INT); - pin2 = find_isa_irq_pin(0, mp_ExtINT); - - printk(KERN_INFO "..TIMER: vector=0x%02X pin1=%d pin2=%d\n", vector, pin1, pin2); + pin1 = find_isa_irq_pin(0, mp_INT); + apic1 = find_isa_irq_apic(0, mp_INT); + pin2 = ioapic_i8259.pin; + apic2 = ioapic_i8259.apic; + + printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", + vector, apic1, pin1, apic2, pin2); if (pin1 != -1) { /* @@ -1436,10 +1565,13 @@ */ unmask_IO_APIC_irq(0); if (timer_irq_works()) { + if (disable_timer_pin_1 > 0) + clear_IO_APIC_pin(apic1, pin1); return; } - clear_IO_APIC_pin(0, pin1); - printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to IO-APIC\n"); + clear_IO_APIC_pin(apic1, pin1); + printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to " + "IO-APIC\n"); } printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... "); @@ -1448,19 +1580,19 @@ /* * legacy devices should be connected to IO APIC #0 */ - setup_ExtINT_IRQ0_pin(pin2, vector); + setup_ExtINT_IRQ0_pin(apic2, pin2, vector); if (timer_irq_works()) { printk("works.\n"); if (pin1 != -1) - replace_pin_at_irq(0, 0, pin1, 0, pin2); + replace_pin_at_irq(0, apic1, pin1, apic2, pin2); else - add_pin_to_irq(0, 0, pin2); + add_pin_to_irq(0, apic2, pin2); return; } /* * Cleanup, just in case ... */ - clear_IO_APIC_pin(0, pin2); + clear_IO_APIC_pin(apic2, pin2); } printk(" failed.\n"); @@ -1699,6 +1831,7 @@ spin_lock_irqsave(&ioapic_lock, flags); io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1)); io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0)); + set_native_irq_info(entry.vector, TARGET_CPUS); spin_unlock_irqrestore(&ioapic_lock, flags); return 0; diff -r b9b411b50587 -r 07a892f12609 xen/arch/x86/irq.c --- a/xen/arch/x86/irq.c Tue Feb 14 15:23:43 2006 +++ b/xen/arch/x86/irq.c Tue Feb 14 17:25:10 2006 @@ -31,8 +31,7 @@ static void disable_none(unsigned int vector) { } static void ack_none(unsigned int vector) { - printk("Unexpected IRQ trap at vector %02x.\n", vector); - ack_APIC_irq(); + ack_bad_irq(vector); } #define shutdown_none disable_none @@ -84,11 +83,11 @@ while ( desc->status & IRQ_PENDING ) { desc->status &= ~IRQ_PENDING; - irq_enter(smp_processor_id()); + irq_enter(); spin_unlock_irq(&desc->lock); action->handler(vector_to_irq(vector), action->dev_id, regs); spin_lock_irq(&desc->lock); - irq_exit(smp_processor_id()); + irq_exit(); } desc->status &= ~IRQ_INPROGRESS; diff -r b9b411b50587 -r 07a892f12609 xen/arch/x86/smpboot.c --- a/xen/arch/x86/smpboot.c Tue Feb 14 15:23:43 2006 +++ b/xen/arch/x86/smpboot.c Tue Feb 14 17:25:10 2006 @@ -1189,14 +1189,17 @@ set_kernel_exec((unsigned long)trampoline_base, trampoline_exec); } -#if 0 void __init smp_intr_init(void) { /* - * The reschedule interrupt is a CPU-to-CPU reschedule-helper - * IPI, driven by wakeup. - */ - set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); + * IRQ0 must be given a fixed assignment and initialized, + * because it's used before the IO-APIC is set up. + */ + irq_vector[0] = FIRST_DEVICE_VECTOR; + vector_irq[FIRST_DEVICE_VECTOR] = 0; + + /* IPI for event checking. */ + set_intr_gate(EVENT_CHECK_VECTOR, event_check_interrupt); /* IPI for invalidation */ set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt); @@ -1204,4 +1207,3 @@ /* IPI for generic function call */ set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); } -#endif diff -r b9b411b50587 -r 07a892f12609 xen/include/asm-x86/apic.h --- a/xen/include/asm-x86/apic.h Tue Feb 14 15:23:43 2006 +++ b/xen/include/asm-x86/apic.h Tue Feb 14 17:25:10 2006 @@ -87,7 +87,7 @@ extern int get_maxlvt(void); extern void clear_local_APIC(void); extern void connect_bsp_APIC (void); -extern void disconnect_bsp_APIC (void); +extern void disconnect_bsp_APIC (int virt_wire_setup); extern void disable_local_APIC (void); extern void lapic_shutdown (void); extern int verify_local_APIC (void); diff -r b9b411b50587 -r 07a892f12609 xen/include/asm-x86/apicdef.h --- a/xen/include/asm-x86/apicdef.h Tue Feb 14 15:23:43 2006 +++ b/xen/include/asm-x86/apicdef.h Tue Feb 14 17:25:10 2006 @@ -87,11 +87,12 @@ #define APIC_LVT_REMOTE_IRR (1<<14) #define APIC_INPUT_POLARITY (1<<13) #define APIC_SEND_PENDING (1<<12) +#define APIC_MODE_MASK 0x700 #define GET_APIC_DELIVERY_MODE(x) (((x)>>8)&0x7) #define SET_APIC_DELIVERY_MODE(x,y) (((x)&~0x700)|((y)<<8)) #define APIC_MODE_FIXED 0x0 #define APIC_MODE_NMI 0x4 -#define APIC_MODE_EXINT 0x7 +#define APIC_MODE_EXTINT 0x7 #define APIC_LVT1 0x360 #define APIC_LVTERR 0x370 #define APIC_TMICT 0x380 @@ -109,11 +110,10 @@ #define APIC_BASE (fix_to_virt(FIX_APIC_BASE)) -/* These limits are dictated by ES7000 hardware. */ #ifdef __i386__ - #define MAX_IO_APICS 65 + #define MAX_IO_APICS 64 #else - #define MAX_IO_APICS 129 + #define MAX_IO_APICS 128 #endif /* diff -r b9b411b50587 -r 07a892f12609 xen/include/asm-x86/hardirq.h --- a/xen/include/asm-x86/hardirq.h Tue Feb 14 15:23:43 2006 +++ b/xen/include/asm-x86/hardirq.h Tue Feb 14 17:25:10 2006 @@ -15,7 +15,12 @@ #define in_irq() (local_irq_count(smp_processor_id()) != 0) -#define irq_enter(cpu) (local_irq_count(cpu)++) -#define irq_exit(cpu) (local_irq_count(cpu)--) +#define irq_enter() (local_irq_count(smp_processor_id())++) +#define irq_exit() (local_irq_count(smp_processor_id())--) + +void ack_bad_irq(unsigned int irq); + +extern void apic_intr_init(void); +extern void smp_intr_init(void); #endif /* __ASM_HARDIRQ_H */ diff -r b9b411b50587 -r 07a892f12609 xen/include/asm-x86/irq.h --- a/xen/include/asm-x86/irq.h Tue Feb 14 15:23:43 2006 +++ b/xen/include/asm-x86/irq.h Tue Feb 14 17:25:10 2006 @@ -24,6 +24,14 @@ #define platform_legacy_irq(irq) ((irq) < 16) +fastcall void event_check_interrupt(void); +fastcall void invalidate_interrupt(void); +fastcall void call_function_interrupt(void); +fastcall void apic_timer_interrupt(void); +fastcall void error_interrupt(void); +fastcall void spurious_interrupt(void); +fastcall void thermal_interrupt(void); + void disable_8259A_irq(unsigned int irq); void enable_8259A_irq(unsigned int irq); int i8259A_irq_pending(unsigned int irq); diff -r b9b411b50587 -r 07a892f12609 xen/include/asm-x86/x86_32/asm_defns.h --- a/xen/include/asm-x86/x86_32/asm_defns.h Tue Feb 14 15:23:43 2006 +++ b/xen/include/asm-x86/x86_32/asm_defns.h Tue Feb 14 17:25:10 2006 @@ -58,6 +58,7 @@ asmlinkage void x(void); \ __asm__( \ "\n"__ALIGN_STR"\n" \ + ".globl " STR(x) "\n\t" \ STR(x) ":\n\t" \ "pushl $"#v"<<16\n\t" \ STR(SAVE_ALL(a)) \ @@ -66,8 +67,6 @@ "call "STR(smp_##x)"\n\t" \ "addl $4,%esp\n\t" \ "jmp ret_from_intr\n"); - -#define BUILD_SMP_TIMER_INTERRUPT(x,v) BUILD_SMP_INTERRUPT(x,v) #define BUILD_COMMON_IRQ() \ __asm__( \ diff -r b9b411b50587 -r 07a892f12609 xen/include/asm-x86/x86_64/asm_defns.h --- a/xen/include/asm-x86/x86_64/asm_defns.h Tue Feb 14 15:23:43 2006 +++ b/xen/include/asm-x86/x86_64/asm_defns.h Tue Feb 14 17:25:10 2006 @@ -65,6 +65,7 @@ asmlinkage void x(void); \ __asm__( \ "\n"__ALIGN_STR"\n" \ + ".globl " STR(x) "\n\t" \ STR(x) ":\n\t" \ "pushq $0\n\t" \ "movl $"#v",4(%rsp)\n\t" \ @@ -72,8 +73,6 @@ "movq %rsp,%rdi\n\t" \ "callq "STR(smp_##x)"\n\t" \ "jmp ret_from_intr\n"); - -#define BUILD_SMP_TIMER_INTERRUPT(x,v) BUILD_SMP_INTERRUPT(x,v) #define BUILD_COMMON_IRQ() \ __asm__( \ diff -r b9b411b50587 -r 07a892f12609 xen/include/xen/config.h --- a/xen/include/xen/config.h Tue Feb 14 15:23:43 2006 +++ b/xen/include/xen/config.h Tue Feb 14 17:25:10 2006 @@ -52,4 +52,7 @@ #define mk_unsigned_long(x) x #endif /* !__ASSEMBLY__ */ +#define fastcall +#define __read_mostly + #endif /* __XEN_CONFIG_H__ */ diff -r b9b411b50587 -r 07a892f12609 xen/include/xen/init.h --- a/xen/include/xen/init.h Tue Feb 14 15:23:43 2006 +++ b/xen/include/xen/init.h Tue Feb 14 17:25:10 2006 @@ -100,6 +100,4 @@ #define __devexitdata __exitdata #endif -#define fastcall - #endif /* _LINUX_INIT_H */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |