[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: Fix management support on HP ProLiant systems.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1196940184 0 # Node ID 1936e6a79f850b91d2c4336df3405c20066e9a7f # Parent 90f02ca762448d7af4106b1552ded64cbea5919a x86: Fix management support on HP ProLiant systems. Adds support to allow host-platform-specific handling of I/O port traps. Specifically adds support to handle an HP ProLiant I/O port in a special way. Signed-off-by: Mike Garrett <michael.garrett@xxxxxx> Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/Makefile | 1 xen/arch/x86/ioport_emulate.c | 125 ++++++++++++++++++++++++++++++++++++++++++ xen/arch/x86/traps.c | 7 ++ 3 files changed, 132 insertions(+), 1 deletion(-) diff -r 90f02ca76244 -r 1936e6a79f85 xen/arch/x86/Makefile --- a/xen/arch/x86/Makefile Thu Dec 06 10:41:10 2007 +0000 +++ b/xen/arch/x86/Makefile Thu Dec 06 11:23:04 2007 +0000 @@ -24,6 +24,7 @@ obj-y += i387.o obj-y += i387.o obj-y += i8259.o obj-y += io_apic.o +obj-y += ioport_emulate.o obj-y += irq.o obj-y += microcode.o obj-y += mm.o diff -r 90f02ca76244 -r 1936e6a79f85 xen/arch/x86/ioport_emulate.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/arch/x86/ioport_emulate.c Thu Dec 06 11:23:04 2007 +0000 @@ -0,0 +1,125 @@ +/****************************************************************************** + * ioport_emulate.c + * + * Handle I/O port access quirks of various platforms. + */ + +#include <xen/config.h> +#include <xen/init.h> +#include <xen/sched.h> +#include <xen/dmi.h> + +/* Function pointer used to handle platform specific I/O port emulation. */ +extern void (*ioemul_handle_quirk)( + u8 opcode, char *io_emul_stub, struct cpu_user_regs *regs); + +static void ioemul_handle_proliant_quirk( + u8 opcode, char *io_emul_stub, struct cpu_user_regs *regs) +{ + uint16_t port = regs->edx; + uint8_t value = regs->eax; + + if ( (opcode != 0xee) || (port != 0xcd4) || !(value & 0x80) ) + return; + + /* pushfw */ + io_emul_stub[ 0] = 0x66; + io_emul_stub[ 1] = 0x9c; + /* cli */ + io_emul_stub[ 2] = 0xfa; + /* out %al,%dx */ + io_emul_stub[ 3] = 0xee; + /* 1: in %dx,%al */ + io_emul_stub[ 4] = 0xec; + /* test $0x80,%al */ + io_emul_stub[ 5] = 0xa8; + io_emul_stub[ 6] = 0x80; + /* jnz 1b */ + io_emul_stub[ 7] = 0x75; + io_emul_stub[ 8] = 0xfb; + /* popfw */ + io_emul_stub[ 9] = 0x66; + io_emul_stub[10] = 0x9d; + /* ret */ + io_emul_stub[11] = 0xc3; +} + +int __init proliant_quirk(struct dmi_system_id *d) +{ + ioemul_handle_quirk = ioemul_handle_proliant_quirk; + return 0; +} + +/* This table is the set of system-specific I/O emulation hooks. */ +static struct dmi_system_id __initdata ioport_quirks_tbl[] = { + /* + * I/O emulation hook for certain HP ProLiant servers with + * 'special' SMM goodness. + */ + { + .callback = proliant_quirk, + .ident = "HP ProLiant DL3xx", + .matches = { + DMI_MATCH(DMI_BIOS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL3"), + }, + }, + { + .callback = proliant_quirk, + .ident = "HP ProLiant DL5xx", + .matches = { + DMI_MATCH(DMI_BIOS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL5"), + }, + }, + { + .callback = proliant_quirk, + .ident = "HP ProLiant ML3xx", + .matches = { + DMI_MATCH(DMI_BIOS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant ML3"), + }, + }, + { + .callback = proliant_quirk, + .ident = "HP ProLiant ML5xx", + .matches = { + DMI_MATCH(DMI_BIOS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant ML5"), + }, + }, + { + .callback = proliant_quirk, + .ident = "HP ProLiant BL4xx", + .matches = { + DMI_MATCH(DMI_BIOS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL4"), + }, + }, + { + .callback = proliant_quirk, + .ident = "HP ProLiant BL6xx", + .matches = { + DMI_MATCH(DMI_BIOS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL6"), + }, + }, + { } +}; + +int __init ioport_quirks_init(void) +{ + dmi_check_system(ioport_quirks_tbl); + return 0; +} +__initcall(ioport_quirks_init); + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 90f02ca76244 -r 1936e6a79f85 xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Thu Dec 06 10:41:10 2007 +0000 +++ b/xen/arch/x86/traps.c Thu Dec 06 11:23:04 2007 +0000 @@ -110,6 +110,8 @@ DECLARE_TRAP_HANDLER(spurious_interrupt_ long do_set_debugreg(int reg, unsigned long value); unsigned long do_get_debugreg(int reg); +void (*ioemul_handle_quirk)( + u8 opcode, char *io_emul_stub, struct cpu_user_regs *regs); static int debug_stack_lines = 20; integer_param("debug_stack_lines", debug_stack_lines); @@ -1379,7 +1381,7 @@ static int emulate_privileged_op(struct ? (*(u32 *)®s->reg = (val)) \ : (*(u16 *)®s->reg = (val))) unsigned long code_base, code_limit; - char io_emul_stub[16]; + char io_emul_stub[32]; void (*io_emul)(struct cpu_user_regs *) __attribute__((__regparm__(1))); u32 l, h, eax, edx; @@ -1635,6 +1637,9 @@ static int emulate_privileged_op(struct /* Handy function-typed pointer to the stub. */ io_emul = (void *)io_emul_stub; + + if ( ioemul_handle_quirk ) + ioemul_handle_quirk(opcode, &io_emul_stub[12], regs); /* I/O Port and Interrupt Flag instructions. */ switch ( opcode ) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |