aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/console/daemon/io.c2
-rw-r--r--tools/firmware/hvmloader/acpi/dsdt.asl126
-rw-r--r--tools/firmware/hvmloader/acpi/dsdt.c964
-rw-r--r--tools/firmware/hvmloader/acpi/static_tables.c2
-rw-r--r--tools/ioemu/hw/pass-through.c329
-rw-r--r--tools/ioemu/hw/pc.c6
-rw-r--r--tools/ioemu/hw/pci.c9
-rw-r--r--tools/ioemu/hw/piix4acpi.c389
-rw-r--r--tools/ioemu/monitor.c6
-rw-r--r--tools/ioemu/vl.c22
-rw-r--r--tools/ioemu/vl.h27
-rw-r--r--tools/ioemu/xenstore.c96
-rw-r--r--tools/libxc/xc_domain.c44
-rw-r--r--tools/libxc/xenctrl.h13
-rw-r--r--tools/python/xen/xend/XendDomainInfo.py202
-rw-r--r--tools/python/xen/xend/image.py31
-rw-r--r--tools/python/xen/xend/server/DevController.py8
-rw-r--r--tools/python/xen/xend/server/pciif.py48
-rw-r--r--tools/python/xen/xm/main.py67
-rw-r--r--xen/arch/x86/domctl.c45
-rw-r--r--xen/arch/x86/hvm/hvm.c24
-rw-r--r--xen/arch/x86/hvm/iommu.c10
-rw-r--r--xen/arch/x86/hvm/irq.c3
-rw-r--r--xen/arch/x86/hvm/svm/amd_iommu/pci-amd-iommu.c7
-rw-r--r--xen/arch/x86/hvm/vmx/vtd/dmar.c2
-rw-r--r--xen/arch/x86/hvm/vmx/vtd/intel-iommu.c22
-rw-r--r--xen/arch/x86/hvm/vmx/vtd/io.c61
-rw-r--r--xen/arch/x86/mm.c30
-rw-r--r--xen/arch/x86/mm/shadow/common.c7
-rw-r--r--xen/arch/x86/mm/shadow/multi.c100
-rw-r--r--xen/arch/x86/mm/shadow/private.h3
-rw-r--r--xen/include/asm-x86/domain.h10
-rw-r--r--xen/include/asm-x86/hvm/irq.h2
-rw-r--r--xen/include/asm-x86/iommu.h7
-rw-r--r--xen/include/asm-x86/perfc_defn.h3
-rw-r--r--xen/include/public/domctl.h2
-rw-r--r--xen/include/public/hvm/ioreq.h4
37 files changed, 2183 insertions, 550 deletions
diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c
index 9573333c08..396a0955d6 100644
--- a/tools/console/daemon/io.c
+++ b/tools/console/daemon/io.c
@@ -122,7 +122,7 @@ static int write_with_timestamp(int fd, const char *data, size_t sz)
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 --git a/tools/firmware/hvmloader/acpi/dsdt.asl b/tools/firmware/hvmloader/acpi/dsdt.asl
index fde51ac0ad..697a70f924 100644
--- a/tools/firmware/hvmloader/acpi/dsdt.asl
+++ b/tools/firmware/hvmloader/acpi/dsdt.asl
@@ -27,7 +27,14 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, "Xen", "HVM", 0)
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, "Xen", "HVM", 0)
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, "Xen", "HVM", 0)
})
}
}
+
+ /******************************************************************
+ * 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 --git a/tools/firmware/hvmloader/acpi/dsdt.c b/tools/firmware/hvmloader/acpi/dsdt.c
index 54088c6746..4ddc866f3a 100644
--- a/tools/firmware/hvmloader/acpi/dsdt.c
+++ b/tools/firmware/hvmloader/acpi/dsdt.c
@@ -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 --git a/tools/firmware/hvmloader/acpi/static_tables.c b/tools/firmware/hvmloader/acpi/static_tables.c
index 96d7f0c331..8a93218c14 100644
--- a/tools/firmware/hvmloader/acpi/static_tables.c
+++ b/tools/firmware/hvmloader/acpi/static_tables.c
@@ -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 --git a/tools/ioemu/hw/pass-through.c b/tools/ioemu/hw/pass-through.c
index d6fd35b9e9..29ffda451e 100644
--- a/tools/ioemu/hw/pass-through.c
+++ b/tools/ioemu/hw/pass-through.c
@@ -29,33 +29,161 @@
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;
+ char *token, *delim = ":.-";
- if ( !(*str) || !strchr(*str, ',') )
+ 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 */
void pt_iomem_map(PCIDevice *d, int i, uint32_t e_phys, uint32_t e_size,
int type)
@@ -269,15 +397,64 @@ static int pt_register_regions(struct pt_dev *assigned_device)
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);
@@ -296,6 +473,15 @@ struct pt_dev * register_real_device(PCIBus *e_bus,
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 */
assigned_device = (struct pt_dev *) pci_register_device(e_bus, e_dev_name,
sizeof(struct pt_dev), e_devfn,
@@ -306,8 +492,12 @@ struct pt_dev * register_real_device(PCIBus *e_bus,
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;
machine_bdf.bus = r_bus;
@@ -355,11 +545,96 @@ struct pt_dev * register_real_device(PCIBus *e_bus,
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();
@@ -371,6 +646,19 @@ int pt_init(PCIBus *e_bus, char *direct_pci)
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,8 +670,25 @@ int pt_init(PCIBus *e_bus, char *direct_pci)
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 --git a/tools/ioemu/hw/pc.c b/tools/ioemu/hw/pc.c
index c6ebc6780d..9731ef0aac 100644
--- a/tools/ioemu/hw/pc.c
+++ b/tools/ioemu/hw/pc.c
@@ -945,8 +945,10 @@ static void pc_init1(uint64_t ram_size, int vga_ram_size, char *boot_device,
}
#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 --git a/tools/ioemu/hw/pci.c b/tools/ioemu/hw/pci.c
index 1565758c3e..5d70133e88 100644
--- a/tools/ioemu/hw/pci.c
+++ b/tools/ioemu/hw/pci.c
@@ -107,7 +107,8 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
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;
@@ -132,6 +133,12 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
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,
uint32_t size, int type,
PCIMapIORegionFunc *map_func)
diff --git a/tools/ioemu/hw/piix4acpi.c b/tools/ioemu/hw/piix4acpi.c
index e232e82035..a4ebfc4163 100644
--- a/tools/ioemu/hw/piix4acpi.c
+++ b/tools/ioemu/hw/piix4acpi.c
@@ -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,8 +34,22 @@
/* 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;
@@ -43,6 +58,27 @@ typedef struct PCIAcpiState {
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)
{
PCIAcpiState *s = opaque;
@@ -58,7 +94,7 @@ static int piix4acpi_load(QEMUFile *f, void *opaque, int version_id)
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(void *opaque, uint32_t addr)
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 *opaque, uint32_t addr, uint32_t val)
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 *opaque, uint32_t addr, uint32_t val)
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(void *opaque, uint32_t addr)
}
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;
@@ -129,6 +176,326 @@ static void acpi_map(PCIDevice *pci_dev, int region_num,
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, int devfn)
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 --git a/tools/ioemu/monitor.c b/tools/ioemu/monitor.c
index abfe0666b9..9346f0d66a 100644
--- a/tools/ioemu/monitor.c
+++ b/tools/ioemu/monitor.c
@@ -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 --git a/tools/ioemu/vl.c b/tools/ioemu/vl.c
index 703f1bfd6d..f9a575043d 100644
--- a/tools/ioemu/vl.c
+++ b/tools/ioemu/vl.c
@@ -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 --git a/tools/ioemu/vl.h b/tools/ioemu/vl.h
index 00f5c16333..ae691b6131 100644
--- a/tools/ioemu/vl.h
+++ b/tools/ioemu/vl.h
@@ -817,11 +817,15 @@ 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,
PCIMapIORegionFunc *map_func);
@@ -850,6 +854,21 @@ 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, void *irq_opaque, int irq);
/* 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_add(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 readline_start(const char *prompt, int is_password,
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 --git a/tools/ioemu/xenstore.c b/tools/ioemu/xenstore.c
index 8cad6bda2d..843a10e875 100644
--- a/tools/ioemu/xenstore.c
+++ b/tools/ioemu/xenstore.c
@@ -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 domid)
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 domid)
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(void)
/* 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_event(void)
} 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,22 +478,27 @@ static void xenstore_process_dm_command_event(void)
free(command);
}
-void xenstore_record_dm_state(char *state)
+void xenstore_record_dm(char *subpath, 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");
+ "/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 state\n");
+ fprintf(logfile, "error recording dm \n");
out:
free(path);
}
+void xenstore_record_dm_state(char *state)
+{
+ xenstore_record_dm("state", state);
+}
+
void xenstore_process_event(void *opaque)
{
char **vec, *offset, *bpath = NULL, *buf = NULL, *drv = NULL, *image = NULL;
@@ -522,6 +589,23 @@ void xenstore_write_vncport(int display)
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)
{
char *buf = NULL, *path, *uuid = NULL, *passwd = NULL;
diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index 0f28ed5ca5..073fe95175 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -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 --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
index afc80a36df..b22497c01e 100644
--- a/tools/libxc/xenctrl.h
+++ b/tools/libxc/xenctrl.h
@@ -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 --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py
index c1cb6aa998..341433f0d3 100644
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/tools/python/xen/xend/XendDomainInfo.py
@@ -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,10 +714,65 @@ 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
# needed to remove its configuration.
@@ -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.
@@ -1543,6 +1742,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."""
if self.image:
diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py
index 069cde7dbe..414bf53d14 100644
--- a/tools/python/xen/xend/image.py
+++ b/tools/python/xen/xend/image.py
@@ -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 --git a/tools/python/xen/xend/server/DevController.py b/tools/python/xen/xend/server/DevController.py
index 8e70c376f7..89838096cc 100644
--- a/tools/python/xen/xend/server/DevController.py
+++ b/tools/python/xen/xend/server/DevController.py
@@ -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 --git a/tools/python/xen/xend/server/pciif.py b/tools/python/xen/xend/server/pciif.py
index ec875950ad..361fd80fd4 100644
--- a/tools/python/xen/xend/server/pciif.py
+++ b/tools/python/xen/xend/server/pciif.py
@@ -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 --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py
index 198477d8b0..da2de11d98 100644
--- a/tools/python/xen/xm/main.py
+++ b/tools/python/xen/xm/main.py
@@ -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
@@ -2263,6 +2320,12 @@ def xm_network_detach(args):
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()
try:
@@ -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 --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index abfda3e737..4e8ad4acde 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -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;
@@ -595,6 +623,23 @@ long arch_do_domctl(
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;
case XEN_DOMCTL_memory_mapping:
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 92a63bf325..d77fb6a402 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -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.
+ * Hence we do not gather extra PFEC flags if CR0.PG == 0.
+ */
+ if ( virt && (curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PG) )
{
- /*
- * 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;
- }
+ 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 --git a/xen/arch/x86/hvm/iommu.c b/xen/arch/x86/hvm/iommu.c
index 30c92f42ea..963ef5a029 100644
--- a/xen/arch/x86/hvm/iommu.c
+++ b/xen/arch/x86/hvm/iommu.c
@@ -133,3 +133,13 @@ int iommu_unmap_page(struct domain *d, unsigned long gfn)
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 --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c
index 072452a861..97eb25f9cb 100644
--- a/xen/arch/x86/hvm/irq.c
+++ b/xen/arch/x86/hvm/irq.c
@@ -211,8 +211,7 @@ void hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq)
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 --git a/xen/arch/x86/hvm/svm/amd_iommu/pci-amd-iommu.c b/xen/arch/x86/hvm/svm/amd_iommu/pci-amd-iommu.c
index 7caa276f73..815a1aee88 100644
--- a/xen/arch/x86/hvm/svm/amd_iommu/pci-amd-iommu.c
+++ b/xen/arch/x86/hvm/svm/amd_iommu/pci-amd-iommu.c
@@ -562,10 +562,17 @@ void amd_iommu_domain_destroy(struct domain *d)
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 --git a/xen/arch/x86/hvm/vmx/vtd/dmar.c b/xen/arch/x86/hvm/vmx/vtd/dmar.c
index 1e320ad27d..4f3f71e962 100644
--- a/xen/arch/x86/hvm/vmx/vtd/dmar.c
+++ b/xen/arch/x86/hvm/vmx/vtd/dmar.c
@@ -102,7 +102,7 @@ struct iommu * ioapic_to_iommu(unsigned int apic_id)
return drhd->iommu;
}
}
- dprintk(XENLOG_WARNING VTDPREFIX, "returning NULL\n");
+ dprintk(XENLOG_INFO VTDPREFIX, "returning NULL\n");
return NULL;
}
diff --git a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c
index c497b9c392..2eda71514e 100644
--- a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c
+++ b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c
@@ -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 domain *d)
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 domain *d, u8 bus, u8 devfn)
"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 --git a/xen/arch/x86/hvm/vmx/vtd/io.c b/xen/arch/x86/hvm/vmx/vtd/io.c
index 0962757a0e..714de89735 100644
--- a/xen/arch/x86/hvm/vmx/vtd/io.c
+++ b/xen/arch/x86/hvm/vmx/vtd/io.c
@@ -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 )
@@ -137,6 +137,65 @@ int pt_irq_create_bind_vtd(
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;
+}
+
int hvm_do_IRQ_dpci(struct domain *d, unsigned int mirq)
{
struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 0b0e8c1d94..469842787e 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -1443,16 +1443,18 @@ static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgentry_t nl1e,
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 *pl2e,
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 *pl3e,
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 *pl4e,
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 --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c
index f7c73e008b..d30e7e721a 100644
--- a/xen/arch/x86/mm/shadow/common.c
+++ b/xen/arch/x86/mm/shadow/common.c
@@ -1039,13 +1039,18 @@ void shadow_free(struct domain *d, mfn_t smfn)
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 --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c
index 8407beacf7..2103fe0d5b 100644
--- a/xen/arch/x86/mm/shadow/multi.c
+++ b/xen/arch/x86/mm/shadow/multi.c
@@ -2623,13 +2623,13 @@ sh_map_and_validate_gl1e(struct vcpu *v, mfn_t gl1mfn,
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 check_for_early_unshadow(struct vcpu *v, mfn_t gmfn)
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));
@@ -2982,14 +3027,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);
r = x86_emulate(&emul_ctxt.ctxt, emul_ops);
@@ -3001,15 +3038,44 @@ 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 ) {
int i;
@@ -3079,6 +3145,10 @@ sh_invlpg(struct vcpu *v, unsigned long va)
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
* run as high as 6% of invlpg calls where we haven't shadowed the l2
* yet. */
@@ -3815,6 +3885,10 @@ sh_update_cr3(struct vcpu *v, int do_locking)
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 --git a/xen/arch/x86/mm/shadow/private.h b/xen/arch/x86/mm/shadow/private.h
index 82d1e9e9b8..0c9edf63a2 100644
--- a/xen/arch/x86/mm/shadow/private.h
+++ b/xen/arch/x86/mm/shadow/private.h
@@ -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 SHOPT_FAST_EMULATION 0x80 /* Fast write emulation */
-#define SHADOW_OPTIMIZATIONS 0x7f
+#define SHADOW_OPTIMIZATIONS 0xff
/******************************************************************************
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 73ff9b817f..02477aa5c2 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -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 --git a/xen/include/asm-x86/hvm/irq.h b/xen/include/asm-x86/hvm/irq.h
index 355928d3ba..50ca945e32 100644
--- a/xen/include/asm-x86/hvm/irq.h
+++ b/xen/include/asm-x86/hvm/irq.h
@@ -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 --git a/xen/include/asm-x86/iommu.h b/xen/include/asm-x86/iommu.h
index 6707f94cbe..1f975dfa53 100644
--- a/xen/include/asm-x86/iommu.h
+++ b/xen/include/asm-x86/iommu.h
@@ -74,6 +74,10 @@ int iommu_domain_init(struct domain *d);
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 hvm_do_IRQ_dpci(struct domain *d, unsigned int irq);
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 --git a/xen/include/asm-x86/perfc_defn.h b/xen/include/asm-x86/perfc_defn.h
index 460c1f2b58..729550d8fa 100644
--- a/xen/include/asm-x86/perfc_defn.h
+++ b/xen/include/asm-x86/perfc_defn.h
@@ -57,6 +57,9 @@ PERFCOUNTER(shadow_fault_emulate_write, "shadow_fault emulates a write")
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 --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 7a254cd2b8..cfaa027357 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -441,6 +441,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendtrigger_t);
/* 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_assign_device_t);
/* 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 --git a/xen/include/public/hvm/ioreq.h b/xen/include/public/hvm/ioreq.h
index e14d5a9291..91e7de5c26 100644
--- a/xen/include/public/hvm/ioreq.h
+++ b/xen/include/public/hvm/ioreq.h
@@ -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_ */