[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1203444880 25200
# Node ID f853c049709546b4f1fa1b4b03ddff165c163d38
# Parent  63b0a8cb56ff0d35b6ed9b5bfa5b6454cebef21c
# Parent  8848d9e075848a09f130dc205298a8ce55809ef5
merge with xen-unstable.hg
---
 tools/console/daemon/io.c                      |    2 
 tools/firmware/hvmloader/acpi/dsdt.asl         |  126 +++
 tools/firmware/hvmloader/acpi/dsdt.c           |  964 +++++++++++++------------
 tools/firmware/hvmloader/acpi/static_tables.c  |    2 
 tools/ioemu/hw/pass-through.c                  |  333 ++++++++
 tools/ioemu/hw/pc.c                            |    6 
 tools/ioemu/hw/pci.c                           |    9 
 tools/ioemu/hw/piix4acpi.c                     |  389 +++++++++-
 tools/ioemu/monitor.c                          |    6 
 tools/ioemu/vl.c                               |   22 
 tools/ioemu/vl.h                               |   27 
 tools/ioemu/xenstore.c                         |  112 ++
 tools/libxc/xc_domain.c                        |   44 +
 tools/libxc/xenctrl.h                          |   13 
 tools/python/xen/xend/XendDomainInfo.py        |  202 +++++
 tools/python/xen/xend/image.py                 |   31 
 tools/python/xen/xend/server/DevController.py  |    8 
 tools/python/xen/xend/server/pciif.py          |   48 +
 tools/python/xen/xm/main.py                    |   67 +
 xen/arch/x86/domctl.c                          |   45 +
 xen/arch/x86/hvm/hvm.c                         |   26 
 xen/arch/x86/hvm/iommu.c                       |   10 
 xen/arch/x86/hvm/irq.c                         |    3 
 xen/arch/x86/hvm/svm/amd_iommu/pci-amd-iommu.c |    7 
 xen/arch/x86/hvm/vmx/vtd/dmar.c                |    2 
 xen/arch/x86/hvm/vmx/vtd/intel-iommu.c         |   24 
 xen/arch/x86/hvm/vmx/vtd/io.c                  |   61 +
 xen/arch/x86/mm.c                              |   30 
 xen/arch/x86/mm/shadow/common.c                |    7 
 xen/arch/x86/mm/shadow/multi.c                 |  100 ++
 xen/arch/x86/mm/shadow/private.h               |    5 
 xen/include/asm-x86/domain.h                   |   10 
 xen/include/asm-x86/hvm/irq.h                  |    2 
 xen/include/asm-x86/iommu.h                    |    7 
 xen/include/asm-x86/perfc_defn.h               |    3 
 xen/include/public/domctl.h                    |    2 
 xen/include/public/hvm/ioreq.h                 |    4 
 37 files changed, 2196 insertions(+), 563 deletions(-)

diff -r 63b0a8cb56ff -r f853c0497095 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Tue Feb 19 09:28:09 2008 -0700
+++ b/tools/console/daemon/io.c Tue Feb 19 11:14:40 2008 -0700
@@ -122,7 +122,7 @@ static int write_with_timestamp(int fd, 
        char ts[32];
        time_t now = time(NULL);
        const struct tm *tmnow = localtime(&now);
-       size_t tslen = strftime(ts, sizeof(ts), "[%d-%m-%Y %H:%M:%S] ", tmnow);
+       size_t tslen = strftime(ts, sizeof(ts), "[%Y-%m-%d %H:%M:%S] ", tmnow);
 
        memcpy(buf, data, sz);
        while (sz > 0 && buf[sz-1] == '\r')
diff -r 63b0a8cb56ff -r f853c0497095 tools/firmware/hvmloader/acpi/dsdt.asl
--- a/tools/firmware/hvmloader/acpi/dsdt.asl    Tue Feb 19 09:28:09 2008 -0700
+++ b/tools/firmware/hvmloader/acpi/dsdt.asl    Tue Feb 19 11:14:40 2008 -0700
@@ -27,7 +27,14 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, 
     Name (\APCL, 0x00010000)
     Name (\PUID, 0x00)
 
-    /* S5 (power-off) type codes: must match with piix4 emulation! */
+    /* S4 (STD) and S5 (power-off) type codes: must match piix4 emulation. */
+    Name (\_S4, Package (0x04)
+    {
+        0x06,  /* PM1a_CNT.SLP_TYP */
+        0x06,  /* PM1b_CNT.SLP_TYP */
+        0x00,  /* reserved */
+        0x00   /* reserved */
+    })
     Name (\_S5, Package (0x04)
     {
         0x07,  /* PM1a_CNT.SLP_TYP */
@@ -79,7 +86,7 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, 
            Name (_UID, 0x00)
            Name (_ADR, 0x00)
            Name (_BBN, 0x00)
- 
+
            Method (_CRS, 0, NotSerialized)
            {
                Name (PRT0, ResourceTemplate ()
@@ -713,6 +720,121 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, 
                     })
                 } 
             }
+
+            /******************************************************************
+             * Each PCI hotplug slot needs at least two methods to handle
+             * the ACPI event:
+             *  _EJ0: eject a device
+             *  _STA: return a device's status, e.g. enabled or removed
+             * Other methods are optional: 
+             *  _PS0/3: put them here for debug purpose
+             * 
+             * Eject button would generate a general-purpose event, then the
+             * control method for this event uses Notify() to inform OSPM which
+             * action happened and on which device.
+             *
+             * Pls. refer "6.3 Device Insertion, Removal, and Status Objects"
+             * in ACPI spec 3.0b for details.
+             *
+             * QEMU provides a simple hotplug controller with some I/O to
+             * handle the hotplug action and status, which is beyond the ACPI
+             * scope.
+             */
+
+            Device (S1F0)
+            {
+                Name (_ADR, 0x00060000) /* Dev 6, Func 0 */
+                Name (_SUN, 0x00000001)
+
+                Method (_PS0, 0)
+                {
+                    Store (0x80, \_GPE.DPT2)
+                }
+
+                Method (_PS3, 0)
+                {
+                    Store (0x83, \_GPE.DPT2)
+                }
+
+                Method (_EJ0, 1)
+                {
+                    Store (0x88, \_GPE.DPT2)
+                    Store (0x1, \_GPE.PHP1) /* eject php slot 1*/
+                }
+
+                Method (_STA, 0)
+                {
+                    Store (0x89, \_GPE.DPT2)
+                    Return ( \_GPE.PHP1 )   /* IN status as the _STA */
+                }
+            }
+
+            Device (S2F0)
+            {
+                Name (_ADR, 0x00070000) /* Dev 7, Func 0 */
+                Name (_SUN, 0x00000002)
+
+                Method (_PS0, 0)
+                {
+                    Store (0x90, \_GPE.DPT2)
+                }
+
+                Method (_PS3, 0)
+                {
+                    Store (0x93, \_GPE.DPT2)
+                }
+
+                Method (_EJ0, 1)
+                {
+                    Store (0x98, \_GPE.DPT2)
+                    Store (0x1, \_GPE.PHP2) /* eject php slot 1*/
+                }
+
+                Method (_STA, 0)
+                {
+                    Store (0x99, \_GPE.DPT2)
+                    Return ( \_GPE.PHP2 )   /* IN status as the _STA */
+                }
+            }
+        }
+    }
+
+    Scope (\_GPE)
+    {
+        OperationRegion (PHP, SystemIO, 0x10c0, 0x03)
+        Field (PHP, ByteAcc, NoLock, Preserve)
+        {
+            PSTA,   8, /* hotplug controller status reg */
+            PHP1,   8, /* hotplug slot 1 control reg */
+            PHP2,   8  /* hotplug slot 2 control reg */
+        }
+        OperationRegion (DG1, SystemIO, 0xb044, 0x04)
+        Field (DG1, ByteAcc, NoLock, Preserve)
+        {
+            DPT1,   8,
+            DPT2,   8
+        }
+        Method (_L03, 0, NotSerialized)
+        {
+            /* detect slot and event(remove/add) */
+            Name (SLT, 0x0)
+            Name (EVT, 0x0)
+            Store (PSTA, Local1)
+            ShiftRight (Local1, 0x4, SLT)
+            And (Local1, 0xf, EVT)
+
+            /* debug */
+            Store (SLT, DPT1)
+            Store (EVT, DPT2)
+
+            If ( LEqual(SLT, 0x1) )
+            {
+                Notify (\_SB.PCI0.S1F0, EVT)
+            }
+            ElseIf ( LEqual(SLT, 0x2) )
+            {
+                Notify (\_SB.PCI0.S2F0, EVT)
+            }
         }
     }
 }
diff -r 63b0a8cb56ff -r f853c0497095 tools/firmware/hvmloader/acpi/dsdt.c
--- a/tools/firmware/hvmloader/acpi/dsdt.c      Tue Feb 19 09:28:09 2008 -0700
+++ b/tools/firmware/hvmloader/acpi/dsdt.c      Tue Feb 19 11:14:40 2008 -0700
@@ -5,15 +5,15 @@
  * Copyright (C) 2000 - 2006 Intel Corporation
  * Supports ACPI Specification Revision 3.0a
  * 
