ia64/xen-unstable

changeset 151:0834a70d2e19

bitkeeper revision 1.22.2.20 (3e4bb0deGlYf76D1jtppEmaeeRJyVQ)

Pulled in IO APIC stuff from linux-2.4.21-pre4
author iap10@labyrinth.cl.cam.ac.uk
date Thu Feb 13 14:51:10 2003 +0000 (2003-02-13)
parents 12beced1bf62
children 42a318e8648e 9f696c88dd6d ba73696088e6
files xen-2.4.16/arch/i386/io_apic.c xen-2.4.16/arch/i386/mpparse.c xen-2.4.16/drivers/net/Makefile xen-2.4.16/drivers/net/e1000/e1000.h xen-2.4.16/drivers/net/e1000/e1000_hw.c xen-2.4.16/drivers/net/e1000/e1000_main.c xen-2.4.16/drivers/net/e1000/e1000_osdep.h xen-2.4.16/include/asm-i386/apic.h xen-2.4.16/include/asm-i386/apicdef.h xen-2.4.16/include/asm-i386/io_apic.h xen-2.4.16/include/asm-i386/mpspec.h xen-2.4.16/include/asm-i386/smpboot.h
line diff
     1.1 --- a/xen-2.4.16/arch/i386/io_apic.c	Thu Feb 13 11:03:29 2003 +0000
     1.2 +++ b/xen-2.4.16/arch/i386/io_apic.c	Thu Feb 13 14:51:10 2003 +0000
     1.3 @@ -28,11 +28,23 @@
     1.4  #include <xeno/config.h>
     1.5  #include <asm/mc146818rtc.h>
     1.6  #include <asm/io.h>
     1.7 +#include <asm/smp.h>
     1.8  #include <asm/desc.h>
     1.9 -#include <asm/smp.h>
    1.10 +#include <asm/smpboot.h>
    1.11 +
    1.12 +
    1.13 +static unsigned int nmi_watchdog;  /* XXXX XEN */
    1.14 +
    1.15 +#undef APIC_LOCKUP_DEBUG
    1.16 +
    1.17 +#define APIC_LOCKUP_DEBUG
    1.18  
    1.19  static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED;
    1.20  
    1.21 +unsigned int int_dest_addr_mode = APIC_DEST_LOGICAL;
    1.22 +unsigned char int_delivery_mode = dest_LowestPrio;
    1.23 +
    1.24 +
    1.25  /*
    1.26   * # of IRQ routing registers
    1.27   */
    1.28 @@ -47,6 +59,7 @@ int nr_ioapic_registers[MAX_IO_APICS];
    1.29  
    1.30  /*
    1.31   * This is performance-critical, we want to do it O(1)
    1.32 + *
    1.33   * the indexing order of this array favors 1:1 mappings
    1.34   * between pins and IRQs.
    1.35   */
    1.36 @@ -60,7 +73,7 @@ static struct irq_pin_list {
    1.37   * shared ISA-space IRQs, so we have to support them. We are super
    1.38   * fast in the common case, and fast for shared ISA-space IRQs.
    1.39   */
    1.40 -static void add_pin_to_irq(unsigned int irq, int apic, int pin)
    1.41 +static void __init add_pin_to_irq(unsigned int irq, int apic, int pin)
    1.42  {
    1.43  	static int first_free_entry = NR_IRQS;
    1.44  	struct irq_pin_list *entry = irq_2_pin + irq;
    1.45 @@ -78,6 +91,26 @@ static void add_pin_to_irq(unsigned int 
    1.46  	entry->pin = pin;
    1.47  }
    1.48  
    1.49 +/*
    1.50 + * Reroute an IRQ to a different pin.
    1.51 + */
    1.52 +static void __init replace_pin_at_irq(unsigned int irq,
    1.53 +				      int oldapic, int oldpin,
    1.54 +				      int newapic, int newpin)
    1.55 +{
    1.56 +	struct irq_pin_list *entry = irq_2_pin + irq;
    1.57 +
    1.58 +	while (1) {
    1.59 +		if (entry->apic == oldapic && entry->pin == oldpin) {
    1.60 +			entry->apic = newapic;
    1.61 +			entry->pin = newpin;
    1.62 +		}
    1.63 +		if (!entry->next)
    1.64 +			break;
    1.65 +		entry = irq_2_pin + entry->next;
    1.66 +	}
    1.67 +}
    1.68 +
    1.69  #define __DO_ACTION(R, ACTION, FINAL)					\
    1.70  									\
    1.71  {									\
    1.72 @@ -157,6 +190,66 @@ static void clear_IO_APIC (void)
    1.73  }
    1.74  
    1.75  /*
    1.76 + * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to
    1.77 + * specific CPU-side IRQs.
    1.78 + */
    1.79 +
    1.80 +#define MAX_PIRQS 8
    1.81 +int pirq_entries [MAX_PIRQS];
    1.82 +int pirqs_enabled;
    1.83 +
    1.84 +int skip_ioapic_setup;
    1.85 +#if 0
    1.86 +
    1.87 +static int __init noioapic_setup(char *str)
    1.88 +{
    1.89 +	skip_ioapic_setup = 1;
    1.90 +	return 1;
    1.91 +}
    1.92 +
    1.93 +__setup("noapic", noioapic_setup);
    1.94 +
    1.95 +static int __init ioapic_setup(char *str)
    1.96 +{
    1.97 +	skip_ioapic_setup = 0;
    1.98 +	return 1;
    1.99 +}
   1.100 +
   1.101 +__setup("apic", ioapic_setup);
   1.102 +
   1.103 +
   1.104 +
   1.105 +static int __init ioapic_pirq_setup(char *str)
   1.106 +{
   1.107 +	int i, max;
   1.108 +	int ints[MAX_PIRQS+1];
   1.109 +
   1.110 +	get_options(str, ARRAY_SIZE(ints), ints);
   1.111 +
   1.112 +	for (i = 0; i < MAX_PIRQS; i++)
   1.113 +		pirq_entries[i] = -1;
   1.114 +
   1.115 +	pirqs_enabled = 1;
   1.116 +	printk(KERN_INFO "PIRQ redirection, working around broken MP-BIOS.\n");
   1.117 +	max = MAX_PIRQS;
   1.118 +	if (ints[0] < MAX_PIRQS)
   1.119 +		max = ints[0];
   1.120 +
   1.121 +	for (i = 0; i < max; i++) {
   1.122 +		printk(KERN_DEBUG "... PIRQ%d -> IRQ %d\n", i, ints[i+1]);
   1.123 +		/*
   1.124 +		 * PIRQs are mapped upside down, usually.
   1.125 +		 */
   1.126 +		pirq_entries[MAX_PIRQS-i-1] = ints[i+1];
   1.127 +	}
   1.128 +	return 1;
   1.129 +}
   1.130 +
   1.131 +__setup("pirq=", ioapic_pirq_setup);
   1.132 +
   1.133 +#endif
   1.134 +
   1.135 +/*
   1.136   * Find the IRQ entry number of a certain pin.
   1.137   */
   1.138  static int __init find_irq_entry(int apic, int pin, int type)
   1.139 @@ -206,7 +299,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, 
   1.140  
   1.141  	Dprintk("querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n",
   1.142  		bus, slot, pin);
   1.143 -	if (mp_bus_id_to_pci_bus[bus] == -1) {
   1.144 +	if ((mp_bus_id_to_pci_bus==NULL) || (mp_bus_id_to_pci_bus[bus] == -1)) {
   1.145  		printk(KERN_WARNING "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
   1.146  		return -1;
   1.147  	}
   1.148 @@ -466,6 +559,20 @@ static int pin_2_irq(int idx, int apic, 
   1.149  		}
   1.150  	}
   1.151  
   1.152 +	/*
   1.153 +	 * PCI IRQ command line redirection. Yes, limits are hardcoded.
   1.154 +	 */
   1.155 +	if ((pin >= 16) && (pin <= 23)) {
   1.156 +		if (pirq_entries[pin-16] != -1) {
   1.157 +			if (!pirq_entries[pin-16]) {
   1.158 +				printk(KERN_DEBUG "disabling PIRQ%d\n", pin-16);
   1.159 +			} else {
   1.160 +				irq = pirq_entries[pin-16];
   1.161 +				printk(KERN_DEBUG "using PIRQ%d -> IRQ %d\n",
   1.162 +						pin-16, irq);
   1.163 +			}
   1.164 +		}
   1.165 +	}
   1.166  	return irq;
   1.167  }
   1.168  
   1.169 @@ -495,11 +602,17 @@ static int __init assign_irq_vector(int 
   1.170  		return IO_APIC_VECTOR(irq);
   1.171  next:
   1.172  	current_vector += 8;
   1.173 +
   1.174          /* XXX Skip the guestOS -> Xen syscall vector! XXX */
   1.175  	if (current_vector == HYPERVISOR_CALL_VECTOR) goto next;
   1.176          /* XXX Skip the Linux/BSD fast-trap vector! XXX */
   1.177          if (current_vector == 0x80) goto next;
   1.178  
   1.179 +#if 0
   1.180 +	if (current_vector == SYSCALL_VECTOR)
   1.181 +		goto next;
   1.182 +#endif
   1.183 +
   1.184  	if (current_vector > FIRST_SYSTEM_VECTOR) {
   1.185  		offset++;
   1.186  		current_vector = FIRST_DEVICE_VECTOR + offset;
   1.187 @@ -532,10 +645,10 @@ void __init setup_IO_APIC_irqs(void)
   1.188  		 */
   1.189  		memset(&entry,0,sizeof(entry));
   1.190  
   1.191 -		entry.delivery_mode = dest_LowestPrio;
   1.192 -		entry.dest_mode = INT_DELIVERY_MODE;
   1.193 +		entry.delivery_mode = INT_DELIVERY_MODE;
   1.194 +		entry.dest_mode = (INT_DEST_ADDR_MODE != 0);
   1.195  		entry.mask = 0;				/* enable IRQ */
   1.196 -		entry.dest.logical.logical_dest = TARGET_CPUS;
   1.197 +		entry.dest.logical.logical_dest = target_cpus();
   1.198  
   1.199  		idx = find_irq_entry(apic,pin,mp_INT);
   1.200  		if (idx == -1) {
   1.201 @@ -553,11 +666,18 @@ void __init setup_IO_APIC_irqs(void)
   1.202  		if (irq_trigger(idx)) {
   1.203  			entry.trigger = 1;
   1.204  			entry.mask = 1;
   1.205 -			entry.dest.logical.logical_dest = TARGET_CPUS;
   1.206  		}
   1.207  
   1.208  		irq = pin_2_irq(idx, apic, pin);
   1.209 -		add_pin_to_irq(irq, apic, pin);
   1.210 +		/*
   1.211 +		 * skip adding the timer int on secondary nodes, which causes
   1.212 +		 * a small but painful rift in the time-space continuum
   1.213 +		 */
   1.214 +		if ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ) 
   1.215 +			&& (apic != 0) && (irq == 0))
   1.216 +			continue;
   1.217 +		else
   1.218 +			add_pin_to_irq(irq, apic, pin);
   1.219  
   1.220  		if (!apic && !IO_APIC_IRQ(irq))
   1.221  			continue;
   1.222 @@ -607,16 +727,16 @@ void __init setup_ExtINT_IRQ0_pin(unsign
   1.223  	 * We use logical delivery to get the timer IRQ
   1.224  	 * to the first CPU.
   1.225  	 */
   1.226 -	entry.dest_mode = INT_DELIVERY_MODE;
   1.227 +	entry.dest_mode = (INT_DEST_ADDR_MODE != 0);
   1.228  	entry.mask = 0;					/* unmask IRQ now */
   1.229 -	entry.dest.logical.logical_dest = TARGET_CPUS;
   1.230 -	entry.delivery_mode = dest_LowestPrio;
   1.231 +	entry.dest.logical.logical_dest = target_cpus();
   1.232 +	entry.delivery_mode = INT_DELIVERY_MODE;
   1.233  	entry.polarity = 0;
   1.234  	entry.trigger = 0;
   1.235  	entry.vector = vector;
   1.236  
   1.237  	/*
   1.238 -	 * The timer IRQ doesnt have to know that behind the
   1.239 +	 * The timer IRQ doesn't have to know that behind the
   1.240  	 * scene we have a 8259A-master in AEOI mode ...
   1.241  	 */
   1.242  	irq_desc[0].handler = &ioapic_edge_irq_type;
   1.243 @@ -634,8 +754,9 @@ void __init setup_ExtINT_IRQ0_pin(unsign
   1.244  
   1.245  void __init UNEXPECTED_IO_APIC(void)
   1.246  {
   1.247 -	printk(KERN_WARNING " WARNING: unexpected IO-APIC, please mail\n");
   1.248 -	printk(KERN_WARNING "          to linux-smp@vger.kernel.org\n");
   1.249 +	printk(KERN_WARNING 
   1.250 +		"An unexpected IO-APIC was found. If this kernel release is less than\n"
   1.251 +		"three months old please report this to linux-smp@vger.kernel.org\n");
   1.252  }
   1.253  
   1.254  void __init print_IO_APIC(void)
   1.255 @@ -667,7 +788,7 @@ void __init print_IO_APIC(void)
   1.256  	spin_unlock_irqrestore(&ioapic_lock, flags);
   1.257  
   1.258  	printk("\n");
   1.259 -	printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid);
   1.260 +	printk(KERN_DEBUG "IO APIC #%d..XXXX....\n", mp_ioapics[apic].mpc_apicid);
   1.261  	printk(KERN_DEBUG ".... register #00: %08X\n", *(int *)&reg_00);
   1.262  	printk(KERN_DEBUG ".......    : physical APIC id: %02X\n", reg_00.ID);
   1.263  	if (reg_00.__reserved_1 || reg_00.__reserved_2)
   1.264 @@ -688,6 +809,7 @@ void __init print_IO_APIC(void)
   1.265  	printk(KERN_DEBUG ".......     : PRQ implemented: %X\n", reg_01.PRQ);
   1.266  	printk(KERN_DEBUG ".......     : IO APIC version: %04X\n", reg_01.version);
   1.267  	if (	(reg_01.version != 0x01) && /* 82489DX IO-APICs */
   1.268 +		(reg_01.version != 0x02) && /* VIA */
   1.269  		(reg_01.version != 0x10) && /* oldest IO-APICs */
   1.270  		(reg_01.version != 0x11) && /* Pentium/Pro IO-APICs */
   1.271  		(reg_01.version != 0x13) && /* Xeon IO-APICs */
   1.272 @@ -898,6 +1020,9 @@ static void __init enable_IO_APIC(void)
   1.273  		irq_2_pin[i].pin = -1;
   1.274  		irq_2_pin[i].next = 0;
   1.275  	}
   1.276 +	if (!pirqs_enabled)
   1.277 +		for (i = 0; i < MAX_PIRQS; i++)
   1.278 +			pirq_entries[i] = -1;
   1.279  
   1.280  	/*
   1.281  	 * The number of IO-APIC IRQ registers (== #pins):
   1.282 @@ -944,6 +1069,9 @@ static void __init setup_ioapic_ids_from
   1.283  	unsigned char old_id;
   1.284  	unsigned long flags;
   1.285  
   1.286 +	if (clustered_apic_mode)
   1.287 +		/* We don't have a good way to do this yet - hack */
   1.288 +		phys_id_present_map = (u_long) 0xf;
   1.289  	/*
   1.290  	 * Set the IOAPIC ID to the value stored in the MPC table.
   1.291  	 */
   1.292 @@ -956,7 +1084,7 @@ static void __init setup_ioapic_ids_from
   1.293  		
   1.294  		old_id = mp_ioapics[apic].mpc_apicid;
   1.295  
   1.296 -		if (mp_ioapics[apic].mpc_apicid >= 0xf) {
   1.297 +		if (mp_ioapics[apic].mpc_apicid >= apic_broadcast_id) {
   1.298  			printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
   1.299  				apic, mp_ioapics[apic].mpc_apicid);
   1.300  			printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
   1.301 @@ -968,14 +1096,16 @@ static void __init setup_ioapic_ids_from
   1.302  		 * Sanity check, is the ID really free? Every APIC in a
   1.303  		 * system must have a unique ID or we get lots of nice
   1.304  		 * 'stuck on smp_invalidate_needed IPI wait' messages.
   1.305 +		 * I/O APIC IDs no longer have any meaning for xAPICs and SAPICs.
   1.306  		 */
   1.307 -		if (phys_id_present_map & (1 << mp_ioapics[apic].mpc_apicid)) {
   1.308 +		if ((clustered_apic_mode != CLUSTERED_APIC_XAPIC) &&
   1.309 +		    (phys_id_present_map & (1 << mp_ioapics[apic].mpc_apicid))) {
   1.310  			printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
   1.311  				apic, mp_ioapics[apic].mpc_apicid);
   1.312  			for (i = 0; i < 0xf; i++)
   1.313  				if (!(phys_id_present_map & (1 << i)))
   1.314  					break;
   1.315 -			if (i >= 0xf)
   1.316 +			if (i >= apic_broadcast_id)
   1.317  				panic("Max APIC ID exceeded!\n");
   1.318  			printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
   1.319  				i);
   1.320 @@ -1170,6 +1300,10 @@ static void end_level_ioapic_irq (unsign
   1.321  #ifdef APIC_LOCKUP_DEBUG
   1.322  		struct irq_pin_list *entry;
   1.323  #endif
   1.324 +
   1.325 +#ifdef APIC_MISMATCH_DEBUG
   1.326 +		atomic_inc(&irq_mis_count);
   1.327 +#endif
   1.328  		spin_lock(&ioapic_lock);
   1.329  		__mask_and_edge_IO_APIC_irq(irq);
   1.330  #ifdef APIC_LOCKUP_DEBUG
   1.331 @@ -1302,6 +1436,36 @@ static struct hw_interrupt_type lapic_ir
   1.332  	end_lapic_irq
   1.333  };
   1.334  
   1.335 +static void enable_NMI_through_LVT0 (void * dummy)
   1.336 +{
   1.337 +	unsigned int v, ver;
   1.338 +
   1.339 +	ver = apic_read(APIC_LVR);
   1.340 +	ver = GET_APIC_VERSION(ver);
   1.341 +	v = APIC_DM_NMI;			/* unmask and set to NMI */
   1.342 +	if (!APIC_INTEGRATED(ver))		/* 82489DX */
   1.343 +		v |= APIC_LVT_LEVEL_TRIGGER;
   1.344 +	apic_write_around(APIC_LVT0, v);
   1.345 +}
   1.346 +
   1.347 +static void setup_nmi (void)
   1.348 +{
   1.349 +	/*
   1.350 + 	 * Dirty trick to enable the NMI watchdog ...
   1.351 +	 * We put the 8259A master into AEOI mode and
   1.352 +	 * unmask on all local APICs LVT0 as NMI.
   1.353 +	 *
   1.354 +	 * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire')
   1.355 +	 * is from Maciej W. Rozycki - so we do not have to EOI from
   1.356 +	 * the NMI handler or the timer interrupt.
   1.357 +	 */ 
   1.358 +	printk(KERN_INFO "activating NMI Watchdog ...");
   1.359 +
   1.360 +	smp_call_function(enable_NMI_through_LVT0, NULL, 1, 1);
   1.361 +	enable_NMI_through_LVT0(NULL);
   1.362 +
   1.363 +	printk(" done.\n");
   1.364 +}
   1.365  
   1.366  /*
   1.367   * This looks a bit hackish but it's about the only one way of sending
   1.368 @@ -1407,6 +1571,12 @@ static inline void check_timer(void)
   1.369  		 */
   1.370  		unmask_IO_APIC_irq(0);
   1.371  		if (timer_irq_works()) {
   1.372 +			if (nmi_watchdog == NMI_IO_APIC) {
   1.373 +				disable_8259A_irq(0);
   1.374 +				setup_nmi();
   1.375 +				enable_8259A_irq(0);
   1.376 +				// XXX Xen check_nmi_watchdog();
   1.377 +			}
   1.378  			return;
   1.379  		}
   1.380  		clear_IO_APIC_pin(0, pin1);
   1.381 @@ -1422,6 +1592,14 @@ static inline void check_timer(void)
   1.382  		setup_ExtINT_IRQ0_pin(pin2, vector);
   1.383  		if (timer_irq_works()) {
   1.384  			printk("works.\n");
   1.385 +			if (pin1 != -1)
   1.386 +				replace_pin_at_irq(0, 0, pin1, 0, pin2);
   1.387 +			else
   1.388 +				add_pin_to_irq(0, 0, pin2);
   1.389 +			if (nmi_watchdog == NMI_IO_APIC) {
   1.390 +				setup_nmi();
   1.391 +				// XXX Xen check_nmi_watchdog();
   1.392 +			}
   1.393  			return;
   1.394  		}
   1.395  		/*
   1.396 @@ -1431,6 +1609,11 @@ static inline void check_timer(void)
   1.397  	}
   1.398  	printk(" failed.\n");
   1.399  
   1.400 +	if (nmi_watchdog) {
   1.401 +		printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
   1.402 +		nmi_watchdog = 0;
   1.403 +	}
   1.404 +
   1.405  	printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
   1.406  
   1.407  	disable_8259A_irq(0);
   1.408 @@ -1462,10 +1645,19 @@ static inline void check_timer(void)
   1.409  }
   1.410  
   1.411  /*
   1.412 + *
   1.413   * IRQ's that are handled by the old PIC in all cases:
   1.414   * - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ.
   1.415   *   Linux doesn't really care, as it's not actually used
   1.416   *   for any interrupt handling anyway.
   1.417 + * - There used to be IRQ13 here as well, but all
   1.418 + *   MPS-compliant must not use it for FPU coupling and we
   1.419 + *   want to use exception 16 anyway.  And there are
   1.420 + *   systems who connect it to an I/O APIC for other uses.
   1.421 + *   Thus we don't mark it special any longer.
   1.422 + *
   1.423 + * Additionally, something is definitely wrong with irq9
   1.424 + * on PIIX4 boards.
   1.425   */
   1.426  #define PIC_IRQS	(1<<2)
   1.427  
     2.1 --- a/xen-2.4.16/arch/i386/mpparse.c	Thu Feb 13 11:03:29 2003 +0000
     2.2 +++ b/xen-2.4.16/arch/i386/mpparse.c	Thu Feb 13 14:51:10 2003 +0000
     2.3 @@ -20,6 +20,10 @@
     2.4  #include <xeno/smp.h>
     2.5  #include <asm/mpspec.h>
     2.6  #include <asm/pgalloc.h>
     2.7 +#include <asm/smpboot.h>
     2.8 +#include <xeno/kernel.h>
     2.9 +
    2.10 +int numnodes = 1; /* XXX Xen */
    2.11  
    2.12  /* Have we found an MP table */
    2.13  int smp_found_config;
    2.14 @@ -29,16 +33,20 @@ int smp_found_config;
    2.15   * MP-table.
    2.16   */
    2.17  int apic_version [MAX_APICS];
    2.18 -int mp_bus_id_to_type [MAX_MP_BUSSES];
    2.19 -int mp_bus_id_to_node [MAX_MP_BUSSES];
    2.20 -int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
    2.21 +int quad_local_to_mp_bus_id [NR_CPUS/4][4];
    2.22  int mp_current_pci_id;
    2.23 +int *mp_bus_id_to_type;
    2.24 +int *mp_bus_id_to_node;
    2.25 +int *mp_bus_id_to_local;
    2.26 +int *mp_bus_id_to_pci_bus;
    2.27 +int max_mp_busses;
    2.28 +int max_irq_sources;
    2.29  
    2.30  /* I/O APIC entries */
    2.31  struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
    2.32  
    2.33  /* # of MP IRQ source entries */
    2.34 -struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
    2.35 +struct mpc_config_intsrc *mp_irqs;
    2.36  
    2.37  /* MP IRQ source entries */
    2.38  int mp_irq_entries;
    2.39 @@ -56,23 +64,32 @@ static unsigned int num_processors;
    2.40  
    2.41  /* Bitmask of physically existing CPUs */
    2.42  unsigned long phys_cpu_present_map;
    2.43 +unsigned long logical_cpu_present_map;
    2.44 +
    2.45 +#ifdef CONFIG_X86_CLUSTERED_APIC
    2.46 +unsigned char esr_disable = 0;
    2.47 +unsigned char clustered_apic_mode = CLUSTERED_APIC_NONE;
    2.48 +unsigned int apic_broadcast_id = APIC_BROADCAST_ID_APIC;
    2.49 +#endif
    2.50 +unsigned char raw_phys_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
    2.51  
    2.52  /*
    2.53   * Intel MP BIOS table parsing routines:
    2.54   */
    2.55  
    2.56 +#ifndef CONFIG_X86_VISWS_APIC
    2.57  /*
    2.58   * Checksum an MP configuration block.
    2.59   */
    2.60  
    2.61  static int __init mpf_checksum(unsigned char *mp, int len)
    2.62  {
    2.63 -    int sum = 0;
    2.64 +	int sum = 0;
    2.65  
    2.66 -    while (len--)
    2.67 -        sum += *mp++;
    2.68 +	while (len--)
    2.69 +		sum += *mp++;
    2.70  
    2.71 -    return sum & 0xFF;
    2.72 +	return sum & 0xFF;
    2.73  }
    2.74  
    2.75  /*
    2.76 @@ -81,38 +98,47 @@ static int __init mpf_checksum(unsigned 
    2.77  
    2.78  static char __init *mpc_family(int family,int model)
    2.79  {
    2.80 -    static char n[32];
    2.81 -    static char *model_defs[]=
    2.82 -    {
    2.83 -        "80486DX","80486DX",
    2.84 -        "80486SX","80486DX/2 or 80487",
    2.85 -        "80486SL","80486SX/2",
    2.86 -        "Unknown","80486DX/2-WB",
    2.87 -        "80486DX/4","80486DX/4-WB"
    2.88 -    };
    2.89 +	static char n[32];
    2.90 +	static char *model_defs[]=
    2.91 +	{
    2.92 +		"80486DX","80486DX",
    2.93 +		"80486SX","80486DX/2 or 80487",
    2.94 +		"80486SL","80486SX/2",
    2.95 +		"Unknown","80486DX/2-WB",
    2.96 +		"80486DX/4","80486DX/4-WB"
    2.97 +	};
    2.98  
    2.99 -    switch (family) {
   2.100 -    case 0x04:
   2.101 -        if (model < 10)
   2.102 -            return model_defs[model];
   2.103 -        break;
   2.104 +	switch (family) {
   2.105 +		case 0x04:
   2.106 +			if (model < 10)
   2.107 +				return model_defs[model];
   2.108 +			break;
   2.109 +
   2.110 +		case 0x05:
   2.111 +			return("Pentium(tm)");
   2.112  
   2.113 -    case 0x05:
   2.114 -        return("Pentium(tm)");
   2.115 -
   2.116 -    case 0x06:
   2.117 -        return("Pentium(tm) Pro");
   2.118 +		case 0x06:
   2.119 +			return("Pentium(tm) Pro");
   2.120  
   2.121 -    case 0x0F:
   2.122 -        if (model == 0x00)
   2.123 -            return("Pentium 4(tm)");
   2.124 -        if (model == 0x0F)
   2.125 -            return("Special controller");
   2.126 -    }
   2.127 -    sprintf(n,"Unknown CPU [%d:%d]",family, model);
   2.128 -    return n;
   2.129 +		case 0x0F:
   2.130 +			if (model == 0x00)
   2.131 +				return("Pentium 4(tm)");
   2.132 +			if (model == 0x02)
   2.133 +				return("Pentium 4(tm) XEON(tm)");
   2.134 +			if (model == 0x0F)
   2.135 +				return("Special controller");
   2.136 +	}
   2.137 +	sprintf(n,"Unknown CPU [%d:%d]",family, model);
   2.138 +	return n;
   2.139  }
   2.140  
   2.141 +#ifdef CONFIG_X86_IO_APIC
   2.142 +// XXX Xen extern int have_acpi_tables;	/* set by acpitable.c */
   2.143 +#define have_acpi_tables (0)
   2.144 +#else
   2.145 +#define have_acpi_tables (0)
   2.146 +#endif
   2.147 +
   2.148  /* 
   2.149   * Have to match translation table entries to main table entries by counter
   2.150   * hence the mpc_record variable .... can't see a less disgusting way of
   2.151 @@ -120,127 +146,256 @@ static char __init *mpc_family(int famil
   2.152   */
   2.153  
   2.154  static int mpc_record; 
   2.155 +static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata;
   2.156  
   2.157  void __init MP_processor_info (struct mpc_config_processor *m)
   2.158  {
   2.159 -    int ver, logical_apicid;
   2.160 + 	int ver, quad, logical_apicid;
   2.161   	
   2.162 -    if (!(m->mpc_cpuflag & CPU_ENABLED))
   2.163 -        return;
   2.164 +	if (!(m->mpc_cpuflag & CPU_ENABLED))
   2.165 +		return;
   2.166  
   2.167 -    logical_apicid = m->mpc_apicid;
   2.168 -    printk("Processor #%d %s APIC version %d\n",
   2.169 -           m->mpc_apicid,
   2.170 -           mpc_family((m->mpc_cpufeature & CPU_FAMILY_MASK)>>8 ,
   2.171 -                      (m->mpc_cpufeature & CPU_MODEL_MASK)>>4),
   2.172 -           m->mpc_apicver);
   2.173 -
   2.174 -    if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
   2.175 -        Dprintk("    Bootup CPU\n");
   2.176 -        boot_cpu_physical_apicid = m->mpc_apicid;
   2.177 -        boot_cpu_logical_apicid = logical_apicid;
   2.178 -    }
   2.179 +	logical_apicid = m->mpc_apicid;
   2.180 +	if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
   2.181 +		quad = translation_table[mpc_record]->trans_quad;
   2.182 +		logical_apicid = (quad << 4) + 
   2.183 +			(m->mpc_apicid ? m->mpc_apicid << 1 : 1);
   2.184 +		printk("Processor #%d %s APIC version %d (quad %d, apic %d)\n",
   2.185 +			m->mpc_apicid,
   2.186 +			mpc_family((m->mpc_cpufeature & CPU_FAMILY_MASK)>>8 ,
   2.187 +				   (m->mpc_cpufeature & CPU_MODEL_MASK)>>4),
   2.188 +			m->mpc_apicver, quad, logical_apicid);
   2.189 +	} else {
   2.190 +		printk("Processor #%d %s APIC version %d\n",
   2.191 +			m->mpc_apicid,
   2.192 +			mpc_family((m->mpc_cpufeature & CPU_FAMILY_MASK)>>8 ,
   2.193 +				   (m->mpc_cpufeature & CPU_MODEL_MASK)>>4),
   2.194 +			m->mpc_apicver);
   2.195 +	}
   2.196  
   2.197 -    num_processors++;
   2.198 -
   2.199 -    if (m->mpc_apicid > MAX_APICS) {
   2.200 -        printk("Processor #%d INVALID. (Max ID: %d).\n",
   2.201 -               m->mpc_apicid, MAX_APICS);
   2.202 -        return;
   2.203 -    }
   2.204 -    ver = m->mpc_apicver;
   2.205 +	if (m->mpc_featureflag&(1<<0))
   2.206 +		Dprintk("    Floating point unit present.\n");
   2.207 +	if (m->mpc_featureflag&(1<<7))
   2.208 +		Dprintk("    Machine Exception supported.\n");
   2.209 +	if (m->mpc_featureflag&(1<<8))
   2.210 +		Dprintk("    64 bit compare & exchange supported.\n");
   2.211 +	if (m->mpc_featureflag&(1<<9))
   2.212 +		Dprintk("    Internal APIC present.\n");
   2.213 +	if (m->mpc_featureflag&(1<<11))
   2.214 +		Dprintk("    SEP present.\n");
   2.215 +	if (m->mpc_featureflag&(1<<12))
   2.216 +		Dprintk("    MTRR  present.\n");
   2.217 +	if (m->mpc_featureflag&(1<<13))
   2.218 +		Dprintk("    PGE  present.\n");
   2.219 +	if (m->mpc_featureflag&(1<<14))
   2.220 +		Dprintk("    MCA  present.\n");
   2.221 +	if (m->mpc_featureflag&(1<<15))
   2.222 +		Dprintk("    CMOV  present.\n");
   2.223 +	if (m->mpc_featureflag&(1<<16))
   2.224 +		Dprintk("    PAT  present.\n");
   2.225 +	if (m->mpc_featureflag&(1<<17))
   2.226 +		Dprintk("    PSE  present.\n");
   2.227 +	if (m->mpc_featureflag&(1<<18))
   2.228 +		Dprintk("    PSN  present.\n");
   2.229 +	if (m->mpc_featureflag&(1<<19))
   2.230 +		Dprintk("    Cache Line Flush Instruction present.\n");
   2.231 +	/* 20 Reserved */
   2.232 +	if (m->mpc_featureflag&(1<<21))
   2.233 +		Dprintk("    Debug Trace and EMON Store present.\n");
   2.234 +	if (m->mpc_featureflag&(1<<22))
   2.235 +		Dprintk("    ACPI Thermal Throttle Registers  present.\n");
   2.236 +	if (m->mpc_featureflag&(1<<23))
   2.237 +		Dprintk("    MMX  present.\n");
   2.238 +	if (m->mpc_featureflag&(1<<24))
   2.239 +		Dprintk("    FXSR  present.\n");
   2.240 +	if (m->mpc_featureflag&(1<<25))
   2.241 +		Dprintk("    XMM  present.\n");
   2.242 +	if (m->mpc_featureflag&(1<<26))
   2.243 +		Dprintk("    Willamette New Instructions  present.\n");
   2.244 +	if (m->mpc_featureflag&(1<<27))
   2.245 +		Dprintk("    Self Snoop  present.\n");
   2.246 +	if (m->mpc_featureflag&(1<<28))
   2.247 +		Dprintk("    HT  present.\n");
   2.248 +	if (m->mpc_featureflag&(1<<29))
   2.249 +		Dprintk("    Thermal Monitor present.\n");
   2.250 +	/* 30, 31 Reserved */
   2.251  
   2.252 -    phys_cpu_present_map |= 1 << m->mpc_apicid;
   2.253 +
   2.254 +	if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
   2.255 +		Dprintk("    Bootup CPU\n");
   2.256 +		boot_cpu_physical_apicid = m->mpc_apicid;
   2.257 +		boot_cpu_logical_apicid = logical_apicid;
   2.258 +	}
   2.259 +
   2.260 +	num_processors++;
   2.261  
   2.262 -    /*
   2.263 -     * Validate version
   2.264 -     */
   2.265 -    if (ver == 0x0) {
   2.266 -        printk("BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid);
   2.267 -        ver = 0x10;
   2.268 -    }
   2.269 -    apic_version[m->mpc_apicid] = ver;
   2.270 +	if (m->mpc_apicid > MAX_APICS) {
   2.271 +		printk("Processor #%d INVALID. (Max ID: %d).\n",
   2.272 +			m->mpc_apicid, MAX_APICS);
   2.273 +		--num_processors;
   2.274 +		return;
   2.275 +	}
   2.276 +	ver = m->mpc_apicver;
   2.277 +
   2.278 +	logical_cpu_present_map |= 1 << (num_processors-1);
   2.279 + 	phys_cpu_present_map |= apicid_to_phys_cpu_present(m->mpc_apicid);
   2.280 + 
   2.281 +	/*
   2.282 +	 * Validate version
   2.283 +	 */
   2.284 +	if (ver == 0x0) {
   2.285 +		printk("BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid);
   2.286 +		ver = 0x10;
   2.287 +	}
   2.288 +	apic_version[m->mpc_apicid] = ver;
   2.289 +	raw_phys_apicid[num_processors - 1] = m->mpc_apicid;
   2.290  }
   2.291  
   2.292  static void __init MP_bus_info (struct mpc_config_bus *m)
   2.293  {
   2.294 -    char str[7];
   2.295 -
   2.296 -    memcpy(str, m->mpc_bustype, 6);
   2.297 -    str[6] = 0;
   2.298 -	
   2.299 -    Dprintk("Bus #%d is %s\n", m->mpc_busid, str);
   2.300 +	char str[7];
   2.301 +	int quad;
   2.302  
   2.303 -    if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) {
   2.304 -        mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
   2.305 -    } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) {
   2.306 -        mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA;
   2.307 -    } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0) {
   2.308 -        mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI;
   2.309 -        mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id;
   2.310 -        mp_current_pci_id++;
   2.311 -    } else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) {
   2.312 -        mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA;
   2.313 -    } else {
   2.314 -        printk("Unknown bustype %s - ignoring\n", str);
   2.315 -    }
   2.316 +	memcpy(str, m->mpc_bustype, 6);
   2.317 +	str[6] = 0;
   2.318 +	
   2.319 +	if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
   2.320 +		quad = translation_table[mpc_record]->trans_quad;
   2.321 +		mp_bus_id_to_node[m->mpc_busid] = quad;
   2.322 +		mp_bus_id_to_local[m->mpc_busid] = translation_table[mpc_record]->trans_local;
   2.323 +		quad_local_to_mp_bus_id[quad][translation_table[mpc_record]->trans_local] = m->mpc_busid;
   2.324 +		printk("Bus #%d is %s (node %d)\n", m->mpc_busid, str, quad);
   2.325 +	} else {
   2.326 +		Dprintk("Bus #%d is %s\n", m->mpc_busid, str);
   2.327 +	}
   2.328 +
   2.329 +	if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) {
   2.330 +		mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
   2.331 +	} else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) {
   2.332 +		mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA;
   2.333 +	} else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0) {
   2.334 +		mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI;
   2.335 +		mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id;
   2.336 +		mp_current_pci_id++;
   2.337 +	} else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) {
   2.338 +		mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA;
   2.339 +	} else {
   2.340 +		printk("Unknown bustype %s - ignoring\n", str);
   2.341 +	}
   2.342  }
   2.343  
   2.344  static void __init MP_ioapic_info (struct mpc_config_ioapic *m)
   2.345  {
   2.346 -    if (!(m->mpc_flags & MPC_APIC_USABLE))
   2.347 -        return;
   2.348 +	if (!(m->mpc_flags & MPC_APIC_USABLE))
   2.349 +		return;
   2.350  
   2.351 -    printk("I/O APIC #%d Version %d at 0x%lX.\n",
   2.352 -           m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr);
   2.353 -    if (nr_ioapics >= MAX_IO_APICS) {
   2.354 -        printk("Max # of I/O APICs (%d) exceeded (found %d).\n",
   2.355 -               MAX_IO_APICS, nr_ioapics);
   2.356 -        panic("Recompile kernel with bigger MAX_IO_APICS!.\n");
   2.357 -    }
   2.358 -    if (!m->mpc_apicaddr) {
   2.359 -        printk("WARNING: bogus zero I/O APIC address"
   2.360 -               " found in MP table, skipping!\n");
   2.361 -        return;
   2.362 -    }
   2.363 -    mp_ioapics[nr_ioapics] = *m;
   2.364 -    nr_ioapics++;
   2.365 +	printk("I/O APIC #%d Version %d at 0x%lX.\n",
   2.366 +		m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr);
   2.367 +	if (nr_ioapics >= MAX_IO_APICS) {
   2.368 +		printk("Max # of I/O APICs (%d) exceeded (found %d).\n",
   2.369 +			MAX_IO_APICS, nr_ioapics);
   2.370 +		panic("Recompile kernel with bigger MAX_IO_APICS!.\n");
   2.371 +	}
   2.372 +	if (!m->mpc_apicaddr) {
   2.373 +		printk(KERN_ERR "WARNING: bogus zero I/O APIC address"
   2.374 +			" found in MP table, skipping!\n");
   2.375 +		return;
   2.376 +	}
   2.377 +	mp_ioapics[nr_ioapics] = *m;
   2.378 +	nr_ioapics++;
   2.379  }
   2.380  
   2.381  static void __init MP_intsrc_info (struct mpc_config_intsrc *m)
   2.382  {
   2.383 -    mp_irqs [mp_irq_entries] = *m;
   2.384 -    Dprintk("Int: type %d, pol %d, trig %d, bus %d,"
   2.385 -            " IRQ %02x, APIC ID %x, APIC INT %02x\n",
   2.386 -            m->mpc_irqtype, m->mpc_irqflag & 3,
   2.387 -            (m->mpc_irqflag >> 2) & 3, m->mpc_srcbus,
   2.388 -            m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq);
   2.389 -    if (++mp_irq_entries == MAX_IRQ_SOURCES)
   2.390 -        panic("Max # of irq sources exceeded!!\n");
   2.391 +	mp_irqs [mp_irq_entries] = *m;
   2.392 +	Dprintk("Int: type %d, pol %d, trig %d, bus %d,"
   2.393 +		" IRQ %02x, APIC ID %x, APIC INT %02x\n",
   2.394 +			m->mpc_irqtype, m->mpc_irqflag & 3,
   2.395 +			(m->mpc_irqflag >> 2) & 3, m->mpc_srcbus,
   2.396 +			m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq);
   2.397 +	if (++mp_irq_entries == max_irq_sources)
   2.398 +		panic("Max # of irq sources exceeded!!\n");
   2.399  }
   2.400  
   2.401  static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m)
   2.402  {
   2.403 -    Dprintk("Lint: type %d, pol %d, trig %d, bus %d,"
   2.404 -            " IRQ %02x, APIC ID %x, APIC LINT %02x\n",
   2.405 -            m->mpc_irqtype, m->mpc_irqflag & 3,
   2.406 -            (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid,
   2.407 -            m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint);
   2.408 -    /*
   2.409 -     * Well it seems all SMP boards in existence
   2.410 -     * use ExtINT/LVT1 == LINT0 and
   2.411 -     * NMI/LVT2 == LINT1 - the following check
   2.412 -     * will show us if this assumptions is false.
   2.413 -     * Until then we do not have to add baggage.
   2.414 -     */
   2.415 -    if ((m->mpc_irqtype == mp_ExtINT) &&
   2.416 -        (m->mpc_destapiclint != 0))
   2.417 -        BUG();
   2.418 -    if ((m->mpc_irqtype == mp_NMI) &&
   2.419 -        (m->mpc_destapiclint != 1))
   2.420 -        BUG();
   2.421 +	Dprintk("Lint: type %d, pol %d, trig %d, bus %d,"
   2.422 +		" IRQ %02x, APIC ID %x, APIC LINT %02x\n",
   2.423 +			m->mpc_irqtype, m->mpc_irqflag & 3,
   2.424 +			(m->mpc_irqflag >> 2) &3, m->mpc_srcbusid,
   2.425 +			m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint);
   2.426 +	/*
   2.427 +	 * Well it seems all SMP boards in existence
   2.428 +	 * use ExtINT/LVT1 == LINT0 and
   2.429 +	 * NMI/LVT2 == LINT1 - the following check
   2.430 +	 * will show us if this assumptions is false.
   2.431 +	 * Until then we do not have to add baggage.
   2.432 +	 */
   2.433 +	if ((m->mpc_irqtype == mp_ExtINT) &&
   2.434 +		(m->mpc_destapiclint != 0))
   2.435 +			BUG();
   2.436 +	if ((m->mpc_irqtype == mp_NMI) &&
   2.437 +		(m->mpc_destapiclint != 1))
   2.438 +			BUG();
   2.439 +}
   2.440 +
   2.441 +static void __init MP_translation_info (struct mpc_config_translation *m)
   2.442 +{
   2.443 +	printk("Translation: record %d, type %d, quad %d, global %d, local %d\n", mpc_record, m->trans_type, m->trans_quad, m->trans_global, m->trans_local);
   2.444 +
   2.445 +	if (mpc_record >= MAX_MPC_ENTRY) 
   2.446 +		printk("MAX_MPC_ENTRY exceeded!\n");
   2.447 +	else
   2.448 +		translation_table[mpc_record] = m; /* stash this for later */
   2.449 +	if (m->trans_quad+1 > numnodes)
   2.450 +		numnodes = m->trans_quad+1;
   2.451  }
   2.452  
   2.453 +/*
   2.454 + * Read/parse the MPC oem tables
   2.455 + */
   2.456 +
   2.457 +static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, \
   2.458 +	unsigned short oemsize)
   2.459 +{
   2.460 +	int count = sizeof (*oemtable); /* the header size */
   2.461 +	unsigned char *oemptr = ((unsigned char *)oemtable)+count;
   2.462 +	
   2.463 +	printk("Found an OEM MPC table at %8p - parsing it ... \n", oemtable);
   2.464 +	if (memcmp(oemtable->oem_signature,MPC_OEM_SIGNATURE,4))
   2.465 +	{
   2.466 +		printk("SMP mpc oemtable: bad signature [%c%c%c%c]!\n",
   2.467 +			oemtable->oem_signature[0],
   2.468 +			oemtable->oem_signature[1],
   2.469 +			oemtable->oem_signature[2],
   2.470 +			oemtable->oem_signature[3]);
   2.471 +		return;
   2.472 +	}
   2.473 +	if (mpf_checksum((unsigned char *)oemtable,oemtable->oem_length))
   2.474 +	{
   2.475 +		printk("SMP oem mptable: checksum error!\n");
   2.476 +		return;
   2.477 +	}
   2.478 +	while (count < oemtable->oem_length) {
   2.479 +		switch (*oemptr) {
   2.480 +			case MP_TRANSLATION:
   2.481 +			{
   2.482 +				struct mpc_config_translation *m=
   2.483 +					(struct mpc_config_translation *)oemptr;
   2.484 +				MP_translation_info(m);
   2.485 +				oemptr += sizeof(*m);
   2.486 +				count += sizeof(*m);
   2.487 +				++mpc_record;
   2.488 +				break;
   2.489 +			}
   2.490 +			default:
   2.491 +			{
   2.492 +				printk("Unrecognised OEM table entry type! - %d\n", (int) *oemptr);
   2.493 +				return;
   2.494 +			}
   2.495 +		}
   2.496 +       }
   2.497 +}
   2.498  
   2.499  /*
   2.500   * Read/parse the MPC
   2.501 @@ -248,383 +403,542 @@ static void __init MP_lintsrc_info (stru
   2.502  
   2.503  static int __init smp_read_mpc(struct mp_config_table *mpc)
   2.504  {
   2.505 -    char str[16];
   2.506 -    int count=sizeof(*mpc);
   2.507 -    unsigned char *mpt=((unsigned char *)mpc)+count;
   2.508 +	char oem[16], prod[14];
   2.509 +	int count=sizeof(*mpc);
   2.510 +	unsigned char *mpt=((unsigned char *)mpc)+count;
   2.511 +	int num_bus = 0;
   2.512 +	int num_irq = 0;
   2.513 +	unsigned char *bus_data;
   2.514  
   2.515 -    if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) {
   2.516 -        panic("SMP mptable: bad signature [%c%c%c%c]!\n",
   2.517 -              mpc->mpc_signature[0],
   2.518 -              mpc->mpc_signature[1],
   2.519 -              mpc->mpc_signature[2],
   2.520 -              mpc->mpc_signature[3]);
   2.521 -        return 0;
   2.522 -    }
   2.523 -    if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) {
   2.524 -        panic("SMP mptable: checksum error!\n");
   2.525 -        return 0;
   2.526 -    }
   2.527 -    if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) {
   2.528 -        printk("SMP mptable: bad table version (%d)!!\n",
   2.529 -               mpc->mpc_spec);
   2.530 -        return 0;
   2.531 -    }
   2.532 -    if (!mpc->mpc_lapic) {
   2.533 -        printk("SMP mptable: null local APIC address!\n");
   2.534 -        return 0;
   2.535 -    }
   2.536 -    memcpy(str,mpc->mpc_oem,8);
   2.537 -    str[8]=0;
   2.538 -    printk("OEM ID: %s ",str);
   2.539 +	if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) {
   2.540 +		panic("SMP mptable: bad signature [%c%c%c%c]!\n",
   2.541 +			mpc->mpc_signature[0],
   2.542 +			mpc->mpc_signature[1],
   2.543 +			mpc->mpc_signature[2],
   2.544 +			mpc->mpc_signature[3]);
   2.545 +		return 0;
   2.546 +	}
   2.547 +	if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) {
   2.548 +		panic("SMP mptable: checksum error!\n");
   2.549 +		return 0;
   2.550 +	}
   2.551 +	if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) {
   2.552 +		printk(KERN_ERR "SMP mptable: bad table version (%d)!!\n",
   2.553 +			mpc->mpc_spec);
   2.554 +		return 0;
   2.555 +	}
   2.556 +	if (!mpc->mpc_lapic) {
   2.557 +		printk(KERN_ERR "SMP mptable: null local APIC address!\n");
   2.558 +		return 0;
   2.559 +	}
   2.560 +	memcpy(oem,mpc->mpc_oem,8);
   2.561 +	oem[8]=0;
   2.562 +	printk("OEM ID: %s ",oem);
   2.563  
   2.564 -    memcpy(str,mpc->mpc_productid,12);
   2.565 -    str[12]=0;
   2.566 -    printk("Product ID: %s ",str);
   2.567 +	memcpy(prod,mpc->mpc_productid,12);
   2.568 +	prod[12]=0;
   2.569 +	printk("Product ID: %s ",prod);
   2.570  
   2.571 -    printk("APIC at: 0x%lX\n", mpc->mpc_lapic);
   2.572 -
   2.573 -    /* save the local APIC address, it might be non-default. */
   2.574 -    mp_lapic_addr = mpc->mpc_lapic;
   2.575 +	detect_clustered_apic(oem, prod);
   2.576 +	
   2.577 +	printk("APIC at: 0x%lX\n",mpc->mpc_lapic);
   2.578  
   2.579 -    /*
   2.580 -     *	Now process the configuration blocks.
   2.581 -     */
   2.582 -    while (count < mpc->mpc_length) {
   2.583 -        switch(*mpt) {
   2.584 -        case MP_PROCESSOR:
   2.585 -        {
   2.586 -            struct mpc_config_processor *m=
   2.587 -                (struct mpc_config_processor *)mpt;
   2.588 +	/* save the local APIC address, it might be non-default,
   2.589 +	 * but only if we're not using the ACPI tables
   2.590 +	 */
   2.591 +	if (!have_acpi_tables)
   2.592 +		mp_lapic_addr = mpc->mpc_lapic;
   2.593 +
   2.594 +	if ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ) && mpc->mpc_oemptr) {
   2.595 +		/* We need to process the oem mpc tables to tell us which quad things are in ... */
   2.596 +		mpc_record = 0;
   2.597 +		smp_read_mpc_oem((struct mp_config_oemtable *) mpc->mpc_oemptr, mpc->mpc_oemsize);
   2.598 +		mpc_record = 0;
   2.599 +	}
   2.600  
   2.601 -            MP_processor_info(m);
   2.602 -            mpt += sizeof(*m);
   2.603 -            count += sizeof(*m);
   2.604 -            break;
   2.605 -        }
   2.606 -        case MP_BUS:
   2.607 -        {
   2.608 -            struct mpc_config_bus *m=
   2.609 -                (struct mpc_config_bus *)mpt;
   2.610 -            MP_bus_info(m);
   2.611 -            mpt += sizeof(*m);
   2.612 -            count += sizeof(*m);
   2.613 -            break;
   2.614 -        }
   2.615 -        case MP_IOAPIC:
   2.616 -        {
   2.617 -            struct mpc_config_ioapic *m=
   2.618 -                (struct mpc_config_ioapic *)mpt;
   2.619 -            MP_ioapic_info(m);
   2.620 -            mpt+=sizeof(*m);
   2.621 -            count+=sizeof(*m);
   2.622 -            break;
   2.623 -        }
   2.624 -        case MP_INTSRC:
   2.625 -        {
   2.626 -            struct mpc_config_intsrc *m=
   2.627 -                (struct mpc_config_intsrc *)mpt;
   2.628 +	/* Pre-scan to determine the number of bus and 
   2.629 +	 * interrupts records we have
   2.630 +	 */
   2.631 +	while (count < mpc->mpc_length) {
   2.632 +		switch (*mpt) {
   2.633 +			case MP_PROCESSOR:
   2.634 +				mpt += sizeof(struct mpc_config_processor);
   2.635 +				count += sizeof(struct mpc_config_processor);
   2.636 +				break;
   2.637 +			case MP_BUS:
   2.638 +				++num_bus;
   2.639 +				mpt += sizeof(struct mpc_config_bus);
   2.640 +				count += sizeof(struct mpc_config_bus);
   2.641 +				break;
   2.642 +			case MP_INTSRC:
   2.643 +				++num_irq;
   2.644 +				mpt += sizeof(struct mpc_config_intsrc);
   2.645 +				count += sizeof(struct mpc_config_intsrc);
   2.646 +				break;
   2.647 +			case MP_IOAPIC:
   2.648 +				mpt += sizeof(struct mpc_config_ioapic);
   2.649 +				count += sizeof(struct mpc_config_ioapic);
   2.650 +				break;
   2.651 +			case MP_LINTSRC:
   2.652 +				mpt += sizeof(struct mpc_config_lintsrc);
   2.653 +				count += sizeof(struct mpc_config_lintsrc);
   2.654 +				break;
   2.655 +			default:
   2.656 +				count = mpc->mpc_length;
   2.657 +				break;
   2.658 +		}
   2.659 +	}
   2.660 +	/* 
   2.661 +	 * Paranoia: Allocate one extra of both the number of busses and number
   2.662 +	 * of irqs, and make sure that we have at least 4 interrupts per PCI
   2.663 +	 * slot.  But some machines do not report very many busses, so we need
   2.664 +	 * to fall back on the older defaults.
   2.665 +	 */
   2.666 +	++num_bus;
   2.667 +	max_mp_busses = max(num_bus, MAX_MP_BUSSES);
   2.668 +	if (num_irq < (4 * max_mp_busses))
   2.669 +		num_irq = 4 * num_bus;	/* 4 intr/PCI slot */
   2.670 +	++num_irq;
   2.671 +	max_irq_sources = max(num_irq, MAX_IRQ_SOURCES);
   2.672 +	
   2.673 +	count = (max_mp_busses * sizeof(int)) * 4;
   2.674 +	count += (max_irq_sources * sizeof(struct mpc_config_intsrc));
   2.675 +	
   2.676 +	{
   2.677 +	//bus_data = alloc_bootmem(count);  XXX Xen
   2.678 +	static char arr[4096];
   2.679 +	if(count > 4096) BUG();
   2.680 +	bus_data = (void*)arr;
   2.681 +	
   2.682 +	}
   2.683 +	if (!bus_data) {
   2.684 +		printk(KERN_ERR "SMP mptable: out of memory!\n");
   2.685 +		return 0;
   2.686 +	}
   2.687 +	mp_bus_id_to_type = (int *)&bus_data[0];
   2.688 +	mp_bus_id_to_node = (int *)&bus_data[(max_mp_busses * sizeof(int))];
   2.689 +	mp_bus_id_to_local = (int *)&bus_data[(max_mp_busses * sizeof(int)) * 2];
   2.690 +	mp_bus_id_to_pci_bus = (int *)&bus_data[(max_mp_busses * sizeof(int)) * 3];
   2.691 +	mp_irqs = (struct mpc_config_intsrc *)&bus_data[(max_mp_busses * sizeof(int)) * 4];
   2.692 +	memset(mp_bus_id_to_pci_bus, -1, max_mp_busses);
   2.693  
   2.694 -            MP_intsrc_info(m);
   2.695 -            mpt+=sizeof(*m);
   2.696 -            count+=sizeof(*m);
   2.697 -            break;
   2.698 -        }
   2.699 -        case MP_LINTSRC:
   2.700 -        {
   2.701 -            struct mpc_config_lintsrc *m=
   2.702 -                (struct mpc_config_lintsrc *)mpt;
   2.703 -            MP_lintsrc_info(m);
   2.704 -            mpt+=sizeof(*m);
   2.705 -            count+=sizeof(*m);
   2.706 -            break;
   2.707 -        }
   2.708 -        default:
   2.709 -        {
   2.710 -            count = mpc->mpc_length;
   2.711 -            break;
   2.712 -        }
   2.713 -        }
   2.714 -        ++mpc_record;
   2.715 -    }
   2.716 +	/*
   2.717 +	 *	Now process the configuration blocks.
   2.718 +	 */
   2.719 +	count = sizeof(*mpc);
   2.720 +	mpt = ((unsigned char *)mpc)+count;
   2.721 +	while (count < mpc->mpc_length) {
   2.722 +		switch(*mpt) {
   2.723 +			case MP_PROCESSOR:
   2.724 +			{
   2.725 +				struct mpc_config_processor *m=
   2.726 +					(struct mpc_config_processor *)mpt;
   2.727  
   2.728 -    if (!num_processors)
   2.729 -        printk("SMP mptable: no processors registered!\n");
   2.730 -    return num_processors;
   2.731 +				/* ACPI may already have provided this one for us */
   2.732 +				if (!have_acpi_tables)
   2.733 +					MP_processor_info(m);
   2.734 +				mpt += sizeof(*m);
   2.735 +				count += sizeof(*m);
   2.736 +				break;
   2.737 +			}
   2.738 +			case MP_BUS:
   2.739 +			{
   2.740 +				struct mpc_config_bus *m=
   2.741 +					(struct mpc_config_bus *)mpt;
   2.742 +				MP_bus_info(m);
   2.743 +				mpt += sizeof(*m);
   2.744 +				count += sizeof(*m);
   2.745 +				break;
   2.746 +			}
   2.747 +			case MP_IOAPIC:
   2.748 +			{
   2.749 +				struct mpc_config_ioapic *m=
   2.750 +					(struct mpc_config_ioapic *)mpt;
   2.751 +				MP_ioapic_info(m);
   2.752 +				mpt+=sizeof(*m);
   2.753 +				count+=sizeof(*m);
   2.754 +				break;
   2.755 +			}
   2.756 +			case MP_INTSRC:
   2.757 +			{
   2.758 +				struct mpc_config_intsrc *m=
   2.759 +					(struct mpc_config_intsrc *)mpt;
   2.760 +
   2.761 +				MP_intsrc_info(m);
   2.762 +				mpt+=sizeof(*m);
   2.763 +				count+=sizeof(*m);
   2.764 +				break;
   2.765 +			}
   2.766 +			case MP_LINTSRC:
   2.767 +			{
   2.768 +				struct mpc_config_lintsrc *m=
   2.769 +					(struct mpc_config_lintsrc *)mpt;
   2.770 +				MP_lintsrc_info(m);
   2.771 +				mpt+=sizeof(*m);
   2.772 +				count+=sizeof(*m);
   2.773 +				break;
   2.774 +			}
   2.775 +			default:
   2.776 +			{
   2.777 +				count = mpc->mpc_length;
   2.778 +				break;
   2.779 +			}
   2.780 +		}
   2.781 +		++mpc_record;
   2.782 +	}
   2.783 +
   2.784 +	if (clustered_apic_mode){
   2.785 +		phys_cpu_present_map = logical_cpu_present_map;
   2.786 +	}
   2.787 +
   2.788 +
   2.789 +	printk("Enabling APIC mode: ");
   2.790 +	if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
   2.791 +		printk("Clustered Logical.	");
   2.792 +	else if(clustered_apic_mode == CLUSTERED_APIC_XAPIC)
   2.793 +		printk("Physical.	");
   2.794 +	else
   2.795 +		printk("Flat.	");
   2.796 +	printk("Using %d I/O APICs\n",nr_ioapics);
   2.797 +
   2.798 +	if (!num_processors)
   2.799 +		printk(KERN_ERR "SMP mptable: no processors registered!\n");
   2.800 +	return num_processors;
   2.801  }
   2.802  
   2.803  static int __init ELCR_trigger(unsigned int irq)
   2.804  {
   2.805 -    unsigned int port;
   2.806 +	unsigned int port;
   2.807  
   2.808 -    port = 0x4d0 + (irq >> 3);
   2.809 -    return (inb(port) >> (irq & 7)) & 1;
   2.810 +	port = 0x4d0 + (irq >> 3);
   2.811 +	return (inb(port) >> (irq & 7)) & 1;
   2.812  }
   2.813  
   2.814  static void __init construct_default_ioirq_mptable(int mpc_default_type)
   2.815  {
   2.816 -    struct mpc_config_intsrc intsrc;
   2.817 -    int i;
   2.818 -    int ELCR_fallback = 0;
   2.819 +	struct mpc_config_intsrc intsrc;
   2.820 +	int i;
   2.821 +	int ELCR_fallback = 0;
   2.822  
   2.823 -    intsrc.mpc_type = MP_INTSRC;
   2.824 -    intsrc.mpc_irqflag = 0;			/* conforming */
   2.825 -    intsrc.mpc_srcbus = 0;
   2.826 -    intsrc.mpc_dstapic = mp_ioapics[0].mpc_apicid;
   2.827 +	intsrc.mpc_type = MP_INTSRC;
   2.828 +	intsrc.mpc_irqflag = 0;			/* conforming */
   2.829 +	intsrc.mpc_srcbus = 0;
   2.830 +	intsrc.mpc_dstapic = mp_ioapics[0].mpc_apicid;
   2.831  
   2.832 -    intsrc.mpc_irqtype = mp_INT;
   2.833 +	intsrc.mpc_irqtype = mp_INT;
   2.834  
   2.835 -    /*
   2.836 -     *  If true, we have an ISA/PCI system with no IRQ entries
   2.837 -     *  in the MP table. To prevent the PCI interrupts from being set up
   2.838 -     *  incorrectly, we try to use the ELCR. The sanity check to see if
   2.839 -     *  there is good ELCR data is very simple - IRQ0, 1, 2 and 13 can
   2.840 -     *  never be level sensitive, so we simply see if the ELCR agrees.
   2.841 -     *  If it does, we assume it's valid.
   2.842 -     */
   2.843 -    if (mpc_default_type == 5) {
   2.844 -        printk("ISA/PCI bus type with no IRQ information... falling back to ELCR\n");
   2.845 +	/*
   2.846 +	 *  If true, we have an ISA/PCI system with no IRQ entries
   2.847 +	 *  in the MP table. To prevent the PCI interrupts from being set up
   2.848 +	 *  incorrectly, we try to use the ELCR. The sanity check to see if
   2.849 +	 *  there is good ELCR data is very simple - IRQ0, 1, 2 and 13 can
   2.850 +	 *  never be level sensitive, so we simply see if the ELCR agrees.
   2.851 +	 *  If it does, we assume it's valid.
   2.852 +	 */
   2.853 +	if (mpc_default_type == 5) {
   2.854 +		printk("ISA/PCI bus type with no IRQ information... falling back to ELCR\n");
   2.855  
   2.856 -        if (ELCR_trigger(0) || ELCR_trigger(1) || ELCR_trigger(2) || ELCR_trigger(13))
   2.857 -            printk("ELCR contains invalid data... not using ELCR\n");
   2.858 -        else {
   2.859 -            printk("Using ELCR to identify PCI interrupts\n");
   2.860 -            ELCR_fallback = 1;
   2.861 -        }
   2.862 -    }
   2.863 +		if (ELCR_trigger(0) || ELCR_trigger(1) || ELCR_trigger(2) || ELCR_trigger(13))
   2.864 +			printk("ELCR contains invalid data... not using ELCR\n");
   2.865 +		else {
   2.866 +			printk("Using ELCR to identify PCI interrupts\n");
   2.867 +			ELCR_fallback = 1;
   2.868 +		}
   2.869 +	}
   2.870  
   2.871 -    for (i = 0; i < 16; i++) {
   2.872 -        switch (mpc_default_type) {
   2.873 -        case 2:
   2.874 -            if (i == 0 || i == 13)
   2.875 -                continue;	/* IRQ0 & IRQ13 not connected */
   2.876 -            /* fall through */
   2.877 -        default:
   2.878 -            if (i == 2)
   2.879 -                continue;	/* IRQ2 is never connected */
   2.880 -        }
   2.881 +	for (i = 0; i < 16; i++) {
   2.882 +		switch (mpc_default_type) {
   2.883 +		case 2:
   2.884 +			if (i == 0 || i == 13)
   2.885 +				continue;	/* IRQ0 & IRQ13 not connected */
   2.886 +			/* fall through */
   2.887 +		default:
   2.888 +			if (i == 2)
   2.889 +				continue;	/* IRQ2 is never connected */
   2.890 +		}
   2.891  
   2.892 -        if (ELCR_fallback) {
   2.893 -            /*
   2.894 -             *  If the ELCR indicates a level-sensitive interrupt, we
   2.895 -             *  copy that information over to the MP table in the
   2.896 -             *  irqflag field (level sensitive, active high polarity).
   2.897 -             */
   2.898 -            if (ELCR_trigger(i))
   2.899 -                intsrc.mpc_irqflag = 13;
   2.900 -            else
   2.901 -                intsrc.mpc_irqflag = 0;
   2.902 -        }
   2.903 +		if (ELCR_fallback) {
   2.904 +			/*
   2.905 +			 *  If the ELCR indicates a level-sensitive interrupt, we
   2.906 +			 *  copy that information over to the MP table in the
   2.907 +			 *  irqflag field (level sensitive, active high polarity).
   2.908 +			 */
   2.909 +			if (ELCR_trigger(i))
   2.910 +				intsrc.mpc_irqflag = 13;
   2.911 +			else
   2.912 +				intsrc.mpc_irqflag = 0;
   2.913 +		}
   2.914  
   2.915 -        intsrc.mpc_srcbusirq = i;
   2.916 -        intsrc.mpc_dstirq = i ? i : 2;		/* IRQ0 to INTIN2 */
   2.917 -        MP_intsrc_info(&intsrc);
   2.918 -    }
   2.919 +		intsrc.mpc_srcbusirq = i;
   2.920 +		intsrc.mpc_dstirq = i ? i : 2;		/* IRQ0 to INTIN2 */
   2.921 +		MP_intsrc_info(&intsrc);
   2.922 +	}
   2.923  
   2.924 -    intsrc.mpc_irqtype = mp_ExtINT;
   2.925 -    intsrc.mpc_srcbusirq = 0;
   2.926 -    intsrc.mpc_dstirq = 0;				/* 8259A to INTIN0 */
   2.927 -    MP_intsrc_info(&intsrc);
   2.928 +	intsrc.mpc_irqtype = mp_ExtINT;
   2.929 +	intsrc.mpc_srcbusirq = 0;
   2.930 +	intsrc.mpc_dstirq = 0;				/* 8259A to INTIN0 */
   2.931 +	MP_intsrc_info(&intsrc);
   2.932  }
   2.933  
   2.934  static inline void __init construct_default_ISA_mptable(int mpc_default_type)
   2.935  {
   2.936 -    struct mpc_config_processor processor;
   2.937 -    struct mpc_config_bus bus;
   2.938 -    struct mpc_config_ioapic ioapic;
   2.939 -    struct mpc_config_lintsrc lintsrc;
   2.940 -    int linttypes[2] = { mp_ExtINT, mp_NMI };
   2.941 -    int i;
   2.942 +	struct mpc_config_processor processor;
   2.943 +	struct mpc_config_bus bus;
   2.944 +	struct mpc_config_ioapic ioapic;
   2.945 +	struct mpc_config_lintsrc lintsrc;
   2.946 +	int linttypes[2] = { mp_ExtINT, mp_NMI };
   2.947 +	int i;
   2.948  
   2.949 -    /*
   2.950 -     * local APIC has default address
   2.951 -     */
   2.952 -    mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
   2.953 +	/*
   2.954 +	 * local APIC has default address
   2.955 +	 */
   2.956 +	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
   2.957  
   2.958 -    /*
   2.959 -     * 2 CPUs, numbered 0 & 1.
   2.960 -     */
   2.961 -    processor.mpc_type = MP_PROCESSOR;
   2.962 -    /* Either an integrated APIC or a discrete 82489DX. */
   2.963 -    processor.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
   2.964 -    processor.mpc_cpuflag = CPU_ENABLED;
   2.965 -    processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) |
   2.966 -        (boot_cpu_data.x86_model << 4) |
   2.967 -        boot_cpu_data.x86_mask;
   2.968 -    processor.mpc_featureflag = boot_cpu_data.x86_capability[0];
   2.969 -    processor.mpc_reserved[0] = 0;
   2.970 -    processor.mpc_reserved[1] = 0;
   2.971 -    for (i = 0; i < 2; i++) {
   2.972 -        processor.mpc_apicid = i;
   2.973 -        MP_processor_info(&processor);
   2.974 -    }
   2.975 +	/*
   2.976 +	 * 2 CPUs, numbered 0 & 1.
   2.977 +	 */
   2.978 +	processor.mpc_type = MP_PROCESSOR;
   2.979 +	/* Either an integrated APIC or a discrete 82489DX. */
   2.980 +	processor.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
   2.981 +	processor.mpc_cpuflag = CPU_ENABLED;
   2.982 +	processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) |
   2.983 +				   (boot_cpu_data.x86_model << 4) |
   2.984 +				   boot_cpu_data.x86_mask;
   2.985 +	processor.mpc_featureflag = boot_cpu_data.x86_capability[0];
   2.986 +	processor.mpc_reserved[0] = 0;
   2.987 +	processor.mpc_reserved[1] = 0;
   2.988 +	for (i = 0; i < 2; i++) {
   2.989 +		processor.mpc_apicid = i;
   2.990 +		MP_processor_info(&processor);
   2.991 +	}
   2.992  
   2.993 -    bus.mpc_type = MP_BUS;
   2.994 -    bus.mpc_busid = 0;
   2.995 -    switch (mpc_default_type) {
   2.996 -    default:
   2.997 -        printk("???\nUnknown standard configuration %d\n",
   2.998 -               mpc_default_type);
   2.999 -        /* fall through */
  2.1000 -    case 1:
  2.1001 -    case 5:
  2.1002 -        memcpy(bus.mpc_bustype, "ISA   ", 6);
  2.1003 -        break;
  2.1004 -    case 2:
  2.1005 -    case 6:
  2.1006 -    case 3:
  2.1007 -        memcpy(bus.mpc_bustype, "EISA  ", 6);
  2.1008 -        break;
  2.1009 -    case 4:
  2.1010 -    case 7:
  2.1011 -        memcpy(bus.mpc_bustype, "MCA   ", 6);
  2.1012 -    }
  2.1013 -    MP_bus_info(&bus);
  2.1014 -    if (mpc_default_type > 4) {
  2.1015 -        bus.mpc_busid = 1;
  2.1016 -        memcpy(bus.mpc_bustype, "PCI   ", 6);
  2.1017 -        MP_bus_info(&bus);
  2.1018 -    }
  2.1019 +	bus.mpc_type = MP_BUS;
  2.1020 +	bus.mpc_busid = 0;
  2.1021 +	switch (mpc_default_type) {
  2.1022 +		default:
  2.1023 +			printk("???\nUnknown standard configuration %d\n",
  2.1024 +				mpc_default_type);
  2.1025 +			/* fall through */
  2.1026 +		case 1:
  2.1027 +		case 5:
  2.1028 +			memcpy(bus.mpc_bustype, "ISA   ", 6);
  2.1029 +			break;
  2.1030 +		case 2:
  2.1031 +		case 6:
  2.1032 +		case 3:
  2.1033 +			memcpy(bus.mpc_bustype, "EISA  ", 6);
  2.1034 +			break;
  2.1035 +		case 4:
  2.1036 +		case 7:
  2.1037 +			memcpy(bus.mpc_bustype, "MCA   ", 6);
  2.1038 +	}
  2.1039 +	MP_bus_info(&bus);
  2.1040 +	if (mpc_default_type > 4) {
  2.1041 +		bus.mpc_busid = 1;
  2.1042 +		memcpy(bus.mpc_bustype, "PCI   ", 6);
  2.1043 +		MP_bus_info(&bus);
  2.1044 +	}
  2.1045  
  2.1046 -    ioapic.mpc_type = MP_IOAPIC;
  2.1047 -    ioapic.mpc_apicid = 2;
  2.1048 -    ioapic.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
  2.1049 -    ioapic.mpc_flags = MPC_APIC_USABLE;
  2.1050 -    ioapic.mpc_apicaddr = 0xFEC00000;
  2.1051 -    MP_ioapic_info(&ioapic);
  2.1052 +	ioapic.mpc_type = MP_IOAPIC;
  2.1053 +	ioapic.mpc_apicid = 2;
  2.1054 +	ioapic.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
  2.1055 +	ioapic.mpc_flags = MPC_APIC_USABLE;
  2.1056 +	ioapic.mpc_apicaddr = 0xFEC00000;
  2.1057 +	MP_ioapic_info(&ioapic);
  2.1058  
  2.1059 -    /*
  2.1060 -     * We set up most of the low 16 IO-APIC pins according to MPS rules.
  2.1061 -     */
  2.1062 -    construct_default_ioirq_mptable(mpc_default_type);
  2.1063 +	/*
  2.1064 +	 * We set up most of the low 16 IO-APIC pins according to MPS rules.
  2.1065 +	 */
  2.1066 +	construct_default_ioirq_mptable(mpc_default_type);
  2.1067  
  2.1068 -    lintsrc.mpc_type = MP_LINTSRC;
  2.1069 -    lintsrc.mpc_irqflag = 0;		/* conforming */
  2.1070 -    lintsrc.mpc_srcbusid = 0;
  2.1071 -    lintsrc.mpc_srcbusirq = 0;
  2.1072 -    lintsrc.mpc_destapic = MP_APIC_ALL;
  2.1073 -    for (i = 0; i < 2; i++) {
  2.1074 -        lintsrc.mpc_irqtype = linttypes[i];
  2.1075 -        lintsrc.mpc_destapiclint = i;
  2.1076 -        MP_lintsrc_info(&lintsrc);
  2.1077 -    }
  2.1078 +	lintsrc.mpc_type = MP_LINTSRC;
  2.1079 +	lintsrc.mpc_irqflag = 0;		/* conforming */
  2.1080 +	lintsrc.mpc_srcbusid = 0;
  2.1081 +	lintsrc.mpc_srcbusirq = 0;
  2.1082 +	lintsrc.mpc_destapic = MP_APIC_ALL;
  2.1083 +	for (i = 0; i < 2; i++) {
  2.1084 +		lintsrc.mpc_irqtype = linttypes[i];
  2.1085 +		lintsrc.mpc_destapiclint = i;
  2.1086 +		MP_lintsrc_info(&lintsrc);
  2.1087 +	}
  2.1088  }
  2.1089  
  2.1090  static struct intel_mp_floating *mpf_found;
  2.1091 +extern void 	config_acpi_tables(void);
  2.1092  
  2.1093  /*
  2.1094   * Scan the memory blocks for an SMP configuration block.
  2.1095   */
  2.1096  void __init get_smp_config (void)
  2.1097  {
  2.1098 -    struct intel_mp_floating *mpf = mpf_found;
  2.1099 +	struct intel_mp_floating *mpf = mpf_found;
  2.1100 +
  2.1101 +#ifdef CONFIG_X86_IO_APIC
  2.1102 +	/*
  2.1103 +	 * Check if the ACPI tables are provided. Use them only to get
  2.1104 +	 * the processor information, mainly because it provides
  2.1105 +	 * the info on the logical processor(s), rather than the physical
  2.1106 +	 * processor(s) that are provided by the MPS. We attempt to 
  2.1107 +	 * check only if the user provided a commandline override
  2.1108 +	 */
  2.1109 +	//XXX Xen config_acpi_tables();
  2.1110 +#endif
  2.1111  	
  2.1112 -    printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
  2.1113 -    if (mpf->mpf_feature2 & (1<<7)) {
  2.1114 -        printk("    IMCR and PIC compatibility mode.\n");
  2.1115 -        pic_mode = 1;
  2.1116 -    } else {
  2.1117 -        printk("    Virtual Wire compatibility mode.\n");
  2.1118 -        pic_mode = 0;
  2.1119 -    }
  2.1120 +	printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
  2.1121 +	if (mpf->mpf_feature2 & (1<<7)) {
  2.1122 +		printk("    IMCR and PIC compatibility mode.\n");
  2.1123 +		pic_mode = 1;
  2.1124 +	} else {
  2.1125 +		printk("    Virtual Wire compatibility mode.\n");
  2.1126 +		pic_mode = 0;
  2.1127 +	}
  2.1128  
  2.1129 -    /*
  2.1130 -     * Now see if we need to read further.
  2.1131 -     */
  2.1132 -    if (mpf->mpf_feature1 != 0) {
  2.1133 +	/*
  2.1134 +	 * Now see if we need to read further.
  2.1135 +	 */
  2.1136 +	if (mpf->mpf_feature1 != 0) {
  2.1137  
  2.1138 -        printk("Default MP configuration #%d\n", mpf->mpf_feature1);
  2.1139 -        construct_default_ISA_mptable(mpf->mpf_feature1);
  2.1140 +		printk("Default MP configuration #%d\n", mpf->mpf_feature1);
  2.1141 +		construct_default_ISA_mptable(mpf->mpf_feature1);
  2.1142  
  2.1143 -    } else if (mpf->mpf_physptr) {
  2.1144 +	} else if (mpf->mpf_physptr) {
  2.1145  
  2.1146 -        /*
  2.1147 -         * Read the physical hardware table.  Anything here will
  2.1148 -         * override the defaults.
  2.1149 -         */
  2.1150 -        if (!smp_read_mpc((void *)mpf->mpf_physptr)) {
  2.1151 -            smp_found_config = 0;
  2.1152 -            printk("BIOS bug, MP table errors detected!...\n");
  2.1153 -            printk("... disabling SMP support. (tell your hw vendor)\n");
  2.1154 -            return;
  2.1155 -        }
  2.1156 -        /*
  2.1157 -         * If there are no explicit MP IRQ entries, then we are
  2.1158 -         * broken.  We set up most of the low 16 IO-APIC pins to
  2.1159 -         * ISA defaults and hope it will work.
  2.1160 -         */
  2.1161 -        if (!mp_irq_entries) {
  2.1162 -            struct mpc_config_bus bus;
  2.1163 +		/*
  2.1164 +		 * Read the physical hardware table.  Anything here will
  2.1165 +		 * override the defaults.
  2.1166 +		 */
  2.1167 +		if (!smp_read_mpc((void *)mpf->mpf_physptr)) {
  2.1168 +			smp_found_config = 0;
  2.1169 +			printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
  2.1170 +			printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
  2.1171 +			return;
  2.1172 +		}
  2.1173 +		/*
  2.1174 +		 * If there are no explicit MP IRQ entries, then we are
  2.1175 +		 * broken.  We set up most of the low 16 IO-APIC pins to
  2.1176 +		 * ISA defaults and hope it will work.
  2.1177 +		 */
  2.1178 +		if (!mp_irq_entries) {
  2.1179 +			struct mpc_config_bus bus;
  2.1180  
  2.1181 -            printk("BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n");
  2.1182 +			printk("BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n");
  2.1183  
  2.1184 -            bus.mpc_type = MP_BUS;
  2.1185 -            bus.mpc_busid = 0;
  2.1186 -            memcpy(bus.mpc_bustype, "ISA   ", 6);
  2.1187 -            MP_bus_info(&bus);
  2.1188 +			bus.mpc_type = MP_BUS;
  2.1189 +			bus.mpc_busid = 0;
  2.1190 +			memcpy(bus.mpc_bustype, "ISA   ", 6);
  2.1191 +			MP_bus_info(&bus);
  2.1192  
  2.1193 -            construct_default_ioirq_mptable(0);
  2.1194 -        }
  2.1195 +			construct_default_ioirq_mptable(0);
  2.1196 +		}
  2.1197  
  2.1198 -    } else
  2.1199 -        BUG();
  2.1200 +	} else
  2.1201 +		BUG();
  2.1202  
  2.1203 -    printk("Processors: %d\n", num_processors);
  2.1204 -    /*
  2.1205 -     * Only use the first configuration found.
  2.1206 -     */
  2.1207 +	printk("Processors: %d\n", num_processors);
  2.1208 +	/*
  2.1209 +	 * Only use the first configuration found.
  2.1210 +	 */
  2.1211  }
  2.1212  
  2.1213  static int __init smp_scan_config (unsigned long base, unsigned long length)
  2.1214  {
  2.1215 -    unsigned long *bp = phys_to_virt(base);
  2.1216 -    struct intel_mp_floating *mpf;
  2.1217 +	unsigned long *bp = phys_to_virt(base);
  2.1218 +	struct intel_mp_floating *mpf;
  2.1219  
  2.1220 -    Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
  2.1221 -    if (sizeof(*mpf) != 16)
  2.1222 -        printk("Error: MPF size\n");
  2.1223 +	Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
  2.1224 +	if (sizeof(*mpf) != 16)
  2.1225 +		printk("Error: MPF size\n");
  2.1226  
  2.1227 -    while (length > 0) {
  2.1228 -        mpf = (struct intel_mp_floating *)bp;
  2.1229 -        if ((*bp == SMP_MAGIC_IDENT) &&
  2.1230 -            (mpf->mpf_length == 1) &&
  2.1231 -            !mpf_checksum((unsigned char *)bp, 16) &&
  2.1232 -            ((mpf->mpf_specification == 1)
  2.1233 -             || (mpf->mpf_specification == 4)) ) {
  2.1234 +	while (length > 0) {
  2.1235 +		mpf = (struct intel_mp_floating *)bp;
  2.1236 +		if ((*bp == SMP_MAGIC_IDENT) &&
  2.1237 +			(mpf->mpf_length == 1) &&
  2.1238 +			!mpf_checksum((unsigned char *)bp, 16) &&
  2.1239 +			((mpf->mpf_specification == 1)
  2.1240 +				|| (mpf->mpf_specification == 4)) ) {
  2.1241  
  2.1242 -            smp_found_config = 1;
  2.1243 -            printk("found SMP MP-table at %08lx\n",
  2.1244 -                   virt_to_phys(mpf));
  2.1245 -            reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE);
  2.1246 -            if (mpf->mpf_physptr)
  2.1247 -                reserve_bootmem(mpf->mpf_physptr, PAGE_SIZE);
  2.1248 -            mpf_found = mpf;
  2.1249 -            return 1;
  2.1250 -        }
  2.1251 -        bp += 4;
  2.1252 -        length -= 16;
  2.1253 -    }
  2.1254 -    return 0;
  2.1255 +			smp_found_config = 1;
  2.1256 +			printk("found SMP MP-table at %08lx\n",
  2.1257 +						virt_to_phys(mpf));
  2.1258 +			reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE);
  2.1259 +			if (mpf->mpf_physptr)
  2.1260 +				reserve_bootmem(mpf->mpf_physptr, PAGE_SIZE);
  2.1261 +			mpf_found = mpf;
  2.1262 +			return 1;
  2.1263 +		}
  2.1264 +		bp += 4;
  2.1265 +		length -= 16;
  2.1266 +	}
  2.1267 +	return 0;
  2.1268  }
  2.1269  
  2.1270  void __init find_intel_smp (void)
  2.1271  {
  2.1272 -    /*
  2.1273 -     * 1) Scan the bottom 1K for a signature
  2.1274 -     * 2) Scan the top 1K of base RAM
  2.1275 -     * 3) Scan the 64K of bios
  2.1276 -     */
  2.1277 -    if (smp_scan_config(0x0,0x400) ||
  2.1278 -        smp_scan_config(639*0x400,0x400) ||
  2.1279 -        smp_scan_config(0xF0000,0x10000))
  2.1280 -        return;
  2.1281 +	unsigned int address;
  2.1282 +
  2.1283 +	/*
  2.1284 +	 * FIXME: Linux assumes you have 640K of base ram..
  2.1285 +	 * this continues the error...
  2.1286 +	 *
  2.1287 +	 * 1) Scan the bottom 1K for a signature
  2.1288 +	 * 2) Scan the top 1K of base RAM
  2.1289 +	 * 3) Scan the 64K of bios
  2.1290 +	 */
  2.1291 +	if (smp_scan_config(0x0,0x400) ||
  2.1292 +		smp_scan_config(639*0x400,0x400) ||
  2.1293 +			smp_scan_config(0xF0000,0x10000))
  2.1294 +		return;
  2.1295 +	/*
  2.1296 +	 * If it is an SMP machine we should know now, unless the
  2.1297 +	 * configuration is in an EISA/MCA bus machine with an
  2.1298 +	 * extended bios data area.
  2.1299 +	 *
  2.1300 +	 * there is a real-mode segmented pointer pointing to the
  2.1301 +	 * 4K EBDA area at 0x40E, calculate and scan it here.
  2.1302 +	 *
  2.1303 +	 * NOTE! There were Linux loaders that will corrupt the EBDA
  2.1304 +	 * area, and as such this kind of SMP config may be less
  2.1305 +	 * trustworthy, simply because the SMP table may have been
  2.1306 +	 * stomped on during early boot.  Thankfully the bootloaders
  2.1307 +	 * now honour the EBDA.
  2.1308 +	 */
  2.1309 +
  2.1310 +	address = *(unsigned short *)phys_to_virt(0x40E);
  2.1311 +	address <<= 4;
  2.1312 +	smp_scan_config(address, 0x1000);
  2.1313  }
  2.1314  
  2.1315 +#else
  2.1316 +
  2.1317 +/*
  2.1318 + * The Visual Workstation is Intel MP compliant in the hardware
  2.1319 + * sense, but it doesn't have a BIOS(-configuration table).
  2.1320 + * No problem for Linux.
  2.1321 + */
  2.1322 +void __init find_visws_smp(void)
  2.1323 +{
  2.1324 +	smp_found_config = 1;
  2.1325 +
  2.1326 +	phys_cpu_present_map |= 2; /* or in id 1 */
  2.1327 +	apic_version[1] |= 0x10; /* integrated APIC */
  2.1328 +	apic_version[0] |= 0x10;
  2.1329 +
  2.1330 +	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
  2.1331 +}
  2.1332 +
  2.1333 +#endif
  2.1334 +
  2.1335  /*
  2.1336   * - Intel MP Configuration Table
  2.1337   * - or SGI Visual Workstation configuration
  2.1338   */
  2.1339  void __init find_smp_config (void)
  2.1340  {
  2.1341 -    find_intel_smp();
  2.1342 +#ifdef CONFIG_X86_LOCAL_APIC
  2.1343 +	find_intel_smp();
  2.1344 +#endif
  2.1345 +#ifdef CONFIG_VISWS
  2.1346 +	find_visws_smp();
  2.1347 +#endif
  2.1348  }
  2.1349  
     3.1 --- a/xen-2.4.16/drivers/net/Makefile	Thu Feb 13 11:03:29 2003 +0000
     3.2 +++ b/xen-2.4.16/drivers/net/Makefile	Thu Feb 13 14:51:10 2003 +0000
     3.3 @@ -4,7 +4,8 @@ include $(BASEDIR)/Rules.mk
     3.4  default: $(OBJS)
     3.5  	$(MAKE) -C ne
     3.6  	$(MAKE) -C tulip
     3.7 -	$(LD) -r -o driver.o $(OBJS) tulip/tulip.o ne/ne_drv.o
     3.8 +	$(MAKE) -C e1000
     3.9 +	$(LD) -r -o driver.o e1000/e1000.o $(OBJS) tulip/tulip.o ne/ne_drv.o
    3.10  
    3.11  clean:
    3.12  	$(MAKE) -C ne clean
     4.1 --- a/xen-2.4.16/drivers/net/e1000/e1000.h	Thu Feb 13 11:03:29 2003 +0000
     4.2 +++ b/xen-2.4.16/drivers/net/e1000/e1000.h	Thu Feb 13 14:51:10 2003 +0000
     4.3 @@ -77,14 +77,13 @@
     4.4  struct e1000_adapter;
     4.5  
     4.6  // XEN XXX
     4.7 -#define DBG 1
     4.8 +// #define DBG 1
     4.9  
    4.10  #include "e1000_hw.h"
    4.11  
    4.12  #if DBG
    4.13  #define E1000_DBG(args...) printk(KERN_DEBUG "e1000: " args)
    4.14  #else
    4.15 -XXX
    4.16  #define E1000_DBG(args...)
    4.17  #endif
    4.18  
     5.1 --- a/xen-2.4.16/drivers/net/e1000/e1000_hw.c	Thu Feb 13 11:03:29 2003 +0000
     5.2 +++ b/xen-2.4.16/drivers/net/e1000/e1000_hw.c	Thu Feb 13 14:51:10 2003 +0000
     5.3 @@ -1879,7 +1879,7 @@ e1000_read_phy_reg(struct e1000_hw *hw,
     5.4      uint32_t mdic = 0;
     5.5      const uint32_t phy_addr = 1;
     5.6  
     5.7 -    DEBUGFUNC("e1000_read_phy_reg");
     5.8 +    DEBUGFUNC("XXXXe1000_read_phy_reg");
     5.9  
    5.10      if(reg_addr > MAX_PHY_REG_ADDRESS) {
    5.11          DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
     6.1 --- a/xen-2.4.16/drivers/net/e1000/e1000_main.c	Thu Feb 13 11:03:29 2003 +0000
     6.2 +++ b/xen-2.4.16/drivers/net/e1000/e1000_main.c	Thu Feb 13 14:51:10 2003 +0000
     6.3 @@ -301,11 +301,9 @@ e1000_reset(struct e1000_adapter *adapte
     6.4  
     6.5  	adapter->hw.fc = adapter->hw.original_fc;
     6.6  	e1000_reset_hw(&adapter->hw);
     6.7 -printk("RESET_H/W\n");
     6.8  	if(adapter->hw.mac_type >= e1000_82544)
     6.9  		E1000_WRITE_REG(&adapter->hw, WUC, 0);
    6.10  	e1000_init_hw(&adapter->hw);
    6.11 -printk("INIT H/W\n");
    6.12  	e1000_reset_adaptive(&adapter->hw);
    6.13  	e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
    6.14  }
    6.15 @@ -470,14 +468,12 @@ e1000_probe(struct pci_dev *pdev,
    6.16  
    6.17  	printk(KERN_INFO "%s: %s\n", netdev->name, adapter->id_string);
    6.18  	e1000_check_options(adapter);
    6.19 -printk("OPTIONS OVER\n");
    6.20  	/* Initial Wake on LAN setting
    6.21  	 * If APM wake is enabled in the EEPROM,
    6.22  	 * enable the ACPI Magic Packet filter
    6.23  	 */
    6.24  
    6.25  	e1000_read_eeprom(&adapter->hw, EEPROM_INIT_CONTROL2_REG, &eeprom_data);
    6.26 -printk("EPROM OVER\n");
    6.27  	if((adapter->hw.mac_type >= e1000_82544) &&
    6.28  	   (eeprom_data & E1000_EEPROM_APME))
    6.29  		adapter->wol |= E1000_WUFC_MAG;
    6.30 @@ -485,7 +481,6 @@ printk("EPROM OVER\n");
    6.31  	/* reset the hardware with the new settings */
    6.32  
    6.33  	e1000_reset(adapter);
    6.34 -printk("PROBE OVER\n");
    6.35  	cards_found++;
    6.36  	return 0;
    6.37  
     7.1 --- a/xen-2.4.16/drivers/net/e1000/e1000_osdep.h	Thu Feb 13 11:03:29 2003 +0000
     7.2 +++ b/xen-2.4.16/drivers/net/e1000/e1000_osdep.h	Thu Feb 13 14:51:10 2003 +0000
     7.3 @@ -45,7 +45,7 @@
     7.4  #define msec_delay(x) {\
     7.5   	int s=jiffies+1+((x*HZ)/1000); \
     7.6  	printk("mdelay(%d) called -- spin\n",x); \
     7.7 -	while(jiffies<s); printk("mdelay over\n");}
     7.8 +	while(jiffies<s); }
     7.9  
    7.10  #if 0
    7.11  /********************  NOT in XEN ! *******/
    7.12 @@ -73,7 +73,7 @@ typedef enum {
    7.13  #define ASSERT(x)	if(!(x)) BUG()
    7.14  #define MSGOUT(S, A, B)	printk(KERN_DEBUG S "\n", A, B)
    7.15  
    7.16 -#define DBG 1
    7.17 +//#define DBG 1
    7.18  
    7.19  #if DBG
    7.20  #define DEBUGOUT(S)		printk(KERN_DEBUG S "\n")
     8.1 --- a/xen-2.4.16/include/asm-i386/apic.h	Thu Feb 13 11:03:29 2003 +0000
     8.2 +++ b/xen-2.4.16/include/asm-i386/apic.h	Thu Feb 13 14:51:10 2003 +0000
     8.3 @@ -1,9 +1,12 @@
     8.4  #ifndef __ASM_APIC_H
     8.5  #define __ASM_APIC_H
     8.6  
     8.7 +//#include <linux/config.h>
     8.8 +//#include <linux/pm.h>
     8.9 +#include <asm/apicdef.h>
    8.10  #include <asm/system.h>
    8.11 -#include <asm/ptrace.h>
    8.12 -#include <asm/apicdef.h>
    8.13 +
    8.14 +#ifdef CONFIG_X86_LOCAL_APIC
    8.15  
    8.16  #define APIC_DEBUG 0
    8.17  
    8.18 @@ -37,9 +40,15 @@ static __inline__ void apic_wait_icr_idl
    8.19  	do { } while ( apic_read( APIC_ICR ) & APIC_ICR_BUSY );
    8.20  }
    8.21  
    8.22 -#define FORCE_READ_AROUND_WRITE 0
    8.23 -#define apic_read_around(x)
    8.24 -#define apic_write_around(x,y) apic_write((x),(y))
    8.25 +#ifdef CONFIG_X86_GOOD_APIC
    8.26 +# define FORCE_READ_AROUND_WRITE 0
    8.27 +# define apic_read_around(x)
    8.28 +# define apic_write_around(x,y) apic_write((x),(y))
    8.29 +#else
    8.30 +# define FORCE_READ_AROUND_WRITE 1
    8.31 +# define apic_read_around(x) apic_read(x)
    8.32 +# define apic_write_around(x,y) apic_write_atomic((x),(y))
    8.33 +#endif
    8.34  
    8.35  static inline void ack_APIC_irq(void)
    8.36  {
    8.37 @@ -67,8 +76,24 @@ extern void setup_local_APIC (void);
    8.38  extern void init_apic_mappings (void);
    8.39  extern void smp_local_timer_interrupt (struct pt_regs * regs);
    8.40  extern void setup_APIC_clocks (void);
    8.41 +extern void setup_apic_nmi_watchdog (void);
    8.42 +extern inline void nmi_watchdog_tick (struct pt_regs * regs);
    8.43  extern int APIC_init_uniprocessor (void);
    8.44 +extern void disable_APIC_timer(void);
    8.45 +extern void enable_APIC_timer(void);
    8.46 +
    8.47 +//extern struct pm_dev *apic_pm_register(pm_dev_t, unsigned long, pm_callback);
    8.48 +//extern void apic_pm_unregister(struct pm_dev*);
    8.49  
    8.50  extern unsigned int apic_timer_irqs [NR_CPUS];
    8.51 +extern int check_nmi_watchdog (void);
    8.52 +
    8.53 +extern unsigned int nmi_watchdog;
    8.54 +#define NMI_NONE	0
    8.55 +#define NMI_IO_APIC	1
    8.56 +#define NMI_LOCAL_APIC	2
    8.57 +#define NMI_INVALID	3
    8.58 +
    8.59 +#endif /* CONFIG_X86_LOCAL_APIC */
    8.60  
    8.61  #endif /* __ASM_APIC_H */
     9.1 --- a/xen-2.4.16/include/asm-i386/apicdef.h	Thu Feb 13 11:03:29 2003 +0000
     9.2 +++ b/xen-2.4.16/include/asm-i386/apicdef.h	Thu Feb 13 14:51:10 2003 +0000
     9.3 @@ -32,6 +32,8 @@
     9.4  #define			SET_APIC_LOGICAL_ID(x)	(((x)<<24))
     9.5  #define			APIC_ALL_CPUS		0xFF
     9.6  #define		APIC_DFR	0xE0
     9.7 +#define			APIC_DFR_CLUSTER	0x0FFFFFFFul	/* Clustered */
     9.8 +#define			APIC_DFR_FLAT		0xFFFFFFFFul	/* Flat mode */
     9.9  #define		APIC_SPIV	0xF0
    9.10  #define			APIC_SPIV_FOCUS_DISABLED	(1<<9)
    9.11  #define			APIC_SPIV_APIC_ENABLED		(1<<8)
    9.12 @@ -57,6 +59,7 @@
    9.13  #define			APIC_INT_LEVELTRIG	0x08000
    9.14  #define			APIC_INT_ASSERT		0x04000
    9.15  #define			APIC_ICR_BUSY		0x01000
    9.16 +#define			APIC_DEST_PHYSICAL	0x00000
    9.17  #define			APIC_DEST_LOGICAL	0x00800
    9.18  #define			APIC_DM_FIXED		0x00000
    9.19  #define			APIC_DM_LOWEST		0x00100
    9.20 @@ -107,7 +110,19 @@
    9.21  
    9.22  #define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
    9.23  
    9.24 +#ifdef CONFIG_X86_CLUSTERED_APIC
    9.25 +#define MAX_IO_APICS 32
    9.26 +#else
    9.27  #define MAX_IO_APICS 8
    9.28 +#endif
    9.29 +
    9.30 +
    9.31 +/*
    9.32 + * The broadcast ID is 0xF for old APICs and 0xFF for xAPICs.  SAPICs
    9.33 + * don't broadcast (yet?), but if they did, they might use 0xFFFF.
    9.34 + */
    9.35 +#define APIC_BROADCAST_ID_XAPIC (0xFF)
    9.36 +#define APIC_BROADCAST_ID_APIC  (0x0F)
    9.37  
    9.38  /*
    9.39   * the local APIC register structure, memory mapped. Not terribly well
    10.1 --- a/xen-2.4.16/include/asm-i386/io_apic.h	Thu Feb 13 11:03:29 2003 +0000
    10.2 +++ b/xen-2.4.16/include/asm-i386/io_apic.h	Thu Feb 13 14:51:10 2003 +0000
    10.3 @@ -15,7 +15,8 @@
    10.4  #define APIC_MISMATCH_DEBUG
    10.5  
    10.6  #define IO_APIC_BASE(idx) \
    10.7 -		((volatile int *)__fix_to_virt(FIX_IO_APIC_BASE_0 + idx))
    10.8 +		((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \
    10.9 +		+ (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK)))
   10.10  
   10.11  /*
   10.12   * The structure of the IO-APIC:
   10.13 @@ -96,7 +97,7 @@ extern struct mpc_config_ioapic mp_ioapi
   10.14  extern int mp_irq_entries;
   10.15  
   10.16  /* MP IRQ source entries */
   10.17 -extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
   10.18 +extern struct mpc_config_intsrc *mp_irqs;
   10.19  
   10.20  /* non-0 if default (table-less) MP configuration */
   10.21  extern int mpc_default_type;
   10.22 @@ -132,8 +133,7 @@ static inline void io_apic_sync(unsigned
   10.23  }
   10.24  
   10.25  /* 1 if "noapic" boot option passed */
   10.26 -//extern int skip_ioapic_setup;
   10.27 -#define skip_ioapic_setup 0
   10.28 +extern int skip_ioapic_setup;
   10.29  
   10.30  /*
   10.31   * If we use the IO-APIC for IRQ routing, disable automatic
    11.1 --- a/xen-2.4.16/include/asm-i386/mpspec.h	Thu Feb 13 11:03:29 2003 +0000
    11.2 +++ b/xen-2.4.16/include/asm-i386/mpspec.h	Thu Feb 13 14:51:10 2003 +0000
    11.3 @@ -1,6 +1,7 @@
    11.4  #ifndef __ASM_MPSPEC_H
    11.5  #define __ASM_MPSPEC_H
    11.6  
    11.7 +
    11.8  /*
    11.9   * Structure definitions for SMP machines following the
   11.10   * Intel Multiprocessing Specification 1.1 and 1.4.
   11.11 @@ -13,8 +14,15 @@
   11.12   
   11.13  #define SMP_MAGIC_IDENT	(('_'<<24)|('P'<<16)|('M'<<8)|'_')
   11.14  
   11.15 -/* Maximum of 16 APICs with the current APIC ID architecture. */
   11.16 +/*
   11.17 + * a maximum of 16 APICs with the current APIC ID architecture.
   11.18 + * xAPICs can have up to 256.  SAPICs have 16 ID bits.
   11.19 + */
   11.20 +#ifdef CONFIG_X86_CLUSTERED_APIC
   11.21 +#define MAX_APICS 256
   11.22 +#else
   11.23  #define MAX_APICS 16
   11.24 +#endif
   11.25  
   11.26  #define MAX_MPC_ENTRY 1024
   11.27  
   11.28 @@ -178,7 +186,11 @@ struct mpc_config_translation
   11.29   *	7	2 CPU MCA+PCI
   11.30   */
   11.31  
   11.32 +#ifdef CONFIG_MULTIQUAD
   11.33 +#define MAX_IRQ_SOURCES 512
   11.34 +#else /* !CONFIG_MULTIQUAD */
   11.35  #define MAX_IRQ_SOURCES 256
   11.36 +#endif /* CONFIG_MULTIQUAD */
   11.37  
   11.38  #define MAX_MP_BUSSES 32
   11.39  enum mp_bustype {
   11.40 @@ -187,8 +199,11 @@ enum mp_bustype {
   11.41  	MP_BUS_PCI,
   11.42  	MP_BUS_MCA
   11.43  };
   11.44 -extern int mp_bus_id_to_type [MAX_MP_BUSSES];
   11.45 -extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
   11.46 +extern int *mp_bus_id_to_type;
   11.47 +extern int *mp_bus_id_to_node;
   11.48 +extern int *mp_bus_id_to_local;
   11.49 +extern int *mp_bus_id_to_pci_bus;
   11.50 +extern int quad_local_to_mp_bus_id [NR_CPUS/4][4];
   11.51  
   11.52  extern unsigned int boot_cpu_physical_apicid;
   11.53  extern unsigned long phys_cpu_present_map;
   11.54 @@ -197,11 +212,9 @@ extern void find_smp_config (void);
   11.55  extern void get_smp_config (void);
   11.56  extern int nr_ioapics;
   11.57  extern int apic_version [MAX_APICS];
   11.58 -extern int mp_bus_id_to_type [MAX_MP_BUSSES];
   11.59  extern int mp_irq_entries;
   11.60 -extern struct mpc_config_intsrc mp_irqs [MAX_IRQ_SOURCES];
   11.61 +extern struct mpc_config_intsrc *mp_irqs;
   11.62  extern int mpc_default_type;
   11.63 -extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
   11.64  extern int mp_current_pci_id;
   11.65  extern unsigned long mp_lapic_addr;
   11.66  extern int pic_mode;
    12.1 --- a/xen-2.4.16/include/asm-i386/smpboot.h	Thu Feb 13 11:03:29 2003 +0000
    12.2 +++ b/xen-2.4.16/include/asm-i386/smpboot.h	Thu Feb 13 14:51:10 2003 +0000
    12.3 @@ -1,13 +1,82 @@
    12.4  #ifndef __ASM_SMPBOOT_H
    12.5  #define __ASM_SMPBOOT_H
    12.6  
    12.7 -#define TRAMPOLINE_LOW phys_to_virt(0x467)
    12.8 -#define TRAMPOLINE_HIGH phys_to_virt(0x469)
    12.9 +/*emum for clustered_apic_mode values*/
   12.10 +enum{
   12.11 +	CLUSTERED_APIC_NONE = 0,
   12.12 +	CLUSTERED_APIC_XAPIC,
   12.13 +	CLUSTERED_APIC_NUMAQ
   12.14 +};
   12.15 +
   12.16 +#ifdef CONFIG_X86_CLUSTERED_APIC
   12.17 +extern unsigned int apic_broadcast_id;
   12.18 +extern unsigned char clustered_apic_mode;
   12.19 +extern unsigned char esr_disable;
   12.20 +extern unsigned char int_delivery_mode;
   12.21 +extern unsigned int int_dest_addr_mode;
   12.22 +extern int cyclone_setup(char*);
   12.23  
   12.24 -#define boot_cpu_apicid boot_cpu_physical_apicid
   12.25 +static inline void detect_clustered_apic(char* oem, char* prod)
   12.26 +{
   12.27 +	/*
   12.28 +	 * Can't recognize Summit xAPICs at present, so use the OEM ID.
   12.29 +	 */
   12.30 +	if (!strncmp(oem, "IBM ENSW", 8) && !strncmp(prod, "VIGIL SMP", 9)){
   12.31 +		clustered_apic_mode = CLUSTERED_APIC_XAPIC;
   12.32 +		apic_broadcast_id = APIC_BROADCAST_ID_XAPIC;
   12.33 +		int_dest_addr_mode = APIC_DEST_PHYSICAL;
   12.34 +		int_delivery_mode = dest_Fixed;
   12.35 +		esr_disable = 1;
   12.36 +		/*Start cyclone clock*/
   12.37 +		cyclone_setup(0);
   12.38 +	}
   12.39 +	else if (!strncmp(oem, "IBM NUMA", 8)){
   12.40 +		clustered_apic_mode = CLUSTERED_APIC_NUMAQ;
   12.41 +		apic_broadcast_id = APIC_BROADCAST_ID_APIC;
   12.42 +		int_dest_addr_mode = APIC_DEST_LOGICAL;
   12.43 +		int_delivery_mode = dest_LowestPrio;
   12.44 +		esr_disable = 1;
   12.45 +	}
   12.46 +}
   12.47 +#define	INT_DEST_ADDR_MODE (int_dest_addr_mode)
   12.48 +#define	INT_DELIVERY_MODE (int_delivery_mode)
   12.49 +#else /* CONFIG_X86_CLUSTERED_APIC */
   12.50 +#define apic_broadcast_id (APIC_BROADCAST_ID_APIC)
   12.51 +#define clustered_apic_mode (CLUSTERED_APIC_NONE)
   12.52 +#define esr_disable (0)
   12.53 +#define detect_clustered_apic(x,y)
   12.54 +#define INT_DEST_ADDR_MODE (APIC_DEST_LOGICAL)	/* logical delivery */
   12.55 +#define INT_DELIVERY_MODE (dest_LowestPrio)
   12.56 +#endif /* CONFIG_X86_CLUSTERED_APIC */
   12.57 +#define BAD_APICID 0xFFu
   12.58  
   12.59 -/* How to map from the cpu_present_map. */
   12.60 -#define cpu_present_to_apicid(apicid) (apicid)
   12.61 +#define TRAMPOLINE_LOW phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0x8:0x467)
   12.62 +#define TRAMPOLINE_HIGH phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0xa:0x469)
   12.63 +
   12.64 +#define boot_cpu_apicid ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?boot_cpu_logical_apicid:boot_cpu_physical_apicid)
   12.65 +
   12.66 +extern unsigned char raw_phys_apicid[NR_CPUS];
   12.67 +
   12.68 +/*
   12.69 + * How to map from the cpu_present_map
   12.70 + */
   12.71 +static inline int cpu_present_to_apicid(int mps_cpu)
   12.72 +{
   12.73 +	if (clustered_apic_mode == CLUSTERED_APIC_XAPIC)
   12.74 +		return raw_phys_apicid[mps_cpu];
   12.75 +	if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
   12.76 +		return (mps_cpu/4)*16 + (1<<(mps_cpu%4));
   12.77 +	return mps_cpu;
   12.78 +}
   12.79 +
   12.80 +static inline unsigned long apicid_to_phys_cpu_present(int apicid)
   12.81 +{
   12.82 +	if(clustered_apic_mode)
   12.83 +		return 1UL << (((apicid >> 4) << 2) + (apicid & 0x3));
   12.84 +	return 1UL << apicid;
   12.85 +}
   12.86 +
   12.87 +#define physical_to_logical_apicid(phys_apic) ( (1ul << (phys_apic & 0x3)) | (phys_apic & 0xF0u) )
   12.88  
   12.89  /*
   12.90   * Mappings between logical cpu number and logical / physical apicid
   12.91 @@ -22,7 +91,31 @@ extern volatile int cpu_2_physical_apici
   12.92  #define cpu_to_logical_apicid(cpu) cpu_2_logical_apicid[cpu]
   12.93  #define physical_apicid_to_cpu(apicid) physical_apicid_2_cpu[apicid]
   12.94  #define cpu_to_physical_apicid(cpu) cpu_2_physical_apicid[cpu]
   12.95 +#ifdef CONFIG_MULTIQUAD			/* use logical IDs to bootstrap */
   12.96 +#define boot_apicid_to_cpu(apicid) logical_apicid_2_cpu[apicid]
   12.97 +#define cpu_to_boot_apicid(cpu) cpu_2_logical_apicid[cpu]
   12.98 +#else /* !CONFIG_MULTIQUAD */		/* use physical IDs to bootstrap */
   12.99  #define boot_apicid_to_cpu(apicid) physical_apicid_2_cpu[apicid]
  12.100  #define cpu_to_boot_apicid(cpu) cpu_2_physical_apicid[cpu]
  12.101 +#endif /* CONFIG_MULTIQUAD */
  12.102  
  12.103 +#ifdef CONFIG_X86_CLUSTERED_APIC
  12.104 +static inline int target_cpus(void)
  12.105 +{
  12.106 +	static int cpu;
  12.107 +	switch(clustered_apic_mode){
  12.108 +		case CLUSTERED_APIC_NUMAQ:
  12.109 +			/* Broadcast intrs to local quad only. */
  12.110 +			return APIC_BROADCAST_ID_APIC;
  12.111 +		case CLUSTERED_APIC_XAPIC:
  12.112 +			/*round robin the interrupts*/
  12.113 +			cpu = (cpu+1)%smp_num_cpus;
  12.114 +			return cpu_to_physical_apicid(cpu);
  12.115 +		default:
  12.116 +	}
  12.117 +	return cpu_online_map;
  12.118 +}
  12.119 +#else
  12.120 +#define target_cpus() (0x01)
  12.121  #endif
  12.122 +#endif