ia64/xen-unstable

changeset 8847:07a892f12609

More upgrades of Xen code to linux-2.6.16-rc2.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Feb 14 18:25:10 2006 +0100 (2006-02-14)
parents b9b411b50587
children 39b392a22002
files xen/arch/x86/acpi/boot.c xen/arch/x86/apic.c xen/arch/x86/cpu/mcheck/p4.c xen/arch/x86/i8259.c xen/arch/x86/io_apic.c xen/arch/x86/irq.c xen/arch/x86/smpboot.c xen/include/asm-x86/apic.h xen/include/asm-x86/apicdef.h xen/include/asm-x86/hardirq.h xen/include/asm-x86/irq.h xen/include/asm-x86/x86_32/asm_defns.h xen/include/asm-x86/x86_64/asm_defns.h xen/include/xen/config.h xen/include/xen/init.h
line diff
     1.1 --- a/xen/arch/x86/acpi/boot.c	Tue Feb 14 16:23:43 2006 +0100
     1.2 +++ b/xen/arch/x86/acpi/boot.c	Tue Feb 14 18:25:10 2006 +0100
     1.3 @@ -28,6 +28,7 @@
     1.4  #include <xen/init.h>
     1.5  #include <xen/acpi.h>
     1.6  #include <xen/irq.h>
     1.7 +#include <xen/dmi.h>
     1.8  #include <asm/fixmap.h>
     1.9  #include <asm/page.h>
    1.10  #include <asm/apic.h>
    1.11 @@ -75,7 +76,7 @@ static u64 acpi_lapic_addr __initdata = 
    1.12  
    1.13  #define MAX_MADT_ENTRIES	256
    1.14  u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] =
    1.15 -			{ [0 ... MAX_MADT_ENTRIES-1] = 0xff };
    1.16 +    {[0 ... MAX_MADT_ENTRIES - 1] = 0xff };
    1.17  EXPORT_SYMBOL(x86_acpiid_to_apicid);
    1.18  
    1.19  /* --------------------------------------------------------------------------
    1.20 @@ -105,7 +106,7 @@ char *__acpi_map_table(unsigned long phy
    1.21  	unsigned long base, offset, mapped_size;
    1.22  	int idx;
    1.23  
    1.24 -	if (phys + size < 8*1024*1024) 
    1.25 +	if (phys + size < 8 * 1024 * 1024) 
    1.26  		return __va(phys); 
    1.27  
    1.28  	offset = phys & (PAGE_SIZE - 1);
    1.29 @@ -128,45 +129,15 @@ char *__acpi_map_table(unsigned long phy
    1.30  	return ((char *) base + offset);
    1.31  }
    1.32  
    1.33 -#ifdef CONFIG_PCI_MMCONFIG
    1.34 -static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
    1.35 -{
    1.36 -	struct acpi_table_mcfg *mcfg;
    1.37 -
    1.38 -	if (!phys_addr || !size)
    1.39 -		return -EINVAL;
    1.40 -
    1.41 -	mcfg = (struct acpi_table_mcfg *) __acpi_map_table(phys_addr, size);
    1.42 -	if (!mcfg) {
    1.43 -		printk(KERN_WARNING PREFIX "Unable to map MCFG\n");
    1.44 -		return -ENODEV;
    1.45 -	}
    1.46 -
    1.47 -	if (mcfg->base_reserved) {
    1.48 -		printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n");
    1.49 -		return -ENODEV;
    1.50 -	}
    1.51 -
    1.52 -	pci_mmcfg_base_addr = mcfg->base_address;
    1.53 -
    1.54 -	return 0;
    1.55 -}
    1.56 -#else
    1.57 -#define	acpi_parse_mcfg NULL
    1.58 -#endif /* !CONFIG_PCI_MMCONFIG */
    1.59 -
    1.60  #ifdef CONFIG_X86_LOCAL_APIC
    1.61 -static int __init
    1.62 -acpi_parse_madt (
    1.63 -	unsigned long		phys_addr,
    1.64 -	unsigned long		size)
    1.65 +static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size)
    1.66  {
    1.67  	struct acpi_table_madt	*madt = NULL;
    1.68  
    1.69  	if (!phys_addr || !size)
    1.70  		return -EINVAL;
    1.71  
    1.72 -	madt = (struct acpi_table_madt *) __acpi_map_table(phys_addr, size);
    1.73 +	madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size);
    1.74  	if (!madt) {
    1.75  		printk(KERN_WARNING PREFIX "Unable to map MADT\n");
    1.76  		return -ENODEV;
    1.77 @@ -184,40 +155,35 @@ acpi_parse_madt (
    1.78  	return 0;
    1.79  }
    1.80  
    1.81 -
    1.82  static int __init
    1.83 -acpi_parse_lapic (
    1.84 -	acpi_table_entry_header *header, const unsigned long end)
    1.85 +acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end)
    1.86  {
    1.87  	struct acpi_table_lapic	*processor = NULL;
    1.88  
    1.89 -	processor = (struct acpi_table_lapic*) header;
    1.90 +	processor = (struct acpi_table_lapic *)header;
    1.91  
    1.92  	if (BAD_MADT_ENTRY(processor, end))
    1.93  		return -EINVAL;
    1.94  
    1.95  	acpi_table_print_madt_entry(header);
    1.96  
    1.97 -	/* no utility in registering a disabled processor */
    1.98 -	if (processor->flags.enabled == 0)
    1.99 -		return 0;
   1.100 +	/* Register even disabled CPUs for cpu hotplug */
   1.101  
   1.102  	x86_acpiid_to_apicid[processor->acpi_id] = processor->id;
   1.103  
   1.104 -	mp_register_lapic (
   1.105 -		processor->id,					   /* APIC ID */
   1.106 -		processor->flags.enabled);			  /* Enabled? */
   1.107 +	mp_register_lapic(processor->id,	/* APIC ID */
   1.108 +			  processor->flags.enabled);	/* Enabled? */
   1.109  
   1.110  	return 0;
   1.111  }
   1.112  
   1.113  static int __init
   1.114 -acpi_parse_lapic_addr_ovr (
   1.115 -	acpi_table_entry_header *header, const unsigned long end)
   1.116 +acpi_parse_lapic_addr_ovr(acpi_table_entry_header * header,
   1.117 +			  const unsigned long end)
   1.118  {
   1.119  	struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL;
   1.120  
   1.121 -	lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr*) header;
   1.122 +	lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr *)header;
   1.123  
   1.124  	if (BAD_MADT_ENTRY(lapic_addr_ovr, end))
   1.125  		return -EINVAL;
   1.126 @@ -228,12 +194,11 @@ acpi_parse_lapic_addr_ovr (
   1.127  }
   1.128  
   1.129  static int __init
   1.130 -acpi_parse_lapic_nmi (
   1.131 -	acpi_table_entry_header *header, const unsigned long end)
   1.132 +acpi_parse_lapic_nmi(acpi_table_entry_header * header, const unsigned long end)
   1.133  {
   1.134  	struct acpi_table_lapic_nmi *lapic_nmi = NULL;
   1.135  
   1.136 -	lapic_nmi = (struct acpi_table_lapic_nmi*) header;
   1.137 +	lapic_nmi = (struct acpi_table_lapic_nmi *)header;
   1.138  
   1.139  	if (BAD_MADT_ENTRY(lapic_nmi, end))
   1.140  		return -EINVAL;
   1.141 @@ -246,39 +211,35 @@ acpi_parse_lapic_nmi (
   1.142  	return 0;
   1.143  }
   1.144  
   1.145 -
   1.146 -#endif /*CONFIG_X86_LOCAL_APIC*/
   1.147 +#endif				/*CONFIG_X86_LOCAL_APIC */
   1.148  
   1.149  #if defined(CONFIG_X86_IO_APIC) /*&& defined(CONFIG_ACPI_INTERPRETER)*/
   1.150  
   1.151  static int __init
   1.152 -acpi_parse_ioapic (
   1.153 -	acpi_table_entry_header *header, const unsigned long end)
   1.154 +acpi_parse_ioapic(acpi_table_entry_header * header, const unsigned long end)
   1.155  {
   1.156  	struct acpi_table_ioapic *ioapic = NULL;
   1.157  
   1.158 -	ioapic = (struct acpi_table_ioapic*) header;
   1.159 +	ioapic = (struct acpi_table_ioapic *)header;
   1.160  
   1.161  	if (BAD_MADT_ENTRY(ioapic, end))
   1.162  		return -EINVAL;
   1.163   
   1.164  	acpi_table_print_madt_entry(header);
   1.165  
   1.166 -	mp_register_ioapic (
   1.167 -		ioapic->id,
   1.168 -		ioapic->address,
   1.169 -		ioapic->global_irq_base);
   1.170 - 
   1.171 +	mp_register_ioapic(ioapic->id,
   1.172 +			   ioapic->address, ioapic->global_irq_base);
   1.173 +
   1.174  	return 0;
   1.175  }
   1.176  
   1.177  static int __init
   1.178 -acpi_parse_int_src_ovr (
   1.179 -	acpi_table_entry_header *header, const unsigned long end)
   1.180 +acpi_parse_int_src_ovr(acpi_table_entry_header * header,
   1.181 +		       const unsigned long end)
   1.182  {
   1.183  	struct acpi_table_int_src_ovr *intsrc = NULL;
   1.184  
   1.185 -	intsrc = (struct acpi_table_int_src_ovr*) header;
   1.186 +	intsrc = (struct acpi_table_int_src_ovr *)header;
   1.187  
   1.188  	if (BAD_MADT_ENTRY(intsrc, end))
   1.189  		return -EINVAL;
   1.190 @@ -291,23 +252,19 @@ acpi_parse_int_src_ovr (
   1.191  			return 0;
   1.192  	}
   1.193  
   1.194 -	mp_override_legacy_irq (
   1.195 -		intsrc->bus_irq,
   1.196 -		intsrc->flags.polarity,
   1.197 -		intsrc->flags.trigger,
   1.198 -		intsrc->global_irq);
   1.199 +	mp_override_legacy_irq(intsrc->bus_irq,
   1.200 +			       intsrc->flags.polarity,
   1.201 +			       intsrc->flags.trigger, intsrc->global_irq);
   1.202  
   1.203  	return 0;
   1.204  }
   1.205  
   1.206 -
   1.207  static int __init
   1.208 -acpi_parse_nmi_src (
   1.209 -	acpi_table_entry_header *header, const unsigned long end)
   1.210 +acpi_parse_nmi_src(acpi_table_entry_header * header, const unsigned long end)
   1.211  {
   1.212  	struct acpi_table_nmi_src *nmi_src = NULL;
   1.213  
   1.214 -	nmi_src = (struct acpi_table_nmi_src*) header;
   1.215 +	nmi_src = (struct acpi_table_nmi_src *)header;
   1.216  
   1.217  	if (BAD_MADT_ENTRY(nmi_src, end))
   1.218  		return -EINVAL;
   1.219 @@ -322,9 +279,7 @@ acpi_parse_nmi_src (
   1.220  #endif /* CONFIG_X86_IO_APIC */
   1.221  
   1.222  static unsigned long __init
   1.223 -acpi_scan_rsdp (
   1.224 -	unsigned long		start,
   1.225 -	unsigned long		length)
   1.226 +acpi_scan_rsdp(unsigned long start, unsigned long length)
   1.227  {
   1.228  	unsigned long		offset = 0;
   1.229  	unsigned long		sig_len = sizeof("RSD PTR ") - 1;
   1.230 @@ -334,7 +289,7 @@ acpi_scan_rsdp (
   1.231  	 * RSDP signature.
   1.232  	 */
   1.233  	for (offset = 0; offset < length; offset += 16) {
   1.234 -		if (strncmp((char *) (start + offset), "RSD PTR ", sig_len))
   1.235 +		if (strncmp((char *)(start + offset), "RSD PTR ", sig_len))
   1.236  			continue;
   1.237  		return (start + offset);
   1.238  	}
   1.239 @@ -349,7 +304,7 @@ static int __init acpi_parse_sbf(unsigne
   1.240  	if (!phys_addr || !size)
   1.241  	return -EINVAL;
   1.242  
   1.243 -	sb = (struct acpi_table_sbf *) __acpi_map_table(phys_addr, size);
   1.244 +	sb = (struct acpi_table_sbf *)__acpi_map_table(phys_addr, size);
   1.245  	if (!sb) {
   1.246  		printk(KERN_WARNING PREFIX "Unable to map SBF\n");
   1.247  		return -ENODEV;
   1.248 @@ -370,7 +325,7 @@ static int __init acpi_parse_hpet(unsign
   1.249  	if (!phys || !size)
   1.250  		return -EINVAL;
   1.251  
   1.252 -	hpet_tbl = (struct acpi_table_hpet *) __acpi_map_table(phys, size);
   1.253 +	hpet_tbl = (struct acpi_table_hpet *)__acpi_map_table(phys, size);
   1.254  	if (!hpet_tbl) {
   1.255  		printk(KERN_WARNING PREFIX "Unable to map HPET\n");
   1.256  		return -ENODEV;
   1.257 @@ -412,8 +367,8 @@ static int __init acpi_parse_fadt(unsign
   1.258  {
   1.259  	struct fadt_descriptor_rev2 *fadt = NULL;
   1.260  
   1.261 -	fadt = (struct fadt_descriptor_rev2*) __acpi_map_table(phys,size);
   1.262 -	if(!fadt) {
   1.263 +	fadt = (struct fadt_descriptor_rev2 *)__acpi_map_table(phys, size);
   1.264 +	if (!fadt) {
   1.265  		printk(KERN_WARNING PREFIX "Unable to map FADT\n");
   1.266  		return 0;
   1.267  	}
   1.268 @@ -421,29 +376,42 @@ static int __init acpi_parse_fadt(unsign
   1.269  #ifdef	CONFIG_ACPI_INTERPRETER
   1.270  	/* initialize sci_int early for INT_SRC_OVR MADT parsing */
   1.271  	acpi_fadt.sci_int = fadt->sci_int;
   1.272 +
   1.273 +	/* initialize rev and apic_phys_dest_mode for x86_64 genapic */
   1.274 +	acpi_fadt.revision = fadt->revision;
   1.275 +	acpi_fadt.force_apic_physical_destination_mode =
   1.276 +	    fadt->force_apic_physical_destination_mode;
   1.277  #endif
   1.278  
   1.279  #ifdef CONFIG_X86_PM_TIMER
   1.280  	/* detect the location of the ACPI PM Timer */
   1.281  	if (fadt->revision >= FADT2_REVISION_ID) {
   1.282  		/* FADT rev. 2 */
   1.283 -		if (fadt->xpm_tmr_blk.address_space_id != ACPI_ADR_SPACE_SYSTEM_IO)
   1.284 +		if (fadt->xpm_tmr_blk.address_space_id !=
   1.285 +		    ACPI_ADR_SPACE_SYSTEM_IO)
   1.286  			return 0;
   1.287  
   1.288  		pmtmr_ioport = fadt->xpm_tmr_blk.address;
   1.289 +		/*
   1.290 +		 * "X" fields are optional extensions to the original V1.0
   1.291 +		 * fields, so we must selectively expand V1.0 fields if the
   1.292 +		 * corresponding X field is zero.
   1.293 +	 	 */
   1.294 +		if (!pmtmr_ioport)
   1.295 +			pmtmr_ioport = fadt->V1_pm_tmr_blk;
   1.296  	} else {
   1.297  		/* FADT rev. 1 */
   1.298  		pmtmr_ioport = fadt->V1_pm_tmr_blk;
   1.299  	}
   1.300  	if (pmtmr_ioport)
   1.301 -		printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", pmtmr_ioport);
   1.302 +		printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n",
   1.303 +		       pmtmr_ioport);
   1.304  #endif
   1.305  	return 0;
   1.306  }
   1.307  
   1.308  
   1.309 -unsigned long __init
   1.310 -acpi_find_rsdp (void)
   1.311 +unsigned long __init acpi_find_rsdp(void)
   1.312  {
   1.313  	unsigned long		rsdp_phys = 0;
   1.314  
   1.315 @@ -459,9 +427,9 @@ acpi_find_rsdp (void)
   1.316  	 * Scan memory looking for the RSDP signature. First search EBDA (low
   1.317  	 * memory) paragraphs and then search upper memory (E0000-FFFFF).
   1.318  	 */
   1.319 -	rsdp_phys = acpi_scan_rsdp (0, 0x400);
   1.320 +	rsdp_phys = acpi_scan_rsdp(0, 0x400);
   1.321  	if (!rsdp_phys)
   1.322 -		rsdp_phys = acpi_scan_rsdp (0xE0000, 0x20000);
   1.323 +		rsdp_phys = acpi_scan_rsdp(0xE0000, 0x20000);
   1.324  
   1.325  	return rsdp_phys;
   1.326  }
   1.327 @@ -471,8 +439,7 @@ acpi_find_rsdp (void)
   1.328   * Parse LAPIC entries in MADT
   1.329   * returns 0 on success, < 0 on error
   1.330   */
   1.331 -static int __init
   1.332 -acpi_parse_madt_lapic_entries(void)
   1.333 +static int __init acpi_parse_madt_lapic_entries(void)
   1.334  {
   1.335  	int count;
   1.336  
   1.337 @@ -481,9 +448,12 @@ acpi_parse_madt_lapic_entries(void)
   1.338  	 * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
   1.339  	 */
   1.340  
   1.341 -	count = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0);
   1.342 +	count =
   1.343 +	    acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR,
   1.344 +				  acpi_parse_lapic_addr_ovr, 0);
   1.345  	if (count < 0) {
   1.346 -		printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
   1.347 +		printk(KERN_ERR PREFIX
   1.348 +		       "Error parsing LAPIC address override entry\n");
   1.349  		return count;
   1.350  	}
   1.351  
   1.352 @@ -495,14 +465,14 @@ acpi_parse_madt_lapic_entries(void)
   1.353  		printk(KERN_ERR PREFIX "No LAPIC entries present\n");
   1.354  		/* TBD: Cleanup to allow fallback to MPS */
   1.355  		return -ENODEV;
   1.356 -	}
   1.357 -	else if (count < 0) {
   1.358 +	} else if (count < 0) {
   1.359  		printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n");
   1.360  		/* TBD: Cleanup to allow fallback to MPS */
   1.361  		return count;
   1.362  	}
   1.363  
   1.364 -	count = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0);
   1.365 +	count =
   1.366 +	    acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0);
   1.367  	if (count < 0) {
   1.368  		printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
   1.369  		/* TBD: Cleanup to allow fallback to MPS */
   1.370 @@ -517,8 +487,7 @@ acpi_parse_madt_lapic_entries(void)
   1.371   * Parse IOAPIC related entries in MADT
   1.372   * returns 0 on success, < 0 on error
   1.373   */
   1.374 -static int __init
   1.375 -acpi_parse_madt_ioapic_entries(void)
   1.376 +static int __init acpi_parse_madt_ioapic_entries(void)
   1.377  {
   1.378  	int count;
   1.379  
   1.380 @@ -541,19 +510,23 @@ acpi_parse_madt_ioapic_entries(void)
   1.381  		return -ENODEV;
   1.382  	}
   1.383  
   1.384 -	count = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, MAX_IO_APICS);
   1.385 +	count =
   1.386 +	    acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic,
   1.387 +				  MAX_IO_APICS);
   1.388  	if (!count) {
   1.389  		printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
   1.390  		return -ENODEV;
   1.391 -	}
   1.392 -	else if (count < 0) {
   1.393 +	} else if (count < 0) {
   1.394  		printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n");
   1.395  		return count;
   1.396  	}
   1.397  
   1.398 -	count = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS);
   1.399 +	count =
   1.400 +	    acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr,
   1.401 +				  NR_IRQ_VECTORS);
   1.402  	if (count < 0) {
   1.403 -		printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
   1.404 +		printk(KERN_ERR PREFIX
   1.405 +		       "Error parsing interrupt source overrides entry\n");
   1.406  		/* TBD: Cleanup to allow fallback to MPS */
   1.407  		return count;
   1.408  	}
   1.409 @@ -570,7 +543,9 @@ acpi_parse_madt_ioapic_entries(void)
   1.410  	/* Fill in identity legacy mapings where no override */
   1.411  	mp_config_acpi_legacy_irqs();
   1.412  
   1.413 -	count = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, NR_IRQ_VECTORS);
   1.414 +	count =
   1.415 +	    acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src,
   1.416 +				  NR_IRQ_VECTORS);
   1.417  	if (count < 0) {
   1.418  		printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
   1.419  		/* TBD: Cleanup to allow fallback to MPS */
   1.420 @@ -587,8 +562,7 @@ static inline int acpi_parse_madt_ioapic
   1.421  #endif /* !(CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER) */
   1.422  
   1.423  
   1.424 -static void __init
   1.425 -acpi_process_madt(void)
   1.426 +static void __init acpi_process_madt(void)
   1.427  {
   1.428  #ifdef CONFIG_X86_LOCAL_APIC
   1.429  	int count, error;
   1.430 @@ -621,7 +595,8 @@ acpi_process_madt(void)
   1.431  			/*
   1.432  			 * Dell Precision Workstation 410, 610 come here.
   1.433  			 */
   1.434 -			printk(KERN_ERR PREFIX "Invalid BIOS MADT, disabling ACPI\n");
   1.435 +			printk(KERN_ERR PREFIX
   1.436 +			       "Invalid BIOS MADT, disabling ACPI\n");
   1.437  			disable_acpi();
   1.438  		}
   1.439  	}
   1.440 @@ -629,6 +604,218 @@ acpi_process_madt(void)
   1.441  	return;
   1.442  }
   1.443  
   1.444 +extern int acpi_force;
   1.445 +
   1.446 +#ifdef __i386__
   1.447 +
   1.448 +static int __init disable_acpi_irq(struct dmi_system_id *d)
   1.449 +{
   1.450 +	if (!acpi_force) {
   1.451 +		printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n",
   1.452 +		       d->ident);
   1.453 +		acpi_noirq_set();
   1.454 +	}
   1.455 +	return 0;
   1.456 +}
   1.457 +
   1.458 +static int __init disable_acpi_pci(struct dmi_system_id *d)
   1.459 +{
   1.460 +	if (!acpi_force) {
   1.461 +		printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n",
   1.462 +		       d->ident);
   1.463 +		/*acpi_disable_pci();*/
   1.464 +	}
   1.465 +	return 0;
   1.466 +}
   1.467 +
   1.468 +static int __init dmi_disable_acpi(struct dmi_system_id *d)
   1.469 +{
   1.470 +	if (!acpi_force) {
   1.471 +		printk(KERN_NOTICE "%s detected: acpi off\n", d->ident);
   1.472 +		disable_acpi();
   1.473 +	} else {
   1.474 +		printk(KERN_NOTICE
   1.475 +		       "Warning: DMI blacklist says broken, but acpi forced\n");
   1.476 +	}
   1.477 +	return 0;
   1.478 +}
   1.479 +
   1.480 +/*
   1.481 + * Limit ACPI to CPU enumeration for HT
   1.482 + */
   1.483 +static int __init force_acpi_ht(struct dmi_system_id *d)
   1.484 +{
   1.485 +	if (!acpi_force) {
   1.486 +		printk(KERN_NOTICE "%s detected: force use of acpi=ht\n",
   1.487 +		       d->ident);
   1.488 +		disable_acpi();
   1.489 +		acpi_ht = 1;
   1.490 +	} else {
   1.491 +		printk(KERN_NOTICE
   1.492 +		       "Warning: acpi=force overrules DMI blacklist: acpi=ht\n");
   1.493 +	}
   1.494 +	return 0;
   1.495 +}
   1.496 +
   1.497 +/*
   1.498 + * If your system is blacklisted here, but you find that acpi=force
   1.499 + * works for you, please contact acpi-devel@sourceforge.net
   1.500 + */
   1.501 +static struct dmi_system_id __initdata acpi_dmi_table[] = {
   1.502 +	/*
   1.503 +	 * Boxes that need ACPI disabled
   1.504 +	 */
   1.505 +	{
   1.506 +	 .callback = dmi_disable_acpi,
   1.507 +	 .ident = "IBM Thinkpad",
   1.508 +	 .matches = {
   1.509 +		     DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
   1.510 +		     DMI_MATCH(DMI_BOARD_NAME, "2629H1G"),
   1.511 +		     },
   1.512 +	 },
   1.513 +
   1.514 +	/*
   1.515 +	 * Boxes that need acpi=ht
   1.516 +	 */
   1.517 +	{
   1.518 +	 .callback = force_acpi_ht,
   1.519 +	 .ident = "FSC Primergy T850",
   1.520 +	 .matches = {
   1.521 +		     DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
   1.522 +		     DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
   1.523 +		     },
   1.524 +	 },
   1.525 +	{
   1.526 +	 .callback = force_acpi_ht,
   1.527 +	 .ident = "DELL GX240",
   1.528 +	 .matches = {
   1.529 +		     DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
   1.530 +		     DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
   1.531 +		     },
   1.532 +	 },
   1.533 +	{
   1.534 +	 .callback = force_acpi_ht,
   1.535 +	 .ident = "HP VISUALIZE NT Workstation",
   1.536 +	 .matches = {
   1.537 +		     DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
   1.538 +		     DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
   1.539 +		     },
   1.540 +	 },
   1.541 +	{
   1.542 +	 .callback = force_acpi_ht,
   1.543 +	 .ident = "Compaq Workstation W8000",
   1.544 +	 .matches = {
   1.545 +		     DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
   1.546 +		     DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
   1.547 +		     },
   1.548 +	 },
   1.549 +	{
   1.550 +	 .callback = force_acpi_ht,
   1.551 +	 .ident = "ASUS P4B266",
   1.552 +	 .matches = {
   1.553 +		     DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
   1.554 +		     DMI_MATCH(DMI_BOARD_NAME, "P4B266"),
   1.555 +		     },
   1.556 +	 },
   1.557 +	{
   1.558 +	 .callback = force_acpi_ht,
   1.559 +	 .ident = "ASUS P2B-DS",
   1.560 +	 .matches = {
   1.561 +		     DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
   1.562 +		     DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"),
   1.563 +		     },
   1.564 +	 },
   1.565 +	{
   1.566 +	 .callback = force_acpi_ht,
   1.567 +	 .ident = "ASUS CUR-DLS",
   1.568 +	 .matches = {
   1.569 +		     DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
   1.570 +		     DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"),
   1.571 +		     },
   1.572 +	 },
   1.573 +	{
   1.574 +	 .callback = force_acpi_ht,
   1.575 +	 .ident = "ABIT i440BX-W83977",
   1.576 +	 .matches = {
   1.577 +		     DMI_MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
   1.578 +		     DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
   1.579 +		     },
   1.580 +	 },
   1.581 +	{
   1.582 +	 .callback = force_acpi_ht,
   1.583 +	 .ident = "IBM Bladecenter",
   1.584 +	 .matches = {
   1.585 +		     DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
   1.586 +		     DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
   1.587 +		     },
   1.588 +	 },
   1.589 +	{
   1.590 +	 .callback = force_acpi_ht,
   1.591 +	 .ident = "IBM eServer xSeries 360",
   1.592 +	 .matches = {
   1.593 +		     DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
   1.594 +		     DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
   1.595 +		     },
   1.596 +	 },
   1.597 +	{
   1.598 +	 .callback = force_acpi_ht,
   1.599 +	 .ident = "IBM eserver xSeries 330",
   1.600 +	 .matches = {
   1.601 +		     DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
   1.602 +		     DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
   1.603 +		     },
   1.604 +	 },
   1.605 +	{
   1.606 +	 .callback = force_acpi_ht,
   1.607 +	 .ident = "IBM eserver xSeries 440",
   1.608 +	 .matches = {
   1.609 +		     DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
   1.610 +		     DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
   1.611 +		     },
   1.612 +	 },
   1.613 +
   1.614 +	/*
   1.615 +	 * Boxes that need ACPI PCI IRQ routing disabled
   1.616 +	 */
   1.617 +	{
   1.618 +	 .callback = disable_acpi_irq,
   1.619 +	 .ident = "ASUS A7V",
   1.620 +	 .matches = {
   1.621 +		     DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
   1.622 +		     DMI_MATCH(DMI_BOARD_NAME, "<A7V>"),
   1.623 +		     /* newer BIOS, Revision 1011, does work */
   1.624 +		     DMI_MATCH(DMI_BIOS_VERSION,
   1.625 +			       "ASUS A7V ACPI BIOS Revision 1007"),
   1.626 +		     },
   1.627 +	 },
   1.628 +
   1.629 +	/*
   1.630 +	 * Boxes that need ACPI PCI IRQ routing and PCI scan disabled
   1.631 +	 */
   1.632 +	{			/* _BBN 0 bug */
   1.633 +	 .callback = disable_acpi_pci,
   1.634 +	 .ident = "ASUS PR-DLS",
   1.635 +	 .matches = {
   1.636 +		     DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
   1.637 +		     DMI_MATCH(DMI_BOARD_NAME, "PR-DLS"),
   1.638 +		     DMI_MATCH(DMI_BIOS_VERSION,
   1.639 +			       "ASUS PR-DLS ACPI BIOS Revision 1010"),
   1.640 +		     DMI_MATCH(DMI_BIOS_DATE, "03/21/2003")
   1.641 +		     },
   1.642 +	 },
   1.643 +	{
   1.644 +	 .callback = disable_acpi_pci,
   1.645 +	 .ident = "Acer TravelMate 36x Laptop",
   1.646 +	 .matches = {
   1.647 +		     DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
   1.648 +		     DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
   1.649 +		     },
   1.650 +	 },
   1.651 +	{}
   1.652 +};
   1.653 +
   1.654 +#endif				/* __i386__ */
   1.655 +
   1.656  /*
   1.657   * acpi_boot_table_init() and acpi_boot_init()
   1.658   *  called from setup_arch(), always.
   1.659 @@ -652,11 +839,14 @@ acpi_process_madt(void)
   1.660   *	!0: failure
   1.661   */
   1.662  
   1.663 -int __init
   1.664 -acpi_boot_table_init(void)
   1.665 +int __init acpi_boot_table_init(void)
   1.666  {
   1.667  	int error;
   1.668  
   1.669 +#ifdef __i386__
   1.670 +	dmi_check_system(acpi_dmi_table);
   1.671 +#endif
   1.672 +
   1.673  	/*
   1.674  	 * If acpi_disabled, bail out
   1.675  	 * One exception: acpi=ht continues far enough to enumerate LAPICs
   1.676 @@ -717,7 +907,6 @@ int __init acpi_boot_init(void)
   1.677  	acpi_process_madt();
   1.678  
   1.679  	acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
   1.680 -	acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
   1.681  
   1.682  	return 0;
   1.683  }
     2.1 --- a/xen/arch/x86/apic.c	Tue Feb 14 16:23:43 2006 +0100
     2.2 +++ b/xen/arch/x86/apic.c	Tue Feb 14 18:25:10 2006 +0100
     2.3 @@ -38,10 +38,54 @@
     2.4  #include <io_ports.h>
     2.5  
     2.6  /*
     2.7 + * Knob to control our willingness to enable the local APIC.
     2.8 + */
     2.9 +int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
    2.10 +
    2.11 +/*
    2.12   * Debug level
    2.13   */
    2.14  int apic_verbosity;
    2.15  
    2.16 +
    2.17 +static void apic_pm_activate(void);
    2.18 +
    2.19 +/*
    2.20 + * 'what should we do if we get a hw irq event on an illegal vector'.
    2.21 + * each architecture has to answer this themselves.
    2.22 + */
    2.23 +void ack_bad_irq(unsigned int irq)
    2.24 +{
    2.25 +    printk("unexpected IRQ trap at vector %02x\n", irq);
    2.26 +    /*
    2.27 +     * Currently unexpected vectors happen only on SMP and APIC.
    2.28 +     * We _must_ ack these because every local APIC has only N
    2.29 +     * irq slots per priority level, and a 'hanging, unacked' IRQ
    2.30 +     * holds up an irq slot - in excessive cases (when multiple
    2.31 +     * unexpected vectors occur) that might lock up the APIC
    2.32 +     * completely.
    2.33 +     */
    2.34 +    ack_APIC_irq();
    2.35 +}
    2.36 +
    2.37 +void __init apic_intr_init(void)
    2.38 +{
    2.39 +#ifdef CONFIG_SMP
    2.40 +    smp_intr_init();
    2.41 +#endif
    2.42 +    /* self generated IPI for local APIC timer */
    2.43 +    set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
    2.44 +
    2.45 +    /* IPI vectors for APIC spurious and error interrupts */
    2.46 +    set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
    2.47 +    set_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
    2.48 +
    2.49 +    /* thermal monitor LVT interrupt */
    2.50 +#ifdef CONFIG_X86_MCE_P4THERMAL
    2.51 +    set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
    2.52 +#endif
    2.53 +}
    2.54 +
    2.55  /* Using APIC to generate smp_local_timer_interrupt? */
    2.56  int using_apic_timer = 0;
    2.57  
    2.58 @@ -148,7 +192,7 @@ void __init connect_bsp_APIC(void)
    2.59      enable_apic_mode();
    2.60  }
    2.61  
    2.62 -void disconnect_bsp_APIC(void)
    2.63 +void disconnect_bsp_APIC(int virt_wire_setup)
    2.64  {
    2.65      if (pic_mode) {
    2.66          /*
    2.67 @@ -162,6 +206,42 @@ void disconnect_bsp_APIC(void)
    2.68          outb(0x70, 0x22);
    2.69          outb(0x00, 0x23);
    2.70      }
    2.71 +    else {
    2.72 +        /* Go back to Virtual Wire compatibility mode */
    2.73 +        unsigned long value;
    2.74 +
    2.75 +        /* For the spurious interrupt use vector F, and enable it */
    2.76 +        value = apic_read(APIC_SPIV);
    2.77 +        value &= ~APIC_VECTOR_MASK;
    2.78 +        value |= APIC_SPIV_APIC_ENABLED;
    2.79 +        value |= 0xf;
    2.80 +        apic_write_around(APIC_SPIV, value);
    2.81 +
    2.82 +        if (!virt_wire_setup) {
    2.83 +            /* For LVT0 make it edge triggered, active high, external and enabled */
    2.84 +            value = apic_read(APIC_LVT0);
    2.85 +            value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
    2.86 +                       APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
    2.87 +                       APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED );
    2.88 +            value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
    2.89 +            value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
    2.90 +            apic_write_around(APIC_LVT0, value);
    2.91 +        }
    2.92 +        else {
    2.93 +            /* Disable LVT0 */
    2.94 +            apic_write_around(APIC_LVT0, APIC_LVT_MASKED);
    2.95 +        }
    2.96 +
    2.97 +        /* For LVT1 make it edge triggered, active high, nmi and enabled */
    2.98 +        value = apic_read(APIC_LVT1);
    2.99 +        value &= ~(
   2.100 +            APIC_MODE_MASK | APIC_SEND_PENDING |
   2.101 +            APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
   2.102 +            APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
   2.103 +        value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
   2.104 +        value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
   2.105 +        apic_write_around(APIC_LVT1, value);
   2.106 +    }
   2.107  }
   2.108  
   2.109  void disable_local_APIC(void)
   2.110 @@ -306,7 +386,7 @@ void __init init_bsp_APIC(void)
   2.111      apic_write_around(APIC_LVT1, value);
   2.112  }
   2.113  
   2.114 -void __init setup_local_APIC (void)
   2.115 +void __devinit setup_local_APIC(void)
   2.116  {
   2.117      unsigned long oldvalue, value, ver, maxlvt;
   2.118  
   2.119 @@ -453,18 +533,16 @@ void __init setup_local_APIC (void)
   2.120  
   2.121      if (nmi_watchdog == NMI_LOCAL_APIC)
   2.122          setup_apic_nmi_watchdog();
   2.123 +    apic_pm_activate();
   2.124  }
   2.125  
   2.126 +static void apic_pm_activate(void) { }
   2.127 +
   2.128  /*
   2.129   * Detect and enable local APICs on non-SMP boards.
   2.130   * Original code written by Keir Fraser.
   2.131   */
   2.132  
   2.133 -/*
   2.134 - * Knob to control our willingness to enable the local APIC.
   2.135 - */
   2.136 -int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
   2.137 -
   2.138  static void __init lapic_disable(char *str)
   2.139  {
   2.140      enable_local_apic = -1;
   2.141 @@ -498,9 +576,6 @@ static int __init detect_init_APIC (void
   2.142      if (enable_local_apic < 0)
   2.143          return -1;
   2.144  
   2.145 -    /* Workaround for us being called before identify_cpu(). */
   2.146 -    /*get_cpu_vendor(&boot_cpu_data); Not for Xen */
   2.147 -
   2.148      switch (boot_cpu_data.x86_vendor) {
   2.149      case X86_VENDOR_AMD:
   2.150          if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) ||
   2.151 @@ -564,6 +639,8 @@ static int __init detect_init_APIC (void
   2.152  
   2.153      printk("Found and enabled local APIC!\n");
   2.154  
   2.155 +    apic_pm_activate();
   2.156 +
   2.157      return 0;
   2.158  
   2.159  no_apic:
   2.160 @@ -824,26 +901,27 @@ static unsigned int calibration_result;
   2.161  
   2.162  void __init setup_boot_APIC_clock(void)
   2.163  {
   2.164 +    unsigned long flags;
   2.165      apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n");
   2.166      using_apic_timer = 1;
   2.167  
   2.168 -    local_irq_disable();
   2.169 -    
   2.170 +    local_irq_save(flags);
   2.171 +
   2.172      calibration_result = calibrate_APIC_clock();
   2.173      /*
   2.174       * Now set up the timer for real.
   2.175       */
   2.176      setup_APIC_timer(calibration_result);
   2.177      
   2.178 -    local_irq_enable();
   2.179 +    local_irq_restore(flags);
   2.180  }
   2.181  
   2.182 -void __init setup_secondary_APIC_clock(void)
   2.183 +void __devinit setup_secondary_APIC_clock(void)
   2.184  {
   2.185      setup_APIC_timer(calibration_result);
   2.186  }
   2.187  
   2.188 -void __init disable_APIC_timer(void)
   2.189 +void disable_APIC_timer(void)
   2.190  {
   2.191      if (using_apic_timer) {
   2.192          unsigned long v;
   2.193 @@ -941,6 +1019,7 @@ fastcall void smp_spurious_interrupt(str
   2.194  {
   2.195      unsigned long v;
   2.196  
   2.197 +    irq_enter();
   2.198      /*
   2.199       * Check if this really is a spurious interrupt and ACK it
   2.200       * if it is a vectored one.  Just in case...
   2.201 @@ -953,6 +1032,7 @@ fastcall void smp_spurious_interrupt(str
   2.202      /* see sw-dev-man vol 3, chapter 7.4.13.5 */
   2.203      printk(KERN_INFO "spurious APIC interrupt on CPU#%d, should never happen.\n",
   2.204             smp_processor_id());
   2.205 +    irq_exit();
   2.206  }
   2.207  
   2.208  /*
   2.209 @@ -963,6 +1043,7 @@ fastcall void smp_error_interrupt(struct
   2.210  {
   2.211      unsigned long v, v1;
   2.212  
   2.213 +    irq_enter();
   2.214      /* First tickle the hardware, only then report what went on. -- REW */
   2.215      v = apic_read(APIC_ESR);
   2.216      apic_write(APIC_ESR, 0);
   2.217 @@ -982,6 +1063,7 @@ fastcall void smp_error_interrupt(struct
   2.218      */
   2.219      printk (KERN_DEBUG "APIC error on CPU%d: %02lx(%02lx)\n",
   2.220              smp_processor_id(), v , v1);
   2.221 +    irq_exit();
   2.222  }
   2.223  
   2.224  /*
     3.1 --- a/xen/arch/x86/cpu/mcheck/p4.c	Tue Feb 14 16:23:43 2006 +0100
     3.2 +++ b/xen/arch/x86/cpu/mcheck/p4.c	Tue Feb 14 18:25:10 2006 +0100
     3.3 @@ -71,9 +71,9 @@ static void (*vendor_thermal_interrupt)(
     3.4  
     3.5  fastcall void smp_thermal_interrupt(struct cpu_user_regs *regs)
     3.6  {
     3.7 -	irq_enter(smp_processor_id());
     3.8 +	irq_enter();
     3.9  	vendor_thermal_interrupt(regs);
    3.10 -	irq_exit(smp_processor_id());
    3.11 +	irq_exit();
    3.12  }
    3.13  
    3.14  /* P4/Xeon Thermal regulation detect and init */
     4.1 --- a/xen/arch/x86/i8259.c	Tue Feb 14 16:23:43 2006 +0100
     4.2 +++ b/xen/arch/x86/i8259.c	Tue Feb 14 18:25:10 2006 +0100
     4.3 @@ -374,25 +374,7 @@ void __init init_IRQ(void)
     4.4          irq_desc[LEGACY_VECTOR(i)].handler = &i8259A_irq_type;
     4.5      }
     4.6  
     4.7 -    /*
     4.8 -     * IRQ0 must be given a fixed assignment and initialized,
     4.9 -     * because it's used before the IO-APIC is set up.
    4.10 -     */
    4.11 -    irq_vector[0] = FIRST_DEVICE_VECTOR;
    4.12 -    vector_irq[FIRST_DEVICE_VECTOR] = 0;
    4.13 -
    4.14 -    /* Various IPI functions. */
    4.15 -    set_intr_gate(EVENT_CHECK_VECTOR, event_check_interrupt);
    4.16 -    set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);
    4.17 -    set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
    4.18 -
    4.19 -    /* Self-generated IPI for local APIC timer. */
    4.20 -    set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
    4.21 -
    4.22 -    /* IPI vectors for APIC spurious and error interrupts. */
    4.23 -    set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
    4.24 -    set_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
    4.25 -    set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
    4.26 +    apic_intr_init();
    4.27  
    4.28      /* Set the clock to HZ Hz */
    4.29  #define CLOCK_TICK_RATE 1193180 /* crystal freq (Hz) */
     5.1 --- a/xen/arch/x86/io_apic.c	Tue Feb 14 16:23:43 2006 +0100
     5.2 +++ b/xen/arch/x86/io_apic.c	Tue Feb 14 18:25:10 2006 +0100
     5.3 @@ -35,11 +35,18 @@
     5.4  #include <mach_apic.h>
     5.5  #include <io_ports.h>
     5.6  
     5.7 +#define set_irq_info(irq, mask) ((void)0)
     5.8 +#define set_native_irq_info(irq, mask) ((void)0)
     5.9 +
    5.10 +/* Different to Linux: our implementation can be simpler. */
    5.11  #define make_8259A_irq(irq) (io_apic_irqs &= ~(1<<(irq)))
    5.12  
    5.13  int (*ioapic_renumber_irq)(int ioapic, int irq);
    5.14  atomic_t irq_mis_count;
    5.15  
    5.16 +/* Where if anywhere is the i8259 connect in external int mode */
    5.17 +static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
    5.18 +
    5.19  static DEFINE_SPINLOCK(ioapic_lock);
    5.20  
    5.21  int skip_ioapic_setup;
    5.22 @@ -49,6 +56,8 @@ int skip_ioapic_setup;
    5.23   */
    5.24  int nr_ioapic_registers[MAX_IO_APICS];
    5.25  
    5.26 +int disable_timer_pin_1 __initdata;
    5.27 +
    5.28  /*
    5.29   * Rough estimation of how many shared IRQs there are, can
    5.30   * be changed anytime.
    5.31 @@ -67,7 +76,7 @@ static struct irq_pin_list {
    5.32      int apic, pin, next;
    5.33  } irq_2_pin[PIN_MAP_SIZE];
    5.34  
    5.35 -int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
    5.36 +int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
    5.37  
    5.38  /*
    5.39   * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
    5.40 @@ -173,7 +182,7 @@ static void unmask_IO_APIC_irq (unsigned
    5.41      spin_unlock_irqrestore(&ioapic_lock, flags);
    5.42  }
    5.43  
    5.44 -void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
    5.45 +static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
    5.46  {
    5.47      struct IO_APIC_route_entry entry;
    5.48      unsigned long flags;
    5.49 @@ -206,13 +215,21 @@ static void clear_IO_APIC (void)
    5.50              clear_IO_APIC_pin(apic, pin);
    5.51  }
    5.52  
    5.53 +#ifdef CONFIG_SMP
    5.54  static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask)
    5.55  {
    5.56      unsigned long flags;
    5.57      int pin;
    5.58      struct irq_pin_list *entry = irq_2_pin + irq;
    5.59      unsigned int apicid_value;
    5.60 +    cpumask_t tmp;
    5.61  	
    5.62 +    cpus_and(tmp, cpumask, cpu_online_map);
    5.63 +    if (cpus_empty(tmp))
    5.64 +        tmp = TARGET_CPUS;
    5.65 +
    5.66 +    cpus_and(cpumask, tmp, CPU_MASK_ALL);
    5.67 +
    5.68      apicid_value = cpu_mask_to_apicid(cpumask);
    5.69      /* Prepare to do the io_apic_write */
    5.70      apicid_value = apicid_value << 24;
    5.71 @@ -226,8 +243,10 @@ static void set_ioapic_affinity_irq(unsi
    5.72              break;
    5.73          entry = irq_2_pin + entry->next;
    5.74      }
    5.75 +    set_irq_info(irq, cpumask);
    5.76      spin_unlock_irqrestore(&ioapic_lock, flags);
    5.77  }
    5.78 +#endif /* CONFIG_SMP */
    5.79  
    5.80  /*
    5.81   * Find the IRQ entry number of a certain pin.
    5.82 @@ -249,7 +268,7 @@ static int find_irq_entry(int apic, int 
    5.83  /*
    5.84   * Find the pin to which IRQ[irq] (ISA) is connected
    5.85   */
    5.86 -static int find_isa_irq_pin(int irq, int type)
    5.87 +static int __init find_isa_irq_pin(int irq, int type)
    5.88  {
    5.89      int i;
    5.90  
    5.91 @@ -269,6 +288,33 @@ static int find_isa_irq_pin(int irq, int
    5.92      return -1;
    5.93  }
    5.94  
    5.95 +static int __init find_isa_irq_apic(int irq, int type)
    5.96 +{
    5.97 +    int i;
    5.98 +
    5.99 +    for (i = 0; i < mp_irq_entries; i++) {
   5.100 +        int lbus = mp_irqs[i].mpc_srcbus;
   5.101 +
   5.102 +        if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA ||
   5.103 +             mp_bus_id_to_type[lbus] == MP_BUS_EISA ||
   5.104 +             mp_bus_id_to_type[lbus] == MP_BUS_MCA ||
   5.105 +             mp_bus_id_to_type[lbus] == MP_BUS_NEC98
   5.106 +            ) &&
   5.107 +            (mp_irqs[i].mpc_irqtype == type) &&
   5.108 +            (mp_irqs[i].mpc_srcbusirq == irq))
   5.109 +            break;
   5.110 +    }
   5.111 +    if (i < mp_irq_entries) {
   5.112 +        int apic;
   5.113 +        for(apic = 0; apic < nr_ioapics; apic++) {
   5.114 +            if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic)
   5.115 +                return apic;
   5.116 +        }
   5.117 +    }
   5.118 +
   5.119 +    return -1;
   5.120 +}
   5.121 +
   5.122  /*
   5.123   * Find a specific PCI IRQ entry.
   5.124   * Not an __init, possibly needed by modules
   5.125 @@ -276,10 +322,11 @@ static int find_isa_irq_pin(int irq, int
   5.126  static int pin_2_irq(int idx, int apic, int pin);
   5.127  
   5.128  /*
   5.129 - * This function currently is only a helper for the i386 smp boot process where
   5.130 - * we need to reprogram the ioredtbls to cater for the cpus which have come
   5.131 - * online so mask in all cases should simply be TARGET_CPUS
   5.132 + * This function currently is only a helper for the i386 smp boot process where 
   5.133 + * we need to reprogram the ioredtbls to cater for the cpus which have come online
   5.134 + * so mask in all cases should simply be TARGET_CPUS
   5.135   */
   5.136 +#ifdef CONFIG_SMP
   5.137  void __init setup_ioapic_dest(void)
   5.138  {
   5.139      int pin, ioapic, irq, irq_entry;
   5.140 @@ -298,6 +345,7 @@ void __init setup_ioapic_dest(void)
   5.141  
   5.142      }
   5.143  }
   5.144 +#endif
   5.145  
   5.146  /*
   5.147   * EISA Edge/Level control register, ELCR
   5.148 @@ -571,7 +619,7 @@ static inline int IO_APIC_irq_trigger(in
   5.149  }
   5.150  
   5.151  /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
   5.152 -u8 irq_vector[NR_IRQ_VECTORS];
   5.153 +u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };
   5.154  
   5.155  int assign_irq_vector(int irq)
   5.156  {
   5.157 @@ -580,7 +628,7 @@ int assign_irq_vector(int irq)
   5.158      BUG_ON(irq >= NR_IRQ_VECTORS);
   5.159      if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
   5.160          return IO_APIC_VECTOR(irq);
   5.161 - next:
   5.162 +next:
   5.163      current_vector += 8;
   5.164  
   5.165      /* Skip the hypercall vector. */
   5.166 @@ -621,7 +669,7 @@ static inline void ioapic_register_intr(
   5.167          irq_desc[vector].handler = &ioapic_edge_type;
   5.168  }
   5.169  
   5.170 -void __init setup_IO_APIC_irqs(void)
   5.171 +static void __init setup_IO_APIC_irqs(void)
   5.172  {
   5.173      struct IO_APIC_route_entry entry;
   5.174      int apic, pin, idx, irq, first_notcon = 1, vector;
   5.175 @@ -689,6 +737,7 @@ void __init setup_IO_APIC_irqs(void)
   5.176              spin_lock_irqsave(&ioapic_lock, flags);
   5.177              io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
   5.178              io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
   5.179 +            set_native_irq_info(entry.vector, TARGET_CPUS);
   5.180              spin_unlock_irqrestore(&ioapic_lock, flags);
   5.181  	}
   5.182      }
   5.183 @@ -700,7 +749,7 @@ void __init setup_IO_APIC_irqs(void)
   5.184  /*
   5.185   * Set up the 8259A-master output pin:
   5.186   */
   5.187 -void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
   5.188 +static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, int vector)
   5.189  {
   5.190      struct IO_APIC_route_entry entry;
   5.191      unsigned long flags;
   5.192 @@ -734,8 +783,8 @@ void __init setup_ExtINT_IRQ0_pin(unsign
   5.193       * Add it to the IO-APIC irq-routing table:
   5.194       */
   5.195      spin_lock_irqsave(&ioapic_lock, flags);
   5.196 -    io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
   5.197 -    io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
   5.198 +    io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
   5.199 +    io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
   5.200      spin_unlock_irqrestore(&ioapic_lock, flags);
   5.201  
   5.202      enable_8259A_irq(0);
   5.203 @@ -901,7 +950,8 @@ void print_IO_APIC_keyhandler(unsigned c
   5.204  static void __init enable_IO_APIC(void)
   5.205  {
   5.206      union IO_APIC_reg_01 reg_01;
   5.207 -    int i;
   5.208 +    int i8259_apic, i8259_pin;
   5.209 +    int i, apic;
   5.210      unsigned long flags;
   5.211  
   5.212      for (i = 0; i < PIN_MAP_SIZE; i++) {
   5.213 @@ -912,11 +962,52 @@ static void __init enable_IO_APIC(void)
   5.214      /*
   5.215       * The number of IO-APIC IRQ registers (== #pins):
   5.216       */
   5.217 -    for (i = 0; i < nr_ioapics; i++) {
   5.218 +    for (apic = 0; apic < nr_ioapics; apic++) {
   5.219          spin_lock_irqsave(&ioapic_lock, flags);
   5.220 -        reg_01.raw = io_apic_read(i, 1);
   5.221 +        reg_01.raw = io_apic_read(apic, 1);
   5.222          spin_unlock_irqrestore(&ioapic_lock, flags);
   5.223 -        nr_ioapic_registers[i] = reg_01.bits.entries+1;
   5.224 +        nr_ioapic_registers[apic] = reg_01.bits.entries+1;
   5.225 +    }
   5.226 +    for(apic = 0; apic < nr_ioapics; apic++) {
   5.227 +        int pin;
   5.228 +        /* See if any of the pins is in ExtINT mode */
   5.229 +        for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
   5.230 +            struct IO_APIC_route_entry entry;
   5.231 +            spin_lock_irqsave(&ioapic_lock, flags);
   5.232 +            *(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
   5.233 +            *(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
   5.234 +            spin_unlock_irqrestore(&ioapic_lock, flags);
   5.235 +
   5.236 +
   5.237 +            /* If the interrupt line is enabled and in ExtInt mode
   5.238 +             * I have found the pin where the i8259 is connected.
   5.239 +             */
   5.240 +            if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) {
   5.241 +                ioapic_i8259.apic = apic;
   5.242 +                ioapic_i8259.pin  = pin;
   5.243 +                goto found_i8259;
   5.244 +            }
   5.245 +        }
   5.246 +    }
   5.247 + found_i8259:
   5.248 +    /* Look to see what if the MP table has reported the ExtINT */
   5.249 +    /* If we could not find the appropriate pin by looking at the ioapic
   5.250 +     * the i8259 probably is not connected the ioapic but give the
   5.251 +     * mptable a chance anyway.
   5.252 +     */
   5.253 +    i8259_pin  = find_isa_irq_pin(0, mp_ExtINT);
   5.254 +    i8259_apic = find_isa_irq_apic(0, mp_ExtINT);
   5.255 +    /* Trust the MP table if nothing is setup in the hardware */
   5.256 +    if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) {
   5.257 +        printk(KERN_WARNING "ExtINT not setup in hardware but reported by MP table\n");
   5.258 +        ioapic_i8259.pin  = i8259_pin;
   5.259 +        ioapic_i8259.apic = i8259_apic;
   5.260 +    }
   5.261 +    /* Complain if the MP table and the hardware disagree */
   5.262 +    if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) &&
   5.263 +        (i8259_pin >= 0) && (ioapic_i8259.pin >= 0))
   5.264 +    {
   5.265 +        printk(KERN_WARNING "ExtINT in hardware and MP table differ\n");
   5.266      }
   5.267  
   5.268      /*
   5.269 @@ -932,10 +1023,41 @@ void disable_IO_APIC(void)
   5.270  {
   5.271      /*
   5.272       * Clear the IO-APIC before rebooting:
   5.273 -	 */
   5.274 +     */
   5.275      clear_IO_APIC();
   5.276  
   5.277 -    disconnect_bsp_APIC();
   5.278 +    /*
   5.279 +     * If the i8259 is routed through an IOAPIC
   5.280 +     * Put that IOAPIC in virtual wire mode
   5.281 +     * so legacy interrupts can be delivered.
   5.282 +     */
   5.283 +    if (ioapic_i8259.pin != -1) {
   5.284 +        struct IO_APIC_route_entry entry;
   5.285 +        unsigned long flags;
   5.286 +
   5.287 +        memset(&entry, 0, sizeof(entry));
   5.288 +        entry.mask            = 0; /* Enabled */
   5.289 +        entry.trigger         = 0; /* Edge */
   5.290 +        entry.irr             = 0;
   5.291 +        entry.polarity        = 0; /* High */
   5.292 +        entry.delivery_status = 0;
   5.293 +        entry.dest_mode       = 0; /* Physical */
   5.294 +        entry.delivery_mode   = dest_ExtINT; /* ExtInt */
   5.295 +        entry.vector          = 0;
   5.296 +        entry.dest.physical.physical_dest =
   5.297 +            GET_APIC_ID(apic_read(APIC_ID));
   5.298 +
   5.299 +        /*
   5.300 +         * Add it to the IO-APIC irq-routing table:
   5.301 +         */
   5.302 +        spin_lock_irqsave(&ioapic_lock, flags);
   5.303 +        io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin,
   5.304 +                      *(((int *)&entry)+1));
   5.305 +        io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin,
   5.306 +                      *(((int *)&entry)+0));
   5.307 +        spin_unlock_irqrestore(&ioapic_lock, flags);
   5.308 +    }
   5.309 +    disconnect_bsp_APIC(ioapic_i8259.pin != -1);
   5.310  }
   5.311  
   5.312  /*
   5.313 @@ -1248,6 +1370,8 @@ static void set_ioapic_affinity_vector(
   5.314      unsigned int vector, cpumask_t cpu_mask)
   5.315  {
   5.316      int irq = vector_to_irq(vector);
   5.317 +
   5.318 +    set_native_irq_info(vector, cpu_mask);
   5.319      set_ioapic_affinity_irq(irq, cpu_mask);
   5.320  }
   5.321  
   5.322 @@ -1292,6 +1416,7 @@ static struct hw_interrupt_type ioapic_l
   5.323  static inline void init_IO_APIC_traps(void)
   5.324  {
   5.325      int irq;
   5.326 +    /* Xen: This is way simpler than the Linux implementation. */
   5.327      for (irq = 0; irq < 16 ; irq++)
   5.328          if (IO_APIC_IRQ(irq) && !IO_APIC_VECTOR(irq))
   5.329              make_8259A_irq(irq);
   5.330 @@ -1339,20 +1464,21 @@ static struct hw_interrupt_type lapic_ir
   5.331   */
   5.332  static inline void unlock_ExtINT_logic(void)
   5.333  {
   5.334 -    int pin, i;
   5.335 +    int apic, pin, i;
   5.336      struct IO_APIC_route_entry entry0, entry1;
   5.337      unsigned char save_control, save_freq_select;
   5.338      unsigned long flags;
   5.339  
   5.340      pin = find_isa_irq_pin(8, mp_INT);
   5.341 +    apic = find_isa_irq_apic(8, mp_INT);
   5.342      if (pin == -1)
   5.343          return;
   5.344  
   5.345      spin_lock_irqsave(&ioapic_lock, flags);
   5.346 -    *(((int *)&entry0) + 1) = io_apic_read(0, 0x11 + 2 * pin);
   5.347 -    *(((int *)&entry0) + 0) = io_apic_read(0, 0x10 + 2 * pin);
   5.348 +    *(((int *)&entry0) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
   5.349 +    *(((int *)&entry0) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
   5.350      spin_unlock_irqrestore(&ioapic_lock, flags);
   5.351 -    clear_IO_APIC_pin(0, pin);
   5.352 +    clear_IO_APIC_pin(apic, pin);
   5.353  
   5.354      memset(&entry1, 0, sizeof(entry1));
   5.355  
   5.356 @@ -1365,8 +1491,8 @@ static inline void unlock_ExtINT_logic(v
   5.357      entry1.vector = 0;
   5.358  
   5.359      spin_lock_irqsave(&ioapic_lock, flags);
   5.360 -    io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry1) + 1));
   5.361 -    io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry1) + 0));
   5.362 +    io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry1) + 1));
   5.363 +    io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry1) + 0));
   5.364      spin_unlock_irqrestore(&ioapic_lock, flags);
   5.365  
   5.366      save_control = CMOS_READ(RTC_CONTROL);
   5.367 @@ -1384,11 +1510,11 @@ static inline void unlock_ExtINT_logic(v
   5.368  
   5.369      CMOS_WRITE(save_control, RTC_CONTROL);
   5.370      CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
   5.371 -    clear_IO_APIC_pin(0, pin);
   5.372 +    clear_IO_APIC_pin(apic, pin);
   5.373  
   5.374      spin_lock_irqsave(&ioapic_lock, flags);
   5.375 -    io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry0) + 1));
   5.376 -    io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
   5.377 +    io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry0) + 1));
   5.378 +    io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
   5.379      spin_unlock_irqrestore(&ioapic_lock, flags);
   5.380  }
   5.381  
   5.382 @@ -1400,7 +1526,7 @@ static inline void unlock_ExtINT_logic(v
   5.383   */
   5.384  static inline void check_timer(void)
   5.385  {
   5.386 -    int pin1, pin2;
   5.387 +    int apic1, pin1, apic2, pin2;
   5.388      int vector;
   5.389  
   5.390      /*
   5.391 @@ -1425,10 +1551,13 @@ static inline void check_timer(void)
   5.392      timer_ack = 1;
   5.393      enable_8259A_irq(0);
   5.394  
   5.395 -    pin1 = find_isa_irq_pin(0, mp_INT);
   5.396 -    pin2 = find_isa_irq_pin(0, mp_ExtINT);
   5.397 +    pin1  = find_isa_irq_pin(0, mp_INT);
   5.398 +    apic1 = find_isa_irq_apic(0, mp_INT);
   5.399 +    pin2  = ioapic_i8259.pin;
   5.400 +    apic2 = ioapic_i8259.apic;
   5.401  
   5.402 -    printk(KERN_INFO "..TIMER: vector=0x%02X pin1=%d pin2=%d\n", vector, pin1, pin2);
   5.403 +    printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
   5.404 +           vector, apic1, pin1, apic2, pin2);
   5.405  
   5.406      if (pin1 != -1) {
   5.407          /*
   5.408 @@ -1436,10 +1565,13 @@ static inline void check_timer(void)
   5.409           */
   5.410          unmask_IO_APIC_irq(0);
   5.411          if (timer_irq_works()) {
   5.412 +            if (disable_timer_pin_1 > 0)
   5.413 +                clear_IO_APIC_pin(apic1, pin1);
   5.414              return;
   5.415          }
   5.416 -        clear_IO_APIC_pin(0, pin1);
   5.417 -        printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to IO-APIC\n");
   5.418 +        clear_IO_APIC_pin(apic1, pin1);
   5.419 +        printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to "
   5.420 +               "IO-APIC\n");
   5.421      }
   5.422  
   5.423      printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... ");
   5.424 @@ -1448,19 +1580,19 @@ static inline void check_timer(void)
   5.425          /*
   5.426           * legacy devices should be connected to IO APIC #0
   5.427           */
   5.428 -        setup_ExtINT_IRQ0_pin(pin2, vector);
   5.429 +        setup_ExtINT_IRQ0_pin(apic2, pin2, vector);
   5.430          if (timer_irq_works()) {
   5.431              printk("works.\n");
   5.432              if (pin1 != -1)
   5.433 -                replace_pin_at_irq(0, 0, pin1, 0, pin2);
   5.434 +                replace_pin_at_irq(0, apic1, pin1, apic2, pin2);
   5.435              else
   5.436 -                add_pin_to_irq(0, 0, pin2);
   5.437 +                add_pin_to_irq(0, apic2, pin2);
   5.438              return;
   5.439          }
   5.440          /*
   5.441           * Cleanup, just in case ...
   5.442           */
   5.443 -        clear_IO_APIC_pin(0, pin2);
   5.444 +        clear_IO_APIC_pin(apic2, pin2);
   5.445      }
   5.446      printk(" failed.\n");
   5.447  
   5.448 @@ -1699,6 +1831,7 @@ int io_apic_set_pci_routing (int ioapic,
   5.449      spin_lock_irqsave(&ioapic_lock, flags);
   5.450      io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1));
   5.451      io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0));
   5.452 +    set_native_irq_info(entry.vector, TARGET_CPUS);
   5.453      spin_unlock_irqrestore(&ioapic_lock, flags);
   5.454  
   5.455      return 0;
     6.1 --- a/xen/arch/x86/irq.c	Tue Feb 14 16:23:43 2006 +0100
     6.2 +++ b/xen/arch/x86/irq.c	Tue Feb 14 18:25:10 2006 +0100
     6.3 @@ -31,8 +31,7 @@ static unsigned int startup_none(unsigne
     6.4  static void disable_none(unsigned int vector) { }
     6.5  static void ack_none(unsigned int vector)
     6.6  {
     6.7 -    printk("Unexpected IRQ trap at vector %02x.\n", vector);
     6.8 -    ack_APIC_irq();
     6.9 +    ack_bad_irq(vector);
    6.10  }
    6.11  
    6.12  #define shutdown_none   disable_none
    6.13 @@ -84,11 +83,11 @@ asmlinkage void do_IRQ(struct cpu_user_r
    6.14      while ( desc->status & IRQ_PENDING )
    6.15      {
    6.16          desc->status &= ~IRQ_PENDING;
    6.17 -        irq_enter(smp_processor_id());
    6.18 +        irq_enter();
    6.19          spin_unlock_irq(&desc->lock);
    6.20          action->handler(vector_to_irq(vector), action->dev_id, regs);
    6.21          spin_lock_irq(&desc->lock);
    6.22 -        irq_exit(smp_processor_id());
    6.23 +        irq_exit();
    6.24      }
    6.25  
    6.26      desc->status &= ~IRQ_INPROGRESS;
     7.1 --- a/xen/arch/x86/smpboot.c	Tue Feb 14 16:23:43 2006 +0100
     7.2 +++ b/xen/arch/x86/smpboot.c	Tue Feb 14 18:25:10 2006 +0100
     7.3 @@ -1189,14 +1189,17 @@ void __init smp_cpus_done(unsigned int m
     7.4  	set_kernel_exec((unsigned long)trampoline_base, trampoline_exec);
     7.5  }
     7.6  
     7.7 -#if 0
     7.8  void __init smp_intr_init(void)
     7.9  {
    7.10  	/*
    7.11 -	 * The reschedule interrupt is a CPU-to-CPU reschedule-helper
    7.12 -	 * IPI, driven by wakeup.
    7.13 +	 * IRQ0 must be given a fixed assignment and initialized,
    7.14 +	 * because it's used before the IO-APIC is set up.
    7.15  	 */
    7.16 -	set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
    7.17 +	irq_vector[0] = FIRST_DEVICE_VECTOR;
    7.18 +	vector_irq[FIRST_DEVICE_VECTOR] = 0;
    7.19 +
    7.20 +	/* IPI for event checking. */
    7.21 +	set_intr_gate(EVENT_CHECK_VECTOR, event_check_interrupt);
    7.22  
    7.23  	/* IPI for invalidation */
    7.24  	set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);
    7.25 @@ -1204,4 +1207,3 @@ void __init smp_intr_init(void)
    7.26  	/* IPI for generic function call */
    7.27  	set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
    7.28  }
    7.29 -#endif
     8.1 --- a/xen/include/asm-x86/apic.h	Tue Feb 14 16:23:43 2006 +0100
     8.2 +++ b/xen/include/asm-x86/apic.h	Tue Feb 14 18:25:10 2006 +0100
     8.3 @@ -87,7 +87,7 @@ extern void (*wait_timer_tick)(void);
     8.4  extern int get_maxlvt(void);
     8.5  extern void clear_local_APIC(void);
     8.6  extern void connect_bsp_APIC (void);
     8.7 -extern void disconnect_bsp_APIC (void);
     8.8 +extern void disconnect_bsp_APIC (int virt_wire_setup);
     8.9  extern void disable_local_APIC (void);
    8.10  extern void lapic_shutdown (void);
    8.11  extern int verify_local_APIC (void);
     9.1 --- a/xen/include/asm-x86/apicdef.h	Tue Feb 14 16:23:43 2006 +0100
     9.2 +++ b/xen/include/asm-x86/apicdef.h	Tue Feb 14 18:25:10 2006 +0100
     9.3 @@ -87,11 +87,12 @@
     9.4  #define			APIC_LVT_REMOTE_IRR		(1<<14)
     9.5  #define			APIC_INPUT_POLARITY		(1<<13)
     9.6  #define			APIC_SEND_PENDING		(1<<12)
     9.7 +#define			APIC_MODE_MASK			0x700
     9.8  #define			GET_APIC_DELIVERY_MODE(x)	(((x)>>8)&0x7)
     9.9  #define			SET_APIC_DELIVERY_MODE(x,y)	(((x)&~0x700)|((y)<<8))
    9.10  #define				APIC_MODE_FIXED		0x0
    9.11  #define				APIC_MODE_NMI		0x4
    9.12 -#define				APIC_MODE_EXINT		0x7
    9.13 +#define				APIC_MODE_EXTINT	0x7
    9.14  #define 	APIC_LVT1	0x360
    9.15  #define		APIC_LVTERR	0x370
    9.16  #define		APIC_TMICT	0x380
    9.17 @@ -109,11 +110,10 @@
    9.18  
    9.19  #define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
    9.20  
    9.21 -/* These limits are dictated by ES7000 hardware. */
    9.22  #ifdef __i386__
    9.23 - #define MAX_IO_APICS 65
    9.24 + #define MAX_IO_APICS 64
    9.25  #else
    9.26 - #define MAX_IO_APICS 129
    9.27 + #define MAX_IO_APICS 128
    9.28  #endif
    9.29  
    9.30  /*
    10.1 --- a/xen/include/asm-x86/hardirq.h	Tue Feb 14 16:23:43 2006 +0100
    10.2 +++ b/xen/include/asm-x86/hardirq.h	Tue Feb 14 18:25:10 2006 +0100
    10.3 @@ -15,7 +15,12 @@ typedef struct {
    10.4  
    10.5  #define in_irq() (local_irq_count(smp_processor_id()) != 0)
    10.6  
    10.7 -#define irq_enter(cpu)	(local_irq_count(cpu)++)
    10.8 -#define irq_exit(cpu)	(local_irq_count(cpu)--)
    10.9 +#define irq_enter()	(local_irq_count(smp_processor_id())++)
   10.10 +#define irq_exit()	(local_irq_count(smp_processor_id())--)
   10.11 +
   10.12 +void ack_bad_irq(unsigned int irq);
   10.13 +
   10.14 +extern void apic_intr_init(void);
   10.15 +extern void smp_intr_init(void);
   10.16  
   10.17  #endif /* __ASM_HARDIRQ_H */
    11.1 --- a/xen/include/asm-x86/irq.h	Tue Feb 14 16:23:43 2006 +0100
    11.2 +++ b/xen/include/asm-x86/irq.h	Tue Feb 14 18:25:10 2006 +0100
    11.3 @@ -24,6 +24,14 @@ extern u8 irq_vector[NR_IRQ_VECTORS];
    11.4  
    11.5  #define platform_legacy_irq(irq)	((irq) < 16)
    11.6  
    11.7 +fastcall void event_check_interrupt(void);
    11.8 +fastcall void invalidate_interrupt(void);
    11.9 +fastcall void call_function_interrupt(void);
   11.10 +fastcall void apic_timer_interrupt(void);
   11.11 +fastcall void error_interrupt(void);
   11.12 +fastcall void spurious_interrupt(void);
   11.13 +fastcall void thermal_interrupt(void);
   11.14 +
   11.15  void disable_8259A_irq(unsigned int irq);
   11.16  void enable_8259A_irq(unsigned int irq);
   11.17  int i8259A_irq_pending(unsigned int irq);
    12.1 --- a/xen/include/asm-x86/x86_32/asm_defns.h	Tue Feb 14 16:23:43 2006 +0100
    12.2 +++ b/xen/include/asm-x86/x86_32/asm_defns.h	Tue Feb 14 18:25:10 2006 +0100
    12.3 @@ -58,6 +58,7 @@
    12.4  asmlinkage void x(void);                        \
    12.5  __asm__(                                        \
    12.6      "\n"__ALIGN_STR"\n"                         \
    12.7 +    ".globl " STR(x) "\n\t"                     \
    12.8      STR(x) ":\n\t"                              \
    12.9      "pushl $"#v"<<16\n\t"                       \
   12.10      STR(SAVE_ALL(a))                            \
   12.11 @@ -67,8 +68,6 @@ asmlinkage void x(void);                
   12.12      "addl $4,%esp\n\t"                          \
   12.13      "jmp ret_from_intr\n");
   12.14  
   12.15 -#define BUILD_SMP_TIMER_INTERRUPT(x,v) BUILD_SMP_INTERRUPT(x,v)
   12.16 -
   12.17  #define BUILD_COMMON_IRQ()                      \
   12.18  __asm__(                                        \
   12.19      "\n" __ALIGN_STR"\n"                        \
    13.1 --- a/xen/include/asm-x86/x86_64/asm_defns.h	Tue Feb 14 16:23:43 2006 +0100
    13.2 +++ b/xen/include/asm-x86/x86_64/asm_defns.h	Tue Feb 14 18:25:10 2006 +0100
    13.3 @@ -65,6 +65,7 @@
    13.4  asmlinkage void x(void);                        \
    13.5  __asm__(                                        \
    13.6      "\n"__ALIGN_STR"\n"                         \
    13.7 +    ".globl " STR(x) "\n\t"                     \
    13.8      STR(x) ":\n\t"                              \
    13.9      "pushq $0\n\t"                              \
   13.10      "movl $"#v",4(%rsp)\n\t"                    \
   13.11 @@ -73,8 +74,6 @@ asmlinkage void x(void);                
   13.12      "callq "STR(smp_##x)"\n\t"                  \
   13.13      "jmp ret_from_intr\n");
   13.14  
   13.15 -#define BUILD_SMP_TIMER_INTERRUPT(x,v) BUILD_SMP_INTERRUPT(x,v)
   13.16 -
   13.17  #define BUILD_COMMON_IRQ()                      \
   13.18  __asm__(                                        \
   13.19      "\n" __ALIGN_STR"\n"                        \
    14.1 --- a/xen/include/xen/config.h	Tue Feb 14 16:23:43 2006 +0100
    14.2 +++ b/xen/include/xen/config.h	Tue Feb 14 18:25:10 2006 +0100
    14.3 @@ -52,4 +52,7 @@
    14.4  #define mk_unsigned_long(x) x
    14.5  #endif /* !__ASSEMBLY__ */
    14.6  
    14.7 +#define fastcall
    14.8 +#define __read_mostly
    14.9 +
   14.10  #endif /* __XEN_CONFIG_H__ */
    15.1 --- a/xen/include/xen/init.h	Tue Feb 14 16:23:43 2006 +0100
    15.2 +++ b/xen/include/xen/init.h	Tue Feb 14 18:25:10 2006 +0100
    15.3 @@ -100,6 +100,4 @@ extern struct kernel_param __setup_start
    15.4  #define __devexitdata __exitdata
    15.5  #endif
    15.6  
    15.7 -#define fastcall
    15.8 -
    15.9  #endif /* _LINUX_INIT_H */