WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] merge with xen-unstable.hg

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 08 Jan 2009 06:58:05 -0800
Delivery-date: Thu, 08 Jan 2009 07:05:59 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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(&current_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

<Prev in Thread] Current Thread [Next in Thread>