- * Compilation of "dsdt.asl" - Mon Feb 11 13:31:53 2008
+ * Compilation of "dsdt.asl" - Fri Feb 15 14:07:57 2008
  * 
  * C source code output
  *
  */
 unsigned char AmlCode[] =
 {
-    0x44,0x53,0x44,0x54,0x8E,0x0E,0x00,0x00,  /* 00000000    "DSDT...." */
-    0x02,0x6E,0x58,0x65,0x6E,0x00,0x00,0x00,  /* 00000008    ".nXen..." */
+    0x44,0x53,0x44,0x54,0x5A,0x10,0x00,0x00,  /* 00000000    "DSDTZ..." */
+    0x02,0xCC,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" */
@@ -23,460 +23,518 @@ unsigned char AmlCode[] =
     0x41,0x50,0x43,0x42,0x0C,0x00,0x00,0xC0,  /* 00000040    "APCB...." */
     0xFE,0x08,0x41,0x50,0x43,0x4C,0x0C,0x00,  /* 00000048    "..APCL.." */
     0x00,0x01,0x00,0x08,0x50,0x55,0x49,0x44,  /* 00000050    "....PUID" */
-    0x00,0x08,0x5F,0x53,0x35,0x5F,0x12,0x08,  /* 00000058    ".._S5_.." */
-    0x04,0x0A,0x07,0x0A,0x07,0x00,0x00,0x08,  /* 00000060    "........" */
-    0x50,0x49,0x43,0x44,0x00,0x14,0x0C,0x5F,  /* 00000068    "PICD..._" */
-    0x50,0x49,0x43,0x01,0x70,0x68,0x50,0x49,  /* 00000070    "PIC.phPI" */
-    0x43,0x44,0x10,0x43,0xE1,0x5F,0x53,0x42,  /* 00000078    "CD.C._SB" */
-    0x5F,0x5B,0x80,0x42,0x49,0x4F,0x53,0x00,  /* 00000080    "_[.BIOS." */
-    0x0C,0x00,0xA0,0x0E,0x00,0x0A,0x10,0x5B,  /* 00000088    ".......[" */
-    0x81,0x21,0x42,0x49,0x4F,0x53,0x01,0x55,  /* 00000090    ".!BIOS.U" */
-    0x41,0x52,0x31,0x01,0x55,0x41,0x52,0x32,  /* 00000098    "AR1.UAR2" */
-    0x01,0x48,0x50,0x45,0x54,0x01,0x00,0x1D,  /* 000000A0    ".HPET..." */
-    0x50,0x4D,0x49,0x4E,0x20,0x50,0x4C,0x45,  /* 000000A8    "PMIN PLE" */
-    0x4E,0x20,0x5B,0x82,0x49,0x04,0x4D,0x45,  /* 000000B0    "N [.I.ME" */
-    0x4D,0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 000000B8    "M0._HID." */
-    0x41,0xD0,0x0C,0x02,0x08,0x5F,0x43,0x52,  /* 000000C0    "A...._CR" */
-    0x53,0x11,0x33,0x0A,0x30,0x8A,0x2B,0x00,  /* 000000C8    "S.3.0.+." */
-    0x00,0x0D,0x03,0x00,0x00,0x00,0x00,0x00,  /* 000000D0    "........" */
-    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000D8    "........" */
-    0x00,0x00,0x00,0xFF,0xFF,0x09,0x00,0x00,  /* 000000E0    "........" */
+    0x00,0x08,0x5F,0x53,0x34,0x5F,0x12,0x08,  /* 00000058    ".._S4_.." */
+    0x04,0x0A,0x06,0x0A,0x06,0x00,0x00,0x08,  /* 00000060    "........" */
+    0x5F,0x53,0x35,0x5F,0x12,0x08,0x04,0x0A,  /* 00000068    "_S5_...." */
+    0x07,0x0A,0x07,0x00,0x00,0x08,0x50,0x49,  /* 00000070    "......PI" */
+    0x43,0x44,0x00,0x14,0x0C,0x5F,0x50,0x49,  /* 00000078    "CD..._PI" */
+    0x43,0x01,0x70,0x68,0x50,0x49,0x43,0x44,  /* 00000080    "C.phPICD" */
+    0x10,0x42,0xF1,0x5F,0x53,0x42,0x5F,0x5B,  /* 00000088    ".B._SB_[" */
+    0x80,0x42,0x49,0x4F,0x53,0x00,0x0C,0x00,  /* 00000090    ".BIOS..." */
+    0xA0,0x0E,0x00,0x0A,0x10,0x5B,0x81,0x21,  /* 00000098    ".....[.!" */
+    0x42,0x49,0x4F,0x53,0x01,0x55,0x41,0x52,  /* 000000A0    "BIOS.UAR" */
+    0x31,0x01,0x55,0x41,0x52,0x32,0x01,0x48,  /* 000000A8    "1.UAR2.H" */
+    0x50,0x45,0x54,0x01,0x00,0x1D,0x50,0x4D,  /* 000000B0    "PET...PM" */
+    0x49,0x4E,0x20,0x50,0x4C,0x45,0x4E,0x20,  /* 000000B8    "IN PLEN " */
+    0x5B,0x82,0x49,0x04,0x4D,0x45,0x4D,0x30,  /* 000000C0    "[.I.MEM0" */
+    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 000000C8    "._HID.A." */
+    0x0C,0x02,0x08,0x5F,0x43,0x52,0x53,0x11,  /* 000000D0    "..._CRS." */
+    0x33,0x0A,0x30,0x8A,0x2B,0x00,0x00,0x0D,  /* 000000D8    "3.0.+..." */
+    0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000E0    "........" */
     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000E8    "........" */
-    0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,  /* 000000F0    "........" */
-    0x00,0x00,0x00,0x79,0x00,0x5B,0x82,0x4F,  /* 000000F8    "...y.[.O" */
-    0xD8,0x50,0x43,0x49,0x30,0x08,0x5F,0x48,  /* 00000100    ".PCI0._H" */
-    0x49,0x44,0x0C,0x41,0xD0,0x0A,0x03,0x08,  /* 00000108    "ID.A...." */
-    0x5F,0x55,0x49,0x44,0x00,0x08,0x5F,0x41,  /* 00000110    "_UID.._A" */
-    0x44,0x52,0x00,0x08,0x5F,0x42,0x42,0x4E,  /* 00000118    "DR.._BBN" */
-    0x00,0x14,0x4E,0x0C,0x5F,0x43,0x52,0x53,  /* 00000120    "..N._CRS" */
-    0x00,0x08,0x50,0x52,0x54,0x30,0x11,0x42,  /* 00000128    "..PRT0.B" */
-    0x07,0x0A,0x6E,0x88,0x0D,0x00,0x02,0x0E,  /* 00000130    "..n....." */
-    0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,  /* 00000138    "........" */
-    0x00,0x00,0x01,0x47,0x01,0xF8,0x0C,0xF8,  /* 00000140    "...G...." */
-    0x0C,0x01,0x08,0x88,0x0D,0x00,0x01,0x0C,  /* 00000148    "........" */
-    0x03,0x00,0x00,0x00,0x00,0xF7,0x0C,0x00,  /* 00000150    "........" */
-    0x00,0xF8,0x0C,0x88,0x0D,0x00,0x01,0x0C,  /* 00000158    "........" */
-    0x03,0x00,0x00,0x00,0x0D,0xFF,0xFF,0x00,  /* 00000160    "........" */
-    0x00,0x00,0xF3,0x87,0x17,0x00,0x00,0x0C,  /* 00000168    "........" */
-    0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,  /* 00000170    "........" */
-    0x00,0xFF,0xFF,0x0B,0x00,0x00,0x00,0x00,  /* 00000178    "........" */
-    0x00,0x00,0x00,0x02,0x00,0x87,0x17,0x00,  /* 00000180    "........" */
-    0x00,0x0C,0x03,0x00,0x00,0x00,0x00,0x00,  /* 00000188    "........" */
-    0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xF4,0x00,  /* 00000190    "........" */
-    0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x79,  /* 00000198    ".......y" */
-    0x00,0x8A,0x50,0x52,0x54,0x30,0x0A,0x5C,  /* 000001A0    "..PRT0.\" */
-    0x4D,0x4D,0x49,0x4E,0x8A,0x50,0x52,0x54,  /* 000001A8    "MMIN.PRT" */
-    0x30,0x0A,0x60,0x4D,0x4D,0x41,0x58,0x8A,  /* 000001B0    "0.`MMAX." */
-    0x50,0x52,0x54,0x30,0x0A,0x68,0x4D,0x4C,  /* 000001B8    "PRT0.hML" */
-    0x45,0x4E,0x70,0x50,0x4D,0x49,0x4E,0x4D,  /* 000001C0    "ENpPMINM" */
-    0x4D,0x49,0x4E,0x70,0x50,0x4C,0x45,0x4E,  /* 000001C8    "MINpPLEN" */
-    0x4D,0x4C,0x45,0x4E,0x72,0x4D,0x4D,0x49,  /* 000001D0    "MLENrMMI" */
-    0x4E,0x4D,0x4C,0x45,0x4E,0x4D,0x4D,0x41,  /* 000001D8    "NMLENMMA" */
-    0x58,0x74,0x4D,0x4D,0x41,0x58,0x01,0x4D,  /* 000001E0    "XtMMAX.M" */
-    0x4D,0x41,0x58,0xA4,0x50,0x52,0x54,0x30,  /* 000001E8    "MAX.PRT0" */
-    0x08,0x42,0x55,0x46,0x41,0x11,0x09,0x0A,  /* 000001F0    ".BUFA..." */
-    0x06,0x23,0x20,0x0C,0x18,0x79,0x00,0x08,  /* 000001F8    ".# ..y.." */
-    0x42,0x55,0x46,0x42,0x11,0x09,0x0A,0x06,  /* 00000200    "BUFB...." */
-    0x23,0x00,0x00,0x18,0x79,0x00,0x8B,0x42,  /* 00000208    "#...y..B" */
-    0x55,0x46,0x42,0x01,0x49,0x52,0x51,0x56,  /* 00000210    "UFB.IRQV" */
-    0x5B,0x82,0x48,0x08,0x4C,0x4E,0x4B,0x41,  /* 00000218    "[.H.LNKA" */
-    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000220    "._HID.A." */
-    0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x01,  /* 00000228    "..._UID." */
-    0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,  /* 00000230    ".._STA.{" */
-    0x50,0x49,0x52,0x41,0x0A,0x80,0x60,0xA0,  /* 00000238    "PIRA..`." */
-    0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,  /* 00000240    "..`....." */
-    0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,  /* 00000248    "......._" */
-    0x50,0x52,0x53,0x00,0xA4,0x42,0x55,0x46,  /* 00000250    "PRS..BUF" */
-    0x41,0x14,0x11,0x5F,0x44,0x49,0x53,0x00,  /* 00000258    "A.._DIS." */
-    0x7D,0x50,0x49,0x52,0x41,0x0A,0x80,0x50,  /* 00000260    "}PIRA..P" */
-    0x49,0x52,0x41,0x14,0x1A,0x5F,0x43,0x52,  /* 00000268    "IRA.._CR" */
-    0x53,0x00,0x7B,0x50,0x49,0x52,0x41,0x0A,  /* 00000270    "S.{PIRA." */
-    0x0F,0x60,0x79,0x01,0x60,0x49,0x52,0x51,  /* 00000278    ".`y.`IRQ" */
-    0x56,0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,  /* 00000280    "V.BUFB.." */
-    0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,0x01,  /* 00000288    "_SRS..h." */
-    0x49,0x52,0x51,0x31,0x82,0x49,0x52,0x51,  /* 00000290    "IRQ1.IRQ" */
-    0x31,0x60,0x76,0x60,0x70,0x60,0x50,0x49,  /* 00000298    "1`v`p`PI" */
-    0x52,0x41,0x5B,0x82,0x49,0x08,0x4C,0x4E,  /* 000002A0    "RA[.I.LN" */
-    0x4B,0x42,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 000002A8    "KB._HID." */
-    0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49,  /* 000002B0    "A...._UI" */
-    0x44,0x0A,0x02,0x14,0x1C,0x5F,0x53,0x54,  /* 000002B8    "D...._ST" */
-    0x41,0x00,0x7B,0x50,0x49,0x52,0x42,0x0A,  /* 000002C0    "A.{PIRB." */
-    0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,0x80,  /* 000002C8    ".`...`.." */
-    0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B,  /* 000002D0    "........" */
-    0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4,  /* 000002D8    ".._PRS.." */
-    0x42,0x55,0x46,0x41,0x14,0x11,0x5F,0x44,  /* 000002E0    "BUFA.._D" */
-    0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x42,  /* 000002E8    "IS.}PIRB" */
-    0x0A,0x80,0x50,0x49,0x52,0x42,0x14,0x1A,  /* 000002F0    "..PIRB.." */
-    0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,0x49,  /* 000002F8    "_CRS.{PI" */
-    0x52,0x42,0x0A,0x0F,0x60,0x79,0x01,0x60,  /* 00000300    "RB..`y.`" */
-    0x49,0x52,0x51,0x56,0xA4,0x42,0x55,0x46,  /* 00000308    "IRQV.BUF" */
-    0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01,  /* 00000310    "B.._SRS." */
-    0x8B,0x68,0x01,0x49,0x52,0x51,0x31,0x82,  /* 00000318    ".h.IRQ1." */
-    0x49,0x52,0x51,0x31,0x60,0x76,0x60,0x70,  /* 00000320    "IRQ1`v`p" */
-    0x60,0x50,0x49,0x52,0x42,0x5B,0x82,0x49,  /* 00000328    "`PIRB[.I" */
-    0x08,0x4C,0x4E,0x4B,0x43,0x08,0x5F,0x48,  /* 00000330    ".LNKC._H" */
-    0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,  /* 00000338    "ID.A...." */
-    0x5F,0x55,0x49,0x44,0x0A,0x03,0x14,0x1C,  /* 00000340    "_UID...." */
-    0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49,  /* 00000348    "_STA.{PI" */
-    0x52,0x43,0x0A,0x80,0x60,0xA0,0x08,0x93,  /* 00000350    "RC..`..." */
-    0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,  /* 00000358    "`......." */
-    0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,  /* 00000360    "....._PR" */
-    0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14,  /* 00000368    "S..BUFA." */
-    0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,  /* 00000370    "._DIS.}P" */
-    0x49,0x52,0x43,0x0A,0x80,0x50,0x49,0x52,  /* 00000378    "IRC..PIR" */
-    0x43,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,  /* 00000380    "C.._CRS." */
-    0x7B,0x50,0x49,0x52,0x43,0x0A,0x0F,0x60,  /* 00000388    "{PIRC..`" */
-    0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4,  /* 00000390    "y.`IRQV." */
-    0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,  /* 00000398    "BUFB.._S" */
-    0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52,  /* 000003A0    "RS..h.IR" */
-    0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60,  /* 000003A8    "Q1.IRQ1`" */
-    0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x43,  /* 000003B0    "v`p`PIRC" */
-    0x5B,0x82,0x49,0x08,0x4C,0x4E,0x4B,0x44,  /* 000003B8    "[.I.LNKD" */
-    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 000003C0    "._HID.A." */
-    0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,  /* 000003C8    "..._UID." */
-    0x04,0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,  /* 000003D0    "..._STA." */
-    0x7B,0x50,0x49,0x52,0x44,0x0A,0x80,0x60,  /* 000003D8    "{PIRD..`" */
-    0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,  /* 000003E0    "...`...." */
-    0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,  /* 000003E8    "........" */
-    0x5F,0x50,0x52,0x53,0x00,0xA4,0x42,0x55,  /* 000003F0    "_PRS..BU" */
-    0x46,0x41,0x14,0x11,0x5F,0x44,0x49,0x53,  /* 000003F8    "FA.._DIS" */
-    0x00,0x7D,0x50,0x49,0x52,0x44,0x0A,0x80,  /* 00000400    ".}PIRD.." */
-    0x50,0x49,0x52,0x44,0x14,0x1A,0x5F,0x43,  /* 00000408    "PIRD.._C" */
-    0x52,0x53,0x00,0x7B,0x50,0x49,0x52,0x44,  /* 00000410    "RS.{PIRD" */
-    0x0A,0x0F,0x60,0x79,0x01,0x60,0x49,0x52,  /* 00000418    "..`y.`IR" */
-    0x51,0x56,0xA4,0x42,0x55,0x46,0x42,0x14,  /* 00000420    "QV.BUFB." */
-    0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,  /* 00000428    "._SRS..h" */
-    0x01,0x49,0x52,0x51,0x31,0x82,0x49,0x52,  /* 00000430    ".IRQ1.IR" */
-    0x51,0x31,0x60,0x76,0x60,0x70,0x60,0x50,  /* 00000438    "Q1`v`p`P" */
-    0x49,0x52,0x44,0x5B,0x82,0x44,0x05,0x48,  /* 00000440    "IRD[.D.H" */
-    0x50,0x45,0x54,0x08,0x5F,0x48,0x49,0x44,  /* 00000448    "PET._HID" */
-    0x0C,0x41,0xD0,0x01,0x03,0x08,0x5F,0x55,  /* 00000450    ".A...._U" */
-    0x49,0x44,0x00,0x14,0x18,0x5F,0x53,0x54,  /* 00000458    "ID..._ST" */
-    0x41,0x00,0xA0,0x0C,0x93,0x5E,0x5E,0x5E,  /* 00000460    "A....^^^" */
-    0x48,0x50,0x45,0x54,0x00,0xA4,0x00,0xA1,  /* 00000468    "HPET...." */
-    0x04,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,  /* 00000470    "....._CR" */
-    0x53,0x11,0x1F,0x0A,0x1C,0x87,0x17,0x00,  /* 00000478    "S......." */
-    0x00,0x0D,0x01,0x00,0x00,0x00,0x00,0x00,  /* 00000480    "........" */
-    0x00,0xD0,0xFE,0xFF,0x03,0xD0,0xFE,0x00,  /* 00000488    "........" */
-    0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x79,  /* 00000490    ".......y" */
-    0x00,0x14,0x16,0x5F,0x50,0x52,0x54,0x00,  /* 00000498    "..._PRT." */
-    0xA0,0x0A,0x50,0x49,0x43,0x44,0xA4,0x50,  /* 000004A0    "..PICD.P" */
-    0x52,0x54,0x41,0xA4,0x50,0x52,0x54,0x50,  /* 000004A8    "RTA.PRTP" */
-    0x08,0x50,0x52,0x54,0x50,0x12,0x49,0x36,  /* 000004B0    ".PRTP.I6" */
-    0x3C,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x01,  /* 000004B8    "<......." */
-    0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00,0x12,  /* 000004C0    "..LNKB.." */
-    0x0D,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x01,  /* 000004C8    "........" */
-    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,  /* 000004D0    "LNKC...." */
-    0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02,0x4C,  /* 000004D8    ".......L" */
-    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 000004E0    "NKD....." */
-    0xFF,0xFF,0x01,0x00,0x0A,0x03,0x4C,0x4E,  /* 000004E8    "......LN" */
-    0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 000004F0    "KA......" */
-    0xFF,0x02,0x00,0x00,0x4C,0x4E,0x4B,0x43,  /* 000004F8    "....LNKC" */
+    0x00,0xFF,0xFF,0x09,0x00,0x00,0x00,0x00,  /* 000000F0    "........" */
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000F8    "........" */
+    0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x00,  /* 00000100    "........" */
+    0x00,0x79,0x00,0x5B,0x82,0x4E,0xE8,0x50,  /* 00000108    ".y.[.N.P" */
+    0x43,0x49,0x30,0x08,0x5F,0x48,0x49,0x44,  /* 00000110    "CI0._HID" */
+    0x0C,0x41,0xD0,0x0A,0x03,0x08,0x5F,0x55,  /* 00000118    ".A...._U" */
+    0x49,0x44,0x00,0x08,0x5F,0x41,0x44,0x52,  /* 00000120    "ID.._ADR" */
+    0x00,0x08,0x5F,0x42,0x42,0x4E,0x00,0x14,  /* 00000128    ".._BBN.." */
+    0x4E,0x0C,0x5F,0x43,0x52,0x53,0x00,0x08,  /* 00000130    "N._CRS.." */
+    0x50,0x52,0x54,0x30,0x11,0x42,0x07,0x0A,  /* 00000138    "PRT0.B.." */
+    0x6E,0x88,0x0D,0x00,0x02,0x0E,0x00,0x00,  /* 00000140    "n......." */
+    0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,  /* 00000148    "........" */
+    0x01,0x47,0x01,0xF8,0x0C,0xF8,0x0C,0x01,  /* 00000150    ".G......" */
+    0x08,0x88,0x0D,0x00,0x01,0x0C,0x03,0x00,  /* 00000158    "........" */
+    0x00,0x00,0x00,0xF7,0x0C,0x00,0x00,0xF8,  /* 00000160    "........" */
+    0x0C,0x88,0x0D,0x00,0x01,0x0C,0x03,0x00,  /* 00000168    "........" */
+    0x00,0x00,0x0D,0xFF,0xFF,0x00,0x00,0x00,  /* 00000170    "........" */
+    0xF3,0x87,0x17,0x00,0x00,0x0C,0x03,0x00,  /* 00000178    "........" */
+    0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0xFF,  /* 00000180    "........" */
+    0xFF,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00000188    "........" */
+    0x00,0x02,0x00,0x87,0x17,0x00,0x00,0x0C,  /* 00000190    "........" */
+    0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00000198    "........" */
+    0xF0,0xFF,0xFF,0xFF,0xF4,0x00,0x00,0x00,  /* 000001A0    "........" */
+    0x00,0x00,0x00,0x00,0x05,0x79,0x00,0x8A,  /* 000001A8    ".....y.." */
+    0x50,0x52,0x54,0x30,0x0A,0x5C,0x4D,0x4D,  /* 000001B0    "PRT0.\MM" */
+    0x49,0x4E,0x8A,0x50,0x52,0x54,0x30,0x0A,  /* 000001B8    "IN.PRT0." */
+    0x60,0x4D,0x4D,0x41,0x58,0x8A,0x50,0x52,  /* 000001C0    "`MMAX.PR" */
+    0x54,0x30,0x0A,0x68,0x4D,0x4C,0x45,0x4E,  /* 000001C8    "T0.hMLEN" */
+    0x70,0x50,0x4D,0x49,0x4E,0x4D,0x4D,0x49,  /* 000001D0    "pPMINMMI" */
+    0x4E,0x70,0x50,0x4C,0x45,0x4E,0x4D,0x4C,  /* 000001D8    "NpPLENML" */
+    0x45,0x4E,0x72,0x4D,0x4D,0x49,0x4E,0x4D,  /* 000001E0    "ENrMMINM" */
+    0x4C,0x45,0x4E,0x4D,0x4D,0x41,0x58,0x74,  /* 000001E8    "LENMMAXt" */
+    0x4D,0x4D,0x41,0x58,0x01,0x4D,0x4D,0x41,  /* 000001F0    "MMAX.MMA" */
+    0x58,0xA4,0x50,0x52,0x54,0x30,0x08,0x42,  /* 000001F8    "X.PRT0.B" */
+    0x55,0x46,0x41,0x11,0x09,0x0A,0x06,0x23,  /* 00000200    "UFA....#" */
+    0x20,0x0C,0x18,0x79,0x00,0x08,0x42,0x55,  /* 00000208    " ..y..BU" */
+    0x46,0x42,0x11,0x09,0x0A,0x06,0x23,0x00,  /* 00000210    "FB....#." */
+    0x00,0x18,0x79,0x00,0x8B,0x42,0x55,0x46,  /* 00000218    "..y..BUF" */
+    0x42,0x01,0x49,0x52,0x51,0x56,0x5B,0x82,  /* 00000220    "B.IRQV[." */
+    0x48,0x08,0x4C,0x4E,0x4B,0x41,0x08,0x5F,  /* 00000228    "H.LNKA._" */
+    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,  /* 00000230    "HID.A..." */
+    0x08,0x5F,0x55,0x49,0x44,0x01,0x14,0x1C,  /* 00000238    "._UID..." */
+    0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49,  /* 00000240    "_STA.{PI" */
+    0x52,0x41,0x0A,0x80,0x60,0xA0,0x08,0x93,  /* 00000248    "RA..`..." */
+    0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,  /* 00000250    "`......." */
+    0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,  /* 00000258    "....._PR" */
+    0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14,  /* 00000260    "S..BUFA." */
+    0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,  /* 00000268    "._DIS.}P" */
+    0x49,0x52,0x41,0x0A,0x80,0x50,0x49,0x52,  /* 00000270    "IRA..PIR" */
+    0x41,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,  /* 00000278    "A.._CRS." */
+    0x7B,0x50,0x49,0x52,0x41,0x0A,0x0F,0x60,  /* 00000280    "{PIRA..`" */
+    0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4,  /* 00000288    "y.`IRQV." */
+    0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,  /* 00000290    "BUFB.._S" */
+    0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52,  /* 00000298    "RS..h.IR" */
+    0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60,  /* 000002A0    "Q1.IRQ1`" */
+    0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x41,  /* 000002A8    "v`p`PIRA" */
+    0x5B,0x82,0x49,0x08,0x4C,0x4E,0x4B,0x42,  /* 000002B0    "[.I.LNKB" */
+    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 000002B8    "._HID.A." */
+    0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,  /* 000002C0    "..._UID." */
+    0x02,0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,  /* 000002C8    "..._STA." */
+    0x7B,0x50,0x49,0x52,0x42,0x0A,0x80,0x60,  /* 000002D0    "{PIRB..`" */
+    0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,  /* 000002D8    "...`...." */
+    0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,  /* 000002E0    "........" */
+    0x5F,0x50,0x52,0x53,0x00,0xA4,0x42,0x55,  /* 000002E8    "_PRS..BU" */
+    0x46,0x41,0x14,0x11,0x5F,0x44,0x49,0x53,  /* 000002F0    "FA.._DIS" */
+    0x00,0x7D,0x50,0x49,0x52,0x42,0x0A,0x80,  /* 000002F8    ".}PIRB.." */
+    0x50,0x49,0x52,0x42,0x14,0x1A,0x5F,0x43,  /* 00000300    "PIRB.._C" */
+    0x52,0x53,0x00,0x7B,0x50,0x49,0x52,0x42,  /* 00000308    "RS.{PIRB" */
+    0x0A,0x0F,0x60,0x79,0x01,0x60,0x49,0x52,  /* 00000310    "..`y.`IR" */
+    0x51,0x56,0xA4,0x42,0x55,0x46,0x42,0x14,  /* 00000318    "QV.BUFB." */
+    0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,  /* 00000320    "._SRS..h" */
+    0x01,0x49,0x52,0x51,0x31,0x82,0x49,0x52,  /* 00000328    ".IRQ1.IR" */
+    0x51,0x31,0x60,0x76,0x60,0x70,0x60,0x50,  /* 00000330    "Q1`v`p`P" */
+    0x49,0x52,0x42,0x5B,0x82,0x49,0x08,0x4C,  /* 00000338    "IRB[.I.L" */
+    0x4E,0x4B,0x43,0x08,0x5F,0x48,0x49,0x44,  /* 00000340    "NKC._HID" */
+    0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,  /* 00000348    ".A...._U" */
+    0x49,0x44,0x0A,0x03,0x14,0x1C,0x5F,0x53,  /* 00000350    "ID...._S" */
+    0x54,0x41,0x00,0x7B,0x50,0x49,0x52,0x43,  /* 00000358    "TA.{PIRC" */
+    0x0A,0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,  /* 00000360    "..`...`." */
+    0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,  /* 00000368    "........" */
+    0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,  /* 00000370    "..._PRS." */
+    0xA4,0x42,0x55,0x46,0x41,0x14,0x11,0x5F,  /* 00000378    ".BUFA.._" */
+    0x44,0x49,0x53,0x00,0x7D,0x50,0x49,0x52,  /* 00000380    "DIS.}PIR" */
+    0x43,0x0A,0x80,0x50,0x49,0x52,0x43,0x14,  /* 00000388    "C..PIRC." */
+    0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,  /* 00000390    "._CRS.{P" */
+    0x49,0x52,0x43,0x0A,0x0F,0x60,0x79,0x01,  /* 00000398    "IRC..`y." */
+    0x60,0x49,0x52,0x51,0x56,0xA4,0x42,0x55,  /* 000003A0    "`IRQV.BU" */
+    0x46,0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,  /* 000003A8    "FB.._SRS" */
+    0x01,0x8B,0x68,0x01,0x49,0x52,0x51,0x31,  /* 000003B0    "..h.IRQ1" */
+    0x82,0x49,0x52,0x51,0x31,0x60,0x76,0x60,  /* 000003B8    ".IRQ1`v`" */
+    0x70,0x60,0x50,0x49,0x52,0x43,0x5B,0x82,  /* 000003C0    "p`PIRC[." */
+    0x49,0x08,0x4C,0x4E,0x4B,0x44,0x08,0x5F,  /* 000003C8    "I.LNKD._" */
+    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,  /* 000003D0    "HID.A..." */
+    0x08,0x5F,0x55,0x49,0x44,0x0A,0x04,0x14,  /* 000003D8    "._UID..." */
+    0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,  /* 000003E0    "._STA.{P" */
+    0x49,0x52,0x44,0x0A,0x80,0x60,0xA0,0x08,  /* 000003E8    "IRD..`.." */
+    0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,  /* 000003F0    ".`......" */
+    0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,  /* 000003F8    "......_P" */
+    0x52,0x53,0x00,0xA4,0x42,0x55,0x46,0x41,  /* 00000400    "RS..BUFA" */
+    0x14,0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,  /* 00000408    ".._DIS.}" */
+    0x50,0x49,0x52,0x44,0x0A,0x80,0x50,0x49,  /* 00000410    "PIRD..PI" */
+    0x52,0x44,0x14,0x1A,0x5F,0x43,0x52,0x53,  /* 00000418    "RD.._CRS" */
+    0x00,0x7B,0x50,0x49,0x52,0x44,0x0A,0x0F,  /* 00000420    ".{PIRD.." */
+    0x60,0x79,0x01,0x60,0x49,0x52,0x51,0x56,  /* 00000428    "`y.`IRQV" */
+    0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,  /* 00000430    ".BUFB.._" */
+    0x53,0x52,0x53,0x01,0x8B,0x68,0x01,0x49,  /* 00000438    "SRS..h.I" */
+    0x52,0x51,0x31,0x82,0x49,0x52,0x51,0x31,  /* 00000440    "RQ1.IRQ1" */
+    0x60,0x76,0x60,0x70,0x60,0x50,0x49,0x52,  /* 00000448    "`v`p`PIR" */
+    0x44,0x5B,0x82,0x44,0x05,0x48,0x50,0x45,  /* 00000450    "D[.D.HPE" */
+    0x54,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000458    "T._HID.A" */
+    0xD0,0x01,0x03,0x08,0x5F,0x55,0x49,0x44,  /* 00000460    "...._UID" */
+    0x00,0x14,0x18,0x5F,0x53,0x54,0x41,0x00,  /* 00000468    "..._STA." */
+    0xA0,0x0C,0x93,0x5E,0x5E,0x5E,0x48,0x50,  /* 00000470    "...^^^HP" */
+    0x45,0x54,0x00,0xA4,0x00,0xA1,0x04,0xA4,  /* 00000478    "ET......" */
+    0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,  /* 00000480    "..._CRS." */
+    0x1F,0x0A,0x1C,0x87,0x17,0x00,0x00,0x0D,  /* 00000488    "........" */
+    0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xD0,  /* 00000490    "........" */
+    0xFE,0xFF,0x03,0xD0,0xFE,0x00,0x00,0x00,  /* 00000498    "........" */
+    0x00,0x00,0x04,0x00,0x00,0x79,0x00,0x14,  /* 000004A0    ".....y.." */
+    0x16,0x5F,0x50,0x52,0x54,0x00,0xA0,0x0A,  /* 000004A8    "._PRT..." */
+    0x50,0x49,0x43,0x44,0xA4,0x50,0x52,0x54,  /* 000004B0    "PICD.PRT" */
+    0x41,0xA4,0x50,0x52,0x54,0x50,0x08,0x50,  /* 000004B8    "A.PRTP.P" */
+    0x52,0x54,0x50,0x12,0x49,0x36,0x3C,0x12,  /* 000004C0    "RTP.I6<." */
+    0x0D,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00,  /* 000004C8    "........" */
+    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,  /* 000004D0    "LNKB...." */
+    0x0C,0xFF,0xFF,0x01,0x00,0x01,0x4C,0x4E,  /* 000004D8    "......LN" */
+    0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000004E0    "KC......" */
+    0xFF,0x01,0x00,0x0A,0x02,0x4C,0x4E,0x4B,  /* 000004E8    ".....LNK" */
+    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000004F0    "D......." */
+    0x01,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,  /* 000004F8    "....LNKA" */
     0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x02,  /* 00000500    "........" */
-    0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 00000508    "..LNKD.." */
-    0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A,  /* 00000510    "........" */
-    0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 00000518    ".LNKA..." */
-    0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x03,  /* 00000520    "........" */
-    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,  /* 00000528    "LNKB...." */
-    0x0C,0xFF,0xFF,0x03,0x00,0x00,0x4C,0x4E,  /* 00000530    "......LN" */
-    0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000538    "KD......" */
-    0xFF,0x03,0x00,0x01,0x4C,0x4E,0x4B,0x41,  /* 00000540    "....LNKA" */
-    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x03,  /* 00000548    "........" */
-    0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000550    "...LNKB." */
-    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x03,0x00,  /* 00000558    "........" */
-    0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000560    "..LNKC.." */
-    0x0D,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x00,  /* 00000568    "........" */
-    0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,  /* 00000570    "LNKA...." */
-    0x0C,0xFF,0xFF,0x04,0x00,0x01,0x4C,0x4E,  /* 00000578    "......LN" */
-    0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000580    "KB......" */
-    0xFF,0x04,0x00,0x0A,0x02,0x4C,0x4E,0x4B,  /* 00000588    ".....LNK" */
-    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000590    "C......." */
-    0x04,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x44,  /* 00000598    "....LNKD" */
-    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x05,  /* 000005A0    "........" */
-    0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00,0x12,  /* 000005A8    "..LNKB.." */
-    0x0D,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x01,  /* 000005B0    "........" */
-    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,  /* 000005B8    "LNKC...." */
-    0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02,0x4C,  /* 000005C0    ".......L" */
-    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 000005C8    "NKD....." */
-    0xFF,0xFF,0x05,0x00,0x0A,0x03,0x4C,0x4E,  /* 000005D0    "......LN" */
-    0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 000005D8    "KA......" */
-    0xFF,0x06,0x00,0x00,0x4C,0x4E,0x4B,0x43,  /* 000005E0    "....LNKC" */
+    0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000508    "..LNKC.." */
+    0x0D,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x01,  /* 00000510    "........" */
+    0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,  /* 00000518    "LNKD...." */
+    0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x02,0x4C,  /* 00000520    ".......L" */
+    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 00000528    "NKA....." */
+    0xFF,0xFF,0x02,0x00,0x0A,0x03,0x4C,0x4E,  /* 00000530    "......LN" */
+    0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000538    "KB......" */
+    0xFF,0x03,0x00,0x00,0x4C,0x4E,0x4B,0x44,  /* 00000540    "....LNKD" */
+    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03,  /* 00000548    "........" */
+    0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,  /* 00000550    "..LNKA.." */
+    0x0E,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,  /* 00000558    "........" */
+    0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 00000560    ".LNKB..." */
+    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03,  /* 00000568    "........" */
+    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,  /* 00000570    "LNKC...." */
+    0x0C,0xFF,0xFF,0x04,0x00,0x00,0x4C,0x4E,  /* 00000578    "......LN" */
+    0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000580    "KA......" */
+    0xFF,0x04,0x00,0x01,0x4C,0x4E,0x4B,0x42,  /* 00000588    "....LNKB" */
+    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x04,  /* 00000590    "........" */
+    0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000598    "...LNKC." */
+    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 000005A0    "........" */
+    0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 000005A8    "..LNKD.." */
+    0x0D,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x00,  /* 000005B0    "........" */
+    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,  /* 000005B8    "LNKB...." */
+    0x0C,0xFF,0xFF,0x05,0x00,0x01,0x4C,0x4E,  /* 000005C0    "......LN" */
+    0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000005C8    "KC......" */
+    0xFF,0x05,0x00,0x0A,0x02,0x4C,0x4E,0x4B,  /* 000005D0    ".....LNK" */
+    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000005D8    "D......." */
+    0x05,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,  /* 000005E0    "....LNKA" */
     0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x06,  /* 000005E8    "........" */
-    0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 000005F0    "..LNKD.." */
-    0x0E,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x0A,  /* 000005F8    "........" */
-    0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 00000600    ".LNKA..." */
-    0x04,0x0C,0xFF,0xFF,0x06,0x00,0x0A,0x03,  /* 00000608    "........" */
-    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,  /* 00000610    "LNKB...." */
-    0x0C,0xFF,0xFF,0x07,0x00,0x00,0x4C,0x4E,  /* 00000618    "......LN" */
-    0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000620    "KD......" */
-    0xFF,0x07,0x00,0x01,0x4C,0x4E,0x4B,0x41,  /* 00000628    "....LNKA" */
-    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x07,  /* 00000630    "........" */
-    0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000638    "...LNKB." */
-    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x07,0x00,  /* 00000640    "........" */
-    0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000648    "..LNKC.." */
-    0x0D,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x00,  /* 00000650    "........" */
-    0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,  /* 00000658    "LNKA...." */
-    0x0C,0xFF,0xFF,0x08,0x00,0x01,0x4C,0x4E,  /* 00000660    "......LN" */
-    0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000668    "KB......" */
-    0xFF,0x08,0x00,0x0A,0x02,0x4C,0x4E,0x4B,  /* 00000670    ".....LNK" */
-    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000678    "C......." */
-    0x08,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x44,  /* 00000680    "....LNKD" */
-    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x09,  /* 00000688    "........" */
-    0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00,0x12,  /* 00000690    "..LNKB.." */
-    0x0D,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x01,  /* 00000698    "........" */
-    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,  /* 000006A0    "LNKC...." */
-    0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x02,0x4C,  /* 000006A8    ".......L" */
-    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 000006B0    "NKD....." */
-    0xFF,0xFF,0x09,0x00,0x0A,0x03,0x4C,0x4E,  /* 000006B8    "......LN" */
-    0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 000006C0    "KA......" */
-    0xFF,0x0A,0x00,0x00,0x4C,0x4E,0x4B,0x43,  /* 000006C8    "....LNKC" */
+    0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 000005F0    "..LNKC.." */
+    0x0D,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x01,  /* 000005F8    "........" */
+    0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,  /* 00000600    "LNKD...." */
+    0x0C,0xFF,0xFF,0x06,0x00,0x0A,0x02,0x4C,  /* 00000608    ".......L" */
+    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 00000610    "NKA....." */
+    0xFF,0xFF,0x06,0x00,0x0A,0x03,0x4C,0x4E,  /* 00000618    "......LN" */
+    0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000620    "KB......" */
+    0xFF,0x07,0x00,0x00,0x4C,0x4E,0x4B,0x44,  /* 00000628    "....LNKD" */
+    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x07,  /* 00000630    "........" */
+    0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,  /* 00000638    "..LNKA.." */
+    0x0E,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,  /* 00000640    "........" */
+    0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 00000648    ".LNKB..." */
+    0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x03,  /* 00000650    "........" */
+    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,  /* 00000658    "LNKC...." */
+    0x0C,0xFF,0xFF,0x08,0x00,0x00,0x4C,0x4E,  /* 00000660    "......LN" */
+    0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000668    "KA......" */
+    0xFF,0x08,0x00,0x01,0x4C,0x4E,0x4B,0x42,  /* 00000670    "....LNKB" */
+    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x08,  /* 00000678    "........" */
+    0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000680    "...LNKC." */
+    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x08,0x00,  /* 00000688    "........" */
+    0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 00000690    "..LNKD.." */
+    0x0D,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x00,  /* 00000698    "........" */
+    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,  /* 000006A0    "LNKB...." */
+    0x0C,0xFF,0xFF,0x09,0x00,0x01,0x4C,0x4E,  /* 000006A8    "......LN" */
+    0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000006B0    "KC......" */
+    0xFF,0x09,0x00,0x0A,0x02,0x4C,0x4E,0x4B,  /* 000006B8    ".....LNK" */
+    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000006C0    "D......." */
+    0x09,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,  /* 000006C8    "....LNKA" */
     0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0A,  /* 000006D0    "........" */
-    0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 000006D8    "..LNKD.." */
-    0x0E,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x0A,  /* 000006E0    "........" */
-    0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 000006E8    ".LNKA..." */
-    0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x0A,0x03,  /* 000006F0    "........" */
-    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,  /* 000006F8    "LNKB...." */
-    0x0C,0xFF,0xFF,0x0B,0x00,0x00,0x4C,0x4E,  /* 00000700    "......LN" */
-    0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000708    "KD......" */
-    0xFF,0x0B,0x00,0x01,0x4C,0x4E,0x4B,0x41,  /* 00000710    "....LNKA" */
-    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0B,  /* 00000718    "........" */
-    0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000720    "...LNKB." */
-    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0B,0x00,  /* 00000728    "........" */
-    0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000730    "..LNKC.." */
-    0x0D,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x00,  /* 00000738    "........" */
-    0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,  /* 00000740    "LNKA...." */
-    0x0C,0xFF,0xFF,0x0C,0x00,0x01,0x4C,0x4E,  /* 00000748    "......LN" */
-    0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000750    "KB......" */
-    0xFF,0x0C,0x00,0x0A,0x02,0x4C,0x4E,0x4B,  /* 00000758    ".....LNK" */
-    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000760    "C......." */
-    0x0C,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x44,  /* 00000768    "....LNKD" */
-    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0D,  /* 00000770    "........" */
-    0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00,0x12,  /* 00000778    "..LNKB.." */
-    0x0D,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x01,  /* 00000780    "........" */
-    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,  /* 00000788    "LNKC...." */
-    0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02,0x4C,  /* 00000790    ".......L" */
-    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 00000798    "NKD....." */
-    0xFF,0xFF,0x0D,0x00,0x0A,0x03,0x4C,0x4E,  /* 000007A0    "......LN" */
-    0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 000007A8    "KA......" */
-    0xFF,0x0E,0x00,0x00,0x4C,0x4E,0x4B,0x43,  /* 000007B0    "....LNKC" */
+    0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 000006D8    "..LNKC.." */
+    0x0D,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01,  /* 000006E0    "........" */
+    0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,  /* 000006E8    "LNKD...." */
+    0x0C,0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x4C,  /* 000006F0    ".......L" */
+    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 000006F8    "NKA....." */
+    0xFF,0xFF,0x0A,0x00,0x0A,0x03,0x4C,0x4E,  /* 00000700    "......LN" */
+    0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000708    "KB......" */
+    0xFF,0x0B,0x00,0x00,0x4C,0x4E,0x4B,0x44,  /* 00000710    "....LNKD" */
+    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0B,  /* 00000718    "........" */
+    0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,  /* 00000720    "..LNKA.." */
+    0x0E,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,  /* 00000728    "........" */
+    0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 00000730    ".LNKB..." */
+    0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x03,  /* 00000738    "........" */
+    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,  /* 00000740    "LNKC...." */
+    0x0C,0xFF,0xFF,0x0C,0x00,0x00,0x4C,0x4E,  /* 00000748    "......LN" */
+    0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000750    "KA......" */
+    0xFF,0x0C,0x00,0x01,0x4C,0x4E,0x4B,0x42,  /* 00000758    "....LNKB" */
+    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0C,  /* 00000760    "........" */
+    0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000768    "...LNKC." */
+    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0C,0x00,  /* 00000770    "........" */
+    0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 00000778    "..LNKD.." */
+    0x0D,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x00,  /* 00000780    "........" */
+    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,  /* 00000788    "LNKB...." */
+    0x0C,0xFF,0xFF,0x0D,0x00,0x01,0x4C,0x4E,  /* 00000790    "......LN" */
+    0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000798    "KC......" */
+    0xFF,0x0D,0x00,0x0A,0x02,0x4C,0x4E,0x4B,  /* 000007A0    ".....LNK" */
+    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000007A8    "D......." */
+    0x0D,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,  /* 000007B0    "....LNKA" */
     0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0E,  /* 000007B8    "........" */
-    0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 000007C0    "..LNKD.." */
-    0x0E,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x0A,  /* 000007C8    "........" */
-    0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 000007D0    ".LNKA..." */
-    0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x0A,0x03,  /* 000007D8    "........" */
-    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,  /* 000007E0    "LNKB...." */
-    0x0C,0xFF,0xFF,0x0F,0x00,0x00,0x4C,0x4E,  /* 000007E8    "......LN" */
-    0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 000007F0    "KD......" */
-    0xFF,0x0F,0x00,0x01,0x4C,0x4E,0x4B,0x41,  /* 000007F8    "....LNKA" */
-    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0F,  /* 00000800    "........" */
-    0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000808    "...LNKB." */
-    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0F,0x00,  /* 00000810    "........" */
-    0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00,0x08,  /* 00000818    "..LNKC.." */
-    0x50,0x52,0x54,0x41,0x12,0x41,0x2F,0x3C,  /* 00000820    "PRTA.A/<" */
-    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x01,0x00,  /* 00000828    "........" */
-    0x00,0x00,0x0A,0x14,0x12,0x0B,0x04,0x0C,  /* 00000830    "........" */
-    0xFF,0xFF,0x01,0x00,0x01,0x00,0x0A,0x15,  /* 00000838    "........" */
-    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x01,0x00,  /* 00000840    "........" */
-    0x0A,0x02,0x00,0x0A,0x16,0x12,0x0C,0x04,  /* 00000848    "........" */
-    0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x03,0x00,  /* 00000850    "........" */
-    0x0A,0x17,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000858    "........" */
-    0x02,0x00,0x00,0x00,0x0A,0x18,0x12,0x0B,  /* 00000860    "........" */
-    0x04,0x0C,0xFF,0xFF,0x02,0x00,0x01,0x00,  /* 00000868    "........" */
-    0x0A,0x19,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000870    "........" */
-    0x02,0x00,0x0A,0x02,0x00,0x0A,0x1A,0x12,  /* 00000878    "........" */
-    0x0C,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A,  /* 00000880    "........" */
-    0x03,0x00,0x0A,0x1B,0x12,0x0B,0x04,0x0C,  /* 00000888    "........" */
-    0xFF,0xFF,0x03,0x00,0x00,0x00,0x0A,0x1C,  /* 00000890    "........" */
-    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x03,0x00,  /* 00000898    "........" */
-    0x01,0x00,0x0A,0x1D,0x12,0x0C,0x04,0x0C,  /* 000008A0    "........" */
-    0xFF,0xFF,0x03,0x00,0x0A,0x02,0x00,0x0A,  /* 000008A8    "........" */
-    0x1E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x03,  /* 000008B0    "........" */
-    0x00,0x0A,0x03,0x00,0x0A,0x1F,0x12,0x0B,  /* 000008B8    "........" */
-    0x04,0x0C,0xFF,0xFF,0x04,0x00,0x00,0x00,  /* 000008C0    "........" */
-    0x0A,0x20,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 000008C8    ". ......" */
-    0x04,0x00,0x01,0x00,0x0A,0x21,0x12,0x0C,  /* 000008D0    ".....!.." */
-    0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x02,  /* 000008D8    "........" */
-    0x00,0x0A,0x22,0x12,0x0C,0x04,0x0C,0xFF,  /* 000008E0    ".."....." */
-    0xFF,0x04,0x00,0x0A,0x03,0x00,0x0A,0x23,  /* 000008E8    ".......#" */
-    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x05,0x00,  /* 000008F0    "........" */
-    0x00,0x00,0x0A,0x24,0x12,0x0B,0x04,0x0C,  /* 000008F8    "...$...." */
-    0xFF,0xFF,0x05,0x00,0x01,0x00,0x0A,0x25,  /* 00000900    ".......%" */
-    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x05,0x00,  /* 00000908    "........" */
-    0x0A,0x02,0x00,0x0A,0x26,0x12,0x0C,0x04,  /* 00000910    "....&..." */
-    0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x03,0x00,  /* 00000918    "........" */
-    0x0A,0x27,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000920    ".'......" */
-    0x06,0x00,0x00,0x00,0x0A,0x28,0x12,0x0B,  /* 00000928    ".....(.." */
-    0x04,0x0C,0xFF,0xFF,0x06,0x00,0x01,0x00,  /* 00000930    "........" */
-    0x0A,0x29,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000938    ".)......" */
-    0x06,0x00,0x0A,0x02,0x00,0x0A,0x2A,0x12,  /* 00000940    "......*." */
-    0x0C,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x0A,  /* 00000948    "........" */
-    0x03,0x00,0x0A,0x2B,0x12,0x0B,0x04,0x0C,  /* 00000950    "...+...." */
-    0xFF,0xFF,0x07,0x00,0x00,0x00,0x0A,0x2C,  /* 00000958    ".......," */
-    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x07,0x00,  /* 00000960    "........" */
-    0x01,0x00,0x0A,0x2D,0x12,0x0C,0x04,0x0C,  /* 00000968    "...-...." */
-    0xFF,0xFF,0x07,0x00,0x0A,0x02,0x00,0x0A,  /* 00000970    "........" */
-    0x2E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x07,  /* 00000978    "........" */
-    0x00,0x0A,0x03,0x00,0x0A,0x2F,0x12,0x0B,  /* 00000980    "...../.." */
-    0x04,0x0C,0xFF,0xFF,0x08,0x00,0x00,0x00,  /* 00000988    "........" */
-    0x0A,0x11,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000990    "........" */
-    0x08,0x00,0x01,0x00,0x0A,0x12,0x12,0x0C,  /* 00000998    "........" */
-    0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A,0x02,  /* 000009A0    "........" */
-    0x00,0x0A,0x13,0x12,0x0C,0x04,0x0C,0xFF,  /* 000009A8    "........" */
-    0xFF,0x08,0x00,0x0A,0x03,0x00,0x0A,0x14,  /* 000009B0    "........" */
-    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x09,0x00,  /* 000009B8    "........" */
-    0x00,0x00,0x0A,0x15,0x12,0x0B,0x04,0x0C,  /* 000009C0    "........" */
-    0xFF,0xFF,0x09,0x00,0x01,0x00,0x0A,0x16,  /* 000009C8    "........" */
-    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x09,0x00,  /* 000009D0    "........" */
-    0x0A,0x02,0x00,0x0A,0x17,0x12,0x0C,0x04,  /* 000009D8    "........" */
-    0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x03,0x00,  /* 000009E0    "........" */
-    0x0A,0x18,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 000009E8    "........" */
-    0x0A,0x00,0x00,0x00,0x0A,0x19,0x12,0x0B,  /* 000009F0    "........" */
-    0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01,0x00,  /* 000009F8    "........" */
-    0x0A,0x1A,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000A00    "........" */
-    0x0A,0x00,0x0A,0x02,0x00,0x0A,0x1B,0x12,  /* 00000A08    "........" */
-    0x0C,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x0A,  /* 00000A10    "........" */
-    0x03,0x00,0x0A,0x1C,0x12,0x0B,0x04,0x0C,  /* 00000A18    "........" */
-    0xFF,0xFF,0x0B,0x00,0x00,0x00,0x0A,0x1D,  /* 00000A20    "........" */
-    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0B,0x00,  /* 00000A28    "........" */
-    0x01,0x00,0x0A,0x1E,0x12,0x0C,0x04,0x0C,  /* 00000A30    "........" */
-    0xFF,0xFF,0x0B,0x00,0x0A,0x02,0x00,0x0A,  /* 00000A38    "........" */
-    0x1F,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0B,  /* 00000A40    "........" */
-    0x00,0x0A,0x03,0x00,0x0A,0x20,0x12,0x0B,  /* 00000A48    "..... .." */
-    0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x00,0x00,  /* 00000A50    "........" */
-    0x0A,0x21,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000A58    ".!......" */
-    0x0C,0x00,0x01,0x00,0x0A,0x22,0x12,0x0C,  /* 00000A60    ".....".." */
-    0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A,0x02,  /* 00000A68    "........" */
-    0x00,0x0A,0x23,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000A70    "..#....." */
-    0xFF,0x0C,0x00,0x0A,0x03,0x00,0x0A,0x24,  /* 00000A78    ".......$" */
-    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0D,0x00,  /* 00000A80    "........" */
-    0x00,0x00,0x0A,0x25,0x12,0x0B,0x04,0x0C,  /* 00000A88    "...%...." */
-    0xFF,0xFF,0x0D,0x00,0x01,0x00,0x0A,0x26,  /* 00000A90    ".......&" */
-    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0D,0x00,  /* 00000A98    "........" */
-    0x0A,0x02,0x00,0x0A,0x27,0x12,0x0C,0x04,  /* 00000AA0    "....'..." */
-    0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x03,0x00,  /* 00000AA8    "........" */
-    0x0A,0x28,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000AB0    ".(......" */
-    0x0E,0x00,0x00,0x00,0x0A,0x29,0x12,0x0B,  /* 00000AB8    ".....).." */
-    0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x01,0x00,  /* 00000AC0    "........" */
-    0x0A,0x2A,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000AC8    ".*......" */
-    0x0E,0x00,0x0A,0x02,0x00,0x0A,0x2B,0x12,  /* 00000AD0    "......+." */
-    0x0C,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x0A,  /* 00000AD8    "........" */
-    0x03,0x00,0x0A,0x2C,0x12,0x0B,0x04,0x0C,  /* 00000AE0    "...,...." */
-    0xFF,0xFF,0x0F,0x00,0x00,0x00,0x0A,0x2D,  /* 00000AE8    ".......-" */
-    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0F,0x00,  /* 00000AF0    "........" */
-    0x01,0x00,0x0A,0x2E,0x12,0x0C,0x04,0x0C,  /* 00000AF8    "........" */
-    0xFF,0xFF,0x0F,0x00,0x0A,0x02,0x00,0x0A,  /* 00000B00    "........" */
-    0x2F,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0F,  /* 00000B08    "/......." */
-    0x00,0x0A,0x03,0x00,0x0A,0x10,0x5B,0x82,  /* 00000B10    "......[." */
-    0x46,0x37,0x49,0x53,0x41,0x5F,0x08,0x5F,  /* 00000B18    "F7ISA_._" */
-    0x41,0x44,0x52,0x0C,0x00,0x00,0x01,0x00,  /* 00000B20    "ADR....." */
-    0x5B,0x80,0x50,0x49,0x52,0x51,0x02,0x0A,  /* 00000B28    "[.PIRQ.." */
-    0x60,0x0A,0x04,0x10,0x2E,0x5C,0x00,0x5B,  /* 00000B30    "`....\.[" */
-    0x81,0x29,0x5C,0x2F,0x04,0x5F,0x53,0x42,  /* 00000B38    ".)\/._SB" */
-    0x5F,0x50,0x43,0x49,0x30,0x49,0x53,0x41,  /* 00000B40    "_PCI0ISA" */
-    0x5F,0x50,0x49,0x52,0x51,0x01,0x50,0x49,  /* 00000B48    "_PIRQ.PI" */
-    0x52,0x41,0x08,0x50,0x49,0x52,0x42,0x08,  /* 00000B50    "RA.PIRB." */
-    0x50,0x49,0x52,0x43,0x08,0x50,0x49,0x52,  /* 00000B58    "PIRC.PIR" */
-    0x44,0x08,0x5B,0x82,0x46,0x0B,0x53,0x59,  /* 00000B60    "D.[.F.SY" */
-    0x53,0x52,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000B68    "SR._HID." */
-    0x41,0xD0,0x0C,0x02,0x08,0x5F,0x55,0x49,  /* 00000B70    "A...._UI" */
-    0x44,0x01,0x08,0x43,0x52,0x53,0x5F,0x11,  /* 00000B78    "D..CRS_." */
-    0x4E,0x08,0x0A,0x8A,0x47,0x01,0x10,0x00,  /* 00000B80    "N...G..." */
-    0x10,0x00,0x00,0x10,0x47,0x01,0x22,0x00,  /* 00000B88    "....G."." */
-    0x22,0x00,0x00,0x0C,0x47,0x01,0x30,0x00,  /* 00000B90    ""...G.0." */
-    0x30,0x00,0x00,0x10,0x47,0x01,0x44,0x00,  /* 00000B98    "0...G.D." */
-    0x44,0x00,0x00,0x1C,0x47,0x01,0x62,0x00,  /* 00000BA0    "D...G.b." */
-    0x62,0x00,0x00,0x02,0x47,0x01,0x65,0x00,  /* 00000BA8    "b...G.e." */
-    0x65,0x00,0x00,0x0B,0x47,0x01,0x72,0x00,  /* 00000BB0    "e...G.r." */
-    0x72,0x00,0x00,0x0E,0x47,0x01,0x80,0x00,  /* 00000BB8    "r...G..." */
-    0x80,0x00,0x00,0x01,0x47,0x01,0x84,0x00,  /* 00000BC0    "....G..." */
-    0x84,0x00,0x00,0x03,0x47,0x01,0x88,0x00,  /* 00000BC8    "....G..." */
-    0x88,0x00,0x00,0x01,0x47,0x01,0x8C,0x00,  /* 00000BD0    "....G..." */
-    0x8C,0x00,0x00,0x03,0x47,0x01,0x90,0x00,  /* 00000BD8    "....G..." */
-    0x90,0x00,0x00,0x10,0x47,0x01,0xA2,0x00,  /* 00000BE0    "....G..." */
-    0xA2,0x00,0x00,0x1C,0x47,0x01,0xE0,0x00,  /* 00000BE8    "....G..." */
-    0xE0,0x00,0x00,0x10,0x47,0x01,0xA0,0x08,  /* 00000BF0    "....G..." */
-    0xA0,0x08,0x00,0x04,0x47,0x01,0xC0,0x0C,  /* 00000BF8    "....G..." */
-    0xC0,0x0C,0x00,0x10,0x47,0x01,0xD0,0x04,  /* 00000C00    "....G..." */
-    0xD0,0x04,0x00,0x02,0x79,0x00,0x14,0x0B,  /* 00000C08    "....y..." */
-    0x5F,0x43,0x52,0x53,0x00,0xA4,0x43,0x52,  /* 00000C10    "_CRS..CR" */
-    0x53,0x5F,0x5B,0x82,0x2B,0x50,0x49,0x43,  /* 00000C18    "S_[.+PIC" */
-    0x5F,0x08,0x5F,0x48,0x49,0x44,0x0B,0x41,  /* 00000C20    "_._HID.A" */
-    0xD0,0x08,0x5F,0x43,0x52,0x53,0x11,0x18,  /* 00000C28    ".._CRS.." */
-    0x0A,0x15,0x47,0x01,0x20,0x00,0x20,0x00,  /* 00000C30    "..G. . ." */
-    0x01,0x02,0x47,0x01,0xA0,0x00,0xA0,0x00,  /* 00000C38    "..G....." */
-    0x01,0x02,0x22,0x04,0x00,0x79,0x00,0x5B,  /* 00000C40    ".."..y.[" */
-    0x82,0x47,0x05,0x44,0x4D,0x41,0x30,0x08,  /* 00000C48    ".G.DMA0." */
-    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x02,  /* 00000C50    "_HID.A.." */
-    0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x41,  /* 00000C58    ".._CRS.A" */
-    0x04,0x0A,0x3D,0x2A,0x10,0x04,0x47,0x01,  /* 00000C60    "..=*..G." */
-    0x00,0x00,0x00,0x00,0x00,0x10,0x47,0x01,  /* 00000C68    "......G." */
-    0x81,0x00,0x81,0x00,0x00,0x03,0x47,0x01,  /* 00000C70    "......G." */
-    0x87,0x00,0x87,0x00,0x00,0x01,0x47,0x01,  /* 00000C78    "......G." */
-    0x89,0x00,0x89,0x00,0x00,0x03,0x47,0x01,  /* 00000C80    "......G." */
-    0x8F,0x00,0x8F,0x00,0x00,0x01,0x47,0x01,  /* 00000C88    "......G." */
-    0xC0,0x00,0xC0,0x00,0x00,0x20,0x47,0x01,  /* 00000C90    "..... G." */
-    0x80,0x04,0x80,0x04,0x00,0x10,0x79,0x00,  /* 00000C98    "......y." */
-    0x5B,0x82,0x25,0x54,0x4D,0x52,0x5F,0x08,  /* 00000CA0    "[.%TMR_." */
-    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x01,  /* 00000CA8    "_HID.A.." */
-    0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x10,  /* 00000CB0    ".._CRS.." */
-    0x0A,0x0D,0x47,0x01,0x40,0x00,0x40,0x00,  /* 00000CB8    "..G.@.@." */
-    0x00,0x04,0x22,0x01,0x00,0x79,0x00,0x5B,  /* 00000CC0    ".."..y.[" */
-    0x82,0x25,0x52,0x54,0x43,0x5F,0x08,0x5F,  /* 00000CC8    ".%RTC_._" */
-    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0B,0x00,  /* 00000CD0    "HID.A..." */
-    0x08,0x5F,0x43,0x52,0x53,0x11,0x10,0x0A,  /* 00000CD8    "._CRS..." */
-    0x0D,0x47,0x01,0x70,0x00,0x70,0x00,0x00,  /* 00000CE0    ".G.p.p.." */
-    0x02,0x22,0x00,0x01,0x79,0x00,0x5B,0x82,  /* 00000CE8    "."..y.[." */
-    0x22,0x53,0x50,0x4B,0x52,0x08,0x5F,0x48,  /* 00000CF0    ""SPKR._H" */
-    0x49,0x44,0x0C,0x41,0xD0,0x08,0x00,0x08,  /* 00000CF8    "ID.A...." */
-    0x5F,0x43,0x52,0x53,0x11,0x0D,0x0A,0x0A,  /* 00000D00    "_CRS...." */
-    0x47,0x01,0x61,0x00,0x61,0x00,0x00,0x01,  /* 00000D08    "G.a.a..." */
-    0x79,0x00,0x5B,0x82,0x31,0x50,0x53,0x32,  /* 00000D10    "y.[.1PS2" */
-    0x4D,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000D18    "M._HID.A" */
-    0xD0,0x0F,0x13,0x08,0x5F,0x43,0x49,0x44,  /* 00000D20    "...._CID" */
-    0x0C,0x41,0xD0,0x0F,0x13,0x14,0x09,0x5F,  /* 00000D28    ".A....._" */
-    0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,  /* 00000D30    "STA....." */
-    0x5F,0x43,0x52,0x53,0x11,0x08,0x0A,0x05,  /* 00000D38    "_CRS...." */
-    0x22,0x00,0x10,0x79,0x00,0x5B,0x82,0x42,  /* 00000D40    ""..y.[.B" */
-    0x04,0x50,0x53,0x32,0x4B,0x08,0x5F,0x48,  /* 00000D48    ".PS2K._H" */
-    0x49,0x44,0x0C,0x41,0xD0,0x03,0x03,0x08,  /* 00000D50    "ID.A...." */
-    0x5F,0x43,0x49,0x44,0x0C,0x41,0xD0,0x03,  /* 00000D58    "_CID.A.." */
-    0x0B,0x14,0x09,0x5F,0x53,0x54,0x41,0x00,  /* 00000D60    "..._STA." */
-    0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,  /* 00000D68    "...._CRS" */
-    0x11,0x18,0x0A,0x15,0x47,0x01,0x60,0x00,  /* 00000D70    "....G.`." */
-    0x60,0x00,0x00,0x01,0x47,0x01,0x64,0x00,  /* 00000D78    "`...G.d." */
-    0x64,0x00,0x00,0x01,0x22,0x02,0x00,0x79,  /* 00000D80    "d..."..y" */
-    0x00,0x5B,0x82,0x3A,0x46,0x44,0x43,0x30,  /* 00000D88    ".[.:FDC0" */
-    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000D90    "._HID.A." */
-    0x07,0x00,0x14,0x09,0x5F,0x53,0x54,0x41,  /* 00000D98    "...._STA" */
-    0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,  /* 00000DA0    "....._CR" */
-    0x53,0x11,0x1B,0x0A,0x18,0x47,0x01,0xF0,  /* 00000DA8    "S....G.." */
-    0x03,0xF0,0x03,0x01,0x06,0x47,0x01,0xF7,  /* 00000DB0    ".....G.." */
-    0x03,0xF7,0x03,0x01,0x01,0x22,0x40,0x00,  /* 00000DB8    "....."@." */
-    0x2A,0x04,0x00,0x79,0x00,0x5B,0x82,0x46,  /* 00000DC0    "*..y.[.F" */
-    0x04,0x55,0x41,0x52,0x31,0x08,0x5F,0x48,  /* 00000DC8    ".UAR1._H" */
-    0x49,0x44,0x0C,0x41,0xD0,0x05,0x01,0x08,  /* 00000DD0    "ID.A...." */
-    0x5F,0x55,0x49,0x44,0x01,0x14,0x19,0x5F,  /* 00000DD8    "_UID..._" */
-    0x53,0x54,0x41,0x00,0xA0,0x0D,0x93,0x5E,  /* 00000DE0    "STA....^" */
-    0x5E,0x5E,0x5E,0x55,0x41,0x52,0x31,0x00,  /* 00000DE8    "^^^UAR1." */
-    0xA4,0x00,0xA1,0x04,0xA4,0x0A,0x0F,0x08,  /* 00000DF0    "........" */
-    0x5F,0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,  /* 00000DF8    "_CRS...." */
-    0x47,0x01,0xF8,0x03,0xF8,0x03,0x08,0x08,  /* 00000E00    "G......." */
-    0x22,0x10,0x00,0x79,0x00,0x5B,0x82,0x47,  /* 00000E08    ""..y.[.G" */
-    0x04,0x55,0x41,0x52,0x32,0x08,0x5F,0x48,  /* 00000E10    ".UAR2._H" */
-    0x49,0x44,0x0C,0x41,0xD0,0x05,0x01,0x08,  /* 00000E18    "ID.A...." */
-    0x5F,0x55,0x49,0x44,0x0A,0x02,0x14,0x19,  /* 00000E20    "_UID...." */
-    0x5F,0x53,0x54,0x41,0x00,0xA0,0x0D,0x93,  /* 00000E28    "_STA...." */
-    0x5E,0x5E,0x5E,0x5E,0x55,0x41,0x52,0x32,  /* 00000E30    "^^^^UAR2" */
-    0x00,0xA4,0x00,0xA1,0x04,0xA4,0x0A,0x0F,  /* 00000E38    "........" */
-    0x08,0x5F,0x43,0x52,0x53,0x11,0x10,0x0A,  /* 00000E40    "._CRS..." */
-    0x0D,0x47,0x01,0xF8,0x02,0xF8,0x02,0x08,  /* 00000E48    ".G......" */
-    0x08,0x22,0x08,0x00,0x79,0x00,0x5B,0x82,  /* 00000E50    "."..y.[." */
-    0x36,0x4C,0x54,0x50,0x31,0x08,0x5F,0x48,  /* 00000E58    "6LTP1._H" */
-    0x49,0x44,0x0C,0x41,0xD0,0x04,0x00,0x08,  /* 00000E60    "ID.A...." */
-    0x5F,0x55,0x49,0x44,0x0A,0x02,0x14,0x09,  /* 00000E68    "_UID...." */
-    0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,  /* 00000E70    "_STA...." */
-    0x08,0x5F,0x43,0x52,0x53,0x11,0x10,0x0A,  /* 00000E78    "._CRS..." */
-    0x0D,0x47,0x01,0x78,0x03,0x78,0x03,0x08,  /* 00000E80    ".G.x.x.." */
-    0x08,0x22,0x80,0x00,0x79,0x00,
+    0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 000007C0    "..LNKC.." */
+    0x0D,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x01,  /* 000007C8    "........" */
+    0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,  /* 000007D0    "LNKD...." */
+    0x0C,0xFF,0xFF,0x0E,0x00,0x0A,0x02,0x4C,  /* 000007D8    ".......L" */
+    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 000007E0    "NKA....." */
+    0xFF,0xFF,0x0E,0x00,0x0A,0x03,0x4C,0x4E,  /* 000007E8    "......LN" */
+    0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 000007F0    "KB......" */
+    0xFF,0x0F,0x00,0x00,0x4C,0x4E,0x4B,0x44,  /* 000007F8    "....LNKD" */
+    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0F,  /* 00000800    "........" */
+    0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,  /* 00000808    "..LNKA.." */
+    0x0E,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,  /* 00000810    "........" */
+    0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 00000818    ".LNKB..." */
+    0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x03,  /* 00000820    "........" */
+    0x4C,0x4E,0x4B,0x43,0x00,0x08,0x50,0x52,  /* 00000828    "LNKC..PR" */
+    0x54,0x41,0x12,0x41,0x2F,0x3C,0x12,0x0B,  /* 00000830    "TA.A/<.." */
+    0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00,0x00,  /* 00000838    "........" */
+    0x0A,0x14,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000840    "........" */
+    0x01,0x00,0x01,0x00,0x0A,0x15,0x12,0x0C,  /* 00000848    "........" */
+    0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02,  /* 00000850    "........" */
+    0x00,0x0A,0x16,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000858    "........" */
+    0xFF,0x01,0x00,0x0A,0x03,0x00,0x0A,0x17,  /* 00000860    "........" */
+    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x02,0x00,  /* 00000868    "........" */
+    0x00,0x00,0x0A,0x18,0x12,0x0B,0x04,0x0C,  /* 00000870    "........" */
+    0xFF,0xFF,0x02,0x00,0x01,0x00,0x0A,0x19,  /* 00000878    "........" */
+    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x02,0x00,  /* 00000880    "........" */
+    0x0A,0x02,0x00,0x0A,0x1A,0x12,0x0C,0x04,  /* 00000888    "........" */
+    0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x03,0x00,  /* 00000890    "........" */
+    0x0A,0x1B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000898    "........" */
+    0x03,0x00,0x00,0x00,0x0A,0x1C,0x12,0x0B,  /* 000008A0    "........" */
+    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x01,0x00,  /* 000008A8    "........" */
+    0x0A,0x1D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 000008B0    "........" */
+    0x03,0x00,0x0A,0x02,0x00,0x0A,0x1E,0x12,  /* 000008B8    "........" */
+    0x0C,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,  /* 000008C0    "........" */
+    0x03,0x00,0x0A,0x1F,0x12,0x0B,0x04,0x0C,  /* 000008C8    "........" */
+    0xFF,0xFF,0x04,0x00,0x00,0x00,0x0A,0x20,  /* 000008D0    "....... " */
+    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 000008D8    "........" */
+    0x01,0x00,0x0A,0x21,0x12,0x0C,0x04,0x0C,  /* 000008E0    "...!...." */
+    0xFF,0xFF,0x04,0x00,0x0A,0x02,0x00,0x0A,  /* 000008E8    "........" */
+    0x22,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x04,  /* 000008F0    ""......." */
+    0x00,0x0A,0x03,0x00,0x0A,0x23,0x12,0x0B,  /* 000008F8    ".....#.." */
+    0x04,0x0C,0xFF,0xFF,0x05,0x00,0x00,0x00,  /* 00000900    "........" */
+    0x0A,0x24,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000908    ".$......" */
+    0x05,0x00,0x01,0x00,0x0A,0x25,0x12,0x0C,  /* 00000910    ".....%.." */
+    0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02,  /* 00000918    "........" */
+    0x00,0x0A,0x26,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000920    "..&....." */
+    0xFF,0x05,0x00,0x0A,0x03,0x00,0x0A,0x27,  /* 00000928    ".......'" */
+    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x06,0x00,  /* 00000930    "........" */
+    0x00,0x00,0x0A,0x28,0x12,0x0B,0x04,0x0C,  /* 00000938    "...(...." */
+    0xFF,0xFF,0x06,0x00,0x01,0x00,0x0A,0x29,  /* 00000940    ".......)" */
+    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x06,0x00,  /* 00000948    "........" */
+    0x0A,0x02,0x00,0x0A,0x2A,0x12,0x0C,0x04,  /* 00000950    "....*..." */
+    0x0C,0xFF,0xFF,0x06,0x00,0x0A,0x03,0x00,  /* 00000958    "........" */
+    0x0A,0x2B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000960    ".+......" */
+    0x07,0x00,0x00,0x00,0x0A,0x2C,0x12,0x0B,  /* 00000968    ".....,.." */
+    0x04,0x0C,0xFF,0xFF,0x07,0x00,0x01,0x00,  /* 00000970    "........" */
+    0x0A,0x2D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000978    ".-......" */
+    0x07,0x00,0x0A,0x02,0x00,0x0A,0x2E,0x12,  /* 00000980    "........" */
+    0x0C,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,  /* 00000988    "........" */
+    0x03,0x00,0x0A,0x2F,0x12,0x0B,0x04,0x0C,  /* 00000990    ".../...." */
+    0xFF,0xFF,0x08,0x00,0x00,0x00,0x0A,0x11,  /* 00000998    "........" */
+    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x08,0x00,  /* 000009A0    "........" */
+    0x01,0x00,0x0A,0x12,0x12,0x0C,0x04,0x0C,  /* 000009A8    "........" */
+    0xFF,0xFF,0x08,0x00,0x0A,0x02,0x00,0x0A,  /* 000009B0    "........" */
+    0x13,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x08,  /* 000009B8    "........" */
+    0x00,0x0A,0x03,0x00,0x0A,0x14,0x12,0x0B,  /* 000009C0    "........" */
+    0x04,0x0C,0xFF,0xFF,0x09,0x00,0x00,0x00,  /* 000009C8    "........" */
+    0x0A,0x15,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 000009D0    "........" */
+    0x09,0x00,0x01,0x00,0x0A,0x16,0x12,0x0C,  /* 000009D8    "........" */
+    0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x02,  /* 000009E0    "........" */
+    0x00,0x0A,0x17,0x12,0x0C,0x04,0x0C,0xFF,  /* 000009E8    "........" */
+    0xFF,0x09,0x00,0x0A,0x03,0x00,0x0A,0x18,  /* 000009F0    "........" */
+    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0A,0x00,  /* 000009F8    "........" */
+    0x00,0x00,0x0A,0x19,0x12,0x0B,0x04,0x0C,  /* 00000A00    "........" */
+    0xFF,0xFF,0x0A,0x00,0x01,0x00,0x0A,0x1A,  /* 00000A08    "........" */
+    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0A,0x00,  /* 00000A10    "........" */
+    0x0A,0x02,0x00,0x0A,0x1B,0x12,0x0C,0x04,  /* 00000A18    "........" */
+    0x0C,0xFF,0xFF,0x0A,0x00,0x0A,0x03,0x00,  /* 00000A20    "........" */
+    0x0A,0x1C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000A28    "........" */
+    0x0B,0x00,0x00,0x00,0x0A,0x1D,0x12,0x0B,  /* 00000A30    "........" */
+    0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x01,0x00,  /* 00000A38    "........" */
+    0x0A,0x1E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000A40    "........" */
+    0x0B,0x00,0x0A,0x02,0x00,0x0A,0x1F,0x12,  /* 00000A48    "........" */
+    0x0C,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,  /* 00000A50    "........" */
+    0x03,0x00,0x0A,0x20,0x12,0x0B,0x04,0x0C,  /* 00000A58    "... ...." */
+    0xFF,0xFF,0x0C,0x00,0x00,0x00,0x0A,0x21,  /* 00000A60    ".......!" */
+    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0C,0x00,  /* 00000A68    "........" */
+    0x01,0x00,0x0A,0x22,0x12,0x0C,0x04,0x0C,  /* 00000A70    "..."...." */
+    0xFF,0xFF,0x0C,0x00,0x0A,0x02,0x00,0x0A,  /* 00000A78    "........" */
+    0x23,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0C,  /* 00000A80    "#......." */
+    0x00,0x0A,0x03,0x00,0x0A,0x24,0x12,0x0B,  /* 00000A88    ".....$.." */
+    0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x00,0x00,  /* 00000A90    "........" */
+    0x0A,0x25,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000A98    ".%......" */
+    0x0D,0x00,0x01,0x00,0x0A,0x26,0x12,0x0C,  /* 00000AA0    ".....&.." */
+    0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02,  /* 00000AA8    "........" */
+    0x00,0x0A,0x27,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000AB0    "..'....." */
+    0xFF,0x0D,0x00,0x0A,0x03,0x00,0x0A,0x28,  /* 00000AB8    ".......(" */
+    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0E,0x00,  /* 00000AC0    "........" */
+    0x00,0x00,0x0A,0x29,0x12,0x0B,0x04,0x0C,  /* 00000AC8    "...)...." */
+    0xFF,0xFF,0x0E,0x00,0x01,0x00,0x0A,0x2A,  /* 00000AD0    ".......*" */
+    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0E,0x00,  /* 00000AD8    "........" */
+    0x0A,0x02,0x00,0x0A,0x2B,0x12,0x0C,0x04,  /* 00000AE0    "....+..." */
+    0x0C,0xFF,0xFF,0x0E,0x00,0x0A,0x03,0x00,  /* 00000AE8    "........" */
+    0x0A,0x2C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000AF0    ".,......" */
+    0x0F,0x00,0x00,0x00,0x0A,0x2D,0x12,0x0B,  /* 00000AF8    ".....-.." */
+    0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x01,0x00,  /* 00000B00    "........" */
+    0x0A,0x2E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000B08    "........" */
+    0x0F,0x00,0x0A,0x02,0x00,0x0A,0x2F,0x12,  /* 00000B10    "....../." */
+    0x0C,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,  /* 00000B18    "........" */
+    0x03,0x00,0x0A,0x10,0x5B,0x82,0x46,0x37,  /* 00000B20    "....[.F7" */
+    0x49,0x53,0x41,0x5F,0x08,0x5F,0x41,0x44,  /* 00000B28    "ISA_._AD" */
+    0x52,0x0C,0x00,0x00,0x01,0x00,0x5B,0x80,  /* 00000B30    "R.....[." */
+    0x50,0x49,0x52,0x51,0x02,0x0A,0x60,0x0A,  /* 00000B38    "PIRQ..`." */
+    0x04,0x10,0x2E,0x5C,0x00,0x5B,0x81,0x29,  /* 00000B40    "...\.[.)" */
+    0x5C,0x2F,0x04,0x5F,0x53,0x42,0x5F,0x50,  /* 00000B48    "\/._SB_P" */
+    0x43,0x49,0x30,0x49,0x53,0x41,0x5F,0x50,  /* 00000B50    "CI0ISA_P" */
+    0x49,0x52,0x51,0x01,0x50,0x49,0x52,0x41,  /* 00000B58    "IRQ.PIRA" */
+    0x08,0x50,0x49,0x52,0x42,0x08,0x50,0x49,  /* 00000B60    ".PIRB.PI" */
+    0x52,0x43,0x08,0x50,0x49,0x52,0x44,0x08,  /* 00000B68    "RC.PIRD." */
+    0x5B,0x82,0x46,0x0B,0x53,0x59,0x53,0x52,  /* 00000B70    "[.F.SYSR" */
+    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000B78    "._HID.A." */
+    0x0C,0x02,0x08,0x5F,0x55,0x49,0x44,0x01,  /* 00000B80    "..._UID." */
+    0x08,0x43,0x52,0x53,0x5F,0x11,0x4E,0x08,  /* 00000B88    ".CRS_.N." */
+    0x0A,0x8A,0x47,0x01,0x10,0x00,0x10,0x00,  /* 00000B90    "..G....." */
+    0x00,0x10,0x47,0x01,0x22,0x00,0x22,0x00,  /* 00000B98    "..G."."." */
+    0x00,0x0C,0x47,0x01,0x30,0x00,0x30,0x00,  /* 00000BA0    "..G.0.0." */
+    0x00,0x10,0x47,0x01,0x44,0x00,0x44,0x00,  /* 00000BA8    "..G.D.D." */
+    0x00,0x1C,0x47,0x01,0x62,0x00,0x62,0x00,  /* 00000BB0    "..G.b.b." */
+    0x00,0x02,0x47,0x01,0x65,0x00,0x65,0x00,  /* 00000BB8    "..G.e.e." */
+    0x00,0x0B,0x47,0x01,0x72,0x00,0x72,0x00,  /* 00000BC0    "..G.r.r." */
+    0x00,0x0E,0x47,0x01,0x80,0x00,0x80,0x00,  /* 00000BC8    "..G....." */
+    0x00,0x01,0x47,0x01,0x84,0x00,0x84,0x00,  /* 00000BD0    "..G....." */
+    0x00,0x03,0x47,0x01,0x88,0x00,0x88,0x00,  /* 00000BD8    "..G....." */
+    0x00,0x01,0x47,0x01,0x8C,0x00,0x8C,0x00,  /* 00000BE0    "..G....." */
+    0x00,0x03,0x47,0x01,0x90,0x00,0x90,0x00,  /* 00000BE8    "..G....." */
+    0x00,0x10,0x47,0x01,0xA2,0x00,0xA2,0x00,  /* 00000BF0    "..G....." */
+    0x00,0x1C,0x47,0x01,0xE0,0x00,0xE0,0x00,  /* 00000BF8    "..G....." */
+    0x00,0x10,0x47,0x01,0xA0,0x08,0xA0,0x08,  /* 00000C00    "..G....." */
+    0x00,0x04,0x47,0x01,0xC0,0x0C,0xC0,0x0C,  /* 00000C08    "..G....." */
+    0x00,0x10,0x47,0x01,0xD0,0x04,0xD0,0x04,  /* 00000C10    "..G....." */
+    0x00,0x02,0x79,0x00,0x14,0x0B,0x5F,0x43,  /* 00000C18    "..y..._C" */
+    0x52,0x53,0x00,0xA4,0x43,0x52,0x53,0x5F,  /* 00000C20    "RS..CRS_" */
+    0x5B,0x82,0x2B,0x50,0x49,0x43,0x5F,0x08,  /* 00000C28    "[.+PIC_." */
+    0x5F,0x48,0x49,0x44,0x0B,0x41,0xD0,0x08,  /* 00000C30    "_HID.A.." */
+    0x5F,0x43,0x52,0x53,0x11,0x18,0x0A,0x15,  /* 00000C38    "_CRS...." */
+    0x47,0x01,0x20,0x00,0x20,0x00,0x01,0x02,  /* 00000C40    "G. . ..." */
+    0x47,0x01,0xA0,0x00,0xA0,0x00,0x01,0x02,  /* 00000C48    "G......." */
+    0x22,0x04,0x00,0x79,0x00,0x5B,0x82,0x47,  /* 00000C50    ""..y.[.G" */
+    0x05,0x44,0x4D,0x41,0x30,0x08,0x5F,0x48,  /* 00000C58    ".DMA0._H" */
+    0x49,0x44,0x0C,0x41,0xD0,0x02,0x00,0x08,  /* 00000C60    "ID.A...." */
+    0x5F,0x43,0x52,0x53,0x11,0x41,0x04,0x0A,  /* 00000C68    "_CRS.A.." */
+    0x3D,0x2A,0x10,0x04,0x47,0x01,0x00,0x00,  /* 00000C70    "=*..G..." */
+    0x00,0x00,0x00,0x10,0x47,0x01,0x81,0x00,  /* 00000C78    "....G..." */
+    0x81,0x00,0x00,0x03,0x47,0x01,0x87,0x00,  /* 00000C80    "....G..." */
+    0x87,0x00,0x00,0x01,0x47,0x01,0x89,0x00,  /* 00000C88    "....G..." */
+    0x89,0x00,0x00,0x03,0x47,0x01,0x8F,0x00,  /* 00000C90    "....G..." */
+    0x8F,0x00,0x00,0x01,0x47,0x01,0xC0,0x00,  /* 00000C98    "....G..." */
+    0xC0,0x00,0x00,0x20,0x47,0x01,0x80,0x04,  /* 00000CA0    "... G..." */
+    0x80,0x04,0x00,0x10,0x79,0x00,0x5B,0x82,  /* 00000CA8    "....y.[." */
+    0x25,0x54,0x4D,0x52,0x5F,0x08,0x5F,0x48,  /* 00000CB0    "%TMR_._H" */
+    0x49,0x44,0x0C,0x41,0xD0,0x01,0x00,0x08,  /* 00000CB8    "ID.A...." */
+    0x5F,0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,  /* 00000CC0    "_CRS...." */
+    0x47,0x01,0x40,0x00,0x40,0x00,0x00,0x04,  /* 00000CC8    "G.@.@..." */
+    0x22,0x01,0x00,0x79,0x00,0x5B,0x82,0x25,  /* 00000CD0    ""..y.[.%" */
+    0x52,0x54,0x43,0x5F,0x08,0x5F,0x48,0x49,  /* 00000CD8    "RTC_._HI" */
+    0x44,0x0C,0x41,0xD0,0x0B,0x00,0x08,0x5F,  /* 00000CE0    "D.A...._" */
+    0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,  /* 00000CE8    "CRS....G" */
+    0x01,0x70,0x00,0x70,0x00,0x00,0x02,0x22,  /* 00000CF0    ".p.p..."" */
+    0x00,0x01,0x79,0x00,0x5B,0x82,0x22,0x53,  /* 00000CF8    "..y.[."S" */
+    0x50,0x4B,0x52,0x08,0x5F,0x48,0x49,0x44,  /* 00000D00    "PKR._HID" */
+    0x0C,0x41,0xD0,0x08,0x00,0x08,0x5F,0x43,  /* 00000D08    ".A...._C" */
+    0x52,0x53,0x11,0x0D,0x0A,0x0A,0x47,0x01,  /* 00000D10    "RS....G." */
+    0x61,0x00,0x61,0x00,0x00,0x01,0x79,0x00,  /* 00000D18    "a.a...y." */
+    0x5B,0x82,0x31,0x50,0x53,0x32,0x4D,0x08,  /* 00000D20    "[.1PS2M." */
+    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0F,  /* 00000D28    "_HID.A.." */
+    0x13,0x08,0x5F,0x43,0x49,0x44,0x0C,0x41,  /* 00000D30    ".._CID.A" */
+    0xD0,0x0F,0x13,0x14,0x09,0x5F,0x53,0x54,  /* 00000D38    "....._ST" */
+    0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,  /* 00000D40    "A....._C" */
+    0x52,0x53,0x11,0x08,0x0A,0x05,0x22,0x00,  /* 00000D48    "RS...."." */
+    0x10,0x79,0x00,0x5B,0x82,0x42,0x04,0x50,  /* 00000D50    ".y.[.B.P" */
+    0x53,0x32,0x4B,0x08,0x5F,0x48,0x49,0x44,  /* 00000D58    "S2K._HID" */
+    0x0C,0x41,0xD0,0x03,0x03,0x08,0x5F,0x43,  /* 00000D60    ".A...._C" */
+    0x49,0x44,0x0C,0x41,0xD0,0x03,0x0B,0x14,  /* 00000D68    "ID.A...." */
+    0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,  /* 00000D70    "._STA..." */
+    0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x18,  /* 00000D78    ".._CRS.." */
+    0x0A,0x15,0x47,0x01,0x60,0x00,0x60,0x00,  /* 00000D80    "..G.`.`." */
+    0x00,0x01,0x47,0x01,0x64,0x00,0x64,0x00,  /* 00000D88    "..G.d.d." */
+    0x00,0x01,0x22,0x02,0x00,0x79,0x00,0x5B,  /* 00000D90    ".."..y.[" */
+    0x82,0x3A,0x46,0x44,0x43,0x30,0x08,0x5F,  /* 00000D98    ".:FDC0._" */
+    0x48,0x49,0x44,0x0C,0x41,0xD0,0x07,0x00,  /* 00000DA0    "HID.A..." */
+    0x14,0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,  /* 00000DA8    ".._STA.." */
+    0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,  /* 00000DB0    "..._CRS." */
+    0x1B,0x0A,0x18,0x47,0x01,0xF0,0x03,0xF0,  /* 00000DB8    "...G...." */
+    0x03,0x01,0x06,0x47,0x01,0xF7,0x03,0xF7,  /* 00000DC0    "...G...." */
+    0x03,0x01,0x01,0x22,0x40,0x00,0x2A,0x04,  /* 00000DC8    "..."@.*." */
+    0x00,0x79,0x00,0x5B,0x82,0x46,0x04,0x55,  /* 00000DD0    ".y.[.F.U" */
+    0x41,0x52,0x31,0x08,0x5F,0x48,0x49,0x44,  /* 00000DD8    "AR1._HID" */
+    0x0C,0x41,0xD0,0x05,0x01,0x08,0x5F,0x55,  /* 00000DE0    ".A...._U" */
+    0x49,0x44,0x01,0x14,0x19,0x5F,0x53,0x54,  /* 00000DE8    "ID..._ST" */
+    0x41,0x00,0xA0,0x0D,0x93,0x5E,0x5E,0x5E,  /* 00000DF0    "A....^^^" */
+    0x5E,0x55,0x41,0x52,0x31,0x00,0xA4,0x00,  /* 00000DF8    "^UAR1..." */
+    0xA1,0x04,0xA4,0x0A,0x0F,0x08,0x5F,0x43,  /* 00000E00    "......_C" */
+    0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,  /* 00000E08    "RS....G." */
+    0xF8,0x03,0xF8,0x03,0x08,0x08,0x22,0x10,  /* 00000E10    "......"." */
+    0x00,0x79,0x00,0x5B,0x82,0x47,0x04,0x55,  /* 00000E18    ".y.[.G.U" */
+    0x41,0x52,0x32,0x08,0x5F,0x48,0x49,0x44,  /* 00000E20    "AR2._HID" */
+    0x0C,0x41,0xD0,0x05,0x01,0x08,0x5F,0x55,  /* 00000E28    ".A...._U" */
+    0x49,0x44,0x0A,0x02,0x14,0x19,0x5F,0x53,  /* 00000E30    "ID...._S" */
+    0x54,0x41,0x00,0xA0,0x0D,0x93,0x5E,0x5E,  /* 00000E38    "TA....^^" */
+    0x5E,0x5E,0x55,0x41,0x52,0x32,0x00,0xA4,  /* 00000E40    "^^UAR2.." */
+    0x00,0xA1,0x04,0xA4,0x0A,0x0F,0x08,0x5F,  /* 00000E48    "......._" */
+    0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,  /* 00000E50    "CRS....G" */
+    0x01,0xF8,0x02,0xF8,0x02,0x08,0x08,0x22,  /* 00000E58    "......."" */
+    0x08,0x00,0x79,0x00,0x5B,0x82,0x36,0x4C,  /* 00000E60    "..y.[.6L" */
+    0x54,0x50,0x31,0x08,0x5F,0x48,0x49,0x44,  /* 00000E68    "TP1._HID" */
+    0x0C,0x41,0xD0,0x04,0x00,0x08,0x5F,0x55,  /* 00000E70    ".A...._U" */
+    0x49,0x44,0x0A,0x02,0x14,0x09,0x5F,0x53,  /* 00000E78    "ID...._S" */
+    0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,  /* 00000E80    "TA....._" */
+    0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,  /* 00000E88    "CRS....G" */
+    0x01,0x78,0x03,0x78,0x03,0x08,0x08,0x22,  /* 00000E90    ".x.x..."" */
+    0x80,0x00,0x79,0x00,0x5B,0x82,0x4D,0x07,  /* 00000E98    "..y.[.M." */
+    0x53,0x31,0x46,0x30,0x08,0x5F,0x41,0x44,  /* 00000EA0    "S1F0._AD" */
+    0x52,0x0C,0x00,0x00,0x06,0x00,0x08,0x5F,  /* 00000EA8    "R......_" */
+    0x53,0x55,0x4E,0x01,0x14,0x13,0x5F,0x50,  /* 00000EB0    "SUN..._P" */
+    0x53,0x30,0x00,0x70,0x0A,0x80,0x5C,0x2E,  /* 00000EB8    "S0.p..\." */
+    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000EC0    "_GPEDPT2" */
+    0x14,0x13,0x5F,0x50,0x53,0x33,0x00,0x70,  /* 00000EC8    ".._PS3.p" */
+    0x0A,0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00000ED0    "..\._GPE" */
+    0x44,0x50,0x54,0x32,0x14,0x1F,0x5F,0x45,  /* 00000ED8    "DPT2.._E" */
+    0x4A,0x30,0x01,0x70,0x0A,0x88,0x5C,0x2E,  /* 00000EE0    "J0.p..\." */
+    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000EE8    "_GPEDPT2" */
+    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00000EF0    "p.\._GPE" */
+    0x50,0x48,0x50,0x31,0x14,0x1E,0x5F,0x53,  /* 00000EF8    "PHP1.._S" */
+    0x54,0x41,0x00,0x70,0x0A,0x89,0x5C,0x2E,  /* 00000F00    "TA.p..\." */
+    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000F08    "_GPEDPT2" */
+    0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,  /* 00000F10    ".\._GPEP" */
+    0x48,0x50,0x31,0x5B,0x82,0x4E,0x07,0x53,  /* 00000F18    "HP1[.N.S" */
+    0x32,0x46,0x30,0x08,0x5F,0x41,0x44,0x52,  /* 00000F20    "2F0._ADR" */
+    0x0C,0x00,0x00,0x07,0x00,0x08,0x5F,0x53,  /* 00000F28    "......_S" */
+    0x55,0x4E,0x0A,0x02,0x14,0x13,0x5F,0x50,  /* 00000F30    "UN...._P" */
+    0x53,0x30,0x00,0x70,0x0A,0x90,0x5C,0x2E,  /* 00000F38    "S0.p..\." */
+    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000F40    "_GPEDPT2" */
+    0x14,0x13,0x5F,0x50,0x53,0x33,0x00,0x70,  /* 00000F48    ".._PS3.p" */
+    0x0A,0x93,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00000F50    "..\._GPE" */
+    0x44,0x50,0x54,0x32,0x14,0x1F,0x5F,0x45,  /* 00000F58    "DPT2.._E" */
+    0x4A,0x30,0x01,0x70,0x0A,0x98,0x5C,0x2E,  /* 00000F60    "J0.p..\." */
+    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000F68    "_GPEDPT2" */
+    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00000F70    "p.\._GPE" */
+    0x50,0x48,0x50,0x32,0x14,0x1E,0x5F,0x53,  /* 00000F78    "PHP2.._S" */
+    0x54,0x41,0x00,0x70,0x0A,0x99,0x5C,0x2E,  /* 00000F80    "TA.p..\." */
+    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000F88    "_GPEDPT2" */
+    0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,  /* 00000F90    ".\._GPEP" */
+    0x48,0x50,0x32,0x10,0x4E,0x0B,0x5F,0x47,  /* 00000F98    "HP2.N._G" */
+    0x50,0x45,0x5B,0x80,0x50,0x48,0x50,0x5F,  /* 00000FA0    "PE[.PHP_" */
+    0x01,0x0B,0xC0,0x10,0x0A,0x03,0x5B,0x81,  /* 00000FA8    "......[." */
+    0x15,0x50,0x48,0x50,0x5F,0x01,0x50,0x53,  /* 00000FB0    ".PHP_.PS" */
+    0x54,0x41,0x08,0x50,0x48,0x50,0x31,0x08,  /* 00000FB8    "TA.PHP1." */
+    0x50,0x48,0x50,0x32,0x08,0x5B,0x80,0x44,  /* 00000FC0    "PHP2.[.D" */
+    0x47,0x31,0x5F,0x01,0x0B,0x44,0xB0,0x0A,  /* 00000FC8    "G1_..D.." */
+    0x04,0x5B,0x81,0x10,0x44,0x47,0x31,0x5F,  /* 00000FD0    ".[..DG1_" */
+    0x01,0x44,0x50,0x54,0x31,0x08,0x44,0x50,  /* 00000FD8    ".DPT1.DP" */
+    0x54,0x32,0x08,0x14,0x46,0x07,0x5F,0x4C,  /* 00000FE0    "T2..F._L" */
+    0x30,0x33,0x00,0x08,0x53,0x4C,0x54,0x5F,  /* 00000FE8    "03..SLT_" */
+    0x00,0x08,0x45,0x56,0x54,0x5F,0x00,0x70,  /* 00000FF0    "..EVT_.p" */
+    0x50,0x53,0x54,0x41,0x61,0x7A,0x61,0x0A,  /* 00000FF8    "PSTAaza." */
+    0x04,0x53,0x4C,0x54,0x5F,0x7B,0x61,0x0A,  /* 00001000    ".SLT_{a." */
+    0x0F,0x45,0x56,0x54,0x5F,0x70,0x53,0x4C,  /* 00001008    ".EVT_pSL" */
+    0x54,0x5F,0x44,0x50,0x54,0x31,0x70,0x45,  /* 00001010    "T_DPT1pE" */
+    0x56,0x54,0x5F,0x44,0x50,0x54,0x32,0xA0,  /* 00001018    "VT_DPT2." */
+    0x1B,0x93,0x53,0x4C,0x54,0x5F,0x01,0x86,  /* 00001020    "..SLT_.." */
+    0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,  /* 00001028    "\/._SB_P" */
+    0x43,0x49,0x30,0x53,0x31,0x46,0x30,0x45,  /* 00001030    "CI0S1F0E" */
+    0x56,0x54,0x5F,0xA1,0x1E,0xA0,0x1C,0x93,  /* 00001038    "VT_....." */
+    0x53,0x4C,0x54,0x5F,0x0A,0x02,0x86,0x5C,  /* 00001040    "SLT_...\" */
+    0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,  /* 00001048    "/._SB_PC" */
+    0x49,0x30,0x53,0x32,0x46,0x30,0x45,0x56,  /* 00001050    "I0S2F0EV" */
+    0x54,0x5F,
 };
 int DsdtLen=sizeof(AmlCode);
