[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
# HG changeset patch # User Isaku Yamahata <yamahata@xxxxxxxxxxxxx> # Date 1231298418 -32400 # Node ID 661a839a481e30000c8ad8bcd231c93bd113e236 # Parent b8b66dc0fa1d39ca15f4e85430db7f2d3a7c304c # Parent 284a65851f54ece7f9cab8ec4da219be9c0fe752 merge with xen-unstable.hg --- Config.mk | 5 Makefile | 3 buildconfigs/src.tarball | 2 stubdom/Makefile | 20 tools/firmware/hvmloader/acpi/Makefile | 3 tools/firmware/hvmloader/acpi/dsdt.asl | 14 tools/firmware/hvmloader/acpi/dsdt.c | 995 +++++++++++++------------ tools/firmware/hvmloader/config.h | 11 tools/firmware/hvmloader/e820.h | 4 tools/firmware/hvmloader/hvmloader.c | 30 tools/firmware/hvmloader/smbios.c | 4 tools/firmware/hvmloader/util.c | 22 tools/firmware/rombios/rombios.c | 159 ++-- tools/firmware/rombios/rombios.h | 2 tools/libxc/xc_domain.c | 70 + tools/libxc/xc_hvm_build.c | 64 + tools/libxc/xc_pagetab.c | 234 +----- tools/libxc/xc_private.c | 39 + tools/libxc/xc_private.h | 5 tools/libxc/xc_ptrace.c | 5 tools/libxc/xenctrl.h | 17 tools/libxc/xenguest.h | 6 tools/libxc/xg_private.c | 1 tools/python/xen/lowlevel/xc/xc.c | 45 - tools/python/xen/util/pci.py | 16 tools/python/xen/xend/XendDomainInfo.py | 98 ++ tools/python/xen/xend/image.py | 7 tools/python/xen/xend/server/pciif.py | 2 tools/vnet/Makefile | 3 tools/xentrace/xenctx.c | 328 +++++--- xen/arch/ia64/xen/cpufreq/cpufreq.c | 3 xen/arch/x86/acpi/cpufreq/cpufreq.c | 7 xen/arch/x86/cpu/mcheck/mce_intel.c | 49 - xen/arch/x86/cpu/mcheck/x86_mca.h | 2 xen/arch/x86/domain.c | 5 xen/arch/x86/hvm/svm/svm.c | 2 xen/arch/x86/hvm/viridian.c | 4 xen/arch/x86/hvm/vmx/vmcs.c | 20 xen/arch/x86/hvm/vmx/vmx.c | 44 - xen/arch/x86/irq.c | 4 xen/arch/x86/mm.c | 43 + xen/arch/x86/mm/hap/p2m-ept.c | 10 xen/arch/x86/mm/p2m.c | 1149 ++++++++++++++++++++++++++++-- xen/arch/x86/mm/paging.c | 3 xen/arch/x86/mm/shadow/multi.c | 43 - xen/arch/x86/mm/shadow/types.h | 6 xen/arch/x86/setup.c | 1 xen/arch/x86/x86_64/compat/mm.c | 23 xen/common/domain.c | 31 xen/common/grant_table.c | 29 xen/common/memory.c | 64 + xen/common/schedule.c | 2 xen/drivers/acpi/pmstat.c | 27 xen/drivers/cpufreq/cpufreq.c | 16 xen/drivers/cpufreq/cpufreq_ondemand.c | 4 xen/drivers/cpufreq/utility.c | 91 +- xen/drivers/passthrough/vtd/iommu.c | 12 xen/include/acpi/cpufreq/cpufreq.h | 9 xen/include/acpi/cpufreq/processor_perf.h | 3 xen/include/asm-x86/guest_pt.h | 2 xen/include/asm-x86/p2m.h | 110 ++ xen/include/public/memory.h | 15 xen/include/xen/grant_table.h | 4 xen/include/xen/hypercall.h | 2 xen/include/xen/mm.h | 2 xen/include/xlat.lst | 1 66 files changed, 2934 insertions(+), 1122 deletions(-) diff -r b8b66dc0fa1d -r 661a839a481e Config.mk --- a/Config.mk Wed Jan 07 12:19:36 2009 +0900 +++ b/Config.mk Wed Jan 07 12:20:18 2009 +0900 @@ -96,6 +96,11 @@ FLASK_ENABLE ?= n FLASK_ENABLE ?= n ACM_SECURITY ?= n +XEN_EXTFILES_URL=http://xenbits.xensource.com/xen-extfiles +# All the files at that location were downloaded from elsewhere on +# the internet. The original download URL is preserved as a comment +# near the place in the Xen Makefiles where the file is used. + QEMU_REMOTE=http://xenbits.xensource.com/git-http/qemu-xen-unstable.git # Specify which qemu-dm to use. This may be `ioemu' to use the old diff -r b8b66dc0fa1d -r 661a839a481e Makefile --- a/Makefile Wed Jan 07 12:19:36 2009 +0900 +++ b/Makefile Wed Jan 07 12:20:18 2009 +0900 @@ -240,7 +240,8 @@ linux26: # TBOOT_TARFILE = tboot-20080613.tar.gz -TBOOT_BASE_URL = http://downloads.sourceforge.net/tboot +#TBOOT_BASE_URL = http://downloads.sourceforge.net/tboot +TBOOT_BASE_URL = $(XEN_EXTFILES_URL) .PHONY: build-tboot build-tboot: download_tboot diff -r b8b66dc0fa1d -r 661a839a481e buildconfigs/src.tarball --- a/buildconfigs/src.tarball Wed Jan 07 12:19:36 2009 +0900 +++ b/buildconfigs/src.tarball Wed Jan 07 12:20:18 2009 +0900 @@ -10,7 +10,7 @@ vpath linux-%.tar.bz2 $(LINUX_SRC_PATH) # download a pristine Linux kernel tarball if there isn't one in LINUX_SRC_PATH linux-%.tar.bz2: @echo "Cannot find $@ in path $(LINUX_SRC_PATH)" - wget $(XEN_LINUX_MIRROR)/$@ -O./$@ + false wget $(XEN_LINUX_MIRROR)/$@ -O./$@ # XXX create a pristine tree for diff -Nurp convenience diff -r b8b66dc0fa1d -r 661a839a481e stubdom/Makefile --- a/stubdom/Makefile Wed Jan 07 12:19:36 2009 +0900 +++ b/stubdom/Makefile Wed Jan 07 12:20:18 2009 +0900 @@ -8,15 +8,25 @@ include $(XEN_ROOT)/Config.mk include $(XEN_ROOT)/Config.mk IOEMU_OPTIONS=--disable-sdl --disable-opengl --disable-vnc-tls --disable-brlapi --disable-kqemu -ZLIB_URL?=http://www.zlib.net + +#ZLIB_URL?=http://www.zlib.net +ZLIB_URL=$(XEN_EXTFILES_URL) ZLIB_VERSION=1.2.3 -LIBPCI_URL?=http://www.kernel.org/pub/software/utils/pciutils + +#LIBPCI_URL?=http://www.kernel.org/pub/software/utils/pciutils +LIBPCI_URL?=$(XEN_EXTFILES_URL) LIBPCI_VERSION=2.2.9 -NEWLIB_URL?=ftp://sources.redhat.com/pub/newlib + +#NEWLIB_URL?=ftp://sources.redhat.com/pub/newlib +NEWLIB_URL?=$(XEN_EXTFILES_URL) NEWLIB_VERSION=1.16.0 -LWIP_URL?=http://download.savannah.gnu.org/releases/lwip + +#LWIP_URL?=http://download.savannah.gnu.org/releases/lwip +LWIP_URL?=$(XEN_EXTFILES_URL) LWIP_VERSION=1.3.0 -GRUB_URL?=http://alpha.gnu.org/gnu/grub + +#GRUB_URL?=http://alpha.gnu.org/gnu/grub +GRUB_URL?=$(XEN_EXTFILES_URL) GRUB_VERSION=0.97 WGET=wget -c diff -r b8b66dc0fa1d -r 661a839a481e tools/firmware/hvmloader/acpi/Makefile --- a/tools/firmware/hvmloader/acpi/Makefile Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/firmware/hvmloader/acpi/Makefile Wed Jan 07 12:20:18 2009 +0900 @@ -23,7 +23,8 @@ OBJS = $(patsubst %.c,%.o,$(C_SRC)) OBJS = $(patsubst %.c,%.o,$(C_SRC)) IASL_VER = acpica-unix-20080729 -IASL_URL = http://acpica.org/download/$(IASL_VER).tar.gz +#IASL_URL = http://acpica.org/download/$(IASL_VER).tar.gz +IASL_URL = $(XEN_EXTFILES_URL)/$(IASL_VER).tar.gz CFLAGS += -I. -I.. $(CFLAGS_include) diff -r b8b66dc0fa1d -r 661a839a481e tools/firmware/hvmloader/acpi/dsdt.asl --- a/tools/firmware/hvmloader/acpi/dsdt.asl Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/firmware/hvmloader/acpi/dsdt.asl Wed Jan 07 12:20:18 2009 +0900 @@ -122,6 +122,20 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, Name (_ADR, 0x00) Name (_BBN, 0x00) + /* + * Reserve the IO port ranges [0x10c0, 0x10c2] and [0xb044, 0xb047]. + * Or else, for a hotplugged-in device, the port IO BAR assigned + * by guest OS may conflict with the ranges here. + */ + Device(HP0) + { + Name(_HID, EISAID("PNP0C02")) + Name(_CRS, ResourceTemplate() { + IO (Decode16, 0x10c0, 0x10c0, 0x00, 0x03) + IO (Decode16, 0xb044, 0xb044, 0x00, 0x04) + }) + } + Method (_CRS, 0, NotSerialized) { Name (PRT0, ResourceTemplate () diff -r b8b66dc0fa1d -r 661a839a481e tools/firmware/hvmloader/acpi/dsdt.c --- a/tools/firmware/hvmloader/acpi/dsdt.c Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/firmware/hvmloader/acpi/dsdt.c Wed Jan 07 12:20:18 2009 +0900 @@ -1,22 +1,22 @@ /* * * Intel ACPI Component Architecture - * ASL Optimizing Compiler version 20060707 [Feb 16 2007] - * Copyright (C) 2000 - 2006 Intel Corporation + * ASL Optimizing Compiler version 20080729 [Dec 25 2008] + * Copyright (C) 2000 - 2008 Intel Corporation * Supports ACPI Specification Revision 3.0a * - * Compilation of "dsdt.asl" - Tue May 20 14:34:40 2008 + * Compilation of "dsdt.asl" - Thu Dec 25 17:00:32 2008 * * C source code output * */ unsigned char AmlCode[] = { - 0x44,0x53,0x44,0x54,0x32,0x11,0x00,0x00, /* 00000000 "DSDT2..." */ - 0x02,0xEC,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 "..Xen..." */ + 0x44,0x53,0x44,0x54,0x5E,0x11,0x00,0x00, /* 00000000 "DSDT^..." */ + 0x02,0xD1,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 "..Xen..." */ 0x48,0x56,0x4D,0x00,0x00,0x00,0x00,0x00, /* 00000010 "HVM....." */ 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ - 0x07,0x07,0x06,0x20,0x08,0x50,0x4D,0x42, /* 00000020 "... .PMB" */ + 0x29,0x07,0x08,0x20,0x08,0x50,0x4D,0x42, /* 00000020 ").. .PMB" */ 0x53,0x0B,0x00,0x0C,0x08,0x50,0x4D,0x4C, /* 00000028 "S....PML" */ 0x4E,0x0A,0x08,0x08,0x49,0x4F,0x42,0x31, /* 00000030 "N...IOB1" */ 0x00,0x08,0x49,0x4F,0x4C,0x31,0x00,0x08, /* 00000038 "..IOL1.." */ @@ -56,7 +56,7 @@ unsigned char AmlCode[] = 0x07,0x0A,0x07,0x00,0x00,0x08,0x50,0x49, /* 00000148 "......PI" */ 0x43,0x44,0x00,0x14,0x0C,0x5F,0x50,0x49, /* 00000150 "CD..._PI" */ 0x43,0x01,0x70,0x68,0x50,0x49,0x43,0x44, /* 00000158 "C.phPICD" */ - 0x10,0x42,0xF1,0x5F,0x53,0x42,0x5F,0x5B, /* 00000160 ".B._SB_[" */ + 0x10,0x4E,0xF3,0x5F,0x53,0x42,0x5F,0x5B, /* 00000160 ".N._SB_[" */ 0x80,0x42,0x49,0x4F,0x53,0x00,0x0C,0x00, /* 00000168 ".BIOS..." */ 0xA0,0x0E,0x00,0x0A,0x10,0x5B,0x81,0x21, /* 00000170 ".....[.!" */ 0x42,0x49,0x4F,0x53,0x01,0x55,0x41,0x52, /* 00000178 "BIOS.UAR" */ @@ -72,496 +72,501 @@ unsigned char AmlCode[] = 0x00,0xFF,0xFF,0x09,0x00,0x00,0x00,0x00, /* 000001C8 "........" */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000001D0 "........" */ 0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x00, /* 000001D8 "........" */ - 0x00,0x79,0x00,0x5B,0x82,0x4E,0xE8,0x50, /* 000001E0 ".y.[.N.P" */ + 0x00,0x79,0x00,0x5B,0x82,0x4A,0xEB,0x50, /* 000001E0 ".y.[.J.P" */ 0x43,0x49,0x30,0x08,0x5F,0x48,0x49,0x44, /* 000001E8 "CI0._HID" */ 0x0C,0x41,0xD0,0x0A,0x03,0x08,0x5F,0x55, /* 000001F0 ".A...._U" */ 0x49,0x44,0x00,0x08,0x5F,0x41,0x44,0x52, /* 000001F8 "ID.._ADR" */ - 0x00,0x08,0x5F,0x42,0x42,0x4E,0x00,0x14, /* 00000200 ".._BBN.." */ - 0x4E,0x0C,0x5F,0x43,0x52,0x53,0x00,0x08, /* 00000208 "N._CRS.." */ - 0x50,0x52,0x54,0x30,0x11,0x42,0x07,0x0A, /* 00000210 "PRT0.B.." */ - 0x6E,0x88,0x0D,0x00,0x02,0x0E,0x00,0x00, /* 00000218 "n......." */ - 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00, /* 00000220 "........" */ - 0x01,0x47,0x01,0xF8,0x0C,0xF8,0x0C,0x01, /* 00000228 ".G......" */ - 0x08,0x88,0x0D,0x00,0x01,0x0C,0x03,0x00, /* 00000230 "........" */ - 0x00,0x00,0x00,0xF7,0x0C,0x00,0x00,0xF8, /* 00000238 "........" */ - 0x0C,0x88,0x0D,0x00,0x01,0x0C,0x03,0x00, /* 00000240 "........" */ - 0x00,0x00,0x0D,0xFF,0xFF,0x00,0x00,0x00, /* 00000248 "........" */ - 0xF3,0x87,0x17,0x00,0x00,0x0C,0x03,0x00, /* 00000250 "........" */ - 0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0xFF, /* 00000258 "........" */ - 0xFF,0x0B,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000260 "........" */ - 0x00,0x02,0x00,0x87,0x17,0x00,0x00,0x0C, /* 00000268 "........" */ - 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000270 "........" */ - 0xF0,0xFF,0xFF,0xFF,0xF4,0x00,0x00,0x00, /* 00000278 "........" */ - 0x00,0x00,0x00,0x00,0x05,0x79,0x00,0x8A, /* 00000280 ".....y.." */ - 0x50,0x52,0x54,0x30,0x0A,0x5C,0x4D,0x4D, /* 00000288 "PRT0.\MM" */ - 0x49,0x4E,0x8A,0x50,0x52,0x54,0x30,0x0A, /* 00000290 "IN.PRT0." */ - 0x60,0x4D,0x4D,0x41,0x58,0x8A,0x50,0x52, /* 00000298 "`MMAX.PR" */ - 0x54,0x30,0x0A,0x68,0x4D,0x4C,0x45,0x4E, /* 000002A0 "T0.hMLEN" */ - 0x70,0x50,0x4D,0x49,0x4E,0x4D,0x4D,0x49, /* 000002A8 "pPMINMMI" */ - 0x4E,0x70,0x50,0x4C,0x45,0x4E,0x4D,0x4C, /* 000002B0 "NpPLENML" */ - 0x45,0x4E,0x72,0x4D,0x4D,0x49,0x4E,0x4D, /* 000002B8 "ENrMMINM" */ - 0x4C,0x45,0x4E,0x4D,0x4D,0x41,0x58,0x74, /* 000002C0 "LENMMAXt" */ - 0x4D,0x4D,0x41,0x58,0x01,0x4D,0x4D,0x41, /* 000002C8 "MMAX.MMA" */ - 0x58,0xA4,0x50,0x52,0x54,0x30,0x08,0x42, /* 000002D0 "X.PRT0.B" */ - 0x55,0x46,0x41,0x11,0x09,0x0A,0x06,0x23, /* 000002D8 "UFA....#" */ - 0x20,0x0C,0x18,0x79,0x00,0x08,0x42,0x55, /* 000002E0 " ..y..BU" */ - 0x46,0x42,0x11,0x09,0x0A,0x06,0x23,0x00, /* 000002E8 "FB....#." */ - 0x00,0x18,0x79,0x00,0x8B,0x42,0x55,0x46, /* 000002F0 "..y..BUF" */ - 0x42,0x01,0x49,0x52,0x51,0x56,0x5B,0x82, /* 000002F8 "B.IRQV[." */ - 0x48,0x08,0x4C,0x4E,0x4B,0x41,0x08,0x5F, /* 00000300 "H.LNKA._" */ - 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F, /* 00000308 "HID.A..." */ - 0x08,0x5F,0x55,0x49,0x44,0x01,0x14,0x1C, /* 00000310 "._UID..." */ - 0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49, /* 00000318 "_STA.{PI" */ - 0x52,0x41,0x0A,0x80,0x60,0xA0,0x08,0x93, /* 00000320 "RA..`..." */ - 0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04, /* 00000328 "`......." */ - 0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52, /* 00000330 "....._PR" */ - 0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14, /* 00000338 "S..BUFA." */ - 0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50, /* 00000340 "._DIS.}P" */ - 0x49,0x52,0x41,0x0A,0x80,0x50,0x49,0x52, /* 00000348 "IRA..PIR" */ - 0x41,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00, /* 00000350 "A.._CRS." */ - 0x7B,0x50,0x49,0x52,0x41,0x0A,0x0F,0x60, /* 00000358 "{PIRA..`" */ - 0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4, /* 00000360 "y.`IRQV." */ - 0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53, /* 00000368 "BUFB.._S" */ - 0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52, /* 00000370 "RS..h.IR" */ - 0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60, /* 00000378 "Q1.IRQ1`" */ - 0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x41, /* 00000380 "v`p`PIRA" */ - 0x5B,0x82,0x49,0x08,0x4C,0x4E,0x4B,0x42, /* 00000388 "[.I.LNKB" */ - 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000390 "._HID.A." */ - 0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A, /* 00000398 "..._UID." */ - 0x02,0x14,0x1C,0x5F,0x53,0x54,0x41,0x00, /* 000003A0 "..._STA." */ - 0x7B,0x50,0x49,0x52,0x42,0x0A,0x80,0x60, /* 000003A8 "{PIRB..`" */ - 0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A, /* 000003B0 "...`...." */ - 0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B, /* 000003B8 "........" */ - 0x5F,0x50,0x52,0x53,0x00,0xA4,0x42,0x55, /* 000003C0 "_PRS..BU" */ - 0x46,0x41,0x14,0x11,0x5F,0x44,0x49,0x53, /* 000003C8 "FA.._DIS" */ - 0x00,0x7D,0x50,0x49,0x52,0x42,0x0A,0x80, /* 000003D0 ".}PIRB.." */ - 0x50,0x49,0x52,0x42,0x14,0x1A,0x5F,0x43, /* 000003D8 "PIRB.._C" */ - 0x52,0x53,0x00,0x7B,0x50,0x49,0x52,0x42, /* 000003E0 "RS.{PIRB" */ - 0x0A,0x0F,0x60,0x79,0x01,0x60,0x49,0x52, /* 000003E8 "..`y.`IR" */ - 0x51,0x56,0xA4,0x42,0x55,0x46,0x42,0x14, /* 000003F0 "QV.BUFB." */ - 0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,0x68, /* 000003F8 "._SRS..h" */ - 0x01,0x49,0x52,0x51,0x31,0x82,0x49,0x52, /* 00000400 ".IRQ1.IR" */ - 0x51,0x31,0x60,0x76,0x60,0x70,0x60,0x50, /* 00000408 "Q1`v`p`P" */ - 0x49,0x52,0x42,0x5B,0x82,0x49,0x08,0x4C, /* 00000410 "IRB[.I.L" */ - 0x4E,0x4B,0x43,0x08,0x5F,0x48,0x49,0x44, /* 00000418 "NKC._HID" */ - 0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55, /* 00000420 ".A...._U" */ - 0x49,0x44,0x0A,0x03,0x14,0x1C,0x5F,0x53, /* 00000428 "ID...._S" */ - 0x54,0x41,0x00,0x7B,0x50,0x49,0x52,0x43, /* 00000430 "TA.{PIRC" */ - 0x0A,0x80,0x60,0xA0,0x08,0x93,0x60,0x0A, /* 00000438 "..`...`." */ - 0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A, /* 00000440 "........" */ - 0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53,0x00, /* 00000448 "..._PRS." */ - 0xA4,0x42,0x55,0x46,0x41,0x14,0x11,0x5F, /* 00000450 ".BUFA.._" */ - 0x44,0x49,0x53,0x00,0x7D,0x50,0x49,0x52, /* 00000458 "DIS.}PIR" */ - 0x43,0x0A,0x80,0x50,0x49,0x52,0x43,0x14, /* 00000460 "C..PIRC." */ - 0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B,0x50, /* 00000468 "._CRS.{P" */ - 0x49,0x52,0x43,0x0A,0x0F,0x60,0x79,0x01, /* 00000470 "IRC..`y." */ - 0x60,0x49,0x52,0x51,0x56,0xA4,0x42,0x55, /* 00000478 "`IRQV.BU" */ - 0x46,0x42,0x14,0x1B,0x5F,0x53,0x52,0x53, /* 00000480 "FB.._SRS" */ - 0x01,0x8B,0x68,0x01,0x49,0x52,0x51,0x31, /* 00000488 "..h.IRQ1" */ - 0x82,0x49,0x52,0x51,0x31,0x60,0x76,0x60, /* 00000490 ".IRQ1`v`" */ - 0x70,0x60,0x50,0x49,0x52,0x43,0x5B,0x82, /* 00000498 "p`PIRC[." */ - 0x49,0x08,0x4C,0x4E,0x4B,0x44,0x08,0x5F, /* 000004A0 "I.LNKD._" */ - 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F, /* 000004A8 "HID.A..." */ - 0x08,0x5F,0x55,0x49,0x44,0x0A,0x04,0x14, /* 000004B0 "._UID..." */ - 0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,0x50, /* 000004B8 "._STA.{P" */ - 0x49,0x52,0x44,0x0A,0x80,0x60,0xA0,0x08, /* 000004C0 "IRD..`.." */ - 0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1, /* 000004C8 ".`......" */ - 0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50, /* 000004D0 "......_P" */ - 0x52,0x53,0x00,0xA4,0x42,0x55,0x46,0x41, /* 000004D8 "RS..BUFA" */ - 0x14,0x11,0x5F,0x44,0x49,0x53,0x00,0x7D, /* 000004E0 ".._DIS.}" */ - 0x50,0x49,0x52,0x44,0x0A,0x80,0x50,0x49, /* 000004E8 "PIRD..PI" */ - 0x52,0x44,0x14,0x1A,0x5F,0x43,0x52,0x53, /* 000004F0 "RD.._CRS" */ - 0x00,0x7B,0x50,0x49,0x52,0x44,0x0A,0x0F, /* 000004F8 ".{PIRD.." */ - 0x60,0x79,0x01,0x60,0x49,0x52,0x51,0x56, /* 00000500 "`y.`IRQV" */ - 0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,0x5F, /* 00000508 ".BUFB.._" */ - 0x53,0x52,0x53,0x01,0x8B,0x68,0x01,0x49, /* 00000510 "SRS..h.I" */ - 0x52,0x51,0x31,0x82,0x49,0x52,0x51,0x31, /* 00000518 "RQ1.IRQ1" */ - 0x60,0x76,0x60,0x70,0x60,0x50,0x49,0x52, /* 00000520 "`v`p`PIR" */ - 0x44,0x5B,0x82,0x44,0x05,0x48,0x50,0x45, /* 00000528 "D[.D.HPE" */ - 0x54,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000530 "T._HID.A" */ - 0xD0,0x01,0x03,0x08,0x5F,0x55,0x49,0x44, /* 00000538 "...._UID" */ - 0x00,0x14,0x18,0x5F,0x53,0x54,0x41,0x00, /* 00000540 "..._STA." */ - 0xA0,0x0C,0x93,0x5E,0x5E,0x5E,0x48,0x50, /* 00000548 "...^^^HP" */ - 0x45,0x54,0x00,0xA4,0x00,0xA1,0x04,0xA4, /* 00000550 "ET......" */ - 0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000558 "..._CRS." */ - 0x1F,0x0A,0x1C,0x87,0x17,0x00,0x00,0x0D, /* 00000560 "........" */ - 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xD0, /* 00000568 "........" */ - 0xFE,0xFF,0x03,0xD0,0xFE,0x00,0x00,0x00, /* 00000570 "........" */ - 0x00,0x00,0x04,0x00,0x00,0x79,0x00,0x14, /* 00000578 ".....y.." */ - 0x16,0x5F,0x50,0x52,0x54,0x00,0xA0,0x0A, /* 00000580 "._PRT..." */ - 0x50,0x49,0x43,0x44,0xA4,0x50,0x52,0x54, /* 00000588 "PICD.PRT" */ - 0x41,0xA4,0x50,0x52,0x54,0x50,0x08,0x50, /* 00000590 "A.PRTP.P" */ - 0x52,0x54,0x50,0x12,0x49,0x36,0x3C,0x12, /* 00000598 "RTP.I6<." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00, /* 000005A0 "........" */ - 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04, /* 000005A8 "LNKB...." */ - 0x0C,0xFF,0xFF,0x01,0x00,0x01,0x4C,0x4E, /* 000005B0 "......LN" */ - 0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000005B8 "KC......" */ - 0xFF,0x01,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 000005C0 ".....LNK" */ - 0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 000005C8 "D......." */ - 0x01,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41, /* 000005D0 "....LNKA" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x02, /* 000005D8 "........" */ - 0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 000005E0 "..LNKC.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x01, /* 000005E8 "........" */ - 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 000005F0 "LNKD...." */ - 0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x02,0x4C, /* 000005F8 ".......L" */ - 0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C, /* 00000600 "NKA....." */ - 0xFF,0xFF,0x02,0x00,0x0A,0x03,0x4C,0x4E, /* 00000608 "......LN" */ - 0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000610 "KB......" */ - 0xFF,0x03,0x00,0x00,0x4C,0x4E,0x4B,0x44, /* 00000618 "....LNKD" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03, /* 00000620 "........" */ - 0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000628 "..LNKA.." */ - 0x0E,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A, /* 00000630 "........" */ - 0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E, /* 00000638 ".LNKB..." */ - 0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03, /* 00000640 "........" */ - 0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04, /* 00000648 "LNKC...." */ - 0x0C,0xFF,0xFF,0x04,0x00,0x00,0x4C,0x4E, /* 00000650 "......LN" */ - 0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000658 "KA......" */ - 0xFF,0x04,0x00,0x01,0x4C,0x4E,0x4B,0x42, /* 00000660 "....LNKB" */ - 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x04, /* 00000668 "........" */ - 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00, /* 00000670 "...LNKC." */ - 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 00000678 "........" */ - 0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 00000680 "..LNKD.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x00, /* 00000688 "........" */ - 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04, /* 00000690 "LNKB...." */ - 0x0C,0xFF,0xFF,0x05,0x00,0x01,0x4C,0x4E, /* 00000698 "......LN" */ - 0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000006A0 "KC......" */ - 0xFF,0x05,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 000006A8 ".....LNK" */ - 0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 000006B0 "D......." */ - 0x05,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41, /* 000006B8 "....LNKA" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x06, /* 000006C0 "........" */ - 0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 000006C8 "..LNKC.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x01, /* 000006D0 "........" */ - 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 000006D8 "LNKD...." */ - 0x0C,0xFF,0xFF,0x06,0x00,0x0A,0x02,0x4C, /* 000006E0 ".......L" */ - 0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C, /* 000006E8 "NKA....." */ - 0xFF,0xFF,0x06,0x00,0x0A,0x03,0x4C,0x4E, /* 000006F0 "......LN" */ - 0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000006F8 "KB......" */ - 0xFF,0x07,0x00,0x00,0x4C,0x4E,0x4B,0x44, /* 00000700 "....LNKD" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x07, /* 00000708 "........" */ - 0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000710 "..LNKA.." */ - 0x0E,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A, /* 00000718 "........" */ - 0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E, /* 00000720 ".LNKB..." */ - 0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x03, /* 00000728 "........" */ - 0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04, /* 00000730 "LNKC...." */ - 0x0C,0xFF,0xFF,0x08,0x00,0x00,0x4C,0x4E, /* 00000738 "......LN" */ - 0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000740 "KA......" */ - 0xFF,0x08,0x00,0x01,0x4C,0x4E,0x4B,0x42, /* 00000748 "....LNKB" */ - 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x08, /* 00000750 "........" */ - 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00, /* 00000758 "...LNKC." */ - 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x08,0x00, /* 00000760 "........" */ - 0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 00000768 "..LNKD.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x00, /* 00000770 "........" */ - 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04, /* 00000778 "LNKB...." */ - 0x0C,0xFF,0xFF,0x09,0x00,0x01,0x4C,0x4E, /* 00000780 "......LN" */ - 0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000788 "KC......" */ - 0xFF,0x09,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 00000790 ".....LNK" */ - 0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000798 "D......." */ - 0x09,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41, /* 000007A0 "....LNKA" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0A, /* 000007A8 "........" */ - 0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 000007B0 "..LNKC.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01, /* 000007B8 "........" */ - 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 000007C0 "LNKD...." */ - 0x0C,0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x4C, /* 000007C8 ".......L" */ - 0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C, /* 000007D0 "NKA....." */ - 0xFF,0xFF,0x0A,0x00,0x0A,0x03,0x4C,0x4E, /* 000007D8 "......LN" */ - 0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000007E0 "KB......" */ - 0xFF,0x0B,0x00,0x00,0x4C,0x4E,0x4B,0x44, /* 000007E8 "....LNKD" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0B, /* 000007F0 "........" */ - 0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 000007F8 "..LNKA.." */ - 0x0E,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A, /* 00000800 "........" */ - 0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E, /* 00000808 ".LNKB..." */ - 0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x03, /* 00000810 "........" */ - 0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04, /* 00000818 "LNKC...." */ - 0x0C,0xFF,0xFF,0x0C,0x00,0x00,0x4C,0x4E, /* 00000820 "......LN" */ - 0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000828 "KA......" */ - 0xFF,0x0C,0x00,0x01,0x4C,0x4E,0x4B,0x42, /* 00000830 "....LNKB" */ - 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0C, /* 00000838 "........" */ - 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00, /* 00000840 "...LNKC." */ - 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0C,0x00, /* 00000848 "........" */ - 0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 00000850 "..LNKD.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x00, /* 00000858 "........" */ - 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04, /* 00000860 "LNKB...." */ - 0x0C,0xFF,0xFF,0x0D,0x00,0x01,0x4C,0x4E, /* 00000868 "......LN" */ - 0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000870 "KC......" */ - 0xFF,0x0D,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 00000878 ".....LNK" */ - 0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000880 "D......." */ - 0x0D,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41, /* 00000888 "....LNKA" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0E, /* 00000890 "........" */ - 0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 00000898 "..LNKC.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x01, /* 000008A0 "........" */ - 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 000008A8 "LNKD...." */ - 0x0C,0xFF,0xFF,0x0E,0x00,0x0A,0x02,0x4C, /* 000008B0 ".......L" */ - 0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C, /* 000008B8 "NKA....." */ - 0xFF,0xFF,0x0E,0x00,0x0A,0x03,0x4C,0x4E, /* 000008C0 "......LN" */ - 0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000008C8 "KB......" */ - 0xFF,0x0F,0x00,0x00,0x4C,0x4E,0x4B,0x44, /* 000008D0 "....LNKD" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0F, /* 000008D8 "........" */ - 0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 000008E0 "..LNKA.." */ - 0x0E,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A, /* 000008E8 "........" */ - 0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E, /* 000008F0 ".LNKB..." */ - 0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x03, /* 000008F8 "........" */ - 0x4C,0x4E,0x4B,0x43,0x00,0x08,0x50,0x52, /* 00000900 "LNKC..PR" */ - 0x54,0x41,0x12,0x41,0x2F,0x3C,0x12,0x0B, /* 00000908 "TA.A/<.." */ - 0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00,0x00, /* 00000910 "........" */ - 0x0A,0x14,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000918 "........" */ - 0x01,0x00,0x01,0x00,0x0A,0x15,0x12,0x0C, /* 00000920 "........" */ - 0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02, /* 00000928 "........" */ - 0x00,0x0A,0x16,0x12,0x0C,0x04,0x0C,0xFF, /* 00000930 "........" */ - 0xFF,0x01,0x00,0x0A,0x03,0x00,0x0A,0x17, /* 00000938 "........" */ - 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x02,0x00, /* 00000940 "........" */ - 0x00,0x00,0x0A,0x18,0x12,0x0B,0x04,0x0C, /* 00000948 "........" */ - 0xFF,0xFF,0x02,0x00,0x01,0x00,0x0A,0x19, /* 00000950 "........" */ - 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x02,0x00, /* 00000958 "........" */ - 0x0A,0x02,0x00,0x0A,0x1A,0x12,0x0C,0x04, /* 00000960 "........" */ - 0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x03,0x00, /* 00000968 "........" */ - 0x0A,0x1B,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000970 "........" */ - 0x03,0x00,0x00,0x00,0x0A,0x1C,0x12,0x0B, /* 00000978 "........" */ - 0x04,0x0C,0xFF,0xFF,0x03,0x00,0x01,0x00, /* 00000980 "........" */ - 0x0A,0x1D,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000988 "........" */ - 0x03,0x00,0x0A,0x02,0x00,0x0A,0x1E,0x12, /* 00000990 "........" */ - 0x0C,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A, /* 00000998 "........" */ - 0x03,0x00,0x0A,0x1F,0x12,0x0B,0x04,0x0C, /* 000009A0 "........" */ - 0xFF,0xFF,0x04,0x00,0x00,0x00,0x0A,0x20, /* 000009A8 "....... " */ - 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 000009B0 "........" */ - 0x01,0x00,0x0A,0x21,0x12,0x0C,0x04,0x0C, /* 000009B8 "...!...." */ - 0xFF,0xFF,0x04,0x00,0x0A,0x02,0x00,0x0A, /* 000009C0 "........" */ - 0x22,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x04, /* 000009C8 ""......." */ - 0x00,0x0A,0x03,0x00,0x0A,0x23,0x12,0x0B, /* 000009D0 ".....#.." */ - 0x04,0x0C,0xFF,0xFF,0x05,0x00,0x00,0x00, /* 000009D8 "........" */ - 0x0A,0x24,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 000009E0 ".$......" */ - 0x05,0x00,0x01,0x00,0x0A,0x25,0x12,0x0C, /* 000009E8 ".....%.." */ - 0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02, /* 000009F0 "........" */ - 0x00,0x0A,0x26,0x12,0x0C,0x04,0x0C,0xFF, /* 000009F8 "..&....." */ - 0xFF,0x05,0x00,0x0A,0x03,0x00,0x0A,0x27, /* 00000A00 ".......'" */ - 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x06,0x00, /* 00000A08 "........" */ - 0x00,0x00,0x0A,0x28,0x12,0x0B,0x04,0x0C, /* 00000A10 "...(...." */ - 0xFF,0xFF,0x06,0x00,0x01,0x00,0x0A,0x29, /* 00000A18 ".......)" */ - 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x06,0x00, /* 00000A20 "........" */ - 0x0A,0x02,0x00,0x0A,0x2A,0x12,0x0C,0x04, /* 00000A28 "....*..." */ - 0x0C,0xFF,0xFF,0x06,0x00,0x0A,0x03,0x00, /* 00000A30 "........" */ - 0x0A,0x2B,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000A38 ".+......" */ - 0x07,0x00,0x00,0x00,0x0A,0x2C,0x12,0x0B, /* 00000A40 ".....,.." */ - 0x04,0x0C,0xFF,0xFF,0x07,0x00,0x01,0x00, /* 00000A48 "........" */ - 0x0A,0x2D,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000A50 ".-......" */ - 0x07,0x00,0x0A,0x02,0x00,0x0A,0x2E,0x12, /* 00000A58 "........" */ - 0x0C,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A, /* 00000A60 "........" */ - 0x03,0x00,0x0A,0x2F,0x12,0x0B,0x04,0x0C, /* 00000A68 ".../...." */ - 0xFF,0xFF,0x08,0x00,0x00,0x00,0x0A,0x11, /* 00000A70 "........" */ - 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x08,0x00, /* 00000A78 "........" */ - 0x01,0x00,0x0A,0x12,0x12,0x0C,0x04,0x0C, /* 00000A80 "........" */ - 0xFF,0xFF,0x08,0x00,0x0A,0x02,0x00,0x0A, /* 00000A88 "........" */ - 0x13,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x08, /* 00000A90 "........" */ - 0x00,0x0A,0x03,0x00,0x0A,0x14,0x12,0x0B, /* 00000A98 "........" */ - 0x04,0x0C,0xFF,0xFF,0x09,0x00,0x00,0x00, /* 00000AA0 "........" */ - 0x0A,0x15,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000AA8 "........" */ - 0x09,0x00,0x01,0x00,0x0A,0x16,0x12,0x0C, /* 00000AB0 "........" */ - 0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x02, /* 00000AB8 "........" */ - 0x00,0x0A,0x17,0x12,0x0C,0x04,0x0C,0xFF, /* 00000AC0 "........" */ - 0xFF,0x09,0x00,0x0A,0x03,0x00,0x0A,0x18, /* 00000AC8 "........" */ - 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0A,0x00, /* 00000AD0 "........" */ - 0x00,0x00,0x0A,0x19,0x12,0x0B,0x04,0x0C, /* 00000AD8 "........" */ - 0xFF,0xFF,0x0A,0x00,0x01,0x00,0x0A,0x1A, /* 00000AE0 "........" */ - 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0A,0x00, /* 00000AE8 "........" */ - 0x0A,0x02,0x00,0x0A,0x1B,0x12,0x0C,0x04, /* 00000AF0 "........" */ - 0x0C,0xFF,0xFF,0x0A,0x00,0x0A,0x03,0x00, /* 00000AF8 "........" */ - 0x0A,0x1C,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000B00 "........" */ - 0x0B,0x00,0x00,0x00,0x0A,0x1D,0x12,0x0B, /* 00000B08 "........" */ - 0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x01,0x00, /* 00000B10 "........" */ - 0x0A,0x1E,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000B18 "........" */ - 0x0B,0x00,0x0A,0x02,0x00,0x0A,0x1F,0x12, /* 00000B20 "........" */ - 0x0C,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A, /* 00000B28 "........" */ - 0x03,0x00,0x0A,0x20,0x12,0x0B,0x04,0x0C, /* 00000B30 "... ...." */ - 0xFF,0xFF,0x0C,0x00,0x00,0x00,0x0A,0x21, /* 00000B38 ".......!" */ - 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0C,0x00, /* 00000B40 "........" */ - 0x01,0x00,0x0A,0x22,0x12,0x0C,0x04,0x0C, /* 00000B48 "..."...." */ - 0xFF,0xFF,0x0C,0x00,0x0A,0x02,0x00,0x0A, /* 00000B50 "........" */ - 0x23,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0C, /* 00000B58 "#......." */ - 0x00,0x0A,0x03,0x00,0x0A,0x24,0x12,0x0B, /* 00000B60 ".....$.." */ - 0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x00,0x00, /* 00000B68 "........" */ - 0x0A,0x25,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000B70 ".%......" */ - 0x0D,0x00,0x01,0x00,0x0A,0x26,0x12,0x0C, /* 00000B78 ".....&.." */ - 0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02, /* 00000B80 "........" */ - 0x00,0x0A,0x27,0x12,0x0C,0x04,0x0C,0xFF, /* 00000B88 "..'....." */ - 0xFF,0x0D,0x00,0x0A,0x03,0x00,0x0A,0x28, /* 00000B90 ".......(" */ - 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0E,0x00, /* 00000B98 "........" */ - 0x00,0x00,0x0A,0x29,0x12,0x0B,0x04,0x0C, /* 00000BA0 "...)...." */ - 0xFF,0xFF,0x0E,0x00,0x01,0x00,0x0A,0x2A, /* 00000BA8 ".......*" */ - 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0E,0x00, /* 00000BB0 "........" */ - 0x0A,0x02,0x00,0x0A,0x2B,0x12,0x0C,0x04, /* 00000BB8 "....+..." */ - 0x0C,0xFF,0xFF,0x0E,0x00,0x0A,0x03,0x00, /* 00000BC0 "........" */ - 0x0A,0x2C,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000BC8 ".,......" */ - 0x0F,0x00,0x00,0x00,0x0A,0x2D,0x12,0x0B, /* 00000BD0 ".....-.." */ - 0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x01,0x00, /* 00000BD8 "........" */ - 0x0A,0x2E,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000BE0 "........" */ - 0x0F,0x00,0x0A,0x02,0x00,0x0A,0x2F,0x12, /* 00000BE8 "....../." */ - 0x0C,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A, /* 00000BF0 "........" */ - 0x03,0x00,0x0A,0x10,0x5B,0x82,0x46,0x37, /* 00000BF8 "....[.F7" */ - 0x49,0x53,0x41,0x5F,0x08,0x5F,0x41,0x44, /* 00000C00 "ISA_._AD" */ - 0x52,0x0C,0x00,0x00,0x01,0x00,0x5B,0x80, /* 00000C08 "R.....[." */ - 0x50,0x49,0x52,0x51,0x02,0x0A,0x60,0x0A, /* 00000C10 "PIRQ..`." */ - 0x04,0x10,0x2E,0x5C,0x00,0x5B,0x81,0x29, /* 00000C18 "...\.[.)" */ - 0x5C,0x2F,0x04,0x5F,0x53,0x42,0x5F,0x50, /* 00000C20 "\/._SB_P" */ - 0x43,0x49,0x30,0x49,0x53,0x41,0x5F,0x50, /* 00000C28 "CI0ISA_P" */ - 0x49,0x52,0x51,0x01,0x50,0x49,0x52,0x41, /* 00000C30 "IRQ.PIRA" */ - 0x08,0x50,0x49,0x52,0x42,0x08,0x50,0x49, /* 00000C38 ".PIRB.PI" */ - 0x52,0x43,0x08,0x50,0x49,0x52,0x44,0x08, /* 00000C40 "RC.PIRD." */ - 0x5B,0x82,0x46,0x0B,0x53,0x59,0x53,0x52, /* 00000C48 "[.F.SYSR" */ - 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000C50 "._HID.A." */ - 0x0C,0x02,0x08,0x5F,0x55,0x49,0x44,0x01, /* 00000C58 "..._UID." */ - 0x08,0x43,0x52,0x53,0x5F,0x11,0x4E,0x08, /* 00000C60 ".CRS_.N." */ - 0x0A,0x8A,0x47,0x01,0x10,0x00,0x10,0x00, /* 00000C68 "..G....." */ - 0x00,0x10,0x47,0x01,0x22,0x00,0x22,0x00, /* 00000C70 "..G."."." */ - 0x00,0x0C,0x47,0x01,0x30,0x00,0x30,0x00, /* 00000C78 "..G.0.0." */ - 0x00,0x10,0x47,0x01,0x44,0x00,0x44,0x00, /* 00000C80 "..G.D.D." */ - 0x00,0x1C,0x47,0x01,0x62,0x00,0x62,0x00, /* 00000C88 "..G.b.b." */ - 0x00,0x02,0x47,0x01,0x65,0x00,0x65,0x00, /* 00000C90 "..G.e.e." */ - 0x00,0x0B,0x47,0x01,0x72,0x00,0x72,0x00, /* 00000C98 "..G.r.r." */ - 0x00,0x0E,0x47,0x01,0x80,0x00,0x80,0x00, /* 00000CA0 "..G....." */ - 0x00,0x01,0x47,0x01,0x84,0x00,0x84,0x00, /* 00000CA8 "..G....." */ - 0x00,0x03,0x47,0x01,0x88,0x00,0x88,0x00, /* 00000CB0 "..G....." */ - 0x00,0x01,0x47,0x01,0x8C,0x00,0x8C,0x00, /* 00000CB8 "..G....." */ - 0x00,0x03,0x47,0x01,0x90,0x00,0x90,0x00, /* 00000CC0 "..G....." */ - 0x00,0x10,0x47,0x01,0xA2,0x00,0xA2,0x00, /* 00000CC8 "..G....." */ - 0x00,0x1C,0x47,0x01,0xE0,0x00,0xE0,0x00, /* 00000CD0 "..G....." */ - 0x00,0x10,0x47,0x01,0xA0,0x08,0xA0,0x08, /* 00000CD8 "..G....." */ - 0x00,0x04,0x47,0x01,0xC0,0x0C,0xC0,0x0C, /* 00000CE0 "..G....." */ - 0x00,0x10,0x47,0x01,0xD0,0x04,0xD0,0x04, /* 00000CE8 "..G....." */ - 0x00,0x02,0x79,0x00,0x14,0x0B,0x5F,0x43, /* 00000CF0 "..y..._C" */ - 0x52,0x53,0x00,0xA4,0x43,0x52,0x53,0x5F, /* 00000CF8 "RS..CRS_" */ - 0x5B,0x82,0x2B,0x50,0x49,0x43,0x5F,0x08, /* 00000D00 "[.+PIC_." */ - 0x5F,0x48,0x49,0x44,0x0B,0x41,0xD0,0x08, /* 00000D08 "_HID.A.." */ - 0x5F,0x43,0x52,0x53,0x11,0x18,0x0A,0x15, /* 00000D10 "_CRS...." */ - 0x47,0x01,0x20,0x00,0x20,0x00,0x01,0x02, /* 00000D18 "G. . ..." */ - 0x47,0x01,0xA0,0x00,0xA0,0x00,0x01,0x02, /* 00000D20 "G......." */ - 0x22,0x04,0x00,0x79,0x00,0x5B,0x82,0x47, /* 00000D28 ""..y.[.G" */ - 0x05,0x44,0x4D,0x41,0x30,0x08,0x5F,0x48, /* 00000D30 ".DMA0._H" */ - 0x49,0x44,0x0C,0x41,0xD0,0x02,0x00,0x08, /* 00000D38 "ID.A...." */ - 0x5F,0x43,0x52,0x53,0x11,0x41,0x04,0x0A, /* 00000D40 "_CRS.A.." */ - 0x3D,0x2A,0x10,0x04,0x47,0x01,0x00,0x00, /* 00000D48 "=*..G..." */ - 0x00,0x00,0x00,0x10,0x47,0x01,0x81,0x00, /* 00000D50 "....G..." */ - 0x81,0x00,0x00,0x03,0x47,0x01,0x87,0x00, /* 00000D58 "....G..." */ - 0x87,0x00,0x00,0x01,0x47,0x01,0x89,0x00, /* 00000D60 "....G..." */ - 0x89,0x00,0x00,0x03,0x47,0x01,0x8F,0x00, /* 00000D68 "....G..." */ - 0x8F,0x00,0x00,0x01,0x47,0x01,0xC0,0x00, /* 00000D70 "....G..." */ - 0xC0,0x00,0x00,0x20,0x47,0x01,0x80,0x04, /* 00000D78 "... G..." */ - 0x80,0x04,0x00,0x10,0x79,0x00,0x5B,0x82, /* 00000D80 "....y.[." */ - 0x25,0x54,0x4D,0x52,0x5F,0x08,0x5F,0x48, /* 00000D88 "%TMR_._H" */ - 0x49,0x44,0x0C,0x41,0xD0,0x01,0x00,0x08, /* 00000D90 "ID.A...." */ - 0x5F,0x43,0x52,0x53,0x11,0x10,0x0A,0x0D, /* 00000D98 "_CRS...." */ - 0x47,0x01,0x40,0x00,0x40,0x00,0x00,0x04, /* 00000DA0 "G.@.@..." */ - 0x22,0x01,0x00,0x79,0x00,0x5B,0x82,0x25, /* 00000DA8 ""..y.[.%" */ - 0x52,0x54,0x43,0x5F,0x08,0x5F,0x48,0x49, /* 00000DB0 "RTC_._HI" */ - 0x44,0x0C,0x41,0xD0,0x0B,0x00,0x08,0x5F, /* 00000DB8 "D.A...._" */ - 0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47, /* 00000DC0 "CRS....G" */ - 0x01,0x70,0x00,0x70,0x00,0x00,0x02,0x22, /* 00000DC8 ".p.p..."" */ - 0x00,0x01,0x79,0x00,0x5B,0x82,0x22,0x53, /* 00000DD0 "..y.[."S" */ - 0x50,0x4B,0x52,0x08,0x5F,0x48,0x49,0x44, /* 00000DD8 "PKR._HID" */ - 0x0C,0x41,0xD0,0x08,0x00,0x08,0x5F,0x43, /* 00000DE0 ".A...._C" */ - 0x52,0x53,0x11,0x0D,0x0A,0x0A,0x47,0x01, /* 00000DE8 "RS....G." */ - 0x61,0x00,0x61,0x00,0x00,0x01,0x79,0x00, /* 00000DF0 "a.a...y." */ - 0x5B,0x82,0x31,0x50,0x53,0x32,0x4D,0x08, /* 00000DF8 "[.1PS2M." */ - 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0F, /* 00000E00 "_HID.A.." */ - 0x13,0x08,0x5F,0x43,0x49,0x44,0x0C,0x41, /* 00000E08 ".._CID.A" */ - 0xD0,0x0F,0x13,0x14,0x09,0x5F,0x53,0x54, /* 00000E10 "....._ST" */ - 0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43, /* 00000E18 "A....._C" */ - 0x52,0x53,0x11,0x08,0x0A,0x05,0x22,0x00, /* 00000E20 "RS...."." */ - 0x10,0x79,0x00,0x5B,0x82,0x42,0x04,0x50, /* 00000E28 ".y.[.B.P" */ - 0x53,0x32,0x4B,0x08,0x5F,0x48,0x49,0x44, /* 00000E30 "S2K._HID" */ - 0x0C,0x41,0xD0,0x03,0x03,0x08,0x5F,0x43, /* 00000E38 ".A...._C" */ - 0x49,0x44,0x0C,0x41,0xD0,0x03,0x0B,0x14, /* 00000E40 "ID.A...." */ - 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000E48 "._STA..." */ - 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x18, /* 00000E50 ".._CRS.." */ - 0x0A,0x15,0x47,0x01,0x60,0x00,0x60,0x00, /* 00000E58 "..G.`.`." */ - 0x00,0x01,0x47,0x01,0x64,0x00,0x64,0x00, /* 00000E60 "..G.d.d." */ - 0x00,0x01,0x22,0x02,0x00,0x79,0x00,0x5B, /* 00000E68 ".."..y.[" */ - 0x82,0x3A,0x46,0x44,0x43,0x30,0x08,0x5F, /* 00000E70 ".:FDC0._" */ - 0x48,0x49,0x44,0x0C,0x41,0xD0,0x07,0x00, /* 00000E78 "HID.A..." */ - 0x14,0x09,0x5F,0x53,0x54,0x41,0x00,0xA4, /* 00000E80 ".._STA.." */ - 0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000E88 "..._CRS." */ - 0x1B,0x0A,0x18,0x47,0x01,0xF0,0x03,0xF0, /* 00000E90 "...G...." */ - 0x03,0x01,0x06,0x47,0x01,0xF7,0x03,0xF7, /* 00000E98 "...G...." */ - 0x03,0x01,0x01,0x22,0x40,0x00,0x2A,0x04, /* 00000EA0 "..."@.*." */ - 0x00,0x79,0x00,0x5B,0x82,0x46,0x04,0x55, /* 00000EA8 ".y.[.F.U" */ - 0x41,0x52,0x31,0x08,0x5F,0x48,0x49,0x44, /* 00000EB0 "AR1._HID" */ - 0x0C,0x41,0xD0,0x05,0x01,0x08,0x5F,0x55, /* 00000EB8 ".A...._U" */ - 0x49,0x44,0x01,0x14,0x19,0x5F,0x53,0x54, /* 00000EC0 "ID..._ST" */ - 0x41,0x00,0xA0,0x0D,0x93,0x5E,0x5E,0x5E, /* 00000EC8 "A....^^^" */ - 0x5E,0x55,0x41,0x52,0x31,0x00,0xA4,0x00, /* 00000ED0 "^UAR1..." */ - 0xA1,0x04,0xA4,0x0A,0x0F,0x08,0x5F,0x43, /* 00000ED8 "......_C" */ - 0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01, /* 00000EE0 "RS....G." */ - 0xF8,0x03,0xF8,0x03,0x08,0x08,0x22,0x10, /* 00000EE8 "......"." */ - 0x00,0x79,0x00,0x5B,0x82,0x47,0x04,0x55, /* 00000EF0 ".y.[.G.U" */ - 0x41,0x52,0x32,0x08,0x5F,0x48,0x49,0x44, /* 00000EF8 "AR2._HID" */ - 0x0C,0x41,0xD0,0x05,0x01,0x08,0x5F,0x55, /* 00000F00 ".A...._U" */ - 0x49,0x44,0x0A,0x02,0x14,0x19,0x5F,0x53, /* 00000F08 "ID...._S" */ - 0x54,0x41,0x00,0xA0,0x0D,0x93,0x5E,0x5E, /* 00000F10 "TA....^^" */ - 0x5E,0x5E,0x55,0x41,0x52,0x32,0x00,0xA4, /* 00000F18 "^^UAR2.." */ - 0x00,0xA1,0x04,0xA4,0x0A,0x0F,0x08,0x5F, /* 00000F20 "......._" */ - 0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47, /* 00000F28 "CRS....G" */ - 0x01,0xF8,0x02,0xF8,0x02,0x08,0x08,0x22, /* 00000F30 "......."" */ - 0x08,0x00,0x79,0x00,0x5B,0x82,0x36,0x4C, /* 00000F38 "..y.[.6L" */ - 0x54,0x50,0x31,0x08,0x5F,0x48,0x49,0x44, /* 00000F40 "TP1._HID" */ - 0x0C,0x41,0xD0,0x04,0x00,0x08,0x5F,0x55, /* 00000F48 ".A...._U" */ - 0x49,0x44,0x0A,0x02,0x14,0x09,0x5F,0x53, /* 00000F50 "ID...._S" */ - 0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F, /* 00000F58 "TA....._" */ - 0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47, /* 00000F60 "CRS....G" */ - 0x01,0x78,0x03,0x78,0x03,0x08,0x08,0x22, /* 00000F68 ".x.x..."" */ - 0x80,0x00,0x79,0x00,0x5B,0x82,0x4D,0x07, /* 00000F70 "..y.[.M." */ - 0x53,0x31,0x46,0x30,0x08,0x5F,0x41,0x44, /* 00000F78 "S1F0._AD" */ - 0x52,0x0C,0x00,0x00,0x06,0x00,0x08,0x5F, /* 00000F80 "R......_" */ - 0x53,0x55,0x4E,0x01,0x14,0x13,0x5F,0x50, /* 00000F88 "SUN..._P" */ - 0x53,0x30,0x00,0x70,0x0A,0x80,0x5C,0x2E, /* 00000F90 "S0.p..\." */ - 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00000F98 "_GPEDPT2" */ - 0x14,0x13,0x5F,0x50,0x53,0x33,0x00,0x70, /* 00000FA0 ".._PS3.p" */ - 0x0A,0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00000FA8 "..\._GPE" */ - 0x44,0x50,0x54,0x32,0x14,0x1F,0x5F,0x45, /* 00000FB0 "DPT2.._E" */ - 0x4A,0x30,0x01,0x70,0x0A,0x88,0x5C,0x2E, /* 00000FB8 "J0.p..\." */ - 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00000FC0 "_GPEDPT2" */ - 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00000FC8 "p.\._GPE" */ - 0x50,0x48,0x50,0x31,0x14,0x1E,0x5F,0x53, /* 00000FD0 "PHP1.._S" */ - 0x54,0x41,0x00,0x70,0x0A,0x89,0x5C,0x2E, /* 00000FD8 "TA.p..\." */ - 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00000FE0 "_GPEDPT2" */ - 0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50, /* 00000FE8 ".\._GPEP" */ - 0x48,0x50,0x31,0x5B,0x82,0x4E,0x07,0x53, /* 00000FF0 "HP1[.N.S" */ - 0x32,0x46,0x30,0x08,0x5F,0x41,0x44,0x52, /* 00000FF8 "2F0._ADR" */ - 0x0C,0x00,0x00,0x07,0x00,0x08,0x5F,0x53, /* 00001000 "......_S" */ - 0x55,0x4E,0x0A,0x02,0x14,0x13,0x5F,0x50, /* 00001008 "UN...._P" */ - 0x53,0x30,0x00,0x70,0x0A,0x90,0x5C,0x2E, /* 00001010 "S0.p..\." */ - 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00001018 "_GPEDPT2" */ - 0x14,0x13,0x5F,0x50,0x53,0x33,0x00,0x70, /* 00001020 ".._PS3.p" */ - 0x0A,0x93,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001028 "..\._GPE" */ - 0x44,0x50,0x54,0x32,0x14,0x1F,0x5F,0x45, /* 00001030 "DPT2.._E" */ - 0x4A,0x30,0x01,0x70,0x0A,0x98,0x5C,0x2E, /* 00001038 "J0.p..\." */ - 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00001040 "_GPEDPT2" */ - 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001048 "p.\._GPE" */ - 0x50,0x48,0x50,0x32,0x14,0x1E,0x5F,0x53, /* 00001050 "PHP2.._S" */ - 0x54,0x41,0x00,0x70,0x0A,0x99,0x5C,0x2E, /* 00001058 "TA.p..\." */ - 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00001060 "_GPEDPT2" */ - 0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50, /* 00001068 ".\._GPEP" */ - 0x48,0x50,0x32,0x10,0x4E,0x0B,0x5F,0x47, /* 00001070 "HP2.N._G" */ - 0x50,0x45,0x5B,0x80,0x50,0x48,0x50,0x5F, /* 00001078 "PE[.PHP_" */ - 0x01,0x0B,0xC0,0x10,0x0A,0x03,0x5B,0x81, /* 00001080 "......[." */ - 0x15,0x50,0x48,0x50,0x5F,0x01,0x50,0x53, /* 00001088 ".PHP_.PS" */ - 0x54,0x41,0x08,0x50,0x48,0x50,0x31,0x08, /* 00001090 "TA.PHP1." */ - 0x50,0x48,0x50,0x32,0x08,0x5B,0x80,0x44, /* 00001098 "PHP2.[.D" */ - 0x47,0x31,0x5F,0x01,0x0B,0x44,0xB0,0x0A, /* 000010A0 "G1_..D.." */ - 0x04,0x5B,0x81,0x10,0x44,0x47,0x31,0x5F, /* 000010A8 ".[..DG1_" */ - 0x01,0x44,0x50,0x54,0x31,0x08,0x44,0x50, /* 000010B0 ".DPT1.DP" */ - 0x54,0x32,0x08,0x14,0x46,0x07,0x5F,0x4C, /* 000010B8 "T2..F._L" */ - 0x30,0x33,0x00,0x08,0x53,0x4C,0x54,0x5F, /* 000010C0 "03..SLT_" */ - 0x00,0x08,0x45,0x56,0x54,0x5F,0x00,0x70, /* 000010C8 "..EVT_.p" */ - 0x50,0x53,0x54,0x41,0x61,0x7A,0x61,0x0A, /* 000010D0 "PSTAaza." */ - 0x04,0x53,0x4C,0x54,0x5F,0x7B,0x61,0x0A, /* 000010D8 ".SLT_{a." */ - 0x0F,0x45,0x56,0x54,0x5F,0x70,0x53,0x4C, /* 000010E0 ".EVT_pSL" */ - 0x54,0x5F,0x44,0x50,0x54,0x31,0x70,0x45, /* 000010E8 "T_DPT1pE" */ - 0x56,0x54,0x5F,0x44,0x50,0x54,0x32,0xA0, /* 000010F0 "VT_DPT2." */ - 0x1B,0x93,0x53,0x4C,0x54,0x5F,0x01,0x86, /* 000010F8 "..SLT_.." */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 00001100 "\/._SB_P" */ - 0x43,0x49,0x30,0x53,0x31,0x46,0x30,0x45, /* 00001108 "CI0S1F0E" */ - 0x56,0x54,0x5F,0xA1,0x1E,0xA0,0x1C,0x93, /* 00001110 "VT_....." */ - 0x53,0x4C,0x54,0x5F,0x0A,0x02,0x86,0x5C, /* 00001118 "SLT_...\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00001120 "/._SB_PC" */ - 0x49,0x30,0x53,0x32,0x46,0x30,0x45,0x56, /* 00001128 "I0S2F0EV" */ - 0x54,0x5F, + 0x00,0x08,0x5F,0x42,0x42,0x4E,0x00,0x5B, /* 00000200 ".._BBN.[" */ + 0x82,0x2A,0x48,0x50,0x30,0x5F,0x08,0x5F, /* 00000208 ".*HP0_._" */ + 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x02, /* 00000210 "HID.A..." */ + 0x08,0x5F,0x43,0x52,0x53,0x11,0x15,0x0A, /* 00000218 "._CRS..." */ + 0x12,0x47,0x01,0xC0,0x10,0xC0,0x10,0x00, /* 00000220 ".G......" */ + 0x03,0x47,0x01,0x44,0xB0,0x44,0xB0,0x00, /* 00000228 ".G.D.D.." */ + 0x04,0x79,0x00,0x14,0x4E,0x0C,0x5F,0x43, /* 00000230 ".y..N._C" */ + 0x52,0x53,0x00,0x08,0x50,0x52,0x54,0x30, /* 00000238 "RS..PRT0" */ + 0x11,0x42,0x07,0x0A,0x6E,0x88,0x0D,0x00, /* 00000240 ".B..n..." */ + 0x02,0x0E,0x00,0x00,0x00,0x00,0x00,0xFF, /* 00000248 "........" */ + 0x00,0x00,0x00,0x00,0x01,0x47,0x01,0xF8, /* 00000250 ".....G.." */ + 0x0C,0xF8,0x0C,0x01,0x08,0x88,0x0D,0x00, /* 00000258 "........" */ + 0x01,0x0C,0x03,0x00,0x00,0x00,0x00,0xF7, /* 00000260 "........" */ + 0x0C,0x00,0x00,0xF8,0x0C,0x88,0x0D,0x00, /* 00000268 "........" */ + 0x01,0x0C,0x03,0x00,0x00,0x00,0x0D,0xFF, /* 00000270 "........" */ + 0xFF,0x00,0x00,0x00,0xF3,0x87,0x17,0x00, /* 00000278 "........" */ + 0x00,0x0C,0x03,0x00,0x00,0x00,0x00,0x00, /* 00000280 "........" */ + 0x00,0x0A,0x00,0xFF,0xFF,0x0B,0x00,0x00, /* 00000288 "........" */ + 0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x87, /* 00000290 "........" */ + 0x17,0x00,0x00,0x0C,0x03,0x00,0x00,0x00, /* 00000298 "........" */ + 0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF, /* 000002A0 "........" */ + 0xF4,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000002A8 "........" */ + 0x05,0x79,0x00,0x8A,0x50,0x52,0x54,0x30, /* 000002B0 ".y..PRT0" */ + 0x0A,0x5C,0x4D,0x4D,0x49,0x4E,0x8A,0x50, /* 000002B8 ".\MMIN.P" */ + 0x52,0x54,0x30,0x0A,0x60,0x4D,0x4D,0x41, /* 000002C0 "RT0.`MMA" */ + 0x58,0x8A,0x50,0x52,0x54,0x30,0x0A,0x68, /* 000002C8 "X.PRT0.h" */ + 0x4D,0x4C,0x45,0x4E,0x70,0x50,0x4D,0x49, /* 000002D0 "MLENpPMI" */ + 0x4E,0x4D,0x4D,0x49,0x4E,0x70,0x50,0x4C, /* 000002D8 "NMMINpPL" */ + 0x45,0x4E,0x4D,0x4C,0x45,0x4E,0x72,0x4D, /* 000002E0 "ENMLENrM" */ + 0x4D,0x49,0x4E,0x4D,0x4C,0x45,0x4E,0x4D, /* 000002E8 "MINMLENM" */ + 0x4D,0x41,0x58,0x74,0x4D,0x4D,0x41,0x58, /* 000002F0 "MAXtMMAX" */ + 0x01,0x4D,0x4D,0x41,0x58,0xA4,0x50,0x52, /* 000002F8 ".MMAX.PR" */ + 0x54,0x30,0x08,0x42,0x55,0x46,0x41,0x11, /* 00000300 "T0.BUFA." */ + 0x09,0x0A,0x06,0x23,0x20,0x0C,0x18,0x79, /* 00000308 "...# ..y" */ + 0x00,0x08,0x42,0x55,0x46,0x42,0x11,0x09, /* 00000310 "..BUFB.." */ + 0x0A,0x06,0x23,0x00,0x00,0x18,0x79,0x00, /* 00000318 "..#...y." */ + 0x8B,0x42,0x55,0x46,0x42,0x01,0x49,0x52, /* 00000320 ".BUFB.IR" */ + 0x51,0x56,0x5B,0x82,0x48,0x08,0x4C,0x4E, /* 00000328 "QV[.H.LN" */ + 0x4B,0x41,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000330 "KA._HID." */ + 0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49, /* 00000338 "A...._UI" */ + 0x44,0x01,0x14,0x1C,0x5F,0x53,0x54,0x41, /* 00000340 "D..._STA" */ + 0x00,0x7B,0x50,0x49,0x52,0x41,0x0A,0x80, /* 00000348 ".{PIRA.." */ + 0x60,0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4, /* 00000350 "`...`..." */ + 0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14, /* 00000358 "........" */ + 0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4,0x42, /* 00000360 "._PRS..B" */ + 0x55,0x46,0x41,0x14,0x11,0x5F,0x44,0x49, /* 00000368 "UFA.._DI" */ + 0x53,0x00,0x7D,0x50,0x49,0x52,0x41,0x0A, /* 00000370 "S.}PIRA." */ + 0x80,0x50,0x49,0x52,0x41,0x14,0x1A,0x5F, /* 00000378 ".PIRA.._" */ + 0x43,0x52,0x53,0x00,0x7B,0x50,0x49,0x52, /* 00000380 "CRS.{PIR" */ + 0x41,0x0A,0x0F,0x60,0x79,0x01,0x60,0x49, /* 00000388 "A..`y.`I" */ + 0x52,0x51,0x56,0xA4,0x42,0x55,0x46,0x42, /* 00000390 "RQV.BUFB" */ + 0x14,0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B, /* 00000398 ".._SRS.." */ + 0x68,0x01,0x49,0x52,0x51,0x31,0x82,0x49, /* 000003A0 "h.IRQ1.I" */ + 0x52,0x51,0x31,0x60,0x76,0x60,0x70,0x60, /* 000003A8 "RQ1`v`p`" */ + 0x50,0x49,0x52,0x41,0x5B,0x82,0x49,0x08, /* 000003B0 "PIRA[.I." */ + 0x4C,0x4E,0x4B,0x42,0x08,0x5F,0x48,0x49, /* 000003B8 "LNKB._HI" */ + 0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F, /* 000003C0 "D.A...._" */ + 0x55,0x49,0x44,0x0A,0x02,0x14,0x1C,0x5F, /* 000003C8 "UID...._" */ + 0x53,0x54,0x41,0x00,0x7B,0x50,0x49,0x52, /* 000003D0 "STA.{PIR" */ + 0x42,0x0A,0x80,0x60,0xA0,0x08,0x93,0x60, /* 000003D8 "B..`...`" */ + 0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4, /* 000003E0 "........" */ + 0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53, /* 000003E8 "...._PRS" */ + 0x00,0xA4,0x42,0x55,0x46,0x41,0x14,0x11, /* 000003F0 "..BUFA.." */ + 0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x49, /* 000003F8 "_DIS.}PI" */ + 0x52,0x42,0x0A,0x80,0x50,0x49,0x52,0x42, /* 00000400 "RB..PIRB" */ + 0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B, /* 00000408 ".._CRS.{" */ + 0x50,0x49,0x52,0x42,0x0A,0x0F,0x60,0x79, /* 00000410 "PIRB..`y" */ + 0x01,0x60,0x49,0x52,0x51,0x56,0xA4,0x42, /* 00000418 ".`IRQV.B" */ + 0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,0x52, /* 00000420 "UFB.._SR" */ + 0x53,0x01,0x8B,0x68,0x01,0x49,0x52,0x51, /* 00000428 "S..h.IRQ" */ + 0x31,0x82,0x49,0x52,0x51,0x31,0x60,0x76, /* 00000430 "1.IRQ1`v" */ + 0x60,0x70,0x60,0x50,0x49,0x52,0x42,0x5B, /* 00000438 "`p`PIRB[" */ + 0x82,0x49,0x08,0x4C,0x4E,0x4B,0x43,0x08, /* 00000440 ".I.LNKC." */ + 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C, /* 00000448 "_HID.A.." */ + 0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,0x03, /* 00000450 ".._UID.." */ + 0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B, /* 00000458 ".._STA.{" */ + 0x50,0x49,0x52,0x43,0x0A,0x80,0x60,0xA0, /* 00000460 "PIRC..`." */ + 0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09, /* 00000468 "..`....." */ + 0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F, /* 00000470 "......._" */ + 0x50,0x52,0x53,0x00,0xA4,0x42,0x55,0x46, /* 00000478 "PRS..BUF" */ + 0x41,0x14,0x11,0x5F,0x44,0x49,0x53,0x00, /* 00000480 "A.._DIS." */ + 0x7D,0x50,0x49,0x52,0x43,0x0A,0x80,0x50, /* 00000488 "}PIRC..P" */ + 0x49,0x52,0x43,0x14,0x1A,0x5F,0x43,0x52, /* 00000490 "IRC.._CR" */ + 0x53,0x00,0x7B,0x50,0x49,0x52,0x43,0x0A, /* 00000498 "S.{PIRC." */ + 0x0F,0x60,0x79,0x01,0x60,0x49,0x52,0x51, /* 000004A0 ".`y.`IRQ" */ + 0x56,0xA4,0x42,0x55,0x46,0x42,0x14,0x1B, /* 000004A8 "V.BUFB.." */ + 0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,0x01, /* 000004B0 "_SRS..h." */ + 0x49,0x52,0x51,0x31,0x82,0x49,0x52,0x51, /* 000004B8 "IRQ1.IRQ" */ + 0x31,0x60,0x76,0x60,0x70,0x60,0x50,0x49, /* 000004C0 "1`v`p`PI" */ + 0x52,0x43,0x5B,0x82,0x49,0x08,0x4C,0x4E, /* 000004C8 "RC[.I.LN" */ + 0x4B,0x44,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 000004D0 "KD._HID." */ + 0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49, /* 000004D8 "A...._UI" */ + 0x44,0x0A,0x04,0x14,0x1C,0x5F,0x53,0x54, /* 000004E0 "D...._ST" */ + 0x41,0x00,0x7B,0x50,0x49,0x52,0x44,0x0A, /* 000004E8 "A.{PIRD." */ + 0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,0x80, /* 000004F0 ".`...`.." */ + 0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B, /* 000004F8 "........" */ + 0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4, /* 00000500 ".._PRS.." */ + 0x42,0x55,0x46,0x41,0x14,0x11,0x5F,0x44, /* 00000508 "BUFA.._D" */ + 0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x44, /* 00000510 "IS.}PIRD" */ + 0x0A,0x80,0x50,0x49,0x52,0x44,0x14,0x1A, /* 00000518 "..PIRD.." */ + 0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,0x49, /* 00000520 "_CRS.{PI" */ + 0x52,0x44,0x0A,0x0F,0x60,0x79,0x01,0x60, /* 00000528 "RD..`y.`" */ + 0x49,0x52,0x51,0x56,0xA4,0x42,0x55,0x46, /* 00000530 "IRQV.BUF" */ + 0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01, /* 00000538 "B.._SRS." */ + 0x8B,0x68,0x01,0x49,0x52,0x51,0x31,0x82, /* 00000540 ".h.IRQ1." */ + 0x49,0x52,0x51,0x31,0x60,0x76,0x60,0x70, /* 00000548 "IRQ1`v`p" */ + 0x60,0x50,0x49,0x52,0x44,0x5B,0x82,0x44, /* 00000550 "`PIRD[.D" */ + 0x05,0x48,0x50,0x45,0x54,0x08,0x5F,0x48, /* 00000558 ".HPET._H" */ + 0x49,0x44,0x0C,0x41,0xD0,0x01,0x03,0x08, /* 00000560 "ID.A...." */ + 0x5F,0x55,0x49,0x44,0x00,0x14,0x18,0x5F, /* 00000568 "_UID..._" */ + 0x53,0x54,0x41,0x00,0xA0,0x0C,0x93,0x5E, /* 00000570 "STA....^" */ + 0x5E,0x5E,0x48,0x50,0x45,0x54,0x00,0xA4, /* 00000578 "^^HPET.." */ + 0x00,0xA1,0x04,0xA4,0x0A,0x0F,0x08,0x5F, /* 00000580 "......._" */ + 0x43,0x52,0x53,0x11,0x1F,0x0A,0x1C,0x87, /* 00000588 "CRS....." */ + 0x17,0x00,0x00,0x0D,0x01,0x00,0x00,0x00, /* 00000590 "........" */ + 0x00,0x00,0x00,0xD0,0xFE,0xFF,0x03,0xD0, /* 00000598 "........" */ + 0xFE,0x00,0x00,0x00,0x00,0x00,0x04,0x00, /* 000005A0 "........" */ + 0x00,0x79,0x00,0x14,0x16,0x5F,0x50,0x52, /* 000005A8 ".y..._PR" */ + 0x54,0x00,0xA0,0x0A,0x50,0x49,0x43,0x44, /* 000005B0 "T...PICD" */ + 0xA4,0x50,0x52,0x54,0x41,0xA4,0x50,0x52, /* 000005B8 ".PRTA.PR" */ + 0x54,0x50,0x08,0x50,0x52,0x54,0x50,0x12, /* 000005C0 "TP.PRTP." */ + 0x49,0x36,0x3C,0x12,0x0D,0x04,0x0C,0xFF, /* 000005C8 "I6<....." */ + 0xFF,0x01,0x00,0x00,0x4C,0x4E,0x4B,0x42, /* 000005D0 "....LNKB" */ + 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x01, /* 000005D8 "........" */ + 0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 000005E0 "..LNKC.." */ + 0x0E,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A, /* 000005E8 "........" */ + 0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E, /* 000005F0 ".LNKD..." */ + 0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x03, /* 000005F8 "........" */ + 0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04, /* 00000600 "LNKA...." */ + 0x0C,0xFF,0xFF,0x02,0x00,0x00,0x4C,0x4E, /* 00000608 "......LN" */ + 0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000610 "KC......" */ + 0xFF,0x02,0x00,0x01,0x4C,0x4E,0x4B,0x44, /* 00000618 "....LNKD" */ + 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x02, /* 00000620 "........" */ + 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00, /* 00000628 "...LNKA." */ + 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00, /* 00000630 "........" */ + 0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 00000638 "..LNKB.." */ + 0x0D,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x00, /* 00000640 "........" */ + 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04, /* 00000648 "LNKD...." */ + 0x0C,0xFF,0xFF,0x03,0x00,0x01,0x4C,0x4E, /* 00000650 "......LN" */ + 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000658 "KA......" */ + 0xFF,0x03,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 00000660 ".....LNK" */ + 0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000668 "B......." */ + 0x03,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43, /* 00000670 "....LNKC" */ + 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x04, /* 00000678 "........" */ + 0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000680 "..LNKA.." */ + 0x0D,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x01, /* 00000688 "........" */ + 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 00000690 "LNKB...." */ + 0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x02,0x4C, /* 00000698 ".......L" */ + 0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C, /* 000006A0 "NKC....." */ + 0xFF,0xFF,0x04,0x00,0x0A,0x03,0x4C,0x4E, /* 000006A8 "......LN" */ + 0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000006B0 "KD......" */ + 0xFF,0x05,0x00,0x00,0x4C,0x4E,0x4B,0x42, /* 000006B8 "....LNKB" */ + 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x05, /* 000006C0 "........" */ + 0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 000006C8 "..LNKC.." */ + 0x0E,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A, /* 000006D0 "........" */ + 0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E, /* 000006D8 ".LNKD..." */ + 0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x03, /* 000006E0 "........" */ + 0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04, /* 000006E8 "LNKA...." */ + 0x0C,0xFF,0xFF,0x06,0x00,0x00,0x4C,0x4E, /* 000006F0 "......LN" */ + 0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000006F8 "KC......" */ + 0xFF,0x06,0x00,0x01,0x4C,0x4E,0x4B,0x44, /* 00000700 "....LNKD" */ + 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x06, /* 00000708 "........" */ + 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00, /* 00000710 "...LNKA." */ + 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x06,0x00, /* 00000718 "........" */ + 0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 00000720 "..LNKB.." */ + 0x0D,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x00, /* 00000728 "........" */ + 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04, /* 00000730 "LNKD...." */ + 0x0C,0xFF,0xFF,0x07,0x00,0x01,0x4C,0x4E, /* 00000738 "......LN" */ + 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000740 "KA......" */ + 0xFF,0x07,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 00000748 ".....LNK" */ + 0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000750 "B......." */ + 0x07,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43, /* 00000758 "....LNKC" */ + 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x08, /* 00000760 "........" */ + 0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000768 "..LNKA.." */ + 0x0D,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x01, /* 00000770 "........" */ + 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 00000778 "LNKB...." */ + 0x0C,0xFF,0xFF,0x08,0x00,0x0A,0x02,0x4C, /* 00000780 ".......L" */ + 0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C, /* 00000788 "NKC....." */ + 0xFF,0xFF,0x08,0x00,0x0A,0x03,0x4C,0x4E, /* 00000790 "......LN" */ + 0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000798 "KD......" */ + 0xFF,0x09,0x00,0x00,0x4C,0x4E,0x4B,0x42, /* 000007A0 "....LNKB" */ + 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x09, /* 000007A8 "........" */ + 0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 000007B0 "..LNKC.." */ + 0x0E,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A, /* 000007B8 "........" */ + 0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E, /* 000007C0 ".LNKD..." */ + 0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x03, /* 000007C8 "........" */ + 0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04, /* 000007D0 "LNKA...." */ + 0x0C,0xFF,0xFF,0x0A,0x00,0x00,0x4C,0x4E, /* 000007D8 "......LN" */ + 0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000007E0 "KC......" */ + 0xFF,0x0A,0x00,0x01,0x4C,0x4E,0x4B,0x44, /* 000007E8 "....LNKD" */ + 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0A, /* 000007F0 "........" */ + 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00, /* 000007F8 "...LNKA." */ + 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0A,0x00, /* 00000800 "........" */ + 0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 00000808 "..LNKB.." */ + 0x0D,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x00, /* 00000810 "........" */ + 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04, /* 00000818 "LNKD...." */ + 0x0C,0xFF,0xFF,0x0B,0x00,0x01,0x4C,0x4E, /* 00000820 "......LN" */ + 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000828 "KA......" */ + 0xFF,0x0B,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 00000830 ".....LNK" */ + 0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000838 "B......." */ + 0x0B,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43, /* 00000840 "....LNKC" */ + 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0C, /* 00000848 "........" */ + 0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000850 "..LNKA.." */ + 0x0D,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x01, /* 00000858 "........" */ + 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 00000860 "LNKB...." */ + 0x0C,0xFF,0xFF,0x0C,0x00,0x0A,0x02,0x4C, /* 00000868 ".......L" */ + 0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C, /* 00000870 "NKC....." */ + 0xFF,0xFF,0x0C,0x00,0x0A,0x03,0x4C,0x4E, /* 00000878 "......LN" */ + 0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000880 "KD......" */ + 0xFF,0x0D,0x00,0x00,0x4C,0x4E,0x4B,0x42, /* 00000888 "....LNKB" */ + 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0D, /* 00000890 "........" */ + 0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 00000898 "..LNKC.." */ + 0x0E,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A, /* 000008A0 "........" */ + 0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E, /* 000008A8 ".LNKD..." */ + 0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x03, /* 000008B0 "........" */ + 0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04, /* 000008B8 "LNKA...." */ + 0x0C,0xFF,0xFF,0x0E,0x00,0x00,0x4C,0x4E, /* 000008C0 "......LN" */ + 0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000008C8 "KC......" */ + 0xFF,0x0E,0x00,0x01,0x4C,0x4E,0x4B,0x44, /* 000008D0 "....LNKD" */ + 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0E, /* 000008D8 "........" */ + 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00, /* 000008E0 "...LNKA." */ + 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0E,0x00, /* 000008E8 "........" */ + 0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 000008F0 "..LNKB.." */ + 0x0D,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x00, /* 000008F8 "........" */ + 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04, /* 00000900 "LNKD...." */ + 0x0C,0xFF,0xFF,0x0F,0x00,0x01,0x4C,0x4E, /* 00000908 "......LN" */ + 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000910 "KA......" */ + 0xFF,0x0F,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 00000918 ".....LNK" */ + 0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000920 "B......." */ + 0x0F,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43, /* 00000928 "....LNKC" */ + 0x00,0x08,0x50,0x52,0x54,0x41,0x12,0x41, /* 00000930 "..PRTA.A" */ + 0x2F,0x3C,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000938 "/<......" */ + 0x01,0x00,0x00,0x00,0x0A,0x14,0x12,0x0B, /* 00000940 "........" */ + 0x04,0x0C,0xFF,0xFF,0x01,0x00,0x01,0x00, /* 00000948 "........" */ + 0x0A,0x15,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000950 "........" */ + 0x01,0x00,0x0A,0x02,0x00,0x0A,0x16,0x12, /* 00000958 "........" */ + 0x0C,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A, /* 00000960 "........" */ + 0x03,0x00,0x0A,0x17,0x12,0x0B,0x04,0x0C, /* 00000968 "........" */ + 0xFF,0xFF,0x02,0x00,0x00,0x00,0x0A,0x18, /* 00000970 "........" */ + 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x02,0x00, /* 00000978 "........" */ + 0x01,0x00,0x0A,0x19,0x12,0x0C,0x04,0x0C, /* 00000980 "........" */ + 0xFF,0xFF,0x02,0x00,0x0A,0x02,0x00,0x0A, /* 00000988 "........" */ + 0x1A,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x02, /* 00000990 "........" */ + 0x00,0x0A,0x03,0x00,0x0A,0x1B,0x12,0x0B, /* 00000998 "........" */ + 0x04,0x0C,0xFF,0xFF,0x03,0x00,0x00,0x00, /* 000009A0 "........" */ + 0x0A,0x1C,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 000009A8 "........" */ + 0x03,0x00,0x01,0x00,0x0A,0x1D,0x12,0x0C, /* 000009B0 "........" */ + 0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x02, /* 000009B8 "........" */ + 0x00,0x0A,0x1E,0x12,0x0C,0x04,0x0C,0xFF, /* 000009C0 "........" */ + 0xFF,0x03,0x00,0x0A,0x03,0x00,0x0A,0x1F, /* 000009C8 "........" */ + 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 000009D0 "........" */ + 0x00,0x00,0x0A,0x20,0x12,0x0B,0x04,0x0C, /* 000009D8 "... ...." */ + 0xFF,0xFF,0x04,0x00,0x01,0x00,0x0A,0x21, /* 000009E0 ".......!" */ + 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 000009E8 "........" */ + 0x0A,0x02,0x00,0x0A,0x22,0x12,0x0C,0x04, /* 000009F0 "...."..." */ + 0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x03,0x00, /* 000009F8 "........" */ + 0x0A,0x23,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000A00 ".#......" */ + 0x05,0x00,0x00,0x00,0x0A,0x24,0x12,0x0B, /* 00000A08 ".....$.." */ + 0x04,0x0C,0xFF,0xFF,0x05,0x00,0x01,0x00, /* 00000A10 "........" */ + 0x0A,0x25,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000A18 ".%......" */ + 0x05,0x00,0x0A,0x02,0x00,0x0A,0x26,0x12, /* 00000A20 "......&." */ + 0x0C,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A, /* 00000A28 "........" */ + 0x03,0x00,0x0A,0x27,0x12,0x0B,0x04,0x0C, /* 00000A30 "...'...." */ + 0xFF,0xFF,0x06,0x00,0x00,0x00,0x0A,0x28, /* 00000A38 ".......(" */ + 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x06,0x00, /* 00000A40 "........" */ + 0x01,0x00,0x0A,0x29,0x12,0x0C,0x04,0x0C, /* 00000A48 "...)...." */ + 0xFF,0xFF,0x06,0x00,0x0A,0x02,0x00,0x0A, /* 00000A50 "........" */ + 0x2A,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x06, /* 00000A58 "*......." */ + 0x00,0x0A,0x03,0x00,0x0A,0x2B,0x12,0x0B, /* 00000A60 ".....+.." */ + 0x04,0x0C,0xFF,0xFF,0x07,0x00,0x00,0x00, /* 00000A68 "........" */ + 0x0A,0x2C,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000A70 ".,......" */ + 0x07,0x00,0x01,0x00,0x0A,0x2D,0x12,0x0C, /* 00000A78 ".....-.." */ + 0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x02, /* 00000A80 "........" */ + 0x00,0x0A,0x2E,0x12,0x0C,0x04,0x0C,0xFF, /* 00000A88 "........" */ + 0xFF,0x07,0x00,0x0A,0x03,0x00,0x0A,0x2F, /* 00000A90 "......./" */ + 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x08,0x00, /* 00000A98 "........" */ + 0x00,0x00,0x0A,0x11,0x12,0x0B,0x04,0x0C, /* 00000AA0 "........" */ + 0xFF,0xFF,0x08,0x00,0x01,0x00,0x0A,0x12, /* 00000AA8 "........" */ + 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x08,0x00, /* 00000AB0 "........" */ + 0x0A,0x02,0x00,0x0A,0x13,0x12,0x0C,0x04, /* 00000AB8 "........" */ + 0x0C,0xFF,0xFF,0x08,0x00,0x0A,0x03,0x00, /* 00000AC0 "........" */ + 0x0A,0x14,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000AC8 "........" */ + 0x09,0x00,0x00,0x00,0x0A,0x15,0x12,0x0B, /* 00000AD0 "........" */ + 0x04,0x0C,0xFF,0xFF,0x09,0x00,0x01,0x00, /* 00000AD8 "........" */ + 0x0A,0x16,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000AE0 "........" */ + 0x09,0x00,0x0A,0x02,0x00,0x0A,0x17,0x12, /* 00000AE8 "........" */ + 0x0C,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A, /* 00000AF0 "........" */ + 0x03,0x00,0x0A,0x18,0x12,0x0B,0x04,0x0C, /* 00000AF8 "........" */ + 0xFF,0xFF,0x0A,0x00,0x00,0x00,0x0A,0x19, /* 00000B00 "........" */ + 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0A,0x00, /* 00000B08 "........" */ + 0x01,0x00,0x0A,0x1A,0x12,0x0C,0x04,0x0C, /* 00000B10 "........" */ + 0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x00,0x0A, /* 00000B18 "........" */ + 0x1B,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0A, /* 00000B20 "........" */ + 0x00,0x0A,0x03,0x00,0x0A,0x1C,0x12,0x0B, /* 00000B28 "........" */ + 0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x00,0x00, /* 00000B30 "........" */ + 0x0A,0x1D,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000B38 "........" */ + 0x0B,0x00,0x01,0x00,0x0A,0x1E,0x12,0x0C, /* 00000B40 "........" */ + 0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x02, /* 00000B48 "........" */ + 0x00,0x0A,0x1F,0x12,0x0C,0x04,0x0C,0xFF, /* 00000B50 "........" */ + 0xFF,0x0B,0x00,0x0A,0x03,0x00,0x0A,0x20, /* 00000B58 "....... " */ + 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0C,0x00, /* 00000B60 "........" */ + 0x00,0x00,0x0A,0x21,0x12,0x0B,0x04,0x0C, /* 00000B68 "...!...." */ + 0xFF,0xFF,0x0C,0x00,0x01,0x00,0x0A,0x22, /* 00000B70 "......."" */ + 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0C,0x00, /* 00000B78 "........" */ + 0x0A,0x02,0x00,0x0A,0x23,0x12,0x0C,0x04, /* 00000B80 "....#..." */ + 0x0C,0xFF,0xFF,0x0C,0x00,0x0A,0x03,0x00, /* 00000B88 "........" */ + 0x0A,0x24,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000B90 ".$......" */ + 0x0D,0x00,0x00,0x00,0x0A,0x25,0x12,0x0B, /* 00000B98 ".....%.." */ + 0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x01,0x00, /* 00000BA0 "........" */ + 0x0A,0x26,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000BA8 ".&......" */ + 0x0D,0x00,0x0A,0x02,0x00,0x0A,0x27,0x12, /* 00000BB0 "......'." */ + 0x0C,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A, /* 00000BB8 "........" */ + 0x03,0x00,0x0A,0x28,0x12,0x0B,0x04,0x0C, /* 00000BC0 "...(...." */ + 0xFF,0xFF,0x0E,0x00,0x00,0x00,0x0A,0x29, /* 00000BC8 ".......)" */ + 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0E,0x00, /* 00000BD0 "........" */ + 0x01,0x00,0x0A,0x2A,0x12,0x0C,0x04,0x0C, /* 00000BD8 "...*...." */ + 0xFF,0xFF,0x0E,0x00,0x0A,0x02,0x00,0x0A, /* 00000BE0 "........" */ + 0x2B,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0E, /* 00000BE8 "+......." */ + 0x00,0x0A,0x03,0x00,0x0A,0x2C,0x12,0x0B, /* 00000BF0 ".....,.." */ + 0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x00,0x00, /* 00000BF8 "........" */ + 0x0A,0x2D,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000C00 ".-......" */ + 0x0F,0x00,0x01,0x00,0x0A,0x2E,0x12,0x0C, /* 00000C08 "........" */ + 0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x02, /* 00000C10 "........" */ + 0x00,0x0A,0x2F,0x12,0x0C,0x04,0x0C,0xFF, /* 00000C18 "../....." */ + 0xFF,0x0F,0x00,0x0A,0x03,0x00,0x0A,0x10, /* 00000C20 "........" */ + 0x5B,0x82,0x46,0x37,0x49,0x53,0x41,0x5F, /* 00000C28 "[.F7ISA_" */ + 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 00000C30 "._ADR..." */ + 0x01,0x00,0x5B,0x80,0x50,0x49,0x52,0x51, /* 00000C38 "..[.PIRQ" */ + 0x02,0x0A,0x60,0x0A,0x04,0x10,0x2E,0x5C, /* 00000C40 "..`....\" */ + 0x00,0x5B,0x81,0x29,0x5C,0x2F,0x04,0x5F, /* 00000C48 ".[.)\/._" */ + 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x49, /* 00000C50 "SB_PCI0I" */ + 0x53,0x41,0x5F,0x50,0x49,0x52,0x51,0x01, /* 00000C58 "SA_PIRQ." */ + 0x50,0x49,0x52,0x41,0x08,0x50,0x49,0x52, /* 00000C60 "PIRA.PIR" */ + 0x42,0x08,0x50,0x49,0x52,0x43,0x08,0x50, /* 00000C68 "B.PIRC.P" */ + 0x49,0x52,0x44,0x08,0x5B,0x82,0x46,0x0B, /* 00000C70 "IRD.[.F." */ + 0x53,0x59,0x53,0x52,0x08,0x5F,0x48,0x49, /* 00000C78 "SYSR._HI" */ + 0x44,0x0C,0x41,0xD0,0x0C,0x02,0x08,0x5F, /* 00000C80 "D.A...._" */ + 0x55,0x49,0x44,0x01,0x08,0x43,0x52,0x53, /* 00000C88 "UID..CRS" */ + 0x5F,0x11,0x4E,0x08,0x0A,0x8A,0x47,0x01, /* 00000C90 "_.N...G." */ + 0x10,0x00,0x10,0x00,0x00,0x10,0x47,0x01, /* 00000C98 "......G." */ + 0x22,0x00,0x22,0x00,0x00,0x0C,0x47,0x01, /* 00000CA0 ""."...G." */ + 0x30,0x00,0x30,0x00,0x00,0x10,0x47,0x01, /* 00000CA8 "0.0...G." */ + 0x44,0x00,0x44,0x00,0x00,0x1C,0x47,0x01, /* 00000CB0 "D.D...G." */ + 0x62,0x00,0x62,0x00,0x00,0x02,0x47,0x01, /* 00000CB8 "b.b...G." */ + 0x65,0x00,0x65,0x00,0x00,0x0B,0x47,0x01, /* 00000CC0 "e.e...G." */ + 0x72,0x00,0x72,0x00,0x00,0x0E,0x47,0x01, /* 00000CC8 "r.r...G." */ + 0x80,0x00,0x80,0x00,0x00,0x01,0x47,0x01, /* 00000CD0 "......G." */ + 0x84,0x00,0x84,0x00,0x00,0x03,0x47,0x01, /* 00000CD8 "......G." */ + 0x88,0x00,0x88,0x00,0x00,0x01,0x47,0x01, /* 00000CE0 "......G." */ + 0x8C,0x00,0x8C,0x00,0x00,0x03,0x47,0x01, /* 00000CE8 "......G." */ + 0x90,0x00,0x90,0x00,0x00,0x10,0x47,0x01, /* 00000CF0 "......G." */ + 0xA2,0x00,0xA2,0x00,0x00,0x1C,0x47,0x01, /* 00000CF8 "......G." */ + 0xE0,0x00,0xE0,0x00,0x00,0x10,0x47,0x01, /* 00000D00 "......G." */ + 0xA0,0x08,0xA0,0x08,0x00,0x04,0x47,0x01, /* 00000D08 "......G." */ + 0xC0,0x0C,0xC0,0x0C,0x00,0x10,0x47,0x01, /* 00000D10 "......G." */ + 0xD0,0x04,0xD0,0x04,0x00,0x02,0x79,0x00, /* 00000D18 "......y." */ + 0x14,0x0B,0x5F,0x43,0x52,0x53,0x00,0xA4, /* 00000D20 ".._CRS.." */ + 0x43,0x52,0x53,0x5F,0x5B,0x82,0x2B,0x50, /* 00000D28 "CRS_[.+P" */ + 0x49,0x43,0x5F,0x08,0x5F,0x48,0x49,0x44, /* 00000D30 "IC_._HID" */ + 0x0B,0x41,0xD0,0x08,0x5F,0x43,0x52,0x53, /* 00000D38 ".A.._CRS" */ + 0x11,0x18,0x0A,0x15,0x47,0x01,0x20,0x00, /* 00000D40 "....G. ." */ + 0x20,0x00,0x01,0x02,0x47,0x01,0xA0,0x00, /* 00000D48 " ...G..." */ + 0xA0,0x00,0x01,0x02,0x22,0x04,0x00,0x79, /* 00000D50 "...."..y" */ + 0x00,0x5B,0x82,0x47,0x05,0x44,0x4D,0x41, /* 00000D58 ".[.G.DMA" */ + 0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000D60 "0._HID.A" */ + 0xD0,0x02,0x00,0x08,0x5F,0x43,0x52,0x53, /* 00000D68 "...._CRS" */ + 0x11,0x41,0x04,0x0A,0x3D,0x2A,0x10,0x04, /* 00000D70 ".A..=*.." */ + 0x47,0x01,0x00,0x00,0x00,0x00,0x00,0x10, /* 00000D78 "G......." */ + 0x47,0x01,0x81,0x00,0x81,0x00,0x00,0x03, /* 00000D80 "G......." */ + 0x47,0x01,0x87,0x00,0x87,0x00,0x00,0x01, /* 00000D88 "G......." */ + 0x47,0x01,0x89,0x00,0x89,0x00,0x00,0x03, /* 00000D90 "G......." */ + 0x47,0x01,0x8F,0x00,0x8F,0x00,0x00,0x01, /* 00000D98 "G......." */ + 0x47,0x01,0xC0,0x00,0xC0,0x00,0x00,0x20, /* 00000DA0 "G...... " */ + 0x47,0x01,0x80,0x04,0x80,0x04,0x00,0x10, /* 00000DA8 "G......." */ + 0x79,0x00,0x5B,0x82,0x25,0x54,0x4D,0x52, /* 00000DB0 "y.[.%TMR" */ + 0x5F,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000DB8 "_._HID.A" */ + 0xD0,0x01,0x00,0x08,0x5F,0x43,0x52,0x53, /* 00000DC0 "...._CRS" */ + 0x11,0x10,0x0A,0x0D,0x47,0x01,0x40,0x00, /* 00000DC8 "....G.@." */ + 0x40,0x00,0x00,0x04,0x22,0x01,0x00,0x79, /* 00000DD0 "@..."..y" */ + 0x00,0x5B,0x82,0x25,0x52,0x54,0x43,0x5F, /* 00000DD8 ".[.%RTC_" */ + 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000DE0 "._HID.A." */ + 0x0B,0x00,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000DE8 "..._CRS." */ + 0x10,0x0A,0x0D,0x47,0x01,0x70,0x00,0x70, /* 00000DF0 "...G.p.p" */ + 0x00,0x00,0x02,0x22,0x00,0x01,0x79,0x00, /* 00000DF8 "..."..y." */ + 0x5B,0x82,0x22,0x53,0x50,0x4B,0x52,0x08, /* 00000E00 "[."SPKR." */ + 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x08, /* 00000E08 "_HID.A.." */ + 0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x0D, /* 00000E10 ".._CRS.." */ + 0x0A,0x0A,0x47,0x01,0x61,0x00,0x61,0x00, /* 00000E18 "..G.a.a." */ + 0x00,0x01,0x79,0x00,0x5B,0x82,0x31,0x50, /* 00000E20 "..y.[.1P" */ + 0x53,0x32,0x4D,0x08,0x5F,0x48,0x49,0x44, /* 00000E28 "S2M._HID" */ + 0x0C,0x41,0xD0,0x0F,0x13,0x08,0x5F,0x43, /* 00000E30 ".A...._C" */ + 0x49,0x44,0x0C,0x41,0xD0,0x0F,0x13,0x14, /* 00000E38 "ID.A...." */ + 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000E40 "._STA..." */ + 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x08, /* 00000E48 ".._CRS.." */ + 0x0A,0x05,0x22,0x00,0x10,0x79,0x00,0x5B, /* 00000E50 ".."..y.[" */ + 0x82,0x42,0x04,0x50,0x53,0x32,0x4B,0x08, /* 00000E58 ".B.PS2K." */ + 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x03, /* 00000E60 "_HID.A.." */ + 0x03,0x08,0x5F,0x43,0x49,0x44,0x0C,0x41, /* 00000E68 ".._CID.A" */ + 0xD0,0x03,0x0B,0x14,0x09,0x5F,0x53,0x54, /* 00000E70 "....._ST" */ + 0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43, /* 00000E78 "A....._C" */ + 0x52,0x53,0x11,0x18,0x0A,0x15,0x47,0x01, /* 00000E80 "RS....G." */ + 0x60,0x00,0x60,0x00,0x00,0x01,0x47,0x01, /* 00000E88 "`.`...G." */ + 0x64,0x00,0x64,0x00,0x00,0x01,0x22,0x02, /* 00000E90 "d.d..."." */ + 0x00,0x79,0x00,0x5B,0x82,0x3A,0x46,0x44, /* 00000E98 ".y.[.:FD" */ + 0x43,0x30,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000EA0 "C0._HID." */ + 0x41,0xD0,0x07,0x00,0x14,0x09,0x5F,0x53, /* 00000EA8 "A....._S" */ + 0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F, /* 00000EB0 "TA....._" */ + 0x43,0x52,0x53,0x11,0x1B,0x0A,0x18,0x47, /* 00000EB8 "CRS....G" */ + 0x01,0xF0,0x03,0xF0,0x03,0x01,0x06,0x47, /* 00000EC0 ".......G" */ + 0x01,0xF7,0x03,0xF7,0x03,0x01,0x01,0x22, /* 00000EC8 "......."" */ + 0x40,0x00,0x2A,0x04,0x00,0x79,0x00,0x5B, /* 00000ED0 "@.*..y.[" */ + 0x82,0x46,0x04,0x55,0x41,0x52,0x31,0x08, /* 00000ED8 ".F.UAR1." */ + 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x05, /* 00000EE0 "_HID.A.." */ + 0x01,0x08,0x5F,0x55,0x49,0x44,0x01,0x14, /* 00000EE8 ".._UID.." */ + 0x19,0x5F,0x53,0x54,0x41,0x00,0xA0,0x0D, /* 00000EF0 "._STA..." */ + 0x93,0x5E,0x5E,0x5E,0x5E,0x55,0x41,0x52, /* 00000EF8 ".^^^^UAR" */ + 0x31,0x00,0xA4,0x00,0xA1,0x04,0xA4,0x0A, /* 00000F00 "1......." */ + 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000F08 ".._CRS.." */ + 0x0A,0x0D,0x47,0x01,0xF8,0x03,0xF8,0x03, /* 00000F10 "..G....." */ + 0x08,0x08,0x22,0x10,0x00,0x79,0x00,0x5B, /* 00000F18 ".."..y.[" */ + 0x82,0x47,0x04,0x55,0x41,0x52,0x32,0x08, /* 00000F20 ".G.UAR2." */ + 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x05, /* 00000F28 "_HID.A.." */ + 0x01,0x08,0x5F,0x55,0x49,0x44,0x0A,0x02, /* 00000F30 ".._UID.." */ + 0x14,0x19,0x5F,0x53,0x54,0x41,0x00,0xA0, /* 00000F38 ".._STA.." */ + 0x0D,0x93,0x5E,0x5E,0x5E,0x5E,0x55,0x41, /* 00000F40 "..^^^^UA" */ + 0x52,0x32,0x00,0xA4,0x00,0xA1,0x04,0xA4, /* 00000F48 "R2......" */ + 0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000F50 "..._CRS." */ + 0x10,0x0A,0x0D,0x47,0x01,0xF8,0x02,0xF8, /* 00000F58 "...G...." */ + 0x02,0x08,0x08,0x22,0x08,0x00,0x79,0x00, /* 00000F60 "..."..y." */ + 0x5B,0x82,0x36,0x4C,0x54,0x50,0x31,0x08, /* 00000F68 "[.6LTP1." */ + 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x04, /* 00000F70 "_HID.A.." */ + 0x00,0x08,0x5F,0x55,0x49,0x44,0x0A,0x02, /* 00000F78 ".._UID.." */ + 0x14,0x09,0x5F,0x53,0x54,0x41,0x00,0xA4, /* 00000F80 ".._STA.." */ + 0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000F88 "..._CRS." */ + 0x10,0x0A,0x0D,0x47,0x01,0x78,0x03,0x78, /* 00000F90 "...G.x.x" */ + 0x03,0x08,0x08,0x22,0x80,0x00,0x79,0x00, /* 00000F98 "..."..y." */ + 0x5B,0x82,0x4D,0x07,0x53,0x31,0x46,0x30, /* 00000FA0 "[.M.S1F0" */ + 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 00000FA8 "._ADR..." */ + 0x06,0x00,0x08,0x5F,0x53,0x55,0x4E,0x01, /* 00000FB0 "..._SUN." */ + 0x14,0x13,0x5F,0x50,0x53,0x30,0x00,0x70, /* 00000FB8 ".._PS0.p" */ + 0x0A,0x80,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00000FC0 "..\._GPE" */ + 0x44,0x50,0x54,0x32,0x14,0x13,0x5F,0x50, /* 00000FC8 "DPT2.._P" */ + 0x53,0x33,0x00,0x70,0x0A,0x83,0x5C,0x2E, /* 00000FD0 "S3.p..\." */ + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00000FD8 "_GPEDPT2" */ + 0x14,0x1F,0x5F,0x45,0x4A,0x30,0x01,0x70, /* 00000FE0 ".._EJ0.p" */ + 0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00000FE8 "..\._GPE" */ + 0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E, /* 00000FF0 "DPT2p.\." */ + 0x5F,0x47,0x50,0x45,0x50,0x48,0x50,0x31, /* 00000FF8 "_GPEPHP1" */ + 0x14,0x1E,0x5F,0x53,0x54,0x41,0x00,0x70, /* 00001000 ".._STA.p" */ + 0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001008 "..\._GPE" */ + 0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E,0x5F, /* 00001010 "DPT2.\._" */ + 0x47,0x50,0x45,0x50,0x48,0x50,0x31,0x5B, /* 00001018 "GPEPHP1[" */ + 0x82,0x4E,0x07,0x53,0x32,0x46,0x30,0x08, /* 00001020 ".N.S2F0." */ + 0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,0x07, /* 00001028 "_ADR...." */ + 0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,0x02, /* 00001030 ".._SUN.." */ + 0x14,0x13,0x5F,0x50,0x53,0x30,0x00,0x70, /* 00001038 ".._PS0.p" */ + 0x0A,0x90,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001040 "..\._GPE" */ + 0x44,0x50,0x54,0x32,0x14,0x13,0x5F,0x50, /* 00001048 "DPT2.._P" */ + 0x53,0x33,0x00,0x70,0x0A,0x93,0x5C,0x2E, /* 00001050 "S3.p..\." */ + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00001058 "_GPEDPT2" */ + 0x14,0x1F,0x5F,0x45,0x4A,0x30,0x01,0x70, /* 00001060 ".._EJ0.p" */ + 0x0A,0x98,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001068 "..\._GPE" */ + 0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E, /* 00001070 "DPT2p.\." */ + 0x5F,0x47,0x50,0x45,0x50,0x48,0x50,0x32, /* 00001078 "_GPEPHP2" */ + 0x14,0x1E,0x5F,0x53,0x54,0x41,0x00,0x70, /* 00001080 ".._STA.p" */ + 0x0A,0x99,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001088 "..\._GPE" */ + 0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E,0x5F, /* 00001090 "DPT2.\._" */ + 0x47,0x50,0x45,0x50,0x48,0x50,0x32,0x10, /* 00001098 "GPEPHP2." */ + 0x4E,0x0B,0x5F,0x47,0x50,0x45,0x5B,0x80, /* 000010A0 "N._GPE[." */ + 0x50,0x48,0x50,0x5F,0x01,0x0B,0xC0,0x10, /* 000010A8 "PHP_...." */ + 0x0A,0x03,0x5B,0x81,0x15,0x50,0x48,0x50, /* 000010B0 "..[..PHP" */ + 0x5F,0x01,0x50,0x53,0x54,0x41,0x08,0x50, /* 000010B8 "_.PSTA.P" */ + 0x48,0x50,0x31,0x08,0x50,0x48,0x50,0x32, /* 000010C0 "HP1.PHP2" */ + 0x08,0x5B,0x80,0x44,0x47,0x31,0x5F,0x01, /* 000010C8 ".[.DG1_." */ + 0x0B,0x44,0xB0,0x0A,0x04,0x5B,0x81,0x10, /* 000010D0 ".D...[.." */ + 0x44,0x47,0x31,0x5F,0x01,0x44,0x50,0x54, /* 000010D8 "DG1_.DPT" */ + 0x31,0x08,0x44,0x50,0x54,0x32,0x08,0x14, /* 000010E0 "1.DPT2.." */ + 0x46,0x07,0x5F,0x4C,0x30,0x33,0x00,0x08, /* 000010E8 "F._L03.." */ + 0x53,0x4C,0x54,0x5F,0x00,0x08,0x45,0x56, /* 000010F0 "SLT_..EV" */ + 0x54,0x5F,0x00,0x70,0x50,0x53,0x54,0x41, /* 000010F8 "T_.pPSTA" */ + 0x61,0x7A,0x61,0x0A,0x04,0x53,0x4C,0x54, /* 00001100 "aza..SLT" */ + 0x5F,0x7B,0x61,0x0A,0x0F,0x45,0x56,0x54, /* 00001108 "_{a..EVT" */ + 0x5F,0x70,0x53,0x4C,0x54,0x5F,0x44,0x50, /* 00001110 "_pSLT_DP" */ + 0x54,0x31,0x70,0x45,0x56,0x54,0x5F,0x44, /* 00001118 "T1pEVT_D" */ + 0x50,0x54,0x32,0xA0,0x1B,0x93,0x53,0x4C, /* 00001120 "PT2...SL" */ + 0x54,0x5F,0x01,0x86,0x5C,0x2F,0x03,0x5F, /* 00001128 "T_..\/._" */ + 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x53, /* 00001130 "SB_PCI0S" */ + 0x31,0x46,0x30,0x45,0x56,0x54,0x5F,0xA1, /* 00001138 "1F0EVT_." */ + 0x1E,0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F, /* 00001140 "....SLT_" */ + 0x0A,0x02,0x86,0x5C,0x2F,0x03,0x5F,0x53, /* 00001148 "...\/._S" */ + 0x42,0x5F,0x50,0x43,0x49,0x30,0x53,0x32, /* 00001150 "B_PCI0S2" */ + 0x46,0x30,0x45,0x56,0x54,0x5F, }; int DsdtLen=sizeof(AmlCode); diff -r b8b66dc0fa1d -r 661a839a481e tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/firmware/hvmloader/config.h Wed Jan 07 12:20:18 2009 +0900 @@ -23,11 +23,18 @@ /* Memory map. */ #define HYPERCALL_PHYSICAL_ADDRESS 0x00080000 #define VGABIOS_PHYSICAL_ADDRESS 0x000C0000 -#define SMBIOS_PHYSICAL_ADDRESS 0x000E9000 -#define SMBIOS_MAXIMUM_SIZE 0x00001000 +#define OPTIONROM_PHYSICAL_ADDRESS 0x000C8000 +#define OPTIONROM_PHYSICAL_END 0x000EA000 #define ACPI_PHYSICAL_ADDRESS 0x000EA000 +#define E820_PHYSICAL_ADDRESS 0x000EA100 +#define SMBIOS_PHYSICAL_ADDRESS 0x000EB000 +#define SMBIOS_MAXIMUM_SIZE 0x00005000 #define ROMBIOS_PHYSICAL_ADDRESS 0x000F0000 #define SCRATCH_PHYSICAL_ADDRESS 0x00010000 + +/* Offsets from E820_PHYSICAL_ADDRESS. */ +#define E820_NR_OFFSET 0x0 +#define E820_OFFSET 0x8 /* Xen Platform Device */ #define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */ diff -r b8b66dc0fa1d -r 661a839a481e tools/firmware/hvmloader/e820.h --- a/tools/firmware/hvmloader/e820.h Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/firmware/hvmloader/e820.h Wed Jan 07 12:20:18 2009 +0900 @@ -17,7 +17,7 @@ struct e820entry { uint32_t type; } __attribute__((packed)); -#define HVM_E820_NR ((unsigned char *)HVM_E820_PAGE + HVM_E820_NR_OFFSET) -#define HVM_E820 ((struct e820entry *)(HVM_E820_PAGE + HVM_E820_OFFSET)) +#define E820_NR ((uint16_t *)(E820_PHYSICAL_ADDRESS + E820_NR_OFFSET)) +#define E820 ((struct e820entry *)(E820_PHYSICAL_ADDRESS + E820_OFFSET)) #endif /* __HVMLOADER_E820_H__ */ diff -r b8b66dc0fa1d -r 661a839a481e tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/firmware/hvmloader/hvmloader.c Wed Jan 07 12:20:18 2009 +0900 @@ -330,7 +330,7 @@ static void pci_setup(void) * Scan the list of Option ROMs at @roms for one which supports * PCI (@vendor_id, @device_id) found at slot @devfn. If one is found, * copy it to @dest and return its size rounded up to a multiple 2kB. This - * function will not copy ROMs beyond address 0xE0000. + * function will not copy ROMs beyond address OPTIONROM_PHYSICAL_END. */ #define round_option_rom(x) (((x) + 2047) & ~2047) static int scan_option_rom( @@ -401,7 +401,7 @@ static int scan_option_rom( printf(" - Product name: %s\n", (char *)rom + pnph->product_name_offset); - if ( (dest + rom->rom_size * 512 + 1) > 0xe0000u ) + if ( (dest + rom->rom_size * 512 + 1) > OPTIONROM_PHYSICAL_END ) { printf("Option ROM size %x exceeds available space\n", rom->rom_size * 512); @@ -488,8 +488,8 @@ static int pci_load_option_roms(uint32_t /* Replace possibly erroneous memory-size CMOS fields with correct values. */ static void cmos_write_memory_size(void) { - struct e820entry *map = HVM_E820; - int i, nr = *HVM_E820_NR; + struct e820entry *map = E820; + int i, nr = *E820_NR; uint32_t base_mem = 640, ext_mem = 0, alt_mem = 0; for ( i = 0; i < nr; i++ ) @@ -541,9 +541,11 @@ static uint16_t init_xen_platform_io_bas return bios_info->xen_pfiob; } -/* Set up an empty TSS area for virtual 8086 mode to use. +/* + * Set up an empty TSS area for virtual 8086 mode to use. * The only important thing is that it musn't have any bits set - * in the interrupt redirection bitmap, so all zeros will do. */ + * in the interrupt redirection bitmap, so all zeros will do. + */ static void init_vm86_tss(void) { uint32_t tss; @@ -558,6 +560,18 @@ static void init_vm86_tss(void) printf("vm86 TSS at %08x\n", tss); } +/* + * Copy the E820 table provided by the HVM domain builder into the correct + * place in the memory map we share with the rombios. + */ +static void copy_e820_table(void) +{ + uint8_t nr = *(uint8_t *)(HVM_E820_PAGE + HVM_E820_NR_OFFSET); + BUG_ON(nr > 16); + memcpy(E820, (char *)HVM_E820_PAGE + HVM_E820_OFFSET, nr * sizeof(*E820)); + *E820_NR = nr; +} + int main(void) { int option_rom_sz = 0, vgabios_sz = 0, etherboot_sz = 0; @@ -566,6 +580,8 @@ int main(void) uint16_t xen_pfiob; printf("HVM Loader\n"); + + copy_e820_table(); init_hypercalls(); @@ -617,6 +633,8 @@ int main(void) } etherboot_phys_addr = VGABIOS_PHYSICAL_ADDRESS + vgabios_sz; + if ( etherboot_phys_addr < OPTIONROM_PHYSICAL_ADDRESS ) + etherboot_phys_addr = OPTIONROM_PHYSICAL_ADDRESS; etherboot_sz = scan_etherboot_nic(etherboot_phys_addr); option_rom_phys_addr = etherboot_phys_addr + etherboot_sz; diff -r b8b66dc0fa1d -r 661a839a481e tools/firmware/hvmloader/smbios.c --- a/tools/firmware/hvmloader/smbios.c Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/firmware/hvmloader/smbios.c Wed Jan 07 12:20:18 2009 +0900 @@ -143,8 +143,8 @@ static uint64_t static uint64_t get_memsize(void) { - struct e820entry *map = HVM_E820; - uint8_t num_entries = *HVM_E820_NR; + struct e820entry *map = E820; + uint8_t num_entries = *E820_NR; uint64_t memsize = 0; int i; diff -r b8b66dc0fa1d -r 661a839a481e tools/firmware/hvmloader/util.c --- a/tools/firmware/hvmloader/util.c Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/firmware/hvmloader/util.c Wed Jan 07 12:20:18 2009 +0900 @@ -307,16 +307,16 @@ static void e820_collapse(void) static void e820_collapse(void) { int i = 0; - struct e820entry *ent = (struct e820entry *)HVM_E820; - - while ( i < (*HVM_E820_NR-1) ) + struct e820entry *ent = E820; + + while ( i < (*E820_NR-1) ) { if ( (ent[i].type == ent[i+1].type) && ((ent[i].addr + ent[i].size) == ent[i+1].addr) ) { ent[i].size += ent[i+1].size; - memcpy(&ent[i+1], &ent[i+2], (*HVM_E820_NR-i-2) * sizeof(*ent)); - (*HVM_E820_NR)--; + memcpy(&ent[i+1], &ent[i+2], (*E820_NR-i-2) * sizeof(*ent)); + (*E820_NR)--; } else { @@ -329,13 +329,13 @@ uint32_t e820_malloc(uint32_t size, uint { uint32_t addr; int i; - struct e820entry *ent = (struct e820entry *)HVM_E820; - - /* Align to at leats one kilobyte. */ + struct e820entry *ent = E820; + + /* Align to at least one kilobyte. */ if ( align < 1024 ) align = 1024; - for ( i = *HVM_E820_NR - 1; i >= 0; i-- ) + for ( i = *E820_NR - 1; i >= 0; i-- ) { addr = (ent[i].addr + ent[i].size - size) & ~(align-1); if ( (ent[i].type != E820_RAM) || /* not ram? */ @@ -345,8 +345,8 @@ uint32_t e820_malloc(uint32_t size, uint if ( addr != ent[i].addr ) { - memmove(&ent[i+1], &ent[i], (*HVM_E820_NR-i) * sizeof(*ent)); - (*HVM_E820_NR)++; + memmove(&ent[i+1], &ent[i], (*E820_NR-i) * sizeof(*ent)); + (*E820_NR)++; ent[i].size = addr - ent[i].addr; ent[i+1].addr = addr; ent[i+1].size -= ent[i].size; diff -r b8b66dc0fa1d -r 661a839a481e tools/firmware/rombios/rombios.c --- a/tools/firmware/rombios/rombios.c Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/firmware/rombios/rombios.c Wed Jan 07 12:20:18 2009 +0900 @@ -177,6 +177,8 @@ # define BIOS_BUILD_DATE "06/23/99" #endif +#define E820_SEG (Bit16u)(E820_PHYSICAL_ADDRESS >> 4) + // 1K of base memory used for Extended Bios Data Area (EBDA) // EBDA is used for PS/2 mouse support, and IDE BIOS, etc. #define EBDA_SEG 0x9FC0 @@ -883,7 +885,6 @@ static void write_byte(); static void write_byte(); static void write_word(); static void bios_printf(); -static void copy_e820_table(); static Bit8u inhibit_mouse_int_and_events(); static void enable_mouse_int_and_events(); @@ -1405,19 +1406,13 @@ ASM_END #ifdef HVMASSIST void -copy_e820_table() +fixup_base_mem_in_k() { - Bit8u nr_entries = read_byte(0x9000, 0x1e8); - Bit32u base_mem; - if (nr_entries > 32) - nr_entries = 32; - write_word(0xe000, 0x8, nr_entries); - memcpyb(0xe000, 0x10, 0x9000, 0x2d0, nr_entries * 0x14); /* Report the proper base memory size at address 0x0413: otherwise * non-e820 code will clobber things if BASE_MEM_IN_K is bigger than * the first e820 entry. Get the size by reading the second 64bit * field of the first e820 slot. */ - base_mem = read_dword(0x9000, 0x2d0 + 8); + Bit32u base_mem = read_dword(E820_SEG, E820_OFFSET + 8); write_word(0x40, 0x13, base_mem >> 10); } @@ -2146,64 +2141,62 @@ interactive_bootkey() Bit16u valid_choice = 0; Bit16u ebda_seg = read_word(0x0040, 0x000E); + printf("\n\nPress F12 for boot menu.\n\n"); + while (check_for_keystroke()) - get_keystroke(); - - printf("\nPress F12 for boot menu.\n\n"); - - delay_ticks_and_check_for_keystroke(11, 5); /* ~3 seconds */ - if (check_for_keystroke()) { scan_code = get_keystroke(); - if (scan_code == 0x86) /* F12 */ + if (scan_code != 0x86) /* F12 */ + continue; + + while (check_for_keystroke()) + get_keystroke(); + + printf("Select boot device:\n\n"); + + count = read_word(ebda_seg, IPL_COUNT_OFFSET); + for (i = 0; i < count; i++) { - while (check_for_keystroke()) - get_keystroke(); - - printf("Select boot device:\n\n"); - - count = read_word(ebda_seg, IPL_COUNT_OFFSET); - for (i = 0; i < count; i++) + memcpyb(ss, &e, ebda_seg, IPL_TABLE_OFFSET + i * sizeof (e), sizeof (e)); + printf("%d. ", i+1); + switch(e.type) { - memcpyb(ss, &e, ebda_seg, IPL_TABLE_OFFSET + i * sizeof (e), sizeof (e)); - printf("%d. ", i+1); - switch(e.type) - { - case IPL_TYPE_FLOPPY: - case IPL_TYPE_HARDDISK: - case IPL_TYPE_CDROM: - printf("%s\n", drivetypes[e.type]); - break; - case IPL_TYPE_BEV: - printf("%s", drivetypes[4]); - if (e.description != 0) - { - memcpyb(ss, &description, (Bit16u)(e.description >> 16), (Bit16u)(e.description & 0xffff), 32); - description[32] = 0; - printf(" [%S]", ss, description); - } - printf("\n"); - break; - } + case IPL_TYPE_FLOPPY: + case IPL_TYPE_HARDDISK: + case IPL_TYPE_CDROM: + printf("%s\n", drivetypes[e.type]); + break; + case IPL_TYPE_BEV: + printf("%s", drivetypes[4]); + if (e.description != 0) + { + memcpyb(ss, &description, (Bit16u)(e.description >> 16), (Bit16u)(e.description & 0xffff), 32); + description[32] = 0; + printf(" [%S]", ss, description); + } + printf("\n"); + break; } - - count++; - while (!valid_choice) { - scan_code = get_keystroke(); - if (scan_code == 0x01 || scan_code == 0x58) /* ESC or F12 */ - { - valid_choice = 1; - } - else if (scan_code <= count) - { - valid_choice = 1; - scan_code -= 1; - /* Set user selected device */ - write_word(ebda_seg, IPL_BOOTFIRST_OFFSET, scan_code); - } + } + + count++; + while (!valid_choice) { + scan_code = get_keystroke(); + if (scan_code == 0x01 || scan_code == 0x58) /* ESC or F12 */ + { + valid_choice = 1; } + else if (scan_code <= count) + { + valid_choice = 1; + scan_code -= 1; + /* Set user selected device */ + write_word(ebda_seg, IPL_BOOTFIRST_OFFSET, scan_code); + } + } + printf("\n"); - } + break; } } #endif // BX_ELTORITO_BOOT @@ -4669,7 +4662,8 @@ ASM_END { #ifdef HVMASSIST case 0x20: { - Bit16u e820_table_size = read_word(0xe000, 0x8) * 0x14; + Bit16u e820_table_size = + read_word(E820_SEG, E820_NR_OFFSET) * 0x14; if (regs.u.r32.edx != 0x534D4150) /* SMAP */ goto int15_unimplemented; @@ -4677,7 +4671,7 @@ ASM_END if ((regs.u.r16.bx / 0x14) * 0x14 == regs.u.r16.bx) { if (regs.u.r16.bx + 0x14 <= e820_table_size) memcpyb(ES, regs.u.r16.di, - 0xe000, 0x10 + regs.u.r16.bx, 0x14); + E820_SEG, E820_OFFSET + regs.u.r16.bx, 0x14); regs.u.r32.ebx += 0x14; if ((regs.u.r32.ebx + 0x14 - 1) > e820_table_size) regs.u.r32.ebx = 0; @@ -4685,8 +4679,8 @@ ASM_END Bit32u base, type; Bit16u off; for (off = 0; off < e820_table_size; off += 0x14) { - base = read_dword(0xe000, 0x10 + off); - type = read_dword(0xe000, 0x20 + off); + base = read_dword(E820_SEG, E820_OFFSET + off); + type = read_dword(E820_SEG, E820_OFFSET + 0x10 + off); if ((base >= 0x100000) && (type == 1)) break; } @@ -4694,7 +4688,7 @@ ASM_END SET_CF(); break; } - memcpyb(ES, regs.u.r16.di, 0xe000, 0x10 + off, 0x14); + memcpyb(ES, regs.u.r16.di, E820_SEG, E820_OFFSET + off, 0x14); regs.u.r32.ebx = 0; } else { /* AX=E820, DX=534D4150, BX unrecognized */ goto int15_unimplemented; @@ -4707,7 +4701,8 @@ ASM_END } case 0x01: { - Bit16u off, e820_table_size = read_word(0xe000, 0x8) * 0x14; + Bit16u off, e820_table_size = + read_word(E820_SEG, E820_NR_OFFSET) * 0x14; Bit32u base, type, size; // do we have any reason to fail here ? @@ -4723,8 +4718,8 @@ ASM_END // Find first RAM E820 entry >= 1MB. for (off = 0; off < e820_table_size; off += 0x14) { - base = read_dword(0xe000, 0x10 + off); - type = read_dword(0xe000, 0x20 + off); + base = read_dword(E820_SEG, E820_OFFSET + off); + type = read_dword(E820_SEG, E820_OFFSET + 0x10 + off); if ((base >= 0x100000) && (type == 1)) break; } @@ -4732,7 +4727,7 @@ ASM_END // If there is RAM above 16MB, return amount in 64kB chunks. regs.u.r16.dx = 0; if (off != e820_table_size) { - size = base + read_dword(0xe000, 0x18 + off); + size = base + read_dword(E820_SEG, E820_OFFSET + 0x8 + off); if (size > 0x1000000) { size -= 0x1000000; regs.u.r16.dx = (Bit16u)(size >> 16); @@ -10026,7 +10021,7 @@ pci_routing_table_structure_start: db 0 ;; reserved pci_routing_table_structure_end: -#if !BX_ROMBIOS32 +#if !BX_ROMBIOS32 && !defined(HVMASSIST) pci_irq_list: db 11, 10, 9, 5; @@ -10441,8 +10436,8 @@ rom_scan: rom_scan: ;; Scan for existence of valid expansion ROMS. ;; Video ROM: from 0xC0000..0xC7FFF in 2k increments - ;; General ROM: from 0xC8000..0xDFFFF in 2k increments - ;; System ROM: only 0xE0000 + ;; General ROM: from 0xC8000..0xE9FFF in 2k increments + ;; System ROM: only 0xF0000 ;; ;; Header: ;; Offset Value @@ -10473,8 +10468,6 @@ rom_scan_loop: add al, #0x04 block_count_rounded: - xor bx, bx ;; Restore DS back to 0000: - mov ds, bx #if BX_TCGBIOS push ax push ds @@ -10816,7 +10809,6 @@ post_default_ints: mov ax, #BASE_MEM_IN_K mov 0x0413, ax - ;; Manufacturing Test 40:12 ;; zerod out above @@ -10972,7 +10964,7 @@ post_default_ints: #if BX_ROMBIOS32 call rombios32_init #else -#if BX_PCIBIOS +#if BX_PCIBIOS && !defined(HVMASSIST) call pcibios_init_iomem_bases call pcibios_init_irqs #endif //BX_PCIBIOS @@ -11010,16 +11002,19 @@ post_default_ints: #ifdef HVMASSIST call _enable_rom_write_access call _clobber_entry_point - call _copy_e820_table + call _fixup_base_mem_in_k call smbios_init +#endif + + call _init_boot_vectors + + mov cx, #(OPTIONROM_PHYSICAL_ADDRESS >> 4) ;; init option roms + mov ax, #(OPTIONROM_PHYSICAL_END >> 4) + call rom_scan + +#ifdef HVMASSIST call _disable_rom_write_access #endif - - call _init_boot_vectors - - mov cx, #0xc800 ;; init option roms - mov ax, #0xe000 - call rom_scan #if BX_ELTORITO_BOOT call _interactive_bootkey diff -r b8b66dc0fa1d -r 661a839a481e tools/firmware/rombios/rombios.h --- a/tools/firmware/rombios/rombios.h Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/firmware/rombios/rombios.h Wed Jan 07 12:20:18 2009 +0900 @@ -27,7 +27,7 @@ #else # define BX_ROMBIOS32 0 #endif -#define DEBUG_ROMBIOS 1 +#define DEBUG_ROMBIOS 0 #define PANIC_PORT 0x400 #define PANIC_PORT2 0x401 diff -r b8b66dc0fa1d -r 661a839a481e tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/libxc/xc_domain.c Wed Jan 07 12:20:18 2009 +0900 @@ -562,6 +562,76 @@ int xc_domain_memory_translate_gpfn_list } return err; +} + +static int xc_domain_memory_pod_target(int xc_handle, + int op, + uint32_t domid, + uint64_t target_pages, + uint64_t *tot_pages, + uint64_t *pod_cache_pages, + uint64_t *pod_entries) +{ + int err; + + struct xen_pod_target pod_target = { + .domid = domid, + .target_pages = target_pages + }; + + err = xc_memory_op(xc_handle, op, &pod_target); + + if ( err < 0 ) + { + DPRINTF("Failed %s_memory_target dom %d\n", + (op==XENMEM_set_pod_target)?"set":"get", + domid); + errno = -err; + err = -1; + } + else + err = 0; + + if ( tot_pages ) + *tot_pages = pod_target.tot_pages; + if ( pod_cache_pages ) + *pod_cache_pages = pod_target.pod_cache_pages; + if ( pod_entries ) + *pod_entries = pod_target.pod_entries; + + return err; +} + + +int xc_domain_memory_set_pod_target(int xc_handle, + uint32_t domid, + uint64_t target_pages, + uint64_t *tot_pages, + uint64_t *pod_cache_pages, + uint64_t *pod_entries) +{ + return xc_domain_memory_pod_target(xc_handle, + XENMEM_set_pod_target, + domid, + target_pages, + tot_pages, + pod_cache_pages, + pod_entries); +} + +int xc_domain_memory_get_pod_target(int xc_handle, + uint32_t domid, + uint64_t *tot_pages, + uint64_t *pod_cache_pages, + uint64_t *pod_entries) +{ + return xc_domain_memory_pod_target(xc_handle, + XENMEM_get_pod_target, + domid, + -1, + tot_pages, + pod_cache_pages, + pod_entries); } int xc_domain_max_vcpus(int xc_handle, uint32_t domid, unsigned int max) diff -r b8b66dc0fa1d -r 661a839a481e tools/libxc/xc_hvm_build.c --- a/tools/libxc/xc_hvm_build.c Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/libxc/xc_hvm_build.c Wed Jan 07 12:20:18 2009 +0900 @@ -146,11 +146,13 @@ static int loadelfimage( } static int setup_guest(int xc_handle, - uint32_t dom, int memsize, + uint32_t dom, int memsize, int target, char *image, unsigned long image_size) { xen_pfn_t *page_array = NULL; unsigned long i, nr_pages = (unsigned long)memsize << (20 - PAGE_SHIFT); + unsigned long target_pages = (unsigned long)target << (20 - PAGE_SHIFT); + unsigned long pod_pages = 0; unsigned long special_page_nr, entry_eip, cur_pages; struct xen_add_to_physmap xatp; struct shared_info *shared_info; @@ -160,10 +162,15 @@ static int setup_guest(int xc_handle, uint64_t v_start, v_end; int rc; xen_capabilities_info_t caps; + int pod_mode = 0; + /* An HVM guest must be initialised with at least 2MB memory. */ - if ( memsize < 2 ) - goto error_out; + if ( memsize < 2 || target < 2 ) + goto error_out; + + if ( memsize > target ) + pod_mode = 1; if ( elf_init(&elf, image, image_size) != 0 ) goto error_out; @@ -235,6 +242,10 @@ static int setup_guest(int xc_handle, .extent_order = SUPERPAGE_PFN_SHIFT, .domid = dom }; + + if ( pod_mode ) + sp_req.mem_flags = XENMEMF_populate_on_demand; + set_xen_guest_handle(sp_req.extent_start, sp_extents); for ( i = 0; i < sp_req.nr_extents; i++ ) sp_extents[i] = page_array[cur_pages+(i<<SUPERPAGE_PFN_SHIFT)]; @@ -242,6 +253,11 @@ static int setup_guest(int xc_handle, if ( done > 0 ) { done <<= SUPERPAGE_PFN_SHIFT; + if ( pod_mode && target_pages > cur_pages ) + { + int d = target_pages - cur_pages; + pod_pages += ( done < d ) ? done : d; + } cur_pages += done; count -= done; } @@ -253,8 +269,16 @@ static int setup_guest(int xc_handle, rc = xc_domain_memory_populate_physmap( xc_handle, dom, count, 0, 0, &page_array[cur_pages]); cur_pages += count; + if ( pod_mode ) + pod_pages -= count; } } + + if ( pod_mode ) + rc = xc_domain_memory_set_pod_target(xc_handle, + dom, + pod_pages, + NULL, NULL, NULL); if ( rc != 0 ) { @@ -354,6 +378,7 @@ static int xc_hvm_build_internal(int xc_ static int xc_hvm_build_internal(int xc_handle, uint32_t domid, int memsize, + int target, char *image, unsigned long image_size) { @@ -363,7 +388,7 @@ static int xc_hvm_build_internal(int xc_ return -1; } - return setup_guest(xc_handle, domid, memsize, image, image_size); + return setup_guest(xc_handle, domid, memsize, target, image, image_size); } static inline int is_loadable_phdr(Elf32_Phdr *phdr) @@ -388,7 +413,34 @@ int xc_hvm_build(int xc_handle, ((image = xc_read_image(image_name, &image_size)) == NULL) ) return -1; - sts = xc_hvm_build_internal(xc_handle, domid, memsize, image, image_size); + sts = xc_hvm_build_internal(xc_handle, domid, memsize, memsize, image, image_size); + + free(image); + + return sts; +} + +/* xc_hvm_build_target_mem: + * Create a domain for a pre-ballooned virtualized Linux, using + * files/filenames. If target < memsize, domain is created with + * memsize pages marked populate-on-demand, and with a PoD cache size + * of target. If target == memsize, pages are populated normally. + */ +int xc_hvm_build_target_mem(int xc_handle, + uint32_t domid, + int memsize, + int target, + const char *image_name) +{ + char *image; + int sts; + unsigned long image_size; + + if ( (image_name == NULL) || + ((image = xc_read_image(image_name, &image_size)) == NULL) ) + return -1; + + sts = xc_hvm_build_internal(xc_handle, domid, memsize, target, image, image_size); free(image); @@ -423,7 +475,7 @@ int xc_hvm_build_mem(int xc_handle, return -1; } - sts = xc_hvm_build_internal(xc_handle, domid, memsize, + sts = xc_hvm_build_internal(xc_handle, domid, memsize, memsize, img, img_len); /* xc_inflate_buffer may return the original buffer pointer (for diff -r b8b66dc0fa1d -r 661a839a481e tools/libxc/xc_pagetab.c --- a/tools/libxc/xc_pagetab.c Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/libxc/xc_pagetab.c Wed Jan 07 12:20:18 2009 +0900 @@ -5,180 +5,94 @@ */ #include "xc_private.h" -#if defined(__i386__) - -#define L1_PAGETABLE_SHIFT_PAE 12 -#define L2_PAGETABLE_SHIFT_PAE 21 -#define L3_PAGETABLE_SHIFT_PAE 30 - -#define L1_PAGETABLE_SHIFT 12 -#define L2_PAGETABLE_SHIFT 22 - -#define L0_PAGETABLE_MASK_PAE 0x00000ffffffff000ULL -#define L1_PAGETABLE_MASK_PAE 0x1ffULL -#define L2_PAGETABLE_MASK_PAE 0x1ffULL -#define L3_PAGETABLE_MASK_PAE 0x3ULL - -#define L0_PAGETABLE_MASK 0xfffff000ULL -#define L1_PAGETABLE_MASK 0x3ffULL -#define L2_PAGETABLE_MASK 0x3ffULL - -#elif defined(__x86_64__) - -#define L1_PAGETABLE_SHIFT_PAE 12 -#define L2_PAGETABLE_SHIFT_PAE 21 -#define L3_PAGETABLE_SHIFT_PAE 30 -#define L4_PAGETABLE_SHIFT_PAE 39 - -#define L1_PAGETABLE_SHIFT L1_PAGETABLE_SHIFT_PAE -#define L2_PAGETABLE_SHIFT L2_PAGETABLE_SHIFT_PAE - -#define L0_PAGETABLE_MASK_PAE 0x000ffffffffff000ULL -#define L1_PAGETABLE_MASK_PAE 0x1ffULL -#define L2_PAGETABLE_MASK_PAE 0x1ffULL -#define L3_PAGETABLE_MASK_PAE 0x1ffULL -#define L4_PAGETABLE_MASK_PAE 0x1ffULL - -#define L0_PAGETABLE_MASK L0_PAGETABLE_MASK_PAE -#define L1_PAGETABLE_MASK L1_PAGETABLE_MASK_PAE -#define L2_PAGETABLE_MASK L2_PAGETABLE_MASK_PAE - -#endif +#define CR0_PG 0x80000000 +#define CR4_PAE 0x20 +#define PTE_PSE 0x80 unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom, - int vcpu, unsigned long long virt ) + int vcpu, unsigned long long virt) { + xc_dominfo_t dominfo; vcpu_guest_context_any_t ctx; - unsigned long long cr3; - void *pd, *pt, *pdppage = NULL, *pdp, *pml = NULL; - unsigned long long pde, pte, pdpe, pmle; - unsigned long mfn = 0; -#if defined (__i386__) - static int pt_levels = 0; + uint64_t paddr, mask, pte = 0; + int size, level, pt_levels = 2; + void *map; - if (pt_levels == 0) { + if (xc_domain_getinfo(xc_handle, dom, 1, &dominfo) != 1 + || dominfo.domid != dom + || xc_vcpu_getcontext(xc_handle, dom, vcpu, &ctx) != 0) + return 0; + + /* What kind of paging are we dealing with? */ + if (dominfo.hvm) { + unsigned long cr0, cr3, cr4; xen_capabilities_info_t xen_caps = ""; - if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) - goto out; - if (strstr(xen_caps, "xen-3.0-x86_64")) + return 0; + /* HVM context records are always host-sized */ + if (strstr(xen_caps, "xen-3.0-x86_64")) { + cr0 = ctx.x64.ctrlreg[0]; + cr3 = ctx.x64.ctrlreg[3]; + cr4 = ctx.x64.ctrlreg[4]; + } else { + cr0 = ctx.x32.ctrlreg[0]; + cr3 = ctx.x32.ctrlreg[3]; + cr4 = ctx.x32.ctrlreg[4]; + } + if (!(cr0 & CR0_PG)) + return virt; + if (0 /* XXX how to get EFER.LMA? */) pt_levels = 4; - else if (strstr(xen_caps, "xen-3.0-x86_32p")) + else + pt_levels = (cr4 & CR4_PAE) ? 3 : 2; + paddr = cr3 & ((pt_levels == 3) ? ~0x1full : ~0xfffull); + } else { + DECLARE_DOMCTL; + domctl.domain = dom; + domctl.cmd = XEN_DOMCTL_get_address_size; + if ( do_domctl(xc_handle, &domctl) != 0 ) + return 0; + if (domctl.u.address_size.size == 64) { + pt_levels = 4; + paddr = ctx.x64.ctrlreg[3] & ~0xfffull; + } else { pt_levels = 3; - else if (strstr(xen_caps, "xen-3.0-x86_32")) - pt_levels = 2; - else - goto out; - } -#elif defined (__x86_64__) -#define pt_levels 4 -#endif - - if (xc_vcpu_getcontext(xc_handle, dom, vcpu, &ctx) != 0) { - DPRINTF("failed to retreive vcpu context\n"); - goto out; - } - cr3 = ((unsigned long long)xen_cr3_to_pfn(ctx.c.ctrlreg[3])) << PAGE_SHIFT; - - /* Page Map Level 4 */ - -#if defined(__i386__) - pmle = cr3; -#elif defined(__x86_64__) - pml = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, cr3 >> PAGE_SHIFT); - if (pml == NULL) { - DPRINTF("failed to map PML4\n"); - goto out; - } - pmle = *(unsigned long long *)(pml + 8 * ((virt >> L4_PAGETABLE_SHIFT_PAE) & L4_PAGETABLE_MASK_PAE)); - if((pmle & 1) == 0) { - DPRINTF("page entry not present in PML4\n"); - goto out_unmap_pml; - } -#endif - - /* Page Directory Pointer Table */ - - if (pt_levels >= 3) { - pdppage = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, pmle >> PAGE_SHIFT); - if (pdppage == NULL) { - DPRINTF("failed to map PDP\n"); - goto out_unmap_pml; + paddr = (((uint64_t) xen_cr3_to_pfn(ctx.x32.ctrlreg[3])) + << PAGE_SHIFT); } - if (pt_levels >= 4) - pdp = pdppage; - else - /* PDP is only 32 bit aligned with 3 level pts */ - pdp = pdppage + (pmle & ~(XC_PAGE_MASK | 0x1f)); - - pdpe = *(unsigned long long *)(pdp + 8 * ((virt >> L3_PAGETABLE_SHIFT_PAE) & L3_PAGETABLE_MASK_PAE)); - - if((pdpe & 1) == 0) { - DPRINTF("page entry not present in PDP\n"); - goto out_unmap_pdp; - } - } else { - pdpe = pmle; } - /* Page Directory */ + if (pt_levels == 4) { + virt &= 0x0000ffffffffffffull; + mask = 0x0000ff8000000000ull; + } else if (pt_levels == 3) { + virt &= 0x00000000ffffffffull; + mask = 0x0000007fc0000000ull; + } else { + virt &= 0x00000000ffffffffull; + mask = 0x00000000ffc00000ull; + } + size = (pt_levels == 2 ? 4 : 8); - pd = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, pdpe >> PAGE_SHIFT); - if (pd == NULL) { - DPRINTF("failed to map PD\n"); - goto out_unmap_pdp; + /* Walk the pagetables */ + for (level = pt_levels; level > 0; level--) { + paddr += ((virt & mask) >> (xc_ffs64(mask) - 1)) * size; + map = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, + paddr >>PAGE_SHIFT); + if (!map) + return 0; + memcpy(&pte, map + (paddr & (PAGE_SIZE - 1)), size); + munmap(map, PAGE_SIZE); + if (!(pte & 1)) + return 0; + paddr = pte & 0x000ffffffffff000ull; + if (level == 2 && (pte & PTE_PSE)) { + mask = ((mask ^ ~-mask) >> 1); /* All bits below first set bit */ + return ((paddr & ~mask) | (virt & mask)) >> PAGE_SHIFT; + } + mask >>= (pt_levels == 2 ? 10 : 9); } - - if (pt_levels >= 3) - pde = *(unsigned long long *)(pd + 8 * ((virt >> L2_PAGETABLE_SHIFT_PAE) & L2_PAGETABLE_MASK_PAE)); - else - pde = *(unsigned long *)(pd + 4 * ((virt >> L2_PAGETABLE_SHIFT) & L2_PAGETABLE_MASK)); - - if ((pde & 1) == 0) { - DPRINTF("page entry not present in PD\n"); - goto out_unmap_pd; - } - - /* Page Table */ - - if (pde & 0x00000080) { /* 4M page (or 2M in PAE mode) */ - DPRINTF("Cannot currently cope with 2/4M pages\n"); - exit(-1); - } else { /* 4k page */ - pt = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, - pde >> PAGE_SHIFT); - - if (pt == NULL) { - DPRINTF("failed to map PT\n"); - goto out_unmap_pd; - } - - if (pt_levels >= 3) - pte = *(unsigned long long *)(pt + 8 * ((virt >> L1_PAGETABLE_SHIFT_PAE) & L1_PAGETABLE_MASK_PAE)); - else - pte = *(unsigned long *)(pt + 4 * ((virt >> L1_PAGETABLE_SHIFT) & L1_PAGETABLE_MASK)); - - if ((pte & 1) == 0) { - DPRINTF("page entry not present in PT\n"); - goto out_unmap_pt; - } - - if (pt_levels >= 3) - mfn = (pte & L0_PAGETABLE_MASK_PAE) >> PAGE_SHIFT; - else - mfn = (pte & L0_PAGETABLE_MASK) >> PAGE_SHIFT; - } - - out_unmap_pt: - munmap(pt, PAGE_SIZE); - out_unmap_pd: - munmap(pd, PAGE_SIZE); - out_unmap_pdp: - munmap(pdppage, PAGE_SIZE); - out_unmap_pml: - munmap(pml, PAGE_SIZE); - out: - return mfn; + return paddr >> PAGE_SHIFT; } /* diff -r b8b66dc0fa1d -r 661a839a481e tools/libxc/xc_private.c --- a/tools/libxc/xc_private.c Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/libxc/xc_private.c Wed Jan 07 12:20:18 2009 +0900 @@ -323,6 +323,14 @@ int xc_memory_op(int xc_handle, goto out1; } break; + case XENMEM_set_pod_target: + case XENMEM_get_pod_target: + if ( lock_pages(arg, sizeof(struct xen_pod_target)) ) + { + PERROR("Could not lock"); + goto out1; + } + break; } ret = do_xen_hypercall(xc_handle, &hypercall); @@ -354,6 +362,10 @@ int xc_memory_op(int xc_handle, case XENMEM_maximum_reservation: case XENMEM_maximum_gpfn: unlock_pages(arg, sizeof(domid_t)); + break; + case XENMEM_set_pod_target: + case XENMEM_get_pod_target: + unlock_pages(arg, sizeof(struct xen_pod_target)); break; } @@ -627,6 +639,33 @@ int write_exact(int fd, const void *data return 0; } +int xc_ffs8(uint8_t x) +{ + int i; + for ( i = 0; i < 8; i++ ) + if ( x & (1u << i) ) + return i+1; + return 0; +} + +int xc_ffs16(uint16_t x) +{ + uint8_t h = x>>8, l = x; + return l ? xc_ffs8(l) : h ? xc_ffs8(h) + 8 : 0; +} + +int xc_ffs32(uint32_t x) +{ + uint16_t h = x>>16, l = x; + return l ? xc_ffs16(l) : h ? xc_ffs16(h) + 16 : 0; +} + +int xc_ffs64(uint64_t x) +{ + uint32_t h = x>>32, l = x; + return l ? xc_ffs32(l) : h ? xc_ffs32(h) + 32 : 0; +} + /* * Local variables: * mode: C diff -r b8b66dc0fa1d -r 661a839a481e tools/libxc/xc_private.h --- a/tools/libxc/xc_private.h Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/libxc/xc_private.h Wed Jan 07 12:20:18 2009 +0900 @@ -218,4 +218,9 @@ int read_exact(int fd, void *data, size_ int read_exact(int fd, void *data, size_t size); int write_exact(int fd, const void *data, size_t size); +int xc_ffs8(uint8_t x); +int xc_ffs16(uint16_t x); +int xc_ffs32(uint32_t x); +int xc_ffs64(uint64_t x); + #endif /* __XC_PRIVATE_H__ */ diff -r b8b66dc0fa1d -r 661a839a481e tools/libxc/xc_ptrace.c --- a/tools/libxc/xc_ptrace.c Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/libxc/xc_ptrace.c Wed Jan 07 12:20:18 2009 +0900 @@ -44,8 +44,7 @@ static uint64_t static uint64_t regs_valid; static vcpu_guest_context_any_t ctxt[MAX_VIRT_CPUS]; -extern int ffsll(long long int); -#define FOREACH_CPU(cpumap, i) for ( cpumap = online_cpumap; (i = ffsll(cpumap)); cpumap &= ~(1 << (index - 1)) ) +#define FOREACH_CPU(cpumap, i) for ( cpumap = online_cpumap; (i = xc_ffs64(cpumap)); cpumap &= ~(1 << (index - 1)) ) static int fetch_regs(int xc_handle, int cpu, int *online) @@ -136,7 +135,7 @@ online_vcpus_changed(uint64_t cpumap) uint64_t changed_cpumap = cpumap ^ online_cpumap; int index; - while ( (index = ffsll(changed_cpumap)) ) { + while ( (index = xc_ffs64(changed_cpumap)) ) { if ( cpumap & (1 << (index - 1)) ) { if (handlers.td_create) handlers.td_create(index - 1); diff -r b8b66dc0fa1d -r 661a839a481e tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/libxc/xenctrl.h Wed Jan 07 12:20:18 2009 +0900 @@ -634,6 +634,19 @@ int xc_domain_memory_translate_gpfn_list xen_pfn_t *gpfn_list, xen_pfn_t *mfn_list); +int xc_domain_memory_set_pod_target(int xc_handle, + uint32_t domid, + uint64_t target_pages, + uint64_t *tot_pages, + uint64_t *pod_cache_pages, + uint64_t *pod_entries); + +int xc_domain_memory_get_pod_target(int xc_handle, + uint32_t domid, + uint64_t *tot_pages, + uint64_t *pod_cache_pages, + uint64_t *pod_entries); + int xc_domain_ioport_permission(int xc_handle, uint32_t domid, uint32_t first_port, @@ -703,8 +716,8 @@ void *xc_map_foreign_batch(int xc_handle /** * Translates a virtual address in the context of a given domain and - * vcpu returning the machine page frame number of the associated - * page. + * vcpu returning the GFN containing the address (that is, an MFN for + * PV guests, a PFN for HVM guests). Returns 0 for failure. * * @parm xc_handle a handle on an open hypervisor interface * @parm dom the domain to perform the translation in diff -r b8b66dc0fa1d -r 661a839a481e tools/libxc/xenguest.h --- a/tools/libxc/xenguest.h Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/libxc/xenguest.h Wed Jan 07 12:20:18 2009 +0900 @@ -130,6 +130,12 @@ int xc_hvm_build(int xc_handle, int memsize, const char *image_name); +int xc_hvm_build_target_mem(int xc_handle, + uint32_t domid, + int memsize, + int target, + const char *image_name); + int xc_hvm_build_mem(int xc_handle, uint32_t domid, int memsize, diff -r b8b66dc0fa1d -r 661a839a481e tools/libxc/xg_private.c --- a/tools/libxc/xg_private.c Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/libxc/xg_private.c Wed Jan 07 12:20:18 2009 +0900 @@ -7,7 +7,6 @@ #include <stdlib.h> #include <unistd.h> #include <zlib.h> -#include <strings.h> #include <malloc.h> #include "xg_private.h" diff -r b8b66dc0fa1d -r 661a839a481e tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/python/xen/lowlevel/xc/xc.c Wed Jan 07 12:20:18 2009 +0900 @@ -890,17 +890,20 @@ static PyObject *pyxc_hvm_build(XcObject int i; #endif char *image; - int memsize, vcpus = 1, acpi = 0, apic = 1; + int memsize, target=-1, vcpus = 1, acpi = 0, apic = 1; static char *kwd_list[] = { "domid", - "memsize", "image", "vcpus", "acpi", + "memsize", "image", "target", "vcpus", "acpi", "apic", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iii", kwd_list, - &dom, &memsize, - &image, &vcpus, &acpi, &apic) ) - return NULL; - - if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 ) + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iiii", kwd_list, + &dom, &memsize, &image, &target, &vcpus, + &acpi, &apic) ) + return NULL; + + if ( target == -1 ) + target = memsize; + + if ( xc_hvm_build_target_mem(self->xc_handle, dom, memsize, target, image) != 0 ) return pyxc_error_to_exception(); #if !defined(__ia64__) @@ -1329,6 +1332,24 @@ static PyObject *pyxc_domain_setmaxmem(X return NULL; if (xc_domain_setmaxmem(self->xc_handle, dom, maxmem_kb) != 0) + return pyxc_error_to_exception(); + + Py_INCREF(zero); + return zero; +} + +static PyObject *pyxc_domain_set_target_mem(XcObject *self, PyObject *args) +{ + uint32_t dom; + unsigned int mem_kb, mem_pages; + + if (!PyArg_ParseTuple(args, "ii", &dom, &mem_kb)) + return NULL; + + mem_pages = mem_kb / 4; + + if (xc_domain_memory_set_pod_target(self->xc_handle, dom, mem_pages, + NULL, NULL, NULL) != 0) return pyxc_error_to_exception(); Py_INCREF(zero); @@ -1813,6 +1834,14 @@ static PyMethodDef pyxc_methods[] = { "Set a domain's memory limit\n" " dom [int]: Identifier of domain.\n" " maxmem_kb [int]: .\n" + "Returns: [int] 0 on success; -1 on error.\n" }, + + { "domain_set_target_mem", + (PyCFunction)pyxc_domain_set_target_mem, + METH_VARARGS, "\n" + "Set a domain's memory target\n" + " dom [int]: Identifier of domain.\n" + " mem_kb [int]: .\n" "Returns: [int] 0 on success; -1 on error.\n" }, { "domain_set_memmap_limit", diff -r b8b66dc0fa1d -r 661a839a481e tools/python/xen/util/pci.py --- a/tools/python/xen/util/pci.py Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/python/xen/util/pci.py Wed Jan 07 12:20:18 2009 +0900 @@ -276,7 +276,7 @@ def check_FLR_capability(dev_list): coassigned_pci_list = dev.find_all_the_multi_functions() need_transform = True elif dev.dev_type == DEV_TYPE_PCI and not dev.pci_af_flr: - coassigned_pci_list = dev.find_coassigned_devices(True) + coassigned_pci_list = dev.find_coassigned_pci_devices(True) del coassigned_pci_list[0] need_transform = True @@ -434,7 +434,7 @@ class PciDevice: list = list + [dev.name] return list - def find_coassigned_devices(self, ignore_bridge = True): + def find_coassigned_pci_devices(self, ignore_bridge = True): ''' Here'self' is a PCI device, we need find the uppermost PCI/PCI-X bridge, and all devices behind it must be co-assigned to the same guest. @@ -532,6 +532,16 @@ class PciDevice: funcs = re.findall(p, pci_names) return funcs + def find_coassigned_devices(self): + if self.dev_type == DEV_TYPE_PCIe_ENDPOINT and not self.pcie_flr: + return self.find_all_the_multi_functions() + elif self.dev_type == DEV_TYPE_PCI and not self.pci_af_flr: + coassigned_pci_list = self.find_coassigned_pci_devices(True) + del coassigned_pci_list[0] + return coassigned_pci_list + else: + return [self.name] + def find_cap_offset(self, cap): path = find_sysfs_mnt()+SYSFS_PCI_DEVS_PATH+'/'+ \ self.name+SYSFS_PCI_DEV_CONFIG_PATH @@ -718,7 +728,7 @@ class PciDevice: if self.bus == 0: self.do_FLR_for_integrated_device() else: - devs = self.find_coassigned_devices(False) + devs = self.find_coassigned_pci_devices(False) # Remove the element 0 which is a bridge target_bus = devs[0] del devs[0] diff -r b8b66dc0fa1d -r 661a839a481e tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/python/xen/xend/XendDomainInfo.py Wed Jan 07 12:20:18 2009 +0900 @@ -290,19 +290,21 @@ def dom_get(dom): log.trace("domain_getinfo(%d) failed, ignoring: %s", dom, str(err)) return None -def do_FLR(domid): - from xen.xend.server.pciif import parse_pci_name, PciDevice +def get_assigned_pci_devices(domid): + dev_str_list = [] path = '/local/domain/0/backend/pci/%u/0/' % domid num_devs = xstransact.Read(path + 'num_devs'); if num_devs is None or num_devs == "": - return; - - num_devs = int(xstransact.Read(path + 'num_devs')); - - dev_str_list = [] + return dev_str_list + num_devs = int(num_devs); for i in range(num_devs): dev_str = xstransact.Read(path + 'dev-%i' % i) dev_str_list = dev_str_list + [dev_str] + return dev_str_list + +def do_FLR(domid): + from xen.xend.server.pciif import parse_pci_name, PciDevice + dev_str_list = get_assigned_pci_devices(domid) for dev_str in dev_str_list: (dom, b, d, f) = parse_pci_name(dev_str) @@ -645,6 +647,55 @@ class XendDomainInfo: " already been assigned to other domain, or maybe" " it doesn't exist." % (bus, dev, func)) + # Here, we duplicate some checkings (in some cases, we mustn't allow + # a device to be hot-plugged into an HVM guest) that are also done in + # pci_device_configure()'s self.device_create(dev_sxp) or + # dev_control.reconfigureDevice(devid, dev_config). + # We must make the checkings before sending the command 'pci-ins' to + # ioemu. + + # Test whether the device is owned by pciback. For instance, we can't + # hotplug a device being used by Dom0 itself to an HVM guest. + from xen.xend.server.pciif import PciDevice, parse_pci_name + domain = int(new_dev['domain'],16) + bus = int(new_dev['bus'],16) + dev = int(new_dev['slot'],16) + func = int(new_dev['func'],16) + try: + pci_device = PciDevice(domain, bus, dev, func) + except Exception, e: + raise VmError("pci: failed to locate device and "+ + "parse it's resources - "+str(e)) + if pci_device.driver!='pciback': + raise VmError(("pci: PCI Backend does not own device "+ \ + "%s\n"+ \ + "See the pciback.hide kernel "+ \ + "command-line parameter or\n"+ \ + "bind your slot/device to the PCI backend using sysfs" \ + )%(pci_device.name)) + + # Check non-page-aligned MMIO BAR. + if pci_device.has_non_page_aligned_bar and arch.type != "ia64": + raise VmError("pci: %s: non-page-aligned MMIO BAR found." % \ + pci_device.name) + + # Check the co-assignment. + # To pci-attach a device D to domN, we should ensure each of D's + # co-assignment devices hasn't been assigned, or has been assigned to + # domN. + coassignment_list = pci_device.find_coassigned_devices() + assigned_pci_device_str_list = get_assigned_pci_devices(self.domid) + for pci_str in coassignment_list: + (domain, bus, dev, func) = parse_pci_name(pci_str) + dev_str = '0x%x,0x%x,0x%x,0x%x' % (domain, bus, dev, func) + if xc.test_assign_device(self.domid, dev_str) == 0: + continue + if not pci_str in assigned_pci_device_str_list: + raise VmError(('pci: failed to pci-attach %s to dom%d" + \ + " because one of its co-assignment device %s has been" + \ + " assigned to other domain.' \ + )% (pci_device.name, self.domid, pci_str)) + bdf_str = "%s:%s:%s.%s@%s" % (new_dev['domain'], new_dev['bus'], new_dev['slot'], @@ -675,7 +726,7 @@ class XendDomainInfo: if dev_type == 'pci': for dev in dev_config_dict['devs']: XendAPIStore.deregister(dev['uuid'], 'DPCI') - if dev_type == 'vscsi': + elif dev_type == 'vscsi': for dev in dev_config_dict['devs']: XendAPIStore.deregister(dev['uuid'], 'DSCSI') elif dev_type == 'tap': @@ -935,6 +986,31 @@ class XendDomainInfo: if vslot == 0: raise VmError("Device @ vslot 0x%x do not support hotplug." % (vslot)) + # Check the co-assignment. + # To pci-detach a device D from domN, we should ensure: for each DD in the + # list of D's co-assignment devices, DD is not assigned (to domN). + # + from xen.xend.server.pciif import PciDevice + domain = int(x['domain'],16) + bus = int(x['bus'],16) + dev = int(x['slot'],16) + func = int(x['func'],16) + try: + pci_device = PciDevice(domain, bus, dev, func) + except Exception, e: + raise VmError("pci: failed to locate device and "+ + "parse it's resources - "+str(e)) + coassignment_list = pci_device.find_coassigned_devices() + coassignment_list.remove(pci_device.name) + assigned_pci_device_str_list = get_assigned_pci_devices(self.domid) + for pci_str in coassignment_list: + if pci_str in assigned_pci_device_str_list: + raise VmError(('pci: failed to pci-detach %s from dom%d" + \ + " because one of its co-assignment device %s is still " + \ + " assigned to the domain.' \ + )% (pci_device.name, self.domid, pci_str)) + + bdf_str = "%s:%s:%s.%s" % (x['domain'], x['bus'], x['slot'], x['func']) log.info("hvm_destroyPCIDevice:%s:%s!", x, bdf_str) @@ -1104,10 +1180,10 @@ class XendDomainInfo: self.info['name_label'], str(self.domid), target) MiB = 1024 * 1024 + memory_cur = self.get_memory_dynamic_max() / MiB if self.domid == 0: dom0_min_mem = xoptions.get_dom0_min_mem() - memory_cur = self.get_memory_dynamic_max() / MiB if target < memory_cur and dom0_min_mem > target: raise XendError("memory_dynamic_max too small") @@ -1115,8 +1191,12 @@ class XendDomainInfo: self._safe_set_memory('memory_dynamic_max', target * MiB) if self.domid >= 0: + if target > memory_cur: + balloon.free( (target-memory_cur)*1024 ) self.storeVm("memory", target) self.storeDom("memory/target", target << 10) + xc.domain_set_target_mem(self.domid, + (target * 1024)) xen.xend.XendDomain.instance().managed_config_save(self) def setMemoryMaximum(self, limit): diff -r b8b66dc0fa1d -r 661a839a481e tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/python/xen/xend/image.py Wed Jan 07 12:20:18 2009 +0900 @@ -799,19 +799,22 @@ class HVMImageHandler(ImageHandler): def buildDomain(self): store_evtchn = self.vm.getStorePort() + memmax_mb = self.getRequiredMaximumReservation() / 1024 mem_mb = self.getRequiredInitialReservation() / 1024 log.debug("domid = %d", self.vm.getDomid()) log.debug("image = %s", self.loader) log.debug("store_evtchn = %d", store_evtchn) - log.debug("memsize = %d", mem_mb) + log.debug("memsize = %d", memmax_mb) + log.debug("target = %d", mem_mb) log.debug("vcpus = %d", self.vm.getVCpuCount()) log.debug("acpi = %d", self.acpi) log.debug("apic = %d", self.apic) rc = xc.hvm_build(domid = self.vm.getDomid(), image = self.loader, - memsize = mem_mb, + memsize = memmax_mb, + target = mem_mb, vcpus = self.vm.getVCpuCount(), acpi = self.acpi, apic = self.apic) diff -r b8b66dc0fa1d -r 661a839a481e tools/python/xen/xend/server/pciif.py --- a/tools/python/xen/xend/server/pciif.py Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/python/xen/xend/server/pciif.py Wed Jan 07 12:20:18 2009 +0900 @@ -417,7 +417,7 @@ class PciController(DevController): else: # All devices behind the uppermost PCI/PCI-X bridge must be\ # co-assigned to the same guest. - devs_str = dev.find_coassigned_devices(True) + devs_str = dev.find_coassigned_pci_devices(True) # Remove the element 0 which is a bridge del devs_str[0] diff -r b8b66dc0fa1d -r 661a839a481e tools/vnet/Makefile --- a/tools/vnet/Makefile Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/vnet/Makefile Wed Jan 07 12:20:18 2009 +0900 @@ -17,7 +17,8 @@ all: compile all: compile gc.tar.gz: - wget http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/$@ + #wget http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/$@ + wget $(XEN_EXTFILES_URL)/$@ .PHONY: gc gc: gc.tar.gz diff -r b8b66dc0fa1d -r 661a839a481e tools/xentrace/xenctx.c --- a/tools/xentrace/xenctx.c Wed Jan 07 12:19:36 2009 +0900 +++ b/tools/xentrace/xenctx.c Wed Jan 07 12:20:18 2009 +0900 @@ -24,6 +24,8 @@ #include <getopt.h> #include "xenctrl.h" +#include <xen/foreign/x86_32.h> +#include <xen/foreign/x86_64.h> int xc_handle = 0; int domid = 0; @@ -31,28 +33,18 @@ int stack_trace = 0; int stack_trace = 0; int disp_all = 0; -#if defined (__i386__) -#if defined (__OpenBSD__) -#define FMT_SIZE_T "%08lx" -#define INSTR_POINTER(regs) (unsigned long)(regs->eip) -#else -#define FMT_SIZE_T "%08x" -#define INSTR_POINTER(regs) (regs->eip) -#endif -#define STACK_POINTER(regs) (regs->esp) -#define FRAME_POINTER(regs) (regs->ebp) -#define STACK_ROWS 4 -#define STACK_COLS 8 -#elif defined (__x86_64__) -#define FMT_SIZE_T "%016lx" -#define STACK_POINTER(regs) (regs->rsp) -#define FRAME_POINTER(regs) (regs->rbp) -#define INSTR_POINTER(regs) (regs->rip) -#define STACK_ROWS 4 -#define STACK_COLS 4 +#if defined (__i386__) || defined (__x86_64__) +typedef unsigned long long guest_word_t; +#define FMT_32B_WORD "%08llx" +#define FMT_64B_WORD "%016llx" +/* Word-length of the guest's own data structures */ +int guest_word_size = sizeof (unsigned long); +/* Word-length of the context record we get from xen */ +int ctxt_word_size = sizeof (unsigned long); #elif defined (__ia64__) /* On ia64, we can't translate virtual address to physical address. */ #define NO_TRANSLATION +typedef size_t guest_word_t; /* Which registers should be displayed. */ int disp_cr_regs; @@ -63,22 +55,19 @@ int disp_tlb; #endif struct symbol { - size_t address; + guest_word_t address; char type; char *name; struct symbol *next; } *symbol_table = NULL; -size_t kernel_stext, kernel_etext, kernel_sinittext, kernel_einittext, kernel_hypercallpage; - -static int is_kernel_text(size_t addr) -{ -#if defined (__i386__) +guest_word_t kernel_stext, kernel_etext, kernel_sinittext, kernel_einittext, kernel_hypercallpage; + +static int is_kernel_text(guest_word_t addr) +{ +#if defined (__i386__) || defined (__x86_64__) if (symbol_table == NULL) - return (addr > 0xc000000); -#elif defined (__x86_64__) - if (symbol_table == NULL) - return (addr > 0xffffffff80000000UL); + return (addr > ((guest_word_size == 4) ? 0xc000000 : 0xffffffff80000000ULL)); #elif defined (__ia64__) if (symbol_table == NULL) return (addr > 0xa000000000000000UL); @@ -134,7 +123,7 @@ static void insert_symbol(struct symbol prev = symbol; } -static struct symbol *lookup_symbol(size_t address) +static struct symbol *lookup_symbol(guest_word_t address) { struct symbol *s = symbol_table; @@ -147,7 +136,7 @@ static struct symbol *lookup_symbol(size return NULL; } -static void print_symbol(size_t addr) +static void print_symbol(guest_word_t addr) { struct symbol *s; @@ -255,21 +244,23 @@ static void print_flags(uint64_t flags) printf("\n"); } -static void print_special(unsigned long *regs, const char *name, unsigned int mask) +static void print_special(void *regs, const char *name, unsigned int mask, int width) { unsigned int i; printf("\n"); for (i = 0; mask; mask >>= 1, ++i) - if (mask & 1) - printf("%s%u: " FMT_SIZE_T "\n", name, i, (size_t)regs[i]); -} -#endif - -#ifdef __i386__ -static void print_ctx(vcpu_guest_context_t *ctx1) -{ - struct cpu_user_regs *regs = &ctx1->user_regs; + if (mask & 1) { + if (width == 4) + printf("%s%u: %08"PRIx32"\n", name, i, ((uint32_t *) regs)[i]); + else + printf("%s%u: %08"PRIx64"\n", name, i, ((uint64_t *) regs)[i]); + } +} + +static void print_ctx_32(vcpu_guest_context_x86_32_t *ctx) +{ + struct cpu_user_regs_x86_32 *regs = &ctx->user_regs; printf("cs:eip: %04x:%08x ", regs->cs, regs->eip); print_symbol(regs->eip); @@ -291,54 +282,87 @@ static void print_ctx(vcpu_guest_context printf(" gs: %04x\n", regs->gs); if (disp_all) { - print_special(ctx1->ctrlreg, "cr", 0x1d); - print_special(ctx1->debugreg, "dr", 0xcf); - } -} -#elif defined(__x86_64__) -static void print_ctx(vcpu_guest_context_t *ctx1) -{ - struct cpu_user_regs *regs = &ctx1->user_regs; - - printf("rip: %016lx ", regs->rip); + print_special(ctx->ctrlreg, "cr", 0x1d, 4); + print_special(ctx->debugreg, "dr", 0xcf, 4); + } +} + +static void print_ctx_64(vcpu_guest_context_x86_64_t *ctx) +{ + struct cpu_user_regs_x86_64 *regs = &ctx->user_regs; + + printf("rip: %016"PRIx64" ", regs->rip); print_symbol(regs->rip); print_flags(regs->rflags); - printf("rsp: %016lx\n", regs->rsp); - - printf("rax: %016lx\t", regs->rax); - printf("rcx: %016lx\t", regs->rcx); - printf("rdx: %016lx\n", regs->rdx); - - printf("rbx: %016lx\t", regs->rbx); - printf("rsi: %016lx\t", regs->rsi); - printf("rdi: %016lx\n", regs->rdi); - - printf("rbp: %016lx\t", regs->rbp); - printf(" r8: %016lx\t", regs->r8); - printf(" r9: %016lx\n", regs->r9); - - printf("r10: %016lx\t", regs->r10); - printf("r11: %016lx\t", regs->r11); - printf("r12: %016lx\n", regs->r12); - - printf("r13: %016lx\t", regs->r13); - printf("r14: %016lx\t", regs->r14); - printf("r15: %016lx\n", regs->r15); + printf("rsp: %016"PRIx64"\n", regs->rsp); + + printf("rax: %016"PRIx64"\t", regs->rax); + printf("rcx: %016"PRIx64"\t", regs->rcx); + printf("rdx: %016"PRIx64"\n", regs->rdx); + + printf("rbx: %016"PRIx64"\t", regs->rbx); + printf("rsi: %016"PRIx64"\t", regs->rsi); + printf("rdi: %016"PRIx64"\n", regs->rdi); + + printf("rbp: %016"PRIx64"\t", regs->rbp); + printf(" r8: %016"PRIx64"\t", regs->r8); + printf(" r9: %016"PRIx64"\n", regs->r9); + + printf("r10: %016"PRIx64"\t", regs->r10); + printf("r11: %016"PRIx64"\t", regs->r11); + printf("r12: %016"PRIx64"\n", regs->r12); + + printf("r13: %016"PRIx64"\t", regs->r13); + printf("r14: %016"PRIx64"\t", regs->r14); + printf("r15: %016"PRIx64"\n", regs->r15); printf(" cs: %04x\t", regs->cs); printf(" ss: %04x\t", regs->ss); printf(" ds: %04x\t", regs->ds); printf(" es: %04x\n", regs->es); - printf(" fs: %04x @ %016lx\n", regs->fs, ctx1->fs_base); - printf(" gs: %04x @ %016lx/%016lx\n", regs->gs, - ctx1->gs_base_kernel, ctx1->gs_base_user); + printf(" fs: %04x @ %016"PRIx64"\n", regs->fs, ctx->fs_base); + printf(" gs: %04x @ %016"PRIx64"/%016"PRIx64"\n", regs->gs, + ctx->gs_base_kernel, ctx->gs_base_user); if (disp_all) { - print_special(ctx1->ctrlreg, "cr", 0x1d); - print_special(ctx1->debugreg, "dr", 0xcf); - } -} + print_special(ctx->ctrlreg, "cr", 0x1d, 8); + print_special(ctx->debugreg, "dr", 0xcf, 8); + } +} + +static void print_ctx(vcpu_guest_context_any_t *ctx) +{ + if (ctxt_word_size == 4) + print_ctx_32(&ctx->x32); + else + print_ctx_64(&ctx->x64); +} + +static guest_word_t instr_pointer(vcpu_guest_context_any_t *ctx) +{ + if (ctxt_word_size == 4) + return ctx->x32.user_regs.eip; + else + return ctx->x64.user_regs.rip; +} + +static guest_word_t stack_pointer(vcpu_guest_context_any_t *ctx) +{ + if (ctxt_word_size == 4) + return ctx->x32.user_regs.esp; + else + return ctx->x64.user_regs.rsp; +} + +static guest_word_t frame_pointer(vcpu_guest_context_any_t *ctx) +{ + if (ctxt_word_size == 4) + return ctx->x32.user_regs.ebp; + else + return ctx->x64.user_regs.rbp; +} + #elif defined(__ia64__) #define PTE_ED_SHIFT 52 @@ -401,9 +425,9 @@ static void print_tr(int i, const struct tr->itir >> ITIR_KEY_SHIFT & ITIR_KEY_MASK); } -void print_ctx(vcpu_guest_context_t *ctx) -{ - struct vcpu_guest_context_regs *regs = &ctx->regs; +void print_ctx(vcpu_guest_context_any_t *ctx) +{ + struct vcpu_guest_context_regs *regs = &ctx.c->regs; struct vcpu_tr_regs *tr = &ctx->regs.tr; int i; unsigned int rbs_size, cfm_sof; @@ -584,7 +608,7 @@ void print_ctx(vcpu_guest_context_t *ctx #endif #ifndef NO_TRANSLATION -static void *map_page(vcpu_guest_context_t *ctx, int vcpu, size_t virt) +static void *map_page(vcpu_guest_context_any_t *ctx, int vcpu, guest_word_t virt) { static unsigned long previous_mfn = 0; static void *mapped = NULL; @@ -611,33 +635,53 @@ static void *map_page(vcpu_guest_context return (void *)(mapped + offset); } -static void print_stack(vcpu_guest_context_t *ctx, int vcpu) -{ - struct cpu_user_regs *regs = &ctx->user_regs; - size_t stack = STACK_POINTER(regs); - size_t stack_limit = (STACK_POINTER(regs) & XC_PAGE_MASK) + XC_PAGE_SIZE; - size_t frame; - size_t instr; - size_t *p; +static guest_word_t read_stack_word(guest_word_t *src, int width) +{ + guest_word_t word = 0; + /* Little-endian only */ + memcpy(&word, src, width); + return word; +} + +static void print_stack_word(guest_word_t word, int width) +{ + if (width == 4) + printf(FMT_32B_WORD, word); + else + printf(FMT_64B_WORD, word); +} + +static void print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width) +{ + guest_word_t stack = stack_pointer(ctx); + guest_word_t stack_limit; + guest_word_t frame; + guest_word_t instr; + guest_word_t word; + guest_word_t *p; int i; + stack_limit = ((stack_pointer(ctx) + XC_PAGE_SIZE) + & ~((guest_word_t) XC_PAGE_SIZE - 1)); printf("\n"); printf("Stack:\n"); - for (i=1; i<STACK_ROWS+1 && stack < stack_limit; i++) { - while(stack < stack_limit && stack < STACK_POINTER(regs) + i*STACK_COLS*sizeof(stack)) { + for (i=1; i<5 && stack < stack_limit; i++) { + while(stack < stack_limit && stack < stack_pointer(ctx) + i*32) { p = map_page(ctx, vcpu, stack); - printf(" " FMT_SIZE_T, *p); - stack += sizeof(stack); + word = read_stack_word(p, width); + printf(" "); + print_stack_word(word, width); + stack += width; } printf("\n"); } printf("\n"); printf("Code:\n"); - instr = INSTR_POINTER(regs) - 21; + instr = instr_pointer(ctx) - 21; for(i=0; i<32; i++) { unsigned char *c = map_page(ctx, vcpu, instr+i); - if (instr+i == INSTR_POINTER(regs)) + if (instr+i == instr_pointer(ctx)) printf("<%02x> ", *c); else printf("%02x ", *c); @@ -650,52 +694,65 @@ static void print_stack(vcpu_guest_conte printf("Stack Trace:\n"); else printf("Call Trace:\n"); - printf("%c [<" FMT_SIZE_T ">] ", - stack_trace ? '*' : ' ', INSTR_POINTER(regs)); - - print_symbol(INSTR_POINTER(regs)); + printf("%c [<", stack_trace ? '*' : ' '); + print_stack_word(instr_pointer(ctx), width); + printf(">] "); + + print_symbol(instr_pointer(ctx)); printf(" <--\n"); if (frame_ptrs) { - stack = STACK_POINTER(regs); - frame = FRAME_POINTER(regs); + stack = stack_pointer(ctx); + frame = frame_pointer(ctx); while(frame && stack < stack_limit) { if (stack_trace) { while (stack < frame) { p = map_page(ctx, vcpu, stack); - printf("| " FMT_SIZE_T " ", *p); - printf("\n"); - stack += sizeof(*p); + printf("| "); + print_stack_word(read_stack_word(p, width), width); + printf(" \n"); + stack += width; } } else { stack = frame; } p = map_page(ctx, vcpu, stack); - frame = *p; - if (stack_trace) - printf("|-- " FMT_SIZE_T "\n", *p); - stack += sizeof(*p); + frame = read_stack_word(p, width); + if (stack_trace) { + printf("|-- "); + print_stack_word(read_stack_word(p, width), width); + printf("\n"); + } + stack += width; if (frame) { p = map_page(ctx, vcpu, stack); - printf("%c [<" FMT_SIZE_T ">] ", stack_trace ? '|' : ' ', *p); - print_symbol(*p); + word = read_stack_word(p, width); + printf("%c [<", stack_trace ? '|' : ' '); + print_stack_word(word, width); + printf(">] "); + print_symbol(word); printf("\n"); - stack += sizeof(*p); + stack += width; } } } else { - stack = STACK_POINTER(regs); + stack = stack_pointer(ctx); while(stack < stack_limit) { p = map_page(ctx, vcpu, stack); - if (is_kernel_text(*p)) { - printf(" [<" FMT_SIZE_T ">] ", *p); - print_symbol(*p); + word = read_stack_word(p, width); + if (is_kernel_text(word)) { + printf(" [<"); + print_stack_word(word, width); + printf(">] "); + print_symbol(word); printf("\n"); } else if (stack_trace) { - printf(" " FMT_SIZE_T "\n", *p); + printf(" "); + print_stack_word(word, width); + printf("\n"); } - stack += sizeof(*p); + stack += width; } } } @@ -729,10 +786,33 @@ static void dump_ctx(int vcpu) exit(-1); } - print_ctx(&ctx.c); +#if defined(__i386__) || defined(__x86_64__) + { + struct xen_domctl domctl; + memset(&domctl, 0, sizeof domctl); + domctl.domain = domid; + domctl.cmd = XEN_DOMCTL_get_address_size; + if (xc_domctl(xc_handle, &domctl) == 0) + ctxt_word_size = guest_word_size = domctl.u.address_size.size / 8; + if (dominfo.hvm) { + xen_capabilities_info_t xen_caps = ""; + if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) { + perror("xc_version"); + exit(-1); + } + /* HVM guest context records are always host-sized */ + ctxt_word_size = (strstr(xen_caps, "xen-3.0-x86_64")) ? 8 : 4; + /* XXX For now we can't tell whether a HVM guest is in long + * XXX mode; eventually fix this here and in xc_pagetab.c */ + guest_word_size = 4; + } + } +#endif + + print_ctx(&ctx); #ifndef NO_TRANSLATION - if (is_kernel_text(INSTR_POINTER((&ctx.c.user_regs)))) - print_stack(&ctx.c, vcpu); + if (is_kernel_text(instr_pointer(&ctx))) + print_stack(&ctx, vcpu, guest_word_size); #endif if (!dominfo.paused) { @@ -774,9 +854,9 @@ int main(int argc, char **argv) int main(int argc, char **argv) { int ch; - static const char *sopts = "fs:h" + static const char *sopts = "fs:ha" #ifdef __ia64__ - "ar:" + "r:" #endif ; static const struct option lopts[] = { diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/ia64/xen/cpufreq/cpufreq.c --- a/xen/arch/ia64/xen/cpufreq/cpufreq.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/ia64/xen/cpufreq/cpufreq.c Wed Jan 07 12:20:18 2009 +0900 @@ -226,7 +226,8 @@ acpi_cpufreq_cpu_init (struct cpufreq_po data->acpi_data->states[i].transition_latency * 1000; } } - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + + policy->governor = cpufreq_opt_governor ? : CPUFREQ_DEFAULT_GOVERNOR; policy->cur = acpi_cpufreq_get(policy->cpu); printk(KERN_INFO "Current freq of CPU %u is %u\n", cpu, policy->cur); diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/x86/acpi/cpufreq/cpufreq.c --- a/xen/arch/x86/acpi/cpufreq/cpufreq.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c Wed Jan 07 12:20:18 2009 +0900 @@ -393,8 +393,10 @@ static int acpi_cpufreq_target(struct cp drv_write(&cmd); - if (!check_freqs(cmd.mask, freqs.new, data)) + if (!check_freqs(cmd.mask, freqs.new, data)) { + printk(KERN_WARNING "Fail transfer to new freq %d\n", freqs.new); return -EAGAIN; + } for_each_cpu_mask(j, online_policy_cpus) cpufreq_statistic_update(j, perf->state, next_perf_state); @@ -508,7 +510,8 @@ acpi_cpufreq_cpu_init(struct cpufreq_pol policy->cpuinfo.transition_latency = perf->states[i].transition_latency * 1000; } - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + + policy->governor = cpufreq_opt_governor ? : CPUFREQ_DEFAULT_GOVERNOR; data->max_freq = perf->states[0].core_frequency * 1000; /* table init */ diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/x86/cpu/mcheck/mce_intel.c --- a/xen/arch/x86/cpu/mcheck/mce_intel.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c Wed Jan 07 12:20:18 2009 +0900 @@ -158,8 +158,9 @@ static inline void intel_get_extended_ms * It will generate a new mc_info item if found CE/UC errors. DOM0 is the * consumer. */ -static int machine_check_poll(struct mc_info *mi, int calltype) -{ +static struct mc_info *machine_check_poll(int calltype) +{ + struct mc_info *mi = NULL; int exceptions = (read_cr4() & X86_CR4_MCE); int i, nr_unit = 0, uc = 0, pcc = 0; uint64_t status, addr; @@ -169,12 +170,6 @@ static int machine_check_poll(struct mc_ struct domain *d; cpu = smp_processor_id(); - - if (!mi) { - printk(KERN_ERR "mcheck_poll: Failed to get mc_info entry\n"); - return 0; - } - x86_mcinfo_clear(mi); memset(&mcg, 0, sizeof(mcg)); mcg.common.type = MC_TYPE_GLOBAL; @@ -217,6 +212,14 @@ static int machine_check_poll(struct mc_ if (status & MCi_STATUS_PCC) pcc = 1; + if (!mi) { + mi = x86_mcinfo_getptr(); + if (!mi) { + printk(KERN_ERR "mcheck_poll: Failed to get mc_info entry\n"); + return NULL; + } + x86_mcinfo_clear(mi); + } memset(&mcb, 0, sizeof(mcb)); mcb.common.type = MC_TYPE_BANK; mcb.common.size = sizeof(mcb); @@ -262,7 +265,7 @@ static int machine_check_poll(struct mc_ if (nr_unit) x86_mcinfo_add(mi, &mcg); /*Clear global state*/ - return nr_unit; + return mi; } static fastcall void intel_machine_check(struct cpu_user_regs * regs, long error_code) @@ -358,6 +361,12 @@ static int do_cmci_discover(int i) return 0; } set_bit(i, __get_cpu_var(mce_banks_owned)); + /* Clear Corected Error Counter field, make sure CMCI could + * be triggered on the new owner + */ + msr = MSR_IA32_MC0_STATUS + 4 * i; + rdmsrl(msr, val); + wrmsrl(msr, val & ~MCi_STATUS_ERRCOUNT); out: clear_bit(i, __get_cpu_var(no_cmci_banks)); return 1; @@ -472,15 +481,14 @@ static void intel_init_cmci(struct cpuin fastcall void smp_cmci_interrupt(struct cpu_user_regs *regs) { - int nr_unit; - struct mc_info *mi = x86_mcinfo_getptr(); + struct mc_info *mi = NULL; int cpu = smp_processor_id(); ack_APIC_irq(); irq_enter(); printk(KERN_DEBUG "CMCI: cmci_intr happen on CPU%d\n", cpu); - nr_unit = machine_check_poll(mi, MC_FLAG_CMCI); - if (nr_unit) { + mi = machine_check_poll(MC_FLAG_CMCI); + if (mi) { x86_mcinfo_dump(mi); if (dom0 && guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) send_guest_global_virq(dom0, VIRQ_MCA); @@ -526,16 +534,16 @@ static void mce_init(void) static void mce_init(void) { u32 l, h; - int i, nr_unit; - struct mc_info *mi = x86_mcinfo_getptr(); + int i; + struct mc_info *mi; clear_in_cr4(X86_CR4_MCE); /* log the machine checks left over from the previous reset. * This also clears all registers*/ - nr_unit = machine_check_poll(mi, MC_FLAG_RESET); + mi = machine_check_poll(MC_FLAG_RESET); /*in the boot up stage, not expect inject to DOM0, but go print out */ - if (nr_unit > 0) + if (mi) x86_mcinfo_dump(mi); set_in_cr4(X86_CR4_MCE); @@ -589,13 +597,12 @@ static int adjust = 0; static void mce_intel_checkregs(void *info) { - int nr_unit; - struct mc_info *mi = x86_mcinfo_getptr(); + struct mc_info *mi; if( !mce_available(¤t_cpu_data)) return; - nr_unit = machine_check_poll(mi, MC_FLAG_POLLED); - if (nr_unit) + mi = machine_check_poll(MC_FLAG_POLLED); + if (mi) { x86_mcinfo_dump(mi); adjust++; diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/x86/cpu/mcheck/x86_mca.h --- a/xen/arch/x86/cpu/mcheck/x86_mca.h Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/x86/cpu/mcheck/x86_mca.h Wed Jan 07 12:20:18 2009 +0900 @@ -46,6 +46,8 @@ #define MCi_STATUS_MSEC 0x00000000ffff0000ULL /* Other information */ #define MCi_STATUS_OTHER 0x01ffffff00000000ULL +/*Corrected Error Count*/ +#define MCi_STATUS_ERRCOUNT 0x001FFFC0000000000ULL /* processor context corrupt */ #define MCi_STATUS_PCC 0x0200000000000000ULL /* MSR_K8_MCi_ADDR register valid */ diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/x86/domain.c Wed Jan 07 12:20:18 2009 +0900 @@ -149,6 +149,11 @@ void dump_pageframe_info(struct domain * } } + if ( is_hvm_domain(d) ) + { + p2m_pod_dump_data(d); + } + list_for_each_entry ( page, &d->xenpage_list, list ) { printk(" XenPage %p: caf=%08x, taf=%" PRtype_info "\n", diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/x86/hvm/svm/svm.c Wed Jan 07 12:20:18 2009 +0900 @@ -888,7 +888,7 @@ static void svm_do_nested_pgfault(paddr_ * If this GFN is emulated MMIO or marked as read-only, pass the fault * to the mmio handler. */ - mfn = gfn_to_mfn_current(gfn, &p2mt); + mfn = gfn_to_mfn_type_current(gfn, &p2mt, p2m_guest); if ( (p2mt == p2m_mmio_dm) || (p2mt == p2m_ram_ro) ) { if ( !handle_mmio() ) diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/x86/hvm/viridian.c --- a/xen/arch/x86/hvm/viridian.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/x86/hvm/viridian.c Wed Jan 07 12:20:18 2009 +0900 @@ -37,6 +37,7 @@ /* Viridian CPUID 4000004, Implementation Recommendations. */ #define CPUID4A_MSR_BASED_APIC (1 << 3) +#define CPUID4A_RELAX_TIMER_INT (1 << 5) int cpuid_viridian_leaves(unsigned int leaf, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, @@ -84,7 +85,8 @@ int cpuid_viridian_leaves(unsigned int l if ( (d->arch.hvm_domain.viridian.guest_os_id.raw == 0) || (d->arch.hvm_domain.viridian.guest_os_id.fields.os < 4) ) break; - *eax = CPUID4A_MSR_BASED_APIC; + *eax = (CPUID4A_MSR_BASED_APIC | + CPUID4A_RELAX_TIMER_INT); *ebx = 2047; /* long spin count */ break; } diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Wed Jan 07 12:20:18 2009 +0900 @@ -55,6 +55,25 @@ static DEFINE_PER_CPU(struct list_head, static u32 vmcs_revision_id __read_mostly; +static void __init vmx_display_features(void) +{ + int printed = 0; + + printk("VMX: Supported advanced features:\n"); + +#define P(p,s) if ( p ) { printk(" - %s\n", s); printed = 1; } + P(cpu_has_vmx_virtualize_apic_accesses, "APIC MMIO access virtualisation"); + P(cpu_has_vmx_tpr_shadow, "APIC TPR shadow"); + P(cpu_has_vmx_ept, "Extended Page Tables (EPT)"); + P(cpu_has_vmx_vpid, "Virtual-Processor Identifiers (VPID)"); + P(cpu_has_vmx_vnmi, "Virtual NMI"); + P(cpu_has_vmx_msr_bitmap, "MSR direct-access bitmap"); +#undef P + + if ( !printed ) + printk(" - none\n"); +} + static u32 adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, u32 msr) { u32 vmx_msr_low, vmx_msr_high, ctl = ctl_min | ctl_opt; @@ -169,6 +188,7 @@ static void vmx_init_vmcs_config(void) vmx_vmexit_control = _vmx_vmexit_control; vmx_vmentry_control = _vmx_vmentry_control; cpu_has_vmx_ins_outs_instr_info = !!(vmx_basic_msr_high & (1U<<22)); + vmx_display_features(); } else { diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/x86/hvm/vmx/vmx.c Wed Jan 07 12:20:18 2009 +0900 @@ -1314,8 +1314,29 @@ static void vmx_set_uc_mode(struct vcpu static void vmx_set_info_guest(struct vcpu *v) { + unsigned long intr_shadow; + vmx_vmcs_enter(v); + __vmwrite(GUEST_DR7, v->arch.guest_context.debugreg[7]); + + /* + * If the interruptibility-state field indicates blocking by STI, + * setting the TF flag in the EFLAGS may cause VM entry to fail + * and crash the guest. See SDM 3B 22.3.1.5. + * Resetting the VMX_INTR_SHADOW_STI flag looks hackish but + * to set the GUEST_PENDING_DBG_EXCEPTIONS.BS here incurs + * immediately vmexit and hence make no progress. + */ + intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO); + if ( v->domain->debugger_attached && + (v->arch.guest_context.user_regs.eflags & X86_EFLAGS_TF) && + (intr_shadow & VMX_INTR_SHADOW_STI) ) + { + intr_shadow &= ~VMX_INTR_SHADOW_STI; + __vmwrite(GUEST_INTERRUPTIBILITY_INFO, intr_shadow); + } + vmx_vmcs_exit(v); } @@ -2103,9 +2124,9 @@ static void ept_handle_violation(unsigne mfn_t mfn; p2m_type_t t; - mfn = gfn_to_mfn(d, gfn, &t); - - /* There are two legitimate reasons for taking an EPT violation. + mfn = gfn_to_mfn_guest(d, gfn, &t); + + /* There are three legitimate reasons for taking an EPT violation. * One is a guest access to MMIO space. */ if ( gla_validity == EPT_GLA_VALIDITY_MATCH && p2m_is_mmio(t) ) { @@ -2113,15 +2134,18 @@ static void ept_handle_violation(unsigne return; } - /* The other is log-dirty mode, writing to a read-only page */ - if ( paging_mode_log_dirty(d) - && (gla_validity == EPT_GLA_VALIDITY_MATCH - || gla_validity == EPT_GLA_VALIDITY_GPT_WALK) + /* The second is log-dirty mode, writing to a read-only page; + * The third is populating a populate-on-demand page. */ + if ( (gla_validity == EPT_GLA_VALIDITY_MATCH + || gla_validity == EPT_GLA_VALIDITY_GPT_WALK) && p2m_is_ram(t) && (t != p2m_ram_ro) ) { - paging_mark_dirty(d, mfn_x(mfn)); - p2m_change_type(d, gfn, p2m_ram_logdirty, p2m_ram_rw); - flush_tlb_mask(d->domain_dirty_cpumask); + if ( paging_mode_log_dirty(d) ) + { + paging_mark_dirty(d, mfn_x(mfn)); + p2m_change_type(d, gfn, p2m_ram_logdirty, p2m_ram_rw); + flush_tlb_mask(d->domain_dirty_cpumask); + } return; } diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/x86/irq.c --- a/xen/arch/x86/irq.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/x86/irq.c Wed Jan 07 12:20:18 2009 +0900 @@ -853,6 +853,10 @@ int map_domain_pirq( ASSERT(spin_is_locked(&pcidevs_lock)); ASSERT(spin_is_locked(&d->event_lock)); + /* XXX Until pcidev and msi locking is fixed. */ + if ( type == MAP_PIRQ_TYPE_MSI ) + return -EINVAL; + if ( !IS_PRIV(current->domain) ) return -EPERM; diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/x86/mm.c Wed Jan 07 12:20:18 2009 +0900 @@ -3976,6 +3976,49 @@ long arch_memory_op(int op, XEN_GUEST_HA return 0; } + case XENMEM_set_pod_target: + case XENMEM_get_pod_target: + { + xen_pod_target_t target; + struct domain *d; + + /* Support DOMID_SELF? */ + if ( !IS_PRIV(current->domain) ) + return -EINVAL; + + if ( copy_from_guest(&target, arg, 1) ) + return -EFAULT; + + rc = rcu_lock_target_domain_by_id(target.domid, &d); + if ( rc != 0 ) + return rc; + + if ( op == XENMEM_set_pod_target ) + { + if ( target.target_pages > d->max_pages ) + { + rc = -EINVAL; + goto pod_target_out_unlock; + } + + rc = p2m_pod_set_mem_target(d, target.target_pages); + } + + target.tot_pages = d->tot_pages; + target.pod_cache_pages = d->arch.p2m->pod.count; + target.pod_entries = d->arch.p2m->pod.entry_count; + + if ( copy_to_guest(arg, &target, 1) ) + { + rc= -EFAULT; + goto pod_target_out_unlock; + } + + pod_target_out_unlock: + rcu_unlock_domain(d); + return rc; + } + default: return subarch_memory_op(op, arg); } diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/x86/mm/hap/p2m-ept.c --- a/xen/arch/x86/mm/hap/p2m-ept.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/x86/mm/hap/p2m-ept.c Wed Jan 07 12:20:18 2009 +0900 @@ -274,7 +274,8 @@ out: } /* Read ept p2m entries */ -static mfn_t ept_get_entry(struct domain *d, unsigned long gfn, p2m_type_t *t) +static mfn_t ept_get_entry(struct domain *d, unsigned long gfn, p2m_type_t *t, + p2m_query_t q) { ept_entry_t *table = map_domain_page(mfn_x(pagetable_get_mfn(d->arch.phys_table))); @@ -359,9 +360,10 @@ static uint64_t ept_get_entry_content(st return content; } -static mfn_t ept_get_entry_current(unsigned long gfn, p2m_type_t *t) -{ - return ept_get_entry(current->domain, gfn, t); +static mfn_t ept_get_entry_current(unsigned long gfn, p2m_type_t *t, + p2m_query_t q) +{ + return ept_get_entry(current->domain, gfn, t, q); } void ept_change_entry_emt_with_range(struct domain *d, unsigned long start_gfn, diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/x86/mm/p2m.c --- a/xen/arch/x86/mm/p2m.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/x86/mm/p2m.c Wed Jan 07 12:20:18 2009 +0900 @@ -118,9 +118,16 @@ static unsigned long p2m_type_to_flags(p return flags; case p2m_mmio_direct: return flags | P2M_BASE_FLAGS | _PAGE_RW | _PAGE_PCD; - } -} - + case p2m_populate_on_demand: + return flags; + } +} + +#if P2M_AUDIT +static void audit_p2m(struct domain *d); +#else +# define audit_p2m(_d) do { (void)(_d); } while(0) +#endif /* P2M_AUDIT */ // Find the next level's P2M entry, checking for out-of-range gfn's... // Returns NULL on error. @@ -162,7 +169,8 @@ p2m_next_level(struct domain *d, mfn_t * shift, max)) ) return 0; - if ( !(l1e_get_flags(*p2m_entry) & _PAGE_PRESENT) ) + /* PoD: Not present doesn't imply empty. */ + if ( !l1e_get_flags(*p2m_entry) ) { struct page_info *pg = d->arch.p2m->alloc_page(d); if ( pg == NULL ) @@ -197,7 +205,7 @@ p2m_next_level(struct domain *d, mfn_t * } } - ASSERT(l1e_get_flags(*p2m_entry) & _PAGE_PRESENT); + ASSERT(l1e_get_flags(*p2m_entry) & (_PAGE_PRESENT|_PAGE_PSE)); /* split single large page into 4KB page in P2M table */ if ( type == PGT_l1_page_table && (l1e_get_flags(*p2m_entry) & _PAGE_PSE) ) @@ -240,6 +248,861 @@ p2m_next_level(struct domain *d, mfn_t * *table = next; return 1; +} + +/* + * Populate-on-demand functionality + */ +static +int set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn, + unsigned int page_order, p2m_type_t p2mt); + +int +p2m_pod_cache_add(struct domain *d, + struct page_info *page, + unsigned long order) +{ + int i; + struct page_info *p; + struct p2m_domain *p2md = d->arch.p2m; + +#ifndef NDEBUG + mfn_t mfn; + + mfn = page_to_mfn(page); + + /* Check to make sure this is a contiguous region */ + if( mfn_x(mfn) & ((1 << order) - 1) ) + { + printk("%s: mfn %lx not aligned order %lu! (mask %lx)\n", + __func__, mfn_x(mfn), order, ((1UL << order) - 1)); + return -1; + } + + for(i=0; i < 1 << order ; i++) { + struct domain * od; + + p = mfn_to_page(_mfn(mfn_x(mfn) + i)); + od = page_get_owner(p); + if(od != d) + { + printk("%s: mfn %lx expected owner d%d, got owner d%d!\n", + __func__, mfn_x(mfn), d->domain_id, + od?od->domain_id:-1); + return -1; + } + } +#endif + + spin_lock(&d->page_alloc_lock); + + /* First, take all pages off the domain list */ + for(i=0; i < 1 << order ; i++) + { + p = page + i; + list_del(&p->list); + } + + /* Then add the first one to the appropriate populate-on-demand list */ + switch(order) + { + case 9: + list_add_tail(&page->list, &p2md->pod.super); /* lock: page_alloc */ + p2md->pod.count += 1 << order; + break; + case 0: + list_add_tail(&page->list, &p2md->pod.single); /* lock: page_alloc */ + p2md->pod.count += 1 ; + break; + default: + BUG(); + } + + spin_unlock(&d->page_alloc_lock); + + return 0; +} + +/* Get a page of size order from the populate-on-demand cache. Will break + * down 2-meg pages into singleton pages automatically. Returns null if + * a superpage is requested and no superpages are available. Must be called + * with the d->page_lock held. */ +static struct page_info * p2m_pod_cache_get(struct domain *d, + unsigned long order) +{ + struct p2m_domain *p2md = d->arch.p2m; + struct page_info *p = NULL; + int i; + + if ( order == 9 && list_empty(&p2md->pod.super) ) + { + return NULL; + } + else if ( order == 0 && list_empty(&p2md->pod.single) ) + { + unsigned long mfn; + struct page_info *q; + + BUG_ON( list_empty(&p2md->pod.super) ); + + /* Break up a superpage to make single pages. NB count doesn't + * need to be adjusted. */ + printk("%s: Breaking up superpage.\n", __func__); + p = list_entry(p2md->pod.super.next, struct page_info, list); + list_del(&p->list); + mfn = mfn_x(page_to_mfn(p)); + + for ( i=0; i<(1<<9); i++ ) + { + q = mfn_to_page(_mfn(mfn+i)); + list_add_tail(&q->list, &p2md->pod.single); + } + } + + switch ( order ) + { + case 9: + BUG_ON( list_empty(&p2md->pod.super) ); + p = list_entry(p2md->pod.super.next, struct page_info, list); + p2md->pod.count -= 1 << order; /* Lock: page_alloc */ + break; + case 0: + BUG_ON( list_empty(&p2md->pod.single) ); + p = list_entry(p2md->pod.single.next, struct page_info, list); + p2md->pod.count -= 1; + break; + default: + BUG(); + } + + list_del(&p->list); + + /* Put the pages back on the domain page_list */ + for ( i = 0 ; i < (1 << order) ; i++ ) + { + BUG_ON(page_get_owner(p + i) != d); + list_add_tail(&p[i].list, &d->page_list); + } + + return p; +} + +/* Set the size of the cache, allocating or freeing as necessary. */ +static int +p2m_pod_set_cache_target(struct domain *d, unsigned long pod_target) +{ + struct p2m_domain *p2md = d->arch.p2m; + int ret = 0; + + /* Increasing the target */ + while ( pod_target > p2md->pod.count ) + { + struct page_info * page; + int order; + + if ( (pod_target - p2md->pod.count) >= (1>>9) ) + order = 9; + else + order = 0; + + page = alloc_domheap_pages(d, order, 0); + if ( unlikely(page == NULL) ) + goto out; + + p2m_pod_cache_add(d, page, order); + } + + /* Decreasing the target */ + /* We hold the p2m lock here, so we don't need to worry about + * cache disappearing under our feet. */ + while ( pod_target < p2md->pod.count ) + { + struct page_info * page; + int order, i; + + /* Grab the lock before checking that pod.super is empty, or the last + * entries may disappear before we grab the lock. */ + spin_lock(&d->page_alloc_lock); + + if ( (p2md->pod.count - pod_target) > (1>>9) + && !list_empty(&p2md->pod.super) ) + order = 9; + else + order = 0; + + page = p2m_pod_cache_get(d, order); + + ASSERT(page != NULL); + + spin_unlock(&d->page_alloc_lock); + + /* Then free them */ + for ( i = 0 ; i < (1 << order) ; i++ ) + { + /* Copied from common/memory.c:guest_remove_page() */ + if ( unlikely(!get_page(page+i, d)) ) + { + gdprintk(XENLOG_INFO, "Bad page free for domain %u\n", d->domain_id); + ret = -EINVAL; + goto out; + } + + if ( test_and_clear_bit(_PGT_pinned, &(page+i)->u.inuse.type_info) ) + put_page_and_type(page+i); + + if ( test_and_clear_bit(_PGC_allocated, &(page+i)->count_info) ) + put_page(page+i); + + put_page(page+i); + } + } + +out: + return ret; +} + +/* + * The "right behavior" here requires some careful thought. First, some + * definitions: + * + M: static_max + * + B: number of pages the balloon driver has ballooned down to. + * + P: Number of populated pages. + * + T: Old target + * + T': New target + * + * The following equations should hold: + * 0 <= P <= T <= B <= M + * d->arch.p2m->pod.entry_count == B - P + * d->tot_pages == P + d->arch.p2m->pod.count + * + * Now we have the following potential cases to cover: + * B <T': Set the PoD cache size equal to the number of outstanding PoD + * entries. The balloon driver will deflate the balloon to give back + * the remainder of the ram to the guest OS. + * T <T'<B : Increase PoD cache size. + * T'<T<=B : Here we have a choice. We can decrease the size of the cache, + * get the memory right away. However, that means every time we + * reduce the memory target we risk the guest attempting to populate the + * memory before the balloon driver has reached its new target. Safer to + * never reduce the cache size here, but only when the balloon driver frees + * PoD ranges. + * + * If there are many zero pages, we could reach the target also by doing + * zero sweeps and marking the ranges PoD; but the balloon driver will have + * to free this memory eventually anyway, so we don't actually gain that much + * by doing so. + * + * NB that the equation (B<T') may require adjustment to the cache + * size as PoD pages are freed as well; i.e., freeing a PoD-backed + * entry when pod.entry_count == pod.count requires us to reduce both + * pod.entry_count and pod.count. + */ +int +p2m_pod_set_mem_target(struct domain *d, unsigned long target) +{ + unsigned pod_target; + struct p2m_domain *p2md = d->arch.p2m; + int ret = 0; + unsigned long populated; + + /* P == B: Nothing to do. */ + if ( p2md->pod.entry_count == 0 ) + goto out; + + /* T' < B: Don't reduce the cache size; let the balloon driver + * take care of it. */ + if ( target < d->tot_pages ) + goto out; + + populated = d->tot_pages - p2md->pod.count; + + pod_target = target - populated; + + /* B < T': Set the cache size equal to # of outstanding entries, + * let the balloon driver fill in the rest. */ + if ( pod_target > p2md->pod.entry_count ) + pod_target = p2md->pod.entry_count; + + ASSERT( pod_target > p2md->pod.count ); + + ret = p2m_pod_set_cache_target(d, pod_target); + +out: + return ret; +} + +void +p2m_pod_empty_cache(struct domain *d) +{ + struct p2m_domain *p2md = d->arch.p2m; + struct list_head *q, *p; + + spin_lock(&d->page_alloc_lock); + + list_for_each_safe(p, q, &p2md->pod.super) /* lock: page_alloc */ + { + int i; + struct page_info *page; + + list_del(p); + + page = list_entry(p, struct page_info, list); + + for ( i = 0 ; i < (1 << 9) ; i++ ) + { + BUG_ON(page_get_owner(page + i) != d); + list_add_tail(&page[i].list, &d->page_list); + } + + p2md->pod.count -= 1<<9; + } + + list_for_each_safe(p, q, &p2md->pod.single) + { + struct page_info *page; + + list_del(p); + + page = list_entry(p, struct page_info, list); + + BUG_ON(page_get_owner(page) != d); + list_add_tail(&page->list, &d->page_list); + + p2md->pod.count -= 1; + } + + BUG_ON(p2md->pod.count != 0); + + spin_unlock(&d->page_alloc_lock); +} + +/* This function is needed for two reasons: + * + To properly handle clearing of PoD entries + * + To "steal back" memory being freed for the PoD cache, rather than + * releasing it. + * + * Once both of these functions have been completed, we can return and + * allow decrease_reservation() to handle everything else. + */ +int +p2m_pod_decrease_reservation(struct domain *d, + xen_pfn_t gpfn, + unsigned int order) +{ + struct p2m_domain *p2md = d->arch.p2m; + int ret=0; + int i; + + int steal_for_cache = 0; + int pod = 0, nonpod = 0, ram = 0; + + + /* If we don't have any outstanding PoD entries, let things take their + * course */ + if ( p2md->pod.entry_count == 0 ) + goto out; + + /* Figure out if we need to steal some freed memory for our cache */ + steal_for_cache = ( p2md->pod.entry_count > p2md->pod.count ); + + p2m_lock(p2md); + audit_p2m(d); + + /* See what's in here. */ + /* FIXME: Add contiguous; query for PSE entries? */ + for ( i=0; i<(1<<order); i++) + { + p2m_type_t t; + + gfn_to_mfn_query(d, gpfn + i, &t); + + if ( t == p2m_populate_on_demand ) + pod++; + else + { + nonpod++; + if ( p2m_is_ram(t) ) + ram++; + } + } + + /* No populate-on-demand? Don't need to steal anything? Then we're done!*/ + if(!pod && !steal_for_cache) + goto out_unlock; + + if ( !nonpod ) + { + /* All PoD: Mark the whole region invalid and tell caller + * we're done. */ + set_p2m_entry(d, gpfn, _mfn(INVALID_MFN), order, p2m_invalid); + p2md->pod.entry_count-=(1<<order); /* Lock: p2m */ + BUG_ON(p2md->pod.entry_count < 0); + ret = 1; + goto out_unlock; + } + + /* FIXME: Steal contig 2-meg regions for cache */ + + /* Process as long as: + * + There are PoD entries to handle, or + * + There is ram left, and we want to steal it + */ + for ( i=0; + i<(1<<order) && (pod>0 || (steal_for_cache && ram > 0)); + i++) + { + mfn_t mfn; + p2m_type_t t; + + mfn = gfn_to_mfn_query(d, gpfn + i, &t); + if ( t == p2m_populate_on_demand ) + { + set_p2m_entry(d, gpfn + i, _mfn(INVALID_MFN), 0, p2m_invalid); + p2md->pod.entry_count--; /* Lock: p2m */ + BUG_ON(p2md->pod.entry_count < 0); + pod--; + } + else if ( steal_for_cache && p2m_is_ram(t) ) + { + struct page_info *page; + + ASSERT(mfn_valid(mfn)); + + page = mfn_to_page(mfn); + + set_p2m_entry(d, gpfn + i, _mfn(INVALID_MFN), 0, p2m_invalid); + set_gpfn_from_mfn(mfn_x(mfn), INVALID_M2P_ENTRY); + + p2m_pod_cache_add(d, page, 0); + + steal_for_cache = ( p2md->pod.entry_count > p2md->pod.count ); + + nonpod--; + ram--; + } + } + + /* If we've reduced our "liabilities" beyond our "assets", free some */ + if ( p2md->pod.entry_count < p2md->pod.count ) + { + printk("b %d\n", p2md->pod.entry_count); + p2m_pod_set_cache_target(d, p2md->pod.entry_count); + } + + /* If there are no more non-PoD entries, tell decrease_reservation() that + * there's nothing left to do. */ + if ( nonpod == 0 ) + ret = 1; + +out_unlock: + audit_p2m(d); + p2m_unlock(p2md); + +out: + return ret; +} + +void +p2m_pod_dump_data(struct domain *d) +{ + struct p2m_domain *p2md = d->arch.p2m; + + printk(" PoD entries=%d cachesize=%d\n", + p2md->pod.entry_count, p2md->pod.count); +} + +#define superpage_aligned(_x) (((_x)&((1<<9)-1))==0) + +/* Must be called w/ p2m lock held, page_alloc lock not held */ +static int +p2m_pod_zero_check_superpage(struct domain *d, unsigned long gfn) +{ + mfn_t mfns[1<<9]; + p2m_type_t types[1<<9]; + unsigned long * map[1<<9] = { NULL }; + int ret=0, reset = 0, reset_max = 0; + int i, j; + + if ( !superpage_aligned(gfn) ) + goto out; + + /* Look up the mfns, checking to make sure they're the same mfn + * and aligned, and mapping them. */ + for ( i=0; i<(1<<9); i++ ) + { + mfns[i] = gfn_to_mfn_query(d, gfn + i, types + i); + + /* Conditions that must be met for superpage-superpage: + * + All gfns are ram types + * + All gfns have the same type + * + None of the mfns are used as pagetables + * + The first mfn is 2-meg aligned + * + All the other mfns are in sequence + */ + if ( p2m_is_ram(types[i]) + && types[i] == types[0] + && ( (mfn_to_page(mfns[i])->count_info & PGC_page_table) == 0 ) + && ( ( i == 0 && superpage_aligned(mfn_x(mfns[0])) ) + || ( i != 0 && mfn_x(mfns[i]) == mfn_x(mfns[0]) + i ) ) ) + map[i] = map_domain_page(mfn_x(mfns[i])); + else + goto out_unmap; + } + + /* Now, do a quick check to see if it may be zero before unmapping. */ + for ( i=0; i<(1<<9); i++ ) + { + /* Quick zero-check */ + for ( j=0; j<16; j++ ) + if( *(map[i]+j) != 0 ) + break; + + if ( j < 16 ) + goto out_unmap; + + } + + /* Try to remove the page, restoring old mapping if it fails. */ + reset_max = 1<<9; + set_p2m_entry(d, gfn, + _mfn(POPULATE_ON_DEMAND_MFN), 9, + p2m_populate_on_demand); + + if ( (mfn_to_page(mfns[0])->u.inuse.type_info & PGT_count_mask) != 0 ) + { + reset = 1; + goto out_reset; + } + + /* Timing here is important. We need to make sure not to reclaim + * a page which has been grant-mapped to another domain. But we + * can't grab the grant table lock, because we may be invoked from + * the grant table code! So we first remove the page from the + * p2m, then check to see if the gpfn has been granted. Once this + * gpfn is marked PoD, any future gfn_to_mfn() call will block + * waiting for the p2m lock. If we find that it has been granted, we + * simply restore the old value. + */ + if ( gnttab_is_granted(d, gfn, 9) ) + { + printk("gfn contains grant table %lx\n", gfn); + reset = 1; + goto out_reset; + } + + /* Finally, do a full zero-check */ + for ( i=0; i < (1<<9); i++ ) + { + for ( j=0; j<PAGE_SIZE/sizeof(*map[i]); j++ ) + if( *(map[i]+j) != 0 ) + { + reset = 1; + break; + } + + if ( reset ) + goto out_reset; + } + + /* Finally! We've passed all the checks, and can add the mfn superpage + * back on the PoD cache, and account for the new p2m PoD entries */ + p2m_pod_cache_add(d, mfn_to_page(mfns[0]), 9); + d->arch.p2m->pod.entry_count += (1<<9); + +out_reset: + if ( reset ) + { + if (reset_max == (1<<9) ) + set_p2m_entry(d, gfn, mfns[0], 9, types[0]); + else + for ( i=0; i<reset_max; i++) + set_p2m_entry(d, gfn + i, mfns[i], 0, types[i]); + } + +out_unmap: + for ( i=0; i<(1<<9); i++ ) + if ( map[i] ) + unmap_domain_page(map[i]); +out: + return ret; +} + +static void +p2m_pod_zero_check(struct domain *d, unsigned long *gfns, int count) +{ + mfn_t mfns[count]; + p2m_type_t types[count]; + unsigned long * map[count]; + + int i, j; + + /* First, get the gfn list, translate to mfns, and map the pages. */ + for ( i=0; i<count; i++ ) + { + mfns[i] = gfn_to_mfn_query(d, gfns[i], types + i); + /* If this is ram, and not a pagetable, map it; otherwise, + * skip. */ + if ( p2m_is_ram(types[i]) + && ( (mfn_to_page(mfns[i])->count_info & PGC_page_table) == 0 ) ) + map[i] = map_domain_page(mfn_x(mfns[i])); + else + map[i] = NULL; + } + + /* Then, go through and check for zeroed pages, removing write permission + * for those with zeroes. */ + for ( i=0; i<count; i++ ) + { + if(!map[i]) + continue; + + /* Quick zero-check */ + for ( j=0; j<16; j++ ) + if( *(map[i]+j) != 0 ) + break; + + if ( j < 16 ) + { + unmap_domain_page(map[i]); + map[i] = NULL; + continue; + } + + /* Try to remove the page, restoring old mapping if it fails. */ + set_p2m_entry(d, gfns[i], + _mfn(POPULATE_ON_DEMAND_MFN), 0, + p2m_populate_on_demand); + + if ( (mfn_to_page(mfns[i])->u.inuse.type_info & PGT_count_mask) != 0 ) + { + unmap_domain_page(map[i]); + map[i] = NULL; + + set_p2m_entry(d, gfns[i], mfns[i], 0, types[i]); + + continue; + } + } + + /* Now check each page for real */ + for ( i=0; i < count; i++ ) + { + if(!map[i]) + continue; + + for ( j=0; j<PAGE_SIZE/sizeof(*map[i]); j++ ) + if( *(map[i]+j) != 0 ) + break; + + /* See comment in p2m_pod_zero_check_superpage() re gnttab + * check timing. */ + if ( j < PAGE_SIZE/sizeof(*map[i]) + || gnttab_is_granted(d, gfns[i], 0) ) + { + set_p2m_entry(d, gfns[i], mfns[i], 0, types[i]); + continue; + } + else + { + /* Add to cache, and account for the new p2m PoD entry */ + p2m_pod_cache_add(d, mfn_to_page(mfns[i]), 0); + d->arch.p2m->pod.entry_count++; + } + + unmap_domain_page(map[i]); + map[i] = NULL; + } + +} + +#define POD_SWEEP_LIMIT 1024 +static void +p2m_pod_emergency_sweep_super(struct domain *d) +{ + struct p2m_domain *p2md = d->arch.p2m; + unsigned long i, start, limit; + + if ( p2md->pod.reclaim_super == 0 ) + { + p2md->pod.reclaim_super = (p2md->pod.max_guest>>9)<<9; + p2md->pod.reclaim_super -= (1<<9); + } + + start = p2md->pod.reclaim_super; + limit = (start > POD_SWEEP_LIMIT) ? (start - POD_SWEEP_LIMIT) : 0; + + for ( i=p2md->pod.reclaim_super ; i > 0 ; i-=(1<<9) ) + { + p2m_pod_zero_check_superpage(d, i); + /* Stop if we're past our limit and we have found *something*. + * + * NB that this is a zero-sum game; we're increasing our cache size + * by increasing our 'debt'. Since we hold the p2m lock, + * (entry_count - count) must remain the same. */ + if ( !list_empty(&p2md->pod.super) && i < limit ) + break; + } + + p2md->pod.reclaim_super = i ? i - (1<<9) : 0; + +} + +#define POD_SWEEP_STRIDE 16 +static void +p2m_pod_emergency_sweep(struct domain *d) +{ + struct p2m_domain *p2md = d->arch.p2m; + unsigned long gfns[POD_SWEEP_STRIDE]; + unsigned long i, j=0, start, limit; + p2m_type_t t; + + + if ( p2md->pod.reclaim_single == 0 ) + p2md->pod.reclaim_single = p2md->pod.max_guest; + + start = p2md->pod.reclaim_single; + limit = (start > POD_SWEEP_LIMIT) ? (start - POD_SWEEP_LIMIT) : 0; + + /* FIXME: Figure out how to avoid superpages */ + for ( i=p2md->pod.reclaim_single ; i > 0 ; i-- ) + { + gfn_to_mfn_query(d, i, &t ); + if ( p2m_is_ram(t) ) + { + gfns[j] = i; + j++; + BUG_ON(j > POD_SWEEP_STRIDE); + if ( j == POD_SWEEP_STRIDE ) + { + p2m_pod_zero_check(d, gfns, j); + j = 0; + } + } + /* Stop if we're past our limit and we have found *something*. + * + * NB that this is a zero-sum game; we're increasing our cache size + * by re-increasing our 'debt'. Since we hold the p2m lock, + * (entry_count - count) must remain the same. */ + if ( p2md->pod.count > 0 && i < limit ) + break; + } + + if ( j ) + p2m_pod_zero_check(d, gfns, j); + + p2md->pod.reclaim_single = i ? i - 1 : i; + +} + +static int +p2m_pod_demand_populate(struct domain *d, unsigned long gfn, + mfn_t table_mfn, + l1_pgentry_t *p2m_entry, + unsigned int order, + p2m_query_t q) +{ + struct page_info *p = NULL; /* Compiler warnings */ + unsigned long gfn_aligned; + mfn_t mfn; + l1_pgentry_t entry_content = l1e_empty(); + struct p2m_domain *p2md = d->arch.p2m; + int i; + + /* We need to grab the p2m lock here and re-check the entry to make + * sure that someone else hasn't populated it for us, then hold it + * until we're done. */ + p2m_lock(p2md); + audit_p2m(d); + + /* Check to make sure this is still PoD */ + if ( p2m_flags_to_type(l1e_get_flags(*p2m_entry)) != p2m_populate_on_demand ) + { + p2m_unlock(p2md); + return 0; + } + + /* If we're low, start a sweep */ + if ( order == 9 && list_empty(&p2md->pod.super) ) + p2m_pod_emergency_sweep_super(d); + + if ( list_empty(&p2md->pod.single) && + ( ( order == 0 ) + || (order == 9 && list_empty(&p2md->pod.super) ) ) ) + p2m_pod_emergency_sweep(d); + + /* Keep track of the highest gfn demand-populated by a guest fault */ + if ( q == p2m_guest && gfn > p2md->pod.max_guest ) + p2md->pod.max_guest = gfn; + + spin_lock(&d->page_alloc_lock); + + if ( p2md->pod.count == 0 ) + goto out_of_memory; + + /* Get a page f/ the cache. A NULL return value indicates that the + * 2-meg range should be marked singleton PoD, and retried */ + if ( (p = p2m_pod_cache_get(d, order)) == NULL ) + goto remap_and_retry; + + mfn = page_to_mfn(p); + + BUG_ON((mfn_x(mfn) & ((1 << order)-1)) != 0); + + spin_unlock(&d->page_alloc_lock); + + /* Fill in the entry in the p2m */ + switch ( order ) + { + case 9: + { + l2_pgentry_t l2e_content; + + l2e_content = l2e_from_pfn(mfn_x(mfn), + p2m_type_to_flags(p2m_ram_rw) | _PAGE_PSE); + + entry_content.l1 = l2e_content.l2; + } + break; + case 0: + entry_content = l1e_from_pfn(mfn_x(mfn), + p2m_type_to_flags(p2m_ram_rw)); + break; + + } + + gfn_aligned = (gfn >> order) << order; + + paging_write_p2m_entry(d, gfn_aligned, p2m_entry, table_mfn, + entry_content, (order==9)?2:1); + + for( i = 0 ; i < (1UL << order) ; i++ ) + set_gpfn_from_mfn(mfn_x(mfn) + i, gfn_aligned + i); + + p2md->pod.entry_count -= (1 << order); /* Lock: p2m */ + BUG_ON(p2md->pod.entry_count < 0); + audit_p2m(d); + p2m_unlock(p2md); + + return 0; +out_of_memory: + spin_unlock(&d->page_alloc_lock); + audit_p2m(d); + p2m_unlock(p2md); + printk("%s: Out of populate-on-demand memory!\n", __func__); + domain_crash(d); + return -1; +remap_and_retry: + BUG_ON(order != 9); + spin_unlock(&d->page_alloc_lock); + + /* Remap this 2-meg region in singleton chunks */ + gfn_aligned = (gfn>>order)<<order; + for(i=0; i<(1<<order); i++) + set_p2m_entry(d, gfn_aligned+i, _mfn(POPULATE_ON_DEMAND_MFN), 0, + p2m_populate_on_demand); + audit_p2m(d); + p2m_unlock(p2md); + return 0; } // Returns 0 on error (out of memory) @@ -303,6 +1166,7 @@ p2m_set_entry(struct domain *d, unsigned L2_PAGETABLE_ENTRIES); ASSERT(p2m_entry); + /* FIXME: Deal with 4k replaced by 2meg pages */ if ( (l1e_get_flags(*p2m_entry) & _PAGE_PRESENT) && !(l1e_get_flags(*p2m_entry) & _PAGE_PSE) ) { @@ -311,7 +1175,7 @@ p2m_set_entry(struct domain *d, unsigned goto out; } - if ( mfn_valid(mfn) ) + if ( mfn_valid(mfn) || p2m_is_magic(p2mt) ) l2e_content = l2e_from_pfn(mfn_x(mfn), p2m_type_to_flags(p2mt) | _PAGE_PSE); else @@ -345,7 +1209,8 @@ p2m_set_entry(struct domain *d, unsigned } static mfn_t -p2m_gfn_to_mfn(struct domain *d, unsigned long gfn, p2m_type_t *t) +p2m_gfn_to_mfn(struct domain *d, unsigned long gfn, p2m_type_t *t, + p2m_query_t q) { mfn_t mfn; paddr_t addr = ((paddr_t)gfn) << PAGE_SHIFT; @@ -402,8 +1267,21 @@ p2m_gfn_to_mfn(struct domain *d, unsigne l2e = map_domain_page(mfn_x(mfn)); l2e += l2_table_offset(addr); + +pod_retry_l2: if ( (l2e_get_flags(*l2e) & _PAGE_PRESENT) == 0 ) { + /* PoD: Try to populate a 2-meg chunk */ + if ( p2m_flags_to_type(l2e_get_flags(*l2e)) == p2m_populate_on_demand ) + { + if ( q != p2m_query ) { + if( !p2m_pod_demand_populate(d, gfn, mfn, + (l1_pgentry_t *)l2e, 9, q) ) + goto pod_retry_l2; + } else + *t = p2m_populate_on_demand; + } + unmap_domain_page(l2e); return _mfn(INVALID_MFN); } @@ -422,8 +1300,20 @@ p2m_gfn_to_mfn(struct domain *d, unsigne l1e = map_domain_page(mfn_x(mfn)); l1e += l1_table_offset(addr); +pod_retry_l1: if ( (l1e_get_flags(*l1e) & _PAGE_PRESENT) == 0 ) { + /* PoD: Try to populate */ + if ( p2m_flags_to_type(l1e_get_flags(*l1e)) == p2m_populate_on_demand ) + { + if ( q != p2m_query ) { + if( !p2m_pod_demand_populate(d, gfn, mfn, + (l1_pgentry_t *)l1e, 0, q) ) + goto pod_retry_l1; + } else + *t = p2m_populate_on_demand; + } + unmap_domain_page(l1e); return _mfn(INVALID_MFN); } @@ -436,7 +1326,8 @@ p2m_gfn_to_mfn(struct domain *d, unsigne } /* Read the current domain's p2m table (through the linear mapping). */ -static mfn_t p2m_gfn_to_mfn_current(unsigned long gfn, p2m_type_t *t) +static mfn_t p2m_gfn_to_mfn_current(unsigned long gfn, p2m_type_t *t, + p2m_query_t q) { mfn_t mfn = _mfn(INVALID_MFN); p2m_type_t p2mt = p2m_mmio_dm; @@ -448,48 +1339,114 @@ static mfn_t p2m_gfn_to_mfn_current(unsi if ( gfn <= current->domain->arch.p2m->max_mapped_pfn ) { - l1_pgentry_t l1e = l1e_empty(); + l1_pgentry_t l1e = l1e_empty(), *p2m_entry; l2_pgentry_t l2e = l2e_empty(); int ret; ASSERT(gfn < (RO_MPT_VIRT_END - RO_MPT_VIRT_START) / sizeof(l1_pgentry_t)); + /* + * Read & process L2 + */ + p2m_entry = &__linear_l1_table[l1_linear_offset(RO_MPT_VIRT_START) + + l2_linear_offset(addr)]; + + pod_retry_l2: ret = __copy_from_user(&l2e, - &__linear_l1_table[l1_linear_offset(RO_MPT_VIRT_START) + l2_linear_offset(addr)], + p2m_entry, sizeof(l2e)); + if ( ret != 0 + || !(l2e_get_flags(l2e) & _PAGE_PRESENT) ) + { + if( (l2e_get_flags(l2e) & _PAGE_PSE) + && ( p2m_flags_to_type(l2e_get_flags(l2e)) + == p2m_populate_on_demand ) ) + { + /* The read has succeeded, so we know that the mapping + * exits at this point. */ + if ( q != p2m_query ) + { + if( !p2m_pod_demand_populate(current->domain, gfn, mfn, + p2m_entry, 9, q) ) + goto pod_retry_l2; + + /* Allocate failed. */ + p2mt = p2m_invalid; + printk("%s: Allocate failed!\n", __func__); + goto out; + } + else + { + p2mt = p2m_populate_on_demand; + goto out; + } + } + + goto pod_retry_l1; + } - if ( (ret == 0) && (l2e_get_flags(l2e) & _PAGE_PRESENT) && - (l2e_get_flags(l2e) & _PAGE_PSE) ) + if (l2e_get_flags(l2e) & _PAGE_PSE) { p2mt = p2m_flags_to_type(l2e_get_flags(l2e)); ASSERT(l2e_get_pfn(l2e) != INVALID_MFN || !p2m_is_ram(p2mt)); + if ( p2m_is_valid(p2mt) ) mfn = _mfn(l2e_get_pfn(l2e) + l1_table_offset(addr)); else p2mt = p2m_mmio_dm; - } - else - { - - /* Need to __copy_from_user because the p2m is sparse and this - * part might not exist */ - ret = __copy_from_user(&l1e, - &phys_to_machine_mapping[gfn], - sizeof(l1e)); + + goto out; + } + + /* + * Read and process L1 + */ + + /* Need to __copy_from_user because the p2m is sparse and this + * part might not exist */ + pod_retry_l1: + p2m_entry = &phys_to_machine_mapping[gfn]; + + ret = __copy_from_user(&l1e, + p2m_entry, + sizeof(l1e)); - if ( ret == 0 ) { - p2mt = p2m_flags_to_type(l1e_get_flags(l1e)); - ASSERT(l1e_get_pfn(l1e) != INVALID_MFN || !p2m_is_ram(p2mt)); - if ( p2m_is_valid(p2mt) ) - mfn = _mfn(l1e_get_pfn(l1e)); - else - /* XXX see above */ - p2mt = p2m_mmio_dm; + if ( ret == 0 ) { + p2mt = p2m_flags_to_type(l1e_get_flags(l1e)); + ASSERT(l1e_get_pfn(l1e) != INVALID_MFN || !p2m_is_ram(p2mt)); + + if ( p2m_flags_to_type(l1e_get_flags(l1e)) + == p2m_populate_on_demand ) + { + /* The read has succeeded, so we know that the mapping + * exits at this point. */ + if ( q != p2m_query ) + { + if( !p2m_pod_demand_populate(current->domain, gfn, mfn, + (l1_pgentry_t *)p2m_entry, 0, + q) ) + goto pod_retry_l1; + + /* Allocate failed. */ + p2mt = p2m_invalid; + goto out; + } + else + { + p2mt = p2m_populate_on_demand; + goto out; + } } - } - } - + + if ( p2m_is_valid(p2mt) ) + mfn = _mfn(l1e_get_pfn(l1e)); + else + /* XXX see above */ + p2mt = p2m_mmio_dm; + } + } +out: *t = p2mt; return mfn; } @@ -508,6 +1465,8 @@ int p2m_init(struct domain *d) memset(p2m, 0, sizeof(*p2m)); p2m_lock_init(p2m); INIT_LIST_HEAD(&p2m->pages); + INIT_LIST_HEAD(&p2m->pod.super); + INIT_LIST_HEAD(&p2m->pod.single); p2m->set_entry = p2m_set_entry; p2m->get_entry = p2m_gfn_to_mfn; @@ -678,6 +1637,7 @@ static void audit_p2m(struct domain *d) struct page_info *page; struct domain *od; unsigned long mfn, gfn, m2pfn, lp2mfn = 0; + int entry_count = 0; mfn_t p2mfn; unsigned long orphans_d = 0, orphans_i = 0, mpbad = 0, pmbad = 0; int test_linear; @@ -692,6 +1652,8 @@ static void audit_p2m(struct domain *d) && !pagetable_is_null(current->arch.monitor_table) ); if ( test_linear ) flush_tlb_local(); + + spin_lock(&d->page_alloc_lock); /* Audit part one: walk the domain's page allocation list, checking * the m2p entries. */ @@ -730,7 +1692,7 @@ static void audit_p2m(struct domain *d) continue; } - p2mfn = gfn_to_mfn_foreign(d, gfn, &type); + p2mfn = gfn_to_mfn_type_foreign(d, gfn, &type, p2m_query); if ( mfn_x(p2mfn) != mfn ) { mpbad++; @@ -748,7 +1710,7 @@ static void audit_p2m(struct domain *d) if ( test_linear && (gfn <= d->arch.p2m->max_mapped_pfn) ) { - lp2mfn = mfn_x(gfn_to_mfn(d, gfn, &type)); + lp2mfn = mfn_x(gfn_to_mfn_query(d, gfn, &type)); if ( lp2mfn != mfn_x(p2mfn) ) { P2M_PRINTK("linear mismatch gfn %#lx -> mfn %#lx " @@ -759,6 +1721,8 @@ static void audit_p2m(struct domain *d) // P2M_PRINTK("OK: mfn=%#lx, gfn=%#lx, p2mfn=%#lx, lp2mfn=%#lx\n", // mfn, gfn, p2mfn, lp2mfn); } + + spin_unlock(&d->page_alloc_lock); /* Audit part two: walk the domain's p2m table, checking the entries. */ if ( pagetable_get_pfn(d->arch.phys_table) != 0 ) @@ -803,6 +1767,10 @@ static void audit_p2m(struct domain *d) { if ( !(l2e_get_flags(l2e[i2]) & _PAGE_PRESENT) ) { + if ( (l2e_get_flags(l2e[i2]) & _PAGE_PSE) + && ( p2m_flags_to_type(l2e_get_flags(l2e[i2])) + == p2m_populate_on_demand ) ) + entry_count+=(1<<9); gfn += 1 << (L2_PAGETABLE_SHIFT - PAGE_SHIFT); continue; } @@ -815,7 +1783,7 @@ static void audit_p2m(struct domain *d) for ( i1 = 0; i1 < L1_PAGETABLE_ENTRIES; i1++) { m2pfn = get_gpfn_from_mfn(mfn+i1); - if ( m2pfn != (gfn + i) ) + if ( m2pfn != (gfn + i1) ) { pmbad++; P2M_PRINTK("mismatch: gfn %#lx -> mfn %#lx" @@ -833,13 +1801,20 @@ static void audit_p2m(struct domain *d) for ( i1 = 0; i1 < L1_PAGETABLE_ENTRIES; i1++, gfn++ ) { if ( !(l1e_get_flags(l1e[i1]) & _PAGE_PRESENT) ) + { + if ( p2m_flags_to_type(l1e_get_flags(l1e[i1])) + == p2m_populate_on_demand ) + entry_count++; continue; + } mfn = l1e_get_pfn(l1e[i1]); ASSERT(mfn_valid(_mfn(mfn))); m2pfn = get_gpfn_from_mfn(mfn); if ( m2pfn != gfn ) { pmbad++; + printk("mismatch: gfn %#lx -> mfn %#lx" + " -> gfn %#lx\n", gfn, mfn, m2pfn); P2M_PRINTK("mismatch: gfn %#lx -> mfn %#lx" " -> gfn %#lx\n", gfn, mfn, m2pfn); BUG(); @@ -862,6 +1837,15 @@ static void audit_p2m(struct domain *d) } + if ( entry_count != d->arch.p2m->pod.entry_count ) + { + printk("%s: refcounted entry count %d, audit count %d!\n", + __func__, + d->arch.p2m->pod.entry_count, + entry_count); + BUG(); + } + //P2M_PRINTK("p2m audit complete\n"); //if ( orphans_i | orphans_d | mpbad | pmbad ) // P2M_PRINTK("p2m audit found %lu orphans (%lu inval %lu debug)\n", @@ -870,8 +1854,6 @@ static void audit_p2m(struct domain *d) P2M_PRINTK("p2m audit found %lu odd p2m, %lu bad m2p entries\n", pmbad, mpbad); } -#else -#define audit_p2m(_d) do { (void)(_d); } while(0) #endif /* P2M_AUDIT */ @@ -909,6 +1891,77 @@ guest_physmap_remove_page(struct domain } int +guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn, + unsigned int order) +{ + struct p2m_domain *p2md = d->arch.p2m; + unsigned long i; + p2m_type_t ot; + mfn_t omfn; + int pod_count = 0; + int rc = 0; + + BUG_ON(!paging_mode_translate(d)); + +#if CONFIG_PAGING_LEVELS == 3 + /* + * 32bit PAE nested paging does not support over 4GB guest due to + * hardware translation limit. This limitation is checked by comparing + * gfn with 0xfffffUL. + */ + if ( paging_mode_hap(d) && (gfn > 0xfffffUL) ) + { + if ( !test_and_set_bool(d->arch.hvm_domain.svm.npt_4gb_warning) ) + dprintk(XENLOG_WARNING, "Dom%d failed to populate memory beyond" + " 4GB: specify 'hap=0' domain config option.\n", + d->domain_id); + return -EINVAL; + } +#endif + + p2m_lock(p2md); + audit_p2m(d); + + P2M_DEBUG("adding gfn=%#lx mfn=%#lx\n", gfn, mfn); + + /* Make sure all gpfns are unused */ + for ( i = 0; i < (1UL << order); i++ ) + { + omfn = gfn_to_mfn_query(d, gfn + i, &ot); + if ( p2m_is_ram(ot) ) + { + printk("%s: gfn_to_mfn returned type %d!\n", + __func__, ot); + rc = -EBUSY; + goto out; + } + else if ( ot == p2m_populate_on_demand ) + { + /* Count how man PoD entries we'll be replacing if successful */ + pod_count++; + } + } + + /* Now, actually do the two-way mapping */ + if ( !set_p2m_entry(d, gfn, _mfn(POPULATE_ON_DEMAND_MFN), order, + p2m_populate_on_demand) ) + rc = -EINVAL; + else + { + p2md->pod.entry_count += 1 << order; /* Lock: p2m */ + p2md->pod.entry_count -= pod_count; + BUG_ON(p2md->pod.entry_count < 0); + } + + audit_p2m(d); + p2m_unlock(p2md); + +out: + return rc; + +} + +int guest_physmap_add_entry(struct domain *d, unsigned long gfn, unsigned long mfn, unsigned int page_order, p2m_type_t t) @@ -916,6 +1969,7 @@ guest_physmap_add_entry(struct domain *d unsigned long i, ogfn; p2m_type_t ot; mfn_t omfn; + int pod_count = 0; int rc = 0; if ( !paging_mode_translate(d) ) @@ -935,11 +1989,12 @@ guest_physmap_add_entry(struct domain *d #if CONFIG_PAGING_LEVELS == 3 /* - * 32bit PAE nested paging does not support over 4GB guest due to + * 32bit AMD nested paging does not support over 4GB guest due to * hardware translation limit. This limitation is checked by comparing * gfn with 0xfffffUL. */ - if ( paging_mode_hap(d) && (gfn > 0xfffffUL) ) + if ( paging_mode_hap(d) && (gfn > 0xfffffUL) && + (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) ) { if ( !test_and_set_bool(d->arch.hvm_domain.svm.npt_4gb_warning) ) dprintk(XENLOG_WARNING, "Dom%d failed to populate memory beyond" @@ -957,11 +2012,16 @@ guest_physmap_add_entry(struct domain *d /* First, remove m->p mappings for existing p->m mappings */ for ( i = 0; i < (1UL << page_order); i++ ) { - omfn = gfn_to_mfn(d, gfn + i, &ot); + omfn = gfn_to_mfn_query(d, gfn + i, &ot); if ( p2m_is_ram(ot) ) { ASSERT(mfn_valid(omfn)); set_gpfn_from_mfn(mfn_x(omfn), INVALID_M2P_ENTRY); + } + else if ( ot == p2m_populate_on_demand ) + { + /* Count how man PoD entries we'll be replacing if successful */ + pod_count++; } } @@ -982,7 +2042,7 @@ guest_physmap_add_entry(struct domain *d * address */ P2M_DEBUG("aliased! mfn=%#lx, old gfn=%#lx, new gfn=%#lx\n", mfn + i, ogfn, gfn + i); - omfn = gfn_to_mfn(d, ogfn, &ot); + omfn = gfn_to_mfn_query(d, ogfn, &ot); if ( p2m_is_ram(ot) ) { ASSERT(mfn_valid(omfn)); @@ -1009,6 +2069,11 @@ guest_physmap_add_entry(struct domain *d if ( !set_p2m_entry(d, gfn, _mfn(INVALID_MFN), page_order, p2m_invalid) ) rc = -EINVAL; + else + { + d->arch.p2m->pod.entry_count -= pod_count; /* Lock: p2m */ + BUG_ON(d->arch.p2m->pod.entry_count < 0); + } } audit_p2m(d); @@ -1151,7 +2216,7 @@ set_mmio_p2m_entry(struct domain *d, uns if ( !paging_mode_translate(d) ) return 0; - omfn = gfn_to_mfn(d, gfn, &ot); + omfn = gfn_to_mfn_query(d, gfn, &ot); if ( p2m_is_ram(ot) ) { ASSERT(mfn_valid(omfn)); diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/x86/mm/paging.c --- a/xen/arch/x86/mm/paging.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/x86/mm/paging.c Wed Jan 07 12:20:18 2009 +0900 @@ -585,6 +585,9 @@ void paging_teardown(struct domain *d) /* clean up log dirty resources. */ paging_log_dirty_teardown(d); + + /* Move populate-on-demand cache back to domain_list for destruction */ + p2m_pod_empty_cache(d); } /* Call once all of the references to the domain have gone away */ diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/x86/mm/shadow/multi.c --- a/xen/arch/x86/mm/shadow/multi.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/x86/mm/shadow/multi.c Wed Jan 07 12:20:18 2009 +0900 @@ -2170,10 +2170,10 @@ static int validate_gl4e(struct vcpu *v, if ( guest_l4e_get_flags(new_gl4e) & _PAGE_PRESENT ) { gfn_t gl3gfn = guest_l4e_get_gfn(new_gl4e); - mfn_t gl3mfn = gfn_to_mfn(d, gl3gfn, &p2mt); + mfn_t gl3mfn = gfn_to_mfn_query(d, gl3gfn, &p2mt); if ( p2m_is_ram(p2mt) ) sl3mfn = get_shadow_status(v, gl3mfn, SH_type_l3_shadow); - else + else if ( p2mt != p2m_populate_on_demand ) result |= SHADOW_SET_ERROR; #if (SHADOW_OPTIMIZATIONS && SHOPT_OUT_OF_SYNC ) @@ -2227,10 +2227,10 @@ static int validate_gl3e(struct vcpu *v, if ( guest_l3e_get_flags(new_gl3e) & _PAGE_PRESENT ) { gfn_t gl2gfn = guest_l3e_get_gfn(new_gl3e); - mfn_t gl2mfn = gfn_to_mfn(v->domain, gl2gfn, &p2mt); + mfn_t gl2mfn = gfn_to_mfn_query(v->domain, gl2gfn, &p2mt); if ( p2m_is_ram(p2mt) ) sl2mfn = get_shadow_status(v, gl2mfn, SH_type_l2_shadow); - else + else if ( p2mt != p2m_populate_on_demand ) result |= SHADOW_SET_ERROR; #if (SHADOW_OPTIMIZATIONS && SHOPT_OUT_OF_SYNC ) @@ -2276,10 +2276,10 @@ static int validate_gl2e(struct vcpu *v, } else { - mfn_t gl1mfn = gfn_to_mfn(v->domain, gl1gfn, &p2mt); + mfn_t gl1mfn = gfn_to_mfn_query(v->domain, gl1gfn, &p2mt); if ( p2m_is_ram(p2mt) ) - sl1mfn = get_shadow_status(v, gl1mfn, SH_type_l1_shadow); - else + sl1mfn = get_shadow_status(v, gl1mfn, SH_type_l1_shadow); + else if ( p2mt != p2m_populate_on_demand ) result |= SHADOW_SET_ERROR; } } @@ -2346,7 +2346,7 @@ static int validate_gl1e(struct vcpu *v, perfc_incr(shadow_validate_gl1e_calls); gfn = guest_l1e_get_gfn(new_gl1e); - gmfn = gfn_to_mfn(v->domain, gfn, &p2mt); + gmfn = gfn_to_mfn_query(v->domain, gfn, &p2mt); l1e_propagate_from_guest(v, new_gl1e, gmfn, &new_sl1e, ft_prefetch, p2mt); result |= shadow_set_l1e(v, sl1p, new_sl1e, sl1mfn); @@ -2406,7 +2406,7 @@ void sh_resync_l1(struct vcpu *v, mfn_t shadow_l1e_t nsl1e; gfn = guest_l1e_get_gfn(gl1e); - gmfn = gfn_to_mfn(v->domain, gfn, &p2mt); + gmfn = gfn_to_mfn_query(v->domain, gfn, &p2mt); l1e_propagate_from_guest(v, gl1e, gmfn, &nsl1e, ft_prefetch, p2mt); rc |= shadow_set_l1e(v, sl1p, nsl1e, sl1mfn); @@ -2723,7 +2723,7 @@ static void sh_prefetch(struct vcpu *v, /* Look at the gfn that the l1e is pointing at */ gfn = guest_l1e_get_gfn(gl1e); - gmfn = gfn_to_mfn(v->domain, gfn, &p2mt); + gmfn = gfn_to_mfn_query(v->domain, gfn, &p2mt); /* Propagate the entry. */ l1e_propagate_from_guest(v, gl1e, gmfn, &sl1e, ft_prefetch, p2mt); @@ -3079,7 +3079,7 @@ static int sh_page_fault(struct vcpu *v, /* What mfn is the guest trying to access? */ gfn = guest_l1e_get_gfn(gw.l1e); - gmfn = gfn_to_mfn(d, gfn, &p2mt); + gmfn = gfn_to_mfn_guest(d, gfn, &p2mt); if ( shadow_mode_refcounts(d) && (!p2m_is_valid(p2mt) || (!p2m_is_mmio(p2mt) && !mfn_valid(gmfn))) ) @@ -4119,7 +4119,7 @@ sh_update_cr3(struct vcpu *v, int do_loc if ( guest_l3e_get_flags(gl3e[i]) & _PAGE_PRESENT ) { gl2gfn = guest_l3e_get_gfn(gl3e[i]); - gl2mfn = gfn_to_mfn(d, gl2gfn, &p2mt); + gl2mfn = gfn_to_mfn_query(d, gl2gfn, &p2mt); if ( p2m_is_ram(p2mt) ) flush |= sh_remove_write_access(v, gl2mfn, 2, 0); } @@ -4132,7 +4132,7 @@ sh_update_cr3(struct vcpu *v, int do_loc if ( guest_l3e_get_flags(gl3e[i]) & _PAGE_PRESENT ) { gl2gfn = guest_l3e_get_gfn(gl3e[i]); - gl2mfn = gfn_to_mfn(d, gl2gfn, &p2mt); + gl2mfn = gfn_to_mfn_query(d, gl2gfn, &p2mt); if ( p2m_is_ram(p2mt) ) sh_set_toplevel_shadow(v, i, gl2mfn, (i == 3) ? SH_type_l2h_shadow @@ -4518,7 +4518,12 @@ static mfn_t emulate_gva_to_mfn(struct v } /* Translate the GFN to an MFN */ - mfn = gfn_to_mfn(v->domain, _gfn(gfn), &p2mt); + /* PoD: query only if shadow lock is held (to avoid deadlock) */ + if ( shadow_locked_by_me(v->domain) ) + mfn = gfn_to_mfn_query(v->domain, _gfn(gfn), &p2mt); + else + mfn = gfn_to_mfn(v->domain, _gfn(gfn), &p2mt); + if ( p2mt == p2m_ram_ro ) return _mfn(READONLY_GFN); if ( !p2m_is_ram(p2mt) ) @@ -4922,7 +4927,7 @@ int sh_audit_l1_table(struct vcpu *v, mf { gfn = guest_l1e_get_gfn(*gl1e); mfn = shadow_l1e_get_mfn(*sl1e); - gmfn = gfn_to_mfn(v->domain, gfn, &p2mt); + gmfn = gfn_to_mfn_query(v->domain, gfn, &p2mt); if ( mfn_x(gmfn) != mfn_x(mfn) ) AUDIT_FAIL(1, "bad translation: gfn %" SH_PRI_gfn " --> %" PRI_mfn " != mfn %" PRI_mfn, @@ -4989,7 +4994,7 @@ int sh_audit_l2_table(struct vcpu *v, mf mfn = shadow_l2e_get_mfn(*sl2e); gmfn = (guest_l2e_get_flags(*gl2e) & _PAGE_PSE) ? get_fl1_shadow_status(v, gfn) - : get_shadow_status(v, gfn_to_mfn(v->domain, gfn, &p2mt), + : get_shadow_status(v, gfn_to_mfn_query(v->domain, gfn, &p2mt), SH_type_l1_shadow); if ( mfn_x(gmfn) != mfn_x(mfn) ) AUDIT_FAIL(2, "bad translation: gfn %" SH_PRI_gfn @@ -4997,7 +5002,7 @@ int sh_audit_l2_table(struct vcpu *v, mf " --> %" PRI_mfn " != mfn %" PRI_mfn, gfn_x(gfn), (guest_l2e_get_flags(*gl2e) & _PAGE_PSE) ? 0 - : mfn_x(gfn_to_mfn(v->domain, gfn, &p2mt)), + : mfn_x(gfn_to_mfn_query(v->domain, gfn, &p2mt)), mfn_x(gmfn), mfn_x(mfn)); } }); @@ -5036,7 +5041,7 @@ int sh_audit_l3_table(struct vcpu *v, mf { gfn = guest_l3e_get_gfn(*gl3e); mfn = shadow_l3e_get_mfn(*sl3e); - gmfn = get_shadow_status(v, gfn_to_mfn(v->domain, gfn, &p2mt), + gmfn = get_shadow_status(v, gfn_to_mfn_query(v->domain, gfn, &p2mt), ((GUEST_PAGING_LEVELS == 3 || is_pv_32on64_vcpu(v)) && !shadow_mode_external(v->domain) @@ -5083,7 +5088,7 @@ int sh_audit_l4_table(struct vcpu *v, mf { gfn = guest_l4e_get_gfn(*gl4e); mfn = shadow_l4e_get_mfn(*sl4e); - gmfn = get_shadow_status(v, gfn_to_mfn(v->domain, gfn, &p2mt), + gmfn = get_shadow_status(v, gfn_to_mfn_query(v->domain, gfn, &p2mt), SH_type_l3_shadow); if ( mfn_x(gmfn) != mfn_x(mfn) ) AUDIT_FAIL(4, "bad translation: gfn %" SH_PRI_gfn diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/x86/mm/shadow/types.h --- a/xen/arch/x86/mm/shadow/types.h Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/x86/mm/shadow/types.h Wed Jan 07 12:20:18 2009 +0900 @@ -190,6 +190,12 @@ static inline shadow_l4e_t shadow_l4e_fr shadow_l3_linear_offset(SH_LINEAR_PT_VIRT_START)); \ }) #endif + + /* Override gfn_to_mfn to work with gfn_t */ +#undef gfn_to_mfn_query +#define gfn_to_mfn_query(d, g, t) _gfn_to_mfn_type((d), gfn_x(g), (t), p2m_query) +#undef gfn_to_mfn_guest +#define gfn_to_mfn_guest(d, g, t) _gfn_to_mfn_type((d), gfn_x(g), (t), p2m_guest) /* The shadow types needed for the various levels. */ diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/x86/setup.c Wed Jan 07 12:20:18 2009 +0900 @@ -386,6 +386,7 @@ void init_done(void) extern char __init_begin[], __init_end[]; /* Free (or page-protect) the init areas. */ + memset(__init_begin, 0xcc, __init_end - __init_begin); /* int3 poison */ #ifndef MEMORY_GUARD init_xenheap_pages(__pa(__init_begin), __pa(__init_end)); #endif diff -r b8b66dc0fa1d -r 661a839a481e xen/arch/x86/x86_64/compat/mm.c --- a/xen/arch/x86/x86_64/compat/mm.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/arch/x86/x86_64/compat/mm.c Wed Jan 07 12:20:18 2009 +0900 @@ -122,6 +122,29 @@ int compat_arch_memory_op(int op, XEN_GU #define XLAT_memory_map_HNDL_buffer(_d_, _s_) ((void)0) XLAT_memory_map(&cmp, nat); #undef XLAT_memory_map_HNDL_buffer + if ( copy_to_guest(arg, &cmp, 1) ) + rc = -EFAULT; + + break; + } + + case XENMEM_set_pod_target: + case XENMEM_get_pod_target: + { + struct compat_pod_target cmp; + struct xen_pod_target *nat = (void *)COMPAT_ARG_XLAT_VIRT_BASE; + + if ( copy_from_guest(&cmp, arg, 1) ) + return -EFAULT; + + XLAT_pod_target(nat, &cmp); + + rc = arch_memory_op(op, guest_handle_from_ptr(nat, void)); + if ( rc < 0 ) + break; + + XLAT_pod_target(&cmp, nat); + if ( copy_to_guest(arg, &cmp, 1) ) rc = -EFAULT; diff -r b8b66dc0fa1d -r 661a839a481e xen/common/domain.c --- a/xen/common/domain.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/common/domain.c Wed Jan 07 12:20:18 2009 +0900 @@ -33,13 +33,16 @@ /* Linux config option: propageted to domain0 */ /* xen_processor_pmbits: xen control Cx, Px, ... */ -unsigned int xen_processor_pmbits = 0; +unsigned int xen_processor_pmbits = XEN_PROCESSOR_PM_PX; /* opt_dom0_vcpus_pin: If true, dom0 VCPUs are pinned. */ static unsigned int opt_dom0_vcpus_pin; boolean_param("dom0_vcpus_pin", opt_dom0_vcpus_pin); -enum cpufreq_controller cpufreq_controller; +/* set xen as default cpufreq */ +enum cpufreq_controller cpufreq_controller = FREQCTL_xen; +struct cpufreq_governor *cpufreq_opt_governor; + static void __init setup_cpufreq_option(char *str) { char *arg; @@ -52,18 +55,34 @@ static void __init setup_cpufreq_option( return; } + if ( !strcmp(str, "none") ) + { + xen_processor_pmbits &= ~XEN_PROCESSOR_PM_PX; + cpufreq_controller = FREQCTL_none; + return; + } + if ( (arg = strpbrk(str, ",:")) != NULL ) *arg++ = '\0'; if ( !strcmp(str, "xen") ) - { - xen_processor_pmbits |= XEN_PROCESSOR_PM_PX; - cpufreq_controller = FREQCTL_xen; if ( arg && *arg ) cpufreq_cmdline_parse(arg); - } } custom_param("cpufreq", setup_cpufreq_option); + +static void __init setup_cpufreq_gov_option(char *str) +{ + if ( !strcmp(str, "userspace") ) + cpufreq_opt_governor = &cpufreq_gov_userspace; + else if ( !strcmp(str, "performance") ) + cpufreq_opt_governor = &cpufreq_gov_performance; + else if ( !strcmp(str, "powersave") ) + cpufreq_opt_governor = &cpufreq_gov_powersave; + else if ( !strcmp(str, "ondemand") ) + cpufreq_opt_governor = &cpufreq_gov_dbs; +} +custom_param("cpufreq_governor", setup_cpufreq_gov_option); /* Protect updates/reads (resp.) of domain_list and domain_hash. */ DEFINE_SPINLOCK(domlist_update_lock); diff -r b8b66dc0fa1d -r 661a839a481e xen/common/grant_table.c --- a/xen/common/grant_table.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/common/grant_table.c Wed Jan 07 12:20:18 2009 +0900 @@ -111,6 +111,33 @@ static unsigned inline int max_nr_maptra #define active_entry(t, e) \ ((t)->active[(e)/ACGNT_PER_PAGE][(e)%ACGNT_PER_PAGE]) +/* The p2m emergency sweep code should not reclaim a frame that is currenlty + * grant mapped by another domain. That would involve checking all other + * domains grant maps, which is impractical. Instead, we check the active + * grant table for this domain to see if it's been granted. Since this + * may be called as a result of a grant table op, we can't grab the lock. */ +int +gnttab_is_granted(struct domain *d, xen_pfn_t gfn, int order) +{ + int i, found=0; + struct active_grant_entry *act; + + /* We need to compare with active grant entries to make sure that + * pinned (== currently mapped) entries don't disappear under our + * feet. */ + for ( i=0; i<nr_grant_entries(d->grant_table); i++ ) + { + act = &active_entry(d->grant_table, i); + if ( act->gfn >> order == gfn >> order ) + { + found = 1; + break; + } + } + + return found; +} + static inline int __get_maptrack_handle( struct grant_table *t) @@ -317,6 +344,7 @@ __gnttab_map_grant_ref( if ( !act->pin ) { act->domid = scombo.shorts.domid; + act->gfn = sha->frame; act->frame = gmfn_to_mfn(rd, sha->frame); } } @@ -1335,6 +1363,7 @@ __acquire_grant_for_copy( if ( !act->pin ) { act->domid = scombo.shorts.domid; + act->gfn = sha->frame; act->frame = gmfn_to_mfn(rd, sha->frame); } } diff -r b8b66dc0fa1d -r 661a839a481e xen/common/memory.c --- a/xen/common/memory.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/common/memory.c Wed Jan 07 12:20:18 2009 +0900 @@ -111,31 +111,40 @@ static void populate_physmap(struct memo if ( unlikely(__copy_from_guest_offset(&gpfn, a->extent_list, i, 1)) ) goto out; - page = alloc_domheap_pages(d, a->extent_order, a->memflags); - if ( unlikely(page == NULL) ) - { - gdprintk(XENLOG_INFO, "Could not allocate order=%d extent: " - "id=%d memflags=%x (%ld of %d)\n", - a->extent_order, d->domain_id, a->memflags, - i, a->nr_extents); - goto out; - } - - mfn = page_to_mfn(page); - guest_physmap_add_page(d, gpfn, mfn, a->extent_order); - - if ( !paging_mode_translate(d) ) - { - for ( j = 0; j < (1 << a->extent_order); j++ ) - set_gpfn_from_mfn(mfn + j, gpfn + j); - - /* Inform the domain of the new page's machine address. */ - if ( unlikely(__copy_to_guest_offset(a->extent_list, i, &mfn, 1)) ) + if ( a->memflags & MEMF_populate_on_demand ) + { + if ( guest_physmap_mark_populate_on_demand(d, gpfn, + a->extent_order) < 0 ) goto out; } - } - - out: + else + { + page = alloc_domheap_pages(d, a->extent_order, a->memflags); + if ( unlikely(page == NULL) ) + { + gdprintk(XENLOG_INFO, "Could not allocate order=%d extent: " + "id=%d memflags=%x (%ld of %d)\n", + a->extent_order, d->domain_id, a->memflags, + i, a->nr_extents); + goto out; + } + + mfn = page_to_mfn(page); + guest_physmap_add_page(d, gpfn, mfn, a->extent_order); + + if ( !paging_mode_translate(d) ) + { + for ( j = 0; j < (1 << a->extent_order); j++ ) + set_gpfn_from_mfn(mfn + j, gpfn + j); + + /* Inform the domain of the new page's machine address. */ + if ( unlikely(__copy_to_guest_offset(a->extent_list, i, &mfn, 1)) ) + goto out; + } + } + } + +out: a->nr_done = i; } @@ -191,6 +200,11 @@ static void decrease_reservation(struct if ( unlikely(__copy_from_guest_offset(&gmfn, a->extent_list, i, 1)) ) goto out; + + /* See if populate-on-demand wants to handle this */ + if ( is_hvm_domain(a->domain) + && p2m_pod_decrease_reservation(a->domain, gmfn, a->extent_order) ) + continue; for ( j = 0; j < (1 << a->extent_order); j++ ) if ( !guest_remove_page(a->domain, gmfn + j) ) @@ -522,6 +536,10 @@ long do_memory_op(unsigned long cmd, XEN args.memflags |= MEMF_node(XENMEMF_get_node(reservation.mem_flags)); + if ( op == XENMEM_populate_physmap + && (reservation.mem_flags & XENMEMF_populate_on_demand) ) + args.memflags |= MEMF_populate_on_demand; + if ( likely(reservation.domid == DOMID_SELF) ) { d = rcu_lock_current_domain(); diff -r b8b66dc0fa1d -r 661a839a481e xen/common/schedule.c --- a/xen/common/schedule.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/common/schedule.c Wed Jan 07 12:20:18 2009 +0900 @@ -119,7 +119,7 @@ void vcpu_runstate_get(struct vcpu *v, s uint64_t get_cpu_idle_time(unsigned int cpu) { - struct vcpu_runstate_info state = { .state = RUNSTATE_running }; + struct vcpu_runstate_info state; struct vcpu *v; if ( (v = idle_vcpu[cpu]) == NULL ) diff -r b8b66dc0fa1d -r 661a839a481e xen/drivers/acpi/pmstat.c --- a/xen/drivers/acpi/pmstat.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/drivers/acpi/pmstat.c Wed Jan 07 12:20:18 2009 +0900 @@ -87,33 +87,34 @@ int do_get_pm_info(struct xen_sysctl_get case PMSTAT_get_pxstat: { - uint64_t now, ct; - uint64_t total_idle_ns; - uint64_t tmp_idle_ns; + uint32_t ct; struct pm_px *pxpt = cpufreq_statistic_data[op->cpuid]; + spinlock_t *cpufreq_statistic_lock = + &per_cpu(cpufreq_statistic_lock, op->cpuid); + + spin_lock_irq(cpufreq_statistic_lock); if ( !pxpt || !pxpt->u.pt || !pxpt->u.trans_pt ) + { + spin_unlock_irq(cpufreq_statistic_lock); return -ENODATA; - - total_idle_ns = get_cpu_idle_time(op->cpuid); - tmp_idle_ns = total_idle_ns - pxpt->prev_idle_wall; - - now = NOW(); + } + pxpt->u.usable = pmpt->perf.state_count - pmpt->perf.platform_limit; - pxpt->u.pt[pxpt->u.cur].residency += now - pxpt->prev_state_wall; - pxpt->u.pt[pxpt->u.cur].residency -= tmp_idle_ns; - pxpt->prev_state_wall = now; - pxpt->prev_idle_wall = total_idle_ns; + + cpufreq_residency_update(op->cpuid, pxpt->u.cur); ct = pmpt->perf.state_count; if ( copy_to_guest(op->u.getpx.trans_pt, pxpt->u.trans_pt, ct*ct) ) { + spin_unlock_irq(cpufreq_statistic_lock); ret = -EFAULT; break; } if ( copy_to_guest(op->u.getpx.pt, pxpt->u.pt, ct) ) { + spin_unlock_irq(cpufreq_statistic_lock); ret = -EFAULT; break; } @@ -122,6 +123,8 @@ int do_get_pm_info(struct xen_sysctl_get op->u.getpx.usable = pxpt->u.usable; op->u.getpx.last = pxpt->u.last; op->u.getpx.cur = pxpt->u.cur; + + spin_unlock_irq(cpufreq_statistic_lock); break; } diff -r b8b66dc0fa1d -r 661a839a481e xen/drivers/cpufreq/cpufreq.c --- a/xen/drivers/cpufreq/cpufreq.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/drivers/cpufreq/cpufreq.c Wed Jan 07 12:20:18 2009 +0900 @@ -214,8 +214,20 @@ int cpufreq_add_cpu(unsigned int cpu) memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); policy->governor = NULL; ret = __cpufreq_set_policy(policy, &new_policy); - if (ret) - goto err2; + if (ret) { + if (new_policy.governor == CPUFREQ_DEFAULT_GOVERNOR) + /* if default governor fail, cpufreq really meet troubles */ + goto err2; + else { + /* grub option governor fail */ + /* give one more chance to default gov */ + memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); + new_policy.governor = CPUFREQ_DEFAULT_GOVERNOR; + ret = __cpufreq_set_policy(policy, &new_policy); + if (ret) + goto err2; + } + } } return 0; diff -r b8b66dc0fa1d -r 661a839a481e xen/drivers/cpufreq/cpufreq_ondemand.c --- a/xen/drivers/cpufreq/cpufreq_ondemand.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/drivers/cpufreq/cpufreq_ondemand.c Wed Jan 07 12:20:18 2009 +0900 @@ -307,11 +307,11 @@ void __init cpufreq_cmdline_parse(char * *end++ = '\0'; val = strchr(str, '='); if ( val ) - *val = '\0'; + *val++ = '\0'; if ( !strcmp(str, "rate") && val ) { - usr_sampling_rate = simple_strtoull(val, NULL, 0); + usr_sampling_rate = simple_strtoull(val, NULL, 0) * MICROSECS(1); } else if ( !strcmp(str, "threshold") && val ) { diff -r b8b66dc0fa1d -r 661a839a481e xen/drivers/cpufreq/utility.c --- a/xen/drivers/cpufreq/utility.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/drivers/cpufreq/utility.c Wed Jan 07 12:20:18 2009 +0900 @@ -36,35 +36,54 @@ struct processor_pminfo *__read_mostly p struct processor_pminfo *__read_mostly processor_pminfo[NR_CPUS]; struct cpufreq_policy *__read_mostly cpufreq_cpu_policy[NR_CPUS]; +DEFINE_PER_CPU(spinlock_t, cpufreq_statistic_lock) = SPIN_LOCK_UNLOCKED; + /********************************************************************* * Px STATISTIC INFO * *********************************************************************/ +void cpufreq_residency_update(unsigned int cpu, uint8_t state) +{ + uint64_t now, total_idle_ns; + int64_t delta; + struct pm_px *pxpt = cpufreq_statistic_data[cpu]; + + total_idle_ns = get_cpu_idle_time(cpu); + now = NOW(); + + delta = (now - pxpt->prev_state_wall) - + (total_idle_ns - pxpt->prev_idle_wall); + + if ( likely(delta >= 0) ) + pxpt->u.pt[state].residency += delta; + + pxpt->prev_state_wall = now; + pxpt->prev_idle_wall = total_idle_ns; +} + void cpufreq_statistic_update(unsigned int cpu, uint8_t from, uint8_t to) { - uint64_t now; struct pm_px *pxpt = cpufreq_statistic_data[cpu]; struct processor_pminfo *pmpt = processor_pminfo[cpu]; - uint64_t total_idle_ns; - uint64_t tmp_idle_ns; - - if ( !pxpt || !pmpt ) + spinlock_t *cpufreq_statistic_lock = + &per_cpu(cpufreq_statistic_lock, cpu); + + spin_lock_irq(cpufreq_statistic_lock); + + if ( !pxpt || !pmpt ) { + spin_unlock_irq(cpufreq_statistic_lock); return; - - now = NOW(); - total_idle_ns = get_cpu_idle_time(cpu); - tmp_idle_ns = total_idle_ns - pxpt->prev_idle_wall; + } pxpt->u.last = from; pxpt->u.cur = to; pxpt->u.pt[to].count++; - pxpt->u.pt[from].residency += now - pxpt->prev_state_wall; - pxpt->u.pt[from].residency -= tmp_idle_ns; + + cpufreq_residency_update(cpu, from); (*(pxpt->u.trans_pt + from * pmpt->perf.state_count + to))++; - pxpt->prev_state_wall = now; - pxpt->prev_idle_wall = total_idle_ns; + spin_unlock_irq(cpufreq_statistic_lock); } int cpufreq_statistic_init(unsigned int cpuid) @@ -72,24 +91,33 @@ int cpufreq_statistic_init(unsigned int uint32_t i, count; struct pm_px *pxpt = cpufreq_statistic_data[cpuid]; const struct processor_pminfo *pmpt = processor_pminfo[cpuid]; + spinlock_t *cpufreq_statistic_lock = + &per_cpu(cpufreq_statistic_lock, cpuid); if ( !pmpt ) return -EINVAL; - if ( pxpt ) + spin_lock_irq(cpufreq_statistic_lock); + + if ( pxpt ) { + spin_unlock_irq(cpufreq_statistic_lock); return 0; + } count = pmpt->perf.state_count; pxpt = xmalloc(struct pm_px); - if ( !pxpt ) + if ( !pxpt ) { + spin_unlock_irq(cpufreq_statistic_lock); return -ENOMEM; + } memset(pxpt, 0, sizeof(*pxpt)); cpufreq_statistic_data[cpuid] = pxpt; pxpt->u.trans_pt = xmalloc_array(uint64_t, count * count); if (!pxpt->u.trans_pt) { xfree(pxpt); + spin_unlock_irq(cpufreq_statistic_lock); return -ENOMEM; } @@ -97,6 +125,7 @@ int cpufreq_statistic_init(unsigned int if (!pxpt->u.pt) { xfree(pxpt->u.trans_pt); xfree(pxpt); + spin_unlock_irq(cpufreq_statistic_lock); return -ENOMEM; } @@ -112,19 +141,30 @@ int cpufreq_statistic_init(unsigned int pxpt->prev_state_wall = NOW(); pxpt->prev_idle_wall = get_cpu_idle_time(cpuid); + spin_unlock_irq(cpufreq_statistic_lock); + return 0; } void cpufreq_statistic_exit(unsigned int cpuid) { struct pm_px *pxpt = cpufreq_statistic_data[cpuid]; - - if (!pxpt) + spinlock_t *cpufreq_statistic_lock = + &per_cpu(cpufreq_statistic_lock, cpuid); + + spin_lock_irq(cpufreq_statistic_lock); + + if (!pxpt) { + spin_unlock_irq(cpufreq_statistic_lock); return; + } + xfree(pxpt->u.trans_pt); xfree(pxpt->u.pt); xfree(pxpt); cpufreq_statistic_data[cpuid] = NULL; + + spin_unlock_irq(cpufreq_statistic_lock); } void cpufreq_statistic_reset(unsigned int cpuid) @@ -132,9 +172,15 @@ void cpufreq_statistic_reset(unsigned in uint32_t i, j, count; struct pm_px *pxpt = cpufreq_statistic_data[cpuid]; const struct processor_pminfo *pmpt = processor_pminfo[cpuid]; - - if ( !pmpt || !pxpt || !pxpt->u.pt || !pxpt->u.trans_pt ) + spinlock_t *cpufreq_statistic_lock = + &per_cpu(cpufreq_statistic_lock, cpuid); + + spin_lock_irq(cpufreq_statistic_lock); + + if ( !pmpt || !pxpt || !pxpt->u.pt || !pxpt->u.trans_pt ) { + spin_unlock_irq(cpufreq_statistic_lock); return; + } count = pmpt->perf.state_count; @@ -148,6 +194,8 @@ void cpufreq_statistic_reset(unsigned in pxpt->prev_state_wall = NOW(); pxpt->prev_idle_wall = get_cpu_idle_time(cpuid); + + spin_unlock_irq(cpufreq_statistic_lock); } @@ -360,10 +408,15 @@ int __cpufreq_set_policy(struct cpufreq_ /* start new governor */ data->governor = policy->governor; if (__cpufreq_governor(data, CPUFREQ_GOV_START)) { + printk(KERN_WARNING "Fail change to %s governor\n", + data->governor->name); + /* new governor failed, so re-start old one */ if (old_gov) { data->governor = old_gov; __cpufreq_governor(data, CPUFREQ_GOV_START); + printk(KERN_WARNING "Still stay at %s governor\n", + data->governor->name); } return -EINVAL; } diff -r b8b66dc0fa1d -r 661a839a481e xen/drivers/passthrough/vtd/iommu.c --- a/xen/drivers/passthrough/vtd/iommu.c Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/drivers/passthrough/vtd/iommu.c Wed Jan 07 12:20:18 2009 +0900 @@ -1209,7 +1209,7 @@ static int domain_context_mapping(struct int ret = 0; u16 sec_bus, sub_bus; u32 type; - u8 secbus; + u8 secbus, secdevfn; drhd = acpi_find_matched_drhd_unit(bus, devfn); if ( !drhd ) @@ -1256,10 +1256,12 @@ static int domain_context_mapping(struct break; secbus = bus; + secdevfn = devfn; /* dependent devices mapping */ while ( bus2bridge[bus].map ) { secbus = bus; + secdevfn = devfn; devfn = bus2bridge[bus].devfn; bus = bus2bridge[bus].bus; ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn); @@ -1267,7 +1269,7 @@ static int domain_context_mapping(struct return ret; } - if ( secbus != bus ) + if ( (secbus != bus) && (secdevfn != 0) ) /* * The source-id for transactions on non-PCIe buses seem * to originate from devfn=0 on the secondary bus behind @@ -1333,7 +1335,7 @@ static int domain_context_unmap(struct d struct acpi_drhd_unit *drhd; int ret = 0; u32 type; - u8 secbus; + u8 secbus, secdevfn; drhd = acpi_find_matched_drhd_unit(bus, devfn); if ( !drhd ) @@ -1362,10 +1364,12 @@ static int domain_context_unmap(struct d break; secbus = bus; + secdevfn = devfn; /* dependent devices unmapping */ while ( bus2bridge[bus].map ) { secbus = bus; + secdevfn = devfn; devfn = bus2bridge[bus].devfn; bus = bus2bridge[bus].bus; ret = domain_context_unmap_one(domain, drhd->iommu, bus, devfn); @@ -1373,7 +1377,7 @@ static int domain_context_unmap(struct d return ret; } - if ( bus != secbus ) + if ( (secbus != bus) && (secdevfn != 0) ) ret = domain_context_unmap_one(domain, drhd->iommu, secbus, 0); break; diff -r b8b66dc0fa1d -r 661a839a481e xen/include/acpi/cpufreq/cpufreq.h --- a/xen/include/acpi/cpufreq/cpufreq.h Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/include/acpi/cpufreq/cpufreq.h Wed Jan 07 12:20:18 2009 +0900 @@ -11,11 +11,16 @@ * published by the Free Software Foundation. */ +#ifndef __XEN_CPUFREQ_PM_H__ +#define __XEN_CPUFREQ_PM_H__ + #include <xen/types.h> #include <xen/list.h> #include <xen/cpumask.h> #include "processor_perf.h" + +DECLARE_PER_CPU(spinlock_t, cpufreq_statistic_lock); struct cpufreq_governor; @@ -85,6 +90,7 @@ struct cpufreq_governor { struct list_head governor_list; }; +extern struct cpufreq_governor *cpufreq_opt_governor; extern struct cpufreq_governor cpufreq_gov_dbs; extern struct cpufreq_governor cpufreq_gov_userspace; extern struct cpufreq_governor cpufreq_gov_performance; @@ -93,7 +99,7 @@ extern int cpufreq_register_governor(str extern int cpufreq_register_governor(struct cpufreq_governor *governor); extern int cpufreq_unregister_governor(struct cpufreq_governor *governor); extern struct cpufreq_governor *__find_governor(const char *governor); -#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_performance +#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_userspace /* pass a target to the cpufreq driver */ extern int __cpufreq_driver_target(struct cpufreq_policy *policy, @@ -220,3 +226,4 @@ int get_cpufreq_ondemand_para(uint32_t * uint32_t *up_threshold); int write_ondemand_sampling_rate(unsigned int sampling_rate); int write_ondemand_up_threshold(unsigned int up_threshold); +#endif /* __XEN_CPUFREQ_PM_H__ */ diff -r b8b66dc0fa1d -r 661a839a481e xen/include/acpi/cpufreq/processor_perf.h --- a/xen/include/acpi/cpufreq/processor_perf.h Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/include/acpi/cpufreq/processor_perf.h Wed Jan 07 12:20:18 2009 +0900 @@ -9,6 +9,7 @@ int get_cpu_id(u8); int get_cpu_id(u8); int powernow_cpufreq_init(void); +void cpufreq_residency_update(unsigned int, uint8_t); void cpufreq_statistic_update(unsigned int, uint8_t, uint8_t); int cpufreq_statistic_init(unsigned int); void cpufreq_statistic_exit(unsigned int); @@ -18,8 +19,6 @@ int cpufreq_limit_change(unsigned int); int cpufreq_add_cpu(unsigned int); int cpufreq_del_cpu(unsigned int); - -uint64_t get_cpu_idle_time(unsigned int); struct processor_performance { uint32_t state; diff -r b8b66dc0fa1d -r 661a839a481e xen/include/asm-x86/guest_pt.h --- a/xen/include/asm-x86/guest_pt.h Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/include/asm-x86/guest_pt.h Wed Jan 07 12:20:18 2009 +0900 @@ -49,7 +49,7 @@ gfn_to_paddr(gfn_t gfn) /* Override gfn_to_mfn to work with gfn_t */ #undef gfn_to_mfn -#define gfn_to_mfn(d, g, t) _gfn_to_mfn((d), gfn_x(g), (t)) +#define gfn_to_mfn(d, g, t) _gfn_to_mfn_type((d), gfn_x(g), (t), p2m_alloc) /* Types of the guest's page tables and access functions for them */ diff -r b8b66dc0fa1d -r 661a839a481e xen/include/asm-x86/p2m.h --- a/xen/include/asm-x86/p2m.h Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/include/asm-x86/p2m.h Wed Jan 07 12:20:18 2009 +0900 @@ -64,7 +64,14 @@ typedef enum { p2m_ram_ro = 3, /* Read-only; writes are silently dropped */ p2m_mmio_dm = 4, /* Reads and write go to the device model */ p2m_mmio_direct = 5, /* Read/write mapping of genuine MMIO area */ + p2m_populate_on_demand = 6, /* Place-holder for empty memory */ } p2m_type_t; + +typedef enum { + p2m_query = 0, /* Do not populate a PoD entries */ + p2m_alloc = 1, /* Automatically populate PoD entries */ + p2m_guest = 2, /* Guest demand-fault; implies alloc */ +} p2m_query_t; /* We use bitmaps and maks to handle groups of types */ #define p2m_to_mask(_t) (1UL << (_t)) @@ -82,11 +89,19 @@ typedef enum { #define P2M_RO_TYPES (p2m_to_mask(p2m_ram_logdirty) \ | p2m_to_mask(p2m_ram_ro)) +#define P2M_MAGIC_TYPES (p2m_to_mask(p2m_populate_on_demand)) + /* Useful predicates */ #define p2m_is_ram(_t) (p2m_to_mask(_t) & P2M_RAM_TYPES) #define p2m_is_mmio(_t) (p2m_to_mask(_t) & P2M_MMIO_TYPES) #define p2m_is_readonly(_t) (p2m_to_mask(_t) & P2M_RO_TYPES) +#define p2m_is_magic(_t) (p2m_to_mask(_t) & P2M_MAGIC_TYPES) #define p2m_is_valid(_t) (p2m_to_mask(_t) & (P2M_RAM_TYPES | P2M_MMIO_TYPES)) + +/* Populate-on-demand */ +#define POPULATE_ON_DEMAND_MFN (1<<9) +#define POD_PAGE_ORDER 9 + struct p2m_domain { /* Lock that protects updates to the p2m */ @@ -105,15 +120,42 @@ struct p2m_domain { mfn_t mfn, unsigned int page_order, p2m_type_t p2mt); mfn_t (*get_entry )(struct domain *d, unsigned long gfn, - p2m_type_t *p2mt); + p2m_type_t *p2mt, + p2m_query_t q); mfn_t (*get_entry_current)(unsigned long gfn, - p2m_type_t *p2mt); + p2m_type_t *p2mt, + p2m_query_t q); void (*change_entry_type_global)(struct domain *d, p2m_type_t ot, p2m_type_t nt); /* Highest guest frame that's ever been mapped in the p2m */ unsigned long max_mapped_pfn; + + /* Populate-on-demand variables + * NB on locking. {super,single,count} are + * covered by d->page_alloc_lock, since they're almost always used in + * conjunction with that functionality. {entry_count} is covered by + * the domain p2m lock, since it's almost always used in conjunction + * with changing the p2m tables. + * + * At this point, both locks are held in two places. In both, + * the order is [p2m,page_alloc]: + * + p2m_pod_decrease_reservation() calls p2m_pod_cache_add(), + * which grabs page_alloc + * + p2m_pod_demand_populate() grabs both; the p2m lock to avoid + * double-demand-populating of pages, the page_alloc lock to + * protect moving stuff from the PoD cache to the domain page list. + */ + struct { + struct list_head super, /* List of superpages */ + single; /* Non-super lists */ + int count, /* # of pages in cache lists */ + entry_count; /* # of pages in p2m marked pod */ + unsigned reclaim_super; /* Last gpfn of a scan */ + unsigned reclaim_single; /* Last gpfn of a scan */ + unsigned max_guest; /* gpfn of max guest demand-populate */ + } pod; }; /* Extract the type from the PTE flags that store it */ @@ -123,23 +165,26 @@ static inline p2m_type_t p2m_flags_to_ty return (flags >> 9) & 0x7; } -/* Read the current domain's p2m table. */ -static inline mfn_t gfn_to_mfn_current(unsigned long gfn, p2m_type_t *t) -{ - return current->domain->arch.p2m->get_entry_current(gfn, t); -} - -/* Read another domain's P2M table, mapping pages as we go */ +/* Read the current domain's p2m table. Do not populate PoD pages. */ +static inline mfn_t gfn_to_mfn_type_current(unsigned long gfn, p2m_type_t *t, + p2m_query_t q) +{ + return current->domain->arch.p2m->get_entry_current(gfn, t, q); +} + +/* Read another domain's P2M table, mapping pages as we go. + * Do not populate PoD pages. */ static inline -mfn_t gfn_to_mfn_foreign(struct domain *d, unsigned long gfn, p2m_type_t *t) -{ - return d->arch.p2m->get_entry(d, gfn, t); +mfn_t gfn_to_mfn_type_foreign(struct domain *d, unsigned long gfn, p2m_type_t *t, + p2m_query_t q) +{ + return d->arch.p2m->get_entry(d, gfn, t, q); } /* General conversion function from gfn to mfn */ -#define gfn_to_mfn(d, g, t) _gfn_to_mfn((d), (g), (t)) -static inline mfn_t _gfn_to_mfn(struct domain *d, - unsigned long gfn, p2m_type_t *t) +static inline mfn_t _gfn_to_mfn_type(struct domain *d, + unsigned long gfn, p2m_type_t *t, + p2m_query_t q) { if ( !paging_mode_translate(d) ) { @@ -149,10 +194,17 @@ static inline mfn_t _gfn_to_mfn(struct d return _mfn(gfn); } if ( likely(current->domain == d) ) - return gfn_to_mfn_current(gfn, t); + return gfn_to_mfn_type_current(gfn, t, q); else - return gfn_to_mfn_foreign(d, gfn, t); -} + return gfn_to_mfn_type_foreign(d, gfn, t, q); +} + +#define gfn_to_mfn(d, g, t) _gfn_to_mfn_type((d), (g), (t), p2m_alloc) +#define gfn_to_mfn_query(d, g, t) _gfn_to_mfn_type((d), (g), (t), p2m_query) +#define gfn_to_mfn_guest(d, g, t) _gfn_to_mfn_type((d), (g), (t), p2m_guest) + +#define gfn_to_mfn_current(g, t) gfn_to_mfn_type_current((g), (t), p2m_alloc) +#define gfn_to_mfn_foreign(d, g, t) gfn_to_mfn_type_foreign((d), (g), (t), p2m_alloc) /* Compatibility function exporting the old untyped interface */ static inline unsigned long gmfn_to_mfn(struct domain *d, unsigned long gpfn) @@ -202,10 +254,32 @@ void p2m_teardown(struct domain *d); void p2m_teardown(struct domain *d); void p2m_final_teardown(struct domain *d); +/* Dump PoD information about the domain */ +void p2m_pod_dump_data(struct domain *d); + +/* Move all pages from the populate-on-demand cache to the domain page_list + * (usually in preparation for domain destruction) */ +void p2m_pod_empty_cache(struct domain *d); + +/* Set populate-on-demand cache size so that the total memory allocated to a + * domain matches target */ +int p2m_pod_set_mem_target(struct domain *d, unsigned long target); + +/* Call when decreasing memory reservation to handle PoD entries properly. + * Will return '1' if all entries were handled and nothing more need be done.*/ +int +p2m_pod_decrease_reservation(struct domain *d, + xen_pfn_t gpfn, + unsigned int order); + /* Add a page to a domain's p2m table */ int guest_physmap_add_entry(struct domain *d, unsigned long gfn, unsigned long mfn, unsigned int page_order, p2m_type_t t); + +/* Set a p2m range as populate-on-demand */ +int guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn, + unsigned int order); /* Untyped version for RAM only, for compatibility * diff -r b8b66dc0fa1d -r 661a839a481e xen/include/public/memory.h --- a/xen/include/public/memory.h Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/include/public/memory.h Wed Jan 07 12:20:18 2009 +0900 @@ -48,6 +48,8 @@ /* NUMA node to allocate from. */ #define XENMEMF_node(x) (((x) + 1) << 8) #define XENMEMF_get_node(x) ((((x) >> 8) - 1) & 0xffu) +/* Flag to populate physmap with populate-on-demand entries */ +#define XENMEMF_populate_on_demand (1<<16) #endif struct xen_memory_reservation { @@ -299,6 +301,19 @@ typedef struct xen_foreign_memory_map xe typedef struct xen_foreign_memory_map xen_foreign_memory_map_t; DEFINE_XEN_GUEST_HANDLE(xen_foreign_memory_map_t); +#define XENMEM_set_pod_target 16 +#define XENMEM_get_pod_target 17 +struct xen_pod_target { + /* IN */ + uint64_t target_pages; + /* OUT */ + uint64_t tot_pages; + uint64_t pod_cache_pages; + uint64_t pod_entries; + /* IN */ + domid_t domid; +}; +typedef struct xen_pod_target xen_pod_target_t; #endif /* __XEN_PUBLIC_MEMORY_H__ */ /* diff -r b8b66dc0fa1d -r 661a839a481e xen/include/xen/grant_table.h --- a/xen/include/xen/grant_table.h Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/include/xen/grant_table.h Wed Jan 07 12:20:18 2009 +0900 @@ -32,6 +32,7 @@ struct active_grant_entry { struct active_grant_entry { u32 pin; /* Reference count information. */ domid_t domid; /* Domain being granted access. */ + unsigned long gfn; /* Guest's idea of the frame being granted. */ unsigned long frame; /* Frame being granted. */ }; @@ -146,4 +147,7 @@ nr_active_grant_frames(struct grant_tabl return num_act_frames_from_sha_frames(nr_grant_frames(gt)); } +int +gnttab_is_granted(struct domain *d, xen_pfn_t gfn, int order); + #endif /* __XEN_GRANT_TABLE_H__ */ diff -r b8b66dc0fa1d -r 661a839a481e xen/include/xen/hypercall.h --- a/xen/include/xen/hypercall.h Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/include/xen/hypercall.h Wed Jan 07 12:20:18 2009 +0900 @@ -48,7 +48,7 @@ do_platform_op( * at what point in the page list to resume. For this purpose I steal the * high-order bits of the @cmd parameter, which are otherwise unused and zero. */ -#define MEMOP_EXTENT_SHIFT 4 /* cmd[:4] == start_extent */ +#define MEMOP_EXTENT_SHIFT 6 /* cmd[:6] == start_extent */ #define MEMOP_CMD_MASK ((1 << MEMOP_EXTENT_SHIFT) - 1) extern long diff -r b8b66dc0fa1d -r 661a839a481e xen/include/xen/mm.h --- a/xen/include/xen/mm.h Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/include/xen/mm.h Wed Jan 07 12:20:18 2009 +0900 @@ -72,6 +72,8 @@ int assign_pages( /* memflags: */ #define _MEMF_no_refcount 0 #define MEMF_no_refcount (1U<<_MEMF_no_refcount) +#define _MEMF_populate_on_demand 1 +#define MEMF_populate_on_demand (1U<<_MEMF_populate_on_demand) #define _MEMF_node 8 #define MEMF_node(n) ((((n)+1)&0xff)<<_MEMF_node) #define _MEMF_bits 24 diff -r b8b66dc0fa1d -r 661a839a481e xen/include/xlat.lst --- a/xen/include/xlat.lst Wed Jan 07 12:19:36 2009 +0900 +++ b/xen/include/xlat.lst Wed Jan 07 12:20:18 2009 +0900 @@ -38,6 +38,7 @@ ! memory_exchange memory.h ! memory_map memory.h ! memory_reservation memory.h +! pod_target memory.h ! translate_gpfn_list memory.h ! sched_poll sched.h ? sched_remote_shutdown sched.h _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |