]> git.proxmox.com Git - qemu.git/commitdiff
Merge remote-tracking branch 'kraxel/audio.2' into staging
authorAnthony Liguori <anthony@codemonkey.ws>
Thu, 31 Oct 2013 16:00:55 +0000 (17:00 +0100)
committerAnthony Liguori <anthony@codemonkey.ws>
Thu, 31 Oct 2013 16:00:55 +0000 (17:00 +0100)
* kraxel/audio.2:
  audio: honor QEMU_AUDIO_TIMER_PERIOD instead of waking up every *nano* second

Message-id: 1382622110-19460-1-git-send-email-kraxel@redhat.com
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
115 files changed:
configure
default-configs/arm-softmmu.mak
docs/memory.txt
hw/acpi/core.c
hw/acpi/ich9.c
hw/acpi/piix4.c
hw/arm/boot.c
hw/arm/integratorcp.c
hw/arm/omap_sx1.c
hw/arm/palm.c
hw/arm/z2.c
hw/audio/ac97.c
hw/audio/es1370.c
hw/audio/intel-hda.c
hw/block/nvme.c
hw/char/serial-pci.c
hw/char/tpci200.c
hw/core/irq.c
hw/core/loader.c
hw/core/sysbus.c
hw/display/qxl.c
hw/i386/Makefile.objs
hw/i386/acpi-build.c [new file with mode: 0644]
hw/i386/acpi-build.h [new file with mode: 0644]
hw/i386/acpi-defs.h [new file with mode: 0644]
hw/i386/acpi-dsdt-cpu-hotplug.dsl [new file with mode: 0644]
hw/i386/acpi-dsdt-dbug.dsl [new file with mode: 0644]
hw/i386/acpi-dsdt-hpet.dsl [new file with mode: 0644]
hw/i386/acpi-dsdt-isa.dsl [new file with mode: 0644]
hw/i386/acpi-dsdt-pci-crs.dsl [new file with mode: 0644]
hw/i386/acpi-dsdt.dsl [new file with mode: 0644]
hw/i386/acpi-dsdt.hex.generated [new file with mode: 0644]
hw/i386/bios-linker-loader.c [new file with mode: 0644]
hw/i386/bios-linker-loader.h [new file with mode: 0644]
hw/i386/pc.c
hw/i386/pc_piix.c
hw/i386/pc_q35.c
hw/i386/q35-acpi-dsdt.dsl [new file with mode: 0644]
hw/i386/q35-acpi-dsdt.hex.generated [new file with mode: 0644]
hw/i386/ssdt-misc.dsl [new file with mode: 0644]
hw/i386/ssdt-misc.hex.generated [new file with mode: 0644]
hw/i386/ssdt-pcihp.dsl [new file with mode: 0644]
hw/i386/ssdt-pcihp.hex.generated [new file with mode: 0644]
hw/i386/ssdt-proc.dsl [new file with mode: 0644]
hw/i386/ssdt-proc.hex.generated [new file with mode: 0644]
hw/ide/cmd646.c
hw/ide/ich.c
hw/isa/lpc_ich9.c
hw/isa/vt82c686.c
hw/lm32/lm32_hwsetup.h
hw/microblaze/boot.c
hw/microblaze/boot.h
hw/microblaze/petalogix_ml605_mmu.c
hw/microblaze/petalogix_s3adsp1800_mmu.c
hw/misc/Makefile.objs
hw/misc/arm_integrator_debug.c [new file with mode: 0644]
hw/misc/ivshmem.c
hw/misc/pvpanic.c
hw/misc/vfio.c
hw/net/e1000.c
hw/net/eepro100.c
hw/net/ne2000.c
hw/net/pcnet-pci.c
hw/net/rtl8139.c
hw/net/vmxnet3.c
hw/nvram/fw_cfg.c
hw/pci-bridge/pci_bridge_dev.c
hw/pci-host/piix.c
hw/pci-host/q35.c
hw/pci/pci.c
hw/pci/pcie.c
hw/pci/pcie_aer.c
hw/pci/pcie_host.c
hw/pci/shpc.c
hw/scsi/esp-pci.c
hw/scsi/lsi53c895a.c
hw/scsi/megasas.c
hw/scsi/vmw_pvscsi.c
hw/timer/hpet.c
hw/usb/hcd-ehci-pci.c
hw/usb/hcd-ohci.c
hw/usb/hcd-uhci.c
hw/usb/hcd-xhci.c
hw/usb/host-libusb.c
hw/virtio/virtio-pci.c
include/exec/memory.h
include/hw/acpi/acpi.h
include/hw/acpi/ich9.h
include/hw/acpi/piix4.h [new file with mode: 0644]
include/hw/i386/ich9.h
include/hw/i386/pc.h
include/hw/irq.h
include/hw/loader.h
include/hw/misc/arm_integrator_debug.h [new file with mode: 0644]
include/hw/nvram/fw_cfg.h
include/hw/pci-host/q35.h
include/hw/pci/pci.h
include/hw/pci/pci_bus.h
include/hw/pci/pcie.h
include/hw/pci/pcie_host.h
include/hw/sysbus.h
include/hw/timer/hpet.h
include/qom/object.h
memory.c
monitor.c
qom/object.c
scripts/acpi_extract.py [new file with mode: 0755]
scripts/acpi_extract_preprocess.py [new file with mode: 0755]
scripts/update-acpi.sh [new file with mode: 0644]
target-arm/cpu.h
target-arm/helper.c
target-arm/kvm.c
target-microblaze/cpu.h
target-microblaze/translate.c
vl.c

index 57ee62a6967a3c16e4e3d3183ff4fa213fd46ad9..03d82f59b80803d0220a246a099ade05c21d9f23 100755 (executable)
--- a/configure
+++ b/configure
@@ -119,6 +119,7 @@ path_of() {
 # default parameters
 source_path=`dirname "$0"`
 cpu=""
+iasl="iasl"
 interp_prefix="/usr/gnemul/qemu-%M"
 static="no"
 cross_prefix=""
@@ -257,6 +258,8 @@ for opt do
   ;;
   --cxx=*) CXX="$optarg"
   ;;
+  --iasl=*) iasl="$optarg"
+  ;;
   --source-path=*) source_path="$optarg"
   ;;
   --cpu=*) cpu="$optarg"
@@ -1058,6 +1061,7 @@ echo "Advanced options (experts only):"
 echo "  --source-path=PATH       path of source code [$source_path]"
 echo "  --cross-prefix=PREFIX    use PREFIX for compile tools [$cross_prefix]"
 echo "  --cc=CC                  use C compiler CC [$cc]"
+echo "  --iasl=IASL              use ACPI compiler IASL [$iasl]"
 echo "  --host-cc=CC             use C compiler CC [$host_cc] for code run at"
 echo "                           build time"
 echo "  --cxx=CXX                use C++ compiler CXX [$cxx]"
@@ -4234,6 +4238,9 @@ else
 fi
 echo "PYTHON=$python" >> $config_host_mak
 echo "CC=$cc" >> $config_host_mak
+if $iasl -h > /dev/null 2>&1; then
+  echo "IASL=$iasl" >> $config_host_mak
+fi
 echo "CC_I386=$cc_i386" >> $config_host_mak
 echo "HOST_CC=$host_cc" >> $config_host_mak
 echo "CXX=$cxx" >> $config_host_mak
@@ -4686,7 +4693,7 @@ for rom in seabios vgabios ; do
     echo "BCC=bcc" >> $config_mak
     echo "CPP=$cpp" >> $config_mak
     echo "OBJCOPY=objcopy" >> $config_mak
-    echo "IASL=iasl" >> $config_mak
+    echo "IASL=$iasl" >> $config_mak
     echo "LD=$ld" >> $config_mak
 done
 
index d13bc2bb2278e8d1f106799aa18f4d4a5b98ba2d..7e6913782edf5dfa7b8c35a460c62bf78cc85e5c 100644 (file)
@@ -79,3 +79,4 @@ CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
 
 CONFIG_SDHCI=y
+CONFIG_INTEGRATOR_DEBUG=y
index feb9fe90d7533786fc75518a63a207528d3a105f..174c0d7b435ca8933b34272c9c4bd885dce5ab0c 100644 (file)
@@ -80,6 +80,10 @@ guest.  This is done with memory_region_add_subregion_overlap(), which
 allows the region to overlap any other region in the same container, and
 specifies a priority that allows the core to decide which of two regions at
 the same address are visible (highest wins).
+Priority values are signed, and the default value is zero. This means that
+you can use memory_region_add_subregion_overlap() both to specify a region
+that must sit 'above' any others (with a positive priority) and also a
+background region that sits 'below' others (with a negative priority).
 
 Visibility
 ----------
index 7138139d324e981d9d41b31c51c1b22fd7e7ee0a..d8dff5b9d0665c3cec84b4274e70f045222089c1 100644 (file)
@@ -309,6 +309,46 @@ out:
     error_propagate(errp, err);
 }
 
+static bool acpi_table_builtin = false;
+
+void acpi_table_add_builtin(const QemuOpts *opts, Error **errp)
+{
+    acpi_table_builtin = true;
+    acpi_table_add(opts, errp);
+}
+
+unsigned acpi_table_len(void *current)
+{
+    struct acpi_table_header *hdr = current - sizeof(hdr->_length);
+    return hdr->_length;
+}
+
+static
+void *acpi_table_hdr(void *h)
+{
+    struct acpi_table_header *hdr = h;
+    return &hdr->sig;
+}
+
+uint8_t *acpi_table_first(void)
+{
+    if (acpi_table_builtin || !acpi_tables) {
+        return NULL;
+    }
+    return acpi_table_hdr(acpi_tables + ACPI_TABLE_PFX_SIZE);
+}
+
+uint8_t *acpi_table_next(uint8_t *current)
+{
+    uint8_t *next = current + acpi_table_len(current);
+
+    if (next - acpi_tables >= acpi_tables_len) {
+        return NULL;
+    } else {
+        return acpi_table_hdr(next);
+    }
+}
+
 static void acpi_notify_wakeup(Notifier *notifier, void *data)
 {
     ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup);
index 3fb443d06d809277b85f8c79e30e8b41c649111c..7e0429e0f944b24454d04217eae09e610d3b59bc 100644 (file)
@@ -24,6 +24,7 @@
  * GNU GPL, version 2 or (at your option) any later version.
  */
 #include "hw/hw.h"
+#include "qapi/visitor.h"
 #include "hw/i386/pc.h"
 #include "hw/pci/pci.h"
 #include "qemu/timer.h"
@@ -228,3 +229,26 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
     pm->powerdown_notifier.notify = pm_powerdown_req;
     qemu_register_powerdown_notifier(&pm->powerdown_notifier);
 }
+
+static void ich9_pm_get_gpe0_blk(Object *obj, Visitor *v,
+                                 void *opaque, const char *name,
+                                 Error **errp)
+{
+    ICH9LPCPMRegs *pm = opaque;
+    uint32_t value = pm->pm_io_base + ICH9_PMIO_GPE0_STS;
+
+    visit_type_uint32(v, &value, name, errp);
+}
+
+void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp)
+{
+    static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN;
+
+    object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
+                                   &pm->pm_io_base, errp);
+    object_property_add(obj, ACPI_PM_PROP_GPE0_BLK, "uint32",
+                        ich9_pm_get_gpe0_blk,
+                        NULL, NULL, pm, NULL);
+    object_property_add_uint32_ptr(obj, ACPI_PM_PROP_GPE0_BLK_LEN,
+                                   &gpe0_len, errp);
+}
index b46bd5ea6afec9ea4b41f047bd0c471fc1b006a2..3bcd89056796cace33e4fbfa72b0631b0beac436 100644 (file)
@@ -29,6 +29,7 @@
 #include "exec/ioport.h"
 #include "hw/nvram/fw_cfg.h"
 #include "exec/address-spaces.h"
+#include "hw/acpi/piix4.h"
 
 //#define DEBUG
 
@@ -69,6 +70,8 @@ typedef struct PIIX4PMState {
     /*< public >*/
 
     MemoryRegion io;
+    uint32_t io_base;
+
     MemoryRegion io_gpe;
     MemoryRegion io_pci;
     MemoryRegion io_cpu;
@@ -152,14 +155,13 @@ static void apm_ctrl_changed(uint32_t val, void *arg)
 static void pm_io_space_update(PIIX4PMState *s)
 {
     PCIDevice *d = PCI_DEVICE(s);
-    uint32_t pm_io_base;
 
-    pm_io_base = le32_to_cpu(*(uint32_t *)(d->config + 0x40));
-    pm_io_base &= 0xffc0;
+    s->io_base = le32_to_cpu(*(uint32_t *)(d->config + 0x40));
+    s->io_base &= 0xffc0;
 
     memory_region_transaction_begin();
     memory_region_set_enabled(&s->io, d->config[0x80] & 1);
-    memory_region_set_address(&s->io, pm_io_base);
+    memory_region_set_address(&s->io, s->io_base);
     memory_region_transaction_commit();
 }
 
@@ -407,6 +409,28 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque)
         (memory_region_present(io_as, 0x2f8) ? 0x90 : 0);
 }
 
+static void piix4_pm_add_propeties(PIIX4PMState *s)
+{
+    static const uint8_t acpi_enable_cmd = ACPI_ENABLE;
+    static const uint8_t acpi_disable_cmd = ACPI_DISABLE;
+    static const uint32_t gpe0_blk = GPE_BASE;
+    static const uint32_t gpe0_blk_len = GPE_LEN;
+    static const uint16_t sci_int = 9;
+
+    object_property_add_uint8_ptr(OBJECT(s), ACPI_PM_PROP_ACPI_ENABLE_CMD,
+                                  &acpi_enable_cmd, NULL);
+    object_property_add_uint8_ptr(OBJECT(s), ACPI_PM_PROP_ACPI_DISABLE_CMD,
+                                  &acpi_disable_cmd, NULL);
+    object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_GPE0_BLK,
+                                  &gpe0_blk, NULL);
+    object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_GPE0_BLK_LEN,
+                                  &gpe0_blk_len, NULL);
+    object_property_add_uint16_ptr(OBJECT(s), ACPI_PM_PROP_SCI_INT,
+                                  &sci_int, NULL);
+    object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_PM_IO_BASE,
+                                  &s->io_base, NULL);
+}
+
 static int piix4_pm_initfn(PCIDevice *dev)
 {
     PIIX4PMState *s = PIIX4_PM(dev);
@@ -456,9 +480,21 @@ static int piix4_pm_initfn(PCIDevice *dev)
 
     piix4_acpi_system_hot_add_init(pci_address_space_io(dev), dev->bus, s);
 
+    piix4_pm_add_propeties(s);
     return 0;
 }
 
+Object *piix4_pm_find(void)
+{
+    bool ambig;
+    Object *o = object_resolve_path_type("", TYPE_PIIX4_PM, &ambig);
+
+    if (ambig || !o) {
+        return NULL;
+    }
+    return o;
+}
+
 i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
                        qemu_irq sci_irq, qemu_irq smi_irq,
                        int kvm_enabled, FWCfgState *fw_cfg)
@@ -489,9 +525,9 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
 
 static Property piix4_pm_properties[] = {
     DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
-    DEFINE_PROP_UINT8("disable_s3", PIIX4PMState, disable_s3, 0),
-    DEFINE_PROP_UINT8("disable_s4", PIIX4PMState, disable_s4, 0),
-    DEFINE_PROP_UINT8("s4_val", PIIX4PMState, s4_val, 2),
+    DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0),
+    DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0),
+    DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2),
     DEFINE_PROP_END_OF_LIST(),
 };
 
index 1e313afe8d43c5629103c2853c65ca969df7a1b2..583ec7992e44af684ebdaba681fbebdbb82177ed 100644 (file)
@@ -354,8 +354,10 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
 
     /* Load the kernel.  */
     if (!info->kernel_filename) {
-        fprintf(stderr, "Kernel image must be specified\n");
-        exit(1);
+        /* If no kernel specified, do nothing; we will start from address 0
+         * (typically a boot ROM image) in the same way as hardware.
+         */
+        return;
     }
 
     info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
index 2ef93ed8d6a26e53da31167b01ad06061cf87a1b..c44b2a499cb1c7ab90fdb9f5f79d8219261d510b 100644 (file)
@@ -11,6 +11,7 @@
 #include "hw/devices.h"
 #include "hw/boards.h"
 #include "hw/arm/arm.h"
+#include "hw/misc/arm_integrator_debug.h"
 #include "net/net.h"
 #include "exec/address-spaces.h"
 #include "sysemu/sysemu.h"
@@ -508,6 +509,7 @@ static void integratorcp_init(QEMUMachineInitArgs *args)
     icp_control_init(0xcb000000);
     sysbus_create_simple("pl050_keyboard", 0x18000000, pic[3]);
     sysbus_create_simple("pl050_mouse", 0x19000000, pic[4]);
+    sysbus_create_simple(TYPE_INTEGRATOR_DEBUG, 0x1a000000, 0);
     sysbus_create_varargs("pl181", 0x1c000000, pic[23], pic[24], NULL);
     if (nd_table[0].used)
         smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
index b0f8664607f7b8e9488317d8379fac1ef3b5ee0f..03b381688bde99182645907c52a8d7f1a008f7f4 100644 (file)
@@ -194,12 +194,10 @@ static void sx1_init(QEMUMachineInitArgs *args, const int version)
     }
 
     /* Load the kernel.  */
-    if (args->kernel_filename) {
-        sx1_binfo.kernel_filename = args->kernel_filename;
-        sx1_binfo.kernel_cmdline = args->kernel_cmdline;
-        sx1_binfo.initrd_filename = args->initrd_filename;
-        arm_load_kernel(mpu->cpu, &sx1_binfo);
-    }
+    sx1_binfo.kernel_filename = args->kernel_filename;
+    sx1_binfo.kernel_cmdline = args->kernel_cmdline;
+    sx1_binfo.initrd_filename = args->initrd_filename;
+    arm_load_kernel(mpu->cpu, &sx1_binfo);
 
     /* TODO: fix next line */
     //~ qemu_console_resize(ds, 640, 480);
index 3e390448e2db67efe1224c14f71b9da43cfe997a..0b72bbe5fb9cbf32f07fa8e9ab0d80dffae2f28b 100644 (file)
@@ -261,12 +261,10 @@ static void palmte_init(QEMUMachineInitArgs *args)
     }
 
     /* Load the kernel.  */
-    if (kernel_filename) {
-        palmte_binfo.kernel_filename = kernel_filename;
-        palmte_binfo.kernel_cmdline = kernel_cmdline;
-        palmte_binfo.initrd_filename = initrd_filename;
-        arm_load_kernel(mpu->cpu, &palmte_binfo);
-    }
+    palmte_binfo.kernel_filename = kernel_filename;
+    palmte_binfo.kernel_cmdline = kernel_cmdline;
+    palmte_binfo.initrd_filename = initrd_filename;
+    arm_load_kernel(mpu->cpu, &palmte_binfo);
 }
 
 static QEMUMachine palmte_machine = {
index 2e0d5d4bcc1aa924ef2bb153e11db91ba34acb3a..a00fcc042d48af80a2c26ad44a7c3fe03fd8b832 100644 (file)
@@ -360,13 +360,11 @@ static void z2_init(QEMUMachineInitArgs *args)
     qdev_connect_gpio_out(mpu->gpio, Z2_GPIO_LCD_CS,
         qemu_allocate_irqs(z2_lcd_cs, z2_lcd, 1)[0]);
 
-    if (kernel_filename) {
-        z2_binfo.kernel_filename = kernel_filename;
-        z2_binfo.kernel_cmdline = kernel_cmdline;
-        z2_binfo.initrd_filename = initrd_filename;
-        z2_binfo.board_id = 0x6dd;
-        arm_load_kernel(mpu->cpu, &z2_binfo);
-    }
+    z2_binfo.kernel_filename = kernel_filename;
+    z2_binfo.kernel_cmdline = kernel_cmdline;
+    z2_binfo.initrd_filename = initrd_filename;
+    z2_binfo.board_id = 0x6dd;
+    arm_load_kernel(mpu->cpu, &z2_binfo);
 }
 
 static QEMUMachine z2_machine = {
index 01b4dfbc674b1c6e2dc548bb27a3c07934f1e86a..03f484628e0eef7049285eb1d9cbdc6f1f2ca2e8 100644 (file)
@@ -280,12 +280,12 @@ static void update_sr (AC97LinkState *s, AC97BusMasterRegs *r, uint32_t new_sr)
     if (level) {
         s->glob_sta |= masks[r - s->bm_regs];
         dolog ("set irq level=1\n");
-        qemu_set_irq (s->dev.irq[0], 1);
+        pci_irq_assert(&s->dev);
     }
     else {
         s->glob_sta &= ~masks[r - s->bm_regs];
         dolog ("set irq level=0\n");
-        qemu_set_irq (s->dev.irq[0], 0);
+        pci_irq_deassert(&s->dev);
     }
 }
 
index adb66ced713ae20eac6114c726aa00b145995353..1ec7acee024f2f8e71fdf63a9c0b66625dd1f6b6 100644 (file)
@@ -323,7 +323,7 @@ static void es1370_update_status (ES1370State *s, uint32_t new_status)
     else {
         s->status = new_status & ~STAT_INTR;
     }
-    qemu_set_irq (s->dev.irq[0], !!level);
+    pci_set_irq(&s->dev, !!level);
 }
 
 static void es1370_reset (ES1370State *s)
@@ -349,7 +349,7 @@ static void es1370_reset (ES1370State *s)
             s->dac_voice[i] = NULL;
         }
     }
-    qemu_irq_lower (s->dev.irq[0]);
+    pci_irq_deassert(&s->dev);
 }
 
 static void es1370_maybe_lower_irq (ES1370State *s, uint32_t sctl)
index a6666c6cdf6e7d5233f589135b31ecab37b7d0e0..43272643946d3533a190e8dfea5ede81999641bc 100644 (file)
@@ -269,7 +269,7 @@ static void intel_hda_update_irq(IntelHDAState *d)
             msi_notify(&d->pci, 0);
         }
     } else {
-        qemu_set_irq(d->pci.irq[0], level);
+        pci_set_irq(&d->pci, level);
     }
 }
 
index 5dee229734cc53efc986f3f5884be38f592b0910..2882ffefce6c7a49695fdf574f2f850d7f6b0f43 100644 (file)
@@ -69,7 +69,7 @@ static void nvme_isr_notify(NvmeCtrl *n, NvmeCQueue *cq)
         if (msix_enabled(&(n->parent_obj))) {
             msix_notify(&(n->parent_obj), cq->vector);
         } else {
-            qemu_irq_pulse(n->parent_obj.irq[0]);
+            pci_irq_pulse(&n->parent_obj);
         }
     }
 }
index aec6705a0108477d5b27729e1dd0513a63641954..991c99fa6ebdc803212b8fab99c4be123332a824 100644 (file)
@@ -61,7 +61,7 @@ static int serial_pci_init(PCIDevice *dev)
     }
 
     pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
-    s->irq = pci->dev.irq[0];
+    s->irq = pci_allocate_irq(&pci->dev);
 
     memory_region_init_io(&s->io, OBJECT(pci), &serial_io_ops, s, "serial", 8);
     pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
@@ -79,7 +79,7 @@ static void multi_serial_irq_mux(void *opaque, int n, int level)
             pending = 1;
         }
     }
-    qemu_set_irq(pci->dev.irq[0], pending);
+    pci_set_irq(&pci->dev, pending);
 }
 
 static int multi_serial_pci_init(PCIDevice *dev)
@@ -132,6 +132,7 @@ static void serial_pci_exit(PCIDevice *dev)
 
     serial_exit_core(s);
     memory_region_destroy(&s->io);
+    qemu_free_irq(s->irq);
 }
 
 static void multi_serial_pci_exit(PCIDevice *dev)
index e04ff26019e02e8246c6ee8860f6859552989cca..a49d2ed5c114967c04f2c5a9ef9063b22c1b8dd5 100644 (file)
@@ -134,8 +134,8 @@ static void tpci200_set_irq(void *opaque, int intno, int level)
     /* Check if the interrupt is edge sensitive */
     if (dev->ctrl[ip_n] & CTRL_INT_EDGE(intno)) {
         if (level) {
-            qemu_set_irq(dev->dev.irq[0], !dev->int_set);
-            qemu_set_irq(dev->dev.irq[0],  dev->int_set);
+            pci_set_irq(&dev->dev, !dev->int_set);
+            pci_set_irq(&dev->dev,  dev->int_set);
         }
     } else {
         unsigned i, j;
@@ -153,10 +153,10 @@ static void tpci200_set_irq(void *opaque, int intno, int level)
         }
 
         if (level_status && !dev->int_set) {
-            qemu_irq_raise(dev->dev.irq[0]);
+            pci_irq_assert(&dev->dev);
             dev->int_set = 1;
         } else if (!level_status && dev->int_set) {
-            qemu_irq_lower(dev->dev.irq[0]);
+            pci_irq_deassert(&dev->dev);
             dev->int_set = 0;
         }
     }
index 20785428ef00eff815b67a98a90a8816ccab9987..03c8cb31ea9b89ce11a7f1473b766902ae4fb9dd 100644 (file)
@@ -68,6 +68,17 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
     return qemu_extend_irqs(NULL, 0, handler, opaque, n);
 }
 
+qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n)
+{
+    struct IRQState *irq;
+
+    irq = g_new(struct IRQState, 1);
+    irq->handler = handler;
+    irq->opaque = opaque;
+    irq->n = n;
+
+    return irq;
+}
 
 void qemu_free_irqs(qemu_irq *s)
 {
@@ -75,6 +86,11 @@ void qemu_free_irqs(qemu_irq *s)
     g_free(s);
 }
 
+void qemu_free_irq(qemu_irq irq)
+{
+    g_free(irq);
+}
+
 static void qemu_notirq(void *opaque, int line, int level)
 {
     struct IRQState *irq = opaque;
index 7b3d3ee6a0dbfaa54e6ded0fdf44328da928b06b..60d2ebd4ac85d98079fd65cf3d5d955709ca02f3 100644 (file)
@@ -663,7 +663,7 @@ int rom_add_file(const char *file, const char *fw_dir,
     rom_insert(rom);
     if (rom->fw_file && fw_cfg) {
         const char *basename;
-        char fw_file_name[56];
+        char fw_file_name[FW_CFG_MAX_FILE_PATH];
         void *data;
 
         basename = strrchr(rom->fw_file, '/');
@@ -700,10 +700,12 @@ err:
     return -1;
 }
 
-int rom_add_blob(const char *name, const void *blob, size_t len,
-                 hwaddr addr)
+void *rom_add_blob(const char *name, const void *blob, size_t len,
+                   hwaddr addr, const char *fw_file_name,
+                   FWCfgReadCallback fw_callback, void *callback_opaque)
 {
     Rom *rom;
+    void *data = NULL;
 
     rom           = g_malloc0(sizeof(*rom));
     rom->name     = g_strdup(name);
@@ -713,7 +715,22 @@ int rom_add_blob(const char *name, const void *blob, size_t len,
     rom->data     = g_malloc0(rom->datasize);
     memcpy(rom->data, blob, len);
     rom_insert(rom);
-    return 0;
+    if (fw_file_name && fw_cfg) {
+        char devpath[100];
+
+        snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name);
+
+        if (rom_file_in_ram) {
+            data = rom_set_mr(rom, OBJECT(fw_cfg), devpath);
+        } else {
+            data = rom->data;
+        }
+
+        fw_cfg_add_file_callback(fw_cfg, fw_file_name,
+                                 fw_callback, callback_opaque,
+                                 data, rom->romsize);
+    }
+    return data;
 }
 
 /* This function is specific for elf program because we don't need to allocate
@@ -795,10 +812,14 @@ int rom_load_all(void)
         memory_region_unref(section.mr);
     }
     qemu_register_reset(rom_reset, NULL);
-    roms_loaded = 1;
     return 0;
 }
 
+void rom_load_done(void)
+{
+    roms_loaded = 1;
+}
+
 void rom_set_fw(FWCfgState *f)
 {
     fw_cfg = f;
index b84cd4a16f75975af9624ce08b80b3ee7b1f07ba..146f50aa157ac5047c30664adeb4673b74ca907f 100644 (file)
@@ -49,7 +49,7 @@ void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq)
 }
 
 static void sysbus_mmio_map_common(SysBusDevice *dev, int n, hwaddr addr,
-                                   bool may_overlap, unsigned priority)
+                                   bool may_overlap, int priority)
 {
     assert(n >= 0 && n < dev->num_mmio);
 
@@ -81,7 +81,7 @@ void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr)
 }
 
 void sysbus_mmio_map_overlap(SysBusDevice *dev, int n, hwaddr addr,
-                             unsigned priority)
+                             int priority)
 {
     sysbus_mmio_map_common(dev, n, addr, true, priority);
 }
index de835d6af821f50df3fdf800d4de114dcd6a395f..5977d526d48a5ac500dacdd64bb1893a959d36b5 100644 (file)
@@ -1101,7 +1101,7 @@ static void qxl_update_irq(PCIQXLDevice *d)
     uint32_t pending = le32_to_cpu(d->ram->int_pending);
     uint32_t mask    = le32_to_cpu(d->ram->int_mask);
     int level = !!(pending & mask);
-    qemu_set_irq(d->pci.irq[0], level);
+    pci_set_irq(&d->pci, level);
     qxl_ring_set_dirty(d);
 }
 
index 45e61655e9f786be3fd4e427896842528cefc070..185aacbc69e8be578a4970287e1b762e09b9b09f 100644 (file)
@@ -5,3 +5,30 @@ obj-y += pc_sysfw.o
 obj-$(CONFIG_XEN) += xen_domainbuild.o xen_machine_pv.o
 
 obj-y += kvmvapic.o
+obj-y += acpi-build.o
+obj-y += bios-linker-loader.o
+hw/i386/acpi-build.o: hw/i386/acpi-build.c hw/i386/acpi-dsdt.hex \
+       hw/i386/ssdt-proc.hex hw/i386/ssdt-pcihp.hex hw/i386/ssdt-misc.hex \
+       hw/i386/acpi-dsdt.hex hw/i386/q35-acpi-dsdt.hex
+
+iasl-option=$(shell if test -z "`$(1) $(2) 2>&1 > /dev/null`" \
+    ; then echo "$(2)"; else echo "$(3)"; fi ;)
+
+ifdef IASL
+#IASL Present. Generate hex files from .dsl
+hw/i386/%.hex: $(SRC_PATH)/hw/i386/%.dsl $(SRC_PATH)/scripts/acpi_extract_preprocess.py $(SRC_PATH)/scripts/acpi_extract.py
+       $(call quiet-command, cpp -P $< -o $*.dsl.i.orig, "  CPP $(TARGET_DIR)$*.dsl.i.orig")
+       $(call quiet-command, $(PYTHON) $(SRC_PATH)/scripts/acpi_extract_preprocess.py $*.dsl.i.orig > $*.dsl.i, "  ACPI_PREPROCESS $(TARGET_DIR)$*.dsl.i")
+       $(call quiet-command, $(IASL) $(call iasl-option,$(IASL),-Pn,) -vs -l -tc -p $* $*.dsl.i $(if $(V), , > /dev/null) 2>&1 ,"  IASL $(TARGET_DIR)$*.dsl.i")
+       $(call quiet-command, $(SRC_PATH)/scripts/acpi_extract.py $*.lst > $*.off, "  ACPI_EXTRACT $(TARGET_DIR)$*.off")
+       $(call quiet-command, cat $*.off > $@, "  CAT $(TARGET_DIR)$@")
+else
+#IASL Not present. Restore pre-generated hex files.
+hw/i386/%.hex: $(SRC_PATH)/hw/i386/%.hex.generated
+       $(call quiet-command, cp -f $< $@, "  CP $(TARGET_DIR)$@")
+endif
+
+.PHONY: cleanhex
+cleanhex:
+       rm -f hw/i386/*hex
+clean: cleanhex
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
new file mode 100644 (file)
index 0000000..6cfa044
--- /dev/null
@@ -0,0 +1,1214 @@
+/* Support for generating ACPI tables and passing them to Guests
+ *
+ * Copyright (C) 2008-2010  Kevin O'Connor <kevin@koconnor.net>
+ * Copyright (C) 2006 Fabrice Bellard
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * Author: Michael S. Tsirkin <mst@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "acpi-build.h"
+#include <stddef.h>
+#include <glib.h>
+#include "qemu-common.h"
+#include "qemu/bitmap.h"
+#include "qemu/range.h"
+#include "hw/pci/pci.h"
+#include "qom/cpu.h"
+#include "hw/i386/pc.h"
+#include "target-i386/cpu.h"
+#include "hw/timer/hpet.h"
+#include "hw/i386/acpi-defs.h"
+#include "hw/acpi/acpi.h"
+#include "hw/nvram/fw_cfg.h"
+#include "bios-linker-loader.h"
+#include "hw/loader.h"
+
+/* Supported chipsets: */
+#include "hw/acpi/piix4.h"
+#include "hw/i386/ich9.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/pci-host/q35.h"
+
+#include "hw/i386/q35-acpi-dsdt.hex"
+#include "hw/i386/acpi-dsdt.hex"
+
+#include "qapi/qmp/qint.h"
+#include "qom/qom-qobject.h"
+
+typedef struct AcpiCpuInfo {
+    DECLARE_BITMAP(found_cpus, MAX_CPUMASK_BITS + 1);
+} AcpiCpuInfo;
+
+typedef struct AcpiMcfgInfo {
+    uint64_t mcfg_base;
+    uint32_t mcfg_size;
+} AcpiMcfgInfo;
+
+typedef struct AcpiPmInfo {
+    bool s3_disabled;
+    bool s4_disabled;
+    uint8_t s4_val;
+    uint16_t sci_int;
+    uint8_t acpi_enable_cmd;
+    uint8_t acpi_disable_cmd;
+    uint32_t gpe0_blk;
+    uint32_t gpe0_blk_len;
+    uint32_t io_base;
+} AcpiPmInfo;
+
+typedef struct AcpiMiscInfo {
+    bool has_hpet;
+    DECLARE_BITMAP(slot_hotplug_enable, PCI_SLOT_MAX);
+    const unsigned char *dsdt_code;
+    unsigned dsdt_size;
+    uint16_t pvpanic_port;
+} AcpiMiscInfo;
+
+static void acpi_get_dsdt(AcpiMiscInfo *info)
+{
+    Object *piix = piix4_pm_find();
+    Object *lpc = ich9_lpc_find();
+    assert(!!piix != !!lpc);
+
+    if (piix) {
+        info->dsdt_code = AcpiDsdtAmlCode;
+        info->dsdt_size = sizeof AcpiDsdtAmlCode;
+    }
+    if (lpc) {
+        info->dsdt_code = Q35AcpiDsdtAmlCode;
+        info->dsdt_size = sizeof Q35AcpiDsdtAmlCode;
+    }
+}
+
+static
+int acpi_add_cpu_info(Object *o, void *opaque)
+{
+    AcpiCpuInfo *cpu = opaque;
+    uint64_t apic_id;
+
+    if (object_dynamic_cast(o, TYPE_CPU)) {
+        apic_id = object_property_get_int(o, "apic-id", NULL);
+        assert(apic_id <= MAX_CPUMASK_BITS);
+
+        set_bit(apic_id, cpu->found_cpus);
+    }
+
+    object_child_foreach(o, acpi_add_cpu_info, opaque);
+    return 0;
+}
+
+static void acpi_get_cpu_info(AcpiCpuInfo *cpu)
+{
+    Object *root = object_get_root();
+
+    memset(cpu->found_cpus, 0, sizeof cpu->found_cpus);
+    object_child_foreach(root, acpi_add_cpu_info, cpu);
+}
+
+static void acpi_get_pm_info(AcpiPmInfo *pm)
+{
+    Object *piix = piix4_pm_find();
+    Object *lpc = ich9_lpc_find();
+    Object *obj = NULL;
+    QObject *o;
+
+    if (piix) {
+        obj = piix;
+    }
+    if (lpc) {
+        obj = lpc;
+    }
+    assert(obj);
+
+    /* Fill in optional s3/s4 related properties */
+    o = object_property_get_qobject(obj, ACPI_PM_PROP_S3_DISABLED, NULL);
+    if (o) {
+        pm->s3_disabled = qint_get_int(qobject_to_qint(o));
+    } else {
+        pm->s3_disabled = false;
+    }
+    o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_DISABLED, NULL);
+    if (o) {
+        pm->s4_disabled = qint_get_int(qobject_to_qint(o));
+    } else {
+        pm->s4_disabled = false;
+    }
+    o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_VAL, NULL);
+    if (o) {
+        pm->s4_val = qint_get_int(qobject_to_qint(o));
+    } else {
+        pm->s4_val = false;
+    }
+
+    /* Fill in mandatory properties */
+    pm->sci_int = object_property_get_int(obj, ACPI_PM_PROP_SCI_INT, NULL);
+
+    pm->acpi_enable_cmd = object_property_get_int(obj,
+                                                  ACPI_PM_PROP_ACPI_ENABLE_CMD,
+                                                  NULL);
+    pm->acpi_disable_cmd = object_property_get_int(obj,
+                                                  ACPI_PM_PROP_ACPI_DISABLE_CMD,
+                                                  NULL);
+    pm->io_base = object_property_get_int(obj, ACPI_PM_PROP_PM_IO_BASE,
+                                          NULL);
+    pm->gpe0_blk = object_property_get_int(obj, ACPI_PM_PROP_GPE0_BLK,
+                                           NULL);
+    pm->gpe0_blk_len = object_property_get_int(obj, ACPI_PM_PROP_GPE0_BLK_LEN,
+                                               NULL);
+}
+
+static void acpi_get_hotplug_info(AcpiMiscInfo *misc)
+{
+    int i;
+    PCIBus *bus = find_i440fx();
+
+    if (!bus) {
+        /* Only PIIX supports ACPI hotplug */
+        memset(misc->slot_hotplug_enable, 0, sizeof misc->slot_hotplug_enable);
+        return;
+    }
+
+    memset(misc->slot_hotplug_enable, 0xff,
+           DIV_ROUND_UP(PCI_SLOT_MAX, BITS_PER_BYTE));
+
+    for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
+        PCIDeviceClass *pc;
+        PCIDevice *pdev = bus->devices[i];
+
+        if (!pdev) {
+            continue;
+        }
+
+        pc = PCI_DEVICE_GET_CLASS(pdev);
+
+        if (pc->no_hotplug) {
+            int slot = PCI_SLOT(i);
+
+            clear_bit(slot, misc->slot_hotplug_enable);
+        }
+    }
+}
+
+static void acpi_get_misc_info(AcpiMiscInfo *info)
+{
+    info->has_hpet = hpet_find();
+    info->pvpanic_port = pvpanic_port();
+}
+
+static void acpi_get_pci_info(PcPciInfo *info)
+{
+    Object *pci_host;
+    bool ambiguous;
+
+    pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
+    g_assert(!ambiguous);
+    g_assert(pci_host);
+
+    info->w32.begin = object_property_get_int(pci_host,
+                                              PCI_HOST_PROP_PCI_HOLE_START,
+                                              NULL);
+    info->w32.end = object_property_get_int(pci_host,
+                                            PCI_HOST_PROP_PCI_HOLE_END,
+                                            NULL);
+    info->w64.begin = object_property_get_int(pci_host,
+                                              PCI_HOST_PROP_PCI_HOLE64_START,
+                                              NULL);
+    info->w64.end = object_property_get_int(pci_host,
+                                            PCI_HOST_PROP_PCI_HOLE64_END,
+                                            NULL);
+}
+
+#define ACPI_BUILD_APPNAME  "Bochs"
+#define ACPI_BUILD_APPNAME6 "BOCHS "
+#define ACPI_BUILD_APPNAME4 "BXPC"
+
+#define ACPI_BUILD_DPRINTF(level, fmt, ...) do {} while (0)
+
+#define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
+#define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
+
+static void
+build_header(GArray *linker, GArray *table_data,
+             AcpiTableHeader *h, uint32_t sig, int len, uint8_t rev)
+{
+    h->signature = cpu_to_le32(sig);
+    h->length = cpu_to_le32(len);
+    h->revision = rev;
+    memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
+    memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);
+    memcpy(h->oem_table_id + 4, (void *)&sig, 4);
+    h->oem_revision = cpu_to_le32(1);
+    memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
+    h->asl_compiler_revision = cpu_to_le32(1);
+    h->checksum = 0;
+    /* Checksum to be filled in by Guest linker */
+    bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
+                                    table_data->data, h, len, &h->checksum);
+}
+
+static inline GArray *build_alloc_array(void)
+{
+        return g_array_new(false, true /* clear */, 1);
+}
+
+static inline void build_free_array(GArray *array)
+{
+        g_array_free(array, true);
+}
+
+static inline void build_prepend_byte(GArray *array, uint8_t val)
+{
+    g_array_prepend_val(array, val);
+}
+
+static inline void build_append_byte(GArray *array, uint8_t val)
+{
+    g_array_append_val(array, val);
+}
+
+static inline void build_append_array(GArray *array, GArray *val)
+{
+    g_array_append_vals(array, val->data, val->len);
+}
+
+static void build_append_nameseg(GArray *array, const char *format, ...)
+{
+    GString *s = g_string_new("");
+    va_list args;
+
+    va_start(args, format);
+    g_string_vprintf(s, format, args);
+    va_end(args);
+
+    assert(s->len == 4);
+    g_array_append_vals(array, s->str, s->len);
+    g_string_free(s, true);
+}
+
+/* 5.4 Definition Block Encoding */
+enum {
+    PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
+    PACKAGE_LENGTH_2BYTE_SHIFT = 4,
+    PACKAGE_LENGTH_3BYTE_SHIFT = 12,
+    PACKAGE_LENGTH_4BYTE_SHIFT = 20,
+};
+
+static void build_prepend_package_length(GArray *package, unsigned min_bytes)
+{
+    uint8_t byte;
+    unsigned length = package->len;
+    unsigned length_bytes;
+
+    if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) {
+        length_bytes = 1;
+    } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) {
+        length_bytes = 2;
+    } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) {
+        length_bytes = 3;
+    } else {
+        length_bytes = 4;
+    }
+
+    /* Force length to at least min_bytes.
+     * This wastes memory but that's how bios did it.
+     */
+    length_bytes = MAX(length_bytes, min_bytes);
+
+    /* PkgLength is the length of the inclusive length of the data. */
+    length += length_bytes;
+
+    switch (length_bytes) {
+    case 1:
+        byte = length;
+        build_prepend_byte(package, byte);
+        return;
+    case 4:
+        byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT;
+        build_prepend_byte(package, byte);
+        length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1;
+        /* fall through */
+    case 3:
+        byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT;
+        build_prepend_byte(package, byte);
+        length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1;
+        /* fall through */
+    case 2:
+        byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT;
+        build_prepend_byte(package, byte);
+        length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1;
+        /* fall through */
+    }
+    /*
+     * Most significant two bits of byte zero indicate how many following bytes
+     * are in PkgLength encoding.
+     */
+    byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length;
+    build_prepend_byte(package, byte);
+}
+
+static void build_package(GArray *package, uint8_t op, unsigned min_bytes)
+{
+    build_prepend_package_length(package, min_bytes);
+    build_prepend_byte(package, op);
+}
+
+static void build_append_value(GArray *table, uint32_t value, int size)
+{
+    uint8_t prefix;
+    int i;
+
+    switch (size) {
+    case 1:
+        prefix = 0x0A; /* BytePrefix */
+        break;
+    case 2:
+        prefix = 0x0B; /* WordPrefix */
+        break;
+    case 4:
+        prefix = 0x0C; /* DWordPrefix */
+        break;
+    default:
+        assert(0);
+        return;
+    }
+    build_append_byte(table, prefix);
+    for (i = 0; i < size; ++i) {
+        build_append_byte(table, value & 0xFF);
+        value = value >> 8;
+    }
+}
+
+static void build_append_notify_target(GArray *method, GArray *target_name,
+                                       uint32_t value, int size)
+{
+    GArray *notify = build_alloc_array();
+    uint8_t op = 0xA0; /* IfOp */
+
+    build_append_byte(notify, 0x93); /* LEqualOp */
+    build_append_byte(notify, 0x68); /* Arg0Op */
+    build_append_value(notify, value, size);
+    build_append_byte(notify, 0x86); /* NotifyOp */
+    build_append_array(notify, target_name);
+    build_append_byte(notify, 0x69); /* Arg1Op */
+
+    /* Pack it up */
+    build_package(notify, op, 1);
+
+    build_append_array(method, notify);
+
+    build_free_array(notify);
+}
+
+#define ACPI_PORT_SMI_CMD           0x00b2 /* TODO: this is APM_CNT_IOPORT */
+
+static inline void *acpi_data_push(GArray *table_data, unsigned size)
+{
+    unsigned off = table_data->len;
+    g_array_set_size(table_data, off + size);
+    return table_data->data + off;
+}
+
+static unsigned acpi_data_len(GArray *table)
+{
+    return table->len * g_array_get_element_size(table);
+}
+
+static void acpi_align_size(GArray *blob, unsigned align)
+{
+    /* Align size to multiple of given size. This reduces the chance
+     * we need to change size in the future (breaking cross version migration).
+     */
+    g_array_set_size(blob, (ROUND_UP(acpi_data_len(blob), align) +
+                            g_array_get_element_size(blob) - 1) /
+                             g_array_get_element_size(blob));
+}
+
+/* Get pointer within table in a safe manner */
+#define ACPI_BUILD_PTR(table, size, off, type) \
+    ((type *)(acpi_data_get_ptr(table, size, off, sizeof(type))))
+
+static inline void *acpi_data_get_ptr(uint8_t *table_data, unsigned table_size,
+                                      unsigned off, unsigned size)
+{
+    assert(off + size > off);
+    assert(off + size <= table_size);
+    return table_data + off;
+}
+
+static inline void acpi_add_table(GArray *table_offsets, GArray *table_data)
+{
+    uint32_t offset = cpu_to_le32(table_data->len);
+    g_array_append_val(table_offsets, offset);
+}
+
+/* FACS */
+static void
+build_facs(GArray *table_data, GArray *linker, PcGuestInfo *guest_info)
+{
+    AcpiFacsDescriptorRev1 *facs = acpi_data_push(table_data, sizeof *facs);
+    facs->signature = cpu_to_le32(ACPI_FACS_SIGNATURE);
+    facs->length = cpu_to_le32(sizeof(*facs));
+}
+
+/* Load chipset information in FADT */
+static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
+{
+    fadt->model = 1;
+    fadt->reserved1 = 0;
+    fadt->sci_int = cpu_to_le16(pm->sci_int);
+    fadt->smi_cmd = cpu_to_le32(ACPI_PORT_SMI_CMD);
+    fadt->acpi_enable = pm->acpi_enable_cmd;
+    fadt->acpi_disable = pm->acpi_disable_cmd;
+    /* EVT, CNT, TMR offset matches hw/acpi/core.c */
+    fadt->pm1a_evt_blk = cpu_to_le32(pm->io_base);
+    fadt->pm1a_cnt_blk = cpu_to_le32(pm->io_base + 0x04);
+    fadt->pm_tmr_blk = cpu_to_le32(pm->io_base + 0x08);
+    fadt->gpe0_blk = cpu_to_le32(pm->gpe0_blk);
+    /* EVT, CNT, TMR length matches hw/acpi/core.c */
+    fadt->pm1_evt_len = 4;
+    fadt->pm1_cnt_len = 2;
+    fadt->pm_tmr_len = 4;
+    fadt->gpe0_blk_len = pm->gpe0_blk_len;
+    fadt->plvl2_lat = cpu_to_le16(0xfff); /* C2 state not supported */
+    fadt->plvl3_lat = cpu_to_le16(0xfff); /* C3 state not supported */
+    fadt->flags = cpu_to_le32((1 << ACPI_FADT_F_WBINVD) |
+                              (1 << ACPI_FADT_F_PROC_C1) |
+                              (1 << ACPI_FADT_F_SLP_BUTTON) |
+                              (1 << ACPI_FADT_F_RTC_S4));
+    fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_USE_PLATFORM_CLOCK);
+}
+
+
+/* FADT */
+static void
+build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
+           unsigned facs, unsigned dsdt)
+{
+    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
+
+    fadt->firmware_ctrl = cpu_to_le32(facs);
+    /* FACS address to be filled by Guest linker */
+    bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
+                                   ACPI_BUILD_TABLE_FILE,
+                                   table_data, &fadt->firmware_ctrl,
+                                   sizeof fadt->firmware_ctrl);
+
+    fadt->dsdt = cpu_to_le32(dsdt);
+    /* DSDT address to be filled by Guest linker */
+    bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
+                                   ACPI_BUILD_TABLE_FILE,
+                                   table_data, &fadt->dsdt,
+                                   sizeof fadt->dsdt);
+
+    fadt_setup(fadt, pm);
+
+    build_header(linker, table_data,
+                 (void *)fadt, ACPI_FACP_SIGNATURE, sizeof(*fadt), 1);
+}
+
+static void
+build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu,
+           PcGuestInfo *guest_info)
+{
+    int madt_start = table_data->len;
+
+    AcpiMultipleApicTable *madt;
+    AcpiMadtIoApic *io_apic;
+    AcpiMadtIntsrcovr *intsrcovr;
+    AcpiMadtLocalNmi *local_nmi;
+    int i;
+
+    madt = acpi_data_push(table_data, sizeof *madt);
+    madt->local_apic_address = cpu_to_le32(APIC_DEFAULT_ADDRESS);
+    madt->flags = cpu_to_le32(1);
+
+    for (i = 0; i < guest_info->apic_id_limit; i++) {
+        AcpiMadtProcessorApic *apic = acpi_data_push(table_data, sizeof *apic);
+        apic->type = ACPI_APIC_PROCESSOR;
+        apic->length = sizeof(*apic);
+        apic->processor_id = i;
+        apic->local_apic_id = i;
+        if (test_bit(i, cpu->found_cpus)) {
+            apic->flags = cpu_to_le32(1);
+        } else {
+            apic->flags = cpu_to_le32(0);
+        }
+    }
+    io_apic = acpi_data_push(table_data, sizeof *io_apic);
+    io_apic->type = ACPI_APIC_IO;
+    io_apic->length = sizeof(*io_apic);
+#define ACPI_BUILD_IOAPIC_ID 0x0
+    io_apic->io_apic_id = ACPI_BUILD_IOAPIC_ID;
+    io_apic->address = cpu_to_le32(IO_APIC_DEFAULT_ADDRESS);
+    io_apic->interrupt = cpu_to_le32(0);
+
+    if (guest_info->apic_xrupt_override) {
+        intsrcovr = acpi_data_push(table_data, sizeof *intsrcovr);
+        intsrcovr->type   = ACPI_APIC_XRUPT_OVERRIDE;
+        intsrcovr->length = sizeof(*intsrcovr);
+        intsrcovr->source = 0;
+        intsrcovr->gsi    = cpu_to_le32(2);
+        intsrcovr->flags  = cpu_to_le16(0); /* conforms to bus specifications */
+    }
+    for (i = 1; i < 16; i++) {
+#define ACPI_BUILD_PCI_IRQS ((1<<5) | (1<<9) | (1<<10) | (1<<11))
+        if (!(ACPI_BUILD_PCI_IRQS & (1 << i))) {
+            /* No need for a INT source override structure. */
+            continue;
+        }
+        intsrcovr = acpi_data_push(table_data, sizeof *intsrcovr);
+        intsrcovr->type   = ACPI_APIC_XRUPT_OVERRIDE;
+        intsrcovr->length = sizeof(*intsrcovr);
+        intsrcovr->source = i;
+        intsrcovr->gsi    = cpu_to_le32(i);
+        intsrcovr->flags  = cpu_to_le16(0xd); /* active high, level triggered */
+    }
+
+    local_nmi = acpi_data_push(table_data, sizeof *local_nmi);
+    local_nmi->type         = ACPI_APIC_LOCAL_NMI;
+    local_nmi->length       = sizeof(*local_nmi);
+    local_nmi->processor_id = 0xff; /* all processors */
+    local_nmi->flags        = cpu_to_le16(0);
+    local_nmi->lint         = 1; /* ACPI_LINT1 */
+
+    build_header(linker, table_data,
+                 (void *)(table_data->data + madt_start), ACPI_APIC_SIGNATURE,
+                 table_data->len - madt_start, 1);
+}
+
+/* Encode a hex value */
+static inline char acpi_get_hex(uint32_t val)
+{
+    val &= 0x0f;
+    return (val <= 9) ? ('0' + val) : ('A' + val - 10);
+}
+
+#include "hw/i386/ssdt-proc.hex"
+
+/* 0x5B 0x83 ProcessorOp PkgLength NameString ProcID */
+#define ACPI_PROC_OFFSET_CPUHEX (*ssdt_proc_name - *ssdt_proc_start + 2)
+#define ACPI_PROC_OFFSET_CPUID1 (*ssdt_proc_name - *ssdt_proc_start + 4)
+#define ACPI_PROC_OFFSET_CPUID2 (*ssdt_proc_id - *ssdt_proc_start)
+#define ACPI_PROC_SIZEOF (*ssdt_proc_end - *ssdt_proc_start)
+#define ACPI_PROC_AML (ssdp_proc_aml + *ssdt_proc_start)
+
+/* 0x5B 0x82 DeviceOp PkgLength NameString */
+#define ACPI_PCIHP_OFFSET_HEX (*ssdt_pcihp_name - *ssdt_pcihp_start + 1)
+#define ACPI_PCIHP_OFFSET_ID (*ssdt_pcihp_id - *ssdt_pcihp_start)
+#define ACPI_PCIHP_OFFSET_ADR (*ssdt_pcihp_adr - *ssdt_pcihp_start)
+#define ACPI_PCIHP_OFFSET_EJ0 (*ssdt_pcihp_ej0 - *ssdt_pcihp_start)
+#define ACPI_PCIHP_SIZEOF (*ssdt_pcihp_end - *ssdt_pcihp_start)
+#define ACPI_PCIHP_AML (ssdp_pcihp_aml + *ssdt_pcihp_start)
+
+#define ACPI_SSDT_SIGNATURE 0x54445353 /* SSDT */
+#define ACPI_SSDT_HEADER_LENGTH 36
+
+#include "hw/i386/ssdt-misc.hex"
+#include "hw/i386/ssdt-pcihp.hex"
+
+static void
+build_append_notify(GArray *device, const char *name,
+                    const char *format, int skip, int count)
+{
+    int i;
+    GArray *method = build_alloc_array();
+    uint8_t op = 0x14; /* MethodOp */
+
+    build_append_nameseg(method, name);
+    build_append_byte(method, 0x02); /* MethodFlags: ArgCount */
+    for (i = skip; i < count; i++) {
+        GArray *target = build_alloc_array();
+        build_append_nameseg(target, format, i);
+        assert(i < 256); /* Fits in 1 byte */
+        build_append_notify_target(method, target, i, 1);
+        build_free_array(target);
+    }
+    build_package(method, op, 2);
+
+    build_append_array(device, method);
+    build_free_array(method);
+}
+
+static void patch_pcihp(int slot, uint8_t *ssdt_ptr, uint32_t eject)
+{
+    ssdt_ptr[ACPI_PCIHP_OFFSET_HEX] = acpi_get_hex(slot >> 4);
+    ssdt_ptr[ACPI_PCIHP_OFFSET_HEX + 1] = acpi_get_hex(slot);
+    ssdt_ptr[ACPI_PCIHP_OFFSET_ID] = slot;
+    ssdt_ptr[ACPI_PCIHP_OFFSET_ADR + 2] = slot;
+
+    /* Runtime patching of ACPI_EJ0: to disable hotplug for a slot,
+     * replace the method name: _EJ0 by ACPI_EJ0_.
+     */
+    /* Sanity check */
+    assert(!memcmp(ssdt_ptr + ACPI_PCIHP_OFFSET_EJ0, "_EJ0", 4));
+
+    if (!eject) {
+        memcpy(ssdt_ptr + ACPI_PCIHP_OFFSET_EJ0, "EJ0_", 4);
+    }
+}
+
+static void patch_pci_windows(PcPciInfo *pci, uint8_t *start, unsigned size)
+{
+    *ACPI_BUILD_PTR(start, size, acpi_pci32_start[0], uint32_t) =
+        cpu_to_le32(pci->w32.begin);
+
+    *ACPI_BUILD_PTR(start, size, acpi_pci32_end[0], uint32_t) =
+        cpu_to_le32(pci->w32.end - 1);
+
+    if (pci->w64.end || pci->w64.begin) {
+        *ACPI_BUILD_PTR(start, size, acpi_pci64_valid[0], uint8_t) = 1;
+        *ACPI_BUILD_PTR(start, size, acpi_pci64_start[0], uint64_t) =
+            cpu_to_le64(pci->w64.begin);
+        *ACPI_BUILD_PTR(start, size, acpi_pci64_end[0], uint64_t) =
+            cpu_to_le64(pci->w64.end - 1);
+        *ACPI_BUILD_PTR(start, size, acpi_pci64_length[0], uint64_t) =
+            cpu_to_le64(pci->w64.end - pci->w64.begin);
+    } else {
+        *ACPI_BUILD_PTR(start, size, acpi_pci64_valid[0], uint8_t) = 0;
+    }
+}
+
+static void
+build_ssdt(GArray *table_data, GArray *linker,
+           AcpiCpuInfo *cpu, AcpiPmInfo *pm, AcpiMiscInfo *misc,
+           PcPciInfo *pci, PcGuestInfo *guest_info)
+{
+    int acpi_cpus = MIN(0xff, guest_info->apic_id_limit);
+    int ssdt_start = table_data->len;
+    uint8_t *ssdt_ptr;
+    int i;
+
+    /* Copy header and patch values in the S3_ / S4_ / S5_ packages */
+    ssdt_ptr = acpi_data_push(table_data, sizeof(ssdp_misc_aml));
+    memcpy(ssdt_ptr, ssdp_misc_aml, sizeof(ssdp_misc_aml));
+    if (pm->s3_disabled) {
+        ssdt_ptr[acpi_s3_name[0]] = 'X';
+    }
+    if (pm->s4_disabled) {
+        ssdt_ptr[acpi_s4_name[0]] = 'X';
+    } else {
+        ssdt_ptr[acpi_s4_pkg[0] + 1] = ssdt_ptr[acpi_s4_pkg[0] + 3] =
+            pm->s4_val;
+    }
+
+    patch_pci_windows(pci, ssdt_ptr, sizeof(ssdp_misc_aml));
+
+    *(uint16_t *)(ssdt_ptr + *ssdt_isa_pest) =
+        cpu_to_le16(misc->pvpanic_port);
+
+    {
+        GArray *sb_scope = build_alloc_array();
+        uint8_t op = 0x10; /* ScopeOp */
+
+        build_append_nameseg(sb_scope, "_SB_");
+
+        /* build Processor object for each processor */
+        for (i = 0; i < acpi_cpus; i++) {
+            uint8_t *proc = acpi_data_push(sb_scope, ACPI_PROC_SIZEOF);
+            memcpy(proc, ACPI_PROC_AML, ACPI_PROC_SIZEOF);
+            proc[ACPI_PROC_OFFSET_CPUHEX] = acpi_get_hex(i >> 4);
+            proc[ACPI_PROC_OFFSET_CPUHEX+1] = acpi_get_hex(i);
+            proc[ACPI_PROC_OFFSET_CPUID1] = i;
+            proc[ACPI_PROC_OFFSET_CPUID2] = i;
+        }
+
+        /* build this code:
+         *   Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}
+         */
+        /* Arg0 = Processor ID = APIC ID */
+        build_append_notify(sb_scope, "NTFY", "CP%0.02X", 0, acpi_cpus);
+
+        /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })" */
+        build_append_byte(sb_scope, 0x08); /* NameOp */
+        build_append_nameseg(sb_scope, "CPON");
+
+        {
+            GArray *package = build_alloc_array();
+            uint8_t op = 0x12; /* PackageOp */
+
+            build_append_byte(package, acpi_cpus); /* NumElements */
+            for (i = 0; i < acpi_cpus; i++) {
+                uint8_t b = test_bit(i, cpu->found_cpus) ? 0x01 : 0x00;
+                build_append_byte(package, b);
+            }
+
+            build_package(package, op, 2);
+            build_append_array(sb_scope, package);
+            build_free_array(package);
+        }
+
+        {
+            GArray *pci0 = build_alloc_array();
+            uint8_t op = 0x10; /* ScopeOp */;
+
+            build_append_nameseg(pci0, "PCI0");
+
+            /* build Device object for each slot */
+            for (i = 1; i < PCI_SLOT_MAX; i++) {
+                bool eject = test_bit(i, misc->slot_hotplug_enable);
+                void *pcihp = acpi_data_push(pci0, ACPI_PCIHP_SIZEOF);
+
+                memcpy(pcihp, ACPI_PCIHP_AML, ACPI_PCIHP_SIZEOF);
+                patch_pcihp(i, pcihp, eject);
+            }
+
+            build_append_notify(pci0, "PCNT", "S%0.02X_", 1, PCI_SLOT_MAX);
+            build_package(pci0, op, 3);
+            build_append_array(sb_scope, pci0);
+            build_free_array(pci0);
+        }
+
+        build_package(sb_scope, op, 3);
+        build_append_array(table_data, sb_scope);
+        build_free_array(sb_scope);
+    }
+
+    build_header(linker, table_data,
+                 (void *)(table_data->data + ssdt_start),
+                 ACPI_SSDT_SIGNATURE, table_data->len - ssdt_start, 1);
+}
+
+static void
+build_hpet(GArray *table_data, GArray *linker)
+{
+    Acpi20Hpet *hpet;
+
+    hpet = acpi_data_push(table_data, sizeof(*hpet));
+    /* Note timer_block_id value must be kept in sync with value advertised by
+     * emulated hpet
+     */
+    hpet->timer_block_id = cpu_to_le32(0x8086a201);
+    hpet->addr.address = cpu_to_le64(HPET_BASE);
+    build_header(linker, table_data,
+                 (void *)hpet, ACPI_HPET_SIGNATURE, sizeof(*hpet), 1);
+}
+
+static void
+acpi_build_srat_memory(AcpiSratMemoryAffinity *numamem,
+                       uint64_t base, uint64_t len, int node, int enabled)
+{
+    numamem->type = ACPI_SRAT_MEMORY;
+    numamem->length = sizeof(*numamem);
+    memset(numamem->proximity, 0, 4);
+    numamem->proximity[0] = node;
+    numamem->flags = cpu_to_le32(!!enabled);
+    numamem->base_addr = cpu_to_le64(base);
+    numamem->range_length = cpu_to_le64(len);
+}
+
+static void
+build_srat(GArray *table_data, GArray *linker,
+           AcpiCpuInfo *cpu, PcGuestInfo *guest_info)
+{
+    AcpiSystemResourceAffinityTable *srat;
+    AcpiSratProcessorAffinity *core;
+    AcpiSratMemoryAffinity *numamem;
+
+    int i;
+    uint64_t curnode;
+    int srat_start, numa_start, slots;
+    uint64_t mem_len, mem_base, next_base;
+
+    srat_start = table_data->len;
+
+    srat = acpi_data_push(table_data, sizeof *srat);
+    srat->reserved1 = cpu_to_le32(1);
+    core = (void *)(srat + 1);
+
+    for (i = 0; i < guest_info->apic_id_limit; ++i) {
+        core = acpi_data_push(table_data, sizeof *core);
+        core->type = ACPI_SRAT_PROCESSOR;
+        core->length = sizeof(*core);
+        core->local_apic_id = i;
+        curnode = guest_info->node_cpu[i];
+        core->proximity_lo = curnode;
+        memset(core->proximity_hi, 0, 3);
+        core->local_sapic_eid = 0;
+        if (test_bit(i, cpu->found_cpus)) {
+            core->flags = cpu_to_le32(1);
+        } else {
+            core->flags = cpu_to_le32(0);
+        }
+    }
+
+
+    /* the memory map is a bit tricky, it contains at least one hole
+     * from 640k-1M and possibly another one from 3.5G-4G.
+     */
+    next_base = 0;
+    numa_start = table_data->len;
+
+    numamem = acpi_data_push(table_data, sizeof *numamem);
+    acpi_build_srat_memory(numamem, 0, 640*1024, 0, 1);
+    next_base = 1024 * 1024;
+    for (i = 1; i < guest_info->numa_nodes + 1; ++i) {
+        mem_base = next_base;
+        mem_len = guest_info->node_mem[i - 1];
+        if (i == 1) {
+            mem_len -= 1024 * 1024;
+        }
+        next_base = mem_base + mem_len;
+
+        /* Cut out the ACPI_PCI hole */
+        if (mem_base <= guest_info->ram_size &&
+            next_base > guest_info->ram_size) {
+            mem_len -= next_base - guest_info->ram_size;
+            if (mem_len > 0) {
+                numamem = acpi_data_push(table_data, sizeof *numamem);
+                acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1);
+            }
+            mem_base = 1ULL << 32;
+            mem_len = next_base - guest_info->ram_size;
+            next_base += (1ULL << 32) - guest_info->ram_size;
+        }
+        numamem = acpi_data_push(table_data, sizeof *numamem);
+        acpi_build_srat_memory(numamem, mem_base, mem_len, i - 1, 1);
+    }
+    slots = (table_data->len - numa_start) / sizeof *numamem;
+    for (; slots < guest_info->numa_nodes + 2; slots++) {
+        numamem = acpi_data_push(table_data, sizeof *numamem);
+        acpi_build_srat_memory(numamem, 0, 0, 0, 0);
+    }
+
+    build_header(linker, table_data,
+                 (void *)(table_data->data + srat_start),
+                 ACPI_SRAT_SIGNATURE,
+                 table_data->len - srat_start, 1);
+}
+
+static void
+build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
+{
+    AcpiTableMcfg *mcfg;
+    uint32_t sig;
+    int len = sizeof(*mcfg) + 1 * sizeof(mcfg->allocation[0]);
+
+    mcfg = acpi_data_push(table_data, len);
+    mcfg->allocation[0].address = cpu_to_le64(info->mcfg_base);
+    /* Only a single allocation so no need to play with segments */
+    mcfg->allocation[0].pci_segment = cpu_to_le16(0);
+    mcfg->allocation[0].start_bus_number = 0;
+    mcfg->allocation[0].end_bus_number = PCIE_MMCFG_BUS(info->mcfg_size - 1);
+
+    /* MCFG is used for ECAM which can be enabled or disabled by guest.
+     * To avoid table size changes (which create migration issues),
+     * always create the table even if there are no allocations,
+     * but set the signature to a reserved value in this case.
+     * ACPI spec requires OSPMs to ignore such tables.
+     */
+    if (info->mcfg_base == PCIE_BASE_ADDR_UNMAPPED) {
+        sig = ACPI_RSRV_SIGNATURE;
+    } else {
+        sig = ACPI_MCFG_SIGNATURE;
+    }
+    build_header(linker, table_data, (void *)mcfg, sig, len, 1);
+}
+
+static void
+build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
+{
+    void *dsdt;
+    assert(misc->dsdt_code && misc->dsdt_size);
+    dsdt = acpi_data_push(table_data, misc->dsdt_size);
+    memcpy(dsdt, misc->dsdt_code, misc->dsdt_size);
+}
+
+/* Build final rsdt table */
+static void
+build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
+{
+    AcpiRsdtDescriptorRev1 *rsdt;
+    size_t rsdt_len;
+    int i;
+
+    rsdt_len = sizeof(*rsdt) + sizeof(uint32_t) * table_offsets->len;
+    rsdt = acpi_data_push(table_data, rsdt_len);
+    memcpy(rsdt->table_offset_entry, table_offsets->data,
+           sizeof(uint32_t) * table_offsets->len);
+    for (i = 0; i < table_offsets->len; ++i) {
+        /* rsdt->table_offset_entry to be filled by Guest linker */
+        bios_linker_loader_add_pointer(linker,
+                                       ACPI_BUILD_TABLE_FILE,
+                                       ACPI_BUILD_TABLE_FILE,
+                                       table_data, &rsdt->table_offset_entry[i],
+                                       sizeof(uint32_t));
+    }
+    build_header(linker, table_data,
+                 (void *)rsdt, ACPI_RSDT_SIGNATURE, rsdt_len, 1);
+}
+
+static GArray *
+build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
+{
+    AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);
+
+    bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 1,
+                             true /* fseg memory */);
+
+    rsdp->signature = cpu_to_le64(ACPI_RSDP_SIGNATURE);
+    memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, 6);
+    rsdp->rsdt_physical_address = cpu_to_le32(rsdt);
+    /* Address to be filled by Guest linker */
+    bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
+                                   ACPI_BUILD_TABLE_FILE,
+                                   rsdp_table, &rsdp->rsdt_physical_address,
+                                   sizeof rsdp->rsdt_physical_address);
+    rsdp->checksum = 0;
+    /* Checksum to be filled by Guest linker */
+    bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
+                                    rsdp, rsdp, sizeof *rsdp, &rsdp->checksum);
+
+    return rsdp_table;
+}
+
+typedef
+struct AcpiBuildTables {
+    GArray *table_data;
+    GArray *rsdp;
+    GArray *linker;
+} AcpiBuildTables;
+
+static inline void acpi_build_tables_init(AcpiBuildTables *tables)
+{
+    tables->rsdp = g_array_new(false, true /* clear */, 1);
+    tables->table_data = g_array_new(false, true /* clear */, 1);
+    tables->linker = bios_linker_loader_init();
+}
+
+static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
+{
+    void *linker_data = bios_linker_loader_cleanup(tables->linker);
+    if (mfre) {
+        g_free(linker_data);
+    }
+    g_array_free(tables->rsdp, mfre);
+    g_array_free(tables->table_data, mfre);
+}
+
+typedef
+struct AcpiBuildState {
+    /* Copy of table in RAM (for patching). */
+    uint8_t *table_ram;
+    uint32_t table_size;
+    /* Is table patched? */
+    uint8_t patched;
+    PcGuestInfo *guest_info;
+} AcpiBuildState;
+
+static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
+{
+    Object *pci_host;
+    QObject *o;
+    bool ambiguous;
+
+    pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
+    g_assert(!ambiguous);
+    g_assert(pci_host);
+
+    o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_BASE, NULL);
+    if (!o) {
+        return false;
+    }
+    mcfg->mcfg_base = qint_get_int(qobject_to_qint(o));
+
+    o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL);
+    assert(o);
+    mcfg->mcfg_size = qint_get_int(qobject_to_qint(o));
+    return true;
+}
+
+static
+void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
+{
+    GArray *table_offsets;
+    unsigned facs, dsdt, rsdt;
+    AcpiCpuInfo cpu;
+    AcpiPmInfo pm;
+    AcpiMiscInfo misc;
+    AcpiMcfgInfo mcfg;
+    PcPciInfo pci;
+    uint8_t *u;
+
+    acpi_get_cpu_info(&cpu);
+    acpi_get_pm_info(&pm);
+    acpi_get_dsdt(&misc);
+    acpi_get_hotplug_info(&misc);
+    acpi_get_misc_info(&misc);
+    acpi_get_pci_info(&pci);
+
+    table_offsets = g_array_new(false, true /* clear */,
+                                        sizeof(uint32_t));
+    ACPI_BUILD_DPRINTF(3, "init ACPI tables\n");
+
+    bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE,
+                             64 /* Ensure FACS is aligned */,
+                             false /* high memory */);
+
+    /*
+     * FACS is pointed to by FADT.
+     * We place it first since it's the only table that has alignment
+     * requirements.
+     */
+    facs = tables->table_data->len;
+    build_facs(tables->table_data, tables->linker, guest_info);
+
+    /* DSDT is pointed to by FADT */
+    dsdt = tables->table_data->len;
+    build_dsdt(tables->table_data, tables->linker, &misc);
+
+    /* ACPI tables pointed to by RSDT */
+    acpi_add_table(table_offsets, tables->table_data);
+    build_fadt(tables->table_data, tables->linker, &pm, facs, dsdt);
+    acpi_add_table(table_offsets, tables->table_data);
+
+    build_ssdt(tables->table_data, tables->linker, &cpu, &pm, &misc, &pci,
+               guest_info);
+    acpi_add_table(table_offsets, tables->table_data);
+
+    build_madt(tables->table_data, tables->linker, &cpu, guest_info);
+    acpi_add_table(table_offsets, tables->table_data);
+    if (misc.has_hpet) {
+        build_hpet(tables->table_data, tables->linker);
+    }
+    if (guest_info->numa_nodes) {
+        acpi_add_table(table_offsets, tables->table_data);
+        build_srat(tables->table_data, tables->linker, &cpu, guest_info);
+    }
+    if (acpi_get_mcfg(&mcfg)) {
+        acpi_add_table(table_offsets, tables->table_data);
+        build_mcfg_q35(tables->table_data, tables->linker, &mcfg);
+    }
+
+    /* Add tables supplied by user (if any) */
+    for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
+        unsigned len = acpi_table_len(u);
+
+        acpi_add_table(table_offsets, tables->table_data);
+        g_array_append_vals(tables->table_data, u, len);
+    }
+
+    /* RSDT is pointed to by RSDP */
+    rsdt = tables->table_data->len;
+    build_rsdt(tables->table_data, tables->linker, table_offsets);
+
+    /* RSDP is in FSEG memory, so allocate it separately */
+    build_rsdp(tables->rsdp, tables->linker, rsdt);
+
+    /* We'll expose it all to Guest so align size to reduce
+     * chance of size changes.
+     * RSDP is small so it's easy to keep it immutable, no need to
+     * bother with alignment.
+     */
+    acpi_align_size(tables->table_data, 0x1000);
+
+    acpi_align_size(tables->linker, 0x1000);
+
+    /* Cleanup memory that's no longer used. */
+    g_array_free(table_offsets, true);
+}
+
+static void acpi_build_update(void *build_opaque, uint32_t offset)
+{
+    AcpiBuildState *build_state = build_opaque;
+    AcpiBuildTables tables;
+
+    /* No state to update or already patched? Nothing to do. */
+    if (!build_state || build_state->patched) {
+        return;
+    }
+    build_state->patched = 1;
+
+    acpi_build_tables_init(&tables);
+
+    acpi_build(build_state->guest_info, &tables);
+
+    assert(acpi_data_len(tables.table_data) == build_state->table_size);
+    memcpy(build_state->table_ram, tables.table_data->data,
+           build_state->table_size);
+
+    acpi_build_tables_cleanup(&tables, true);
+}
+
+static void acpi_build_reset(void *build_opaque)
+{
+    AcpiBuildState *build_state = build_opaque;
+    build_state->patched = 0;
+}
+
+static void *acpi_add_rom_blob(AcpiBuildState *build_state, GArray *blob,
+                               const char *name)
+{
+    return rom_add_blob(name, blob->data, acpi_data_len(blob), -1, name,
+                        acpi_build_update, build_state);
+}
+
+static const VMStateDescription vmstate_acpi_build = {
+    .name = "acpi_build",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT8(patched, AcpiBuildState),
+        VMSTATE_END_OF_LIST()
+    },
+};
+
+void acpi_setup(PcGuestInfo *guest_info)
+{
+    AcpiBuildTables tables;
+    AcpiBuildState *build_state;
+
+    if (!guest_info->fw_cfg) {
+        ACPI_BUILD_DPRINTF(3, "No fw cfg. Bailing out.\n");
+        return;
+    }
+
+    if (!guest_info->has_acpi_build) {
+        ACPI_BUILD_DPRINTF(3, "ACPI build disabled. Bailing out.\n");
+        return;
+    }
+
+    build_state = g_malloc0(sizeof *build_state);
+
+    build_state->guest_info = guest_info;
+
+    acpi_build_tables_init(&tables);
+    acpi_build(build_state->guest_info, &tables);
+
+    /* Now expose it all to Guest */
+    build_state->table_ram = acpi_add_rom_blob(build_state, tables.table_data,
+                                               ACPI_BUILD_TABLE_FILE);
+    build_state->table_size = acpi_data_len(tables.table_data);
+
+    acpi_add_rom_blob(NULL, tables.linker, "etc/table-loader");
+
+    /*
+     * RSDP is small so it's easy to keep it immutable, no need to
+     * bother with ROM blobs.
+     */
+    fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_RSDP_FILE,
+                    tables.rsdp->data, acpi_data_len(tables.rsdp));
+
+    qemu_register_reset(acpi_build_reset, build_state);
+    acpi_build_reset(build_state);
+    vmstate_register(NULL, 0, &vmstate_acpi_build, build_state);
+
+    /* Cleanup tables but don't free the memory: we track it
+     * in build_state.
+     */
+    acpi_build_tables_cleanup(&tables, false);
+}
diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
new file mode 100644 (file)
index 0000000..e57b1aa
--- /dev/null
@@ -0,0 +1,9 @@
+
+#ifndef HW_I386_ACPI_BUILD_H
+#define HW_I386_ACPI_BUILD_H
+
+#include "qemu/typedefs.h"
+
+void acpi_setup(PcGuestInfo *);
+
+#endif
diff --git a/hw/i386/acpi-defs.h b/hw/i386/acpi-defs.h
new file mode 100644 (file)
index 0000000..78ca204
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef QEMU_ACPI_DEFS_H
+#define QEMU_ACPI_DEFS_H
+
+enum {
+    ACPI_FADT_F_WBINVD,
+    ACPI_FADT_F_WBINVD_FLUSH,
+    ACPI_FADT_F_PROC_C1,
+    ACPI_FADT_F_P_LVL2_UP,
+    ACPI_FADT_F_PWR_BUTTON,
+    ACPI_FADT_F_SLP_BUTTON,
+    ACPI_FADT_F_FIX_RTC,
+    ACPI_FADT_F_RTC_S4,
+    ACPI_FADT_F_TMR_VAL_EXT,
+    ACPI_FADT_F_DCK_CAP,
+    ACPI_FADT_F_RESET_REG_SUP,
+    ACPI_FADT_F_SEALED_CASE,
+    ACPI_FADT_F_HEADLESS,
+    ACPI_FADT_F_CPU_SW_SLP,
+    ACPI_FADT_F_PCI_EXP_WAK,
+    ACPI_FADT_F_USE_PLATFORM_CLOCK,
+    ACPI_FADT_F_S4_RTC_STS_VALID,
+    ACPI_FADT_F_REMOTE_POWER_ON_CAPABLE,
+    ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL,
+    ACPI_FADT_F_FORCE_APIC_PHYSICAL_DESTINATION_MODE,
+    ACPI_FADT_F_HW_REDUCED_ACPI,
+    ACPI_FADT_F_LOW_POWER_S0_IDLE_CAPABLE,
+};
+
+/*
+ * ACPI 2.0 Generic Address Space definition.
+ */
+struct Acpi20GenericAddress {
+    uint8_t  address_space_id;
+    uint8_t  register_bit_width;
+    uint8_t  register_bit_offset;
+    uint8_t  reserved;
+    uint64_t address;
+} QEMU_PACKED;
+typedef struct Acpi20GenericAddress Acpi20GenericAddress;
+
+#define ACPI_RSDP_SIGNATURE 0x2052545020445352LL // "RSD PTR "
+
+struct AcpiRsdpDescriptor {        /* Root System Descriptor Pointer */
+    uint64_t signature;              /* ACPI signature, contains "RSD PTR " */
+    uint8_t  checksum;               /* To make sum of struct == 0 */
+    uint8_t  oem_id [6];             /* OEM identification */
+    uint8_t  revision;               /* Must be 0 for 1.0, 2 for 2.0 */
+    uint32_t rsdt_physical_address;  /* 32-bit physical address of RSDT */
+    uint32_t length;                 /* XSDT Length in bytes including hdr */
+    uint64_t xsdt_physical_address;  /* 64-bit physical address of XSDT */
+    uint8_t  extended_checksum;      /* Checksum of entire table */
+    uint8_t  reserved [3];           /* Reserved field must be 0 */
+} QEMU_PACKED;
+typedef struct AcpiRsdpDescriptor AcpiRsdpDescriptor;
+
+/* Table structure from Linux kernel (the ACPI tables are under the
+   BSD license) */
+
+
+#define ACPI_TABLE_HEADER_DEF   /* ACPI common table header */ \
+    uint32_t signature;          /* ACPI signature (4 ASCII characters) */ \
+    uint32_t length;                 /* Length of table, in bytes, including header */ \
+    uint8_t  revision;               /* ACPI Specification minor version # */ \
+    uint8_t  checksum;               /* To make sum of entire table == 0 */ \
+    uint8_t  oem_id [6];             /* OEM identification */ \
+    uint8_t  oem_table_id [8];       /* OEM table identification */ \
+    uint32_t oem_revision;           /* OEM revision number */ \
+    uint8_t  asl_compiler_id [4];    /* ASL compiler vendor ID */ \
+    uint32_t asl_compiler_revision;  /* ASL compiler revision number */
+
+
+struct AcpiTableHeader         /* ACPI common table header */
+{
+    ACPI_TABLE_HEADER_DEF
+} QEMU_PACKED;
+typedef struct AcpiTableHeader AcpiTableHeader;
+
+/*
+ * ACPI 1.0 Fixed ACPI Description Table (FADT)
+ */
+#define ACPI_FACP_SIGNATURE 0x50434146 // FACP
+struct AcpiFadtDescriptorRev1
+{
+    ACPI_TABLE_HEADER_DEF     /* ACPI common table header */
+    uint32_t firmware_ctrl;          /* Physical address of FACS */
+    uint32_t dsdt;                   /* Physical address of DSDT */
+    uint8_t  model;                  /* System Interrupt Model */
+    uint8_t  reserved1;              /* Reserved */
+    uint16_t sci_int;                /* System vector of SCI interrupt */
+    uint32_t smi_cmd;                /* Port address of SMI command port */
+    uint8_t  acpi_enable;            /* Value to write to smi_cmd to enable ACPI */
+    uint8_t  acpi_disable;           /* Value to write to smi_cmd to disable ACPI */
+    uint8_t  S4bios_req;             /* Value to write to SMI CMD to enter S4BIOS state */
+    uint8_t  reserved2;              /* Reserved - must be zero */
+    uint32_t pm1a_evt_blk;           /* Port address of Power Mgt 1a acpi_event Reg Blk */
+    uint32_t pm1b_evt_blk;           /* Port address of Power Mgt 1b acpi_event Reg Blk */
+    uint32_t pm1a_cnt_blk;           /* Port address of Power Mgt 1a Control Reg Blk */
+    uint32_t pm1b_cnt_blk;           /* Port address of Power Mgt 1b Control Reg Blk */
+    uint32_t pm2_cnt_blk;            /* Port address of Power Mgt 2 Control Reg Blk */
+    uint32_t pm_tmr_blk;             /* Port address of Power Mgt Timer Ctrl Reg Blk */
+    uint32_t gpe0_blk;               /* Port addr of General Purpose acpi_event 0 Reg Blk */
+    uint32_t gpe1_blk;               /* Port addr of General Purpose acpi_event 1 Reg Blk */
+    uint8_t  pm1_evt_len;            /* Byte length of ports at pm1_x_evt_blk */
+    uint8_t  pm1_cnt_len;            /* Byte length of ports at pm1_x_cnt_blk */
+    uint8_t  pm2_cnt_len;            /* Byte Length of ports at pm2_cnt_blk */
+    uint8_t  pm_tmr_len;             /* Byte Length of ports at pm_tm_blk */
+    uint8_t  gpe0_blk_len;           /* Byte Length of ports at gpe0_blk */
+    uint8_t  gpe1_blk_len;           /* Byte Length of ports at gpe1_blk */
+    uint8_t  gpe1_base;              /* Offset in gpe model where gpe1 events start */
+    uint8_t  reserved3;              /* Reserved */
+    uint16_t plvl2_lat;              /* Worst case HW latency to enter/exit C2 state */
+    uint16_t plvl3_lat;              /* Worst case HW latency to enter/exit C3 state */
+    uint16_t flush_size;             /* Size of area read to flush caches */
+    uint16_t flush_stride;           /* Stride used in flushing caches */
+    uint8_t  duty_offset;            /* Bit location of duty cycle field in p_cnt reg */
+    uint8_t  duty_width;             /* Bit width of duty cycle field in p_cnt reg */
+    uint8_t  day_alrm;               /* Index to day-of-month alarm in RTC CMOS RAM */
+    uint8_t  mon_alrm;               /* Index to month-of-year alarm in RTC CMOS RAM */
+    uint8_t  century;                /* Index to century in RTC CMOS RAM */
+    uint8_t  reserved4;              /* Reserved */
+    uint8_t  reserved4a;             /* Reserved */
+    uint8_t  reserved4b;             /* Reserved */
+    uint32_t flags;
+} QEMU_PACKED;
+typedef struct AcpiFadtDescriptorRev1 AcpiFadtDescriptorRev1;
+
+/*
+ * ACPI 1.0 Root System Description Table (RSDT)
+ */
+#define ACPI_RSDT_SIGNATURE 0x54445352 // RSDT
+struct AcpiRsdtDescriptorRev1
+{
+    ACPI_TABLE_HEADER_DEF       /* ACPI common table header */
+    uint32_t table_offset_entry[0];  /* Array of pointers to other */
+    /* ACPI tables */
+} QEMU_PACKED;
+typedef struct AcpiRsdtDescriptorRev1 AcpiRsdtDescriptorRev1;
+
+/*
+ * ACPI 1.0 Firmware ACPI Control Structure (FACS)
+ */
+#define ACPI_FACS_SIGNATURE 0x53434146 // FACS
+struct AcpiFacsDescriptorRev1
+{
+    uint32_t signature;           /* ACPI Signature */
+    uint32_t length;                 /* Length of structure, in bytes */
+    uint32_t hardware_signature;     /* Hardware configuration signature */
+    uint32_t firmware_waking_vector; /* ACPI OS waking vector */
+    uint32_t global_lock;            /* Global Lock */
+    uint32_t flags;
+    uint8_t  resverved3 [40];        /* Reserved - must be zero */
+} QEMU_PACKED;
+typedef struct AcpiFacsDescriptorRev1 AcpiFacsDescriptorRev1;
+
+/*
+ * Differentiated System Description Table (DSDT)
+ */
+#define ACPI_DSDT_SIGNATURE 0x54445344 // DSDT
+
+/*
+ * MADT values and structures
+ */
+
+/* Values for MADT PCATCompat */
+
+#define ACPI_DUAL_PIC                0
+#define ACPI_MULTIPLE_APIC           1
+
+/* Master MADT */
+
+#define ACPI_APIC_SIGNATURE 0x43495041 // APIC
+struct AcpiMultipleApicTable
+{
+    ACPI_TABLE_HEADER_DEF     /* ACPI common table header */
+    uint32_t local_apic_address;     /* Physical address of local APIC */
+    uint32_t flags;
+} QEMU_PACKED;
+typedef struct AcpiMultipleApicTable AcpiMultipleApicTable;
+
+/* Values for Type in APIC sub-headers */
+
+#define ACPI_APIC_PROCESSOR          0
+#define ACPI_APIC_IO                 1
+#define ACPI_APIC_XRUPT_OVERRIDE     2
+#define ACPI_APIC_NMI                3
+#define ACPI_APIC_LOCAL_NMI          4
+#define ACPI_APIC_ADDRESS_OVERRIDE   5
+#define ACPI_APIC_IO_SAPIC           6
+#define ACPI_APIC_LOCAL_SAPIC        7
+#define ACPI_APIC_XRUPT_SOURCE       8
+#define ACPI_APIC_RESERVED           9           /* 9 and greater are reserved */
+
+/*
+ * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
+ */
+#define ACPI_SUB_HEADER_DEF   /* Common ACPI sub-structure header */\
+    uint8_t  type;                               \
+    uint8_t  length;
+
+/* Sub-structures for MADT */
+
+struct AcpiMadtProcessorApic
+{
+    ACPI_SUB_HEADER_DEF
+    uint8_t  processor_id;           /* ACPI processor id */
+    uint8_t  local_apic_id;          /* Processor's local APIC id */
+    uint32_t flags;
+} QEMU_PACKED;
+typedef struct AcpiMadtProcessorApic AcpiMadtProcessorApic;
+
+struct AcpiMadtIoApic
+{
+    ACPI_SUB_HEADER_DEF
+    uint8_t  io_apic_id;             /* I/O APIC ID */
+    uint8_t  reserved;               /* Reserved - must be zero */
+    uint32_t address;                /* APIC physical address */
+    uint32_t interrupt;              /* Global system interrupt where INTI
+                                 * lines start */
+} QEMU_PACKED;
+typedef struct AcpiMadtIoApic AcpiMadtIoApic;
+
+struct AcpiMadtIntsrcovr {
+    ACPI_SUB_HEADER_DEF
+    uint8_t  bus;
+    uint8_t  source;
+    uint32_t gsi;
+    uint16_t flags;
+} QEMU_PACKED;
+typedef struct AcpiMadtIntsrcovr AcpiMadtIntsrcovr;
+
+struct AcpiMadtLocalNmi {
+    ACPI_SUB_HEADER_DEF
+    uint8_t  processor_id;           /* ACPI processor id */
+    uint16_t flags;                  /* MPS INTI flags */
+    uint8_t  lint;                   /* Local APIC LINT# */
+} QEMU_PACKED;
+typedef struct AcpiMadtLocalNmi AcpiMadtLocalNmi;
+
+/*
+ * HPET Description Table
+ */
+#define ACPI_HPET_SIGNATURE 0x54455048 // HPET
+struct Acpi20Hpet {
+    ACPI_TABLE_HEADER_DEF                    /* ACPI common table header */
+    uint32_t           timer_block_id;
+    Acpi20GenericAddress addr;
+    uint8_t            hpet_number;
+    uint16_t           min_tick;
+    uint8_t            page_protect;
+} QEMU_PACKED;
+typedef struct Acpi20Hpet Acpi20Hpet;
+
+/*
+ * SRAT (NUMA topology description) table
+ */
+
+#define ACPI_SRAT_SIGNATURE 0x54415253 // SRAT
+struct AcpiSystemResourceAffinityTable
+{
+    ACPI_TABLE_HEADER_DEF
+    uint32_t    reserved1;
+    uint32_t    reserved2[2];
+} QEMU_PACKED;
+typedef struct AcpiSystemResourceAffinityTable AcpiSystemResourceAffinityTable;
+
+#define ACPI_SRAT_PROCESSOR          0
+#define ACPI_SRAT_MEMORY             1
+
+struct AcpiSratProcessorAffinity
+{
+    ACPI_SUB_HEADER_DEF
+    uint8_t     proximity_lo;
+    uint8_t     local_apic_id;
+    uint32_t    flags;
+    uint8_t     local_sapic_eid;
+    uint8_t     proximity_hi[3];
+    uint32_t    reserved;
+} QEMU_PACKED;
+typedef struct AcpiSratProcessorAffinity AcpiSratProcessorAffinity;
+
+struct AcpiSratMemoryAffinity
+{
+    ACPI_SUB_HEADER_DEF
+    uint8_t     proximity[4];
+    uint16_t    reserved1;
+    uint64_t    base_addr;
+    uint64_t    range_length;
+    uint32_t    reserved2;
+    uint32_t    flags;
+    uint32_t    reserved3[2];
+} QEMU_PACKED;
+typedef struct AcpiSratMemoryAffinity AcpiSratMemoryAffinity;
+
+/* PCI fw r3.0 MCFG table. */
+/* Subtable */
+struct AcpiMcfgAllocation {
+    uint64_t address;                /* Base address, processor-relative */
+    uint16_t pci_segment;            /* PCI segment group number */
+    uint8_t start_bus_number;       /* Starting PCI Bus number */
+    uint8_t end_bus_number;         /* Final PCI Bus number */
+    uint32_t reserved;
+} QEMU_PACKED;
+typedef struct AcpiMcfgAllocation AcpiMcfgAllocation;
+
+#define ACPI_MCFG_SIGNATURE 0x4746434d       // MCFG
+
+/* Reserved signature: ignored by OSPM */
+#define ACPI_RSRV_SIGNATURE 0x554d4551       // QEMU
+
+struct AcpiTableMcfg {
+    ACPI_TABLE_HEADER_DEF;
+    uint8_t reserved[8];
+    AcpiMcfgAllocation allocation[0];
+} QEMU_PACKED;
+typedef struct AcpiTableMcfg AcpiTableMcfg;
+
+#endif
diff --git a/hw/i386/acpi-dsdt-cpu-hotplug.dsl b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
new file mode 100644 (file)
index 0000000..c96ac42
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/****************************************************************
+ * CPU hotplug
+ ****************************************************************/
+
+Scope(\_SB) {
+    /* Objects filled in by run-time generated SSDT */
+    External(NTFY, MethodObj)
+    External(CPON, PkgObj)
+
+    /* Methods called by run-time generated SSDT Processor objects */
+    Method(CPMA, 1, NotSerialized) {
+        // _MAT method - create an madt apic buffer
+        // Arg0 = Processor ID = Local APIC ID
+        // Local0 = CPON flag for this cpu
+        Store(DerefOf(Index(CPON, Arg0)), Local0)
+        // Local1 = Buffer (in madt apic form) to return
+        Store(Buffer(8) {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0}, Local1)
+        // Update the processor id, lapic id, and enable/disable status
+        Store(Arg0, Index(Local1, 2))
+        Store(Arg0, Index(Local1, 3))
+        Store(Local0, Index(Local1, 4))
+        Return (Local1)
+    }
+    Method(CPST, 1, NotSerialized) {
+        // _STA method - return ON status of cpu
+        // Arg0 = Processor ID = Local APIC ID
+        // Local0 = CPON flag for this cpu
+        Store(DerefOf(Index(CPON, Arg0)), Local0)
+        If (Local0) {
+            Return (0xF)
+        } Else {
+            Return (0x0)
+        }
+    }
+    Method(CPEJ, 2, NotSerialized) {
+        // _EJ0 method - eject callback
+        Sleep(200)
+    }
+
+    /* CPU hotplug notify method */
+    OperationRegion(PRST, SystemIO, 0xaf00, 32)
+    Field(PRST, ByteAcc, NoLock, Preserve) {
+        PRS, 256
+    }
+    Method(PRSC, 0) {
+        // Local5 = active cpu bitmap
+        Store(PRS, Local5)
+        // Local2 = last read byte from bitmap
+        Store(Zero, Local2)
+        // Local0 = Processor ID / APIC ID iterator
+        Store(Zero, Local0)
+        While (LLess(Local0, SizeOf(CPON))) {
+            // Local1 = CPON flag for this cpu
+            Store(DerefOf(Index(CPON, Local0)), Local1)
+            If (And(Local0, 0x07)) {
+                // Shift down previously read bitmap byte
+                ShiftRight(Local2, 1, Local2)
+            } Else {
+                // Read next byte from cpu bitmap
+                Store(DerefOf(Index(Local5, ShiftRight(Local0, 3))), Local2)
+            }
+            // Local3 = active state for this cpu
+            Store(And(Local2, 1), Local3)
+
+            If (LNotEqual(Local1, Local3)) {
+                // State change - update CPON with new state
+                Store(Local3, Index(CPON, Local0))
+                // Do CPU notify
+                If (LEqual(Local3, 1)) {
+                    NTFY(Local0, 1)
+                } Else {
+                    NTFY(Local0, 3)
+                }
+            }
+            Increment(Local0)
+        }
+    }
+}
diff --git a/hw/i386/acpi-dsdt-dbug.dsl b/hw/i386/acpi-dsdt-dbug.dsl
new file mode 100644 (file)
index 0000000..86230f7
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/****************************************************************
+ * Debugging
+ ****************************************************************/
+
+Scope(\) {
+    /* Debug Output */
+    OperationRegion(DBG, SystemIO, 0x0402, 0x01)
+    Field(DBG, ByteAcc, NoLock, Preserve) {
+        DBGB,   8,
+    }
+
+    /* Debug method - use this method to send output to the QEMU
+     * BIOS debug port.  This method handles strings, integers,
+     * and buffers.  For example: DBUG("abc") DBUG(0x123) */
+    Method(DBUG, 1) {
+        ToHexString(Arg0, Local0)
+        ToBuffer(Local0, Local0)
+        Subtract(SizeOf(Local0), 1, Local1)
+        Store(Zero, Local2)
+        While (LLess(Local2, Local1)) {
+            Store(DerefOf(Index(Local0, Local2)), DBGB)
+            Increment(Local2)
+        }
+        Store(0x0A, DBGB)
+    }
+}
diff --git a/hw/i386/acpi-dsdt-hpet.dsl b/hw/i386/acpi-dsdt-hpet.dsl
new file mode 100644 (file)
index 0000000..dfde174
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/****************************************************************
+ * HPET
+ ****************************************************************/
+
+Scope(\_SB) {
+    Device(HPET) {
+        Name(_HID, EISAID("PNP0103"))
+        Name(_UID, 0)
+        OperationRegion(HPTM, SystemMemory, 0xFED00000, 0x400)
+        Field(HPTM, DWordAcc, Lock, Preserve) {
+            VEND, 32,
+            PRD, 32,
+        }
+        Method(_STA, 0, NotSerialized) {
+            Store(VEND, Local0)
+            Store(PRD, Local1)
+            ShiftRight(Local0, 16, Local0)
+            If (LOr(LEqual(Local0, 0), LEqual(Local0, 0xffff))) {
+                Return (0x0)
+            }
+            If (LOr(LEqual(Local1, 0), LGreater(Local1, 100000000))) {
+                Return (0x0)
+            }
+            Return (0x0F)
+        }
+        Name(_CRS, ResourceTemplate() {
+#if 0       /* This makes WinXP BSOD for not yet figured reasons. */
+            IRQNoFlags() {2, 8}
+#endif
+            Memory32Fixed(ReadOnly,
+                0xFED00000,         // Address Base
+                0x00000400,         // Address Length
+                )
+        })
+    }
+}
diff --git a/hw/i386/acpi-dsdt-isa.dsl b/hw/i386/acpi-dsdt-isa.dsl
new file mode 100644 (file)
index 0000000..89caa16
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Common legacy ISA style devices. */
+Scope(\_SB.PCI0.ISA) {
+
+    Device(RTC) {
+        Name(_HID, EisaId("PNP0B00"))
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x0070, 0x0070, 0x10, 0x02)
+            IRQNoFlags() { 8 }
+            IO(Decode16, 0x0072, 0x0072, 0x02, 0x06)
+        })
+    }
+
+    Device(KBD) {
+        Name(_HID, EisaId("PNP0303"))
+        Method(_STA, 0, NotSerialized) {
+            Return (0x0f)
+        }
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x0060, 0x0060, 0x01, 0x01)
+            IO(Decode16, 0x0064, 0x0064, 0x01, 0x01)
+            IRQNoFlags() { 1 }
+        })
+    }
+
+    Device(MOU) {
+        Name(_HID, EisaId("PNP0F13"))
+        Method(_STA, 0, NotSerialized) {
+            Return (0x0f)
+        }
+        Name(_CRS, ResourceTemplate() {
+            IRQNoFlags() { 12 }
+        })
+    }
+
+    Device(FDC0) {
+        Name(_HID, EisaId("PNP0700"))
+        Method(_STA, 0, NotSerialized) {
+            Store(FDEN, Local0)
+            If (LEqual(Local0, 0)) {
+                Return (0x00)
+            } Else {
+                Return (0x0F)
+            }
+        }
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x03F2, 0x03F2, 0x00, 0x04)
+            IO(Decode16, 0x03F7, 0x03F7, 0x00, 0x01)
+            IRQNoFlags() { 6 }
+            DMA(Compatibility, NotBusMaster, Transfer8) { 2 }
+        })
+    }
+
+    Device(LPT) {
+        Name(_HID, EisaId("PNP0400"))
+        Method(_STA, 0, NotSerialized) {
+            Store(LPEN, Local0)
+            If (LEqual(Local0, 0)) {
+                Return (0x00)
+            } Else {
+                Return (0x0F)
+            }
+        }
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x0378, 0x0378, 0x08, 0x08)
+            IRQNoFlags() { 7 }
+        })
+    }
+
+    Device(COM1) {
+        Name(_HID, EisaId("PNP0501"))
+        Name(_UID, 0x01)
+        Method(_STA, 0, NotSerialized) {
+            Store(CAEN, Local0)
+            If (LEqual(Local0, 0)) {
+                Return (0x00)
+            } Else {
+                Return (0x0F)
+            }
+        }
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x03F8, 0x03F8, 0x00, 0x08)
+            IRQNoFlags() { 4 }
+        })
+    }
+
+    Device(COM2) {
+        Name(_HID, EisaId("PNP0501"))
+        Name(_UID, 0x02)
+        Method(_STA, 0, NotSerialized) {
+            Store(CBEN, Local0)
+            If (LEqual(Local0, 0)) {
+                Return (0x00)
+            } Else {
+                Return (0x0F)
+            }
+        }
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x02F8, 0x02F8, 0x00, 0x08)
+            IRQNoFlags() { 3 }
+        })
+    }
+}
diff --git a/hw/i386/acpi-dsdt-pci-crs.dsl b/hw/i386/acpi-dsdt-pci-crs.dsl
new file mode 100644 (file)
index 0000000..b375a19
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* PCI CRS (current resources) definition. */
+Scope(\_SB.PCI0) {
+
+    Name(CRES, ResourceTemplate() {
+        WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode,
+            0x0000,             // Address Space Granularity
+            0x0000,             // Address Range Minimum
+            0x00FF,             // Address Range Maximum
+            0x0000,             // Address Translation Offset
+            0x0100,             // Address Length
+            ,, )
+        IO(Decode16,
+            0x0CF8,             // Address Range Minimum
+            0x0CF8,             // Address Range Maximum
+            0x01,               // Address Alignment
+            0x08,               // Address Length
+            )
+        WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+            0x0000,             // Address Space Granularity
+            0x0000,             // Address Range Minimum
+            0x0CF7,             // Address Range Maximum
+            0x0000,             // Address Translation Offset
+            0x0CF8,             // Address Length
+            ,, , TypeStatic)
+        WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+            0x0000,             // Address Space Granularity
+            0x0D00,             // Address Range Minimum
+            0xFFFF,             // Address Range Maximum
+            0x0000,             // Address Translation Offset
+            0xF300,             // Address Length
+            ,, , TypeStatic)
+        DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+            0x00000000,         // Address Space Granularity
+            0x000A0000,         // Address Range Minimum
+            0x000BFFFF,         // Address Range Maximum
+            0x00000000,         // Address Translation Offset
+            0x00020000,         // Address Length
+            ,, , AddressRangeMemory, TypeStatic)
+        DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
+            0x00000000,         // Address Space Granularity
+            0xE0000000,         // Address Range Minimum
+            0xFEBFFFFF,         // Address Range Maximum
+            0x00000000,         // Address Translation Offset
+            0x1EC00000,         // Address Length
+            ,, PW32, AddressRangeMemory, TypeStatic)
+    })
+
+    Name(CR64, ResourceTemplate() {
+        QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+            0x00000000,          // Address Space Granularity
+            0x8000000000,        // Address Range Minimum
+            0xFFFFFFFFFF,        // Address Range Maximum
+            0x00000000,          // Address Translation Offset
+            0x8000000000,        // Address Length
+            ,, PW64, AddressRangeMemory, TypeStatic)
+    })
+
+    Method(_CRS, 0) {
+        /* Fields provided by dynamically created ssdt */
+        External(P0S, IntObj)
+        External(P0E, IntObj)
+        External(P1V, IntObj)
+        External(P1S, BuffObj)
+        External(P1E, BuffObj)
+        External(P1L, BuffObj)
+
+        /* fixup 32bit pci io window */
+        CreateDWordField(CRES, \_SB.PCI0.PW32._MIN, PS32)
+        CreateDWordField(CRES, \_SB.PCI0.PW32._MAX, PE32)
+        CreateDWordField(CRES, \_SB.PCI0.PW32._LEN, PL32)
+        Store(P0S, PS32)
+        Store(P0E, PE32)
+        Store(Add(Subtract(P0E, P0S), 1), PL32)
+
+        If (LEqual(P1V, Zero)) {
+            Return (CRES)
+        }
+
+        /* fixup 64bit pci io window */
+        CreateQWordField(CR64, \_SB.PCI0.PW64._MIN, PS64)
+        CreateQWordField(CR64, \_SB.PCI0.PW64._MAX, PE64)
+        CreateQWordField(CR64, \_SB.PCI0.PW64._LEN, PL64)
+        Store(P1S, PS64)
+        Store(P1E, PE64)
+        Store(P1L, PL64)
+        /* add window and return result */
+        ConcatenateResTemplate(CRES, CR64, Local0)
+        Return (Local0)
+    }
+}
diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl
new file mode 100644 (file)
index 0000000..90efce0
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+ * Bochs/QEMU ACPI DSDT ASL definition
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+ACPI_EXTRACT_ALL_CODE AcpiDsdtAmlCode
+
+DefinitionBlock (
+    "acpi-dsdt.aml",    // Output Filename
+    "DSDT",             // Signature
+    0x01,               // DSDT Compliance Revision
+    "BXPC",             // OEMID
+    "BXDSDT",           // TABLE ID
+    0x1                 // OEM Revision
+    )
+{
+
+#include "acpi-dsdt-dbug.dsl"
+
+
+/****************************************************************
+ * PCI Bus definition
+ ****************************************************************/
+
+    Scope(\_SB) {
+        Device(PCI0) {
+            Name(_HID, EisaId("PNP0A03"))
+            Name(_ADR, 0x00)
+            Name(_UID, 1)
+        }
+    }
+
+#include "acpi-dsdt-pci-crs.dsl"
+#include "acpi-dsdt-hpet.dsl"
+
+
+/****************************************************************
+ * VGA
+ ****************************************************************/
+
+    Scope(\_SB.PCI0) {
+        Device(VGA) {
+            Name(_ADR, 0x00020000)
+            OperationRegion(PCIC, PCI_Config, Zero, 0x4)
+            Field(PCIC, DWordAcc, NoLock, Preserve) {
+                VEND, 32
+            }
+            Method(_S1D, 0, NotSerialized) {
+                Return (0x00)
+            }
+            Method(_S2D, 0, NotSerialized) {
+                Return (0x00)
+            }
+            Method(_S3D, 0, NotSerialized) {
+                If (LEqual(VEND, 0x1001b36)) {
+                    Return (0x03)           // QXL
+                } Else {
+                    Return (0x00)
+                }
+            }
+        }
+    }
+
+
+/****************************************************************
+ * PIIX4 PM
+ ****************************************************************/
+
+    Scope(\_SB.PCI0) {
+        Device(PX13) {
+            Name(_ADR, 0x00010003)
+            OperationRegion(P13C, PCI_Config, 0x00, 0xff)
+        }
+    }
+
+
+/****************************************************************
+ * PIIX3 ISA bridge
+ ****************************************************************/
+
+    Scope(\_SB.PCI0) {
+        Device(ISA) {
+            Name(_ADR, 0x00010000)
+
+            /* PIIX PCI to ISA irq remapping */
+            OperationRegion(P40C, PCI_Config, 0x60, 0x04)
+
+            /* enable bits */
+            Field(\_SB.PCI0.PX13.P13C, AnyAcc, NoLock, Preserve) {
+                Offset(0x5f),
+                , 7,
+                LPEN, 1,         // LPT
+                Offset(0x67),
+                , 3,
+                CAEN, 1,         // COM1
+                , 3,
+                CBEN, 1,         // COM2
+            }
+            Name(FDEN, 1)
+        }
+    }
+
+#include "acpi-dsdt-isa.dsl"
+
+
+/****************************************************************
+ * PCI hotplug
+ ****************************************************************/
+
+    Scope(\_SB.PCI0) {
+        OperationRegion(PCST, SystemIO, 0xae00, 0x08)
+        Field(PCST, DWordAcc, NoLock, WriteAsZeros) {
+            PCIU, 32,
+            PCID, 32,
+        }
+
+        OperationRegion(SEJ, SystemIO, 0xae08, 0x04)
+        Field(SEJ, DWordAcc, NoLock, WriteAsZeros) {
+            B0EJ, 32,
+        }
+
+        /* Methods called by bulk generated PCI devices below */
+
+        /* Methods called by hotplug devices */
+        Method(PCEJ, 1, NotSerialized) {
+            // _EJ0 method - eject callback
+            Store(ShiftLeft(1, Arg0), B0EJ)
+            Return (0x0)
+        }
+
+        /* Hotplug notification method supplied by SSDT */
+        External(\_SB.PCI0.PCNT, MethodObj)
+
+        /* PCI hotplug notify method */
+        Method(PCNF, 0) {
+            // Local0 = iterator
+            Store(Zero, Local0)
+            While (LLess(Local0, 31)) {
+                Increment(Local0)
+                If (And(PCIU, ShiftLeft(1, Local0))) {
+                    PCNT(Local0, 1)
+                }
+                If (And(PCID, ShiftLeft(1, Local0))) {
+                    PCNT(Local0, 3)
+                }
+            }
+        }
+    }
+
+
+/****************************************************************
+ * PCI IRQs
+ ****************************************************************/
+
+    Scope(\_SB) {
+        Scope(PCI0) {
+            Name(_PRT, Package() {
+                /* PCI IRQ routing table, example from ACPI 2.0a specification,
+                   section 6.2.8.1 */
+                /* Note: we provide the same info as the PCI routing
+                   table of the Bochs BIOS */
+
+#define prt_slot(nr, lnk0, lnk1, lnk2, lnk3) \
+    Package() { nr##ffff, 0, lnk0, 0 }, \
+    Package() { nr##ffff, 1, lnk1, 0 }, \
+    Package() { nr##ffff, 2, lnk2, 0 }, \
+    Package() { nr##ffff, 3, lnk3, 0 }
+
+#define prt_slot0(nr) prt_slot(nr, LNKD, LNKA, LNKB, LNKC)
+#define prt_slot1(nr) prt_slot(nr, LNKA, LNKB, LNKC, LNKD)
+#define prt_slot2(nr) prt_slot(nr, LNKB, LNKC, LNKD, LNKA)
+#define prt_slot3(nr) prt_slot(nr, LNKC, LNKD, LNKA, LNKB)
+
+                prt_slot0(0x0000),
+                /* Device 1 is power mgmt device, and can only use irq 9 */
+                prt_slot(0x0001, LNKS, LNKB, LNKC, LNKD),
+                prt_slot2(0x0002),
+                prt_slot3(0x0003),
+                prt_slot0(0x0004),
+                prt_slot1(0x0005),
+                prt_slot2(0x0006),
+                prt_slot3(0x0007),
+                prt_slot0(0x0008),
+                prt_slot1(0x0009),
+                prt_slot2(0x000a),
+                prt_slot3(0x000b),
+                prt_slot0(0x000c),
+                prt_slot1(0x000d),
+                prt_slot2(0x000e),
+                prt_slot3(0x000f),
+                prt_slot0(0x0010),
+                prt_slot1(0x0011),
+                prt_slot2(0x0012),
+                prt_slot3(0x0013),
+                prt_slot0(0x0014),
+                prt_slot1(0x0015),
+                prt_slot2(0x0016),
+                prt_slot3(0x0017),
+                prt_slot0(0x0018),
+                prt_slot1(0x0019),
+                prt_slot2(0x001a),
+                prt_slot3(0x001b),
+                prt_slot0(0x001c),
+                prt_slot1(0x001d),
+                prt_slot2(0x001e),
+                prt_slot3(0x001f),
+            })
+        }
+
+        Field(PCI0.ISA.P40C, ByteAcc, NoLock, Preserve) {
+            PRQ0,   8,
+            PRQ1,   8,
+            PRQ2,   8,
+            PRQ3,   8
+        }
+
+        Method(IQST, 1, NotSerialized) {
+            // _STA method - get status
+            If (And(0x80, Arg0)) {
+                Return (0x09)
+            }
+            Return (0x0B)
+        }
+        Method(IQCR, 1, NotSerialized) {
+            // _CRS method - get current settings
+            Name(PRR0, ResourceTemplate() {
+                Interrupt(, Level, ActiveHigh, Shared) { 0 }
+            })
+            CreateDWordField(PRR0, 0x05, PRRI)
+            If (LLess(Arg0, 0x80)) {
+                Store(Arg0, PRRI)
+            }
+            Return (PRR0)
+        }
+
+#define define_link(link, uid, reg)                             \
+        Device(link) {                                          \
+            Name(_HID, EISAID("PNP0C0F"))                       \
+            Name(_UID, uid)                                     \
+            Name(_PRS, ResourceTemplate() {                     \
+                Interrupt(, Level, ActiveHigh, Shared) {        \
+                    5, 10, 11                                   \
+                }                                               \
+            })                                                  \
+            Method(_STA, 0, NotSerialized) {                    \
+                Return (IQST(reg))                              \
+            }                                                   \
+            Method(_DIS, 0, NotSerialized) {                    \
+                Or(reg, 0x80, reg)                              \
+            }                                                   \
+            Method(_CRS, 0, NotSerialized) {                    \
+                Return (IQCR(reg))                              \
+            }                                                   \
+            Method(_SRS, 1, NotSerialized) {                    \
+                CreateDWordField(Arg0, 0x05, PRRI)              \
+                Store(PRRI, reg)                                \
+            }                                                   \
+        }
+
+        define_link(LNKA, 0, PRQ0)
+        define_link(LNKB, 1, PRQ1)
+        define_link(LNKC, 2, PRQ2)
+        define_link(LNKD, 3, PRQ3)
+
+        Device(LNKS) {
+            Name(_HID, EISAID("PNP0C0F"))
+            Name(_UID, 4)
+            Name(_PRS, ResourceTemplate() {
+                Interrupt(, Level, ActiveHigh, Shared) { 9 }
+            })
+
+            // The SCI cannot be disabled and is always attached to GSI 9,
+            // so these are no-ops.  We only need this link to override the
+            // polarity to active high and match the content of the MADT.
+            Method(_STA, 0, NotSerialized) { Return (0x0b) }
+            Method(_DIS, 0, NotSerialized) { }
+            Method(_CRS, 0, NotSerialized) { Return (_PRS) }
+            Method(_SRS, 1, NotSerialized) { }
+        }
+    }
+
+#include "acpi-dsdt-cpu-hotplug.dsl"
+
+
+/****************************************************************
+ * General purpose events
+ ****************************************************************/
+
+    Scope(\_GPE) {
+        Name(_HID, "ACPI0006")
+
+        Method(_L00) {
+        }
+        Method(_E01) {
+            // PCI hotplug event
+            \_SB.PCI0.PCNF()
+        }
+        Method(_E02) {
+            // CPU hotplug event
+            \_SB.PRSC()
+        }
+        Method(_L03) {
+        }
+        Method(_L04) {
+        }
+        Method(_L05) {
+        }
+        Method(_L06) {
+        }
+        Method(_L07) {
+        }
+        Method(_L08) {
+        }
+        Method(_L09) {
+        }
+        Method(_L0A) {
+        }
+        Method(_L0B) {
+        }
+        Method(_L0C) {
+        }
+        Method(_L0D) {
+        }
+        Method(_L0E) {
+        }
+        Method(_L0F) {
+        }
+    }
+}
diff --git a/hw/i386/acpi-dsdt.hex.generated b/hw/i386/acpi-dsdt.hex.generated
new file mode 100644 (file)
index 0000000..2c01107
--- /dev/null
@@ -0,0 +1,4409 @@
+static unsigned char AcpiDsdtAmlCode[] = {
+0x44,
+0x53,
+0x44,
+0x54,
+0x37,
+0x11,
+0x0,
+0x0,
+0x1,
+0xe0,
+0x42,
+0x58,
+0x50,
+0x43,
+0x0,
+0x0,
+0x42,
+0x58,
+0x44,
+0x53,
+0x44,
+0x54,
+0x0,
+0x0,
+0x1,
+0x0,
+0x0,
+0x0,
+0x49,
+0x4e,
+0x54,
+0x4c,
+0x23,
+0x8,
+0x13,
+0x20,
+0x10,
+0x49,
+0x4,
+0x5c,
+0x0,
+0x5b,
+0x80,
+0x44,
+0x42,
+0x47,
+0x5f,
+0x1,
+0xb,
+0x2,
+0x4,
+0x1,
+0x5b,
+0x81,
+0xb,
+0x44,
+0x42,
+0x47,
+0x5f,
+0x1,
+0x44,
+0x42,
+0x47,
+0x42,
+0x8,
+0x14,
+0x2c,
+0x44,
+0x42,
+0x55,
+0x47,
+0x1,
+0x98,
+0x68,
+0x60,
+0x96,
+0x60,
+0x60,
+0x74,
+0x87,
+0x60,
+0x1,
+0x61,
+0x70,
+0x0,
+0x62,
+0xa2,
+0x10,
+0x95,
+0x62,
+0x61,
+0x70,
+0x83,
+0x88,
+0x60,
+0x62,
+0x0,
+0x44,
+0x42,
+0x47,
+0x42,
+0x75,
+0x62,
+0x70,
+0xa,
+0xa,
+0x44,
+0x42,
+0x47,
+0x42,
+0x10,
+0x22,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x5b,
+0x82,
+0x1b,
+0x50,
+0x43,
+0x49,
+0x30,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xa,
+0x3,
+0x8,
+0x5f,
+0x41,
+0x44,
+0x52,
+0x0,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x1,
+0x10,
+0x4e,
+0x15,
+0x2e,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x50,
+0x43,
+0x49,
+0x30,
+0x8,
+0x43,
+0x52,
+0x45,
+0x53,
+0x11,
+0x42,
+0x7,
+0xa,
+0x6e,
+0x88,
+0xd,
+0x0,
+0x2,
+0xc,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x1,
+0x47,
+0x1,
+0xf8,
+0xc,
+0xf8,
+0xc,
+0x1,
+0x8,
+0x88,
+0xd,
+0x0,
+0x1,
+0xc,
+0x3,
+0x0,
+0x0,
+0x0,
+0x0,
+0xf7,
+0xc,
+0x0,
+0x0,
+0xf8,
+0xc,
+0x88,
+0xd,
+0x0,
+0x1,
+0xc,
+0x3,
+0x0,
+0x0,
+0x0,
+0xd,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0xf3,
+0x87,
+0x17,
+0x0,
+0x0,
+0xc,
+0x3,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0xa,
+0x0,
+0xff,
+0xff,
+0xb,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x2,
+0x0,
+0x87,
+0x17,
+0x0,
+0x0,
+0xc,
+0x1,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0xe0,
+0xff,
+0xff,
+0xbf,
+0xfe,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0xc0,
+0x1e,
+0x79,
+0x0,
+0x8,
+0x43,
+0x52,
+0x36,
+0x34,
+0x11,
+0x33,
+0xa,
+0x30,
+0x8a,
+0x2b,
+0x0,
+0x0,
+0xc,
+0x3,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x80,
+0x0,
+0x0,
+0x0,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x80,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0x41,
+0xa,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x0,
+0x8a,
+0x43,
+0x52,
+0x45,
+0x53,
+0xa,
+0x5c,
+0x50,
+0x53,
+0x33,
+0x32,
+0x8a,
+0x43,
+0x52,
+0x45,
+0x53,
+0xa,
+0x60,
+0x50,
+0x45,
+0x33,
+0x32,
+0x8a,
+0x43,
+0x52,
+0x45,
+0x53,
+0xa,
+0x68,
+0x50,
+0x4c,
+0x33,
+0x32,
+0x70,
+0x50,
+0x30,
+0x53,
+0x5f,
+0x50,
+0x53,
+0x33,
+0x32,
+0x70,
+0x50,
+0x30,
+0x45,
+0x5f,
+0x50,
+0x45,
+0x33,
+0x32,
+0x70,
+0x72,
+0x74,
+0x50,
+0x30,
+0x45,
+0x5f,
+0x50,
+0x30,
+0x53,
+0x5f,
+0x0,
+0x1,
+0x0,
+0x50,
+0x4c,
+0x33,
+0x32,
+0xa0,
+0xc,
+0x93,
+0x50,
+0x31,
+0x56,
+0x5f,
+0x0,
+0xa4,
+0x43,
+0x52,
+0x45,
+0x53,
+0x8f,
+0x43,
+0x52,
+0x36,
+0x34,
+0xa,
+0xe,
+0x50,
+0x53,
+0x36,
+0x34,
+0x8f,
+0x43,
+0x52,
+0x36,
+0x34,
+0xa,
+0x16,
+0x50,
+0x45,
+0x36,
+0x34,
+0x8f,
+0x43,
+0x52,
+0x36,
+0x34,
+0xa,
+0x26,
+0x50,
+0x4c,
+0x36,
+0x34,
+0x70,
+0x50,
+0x31,
+0x53,
+0x5f,
+0x50,
+0x53,
+0x36,
+0x34,
+0x70,
+0x50,
+0x31,
+0x45,
+0x5f,
+0x50,
+0x45,
+0x36,
+0x34,
+0x70,
+0x50,
+0x31,
+0x4c,
+0x5f,
+0x50,
+0x4c,
+0x36,
+0x34,
+0x84,
+0x43,
+0x52,
+0x45,
+0x53,
+0x43,
+0x52,
+0x36,
+0x34,
+0x60,
+0xa4,
+0x60,
+0x10,
+0x4d,
+0x8,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x5b,
+0x82,
+0x45,
+0x8,
+0x48,
+0x50,
+0x45,
+0x54,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0x1,
+0x3,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x0,
+0x5b,
+0x80,
+0x48,
+0x50,
+0x54,
+0x4d,
+0x0,
+0xc,
+0x0,
+0x0,
+0xd0,
+0xfe,
+0xb,
+0x0,
+0x4,
+0x5b,
+0x81,
+0x10,
+0x48,
+0x50,
+0x54,
+0x4d,
+0x13,
+0x56,
+0x45,
+0x4e,
+0x44,
+0x20,
+0x50,
+0x52,
+0x44,
+0x5f,
+0x20,
+0x14,
+0x36,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0x70,
+0x56,
+0x45,
+0x4e,
+0x44,
+0x60,
+0x70,
+0x50,
+0x52,
+0x44,
+0x5f,
+0x61,
+0x7a,
+0x60,
+0xa,
+0x10,
+0x60,
+0xa0,
+0xc,
+0x91,
+0x93,
+0x60,
+0x0,
+0x93,
+0x60,
+0xb,
+0xff,
+0xff,
+0xa4,
+0x0,
+0xa0,
+0xe,
+0x91,
+0x93,
+0x61,
+0x0,
+0x94,
+0x61,
+0xc,
+0x0,
+0xe1,
+0xf5,
+0x5,
+0xa4,
+0x0,
+0xa4,
+0xa,
+0xf,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0x11,
+0xa,
+0xe,
+0x86,
+0x9,
+0x0,
+0x0,
+0x0,
+0x0,
+0xd0,
+0xfe,
+0x0,
+0x4,
+0x0,
+0x0,
+0x79,
+0x0,
+0x10,
+0x40,
+0x6,
+0x2e,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x50,
+0x43,
+0x49,
+0x30,
+0x5b,
+0x82,
+0x43,
+0x5,
+0x56,
+0x47,
+0x41,
+0x5f,
+0x8,
+0x5f,
+0x41,
+0x44,
+0x52,
+0xc,
+0x0,
+0x0,
+0x2,
+0x0,
+0x5b,
+0x80,
+0x50,
+0x43,
+0x49,
+0x43,
+0x2,
+0x0,
+0xa,
+0x4,
+0x5b,
+0x81,
+0xb,
+0x50,
+0x43,
+0x49,
+0x43,
+0x3,
+0x56,
+0x45,
+0x4e,
+0x44,
+0x20,
+0x14,
+0x8,
+0x5f,
+0x53,
+0x31,
+0x44,
+0x0,
+0xa4,
+0x0,
+0x14,
+0x8,
+0x5f,
+0x53,
+0x32,
+0x44,
+0x0,
+0xa4,
+0x0,
+0x14,
+0x19,
+0x5f,
+0x53,
+0x33,
+0x44,
+0x0,
+0xa0,
+0xe,
+0x93,
+0x56,
+0x45,
+0x4e,
+0x44,
+0xc,
+0x36,
+0x1b,
+0x0,
+0x1,
+0xa4,
+0xa,
+0x3,
+0xa1,
+0x3,
+0xa4,
+0x0,
+0x10,
+0x25,
+0x2e,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x50,
+0x43,
+0x49,
+0x30,
+0x5b,
+0x82,
+0x19,
+0x50,
+0x58,
+0x31,
+0x33,
+0x8,
+0x5f,
+0x41,
+0x44,
+0x52,
+0xc,
+0x3,
+0x0,
+0x1,
+0x0,
+0x5b,
+0x80,
+0x50,
+0x31,
+0x33,
+0x43,
+0x2,
+0x0,
+0xa,
+0xff,
+0x10,
+0x46,
+0x5,
+0x2e,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x50,
+0x43,
+0x49,
+0x30,
+0x5b,
+0x82,
+0x49,
+0x4,
+0x49,
+0x53,
+0x41,
+0x5f,
+0x8,
+0x5f,
+0x41,
+0x44,
+0x52,
+0xc,
+0x0,
+0x0,
+0x1,
+0x0,
+0x5b,
+0x80,
+0x50,
+0x34,
+0x30,
+0x43,
+0x2,
+0xa,
+0x60,
+0xa,
+0x4,
+0x5b,
+0x81,
+0x26,
+0x5e,
+0x2e,
+0x50,
+0x58,
+0x31,
+0x33,
+0x50,
+0x31,
+0x33,
+0x43,
+0x0,
+0x0,
+0x48,
+0x2f,
+0x0,
+0x7,
+0x4c,
+0x50,
+0x45,
+0x4e,
+0x1,
+0x0,
+0x38,
+0x0,
+0x3,
+0x43,
+0x41,
+0x45,
+0x4e,
+0x1,
+0x0,
+0x3,
+0x43,
+0x42,
+0x45,
+0x4e,
+0x1,
+0x8,
+0x46,
+0x44,
+0x45,
+0x4e,
+0x1,
+0x10,
+0x4c,
+0x1b,
+0x2f,
+0x3,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x50,
+0x43,
+0x49,
+0x30,
+0x49,
+0x53,
+0x41,
+0x5f,
+0x5b,
+0x82,
+0x2d,
+0x52,
+0x54,
+0x43,
+0x5f,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xb,
+0x0,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0x18,
+0xa,
+0x15,
+0x47,
+0x1,
+0x70,
+0x0,
+0x70,
+0x0,
+0x10,
+0x2,
+0x22,
+0x0,
+0x1,
+0x47,
+0x1,
+0x72,
+0x0,
+0x72,
+0x0,
+0x2,
+0x6,
+0x79,
+0x0,
+0x5b,
+0x82,
+0x37,
+0x4b,
+0x42,
+0x44,
+0x5f,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0x3,
+0x3,
+0x14,
+0x9,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0xa,
+0xf,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0x18,
+0xa,
+0x15,
+0x47,
+0x1,
+0x60,
+0x0,
+0x60,
+0x0,
+0x1,
+0x1,
+0x47,
+0x1,
+0x64,
+0x0,
+0x64,
+0x0,
+0x1,
+0x1,
+0x22,
+0x2,
+0x0,
+0x79,
+0x0,
+0x5b,
+0x82,
+0x27,
+0x4d,
+0x4f,
+0x55,
+0x5f,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xf,
+0x13,
+0x14,
+0x9,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0xa,
+0xf,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0x8,
+0xa,
+0x5,
+0x22,
+0x0,
+0x10,
+0x79,
+0x0,
+0x5b,
+0x82,
+0x4a,
+0x4,
+0x46,
+0x44,
+0x43,
+0x30,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0x7,
+0x0,
+0x14,
+0x18,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0x70,
+0x46,
+0x44,
+0x45,
+0x4e,
+0x60,
+0xa0,
+0x6,
+0x93,
+0x60,
+0x0,
+0xa4,
+0x0,
+0xa1,
+0x4,
+0xa4,
+0xa,
+0xf,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0x1b,
+0xa,
+0x18,
+0x47,
+0x1,
+0xf2,
+0x3,
+0xf2,
+0x3,
+0x0,
+0x4,
+0x47,
+0x1,
+0xf7,
+0x3,
+0xf7,
+0x3,
+0x0,
+0x1,
+0x22,
+0x40,
+0x0,
+0x2a,
+0x4,
+0x0,
+0x79,
+0x0,
+0x5b,
+0x82,
+0x3e,
+0x4c,
+0x50,
+0x54,
+0x5f,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0x4,
+0x0,
+0x14,
+0x18,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0x70,
+0x4c,
+0x50,
+0x45,
+0x4e,
+0x60,
+0xa0,
+0x6,
+0x93,
+0x60,
+0x0,
+0xa4,
+0x0,
+0xa1,
+0x4,
+0xa4,
+0xa,
+0xf,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0x10,
+0xa,
+0xd,
+0x47,
+0x1,
+0x78,
+0x3,
+0x78,
+0x3,
+0x8,
+0x8,
+0x22,
+0x80,
+0x0,
+0x79,
+0x0,
+0x5b,
+0x82,
+0x45,
+0x4,
+0x43,
+0x4f,
+0x4d,
+0x31,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0x5,
+0x1,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x1,
+0x14,
+0x18,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0x70,
+0x43,
+0x41,
+0x45,
+0x4e,
+0x60,
+0xa0,
+0x6,
+0x93,
+0x60,
+0x0,
+0xa4,
+0x0,
+0xa1,
+0x4,
+0xa4,
+0xa,
+0xf,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0x10,
+0xa,
+0xd,
+0x47,
+0x1,
+0xf8,
+0x3,
+0xf8,
+0x3,
+0x0,
+0x8,
+0x22,
+0x10,
+0x0,
+0x79,
+0x0,
+0x5b,
+0x82,
+0x46,
+0x4,
+0x43,
+0x4f,
+0x4d,
+0x32,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0x5,
+0x1,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0xa,
+0x2,
+0x14,
+0x18,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0x70,
+0x43,
+0x42,
+0x45,
+0x4e,
+0x60,
+0xa0,
+0x6,
+0x93,
+0x60,
+0x0,
+0xa4,
+0x0,
+0xa1,
+0x4,
+0xa4,
+0xa,
+0xf,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0x10,
+0xa,
+0xd,
+0x47,
+0x1,
+0xf8,
+0x2,
+0xf8,
+0x2,
+0x0,
+0x8,
+0x22,
+0x8,
+0x0,
+0x79,
+0x0,
+0x10,
+0x4b,
+0x8,
+0x2e,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x50,
+0x43,
+0x49,
+0x30,
+0x5b,
+0x80,
+0x50,
+0x43,
+0x53,
+0x54,
+0x1,
+0xb,
+0x0,
+0xae,
+0xa,
+0x8,
+0x5b,
+0x81,
+0x10,
+0x50,
+0x43,
+0x53,
+0x54,
+0x43,
+0x50,
+0x43,
+0x49,
+0x55,
+0x20,
+0x50,
+0x43,
+0x49,
+0x44,
+0x20,
+0x5b,
+0x80,
+0x53,
+0x45,
+0x4a,
+0x5f,
+0x1,
+0xb,
+0x8,
+0xae,
+0xa,
+0x4,
+0x5b,
+0x81,
+0xb,
+0x53,
+0x45,
+0x4a,
+0x5f,
+0x43,
+0x42,
+0x30,
+0x45,
+0x4a,
+0x20,
+0x14,
+0x11,
+0x50,
+0x43,
+0x45,
+0x4a,
+0x1,
+0x70,
+0x79,
+0x1,
+0x68,
+0x0,
+0x42,
+0x30,
+0x45,
+0x4a,
+0xa4,
+0x0,
+0x14,
+0x36,
+0x50,
+0x43,
+0x4e,
+0x46,
+0x0,
+0x70,
+0x0,
+0x60,
+0xa2,
+0x2c,
+0x95,
+0x60,
+0xa,
+0x1f,
+0x75,
+0x60,
+0xa0,
+0x11,
+0x7b,
+0x50,
+0x43,
+0x49,
+0x55,
+0x79,
+0x1,
+0x60,
+0x0,
+0x0,
+0x50,
+0x43,
+0x4e,
+0x54,
+0x60,
+0x1,
+0xa0,
+0x12,
+0x7b,
+0x50,
+0x43,
+0x49,
+0x44,
+0x79,
+0x1,
+0x60,
+0x0,
+0x0,
+0x50,
+0x43,
+0x4e,
+0x54,
+0x60,
+0xa,
+0x3,
+0x10,
+0x4a,
+0xa0,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x10,
+0x47,
+0x74,
+0x50,
+0x43,
+0x49,
+0x30,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x54,
+0x12,
+0x4b,
+0x73,
+0x80,
+0x12,
+0xb,
+0x4,
+0xb,
+0xff,
+0xff,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xb,
+0x4,
+0xb,
+0xff,
+0xff,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xc,
+0x4,
+0xb,
+0xff,
+0xff,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xc,
+0x4,
+0xb,
+0xff,
+0xff,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x53,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x2,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x2,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x2,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x2,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x3,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x3,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x3,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x3,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x4,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x4,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x4,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x4,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x5,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x5,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x5,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x5,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x6,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x6,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x6,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x6,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x7,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x7,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x7,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x7,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x8,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x8,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x8,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x8,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x9,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x9,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x9,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x9,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xa,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xa,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xa,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xa,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xb,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xb,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xb,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xb,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xc,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xc,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xc,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xc,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xd,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xd,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xd,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xd,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xe,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xe,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xe,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xe,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xf,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xf,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xf,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xf,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x10,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x10,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x10,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x10,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x11,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x11,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x11,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x11,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x12,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x12,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x12,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x12,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x13,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x13,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x13,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x13,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x14,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x14,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x14,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x14,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x15,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x15,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x15,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x15,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x16,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x16,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x16,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x16,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x17,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x17,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x17,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x17,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x18,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x18,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x18,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x18,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x19,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x19,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x19,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x19,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1a,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1a,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1a,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1a,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1b,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1b,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1b,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1b,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1c,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1c,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1c,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1c,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1d,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1d,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1d,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1d,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1e,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1e,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1e,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1e,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1f,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1f,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1f,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1f,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x5b,
+0x81,
+0x24,
+0x2f,
+0x3,
+0x50,
+0x43,
+0x49,
+0x30,
+0x49,
+0x53,
+0x41,
+0x5f,
+0x50,
+0x34,
+0x30,
+0x43,
+0x1,
+0x50,
+0x52,
+0x51,
+0x30,
+0x8,
+0x50,
+0x52,
+0x51,
+0x31,
+0x8,
+0x50,
+0x52,
+0x51,
+0x32,
+0x8,
+0x50,
+0x52,
+0x51,
+0x33,
+0x8,
+0x14,
+0x13,
+0x49,
+0x51,
+0x53,
+0x54,
+0x1,
+0xa0,
+0x9,
+0x7b,
+0xa,
+0x80,
+0x68,
+0x0,
+0xa4,
+0xa,
+0x9,
+0xa4,
+0xa,
+0xb,
+0x14,
+0x36,
+0x49,
+0x51,
+0x43,
+0x52,
+0x1,
+0x8,
+0x50,
+0x52,
+0x52,
+0x30,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x0,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x8a,
+0x50,
+0x52,
+0x52,
+0x30,
+0xa,
+0x5,
+0x50,
+0x52,
+0x52,
+0x49,
+0xa0,
+0xb,
+0x95,
+0x68,
+0xa,
+0x80,
+0x70,
+0x68,
+0x50,
+0x52,
+0x52,
+0x49,
+0xa4,
+0x50,
+0x52,
+0x52,
+0x30,
+0x5b,
+0x82,
+0x4c,
+0x7,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x0,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0x16,
+0xa,
+0x13,
+0x89,
+0xe,
+0x0,
+0x9,
+0x3,
+0x5,
+0x0,
+0x0,
+0x0,
+0xa,
+0x0,
+0x0,
+0x0,
+0xb,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0xf,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x53,
+0x54,
+0x50,
+0x52,
+0x51,
+0x30,
+0x14,
+0x11,
+0x5f,
+0x44,
+0x49,
+0x53,
+0x0,
+0x7d,
+0x50,
+0x52,
+0x51,
+0x30,
+0xa,
+0x80,
+0x50,
+0x52,
+0x51,
+0x30,
+0x14,
+0xf,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x43,
+0x52,
+0x50,
+0x52,
+0x51,
+0x30,
+0x14,
+0x17,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x8a,
+0x68,
+0xa,
+0x5,
+0x50,
+0x52,
+0x52,
+0x49,
+0x70,
+0x50,
+0x52,
+0x52,
+0x49,
+0x50,
+0x52,
+0x51,
+0x30,
+0x5b,
+0x82,
+0x4c,
+0x7,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x1,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0x16,
+0xa,
+0x13,
+0x89,
+0xe,
+0x0,
+0x9,
+0x3,
+0x5,
+0x0,
+0x0,
+0x0,
+0xa,
+0x0,
+0x0,
+0x0,
+0xb,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0xf,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x53,
+0x54,
+0x50,
+0x52,
+0x51,
+0x31,
+0x14,
+0x11,
+0x5f,
+0x44,
+0x49,
+0x53,
+0x0,
+0x7d,
+0x50,
+0x52,
+0x51,
+0x31,
+0xa,
+0x80,
+0x50,
+0x52,
+0x51,
+0x31,
+0x14,
+0xf,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x43,
+0x52,
+0x50,
+0x52,
+0x51,
+0x31,
+0x14,
+0x17,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x8a,
+0x68,
+0xa,
+0x5,
+0x50,
+0x52,
+0x52,
+0x49,
+0x70,
+0x50,
+0x52,
+0x52,
+0x49,
+0x50,
+0x52,
+0x51,
+0x31,
+0x5b,
+0x82,
+0x4d,
+0x7,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0xa,
+0x2,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0x16,
+0xa,
+0x13,
+0x89,
+0xe,
+0x0,
+0x9,
+0x3,
+0x5,
+0x0,
+0x0,
+0x0,
+0xa,
+0x0,
+0x0,
+0x0,
+0xb,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0xf,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x53,
+0x54,
+0x50,
+0x52,
+0x51,
+0x32,
+0x14,
+0x11,
+0x5f,
+0x44,
+0x49,
+0x53,
+0x0,
+0x7d,
+0x50,
+0x52,
+0x51,
+0x32,
+0xa,
+0x80,
+0x50,
+0x52,
+0x51,
+0x32,
+0x14,
+0xf,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x43,
+0x52,
+0x50,
+0x52,
+0x51,
+0x32,
+0x14,
+0x17,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x8a,
+0x68,
+0xa,
+0x5,
+0x50,
+0x52,
+0x52,
+0x49,
+0x70,
+0x50,
+0x52,
+0x52,
+0x49,
+0x50,
+0x52,
+0x51,
+0x32,
+0x5b,
+0x82,
+0x4d,
+0x7,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0xa,
+0x3,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0x16,
+0xa,
+0x13,
+0x89,
+0xe,
+0x0,
+0x9,
+0x3,
+0x5,
+0x0,
+0x0,
+0x0,
+0xa,
+0x0,
+0x0,
+0x0,
+0xb,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0xf,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x53,
+0x54,
+0x50,
+0x52,
+0x51,
+0x33,
+0x14,
+0x11,
+0x5f,
+0x44,
+0x49,
+0x53,
+0x0,
+0x7d,
+0x50,
+0x52,
+0x51,
+0x33,
+0xa,
+0x80,
+0x50,
+0x52,
+0x51,
+0x33,
+0x14,
+0xf,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x43,
+0x52,
+0x50,
+0x52,
+0x51,
+0x33,
+0x14,
+0x17,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x8a,
+0x68,
+0xa,
+0x5,
+0x50,
+0x52,
+0x52,
+0x49,
+0x70,
+0x50,
+0x52,
+0x52,
+0x49,
+0x50,
+0x52,
+0x51,
+0x33,
+0x5b,
+0x82,
+0x4f,
+0x4,
+0x4c,
+0x4e,
+0x4b,
+0x53,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0xa,
+0x4,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x9,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0x9,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0xa,
+0xb,
+0x14,
+0x6,
+0x5f,
+0x44,
+0x49,
+0x53,
+0x0,
+0x14,
+0xb,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x0,
+0xa4,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x14,
+0x6,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x10,
+0x47,
+0xe,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x14,
+0x35,
+0x43,
+0x50,
+0x4d,
+0x41,
+0x1,
+0x70,
+0x83,
+0x88,
+0x43,
+0x50,
+0x4f,
+0x4e,
+0x68,
+0x0,
+0x60,
+0x70,
+0x11,
+0xb,
+0xa,
+0x8,
+0x0,
+0x8,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x61,
+0x70,
+0x68,
+0x88,
+0x61,
+0xa,
+0x2,
+0x0,
+0x70,
+0x68,
+0x88,
+0x61,
+0xa,
+0x3,
+0x0,
+0x70,
+0x60,
+0x88,
+0x61,
+0xa,
+0x4,
+0x0,
+0xa4,
+0x61,
+0x14,
+0x1a,
+0x43,
+0x50,
+0x53,
+0x54,
+0x1,
+0x70,
+0x83,
+0x88,
+0x43,
+0x50,
+0x4f,
+0x4e,
+0x68,
+0x0,
+0x60,
+0xa0,
+0x5,
+0x60,
+0xa4,
+0xa,
+0xf,
+0xa1,
+0x3,
+0xa4,
+0x0,
+0x14,
+0xa,
+0x43,
+0x50,
+0x45,
+0x4a,
+0x2,
+0x5b,
+0x22,
+0xa,
+0xc8,
+0x5b,
+0x80,
+0x50,
+0x52,
+0x53,
+0x54,
+0x1,
+0xb,
+0x0,
+0xaf,
+0xa,
+0x20,
+0x5b,
+0x81,
+0xc,
+0x50,
+0x52,
+0x53,
+0x54,
+0x1,
+0x50,
+0x52,
+0x53,
+0x5f,
+0x40,
+0x10,
+0x14,
+0x4a,
+0x6,
+0x50,
+0x52,
+0x53,
+0x43,
+0x0,
+0x70,
+0x50,
+0x52,
+0x53,
+0x5f,
+0x65,
+0x70,
+0x0,
+0x62,
+0x70,
+0x0,
+0x60,
+0xa2,
+0x46,
+0x5,
+0x95,
+0x60,
+0x87,
+0x43,
+0x50,
+0x4f,
+0x4e,
+0x70,
+0x83,
+0x88,
+0x43,
+0x50,
+0x4f,
+0x4e,
+0x60,
+0x0,
+0x61,
+0xa0,
+0xa,
+0x7b,
+0x60,
+0xa,
+0x7,
+0x0,
+0x7a,
+0x62,
+0x1,
+0x62,
+0xa1,
+0xc,
+0x70,
+0x83,
+0x88,
+0x65,
+0x7a,
+0x60,
+0xa,
+0x3,
+0x0,
+0x0,
+0x62,
+0x70,
+0x7b,
+0x62,
+0x1,
+0x0,
+0x63,
+0xa0,
+0x22,
+0x92,
+0x93,
+0x61,
+0x63,
+0x70,
+0x63,
+0x88,
+0x43,
+0x50,
+0x4f,
+0x4e,
+0x60,
+0x0,
+0xa0,
+0xa,
+0x93,
+0x63,
+0x1,
+0x4e,
+0x54,
+0x46,
+0x59,
+0x60,
+0x1,
+0xa1,
+0x8,
+0x4e,
+0x54,
+0x46,
+0x59,
+0x60,
+0xa,
+0x3,
+0x75,
+0x60,
+0x10,
+0x4e,
+0x9,
+0x5f,
+0x47,
+0x50,
+0x45,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xd,
+0x41,
+0x43,
+0x50,
+0x49,
+0x30,
+0x30,
+0x30,
+0x36,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x30,
+0x0,
+0x14,
+0x15,
+0x5f,
+0x45,
+0x30,
+0x31,
+0x0,
+0x5c,
+0x2f,
+0x3,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x50,
+0x43,
+0x49,
+0x30,
+0x50,
+0x43,
+0x4e,
+0x46,
+0x14,
+0x10,
+0x5f,
+0x45,
+0x30,
+0x32,
+0x0,
+0x5c,
+0x2e,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x43,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x33,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x34,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x35,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x36,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x37,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x38,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x39,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x41,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x42,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x43,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x44,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x45,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x46,
+0x0
+};
diff --git a/hw/i386/bios-linker-loader.c b/hw/i386/bios-linker-loader.c
new file mode 100644 (file)
index 0000000..0833853
--- /dev/null
@@ -0,0 +1,158 @@
+/* Dynamic linker/loader of ACPI tables
+ *
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * Author: Michael S. Tsirkin <mst@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bios-linker-loader.h"
+#include "hw/nvram/fw_cfg.h"
+
+#include <string.h>
+#include <assert.h>
+#include "qemu/bswap.h"
+
+#define BIOS_LINKER_LOADER_FILESZ FW_CFG_MAX_FILE_PATH
+
+struct BiosLinkerLoaderEntry {
+    uint32_t command;
+    union {
+        /*
+         * COMMAND_ALLOCATE - allocate a table from @alloc.file
+         * subject to @alloc.align alignment (must be power of 2)
+         * and @alloc.zone (can be HIGH or FSEG) requirements.
+         *
+         * Must appear exactly once for each file, and before
+         * this file is referenced by any other command.
+         */
+        struct {
+            char file[BIOS_LINKER_LOADER_FILESZ];
+            uint32_t align;
+            uint8_t zone;
+        } alloc;
+
+        /*
+         * COMMAND_ADD_POINTER - patch the table (originating from
+         * @dest_file) at @pointer.offset, by adding a pointer to the table
+         * originating from @src_file. 1,2,4 or 8 byte unsigned
+         * addition is used depending on @pointer.size.
+         */
+        struct {
+            char dest_file[BIOS_LINKER_LOADER_FILESZ];
+            char src_file[BIOS_LINKER_LOADER_FILESZ];
+            uint32_t offset;
+            uint8_t size;
+        } pointer;
+
+        /*
+         * COMMAND_ADD_CHECKSUM - calculate checksum of the range specified by
+         * @cksum_start and @cksum_length fields,
+         * and then add the value at @cksum.offset.
+         * Checksum simply sums -X for each byte X in the range
+         * using 8-bit math.
+         */
+        struct {
+            char file[BIOS_LINKER_LOADER_FILESZ];
+            uint32_t offset;
+            uint32_t start;
+            uint32_t length;
+        } cksum;
+
+        /* padding */
+        char pad[124];
+    };
+} QEMU_PACKED;
+typedef struct BiosLinkerLoaderEntry BiosLinkerLoaderEntry;
+
+enum {
+    BIOS_LINKER_LOADER_COMMAND_ALLOCATE     = 0x1,
+    BIOS_LINKER_LOADER_COMMAND_ADD_POINTER  = 0x2,
+    BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM = 0x3,
+};
+
+enum {
+    BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH = 0x1,
+    BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG = 0x2,
+};
+
+GArray *bios_linker_loader_init(void)
+{
+    return g_array_new(false, true /* clear */, sizeof(BiosLinkerLoaderEntry));
+}
+
+/* Free linker wrapper and return the linker array. */
+void *bios_linker_loader_cleanup(GArray *linker)
+{
+    return g_array_free(linker, false);
+}
+
+void bios_linker_loader_alloc(GArray *linker,
+                              const char *file,
+                              uint32_t alloc_align,
+                              bool alloc_fseg)
+{
+    BiosLinkerLoaderEntry entry;
+
+    memset(&entry, 0, sizeof entry);
+    strncpy(entry.alloc.file, file, sizeof entry.alloc.file - 1);
+    entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ALLOCATE);
+    entry.alloc.align = cpu_to_le32(alloc_align);
+    entry.alloc.zone = cpu_to_le32(alloc_fseg ?
+                                    BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG :
+                                    BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH);
+
+    /* Alloc entries must come first, so prepend them */
+    g_array_prepend_val(linker, entry);
+}
+
+void bios_linker_loader_add_checksum(GArray *linker, const char *file,
+                                     void *table,
+                                     void *start, unsigned size,
+                                     uint8_t *checksum)
+{
+    BiosLinkerLoaderEntry entry;
+
+    memset(&entry, 0, sizeof entry);
+    strncpy(entry.cksum.file, file, sizeof entry.cksum.file - 1);
+    entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM);
+    entry.cksum.offset = cpu_to_le32(checksum - (uint8_t *)table);
+    entry.cksum.start = cpu_to_le32((uint8_t *)start - (uint8_t *)table);
+    entry.cksum.length = cpu_to_le32(size);
+
+    g_array_append_val(linker, entry);
+}
+
+void bios_linker_loader_add_pointer(GArray *linker,
+                                    const char *dest_file,
+                                    const char *src_file,
+                                    GArray *table, void *pointer,
+                                    uint8_t pointer_size)
+{
+    BiosLinkerLoaderEntry entry;
+
+    memset(&entry, 0, sizeof entry);
+    strncpy(entry.pointer.dest_file, dest_file,
+            sizeof entry.pointer.dest_file - 1);
+    strncpy(entry.pointer.src_file, src_file,
+            sizeof entry.pointer.src_file - 1);
+    entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ADD_POINTER);
+    entry.pointer.offset = cpu_to_le32((gchar *)pointer - table->data);
+    entry.pointer.size = pointer_size;
+    assert(pointer_size == 1 || pointer_size == 2 ||
+           pointer_size == 4 || pointer_size == 8);
+
+    g_array_append_val(linker, entry);
+}
diff --git a/hw/i386/bios-linker-loader.h b/hw/i386/bios-linker-loader.h
new file mode 100644 (file)
index 0000000..498c0af
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef BIOS_LINKER_LOADER_H
+#define BIOS_LINKER_LOADER_H
+
+#include <glib.h>
+#include <stdbool.h>
+#include <inttypes.h>
+
+GArray *bios_linker_loader_init(void);
+
+void bios_linker_loader_alloc(GArray *linker,
+                              const char *file,
+                              uint32_t alloc_align,
+                              bool alloc_fseg);
+
+void bios_linker_loader_add_checksum(GArray *linker, const char *file,
+                                     void *table,
+                                     void *start, unsigned size,
+                                     uint8_t *checksum);
+
+void bios_linker_loader_add_pointer(GArray *linker,
+                                    const char *dest_file,
+                                    const char *src_file,
+                                    GArray *table, void *pointer,
+                                    uint8_t pointer_size);
+
+void *bios_linker_loader_cleanup(GArray *linker);
+#endif
index 0c313feb0b297709a5c554051cf1a517e2786340..dee409d2711ce2ea9814a7ea1aecd9add16181e6 100644 (file)
@@ -56,6 +56,7 @@
 #include "hw/cpu/icc_bus.h"
 #include "hw/boards.h"
 #include "hw/pci/pci_host.h"
+#include "acpi-build.h"
 
 /* debug PC/ISA interrupts */
 //#define DEBUG_IRQ
@@ -1040,6 +1041,7 @@ void pc_guest_info_machine_done(Notifier *notifier, void *data)
                                                       PcGuestInfoState,
                                                       machine_done);
     pc_fw_cfg_guest_info(&guest_info_state->info);
+    acpi_setup(&guest_info_state->info);
 }
 
 PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
@@ -1047,6 +1049,27 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
 {
     PcGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state);
     PcGuestInfo *guest_info = &guest_info_state->info;
+    int i, j;
+
+    guest_info->ram_size = below_4g_mem_size + above_4g_mem_size;
+    guest_info->apic_id_limit = pc_apic_id_limit(max_cpus);
+    guest_info->apic_xrupt_override = kvm_allows_irq0_override();
+    guest_info->numa_nodes = nb_numa_nodes;
+    guest_info->node_mem = g_memdup(node_mem, guest_info->numa_nodes *
+                                    sizeof *guest_info->node_mem);
+    guest_info->node_cpu = g_malloc0(guest_info->apic_id_limit *
+                                     sizeof *guest_info->node_cpu);
+
+    for (i = 0; i < max_cpus; i++) {
+        unsigned int apic_id = x86_cpu_apic_id_from_index(i);
+        assert(apic_id < guest_info->apic_id_limit);
+        for (j = 0; j < nb_numa_nodes; j++) {
+            if (test_bit(i, node_cpumask[j])) {
+                guest_info->node_cpu[apic_id] = j;
+                break;
+            }
+        }
+    }
 
     guest_info_state->machine_done.notify = pc_guest_info_machine_done;
     qemu_add_machine_init_done_notifier(&guest_info_state->machine_done);
@@ -1093,7 +1116,7 @@ void pc_acpi_init(const char *default_dsdt)
         opts = qemu_opts_parse(qemu_find_opts("acpi"), arg, 0);
         g_assert(opts != NULL);
 
-        acpi_table_add(opts, &err);
+        acpi_table_add_builtin(opts, &err);
         if (err) {
             error_report("WARNING: failed to load %s: %s", filename,
                          error_get_pretty(err));
@@ -1134,12 +1157,20 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
     memory_region_init_alias(ram_below_4g, NULL, "ram-below-4g", ram,
                              0, below_4g_mem_size);
     memory_region_add_subregion(system_memory, 0, ram_below_4g);
+    if (0) {
+        /*
+         * Ideally we should do that too, but that would ruin the e820
+         * reservations added by seabios before initializing fw_cfg.
+         */
+        e820_add_entry(0, below_4g_mem_size, E820_RAM);
+    }
     if (above_4g_mem_size > 0) {
         ram_above_4g = g_malloc(sizeof(*ram_above_4g));
         memory_region_init_alias(ram_above_4g, NULL, "ram-above-4g", ram,
                                  below_4g_mem_size, above_4g_mem_size);
         memory_region_add_subregion(system_memory, 0x100000000ULL,
                                     ram_above_4g);
+        e820_add_entry(0x100000000ULL, above_4g_mem_size, E820_RAM);
     }
 
 
index c6042c7e23f2432dd053dc45270c5fb295bf1fda..24a98cbee74a6fe2ea42312c9bf95160b99981bd 100644 (file)
@@ -59,6 +59,7 @@ static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
 
 static bool has_pvpanic;
 static bool has_pci_info = true;
+static bool has_acpi_build = true;
 
 /* PC hardware initialisation */
 static void pc_init1(QEMUMachineInitArgs *args,
@@ -122,6 +123,9 @@ static void pc_init1(QEMUMachineInitArgs *args,
     }
 
     guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size);
+
+    guest_info->has_acpi_build = has_acpi_build;
+
     guest_info->has_pci_info = has_pci_info;
     guest_info->isapc_ram_fw = !pci_enabled;
 
@@ -240,6 +244,7 @@ static void pc_compat_1_6(QEMUMachineInitArgs *args)
 {
     has_pci_info = false;
     rom_file_in_ram = false;
+    has_acpi_build = false;
 }
 
 static void pc_compat_1_5(QEMUMachineInitArgs *args)
index ca84e1c04ceb38c4c94a0406aa367059395956d7..4c191d3b425ee289cde44e982bcd9fa7ad2d2851 100644 (file)
@@ -49,6 +49,7 @@
 
 static bool has_pvpanic;
 static bool has_pci_info = true;
+static bool has_acpi_build = true;
 
 /* PC hardware initialisation */
 static void pc_q35_init(QEMUMachineInitArgs *args)
@@ -111,6 +112,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
     guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size);
     guest_info->has_pci_info = has_pci_info;
     guest_info->isapc_ram_fw = false;
+    guest_info->has_acpi_build = has_acpi_build;
 
     /* allocate ram and load rom/bios */
     if (!xen_enabled()) {
@@ -224,6 +226,7 @@ static void pc_compat_1_6(QEMUMachineInitArgs *args)
 {
     has_pci_info = false;
     rom_file_in_ram = false;
+    has_acpi_build = false;
 }
 
 static void pc_compat_1_5(QEMUMachineInitArgs *args)
diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl
new file mode 100644 (file)
index 0000000..21c89b0
--- /dev/null
@@ -0,0 +1,452 @@
+/*
+ * Bochs/QEMU ACPI DSDT ASL definition
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+/*
+ * Copyright (c) 2010 Isaku Yamahata
+ *                    yamahata at valinux co jp
+ * Based on acpi-dsdt.dsl, but heavily modified for q35 chipset.
+ */
+
+ACPI_EXTRACT_ALL_CODE Q35AcpiDsdtAmlCode
+
+DefinitionBlock (
+    "q35-acpi-dsdt.aml",// Output Filename
+    "DSDT",             // Signature
+    0x01,               // DSDT Compliance Revision
+    "BXPC",             // OEMID
+    "BXDSDT",           // TABLE ID
+    0x2                 // OEM Revision
+    )
+{
+
+#include "acpi-dsdt-dbug.dsl"
+
+    Scope(\_SB) {
+        OperationRegion(PCST, SystemIO, 0xae00, 0x0c)
+        OperationRegion(PCSB, SystemIO, 0xae0c, 0x01)
+        Field(PCSB, AnyAcc, NoLock, WriteAsZeros) {
+            PCIB, 8,
+        }
+    }
+
+
+/****************************************************************
+ * PCI Bus definition
+ ****************************************************************/
+
+    Scope(\_SB) {
+        Device(PCI0) {
+            Name(_HID, EisaId("PNP0A08"))
+            Name(_CID, EisaId("PNP0A03"))
+            Name(_ADR, 0x00)
+            Name(_UID, 1)
+
+            // _OSC: based on sample of ACPI3.0b spec
+            Name(SUPP, 0) // PCI _OSC Support Field value
+            Name(CTRL, 0) // PCI _OSC Control Field value
+            Method(_OSC, 4) {
+                // Create DWORD-addressable fields from the Capabilities Buffer
+                CreateDWordField(Arg3, 0, CDW1)
+
+                // Check for proper UUID
+                If (LEqual(Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+                    // Create DWORD-addressable fields from the Capabilities Buffer
+                    CreateDWordField(Arg3, 4, CDW2)
+                    CreateDWordField(Arg3, 8, CDW3)
+
+                    // Save Capabilities DWORD2 & 3
+                    Store(CDW2, SUPP)
+                    Store(CDW3, CTRL)
+
+                    // Always allow native PME, AER (no dependencies)
+                    // Never allow SHPC (no SHPC controller in this system)
+                    And(CTRL, 0x1D, CTRL)
+
+#if 0 // For now, nothing to do
+                    If (Not(And(CDW1, 1))) { // Query flag clear?
+                        // Disable GPEs for features granted native control.
+                        If (And(CTRL, 0x01)) { // Hot plug control granted?
+                            Store(0, HPCE) // clear the hot plug SCI enable bit
+                            Store(1, HPCS) // clear the hot plug SCI status bit
+                        }
+                        If (And(CTRL, 0x04)) { // PME control granted?
+                            Store(0, PMCE) // clear the PME SCI enable bit
+                            Store(1, PMCS) // clear the PME SCI status bit
+                        }
+                        If (And(CTRL, 0x10)) { // OS restoring PCI Express cap structure?
+                            // Set status to not restore PCI Express cap structure
+                            // upon resume from S3
+                            Store(1, S3CR)
+                        }
+                    }
+#endif
+                    If (LNotEqual(Arg1, One)) {
+                        // Unknown revision
+                        Or(CDW1, 0x08, CDW1)
+                    }
+                    If (LNotEqual(CDW3, CTRL)) {
+                        // Capabilities bits were masked
+                        Or(CDW1, 0x10, CDW1)
+                    }
+                    // Update DWORD3 in the buffer
+                    Store(CTRL, CDW3)
+                } Else {
+                    Or(CDW1, 4, CDW1) // Unrecognized UUID
+                }
+                Return (Arg3)
+            }
+        }
+    }
+
+#include "acpi-dsdt-pci-crs.dsl"
+#include "acpi-dsdt-hpet.dsl"
+
+
+/****************************************************************
+ * VGA
+ ****************************************************************/
+
+    Scope(\_SB.PCI0) {
+        Device(VGA) {
+            Name(_ADR, 0x00010000)
+            Method(_S1D, 0, NotSerialized) {
+                Return (0x00)
+            }
+            Method(_S2D, 0, NotSerialized) {
+                Return (0x00)
+            }
+            Method(_S3D, 0, NotSerialized) {
+                Return (0x00)
+            }
+        }
+    }
+
+
+/****************************************************************
+ * LPC ISA bridge
+ ****************************************************************/
+
+    Scope(\_SB.PCI0) {
+        /* PCI D31:f0 LPC ISA bridge */
+        Device(ISA) {
+            /* PCI D31:f0 */
+            Name(_ADR, 0x001f0000)
+
+            /* ICH9 PCI to ISA irq remapping */
+            OperationRegion(PIRQ, PCI_Config, 0x60, 0x0C)
+
+            OperationRegion(LPCD, PCI_Config, 0x80, 0x2)
+            Field(LPCD, AnyAcc, NoLock, Preserve) {
+                COMA,   3,
+                    ,   1,
+                COMB,   3,
+
+                Offset(0x01),
+                LPTD,   2,
+                    ,   2,
+                FDCD,   2
+            }
+            OperationRegion(LPCE, PCI_Config, 0x82, 0x2)
+            Field(LPCE, AnyAcc, NoLock, Preserve) {
+                CAEN,   1,
+                CBEN,   1,
+                LPEN,   1,
+                FDEN,   1
+            }
+        }
+    }
+
+#include "acpi-dsdt-isa.dsl"
+
+
+/****************************************************************
+ * PCI IRQs
+ ****************************************************************/
+
+    /* Zero => PIC mode, One => APIC Mode */
+    Name(\PICF, Zero)
+    Method(\_PIC, 1, NotSerialized) {
+        Store(Arg0, \PICF)
+    }
+
+    Scope(\_SB) {
+        Scope(PCI0) {
+#define prt_slot_lnk(nr, lnk0, lnk1, lnk2, lnk3)  \
+    Package() { nr##ffff, 0, lnk0, 0 },           \
+    Package() { nr##ffff, 1, lnk1, 0 },           \
+    Package() { nr##ffff, 2, lnk2, 0 },           \
+    Package() { nr##ffff, 3, lnk3, 0 }
+
+#define prt_slot_lnkA(nr) prt_slot_lnk(nr, LNKA, LNKB, LNKC, LNKD)
+#define prt_slot_lnkB(nr) prt_slot_lnk(nr, LNKB, LNKC, LNKD, LNKA)
+#define prt_slot_lnkC(nr) prt_slot_lnk(nr, LNKC, LNKD, LNKA, LNKB)
+#define prt_slot_lnkD(nr) prt_slot_lnk(nr, LNKD, LNKA, LNKB, LNKC)
+
+#define prt_slot_lnkE(nr) prt_slot_lnk(nr, LNKE, LNKF, LNKG, LNKH)
+#define prt_slot_lnkF(nr) prt_slot_lnk(nr, LNKF, LNKG, LNKH, LNKE)
+#define prt_slot_lnkG(nr) prt_slot_lnk(nr, LNKG, LNKH, LNKE, LNKF)
+#define prt_slot_lnkH(nr) prt_slot_lnk(nr, LNKH, LNKE, LNKF, LNKG)
+
+            Name(PRTP, package() {
+                prt_slot_lnkE(0x0000),
+                prt_slot_lnkF(0x0001),
+                prt_slot_lnkG(0x0002),
+                prt_slot_lnkH(0x0003),
+                prt_slot_lnkE(0x0004),
+                prt_slot_lnkF(0x0005),
+                prt_slot_lnkG(0x0006),
+                prt_slot_lnkH(0x0007),
+                prt_slot_lnkE(0x0008),
+                prt_slot_lnkF(0x0009),
+                prt_slot_lnkG(0x000a),
+                prt_slot_lnkH(0x000b),
+                prt_slot_lnkE(0x000c),
+                prt_slot_lnkF(0x000d),
+                prt_slot_lnkG(0x000e),
+                prt_slot_lnkH(0x000f),
+                prt_slot_lnkE(0x0010),
+                prt_slot_lnkF(0x0011),
+                prt_slot_lnkG(0x0012),
+                prt_slot_lnkH(0x0013),
+                prt_slot_lnkE(0x0014),
+                prt_slot_lnkF(0x0015),
+                prt_slot_lnkG(0x0016),
+                prt_slot_lnkH(0x0017),
+                prt_slot_lnkE(0x0018),
+
+                /* INTA -> PIRQA for slot 25 - 31
+                   see the default value of D<N>IR */
+                prt_slot_lnkA(0x0019),
+                prt_slot_lnkA(0x001a),
+                prt_slot_lnkA(0x001b),
+                prt_slot_lnkA(0x001c),
+                prt_slot_lnkA(0x001d),
+
+                /* PCIe->PCI bridge. use PIRQ[E-H] */
+                prt_slot_lnkE(0x001e),
+
+                prt_slot_lnkA(0x001f)
+            })
+
+#define prt_slot_gsi(nr, gsi0, gsi1, gsi2, gsi3)  \
+    Package() { nr##ffff, 0, gsi0, 0 },           \
+    Package() { nr##ffff, 1, gsi1, 0 },           \
+    Package() { nr##ffff, 2, gsi2, 0 },           \
+    Package() { nr##ffff, 3, gsi3, 0 }
+
+#define prt_slot_gsiA(nr) prt_slot_gsi(nr, GSIA, GSIB, GSIC, GSID)
+#define prt_slot_gsiB(nr) prt_slot_gsi(nr, GSIB, GSIC, GSID, GSIA)
+#define prt_slot_gsiC(nr) prt_slot_gsi(nr, GSIC, GSID, GSIA, GSIB)
+#define prt_slot_gsiD(nr) prt_slot_gsi(nr, GSID, GSIA, GSIB, GSIC)
+
+#define prt_slot_gsiE(nr) prt_slot_gsi(nr, GSIE, GSIF, GSIG, GSIH)
+#define prt_slot_gsiF(nr) prt_slot_gsi(nr, GSIF, GSIG, GSIH, GSIE)
+#define prt_slot_gsiG(nr) prt_slot_gsi(nr, GSIG, GSIH, GSIE, GSIF)
+#define prt_slot_gsiH(nr) prt_slot_gsi(nr, GSIH, GSIE, GSIF, GSIG)
+
+            Name(PRTA, package() {
+                prt_slot_gsiE(0x0000),
+                prt_slot_gsiF(0x0001),
+                prt_slot_gsiG(0x0002),
+                prt_slot_gsiH(0x0003),
+                prt_slot_gsiE(0x0004),
+                prt_slot_gsiF(0x0005),
+                prt_slot_gsiG(0x0006),
+                prt_slot_gsiH(0x0007),
+                prt_slot_gsiE(0x0008),
+                prt_slot_gsiF(0x0009),
+                prt_slot_gsiG(0x000a),
+                prt_slot_gsiH(0x000b),
+                prt_slot_gsiE(0x000c),
+                prt_slot_gsiF(0x000d),
+                prt_slot_gsiG(0x000e),
+                prt_slot_gsiH(0x000f),
+                prt_slot_gsiE(0x0010),
+                prt_slot_gsiF(0x0011),
+                prt_slot_gsiG(0x0012),
+                prt_slot_gsiH(0x0013),
+                prt_slot_gsiE(0x0014),
+                prt_slot_gsiF(0x0015),
+                prt_slot_gsiG(0x0016),
+                prt_slot_gsiH(0x0017),
+                prt_slot_gsiE(0x0018),
+
+                /* INTA -> PIRQA for slot 25 - 31, but 30
+                   see the default value of D<N>IR */
+                prt_slot_gsiA(0x0019),
+                prt_slot_gsiA(0x001a),
+                prt_slot_gsiA(0x001b),
+                prt_slot_gsiA(0x001c),
+                prt_slot_gsiA(0x001d),
+
+                /* PCIe->PCI bridge. use PIRQ[E-H] */
+                prt_slot_gsiE(0x001e),
+
+                prt_slot_gsiA(0x001f)
+            })
+
+            Method(_PRT, 0, NotSerialized) {
+                /* PCI IRQ routing table, example from ACPI 2.0a specification,
+                   section 6.2.8.1 */
+                /* Note: we provide the same info as the PCI routing
+                   table of the Bochs BIOS */
+                If (LEqual(\PICF, Zero)) {
+                    Return (PRTP)
+                } Else {
+                    Return (PRTA)
+                }
+            }
+        }
+
+        Field(PCI0.ISA.PIRQ, ByteAcc, NoLock, Preserve) {
+            PRQA,   8,
+            PRQB,   8,
+            PRQC,   8,
+            PRQD,   8,
+
+            Offset(0x08),
+            PRQE,   8,
+            PRQF,   8,
+            PRQG,   8,
+            PRQH,   8
+        }
+
+        Method(IQST, 1, NotSerialized) {
+            // _STA method - get status
+            If (And(0x80, Arg0)) {
+                Return (0x09)
+            }
+            Return (0x0B)
+        }
+        Method(IQCR, 1, NotSerialized) {
+            // _CRS method - get current settings
+            Name(PRR0, ResourceTemplate() {
+                Interrupt(, Level, ActiveHigh, Shared) { 0 }
+            })
+            CreateDWordField(PRR0, 0x05, PRRI)
+            Store(And(Arg0, 0x0F), PRRI)
+            Return (PRR0)
+        }
+
+#define define_link(link, uid, reg)                             \
+        Device(link) {                                          \
+            Name(_HID, EISAID("PNP0C0F"))                       \
+            Name(_UID, uid)                                     \
+            Name(_PRS, ResourceTemplate() {                     \
+                Interrupt(, Level, ActiveHigh, Shared) {        \
+                    5, 10, 11                                   \
+                }                                               \
+            })                                                  \
+            Method(_STA, 0, NotSerialized) {                    \
+                Return (IQST(reg))                              \
+            }                                                   \
+            Method(_DIS, 0, NotSerialized) {                    \
+                Or(reg, 0x80, reg)                              \
+            }                                                   \
+            Method(_CRS, 0, NotSerialized) {                    \
+                Return (IQCR(reg))                              \
+            }                                                   \
+            Method(_SRS, 1, NotSerialized) {                    \
+                CreateDWordField(Arg0, 0x05, PRRI)              \
+                Store(PRRI, reg)                                \
+            }                                                   \
+        }
+
+        define_link(LNKA, 0, PRQA)
+        define_link(LNKB, 1, PRQB)
+        define_link(LNKC, 2, PRQC)
+        define_link(LNKD, 3, PRQD)
+        define_link(LNKE, 4, PRQE)
+        define_link(LNKF, 5, PRQF)
+        define_link(LNKG, 6, PRQG)
+        define_link(LNKH, 7, PRQH)
+
+#define define_gsi_link(link, uid, gsi)                         \
+        Device(link) {                                          \
+            Name(_HID, EISAID("PNP0C0F"))                       \
+            Name(_UID, uid)                                     \
+            Name(_PRS, ResourceTemplate() {                     \
+                Interrupt(, Level, ActiveHigh, Shared) {        \
+                    gsi                                         \
+                }                                               \
+            })                                                  \
+            Name(_CRS, ResourceTemplate() {                     \
+                Interrupt(, Level, ActiveHigh, Shared) {        \
+                    gsi                                         \
+                }                                               \
+            })                                                  \
+            Method(_SRS, 1, NotSerialized) {                    \
+            }                                                   \
+        }
+
+        define_gsi_link(GSIA, 0, 0x10)
+        define_gsi_link(GSIB, 0, 0x11)
+        define_gsi_link(GSIC, 0, 0x12)
+        define_gsi_link(GSID, 0, 0x13)
+        define_gsi_link(GSIE, 0, 0x14)
+        define_gsi_link(GSIF, 0, 0x15)
+        define_gsi_link(GSIG, 0, 0x16)
+        define_gsi_link(GSIH, 0, 0x17)
+    }
+
+#include "acpi-dsdt-cpu-hotplug.dsl"
+
+
+/****************************************************************
+ * General purpose events
+ ****************************************************************/
+
+    Scope(\_GPE) {
+        Name(_HID, "ACPI0006")
+
+        Method(_L00) {
+        }
+        Method(_L01) {
+            // CPU hotplug event
+            \_SB.PRSC()
+        }
+        Method(_L02) {
+        }
+        Method(_L03) {
+        }
+        Method(_L04) {
+        }
+        Method(_L05) {
+        }
+        Method(_L06) {
+        }
+        Method(_L07) {
+        }
+        Method(_L08) {
+        }
+        Method(_L09) {
+        }
+        Method(_L0A) {
+        }
+        Method(_L0B) {
+        }
+        Method(_L0C) {
+        }
+        Method(_L0D) {
+        }
+        Method(_L0E) {
+        }
+        Method(_L0F) {
+        }
+    }
+}
diff --git a/hw/i386/q35-acpi-dsdt.hex.generated b/hw/i386/q35-acpi-dsdt.hex.generated
new file mode 100644 (file)
index 0000000..32c16ff
--- /dev/null
@@ -0,0 +1,7346 @@
+static unsigned char Q35AcpiDsdtAmlCode[] = {
+0x44,
+0x53,
+0x44,
+0x54,
+0xb0,
+0x1c,
+0x0,
+0x0,
+0x1,
+0x6,
+0x42,
+0x58,
+0x50,
+0x43,
+0x0,
+0x0,
+0x42,
+0x58,
+0x44,
+0x53,
+0x44,
+0x54,
+0x0,
+0x0,
+0x2,
+0x0,
+0x0,
+0x0,
+0x49,
+0x4e,
+0x54,
+0x4c,
+0x23,
+0x8,
+0x13,
+0x20,
+0x10,
+0x49,
+0x4,
+0x5c,
+0x0,
+0x5b,
+0x80,
+0x44,
+0x42,
+0x47,
+0x5f,
+0x1,
+0xb,
+0x2,
+0x4,
+0x1,
+0x5b,
+0x81,
+0xb,
+0x44,
+0x42,
+0x47,
+0x5f,
+0x1,
+0x44,
+0x42,
+0x47,
+0x42,
+0x8,
+0x14,
+0x2c,
+0x44,
+0x42,
+0x55,
+0x47,
+0x1,
+0x98,
+0x68,
+0x60,
+0x96,
+0x60,
+0x60,
+0x74,
+0x87,
+0x60,
+0x1,
+0x61,
+0x70,
+0x0,
+0x62,
+0xa2,
+0x10,
+0x95,
+0x62,
+0x61,
+0x70,
+0x83,
+0x88,
+0x60,
+0x62,
+0x0,
+0x44,
+0x42,
+0x47,
+0x42,
+0x75,
+0x62,
+0x70,
+0xa,
+0xa,
+0x44,
+0x42,
+0x47,
+0x42,
+0x10,
+0x29,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x5b,
+0x80,
+0x50,
+0x43,
+0x53,
+0x54,
+0x1,
+0xb,
+0x0,
+0xae,
+0xa,
+0xc,
+0x5b,
+0x80,
+0x50,
+0x43,
+0x53,
+0x42,
+0x1,
+0xb,
+0xc,
+0xae,
+0x1,
+0x5b,
+0x81,
+0xb,
+0x50,
+0x43,
+0x53,
+0x42,
+0x40,
+0x50,
+0x43,
+0x49,
+0x42,
+0x8,
+0x10,
+0x4f,
+0xc,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x5b,
+0x82,
+0x47,
+0xc,
+0x50,
+0x43,
+0x49,
+0x30,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xa,
+0x8,
+0x8,
+0x5f,
+0x43,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xa,
+0x3,
+0x8,
+0x5f,
+0x41,
+0x44,
+0x52,
+0x0,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x1,
+0x8,
+0x53,
+0x55,
+0x50,
+0x50,
+0x0,
+0x8,
+0x43,
+0x54,
+0x52,
+0x4c,
+0x0,
+0x14,
+0x44,
+0x9,
+0x5f,
+0x4f,
+0x53,
+0x43,
+0x4,
+0x8a,
+0x6b,
+0x0,
+0x43,
+0x44,
+0x57,
+0x31,
+0xa0,
+0x46,
+0x7,
+0x93,
+0x68,
+0x11,
+0x13,
+0xa,
+0x10,
+0x5b,
+0x4d,
+0xdb,
+0x33,
+0xf7,
+0x1f,
+0x1c,
+0x40,
+0x96,
+0x57,
+0x74,
+0x41,
+0xc0,
+0x3d,
+0xd7,
+0x66,
+0x8a,
+0x6b,
+0xa,
+0x4,
+0x43,
+0x44,
+0x57,
+0x32,
+0x8a,
+0x6b,
+0xa,
+0x8,
+0x43,
+0x44,
+0x57,
+0x33,
+0x70,
+0x43,
+0x44,
+0x57,
+0x32,
+0x53,
+0x55,
+0x50,
+0x50,
+0x70,
+0x43,
+0x44,
+0x57,
+0x33,
+0x43,
+0x54,
+0x52,
+0x4c,
+0x7b,
+0x43,
+0x54,
+0x52,
+0x4c,
+0xa,
+0x1d,
+0x43,
+0x54,
+0x52,
+0x4c,
+0xa0,
+0x10,
+0x92,
+0x93,
+0x69,
+0x1,
+0x7d,
+0x43,
+0x44,
+0x57,
+0x31,
+0xa,
+0x8,
+0x43,
+0x44,
+0x57,
+0x31,
+0xa0,
+0x16,
+0x92,
+0x93,
+0x43,
+0x44,
+0x57,
+0x33,
+0x43,
+0x54,
+0x52,
+0x4c,
+0x7d,
+0x43,
+0x44,
+0x57,
+0x31,
+0xa,
+0x10,
+0x43,
+0x44,
+0x57,
+0x31,
+0x70,
+0x43,
+0x54,
+0x52,
+0x4c,
+0x43,
+0x44,
+0x57,
+0x33,
+0xa1,
+0xc,
+0x7d,
+0x43,
+0x44,
+0x57,
+0x31,
+0xa,
+0x4,
+0x43,
+0x44,
+0x57,
+0x31,
+0xa4,
+0x6b,
+0x10,
+0x4e,
+0x15,
+0x2e,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x50,
+0x43,
+0x49,
+0x30,
+0x8,
+0x43,
+0x52,
+0x45,
+0x53,
+0x11,
+0x42,
+0x7,
+0xa,
+0x6e,
+0x88,
+0xd,
+0x0,
+0x2,
+0xc,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x1,
+0x47,
+0x1,
+0xf8,
+0xc,
+0xf8,
+0xc,
+0x1,
+0x8,
+0x88,
+0xd,
+0x0,
+0x1,
+0xc,
+0x3,
+0x0,
+0x0,
+0x0,
+0x0,
+0xf7,
+0xc,
+0x0,
+0x0,
+0xf8,
+0xc,
+0x88,
+0xd,
+0x0,
+0x1,
+0xc,
+0x3,
+0x0,
+0x0,
+0x0,
+0xd,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0xf3,
+0x87,
+0x17,
+0x0,
+0x0,
+0xc,
+0x3,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0xa,
+0x0,
+0xff,
+0xff,
+0xb,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x2,
+0x0,
+0x87,
+0x17,
+0x0,
+0x0,
+0xc,
+0x1,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0xe0,
+0xff,
+0xff,
+0xbf,
+0xfe,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0xc0,
+0x1e,
+0x79,
+0x0,
+0x8,
+0x43,
+0x52,
+0x36,
+0x34,
+0x11,
+0x33,
+0xa,
+0x30,
+0x8a,
+0x2b,
+0x0,
+0x0,
+0xc,
+0x3,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x80,
+0x0,
+0x0,
+0x0,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x80,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0x41,
+0xa,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x0,
+0x8a,
+0x43,
+0x52,
+0x45,
+0x53,
+0xa,
+0x5c,
+0x50,
+0x53,
+0x33,
+0x32,
+0x8a,
+0x43,
+0x52,
+0x45,
+0x53,
+0xa,
+0x60,
+0x50,
+0x45,
+0x33,
+0x32,
+0x8a,
+0x43,
+0x52,
+0x45,
+0x53,
+0xa,
+0x68,
+0x50,
+0x4c,
+0x33,
+0x32,
+0x70,
+0x50,
+0x30,
+0x53,
+0x5f,
+0x50,
+0x53,
+0x33,
+0x32,
+0x70,
+0x50,
+0x30,
+0x45,
+0x5f,
+0x50,
+0x45,
+0x33,
+0x32,
+0x70,
+0x72,
+0x74,
+0x50,
+0x30,
+0x45,
+0x5f,
+0x50,
+0x30,
+0x53,
+0x5f,
+0x0,
+0x1,
+0x0,
+0x50,
+0x4c,
+0x33,
+0x32,
+0xa0,
+0xc,
+0x93,
+0x50,
+0x31,
+0x56,
+0x5f,
+0x0,
+0xa4,
+0x43,
+0x52,
+0x45,
+0x53,
+0x8f,
+0x43,
+0x52,
+0x36,
+0x34,
+0xa,
+0xe,
+0x50,
+0x53,
+0x36,
+0x34,
+0x8f,
+0x43,
+0x52,
+0x36,
+0x34,
+0xa,
+0x16,
+0x50,
+0x45,
+0x36,
+0x34,
+0x8f,
+0x43,
+0x52,
+0x36,
+0x34,
+0xa,
+0x26,
+0x50,
+0x4c,
+0x36,
+0x34,
+0x70,
+0x50,
+0x31,
+0x53,
+0x5f,
+0x50,
+0x53,
+0x36,
+0x34,
+0x70,
+0x50,
+0x31,
+0x45,
+0x5f,
+0x50,
+0x45,
+0x36,
+0x34,
+0x70,
+0x50,
+0x31,
+0x4c,
+0x5f,
+0x50,
+0x4c,
+0x36,
+0x34,
+0x84,
+0x43,
+0x52,
+0x45,
+0x53,
+0x43,
+0x52,
+0x36,
+0x34,
+0x60,
+0xa4,
+0x60,
+0x10,
+0x4d,
+0x8,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x5b,
+0x82,
+0x45,
+0x8,
+0x48,
+0x50,
+0x45,
+0x54,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0x1,
+0x3,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x0,
+0x5b,
+0x80,
+0x48,
+0x50,
+0x54,
+0x4d,
+0x0,
+0xc,
+0x0,
+0x0,
+0xd0,
+0xfe,
+0xb,
+0x0,
+0x4,
+0x5b,
+0x81,
+0x10,
+0x48,
+0x50,
+0x54,
+0x4d,
+0x13,
+0x56,
+0x45,
+0x4e,
+0x44,
+0x20,
+0x50,
+0x52,
+0x44,
+0x5f,
+0x20,
+0x14,
+0x36,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0x70,
+0x56,
+0x45,
+0x4e,
+0x44,
+0x60,
+0x70,
+0x50,
+0x52,
+0x44,
+0x5f,
+0x61,
+0x7a,
+0x60,
+0xa,
+0x10,
+0x60,
+0xa0,
+0xc,
+0x91,
+0x93,
+0x60,
+0x0,
+0x93,
+0x60,
+0xb,
+0xff,
+0xff,
+0xa4,
+0x0,
+0xa0,
+0xe,
+0x91,
+0x93,
+0x61,
+0x0,
+0x94,
+0x61,
+0xc,
+0x0,
+0xe1,
+0xf5,
+0x5,
+0xa4,
+0x0,
+0xa4,
+0xa,
+0xf,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0x11,
+0xa,
+0xe,
+0x86,
+0x9,
+0x0,
+0x0,
+0x0,
+0x0,
+0xd0,
+0xfe,
+0x0,
+0x4,
+0x0,
+0x0,
+0x79,
+0x0,
+0x10,
+0x36,
+0x2e,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x50,
+0x43,
+0x49,
+0x30,
+0x5b,
+0x82,
+0x2a,
+0x56,
+0x47,
+0x41,
+0x5f,
+0x8,
+0x5f,
+0x41,
+0x44,
+0x52,
+0xc,
+0x0,
+0x0,
+0x1,
+0x0,
+0x14,
+0x8,
+0x5f,
+0x53,
+0x31,
+0x44,
+0x0,
+0xa4,
+0x0,
+0x14,
+0x8,
+0x5f,
+0x53,
+0x32,
+0x44,
+0x0,
+0xa4,
+0x0,
+0x14,
+0x8,
+0x5f,
+0x53,
+0x33,
+0x44,
+0x0,
+0xa4,
+0x0,
+0x10,
+0x4c,
+0x7,
+0x2e,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x50,
+0x43,
+0x49,
+0x30,
+0x5b,
+0x82,
+0x4f,
+0x6,
+0x49,
+0x53,
+0x41,
+0x5f,
+0x8,
+0x5f,
+0x41,
+0x44,
+0x52,
+0xc,
+0x0,
+0x0,
+0x1f,
+0x0,
+0x5b,
+0x80,
+0x50,
+0x49,
+0x52,
+0x51,
+0x2,
+0xa,
+0x60,
+0xa,
+0xc,
+0x5b,
+0x80,
+0x4c,
+0x50,
+0x43,
+0x44,
+0x2,
+0xa,
+0x80,
+0xa,
+0x2,
+0x5b,
+0x81,
+0x20,
+0x4c,
+0x50,
+0x43,
+0x44,
+0x0,
+0x43,
+0x4f,
+0x4d,
+0x41,
+0x3,
+0x0,
+0x1,
+0x43,
+0x4f,
+0x4d,
+0x42,
+0x3,
+0x0,
+0x1,
+0x4c,
+0x50,
+0x54,
+0x44,
+0x2,
+0x0,
+0x2,
+0x46,
+0x44,
+0x43,
+0x44,
+0x2,
+0x5b,
+0x80,
+0x4c,
+0x50,
+0x43,
+0x45,
+0x2,
+0xa,
+0x82,
+0xa,
+0x2,
+0x5b,
+0x81,
+0x1a,
+0x4c,
+0x50,
+0x43,
+0x45,
+0x0,
+0x43,
+0x41,
+0x45,
+0x4e,
+0x1,
+0x43,
+0x42,
+0x45,
+0x4e,
+0x1,
+0x4c,
+0x50,
+0x45,
+0x4e,
+0x1,
+0x46,
+0x44,
+0x45,
+0x4e,
+0x1,
+0x10,
+0x4c,
+0x1b,
+0x2f,
+0x3,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x50,
+0x43,
+0x49,
+0x30,
+0x49,
+0x53,
+0x41,
+0x5f,
+0x5b,
+0x82,
+0x2d,
+0x52,
+0x54,
+0x43,
+0x5f,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xb,
+0x0,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0x18,
+0xa,
+0x15,
+0x47,
+0x1,
+0x70,
+0x0,
+0x70,
+0x0,
+0x10,
+0x2,
+0x22,
+0x0,
+0x1,
+0x47,
+0x1,
+0x72,
+0x0,
+0x72,
+0x0,
+0x2,
+0x6,
+0x79,
+0x0,
+0x5b,
+0x82,
+0x37,
+0x4b,
+0x42,
+0x44,
+0x5f,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0x3,
+0x3,
+0x14,
+0x9,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0xa,
+0xf,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0x18,
+0xa,
+0x15,
+0x47,
+0x1,
+0x60,
+0x0,
+0x60,
+0x0,
+0x1,
+0x1,
+0x47,
+0x1,
+0x64,
+0x0,
+0x64,
+0x0,
+0x1,
+0x1,
+0x22,
+0x2,
+0x0,
+0x79,
+0x0,
+0x5b,
+0x82,
+0x27,
+0x4d,
+0x4f,
+0x55,
+0x5f,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xf,
+0x13,
+0x14,
+0x9,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0xa,
+0xf,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0x8,
+0xa,
+0x5,
+0x22,
+0x0,
+0x10,
+0x79,
+0x0,
+0x5b,
+0x82,
+0x4a,
+0x4,
+0x46,
+0x44,
+0x43,
+0x30,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0x7,
+0x0,
+0x14,
+0x18,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0x70,
+0x46,
+0x44,
+0x45,
+0x4e,
+0x60,
+0xa0,
+0x6,
+0x93,
+0x60,
+0x0,
+0xa4,
+0x0,
+0xa1,
+0x4,
+0xa4,
+0xa,
+0xf,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0x1b,
+0xa,
+0x18,
+0x47,
+0x1,
+0xf2,
+0x3,
+0xf2,
+0x3,
+0x0,
+0x4,
+0x47,
+0x1,
+0xf7,
+0x3,
+0xf7,
+0x3,
+0x0,
+0x1,
+0x22,
+0x40,
+0x0,
+0x2a,
+0x4,
+0x0,
+0x79,
+0x0,
+0x5b,
+0x82,
+0x3e,
+0x4c,
+0x50,
+0x54,
+0x5f,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0x4,
+0x0,
+0x14,
+0x18,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0x70,
+0x4c,
+0x50,
+0x45,
+0x4e,
+0x60,
+0xa0,
+0x6,
+0x93,
+0x60,
+0x0,
+0xa4,
+0x0,
+0xa1,
+0x4,
+0xa4,
+0xa,
+0xf,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0x10,
+0xa,
+0xd,
+0x47,
+0x1,
+0x78,
+0x3,
+0x78,
+0x3,
+0x8,
+0x8,
+0x22,
+0x80,
+0x0,
+0x79,
+0x0,
+0x5b,
+0x82,
+0x45,
+0x4,
+0x43,
+0x4f,
+0x4d,
+0x31,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0x5,
+0x1,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x1,
+0x14,
+0x18,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0x70,
+0x43,
+0x41,
+0x45,
+0x4e,
+0x60,
+0xa0,
+0x6,
+0x93,
+0x60,
+0x0,
+0xa4,
+0x0,
+0xa1,
+0x4,
+0xa4,
+0xa,
+0xf,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0x10,
+0xa,
+0xd,
+0x47,
+0x1,
+0xf8,
+0x3,
+0xf8,
+0x3,
+0x0,
+0x8,
+0x22,
+0x10,
+0x0,
+0x79,
+0x0,
+0x5b,
+0x82,
+0x46,
+0x4,
+0x43,
+0x4f,
+0x4d,
+0x32,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0x5,
+0x1,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0xa,
+0x2,
+0x14,
+0x18,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0x70,
+0x43,
+0x42,
+0x45,
+0x4e,
+0x60,
+0xa0,
+0x6,
+0x93,
+0x60,
+0x0,
+0xa4,
+0x0,
+0xa1,
+0x4,
+0xa4,
+0xa,
+0xf,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0x10,
+0xa,
+0xd,
+0x47,
+0x1,
+0xf8,
+0x2,
+0xf8,
+0x2,
+0x0,
+0x8,
+0x22,
+0x8,
+0x0,
+0x79,
+0x0,
+0x8,
+0x50,
+0x49,
+0x43,
+0x46,
+0x0,
+0x14,
+0xc,
+0x5f,
+0x50,
+0x49,
+0x43,
+0x1,
+0x70,
+0x68,
+0x50,
+0x49,
+0x43,
+0x46,
+0x10,
+0x8e,
+0x55,
+0x1,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x10,
+0x43,
+0xea,
+0x50,
+0x43,
+0x49,
+0x30,
+0x8,
+0x50,
+0x52,
+0x54,
+0x50,
+0x12,
+0x4b,
+0x73,
+0x80,
+0x12,
+0xb,
+0x4,
+0xb,
+0xff,
+0xff,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xb,
+0x4,
+0xb,
+0xff,
+0xff,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xc,
+0x4,
+0xb,
+0xff,
+0xff,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xc,
+0x4,
+0xb,
+0xff,
+0xff,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x2,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x2,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x2,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x2,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x3,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x3,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x3,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x3,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x4,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x4,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x4,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x4,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x5,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x5,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x5,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x5,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x6,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x6,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x6,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x6,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x7,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x7,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x7,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x7,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x8,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x8,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x8,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x8,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x9,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x9,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x9,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x9,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xa,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xa,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xa,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xa,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xb,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xb,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xb,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xb,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xc,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xc,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xc,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xc,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xd,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xd,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xd,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xd,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xe,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xe,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xe,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xe,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xf,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xf,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xf,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xf,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x10,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x10,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x10,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x10,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x11,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x11,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x11,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x11,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x12,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x12,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x12,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x12,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x13,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x13,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x13,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x13,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x14,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x14,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x14,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x14,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x15,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x15,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x15,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x15,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x16,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x16,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x16,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x16,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x17,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x17,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x17,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x17,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x18,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x18,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x18,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x18,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x19,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x19,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x19,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x19,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1a,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1a,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1a,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1a,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1b,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1b,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1b,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1b,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1c,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1c,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1c,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1c,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1d,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1d,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1d,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1d,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1e,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1e,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1e,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1e,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1f,
+0x0,
+0x0,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1f,
+0x0,
+0x1,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1f,
+0x0,
+0xa,
+0x2,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1f,
+0x0,
+0xa,
+0x3,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x0,
+0x8,
+0x50,
+0x52,
+0x54,
+0x41,
+0x12,
+0x4b,
+0x73,
+0x80,
+0x12,
+0xb,
+0x4,
+0xb,
+0xff,
+0xff,
+0x0,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xb,
+0x4,
+0xb,
+0xff,
+0xff,
+0x1,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xc,
+0x4,
+0xb,
+0xff,
+0xff,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xc,
+0x4,
+0xb,
+0xff,
+0xff,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x2,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x2,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x2,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x2,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x3,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x3,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x3,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x3,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x4,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x4,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x4,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x4,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x5,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x5,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x5,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x5,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x6,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x6,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x6,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x6,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x7,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x7,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x7,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x7,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x8,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x8,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x8,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x8,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x9,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x9,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x9,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x9,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xa,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xa,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xa,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xa,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xb,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xb,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xb,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xb,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xc,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xc,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xc,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xc,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xd,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xd,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xd,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xd,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xe,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xe,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xe,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xe,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xf,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0xf,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xf,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0xf,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x10,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x10,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x10,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x10,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x11,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x11,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x11,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x11,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x12,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x12,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x12,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x12,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x13,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x13,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x13,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x13,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x14,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x14,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x14,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x14,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x15,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x15,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x15,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x15,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x16,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x16,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x16,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x16,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x17,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x17,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x17,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x17,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x18,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x18,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x18,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x18,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x19,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x19,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x19,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x19,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1a,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1a,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1a,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1a,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1b,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1b,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1b,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1b,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1c,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1c,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1c,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1c,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1d,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1d,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1d,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1d,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x44,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1e,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x45,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1e,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x46,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1e,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x47,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1e,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x48,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1f,
+0x0,
+0x0,
+0x47,
+0x53,
+0x49,
+0x41,
+0x0,
+0x12,
+0xd,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1f,
+0x0,
+0x1,
+0x47,
+0x53,
+0x49,
+0x42,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1f,
+0x0,
+0xa,
+0x2,
+0x47,
+0x53,
+0x49,
+0x43,
+0x0,
+0x12,
+0xe,
+0x4,
+0xc,
+0xff,
+0xff,
+0x1f,
+0x0,
+0xa,
+0x3,
+0x47,
+0x53,
+0x49,
+0x44,
+0x0,
+0x14,
+0x1a,
+0x5f,
+0x50,
+0x52,
+0x54,
+0x0,
+0xa0,
+0xc,
+0x93,
+0x50,
+0x49,
+0x43,
+0x46,
+0x0,
+0xa4,
+0x50,
+0x52,
+0x54,
+0x50,
+0xa1,
+0x6,
+0xa4,
+0x50,
+0x52,
+0x54,
+0x41,
+0x5b,
+0x81,
+0x3a,
+0x2f,
+0x3,
+0x50,
+0x43,
+0x49,
+0x30,
+0x49,
+0x53,
+0x41,
+0x5f,
+0x50,
+0x49,
+0x52,
+0x51,
+0x1,
+0x50,
+0x52,
+0x51,
+0x41,
+0x8,
+0x50,
+0x52,
+0x51,
+0x42,
+0x8,
+0x50,
+0x52,
+0x51,
+0x43,
+0x8,
+0x50,
+0x52,
+0x51,
+0x44,
+0x8,
+0x0,
+0x20,
+0x50,
+0x52,
+0x51,
+0x45,
+0x8,
+0x50,
+0x52,
+0x51,
+0x46,
+0x8,
+0x50,
+0x52,
+0x51,
+0x47,
+0x8,
+0x50,
+0x52,
+0x51,
+0x48,
+0x8,
+0x14,
+0x13,
+0x49,
+0x51,
+0x53,
+0x54,
+0x1,
+0xa0,
+0x9,
+0x7b,
+0xa,
+0x80,
+0x68,
+0x0,
+0xa4,
+0xa,
+0x9,
+0xa4,
+0xa,
+0xb,
+0x14,
+0x34,
+0x49,
+0x51,
+0x43,
+0x52,
+0x1,
+0x8,
+0x50,
+0x52,
+0x52,
+0x30,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x0,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x8a,
+0x50,
+0x52,
+0x52,
+0x30,
+0xa,
+0x5,
+0x50,
+0x52,
+0x52,
+0x49,
+0x70,
+0x7b,
+0x68,
+0xa,
+0xf,
+0x0,
+0x50,
+0x52,
+0x52,
+0x49,
+0xa4,
+0x50,
+0x52,
+0x52,
+0x30,
+0x5b,
+0x82,
+0x4c,
+0x7,
+0x4c,
+0x4e,
+0x4b,
+0x41,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x0,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0x16,
+0xa,
+0x13,
+0x89,
+0xe,
+0x0,
+0x9,
+0x3,
+0x5,
+0x0,
+0x0,
+0x0,
+0xa,
+0x0,
+0x0,
+0x0,
+0xb,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0xf,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x53,
+0x54,
+0x50,
+0x52,
+0x51,
+0x41,
+0x14,
+0x11,
+0x5f,
+0x44,
+0x49,
+0x53,
+0x0,
+0x7d,
+0x50,
+0x52,
+0x51,
+0x41,
+0xa,
+0x80,
+0x50,
+0x52,
+0x51,
+0x41,
+0x14,
+0xf,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x43,
+0x52,
+0x50,
+0x52,
+0x51,
+0x41,
+0x14,
+0x17,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x8a,
+0x68,
+0xa,
+0x5,
+0x50,
+0x52,
+0x52,
+0x49,
+0x70,
+0x50,
+0x52,
+0x52,
+0x49,
+0x50,
+0x52,
+0x51,
+0x41,
+0x5b,
+0x82,
+0x4c,
+0x7,
+0x4c,
+0x4e,
+0x4b,
+0x42,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x1,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0x16,
+0xa,
+0x13,
+0x89,
+0xe,
+0x0,
+0x9,
+0x3,
+0x5,
+0x0,
+0x0,
+0x0,
+0xa,
+0x0,
+0x0,
+0x0,
+0xb,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0xf,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x53,
+0x54,
+0x50,
+0x52,
+0x51,
+0x42,
+0x14,
+0x11,
+0x5f,
+0x44,
+0x49,
+0x53,
+0x0,
+0x7d,
+0x50,
+0x52,
+0x51,
+0x42,
+0xa,
+0x80,
+0x50,
+0x52,
+0x51,
+0x42,
+0x14,
+0xf,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x43,
+0x52,
+0x50,
+0x52,
+0x51,
+0x42,
+0x14,
+0x17,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x8a,
+0x68,
+0xa,
+0x5,
+0x50,
+0x52,
+0x52,
+0x49,
+0x70,
+0x50,
+0x52,
+0x52,
+0x49,
+0x50,
+0x52,
+0x51,
+0x42,
+0x5b,
+0x82,
+0x4d,
+0x7,
+0x4c,
+0x4e,
+0x4b,
+0x43,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0xa,
+0x2,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0x16,
+0xa,
+0x13,
+0x89,
+0xe,
+0x0,
+0x9,
+0x3,
+0x5,
+0x0,
+0x0,
+0x0,
+0xa,
+0x0,
+0x0,
+0x0,
+0xb,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0xf,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x53,
+0x54,
+0x50,
+0x52,
+0x51,
+0x43,
+0x14,
+0x11,
+0x5f,
+0x44,
+0x49,
+0x53,
+0x0,
+0x7d,
+0x50,
+0x52,
+0x51,
+0x43,
+0xa,
+0x80,
+0x50,
+0x52,
+0x51,
+0x43,
+0x14,
+0xf,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x43,
+0x52,
+0x50,
+0x52,
+0x51,
+0x43,
+0x14,
+0x17,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x8a,
+0x68,
+0xa,
+0x5,
+0x50,
+0x52,
+0x52,
+0x49,
+0x70,
+0x50,
+0x52,
+0x52,
+0x49,
+0x50,
+0x52,
+0x51,
+0x43,
+0x5b,
+0x82,
+0x4d,
+0x7,
+0x4c,
+0x4e,
+0x4b,
+0x44,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0xa,
+0x3,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0x16,
+0xa,
+0x13,
+0x89,
+0xe,
+0x0,
+0x9,
+0x3,
+0x5,
+0x0,
+0x0,
+0x0,
+0xa,
+0x0,
+0x0,
+0x0,
+0xb,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0xf,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x53,
+0x54,
+0x50,
+0x52,
+0x51,
+0x44,
+0x14,
+0x11,
+0x5f,
+0x44,
+0x49,
+0x53,
+0x0,
+0x7d,
+0x50,
+0x52,
+0x51,
+0x44,
+0xa,
+0x80,
+0x50,
+0x52,
+0x51,
+0x44,
+0x14,
+0xf,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x43,
+0x52,
+0x50,
+0x52,
+0x51,
+0x44,
+0x14,
+0x17,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x8a,
+0x68,
+0xa,
+0x5,
+0x50,
+0x52,
+0x52,
+0x49,
+0x70,
+0x50,
+0x52,
+0x52,
+0x49,
+0x50,
+0x52,
+0x51,
+0x44,
+0x5b,
+0x82,
+0x4d,
+0x7,
+0x4c,
+0x4e,
+0x4b,
+0x45,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0xa,
+0x4,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0x16,
+0xa,
+0x13,
+0x89,
+0xe,
+0x0,
+0x9,
+0x3,
+0x5,
+0x0,
+0x0,
+0x0,
+0xa,
+0x0,
+0x0,
+0x0,
+0xb,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0xf,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x53,
+0x54,
+0x50,
+0x52,
+0x51,
+0x45,
+0x14,
+0x11,
+0x5f,
+0x44,
+0x49,
+0x53,
+0x0,
+0x7d,
+0x50,
+0x52,
+0x51,
+0x45,
+0xa,
+0x80,
+0x50,
+0x52,
+0x51,
+0x45,
+0x14,
+0xf,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x43,
+0x52,
+0x50,
+0x52,
+0x51,
+0x45,
+0x14,
+0x17,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x8a,
+0x68,
+0xa,
+0x5,
+0x50,
+0x52,
+0x52,
+0x49,
+0x70,
+0x50,
+0x52,
+0x52,
+0x49,
+0x50,
+0x52,
+0x51,
+0x45,
+0x5b,
+0x82,
+0x4d,
+0x7,
+0x4c,
+0x4e,
+0x4b,
+0x46,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0xa,
+0x5,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0x16,
+0xa,
+0x13,
+0x89,
+0xe,
+0x0,
+0x9,
+0x3,
+0x5,
+0x0,
+0x0,
+0x0,
+0xa,
+0x0,
+0x0,
+0x0,
+0xb,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0xf,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x53,
+0x54,
+0x50,
+0x52,
+0x51,
+0x46,
+0x14,
+0x11,
+0x5f,
+0x44,
+0x49,
+0x53,
+0x0,
+0x7d,
+0x50,
+0x52,
+0x51,
+0x46,
+0xa,
+0x80,
+0x50,
+0x52,
+0x51,
+0x46,
+0x14,
+0xf,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x43,
+0x52,
+0x50,
+0x52,
+0x51,
+0x46,
+0x14,
+0x17,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x8a,
+0x68,
+0xa,
+0x5,
+0x50,
+0x52,
+0x52,
+0x49,
+0x70,
+0x50,
+0x52,
+0x52,
+0x49,
+0x50,
+0x52,
+0x51,
+0x46,
+0x5b,
+0x82,
+0x4d,
+0x7,
+0x4c,
+0x4e,
+0x4b,
+0x47,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0xa,
+0x6,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0x16,
+0xa,
+0x13,
+0x89,
+0xe,
+0x0,
+0x9,
+0x3,
+0x5,
+0x0,
+0x0,
+0x0,
+0xa,
+0x0,
+0x0,
+0x0,
+0xb,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0xf,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x53,
+0x54,
+0x50,
+0x52,
+0x51,
+0x47,
+0x14,
+0x11,
+0x5f,
+0x44,
+0x49,
+0x53,
+0x0,
+0x7d,
+0x50,
+0x52,
+0x51,
+0x47,
+0xa,
+0x80,
+0x50,
+0x52,
+0x51,
+0x47,
+0x14,
+0xf,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x43,
+0x52,
+0x50,
+0x52,
+0x51,
+0x47,
+0x14,
+0x17,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x8a,
+0x68,
+0xa,
+0x5,
+0x50,
+0x52,
+0x52,
+0x49,
+0x70,
+0x50,
+0x52,
+0x52,
+0x49,
+0x50,
+0x52,
+0x51,
+0x47,
+0x5b,
+0x82,
+0x4d,
+0x7,
+0x4c,
+0x4e,
+0x4b,
+0x48,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0xa,
+0x7,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0x16,
+0xa,
+0x13,
+0x89,
+0xe,
+0x0,
+0x9,
+0x3,
+0x5,
+0x0,
+0x0,
+0x0,
+0xa,
+0x0,
+0x0,
+0x0,
+0xb,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0xf,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x53,
+0x54,
+0x50,
+0x52,
+0x51,
+0x48,
+0x14,
+0x11,
+0x5f,
+0x44,
+0x49,
+0x53,
+0x0,
+0x7d,
+0x50,
+0x52,
+0x51,
+0x48,
+0xa,
+0x80,
+0x50,
+0x52,
+0x51,
+0x48,
+0x14,
+0xf,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x0,
+0xa4,
+0x49,
+0x51,
+0x43,
+0x52,
+0x50,
+0x52,
+0x51,
+0x48,
+0x14,
+0x17,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x8a,
+0x68,
+0xa,
+0x5,
+0x50,
+0x52,
+0x52,
+0x49,
+0x70,
+0x50,
+0x52,
+0x52,
+0x49,
+0x50,
+0x52,
+0x51,
+0x48,
+0x5b,
+0x82,
+0x45,
+0x4,
+0x47,
+0x53,
+0x49,
+0x41,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x0,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x10,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x10,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x5b,
+0x82,
+0x45,
+0x4,
+0x47,
+0x53,
+0x49,
+0x42,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x0,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x11,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x11,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x5b,
+0x82,
+0x45,
+0x4,
+0x47,
+0x53,
+0x49,
+0x43,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x0,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x12,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x12,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x5b,
+0x82,
+0x45,
+0x4,
+0x47,
+0x53,
+0x49,
+0x44,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x0,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x13,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x13,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x5b,
+0x82,
+0x45,
+0x4,
+0x47,
+0x53,
+0x49,
+0x45,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x0,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x14,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x14,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x5b,
+0x82,
+0x45,
+0x4,
+0x47,
+0x53,
+0x49,
+0x46,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x0,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x15,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x15,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x5b,
+0x82,
+0x45,
+0x4,
+0x47,
+0x53,
+0x49,
+0x47,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x0,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x16,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x16,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x5b,
+0x82,
+0x45,
+0x4,
+0x47,
+0x53,
+0x49,
+0x48,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0xf,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x0,
+0x8,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x17,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0xe,
+0xa,
+0xb,
+0x89,
+0x6,
+0x0,
+0x9,
+0x1,
+0x17,
+0x0,
+0x0,
+0x0,
+0x79,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x53,
+0x52,
+0x53,
+0x1,
+0x10,
+0x47,
+0xe,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x14,
+0x35,
+0x43,
+0x50,
+0x4d,
+0x41,
+0x1,
+0x70,
+0x83,
+0x88,
+0x43,
+0x50,
+0x4f,
+0x4e,
+0x68,
+0x0,
+0x60,
+0x70,
+0x11,
+0xb,
+0xa,
+0x8,
+0x0,
+0x8,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x61,
+0x70,
+0x68,
+0x88,
+0x61,
+0xa,
+0x2,
+0x0,
+0x70,
+0x68,
+0x88,
+0x61,
+0xa,
+0x3,
+0x0,
+0x70,
+0x60,
+0x88,
+0x61,
+0xa,
+0x4,
+0x0,
+0xa4,
+0x61,
+0x14,
+0x1a,
+0x43,
+0x50,
+0x53,
+0x54,
+0x1,
+0x70,
+0x83,
+0x88,
+0x43,
+0x50,
+0x4f,
+0x4e,
+0x68,
+0x0,
+0x60,
+0xa0,
+0x5,
+0x60,
+0xa4,
+0xa,
+0xf,
+0xa1,
+0x3,
+0xa4,
+0x0,
+0x14,
+0xa,
+0x43,
+0x50,
+0x45,
+0x4a,
+0x2,
+0x5b,
+0x22,
+0xa,
+0xc8,
+0x5b,
+0x80,
+0x50,
+0x52,
+0x53,
+0x54,
+0x1,
+0xb,
+0x0,
+0xaf,
+0xa,
+0x20,
+0x5b,
+0x81,
+0xc,
+0x50,
+0x52,
+0x53,
+0x54,
+0x1,
+0x50,
+0x52,
+0x53,
+0x5f,
+0x40,
+0x10,
+0x14,
+0x4a,
+0x6,
+0x50,
+0x52,
+0x53,
+0x43,
+0x0,
+0x70,
+0x50,
+0x52,
+0x53,
+0x5f,
+0x65,
+0x70,
+0x0,
+0x62,
+0x70,
+0x0,
+0x60,
+0xa2,
+0x46,
+0x5,
+0x95,
+0x60,
+0x87,
+0x43,
+0x50,
+0x4f,
+0x4e,
+0x70,
+0x83,
+0x88,
+0x43,
+0x50,
+0x4f,
+0x4e,
+0x60,
+0x0,
+0x61,
+0xa0,
+0xa,
+0x7b,
+0x60,
+0xa,
+0x7,
+0x0,
+0x7a,
+0x62,
+0x1,
+0x62,
+0xa1,
+0xc,
+0x70,
+0x83,
+0x88,
+0x65,
+0x7a,
+0x60,
+0xa,
+0x3,
+0x0,
+0x0,
+0x62,
+0x70,
+0x7b,
+0x62,
+0x1,
+0x0,
+0x63,
+0xa0,
+0x22,
+0x92,
+0x93,
+0x61,
+0x63,
+0x70,
+0x63,
+0x88,
+0x43,
+0x50,
+0x4f,
+0x4e,
+0x60,
+0x0,
+0xa0,
+0xa,
+0x93,
+0x63,
+0x1,
+0x4e,
+0x54,
+0x46,
+0x59,
+0x60,
+0x1,
+0xa1,
+0x8,
+0x4e,
+0x54,
+0x46,
+0x59,
+0x60,
+0xa,
+0x3,
+0x75,
+0x60,
+0x10,
+0x4f,
+0x8,
+0x5f,
+0x47,
+0x50,
+0x45,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xd,
+0x41,
+0x43,
+0x50,
+0x49,
+0x30,
+0x30,
+0x30,
+0x36,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x30,
+0x0,
+0x14,
+0x10,
+0x5f,
+0x4c,
+0x30,
+0x31,
+0x0,
+0x5c,
+0x2e,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x50,
+0x52,
+0x53,
+0x43,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x32,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x33,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x34,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x35,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x36,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x37,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x38,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x39,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x41,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x42,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x43,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x44,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x45,
+0x0,
+0x14,
+0x6,
+0x5f,
+0x4c,
+0x30,
+0x46,
+0x0
+};
diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl
new file mode 100644 (file)
index 0000000..a4484b8
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+ACPI_EXTRACT_ALL_CODE ssdp_misc_aml
+
+DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
+{
+
+/****************************************************************
+ * PCI memory ranges
+ ****************************************************************/
+
+    Scope(\) {
+       ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_start
+       Name(P0S, 0x12345678)
+       ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_end
+       Name(P0E, 0x12345678)
+       ACPI_EXTRACT_NAME_BYTE_CONST acpi_pci64_valid
+       Name(P1V, 0x12)
+       ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_start
+       Name(P1S, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
+       ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_end
+       Name(P1E, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
+       ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_length
+       Name(P1L, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
+    }
+
+
+/****************************************************************
+ * Suspend
+ ****************************************************************/
+
+    Scope(\) {
+    /*
+     * S3 (suspend-to-ram), S4 (suspend-to-disk) and S5 (power-off) type codes:
+     * must match piix4 emulation.
+     */
+
+        ACPI_EXTRACT_NAME_STRING acpi_s3_name
+        Name(_S3, Package(0x04) {
+            One,  /* PM1a_CNT.SLP_TYP */
+            One,  /* PM1b_CNT.SLP_TYP */
+            Zero,  /* reserved */
+            Zero   /* reserved */
+        })
+        ACPI_EXTRACT_NAME_STRING acpi_s4_name
+        ACPI_EXTRACT_PKG_START acpi_s4_pkg
+        Name(_S4, Package(0x04) {
+            0x2,  /* PM1a_CNT.SLP_TYP */
+            0x2,  /* PM1b_CNT.SLP_TYP */
+            Zero,  /* reserved */
+            Zero   /* reserved */
+        })
+        Name(_S5, Package(0x04) {
+            Zero,  /* PM1a_CNT.SLP_TYP */
+            Zero,  /* PM1b_CNT.SLP_TYP */
+            Zero,  /* reserved */
+            Zero   /* reserved */
+        })
+    }
+
+    External(\_SB.PCI0, DeviceObj)
+    External(\_SB.PCI0.ISA, DeviceObj)
+
+    Scope(\_SB.PCI0.ISA) {
+        Device(PEVT) {
+            Name(_HID, "QEMU0001")
+            /* PEST will be patched to be Zero if no such device */
+            ACPI_EXTRACT_NAME_WORD_CONST ssdt_isa_pest
+            Name(PEST, 0xFFFF)
+            OperationRegion(PEOR, SystemIO, PEST, 0x01)
+            Field(PEOR, ByteAcc, NoLock, Preserve) {
+                PEPT,   8,
+            }
+
+            Method(_STA, 0, NotSerialized) {
+                Store(PEST, Local0)
+                If (LEqual(Local0, Zero)) {
+                    Return (0x00)
+                } Else {
+                    Return (0x0F)
+                }
+            }
+
+            Method(RDPT, 0, NotSerialized) {
+                Store(PEPT, Local0)
+                Return (Local0)
+            }
+
+            Method(WRPT, 1, NotSerialized) {
+                Store(Arg0, PEPT)
+            }
+
+            Name(_CRS, ResourceTemplate() {
+                IO(Decode16, 0x00, 0x00, 0x01, 0x01, IO)
+            })
+
+            CreateWordField(_CRS, IO._MIN, IOMN)
+            CreateWordField(_CRS, IO._MAX, IOMX)
+
+            Method(_INI, 0, NotSerialized) {
+                Store(PEST, IOMN)
+                Store(PEST, IOMX)
+            }
+        }
+    }
+}
diff --git a/hw/i386/ssdt-misc.hex.generated b/hw/i386/ssdt-misc.hex.generated
new file mode 100644 (file)
index 0000000..55e3bd2
--- /dev/null
@@ -0,0 +1,386 @@
+static unsigned char acpi_pci64_length[] = {
+0x6f
+};
+static unsigned char acpi_s4_pkg[] = {
+0x8f
+};
+static unsigned char acpi_s3_name[] = {
+0x7c
+};
+static unsigned char acpi_pci32_start[] = {
+0x2f
+};
+static unsigned char acpi_pci64_valid[] = {
+0x43
+};
+static unsigned char ssdp_misc_aml[] = {
+0x53,
+0x53,
+0x44,
+0x54,
+0x62,
+0x1,
+0x0,
+0x0,
+0x1,
+0x76,
+0x42,
+0x58,
+0x50,
+0x43,
+0x0,
+0x0,
+0x42,
+0x58,
+0x53,
+0x53,
+0x44,
+0x54,
+0x53,
+0x55,
+0x1,
+0x0,
+0x0,
+0x0,
+0x49,
+0x4e,
+0x54,
+0x4c,
+0x23,
+0x8,
+0x13,
+0x20,
+0x10,
+0x42,
+0x5,
+0x5c,
+0x0,
+0x8,
+0x50,
+0x30,
+0x53,
+0x5f,
+0xc,
+0x78,
+0x56,
+0x34,
+0x12,
+0x8,
+0x50,
+0x30,
+0x45,
+0x5f,
+0xc,
+0x78,
+0x56,
+0x34,
+0x12,
+0x8,
+0x50,
+0x31,
+0x56,
+0x5f,
+0xa,
+0x12,
+0x8,
+0x50,
+0x31,
+0x53,
+0x5f,
+0x11,
+0xb,
+0xa,
+0x8,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x8,
+0x50,
+0x31,
+0x45,
+0x5f,
+0x11,
+0xb,
+0xa,
+0x8,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x8,
+0x50,
+0x31,
+0x4c,
+0x5f,
+0x11,
+0xb,
+0xa,
+0x8,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x10,
+0x29,
+0x5c,
+0x0,
+0x8,
+0x5f,
+0x53,
+0x33,
+0x5f,
+0x12,
+0x6,
+0x4,
+0x1,
+0x1,
+0x0,
+0x0,
+0x8,
+0x5f,
+0x53,
+0x34,
+0x5f,
+0x12,
+0x8,
+0x4,
+0xa,
+0x2,
+0xa,
+0x2,
+0x0,
+0x0,
+0x8,
+0x5f,
+0x53,
+0x35,
+0x5f,
+0x12,
+0x6,
+0x4,
+0x0,
+0x0,
+0x0,
+0x0,
+0x10,
+0x40,
+0xc,
+0x5c,
+0x2f,
+0x3,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x50,
+0x43,
+0x49,
+0x30,
+0x49,
+0x53,
+0x41,
+0x5f,
+0x5b,
+0x82,
+0x4d,
+0xa,
+0x50,
+0x45,
+0x56,
+0x54,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xd,
+0x51,
+0x45,
+0x4d,
+0x55,
+0x30,
+0x30,
+0x30,
+0x31,
+0x0,
+0x8,
+0x50,
+0x45,
+0x53,
+0x54,
+0xb,
+0xff,
+0xff,
+0x5b,
+0x80,
+0x50,
+0x45,
+0x4f,
+0x52,
+0x1,
+0x50,
+0x45,
+0x53,
+0x54,
+0x1,
+0x5b,
+0x81,
+0xb,
+0x50,
+0x45,
+0x4f,
+0x52,
+0x1,
+0x50,
+0x45,
+0x50,
+0x54,
+0x8,
+0x14,
+0x18,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0x70,
+0x50,
+0x45,
+0x53,
+0x54,
+0x60,
+0xa0,
+0x6,
+0x93,
+0x60,
+0x0,
+0xa4,
+0x0,
+0xa1,
+0x4,
+0xa4,
+0xa,
+0xf,
+0x14,
+0xe,
+0x52,
+0x44,
+0x50,
+0x54,
+0x0,
+0x70,
+0x50,
+0x45,
+0x50,
+0x54,
+0x60,
+0xa4,
+0x60,
+0x14,
+0xc,
+0x57,
+0x52,
+0x50,
+0x54,
+0x1,
+0x70,
+0x68,
+0x50,
+0x45,
+0x50,
+0x54,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0xd,
+0xa,
+0xa,
+0x47,
+0x1,
+0x0,
+0x0,
+0x0,
+0x0,
+0x1,
+0x1,
+0x79,
+0x0,
+0x8b,
+0x5f,
+0x43,
+0x52,
+0x53,
+0xa,
+0x2,
+0x49,
+0x4f,
+0x4d,
+0x4e,
+0x8b,
+0x5f,
+0x43,
+0x52,
+0x53,
+0xa,
+0x4,
+0x49,
+0x4f,
+0x4d,
+0x58,
+0x14,
+0x18,
+0x5f,
+0x49,
+0x4e,
+0x49,
+0x0,
+0x70,
+0x50,
+0x45,
+0x53,
+0x54,
+0x49,
+0x4f,
+0x4d,
+0x4e,
+0x70,
+0x50,
+0x45,
+0x53,
+0x54,
+0x49,
+0x4f,
+0x4d,
+0x58
+};
+static unsigned char ssdt_isa_pest[] = {
+0xd0
+};
+static unsigned char acpi_s4_name[] = {
+0x88
+};
+static unsigned char acpi_pci64_start[] = {
+0x4d
+};
+static unsigned char acpi_pci64_end[] = {
+0x5e
+};
+static unsigned char acpi_pci32_end[] = {
+0x39
+};
diff --git a/hw/i386/ssdt-pcihp.dsl b/hw/i386/ssdt-pcihp.dsl
new file mode 100644 (file)
index 0000000..d29a5b9
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+ACPI_EXTRACT_ALL_CODE ssdp_pcihp_aml
+
+DefinitionBlock ("ssdt-pcihp.aml", "SSDT", 0x01, "BXPC", "BXSSDTPCIHP", 0x1)
+{
+
+/****************************************************************
+ * PCI hotplug
+ ****************************************************************/
+
+    /* Objects supplied by DSDT */
+    External(\_SB.PCI0, DeviceObj)
+    External(\_SB.PCI0.PCEJ, MethodObj)
+
+    Scope(\_SB.PCI0) {
+
+        /* Bulk generated PCI hotplug devices */
+        ACPI_EXTRACT_DEVICE_START ssdt_pcihp_start
+        ACPI_EXTRACT_DEVICE_END ssdt_pcihp_end
+        ACPI_EXTRACT_DEVICE_STRING ssdt_pcihp_name
+
+        // Method _EJ0 can be patched by BIOS to EJ0_
+        // at runtime, if the slot is detected to not support hotplug.
+        // Extract the offset of the address dword and the
+        // _EJ0 name to allow this patching.
+        Device(SAA) {
+            ACPI_EXTRACT_NAME_BYTE_CONST ssdt_pcihp_id
+            Name(_SUN, 0xAA)
+            ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pcihp_adr
+            Name(_ADR, 0xAA0000)
+            ACPI_EXTRACT_METHOD_STRING ssdt_pcihp_ej0
+            Method(_EJ0, 1) {
+                Return (PCEJ(_SUN))
+            }
+        }
+    }
+}
diff --git a/hw/i386/ssdt-pcihp.hex.generated b/hw/i386/ssdt-pcihp.hex.generated
new file mode 100644 (file)
index 0000000..b3c2cd5
--- /dev/null
@@ -0,0 +1,108 @@
+static unsigned char ssdt_pcihp_name[] = {
+0x33
+};
+static unsigned char ssdt_pcihp_adr[] = {
+0x44
+};
+static unsigned char ssdt_pcihp_end[] = {
+0x58
+};
+static unsigned char ssdp_pcihp_aml[] = {
+0x53,
+0x53,
+0x44,
+0x54,
+0x58,
+0x0,
+0x0,
+0x0,
+0x1,
+0x76,
+0x42,
+0x58,
+0x50,
+0x43,
+0x0,
+0x0,
+0x42,
+0x58,
+0x53,
+0x53,
+0x44,
+0x54,
+0x50,
+0x43,
+0x1,
+0x0,
+0x0,
+0x0,
+0x49,
+0x4e,
+0x54,
+0x4c,
+0x23,
+0x8,
+0x13,
+0x20,
+0x10,
+0x33,
+0x5c,
+0x2e,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x50,
+0x43,
+0x49,
+0x30,
+0x5b,
+0x82,
+0x26,
+0x53,
+0x41,
+0x41,
+0x5f,
+0x8,
+0x5f,
+0x53,
+0x55,
+0x4e,
+0xa,
+0xaa,
+0x8,
+0x5f,
+0x41,
+0x44,
+0x52,
+0xc,
+0x0,
+0x0,
+0xaa,
+0x0,
+0x14,
+0xf,
+0x5f,
+0x45,
+0x4a,
+0x30,
+0x1,
+0xa4,
+0x50,
+0x43,
+0x45,
+0x4a,
+0x5f,
+0x53,
+0x55,
+0x4e
+};
+static unsigned char ssdt_pcihp_start[] = {
+0x30
+};
+static unsigned char ssdt_pcihp_id[] = {
+0x3d
+};
+static unsigned char ssdt_pcihp_ej0[] = {
+0x4a
+};
diff --git a/hw/i386/ssdt-proc.dsl b/hw/i386/ssdt-proc.dsl
new file mode 100644 (file)
index 0000000..8229bfd
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This file is the basis for the ssdt table generated in src/acpi.c.
+ * It defines the contents of the per-cpu Processor() object.  At
+ * runtime, a dynamically generated SSDT will contain one copy of this
+ * AML snippet for every possible cpu in the system.  The objects will
+ * be placed in the \_SB_ namespace.
+ *
+ * In addition to the aml code generated from this file, the
+ * src/acpi.c file creates a NTFY method with an entry for each cpu:
+ *     Method(NTFY, 2) {
+ *         If (LEqual(Arg0, 0x00)) { Notify(CP00, Arg1) }
+ *         If (LEqual(Arg0, 0x01)) { Notify(CP01, Arg1) }
+ *         ...
+ *     }
+ * and a CPON array with the list of active and inactive cpus:
+ *     Name(CPON, Package() { One, One, ..., Zero, Zero, ... })
+ */
+
+ACPI_EXTRACT_ALL_CODE ssdp_proc_aml
+
+DefinitionBlock ("ssdt-proc.aml", "SSDT", 0x01, "BXPC", "BXSSDT", 0x1)
+{
+    ACPI_EXTRACT_PROCESSOR_START ssdt_proc_start
+    ACPI_EXTRACT_PROCESSOR_END ssdt_proc_end
+    ACPI_EXTRACT_PROCESSOR_STRING ssdt_proc_name
+    Processor(CPAA, 0xAA, 0x00000000, 0x0) {
+        ACPI_EXTRACT_NAME_BYTE_CONST ssdt_proc_id
+        Name(ID, 0xAA)
+/*
+ * The src/acpi.c code requires the above ACP_EXTRACT tags so that it can update
+ * CPAA and 0xAA with the appropriate CPU id (see
+ * SD_OFFSET_CPUHEX/CPUID1/CPUID2).  Don't change the above without
+ * also updating the C code.
+ */
+        Name(_HID, "ACPI0007")
+        External(CPMA, MethodObj)
+        External(CPST, MethodObj)
+        External(CPEJ, MethodObj)
+        Method(_MAT, 0) {
+            Return (CPMA(ID))
+        }
+        Method(_STA, 0) {
+            Return (CPST(ID))
+        }
+        Method(_EJ0, 1, NotSerialized) {
+            CPEJ(ID, Arg0)
+        }
+    }
+}
diff --git a/hw/i386/ssdt-proc.hex.generated b/hw/i386/ssdt-proc.hex.generated
new file mode 100644 (file)
index 0000000..bb9920d
--- /dev/null
@@ -0,0 +1,134 @@
+static unsigned char ssdt_proc_name[] = {
+0x28
+};
+static unsigned char ssdp_proc_aml[] = {
+0x53,
+0x53,
+0x44,
+0x54,
+0x78,
+0x0,
+0x0,
+0x0,
+0x1,
+0xb8,
+0x42,
+0x58,
+0x50,
+0x43,
+0x0,
+0x0,
+0x42,
+0x58,
+0x53,
+0x53,
+0x44,
+0x54,
+0x0,
+0x0,
+0x1,
+0x0,
+0x0,
+0x0,
+0x49,
+0x4e,
+0x54,
+0x4c,
+0x23,
+0x8,
+0x13,
+0x20,
+0x5b,
+0x83,
+0x42,
+0x5,
+0x43,
+0x50,
+0x41,
+0x41,
+0xaa,
+0x10,
+0xb0,
+0x0,
+0x0,
+0x0,
+0x8,
+0x49,
+0x44,
+0x5f,
+0x5f,
+0xa,
+0xaa,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xd,
+0x41,
+0x43,
+0x50,
+0x49,
+0x30,
+0x30,
+0x30,
+0x37,
+0x0,
+0x14,
+0xf,
+0x5f,
+0x4d,
+0x41,
+0x54,
+0x0,
+0xa4,
+0x43,
+0x50,
+0x4d,
+0x41,
+0x49,
+0x44,
+0x5f,
+0x5f,
+0x14,
+0xf,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0x43,
+0x50,
+0x53,
+0x54,
+0x49,
+0x44,
+0x5f,
+0x5f,
+0x14,
+0xf,
+0x5f,
+0x45,
+0x4a,
+0x30,
+0x1,
+0x43,
+0x50,
+0x45,
+0x4a,
+0x49,
+0x44,
+0x5f,
+0x5f,
+0x68
+};
+static unsigned char ssdt_proc_id[] = {
+0x38
+};
+static unsigned char ssdt_proc_end[] = {
+0x78
+};
+static unsigned char ssdt_proc_start[] = {
+0x24
+};
index 0500a7a1b68fc46e4d487b226b9b849a95105054..a8e35fe38f3b200ef17c363dfe9bc3d3a1ce7b07 100644 (file)
@@ -230,7 +230,7 @@ static void cmd646_update_irq(PCIIDEState *d)
                  !(pd->config[MRDMODE] & MRDMODE_BLK_CH0)) ||
         ((pd->config[MRDMODE] & MRDMODE_INTR_CH1) &&
          !(pd->config[MRDMODE] & MRDMODE_BLK_CH1));
-    qemu_set_irq(pd->irq[0], pci_level);
+    pci_set_irq(pd, pci_level);
 }
 
 /* the PCI irq level is the logical OR of the two channels */
index bff952bf6a90fc8c5f6bd0cef2c488e547311a47..1c7c05810dbd41f2bc7c8355d79878ebdd48d390 100644 (file)
@@ -116,7 +116,7 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
     dev->config[0x90]   = 1 << 6; /* Address Map Register - AHCI mode */
 
     msi_init(dev, 0x50, 1, true, false);
-    d->ahci.irq = dev->irq[0];
+    d->ahci.irq = pci_allocate_irq(dev);
 
     pci_register_bar(dev, ICH9_IDP_BAR, PCI_BASE_ADDRESS_SPACE_IO,
                      &d->ahci.idp);
@@ -145,6 +145,7 @@ static void pci_ich9_uninit(PCIDevice *dev)
 
     msi_uninit(dev);
     ahci_uninit(&d->ahci);
+    qemu_free_irq(d->ahci.irq);
 }
 
 static void ich_ahci_class_init(ObjectClass *klass, void *data)
index 5633d08b62fc62c9555fa989fca767b98601f6f7..19b2198fa681eca6ec814ce09384fc8bd859ecda 100644 (file)
@@ -29,6 +29,7 @@
  */
 #include "qemu-common.h"
 #include "hw/hw.h"
+#include "qapi/visitor.h"
 #include "qemu/range.h"
 #include "hw/isa/isa.h"
 #include "hw/sysbus.h"
@@ -525,6 +526,43 @@ static const MemoryRegionOps ich9_rst_cnt_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN
 };
 
+Object *ich9_lpc_find(void)
+{
+    bool ambig;
+    Object *o = object_resolve_path_type("", TYPE_ICH9_LPC_DEVICE, &ambig);
+
+    if (ambig) {
+        return NULL;
+    }
+    return o;
+}
+
+static void ich9_lpc_get_sci_int(Object *obj, Visitor *v,
+                                 void *opaque, const char *name,
+                                 Error **errp)
+{
+    ICH9LPCState *lpc = ICH9_LPC_DEVICE(obj);
+    uint32_t value = ich9_lpc_sci_irq(lpc);
+
+    visit_type_uint32(v, &value, name, errp);
+}
+
+static void ich9_lpc_add_properties(ICH9LPCState *lpc)
+{
+    static const uint8_t acpi_enable_cmd = ICH9_APM_ACPI_ENABLE;
+    static const uint8_t acpi_disable_cmd = ICH9_APM_ACPI_DISABLE;
+
+    object_property_add(OBJECT(lpc), ACPI_PM_PROP_SCI_INT, "uint32",
+                        ich9_lpc_get_sci_int,
+                        NULL, NULL, NULL, NULL);
+    object_property_add_uint8_ptr(OBJECT(lpc), ACPI_PM_PROP_ACPI_ENABLE_CMD,
+                                  &acpi_enable_cmd, NULL);
+    object_property_add_uint8_ptr(OBJECT(lpc), ACPI_PM_PROP_ACPI_DISABLE_CMD,
+                                  &acpi_disable_cmd, NULL);
+
+    ich9_pm_add_properties(OBJECT(lpc), &lpc->pm, NULL);
+}
+
 static int ich9_lpc_initfn(PCIDevice *d)
 {
     ICH9LPCState *lpc = ICH9_LPC_DEVICE(d);
@@ -552,6 +590,8 @@ static int ich9_lpc_initfn(PCIDevice *d)
                                         ICH9_RST_CNT_IOPORT, &lpc->rst_cnt_mem,
                                         1);
 
+    ich9_lpc_add_properties(lpc);
+
     return 0;
 }
 
index 8fe4fcb4a139d3266652d0ae1398c3ad64202e46..5fb808630fff91f3880e06b8ad688c88a24d4143 100644 (file)
@@ -185,7 +185,7 @@ static void pm_update_sci(VT686PMState *s)
                    ACPI_BITMASK_POWER_BUTTON_ENABLE |
                    ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
                    ACPI_BITMASK_TIMER_ENABLE)) != 0);
-    qemu_set_irq(s->dev.irq[0], sci_level);
+    pci_set_irq(&s->dev, sci_level);
     /* schedule a timer interruption if needed */
     acpi_pm_tmr_update(&s->ar, (s->ar.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
                        !(pmsts & ACPI_BITMASK_TIMER_STATUS));
index 3449bd8dfc10b6506c71e553b8665f68c58a1c80..9fd5e697a737718d94dbc8a02e172b4123d0870c 100644 (file)
@@ -73,7 +73,7 @@ static inline void hwsetup_free(HWSetup *hw)
 static inline void hwsetup_create_rom(HWSetup *hw,
         hwaddr base)
 {
-    rom_add_blob("hwsetup", hw->data, TARGET_PAGE_SIZE, base);
+    rom_add_blob("hwsetup", hw->data, TARGET_PAGE_SIZE, base, NULL, NULL, NULL);
 }
 
 static inline void hwsetup_add_u8(HWSetup *hw, uint8_t u)
index 5b057f78807d137ff3792d1996422dc50e9c8e7a..2a7ea5c0f9de4d3a7d4ac7087c0e2c0efbd5f0e8 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "qemu/option.h"
 #include "qemu/config-file.h"
+#include "qemu/error-report.h"
 #include "qemu-common.h"
 #include "sysemu/device_tree.h"
 #include "sysemu/sysemu.h"
@@ -39,6 +40,8 @@ static struct
     void (*machine_cpu_reset)(MicroBlazeCPU *);
     uint32_t bootstrap_pc;
     uint32_t cmdline;
+    uint32_t initrd_start;
+    uint32_t initrd_end;
     uint32_t fdt;
 } boot_info;
 
@@ -49,6 +52,7 @@ static void main_cpu_reset(void *opaque)
 
     cpu_reset(CPU(cpu));
     env->regs[5] = boot_info.cmdline;
+    env->regs[6] = boot_info.initrd_start;
     env->regs[7] = boot_info.fdt;
     env->sregs[SR_PC] = boot_info.bootstrap_pc;
     if (boot_info.machine_cpu_reset) {
@@ -57,9 +61,11 @@ static void main_cpu_reset(void *opaque)
 }
 
 static int microblaze_load_dtb(hwaddr addr,
-                                      uint32_t ramsize,
-                                      const char *kernel_cmdline,
-                                      const char *dtb_filename)
+                               uint32_t ramsize,
+                               uint32_t initrd_start,
+                               uint32_t initrd_end,
+                               const char *kernel_cmdline,
+                               const char *dtb_filename)
 {
     int fdt_size;
     void *fdt = NULL;
@@ -80,6 +86,14 @@ static int microblaze_load_dtb(hwaddr addr,
         }
     }
 
+    if (initrd_start) {
+        qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
+                                  initrd_start);
+
+        qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
+                                  initrd_end);
+    }
+
     cpu_physical_memory_write(addr, fdt, fdt_size);
     return fdt_size;
 }
@@ -90,7 +104,9 @@ static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
 }
 
 void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
-                            uint32_t ramsize, const char *dtb_filename,
+                            uint32_t ramsize,
+                            const char *initrd_filename,
+                            const char *dtb_filename,
                             void (*machine_cpu_reset)(MicroBlazeCPU *))
 {
     QemuOpts *machine_opts;
@@ -151,14 +167,36 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
             high = (ddr_base + kernel_size + 3) & ~3;
         }
 
+        if (initrd_filename) {
+            int initrd_size;
+            uint32_t initrd_offset;
+
+            high = ROUND_UP(high + kernel_size, 4);
+            boot_info.initrd_start = high;
+            initrd_offset = boot_info.initrd_start - ddr_base;
+            initrd_size = load_image_targphys(initrd_filename,
+                                              boot_info.initrd_start,
+                                              ram_size - initrd_offset);
+            if (initrd_size < 0) {
+                error_report("qemu: could not load initrd '%s'\n",
+                             initrd_filename);
+                exit(EXIT_FAILURE);
+            }
+            boot_info.initrd_end = boot_info.initrd_start + initrd_size;
+            high = ROUND_UP(high + initrd_size, 4);
+        }
+
         boot_info.cmdline = high + 4096;
         if (kernel_cmdline && strlen(kernel_cmdline)) {
             pstrcpy_targphys("cmdline", boot_info.cmdline, 256, kernel_cmdline);
         }
         /* Provide a device-tree.  */
         boot_info.fdt = boot_info.cmdline + 4096;
-        microblaze_load_dtb(boot_info.fdt, ram_size, kernel_cmdline,
-                                                     dtb_filename);
+        microblaze_load_dtb(boot_info.fdt, ram_size,
+                            boot_info.initrd_start,
+                            boot_info.initrd_end,
+                            kernel_cmdline,
+                            dtb_filename);
     }
 
 }
index b14ef2b99276192bd21899d265bedd5f56fa8db4..0eb7f8e4f6c16b670fb19e3651fffa4a057a71d0 100644 (file)
@@ -4,7 +4,9 @@
 #include "hw/hw.h"
 
 void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
-                            uint32_t ramsize, const char *dtb_filename,
+                            uint32_t ramsize,
+                            const char *initrd_filename,
+                            const char *dtb_filename,
                             void (*machine_cpu_reset)(MicroBlazeCPU *));
 
 #endif /* __MICROBLAZE_BOOT __ */
index e003c7c7b408fac89a9ec68dad16f44860cde129..10970e0f3f2d9de2aaca88920458cddeeb979d34 100644 (file)
@@ -176,8 +176,10 @@ petalogix_ml605_init(QEMUMachineInitArgs *args)
         }
     }
 
-    microblaze_load_kernel(cpu, ddr_base, ram_size, BINARY_DEVICE_TREE_FILE,
-                                                            machine_cpu_reset);
+    microblaze_load_kernel(cpu, ddr_base, ram_size,
+                           args->initrd_filename,
+                           BINARY_DEVICE_TREE_FILE,
+                           machine_cpu_reset);
 
 }
 
index 00af2b5abc05602d4386fb7a280270540fb1238f..ec6489c2d3cc697ff709b2e1556fc4869a9bec1d 100644 (file)
@@ -108,7 +108,9 @@ petalogix_s3adsp1800_init(QEMUMachineInitArgs *args)
     xilinx_ethlite_create(&nd_table[0], ETHLITE_BASEADDR, irq[1], 0, 0);
 
     microblaze_load_kernel(cpu, ddr_base, ram_size,
-                    BINARY_DEVICE_TREE_FILE, machine_cpu_reset);
+                           args->initrd_filename,
+                           BINARY_DEVICE_TREE_FILE,
+                           machine_cpu_reset);
 }
 
 static QEMUMachine petalogix_s3adsp1800_machine = {
index 2578e2939dfb76ed474a9db3c7ac91e62b6477cc..cca5c058cc1da56b25d026ea97b72377548c2562 100644 (file)
@@ -10,6 +10,7 @@ obj-$(CONFIG_VMPORT) += vmport.o
 
 # ARM devices
 common-obj-$(CONFIG_PL310) += arm_l2x0.o
+common-obj-$(CONFIG_INTEGRATOR_DEBUG) += arm_integrator_debug.o
 
 # PKUnity SoC devices
 common-obj-$(CONFIG_PUV3) += puv3_pm.o
diff --git a/hw/misc/arm_integrator_debug.c b/hw/misc/arm_integrator_debug.c
new file mode 100644 (file)
index 0000000..99b720f
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * LED, Switch and Debug control registers for ARM Integrator Boards
+ *
+ * This is currently a stub for this functionality but at least
+ * ensures something other than unassigned_mem_read() handles access
+ * to this area.
+ *
+ * The real h/w is described at:
+ *  http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0159b/Babbfijf.html
+ *
+ * Copyright (c) 2013 Alex Bennée <alex@bennee.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "exec/address-spaces.h"
+#include "hw/misc/arm_integrator_debug.h"
+
+#define INTEGRATOR_DEBUG(obj) \
+    OBJECT_CHECK(IntegratorDebugState, (obj), TYPE_INTEGRATOR_DEBUG)
+
+typedef struct {
+    SysBusDevice parent_obj;
+
+    MemoryRegion iomem;
+} IntegratorDebugState;
+
+static uint64_t intdbg_control_read(void *opaque, hwaddr offset,
+                                    unsigned size)
+{
+    switch (offset >> 2) {
+    case 0: /* ALPHA */
+    case 1: /* LEDS */
+    case 2: /* SWITCHES */
+        qemu_log_mask(LOG_UNIMP,
+                      "%s: returning zero from %" HWADDR_PRIx ":%u\n",
+                      __func__, offset, size);
+        return 0;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Bad offset %" HWADDR_PRIx,
+                      __func__, offset);
+        return 0;
+    }
+}
+
+static void intdbg_control_write(void *opaque, hwaddr offset,
+                                 uint64_t value, unsigned size)
+{
+    switch (offset >> 2) {
+    case 1: /* ALPHA */
+    case 2: /* LEDS */
+    case 3: /* SWITCHES */
+        /* Nothing interesting implemented yet.  */
+        qemu_log_mask(LOG_UNIMP,
+                      "%s: ignoring write of %" PRIu64
+                      " to %" HWADDR_PRIx ":%u\n",
+                      __func__, value, offset, size);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: write of %" PRIu64
+                      " to bad offset %" HWADDR_PRIx "\n",
+                      __func__, value, offset);
+    }
+}
+
+static const MemoryRegionOps intdbg_control_ops = {
+    .read = intdbg_control_read,
+    .write = intdbg_control_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void intdbg_control_init(Object *obj)
+{
+    SysBusDevice *sd = SYS_BUS_DEVICE(obj);
+    IntegratorDebugState *s = INTEGRATOR_DEBUG(obj);
+
+    memory_region_init_io(&s->iomem, NULL, &intdbg_control_ops,
+                          NULL, "dbg-leds", 0x1000000);
+    sysbus_init_mmio(sd, &s->iomem);
+}
+
+static const TypeInfo intdbg_info = {
+    .name          = TYPE_INTEGRATOR_DEBUG,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(IntegratorDebugState),
+    .instance_init = intdbg_control_init,
+};
+
+static void intdbg_register_types(void)
+{
+    type_register_static(&intdbg_info);
+}
+
+type_init(intdbg_register_types)
index 2838866f4500d1a9be68914b73856b5c425f0395..8d144baa1eaecc09f75d6916b1e7c2b7d7b577fc 100644 (file)
@@ -133,7 +133,7 @@ static void ivshmem_update_irq(IVShmemState *s, int val)
            isr ? 1 : 0, s->intrstatus, s->intrmask);
     }
 
-    qemu_set_irq(d->irq[0], (isr != 0));
+    pci_set_irq(d, (isr != 0));
 }
 
 static void ivshmem_IntrMask_write(IVShmemState *s, uint32_t val)
index b64e3bb7b4a21afee2841cf28adcb27e3539d417..226e2983d36ba96d58dbdd6fe973fffbd8c28543 100644 (file)
@@ -117,8 +117,19 @@ void pvpanic_init(ISABus *bus)
     isa_create_simple(bus, TYPE_ISA_PVPANIC_DEVICE);
 }
 
+#define PVPANIC_IOPORT_PROP "ioport"
+
+uint16_t pvpanic_port(void)
+{
+    Object *o = object_resolve_path_type("", TYPE_ISA_PVPANIC_DEVICE, NULL);
+    if (!o) {
+        return 0;
+    }
+    return object_property_get_int(o, PVPANIC_IOPORT_PROP, NULL);
+}
+
 static Property pvpanic_isa_properties[] = {
-    DEFINE_PROP_UINT16("ioport", PVPanicState, ioport, 0x505),
+    DEFINE_PROP_UINT16(PVPANIC_IOPORT_PROP, PVPanicState, ioport, 0x505),
     DEFINE_PROP_END_OF_LIST(),
 };
 
index a2d5283ff91fe7c82f4d109b10b8d47403156941..fe95e03d1d7d4ad906371370236025f6d2d354d0 100644 (file)
@@ -302,7 +302,7 @@ static void vfio_intx_interrupt(void *opaque)
             'A' + vdev->intx.pin);
 
     vdev->intx.pending = true;
-    qemu_set_irq(vdev->pdev.irq[vdev->intx.pin], 1);
+    pci_irq_assert(&vdev->pdev);
     vfio_mmap_set_enabled(vdev, false);
     if (vdev->intx.mmap_timeout) {
         timer_mod(vdev->intx.mmap_timer,
@@ -320,7 +320,7 @@ static void vfio_eoi(VFIODevice *vdev)
             vdev->host.bus, vdev->host.slot, vdev->host.function);
 
     vdev->intx.pending = false;
-    qemu_set_irq(vdev->pdev.irq[vdev->intx.pin], 0);
+    pci_irq_deassert(&vdev->pdev);
     vfio_unmask_intx(vdev);
 }
 
@@ -346,7 +346,7 @@ static void vfio_enable_intx_kvm(VFIODevice *vdev)
     qemu_set_fd_handler(irqfd.fd, NULL, NULL, vdev);
     vfio_mask_intx(vdev);
     vdev->intx.pending = false;
-    qemu_set_irq(vdev->pdev.irq[vdev->intx.pin], 0);
+    pci_irq_deassert(&vdev->pdev);
 
     /* Get an eventfd for resample/unmask */
     if (event_notifier_init(&vdev->intx.unmask, 0)) {
@@ -422,7 +422,7 @@ static void vfio_disable_intx_kvm(VFIODevice *vdev)
      */
     vfio_mask_intx(vdev);
     vdev->intx.pending = false;
-    qemu_set_irq(vdev->pdev.irq[vdev->intx.pin], 0);
+    pci_irq_deassert(&vdev->pdev);
 
     /* Tell KVM to stop listening for an INTx irqfd */
     if (kvm_vm_ioctl(kvm_state, KVM_IRQFD, &irqfd)) {
@@ -493,6 +493,7 @@ static int vfio_enable_intx(VFIODevice *vdev)
     vfio_disable_interrupts(vdev);
 
     vdev->intx.pin = pin - 1; /* Pin A (1) -> irq[0] */
+    pci_config_set_interrupt_pin(vdev->pdev.config, pin);
 
 #ifdef CONFIG_KVM
     /*
@@ -552,7 +553,7 @@ static void vfio_disable_intx(VFIODevice *vdev)
     vfio_disable_intx_kvm(vdev);
     vfio_disable_irqindex(vdev, VFIO_PCI_INTX_IRQ_INDEX);
     vdev->intx.pending = false;
-    qemu_set_irq(vdev->pdev.irq[vdev->intx.pin], 0);
+    pci_irq_deassert(&vdev->pdev);
     vfio_mmap_set_enabled(vdev, true);
 
     fd = event_notifier_get_fd(&vdev->intx.interrupt);
index 70a59fde7ff06be945780f81a330825f641cb00f..ec8ecd7b94934532c8d77138cfcd41cf825f7618 100644 (file)
@@ -328,7 +328,7 @@ set_interrupt_cause(E1000State *s, int index, uint32_t val)
     }
 
     s->mit_irq_level = (pending_ints != 0);
-    qemu_set_irq(d->irq[0], s->mit_irq_level);
+    pci_set_irq(d, s->mit_irq_level);
 }
 
 static void
index ffa60d5c96f4f39c846a13c5c395a9f6502cd3a4..3b891ca340fb2f54089d5a6ff745c4079ade50af 100644 (file)
@@ -409,7 +409,7 @@ static void disable_interrupt(EEPRO100State * s)
 {
     if (s->int_stat) {
         TRACE(INT, logout("interrupt disabled\n"));
-        qemu_irq_lower(s->dev.irq[0]);
+        pci_irq_deassert(&s->dev);
         s->int_stat = 0;
     }
 }
@@ -418,7 +418,7 @@ static void enable_interrupt(EEPRO100State * s)
 {
     if (!s->int_stat) {
         TRACE(INT, logout("interrupt enabled\n"));
-        qemu_irq_raise(s->dev.irq[0]);
+        pci_irq_assert(&s->dev);
         s->int_stat = 1;
     }
 }
index c96125895ee1d986314188e26c259164a24a0913..a94cf74bf2a0dd7d35f3fedaf6420668087057f0 100644 (file)
@@ -731,7 +731,7 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
     s = &d->ne2000;
     ne2000_setup_io(s, DEVICE(pci_dev), 0x100);
     pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
-    s->irq = d->dev.irq[0];
+    s->irq = pci_allocate_irq(&d->dev);
 
     qemu_macaddr_default_if_unset(&s->c.macaddr);
     ne2000_reset(s);
@@ -752,6 +752,7 @@ static void pci_ne2000_exit(PCIDevice *pci_dev)
 
     memory_region_destroy(&s->io);
     qemu_del_nic(s->nic);
+    qemu_free_irq(s->irq);
 }
 
 static Property ne2000_properties[] = {
index 865f2f0c592500e93785e88dc422da64d3792064..6a5d8064bb526d6af221b747e63d7af52779312a 100644 (file)
@@ -282,6 +282,7 @@ static void pci_pcnet_uninit(PCIDevice *dev)
 {
     PCIPCNetState *d = PCI_PCNET(dev);
 
+    qemu_free_irq(d->state.irq);
     memory_region_destroy(&d->state.mmio);
     memory_region_destroy(&d->io_bar);
     timer_del(d->state.poll_timer);
@@ -331,7 +332,7 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
 
     pci_register_bar(pci_dev, 1, 0, &s->mmio);
 
-    s->irq = pci_dev->irq[0];
+    s->irq = pci_allocate_irq(pci_dev);
     s->phys_mem_read = pci_physical_memory_read;
     s->phys_mem_write = pci_physical_memory_write;
     s->dma_opaque = pci_dev;
index 3225f3d3e55ca27e2199315760747be5bb5651b3..5329f44a9dfd73a5d93201accdab70b8097a2572 100644 (file)
@@ -716,7 +716,7 @@ static void rtl8139_update_irq(RTL8139State *s)
     DPRINTF("Set IRQ to %d (%04x %04x)\n", isr ? 1 : 0, s->IntrStatus,
         s->IntrMask);
 
-    qemu_set_irq(d->irq[0], (isr != 0));
+    pci_set_irq(d, (isr != 0));
 }
 
 static int rtl8139_RxWrap(RTL8139State *s)
index 49c2466434c9e5876e3a4617be8c59e3497764c2..19687aa03c7b42c9d1c5ef2562f58b330c078f8a 100644 (file)
@@ -336,7 +336,7 @@ static bool _vmxnet3_assert_interrupt_line(VMXNET3State *s, uint32_t int_idx)
     }
 
     VMW_IRPRN("Asserting line for interrupt %u", int_idx);
-    qemu_set_irq(d->irq[int_idx], 1);
+    pci_irq_assert(d);
     return true;
 }
 
@@ -356,7 +356,7 @@ static void _vmxnet3_deassert_interrupt_line(VMXNET3State *s, int lidx)
     assert(!s->msi_used || !msi_enabled(d));
 
     VMW_IRPRN("Deasserting line for interrupt %u", lidx);
-    qemu_set_irq(d->irq[lidx], 0);
+    pci_irq_deassert(d);
 }
 
 static void vmxnet3_update_interrupt_line_state(VMXNET3State *s, int lidx)
@@ -1299,6 +1299,12 @@ static void vmxnet3_update_features(VMXNET3State *s)
     }
 }
 
+static bool vmxnet3_verify_intx(VMXNET3State *s, int intx)
+{
+    return s->msix_used || s->msi_used || (intx ==
+           (pci_get_byte(s->parent_obj.config + PCI_INTERRUPT_PIN) - 1));
+}
+
 static void vmxnet3_activate_device(VMXNET3State *s)
 {
     int i;
@@ -1332,6 +1338,7 @@ static void vmxnet3_activate_device(VMXNET3State *s)
 
     s->event_int_idx =
         VMXNET3_READ_DRV_SHARED8(s->drv_shmem, devRead.intrConf.eventIntrIdx);
+    assert(vmxnet3_verify_intx(s, s->event_int_idx));
     VMW_CFPRN("Events interrupt line is %u", s->event_int_idx);
 
     s->auto_int_masking =
@@ -1364,6 +1371,7 @@ static void vmxnet3_activate_device(VMXNET3State *s)
         /* Read interrupt number for this TX queue */
         s->txq_descr[i].intr_idx =
             VMXNET3_READ_TX_QUEUE_DESCR8(qdescr_pa, conf.intrIdx);
+        assert(vmxnet3_verify_intx(s, s->txq_descr[i].intr_idx));
 
         VMW_CFPRN("TX Queue %d interrupt: %d", i, s->txq_descr[i].intr_idx);
 
@@ -1411,6 +1419,7 @@ static void vmxnet3_activate_device(VMXNET3State *s)
         /* Read interrupt number for this RX queue */
         s->rxq_descr[i].intr_idx =
             VMXNET3_READ_TX_QUEUE_DESCR8(qd_pa, conf.intrIdx);
+        assert(vmxnet3_verify_intx(s, s->rxq_descr[i].intr_idx));
 
         VMW_CFPRN("RX Queue %d interrupt: %d", i, s->rxq_descr[i].intr_idx);
 
index d0820e507b78720c9bf5a7019d108dc3dda877aa..f5dc3ea8459d31f2a36d97ec0bfa82e951ede25d 100644 (file)
@@ -42,6 +42,7 @@ typedef struct FWCfgEntry {
     uint8_t *data;
     void *callback_opaque;
     FWCfgCallback callback;
+    FWCfgReadCallback read_callback;
 } FWCfgEntry;
 
 struct FWCfgState {
@@ -249,8 +250,12 @@ static uint8_t fw_cfg_read(FWCfgState *s)
 
     if (s->cur_entry == FW_CFG_INVALID || !e->data || s->cur_offset >= e->len)
         ret = 0;
-    else
+    else {
+        if (e->read_callback) {
+            e->read_callback(e->callback_opaque, s->cur_offset);
+        }
         ret = e->data[s->cur_offset++];
+    }
 
     trace_fw_cfg_read(s, ret);
     return ret;
@@ -381,7 +386,10 @@ static const VMStateDescription vmstate_fw_cfg = {
     }
 };
 
-void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len)
+static void fw_cfg_add_bytes_read_callback(FWCfgState *s, uint16_t key,
+                                           FWCfgReadCallback callback,
+                                           void *callback_opaque,
+                                           void *data, size_t len)
 {
     int arch = !!(key & FW_CFG_ARCH_LOCAL);
 
@@ -391,6 +399,13 @@ void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len)
 
     s->entries[arch][key].data = data;
     s->entries[arch][key].len = (uint32_t)len;
+    s->entries[arch][key].read_callback = callback;
+    s->entries[arch][key].callback_opaque = callback_opaque;
+}
+
+void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len)
+{
+    fw_cfg_add_bytes_read_callback(s, key, NULL, NULL, data, len);
 }
 
 void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value)
@@ -444,8 +459,9 @@ void fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
     s->entries[arch][key].callback = callback;
 }
 
-void fw_cfg_add_file(FWCfgState *s,  const char *filename,
-                     void *data, size_t len)
+void fw_cfg_add_file_callback(FWCfgState *s,  const char *filename,
+                              FWCfgReadCallback callback, void *callback_opaque,
+                              void *data, size_t len)
 {
     int i, index;
     size_t dsize;
@@ -459,7 +475,8 @@ void fw_cfg_add_file(FWCfgState *s,  const char *filename,
     index = be32_to_cpu(s->files->count);
     assert(index < FW_CFG_FILE_SLOTS);
 
-    fw_cfg_add_bytes(s, FW_CFG_FILE_FIRST + index, data, len);
+    fw_cfg_add_bytes_read_callback(s, FW_CFG_FILE_FIRST + index,
+                                   callback, callback_opaque, data, len);
 
     pstrcpy(s->files->f[index].name, sizeof(s->files->f[index].name),
             filename);
@@ -477,6 +494,12 @@ void fw_cfg_add_file(FWCfgState *s,  const char *filename,
     s->files->count = cpu_to_be32(index+1);
 }
 
+void fw_cfg_add_file(FWCfgState *s,  const char *filename,
+                     void *data, size_t len)
+{
+    fw_cfg_add_file_callback(s, filename, NULL, NULL, data, len);
+}
+
 static void fw_cfg_machine_ready(struct Notifier *n, void *data)
 {
     size_t len;
index a9392c7bdc4e015493887565d26f370c1cf08a1e..440e187c463c6b867dd0d041b860629031d952c5 100644 (file)
@@ -53,6 +53,7 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
     if (err) {
         goto bridge_error;
     }
+    dev->config[PCI_INTERRUPT_PIN] = 0x1;
     memory_region_init(&bridge_dev->bar, OBJECT(dev), "shpc-bar", shpc_bar_size(dev));
     err = shpc_init(dev, &br->sec_bus, &bridge_dev->bar, 0);
     if (err) {
@@ -73,7 +74,6 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
      * Check whether that works well. */
     pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
                     PCI_BASE_ADDRESS_MEM_TYPE_64, &bridge_dev->bar);
-    dev->config[PCI_INTERRUPT_PIN] = 0x1;
     return 0;
 msi_error:
     slotid_cap_cleanup(dev);
index c04114932049db3d80c7b308b3a8ac531b944676..bad3953fb5bc1cff19dc081df75158cb973e07b8 100644 (file)
@@ -416,6 +416,14 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
     return b;
 }
 
+PCIBus *find_i440fx(void)
+{
+    PCIHostState *s = OBJECT_CHECK(PCIHostState,
+                                   object_resolve_path("/machine/i440fx", NULL),
+                                   TYPE_PCI_HOST_BRIDGE);
+    return s ? s->bus : NULL;
+}
+
 /* PIIX3 PCI to ISA bridge */
 static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq)
 {
index ad703a4bf788fceaab5e5f2a49afd2d098689d0d..b8feed125433d17e4390d992bbb3ea0a4b943122 100644 (file)
@@ -109,8 +109,18 @@ static void q35_host_get_pci_hole64_end(Object *obj, Visitor *v,
     visit_type_uint64(v, &w64.end, name, errp);
 }
 
+static void q35_host_get_mmcfg_size(Object *obj, Visitor *v,
+                                    void *opaque, const char *name,
+                                    Error **errp)
+{
+    PCIExpressHost *e = PCIE_HOST_BRIDGE(obj);
+    uint32_t value = e->size;
+
+    visit_type_uint32(v, &value, name, errp);
+}
+
 static Property mch_props[] = {
-    DEFINE_PROP_UINT64("MCFG", Q35PCIHost, parent_obj.base_addr,
+    DEFINE_PROP_UINT64(PCIE_HOST_MCFG_BASE, Q35PCIHost, parent_obj.base_addr,
                         MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT),
     DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, Q35PCIHost,
                      mch.pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE),
@@ -160,6 +170,10 @@ static void q35_host_initfn(Object *obj)
                         q35_host_get_pci_hole64_end,
                         NULL, NULL, NULL, NULL);
 
+    object_property_add(obj, PCIE_HOST_MCFG_SIZE, "int",
+                        q35_host_get_mmcfg_size,
+                        NULL, NULL, NULL, NULL);
+
     /* Leave enough space for the biggest MCFG BAR */
     /* TODO: this matches current bios behaviour, but
      * it's not a power of two, which means an MTRR
@@ -375,6 +389,16 @@ static int mch_init(PCIDevice *d)
     return 0;
 }
 
+uint64_t mch_mcfg_base(void)
+{
+    bool ambiguous;
+    Object *o = object_resolve_path_type("", TYPE_MCH_PCI_DEVICE, &ambiguous);
+    if (!o) {
+        return 0;
+    }
+    return MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT;
+}
+
 static void mch_class_init(ObjectClass *klass, void *data)
 {
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
index 00554a05acce0a0d3503a145ad720a5adc681634..a98c8a05804f9ced185afaeeac4c4d83984c5a95 100644 (file)
@@ -83,7 +83,7 @@ static const TypeInfo pcie_bus_info = {
 
 static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
 static void pci_update_mappings(PCIDevice *d);
-static void pci_set_irq(void *opaque, int irq_num, int level);
+static void pci_irq_handler(void *opaque, int irq_num, int level);
 static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom);
 static void pci_del_option_rom(PCIDevice *pdev);
 
@@ -161,7 +161,7 @@ void pci_device_deassert_intx(PCIDevice *dev)
 {
     int i;
     for (i = 0; i < PCI_NUM_PINS; ++i) {
-        qemu_set_irq(dev->irq[i], 0);
+        pci_irq_handler(dev, i, 0);
     }
 }
 
@@ -283,6 +283,24 @@ const char *pci_root_bus_path(PCIDevice *dev)
     return rootbus->qbus.name;
 }
 
+static uint64_t master_abort_mem_read(void *opaque, hwaddr addr, unsigned size)
+{
+   return -1ULL;
+}
+
+static void master_abort_mem_write(void *opaque, hwaddr addr, uint64_t val,
+                                   unsigned size)
+{
+}
+
+static const MemoryRegionOps master_abort_mem_ops = {
+    .read = master_abort_mem_read,
+    .write = master_abort_mem_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+#define MASTER_ABORT_MEM_PRIORITY INT_MIN
+
 static void pci_bus_init(PCIBus *bus, DeviceState *parent,
                          const char *name,
                          MemoryRegion *address_space_mem,
@@ -294,6 +312,14 @@ static void pci_bus_init(PCIBus *bus, DeviceState *parent,
     bus->address_space_mem = address_space_mem;
     bus->address_space_io = address_space_io;
 
+
+    memory_region_init_io(&bus->master_abort_mem, OBJECT(bus),
+                          &master_abort_mem_ops, bus, "pci-master-abort",
+                          memory_region_size(bus->address_space_mem));
+    memory_region_add_subregion_overlap(bus->address_space_mem,
+                                        0, &bus->master_abort_mem,
+                                        MASTER_ABORT_MEM_PRIORITY);
+
     /* host bridge */
     QLIST_INIT(&bus->child);
 
@@ -863,14 +889,12 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
     pci_dev->config_read = config_read;
     pci_dev->config_write = config_write;
     bus->devices[devfn] = pci_dev;
-    pci_dev->irq = qemu_allocate_irqs(pci_set_irq, pci_dev, PCI_NUM_PINS);
     pci_dev->version_id = 2; /* Current pci device vmstate version */
     return pci_dev;
 }
 
 static void do_pci_unregister_device(PCIDevice *pci_dev)
 {
-    qemu_free_irqs(pci_dev->irq);
     pci_dev->bus->devices[pci_dev->devfn] = NULL;
     pci_config_free(pci_dev);
 
@@ -1175,7 +1199,7 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
 /* generic PCI irq support */
 
 /* 0 <= irq_num <= 3. level must be 0 or 1 */
-static void pci_set_irq(void *opaque, int irq_num, int level)
+static void pci_irq_handler(void *opaque, int irq_num, int level)
 {
     PCIDevice *pci_dev = opaque;
     int change;
@@ -1191,6 +1215,24 @@ static void pci_set_irq(void *opaque, int irq_num, int level)
     pci_change_irq_level(pci_dev, irq_num, change);
 }
 
+static inline int pci_intx(PCIDevice *pci_dev)
+{
+    return pci_get_byte(pci_dev->config + PCI_INTERRUPT_PIN) - 1;
+}
+
+qemu_irq pci_allocate_irq(PCIDevice *pci_dev)
+{
+    int intx = pci_intx(pci_dev);
+
+    return qemu_allocate_irq(pci_irq_handler, pci_dev, intx);
+}
+
+void pci_set_irq(PCIDevice *pci_dev, int level)
+{
+    int intx = pci_intx(pci_dev);
+    pci_irq_handler(pci_dev, intx, level);
+}
+
 /* Special hooks used by device assignment */
 void pci_bus_set_route_irq_fn(PCIBus *bus, pci_route_irq_fn route_intx_to_irq)
 {
@@ -2264,7 +2306,7 @@ static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque)
     Range *range = opaque;
     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
     uint16_t cmd = pci_get_word(dev->config + PCI_COMMAND);
-    int r;
+    int i;
 
     if (!(cmd & PCI_COMMAND_MEMORY)) {
         return;
@@ -2283,17 +2325,21 @@ static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque)
             range_extend(range, &pref_range);
         }
     }
-    for (r = 0; r < PCI_NUM_REGIONS; ++r) {
-        PCIIORegion *region = &dev->io_regions[r];
+    for (i = 0; i < PCI_NUM_REGIONS; ++i) {
+        PCIIORegion *r = &dev->io_regions[i];
         Range region_range;
 
-        if (!region->size ||
-            (region->type & PCI_BASE_ADDRESS_SPACE_IO) ||
-            !(region->type & PCI_BASE_ADDRESS_MEM_TYPE_64)) {
+        if (!r->size ||
+            (r->type & PCI_BASE_ADDRESS_SPACE_IO) ||
+            !(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64)) {
+            continue;
+        }
+        region_range.begin = pci_bar_address(dev, i, r->type, r->size);
+        region_range.end = region_range.begin + r->size;
+
+        if (region_range.begin == PCI_BAR_UNMAPPED) {
             continue;
         }
-        region_range.begin = pci_get_quad(dev->config + pci_bar(dev, r));
-        region_range.end = region_range.begin + region->size;
 
         region_range.begin = MAX(region_range.begin, 0x1ULL << 32);
 
index 50af3c1dfe304e34fa79d8832a2e8a3ba50c9391..268a69664654b8816f835c708c105ba4c9ce2421 100644 (file)
@@ -187,7 +187,7 @@ static void hotplug_event_notify(PCIDevice *dev)
     } else if (msi_enabled(dev)) {
         msi_notify(dev, pcie_cap_flags_get_vector(dev));
     } else {
-        qemu_set_irq(dev->irq[dev->exp.hpev_intx], dev->exp.hpev_notified);
+        pci_set_irq(dev, dev->exp.hpev_notified);
     }
 }
 
@@ -195,7 +195,7 @@ static void hotplug_event_clear(PCIDevice *dev)
 {
     hotplug_event_update_event_status(dev);
     if (!msix_enabled(dev) && !msi_enabled(dev) && !dev->exp.hpev_notified) {
-        qemu_set_irq(dev->irq[dev->exp.hpev_intx], 0);
+        pci_irq_deassert(dev);
     }
 }
 
index ca762ab09a211a0c1a24667ba2efc665031f8326..32aa0c61b5042bcd98e502b03f86c8aa84789c71 100644 (file)
@@ -285,7 +285,7 @@ static void pcie_aer_root_notify(PCIDevice *dev)
     } else if (msi_enabled(dev)) {
         msi_notify(dev, pcie_aer_root_get_vector(dev));
     } else {
-        qemu_set_irq(dev->irq[dev->exp.aer_intx], 1);
+        pci_irq_assert(dev);
     }
 }
 
@@ -768,7 +768,7 @@ void pcie_aer_root_write_config(PCIDevice *dev,
     uint32_t root_cmd = pci_get_long(aer_cap + PCI_ERR_ROOT_COMMAND);
     /* 6.2.4.1.2 Interrupt Generation */
     if (!msix_enabled(dev) && !msi_enabled(dev)) {
-        qemu_set_irq(dev->irq[dev->exp.aer_intx], !!(root_cmd & enabled_cmd));
+        pci_set_irq(dev, !!(root_cmd & enabled_cmd));
         return;
     }
 
index b70e5adc4bd06134ab808e601b981eacfb6fb0f3..c6e1b573e1681c4510f0f1fd2e17545cb40183a9 100644 (file)
 #include "hw/pci/pcie_host.h"
 #include "exec/address-spaces.h"
 
-/*
- * PCI express mmcfig address
- * bit 20 - 28: bus number
- * bit 15 - 19: device number
- * bit 12 - 14: function number
- * bit  0 - 11: offset in configuration space of a given device
- */
-#define PCIE_MMCFG_SIZE_MAX             (1ULL << 28)
-#define PCIE_MMCFG_SIZE_MIN             (1ULL << 20)
-#define PCIE_MMCFG_BUS_BIT              20
-#define PCIE_MMCFG_BUS_MASK             0x1ff
-#define PCIE_MMCFG_DEVFN_BIT            12
-#define PCIE_MMCFG_DEVFN_MASK           0xff
-#define PCIE_MMCFG_CONFOFFSET_MASK      0xfff
-#define PCIE_MMCFG_BUS(addr)            (((addr) >> PCIE_MMCFG_BUS_BIT) & \
-                                         PCIE_MMCFG_BUS_MASK)
-#define PCIE_MMCFG_DEVFN(addr)          (((addr) >> PCIE_MMCFG_DEVFN_BIT) & \
-                                         PCIE_MMCFG_DEVFN_MASK)
-#define PCIE_MMCFG_CONFOFFSET(addr)     ((addr) & PCIE_MMCFG_CONFOFFSET_MASK)
-
-
 /* a helper function to get a PCIDevice for a given mmconfig address */
 static inline PCIDevice *pcie_dev_find_by_mmcfg_addr(PCIBus *s,
                                                      uint32_t mmcfg_addr)
@@ -104,9 +83,6 @@ static const MemoryRegionOps pcie_mmcfg_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-/* pcie_host::base_addr == PCIE_BASE_ADDR_UNMAPPED when it isn't mapped. */
-#define PCIE_BASE_ADDR_UNMAPPED  ((hwaddr)-1ULL)
-
 int pcie_host_init(PCIExpressHost *e)
 {
     e->base_addr = PCIE_BASE_ADDR_UNMAPPED;
index eb092fdb615bb5cb07c85da7fc6cfbf389f56946..0bbd36e2721e60cfba349ab615f10b5530b191ed 100644 (file)
@@ -172,7 +172,7 @@ static void shpc_interrupt_update(PCIDevice *d)
     if (msi_enabled(d) && shpc->msi_requested != level)
         msi_notify(d, 0);
     else
-        qemu_set_irq(d->irq[0], level);
+        pci_set_irq(d, level);
     shpc->msi_requested = level;
 }
 
index 99bf8ec446badebb76168a000169d8aed349d8e7..48c8b823500283310576cb92d8d37c7082279a44 100644 (file)
@@ -361,7 +361,7 @@ static int esp_pci_scsi_init(PCIDevice *dev)
                           "esp-io", 0x80);
 
     pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->io);
-    s->irq = dev->irq[0];
+    s->irq = pci_allocate_irq(dev);
 
     scsi_bus_new(&s->bus, sizeof(s->bus), d, &esp_pci_scsi_info, NULL);
     if (!d->hotplugged) {
@@ -378,6 +378,7 @@ static void esp_pci_scsi_uninit(PCIDevice *d)
 {
     PCIESPState *pci = PCI_ESP(d);
 
+    qemu_free_irq(pci->esp.irq);
     memory_region_destroy(&pci->io);
 }
 
index 36e5f5036014807b4c8602aae437f7aac8dbb1e2..cb304148493841d5e504fdf93919f29edc580d42 100644 (file)
@@ -437,7 +437,7 @@ static void lsi_update_irq(LSIState *s)
                 level, s->dstat, s->sist1, s->sist0);
         last_level = level;
     }
-    qemu_set_irq(d->irq[0], level);
+    pci_set_irq(d, level);
 
     if (!level && lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON)) {
         DPRINTF("Handled IRQs & disconnected, looking for pending "
index 09b51b387b6c074d0335ecb8cccf7fa3f020ed98..7c5a1a2b3a19554e2588bee9a597eff1560e4188 100644 (file)
@@ -535,7 +535,7 @@ static void megasas_complete_frame(MegasasState *s, uint64_t context)
                 msix_notify(pci_dev, 0);
             } else {
                 trace_megasas_irq_raise();
-                qemu_irq_raise(pci_dev->irq[0]);
+                pci_irq_assert(pci_dev);
             }
         }
     } else {
@@ -1936,7 +1936,7 @@ static void megasas_mmio_write(void *opaque, hwaddr addr,
         s->intr_mask = val;
         if (!megasas_intr_enabled(s) && !msix_enabled(pci_dev)) {
             trace_megasas_irq_lower();
-            qemu_irq_lower(pci_dev->irq[0]);
+            pci_irq_deassert(pci_dev);
         }
         if (megasas_intr_enabled(s)) {
             trace_megasas_intr_enabled();
@@ -1952,7 +1952,7 @@ static void megasas_mmio_write(void *opaque, hwaddr addr,
             stl_le_phys(s->producer_pa, s->reply_queue_head);
             if (!msix_enabled(pci_dev)) {
                 trace_megasas_irq_lower();
-                qemu_irq_lower(pci_dev->irq[0]);
+                pci_irq_deassert(pci_dev);
             }
         }
         break;
index 819d671ba2e28c78e39275ec38b840b41a19dff4..94b328f18660f3d9de8cfc7ae5e710aea2b04b49 100644 (file)
@@ -330,7 +330,7 @@ pvscsi_update_irq_status(PVSCSIState *s)
         return;
     }
 
-    qemu_set_irq(d->irq[0], !!should_raise);
+    pci_set_irq(d, !!should_raise);
 }
 
 static void
index fcd22aea59d8193dbd16aaa1e02bfe8c85df08fc..2eb75ea945005b22148d2071211735bd0d703201 100644 (file)
@@ -757,6 +757,11 @@ static void hpet_device_class_init(ObjectClass *klass, void *data)
     dc->props = hpet_device_properties;
 }
 
+bool hpet_find(void)
+{
+    return object_resolve_path_type("", TYPE_HPET, NULL);
+}
+
 static const TypeInfo hpet_device_info = {
     .name          = TYPE_HPET,
     .parent        = TYPE_SYS_BUS_DEVICE,
index 4d21a0b7bbea382407cb08930d79a2b9fb0334b6..0c985942f99f332541d672335525d167e2e1016b 100644 (file)
@@ -60,7 +60,7 @@ static int usb_ehci_pci_initfn(PCIDevice *dev)
     pci_conf[0x6e] = 0x00;
     pci_conf[0x6f] = 0xc0;  /* USBLEFCTLSTS */
 
-    s->irq = dev->irq[3];
+    s->irq = pci_allocate_irq(dev);
     s->as = pci_get_address_space(dev);
 
     usb_ehci_realize(s, DEVICE(dev), NULL);
index 0396e334edf28d52c4eee3b0f9e843a15f459f5a..e38cdebfecbada03f0e56e0404d4db518a3ac6b2 100644 (file)
@@ -1946,7 +1946,7 @@ static int usb_ohci_initfn_pci(PCIDevice *dev)
                       pci_get_address_space(dev)) != 0) {
         return -1;
     }
-    ohci->state.irq = dev->irq[0];
+    ohci->state.irq = pci_allocate_irq(dev);
 
     pci_register_bar(dev, 0, 0, &ohci->state.mem);
     return 0;
index becc7faec13b28afc45eaaf58ce5b00fda43e5af..238d1d2b5f7cb370f75ff02c14f725feeaf59ec6 100644 (file)
@@ -164,7 +164,6 @@ struct UHCIState {
 
     /* Interrupts that should be raised at the end of the current frame.  */
     uint32_t pending_int_mask;
-    int irq_pin;
 
     /* Active packets */
     QTAILQ_HEAD(, UHCIQueue) queues;
@@ -381,7 +380,7 @@ static void uhci_update_irq(UHCIState *s)
     } else {
         level = 0;
     }
-    qemu_set_irq(s->dev.irq[s->irq_pin], level);
+    pci_set_irq(&s->dev, level);
 }
 
 static void uhci_reset(void *opaque)
@@ -1240,8 +1239,7 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
     /* TODO: reset value should be 0. */
     pci_conf[USB_SBRN] = USB_RELEASE_1; // release number
 
-    s->irq_pin = u->info.irq_pin;
-    pci_config_set_interrupt_pin(pci_conf, s->irq_pin + 1);
+    pci_config_set_interrupt_pin(pci_conf, u->info.irq_pin + 1);
 
     if (s->masterbus) {
         USBPort *ports[NB_PORTS];
index 469c24d768523f94854efadf4ecc38b76a276e85..835f65ed81602b7fe132bb874d16d4f4b2f7b8c4 100644 (file)
@@ -346,7 +346,6 @@ typedef struct XHCITransfer {
     QEMUSGList sgl;
     bool running_async;
     bool running_retry;
-    bool cancelled;
     bool complete;
     bool int_req;
     unsigned int iso_pkts;
@@ -374,7 +373,6 @@ struct XHCIStreamContext {
     dma_addr_t pctx;
     unsigned int sct;
     XHCIRing ring;
-    XHCIStreamContext *sstreams;
 };
 
 struct XHCIEPContext {
@@ -449,7 +447,6 @@ struct XHCIState {
     /*< public >*/
 
     USBBus bus;
-    qemu_irq irq;
     MemoryRegion mem;
     MemoryRegion mem_cap;
     MemoryRegion mem_oper;
@@ -507,6 +504,7 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
                          unsigned int epid, unsigned int streamid);
 static TRBCCode xhci_disable_ep(XHCIState *xhci, unsigned int slotid,
                                 unsigned int epid);
+static void xhci_xfer_report(XHCITransfer *xfer);
 static void xhci_event(XHCIState *xhci, XHCIEvent *event, int v);
 static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v);
 static USBEndpoint *xhci_epid_to_usbep(XHCIState *xhci,
@@ -739,7 +737,7 @@ static void xhci_intx_update(XHCIState *xhci)
     }
 
     trace_usb_xhci_irq_intx(level);
-    qemu_set_irq(xhci->irq, level);
+    pci_set_irq(pci_dev, level);
 }
 
 static void xhci_msix_update(XHCIState *xhci, int v)
@@ -797,7 +795,7 @@ static void xhci_intr_raise(XHCIState *xhci, int v)
 
     if (v == 0) {
         trace_usb_xhci_irq_intx(1);
-        qemu_set_irq(xhci->irq, 1);
+        pci_irq_assert(pci_dev);
     }
 }
 
@@ -1133,7 +1131,6 @@ static void xhci_reset_streams(XHCIEPContext *epctx)
 
     for (i = 0; i < epctx->nr_pstreams; i++) {
         epctx->pstreams[i].sct = -1;
-        g_free(epctx->pstreams[i].sstreams);
     }
 }
 
@@ -1146,15 +1143,8 @@ static void xhci_alloc_streams(XHCIEPContext *epctx, dma_addr_t base)
 
 static void xhci_free_streams(XHCIEPContext *epctx)
 {
-    int i;
-
     assert(epctx->pstreams != NULL);
 
-    if (!epctx->lsa) {
-        for (i = 0; i < epctx->nr_pstreams; i++) {
-            g_free(epctx->pstreams[i].sstreams);
-        }
-    }
     g_free(epctx->pstreams);
     epctx->pstreams = NULL;
     epctx->nr_pstreams = 0;
@@ -1196,6 +1186,7 @@ static XHCIStreamContext *xhci_find_stream(XHCIEPContext *epctx,
 static void xhci_set_ep_state(XHCIState *xhci, XHCIEPContext *epctx,
                               XHCIStreamContext *sctx, uint32_t state)
 {
+    XHCIRing *ring = NULL;
     uint32_t ctx[5];
     uint32_t ctx2[2];
 
@@ -1206,6 +1197,7 @@ static void xhci_set_ep_state(XHCIState *xhci, XHCIEPContext *epctx,
     /* update ring dequeue ptr */
     if (epctx->nr_pstreams) {
         if (sctx != NULL) {
+            ring = &sctx->ring;
             xhci_dma_read_u32s(xhci, sctx->pctx, ctx2, sizeof(ctx2));
             ctx2[0] &= 0xe;
             ctx2[0] |= sctx->ring.dequeue | sctx->ring.ccs;
@@ -1213,8 +1205,12 @@ static void xhci_set_ep_state(XHCIState *xhci, XHCIEPContext *epctx,
             xhci_dma_write_u32s(xhci, sctx->pctx, ctx2, sizeof(ctx2));
         }
     } else {
-        ctx[2] = epctx->ring.dequeue | epctx->ring.ccs;
-        ctx[3] = (epctx->ring.dequeue >> 16) >> 16;
+        ring = &epctx->ring;
+    }
+    if (ring) {
+        ctx[2] = ring->dequeue | ring->ccs;
+        ctx[3] = (ring->dequeue >> 16) >> 16;
+
         DPRINTF("xhci: set epctx: " DMA_ADDR_FMT " state=%d dequeue=%08x%08x\n",
                 epctx->pctx, state, ctx[3], ctx[2]);
     }
@@ -1312,15 +1308,18 @@ static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,
     return CC_SUCCESS;
 }
 
-static int xhci_ep_nuke_one_xfer(XHCITransfer *t)
+static int xhci_ep_nuke_one_xfer(XHCITransfer *t, TRBCCode report)
 {
     int killed = 0;
 
+    if (report && (t->running_async || t->running_retry)) {
+        t->status = report;
+        xhci_xfer_report(t);
+    }
+
     if (t->running_async) {
         usb_cancel_packet(&t->packet);
         t->running_async = 0;
-        t->cancelled = 1;
-        DPRINTF("xhci: cancelling transfer, waiting for it to complete\n");
         killed = 1;
     }
     if (t->running_retry) {
@@ -1330,6 +1329,7 @@ static int xhci_ep_nuke_one_xfer(XHCITransfer *t)
             timer_del(epctx->kick_timer);
         }
         t->running_retry = 0;
+        killed = 1;
     }
     if (t->trbs) {
         g_free(t->trbs);
@@ -1342,7 +1342,7 @@ static int xhci_ep_nuke_one_xfer(XHCITransfer *t)
 }
 
 static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned int slotid,
-                               unsigned int epid)
+                               unsigned int epid, TRBCCode report)
 {
     XHCISlot *slot;
     XHCIEPContext *epctx;
@@ -1363,7 +1363,10 @@ static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned int slotid,
 
     xferi = epctx->next_xfer;
     for (i = 0; i < TD_QUEUE; i++) {
-        killed += xhci_ep_nuke_one_xfer(&epctx->transfers[xferi]);
+        killed += xhci_ep_nuke_one_xfer(&epctx->transfers[xferi], report);
+        if (killed) {
+            report = 0; /* Only report once */
+        }
         epctx->transfers[xferi].packet.ep = NULL;
         xferi = (xferi + 1) % TD_QUEUE;
     }
@@ -1393,7 +1396,7 @@ static TRBCCode xhci_disable_ep(XHCIState *xhci, unsigned int slotid,
         return CC_SUCCESS;
     }
 
-    xhci_ep_nuke_xfers(xhci, slotid, epid);
+    xhci_ep_nuke_xfers(xhci, slotid, epid, 0);
 
     epctx = slot->eps[epid-1];
 
@@ -1435,7 +1438,7 @@ static TRBCCode xhci_stop_ep(XHCIState *xhci, unsigned int slotid,
         return CC_EP_NOT_ENABLED_ERROR;
     }
 
-    if (xhci_ep_nuke_xfers(xhci, slotid, epid) > 0) {
+    if (xhci_ep_nuke_xfers(xhci, slotid, epid, CC_STOPPED) > 0) {
         fprintf(stderr, "xhci: FIXME: endpoint stopped w/ xfers running, "
                 "data might be lost\n");
     }
@@ -1480,7 +1483,7 @@ static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigned int slotid,
         return CC_CONTEXT_STATE_ERROR;
     }
 
-    if (xhci_ep_nuke_xfers(xhci, slotid, epid) > 0) {
+    if (xhci_ep_nuke_xfers(xhci, slotid, epid, 0) > 0) {
         fprintf(stderr, "xhci: FIXME: endpoint reset w/ xfers running, "
                 "data might be lost\n");
     }
@@ -1737,14 +1740,12 @@ static int xhci_complete_packet(XHCITransfer *xfer)
         xfer->running_async = 1;
         xfer->running_retry = 0;
         xfer->complete = 0;
-        xfer->cancelled = 0;
         return 0;
     } else if (xfer->packet.status == USB_RET_NAK) {
         trace_usb_xhci_xfer_nak(xfer);
         xfer->running_async = 0;
         xfer->running_retry = 1;
         xfer->complete = 0;
-        xfer->cancelled = 0;
         return 0;
     } else {
         xfer->running_async = 0;
@@ -2475,7 +2476,7 @@ static void xhci_detach_slot(XHCIState *xhci, USBPort *uport)
 
     for (ep = 0; ep < 31; ep++) {
         if (xhci->slots[slot].eps[ep]) {
-            xhci_ep_nuke_xfers(xhci, slot+1, ep+1);
+            xhci_ep_nuke_xfers(xhci, slot + 1, ep + 1, 0);
         }
     }
     xhci->slots[slot].uport = NULL;
@@ -3290,7 +3291,7 @@ static void xhci_complete(USBPort *port, USBPacket *packet)
     XHCITransfer *xfer = container_of(packet, XHCITransfer, packet);
 
     if (packet->status == USB_RET_REMOVE_FROM_QUEUE) {
-        xhci_ep_nuke_one_xfer(xfer);
+        xhci_ep_nuke_one_xfer(xfer, 0);
         return;
     }
     xhci_complete_packet(xfer);
@@ -3433,8 +3434,6 @@ static int usb_xhci_initfn(struct PCIDevice *dev)
 
     xhci->mfwrap_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, xhci_mfwrap_timer, xhci);
 
-    xhci->irq = dev->irq[0];
-
     memory_region_init(&xhci->mem, OBJECT(xhci), "xhci", LEN_REGS);
     memory_region_init_io(&xhci->mem_cap, OBJECT(xhci), &xhci_cap_ops, xhci,
                           "capabilities", LEN_CAP);
index 128955dd92a0d9afe958c99d2ce089638440705c..fd320cd8aae1ecfae9f82791d7b02138db0b1036 100644 (file)
@@ -137,6 +137,7 @@ static QTAILQ_HEAD(, USBHostDevice) hostdevs =
 static void usb_host_auto_check(void *unused);
 static void usb_host_release_interfaces(USBHostDevice *s);
 static void usb_host_nodev(USBHostDevice *s);
+static void usb_host_detach_kernel(USBHostDevice *s);
 static void usb_host_attach_kernel(USBHostDevice *s);
 
 /* ------------------------------------------------------------------------ */
@@ -787,10 +788,13 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev)
         goto fail;
     }
 
-    libusb_get_device_descriptor(dev, &s->ddesc);
     s->dev     = dev;
     s->bus_num = bus_num;
     s->addr    = addr;
+
+    usb_host_detach_kernel(s);
+
+    libusb_get_device_descriptor(dev, &s->ddesc);
     usb_host_get_port(s->dev, s->port, sizeof(s->port));
 
     usb_ep_init(udev);
@@ -992,15 +996,14 @@ static int usb_host_claim_interfaces(USBHostDevice *s, int configuration)
     udev->ninterfaces   = 0;
     udev->configuration = 0;
 
-    if (configuration == 0) {
-        /* address state - ignore */
-        return USB_RET_SUCCESS;
-    }
-
     usb_host_detach_kernel(s);
 
     rc = libusb_get_active_config_descriptor(s->dev, &conf);
     if (rc != 0) {
+        if (rc == LIBUSB_ERROR_NOT_FOUND) {
+            /* address state - ignore */
+            return USB_RET_SUCCESS;
+        }
         return USB_RET_STALL;
     }
 
@@ -1052,7 +1055,6 @@ static void usb_host_set_config(USBHostDevice *s, int config, USBPacket *p)
     trace_usb_host_set_config(s->bus_num, s->addr, config);
 
     usb_host_release_interfaces(s);
-    usb_host_detach_kernel(s);
     rc = libusb_set_configuration(s->dh, config);
     if (rc != 0) {
         usb_host_libusb_error("libusb_set_configuration", rc);
@@ -1256,16 +1258,14 @@ static void usb_host_flush_ep_queue(USBDevice *dev, USBEndpoint *ep)
 static void usb_host_handle_reset(USBDevice *udev)
 {
     USBHostDevice *s = USB_HOST_DEVICE(udev);
+    int rc;
 
     trace_usb_host_reset(s->bus_num, s->addr);
 
-    if (udev->configuration == 0) {
-        return;
+    rc = libusb_reset_device(s->dh);
+    if (rc != 0) {
+        usb_host_nodev(s);
     }
-    usb_host_release_interfaces(s);
-    libusb_reset_device(s->dh);
-    usb_host_claim_interfaces(s, 0);
-    usb_host_ep_update(s);
 }
 
 /*
index 482580259848e656ee38ae1ab3e0a775864ce42c..7647be8a3c8d1d1518ba9cbc45168941a0aeb2dd 100644 (file)
@@ -116,7 +116,7 @@ static void virtio_pci_notify(DeviceState *d, uint16_t vector)
     if (msix_enabled(&proxy->pci_dev))
         msix_notify(&proxy->pci_dev, vector);
     else
-        qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1);
+        pci_set_irq(&proxy->pci_dev, proxy->vdev->isr & 1);
 }
 
 static void virtio_pci_save_config(DeviceState *d, QEMUFile *f)
@@ -362,7 +362,7 @@ static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
         /* reading from the ISR also clears it. */
         ret = vdev->isr;
         vdev->isr = 0;
-        qemu_set_irq(proxy->pci_dev.irq[0], 0);
+        pci_irq_deassert(&proxy->pci_dev);
         break;
     case VIRTIO_MSI_CONFIG_VECTOR:
         ret = vdev->config_vector;
index ebe0d24182cabbe01ee75e603765556e52883fb0..480dfbf9dadf31cdca8521dd34aabcbe75656cf6 100644 (file)
@@ -153,7 +153,7 @@ struct MemoryRegion {
     bool flush_coalesced_mmio;
     MemoryRegion *alias;
     hwaddr alias_offset;
-    unsigned priority;
+    int priority;
     bool may_overlap;
     QTAILQ_HEAD(subregions, MemoryRegion) subregions;
     QTAILQ_ENTRY(MemoryRegion) subregions_link;
@@ -779,7 +779,7 @@ void memory_region_add_subregion(MemoryRegion *mr,
 void memory_region_add_subregion_overlap(MemoryRegion *mr,
                                          hwaddr offset,
                                          MemoryRegion *subregion,
-                                         unsigned priority);
+                                         int priority);
 
 /**
  * memory_region_get_ram_addr: Get the ram address associated with a memory
index 51733d33903f2a329df59e59de29fe91b7a9d2dd..6bbcb1750dbabbed33622e1d04f5e29c8fc14657 100644 (file)
@@ -165,6 +165,10 @@ extern int acpi_enabled;
 extern char unsigned *acpi_tables;
 extern size_t acpi_tables_len;
 
+uint8_t *acpi_table_first(void);
+uint8_t *acpi_table_next(uint8_t *current);
+unsigned acpi_table_len(void *current);
 void acpi_table_add(const QemuOpts *opts, Error **errp);
+void acpi_table_add_builtin(const QemuOpts *opts, Error **errp);
 
 #endif /* !QEMU_HW_ACPI_H */
index b1fe71faf5314116f4da125b0c09e95671016825..82fcf9f2ebc5264454ba9cfffdfaee551309cedf 100644 (file)
@@ -49,4 +49,6 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base);
 extern const VMStateDescription vmstate_ich9_pm;
 
+void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp);
+
 #endif /* HW_ACPI_ICH9_H */
diff --git a/include/hw/acpi/piix4.h b/include/hw/acpi/piix4.h
new file mode 100644 (file)
index 0000000..65e6fd7
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef HW_ACPI_PIIX4_H
+#define HW_ACPI_PIIX4_H
+
+#include "qemu/typedefs.h"
+
+Object *piix4_pm_find(void);
+
+#endif
index c5f637bffd9b8c048938a6b50636b4a076fb4a01..4a68b359a6c9150dc7ebc9a3c67b28a318eba426 100644 (file)
@@ -66,6 +66,8 @@ typedef struct ICH9LPCState {
     qemu_irq *ioapic;
 } ICH9LPCState;
 
+Object *ich9_lpc_find(void);
+
 #define Q35_MASK(bit, ms_bit, ls_bit) \
 ((uint##bit##_t)(((1ULL << ((ms_bit) + 1)) - 1) & ~((1ULL << ls_bit) - 1)))
 
index 60838390848546be44c0c1e918ad473a4b72ef89..03cc0ba0f75c458cc64fd77d65ea28df2162cf77 100644 (file)
@@ -9,6 +9,9 @@
 #include "hw/i386/ioapic.h"
 
 #include "qemu/range.h"
+#include "qemu/bitmap.h"
+#include "sysemu/sysemu.h"
+#include "hw/pci/pci.h"
 
 /* PC-style peripherals (also used by other machines).  */
 
@@ -17,10 +20,27 @@ typedef struct PcPciInfo {
     Range w64;
 } PcPciInfo;
 
+#define ACPI_PM_PROP_S3_DISABLED "disable_s3"
+#define ACPI_PM_PROP_S4_DISABLED "disable_s4"
+#define ACPI_PM_PROP_S4_VAL "s4_val"
+#define ACPI_PM_PROP_SCI_INT "sci_int"
+#define ACPI_PM_PROP_ACPI_ENABLE_CMD "acpi_enable_cmd"
+#define ACPI_PM_PROP_ACPI_DISABLE_CMD "acpi_disable_cmd"
+#define ACPI_PM_PROP_PM_IO_BASE "pm_io_base"
+#define ACPI_PM_PROP_GPE0_BLK "gpe0_blk"
+#define ACPI_PM_PROP_GPE0_BLK_LEN "gpe0_blk_len"
+
 struct PcGuestInfo {
     bool has_pci_info;
     bool isapc_ram_fw;
+    hwaddr ram_size;
+    unsigned apic_id_limit;
+    bool apic_xrupt_override;
+    uint64_t numa_nodes;
+    uint64_t *node_mem;
+    uint64_t *node_cpu;
     FWCfgState *fw_cfg;
+    bool has_acpi_build;
 };
 
 /* parallel.c */
@@ -173,6 +193,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn,
                     MemoryRegion *pci_memory,
                     MemoryRegion *ram_memory);
 
+PCIBus *find_i440fx(void);
 /* piix4.c */
 extern PCIDevice *piix4_dev;
 int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn);
@@ -215,6 +236,7 @@ void pc_system_firmware_init(MemoryRegion *rom_memory,
 
 /* pvpanic.c */
 void pvpanic_init(ISABus *bus);
+uint16_t pvpanic_port(void);
 
 /* e820 types */
 #define E820_RAM        1
index 610e6b76236e8c2ee9b56f1c32a7617f2f2c7881..d08bc02a0d1065531969d080903c8358fad9ad8e 100644 (file)
@@ -30,6 +30,12 @@ static inline void qemu_irq_pulse(qemu_irq irq)
  */
 qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n);
 
+/*
+ * Allocates a single IRQ. The irq is assigned with a handler, an opaque
+ * data and the interrupt number.
+ */
+qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n);
+
 /* Extends an Array of IRQs. Old IRQs have their handlers and opaque data
  * preserved. New IRQs are assigned the argument handler and opaque data.
  */
@@ -37,6 +43,7 @@ qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler,
                                 void *opaque, int n);
 
 void qemu_free_irqs(qemu_irq *s);
+void qemu_free_irq(qemu_irq irq);
 
 /* Returns a new IRQ with opposite polarity.  */
 qemu_irq qemu_irq_invert(qemu_irq irq);
index 61457360f6bfcf0c550844681c692b9dbc394b34..58eca9832bb2468d03e920418eda416b724886b5 100644 (file)
@@ -40,11 +40,13 @@ extern bool rom_file_in_ram;
 
 int rom_add_file(const char *file, const char *fw_dir,
                  hwaddr addr, int32_t bootindex);
-int rom_add_blob(const char *name, const void *blob, size_t len,
-                 hwaddr addr);
+void *rom_add_blob(const char *name, const void *blob, size_t len,
+                   hwaddr addr, const char *fw_file_name,
+                   FWCfgReadCallback fw_callback, void *callback_opaque);
 int rom_add_elf_program(const char *name, void *data, size_t datasize,
                         size_t romsize, hwaddr addr);
 int rom_load_all(void);
+void rom_load_done(void);
 void rom_set_fw(FWCfgState *f);
 int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
 void *rom_ptr(hwaddr addr);
@@ -53,7 +55,7 @@ void do_info_roms(Monitor *mon, const QDict *qdict);
 #define rom_add_file_fixed(_f, _a, _i)          \
     rom_add_file(_f, NULL, _a, _i)
 #define rom_add_blob_fixed(_f, _b, _l, _a)      \
-    rom_add_blob(_f, _b, _l, _a)
+    (rom_add_blob(_f, _b, _l, _a, NULL, NULL, NULL) ? 0 : -1)
 
 #define PC_ROM_MIN_VGA     0xc0000
 #define PC_ROM_MIN_OPTION  0xc8000
diff --git a/include/hw/misc/arm_integrator_debug.h b/include/hw/misc/arm_integrator_debug.h
new file mode 100644 (file)
index 0000000..37789b6
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * ARM Integrator Board Debug, switch and LED section
+ *
+ * Browse the data sheet:
+ *
+ *    http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0159b/Babbfijf.html
+ *
+ * Copyright (c) 2013 Alex Bennée <alex@bennee.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef QEMU_INTEGRATOR_DEBUG_H
+#define QEMU_INTEGRATOR_DEBUG_H
+
+#define TYPE_INTEGRATOR_DEBUG "integrator_debug"
+
+#endif
index f60dd676c8c696aaa76676c77d329cb901159e95..72b1549dc4ad85dc5678710af57ef5557b011867 100644 (file)
 
 #define FW_CFG_INVALID          0xffff
 
+#define FW_CFG_MAX_FILE_PATH    56
+
 #ifndef NO_QEMU_PROTOS
 typedef struct FWCfgFile {
     uint32_t  size;        /* file size */
     uint16_t  select;      /* write this to 0x510 to read it */
     uint16_t  reserved;
-    char      name[56];
+    char      name[FW_CFG_MAX_FILE_PATH];
 } FWCfgFile;
 
 typedef struct FWCfgFiles {
@@ -60,6 +62,7 @@ typedef struct FWCfgFiles {
 } FWCfgFiles;
 
 typedef void (*FWCfgCallback)(void *opaque, uint8_t *data);
+typedef void (*FWCfgReadCallback)(void *opaque, uint32_t offset);
 
 void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len);
 void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value);
@@ -70,6 +73,9 @@ void fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
                          void *callback_opaque, void *data, size_t len);
 void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data,
                      size_t len);
+void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
+                              FWCfgReadCallback callback, void *callback_opaque,
+                              void *data, size_t len);
 FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
                         hwaddr crl_addr, hwaddr data_addr);
 
index 56de92ede2f41407d03660dbb945db31e6b7a4bf..aee91aa038e9d95d53b24591ec866597135992a3 100644 (file)
@@ -156,4 +156,6 @@ typedef struct Q35PCIHost {
 #define MCH_PCIE_DEV                           1
 #define MCH_PCIE_FUNC                          0
 
+uint64_t mch_mcfg_base(void);
+
 #endif /* HW_Q35_H */
index 4b90e5d00b26d04947fa422a038f21c2cd3ccfdd..37ffa531199db4fd382602ea1fed1fee56116de3 100644 (file)
@@ -247,9 +247,6 @@ struct PCIDevice {
     PCIConfigReadFunc *config_read;
     PCIConfigWriteFunc *config_write;
 
-    /* IRQ objects for the INTA-INTD pins.  */
-    qemu_irq *irq;
-
     /* Legacy PCI VGA regions */
     MemoryRegion *vga_regions[QEMU_PCI_VGA_NUM_REGIONS];
     bool has_vga;
@@ -632,6 +629,29 @@ PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn,
 PCIDevice *pci_create(PCIBus *bus, int devfn, const char *name);
 PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name);
 
+qemu_irq pci_allocate_irq(PCIDevice *pci_dev);
+void pci_set_irq(PCIDevice *pci_dev, int level);
+
+static inline void pci_irq_assert(PCIDevice *pci_dev)
+{
+    pci_set_irq(pci_dev, 1);
+}
+
+static inline void pci_irq_deassert(PCIDevice *pci_dev)
+{
+    pci_set_irq(pci_dev, 0);
+}
+
+/*
+ * FIXME: PCI does not work this way.
+ * All the callers to this method should be fixed.
+ */
+static inline void pci_irq_pulse(PCIDevice *pci_dev)
+{
+    pci_irq_assert(pci_dev);
+    pci_irq_deassert(pci_dev);
+}
+
 static inline int pci_is_express(const PCIDevice *d)
 {
     return d->cap_present & QEMU_PCI_CAP_EXPRESS;
index 9df17885eca2555fb23f2486bfdc7bca199ea4dc..2ad5edbde9c79d58d56e686d78b4630463dca78d 100644 (file)
@@ -23,6 +23,7 @@ struct PCIBus {
     PCIDevice *parent_dev;
     MemoryRegion *address_space_mem;
     MemoryRegion *address_space_io;
+    MemoryRegion master_abort_mem;
 
     QLIST_HEAD(, PCIBus) child; /* this will be replaced by qdev later */
     QLIST_ENTRY(PCIBus) sibling;/* this will be replaced by qdev later */
index c010007c5e20a2676111ef11780a2717ca075383..1966169553f94b473c381331eace3421c9d97a6f 100644 (file)
@@ -64,15 +64,6 @@ struct PCIExpressDevice {
     uint8_t exp_cap;
 
     /* SLOT */
-    unsigned int hpev_intx;     /* INTx for hot plug event (0-3:INT[A-D]#)
-                                 * default is 0 = INTA#
-                                 * If the chip wants to use other interrupt
-                                 * line, initialize this member with the
-                                 * desired number.
-                                 * If the chip dynamically changes this member,
-                                 * also initialize it when loaded as
-                                 * appropreately.
-                                 */
     bool hpev_notified; /* Logical AND of conditions for hot plug event.
                          Following 6.7.3.4:
                          Software Notification of Hot-Plug Events, an interrupt
@@ -82,15 +73,6 @@ struct PCIExpressDevice {
     /* AER */
     uint16_t aer_cap;
     PCIEAERLog aer_log;
-    unsigned int aer_intx;      /* INTx for error reporting
-                                 * default is 0 = INTA#
-                                 * If the chip wants to use other interrupt
-                                 * line, initialize this member with the
-                                 * desired number.
-                                 * If the chip dynamically changes this member,
-                                 * also initialize it when loaded as
-                                 * appropreately.
-                                 */
 };
 
 /* PCI express capability helper functions */
index 1228e36cb260106c9c4133f2c6e51ccbfa2aa633..acca45ed586b2d42955caf2d0f642071cb565fed 100644 (file)
 #define PCIE_HOST_BRIDGE(obj) \
     OBJECT_CHECK(PCIExpressHost, (obj), TYPE_PCIE_HOST_BRIDGE)
 
+#define PCIE_HOST_MCFG_BASE "MCFG"
+#define PCIE_HOST_MCFG_SIZE "mcfg_size"
+
+/* pcie_host::base_addr == PCIE_BASE_ADDR_UNMAPPED when it isn't mapped. */
+#define PCIE_BASE_ADDR_UNMAPPED  ((hwaddr)-1ULL)
+
 struct PCIExpressHost {
     PCIHostState pci;
 
@@ -51,4 +57,25 @@ void pcie_host_mmcfg_update(PCIExpressHost *e,
                             hwaddr addr,
                             uint32_t size);
 
+/*
+ * PCI express ECAM (Enhanced Configuration Address Mapping) format.
+ * AKA mmcfg address
+ * bit 20 - 28: bus number
+ * bit 15 - 19: device number
+ * bit 12 - 14: function number
+ * bit  0 - 11: offset in configuration space of a given device
+ */
+#define PCIE_MMCFG_SIZE_MAX             (1ULL << 28)
+#define PCIE_MMCFG_SIZE_MIN             (1ULL << 20)
+#define PCIE_MMCFG_BUS_BIT              20
+#define PCIE_MMCFG_BUS_MASK             0x1ff
+#define PCIE_MMCFG_DEVFN_BIT            12
+#define PCIE_MMCFG_DEVFN_MASK           0xff
+#define PCIE_MMCFG_CONFOFFSET_MASK      0xfff
+#define PCIE_MMCFG_BUS(addr)            (((addr) >> PCIE_MMCFG_BUS_BIT) & \
+                                         PCIE_MMCFG_BUS_MASK)
+#define PCIE_MMCFG_DEVFN(addr)          (((addr) >> PCIE_MMCFG_DEVFN_BIT) & \
+                                         PCIE_MMCFG_DEVFN_MASK)
+#define PCIE_MMCFG_CONFOFFSET(addr)     ((addr) & PCIE_MMCFG_CONFOFFSET_MASK)
+
 #endif /* PCIE_HOST_H */
index bb50a877ccf56764c78d5c717451c51f64bf0ff7..f5aaa05ee3b55814e117ad8ad949f8db747bca2d 100644 (file)
@@ -68,7 +68,7 @@ void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size);
 void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq);
 void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr);
 void sysbus_mmio_map_overlap(SysBusDevice *dev, int n, hwaddr addr,
-                             unsigned priority);
+                             int priority);
 void sysbus_add_io(SysBusDevice *dev, hwaddr addr,
                    MemoryRegion *mem);
 void sysbus_del_io(SysBusDevice *dev, MemoryRegion *mem);
index 757f79fdd2506bfeb7bc62ca81b2b6b504e884c7..ab44bd31fd4c9d7567d4f358f5a3a12e6c7a2f8b 100644 (file)
@@ -71,4 +71,6 @@ struct hpet_fw_config
 } QEMU_PACKED;
 
 extern struct hpet_fw_config hpet_cfg;
+
+bool hpet_find(void);
 #endif
index 1a7b71aba532e96f5a4d2293b0a0769e60cfe269..d02172adcac3f0b0646f50fe2b826d2140882a48 100644 (file)
@@ -18,9 +18,9 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include "qemu/queue.h"
+#include "qapi/error.h"
 
 struct Visitor;
-struct Error;
 
 struct TypeImpl;
 typedef struct TypeImpl *Type;
@@ -301,7 +301,7 @@ typedef void (ObjectPropertyAccessor)(Object *obj,
                                       struct Visitor *v,
                                       void *opaque,
                                       const char *name,
-                                      struct Error **errp);
+                                      Error **errp);
 
 /**
  * ObjectPropertyRelease:
@@ -790,9 +790,30 @@ void object_property_add(Object *obj, const char *name, const char *type,
                          ObjectPropertyAccessor *get,
                          ObjectPropertyAccessor *set,
                          ObjectPropertyRelease *release,
-                         void *opaque, struct Error **errp);
+                         void *opaque, Error **errp);
 
-void object_property_del(Object *obj, const char *name, struct Error **errp);
+void object_property_del(Object *obj, const char *name, Error **errp);
+
+/**
+ * object_property_add_uint8_ptr:
+ * object_property_add_uint16_ptr:
+ * object_property_add_uint32_ptr:
+ * object_property_add_uint64_ptr:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @v: pointer to value
+ *
+ * Add an integer property in memory.  This function will add a
+ * property of the appropriate type.
+ */
+void object_property_add_uint8_ptr(Object *obj, const char *name,
+                                   const uint8_t *v, Error **errp);
+void object_property_add_uint16_ptr(Object *obj, const char *name,
+                                    const uint16_t *v, Error **errp);
+void object_property_add_uint32_ptr(Object *obj, const char *name,
+                                    const uint32_t *v, Error **errp);
+void object_property_add_uint64_ptr(Object *obj, const char *name,
+                                    const uint64_t *v, Error **Errp);
 
 /**
  * object_property_find:
@@ -803,7 +824,7 @@ void object_property_del(Object *obj, const char *name, struct Error **errp);
  * Look up a property for an object and return its #ObjectProperty if found.
  */
 ObjectProperty *object_property_find(Object *obj, const char *name,
-                                     struct Error **errp);
+                                     Error **errp);
 
 void object_unparent(Object *obj);
 
@@ -818,7 +839,7 @@ void object_unparent(Object *obj);
  * Reads a property from a object.
  */
 void object_property_get(Object *obj, struct Visitor *v, const char *name,
-                         struct Error **errp);
+                         Error **errp);
 
 /**
  * object_property_set_str:
@@ -829,7 +850,7 @@ void object_property_get(Object *obj, struct Visitor *v, const char *name,
  * Writes a string value to a property.
  */
 void object_property_set_str(Object *obj, const char *value,
-                             const char *name, struct Error **errp);
+                             const char *name, Error **errp);
 
 /**
  * object_property_get_str:
@@ -842,7 +863,7 @@ void object_property_set_str(Object *obj, const char *value,
  * The caller should free the string.
  */
 char *object_property_get_str(Object *obj, const char *name,
-                              struct Error **errp);
+                              Error **errp);
 
 /**
  * object_property_set_link:
@@ -853,7 +874,7 @@ char *object_property_get_str(Object *obj, const char *name,
  * Writes an object's canonical path to a property.
  */
 void object_property_set_link(Object *obj, Object *value,
-                              const char *name, struct Error **errp);
+                              const char *name, Error **errp);
 
 /**
  * object_property_get_link:
@@ -866,7 +887,7 @@ void object_property_set_link(Object *obj, Object *value,
  * string or not a valid object path).
  */
 Object *object_property_get_link(Object *obj, const char *name,
-                                 struct Error **errp);
+                                 Error **errp);
 
 /**
  * object_property_set_bool:
@@ -877,7 +898,7 @@ Object *object_property_get_link(Object *obj, const char *name,
  * Writes a bool value to a property.
  */
 void object_property_set_bool(Object *obj, bool value,
-                              const char *name, struct Error **errp);
+                              const char *name, Error **errp);
 
 /**
  * object_property_get_bool:
@@ -889,7 +910,7 @@ void object_property_set_bool(Object *obj, bool value,
  * an error occurs (including when the property value is not a bool).
  */
 bool object_property_get_bool(Object *obj, const char *name,
-                              struct Error **errp);
+                              Error **errp);
 
 /**
  * object_property_set_int:
@@ -900,7 +921,7 @@ bool object_property_get_bool(Object *obj, const char *name,
  * Writes an integer value to a property.
  */
 void object_property_set_int(Object *obj, int64_t value,
-                             const char *name, struct Error **errp);
+                             const char *name, Error **errp);
 
 /**
  * object_property_get_int:
@@ -912,7 +933,7 @@ void object_property_set_int(Object *obj, int64_t value,
  * an error occurs (including when the property value is not an integer).
  */
 int64_t object_property_get_int(Object *obj, const char *name,
-                                struct Error **errp);
+                                Error **errp);
 
 /**
  * object_property_set:
@@ -926,7 +947,7 @@ int64_t object_property_get_int(Object *obj, const char *name,
  * Writes a property to a object.
  */
 void object_property_set(Object *obj, struct Visitor *v, const char *name,
-                         struct Error **errp);
+                         Error **errp);
 
 /**
  * object_property_parse:
@@ -938,7 +959,7 @@ void object_property_set(Object *obj, struct Visitor *v, const char *name,
  * Parses a string and writes the result into a property of an object.
  */
 void object_property_parse(Object *obj, const char *string,
-                           const char *name, struct Error **errp);
+                           const char *name, Error **errp);
 
 /**
  * object_property_print:
@@ -950,7 +971,7 @@ void object_property_parse(Object *obj, const char *string,
  * caller shall free the string.
  */
 char *object_property_print(Object *obj, const char *name,
-                            struct Error **errp);
+                            Error **errp);
 
 /**
  * object_property_get_type:
@@ -961,7 +982,7 @@ char *object_property_print(Object *obj, const char *name,
  * Returns:  The type name of the property.
  */
 const char *object_property_get_type(Object *obj, const char *name,
-                                     struct Error **errp);
+                                     Error **errp);
 
 /**
  * object_get_root:
@@ -1054,7 +1075,7 @@ Object *object_resolve_path_component(Object *parent, const gchar *part);
  * The child object itself can be retrieved using object_property_get_link().
  */
 void object_property_add_child(Object *obj, const char *name,
-                               Object *child, struct Error **errp);
+                               Object *child, Error **errp);
 
 /**
  * object_property_add_link:
@@ -1077,7 +1098,7 @@ void object_property_add_child(Object *obj, const char *name,
  */
 void object_property_add_link(Object *obj, const char *name,
                               const char *type, Object **child,
-                              struct Error **errp);
+                              Error **errp);
 
 /**
  * object_property_add_str:
@@ -1092,9 +1113,9 @@ void object_property_add_link(Object *obj, const char *name,
  * property of type 'string'.
  */
 void object_property_add_str(Object *obj, const char *name,
-                             char *(*get)(Object *, struct Error **),
-                             void (*set)(Object *, const char *, struct Error **),
-                             struct Error **errp);
+                             char *(*get)(Object *, Error **),
+                             void (*set)(Object *, const char *, Error **),
+                             Error **errp);
 
 /**
  * object_property_add_bool:
@@ -1108,9 +1129,9 @@ void object_property_add_str(Object *obj, const char *name,
  * property of type 'bool'.
  */
 void object_property_add_bool(Object *obj, const char *name,
-                              bool (*get)(Object *, struct Error **),
-                              void (*set)(Object *, bool, struct Error **),
-                              struct Error **errp);
+                              bool (*get)(Object *, Error **),
+                              void (*set)(Object *, bool, Error **),
+                              Error **errp);
 
 /**
  * object_child_foreach:
index 7f1f2661a5ee082a519499862d3f38399a51617e..28f64491d06fcbb217928733491dbb5e6547da9d 100644 (file)
--- a/memory.c
+++ b/memory.c
@@ -1473,7 +1473,7 @@ void memory_region_add_subregion(MemoryRegion *mr,
 void memory_region_add_subregion_overlap(MemoryRegion *mr,
                                          hwaddr offset,
                                          MemoryRegion *subregion,
-                                         unsigned priority)
+                                         int priority)
 {
     subregion->may_overlap = true;
     subregion->priority = priority;
@@ -1506,7 +1506,7 @@ void memory_region_set_enabled(MemoryRegion *mr, bool enabled)
 void memory_region_set_address(MemoryRegion *mr, hwaddr addr)
 {
     MemoryRegion *parent = mr->parent;
-    unsigned priority = mr->priority;
+    int priority = mr->priority;
     bool may_overlap = mr->may_overlap;
 
     if (addr == mr->addr || !parent) {
index 74f3f1ba603c60390f767ab0720389d1d2eed10a..0ae99dc270ee23c9129fa65b74008c2cd82707b3 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -511,7 +511,6 @@ static const char *monitor_event_names[] = {
 QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX)
 
 MonitorEventState monitor_event_state[QEVENT_MAX];
-QemuMutex monitor_event_state_lock;
 
 /*
  * Emits the event to every monitor instance
@@ -543,7 +542,6 @@ monitor_protocol_event_queue(MonitorEvent event,
     int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
     assert(event < QEVENT_MAX);
 
-    qemu_mutex_lock(&monitor_event_state_lock);
     evstate = &(monitor_event_state[event]);
     trace_monitor_protocol_event_queue(event,
                                        data,
@@ -576,7 +574,6 @@ monitor_protocol_event_queue(MonitorEvent event,
             evstate->last = now;
         }
     }
-    qemu_mutex_unlock(&monitor_event_state_lock);
 }
 
 
@@ -589,7 +586,6 @@ static void monitor_protocol_event_handler(void *opaque)
     MonitorEventState *evstate = opaque;
     int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
 
-    qemu_mutex_lock(&monitor_event_state_lock);
 
     trace_monitor_protocol_event_handler(evstate->event,
                                          evstate->data,
@@ -601,7 +597,6 @@ static void monitor_protocol_event_handler(void *opaque)
         evstate->data = NULL;
     }
     evstate->last = now;
-    qemu_mutex_unlock(&monitor_event_state_lock);
 }
 
 
@@ -638,7 +633,6 @@ monitor_protocol_event_throttle(MonitorEvent event,
  * and initialize state */
 static void monitor_protocol_event_init(void)
 {
-    qemu_mutex_init(&monitor_event_state_lock);
     /* Limit RTC & BALLOON events to 1 per second */
     monitor_protocol_event_throttle(QEVENT_RTC_CHANGE, 1000);
     monitor_protocol_event_throttle(QEVENT_BALLOON_CHANGE, 1000);
index e90e3827d90ff3115fd4b74d5cd962822da80e53..b617f265e7a1d3dca2135bfbea3643d43860c629 100644 (file)
@@ -1344,6 +1344,66 @@ static char *qdev_get_type(Object *obj, Error **errp)
     return g_strdup(object_get_typename(obj));
 }
 
+static void property_get_uint8_ptr(Object *obj, Visitor *v,
+                                   void *opaque, const char *name,
+                                   Error **errp)
+{
+    uint8_t value = *(uint8_t *)opaque;
+    visit_type_uint8(v, &value, name, errp);
+}
+
+static void property_get_uint16_ptr(Object *obj, Visitor *v,
+                                   void *opaque, const char *name,
+                                   Error **errp)
+{
+    uint16_t value = *(uint16_t *)opaque;
+    visit_type_uint16(v, &value, name, errp);
+}
+
+static void property_get_uint32_ptr(Object *obj, Visitor *v,
+                                   void *opaque, const char *name,
+                                   Error **errp)
+{
+    uint32_t value = *(uint32_t *)opaque;
+    visit_type_uint32(v, &value, name, errp);
+}
+
+static void property_get_uint64_ptr(Object *obj, Visitor *v,
+                                   void *opaque, const char *name,
+                                   Error **errp)
+{
+    uint64_t value = *(uint64_t *)opaque;
+    visit_type_uint64(v, &value, name, errp);
+}
+
+void object_property_add_uint8_ptr(Object *obj, const char *name,
+                                   const uint8_t *v, Error **errp)
+{
+    object_property_add(obj, name, "uint8", property_get_uint8_ptr,
+                        NULL, NULL, (void *)v, errp);
+}
+
+void object_property_add_uint16_ptr(Object *obj, const char *name,
+                                    const uint16_t *v, Error **errp)
+{
+    object_property_add(obj, name, "uint16", property_get_uint16_ptr,
+                        NULL, NULL, (void *)v, errp);
+}
+
+void object_property_add_uint32_ptr(Object *obj, const char *name,
+                                    const uint32_t *v, Error **errp)
+{
+    object_property_add(obj, name, "uint32", property_get_uint32_ptr,
+                        NULL, NULL, (void *)v, errp);
+}
+
+void object_property_add_uint64_ptr(Object *obj, const char *name,
+                                    const uint64_t *v, Error **errp)
+{
+    object_property_add(obj, name, "uint64", property_get_uint64_ptr,
+                        NULL, NULL, (void *)v, errp);
+}
+
 static void object_instance_init(Object *obj)
 {
     object_property_add_str(obj, "type", qdev_get_type, NULL, NULL);
diff --git a/scripts/acpi_extract.py b/scripts/acpi_extract.py
new file mode 100755 (executable)
index 0000000..22ea468
--- /dev/null
@@ -0,0 +1,362 @@
+#!/usr/bin/python
+# Copyright (C) 2011 Red Hat, Inc., Michael S. Tsirkin <mst@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, see <http://www.gnu.org/licenses/>.
+
+# Process mixed ASL/AML listing (.lst file) produced by iasl -l
+# Locate and execute ACPI_EXTRACT directives, output offset info
+#
+# Documentation of ACPI_EXTRACT_* directive tags:
+#
+# These directive tags output offset information from AML for BIOS runtime
+# table generation.
+# Each directive is of the form:
+# ACPI_EXTRACT_<TYPE> <array_name> <Operator> (...)
+# and causes the extractor to create an array
+# named <array_name> with offset, in the generated AML,
+# of an object of a given type in the following <Operator>.
+#
+# A directive must fit on a single code line.
+#
+# Object type in AML is verified, a mismatch causes a build failure.
+#
+# Directives and operators currently supported are:
+# ACPI_EXTRACT_NAME_DWORD_CONST - extract a Dword Const object from Name()
+# ACPI_EXTRACT_NAME_WORD_CONST - extract a Word Const object from Name()
+# ACPI_EXTRACT_NAME_BYTE_CONST - extract a Byte Const object from Name()
+# ACPI_EXTRACT_METHOD_STRING - extract a NameString from Method()
+# ACPI_EXTRACT_NAME_STRING - extract a NameString from Name()
+# ACPI_EXTRACT_PROCESSOR_START - start of Processor() block
+# ACPI_EXTRACT_PROCESSOR_STRING - extract a NameString from Processor()
+# ACPI_EXTRACT_PROCESSOR_END - offset at last byte of Processor() + 1
+# ACPI_EXTRACT_PKG_START - start of Package block
+#
+# ACPI_EXTRACT_ALL_CODE - create an array storing the generated AML bytecode
+#
+# ACPI_EXTRACT is not allowed anywhere else in code, except in comments.
+
+import re;
+import sys;
+import fileinput;
+
+aml = []
+asl = []
+output = {}
+debug = ""
+
+class asl_line:
+    line = None
+    lineno = None
+    aml_offset = None
+
+def die(diag):
+    sys.stderr.write("Error: %s; %s\n" % (diag, debug))
+    sys.exit(1)
+
+#Store an ASL command, matching AML offset, and input line (for debugging)
+def add_asl(lineno, line):
+    l = asl_line()
+    l.line = line
+    l.lineno = lineno
+    l.aml_offset = len(aml)
+    asl.append(l)
+
+#Store an AML byte sequence
+#Verify that offset output by iasl matches # of bytes so far
+def add_aml(offset, line):
+    o = int(offset, 16);
+    # Sanity check: offset must match size of code so far
+    if (o != len(aml)):
+        die("Offset 0x%x != 0x%x" % (o, len(aml)))
+    # Strip any trailing dots and ASCII dump after "
+    line = re.sub(r'\s*\.*\s*".*$',"", line)
+    # Strip traling whitespace
+    line = re.sub(r'\s+$',"", line)
+    # Strip leading whitespace
+    line = re.sub(r'^\s+',"", line)
+    # Split on whitespace
+    code = re.split(r'\s+', line)
+    for c in code:
+        # Require a legal hex number, two digits
+        if (not(re.search(r'^[0-9A-Fa-f][0-9A-Fa-f]$', c))):
+            die("Unexpected octet %s" % c);
+        aml.append(int(c, 16));
+
+# Process aml bytecode array, decoding AML
+def aml_pkglen_bytes(offset):
+    # PkgLength can be multibyte. Bits 8-7 give the # of extra bytes.
+    pkglenbytes = aml[offset] >> 6;
+    return pkglenbytes + 1
+
+def aml_pkglen(offset):
+    pkgstart = offset
+    pkglenbytes = aml_pkglen_bytes(offset)
+    pkglen = aml[offset] & 0x3F
+    # If multibyte, first nibble only uses bits 0-3
+    if ((pkglenbytes > 1) and (pkglen & 0x30)):
+        die("PkgLen bytes 0x%x but first nibble 0x%x expected 0x0X" %
+            (pkglen, pkglen))
+    offset += 1
+    pkglenbytes -= 1
+    for i in range(pkglenbytes):
+        pkglen |= aml[offset + i] << (i * 8 + 4)
+    if (len(aml) < pkgstart + pkglen):
+        die("PckgLen 0x%x at offset 0x%x exceeds AML size 0x%x" %
+            (pkglen, offset, len(aml)))
+    return pkglen
+
+# Given method offset, find its NameString offset
+def aml_method_string(offset):
+    #0x14 MethodOp PkgLength NameString MethodFlags TermList
+    if (aml[offset] != 0x14):
+        die( "Method offset 0x%x: expected 0x14 actual 0x%x" %
+             (offset, aml[offset]));
+    offset += 1;
+    pkglenbytes = aml_pkglen_bytes(offset)
+    offset += pkglenbytes;
+    return offset;
+
+# Given name offset, find its NameString offset
+def aml_name_string(offset):
+    #0x08 NameOp NameString DataRef
+    if (aml[offset] != 0x08):
+        die( "Name offset 0x%x: expected 0x08 actual 0x%x" %
+             (offset, aml[offset]));
+    offset += 1
+    # Block Name Modifier. Skip it.
+    if (aml[offset] == 0x5c or aml[offset] == 0x5e):
+        offset += 1
+    return offset;
+
+# Given data offset, find 8 byte buffer offset
+def aml_data_buffer8(offset):
+    #0x08 NameOp NameString DataRef
+    expect = [0x11, 0x0B, 0x0A, 0x08]
+    if (aml[offset:offset+4] != expect):
+        die( "Name offset 0x%x: expected %s actual %s" %
+             (offset, aml[offset:offset+4], expect))
+    return offset + len(expect)
+
+# Given data offset, find dword const offset
+def aml_data_dword_const(offset):
+    #0x08 NameOp NameString DataRef
+    if (aml[offset] != 0x0C):
+        die( "Name offset 0x%x: expected 0x0C actual 0x%x" %
+             (offset, aml[offset]));
+    return offset + 1;
+
+# Given data offset, find word const offset
+def aml_data_word_const(offset):
+    #0x08 NameOp NameString DataRef
+    if (aml[offset] != 0x0B):
+        die( "Name offset 0x%x: expected 0x0B actual 0x%x" %
+             (offset, aml[offset]));
+    return offset + 1;
+
+# Given data offset, find byte const offset
+def aml_data_byte_const(offset):
+    #0x08 NameOp NameString DataRef
+    if (aml[offset] != 0x0A):
+        die( "Name offset 0x%x: expected 0x0A actual 0x%x" %
+             (offset, aml[offset]));
+    return offset + 1;
+
+# Find name'd buffer8
+def aml_name_buffer8(offset):
+    return aml_data_buffer8(aml_name_string(offset) + 4)
+
+# Given name offset, find dword const offset
+def aml_name_dword_const(offset):
+    return aml_data_dword_const(aml_name_string(offset) + 4)
+
+# Given name offset, find word const offset
+def aml_name_word_const(offset):
+    return aml_data_word_const(aml_name_string(offset) + 4)
+
+# Given name offset, find byte const offset
+def aml_name_byte_const(offset):
+    return aml_data_byte_const(aml_name_string(offset) + 4)
+
+def aml_device_start(offset):
+    #0x5B 0x82 DeviceOp PkgLength NameString
+    if ((aml[offset] != 0x5B) or (aml[offset + 1] != 0x82)):
+        die( "Name offset 0x%x: expected 0x5B 0x82 actual 0x%x 0x%x" %
+             (offset, aml[offset], aml[offset + 1]));
+    return offset
+
+def aml_device_string(offset):
+    #0x5B 0x82 DeviceOp PkgLength NameString
+    start = aml_device_start(offset)
+    offset += 2
+    pkglenbytes = aml_pkglen_bytes(offset)
+    offset += pkglenbytes
+    return offset
+
+def aml_device_end(offset):
+    start = aml_device_start(offset)
+    offset += 2
+    pkglenbytes = aml_pkglen_bytes(offset)
+    pkglen = aml_pkglen(offset)
+    return offset + pkglen
+
+def aml_processor_start(offset):
+    #0x5B 0x83 ProcessorOp PkgLength NameString ProcID
+    if ((aml[offset] != 0x5B) or (aml[offset + 1] != 0x83)):
+        die( "Name offset 0x%x: expected 0x5B 0x83 actual 0x%x 0x%x" %
+             (offset, aml[offset], aml[offset + 1]));
+    return offset
+
+def aml_processor_string(offset):
+    #0x5B 0x83 ProcessorOp PkgLength NameString ProcID
+    start = aml_processor_start(offset)
+    offset += 2
+    pkglenbytes = aml_pkglen_bytes(offset)
+    offset += pkglenbytes
+    return offset
+
+def aml_processor_end(offset):
+    start = aml_processor_start(offset)
+    offset += 2
+    pkglenbytes = aml_pkglen_bytes(offset)
+    pkglen = aml_pkglen(offset)
+    return offset + pkglen
+
+def aml_package_start(offset):
+    offset = aml_name_string(offset) + 4
+    # 0x12 PkgLength NumElements PackageElementList
+    if (aml[offset] != 0x12):
+        die( "Name offset 0x%x: expected 0x12 actual 0x%x" %
+             (offset, aml[offset]));
+    offset += 1
+    return offset + aml_pkglen_bytes(offset) + 1
+
+lineno = 0
+for line in fileinput.input():
+    # Strip trailing newline
+    line = line.rstrip();
+    # line number and debug string to output in case of errors
+    lineno = lineno + 1
+    debug = "input line %d: %s" % (lineno, line)
+    #ASL listing: space, then line#, then ...., then code
+    pasl = re.compile('^\s+([0-9]+)(:\s\s|\.\.\.\.)\s*')
+    m = pasl.search(line)
+    if (m):
+        add_asl(lineno, pasl.sub("", line));
+    # AML listing: offset in hex, then ...., then code
+    paml = re.compile('^([0-9A-Fa-f]+)(:\s\s|\.\.\.\.)\s*')
+    m = paml.search(line)
+    if (m):
+        add_aml(m.group(1), paml.sub("", line))
+
+# Now go over code
+# Track AML offset of a previous non-empty ASL command
+prev_aml_offset = -1
+for i in range(len(asl)):
+    debug = "input line %d: %s" % (asl[i].lineno, asl[i].line)
+
+    l = asl[i].line
+
+    # skip if not an extract directive
+    a = len(re.findall(r'ACPI_EXTRACT', l))
+    if (not a):
+        # If not empty, store AML offset. Will be used for sanity checks
+        # IASL seems to put {}. at random places in the listing.
+        # Ignore any non-words for the purpose of this test.
+        m = re.search(r'\w+', l)
+        if (m):
+                prev_aml_offset = asl[i].aml_offset
+        continue
+
+    if (a > 1):
+        die("Expected at most one ACPI_EXTRACT per line, actual %d" % a)
+
+    mext = re.search(r'''
+                      ^\s* # leading whitespace
+                      /\*\s* # start C comment
+                      (ACPI_EXTRACT_\w+) # directive: group(1)
+                      \s+ # whitspace separates directive from array name
+                      (\w+) # array name: group(2)
+                      \s*\*/ # end of C comment
+                      \s*$ # trailing whitespace
+                      ''', l, re.VERBOSE)
+    if (not mext):
+        die("Stray ACPI_EXTRACT in input")
+
+    # previous command must have produced some AML,
+    # otherwise we are in a middle of a block
+    if (prev_aml_offset == asl[i].aml_offset):
+        die("ACPI_EXTRACT directive in the middle of a block")
+
+    directive = mext.group(1)
+    array = mext.group(2)
+    offset = asl[i].aml_offset
+
+    if (directive == "ACPI_EXTRACT_ALL_CODE"):
+        if array in output:
+            die("%s directive used more than once" % directive)
+        output[array] = aml
+        continue
+    if (directive == "ACPI_EXTRACT_NAME_BUFFER8"):
+        offset = aml_name_buffer8(offset)
+    elif (directive == "ACPI_EXTRACT_NAME_DWORD_CONST"):
+        offset = aml_name_dword_const(offset)
+    elif (directive == "ACPI_EXTRACT_NAME_WORD_CONST"):
+        offset = aml_name_word_const(offset)
+    elif (directive == "ACPI_EXTRACT_NAME_BYTE_CONST"):
+        offset = aml_name_byte_const(offset)
+    elif (directive == "ACPI_EXTRACT_NAME_STRING"):
+        offset = aml_name_string(offset)
+    elif (directive == "ACPI_EXTRACT_METHOD_STRING"):
+        offset = aml_method_string(offset)
+    elif (directive == "ACPI_EXTRACT_DEVICE_START"):
+        offset = aml_device_start(offset)
+    elif (directive == "ACPI_EXTRACT_DEVICE_STRING"):
+        offset = aml_device_string(offset)
+    elif (directive == "ACPI_EXTRACT_DEVICE_END"):
+        offset = aml_device_end(offset)
+    elif (directive == "ACPI_EXTRACT_PROCESSOR_START"):
+        offset = aml_processor_start(offset)
+    elif (directive == "ACPI_EXTRACT_PROCESSOR_STRING"):
+        offset = aml_processor_string(offset)
+    elif (directive == "ACPI_EXTRACT_PROCESSOR_END"):
+        offset = aml_processor_end(offset)
+    elif (directive == "ACPI_EXTRACT_PKG_START"):
+        offset = aml_package_start(offset)
+    else:
+        die("Unsupported directive %s" % directive)
+
+    if array not in output:
+        output[array] = []
+    output[array].append(offset)
+
+debug = "at end of file"
+
+def get_value_type(maxvalue):
+    #Use type large enough to fit the table
+    if (maxvalue >= 0x10000):
+            return "int"
+    elif (maxvalue >= 0x100):
+            return "short"
+    else:
+            return "char"
+
+# Pretty print output
+for array in output.keys():
+    otype = get_value_type(max(output[array]))
+    odata = []
+    for value in output[array]:
+        odata.append("0x%x" % value)
+    sys.stdout.write("static unsigned %s %s[] = {\n" % (otype, array))
+    sys.stdout.write(",\n".join(odata))
+    sys.stdout.write('\n};\n');
diff --git a/scripts/acpi_extract_preprocess.py b/scripts/acpi_extract_preprocess.py
new file mode 100755 (executable)
index 0000000..69d10d6
--- /dev/null
@@ -0,0 +1,51 @@
+#!/usr/bin/python
+# Copyright (C) 2011 Red Hat, Inc., Michael S. Tsirkin <mst@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, see <http://www.gnu.org/licenses/>.
+
+# Read a preprocessed ASL listing and put each ACPI_EXTRACT
+# directive in a comment, to make iasl skip it.
+# We also put each directive on a new line, the machinery
+# in tools/acpi_extract.py requires this.
+
+import re;
+import sys;
+import fileinput;
+
+def die(diag):
+    sys.stderr.write("Error: %s\n" % (diag))
+    sys.exit(1)
+
+# Note: () around pattern make split return matched string as part of list
+psplit = re.compile(r''' (
+                          \b # At word boundary
+                          ACPI_EXTRACT_\w+ # directive
+                          \s+ # some whitespace
+                          \w+ # array name
+                         )''', re.VERBOSE);
+
+lineno = 0
+for line in fileinput.input():
+    # line number and debug string to output in case of errors
+    lineno = lineno + 1
+    debug = "input line %d: %s" % (lineno, line.rstrip())
+
+    s = psplit.split(line);
+    # The way split works, each odd item is the matching ACPI_EXTRACT directive.
+    # Put each in a comment, and on a line by itself.
+    for i in range(len(s)):
+        if (i % 2):
+            sys.stdout.write("\n/* %s */\n" % s[i])
+        else:
+            sys.stdout.write(s[i])
diff --git a/scripts/update-acpi.sh b/scripts/update-acpi.sh
new file mode 100644 (file)
index 0000000..b5f05ff
--- /dev/null
@@ -0,0 +1,4 @@
+cd x86_64-softmmu
+for file in hw/i386/*.hex; do
+    cp -f $file ../$file.generated
+done
index 2c56740bf6806b4cd3c04580726d75ce32afe870..9f110f15b6c83b3d89867fe8f8995fa7364091c6 100644 (file)
@@ -176,6 +176,7 @@ typedef struct CPUARMState {
         uint32_t c9_pmxevtyper; /* perf monitor event type */
         uint32_t c9_pmuserenr; /* perf monitor user enable */
         uint32_t c9_pminten; /* perf monitor interrupt enables */
+        uint32_t c12_vbar; /* vector base address register */
         uint32_t c13_fcse; /* FCSE PID.  */
         uint32_t c13_context; /* Context ID.  */
         uint32_t c13_tls1; /* User RW Thread register.  */
index c63bbd7fc196c8efad4892bf4a216bccc0fbfefa..3445813465585044b6afa7ca16e6733e9cac07f4 100644 (file)
@@ -225,10 +225,16 @@ static void count_cpreg(gpointer key, gpointer opaque)
 
 static gint cpreg_key_compare(gconstpointer a, gconstpointer b)
 {
-    uint32_t aidx = *(uint32_t *)a;
-    uint32_t bidx = *(uint32_t *)b;
+    uint64_t aidx = cpreg_to_kvm_id(*(uint32_t *)a);
+    uint64_t bidx = cpreg_to_kvm_id(*(uint32_t *)b);
 
-    return aidx - bidx;
+    if (aidx > bidx) {
+        return 1;
+    }
+    if (aidx < bidx) {
+        return -1;
+    }
+    return 0;
 }
 
 static void cpreg_make_keylist(gpointer key, gpointer value, gpointer udata)
@@ -537,6 +543,13 @@ static int pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
     return 0;
 }
 
+static int vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                      uint64_t value)
+{
+    env->cp15.c12_vbar = value & ~0x1Ful;
+    return 0;
+}
+
 static int ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri,
                        uint64_t *value)
 {
@@ -622,6 +635,10 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
       .access = PL1_RW, .type = ARM_CP_NO_MIGRATE,
       .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
       .resetvalue = 0, .writefn = pmintenclr_write, },
+    { .name = "VBAR", .cp = 15, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
+      .access = PL1_RW, .writefn = vbar_write,
+      .fieldoffset = offsetof(CPUARMState, cp15.c12_vbar),
+      .resetvalue = 0 },
     { .name = "SCR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_scr),
       .resetvalue = 0, },
@@ -2470,7 +2487,17 @@ void arm_cpu_do_interrupt(CPUState *cs)
     }
     /* High vectors.  */
     if (env->cp15.c1_sys & (1 << 13)) {
+        /* when enabled, base address cannot be remapped.  */
         addr += 0xffff0000;
+    } else {
+        /* ARM v7 architectures provide a vector base address register to remap
+         * the interrupt vector table.
+         * This register is only followed in non-monitor mode, and has a secure
+         * and un-secure copy. Since the cpu is always in a un-secure operation
+         * and is never in monitor mode this feature is always active.
+         * Note: only bits 31:5 are valid.
+         */
+        addr += env->cp15.c12_vbar;
     }
     switch_mode (env, new_mode);
     env->spsr = cpsr_read(env);
index b92e00dae037d7262e540524e50c386f94c1b881..6e5cd36faea1a5aecc62cf49a514788db36cf1fd 100644 (file)
@@ -67,7 +67,13 @@ static bool reg_syncs_via_tuple_list(uint64_t regidx)
 
 static int compare_u64(const void *a, const void *b)
 {
-    return *(uint64_t *)a - *(uint64_t *)b;
+    if (*(uint64_t *)a > *(uint64_t *)b) {
+        return 1;
+    }
+    if (*(uint64_t *)a < *(uint64_t *)b) {
+        return -1;
+    }
+    return 0;
 }
 
 int kvm_arch_init_vcpu(CPUState *cs)
index 7508cf5a06c063aa2050ebebbf708827f14b0de6..e1415f043c0eb4d634f3b027e5d4ffaca852f415 100644 (file)
@@ -246,6 +246,7 @@ struct CPUMBState {
     /* lwx/swx reserved address */
 #define RES_ADDR_NONE 0xffffffff /* Use 0xffffffff to indicate no reservation */
     uint32_t res_addr;
+    uint32_t res_val;
 
     /* Internal flags.  */
 #define IMM_FLAG       4
index 1b937b3f0d18cf44852d8adec6be94c7bfe17b1b..9edcb67e6660594b0d75101837fb4b0508878bb4 100644 (file)
@@ -49,6 +49,8 @@ static TCGv env_imm;
 static TCGv env_btaken;
 static TCGv env_btarget;
 static TCGv env_iflags;
+static TCGv env_res_addr;
+static TCGv env_res_val;
 
 #include "exec/gen-icount.h"
 
@@ -150,6 +152,10 @@ static void read_carry(DisasContext *dc, TCGv d)
     tcg_gen_shri_tl(d, cpu_SR[SR_MSR], 31);
 }
 
+/*
+ * write_carry sets the carry bits in MSR based on bit 0 of v.
+ * v[31:1] are ignored.
+ */
 static void write_carry(DisasContext *dc, TCGv v)
 {
     TCGv t0 = tcg_temp_new();
@@ -162,10 +168,10 @@ static void write_carry(DisasContext *dc, TCGv v)
     tcg_temp_free(t0);
 }
 
-static void write_carryi(DisasContext *dc, int carry)
+static void write_carryi(DisasContext *dc, bool carry)
 {
     TCGv t0 = tcg_temp_new();
-    tcg_gen_movi_tl(t0, carry ? 1 : 0);
+    tcg_gen_movi_tl(t0, carry);
     write_carry(dc, t0);
     tcg_temp_free(t0);
 }
@@ -386,10 +392,7 @@ static void dec_and(DisasContext *dc)
         return;
 
     if (not) {
-        TCGv t = tcg_temp_new();
-        tcg_gen_not_tl(t, *(dec_alu_op_b(dc)));
-        tcg_gen_and_tl(cpu_R[dc->rd], cpu_R[dc->ra], t);
-        tcg_temp_free(t);
+        tcg_gen_andc_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
     } else
         tcg_gen_and_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 }
@@ -749,7 +752,7 @@ static void dec_barrel(DisasContext *dc)
 
 static void dec_bit(DisasContext *dc)
 {
-    TCGv t0, t1;
+    TCGv t0;
     unsigned int op;
     int mem_index = cpu_mmu_index(dc->env);
 
@@ -760,32 +763,22 @@ static void dec_bit(DisasContext *dc)
             t0 = tcg_temp_new();
 
             LOG_DIS("src r%d r%d\n", dc->rd, dc->ra);
-            tcg_gen_andi_tl(t0, cpu_R[dc->ra], 1);
+            tcg_gen_andi_tl(t0, cpu_SR[SR_MSR], MSR_CC);
+            write_carry(dc, cpu_R[dc->ra]);
             if (dc->rd) {
-                t1 = tcg_temp_new();
-                read_carry(dc, t1);
-                tcg_gen_shli_tl(t1, t1, 31);
-
                 tcg_gen_shri_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
-                tcg_gen_or_tl(cpu_R[dc->rd], cpu_R[dc->rd], t1);
-                tcg_temp_free(t1);
+                tcg_gen_or_tl(cpu_R[dc->rd], cpu_R[dc->rd], t0);
             }
-
-            /* Update carry.  */
-            write_carry(dc, t0);
             tcg_temp_free(t0);
             break;
 
         case 0x1:
         case 0x41:
             /* srl.  */
-            t0 = tcg_temp_new();
             LOG_DIS("srl r%d r%d\n", dc->rd, dc->ra);
 
-            /* Update carry.  */
-            tcg_gen_andi_tl(t0, cpu_R[dc->ra], 1);
-            write_carry(dc, t0);
-            tcg_temp_free(t0);
+            /* Update carry. Note that write carry only looks at the LSB.  */
+            write_carry(dc, cpu_R[dc->ra]);
             if (dc->rd) {
                 if (op == 0x41)
                     tcg_gen_shri_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
@@ -872,7 +865,7 @@ static void dec_imm(DisasContext *dc)
 }
 
 static inline void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
-                            unsigned int size)
+                            unsigned int size, bool exclusive)
 {
     int mem_index = cpu_mmu_index(dc->env);
 
@@ -884,6 +877,11 @@ static inline void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
         tcg_gen_qemu_ld32u(dst, addr, mem_index);
     } else
         cpu_abort(dc->env, "Incorrect load size %d\n", size);
+
+    if (exclusive) {
+        tcg_gen_mov_tl(env_res_addr, addr);
+        tcg_gen_mov_tl(env_res_val, dst);
+    }
 }
 
 static inline TCGv *compute_ldst_addr(DisasContext *dc, TCGv *t)
@@ -1055,7 +1053,7 @@ static void dec_load(DisasContext *dc)
          * into v. If the load succeeds, we verify alignment of the
          * address and if that succeeds we write into the destination reg.
          */
-        gen_load(dc, v, *addr, size);
+        gen_load(dc, v, *addr, size, ex);
 
         tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
         gen_helper_memalign(cpu_env, *addr, tcg_const_tl(dc->rd),
@@ -1070,20 +1068,19 @@ static void dec_load(DisasContext *dc)
         tcg_temp_free(v);
     } else {
         if (dc->rd) {
-            gen_load(dc, cpu_R[dc->rd], *addr, size);
+            gen_load(dc, cpu_R[dc->rd], *addr, size, ex);
             if (rev) {
                 dec_byteswap(dc, cpu_R[dc->rd], cpu_R[dc->rd], size);
             }
         } else {
             /* We are loading into r0, no need to reverse.  */
-            gen_load(dc, env_imm, *addr, size);
+            gen_load(dc, env_imm, *addr, size, ex);
         }
     }
 
     if (ex) { /* lwx */
         /* no support for for AXI exclusive so always clear C */
         write_carryi(dc, 0);
-        tcg_gen_st_tl(*addr, cpu_env, offsetof(CPUMBState, res_addr));
     }
 
     if (addr == &t)
@@ -1107,7 +1104,7 @@ static void gen_store(DisasContext *dc, TCGv addr, TCGv val,
 
 static void dec_store(DisasContext *dc)
 {
-    TCGv t, *addr, swx_addr, r_check;
+    TCGv t, *addr, swx_addr;
     int swx_skip = 0;
     unsigned int size, rev = 0, ex = 0;
 
@@ -1131,9 +1128,9 @@ static void dec_store(DisasContext *dc)
     sync_jmpstate(dc);
     addr = compute_ldst_addr(dc, &t);
 
-    r_check = tcg_temp_new();
     swx_addr = tcg_temp_local_new();
     if (ex) { /* swx */
+        TCGv tval;
 
         /* Force addr into the swx_addr. */
         tcg_gen_mov_tl(swx_addr, *addr);
@@ -1141,11 +1138,20 @@ static void dec_store(DisasContext *dc)
         /* swx does not throw unaligned access errors, so force alignment */
         tcg_gen_andi_tl(swx_addr, swx_addr, ~3);
 
-        tcg_gen_ld_tl(r_check, cpu_env, offsetof(CPUMBState, res_addr));
         write_carryi(dc, 1);
         swx_skip = gen_new_label();
-        tcg_gen_brcond_tl(TCG_COND_NE, r_check, swx_addr, swx_skip);
+        tcg_gen_brcond_tl(TCG_COND_NE, env_res_addr, swx_addr, swx_skip);
+
+        /* Compare the value loaded at lwx with current contents of
+           the reserved location.
+           FIXME: This only works for system emulation where we can expect
+           this compare and the following write to be atomic. For user
+           emulation we need to add atomicity between threads.  */
+        tval = tcg_temp_new();
+        gen_load(dc, tval, swx_addr, 4, false);
+        tcg_gen_brcond_tl(TCG_COND_NE, env_res_val, tval, swx_skip);
         write_carryi(dc, 0);
+        tcg_temp_free(tval);
     }
 
     if (rev && size != 4) {
@@ -1227,7 +1233,6 @@ static void dec_store(DisasContext *dc)
     if (ex) {
         gen_set_label(swx_skip);
     }
-    tcg_temp_free(r_check);
     tcg_temp_free(swx_addr);
 
     if (addr == &t)
@@ -2014,6 +2019,12 @@ void mb_tcg_init(void)
     env_btaken = tcg_global_mem_new(TCG_AREG0,
                      offsetof(CPUMBState, btaken),
                      "btaken");
+    env_res_addr = tcg_global_mem_new(TCG_AREG0,
+                     offsetof(CPUMBState, res_addr),
+                     "res_addr");
+    env_res_val = tcg_global_mem_new(TCG_AREG0,
+                     offsetof(CPUMBState, res_val),
+                     "res_val");
     for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
         cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
                           offsetof(CPUMBState, regs[i]),
diff --git a/vl.c b/vl.c
index b42ac67100ac76b8b6fb649181a1a7c1fb9b5765..efbff6512ab97975ad46463bb5db4ddc246851a2 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -4336,6 +4336,9 @@ int main(int argc, char **argv, char **envp)
     qemu_register_reset(qbus_reset_all_fn, sysbus_get_default());
     qemu_run_machine_init_done_notifiers();
 
+    /* Done notifiers can load ROMs */
+    rom_load_done();
+
     qemu_system_reset(VMRESET_SILENT);
     if (loadvm) {
         if (load_vmstate(loadvm) < 0) {