diff -r 63b0a8cb56ff -r f853c0497095 
tools/firmware/hvmloader/acpi/static_tables.c
--- a/tools/firmware/hvmloader/acpi/static_tables.c     Tue Feb 19 09:28:09 
2008 -0700
+++ b/tools/firmware/hvmloader/acpi/static_tables.c     Tue Feb 19 11:14:40 
2008 -0700
@@ -59,9 +59,11 @@ struct acpi_20_fadt Fadt = {
     .pm1a_evt_blk = ACPI_PM1A_EVT_BLK_ADDRESS,
     .pm1a_cnt_blk = ACPI_PM1A_CNT_BLK_ADDRESS,
     .pm_tmr_blk = ACPI_PM_TMR_BLK_ADDRESS,
+    .gpe0_blk = ACPI_GPE0_BLK_ADDRESS,
     .pm1_evt_len = ACPI_PM1A_EVT_BLK_BIT_WIDTH / 8,
     .pm1_cnt_len = ACPI_PM1A_CNT_BLK_BIT_WIDTH / 8,
     .pm_tmr_len = ACPI_PM_TMR_BLK_BIT_WIDTH / 8,
+    .gpe0_blk_len = ACPI_GPE0_BLK_LEN,
 
     .p_lvl2_lat = 0x0fff, /* >100,  means we do not support C2 state */
     .p_lvl3_lat = 0x0fff, /* >1000, means we do not support C3 state */
diff -r 63b0a8cb56ff -r f853c0497095 tools/ioemu/hw/pass-through.c
--- a/tools/ioemu/hw/pass-through.c     Tue Feb 19 09:28:09 2008 -0700
+++ b/tools/ioemu/hw/pass-through.c     Tue Feb 19 11:14:40 2008 -0700
@@ -29,31 +29,159 @@
 
 extern FILE *logfile;
 
+struct php_dev {
+    struct pt_dev *pt_dev;
+    uint8_t valid;
+    uint8_t r_bus;
+    uint8_t r_dev;
+    uint8_t r_func;
+};
+struct dpci_infos {
+
+    struct php_dev php_devs[PHP_SLOT_LEN];
+
+    PCIBus *e_bus;
+    struct pci_access *pci_access;
+
+} dpci_infos;
+
 static int token_value(char *token)
 {
-    token = strchr(token, 'x') + 1;
     return strtol(token, NULL, 16);
 }
 
 static int next_bdf(char **str, int *seg, int *bus, int *dev, int *func)
 {
-    char *token;
-
-    if ( !(*str) || !strchr(*str, ',') )
+    char *token, *delim = ":.-";
+
+    if ( !(*str) ||
+          ( !strchr(*str, ':') && !strchr(*str, '.')) )
         return 0;
 
-    token = *str;
-    *seg  = token_value(token);
-    token = strchr(token, ',') + 1;
+    token  = strsep(str, delim);
+    *seg = token_value(token);
+
+    token  = strsep(str, delim);
     *bus  = token_value(token);
-    token = strchr(token, ',') + 1;
+
+    token  = strsep(str, delim);
     *dev  = token_value(token);
-    token = strchr(token, ',') + 1;
+
+    token  = strsep(str, delim);
     *func  = token_value(token);
-    token = strchr(token, ',');
-    *str = token ? token + 1 : NULL;
 
     return 1;
+}
+
+/* Insert a new pass-through device into a specific pci slot.
+ * input  dom:bus:dev.func@slot, chose free one if slot == 0
+ * return -1: required slot not available
+ *         0: no free hotplug slots, but normal slot should okay
+ *        >0: the new hotplug slot
+ */
+static int __insert_to_pci_slot(int bus, int dev, int func, int slot)
+{
+    int i, php_slot;
+
+    /* preferred virt pci slot */
+    if ( slot >= PHP_SLOT_START && slot < PHP_SLOT_END )
+    {
+        php_slot = PCI_TO_PHP_SLOT(slot);
+        if ( !dpci_infos.php_devs[php_slot].valid )
+        {
+            goto found;
+        }
+        else
+            return -1;
+    }
+
+    if ( slot != 0 )
+        return -1;
+
+    /* slot == 0, pick up a free one */
+    for ( i = 0; i < PHP_SLOT_LEN; i++ )
+    {
+        if ( !dpci_infos.php_devs[i].valid )
+        {
+            php_slot = i;
+            goto found;
+        }
+    }
+
+    /* not found */
+    return 0;
+
+found:
+    dpci_infos.php_devs[php_slot].valid  = 1;
+    dpci_infos.php_devs[php_slot].r_bus  = bus;
+    dpci_infos.php_devs[php_slot].r_dev  = dev;
+    dpci_infos.php_devs[php_slot].r_func = func;
+    return PHP_TO_PCI_SLOT(php_slot);
+}
+
+/* Insert a new pass-through device into a specific pci slot.
+ * input  dom:bus:dev.func@slot
+ */
+int insert_to_pci_slot(char *bdf_slt)
+{
+    int seg, bus, dev, func, slot;
+    char *bdf_str, *slt_str, *delim="@";
+
+    bdf_str = strsep(&bdf_slt, delim);
+    slt_str = bdf_slt;
+    slot = token_value(slt_str);
+
+    if ( !next_bdf(&bdf_str, &seg, &bus, &dev, &func))
+    {
+        return -1;
+    }
+
+    return __insert_to_pci_slot(bus, dev, func, slot);
+
+}
+
+/* Test if a pci slot has a device
+ * 1:  present
+ * 0:  not present
+ * -1: invalide pci slot input
+ */
+int test_pci_slot(int slot)
+{
+    int php_slot;
+
+    if ( slot < PHP_SLOT_START || slot >= PHP_SLOT_END )
+        return -1;
+
+    php_slot = PCI_TO_PHP_SLOT(slot);
+    if ( dpci_infos.php_devs[php_slot].valid )
+        return 1;
+    else
+        return 0;
+}
+
+/* find the pci slot for pass-through dev with specified BDF */
+int bdf_to_slot(char *bdf_str)
+{
+    int seg, bus, dev, func, i;
+
+    if ( !next_bdf(&bdf_str, &seg, &bus, &dev, &func))
+    {
+        return -1;
+    }
+
+    /* locate the virtual pci slot for this VTd device */
+    for ( i = 0; i < PHP_SLOT_LEN; i++ )
+    {
+        if ( dpci_infos.php_devs[i].valid &&
+           dpci_infos.php_devs[i].r_bus == bus &&
+           dpci_infos.php_devs[i].r_dev  == dev &&
+           dpci_infos.php_devs[i].r_func == func )
+        {
+            return PHP_TO_PCI_SLOT(i);
+        }
+    }
+
+    return -1;
 }
 
 /* Being called each time a mmio region has been updated */
@@ -269,15 +397,64 @@ static int pt_register_regions(struct pt
     return 0;
 }
 
+static int pt_unregister_regions(struct pt_dev *assigned_device)
+{
+    int i, type, ret;
+    uint32_t e_size;
+    PCIDevice *d = (PCIDevice*)assigned_device;
+
+    for ( i = 0; i < PCI_NUM_REGIONS; i++ )
+    {
+        e_size = assigned_device->bases[i].e_size;
+        if ( e_size == 0 )
+            continue;
+
+        type = d->io_regions[i].type;
+
+        if ( type == PCI_ADDRESS_SPACE_MEM ||
+             type == PCI_ADDRESS_SPACE_MEM_PREFETCH )
+        {
+            ret = xc_domain_memory_mapping(xc_handle, domid,
+                    assigned_device->bases[i].e_physbase >> XC_PAGE_SHIFT,
+                    assigned_device->bases[i].access.maddr >> XC_PAGE_SHIFT,
+                    (e_size+XC_PAGE_SIZE-1) >> XC_PAGE_SHIFT,
+                    DPCI_REMOVE_MAPPING);
+            if ( ret != 0 )
+            {
+                PT_LOG("Error: remove old mem mapping failed!\n");
+                continue;
+            }
+
+        }
+        else if ( type == PCI_ADDRESS_SPACE_IO )
+        {
+            ret = xc_domain_ioport_mapping(xc_handle, domid,
+                        assigned_device->bases[i].e_physbase,
+                        assigned_device->bases[i].access.pio_base,
+                        e_size,
+                        DPCI_REMOVE_MAPPING);
+            if ( ret != 0 )
+            {
+                PT_LOG("Error: remove old io mapping failed!\n");
+                continue;
+            }
+
+        }
+        
+    }
+
+}
+
 struct pt_dev * register_real_device(PCIBus *e_bus,
         const char *e_dev_name, int e_devfn, uint8_t r_bus, uint8_t r_dev,
         uint8_t r_func, uint32_t machine_irq, struct pci_access *pci_access)
 {
-    int rc, i;
+    int rc = -1, i;
     struct pt_dev *assigned_device = NULL;
     struct pci_dev *pci_dev;
     uint8_t e_device, e_intx;
     struct pci_config_cf8 machine_bdf;
+    int free_pci_slot = -1;
 
     PT_LOG("Assigning real physical device %02x:%02x.%x ...\n",
         r_bus, r_dev, r_func);
@@ -294,6 +471,15 @@ struct pt_dev * register_real_device(PCI
     {
         PT_LOG("Error: couldn't locate device in libpci structures\n");
         return NULL;
+    }
+
+    if ( e_devfn == PT_VIRT_DEVFN_AUTO ) {
+        /*indicate a static assignment(not hotplug), so find a free PCI hot 
plug slot */
+        free_pci_slot = __insert_to_pci_slot(r_bus, r_dev, r_func, 0);
+        if ( free_pci_slot > 0 )
+            e_devfn = free_pci_slot  << 3;
+        else
+            PT_LOG("Error: no free virtual PCI hot plug slot, thus no live 
migration.\n");
     }
 
     /* Register device */
@@ -306,7 +492,11 @@ struct pt_dev * register_real_device(PCI
         return NULL;
     }
 
+    if ( free_pci_slot > 0 )
+        dpci_infos.php_devs[PCI_TO_PHP_SLOT(free_pci_slot)].pt_dev = 
assigned_device;
+
     assigned_device->pci_dev = pci_dev;
+
 
     /* Assign device */
     machine_bdf.reg = 0;
@@ -355,11 +545,96 @@ struct pt_dev * register_real_device(PCI
     return assigned_device;
 }
 
+int unregister_real_device(int php_slot)
+{
+    struct php_dev *php_dev;
+    struct pci_dev *pci_dev;
+    uint8_t e_device, e_intx;
+    struct pt_dev *assigned_device = NULL;
+    uint32_t machine_irq;
+    uint32_t bdf = 0;
+    int rc = -1;
+
+    if ( php_slot < 0 || php_slot >= PHP_SLOT_LEN )
+       return -1;
+
+    php_dev = &dpci_infos.php_devs[php_slot];
+    assigned_device = php_dev->pt_dev;
+
+    if ( !assigned_device || !php_dev->valid )
+        return -1;
+
+    pci_dev = assigned_device->pci_dev;
+
+    /* hide pci dev from qemu */
+    pci_hide_device((PCIDevice*)assigned_device);
+
+    /* Unbind interrupt */
+    e_device = (assigned_device->dev.devfn >> 3) & 0x1f;
+    e_intx = assigned_device->dev.config[0x3d]-1;
+    machine_irq = pci_dev->irq;
+
+    if ( machine_irq != 0 ) {
+        rc = xc_domain_unbind_pt_irq(xc_handle, domid, machine_irq, 
PT_IRQ_TYPE_PCI, 0,
+                                       e_device, e_intx, 0);
+        if ( rc < 0 )
+        {
+            /* TBD: unregister device in case of an error */
+            PT_LOG("Error: Unbinding of interrupt failed! rc=%d\n", rc);
+        }
+    }
+
+    /* unregister real device's MMIO/PIO BARs */
+    pt_unregister_regions(assigned_device);
+    
+    /* deassign the dev to dom0 */
+    bdf |= (pci_dev->bus  & 0xff) << 16;
+    bdf |= (pci_dev->dev  & 0x1f) << 11;
+    bdf |= (pci_dev->func & 0x1f) << 8;
+    if ( (rc = xc_deassign_device(xc_handle, domid, bdf)) != 0)
+        PT_LOG("Error: Revoking the device failed! rc=%d\n", rc);
+
+    /* mark this slot as free */
+    php_dev->valid = 0;
+    php_dev->pt_dev = NULL;
+    qemu_free(assigned_device);
+
+    return 0;
+}
+
+int power_on_php_slot(int php_slot)
+{
+    struct php_dev *php_dev = &dpci_infos.php_devs[php_slot];
+    int pci_slot = php_slot + PHP_SLOT_START;
+    struct pt_dev *pt_dev;
+    pt_dev = 
+        register_real_device(dpci_infos.e_bus,
+            "DIRECT PCI",
+            pci_slot << 3,
+            php_dev->r_bus,
+            php_dev->r_dev,
+            php_dev->r_func,
+            PT_MACHINE_IRQ_AUTO,
+            dpci_infos.pci_access);
+
+    php_dev->pt_dev = pt_dev;
+
+    return 0;
+
+}
+
+int power_off_php_slot(int php_slot)
+{
+    return unregister_real_device(php_slot);
+}
+
 int pt_init(PCIBus *e_bus, char *direct_pci)
 {
-    int seg, b, d, f;
+    int seg, b, d, f, php_slot = 0;
     struct pt_dev *pt_dev;
     struct pci_access *pci_access;
+    char *vslots;
+    char slot_str[8];
 
     /* Initialize libpci */
     pci_access = pci_alloc();
@@ -370,6 +645,19 @@ int pt_init(PCIBus *e_bus, char *direct_
     }
     pci_init(pci_access);
     pci_scan_bus(pci_access);
+
+    memset(&dpci_infos, 0, sizeof(struct dpci_infos));
+    dpci_infos.pci_access = pci_access;
+    dpci_infos.e_bus      = e_bus;
+
+    if ( strlen(direct_pci) == 0 ) {
+        return 0;
+    }
+
+    /* the virtual pci slots of all pass-through devs
+     * with hex format: xx;xx...;
+     */
+    vslots = qemu_mallocz ( strlen(direct_pci) / 3 );
 
     /* Assign given devices to guest */
     while ( next_bdf(&direct_pci, &seg, &b, &d, &f) )
@@ -382,7 +670,24 @@ int pt_init(PCIBus *e_bus, char *direct_
             PT_LOG("Error: Registration failed (%02x:%02x.%x)\n", b, d, f);
             return -1;
         }
-    }
+
+        /* Record the virtual slot info */
+        if ( php_slot < PHP_SLOT_LEN &&
+              dpci_infos.php_devs[php_slot].pt_dev == pt_dev )
+        {
+            sprintf(slot_str, "0x%x;", PHP_TO_PCI_SLOT(php_slot));
+        }
+        else
+            sprintf(slot_str, "0x%x;", 0);
+
+        strcat(vslots, slot_str);
+        php_slot++;
+    }
+
+    /* Write virtual slots info to xenstore for Control panel use */
+    xenstore_write_vslots(vslots);
+
+    qemu_free(vslots);
 
     /* Success */
     return 0;
diff -r 63b0a8cb56ff -r f853c0497095 tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c       Tue Feb 19 09:28:09 2008 -0700
+++ b/tools/ioemu/hw/pc.c       Tue Feb 19 11:14:40 2008 -0700
@@ -945,8 +945,10 @@ static void pc_init1(uint64_t ram_size, 
     }
 
 #ifdef CONFIG_PASSTHROUGH
-    /* Pass-through Initialization */
-    if ( pci_enabled && direct_pci )
+    /* Pass-through Initialization
+     * init libpci even direct_pci is null, as can hotplug a dev runtime
+     */
+    if ( pci_enabled )
     {
         rc = pt_init(pci_bus, direct_pci); 
         if ( rc < 0 )
diff -r 63b0a8cb56ff -r f853c0497095 tools/ioemu/hw/pci.c
--- a/tools/ioemu/hw/pci.c      Tue Feb 19 09:28:09 2008 -0700
+++ b/tools/ioemu/hw/pci.c      Tue Feb 19 11:14:40 2008 -0700
@@ -107,7 +107,8 @@ PCIDevice *pci_register_device(PCIBus *b
     
     if (devfn < 0) {
         for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
-            if (!bus->devices[devfn])
+            if ( !bus->devices[devfn] &&
+                 !( devfn >= PHP_DEVFN_START && devfn < PHP_DEVFN_END ) )
                 goto found;
         }
         return NULL;
@@ -130,6 +131,12 @@ PCIDevice *pci_register_device(PCIBus *b
     pci_dev->irq_index = pci_irq_index++;
     bus->devices[devfn] = pci_dev;
     return pci_dev;
+}
+
+void pci_hide_device(PCIDevice *pci_dev)
+{
+    PCIBus *bus = pci_dev->bus;
+    bus->devices[pci_dev->devfn] = NULL;
 }
 
 void pci_register_io_region(PCIDevice *pci_dev, int region_num, 
diff -r 63b0a8cb56ff -r f853c0497095 tools/ioemu/hw/piix4acpi.c
--- a/tools/ioemu/hw/piix4acpi.c        Tue Feb 19 09:28:09 2008 -0700
+++ b/tools/ioemu/hw/piix4acpi.c        Tue Feb 19 11:14:40 2008 -0700
@@ -24,6 +24,7 @@
  */
 
 #include "vl.h"
+#include <xen/hvm/ioreq.h>
 
 /* PM1a_CNT bits, as defined in the ACPI specification. */
 #define SCI_EN            (1 <<  0)
@@ -33,7 +34,21 @@
 
 /* Sleep state type codes as defined by the \_Sx objects in the DSDT. */
 /* These must be kept in sync with the DSDT (hvmloader/acpi/dsdt.asl) */
+#define SLP_TYP_S4        (6 << 10)
 #define SLP_TYP_S5        (7 << 10)
+
+#define ACPI_DBG_IO_ADDR  0xb044
+#define ACPI_PHP_IO_ADDR  0x10c0
+
+#define PHP_EVT_ADD     0x0
+#define PHP_EVT_REMOVE  0x3
+
+#define ACPI_SCI_IRQ 9
+
+/* The bit in GPE0_STS/EN to notify the pci hotplug event */
+#define ACPI_PHP_GPE_BIT 3
+
+#define ACPI_PHP_SLOT_NUM PHP_SLOT_LEN
 
 typedef struct AcpiDeviceState AcpiDeviceState;
 AcpiDeviceState *acpi_device_table;
@@ -42,6 +57,27 @@ typedef struct PCIAcpiState {
     PCIDevice dev;
     uint16_t pm1_control; /* pm1a_ECNT_BLK */
 } PCIAcpiState;
+
+typedef struct GPEState {
+    /* GPE0 block */
+    uint8_t gpe0_sts[ACPI_GPE0_BLK_LEN / 2];
+    uint8_t gpe0_en[ACPI_GPE0_BLK_LEN / 2];
+
+    /* SCI IRQ level */
+    uint8_t sci_asserted;
+
+} GPEState;
+
+GPEState gpe_state;
+
+typedef struct PHPSlots {
+    struct {
+        uint8_t status;    /* Apaptor stats */
+    } slot[ACPI_PHP_SLOT_NUM];
+    uint8_t plug_evt;      /* slot|event slot:0-no event;1-1st. 
event:0-remove;1-add */
+} PHPSlots;
+
+PHPSlots php_slots;
 
 static void piix4acpi_save(QEMUFile *f, void *opaque)
 {
@@ -58,7 +94,7 @@ static int piix4acpi_load(QEMUFile *f, v
         return -EINVAL;
     ret = pci_device_load(&s->dev, f);
     if (ret < 0)
-       return ret;
+        return ret;
     qemu_get_be16s(f, &s->pm1_control);
     return 0;
 }
@@ -76,6 +112,21 @@ static uint32_t acpiPm1Control_readb(voi
     return (uint8_t)(s->pm1_control & ~(GBL_RLS|SLP_EN));
 }
 
+static void acpi_shutdown(uint32_t val)
+{
+    if (!(val & SLP_EN))
+        return;
+
+    switch (val & SLP_TYP_Sx) {
+    case SLP_TYP_S4:
+    case SLP_TYP_S5:
+        qemu_system_shutdown_request();
+        break;
+    default:
+        break;
+    }
+}
+
 static void acpiPm1ControlP1_writeb(void *opaque, uint32_t addr, uint32_t val)
 {
     PCIAcpiState *s = opaque;
@@ -83,9 +134,7 @@ static void acpiPm1ControlP1_writeb(void
     val <<= 8;
     s->pm1_control = ((s->pm1_control & 0xff) | val) & ~SLP_EN;
 
-    /* Check for power off request. */
-    if ((val & (SLP_EN|SLP_TYP_Sx)) == (SLP_EN|SLP_TYP_S5))
-        qemu_system_shutdown_request();
+    acpi_shutdown(val);
 }
 
 static uint32_t acpiPm1ControlP1_readb(void *opaque, uint32_t addr)
@@ -101,9 +150,7 @@ static void acpiPm1Control_writew(void *
 
     s->pm1_control = val & ~SLP_EN;
 
-    /* Check for power off request. */
-    if ((val & (SLP_EN|SLP_TYP_Sx)) == (SLP_EN|SLP_TYP_S5))
-        qemu_system_shutdown_request();
+    acpi_shutdown(val);
 }
 
 static uint32_t acpiPm1Control_readw(void *opaque, uint32_t addr)
@@ -114,7 +161,7 @@ static uint32_t acpiPm1Control_readw(voi
 }
 
 static void acpi_map(PCIDevice *pci_dev, int region_num,
-                    uint32_t addr, uint32_t size, int type)
+                     uint32_t addr, uint32_t size, int type)
 {
     PCIAcpiState *d = (PCIAcpiState *)pci_dev;
 
@@ -128,6 +175,326 @@ static void acpi_map(PCIDevice *pci_dev,
     register_ioport_write(addr + 4, 2, 2, acpiPm1Control_writew, d);
     register_ioport_read(addr + 4, 2, 2, acpiPm1Control_readw, d);
 }
+
+#ifdef CONFIG_PASSTHROUGH
+
+static inline int test_bit(uint8_t *map, int bit)
+{
+    return ( map[bit / 8] & (1 << (bit % 8)) );
+}
+
+static inline void set_bit(uint8_t *map, int bit)
+{
+    map[bit / 8] |= (1 << (bit % 8));
+}
+
+static inline void clear_bit(uint8_t *map, int bit)
+{
+    map[bit / 8] &= ~(1 << (bit % 8));
+}
+
+extern FILE *logfile;
+static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
+{
+#if defined(DEBUG)
+    printf("ACPI: DBG: 0x%08x\n", val);
+#endif
+    fprintf(logfile, "ACPI:debug: write addr=0x%x, val=0x%x.\n", addr, val);
+}
+
+/*
+ * simple PCI hotplug controller IO 
+ * ACPI_PHP_IO_ADDR + :
+ * 0 - the hotplug description: slot(|event(remove/add); 
+ * 1 - 1st php slot ctr/sts reg
+ * 2 - 2nd php slot ctr/sts reg
+ * ......
+ */
+static uint32_t acpi_php_readb(void *opaque, uint32_t addr)
+{
+    PHPSlots *hotplug_slots = opaque;
+    int num;
+    uint32_t val; 
+
+    switch (addr)
+    {
+    case ACPI_PHP_IO_ADDR:
+        val = hotplug_slots->plug_evt;
+        break;
+    default:
+        num = addr - ACPI_PHP_IO_ADDR - 1;
+        val = hotplug_slots->slot[num].status;
+    }
+
+    fprintf(logfile, "ACPI PCI hotplug: read addr=0x%x, val=0x%x.\n",
+            addr, val);
+
+    return val;
+}
+
+static void acpi_php_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+    PHPSlots *hotplug_slots = opaque;
+    int php_slot;
+
+    fprintf(logfile, "ACPI PCI hotplug: write addr=0x%x, val=0x%x.\n",
+            addr, val);
+
+    switch (addr)
+    {
+    case ACPI_PHP_IO_ADDR:
+        break;
+    default:
+        php_slot = addr - ACPI_PHP_IO_ADDR - 1;
+        if ( val == 0x1 ) { /* Eject command */
+            /* make _STA of the slot 0 */
+            hotplug_slots->slot[php_slot].status = 0;
+
+            /* clear the hotplug event */
+            hotplug_slots->plug_evt = 0;
+
+            /* power off the slot */
+            power_off_php_slot(php_slot);
+
+            /* signal the CP ACPI hot remove done. */
+            xenstore_record_dm_state("pci-removed");
+        }
+    }
+}
+
+static void pcislots_save(QEMUFile* f, void* opaque)
+{
+    PHPSlots *s = (PHPSlots*)opaque;
+    int i;
+    for ( i = 0; i < ACPI_PHP_SLOT_NUM; i++ ) {
+        qemu_put_8s( f, &s->slot[i].status);
+    }
+    qemu_put_8s(f, &s->plug_evt);
+}
+
+static int pcislots_load(QEMUFile* f, void* opaque, int version_id)
+{
+    PHPSlots *s = (PHPSlots*)opaque;
+    int i;
+    if (version_id != 1)
+        return -EINVAL;
+    for ( i = 0; i < ACPI_PHP_SLOT_NUM; i++ ) {
+        qemu_get_8s( f, &s->slot[i].status);
+    }
+    qemu_get_8s(f, &s->plug_evt);
+    return 0;
+}
+
+static void php_slots_init(void)
+{
+    PHPSlots *slots = &php_slots;
+    int i;
+    memset(slots, 0, sizeof(PHPSlots));
+
+    /* update the pci slot status */
+    for ( i = 0; i < PHP_SLOT_LEN; i++ ) {
+        if ( test_pci_slot( PHP_TO_PCI_SLOT(i) ) == 1 )
+            slots->slot[i].status = 0xf;
+    }
+
+
+    /* ACPI PCI hotplug controller */
+    register_ioport_read(ACPI_PHP_IO_ADDR, ACPI_PHP_SLOT_NUM + 1, 1, 
acpi_php_readb, slots);
+    register_ioport_write(ACPI_PHP_IO_ADDR, ACPI_PHP_SLOT_NUM + 1, 1, 
acpi_php_writeb, slots);
+    register_savevm("pcislots", 0, 1, pcislots_save, pcislots_load, slots);
+}
+
+/* GPEx_STS occupy 1st half of the block, while GPEx_EN 2nd half */
+static uint32_t gpe_sts_read(void *opaque, uint32_t addr)
+{
+    GPEState *s = opaque;
+
+    return s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS];
+}
+
+/* write 1 to clear specific GPE bits */
+static void gpe_sts_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    GPEState *s = opaque;
+    int hotplugged = 0;
+
+    fprintf(logfile, "gpe_sts_write: addr=0x%x, val=0x%x.\n", addr, val);
+
+    hotplugged = test_bit(&s->gpe0_sts[0], ACPI_PHP_GPE_BIT);
+    s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS] &= ~val;
+    if ( s->sci_asserted &&
+         hotplugged &&
+         !test_bit(&s->gpe0_sts[0], ACPI_PHP_GPE_BIT)) {
+        fprintf(logfile, "Clear the GPE0_STS bit for ACPI hotplug & deassert 
the IRQ.\n");
+        pic_set_irq(ACPI_SCI_IRQ, 0);
+    }
+
+}
+
+static uint32_t gpe_en_read(void *opaque, uint32_t addr)
+{
+    GPEState *s = opaque;
+
+    return s->gpe0_en[addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2)];
+}
+
+/* write 0 to clear en bit */
+static void gpe_en_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    GPEState *s = opaque;
+    int reg_count;
+
+    fprintf(logfile, "gpe_en_write: addr=0x%x, val=0x%x.\n", addr, val);
+    reg_count = addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2);
+    s->gpe0_en[reg_count] = val;
+    /* If disable GPE bit right after generating SCI on it, 
+     * need deassert the intr to avoid redundant intrs
+     */
+    if ( s->sci_asserted &&
+         reg_count == (ACPI_PHP_GPE_BIT / 8) &&
+         !(val & (1 << (ACPI_PHP_GPE_BIT % 8))) ) {
+        fprintf(logfile, "deassert due to disable GPE bit.\n");
+        s->sci_asserted = 0;
+        pic_set_irq(ACPI_SCI_IRQ, 0);
+    }
+
+}
+
+static void gpe_save(QEMUFile* f, void* opaque)
+{
+    GPEState *s = (GPEState*)opaque;
+    int i;
+
+    for ( i = 0; i < ACPI_GPE0_BLK_LEN / 2; i++ ) {
+        qemu_put_8s(f, &s->gpe0_sts[i]);
+        qemu_put_8s(f, &s->gpe0_en[i]);
+    }
+
+    qemu_put_8s(f, &s->sci_asserted);
+    if ( s->sci_asserted ) {
+        fprintf(logfile, "gpe_save with sci asserted!\n");
+    }
+}
+
+static int gpe_load(QEMUFile* f, void* opaque, int version_id)
+{
+    GPEState *s = (GPEState*)opaque;
+    int i;
+    if (version_id != 1)
+        return -EINVAL;
+
+    for ( i = 0; i < ACPI_GPE0_BLK_LEN / 2; i++ ) {
+        qemu_get_8s(f, &s->gpe0_sts[i]);
+        qemu_get_8s(f, &s->gpe0_en[i]);
+    }
+
+    qemu_get_8s(f, &s->sci_asserted);
+    return 0;
+}
+
+static void gpe_acpi_init(void)
+{
+    GPEState *s = &gpe_state;
+    memset(s, 0, sizeof(GPEState));
+
+    register_ioport_read(ACPI_GPE0_BLK_ADDRESS,
+                         ACPI_GPE0_BLK_LEN / 2,
+                         1,
+                         gpe_sts_read,
+                         s);
+    register_ioport_read(ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2,
+                         ACPI_GPE0_BLK_LEN / 2,
+                         1,
+                         gpe_en_read,
+                         s);
+
+    register_ioport_write(ACPI_GPE0_BLK_ADDRESS,
+                          ACPI_GPE0_BLK_LEN / 2,
+                          1,
+                          gpe_sts_write,
+                          s);
+    register_ioport_write(ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2,
+                          ACPI_GPE0_BLK_LEN / 2,
+                          1,
+                          gpe_en_write,
+                          s);
+
+    register_savevm("gpe", 0, 1, gpe_save, gpe_load, s);
+}
+
+static void acpi_sci_intr(GPEState *s)
+{
+    if ( !test_bit(&s->gpe0_sts[0], ACPI_PHP_GPE_BIT) &&
+         test_bit(&s->gpe0_en[0], ACPI_PHP_GPE_BIT) ) {
+
+        set_bit(&s->gpe0_sts[0], ACPI_PHP_GPE_BIT);
+        s->sci_asserted = 1;
+        pic_set_irq(ACPI_SCI_IRQ, 1);
+        fprintf(logfile, "generate a sci for PHP.\n");
+    }
+}
+
+void acpi_php_del(int pci_slot)
+{
+    GPEState *s = &gpe_state;
+    PHPSlots *hotplug_slots = &php_slots;
+    int php_slot = PCI_TO_PHP_SLOT(pci_slot);
+
+    if ( pci_slot < PHP_SLOT_START || pci_slot >= PHP_SLOT_END ) {
+        fprintf(logfile, "not find the pci slot %d when hot remove.\n", 
pci_slot);
+
+        return;
+    }
+
+    /* update the php controller status */
+    hotplug_slots->plug_evt = (((php_slot+1) << 4) | PHP_EVT_REMOVE);
+
+    /* generate a SCI interrupt */
+    acpi_sci_intr(s);
+}
+
+void acpi_php_add(int pci_slot)
+{
+    GPEState *s = &gpe_state;
+    PHPSlots *hotplug_slots = &php_slots;
+    int php_slot = PCI_TO_PHP_SLOT(pci_slot);
+    char ret_str[30];
+
+    if ( pci_slot < PHP_SLOT_START || pci_slot >= PHP_SLOT_END ) {
+        fprintf(logfile, "hot add pci slot %d exceed.\n", pci_slot);
+
+        if ( pci_slot == 0 )
+            sprintf(ret_str, "no free hotplug slots");
+        else if ( pci_slot == -1 )
+            sprintf(ret_str, "wrong bdf or vslot");
+
+        if ( strlen(ret_str) > 0 )
+            xenstore_record_dm("parameter", ret_str);
+
+        return;
+    }
+
+    /* update the php controller status */
+    hotplug_slots->plug_evt = (((php_slot+1) << 4) | PHP_EVT_ADD);
+
+    /* update the slot status as present */
+    hotplug_slots->slot[php_slot].status = 0xf;
+
+    /* power on the slot */
+    power_on_php_slot(php_slot);
+
+    /* tell Control panel which slot for the new pass-throgh dev */
+    sprintf(ret_str, "0x%x", pci_slot);
+    xenstore_record_dm("parameter", ret_str);
+
+    /* signal the CP ACPI hot insert done */
+    xenstore_record_dm_state("pci-inserted");
+
+    /* generate a SCI interrupt */
+    acpi_sci_intr(s);
+}
+
+#endif /* CONFIG_PASSTHROUGH */
 
 /* PIIX4 acpi pci configuration space, func 2 */
 void pci_piix4_acpi_init(PCIBus *bus, int devfn)
@@ -168,5 +535,11 @@ void pci_piix4_acpi_init(PCIBus *bus, in
 
     acpi_map((PCIDevice *)d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
 
+#ifdef CONFIG_PASSTHROUGH
+    gpe_acpi_init();
+    php_slots_init();
+    register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, d);
+#endif
+
     register_savevm("piix4acpi", 0, 1, piix4acpi_save, piix4acpi_load, d);
 }
diff -r 63b0a8cb56ff -r f853c0497095 tools/ioemu/monitor.c
--- a/tools/ioemu/monitor.c     Tue Feb 19 09:28:09 2008 -0700
+++ b/tools/ioemu/monitor.c     Tue Feb 19 11:14:40 2008 -0700
@@ -1280,6 +1280,12 @@ static term_cmd_t term_cmds[] = {
       "device", "add USB device (e.g. 'host:bus.addr' or 
'host:vendor_id:product_id')" },
     { "usb_del", "s", do_usb_del,
       "device", "remove USB device 'bus.addr'" },
+#ifdef CONFIG_PHP_DEBUG
+    { "pci_add", "s", do_pci_add,
+      "device", "insert PCI pass-through device by BDF,e.g. (dom, bus, dev, 
func) by hex '0x0, 0x3, 0x0, 0x0'" },
+    { "pci_del", "s", do_pci_del,
+      "device", "remove PCI pass-through device by BDF,e.g. (dom, bus, dev, 
func) by hex '0x0, 0x3, 0x0, 0x0'" },
+#endif
 #ifndef CONFIG_DM
     { "cpu", "i", do_cpu_set, 
       "index", "set the default CPU" },
diff -r 63b0a8cb56ff -r f853c0497095 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Tue Feb 19 09:28:09 2008 -0700
+++ b/tools/ioemu/vl.c  Tue Feb 19 11:14:40 2008 -0700
@@ -4382,6 +4382,23 @@ void usb_info(void)
     }
 }
 
