diff options
author | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2005-05-25 17:29:20 +0000 |
---|---|---|
committer | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2005-05-25 17:29:20 +0000 |
commit | 7cd2aeee943e69146bd5965b7160d4a461d94fd4 (patch) | |
tree | c3b2643b0baafe8ef0005cc2dcd6f8d30011dfdc | |
parent | 5443ed833b79b2e3da48bf203bd2707f31c349e8 (diff) | |
download | xen-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>
54 files changed, 2418 insertions, 586 deletions
@@ -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__ */ |