summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.target10
-rw-r--r--block/raw-win32.c5
-rw-r--r--block/vmdk.c10
-rw-r--r--blockdev.c7
-rwxr-xr-xconfigure9
-rw-r--r--cpus.c144
-rw-r--r--default-configs/arm-linux-user.mak2
-rw-r--r--default-configs/arm-softmmu.mak2
-rw-r--r--default-configs/armeb-linux-user.mak2
-rw-r--r--default-configs/m68k-linux-user.mak2
-rw-r--r--default-configs/m68k-softmmu.mak1
-rw-r--r--default-configs/ppc-linux-user.mak2
-rw-r--r--default-configs/ppc-softmmu.mak1
-rw-r--r--default-configs/ppc64-linux-user.mak2
-rw-r--r--default-configs/ppc64-softmmu.mak1
-rw-r--r--default-configs/ppc64abi32-linux-user.mak2
-rw-r--r--default-configs/ppcemb-softmmu.mak1
-rw-r--r--docs/memory.txt4
-rw-r--r--exec.c97
-rw-r--r--hmp.c2
-rw-r--r--hw/acpi/core.c40
-rw-r--r--hw/acpi/ich9.c24
-rw-r--r--hw/acpi/piix4.c50
-rw-r--r--hw/arm/boot.c6
-rw-r--r--hw/arm/integratorcp.c2
-rw-r--r--hw/arm/omap_sx1.c10
-rw-r--r--hw/arm/palm.c10
-rw-r--r--hw/arm/z2.c12
-rw-r--r--hw/audio/ac97.c4
-rw-r--r--hw/audio/es1370.c4
-rw-r--r--hw/audio/intel-hda.c2
-rw-r--r--hw/block/nvme.c2
-rw-r--r--hw/block/virtio-blk.c1
-rw-r--r--hw/char/serial-pci.c5
-rw-r--r--hw/char/tpci200.c8
-rw-r--r--hw/core/irq.c16
-rw-r--r--hw/core/loader.c31
-rw-r--r--hw/core/sysbus.c4
-rw-r--r--hw/display/cirrus_vga.c3
-rw-r--r--hw/display/qxl.c22
-rw-r--r--hw/display/vga.c5
-rw-r--r--hw/i386/Makefile.objs27
-rw-r--r--hw/i386/acpi-build.c1214
-rw-r--r--hw/i386/acpi-build.h9
-rw-r--r--hw/i386/acpi-defs.h331
-rw-r--r--hw/i386/acpi-dsdt-cpu-hotplug.dsl93
-rw-r--r--hw/i386/acpi-dsdt-dbug.dsl41
-rw-r--r--hw/i386/acpi-dsdt-hpet.dsl51
-rw-r--r--hw/i386/acpi-dsdt-isa.dsl117
-rw-r--r--hw/i386/acpi-dsdt-pci-crs.dsl105
-rw-r--r--hw/i386/acpi-dsdt.dsl343
-rw-r--r--hw/i386/acpi-dsdt.hex.generated4409
-rw-r--r--hw/i386/bios-linker-loader.c158
-rw-r--r--hw/i386/bios-linker-loader.h27
-rw-r--r--hw/i386/kvmvapic.c3
-rw-r--r--hw/i386/pc.c25
-rw-r--r--hw/i386/pc_piix.c5
-rw-r--r--hw/i386/pc_q35.c3
-rw-r--r--hw/i386/q35-acpi-dsdt.dsl452
-rw-r--r--hw/i386/q35-acpi-dsdt.hex.generated7346
-rw-r--r--hw/i386/ssdt-misc.dsl119
-rw-r--r--hw/i386/ssdt-misc.hex.generated386
-rw-r--r--hw/i386/ssdt-pcihp.dsl51
-rw-r--r--hw/i386/ssdt-pcihp.hex.generated108
-rw-r--r--hw/i386/ssdt-proc.dsl63
-rw-r--r--hw/i386/ssdt-proc.hex.generated134
-rw-r--r--hw/ide/cmd646.c2
-rw-r--r--hw/ide/ich.c3
-rw-r--r--hw/isa/lpc_ich9.c40
-rw-r--r--hw/isa/vt82c686.c2
-rw-r--r--hw/lm32/lm32_hwsetup.h2
-rw-r--r--hw/microblaze/boot.c50
-rw-r--r--hw/microblaze/boot.h4
-rw-r--r--hw/microblaze/petalogix_ml605_mmu.c6
-rw-r--r--hw/microblaze/petalogix_s3adsp1800_mmu.c4
-rw-r--r--hw/misc/Makefile.objs1
-rw-r--r--hw/misc/arm_integrator_debug.c99
-rw-r--r--hw/misc/ivshmem.c2
-rw-r--r--hw/misc/pvpanic.c13
-rw-r--r--hw/misc/vfio.c11
-rw-r--r--hw/net/e1000.c11
-rw-r--r--hw/net/eepro100.c4
-rw-r--r--hw/net/ne2000.c3
-rw-r--r--hw/net/pcnet-pci.c3
-rw-r--r--hw/net/rtl8139.c9
-rw-r--r--hw/net/vmxnet3.c13
-rw-r--r--hw/nvram/fw_cfg.c33
-rw-r--r--hw/pci-bridge/pci_bridge_dev.c2
-rw-r--r--hw/pci-host/piix.c8
-rw-r--r--hw/pci-host/q35.c26
-rw-r--r--hw/pci/Makefile.objs2
-rw-r--r--hw/pci/pci.c72
-rw-r--r--hw/pci/pcie.c4
-rw-r--r--hw/pci/pcie_aer.c4
-rw-r--r--hw/pci/pcie_host.c24
-rw-r--r--hw/pci/shpc.c2
-rw-r--r--hw/scsi/esp-pci.c3
-rw-r--r--hw/scsi/lsi53c895a.c2
-rw-r--r--hw/scsi/megasas.c6
-rw-r--r--hw/scsi/vmw_pvscsi.c2
-rw-r--r--hw/sd/sd.c2
-rw-r--r--hw/timer/hpet.c5
-rw-r--r--hw/usb/hcd-ehci-pci.c2
-rw-r--r--hw/usb/hcd-ohci.c2
-rw-r--r--hw/usb/hcd-uhci.c6
-rw-r--r--hw/usb/hcd-xhci.c7
-rw-r--r--hw/virtio/virtio-pci.c4
-rw-r--r--include/exec/ioport.h2
-rw-r--r--include/exec/memory.h4
-rw-r--r--include/hw/acpi/acpi.h4
-rw-r--r--include/hw/acpi/ich9.h2
-rw-r--r--include/hw/acpi/piix4.h8
-rw-r--r--include/hw/i386/ich9.h2
-rw-r--r--include/hw/i386/pc.h22
-rw-r--r--include/hw/irq.h7
-rw-r--r--include/hw/loader.h8
-rw-r--r--include/hw/misc/arm_integrator_debug.h18
-rw-r--r--include/hw/nvram/fw_cfg.h8
-rw-r--r--include/hw/pci-host/q35.h2
-rw-r--r--include/hw/pci/pci.h26
-rw-r--r--include/hw/pci/pci_bus.h1
-rw-r--r--include/hw/pci/pcie.h18
-rw-r--r--include/hw/pci/pcie_host.h27
-rw-r--r--include/hw/sysbus.h2
-rw-r--r--include/hw/timer/hpet.h2
-rw-r--r--include/qemu/seqlock.h72
-rw-r--r--include/qemu/thread-posix.h8
-rw-r--r--include/qemu/thread-win32.h4
-rw-r--r--include/qemu/thread.h7
-rw-r--r--include/qemu/timer.h34
-rw-r--r--include/qom/object.h73
-rw-r--r--include/ui/qemu-spice.h5
-rw-r--r--ioport.c9
-rw-r--r--memory.c8
-rw-r--r--qemu-timer.c97
-rw-r--r--qom/object.c60
-rw-r--r--rules.mak28
-rwxr-xr-xscripts/acpi_extract.py362
-rwxr-xr-xscripts/acpi_extract_preprocess.py51
-rw-r--r--scripts/update-acpi.sh4
-rw-r--r--target-arm/Makefile.objs2
-rw-r--r--target-arm/cpu.h1
-rw-r--r--target-arm/helper.c33
-rw-r--r--target-arm/kvm.c8
-rw-r--r--target-i386/Makefile.objs2
-rw-r--r--target-i386/cpu.c66
-rw-r--r--target-i386/cpu.h4
-rw-r--r--target-microblaze/cpu.h1
-rw-r--r--target-microblaze/translate.c75
-rw-r--r--target-ppc/Makefile.objs2
-rw-r--r--target-xtensa/translate.c8
-rw-r--r--ui/Makefile.objs2
-rw-r--r--ui/spice-core.c40
-rw-r--r--ui/spice-display.c60
-rw-r--r--util/compatfd.c16
-rw-r--r--util/qemu-thread-posix.c116
-rw-r--r--util/qemu-thread-win32.c26
-rw-r--r--vl.c7
158 files changed, 17649 insertions, 492 deletions
diff --git a/Makefile.target b/Makefile.target
index 9a4985213b..af6ac7eaa1 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -70,10 +70,6 @@ all: $(PROGS) stap
# Dummy command so that make thinks it has done something
@true
-CONFIG_NO_PCI = $(if $(subst n,,$(CONFIG_PCI)),n,y)
-CONFIG_NO_KVM = $(if $(subst n,,$(CONFIG_KVM)),n,y)
-CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),n,y)
-
#########################################################
# cpu emulator library
obj-y = exec.o translate-all.o cpu-exec.o
@@ -83,8 +79,8 @@ obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
obj-y += fpu/softfloat.o
obj-y += target-$(TARGET_BASE_ARCH)/
obj-y += disas.o
-obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o
-obj-$(CONFIG_NO_KVM) += kvm-stub.o
+obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
+obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
#########################################################
# Linux user emulator target
@@ -125,7 +121,7 @@ LIBS+=$(libs_softmmu)
# xen support
obj-$(CONFIG_XEN) += xen-all.o xen-mapcache.o
-obj-$(CONFIG_NO_XEN) += xen-stub.o
+obj-$(call lnot,$(CONFIG_XEN)) += xen-stub.o
# Hardware support
ifeq ($(TARGET_NAME), sparc64)
diff --git a/block/raw-win32.c b/block/raw-win32.c
index c3e4c62d53..676b5701db 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -590,12 +590,11 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
int err = GetLastError();
if (err == ERROR_ACCESS_DENIED) {
- error_setg_errno(errp, EACCES, "Could not open device");
ret = -EACCES;
} else {
- error_setg(errp, "Could not open device");
- ret = -1;
+ ret = -EINVAL;
}
+ error_setg_errno(errp, -ret, "Could not open device");
goto done;
}
diff --git a/block/vmdk.c b/block/vmdk.c
index 5a9f2787f8..32ec8b7766 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -112,6 +112,7 @@ typedef struct BDRVVmdkState {
CoMutex lock;
uint64_t desc_offset;
bool cid_updated;
+ bool cid_checked;
uint32_t parent_cid;
int num_extents;
/* Extent array with num_extents entries, ascend ordered by address */
@@ -197,8 +198,6 @@ static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
}
}
-#define CHECK_CID 1
-
#define SECTOR_SIZE 512
#define DESC_SIZE (20 * SECTOR_SIZE) /* 20 sectors of 512 bytes each */
#define BUF_SIZE 4096
@@ -301,19 +300,18 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
static int vmdk_is_cid_valid(BlockDriverState *bs)
{
-#ifdef CHECK_CID
BDRVVmdkState *s = bs->opaque;
BlockDriverState *p_bs = bs->backing_hd;
uint32_t cur_pcid;
- if (p_bs) {
+ if (!s->cid_checked && p_bs) {
cur_pcid = vmdk_read_cid(p_bs, 0);
if (s->parent_cid != cur_pcid) {
/* CID not valid */
return 0;
}
}
-#endif
+ s->cid_checked = true;
/* CID valid */
return 1;
}
@@ -728,6 +726,8 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
error_setg(errp, "Invalid extent lines: \n%s", p);
return -EINVAL;
}
+ } else if (!strcmp(type, "VMFS")) {
+ flat_offset = 0;
} else if (ret != 4) {
error_setg(errp, "Invalid extent lines: \n%s", p);
return -EINVAL;
diff --git a/blockdev.c b/blockdev.c
index 4f76e28164..b260477f1b 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -625,7 +625,8 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
int cyls, heads, secs, translation;
int max_devs, bus_id, unit_id, index;
const char *devaddr;
- bool read_only, copy_on_read;
+ bool read_only = false;
+ bool copy_on_read;
Error *local_err = NULL;
/* Change legacy command line options into QMP ones */
@@ -701,7 +702,7 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
media = MEDIA_DISK;
} else if (!strcmp(value, "cdrom")) {
media = MEDIA_CDROM;
- qdict_put(bs_opts, "read-only", qstring_from_str("on"));
+ read_only = true;
} else {
error_report("'%s' invalid media", value);
goto fail;
@@ -709,7 +710,7 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
}
/* copy-on-read is disabled with a warning for read-only devices */
- read_only = qemu_opt_get_bool(legacy_opts, "read-only", false);
+ read_only |= qemu_opt_get_bool(legacy_opts, "read-only", false);
copy_on_read = qemu_opt_get_bool(legacy_opts, "copy-on-read", false);
if (read_only && copy_on_read) {
diff --git a/configure b/configure
index 57ee62a696..03d82f59b8 100755
--- 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
diff --git a/cpus.c b/cpus.c
index e566297bd3..398229ecbd 100644
--- a/cpus.c
+++ b/cpus.c
@@ -37,6 +37,7 @@
#include "sysemu/qtest.h"
#include "qemu/main-loop.h"
#include "qemu/bitmap.h"
+#include "qemu/seqlock.h"
#ifndef _WIN32
#include "qemu/compatfd.h"
@@ -97,21 +98,32 @@ static bool all_cpu_threads_idle(void)
/***********************************************************/
/* guest cycle counter */
+/* Protected by TimersState seqlock */
+
+/* Compensate for varying guest execution speed. */
+static int64_t qemu_icount_bias;
+static int64_t vm_clock_warp_start;
/* Conversion factor from emulated instructions to virtual clock ticks. */
static int icount_time_shift;
/* Arbitrarily pick 1MIPS as the minimum allowable speed. */
#define MAX_ICOUNT_SHIFT 10
-/* Compensate for varying guest execution speed. */
-static int64_t qemu_icount_bias;
+
+/* Only written by TCG thread */
+static int64_t qemu_icount;
+
static QEMUTimer *icount_rt_timer;
static QEMUTimer *icount_vm_timer;
static QEMUTimer *icount_warp_timer;
-static int64_t vm_clock_warp_start;
-static int64_t qemu_icount;
typedef struct TimersState {
+ /* Protected by BQL. */
int64_t cpu_ticks_prev;
int64_t cpu_ticks_offset;
+
+ /* cpu_clock_offset can be read out of BQL, so protect it with
+ * this lock.
+ */
+ QemuSeqLock vm_clock_seqlock;
int64_t cpu_clock_offset;
int32_t cpu_ticks_enabled;
int64_t dummy;
@@ -120,7 +132,7 @@ typedef struct TimersState {
static TimersState timers_state;
/* Return the virtual CPU time, based on the instruction counter. */
-int64_t cpu_get_icount(void)
+static int64_t cpu_get_icount_locked(void)
{
int64_t icount;
CPUState *cpu = current_cpu;
@@ -136,7 +148,21 @@ int64_t cpu_get_icount(void)
return qemu_icount_bias + (icount << icount_time_shift);
}
+int64_t cpu_get_icount(void)
+{
+ int64_t icount;
+ unsigned start;
+
+ do {
+ start = seqlock_read_begin(&timers_state.vm_clock_seqlock);
+ icount = cpu_get_icount_locked();
+ } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start));
+
+ return icount;
+}
+
/* return the host CPU cycle counter and handle stop/restart */
+/* Caller must hold the BQL */
int64_t cpu_get_ticks(void)
{
if (use_icount) {
@@ -157,37 +183,63 @@ int64_t cpu_get_ticks(void)
}
}
-/* return the host CPU monotonic timer and handle stop/restart */
-int64_t cpu_get_clock(void)
+static int64_t cpu_get_clock_locked(void)
{
int64_t ti;
+
if (!timers_state.cpu_ticks_enabled) {
- return timers_state.cpu_clock_offset;
+ ti = timers_state.cpu_clock_offset;
} else {
ti = get_clock();
- return ti + timers_state.cpu_clock_offset;
+ ti += timers_state.cpu_clock_offset;
}
+
+ return ti;
}
-/* enable cpu_get_ticks() */
+/* return the host CPU monotonic timer and handle stop/restart */
+int64_t cpu_get_clock(void)
+{
+ int64_t ti;
+ unsigned start;
+
+ do {
+ start = seqlock_read_begin(&timers_state.vm_clock_seqlock);
+ ti = cpu_get_clock_locked();
+ } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start));
+
+ return ti;
+}
+
+/* enable cpu_get_ticks()
+ * Caller must hold BQL which server as mutex for vm_clock_seqlock.
+ */
void cpu_enable_ticks(void)
{
+ /* Here, the really thing protected by seqlock is cpu_clock_offset. */
+ seqlock_write_lock(&timers_state.vm_clock_seqlock);
if (!timers_state.cpu_ticks_enabled) {
timers_state.cpu_ticks_offset -= cpu_get_real_ticks();
timers_state.cpu_clock_offset -= get_clock();
timers_state.cpu_ticks_enabled = 1;
}
+ seqlock_write_unlock(&timers_state.vm_clock_seqlock);
}
/* disable cpu_get_ticks() : the clock is stopped. You must not call
- cpu_get_ticks() after that. */
+ * cpu_get_ticks() after that.
+ * Caller must hold BQL which server as mutex for vm_clock_seqlock.
+ */
void cpu_disable_ticks(void)
{
+ /* Here, the really thing protected by seqlock is cpu_clock_offset. */
+ seqlock_write_lock(&timers_state.vm_clock_seqlock);
if (timers_state.cpu_ticks_enabled) {
timers_state.cpu_ticks_offset = cpu_get_ticks();
- timers_state.cpu_clock_offset = cpu_get_clock();
+ timers_state.cpu_clock_offset = cpu_get_clock_locked();
timers_state.cpu_ticks_enabled = 0;
}
+ seqlock_write_unlock(&timers_state.vm_clock_seqlock);
}
/* Correlation between real and virtual time is always going to be
@@ -201,13 +253,19 @@ static void icount_adjust(void)
int64_t cur_time;
int64_t cur_icount;
int64_t delta;
+
+ /* Protected by TimersState mutex. */
static int64_t last_delta;
+
/* If the VM is not running, then do nothing. */
if (!runstate_is_running()) {
return;
}
- cur_time = cpu_get_clock();
- cur_icount = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+
+ seqlock_write_lock(&timers_state.vm_clock_seqlock);
+ cur_time = cpu_get_clock_locked();
+ cur_icount = cpu_get_icount_locked();
+
delta = cur_icount - cur_time;
/* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */
if (delta > 0
@@ -224,6 +282,7 @@ static void icount_adjust(void)
}
last_delta = delta;
qemu_icount_bias = cur_icount - (qemu_icount << icount_time_shift);
+ seqlock_write_unlock(&timers_state.vm_clock_seqlock);
}
static void icount_adjust_rt(void *opaque)
@@ -248,30 +307,37 @@ static int64_t qemu_icount_round(int64_t count)
static void icount_warp_rt(void *opaque)
{
- if (vm_clock_warp_start == -1) {
+ /* The icount_warp_timer is rescheduled soon after vm_clock_warp_start
+ * changes from -1 to another value, so the race here is okay.
+ */
+ if (atomic_read(&vm_clock_warp_start) == -1) {
return;
}
+ seqlock_write_lock(&timers_state.vm_clock_seqlock);
if (runstate_is_running()) {
int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
- int64_t warp_delta = clock - vm_clock_warp_start;
- if (use_icount == 1) {
- qemu_icount_bias += warp_delta;
- } else {
+ int64_t warp_delta;
+
+ warp_delta = clock - vm_clock_warp_start;
+ if (use_icount == 2) {
/*
* In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too
* far ahead of real time.
*/
- int64_t cur_time = cpu_get_clock();
- int64_t cur_icount = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ int64_t cur_time = cpu_get_clock_locked();
+ int64_t cur_icount = cpu_get_icount_locked();
int64_t delta = cur_time - cur_icount;
- qemu_icount_bias += MIN(warp_delta, delta);
- }
- if (qemu_clock_expired(QEMU_CLOCK_VIRTUAL)) {
- qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
+ warp_delta = MIN(warp_delta, delta);
}
+ qemu_icount_bias += warp_delta;
}
vm_clock_warp_start = -1;
+ seqlock_write_unlock(&timers_state.vm_clock_seqlock);
+
+ if (qemu_clock_expired(QEMU_CLOCK_VIRTUAL)) {
+ qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
+ }
}
void qtest_clock_warp(int64_t dest)
@@ -281,7 +347,10 @@ void qtest_clock_warp(int64_t dest)
while (clock < dest) {
int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
int64_t warp = MIN(dest - clock, deadline);
+ seqlock_write_lock(&timers_state.vm_clock_seqlock);
qemu_icount_bias += warp;
+ seqlock_write_unlock(&timers_state.vm_clock_seqlock);
+
qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL);
clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}
@@ -290,6 +359,7 @@ void qtest_clock_warp(int64_t dest)
void qemu_clock_warp(QEMUClockType type)
{
+ int64_t clock;
int64_t deadline;
/*
@@ -309,8 +379,8 @@ void qemu_clock_warp(QEMUClockType type)
* the earliest QEMU_CLOCK_VIRTUAL timer.
*/
icount_warp_rt(NULL);
- if (!all_cpu_threads_idle() || !qemu_clock_has_timers(QEMU_CLOCK_VIRTUAL)) {
- timer_del(icount_warp_timer);
+ timer_del(icount_warp_timer);
+ if (!all_cpu_threads_idle()) {
return;
}
@@ -319,17 +389,11 @@ void qemu_clock_warp(QEMUClockType type)
return;
}
- vm_clock_warp_start = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
/* We want to use the earliest deadline from ALL vm_clocks */
+ clock = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
-
- /* Maintain prior (possibly buggy) behaviour where if no deadline
- * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more than
- * INT32_MAX nanoseconds ahead, we still use INT32_MAX
- * nanoseconds.
- */
- if ((deadline < 0) || (deadline > INT32_MAX)) {
- deadline = INT32_MAX;
+ if (deadline < 0) {
+ return;
}
if (deadline > 0) {
@@ -350,7 +414,12 @@ void qemu_clock_warp(QEMUClockType type)
* you will not be sending network packets continuously instead of
* every 100ms.
*/
- timer_mod(icount_warp_timer, vm_clock_warp_start + deadline);
+ seqlock_write_lock(&timers_state.vm_clock_seqlock);
+ if (vm_clock_warp_start == -1 || vm_clock_warp_start > clock) {
+ vm_clock_warp_start = clock;
+ }
+ seqlock_write_unlock(&timers_state.vm_clock_seqlock);
+ timer_mod_anticipate(icount_warp_timer, clock + deadline);
} else if (deadline == 0) {
qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
}
@@ -371,6 +440,7 @@ static const VMStateDescription vmstate_timers = {
void configure_icount(const char *option)
{
+ seqlock_init(&timers_state.vm_clock_seqlock, NULL);
vmstate_register(NULL, 0, &vmstate_timers, &timers_state);
if (!option) {
return;
diff --git a/default-configs/arm-linux-user.mak b/default-configs/arm-linux-user.mak
index 46d4aa2d71..413361a022 100644
--- a/default-configs/arm-linux-user.mak
+++ b/default-configs/arm-linux-user.mak
@@ -1,3 +1 @@
# Default configuration for arm-linux-user
-
-CONFIG_GDBSTUB_XML=y
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index ac0815d663..7e6913782e 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -2,7 +2,6 @@
include pci.mak
include usb.mak
-CONFIG_GDBSTUB_XML=y
CONFIG_VGA=y
CONFIG_ISA_MMIO=y
CONFIG_NAND=y
@@ -80,3 +79,4 @@ CONFIG_VERSATILE_PCI=y
CONFIG_VERSATILE_I2C=y
CONFIG_SDHCI=y
+CONFIG_INTEGRATOR_DEBUG=y
diff --git a/default-configs/armeb-linux-user.mak b/default-configs/armeb-linux-user.mak
index 41d0cc4926..bf2ffe7038 100644
--- a/default-configs/armeb-linux-user.mak
+++ b/default-configs/armeb-linux-user.mak
@@ -1,3 +1 @@
# Default configuration for armeb-linux-user
-
-CONFIG_GDBSTUB_XML=y
diff --git a/default-configs/m68k-linux-user.mak b/default-configs/m68k-linux-user.mak
index f3487aa3d9..06cd5ed7ed 100644
--- a/default-configs/m68k-linux-user.mak
+++ b/default-configs/m68k-linux-user.mak
@@ -1,3 +1 @@
# Default configuration for m68k-linux-user
-
-CONFIG_GDBSTUB_XML=y
diff --git a/default-configs/m68k-softmmu.mak b/default-configs/m68k-softmmu.mak
index 51fe5bb321..d9552df076 100644
--- a/default-configs/m68k-softmmu.mak
+++ b/default-configs/m68k-softmmu.mak
@@ -3,5 +3,4 @@
include pci.mak
include usb.mak
CONFIG_COLDFIRE=y
-CONFIG_GDBSTUB_XML=y
CONFIG_PTIMER=y
diff --git a/default-configs/ppc-linux-user.mak b/default-configs/ppc-linux-user.mak
index 681a94598e..6273df2930 100644
--- a/default-configs/ppc-linux-user.mak
+++ b/default-configs/ppc-linux-user.mak
@@ -1,3 +1 @@
# Default configuration for ppc-linux-user
-
-CONFIG_GDBSTUB_XML=y
diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index eac0b28fb9..f5cd0bdcc0 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -3,7 +3,6 @@
include pci.mak
include sound.mak
include usb.mak
-CONFIG_GDBSTUB_XML=y
CONFIG_ISA_MMIO=y
CONFIG_ESCC=y
CONFIG_M48T59=y
diff --git a/default-configs/ppc64-linux-user.mak b/default-configs/ppc64-linux-user.mak
index 089c08f3a0..422d3fbaeb 100644
--- a/default-configs/ppc64-linux-user.mak
+++ b/default-configs/ppc64-linux-user.mak
@@ -1,3 +1 @@
# Default configuration for ppc64-linux-user
-
-CONFIG_GDBSTUB_XML=y
diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
index 7831c2bf57..975112acf7 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -3,7 +3,6 @@
include pci.mak
include sound.mak
include usb.mak
-CONFIG_GDBSTUB_XML=y
CONFIG_ISA_MMIO=y
CONFIG_ESCC=y
CONFIG_M48T59=y
diff --git a/default-configs/ppc64abi32-linux-user.mak b/default-configs/ppc64abi32-linux-user.mak
index f038ffd97c..1c657ec9bb 100644
--- a/default-configs/ppc64abi32-linux-user.mak
+++ b/default-configs/ppc64abi32-linux-user.mak
@@ -1,3 +1 @@
# Default configuration for ppc64abi32-linux-user
-
-CONFIG_GDBSTUB_XML=y
diff --git a/default-configs/ppcemb-softmmu.mak b/default-configs/ppcemb-softmmu.mak
index 86080a7574..4411203a9a 100644
--- a/default-configs/ppcemb-softmmu.mak
+++ b/default-configs/ppcemb-softmmu.mak
@@ -3,7 +3,6 @@
include pci.mak
include sound.mak
include usb.mak
-CONFIG_GDBSTUB_XML=y
CONFIG_ISA_MMIO=y
CONFIG_ESCC=y
CONFIG_M48T59=y
diff --git a/docs/memory.txt b/docs/memory.txt
index feb9fe90d7..174c0d7b43 100644
--- a/docs/memory.txt
+++ b/docs/memory.txt
@@ -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
----------
diff --git a/exec.c b/exec.c
index bea2cffd94..2e31ffcb2c 100644
--- a/exec.c
+++ b/exec.c
@@ -129,7 +129,6 @@ static PhysPageMap next_map;
static void io_mem_init(void);
static void memory_map_init(void);
-static void *qemu_safe_ram_ptr(ram_addr_t addr);
static MemoryRegion io_mem_watch;
#endif
@@ -626,22 +625,39 @@ void cpu_abort(CPUArchState *env, const char *fmt, ...)
}
#if !defined(CONFIG_USER_ONLY)
+static RAMBlock *qemu_get_ram_block(ram_addr_t addr)
+{
+ RAMBlock *block;
+
+ /* The list is protected by the iothread lock here. */
+ block = ram_list.mru_block;
+ if (block && addr - block->offset < block->length) {
+ goto found;
+ }
+ QTAILQ_FOREACH(block, &ram_list.blocks, next) {
+ if (addr - block->offset < block->length) {
+ goto found;
+ }
+ }
+
+ fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr);
+ abort();
+
+found:
+ ram_list.mru_block = block;
+ return block;
+}
+
static void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t end,
uintptr_t length)
{
- uintptr_t start1;
+ RAMBlock *block;
+ ram_addr_t start1;
- /* we modify the TLB cache so that the dirty bit will be set again
- when accessing the range */
- start1 = (uintptr_t)qemu_safe_ram_ptr(start);
- /* Check that we don't span multiple blocks - this breaks the
- address comparisons below. */
- if ((uintptr_t)qemu_safe_ram_ptr(end - 1) - start1
- != (end - 1) - start) {
- abort();
- }
+ block = qemu_get_ram_block(start);
+ assert(block == qemu_get_ram_block(end - 1));
+ start1 = (uintptr_t)block->host + (start - block->offset);
cpu_tlb_reset_dirty_all(start1, length);
-
}
/* Note: start and end must be within the same ram block. */
@@ -1269,29 +1285,6 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
}
#endif /* !_WIN32 */
-static RAMBlock *qemu_get_ram_block(ram_addr_t addr)
-{
- RAMBlock *block;
-
- /* The list is protected by the iothread lock here. */
- block = ram_list.mru_block;
- if (block && addr - block->offset < block->length) {
- goto found;
- }
- QTAILQ_FOREACH(block, &ram_list.blocks, next) {
- if (addr - block->offset < block->length) {
- goto found;
- }
- }
-
- fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr);
- abort();
-
-found:
- ram_list.mru_block = block;
- return block;
-}
-
/* Return a host pointer to ram allocated with qemu_ram_alloc.
With the exception of the softmmu code in this file, this should
only be used for local memory (e.g. video ram) that the device owns,
@@ -1319,40 +1312,6 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
return block->host + (addr - block->offset);
}
-/* Return a host pointer to ram allocated with qemu_ram_alloc. Same as
- * qemu_get_ram_ptr but do not touch ram_list.mru_block.
- *
- * ??? Is this still necessary?
- */
-static void *qemu_safe_ram_ptr(ram_addr_t addr)
-{
- RAMBlock *block;
-
- /* The list is protected by the iothread lock here. */
- QTAILQ_FOREACH(block, &ram_list.blocks, next) {
- if (addr - block->offset < block->length) {
- if (xen_enabled()) {
- /* We need to check if the requested address is in the RAM
- * because we don't want to map the entire memory in QEMU.
- * In that case just map until the end of the page.
- */
- if (block->offset == 0) {
- return xen_map_cache(addr, 0, 0);
- } else if (block->host == NULL) {
- block->host =
- xen_map_cache(block->offset, block->length, 1);
- }
- }
- return block->host + (addr - block->offset);
- }
- }
-
- fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr);
- abort();
-
- return NULL;
-}
-
/* Return a host pointer to guest's ram. Similar to qemu_get_ram_ptr
* but takes a size argument */
static void *qemu_ram_ptr_length(ram_addr_t addr, hwaddr *size)
diff --git a/hmp.c b/hmp.c
index 589150773e..32ee285a1e 100644
--- a/hmp.c
+++ b/hmp.c
@@ -366,8 +366,6 @@ void hmp_info_block(Monitor *mon, const QDict *qdict)
info->value->inserted->iops_rd_max,
info->value->inserted->iops_wr_max,
info->value->inserted->iops_size);
- } else {
- monitor_printf(mon, " [not inserted]");
}
if (verbose) {
diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index 7138139d32..d8dff5b9d0 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -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);
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 3fb443d06d..7e0429e0f9 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -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);
+}
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index b46bd5ea6a..3bcd890567 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -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(),
};
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 1e313afe8d..583ec7992e 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -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");
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index 2ef93ed8d6..c44b2a499c 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -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]);
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
index b0f8664607..03b381688b 100644
--- a/hw/arm/omap_sx1.c
+++ b/hw/arm/omap_sx1.c
@@ -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);
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
index 3e390448e2..0b72bbe5fb 100644
--- a/hw/arm/palm.c
+++ b/hw/arm/palm.c
@@ -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 = {
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index 2e0d5d4bcc..a00fcc042d 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -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 = {
diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c
index 01b4dfbc67..03f484628e 100644
--- a/hw/audio/ac97.c
+++ b/hw/audio/ac97.c
@@ -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);
}
}
diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c
index adb66ced71..1ec7acee02 100644
--- a/hw/audio/es1370.c
+++ b/hw/audio/es1370.c
@@ -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)
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index a6666c6cdf..4327264394 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -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);
}
}
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 5dee229734..2882ffefce 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -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);
}
}
}
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 49a23c33f7..13f6d8276e 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -703,7 +703,6 @@ static int virtio_blk_device_init(VirtIODevice *vdev)
s->bs = blk->conf.bs;
s->conf = &blk->conf;
- memcpy(&(s->blk), blk, sizeof(struct VirtIOBlkConf));
s->rq = NULL;
s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c
index aec6705a01..991c99fa6e 100644
--- a/hw/char/serial-pci.c
+++ b/hw/char/serial-pci.c
@@ -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)
diff --git a/hw/char/tpci200.c b/hw/char/tpci200.c
index e04ff26019..a49d2ed5c1 100644
--- a/hw/char/tpci200.c
+++ b/hw/char/tpci200.c
@@ -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;
}
}
diff --git a/hw/core/irq.c b/hw/core/irq.c
index 20785428ef..03c8cb31ea 100644
--- a/hw/core/irq.c
+++ b/hw/core/irq.c
@@ -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;
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 7b3d3ee6a0..60d2ebd4ac 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -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;
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index b84cd4a16f..146f50aa15 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -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);
}
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
index dbd1f4a47b..e4c345fa82 100644
--- a/hw/display/cirrus_vga.c
+++ b/hw/display/cirrus_vga.c
@@ -2447,7 +2447,6 @@ static uint64_t cirrus_vga_ioport_read(void *opaque, hwaddr addr,
VGACommonState *s = &c->vga;
int val, index;
- qemu_flush_coalesced_mmio_buffer();
addr += 0x3b0;
if (vga_ioport_invalid(s, addr)) {
@@ -2544,7 +2543,6 @@ static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val,
VGACommonState *s = &c->vga;
int index;
- qemu_flush_coalesced_mmio_buffer();
addr += 0x3b0;
/* check port range access depending on color/monochrome mode */
@@ -2843,6 +2841,7 @@ static void cirrus_init_common(CirrusVGAState *s, Object *owner,
/* Register ioport 0x3b0 - 0x3df */
memory_region_init_io(&s->cirrus_vga_io, owner, &cirrus_vga_io_ops, s,
"cirrus-io", 0x30);
+ memory_region_set_flush_coalesced(&s->cirrus_vga_io);
memory_region_add_subregion(system_io, 0x3b0, &s->cirrus_vga_io);
memory_region_init(&s->low_mem_container, owner,
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index ee2db0da1a..5977d526d4 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -162,7 +162,7 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
trace_qxl_spice_update_area_rest(qxl->id, num_dirty_rects,
clear_dirty_region);
if (async == QXL_SYNC) {
- qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area,
+ spice_qxl_update_area(&qxl->ssd.qxl, surface_id, area,
dirty_rects, num_dirty_rects, clear_dirty_region);
} else {
assert(cookie != NULL);
@@ -193,7 +193,7 @@ static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
cookie->u.surface_id = id;
spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id, (uintptr_t)cookie);
} else {
- qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
+ spice_qxl_destroy_surface_wait(&qxl->ssd.qxl, id);
qxl_spice_destroy_surface_wait_complete(qxl, id);
}
}
@@ -211,19 +211,19 @@ void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
uint32_t count)
{
trace_qxl_spice_loadvm_commands(qxl->id, ext, count);
- qxl->ssd.worker->loadvm_commands(qxl->ssd.worker, ext, count);
+ spice_qxl_loadvm_commands(&qxl->ssd.qxl, ext, count);
}
void qxl_spice_oom(PCIQXLDevice *qxl)
{
trace_qxl_spice_oom(qxl->id);
- qxl->ssd.worker->oom(qxl->ssd.worker);
+ spice_qxl_oom(&qxl->ssd.qxl);
}
void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
{
trace_qxl_spice_reset_memslots(qxl->id);
- qxl->ssd.worker->reset_memslots(qxl->ssd.worker);
+ spice_qxl_reset_memslots(&qxl->ssd.qxl);
}
static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
@@ -244,7 +244,7 @@ static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
(uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
QXL_IO_DESTROY_ALL_SURFACES_ASYNC));
} else {
- qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
+ spice_qxl_destroy_surfaces(&qxl->ssd.qxl);
qxl_spice_destroy_surfaces_complete(qxl);
}
}
@@ -278,13 +278,13 @@ static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay)
void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
{
trace_qxl_spice_reset_image_cache(qxl->id);
- qxl->ssd.worker->reset_image_cache(qxl->ssd.worker);
+ spice_qxl_reset_image_cache(&qxl->ssd.qxl);
}
void qxl_spice_reset_cursor(PCIQXLDevice *qxl)
{
trace_qxl_spice_reset_cursor(qxl->id);
- qxl->ssd.worker->reset_cursor(qxl->ssd.worker);
+ spice_qxl_reset_cursor(&qxl->ssd.qxl);
qemu_mutex_lock(&qxl->track_lock);
qxl->guest_cursor = 0;
qemu_mutex_unlock(&qxl->track_lock);
@@ -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);
}
@@ -2037,8 +2037,7 @@ static int qxl_init_common(PCIQXLDevice *qxl)
qxl->vram32_size < qxl->vram_size ? "[region 4]" : "[unmapped]");
qxl->ssd.qxl.base.sif = &qxl_interface.base;
- qxl->ssd.qxl.id = qxl->id;
- if (qemu_spice_add_interface(&qxl->ssd.qxl.base) != 0) {
+ if (qemu_spice_add_display_interface(&qxl->ssd.qxl, qxl->vga.con) != 0) {
error_report("qxl interface %d.%d not supported by spice-server",
SPICE_INTERFACE_QXL_MAJOR, SPICE_INTERFACE_QXL_MINOR);
return -1;
@@ -2074,6 +2073,7 @@ static int qxl_init_primary(PCIDevice *dev)
pci_address_space(dev), pci_address_space_io(dev), false);
portio_list_init(qxl_vga_port_list, OBJECT(dev), qxl_vga_portio_list,
vga, "vga");
+ portio_list_set_flush_coalesced(qxl_vga_port_list);
portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0);
vga->con = graphic_console_init(DEVICE(dev), &qxl_ops, qxl);
diff --git a/hw/display/vga.c b/hw/display/vga.c
index 7b91d9c54e..b5e22849ab 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -359,8 +359,6 @@ uint32_t vga_ioport_read(void *opaque, uint32_t addr)
VGACommonState *s = opaque;
int val, index;
- qemu_flush_coalesced_mmio_buffer();
-
if (vga_ioport_invalid(s, addr)) {
val = 0xff;
} else {
@@ -453,8 +451,6 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
VGACommonState *s = opaque;
int index;
- qemu_flush_coalesced_mmio_buffer();
-
/* check port range access depending on color/monochrome mode */
if (vga_ioport_invalid(s, addr)) {
return;
@@ -2373,6 +2369,7 @@ void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
memory_region_set_coalescing(vga_io_memory);
if (init_vga_ports) {
portio_list_init(vga_port_list, obj, vga_ports, s, "vga");
+ portio_list_set_flush_coalesced(vga_port_list);
portio_list_add(vga_port_list, address_space_io, 0x3b0);
}
if (vbe_ports) {
diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index 45e61655e9..185aacbc69 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -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
index 0000000000..6cfa0446ac
--- /dev/null
+++ b/hw/i386/acpi-build.c
@@ -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
index 0000000000..e57b1aafdc
--- /dev/null
+++ b/hw/i386/acpi-build.h
@@ -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
index 0000000000..78ca20489f
--- /dev/null
+++ b/hw/i386/acpi-defs.h
@@ -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
index 0000000000..c96ac42a31
--- /dev/null
+++ b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
@@ -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
index 0000000000..86230f75a0
--- /dev/null
+++ b/hw/i386/acpi-dsdt-dbug.dsl
@@ -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
index 0000000000..dfde174317
--- /dev/null
+++ b/hw/i386/acpi-dsdt-hpet.dsl
@@ -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
index 0000000000..89caa1649d
--- /dev/null
+++ b/hw/i386/acpi-dsdt-isa.dsl
@@ -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
index 0000000000..b375a19cf6
--- /dev/null
+++ b/hw/i386/acpi-dsdt-pci-crs.dsl
@@ -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
index 0000000000..90efce0d18
--- /dev/null
+++ b/hw/i386/acpi-dsdt.dsl
@@ -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
index 0000000000..2c011070c4
--- /dev/null
+++ b/hw/i386/acpi-dsdt.hex.generated
@@ -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
index 0000000000..083385332e
--- /dev/null
+++ b/hw/i386/bios-linker-loader.c
@@ -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
index 0000000000..498c0af773
--- /dev/null
+++ b/hw/i386/bios-linker-loader.h
@@ -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
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 1c2dbf59cf..2d876009fc 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -596,6 +596,9 @@ static int vapic_map_rom_writable(VAPICROMState *s)
section = memory_region_find(as, 0, 1);
/* read ROM size from RAM region */
+ if (rom_paddr + 2 >= memory_region_size(section.mr)) {
+ return -1;
+ }
ram = memory_region_get_ram_ptr(section.mr);
rom_size = ram[rom_paddr + 2] * ROM_BLOCK_SIZE;
if (rom_size == 0) {
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index ec5508b288..dee409d271 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -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));
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index c6042c7e23..24a98cbee7 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -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)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index ca84e1c04c..4c191d3b42 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -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
index 0000000000..21c89b098b
--- /dev/null
+++ b/hw/i386/q35-acpi-dsdt.dsl
@@ -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
index 0000000000..32c16ff86f
--- /dev/null
+++ b/hw/i386/q35-acpi-dsdt.hex.generated
@@ -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
index 0000000000..a4484b8176
--- /dev/null
+++ b/hw/i386/ssdt-misc.dsl
@@ -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
index 0000000000..55e3bd2aa6
--- /dev/null
+++ b/hw/i386/ssdt-misc.hex.generated
@@ -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
index 0000000000..d29a5b95d2
--- /dev/null
+++ b/hw/i386/ssdt-pcihp.dsl
@@ -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
index 0000000000..b3c2cd5cf9
--- /dev/null
+++ b/hw/i386/ssdt-pcihp.hex.generated
@@ -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
index 0000000000..8229bfd702
--- /dev/null
+++ b/hw/i386/ssdt-proc.dsl
@@ -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
index 0000000000..bb9920d3c9
--- /dev/null
+++ b/hw/i386/ssdt-proc.hex.generated
@@ -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
+};
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 0500a7a1b6..a8e35fe38f 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -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 */
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index bff952bf6a..1c7c05810d 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -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)
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 5633d08b62..19b2198fa6 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -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;
}
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 8fe4fcb4a1..5fb808630f 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -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));
diff --git a/hw/lm32/lm32_hwsetup.h b/hw/lm32/lm32_hwsetup.h
index 3449bd8dfc..9fd5e697a7 100644
--- a/hw/lm32/lm32_hwsetup.h
+++ b/hw/lm32/lm32_hwsetup.h
@@ -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)
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index 5b057f7880..2a7ea5c0f9 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -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);
}
}
diff --git a/hw/microblaze/boot.h b/hw/microblaze/boot.h
index b14ef2b992..0eb7f8e4f6 100644
--- a/hw/microblaze/boot.h
+++ b/hw/microblaze/boot.h
@@ -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 __ */
diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
index e003c7c7b4..10970e0f3f 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -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);
}
diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
index 00af2b5abc..ec6489c2d3 100644
--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
+++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
@@ -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 = {
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 2578e2939d..cca5c058cc 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -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
index 0000000000..99b720fbb9
--- /dev/null
+++ b/hw/misc/arm_integrator_debug.c
@@ -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)
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 2838866f45..8d144baa1e 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -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)
diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index b64e3bb7b4..226e2983d3 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -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(),
};
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index a2d5283ff9..fe95e03d1d 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -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);
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 151d25e0b7..ec8ecd7b94 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -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
@@ -401,6 +401,7 @@ static void e1000_reset(void *opaque)
d->mac_reg[RA] |= macaddr[i] << (8 * i);
d->mac_reg[RA + 1] |= (i < 2) ? macaddr[i + 4] << (8 * i) : 0;
}
+ qemu_format_nic_info_str(qemu_get_queue(d->nic), macaddr);
}
static void
@@ -1105,7 +1106,15 @@ mac_read_clr8(E1000State *s, int index)
static void
mac_writereg(E1000State *s, int index, uint32_t val)
{
+ uint32_t macaddr[2];
+
s->mac_reg[index] = val;
+
+ if (index == RA + 1) {
+ macaddr[0] = cpu_to_le32(s->mac_reg[RA]);
+ macaddr[1] = cpu_to_le32(s->mac_reg[RA + 1]);
+ qemu_format_nic_info_str(qemu_get_queue(s->nic), (uint8_t *)macaddr);
+ }
}
static void
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index ffa60d5c96..3b891ca340 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -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;
}
}
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index c96125895e..a94cf74bf2 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -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[] = {
diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c
index 865f2f0c59..6a5d8064bb 100644
--- a/hw/net/pcnet-pci.c
+++ b/hw/net/pcnet-pci.c
@@ -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;
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index c31199f8c8..5329f44a9d 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -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)
@@ -1214,6 +1214,7 @@ static void rtl8139_reset(DeviceState *d)
/* restore MAC address */
memcpy(s->phys, s->conf.macaddr.a, 6);
+ qemu_format_nic_info_str(qemu_get_queue(s->nic), s->phys);
/* reset interrupt mask */
s->IntrStatus = 0;
@@ -2740,8 +2741,12 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
switch (addr)
{
- case MAC0 ... MAC0+5:
+ case MAC0 ... MAC0+4:
+ s->phys[addr - MAC0] = val;
+ break;
+ case MAC0+5:
s->phys[addr - MAC0] = val;
+ qemu_format_nic_info_str(qemu_get_queue(s->nic), s->phys);
break;
case MAC0+6 ... MAC0+7:
/* reserved */
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index 49c2466434..19687aa03c 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -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);
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index d0820e507b..f5dc3ea845 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -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;
diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c
index a9392c7bdc..440e187c46 100644
--- a/hw/pci-bridge/pci_bridge_dev.c
+++ b/hw/pci-bridge/pci_bridge_dev.c
@@ -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);
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index c041149320..bad3953fb5 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -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)
{
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index ad703a4bf7..b8feed1254 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -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);
diff --git a/hw/pci/Makefile.objs b/hw/pci/Makefile.objs
index 720f438ac9..80f8aa69ac 100644
--- a/hw/pci/Makefile.objs
+++ b/hw/pci/Makefile.objs
@@ -5,7 +5,7 @@ common-obj-$(CONFIG_PCI) += slotid_cap.o
common-obj-$(CONFIG_PCI) += pci_host.o pcie_host.o
common-obj-$(CONFIG_PCI) += pcie.o pcie_aer.o pcie_port.o
-common-obj-$(CONFIG_NO_PCI) += pci-stub.o
+common-obj-$(call lnot,$(CONFIG_PCI)) += pci-stub.o
common-obj-$(CONFIG_ALL) += pci-stub.o
common-obj-$(CONFIG_PCI_HOTPLUG_OLD) += pci-hotplug-old.o
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 00554a05ac..a98c8a0580 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -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);
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 50af3c1dfe..268a696646 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -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);
}
}
diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
index ca762ab09a..32aa0c61b5 100644
--- a/hw/pci/pcie_aer.c
+++ b/hw/pci/pcie_aer.c
@@ -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;
}
diff --git a/hw/pci/pcie_host.c b/hw/pci/pcie_host.c
index b70e5adc4b..c6e1b573e1 100644
--- a/hw/pci/pcie_host.c
+++ b/hw/pci/pcie_host.c
@@ -24,27 +24,6 @@
#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;
diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c
index eb092fdb61..0bbd36e272 100644
--- a/hw/pci/shpc.c
+++ b/hw/pci/shpc.c
@@ -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;
}
diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c
index 99bf8ec446..48c8b82350 100644
--- a/hw/scsi/esp-pci.c
+++ b/hw/scsi/esp-pci.c
@@ -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);
}
diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 36e5f50360..cb30414849 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -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 "
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 09b51b387b..7c5a1a2b3a 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -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;
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index 819d671ba2..94b328f186 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -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
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 7380f063f7..4502ad143d 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -494,7 +494,7 @@ SDState *sd_init(BlockDriverState *bs, bool is_spi)
{
SDState *sd;
- if (bdrv_is_read_only(bs)) {
+ if (bs && bdrv_is_read_only(bs)) {
fprintf(stderr, "sd_init: Cannot use read-only drive\n");
return NULL;
}
diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
index fcd22aea59..2eb75ea945 100644
--- a/hw/timer/hpet.c
+++ b/hw/timer/hpet.c
@@ -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,
diff --git a/hw/usb/hcd-ehci-pci.c b/hw/usb/hcd-ehci-pci.c
index 4d21a0b7bb..0c985942f9 100644
--- a/hw/usb/hcd-ehci-pci.c
+++ b/hw/usb/hcd-ehci-pci.c
@@ -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);
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 0396e334ed..e38cdebfec 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -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;
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index becc7faec1..238d1d2b5f 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -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];
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 469c24d768..4f0bbb72fc 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -449,7 +449,6 @@ struct XHCIState {
/*< public >*/
USBBus bus;
- qemu_irq irq;
MemoryRegion mem;
MemoryRegion mem_cap;
MemoryRegion mem_oper;
@@ -739,7 +738,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 +796,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);
}
}
@@ -3433,8 +3432,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);
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 4825802598..7647be8a3c 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -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;
diff --git a/include/exec/ioport.h b/include/exec/ioport.h
index b3848be684..3bd6722627 100644
--- a/include/exec/ioport.h
+++ b/include/exec/ioport.h
@@ -64,11 +64,13 @@ typedef struct PortioList {
struct MemoryRegion **regions;
void *opaque;
const char *name;
+ bool flush_coalesced_mmio;
} PortioList;
void portio_list_init(PortioList *piolist, Object *owner,
const struct MemoryRegionPortio *callbacks,
void *opaque, const char *name);
+void portio_list_set_flush_coalesced(PortioList *piolist);
void portio_list_destroy(PortioList *piolist);
void portio_list_add(PortioList *piolist,
struct MemoryRegion *address_space,
diff --git a/include/exec/memory.h b/include/exec/memory.h
index ebe0d24182..480dfbf9da 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -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
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index 51733d3390..6bbcb1750d 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -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 */
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index b1fe71faf5..82fcf9f2eb 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -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
index 0000000000..65e6fd7aa0
--- /dev/null
+++ b/include/hw/acpi/piix4.h
@@ -0,0 +1,8 @@
+#ifndef HW_ACPI_PIIX4_H
+#define HW_ACPI_PIIX4_H
+
+#include "qemu/typedefs.h"
+
+Object *piix4_pm_find(void);
+
+#endif
diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h
index c5f637bffd..4a68b359a6 100644
--- a/include/hw/i386/ich9.h
+++ b/include/hw/i386/ich9.h
@@ -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)))
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 6083839084..03cc0ba0f7 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -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
diff --git a/include/hw/irq.h b/include/hw/irq.h
index 610e6b7623..d08bc02a0d 100644
--- a/include/hw/irq.h
+++ b/include/hw/irq.h
@@ -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);
diff --git a/include/hw/loader.h b/include/hw/loader.h
index 61457360f6..58eca9832b 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -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
index 0000000000..37789b69d9
--- /dev/null
+++ b/include/hw/misc/arm_integrator_debug.h
@@ -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
diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
index f60dd676c8..72b1549dc4 100644
--- a/include/hw/nvram/fw_cfg.h
+++ b/include/hw/nvram/fw_cfg.h
@@ -46,12 +46,14 @@
#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);
diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
index 56de92ede2..aee91aa038 100644
--- a/include/hw/pci-host/q35.h
+++ b/include/hw/pci-host/q35.h
@@ -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 */
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 4b90e5d00b..37ffa53119 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -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;
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index 9df17885ec..2ad5edbde9 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -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 */
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index c010007c5e..1966169553 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -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 */
diff --git a/include/hw/pci/pcie_host.h b/include/hw/pci/pcie_host.h
index 1228e36cb2..acca45ed58 100644
--- a/include/hw/pci/pcie_host.h
+++ b/include/hw/pci/pcie_host.h
@@ -28,6 +28,12 @@
#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 */
diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h
index bb50a877cc..f5aaa05ee3 100644
--- a/include/hw/sysbus.h
+++ b/include/hw/sysbus.h
@@ -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);
diff --git a/include/hw/timer/hpet.h b/include/hw/timer/hpet.h
index 757f79fdd2..ab44bd31fd 100644
--- a/include/hw/timer/hpet.h
+++ b/include/hw/timer/hpet.h
@@ -71,4 +71,6 @@ struct hpet_fw_config
} QEMU_PACKED;
extern struct hpet_fw_config hpet_cfg;
+
+bool hpet_find(void);
#endif
diff --git a/include/qemu/seqlock.h b/include/qemu/seqlock.h
new file mode 100644
index 0000000000..3ff118a1a1
--- /dev/null
+++ b/include/qemu/seqlock.h
@@ -0,0 +1,72 @@
+/*
+ * Seqlock implementation for QEMU
+ *
+ * Copyright Red Hat, Inc. 2013
+ *
+ * Author:
+ * Paolo Bonzini <pbonzini@redhat.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_SEQLOCK_H
+#define QEMU_SEQLOCK_H 1
+
+#include <qemu/atomic.h>
+#include <qemu/thread.h>
+
+typedef struct QemuSeqLock QemuSeqLock;
+
+struct QemuSeqLock {
+ QemuMutex *mutex;
+ unsigned sequence;
+};
+
+static inline void seqlock_init(QemuSeqLock *sl, QemuMutex *mutex)
+{
+ sl->mutex = mutex;
+ sl->sequence = 0;
+}
+
+/* Lock out other writers and update the count. */
+static inline void seqlock_write_lock(QemuSeqLock *sl)
+{
+ if (sl->mutex) {
+ qemu_mutex_lock(sl->mutex);
+ }
+ ++sl->sequence;
+
+ /* Write sequence before updating other fields. */
+ smp_wmb();
+}
+
+static inline void seqlock_write_unlock(QemuSeqLock *sl)
+{
+ /* Write other fields before finalizing sequence. */
+ smp_wmb();
+
+ ++sl->sequence;
+ if (sl->mutex) {
+ qemu_mutex_unlock(sl->mutex);
+ }
+}
+
+static inline unsigned seqlock_read_begin(QemuSeqLock *sl)
+{
+ /* Always fail if a write is in progress. */
+ unsigned ret = sl->sequence & ~1;
+
+ /* Read sequence before reading other fields. */
+ smp_rmb();
+ return ret;
+}
+
+static int seqlock_read_retry(const QemuSeqLock *sl, unsigned start)
+{
+ /* Read other fields before reading final sequence. */
+ smp_rmb();
+ return unlikely(sl->sequence != start);
+}
+
+#endif
diff --git a/include/qemu/thread-posix.h b/include/qemu/thread-posix.h
index 361566abc4..eb5c7a1da1 100644
--- a/include/qemu/thread-posix.h
+++ b/include/qemu/thread-posix.h
@@ -21,6 +21,14 @@ struct QemuSemaphore {
#endif
};
+struct QemuEvent {
+#ifndef __linux__
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+#endif
+ unsigned value;
+};
+
struct QemuThread {
pthread_t thread;
};
diff --git a/include/qemu/thread-win32.h b/include/qemu/thread-win32.h
index 13adb958f0..3d58081bed 100644
--- a/include/qemu/thread-win32.h
+++ b/include/qemu/thread-win32.h
@@ -17,6 +17,10 @@ struct QemuSemaphore {
HANDLE sema;
};
+struct QemuEvent {
+ HANDLE event;
+};
+
typedef struct QemuThreadData QemuThreadData;
struct QemuThread {
QemuThreadData *data;
diff --git a/include/qemu/thread.h b/include/qemu/thread.h
index c02404b9fb..3e32c6531c 100644
--- a/include/qemu/thread.h
+++ b/include/qemu/thread.h
@@ -7,6 +7,7 @@
typedef struct QemuMutex QemuMutex;
typedef struct QemuCond QemuCond;
typedef struct QemuSemaphore QemuSemaphore;
+typedef struct QemuEvent QemuEvent;
typedef struct QemuThread QemuThread;
#ifdef _WIN32
@@ -45,6 +46,12 @@ void qemu_sem_wait(QemuSemaphore *sem);
int qemu_sem_timedwait(QemuSemaphore *sem, int ms);
void qemu_sem_destroy(QemuSemaphore *sem);
+void qemu_event_init(QemuEvent *ev, bool init);
+void qemu_event_set(QemuEvent *ev);
+void qemu_event_reset(QemuEvent *ev);
+void qemu_event_wait(QemuEvent *ev);
+void qemu_event_destroy(QemuEvent *ev);
+
void qemu_thread_create(QemuThread *thread,
void *(*start_routine)(void *),
void *arg, int mode);
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index b58903bef5..5afcffc3f9 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -189,6 +189,12 @@ void qemu_clock_notify(QEMUClockType type);
* @enabled: true to enable, false to disable
*
* Enable or disable a clock
+ * Disabling the clock will wait for related timerlists to stop
+ * executing qemu_run_timers. Thus, this functions should not
+ * be used from the callback of a timer that is based on @clock.
+ * Doing so would cause a deadlock.
+ *
+ * Caller should hold BQL.
*/
void qemu_clock_enable(QEMUClockType type, bool enabled);
@@ -539,6 +545,19 @@ void timer_del(QEMUTimer *ts);
void timer_mod_ns(QEMUTimer *ts, int64_t expire_time);
/**
+ * timer_mod_anticipate_ns:
+ * @ts: the timer
+ * @expire_time: the expiry time in nanoseconds
+ *
+ * Modify a timer to expire at @expire_time or the current time,
+ * whichever comes earlier.
+ *
+ * This function is thread-safe but the timer and its timer list must not be
+ * freed while this function is running.
+ */
+void timer_mod_anticipate_ns(QEMUTimer *ts, int64_t expire_time);
+
+/**
* timer_mod:
* @ts: the timer
* @expire_time: the expire time in the units associated with the timer
@@ -552,6 +571,19 @@ void timer_mod_ns(QEMUTimer *ts, int64_t expire_time);
void timer_mod(QEMUTimer *ts, int64_t expire_timer);
/**
+ * timer_mod_anticipate:
+ * @ts: the timer
+ * @expire_time: the expiry time in nanoseconds
+ *
+ * Modify a timer to expire at @expire_time or the current time, whichever
+ * comes earlier, taking into account the scale associated with the timer.
+ *
+ * This function is thread-safe but the timer and its timer list must not be
+ * freed while this function is running.
+ */
+void timer_mod_anticipate(QEMUTimer *ts, int64_t expire_time);
+
+/**
* timer_pending:
* @ts: the timer
*
@@ -653,7 +685,9 @@ static inline int64_t qemu_soonest_timeout(int64_t timeout1, int64_t timeout2)
void init_clocks(void);
int64_t cpu_get_ticks(void);
+/* Caller must hold BQL */
void cpu_enable_ticks(void);
+/* Caller must hold BQL */
void cpu_disable_ticks(void);
static inline int64_t get_ticks_per_sec(void)
diff --git a/include/qom/object.h b/include/qom/object.h
index 1a7b71aba5..d02172adca 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -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:
diff --git a/include/ui/qemu-spice.h b/include/ui/qemu-spice.h
index c6c756b23d..86c75c7a71 100644
--- a/include/ui/qemu-spice.h
+++ b/include/ui/qemu-spice.h
@@ -27,14 +27,15 @@
#include "monitor/monitor.h"
extern int using_spice;
-extern int spice_displays;
void qemu_spice_init(void);
void qemu_spice_input_init(void);
void qemu_spice_audio_init(void);
-void qemu_spice_display_init(DisplayState *ds);
+void qemu_spice_display_init(void);
int qemu_spice_display_add_client(int csock, int skipauth, int tls);
int qemu_spice_add_interface(SpiceBaseInstance *sin);
+bool qemu_spice_have_display_interface(QemuConsole *con);
+int qemu_spice_add_display_interface(QXLInstance *qxlin, QemuConsole *con);
int qemu_spice_set_passwd(const char *passwd,
bool fail_if_connected, bool disconnect_if_connected);
int qemu_spice_set_pw_expire(time_t expires);
diff --git a/ioport.c b/ioport.c
index 707cce88ab..3d91e79edc 100644
--- a/ioport.c
+++ b/ioport.c
@@ -139,6 +139,12 @@ void portio_list_init(PortioList *piolist,
piolist->opaque = opaque;
piolist->owner = owner;
piolist->name = name;
+ piolist->flush_coalesced_mmio = false;
+}
+
+void portio_list_set_flush_coalesced(PortioList *piolist)
+{
+ piolist->flush_coalesced_mmio = true;
}
void portio_list_destroy(PortioList *piolist)
@@ -231,6 +237,9 @@ static void portio_list_add_1(PortioList *piolist,
*/
memory_region_init_io(&mrpio->mr, piolist->owner, &portio_ops, mrpio,
piolist->name, off_high - off_low);
+ if (piolist->flush_coalesced_mmio) {
+ memory_region_set_flush_coalesced(&mrpio->mr);
+ }
memory_region_add_subregion(piolist->address_space,
start + off_low, &mrpio->mr);
piolist->regions[piolist->nr] = &mrpio->mr;
diff --git a/memory.c b/memory.c
index 5a10fd0bde..28f64491d0 100644
--- 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) {
@@ -1809,7 +1809,9 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f,
mr->alias->name,
mr->alias_offset,
mr->alias_offset
- + (hwaddr)int128_get64(mr->size) - 1);
+ + (int128_nz(mr->size) ?
+ (hwaddr)int128_get64(int128_sub(mr->size,
+ int128_one())) : 0));
} else {
mon_printf(f,
TARGET_FMT_plx "-" TARGET_FMT_plx " (prio %d, %c%c): %s\n",
diff --git a/qemu-timer.c b/qemu-timer.c
index 6b62e88669..e15ce477cc 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -45,6 +45,7 @@
/* timers */
typedef struct QEMUClock {
+ /* We rely on BQL to protect the timerlists */
QLIST_HEAD(, QEMUTimerList) timerlists;
NotifierList reset_notifiers;
@@ -71,6 +72,9 @@ struct QEMUTimerList {
QLIST_ENTRY(QEMUTimerList) list;
QEMUTimerListNotifyCB *notify_cb;
void *notify_opaque;
+
+ /* lightweight method to mark the end of timerlist's running */
+ QemuEvent timers_done_ev;
};
/**
@@ -99,6 +103,7 @@ QEMUTimerList *timerlist_new(QEMUClockType type,
QEMUClock *clock = qemu_clock_ptr(type);
timer_list = g_malloc0(sizeof(QEMUTimerList));
+ qemu_event_init(&timer_list->timers_done_ev, false);
timer_list->clock = clock;
timer_list->notify_cb = cb;
timer_list->notify_opaque = opaque;
@@ -143,13 +148,25 @@ void qemu_clock_notify(QEMUClockType type)
}
}
+/* Disabling the clock will wait for related timerlists to stop
+ * executing qemu_run_timers. Thus, this functions should not
+ * be used from the callback of a timer that is based on @clock.
+ * Doing so would cause a deadlock.
+ *
+ * Caller should hold BQL.
+ */
void qemu_clock_enable(QEMUClockType type, bool enabled)
{
QEMUClock *clock = qemu_clock_ptr(type);
+ QEMUTimerList *tl;
bool old = clock->enabled;
clock->enabled = enabled;
if (enabled && !old) {
qemu_clock_notify(type);
+ } else if (!enabled && old) {
+ QLIST_FOREACH(tl, &clock->timerlists, list) {
+ qemu_event_wait(&tl->timers_done_ev);
+ }
}
}
@@ -338,6 +355,34 @@ static void timer_del_locked(QEMUTimerList *timer_list, QEMUTimer *ts)
}
}
+static bool timer_mod_ns_locked(QEMUTimerList *timer_list,
+ QEMUTimer *ts, int64_t expire_time)
+{
+ QEMUTimer **pt, *t;
+
+ /* add the timer in the sorted list */
+ pt = &timer_list->active_timers;
+ for (;;) {
+ t = *pt;
+ if (!timer_expired_ns(t, expire_time)) {
+ break;
+ }
+ pt = &t->next;
+ }
+ ts->expire_time = MAX(expire_time, 0);
+ ts->next = *pt;
+ *pt = ts;
+
+ return pt == &timer_list->active_timers;
+}
+
+static void timerlist_rearm(QEMUTimerList *timer_list)
+{
+ /* Interrupt execution to force deadline recalculation. */
+ qemu_clock_warp(timer_list->clock->type);
+ timerlist_notify(timer_list);
+}
+
/* stop a timer, but do not dealloc it */
void timer_del(QEMUTimer *ts)
{
@@ -353,30 +398,39 @@ void timer_del(QEMUTimer *ts)
void timer_mod_ns(QEMUTimer *ts, int64_t expire_time)
{
QEMUTimerList *timer_list = ts->timer_list;
- QEMUTimer **pt, *t;
+ bool rearm;
qemu_mutex_lock(&timer_list->active_timers_lock);
timer_del_locked(timer_list, ts);
+ rearm = timer_mod_ns_locked(timer_list, ts, expire_time);
+ qemu_mutex_unlock(&timer_list->active_timers_lock);
- /* add the timer in the sorted list */
- pt = &timer_list->active_timers;
- for(;;) {
- t = *pt;
- if (!timer_expired_ns(t, expire_time)) {
- break;
+ if (rearm) {
+ timerlist_rearm(timer_list);
+ }
+}
+
+/* modify the current timer so that it will be fired when current_time
+ >= expire_time or the current deadline, whichever comes earlier.
+ The corresponding callback will be called. */
+void timer_mod_anticipate_ns(QEMUTimer *ts, int64_t expire_time)
+{
+ QEMUTimerList *timer_list = ts->timer_list;
+ bool rearm;
+
+ qemu_mutex_lock(&timer_list->active_timers_lock);
+ if (ts->expire_time == -1 || ts->expire_time > expire_time) {
+ if (ts->expire_time != -1) {
+ timer_del_locked(timer_list, ts);
}
- pt = &t->next;
+ rearm = timer_mod_ns_locked(timer_list, ts, expire_time);
+ } else {
+ rearm = false;
}
- ts->expire_time = MAX(expire_time, 0);
- ts->next = *pt;
- *pt = ts;
qemu_mutex_unlock(&timer_list->active_timers_lock);
- /* Rearm if necessary */
- if (pt == &timer_list->active_timers) {
- /* Interrupt execution to force deadline recalculation. */
- qemu_clock_warp(timer_list->clock->type);
- timerlist_notify(timer_list);
+ if (rearm) {
+ timerlist_rearm(timer_list);
}
}
@@ -385,6 +439,11 @@ void timer_mod(QEMUTimer *ts, int64_t expire_time)
timer_mod_ns(ts, expire_time * ts->scale);
}
+void timer_mod_anticipate(QEMUTimer *ts, int64_t expire_time)
+{
+ timer_mod_anticipate_ns(ts, expire_time * ts->scale);
+}
+
bool timer_pending(QEMUTimer *ts)
{
return ts->expire_time >= 0;
@@ -403,8 +462,9 @@ bool timerlist_run_timers(QEMUTimerList *timer_list)
QEMUTimerCB *cb;
void *opaque;
+ qemu_event_reset(&timer_list->timers_done_ev);
if (!timer_list->clock->enabled) {
- return progress;
+ goto out;
}
current_time = qemu_clock_get_ns(timer_list->clock->type);
@@ -428,6 +488,9 @@ bool timerlist_run_timers(QEMUTimerList *timer_list)
cb(opaque);
progress = true;
}
+
+out:
+ qemu_event_set(&timer_list->timers_done_ev);
return progress;
}
diff --git a/qom/object.c b/qom/object.c
index e90e3827d9..b617f265e7 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -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/rules.mak b/rules.mak
index abc2e846b3..49edb9bf07 100644
--- a/rules.mak
+++ b/rules.mak
@@ -89,6 +89,34 @@ find-in-path = $(if $(find-string /, $1), \
$(wildcard $1), \
$(wildcard $(patsubst %, %/$1, $(subst :, ,$(PATH)))))
+# Logical functions (for operating on y/n values like CONFIG_FOO vars)
+# Inputs to these must be either "y" (true) or "n" or "" (both false)
+# Output is always either "y" or "n".
+# Usage: $(call land,$(CONFIG_FOO),$(CONFIG_BAR))
+# Logical NOT
+lnot = $(if $(subst n,,$1),n,y)
+# Logical AND
+land = $(if $(findstring yy,$1$2),y,n)
+# Logical OR
+lor = $(if $(findstring y,$1$2),y,n)
+# Logical XOR (note that this is the inverse of leqv)
+lxor = $(if $(filter $(call lnot,$1),$(call lnot,$2)),n,y)
+# Logical equivalence (note that leqv "","n" is true)
+leqv = $(if $(filter $(call lnot,$1),$(call lnot,$2)),y,n)
+# Logical if: like make's $(if) but with an leqv-like test
+lif = $(if $(subst n,,$1),$2,$3)
+
+# String testing functions: inputs to these can be any string;
+# the output is always either "y" or "n". Leading and trailing whitespace
+# is ignored when comparing strings.
+# String equality
+eq = $(if $(subst $2,,$1)$(subst $1,,$2),n,y)
+# String inequality
+ne = $(if $(subst $2,,$1)$(subst $1,,$2),y,n)
+# Emptiness/non-emptiness tests:
+isempty = $(if $1,n,y)
+notempty = $(if $1,y,n)
+
# Generate files with tracetool
TRACETOOL=$(PYTHON) $(SRC_PATH)/scripts/tracetool.py
diff --git a/scripts/acpi_extract.py b/scripts/acpi_extract.py
new file mode 100755
index 0000000000..22ea468102
--- /dev/null
+++ b/scripts/acpi_extract.py
@@ -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
index 0000000000..69d10d621c
--- /dev/null
+++ b/scripts/acpi_extract_preprocess.py
@@ -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
index 0000000000..b5f05ff3cf
--- /dev/null
+++ b/scripts/update-acpi.sh
@@ -0,0 +1,4 @@
+cd x86_64-softmmu
+for file in hw/i386/*.hex; do
+ cp -f $file ../$file.generated
+done
diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
index 6453f5c011..356fbfcdfd 100644
--- a/target-arm/Makefile.objs
+++ b/target-arm/Makefile.objs
@@ -1,7 +1,7 @@
obj-y += arm-semi.o
obj-$(CONFIG_SOFTMMU) += machine.o
obj-$(CONFIG_KVM) += kvm.o
-obj-$(CONFIG_NO_KVM) += kvm-stub.o
+obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
obj-y += translate.o op_helper.o helper.o cpu.o
obj-y += neon_helper.o iwmmxt_helper.o
obj-y += gdbstub.o
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 2c56740bf6..9f110f15b6 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -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. */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index c63bbd7fc1..3445813465 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -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);
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index b92e00dae0..6e5cd36fae 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -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)
diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs
index da1fc404c7..027b94e1d3 100644
--- a/target-i386/Makefile.objs
+++ b/target-i386/Makefile.objs
@@ -4,6 +4,6 @@ obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o
obj-y += gdbstub.o
obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o
obj-$(CONFIG_KVM) += kvm.o
-obj-$(CONFIG_NO_KVM) += kvm-stub.o
+obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
obj-$(CONFIG_LINUX_USER) += ioport-user.o
obj-$(CONFIG_BSD_USER) += ioport-user.o
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index d0c9bdb629..864c80eb47 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -328,6 +328,15 @@ X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
};
#undef REGISTER
+typedef struct ExtSaveArea {
+ uint32_t feature, bits;
+ uint32_t offset, size;
+} ExtSaveArea;
+
+static const ExtSaveArea ext_save_areas[] = {
+ [2] = { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX,
+ .offset = 0x100, .size = 0x240 },
+};
const char *get_register_name_32(unsigned int reg)
{
@@ -2177,29 +2186,51 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*edx = 0;
}
break;
- case 0xD:
+ case 0xD: {
+ KVMState *s = cs->kvm_state;
+ uint64_t kvm_mask;
+ int i;
+
/* Processor Extended State */
- if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
- *eax = 0;
- *ebx = 0;
- *ecx = 0;
- *edx = 0;
+ *eax = 0;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0;
+ if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) || !kvm_enabled()) {
break;
}
- if (kvm_enabled()) {
- KVMState *s = cs->kvm_state;
+ kvm_mask =
+ kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EAX) |
+ ((uint64_t)kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EDX) << 32);
- *eax = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EAX);
- *ebx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EBX);
- *ecx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_ECX);
- *edx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EDX);
- } else {
- *eax = 0;
- *ebx = 0;
- *ecx = 0;
- *edx = 0;
+ if (count == 0) {
+ *ecx = 0x240;
+ for (i = 2; i < ARRAY_SIZE(ext_save_areas); i++) {
+ const ExtSaveArea *esa = &ext_save_areas[i];
+ if ((env->features[esa->feature] & esa->bits) == esa->bits &&
+ (kvm_mask & (1 << i)) != 0) {
+ if (i < 32) {
+ *eax |= 1 << i;
+ } else {
+ *edx |= 1 << (i - 32);
+ }
+ *ecx = MAX(*ecx, esa->offset + esa->size);
+ }
+ }
+ *eax |= kvm_mask & (XSTATE_FP | XSTATE_SSE);
+ *ebx = *ecx;
+ } else if (count == 1) {
+ *eax = kvm_arch_get_supported_cpuid(s, 0xd, 1, R_EAX);
+ } else if (count < ARRAY_SIZE(ext_save_areas)) {
+ const ExtSaveArea *esa = &ext_save_areas[count];
+ if ((env->features[esa->feature] & esa->bits) == esa->bits &&
+ (kvm_mask & (1 << count)) != 0) {
+ *eax = esa->offset;
+ *ebx = esa->size;
+ }
}
break;
+ }
case 0x80000000:
*eax = env->cpuid_xlevel;
*ebx = env->cpuid_vendor1;
@@ -2402,6 +2433,7 @@ static void x86_cpu_reset(CPUState *s)
env->fpuc = 0x37f;
env->mxcsr = 0x1f80;
+ env->xstate_bv = XSTATE_FP | XSTATE_SSE;
env->pat = 0x0007040600070406ULL;
env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 5723eff9a8..ea373e82dc 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -380,6 +380,10 @@
#define MSR_VM_HSAVE_PA 0xc0010117
+#define XSTATE_FP 1
+#define XSTATE_SSE 2
+#define XSTATE_YMM 4
+
/* CPUID feature words */
typedef enum FeatureWord {
FEAT_1_EDX, /* CPUID[1].EDX */
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index 7508cf5a06..e1415f043c 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -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
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 1b937b3f0d..9edcb67e66 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -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/target-ppc/Makefile.objs b/target-ppc/Makefile.objs
index f72e3993f7..94d6d0c43b 100644
--- a/target-ppc/Makefile.objs
+++ b/target-ppc/Makefile.objs
@@ -5,7 +5,7 @@ obj-y += machine.o mmu_helper.o mmu-hash32.o
obj-$(TARGET_PPC64) += mmu-hash64.o
endif
obj-$(CONFIG_KVM) += kvm.o kvm_ppc.o
-obj-$(CONFIG_NO_KVM) += kvm-stub.o
+obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
obj-y += excp_helper.o
obj-y += fpu_helper.o
obj-y += int_helper.o
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 06641bb7d0..2d2df33115 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -3016,6 +3016,14 @@ void gen_intermediate_code_internal(XtensaCPU *cpu,
gen_tb_end(tb, insn_count);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
+#ifdef DEBUG_DISAS
+ if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
+ qemu_log("----------------\n");
+ qemu_log("IN: %s\n", lookup_symbol(pc_start));
+ log_target_disas(env, pc_start, dc.pc - pc_start, 0);
+ qemu_log("\n");
+ }
+#endif
if (search_pc) {
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
memset(tcg_ctx.gen_opc_instr_start + lj + 1, 0,
diff --git a/ui/Makefile.objs b/ui/Makefile.objs
index 6ddc0def6d..f33be47576 100644
--- a/ui/Makefile.objs
+++ b/ui/Makefile.objs
@@ -17,6 +17,4 @@ common-obj-$(CONFIG_GTK) += gtk.o x_keymap.o
$(obj)/sdl.o $(obj)/sdl_zoom.o: QEMU_CFLAGS += $(SDL_CFLAGS)
-$(obj)/cocoa.o: $(SRC_PATH)/$(obj)/cocoa.m
-
$(obj)/gtk.o: QEMU_CFLAGS += $(GTK_CFLAGS) $(VTE_CFLAGS)
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 33ef83731a..e4d533d4c4 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -48,7 +48,6 @@ static char *auth_passwd;
static time_t auth_expires = TIME_MAX;
static int spice_migration_completed;
int using_spice = 0;
-int spice_displays;
static QemuThread me;
@@ -383,17 +382,16 @@ static SpiceChannelList *qmp_query_spice_channels(void)
struct sockaddr *paddr;
socklen_t plen;
+ if (!(item->info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT)) {
+ error_report("invalid channel event");
+ return NULL;
+ }
+
chan = g_malloc0(sizeof(*chan));
chan->value = g_malloc0(sizeof(*chan->value));
- if (item->info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) {
- paddr = (struct sockaddr *)&item->info->paddr_ext;
- plen = item->info->plen_ext;
- } else {
- paddr = &item->info->paddr;
- plen = item->info->plen;
- }
-
+ paddr = (struct sockaddr *)&item->info->paddr_ext;
+ plen = item->info->plen_ext;
getnameinfo(paddr, plen,
host, sizeof(host), port, sizeof(port),
NI_NUMERICHOST | NI_NUMERICSERV);
@@ -833,15 +831,33 @@ int qemu_spice_add_interface(SpiceBaseInstance *sin)
* With a command line like '-vnc :0 -vga qxl' you'll end up here.
*/
spice_server = spice_server_new();
+ spice_server_set_sasl_appname(spice_server, "qemu");
spice_server_init(spice_server, &core_interface);
qemu_add_vm_change_state_handler(vm_change_state_handler, NULL);
}
- if (strcmp(sin->sif->type, SPICE_INTERFACE_QXL) == 0) {
- spice_displays++;
+ return spice_server_add_interface(spice_server, sin);
+}
+
+static GSList *spice_consoles;
+static int display_id;
+
+bool qemu_spice_have_display_interface(QemuConsole *con)
+{
+ if (g_slist_find(spice_consoles, con)) {
+ return true;
}
+ return false;
+}
- return spice_server_add_interface(spice_server, sin);
+int qemu_spice_add_display_interface(QXLInstance *qxlin, QemuConsole *con)
+{
+ if (g_slist_find(spice_consoles, con)) {
+ return -1;
+ }
+ qxlin->id = display_id++;
+ spice_consoles = g_slist_append(spice_consoles, con);
+ return qemu_spice_add_interface(&qxlin->base);
}
static int qemu_spice_set_ticket(bool fail_if_conn, bool disconnect_if_conn)
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 82d8b9f9a5..f23a31854d 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -83,14 +83,14 @@ void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
(uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
QXL_IO_MEMSLOT_ADD_ASYNC));
} else {
- ssd->worker->add_memslot(ssd->worker, memslot);
+ spice_qxl_add_memslot(&ssd->qxl, memslot);
}
}
void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid)
{
trace_qemu_spice_del_memslot(ssd->qxl.id, gid, sid);
- ssd->worker->del_memslot(ssd->worker, gid, sid);
+ spice_qxl_del_memslot(&ssd->qxl, gid, sid);
}
void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
@@ -103,7 +103,7 @@ void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
(uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
QXL_IO_CREATE_PRIMARY_ASYNC));
} else {
- ssd->worker->create_primary_surface(ssd->worker, id, surface);
+ spice_qxl_create_primary_surface(&ssd->qxl, id, surface);
}
}
@@ -116,14 +116,14 @@ void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
(uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
QXL_IO_DESTROY_PRIMARY_ASYNC));
} else {
- ssd->worker->destroy_primary_surface(ssd->worker, id);
+ spice_qxl_destroy_primary_surface(&ssd->qxl, id);
}
}
void qemu_spice_wakeup(SimpleSpiceDisplay *ssd)
{
trace_qemu_spice_wakeup(ssd->qxl.id);
- ssd->worker->wakeup(ssd->worker);
+ spice_qxl_wakeup(&ssd->qxl);
}
static int spice_display_is_running;
@@ -297,7 +297,7 @@ void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd)
{
QXLDevMemSlot memslot;
- dprint(1, "%s:\n", __FUNCTION__);
+ dprint(1, "%s/%d:\n", __func__, ssd->qxl.id);
memset(&memslot, 0, sizeof(memslot));
memslot.slot_group_id = MEMSLOT_GROUP_HOST;
@@ -311,7 +311,7 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
memset(&surface, 0, sizeof(surface));
- dprint(1, "%s: %dx%d\n", __FUNCTION__,
+ dprint(1, "%s/%d: %dx%d\n", __func__, ssd->qxl.id,
surface_width(ssd->ds), surface_height(ssd->ds));
surface.format = SPICE_SURFACE_FMT_32_xRGB;
@@ -329,7 +329,7 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
{
- dprint(1, "%s:\n", __FUNCTION__);
+ dprint(1, "%s/%d:\n", __func__, ssd->qxl.id);
qemu_spice_destroy_primary_surface(ssd, 0, QXL_SYNC);
}
@@ -354,7 +354,8 @@ void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
{
QXLRect update_area;
- dprint(2, "%s: x %d y %d w %d h %d\n", __FUNCTION__, x, y, w, h);
+ dprint(2, "%s/%d: x %d y %d w %d h %d\n", __func__,
+ ssd->qxl.id, x, y, w, h);
update_area.left = x,
update_area.right = x + w;
update_area.top = y;
@@ -371,7 +372,7 @@ void qemu_spice_display_switch(SimpleSpiceDisplay *ssd,
{
SimpleSpiceUpdate *update;
- dprint(1, "%s:\n", __FUNCTION__);
+ dprint(1, "%s/%d:\n", __func__, ssd->qxl.id);
memset(&ssd->dirty, 0, sizeof(ssd->dirty));
if (ssd->surface) {
@@ -413,7 +414,7 @@ void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
{
- dprint(3, "%s:\n", __func__);
+ dprint(3, "%s/%d:\n", __func__, ssd->qxl.id);
graphic_hw_update(ssd->dcl.con);
qemu_mutex_lock(&ssd->lock);
@@ -427,7 +428,7 @@ void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
if (ssd->notify) {
ssd->notify = 0;
qemu_spice_wakeup(ssd);
- dprint(2, "%s: notify\n", __FUNCTION__);
+ dprint(2, "%s/%d: notify\n", __func__, ssd->qxl.id);
}
}
@@ -437,19 +438,19 @@ static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
{
SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
- dprint(1, "%s:\n", __FUNCTION__);
+ dprint(1, "%s/%d:\n", __func__, ssd->qxl.id);
ssd->worker = qxl_worker;
}
static void interface_set_compression_level(QXLInstance *sin, int level)
{
- dprint(1, "%s:\n", __FUNCTION__);
+ dprint(1, "%s/%d:\n", __func__, sin->id);
/* nothing to do */
}
static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
{
- dprint(3, "%s:\n", __FUNCTION__);
+ dprint(3, "%s/%d:\n", __func__, sin->id);
/* nothing to do */
}
@@ -472,7 +473,7 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
SimpleSpiceUpdate *update;
int ret = false;
- dprint(3, "%s:\n", __FUNCTION__);
+ dprint(3, "%s/%d:\n", __func__, ssd->qxl.id);
qemu_mutex_lock(&ssd->lock);
update = QTAILQ_FIRST(&ssd->updates);
@@ -488,7 +489,7 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
static int interface_req_cmd_notification(QXLInstance *sin)
{
- dprint(1, "%s:\n", __FUNCTION__);
+ dprint(1, "%s/%d:\n", __func__, sin->id);
return 1;
}
@@ -498,7 +499,7 @@ static void interface_release_resource(QXLInstance *sin,
SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
uintptr_t id;
- dprint(2, "%s:\n", __FUNCTION__);
+ dprint(2, "%s/%d:\n", __func__, ssd->qxl.id);
id = ext.info->id;
qemu_spice_destroy_update(ssd, (void*)id);
}
@@ -611,21 +612,38 @@ static const DisplayChangeListenerOps display_listener_ops = {
.dpy_refresh = display_refresh,
};
-void qemu_spice_display_init(DisplayState *ds)
+static void qemu_spice_display_init_one(QemuConsole *con)
{
SimpleSpiceDisplay *ssd = g_new0(SimpleSpiceDisplay, 1);
qemu_spice_display_init_common(ssd);
ssd->qxl.base.sif = &dpy_interface.base;
- qemu_spice_add_interface(&ssd->qxl.base);
+ qemu_spice_add_display_interface(&ssd->qxl, con);
assert(ssd->worker);
qemu_spice_create_host_memslot(ssd);
ssd->dcl.ops = &display_listener_ops;
- ssd->dcl.con = qemu_console_lookup_by_index(0);
+ ssd->dcl.con = con;
register_displaychangelistener(&ssd->dcl);
qemu_spice_create_host_primary(ssd);
}
+
+void qemu_spice_display_init(void)
+{
+ QemuConsole *con;
+ int i;
+
+ for (i = 0;; i++) {
+ con = qemu_console_lookup_by_index(i);
+ if (!con || !qemu_console_is_graphic(con)) {
+ break;
+ }
+ if (qemu_spice_have_display_interface(con)) {
+ continue;
+ }
+ qemu_spice_display_init_one(con);
+ }
+}
diff --git a/util/compatfd.c b/util/compatfd.c
index 9cf3f2834d..430a41c855 100644
--- a/util/compatfd.c
+++ b/util/compatfd.c
@@ -15,9 +15,9 @@
#include "qemu-common.h"
#include "qemu/compatfd.h"
+#include "qemu/thread.h"
#include <sys/syscall.h>
-#include <pthread.h>
struct sigfd_compat_info
{
@@ -28,10 +28,6 @@ struct sigfd_compat_info
static void *sigwait_compat(void *opaque)
{
struct sigfd_compat_info *info = opaque;
- sigset_t all;
-
- sigfillset(&all);
- pthread_sigmask(SIG_BLOCK, &all, NULL);
while (1) {
int sig;
@@ -71,9 +67,8 @@ static void *sigwait_compat(void *opaque)
static int qemu_signalfd_compat(const sigset_t *mask)
{
- pthread_attr_t attr;
- pthread_t tid;
struct sigfd_compat_info *info;
+ QemuThread thread;
int fds[2];
info = malloc(sizeof(*info));
@@ -93,12 +88,7 @@ static int qemu_signalfd_compat(const sigset_t *mask)
memcpy(&info->mask, mask, sizeof(*mask));
info->fd = fds[1];
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- pthread_create(&tid, &attr, sigwait_compat, info);
-
- pthread_attr_destroy(&attr);
+ qemu_thread_create(&thread, sigwait_compat, info, QEMU_THREAD_DETACHED);
return fds[0];
}
diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c
index 4de133e7b2..37dd298631 100644
--- a/util/qemu-thread-posix.c
+++ b/util/qemu-thread-posix.c
@@ -20,7 +20,12 @@
#include <limits.h>
#include <unistd.h>
#include <sys/time.h>
+#ifdef __linux__
+#include <sys/syscall.h>
+#include <linux/futex.h>
+#endif
#include "qemu/thread.h"
+#include "qemu/atomic.h"
static void error_exit(int err, const char *msg)
{
@@ -272,6 +277,117 @@ void qemu_sem_wait(QemuSemaphore *sem)
#endif
}
+#ifdef __linux__
+#define futex(...) syscall(__NR_futex, __VA_ARGS__)
+
+static inline void futex_wake(QemuEvent *ev, int n)
+{
+ futex(ev, FUTEX_WAKE, n, NULL, NULL, 0);
+}
+
+static inline void futex_wait(QemuEvent *ev, unsigned val)
+{
+ futex(ev, FUTEX_WAIT, (int) val, NULL, NULL, 0);
+}
+#else
+static inline void futex_wake(QemuEvent *ev, int n)
+{
+ if (n == 1) {
+ pthread_cond_signal(&ev->cond);
+ } else {
+ pthread_cond_broadcast(&ev->cond);
+ }
+}
+
+static inline void futex_wait(QemuEvent *ev, unsigned val)
+{
+ pthread_mutex_lock(&ev->lock);
+ if (ev->value == val) {
+ pthread_cond_wait(&ev->cond, &ev->lock);
+ }
+ pthread_mutex_unlock(&ev->lock);
+}
+#endif
+
+/* Valid transitions:
+ * - free->set, when setting the event
+ * - busy->set, when setting the event, followed by futex_wake
+ * - set->free, when resetting the event
+ * - free->busy, when waiting
+ *
+ * set->busy does not happen (it can be observed from the outside but
+ * it really is set->free->busy).
+ *
+ * busy->free provably cannot happen; to enforce it, the set->free transition
+ * is done with an OR, which becomes a no-op if the event has concurrently
+ * transitioned to free or busy.
+ */
+
+#define EV_SET 0
+#define EV_FREE 1
+#define EV_BUSY -1
+
+void qemu_event_init(QemuEvent *ev, bool init)
+{
+#ifndef __linux__
+ pthread_mutex_init(&ev->lock, NULL);
+ pthread_cond_init(&ev->cond, NULL);
+#endif
+
+ ev->value = (init ? EV_SET : EV_FREE);
+}
+
+void qemu_event_destroy(QemuEvent *ev)
+{
+#ifndef __linux__
+ pthread_mutex_destroy(&ev->lock);
+ pthread_cond_destroy(&ev->cond);
+#endif
+}
+
+void qemu_event_set(QemuEvent *ev)
+{
+ if (atomic_mb_read(&ev->value) != EV_SET) {
+ if (atomic_xchg(&ev->value, EV_SET) == EV_BUSY) {
+ /* There were waiters, wake them up. */
+ futex_wake(ev, INT_MAX);
+ }
+ }
+}
+
+void qemu_event_reset(QemuEvent *ev)
+{
+ if (atomic_mb_read(&ev->value) == EV_SET) {
+ /*
+ * If there was a concurrent reset (or even reset+wait),
+ * do nothing. Otherwise change EV_SET->EV_FREE.
+ */
+ atomic_or(&ev->value, EV_FREE);
+ }
+}
+
+void qemu_event_wait(QemuEvent *ev)
+{
+ unsigned value;
+
+ value = atomic_mb_read(&ev->value);
+ if (value != EV_SET) {
+ if (value == EV_FREE) {
+ /*
+ * Leave the event reset and tell qemu_event_set that there
+ * are waiters. No need to retry, because there cannot be
+ * a concurent busy->free transition. After the CAS, the
+ * event will be either set or busy.
+ */
+ if (atomic_cmpxchg(&ev->value, EV_FREE, EV_BUSY) == EV_SET) {
+ return;
+ }
+ }
+ futex_wait(ev, EV_BUSY);
+ }
+}
+
+
void qemu_thread_create(QemuThread *thread,
void *(*start_routine)(void*),
void *arg, int mode)
diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c
index 517878dcc1..27a5217769 100644
--- a/util/qemu-thread-win32.c
+++ b/util/qemu-thread-win32.c
@@ -227,6 +227,32 @@ void qemu_sem_wait(QemuSemaphore *sem)
}
}
+void qemu_event_init(QemuEvent *ev, bool init)
+{
+ /* Manual reset. */
+ ev->event = CreateEvent(NULL, TRUE, init, NULL);
+}
+
+void qemu_event_destroy(QemuEvent *ev)
+{
+ CloseHandle(ev->event);
+}
+
+void qemu_event_set(QemuEvent *ev)
+{
+ SetEvent(ev->event);
+}
+
+void qemu_event_reset(QemuEvent *ev)
+{
+ ResetEvent(ev->event);
+}
+
+void qemu_event_wait(QemuEvent *ev)
+{
+ WaitForSingleObject(ev->event, INFINITE);
+}
+
struct QemuThreadData {
/* Passed to win32_start_routine. */
void *(*start_routine)(void *);
diff --git a/vl.c b/vl.c
index 7e1f40880d..efbff6512a 100644
--- a/vl.c
+++ b/vl.c
@@ -4315,8 +4315,8 @@ int main(int argc, char **argv, char **envp)
}
#endif
#ifdef CONFIG_SPICE
- if (using_spice && !spice_displays) {
- qemu_spice_display_init(ds);
+ if (using_spice) {
+ qemu_spice_display_init();
}
#endif
@@ -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) {