+void do_pci_del(char *devname)
+{
+#ifdef CONFIG_PASSTHROUGH
+    int pci_slot = bdf_to_slot(devname);
+    acpi_php_del(pci_slot);
+#endif
+}
+
+void do_pci_add(char *devname)
+{
+#ifdef CONFIG_PASSTHROUGH
+    int pci_slot = insert_to_pci_slot(devname);
+    acpi_php_add(pci_slot);
+#endif
+}
+
+
 /***********************************************************/
 /* pid file */
 
@@ -7067,7 +7084,7 @@ int main(int argc, char **argv)
 #endif
     sigset_t set;
     char qemu_dm_logfilename[128];
-    const char *direct_pci = NULL;
+    const char *direct_pci = direct_pci_str;
 
 #if !defined(__sun__) && !defined(CONFIG_STUBDOM)
     /* Maximise rlimits. Needed where default constraints are tight (*BSD). */
@@ -7590,9 +7607,6 @@ int main(int argc, char **argv)
             case QEMU_OPTION_vncunused:
                 vncunused++;
                 break;
-            case QEMU_OPTION_pci:
-                direct_pci = optarg;
-                break;
             }
         }
     }
diff -r 63b0a8cb56ff -r f853c0497095 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Tue Feb 19 09:28:09 2008 -0700
+++ b/tools/ioemu/vl.h  Tue Feb 19 11:14:40 2008 -0700
@@ -817,10 +817,14 @@ struct PCIDevice {
     int irq_state[4];
 };
 
