aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/acpi.c359
-rw-r--r--hw/acpi.h2
-rw-r--r--hw/acpi_ich9.c2
-rw-r--r--hw/acpi_piix4.c2
-rw-r--r--hw/apic_common.c2
-rw-r--r--hw/arm/nseries.c18
-rw-r--r--hw/arm/pxa2xx.c4
-rw-r--r--hw/arm/xilinx_zynq.c3
-rw-r--r--hw/arm_gic_common.c112
-rw-r--r--hw/arm_gic_internal.h42
-rw-r--r--hw/arm_mptimer.c5
-rw-r--r--hw/armv7m_nvic.c4
-rw-r--r--hw/bt-hci-csr.c1
-rw-r--r--hw/cadence_uart.c1
-rw-r--r--hw/i386/kvmvapic.c2
-rw-r--r--hw/i386/pc.c32
-rw-r--r--hw/ipoctal232.c42
-rw-r--r--hw/ivshmem.c1
-rw-r--r--hw/mcf_uart.c1
-rw-r--r--hw/microblaze/petalogix_ml605_mmu.c3
-rw-r--r--hw/nand.c1
-rw-r--r--hw/onenand.c3
-rw-r--r--hw/pc.h4
-rw-r--r--hw/pci/pci-hotplug.c2
-rw-r--r--hw/pflash_cfi01.c30
-rw-r--r--hw/pl050.c5
-rw-r--r--hw/pl330.c3
-rw-r--r--hw/qdev-properties-system.c5
-rw-r--r--hw/scsi-bus.c8
-rw-r--r--hw/scsi.h3
-rw-r--r--hw/sd.c2
-rw-r--r--hw/sh_serial.c4
-rw-r--r--hw/usb/dev-storage.c2
-rw-r--r--hw/vt82c686.c2
-rw-r--r--hw/xen_backend.c15
-rw-r--r--hw/xen_backend.h2
-rw-r--r--hw/xen_console.c18
-rw-r--r--hw/xen_disk.c76
-rw-r--r--hw/xilinx_axienet.c2
39 files changed, 456 insertions, 369 deletions
diff --git a/hw/acpi.c b/hw/acpi.c
index 53e47d5857..856da81f0c 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -23,10 +23,14 @@
#include "hw/pc.h"
#include "hw/acpi.h"
#include "monitor/monitor.h"
+#include "qemu/config-file.h"
+#include "qapi/opts-visitor.h"
+#include "qapi/dealloc-visitor.h"
+#include "qapi-visit.h"
struct acpi_table_header {
uint16_t _length; /* our length, not actual part of the hdr */
- /* XXX why we have 2 length fields here? */
+ /* allows easier parsing for fw_cfg clients */
char sig[4]; /* ACPI signature (4 ASCII characters) */
uint32_t length; /* Length of table, in bytes, including header */
uint8_t revision; /* ACPI Specification minor version # */
@@ -41,16 +45,29 @@ struct acpi_table_header {
#define ACPI_TABLE_HDR_SIZE sizeof(struct acpi_table_header)
#define ACPI_TABLE_PFX_SIZE sizeof(uint16_t) /* size of the extra prefix */
-static const char dfl_hdr[ACPI_TABLE_HDR_SIZE] =
- "\0\0" /* fake _length (2) */
+static const char unsigned dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
"QEMU\0\0\0\0\1\0" /* sig (4), len(4), revno (1), csum (1) */
"QEMUQEQEMUQEMU\1\0\0\0" /* OEM id (6), table (8), revno (4) */
"QEMU\1\0\0\0" /* ASL compiler ID (4), version (4) */
;
-char *acpi_tables;
+char unsigned *acpi_tables;
size_t acpi_tables_len;
+static QemuOptsList qemu_acpi_opts = {
+ .name = "acpi",
+ .implied_opt_name = "data",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_acpi_opts.head),
+ .desc = { { 0 } } /* validated with OptsVisitor */
+};
+
+static void acpi_register_config(void)
+{
+ qemu_add_opts(&qemu_acpi_opts);
+}
+
+machine_init(acpi_register_config);
+
static int acpi_checksum(const uint8_t *data, int len)
{
int sum, i;
@@ -61,184 +78,235 @@ static int acpi_checksum(const uint8_t *data, int len)
return (-sum) & 0xff;
}
-/* XXX fixme: this function uses obsolete argument parsing interface */
-int acpi_table_add(const char *t)
-{
- char buf[1024], *p, *f;
- unsigned long val;
- size_t len, start, allen;
- bool has_header;
- int changed;
- int r;
- struct acpi_table_header hdr;
-
- r = 0;
- r |= get_param_value(buf, sizeof(buf), "data", t) ? 1 : 0;
- r |= get_param_value(buf, sizeof(buf), "file", t) ? 2 : 0;
- switch (r) {
- case 0:
- buf[0] = '\0';
- /* fallthrough for default behavior */
- case 1:
- has_header = false;
- break;
- case 2:
- has_header = true;
- break;
- default:
- fprintf(stderr, "acpitable: both data and file are specified\n");
- return -1;
- }
- if (!acpi_tables) {
- allen = sizeof(uint16_t);
- acpi_tables = g_malloc0(allen);
+/* Install a copy of the ACPI table specified in @blob.
+ *
+ * If @has_header is set, @blob starts with the System Description Table Header
+ * structure. Otherwise, "dfl_hdr" is prepended. In any case, each header field
+ * is optionally overwritten from @hdrs.
+ *
+ * It is valid to call this function with
+ * (@blob == NULL && bloblen == 0 && !has_header).
+ *
+ * @hdrs->file and @hdrs->data are ignored.
+ *
+ * SIZE_MAX is considered "infinity" in this function.
+ *
+ * The number of tables that can be installed is not limited, but the 16-bit
+ * counter at the beginning of "acpi_tables" wraps around after UINT16_MAX.
+ */
+static void acpi_table_install(const char unsigned *blob, size_t bloblen,
+ bool has_header,
+ const struct AcpiTableOptions *hdrs,
+ Error **errp)
+{
+ size_t body_start;
+ const char unsigned *hdr_src;
+ size_t body_size, acpi_payload_size;
+ struct acpi_table_header *ext_hdr;
+ unsigned changed_fields;
+
+ /* Calculate where the ACPI table body starts within the blob, plus where
+ * to copy the ACPI table header from.
+ */
+ if (has_header) {
+ /* _length | ACPI header in blob | blob body
+ * ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^
+ * ACPI_TABLE_PFX_SIZE sizeof dfl_hdr body_size
+ * == body_start
+ *
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * acpi_payload_size == bloblen
+ */
+ body_start = sizeof dfl_hdr;
+
+ if (bloblen < body_start) {
+ error_setg(errp, "ACPI table claiming to have header is too "
+ "short, available: %zu, expected: %zu", bloblen,
+ body_start);
+ return;
+ }
+ hdr_src = blob;
} else {
- allen = acpi_tables_len;
+ /* _length | ACPI header in template | blob body
+ * ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^
+ * ACPI_TABLE_PFX_SIZE sizeof dfl_hdr body_size
+ * == bloblen
+ *
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * acpi_payload_size
+ */
+ body_start = 0;
+ hdr_src = dfl_hdr;
}
+ body_size = bloblen - body_start;
+ acpi_payload_size = sizeof dfl_hdr + body_size;
- start = allen;
- acpi_tables = g_realloc(acpi_tables, start + ACPI_TABLE_HDR_SIZE);
- allen += has_header ? ACPI_TABLE_PFX_SIZE : ACPI_TABLE_HDR_SIZE;
+ if (acpi_payload_size > UINT16_MAX) {
+ error_setg(errp, "ACPI table too big, requested: %zu, max: %u",
+ acpi_payload_size, (unsigned)UINT16_MAX);
+ return;
+ }
- /* now read in the data files, reallocating buffer as needed */
+ /* We won't fail from here on. Initialize / extend the globals. */
+ if (acpi_tables == NULL) {
+ acpi_tables_len = sizeof(uint16_t);
+ acpi_tables = g_malloc0(acpi_tables_len);
+ }
- for (f = strtok(buf, ":"); f; f = strtok(NULL, ":")) {
- int fd = open(f, O_RDONLY | O_BINARY);
+ acpi_tables = g_realloc(acpi_tables, acpi_tables_len +
+ ACPI_TABLE_PFX_SIZE +
+ sizeof dfl_hdr + body_size);
- if (fd < 0) {
- fprintf(stderr, "can't open file %s: %s\n", f, strerror(errno));
- return -1;
- }
+ ext_hdr = (struct acpi_table_header *)(acpi_tables + acpi_tables_len);
+ acpi_tables_len += ACPI_TABLE_PFX_SIZE;
- for (;;) {
- char data[8192];
- r = read(fd, data, sizeof(data));
- if (r == 0) {
- break;
- } else if (r > 0) {
- acpi_tables = g_realloc(acpi_tables, allen + r);
- memcpy(acpi_tables + allen, data, r);
- allen += r;
- } else if (errno != EINTR) {
- fprintf(stderr, "can't read file %s: %s\n",
- f, strerror(errno));
- close(fd);
- return -1;
- }
- }
+ memcpy(acpi_tables + acpi_tables_len, hdr_src, sizeof dfl_hdr);
+ acpi_tables_len += sizeof dfl_hdr;
- close(fd);
+ if (blob != NULL) {
+ memcpy(acpi_tables + acpi_tables_len, blob + body_start, body_size);
+ acpi_tables_len += body_size;
}
- /* now fill in the header fields */
+ /* increase number of tables */
+ cpu_to_le16wu((uint16_t *)acpi_tables,
+ le16_to_cpupu((uint16_t *)acpi_tables) + 1u);
- f = acpi_tables + start; /* start of the table */
- changed = 0;
+ /* Update the header fields. The strings need not be NUL-terminated. */
+ changed_fields = 0;
+ ext_hdr->_length = cpu_to_le16(acpi_payload_size);
- /* copy the header to temp place to align the fields */
- memcpy(&hdr, has_header ? f : dfl_hdr, ACPI_TABLE_HDR_SIZE);
+ if (hdrs->has_sig) {
+ strncpy(ext_hdr->sig, hdrs->sig, sizeof ext_hdr->sig);
+ ++changed_fields;
+ }
- /* length of the table minus our prefix */
- len = allen - start - ACPI_TABLE_PFX_SIZE;
+ if (has_header && le32_to_cpu(ext_hdr->length) != acpi_payload_size) {
+ fprintf(stderr,
+ "warning: ACPI table has wrong length, header says "
+ "%" PRIu32 ", actual size %zu bytes\n",
+ le32_to_cpu(ext_hdr->length), acpi_payload_size);
+ }
+ ext_hdr->length = cpu_to_le32(acpi_payload_size);
- hdr._length = cpu_to_le16(len);
+ if (hdrs->has_rev) {
+ ext_hdr->revision = hdrs->rev;
+ ++changed_fields;
+ }
- if (get_param_value(buf, sizeof(buf), "sig", t)) {
- /* strncpy is justified: the field need not be NUL-terminated. */
- strncpy(hdr.sig, buf, sizeof(hdr.sig));
- ++changed;
+ ext_hdr->checksum = 0;
+
+ if (hdrs->has_oem_id) {
+ strncpy(ext_hdr->oem_id, hdrs->oem_id, sizeof ext_hdr->oem_id);
+ ++changed_fields;
+ }
+ if (hdrs->has_oem_table_id) {
+ strncpy(ext_hdr->oem_table_id, hdrs->oem_table_id,
+ sizeof ext_hdr->oem_table_id);
+ ++changed_fields;
+ }
+ if (hdrs->has_oem_rev) {
+ ext_hdr->oem_revision = cpu_to_le32(hdrs->oem_rev);
+ ++changed_fields;
+ }
+ if (hdrs->has_asl_compiler_id) {
+ strncpy(ext_hdr->asl_compiler_id, hdrs->asl_compiler_id,
+ sizeof ext_hdr->asl_compiler_id);
+ ++changed_fields;
+ }
+ if (hdrs->has_asl_compiler_rev) {
+ ext_hdr->asl_compiler_revision = cpu_to_le32(hdrs->asl_compiler_rev);
+ ++changed_fields;
}
- /* length of the table including header, in bytes */
- if (has_header) {
- /* check if actual length is correct */
- val = le32_to_cpu(hdr.length);
- if (val != len) {
- fprintf(stderr,
- "warning: acpitable has wrong length,"
- " header says %lu, actual size %zu bytes\n",
- val, len);
- ++changed;
- }
+ if (!has_header && changed_fields == 0) {
+ fprintf(stderr, "warning: ACPI table: no headers are specified\n");
}
- /* we may avoid putting length here if has_header is true */
- hdr.length = cpu_to_le32(len);
- if (get_param_value(buf, sizeof(buf), "rev", t)) {
- val = strtoul(buf, &p, 0);
- if (val > 255 || *p) {
- fprintf(stderr, "acpitable: \"rev=%s\" is invalid\n", buf);
- return -1;
- }
- hdr.revision = (uint8_t)val;
- ++changed;
+ /* recalculate checksum */
+ ext_hdr->checksum = acpi_checksum((const char unsigned *)ext_hdr +
+ ACPI_TABLE_PFX_SIZE, acpi_payload_size);
+}
+
+void acpi_table_add(const QemuOpts *opts, Error **errp)
+{
+ AcpiTableOptions *hdrs = NULL;
+ Error *err = NULL;
+ char **pathnames = NULL;
+ char **cur;
+ size_t bloblen = 0;
+ char unsigned *blob = NULL;
+
+ {
+ OptsVisitor *ov;
+
+ ov = opts_visitor_new(opts);
+ visit_type_AcpiTableOptions(opts_get_visitor(ov), &hdrs, NULL, &err);
+ opts_visitor_cleanup(ov);
}
- if (get_param_value(buf, sizeof(buf), "oem_id", t)) {
- /* strncpy is justified: the field need not be NUL-terminated. */
- strncpy(hdr.oem_id, buf, sizeof(hdr.oem_id));
- ++changed;
+ if (err) {
+ goto out;
+ }
+ if (hdrs->has_file == hdrs->has_data) {
+ error_setg(&err, "'-acpitable' requires one of 'data' or 'file'");
+ goto out;
}
- if (get_param_value(buf, sizeof(buf), "oem_table_id", t)) {
- /* strncpy is justified: the field need not be NUL-terminated. */
- strncpy(hdr.oem_table_id, buf, sizeof(hdr.oem_table_id));
- ++changed;
+ pathnames = g_strsplit(hdrs->has_file ? hdrs->file : hdrs->data, ":", 0);
+ if (pathnames == NULL || pathnames[0] == NULL) {
+ error_setg(&err, "'-acpitable' requires at least one pathname");
+ goto out;
}
- if (get_param_value(buf, sizeof(buf), "oem_rev", t)) {
- val = strtol(buf, &p, 0);
- if (*p) {
- fprintf(stderr, "acpitable: \"oem_rev=%s\" is invalid\n", buf);
- return -1;
+ /* now read in the data files, reallocating buffer as needed */
+ for (cur = pathnames; *cur; ++cur) {
+ int fd = open(*cur, O_RDONLY | O_BINARY);
+
+ if (fd < 0) {
+ error_setg(&err, "can't open file %s: %s", *cur, strerror(errno));
+ goto out;
}
- hdr.oem_revision = cpu_to_le32(val);
- ++changed;
- }
- if (get_param_value(buf, sizeof(buf), "asl_compiler_id", t)) {
- /* strncpy is justified: the field need not be NUL-terminated. */
- strncpy(hdr.asl_compiler_id, buf, sizeof(hdr.asl_compiler_id));
- ++changed;
- }
+ for (;;) {
+ char unsigned data[8192];
+ ssize_t r;
- if (get_param_value(buf, sizeof(buf), "asl_compiler_rev", t)) {
- val = strtol(buf, &p, 0);
- if (*p) {
- fprintf(stderr, "acpitable: \"%s=%s\" is invalid\n",
- "asl_compiler_rev", buf);
- return -1;
+ r = read(fd, data, sizeof data);
+ if (r == 0) {
+ break;
+ } else if (r > 0) {
+ blob = g_realloc(blob, bloblen + r);
+ memcpy(blob + bloblen, data, r);
+ bloblen += r;
+ } else if (errno != EINTR) {
+ error_setg(&err, "can't read file %s: %s",
+ *cur, strerror(errno));
+ close(fd);
+ goto out;
+ }
}
- hdr.asl_compiler_revision = cpu_to_le32(val);
- ++changed;
- }
- if (!has_header && !changed) {
- fprintf(stderr, "warning: acpitable: no table headers are specified\n");
+ close(fd);
}
+ acpi_table_install(blob, bloblen, hdrs->has_file, hdrs, &err);
- /* now calculate checksum of the table, complete with the header */
- /* we may as well leave checksum intact if has_header is true */
- /* alternatively there may be a way to set cksum to a given value */
- hdr.checksum = 0; /* for checksum calculation */
+out:
+ g_free(blob);
+ g_strfreev(pathnames);
- /* put header back */
- memcpy(f, &hdr, sizeof(hdr));
+ if (hdrs != NULL) {
+ QapiDeallocVisitor *dv;
- if (changed || !has_header || 1) {
- ((struct acpi_table_header *)f)->checksum =
- acpi_checksum((uint8_t *)f + ACPI_TABLE_PFX_SIZE, len);
+ dv = qapi_dealloc_visitor_new();
+ visit_type_AcpiTableOptions(qapi_dealloc_get_visitor(dv), &hdrs, NULL,
+ NULL);
+ qapi_dealloc_visitor_cleanup(dv);
}
- /* increase number of tables */
- (*(uint16_t *)acpi_tables) =
- cpu_to_le32(le32_to_cpu(*(uint16_t *)acpi_tables) + 1);
-
- acpi_tables_len = allen;
- return 0;
-
+ error_propagate(errp, err);
}
static void acpi_notify_wakeup(Notifier *notifier, void *data)
@@ -472,8 +540,9 @@ static const MemoryRegionOps acpi_pm_cnt_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
-void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent)
+void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent, uint8_t s4_val)
{
+ ar->pm1.cnt.s4_val = s4_val;
ar->wakeup.notify = acpi_notify_wakeup;
qemu_register_wakeup_notifier(&ar->wakeup);
memory_region_init_io(&ar->pm1.cnt.io, &acpi_pm_cnt_ops, ar, "acpi-cnt", 2);
diff --git a/hw/acpi.h b/hw/acpi.h
index c3628d070d..e18ef28fd3 100644
--- a/hw/acpi.h
+++ b/hw/acpi.h
@@ -142,7 +142,7 @@ void acpi_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
MemoryRegion *parent);
/* PM1a_CNT: piix and ich9 don't implement PM1b CNT. */
-void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent);
+void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent, uint8_t s4_val);
void acpi_pm1_cnt_update(ACPIREGS *ar,
bool sci_enable, bool sci_disable);
void acpi_pm1_cnt_reset(ACPIREGS *ar);
diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
index 29f84ffb45..7b34a03866 100644
--- a/hw/acpi_ich9.c
+++ b/hw/acpi_ich9.c
@@ -212,7 +212,7 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
acpi_pm1_evt_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
- acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io);
+ acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io, 2);
acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN);
memory_region_init_io(&pm->io_gpe, &ich9_gpe_ops, pm, "apci-gpe0",
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 7a4b712919..48a32b5aa0 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -418,7 +418,7 @@ static int piix4_pm_initfn(PCIDevice *dev)
acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
- acpi_pm1_cnt_init(&s->ar, &s->io);
+ acpi_pm1_cnt_init(&s->ar, &s->io, s->s4_val);
acpi_gpe_init(&s->ar, GPE_LEN);
s->powerdown_notifier.notify = piix4_pm_powerdown_req;
diff --git a/hw/apic_common.c b/hw/apic_common.c
index d0c261602c..37985097ca 100644
--- a/hw/apic_common.c
+++ b/hw/apic_common.c
@@ -218,7 +218,7 @@ static void apic_reset_common(DeviceState *d)
bool bsp;
bsp = cpu_is_bsp(s->cpu);
- s->apicbase = 0xfee00000 |
+ s->apicbase = APIC_DEFAULT_ADDRESS |
(bsp ? MSR_IA32_APICBASE_BSP : 0) | MSR_IA32_APICBASE_ENABLE;
s->vapic_paddr = 0;
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index 6747c1c547..b28e7d372f 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -129,8 +129,6 @@ static void n800_mmc_cs_cb(void *opaque, int line, int level)
/* TODO: this seems to actually be connected to the menelaus, to
* which also both MMC slots connect. */
omap_mmc_enable((struct omap_mmc_s *) opaque, !level);
-
- printf("%s: MMC slot %i active\n", __FUNCTION__, level + 1);
}
static void n8x0_gpio_setup(struct n800_s *s)
@@ -428,9 +426,6 @@ struct mipid_s {
static void mipid_reset(struct mipid_s *s)
{
- if (!s->sleep)
- fprintf(stderr, "%s: Display off\n", __FUNCTION__);
-
s->pm = 0;
s->cmd = 0;
@@ -578,11 +573,9 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
case 0x28: /* DISPOFF */
s->onoff = 0;
- fprintf(stderr, "%s: Display off\n", __FUNCTION__);
break;
case 0x29: /* DISPON */
s->onoff = 1;
- fprintf(stderr, "%s: Display on\n", __FUNCTION__);
break;
case 0x2a: /* CASET */
@@ -669,7 +662,8 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
default:
bad_cmd:
- fprintf(stderr, "%s: unknown command %02x\n", __FUNCTION__, s->cmd);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: unknown command %02x\n", __func__, s->cmd);
break;
}
@@ -1347,7 +1341,6 @@ static void n8x0_init(QEMUMachineInitArgs *args,
if (option_rom[0].name &&
(args->boot_device[0] == 'n' || !args->kernel_filename)) {
- int rom_size;
uint8_t nolo_tags[0x10000];
/* No, wait, better start at the ROM. */
s->mpu->cpu->env.regs[15] = OMAP2_Q2_BASE + 0x400000;
@@ -1361,10 +1354,9 @@ static void n8x0_init(QEMUMachineInitArgs *args,
*
* The code above is for loading the `zImage' file from Nokia
* images. */
- rom_size = load_image_targphys(option_rom[0].name,
- OMAP2_Q2_BASE + 0x400000,
- sdram_size - 0x400000);
- printf("%i bytes of image loaded\n", rom_size);
+ load_image_targphys(option_rom[0].name,
+ OMAP2_Q2_BASE + 0x400000,
+ sdram_size - 0x400000);
n800_setup_nolo_tags(nolo_tags);
cpu_physical_memory_write(OMAP2_SRAM_BASE, nolo_tags, 0x10000);
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 7467cca4f7..b7ca511d45 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -1981,9 +1981,11 @@ static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem,
memory_region_init_io(&s->iomem, &pxa2xx_fir_ops, s, "pxa2xx-fir", 0x1000);
memory_region_add_subregion(sysmem, base, &s->iomem);
- if (chr)
+ if (chr) {
+ qemu_chr_fe_claim_no_fail(chr);
qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty,
pxa2xx_fir_rx, pxa2xx_fir_event, s);
+ }
register_savevm(NULL, "pxa2xx_fir", 0, 0, pxa2xx_fir_save,
pxa2xx_fir_load, s);
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 6f362865f9..5b9257a9de 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -86,8 +86,7 @@ static inline void zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq,
spi = (SSIBus *)qdev_get_child_bus(dev, bus_name);
for (j = 0; j < num_ss; ++j) {
- flash_dev = ssi_create_slave_no_init(spi, "n25q128");
- qdev_init_nofail(flash_dev);
+ flash_dev = ssi_create_slave(spi, "n25q128");
cs_line = qdev_get_gpio_in(flash_dev, 0);
sysbus_connect_irq(busdev, i * num_ss + j + 1, cs_line);
diff --git a/hw/arm_gic_common.c b/hw/arm_gic_common.c
index f2dc8bf555..71594f1f87 100644
--- a/hw/arm_gic_common.c
+++ b/hw/arm_gic_common.c
@@ -20,90 +20,65 @@
#include "hw/arm_gic_internal.h"
-static void gic_save(QEMUFile *f, void *opaque)
+static void gic_pre_save(void *opaque)
{
GICState *s = (GICState *)opaque;
ARMGICCommonClass *c = ARM_GIC_COMMON_GET_CLASS(s);
- int i;
- int j;
if (c->pre_save) {
c->pre_save(s);
}
-
- qemu_put_be32(f, s->enabled);
- for (i = 0; i < s->num_cpu; i++) {
- qemu_put_be32(f, s->cpu_enabled[i]);
- for (j = 0; j < GIC_INTERNAL; j++) {
- qemu_put_be32(f, s->priority1[j][i]);
- }
- for (j = 0; j < s->num_irq; j++) {
- qemu_put_be32(f, s->last_active[j][i]);
- }
- qemu_put_be32(f, s->priority_mask[i]);
- qemu_put_be32(f, s->running_irq[i]);
- qemu_put_be32(f, s->running_priority[i]);
- qemu_put_be32(f, s->current_pending[i]);
- }
- for (i = 0; i < s->num_irq - GIC_INTERNAL; i++) {
- qemu_put_be32(f, s->priority2[i]);
- }
- for (i = 0; i < s->num_irq; i++) {
- qemu_put_be32(f, s->irq_target[i]);
- qemu_put_byte(f, s->irq_state[i].enabled);
- qemu_put_byte(f, s->irq_state[i].pending);
- qemu_put_byte(f, s->irq_state[i].active);
- qemu_put_byte(f, s->irq_state[i].level);
- qemu_put_byte(f, s->irq_state[i].model);
- qemu_put_byte(f, s->irq_state[i].trigger);
- }
}
-static int gic_load(QEMUFile *f, void *opaque, int version_id)
+static int gic_post_load(void *opaque, int version_id)
{
GICState *s = (GICState *)opaque;
ARMGICCommonClass *c = ARM_GIC_COMMON_GET_CLASS(s);
- int i;
- int j;
-
- if (version_id != 3) {
- return -EINVAL;
- }
-
- s->enabled = qemu_get_be32(f);
- for (i = 0; i < s->num_cpu; i++) {
- s->cpu_enabled[i] = qemu_get_be32(f);
- for (j = 0; j < GIC_INTERNAL; j++) {
- s->priority1[j][i] = qemu_get_be32(f);
- }
- for (j = 0; j < s->num_irq; j++) {
- s->last_active[j][i] = qemu_get_be32(f);
- }
- s->priority_mask[i] = qemu_get_be32(f);
- s->running_irq[i] = qemu_get_be32(f);
- s->running_priority[i] = qemu_get_be32(f);
- s->current_pending[i] = qemu_get_be32(f);
- }
- for (i = 0; i < s->num_irq - GIC_INTERNAL; i++) {
- s->priority2[i] = qemu_get_be32(f);
- }
- for (i = 0; i < s->num_irq; i++) {
- s->irq_target[i] = qemu_get_be32(f);
- s->irq_state[i].enabled = qemu_get_byte(f);
- s->irq_state[i].pending = qemu_get_byte(f);
- s->irq_state[i].active = qemu_get_byte(f);
- s->irq_state[i].level = qemu_get_byte(f);
- s->irq_state[i].model = qemu_get_byte(f);
- s->irq_state[i].trigger = qemu_get_byte(f);
- }
if (c->post_load) {
c->post_load(s);
}
-
return 0;
}
+static const VMStateDescription vmstate_gic_irq_state = {
+ .name = "arm_gic_irq_state",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(enabled, gic_irq_state),
+ VMSTATE_UINT8(pending, gic_irq_state),
+ VMSTATE_UINT8(active, gic_irq_state),
+ VMSTATE_UINT8(level, gic_irq_state),
+ VMSTATE_BOOL(model, gic_irq_state),
+ VMSTATE_BOOL(trigger, gic_irq_state),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const VMStateDescription vmstate_gic = {
+ .name = "arm_gic",
+ .version_id = 4,
+ .minimum_version_id = 4,
+ .pre_save = gic_pre_save,
+ .post_load = gic_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_BOOL(enabled, GICState),
+ VMSTATE_BOOL_ARRAY(cpu_enabled, GICState, NCPU),
+ VMSTATE_STRUCT_ARRAY(irq_state, GICState, GIC_MAXIRQ, 1,
+ vmstate_gic_irq_state, gic_irq_state),
+ VMSTATE_UINT8_ARRAY(irq_target, GICState, GIC_MAXIRQ),
+ VMSTATE_UINT8_2DARRAY(priority1, GICState, GIC_INTERNAL, NCPU),
+ VMSTATE_UINT8_ARRAY(priority2, GICState, GIC_MAXIRQ - GIC_INTERNAL),
+ VMSTATE_UINT16_2DARRAY(last_active, GICState, GIC_MAXIRQ, NCPU),
+ VMSTATE_UINT16_ARRAY(priority_mask, GICState, NCPU),
+ VMSTATE_UINT16_ARRAY(running_irq, GICState, NCPU),
+ VMSTATE_UINT16_ARRAY(running_priority, GICState, NCPU),
+ VMSTATE_UINT16_ARRAY(current_pending, GICState, NCPU),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static void arm_gic_common_realize(DeviceState *dev, Error **errp)
{
GICState *s = ARM_GIC_COMMON(dev);
@@ -131,8 +106,6 @@ static void arm_gic_common_realize(DeviceState *dev, Error **errp)
num_irq);
return;
}
-
- register_savevm(NULL, "arm_gic", -1, 3, gic_save, gic_load, s);
}
static void arm_gic_common_reset(DeviceState *dev)
@@ -149,7 +122,7 @@ static void arm_gic_common_reset(DeviceState *dev)
s->current_pending[i] = 1023;
s->running_irq[i] = 1023;
s->running_priority[i] = 0x100;
- s->cpu_enabled[i] = 0;
+ s->cpu_enabled[i] = false;
}
for (i = 0; i < 16; i++) {
GIC_SET_ENABLED(i, ALL_CPU_MASK);
@@ -161,7 +134,7 @@ static void arm_gic_common_reset(DeviceState *dev)
s->irq_target[i] = 1;
}
}
- s->enabled = 0;
+ s->enabled = false;
}
static Property arm_gic_common_properties[] = {
@@ -182,6 +155,7 @@ static void arm_gic_common_class_init(ObjectClass *klass, void *data)
dc->reset = arm_gic_common_reset;
dc->realize = arm_gic_common_realize;
dc->props = arm_gic_common_properties;
+ dc->vmsd = &vmstate_gic;
dc->no_user = 1;
}
diff --git a/hw/arm_gic_internal.h b/hw/arm_gic_internal.h
index 3e1928b7eb..99a3bc362b 100644
--- a/hw/arm_gic_internal.h
+++ b/hw/arm_gic_internal.h
@@ -45,14 +45,14 @@
#define GIC_SET_ACTIVE(irq, cm) s->irq_state[irq].active |= (cm)
#define GIC_CLEAR_ACTIVE(irq, cm) s->irq_state[irq].active &= ~(cm)
#define GIC_TEST_ACTIVE(irq, cm) ((s->irq_state[irq].active & (cm)) != 0)
-#define GIC_SET_MODEL(irq) s->irq_state[irq].model = 1
-#define GIC_CLEAR_MODEL(irq) s->irq_state[irq].model = 0
+#define GIC_SET_MODEL(irq) s->irq_state[irq].model = true
+#define GIC_CLEAR_MODEL(irq) s->irq_state[irq].model = false
#define GIC_TEST_MODEL(irq) s->irq_state[irq].model
#define GIC_SET_LEVEL(irq, cm) s->irq_state[irq].level = (cm)
#define GIC_CLEAR_LEVEL(irq, cm) s->irq_state[irq].level &= ~(cm)
#define GIC_TEST_LEVEL(irq, cm) ((s->irq_state[irq].level & (cm)) != 0)
-#define GIC_SET_TRIGGER(irq) s->irq_state[irq].trigger = 1
-#define GIC_CLEAR_TRIGGER(irq) s->irq_state[irq].trigger = 0
+#define GIC_SET_TRIGGER(irq) s->irq_state[irq].trigger = true
+#define GIC_CLEAR_TRIGGER(irq) s->irq_state[irq].trigger = false
#define GIC_TEST_TRIGGER(irq) s->irq_state[irq].trigger
#define GIC_GET_PRIORITY(irq, cpu) (((irq) < GIC_INTERNAL) ? \
s->priority1[irq][cpu] : \
@@ -61,30 +61,30 @@
typedef struct gic_irq_state {
/* The enable bits are only banked for per-cpu interrupts. */
- unsigned enabled:NCPU;
- unsigned pending:NCPU;
- unsigned active:NCPU;
- unsigned level:NCPU;
- unsigned model:1; /* 0 = N:N, 1 = 1:N */
- unsigned trigger:1; /* nonzero = edge triggered. */
+ uint8_t enabled;
+ uint8_t pending;
+ uint8_t active;
+ uint8_t level;
+ bool model; /* 0 = N:N, 1 = 1:N */
+ bool trigger; /* nonzero = edge triggered. */
} gic_irq_state;
typedef struct GICState {
SysBusDevice busdev;
qemu_irq parent_irq[NCPU];
- int enabled;
- int cpu_enabled[NCPU];
+ bool enabled;
+ bool cpu_enabled[NCPU];
gic_irq_state irq_state[GIC_MAXIRQ];
- int irq_target[GIC_MAXIRQ];
- int priority1[GIC_INTERNAL][NCPU];
- int priority2[GIC_MAXIRQ - GIC_INTERNAL];
- int last_active[GIC_MAXIRQ][NCPU];
-
- int priority_mask[NCPU];
- int running_irq[NCPU];
- int running_priority[NCPU];
- int current_pending[NCPU];
+ uint8_t irq_target[GIC_MAXIRQ];
+ uint8_t priority1[GIC_INTERNAL][NCPU];
+ uint8_t priority2[GIC_MAXIRQ - GIC_INTERNAL];
+ uint16_t last_active[GIC_MAXIRQ][NCPU];
+
+ uint16_t priority_mask[NCPU];
+ uint16_t running_irq[NCPU];
+ uint16_t running_priority[NCPU];
+ uint16_t current_pending[NCPU];
uint32_t num_cpu;
diff --git a/hw/arm_mptimer.c b/hw/arm_mptimer.c
index f59a9f11f0..317f5e43ed 100644
--- a/hw/arm_mptimer.c
+++ b/hw/arm_mptimer.c
@@ -253,14 +253,15 @@ static int arm_mptimer_init(SysBusDevice *dev)
static const VMStateDescription vmstate_timerblock = {
.name = "arm_mptimer_timerblock",
- .version_id = 1,
- .minimum_version_id = 1,
+ .version_id = 2,
+ .minimum_version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_UINT32(count, TimerBlock),
VMSTATE_UINT32(load, TimerBlock),
VMSTATE_UINT32(control, TimerBlock),
VMSTATE_UINT32(status, TimerBlock),
VMSTATE_INT64(tick, TimerBlock),
+ VMSTATE_TIMER(timer, TimerBlock),
VMSTATE_END_OF_LIST()
}
};
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index d198cfd96e..235120024f 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -458,10 +458,10 @@ static void armv7m_nvic_reset(DeviceState *dev)
* as enabled by default, and with a priority mask which allows
* all interrupts through.
*/
- s->gic.cpu_enabled[0] = 1;
+ s->gic.cpu_enabled[0] = true;
s->gic.priority_mask[0] = 0x100;
/* The NVIC as a whole is always enabled. */
- s->gic.enabled = 1;
+ s->gic.enabled = true;
systick_reset(s);
}
diff --git a/hw/bt-hci-csr.c b/hw/bt-hci-csr.c
index e4ada3c731..55c819b085 100644
--- a/hw/bt-hci-csr.c
+++ b/hw/bt-hci-csr.c
@@ -439,6 +439,7 @@ CharDriverState *uart_hci_init(qemu_irq wakeup)
s->chr.opaque = s;
s->chr.chr_write = csrhci_write;
s->chr.chr_ioctl = csrhci_ioctl;
+ s->chr.avail_connections = 1;
s->hci = qemu_next_hci();
s->hci->opaque = s;
diff --git a/hw/cadence_uart.c b/hw/cadence_uart.c
index 5426f10018..421ec998d6 100644
--- a/hw/cadence_uart.c
+++ b/hw/cadence_uart.c
@@ -157,6 +157,7 @@ static void uart_rx_reset(UartState *s)
{
s->rx_wpos = 0;
s->rx_count = 0;
+ qemu_chr_accept_input(s->chr);
s->r[R_SR] |= UART_SR_INTR_REMPTY;
s->r[R_SR] &= ~UART_SR_INTR_RFUL;
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index c151c95c3e..cc95e5c3f0 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -13,8 +13,6 @@
#include "sysemu/kvm.h"
#include "hw/apic_internal.h"
-#define APIC_DEFAULT_ADDRESS 0xfee00000
-
#define VAPIC_IO_PORT 0x7e
#define VAPIC_CPU_SHIFT 7
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index b1e06fa0e7..ebbf059225 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -51,6 +51,7 @@
#include "exec/address-spaces.h"
#include "sysemu/arch_init.h"
#include "qemu/bitmap.h"
+#include "qemu/config-file.h"
/* debug PC/ISA interrupts */
//#define DEBUG_IRQ
@@ -71,6 +72,8 @@
#define FW_CFG_E820_TABLE (FW_CFG_ARCH_LOCAL + 3)
#define FW_CFG_HPET (FW_CFG_ARCH_LOCAL + 4)
+#define IO_APIC_DEFAULT_ADDRESS 0xfec00000
+
#define E820_NR_ENTRIES 16
struct e820_entry {
@@ -888,7 +891,7 @@ void pc_cpus_init(const char *cpu_model)
void pc_acpi_init(const char *default_dsdt)
{
- char *filename = NULL, *arg = NULL;
+ char *filename;
if (acpi_tables != NULL) {
/* manually set via -acpitable, leave it alone */
@@ -898,15 +901,26 @@ void pc_acpi_init(const char *default_dsdt)
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, default_dsdt);
if (filename == NULL) {
fprintf(stderr, "WARNING: failed to find %s\n", default_dsdt);
- return;
- }
+ } else {
+ char *arg;
+ QemuOpts *opts;
+ Error *err = NULL;
- arg = g_strdup_printf("file=%s", filename);
- if (acpi_table_add(arg) != 0) {
- fprintf(stderr, "WARNING: failed to load %s\n", filename);
+ arg = g_strdup_printf("file=%s", filename);
+
+ /* creates a deep copy of "arg" */
+ opts = qemu_opts_parse(qemu_find_opts("acpi"), arg, 0);
+ g_assert(opts != NULL);
+
+ acpi_table_add(opts, &err);
+ if (err) {
+ fprintf(stderr, "WARNING: failed to load %s: %s\n", filename,
+ error_get_pretty(err));
+ error_free(err);
+ }
+ g_free(arg);
+ g_free(filename);
}
- g_free(arg);
- g_free(filename);
}
void *pc_memory_init(MemoryRegion *system_memory,
@@ -1158,7 +1172,7 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
}
qdev_init_nofail(dev);
d = SYS_BUS_DEVICE(dev);
- sysbus_mmio_map(d, 0, 0xfec00000);
+ sysbus_mmio_map(d, 0, IO_APIC_DEFAULT_ADDRESS);
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
diff --git a/hw/ipoctal232.c b/hw/ipoctal232.c
index 1da6a99175..685fee2d2e 100644
--- a/hw/ipoctal232.c
+++ b/hw/ipoctal232.c
@@ -93,7 +93,6 @@ typedef struct SCC2698Block SCC2698Block;
struct SCC2698Channel {
IPOctalState *ipoctal;
CharDriverState *dev;
- char *devpath;
bool rx_enabled;
uint8_t mr[2];
uint8_t mr_idx;
@@ -545,25 +544,12 @@ static int ipoctal_init(IPackDevice *ip)
ch->ipoctal = s;
/* Redirect IP-Octal channels to host character devices */
- if (ch->devpath) {
- const char chr_name[] = "ipoctal";
- char label[ARRAY_SIZE(chr_name) + 2];
- static int index;
-
- snprintf(label, sizeof(label), "%s%d", chr_name, index);
-
- ch->dev = qemu_chr_new(label, ch->devpath, NULL);
-
- if (ch->dev) {
- index++;
- qemu_chr_add_handlers(ch->dev, hostdev_can_receive,
- hostdev_receive, hostdev_event, ch);
- DPRINTF("Redirecting channel %u to %s (%s)\n",
- i, ch->devpath, label);
- } else {
- DPRINTF("Could not redirect channel %u to %s\n",
- i, ch->devpath);
- }
+ if (ch->dev) {
+ qemu_chr_add_handlers(ch->dev, hostdev_can_receive,
+ hostdev_receive, hostdev_event, ch);
+ DPRINTF("Redirecting channel %u to %s\n", i, ch->dev->label);
+ } else {
+ DPRINTF("Could not redirect channel %u, no chardev set\n", i);
}
}
@@ -571,14 +557,14 @@ static int ipoctal_init(IPackDevice *ip)
}
static Property ipoctal_properties[] = {
- DEFINE_PROP_STRING("serial0", IPOctalState, ch[0].devpath),
- DEFINE_PROP_STRING("serial1", IPOctalState, ch[1].devpath),
- DEFINE_PROP_STRING("serial2", IPOctalState, ch[2].devpath),
- DEFINE_PROP_STRING("serial3", IPOctalState, ch[3].devpath),
- DEFINE_PROP_STRING("serial4", IPOctalState, ch[4].devpath),
- DEFINE_PROP_STRING("serial5", IPOctalState, ch[5].devpath),
- DEFINE_PROP_STRING("serial6", IPOctalState, ch[6].devpath),
- DEFINE_PROP_STRING("serial7", IPOctalState, ch[7].devpath),
+ DEFINE_PROP_CHR("chardev0", IPOctalState, ch[0].dev),
+ DEFINE_PROP_CHR("chardev1", IPOctalState, ch[1].dev),
+ DEFINE_PROP_CHR("chardev2", IPOctalState, ch[2].dev),
+ DEFINE_PROP_CHR("chardev3", IPOctalState, ch[3].dev),
+ DEFINE_PROP_CHR("chardev4", IPOctalState, ch[4].dev),
+ DEFINE_PROP_CHR("chardev5", IPOctalState, ch[5].dev),
+ DEFINE_PROP_CHR("chardev6", IPOctalState, ch[6].dev),
+ DEFINE_PROP_CHR("chardev7", IPOctalState, ch[7].dev),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 68a2cf2e69..af2789e9ac 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -292,6 +292,7 @@ static CharDriverState* create_eventfd_chr_device(void * opaque, EventNotifier *
fprintf(stderr, "creating eventfd for eventfd %d failed\n", eventfd);
exit(-1);
}
+ qemu_chr_fe_claim_no_fail(chr);
/* if MSI is supported we need multiple interrupts */
if (ivshmem_has_feature(s, IVSHMEM_MSI)) {
diff --git a/hw/mcf_uart.c b/hw/mcf_uart.c
index aacf0f05ed..e5de801671 100644
--- a/hw/mcf_uart.c
+++ b/hw/mcf_uart.c
@@ -280,6 +280,7 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
s->chr = chr;
s->irq = irq;
if (chr) {
+ qemu_chr_fe_claim_no_fail(chr);
qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive,
mcf_uart_event, s);
}
diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
index cfc02207ab..07dc808405 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -158,8 +158,7 @@ petalogix_ml605_init(QEMUMachineInitArgs *args)
for (i = 0; i < NUM_SPI_FLASHES; i++) {
qemu_irq cs_line;
- dev = ssi_create_slave_no_init(spi, "n25q128");
- qdev_init_nofail(dev);
+ dev = ssi_create_slave(spi, "n25q128");
cs_line = qdev_get_gpio_in(dev, 0);
sysbus_connect_irq(busdev, i+1, cs_line);
}
diff --git a/hw/nand.c b/hw/nand.c
index de3e502596..63620938fb 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -297,6 +297,7 @@ static void nand_command(NANDFlashState *s)
break;
case NAND_CMD_BLOCKERASE2:
+ s->addr &= (1ull << s->addrlen * 8) - 1;
if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP)
s->addr <<= 16;
else
diff --git a/hw/onenand.c b/hw/onenand.c
index ddba366ef5..57a346d7da 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -185,7 +185,8 @@ static const VMStateDescription vmstate_onenand = {
VMSTATE_UINT8(ecc.cp, OneNANDState),
VMSTATE_UINT16_ARRAY(ecc.lp, OneNANDState, 2),
VMSTATE_UINT16(ecc.count, OneNANDState),
- VMSTATE_BUFFER_UNSAFE(otp, OneNANDState, 0, ((64 + 2) << PAGE_SHIFT)),
+ VMSTATE_BUFFER_POINTER_UNSAFE(otp, OneNANDState, 0,
+ ((64 + 2) << PAGE_SHIFT)),
VMSTATE_END_OF_LIST()
}
};
diff --git a/hw/pc.h b/hw/pc.h
index 8e1dd4cad4..55964ced93 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -109,11 +109,11 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
/* acpi.c */
extern int acpi_enabled;
-extern char *acpi_tables;
+extern char unsigned *acpi_tables;
extern size_t acpi_tables_len;
void acpi_bios_init(void);
-int acpi_table_add(const char *table_desc);
+void acpi_table_add(const QemuOpts *opts, Error **errp);
/* acpi_piix.c */
diff --git a/hw/pci/pci-hotplug.c b/hw/pci/pci-hotplug.c
index f38df30540..180ee07fef 100644
--- a/hw/pci/pci-hotplug.c
+++ b/hw/pci/pci-hotplug.c
@@ -99,7 +99,7 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter,
dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1);
dinfo->bus = scsibus->busnr;
scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo->bdrv, dinfo->unit,
- false, -1);
+ false, -1, NULL);
if (!scsidev) {
return -1;
}
diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c
index 5d57babe07..646dc794bf 100644
--- a/hw/pflash_cfi01.c
+++ b/hw/pflash_cfi01.c
@@ -67,8 +67,7 @@ struct pflash_t {
uint64_t sector_len;
uint8_t width;
uint8_t be;
- int wcycle; /* if 0, the flash is read normally */
- int bypass;
+ uint8_t wcycle; /* if 0, the flash is read normally */
int ro;
uint8_t cmd;
uint8_t status;
@@ -78,7 +77,7 @@ struct pflash_t {
uint16_t ident3;
uint8_t cfi_len;
uint8_t cfi_table[0x52];
- hwaddr counter;
+ uint64_t counter;
unsigned int writeblock_size;
QEMUTimer *timer;
MemoryRegion mem;
@@ -86,6 +85,19 @@ struct pflash_t {
void *storage;
};
+static const VMStateDescription vmstate_pflash = {
+ .name = "pflash_cfi01",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(wcycle, pflash_t),
+ VMSTATE_UINT8(cmd, pflash_t),
+ VMSTATE_UINT8(status, pflash_t),
+ VMSTATE_UINT64(counter, pflash_t),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static void pflash_timer (void *opaque)
{
pflash_t *pfl = opaque;
@@ -93,12 +105,8 @@ static void pflash_timer (void *opaque)
DPRINTF("%s: command %02x done\n", __func__, pfl->cmd);
/* Reset flash */
pfl->status ^= 0x80;
- if (pfl->bypass) {
- pfl->wcycle = 2;
- } else {
- memory_region_rom_device_set_readable(&pfl->mem, true);
- pfl->wcycle = 0;
- }
+ memory_region_rom_device_set_readable(&pfl->mem, true);
+ pfl->wcycle = 0;
pfl->cmd = 0;
}
@@ -228,7 +236,7 @@ static inline void pflash_data_write(pflash_t *pfl, hwaddr offset,
uint8_t *p = pfl->storage;
DPRINTF("%s: block write offset " TARGET_FMT_plx
- " value %x counter " TARGET_FMT_plx "\n",
+ " value %x counter %016" PRIx64 "\n",
__func__, offset, value, pfl->counter);
switch (width) {
case 1:
@@ -452,7 +460,6 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
reset_flash:
memory_region_rom_device_set_readable(&pfl->mem, true);
- pfl->bypass = 0;
pfl->wcycle = 0;
pfl->cmd = 0;
}
@@ -707,6 +714,7 @@ static void pflash_cfi01_class_init(ObjectClass *klass, void *data)
k->init = pflash_cfi01_init;
dc->props = pflash_cfi01_properties;
+ dc->vmsd = &vmstate_pflash;
}
diff --git a/hw/pl050.c b/hw/pl050.c
index bc31ab6885..76735a0eda 100644
--- a/hw/pl050.c
+++ b/hw/pl050.c
@@ -24,14 +24,13 @@ typedef struct {
static const VMStateDescription vmstate_pl050 = {
.name = "pl050",
- .version_id = 1,
- .minimum_version_id = 1,
+ .version_id = 2,
+ .minimum_version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_UINT32(cr, pl050_state),
VMSTATE_UINT32(clk, pl050_state),
VMSTATE_UINT32(last, pl050_state),
VMSTATE_INT32(pending, pl050_state),
- VMSTATE_INT32(is_mouse, pl050_state),
VMSTATE_END_OF_LIST()
}
};
diff --git a/hw/pl330.c b/hw/pl330.c
index 1a04773a71..60aa4a8f9f 100644
--- a/hw/pl330.c
+++ b/hw/pl330.c
@@ -870,9 +870,8 @@ static void pl330_dmasev(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
ch->parent->int_status |= (1 << ev_id);
DB_PRINT("event interrupt raised %d\n", ev_id);
qemu_irq_raise(ch->parent->irq[ev_id]);
- } else {
- ch->parent->ev_status |= (1 << ev_id);
}
+ ch->parent->ev_status |= (1 << ev_id);
}
static void pl330_dmast(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
diff --git a/hw/qdev-properties-system.c b/hw/qdev-properties-system.c
index d9934b5b9c..a22b155b6f 100644
--- a/hw/qdev-properties-system.c
+++ b/hw/qdev-properties-system.c
@@ -123,11 +123,10 @@ static int parse_chr(DeviceState *dev, const char *str, void **ptr)
if (chr == NULL) {
return -ENOENT;
}
- if (chr->avail_connections < 1) {
+ if (qemu_chr_fe_claim(chr) != 0) {
return -EEXIST;
}
*ptr = chr;
- --chr->avail_connections;
return 0;
}
@@ -140,7 +139,7 @@ static void release_chr(Object *obj, const char *name, void *opaque)
if (chr) {
qemu_chr_add_handlers(chr, NULL, NULL, NULL, NULL);
- ++chr->avail_connections;
+ qemu_chr_fe_release(chr);
}
}
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 08787c2a9b..ac2093a5ef 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -207,7 +207,8 @@ static int scsi_qdev_exit(DeviceState *qdev)
/* handle legacy '-drive if=scsi,...' cmd line args */
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
- int unit, bool removable, int bootindex)
+ int unit, bool removable, int bootindex,
+ const char *serial)
{
const char *driver;
DeviceState *dev;
@@ -221,6 +222,9 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
if (object_property_find(OBJECT(dev), "removable", NULL)) {
qdev_prop_set_bit(dev, "removable", removable);
}
+ if (serial) {
+ qdev_prop_set_string(dev, "serial", serial);
+ }
if (qdev_prop_set_drive(dev, "drive", bdrv) < 0) {
qdev_free(dev);
return NULL;
@@ -243,7 +247,7 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
continue;
}
qemu_opts_loc_restore(dinfo->opts);
- if (!scsi_bus_legacy_add_drive(bus, dinfo->bdrv, unit, false, -1)) {
+ if (!scsi_bus_legacy_add_drive(bus, dinfo->bdrv, unit, false, -1, NULL)) {
res = -1;
break;
}
diff --git a/hw/scsi.h b/hw/scsi.h
index 33e2e0bdf1..02a1497d7a 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -160,7 +160,8 @@ static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
}
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
- int unit, bool removable, int bootindex);
+ int unit, bool removable, int bootindex,
+ const char *serial);
int scsi_bus_legacy_handle_cmdline(SCSIBus *bus);
/*
diff --git a/hw/sd.c b/hw/sd.c
index a895123867..66c4014fbe 100644
--- a/hw/sd.c
+++ b/hw/sd.c
@@ -478,7 +478,7 @@ static const VMStateDescription sd_vmstate = {
VMSTATE_UINT64(data_start, SDState),
VMSTATE_UINT32(data_offset, SDState),
VMSTATE_UINT8_ARRAY(data, SDState, 512),
- VMSTATE_BUFFER_UNSAFE(buf, SDState, 1, 512),
+ VMSTATE_BUFFER_POINTER_UNSAFE(buf, SDState, 1, 512),
VMSTATE_BOOL(enable, SDState),
VMSTATE_END_OF_LIST()
}
diff --git a/hw/sh_serial.c b/hw/sh_serial.c
index 40e797c5a2..462969557c 100644
--- a/hw/sh_serial.c
+++ b/hw/sh_serial.c
@@ -396,9 +396,11 @@ void sh_serial_init(MemoryRegion *sysmem,
s->chr = chr;
- if (chr)
+ if (chr) {
+ qemu_chr_fe_claim_no_fail(chr);
qemu_chr_add_handlers(chr, sh_serial_can_receive1, sh_serial_receive1,
sh_serial_event, s);
+ }
s->eri = eri_source;
s->rxi = rxi_source;
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index d3f01aa2a7..21651b3637 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -625,7 +625,7 @@ static int usb_msd_initfn_storage(USBDevice *dev)
usb_desc_init(dev);
scsi_bus_new(&s->bus, &s->dev.qdev, &usb_msd_scsi_info_storage);
scsi_dev = scsi_bus_legacy_add_drive(&s->bus, bs, 0, !!s->removable,
- s->conf.bootindex);
+ s->conf.bootindex, s->serial);
if (!scsi_dev) {
return -1;
}
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 452950826c..9d9b64eedd 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -360,7 +360,7 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
- acpi_pm1_cnt_init(&s->ar, &s->io);
+ acpi_pm1_cnt_init(&s->ar, &s->io, 2);
return 0;
}
diff --git a/hw/xen_backend.c b/hw/xen_backend.c
index 24381b55e5..02693d7565 100644
--- a/hw/xen_backend.c
+++ b/hw/xen_backend.c
@@ -85,12 +85,20 @@ char *xenstore_read_str(const char *base, const char *node)
int xenstore_write_int(const char *base, const char *node, int ival)
{
- char val[32];
+ char val[12];
snprintf(val, sizeof(val), "%d", ival);
return xenstore_write_str(base, node, val);
}
+int xenstore_write_int64(const char *base, const char *node, int64_t ival)
+{
+ char val[21];
+
+ snprintf(val, sizeof(val), "%"PRId64, ival);
+ return xenstore_write_str(base, node, val);
+}
+
int xenstore_read_int(const char *base, const char *node, int *ival)
{
char *val;
@@ -114,6 +122,11 @@ int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival)
return xenstore_write_int(xendev->be, node, ival);
}
+int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, int64_t ival)
+{
+ return xenstore_write_int64(xendev->be, node, ival);
+}
+
char *xenstore_read_be_str(struct XenDevice *xendev, const char *node)
{
return xenstore_read_str(xendev->be, node);
diff --git a/hw/xen_backend.h b/hw/xen_backend.h
index 6d5c699c51..d04b985d10 100644
--- a/hw/xen_backend.h
+++ b/hw/xen_backend.h
@@ -63,11 +63,13 @@ extern const char *xen_protocol;
/* xenstore helper functions */
int xenstore_write_str(const char *base, const char *node, const char *val);
int xenstore_write_int(const char *base, const char *node, int ival);
+int xenstore_write_int64(const char *base, const char *node, int64_t ival);
char *xenstore_read_str(const char *base, const char *node);
int xenstore_read_int(const char *base, const char *node, int *ival);
int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val);
int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival);
+int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, int64_t ival);
char *xenstore_read_be_str(struct XenDevice *xendev, const char *node);
int xenstore_read_be_int(struct XenDevice *xendev, const char *node, int *ival);
char *xenstore_read_fe_str(struct XenDevice *xendev, const char *node);
diff --git a/hw/xen_console.c b/hw/xen_console.c
index a8db6f8d8f..c56ef4737f 100644
--- a/hw/xen_console.c
+++ b/hw/xen_console.c
@@ -241,9 +241,17 @@ static int con_initialise(struct XenDevice *xendev)
return -1;
xen_be_bind_evtchn(&con->xendev);
- if (con->chr)
- qemu_chr_add_handlers(con->chr, xencons_can_receive, xencons_receive,
- NULL, con);
+ if (con->chr) {
+ if (qemu_chr_fe_claim(con->chr) == 0) {
+ qemu_chr_add_handlers(con->chr, xencons_can_receive,
+ xencons_receive, NULL, con);
+ } else {
+ xen_be_printf(xendev, 0,
+ "xen_console_init error chardev %s already used\n",
+ con->chr->label);
+ con->chr = NULL;
+ }
+ }
xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n",
con->ring_ref,
@@ -260,8 +268,10 @@ static void con_disconnect(struct XenDevice *xendev)
if (!xendev->dev) {
return;
}
- if (con->chr)
+ if (con->chr) {
qemu_chr_add_handlers(con->chr, NULL, NULL, NULL, NULL);
+ qemu_chr_fe_release(con->chr);
+ }
xen_be_unbind_evtchn(&con->xendev);
if (con->sring) {
diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index 83329e2e69..47a51cf014 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -700,7 +700,7 @@ static void blk_alloc(struct XenDevice *xendev)
static int blk_init(struct XenDevice *xendev)
{
struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
- int index, qflags, info = 0;
+ int info = 0;
/* read xenstore entries */
if (blkdev->params == NULL) {
@@ -743,10 +743,7 @@ static int blk_init(struct XenDevice *xendev)
}
/* read-only ? */
- qflags = BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NATIVE_AIO;
- if (strcmp(blkdev->mode, "w") == 0) {
- qflags |= BDRV_O_RDWR;
- } else {
+ if (strcmp(blkdev->mode, "w")) {
info |= VDISK_READONLY;
}
@@ -755,6 +752,41 @@ static int blk_init(struct XenDevice *xendev)
info |= VDISK_CDROM;
}
+ blkdev->file_blk = BLOCK_SIZE;
+
+ /* fill info
+ * blk_connect supplies sector-size and sectors
+ */
+ xenstore_write_be_int(&blkdev->xendev, "feature-flush-cache", 1);
+ xenstore_write_be_int(&blkdev->xendev, "feature-persistent", 1);
+ xenstore_write_be_int(&blkdev->xendev, "info", info);
+ return 0;
+
+out_error:
+ g_free(blkdev->params);
+ blkdev->params = NULL;
+ g_free(blkdev->mode);
+ blkdev->mode = NULL;
+ g_free(blkdev->type);
+ blkdev->type = NULL;
+ g_free(blkdev->dev);
+ blkdev->dev = NULL;
+ g_free(blkdev->devtype);
+ blkdev->devtype = NULL;
+ return -1;
+}
+
+static int blk_connect(struct XenDevice *xendev)
+{
+ struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
+ int pers, index, qflags;
+
+ /* read-only ? */
+ qflags = BDRV_O_CACHE_WB | BDRV_O_NATIVE_AIO;
+ if (strcmp(blkdev->mode, "w") == 0) {
+ qflags |= BDRV_O_RDWR;
+ }
+
/* init qemu block driver */
index = (blkdev->xendev.dev - 202 * 256) / 16;
blkdev->dinfo = drive_get(IF_XEN, 0, index);
@@ -770,7 +802,7 @@ static int blk_init(struct XenDevice *xendev)
}
}
if (!blkdev->bs) {
- goto out_error;
+ return -1;
}
} else {
/* setup via qemu cmdline -> already setup for us */
@@ -778,7 +810,6 @@ static int blk_init(struct XenDevice *xendev)
blkdev->bs = blkdev->dinfo->bdrv;
}
bdrv_attach_dev_nofail(blkdev->bs, blkdev);
- blkdev->file_blk = BLOCK_SIZE;
blkdev->file_size = bdrv_getlength(blkdev->bs);
if (blkdev->file_size < 0) {
xen_be_printf(&blkdev->xendev, 1, "bdrv_getlength: %d (%s) | drv %s\n",
@@ -792,33 +823,10 @@ static int blk_init(struct XenDevice *xendev)
blkdev->type, blkdev->fileproto, blkdev->filename,
blkdev->file_size, blkdev->file_size >> 20);
- /* fill info */
- xenstore_write_be_int(&blkdev->xendev, "feature-flush-cache", 1);
- xenstore_write_be_int(&blkdev->xendev, "feature-persistent", 1);
- xenstore_write_be_int(&blkdev->xendev, "info", info);
- xenstore_write_be_int(&blkdev->xendev, "sector-size", blkdev->file_blk);
- xenstore_write_be_int(&blkdev->xendev, "sectors",
- blkdev->file_size / blkdev->file_blk);
- return 0;
-
-out_error:
- g_free(blkdev->params);
- blkdev->params = NULL;
- g_free(blkdev->mode);
- blkdev->mode = NULL;
- g_free(blkdev->type);
- blkdev->type = NULL;
- g_free(blkdev->dev);
- blkdev->dev = NULL;
- g_free(blkdev->devtype);
- blkdev->devtype = NULL;
- return -1;
-}
-
-static int blk_connect(struct XenDevice *xendev)
-{
- struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
- int pers;
+ /* Fill in number of sector size and number of sectors */
+ xenstore_write_be_int(&blkdev->xendev, "sector-size", blkdev->file_blk);
+ xenstore_write_be_int64(&blkdev->xendev, "sectors",
+ blkdev->file_size / blkdev->file_blk);
if (xenstore_read_fe_int(&blkdev->xendev, "ring-ref", &blkdev->ring_ref) == -1) {
return -1;
diff --git a/hw/xilinx_axienet.c b/hw/xilinx_axienet.c
index 5785290224..07c4badd98 100644
--- a/hw/xilinx_axienet.c
+++ b/hw/xilinx_axienet.c
@@ -516,6 +516,8 @@ static void enet_write(void *opaque, hwaddr addr,
s->rcw[addr & 1] = value;
if ((addr & 1) && value & RCW1_RST) {
axienet_rx_reset(s);
+ } else {
+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
}
break;