aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-05-25 17:29:20 +0000
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-05-25 17:29:20 +0000
commit7cd2aeee943e69146bd5965b7160d4a461d94fd4 (patch)
treec3b2643b0baafe8ef0005cc2dcd6f8d30011dfdc
parent5443ed833b79b2e3da48bf203bd2707f31c349e8 (diff)
downloadxen-7cd2aeee943e69146bd5965b7160d4a461d94fd4.tar.gz
xen-7cd2aeee943e69146bd5965b7160d4a461d94fd4.tar.bz2
xen-7cd2aeee943e69146bd5965b7160d4a461d94fd4.zip
bitkeeper revision 1.1555 (4294b5f0B3iu-SnB9loIMnLXO0loTA)
Ported genapic to Xen: support for bigsmp and numa platforms such as es7000. Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r--.rootkeys38
-rw-r--r--xen/arch/x86/Makefile2
-rw-r--r--xen/arch/x86/Rules.mk4
-rw-r--r--xen/arch/x86/apic.c3
-rw-r--r--xen/arch/x86/dmi_scan.c493
-rw-r--r--xen/arch/x86/genapic/bigsmp.c51
-rw-r--r--xen/arch/x86/genapic/default.c26
-rw-r--r--xen/arch/x86/genapic/es7000.c28
-rw-r--r--xen/arch/x86/genapic/es7000.h110
-rw-r--r--xen/arch/x86/genapic/es7000plat.c302
-rw-r--r--xen/arch/x86/genapic/probe.c101
-rw-r--r--xen/arch/x86/genapic/summit.c26
-rw-r--r--xen/arch/x86/mpparse.c2
-rw-r--r--xen/arch/x86/mtrr/generic.c1
-rw-r--r--xen/arch/x86/setup.c15
-rw-r--r--xen/arch/x86/smp.c74
-rw-r--r--xen/arch/x86/smpboot.c1
-rw-r--r--xen/common/kernel.c56
-rw-r--r--xen/include/asm-x86/apic.h1
-rw-r--r--xen/include/asm-x86/fixmap.h11
-rw-r--r--xen/include/asm-x86/genapic.h115
-rw-r--r--xen/include/asm-x86/mach-bigsmp/mach_apic.h167
-rw-r--r--xen/include/asm-x86/mach-bigsmp/mach_apicdef.h13
-rw-r--r--xen/include/asm-x86/mach-bigsmp/mach_ipi.h25
-rw-r--r--xen/include/asm-x86/mach-default/apm.h75
-rw-r--r--xen/include/asm-x86/mach-default/do_timer.h85
-rw-r--r--xen/include/asm-x86/mach-default/entry_arch.h34
-rw-r--r--xen/include/asm-x86/mach-default/irq_vectors_limits.h16
-rw-r--r--xen/include/asm-x86/mach-default/mach_mpspec.h8
-rw-r--r--xen/include/asm-x86/mach-default/mach_reboot.h30
-rw-r--r--xen/include/asm-x86/mach-default/mach_time.h122
-rw-r--r--xen/include/asm-x86/mach-default/mach_timer.h48
-rw-r--r--xen/include/asm-x86/mach-default/mach_traps.h29
-rw-r--r--xen/include/asm-x86/mach-default/pci-functions.h19
-rw-r--r--xen/include/asm-x86/mach-default/setup_arch_post.h40
-rw-r--r--xen/include/asm-x86/mach-default/setup_arch_pre.h5
-rw-r--r--xen/include/asm-x86/mach-es7000/mach_apic.h207
-rw-r--r--xen/include/asm-x86/mach-es7000/mach_apicdef.h13
-rw-r--r--xen/include/asm-x86/mach-es7000/mach_ipi.h24
-rw-r--r--xen/include/asm-x86/mach-es7000/mach_mpparse.h41
-rw-r--r--xen/include/asm-x86/mach-es7000/mach_wakecpu.h58
-rw-r--r--xen/include/asm-x86/mach-generic/mach_apic.h32
-rw-r--r--xen/include/asm-x86/mach-generic/mach_apicdef.h11
-rw-r--r--xen/include/asm-x86/mach-generic/mach_ipi.h10
-rw-r--r--xen/include/asm-x86/mach-generic/mach_mpparse.h12
-rw-r--r--xen/include/asm-x86/mach-generic/mach_mpspec.h10
-rw-r--r--xen/include/asm-x86/mach-summit/mach_apic.h189
-rw-r--r--xen/include/asm-x86/mach-summit/mach_apicdef.h13
-rw-r--r--xen/include/asm-x86/mach-summit/mach_ipi.h25
-rw-r--r--xen/include/asm-x86/mach-summit/mach_mpparse.h121
-rw-r--r--xen/include/asm-x86/page.h12
-rw-r--r--xen/include/asm-x86/shadow.h1
-rw-r--r--xen/include/asm-x86/system.h2
-rw-r--r--xen/include/xen/dmi.h47
54 files changed, 2418 insertions, 586 deletions
diff --git a/.rootkeys b/.rootkeys
index 0e2535c7f5..93567d5df2 100644
--- a/.rootkeys
+++ b/.rootkeys
@@ -1131,12 +1131,20 @@
40e42bdbNu4MjI750THP_8J1S-Sa0g xen/arch/x86/boot/x86_64.S
4107c15e-VmEcLsE-7JCXZaabI8C7A xen/arch/x86/cdb.c
3ddb79bcUrk2EIaM5VsT6wUudH1kkg xen/arch/x86/delay.c
+4294b5ee34eGSh5YNDKMSxBIOycluw xen/arch/x86/dmi_scan.c
40e34414WiQO4h2m3tcpaCPn7SyYyg xen/arch/x86/dom0_ops.c
3ddb79bc1_2bAt67x9MFCP4AZrQnvQ xen/arch/x86/domain.c
4202391dkvdTZ8GhWXe3Gqf9EOgWXg xen/arch/x86/domain_build.c
41d3eaae6GSDo3ZJDfK3nvQsJux-PQ xen/arch/x86/e820.c
3ddb79bcY5zW7KhvI9gvfuPi3ZumEg xen/arch/x86/extable.c
3fe443fdDDb0Sw6NQBCk4GQapayfTA xen/arch/x86/flushtlb.c
+4294b5ee0qd8iX0Z4a6XpmbS-7r9CQ xen/arch/x86/genapic/bigsmp.c
+4294b5eeRyEW29Ue9ykTGCgG4PD2OQ xen/arch/x86/genapic/default.c
+4294b5eeGvaKRkeAfnvIbNqPn__sLA xen/arch/x86/genapic/es7000.c
+4294b5eezzXwm3k_PG72kjEidxESjA xen/arch/x86/genapic/es7000.h
+4294b5eeUsoC73al4Bsg2E1NKy0oYQ xen/arch/x86/genapic/es7000plat.c
+4294b5ee8T56zBzx90toTSftqiKoVA xen/arch/x86/genapic/probe.c
+4294b5ee2PhCf6SsLxck58bGLR8hYA xen/arch/x86/genapic/summit.c
3ddb79bcesE5E-lS4QhRhlqXxqj9cA xen/arch/x86/i387.c
3ddb79bcCAq6IpdkHueChoVTfXqEQQ xen/arch/x86/i8259.c
3ddb79bcBit4xJXbwtX0kb1hh2uO1Q xen/arch/x86/idle0_task.c
@@ -1289,6 +1297,7 @@
41d3eaaeIBzW621S1oa0c2yk7X43qQ xen/include/asm-x86/e820.h
3ddb79c3NU8Zy40OTrq3D-i30Y3t4A xen/include/asm-x86/fixmap.h
3e2d29944GI24gf7vOP_7x8EyuqxeA xen/include/asm-x86/flushtlb.h
+4294b5eep4lWuDtYUR74gYwt-_FnHA xen/include/asm-x86/genapic.h
3ddb79c39o75zPP0T1aQQ4mNrCAN2w xen/include/asm-x86/hardirq.h
3ddb79c3TMDjkxVndKFKnGiwY0HzDg xen/include/asm-x86/i387.h
4204e7acwXDo-5iAAiO2eQbtDeYZXA xen/include/asm-x86/init.h
@@ -1296,10 +1305,10 @@
3ddb79c2TKeScYHQZreTdHqYNLbehQ xen/include/asm-x86/io_apic.h
3ddb79c2L7rTlFzazOLW1XuSZefpFw xen/include/asm-x86/irq.h
404f1b93OjLO4bFfBXYNaJdIqlNz-Q xen/include/asm-x86/ldt.h
-427fa2d0m8MOSSXT13zgb-q0fGA_Dw xen/include/asm-x86/mach-default/apm.h
+4294b5eeeAE-U0umBauOpcfs9bOixw xen/include/asm-x86/mach-bigsmp/mach_apic.h
+4294b5ee5qY2lHkA2hcNVFnZkHBVQw xen/include/asm-x86/mach-bigsmp/mach_apicdef.h
+4294b5eeq6ore4EePanoutorWtvS1w xen/include/asm-x86/mach-bigsmp/mach_ipi.h
427fa2d0suK9Av7vsAXhsQxZjqpc_Q xen/include/asm-x86/mach-default/bios_ebda.h
-427fa2d0yC3KzLozoeK3Xa3uGVfIdw xen/include/asm-x86/mach-default/do_timer.h
-427fa2d0bWQkR1mW5OBYxn07AN-bDw xen/include/asm-x86/mach-default/entry_arch.h
427fa2d0-SWcuwbdSypo4953bc2JdQ xen/include/asm-x86/mach-default/io_ports.h
427fa2d0eyAl7LAeO-SVV4IW7lZPGQ xen/include/asm-x86/mach-default/irq_vectors.h
427fa2d0df7VWG4KKpnKbKR2Cbd1_w xen/include/asm-x86/mach-default/irq_vectors_limits.h
@@ -1307,16 +1316,22 @@
427fa2d0I3FWjE2tWdOhlEOJn7stcg xen/include/asm-x86/mach-default/mach_apicdef.h
427fa2d093fDS2gOBLcl7Yndzl7HmA xen/include/asm-x86/mach-default/mach_ipi.h
427fa2d0Y7bD35d-FvDAeiJDIdRw2A xen/include/asm-x86/mach-default/mach_mpparse.h
-427fa2d0aLQgE9e1GY9ZP5jrMOC8pQ xen/include/asm-x86/mach-default/mach_mpspec.h
-427fa2d0fJ5nNn5ydJuOaZIL6F2fjQ xen/include/asm-x86/mach-default/mach_reboot.h
-427fa2d0VlN555TE68TjKMsrOoFXNA xen/include/asm-x86/mach-default/mach_time.h
-427fa2d0C0jWTKYjy7WJjGKeujSpSg xen/include/asm-x86/mach-default/mach_timer.h
-427fa2d0UXLiS1scpNrK26ZT6Oes3g xen/include/asm-x86/mach-default/mach_traps.h
427fa2d0OfglYyfpDTD5DII4M0uZRw xen/include/asm-x86/mach-default/mach_wakecpu.h
-427fa2d0_OBPxdi5Qo04JWgZhz7BFA xen/include/asm-x86/mach-default/pci-functions.h
-427fa2d0mrTtXrliqDfLuJc5LLVXaA xen/include/asm-x86/mach-default/setup_arch_post.h
-427fa2d0Uoo7gC61Kep6Yy7Os367Hg xen/include/asm-x86/mach-default/setup_arch_pre.h
427fa2d1EKnA8zCq2QLHiGOUqOgszg xen/include/asm-x86/mach-default/smpboot_hooks.h
+4294b5eeTwL8TeEI5pEzxvGD5obZsA xen/include/asm-x86/mach-es7000/mach_apic.h
+4294b5efhhBHJ81dsuLfJxWuN9PcDQ xen/include/asm-x86/mach-es7000/mach_apicdef.h
+4294b5efvb29X4mFAhUBdeGUPTFoBw xen/include/asm-x86/mach-es7000/mach_ipi.h
+4294b5efLlV3WvmctnQsCPAte4Bf6A xen/include/asm-x86/mach-es7000/mach_mpparse.h
+4294b5efC90I55FIDtKg8jyW8FVffA xen/include/asm-x86/mach-es7000/mach_wakecpu.h
+4294b5efqI--HHz7d7QVcVOi635jgw xen/include/asm-x86/mach-generic/mach_apic.h
+4294b5efHFX7nHDP4ch4NGAPmCsp_w xen/include/asm-x86/mach-generic/mach_apicdef.h
+4294b5efaen_warQx_kSN54AgXgBtg xen/include/asm-x86/mach-generic/mach_ipi.h
+4294b5efq7CDZzdxl-Rxu2K_6cIePQ xen/include/asm-x86/mach-generic/mach_mpparse.h
+4294b5efsEtawAifmsBZAjFagr8Z6Q xen/include/asm-x86/mach-generic/mach_mpspec.h
+4294b5efz5xMcRrYJfcH-wTylihXMA xen/include/asm-x86/mach-summit/mach_apic.h
+4294b5efmKbMzT7YOGp4Jn-5xoB3Uw xen/include/asm-x86/mach-summit/mach_apicdef.h
+4294b5efyUK3aZFqxp7BVF_GXCx56g xen/include/asm-x86/mach-summit/mach_ipi.h
+4294b5efjw2vUbiP4dQX6S6xZvAmZA xen/include/asm-x86/mach-summit/mach_mpparse.h
3ddb79c3I98vWcQR8xEo34JMJ4Ahyw xen/include/asm-x86/mc146818rtc.h
40ec25fd7cSvbP7Biw91zaU_g0xsEQ xen/include/asm-x86/mm.h
3ddb79c3n_UbPuxlkNxvvLycClIkxA xen/include/asm-x86/mpspec.h
@@ -1388,6 +1403,7 @@
427fa2d1bQCWgEQqTTh5MjG4MPEH9g xen/include/xen/cpumask.h
3ddb79c1V44RD26YqCUm-kqIupM37A xen/include/xen/ctype.h
3ddb79c05DdHQ0UxX_jKsXdR4QlMCA xen/include/xen/delay.h
+4294b5efxcDdUVp4XMEE__IFw7nPow xen/include/xen/dmi.h
40f2b4a2hC3HtChu-ArD8LyojxWMjg xen/include/xen/domain.h
3ddb79c2O729EttZTYu1c8LcsUO_GQ xen/include/xen/elf.h
3ddb79c0HIghfBF8zFUdmXhOU8i6hA xen/include/xen/errno.h
diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index dfc64ddf9c..3978f2ea06 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -5,6 +5,7 @@ OBJS += $(patsubst %.S,%.o,$(wildcard $(TARGET_SUBARCH)/*.S))
OBJS += $(patsubst %.c,%.o,$(wildcard $(TARGET_SUBARCH)/*.c))
OBJS += $(patsubst %.c,%.o,$(wildcard acpi/*.c))
OBJS += $(patsubst %.c,%.o,$(wildcard mtrr/*.c))
+OBJS += $(patsubst %.c,%.o,$(wildcard genapic/*.c))
OBJS := $(subst $(TARGET_SUBARCH)/asm-offsets.o,,$(OBJS))
@@ -36,6 +37,7 @@ clean:
rm -f x86_64/*.o x86_64/*~ x86_64/core
rm -f mtrr/*.o mtrr/*~ mtrr/core
rm -f acpi/*.o acpi/*~ acpi/core
+ rm -f genapic/*.o genapic/*~ genapic/core
delete-unfresh-files:
# nothing
diff --git a/xen/arch/x86/Rules.mk b/xen/arch/x86/Rules.mk
index f21be04704..647640797d 100644
--- a/xen/arch/x86/Rules.mk
+++ b/xen/arch/x86/Rules.mk
@@ -3,7 +3,9 @@
CFLAGS += -nostdinc -fno-builtin -fno-common -fno-strict-aliasing
CFLAGS += -iwithprefix include -Wall -Werror -Wno-pointer-arith -pipe
-CFLAGS += -I$(BASEDIR)/include -I$(BASEDIR)/include/asm-x86/mach-default
+CFLAGS += -I$(BASEDIR)/include
+CFLAGS += -I$(BASEDIR)/include/asm-x86/mach-generic
+CFLAGS += -I$(BASEDIR)/include/asm-x86/mach-default
ifeq ($(optimize),y)
CFLAGS += -O3 -fomit-frame-pointer
diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c
index 86bdb6253c..9857365074 100644
--- a/xen/arch/x86/apic.c
+++ b/xen/arch/x86/apic.c
@@ -454,9 +454,6 @@ static void __init apic_set_verbosity(char *str)
apic_verbosity = APIC_DEBUG;
else if (strcmp("verbose", str) == 0)
apic_verbosity = APIC_VERBOSE;
- else
- printk(KERN_WARNING "APIC Verbosity level %s not recognised"
- " use apic=verbose or apic=debug", str);
}
custom_param("apic", apic_set_verbosity);
diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c
new file mode 100644
index 0000000000..06f8c15a96
--- /dev/null
+++ b/xen/arch/x86/dmi_scan.c
@@ -0,0 +1,493 @@
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/kernel.h>
+#include <xen/string.h>
+#include <xen/init.h>
+#include <xen/slab.h>
+#include <xen/acpi.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <xen/dmi.h>
+
+#define bt_ioremap(b,l) __acpi_map_table(b,l)
+#define bt_iounmap(b,l) ((void)0)
+#define ioremap(b,l) (__va(b))
+#define memcpy_fromio memcpy
+#define alloc_bootmem(l) xmalloc_bytes(l)
+
+int es7000_plat = 0;
+
+struct dmi_header
+{
+ u8 type;
+ u8 length;
+ u16 handle;
+};
+
+#undef DMI_DEBUG
+
+#ifdef DMI_DEBUG
+#define dmi_printk(x) printk x
+#else
+#define dmi_printk(x)
+#endif
+
+static char * __init dmi_string(struct dmi_header *dm, u8 s)
+{
+ u8 *bp=(u8 *)dm;
+ bp+=dm->length;
+ if(!s)
+ return "";
+ s--;
+ while(s>0 && *bp)
+ {
+ bp+=strlen(bp);
+ bp++;
+ s--;
+ }
+ return bp;
+}
+
+/*
+ * We have to be cautious here. We have seen BIOSes with DMI pointers
+ * pointing to completely the wrong place for example
+ */
+
+static int __init dmi_table(u32 base, int len, int num, void (*decode)(struct dmi_header *))
+{
+ u8 *buf;
+ struct dmi_header *dm;
+ u8 *data;
+ int i=0;
+
+ buf = bt_ioremap(base, len);
+ if(buf==NULL)
+ return -1;
+
+ data = buf;
+
+ /*
+ * Stop when we see all the items the table claimed to have
+ * OR we run off the end of the table (also happens)
+ */
+
+ while(i<num && data-buf+sizeof(struct dmi_header)<=len)
+ {
+ dm=(struct dmi_header *)data;
+ /*
+ * We want to know the total length (formated area and strings)
+ * before decoding to make sure we won't run off the table in
+ * dmi_decode or dmi_string
+ */
+ data+=dm->length;
+ while(data-buf<len-1 && (data[0] || data[1]))
+ data++;
+ if(data-buf<len-1)
+ decode(dm);
+ data+=2;
+ i++;
+ }
+ bt_iounmap(buf, len);
+ return 0;
+}
+
+
+inline static int __init dmi_checksum(u8 *buf)
+{
+ u8 sum=0;
+ int a;
+
+ for(a=0; a<15; a++)
+ sum+=buf[a];
+ return (sum==0);
+}
+
+static int __init dmi_iterate(void (*decode)(struct dmi_header *))
+{
+ u8 buf[15];
+ char __iomem *p, *q;
+
+ /*
+ * no iounmap() for that ioremap(); it would be a no-op, but it's
+ * so early in setup that sucker gets confused into doing what
+ * it shouldn't if we actually call it.
+ */
+ p = ioremap(0xF0000, 0x10000);
+ if (p == NULL)
+ return -1;
+ for (q = p; q < p + 0x10000; q += 16) {
+ memcpy_fromio(buf, q, 15);
+ if(memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf))
+ {
+ u16 num=buf[13]<<8|buf[12];
+ u16 len=buf[7]<<8|buf[6];
+ u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8];
+
+ /*
+ * DMI version 0.0 means that the real version is taken from
+ * the SMBIOS version, which we don't know at this point.
+ */
+ if(buf[14]!=0)
+ printk(KERN_INFO "DMI %d.%d present.\n",
+ buf[14]>>4, buf[14]&0x0F);
+ else
+ printk(KERN_INFO "DMI present.\n");
+ dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n",
+ num, len));
+ dmi_printk((KERN_INFO "DMI table at 0x%08X.\n",
+ base));
+ if(dmi_table(base,len, num, decode)==0)
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static char *dmi_ident[DMI_STRING_MAX];
+
+/*
+ * Save a DMI string
+ */
+
+static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
+{
+ char *d = (char*)dm;
+ char *p = dmi_string(dm, d[string]);
+ if(p==NULL || *p == 0)
+ return;
+ if (dmi_ident[slot])
+ return;
+ dmi_ident[slot] = alloc_bootmem(strlen(p)+1);
+ if(dmi_ident[slot])
+ strcpy(dmi_ident[slot], p);
+ else
+ printk(KERN_ERR "dmi_save_ident: out of memory.\n");
+}
+
+/*
+ * Ugly compatibility crap.
+ */
+#define dmi_blacklist dmi_system_id
+#define NO_MATCH { DMI_NONE, NULL}
+#define MATCH DMI_MATCH
+
+/*
+ * Toshiba keyboard likes to repeat keys when they are not repeated.
+ */
+
+static __init int broken_toshiba_keyboard(struct dmi_blacklist *d)
+{
+ printk(KERN_WARNING "Toshiba with broken keyboard detected. If your keyboard sometimes generates 3 keypresses instead of one, see http://davyd.ucc.asn.au/projects/toshiba/README\n");
+ return 0;
+}
+
+
+#ifdef CONFIG_ACPI_SLEEP
+static __init int reset_videomode_after_s3(struct dmi_blacklist *d)
+{
+ /* See acpi_wakeup.S */
+ extern long acpi_video_flags;
+ acpi_video_flags |= 2;
+ return 0;
+}
+#endif
+
+
+#ifdef CONFIG_ACPI_BOOT
+extern int acpi_force;
+
+static __init __attribute__((unused)) int dmi_disable_acpi(struct dmi_blacklist *d)
+{
+ if (!acpi_force) {
+ printk(KERN_NOTICE "%s detected: acpi off\n",d->ident);
+ disable_acpi();
+ } else {
+ printk(KERN_NOTICE
+ "Warning: DMI blacklist says broken, but acpi forced\n");
+ }
+ return 0;
+}
+
+/*
+ * Limit ACPI to CPU enumeration for HT
+ */
+static __init __attribute__((unused)) int force_acpi_ht(struct dmi_blacklist *d)
+{
+ if (!acpi_force) {
+ printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident);
+ disable_acpi();
+ acpi_ht = 1;
+ } else {
+ printk(KERN_NOTICE
+ "Warning: acpi=force overrules DMI blacklist: acpi=ht\n");
+ }
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_ACPI_PCI
+static __init int disable_acpi_irq(struct dmi_blacklist *d)
+{
+ if (!acpi_force) {
+ printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n",
+ d->ident);
+ acpi_noirq_set();
+ }
+ return 0;
+}
+static __init int disable_acpi_pci(struct dmi_blacklist *d)
+{
+ if (!acpi_force) {
+ printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n",
+ d->ident);
+ acpi_disable_pci();
+ }
+ return 0;
+}
+#endif
+
+/*
+ * Process the DMI blacklists
+ */
+
+
+/*
+ * This will be expanded over time to force things like the APM
+ * interrupt mask settings according to the laptop
+ */
+
+static __initdata struct dmi_blacklist dmi_blacklist[]={
+
+ { broken_toshiba_keyboard, "Toshiba Satellite 4030cdt", { /* Keyboard generates spurious repeats */
+ MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
+ NO_MATCH, NO_MATCH, NO_MATCH
+ } },
+#ifdef CONFIG_ACPI_SLEEP
+ { reset_videomode_after_s3, "Toshiba Satellite 4030cdt", { /* Reset video mode after returning from ACPI S3 sleep */
+ MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
+ NO_MATCH, NO_MATCH, NO_MATCH
+ } },
+#endif
+
+#ifdef CONFIG_ACPI_BOOT
+ /*
+ * If your system is blacklisted here, but you find that acpi=force
+ * works for you, please contact acpi-devel@sourceforge.net
+ */
+
+ /*
+ * Boxes that need ACPI disabled
+ */
+
+ { dmi_disable_acpi, "IBM Thinkpad", {
+ MATCH(DMI_BOARD_VENDOR, "IBM"),
+ MATCH(DMI_BOARD_NAME, "2629H1G"),
+ NO_MATCH, NO_MATCH }},
+
+ /*
+ * Boxes that need acpi=ht
+ */
+
+ { force_acpi_ht, "FSC Primergy T850", {
+ MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "DELL GX240", {
+ MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
+ MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "HP VISUALIZE NT Workstation", {
+ MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+ MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "Compaq Workstation W8000", {
+ MATCH(DMI_SYS_VENDOR, "Compaq"),
+ MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "ASUS P4B266", {
+ MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ MATCH(DMI_BOARD_NAME, "P4B266"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "ASUS P2B-DS", {
+ MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ MATCH(DMI_BOARD_NAME, "P2B-DS"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "ASUS CUR-DLS", {
+ MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ MATCH(DMI_BOARD_NAME, "CUR-DLS"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "ABIT i440BX-W83977", {
+ MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
+ MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "IBM Bladecenter", {
+ MATCH(DMI_BOARD_VENDOR, "IBM"),
+ MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "IBM eServer xSeries 360", {
+ MATCH(DMI_BOARD_VENDOR, "IBM"),
+ MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "IBM eserver xSeries 330", {
+ MATCH(DMI_BOARD_VENDOR, "IBM"),
+ MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "IBM eserver xSeries 440", {
+ MATCH(DMI_BOARD_VENDOR, "IBM"),
+ MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
+ NO_MATCH, NO_MATCH }},
+
+#endif // CONFIG_ACPI_BOOT
+
+#ifdef CONFIG_ACPI_PCI
+ /*
+ * Boxes that need ACPI PCI IRQ routing disabled
+ */
+
+ { disable_acpi_irq, "ASUS A7V", {
+ MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
+ MATCH(DMI_BOARD_NAME, "<A7V>"),
+ /* newer BIOS, Revision 1011, does work */
+ MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"),
+ NO_MATCH }},
+
+ /*
+ * Boxes that need ACPI PCI IRQ routing and PCI scan disabled
+ */
+ { disable_acpi_pci, "ASUS PR-DLS", { /* _BBN 0 bug */
+ MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ MATCH(DMI_BOARD_NAME, "PR-DLS"),
+ MATCH(DMI_BIOS_VERSION, "ASUS PR-DLS ACPI BIOS Revision 1010"),
+ MATCH(DMI_BIOS_DATE, "03/21/2003") }},
+
+ { disable_acpi_pci, "Acer TravelMate 36x Laptop", {
+ MATCH(DMI_SYS_VENDOR, "Acer"),
+ MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
+ NO_MATCH, NO_MATCH
+ } },
+
+#endif
+
+ { NULL, }
+};
+
+/*
+ * Process a DMI table entry. Right now all we care about are the BIOS
+ * and machine entries. For 2.5 we should pull the smbus controller info
+ * out of here.
+ */
+
+static void __init dmi_decode(struct dmi_header *dm)
+{
+#ifdef DMI_DEBUG
+ u8 *data = (u8 *)dm;
+#endif
+
+ switch(dm->type)
+ {
+ case 0:
+ dmi_printk(("BIOS Vendor: %s\n",
+ dmi_string(dm, data[4])));
+ dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
+ dmi_printk(("BIOS Version: %s\n",
+ dmi_string(dm, data[5])));
+ dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
+ dmi_printk(("BIOS Release: %s\n",
+ dmi_string(dm, data[8])));
+ dmi_save_ident(dm, DMI_BIOS_DATE, 8);
+ break;
+ case 1:
+ dmi_printk(("System Vendor: %s\n",
+ dmi_string(dm, data[4])));
+ dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
+ dmi_printk(("Product Name: %s\n",
+ dmi_string(dm, data[5])));
+ dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
+ dmi_printk(("Version: %s\n",
+ dmi_string(dm, data[6])));
+ dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
+ dmi_printk(("Serial Number: %s\n",
+ dmi_string(dm, data[7])));
+ break;
+ case 2:
+ dmi_printk(("Board Vendor: %s\n",
+ dmi_string(dm, data[4])));
+ dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
+ dmi_printk(("Board Name: %s\n",
+ dmi_string(dm, data[5])));
+ dmi_save_ident(dm, DMI_BOARD_NAME, 5);
+ dmi_printk(("Board Version: %s\n",
+ dmi_string(dm, data[6])));
+ dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
+ break;
+ }
+}
+
+void __init dmi_scan_machine(void)
+{
+ int err = dmi_iterate(dmi_decode);
+ if(err == 0)
+ dmi_check_system(dmi_blacklist);
+ else
+ printk(KERN_INFO "DMI not present.\n");
+}
+
+
+/**
+ * dmi_check_system - check system DMI data
+ * @list: array of dmi_system_id structures to match against
+ *
+ * Walk the blacklist table running matching functions until someone
+ * returns non zero or we hit the end. Callback function is called for
+ * each successfull match. Returns the number of matches.
+ */
+int dmi_check_system(struct dmi_system_id *list)
+{
+ int i, count = 0;
+ struct dmi_system_id *d = list;
+
+ while (d->ident) {
+ for (i = 0; i < ARRAY_SIZE(d->matches); i++) {
+ int s = d->matches[i].slot;
+ if (s == DMI_NONE)
+ continue;
+ if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr))
+ continue;
+ /* No match */
+ goto fail;
+ }
+ if (d->callback && d->callback(d))
+ break;
+ count++;
+fail: d++;
+ }
+
+ return count;
+}
+
+EXPORT_SYMBOL(dmi_check_system);
+
+/**
+ * dmi_get_system_info - return DMI data value
+ * @field: data index (see enum dmi_filed)
+ *
+ * Returns one DMI data value, can be used to perform
+ * complex DMI data checks.
+ */
+char * dmi_get_system_info(int field)
+{
+ return dmi_ident[field];
+}
+
+EXPORT_SYMBOL(dmi_get_system_info);
diff --git a/xen/arch/x86/genapic/bigsmp.c b/xen/arch/x86/genapic/bigsmp.c
new file mode 100644
index 0000000000..1984b64825
--- /dev/null
+++ b/xen/arch/x86/genapic/bigsmp.c
@@ -0,0 +1,51 @@
+/*
+ * APIC driver for "bigsmp" XAPIC machines with more than 8 virtual CPUs.
+ * Drives the local APIC in "clustered mode".
+ */
+#define APIC_DEFINITION 1
+#include <xen/config.h>
+#include <xen/cpumask.h>
+#include <asm/mpspec.h>
+#include <asm/genapic.h>
+#include <asm/fixmap.h>
+#include <asm/apicdef.h>
+#include <xen/kernel.h>
+#include <xen/smp.h>
+#include <xen/init.h>
+#include <xen/dmi.h>
+#include <asm/mach-bigsmp/mach_apic.h>
+#include <asm/mach-bigsmp/mach_apicdef.h>
+#include <asm/mach-bigsmp/mach_ipi.h>
+#include <asm/mach-default/mach_mpparse.h>
+
+static int dmi_bigsmp; /* can be set by dmi scanners */
+
+static __init int hp_ht_bigsmp(struct dmi_system_id *d)
+{
+ printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident);
+ dmi_bigsmp = 1;
+ return 0;
+}
+
+
+static struct dmi_system_id __initdata bigsmp_dmi_table[] = {
+ { hp_ht_bigsmp, "HP ProLiant DL760 G2", {
+ DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
+ DMI_MATCH(DMI_BIOS_VERSION, "P44-"),
+ }},
+
+ { hp_ht_bigsmp, "HP ProLiant DL740", {
+ DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
+ DMI_MATCH(DMI_BIOS_VERSION, "P47-"),
+ }},
+ { }
+};
+
+
+static __init int probe_bigsmp(void)
+{
+ dmi_check_system(bigsmp_dmi_table);
+ return dmi_bigsmp;
+}
+
+struct genapic apic_bigsmp = APIC_INIT("bigsmp", probe_bigsmp);
diff --git a/xen/arch/x86/genapic/default.c b/xen/arch/x86/genapic/default.c
new file mode 100644
index 0000000000..2fe4da78ea
--- /dev/null
+++ b/xen/arch/x86/genapic/default.c
@@ -0,0 +1,26 @@
+/*
+ * Default generic APIC driver. This handles upto 8 CPUs.
+ */
+#define APIC_DEFINITION 1
+#include <xen/config.h>
+#include <xen/cpumask.h>
+#include <asm/mpspec.h>
+#include <asm/mach-default/mach_apicdef.h>
+#include <asm/genapic.h>
+#include <asm/fixmap.h>
+#include <asm/apicdef.h>
+#include <xen/kernel.h>
+#include <xen/string.h>
+#include <xen/smp.h>
+#include <xen/init.h>
+#include <asm/mach-default/mach_apic.h>
+#include <asm/mach-default/mach_ipi.h>
+#include <asm/mach-default/mach_mpparse.h>
+
+/* should be called last. */
+static __init int probe_default(void)
+{
+ return 1;
+}
+
+struct genapic apic_default = APIC_INIT("default", probe_default);
diff --git a/xen/arch/x86/genapic/es7000.c b/xen/arch/x86/genapic/es7000.c
new file mode 100644
index 0000000000..9e68384863
--- /dev/null
+++ b/xen/arch/x86/genapic/es7000.c
@@ -0,0 +1,28 @@
+/*
+ * APIC driver for the Unisys ES7000 chipset.
+ */
+#define APIC_DEFINITION 1
+#include <xen/config.h>
+#include <xen/cpumask.h>
+#include <asm/mpspec.h>
+#include <asm/genapic.h>
+#include <asm/fixmap.h>
+#include <asm/apicdef.h>
+#include <asm/atomic.h>
+#include <xen/kernel.h>
+#include <xen/string.h>
+#include <xen/smp.h>
+#include <xen/init.h>
+#include <asm/mach-es7000/mach_apicdef.h>
+#include <asm/mach-es7000/mach_apic.h>
+#include <asm/mach-es7000/mach_ipi.h>
+#include <asm/mach-es7000/mach_mpparse.h>
+#include <asm/mach-es7000/mach_wakecpu.h>
+
+static __init int probe_es7000(void)
+{
+ /* probed later in mptable/ACPI hooks */
+ return 0;
+}
+
+struct genapic apic_es7000 = APIC_INIT("es7000", probe_es7000);
diff --git a/xen/arch/x86/genapic/es7000.h b/xen/arch/x86/genapic/es7000.h
new file mode 100644
index 0000000000..70691f0c4c
--- /dev/null
+++ b/xen/arch/x86/genapic/es7000.h
@@ -0,0 +1,110 @@
+/*
+ * Written by: Garry Forsgren, Unisys Corporation
+ * Natalie Protasevich, Unisys Corporation
+ * This file contains the code to configure and interface
+ * with Unisys ES7000 series hardware system manager.
+ *
+ * Copyright (c) 2003 Unisys Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Unisys Corporation, Township Line & Union Meeting
+ * Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or:
+ *
+ * http://www.unisys.com
+ */
+
+#define MIP_REG 1
+#define MIP_PSAI_REG 4
+
+#define MIP_BUSY 1
+#define MIP_SPIN 0xf0000
+#define MIP_VALID 0x0100000000000000ULL
+#define MIP_PORT(VALUE) ((VALUE >> 32) & 0xffff)
+
+#define MIP_RD_LO(VALUE) (VALUE & 0xffffffff)
+
+struct mip_reg_info {
+ unsigned long long mip_info;
+ unsigned long long delivery_info;
+ unsigned long long host_reg;
+ unsigned long long mip_reg;
+};
+
+struct part_info {
+ unsigned char type;
+ unsigned char length;
+ unsigned char part_id;
+ unsigned char apic_mode;
+ unsigned long snum;
+ char ptype[16];
+ char sname[64];
+ char pname[64];
+};
+
+struct psai {
+ unsigned long long entry_type;
+ unsigned long long addr;
+ unsigned long long bep_addr;
+};
+
+struct es7000_mem_info {
+ unsigned char type;
+ unsigned char length;
+ unsigned char resv[6];
+ unsigned long long start;
+ unsigned long long size;
+};
+
+struct es7000_oem_table {
+ unsigned long long hdr;
+ struct mip_reg_info mip;
+ struct part_info pif;
+ struct es7000_mem_info shm;
+ struct psai psai;
+};
+
+struct acpi_table_sdt {
+ unsigned long pa;
+ unsigned long count;
+ struct {
+ unsigned long pa;
+ enum acpi_table_id id;
+ unsigned long size;
+ } entry[50];
+};
+
+struct oem_table {
+ struct acpi_table_header Header;
+ u32 OEMTableAddr;
+ u32 OEMTableSize;
+};
+
+struct mip_reg {
+ unsigned long long off_0;
+ unsigned long long off_8;
+ unsigned long long off_10;
+ unsigned long long off_18;
+ unsigned long long off_20;
+ unsigned long long off_28;
+ unsigned long long off_30;
+ unsigned long long off_38;
+};
+
+#define MIP_SW_APIC 0x1020b
+#define MIP_FUNC(VALUE) (VALUE & 0xff)
+
+extern int parse_unisys_oem (char *oemptr, int oem_entries);
+extern int find_unisys_acpi_oem_table(unsigned long *oem_addr, int *length);
+extern int es7000_start_cpu(int cpu, unsigned long eip);
+extern void es7000_sw_apic(void);
diff --git a/xen/arch/x86/genapic/es7000plat.c b/xen/arch/x86/genapic/es7000plat.c
new file mode 100644
index 0000000000..58cc0bf610
--- /dev/null
+++ b/xen/arch/x86/genapic/es7000plat.c
@@ -0,0 +1,302 @@
+/*
+ * Written by: Garry Forsgren, Unisys Corporation
+ * Natalie Protasevich, Unisys Corporation
+ * This file contains the code to configure and interface
+ * with Unisys ES7000 series hardware system manager.
+ *
+ * Copyright (c) 2003 Unisys Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Unisys Corporation, Township Line & Union Meeting
+ * Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or:
+ *
+ * http://www.unisys.com
+ */
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/kernel.h>
+#include <xen/smp.h>
+#include <xen/string.h>
+#include <xen/spinlock.h>
+#include <xen/errno.h>
+#include <xen/reboot.h>
+#include <xen/init.h>
+#include <xen/acpi.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/apicdef.h>
+#include "es7000.h"
+
+/*
+ * ES7000 Globals
+ */
+
+volatile unsigned long *psai = NULL;
+struct mip_reg *mip_reg;
+struct mip_reg *host_reg;
+int mip_port;
+unsigned long mip_addr, host_addr;
+
+#if defined(CONFIG_X86_IO_APIC) && (defined(CONFIG_ACPI_INTERPRETER) || defined(CONFIG_ACPI_BOOT))
+
+/*
+ * GSI override for ES7000 platforms.
+ */
+
+static unsigned int base;
+
+static int
+es7000_rename_gsi(int ioapic, int gsi)
+{
+ if (!base) {
+ int i;
+ for (i = 0; i < nr_ioapics; i++)
+ base += nr_ioapic_registers[i];
+ }
+
+ if (!ioapic && (gsi < 16))
+ gsi += base;
+ return gsi;
+}
+
+#endif // (CONFIG_X86_IO_APIC) && (CONFIG_ACPI_INTERPRETER || CONFIG_ACPI_BOOT)
+
+/*
+ * Parse the OEM Table
+ */
+
+int __init
+parse_unisys_oem (char *oemptr, int oem_entries)
+{
+ int i;
+ int success = 0;
+ unsigned char type, size;
+ unsigned long val;
+ char *tp = NULL;
+ struct psai *psaip = NULL;
+ struct mip_reg_info *mi;
+ struct mip_reg *host, *mip;
+
+ tp = oemptr;
+
+ tp += 8;
+
+ for (i=0; i <= oem_entries; i++) {
+ type = *tp++;
+ size = *tp++;
+ tp -= 2;
+ switch (type) {
+ case MIP_REG:
+ mi = (struct mip_reg_info *)tp;
+ val = MIP_RD_LO(mi->host_reg);
+ host_addr = val;
+ host = (struct mip_reg *)val;
+ host_reg = __va(host);
+ val = MIP_RD_LO(mi->mip_reg);
+ mip_port = MIP_PORT(mi->mip_info);
+ mip_addr = val;
+ mip = (struct mip_reg *)val;
+ mip_reg = __va(mip);
+ Dprintk("es7000_mipcfg: host_reg = 0x%lx \n",
+ (unsigned long)host_reg);
+ Dprintk("es7000_mipcfg: mip_reg = 0x%lx \n",
+ (unsigned long)mip_reg);
+ success++;
+ break;
+ case MIP_PSAI_REG:
+ psaip = (struct psai *)tp;
+ if (tp != NULL) {
+ if (psaip->addr)
+ psai = __va(psaip->addr);
+ else
+ psai = NULL;
+ success++;
+ }
+ break;
+ default:
+ break;
+ }
+ if (i == 6) break;
+ tp += size;
+ }
+
+ if (success < 2) {
+ es7000_plat = 0;
+ } else {
+ printk("\nEnabling ES7000 specific features...\n");
+ es7000_plat = 1;
+ ioapic_renumber_irq = es7000_rename_gsi;
+ }
+ return es7000_plat;
+}
+
+int __init
+find_unisys_acpi_oem_table(unsigned long *oem_addr, int *length)
+{
+ struct acpi_table_rsdp *rsdp = NULL;
+ unsigned long rsdp_phys = 0;
+ struct acpi_table_header *header = NULL;
+ int i;
+ struct acpi_table_sdt sdt;
+
+ rsdp_phys = acpi_find_rsdp();
+ rsdp = __va(rsdp_phys);
+ if (rsdp->rsdt_address) {
+ struct acpi_table_rsdt *mapped_rsdt = NULL;
+ sdt.pa = rsdp->rsdt_address;
+
+ header = (struct acpi_table_header *)
+ __acpi_map_table(sdt.pa, sizeof(struct acpi_table_header));
+ if (!header)
+ return -ENODEV;
+
+ sdt.count = (header->length - sizeof(struct acpi_table_header)) >> 3;
+ mapped_rsdt = (struct acpi_table_rsdt *)
+ __acpi_map_table(sdt.pa, header->length);
+ if (!mapped_rsdt)
+ return -ENODEV;
+
+ header = &mapped_rsdt->header;
+
+ for (i = 0; i < sdt.count; i++)
+ sdt.entry[i].pa = (unsigned long) mapped_rsdt->entry[i];
+ };
+ for (i = 0; i < sdt.count; i++) {
+
+ header = (struct acpi_table_header *)
+ __acpi_map_table(sdt.entry[i].pa,
+ sizeof(struct acpi_table_header));
+ if (!header)
+ continue;
+ if (!strncmp((char *) &header->signature, "OEM1", 4)) {
+ if (!strncmp((char *) &header->oem_id, "UNISYS", 6)) {
+ void *addr;
+ struct oem_table *t;
+ acpi_table_print(header, sdt.entry[i].pa);
+ t = (struct oem_table *) __acpi_map_table(sdt.entry[i].pa, header->length);
+ addr = (void *) __acpi_map_table(t->OEMTableAddr, t->OEMTableSize);
+ *length = header->length;
+ *oem_addr = (unsigned long) addr;
+ return 0;
+ }
+ }
+ }
+ Dprintk("ES7000: did not find Unisys ACPI OEM table!\n");
+ return -1;
+}
+
+static void
+es7000_spin(int n)
+{
+ int i = 0;
+
+ while (i++ < n)
+ rep_nop();
+}
+
+static int __init
+es7000_mip_write(struct mip_reg *mip_reg)
+{
+ int status = 0;
+ int spin;
+
+ spin = MIP_SPIN;
+ while (((unsigned long long)host_reg->off_38 &
+ (unsigned long long)MIP_VALID) != 0) {
+ if (--spin <= 0) {
+ printk("es7000_mip_write: Timeout waiting for Host Valid Flag");
+ return -1;
+ }
+ es7000_spin(MIP_SPIN);
+ }
+
+ memcpy(host_reg, mip_reg, sizeof(struct mip_reg));
+ outb(1, mip_port);
+
+ spin = MIP_SPIN;
+
+ while (((unsigned long long)mip_reg->off_38 &
+ (unsigned long long)MIP_VALID) == 0) {
+ if (--spin <= 0) {
+ printk("es7000_mip_write: Timeout waiting for MIP Valid Flag");
+ return -1;
+ }
+ es7000_spin(MIP_SPIN);
+ }
+
+ status = ((unsigned long long)mip_reg->off_0 &
+ (unsigned long long)0xffff0000000000ULL) >> 48;
+ mip_reg->off_38 = ((unsigned long long)mip_reg->off_38 &
+ (unsigned long long)~MIP_VALID);
+ return status;
+}
+
+int
+es7000_start_cpu(int cpu, unsigned long eip)
+{
+ unsigned long vect = 0, psaival = 0;
+
+ if (psai == NULL)
+ return -1;
+
+ vect = ((unsigned long)__pa(eip)/0x1000) << 16;
+ psaival = (0x1000000 | vect | cpu);
+
+ while (*psai & 0x1000000)
+ ;
+
+ *psai = psaival;
+
+ return 0;
+
+}
+
+int
+es7000_stop_cpu(int cpu)
+{
+ int startup;
+
+ if (psai == NULL)
+ return -1;
+
+ startup= (0x1000000 | cpu);
+
+ while ((*psai & 0xff00ffff) != startup)
+ ;
+
+ startup = (*psai & 0xff0000) >> 16;
+ *psai &= 0xffffff;
+
+ return 0;
+
+}
+
+void __init
+es7000_sw_apic()
+{
+ if (es7000_plat) {
+ int mip_status;
+ struct mip_reg es7000_mip_reg;
+
+ printk("ES7000: Enabling APIC mode.\n");
+ memset(&es7000_mip_reg, 0, sizeof(struct mip_reg));
+ es7000_mip_reg.off_0 = MIP_SW_APIC;
+ es7000_mip_reg.off_38 = (MIP_VALID);
+ while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0)
+ printk("es7000_sw_apic: command failed, status = %x\n",
+ mip_status);
+ return;
+ }
+}
diff --git a/xen/arch/x86/genapic/probe.c b/xen/arch/x86/genapic/probe.c
new file mode 100644
index 0000000000..9645f46654
--- /dev/null
+++ b/xen/arch/x86/genapic/probe.c
@@ -0,0 +1,101 @@
+/* Copyright 2003 Andi Kleen, SuSE Labs.
+ * Subject to the GNU Public License, v.2
+ *
+ * Generic x86 APIC driver probe layer.
+ */
+#include <xen/config.h>
+#include <xen/cpumask.h>
+#include <xen/string.h>
+#include <xen/kernel.h>
+#include <xen/ctype.h>
+#include <xen/init.h>
+#include <asm/fixmap.h>
+#include <asm/mpspec.h>
+#include <asm/apicdef.h>
+#include <asm/genapic.h>
+
+extern struct genapic apic_summit;
+extern struct genapic apic_bigsmp;
+extern struct genapic apic_es7000;
+extern struct genapic apic_default;
+
+struct genapic *genapic = &apic_default;
+
+struct genapic *apic_probe[] __initdata = {
+ &apic_summit,
+ &apic_bigsmp,
+ &apic_es7000,
+ &apic_default, /* must be last */
+ NULL,
+};
+
+void __init generic_apic_probe(char *command_line)
+{
+ char *s;
+ int i;
+ int changed = 0;
+
+ s = strstr(command_line, "apic=");
+ if (s && (s == command_line || isspace(s[-1]))) {
+ char *p = strchr(s, ' '), old;
+ if (!p)
+ p = strchr(s, '\0');
+ old = *p;
+ *p = 0;
+ for (i = 0; !changed && apic_probe[i]; i++) {
+ if (!strcmp(apic_probe[i]->name, s+5)) {
+ changed = 1;
+ genapic = apic_probe[i];
+ }
+ }
+ if (!changed)
+ printk(KERN_ERR "Unknown genapic `%s' specified.\n", s);
+ *p = old;
+ }
+ for (i = 0; !changed && apic_probe[i]; i++) {
+ if (apic_probe[i]->probe()) {
+ changed = 1;
+ genapic = apic_probe[i];
+ }
+ }
+ /* Not visible without early console */
+ if (!changed)
+ panic("Didn't find an APIC driver");
+
+ printk(KERN_INFO "Using APIC driver %s\n", genapic->name);
+}
+
+/* These functions can switch the APIC even after the initial ->probe() */
+
+int __init mps_oem_check(struct mp_config_table *mpc, char *oem, char *productid)
+{
+ int i;
+ for (i = 0; apic_probe[i]; ++i) {
+ if (apic_probe[i]->mps_oem_check(mpc,oem,productid)) {
+ genapic = apic_probe[i];
+ printk(KERN_INFO "Switched to APIC driver `%s'.\n",
+ genapic->name);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+ int i;
+ for (i = 0; apic_probe[i]; ++i) {
+ if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) {
+ genapic = apic_probe[i];
+ printk(KERN_INFO "Switched to APIC driver `%s'.\n",
+ genapic->name);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int hard_smp_processor_id(void)
+{
+ return genapic->get_apic_id(*(unsigned long *)(APIC_BASE+APIC_ID));
+}
diff --git a/xen/arch/x86/genapic/summit.c b/xen/arch/x86/genapic/summit.c
new file mode 100644
index 0000000000..bbca9d8632
--- /dev/null
+++ b/xen/arch/x86/genapic/summit.c
@@ -0,0 +1,26 @@
+/*
+ * APIC driver for the IBM "Summit" chipset.
+ */
+#define APIC_DEFINITION 1
+#include <xen/config.h>
+#include <xen/cpumask.h>
+#include <asm/mpspec.h>
+#include <asm/genapic.h>
+#include <asm/fixmap.h>
+#include <asm/apicdef.h>
+#include <xen/kernel.h>
+#include <xen/string.h>
+#include <xen/smp.h>
+#include <xen/init.h>
+#include <asm/mach-summit/mach_apic.h>
+#include <asm/mach-summit/mach_apicdef.h>
+#include <asm/mach-summit/mach_ipi.h>
+#include <asm/mach-summit/mach_mpparse.h>
+
+static __init int probe_summit(void)
+{
+ /* probed later in mptable/ACPI hooks */
+ return 0;
+}
+
+struct genapic apic_summit = APIC_INIT("summit", probe_summit);
diff --git a/xen/arch/x86/mpparse.c b/xen/arch/x86/mpparse.c
index 83d93ef3e6..234b14106f 100644
--- a/xen/arch/x86/mpparse.c
+++ b/xen/arch/x86/mpparse.c
@@ -33,8 +33,6 @@
#include <mach_mpparse.h>
#include <bios_ebda.h>
-#define es7000_plat 0 /* XXX XEN */
-
/* Have we found an MP table */
int smp_found_config;
unsigned int __initdata maxcpus = NR_CPUS;
diff --git a/xen/arch/x86/mtrr/generic.c b/xen/arch/x86/mtrr/generic.c
index 4834266fbe..899069acf4 100644
--- a/xen/arch/x86/mtrr/generic.c
+++ b/xen/arch/x86/mtrr/generic.c
@@ -3,6 +3,7 @@
#include <xen/init.h>
#include <xen/mm.h>
#include <xen/slab.h>
+#include <asm/flushtlb.h>
#include <asm/io.h>
#include <asm/mtrr.h>
#include <asm/msr.h>
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 7fcadad2d7..0751594777 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -20,6 +20,9 @@
#include <asm/shadow.h>
#include <asm/e820.h>
+extern void dmi_scan_machine(void);
+extern void generic_apic_probe(char *);
+
/*
* opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
* pfn_info table and allocation bitmap.
@@ -64,6 +67,8 @@ boolean_param("acpi_skip_timer_override", acpi_skip_timer_override);
extern int skip_ioapic_setup;
boolean_param("noapic", skip_ioapic_setup);
+static char *xen_cmdline;
+
int early_boot = 1;
int ht_per_core = 1;
@@ -422,6 +427,11 @@ static void __init start_of_day(void)
paging_init();
+ dmi_scan_machine();
+
+ if ( xen_cmdline != NULL )
+ generic_apic_probe(xen_cmdline);
+
acpi_boot_table_init();
acpi_boot_init();
@@ -488,7 +498,10 @@ void __init __start_xen(multiboot_info_t *mbi)
/* Parse the command-line options. */
if ( (mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0) )
- cmdline_parse(__va(mbi->cmdline));
+ {
+ xen_cmdline = __va(mbi->cmdline);
+ cmdline_parse(xen_cmdline);
+ }
/* Must do this early -- e.g., spinlocks rely on get_current(). */
set_current(&idle0_exec_domain);
diff --git a/xen/arch/x86/smp.c b/xen/arch/x86/smp.c
index 71b565e097..9598ff2e93 100644
--- a/xen/arch/x86/smp.c
+++ b/xen/arch/x86/smp.c
@@ -19,6 +19,7 @@
#include <asm/flushtlb.h>
#include <asm/smpboot.h>
#include <asm/hardirq.h>
+#include <mach_apic.h>
/*
* Some notes on x86 processor bugs affecting SMP operation:
@@ -72,7 +73,7 @@ static inline int __prepare_ICR2 (unsigned int mask)
return SET_APIC_DEST_FIELD(mask);
}
-static inline void __send_IPI_shortcut(unsigned int shortcut, int vector)
+void __send_IPI_shortcut(unsigned int shortcut, int vector)
{
/*
* Subtle. In the case of the 'never do double writes' workaround
@@ -104,8 +105,12 @@ void send_IPI_self(int vector)
__send_IPI_shortcut(APIC_DEST_SELF, vector);
}
-static inline void send_IPI_mask(int mask, int vector)
+/*
+ * This is only used on smaller machines.
+ */
+void send_IPI_mask_bitmask(cpumask_t cpumask, int vector)
{
+ unsigned long mask = cpus_addr(cpumask)[0];
unsigned long cfg;
unsigned long flags;
@@ -115,38 +120,69 @@ static inline void send_IPI_mask(int mask, int vector)
* Wait for idle.
*/
apic_wait_icr_idle();
-
+
/*
* prepare target chip field
*/
cfg = __prepare_ICR2(mask);
apic_write_around(APIC_ICR2, cfg);
-
+
/*
- * program the ICR
+ * program the ICR
*/
cfg = __prepare_ICR(0, vector);
-
+
/*
* Send the IPI. The write to APIC_ICR fires this off.
*/
apic_write_around(APIC_ICR, cfg);
-
+
local_irq_restore(flags);
}
-static inline void send_IPI_allbutself(int vector)
+inline void send_IPI_mask_sequence(cpumask_t mask, int vector)
{
+ unsigned long cfg, flags;
+ unsigned int query_cpu;
+
/*
- * If there are no other CPUs in the system then we get an APIC send error
- * if we try to broadcast. thus we have to avoid sending IPIs in this case.
- */
- if ( num_online_cpus() <= 1 )
- return;
+ * Hack. The clustered APIC addressing mode doesn't allow us to send
+ * to an arbitrary mask, so I do a unicasts to each CPU instead. This
+ * should be modified to do 1 message per cluster ID - mbligh
+ */
+
+ local_irq_save(flags);
- __send_IPI_shortcut(APIC_DEST_ALLBUT, vector);
+ for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) {
+ if (cpu_isset(query_cpu, mask)) {
+
+ /*
+ * Wait for idle.
+ */
+ apic_wait_icr_idle();
+
+ /*
+ * prepare target chip field
+ */
+ cfg = __prepare_ICR2(cpu_to_logical_apicid(query_cpu));
+ apic_write_around(APIC_ICR2, cfg);
+
+ /*
+ * program the ICR
+ */
+ cfg = __prepare_ICR(0, vector);
+
+ /*
+ * Send the IPI. The write to APIC_ICR fires this off.
+ */
+ apic_write_around(APIC_ICR, cfg);
+ }
+ }
+ local_irq_restore(flags);
}
+#include <mach_ipi.h>
+
static spinlock_t flush_lock = SPIN_LOCK_UNLOCKED;
static unsigned long flush_cpumask, flush_va;
@@ -179,7 +215,11 @@ void __flush_tlb_mask(unsigned long mask, unsigned long va)
spin_lock(&flush_lock);
flush_cpumask = mask;
flush_va = va;
- send_IPI_mask(mask, INVALIDATE_TLB_VECTOR);
+ {
+ cpumask_t _mask;
+ cpus_addr(_mask)[0] = mask;
+ send_IPI_mask(_mask, INVALIDATE_TLB_VECTOR);
+ }
while ( flush_cpumask != 0 )
cpu_relax();
spin_unlock(&flush_lock);
@@ -222,9 +262,11 @@ void flush_tlb_all_pge(void)
void smp_send_event_check_mask(unsigned long cpu_mask)
{
+ cpumask_t mask;
cpu_mask &= ~(1UL << smp_processor_id());
+ cpus_addr(mask)[0] = cpu_mask;
if ( cpu_mask != 0 )
- send_IPI_mask(cpu_mask, EVENT_CHECK_VECTOR);
+ send_IPI_mask(mask, EVENT_CHECK_VECTOR);
}
/*
diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
index 5b43462e50..b4a1ffb894 100644
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -43,6 +43,7 @@
#include <asm/mc146818rtc.h>
#include <asm/desc.h>
#include <asm/div64.h>
+#include <asm/flushtlb.h>
#include <asm/msr.h>
#include <mach_apic.h>
#include <mach_wakecpu.h>
diff --git a/xen/common/kernel.c b/xen/common/kernel.c
index 46d63901da..d577cbc2a0 100644
--- a/xen/common/kernel.c
+++ b/xen/common/kernel.c
@@ -16,55 +16,65 @@
void cmdline_parse(char *cmdline)
{
- char *opt_end, *opt;
+ char opt[100], *optval, *p = cmdline, *q;
struct kernel_param *param;
- if ( cmdline == NULL )
+ if ( p == NULL )
return;
- while ( *cmdline == ' ' )
- cmdline++;
- cmdline = strchr(cmdline, ' '); /* skip the image name */
- while ( cmdline != NULL )
+ /* Skip whitespace and the image name. */
+ while ( *p == ' ' )
+ p++;
+ if ( (p = strchr(p, ' ')) == NULL )
+ return;
+
+ for ( ; ; )
{
- while ( *cmdline == ' ' )
- cmdline++;
- if ( *cmdline == '\0' )
+ /* Skip whitespace. */
+ while ( *p == ' ' )
+ p++;
+ if ( *p == '\0' )
break;
- opt_end = strchr(cmdline, ' ');
- if ( opt_end != NULL )
- *opt_end++ = '\0';
- opt = strchr(cmdline, '=');
- if ( opt != NULL )
- *opt++ = '\0';
+
+ /* Grab the next whitespace-delimited option. */
+ q = opt;
+ while ( (*p != ' ') && (*p != '\0') )
+ *q++ = *p++;
+ *q = '\0';
+
+ /* Search for value part of a key=value option. */
+ optval = strchr(opt, '=');
+ if ( optval != NULL )
+ *optval++ = '\0';
+
for ( param = &__setup_start; param != &__setup_end; param++ )
{
- if ( strcmp(param->name, cmdline ) != 0 )
+ if ( strcmp(param->name, opt ) != 0 )
continue;
+
switch ( param->type )
{
case OPT_STR:
- if ( opt != NULL )
+ if ( optval != NULL )
{
- strncpy(param->var, opt, param->len);
+ strncpy(param->var, optval, param->len);
((char *)param->var)[param->len-1] = '\0';
}
break;
case OPT_UINT:
- if ( opt != NULL )
+ if ( optval != NULL )
*(unsigned int *)param->var =
- simple_strtol(opt, (char **)&opt, 0);
+ simple_strtol(optval, (char **)&optval, 0);
break;
case OPT_BOOL:
*(int *)param->var = 1;
break;
case OPT_CUSTOM:
- if ( opt != NULL )
- ((void (*)(char *))param->var)(opt);
+ if ( optval != NULL )
+ ((void (*)(char *))param->var)(optval);
break;
}
}
- cmdline = opt_end;
}
}
diff --git a/xen/include/asm-x86/apic.h b/xen/include/asm-x86/apic.h
index dcced35f79..2dc0ce8c27 100644
--- a/xen/include/asm-x86/apic.h
+++ b/xen/include/asm-x86/apic.h
@@ -4,6 +4,7 @@
#include <xen/config.h>
#include <asm/fixmap.h>
#include <asm/apicdef.h>
+#include <asm/processor.h>
#include <asm/system.h>
#define Dprintk(x...)
diff --git a/xen/include/asm-x86/fixmap.h b/xen/include/asm-x86/fixmap.h
index c70b2a8b01..ca01c687fe 100644
--- a/xen/include/asm-x86/fixmap.h
+++ b/xen/include/asm-x86/fixmap.h
@@ -13,9 +13,8 @@
#define _ASM_FIXMAP_H
#include <xen/config.h>
-#include <xen/lib.h>
-#include <asm/acpi.h>
#include <asm/apicdef.h>
+#include <asm/acpi.h>
#include <asm/page.h>
/*
@@ -26,17 +25,11 @@
* from the end of virtual memory backwards.
*/
enum fixed_addresses {
-#ifdef CONFIG_X86_LOCAL_APIC
- FIX_APIC_BASE, /* local (CPU) APIC -- required for SMP or not */
-#endif
-#ifdef CONFIG_X86_IO_APIC
+ FIX_APIC_BASE,
FIX_IO_APIC_BASE_0,
FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1,
-#endif
-#ifdef CONFIG_ACPI_BOOT
FIX_ACPI_BEGIN,
FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
-#endif
__end_of_fixed_addresses
};
diff --git a/xen/include/asm-x86/genapic.h b/xen/include/asm-x86/genapic.h
new file mode 100644
index 0000000000..fc813b2e82
--- /dev/null
+++ b/xen/include/asm-x86/genapic.h
@@ -0,0 +1,115 @@
+#ifndef _ASM_GENAPIC_H
+#define _ASM_GENAPIC_H 1
+
+/*
+ * Generic APIC driver interface.
+ *
+ * An straight forward mapping of the APIC related parts of the
+ * x86 subarchitecture interface to a dynamic object.
+ *
+ * This is used by the "generic" x86 subarchitecture.
+ *
+ * Copyright 2003 Andi Kleen, SuSE Labs.
+ */
+
+struct mpc_config_translation;
+struct mpc_config_bus;
+struct mp_config_table;
+struct mpc_config_processor;
+
+struct genapic {
+ char *name;
+ int (*probe)(void);
+
+ int (*apic_id_registered)(void);
+ cpumask_t (*target_cpus)(void);
+ int int_delivery_mode;
+ int int_dest_mode;
+ int ESR_DISABLE;
+ int apic_destination_logical;
+ unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid);
+ unsigned long (*check_apicid_present)(int apicid);
+ int no_balance_irq;
+ int no_ioapic_check;
+ void (*init_apic_ldr)(void);
+ physid_mask_t (*ioapic_phys_id_map)(physid_mask_t map);
+
+ void (*clustered_apic_check)(void);
+ int (*multi_timer_check)(int apic, int irq);
+ int (*apicid_to_node)(int logical_apicid);
+ int (*cpu_to_logical_apicid)(int cpu);
+ int (*cpu_present_to_apicid)(int mps_cpu);
+ physid_mask_t (*apicid_to_cpu_present)(int phys_apicid);
+ int (*mpc_apic_id)(struct mpc_config_processor *m,
+ struct mpc_config_translation *t);
+ void (*setup_portio_remap)(void);
+ int (*check_phys_apicid_present)(int boot_cpu_physical_apicid);
+ void (*enable_apic_mode)(void);
+ u32 (*phys_pkg_id)(u32 cpuid_apic, int index_msb);
+
+ /* mpparse */
+ void (*mpc_oem_bus_info)(struct mpc_config_bus *, char *,
+ struct mpc_config_translation *);
+ void (*mpc_oem_pci_bus)(struct mpc_config_bus *,
+ struct mpc_config_translation *);
+
+ /* When one of the next two hooks returns 1 the genapic
+ is switched to this. Essentially they are additional probe
+ functions. */
+ int (*mps_oem_check)(struct mp_config_table *mpc, char *oem,
+ char *productid);
+ int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
+
+ unsigned (*get_apic_id)(unsigned long x);
+ unsigned long apic_id_mask;
+ unsigned int (*cpu_mask_to_apicid)(cpumask_t cpumask);
+
+ /* ipi */
+ void (*send_IPI_mask)(cpumask_t mask, int vector);
+ void (*send_IPI_allbutself)(int vector);
+ void (*send_IPI_all)(int vector);
+};
+
+#define APICFUNC(x) .x = x
+
+#define APIC_INIT(aname, aprobe) { \
+ .name = aname, \
+ .probe = aprobe, \
+ .int_delivery_mode = INT_DELIVERY_MODE, \
+ .int_dest_mode = INT_DEST_MODE, \
+ .no_balance_irq = NO_BALANCE_IRQ, \
+ .no_ioapic_check = NO_IOAPIC_CHECK, \
+ .ESR_DISABLE = esr_disable, \
+ .apic_destination_logical = APIC_DEST_LOGICAL, \
+ APICFUNC(apic_id_registered), \
+ APICFUNC(target_cpus), \
+ APICFUNC(check_apicid_used), \
+ APICFUNC(check_apicid_present), \
+ APICFUNC(init_apic_ldr), \
+ APICFUNC(ioapic_phys_id_map), \
+ APICFUNC(clustered_apic_check), \
+ APICFUNC(multi_timer_check), \
+ APICFUNC(apicid_to_node), \
+ APICFUNC(cpu_to_logical_apicid), \
+ APICFUNC(cpu_present_to_apicid), \
+ APICFUNC(apicid_to_cpu_present), \
+ APICFUNC(mpc_apic_id), \
+ APICFUNC(setup_portio_remap), \
+ APICFUNC(check_phys_apicid_present), \
+ APICFUNC(mpc_oem_bus_info), \
+ APICFUNC(mpc_oem_pci_bus), \
+ APICFUNC(mps_oem_check), \
+ APICFUNC(get_apic_id), \
+ .apic_id_mask = APIC_ID_MASK, \
+ APICFUNC(cpu_mask_to_apicid), \
+ APICFUNC(acpi_madt_oem_check), \
+ APICFUNC(send_IPI_mask), \
+ APICFUNC(send_IPI_allbutself), \
+ APICFUNC(send_IPI_all), \
+ APICFUNC(enable_apic_mode), \
+ APICFUNC(phys_pkg_id), \
+ }
+
+extern struct genapic *genapic;
+
+#endif
diff --git a/xen/include/asm-x86/mach-bigsmp/mach_apic.h b/xen/include/asm-x86/mach-bigsmp/mach_apic.h
new file mode 100644
index 0000000000..1540c1f934
--- /dev/null
+++ b/xen/include/asm-x86/mach-bigsmp/mach_apic.h
@@ -0,0 +1,167 @@
+#ifndef __ASM_MACH_APIC_H
+#define __ASM_MACH_APIC_H
+#include <asm/smp.h>
+
+#define SEQUENTIAL_APICID
+#ifdef SEQUENTIAL_APICID
+#define xapic_phys_to_log_apicid(phys_apic) ( (1ul << ((phys_apic) & 0x3)) |\
+ ((phys_apic<<2) & (~0xf)) )
+#elif CLUSTERED_APICID
+#define xapic_phys_to_log_apicid(phys_apic) ( (1ul << ((phys_apic) & 0x3)) |\
+ ((phys_apic) & (~0xf)) )
+#endif
+
+#define NO_BALANCE_IRQ (1)
+#define esr_disable (1)
+
+#define NO_IOAPIC_CHECK (0)
+
+static inline int apic_id_registered(void)
+{
+ return (1);
+}
+
+#define APIC_DFR_VALUE (APIC_DFR_CLUSTER)
+/* Round robin the irqs amoung the online cpus */
+static inline cpumask_t target_cpus(void)
+{
+ static unsigned long cpu = NR_CPUS;
+ do {
+ if (cpu >= NR_CPUS)
+ cpu = first_cpu(cpu_online_map);
+ else
+ cpu = next_cpu(cpu, cpu_online_map);
+ } while (cpu >= NR_CPUS);
+ return cpumask_of_cpu(cpu);
+}
+#define TARGET_CPUS (target_cpus())
+
+#define INT_DELIVERY_MODE dest_Fixed
+#define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */
+
+static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
+{
+ return 0;
+}
+
+/* we don't use the phys_cpu_present_map to indicate apicid presence */
+static inline unsigned long check_apicid_present(int bit)
+{
+ return 1;
+}
+
+#define apicid_cluster(apicid) (apicid & 0xF0)
+
+static inline unsigned long calculate_ldr(unsigned long old)
+{
+ unsigned long id;
+ id = xapic_phys_to_log_apicid(hard_smp_processor_id());
+ return ((old & ~APIC_LDR_MASK) | SET_APIC_LOGICAL_ID(id));
+}
+
+/*
+ * Set up the logical destination ID.
+ *
+ * Intel recommends to set DFR, LDR and TPR before enabling
+ * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
+ * document number 292116). So here it goes...
+ */
+static inline void init_apic_ldr(void)
+{
+ unsigned long val;
+
+ apic_write_around(APIC_DFR, APIC_DFR_VALUE);
+ val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
+ val = calculate_ldr(val);
+ apic_write_around(APIC_LDR, val);
+}
+
+static inline void clustered_apic_check(void)
+{
+ printk("Enabling APIC mode: %s. Using %d I/O APICs\n",
+ "Cluster", nr_ioapics);
+}
+
+static inline int multi_timer_check(int apic, int irq)
+{
+ return 0;
+}
+
+static inline int apicid_to_node(int logical_apicid)
+{
+ return 0;
+}
+
+extern u8 bios_cpu_apicid[];
+
+static inline int cpu_present_to_apicid(int mps_cpu)
+{
+ if (mps_cpu < NR_CPUS)
+ return (int)bios_cpu_apicid[mps_cpu];
+ else
+ return BAD_APICID;
+}
+
+static inline physid_mask_t apicid_to_cpu_present(int phys_apicid)
+{
+ return physid_mask_of_physid(phys_apicid);
+}
+
+extern u8 cpu_2_logical_apicid[];
+/* Mapping from cpu number to logical apicid */
+static inline int cpu_to_logical_apicid(int cpu)
+{
+ if (cpu >= NR_CPUS)
+ return BAD_APICID;
+ return (int)cpu_2_logical_apicid[cpu];
+ }
+
+static inline int mpc_apic_id(struct mpc_config_processor *m,
+ struct mpc_config_translation *translation_record)
+{
+ printk("Processor #%d %d:%d APIC version %d\n",
+ m->mpc_apicid,
+ (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8,
+ (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
+ m->mpc_apicver);
+ return m->mpc_apicid;
+}
+
+static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map)
+{
+ /* For clustered we don't have a good way to do this yet - hack */
+ return physids_promote(0xFUL);
+}
+
+#define WAKE_SECONDARY_VIA_INIT
+
+static inline void setup_portio_remap(void)
+{
+}
+
+static inline void enable_apic_mode(void)
+{
+}
+
+static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
+{
+ return (1);
+}
+
+/* As we are using single CPU as destination, pick only one CPU here */
+static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask)
+{
+ int cpu;
+ int apicid;
+
+ cpu = first_cpu(cpumask);
+ apicid = cpu_to_logical_apicid(cpu);
+ return apicid;
+}
+
+static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
+{
+ return cpuid_apic >> index_msb;
+}
+
+#endif /* __ASM_MACH_APIC_H */
diff --git a/xen/include/asm-x86/mach-bigsmp/mach_apicdef.h b/xen/include/asm-x86/mach-bigsmp/mach_apicdef.h
new file mode 100644
index 0000000000..23e58b317c
--- /dev/null
+++ b/xen/include/asm-x86/mach-bigsmp/mach_apicdef.h
@@ -0,0 +1,13 @@
+#ifndef __ASM_MACH_APICDEF_H
+#define __ASM_MACH_APICDEF_H
+
+#define APIC_ID_MASK (0x0F<<24)
+
+static inline unsigned get_apic_id(unsigned long x)
+{
+ return (((x)>>24)&0x0F);
+}
+
+#define GET_APIC_ID(x) get_apic_id(x)
+
+#endif
diff --git a/xen/include/asm-x86/mach-bigsmp/mach_ipi.h b/xen/include/asm-x86/mach-bigsmp/mach_ipi.h
new file mode 100644
index 0000000000..9404c535b7
--- /dev/null
+++ b/xen/include/asm-x86/mach-bigsmp/mach_ipi.h
@@ -0,0 +1,25 @@
+#ifndef __ASM_MACH_IPI_H
+#define __ASM_MACH_IPI_H
+
+void send_IPI_mask_sequence(cpumask_t mask, int vector);
+
+static inline void send_IPI_mask(cpumask_t mask, int vector)
+{
+ send_IPI_mask_sequence(mask, vector);
+}
+
+static inline void send_IPI_allbutself(int vector)
+{
+ cpumask_t mask = cpu_online_map;
+ cpu_clear(smp_processor_id(), mask);
+
+ if (!cpus_empty(mask))
+ send_IPI_mask(mask, vector);
+}
+
+static inline void send_IPI_all(int vector)
+{
+ send_IPI_mask(cpu_online_map, vector);
+}
+
+#endif /* __ASM_MACH_IPI_H */
diff --git a/xen/include/asm-x86/mach-default/apm.h b/xen/include/asm-x86/mach-default/apm.h
deleted file mode 100644
index 1f730b8bd1..0000000000
--- a/xen/include/asm-x86/mach-default/apm.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * include/asm-i386/mach-default/apm.h
- *
- * Machine specific APM BIOS functions for generic.
- * Split out from apm.c by Osamu Tomita <tomita@cinet.co.jp>
- */
-
-#ifndef _ASM_APM_H
-#define _ASM_APM_H
-
-#ifdef APM_ZERO_SEGS
-# define APM_DO_ZERO_SEGS \
- "pushl %%ds\n\t" \
- "pushl %%es\n\t" \
- "xorl %%edx, %%edx\n\t" \
- "mov %%dx, %%ds\n\t" \
- "mov %%dx, %%es\n\t" \
- "mov %%dx, %%fs\n\t" \
- "mov %%dx, %%gs\n\t"
-# define APM_DO_POP_SEGS \
- "popl %%es\n\t" \
- "popl %%ds\n\t"
-#else
-# define APM_DO_ZERO_SEGS
-# define APM_DO_POP_SEGS
-#endif
-
-static inline void apm_bios_call_asm(u32 func, u32 ebx_in, u32 ecx_in,
- u32 *eax, u32 *ebx, u32 *ecx,
- u32 *edx, u32 *esi)
-{
- /*
- * N.B. We do NOT need a cld after the BIOS call
- * because we always save and restore the flags.
- */
- __asm__ __volatile__(APM_DO_ZERO_SEGS
- "pushl %%edi\n\t"
- "pushl %%ebp\n\t"
- "lcall *%%cs:apm_bios_entry\n\t"
- "setc %%al\n\t"
- "popl %%ebp\n\t"
- "popl %%edi\n\t"
- APM_DO_POP_SEGS
- : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx),
- "=S" (*esi)
- : "a" (func), "b" (ebx_in), "c" (ecx_in)
- : "memory", "cc");
-}
-
-static inline u8 apm_bios_call_simple_asm(u32 func, u32 ebx_in,
- u32 ecx_in, u32 *eax)
-{
- int cx, dx, si;
- u8 error;
-
- /*
- * N.B. We do NOT need a cld after the BIOS call
- * because we always save and restore the flags.
- */
- __asm__ __volatile__(APM_DO_ZERO_SEGS
- "pushl %%edi\n\t"
- "pushl %%ebp\n\t"
- "lcall *%%cs:apm_bios_entry\n\t"
- "setc %%bl\n\t"
- "popl %%ebp\n\t"
- "popl %%edi\n\t"
- APM_DO_POP_SEGS
- : "=a" (*eax), "=b" (error), "=c" (cx), "=d" (dx),
- "=S" (si)
- : "a" (func), "b" (ebx_in), "c" (ecx_in)
- : "memory", "cc");
- return error;
-}
-
-#endif /* _ASM_APM_H */
diff --git a/xen/include/asm-x86/mach-default/do_timer.h b/xen/include/asm-x86/mach-default/do_timer.h
deleted file mode 100644
index 03dd13a48a..0000000000
--- a/xen/include/asm-x86/mach-default/do_timer.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* defines for inline arch setup functions */
-
-#include <asm/apic.h>
-
-/**
- * do_timer_interrupt_hook - hook into timer tick
- * @regs: standard registers from interrupt
- *
- * Description:
- * This hook is called immediately after the timer interrupt is ack'd.
- * It's primary purpose is to allow architectures that don't possess
- * individual per CPU clocks (like the CPU APICs supply) to broadcast the
- * timer interrupt as a means of triggering reschedules etc.
- **/
-
-static inline void do_timer_interrupt_hook(struct pt_regs *regs)
-{
- do_timer(regs);
-#ifndef CONFIG_SMP
- update_process_times(user_mode(regs));
-#endif
-/*
- * In the SMP case we use the local APIC timer interrupt to do the
- * profiling, except when we simulate SMP mode on a uniprocessor
- * system, in that case we have to call the local interrupt handler.
- */
-#ifndef CONFIG_X86_LOCAL_APIC
- profile_tick(CPU_PROFILING, regs);
-#else
- if (!using_apic_timer)
- smp_local_timer_interrupt(regs);
-#endif
-}
-
-
-/* you can safely undefine this if you don't have the Neptune chipset */
-
-#define BUGGY_NEPTUN_TIMER
-
-/**
- * do_timer_overflow - process a detected timer overflow condition
- * @count: hardware timer interrupt count on overflow
- *
- * Description:
- * This call is invoked when the jiffies count has not incremented but
- * the hardware timer interrupt has. It means that a timer tick interrupt
- * came along while the previous one was pending, thus a tick was missed
- **/
-static inline int do_timer_overflow(int count)
-{
- int i;
-
- spin_lock(&i8259A_lock);
- /*
- * This is tricky when I/O APICs are used;
- * see do_timer_interrupt().
- */
- i = inb(0x20);
- spin_unlock(&i8259A_lock);
-
- /* assumption about timer being IRQ0 */
- if (i & 0x01) {
- /*
- * We cannot detect lost timer interrupts ...
- * well, that's why we call them lost, don't we? :)
- * [hmm, on the Pentium and Alpha we can ... sort of]
- */
- count -= LATCH;
- } else {
-#ifdef BUGGY_NEPTUN_TIMER
- /*
- * for the Neptun bug we know that the 'latch'
- * command doesn't latch the high and low value
- * of the counter atomically. Thus we have to
- * substract 256 from the counter
- * ... funny, isnt it? :)
- */
-
- count -= 256;
-#else
- printk("do_slow_gettimeoffset(): hardware timer problem?\n");
-#endif
- }
- return count;
-}
diff --git a/xen/include/asm-x86/mach-default/entry_arch.h b/xen/include/asm-x86/mach-default/entry_arch.h
deleted file mode 100644
index bc861469bd..0000000000
--- a/xen/include/asm-x86/mach-default/entry_arch.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * This file is designed to contain the BUILD_INTERRUPT specifications for
- * all of the extra named interrupt vectors used by the architecture.
- * Usually this is the Inter Process Interrupts (IPIs)
- */
-
-/*
- * The following vectors are part of the Linux architecture, there
- * is no hardware IRQ pin equivalent for them, they are triggered
- * through the ICC by us (IPIs)
- */
-#ifdef CONFIG_X86_SMP
-BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR)
-BUILD_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR)
-BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
-#endif
-
-/*
- * every pentium local APIC has two 'local interrupts', with a
- * soft-definable vector attached to both interrupts, one of
- * which is a timer interrupt, the other one is error counter
- * overflow. Linux uses the local APIC timer interrupt to get
- * a much simpler SMP time architecture:
- */
-#ifdef CONFIG_X86_LOCAL_APIC
-BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR)
-BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)
-BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)
-
-#ifdef CONFIG_X86_MCE_P4THERMAL
-BUILD_INTERRUPT(thermal_interrupt,THERMAL_APIC_VECTOR)
-#endif
-
-#endif
diff --git a/xen/include/asm-x86/mach-default/irq_vectors_limits.h b/xen/include/asm-x86/mach-default/irq_vectors_limits.h
index b330026e6f..69297bc0dc 100644
--- a/xen/include/asm-x86/mach-default/irq_vectors_limits.h
+++ b/xen/include/asm-x86/mach-default/irq_vectors_limits.h
@@ -1,21 +1,7 @@
#ifndef _ASM_IRQ_VECTORS_LIMITS_H
#define _ASM_IRQ_VECTORS_LIMITS_H
-#ifdef CONFIG_PCI_MSI
-#define NR_IRQS FIRST_SYSTEM_VECTOR
+#define NR_IRQS 224
#define NR_IRQ_VECTORS NR_IRQS
-#else
-#ifdef CONFIG_X86_IO_APIC
-#define NR_IRQS 224
-# if (224 >= 32 * NR_CPUS)
-# define NR_IRQ_VECTORS NR_IRQS
-# else
-# define NR_IRQ_VECTORS (32 * NR_CPUS)
-# endif
-#else
-#define NR_IRQS 16
-#define NR_IRQ_VECTORS NR_IRQS
-#endif
-#endif
#endif /* _ASM_IRQ_VECTORS_LIMITS_H */
diff --git a/xen/include/asm-x86/mach-default/mach_mpspec.h b/xen/include/asm-x86/mach-default/mach_mpspec.h
deleted file mode 100644
index 6b5dadcf1d..0000000000
--- a/xen/include/asm-x86/mach-default/mach_mpspec.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __ASM_MACH_MPSPEC_H
-#define __ASM_MACH_MPSPEC_H
-
-#define MAX_IRQ_SOURCES 256
-
-#define MAX_MP_BUSSES 32
-
-#endif /* __ASM_MACH_MPSPEC_H */
diff --git a/xen/include/asm-x86/mach-default/mach_reboot.h b/xen/include/asm-x86/mach-default/mach_reboot.h
deleted file mode 100644
index 521e227db6..0000000000
--- a/xen/include/asm-x86/mach-default/mach_reboot.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * arch/i386/mach-generic/mach_reboot.h
- *
- * Machine specific reboot functions for generic.
- * Split out from reboot.c by Osamu Tomita <tomita@cinet.co.jp>
- */
-#ifndef _MACH_REBOOT_H
-#define _MACH_REBOOT_H
-
-static inline void kb_wait(void)
-{
- int i;
-
- for (i = 0; i < 0x10000; i++)
- if ((inb_p(0x64) & 0x02) == 0)
- break;
-}
-
-static inline void mach_reboot(void)
-{
- int i;
- for (i = 0; i < 100; i++) {
- kb_wait();
- udelay(50);
- outb(0xfe, 0x64); /* pulse reset low */
- udelay(50);
- }
-}
-
-#endif /* !_MACH_REBOOT_H */
diff --git a/xen/include/asm-x86/mach-default/mach_time.h b/xen/include/asm-x86/mach-default/mach_time.h
deleted file mode 100644
index b749aa44a8..0000000000
--- a/xen/include/asm-x86/mach-default/mach_time.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * include/asm-i386/mach-default/mach_time.h
- *
- * Machine specific set RTC function for generic.
- * Split out from time.c by Osamu Tomita <tomita@cinet.co.jp>
- */
-#ifndef _MACH_TIME_H
-#define _MACH_TIME_H
-
-#include <linux/mc146818rtc.h>
-
-/* for check timing call set_rtc_mmss() 500ms */
-/* used in arch/i386/time.c::do_timer_interrupt() */
-#define USEC_AFTER 500000
-#define USEC_BEFORE 500000
-
-/*
- * In order to set the CMOS clock precisely, set_rtc_mmss has to be
- * called 500 ms after the second nowtime has started, because when
- * nowtime is written into the registers of the CMOS clock, it will
- * jump to the next second precisely 500 ms later. Check the Motorola
- * MC146818A or Dallas DS12887 data sheet for details.
- *
- * BUG: This routine does not handle hour overflow properly; it just
- * sets the minutes. Usually you'll only notice that after reboot!
- */
-static inline int mach_set_rtc_mmss(unsigned long nowtime)
-{
- int retval = 0;
- int real_seconds, real_minutes, cmos_minutes;
- unsigned char save_control, save_freq_select;
-
- save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
- CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
-
- save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
- CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
-
- cmos_minutes = CMOS_READ(RTC_MINUTES);
- if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
- BCD_TO_BIN(cmos_minutes);
-
- /*
- * since we're only adjusting minutes and seconds,
- * don't interfere with hour overflow. This avoids
- * messing with unknown time zones but requires your
- * RTC not to be off by more than 15 minutes
- */
- real_seconds = nowtime % 60;
- real_minutes = nowtime / 60;
- if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
- real_minutes += 30; /* correct for half hour time zone */
- real_minutes %= 60;
-
- if (abs(real_minutes - cmos_minutes) < 30) {
- if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
- BIN_TO_BCD(real_seconds);
- BIN_TO_BCD(real_minutes);
- }
- CMOS_WRITE(real_seconds,RTC_SECONDS);
- CMOS_WRITE(real_minutes,RTC_MINUTES);
- } else {
- printk(KERN_WARNING
- "set_rtc_mmss: can't update from %d to %d\n",
- cmos_minutes, real_minutes);
- retval = -1;
- }
-
- /* The following flags have to be released exactly in this order,
- * otherwise the DS12887 (popular MC146818A clone with integrated
- * battery and quartz) will not reset the oscillator and will not
- * update precisely 500 ms later. You won't find this mentioned in
- * the Dallas Semiconductor data sheets, but who believes data
- * sheets anyway ... -- Markus Kuhn
- */
- CMOS_WRITE(save_control, RTC_CONTROL);
- CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-
- return retval;
-}
-
-static inline unsigned long mach_get_cmos_time(void)
-{
- unsigned int year, mon, day, hour, min, sec;
- int i;
-
- /* The Linux interpretation of the CMOS clock register contents:
- * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
- * RTC registers show the second which has precisely just started.
- * Let's hope other operating systems interpret the RTC the same way.
- */
- /* read RTC exactly on falling edge of update flag */
- for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
- if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
- break;
- for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
- if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
- break;
- do { /* Isn't this overkill ? UIP above should guarantee consistency */
- sec = CMOS_READ(RTC_SECONDS);
- min = CMOS_READ(RTC_MINUTES);
- hour = CMOS_READ(RTC_HOURS);
- day = CMOS_READ(RTC_DAY_OF_MONTH);
- mon = CMOS_READ(RTC_MONTH);
- year = CMOS_READ(RTC_YEAR);
- } while (sec != CMOS_READ(RTC_SECONDS));
- if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
- {
- BCD_TO_BIN(sec);
- BCD_TO_BIN(min);
- BCD_TO_BIN(hour);
- BCD_TO_BIN(day);
- BCD_TO_BIN(mon);
- BCD_TO_BIN(year);
- }
- if ((year += 1900) < 1970)
- year += 100;
-
- return mktime(year, mon, day, hour, min, sec);
-}
-
-#endif /* !_MACH_TIME_H */
diff --git a/xen/include/asm-x86/mach-default/mach_timer.h b/xen/include/asm-x86/mach-default/mach_timer.h
deleted file mode 100644
index 4b9703bb02..0000000000
--- a/xen/include/asm-x86/mach-default/mach_timer.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * include/asm-i386/mach-default/mach_timer.h
- *
- * Machine specific calibrate_tsc() for generic.
- * Split out from timer_tsc.c by Osamu Tomita <tomita@cinet.co.jp>
- */
-/* ------ Calibrate the TSC -------
- * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
- * Too much 64-bit arithmetic here to do this cleanly in C, and for
- * accuracy's sake we want to keep the overhead on the CTC speaker (channel 2)
- * output busy loop as low as possible. We avoid reading the CTC registers
- * directly because of the awkward 8-bit access mechanism of the 82C54
- * device.
- */
-#ifndef _MACH_TIMER_H
-#define _MACH_TIMER_H
-
-#define CALIBRATE_LATCH (5 * LATCH)
-
-static inline void mach_prepare_counter(void)
-{
- /* Set the Gate high, disable speaker */
- outb((inb(0x61) & ~0x02) | 0x01, 0x61);
-
- /*
- * Now let's take care of CTC channel 2
- *
- * Set the Gate high, program CTC channel 2 for mode 0,
- * (interrupt on terminal count mode), binary count,
- * load 5 * LATCH count, (LSB and MSB) to begin countdown.
- *
- * Some devices need a delay here.
- */
- outb(0xb0, 0x43); /* binary, mode 0, LSB/MSB, Ch 2 */
- outb_p(CALIBRATE_LATCH & 0xff, 0x42); /* LSB of count */
- outb_p(CALIBRATE_LATCH >> 8, 0x42); /* MSB of count */
-}
-
-static inline void mach_countup(unsigned long *count_p)
-{
- unsigned long count = 0;
- do {
- count++;
- } while ((inb_p(0x61) & 0x20) == 0);
- *count_p = count;
-}
-
-#endif /* !_MACH_TIMER_H */
diff --git a/xen/include/asm-x86/mach-default/mach_traps.h b/xen/include/asm-x86/mach-default/mach_traps.h
deleted file mode 100644
index c98c2880c5..0000000000
--- a/xen/include/asm-x86/mach-default/mach_traps.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * include/asm-i386/mach-default/mach_traps.h
- *
- * Machine specific NMI handling for generic.
- * Split out from traps.c by Osamu Tomita <tomita@cinet.co.jp>
- */
-#ifndef _MACH_TRAPS_H
-#define _MACH_TRAPS_H
-
-static inline void clear_mem_error(unsigned char reason)
-{
- reason = (reason & 0xf) | 4;
- outb(reason, 0x61);
-}
-
-static inline unsigned char get_nmi_reason(void)
-{
- return inb(0x61);
-}
-
-static inline void reassert_nmi(void)
-{
- outb(0x8f, 0x70);
- inb(0x71); /* dummy */
- outb(0x0f, 0x70);
- inb(0x71); /* dummy */
-}
-
-#endif /* !_MACH_TRAPS_H */
diff --git a/xen/include/asm-x86/mach-default/pci-functions.h b/xen/include/asm-x86/mach-default/pci-functions.h
deleted file mode 100644
index ed0bab4273..0000000000
--- a/xen/include/asm-x86/mach-default/pci-functions.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * PCI BIOS function numbering for conventional PCI BIOS
- * systems
- */
-
-#define PCIBIOS_PCI_FUNCTION_ID 0xb1XX
-#define PCIBIOS_PCI_BIOS_PRESENT 0xb101
-#define PCIBIOS_FIND_PCI_DEVICE 0xb102
-#define PCIBIOS_FIND_PCI_CLASS_CODE 0xb103
-#define PCIBIOS_GENERATE_SPECIAL_CYCLE 0xb106
-#define PCIBIOS_READ_CONFIG_BYTE 0xb108
-#define PCIBIOS_READ_CONFIG_WORD 0xb109
-#define PCIBIOS_READ_CONFIG_DWORD 0xb10a
-#define PCIBIOS_WRITE_CONFIG_BYTE 0xb10b
-#define PCIBIOS_WRITE_CONFIG_WORD 0xb10c
-#define PCIBIOS_WRITE_CONFIG_DWORD 0xb10d
-#define PCIBIOS_GET_ROUTING_OPTIONS 0xb10e
-#define PCIBIOS_SET_PCI_HW_INT 0xb10f
-
diff --git a/xen/include/asm-x86/mach-default/setup_arch_post.h b/xen/include/asm-x86/mach-default/setup_arch_post.h
deleted file mode 100644
index 2fc4888721..0000000000
--- a/xen/include/asm-x86/mach-default/setup_arch_post.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * machine_specific_memory_setup - Hook for machine specific memory setup.
- *
- * Description:
- * This is included late in kernel/setup.c so that it can make
- * use of all of the static functions.
- **/
-
-static char * __init machine_specific_memory_setup(void)
-{
- char *who;
-
-
- who = "BIOS-e820";
-
- /*
- * Try to copy the BIOS-supplied E820-map.
- *
- * Otherwise fake a memory map; one section from 0k->640k,
- * the next section from 1mb->appropriate_mem_k
- */
- sanitize_e820_map(E820_MAP, &E820_MAP_NR);
- if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) {
- unsigned long mem_size;
-
- /* compare results from other methods and take the greater */
- if (ALT_MEM_K < EXT_MEM_K) {
- mem_size = EXT_MEM_K;
- who = "BIOS-88";
- } else {
- mem_size = ALT_MEM_K;
- who = "BIOS-e801";
- }
-
- e820.nr_map = 0;
- add_memory_region(0, LOWMEMSIZE(), E820_RAM);
- add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
- }
- return who;
-}
diff --git a/xen/include/asm-x86/mach-default/setup_arch_pre.h b/xen/include/asm-x86/mach-default/setup_arch_pre.h
deleted file mode 100644
index fb42099e7b..0000000000
--- a/xen/include/asm-x86/mach-default/setup_arch_pre.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Hook to call BIOS initialisation function */
-
-/* no action for generic */
-
-#define ARCH_SETUP
diff --git a/xen/include/asm-x86/mach-es7000/mach_apic.h b/xen/include/asm-x86/mach-es7000/mach_apic.h
new file mode 100644
index 0000000000..4cf0e75a6d
--- /dev/null
+++ b/xen/include/asm-x86/mach-es7000/mach_apic.h
@@ -0,0 +1,207 @@
+#ifndef __ASM_MACH_APIC_H
+#define __ASM_MACH_APIC_H
+
+extern u8 bios_cpu_apicid[];
+
+#define xapic_phys_to_log_apicid(cpu) (bios_cpu_apicid[cpu])
+#define esr_disable (1)
+
+static inline int apic_id_registered(void)
+{
+ return (1);
+}
+
+static inline cpumask_t target_cpus(void)
+{
+#if defined CONFIG_ES7000_CLUSTERED_APIC
+ return CPU_MASK_ALL;
+#else
+ return cpumask_of_cpu(smp_processor_id());
+#endif
+}
+#define TARGET_CPUS (target_cpus())
+
+#if defined CONFIG_ES7000_CLUSTERED_APIC
+#define APIC_DFR_VALUE (APIC_DFR_CLUSTER)
+#define INT_DELIVERY_MODE (dest_LowestPrio)
+#define INT_DEST_MODE (1) /* logical delivery broadcast to all procs */
+#define NO_BALANCE_IRQ (1)
+#undef WAKE_SECONDARY_VIA_INIT
+#define WAKE_SECONDARY_VIA_MIP
+#else
+#define APIC_DFR_VALUE (APIC_DFR_FLAT)
+#define INT_DELIVERY_MODE (dest_Fixed)
+#define INT_DEST_MODE (0) /* phys delivery to target procs */
+#define NO_BALANCE_IRQ (0)
+#undef APIC_DEST_LOGICAL
+#define APIC_DEST_LOGICAL 0x0
+#define WAKE_SECONDARY_VIA_INIT
+#endif
+
+#define NO_IOAPIC_CHECK (1)
+
+static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
+{
+ return 0;
+}
+static inline unsigned long check_apicid_present(int bit)
+{
+ return physid_isset(bit, phys_cpu_present_map);
+}
+
+#define apicid_cluster(apicid) (apicid & 0xF0)
+
+static inline unsigned long calculate_ldr(int cpu)
+{
+ unsigned long id;
+ id = xapic_phys_to_log_apicid(cpu);
+ return (SET_APIC_LOGICAL_ID(id));
+}
+
+/*
+ * Set up the logical destination ID.
+ *
+ * Intel recommends to set DFR, LdR and TPR before enabling
+ * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
+ * document number 292116). So here it goes...
+ */
+static inline void init_apic_ldr(void)
+{
+ unsigned long val;
+ int cpu = smp_processor_id();
+
+ apic_write_around(APIC_DFR, APIC_DFR_VALUE);
+ val = calculate_ldr(cpu);
+ apic_write_around(APIC_LDR, val);
+}
+
+extern void es7000_sw_apic(void);
+static inline void enable_apic_mode(void)
+{
+ es7000_sw_apic();
+ return;
+}
+
+extern int apic_version [MAX_APICS];
+static inline void clustered_apic_check(void)
+{
+ int apic = bios_cpu_apicid[smp_processor_id()];
+ printk("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n",
+ (apic_version[apic] == 0x14) ?
+ "Physical Cluster" : "Logical Cluster", nr_ioapics, cpus_addr(TARGET_CPUS)[0]);
+}
+
+static inline int multi_timer_check(int apic, int irq)
+{
+ return 0;
+}
+
+static inline int apicid_to_node(int logical_apicid)
+{
+ return 0;
+}
+
+
+static inline int cpu_present_to_apicid(int mps_cpu)
+{
+ if (!mps_cpu)
+ return boot_cpu_physical_apicid;
+ else if (mps_cpu < NR_CPUS)
+ return (int) bios_cpu_apicid[mps_cpu];
+ else
+ return BAD_APICID;
+}
+
+static inline physid_mask_t apicid_to_cpu_present(int phys_apicid)
+{
+ static int id = 0;
+ physid_mask_t mask;
+ mask = physid_mask_of_physid(id);
+ ++id;
+ return mask;
+}
+
+extern u8 cpu_2_logical_apicid[];
+/* Mapping from cpu number to logical apicid */
+static inline int cpu_to_logical_apicid(int cpu)
+{
+ if (cpu >= NR_CPUS)
+ return BAD_APICID;
+ return (int)cpu_2_logical_apicid[cpu];
+}
+
+static inline int mpc_apic_id(struct mpc_config_processor *m, struct mpc_config_translation *unused)
+{
+ printk("Processor #%d %d:%d APIC version %d\n",
+ m->mpc_apicid,
+ (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8,
+ (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
+ m->mpc_apicver);
+ return (m->mpc_apicid);
+}
+
+static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map)
+{
+ /* For clustered we don't have a good way to do this yet - hack */
+ return physids_promote(0xff);
+}
+
+
+static inline void setup_portio_remap(void)
+{
+}
+
+extern unsigned int boot_cpu_physical_apicid;
+static inline int check_phys_apicid_present(int cpu_physical_apicid)
+{
+ boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
+ return (1);
+}
+
+static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask)
+{
+ int num_bits_set;
+ int cpus_found = 0;
+ int cpu;
+ int apicid;
+
+ num_bits_set = cpus_weight(cpumask);
+ /* Return id to all */
+ if (num_bits_set == NR_CPUS)
+#if defined CONFIG_ES7000_CLUSTERED_APIC
+ return 0xFF;
+#else
+ return cpu_to_logical_apicid(0);
+#endif
+ /*
+ * The cpus in the mask must all be on the apic cluster. If are not
+ * on the same apicid cluster return default value of TARGET_CPUS.
+ */
+ cpu = first_cpu(cpumask);
+ apicid = cpu_to_logical_apicid(cpu);
+ while (cpus_found < num_bits_set) {
+ if (cpu_isset(cpu, cpumask)) {
+ int new_apicid = cpu_to_logical_apicid(cpu);
+ if (apicid_cluster(apicid) !=
+ apicid_cluster(new_apicid)){
+ printk ("%s: Not a valid mask!\n",__FUNCTION__);
+#if defined CONFIG_ES7000_CLUSTERED_APIC
+ return 0xFF;
+#else
+ return cpu_to_logical_apicid(0);
+#endif
+ }
+ apicid = new_apicid;
+ cpus_found++;
+ }
+ cpu++;
+ }
+ return apicid;
+}
+
+static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
+{
+ return cpuid_apic >> index_msb;
+}
+
+#endif /* __ASM_MACH_APIC_H */
diff --git a/xen/include/asm-x86/mach-es7000/mach_apicdef.h b/xen/include/asm-x86/mach-es7000/mach_apicdef.h
new file mode 100644
index 0000000000..a58ab5a75c
--- /dev/null
+++ b/xen/include/asm-x86/mach-es7000/mach_apicdef.h
@@ -0,0 +1,13 @@
+#ifndef __ASM_MACH_APICDEF_H
+#define __ASM_MACH_APICDEF_H
+
+#define APIC_ID_MASK (0xFF<<24)
+
+static inline unsigned get_apic_id(unsigned long x)
+{
+ return (((x)>>24)&0xFF);
+}
+
+#define GET_APIC_ID(x) get_apic_id(x)
+
+#endif
diff --git a/xen/include/asm-x86/mach-es7000/mach_ipi.h b/xen/include/asm-x86/mach-es7000/mach_ipi.h
new file mode 100644
index 0000000000..5e61bd220b
--- /dev/null
+++ b/xen/include/asm-x86/mach-es7000/mach_ipi.h
@@ -0,0 +1,24 @@
+#ifndef __ASM_MACH_IPI_H
+#define __ASM_MACH_IPI_H
+
+void send_IPI_mask_sequence(cpumask_t mask, int vector);
+
+static inline void send_IPI_mask(cpumask_t mask, int vector)
+{
+ send_IPI_mask_sequence(mask, vector);
+}
+
+static inline void send_IPI_allbutself(int vector)
+{
+ cpumask_t mask = cpu_online_map;
+ cpu_clear(smp_processor_id(), mask);
+ if (!cpus_empty(mask))
+ send_IPI_mask(mask, vector);
+}
+
+static inline void send_IPI_all(int vector)
+{
+ send_IPI_mask(cpu_online_map, vector);
+}
+
+#endif /* __ASM_MACH_IPI_H */
diff --git a/xen/include/asm-x86/mach-es7000/mach_mpparse.h b/xen/include/asm-x86/mach-es7000/mach_mpparse.h
new file mode 100644
index 0000000000..85809e0898
--- /dev/null
+++ b/xen/include/asm-x86/mach-es7000/mach_mpparse.h
@@ -0,0 +1,41 @@
+#ifndef __ASM_MACH_MPPARSE_H
+#define __ASM_MACH_MPPARSE_H
+
+static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name,
+ struct mpc_config_translation *translation)
+{
+ Dprintk("Bus #%d is %s\n", m->mpc_busid, name);
+}
+
+static inline void mpc_oem_pci_bus(struct mpc_config_bus *m,
+ struct mpc_config_translation *translation)
+{
+}
+
+extern int parse_unisys_oem (char *oemptr, int oem_entries);
+extern int find_unisys_acpi_oem_table(unsigned long *oem_addr, int *length);
+
+static inline int mps_oem_check(struct mp_config_table *mpc, char *oem,
+ char *productid)
+{
+ if (mpc->mpc_oemptr) {
+ struct mp_config_oemtable *oem_table =
+ (struct mp_config_oemtable *)mpc->mpc_oemptr;
+ if (!strncmp(oem, "UNISYS", 6))
+ return parse_unisys_oem((char *)oem_table, oem_table->oem_length);
+ }
+ return 0;
+}
+
+/* Hook from generic ACPI tables.c */
+static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+ unsigned long oem_addr;
+ int oem_entries;
+ if (!find_unisys_acpi_oem_table(&oem_addr, &oem_entries))
+ return parse_unisys_oem((char *)oem_addr, oem_entries);
+ return 0;
+}
+
+
+#endif /* __ASM_MACH_MPPARSE_H */
diff --git a/xen/include/asm-x86/mach-es7000/mach_wakecpu.h b/xen/include/asm-x86/mach-es7000/mach_wakecpu.h
new file mode 100644
index 0000000000..efc903b734
--- /dev/null
+++ b/xen/include/asm-x86/mach-es7000/mach_wakecpu.h
@@ -0,0 +1,58 @@
+#ifndef __ASM_MACH_WAKECPU_H
+#define __ASM_MACH_WAKECPU_H
+
+/*
+ * This file copes with machines that wakeup secondary CPUs by the
+ * INIT, INIT, STARTUP sequence.
+ */
+
+#ifdef CONFIG_ES7000_CLUSTERED_APIC
+#define WAKE_SECONDARY_VIA_MIP
+#else
+#define WAKE_SECONDARY_VIA_INIT
+#endif
+
+#ifdef WAKE_SECONDARY_VIA_MIP
+extern int es7000_start_cpu(int cpu, unsigned long eip);
+static inline int
+wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
+{
+ int boot_error = 0;
+ boot_error = es7000_start_cpu(phys_apicid, start_eip);
+ return boot_error;
+}
+#endif
+
+#define TRAMPOLINE_LOW phys_to_virt(0x467)
+#define TRAMPOLINE_HIGH phys_to_virt(0x469)
+
+#define boot_cpu_apicid boot_cpu_physical_apicid
+
+static inline void wait_for_init_deassert(atomic_t *deassert)
+{
+#ifdef WAKE_SECONDARY_VIA_INIT
+ while (!atomic_read(deassert));
+#endif
+ return;
+}
+
+/* Nothing to do for most platforms, since cleared by the INIT cycle */
+static inline void smp_callin_clear_local_apic(void)
+{
+}
+
+static inline void store_NMI_vector(unsigned short *high, unsigned short *low)
+{
+}
+
+static inline void restore_NMI_vector(unsigned short *high, unsigned short *low)
+{
+}
+
+#if APIC_DEBUG
+ #define inquire_remote_apic(apicid) __inquire_remote_apic(apicid)
+#else
+ #define inquire_remote_apic(apicid) {}
+#endif
+
+#endif /* __ASM_MACH_WAKECPU_H */
diff --git a/xen/include/asm-x86/mach-generic/mach_apic.h b/xen/include/asm-x86/mach-generic/mach_apic.h
new file mode 100644
index 0000000000..ab36d02ebe
--- /dev/null
+++ b/xen/include/asm-x86/mach-generic/mach_apic.h
@@ -0,0 +1,32 @@
+#ifndef __ASM_MACH_APIC_H
+#define __ASM_MACH_APIC_H
+
+#include <asm/genapic.h>
+
+#define esr_disable (genapic->ESR_DISABLE)
+#define NO_BALANCE_IRQ (genapic->no_balance_irq)
+#define NO_IOAPIC_CHECK (genapic->no_ioapic_check)
+#define INT_DELIVERY_MODE (genapic->int_delivery_mode)
+#define INT_DEST_MODE (genapic->int_dest_mode)
+#undef APIC_DEST_LOGICAL
+#define APIC_DEST_LOGICAL (genapic->apic_destination_logical)
+#define TARGET_CPUS (genapic->target_cpus())
+#define apic_id_registered (genapic->apic_id_registered)
+#define init_apic_ldr (genapic->init_apic_ldr)
+#define ioapic_phys_id_map (genapic->ioapic_phys_id_map)
+#define clustered_apic_check (genapic->clustered_apic_check)
+#define multi_timer_check (genapic->multi_timer_check)
+#define apicid_to_node (genapic->apicid_to_node)
+#define cpu_to_logical_apicid (genapic->cpu_to_logical_apicid)
+#define cpu_present_to_apicid (genapic->cpu_present_to_apicid)
+#define apicid_to_cpu_present (genapic->apicid_to_cpu_present)
+#define mpc_apic_id (genapic->mpc_apic_id)
+#define setup_portio_remap (genapic->setup_portio_remap)
+#define check_apicid_present (genapic->check_apicid_present)
+#define check_phys_apicid_present (genapic->check_phys_apicid_present)
+#define check_apicid_used (genapic->check_apicid_used)
+#define cpu_mask_to_apicid (genapic->cpu_mask_to_apicid)
+#define enable_apic_mode (genapic->enable_apic_mode)
+#define phys_pkg_id (genapic->phys_pkg_id)
+
+#endif /* __ASM_MACH_APIC_H */
diff --git a/xen/include/asm-x86/mach-generic/mach_apicdef.h b/xen/include/asm-x86/mach-generic/mach_apicdef.h
new file mode 100644
index 0000000000..28ed98972c
--- /dev/null
+++ b/xen/include/asm-x86/mach-generic/mach_apicdef.h
@@ -0,0 +1,11 @@
+#ifndef _GENAPIC_MACH_APICDEF_H
+#define _GENAPIC_MACH_APICDEF_H 1
+
+#ifndef APIC_DEFINITION
+#include <asm/genapic.h>
+
+#define GET_APIC_ID (genapic->get_apic_id)
+#define APIC_ID_MASK (genapic->apic_id_mask)
+#endif
+
+#endif
diff --git a/xen/include/asm-x86/mach-generic/mach_ipi.h b/xen/include/asm-x86/mach-generic/mach_ipi.h
new file mode 100644
index 0000000000..441b0fe3ed
--- /dev/null
+++ b/xen/include/asm-x86/mach-generic/mach_ipi.h
@@ -0,0 +1,10 @@
+#ifndef _MACH_IPI_H
+#define _MACH_IPI_H 1
+
+#include <asm/genapic.h>
+
+#define send_IPI_mask (genapic->send_IPI_mask)
+#define send_IPI_allbutself (genapic->send_IPI_allbutself)
+#define send_IPI_all (genapic->send_IPI_all)
+
+#endif
diff --git a/xen/include/asm-x86/mach-generic/mach_mpparse.h b/xen/include/asm-x86/mach-generic/mach_mpparse.h
new file mode 100644
index 0000000000..dbd9fce54f
--- /dev/null
+++ b/xen/include/asm-x86/mach-generic/mach_mpparse.h
@@ -0,0 +1,12 @@
+#ifndef _MACH_MPPARSE_H
+#define _MACH_MPPARSE_H 1
+
+#include <asm/genapic.h>
+
+#define mpc_oem_bus_info (genapic->mpc_oem_bus_info)
+#define mpc_oem_pci_bus (genapic->mpc_oem_pci_bus)
+
+int mps_oem_check(struct mp_config_table *mpc, char *oem, char *productid);
+int acpi_madt_oem_check(char *oem_id, char *oem_table_id);
+
+#endif
diff --git a/xen/include/asm-x86/mach-generic/mach_mpspec.h b/xen/include/asm-x86/mach-generic/mach_mpspec.h
new file mode 100644
index 0000000000..9ef0b941bb
--- /dev/null
+++ b/xen/include/asm-x86/mach-generic/mach_mpspec.h
@@ -0,0 +1,10 @@
+#ifndef __ASM_MACH_MPSPEC_H
+#define __ASM_MACH_MPSPEC_H
+
+#define MAX_IRQ_SOURCES 256
+
+/* Summit or generic (i.e. installer) kernels need lots of bus entries. */
+/* Maximum 256 PCI busses, plus 1 ISA bus in each of 4 cabinets. */
+#define MAX_MP_BUSSES 260
+
+#endif /* __ASM_MACH_MPSPEC_H */
diff --git a/xen/include/asm-x86/mach-summit/mach_apic.h b/xen/include/asm-x86/mach-summit/mach_apic.h
new file mode 100644
index 0000000000..61cac6b453
--- /dev/null
+++ b/xen/include/asm-x86/mach-summit/mach_apic.h
@@ -0,0 +1,189 @@
+#ifndef __ASM_MACH_APIC_H
+#define __ASM_MACH_APIC_H
+
+#include <xen/config.h>
+#include <asm/smp.h>
+
+#define esr_disable (1)
+#define NO_BALANCE_IRQ (0)
+
+#define NO_IOAPIC_CHECK (1) /* Don't check I/O APIC ID for xAPIC */
+
+/* In clustered mode, the high nibble of APIC ID is a cluster number.
+ * The low nibble is a 4-bit bitmap. */
+#define XAPIC_DEST_CPUS_SHIFT 4
+#define XAPIC_DEST_CPUS_MASK ((1u << XAPIC_DEST_CPUS_SHIFT) - 1)
+#define XAPIC_DEST_CLUSTER_MASK (XAPIC_DEST_CPUS_MASK << XAPIC_DEST_CPUS_SHIFT)
+
+#define APIC_DFR_VALUE (APIC_DFR_CLUSTER)
+
+static inline cpumask_t target_cpus(void)
+{
+ /* CPU_MASK_ALL (0xff) has undefined behaviour with
+ * dest_LowestPrio mode logical clustered apic interrupt routing
+ * Just start on cpu 0. IRQ balancing will spread load
+ */
+ return cpumask_of_cpu(0);
+}
+#define TARGET_CPUS (target_cpus())
+
+#define INT_DELIVERY_MODE (dest_LowestPrio)
+#define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */
+
+static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
+{
+ return 0;
+}
+
+/* we don't use the phys_cpu_present_map to indicate apicid presence */
+static inline unsigned long check_apicid_present(int bit)
+{
+ return 1;
+}
+
+#define apicid_cluster(apicid) ((apicid) & XAPIC_DEST_CLUSTER_MASK)
+
+extern u8 bios_cpu_apicid[];
+extern u8 cpu_2_logical_apicid[];
+
+static inline void init_apic_ldr(void)
+{
+ unsigned long val, id;
+ int i, count;
+ u8 lid;
+ u8 my_id = (u8)hard_smp_processor_id();
+ u8 my_cluster = (u8)apicid_cluster(my_id);
+
+ /* Create logical APIC IDs by counting CPUs already in cluster. */
+ for (count = 0, i = NR_CPUS; --i >= 0; ) {
+ lid = cpu_2_logical_apicid[i];
+ if (lid != BAD_APICID && apicid_cluster(lid) == my_cluster)
+ ++count;
+ }
+ /* We only have a 4 wide bitmap in cluster mode. If a deranged
+ * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */
+ BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT);
+ id = my_cluster | (1UL << count);
+ apic_write_around(APIC_DFR, APIC_DFR_VALUE);
+ val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
+ val |= SET_APIC_LOGICAL_ID(id);
+ apic_write_around(APIC_LDR, val);
+}
+
+static inline int multi_timer_check(int apic, int irq)
+{
+ return 0;
+}
+
+static inline int apic_id_registered(void)
+{
+ return 1;
+}
+
+static inline void clustered_apic_check(void)
+{
+ printk("Enabling APIC mode: Summit. Using %d I/O APICs\n",
+ nr_ioapics);
+}
+
+static inline int apicid_to_node(int logical_apicid)
+{
+ return logical_apicid >> 5; /* 2 clusterids per CEC */
+}
+
+/* Mapping from cpu number to logical apicid */
+static inline int cpu_to_logical_apicid(int cpu)
+{
+ if (cpu >= NR_CPUS)
+ return BAD_APICID;
+ return (int)cpu_2_logical_apicid[cpu];
+}
+
+static inline int cpu_present_to_apicid(int mps_cpu)
+{
+ if (mps_cpu < NR_CPUS)
+ return (int)bios_cpu_apicid[mps_cpu];
+ else
+ return BAD_APICID;
+}
+
+static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_id_map)
+{
+ /* For clustered we don't have a good way to do this yet - hack */
+ return physids_promote(0x0F);
+}
+
+static inline physid_mask_t apicid_to_cpu_present(int apicid)
+{
+ return physid_mask_of_physid(0);
+}
+
+static inline int mpc_apic_id(struct mpc_config_processor *m,
+ struct mpc_config_translation *translation_record)
+{
+ printk("Processor #%d %d:%d APIC version %d\n",
+ m->mpc_apicid,
+ (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8,
+ (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
+ m->mpc_apicver);
+ return (m->mpc_apicid);
+}
+
+static inline void setup_portio_remap(void)
+{
+}
+
+static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
+{
+ return 1;
+}
+
+static inline void enable_apic_mode(void)
+{
+}
+
+static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask)
+{
+ int num_bits_set;
+ int cpus_found = 0;
+ int cpu;
+ int apicid;
+
+ num_bits_set = cpus_weight(cpumask);
+ /* Return id to all */
+ if (num_bits_set == NR_CPUS)
+ return (int) 0xFF;
+ /*
+ * The cpus in the mask must all be on the apic cluster. If are not
+ * on the same apicid cluster return default value of TARGET_CPUS.
+ */
+ cpu = first_cpu(cpumask);
+ apicid = cpu_to_logical_apicid(cpu);
+ while (cpus_found < num_bits_set) {
+ if (cpu_isset(cpu, cpumask)) {
+ int new_apicid = cpu_to_logical_apicid(cpu);
+ if (apicid_cluster(apicid) !=
+ apicid_cluster(new_apicid)){
+ printk ("%s: Not a valid mask!\n",__FUNCTION__);
+ return 0xFF;
+ }
+ apicid = apicid | new_apicid;
+ cpus_found++;
+ }
+ cpu++;
+ }
+ return apicid;
+}
+
+/* cpuid returns the value latched in the HW at reset, not the APIC ID
+ * register's value. For any box whose BIOS changes APIC IDs, like
+ * clustered APIC systems, we must use hard_smp_processor_id.
+ *
+ * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID.
+ */
+static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
+{
+ return hard_smp_processor_id() >> index_msb;
+}
+
+#endif /* __ASM_MACH_APIC_H */
diff --git a/xen/include/asm-x86/mach-summit/mach_apicdef.h b/xen/include/asm-x86/mach-summit/mach_apicdef.h
new file mode 100644
index 0000000000..a58ab5a75c
--- /dev/null
+++ b/xen/include/asm-x86/mach-summit/mach_apicdef.h
@@ -0,0 +1,13 @@
+#ifndef __ASM_MACH_APICDEF_H
+#define __ASM_MACH_APICDEF_H
+
+#define APIC_ID_MASK (0xFF<<24)
+
+static inline unsigned get_apic_id(unsigned long x)
+{
+ return (((x)>>24)&0xFF);
+}
+
+#define GET_APIC_ID(x) get_apic_id(x)
+
+#endif
diff --git a/xen/include/asm-x86/mach-summit/mach_ipi.h b/xen/include/asm-x86/mach-summit/mach_ipi.h
new file mode 100644
index 0000000000..9404c535b7
--- /dev/null
+++ b/xen/include/asm-x86/mach-summit/mach_ipi.h
@@ -0,0 +1,25 @@
+#ifndef __ASM_MACH_IPI_H
+#define __ASM_MACH_IPI_H
+
+void send_IPI_mask_sequence(cpumask_t mask, int vector);
+
+static inline void send_IPI_mask(cpumask_t mask, int vector)
+{
+ send_IPI_mask_sequence(mask, vector);
+}
+
+static inline void send_IPI_allbutself(int vector)
+{
+ cpumask_t mask = cpu_online_map;
+ cpu_clear(smp_processor_id(), mask);
+
+ if (!cpus_empty(mask))
+ send_IPI_mask(mask, vector);
+}
+
+static inline void send_IPI_all(int vector)
+{
+ send_IPI_mask(cpu_online_map, vector);
+}
+
+#endif /* __ASM_MACH_IPI_H */
diff --git a/xen/include/asm-x86/mach-summit/mach_mpparse.h b/xen/include/asm-x86/mach-summit/mach_mpparse.h
new file mode 100644
index 0000000000..88f6c50da2
--- /dev/null
+++ b/xen/include/asm-x86/mach-summit/mach_mpparse.h
@@ -0,0 +1,121 @@
+#ifndef __ASM_MACH_MPPARSE_H
+#define __ASM_MACH_MPPARSE_H
+
+#include <mach_apic.h>
+
+extern int use_cyclone;
+
+#ifdef CONFIG_X86_SUMMIT_NUMA
+extern void setup_summit(void);
+#else
+#define setup_summit() {}
+#endif
+
+static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name,
+ struct mpc_config_translation *translation)
+{
+ Dprintk("Bus #%d is %s\n", m->mpc_busid, name);
+}
+
+static inline void mpc_oem_pci_bus(struct mpc_config_bus *m,
+ struct mpc_config_translation *translation)
+{
+}
+
+extern int usb_early_handoff;
+static inline int mps_oem_check(struct mp_config_table *mpc, char *oem,
+ char *productid)
+{
+ if (!strncmp(oem, "IBM ENSW", 8) &&
+ (!strncmp(productid, "VIGIL SMP", 9)
+ || !strncmp(productid, "EXA", 3)
+ || !strncmp(productid, "RUTHLESS SMP", 12))){
+ /*use_cyclone = 1;*/ /*enable cyclone-timer*/
+ setup_summit();
+ /*usb_early_handoff = 1;*/
+ return 1;
+ }
+ return 0;
+}
+
+/* Hook from generic ACPI tables.c */
+static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+ if (!strncmp(oem_id, "IBM", 3) &&
+ (!strncmp(oem_table_id, "SERVIGIL", 8)
+ || !strncmp(oem_table_id, "EXA", 3))){
+ /*use_cyclone = 1;*/ /*enable cyclone-timer*/
+ setup_summit();
+ /*usb_early_handoff = 1;*/
+ return 1;
+ }
+ return 0;
+}
+
+struct rio_table_hdr {
+ unsigned char version; /* Version number of this data structure */
+ /* Version 3 adds chassis_num & WP_index */
+ unsigned char num_scal_dev; /* # of Scalability devices (Twisters for Vigil) */
+ unsigned char num_rio_dev; /* # of RIO I/O devices (Cyclones and Winnipegs) */
+} __attribute__((packed));
+
+struct scal_detail {
+ unsigned char node_id; /* Scalability Node ID */
+ unsigned long CBAR; /* Address of 1MB register space */
+ unsigned char port0node; /* Node ID port connected to: 0xFF=None */
+ unsigned char port0port; /* Port num port connected to: 0,1,2, or 0xFF=None */
+ unsigned char port1node; /* Node ID port connected to: 0xFF = None */
+ unsigned char port1port; /* Port num port connected to: 0,1,2, or 0xFF=None */
+ unsigned char port2node; /* Node ID port connected to: 0xFF = None */
+ unsigned char port2port; /* Port num port connected to: 0,1,2, or 0xFF=None */
+ unsigned char chassis_num; /* 1 based Chassis number (1 = boot node) */
+} __attribute__((packed));
+
+struct rio_detail {
+ unsigned char node_id; /* RIO Node ID */
+ unsigned long BBAR; /* Address of 1MB register space */
+ unsigned char type; /* Type of device */
+ unsigned char owner_id; /* For WPEG: Node ID of Cyclone that owns this WPEG*/
+ /* For CYC: Node ID of Twister that owns this CYC */
+ unsigned char port0node; /* Node ID port connected to: 0xFF=None */
+ unsigned char port0port; /* Port num port connected to: 0,1,2, or 0xFF=None */
+ unsigned char port1node; /* Node ID port connected to: 0xFF=None */
+ unsigned char port1port; /* Port num port connected to: 0,1,2, or 0xFF=None */
+ unsigned char first_slot; /* For WPEG: Lowest slot number below this WPEG */
+ /* For CYC: 0 */
+ unsigned char status; /* For WPEG: Bit 0 = 1 : the XAPIC is used */
+ /* = 0 : the XAPIC is not used, ie:*/
+ /* ints fwded to another XAPIC */
+ /* Bits1:7 Reserved */
+ /* For CYC: Bits0:7 Reserved */
+ unsigned char WP_index; /* For WPEG: WPEG instance index - lower ones have */
+ /* lower slot numbers/PCI bus numbers */
+ /* For CYC: No meaning */
+ unsigned char chassis_num; /* 1 based Chassis number */
+ /* For LookOut WPEGs this field indicates the */
+ /* Expansion Chassis #, enumerated from Boot */
+ /* Node WPEG external port, then Boot Node CYC */
+ /* external port, then Next Vigil chassis WPEG */
+ /* external port, etc. */
+ /* Shared Lookouts have only 1 chassis number (the */
+ /* first one assigned) */
+} __attribute__((packed));
+
+
+typedef enum {
+ CompatTwister = 0, /* Compatibility Twister */
+ AltTwister = 1, /* Alternate Twister of internal 8-way */
+ CompatCyclone = 2, /* Compatibility Cyclone */
+ AltCyclone = 3, /* Alternate Cyclone of internal 8-way */
+ CompatWPEG = 4, /* Compatibility WPEG */
+ AltWPEG = 5, /* Second Planar WPEG */
+ LookOutAWPEG = 6, /* LookOut WPEG */
+ LookOutBWPEG = 7, /* LookOut WPEG */
+} node_type;
+
+static inline int is_WPEG(struct rio_detail *rio){
+ return (rio->type == CompatWPEG || rio->type == AltWPEG ||
+ rio->type == LookOutAWPEG || rio->type == LookOutBWPEG);
+}
+
+#endif /* __ASM_MACH_MPPARSE_H */
diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
index 529c4ed0b6..30f1a8fe93 100644
--- a/xen/include/asm-x86/page.h
+++ b/xen/include/asm-x86/page.h
@@ -54,12 +54,6 @@ typedef struct { unsigned long pt_lo; } pagetable_t;
#define HYPERVISOR_ENTRIES_PER_L2_PAGETABLE \
(L2_PAGETABLE_ENTRIES - DOMAIN_ENTRIES_PER_L2_PAGETABLE)
-#ifndef __ASSEMBLY__
-#include <asm/processor.h>
-#include <asm/fixmap.h>
-#include <asm/bitops.h>
-#include <asm/flushtlb.h>
-
#define linear_l1_table \
((l1_pgentry_t *)(LINEAR_PT_VIRT_START))
#define __linear_l2_table \
@@ -83,9 +77,10 @@ typedef struct { unsigned long pt_lo; } pagetable_t;
#define va_to_l1mfn(_ed, _va) \
(l2e_get_pfn(linear_l2_table(_ed)[_va>>L2_PAGETABLE_SHIFT]))
+#ifndef __ASSEMBLY__
extern root_pgentry_t idle_pg_table[ROOT_PAGETABLE_ENTRIES];
-
extern void paging_init(void);
+#endif
#define __pge_off() \
do { \
@@ -101,9 +96,6 @@ extern void paging_init(void);
: : "r" (mmu_cr4_features) ); \
} while ( 0 )
-#endif /* !__ASSEMBLY__ */
-
-
#define _PAGE_PRESENT 0x001UL
#define _PAGE_RW 0x002UL
#define _PAGE_USER 0x004UL
diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h
index f176427991..5b9eeaf17f 100644
--- a/xen/include/asm-x86/shadow.h
+++ b/xen/include/asm-x86/shadow.h
@@ -27,6 +27,7 @@
#include <xen/perfc.h>
#include <xen/sched.h>
#include <xen/mm.h>
+#include <asm/flushtlb.h>
#include <asm/processor.h>
#include <asm/domain_page.h>
#include <public/dom0_ops.h>
diff --git a/xen/include/asm-x86/system.h b/xen/include/asm-x86/system.h
index a614d11b4a..cb5f64d001 100644
--- a/xen/include/asm-x86/system.h
+++ b/xen/include/asm-x86/system.h
@@ -333,4 +333,6 @@ static inline int local_irq_is_enabled(void)
#define BROKEN_ACPI_Sx 0x0001
#define BROKEN_INIT_AFTER_S1 0x0002
+extern int es7000_plat;
+
#endif
diff --git a/xen/include/xen/dmi.h b/xen/include/xen/dmi.h
new file mode 100644
index 0000000000..d2bcf55608
--- /dev/null
+++ b/xen/include/xen/dmi.h
@@ -0,0 +1,47 @@
+#ifndef __DMI_H__
+#define __DMI_H__
+
+enum dmi_field {
+ DMI_NONE,
+ DMI_BIOS_VENDOR,
+ DMI_BIOS_VERSION,
+ DMI_BIOS_DATE,
+ DMI_SYS_VENDOR,
+ DMI_PRODUCT_NAME,
+ DMI_PRODUCT_VERSION,
+ DMI_BOARD_VENDOR,
+ DMI_BOARD_NAME,
+ DMI_BOARD_VERSION,
+ DMI_STRING_MAX,
+};
+
+/*
+ * DMI callbacks for problem boards
+ */
+struct dmi_strmatch {
+ u8 slot;
+ char *substr;
+};
+
+struct dmi_system_id {
+ int (*callback)(struct dmi_system_id *);
+ char *ident;
+ struct dmi_strmatch matches[4];
+ void *driver_data;
+};
+
+#define DMI_MATCH(a,b) { a, b }
+
+#if defined(CONFIG_X86) && !defined(CONFIG_X86_64)
+
+extern int dmi_check_system(struct dmi_system_id *list);
+extern char * dmi_get_system_info(int field);
+
+#else
+
+static inline int dmi_check_system(struct dmi_system_id *list) { return 0; }
+static inline char * dmi_get_system_info(int field) { return NULL; }
+
+#endif
+
+#endif /* __DMI_H__ */