+extern char direct_pci_str[];
+
 PCIDevice *pci_register_device(PCIBus *bus, const char *name,
                                int instance_size, int devfn,
                                PCIConfigReadFunc *config_read, 
                                PCIConfigWriteFunc *config_write);
+
+void pci_hide_device(PCIDevice *pci_dev);
 
 void pci_register_io_region(PCIDevice *pci_dev, int region_num, 
                             uint32_t size, int type, 
@@ -849,6 +853,21 @@ void pci_info(void);
 void pci_info(void);
 PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
                         pci_map_irq_fn map_irq, const char *name);
+
+/* PCI slot 6~7 support ACPI PCI hot plug */
+#define PHP_SLOT_START  (6)
+#define PHP_SLOT_END    (8)
+#define PHP_SLOT_LEN    (PHP_SLOT_END - PHP_SLOT_START)
+#define PHP_TO_PCI_SLOT(x) (x + PHP_SLOT_START)
+#define PCI_TO_PHP_SLOT(x) (x - PHP_SLOT_START)
+#define PHP_DEVFN_START (PHP_SLOT_START << 3)
+#define PHP_DEVFN_END   (PHP_SLOT_END << 3)
+
+int insert_to_pci_slot(char*);
+int test_pci_slot(int);
+int bdf_to_slot(char*);
+int power_on_php_slot(int);
+int power_off_php_slot(int);
 
 /* prep_pci.c */
 PCIBus *pci_prep_init(void);
@@ -1120,6 +1139,9 @@ void tpm_tis_init(SetIRQFunc *set_irq, v
 
 /* piix4acpi.c */
 extern void pci_piix4_acpi_init(PCIBus *bus, int devfn);
+void acpi_php_add(int);
+void acpi_php_del(int);
+
 
 /* pc.c */
 extern QEMUMachine pc_machine;
@@ -1320,6 +1342,9 @@ void do_usb_del(const char *devname);
 void do_usb_del(const char *devname);
 void usb_info(void);
 
+void do_pci_add(char *devname);
+void do_pci_del(char *devname);
+
 /* scsi-disk.c */
 enum scsi_reason {
     SCSI_REASON_DONE, /* Command complete.  */
@@ -1466,10 +1491,12 @@ void xenstore_parse_domain_config(int do
 void xenstore_parse_domain_config(int domid);
 int xenstore_fd(void);
 void xenstore_process_event(void *opaque);
+void xenstore_record_dm(char *subpath, char *state);
 void xenstore_record_dm_state(char *state);
 void xenstore_check_new_media_present(int timeout);
 void xenstore_write_vncport(int vnc_display);
 void xenstore_read_vncpasswd(int domid, char *pwbuf, size_t pwbuflen);
+void xenstore_write_vslots(char *vslots);
 
 int xenstore_domain_has_devtype(struct xs_handle *handle,
                                 const char *devtype);
diff -r 63b0a8cb56ff -r f853c0497095 tools/ioemu/xenstore.c
--- a/tools/ioemu/xenstore.c    Tue Feb 19 09:28:09 2008 -0700
+++ b/tools/ioemu/xenstore.c    Tue Feb 19 11:14:40 2008 -0700
@@ -79,6 +79,8 @@ static void waitForDevice(char *fn)
     return;
 }
 
+#define DIRECT_PCI_STR_LEN 160
+char direct_pci_str[DIRECT_PCI_STR_LEN];
 void xenstore_parse_domain_config(int domid)
 {
     char **e = NULL;
@@ -86,7 +88,7 @@ void xenstore_parse_domain_config(int do
     char *fpath = NULL, *bpath = NULL,
         *dev = NULL, *params = NULL, *type = NULL, *drv = NULL;
     int i, is_scsi, is_hdN = 0;
-    unsigned int len, num, hd_index;
+    unsigned int len, num, hd_index, pci_devid = 0;
     BlockDriverState *bs;
 
     for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++)
@@ -250,6 +252,38 @@ void xenstore_parse_domain_config(int do
         fprintf(logfile, "Watching %s\n", buf);
     }
 
+    /* get the pci pass-through parameter */
+    if (pasprintf(&buf, "/local/domain/0/backend/pci/%u/%u/num_devs",
+                  domid, pci_devid) == -1)
+        goto out;
+
+    free(params);
+    params = xs_read(xsh, XBT_NULL, buf, &len);
+    if (params == NULL)
+        goto out;
+    num = atoi(params);
+
+    for ( i = 0; i < num; i++ ) {
+        if (pasprintf(&buf, "/local/domain/0/backend/pci/%u/%u/dev-%d",
+                    domid, pci_devid, i) != -1) {
+            free(dev);
+            dev = xs_read(xsh, XBT_NULL, buf, &len);
+
+            if ( strlen(dev) + strlen(direct_pci_str) > DIRECT_PCI_STR_LEN ) {
+                fprintf(stderr, "qemu: too many pci pass-through devices\n");
+                memset(direct_pci_str, 0, DIRECT_PCI_STR_LEN);
+                goto out;
+            }
+
+            /* append to direct_pci_str */
+            if ( dev ) {
+                strcat(direct_pci_str, dev);
+                strcat(direct_pci_str, "-");
+            }
+        }
+    }
+
+
  out:
     free(type);
     free(params);
@@ -388,7 +422,7 @@ void xenstore_process_logdirty_event(voi
 /* Accept state change commands from the control tools */
 static void xenstore_process_dm_command_event(void)
 {
-    char *path = NULL, *command = NULL;
+    char *path = NULL, *command = NULL, *par = NULL;
     unsigned int len;
     extern int suspend_requested;
 
@@ -407,6 +441,34 @@ static void xenstore_process_dm_command_
     } else if (!strncmp(command, "continue", len)) {
         fprintf(logfile, "dm-command: continue after state save\n");
         suspend_requested = 0;
+    } else if (!strncmp(command, "pci-rem", len)) {
+        fprintf(logfile, "dm-command: hot remove pass-through pci dev \n");
+
+        if (pasprintf(&path, 
+                      "/local/domain/0/device-model/%u/parameter", domid) == 
-1) {
+            fprintf(logfile, "out of memory reading dm command parameter\n");
+            goto out;
+        }
+        par = xs_read(xsh, XBT_NULL, path, &len);
+        if (!par)
+            goto out;
+
+        do_pci_del(par);
+        free(par);
+    } else if (!strncmp(command, "pci-ins", len)) {
+        fprintf(logfile, "dm-command: hot insert pass-through pci dev \n");
+
+        if (pasprintf(&path, 
+                      "/local/domain/0/device-model/%u/parameter", domid) == 
-1) {
+            fprintf(logfile, "out of memory reading dm command parameter\n");
+            goto out;
+        }
+        par = xs_read(xsh, XBT_NULL, path, &len);
+        if (!par)
+            goto out;
+
+        do_pci_add(par);
+        free(par);
     } else {
         fprintf(logfile, "dm-command: unknown command\"%*s\"\n", len, command);
     }
@@ -416,20 +478,25 @@ static void xenstore_process_dm_command_
     free(command);
 }
 
+void xenstore_record_dm(char *subpath, char *state)
+{
+    char *path = NULL;
+
+    if (pasprintf(&path, 
+                  "/local/domain/0/device-model/%u/%s", domid, subpath) == -1) 
{
+        fprintf(logfile, "out of memory recording dm \n");
+        goto out;
+    }
+    if (!xs_write(xsh, XBT_NULL, path, state, strlen(state)))
+        fprintf(logfile, "error recording dm \n");
+
+ out:
+    free(path);
+}
+
 void xenstore_record_dm_state(char *state)
 {
-    char *path = NULL;
-
-    if (pasprintf(&path, 
-                  "/local/domain/0/device-model/%u/state", domid) == -1) {
-        fprintf(logfile, "out of memory recording dm state\n");
-        goto out;
-    }
-    if (!xs_write(xsh, XBT_NULL, path, state, strlen(state)))
-        fprintf(logfile, "error recording dm state\n");
-
- out:
-    free(path);
+    xenstore_record_dm("state", state);
 }
 
 void xenstore_process_event(void *opaque)
@@ -520,6 +587,23 @@ void xenstore_write_vncport(int display)
  out:
     free(portstr);
     free(buf);
+}
+
+void xenstore_write_vslots(char *vslots)
+{
+    char *path = NULL;
+    int pci_devid = 0;
+
+    if (pasprintf(&path, 
+                  "/local/domain/0/backend/pci/%u/%u/vslots", domid, 
pci_devid) == -1) {
+        fprintf(logfile, "out of memory when updating vslots.\n");
+        goto out;
+    }
+    if (!xs_write(xsh, XBT_NULL, path, vslots, strlen(vslots)))
+        fprintf(logfile, "error updating vslots \n");
+
+ out:
+    free(path);
 }
 
 void xenstore_read_vncpasswd(int domid, char *pwbuf, size_t pwbuflen)
diff -r 63b0a8cb56ff -r f853c0497095 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Tue Feb 19 09:28:09 2008 -0700
+++ b/tools/libxc/xc_domain.c   Tue Feb 19 11:14:40 2008 -0700
@@ -762,6 +762,20 @@ int xc_test_assign_device(
     return do_domctl(xc_handle, &domctl);
 }
 
+int xc_deassign_device(
+    int xc_handle,
+    uint32_t domid,
+    uint32_t machine_bdf)
+{
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_deassign_device;
+    domctl.domain = domid;
+    domctl.u.assign_device.machine_bdf = machine_bdf;
+ 
+    return do_domctl(xc_handle, &domctl);
+}
+
 /* Pass-through: binds machine irq to guests irq */
 int xc_domain_bind_pt_irq(
     int xc_handle,
@@ -797,6 +811,36 @@ int xc_domain_bind_pt_irq(
     return rc;
 }
 
+int xc_domain_unbind_pt_irq(
+    int xc_handle,
+    uint32_t domid,
+    uint8_t machine_irq,
+    uint8_t irq_type,
+    uint8_t bus,
+    uint8_t device,
+    uint8_t intx,
+    uint8_t isa_irq)
+{
+    int rc;
+    xen_domctl_bind_pt_irq_t * bind;
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_unbind_pt_irq;
+    domctl.domain = (domid_t)domid;
+
+    bind = &(domctl.u.bind_pt_irq);
+    bind->hvm_domid = domid;
+    bind->irq_type = irq_type;
+    bind->machine_irq = machine_irq;
+    bind->u.pci.bus = bus;
+    bind->u.pci.device = device;    
+    bind->u.pci.intx = intx;
+    bind->u.isa.isa_irq = isa_irq;
+    
+    rc = do_domctl(xc_handle, &domctl);
+    return rc;
+}
+
 int xc_domain_bind_pt_pci_irq(
     int xc_handle,
     uint32_t domid,
diff -r 63b0a8cb56ff -r f853c0497095 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Tue Feb 19 09:28:09 2008 -0700
+++ b/tools/libxc/xenctrl.h     Tue Feb 19 11:14:40 2008 -0700
@@ -914,6 +914,10 @@ int xc_test_assign_device(int xc_handle,
                           uint32_t domid,
                           uint32_t machine_bdf);
 
+int xc_deassign_device(int xc_handle,
+                     uint32_t domid,
+                     uint32_t machine_bdf);
+
 int xc_domain_memory_mapping(int xc_handle,
                              uint32_t domid,
                              unsigned long first_gfn,
@@ -937,6 +941,15 @@ int xc_domain_bind_pt_irq(int xc_handle,
                           uint8_t intx,
                           uint8_t isa_irq);
 
+int xc_domain_unbind_pt_irq(int xc_handle,
+                          uint32_t domid,
+                          uint8_t machine_irq,
+                          uint8_t irq_type,
+                          uint8_t bus,
+                          uint8_t device,
+                          uint8_t intx,
+                          uint8_t isa_irq);
+
 int xc_domain_bind_pt_pci_irq(int xc_handle,
                               uint32_t domid,
                               uint8_t machine_irq,
diff -r 63b0a8cb56ff -r f853c0497095 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Tue Feb 19 09:28:09 2008 -0700
+++ b/tools/python/xen/xend/XendDomainInfo.py   Tue Feb 19 11:14:40 2008 -0700
@@ -516,6 +516,131 @@ class XendDomainInfo:
         asserts.isCharConvertible(key)
         self.storeDom("control/sysrq", '%c' % key)
 
+    def sync_pcidev_info(self):
+
+        if not self.info.is_hvm():
+            return
+
+        devid = '0'
+        dev_info = self._getDeviceInfo_pci(devid)
+        if dev_info is None:
+            return
+
+        # get the virtual slot info from xenstore
+        dev_uuid = sxp.child_value(dev_info, 'uuid')
+        pci_conf = self.info['devices'][dev_uuid][1]
+        pci_devs = pci_conf['devs']
+
+        count = 0
+        vslots = None
+        while vslots is None and count < 20:
+            vslots = xstransact.Read("/local/domain/0/backend/pci/%u/%s/vslots"
+                              % (self.getDomid(), devid))
+            time.sleep(0.1)
+            count += 1
+        if vslots is None:
+            log.error("Device model didn't tell the vslots for PCI device")
+            return
+
+        #delete last delim
+        if vslots[-1] == ";":
+            vslots = vslots[:-1]
+
+        slot_list = vslots.split(';')
+        if len(slot_list) != len(pci_devs):
+            log.error("Device model's pci dev num dismatch")
+            return
+
+        #update the vslot info
+        count = 0;
+        for x in pci_devs:
+            x['vslt'] = slot_list[count]
+            count += 1
+
+
+    def pci_device_create(self, dev_config):
+        log.debug("XendDomainInfo.pci_device_create: %s" % 
scrub_password(dev_config))
+
+        if not self.info.is_hvm():
+            raise VmError("only HVM guest support pci attach")
+
+        #all the PCI devs share one conf node
+        devid = '0'
+
+        dev_type = sxp.name(dev_config)
+        new_devs = sxp.child_value(dev_config, 'devs')
+        new_dev = new_devs[0]
+        dev_info = self._getDeviceInfo_pci(devid)#from self.info['devices']
+
+        #check conflict before trigger hotplug event
+        if dev_info is not None:
+            dev_uuid = sxp.child_value(dev_info, 'uuid')
+            pci_conf = self.info['devices'][dev_uuid][1]
+            pci_devs = pci_conf['devs']
+            for x in pci_devs:
+                if (int(x['vslt'], 16) == int(new_dev['vslt'], 16) and
+                   int(x['vslt'], 16) != 0 ):
+                    raise VmError("vslot %s already have a device." % 
(new_dev['vslt']))
+
+                if (int(x['domain'], 16) == int(new_dev['domain'], 16) and
+                   int(x['bus'], 16)    == int(new_dev['bus'], 16) and
+                   int(x['slot'], 16)   == int(new_dev['slot'], 16) and
+                   int(x['func'], 16)   == int(new_dev['func'], 16) ):
+                    raise VmError("device is already inserted")
+
+        # Test whether the devices can be assigned with VT-d
+        pci_str = "%s, %s, %s, %s" % (new_dev['domain'],
+                new_dev['bus'],
+                new_dev['slot'],
+                new_dev['func'])
+        bdf = xc.test_assign_device(self.domid, pci_str)
+        if bdf != 0:
+            bus = (bdf >> 16) & 0xff
+            devfn = (bdf >> 8) & 0xff
+            dev = (devfn >> 3) & 0x1f
+            func = devfn & 0x7
+            raise VmError("Fail to hot insert device(%x:%x.%x): maybe VT-d is "
+                          "not enabled, or the device is not exist, or it "
+                          "has already been assigned to other domain"
+                          % (bus, dev, func))
+
+        bdf_str = "%s:%s:%s.%s@%s" % (new_dev['domain'],
+                new_dev['bus'],
+                new_dev['slot'],
+                new_dev['func'],
+                new_dev['vslt'])
+        self.image.signalDeviceModel('pci-ins', 'pci-inserted', bdf_str)
+
+        # update the virtual pci slot
+        vslt = xstransact.Read("/local/domain/0/device-model/%i/parameter"
+                          % self.getDomid())
+        new_dev['vslt'] = vslt
+
+        if dev_info is None:
+            # create a new one from scrach
+            dev_cfg_sxp = [dev_type,
+                ['dev',
+                  ['domain', new_dev['domain']],
+                  ['bus',    new_dev['bus']],
+                  ['slot',   new_dev['slot']],
+                  ['func',   new_dev['func']],
+                  ['vslt',   new_dev['vslt']]
+                ]]
+            dev_uuid = self.info.device_add(dev_type, cfg_sxp = dev_cfg_sxp)
+            dev_config_dict = self.info['devices'][dev_uuid][1]
+            try:
+                dev_config_dict['devid'] = devid = \
+                    self._createDevice(dev_type, dev_config_dict)
+                self._waitForDevice(dev_type, devid)
+            except VmError, ex:
+                raise ex
+        else:
+            # update the pci config to add the new dev
+            pci_devs.extend(new_devs)
+            self._reconfigureDevice('pci', devid, pci_conf)
+
+        return self.getDeviceController('pci').sxpr(devid)
+
     def device_create(self, dev_config):
         """Create a new device.
 
@@ -524,6 +649,11 @@ class XendDomainInfo:
         """
         log.debug("XendDomainInfo.device_create: %s" % 
scrub_password(dev_config))
         dev_type = sxp.name(dev_config)
+
+        if dev_type == 'pci':
+            rc = self.pci_device_create(dev_config)
+            return rc
+
         dev_uuid = self.info.device_add(dev_type, cfg_sxp = dev_config)
         dev_config_dict = self.info['devices'][dev_uuid][1]
         log.debug("XendDomainInfo.device_create: %s" % 
scrub_password(dev_config_dict))
@@ -584,9 +714,64 @@ class XendDomainInfo:
         for devclass in XendDevices.valid_devices():
             self.getDeviceController(devclass).waitForDevices()
 
+    def destroyPCIDevice(self, vslot):
+        log.debug("destroyPCIDevice called %s", vslot)
+
+        if not self.info.is_hvm():
+            raise VmError("only HVM guest support pci detach")
+
+        #all the PCI devs share one conf node
+        devid = '0'
+        vslot = int(vslot)
+        dev_info = self._getDeviceInfo_pci('0')#from self.info['devices']
+        dev_uuid = sxp.child_value(dev_info, 'uuid')
+
+        #delete the pci bdf config under the pci device
+        pci_conf = self.info['devices'][dev_uuid][1]
+        pci_len = len(pci_conf['devs'])
+
+        #find the pass-through device with the virtual slot
+        devnum = 0
+        for x in pci_conf['devs']:
+            if int(x['vslt'], 16) == vslot:
+                break
+            devnum += 1
+
+        if devnum >= pci_len:
+            raise VmError("Device @ vslot 0x%x doesn't exist." % (vslot))
+
+        if vslot == 0:
+            raise VmError("Device @ vslot 0x%x do not support hotplug." % 
(vslot))
+
+        bdf_str = "%s:%s:%s.%s" % (x['domain'], x['bus'], x['slot'], x['func'])
+        log.info("destroyPCIDevice:%s:%s!", x, bdf_str)
+
+        self.image.signalDeviceModel('pci-rem', 'pci-removed', bdf_str)
+
+        if pci_len > 1:
+            del pci_conf['devs'][devnum]
+            self._reconfigureDevice('pci', devid, pci_conf)
+        else:
+            self.getDeviceController('pci').destroyDevice(devid, True)
+            del self.info['devices'][dev_uuid]
+            platform = self.info['platform']
+            orig_dev_num = len(platform['pci'])
+
+            #need remove the pci config
+            #TODO:can use this to keep some info to ask high level management 
tools to hot insert a new passthrough dev after migration
+            if orig_dev_num != 0:
+#                platform['pci'] = ["%dDEVs" % orig_dev_num]
+                platform['pci'] = []
+
+        return 0
+
     def destroyDevice(self, deviceClass, devid, force = False, rm_cfg = False):
         log.debug("XendDomainInfo.destroyDevice: deviceClass = %s, device = 
%s",
                   deviceClass, devid)
+
+        if deviceClass == 'dpci':
+            rc = self.destroyPCIDevice(devid)
+            return rc
 
         if rm_cfg:
             # Convert devid to device number.  A device number is
@@ -647,6 +832,14 @@ class XendDomainInfo:
         return rc
 
     def getDeviceSxprs(self, deviceClass):
+        if deviceClass == 'pci':
+            dev_info = self._getDeviceInfo_pci('0')#from self.info['devices']
+            if dev_info is None:
+                return []
+            dev_uuid = sxp.child_value(dev_info, 'uuid')
+            pci_devs = self.info['devices'][dev_uuid][1]['devs']
+            pci_len = len(pci_devs)
+            return pci_devs
         if self._stateGet() in (DOM_STATE_RUNNING, DOM_STATE_PAUSED, 
DOM_STATE_CRASHED):
             return self.getDeviceController(deviceClass).sxprs()
         else:
@@ -683,6 +876,12 @@ class XendDomainInfo:
             if devid == dev:
                 return dev_info
 
+    def _getDeviceInfo_pci(self, devid):
+        for dev_type, dev_info in self.info.all_devices_sxpr():
+            if dev_type != 'pci':
+                continue
+            return dev_info
+        return None
 
     def setMemoryTarget(self, target):
         """Set the memory target of this domain.
@@ -1542,6 +1741,9 @@ class XendDomainInfo:
 
         if self.image:
             self.image.createDeviceModel()
+
+        #if have pass-through devs, need the virtual pci slots info from qemu
+        self.sync_pcidev_info()
 
     def _releaseDevices(self, suspend = False):
         """Release all domain's devices.  Nothrow guarantee."""
diff -r 63b0a8cb56ff -r f853c0497095 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Tue Feb 19 09:28:09 2008 -0700
+++ b/tools/python/xen/xend/image.py    Tue Feb 19 11:14:40 2008 -0700
@@ -300,23 +300,42 @@ class ImageHandler:
         self.vm.storeDom("image/device-model-pid", self.pid)
         log.info("device model pid: %d", self.pid)
 
-    def saveDeviceModel(self):
+    def signalDeviceModel(self, cmd, ret, par = None):
         if self.device_model is None:
             return
-        # Signal the device model to pause itself and save its state
+        # Signal the device model to for action
+        if cmd is '' or ret is '':
+            raise VmError('need valid command and result when signal device 
model')
+
+        orig_state = xstransact.Read("/local/domain/0/device-model/%i/state"
+                                % self.vm.getDomid())
+
+        if par is not None:
+            xstransact.Store("/local/domain/0/device-model/%i"
+                             % self.vm.getDomid(), ('parameter', par))
+
         xstransact.Store("/local/domain/0/device-model/%i"
-                         % self.vm.getDomid(), ('command', 'save'))
+                         % self.vm.getDomid(), ('command', cmd))
         # Wait for confirmation.  Could do this with a watch but we'd
         # still end up spinning here waiting for the watch to fire. 
         state = ''
         count = 0
-        while state != 'paused':
+        while state != ret:
             state = xstransact.Read("/local/domain/0/device-model/%i/state"
                                     % self.vm.getDomid())
             time.sleep(0.1)
             count += 1
             if count > 100:
-                raise VmError('Timed out waiting for device model to save')
+                raise VmError('Timed out waiting for device model action')
+
+        #resotre orig state
+        xstransact.Store("/local/domain/0/device-model/%i"
+                         % self.vm.getDomid(), ('state', orig_state))
+        log.info("signalDeviceModel:restore dm state to %s", orig_state)
+
+    def saveDeviceModel(self):
+        # Signal the device model to pause itself and save its state
+        self.signalDeviceModel('save', 'paused')
 
     def resumeDeviceModel(self):
         if self.device_model is None:
@@ -479,7 +498,7 @@ class HVMImageHandler(ImageHandler):
 
         dmargs = [ 'boot', 'fda', 'fdb', 'soundhw',
                    'localtime', 'serial', 'stdvga', 'isa',
-                   'acpi', 'usb', 'usbdevice', 'pci' ]
+                   'acpi', 'usb', 'usbdevice' ]
 
         for a in dmargs:
             v = vmConfig['platform'].get(a)
diff -r 63b0a8cb56ff -r f853c0497095 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Tue Feb 19 09:28:09 
2008 -0700
+++ b/tools/python/xen/xend/server/DevController.py     Tue Feb 19 11:14:40 
2008 -0700
@@ -412,6 +412,14 @@ class DevController:
         return result
 
 
+    def removeBackend(self, devid, *args):
+        frontpath = self.frontendPath(devid)
+        backpath = xstransact.Read(frontpath, "backend")
+        if backpath:
+            return xstransact.Remove(backpath, *args)
+        else:
+            raise VmError("Device %s not connected" % devid)
+
     def readBackend(self, devid, *args):
         frontpath = self.frontendPath(devid)
         backpath = xstransact.Read(frontpath, "backend")
diff -r 63b0a8cb56ff -r f853c0497095 tools/python/xen/xend/server/pciif.py
--- a/tools/python/xen/xend/server/pciif.py     Tue Feb 19 09:28:09 2008 -0700
+++ b/tools/python/xen/xend/server/pciif.py     Tue Feb 19 11:14:40 2008 -0700
@@ -18,6 +18,7 @@
 
 
 import types
+import time
 
 from xen.xend import sxp
 from xen.xend.XendError import VmError
@@ -62,25 +63,62 @@ class PciController(DevController):
             
         back = {}
         pcidevid = 0
+        vslots = ""
         for pci_config in config.get('devs', []):
             domain = parse_hex(pci_config.get('domain', 0))
             bus = parse_hex(pci_config.get('bus', 0))
             slot = parse_hex(pci_config.get('slot', 0))
             func = parse_hex(pci_config.get('func', 0))            
+
+            vslt = pci_config.get('vslt')
+            if vslt is not None:
+                vslots = vslots + vslt + ";"
+
             self.setupDevice(domain, bus, slot, func)
             back['dev-%i' % pcidevid] = "%04x:%02x:%02x.%02x" % \
                                         (domain, bus, slot, func)
             pcidevid += 1
 
+        if vslots != "":
+            back['vslots'] = vslots
+
         back['num_devs']=str(pcidevid)
         back['uuid'] = config.get('uuid','')
         return (0, back, {})
+
+    def reconfigureDevice(self, _, config):
+        """@see DevController.reconfigureDevice"""
+        #currently only support config changes by hot insert/remove 
pass-through dev
+        #delete all the devices in xenstore
+        (devid, new_back, new_front) = self.getDeviceDetails(config)
+        num_devs = self.readBackend(devid, 'num_devs')
+        for i in range(int(num_devs)):
+            self.removeBackend(devid, 'dev-%d' % i)
+        self.removeBackend(devid, 'num_devs')
+
+        #create new devices config
+        num_devs = new_back['num_devs']
+        for i in range(int(num_devs)):
+            dev_no = 'dev-%d' % i
+            self.writeBackend(devid, dev_no, new_back[dev_no])
+        self.writeBackend(devid, 'num_devs', num_devs)
+
+        if new_back['vslots'] is not None:
+            self.writeBackend(devid, 'vslots', new_back['vslots'])
+
+        return new_back.get('uuid')
 
     def getDeviceConfiguration(self, devid, transaction = None):
         result = DevController.getDeviceConfiguration(self, devid, transaction)
         num_devs = self.readBackend(devid, 'num_devs')
         pci_devs = []
         
+        vslots = self.readBackend(devid, 'vslots')
+        if vslots is not None:
+            if vslots[-1] == ";":
+                vslots = vslots[:-1]
+            slot_list = vslots.split(';')
+
         for i in range(int(num_devs)):
             dev_config = self.readBackend(devid, 'dev-%d' % i)
 
@@ -91,10 +129,16 @@ class PciController(DevController):
             
             if pci_match!=None:
                 pci_dev_info = pci_match.groupdict()
-                pci_devs.append({'domain': '0x%(domain)s' % pci_dev_info,
+                dev_dict = {'domain': '0x%(domain)s' % pci_dev_info,
                                  'bus': '0x%(bus)s' % pci_dev_info,
                                  'slot': '0x%(slot)s' % pci_dev_info,
-                                 'func': '0x%(func)s' % pci_dev_info})
+                                 'func': '0x%(func)s' % pci_dev_info}
+
+                #append vslot info
+                if vslots is not None:
+                    dev_dict['vslt'] = slot_list[i]
+
+                pci_devs.append(dev_dict)
 
         result['devs'] = pci_devs
         result['uuid'] = self.readBackend(devid, 'uuid')
diff -r 63b0a8cb56ff -r f853c0497095 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Tue Feb 19 09:28:09 2008 -0700
+++ b/tools/python/xen/xm/main.py       Tue Feb 19 11:14:40 2008 -0700
@@ -175,6 +175,12 @@ SUBCOMMAND_HELP = {
     'vnet-delete'   :  ('<VnetId>', 'Delete a Vnet.'),
     'vnet-list'     :  ('[-l|--long]', 'List Vnets.'),
     'vtpm-list'     :  ('<Domain> [--long]', 'List virtual TPM devices.'),
+    'pci-attach '   :  ('<Domain> <dom> <bus> <slot> <func> [virtual slot]',
+                        'Insert a new pass-through pci device.'),
+    'pci-detach '   :  ('<Domain> <virtual slot>',
+                        'Remove a domain\'s pass-through pci device.'),
+    'pci-list'     :  ('<Domain>',
+                        'List pass-through pci devices for a domain.'),
 
     # security
 
@@ -335,6 +341,9 @@ device_commands = [
     "network-detach",
     "network-list",
     "vtpm-list",
+    "pci-attach",
+    "pci-detach",
+    "pci-list",
     ]
 
 vnet_commands = [
@@ -2051,6 +2060,31 @@ def xm_vtpm_list(args):
                    % ni)
 
 
+def xm_pci_list(args):
+    (use_long, params) = arg_check_for_resource_list(args, "pci-list")
+
+    dom = params[0]
+
+    devs = server.xend.domain.getDeviceSxprs(dom, 'pci')
+
+    if len(devs) == 0:
+        return
+
+    has_vslt = devs[0].has_key('vslt')
+    if has_vslt:
+        hdr_str = 'VSlt domain   bus   slot   func'
+        fmt_str =  "%(vslt)-3s    %(domain)-3s  %(bus)-3s   %(slot)-3s    
%(func)-3s    "
+    else:
+        hdr_str = 'domain   bus   slot   func'
+        fmt_str =  "%(domain)-3s  %(bus)-3s   %(slot)-3s    %(func)-3s    "
+    hdr = 0
+
+    for x in devs:
+        if hdr == 0:
+            print (hdr_str)
+            hdr = 1
+        print ( fmt_str % x )
+
 def parse_block_configuration(args):
     dom = args[0]
 
@@ -2198,6 +2232,29 @@ def xm_network_attach(args):
             vif.append(vif_param)
         server.xend.domain.device_create(dom, vif)
 
+def parse_pci_configuration(args):
+    dom = args[0]
+
+    if len(args) == 6:
+        vslt = args[5]
+    else:
+        vslt = '0x0' #chose a free virtual PCI slot
+
+    pci = ['pci',
+          ['devs',
+            [{'domain': "0x%x" % int(args[1], 16),
+              'bus':    "0x%x" % int(args[2], 16),
+              'slot':   "0x%x" % int(args[3], 16),
+              'func':   "0x%x" % int(args[4], 16),
+              'vslt':   "0x%x" % int(vslt,    16)}]
+          ]]
+
+    return (dom, pci)
+
+def xm_pci_attach(args):
+    arg_check(args, 'xm_pci_attach', 5, 6)
+    (dom, pci) = parse_pci_configuration(args)
+    server.xend.domain.device_create(dom, pci)
 
 def detach(args, deviceClass):
     rm_cfg = True
@@ -2262,6 +2319,12 @@ def xm_network_detach(args):
         arg_check(args, 'network-detach', 2, 3)
         detach(args, 'vif')
 
+
+def xm_pci_detach(args):
+    arg_check(args, 'xm_pci_detach', 2, 2)
+    dom = args[0]
+    dev = args[1]
+    server.xend.domain.destroyDevice(dom, 'dpci', dev)
 
 def xm_vnet_list(args):
     xenapi_unsupported()
@@ -2452,6 +2515,10 @@ commands = {
     "vnet-delete": xm_vnet_delete,
     # vtpm
     "vtpm-list": xm_vtpm_list,
+    #pci
+    "pci-attach": xm_pci_attach,
+    "pci-detach": xm_pci_detach,
+    "pci-list": xm_pci_list,
     }
 
 ## The commands supported by a separate argument parser in xend.xm.
diff -r 63b0a8cb56ff -r f853c0497095 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c     Tue Feb 19 09:28:09 2008 -0700
+++ b/xen/arch/x86/domctl.c     Tue Feb 19 11:14:40 2008 -0700
@@ -580,6 +580,34 @@ long arch_do_domctl(
     }
     break;
 
+    case XEN_DOMCTL_deassign_device:
+    {
+        struct domain *d;
+        u8 bus, devfn;
+
+        ret = -EINVAL;
+        if ( !iommu_enabled )
+            break;
+
+        if ( unlikely((d = get_domain_by_id(domctl->domain)) == NULL) )
+        {
+            gdprintk(XENLOG_ERR,
+                "XEN_DOMCTL_deassign_device: get_domain_by_id() failed\n"); 
+            break;
+        }
+        bus = (domctl->u.assign_device.machine_bdf >> 16) & 0xff;
+        devfn = (domctl->u.assign_device.machine_bdf >> 8) & 0xff;
+
+        if ( !device_assigned(bus, devfn) )
+            break;
+
+        deassign_device(d, bus, devfn);
+        gdprintk(XENLOG_INFO, "XEN_DOMCTL_deassign_device: bdf = %x:%x:%x\n",
+            bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+        put_domain(d);
+    }
+    break;
+
     case XEN_DOMCTL_bind_pt_irq:
     {
         struct domain * d;
@@ -593,6 +621,23 @@ long arch_do_domctl(
             ret = pt_irq_create_bind_vtd(d, bind);
         if ( ret < 0 )
             gdprintk(XENLOG_ERR, "pt_irq_create_bind failed!\n");
+        rcu_unlock_domain(d);
+    }
+    break;    
+
+    case XEN_DOMCTL_unbind_pt_irq:
+    {
+        struct domain * d;
+        xen_domctl_bind_pt_irq_t * bind;
+
+        ret = -ESRCH;
+        if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL )
+            break;
+        bind = &(domctl->u.bind_pt_irq);
+        if ( iommu_enabled )
+            ret = pt_irq_destroy_bind_vtd(d, bind);
+        if ( ret < 0 )
+            gdprintk(XENLOG_ERR, "pt_irq_destroy_bind failed!\n");
         rcu_unlock_domain(d);
     }
     break;
diff -r 63b0a8cb56ff -r f853c0497095 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Tue Feb 19 09:28:09 2008 -0700
+++ b/xen/arch/x86/hvm/hvm.c    Tue Feb 19 11:14:40 2008 -0700
@@ -1393,20 +1393,18 @@ static enum hvm_copy_result __hvm_copy(
     int count, todo;
     uint32_t pfec = PFEC_page_present;
 
-    if ( virt )
-    {
-        /*
-         * We cannot use hvm_get_segment_register() while executing in
-         * vmx_realmode() as segment register state is cached. Furthermore,
-         * VMREADs on every data access hurts emulation performance.
-         */
-        if ( !curr->arch.hvm_vmx.vmxemul )
-        {
-            struct segment_register sreg;
-            hvm_get_segment_register(curr, x86_seg_ss, &sreg);
-            if ( sreg.attr.fields.dpl == 3 )
-                pfec |= PFEC_user_mode;
-        }
+    /*
+     * We cannot use hvm_get_segment_register() while executing in
+     * vmx_realmode() as segment register state is cached. Furthermore,
+     * VMREADs on every data access hurts emulation performance.
+     * Hence we do not gather extra PFEC flags if CR0.PG == 0.
+     */
+    if ( virt && (curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PG) )
+    {
+        struct segment_register sreg;
+        hvm_get_segment_register(curr, x86_seg_ss, &sreg);
+        if ( sreg.attr.fields.dpl == 3 )
+            pfec |= PFEC_user_mode;
 
         if ( dir ) 
             pfec |= PFEC_write_access;
diff -r 63b0a8cb56ff -r f853c0497095 xen/arch/x86/hvm/iommu.c
--- a/xen/arch/x86/hvm/iommu.c  Tue Feb 19 09:28:09 2008 -0700
+++ b/xen/arch/x86/hvm/iommu.c  Tue Feb 19 11:14:40 2008 -0700
@@ -133,3 +133,13 @@ int iommu_unmap_page(struct domain *d, u
 
     return hd->platform_ops->unmap_page(d, gfn);
 }
+
+void deassign_device(struct domain *d, u8 bus, u8 devfn)
+{
+    struct hvm_iommu *hd = domain_hvm_iommu(d);
+
+    if ( !iommu_enabled || !hd->platform_ops)
+        return;
+
+    return hd->platform_ops->reassign_device(d, dom0, bus, devfn);
+}
diff -r 63b0a8cb56ff -r f853c0497095 xen/arch/x86/hvm/irq.c
--- a/xen/arch/x86/hvm/irq.c    Tue Feb 19 09:28:09 2008 -0700
+++ b/xen/arch/x86/hvm/irq.c    Tue Feb 19 11:14:40 2008 -0700
@@ -211,8 +211,7 @@ void hvm_set_pci_link_route(struct domai
             clear_bit(old_isa_irq, &hvm_irq->dpci->isairq_map);
 
         for ( i = 0; i < NR_LINK; i++ )
-            if ( test_bit(i, &hvm_irq->dpci->link_map) &&
-                 hvm_irq->pci_link.route[i] )
+            if ( hvm_irq->dpci->link_cnt[i] && hvm_irq->pci_link.route[i] )
                 set_bit(hvm_irq->pci_link.route[i],
                         &hvm_irq->dpci->isairq_map);
     }
diff -r 63b0a8cb56ff -r f853c0497095 
xen/arch/x86/hvm/svm/amd_iommu/pci-amd-iommu.c
--- a/xen/arch/x86/hvm/svm/amd_iommu/pci-amd-iommu.c    Tue Feb 19 09:28:09 
2008 -0700
+++ b/xen/arch/x86/hvm/svm/amd_iommu/pci-amd-iommu.c    Tue Feb 19 11:14:40 
2008 -0700
@@ -562,10 +562,17 @@ void amd_iommu_domain_destroy(struct dom
     release_domain_devices(d);
 }
 
+void amd_iommu_return_device(struct domain *s, struct domain *t, u8 bus, u8 
devfn)
+{
+    pdev_flr(bus, devfn);
+    reassign_device(s, t, bus, devfn);
+}
+
 struct iommu_ops amd_iommu_ops = {
     .init = amd_iommu_domain_init,
     .assign_device  = amd_iommu_assign_device,
     .teardown = amd_iommu_domain_destroy,
     .map_page = amd_iommu_map_page,
     .unmap_page = amd_iommu_unmap_page,
+    .reassign_device = amd_iommu_return_device,
 };
diff -r 63b0a8cb56ff -r f853c0497095 xen/arch/x86/hvm/vmx/vtd/dmar.c
--- a/xen/arch/x86/hvm/vmx/vtd/dmar.c   Tue Feb 19 09:28:09 2008 -0700
+++ b/xen/arch/x86/hvm/vmx/vtd/dmar.c   Tue Feb 19 11:14:40 2008 -0700
@@ -102,7 +102,7 @@ struct iommu * ioapic_to_iommu(unsigned 
             return drhd->iommu;
         }
     }
-    dprintk(XENLOG_WARNING VTDPREFIX, "returning NULL\n");
+    dprintk(XENLOG_INFO VTDPREFIX, "returning NULL\n");
     return NULL;
 }
 
diff -r 63b0a8cb56ff -r f853c0497095 xen/arch/x86/hvm/vmx/vtd/intel-iommu.c
--- a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c    Tue Feb 19 09:28:09 2008 -0700
+++ b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c    Tue Feb 19 11:14:40 2008 -0700
@@ -1441,6 +1441,8 @@ void reassign_device_ownership(
              bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
              source->domain_id, target->domain_id);
 
+    pdev_flr(bus, devfn);
+
     for_each_pdev( source, pdev )
     {
         if ( (pdev->bus != bus) || (pdev->devfn != devfn) )
@@ -1476,7 +1478,6 @@ void return_devices_to_dom0(struct domai
         dprintk(XENLOG_INFO VTDPREFIX,
                 "return_devices_to_dom0: bdf = %x:%x:%x\n",
                 pdev->bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
-        pdev_flr(pdev->bus, pdev->devfn);
         reassign_device_ownership(d, dom0, pdev->bus, pdev->devfn);
     }
 
@@ -1811,7 +1812,18 @@ static int init_vtd_hw(void)
         flush = iommu_get_flush(iommu);
         flush->context = flush_context_reg;
         flush->iotlb = flush_iotlb_reg;
-
+    }
+    return 0;
+}
+
+static int init_vtd2_hw(void)
+{
+    struct acpi_drhd_unit *drhd;
+    struct iommu *iommu;
+
+    for_each_drhd_unit ( drhd )
+    {
+        iommu = drhd->iommu;
         if ( qinval_setup(iommu) != 0 )
             dprintk(XENLOG_ERR VTDPREFIX,
                     "Queued Invalidation hardware not found\n");
@@ -1883,12 +1895,12 @@ int iommu_setup(void)
     for ( i = 0; i < max_page; i++ )
         iommu_map_page(dom0, i, i);
 
-    enable_vtd_translation();
-    if ( init_vtd_hw() )
-        goto error;
+    init_vtd_hw();
     setup_dom0_devices();
     setup_dom0_rmrr();
     iommu_flush_all();
+    enable_vtd_translation();
+    init_vtd2_hw();
 
     return 0;
 
@@ -1930,7 +1942,6 @@ int intel_iommu_assign_device(struct dom
              "assign_device: bus = %x dev = %x func = %x\n",
              bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
 
-    pdev_flr(bus, devfn);
     reassign_device_ownership(dom0, d, bus, devfn);
 
     /* Setup rmrr identify mapping */
@@ -2153,6 +2164,7 @@ struct iommu_ops intel_iommu_ops = {
     .teardown = iommu_domain_teardown,
     .map_page = intel_iommu_map_page,
     .unmap_page = intel_iommu_unmap_page,
+    .reassign_device = reassign_device_ownership,
 };
 
 /*
diff -r 63b0a8cb56ff -r f853c0497095 xen/arch/x86/hvm/vmx/vtd/io.c
--- a/xen/arch/x86/hvm/vmx/vtd/io.c     Tue Feb 19 09:28:09 2008 -0700
+++ b/xen/arch/x86/hvm/vmx/vtd/io.c     Tue Feb 19 11:14:40 2008 -0700
@@ -101,7 +101,7 @@ int pt_irq_create_bind_vtd(
     intx = pt_irq_bind->u.pci.intx;
     guest_gsi = hvm_pci_intx_gsi(device, intx);
     link = hvm_pci_intx_link(device, intx);
-    set_bit(link, hvm_irq_dpci->link_map);
+    hvm_irq_dpci->link_cnt[link]++;
 
     digl = xmalloc(struct dev_intx_gsi_link);
     if ( !digl )
@@ -134,6 +134,65 @@ int pt_irq_create_bind_vtd(
     gdprintk(XENLOG_INFO VTDPREFIX,
              "VT-d irq bind: m_irq = %x device = %x intx = %x\n",
              machine_gsi, device, intx);
+    return 0;
+}
+
+int pt_irq_destroy_bind_vtd(
+    struct domain *d, xen_domctl_bind_pt_irq_t *pt_irq_bind)
+{
+    struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
+    uint32_t machine_gsi, guest_gsi;
+    uint32_t device, intx, link;
+    struct list_head *digl_list, *tmp;
+    struct dev_intx_gsi_link *digl;
+
+    if ( hvm_irq_dpci == NULL )
+        return 0;
+
+    machine_gsi = pt_irq_bind->machine_irq;
+    device = pt_irq_bind->u.pci.device;
+    intx = pt_irq_bind->u.pci.intx;
+    guest_gsi = hvm_pci_intx_gsi(device, intx);
+    link = hvm_pci_intx_link(device, intx);
+    hvm_irq_dpci->link_cnt[link]--;
+
+    gdprintk(XENLOG_INFO,
+            "pt_irq_destroy_bind_vtd: machine_gsi=%d, guest_gsi=%d, device=%d, 
intx=%d.\n",
+            machine_gsi, guest_gsi, device, intx);
+    memset(&hvm_irq_dpci->girq[guest_gsi], 0, sizeof(struct 
hvm_girq_dpci_mapping));
+
+    /* clear the mirq info */
+    if ( hvm_irq_dpci->mirq[machine_gsi].valid )
+    {
+
+        list_for_each_safe ( digl_list, tmp,
+                &hvm_irq_dpci->mirq[machine_gsi].digl_list )
+        {
+            digl = list_entry(digl_list,
+                    struct dev_intx_gsi_link, list);
+            if ( digl->device == device &&
+                 digl->intx   == intx &&
+                 digl->link   == link &&
+                 digl->gsi    == guest_gsi )
+            {
+                list_del(&digl->list);
+                xfree(digl);
+            }
+        }
+
+        if ( list_empty(&hvm_irq_dpci->mirq[machine_gsi].digl_list) )
+        {
+            pirq_guest_unbind(d, machine_gsi);
+            kill_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(machine_gsi)]);
+            hvm_irq_dpci->mirq[machine_gsi].dom   = NULL;
+            hvm_irq_dpci->mirq[machine_gsi].valid = 0;
+        }
+    }
+
+    gdprintk(XENLOG_INFO,
+             "XEN_DOMCTL_irq_unmapping: m_irq = %x device = %x intx = %x\n",
+             machine_gsi, device, intx);
+
     return 0;
 }
 
diff -r 63b0a8cb56ff -r f853c0497095 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Tue Feb 19 09:28:09 2008 -0700
+++ b/xen/arch/x86/mm.c Tue Feb 19 11:14:40 2008 -0700
@@ -1443,16 +1443,18 @@ static int mod_l1_entry(l1_pgentry_t *pl
             return 0;
         }
 
-        adjust_guest_l1e(nl1e, d);
-
         /* Fast path for identical mapping, r/w and presence. */
         if ( !l1e_has_changed(ol1e, nl1e, _PAGE_RW | _PAGE_PRESENT) )
+        {
+            adjust_guest_l1e(nl1e, d);
             return UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, curr,
                                 preserve_ad);
+        }
 
         if ( unlikely(!get_page_from_l1e(nl1e, FOREIGNDOM)) )
             return 0;
         
+        adjust_guest_l1e(nl1e, d);
         if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, curr,
                                     preserve_ad)) )
         {
@@ -1501,15 +1503,17 @@ static int mod_l2_entry(l2_pgentry_t *pl
             return 0;
         }
 
-        adjust_guest_l2e(nl2e, d);
-
         /* Fast path for identical mapping and presence. */
-        if ( !l2e_has_changed(ol2e, nl2e, _PAGE_PRESENT))
+        if ( !l2e_has_changed(ol2e, nl2e, _PAGE_PRESENT) )
+        {
+            adjust_guest_l2e(nl2e, d);
             return UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, curr, preserve_ad);
+        }
 
         if ( unlikely(!get_page_from_l2e(nl2e, pfn, d)) )
             return 0;
 
+        adjust_guest_l2e(nl2e, d);
         if ( unlikely(!UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, curr,
                                     preserve_ad)) )
         {
@@ -1567,15 +1571,17 @@ static int mod_l3_entry(l3_pgentry_t *pl
             return 0;
         }
 
-        adjust_guest_l3e(nl3e, d);
-
         /* Fast path for identical mapping and presence. */
-        if (!l3e_has_changed(ol3e, nl3e, _PAGE_PRESENT))
+        if ( !l3e_has_changed(ol3e, nl3e, _PAGE_PRESENT) )
+        {
+            adjust_guest_l3e(nl3e, d);
             return UPDATE_ENTRY(l3, pl3e, ol3e, nl3e, pfn, curr, preserve_ad);
+        }
 
         if ( unlikely(!get_page_from_l3e(nl3e, pfn, d)) )
             return 0;
 
+        adjust_guest_l3e(nl3e, d);
         if ( unlikely(!UPDATE_ENTRY(l3, pl3e, ol3e, nl3e, pfn, curr,
                                     preserve_ad)) )
         {
@@ -1630,15 +1636,17 @@ static int mod_l4_entry(l4_pgentry_t *pl
             return 0;
         }
 
-        adjust_guest_l4e(nl4e, d);
-
         /* Fast path for identical mapping and presence. */
-        if (!l4e_has_changed(ol4e, nl4e, _PAGE_PRESENT))
+        if ( !l4e_has_changed(ol4e, nl4e, _PAGE_PRESENT) )
+        {
+            adjust_guest_l4e(nl4e, d);
             return UPDATE_ENTRY(l4, pl4e, ol4e, nl4e, pfn, curr, preserve_ad);
+        }
 
         if ( unlikely(!get_page_from_l4e(nl4e, pfn, d)) )
             return 0;
 
+        adjust_guest_l4e(nl4e, d);
         if ( unlikely(!UPDATE_ENTRY(l4, pl4e, ol4e, nl4e, pfn, curr,
                                     preserve_ad)) )
         {
diff -r 63b0a8cb56ff -r f853c0497095 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Tue Feb 19 09:28:09 2008 -0700
+++ b/xen/arch/x86/mm/shadow/common.c   Tue Feb 19 11:14:40 2008 -0700
@@ -1039,13 +1039,18 @@ void shadow_free(struct domain *d, mfn_t
 
     for ( i = 0; i < 1<<order; i++ ) 
     {
-#if SHADOW_OPTIMIZATIONS & SHOPT_WRITABLE_HEURISTIC
+#if SHADOW_OPTIMIZATIONS & (SHOPT_WRITABLE_HEURISTIC | SHOPT_FAST_EMULATION)
         struct vcpu *v;
         for_each_vcpu(d, v) 
         {
+#if SHADOW_OPTIMIZATIONS & SHOPT_WRITABLE_HEURISTIC
             /* No longer safe to look for a writeable mapping in this shadow */
             if ( v->arch.paging.shadow.last_writeable_pte_smfn == mfn_x(smfn) 
+ i ) 
                 v->arch.paging.shadow.last_writeable_pte_smfn = 0;
+#endif
+#if SHADOW_OPTIMIZATIONS & SHOPT_FAST_EMULATION
+            v->arch.paging.last_write_emul_ok = 0;
+#endif
         }
 #endif
         /* Strip out the type: this is now a free shadow page */
diff -r 63b0a8cb56ff -r f853c0497095 xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Tue Feb 19 09:28:09 2008 -0700
+++ b/xen/arch/x86/mm/shadow/multi.c    Tue Feb 19 11:14:40 2008 -0700
@@ -2623,13 +2623,13 @@ static inline void check_for_early_unsha
 static inline void check_for_early_unshadow(struct vcpu *v, mfn_t gmfn)
 {
 #if SHADOW_OPTIMIZATIONS & SHOPT_EARLY_UNSHADOW
-    if ( v->arch.paging.shadow.last_emulated_mfn == mfn_x(gmfn) &&
-         sh_mfn_is_a_page_table(gmfn) )
+    if ( v->arch.paging.shadow.last_emulated_mfn_for_unshadow == mfn_x(gmfn)
+         && sh_mfn_is_a_page_table(gmfn) )
     {
         perfc_incr(shadow_early_unshadow);
         sh_remove_shadows(v, gmfn, 1, 0 /* Fast, can fail to unshadow */ );
     }
-    v->arch.paging.shadow.last_emulated_mfn = mfn_x(gmfn);
+    v->arch.paging.shadow.last_emulated_mfn_for_unshadow = mfn_x(gmfn);
 #endif
 }
 
@@ -2637,7 +2637,7 @@ static inline void reset_early_unshadow(
 static inline void reset_early_unshadow(struct vcpu *v)
 {
 #if SHADOW_OPTIMIZATIONS & SHOPT_EARLY_UNSHADOW
-    v->arch.paging.shadow.last_emulated_mfn = INVALID_MFN;
+    v->arch.paging.shadow.last_emulated_mfn_for_unshadow = INVALID_MFN;
 #endif
 }
 
@@ -2744,12 +2744,39 @@ static int sh_page_fault(struct vcpu *v,
     int r;
     fetch_type_t ft = 0;
     p2m_type_t p2mt;
+#if SHADOW_OPTIMIZATIONS & SHOPT_FAST_EMULATION
+    int fast_emul = 0;
+#endif
 
     SHADOW_PRINTK("d:v=%u:%u va=%#lx err=%u, rip=%lx\n",
                   v->domain->domain_id, v->vcpu_id, va, regs->error_code,
                   regs->rip);
 
     perfc_incr(shadow_fault);
+
+#if SHADOW_OPTIMIZATIONS & SHOPT_FAST_EMULATION
+    /* If faulting frame is successfully emulated in last shadow fault
+     * it's highly likely to reach same emulation action for this frame.
+     * Then try to emulate early to avoid lock aquisition.
+     */
+    if ( v->arch.paging.last_write_emul_ok
+         && v->arch.paging.shadow.last_emulated_frame == (va >> PAGE_SHIFT) ) 
+    {
+        /* check whether error code is 3, or else fall back to normal path
+         * in case of some validation is required
+         */
+        if ( regs->error_code == (PFEC_write_access | PFEC_page_present) )
+        {
+            fast_emul = 1;
+            gmfn = _mfn(v->arch.paging.shadow.last_emulated_mfn);
+            perfc_incr(shadow_fault_fast_emulate);
+            goto early_emulation;
+        }
+        else
+            v->arch.paging.last_write_emul_ok = 0;
+    }
+#endif
+
     //
     // XXX: Need to think about eventually mapping superpages directly in the
     //      shadow (when possible), as opposed to splintering them into a
@@ -2960,6 +2987,17 @@ static int sh_page_fault(struct vcpu *v,
         goto done;
     }
 
+    /*
+     * We don't need to hold the lock for the whole emulation; we will
+     * take it again when we write to the pagetables.
+     */
+    sh_audit_gw(v, &gw);
+    shadow_audit_tables(v);
+    shadow_unlock(d);
+
+#if SHADOW_OPTIMIZATIONS & SHOPT_FAST_EMULATION
+ early_emulation:
+#endif
     if ( is_hvm_domain(d) )
     {
         /*
@@ -2971,6 +3009,13 @@ static int sh_page_fault(struct vcpu *v,
          */
         if ( unlikely(hvm_event_pending(v)) )
         {
+#if SHADOW_OPTIMIZATIONS & SHOPT_FAST_EMULATION
+            if ( fast_emul )
+            {
+                perfc_incr(shadow_fault_fast_emulate_fail);
+                v->arch.paging.last_write_emul_ok = 0;
+            }
+#endif
             gdprintk(XENLOG_DEBUG, "write to pagetable during event "
                      "injection: cr2=%#lx, mfn=%#lx\n", 
                      va, mfn_x(gmfn));
@@ -2981,14 +3026,6 @@ static int sh_page_fault(struct vcpu *v,
 
     SHADOW_PRINTK("emulate: eip=%#lx esp=%#lx\n", 
                   (unsigned long)regs->eip, (unsigned long)regs->esp);
-
-    /*
-     * We don't need to hold the lock for the whole emulation; we will
-     * take it again when we write to the pagetables.
-     */
-    sh_audit_gw(v, &gw);
-    shadow_audit_tables(v);
-    shadow_unlock(d);
 
     emul_ops = shadow_init_emulation(&emul_ctxt, regs);
 
@@ -3001,14 +3038,43 @@ static int sh_page_fault(struct vcpu *v,
      */
     if ( r == X86EMUL_UNHANDLEABLE )
     {
+        perfc_incr(shadow_fault_emulate_failed);
+#if SHADOW_OPTIMIZATIONS & SHOPT_FAST_EMULATION
+        if ( fast_emul )
+        {
+            perfc_incr(shadow_fault_fast_emulate_fail);
+            v->arch.paging.last_write_emul_ok = 0;
+        }
+#endif
         SHADOW_PRINTK("emulator failure, unshadowing mfn %#lx\n", 
                        mfn_x(gmfn));
-        perfc_incr(shadow_fault_emulate_failed);
         /* If this is actually a page table, then we have a bug, and need 
          * to support more operations in the emulator.  More likely, 
          * though, this is a hint that this page should not be shadowed. */
         shadow_remove_all_shadows(v, gmfn);
     }
+
+#if SHADOW_OPTIMIZATIONS & SHOPT_FAST_EMULATION
+    /* Record successfully emulated information as heuristics to next
+     * fault on same frame for acceleration. But be careful to verify
+     * its attribute still as page table, or else unshadow triggered
+     * in write emulation normally requires a re-sync with guest page
+     * table to recover r/w permission. Incorrect record for such case
+     * will cause unexpected more shadow faults due to propagation is
+     * skipped.
+     */
+    if ( (r == X86EMUL_OKAY) && sh_mfn_is_a_page_table(gmfn) )
+    {
+        if ( !fast_emul )
+        {
+            v->arch.paging.shadow.last_emulated_frame = va >> PAGE_SHIFT;
+            v->arch.paging.shadow.last_emulated_mfn = mfn_x(gmfn);
+            v->arch.paging.last_write_emul_ok = 1;
+        }
+    }
+    else if ( fast_emul )
+        v->arch.paging.last_write_emul_ok = 0;
+#endif
 
 #if GUEST_PAGING_LEVELS == 3 /* PAE guest */
     if ( r == X86EMUL_OKAY ) {
@@ -3077,6 +3143,10 @@ sh_invlpg(struct vcpu *v, unsigned long 
 #if (SHADOW_OPTIMIZATIONS & SHOPT_VIRTUAL_TLB)
     /* No longer safe to use cached gva->gfn translations */
     vtlb_flush(v);
+#endif
+
+#if SHADOW_OPTIMIZATIONS & SHOPT_FAST_EMULATION
+    v->arch.paging.last_write_emul_ok = 0;
 #endif
 
     /* First check that we can safely read the shadow l2e.  SMP/PAE linux can
@@ -3815,6 +3885,10 @@ sh_update_cr3(struct vcpu *v, int do_loc
     vtlb_flush(v);
 #endif
 
+#if SHADOW_OPTIMIZATIONS & SHOPT_FAST_EMULATION
+    v->arch.paging.last_write_emul_ok = 0;
+#endif
+
     /* Release the lock, if we took it (otherwise it's the caller's problem) */
     if ( do_locking ) shadow_unlock(v->domain);
 }
diff -r 63b0a8cb56ff -r f853c0497095 xen/arch/x86/mm/shadow/private.h
--- a/xen/arch/x86/mm/shadow/private.h  Tue Feb 19 09:28:09 2008 -0700
+++ b/xen/arch/x86/mm/shadow/private.h  Tue Feb 19 11:14:40 2008 -0700
@@ -62,8 +62,9 @@ extern int shadow_audit_enable;
 #define SHOPT_LINUX_L3_TOPLEVEL   0x10  /* Pin l3es on early 64bit linux */
 #define SHOPT_SKIP_VERIFY         0x20  /* Skip PTE v'fy when safe to do so */
 #define SHOPT_VIRTUAL_TLB         0x40  /* Cache guest v->p translations */
-
-#define SHADOW_OPTIMIZATIONS      0x7f
+#define SHOPT_FAST_EMULATION      0x80  /* Fast write emulation */
+
+#define SHADOW_OPTIMIZATIONS      0xff
 
 
 /******************************************************************************
diff -r 63b0a8cb56ff -r f853c0497095 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Tue Feb 19 09:28:09 2008 -0700
+++ b/xen/include/asm-x86/domain.h      Tue Feb 19 11:14:40 2008 -0700
@@ -108,10 +108,14 @@ struct shadow_vcpu {
 #endif
     /* Non-PAE guests: pointer to guest top-level pagetable */
     void *guest_vtable;
-    /* Last MFN that we emulated a write to. */
-    unsigned long last_emulated_mfn;
+    /* Last MFN that we emulated a write to as unshadow heuristics. */
+    unsigned long last_emulated_mfn_for_unshadow;
     /* MFN of the last shadow that we shot a writeable mapping in */
     unsigned long last_writeable_pte_smfn;
+    /* Last frame number that we emulated a write to. */
+    unsigned long last_emulated_frame;
+    /* Last MFN that we emulated a write successfully */
+    unsigned long last_emulated_mfn;
 };
 
 /************************************************/
@@ -189,6 +193,8 @@ struct paging_vcpu {
     struct paging_mode *mode;
     /* HVM guest: last emulate was to a pagetable */
     unsigned int last_write_was_pt:1;
+    /* HVM guest: last write emulation succeeds */
+    unsigned int last_write_emul_ok:1;
     /* Translated guest: virtual TLB */
     struct shadow_vtlb *vtlb;
     spinlock_t          vtlb_lock;
diff -r 63b0a8cb56ff -r f853c0497095 xen/include/asm-x86/hvm/irq.h
--- a/xen/include/asm-x86/hvm/irq.h     Tue Feb 19 09:28:09 2008 -0700
+++ b/xen/include/asm-x86/hvm/irq.h     Tue Feb 19 11:14:40 2008 -0700
@@ -64,7 +64,7 @@ struct hvm_irq_dpci {
     /* Record of mapped ISA IRQs */
     DECLARE_BITMAP(isairq_map, NR_ISAIRQS);
     /* Record of mapped Links */
-    DECLARE_BITMAP(link_map, NR_LINK);
+    uint8_t link_cnt[NR_LINK];
     struct timer hvm_timer[NR_IRQS];
 };
 
diff -r 63b0a8cb56ff -r f853c0497095 xen/include/asm-x86/iommu.h
--- a/xen/include/asm-x86/iommu.h       Tue Feb 19 09:28:09 2008 -0700
+++ b/xen/include/asm-x86/iommu.h       Tue Feb 19 11:14:40 2008 -0700
@@ -74,6 +74,10 @@ void iommu_domain_destroy(struct domain 
 void iommu_domain_destroy(struct domain *d);
 int device_assigned(u8 bus, u8 devfn);
 int assign_device(struct domain *d, u8 bus, u8 devfn);
+void deassign_device(struct domain *d, u8 bus, u8 devfn);
+void reassign_device_ownership(struct domain *source,
+                               struct domain *target,
+                               u8 bus, u8 devfn);
 int iommu_map_page(struct domain *d, unsigned long gfn, unsigned long mfn);
 int iommu_unmap_page(struct domain *d, unsigned long gfn);
 void iommu_flush(struct domain *d, unsigned long gfn, u64 *p2m_entry);
@@ -83,6 +87,8 @@ int dpci_ioport_intercept(ioreq_t *p);
 int dpci_ioport_intercept(ioreq_t *p);
 int pt_irq_create_bind_vtd(struct domain *d,
                            xen_domctl_bind_pt_irq_t *pt_irq_bind);
+int pt_irq_destroy_bind_vtd(struct domain *d,
+                            xen_domctl_bind_pt_irq_t *pt_irq_bind);
 unsigned int io_apic_read_remap_rte(
     unsigned int apic, unsigned int reg);
 void io_apic_write_remap_rte(unsigned int apic,
@@ -97,6 +103,7 @@ struct iommu_ops {
     void (*teardown)(struct domain *d);
     int (*map_page)(struct domain *d, unsigned long gfn, unsigned long mfn);
     int (*unmap_page)(struct domain *d, unsigned long gfn);
+    void (*reassign_device)(struct domain *s, struct domain *t, u8 bus, u8 
devfn);
 };
 
 #endif /* _IOMMU_H_ */
diff -r 63b0a8cb56ff -r f853c0497095 xen/include/asm-x86/perfc_defn.h
--- a/xen/include/asm-x86/perfc_defn.h  Tue Feb 19 09:28:09 2008 -0700
+++ b/xen/include/asm-x86/perfc_defn.h  Tue Feb 19 11:14:40 2008 -0700
@@ -57,6 +57,9 @@ PERFCOUNTER(shadow_fault_emulate_failed,
 PERFCOUNTER(shadow_fault_emulate_failed, "shadow_fault emulator fails")
 PERFCOUNTER(shadow_fault_emulate_stack, "shadow_fault emulate stack write")
 PERFCOUNTER(shadow_fault_emulate_wp, "shadow_fault emulate for CR0.WP=0")
+PERFCOUNTER(shadow_fault_fast_emulate, "shadow_fault fast emulate")
+PERFCOUNTER(shadow_fault_fast_emulate_fail,
+                                   "shadow_fault fast emulate failed")
 PERFCOUNTER(shadow_fault_mmio,     "shadow_fault handled as mmio")
 PERFCOUNTER(shadow_fault_fixed,    "shadow_fault fixed fault")
 PERFCOUNTER(shadow_ptwr_emulate,   "shadow causes ptwr to emulate")
diff -r 63b0a8cb56ff -r f853c0497095 xen/include/public/domctl.h
--- a/xen/include/public/domctl.h       Tue Feb 19 09:28:09 2008 -0700
+++ b/xen/include/public/domctl.h       Tue Feb 19 11:14:40 2008 -0700
@@ -441,6 +441,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendt
 /* Assign PCI device to HVM guest. Sets up IOMMU structures. */
 #define XEN_DOMCTL_assign_device      37
 #define XEN_DOMCTL_test_assign_device 45
+#define XEN_DOMCTL_deassign_device 47
 struct xen_domctl_assign_device {
     uint32_t  machine_bdf;   /* machine PCI ID of assigned device */
 };
@@ -450,6 +451,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_assig
 
 /* Pass-through interrupts: bind real irq -> hvm devfn. */
 #define XEN_DOMCTL_bind_pt_irq       38
+#define XEN_DOMCTL_unbind_pt_irq     48
 typedef enum pt_irq_type_e {
     PT_IRQ_TYPE_PCI,
     PT_IRQ_TYPE_ISA
diff -r 63b0a8cb56ff -r f853c0497095 xen/include/public/hvm/ioreq.h
--- a/xen/include/public/hvm/ioreq.h    Tue Feb 19 09:28:09 2008 -0700
+++ b/xen/include/public/hvm/ioreq.h    Tue Feb 19 11:14:40 2008 -0700
@@ -114,11 +114,11 @@ struct buffered_piopage {
 };
 #endif /* defined(__ia64__) */
 
-#if defined(__i386__) || defined(__x86_64__)
 #define ACPI_PM1A_EVT_BLK_ADDRESS           0x0000000000001f40
 #define ACPI_PM1A_CNT_BLK_ADDRESS           (ACPI_PM1A_EVT_BLK_ADDRESS + 0x04)
 #define ACPI_PM_TMR_BLK_ADDRESS             (ACPI_PM1A_EVT_BLK_ADDRESS + 0x08)
-#endif /* defined(__i386__) || defined(__x86_64__) */
+#define ACPI_GPE0_BLK_ADDRESS               (ACPI_PM_TMR_BLK_ADDRESS + 0x20)
+#define ACPI_GPE0_BLK_LEN                   0x08
 
 #endif /* _IOREQ_H_ */
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.