# 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
|