F: tests/qtest/acpi-utils.[hc]
F: tests/data/acpi/
+ACPI/HEST/GHES
+R: Dongjiu Geng <gengdongjiu@huawei.com>
+R: Xiang Zheng <zhengxiang9@huawei.com>
+L: qemu-arm@nongnu.org
+S: Maintained
+F: hw/acpi/ghes.c
+F: include/hw/acpi/ghes.h
+F: docs/specs/acpi_hest_ghes.rst
+
ppc4xx
M: David Gibson <david@gibson.dropbear.id.au>
L: qemu-ppc@nongnu.org
virtio-9p
M: Greg Kurz <groug@kaod.org>
-R: Christian Schoenebeck <qemu_oss@crudebyte.com>
+M: Christian Schoenebeck <qemu_oss@crudebyte.com>
S: Odd Fixes
F: hw/9pfs/
X: hw/9pfs/xen-9p*
F: include/net/slirp.h
T: git https://people.debian.org/~sthibault/qemu.git slirp
+Streams
+M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
+S: Maintained
+F: hw/core/stream.c
+F: include/hw/stream.h
+
Stubs
M: Paolo Bonzini <pbonzini@redhat.com>
S: Maintained
#include "qapi/visitor.h"
#include "qapi/qapi-types-common.h"
#include "qapi/qapi-visit-common.h"
+#include "sysemu/reset.h"
#include "hw/boards.h"
return ret;
}
+typedef struct HWPoisonPage {
+ ram_addr_t ram_addr;
+ QLIST_ENTRY(HWPoisonPage) list;
+} HWPoisonPage;
+
+static QLIST_HEAD(, HWPoisonPage) hwpoison_page_list =
+ QLIST_HEAD_INITIALIZER(hwpoison_page_list);
+
+static void kvm_unpoison_all(void *param)
+{
+ HWPoisonPage *page, *next_page;
+
+ QLIST_FOREACH_SAFE(page, &hwpoison_page_list, list, next_page) {
+ QLIST_REMOVE(page, list);
+ qemu_ram_remap(page->ram_addr, TARGET_PAGE_SIZE);
+ g_free(page);
+ }
+}
+
+void kvm_hwpoison_page_add(ram_addr_t ram_addr)
+{
+ HWPoisonPage *page;
+
+ QLIST_FOREACH(page, &hwpoison_page_list, list) {
+ if (page->ram_addr == ram_addr) {
+ return;
+ }
+ }
+ page = g_new(HWPoisonPage, 1);
+ page->ram_addr = ram_addr;
+ QLIST_INSERT_HEAD(&hwpoison_page_list, page, list);
+}
+
static uint32_t adjust_ioeventfd_endianness(uint32_t val, uint32_t size)
{
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
s->kernel_irqchip_split = mc->default_kernel_irqchip_split ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
}
+ qemu_register_reset(kvm_unpoison_all, NULL);
+
if (s->kernel_irqchip_allowed) {
kvm_irqchip_create(s);
}
object_class_property_add(oc, "kernel-irqchip", "on|off|split",
NULL, kvm_set_kernel_irqchip,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_set_description(oc, "kernel-irqchip",
- "Configure KVM in-kernel irqchip", &error_abort);
+ "Configure KVM in-kernel irqchip");
object_class_property_add(oc, "kvm-shadow-mem", "int",
kvm_get_kvm_shadow_mem, kvm_set_kvm_shadow_mem,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_set_description(oc, "kvm-shadow-mem",
- "KVM shadow MMU size", &error_abort);
+ "KVM shadow MMU size");
}
static const TypeInfo kvm_accel_type = {
object_class_property_add_str(oc, "thread",
tcg_get_thread,
- tcg_set_thread,
- NULL);
+ tcg_set_thread);
object_class_property_add(oc, "tb-size", "int",
tcg_get_tb_size, tcg_set_tb_size,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_set_description(oc, "tb-size",
- "TCG translation block cache size", &error_abort);
+ "TCG translation block cache size");
}
"QAuthZListPolicy",
&QAuthZListPolicy_lookup,
qauthz_list_prop_get_policy,
- qauthz_list_prop_set_policy,
- NULL);
+ qauthz_list_prop_set_policy);
object_class_property_add(oc, "rules", "QAuthZListRule",
qauthz_list_prop_get_rules,
qauthz_list_prop_set_rules,
- NULL, NULL, NULL);
+ NULL, NULL);
authz->is_allowed = qauthz_list_is_allowed;
}
object_class_property_add_str(oc, "filename",
qauthz_list_file_prop_get_filename,
- qauthz_list_file_prop_set_filename,
- NULL);
+ qauthz_list_file_prop_set_filename);
object_class_property_add_bool(oc, "refresh",
qauthz_list_file_prop_get_refresh,
- qauthz_list_file_prop_set_refresh,
- NULL);
+ qauthz_list_file_prop_set_refresh);
authz->is_allowed = qauthz_list_file_is_allowed;
}
object_class_property_add_str(oc, "service",
qauthz_pam_prop_get_service,
- qauthz_pam_prop_set_service,
- NULL);
+ qauthz_pam_prop_set_service);
}
object_class_property_add_str(oc, "identity",
qauthz_simple_prop_get_identity,
- qauthz_simple_prop_set_identity,
- NULL);
+ qauthz_simple_prop_set_identity);
}
{
object_property_add_str(obj, "chardev",
cryptodev_vhost_user_get_chardev,
- cryptodev_vhost_user_set_chardev,
- NULL);
+ cryptodev_vhost_user_set_chardev);
}
static void cryptodev_vhost_user_finalize(Object *obj)
object_property_add(obj, "queues", "uint32",
cryptodev_backend_get_queues,
cryptodev_backend_set_queues,
- NULL, NULL, NULL);
+ NULL, NULL);
/* Initialize devices' queues property to 1 */
object_property_set_int(obj, 1, "queues", NULL);
}
vc->get_id = dbus_vmstate_get_id;
object_class_property_add_str(oc, "addr",
- get_dbus_addr, set_dbus_addr,
- &error_abort);
+ get_dbus_addr, set_dbus_addr);
object_class_property_add_str(oc, "id-list",
- get_id_list, set_id_list,
- &error_abort);
+ get_id_list, set_id_list);
}
static const TypeInfo dbus_vmstate_info = {
oc->unparent = file_backend_unparent;
object_class_property_add_bool(oc, "discard-data",
- file_memory_backend_get_discard_data, file_memory_backend_set_discard_data,
- &error_abort);
+ file_memory_backend_get_discard_data, file_memory_backend_set_discard_data);
object_class_property_add_str(oc, "mem-path",
- get_mem_path, set_mem_path,
- &error_abort);
+ get_mem_path, set_mem_path);
object_class_property_add(oc, "align", "int",
file_memory_backend_get_align,
file_memory_backend_set_align,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_add_bool(oc, "pmem",
- file_memory_backend_get_pmem, file_memory_backend_set_pmem,
- &error_abort);
+ file_memory_backend_get_pmem, file_memory_backend_set_pmem);
}
static void file_backend_instance_finalize(Object *o)
if (qemu_memfd_check(MFD_HUGETLB)) {
object_class_property_add_bool(oc, "hugetlb",
memfd_backend_get_hugetlb,
- memfd_backend_set_hugetlb,
- &error_abort);
+ memfd_backend_set_hugetlb);
object_class_property_set_description(oc, "hugetlb",
- "Use huge pages",
- &error_abort);
+ "Use huge pages");
object_class_property_add(oc, "hugetlbsize", "int",
memfd_backend_get_hugetlbsize,
memfd_backend_set_hugetlbsize,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_set_description(oc, "hugetlbsize",
- "Huge pages size (ex: 2M, 1G)",
- &error_abort);
+ "Huge pages size (ex: 2M, 1G)");
}
object_class_property_add_bool(oc, "seal",
memfd_backend_get_seal,
- memfd_backend_set_seal,
- &error_abort);
+ memfd_backend_set_seal);
object_class_property_set_description(oc, "seal",
- "Seal growing & shrinking",
- &error_abort);
+ "Seal growing & shrinking");
}
static const TypeInfo memfd_backend_info = {
object_class_property_add_bool(oc, "merge",
host_memory_backend_get_merge,
- host_memory_backend_set_merge, &error_abort);
+ host_memory_backend_set_merge);
object_class_property_set_description(oc, "merge",
- "Mark memory as mergeable", &error_abort);
+ "Mark memory as mergeable");
object_class_property_add_bool(oc, "dump",
host_memory_backend_get_dump,
- host_memory_backend_set_dump, &error_abort);
+ host_memory_backend_set_dump);
object_class_property_set_description(oc, "dump",
- "Set to 'off' to exclude from core dump", &error_abort);
+ "Set to 'off' to exclude from core dump");
object_class_property_add_bool(oc, "prealloc",
host_memory_backend_get_prealloc,
- host_memory_backend_set_prealloc, &error_abort);
+ host_memory_backend_set_prealloc);
object_class_property_set_description(oc, "prealloc",
- "Preallocate memory", &error_abort);
+ "Preallocate memory");
object_class_property_add(oc, "prealloc-threads", "int",
host_memory_backend_get_prealloc_threads,
host_memory_backend_set_prealloc_threads,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_set_description(oc, "prealloc-threads",
- "Number of CPU threads to use for prealloc", &error_abort);
+ "Number of CPU threads to use for prealloc");
object_class_property_add(oc, "size", "int",
host_memory_backend_get_size,
host_memory_backend_set_size,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_set_description(oc, "size",
- "Size of the memory region (ex: 500M)", &error_abort);
+ "Size of the memory region (ex: 500M)");
object_class_property_add(oc, "host-nodes", "int",
host_memory_backend_get_host_nodes,
host_memory_backend_set_host_nodes,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_set_description(oc, "host-nodes",
- "Binds memory to the list of NUMA host nodes", &error_abort);
+ "Binds memory to the list of NUMA host nodes");
object_class_property_add_enum(oc, "policy", "HostMemPolicy",
&HostMemPolicy_lookup,
host_memory_backend_get_policy,
- host_memory_backend_set_policy, &error_abort);
+ host_memory_backend_set_policy);
object_class_property_set_description(oc, "policy",
- "Set the NUMA policy", &error_abort);
+ "Set the NUMA policy");
object_class_property_add_bool(oc, "share",
- host_memory_backend_get_share, host_memory_backend_set_share,
- &error_abort);
+ host_memory_backend_get_share, host_memory_backend_set_share);
object_class_property_set_description(oc, "share",
- "Mark the memory as private to QEMU or shared", &error_abort);
+ "Mark the memory as private to QEMU or shared");
object_class_property_add_bool(oc, "x-use-canonical-path-for-ramblock-id",
host_memory_backend_get_use_canonical_path,
- host_memory_backend_set_use_canonical_path, &error_abort);
+ host_memory_backend_set_use_canonical_path);
}
static const TypeInfo host_memory_backend_info = {
static void rng_egd_init(Object *obj)
{
object_property_add_str(obj, "chardev",
- rng_egd_get_chardev, rng_egd_set_chardev,
- NULL);
+ rng_egd_get_chardev, rng_egd_set_chardev);
}
static void rng_egd_finalize(Object *obj)
object_property_add_str(obj, "filename",
rng_random_get_filename,
- rng_random_set_filename,
- NULL);
+ rng_random_set_filename);
s->filename = g_strdup("/dev/urandom");
s->fd = -1;
object_property_add_bool(obj, "opened",
rng_backend_prop_get_opened,
- rng_backend_prop_set_opened,
- NULL);
+ rng_backend_prop_set_opened);
}
static void rng_backend_finalize(Object *obj)
static void vhost_user_backend_init(Object *obj)
{
- object_property_add_str(obj, "chardev", get_chardev, set_chardev, NULL);
+ object_property_add_str(obj, "chardev", get_chardev, set_chardev);
}
static void vhost_user_backend_finalize(Object *obj)
}
if (s->skip_unallocated && !(ret & BDRV_BLOCK_ALLOCATED)) {
block_copy_task_end(task, 0);
- g_free(task);
progress_set_remaining(s->progress,
bdrv_get_dirty_count(s->copy_bitmap) +
s->in_flight_bytes);
trace_block_copy_skip_range(s, task->offset, task->bytes);
offset = task_end(task);
bytes = end - offset;
+ g_free(task);
continue;
}
task->zeroes = ret & BDRV_BLOCK_ZERO;
#define ZLIB_CONST
#include <zlib.h>
+#ifdef CONFIG_ZSTD
+#include <zstd.h>
+#include <zstd_errors.h>
+#endif
+
#include "qcow2.h"
#include "block/thread-pool.h"
#include "crypto.h"
} Qcow2CompressData;
/*
- * qcow2_compress()
+ * qcow2_zlib_compress()
+ *
+ * Compress @src_size bytes of data using zlib compression method
*
* @dest - destination buffer, @dest_size bytes
* @src - source buffer, @src_size bytes
* -ENOMEM destination buffer is not enough to store compressed data
* -EIO on any other error
*/
-static ssize_t qcow2_compress(void *dest, size_t dest_size,
- const void *src, size_t src_size)
+static ssize_t qcow2_zlib_compress(void *dest, size_t dest_size,
+ const void *src, size_t src_size)
{
ssize_t ret;
z_stream strm;
}
/*
- * qcow2_decompress()
+ * qcow2_zlib_decompress()
*
* Decompress some data (not more than @src_size bytes) to produce exactly
- * @dest_size bytes.
+ * @dest_size bytes using zlib compression method
*
* @dest - destination buffer, @dest_size bytes
* @src - source buffer, @src_size bytes
* Returns: 0 on success
* -EIO on fail
*/
-static ssize_t qcow2_decompress(void *dest, size_t dest_size,
- const void *src, size_t src_size)
+static ssize_t qcow2_zlib_decompress(void *dest, size_t dest_size,
+ const void *src, size_t src_size)
{
int ret;
z_stream strm;
return ret;
}
+#ifdef CONFIG_ZSTD
+
+/*
+ * qcow2_zstd_compress()
+ *
+ * Compress @src_size bytes of data using zstd compression method
+ *
+ * @dest - destination buffer, @dest_size bytes
+ * @src - source buffer, @src_size bytes
+ *
+ * Returns: compressed size on success
+ * -ENOMEM destination buffer is not enough to store compressed data
+ * -EIO on any other error
+ */
+static ssize_t qcow2_zstd_compress(void *dest, size_t dest_size,
+ const void *src, size_t src_size)
+{
+ ssize_t ret;
+ size_t zstd_ret;
+ ZSTD_outBuffer output = {
+ .dst = dest,
+ .size = dest_size,
+ .pos = 0
+ };
+ ZSTD_inBuffer input = {
+ .src = src,
+ .size = src_size,
+ .pos = 0
+ };
+ ZSTD_CCtx *cctx = ZSTD_createCCtx();
+
+ if (!cctx) {
+ return -EIO;
+ }
+ /*
+ * Use the zstd streamed interface for symmetry with decompression,
+ * where streaming is essential since we don't record the exact
+ * compressed size.
+ *
+ * ZSTD_compressStream2() tries to compress everything it could
+ * with a single call. Although, ZSTD docs says that:
+ * "You must continue calling ZSTD_compressStream2() with ZSTD_e_end
+ * until it returns 0, at which point you are free to start a new frame",
+ * in out tests we saw the only case when it returned with >0 -
+ * when the output buffer was too small. In that case,
+ * ZSTD_compressStream2() expects a bigger buffer on the next call.
+ * We can't provide a bigger buffer because we are limited with dest_size
+ * which we pass to the ZSTD_compressStream2() at once.
+ * So, we don't need any loops and just abort the compression when we
+ * don't get 0 result on the first call.
+ */
+ zstd_ret = ZSTD_compressStream2(cctx, &output, &input, ZSTD_e_end);
+
+ if (zstd_ret) {
+ if (zstd_ret > output.size - output.pos) {
+ ret = -ENOMEM;
+ } else {
+ ret = -EIO;
+ }
+ goto out;
+ }
+
+ /* make sure that zstd didn't overflow the dest buffer */
+ assert(output.pos <= dest_size);
+ ret = output.pos;
+out:
+ ZSTD_freeCCtx(cctx);
+ return ret;
+}
+
+/*
+ * qcow2_zstd_decompress()
+ *
+ * Decompress some data (not more than @src_size bytes) to produce exactly
+ * @dest_size bytes using zstd compression method
+ *
+ * @dest - destination buffer, @dest_size bytes
+ * @src - source buffer, @src_size bytes
+ *
+ * Returns: 0 on success
+ * -EIO on any error
+ */
+static ssize_t qcow2_zstd_decompress(void *dest, size_t dest_size,
+ const void *src, size_t src_size)
+{
+ size_t zstd_ret = 0;
+ ssize_t ret = 0;
+ ZSTD_outBuffer output = {
+ .dst = dest,
+ .size = dest_size,
+ .pos = 0
+ };
+ ZSTD_inBuffer input = {
+ .src = src,
+ .size = src_size,
+ .pos = 0
+ };
+ ZSTD_DCtx *dctx = ZSTD_createDCtx();
+
+ if (!dctx) {
+ return -EIO;
+ }
+
+ /*
+ * The compressed stream from the input buffer may consist of more
+ * than one zstd frame. So we iterate until we get a fully
+ * uncompressed cluster.
+ * From zstd docs related to ZSTD_decompressStream:
+ * "return : 0 when a frame is completely decoded and fully flushed"
+ * We suppose that this means: each time ZSTD_decompressStream reads
+ * only ONE full frame and returns 0 if and only if that frame
+ * is completely decoded and flushed. Only after returning 0,
+ * ZSTD_decompressStream reads another ONE full frame.
+ */
+ while (output.pos < output.size) {
+ size_t last_in_pos = input.pos;
+ size_t last_out_pos = output.pos;
+ zstd_ret = ZSTD_decompressStream(dctx, &output, &input);
+
+ if (ZSTD_isError(zstd_ret)) {
+ ret = -EIO;
+ break;
+ }
+
+ /*
+ * The ZSTD manual is vague about what to do if it reads
+ * the buffer partially, and we don't want to get stuck
+ * in an infinite loop where ZSTD_decompressStream
+ * returns > 0 waiting for another input chunk. So, we add
+ * a check which ensures that the loop makes some progress
+ * on each step.
+ */
+ if (last_in_pos >= input.pos &&
+ last_out_pos >= output.pos) {
+ ret = -EIO;
+ break;
+ }
+ }
+ /*
+ * Make sure that we have the frame fully flushed here
+ * if not, we somehow managed to get uncompressed cluster
+ * greater then the cluster size, possibly because of its
+ * damage.
+ */
+ if (zstd_ret > 0) {
+ ret = -EIO;
+ }
+
+ ZSTD_freeDCtx(dctx);
+ assert(ret == 0 || ret == -EIO);
+ return ret;
+}
+#endif
+
static int qcow2_compress_pool_func(void *opaque)
{
Qcow2CompressData *data = opaque;
return arg.ret;
}
+/*
+ * qcow2_co_compress()
+ *
+ * Compress @src_size bytes of data using the compression
+ * method defined by the image compression type
+ *
+ * @dest - destination buffer, @dest_size bytes
+ * @src - source buffer, @src_size bytes
+ *
+ * Returns: compressed size on success
+ * a negative error code on failure
+ */
ssize_t coroutine_fn
qcow2_co_compress(BlockDriverState *bs, void *dest, size_t dest_size,
const void *src, size_t src_size)
{
- return qcow2_co_do_compress(bs, dest, dest_size, src, src_size,
- qcow2_compress);
+ BDRVQcow2State *s = bs->opaque;
+ Qcow2CompressFunc fn;
+
+ switch (s->compression_type) {
+ case QCOW2_COMPRESSION_TYPE_ZLIB:
+ fn = qcow2_zlib_compress;
+ break;
+
+#ifdef CONFIG_ZSTD
+ case QCOW2_COMPRESSION_TYPE_ZSTD:
+ fn = qcow2_zstd_compress;
+ break;
+#endif
+ default:
+ abort();
+ }
+
+ return qcow2_co_do_compress(bs, dest, dest_size, src, src_size, fn);
}
+/*
+ * qcow2_co_decompress()
+ *
+ * Decompress some data (not more than @src_size bytes) to produce exactly
+ * @dest_size bytes using the compression method defined by the image
+ * compression type
+ *
+ * @dest - destination buffer, @dest_size bytes
+ * @src - source buffer, @src_size bytes
+ *
+ * Returns: 0 on success
+ * a negative error code on failure
+ */
ssize_t coroutine_fn
qcow2_co_decompress(BlockDriverState *bs, void *dest, size_t dest_size,
const void *src, size_t src_size)
{
- return qcow2_co_do_compress(bs, dest, dest_size, src, src_size,
- qcow2_decompress);
+ BDRVQcow2State *s = bs->opaque;
+ Qcow2CompressFunc fn;
+
+ switch (s->compression_type) {
+ case QCOW2_COMPRESSION_TYPE_ZLIB:
+ fn = qcow2_zlib_decompress;
+ break;
+
+#ifdef CONFIG_ZSTD
+ case QCOW2_COMPRESSION_TYPE_ZSTD:
+ fn = qcow2_zstd_decompress;
+ break;
+#endif
+ default:
+ abort();
+ }
+
+ return qcow2_co_do_compress(bs, dest, dest_size, src, src_size, fn);
}
return ret;
}
+static int validate_compression_type(BDRVQcow2State *s, Error **errp)
+{
+ switch (s->compression_type) {
+ case QCOW2_COMPRESSION_TYPE_ZLIB:
+#ifdef CONFIG_ZSTD
+ case QCOW2_COMPRESSION_TYPE_ZSTD:
+#endif
+ break;
+
+ default:
+ error_setg(errp, "qcow2: unknown compression type: %u",
+ s->compression_type);
+ return -ENOTSUP;
+ }
+
+ /*
+ * if the compression type differs from QCOW2_COMPRESSION_TYPE_ZLIB
+ * the incompatible feature flag must be set
+ */
+ if (s->compression_type == QCOW2_COMPRESSION_TYPE_ZLIB) {
+ if (s->incompatible_features & QCOW2_INCOMPAT_COMPRESSION) {
+ error_setg(errp, "qcow2: Compression type incompatible feature "
+ "bit must not be set");
+ return -EINVAL;
+ }
+ } else {
+ if (!(s->incompatible_features & QCOW2_INCOMPAT_COMPRESSION)) {
+ error_setg(errp, "qcow2: Compression type incompatible feature "
+ "bit must be set");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
/* Called with s->lock held. */
static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
int flags, Error **errp)
s->compatible_features = header.compatible_features;
s->autoclear_features = header.autoclear_features;
+ /*
+ * Handle compression type
+ * Older qcow2 images don't contain the compression type header.
+ * Distinguish them by the header length and use
+ * the only valid (default) compression type in that case
+ */
+ if (header.header_length > offsetof(QCowHeader, compression_type)) {
+ s->compression_type = header.compression_type;
+ } else {
+ s->compression_type = QCOW2_COMPRESSION_TYPE_ZLIB;
+ }
+
+ ret = validate_compression_type(s, errp);
+ if (ret) {
+ goto fail;
+ }
+
if (s->incompatible_features & ~QCOW2_INCOMPAT_MASK) {
void *feature_table = NULL;
qcow2_read_extensions(bs, header.header_length, ext_end,
total_size = bs->total_sectors * BDRV_SECTOR_SIZE;
refcount_table_clusters = s->refcount_table_size >> (s->cluster_bits - 3);
+ ret = validate_compression_type(s, NULL);
+ if (ret) {
+ goto fail;
+ }
+
*header = (QCowHeader) {
/* Version 2 fields */
.magic = cpu_to_be32(QCOW_MAGIC),
.autoclear_features = cpu_to_be64(s->autoclear_features),
.refcount_order = cpu_to_be32(s->refcount_order),
.header_length = cpu_to_be32(header_length),
+ .compression_type = s->compression_type,
};
/* For older versions, write a shorter header */
.bit = QCOW2_INCOMPAT_DATA_FILE_BITNR,
.name = "external data file",
},
+ {
+ .type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
+ .bit = QCOW2_INCOMPAT_COMPRESSION_BITNR,
+ .name = "compression type",
+ },
{
.type = QCOW2_FEAT_TYPE_COMPATIBLE,
.bit = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
uint64_t* refcount_table;
Error *local_err = NULL;
int ret;
+ uint8_t compression_type = QCOW2_COMPRESSION_TYPE_ZLIB;
assert(create_options->driver == BLOCKDEV_DRIVER_QCOW2);
qcow2_opts = &create_options->u.qcow2;
}
}
+ if (qcow2_opts->has_compression_type &&
+ qcow2_opts->compression_type != QCOW2_COMPRESSION_TYPE_ZLIB) {
+
+ ret = -EINVAL;
+
+ if (version < 3) {
+ error_setg(errp, "Non-zlib compression type is only supported with "
+ "compatibility level 1.1 and above (use version=v3 or "
+ "greater)");
+ goto out;
+ }
+
+ switch (qcow2_opts->compression_type) {
+#ifdef CONFIG_ZSTD
+ case QCOW2_COMPRESSION_TYPE_ZSTD:
+ break;
+#endif
+ default:
+ error_setg(errp, "Unknown compression type");
+ goto out;
+ }
+
+ compression_type = qcow2_opts->compression_type;
+ }
+
/* Create BlockBackend to write to the image */
blk = blk_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
errp);
.refcount_table_offset = cpu_to_be64(cluster_size),
.refcount_table_clusters = cpu_to_be32(1),
.refcount_order = cpu_to_be32(refcount_order),
+ /* don't deal with endianness since compression_type is 1 byte long */
+ .compression_type = compression_type,
.header_length = cpu_to_be32(sizeof(*header)),
};
header->autoclear_features |=
cpu_to_be64(QCOW2_AUTOCLEAR_DATA_FILE_RAW);
}
+ if (compression_type != QCOW2_COMPRESSION_TYPE_ZLIB) {
+ header->incompatible_features |=
+ cpu_to_be64(QCOW2_INCOMPAT_COMPRESSION);
+ }
ret = blk_pwrite(blk, 0, header, cluster_size, 0);
g_free(header);
{ BLOCK_OPT_ENCRYPT, BLOCK_OPT_ENCRYPT_FORMAT },
{ BLOCK_OPT_COMPAT_LEVEL, "version" },
{ BLOCK_OPT_DATA_FILE_RAW, "data-file-raw" },
+ { BLOCK_OPT_COMPRESSION_TYPE, "compression-type" },
{ NULL, NULL },
};
.data_file = g_strdup(s->image_data_file),
.has_data_file_raw = has_data_file(bs),
.data_file_raw = data_file_is_raw(bs),
+ .compression_type = s->compression_type,
};
} else {
/* if this assertion fails, this probably means a new version was
"images");
return -EINVAL;
}
+ } else if (!strcmp(desc->name, BLOCK_OPT_COMPRESSION_TYPE)) {
+ const char *ct_name =
+ qemu_opt_get(opts, BLOCK_OPT_COMPRESSION_TYPE);
+ int compression_type =
+ qapi_enum_parse(&Qcow2CompressionType_lookup, ct_name, -1,
+ NULL);
+ if (compression_type == -1) {
+ error_setg(errp, "Unknown compression type: %s", ct_name);
+ return -ENOTSUP;
+ }
+
+ if (compression_type != s->compression_type) {
+ error_setg(errp, "Changing the compression type "
+ "is not supported");
+ return -ENOTSUP;
+ }
} else {
/* if this point is reached, this probably means a new option was
* added without having it covered here */
.help = "Width of a reference count entry in bits",
.def_value_str = "16"
},
+ {
+ .name = BLOCK_OPT_COMPRESSION_TYPE,
+ .type = QEMU_OPT_STRING,
+ .help = "Compression method used for image cluster compression",
+ .def_value_str = "zlib"
+ },
{ /* end of list */ }
}
};
uint32_t refcount_order;
uint32_t header_length;
+
+ /* Additional fields */
+ uint8_t compression_type;
+
+ /* header must be a multiple of 8 */
+ uint8_t padding[7];
} QEMU_PACKED QCowHeader;
+QEMU_BUILD_BUG_ON(!QEMU_IS_ALIGNED(sizeof(QCowHeader), 8));
+
typedef struct QEMU_PACKED QCowSnapshotHeader {
/* header is 8 byte aligned */
uint64_t l1_table_offset;
QCOW2_INCOMPAT_DIRTY_BITNR = 0,
QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
QCOW2_INCOMPAT_DATA_FILE_BITNR = 2,
+ QCOW2_INCOMPAT_COMPRESSION_BITNR = 3,
QCOW2_INCOMPAT_DIRTY = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
QCOW2_INCOMPAT_CORRUPT = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
QCOW2_INCOMPAT_DATA_FILE = 1 << QCOW2_INCOMPAT_DATA_FILE_BITNR,
+ QCOW2_INCOMPAT_COMPRESSION = 1 << QCOW2_INCOMPAT_COMPRESSION_BITNR,
QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY
| QCOW2_INCOMPAT_CORRUPT
- | QCOW2_INCOMPAT_DATA_FILE,
+ | QCOW2_INCOMPAT_DATA_FILE
+ | QCOW2_INCOMPAT_COMPRESSION,
};
/* Compatible feature bits */
bool metadata_preallocation_checked;
bool metadata_preallocation;
+ /*
+ * Compression type used for the image. Default: 0 - ZLIB
+ * The image compression type is set on image creation.
+ * For now, the only way to change the compression type
+ * is to convert the image with the desired compression type set.
+ */
+ Qcow2CompressionType compression_type;
} BDRVQcow2State;
typedef struct Qcow2COWRegion {
"int",
throttle_group_get,
throttle_group_set,
- NULL, &properties[i],
- &error_abort);
+ NULL, &properties[i]);
}
/* ThrottleLimits */
"limits", "ThrottleLimits",
throttle_group_get_limits,
throttle_group_set_limits,
- NULL, NULL,
- &error_abort);
+ NULL, NULL);
}
static const TypeInfo throttle_group_info = {
void device_add_bootindex_property(Object *obj, int32_t *bootindex,
const char *name, const char *suffix,
- DeviceState *dev, Error **errp)
+ DeviceState *dev)
{
- Error *local_err = NULL;
BootIndexProperty *prop = g_malloc0(sizeof(*prop));
prop->bootindex = bootindex;
device_get_bootindex,
device_set_bootindex,
property_release_bootindex,
- prop, &local_err);
+ prop);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- return;
- }
/* initialize devices' bootindex property to -1 */
object_property_set_int(obj, -1, name, NULL);
}
object_class_property_add(oc, "addr", "SocketAddress",
char_socket_get_addr, NULL,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_add_bool(oc, "connected", char_socket_get_connected,
- NULL, &error_abort);
+ NULL);
}
static const TypeInfo char_socket_type_info = {
}
if (id) {
- object_property_add_child(get_chardevs_root(), id, obj, &local_err);
- if (local_err) {
- goto end;
- }
+ object_property_add_child(get_chardevs_root(), id, obj);
object_unref(obj);
}
object_unparent(OBJECT(chr));
object_property_add_child(get_chardevs_root(), chr_new->label,
- OBJECT(chr_new), &error_abort);
+ OBJECT(chr_new));
object_unref(OBJECT(chr_new));
ret = g_new0(ChardevReturn, 1);
lzfse support of lzfse compression library
(for reading lzfse-compressed dmg images)
zstd support for zstd compression library
- (for migration compression)
+ (for migration compression and qcow2 cluster compression)
seccomp seccomp support
coroutine-pool coroutine freelist (better performance)
glusterfs GlusterFS backend
TARGET_SYSTBL_ABI=common,oabi
bflt="yes"
mttcg="yes"
- gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
+ gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml arm-m-profile.xml"
;;
aarch64|aarch64_be)
TARGET_ARCH=aarch64
TARGET_BASE_ARCH=arm
bflt="yes"
mttcg="yes"
- gdb_xml_files="aarch64-core.xml aarch64-fpu.xml arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
+ gdb_xml_files="aarch64-core.xml aarch64-fpu.xml arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml arm-m-profile.xml"
;;
cris)
;;
object_class_property_add_bool(oc, "loaded",
qcrypto_secret_prop_get_loaded,
- qcrypto_secret_prop_set_loaded,
- NULL);
+ qcrypto_secret_prop_set_loaded);
object_class_property_add_enum(oc, "format",
"QCryptoSecretFormat",
&QCryptoSecretFormat_lookup,
qcrypto_secret_prop_get_format,
- qcrypto_secret_prop_set_format,
- NULL);
+ qcrypto_secret_prop_set_format);
object_class_property_add_str(oc, "data",
qcrypto_secret_prop_get_data,
- qcrypto_secret_prop_set_data,
- NULL);
+ qcrypto_secret_prop_set_data);
object_class_property_add_str(oc, "file",
qcrypto_secret_prop_get_file,
- qcrypto_secret_prop_set_file,
- NULL);
+ qcrypto_secret_prop_set_file);
object_class_property_add_str(oc, "keyid",
qcrypto_secret_prop_get_keyid,
- qcrypto_secret_prop_set_keyid,
- NULL);
+ qcrypto_secret_prop_set_keyid);
object_class_property_add_str(oc, "iv",
qcrypto_secret_prop_get_iv,
- qcrypto_secret_prop_set_iv,
- NULL);
+ qcrypto_secret_prop_set_iv);
}
{
object_class_property_add_bool(oc, "verify-peer",
qcrypto_tls_creds_prop_get_verify,
- qcrypto_tls_creds_prop_set_verify,
- NULL);
+ qcrypto_tls_creds_prop_set_verify);
object_class_property_add_str(oc, "dir",
qcrypto_tls_creds_prop_get_dir,
- qcrypto_tls_creds_prop_set_dir,
- NULL);
+ qcrypto_tls_creds_prop_set_dir);
object_class_property_add_enum(oc, "endpoint",
"QCryptoTLSCredsEndpoint",
&QCryptoTLSCredsEndpoint_lookup,
qcrypto_tls_creds_prop_get_endpoint,
- qcrypto_tls_creds_prop_set_endpoint,
- NULL);
+ qcrypto_tls_creds_prop_set_endpoint);
object_class_property_add_str(oc, "priority",
qcrypto_tls_creds_prop_get_priority,
- qcrypto_tls_creds_prop_set_priority,
- NULL);
+ qcrypto_tls_creds_prop_set_priority);
}
object_class_property_add_bool(oc, "loaded",
qcrypto_tls_creds_anon_prop_get_loaded,
- qcrypto_tls_creds_anon_prop_set_loaded,
- NULL);
+ qcrypto_tls_creds_anon_prop_set_loaded);
}
object_class_property_add_bool(oc, "loaded",
qcrypto_tls_creds_psk_prop_get_loaded,
- qcrypto_tls_creds_psk_prop_set_loaded,
- NULL);
+ qcrypto_tls_creds_psk_prop_set_loaded);
object_class_property_add_str(oc, "username",
qcrypto_tls_creds_psk_prop_get_username,
- qcrypto_tls_creds_psk_prop_set_username,
- NULL);
+ qcrypto_tls_creds_psk_prop_set_username);
}
object_class_property_add_bool(oc, "loaded",
qcrypto_tls_creds_x509_prop_get_loaded,
- qcrypto_tls_creds_x509_prop_set_loaded,
- NULL);
+ qcrypto_tls_creds_x509_prop_set_loaded);
object_class_property_add_bool(oc, "sanity-check",
qcrypto_tls_creds_x509_prop_get_sanity,
- qcrypto_tls_creds_x509_prop_set_sanity,
- NULL);
+ qcrypto_tls_creds_x509_prop_set_sanity);
object_class_property_add_str(oc, "passwordid",
qcrypto_tls_creds_x509_prop_get_passwordid,
- qcrypto_tls_creds_x509_prop_set_passwordid,
- NULL);
+ qcrypto_tls_creds_x509_prop_set_passwordid);
}
CONFIG_FSL_IMX6UL=y
CONFIG_SEMIHOSTING=y
CONFIG_ALLWINNER_H3=y
+CONFIG_ACPI_APEI=y
Available compression type values:
0: zlib <https://www.zlib.net/>
+ 1: zstd <http://github.com/facebook/zstd>
=== Header padding ===
--- /dev/null
+APEI tables generating and CPER record
+======================================
+
+..
+ Copyright (c) 2020 HUAWEI TECHNOLOGIES CO., LTD.
+
+ This work is licensed under the terms of the GNU GPL, version 2 or later.
+ See the COPYING file in the top-level directory.
+
+Design Details
+--------------
+
+::
+
+ etc/acpi/tables etc/hardware_errors
+ ==================== ===============================
+ + +--------------------------+ +----------------------------+
+ | | HEST | +--------->| error_block_address1 |------+
+ | +--------------------------+ | +----------------------------+ |
+ | | GHES1 | | +------->| error_block_address2 |------+-+
+ | +--------------------------+ | | +----------------------------+ | |
+ | | ................. | | | | .............. | | |
+ | | error_status_address-----+-+ | -----------------------------+ | |
+ | | ................. | | +--->| error_block_addressN |------+-+---+
+ | | read_ack_register--------+-+ | | +----------------------------+ | | |
+ | | read_ack_preserve | +-+---+--->| read_ack_register1 | | | |
+ | | read_ack_write | | | +----------------------------+ | | |
+ + +--------------------------+ | +-+--->| read_ack_register2 | | | |
+ | | GHES2 | | | | +----------------------------+ | | |
+ + +--------------------------+ | | | | ............. | | | |
+ | | ................. | | | | +----------------------------+ | | |
+ | | error_status_address-----+---+ | | +->| read_ack_registerN | | | |
+ | | ................. | | | | +----------------------------+ | | |
+ | | read_ack_register--------+-----+ | | |Generic Error Status Block 1|<-----+ | |
+ | | read_ack_preserve | | | |-+------------------------+-+ | |
+ | | read_ack_write | | | | | CPER | | | |
+ + +--------------------------| | | | | CPER | | | |
+ | | ............... | | | | | .... | | | |
+ + +--------------------------+ | | | | CPER | | | |
+ | | GHESN | | | |-+------------------------+-| | |
+ + +--------------------------+ | | |Generic Error Status Block 2|<-------+ |
+ | | ................. | | | |-+------------------------+-+ |
+ | | error_status_address-----+-------+ | | | CPER | | |
+ | | ................. | | | | CPER | | |
+ | | read_ack_register--------+---------+ | | .... | | |
+ | | read_ack_preserve | | | CPER | | |
+ | | read_ack_write | +-+------------------------+-+ |
+ + +--------------------------+ | .......... | |
+ |----------------------------+ |
+ |Generic Error Status Block N |<----------+
+ |-+-------------------------+-+
+ | | CPER | |
+ | | CPER | |
+ | | .... | |
+ | | CPER | |
+ +-+-------------------------+-+
+
+
+(1) QEMU generates the ACPI HEST table. This table goes in the current
+ "etc/acpi/tables" fw_cfg blob. Each error source has different
+ notification types.
+
+(2) A new fw_cfg blob called "etc/hardware_errors" is introduced. QEMU
+ also needs to populate this blob. The "etc/hardware_errors" fw_cfg blob
+ contains an address registers table and an Error Status Data Block table.
+
+(3) The address registers table contains N Error Block Address entries
+ and N Read Ack Register entries. The size for each entry is 8-byte.
+ The Error Status Data Block table contains N Error Status Data Block
+ entries. The size for each entry is 4096(0x1000) bytes. The total size
+ for the "etc/hardware_errors" fw_cfg blob is (N * 8 * 2 + N * 4096) bytes.
+ N is the number of the kinds of hardware error sources.
+
+(4) QEMU generates the ACPI linker/loader script for the firmware. The
+ firmware pre-allocates memory for "etc/acpi/tables", "etc/hardware_errors"
+ and copies blob contents there.
+
+(5) QEMU generates N ADD_POINTER commands, which patch addresses in the
+ "error_status_address" fields of the HEST table with a pointer to the
+ corresponding "address registers" in the "etc/hardware_errors" blob.
+
+(6) QEMU generates N ADD_POINTER commands, which patch addresses in the
+ "read_ack_register" fields of the HEST table with a pointer to the
+ corresponding "read_ack_register" within the "etc/hardware_errors" blob.
+
+(7) QEMU generates N ADD_POINTER commands for the firmware, which patch
+ addresses in the "error_block_address" fields with a pointer to the
+ respective "Error Status Data Block" in the "etc/hardware_errors" blob.
+
+(8) QEMU defines a third and write-only fw_cfg blob which is called
+ "etc/hardware_errors_addr". Through that blob, the firmware can send back
+ the guest-side allocation addresses to QEMU. The "etc/hardware_errors_addr"
+ blob contains a 8-byte entry. QEMU generates a single WRITE_POINTER command
+ for the firmware. The firmware will write back the start address of
+ "etc/hardware_errors" blob to the fw_cfg file "etc/hardware_errors_addr".
+
+(9) When QEMU gets a SIGBUS from the kernel, QEMU writes CPER into corresponding
+ "Error Status Data Block", guest memory, and then injects platform specific
+ interrupt (in case of arm/virt machine it's Synchronous External Abort) as a
+ notification which is necessary for notifying the guest.
+
+(10) This notification (in virtual hardware) will be handled by the guest
+ kernel, on receiving notification, guest APEI driver could read the CPER error
+ and take appropriate action.
+
+(11) kvm_arch_on_sigbus_vcpu() uses source_id as index in "etc/hardware_errors" to
+ find out "Error Status Data Block" entry corresponding to error source. So supported
+ source_id values should be assigned here and not be changed afterwards to make sure
+ that guest will write error into expected "Error Status Data Block" even if guest was
+ migrated to a newer QEMU.
ppc-spapr-xive
acpi_hw_reduced_hotplug
tpm
+ acpi_hest_ghes
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2020 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.arm.m-profile">
+ <reg name="r0" bitsize="32"/>
+ <reg name="r1" bitsize="32"/>
+ <reg name="r2" bitsize="32"/>
+ <reg name="r3" bitsize="32"/>
+ <reg name="r4" bitsize="32"/>
+ <reg name="r5" bitsize="32"/>
+ <reg name="r6" bitsize="32"/>
+ <reg name="r7" bitsize="32"/>
+ <reg name="r8" bitsize="32"/>
+ <reg name="r9" bitsize="32"/>
+ <reg name="r10" bitsize="32"/>
+ <reg name="r11" bitsize="32"/>
+ <reg name="r12" bitsize="32"/>
+ <reg name="sp" bitsize="32" type="data_ptr"/>
+ <reg name="lr" bitsize="32"/>
+ <reg name="pc" bitsize="32" type="code_ptr"/>
+ <reg name="xpsr" bitsize="32" regnum="25"/>
+</feature>
{
int fd, serrno, ret;
+again:
fd = openat(dirfd, name, flags | O_NOFOLLOW | O_NOCTTY | O_NONBLOCK,
mode);
if (fd == -1) {
+ if (errno == EPERM && (flags & O_NOATIME)) {
+ /*
+ * The client passed O_NOATIME but we lack permissions to honor it.
+ * Rather than failing the open, fall back without O_NOATIME. This
+ * doesn't break the semantics on the client side, as the Linux
+ * open(2) man page notes that O_NOATIME "may not be effective on
+ * all filesystems". In particular, NFS and other network
+ * filesystems ignore it entirely.
+ */
+ flags &= ~O_NOATIME;
+ goto again;
+ }
return -1;
}
rc = 0;
out:
if (rc) {
- v9fs_device_unrealize_common(s, NULL);
+ v9fs_device_unrealize_common(s);
}
v9fs_path_free(&path);
return rc;
}
-void v9fs_device_unrealize_common(V9fsState *s, Error **errp)
+void v9fs_device_unrealize_common(V9fsState *s)
{
if (s->ops && s->ops->cleanup) {
s->ops->cleanup(&s->ctx);
const char *name, V9fsPath *path);
int v9fs_device_realize_common(V9fsState *s, const V9fsTransport *t,
Error **errp);
-void v9fs_device_unrealize_common(V9fsState *s, Error **errp);
+void v9fs_device_unrealize_common(V9fsState *s);
V9fsPDU *pdu_alloc(V9fsState *s);
void pdu_free(V9fsPDU *pdu);
v->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output);
}
-static void virtio_9p_device_unrealize(DeviceState *dev, Error **errp)
+static void virtio_9p_device_unrealize(DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
V9fsVirtioState *v = VIRTIO_9P(dev);
virtio_delete_queue(v->vq);
virtio_cleanup(vdev);
- v9fs_device_unrealize_common(s, errp);
+ v9fs_device_unrealize_common(s);
}
/* virtio-9p device */
ret = v9fs_iov_vmarshal(in_sg, num, offset, 0, fmt, ap);
if (ret < 0) {
xen_pv_printf(&xen_9pfs->xendev, 0,
- "Failed to encode VirtFS request type %d\n", pdu->id + 1);
+ "Failed to encode VirtFS reply type %d\n",
+ pdu->id + 1);
xen_be_set_state(&xen_9pfs->xendev, XenbusStateClosing);
xen_9pfs_disconnect(&xen_9pfs->xendev);
}
buf_size = iov_size(ring->sg, num);
if (buf_size < P9_IOHDRSZ) {
- xen_pv_printf(&xen_9pfs->xendev, 0, "Xen 9pfs request type %d"
- "needs %zu bytes, buffer has %zu, less than minimum\n",
- pdu->id, *size, buf_size);
+ xen_pv_printf(&xen_9pfs->xendev, 0, "Xen 9pfs reply type %d needs "
+ "%zu bytes, buffer has %zu, less than minimum\n",
+ pdu->id + 1, *size, buf_size);
xen_be_set_state(&xen_9pfs->xendev, XenbusStateClosing);
xen_9pfs_disconnect(&xen_9pfs->xendev);
}
bool
depends on ACPI
+config ACPI_APEI
+ bool
+ depends on ACPI
+
config ACPI_PCI
bool
depends on ACPI && PCI
common-obj-$(CONFIG_ACPI_VMGENID) += vmgenid.o
common-obj-$(CONFIG_ACPI_HW_REDUCED) += generic_event_device.o
common-obj-$(CONFIG_ACPI_HMAT) += hmat.o
+common-obj-$(CONFIG_ACPI_APEI) += ghes.o
common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o
common-obj-$(call lnot,$(CONFIG_PC)) += acpi-x86-stub.o
tables->table_data = g_array_new(false, true /* clear */, 1);
tables->tcpalog = g_array_new(false, true /* clear */, 1);
tables->vmgenid = g_array_new(false, true /* clear */, 1);
+ tables->hardware_errors = g_array_new(false, true /* clear */, 1);
tables->linker = bios_linker_loader_init();
}
g_array_free(tables->table_data, true);
g_array_free(tables->tcpalog, mfre);
g_array_free(tables->vmgenid, mfre);
+ g_array_free(tables->hardware_errors, mfre);
}
/*
}
};
+static bool ghes_needed(void *opaque)
+{
+ AcpiGedState *s = opaque;
+ return s->ghes_state.ghes_addr_le;
+}
+
+static const VMStateDescription vmstate_ghes_state = {
+ .name = "acpi-ged/ghes",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = ghes_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_STRUCT(ghes_state, AcpiGedState, 1,
+ vmstate_ghes_state, AcpiGhesState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static const VMStateDescription vmstate_acpi_ged = {
.name = "acpi-ged",
.version_id = 1,
},
.subsections = (const VMStateDescription * []) {
&vmstate_memhp_state,
+ &vmstate_ghes_state,
NULL
}
};
--- /dev/null
+/*
+ * Support for generating APEI tables and recording CPER for Guests
+ *
+ * Copyright (c) 2020 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Author: Dongjiu Geng <gengdongjiu@huawei.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 "qemu/osdep.h"
+#include "qemu/units.h"
+#include "hw/acpi/ghes.h"
+#include "hw/acpi/aml-build.h"
+#include "qemu/error-report.h"
+#include "hw/acpi/generic_event_device.h"
+#include "hw/nvram/fw_cfg.h"
+#include "qemu/uuid.h"
+
+#define ACPI_GHES_ERRORS_FW_CFG_FILE "etc/hardware_errors"
+#define ACPI_GHES_DATA_ADDR_FW_CFG_FILE "etc/hardware_errors_addr"
+
+/* The max size in bytes for one error block */
+#define ACPI_GHES_MAX_RAW_DATA_LENGTH (1 * KiB)
+
+/* Now only support ARMv8 SEA notification type error source */
+#define ACPI_GHES_ERROR_SOURCE_COUNT 1
+
+/* Generic Hardware Error Source version 2 */
+#define ACPI_GHES_SOURCE_GENERIC_ERROR_V2 10
+
+/* Address offset in Generic Address Structure(GAS) */
+#define GAS_ADDR_OFFSET 4
+
+/*
+ * The total size of Generic Error Data Entry
+ * ACPI 6.1/6.2: 18.3.2.7.1 Generic Error Data,
+ * Table 18-343 Generic Error Data Entry
+ */
+#define ACPI_GHES_DATA_LENGTH 72
+
+/* The memory section CPER size, UEFI 2.6: N.2.5 Memory Error Section */
+#define ACPI_GHES_MEM_CPER_LENGTH 80
+
+/* Masks for block_status flags */
+#define ACPI_GEBS_UNCORRECTABLE 1
+
+/*
+ * Total size for Generic Error Status Block except Generic Error Data Entries
+ * ACPI 6.2: 18.3.2.7.1 Generic Error Data,
+ * Table 18-380 Generic Error Status Block
+ */
+#define ACPI_GHES_GESB_SIZE 20
+
+/*
+ * Values for error_severity field
+ */
+enum AcpiGenericErrorSeverity {
+ ACPI_CPER_SEV_RECOVERABLE = 0,
+ ACPI_CPER_SEV_FATAL = 1,
+ ACPI_CPER_SEV_CORRECTED = 2,
+ ACPI_CPER_SEV_NONE = 3,
+};
+
+/*
+ * Hardware Error Notification
+ * ACPI 4.0: 17.3.2.7 Hardware Error Notification
+ * Composes dummy Hardware Error Notification descriptor of specified type
+ */
+static void build_ghes_hw_error_notification(GArray *table, const uint8_t type)
+{
+ /* Type */
+ build_append_int_noprefix(table, type, 1);
+ /*
+ * Length:
+ * Total length of the structure in bytes
+ */
+ build_append_int_noprefix(table, 28, 1);
+ /* Configuration Write Enable */
+ build_append_int_noprefix(table, 0, 2);
+ /* Poll Interval */
+ build_append_int_noprefix(table, 0, 4);
+ /* Vector */
+ build_append_int_noprefix(table, 0, 4);
+ /* Switch To Polling Threshold Value */
+ build_append_int_noprefix(table, 0, 4);
+ /* Switch To Polling Threshold Window */
+ build_append_int_noprefix(table, 0, 4);
+ /* Error Threshold Value */
+ build_append_int_noprefix(table, 0, 4);
+ /* Error Threshold Window */
+ build_append_int_noprefix(table, 0, 4);
+}
+
+/*
+ * Generic Error Data Entry
+ * ACPI 6.1: 18.3.2.7.1 Generic Error Data
+ */
+static void acpi_ghes_generic_error_data(GArray *table,
+ const uint8_t *section_type, uint32_t error_severity,
+ uint8_t validation_bits, uint8_t flags,
+ uint32_t error_data_length, QemuUUID fru_id,
+ uint64_t time_stamp)
+{
+ const uint8_t fru_text[20] = {0};
+
+ /* Section Type */
+ g_array_append_vals(table, section_type, 16);
+
+ /* Error Severity */
+ build_append_int_noprefix(table, error_severity, 4);
+ /* Revision */
+ build_append_int_noprefix(table, 0x300, 2);
+ /* Validation Bits */
+ build_append_int_noprefix(table, validation_bits, 1);
+ /* Flags */
+ build_append_int_noprefix(table, flags, 1);
+ /* Error Data Length */
+ build_append_int_noprefix(table, error_data_length, 4);
+
+ /* FRU Id */
+ g_array_append_vals(table, fru_id.data, ARRAY_SIZE(fru_id.data));
+
+ /* FRU Text */
+ g_array_append_vals(table, fru_text, sizeof(fru_text));
+
+ /* Timestamp */
+ build_append_int_noprefix(table, time_stamp, 8);
+}
+
+/*
+ * Generic Error Status Block
+ * ACPI 6.1: 18.3.2.7.1 Generic Error Data
+ */
+static void acpi_ghes_generic_error_status(GArray *table, uint32_t block_status,
+ uint32_t raw_data_offset, uint32_t raw_data_length,
+ uint32_t data_length, uint32_t error_severity)
+{
+ /* Block Status */
+ build_append_int_noprefix(table, block_status, 4);
+ /* Raw Data Offset */
+ build_append_int_noprefix(table, raw_data_offset, 4);
+ /* Raw Data Length */
+ build_append_int_noprefix(table, raw_data_length, 4);
+ /* Data Length */
+ build_append_int_noprefix(table, data_length, 4);
+ /* Error Severity */
+ build_append_int_noprefix(table, error_severity, 4);
+}
+
+/* UEFI 2.6: N.2.5 Memory Error Section */
+static void acpi_ghes_build_append_mem_cper(GArray *table,
+ uint64_t error_physical_addr)
+{
+ /*
+ * Memory Error Record
+ */
+
+ /* Validation Bits */
+ build_append_int_noprefix(table,
+ (1ULL << 14) | /* Type Valid */
+ (1ULL << 1) /* Physical Address Valid */,
+ 8);
+ /* Error Status */
+ build_append_int_noprefix(table, 0, 8);
+ /* Physical Address */
+ build_append_int_noprefix(table, error_physical_addr, 8);
+ /* Skip all the detailed information normally found in such a record */
+ build_append_int_noprefix(table, 0, 48);
+ /* Memory Error Type */
+ build_append_int_noprefix(table, 0 /* Unknown error */, 1);
+ /* Skip all the detailed information normally found in such a record */
+ build_append_int_noprefix(table, 0, 7);
+}
+
+static int acpi_ghes_record_mem_error(uint64_t error_block_address,
+ uint64_t error_physical_addr)
+{
+ GArray *block;
+
+ /* Memory Error Section Type */
+ const uint8_t uefi_cper_mem_sec[] =
+ UUID_LE(0xA5BC1114, 0x6F64, 0x4EDE, 0xB8, 0x63, 0x3E, 0x83, \
+ 0xED, 0x7C, 0x83, 0xB1);
+
+ /* invalid fru id: ACPI 4.0: 17.3.2.6.1 Generic Error Data,
+ * Table 17-13 Generic Error Data Entry
+ */
+ QemuUUID fru_id = {};
+ uint32_t data_length;
+
+ block = g_array_new(false, true /* clear */, 1);
+
+ /* This is the length if adding a new generic error data entry*/
+ data_length = ACPI_GHES_DATA_LENGTH + ACPI_GHES_MEM_CPER_LENGTH;
+
+ /*
+ * Check whether it will run out of the preallocated memory if adding a new
+ * generic error data entry
+ */
+ if ((data_length + ACPI_GHES_GESB_SIZE) > ACPI_GHES_MAX_RAW_DATA_LENGTH) {
+ error_report("Not enough memory to record new CPER!!!");
+ g_array_free(block, true);
+ return -1;
+ }
+
+ /* Build the new generic error status block header */
+ acpi_ghes_generic_error_status(block, ACPI_GEBS_UNCORRECTABLE,
+ 0, 0, data_length, ACPI_CPER_SEV_RECOVERABLE);
+
+ /* Build this new generic error data entry header */
+ acpi_ghes_generic_error_data(block, uefi_cper_mem_sec,
+ ACPI_CPER_SEV_RECOVERABLE, 0, 0,
+ ACPI_GHES_MEM_CPER_LENGTH, fru_id, 0);
+
+ /* Build the memory section CPER for above new generic error data entry */
+ acpi_ghes_build_append_mem_cper(block, error_physical_addr);
+
+ /* Write the generic error data entry into guest memory */
+ cpu_physical_memory_write(error_block_address, block->data, block->len);
+
+ g_array_free(block, true);
+
+ return 0;
+}
+
+/*
+ * Build table for the hardware error fw_cfg blob.
+ * Initialize "etc/hardware_errors" and "etc/hardware_errors_addr" fw_cfg blobs.
+ * See docs/specs/acpi_hest_ghes.rst for blobs format.
+ */
+void build_ghes_error_table(GArray *hardware_errors, BIOSLinker *linker)
+{
+ int i, error_status_block_offset;
+
+ /* Build error_block_address */
+ for (i = 0; i < ACPI_GHES_ERROR_SOURCE_COUNT; i++) {
+ build_append_int_noprefix(hardware_errors, 0, sizeof(uint64_t));
+ }
+
+ /* Build read_ack_register */
+ for (i = 0; i < ACPI_GHES_ERROR_SOURCE_COUNT; i++) {
+ /*
+ * Initialize the value of read_ack_register to 1, so GHES can be
+ * writeable after (re)boot.
+ * ACPI 6.2: 18.3.2.8 Generic Hardware Error Source version 2
+ * (GHESv2 - Type 10)
+ */
+ build_append_int_noprefix(hardware_errors, 1, sizeof(uint64_t));
+ }
+
+ /* Generic Error Status Block offset in the hardware error fw_cfg blob */
+ error_status_block_offset = hardware_errors->len;
+
+ /* Reserve space for Error Status Data Block */
+ acpi_data_push(hardware_errors,
+ ACPI_GHES_MAX_RAW_DATA_LENGTH * ACPI_GHES_ERROR_SOURCE_COUNT);
+
+ /* Tell guest firmware to place hardware_errors blob into RAM */
+ bios_linker_loader_alloc(linker, ACPI_GHES_ERRORS_FW_CFG_FILE,
+ hardware_errors, sizeof(uint64_t), false);
+
+ for (i = 0; i < ACPI_GHES_ERROR_SOURCE_COUNT; i++) {
+ /*
+ * Tell firmware to patch error_block_address entries to point to
+ * corresponding "Generic Error Status Block"
+ */
+ bios_linker_loader_add_pointer(linker,
+ ACPI_GHES_ERRORS_FW_CFG_FILE, sizeof(uint64_t) * i,
+ sizeof(uint64_t), ACPI_GHES_ERRORS_FW_CFG_FILE,
+ error_status_block_offset + i * ACPI_GHES_MAX_RAW_DATA_LENGTH);
+ }
+
+ /*
+ * tell firmware to write hardware_errors GPA into
+ * hardware_errors_addr fw_cfg, once the former has been initialized.
+ */
+ bios_linker_loader_write_pointer(linker, ACPI_GHES_DATA_ADDR_FW_CFG_FILE,
+ 0, sizeof(uint64_t), ACPI_GHES_ERRORS_FW_CFG_FILE, 0);
+}
+
+/* Build Generic Hardware Error Source version 2 (GHESv2) */
+static void build_ghes_v2(GArray *table_data, int source_id, BIOSLinker *linker)
+{
+ uint64_t address_offset;
+ /*
+ * Type:
+ * Generic Hardware Error Source version 2(GHESv2 - Type 10)
+ */
+ build_append_int_noprefix(table_data, ACPI_GHES_SOURCE_GENERIC_ERROR_V2, 2);
+ /* Source Id */
+ build_append_int_noprefix(table_data, source_id, 2);
+ /* Related Source Id */
+ build_append_int_noprefix(table_data, 0xffff, 2);
+ /* Flags */
+ build_append_int_noprefix(table_data, 0, 1);
+ /* Enabled */
+ build_append_int_noprefix(table_data, 1, 1);
+
+ /* Number of Records To Pre-allocate */
+ build_append_int_noprefix(table_data, 1, 4);
+ /* Max Sections Per Record */
+ build_append_int_noprefix(table_data, 1, 4);
+ /* Max Raw Data Length */
+ build_append_int_noprefix(table_data, ACPI_GHES_MAX_RAW_DATA_LENGTH, 4);
+
+ address_offset = table_data->len;
+ /* Error Status Address */
+ build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 0x40, 0,
+ 4 /* QWord access */, 0);
+ bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
+ address_offset + GAS_ADDR_OFFSET, sizeof(uint64_t),
+ ACPI_GHES_ERRORS_FW_CFG_FILE, source_id * sizeof(uint64_t));
+
+ switch (source_id) {
+ case ACPI_HEST_SRC_ID_SEA:
+ /*
+ * Notification Structure
+ * Now only enable ARMv8 SEA notification type
+ */
+ build_ghes_hw_error_notification(table_data, ACPI_GHES_NOTIFY_SEA);
+ break;
+ default:
+ error_report("Not support this error source");
+ abort();
+ }
+
+ /* Error Status Block Length */
+ build_append_int_noprefix(table_data, ACPI_GHES_MAX_RAW_DATA_LENGTH, 4);
+
+ /*
+ * Read Ack Register
+ * ACPI 6.1: 18.3.2.8 Generic Hardware Error Source
+ * version 2 (GHESv2 - Type 10)
+ */
+ address_offset = table_data->len;
+ build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 0x40, 0,
+ 4 /* QWord access */, 0);
+ bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
+ address_offset + GAS_ADDR_OFFSET,
+ sizeof(uint64_t), ACPI_GHES_ERRORS_FW_CFG_FILE,
+ (ACPI_GHES_ERROR_SOURCE_COUNT + source_id) * sizeof(uint64_t));
+
+ /*
+ * Read Ack Preserve field
+ * We only provide the first bit in Read Ack Register to OSPM to write
+ * while the other bits are preserved.
+ */
+ build_append_int_noprefix(table_data, ~0x1ULL, 8);
+ /* Read Ack Write */
+ build_append_int_noprefix(table_data, 0x1, 8);
+}
+
+/* Build Hardware Error Source Table */
+void acpi_build_hest(GArray *table_data, BIOSLinker *linker)
+{
+ uint64_t hest_start = table_data->len;
+
+ /* Hardware Error Source Table header*/
+ acpi_data_push(table_data, sizeof(AcpiTableHeader));
+
+ /* Error Source Count */
+ build_append_int_noprefix(table_data, ACPI_GHES_ERROR_SOURCE_COUNT, 4);
+
+ build_ghes_v2(table_data, ACPI_HEST_SRC_ID_SEA, linker);
+
+ build_header(linker, table_data, (void *)(table_data->data + hest_start),
+ "HEST", table_data->len - hest_start, 1, NULL, NULL);
+}
+
+void acpi_ghes_add_fw_cfg(AcpiGhesState *ags, FWCfgState *s,
+ GArray *hardware_error)
+{
+ /* Create a read-only fw_cfg file for GHES */
+ fw_cfg_add_file(s, ACPI_GHES_ERRORS_FW_CFG_FILE, hardware_error->data,
+ hardware_error->len);
+
+ /* Create a read-write fw_cfg file for Address */
+ fw_cfg_add_file_callback(s, ACPI_GHES_DATA_ADDR_FW_CFG_FILE, NULL, NULL,
+ NULL, &(ags->ghes_addr_le), sizeof(ags->ghes_addr_le), false);
+}
+
+int acpi_ghes_record_errors(uint8_t source_id, uint64_t physical_address)
+{
+ uint64_t error_block_addr, read_ack_register_addr, read_ack_register = 0;
+ uint64_t start_addr;
+ bool ret = -1;
+ AcpiGedState *acpi_ged_state;
+ AcpiGhesState *ags;
+
+ assert(source_id < ACPI_HEST_SRC_ID_RESERVED);
+
+ acpi_ged_state = ACPI_GED(object_resolve_path_type("", TYPE_ACPI_GED,
+ NULL));
+ g_assert(acpi_ged_state);
+ ags = &acpi_ged_state->ghes_state;
+
+ start_addr = le64_to_cpu(ags->ghes_addr_le);
+
+ if (physical_address) {
+
+ if (source_id < ACPI_HEST_SRC_ID_RESERVED) {
+ start_addr += source_id * sizeof(uint64_t);
+ }
+
+ cpu_physical_memory_read(start_addr, &error_block_addr,
+ sizeof(error_block_addr));
+
+ error_block_addr = le64_to_cpu(error_block_addr);
+
+ read_ack_register_addr = start_addr +
+ ACPI_GHES_ERROR_SOURCE_COUNT * sizeof(uint64_t);
+
+ cpu_physical_memory_read(read_ack_register_addr,
+ &read_ack_register, sizeof(read_ack_register));
+
+ /* zero means OSPM does not acknowledge the error */
+ if (!read_ack_register) {
+ error_report("OSPM does not acknowledge previous error,"
+ " so can not record CPER for current error anymore");
+ } else if (error_block_addr) {
+ read_ack_register = cpu_to_le64(0);
+ /*
+ * Clear the Read Ack Register, OSPM will write it to 1 when
+ * it acknowledges this error.
+ */
+ cpu_physical_memory_write(read_ack_register_addr,
+ &read_ack_register, sizeof(uint64_t));
+
+ ret = acpi_ghes_record_mem_error(error_block_addr,
+ physical_address);
+ } else
+ error_report("can not find Generic Error Status Block");
+ }
+
+ return ret;
+}
s->pm.enable_tco = value;
}
-void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp)
+void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
{
static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN;
pm->acpi_memory_hotplug.is_enabled = true;
pm->s4_val = 2;
object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
- &pm->pm_io_base, OBJ_PROP_FLAG_READ, errp);
+ &pm->pm_io_base, OBJ_PROP_FLAG_READ);
object_property_add(obj, ACPI_PM_PROP_GPE0_BLK, "uint32",
ich9_pm_get_gpe0_blk,
- NULL, NULL, pm, NULL);
+ NULL, NULL, pm);
object_property_add_uint32_ptr(obj, ACPI_PM_PROP_GPE0_BLK_LEN,
- &gpe0_len, OBJ_PROP_FLAG_READ, errp);
+ &gpe0_len, OBJ_PROP_FLAG_READ);
object_property_add_bool(obj, "memory-hotplug-support",
ich9_pm_get_memory_hotplug_support,
- ich9_pm_set_memory_hotplug_support,
- NULL);
+ ich9_pm_set_memory_hotplug_support);
object_property_add_bool(obj, "cpu-hotplug-legacy",
ich9_pm_get_cpu_hotplug_legacy,
- ich9_pm_set_cpu_hotplug_legacy,
- NULL);
+ ich9_pm_set_cpu_hotplug_legacy);
object_property_add_uint8_ptr(obj, ACPI_PM_PROP_S3_DISABLED,
- &pm->disable_s3, OBJ_PROP_FLAG_READWRITE,
- NULL);
+ &pm->disable_s3, OBJ_PROP_FLAG_READWRITE);
object_property_add_uint8_ptr(obj, ACPI_PM_PROP_S4_DISABLED,
- &pm->disable_s4, OBJ_PROP_FLAG_READWRITE,
- NULL);
+ &pm->disable_s4, OBJ_PROP_FLAG_READWRITE);
object_property_add_uint8_ptr(obj, ACPI_PM_PROP_S4_VAL,
- &pm->s4_val, OBJ_PROP_FLAG_READWRITE, NULL);
+ &pm->s4_val, OBJ_PROP_FLAG_READWRITE);
object_property_add_bool(obj, ACPI_PM_PROP_TCO_ENABLED,
ich9_pm_get_enable_tco,
- ich9_pm_set_enable_tco,
- NULL);
+ ich9_pm_set_enable_tco);
}
void ich9_pm_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
*/
#include "qemu/osdep.h"
+#include "qemu/uuid.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/aml-build.h"
#include "hw/acpi/bios-linker-loader.h"
#include "hw/mem/nvdimm.h"
#include "qemu/nvdimm-utils.h"
-#define NVDIMM_UUID_LE(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
- { (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
- (b) & 0xff, ((b) >> 8) & 0xff, (c) & 0xff, ((c) >> 8) & 0xff, \
- (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }
-
/*
* define Byte Addressable Persistent Memory (PM) Region according to
* ACPI 6.0: 5.2.25.1 System Physical Address Range Structure.
*/
static const uint8_t nvdimm_nfit_spa_uuid[] =
- NVDIMM_UUID_LE(0x66f0d379, 0xb4f3, 0x4074, 0xac, 0x43, 0x0d, 0x33,
- 0x18, 0xb7, 0x8c, 0xdb);
+ UUID_LE(0x66f0d379, 0xb4f3, 0x4074, 0xac, 0x43, 0x0d, 0x33,
+ 0x18, 0xb7, 0x8c, 0xdb);
/*
* NVDIMM Firmware Interface Table
*bus_bsel = (*bsel_alloc)++;
object_property_add_uint32_ptr(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
- bus_bsel, OBJ_PROP_FLAG_READ,
- &error_abort);
+ bus_bsel, OBJ_PROP_FLAG_READ);
}
return bsel_alloc;
{
trace_acpi_pci_unplug(PCI_SLOT(PCI_DEVICE(dev)->devfn),
acpi_pcihp_get_bsel(pci_get_bus(PCI_DEVICE(dev))));
- object_property_set_bool(OBJECT(dev), false, "realized", NULL);
+ object_property_set_bool(OBJECT(dev), false, "realized", &error_abort);
}
void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
memory_region_add_subregion(address_space_io, s->io_base, &s->io);
object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_BASE_PROP, &s->io_base,
- OBJ_PROP_FLAG_READ, &error_abort);
+ OBJ_PROP_FLAG_READ);
object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_LEN_PROP, &s->io_len,
- OBJ_PROP_FLAG_READ, &error_abort);
+ OBJ_PROP_FLAG_READ);
}
const VMStateDescription vmstate_acpi_pcihp_pci_status = {
static const uint16_t sci_int = 9;
object_property_add_uint8_ptr(OBJECT(s), ACPI_PM_PROP_ACPI_ENABLE_CMD,
- &acpi_enable_cmd, OBJ_PROP_FLAG_READ, NULL);
+ &acpi_enable_cmd, OBJ_PROP_FLAG_READ);
object_property_add_uint8_ptr(OBJECT(s), ACPI_PM_PROP_ACPI_DISABLE_CMD,
- &acpi_disable_cmd, OBJ_PROP_FLAG_READ, NULL);
+ &acpi_disable_cmd, OBJ_PROP_FLAG_READ);
object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_GPE0_BLK,
- &gpe0_blk, OBJ_PROP_FLAG_READ, NULL);
+ &gpe0_blk, OBJ_PROP_FLAG_READ);
object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_GPE0_BLK_LEN,
- &gpe0_blk_len, OBJ_PROP_FLAG_READ, NULL);
+ &gpe0_blk_len, OBJ_PROP_FLAG_READ);
object_property_add_uint16_ptr(OBJECT(s), ACPI_PM_PROP_SCI_INT,
- &sci_int, OBJ_PROP_FLAG_READ, NULL);
+ &sci_int, OBJ_PROP_FLAG_READ);
object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_PM_IO_BASE,
- &s->io_base, OBJ_PROP_FLAG_READ, NULL);
+ &s->io_base, OBJ_PROP_FLAG_READ);
}
static void piix4_pm_realize(PCIDevice *dev, Error **errp)
s->cpu_hotplug_legacy = true;
object_property_add_bool(OBJECT(s), "cpu-hotplug-legacy",
piix4_get_cpu_hotplug_legacy,
- piix4_set_cpu_hotplug_legacy,
- NULL);
+ piix4_set_cpu_hotplug_legacy);
legacy_acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu,
PIIX4_CPU_HOTPLUG_IO_BASE);
sysbus_mmio_map(SYS_BUS_DEVICE(&s->mmc0), 0, AW_A10_MMC0_BASE);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->mmc0), 0, qdev_get_gpio_in(dev, 32));
object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->mmc0),
- "sd-bus", &error_abort);
+ "sd-bus");
/* RTC */
qdev_init_nofail(DEVICE(&s->rtc));
sysbus_init_child_obj(obj, "timer", &s->timer, sizeof(s->timer),
TYPE_AW_A10_PIT);
object_property_add_alias(obj, "clk0-freq", OBJECT(&s->timer),
- "clk0-freq", &error_abort);
+ "clk0-freq");
object_property_add_alias(obj, "clk1-freq", OBJECT(&s->timer),
- "clk1-freq", &error_abort);
+ "clk1-freq");
sysbus_init_child_obj(obj, "ccu", &s->ccu, sizeof(s->ccu),
TYPE_AW_H3_CCU);
sysbus_init_child_obj(obj, "sid", &s->sid, sizeof(s->sid),
TYPE_AW_SID);
object_property_add_alias(obj, "identifier", OBJECT(&s->sid),
- "identifier", &error_abort);
+ "identifier");
sysbus_init_child_obj(obj, "mmc0", &s->mmc0, sizeof(s->mmc0),
TYPE_AW_SDHOST_SUN5I);
sysbus_init_child_obj(obj, "dramc", &s->dramc, sizeof(s->dramc),
TYPE_AW_H3_DRAMC);
object_property_add_alias(obj, "ram-addr", OBJECT(&s->dramc),
- "ram-addr", &error_abort);
+ "ram-addr");
object_property_add_alias(obj, "ram-size", OBJECT(&s->dramc),
- "ram-size", &error_abort);
+ "ram-size");
sysbus_init_child_obj(obj, "rtc", &s->rtc, sizeof(s->rtc),
TYPE_AW_RTC_SUN6I);
qdev_get_gpio_in(DEVICE(&s->gic), AW_H3_GIC_SPI_MMC0));
object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->mmc0),
- "sd-bus", &error_abort);
+ "sd-bus");
/* EMAC */
if (nd_table[0].used) {
sysbus_init_child_obj(obj, "nvnic", &s->nvic, sizeof(s->nvic), TYPE_NVIC);
object_property_add_alias(obj, "num-irq",
- OBJECT(&s->nvic), "num-irq", &error_abort);
+ OBJECT(&s->nvic), "num-irq");
for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
sysbus_init_child_obj(obj, "bitband[*]", &s->bitband[i],
SCU_AST2500_HW_STRAP_ACPI_ENABLE | \
SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER))
+/* Sonorapass hardware value: 0xF100D216 */
+#define SONORAPASS_BMC_HW_STRAP1 ( \
+ SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE | \
+ SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE | \
+ SCU_AST2500_HW_STRAP_UART_DEBUG | \
+ SCU_AST2500_HW_STRAP_RESERVED28 | \
+ SCU_AST2500_HW_STRAP_DDR4_ENABLE | \
+ SCU_HW_STRAP_VGA_CLASS_CODE | \
+ SCU_HW_STRAP_LPC_RESET_PIN | \
+ SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER) | \
+ SCU_AST2500_HW_STRAP_SET_AXI_AHB_RATIO(AXI_AHB_RATIO_2_1) | \
+ SCU_HW_STRAP_VGA_BIOS_ROM | \
+ SCU_HW_STRAP_VGA_SIZE_SET(VGA_16M_DRAM) | \
+ SCU_AST2500_HW_STRAP_RESERVED1)
+
/* Swift hardware value: 0xF11AD206 */
#define SWIFT_BMC_HW_STRAP1 ( \
AST2500_HW_STRAP1_DEFAULTS | \
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 12), "tmp105", 0x4a);
}
+static void sonorapass_bmc_i2c_init(AspeedBoardState *bmc)
+{
+ AspeedSoCState *soc = &bmc->soc;
+
+ /* bus 2 : */
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 2), "tmp105", 0x48);
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 2), "tmp105", 0x49);
+ /* bus 2 : pca9546 @ 0x73 */
+
+ /* bus 3 : pca9548 @ 0x70 */
+
+ /* bus 4 : */
+ uint8_t *eeprom4_54 = g_malloc0(8 * 1024);
+ smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), 0x54,
+ eeprom4_54);
+ /* PCA9539 @ 0x76, but PCA9552 is compatible */
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "pca9552", 0x76);
+ /* PCA9539 @ 0x77, but PCA9552 is compatible */
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "pca9552", 0x77);
+
+ /* bus 6 : */
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 6), "tmp105", 0x48);
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 6), "tmp105", 0x49);
+ /* bus 6 : pca9546 @ 0x73 */
+
+ /* bus 8 : */
+ uint8_t *eeprom8_56 = g_malloc0(8 * 1024);
+ smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 8), 0x56,
+ eeprom8_56);
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 8), "pca9552", 0x60);
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 8), "pca9552", 0x61);
+ /* bus 8 : adc128d818 @ 0x1d */
+ /* bus 8 : adc128d818 @ 0x1f */
+
+ /*
+ * bus 13 : pca9548 @ 0x71
+ * - channel 3:
+ * - tmm421 @ 0x4c
+ * - tmp421 @ 0x4e
+ * - tmp421 @ 0x4f
+ */
+
+}
+
static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
{
AspeedSoCState *soc = &bmc->soc;
{
object_class_property_add_bool(oc, "execute-in-place",
aspeed_get_mmio_exec,
- aspeed_set_mmio_exec, &error_abort);
+ aspeed_set_mmio_exec);
object_class_property_set_description(oc, "execute-in-place",
- "boot directly from CE0 flash device", &error_abort);
+ "boot directly from CE0 flash device");
}
static void aspeed_machine_class_init(ObjectClass *oc, void *data)
mc->default_ram_size = 512 * MiB;
};
+static void aspeed_machine_sonorapass_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
+
+ mc->desc = "OCP SonoraPass BMC (ARM1176)";
+ amc->soc_name = "ast2500-a1";
+ amc->hw_strap1 = SONORAPASS_BMC_HW_STRAP1;
+ amc->fmc_model = "mx66l1g45g";
+ amc->spi_model = "mx66l1g45g";
+ amc->num_cs = 2;
+ amc->i2c_init = sonorapass_bmc_i2c_init;
+ mc->default_ram_size = 512 * MiB;
+};
+
static void aspeed_machine_swift_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
.name = MACHINE_TYPE_NAME("swift-bmc"),
.parent = TYPE_ASPEED_MACHINE,
.class_init = aspeed_machine_swift_class_init,
+ }, {
+ .name = MACHINE_TYPE_NAME("sonorapass-bmc"),
+ .parent = TYPE_ASPEED_MACHINE,
+ .class_init = aspeed_machine_sonorapass_class_init,
}, {
.name = MACHINE_TYPE_NAME("witherspoon-bmc"),
.parent = TYPE_ASPEED_MACHINE,
qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev",
sc->silicon_rev);
object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
- "hw-strap1", &error_abort);
+ "hw-strap1");
object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
- "hw-strap2", &error_abort);
+ "hw-strap2");
object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu),
- "hw-prot-key", &error_abort);
+ "hw-prot-key");
sysbus_init_child_obj(obj, "a7mpcore", &s->a7mpcore,
sizeof(s->a7mpcore), TYPE_A15MPCORE_PRIV);
snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
sysbus_init_child_obj(obj, "fmc", OBJECT(&s->fmc), sizeof(s->fmc),
typename);
- object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
- &error_abort);
+ object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs");
for (i = 0; i < sc->spis_num; i++) {
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc),
typename);
object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
- "ram-size", &error_abort);
+ "ram-size");
object_property_add_alias(obj, "max-ram-size", OBJECT(&s->sdmc),
- "max-ram-size", &error_abort);
+ "max-ram-size");
for (i = 0; i < sc->wdts_num; i++) {
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev",
sc->silicon_rev);
object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
- "hw-strap1", &error_abort);
+ "hw-strap1");
object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
- "hw-strap2", &error_abort);
+ "hw-strap2");
object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu),
- "hw-prot-key", &error_abort);
+ "hw-prot-key");
sysbus_init_child_obj(obj, "vic", OBJECT(&s->vic), sizeof(s->vic),
TYPE_ASPEED_VIC);
snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
sysbus_init_child_obj(obj, "fmc", OBJECT(&s->fmc), sizeof(s->fmc),
typename);
- object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
- &error_abort);
+ object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs");
for (i = 0; i < sc->spis_num; i++) {
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc),
typename);
object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
- "ram-size", &error_abort);
+ "ram-size");
object_property_add_alias(obj, "max-ram-size", OBJECT(&s->sdmc),
- "max-ram-size", &error_abort);
+ "max-ram-size");
for (i = 0; i < sc->wdts_num; i++) {
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
/* Memory region for peripheral devices, which we export to our parent */
memory_region_init(&s->peri_mr, obj,"bcm2835-peripherals", 0x1000000);
- object_property_add_child(obj, "peripheral-io", OBJECT(&s->peri_mr), NULL);
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->peri_mr);
/* Internal memory region for peripheral bus addresses (not exported) */
memory_region_init(&s->gpu_bus_mr, obj, "bcm2835-gpu", (uint64_t)1 << 32);
- object_property_add_child(obj, "gpu-bus", OBJECT(&s->gpu_bus_mr), NULL);
/* Internal memory region for request/response communication with
* mailbox-addressable peripherals (not exported)
TYPE_BCM2835_MBOX);
object_property_add_const_link(OBJECT(&s->mboxes), "mbox-mr",
- OBJECT(&s->mbox_mr), &error_abort);
+ OBJECT(&s->mbox_mr));
/* Framebuffer */
sysbus_init_child_obj(obj, "fb", &s->fb, sizeof(s->fb), TYPE_BCM2835_FB);
- object_property_add_alias(obj, "vcram-size", OBJECT(&s->fb), "vcram-size",
- &error_abort);
+ object_property_add_alias(obj, "vcram-size", OBJECT(&s->fb), "vcram-size");
object_property_add_const_link(OBJECT(&s->fb), "dma-mr",
- OBJECT(&s->gpu_bus_mr), &error_abort);
+ OBJECT(&s->gpu_bus_mr));
/* Property channel */
sysbus_init_child_obj(obj, "property", &s->property, sizeof(s->property),
TYPE_BCM2835_PROPERTY);
object_property_add_alias(obj, "board-rev", OBJECT(&s->property),
- "board-rev", &error_abort);
+ "board-rev");
object_property_add_const_link(OBJECT(&s->property), "fb",
- OBJECT(&s->fb), &error_abort);
+ OBJECT(&s->fb));
object_property_add_const_link(OBJECT(&s->property), "dma-mr",
- OBJECT(&s->gpu_bus_mr), &error_abort);
+ OBJECT(&s->gpu_bus_mr));
/* Random Number Generator */
sysbus_init_child_obj(obj, "rng", &s->rng, sizeof(s->rng),
TYPE_BCM2835_DMA);
object_property_add_const_link(OBJECT(&s->dma), "dma-mr",
- OBJECT(&s->gpu_bus_mr), &error_abort);
+ OBJECT(&s->gpu_bus_mr));
/* Thermal */
sysbus_init_child_obj(obj, "thermal", &s->thermal, sizeof(s->thermal),
TYPE_BCM2835_GPIO);
object_property_add_const_link(OBJECT(&s->gpio), "sdbus-sdhci",
- OBJECT(&s->sdhci.sdbus), &error_abort);
+ OBJECT(&s->sdhci.sdbus));
object_property_add_const_link(OBJECT(&s->gpio), "sdbus-sdhost",
- OBJECT(&s->sdhost.sdbus), &error_abort);
+ OBJECT(&s->sdhost.sdbus));
}
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
memory_region_add_subregion(&s->peri_mr, GPIO_OFFSET,
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gpio), 0));
- object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->gpio), "sd-bus",
- &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->gpio), "sd-bus");
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
create_unimp(s, &s->cprman, "bcm2835-cprman", CPRMAN_OFFSET, 0x1000);
sysbus_init_child_obj(obj, "peripherals", &s->peripherals,
sizeof(s->peripherals), TYPE_BCM2835_PERIPHERALS);
object_property_add_alias(obj, "board-rev", OBJECT(&s->peripherals),
- "board-rev", &error_abort);
+ "board-rev");
object_property_add_alias(obj, "vcram-size", OBJECT(&s->peripherals),
- "vcram-size", &error_abort);
+ "vcram-size");
}
static void bcm2836_realize(DeviceState *dev, Error **errp)
return;
}
- object_property_add_const_link(OBJECT(&s->peripherals), "ram", obj, &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ object_property_add_const_link(OBJECT(&s->peripherals), "ram", obj);
object_property_set_bool(OBJECT(&s->peripherals), true, "realized", &err);
if (err) {
}
object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->peripherals),
- "sd-bus", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ "sd-bus");
sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->peripherals), 0,
info->peri_base, 1);
}
a10 = AW_A10(object_new(TYPE_AW_A10));
- object_property_add_child(OBJECT(machine), "soc", OBJECT(a10),
- &error_abort);
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(a10));
object_unref(OBJECT(a10));
object_property_set_int(OBJECT(&a10->emac), 1, "phy-addr", &err);
};
s = FSL_IMX6UL(object_new(TYPE_FSL_IMX6UL));
- object_property_add_child(OBJECT(machine), "soc", OBJECT(s), &error_fatal);
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(s));
object_property_set_bool(OBJECT(s), true, "realized", &error_fatal);
memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_MMDC_ADDR,
};
s = FSL_IMX7(object_new(TYPE_FSL_IMX7));
- object_property_add_child(OBJECT(machine), "soc", OBJECT(s), &error_fatal);
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(s));
object_property_set_bool(OBJECT(s), true, "realized", &error_fatal);
memory_region_add_subregion(get_system_memory(), FSL_IMX7_MMDC_ADDR,
/* Alias controller SPI bus to the SoC itself */
bus_name = g_strdup_printf("spi%d", i);
object_property_add_alias(OBJECT(s), bus_name,
- OBJECT(&s->spi[i]), "spi",
- &error_abort);
+ OBJECT(&s->spi[i]), "spi");
g_free(bus_name);
}
sysbus_init_child_obj(obj, "uart", &s->uart, sizeof(s->uart),
TYPE_NRF51_UART);
- object_property_add_alias(obj, "serial0", OBJECT(&s->uart), "chardev",
- &error_abort);
+ object_property_add_alias(obj, "serial0", OBJECT(&s->uart), "chardev");
sysbus_init_child_obj(obj, "rng", &s->rng, sizeof(s->rng),
TYPE_NRF51_RNG);
}
h3 = AW_H3(object_new(TYPE_AW_H3));
- object_property_add_child(OBJECT(machine), "soc", OBJECT(h3),
- &error_abort);
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(h3));
object_unref(OBJECT(h3));
/* Setup timer properties */
/* Setup the SOC */
object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc),
board_soc_type(board_rev), &error_abort, NULL);
- object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(machine->ram),
- &error_abort);
+ object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(machine->ram));
object_property_set_int(OBJECT(&s->soc), board_rev, "board-rev",
&error_abort);
object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_abort);
}
s = FSL_IMX6(object_new(TYPE_FSL_IMX6));
- object_property_add_child(OBJECT(machine), "soc", OBJECT(s), &error_fatal);
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(s));
object_property_set_bool(OBJECT(s), true, "realized", &err);
if (err != NULL) {
error_report("%s", error_get_pretty(err));
qdev_prop_set_uint16(dev, "id2", 0x00);
qdev_prop_set_uint16(dev, "id3", 0x00);
qdev_prop_set_string(dev, "name", name);
- object_property_add_child(OBJECT(sms), name, OBJECT(dev),
- &error_abort);
+ object_property_add_child(OBJECT(sms), name, OBJECT(dev));
object_property_add_alias(OBJECT(sms), alias_prop_name,
- OBJECT(dev), "drive", &error_abort);
+ OBJECT(dev), "drive");
return PFLASH_CFI01(dev);
}
/* EL3 is enabled by default on vexpress */
vms->secure = true;
object_property_add_bool(obj, "secure", vexpress_get_secure,
- vexpress_set_secure, NULL);
+ vexpress_set_secure);
object_property_set_description(obj, "secure",
"Set on/off to enable/disable the ARM "
- "Security Extensions (TrustZone)",
- NULL);
+ "Security Extensions (TrustZone)");
}
static void vexpress_a15_instance_init(Object *obj)
*/
vms->virt = true;
object_property_add_bool(obj, "virtualization", vexpress_get_virt,
- vexpress_set_virt, NULL);
+ vexpress_set_virt);
object_property_set_description(obj, "virtualization",
"Set on/off to enable/disable the ARM "
"Virtualization Extensions "
- "(defaults to same as 'secure')",
- NULL);
+ "(defaults to same as 'secure')");
}
static void vexpress_a9_instance_init(Object *obj)
#include "sysemu/reset.h"
#include "kvm_arm.h"
#include "migration/vmstate.h"
+#include "hw/acpi/ghes.h"
#define ARM_SPI_BASE 32
acpi_add_table(table_offsets, tables_blob);
build_spcr(tables_blob, tables->linker, vms);
+ if (vms->ras) {
+ build_ghes_error_table(tables->hardware_errors, tables->linker);
+ acpi_add_table(table_offsets, tables_blob);
+ acpi_build_hest(tables_blob, tables->linker);
+ }
+
if (ms->numa_state->num_nodes > 0) {
acpi_add_table(table_offsets, tables_blob);
build_srat(tables_blob, tables->linker, vms);
{
AcpiBuildTables tables;
AcpiBuildState *build_state;
+ AcpiGedState *acpi_ged_state;
if (!vms->fw_cfg) {
trace_virt_acpi_setup();
fw_cfg_add_file(vms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data,
acpi_data_len(tables.tcpalog));
+ if (vms->ras) {
+ assert(vms->acpi_dev);
+ acpi_ged_state = ACPI_GED(vms->acpi_dev);
+ acpi_ghes_add_fw_cfg(&acpi_ged_state->ghes_state,
+ vms->fw_cfg, tables.hardware_errors);
+ }
+
build_state->rsdp_mr = acpi_add_rom_blob(virt_acpi_build_update,
build_state, tables.rsdp,
ACPI_BUILD_RSDP_FILE, 0);
qdev_prop_set_uint16(dev, "id2", 0x00);
qdev_prop_set_uint16(dev, "id3", 0x00);
qdev_prop_set_string(dev, "name", name);
- object_property_add_child(OBJECT(vms), name, OBJECT(dev),
- &error_abort);
+ object_property_add_child(OBJECT(vms), name, OBJECT(dev));
object_property_add_alias(OBJECT(vms), alias_prop_name,
- OBJECT(dev), "drive", &error_abort);
+ OBJECT(dev), "drive");
return PFLASH_CFI01(dev);
}
visit_type_OnOffAuto(v, name, &vms->acpi, errp);
}
+static bool virt_get_ras(Object *obj, Error **errp)
+{
+ VirtMachineState *vms = VIRT_MACHINE(obj);
+
+ return vms->ras;
+}
+
+static void virt_set_ras(Object *obj, bool value, Error **errp)
+{
+ VirtMachineState *vms = VIRT_MACHINE(obj);
+
+ vms->ras = value;
+}
+
static char *virt_get_gic_version(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
object_class_property_add(oc, "acpi", "OnOffAuto",
virt_get_acpi, virt_set_acpi,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_set_description(oc, "acpi",
- "Enable ACPI", &error_abort);
+ "Enable ACPI");
}
static void virt_instance_init(Object *obj)
*/
vms->secure = false;
object_property_add_bool(obj, "secure", virt_get_secure,
- virt_set_secure, NULL);
+ virt_set_secure);
object_property_set_description(obj, "secure",
"Set on/off to enable/disable the ARM "
- "Security Extensions (TrustZone)",
- NULL);
+ "Security Extensions (TrustZone)");
/* EL2 is also disabled by default, for similar reasons */
vms->virt = false;
object_property_add_bool(obj, "virtualization", virt_get_virt,
- virt_set_virt, NULL);
+ virt_set_virt);
object_property_set_description(obj, "virtualization",
"Set on/off to enable/disable emulating a "
"guest CPU which implements the ARM "
- "Virtualization Extensions",
- NULL);
+ "Virtualization Extensions");
/* High memory is enabled by default */
vms->highmem = true;
object_property_add_bool(obj, "highmem", virt_get_highmem,
- virt_set_highmem, NULL);
+ virt_set_highmem);
object_property_set_description(obj, "highmem",
"Set on/off to enable/disable using "
- "physical address space above 32 bits",
- NULL);
+ "physical address space above 32 bits");
vms->gic_version = VIRT_GIC_VERSION_NOSEL;
object_property_add_str(obj, "gic-version", virt_get_gic_version,
- virt_set_gic_version, NULL);
+ virt_set_gic_version);
object_property_set_description(obj, "gic-version",
"Set GIC version. "
- "Valid values are 2, 3, host and max",
- NULL);
+ "Valid values are 2, 3, host and max");
vms->highmem_ecam = !vmc->no_highmem_ecam;
/* Default allows ITS instantiation */
vms->its = true;
object_property_add_bool(obj, "its", virt_get_its,
- virt_set_its, NULL);
+ virt_set_its);
object_property_set_description(obj, "its",
"Set on/off to enable/disable "
- "ITS instantiation",
- NULL);
+ "ITS instantiation");
}
/* Default disallows iommu instantiation */
vms->iommu = VIRT_IOMMU_NONE;
- object_property_add_str(obj, "iommu", virt_get_iommu, virt_set_iommu, NULL);
+ object_property_add_str(obj, "iommu", virt_get_iommu, virt_set_iommu);
object_property_set_description(obj, "iommu",
"Set the IOMMU type. "
- "Valid values are none and smmuv3",
- NULL);
+ "Valid values are none and smmuv3");
+
+ /* Default disallows RAS instantiation */
+ vms->ras = false;
+ object_property_add_bool(obj, "ras", virt_get_ras,
+ virt_set_ras);
+ object_property_set_description(obj, "ras",
+ "Set on/off to enable/disable reporting host memory errors "
+ "to a KVM guest using ACPI and guest external abort exceptions");
vms->irqmap = a15irqmap;
/* Create the main clock source, and feed slcr with it */
zynq_machine->ps_clk = CLOCK(object_new(TYPE_CLOCK));
object_property_add_child(OBJECT(zynq_machine), "ps_clk",
- OBJECT(zynq_machine->ps_clk), &error_abort);
+ OBJECT(zynq_machine->ps_clk));
object_unref(OBJECT(zynq_machine->ps_clk));
clock_set_hz(zynq_machine->ps_clk, PS_CLK_FREQUENCY);
qdev_connect_clock_in(slcr, "ps_clk", zynq_machine->ps_clk);
pic_irq = qdev_get_gpio_in(DEVICE(&s->soc.fpd.apu.gic), irq);
dev = qdev_create(NULL, "virtio-mmio");
- object_property_add_child(OBJECT(&s->soc), name, OBJECT(dev),
- &error_fatal);
+ object_property_add_child(OBJECT(&s->soc), name, OBJECT(dev));
qdev_init_nofail(dev);
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic_irq);
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
DeviceState *card;
card = qdev_create(qdev_get_child_bus(DEVICE(sd), "sd-bus"), TYPE_SD_CARD);
- object_property_add_child(OBJECT(sd), "card[*]", OBJECT(card),
- &error_fatal);
+ object_property_add_child(OBJECT(sd), "card[*]", OBJECT(card));
qdev_prop_set_drive(card, "drive", blk, &error_fatal);
object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
}
qdev_prop_set_string(dev, "name", name);
qdev_prop_set_uint64(dev, "size", size);
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
+ object_property_add_child(OBJECT(s), name, OBJECT(dev));
qdev_init_nofail(dev);
mr_dev = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
/* Default to secure mode being disabled */
s->secure = false;
object_property_add_bool(obj, "secure", zcu102_get_secure,
- zcu102_set_secure, NULL);
+ zcu102_set_secure);
object_property_set_description(obj, "secure",
"Set on/off to enable/disable the ARM "
- "Security Extensions (TrustZone)",
- NULL);
+ "Security Extensions (TrustZone)");
/* Default to virt (EL2) being disabled */
s->virt = false;
object_property_add_bool(obj, "virtualization", zcu102_get_virt,
- zcu102_set_virt, NULL);
+ zcu102_set_virt);
object_property_set_description(obj, "virtualization",
"Set on/off to enable/disable emulating a "
"guest CPU which implements the ARM "
- "Virtualization Extensions",
- NULL);
+ "Virtualization Extensions");
}
static void xlnx_zcu102_machine_class_init(ObjectClass *oc, void *data)
/* Alias controller SD bus to the SoC itself */
bus_name = g_strdup_printf("sd-bus%d", i);
- object_property_add_alias(OBJECT(s), bus_name, sdhci, "sd-bus",
- &error_abort);
+ object_property_add_alias(OBJECT(s), bus_name, sdhci, "sd-bus");
g_free(bus_name);
}
/* Alias controller SPI bus to the SoC itself */
bus_name = g_strdup_printf("spi%d", i);
object_property_add_alias(OBJECT(s), bus_name,
- OBJECT(&s->spi[i]), "spi0",
- &error_abort);
+ OBJECT(&s->spi[i]), "spi0");
g_free(bus_name);
}
bus_name = g_strdup_printf("qspi%d", i);
target_bus = g_strdup_printf("spi%d", i);
object_property_add_alias(OBJECT(s), bus_name,
- OBJECT(&s->qspi), target_bus,
- &error_abort);
+ OBJECT(&s->qspi), target_bus);
g_free(bus_name);
g_free(target_bus);
}
}
}
-static void hda_codec_dev_unrealize(DeviceState *qdev, Error **errp)
+static void hda_codec_dev_unrealize(DeviceState *qdev)
{
HDACodecDevice *dev = HDA_CODEC_DEVICE(qdev);
HDACodecDeviceClass *cdc = HDA_CODEC_DEVICE_GET_CLASS(dev);
object_property_add_link(OBJECT(dev), "wm8750", TYPE_WM8750,
(Object **) &s->wm,
qdev_prop_allow_set_link_before_realize,
- 0, &error_abort);
+ 0);
}
static void mv88w8618_audio_realize(DeviceState *dev, Error **errp)
object_property_add_link(obj, "pit", TYPE_PIT_COMMON,
(Object **)&s->pit,
qdev_prop_allow_set_link_before_realize,
- 0, &error_abort);
+ 0);
}
static void pcspk_realizefn(DeviceState *dev, Error **errp)
device_add_bootindex_property(obj, &isa->bootindexA,
"bootindexA", "/floppy@0",
- DEVICE(obj), NULL);
+ DEVICE(obj));
device_add_bootindex_property(obj, &isa->bootindexB,
"bootindexB", "/floppy@1",
- DEVICE(obj), NULL);
+ DEVICE(obj));
}
static const TypeInfo isa_fdc_info = {
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/namespace@1,0",
- DEVICE(obj), &error_abort);
+ DEVICE(obj));
}
static const TypeInfo nvme_info = {
DEFINE_PROP_END_OF_LIST(),
};
-static void pflash_cfi02_unrealize(DeviceState *dev, Error **errp)
+static void pflash_cfi02_unrealize(DeviceState *dev)
{
PFlashCFI02 *pfl = PFLASH_CFI02(dev);
timer_del(&pfl->timer);
vhost_user_cleanup(&s->vhost_user);
}
-static void vhost_user_blk_device_unrealize(DeviceState *dev, Error **errp)
+static void vhost_user_blk_device_unrealize(DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VHostUserBlk *s = VHOST_USER_BLK(dev);
VHostUserBlk *s = VHOST_USER_BLK(obj);
device_add_bootindex_property(obj, &s->bootindex, "bootindex",
- "/disk@0,0", DEVICE(obj), NULL);
+ "/disk@0,0", DEVICE(obj));
}
static const VMStateDescription vmstate_vhost_user_blk = {
conf->conf.lsecs);
}
-static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
+static void virtio_blk_device_unrealize(DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIOBlock *s = VIRTIO_BLK(dev);
device_add_bootindex_property(obj, &s->conf.conf.bootindex,
"bootindex", "/disk@0,0",
- DEVICE(obj), NULL);
+ DEVICE(obj));
}
static const VMStateDescription vmstate_virtio_blk = {
g_free(ring_ref);
}
-static void xen_block_unrealize(XenDevice *xendev, Error **errp)
+static void xen_block_unrealize(XenDevice *xendev)
{
XenBlockDevice *blockdev = XEN_BLOCK_DEVICE(xendev);
XenBlockDeviceClass *blockdev_class =
blockdev->dataplane = NULL;
if (blockdev_class->unrealize) {
- blockdev_class->unrealize(blockdev, errp);
+ blockdev_class->unrealize(blockdev);
}
}
.class_init = xen_block_class_init,
};
-static void xen_disk_unrealize(XenBlockDevice *blockdev, Error **errp)
+static void xen_disk_unrealize(XenBlockDevice *blockdev)
{
trace_xen_disk_unrealize();
}
.class_init = xen_disk_class_init,
};
-static void xen_cdrom_unrealize(XenBlockDevice *blockdev, Error **errp)
+static void xen_cdrom_unrealize(XenBlockDevice *blockdev)
{
trace_xen_cdrom_unrealize();
}
for (i = 0; i < pci->ports; i++) {
s = pci->state + i;
- object_property_set_bool(OBJECT(s), false, "realized", NULL);
+ object_property_set_bool(OBJECT(s), false, "realized", &error_abort);
memory_region_del_subregion(&pci->iobar, &s->io);
g_free(pci->name[i]);
}
PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
SerialState *s = &pci->state;
- object_property_set_bool(OBJECT(s), false, "realized", NULL);
+ object_property_set_bool(OBJECT(s), false, "realized", &error_abort);
qemu_free_irq(s->irq);
}
serial_reset(s);
}
-static void serial_unrealize(DeviceState *dev, Error **errp)
+static void serial_unrealize(DeviceState *dev)
{
SerialState *s = SERIAL(dev);
}
}
-static void virtconsole_unrealize(DeviceState *dev, Error **errp)
+static void virtconsole_unrealize(DeviceState *dev)
{
VirtConsole *vcon = VIRTIO_CONSOLE(dev);
virtio_notify_config(VIRTIO_DEVICE(hotplug_dev));
}
-static void virtser_port_device_unrealize(DeviceState *dev, Error **errp)
+static void virtser_port_device_unrealize(DeviceState *dev)
{
VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(dev);
QTAILQ_REMOVE(&vser->ports, port, next);
if (vsc->unrealize) {
- vsc->unrealize(dev, errp);
+ vsc->unrealize(dev);
}
}
.class_init = virtio_serial_port_class_init,
};
-static void virtio_serial_device_unrealize(DeviceState *dev, Error **errp)
+static void virtio_serial_device_unrealize(DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIOSerial *vser = VIRTIO_SERIAL(dev);
g_free(vser->post_load);
}
- qbus_set_hotplug_handler(BUS(&vser->bus), NULL, errp);
+ qbus_set_hotplug_handler(BUS(&vser->bus), NULL, &error_abort);
virtio_cleanup(vdev);
}
void qbus_set_hotplug_handler(BusState *bus, Object *handler, Error **errp)
{
- object_property_set_link(OBJECT(bus), OBJECT(handler),
+ object_property_set_link(OBJECT(bus), handler,
QDEV_HOTPLUG_HANDLER_PROPERTY, errp);
}
if (bus->parent) {
QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
bus->parent->num_child_bus++;
- object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
+ object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus));
object_unref(OBJECT(bus));
} else {
/* The only bus without a parent is the main system bus */
BusState *bus = BUS(obj);
BusClass *bc = BUS_GET_CLASS(bus);
BusChild *kid;
- Error *local_err = NULL;
if (value && !bus->realized) {
if (bc->realize) {
- bc->realize(bus, &local_err);
+ bc->realize(bus, errp);
}
/* TODO: recursive realization */
QTAILQ_FOREACH(kid, &bus->children, sibling) {
DeviceState *dev = kid->child;
object_property_set_bool(OBJECT(dev), false, "realized",
- &local_err);
- if (local_err != NULL) {
- break;
- }
+ &error_abort);
}
- if (bc->unrealize && local_err == NULL) {
- bc->unrealize(bus, &local_err);
+ if (bc->unrealize) {
+ bc->unrealize(bus);
}
}
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
-
bus->realized = value;
}
TYPE_HOTPLUG_HANDLER,
(Object **)&bus->hotplug_handler,
object_property_allow_set_link,
- 0,
- NULL);
+ 0);
object_property_add_bool(obj, "realized",
- bus_get_realized, bus_set_realized, NULL);
+ bus_get_realized, bus_set_realized);
}
static char *default_bus_get_fw_dev_path(DeviceState *dev)
trace_init_vcpu(cpu);
}
-static void cpu_common_unrealizefn(DeviceState *dev, Error **errp)
+static void cpu_common_unrealizefn(DeviceState *dev)
{
CPUState *cpu = CPU(dev);
/* NOTE: latest generic point before the cpu is fully unrealized */
}
}
-static void generic_loader_unrealize(DeviceState *dev, Error **errp)
+static void generic_loader_unrealize(DeviceState *dev)
{
qemu_unregister_reset(generic_loader_reset, dev);
}
#include "cpu.h"
#include "hw/boards.h"
#include "qapi/error.h"
+#include "qapi/qapi-builtin-visit.h"
#include "qapi/qapi-commands-machine.h"
#include "qapi/qmp/qerror.h"
+#include "qapi/qmp/qobject.h"
+#include "qapi/qobject-input-visitor.h"
#include "qemu/main-loop.h"
+#include "qom/qom-qobject.h"
#include "sysemu/hostmem.h"
#include "sysemu/hw_accel.h"
#include "sysemu/numa.h"
{
MemdevList **list = opaque;
MemdevList *m = NULL;
+ QObject *host_nodes;
+ Visitor *v;
if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) {
m = g_malloc0(sizeof(*m));
"policy",
"HostMemPolicy",
&error_abort);
- object_property_get_uint16List(obj, "host-nodes",
- &m->value->host_nodes,
- &error_abort);
+ host_nodes = object_property_get_qobject(obj,
+ "host-nodes",
+ &error_abort);
+ v = qobject_input_visitor_new(host_nodes);
+ visit_type_uint16List(v, NULL, &m->value->host_nodes, &error_abort);
+ visit_free(v);
+ qobject_unref(host_nodes);
m->next = *list;
*list = m;
mc->numa_auto_assign_ram = numa_default_auto_assign_ram;
object_class_property_add_str(oc, "kernel",
- machine_get_kernel, machine_set_kernel, &error_abort);
+ machine_get_kernel, machine_set_kernel);
object_class_property_set_description(oc, "kernel",
- "Linux kernel image file", &error_abort);
+ "Linux kernel image file");
object_class_property_add_str(oc, "initrd",
- machine_get_initrd, machine_set_initrd, &error_abort);
+ machine_get_initrd, machine_set_initrd);
object_class_property_set_description(oc, "initrd",
- "Linux initial ramdisk file", &error_abort);
+ "Linux initial ramdisk file");
object_class_property_add_str(oc, "append",
- machine_get_append, machine_set_append, &error_abort);
+ machine_get_append, machine_set_append);
object_class_property_set_description(oc, "append",
- "Linux kernel command line", &error_abort);
+ "Linux kernel command line");
object_class_property_add_str(oc, "dtb",
- machine_get_dtb, machine_set_dtb, &error_abort);
+ machine_get_dtb, machine_set_dtb);
object_class_property_set_description(oc, "dtb",
- "Linux kernel device tree file", &error_abort);
+ "Linux kernel device tree file");
object_class_property_add_str(oc, "dumpdtb",
- machine_get_dumpdtb, machine_set_dumpdtb, &error_abort);
+ machine_get_dumpdtb, machine_set_dumpdtb);
object_class_property_set_description(oc, "dumpdtb",
- "Dump current dtb to a file and quit", &error_abort);
+ "Dump current dtb to a file and quit");
object_class_property_add(oc, "phandle-start", "int",
machine_get_phandle_start, machine_set_phandle_start,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_set_description(oc, "phandle-start",
- "The first phandle ID we may generate dynamically", &error_abort);
+ "The first phandle ID we may generate dynamically");
object_class_property_add_str(oc, "dt-compatible",
- machine_get_dt_compatible, machine_set_dt_compatible, &error_abort);
+ machine_get_dt_compatible, machine_set_dt_compatible);
object_class_property_set_description(oc, "dt-compatible",
- "Overrides the \"compatible\" property of the dt root node",
- &error_abort);
+ "Overrides the \"compatible\" property of the dt root node");
object_class_property_add_bool(oc, "dump-guest-core",
- machine_get_dump_guest_core, machine_set_dump_guest_core, &error_abort);
+ machine_get_dump_guest_core, machine_set_dump_guest_core);
object_class_property_set_description(oc, "dump-guest-core",
- "Include guest memory in a core dump", &error_abort);
+ "Include guest memory in a core dump");
object_class_property_add_bool(oc, "mem-merge",
- machine_get_mem_merge, machine_set_mem_merge, &error_abort);
+ machine_get_mem_merge, machine_set_mem_merge);
object_class_property_set_description(oc, "mem-merge",
- "Enable/disable memory merge support", &error_abort);
+ "Enable/disable memory merge support");
object_class_property_add_bool(oc, "usb",
- machine_get_usb, machine_set_usb, &error_abort);
+ machine_get_usb, machine_set_usb);
object_class_property_set_description(oc, "usb",
- "Set on/off to enable/disable usb", &error_abort);
+ "Set on/off to enable/disable usb");
object_class_property_add_bool(oc, "graphics",
- machine_get_graphics, machine_set_graphics, &error_abort);
+ machine_get_graphics, machine_set_graphics);
object_class_property_set_description(oc, "graphics",
- "Set on/off to enable/disable graphics emulation", &error_abort);
+ "Set on/off to enable/disable graphics emulation");
object_class_property_add_str(oc, "firmware",
- machine_get_firmware, machine_set_firmware,
- &error_abort);
+ machine_get_firmware, machine_set_firmware);
object_class_property_set_description(oc, "firmware",
- "Firmware image", &error_abort);
+ "Firmware image");
object_class_property_add_bool(oc, "suppress-vmdesc",
- machine_get_suppress_vmdesc, machine_set_suppress_vmdesc,
- &error_abort);
+ machine_get_suppress_vmdesc, machine_set_suppress_vmdesc);
object_class_property_set_description(oc, "suppress-vmdesc",
- "Set on to disable self-describing migration", &error_abort);
+ "Set on to disable self-describing migration");
object_class_property_add_bool(oc, "enforce-config-section",
- machine_get_enforce_config_section, machine_set_enforce_config_section,
- &error_abort);
+ machine_get_enforce_config_section, machine_set_enforce_config_section);
object_class_property_set_description(oc, "enforce-config-section",
- "Set on to enforce configuration section migration", &error_abort);
+ "Set on to enforce configuration section migration");
object_class_property_add_str(oc, "memory-encryption",
- machine_get_memory_encryption, machine_set_memory_encryption,
- &error_abort);
+ machine_get_memory_encryption, machine_set_memory_encryption);
object_class_property_set_description(oc, "memory-encryption",
- "Set memory encryption object to use", &error_abort);
+ "Set memory encryption object to use");
}
static void machine_class_base_init(ObjectClass *oc, void *data)
ms->nvdimms_state = g_new0(NVDIMMState, 1);
object_property_add_bool(obj, "nvdimm",
- machine_get_nvdimm, machine_set_nvdimm,
- &error_abort);
+ machine_get_nvdimm, machine_set_nvdimm);
object_property_set_description(obj, "nvdimm",
"Set on/off to enable/disable "
- "NVDIMM instantiation", NULL);
+ "NVDIMM instantiation");
object_property_add_str(obj, "nvdimm-persistence",
machine_get_nvdimm_persistence,
- machine_set_nvdimm_persistence,
- &error_abort);
+ machine_set_nvdimm_persistence);
object_property_set_description(obj, "nvdimm-persistence",
"Set NVDIMM persistence"
- "Valid values are cpu, mem-ctrl",
- NULL);
+ "Valid values are cpu, mem-ctrl");
}
if (mc->cpu_index_to_instance_props && mc->get_default_cpu_node_id) {
ms->numa_state = g_new0(NumaState, 1);
object_property_add_bool(obj, "hmat",
- machine_get_hmat, machine_set_hmat,
- &error_abort);
+ machine_get_hmat, machine_set_hmat);
object_property_set_description(obj, "hmat",
"Set on/off to enable/disable "
"ACPI Heterogeneous Memory Attribute "
- "Table (HMAT)", NULL);
+ "Table (HMAT)");
}
object_property_add_str(obj, "memory-backend",
- machine_get_memdev, machine_set_memdev,
- &error_abort);
+ machine_get_memdev, machine_set_memdev);
object_property_set_description(obj, "memory-backend",
"Set RAM backend"
- "Valid value is ID of hostmem based backend",
- &error_abort);
+ "Valid value is ID of hostmem based backend");
/* Register notifier when init is done for sysbus sanity checks */
ms->sysbus_notifier.notify = machine_init_notify;
*/
if (clk == NULL) {
clk = CLOCK(object_new(TYPE_CLOCK));
- object_property_add_child(OBJECT(dev), name, OBJECT(clk), &error_abort);
+ object_property_add_child(OBJECT(dev), name, OBJECT(clk));
if (output) {
/*
* Remove object_new()'s initial reference.
object_property_add_link(OBJECT(dev), name,
object_get_typename(OBJECT(clk)),
(Object **) &ncl->clock,
- NULL, OBJ_PROP_LINK_STRONG, &error_abort);
+ NULL, OBJ_PROP_LINK_STRONG);
}
ncl->clock = clk;
arrayprop->prop.info->get,
arrayprop->prop.info->set,
array_element_release,
- arrayprop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
+ arrayprop);
}
}
/* --- object link property --- */
-static void create_link_property(ObjectClass *oc, Property *prop, Error **errp)
+static void create_link_property(ObjectClass *oc, Property *prop)
{
object_class_property_add_link(oc, prop->name, prop->link_type,
prop->offset,
qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_STRONG,
- errp);
+ OBJ_PROP_LINK_STRONG);
}
const PropertyInfo qdev_prop_link = {
bus->num_children--;
/* This gives back ownership of kid->child back to us. */
- object_property_del(OBJECT(bus), name, NULL);
+ object_property_del(OBJECT(bus), name);
object_unref(OBJECT(kid->child));
g_free(kid);
return;
object_get_typename(OBJECT(child)),
(Object **)&kid->child,
NULL, /* read-only property */
- 0, /* return ownership on prop deletion */
- NULL);
+ 0);
}
void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
- object_property_set_bool(OBJECT(dev), false, "realized", NULL);
+ object_property_set_bool(OBJECT(dev), false, "realized", &error_abort);
}
/*
gchar *propname = g_strdup_printf("%s[%u]", name, i);
object_property_add_child(OBJECT(dev), propname,
- OBJECT(gpio_list->in[i]), &error_abort);
+ OBJECT(gpio_list->in[i]));
g_free(propname);
}
object_property_add_link(OBJECT(dev), propname, TYPE_IRQ,
(Object **)&pins[i],
object_property_allow_set_link,
- OBJ_PROP_LINK_STRONG,
- &error_abort);
+ OBJ_PROP_LINK_STRONG);
g_free(propname);
}
gpio_list->num_out += n;
{
char *propname = g_strdup_printf("%s[%d]",
name ? name : "unnamed-gpio-out", n);
- if (pin) {
- /* We need a name for object_property_set_link to work. If the
- * object has a parent, object_property_add_child will come back
- * with an error without doing anything. If it has none, it will
- * never fail. So we can just call it with a NULL Error pointer.
- */
+ if (pin && !OBJECT(pin)->parent) {
+ /* We need a name for object_property_set_link to work */
object_property_add_child(container_get(qdev_get_machine(),
"/unattached"),
- "non-qdev-gpio[*]", OBJECT(pin), NULL);
+ "non-qdev-gpio[*]", OBJECT(pin));
}
object_property_set_link(OBJECT(dev), OBJECT(pin), propname, &error_abort);
g_free(propname);
char *propname = g_strdup_printf("%s[%d]", nm, i);
object_property_add_alias(OBJECT(container), propname,
- OBJECT(dev), propname,
- &error_abort);
+ OBJECT(dev), propname);
g_free(propname);
}
for (i = 0; i < ngl->num_out; i++) {
char *propname = g_strdup_printf("%s[%d]", nm, i);
object_property_add_alias(OBJECT(container), propname,
- OBJECT(dev), propname,
- &error_abort);
+ OBJECT(dev), propname);
g_free(propname);
}
QLIST_REMOVE(ngl, node);
name = g_strdup_printf("legacy-%s", prop->name);
object_class_property_add(OBJECT_CLASS(dc), name, "str",
prop->info->print ? qdev_get_legacy_property : prop->info->get,
- NULL, NULL, prop, &error_abort);
+ NULL, NULL, prop);
}
void qdev_property_add_static(DeviceState *dev, Property *prop)
op = object_property_add(obj, prop->name, prop->info->name,
prop->info->get, prop->info->set,
prop->info->release,
- prop, &error_abort);
+ prop);
object_property_set_description(obj, prop->name,
- prop->info->description,
- &error_abort);
+ prop->info->description);
if (prop->set_default) {
prop->info->set_default_value(op, prop);
ObjectClass *oc = OBJECT_CLASS(klass);
if (prop->info->create) {
- prop->info->create(oc, prop, &error_abort);
+ prop->info->create(oc, prop);
} else {
ObjectProperty *op;
prop->name, prop->info->name,
prop->info->get, prop->info->set,
prop->info->release,
- prop, &error_abort);
+ prop);
if (prop->set_default) {
prop->info->set_default_value(op, prop);
}
}
object_class_property_set_description(oc, prop->name,
- prop->info->description,
- &error_abort);
+ prop->info->description);
}
/* @qdev_alias_all_properties - Add alias properties to the source object for
for (prop = dc->props_; prop && prop->name; prop++) {
object_property_add_alias(source, prop->name,
- OBJECT(target), prop->name,
- &error_abort);
+ OBJECT(target), prop->name);
}
class = object_class_get_parent(class);
} while (class != object_class_by_name(TYPE_DEVICE));
object_property_add_child(container_get(qdev_get_machine(),
"/unattached"),
- name, obj, &error_abort);
+ name, obj);
unattached_parent = true;
g_free(name);
}
}
} else if (!value && dev->realized) {
- /* We want local_err to track only the first error */
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
object_property_set_bool(OBJECT(bus), false, "realized",
- local_err ? NULL : &local_err);
+ &error_abort);
}
if (qdev_get_vmsd(dev)) {
vmstate_unregister(VMSTATE_IF(dev), qdev_get_vmsd(dev), dev);
}
if (dc->unrealize) {
- dc->unrealize(dev, local_err ? NULL : &local_err);
+ dc->unrealize(dev);
}
dev->pending_deleted_event = true;
DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
-
- if (local_err != NULL) {
- goto fail;
- }
}
assert(local_err == NULL);
child_realize_fail:
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
object_property_set_bool(OBJECT(bus), false, "realized",
- NULL);
+ &error_abort);
}
if (qdev_get_vmsd(dev)) {
g_free(dev->canonical_path);
dev->canonical_path = NULL;
if (dc->unrealize) {
- dc->unrealize(dev, NULL);
+ dc->unrealize(dev);
}
fail:
BusState *bus;
if (dev->realized) {
- object_property_set_bool(obj, false, "realized", NULL);
+ object_property_set_bool(obj, false, "realized", &error_abort);
}
while (dev->num_child_bus) {
bus = QLIST_FIRST(&dev->child_bus);
rc->get_transitional_function = device_get_transitional_reset;
object_class_property_add_bool(class, "realized",
- device_get_realized, device_set_realized,
- &error_abort);
+ device_get_realized, device_set_realized);
object_class_property_add_bool(class, "hotpluggable",
- device_get_hotpluggable, NULL,
- &error_abort);
+ device_get_hotpluggable, NULL);
object_class_property_add_bool(class, "hotplugged",
- device_get_hotplugged, NULL,
- &error_abort);
+ device_get_hotplugged, NULL);
object_class_property_add_link(class, "parent_bus", TYPE_BUS,
- offsetof(DeviceState, parent_bus), NULL, 0,
- &error_abort);
+ offsetof(DeviceState, parent_bus), NULL, 0);
}
void device_class_set_props(DeviceClass *dc, Property *props)
#include "qemu/module.h"
size_t
-stream_push(StreamSlave *sink, uint8_t *buf, size_t len)
+stream_push(StreamSlave *sink, uint8_t *buf, size_t len, bool eop)
{
StreamSlaveClass *k = STREAM_SLAVE_GET_CLASS(sink);
- return k->push(sink, buf, len);
+ return k->push(sink, buf, len, eop);
}
bool
CPUCore *core = CPU_CORE(obj);
object_property_add(obj, "core-id", "int", core_prop_get_core_id,
- core_prop_set_core_id, NULL, NULL, NULL);
+ core_prop_set_core_id, NULL, NULL);
object_property_add(obj, "nr-threads", "int", core_prop_get_nr_threads,
- core_prop_set_nr_threads, NULL, NULL, NULL);
+ core_prop_set_nr_threads, NULL, NULL);
core->nr_threads = ms->smp.threads;
}
s->cursor_height = 32;
s->cursor_width = 32;
- s->con = graphic_console_init(DEVICE(dev), 0, &artist_ops, s);
+ s->con = graphic_console_init(dev, 0, &artist_ops, s);
qemu_console_resize(s->con, s->width, s->height);
}
/* Expose framebuffer byteorder via QOM */
object_property_add_bool(obj, "big-endian-framebuffer",
bochs_display_get_big_endian_fb,
- bochs_display_set_big_endian_fb,
- NULL);
+ bochs_display_set_big_endian_fb);
dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
}
sysbus_init_irq(sbd, &s->irq);
- s->con = graphic_console_init(DEVICE(dev), 0, &cg3_ops, s);
+ s->con = graphic_console_init(dev, 0, &cg3_ops, s);
qemu_console_resize(s->con, s->width, s->height);
}
&s->twoD_engine_region);
/* create qemu graphic console */
- s->con = graphic_console_init(DEVICE(dev), 0, &sm501_ops, s);
+ s->con = graphic_console_init(dev, 0, &sm501_ops, s);
}
static const VMStateDescription vmstate_sm501_state = {
qdev_prop_set_uint8(DEVICE(smm), "endianness", DEVICE_LITTLE_ENDIAN);
object_property_add_alias(o, "chardev",
- OBJECT(smm), "chardev", &error_abort);
+ OBJECT(smm), "chardev");
}
static const TypeInfo sm501_sysbus_info = {
sysbus_init_irq(sbd, &s->irq);
if (s->depth == 8) {
- s->con = graphic_console_init(DEVICE(dev), 0, &tcx_ops, s);
+ s->con = graphic_console_init(dev, 0, &tcx_ops, s);
} else {
- s->con = graphic_console_init(DEVICE(dev), 0, &tcx24_ops, s);
+ s->con = graphic_console_init(dev, 0, &tcx24_ops, s);
}
s->thcmisc = 0;
0x000a0000,
vga_io_memory, 1);
memory_region_set_coalescing(vga_io_memory);
- s->con = graphic_console_init(DEVICE(dev), 0, s->hw_ops, s);
+ s->con = graphic_console_init(dev, 0, s->hw_ops, s);
memory_region_add_subregion(isa_address_space(isadev),
VBE_DISPI_LFB_PHYSICAL_ADDRESS,
{
/* Expose framebuffer byteorder via QOM */
object_property_add_bool(obj, "big-endian-framebuffer",
- vga_get_big_endian_fb, vga_set_big_endian_fb, NULL);
+ vga_get_big_endian_fb, vga_set_big_endian_fb);
}
static void pci_secondary_vga_realize(PCIDevice *dev, Error **errp)
{
/* Expose framebuffer byteorder via QOM */
object_property_add_bool(obj, "big-endian-framebuffer",
- vga_get_big_endian_fb, vga_set_big_endian_fb, NULL);
+ vga_get_big_endian_fb, vga_set_big_endian_fb);
}
static void pci_secondary_vga_reset(DeviceState *dev)
VIRTIO_GPU_PCI_BASE(obj)->vgpu = VIRTIO_GPU_BASE(&dev->vdev);
object_property_add_alias(obj, "chardev",
- OBJECT(&dev->vdev), "chardev",
- &error_abort);
+ OBJECT(&dev->vdev), "chardev");
}
static const VirtioPCIDeviceTypeInfo vhost_user_gpu_pci_info = {
g->vhost = VHOST_USER_BACKEND(object_new(TYPE_VHOST_USER_BACKEND));
object_property_add_alias(obj, "chardev",
- OBJECT(g->vhost), "chardev", &error_abort);
+ OBJECT(g->vhost), "chardev");
}
static void
VIRTIO_VGA_BASE(dev)->vgpu = VIRTIO_GPU_BASE(&dev->vdev);
object_property_add_alias(obj, "chardev",
- OBJECT(&dev->vdev), "chardev",
- &error_abort);
+ OBJECT(&dev->vdev), "chardev");
}
static const VirtioPCIDeviceTypeInfo vhost_user_vga_info = {
}
static void
-virtio_gpu_base_device_unrealize(DeviceState *qdev, Error **errp)
+virtio_gpu_base_device_unrealize(DeviceState *qdev)
{
VirtIOGPUBase *g = VIRTIO_GPU_BASE(qdev);
object_property_add_link(obj, "dpdma", TYPE_XLNX_DPDMA,
(Object **) &s->dpdma,
xlnx_dp_set_dpdma,
- OBJ_PROP_LINK_STRONG,
- &error_abort);
+ OBJ_PROP_LINK_STRONG);
/*
* Initialize AUX Bus.
* Initialize DPCD and EDID..
*/
s->dpcd = DPCD(aux_create_slave(s->aux_bus, "dpcd"));
- object_property_add_child(OBJECT(s), "dpcd", OBJECT(s->dpcd), NULL);
+ object_property_add_child(OBJECT(s), "dpcd", OBJECT(s->dpcd));
s->edid = I2CDDC(qdev_create(BUS(aux_get_i2c_bus(s->aux_bus)), "i2c-ddc"));
i2c_set_slave_address(I2C_SLAVE(s->edid), 0x50);
- object_property_add_child(OBJECT(s), "edid", OBJECT(s->edid), NULL);
+ object_property_add_child(OBJECT(s), "edid", OBJECT(s->edid));
fifo8_create(&s->rx_fifo, 16);
fifo8_create(&s->tx_fifo, 16);
address_space_init(&s->dma_as, MEMORY_REGION(&s->dma_mr), "rc4030-dma");
}
-static void rc4030_unrealize(DeviceState *dev, Error **errp)
+static void rc4030_unrealize(DeviceState *dev)
{
rc4030State *s = RC4030(dev);
object_property_add_link(OBJECT(dev), "iommu", TYPE_SUN4M_IOMMU,
(Object **) &s->iommu,
qdev_prop_allow_set_link_before_realize,
- 0, NULL);
+ 0);
qdev_init_gpio_in(dev, dma_set_irq, 1);
qdev_init_gpio_out(dev, s->gpio, 2);
ESPState *esp;
d = qdev_create(NULL, TYPE_ESP);
- object_property_add_child(OBJECT(dev), "esp", OBJECT(d), errp);
+ object_property_add_child(OBJECT(dev), "esp", OBJECT(d));
sysbus = ESP_STATE(d);
esp = &sysbus->esp;
esp->dma_memory_read = espdma_memory_read;
qemu_check_nic_model(nd, TYPE_LANCE);
d = qdev_create(NULL, TYPE_LANCE);
- object_property_add_child(OBJECT(dev), "lance", OBJECT(d), errp);
+ object_property_add_child(OBJECT(dev), "lance", OBJECT(d));
qdev_set_nic_properties(d, nd);
object_property_set_link(OBJECT(d), OBJECT(dev), "dma", errp);
qdev_init_nofail(d);
espdma = qdev_create(NULL, TYPE_SPARC32_ESPDMA_DEVICE);
object_property_set_link(OBJECT(espdma), iommu, "iommu", errp);
- object_property_add_child(OBJECT(s), "espdma", OBJECT(espdma), errp);
+ object_property_add_child(OBJECT(s), "espdma", OBJECT(espdma));
qdev_init_nofail(espdma);
esp = DEVICE(object_resolve_path_component(OBJECT(espdma), "esp"));
ledma = qdev_create(NULL, TYPE_SPARC32_LEDMA_DEVICE);
object_property_set_link(OBJECT(ledma), iommu, "iommu", errp);
- object_property_add_child(OBJECT(s), "ledma", OBJECT(ledma), errp);
+ object_property_add_child(OBJECT(s), "ledma", OBJECT(ledma));
qdev_init_nofail(ledma);
lance = DEVICE(object_resolve_path_component(OBJECT(ledma), "lance"));
#include "qemu/log.h"
#include "qemu/module.h"
+#include "sysemu/dma.h"
#include "hw/stream.h"
#define D(x)
};
struct Stream {
+ struct XilinxAXIDMA *dma;
ptimer_state *ptimer;
qemu_irq irq;
int nr;
+ bool sof;
struct SDesc desc;
- int pos;
unsigned int complete_cnt;
uint32_t regs[R_MAX];
uint8_t app[20];
struct XilinxAXIDMA {
SysBusDevice busdev;
MemoryRegion iomem;
+ MemoryRegion *dma_mr;
+ AddressSpace as;
+
uint32_t freqhz;
StreamSlave *tx_data_dev;
StreamSlave *tx_control_dev;
{
s->regs[R_DMASR] = DMASR_HALTED; /* starts up halted. */
s->regs[R_DMACR] = 1 << 16; /* Starts with one in compl threshold. */
+ s->sof = true;
}
/* Map an offset addr into a channel index. */
{
struct SDesc *d = &s->desc;
- cpu_physical_memory_read(addr, d, sizeof *d);
+ address_space_read(&s->dma->as, addr, MEMTXATTRS_UNSPECIFIED, d, sizeof *d);
/* Convert from LE into host endianness. */
d->buffer_address = le64_to_cpu(d->buffer_address);
d->nxtdesc = cpu_to_le64(d->nxtdesc);
d->control = cpu_to_le32(d->control);
d->status = cpu_to_le32(d->status);
- cpu_physical_memory_write(addr, d, sizeof *d);
+ address_space_write(&s->dma->as, addr, MEMTXATTRS_UNSPECIFIED,
+ d, sizeof *d);
}
static void stream_update_irq(struct Stream *s)
StreamSlave *tx_control_dev)
{
uint32_t prev_d;
- unsigned int txlen;
+ uint32_t txlen;
+ uint64_t addr;
+ bool eop;
if (!stream_running(s) || stream_idle(s)) {
return;
}
if (stream_desc_sof(&s->desc)) {
- s->pos = 0;
- stream_push(tx_control_dev, s->desc.app, sizeof(s->desc.app));
+ stream_push(tx_control_dev, s->desc.app, sizeof(s->desc.app), true);
}
txlen = s->desc.control & SDESC_CTRL_LEN_MASK;
- if ((txlen + s->pos) > sizeof s->txbuf) {
- hw_error("%s: too small internal txbuf! %d\n", __func__,
- txlen + s->pos);
- }
- cpu_physical_memory_read(s->desc.buffer_address,
- s->txbuf + s->pos, txlen);
- s->pos += txlen;
+ eop = stream_desc_eof(&s->desc);
+ addr = s->desc.buffer_address;
+ while (txlen) {
+ unsigned int len;
+
+ len = txlen > sizeof s->txbuf ? sizeof s->txbuf : txlen;
+ address_space_read(&s->dma->as, addr,
+ MEMTXATTRS_UNSPECIFIED,
+ s->txbuf, len);
+ stream_push(tx_data_dev, s->txbuf, len, eop && len == txlen);
+ txlen -= len;
+ addr += len;
+ }
- if (stream_desc_eof(&s->desc)) {
- stream_push(tx_data_dev, s->txbuf, s->pos);
- s->pos = 0;
+ if (eop) {
stream_complete(s);
}
}
static size_t stream_process_s2mem(struct Stream *s, unsigned char *buf,
- size_t len)
+ size_t len, bool eop)
{
uint32_t prev_d;
unsigned int rxlen;
size_t pos = 0;
- int sof = 1;
if (!stream_running(s) || stream_idle(s)) {
return 0;
rxlen = len;
}
- cpu_physical_memory_write(s->desc.buffer_address, buf + pos, rxlen);
+ address_space_write(&s->dma->as, s->desc.buffer_address,
+ MEMTXATTRS_UNSPECIFIED, buf + pos, rxlen);
len -= rxlen;
pos += rxlen;
/* Update the descriptor. */
- if (!len) {
+ if (eop) {
stream_complete(s);
memcpy(s->desc.app, s->app, sizeof(s->desc.app));
s->desc.status |= SDESC_STATUS_EOF;
}
- s->desc.status |= sof << SDESC_STATUS_SOF_BIT;
+ s->desc.status |= s->sof << SDESC_STATUS_SOF_BIT;
s->desc.status |= SDESC_STATUS_COMPLETE;
stream_desc_store(s, s->regs[R_CURDESC]);
- sof = 0;
+ s->sof = eop;
/* Advance. */
prev_d = s->regs[R_CURDESC];
static size_t
xilinx_axidma_control_stream_push(StreamSlave *obj, unsigned char *buf,
- size_t len)
+ size_t len, bool eop)
{
XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM(obj);
struct Stream *s = &cs->dma->streams[1];
}
static size_t
-xilinx_axidma_data_stream_push(StreamSlave *obj, unsigned char *buf, size_t len)
+xilinx_axidma_data_stream_push(StreamSlave *obj, unsigned char *buf, size_t len,
+ bool eop)
{
XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(obj);
struct Stream *s = &ds->dma->streams[1];
size_t ret;
- ret = stream_process_s2mem(s, buf, len);
+ ret = stream_process_s2mem(s, buf, len, eop);
stream_update_irq(s);
return ret;
}
XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM(
&s->rx_control_dev);
Error *local_err = NULL;
+ int i;
object_property_add_link(OBJECT(ds), "dma", TYPE_XILINX_AXI_DMA,
(Object **)&ds->dma,
object_property_allow_set_link,
- OBJ_PROP_LINK_STRONG,
- &local_err);
+ OBJ_PROP_LINK_STRONG);
object_property_add_link(OBJECT(cs), "dma", TYPE_XILINX_AXI_DMA,
(Object **)&cs->dma,
object_property_allow_set_link,
- OBJ_PROP_LINK_STRONG,
- &local_err);
- if (local_err) {
- goto xilinx_axidma_realize_fail;
- }
+ OBJ_PROP_LINK_STRONG);
object_property_set_link(OBJECT(ds), OBJECT(s), "dma", &local_err);
object_property_set_link(OBJECT(cs), OBJECT(s), "dma", &local_err);
if (local_err) {
goto xilinx_axidma_realize_fail;
}
- int i;
-
for (i = 0; i < 2; i++) {
struct Stream *st = &s->streams[i];
+ st->dma = s;
st->nr = i;
st->ptimer = ptimer_init(timer_hit, st, PTIMER_POLICY_DEFAULT);
ptimer_transaction_begin(st->ptimer);
ptimer_set_freq(st->ptimer, s->freqhz);
ptimer_transaction_commit(st->ptimer);
}
+
+ address_space_init(&s->as,
+ s->dma_mr ? s->dma_mr : get_system_memory(), "dma");
return;
xilinx_axidma_realize_fail:
&s->rx_control_dev, sizeof(s->rx_control_dev),
TYPE_XILINX_AXI_DMA_CONTROL_STREAM, &error_abort,
NULL);
+ object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
+ (Object **)&s->dma_mr,
+ qdev_prop_allow_set_link_before_realize,
+ OBJ_PROP_LINK_STRONG);
sysbus_init_irq(sbd, &s->streams[0].irq);
sysbus_init_irq(sbd, &s->streams[1].irq);
RegisterInfo *r = &s->regs_info[addr / 4];
if (!r->data) {
- gchar *path = object_get_canonical_path(OBJECT(s));
+ char *path = object_get_canonical_path(OBJECT(s));
qemu_log("%s: Decode error: read from %" HWADDR_PRIx "\n",
path,
addr);
RegisterInfo *r = &s->regs_info[addr / 4];
if (!r->data) {
- gchar *path = object_get_canonical_path(OBJECT(s));
+ char *path = object_get_canonical_path(OBJECT(s));
qemu_log("%s: Decode error: write to %" HWADDR_PRIx "=%" PRIx64 "\n",
path,
addr, value);
object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
(Object **)&s->dma_mr,
qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_STRONG,
- &error_abort);
+ OBJ_PROP_LINK_STRONG);
}
static const VMStateDescription vmstate_zdma = {
name = g_strdup_printf("gpio%s%d", props->group_label[group_idx],
pin_idx % GPIOS_PER_GROUP);
object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
- aspeed_gpio_set_pin, NULL, NULL, NULL);
+ aspeed_gpio_set_pin, NULL, NULL);
g_free(name);
}
}
obj = object_new(TYPE_SYNIC);
synic = SYNIC(obj);
synic->cs = cs;
- object_property_add_child(OBJECT(cs), "synic", obj, &error_abort);
+ object_property_add_child(OBJECT(cs), "synic", obj);
object_unref(obj);
object_property_set_bool(obj, true, "realized", &error_abort);
}
IMX_I2C_MEM_SIZE);
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
- s->bus = i2c_init_bus(DEVICE(dev), NULL);
+ s->bus = i2c_init_bus(dev, NULL);
}
static void imx_i2c_class_init(ObjectClass *klass, void *data)
memory_region_init_io(&i2c->iomem, OBJECT(i2c), &i2c_ops, i2c,
"mpc-i2c", 0x14);
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &i2c->iomem);
- i2c->bus = i2c_init_bus(DEVICE(dev), "i2c");
+ i2c->bus = i2c_init_bus(dev, "i2c");
}
static void mpc_i2c_class_init(ObjectClass *klass, void *data)
}
}
-static void kvm_apic_unrealize(DeviceState *dev, Error **errp)
+static void kvm_apic_unrealize(DeviceState *dev)
{
}
object_class_property_add(oc, MICROVM_MACHINE_PIC, "OnOffAuto",
microvm_machine_get_pic,
microvm_machine_set_pic,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_set_description(oc, MICROVM_MACHINE_PIC,
- "Enable i8259 PIC", &error_abort);
+ "Enable i8259 PIC");
object_class_property_add(oc, MICROVM_MACHINE_PIT, "OnOffAuto",
microvm_machine_get_pit,
microvm_machine_set_pit,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_set_description(oc, MICROVM_MACHINE_PIT,
- "Enable i8254 PIT", &error_abort);
+ "Enable i8254 PIT");
object_class_property_add(oc, MICROVM_MACHINE_RTC, "OnOffAuto",
microvm_machine_get_rtc,
microvm_machine_set_rtc,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_set_description(oc, MICROVM_MACHINE_RTC,
- "Enable MC146818 RTC", &error_abort);
+ "Enable MC146818 RTC");
object_class_property_add_bool(oc, MICROVM_MACHINE_ISA_SERIAL,
microvm_machine_get_isa_serial,
- microvm_machine_set_isa_serial,
- &error_abort);
+ microvm_machine_set_isa_serial);
object_class_property_set_description(oc, MICROVM_MACHINE_ISA_SERIAL,
- "Set off to disable the instantiation an ISA serial port",
- &error_abort);
+ "Set off to disable the instantiation an ISA serial port");
object_class_property_add_bool(oc, MICROVM_MACHINE_OPTION_ROMS,
microvm_machine_get_option_roms,
- microvm_machine_set_option_roms,
- &error_abort);
+ microvm_machine_set_option_roms);
object_class_property_set_description(oc, MICROVM_MACHINE_OPTION_ROMS,
- "Set off to disable loading option ROMs", &error_abort);
+ "Set off to disable loading option ROMs");
object_class_property_add_bool(oc, MICROVM_MACHINE_AUTO_KERNEL_CMDLINE,
microvm_machine_get_auto_kernel_cmdline,
- microvm_machine_set_auto_kernel_cmdline,
- &error_abort);
+ microvm_machine_set_auto_kernel_cmdline);
object_class_property_set_description(oc,
MICROVM_MACHINE_AUTO_KERNEL_CMDLINE,
- "Set off to disable adding virtio-mmio devices to the kernel cmdline",
- &error_abort);
+ "Set off to disable adding virtio-mmio devices to the kernel cmdline");
}
static const TypeInfo microvm_machine_info = {
TYPE_ISA_DEVICE,
(Object **)&x86ms->rtc,
object_property_allow_set_link,
- OBJ_PROP_LINK_STRONG, &error_abort);
+ OBJ_PROP_LINK_STRONG);
object_property_set_link(OBJECT(pcms), OBJECT(s),
"rtc_state", &error_abort);
}
pc_dimm_unplug(PC_DIMM(dev), MACHINE(pcms));
- object_property_set_bool(OBJECT(dev), false, "realized", NULL);
+ object_property_set_bool(OBJECT(dev), false, "realized", &error_abort);
out:
error_propagate(errp, local_err);
}
found_cpu = pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, NULL);
found_cpu->cpu = NULL;
- object_property_set_bool(OBJECT(dev), false, "realized", NULL);
+ object_property_set_bool(OBJECT(dev), false, "realized", &error_abort);
/* decrement the number of CPUs */
x86ms->boot_cpus--;
object_class_property_add(oc, PC_MACHINE_DEVMEM_REGION_SIZE, "int",
pc_machine_get_device_memory_region_size, NULL,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_add(oc, PC_MACHINE_VMPORT, "OnOffAuto",
pc_machine_get_vmport, pc_machine_set_vmport,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_set_description(oc, PC_MACHINE_VMPORT,
- "Enable vmport (pc & q35)", &error_abort);
+ "Enable vmport (pc & q35)");
object_class_property_add_bool(oc, PC_MACHINE_SMBUS,
- pc_machine_get_smbus, pc_machine_set_smbus, &error_abort);
+ pc_machine_get_smbus, pc_machine_set_smbus);
object_class_property_add_bool(oc, PC_MACHINE_SATA,
- pc_machine_get_sata, pc_machine_set_sata, &error_abort);
+ pc_machine_get_sata, pc_machine_set_sata);
object_class_property_add_bool(oc, PC_MACHINE_PIT,
- pc_machine_get_pit, pc_machine_set_pit, &error_abort);
+ pc_machine_get_pit, pc_machine_set_pit);
}
static const TypeInfo pc_machine_info = {
TYPE_HOTPLUG_HANDLER,
(Object **)&pcms->acpi_dev,
object_property_allow_set_link,
- OBJ_PROP_LINK_STRONG, &error_abort);
+ OBJ_PROP_LINK_STRONG);
object_property_set_link(OBJECT(machine), OBJECT(piix4_pm),
PC_MACHINE_ACPI_DEVICE_PROP, &error_abort);
}
/* create pci host bus */
q35_host = Q35_HOST_DEVICE(qdev_create(NULL, TYPE_Q35_HOST_DEVICE));
- object_property_add_child(qdev_get_machine(), "q35", OBJECT(q35_host), NULL);
+ object_property_add_child(qdev_get_machine(), "q35", OBJECT(q35_host));
object_property_set_link(OBJECT(q35_host), OBJECT(ram_memory),
MCH_HOST_PROP_RAM_MEM, NULL);
object_property_set_link(OBJECT(q35_host), OBJECT(pci_memory),
TYPE_HOTPLUG_HANDLER,
(Object **)&pcms->acpi_dev,
object_property_allow_set_link,
- OBJ_PROP_LINK_STRONG, &error_abort);
+ OBJ_PROP_LINK_STRONG);
object_property_set_link(OBJECT(machine), OBJECT(lpc),
PC_MACHINE_ACPI_DEVICE_PROP, &error_abort);
qdev_prop_set_uint64(dev, "sector-length", FLASH_SECTOR_SIZE);
qdev_prop_set_uint8(dev, "width", 1);
qdev_prop_set_string(dev, "name", name);
- object_property_add_child(OBJECT(pcms), name, OBJECT(dev),
- &error_abort);
+ object_property_add_child(OBJECT(pcms), name, OBJECT(dev));
object_property_add_alias(OBJECT(pcms), alias_prop_name,
- OBJECT(dev), "drive", &error_abort);
+ OBJECT(dev), "drive");
return PFLASH_CFI01(dev);
}
dev_obj = OBJECT(pcms->flash[i]);
if (!object_property_get_bool(dev_obj, "realized", &error_abort)) {
prop_name = g_strdup_printf("pflash%d", i);
- object_property_del(OBJECT(pcms), prop_name, &error_abort);
+ object_property_del(OBJECT(pcms), prop_name);
g_free(prop_name);
object_unparent(dev_obj);
pcms->flash[i] = NULL;
dev = qdev_create(NULL, TYPE_IOAPIC);
}
object_property_add_child(object_resolve_path(parent_name, NULL),
- "ioapic", OBJECT(dev), NULL);
+ "ioapic", OBJECT(dev));
qdev_init_nofail(dev);
d = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(d, 0, IO_APIC_DEFAULT_ADDRESS);
object_class_property_add(oc, X86_MACHINE_MAX_RAM_BELOW_4G, "size",
x86_machine_get_max_ram_below_4g, x86_machine_set_max_ram_below_4g,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_set_description(oc, X86_MACHINE_MAX_RAM_BELOW_4G,
- "Maximum ram below the 4G boundary (32bit boundary)", &error_abort);
+ "Maximum ram below the 4G boundary (32bit boundary)");
object_class_property_add(oc, X86_MACHINE_SMM, "OnOffAuto",
x86_machine_get_smm, x86_machine_set_smm,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_set_description(oc, X86_MACHINE_SMM,
- "Enable SMM", &error_abort);
+ "Enable SMM");
object_class_property_add(oc, X86_MACHINE_ACPI, "OnOffAuto",
x86_machine_get_acpi, x86_machine_set_acpi,
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_class_property_set_description(oc, X86_MACHINE_ACPI,
- "Enable ACPI", &error_abort);
+ "Enable ACPI");
}
static const TypeInfo x86_machine_info = {
SysbusAHCIState *s = SYSBUS_AHCI(obj);
AllwinnerAHCIState *a = ALLWINNER_AHCI(obj);
- memory_region_init_io(&a->mmio, OBJECT(obj), &allwinner_ahci_mem_ops, a,
+ memory_region_init_io(&a->mmio, obj, &allwinner_ahci_mem_ops, a,
"allwinner-ahci", ALLWINNER_AHCI_MMIO_SIZE);
memory_region_add_subregion(&s->ahci.mem, ALLWINNER_AHCI_MMIO_OFF,
&a->mmio);
object_property_add_link(obj, "dbdma", TYPE_MAC_DBDMA,
(Object **) &s->dbdma,
- qdev_prop_allow_set_link_before_realize, 0, NULL);
+ qdev_prop_allow_set_link_before_realize, 0);
}
static Property macio_ide_properties[] = {
blk_unref(blk);
}
}
- qdev_reset_all(DEVICE(dev));
+ qdev_reset_all(dev);
return 0;
}
/* --------------------------------- */
static char *idebus_get_fw_dev_path(DeviceState *dev);
-static void idebus_unrealize(BusState *qdev, Error **errp);
+static void idebus_unrealize(BusState *qdev);
static Property ide_props[] = {
DEFINE_PROP_UINT32("unit", IDEDevice, unit, -1),
k->unrealize = idebus_unrealize;
}
-static void idebus_unrealize(BusState *bus, Error **errp)
+static void idebus_unrealize(BusState *bus)
{
IDEBus *ibus = IDE_BUS(bus);
{
object_property_add(obj, "bootindex", "int32",
ide_dev_get_bootindex,
- ide_dev_set_bootindex, NULL, NULL, NULL);
+ ide_dev_set_bootindex, NULL, NULL);
object_property_set_int(obj, -1, "bootindex", NULL);
}
vhi->vhost = VHOST_USER_BACKEND(object_new(TYPE_VHOST_USER_BACKEND));
object_property_add_alias(obj, "chardev",
- OBJECT(vhi->vhost), "chardev", &error_abort);
+ OBJECT(vhi->vhost), "chardev");
}
static void vhost_input_finalize(Object *obj)
}
}
-static void virtio_input_hid_unrealize(DeviceState *dev, Error **errp)
+static void virtio_input_hid_unrealize(DeviceState *dev)
{
VirtIOInputHID *vhid = VIRTIO_INPUT_HID(dev);
qemu_input_handler_unregister(vhid->hs);
return;
}
-static void virtio_input_host_unrealize(DeviceState *dev, Error **errp)
+static void virtio_input_host_unrealize(DeviceState *dev)
{
VirtIOInputHost *vih = VIRTIO_INPUT_HOST(dev);
g_free(vinput->queue);
}
-static void virtio_input_device_unrealize(DeviceState *dev, Error **errp)
+static void virtio_input_device_unrealize(DeviceState *dev)
{
VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev);
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIOInput *vinput = VIRTIO_INPUT(dev);
- Error *local_err = NULL;
if (vic->unrealize) {
- vic->unrealize(dev, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
+ vic->unrealize(dev);
}
virtio_delete_queue(vinput->evt);
virtio_delete_queue(vinput->sts);
msi_nonbroken = true;
}
-static void apic_unrealize(DeviceState *dev, Error **errp)
+static void apic_unrealize(DeviceState *dev)
{
APICCommonState *s = APIC(dev);
s, -1, 0, NULL);
}
-static void apic_common_unrealize(DeviceState *dev, Error **errp)
+static void apic_common_unrealize(DeviceState *dev)
{
APICCommonState *s = APIC_COMMON(dev);
APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
vmstate_unregister(NULL, &vmstate_apic_common, s);
- info->unrealize(dev, errp);
+ info->unrealize(dev);
if (apic_report_tpr_access && info->enable_tpr_reporting) {
info->enable_tpr_reporting(s, false);
s->id = s->initial_apic_id = -1;
object_property_add(obj, "id", "uint32",
apic_common_get_id,
- apic_common_set_id, NULL, NULL, NULL);
+ apic_common_set_id, NULL, NULL);
}
static void apic_common_class_init(ObjectClass *klass, void *data)
qemu_add_machine_init_done_notifier(&s->machine_done);
}
-static void ioapic_unrealize(DeviceState *dev, Error **errp)
+static void ioapic_unrealize(DeviceState *dev)
{
IOAPICCommonState *s = IOAPIC_COMMON(dev);
if (kvm_enabled()) {
dev = qdev_create(NULL, TYPE_KVM_S390_FLIC);
object_property_add_child(qdev_get_machine(), TYPE_KVM_S390_FLIC,
- OBJECT(dev), NULL);
+ OBJECT(dev));
} else {
dev = qdev_create(NULL, TYPE_QEMU_S390_FLIC);
object_property_add_child(qdev_get_machine(), TYPE_QEMU_S390_FLIC,
- OBJECT(dev), NULL);
+ OBJECT(dev));
}
qdev_init_nofail(dev);
}
vmstate_register(NULL, icp->cs->cpu_index, &vmstate_icp_server, icp);
}
-static void icp_unrealize(DeviceState *dev, Error **errp)
+static void icp_unrealize(DeviceState *dev)
{
ICPState *icp = ICP(dev);
Object *obj;
obj = object_new(type);
- object_property_add_child(cpu, type, obj, &error_abort);
+ object_property_add_child(cpu, type, obj);
object_unref(obj);
object_property_set_link(obj, OBJECT(xi), ICP_PROP_XICS, &error_abort);
object_property_set_link(obj, cpu, ICP_PROP_CPU, &error_abort);
Object *obj;
obj = object_new(TYPE_XIVE_TCTX);
- object_property_add_child(cpu, TYPE_XIVE_TCTX, obj, &error_abort);
+ object_property_add_child(cpu, TYPE_XIVE_TCTX, obj);
object_unref(obj);
object_property_set_link(obj, cpu, "cpu", &error_abort);
object_property_set_link(obj, OBJECT(xptr), "presenter", &error_abort);
k->realize(dev, errp);
}
-static void ipack_device_unrealize(DeviceState *dev, Error **errp)
+static void ipack_device_unrealize(DeviceState *dev)
{
IPackDevice *idev = IPACK_DEVICE(dev);
IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev);
- Error *err = NULL;
if (k->unrealize) {
- k->unrealize(dev, &err);
- error_propagate(errp, err);
+ k->unrealize(dev);
return;
}
{
object_property_add_link(obj, "bmc", TYPE_IPMI_BMC, bmc,
isa_ipmi_bmc_check,
- OBJ_PROP_LINK_STRONG,
- &error_abort);
+ OBJ_PROP_LINK_STRONG);
}
static Property ipmi_bmc_properties[] = {
{
SMBusIPMIDevice *sid = SMBUS_IPMI(obj);
- ipmi_bmc_find_and_link(OBJECT(obj), (Object **) &sid->bmc);
+ ipmi_bmc_find_and_link(obj, (Object **) &sid->bmc);
}
static void smbus_ipmi_get_fwinfo(struct IPMIInterface *ii, IPMIFwInfo *info)
qdev_prop_set_uint32(d, "irq", k->parallel.get_irq(sio, i));
}
qdev_prop_set_chr(d, "chardev", chr);
+ object_property_add_child(OBJECT(dev), name, OBJECT(isa));
qdev_init_nofail(d);
sio->parallel[i] = isa;
trace_superio_create_parallel(i,
k->parallel.get_iobase(sio, i) : -1,
k->parallel.get_irq ?
k->parallel.get_irq(sio, i) : -1);
- object_property_add_child(OBJECT(dev), name,
- OBJECT(sio->parallel[i]), NULL);
g_free(name);
}
}
qdev_prop_set_uint32(d, "irq", k->serial.get_irq(sio, i));
}
qdev_prop_set_chr(d, "chardev", chr);
+ object_property_add_child(OBJECT(dev), name, OBJECT(isa));
qdev_init_nofail(d);
sio->serial[i] = isa;
trace_superio_create_serial(i,
k->serial.get_iobase(sio, i) : -1,
k->serial.get_irq ?
k->serial.get_irq(sio, i) : -1);
- object_property_add_child(OBJECT(dev), name,
- OBJECT(sio->serial[0]), NULL);
g_free(name);
}
}
qdev_prop_set_drive(d, "driveB", blk_by_legacy_dinfo(drive),
&error_fatal);
}
+ object_property_add_child(OBJECT(sio), "isa-fdc", OBJECT(isa));
qdev_init_nofail(d);
sio->floppy = isa;
trace_superio_create_floppy(0,
}
/* Keyboard, mouse */
- sio->kbc = isa_create_simple(bus, TYPE_I8042);
+ isa = isa_create(bus, TYPE_I8042);
+ object_property_add_child(OBJECT(sio), TYPE_I8042, OBJECT(isa));
+ qdev_init_nofail(DEVICE(isa));
+ sio->kbc = isa;
/* IDE */
if (k->ide.count && (!k->ide.is_enabled || k->ide.is_enabled(sio, 0))) {
qdev_prop_set_uint32(d, "irq", k->ide.get_irq(sio, 0));
}
qdev_init_nofail(d);
+ object_property_add_child(OBJECT(sio), "isa-ide", OBJECT(isa));
sio->ide = isa;
trace_superio_create_ide(0,
k->ide.get_iobase ?
static const uint8_t acpi_disable_cmd = ICH9_APM_ACPI_DISABLE;
object_property_add_uint8_ptr(obj, ACPI_PM_PROP_SCI_INT,
- &lpc->sci_gsi, OBJ_PROP_FLAG_READ, NULL);
+ &lpc->sci_gsi, OBJ_PROP_FLAG_READ);
object_property_add_uint8_ptr(OBJECT(lpc), ACPI_PM_PROP_ACPI_ENABLE_CMD,
- &acpi_enable_cmd, OBJ_PROP_FLAG_READ, NULL);
+ &acpi_enable_cmd, OBJ_PROP_FLAG_READ);
object_property_add_uint8_ptr(OBJECT(lpc), ACPI_PM_PROP_ACPI_DISABLE_CMD,
- &acpi_disable_cmd, OBJ_PROP_FLAG_READ, NULL);
+ &acpi_disable_cmd, OBJ_PROP_FLAG_READ);
- ich9_pm_add_properties(obj, &lpc->pm, NULL);
+ ich9_pm_add_properties(obj, &lpc->pm);
}
static void ich9_lpc_realize(PCIDevice *d, Error **errp)
{
object_property_add(obj, NVDIMM_LABEL_SIZE_PROP, "int",
nvdimm_get_label_size, nvdimm_set_label_size, NULL,
- NULL, NULL);
+ NULL);
object_property_add(obj, NVDIMM_UUID_PROP, "QemuUUID", nvdimm_get_uuid,
- nvdimm_set_uuid, NULL, NULL, NULL);
+ nvdimm_set_uuid, NULL, NULL);
}
static void nvdimm_finalize(Object *obj)
static void pc_dimm_init(Object *obj)
{
object_property_add(obj, PC_DIMM_SIZE_PROP, "uint64", pc_dimm_get_size,
- NULL, NULL, NULL, &error_abort);
+ NULL, NULL, NULL);
}
static void pc_dimm_realize(DeviceState *dev, Error **errp)
host_memory_backend_set_mapped(dimm->hostmem, true);
}
-static void pc_dimm_unrealize(DeviceState *dev, Error **errp)
+static void pc_dimm_unrealize(DeviceState *dev)
{
PCDIMMDevice *dimm = PC_DIMM(dev);
dma = qdev_create(NULL, "xlnx.axi-dma");
/* FIXME: attach to the sysbus instead */
- object_property_add_child(qdev_get_machine(), "xilinx-eth", OBJECT(eth0),
- NULL);
- object_property_add_child(qdev_get_machine(), "xilinx-dma", OBJECT(dma),
- NULL);
+ object_property_add_child(qdev_get_machine(), "xilinx-eth", OBJECT(eth0));
+ object_property_add_child(qdev_get_machine(), "xilinx-dma", OBJECT(dma));
ds = object_property_get_link(OBJECT(dma),
"axistream-connected-target", NULL);
qdev_set_nic_properties(eth0, &nd_table[0]);
qdev_prop_set_uint32(eth0, "rxmem", 0x1000);
qdev_prop_set_uint32(eth0, "txmem", 0x1000);
- object_property_set_link(OBJECT(eth0), OBJECT(ds),
+ object_property_set_link(OBJECT(eth0), ds,
"axistream-connected", &error_abort);
- object_property_set_link(OBJECT(eth0), OBJECT(cs),
+ object_property_set_link(OBJECT(eth0), cs,
"axistream-control-connected", &error_abort);
qdev_init_nofail(eth0);
sysbus_mmio_map(SYS_BUS_DEVICE(eth0), 0, AXIENET_BASEADDR);
cs = object_property_get_link(OBJECT(eth0),
"axistream-control-connected-target", NULL);
qdev_prop_set_uint32(dma, "freqhz", 100 * 1000000);
- object_property_set_link(OBJECT(dma), OBJECT(ds),
+ object_property_set_link(OBJECT(dma), ds,
"axistream-connected", &error_abort);
- object_property_set_link(OBJECT(dma), OBJECT(cs),
+ object_property_set_link(OBJECT(dma), cs,
"axistream-control-connected", &error_abort);
qdev_init_nofail(dma);
sysbus_mmio_map(SYS_BUS_DEVICE(dma), 0, AXIDMA_BASEADDR);
{
object_property_add(obj, "ram-size", "int",
aspeed_sdmc_get_ram_size, aspeed_sdmc_set_ram_size,
- NULL, NULL, NULL);
+ NULL, NULL);
}
static void aspeed_sdmc_realize(DeviceState *dev, Error **errp)
edu->dma_mask = (1UL << 28) - 1;
object_property_add_uint64_ptr(obj, "dma_mask",
- &edu->dma_mask, OBJ_PROP_FLAG_READWRITE,
- NULL);
+ &edu->dma_mask, OBJ_PROP_FLAG_READWRITE);
}
static void edu_class_init(ObjectClass *class, void *data)
/* Pass through mos6522 output IRQs */
ms = MOS6522(&m->mos6522_via1);
object_property_add_alias(OBJECT(dev), "irq[0]", OBJECT(ms),
- SYSBUS_DEVICE_GPIO_IRQ "[0]", &error_abort);
+ SYSBUS_DEVICE_GPIO_IRQ "[0]");
ms = MOS6522(&m->mos6522_via2);
object_property_add_alias(OBJECT(dev), "irq[1]", OBJECT(ms),
- SYSBUS_DEVICE_GPIO_IRQ "[0]", &error_abort);
+ SYSBUS_DEVICE_GPIO_IRQ "[0]");
/* Pass through mos6522 input IRQs */
qdev_pass_gpios(DEVICE(&m->mos6522_via1), dev, "via1-irq");
object_property_add_link(obj, "pic", TYPE_OPENPIC,
(Object **) &s->pic,
qdev_prop_allow_set_link_before_realize,
- 0, NULL);
+ 0);
memory_region_init_io(&s->gpiomem, OBJECT(s), &macio_gpio_ops, obj,
"gpio", 0x30);
object_property_add_link(obj, "pic", TYPE_HEATHROW,
(Object **) &os->pic,
qdev_prop_allow_set_link_before_realize,
- 0, NULL);
+ 0);
macio_init_child_obj(s, "cuda", &s->cuda, sizeof(s->cuda), TYPE_CUDA);
object_property_add_link(obj, "pic", TYPE_OPENPIC,
(Object **) &ns->pic,
qdev_prop_allow_set_link_before_realize,
- 0, NULL);
+ 0);
macio_init_child_obj(s, "gpio", &ns->gpio, sizeof(ns->gpio),
TYPE_MACIO_GPIO);
if (s->has_adb) {
qbus_create_inplace(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
- DEVICE(dev), "adb.0");
+ dev, "adb.0");
s->adb_poll_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, pmu_adb_poll, s);
s->adb_poll_mask = 0xffff;
s->autopoll_rate_ms = 20;
object_property_add_link(obj, "gpio", TYPE_MACIO_GPIO,
(Object **) &s->gpio,
qdev_prop_allow_set_link_before_realize,
- 0, NULL);
+ 0);
sysbus_init_child_obj(obj, "mos6522-pmu", &s->mos6522_pmu,
sizeof(s->mos6522_pmu), TYPE_MOS6522_PMU);
name = g_strdup_printf("led%d", led);
object_property_add(obj, name, "bool", pca9552_get_led, pca9552_set_led,
- NULL, NULL, NULL);
+ NULL, NULL);
g_free(name);
}
}
{
object_property_add(obj, "temperature", "int",
tmp105_get_temperature,
- tmp105_set_temperature, NULL, NULL, NULL);
+ tmp105_set_temperature, NULL, NULL);
}
static void tmp105_class_init(ObjectClass *klass, void *data)
{
object_property_add(obj, "temperature0", "int",
tmp421_get_temperature,
- tmp421_set_temperature, NULL, NULL, NULL);
+ tmp421_set_temperature, NULL, NULL);
object_property_add(obj, "temperature1", "int",
tmp421_get_temperature,
- tmp421_set_temperature, NULL, NULL, NULL);
+ tmp421_set_temperature, NULL, NULL);
object_property_add(obj, "temperature2", "int",
tmp421_get_temperature,
- tmp421_set_temperature, NULL, NULL, NULL);
+ tmp421_set_temperature, NULL, NULL);
object_property_add(obj, "temperature3", "int",
tmp421_get_temperature,
- tmp421_set_temperature, NULL, NULL, NULL);
+ tmp421_set_temperature, NULL, NULL);
}
static void tmp421_class_init(ObjectClass *klass, void *data)
object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
(Object **)&s->dma_mr,
qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_STRONG,
- &error_abort);
+ OBJ_PROP_LINK_STRONG);
}
static const VMStateDescription vmstate_cadence_gem = {
object_property_add_link(obj, "canbus", TYPE_CAN_BUS,
(Object **)&d->canbus,
qdev_prop_allow_set_link_before_realize,
- 0, &error_abort);
+ 0);
}
static void kvaser_pci_class_init(ObjectClass *klass, void *data)
object_property_add_link(obj, "canbus0", TYPE_CAN_BUS,
(Object **)&d->canbus[0],
qdev_prop_allow_set_link_before_realize,
- 0, &error_abort);
+ 0);
object_property_add_link(obj, "canbus1", TYPE_CAN_BUS,
(Object **)&d->canbus[1],
qdev_prop_allow_set_link_before_realize,
- 0, &error_abort);
+ 0);
}
static void mioe3680_pci_class_init(ObjectClass *klass, void *data)
object_property_add_link(obj, "canbus0", TYPE_CAN_BUS,
(Object **)&d->canbus[0],
qdev_prop_allow_set_link_before_realize,
- 0, &error_abort);
+ 0);
object_property_add_link(obj, "canbus1", TYPE_CAN_BUS,
(Object **)&d->canbus[1],
qdev_prop_allow_set_link_before_realize,
- 0, &error_abort);
+ 0);
}
static void pcm3680i_pci_class_init(ObjectClass *klass, void *data)
E1000State *n = E1000(obj);
device_add_bootindex_property(obj, &n->conf.bootindex,
"bootindex", "/ethernet-phy@0",
- DEVICE(n), NULL);
+ DEVICE(n));
}
static const TypeInfo e1000_base_info = {
type_info.parent = TYPE_E1000_BASE;
type_info.class_data = (void *)info;
type_info.class_init = e1000_class_init;
- type_info.instance_init = e1000_instance_init;
type_register(&type_info);
}
E1000EState *s = E1000E(obj);
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
- DEVICE(obj), NULL);
+ DEVICE(obj));
}
static const TypeInfo e1000e_info = {
EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, PCI_DEVICE(obj));
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
- DEVICE(s), NULL);
+ DEVICE(s));
}
static E100PCIDeviceInfo e100_devices[] = {
qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&net_ftgmac100_info, &s->conf,
- object_get_typename(OBJECT(dev)), DEVICE(dev)->id,
- s);
+ object_get_typename(OBJECT(dev)), dev->id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
}
s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,
object_get_typename(OBJECT(dev)),
- DEVICE(dev)->id, s);
+ dev->id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
}
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
- DEVICE(obj), NULL);
+ DEVICE(obj));
}
static Property lance_properties[] = {
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
- DEVICE(obj), NULL);
+ DEVICE(obj));
}
static Property lasi_82596_properties[] = {
{
object_property_add(obj, "bootindex", "int32",
isa_ne2000_get_bootindex,
- isa_ne2000_set_bootindex, NULL, NULL, NULL);
+ isa_ne2000_set_bootindex, NULL, NULL);
object_property_set_int(obj, -1, "bootindex", NULL);
}
static const TypeInfo ne2000_isa_info = {
device_add_bootindex_property(obj, &s->c.bootindex,
"bootindex", "/ethernet-phy@0",
- &pci_dev->qdev, NULL);
+ &pci_dev->qdev);
}
static Property ne2000_properties[] = {
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
- DEVICE(obj), NULL);
+ DEVICE(obj));
}
static Property pcnet_properties[] = {
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
- DEVICE(obj), NULL);
+ DEVICE(obj));
}
static Property rtl8139_properties[] = {
device_add_bootindex_property(obj, &dev->nicconf.bootindex,
"bootindex", "",
- DEVICE(dev), NULL);
+ DEVICE(dev));
if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
for (i = 0; i < RX_MAX_POOLS; i++) {
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
- DEVICE(obj), NULL);
+ DEVICE(obj));
}
static Property sungem_properties[] = {
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
- DEVICE(obj), NULL);
+ DEVICE(obj));
}
static void sunhme_reset(DeviceState *ds)
device_add_bootindex_property(obj, &d->c.bootindex,
"bootindex", "/ethernet-phy@0",
- &pci_dev->qdev, NULL);
+ &pci_dev->qdev);
}
static Property tulip_properties[] = {
VirtIONet *n = qemu_get_nic_opaque(nc);
if (nc->rxfilter_notify_enabled) {
- gchar *path = object_get_canonical_path(OBJECT(n->qdev));
+ char *path = object_get_canonical_path(OBJECT(n->qdev));
qapi_event_send_nic_rx_filter_changed(!!n->netclient_name,
n->netclient_name, path);
g_free(path);
n->qdev = dev;
}
-static void virtio_net_device_unrealize(DeviceState *dev, Error **errp)
+static void virtio_net_device_unrealize(DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIONet *n = VIRTIO_NET(dev);
n->config_size = sizeof(struct virtio_net_config);
device_add_bootindex_property(obj, &n->nic_conf.bootindex,
"bootindex", "/ethernet-phy@0",
- DEVICE(n), NULL);
+ DEVICE(n));
}
static int virtio_net_pre_save(void *opaque)
VMXNET3State *s = VMXNET3(obj);
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
- DEVICE(obj), NULL);
+ DEVICE(obj));
}
static void vmxnet3_pci_uninit(PCIDevice *pci_dev)
break;
}
- /* Unconditionally clear regs[BMCR][BMCR_RESET] */
- phy->regs[0] &= ~0x8000;
+ /* Unconditionally clear regs[BMCR][BMCR_RESET] and auto-neg */
+ phy->regs[0] &= ~0x8200;
}
static void
uint32_t hdr[CONTROL_PAYLOAD_WORDS];
+ uint8_t *txmem;
+ uint32_t txpos;
+
uint8_t *rxmem;
uint32_t rxsize;
uint32_t rxpos;
static void axienet_tx_reset(XilinxAXIEnet *s)
{
s->tc = TC_JUM | TC_TX | TC_VLAN;
+ s->txpos = 0;
}
static inline int axienet_rx_resetting(XilinxAXIEnet *s)
axienet_eth_rx_notify, s)) {
size_t ret = stream_push(s->tx_control_dev,
(void *)s->rxapp + CONTROL_PAYLOAD_SIZE
- - s->rxappsize, s->rxappsize);
+ - s->rxappsize, s->rxappsize, true);
s->rxappsize -= ret;
}
while (s->rxsize && stream_can_push(s->tx_data_dev,
axienet_eth_rx_notify, s)) {
size_t ret = stream_push(s->tx_data_dev, (void *)s->rxmem + s->rxpos,
- s->rxsize);
+ s->rxsize, true);
s->rxsize -= ret;
s->rxpos += ret;
if (!s->rxsize) {
}
static size_t
-xilinx_axienet_control_stream_push(StreamSlave *obj, uint8_t *buf, size_t len)
+xilinx_axienet_control_stream_push(StreamSlave *obj, uint8_t *buf, size_t len,
+ bool eop)
{
int i;
XilinxAXIEnetStreamSlave *cs = XILINX_AXI_ENET_CONTROL_STREAM(obj);
XilinxAXIEnet *s = cs->enet;
+ assert(eop);
if (len != CONTROL_PAYLOAD_SIZE) {
hw_error("AXI Enet requires %d byte control stream payload\n",
(int)CONTROL_PAYLOAD_SIZE);
}
static size_t
-xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size)
+xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size,
+ bool eop)
{
XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(obj);
XilinxAXIEnet *s = ds->enet;
return size;
}
+ if (s->txpos + size > s->c_txmem) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Packet larger than txmem\n",
+ TYPE_XILINX_AXI_ENET);
+ s->txpos = 0;
+ return size;
+ }
+
+ if (s->txpos == 0 && eop) {
+ /* Fast path single fragment. */
+ s->txpos = size;
+ } else {
+ memcpy(s->txmem + s->txpos, buf, size);
+ buf = s->txmem;
+ s->txpos += size;
+
+ if (!eop) {
+ return size;
+ }
+ }
+
/* Jumbo or vlan sizes ? */
if (!(s->tc & TC_JUM)) {
- if (size > 1518 && size <= 1522 && !(s->tc & TC_VLAN)) {
+ if (s->txpos > 1518 && s->txpos <= 1522 && !(s->tc & TC_VLAN)) {
+ s->txpos = 0;
return size;
}
}
uint32_t tmp_csum;
uint16_t csum;
- tmp_csum = net_checksum_add(size - start_off,
- (uint8_t *)buf + start_off);
+ tmp_csum = net_checksum_add(s->txpos - start_off,
+ buf + start_off);
/* Accumulate the seed. */
tmp_csum += s->hdr[2] & 0xffff;
buf[write_off + 1] = csum & 0xff;
}
- qemu_send_packet(qemu_get_queue(s->nic), buf, size);
+ qemu_send_packet(qemu_get_queue(s->nic), buf, s->txpos);
- s->stats.tx_bytes += size;
+ s->stats.tx_bytes += s->txpos;
s->regs[R_IS] |= IS_TX_COMPLETE;
enet_update_irq(s);
+ s->txpos = 0;
return size;
}
object_property_add_link(OBJECT(ds), "enet", "xlnx.axi-ethernet",
(Object **) &ds->enet,
object_property_allow_set_link,
- OBJ_PROP_LINK_STRONG,
- &local_err);
+ OBJ_PROP_LINK_STRONG);
object_property_add_link(OBJECT(cs), "enet", "xlnx.axi-ethernet",
(Object **) &cs->enet,
object_property_allow_set_link,
- OBJ_PROP_LINK_STRONG,
- &local_err);
- if (local_err) {
- goto xilinx_enet_realize_fail;
- }
+ OBJ_PROP_LINK_STRONG);
object_property_set_link(OBJECT(ds), OBJECT(s), "enet", &local_err);
object_property_set_link(OBJECT(cs), OBJECT(s), "enet", &local_err);
if (local_err) {
s->TEMAC.parent = s;
s->rxmem = g_malloc(s->c_rxmem);
+ s->txmem = g_malloc(s->c_txmem);
return;
xilinx_enet_realize_fail:
dc->reset = xilinx_axienet_reset;
}
-static void xilinx_enet_stream_class_init(ObjectClass *klass, void *data)
+static void xilinx_enet_control_stream_class_init(ObjectClass *klass,
+ void *data)
+{
+ StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
+
+ ssc->push = xilinx_axienet_control_stream_push;
+}
+
+static void xilinx_enet_data_stream_class_init(ObjectClass *klass, void *data)
{
StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
- ssc->push = data;
+ ssc->push = xilinx_axienet_data_stream_push;
}
static const TypeInfo xilinx_enet_info = {
.name = TYPE_XILINX_AXI_ENET_DATA_STREAM,
.parent = TYPE_OBJECT,
.instance_size = sizeof(struct XilinxAXIEnetStreamSlave),
- .class_init = xilinx_enet_stream_class_init,
- .class_data = xilinx_axienet_data_stream_push,
+ .class_init = xilinx_enet_data_stream_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_STREAM_SLAVE },
{ }
.name = TYPE_XILINX_AXI_ENET_CONTROL_STREAM,
.parent = TYPE_OBJECT,
.instance_size = sizeof(struct XilinxAXIEnetStreamSlave),
- .class_init = xilinx_enet_stream_class_init,
- .class_data = xilinx_axienet_control_stream_push,
+ .class_init = xilinx_enet_control_stream_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_STREAM_SLAVE },
{ }
/* Register: Internal Interrupt Controller (IIC) */
dev = qdev_create(NULL, "altera,iic");
- object_property_add_const_link(OBJECT(dev), "cpu", OBJECT(cpu),
- &error_abort);
+ object_property_add_const_link(OBJECT(dev), "cpu", OBJECT(cpu));
qdev_init_nofail(dev);
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, cpu_irq[0]);
for (i = 0; i < 32; i++) {
static void nubus_device_realize(DeviceState *dev, Error **errp)
{
- NubusBus *nubus = NUBUS_BUS(qdev_get_parent_bus(DEVICE(dev)));
+ NubusBus *nubus = NUBUS_BUS(qdev_get_parent_bus(dev));
NubusDevice *nd = NUBUS_DEVICE(dev);
char *name;
hwaddr slot_offset;
}
object_property_add_child(OBJECT(qdev_get_machine()), TYPE_FW_CFG,
- OBJECT(dev), NULL);
+ OBJECT(dev));
qdev_init_nofail(dev);
sbd = SYS_BUS_DEVICE(dev);
}
object_property_add_child(OBJECT(qdev_get_machine()), TYPE_FW_CFG,
- OBJECT(dev), NULL);
+ OBJECT(dev));
qdev_init_nofail(dev);
sbd = SYS_BUS_DEVICE(dev);
sysbus_init_mmio(d, &s->mem);
}
-static void macio_nvram_unrealizefn(DeviceState *dev, Error **errp)
+static void macio_nvram_unrealizefn(DeviceState *dev)
{
MacIONVRAMState *s = MACIO_NVRAM(dev);
BonitoState *bs = BONITO_PCI_HOST_BRIDGE(dev);
memory_region_init(&bs->pci_mem, OBJECT(dev), "pci.mem", BONITO_PCILO_SIZE);
- phb->bus = pci_register_root_bus(DEVICE(dev), "pci",
+ phb->bus = pci_register_root_bus(dev, "pci",
pci_bonito_set_irq, pci_bonito_map_irq,
dev, &bs->pci_mem, get_system_io(),
0x28, 32, TYPE_PCI_BUS);
object_property_add_link(obj, "pic", TYPE_HEATHROW,
(Object **) &s->pic,
qdev_prop_allow_set_link_before_realize,
- 0, NULL);
+ 0);
sysbus_init_mmio(sbd, &phb->conf_mem);
sysbus_init_mmio(sbd, &phb->data_mem);
object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32",
i440fx_pcihost_get_pci_hole_start,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL);
object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "uint32",
i440fx_pcihost_get_pci_hole_end,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL);
object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "uint64",
i440fx_pcihost_get_pci_hole64_start,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL);
object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "uint64",
i440fx_pcihost_get_pci_hole64_end,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL);
}
static void i440fx_pcihost_realize(DeviceState *dev, Error **errp)
b = pci_root_bus_new(dev, NULL, pci_address_space,
address_space_io, 0, TYPE_PCI_BUS);
s->bus = b;
- object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);
+ object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev));
qdev_init_nofail(dev);
d = pci_create_simple(b, 0, pci_type);
memory_region_set_enabled(&f->low_smram, true);
memory_region_add_subregion(&f->smram, 0xa0000, &f->low_smram);
object_property_add_const_link(qdev_get_machine(), "smram",
- OBJECT(&f->smram), &error_abort);
+ OBJECT(&f->smram));
init_pam(dev, f->ram_memory, f->system_memory, f->pci_address_space,
&f->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE);
object_property_add_link(obj, "phb", TYPE_PNV_PHB3,
(Object **)&msi->phb,
object_property_allow_set_link,
- OBJ_PROP_LINK_STRONG,
- &error_abort);
+ OBJ_PROP_LINK_STRONG);
/* Will be overriden later */
ics->offset = 0;
object_property_add_link(obj, "phb", TYPE_PNV_PHB3,
(Object **)&pbcq->phb,
object_property_allow_set_link,
- OBJ_PROP_LINK_STRONG,
- &error_abort);
+ OBJ_PROP_LINK_STRONG);
}
static void pnv_pbcq_class_init(ObjectClass *klass, void *data)
Q35_PCI_HOST_HOLE64_SIZE_DEFAULT);
object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32",
q35_host_get_pci_hole_start,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL);
object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "uint32",
q35_host_get_pci_hole_end,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL);
object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "uint64",
q35_host_get_pci_hole64_start,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL);
object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "uint64",
q35_host_get_pci_hole64_end,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL);
object_property_add_uint64_ptr(obj, PCIE_HOST_MCFG_SIZE,
- &pehb->size, OBJ_PROP_FLAG_READ, NULL);
+ &pehb->size, OBJ_PROP_FLAG_READ);
object_property_add_link(obj, MCH_HOST_PROP_RAM_MEM, TYPE_MEMORY_REGION,
(Object **) &s->mch.ram_memory,
- qdev_prop_allow_set_link_before_realize, 0, NULL);
+ qdev_prop_allow_set_link_before_realize, 0);
object_property_add_link(obj, MCH_HOST_PROP_PCI_MEM, TYPE_MEMORY_REGION,
(Object **) &s->mch.pci_address_space,
- qdev_prop_allow_set_link_before_realize, 0, NULL);
+ qdev_prop_allow_set_link_before_realize, 0);
object_property_add_link(obj, MCH_HOST_PROP_SYSTEM_MEM, TYPE_MEMORY_REGION,
(Object **) &s->mch.system_memory,
- qdev_prop_allow_set_link_before_realize, 0, NULL);
+ qdev_prop_allow_set_link_before_realize, 0);
object_property_add_link(obj, MCH_HOST_PROP_IO_MEM, TYPE_MEMORY_REGION,
(Object **) &s->mch.address_space_io,
- qdev_prop_allow_set_link_before_realize, 0, NULL);
+ qdev_prop_allow_set_link_before_realize, 0);
}
static const TypeInfo q35_host_info = {
&mch->smbase_window);
object_property_add_const_link(qdev_get_machine(), "smram",
- OBJECT(&mch->smram), &error_abort);
+ OBJECT(&mch->smram));
init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory,
mch->pci_address_space, &mch->pam_regions[0],
object_property_add_link(obj, "iommu", TYPE_SUN4U_IOMMU,
(Object **) &s->iommu,
qdev_prop_allow_set_link_before_realize,
- 0, NULL);
+ 0);
/* sabre_config */
memory_region_init_io(&s->sabre_config, OBJECT(s), &sabre_config_ops, s,
object_property_add_link(obj, "pic", TYPE_OPENPIC,
(Object **) &s->pic,
qdev_prop_allow_set_link_before_realize,
- 0, NULL);
+ 0);
sysbus_init_mmio(sbd, &h->conf_mem);
sysbus_init_mmio(sbd, &h->data_mem);
object_property_add_link(obj, "pic", TYPE_OPENPIC,
(Object **) &s->pic,
qdev_prop_allow_set_link_before_realize,
- 0, NULL);
+ 0);
sysbus_init_mmio(sbd, &h->conf_mem);
sysbus_init_mmio(sbd, &h->data_mem);
object_property_add_link(obj, "pic", TYPE_OPENPIC,
(Object **) &s->pic,
qdev_prop_allow_set_link_before_realize,
- 0, NULL);
+ 0);
sysbus_init_mmio(sbd, &h->conf_mem);
sysbus_init_mmio(sbd, &h->data_mem);
object_property_add_link(obj, "pic", TYPE_OPENPIC,
(Object **) &s->pic,
qdev_prop_allow_set_link_before_realize,
- 0, NULL);
+ 0);
sysbus_init_mmio(sbd, &h->conf_mem);
sysbus_init_mmio(sbd, &h->data_mem);
}
}
-static void pci_bus_unrealize(BusState *qbus, Error **errp)
+static void pci_bus_unrealize(BusState *qbus)
{
PCIBus *bus = PCI_BUS(qbus);
{
pci_bus_uninit(bus);
/* the caller of the unplug hotplug handler will delete this device */
- object_property_set_bool(OBJECT(bus), false, "realized", NULL);
+ object_property_set_bool(OBJECT(bus), false, "realized", &error_abort);
}
void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
pci_unregister_vga(pci_dev);
}
-static void pci_qdev_unrealize(DeviceState *dev, Error **errp)
+static void pci_qdev_unrealize(DeviceState *dev)
{
PCIDevice *pci_dev = PCI_DEVICE(dev);
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
error_setg(errp, "failover primary device must be on "
"PCIExpress bus");
error_propagate(errp, local_err);
- pci_qdev_unrealize(DEVICE(pci_dev), NULL);
+ pci_qdev_unrealize(DEVICE(pci_dev));
return;
}
class_id = pci_get_word(pci_dev->config + PCI_CLASS_DEVICE);
error_setg(errp, "failover primary device is not an "
"Ethernet device");
error_propagate(errp, local_err);
- pci_qdev_unrealize(DEVICE(pci_dev), NULL);
+ pci_qdev_unrealize(DEVICE(pci_dev));
return;
}
if (!(pci_dev->cap_present & QEMU_PCI_CAP_MULTIFUNCTION)
error_setg(errp, "failover: primary device must be in its own "
"PCI slot");
error_propagate(errp, local_err);
- pci_qdev_unrealize(DEVICE(pci_dev), NULL);
+ pci_qdev_unrealize(DEVICE(pci_dev));
return;
}
qdev->allow_unplug_during_migration = true;
pci_add_option_rom(pci_dev, is_default_rom, &local_err);
if (local_err) {
error_propagate(errp, local_err);
- pci_qdev_unrealize(DEVICE(pci_dev), NULL);
+ pci_qdev_unrealize(DEVICE(pci_dev));
return;
}
}
void pcie_cap_slot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
- object_property_set_bool(OBJECT(dev), false, "realized", NULL);
+ object_property_set_bool(OBJECT(dev), false, "realized", &error_abort);
}
static void pcie_unplug_device(PCIBus *bus, PCIDevice *dev, void *opaque)
void shpc_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
- object_property_set_bool(OBJECT(dev), false, "realized", NULL);
+ object_property_set_bool(OBJECT(dev), false, "realized", &error_abort);
}
void shpc_device_unplug_request_cb(HotplugHandler *hotplug_dev,
object_property_add_link(obj, "card", TYPE_PCMCIA_CARD,
(Object **)&s->card,
NULL, /* read-only property */
- 0, NULL);
+ 0);
}
/* Insert a new card into a slot */
const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(pms);
dev = qdev_create(NULL, TYPE_OPENPIC);
- object_property_add_child(OBJECT(machine), "pic", OBJECT(dev),
- &error_fatal);
+ object_property_add_child(OBJECT(machine), "pic", OBJECT(dev));
qdev_prop_set_uint32(dev, "model", pmc->mpic_version);
qdev_prop_set_uint32(dev, "nb_cpus", smp_cpus);
dev = qdev_create(NULL, "e500-ccsr");
object_property_add_child(qdev_get_machine(), "e500-ccsr",
- OBJECT(dev), NULL);
+ OBJECT(dev));
qdev_init_nofail(dev);
ccsr = CCSR(dev);
ccsr_addr_space = &ccsr->ccsr_space;
/* PCI */
dev = qdev_create(NULL, "e500-pcihost");
- object_property_add_child(qdev_get_machine(), "pci-host", OBJECT(dev),
- &error_abort);
+ object_property_add_child(qdev_get_machine(), "pci-host", OBJECT(dev));
qdev_prop_set_uint32(dev, "first_slot", pmc->pci_first_slot);
qdev_prop_set_uint32(dev, "first_pin_irq", pci_irq_nrs[0]);
qdev_init_nofail(dev);
qdev_prop_set_uint32(dev, "data_width", 1);
qdev_prop_set_bit(dev, "dma_enabled", false);
object_property_add_child(OBJECT(qdev_get_machine()), TYPE_FW_CFG,
- OBJECT(fw_cfg), NULL);
+ OBJECT(fw_cfg));
qdev_init_nofail(dev);
s = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(s, 0, CFG_ADDR);
/* Default via_config is CORE99_VIA_CONFIG_CUDA */
cms->via_config = CORE99_VIA_CONFIG_CUDA;
object_property_add_str(obj, "via", core99_get_via_config,
- core99_set_via_config, NULL);
+ core99_set_via_config);
object_property_set_description(obj, "via",
"Set VIA configuration. "
- "Valid values are cuda, pmu and pmu-adb",
- NULL);
+ "Valid values are cuda, pmu and pmu-adb");
return;
}
qdev_prop_set_uint32(dev, "data_width", 1);
qdev_prop_set_bit(dev, "dma_enabled", false);
object_property_add_child(OBJECT(qdev_get_machine()), TYPE_FW_CFG,
- OBJECT(fw_cfg), NULL);
+ OBJECT(fw_cfg));
qdev_init_nofail(dev);
s = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(s, 0, CFG_ADDR);
}
snprintf(chip_name, sizeof(chip_name), "chip[%d]", PNV_CHIP_HWID(i));
- object_property_add_child(OBJECT(pnv), chip_name, chip, &error_fatal);
+ object_property_add_child(OBJECT(pnv), chip_name, chip);
object_property_set_int(chip, PNV_CHIP_HWID(i), "chip-id",
&error_fatal);
object_property_set_int(chip, machine->smp.cores,
object_property_add_link(obj, "xics", TYPE_XICS_FABRIC,
(Object **)&chip8->xics,
object_property_allow_set_link,
- OBJ_PROP_LINK_STRONG,
- &error_abort);
+ OBJ_PROP_LINK_STRONG);
object_initialize_child(obj, "psi", &chip8->psi, sizeof(chip8->psi),
TYPE_PNV8_PSI, &error_abort, NULL);
object_initialize_child(obj, "xive", &chip9->xive, sizeof(chip9->xive),
TYPE_PNV_XIVE, &error_abort, NULL);
object_property_add_alias(obj, "xive-fabric", OBJECT(&chip9->xive),
- "xive-fabric", &error_abort);
+ "xive-fabric");
object_initialize_child(obj, "psi", &chip9->psi, sizeof(chip9->psi),
TYPE_PNV9_PSI, &error_abort, NULL);
pnv_core = PNV_CORE(object_new(typename));
snprintf(core_name, sizeof(core_name), "core[%d]", core_hwid);
- object_property_add_child(OBJECT(chip), core_name, OBJECT(pnv_core),
- &error_abort);
+ object_property_add_child(OBJECT(chip), core_name, OBJECT(pnv_core));
chip->cores[i] = pnv_core;
object_property_set_int(OBJECT(pnv_core), chip->nr_threads,
"nr-threads", &error_fatal);
nc->nmi_monitor_handler = pnv_nmi;
object_class_property_add_bool(oc, "hb-mode",
- pnv_machine_get_hb, pnv_machine_set_hb,
- &error_abort);
+ pnv_machine_get_hb, pnv_machine_set_hb);
object_class_property_set_description(oc, "hb-mode",
- "Use a hostboot like boot loader",
- NULL);
+ "Use a hostboot like boot loader");
}
#define DEFINE_PNV8_CHIP_TYPE(type, class_initfn) \
void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor)
{
object_ref(OBJECT(pnor));
- object_property_add_const_link(OBJECT(bmc), "pnor", OBJECT(pnor),
- &error_abort);
+ object_property_add_const_link(OBJECT(bmc), "pnor", OBJECT(pnor));
/* Install the HIOMAP protocol handlers to access the PNOR */
ipmi_sim_register_netfn(IPMI_BMC_SIMULATOR(bmc), IPMI_NETFN_OEM,
obj = object_new(TYPE_IPMI_BMC_SIMULATOR);
object_ref(OBJECT(pnor));
- object_property_add_const_link(obj, "pnor", OBJECT(pnor), &error_abort);
+ object_property_add_const_link(obj, "pnor", OBJECT(pnor));
object_property_set_bool(obj, true, "realized", &error_fatal);
/* Install the HIOMAP protocol handlers to access the PNOR */
pc->threads[i] = POWERPC_CPU(obj);
snprintf(name, sizeof(name), "thread[%d]", i);
- object_property_add_child(OBJECT(pc), name, obj, &error_abort);
+ object_property_add_child(OBJECT(pc), name, obj);
cpu->machine_data = g_new0(PnvCPUState, 1);
object_unparent(OBJECT(cpu));
}
-static void pnv_core_unrealize(DeviceState *dev, Error **errp)
+static void pnv_core_unrealize(DeviceState *dev)
{
PnvCore *pc = PNV_CORE(dev);
CPUCore *cc = CPU_CORE(dev);
object_initialize_child(obj, "ics-psi", &psi8->ics, sizeof(psi8->ics),
TYPE_ICS, &error_abort, NULL);
object_property_add_alias(obj, ICS_PROP_XICS, OBJECT(&psi8->ics),
- ICS_PROP_XICS, &error_abort);
+ ICS_PROP_XICS);
}
static const uint8_t irq_to_xivr[] = {
rtc_set_memory(rtc, 0x3f, checksum >> 8);
object_property_add_alias(qdev_get_machine(), "rtc-time", OBJECT(rtc),
- "date", NULL);
+ "date");
}
return 0;
}
qdev_prop_set_string(dev, "bios-name", bios_name);
qdev_prop_set_uint32(dev, "elf-machine", PPC_ELF_MACHINE);
pcihost = SYS_BUS_DEVICE(dev);
- object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev), NULL);
+ object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev));
qdev_init_nofail(dev);
pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci.0"));
if (!pci_bus) {
qdev_prop_set_uint32(dev, "data_width", 1);
qdev_prop_set_bit(dev, "dma_enabled", false);
object_property_add_child(OBJECT(qdev_get_machine()), TYPE_FW_CFG,
- OBJECT(fw_cfg), NULL);
+ OBJECT(fw_cfg));
qdev_init_nofail(dev);
s = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(s, 0, CFG_ADDR);
object_property_set_bool(OBJECT(&spapr->rtc), true, "realized",
&error_fatal);
object_property_add_alias(OBJECT(spapr), "rtc-time", OBJECT(&spapr->rtc),
- "date", &error_fatal);
+ "date");
}
/* Returns whether we want to use VGA or not */
spapr->htab_fd = -1;
spapr->use_hotplug_event_source = true;
object_property_add_str(obj, "kvm-type",
- spapr_get_kvm_type, spapr_set_kvm_type, NULL);
+ spapr_get_kvm_type, spapr_set_kvm_type);
object_property_set_description(obj, "kvm-type",
- "Specifies the KVM virtualization mode (HV, PR)",
- NULL);
+ "Specifies the KVM virtualization mode (HV, PR)");
object_property_add_bool(obj, "modern-hotplug-events",
spapr_get_modern_hotplug_events,
- spapr_set_modern_hotplug_events,
- NULL);
+ spapr_set_modern_hotplug_events);
object_property_set_description(obj, "modern-hotplug-events",
"Use dedicated hotplug event mechanism in"
" place of standard EPOW events when possible"
- " (required for memory hot-unplug support)",
- NULL);
+ " (required for memory hot-unplug support)");
ppc_compat_add_property(obj, "max-cpu-compat", &spapr->max_compat_pvr,
- "Maximum permitted CPU compatibility mode",
- &error_fatal);
+ "Maximum permitted CPU compatibility mode");
object_property_add_str(obj, "resize-hpt",
- spapr_get_resize_hpt, spapr_set_resize_hpt, NULL);
+ spapr_get_resize_hpt, spapr_set_resize_hpt);
object_property_set_description(obj, "resize-hpt",
- "Resizing of the Hash Page Table (enabled, disabled, required)",
- NULL);
+ "Resizing of the Hash Page Table (enabled, disabled, required)");
object_property_add_uint32_ptr(obj, "vsmt",
- &spapr->vsmt, OBJ_PROP_FLAG_READWRITE,
- &error_abort);
+ &spapr->vsmt, OBJ_PROP_FLAG_READWRITE);
object_property_set_description(obj, "vsmt",
"Virtual SMT: KVM behaves as if this were"
- " the host's SMT mode", &error_abort);
+ " the host's SMT mode");
object_property_add_bool(obj, "vfio-no-msix-emulation",
- spapr_get_msix_emulation, NULL, NULL);
+ spapr_get_msix_emulation, NULL);
object_property_add_uint64_ptr(obj, "kernel-addr",
- &spapr->kernel_addr, OBJ_PROP_FLAG_READWRITE,
- &error_abort);
+ &spapr->kernel_addr, OBJ_PROP_FLAG_READWRITE);
object_property_set_description(obj, "kernel-addr",
stringify(KERNEL_LOAD_ADDR)
- " for -kernel is the default",
- NULL);
+ " for -kernel is the default");
spapr->kernel_addr = KERNEL_LOAD_ADDR;
/* The machine class defines the default interrupt controller mode */
spapr->irq = smc->irq;
object_property_add_str(obj, "ic-mode", spapr_get_ic_mode,
- spapr_set_ic_mode, NULL);
+ spapr_set_ic_mode);
object_property_set_description(obj, "ic-mode",
- "Specifies the interrupt controller mode (xics, xive, dual)",
- NULL);
+ "Specifies the interrupt controller mode (xics, xive, dual)");
object_property_add_str(obj, "host-model",
- spapr_get_host_model, spapr_set_host_model,
- &error_abort);
+ spapr_get_host_model, spapr_set_host_model);
object_property_set_description(obj, "host-model",
- "Host model to advertise in guest device tree", &error_abort);
+ "Host model to advertise in guest device tree");
object_property_add_str(obj, "host-serial",
- spapr_get_host_serial, spapr_set_host_serial,
- &error_abort);
+ spapr_get_host_serial, spapr_set_host_serial);
object_property_set_description(obj, "host-serial",
- "Host serial number to advertise in guest device tree", &error_abort);
+ "Host serial number to advertise in guest device tree");
}
static void spapr_machine_finalizefn(Object *obj)
SpaprDimmState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev));
pc_dimm_unplug(PC_DIMM(dev), MACHINE(hotplug_dev));
- object_property_set_bool(OBJECT(dev), false, "realized", NULL);
+ object_property_set_bool(OBJECT(dev), false, "realized", &error_abort);
spapr_pending_dimm_unplugs_remove(spapr, ds);
}
assert(core_slot);
core_slot->cpu = NULL;
- object_property_set_bool(OBJECT(dev), false, "realized", NULL);
+ object_property_set_bool(OBJECT(dev), false, "realized", &error_abort);
}
static
/* hotplug hooks should check it's enabled before getting this far */
assert(drc);
- spapr_drc_attach(drc, DEVICE(dev), &local_err);
+ spapr_drc_attach(drc, dev, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
static void spapr_phb_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
{
- object_property_set_bool(OBJECT(dev), false, "realized", NULL);
+ object_property_set_bool(OBJECT(dev), false, "realized", &error_abort);
}
static void spapr_phb_unplug_request(HotplugHandler *hotplug_dev,
{
SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
- object_property_set_bool(OBJECT(dev), false, "realized", NULL);
+ object_property_set_bool(OBJECT(dev), false, "realized", &error_abort);
object_unparent(OBJECT(dev));
spapr->tpm_proxy = NULL;
}
smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON;
smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_ON;
smc->default_caps.caps[SPAPR_CAP_FWNMI] = SPAPR_CAP_ON;
- spapr_caps_add_properties(smc, &error_abort);
+ spapr_caps_add_properties(smc);
smc->irq = &spapr_irq_dual;
smc->dr_phb_enabled = true;
smc->linux_pci_probe = true;
}
}
-void spapr_caps_add_properties(SpaprMachineClass *smc, Error **errp)
+void spapr_caps_add_properties(SpaprMachineClass *smc)
{
- Error *local_err = NULL;
ObjectClass *klass = OBJECT_CLASS(smc);
int i;
object_class_property_add(klass, name, cap->type,
cap->get, cap->set,
- NULL, cap, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(name);
- return;
- }
+ NULL, cap);
desc = g_strdup_printf("%s", cap->description);
- object_class_property_set_description(klass, name, desc, &local_err);
+ object_class_property_set_description(klass, name, desc);
g_free(name);
g_free(desc);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
}
}
spapr_cpu_core_reset(opaque);
}
-static void spapr_cpu_core_unrealize(DeviceState *dev, Error **errp)
+static void spapr_cpu_core_unrealize(DeviceState *dev)
{
SpaprCpuCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
CPUCore *cc = CPU_CORE(dev);
cpu->node_id = sc->node_id;
id = g_strdup_printf("thread[%d]", i);
- object_property_add_child(OBJECT(sc), id, obj, &local_err);
+ object_property_add_child(OBJECT(sc), id, obj);
g_free(id);
- if (local_err) {
- goto err;
- }
cpu->machine_data = g_new0(SpaprCpuState, 1);
object_property_add_link(OBJECT(drc), "device",
object_get_typename(OBJECT(drc->dev)),
(Object **)(&drc->dev),
- NULL, 0, NULL);
+ NULL, 0);
}
static void spapr_drc_release(SpaprDrc *drc)
g_free(drc->fdt);
drc->fdt = NULL;
drc->fdt_start_offset = 0;
- object_property_del(OBJECT(drc), "device", &error_abort);
+ object_property_del(OBJECT(drc), "device");
drc->dev = NULL;
}
SpaprDrc *drc = SPAPR_DR_CONNECTOR(d);
Object *root_container;
gchar *link_name;
- gchar *child_name;
- Error *err = NULL;
+ char *child_name;
trace_spapr_drc_realize(spapr_drc_index(drc));
/* NOTE: we do this as part of realize/unrealize due to the fact
child_name = object_get_canonical_path_component(OBJECT(drc));
trace_spapr_drc_realize_child(spapr_drc_index(drc), child_name);
object_property_add_alias(root_container, link_name,
- drc->owner, child_name, &err);
+ drc->owner, child_name);
g_free(child_name);
g_free(link_name);
- if (err) {
- error_propagate(errp, err);
- return;
- }
vmstate_register(VMSTATE_IF(drc), spapr_drc_index(drc), &vmstate_spapr_drc,
drc);
trace_spapr_drc_realize_complete(spapr_drc_index(drc));
}
-static void unrealize(DeviceState *d, Error **errp)
+static void unrealize(DeviceState *d)
{
SpaprDrc *drc = SPAPR_DR_CONNECTOR(d);
Object *root_container;
vmstate_unregister(VMSTATE_IF(drc), &vmstate_spapr_drc, drc);
root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
name = g_strdup_printf("%x", spapr_drc_index(drc));
- object_property_del(root_container, name, errp);
+ object_property_del(root_container, name);
g_free(name);
}
drc->owner = owner;
prop_name = g_strdup_printf("dr-connector[%"PRIu32"]",
spapr_drc_index(drc));
- object_property_add_child(owner, prop_name, OBJECT(drc), &error_abort);
+ object_property_add_child(owner, prop_name, OBJECT(drc));
object_unref(OBJECT(drc));
object_property_set_bool(OBJECT(drc), true, "realized", NULL);
g_free(prop_name);
SpaprDrc *drc = SPAPR_DR_CONNECTOR(obj);
SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
- object_property_add_uint32_ptr(obj, "id", &drc->id, OBJ_PROP_FLAG_READ,
- NULL);
+ object_property_add_uint32_ptr(obj, "id", &drc->id, OBJ_PROP_FLAG_READ);
object_property_add(obj, "index", "uint32", prop_get_index,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL);
object_property_add(obj, "fdt", "struct", prop_get_fdt,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL);
drc->state = drck->empty_state;
}
qemu_register_reset(drc_physical_reset, drcp);
}
-static void unrealize_physical(DeviceState *d, Error **errp)
+static void unrealize_physical(DeviceState *d)
{
SpaprDrcPhysical *drcp = SPAPR_DRC_PHYSICAL(d);
- Error *local_err = NULL;
-
- unrealize(d, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
+ unrealize(d);
vmstate_unregister(VMSTATE_IF(drcp), &vmstate_spapr_drc_physical, drcp);
qemu_unregister_reset(drc_physical_reset, drcp);
}
tcet->liobn = liobn;
tmp = g_strdup_printf("tce-table-%x", liobn);
- object_property_add_child(OBJECT(owner), tmp, OBJECT(tcet), NULL);
+ object_property_add_child(OBJECT(owner), tmp, OBJECT(tcet));
g_free(tmp);
object_unref(OBJECT(tcet));
tcet->nb_table = 0;
}
-static void spapr_tce_table_unrealize(DeviceState *dev, Error **errp)
+static void spapr_tce_table_unrealize(DeviceState *dev)
{
SpaprTceTable *tcet = SPAPR_TCE_TABLE(dev);
obj = object_new(TYPE_ICS_SPAPR);
- object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort);
+ object_property_add_child(OBJECT(spapr), "ics", obj);
object_property_set_link(obj, OBJECT(spapr), ICS_PROP_XICS,
&error_abort);
object_property_set_int(obj, smc->nr_xirqs, "nr-irqs", &error_abort);
drc_id_from_devfn(phb, chassis, devfn));
}
-static uint8_t chassis_from_bus(PCIBus *bus, Error **errp)
+static uint8_t chassis_from_bus(PCIBus *bus)
{
if (pci_bus_is_root(bus)) {
return 0;
} else {
PCIDevice *bridge = pci_bridge_get_device(bus);
- return object_property_get_uint(OBJECT(bridge), "chassis_nr", errp);
+ return object_property_get_uint(OBJECT(bridge), "chassis_nr",
+ &error_abort);
}
}
static SpaprDrc *drc_from_dev(SpaprPhbState *phb, PCIDevice *dev)
{
- Error *local_err = NULL;
- uint8_t chassis = chassis_from_bus(pci_get_bus(dev), &local_err);
-
- if (local_err) {
- error_report_err(local_err);
- return NULL;
- }
+ uint8_t chassis = chassis_from_bus(pci_get_bus(dev));
return drc_from_devfn(phb, chassis, dev->devfn);
}
-static void add_drcs(SpaprPhbState *phb, PCIBus *bus, Error **errp)
+static void add_drcs(SpaprPhbState *phb, PCIBus *bus)
{
Object *owner;
int i;
uint8_t chassis;
- Error *local_err = NULL;
if (!phb->dr_enabled) {
return;
}
- chassis = chassis_from_bus(bus, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
+ chassis = chassis_from_bus(bus);
if (pci_bus_is_root(bus)) {
owner = OBJECT(phb);
}
}
-static void remove_drcs(SpaprPhbState *phb, PCIBus *bus, Error **errp)
+static void remove_drcs(SpaprPhbState *phb, PCIBus *bus)
{
int i;
uint8_t chassis;
- Error *local_err = NULL;
if (!phb->dr_enabled) {
return;
}
- chassis = chassis_from_bus(bus, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
+ chassis = chassis_from_bus(bus);
for (i = PCI_SLOT_MAX * PCI_FUNC_MAX - 1; i >= 0; i--) {
SpaprDrc *drc = drc_from_devfn(phb, chassis, i);
}
static void spapr_pci_bridge_plug(SpaprPhbState *phb,
- PCIBridge *bridge,
- Error **errp)
+ PCIBridge *bridge)
{
- Error *local_err = NULL;
PCIBus *bus = pci_bridge_get_sec_bus(bridge);
- add_drcs(phb, bus, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
+ add_drcs(phb, bus);
}
static void spapr_pci_plug(HotplugHandler *plug_handler,
g_assert(drc);
if (pc->is_bridge) {
- spapr_pci_bridge_plug(phb, PCI_BRIDGE(plugged_dev), &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
+ spapr_pci_bridge_plug(phb, PCI_BRIDGE(plugged_dev));
}
/* Following the QEMU convention used for PCIe multifunction
spapr_drc_reset(drc);
} else if (PCI_FUNC(pdev->devfn) == 0) {
int i;
- uint8_t chassis = chassis_from_bus(pci_get_bus(pdev), &local_err);
-
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
+ uint8_t chassis = chassis_from_bus(pci_get_bus(pdev));
for (i = 0; i < 8; i++) {
SpaprDrc *func_drc;
}
static void spapr_pci_bridge_unplug(SpaprPhbState *phb,
- PCIBridge *bridge,
- Error **errp)
+ PCIBridge *bridge)
{
- Error *local_err = NULL;
PCIBus *bus = pci_bridge_get_sec_bus(bridge);
- remove_drcs(phb, bus, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
+ remove_drcs(phb, bus);
}
static void spapr_pci_unplug(HotplugHandler *plug_handler,
pci_device_reset(PCI_DEVICE(plugged_dev));
if (pc->is_bridge) {
- Error *local_err = NULL;
- spapr_pci_bridge_unplug(phb, PCI_BRIDGE(plugged_dev), &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- }
+ spapr_pci_bridge_unplug(phb, PCI_BRIDGE(plugged_dev));
return;
}
- object_property_set_bool(OBJECT(plugged_dev), false, "realized", NULL);
+ object_property_set_bool(OBJECT(plugged_dev), false, "realized",
+ &error_abort);
}
static void spapr_pci_unplug_request(HotplugHandler *plug_handler,
SpaprDrcClass *func_drck;
SpaprDREntitySense state;
int i;
- Error *local_err = NULL;
- uint8_t chassis = chassis_from_bus(pci_get_bus(pdev), &local_err);
-
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
+ uint8_t chassis = chassis_from_bus(pci_get_bus(pdev));
if (pc->is_bridge) {
error_setg(errp, "PCI: Hot unplug of PCI bridges not supported");
sphb->dtbusname = NULL;
}
-static void spapr_phb_unrealize(DeviceState *dev, Error **errp)
+static void spapr_phb_unrealize(DeviceState *dev)
{
SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
SysBusDevice *s = SYS_BUS_DEVICE(dev);
SpaprTceTable *tcet;
int i;
const unsigned windows_supported = spapr_phb_windows_supported(sphb);
- Error *local_err = NULL;
spapr_phb_nvgpu_free(sphb);
}
}
- remove_drcs(sphb, phb->bus, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
+ remove_drcs(sphb, phb->bus);
for (i = PCI_NUM_PINS - 1; i >= 0; i--) {
if (sphb->lsi_table[i].irq) {
}
/* allocate connectors for child PCI devices */
- add_drcs(sphb, phb->bus, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- goto unrealize;
- }
+ add_drcs(sphb, phb->bus);
/* DMA setup */
for (i = 0; i < windows_supported; ++i) {
return;
unrealize:
- spapr_phb_unrealize(dev, NULL);
+ spapr_phb_unrealize(dev);
}
static int spapr_phb_children_reset(Object *child, void *opaque)
}
object_property_set_description(obj, "rng",
- "ID of the random number generator backend",
- NULL);
+ "ID of the random number generator backend");
}
static void spapr_rng_realize(DeviceState *dev, Error **errp)
rtc_ns = qemu_clock_get_ns(rtc_clock);
rtc->ns_offset = host_s * NANOSECONDS_PER_SECOND - rtc_ns;
- object_property_add_tm(OBJECT(rtc), "date", spapr_rtc_qom_date, NULL);
+ object_property_add_tm(OBJECT(rtc), "date", spapr_rtc_qom_date);
}
static const VMStateDescription vmstate_spapr_rtc = {
qemu_register_reset(spapr_tpm_proxy_reset, tpm_proxy);
}
-static void spapr_tpm_proxy_unrealize(DeviceState *d, Error **errp)
+static void spapr_tpm_proxy_unrealize(DeviceState *d)
{
SpaprTpmProxy *tpm_proxy = SPAPR_TPM_PROXY(d);
SiFiveUState *s = RISCV_U_MACHINE(obj);
s->start_in_flash = false;
- object_property_add_bool(obj, "start-in-flash", sifive_u_machine_get_start_in_flash,
- sifive_u_machine_set_start_in_flash, NULL);
+ object_property_add_bool(obj, "start-in-flash",
+ sifive_u_machine_get_start_in_flash,
+ sifive_u_machine_set_start_in_flash);
object_property_set_description(obj, "start-in-flash",
"Set on to tell QEMU's ROM to jump to "
- "flash. Otherwise QEMU will jump to DRAM",
- NULL);
+ "flash. Otherwise QEMU will jump to DRAM");
s->serial = OTP_SERIAL;
- object_property_add(obj, "serial", "uint32", sifive_u_machine_get_serial,
- sifive_u_machine_set_serial, NULL, &s->serial, NULL);
- object_property_set_description(obj, "serial", "Board serial number", NULL);
+ object_property_add(obj, "serial", "uint32",
+ sifive_u_machine_get_serial,
+ sifive_u_machine_set_serial, NULL, &s->serial);
+ object_property_set_description(obj, "serial", "Board serial number");
}
static void sifive_u_machine_class_init(ObjectClass *oc, void *data)
qdev_prop_set_uint16(dev, "id3", 0x00);
qdev_prop_set_string(dev, "name", name);
- object_property_add_child(OBJECT(s), name, OBJECT(dev),
- &error_abort);
+ object_property_add_child(OBJECT(s), name, OBJECT(dev));
object_property_add_alias(OBJECT(s), alias_prop_name,
- OBJECT(dev), "drive", &error_abort);
+ OBJECT(dev), "drive");
return PFLASH_CFI01(dev);
}
qdev_set_legacy_instance_id(dev, RTC_ISA_BASE, 3);
qemu_register_reset(rtc_reset, s);
- object_property_add_tm(OBJECT(s), "date", rtc_get_date, NULL);
+ object_property_add_tm(OBJECT(s), "date", rtc_get_date);
qdev_init_gpio_out(dev, &s->irq, 1);
QLIST_INSERT_HEAD(&rtc_devices, s, link);
}
object_property_add_alias(qdev_get_machine(), "rtc-time", OBJECT(isadev),
- "date", NULL);
+ "date");
return isadev;
}
/* Create bridge device */
dev = qdev_create(NULL, TYPE_AP_BRIDGE);
object_property_add_child(qdev_get_machine(), TYPE_AP_BRIDGE,
- OBJECT(dev), NULL);
+ OBJECT(dev));
qdev_init_nofail(dev);
/* Create bus on bridge device */
css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, 1, 0);
- object_property_set_bool(OBJECT(dev), false, "realized", NULL);
+ object_property_set_bool(OBJECT(dev), false, "realized", &error_abort);
}
static void virtual_css_bus_reset(BusState *qbus)
/* Create bridge device */
dev = qdev_create(NULL, TYPE_VIRTUAL_CSS_BRIDGE);
object_property_add_child(qdev_get_machine(), TYPE_VIRTUAL_CSS_BRIDGE,
- OBJECT(dev), NULL);
+ OBJECT(dev));
qdev_init_nofail(dev);
/* Create bus on bridge device */
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
device_class_set_props(dc, virtual_css_bridge_properties);
object_class_property_add_bool(klass, "cssid-unrestricted",
- prop_get_true, NULL, NULL);
+ prop_get_true, NULL);
object_class_property_set_description(klass, "cssid-unrestricted",
"A css device can use any cssid, regardless whether virtual"
- " or not (read only, always true)",
- NULL);
+ " or not (read only, always true)");
}
static const TypeInfo virtual_css_bridge_info = {
event_facility->allow_all_mask_sizes = true;
object_property_add_bool(obj, "allow_all_mask_sizes",
sclp_event_get_allow_all_mask_sizes,
- sclp_event_set_allow_all_mask_sizes, NULL);
+ sclp_event_set_allow_all_mask_sizes);
/* Spawn a new bus for SCLP events */
qbus_create_inplace(&event_facility->sbus, sizeof(event_facility->sbus),
TYPE_SCLP_EVENTS_BUS, sdev, NULL);
new = object_new(TYPE_SCLP_QUIESCE);
- object_property_add_child(obj, TYPE_SCLP_QUIESCE, new, NULL);
+ object_property_add_child(obj, TYPE_SCLP_QUIESCE, new);
object_unref(new);
qdev_set_parent_bus(DEVICE(new), BUS(&event_facility->sbus));
new = object_new(TYPE_SCLP_CPU_HOTPLUG);
- object_property_add_child(obj, TYPE_SCLP_CPU_HOTPLUG, new, NULL);
+ object_property_add_child(obj, TYPE_SCLP_CPU_HOTPLUG, new);
object_unref(new);
qdev_set_parent_bus(DEVICE(new), BUS(&event_facility->sbus));
/* the facility will automatically realize the devices via the bus */
error_propagate(errp, err);
}
-static void s390_ccw_unrealize(S390CCWDevice *cdev, Error **errp)
+static void s390_ccw_unrealize(S390CCWDevice *cdev)
{
CcwDevice *ccw_dev = CCW_DEVICE(cdev);
SubchDev *sch = ccw_dev->sch;
S390CCWDevice *dev = S390_CCW_DEVICE(obj);
device_add_bootindex_property(obj, &dev->bootindex, "bootindex",
- "/disk@0,0", DEVICE(obj), NULL);
+ "/disk@0,0", DEVICE(obj));
}
static void s390_ccw_class_init(ObjectClass *klass, void *data)
pbdev->fh, pbdev->fid);
bus = pci_get_bus(pci_dev);
devfn = pci_dev->devfn;
- object_property_set_bool(OBJECT(dev), false, "realized", NULL);
+ object_property_set_bool(OBJECT(dev), false, "realized", &error_abort);
s390_pci_msix_free(pbdev);
s390_pci_iommu_free(s, bus, devfn);
pbdev->fid = 0;
QTAILQ_REMOVE(&s->zpci_devs, pbdev, link);
g_hash_table_remove(s->zpci_table, &pbdev->idx);
- object_property_set_bool(OBJECT(dev), false, "realized", NULL);
+ object_property_set_bool(OBJECT(dev), false, "realized", &error_abort);
}
}
obj = object_new(TYPE_QEMU_S390_SKEYS);
}
object_property_add_child(qdev_get_machine(), TYPE_S390_SKEYS,
- obj, NULL);
+ obj);
object_unref(obj);
qdev_init_nofail(DEVICE(obj));
{
object_property_add_bool(obj, "migration-enabled",
s390_skeys_get_migration_enabled,
- s390_skeys_set_migration_enabled, NULL);
+ s390_skeys_set_migration_enabled);
object_property_set_bool(obj, true, "migration-enabled", NULL);
}
}
object_property_add_child(qdev_get_machine(), TYPE_S390_STATTRIB,
- obj, NULL);
+ obj);
object_unref(obj);
qdev_init_nofail(DEVICE(obj));
object_property_add_bool(obj, "migration-enabled",
s390_stattrib_get_migration_enabled,
- s390_stattrib_set_migration_enabled, NULL);
+ s390_stattrib_set_migration_enabled);
object_property_set_bool(obj, true, "migration-enabled", NULL);
sas->migration_cur_gfn = 0;
}
}
g_free(netboot_fw_prop);
object_property_add_child(qdev_get_machine(), TYPE_S390_IPL,
- new, NULL);
+ new);
object_unref(new);
qdev_init_nofail(dev);
}
dev = qdev_create(NULL, TYPE_S390_PCI_HOST_BRIDGE);
object_property_add_child(qdev_get_machine(), TYPE_S390_PCI_HOST_BRIDGE,
- OBJECT(dev), NULL);
+ OBJECT(dev));
qdev_init_nofail(dev);
/* register hypercalls */
{
object_property_add_bool(obj, "aes-key-wrap",
machine_get_aes_key_wrap,
- machine_set_aes_key_wrap, NULL);
+ machine_set_aes_key_wrap);
object_property_set_description(obj, "aes-key-wrap",
- "enable/disable AES key wrapping using the CPACF wrapping key",
- NULL);
+ "enable/disable AES key wrapping using the CPACF wrapping key");
object_property_set_bool(obj, true, "aes-key-wrap", NULL);
object_property_add_bool(obj, "dea-key-wrap",
machine_get_dea_key_wrap,
- machine_set_dea_key_wrap, NULL);
+ machine_set_dea_key_wrap);
object_property_set_description(obj, "dea-key-wrap",
- "enable/disable DEA key wrapping using the CPACF wrapping key",
- NULL);
+ "enable/disable DEA key wrapping using the CPACF wrapping key");
object_property_set_bool(obj, true, "dea-key-wrap", NULL);
object_property_add_str(obj, "loadparm",
- machine_get_loadparm, machine_set_loadparm, NULL);
+ machine_get_loadparm, machine_set_loadparm);
object_property_set_description(obj, "loadparm",
"Up to 8 chars in set of [A-Za-z0-9. ] (lower case chars converted"
" to upper case) to pass to machine loader, boot manager,"
- " and guest kernel",
- NULL);
+ " and guest kernel");
}
static const TypeInfo ccw_machine_info = {
{
Object *new = object_new(TYPE_SCLP);
- object_property_add_child(qdev_get_machine(), TYPE_SCLP, new,
- NULL);
- object_unref(OBJECT(new));
+ object_property_add_child(qdev_get_machine(), TYPE_SCLP, new);
+ object_unref(new);
qdev_init_nofail(DEVICE(new));
}
Object *new;
new = object_new(TYPE_SCLP_EVENT_FACILITY);
- object_property_add_child(obj, TYPE_SCLP_EVENT_FACILITY, new, NULL);
+ object_property_add_child(obj, TYPE_SCLP_EVENT_FACILITY, new);
object_unref(new);
sclp->event_facility = EVENT_FACILITY(new);
} else {
obj = object_new(TYPE_QEMU_S390_TOD);
}
- object_property_add_child(qdev_get_machine(), TYPE_S390_TOD, obj, NULL);
+ object_property_add_child(qdev_get_machine(), TYPE_S390_TOD, obj);
object_unref(obj);
qdev_init_nofail(DEVICE(obj));
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_BALLOON);
object_property_add_alias(obj, "guest-stats", OBJECT(&dev->vdev),
- "guest-stats", &error_abort);
+ "guest-stats");
object_property_add_alias(obj, "guest-stats-polling-interval",
OBJECT(&dev->vdev),
- "guest-stats-polling-interval", &error_abort);
+ "guest-stats-polling-interval");
}
static Property virtio_ccw_balloon_properties[] = {
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_BLK);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
- "bootindex", &error_abort);
+ "bootindex");
}
static Property virtio_ccw_blk_properties[] = {
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_NET);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
- "bootindex", &error_abort);
+ "bootindex");
}
static Property virtio_ccw_net_properties[] = {
g_free(sch);
}
-static void virtio_ccw_device_unrealize(VirtioCcwDevice *dev, Error **errp)
+static void virtio_ccw_device_unrealize(VirtioCcwDevice *dev)
{
VirtIOCCWDeviceClass *dc = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
CcwDevice *ccw_dev = CCW_DEVICE(dev);
SubchDev *sch = ccw_dev->sch;
if (dc->unrealize) {
- dc->unrealize(dev, errp);
+ dc->unrealize(dev);
}
if (sch) {
virtio_ccw_device_realize(_dev, errp);
}
-static void virtio_ccw_busdev_unrealize(DeviceState *dev, Error **errp)
+static void virtio_ccw_busdev_unrealize(DeviceState *dev)
{
VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
- virtio_ccw_device_unrealize(_dev, errp);
+ virtio_ccw_device_unrealize(_dev);
}
static void virtio_ccw_busdev_unplug(HotplugHandler *hotplug_dev,
typedef struct VirtIOCCWDeviceClass {
CCWDeviceClass parent_class;
void (*realize)(VirtioCcwDevice *dev, Error **errp);
- void (*unrealize)(VirtioCcwDevice *dev, Error **errp);
+ void (*unrealize)(VirtioCcwDevice *dev);
void (*parent_reset)(DeviceState *dev);
} VirtIOCCWDeviceClass;
scsi_bus_new(&s->bus, sizeof(s->bus), d, &lsi_scsi_info, NULL);
}
-static void lsi_scsi_unrealize(DeviceState *dev, Error **errp)
+static void lsi_scsi_unrealize(DeviceState *dev)
{
LSIState *s = LSI53C895A(dev);
}
}
-static void scsi_device_unrealize(SCSIDevice *s, Error **errp)
+static void scsi_device_unrealize(SCSIDevice *s)
{
SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s);
if (sc->unrealize) {
- sc->unrealize(s, errp);
+ sc->unrealize(s);
}
}
scsi_dma_restart_cb, dev);
}
-static void scsi_qdev_unrealize(DeviceState *qdev, Error **errp)
+static void scsi_qdev_unrealize(DeviceState *qdev)
{
SCSIDevice *dev = SCSI_DEVICE(qdev);
- Error *local_err = NULL;
if (dev->vmsentry) {
qemu_del_vm_change_state_handler(dev->vmsentry);
scsi_device_purge_requests(dev, SENSE_CODE(NO_SENSE));
- scsi_device_unrealize(dev, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
+ scsi_device_unrealize(dev);
blockdev_mark_auto_del(dev->conf.blk);
}
}
dev = qdev_create(&bus->qbus, driver);
name = g_strdup_printf("legacy[%d]", unit);
- object_property_add_child(OBJECT(bus), name, OBJECT(dev), NULL);
+ object_property_add_child(OBJECT(bus), name, OBJECT(dev));
g_free(name);
qdev_prop_set_uint32(dev, "scsi-id", unit);
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", NULL,
- &s->qdev, NULL);
+ &s->qdev);
}
static const TypeInfo scsi_device_type_info = {
dev->conf.lsecs);
}
-static void scsi_unrealize(SCSIDevice *dev, Error **errp)
+static void scsi_unrealize(SCSIDevice *dev)
{
del_boot_device_lchs(&dev->qdev, NULL);
}
return;
}
-static void vhost_scsi_unrealize(DeviceState *dev, Error **errp)
+static void vhost_scsi_unrealize(DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VHostSCSICommon *vsc = VHOST_SCSI_COMMON(dev);
vsc->feature_bits = kernel_feature_bits;
device_add_bootindex_property(obj, &vsc->bootindex, "bootindex", NULL,
- DEVICE(vsc), NULL);
+ DEVICE(vsc));
}
static const TypeInfo vhost_scsi_info = {
virtio_scsi_common_unrealize(dev);
}
-static void vhost_user_scsi_unrealize(DeviceState *dev, Error **errp)
+static void vhost_user_scsi_unrealize(DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VHostUserSCSI *s = VHOST_USER_SCSI(dev);
/* Add the bootindex property for this object */
device_add_bootindex_property(obj, &vsc->bootindex, "bootindex", NULL,
- DEVICE(vsc), NULL);
+ DEVICE(vsc));
}
static const TypeInfo vhost_user_scsi_info = {
virtio_cleanup(vdev);
}
-static void virtio_scsi_device_unrealize(DeviceState *dev, Error **errp)
+static void virtio_scsi_device_unrealize(DeviceState *dev)
{
VirtIOSCSI *s = VIRTIO_SCSI(dev);
void sdhci_initfn(SDHCIState *s);
void sdhci_uninitfn(SDHCIState *s);
void sdhci_common_realize(SDHCIState *s, Error **errp);
-void sdhci_common_unrealize(SDHCIState *s, Error **errp);
+void sdhci_common_unrealize(SDHCIState *s);
void sdhci_common_class_init(ObjectClass *klass, void *data);
#endif
{
SDHCIState *s = PCI_SDHCI(dev);
- sdhci_common_unrealize(s, &error_abort);
+ sdhci_common_unrealize(s);
sdhci_uninitfn(s);
}
SDHC_REGISTERS_MAP_SIZE);
}
-void sdhci_common_unrealize(SDHCIState *s, Error **errp)
+void sdhci_common_unrealize(SDHCIState *s)
{
/* This function is expected to be called only once for each class:
* - SysBus: via DeviceClass->unrealize(),
sysbus_init_mmio(sbd, &s->iomem);
}
-static void sdhci_sysbus_unrealize(DeviceState *dev, Error **errp)
+static void sdhci_sysbus_unrealize(DeviceState *dev)
{
SDHCIState *s = SYSBUS_SDHCI(dev);
- sdhci_common_unrealize(s, &error_abort);
+ sdhci_common_unrealize(s);
if (s->dma_mr) {
address_space_destroy(s->dma_as);
for (i = 0; i < 4; i++) {
sysbus_init_irq(sbd, &s->irq[i]);
}
- phb->bus = pci_register_root_bus(DEVICE(dev), "pci",
+ phb->bus = pci_register_root_bus(dev, "pci",
sh_pci_set_irq, sh_pci_map_irq,
s->irq,
get_system_memory(),
object_property_add_link(obj, "memdev", TYPE_MEMORY_BACKEND,
(Object **)&d->memdev,
object_property_allow_set_link,
- OBJ_PROP_LINK_STRONG, &error_abort);
+ OBJ_PROP_LINK_STRONG);
object_property_set_description(obj, "memdev", "Set RAM backend"
- "Valid value is ID of a hostmem backend",
- &error_abort);
+ "Valid value is ID of a hostmem backend");
}
static void ram_class_init(ObjectClass *klass, void *data)
qdev_prop_set_uint32(dev, "data_width", 1);
qdev_prop_set_bit(dev, "dma_enabled", false);
object_property_add_child(OBJECT(qdev_get_machine()), TYPE_FW_CFG,
- OBJECT(fw_cfg), NULL);
+ OBJECT(fw_cfg));
qdev_init_nofail(dev);
s = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(s, 0, CFG_ADDR);
dev = qdev_create(NULL, TYPE_FW_CFG_IO);
qdev_prop_set_bit(dev, "dma_enabled", false);
- object_property_add_child(OBJECT(ebus), TYPE_FW_CFG, OBJECT(dev), NULL);
+ object_property_add_child(OBJECT(ebus), TYPE_FW_CFG, OBJECT(dev));
qdev_init_nofail(dev);
memory_region_add_subregion(pci_address_space_io(ebus), BIOS_CFG_IOPORT,
&FW_CFG_IO(dev)->comb_iomem);
memcpy(rq->dma_buf, rxd, num);
- ret = stream_push(rq->dma, rq->dma_buf, num);
+ ret = stream_push(rq->dma, rq->dma_buf, num, false);
assert(ret == num);
xlnx_zynqmp_qspips_check_flush(rq);
}
object_property_add_link(obj, "stream-connected-dma", TYPE_STREAM_SLAVE,
(Object **)&rq->dma,
object_property_allow_set_link,
- OBJ_PROP_LINK_STRONG,
- NULL);
+ OBJ_PROP_LINK_STRONG);
}
static int xilinx_spips_post_load(void *opaque, int version_id)
static char *usb_get_dev_path(DeviceState *dev);
static char *usb_get_fw_dev_path(DeviceState *qdev);
-static void usb_qdev_unrealize(DeviceState *qdev, Error **errp);
+static void usb_qdev_unrealize(DeviceState *qdev);
static Property usb_props[] = {
DEFINE_PROP_STRING("port", USBDevice, port_path),
return NULL;
}
-static void usb_device_unrealize(USBDevice *dev, Error **errp)
+static void usb_device_unrealize(USBDevice *dev)
{
USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
if (klass->unrealize) {
- klass->unrealize(dev, errp);
+ klass->unrealize(dev);
}
}
if (dev->auto_attach) {
usb_device_attach(dev, &local_err);
if (local_err) {
- usb_qdev_unrealize(qdev, NULL);
+ usb_qdev_unrealize(qdev);
error_propagate(errp, local_err);
return;
}
}
}
-static void usb_qdev_unrealize(DeviceState *qdev, Error **errp)
+static void usb_qdev_unrealize(DeviceState *qdev)
{
USBDevice *dev = USB_DEVICE(qdev);
USBDescString *s, *next;
if (dev->attached) {
usb_device_detach(dev);
}
- usb_device_unrealize(dev, errp);
+ usb_device_unrealize(dev);
if (dev->port) {
usb_release_port(dev);
}
if (klass->attached_settable) {
object_property_add_bool(obj, "attached",
- usb_get_attached, usb_set_attached,
- NULL);
+ usb_get_attached, usb_set_attached);
} else {
object_property_add_bool(obj, "attached",
- usb_get_attached, NULL,
- NULL);
+ usb_get_attached, NULL);
}
}
qemu_mutex_destroy(&card->event_list_mutex);
}
-static void emulated_unrealize(CCIDCardState *base, Error **errp)
+static void emulated_unrealize(CCIDCardState *base)
{
EmulatedState *card = EMULATED_CCID_CARD(base);
VEvent *vevent = vevent_new(VEVENT_LAST, NULL, NULL);
const uint8_t *apdu,
uint32_t len);
void (*realize)(CCIDCardState *card, Error **errp);
- void (*unrealize)(CCIDCardState *card, Error **errp);
+ void (*unrealize)(CCIDCardState *card);
} CCIDCardClass;
/*
}
}
-static void usb_audio_unrealize(USBDevice *dev, Error **errp)
+static void usb_audio_unrealize(USBDevice *dev)
{
USBAudioState *s = USB_AUDIO(dev);
}
}
-static void usb_hid_unrealize(USBDevice *dev, Error **errp)
+static void usb_hid_unrealize(USBDevice *dev)
{
USBHIDState *us = USB_HID(dev);
}
}
-static void usb_hub_unrealize(USBDevice *dev, Error **errp)
+static void usb_hub_unrealize(USBDevice *dev)
{
USBHubState *s = (USBHubState *)dev;
int i;
s->nic = NULL;
}
-static void usb_net_unrealize(USBDevice *dev, Error **errp)
+static void usb_net_unrealize(USBDevice *dev)
{
USBNetState *s = (USBNetState *) dev;
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
- &dev->qdev, NULL);
+ &dev->qdev);
}
static const VMStateDescription vmstate_usb_net = {
}
}
-static void ccid_unrealize(USBDevice *dev, Error **errp)
+static void ccid_unrealize(USBDevice *dev)
{
USBCCIDState *s = USB_CCID_DEV(dev);
ccid_on_slot_change(s, true);
}
-static void ccid_card_unrealize(DeviceState *qdev, Error **errp)
+static void ccid_card_unrealize(DeviceState *qdev)
{
CCIDCardState *card = CCID_CARD(qdev);
CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
USBCCIDState *s = USB_CCID_DEV(dev);
- Error *local_err = NULL;
if (ccid_card_inserted(s)) {
ccid_card_card_removed(card);
}
if (cc->unrealize) {
- cc->unrealize(card, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
+ cc->unrealize(card);
}
s->card = NULL;
}
{
object_property_add(obj, "bootindex", "int32",
usb_msd_get_bootindex,
- usb_msd_set_bootindex, NULL, NULL, NULL);
+ usb_msd_set_bootindex, NULL, NULL);
object_property_set_int(obj, -1, "bootindex", NULL);
}
}
}
-static void usb_uas_unrealize(USBDevice *dev, Error **errp)
+static void usb_uas_unrealize(USBDevice *dev)
{
UASDevice *uas = USB_UAS(dev);
}
}
-static void usb_wacom_unrealize(USBDevice *dev, Error **errp)
+static void usb_wacom_unrealize(USBDevice *dev)
{
USBWacomState *s = (USBWacomState *) dev;
EHCIPCIState *i = PCI_EHCI(dev);
EHCIState *s = &i->ehci;
- usb_ehci_unrealize(s, DEVICE(dev), NULL);
+ usb_ehci_unrealize(s, DEVICE(dev));
g_free(s->irq);
s->irq = NULL;
s->vmstate = qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s);
}
-void usb_ehci_unrealize(EHCIState *s, DeviceState *dev, Error **errp)
+void usb_ehci_unrealize(EHCIState *s, DeviceState *dev)
{
trace_usb_ehci_unrealize();
void usb_ehci_init(EHCIState *s, DeviceState *dev);
void usb_ehci_finalize(EHCIState *s);
void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp);
-void usb_ehci_unrealize(EHCIState *s, DeviceState *dev, Error **errp);
+void usb_ehci_unrealize(EHCIState *s, DeviceState *dev);
void ehci_reset(void *opaque);
#define TYPE_PCI_EHCI "pci-ehci-usb"
device_add_bootindex_property(obj, &s->bootindex,
"bootindex", NULL,
- &udev->qdev, NULL);
+ &udev->qdev);
}
-static void usb_host_unrealize(USBDevice *udev, Error **errp)
+static void usb_host_unrealize(USBDevice *udev)
{
USBHostDevice *s = USB_HOST_DEVICE(udev);
}
}
-static void usbredir_unrealize(USBDevice *udev, Error **errp)
+static void usbredir_unrealize(USBDevice *udev)
{
USBRedirDevice *dev = USB_REDIRECT(udev);
device_add_bootindex_property(obj, &dev->bootindex,
"bootindex", NULL,
- &udev->qdev, NULL);
+ &udev->qdev);
}
static const TypeInfo usbredir_dev_info = {
vfio_put_group(vfio_group);
}
-static void vfio_ap_unrealize(DeviceState *dev, Error **errp)
+static void vfio_ap_unrealize(DeviceState *dev)
{
APDevice *apdev = AP_DEVICE(dev);
VFIOAPDevice *vapdev = VFIO_AP_DEVICE(apdev);
vfio_put_group(group);
out_group_err:
if (cdc->unrealize) {
- cdc->unrealize(cdev, NULL);
+ cdc->unrealize(cdev);
}
out_err_propagate:
error_propagate(errp, err);
}
-static void vfio_ccw_unrealize(DeviceState *dev, Error **errp)
+static void vfio_ccw_unrealize(DeviceState *dev)
{
CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
vfio_put_group(group);
if (cdc->unrealize) {
- cdc->unrealize(cdev, errp);
+ cdc->unrealize(cdev);
}
}
object_property_add(OBJECT(vdev), "nvlink2-tgt", "uint64",
vfio_pci_nvlink2_get_tgt, NULL, NULL,
- (void *) (uintptr_t) cap->tgt, NULL);
+ (void *) (uintptr_t) cap->tgt);
trace_vfio_pci_nvidia_gpu_setup_quirk(vdev->vbasedev.name, cap->tgt,
nv2reg->size);
free_exit:
object_property_add(OBJECT(vdev), "nvlink2-tgt", "uint64",
vfio_pci_nvlink2_get_tgt, NULL, NULL,
- (void *) (uintptr_t) captgt->tgt, NULL);
+ (void *) (uintptr_t) captgt->tgt);
trace_vfio_pci_nvlink2_setup_quirk_ssatgt(vdev->vbasedev.name, captgt->tgt,
atsdreg->size);
object_property_add(OBJECT(vdev), "nvlink2-link-speed", "uint32",
vfio_pci_nvlink2_get_link_speed, NULL, NULL,
- (void *) (uintptr_t) capspeed->link_speed, NULL);
+ (void *) (uintptr_t) capspeed->link_speed);
trace_vfio_pci_nvlink2_setup_quirk_lnkspd(vdev->vbasedev.name,
capspeed->link_speed);
free_exit:
device_add_bootindex_property(obj, &vdev->bootindex,
"bootindex", NULL,
- &pci_dev->qdev, NULL);
+ &pci_dev->qdev);
vdev->host.domain = ~0U;
vdev->host.bus = ~0U;
vdev->host.slot = ~0U;
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VHOST_SCSI);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
- "bootindex", &error_abort);
+ "bootindex");
}
static const VirtioPCIDeviceTypeInfo vhost_scsi_pci_info = {
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VHOST_USER_BLK);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
- "bootindex", &error_abort);
+ "bootindex");
}
static const VirtioPCIDeviceTypeInfo vhost_user_blk_pci_info = {
return;
}
-static void vuf_device_unrealize(DeviceState *dev, Error **errp)
+static void vuf_device_unrealize(DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VHostUserFS *fs = VHOST_USER_FS(dev);
TYPE_VHOST_USER_INPUT);
object_property_add_alias(obj, "chardev",
- OBJECT(&dev->vhi), "chardev",
- &error_abort);
+ OBJECT(&dev->vhi), "chardev");
}
static const VirtioPCIDeviceTypeInfo vhost_user_input_pci_info = {
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VHOST_USER_SCSI);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
- "bootindex", &error_abort);
+ "bootindex");
}
static const VirtioPCIDeviceTypeInfo vhost_user_scsi_pci_info = {
return;
}
-static void vhost_vsock_device_unrealize(DeviceState *dev, Error **errp)
+static void vhost_vsock_device_unrealize(DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VHostVSock *vsock = VHOST_VSOCK(dev);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_BALLOON);
object_property_add_alias(obj, "guest-stats", OBJECT(&dev->vdev),
- "guest-stats", &error_abort);
+ "guest-stats");
object_property_add_alias(obj, "guest-stats-polling-interval",
OBJECT(&dev->vdev),
- "guest-stats-polling-interval", &error_abort);
+ "guest-stats-polling-interval");
}
static const VirtioPCIDeviceTypeInfo virtio_balloon_pci_info = {
reset_stats(s);
}
-static void virtio_balloon_device_unrealize(DeviceState *dev, Error **errp)
+static void virtio_balloon_device_unrealize(DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIOBalloon *s = VIRTIO_BALLOON(dev);
VirtIOBalloon *s = VIRTIO_BALLOON(obj);
object_property_add(obj, "guest-stats", "guest statistics",
- balloon_stats_get_all, NULL, NULL, s, NULL);
+ balloon_stats_get_all, NULL, NULL, s);
object_property_add(obj, "guest-stats-polling-interval", "int",
balloon_stats_get_poll_interval,
balloon_stats_set_poll_interval,
- NULL, s, NULL);
+ NULL, s);
}
static const VMStateDescription vmstate_virtio_balloon = {
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_BLK);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
- "bootindex", &error_abort);
+ "bootindex");
}
static const VirtioPCIDeviceTypeInfo virtio_blk_pci_info = {
cryptodev_backend_set_used(vcrypto->cryptodev, true);
}
-static void virtio_crypto_device_unrealize(DeviceState *dev, Error **errp)
+static void virtio_crypto_device_unrealize(DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(dev);
}
}
-static void virtio_iommu_device_unrealize(DeviceState *dev, Error **errp)
+static void virtio_iommu_device_unrealize(DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIOIOMMU *s = VIRTIO_IOMMU(dev);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_NET);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
- "bootindex", &error_abort);
+ "bootindex");
}
static const VirtioPCIDeviceTypeInfo virtio_net_pci_info = {
pmem->rq_vq = virtio_add_queue(vdev, 128, virtio_pmem_flush);
}
-static void virtio_pmem_unrealize(DeviceState *dev, Error **errp)
+static void virtio_pmem_unrealize(DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIOPMEM *pmem = VIRTIO_PMEM(dev);
}
object_property_add_child(OBJECT(dev), "default-backend",
- default_backend, &error_abort);
+ default_backend);
/* The child property took a reference, we can safely drop ours now */
object_unref(default_backend);
vrng);
}
-static void virtio_rng_device_unrealize(DeviceState *dev, Error **errp)
+static void virtio_rng_device_unrealize(DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIORNG *vrng = VIRTIO_RNG(dev);
virtio_bus_device_plugged(vdev, &err);
if (err != NULL) {
error_propagate(errp, err);
- vdc->unrealize(dev, NULL);
+ vdc->unrealize(dev);
return;
}
memory_listener_register(&vdev->listener, vdev->dma_as);
}
-static void virtio_device_unrealize(DeviceState *dev, Error **errp)
+static void virtio_device_unrealize(DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(dev);
- Error *err = NULL;
virtio_bus_device_unplugged(vdev);
if (vdc->unrealize != NULL) {
- vdc->unrealize(dev, &err);
- if (err != NULL) {
- error_propagate(errp, err);
- return;
- }
+ vdc->unrealize(dev);
}
g_free(vdev->bus_name);
dev);
}
-static void wdt_diag288_unrealize(DeviceState *dev, Error **errp)
+static void wdt_diag288_unrealize(DeviceState *dev)
{
DIAG288State *diag288 = DIAG288(dev);
xen_bus_cleanup(xenbus);
}
-static void xen_bus_unrealize(BusState *bus, Error **errp)
+static void xen_bus_unrealize(BusState *bus)
{
XenBus *xenbus = XEN_BUS(bus);
return;
fail:
- xen_bus_unrealize(bus, &error_abort);
+ xen_bus_unrealize(bus);
}
static void xen_bus_unplug_request(HotplugHandler *hotplug,
g_free(channel);
}
-static void xen_device_unrealize(DeviceState *dev, Error **errp)
+static void xen_device_unrealize(DeviceState *dev)
{
XenDevice *xendev = XEN_DEVICE(dev);
XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
}
if (xendev_class->unrealize) {
- xendev_class->unrealize(xendev, errp);
+ xendev_class->unrealize(xendev);
}
/* Make sure all event channels are cleaned up */
{
XenDevice *xendev = container_of(n, XenDevice, exit);
- xen_device_unrealize(DEVICE(xendev), &error_abort);
+ xen_device_unrealize(DEVICE(xendev));
}
static void xen_device_realize(DeviceState *dev, Error **errp)
return;
unrealize:
- xen_device_unrealize(dev, &error_abort);
+ xen_device_unrealize(dev);
}
static Property xen_device_props[] = {
compat_props_add(ac->compat_props, compat, G_N_ELEMENTS(compat));
object_class_property_add_bool(oc, "igd-passthru",
- xen_get_igd_gfx_passthru, xen_set_igd_gfx_passthru,
- &error_abort);
+ xen_get_igd_gfx_passthru, xen_set_igd_gfx_passthru);
object_class_property_set_description(oc, "igd-passthru",
- "Set on/off to enable/disable igd passthrou", &error_abort);
+ "Set on/off to enable/disable igd passthrou");
}
#define TYPE_XEN_ACCEL ACCEL_CLASS_NAME("xen")
xen_sysdev = qdev_create(NULL, TYPE_XENSYSDEV);
qdev_init_nofail(xen_sysdev);
- xen_sysbus = qbus_create(TYPE_XENSYSBUS, DEVICE(xen_sysdev), "xen-sysbus");
+ xen_sysbus = qbus_create(TYPE_XENSYSBUS, xen_sysdev, "xen-sysbus");
qbus_set_bus_hotplug_handler(xen_sysbus, &error_abort);
return 0;
#define BLOCK_OPT_REFCOUNT_BITS "refcount_bits"
#define BLOCK_OPT_DATA_FILE "data_file"
#define BLOCK_OPT_DATA_FILE_RAW "data_file_raw"
+#define BLOCK_OPT_COMPRESSION_TYPE "compression_type"
#define BLOCK_PROBE_BUF_SIZE 512
GArray *rsdp;
GArray *tcpalog;
GArray *vmgenid;
+ GArray *hardware_errors;
BIOSLinker *linker;
} AcpiBuildTables;
#include "hw/sysbus.h"
#include "hw/acpi/memory_hotplug.h"
+#include "hw/acpi/ghes.h"
#define ACPI_POWER_BUTTON_DEVICE "PWRB"
GEDState ged_state;
uint32_t ged_event_bitmap;
qemu_irq irq;
+ AcpiGhesState ghes_state;
} AcpiGedState;
void build_ged_aml(Aml *table, const char* name, HotplugHandler *hotplug_dev,
--- /dev/null
+/*
+ * Support for generating APEI tables and recording CPER for Guests
+ *
+ * Copyright (c) 2020 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Author: Dongjiu Geng <gengdongjiu@huawei.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/>.
+ */
+
+#ifndef ACPI_GHES_H
+#define ACPI_GHES_H
+
+#include "hw/acpi/bios-linker-loader.h"
+
+/*
+ * Values for Hardware Error Notification Type field
+ */
+enum AcpiGhesNotifyType {
+ /* Polled */
+ ACPI_GHES_NOTIFY_POLLED = 0,
+ /* External Interrupt */
+ ACPI_GHES_NOTIFY_EXTERNAL = 1,
+ /* Local Interrupt */
+ ACPI_GHES_NOTIFY_LOCAL = 2,
+ /* SCI */
+ ACPI_GHES_NOTIFY_SCI = 3,
+ /* NMI */
+ ACPI_GHES_NOTIFY_NMI = 4,
+ /* CMCI, ACPI 5.0: 18.3.2.7, Table 18-290 */
+ ACPI_GHES_NOTIFY_CMCI = 5,
+ /* MCE, ACPI 5.0: 18.3.2.7, Table 18-290 */
+ ACPI_GHES_NOTIFY_MCE = 6,
+ /* GPIO-Signal, ACPI 6.0: 18.3.2.7, Table 18-332 */
+ ACPI_GHES_NOTIFY_GPIO = 7,
+ /* ARMv8 SEA, ACPI 6.1: 18.3.2.9, Table 18-345 */
+ ACPI_GHES_NOTIFY_SEA = 8,
+ /* ARMv8 SEI, ACPI 6.1: 18.3.2.9, Table 18-345 */
+ ACPI_GHES_NOTIFY_SEI = 9,
+ /* External Interrupt - GSIV, ACPI 6.1: 18.3.2.9, Table 18-345 */
+ ACPI_GHES_NOTIFY_GSIV = 10,
+ /* Software Delegated Exception, ACPI 6.2: 18.3.2.9, Table 18-383 */
+ ACPI_GHES_NOTIFY_SDEI = 11,
+ /* 12 and greater are reserved */
+ ACPI_GHES_NOTIFY_RESERVED = 12
+};
+
+enum {
+ ACPI_HEST_SRC_ID_SEA = 0,
+ /* future ids go here */
+ ACPI_HEST_SRC_ID_RESERVED,
+};
+
+typedef struct AcpiGhesState {
+ uint64_t ghes_addr_le;
+} AcpiGhesState;
+
+void build_ghes_error_table(GArray *hardware_errors, BIOSLinker *linker);
+void acpi_build_hest(GArray *table_data, BIOSLinker *linker);
+void acpi_ghes_add_fw_cfg(AcpiGhesState *vms, FWCfgState *s,
+ GArray *hardware_errors);
+int acpi_ghes_record_errors(uint8_t notify, uint64_t error_physical_addr);
+#endif
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);
+void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm);
void ich9_pm_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp);
bool highmem_ecam;
bool its;
bool virt;
+ bool ras;
OnOffAuto acpi;
VirtGICType gic_version;
VirtIOMMUType iommu;
void spapr_caps_init(SpaprMachineState *spapr);
void spapr_caps_apply(SpaprMachineState *spapr);
void spapr_caps_cpu_apply(SpaprMachineState *spapr, PowerPCCPU *cpu);
-void spapr_caps_add_properties(SpaprMachineClass *smc, Error **errp);
+void spapr_caps_add_properties(SpaprMachineClass *smc);
int spapr_caps_post_migration(SpaprMachineState *spapr);
void spapr_check_pagesize(SpaprMachineState *spapr, hwaddr pagesize,
} DeviceCategory;
typedef void (*DeviceRealize)(DeviceState *dev, Error **errp);
-typedef void (*DeviceUnrealize)(DeviceState *dev, Error **errp);
+typedef void (*DeviceUnrealize)(DeviceState *dev);
typedef void (*DeviceReset)(DeviceState *dev);
typedef void (*BusRealize)(BusState *bus, Error **errp);
-typedef void (*BusUnrealize)(BusState *bus, Error **errp);
+typedef void (*BusUnrealize)(BusState *bus);
/**
* DeviceClass:
const QEnumLookup *enum_table;
int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
void (*set_default_value)(ObjectProperty *op, const Property *prop);
- void (*create)(ObjectClass *oc, Property *prop, Error **errp);
+ void (*create)(ObjectClass *oc, Property *prop);
ObjectPropertyAccessor *get;
ObjectPropertyAccessor *set;
ObjectPropertyRelease *release;
typedef struct S390CCWDeviceClass {
CCWDeviceClass parent_class;
void (*realize)(S390CCWDevice *dev, char *sysfsdev, Error **errp);
- void (*unrealize)(S390CCWDevice *dev, Error **errp);
+ void (*unrealize)(S390CCWDevice *dev);
IOInstEnding (*handle_request) (SubchDev *sch);
int (*handle_halt) (SubchDev *sch);
int (*handle_clear) (SubchDev *sch);
typedef struct SCSIDeviceClass {
DeviceClass parent_class;
void (*realize)(SCSIDevice *dev, Error **errp);
- void (*unrealize)(SCSIDevice *dev, Error **errp);
+ void (*unrealize)(SCSIDevice *dev);
int (*parse_cdb)(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
void *hba_private);
SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
* @obj: Stream slave to push to
* @buf: Data to write
* @len: Maximum number of bytes to write
+ * @eop: End of packet flag
*/
- size_t (*push)(StreamSlave *obj, unsigned char *buf, size_t len);
+ size_t (*push)(StreamSlave *obj, unsigned char *buf, size_t len, bool eop);
} StreamSlaveClass;
size_t
-stream_push(StreamSlave *sink, uint8_t *buf, size_t len);
+stream_push(StreamSlave *sink, uint8_t *buf, size_t len, bool eop);
bool
stream_can_push(StreamSlave *sink, StreamCanPushNotifyFn notify,
OBJECT_GET_CLASS(USBDeviceClass, (obj), TYPE_USB_DEVICE)
typedef void (*USBDeviceRealize)(USBDevice *dev, Error **errp);
-typedef void (*USBDeviceUnrealize)(USBDevice *dev, Error **errp);
+typedef void (*USBDeviceUnrealize)(USBDevice *dev);
typedef struct USBDeviceClass {
DeviceClass parent_class;
} XenBlockDevice;
typedef void (*XenBlockDeviceRealize)(XenBlockDevice *blockdev, Error **errp);
-typedef void (*XenBlockDeviceUnrealize)(XenBlockDevice *blockdev, Error **errp);
+typedef void (*XenBlockDeviceUnrealize)(XenBlockDevice *blockdev);
typedef struct XenBlockDeviceClass {
/*< private >*/
typedef void (*XenDeviceFrontendChanged)(XenDevice *xendev,
enum xenbus_state frontend_state,
Error **errp);
-typedef void (*XenDeviceUnrealize)(XenDevice *xendev, Error **errp);
+typedef void (*XenDeviceUnrealize)(XenDevice *xendev);
typedef struct XenDeviceClass {
/*< private >*/
};
} QemuUUID;
+/**
+ * UUID_LE - converts the fields of UUID to little-endian array,
+ * each of parameters is the filed of UUID.
+ *
+ * @time_low: The low field of the timestamp
+ * @time_mid: The middle field of the timestamp
+ * @time_hi_and_version: The high field of the timestamp
+ * multiplexed with the version number
+ * @clock_seq_hi_and_reserved: The high field of the clock
+ * sequence multiplexed with the variant
+ * @clock_seq_low: The low field of the clock sequence
+ * @node0: The spatially unique node0 identifier
+ * @node1: The spatially unique node1 identifier
+ * @node2: The spatially unique node2 identifier
+ * @node3: The spatially unique node3 identifier
+ * @node4: The spatially unique node4 identifier
+ * @node5: The spatially unique node5 identifier
+ */
+#define UUID_LE(time_low, time_mid, time_hi_and_version, \
+ clock_seq_hi_and_reserved, clock_seq_low, node0, node1, node2, \
+ node3, node4, node5) \
+ { (time_low) & 0xff, ((time_low) >> 8) & 0xff, ((time_low) >> 16) & 0xff, \
+ ((time_low) >> 24) & 0xff, (time_mid) & 0xff, ((time_mid) >> 8) & 0xff, \
+ (time_hi_and_version) & 0xff, ((time_hi_and_version) >> 8) & 0xff, \
+ (clock_seq_hi_and_reserved), (clock_seq_low), (node0), (node1), (node2),\
+ (node3), (node4), (node5) }
+
#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-" \
"%02hhx%02hhx-%02hhx%02hhx-" \
"%02hhx%02hhx-" \
struct ObjectProperty
{
- gchar *name;
- gchar *type;
- gchar *description;
+ char *name;
+ char *type;
+ char *description;
ObjectPropertyAccessor *get;
ObjectPropertyAccessor *set;
ObjectPropertyResolve *resolve;
* meant to allow a property to free its opaque upon object
* destruction. This may be NULL.
* @opaque: an opaque pointer to pass to the callbacks for the property
- * @errp: returns an error if this function fails
*
* Returns: The #ObjectProperty; this can be used to set the @resolve
* callback for child and link properties.
ObjectPropertyAccessor *get,
ObjectPropertyAccessor *set,
ObjectPropertyRelease *release,
- void *opaque, Error **errp);
+ void *opaque);
-void object_property_del(Object *obj, const char *name, Error **errp);
+void object_property_del(Object *obj, const char *name);
ObjectProperty *object_class_property_add(ObjectClass *klass, const char *name,
const char *type,
ObjectPropertyAccessor *get,
ObjectPropertyAccessor *set,
ObjectPropertyRelease *release,
- void *opaque, Error **errp);
+ void *opaque);
/**
* object_property_set_default_bool:
int object_property_get_enum(Object *obj, const char *name,
const char *typename, Error **errp);
-/**
- * object_property_get_uint16List:
- * @obj: the object
- * @name: the name of the property
- * @list: the returned int list
- * @errp: returns an error if this function fails
- *
- * Returns: the value of the property, converted to integers, or
- * undefined if an error occurs (including when the property value is not
- * an list of integers).
- */
-void object_property_get_uint16List(Object *obj, const char *name,
- uint16List **list, Error **errp);
-
/**
* object_property_set:
* @obj: the object
* path is the path within the composition tree starting from the root.
* %NULL if the object doesn't have a parent (and thus a canonical path).
*/
-gchar *object_get_canonical_path_component(Object *obj);
+char *object_get_canonical_path_component(Object *obj);
/**
* object_get_canonical_path:
* Returns: The canonical path for a object. This is the path within the
* composition tree starting from the root.
*/
-gchar *object_get_canonical_path(Object *obj);
+char *object_get_canonical_path(Object *obj);
/**
* object_resolve_path:
*
* Returns: The resolved object or NULL on path lookup failure.
*/
-Object *object_resolve_path_component(Object *parent, const gchar *part);
+Object *object_resolve_path_component(Object *parent, const char *part);
/**
* object_property_add_child:
* @obj: the object to add a property to
* @name: the name of the property
* @child: the child object
- * @errp: if an error occurs, a pointer to an area to store the error
*
* Child properties form the composition tree. All objects need to be a child
* of another object. Objects can only be a child of one object.
* The value of a child property as a C string will be the child object's
* canonical path. It can be retrieved using object_property_get_str().
* The child object itself can be retrieved using object_property_get_link().
+ *
+ * Returns: The newly added property on success, or %NULL on failure.
*/
-void object_property_add_child(Object *obj, const char *name,
- Object *child, Error **errp);
+ObjectProperty *object_property_add_child(Object *obj, const char *name,
+ Object *child);
typedef enum {
/* Unref the link pointer when the property is deleted */
* @targetp: a pointer to where the link object reference is stored
* @check: callback to veto setting or NULL if the property is read-only
* @flags: additional options for the link
- * @errp: if an error occurs, a pointer to an area to store the error
*
* Links establish relationships between objects. Links are unidirectional
* although two links can be combined to form a bidirectional relationship
* <code>@flags</code> <code>OBJ_PROP_LINK_STRONG</code> bit is set,
* the reference count is decremented when the property is deleted or
* modified.
+ *
+ * Returns: The newly added property on success, or %NULL on failure.
*/
-void object_property_add_link(Object *obj, const char *name,
+ObjectProperty *object_property_add_link(Object *obj, const char *name,
const char *type, Object **targetp,
void (*check)(const Object *obj, const char *name,
Object *val, Error **errp),
- ObjectPropertyLinkFlags flags,
- Error **errp);
+ ObjectPropertyLinkFlags flags);
ObjectProperty *object_class_property_add_link(ObjectClass *oc,
const char *name,
const char *type, ptrdiff_t offset,
void (*check)(const Object *obj, const char *name,
Object *val, Error **errp),
- ObjectPropertyLinkFlags flags,
- Error **errp);
+ ObjectPropertyLinkFlags flags);
/**
* object_property_add_str:
* @get: the getter or NULL if the property is write-only. This function must
* return a string to be freed by g_free().
* @set: the setter or NULL if the property is read-only
- * @errp: if an error occurs, a pointer to an area to store the error
*
* Add a string property using getters/setters. This function will add a
* property of type 'string'.
+ *
+ * Returns: The newly added property on success, or %NULL on failure.
*/
-void object_property_add_str(Object *obj, const char *name,
+ObjectProperty *object_property_add_str(Object *obj, const char *name,
char *(*get)(Object *, Error **),
- void (*set)(Object *, const char *, Error **),
- Error **errp);
+ void (*set)(Object *, const char *, Error **));
ObjectProperty *object_class_property_add_str(ObjectClass *klass,
const char *name,
char *(*get)(Object *, Error **),
void (*set)(Object *, const char *,
- Error **),
- Error **errp);
+ Error **));
/**
* object_property_add_bool:
* @name: the name of the property
* @get: the getter or NULL if the property is write-only.
* @set: the setter or NULL if the property is read-only
- * @errp: if an error occurs, a pointer to an area to store the error
*
* Add a bool property using getters/setters. This function will add a
* property of type 'bool'.
+ *
+ * Returns: The newly added property on success, or %NULL on failure.
*/
-void object_property_add_bool(Object *obj, const char *name,
+ObjectProperty *object_property_add_bool(Object *obj, const char *name,
bool (*get)(Object *, Error **),
- void (*set)(Object *, bool, Error **),
- Error **errp);
+ void (*set)(Object *, bool, Error **));
ObjectProperty *object_class_property_add_bool(ObjectClass *klass,
const char *name,
bool (*get)(Object *, Error **),
- void (*set)(Object *, bool, Error **),
- Error **errp);
+ void (*set)(Object *, bool, Error **));
/**
* object_property_add_enum:
* @typename: the name of the enum data type
* @get: the getter or %NULL if the property is write-only.
* @set: the setter or %NULL if the property is read-only
- * @errp: if an error occurs, a pointer to an area to store the error
*
* Add an enum property using getters/setters. This function will add a
* property of type '@typename'.
+ *
+ * Returns: The newly added property on success, or %NULL on failure.
*/
-void object_property_add_enum(Object *obj, const char *name,
+ObjectProperty *object_property_add_enum(Object *obj, const char *name,
const char *typename,
const QEnumLookup *lookup,
int (*get)(Object *, Error **),
- void (*set)(Object *, int, Error **),
- Error **errp);
+ void (*set)(Object *, int, Error **));
ObjectProperty *object_class_property_add_enum(ObjectClass *klass,
const char *name,
const char *typename,
const QEnumLookup *lookup,
int (*get)(Object *, Error **),
- void (*set)(Object *, int, Error **),
- Error **errp);
+ void (*set)(Object *, int, Error **));
/**
* object_property_add_tm:
* @obj: the object to add a property to
* @name: the name of the property
* @get: the getter or NULL if the property is write-only.
- * @errp: if an error occurs, a pointer to an area to store the error
*
* Add a read-only struct tm valued property using a getter function.
* This function will add a property of type 'struct tm'.
+ *
+ * Returns: The newly added property on success, or %NULL on failure.
*/
-void object_property_add_tm(Object *obj, const char *name,
- void (*get)(Object *, struct tm *, Error **),
- Error **errp);
+ObjectProperty *object_property_add_tm(Object *obj, const char *name,
+ void (*get)(Object *, struct tm *, Error **));
ObjectProperty *object_class_property_add_tm(ObjectClass *klass,
- const char *name,
- void (*get)(Object *, struct tm *, Error **),
- Error **errp);
+ const char *name,
+ void (*get)(Object *, struct tm *, Error **));
typedef enum {
/* Automatically add a getter to the property */
* @name: the name of the property
* @v: pointer to value
* @flags: bitwise-or'd ObjectPropertyFlags
- * @errp: if an error occurs, a pointer to an area to store the error
*
* Add an integer property in memory. This function will add a
* property of type 'uint8'.
+ *
+ * Returns: The newly added property on success, or %NULL on failure.
*/
-void object_property_add_uint8_ptr(Object *obj, const char *name,
- const uint8_t *v, ObjectPropertyFlags flags,
- Error **errp);
+ObjectProperty *object_property_add_uint8_ptr(Object *obj, const char *name,
+ const uint8_t *v,
+ ObjectPropertyFlags flags);
ObjectProperty *object_class_property_add_uint8_ptr(ObjectClass *klass,
const char *name,
const uint8_t *v,
- ObjectPropertyFlags flags,
- Error **errp);
+ ObjectPropertyFlags flags);
/**
* object_property_add_uint16_ptr:
* @name: the name of the property
* @v: pointer to value
* @flags: bitwise-or'd ObjectPropertyFlags
- * @errp: if an error occurs, a pointer to an area to store the error
*
* Add an integer property in memory. This function will add a
* property of type 'uint16'.
+ *
+ * Returns: The newly added property on success, or %NULL on failure.
*/
-void object_property_add_uint16_ptr(Object *obj, const char *name,
+ObjectProperty *object_property_add_uint16_ptr(Object *obj, const char *name,
const uint16_t *v,
- ObjectPropertyFlags flags,
- Error **errp);
+ ObjectPropertyFlags flags);
ObjectProperty *object_class_property_add_uint16_ptr(ObjectClass *klass,
const char *name,
const uint16_t *v,
- ObjectPropertyFlags flags,
- Error **errp);
+ ObjectPropertyFlags flags);
/**
* object_property_add_uint32_ptr:
* @name: the name of the property
* @v: pointer to value
* @flags: bitwise-or'd ObjectPropertyFlags
- * @errp: if an error occurs, a pointer to an area to store the error
*
* Add an integer property in memory. This function will add a
* property of type 'uint32'.
+ *
+ * Returns: The newly added property on success, or %NULL on failure.
*/
-void object_property_add_uint32_ptr(Object *obj, const char *name,
+ObjectProperty *object_property_add_uint32_ptr(Object *obj, const char *name,
const uint32_t *v,
- ObjectPropertyFlags flags,
- Error **errp);
+ ObjectPropertyFlags flags);
ObjectProperty *object_class_property_add_uint32_ptr(ObjectClass *klass,
const char *name,
const uint32_t *v,
- ObjectPropertyFlags flags,
- Error **errp);
+ ObjectPropertyFlags flags);
/**
* object_property_add_uint64_ptr:
* @name: the name of the property
* @v: pointer to value
* @flags: bitwise-or'd ObjectPropertyFlags
- * @errp: if an error occurs, a pointer to an area to store the error
*
* Add an integer property in memory. This function will add a
* property of type 'uint64'.
+ *
+ * Returns: The newly added property on success, or %NULL on failure.
*/
-void object_property_add_uint64_ptr(Object *obj, const char *name,
+ObjectProperty *object_property_add_uint64_ptr(Object *obj, const char *name,
const uint64_t *v,
- ObjectPropertyFlags flags,
- Error **Errp);
+ ObjectPropertyFlags flags);
ObjectProperty *object_class_property_add_uint64_ptr(ObjectClass *klass,
const char *name,
const uint64_t *v,
- ObjectPropertyFlags flags,
- Error **Errp);
+ ObjectPropertyFlags flags);
/**
* object_property_add_alias:
* @name: the name of the property
* @target_obj: the object to forward property access to
* @target_name: the name of the property on the forwarded object
- * @errp: if an error occurs, a pointer to an area to store the error
*
* Add an alias for a property on an object. This function will add a property
* of the same type as the forwarded property.
* this property exists. In the case of a child object or an alias on the same
* object this will be the case. For aliases to other objects the caller is
* responsible for taking a reference.
+ *
+ * Returns: The newly added property on success, or %NULL on failure.
*/
-void object_property_add_alias(Object *obj, const char *name,
- Object *target_obj, const char *target_name,
- Error **errp);
+ObjectProperty *object_property_add_alias(Object *obj, const char *name,
+ Object *target_obj, const char *target_name);
/**
* object_property_add_const_link:
* @obj: the object to add a property to
* @name: the name of the property
* @target: the object to be referred by the link
- * @errp: if an error occurs, a pointer to an area to store the error
*
* Add an unmodifiable link for a property on an object. This function will
* add a property of type link<TYPE> where TYPE is the type of @target.
* this property exists. In the case @target is a child of @obj,
* this will be the case. Otherwise, the caller is responsible for
* taking a reference.
+ *
+ * Returns: The newly added property on success, or %NULL on failure.
*/
-void object_property_add_const_link(Object *obj, const char *name,
- Object *target, Error **errp);
+ObjectProperty *object_property_add_const_link(Object *obj, const char *name,
+ Object *target);
/**
* object_property_set_description:
* @obj: the object owning the property
* @name: the name of the property
* @description: the description of the property on the object
- * @errp: if an error occurs, a pointer to an area to store the error
*
* Set an object property's description.
*
*/
void object_property_set_description(Object *obj, const char *name,
- const char *description, Error **errp);
+ const char *description);
void object_class_property_set_description(ObjectClass *klass, const char *name,
- const char *description,
- Error **errp);
+ const char *description);
/**
* object_child_foreach:
/* Returns VCPU ID to be used on KVM_CREATE_VCPU ioctl() */
unsigned long kvm_arch_vcpu_id(CPUState *cpu);
-#ifdef TARGET_I386
-#define KVM_HAVE_MCE_INJECTION 1
+#ifdef KVM_HAVE_MCE_INJECTION
void kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
#endif
AddressSpace *as, int as_id);
void kvm_set_max_memslot_size(hwaddr max_slot_size);
+
+/**
+ * kvm_hwpoison_page_add:
+ *
+ * Parameters:
+ * @ram_addr: the address in the RAM for the poisoned page
+ *
+ * Add a poisoned page to the list
+ *
+ * Return: None.
+ */
+void kvm_hwpoison_page_add(ram_addr_t ram_addr);
#endif
void del_boot_device_path(DeviceState *dev, const char *suffix);
void device_add_bootindex_property(Object *obj, int32_t *bootindex,
const char *name, const char *suffix,
- DeviceState *dev, Error **errp);
+ DeviceState *dev);
void restore_boot_order(void *opaque);
void validate_bootdevices(const char *devices, Error **errp);
void add_boot_device_lchs(DeviceState *dev, const char *suffix,
object_class_property_add(klass, "poll-max-ns", "int",
iothread_get_poll_param,
iothread_set_poll_param,
- NULL, &poll_max_ns_info, &error_abort);
+ NULL, &poll_max_ns_info);
object_class_property_add(klass, "poll-grow", "int",
iothread_get_poll_param,
iothread_set_poll_param,
- NULL, &poll_grow_info, &error_abort);
+ NULL, &poll_grow_info);
object_class_property_add(klass, "poll-shrink", "int",
iothread_get_poll_param,
iothread_set_poll_param,
- NULL, &poll_shrink_info, &error_abort);
+ NULL, &poll_shrink_info);
}
static const TypeInfo iothread_info = {
owner = container_get(qdev_get_machine(), "/unattached");
}
- object_property_add_child(owner, name_array, OBJECT(mr), &error_abort);
+ object_property_add_child(owner, name_array, OBJECT(mr));
object_unref(OBJECT(mr));
g_free(name_array);
g_free(escaped_name);
Error **errp)
{
MemoryRegion *mr = MEMORY_REGION(obj);
- gchar *path = (gchar *)"";
+ char *path = (char *)"";
if (mr->container) {
path = object_get_canonical_path(OBJECT(mr->container));
"link<" TYPE_MEMORY_REGION ">",
memory_region_get_container,
NULL, /* memory_region_set_container */
- NULL, NULL, &error_abort);
+ NULL, NULL);
op->resolve = memory_region_resolve_container;
object_property_add_uint64_ptr(OBJECT(mr), "addr",
- &mr->addr, OBJ_PROP_FLAG_READ, &error_abort);
+ &mr->addr, OBJ_PROP_FLAG_READ);
object_property_add(OBJECT(mr), "priority", "uint32",
memory_region_get_priority,
NULL, /* memory_region_set_priority */
- NULL, NULL, &error_abort);
+ NULL, NULL);
object_property_add(OBJECT(mr), "size", "uint64",
memory_region_get_size,
NULL, /* memory_region_set_size, */
- NULL, NULL, &error_abort);
+ NULL, NULL);
}
static void iommu_memory_region_initfn(Object *obj)
if (dev && dev->id) {
qemu_printf(" id=%s", dev->id);
} else {
- gchar *canonical_path = object_get_canonical_path(obj);
+ char *canonical_path = object_get_canonical_path(obj);
if (canonical_path) {
qemu_printf(" path=%s", canonical_path);
g_free(canonical_path);
static int qdev_add_hotpluggable_device(Object *obj, void *opaque)
{
GSList **list = opaque;
- DeviceState *dev = (DeviceState *)object_dynamic_cast(OBJECT(obj),
- TYPE_DEVICE);
+ DeviceState *dev = (DeviceState *)object_dynamic_cast(obj, TYPE_DEVICE);
if (dev == NULL) {
return 0;
bool skip_flush;
bool use_io_thread;
- gchar *mon_cpu_path;
+ char *mon_cpu_path;
QTAILQ_ENTRY(Monitor) entry;
/*
object_property_add_link(obj, "canbus", TYPE_CAN_BUS,
(Object **)&ch->bus,
object_property_allow_set_link,
- OBJ_PROP_LINK_STRONG,
- &error_abort);
+ OBJ_PROP_LINK_STRONG);
}
static void can_host_class_init(ObjectClass *klass,
object_class_property_add_str(klass, "if",
can_host_socketcan_get_if,
- can_host_socketcan_set_if,
- &error_abort);
+ can_host_socketcan_set_if);
chc->connect = can_host_socketcan_connect;
chc->disconnect = can_host_socketcan_disconnect;
}
CompareState *s = COLO_COMPARE(obj);
object_property_add_str(obj, "primary_in",
- compare_get_pri_indev, compare_set_pri_indev,
- NULL);
+ compare_get_pri_indev, compare_set_pri_indev);
object_property_add_str(obj, "secondary_in",
- compare_get_sec_indev, compare_set_sec_indev,
- NULL);
+ compare_get_sec_indev, compare_set_sec_indev);
object_property_add_str(obj, "outdev",
- compare_get_outdev, compare_set_outdev,
- NULL);
+ compare_get_outdev, compare_set_outdev);
object_property_add_link(obj, "iothread", TYPE_IOTHREAD,
(Object **)&s->iothread,
object_property_allow_set_link,
- OBJ_PROP_LINK_STRONG, NULL);
+ OBJ_PROP_LINK_STRONG);
/* This parameter just for Xen COLO */
object_property_add_str(obj, "notify_dev",
- compare_get_notify_dev, compare_set_notify_dev,
- NULL);
+ compare_get_notify_dev, compare_set_notify_dev);
object_property_add(obj, "compare_timeout", "uint32",
compare_get_timeout,
- compare_set_timeout, NULL, NULL, NULL);
+ compare_set_timeout, NULL, NULL);
object_property_add(obj, "expired_scan_cycle", "uint32",
compare_get_expired_scan_cycle,
- compare_set_expired_scan_cycle, NULL, NULL, NULL);
+ compare_set_expired_scan_cycle, NULL, NULL);
s->vnet_hdr = false;
object_property_add_bool(obj, "vnet_hdr_support", compare_get_vnet_hdr,
- compare_set_vnet_hdr, NULL);
+ compare_set_vnet_hdr);
}
static void colo_compare_finalize(Object *obj)
nfds->maxlen = 65536;
object_property_add(obj, "maxlen", "uint32", filter_dump_get_maxlen,
- filter_dump_set_maxlen, NULL, NULL, NULL);
+ filter_dump_set_maxlen, NULL, NULL);
object_property_add_str(obj, "file", file_dump_get_filename,
- file_dump_set_filename, NULL);
+ file_dump_set_filename);
}
static void filter_dump_instance_finalize(Object *obj)
{
object_property_add(obj, "interval", "uint32",
filter_buffer_get_interval,
- filter_buffer_set_interval, NULL, NULL, NULL);
+ filter_buffer_set_interval, NULL, NULL);
}
static const TypeInfo filter_buffer_info = {
MirrorState *s = FILTER_MIRROR(obj);
object_property_add_str(obj, "outdev", filter_mirror_get_outdev,
- filter_mirror_set_outdev, NULL);
+ filter_mirror_set_outdev);
s->vnet_hdr = false;
object_property_add_bool(obj, "vnet_hdr_support",
filter_mirror_get_vnet_hdr,
- filter_mirror_set_vnet_hdr, NULL);
+ filter_mirror_set_vnet_hdr);
}
static void filter_redirector_init(Object *obj)
MirrorState *s = FILTER_REDIRECTOR(obj);
object_property_add_str(obj, "indev", filter_redirector_get_indev,
- filter_redirector_set_indev, NULL);
+ filter_redirector_set_indev);
object_property_add_str(obj, "outdev", filter_redirector_get_outdev,
- filter_redirector_set_outdev, NULL);
+ filter_redirector_set_outdev);
s->vnet_hdr = false;
object_property_add_bool(obj, "vnet_hdr_support",
filter_redirector_get_vnet_hdr,
- filter_redirector_set_vnet_hdr, NULL);
+ filter_redirector_set_vnet_hdr);
}
static void filter_mirror_fini(Object *obj)
s->failover_mode = FAILOVER_MODE_OFF;
object_property_add_bool(obj, "vnet_hdr_support",
filter_rewriter_get_vnet_hdr,
- filter_rewriter_set_vnet_hdr, NULL);
+ filter_rewriter_set_vnet_hdr);
}
static void colo_rewriter_class_init(ObjectClass *oc, void *data)
nf->position = g_strdup("tail");
object_property_add_str(obj, "netdev",
- netfilter_get_netdev_id, netfilter_set_netdev_id,
- NULL);
+ netfilter_get_netdev_id, netfilter_set_netdev_id);
object_property_add_enum(obj, "queue", "NetFilterDirection",
&NetFilterDirection_lookup,
- netfilter_get_direction, netfilter_set_direction,
- NULL);
+ netfilter_get_direction, netfilter_set_direction);
object_property_add_str(obj, "status",
- netfilter_get_status, netfilter_set_status,
- NULL);
+ netfilter_get_status, netfilter_set_status);
object_property_add_str(obj, "position",
- netfilter_get_position, netfilter_set_position,
- NULL);
+ netfilter_get_position, netfilter_set_position);
object_property_add_str(obj, "insert",
- netfilter_get_insert, netfilter_set_insert,
- NULL);
+ netfilter_get_insert, netfilter_set_insert);
}
static void netfilter_complete(UserCreatable *uc, Error **errp)
#
# @bitmaps: A list of qcow2 bitmap details (since 4.0)
#
+# @compression-type: the image cluster compression method (since 5.1)
+#
# Since: 1.7
##
{ 'struct': 'ImageInfoSpecificQCow2',
'*corrupt': 'bool',
'refcount-bits': 'int',
'*encrypt': 'ImageInfoSpecificQCow2Encryption',
- '*bitmaps': ['Qcow2BitmapInfo']
+ '*bitmaps': ['Qcow2BitmapInfo'],
+ 'compression-type': 'Qcow2CompressionType'
} }
##
'data': [ 'v2', 'v3' ] }
+##
+# @Qcow2CompressionType:
+#
+# Compression type used in qcow2 image file
+#
+# @zlib: zlib compression, see <http://zlib.net/>
+# @zstd: zstd compression, see <http://github.com/facebook/zstd>
+#
+# Since: 5.1
+##
+{ 'enum': 'Qcow2CompressionType',
+ 'data': [ 'zlib', { 'name': 'zstd', 'if': 'defined(CONFIG_ZSTD)' } ] }
+
##
# @BlockdevCreateOptionsQcow2:
#
# allowed values: off, falloc, full, metadata)
# @lazy-refcounts: True if refcounts may be updated lazily (default: off)
# @refcount-bits: Width of reference counts in bits (default: 16)
+# @compression-type: The image cluster compression method
+# (default: zlib, since 5.1)
#
# Since: 2.12
##
'*cluster-size': 'size',
'*preallocation': 'PreallocMode',
'*lazy-refcounts': 'bool',
- '*refcount-bits': 'int' } }
+ '*refcount-bits': 'int',
+ '*compression-type':'Qcow2CompressionType' } }
##
# @BlockdevCreateOptionsQed:
if (dev->id) {
object_property_add_child(qdev_get_peripheral(), dev->id,
- OBJECT(dev), NULL);
+ OBJECT(dev));
} else {
static int anon_count;
gchar *name = g_strdup_printf("device[%d]", anon_count++);
object_property_add_child(qdev_get_peripheral_anon(), name,
- OBJECT(dev), NULL);
+ OBJECT(dev));
g_free(name);
}
}
``-virtfs proxy,sock_fd=sock_fd,mount_tag=mount_tag [,writeout=writeout][,readonly]``
\
``-virtfs synth,mount_tag=mount_tag``
- Define a new filesystem device and expose it to the guest using a
- virtio-9p-device. The general form of a Virtual File system
- pass-through options are:
+ Define a new virtual filesystem device and expose it to the guest using
+ a virtio-9p-device (a.k.a. 9pfs), which essentially means that a certain
+ directory on host is made directly accessible by guest as a pass-through
+ file system by using the 9P network protocol for communication between
+ host and guests, if desired even accessible, shared by several guests
+ simultaniously.
+
+ Note that ``-virtfs`` is actually just a convenience shortcut for its
+ generalized form ``-fsdev -device virtio-9p-pci``.
+
+ The general form of pass-through file system options are:
``local``
Accesses to the filesystem are done by QEMU.
Object *container_get(Object *root, const char *path)
{
Object *obj, *child;
- gchar **parts;
+ char **parts;
int i;
parts = g_strsplit(path, "/", 0);
child = object_resolve_path_component(obj, parts[i]);
if (!child) {
child = object_new("container");
- object_property_add_child(obj, parts[i], child, NULL);
+ object_property_add_child(obj, parts[i], child);
object_unref(child);
}
}
goto out;
}
- object_property_add_child(parentobj, propname, obj, &local_err);
- if (local_err) {
- goto out;
- }
+ object_property_add_child(parentobj, propname, obj);
uc = (UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE);
if (uc) {
}
}
+out:
/*
- * Since object_property_add_child added a reference to the child object,
- * we can drop the reference added by object_initialize(), so the child
- * property will own the only reference to the object.
+ * We want @obj's reference to be 1 on success, 0 on failure.
+ * On success, it's 2: one taken by object_initialize(), and one
+ * by object_property_add_child().
+ * On failure in object_initialize() or earlier, it's 1.
+ * On failure afterwards, it's also 1: object_unparent() releases
+ * the reference taken by object_property_add_child().
*/
object_unref(obj);
-out:
- if (local_err) {
- error_propagate(errp, local_err);
- object_unref(obj);
- }
+ error_propagate(errp, local_err);
}
static inline bool object_property_is_child(ObjectProperty *prop)
g_hash_table_unref(obj->properties);
}
-static void object_property_del_child(Object *obj, Object *child, Error **errp)
+static void object_property_del_child(Object *obj, Object *child)
{
ObjectProperty *prop;
GHashTableIter iter;
void object_unparent(Object *obj)
{
if (obj->parent) {
- object_property_del_child(obj->parent, obj, NULL);
+ object_property_del_child(obj->parent, obj);
}
}
}
if (id != NULL) {
- object_property_add_child(parent, id, obj, &local_err);
- if (local_err) {
- goto error;
- }
+ object_property_add_child(parent, id, obj);
}
uc = (UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE);
}
}
- object_unref(OBJECT(obj));
+ object_unref(obj);
return obj;
error:
}
}
-ObjectProperty *
-object_property_add(Object *obj, const char *name, const char *type,
- ObjectPropertyAccessor *get,
- ObjectPropertyAccessor *set,
- ObjectPropertyRelease *release,
- void *opaque, Error **errp)
+static ObjectProperty *
+object_property_try_add(Object *obj, const char *name, const char *type,
+ ObjectPropertyAccessor *get,
+ ObjectPropertyAccessor *set,
+ ObjectPropertyRelease *release,
+ void *opaque, Error **errp)
{
ObjectProperty *prop;
size_t name_len = strlen(name);
for (i = 0; ; ++i) {
char *full_name = g_strdup_printf("%s[%d]", name_no_array, i);
- ret = object_property_add(obj, full_name, type, get, set,
- release, opaque, NULL);
+ ret = object_property_try_add(obj, full_name, type, get, set,
+ release, opaque, NULL);
g_free(full_name);
if (ret) {
break;
return prop;
}
+ObjectProperty *
+object_property_add(Object *obj, const char *name, const char *type,
+ ObjectPropertyAccessor *get,
+ ObjectPropertyAccessor *set,
+ ObjectPropertyRelease *release,
+ void *opaque)
+{
+ return object_property_try_add(obj, name, type, get, set, release,
+ opaque, &error_abort);
+}
+
ObjectProperty *
object_class_property_add(ObjectClass *klass,
const char *name,
ObjectPropertyAccessor *get,
ObjectPropertyAccessor *set,
ObjectPropertyRelease *release,
- void *opaque,
- Error **errp)
+ void *opaque)
{
ObjectProperty *prop;
- if (object_class_property_find(klass, name, NULL) != NULL) {
- error_setg(errp, "attempt to add duplicate property '%s' to class (type '%s')",
- name, object_class_get_name(klass));
- return NULL;
- }
+ assert(!object_class_property_find(klass, name, NULL));
prop = g_malloc0(sizeof(*prop));
return prop;
}
-void object_property_del(Object *obj, const char *name, Error **errp)
+void object_property_del(Object *obj, const char *name)
{
ObjectProperty *prop = g_hash_table_lookup(obj->properties, name);
- if (!prop) {
- error_setg(errp, "Property '.%s' not found", name);
- return;
- }
-
if (prop->release) {
prop->release(obj, name, prop->opaque);
}
const char *name, Error **errp)
{
if (value) {
- gchar *path = object_get_canonical_path(value);
+ char *path = object_get_canonical_path(value);
object_property_set_str(obj, path, name, errp);
g_free(path);
} else {
int object_property_get_enum(Object *obj, const char *name,
const char *typename, Error **errp)
{
- Error *err = NULL;
- Visitor *v;
char *str;
int ret;
ObjectProperty *prop = object_property_find(obj, name, errp);
enumprop = prop->opaque;
- v = string_output_visitor_new(false, &str);
- object_property_get(obj, v, name, &err);
- if (err) {
- error_propagate(errp, err);
- visit_free(v);
+ str = object_property_get_str(obj, name, errp);
+ if (!str) {
return 0;
}
- visit_complete(v, &str);
- visit_free(v);
ret = qapi_enum_parse(enumprop->lookup, str, -1, errp);
g_free(str);
return ret;
}
-void object_property_get_uint16List(Object *obj, const char *name,
- uint16List **list, Error **errp)
-{
- Error *err = NULL;
- Visitor *v;
- char *str;
-
- v = string_output_visitor_new(false, &str);
- object_property_get(obj, v, name, &err);
- if (err) {
- error_propagate(errp, err);
- goto out;
- }
- visit_complete(v, &str);
- visit_free(v);
- v = string_input_visitor_new(str);
- visit_type_uint16List(v, NULL, list, errp);
-
- g_free(str);
-out:
- visit_free(v);
-}
-
void object_property_parse(Object *obj, const char *string,
const char *name, Error **errp)
{
Error **errp)
{
Object *child = opaque;
- gchar *path;
+ char *path;
path = object_get_canonical_path(child);
visit_type_str(v, name, &path, errp);
g_free(path);
}
-static Object *object_resolve_child_property(Object *parent, void *opaque, const gchar *part)
+static Object *object_resolve_child_property(Object *parent, void *opaque,
+ const char *part)
{
return opaque;
}
object_unref(child);
}
-void object_property_add_child(Object *obj, const char *name,
- Object *child, Error **errp)
+ObjectProperty *
+object_property_add_child(Object *obj, const char *name,
+ Object *child)
{
- Error *local_err = NULL;
- gchar *type;
+ g_autofree char *type = NULL;
ObjectProperty *op;
- if (child->parent != NULL) {
- error_setg(errp, "child object is already parented");
- return;
- }
+ assert(!child->parent);
- type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
+ type = g_strdup_printf("child<%s>", object_get_typename(child));
op = object_property_add(obj, name, type, object_get_child_property, NULL,
- object_finalize_child_property, child, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- goto out;
- }
-
+ object_finalize_child_property, child);
op->resolve = object_resolve_child_property;
object_ref(child);
child->parent = obj;
-
-out:
- g_free(type);
+ return op;
}
void object_property_allow_set_link(const Object *obj, const char *name,
{
LinkProperty *lprop = opaque;
Object **targetp = object_link_get_targetp(obj, lprop);
- gchar *path;
+ char *path;
if (*targetp) {
path = object_get_canonical_path(*targetp);
visit_type_str(v, name, &path, errp);
g_free(path);
} else {
- path = (gchar *)"";
+ path = (char *)"";
visit_type_str(v, name, &path, errp);
}
}
const char *path, Error **errp)
{
const char *type;
- gchar *target_type;
+ char *target_type;
bool ambiguous = false;
Object *target;
}
}
-static Object *object_resolve_link_property(Object *parent, void *opaque, const gchar *part)
+static Object *object_resolve_link_property(Object *parent, void *opaque,
+ const char *part)
{
LinkProperty *lprop = opaque;
}
}
-static void object_add_link_prop(Object *obj, const char *name,
- const char *type, void *ptr,
- void (*check)(const Object *, const char *,
- Object *, Error **),
- ObjectPropertyLinkFlags flags,
- Error **errp)
+static ObjectProperty *
+object_add_link_prop(Object *obj, const char *name,
+ const char *type, void *ptr,
+ void (*check)(const Object *, const char *,
+ Object *, Error **),
+ ObjectPropertyLinkFlags flags)
{
- Error *local_err = NULL;
LinkProperty *prop = g_malloc(sizeof(*prop));
- gchar *full_type;
+ g_autofree char *full_type = NULL;
ObjectProperty *op;
if (flags & OBJ_PROP_LINK_DIRECT) {
object_get_link_property,
check ? object_set_link_property : NULL,
object_release_link_property,
- prop,
- &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- goto out;
- }
-
+ prop);
op->resolve = object_resolve_link_property;
-
-out:
- g_free(full_type);
+ return op;
}
-void object_property_add_link(Object *obj, const char *name,
- const char *type, Object **targetp,
- void (*check)(const Object *, const char *,
- Object *, Error **),
- ObjectPropertyLinkFlags flags,
- Error **errp)
+ObjectProperty *
+object_property_add_link(Object *obj, const char *name,
+ const char *type, Object **targetp,
+ void (*check)(const Object *, const char *,
+ Object *, Error **),
+ ObjectPropertyLinkFlags flags)
{
- object_add_link_prop(obj, name, type, targetp, check, flags, errp);
+ return object_add_link_prop(obj, name, type, targetp, check, flags);
}
ObjectProperty *
const char *type, ptrdiff_t offset,
void (*check)(const Object *obj, const char *name,
Object *val, Error **errp),
- ObjectPropertyLinkFlags flags,
- Error **errp)
+ ObjectPropertyLinkFlags flags)
{
- Error *local_err = NULL;
LinkProperty *prop = g_new0(LinkProperty, 1);
- gchar *full_type;
+ char *full_type;
ObjectProperty *op;
prop->offset = offset;
object_get_link_property,
check ? object_set_link_property : NULL,
object_release_link_property,
- prop,
- &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- goto out;
- }
+ prop);
op->resolve = object_resolve_link_property;
-out:
g_free(full_type);
return op;
}
-void object_property_add_const_link(Object *obj, const char *name,
- Object *target, Error **errp)
+ObjectProperty *
+object_property_add_const_link(Object *obj, const char *name,
+ Object *target)
{
- object_add_link_prop(obj, name, object_get_typename(target), target,
- NULL, OBJ_PROP_LINK_DIRECT, errp);
+ return object_add_link_prop(obj, name,
+ object_get_typename(target), target,
+ NULL, OBJ_PROP_LINK_DIRECT);
}
-gchar *object_get_canonical_path_component(Object *obj)
+char *object_get_canonical_path_component(Object *obj)
{
ObjectProperty *prop = NULL;
GHashTableIter iter;
return NULL;
}
-gchar *object_get_canonical_path(Object *obj)
+char *object_get_canonical_path(Object *obj)
{
Object *root = object_get_root();
char *newpath, *path = NULL;
return path;
}
-Object *object_resolve_path_component(Object *parent, const gchar *part)
+Object *object_resolve_path_component(Object *parent, const char *part)
{
ObjectProperty *prop = object_property_find(parent, part, NULL);
if (prop == NULL) {
}
static Object *object_resolve_abs_path(Object *parent,
- gchar **parts,
- const char *typename,
- int index)
+ char **parts,
+ const char *typename,
+ int index)
{
Object *child;
}
static Object *object_resolve_partial_path(Object *parent,
- gchar **parts,
- const char *typename,
- bool *ambiguous)
+ char **parts,
+ const char *typename,
+ bool *ambiguous)
{
Object *obj;
GHashTableIter iter;
bool *ambiguousp)
{
Object *obj;
- gchar **parts;
+ char **parts;
parts = g_strsplit(path, "/", 0);
assert(parts);
g_free(prop);
}
-void object_property_add_str(Object *obj, const char *name,
- char *(*get)(Object *, Error **),
- void (*set)(Object *, const char *, Error **),
- Error **errp)
+ObjectProperty *
+object_property_add_str(Object *obj, const char *name,
+ char *(*get)(Object *, Error **),
+ void (*set)(Object *, const char *, Error **))
{
- Error *local_err = NULL;
StringProperty *prop = g_malloc0(sizeof(*prop));
prop->get = get;
prop->set = set;
- object_property_add(obj, name, "string",
- get ? property_get_str : NULL,
- set ? property_set_str : NULL,
- property_release_str,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- }
+ return object_property_add(obj, name, "string",
+ get ? property_get_str : NULL,
+ set ? property_set_str : NULL,
+ property_release_str,
+ prop);
}
ObjectProperty *
object_class_property_add_str(ObjectClass *klass, const char *name,
char *(*get)(Object *, Error **),
void (*set)(Object *, const char *,
- Error **),
- Error **errp)
+ Error **))
{
- Error *local_err = NULL;
StringProperty *prop = g_malloc0(sizeof(*prop));
- ObjectProperty *rv;
prop->get = get;
prop->set = set;
- rv = object_class_property_add(klass, name, "string",
- get ? property_get_str : NULL,
- set ? property_set_str : NULL,
- NULL,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- }
-
- return rv;
+ return object_class_property_add(klass, name, "string",
+ get ? property_get_str : NULL,
+ set ? property_set_str : NULL,
+ NULL,
+ prop);
}
typedef struct BoolProperty
g_free(prop);
}
-void object_property_add_bool(Object *obj, const char *name,
- bool (*get)(Object *, Error **),
- void (*set)(Object *, bool, Error **),
- Error **errp)
+ObjectProperty *
+object_property_add_bool(Object *obj, const char *name,
+ bool (*get)(Object *, Error **),
+ void (*set)(Object *, bool, Error **))
{
- Error *local_err = NULL;
BoolProperty *prop = g_malloc0(sizeof(*prop));
prop->get = get;
prop->set = set;
- object_property_add(obj, name, "bool",
- get ? property_get_bool : NULL,
- set ? property_set_bool : NULL,
- property_release_bool,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- }
+ return object_property_add(obj, name, "bool",
+ get ? property_get_bool : NULL,
+ set ? property_set_bool : NULL,
+ property_release_bool,
+ prop);
}
ObjectProperty *
object_class_property_add_bool(ObjectClass *klass, const char *name,
bool (*get)(Object *, Error **),
- void (*set)(Object *, bool, Error **),
- Error **errp)
+ void (*set)(Object *, bool, Error **))
{
- Error *local_err = NULL;
BoolProperty *prop = g_malloc0(sizeof(*prop));
- ObjectProperty *rv;
prop->get = get;
prop->set = set;
- rv = object_class_property_add(klass, name, "bool",
- get ? property_get_bool : NULL,
- set ? property_set_bool : NULL,
- NULL,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- }
-
- return rv;
+ return object_class_property_add(klass, name, "bool",
+ get ? property_get_bool : NULL,
+ set ? property_set_bool : NULL,
+ NULL,
+ prop);
}
static void property_get_enum(Object *obj, Visitor *v, const char *name,
g_free(prop);
}
-void object_property_add_enum(Object *obj, const char *name,
- const char *typename,
- const QEnumLookup *lookup,
- int (*get)(Object *, Error **),
- void (*set)(Object *, int, Error **),
- Error **errp)
+ObjectProperty *
+object_property_add_enum(Object *obj, const char *name,
+ const char *typename,
+ const QEnumLookup *lookup,
+ int (*get)(Object *, Error **),
+ void (*set)(Object *, int, Error **))
{
- Error *local_err = NULL;
EnumProperty *prop = g_malloc(sizeof(*prop));
prop->lookup = lookup;
prop->get = get;
prop->set = set;
- object_property_add(obj, name, typename,
- get ? property_get_enum : NULL,
- set ? property_set_enum : NULL,
- property_release_enum,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- }
+ return object_property_add(obj, name, typename,
+ get ? property_get_enum : NULL,
+ set ? property_set_enum : NULL,
+ property_release_enum,
+ prop);
}
ObjectProperty *
const char *typename,
const QEnumLookup *lookup,
int (*get)(Object *, Error **),
- void (*set)(Object *, int, Error **),
- Error **errp)
+ void (*set)(Object *, int, Error **))
{
- Error *local_err = NULL;
EnumProperty *prop = g_malloc(sizeof(*prop));
- ObjectProperty *rv;
prop->lookup = lookup;
prop->get = get;
prop->set = set;
- rv = object_class_property_add(klass, name, typename,
- get ? property_get_enum : NULL,
- set ? property_set_enum : NULL,
- NULL,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- }
-
- return rv;
+ return object_class_property_add(klass, name, typename,
+ get ? property_get_enum : NULL,
+ set ? property_set_enum : NULL,
+ NULL,
+ prop);
}
typedef struct TMProperty {
g_free(prop);
}
-void object_property_add_tm(Object *obj, const char *name,
- void (*get)(Object *, struct tm *, Error **),
- Error **errp)
+ObjectProperty *
+object_property_add_tm(Object *obj, const char *name,
+ void (*get)(Object *, struct tm *, Error **))
{
- Error *local_err = NULL;
TMProperty *prop = g_malloc0(sizeof(*prop));
prop->get = get;
- object_property_add(obj, name, "struct tm",
- get ? property_get_tm : NULL, NULL,
- property_release_tm,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- }
+ return object_property_add(obj, name, "struct tm",
+ get ? property_get_tm : NULL, NULL,
+ property_release_tm,
+ prop);
}
ObjectProperty *
object_class_property_add_tm(ObjectClass *klass, const char *name,
- void (*get)(Object *, struct tm *, Error **),
- Error **errp)
+ void (*get)(Object *, struct tm *, Error **))
{
- Error *local_err = NULL;
TMProperty *prop = g_malloc0(sizeof(*prop));
- ObjectProperty *rv;
prop->get = get;
- rv = object_class_property_add(klass, name, "struct tm",
- get ? property_get_tm : NULL, NULL,
- NULL,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- }
-
- return rv;
+ return object_class_property_add(klass, name, "struct tm",
+ get ? property_get_tm : NULL,
+ NULL, NULL, prop);
}
static char *qdev_get_type(Object *obj, Error **errp)
*field = value;
}
-void object_property_add_uint8_ptr(Object *obj, const char *name,
- const uint8_t *v,
- ObjectPropertyFlags flags,
- Error **errp)
+ObjectProperty *
+object_property_add_uint8_ptr(Object *obj, const char *name,
+ const uint8_t *v,
+ ObjectPropertyFlags flags)
{
ObjectPropertyAccessor *getter = NULL;
ObjectPropertyAccessor *setter = NULL;
setter = property_set_uint8_ptr;
}
- object_property_add(obj, name, "uint8",
- getter, setter, NULL, (void *)v, errp);
+ return object_property_add(obj, name, "uint8",
+ getter, setter, NULL, (void *)v);
}
ObjectProperty *
object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name,
const uint8_t *v,
- ObjectPropertyFlags flags,
- Error **errp)
+ ObjectPropertyFlags flags)
{
ObjectPropertyAccessor *getter = NULL;
ObjectPropertyAccessor *setter = NULL;
}
return object_class_property_add(klass, name, "uint8",
- getter, setter, NULL, (void *)v, errp);
+ getter, setter, NULL, (void *)v);
}
-void object_property_add_uint16_ptr(Object *obj, const char *name,
- const uint16_t *v,
- ObjectPropertyFlags flags,
- Error **errp)
+ObjectProperty *
+object_property_add_uint16_ptr(Object *obj, const char *name,
+ const uint16_t *v,
+ ObjectPropertyFlags flags)
{
ObjectPropertyAccessor *getter = NULL;
ObjectPropertyAccessor *setter = NULL;
setter = property_set_uint16_ptr;
}
- object_property_add(obj, name, "uint16",
- getter, setter, NULL, (void *)v, errp);
+ return object_property_add(obj, name, "uint16",
+ getter, setter, NULL, (void *)v);
}
ObjectProperty *
object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name,
const uint16_t *v,
- ObjectPropertyFlags flags,
- Error **errp)
+ ObjectPropertyFlags flags)
{
ObjectPropertyAccessor *getter = NULL;
ObjectPropertyAccessor *setter = NULL;
}
return object_class_property_add(klass, name, "uint16",
- getter, setter, NULL, (void *)v, errp);
+ getter, setter, NULL, (void *)v);
}
-void object_property_add_uint32_ptr(Object *obj, const char *name,
- const uint32_t *v,
- ObjectPropertyFlags flags,
- Error **errp)
+ObjectProperty *
+object_property_add_uint32_ptr(Object *obj, const char *name,
+ const uint32_t *v,
+ ObjectPropertyFlags flags)
{
ObjectPropertyAccessor *getter = NULL;
ObjectPropertyAccessor *setter = NULL;
setter = property_set_uint32_ptr;
}
- object_property_add(obj, name, "uint32",
- getter, setter, NULL, (void *)v, errp);
+ return object_property_add(obj, name, "uint32",
+ getter, setter, NULL, (void *)v);
}
ObjectProperty *
object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name,
const uint32_t *v,
- ObjectPropertyFlags flags,
- Error **errp)
+ ObjectPropertyFlags flags)
{
ObjectPropertyAccessor *getter = NULL;
ObjectPropertyAccessor *setter = NULL;
}
return object_class_property_add(klass, name, "uint32",
- getter, setter, NULL, (void *)v, errp);
+ getter, setter, NULL, (void *)v);
}
-void object_property_add_uint64_ptr(Object *obj, const char *name,
- const uint64_t *v,
- ObjectPropertyFlags flags,
- Error **errp)
+ObjectProperty *
+object_property_add_uint64_ptr(Object *obj, const char *name,
+ const uint64_t *v,
+ ObjectPropertyFlags flags)
{
ObjectPropertyAccessor *getter = NULL;
ObjectPropertyAccessor *setter = NULL;
setter = property_set_uint64_ptr;
}
- object_property_add(obj, name, "uint64",
- getter, setter, NULL, (void *)v, errp);
+ return object_property_add(obj, name, "uint64",
+ getter, setter, NULL, (void *)v);
}
ObjectProperty *
object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name,
const uint64_t *v,
- ObjectPropertyFlags flags,
- Error **errp)
+ ObjectPropertyFlags flags)
{
ObjectPropertyAccessor *getter = NULL;
ObjectPropertyAccessor *setter = NULL;
}
return object_class_property_add(klass, name, "uint64",
- getter, setter, NULL, (void *)v, errp);
+ getter, setter, NULL, (void *)v);
}
typedef struct {
}
static Object *property_resolve_alias(Object *obj, void *opaque,
- const gchar *part)
+ const char *part)
{
AliasProperty *prop = opaque;
g_free(prop);
}
-void object_property_add_alias(Object *obj, const char *name,
- Object *target_obj, const char *target_name,
- Error **errp)
+ObjectProperty *
+object_property_add_alias(Object *obj, const char *name,
+ Object *target_obj, const char *target_name)
{
AliasProperty *prop;
ObjectProperty *op;
ObjectProperty *target_prop;
- gchar *prop_type;
- Error *local_err = NULL;
+ g_autofree char *prop_type = NULL;
- target_prop = object_property_find(target_obj, target_name, errp);
- if (!target_prop) {
- return;
- }
+ target_prop = object_property_find(target_obj, target_name,
+ &error_abort);
if (object_property_is_child(target_prop)) {
prop_type = g_strdup_printf("link%s",
property_get_alias,
property_set_alias,
property_release_alias,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- goto out;
- }
+ prop);
op->resolve = property_resolve_alias;
if (target_prop->defval) {
op->defval = qobject_ref(target_prop->defval);
}
object_property_set_description(obj, op->name,
- target_prop->description,
- &error_abort);
-
-out:
- g_free(prop_type);
+ target_prop->description);
+ return op;
}
void object_property_set_description(Object *obj, const char *name,
- const char *description, Error **errp)
+ const char *description)
{
ObjectProperty *op;
- op = object_property_find(obj, name, errp);
- if (!op) {
- return;
- }
-
+ op = object_property_find(obj, name, &error_abort);
g_free(op->description);
op->description = g_strdup(description);
}
void object_class_property_set_description(ObjectClass *klass,
const char *name,
- const char *description,
- Error **errp)
+ const char *description)
{
ObjectProperty *op;
op = g_hash_table_lookup(klass->properties, name);
- if (!op) {
- error_setg(errp, "Property '.%s' not found", name);
- return;
- }
-
g_free(op->description);
op->description = g_strdup(description);
}
static void object_class_init(ObjectClass *klass, void *data)
{
object_class_property_add_str(klass, "type", qdev_get_type,
- NULL, &error_abort);
+ NULL);
}
static void register_types(void)
if (id != NULL) {
object_property_add_child(object_get_objects_root(),
- id, obj, &local_err);
- if (local_err) {
- goto out;
- }
+ id, obj);
}
user_creatable_complete(USER_CREATABLE(obj), &local_err);
if (local_err) {
if (id != NULL) {
- object_property_del(object_get_objects_root(),
- id, &error_abort);
+ object_property_del(object_get_objects_root(), id);
}
goto out;
}
PRManagerClass *prmgr_klass = PR_MANAGER_CLASS(klass);
UserCreatableClass *uc_klass = USER_CREATABLE_CLASS(klass);
- object_class_property_add_str(klass, "path", get_path, set_path,
- &error_abort);
+ object_class_property_add_str(klass, "path", get_path, set_path);
uc_klass->complete = pr_manager_helper_complete;
prmgr_klass->run = pr_manager_helper_run;
prmgr_klass->is_connected = pr_manager_helper_is_connected;
}
object_property_set_int(obj, ms->ram_size, "size", &error_fatal);
object_property_add_child(object_get_objects_root(), mc->default_ram_id,
- obj, &error_fatal);
+ obj);
/* Ensure backend's memory region name is equal to mc->default_ram_id */
object_property_set_bool(obj, false, "x-use-canonical-path-for-ramblock-id",
&error_fatal);
exit(0);
}
object_property_add_child(object_get_root(), "machine",
- OBJECT(current_machine), &error_abort);
+ OBJECT(current_machine));
object_property_add_child(container_get(OBJECT(current_machine),
"/unattached"),
- "sysbus", OBJECT(sysbus_get_default()),
- NULL);
+ "sysbus", OBJECT(sysbus_get_default()));
if (machine_class->minimum_page_bits) {
if (!set_preferred_target_page_bits(machine_class->minimum_page_bits)) {
TYPE_MEMORY_REGION,
(Object **)&cpu->secure_memory,
qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_STRONG,
- &error_abort);
+ OBJ_PROP_LINK_STRONG);
}
if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) {
if (arm_feature(&cpu->env, ARM_FEATURE_PMU)) {
cpu->has_pmu = true;
- object_property_add_bool(obj, "pmu", arm_get_pmu, arm_set_pmu,
- &error_abort);
+ object_property_add_bool(obj, "pmu", arm_get_pmu, arm_set_pmu);
}
/*
if (arm_feature(&cpu->env, ARM_FEATURE_M_SECURITY)) {
object_property_add_link(obj, "idau", TYPE_IDAU_INTERFACE, &cpu->idau,
qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_STRONG,
- &error_abort);
+ OBJ_PROP_LINK_STRONG);
/*
* M profile: initial value of the Secure VTOR. We can't just use
* a simple DEFINE_PROP_UINT32 for this because we want to permit
*/
object_property_add_uint32_ptr(obj, "init-svtor",
&cpu->init_svtor,
- OBJ_PROP_FLAG_READWRITE, &error_abort);
+ OBJ_PROP_FLAG_READWRITE);
}
qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property);
/* ARM processors have a weak memory model */
#define TCG_GUEST_DEFAULT_MO (0)
+#ifdef TARGET_AARCH64
+#define KVM_HAVE_MCE_INJECTION 1
+#endif
+
#define EXCP_UDEF 1 /* undefined instruction */
#define EXCP_SWI 2 /* software interrupt */
#define EXCP_PREFETCH_ABORT 3
uint32_t vq;
object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
- cpu_arm_set_sve, NULL, NULL, &error_fatal);
+ cpu_arm_set_sve, NULL, NULL);
for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
char name[8];
sprintf(name, "sve%d", vq * 128);
object_property_add(obj, name, "bool", cpu_arm_get_sve_vq,
- cpu_arm_set_sve_vq, NULL, NULL, &error_fatal);
+ cpu_arm_set_sve_vq, NULL, NULL);
}
}
aarch64_add_sve_properties(obj);
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
- cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
+ cpu_max_set_sve_max_vq, NULL, NULL);
}
static const ARMCPUInfo aarch64_cpus[] = {
static void aarch64_cpu_initfn(Object *obj)
{
object_property_add_bool(obj, "aarch64", aarch64_cpu_get_aarch64,
- aarch64_cpu_set_aarch64, NULL);
+ aarch64_cpu_set_aarch64);
object_property_set_description(obj, "aarch64",
"Set on/off to enable/disable aarch64 "
- "execution state ",
- NULL);
+ "execution state ");
}
static void aarch64_cpu_finalizefn(Object *obj)
#endif
cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
+ cc->gdb_core_xml_file = "arm-m-profile.xml";
}
static const ARMCPUInfo arm_tcg_cpus[] = {
}
return gdb_get_reg32(mem_buf, 0);
case 25:
- /* CPSR */
- return gdb_get_reg32(mem_buf, cpsr_read(env));
+ /* CPSR, or XPSR for M-profile */
+ if (arm_feature(env, ARM_FEATURE_M)) {
+ return gdb_get_reg32(mem_buf, xpsr_read(env));
+ } else {
+ return gdb_get_reg32(mem_buf, cpsr_read(env));
+ }
}
/* Unknown register. */
return 0;
}
return 4;
case 25:
- /* CPSR */
- cpsr_write(env, tmp, 0xffffffff, CPSRWriteByGDBStub);
+ /* CPSR, or XPSR for M-profile */
+ if (arm_feature(env, ARM_FEATURE_M)) {
+ /*
+ * Don't allow writing to XPSR.Exception as it can cause
+ * a transition into or out of handler mode (it's not
+ * writeable via the MSR insn so this is a reasonable
+ * restriction). Other fields are safe to update.
+ */
+ xpsr_write(env, tmp, ~XPSR_EXCP);
+ } else {
+ cpsr_write(env, tmp, 0xffffffff, CPSRWriteByGDBStub);
+ }
return 4;
}
/* Unknown register. */
* Report exception with ESR indicating a fault due to a
* translation table walk for a cache maintenance instruction.
*/
- syn = syn_data_abort_no_iss(current_el == target_el,
+ syn = syn_data_abort_no_iss(current_el == target_el, 0,
fi.ea, 1, fi.s1ptw, 1, fsc);
env->exception.vaddress = value;
env->exception.fsr = fsr;
DEF_HELPER_4(vfp_muladdd, f64, f64, f64, f64, ptr)
DEF_HELPER_4(vfp_muladds, f32, f32, f32, f32, ptr)
-DEF_HELPER_3(recps_f32, f32, f32, f32, env)
-DEF_HELPER_3(rsqrts_f32, f32, f32, f32, env)
+DEF_HELPER_3(recps_f32, f32, env, f32, f32)
+DEF_HELPER_3(rsqrts_f32, f32, env, f32, f32)
DEF_HELPER_FLAGS_2(recpe_f16, TCG_CALL_NO_RWG, f16, f16, ptr)
DEF_HELPER_FLAGS_2(recpe_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
DEF_HELPER_FLAGS_2(recpe_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
DEF_HELPER_FLAGS_2(rsqrte_f16, TCG_CALL_NO_RWG, f16, f16, ptr)
DEF_HELPER_FLAGS_2(rsqrte_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
DEF_HELPER_FLAGS_2(rsqrte_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
-DEF_HELPER_2(recpe_u32, i32, i32, ptr)
-DEF_HELPER_FLAGS_2(rsqrte_u32, TCG_CALL_NO_RWG, i32, i32, ptr)
+DEF_HELPER_FLAGS_1(recpe_u32, TCG_CALL_NO_RWG, i32, i32)
+DEF_HELPER_FLAGS_1(rsqrte_u32, TCG_CALL_NO_RWG, i32, i32)
DEF_HELPER_FLAGS_4(neon_tbl, TCG_CALL_NO_RWG, i32, i32, i32, ptr, i32)
DEF_HELPER_3(shl_cc, i32, env, i32, i32)
DEF_HELPER_2(neon_pmax_u16, i32, i32, i32)
DEF_HELPER_2(neon_pmax_s16, i32, i32, i32)
-DEF_HELPER_2(neon_abd_u8, i32, i32, i32)
-DEF_HELPER_2(neon_abd_s8, i32, i32, i32)
-DEF_HELPER_2(neon_abd_u16, i32, i32, i32)
-DEF_HELPER_2(neon_abd_s16, i32, i32, i32)
-DEF_HELPER_2(neon_abd_u32, i32, i32, i32)
-DEF_HELPER_2(neon_abd_s32, i32, i32, i32)
-
DEF_HELPER_2(neon_shl_u16, i32, i32, i32)
DEF_HELPER_2(neon_shl_s16, i32, i32, i32)
DEF_HELPER_2(neon_rshl_u8, i32, i32, i32)
DEF_HELPER_FLAGS_2(neon_qneg_s32, TCG_CALL_NO_RWG, i32, env, i32)
DEF_HELPER_FLAGS_2(neon_qneg_s64, TCG_CALL_NO_RWG, i64, env, i64)
-DEF_HELPER_3(neon_abd_f32, i32, i32, i32, ptr)
DEF_HELPER_3(neon_ceq_f32, i32, i32, i32, ptr)
DEF_HELPER_3(neon_cge_f32, i32, i32, i32, ptr)
DEF_HELPER_3(neon_cgt_f32, i32, i32, i32, ptr)
DEF_HELPER_FLAGS_5(gvec_fmul_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmul_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_fabd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
+
DEF_HELPER_FLAGS_5(gvec_ftsmul_h, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_ftsmul_s, TCG_CALL_NO_RWG,
DEF_HELPER_FLAGS_4(neon_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_ssra_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_ssra_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_ssra_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_ssra_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_3(gvec_usra_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_usra_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_usra_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_usra_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_3(gvec_srshr_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_srshr_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_srshr_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_srshr_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_3(gvec_urshr_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_urshr_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_urshr_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_urshr_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_3(gvec_srsra_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_srsra_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_srsra_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_srsra_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_3(gvec_ursra_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_ursra_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_ursra_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_ursra_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_3(gvec_sri_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_sri_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_sri_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_sri_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_3(gvec_sli_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_sli_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_sli_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_sli_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(gvec_sabd_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_sabd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_sabd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_sabd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(gvec_uabd_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_uabd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_uabd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_uabd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(gvec_saba_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_saba_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_saba_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_saba_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(gvec_uaba_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_uaba_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_uaba_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_uaba_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
#ifdef TARGET_AARCH64
#include "helper-a64.h"
#include "helper-sve.h"
| ARM_EL_IL | (ea << 9) | (s1ptw << 7) | fsc;
}
-static inline uint32_t syn_data_abort_no_iss(int same_el,
+static inline uint32_t syn_data_abort_no_iss(int same_el, int fnv,
int ea, int cm, int s1ptw,
int wnr, int fsc)
{
return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
| ARM_EL_IL
- | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
+ | (fnv << 10) | (ea << 9) | (cm << 8) | (s1ptw << 7)
+ | (wnr << 6) | fsc;
}
static inline uint32_t syn_data_abort_with_iss(int same_el,
ARM_CPU(obj)->kvm_adjvtime = true;
object_property_add_bool(obj, "kvm-no-adjvtime", kvm_no_adjvtime_get,
- kvm_no_adjvtime_set, &error_abort);
+ kvm_no_adjvtime_set);
object_property_set_description(obj, "kvm-no-adjvtime",
"Set on to disable the adjustment of "
"the virtual counter. VM stopped time "
- "will be counted.", &error_abort);
+ "will be counted.");
}
bool kvm_arm_pmu_supported(CPUState *cpu)
#include "sysemu/kvm_int.h"
#include "kvm_arm.h"
#include "internals.h"
+#include "hw/acpi/acpi.h"
+#include "hw/acpi/ghes.h"
+#include "hw/arm/virt.h"
static bool have_guest_debug;
return KVM_PUT_RUNTIME_STATE;
}
+/* Callers must hold the iothread mutex lock */
+static void kvm_inject_arm_sea(CPUState *c)
+{
+ ARMCPU *cpu = ARM_CPU(c);
+ CPUARMState *env = &cpu->env;
+ CPUClass *cc = CPU_GET_CLASS(c);
+ uint32_t esr;
+ bool same_el;
+
+ c->exception_index = EXCP_DATA_ABORT;
+ env->exception.target_el = 1;
+
+ /*
+ * Set the DFSC to synchronous external abort and set FnV to not valid,
+ * this will tell guest the FAR_ELx is UNKNOWN for this abort.
+ */
+ same_el = arm_current_el(env) == env->exception.target_el;
+ esr = syn_data_abort_no_iss(same_el, 1, 0, 0, 0, 0, 0x10);
+
+ env->exception.syndrome = esr;
+
+ cc->do_interrupt(c);
+}
+
#define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
return ret;
}
+void kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr)
+{
+ ram_addr_t ram_addr;
+ hwaddr paddr;
+ Object *obj = qdev_get_machine();
+ VirtMachineState *vms = VIRT_MACHINE(obj);
+ bool acpi_enabled = virt_is_acpi_enabled(vms);
+
+ assert(code == BUS_MCEERR_AR || code == BUS_MCEERR_AO);
+
+ if (acpi_enabled && addr &&
+ object_property_get_bool(obj, "ras", NULL)) {
+ ram_addr = qemu_ram_addr_from_host(addr);
+ if (ram_addr != RAM_ADDR_INVALID &&
+ kvm_physical_memory_addr_from_host(c->kvm_state, addr, &paddr)) {
+ kvm_hwpoison_page_add(ram_addr);
+ /*
+ * If this is a BUS_MCEERR_AR, we know we have been called
+ * synchronously from the vCPU thread, so we can easily
+ * synchronize the state and inject an error.
+ *
+ * TODO: we currently don't tell the guest at all about
+ * BUS_MCEERR_AO. In that case we might either be being
+ * called synchronously from the vCPU thread, or a bit
+ * later from the main thread, so doing the injection of
+ * the error would be more complicated.
+ */
+ if (code == BUS_MCEERR_AR) {
+ kvm_cpu_synchronize_state(c);
+ if (!acpi_ghes_record_errors(ACPI_HEST_SRC_ID_SEA, paddr)) {
+ kvm_inject_arm_sea(c);
+ } else {
+ error_report("failed to record the error");
+ abort();
+ }
+ }
+ return;
+ }
+ if (code == BUS_MCEERR_AO) {
+ error_report("Hardware memory error at addr %p for memory used by "
+ "QEMU itself instead of guest system!", addr);
+ }
+ }
+
+ if (code == BUS_MCEERR_AR) {
+ error_report("Hardware memory error!");
+ exit(1);
+ }
+}
+
/* C6.6.29 BRK instruction */
static const uint32_t brk_insn = 0xd4200000;
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
+@3same_q0 .... ... . . . size:2 .... .... .... . 0 . . .... \
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp q=0
+
+# For FP insns the high bit of 'size' is used as part of opcode decode
+@3same_fp .... ... . . . . size:1 .... .... .... . q:1 . . .... \
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
+@3same_fp_q0 .... ... . . . . size:1 .... .... .... . 0 . . .... \
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp q=0
+
+VHADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 0 .... @3same
+VHADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 0 .... @3same
VQADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 1 .... @3same
VQADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 1 .... @3same
+VRHADD_S_3s 1111 001 0 0 . .. .... .... 0001 . . . 0 .... @3same
+VRHADD_U_3s 1111 001 1 0 . .. .... .... 0001 . . . 0 .... @3same
+
@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
+VHSUB_S_3s 1111 001 0 0 . .. .... .... 0010 . . . 0 .... @3same
+VHSUB_U_3s 1111 001 1 0 . .. .... .... 0010 . . . 0 .... @3same
+
VQSUB_S_3s 1111 001 0 0 . .. .... .... 0010 . . . 1 .... @3same
VQSUB_U_3s 1111 001 1 0 . .. .... .... 0010 . . . 1 .... @3same
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
-VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same
-VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same
+# The _rev suffix indicates that Vn and Vm are reversed. This is
+# the case for shifts. In the Arm ARM these insns are documented
+# with the Vm and Vn fields in their usual places, but in the
+# assembly the operands are listed "backwards", ie in the order
+# Dd, Dm, Dn where other insns use Dd, Dn, Dm. For QEMU we choose
+# to consider Vm and Vn as being in different fields in the insn,
+# which allows us to avoid special-casing shifts in the trans_
+# function code. We would otherwise need to manually swap the operands
+# over to call Neon helper functions that are shared with AArch64,
+# which does not have this odd reversed-operand situation.
+@3same_rev .... ... . . . size:2 .... .... .... . q:1 . . .... \
+ &3same vn=%vm_dp vm=%vn_dp vd=%vd_dp
+
+VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same_rev
+VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same_rev
+
+# Insns operating on 64-bit elements (size!=0b11 handled elsewhere)
+# The _rev suffix indicates that Vn and Vm are reversed (as explained
+# by the comment for the @3same_rev format).
+@3same_64_rev .... ... . . . 11 .... .... .... . q:1 . . .... \
+ &3same vm=%vn_dp vn=%vm_dp vd=%vd_dp size=3
+
+{
+ VQSHL_S64_3s 1111 001 0 0 . .. .... .... 0100 . . . 1 .... @3same_64_rev
+ VQSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 1 .... @3same_rev
+}
+{
+ VQSHL_U64_3s 1111 001 1 0 . .. .... .... 0100 . . . 1 .... @3same_64_rev
+ VQSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 1 .... @3same_rev
+}
+{
+ VRSHL_S64_3s 1111 001 0 0 . .. .... .... 0101 . . . 0 .... @3same_64_rev
+ VRSHL_S_3s 1111 001 0 0 . .. .... .... 0101 . . . 0 .... @3same_rev
+}
+{
+ VRSHL_U64_3s 1111 001 1 0 . .. .... .... 0101 . . . 0 .... @3same_64_rev
+ VRSHL_U_3s 1111 001 1 0 . .. .... .... 0101 . . . 0 .... @3same_rev
+}
+{
+ VQRSHL_S64_3s 1111 001 0 0 . .. .... .... 0101 . . . 1 .... @3same_64_rev
+ VQRSHL_S_3s 1111 001 0 0 . .. .... .... 0101 . . . 1 .... @3same_rev
+}
+{
+ VQRSHL_U64_3s 1111 001 1 0 . .. .... .... 0101 . . . 1 .... @3same_64_rev
+ VQRSHL_U_3s 1111 001 1 0 . .. .... .... 0101 . . . 1 .... @3same_rev
+}
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
+VABD_S_3s 1111 001 0 0 . .. .... .... 0111 . . . 0 .... @3same
+VABD_U_3s 1111 001 1 0 . .. .... .... 0111 . . . 0 .... @3same
+
+VABA_S_3s 1111 001 0 0 . .. .... .... 0111 . . . 1 .... @3same
+VABA_U_3s 1111 001 1 0 . .. .... .... 0111 . . . 1 .... @3same
+
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
VMUL_3s 1111 001 0 0 . .. .... .... 1001 . . . 1 .... @3same
VMUL_p_3s 1111 001 1 0 . .. .... .... 1001 . . . 1 .... @3same
+
+VPMAX_S_3s 1111 001 0 0 . .. .... .... 1010 . . . 0 .... @3same_q0
+VPMAX_U_3s 1111 001 1 0 . .. .... .... 1010 . . . 0 .... @3same_q0
+
+VPMIN_S_3s 1111 001 0 0 . .. .... .... 1010 . . . 1 .... @3same_q0
+VPMIN_U_3s 1111 001 1 0 . .. .... .... 1010 . . . 1 .... @3same_q0
+
+VQDMULH_3s 1111 001 0 0 . .. .... .... 1011 . . . 0 .... @3same
+VQRDMULH_3s 1111 001 1 0 . .. .... .... 1011 . . . 0 .... @3same
+
+VPADD_3s 1111 001 0 0 . .. .... .... 1011 . . . 1 .... @3same_q0
+
+VQRDMLAH_3s 1111 001 1 0 . .. .... .... 1011 ... 1 .... @3same
+
+SHA1_3s 1111 001 0 0 . optype:2 .... .... 1100 . 1 . 0 .... \
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
+SHA256H_3s 1111 001 1 0 . 00 .... .... 1100 . 1 . 0 .... \
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
+SHA256H2_3s 1111 001 1 0 . 01 .... .... 1100 . 1 . 0 .... \
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
+SHA256SU1_3s 1111 001 1 0 . 10 .... .... 1100 . 1 . 0 .... \
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
+
+VFMA_fp_3s 1111 001 0 0 . 0 . .... .... 1100 ... 1 .... @3same_fp
+VFMS_fp_3s 1111 001 0 0 . 1 . .... .... 1100 ... 1 .... @3same_fp
+
+VQRDMLSH_3s 1111 001 1 0 . .. .... .... 1100 ... 1 .... @3same
+
+VADD_fp_3s 1111 001 0 0 . 0 . .... .... 1101 ... 0 .... @3same_fp
+VSUB_fp_3s 1111 001 0 0 . 1 . .... .... 1101 ... 0 .... @3same_fp
+VPADD_fp_3s 1111 001 1 0 . 0 . .... .... 1101 ... 0 .... @3same_fp_q0
+VABD_fp_3s 1111 001 1 0 . 1 . .... .... 1101 ... 0 .... @3same_fp
+VMLA_fp_3s 1111 001 0 0 . 0 . .... .... 1101 ... 1 .... @3same_fp
+VMLS_fp_3s 1111 001 0 0 . 1 . .... .... 1101 ... 1 .... @3same_fp
+VMUL_fp_3s 1111 001 1 0 . 0 . .... .... 1101 ... 1 .... @3same_fp
+VCEQ_fp_3s 1111 001 0 0 . 0 . .... .... 1110 ... 0 .... @3same_fp
+VCGE_fp_3s 1111 001 1 0 . 0 . .... .... 1110 ... 0 .... @3same_fp
+VACGE_fp_3s 1111 001 1 0 . 0 . .... .... 1110 ... 1 .... @3same_fp
+VCGT_fp_3s 1111 001 1 0 . 1 . .... .... 1110 ... 0 .... @3same_fp
+VACGT_fp_3s 1111 001 1 0 . 1 . .... .... 1110 ... 1 .... @3same_fp
+VMAX_fp_3s 1111 001 0 0 . 0 . .... .... 1111 ... 0 .... @3same_fp
+VMIN_fp_3s 1111 001 0 0 . 1 . .... .... 1111 ... 0 .... @3same_fp
+VPMAX_fp_3s 1111 001 1 0 . 0 . .... .... 1111 ... 0 .... @3same_fp_q0
+VPMIN_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 0 .... @3same_fp_q0
+VRECPS_fp_3s 1111 001 0 0 . 0 . .... .... 1111 ... 1 .... @3same_fp
+VRSQRTS_fp_3s 1111 001 0 0 . 1 . .... .... 1111 ... 1 .... @3same_fp
+VMAXNM_fp_3s 1111 001 1 0 . 0 . .... .... 1111 ... 1 .... @3same_fp
+VMINNM_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 1 .... @3same_fp
NEON_POP(pmax_u16, neon_u16, 2)
#undef NEON_FN
-#define NEON_FN(dest, src1, src2) \
- dest = (src1 > src2) ? (src1 - src2) : (src2 - src1)
-NEON_VOP(abd_s8, neon_s8, 4)
-NEON_VOP(abd_u8, neon_u8, 4)
-NEON_VOP(abd_s16, neon_s16, 2)
-NEON_VOP(abd_u16, neon_u16, 2)
-NEON_VOP(abd_s32, neon_s32, 1)
-NEON_VOP(abd_u32, neon_u32, 1)
-#undef NEON_FN
-
#define NEON_FN(dest, src1, src2) do { \
int8_t tmp; \
tmp = (int8_t)src2; \
}
/* NEON Float helpers. */
-uint32_t HELPER(neon_abd_f32)(uint32_t a, uint32_t b, void *fpstp)
-{
- float_status *fpst = fpstp;
- float32 f0 = make_float32(a);
- float32 f1 = make_float32(b);
- return float32_val(float32_abs(float32_sub(f0, f1, fpst)));
-}
/* Floating point comparisons produce an integer result.
* Note that EQ doesn't signal InvalidOp for QNaNs but GE and GT do.
* ISV field.
*/
if (!(template_syn & ARM_EL_ISV) || target_el != 2 || s1ptw) {
- syn = syn_data_abort_no_iss(same_el,
+ syn = syn_data_abort_no_iss(same_el, 0,
ea, 0, s1ptw, is_write, fsc);
} else {
/*
is_q ? 16 : 8, vec_full_reg_size(s));
}
-/* Expand a 2-operand AdvSIMD vector operation using an op descriptor. */
-static void gen_gvec_op2(DisasContext *s, bool is_q, int rd,
- int rn, const GVecGen2 *gvec_op)
-{
- tcg_gen_gvec_2(vec_full_reg_offset(s, rd), vec_full_reg_offset(s, rn),
- is_q ? 16 : 8, vec_full_reg_size(s), gvec_op);
-}
-
-/* Expand a 2-operand + immediate AdvSIMD vector operation using
- * an op descriptor.
- */
-static void gen_gvec_op2i(DisasContext *s, bool is_q, int rd,
- int rn, int64_t imm, const GVecGen2i *gvec_op)
-{
- tcg_gen_gvec_2i(vec_full_reg_offset(s, rd), vec_full_reg_offset(s, rn),
- is_q ? 16 : 8, vec_full_reg_size(s), imm, gvec_op);
-}
-
-/* Expand a 3-operand AdvSIMD vector operation using an op descriptor. */
-static void gen_gvec_op3(DisasContext *s, bool is_q, int rd,
- int rn, int rm, const GVecGen3 *gvec_op)
-{
- tcg_gen_gvec_3(vec_full_reg_offset(s, rd), vec_full_reg_offset(s, rn),
- vec_full_reg_offset(s, rm), is_q ? 16 : 8,
- vec_full_reg_size(s), gvec_op);
-}
-
/* Expand a 3-operand operation using an out-of-line helper. */
static void gen_gvec_op3_ool(DisasContext *s, bool is_q, int rd,
int rn, int rm, int data, gen_helper_gvec_3 *fn)
is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
}
-/* Expand a 3-operand + env pointer operation using
- * an out-of-line helper.
- */
-static void gen_gvec_op3_env(DisasContext *s, bool is_q, int rd,
- int rn, int rm, gen_helper_gvec_3_ptr *fn)
-{
- tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
- vec_full_reg_offset(s, rn),
- vec_full_reg_offset(s, rm), cpu_env,
- is_q ? 16 : 8, vec_full_reg_size(s), 0, fn);
-}
-
/* Expand a 3-operand + fpstatus pointer + simd data value operation using
* an out-of-line helper.
*/
switch (opcode) {
case 0x3c: /* URECPE */
- gen_helper_recpe_u32(tcg_res, tcg_op, fpst);
+ gen_helper_recpe_u32(tcg_res, tcg_op);
break;
case 0x3d: /* FRECPE */
gen_helper_recpe_f32(tcg_res, tcg_op, fpst);
int size = 32 - clz32(immh) - 1;
int immhb = immh << 3 | immb;
int shift = 2 * (8 << size) - immhb;
- bool accumulate = false;
- int dsize = is_q ? 128 : 64;
- int esize = 8 << size;
- int elements = dsize/esize;
- MemOp memop = size | (is_u ? 0 : MO_SIGN);
- TCGv_i64 tcg_rn = new_tmp_a64(s);
- TCGv_i64 tcg_rd = new_tmp_a64(s);
- TCGv_i64 tcg_round;
- uint64_t round_const;
- int i;
+ GVecGen2iFn *gvec_fn;
if (extract32(immh, 3, 1) && !is_q) {
unallocated_encoding(s);
switch (opcode) {
case 0x02: /* SSRA / USRA (accumulate) */
- if (is_u) {
- /* Shift count same as element size produces zero to add. */
- if (shift == 8 << size) {
- goto done;
- }
- gen_gvec_op2i(s, is_q, rd, rn, shift, &usra_op[size]);
- } else {
- /* Shift count same as element size produces all sign to add. */
- if (shift == 8 << size) {
- shift -= 1;
- }
- gen_gvec_op2i(s, is_q, rd, rn, shift, &ssra_op[size]);
- }
- return;
+ gvec_fn = is_u ? gen_gvec_usra : gen_gvec_ssra;
+ break;
+
case 0x08: /* SRI */
- /* Shift count same as element size is valid but does nothing. */
- if (shift == 8 << size) {
- goto done;
- }
- gen_gvec_op2i(s, is_q, rd, rn, shift, &sri_op[size]);
- return;
+ gvec_fn = gen_gvec_sri;
+ break;
case 0x00: /* SSHR / USHR */
if (is_u) {
/* Shift count the same size as element size produces zero. */
tcg_gen_gvec_dup_imm(size, vec_full_reg_offset(s, rd),
is_q ? 16 : 8, vec_full_reg_size(s), 0);
- } else {
- gen_gvec_fn2i(s, is_q, rd, rn, shift, tcg_gen_gvec_shri, size);
+ return;
}
+ gvec_fn = tcg_gen_gvec_shri;
} else {
/* Shift count the same size as element size produces all sign. */
if (shift == 8 << size) {
shift -= 1;
}
- gen_gvec_fn2i(s, is_q, rd, rn, shift, tcg_gen_gvec_sari, size);
+ gvec_fn = tcg_gen_gvec_sari;
}
- return;
+ break;
case 0x04: /* SRSHR / URSHR (rounding) */
+ gvec_fn = is_u ? gen_gvec_urshr : gen_gvec_srshr;
break;
+
case 0x06: /* SRSRA / URSRA (accum + rounding) */
- accumulate = true;
+ gvec_fn = is_u ? gen_gvec_ursra : gen_gvec_srsra;
break;
+
default:
g_assert_not_reached();
}
- round_const = 1ULL << (shift - 1);
- tcg_round = tcg_const_i64(round_const);
-
- for (i = 0; i < elements; i++) {
- read_vec_element(s, tcg_rn, rn, i, memop);
- if (accumulate) {
- read_vec_element(s, tcg_rd, rd, i, memop);
- }
-
- handle_shri_with_rndacc(tcg_rd, tcg_rn, tcg_round,
- accumulate, is_u, size, shift);
-
- write_vec_element(s, tcg_rd, rd, i, size);
- }
- tcg_temp_free_i64(tcg_round);
-
- done:
- clear_vec_high(s, is_q, rd);
+ gen_gvec_fn2i(s, is_q, rd, rn, shift, gvec_fn, size);
}
/* SHL/SLI - Vector shift left */
}
if (insert) {
- gen_gvec_op2i(s, is_q, rd, rn, shift, &sli_op[size]);
+ gen_gvec_fn2i(s, is_q, rd, rn, shift, gen_gvec_sli, size);
} else {
gen_gvec_fn2i(s, is_q, rd, rn, shift, tcg_gen_gvec_shli, size);
}
switch (opcode) {
case 0x01: /* SQADD, UQADD */
- tcg_gen_gvec_4(vec_full_reg_offset(s, rd),
- offsetof(CPUARMState, vfp.qc),
- vec_full_reg_offset(s, rn),
- vec_full_reg_offset(s, rm),
- is_q ? 16 : 8, vec_full_reg_size(s),
- (u ? uqadd_op : sqadd_op) + size);
+ if (u) {
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uqadd_qc, size);
+ } else {
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqadd_qc, size);
+ }
return;
case 0x05: /* SQSUB, UQSUB */
- tcg_gen_gvec_4(vec_full_reg_offset(s, rd),
- offsetof(CPUARMState, vfp.qc),
- vec_full_reg_offset(s, rn),
- vec_full_reg_offset(s, rm),
- is_q ? 16 : 8, vec_full_reg_size(s),
- (u ? uqsub_op : sqsub_op) + size);
+ if (u) {
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uqsub_qc, size);
+ } else {
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqsub_qc, size);
+ }
return;
case 0x08: /* SSHL, USHL */
- gen_gvec_op3(s, is_q, rd, rn, rm,
- u ? &ushl_op[size] : &sshl_op[size]);
+ if (u) {
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_ushl, size);
+ } else {
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sshl, size);
+ }
return;
case 0x0c: /* SMAX, UMAX */
if (u) {
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_smin, size);
}
return;
+ case 0xe: /* SABD, UABD */
+ if (u) {
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uabd, size);
+ } else {
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sabd, size);
+ }
+ return;
+ case 0xf: /* SABA, UABA */
+ if (u) {
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uaba, size);
+ } else {
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_saba, size);
+ }
+ return;
case 0x10: /* ADD, SUB */
if (u) {
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_sub, size);
return;
case 0x12: /* MLA, MLS */
if (u) {
- gen_gvec_op3(s, is_q, rd, rn, rm, &mls_op[size]);
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_mls, size);
} else {
- gen_gvec_op3(s, is_q, rd, rn, rm, &mla_op[size]);
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_mla, size);
}
return;
case 0x11:
if (!u) { /* CMTST */
- gen_gvec_op3(s, is_q, rd, rn, rm, &cmtst_op[size]);
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_cmtst, size);
return;
}
/* else CMEQ */
genenvfn = fns[size][u];
break;
}
- case 0xe: /* SABD, UABD */
- case 0xf: /* SABA, UABA */
- {
- static NeonGenTwoOpFn * const fns[3][2] = {
- { gen_helper_neon_abd_s8, gen_helper_neon_abd_u8 },
- { gen_helper_neon_abd_s16, gen_helper_neon_abd_u16 },
- { gen_helper_neon_abd_s32, gen_helper_neon_abd_u32 },
- };
- genfn = fns[size][u];
- break;
- }
case 0x16: /* SQDMULH, SQRDMULH */
{
static NeonGenTwoOpEnvFn * const fns[2][2] = {
switch (opcode) {
case 0x0: /* SQRDMLAH (vector) */
- switch (size) {
- case 1:
- gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlah_s16);
- break;
- case 2:
- gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlah_s32);
- break;
- default:
- g_assert_not_reached();
- }
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqrdmlah_qc, size);
return;
case 0x1: /* SQRDMLSH (vector) */
- switch (size) {
- case 1:
- gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlsh_s16);
- break;
- case 2:
- gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlsh_s32);
- break;
- default:
- g_assert_not_reached();
- }
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqrdmlsh_qc, size);
return;
case 0x2: /* SDOT / UDOT */
unallocated_encoding(s);
return;
}
- need_fpstatus = true;
break;
case 0x1e: /* FRINT32Z */
case 0x1f: /* FRINT64Z */
}
break;
case 0x8: /* CMGT, CMGE */
- gen_gvec_op2(s, is_q, rd, rn, u ? &cge0_op[size] : &cgt0_op[size]);
+ if (u) {
+ gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cge0, size);
+ } else {
+ gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cgt0, size);
+ }
return;
case 0x9: /* CMEQ, CMLE */
- gen_gvec_op2(s, is_q, rd, rn, u ? &cle0_op[size] : &ceq0_op[size]);
+ if (u) {
+ gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cle0, size);
+ } else {
+ gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_ceq0, size);
+ }
return;
case 0xa: /* CMLT */
- gen_gvec_op2(s, is_q, rd, rn, &clt0_op[size]);
+ gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_clt0, size);
return;
case 0xb:
if (u) { /* ABS, NEG */
gen_helper_rints_exact(tcg_res, tcg_op, tcg_fpstatus);
break;
case 0x7c: /* URSQRTE */
- gen_helper_rsqrte_u32(tcg_res, tcg_op, tcg_fpstatus);
+ gen_helper_rsqrte_u32(tcg_res, tcg_op);
break;
case 0x1e: /* FRINT32Z */
case 0x5e: /* FRINT32X */
DO_3SAME(VORR, tcg_gen_gvec_or)
DO_3SAME(VORN, tcg_gen_gvec_orc)
DO_3SAME(VEOR, tcg_gen_gvec_xor)
+DO_3SAME(VSHL_S, gen_gvec_sshl)
+DO_3SAME(VSHL_U, gen_gvec_ushl)
+DO_3SAME(VQADD_S, gen_gvec_sqadd_qc)
+DO_3SAME(VQADD_U, gen_gvec_uqadd_qc)
+DO_3SAME(VQSUB_S, gen_gvec_sqsub_qc)
+DO_3SAME(VQSUB_U, gen_gvec_uqsub_qc)
/* These insns are all gvec_bitsel but with the inputs in various orders. */
#define DO_3SAME_BITSEL(INSN, O1, O2, O3) \
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
DO_3SAME_NO_SZ_3(VMUL, tcg_gen_gvec_mul)
+DO_3SAME_NO_SZ_3(VMLA, gen_gvec_mla)
+DO_3SAME_NO_SZ_3(VMLS, gen_gvec_mls)
+DO_3SAME_NO_SZ_3(VTST, gen_gvec_cmtst)
+DO_3SAME_NO_SZ_3(VABD_S, gen_gvec_sabd)
+DO_3SAME_NO_SZ_3(VABA_S, gen_gvec_saba)
+DO_3SAME_NO_SZ_3(VABD_U, gen_gvec_uabd)
+DO_3SAME_NO_SZ_3(VABA_U, gen_gvec_uaba)
#define DO_3SAME_CMP(INSN, COND) \
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
DO_3SAME_CMP(VCGE_U, TCG_COND_GEU)
DO_3SAME_CMP(VCEQ, TCG_COND_EQ)
-static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
- uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
+static void gen_VMUL_p_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
+{
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz,
+ 0, gen_helper_gvec_pmul_b);
+}
+
+static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
+{
+ if (a->size != 0) {
+ return false;
+ }
+ return do_3same(s, a, gen_VMUL_p_3s);
+}
+
+#define DO_VQRDMLAH(INSN, FUNC) \
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
+ { \
+ if (!dc_isar_feature(aa32_rdm, s)) { \
+ return false; \
+ } \
+ if (a->size != 1 && a->size != 2) { \
+ return false; \
+ } \
+ return do_3same(s, a, FUNC); \
+ }
+
+DO_VQRDMLAH(VQRDMLAH, gen_gvec_sqrdmlah_qc)
+DO_VQRDMLAH(VQRDMLSH, gen_gvec_sqrdmlsh_qc)
+
+static bool trans_SHA1_3s(DisasContext *s, arg_SHA1_3s *a)
+{
+ TCGv_ptr ptr1, ptr2, ptr3;
+ TCGv_i32 tmp;
+
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
+ !dc_isar_feature(aa32_sha1, s)) {
+ return false;
+ }
+
+ /* UNDEF accesses to D16-D31 if they don't exist. */
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
+ ((a->vd | a->vn | a->vm) & 0x10)) {
+ return false;
+ }
+
+ if ((a->vn | a->vm | a->vd) & 1) {
+ return false;
+ }
+
+ if (!vfp_access_check(s)) {
+ return true;
+ }
+
+ ptr1 = vfp_reg_ptr(true, a->vd);
+ ptr2 = vfp_reg_ptr(true, a->vn);
+ ptr3 = vfp_reg_ptr(true, a->vm);
+ tmp = tcg_const_i32(a->optype);
+ gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp);
+ tcg_temp_free_i32(tmp);
+ tcg_temp_free_ptr(ptr1);
+ tcg_temp_free_ptr(ptr2);
+ tcg_temp_free_ptr(ptr3);
+
+ return true;
+}
+
+static bool trans_SHA256H_3s(DisasContext *s, arg_SHA256H_3s *a)
+{
+ TCGv_ptr ptr1, ptr2, ptr3;
+
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
+ !dc_isar_feature(aa32_sha2, s)) {
+ return false;
+ }
+
+ /* UNDEF accesses to D16-D31 if they don't exist. */
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
+ ((a->vd | a->vn | a->vm) & 0x10)) {
+ return false;
+ }
+
+ if ((a->vn | a->vm | a->vd) & 1) {
+ return false;
+ }
+
+ if (!vfp_access_check(s)) {
+ return true;
+ }
+
+ ptr1 = vfp_reg_ptr(true, a->vd);
+ ptr2 = vfp_reg_ptr(true, a->vn);
+ ptr3 = vfp_reg_ptr(true, a->vm);
+ gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
+ tcg_temp_free_ptr(ptr1);
+ tcg_temp_free_ptr(ptr2);
+ tcg_temp_free_ptr(ptr3);
+
+ return true;
+}
+
+static bool trans_SHA256H2_3s(DisasContext *s, arg_SHA256H2_3s *a)
+{
+ TCGv_ptr ptr1, ptr2, ptr3;
+
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
+ !dc_isar_feature(aa32_sha2, s)) {
+ return false;
+ }
+
+ /* UNDEF accesses to D16-D31 if they don't exist. */
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
+ ((a->vd | a->vn | a->vm) & 0x10)) {
+ return false;
+ }
+
+ if ((a->vn | a->vm | a->vd) & 1) {
+ return false;
+ }
+
+ if (!vfp_access_check(s)) {
+ return true;
+ }
+
+ ptr1 = vfp_reg_ptr(true, a->vd);
+ ptr2 = vfp_reg_ptr(true, a->vn);
+ ptr3 = vfp_reg_ptr(true, a->vm);
+ gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
+ tcg_temp_free_ptr(ptr1);
+ tcg_temp_free_ptr(ptr2);
+ tcg_temp_free_ptr(ptr3);
+
+ return true;
+}
+
+static bool trans_SHA256SU1_3s(DisasContext *s, arg_SHA256SU1_3s *a)
{
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
+ TCGv_ptr ptr1, ptr2, ptr3;
+
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
+ !dc_isar_feature(aa32_sha2, s)) {
+ return false;
+ }
+
+ /* UNDEF accesses to D16-D31 if they don't exist. */
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
+ ((a->vd | a->vn | a->vm) & 0x10)) {
+ return false;
+ }
+
+ if ((a->vn | a->vm | a->vd) & 1) {
+ return false;
+ }
+
+ if (!vfp_access_check(s)) {
+ return true;
+ }
+
+ ptr1 = vfp_reg_ptr(true, a->vd);
+ ptr2 = vfp_reg_ptr(true, a->vn);
+ ptr3 = vfp_reg_ptr(true, a->vm);
+ gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
+ tcg_temp_free_ptr(ptr1);
+ tcg_temp_free_ptr(ptr2);
+ tcg_temp_free_ptr(ptr3);
+
+ return true;
}
-DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
-#define DO_3SAME_GVEC4(INSN, OPARRAY) \
+#define DO_3SAME_64(INSN, FUNC) \
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
uint32_t rn_ofs, uint32_t rm_ofs, \
uint32_t oprsz, uint32_t maxsz) \
{ \
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc), \
- rn_ofs, rm_ofs, oprsz, maxsz, &OPARRAY[vece]); \
+ static const GVecGen3 op = { .fni8 = FUNC }; \
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &op); \
} \
DO_3SAME(INSN, gen_##INSN##_3s)
-DO_3SAME_GVEC4(VQADD_S, sqadd_op)
-DO_3SAME_GVEC4(VQADD_U, uqadd_op)
-DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
-DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
+#define DO_3SAME_64_ENV(INSN, FUNC) \
+ static void gen_##INSN##_elt(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m) \
+ { \
+ FUNC(d, cpu_env, n, m); \
+ } \
+ DO_3SAME_64(INSN, gen_##INSN##_elt)
-static void gen_VMUL_p_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
- uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
-{
- tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz,
- 0, gen_helper_gvec_pmul_b);
-}
+DO_3SAME_64(VRSHL_S64, gen_helper_neon_rshl_s64)
+DO_3SAME_64(VRSHL_U64, gen_helper_neon_rshl_u64)
+DO_3SAME_64_ENV(VQSHL_S64, gen_helper_neon_qshl_s64)
+DO_3SAME_64_ENV(VQSHL_U64, gen_helper_neon_qshl_u64)
+DO_3SAME_64_ENV(VQRSHL_S64, gen_helper_neon_qrshl_s64)
+DO_3SAME_64_ENV(VQRSHL_U64, gen_helper_neon_qrshl_u64)
-static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
+#define DO_3SAME_32(INSN, FUNC) \
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
+ uint32_t rn_ofs, uint32_t rm_ofs, \
+ uint32_t oprsz, uint32_t maxsz) \
+ { \
+ static const GVecGen3 ops[4] = { \
+ { .fni4 = gen_helper_neon_##FUNC##8 }, \
+ { .fni4 = gen_helper_neon_##FUNC##16 }, \
+ { .fni4 = gen_helper_neon_##FUNC##32 }, \
+ { 0 }, \
+ }; \
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &ops[vece]); \
+ } \
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
+ { \
+ if (a->size > 2) { \
+ return false; \
+ } \
+ return do_3same(s, a, gen_##INSN##_3s); \
+ }
+
+/*
+ * Some helper functions need to be passed the cpu_env. In order
+ * to use those with the gvec APIs like tcg_gen_gvec_3() we need
+ * to create wrapper functions whose prototype is a NeonGenTwoOpFn()
+ * and which call a NeonGenTwoOpEnvFn().
+ */
+#define WRAP_ENV_FN(WRAPNAME, FUNC) \
+ static void WRAPNAME(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m) \
+ { \
+ FUNC(d, cpu_env, n, m); \
+ }
+
+#define DO_3SAME_32_ENV(INSN, FUNC) \
+ WRAP_ENV_FN(gen_##INSN##_tramp8, gen_helper_neon_##FUNC##8); \
+ WRAP_ENV_FN(gen_##INSN##_tramp16, gen_helper_neon_##FUNC##16); \
+ WRAP_ENV_FN(gen_##INSN##_tramp32, gen_helper_neon_##FUNC##32); \
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
+ uint32_t rn_ofs, uint32_t rm_ofs, \
+ uint32_t oprsz, uint32_t maxsz) \
+ { \
+ static const GVecGen3 ops[4] = { \
+ { .fni4 = gen_##INSN##_tramp8 }, \
+ { .fni4 = gen_##INSN##_tramp16 }, \
+ { .fni4 = gen_##INSN##_tramp32 }, \
+ { 0 }, \
+ }; \
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &ops[vece]); \
+ } \
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
+ { \
+ if (a->size > 2) { \
+ return false; \
+ } \
+ return do_3same(s, a, gen_##INSN##_3s); \
+ }
+
+DO_3SAME_32(VHADD_S, hadd_s)
+DO_3SAME_32(VHADD_U, hadd_u)
+DO_3SAME_32(VHSUB_S, hsub_s)
+DO_3SAME_32(VHSUB_U, hsub_u)
+DO_3SAME_32(VRHADD_S, rhadd_s)
+DO_3SAME_32(VRHADD_U, rhadd_u)
+DO_3SAME_32(VRSHL_S, rshl_s)
+DO_3SAME_32(VRSHL_U, rshl_u)
+
+DO_3SAME_32_ENV(VQSHL_S, qshl_s)
+DO_3SAME_32_ENV(VQSHL_U, qshl_u)
+DO_3SAME_32_ENV(VQRSHL_S, qrshl_s)
+DO_3SAME_32_ENV(VQRSHL_U, qrshl_u)
+
+static bool do_3same_pair(DisasContext *s, arg_3same *a, NeonGenTwoOpFn *fn)
{
- if (a->size != 0) {
+ /* Operations handled pairwise 32 bits at a time */
+ TCGv_i32 tmp, tmp2, tmp3;
+
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
return false;
}
- return do_3same(s, a, gen_VMUL_p_3s);
+
+ /* UNDEF accesses to D16-D31 if they don't exist. */
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
+ ((a->vd | a->vn | a->vm) & 0x10)) {
+ return false;
+ }
+
+ if (a->size == 3) {
+ return false;
+ }
+
+ if (!vfp_access_check(s)) {
+ return true;
+ }
+
+ assert(a->q == 0); /* enforced by decode patterns */
+
+ /*
+ * Note that we have to be careful not to clobber the source operands
+ * in the "vm == vd" case by storing the result of the first pass too
+ * early. Since Q is 0 there are always just two passes, so instead
+ * of a complicated loop over each pass we just unroll.
+ */
+ tmp = neon_load_reg(a->vn, 0);
+ tmp2 = neon_load_reg(a->vn, 1);
+ fn(tmp, tmp, tmp2);
+ tcg_temp_free_i32(tmp2);
+
+ tmp3 = neon_load_reg(a->vm, 0);
+ tmp2 = neon_load_reg(a->vm, 1);
+ fn(tmp3, tmp3, tmp2);
+ tcg_temp_free_i32(tmp2);
+
+ neon_store_reg(a->vd, 0, tmp);
+ neon_store_reg(a->vd, 1, tmp3);
+ return true;
}
-#define DO_3SAME_GVEC3_NO_SZ_3(INSN, OPARRAY) \
+#define DO_3SAME_PAIR(INSN, func) \
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
+ { \
+ static NeonGenTwoOpFn * const fns[] = { \
+ gen_helper_neon_##func##8, \
+ gen_helper_neon_##func##16, \
+ gen_helper_neon_##func##32, \
+ }; \
+ if (a->size > 2) { \
+ return false; \
+ } \
+ return do_3same_pair(s, a, fns[a->size]); \
+ }
+
+/* 32-bit pairwise ops end up the same as the elementwise versions. */
+#define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
+#define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
+#define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
+#define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
+#define gen_helper_neon_padd_u32 tcg_gen_add_i32
+
+DO_3SAME_PAIR(VPMAX_S, pmax_s)
+DO_3SAME_PAIR(VPMIN_S, pmin_s)
+DO_3SAME_PAIR(VPMAX_U, pmax_u)
+DO_3SAME_PAIR(VPMIN_U, pmin_u)
+DO_3SAME_PAIR(VPADD, padd_u)
+
+#define DO_3SAME_VQDMULH(INSN, FUNC) \
+ WRAP_ENV_FN(gen_##INSN##_tramp16, gen_helper_neon_##FUNC##_s16); \
+ WRAP_ENV_FN(gen_##INSN##_tramp32, gen_helper_neon_##FUNC##_s32); \
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
uint32_t rn_ofs, uint32_t rm_ofs, \
uint32_t oprsz, uint32_t maxsz) \
{ \
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, \
- oprsz, maxsz, &OPARRAY[vece]); \
+ static const GVecGen3 ops[2] = { \
+ { .fni4 = gen_##INSN##_tramp16 }, \
+ { .fni4 = gen_##INSN##_tramp32 }, \
+ }; \
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &ops[vece - 1]); \
} \
- DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
+ { \
+ if (a->size != 1 && a->size != 2) { \
+ return false; \
+ } \
+ return do_3same(s, a, gen_##INSN##_3s); \
+ }
+DO_3SAME_VQDMULH(VQDMULH, qdmulh)
+DO_3SAME_VQDMULH(VQRDMULH, qrdmulh)
-DO_3SAME_GVEC3_NO_SZ_3(VMLA, mla_op)
-DO_3SAME_GVEC3_NO_SZ_3(VMLS, mls_op)
+static bool do_3same_fp(DisasContext *s, arg_3same *a, VFPGen3OpSPFn *fn,
+ bool reads_vd)
+{
+ /*
+ * FP operations handled elementwise 32 bits at a time.
+ * If reads_vd is true then the old value of Vd will be
+ * loaded before calling the callback function. This is
+ * used for multiply-accumulate type operations.
+ */
+ TCGv_i32 tmp, tmp2;
+ int pass;
+
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
+ return false;
+ }
+
+ /* UNDEF accesses to D16-D31 if they don't exist. */
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
+ ((a->vd | a->vn | a->vm) & 0x10)) {
+ return false;
+ }
+
+ if ((a->vn | a->vm | a->vd) & a->q) {
+ return false;
+ }
-#define DO_3SAME_GVEC3_SHIFT(INSN, OPARRAY) \
+ if (!vfp_access_check(s)) {
+ return true;
+ }
+
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
+ tmp = neon_load_reg(a->vn, pass);
+ tmp2 = neon_load_reg(a->vm, pass);
+ if (reads_vd) {
+ TCGv_i32 tmp_rd = neon_load_reg(a->vd, pass);
+ fn(tmp_rd, tmp, tmp2, fpstatus);
+ neon_store_reg(a->vd, pass, tmp_rd);
+ tcg_temp_free_i32(tmp);
+ } else {
+ fn(tmp, tmp, tmp2, fpstatus);
+ neon_store_reg(a->vd, pass, tmp);
+ }
+ tcg_temp_free_i32(tmp2);
+ }
+ tcg_temp_free_ptr(fpstatus);
+ return true;
+}
+
+/*
+ * For all the functions using this macro, size == 1 means fp16,
+ * which is an architecture extension we don't implement yet.
+ */
+#define DO_3S_FP_GVEC(INSN,FUNC) \
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
uint32_t rn_ofs, uint32_t rm_ofs, \
uint32_t oprsz, uint32_t maxsz) \
{ \
- /* Note the operation is vshl vd,vm,vn */ \
- tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, \
- oprsz, maxsz, &OPARRAY[vece]); \
+ TCGv_ptr fpst = get_fpstatus_ptr(1); \
+ tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, fpst, \
+ oprsz, maxsz, 0, FUNC); \
+ tcg_temp_free_ptr(fpst); \
} \
- DO_3SAME(INSN, gen_##INSN##_3s)
+ static bool trans_##INSN##_fp_3s(DisasContext *s, arg_3same *a) \
+ { \
+ if (a->size != 0) { \
+ /* TODO fp16 support */ \
+ return false; \
+ } \
+ return do_3same(s, a, gen_##INSN##_3s); \
+ }
+
+
+DO_3S_FP_GVEC(VADD, gen_helper_gvec_fadd_s)
+DO_3S_FP_GVEC(VSUB, gen_helper_gvec_fsub_s)
+DO_3S_FP_GVEC(VABD, gen_helper_gvec_fabd_s)
+DO_3S_FP_GVEC(VMUL, gen_helper_gvec_fmul_s)
+
+/*
+ * For all the functions using this macro, size == 1 means fp16,
+ * which is an architecture extension we don't implement yet.
+ */
+#define DO_3S_FP(INSN,FUNC,READS_VD) \
+ static bool trans_##INSN##_fp_3s(DisasContext *s, arg_3same *a) \
+ { \
+ if (a->size != 0) { \
+ /* TODO fp16 support */ \
+ return false; \
+ } \
+ return do_3same_fp(s, a, FUNC, READS_VD); \
+ }
+
+DO_3S_FP(VCEQ, gen_helper_neon_ceq_f32, false)
+DO_3S_FP(VCGE, gen_helper_neon_cge_f32, false)
+DO_3S_FP(VCGT, gen_helper_neon_cgt_f32, false)
+DO_3S_FP(VACGE, gen_helper_neon_acge_f32, false)
+DO_3S_FP(VACGT, gen_helper_neon_acgt_f32, false)
+DO_3S_FP(VMAX, gen_helper_vfp_maxs, false)
+DO_3S_FP(VMIN, gen_helper_vfp_mins, false)
+
+static void gen_VMLA_fp_3s(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm,
+ TCGv_ptr fpstatus)
+{
+ gen_helper_vfp_muls(vn, vn, vm, fpstatus);
+ gen_helper_vfp_adds(vd, vd, vn, fpstatus);
+}
+
+static void gen_VMLS_fp_3s(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm,
+ TCGv_ptr fpstatus)
+{
+ gen_helper_vfp_muls(vn, vn, vm, fpstatus);
+ gen_helper_vfp_subs(vd, vd, vn, fpstatus);
+}
+
+DO_3S_FP(VMLA, gen_VMLA_fp_3s, true)
+DO_3S_FP(VMLS, gen_VMLS_fp_3s, true)
+
+static bool trans_VMAXNM_fp_3s(DisasContext *s, arg_3same *a)
+{
+ if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
+ return false;
+ }
+
+ if (a->size != 0) {
+ /* TODO fp16 support */
+ return false;
+ }
+
+ return do_3same_fp(s, a, gen_helper_vfp_maxnums, false);
+}
+
+static bool trans_VMINNM_fp_3s(DisasContext *s, arg_3same *a)
+{
+ if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
+ return false;
+ }
+
+ if (a->size != 0) {
+ /* TODO fp16 support */
+ return false;
+ }
+
+ return do_3same_fp(s, a, gen_helper_vfp_minnums, false);
+}
+
+WRAP_ENV_FN(gen_VRECPS_tramp, gen_helper_recps_f32)
+
+static void gen_VRECPS_fp_3s(unsigned vece, uint32_t rd_ofs,
+ uint32_t rn_ofs, uint32_t rm_ofs,
+ uint32_t oprsz, uint32_t maxsz)
+{
+ static const GVecGen3 ops = { .fni4 = gen_VRECPS_tramp };
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &ops);
+}
+
+static bool trans_VRECPS_fp_3s(DisasContext *s, arg_3same *a)
+{
+ if (a->size != 0) {
+ /* TODO fp16 support */
+ return false;
+ }
+
+ return do_3same(s, a, gen_VRECPS_fp_3s);
+}
+
+WRAP_ENV_FN(gen_VRSQRTS_tramp, gen_helper_rsqrts_f32)
+
+static void gen_VRSQRTS_fp_3s(unsigned vece, uint32_t rd_ofs,
+ uint32_t rn_ofs, uint32_t rm_ofs,
+ uint32_t oprsz, uint32_t maxsz)
+{
+ static const GVecGen3 ops = { .fni4 = gen_VRSQRTS_tramp };
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &ops);
+}
+
+static bool trans_VRSQRTS_fp_3s(DisasContext *s, arg_3same *a)
+{
+ if (a->size != 0) {
+ /* TODO fp16 support */
+ return false;
+ }
+
+ return do_3same(s, a, gen_VRSQRTS_fp_3s);
+}
+
+static void gen_VFMA_fp_3s(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm,
+ TCGv_ptr fpstatus)
+{
+ gen_helper_vfp_muladds(vd, vn, vm, vd, fpstatus);
+}
+
+static bool trans_VFMA_fp_3s(DisasContext *s, arg_3same *a)
+{
+ if (!dc_isar_feature(aa32_simdfmac, s)) {
+ return false;
+ }
+
+ if (a->size != 0) {
+ /* TODO fp16 support */
+ return false;
+ }
+
+ return do_3same_fp(s, a, gen_VFMA_fp_3s, true);
+}
+
+static void gen_VFMS_fp_3s(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm,
+ TCGv_ptr fpstatus)
+{
+ gen_helper_vfp_negs(vn, vn);
+ gen_helper_vfp_muladds(vd, vn, vm, vd, fpstatus);
+}
+
+static bool trans_VFMS_fp_3s(DisasContext *s, arg_3same *a)
+{
+ if (!dc_isar_feature(aa32_simdfmac, s)) {
+ return false;
+ }
+
+ if (a->size != 0) {
+ /* TODO fp16 support */
+ return false;
+ }
+
+ return do_3same_fp(s, a, gen_VFMS_fp_3s, true);
+}
+
+static bool do_3same_fp_pair(DisasContext *s, arg_3same *a, VFPGen3OpSPFn *fn)
+{
+ /* FP operations handled pairwise 32 bits at a time */
+ TCGv_i32 tmp, tmp2, tmp3;
+ TCGv_ptr fpstatus;
+
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
+ return false;
+ }
+
+ /* UNDEF accesses to D16-D31 if they don't exist. */
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
+ ((a->vd | a->vn | a->vm) & 0x10)) {
+ return false;
+ }
+
+ if (!vfp_access_check(s)) {
+ return true;
+ }
+
+ assert(a->q == 0); /* enforced by decode patterns */
+
+ /*
+ * Note that we have to be careful not to clobber the source operands
+ * in the "vm == vd" case by storing the result of the first pass too
+ * early. Since Q is 0 there are always just two passes, so instead
+ * of a complicated loop over each pass we just unroll.
+ */
+ fpstatus = get_fpstatus_ptr(1);
+ tmp = neon_load_reg(a->vn, 0);
+ tmp2 = neon_load_reg(a->vn, 1);
+ fn(tmp, tmp, tmp2, fpstatus);
+ tcg_temp_free_i32(tmp2);
+
+ tmp3 = neon_load_reg(a->vm, 0);
+ tmp2 = neon_load_reg(a->vm, 1);
+ fn(tmp3, tmp3, tmp2, fpstatus);
+ tcg_temp_free_i32(tmp2);
+ tcg_temp_free_ptr(fpstatus);
+
+ neon_store_reg(a->vd, 0, tmp);
+ neon_store_reg(a->vd, 1, tmp3);
+ return true;
+}
+
+/*
+ * For all the functions using this macro, size == 1 means fp16,
+ * which is an architecture extension we don't implement yet.
+ */
+#define DO_3S_FP_PAIR(INSN,FUNC) \
+ static bool trans_##INSN##_fp_3s(DisasContext *s, arg_3same *a) \
+ { \
+ if (a->size != 0) { \
+ /* TODO fp16 support */ \
+ return false; \
+ } \
+ return do_3same_fp_pair(s, a, FUNC); \
+ }
-DO_3SAME_GVEC3_SHIFT(VSHL_S, sshl_op)
-DO_3SAME_GVEC3_SHIFT(VSHL_U, ushl_op)
+DO_3S_FP_PAIR(VPADD, gen_helper_vfp_adds)
+DO_3S_FP_PAIR(VPMAX, gen_helper_vfp_maxs)
+DO_3S_FP_PAIR(VPMIN, gen_helper_vfp_mins)
}
}
-/* 32-bit pairwise ops end up the same as the elementwise versions. */
-#define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
-#define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
-#define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
-#define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
-
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
switch ((size << 1) | u) { \
case 0: \
}
}
-/* Symbolic constants for op fields for Neon 3-register same-length.
- * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
- * table A7-9.
- */
-#define NEON_3R_VHADD 0
-#define NEON_3R_VQADD 1
-#define NEON_3R_VRHADD 2
-#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
-#define NEON_3R_VHSUB 4
-#define NEON_3R_VQSUB 5
-#define NEON_3R_VCGT 6
-#define NEON_3R_VCGE 7
-#define NEON_3R_VSHL 8
-#define NEON_3R_VQSHL 9
-#define NEON_3R_VRSHL 10
-#define NEON_3R_VQRSHL 11
-#define NEON_3R_VMAX 12
-#define NEON_3R_VMIN 13
-#define NEON_3R_VABD 14
-#define NEON_3R_VABA 15
-#define NEON_3R_VADD_VSUB 16
-#define NEON_3R_VTST_VCEQ 17
-#define NEON_3R_VML 18 /* VMLA, VMLS */
-#define NEON_3R_VMUL 19
-#define NEON_3R_VPMAX 20
-#define NEON_3R_VPMIN 21
-#define NEON_3R_VQDMULH_VQRDMULH 22
-#define NEON_3R_VPADD_VQRDMLAH 23
-#define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
-#define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
-#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
-#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
-#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
-#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
-#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
-#define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
-
-static const uint8_t neon_3r_sizes[] = {
- [NEON_3R_VHADD] = 0x7,
- [NEON_3R_VQADD] = 0xf,
- [NEON_3R_VRHADD] = 0x7,
- [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
- [NEON_3R_VHSUB] = 0x7,
- [NEON_3R_VQSUB] = 0xf,
- [NEON_3R_VCGT] = 0x7,
- [NEON_3R_VCGE] = 0x7,
- [NEON_3R_VSHL] = 0xf,
- [NEON_3R_VQSHL] = 0xf,
- [NEON_3R_VRSHL] = 0xf,
- [NEON_3R_VQRSHL] = 0xf,
- [NEON_3R_VMAX] = 0x7,
- [NEON_3R_VMIN] = 0x7,
- [NEON_3R_VABD] = 0x7,
- [NEON_3R_VABA] = 0x7,
- [NEON_3R_VADD_VSUB] = 0xf,
- [NEON_3R_VTST_VCEQ] = 0x7,
- [NEON_3R_VML] = 0x7,
- [NEON_3R_VMUL] = 0x7,
- [NEON_3R_VPMAX] = 0x7,
- [NEON_3R_VPMIN] = 0x7,
- [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
- [NEON_3R_VPADD_VQRDMLAH] = 0x7,
- [NEON_3R_SHA] = 0xf, /* size field encodes op type */
- [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
- [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
- [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
- [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
- [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
- [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
- [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
-};
-
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
* table A7-13.
[NEON_2RM_VCVT_UF] = 0x4,
};
-
-/* Expand v8.1 simd helper. */
-static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
- int q, int rd, int rn, int rm)
+static void gen_gvec_fn3_qc(uint32_t rd_ofs, uint32_t rn_ofs, uint32_t rm_ofs,
+ uint32_t opr_sz, uint32_t max_sz,
+ gen_helper_gvec_3_ptr *fn)
{
- if (dc_isar_feature(aa32_rdm, s)) {
- int opr_sz = (1 + q) * 8;
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
- vfp_reg_offset(1, rn),
- vfp_reg_offset(1, rm), cpu_env,
- opr_sz, opr_sz, 0, fn);
- return 0;
- }
- return 1;
-}
+ TCGv_ptr qc_ptr = tcg_temp_new_ptr();
-static void gen_ceq0_i32(TCGv_i32 d, TCGv_i32 a)
-{
- tcg_gen_setcondi_i32(TCG_COND_EQ, d, a, 0);
- tcg_gen_neg_i32(d, d);
+ tcg_gen_addi_ptr(qc_ptr, cpu_env, offsetof(CPUARMState, vfp.qc));
+ tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, qc_ptr,
+ opr_sz, max_sz, 0, fn);
+ tcg_temp_free_ptr(qc_ptr);
}
-static void gen_ceq0_i64(TCGv_i64 d, TCGv_i64 a)
+void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
{
- tcg_gen_setcondi_i64(TCG_COND_EQ, d, a, 0);
- tcg_gen_neg_i64(d, d);
+ static gen_helper_gvec_3_ptr * const fns[2] = {
+ gen_helper_gvec_qrdmlah_s16, gen_helper_gvec_qrdmlah_s32
+ };
+ tcg_debug_assert(vece >= 1 && vece <= 2);
+ gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
}
-static void gen_ceq0_vec(unsigned vece, TCGv_vec d, TCGv_vec a)
+void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
{
- TCGv_vec zero = tcg_const_zeros_vec_matching(d);
- tcg_gen_cmp_vec(TCG_COND_EQ, vece, d, a, zero);
- tcg_temp_free_vec(zero);
-}
+ static gen_helper_gvec_3_ptr * const fns[2] = {
+ gen_helper_gvec_qrdmlsh_s16, gen_helper_gvec_qrdmlsh_s32
+ };
+ tcg_debug_assert(vece >= 1 && vece <= 2);
+ gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
+}
+
+#define GEN_CMP0(NAME, COND) \
+ static void gen_##NAME##0_i32(TCGv_i32 d, TCGv_i32 a) \
+ { \
+ tcg_gen_setcondi_i32(COND, d, a, 0); \
+ tcg_gen_neg_i32(d, d); \
+ } \
+ static void gen_##NAME##0_i64(TCGv_i64 d, TCGv_i64 a) \
+ { \
+ tcg_gen_setcondi_i64(COND, d, a, 0); \
+ tcg_gen_neg_i64(d, d); \
+ } \
+ static void gen_##NAME##0_vec(unsigned vece, TCGv_vec d, TCGv_vec a) \
+ { \
+ TCGv_vec zero = tcg_const_zeros_vec_matching(d); \
+ tcg_gen_cmp_vec(COND, vece, d, a, zero); \
+ tcg_temp_free_vec(zero); \
+ } \
+ void gen_gvec_##NAME##0(unsigned vece, uint32_t d, uint32_t m, \
+ uint32_t opr_sz, uint32_t max_sz) \
+ { \
+ const GVecGen2 op[4] = { \
+ { .fno = gen_helper_gvec_##NAME##0_b, \
+ .fniv = gen_##NAME##0_vec, \
+ .opt_opc = vecop_list_cmp, \
+ .vece = MO_8 }, \
+ { .fno = gen_helper_gvec_##NAME##0_h, \
+ .fniv = gen_##NAME##0_vec, \
+ .opt_opc = vecop_list_cmp, \
+ .vece = MO_16 }, \
+ { .fni4 = gen_##NAME##0_i32, \
+ .fniv = gen_##NAME##0_vec, \
+ .opt_opc = vecop_list_cmp, \
+ .vece = MO_32 }, \
+ { .fni8 = gen_##NAME##0_i64, \
+ .fniv = gen_##NAME##0_vec, \
+ .opt_opc = vecop_list_cmp, \
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64, \
+ .vece = MO_64 }, \
+ }; \
+ tcg_gen_gvec_2(d, m, opr_sz, max_sz, &op[vece]); \
+ }
static const TCGOpcode vecop_list_cmp[] = {
INDEX_op_cmp_vec, 0
};
-const GVecGen2 ceq0_op[4] = {
- { .fno = gen_helper_gvec_ceq0_b,
- .fniv = gen_ceq0_vec,
- .opt_opc = vecop_list_cmp,
- .vece = MO_8 },
- { .fno = gen_helper_gvec_ceq0_h,
- .fniv = gen_ceq0_vec,
- .opt_opc = vecop_list_cmp,
- .vece = MO_16 },
- { .fni4 = gen_ceq0_i32,
- .fniv = gen_ceq0_vec,
- .opt_opc = vecop_list_cmp,
- .vece = MO_32 },
- { .fni8 = gen_ceq0_i64,
- .fniv = gen_ceq0_vec,
- .opt_opc = vecop_list_cmp,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .vece = MO_64 },
-};
-
-static void gen_cle0_i32(TCGv_i32 d, TCGv_i32 a)
-{
- tcg_gen_setcondi_i32(TCG_COND_LE, d, a, 0);
- tcg_gen_neg_i32(d, d);
-}
-
-static void gen_cle0_i64(TCGv_i64 d, TCGv_i64 a)
-{
- tcg_gen_setcondi_i64(TCG_COND_LE, d, a, 0);
- tcg_gen_neg_i64(d, d);
-}
-
-static void gen_cle0_vec(unsigned vece, TCGv_vec d, TCGv_vec a)
-{
- TCGv_vec zero = tcg_const_zeros_vec_matching(d);
- tcg_gen_cmp_vec(TCG_COND_LE, vece, d, a, zero);
- tcg_temp_free_vec(zero);
-}
-
-const GVecGen2 cle0_op[4] = {
- { .fno = gen_helper_gvec_cle0_b,
- .fniv = gen_cle0_vec,
- .opt_opc = vecop_list_cmp,
- .vece = MO_8 },
- { .fno = gen_helper_gvec_cle0_h,
- .fniv = gen_cle0_vec,
- .opt_opc = vecop_list_cmp,
- .vece = MO_16 },
- { .fni4 = gen_cle0_i32,
- .fniv = gen_cle0_vec,
- .opt_opc = vecop_list_cmp,
- .vece = MO_32 },
- { .fni8 = gen_cle0_i64,
- .fniv = gen_cle0_vec,
- .opt_opc = vecop_list_cmp,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .vece = MO_64 },
-};
-
-static void gen_cge0_i32(TCGv_i32 d, TCGv_i32 a)
-{
- tcg_gen_setcondi_i32(TCG_COND_GE, d, a, 0);
- tcg_gen_neg_i32(d, d);
-}
-
-static void gen_cge0_i64(TCGv_i64 d, TCGv_i64 a)
-{
- tcg_gen_setcondi_i64(TCG_COND_GE, d, a, 0);
- tcg_gen_neg_i64(d, d);
-}
+GEN_CMP0(ceq, TCG_COND_EQ)
+GEN_CMP0(cle, TCG_COND_LE)
+GEN_CMP0(cge, TCG_COND_GE)
+GEN_CMP0(clt, TCG_COND_LT)
+GEN_CMP0(cgt, TCG_COND_GT)
-static void gen_cge0_vec(unsigned vece, TCGv_vec d, TCGv_vec a)
-{
- TCGv_vec zero = tcg_const_zeros_vec_matching(d);
- tcg_gen_cmp_vec(TCG_COND_GE, vece, d, a, zero);
- tcg_temp_free_vec(zero);
-}
-
-const GVecGen2 cge0_op[4] = {
- { .fno = gen_helper_gvec_cge0_b,
- .fniv = gen_cge0_vec,
- .opt_opc = vecop_list_cmp,
- .vece = MO_8 },
- { .fno = gen_helper_gvec_cge0_h,
- .fniv = gen_cge0_vec,
- .opt_opc = vecop_list_cmp,
- .vece = MO_16 },
- { .fni4 = gen_cge0_i32,
- .fniv = gen_cge0_vec,
- .opt_opc = vecop_list_cmp,
- .vece = MO_32 },
- { .fni8 = gen_cge0_i64,
- .fniv = gen_cge0_vec,
- .opt_opc = vecop_list_cmp,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .vece = MO_64 },
-};
-
-static void gen_clt0_i32(TCGv_i32 d, TCGv_i32 a)
-{
- tcg_gen_setcondi_i32(TCG_COND_LT, d, a, 0);
- tcg_gen_neg_i32(d, d);
-}
-
-static void gen_clt0_i64(TCGv_i64 d, TCGv_i64 a)
-{
- tcg_gen_setcondi_i64(TCG_COND_LT, d, a, 0);
- tcg_gen_neg_i64(d, d);
-}
-
-static void gen_clt0_vec(unsigned vece, TCGv_vec d, TCGv_vec a)
-{
- TCGv_vec zero = tcg_const_zeros_vec_matching(d);
- tcg_gen_cmp_vec(TCG_COND_LT, vece, d, a, zero);
- tcg_temp_free_vec(zero);
-}
-
-const GVecGen2 clt0_op[4] = {
- { .fno = gen_helper_gvec_clt0_b,
- .fniv = gen_clt0_vec,
- .opt_opc = vecop_list_cmp,
- .vece = MO_8 },
- { .fno = gen_helper_gvec_clt0_h,
- .fniv = gen_clt0_vec,
- .opt_opc = vecop_list_cmp,
- .vece = MO_16 },
- { .fni4 = gen_clt0_i32,
- .fniv = gen_clt0_vec,
- .opt_opc = vecop_list_cmp,
- .vece = MO_32 },
- { .fni8 = gen_clt0_i64,
- .fniv = gen_clt0_vec,
- .opt_opc = vecop_list_cmp,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .vece = MO_64 },
-};
-
-static void gen_cgt0_i32(TCGv_i32 d, TCGv_i32 a)
-{
- tcg_gen_setcondi_i32(TCG_COND_GT, d, a, 0);
- tcg_gen_neg_i32(d, d);
-}
-
-static void gen_cgt0_i64(TCGv_i64 d, TCGv_i64 a)
-{
- tcg_gen_setcondi_i64(TCG_COND_GT, d, a, 0);
- tcg_gen_neg_i64(d, d);
-}
-
-static void gen_cgt0_vec(unsigned vece, TCGv_vec d, TCGv_vec a)
-{
- TCGv_vec zero = tcg_const_zeros_vec_matching(d);
- tcg_gen_cmp_vec(TCG_COND_GT, vece, d, a, zero);
- tcg_temp_free_vec(zero);
-}
-
-const GVecGen2 cgt0_op[4] = {
- { .fno = gen_helper_gvec_cgt0_b,
- .fniv = gen_cgt0_vec,
- .opt_opc = vecop_list_cmp,
- .vece = MO_8 },
- { .fno = gen_helper_gvec_cgt0_h,
- .fniv = gen_cgt0_vec,
- .opt_opc = vecop_list_cmp,
- .vece = MO_16 },
- { .fni4 = gen_cgt0_i32,
- .fniv = gen_cgt0_vec,
- .opt_opc = vecop_list_cmp,
- .vece = MO_32 },
- { .fni8 = gen_cgt0_i64,
- .fniv = gen_cgt0_vec,
- .opt_opc = vecop_list_cmp,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .vece = MO_64 },
-};
+#undef GEN_CMP0
static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
{
tcg_gen_add_vec(vece, d, d, a);
}
-static const TCGOpcode vecop_list_ssra[] = {
- INDEX_op_sari_vec, INDEX_op_add_vec, 0
-};
+void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_sari_vec, INDEX_op_add_vec, 0
+ };
+ static const GVecGen2i ops[4] = {
+ { .fni8 = gen_ssra8_i64,
+ .fniv = gen_ssra_vec,
+ .fno = gen_helper_gvec_ssra_b,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_8 },
+ { .fni8 = gen_ssra16_i64,
+ .fniv = gen_ssra_vec,
+ .fno = gen_helper_gvec_ssra_h,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_16 },
+ { .fni4 = gen_ssra32_i32,
+ .fniv = gen_ssra_vec,
+ .fno = gen_helper_gvec_ssra_s,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_32 },
+ { .fni8 = gen_ssra64_i64,
+ .fniv = gen_ssra_vec,
+ .fno = gen_helper_gvec_ssra_b,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .opt_opc = vecop_list,
+ .load_dest = true,
+ .vece = MO_64 },
+ };
-const GVecGen2i ssra_op[4] = {
- { .fni8 = gen_ssra8_i64,
- .fniv = gen_ssra_vec,
- .load_dest = true,
- .opt_opc = vecop_list_ssra,
- .vece = MO_8 },
- { .fni8 = gen_ssra16_i64,
- .fniv = gen_ssra_vec,
- .load_dest = true,
- .opt_opc = vecop_list_ssra,
- .vece = MO_16 },
- { .fni4 = gen_ssra32_i32,
- .fniv = gen_ssra_vec,
- .load_dest = true,
- .opt_opc = vecop_list_ssra,
- .vece = MO_32 },
- { .fni8 = gen_ssra64_i64,
- .fniv = gen_ssra_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .opt_opc = vecop_list_ssra,
- .load_dest = true,
- .vece = MO_64 },
-};
+ /* tszimm encoding produces immediates in the range [1..esize]. */
+ tcg_debug_assert(shift > 0);
+ tcg_debug_assert(shift <= (8 << vece));
+
+ /*
+ * Shifts larger than the element size are architecturally valid.
+ * Signed results in all sign bits.
+ */
+ shift = MIN(shift, (8 << vece) - 1);
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
+}
static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
{
tcg_gen_add_vec(vece, d, d, a);
}
-static const TCGOpcode vecop_list_usra[] = {
- INDEX_op_shri_vec, INDEX_op_add_vec, 0
-};
+void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_shri_vec, INDEX_op_add_vec, 0
+ };
+ static const GVecGen2i ops[4] = {
+ { .fni8 = gen_usra8_i64,
+ .fniv = gen_usra_vec,
+ .fno = gen_helper_gvec_usra_b,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_8, },
+ { .fni8 = gen_usra16_i64,
+ .fniv = gen_usra_vec,
+ .fno = gen_helper_gvec_usra_h,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_16, },
+ { .fni4 = gen_usra32_i32,
+ .fniv = gen_usra_vec,
+ .fno = gen_helper_gvec_usra_s,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_32, },
+ { .fni8 = gen_usra64_i64,
+ .fniv = gen_usra_vec,
+ .fno = gen_helper_gvec_usra_d,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_64, },
+ };
-const GVecGen2i usra_op[4] = {
- { .fni8 = gen_usra8_i64,
- .fniv = gen_usra_vec,
- .load_dest = true,
- .opt_opc = vecop_list_usra,
- .vece = MO_8, },
- { .fni8 = gen_usra16_i64,
- .fniv = gen_usra_vec,
- .load_dest = true,
- .opt_opc = vecop_list_usra,
- .vece = MO_16, },
- { .fni4 = gen_usra32_i32,
- .fniv = gen_usra_vec,
- .load_dest = true,
- .opt_opc = vecop_list_usra,
- .vece = MO_32, },
- { .fni8 = gen_usra64_i64,
- .fniv = gen_usra_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .load_dest = true,
- .opt_opc = vecop_list_usra,
- .vece = MO_64, },
-};
+ /* tszimm encoding produces immediates in the range [1..esize]. */
+ tcg_debug_assert(shift > 0);
+ tcg_debug_assert(shift <= (8 << vece));
+
+ /*
+ * Shifts larger than the element size are architecturally valid.
+ * Unsigned results in all zeros as input to accumulate: nop.
+ */
+ if (shift < (8 << vece)) {
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
+ } else {
+ /* Nop, but we do need to clear the tail. */
+ tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
+ }
+}
+
+/*
+ * Shift one less than the requested amount, and the low bit is
+ * the rounding bit. For the 8 and 16-bit operations, because we
+ * mask the low bit, we can perform a normal integer shift instead
+ * of a vector shift.
+ */
+static void gen_srshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
+{
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ tcg_gen_shri_i64(t, a, sh - 1);
+ tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
+ tcg_gen_vec_sar8i_i64(d, a, sh);
+ tcg_gen_vec_add8_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
+{
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ tcg_gen_shri_i64(t, a, sh - 1);
+ tcg_gen_andi_i64(t, t, dup_const(MO_16, 1));
+ tcg_gen_vec_sar16i_i64(d, a, sh);
+ tcg_gen_vec_add16_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
+{
+ TCGv_i32 t = tcg_temp_new_i32();
+
+ tcg_gen_extract_i32(t, a, sh - 1, 1);
+ tcg_gen_sari_i32(d, a, sh);
+ tcg_gen_add_i32(d, d, t);
+ tcg_temp_free_i32(t);
+}
+
+static void gen_srshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
+{
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ tcg_gen_extract_i64(t, a, sh - 1, 1);
+ tcg_gen_sari_i64(d, a, sh);
+ tcg_gen_add_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_srshr_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
+{
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
+ TCGv_vec ones = tcg_temp_new_vec_matching(d);
+
+ tcg_gen_shri_vec(vece, t, a, sh - 1);
+ tcg_gen_dupi_vec(vece, ones, 1);
+ tcg_gen_and_vec(vece, t, t, ones);
+ tcg_gen_sari_vec(vece, d, a, sh);
+ tcg_gen_add_vec(vece, d, d, t);
+
+ tcg_temp_free_vec(t);
+ tcg_temp_free_vec(ones);
+}
+
+void gen_gvec_srshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
+ };
+ static const GVecGen2i ops[4] = {
+ { .fni8 = gen_srshr8_i64,
+ .fniv = gen_srshr_vec,
+ .fno = gen_helper_gvec_srshr_b,
+ .opt_opc = vecop_list,
+ .vece = MO_8 },
+ { .fni8 = gen_srshr16_i64,
+ .fniv = gen_srshr_vec,
+ .fno = gen_helper_gvec_srshr_h,
+ .opt_opc = vecop_list,
+ .vece = MO_16 },
+ { .fni4 = gen_srshr32_i32,
+ .fniv = gen_srshr_vec,
+ .fno = gen_helper_gvec_srshr_s,
+ .opt_opc = vecop_list,
+ .vece = MO_32 },
+ { .fni8 = gen_srshr64_i64,
+ .fniv = gen_srshr_vec,
+ .fno = gen_helper_gvec_srshr_d,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .opt_opc = vecop_list,
+ .vece = MO_64 },
+ };
+
+ /* tszimm encoding produces immediates in the range [1..esize] */
+ tcg_debug_assert(shift > 0);
+ tcg_debug_assert(shift <= (8 << vece));
+
+ if (shift == (8 << vece)) {
+ /*
+ * Shifts larger than the element size are architecturally valid.
+ * Signed results in all sign bits. With rounding, this produces
+ * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
+ * I.e. always zero.
+ */
+ tcg_gen_gvec_dup_imm(vece, rd_ofs, opr_sz, max_sz, 0);
+ } else {
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
+ }
+}
+
+static void gen_srsra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
+{
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ gen_srshr8_i64(t, a, sh);
+ tcg_gen_vec_add8_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_srsra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
+{
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ gen_srshr16_i64(t, a, sh);
+ tcg_gen_vec_add16_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_srsra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
+{
+ TCGv_i32 t = tcg_temp_new_i32();
+
+ gen_srshr32_i32(t, a, sh);
+ tcg_gen_add_i32(d, d, t);
+ tcg_temp_free_i32(t);
+}
+
+static void gen_srsra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
+{
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ gen_srshr64_i64(t, a, sh);
+ tcg_gen_add_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_srsra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
+{
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
+
+ gen_srshr_vec(vece, t, a, sh);
+ tcg_gen_add_vec(vece, d, d, t);
+ tcg_temp_free_vec(t);
+}
+
+void gen_gvec_srsra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
+ };
+ static const GVecGen2i ops[4] = {
+ { .fni8 = gen_srsra8_i64,
+ .fniv = gen_srsra_vec,
+ .fno = gen_helper_gvec_srsra_b,
+ .opt_opc = vecop_list,
+ .load_dest = true,
+ .vece = MO_8 },
+ { .fni8 = gen_srsra16_i64,
+ .fniv = gen_srsra_vec,
+ .fno = gen_helper_gvec_srsra_h,
+ .opt_opc = vecop_list,
+ .load_dest = true,
+ .vece = MO_16 },
+ { .fni4 = gen_srsra32_i32,
+ .fniv = gen_srsra_vec,
+ .fno = gen_helper_gvec_srsra_s,
+ .opt_opc = vecop_list,
+ .load_dest = true,
+ .vece = MO_32 },
+ { .fni8 = gen_srsra64_i64,
+ .fniv = gen_srsra_vec,
+ .fno = gen_helper_gvec_srsra_d,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .opt_opc = vecop_list,
+ .load_dest = true,
+ .vece = MO_64 },
+ };
+
+ /* tszimm encoding produces immediates in the range [1..esize] */
+ tcg_debug_assert(shift > 0);
+ tcg_debug_assert(shift <= (8 << vece));
+
+ /*
+ * Shifts larger than the element size are architecturally valid.
+ * Signed results in all sign bits. With rounding, this produces
+ * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
+ * I.e. always zero. With accumulation, this leaves D unchanged.
+ */
+ if (shift == (8 << vece)) {
+ /* Nop, but we do need to clear the tail. */
+ tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
+ } else {
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
+ }
+}
+
+static void gen_urshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
+{
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ tcg_gen_shri_i64(t, a, sh - 1);
+ tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
+ tcg_gen_vec_shr8i_i64(d, a, sh);
+ tcg_gen_vec_add8_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
+{
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ tcg_gen_shri_i64(t, a, sh - 1);
+ tcg_gen_andi_i64(t, t, dup_const(MO_16, 1));
+ tcg_gen_vec_shr16i_i64(d, a, sh);
+ tcg_gen_vec_add16_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
+{
+ TCGv_i32 t = tcg_temp_new_i32();
+
+ tcg_gen_extract_i32(t, a, sh - 1, 1);
+ tcg_gen_shri_i32(d, a, sh);
+ tcg_gen_add_i32(d, d, t);
+ tcg_temp_free_i32(t);
+}
+
+static void gen_urshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
+{
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ tcg_gen_extract_i64(t, a, sh - 1, 1);
+ tcg_gen_shri_i64(d, a, sh);
+ tcg_gen_add_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_urshr_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t shift)
+{
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
+ TCGv_vec ones = tcg_temp_new_vec_matching(d);
+
+ tcg_gen_shri_vec(vece, t, a, shift - 1);
+ tcg_gen_dupi_vec(vece, ones, 1);
+ tcg_gen_and_vec(vece, t, t, ones);
+ tcg_gen_shri_vec(vece, d, a, shift);
+ tcg_gen_add_vec(vece, d, d, t);
+
+ tcg_temp_free_vec(t);
+ tcg_temp_free_vec(ones);
+}
+
+void gen_gvec_urshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_shri_vec, INDEX_op_add_vec, 0
+ };
+ static const GVecGen2i ops[4] = {
+ { .fni8 = gen_urshr8_i64,
+ .fniv = gen_urshr_vec,
+ .fno = gen_helper_gvec_urshr_b,
+ .opt_opc = vecop_list,
+ .vece = MO_8 },
+ { .fni8 = gen_urshr16_i64,
+ .fniv = gen_urshr_vec,
+ .fno = gen_helper_gvec_urshr_h,
+ .opt_opc = vecop_list,
+ .vece = MO_16 },
+ { .fni4 = gen_urshr32_i32,
+ .fniv = gen_urshr_vec,
+ .fno = gen_helper_gvec_urshr_s,
+ .opt_opc = vecop_list,
+ .vece = MO_32 },
+ { .fni8 = gen_urshr64_i64,
+ .fniv = gen_urshr_vec,
+ .fno = gen_helper_gvec_urshr_d,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .opt_opc = vecop_list,
+ .vece = MO_64 },
+ };
+
+ /* tszimm encoding produces immediates in the range [1..esize] */
+ tcg_debug_assert(shift > 0);
+ tcg_debug_assert(shift <= (8 << vece));
+
+ if (shift == (8 << vece)) {
+ /*
+ * Shifts larger than the element size are architecturally valid.
+ * Unsigned results in zero. With rounding, this produces a
+ * copy of the most significant bit.
+ */
+ tcg_gen_gvec_shri(vece, rd_ofs, rm_ofs, shift - 1, opr_sz, max_sz);
+ } else {
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
+ }
+}
+
+static void gen_ursra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
+{
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ if (sh == 8) {
+ tcg_gen_vec_shr8i_i64(t, a, 7);
+ } else {
+ gen_urshr8_i64(t, a, sh);
+ }
+ tcg_gen_vec_add8_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_ursra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
+{
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ if (sh == 16) {
+ tcg_gen_vec_shr16i_i64(t, a, 15);
+ } else {
+ gen_urshr16_i64(t, a, sh);
+ }
+ tcg_gen_vec_add16_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_ursra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
+{
+ TCGv_i32 t = tcg_temp_new_i32();
+
+ if (sh == 32) {
+ tcg_gen_shri_i32(t, a, 31);
+ } else {
+ gen_urshr32_i32(t, a, sh);
+ }
+ tcg_gen_add_i32(d, d, t);
+ tcg_temp_free_i32(t);
+}
+
+static void gen_ursra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
+{
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ if (sh == 64) {
+ tcg_gen_shri_i64(t, a, 63);
+ } else {
+ gen_urshr64_i64(t, a, sh);
+ }
+ tcg_gen_add_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_ursra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
+{
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
+
+ if (sh == (8 << vece)) {
+ tcg_gen_shri_vec(vece, t, a, sh - 1);
+ } else {
+ gen_urshr_vec(vece, t, a, sh);
+ }
+ tcg_gen_add_vec(vece, d, d, t);
+ tcg_temp_free_vec(t);
+}
+
+void gen_gvec_ursra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_shri_vec, INDEX_op_add_vec, 0
+ };
+ static const GVecGen2i ops[4] = {
+ { .fni8 = gen_ursra8_i64,
+ .fniv = gen_ursra_vec,
+ .fno = gen_helper_gvec_ursra_b,
+ .opt_opc = vecop_list,
+ .load_dest = true,
+ .vece = MO_8 },
+ { .fni8 = gen_ursra16_i64,
+ .fniv = gen_ursra_vec,
+ .fno = gen_helper_gvec_ursra_h,
+ .opt_opc = vecop_list,
+ .load_dest = true,
+ .vece = MO_16 },
+ { .fni4 = gen_ursra32_i32,
+ .fniv = gen_ursra_vec,
+ .fno = gen_helper_gvec_ursra_s,
+ .opt_opc = vecop_list,
+ .load_dest = true,
+ .vece = MO_32 },
+ { .fni8 = gen_ursra64_i64,
+ .fniv = gen_ursra_vec,
+ .fno = gen_helper_gvec_ursra_d,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .opt_opc = vecop_list,
+ .load_dest = true,
+ .vece = MO_64 },
+ };
+
+ /* tszimm encoding produces immediates in the range [1..esize] */
+ tcg_debug_assert(shift > 0);
+ tcg_debug_assert(shift <= (8 << vece));
+
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
+}
static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
{
static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
{
- if (sh == 0) {
- tcg_gen_mov_vec(d, a);
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
+ TCGv_vec m = tcg_temp_new_vec_matching(d);
+
+ tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
+ tcg_gen_shri_vec(vece, t, a, sh);
+ tcg_gen_and_vec(vece, d, d, m);
+ tcg_gen_or_vec(vece, d, d, t);
+
+ tcg_temp_free_vec(t);
+ tcg_temp_free_vec(m);
+}
+
+void gen_gvec_sri(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = { INDEX_op_shri_vec, 0 };
+ const GVecGen2i ops[4] = {
+ { .fni8 = gen_shr8_ins_i64,
+ .fniv = gen_shr_ins_vec,
+ .fno = gen_helper_gvec_sri_b,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_8 },
+ { .fni8 = gen_shr16_ins_i64,
+ .fniv = gen_shr_ins_vec,
+ .fno = gen_helper_gvec_sri_h,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_16 },
+ { .fni4 = gen_shr32_ins_i32,
+ .fniv = gen_shr_ins_vec,
+ .fno = gen_helper_gvec_sri_s,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_32 },
+ { .fni8 = gen_shr64_ins_i64,
+ .fniv = gen_shr_ins_vec,
+ .fno = gen_helper_gvec_sri_d,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_64 },
+ };
+
+ /* tszimm encoding produces immediates in the range [1..esize]. */
+ tcg_debug_assert(shift > 0);
+ tcg_debug_assert(shift <= (8 << vece));
+
+ /* Shift of esize leaves destination unchanged. */
+ if (shift < (8 << vece)) {
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
} else {
- TCGv_vec t = tcg_temp_new_vec_matching(d);
- TCGv_vec m = tcg_temp_new_vec_matching(d);
-
- tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
- tcg_gen_shri_vec(vece, t, a, sh);
- tcg_gen_and_vec(vece, d, d, m);
- tcg_gen_or_vec(vece, d, d, t);
-
- tcg_temp_free_vec(t);
- tcg_temp_free_vec(m);
- }
-}
-
-static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
-
-const GVecGen2i sri_op[4] = {
- { .fni8 = gen_shr8_ins_i64,
- .fniv = gen_shr_ins_vec,
- .load_dest = true,
- .opt_opc = vecop_list_sri,
- .vece = MO_8 },
- { .fni8 = gen_shr16_ins_i64,
- .fniv = gen_shr_ins_vec,
- .load_dest = true,
- .opt_opc = vecop_list_sri,
- .vece = MO_16 },
- { .fni4 = gen_shr32_ins_i32,
- .fniv = gen_shr_ins_vec,
- .load_dest = true,
- .opt_opc = vecop_list_sri,
- .vece = MO_32 },
- { .fni8 = gen_shr64_ins_i64,
- .fniv = gen_shr_ins_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .load_dest = true,
- .opt_opc = vecop_list_sri,
- .vece = MO_64 },
-};
+ /* Nop, but we do need to clear the tail. */
+ tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
+ }
+}
static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
{
static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
{
- if (sh == 0) {
- tcg_gen_mov_vec(d, a);
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
+ TCGv_vec m = tcg_temp_new_vec_matching(d);
+
+ tcg_gen_shli_vec(vece, t, a, sh);
+ tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
+ tcg_gen_and_vec(vece, d, d, m);
+ tcg_gen_or_vec(vece, d, d, t);
+
+ tcg_temp_free_vec(t);
+ tcg_temp_free_vec(m);
+}
+
+void gen_gvec_sli(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = { INDEX_op_shli_vec, 0 };
+ const GVecGen2i ops[4] = {
+ { .fni8 = gen_shl8_ins_i64,
+ .fniv = gen_shl_ins_vec,
+ .fno = gen_helper_gvec_sli_b,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_8 },
+ { .fni8 = gen_shl16_ins_i64,
+ .fniv = gen_shl_ins_vec,
+ .fno = gen_helper_gvec_sli_h,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_16 },
+ { .fni4 = gen_shl32_ins_i32,
+ .fniv = gen_shl_ins_vec,
+ .fno = gen_helper_gvec_sli_s,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_32 },
+ { .fni8 = gen_shl64_ins_i64,
+ .fniv = gen_shl_ins_vec,
+ .fno = gen_helper_gvec_sli_d,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_64 },
+ };
+
+ /* tszimm encoding produces immediates in the range [0..esize-1]. */
+ tcg_debug_assert(shift >= 0);
+ tcg_debug_assert(shift < (8 << vece));
+
+ if (shift == 0) {
+ tcg_gen_gvec_mov(vece, rd_ofs, rm_ofs, opr_sz, max_sz);
} else {
- TCGv_vec t = tcg_temp_new_vec_matching(d);
- TCGv_vec m = tcg_temp_new_vec_matching(d);
-
- tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
- tcg_gen_shli_vec(vece, t, a, sh);
- tcg_gen_and_vec(vece, d, d, m);
- tcg_gen_or_vec(vece, d, d, t);
-
- tcg_temp_free_vec(t);
- tcg_temp_free_vec(m);
- }
-}
-
-static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
-
-const GVecGen2i sli_op[4] = {
- { .fni8 = gen_shl8_ins_i64,
- .fniv = gen_shl_ins_vec,
- .load_dest = true,
- .opt_opc = vecop_list_sli,
- .vece = MO_8 },
- { .fni8 = gen_shl16_ins_i64,
- .fniv = gen_shl_ins_vec,
- .load_dest = true,
- .opt_opc = vecop_list_sli,
- .vece = MO_16 },
- { .fni4 = gen_shl32_ins_i32,
- .fniv = gen_shl_ins_vec,
- .load_dest = true,
- .opt_opc = vecop_list_sli,
- .vece = MO_32 },
- { .fni8 = gen_shl64_ins_i64,
- .fniv = gen_shl_ins_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .load_dest = true,
- .opt_opc = vecop_list_sli,
- .vece = MO_64 },
-};
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
+ }
+}
static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
{
/* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
* these tables are shared with AArch64 which does support them.
*/
+void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_mul_vec, INDEX_op_add_vec, 0
+ };
+ static const GVecGen3 ops[4] = {
+ { .fni4 = gen_mla8_i32,
+ .fniv = gen_mla_vec,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_8 },
+ { .fni4 = gen_mla16_i32,
+ .fniv = gen_mla_vec,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_16 },
+ { .fni4 = gen_mla32_i32,
+ .fniv = gen_mla_vec,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_32 },
+ { .fni8 = gen_mla64_i64,
+ .fniv = gen_mla_vec,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_64 },
+ };
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
+}
-static const TCGOpcode vecop_list_mla[] = {
- INDEX_op_mul_vec, INDEX_op_add_vec, 0
-};
-
-static const TCGOpcode vecop_list_mls[] = {
- INDEX_op_mul_vec, INDEX_op_sub_vec, 0
-};
-
-const GVecGen3 mla_op[4] = {
- { .fni4 = gen_mla8_i32,
- .fniv = gen_mla_vec,
- .load_dest = true,
- .opt_opc = vecop_list_mla,
- .vece = MO_8 },
- { .fni4 = gen_mla16_i32,
- .fniv = gen_mla_vec,
- .load_dest = true,
- .opt_opc = vecop_list_mla,
- .vece = MO_16 },
- { .fni4 = gen_mla32_i32,
- .fniv = gen_mla_vec,
- .load_dest = true,
- .opt_opc = vecop_list_mla,
- .vece = MO_32 },
- { .fni8 = gen_mla64_i64,
- .fniv = gen_mla_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .load_dest = true,
- .opt_opc = vecop_list_mla,
- .vece = MO_64 },
-};
-
-const GVecGen3 mls_op[4] = {
- { .fni4 = gen_mls8_i32,
- .fniv = gen_mls_vec,
- .load_dest = true,
- .opt_opc = vecop_list_mls,
- .vece = MO_8 },
- { .fni4 = gen_mls16_i32,
- .fniv = gen_mls_vec,
- .load_dest = true,
- .opt_opc = vecop_list_mls,
- .vece = MO_16 },
- { .fni4 = gen_mls32_i32,
- .fniv = gen_mls_vec,
- .load_dest = true,
- .opt_opc = vecop_list_mls,
- .vece = MO_32 },
- { .fni8 = gen_mls64_i64,
- .fniv = gen_mls_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .load_dest = true,
- .opt_opc = vecop_list_mls,
- .vece = MO_64 },
-};
+void gen_gvec_mls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_mul_vec, INDEX_op_sub_vec, 0
+ };
+ static const GVecGen3 ops[4] = {
+ { .fni4 = gen_mls8_i32,
+ .fniv = gen_mls_vec,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_8 },
+ { .fni4 = gen_mls16_i32,
+ .fniv = gen_mls_vec,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_16 },
+ { .fni4 = gen_mls32_i32,
+ .fniv = gen_mls_vec,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_32 },
+ { .fni8 = gen_mls64_i64,
+ .fniv = gen_mls_vec,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .load_dest = true,
+ .opt_opc = vecop_list,
+ .vece = MO_64 },
+ };
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
+}
/* CMTST : test is "if (X & Y != 0)". */
static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
}
-static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
-
-const GVecGen3 cmtst_op[4] = {
- { .fni4 = gen_helper_neon_tst_u8,
- .fniv = gen_cmtst_vec,
- .opt_opc = vecop_list_cmtst,
- .vece = MO_8 },
- { .fni4 = gen_helper_neon_tst_u16,
- .fniv = gen_cmtst_vec,
- .opt_opc = vecop_list_cmtst,
- .vece = MO_16 },
- { .fni4 = gen_cmtst_i32,
- .fniv = gen_cmtst_vec,
- .opt_opc = vecop_list_cmtst,
- .vece = MO_32 },
- { .fni8 = gen_cmtst_i64,
- .fniv = gen_cmtst_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .opt_opc = vecop_list_cmtst,
- .vece = MO_64 },
-};
+void gen_gvec_cmtst(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = { INDEX_op_cmp_vec, 0 };
+ static const GVecGen3 ops[4] = {
+ { .fni4 = gen_helper_neon_tst_u8,
+ .fniv = gen_cmtst_vec,
+ .opt_opc = vecop_list,
+ .vece = MO_8 },
+ { .fni4 = gen_helper_neon_tst_u16,
+ .fniv = gen_cmtst_vec,
+ .opt_opc = vecop_list,
+ .vece = MO_16 },
+ { .fni4 = gen_cmtst_i32,
+ .fniv = gen_cmtst_vec,
+ .opt_opc = vecop_list,
+ .vece = MO_32 },
+ { .fni8 = gen_cmtst_i64,
+ .fniv = gen_cmtst_vec,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .opt_opc = vecop_list,
+ .vece = MO_64 },
+ };
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
+}
void gen_ushl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
{
tcg_temp_free_vec(rsh);
}
-static const TCGOpcode ushl_list[] = {
- INDEX_op_neg_vec, INDEX_op_shlv_vec,
- INDEX_op_shrv_vec, INDEX_op_cmp_vec, 0
-};
-
-const GVecGen3 ushl_op[4] = {
- { .fniv = gen_ushl_vec,
- .fno = gen_helper_gvec_ushl_b,
- .opt_opc = ushl_list,
- .vece = MO_8 },
- { .fniv = gen_ushl_vec,
- .fno = gen_helper_gvec_ushl_h,
- .opt_opc = ushl_list,
- .vece = MO_16 },
- { .fni4 = gen_ushl_i32,
- .fniv = gen_ushl_vec,
- .opt_opc = ushl_list,
- .vece = MO_32 },
- { .fni8 = gen_ushl_i64,
- .fniv = gen_ushl_vec,
- .opt_opc = ushl_list,
- .vece = MO_64 },
-};
+void gen_gvec_ushl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_neg_vec, INDEX_op_shlv_vec,
+ INDEX_op_shrv_vec, INDEX_op_cmp_vec, 0
+ };
+ static const GVecGen3 ops[4] = {
+ { .fniv = gen_ushl_vec,
+ .fno = gen_helper_gvec_ushl_b,
+ .opt_opc = vecop_list,
+ .vece = MO_8 },
+ { .fniv = gen_ushl_vec,
+ .fno = gen_helper_gvec_ushl_h,
+ .opt_opc = vecop_list,
+ .vece = MO_16 },
+ { .fni4 = gen_ushl_i32,
+ .fniv = gen_ushl_vec,
+ .opt_opc = vecop_list,
+ .vece = MO_32 },
+ { .fni8 = gen_ushl_i64,
+ .fniv = gen_ushl_vec,
+ .opt_opc = vecop_list,
+ .vece = MO_64 },
+ };
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
+}
void gen_sshl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
{
tcg_temp_free_vec(tmp);
}
-static const TCGOpcode sshl_list[] = {
- INDEX_op_neg_vec, INDEX_op_umin_vec, INDEX_op_shlv_vec,
- INDEX_op_sarv_vec, INDEX_op_cmp_vec, INDEX_op_cmpsel_vec, 0
-};
-
-const GVecGen3 sshl_op[4] = {
- { .fniv = gen_sshl_vec,
- .fno = gen_helper_gvec_sshl_b,
- .opt_opc = sshl_list,
- .vece = MO_8 },
- { .fniv = gen_sshl_vec,
- .fno = gen_helper_gvec_sshl_h,
- .opt_opc = sshl_list,
- .vece = MO_16 },
- { .fni4 = gen_sshl_i32,
- .fniv = gen_sshl_vec,
- .opt_opc = sshl_list,
- .vece = MO_32 },
- { .fni8 = gen_sshl_i64,
- .fniv = gen_sshl_vec,
- .opt_opc = sshl_list,
- .vece = MO_64 },
-};
+void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_neg_vec, INDEX_op_umin_vec, INDEX_op_shlv_vec,
+ INDEX_op_sarv_vec, INDEX_op_cmp_vec, INDEX_op_cmpsel_vec, 0
+ };
+ static const GVecGen3 ops[4] = {
+ { .fniv = gen_sshl_vec,
+ .fno = gen_helper_gvec_sshl_b,
+ .opt_opc = vecop_list,
+ .vece = MO_8 },
+ { .fniv = gen_sshl_vec,
+ .fno = gen_helper_gvec_sshl_h,
+ .opt_opc = vecop_list,
+ .vece = MO_16 },
+ { .fni4 = gen_sshl_i32,
+ .fniv = gen_sshl_vec,
+ .opt_opc = vecop_list,
+ .vece = MO_32 },
+ { .fni8 = gen_sshl_i64,
+ .fniv = gen_sshl_vec,
+ .opt_opc = vecop_list,
+ .vece = MO_64 },
+ };
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
+}
static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
TCGv_vec a, TCGv_vec b)
tcg_temp_free_vec(x);
}
-static const TCGOpcode vecop_list_uqadd[] = {
- INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
-};
-
-const GVecGen4 uqadd_op[4] = {
- { .fniv = gen_uqadd_vec,
- .fno = gen_helper_gvec_uqadd_b,
- .write_aofs = true,
- .opt_opc = vecop_list_uqadd,
- .vece = MO_8 },
- { .fniv = gen_uqadd_vec,
- .fno = gen_helper_gvec_uqadd_h,
- .write_aofs = true,
- .opt_opc = vecop_list_uqadd,
- .vece = MO_16 },
- { .fniv = gen_uqadd_vec,
- .fno = gen_helper_gvec_uqadd_s,
- .write_aofs = true,
- .opt_opc = vecop_list_uqadd,
- .vece = MO_32 },
- { .fniv = gen_uqadd_vec,
- .fno = gen_helper_gvec_uqadd_d,
- .write_aofs = true,
- .opt_opc = vecop_list_uqadd,
- .vece = MO_64 },
-};
+void gen_gvec_uqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
+ };
+ static const GVecGen4 ops[4] = {
+ { .fniv = gen_uqadd_vec,
+ .fno = gen_helper_gvec_uqadd_b,
+ .write_aofs = true,
+ .opt_opc = vecop_list,
+ .vece = MO_8 },
+ { .fniv = gen_uqadd_vec,
+ .fno = gen_helper_gvec_uqadd_h,
+ .write_aofs = true,
+ .opt_opc = vecop_list,
+ .vece = MO_16 },
+ { .fniv = gen_uqadd_vec,
+ .fno = gen_helper_gvec_uqadd_s,
+ .write_aofs = true,
+ .opt_opc = vecop_list,
+ .vece = MO_32 },
+ { .fniv = gen_uqadd_vec,
+ .fno = gen_helper_gvec_uqadd_d,
+ .write_aofs = true,
+ .opt_opc = vecop_list,
+ .vece = MO_64 },
+ };
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
+ rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
+}
static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
TCGv_vec a, TCGv_vec b)
tcg_temp_free_vec(x);
}
-static const TCGOpcode vecop_list_sqadd[] = {
- INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
-};
-
-const GVecGen4 sqadd_op[4] = {
- { .fniv = gen_sqadd_vec,
- .fno = gen_helper_gvec_sqadd_b,
- .opt_opc = vecop_list_sqadd,
- .write_aofs = true,
- .vece = MO_8 },
- { .fniv = gen_sqadd_vec,
- .fno = gen_helper_gvec_sqadd_h,
- .opt_opc = vecop_list_sqadd,
- .write_aofs = true,
- .vece = MO_16 },
- { .fniv = gen_sqadd_vec,
- .fno = gen_helper_gvec_sqadd_s,
- .opt_opc = vecop_list_sqadd,
- .write_aofs = true,
- .vece = MO_32 },
- { .fniv = gen_sqadd_vec,
- .fno = gen_helper_gvec_sqadd_d,
- .opt_opc = vecop_list_sqadd,
- .write_aofs = true,
- .vece = MO_64 },
-};
+void gen_gvec_sqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
+ };
+ static const GVecGen4 ops[4] = {
+ { .fniv = gen_sqadd_vec,
+ .fno = gen_helper_gvec_sqadd_b,
+ .opt_opc = vecop_list,
+ .write_aofs = true,
+ .vece = MO_8 },
+ { .fniv = gen_sqadd_vec,
+ .fno = gen_helper_gvec_sqadd_h,
+ .opt_opc = vecop_list,
+ .write_aofs = true,
+ .vece = MO_16 },
+ { .fniv = gen_sqadd_vec,
+ .fno = gen_helper_gvec_sqadd_s,
+ .opt_opc = vecop_list,
+ .write_aofs = true,
+ .vece = MO_32 },
+ { .fniv = gen_sqadd_vec,
+ .fno = gen_helper_gvec_sqadd_d,
+ .opt_opc = vecop_list,
+ .write_aofs = true,
+ .vece = MO_64 },
+ };
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
+ rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
+}
+
+static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
+ TCGv_vec a, TCGv_vec b)
+{
+ TCGv_vec x = tcg_temp_new_vec_matching(t);
+ tcg_gen_sub_vec(vece, x, a, b);
+ tcg_gen_ussub_vec(vece, t, a, b);
+ tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
+ tcg_gen_or_vec(vece, sat, sat, x);
+ tcg_temp_free_vec(x);
+}
+
+void gen_gvec_uqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
+ };
+ static const GVecGen4 ops[4] = {
+ { .fniv = gen_uqsub_vec,
+ .fno = gen_helper_gvec_uqsub_b,
+ .opt_opc = vecop_list,
+ .write_aofs = true,
+ .vece = MO_8 },
+ { .fniv = gen_uqsub_vec,
+ .fno = gen_helper_gvec_uqsub_h,
+ .opt_opc = vecop_list,
+ .write_aofs = true,
+ .vece = MO_16 },
+ { .fniv = gen_uqsub_vec,
+ .fno = gen_helper_gvec_uqsub_s,
+ .opt_opc = vecop_list,
+ .write_aofs = true,
+ .vece = MO_32 },
+ { .fniv = gen_uqsub_vec,
+ .fno = gen_helper_gvec_uqsub_d,
+ .opt_opc = vecop_list,
+ .write_aofs = true,
+ .vece = MO_64 },
+ };
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
+ rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
+}
+
+static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
+ TCGv_vec a, TCGv_vec b)
+{
+ TCGv_vec x = tcg_temp_new_vec_matching(t);
+ tcg_gen_sub_vec(vece, x, a, b);
+ tcg_gen_sssub_vec(vece, t, a, b);
+ tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
+ tcg_gen_or_vec(vece, sat, sat, x);
+ tcg_temp_free_vec(x);
+}
+
+void gen_gvec_sqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
+ };
+ static const GVecGen4 ops[4] = {
+ { .fniv = gen_sqsub_vec,
+ .fno = gen_helper_gvec_sqsub_b,
+ .opt_opc = vecop_list,
+ .write_aofs = true,
+ .vece = MO_8 },
+ { .fniv = gen_sqsub_vec,
+ .fno = gen_helper_gvec_sqsub_h,
+ .opt_opc = vecop_list,
+ .write_aofs = true,
+ .vece = MO_16 },
+ { .fniv = gen_sqsub_vec,
+ .fno = gen_helper_gvec_sqsub_s,
+ .opt_opc = vecop_list,
+ .write_aofs = true,
+ .vece = MO_32 },
+ { .fniv = gen_sqsub_vec,
+ .fno = gen_helper_gvec_sqsub_d,
+ .opt_opc = vecop_list,
+ .write_aofs = true,
+ .vece = MO_64 },
+ };
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
+ rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
+}
+
+static void gen_sabd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
+{
+ TCGv_i32 t = tcg_temp_new_i32();
+
+ tcg_gen_sub_i32(t, a, b);
+ tcg_gen_sub_i32(d, b, a);
+ tcg_gen_movcond_i32(TCG_COND_LT, d, a, b, d, t);
+ tcg_temp_free_i32(t);
+}
+
+static void gen_sabd_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ tcg_gen_sub_i64(t, a, b);
+ tcg_gen_sub_i64(d, b, a);
+ tcg_gen_movcond_i64(TCG_COND_LT, d, a, b, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_sabd_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
+{
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
+
+ tcg_gen_smin_vec(vece, t, a, b);
+ tcg_gen_smax_vec(vece, d, a, b);
+ tcg_gen_sub_vec(vece, d, d, t);
+ tcg_temp_free_vec(t);
+}
+
+void gen_gvec_sabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_sub_vec, INDEX_op_smin_vec, INDEX_op_smax_vec, 0
+ };
+ static const GVecGen3 ops[4] = {
+ { .fniv = gen_sabd_vec,
+ .fno = gen_helper_gvec_sabd_b,
+ .opt_opc = vecop_list,
+ .vece = MO_8 },
+ { .fniv = gen_sabd_vec,
+ .fno = gen_helper_gvec_sabd_h,
+ .opt_opc = vecop_list,
+ .vece = MO_16 },
+ { .fni4 = gen_sabd_i32,
+ .fniv = gen_sabd_vec,
+ .fno = gen_helper_gvec_sabd_s,
+ .opt_opc = vecop_list,
+ .vece = MO_32 },
+ { .fni8 = gen_sabd_i64,
+ .fniv = gen_sabd_vec,
+ .fno = gen_helper_gvec_sabd_d,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .opt_opc = vecop_list,
+ .vece = MO_64 },
+ };
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
+}
+
+static void gen_uabd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
+{
+ TCGv_i32 t = tcg_temp_new_i32();
+
+ tcg_gen_sub_i32(t, a, b);
+ tcg_gen_sub_i32(d, b, a);
+ tcg_gen_movcond_i32(TCG_COND_LTU, d, a, b, d, t);
+ tcg_temp_free_i32(t);
+}
+
+static void gen_uabd_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ tcg_gen_sub_i64(t, a, b);
+ tcg_gen_sub_i64(d, b, a);
+ tcg_gen_movcond_i64(TCG_COND_LTU, d, a, b, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_uabd_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
+{
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
+
+ tcg_gen_umin_vec(vece, t, a, b);
+ tcg_gen_umax_vec(vece, d, a, b);
+ tcg_gen_sub_vec(vece, d, d, t);
+ tcg_temp_free_vec(t);
+}
+
+void gen_gvec_uabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_sub_vec, INDEX_op_umin_vec, INDEX_op_umax_vec, 0
+ };
+ static const GVecGen3 ops[4] = {
+ { .fniv = gen_uabd_vec,
+ .fno = gen_helper_gvec_uabd_b,
+ .opt_opc = vecop_list,
+ .vece = MO_8 },
+ { .fniv = gen_uabd_vec,
+ .fno = gen_helper_gvec_uabd_h,
+ .opt_opc = vecop_list,
+ .vece = MO_16 },
+ { .fni4 = gen_uabd_i32,
+ .fniv = gen_uabd_vec,
+ .fno = gen_helper_gvec_uabd_s,
+ .opt_opc = vecop_list,
+ .vece = MO_32 },
+ { .fni8 = gen_uabd_i64,
+ .fniv = gen_uabd_vec,
+ .fno = gen_helper_gvec_uabd_d,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .opt_opc = vecop_list,
+ .vece = MO_64 },
+ };
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
+}
+
+static void gen_saba_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
+{
+ TCGv_i32 t = tcg_temp_new_i32();
+ gen_sabd_i32(t, a, b);
+ tcg_gen_add_i32(d, d, t);
+ tcg_temp_free_i32(t);
+}
+
+static void gen_saba_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+ TCGv_i64 t = tcg_temp_new_i64();
+ gen_sabd_i64(t, a, b);
+ tcg_gen_add_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
-static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
- TCGv_vec a, TCGv_vec b)
+static void gen_saba_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
{
- TCGv_vec x = tcg_temp_new_vec_matching(t);
- tcg_gen_sub_vec(vece, x, a, b);
- tcg_gen_ussub_vec(vece, t, a, b);
- tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
- tcg_gen_or_vec(vece, sat, sat, x);
- tcg_temp_free_vec(x);
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
+ gen_sabd_vec(vece, t, a, b);
+ tcg_gen_add_vec(vece, d, d, t);
+ tcg_temp_free_vec(t);
}
-static const TCGOpcode vecop_list_uqsub[] = {
- INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
-};
+void gen_gvec_saba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_sub_vec, INDEX_op_add_vec,
+ INDEX_op_smin_vec, INDEX_op_smax_vec, 0
+ };
+ static const GVecGen3 ops[4] = {
+ { .fniv = gen_saba_vec,
+ .fno = gen_helper_gvec_saba_b,
+ .opt_opc = vecop_list,
+ .load_dest = true,
+ .vece = MO_8 },
+ { .fniv = gen_saba_vec,
+ .fno = gen_helper_gvec_saba_h,
+ .opt_opc = vecop_list,
+ .load_dest = true,
+ .vece = MO_16 },
+ { .fni4 = gen_saba_i32,
+ .fniv = gen_saba_vec,
+ .fno = gen_helper_gvec_saba_s,
+ .opt_opc = vecop_list,
+ .load_dest = true,
+ .vece = MO_32 },
+ { .fni8 = gen_saba_i64,
+ .fniv = gen_saba_vec,
+ .fno = gen_helper_gvec_saba_d,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .opt_opc = vecop_list,
+ .load_dest = true,
+ .vece = MO_64 },
+ };
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
+}
-const GVecGen4 uqsub_op[4] = {
- { .fniv = gen_uqsub_vec,
- .fno = gen_helper_gvec_uqsub_b,
- .opt_opc = vecop_list_uqsub,
- .write_aofs = true,
- .vece = MO_8 },
- { .fniv = gen_uqsub_vec,
- .fno = gen_helper_gvec_uqsub_h,
- .opt_opc = vecop_list_uqsub,
- .write_aofs = true,
- .vece = MO_16 },
- { .fniv = gen_uqsub_vec,
- .fno = gen_helper_gvec_uqsub_s,
- .opt_opc = vecop_list_uqsub,
- .write_aofs = true,
- .vece = MO_32 },
- { .fniv = gen_uqsub_vec,
- .fno = gen_helper_gvec_uqsub_d,
- .opt_opc = vecop_list_uqsub,
- .write_aofs = true,
- .vece = MO_64 },
-};
+static void gen_uaba_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
+{
+ TCGv_i32 t = tcg_temp_new_i32();
+ gen_uabd_i32(t, a, b);
+ tcg_gen_add_i32(d, d, t);
+ tcg_temp_free_i32(t);
+}
-static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
- TCGv_vec a, TCGv_vec b)
+static void gen_uaba_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
{
- TCGv_vec x = tcg_temp_new_vec_matching(t);
- tcg_gen_sub_vec(vece, x, a, b);
- tcg_gen_sssub_vec(vece, t, a, b);
- tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
- tcg_gen_or_vec(vece, sat, sat, x);
- tcg_temp_free_vec(x);
+ TCGv_i64 t = tcg_temp_new_i64();
+ gen_uabd_i64(t, a, b);
+ tcg_gen_add_i64(d, d, t);
+ tcg_temp_free_i64(t);
}
-static const TCGOpcode vecop_list_sqsub[] = {
- INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
-};
+static void gen_uaba_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
+{
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
+ gen_uabd_vec(vece, t, a, b);
+ tcg_gen_add_vec(vece, d, d, t);
+ tcg_temp_free_vec(t);
+}
-const GVecGen4 sqsub_op[4] = {
- { .fniv = gen_sqsub_vec,
- .fno = gen_helper_gvec_sqsub_b,
- .opt_opc = vecop_list_sqsub,
- .write_aofs = true,
- .vece = MO_8 },
- { .fniv = gen_sqsub_vec,
- .fno = gen_helper_gvec_sqsub_h,
- .opt_opc = vecop_list_sqsub,
- .write_aofs = true,
- .vece = MO_16 },
- { .fniv = gen_sqsub_vec,
- .fno = gen_helper_gvec_sqsub_s,
- .opt_opc = vecop_list_sqsub,
- .write_aofs = true,
- .vece = MO_32 },
- { .fniv = gen_sqsub_vec,
- .fno = gen_helper_gvec_sqsub_d,
- .opt_opc = vecop_list_sqsub,
- .write_aofs = true,
- .vece = MO_64 },
-};
+void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+ static const TCGOpcode vecop_list[] = {
+ INDEX_op_sub_vec, INDEX_op_add_vec,
+ INDEX_op_umin_vec, INDEX_op_umax_vec, 0
+ };
+ static const GVecGen3 ops[4] = {
+ { .fniv = gen_uaba_vec,
+ .fno = gen_helper_gvec_uaba_b,
+ .opt_opc = vecop_list,
+ .load_dest = true,
+ .vece = MO_8 },
+ { .fniv = gen_uaba_vec,
+ .fno = gen_helper_gvec_uaba_h,
+ .opt_opc = vecop_list,
+ .load_dest = true,
+ .vece = MO_16 },
+ { .fni4 = gen_uaba_i32,
+ .fniv = gen_uaba_vec,
+ .fno = gen_helper_gvec_uaba_s,
+ .opt_opc = vecop_list,
+ .load_dest = true,
+ .vece = MO_32 },
+ { .fni8 = gen_uaba_i64,
+ .fniv = gen_uaba_vec,
+ .fno = gen_helper_gvec_uaba_d,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .opt_opc = vecop_list,
+ .load_dest = true,
+ .vece = MO_64 },
+ };
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
+}
/* Translate a NEON data processing instruction. Return nonzero if the
instruction is invalid.
int shift;
int pass;
int count;
- int pairwise;
int u;
int vec_size;
uint32_t imm;
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
- TCGv_ptr ptr1, ptr2, ptr3;
+ TCGv_ptr ptr1, ptr2;
TCGv_i64 tmp64;
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
rm_ofs = neon_reg_offset(rm, 0);
if ((insn & (1 << 23)) == 0) {
- /* Three register same length. */
- op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
- /* Catch invalid op and bad size combinations: UNDEF */
- if ((neon_3r_sizes[op] & (1 << size)) == 0) {
- return 1;
- }
- /* All insns of this form UNDEF for either this condition or the
- * superset of cases "Q==1"; we catch the latter later.
- */
- if (q && ((rd | rn | rm) & 1)) {
- return 1;
- }
- switch (op) {
- case NEON_3R_SHA:
- /* The SHA-1/SHA-256 3-register instructions require special
- * treatment here, as their size field is overloaded as an
- * op type selector, and they all consume their input in a
- * single pass.
- */
- if (!q) {
- return 1;
- }
- if (!u) { /* SHA-1 */
- if (!dc_isar_feature(aa32_sha1, s)) {
- return 1;
- }
- ptr1 = vfp_reg_ptr(true, rd);
- ptr2 = vfp_reg_ptr(true, rn);
- ptr3 = vfp_reg_ptr(true, rm);
- tmp4 = tcg_const_i32(size);
- gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
- tcg_temp_free_i32(tmp4);
- } else { /* SHA-256 */
- if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
- return 1;
- }
- ptr1 = vfp_reg_ptr(true, rd);
- ptr2 = vfp_reg_ptr(true, rn);
- ptr3 = vfp_reg_ptr(true, rm);
- switch (size) {
- case 0:
- gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
- break;
- case 1:
- gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
- break;
- case 2:
- gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
- break;
- }
- }
- tcg_temp_free_ptr(ptr1);
- tcg_temp_free_ptr(ptr2);
- tcg_temp_free_ptr(ptr3);
- return 0;
-
- case NEON_3R_VPADD_VQRDMLAH:
- if (!u) {
- break; /* VPADD */
- }
- /* VQRDMLAH */
- switch (size) {
- case 1:
- return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
- q, rd, rn, rm);
- case 2:
- return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
- q, rd, rn, rm);
- }
- return 1;
-
- case NEON_3R_VFM_VQRDMLSH:
- if (!u) {
- /* VFM, VFMS */
- if (size == 1) {
- return 1;
- }
- break;
- }
- /* VQRDMLSH */
- switch (size) {
- case 1:
- return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
- q, rd, rn, rm);
- case 2:
- return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
- q, rd, rn, rm);
- }
- return 1;
-
- case NEON_3R_VADD_VSUB:
- case NEON_3R_LOGIC:
- case NEON_3R_VMAX:
- case NEON_3R_VMIN:
- case NEON_3R_VTST_VCEQ:
- case NEON_3R_VCGT:
- case NEON_3R_VCGE:
- case NEON_3R_VQADD:
- case NEON_3R_VQSUB:
- case NEON_3R_VMUL:
- case NEON_3R_VML:
- case NEON_3R_VSHL:
- /* Already handled by decodetree */
- return 1;
- }
-
- if (size == 3) {
- /* 64-bit element instructions. */
- for (pass = 0; pass < (q ? 2 : 1); pass++) {
- neon_load_reg64(cpu_V0, rn + pass);
- neon_load_reg64(cpu_V1, rm + pass);
- switch (op) {
- case NEON_3R_VQSHL:
- if (u) {
- gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
- cpu_V1, cpu_V0);
- } else {
- gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
- cpu_V1, cpu_V0);
- }
- break;
- case NEON_3R_VRSHL:
- if (u) {
- gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
- } else {
- gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
- }
- break;
- case NEON_3R_VQRSHL:
- if (u) {
- gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
- cpu_V1, cpu_V0);
- } else {
- gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
- cpu_V1, cpu_V0);
- }
- break;
- default:
- abort();
- }
- neon_store_reg64(cpu_V0, rd + pass);
- }
- return 0;
- }
- pairwise = 0;
- switch (op) {
- case NEON_3R_VQSHL:
- case NEON_3R_VRSHL:
- case NEON_3R_VQRSHL:
- {
- int rtmp;
- /* Shift instruction operands are reversed. */
- rtmp = rn;
- rn = rm;
- rm = rtmp;
- }
- break;
- case NEON_3R_VPADD_VQRDMLAH:
- case NEON_3R_VPMAX:
- case NEON_3R_VPMIN:
- pairwise = 1;
- break;
- case NEON_3R_FLOAT_ARITH:
- pairwise = (u && size < 2); /* if VPADD (float) */
- break;
- case NEON_3R_FLOAT_MINMAX:
- pairwise = u; /* if VPMIN/VPMAX (float) */
- break;
- case NEON_3R_FLOAT_CMP:
- if (!u && size) {
- /* no encoding for U=0 C=1x */
- return 1;
- }
- break;
- case NEON_3R_FLOAT_ACMP:
- if (!u) {
- return 1;
- }
- break;
- case NEON_3R_FLOAT_MISC:
- /* VMAXNM/VMINNM in ARMv8 */
- if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
- return 1;
- }
- break;
- case NEON_3R_VFM_VQRDMLSH:
- if (!dc_isar_feature(aa32_simdfmac, s)) {
- return 1;
- }
- break;
- default:
- break;
- }
-
- if (pairwise && q) {
- /* All the pairwise insns UNDEF if Q is set */
- return 1;
- }
-
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
-
- if (pairwise) {
- /* Pairwise. */
- if (pass < 1) {
- tmp = neon_load_reg(rn, 0);
- tmp2 = neon_load_reg(rn, 1);
- } else {
- tmp = neon_load_reg(rm, 0);
- tmp2 = neon_load_reg(rm, 1);
- }
- } else {
- /* Elementwise. */
- tmp = neon_load_reg(rn, pass);
- tmp2 = neon_load_reg(rm, pass);
- }
- switch (op) {
- case NEON_3R_VHADD:
- GEN_NEON_INTEGER_OP(hadd);
- break;
- case NEON_3R_VRHADD:
- GEN_NEON_INTEGER_OP(rhadd);
- break;
- case NEON_3R_VHSUB:
- GEN_NEON_INTEGER_OP(hsub);
- break;
- case NEON_3R_VQSHL:
- GEN_NEON_INTEGER_OP_ENV(qshl);
- break;
- case NEON_3R_VRSHL:
- GEN_NEON_INTEGER_OP(rshl);
- break;
- case NEON_3R_VQRSHL:
- GEN_NEON_INTEGER_OP_ENV(qrshl);
- break;
- case NEON_3R_VABD:
- GEN_NEON_INTEGER_OP(abd);
- break;
- case NEON_3R_VABA:
- GEN_NEON_INTEGER_OP(abd);
- tcg_temp_free_i32(tmp2);
- tmp2 = neon_load_reg(rd, pass);
- gen_neon_add(size, tmp, tmp2);
- break;
- case NEON_3R_VPMAX:
- GEN_NEON_INTEGER_OP(pmax);
- break;
- case NEON_3R_VPMIN:
- GEN_NEON_INTEGER_OP(pmin);
- break;
- case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
- if (!u) { /* VQDMULH */
- switch (size) {
- case 1:
- gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
- break;
- case 2:
- gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
- break;
- default: abort();
- }
- } else { /* VQRDMULH */
- switch (size) {
- case 1:
- gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
- break;
- case 2:
- gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
- break;
- default: abort();
- }
- }
- break;
- case NEON_3R_VPADD_VQRDMLAH:
- switch (size) {
- case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
- case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
- case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
- default: abort();
- }
- break;
- case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
- {
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
- switch ((u << 2) | size) {
- case 0: /* VADD */
- case 4: /* VPADD */
- gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
- break;
- case 2: /* VSUB */
- gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
- break;
- case 6: /* VABD */
- gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
- break;
- default:
- abort();
- }
- tcg_temp_free_ptr(fpstatus);
- break;
- }
- case NEON_3R_FLOAT_MULTIPLY:
- {
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
- gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
- if (!u) {
- tcg_temp_free_i32(tmp2);
- tmp2 = neon_load_reg(rd, pass);
- if (size == 0) {
- gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
- } else {
- gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
- }
- }
- tcg_temp_free_ptr(fpstatus);
- break;
- }
- case NEON_3R_FLOAT_CMP:
- {
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
- if (!u) {
- gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
- } else {
- if (size == 0) {
- gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
- } else {
- gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
- }
- }
- tcg_temp_free_ptr(fpstatus);
- break;
- }
- case NEON_3R_FLOAT_ACMP:
- {
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
- if (size == 0) {
- gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
- } else {
- gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
- }
- tcg_temp_free_ptr(fpstatus);
- break;
- }
- case NEON_3R_FLOAT_MINMAX:
- {
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
- if (size == 0) {
- gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
- } else {
- gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
- }
- tcg_temp_free_ptr(fpstatus);
- break;
- }
- case NEON_3R_FLOAT_MISC:
- if (u) {
- /* VMAXNM/VMINNM */
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
- if (size == 0) {
- gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
- } else {
- gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
- }
- tcg_temp_free_ptr(fpstatus);
- } else {
- if (size == 0) {
- gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
- } else {
- gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
- }
- }
- break;
- case NEON_3R_VFM_VQRDMLSH:
- {
- /* VFMA, VFMS: fused multiply-add */
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
- TCGv_i32 tmp3 = neon_load_reg(rd, pass);
- if (size) {
- /* VFMS */
- gen_helper_vfp_negs(tmp, tmp);
- }
- gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
- tcg_temp_free_i32(tmp3);
- tcg_temp_free_ptr(fpstatus);
- break;
- }
- default:
- abort();
- }
- tcg_temp_free_i32(tmp2);
-
- /* Save the result. For elementwise operations we can put it
- straight into the destination register. For pairwise operations
- we have to be careful to avoid clobbering the source operands. */
- if (pairwise && rd == rm) {
- neon_store_scratch(pass, tmp);
- } else {
- neon_store_reg(rd, pass, tmp);
- }
-
- } /* for pass */
- if (pairwise && rd == rm) {
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
- tmp = neon_load_scratch(pass);
- neon_store_reg(rd, pass, tmp);
- }
- }
- /* End of 3 register same size operations. */
+ /* Three register same length: handled by decodetree */
+ return 1;
} else if (insn & (1 << 4)) {
if ((insn & 0x00380080) != 0) {
/* Two registers and shift. */
case 1: /* VSRA */
/* Right shift comes here negative. */
shift = -shift;
- /* Shifts larger than the element size are architecturally
- * valid. Unsigned results in all zeros; signed results
- * in all sign bits.
- */
- if (!u) {
- tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
- MIN(shift, (8 << size) - 1),
- &ssra_op[size]);
- } else if (shift >= 8 << size) {
- /* rd += 0 */
+ if (u) {
+ gen_gvec_usra(size, rd_ofs, rm_ofs, shift,
+ vec_size, vec_size);
+ } else {
+ gen_gvec_ssra(size, rd_ofs, rm_ofs, shift,
+ vec_size, vec_size);
+ }
+ return 0;
+
+ case 2: /* VRSHR */
+ /* Right shift comes here negative. */
+ shift = -shift;
+ if (u) {
+ gen_gvec_urshr(size, rd_ofs, rm_ofs, shift,
+ vec_size, vec_size);
+ } else {
+ gen_gvec_srshr(size, rd_ofs, rm_ofs, shift,
+ vec_size, vec_size);
+ }
+ return 0;
+
+ case 3: /* VRSRA */
+ /* Right shift comes here negative. */
+ shift = -shift;
+ if (u) {
+ gen_gvec_ursra(size, rd_ofs, rm_ofs, shift,
+ vec_size, vec_size);
} else {
- tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
- shift, &usra_op[size]);
+ gen_gvec_srsra(size, rd_ofs, rm_ofs, shift,
+ vec_size, vec_size);
}
return 0;
}
/* Right shift comes here negative. */
shift = -shift;
- /* Shift out of range leaves destination unchanged. */
- if (shift < 8 << size) {
- tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
- shift, &sri_op[size]);
- }
+ gen_gvec_sri(size, rd_ofs, rm_ofs, shift,
+ vec_size, vec_size);
return 0;
case 5: /* VSHL, VSLI */
if (u) { /* VSLI */
- /* Shift out of range leaves destination unchanged. */
- if (shift < 8 << size) {
- tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
- vec_size, shift, &sli_op[size]);
- }
+ gen_gvec_sli(size, rd_ofs, rm_ofs, shift,
+ vec_size, vec_size);
} else { /* VSHL */
- /* Shifts larger than the element size are
- * architecturally valid and results in zero.
- */
- if (shift >= 8 << size) {
- tcg_gen_gvec_dup_imm(size, rd_ofs,
- vec_size, vec_size, 0);
- } else {
- tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
- vec_size, vec_size);
- }
+ tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
+ vec_size, vec_size);
}
return 0;
}
neon_load_reg64(cpu_V0, rm + pass);
tcg_gen_movi_i64(cpu_V1, imm);
switch (op) {
- case 2: /* VRSHR */
- case 3: /* VRSRA */
- if (u)
- gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
- else
- gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
- break;
case 6: /* VQSHLU */
gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
cpu_V0, cpu_V1);
default:
g_assert_not_reached();
}
- if (op == 3) {
- /* Accumulate. */
- neon_load_reg64(cpu_V1, rd + pass);
- tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
- }
neon_store_reg64(cpu_V0, rd + pass);
} else { /* size < 3 */
/* Operands in T0 and T1. */
tmp2 = tcg_temp_new_i32();
tcg_gen_movi_i32(tmp2, imm);
switch (op) {
- case 2: /* VRSHR */
- case 3: /* VRSRA */
- GEN_NEON_INTEGER_OP(rshl);
- break;
case 6: /* VQSHLU */
switch (size) {
case 0:
g_assert_not_reached();
}
tcg_temp_free_i32(tmp2);
-
- if (op == 3) {
- /* Accumulate. */
- tmp2 = neon_load_reg(rd, pass);
- gen_neon_add(size, tmp, tmp2);
- tcg_temp_free_i32(tmp2);
- }
neon_store_reg(rd, pass, tmp);
}
} /* for pass */
break;
case NEON_2RM_VCEQ0:
- tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
- vec_size, &ceq0_op[size]);
+ gen_gvec_ceq0(size, rd_ofs, rm_ofs, vec_size, vec_size);
break;
case NEON_2RM_VCGT0:
- tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
- vec_size, &cgt0_op[size]);
+ gen_gvec_cgt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
break;
case NEON_2RM_VCLE0:
- tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
- vec_size, &cle0_op[size]);
+ gen_gvec_cle0(size, rd_ofs, rm_ofs, vec_size, vec_size);
break;
case NEON_2RM_VCGE0:
- tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
- vec_size, &cge0_op[size]);
+ gen_gvec_cge0(size, rd_ofs, rm_ofs, vec_size, vec_size);
break;
case NEON_2RM_VCLT0:
- tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
- vec_size, &clt0_op[size]);
+ gen_gvec_clt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
break;
default:
break;
}
case NEON_2RM_VRECPE:
- {
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
- gen_helper_recpe_u32(tmp, tmp, fpstatus);
- tcg_temp_free_ptr(fpstatus);
+ gen_helper_recpe_u32(tmp, tmp);
break;
- }
case NEON_2RM_VRSQRTE:
- {
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
- gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
- tcg_temp_free_ptr(fpstatus);
+ gen_helper_rsqrte_u32(tmp, tmp);
break;
- }
case NEON_2RM_VRECPE_F:
{
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
uint64_t vfp_expand_imm(int size, uint8_t imm8);
/* Vector operations shared between ARM and AArch64. */
-extern const GVecGen2 ceq0_op[4];
-extern const GVecGen2 clt0_op[4];
-extern const GVecGen2 cgt0_op[4];
-extern const GVecGen2 cle0_op[4];
-extern const GVecGen2 cge0_op[4];
-extern const GVecGen3 mla_op[4];
-extern const GVecGen3 mls_op[4];
-extern const GVecGen3 cmtst_op[4];
-extern const GVecGen3 sshl_op[4];
-extern const GVecGen3 ushl_op[4];
-extern const GVecGen2i ssra_op[4];
-extern const GVecGen2i usra_op[4];
-extern const GVecGen2i sri_op[4];
-extern const GVecGen2i sli_op[4];
-extern const GVecGen4 uqadd_op[4];
-extern const GVecGen4 sqadd_op[4];
-extern const GVecGen4 uqsub_op[4];
-extern const GVecGen4 sqsub_op[4];
+void gen_gvec_ceq0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_clt0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_cgt0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_cle0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_cge0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ uint32_t opr_sz, uint32_t max_sz);
+
+void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_mls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+
+void gen_gvec_cmtst(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_ushl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+
void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
void gen_ushl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
void gen_sshl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
void gen_ushl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
+void gen_gvec_uqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_sqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_uqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_sqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+
+void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz);
+
+void gen_gvec_srshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_urshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_srsra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_ursra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz);
+
+void gen_gvec_sri(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_sli(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz);
+
+void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+
+void gen_gvec_sabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_uabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+
+void gen_gvec_saba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+
/*
* Forward to the isar_feature_* tests given a DisasContext pointer.
*/
#define H4(x) (x)
#endif
-#define SET_QC() env->vfp.qc[0] = 1
-
static void clear_tail(void *vd, uintptr_t opr_sz, uintptr_t max_sz)
{
uint64_t *d = vd + opr_sz;
}
/* Signed saturating rounding doubling multiply-accumulate high half, 16-bit */
-static uint16_t inl_qrdmlah_s16(CPUARMState *env, int16_t src1,
- int16_t src2, int16_t src3)
+static int16_t inl_qrdmlah_s16(int16_t src1, int16_t src2,
+ int16_t src3, uint32_t *sat)
{
/* Simplify:
* = ((a3 << 16) + ((e1 * e2) << 1) + (1 << 15)) >> 16
ret = ((int32_t)src3 << 15) + ret + (1 << 14);
ret >>= 15;
if (ret != (int16_t)ret) {
- SET_QC();
+ *sat = 1;
ret = (ret < 0 ? -0x8000 : 0x7fff);
}
return ret;
uint32_t HELPER(neon_qrdmlah_s16)(CPUARMState *env, uint32_t src1,
uint32_t src2, uint32_t src3)
{
- uint16_t e1 = inl_qrdmlah_s16(env, src1, src2, src3);
- uint16_t e2 = inl_qrdmlah_s16(env, src1 >> 16, src2 >> 16, src3 >> 16);
+ uint32_t *sat = &env->vfp.qc[0];
+ uint16_t e1 = inl_qrdmlah_s16(src1, src2, src3, sat);
+ uint16_t e2 = inl_qrdmlah_s16(src1 >> 16, src2 >> 16, src3 >> 16, sat);
return deposit32(e1, 16, 16, e2);
}
void HELPER(gvec_qrdmlah_s16)(void *vd, void *vn, void *vm,
- void *ve, uint32_t desc)
+ void *vq, uint32_t desc)
{
uintptr_t opr_sz = simd_oprsz(desc);
int16_t *d = vd;
int16_t *n = vn;
int16_t *m = vm;
- CPUARMState *env = ve;
uintptr_t i;
for (i = 0; i < opr_sz / 2; ++i) {
- d[i] = inl_qrdmlah_s16(env, n[i], m[i], d[i]);
+ d[i] = inl_qrdmlah_s16(n[i], m[i], d[i], vq);
}
clear_tail(d, opr_sz, simd_maxsz(desc));
}
/* Signed saturating rounding doubling multiply-subtract high half, 16-bit */
-static uint16_t inl_qrdmlsh_s16(CPUARMState *env, int16_t src1,
- int16_t src2, int16_t src3)
+static int16_t inl_qrdmlsh_s16(int16_t src1, int16_t src2,
+ int16_t src3, uint32_t *sat)
{
/* Similarly, using subtraction:
* = ((a3 << 16) - ((e1 * e2) << 1) + (1 << 15)) >> 16
ret = ((int32_t)src3 << 15) - ret + (1 << 14);
ret >>= 15;
if (ret != (int16_t)ret) {
- SET_QC();
+ *sat = 1;
ret = (ret < 0 ? -0x8000 : 0x7fff);
}
return ret;
uint32_t HELPER(neon_qrdmlsh_s16)(CPUARMState *env, uint32_t src1,
uint32_t src2, uint32_t src3)
{
- uint16_t e1 = inl_qrdmlsh_s16(env, src1, src2, src3);
- uint16_t e2 = inl_qrdmlsh_s16(env, src1 >> 16, src2 >> 16, src3 >> 16);
+ uint32_t *sat = &env->vfp.qc[0];
+ uint16_t e1 = inl_qrdmlsh_s16(src1, src2, src3, sat);
+ uint16_t e2 = inl_qrdmlsh_s16(src1 >> 16, src2 >> 16, src3 >> 16, sat);
return deposit32(e1, 16, 16, e2);
}
void HELPER(gvec_qrdmlsh_s16)(void *vd, void *vn, void *vm,
- void *ve, uint32_t desc)
+ void *vq, uint32_t desc)
{
uintptr_t opr_sz = simd_oprsz(desc);
int16_t *d = vd;
int16_t *n = vn;
int16_t *m = vm;
- CPUARMState *env = ve;
uintptr_t i;
for (i = 0; i < opr_sz / 2; ++i) {
- d[i] = inl_qrdmlsh_s16(env, n[i], m[i], d[i]);
+ d[i] = inl_qrdmlsh_s16(n[i], m[i], d[i], vq);
}
clear_tail(d, opr_sz, simd_maxsz(desc));
}
/* Signed saturating rounding doubling multiply-accumulate high half, 32-bit */
-uint32_t HELPER(neon_qrdmlah_s32)(CPUARMState *env, int32_t src1,
- int32_t src2, int32_t src3)
+static int32_t inl_qrdmlah_s32(int32_t src1, int32_t src2,
+ int32_t src3, uint32_t *sat)
{
/* Simplify similarly to int_qrdmlah_s16 above. */
int64_t ret = (int64_t)src1 * src2;
ret = ((int64_t)src3 << 31) + ret + (1 << 30);
ret >>= 31;
if (ret != (int32_t)ret) {
- SET_QC();
+ *sat = 1;
ret = (ret < 0 ? INT32_MIN : INT32_MAX);
}
return ret;
}
+uint32_t HELPER(neon_qrdmlah_s32)(CPUARMState *env, int32_t src1,
+ int32_t src2, int32_t src3)
+{
+ uint32_t *sat = &env->vfp.qc[0];
+ return inl_qrdmlah_s32(src1, src2, src3, sat);
+}
+
void HELPER(gvec_qrdmlah_s32)(void *vd, void *vn, void *vm,
- void *ve, uint32_t desc)
+ void *vq, uint32_t desc)
{
uintptr_t opr_sz = simd_oprsz(desc);
int32_t *d = vd;
int32_t *n = vn;
int32_t *m = vm;
- CPUARMState *env = ve;
uintptr_t i;
for (i = 0; i < opr_sz / 4; ++i) {
- d[i] = helper_neon_qrdmlah_s32(env, n[i], m[i], d[i]);
+ d[i] = inl_qrdmlah_s32(n[i], m[i], d[i], vq);
}
clear_tail(d, opr_sz, simd_maxsz(desc));
}
/* Signed saturating rounding doubling multiply-subtract high half, 32-bit */
-uint32_t HELPER(neon_qrdmlsh_s32)(CPUARMState *env, int32_t src1,
- int32_t src2, int32_t src3)
+static int32_t inl_qrdmlsh_s32(int32_t src1, int32_t src2,
+ int32_t src3, uint32_t *sat)
{
/* Simplify similarly to int_qrdmlsh_s16 above. */
int64_t ret = (int64_t)src1 * src2;
ret = ((int64_t)src3 << 31) - ret + (1 << 30);
ret >>= 31;
if (ret != (int32_t)ret) {
- SET_QC();
+ *sat = 1;
ret = (ret < 0 ? INT32_MIN : INT32_MAX);
}
return ret;
}
+uint32_t HELPER(neon_qrdmlsh_s32)(CPUARMState *env, int32_t src1,
+ int32_t src2, int32_t src3)
+{
+ uint32_t *sat = &env->vfp.qc[0];
+ return inl_qrdmlsh_s32(src1, src2, src3, sat);
+}
+
void HELPER(gvec_qrdmlsh_s32)(void *vd, void *vn, void *vm,
- void *ve, uint32_t desc)
+ void *vq, uint32_t desc)
{
uintptr_t opr_sz = simd_oprsz(desc);
int32_t *d = vd;
int32_t *n = vn;
int32_t *m = vm;
- CPUARMState *env = ve;
uintptr_t i;
for (i = 0; i < opr_sz / 4; ++i) {
- d[i] = helper_neon_qrdmlsh_s32(env, n[i], m[i], d[i]);
+ d[i] = inl_qrdmlsh_s32(n[i], m[i], d[i], vq);
}
clear_tail(d, opr_sz, simd_maxsz(desc));
}
return result;
}
+static float32 float32_abd(float32 op1, float32 op2, float_status *stat)
+{
+ return float32_abs(float32_sub(op1, op2, stat));
+}
+
#define DO_3OP(NAME, FUNC, TYPE) \
void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
{ \
DO_3OP(gvec_ftsmul_s, float32_ftsmul, float32)
DO_3OP(gvec_ftsmul_d, float64_ftsmul, float64)
+DO_3OP(gvec_fabd_s, float32_abd, float32)
+
#ifdef TARGET_AARCH64
DO_3OP(gvec_recps_h, helper_recpsf_f16, float16)
d[i + j] = TYPE##_mul(n[i + j], mm, stat); \
} \
} \
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
}
DO_MUL_IDX(gvec_fmul_idx_h, float16, H2)
mm, a[i + j], 0, stat); \
} \
} \
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
}
DO_FMLA_IDX(gvec_fmla_idx_h, float16, H2)
clear_tail(d, oprsz, simd_maxsz(desc));
}
+
+#define DO_SRA(NAME, TYPE) \
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
+{ \
+ intptr_t i, oprsz = simd_oprsz(desc); \
+ int shift = simd_data(desc); \
+ TYPE *d = vd, *n = vn; \
+ for (i = 0; i < oprsz / sizeof(TYPE); i++) { \
+ d[i] += n[i] >> shift; \
+ } \
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
+}
+
+DO_SRA(gvec_ssra_b, int8_t)
+DO_SRA(gvec_ssra_h, int16_t)
+DO_SRA(gvec_ssra_s, int32_t)
+DO_SRA(gvec_ssra_d, int64_t)
+
+DO_SRA(gvec_usra_b, uint8_t)
+DO_SRA(gvec_usra_h, uint16_t)
+DO_SRA(gvec_usra_s, uint32_t)
+DO_SRA(gvec_usra_d, uint64_t)
+
+#undef DO_SRA
+
+#define DO_RSHR(NAME, TYPE) \
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
+{ \
+ intptr_t i, oprsz = simd_oprsz(desc); \
+ int shift = simd_data(desc); \
+ TYPE *d = vd, *n = vn; \
+ for (i = 0; i < oprsz / sizeof(TYPE); i++) { \
+ TYPE tmp = n[i] >> (shift - 1); \
+ d[i] = (tmp >> 1) + (tmp & 1); \
+ } \
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
+}
+
+DO_RSHR(gvec_srshr_b, int8_t)
+DO_RSHR(gvec_srshr_h, int16_t)
+DO_RSHR(gvec_srshr_s, int32_t)
+DO_RSHR(gvec_srshr_d, int64_t)
+
+DO_RSHR(gvec_urshr_b, uint8_t)
+DO_RSHR(gvec_urshr_h, uint16_t)
+DO_RSHR(gvec_urshr_s, uint32_t)
+DO_RSHR(gvec_urshr_d, uint64_t)
+
+#undef DO_RSHR
+
+#define DO_RSRA(NAME, TYPE) \
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
+{ \
+ intptr_t i, oprsz = simd_oprsz(desc); \
+ int shift = simd_data(desc); \
+ TYPE *d = vd, *n = vn; \
+ for (i = 0; i < oprsz / sizeof(TYPE); i++) { \
+ TYPE tmp = n[i] >> (shift - 1); \
+ d[i] += (tmp >> 1) + (tmp & 1); \
+ } \
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
+}
+
+DO_RSRA(gvec_srsra_b, int8_t)
+DO_RSRA(gvec_srsra_h, int16_t)
+DO_RSRA(gvec_srsra_s, int32_t)
+DO_RSRA(gvec_srsra_d, int64_t)
+
+DO_RSRA(gvec_ursra_b, uint8_t)
+DO_RSRA(gvec_ursra_h, uint16_t)
+DO_RSRA(gvec_ursra_s, uint32_t)
+DO_RSRA(gvec_ursra_d, uint64_t)
+
+#undef DO_RSRA
+
+#define DO_SRI(NAME, TYPE) \
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
+{ \
+ intptr_t i, oprsz = simd_oprsz(desc); \
+ int shift = simd_data(desc); \
+ TYPE *d = vd, *n = vn; \
+ for (i = 0; i < oprsz / sizeof(TYPE); i++) { \
+ d[i] = deposit64(d[i], 0, sizeof(TYPE) * 8 - shift, n[i] >> shift); \
+ } \
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
+}
+
+DO_SRI(gvec_sri_b, uint8_t)
+DO_SRI(gvec_sri_h, uint16_t)
+DO_SRI(gvec_sri_s, uint32_t)
+DO_SRI(gvec_sri_d, uint64_t)
+
+#undef DO_SRI
+
+#define DO_SLI(NAME, TYPE) \
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
+{ \
+ intptr_t i, oprsz = simd_oprsz(desc); \
+ int shift = simd_data(desc); \
+ TYPE *d = vd, *n = vn; \
+ for (i = 0; i < oprsz / sizeof(TYPE); i++) { \
+ d[i] = deposit64(d[i], shift, sizeof(TYPE) * 8 - shift, n[i]); \
+ } \
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
+}
+
+DO_SLI(gvec_sli_b, uint8_t)
+DO_SLI(gvec_sli_h, uint16_t)
+DO_SLI(gvec_sli_s, uint32_t)
+DO_SLI(gvec_sli_d, uint64_t)
+
+#undef DO_SLI
+
/*
* Convert float16 to float32, raising no exceptions and
* preserving exceptional values, including SNaN.
DO_CMP0(gvec_cge0_h, int16_t, >=)
#undef DO_CMP0
+
+#define DO_ABD(NAME, TYPE) \
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
+{ \
+ intptr_t i, opr_sz = simd_oprsz(desc); \
+ TYPE *d = vd, *n = vn, *m = vm; \
+ \
+ for (i = 0; i < opr_sz / sizeof(TYPE); ++i) { \
+ d[i] = n[i] < m[i] ? m[i] - n[i] : n[i] - m[i]; \
+ } \
+ clear_tail(d, opr_sz, simd_maxsz(desc)); \
+}
+
+DO_ABD(gvec_sabd_b, int8_t)
+DO_ABD(gvec_sabd_h, int16_t)
+DO_ABD(gvec_sabd_s, int32_t)
+DO_ABD(gvec_sabd_d, int64_t)
+
+DO_ABD(gvec_uabd_b, uint8_t)
+DO_ABD(gvec_uabd_h, uint16_t)
+DO_ABD(gvec_uabd_s, uint32_t)
+DO_ABD(gvec_uabd_d, uint64_t)
+
+#undef DO_ABD
+
+#define DO_ABA(NAME, TYPE) \
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
+{ \
+ intptr_t i, opr_sz = simd_oprsz(desc); \
+ TYPE *d = vd, *n = vn, *m = vm; \
+ \
+ for (i = 0; i < opr_sz / sizeof(TYPE); ++i) { \
+ d[i] += n[i] < m[i] ? m[i] - n[i] : n[i] - m[i]; \
+ } \
+ clear_tail(d, opr_sz, simd_maxsz(desc)); \
+}
+
+DO_ABA(gvec_saba_b, int8_t)
+DO_ABA(gvec_saba_h, int16_t)
+DO_ABA(gvec_saba_s, int32_t)
+DO_ABA(gvec_saba_d, int64_t)
+
+DO_ABA(gvec_uaba_b, uint8_t)
+DO_ABA(gvec_uaba_h, uint16_t)
+DO_ABA(gvec_uaba_s, uint32_t)
+DO_ABA(gvec_uaba_d, uint64_t)
+
+#undef DO_ABA
#define float32_three make_float32(0x40400000)
#define float32_one_point_five make_float32(0x3fc00000)
-float32 HELPER(recps_f32)(float32 a, float32 b, CPUARMState *env)
+float32 HELPER(recps_f32)(CPUARMState *env, float32 a, float32 b)
{
float_status *s = &env->vfp.standard_fp_status;
if ((float32_is_infinity(a) && float32_is_zero_or_denormal(b)) ||
return float32_sub(float32_two, float32_mul(a, b, s), s);
}
-float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUARMState *env)
+float32 HELPER(rsqrts_f32)(CPUARMState *env, float32 a, float32 b)
{
float_status *s = &env->vfp.standard_fp_status;
float32 product;
return make_float64(val);
}
-uint32_t HELPER(recpe_u32)(uint32_t a, void *fpstp)
+uint32_t HELPER(recpe_u32)(uint32_t a)
{
- /* float_status *s = fpstp; */
int input, estimate;
if ((a & 0x80000000) == 0) {
return deposit32(0, (32 - 9), 9, estimate);
}
-uint32_t HELPER(rsqrte_u32)(uint32_t a, void *fpstp)
+uint32_t HELPER(rsqrte_u32)(uint32_t a)
{
int estimate;
cpu->apic_state = DEVICE(object_new_with_class(apic_class));
object_property_add_child(OBJECT(cpu), "lapic",
- OBJECT(cpu->apic_state), &error_abort);
+ OBJECT(cpu->apic_state));
object_unref(OBJECT(cpu->apic_state));
qdev_prop_set_uint32(cpu->apic_state, "id", cpu->apic_id);
}
}
-static void x86_cpu_unrealizefn(DeviceState *dev, Error **errp)
+static void x86_cpu_unrealizefn(DeviceState *dev)
{
X86CPU *cpu = X86_CPU(dev);
X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
- Error *local_err = NULL;
#ifndef CONFIG_USER_ONLY
cpu_remove_sync(CPU(dev));
cpu->apic_state = NULL;
}
- xcc->parent_unrealize(dev, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
+ xcc->parent_unrealize(dev);
}
typedef struct BitProperty {
object_property_add(OBJECT(cpu), prop_name, "bool",
x86_cpu_get_bit_prop,
x86_cpu_set_bit_prop,
- x86_cpu_release_bit_prop, fp, &error_abort);
+ x86_cpu_release_bit_prop, fp);
}
}
object_property_add(obj, "family", "int",
x86_cpuid_version_get_family,
- x86_cpuid_version_set_family, NULL, NULL, NULL);
+ x86_cpuid_version_set_family, NULL, NULL);
object_property_add(obj, "model", "int",
x86_cpuid_version_get_model,
- x86_cpuid_version_set_model, NULL, NULL, NULL);
+ x86_cpuid_version_set_model, NULL, NULL);
object_property_add(obj, "stepping", "int",
x86_cpuid_version_get_stepping,
- x86_cpuid_version_set_stepping, NULL, NULL, NULL);
+ x86_cpuid_version_set_stepping, NULL, NULL);
object_property_add_str(obj, "vendor",
x86_cpuid_get_vendor,
- x86_cpuid_set_vendor, NULL);
+ x86_cpuid_set_vendor);
object_property_add_str(obj, "model-id",
x86_cpuid_get_model_id,
- x86_cpuid_set_model_id, NULL);
+ x86_cpuid_set_model_id);
object_property_add(obj, "tsc-frequency", "int",
x86_cpuid_get_tsc_freq,
- x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
+ x86_cpuid_set_tsc_freq, NULL, NULL);
object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
x86_cpu_get_feature_words,
- NULL, NULL, (void *)env->features, NULL);
+ NULL, NULL, (void *)env->features);
object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo",
x86_cpu_get_feature_words,
- NULL, NULL, (void *)cpu->filtered_features, NULL);
+ NULL, NULL, (void *)cpu->filtered_features);
/*
* The "unavailable-features" property has the same semantics as
* CpuDefinitionInfo.unavailable-features on the "query-cpu-definitions"
*/
object_property_add(obj, "unavailable-features", "strList",
x86_cpu_get_unavailable_features,
- NULL, NULL, NULL, &error_abort);
+ NULL, NULL, NULL);
object_property_add(obj, "crash-information", "GuestPanicInformation",
- x86_cpu_get_crash_info_qom, NULL, NULL, NULL, NULL);
+ x86_cpu_get_crash_info_qom, NULL, NULL, NULL);
for (w = 0; w < FEATURE_WORDS; w++) {
int bitnr;
}
}
- object_property_add_alias(obj, "sse3", obj, "pni", &error_abort);
- object_property_add_alias(obj, "pclmuldq", obj, "pclmulqdq", &error_abort);
- object_property_add_alias(obj, "sse4-1", obj, "sse4.1", &error_abort);
- object_property_add_alias(obj, "sse4-2", obj, "sse4.2", &error_abort);
- object_property_add_alias(obj, "xd", obj, "nx", &error_abort);
- object_property_add_alias(obj, "ffxsr", obj, "fxsr-opt", &error_abort);
- object_property_add_alias(obj, "i64", obj, "lm", &error_abort);
-
- object_property_add_alias(obj, "ds_cpl", obj, "ds-cpl", &error_abort);
- object_property_add_alias(obj, "tsc_adjust", obj, "tsc-adjust", &error_abort);
- object_property_add_alias(obj, "fxsr_opt", obj, "fxsr-opt", &error_abort);
- object_property_add_alias(obj, "lahf_lm", obj, "lahf-lm", &error_abort);
- object_property_add_alias(obj, "cmp_legacy", obj, "cmp-legacy", &error_abort);
- object_property_add_alias(obj, "nodeid_msr", obj, "nodeid-msr", &error_abort);
- object_property_add_alias(obj, "perfctr_core", obj, "perfctr-core", &error_abort);
- object_property_add_alias(obj, "perfctr_nb", obj, "perfctr-nb", &error_abort);
- object_property_add_alias(obj, "kvm_nopiodelay", obj, "kvm-nopiodelay", &error_abort);
- object_property_add_alias(obj, "kvm_mmu", obj, "kvm-mmu", &error_abort);
- object_property_add_alias(obj, "kvm_asyncpf", obj, "kvm-asyncpf", &error_abort);
- object_property_add_alias(obj, "kvm_steal_time", obj, "kvm-steal-time", &error_abort);
- object_property_add_alias(obj, "kvm_pv_eoi", obj, "kvm-pv-eoi", &error_abort);
- object_property_add_alias(obj, "kvm_pv_unhalt", obj, "kvm-pv-unhalt", &error_abort);
- object_property_add_alias(obj, "kvm_poll_control", obj, "kvm-poll-control",
- &error_abort);
- object_property_add_alias(obj, "svm_lock", obj, "svm-lock", &error_abort);
- object_property_add_alias(obj, "nrip_save", obj, "nrip-save", &error_abort);
- object_property_add_alias(obj, "tsc_scale", obj, "tsc-scale", &error_abort);
- object_property_add_alias(obj, "vmcb_clean", obj, "vmcb-clean", &error_abort);
- object_property_add_alias(obj, "pause_filter", obj, "pause-filter", &error_abort);
- object_property_add_alias(obj, "sse4_1", obj, "sse4.1", &error_abort);
- object_property_add_alias(obj, "sse4_2", obj, "sse4.2", &error_abort);
+ object_property_add_alias(obj, "sse3", obj, "pni");
+ object_property_add_alias(obj, "pclmuldq", obj, "pclmulqdq");
+ object_property_add_alias(obj, "sse4-1", obj, "sse4.1");
+ object_property_add_alias(obj, "sse4-2", obj, "sse4.2");
+ object_property_add_alias(obj, "xd", obj, "nx");
+ object_property_add_alias(obj, "ffxsr", obj, "fxsr-opt");
+ object_property_add_alias(obj, "i64", obj, "lm");
+
+ object_property_add_alias(obj, "ds_cpl", obj, "ds-cpl");
+ object_property_add_alias(obj, "tsc_adjust", obj, "tsc-adjust");
+ object_property_add_alias(obj, "fxsr_opt", obj, "fxsr-opt");
+ object_property_add_alias(obj, "lahf_lm", obj, "lahf-lm");
+ object_property_add_alias(obj, "cmp_legacy", obj, "cmp-legacy");
+ object_property_add_alias(obj, "nodeid_msr", obj, "nodeid-msr");
+ object_property_add_alias(obj, "perfctr_core", obj, "perfctr-core");
+ object_property_add_alias(obj, "perfctr_nb", obj, "perfctr-nb");
+ object_property_add_alias(obj, "kvm_nopiodelay", obj, "kvm-nopiodelay");
+ object_property_add_alias(obj, "kvm_mmu", obj, "kvm-mmu");
+ object_property_add_alias(obj, "kvm_asyncpf", obj, "kvm-asyncpf");
+ object_property_add_alias(obj, "kvm_steal_time", obj, "kvm-steal-time");
+ object_property_add_alias(obj, "kvm_pv_eoi", obj, "kvm-pv-eoi");
+ object_property_add_alias(obj, "kvm_pv_unhalt", obj, "kvm-pv-unhalt");
+ object_property_add_alias(obj, "kvm_poll_control", obj, "kvm-poll-control");
+ object_property_add_alias(obj, "svm_lock", obj, "svm-lock");
+ object_property_add_alias(obj, "nrip_save", obj, "nrip-save");
+ object_property_add_alias(obj, "tsc_scale", obj, "tsc-scale");
+ object_property_add_alias(obj, "vmcb_clean", obj, "vmcb-clean");
+ object_property_add_alias(obj, "pause_filter", obj, "pause-filter");
+ object_property_add_alias(obj, "sse4_1", obj, "sse4.1");
+ object_property_add_alias(obj, "sse4_2", obj, "sse4.2");
if (xcc->model) {
x86_cpu_load_model(cpu, xcc->model, &error_abort);
/* The x86 has a strong memory model with some store-after-load re-ordering */
#define TCG_GUEST_DEFAULT_MO (TCG_MO_ALL & ~TCG_MO_ST_LD)
+#define KVM_HAVE_MCE_INJECTION 1
+
/* Maximum instruction code size */
#define TARGET_MAX_INSN_SIZE 16
#include "sysemu/sysemu.h"
#include "sysemu/hw_accel.h"
#include "sysemu/kvm_int.h"
-#include "sysemu/reset.h"
#include "sysemu/runstate.h"
#include "kvm_i386.h"
#include "hyperv.h"
}
}
-
-typedef struct HWPoisonPage {
- ram_addr_t ram_addr;
- QLIST_ENTRY(HWPoisonPage) list;
-} HWPoisonPage;
-
-static QLIST_HEAD(, HWPoisonPage) hwpoison_page_list =
- QLIST_HEAD_INITIALIZER(hwpoison_page_list);
-
-static void kvm_unpoison_all(void *param)
-{
- HWPoisonPage *page, *next_page;
-
- QLIST_FOREACH_SAFE(page, &hwpoison_page_list, list, next_page) {
- QLIST_REMOVE(page, list);
- qemu_ram_remap(page->ram_addr, TARGET_PAGE_SIZE);
- g_free(page);
- }
-}
-
-static void kvm_hwpoison_page_add(ram_addr_t ram_addr)
-{
- HWPoisonPage *page;
-
- QLIST_FOREACH(page, &hwpoison_page_list, list) {
- if (page->ram_addr == ram_addr) {
- return;
- }
- }
- page = g_new(HWPoisonPage, 1);
- page->ram_addr = ram_addr;
- QLIST_INSERT_HEAD(&hwpoison_page_list, page, list);
-}
-
static int kvm_get_mce_cap_supported(KVMState *s, uint64_t *mce_cap,
int *max_banks)
{
fprintf(stderr, "e820_add_entry() table is full\n");
return ret;
}
- qemu_register_reset(kvm_unpoison_all, NULL);
shadow_mem = object_property_get_int(OBJECT(s), "kvm-shadow-mem", &error_abort);
if (shadow_mem != -1) {
{
object_class_property_add_str(oc, "sev-device",
qsev_guest_get_sev_device,
- qsev_guest_set_sev_device,
- NULL);
+ qsev_guest_set_sev_device);
object_class_property_set_description(oc, "sev-device",
- "SEV device to use", NULL);
+ "SEV device to use");
object_class_property_add_str(oc, "dh-cert-file",
qsev_guest_get_dh_cert_file,
- qsev_guest_set_dh_cert_file,
- NULL);
+ qsev_guest_set_dh_cert_file);
object_class_property_set_description(oc, "dh-cert-file",
- "guest owners DH certificate (encoded with base64)", NULL);
+ "guest owners DH certificate (encoded with base64)");
object_class_property_add_str(oc, "session-file",
qsev_guest_get_session_file,
- qsev_guest_set_session_file,
- NULL);
+ qsev_guest_set_session_file);
object_class_property_set_description(oc, "session-file",
- "guest owners session parameters (encoded with base64)", NULL);
+ "guest owners session parameters (encoded with base64)");
}
static void
sev->sev_device = g_strdup(DEFAULT_SEV_DEVICE);
sev->policy = DEFAULT_GUEST_POLICY;
object_property_add_uint32_ptr(obj, "policy", &sev->policy,
- OBJ_PROP_FLAG_READWRITE, NULL);
+ OBJ_PROP_FLAG_READWRITE);
object_property_add_uint32_ptr(obj, "handle", &sev->handle,
- OBJ_PROP_FLAG_READWRITE, NULL);
+ OBJ_PROP_FLAG_READWRITE);
object_property_add_uint32_ptr(obj, "cbitpos", &sev->cbitpos,
- OBJ_PROP_FLAG_READWRITE, NULL);
+ OBJ_PROP_FLAG_READWRITE);
object_property_add_uint32_ptr(obj, "reduced-phys-bits",
&sev->reduced_phys_bits,
- OBJ_PROP_FLAG_READWRITE, NULL);
+ OBJ_PROP_FLAG_READWRITE);
}
/* sev guest info */
#endif
dc->vmsd = &vmstate_mb_cpu;
device_class_set_props(dc, mb_properties);
- cc->gdb_num_core_regs = 32 + 5;
+ cc->gdb_num_core_regs = 32 + 27;
cc->disas_set_info = mb_disas_set_info;
cc->tcg_initialize = mb_tcg_init;
{
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
CPUMBState *env = &cpu->env;
+ /*
+ * GDB expects SREGs in the following order:
+ * PC, MSR, EAR, ESR, FSR, BTR, EDR, PID, ZPR, TLBX, TLBSX, TLBLO, TLBHI.
+ * They aren't stored in this order, so make a map.
+ * PID, ZPR, TLBx, TLBsx, TLBLO, and TLBHI aren't modeled, so we don't
+ * map them to anything and return a value of 0 instead.
+ */
+ static const uint8_t sreg_map[6] = {
+ SR_PC,
+ SR_MSR,
+ SR_EAR,
+ SR_ESR,
+ SR_FSR,
+ SR_BTR
+ };
+ /*
+ * GDB expects registers to be reported in this order:
+ * R0-R31
+ * PC-BTR
+ * PVR0-PVR11
+ * EDR-TLBHI
+ * SLR-SHR
+ */
if (n < 32) {
return gdb_get_reg32(mem_buf, env->regs[n]);
} else {
- return gdb_get_reg32(mem_buf, env->sregs[n - 32]);
+ n -= 32;
+ switch (n) {
+ case 0 ... 5:
+ return gdb_get_reg32(mem_buf, env->sregs[sreg_map[n]]);
+ /* PVR12 is intentionally skipped */
+ case 6 ... 17:
+ n -= 6;
+ return gdb_get_reg32(mem_buf, env->pvr.regs[n]);
+ case 18:
+ return gdb_get_reg32(mem_buf, env->sregs[SR_EDR]);
+ /* Other SRegs aren't modeled, so report a value of 0 */
+ case 19 ... 24:
+ return gdb_get_reg32(mem_buf, 0);
+ case 25:
+ return gdb_get_reg32(mem_buf, env->slr);
+ case 26:
+ return gdb_get_reg32(mem_buf, env->shr);
+ default:
+ return 0;
+ }
}
- return 0;
}
int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
CPUMBState *env = &cpu->env;
uint32_t tmp;
+ /*
+ * GDB expects SREGs in the following order:
+ * PC, MSR, EAR, ESR, FSR, BTR, EDR, PID, ZPR, TLBX, TLBSX, TLBLO, TLBHI.
+ * They aren't stored in this order, so make a map.
+ * PID, ZPR, TLBx, TLBsx, TLBLO, and TLBHI aren't modeled, so we don't
+ * map them to anything.
+ */
+ static const uint8_t sreg_map[6] = {
+ SR_PC,
+ SR_MSR,
+ SR_EAR,
+ SR_ESR,
+ SR_FSR,
+ SR_BTR
+ };
+
if (n > cc->gdb_num_core_regs) {
return 0;
}
tmp = ldl_p(mem_buf);
+ /*
+ * GDB expects registers to be reported in this order:
+ * R0-R31
+ * PC-BTR
+ * PVR0-PVR11
+ * EDR-TLBHI
+ * SLR-SHR
+ */
if (n < 32) {
env->regs[n] = tmp;
} else {
- env->sregs[n - 32] = tmp;
+ n -= 32;
+ switch (n) {
+ case 0 ... 5:
+ env->sregs[sreg_map[n]] = tmp;
+ break;
+ /* PVR12 is intentionally skipped */
+ case 6 ... 17:
+ n -= 6;
+ env->pvr.regs[n] = tmp;
+ break;
+ /* Only EDR is modeled in these indeces, so ignore the rest */
+ case 18:
+ env->sregs[SR_EDR] = tmp;
+ break;
+ case 25:
+ env->slr = tmp;
+ break;
+ case 26:
+ env->shr = tmp;
+ break;
+ }
}
return 4;
}
case SR_ESR:
case SR_FSR:
case SR_BTR:
+ case SR_EDR:
tcg_gen_extrl_i64_i32(cpu_R[dc->rd], cpu_SR[sr]);
break;
case 0x800:
tcg_gen_movi_i64(cpu_SR[SR_ESR], ESR_EC_FPU);
t_gen_raise_exception(dc, EXCP_HW_EXCP);
}
- return (dc->cpu->cfg.use_fpu == 2) ? 0 : PVR2_USE_FPU2_MASK;
+ return (dc->cpu->cfg.use_fpu == 2) ? PVR2_USE_FPU2_MASK : 0;
}
static void dec_fpu(DisasContext *dc)
qemu_fprintf(f, "IN: PC=%" PRIx64 " %s\n",
env->sregs[SR_PC], lookup_symbol(env->sregs[SR_PC]));
qemu_fprintf(f, "rmsr=%" PRIx64 " resr=%" PRIx64 " rear=%" PRIx64 " "
- "debug=%x imm=%x iflags=%x fsr=%" PRIx64 "\n",
+ "debug=%x imm=%x iflags=%x fsr=%" PRIx64 " "
+ "rbtr=%" PRIx64 "\n",
env->sregs[SR_MSR], env->sregs[SR_ESR], env->sregs[SR_EAR],
- env->debug, env->imm, env->iflags, env->sregs[SR_FSR]);
+ env->debug, env->imm, env->iflags, env->sregs[SR_FSR],
+ env->sregs[SR_BTR]);
qemu_fprintf(f, "btaken=%d btarget=%" PRIx64 " mode=%s(saved=%s) "
"eip=%d ie=%d\n",
env->btaken, env->btarget,
(env->sregs[SR_MSR] & MSR_UMS) ? "user" : "kernel",
(bool)(env->sregs[SR_MSR] & MSR_EIP),
(bool)(env->sregs[SR_MSR] & MSR_IE));
+ for (i = 0; i < 12; i++) {
+ qemu_fprintf(f, "rpvr%2.2d=%8.8x ", i, env->pvr.regs[i]);
+ if ((i + 1) % 4 == 0) {
+ qemu_fprintf(f, "\n");
+ }
+ }
+ /* Registers that aren't modeled are reported as 0 */
+ qemu_fprintf(f, "redr=%" PRIx64 " rpid=0 rzpr=0 rtlbx=0 rtlbsx=0 "
+ "rtlblo=0 rtlbhi=0\n", env->sregs[SR_EDR]);
+ qemu_fprintf(f, "slr=%x shr=%x\n", env->slr, env->shr);
for (i = 0; i < 32; i++) {
qemu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
if ((i + 1) % 4 == 0)
}
void ppc_compat_add_property(Object *obj, const char *name,
- uint32_t *compat_pvr, const char *basedesc,
- Error **errp)
+ uint32_t *compat_pvr, const char *basedesc)
{
- Error *local_err = NULL;
gchar *namesv[ARRAY_SIZE(compat_table) + 1];
gchar *names, *desc;
int i;
object_property_add(obj, name, "string",
ppc_compat_prop_get, ppc_compat_prop_set, NULL,
- compat_pvr, &local_err);
- if (local_err) {
- goto out;
- }
+ compat_pvr);
for (i = 0; i < ARRAY_SIZE(compat_table); i++) {
/*
names = g_strjoinv(", ", namesv);
desc = g_strdup_printf("%s. Valid values are %s.", basedesc, names);
- object_property_set_description(obj, name, desc, &local_err);
+ object_property_set_description(obj, name, desc);
g_free(names);
g_free(desc);
-
-out:
- error_propagate(errp, local_err);
}
#endif
int ppc_compat_max_vthreads(PowerPCCPU *cpu);
void ppc_compat_add_property(Object *obj, const char *name,
- uint32_t *compat_pvr, const char *basedesc,
- Error **errp);
+ uint32_t *compat_pvr, const char *basedesc);
#endif /* defined(TARGET_PPC64) */
typedef CPUPPCState CPUArchState;
if (((end - base) >> TARGET_PAGE_BITS) > 1024) {
/* Flushing 1024 4K pages is slower than a complete flush */
LOG_BATS("Flush all BATs\n");
- tlb_flush(CPU(cs));
+ tlb_flush(cs);
LOG_BATS("Flush done\n");
return;
}
cpu_exec_unrealizefn(cs);
}
-static void ppc_cpu_unrealize(DeviceState *dev, Error **errp)
+static void ppc_cpu_unrealize(DeviceState *dev)
{
PowerPCCPU *cpu = POWERPC_CPU(dev);
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
- Error *local_err = NULL;
opc_handler_t **table, **table_2;
int i, j, k;
- pcc->parent_unrealize(dev, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
+ pcc->parent_unrealize(dev);
for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) {
if (cpu->opcodes[i] == &invalid_handler) {
cs->halted = 1;
cs->exception_index = EXCP_HLT;
object_property_add(obj, "crash-information", "GuestPanicInformation",
- s390_cpu_get_crash_info_qom, NULL, NULL, NULL, NULL);
+ s390_cpu_get_crash_info_qom, NULL, NULL, NULL);
s390_cpu_model_register_props(obj);
#if !defined(CONFIG_USER_ONLY)
cpu->env.tod_timer =
DEF_FEAT(PCC_CMAC_TDEA, "pcc-cmac-etdea-192", PCC, 11, "PCC Compute-Last-Block-CMAC-Using-EncryptedTDEA-192")
DEF_FEAT(PCC_CMAC_AES_128, "pcc-cmac-aes-128", PCC, 18, "PCC Compute-Last-Block-CMAC-Using-AES-128")
DEF_FEAT(PCC_CMAC_AES_192, "pcc-cmac-aes-192", PCC, 19, "PCC Compute-Last-Block-CMAC-Using-AES-192")
-DEF_FEAT(PCC_CMAC_AES_256, "pcc-cmac-eaes-256", PCC, 20, "PCC Compute-Last-Block-CMAC-Using-AES-256")
+DEF_FEAT(PCC_CMAC_AES_256, "pcc-cmac-aes-256", PCC, 20, "PCC Compute-Last-Block-CMAC-Using-AES-256")
DEF_FEAT(PCC_CMAC_EAES_128, "pcc-cmac-eaes-128", PCC, 26, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-128")
DEF_FEAT(PCC_CMAC_EAES_192, "pcc-cmac-eaes-192", PCC, 27, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-192")
DEF_FEAT(PCC_CMAC_EAES_256, "pcc-cmac-eaes-256", PCC, 28, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-256")
for (feat = 0; feat < S390_FEAT_MAX; feat++) {
const S390FeatDef *def = s390_feat_def(feat);
object_property_add(obj, def->name, "bool", get_feature,
- set_feature, NULL, (void *) feat, NULL);
- object_property_set_description(obj, def->name, def->desc , NULL);
+ set_feature, NULL, (void *) feat);
+ object_property_set_description(obj, def->name, def->desc);
}
for (group = 0; group < S390_FEAT_GROUP_MAX; group++) {
const S390FeatGroupDef *def = s390_feat_group_def(group);
object_property_add(obj, def->name, "bool", get_feature_group,
- set_feature_group, NULL, (void *) group, NULL);
- object_property_set_description(obj, def->name, def->desc , NULL);
+ set_feature_group, NULL, (void *) group);
+ object_property_set_description(obj, def->name, def->desc);
}
}
void s390_cpu_model_class_register_props(ObjectClass *oc)
{
object_class_property_add_bool(oc, "migration-safe", get_is_migration_safe,
- NULL, NULL);
+ NULL);
object_class_property_add_bool(oc, "static", get_is_static,
- NULL, NULL);
- object_class_property_add_str(oc, "description", get_description, NULL,
- NULL);
+ NULL);
+ object_class_property_add_str(oc, "description", get_description, NULL);
}
#ifdef CONFIG_KVM
static void dummy_init(Object *obj)
{
- Error *err = NULL;
-
object_property_add_bool(obj, "bv",
dummy_get_bv,
- dummy_set_bv,
- &err);
- error_free_or_abort(&err);
+ dummy_set_bv);
}
static void dummy_class_init(ObjectClass *cls, void *data)
{
- object_class_property_add_bool(cls, "bv",
- dummy_get_bv,
- dummy_set_bv,
- NULL);
object_class_property_add_str(cls, "sv",
dummy_get_sv,
- dummy_set_sv,
- NULL);
+ dummy_set_sv);
object_class_property_add_enum(cls, "av",
"DummyAnimal",
&dummy_animal_map,
dummy_get_av,
- dummy_set_av,
- NULL);
+ dummy_set_av);
}
DummyBus *bus = DUMMY_BUS(object_new(TYPE_DUMMY_BUS));
DummyBackend *backend = DUMMY_BACKEND(object_new(TYPE_DUMMY_BACKEND));
- object_property_add_child(obj, "bus", OBJECT(bus), NULL);
+ object_property_add_child(obj, "bus", OBJECT(bus));
dev->bus = bus;
- object_property_add_child(OBJECT(bus), "backend", OBJECT(backend), NULL);
+ object_property_add_child(OBJECT(bus), "backend", OBJECT(backend));
bus->backend = backend;
object_property_add_link(obj, "backend", TYPE_DUMMY_BACKEND,
- (Object **)&bus->backend, NULL, 0, NULL);
+ (Object **)&bus->backend, NULL, 0);
}
static void dummy_dev_unparent(Object *obj)
static void dummy_bus_unparent(Object *obj)
{
DummyBus *bus = DUMMY_BUS(obj);
- object_property_del(obj->parent, "backend", NULL);
+ object_property_del(obj->parent, "backend");
object_unparent(OBJECT(bus->backend));
}
}
-static void test_dummy_prop_iterator(ObjectPropertyIterator *iter)
+static void test_dummy_prop_iterator(ObjectPropertyIterator *iter,
+ const char *expected[], int n)
{
- bool seenbv = false, seensv = false, seenav = false, seentype = false;
ObjectProperty *prop;
+ int i;
while ((prop = object_property_iter_next(iter))) {
- if (!seenbv && g_str_equal(prop->name, "bv")) {
- seenbv = true;
- } else if (!seensv && g_str_equal(prop->name, "sv")) {
- seensv = true;
- } else if (!seenav && g_str_equal(prop->name, "av")) {
- seenav = true;
- } else if (!seentype && g_str_equal(prop->name, "type")) {
- /* This prop comes from the base Object class */
- seentype = true;
- } else {
- g_printerr("Found prop '%s'\n", prop->name);
- g_assert_not_reached();
+ for (i = 0; i < n; i++) {
+ if (!g_strcmp0(prop->name, expected[i])) {
+ break;
+ }
}
+ g_assert(i < n);
+ expected[i] = NULL;
+ }
+
+ for (i = 0; i < n; i++) {
+ g_assert(!expected[i]);
}
- g_assert(seenbv);
- g_assert(seenav);
- g_assert(seensv);
- g_assert(seentype);
}
static void test_dummy_iterator(void)
{
+ const char *expected[] = {
+ "type", /* inherited from TYPE_OBJECT */
+ "sv", "av", /* class properties */
+ "bv"}; /* instance property */
Object *parent = object_get_objects_root();
DummyObject *dobj = DUMMY_OBJECT(
object_new_with_props(TYPE_DUMMY,
ObjectPropertyIterator iter;
object_property_iter_init(&iter, OBJECT(dobj));
- test_dummy_prop_iterator(&iter);
+ test_dummy_prop_iterator(&iter, expected, ARRAY_SIZE(expected));
object_unparent(OBJECT(dobj));
}
static void test_dummy_class_iterator(void)
{
+ const char *expected[] = { "type", "av", "sv" };
ObjectPropertyIterator iter;
ObjectClass *klass = object_class_by_name(TYPE_DUMMY);
object_class_property_iter_init(&iter, klass);
- test_dummy_prop_iterator(&iter);
+ test_dummy_prop_iterator(&iter, expected, ARRAY_SIZE(expected));
}
static void test_dummy_delchild(void)
* /cont1/obj2 (obj2a)
* /obj2 (obj2b)
*/
- object_property_add_child(cont1, "obj1", obj1, &error_abort);
+ object_property_add_child(cont1, "obj1", obj1);
object_unref(obj1);
- object_property_add_child(cont1, "obj2", obj2a, &error_abort);
+ object_property_add_child(cont1, "obj2", obj2a);
object_unref(obj2a);
- object_property_add_child(root, "obj2", obj2b, &error_abort);
+ object_property_add_child(root, "obj2", obj2b);
object_unref(obj2b);
ambiguous = false;
compatible_features []
autoclear_features []
refcount_order 4
-header_length 104
+header_length 112
Header extension:
magic 0x6803f857
-length 288
+length 336
data <binary>
Header extension:
compatible_features []
autoclear_features []
refcount_order 4
-header_length 104
+header_length 112
Header extension:
magic 0x6803f857
-length 288
+length 336
data <binary>
Header extension:
magic 0x514649fb
version 3
-backing_file_offset 0x1d8
+backing_file_offset 0x210
backing_file_size 0x17
cluster_bits 16
size 67108864
compatible_features []
autoclear_features []
refcount_order 4
-header_length 104
+header_length 112
Header extension:
magic 0xe2792aca
Header extension:
magic 0x6803f857
-length 288
+length 336
data <binary>
Header extension:
autoclear_features [63]
Header extension:
magic 0x6803f857
-length 288
+length 336
data <binary>
autoclear_features []
Header extension:
magic 0x6803f857
-length 288
+length 336
data <binary>
*** done
== 1. Traditional size parameter ==
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024b
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1k
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1K
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1G
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1T
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0b
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5k
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5K
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5G
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5T
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
== 2. Specifying size via -o ==
qemu-img create -f qcow2 -o size=1024 TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o size=1024b TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o size=1k TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o size=1K TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o size=1M TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o size=1G TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o size=1T TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o size=1024.0 TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o size=1024.0b TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o size=1.5k TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o size=1.5K TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o size=1.5M TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o size=1.5G TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o size=1.5T TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
== 3. Invalid sizes ==
== Check correct interpretation of suffixes for cluster size ==
qemu-img create -f qcow2 -o cluster_size=1024 TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o cluster_size=1024b TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o cluster_size=1k TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o cluster_size=1K TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o cluster_size=1M TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1048576 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1048576 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o cluster_size=1024.0 TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o cluster_size=1024.0b TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o cluster_size=0.5k TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=512 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=512 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o cluster_size=0.5K TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=512 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=512 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o cluster_size=0.5M TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=524288 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=524288 lazy_refcounts=off refcount_bits=16 compression_type=zlib
== Check compat level option ==
qemu-img create -f qcow2 -o compat=0.10 TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o compat=1.1 TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o compat=0.42 TEST_DIR/t.qcow2 64M
qemu-img: TEST_DIR/t.qcow2: Invalid parameter '0.42'
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.42 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.42 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o compat=foobar TEST_DIR/t.qcow2 64M
qemu-img: TEST_DIR/t.qcow2: Invalid parameter 'foobar'
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=foobar cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=foobar cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
== Check preallocation option ==
qemu-img create -f qcow2 -o preallocation=off TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=off lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=off lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o preallocation=metadata TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=metadata lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=metadata lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M
qemu-img: TEST_DIR/t.qcow2: Invalid parameter '1234'
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=1234 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=1234 lazy_refcounts=off refcount_bits=16 compression_type=zlib
== Check encryption option ==
qemu-img create -f qcow2 -o encryption=off TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 --object secret,id=sec0,data=123456 -o encryption=on,encrypt.key-secret=sec0 TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=on encrypt.key-secret=sec0 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=on encrypt.key-secret=sec0 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
== Check lazy_refcounts option (only with v3) ==
qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=off TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=on TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=on refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=on refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=off TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=on TEST_DIR/t.qcow2 64M
qemu-img: TEST_DIR/t.qcow2: Lazy refcounts only supported with compatibility level 1.1 and above (use version=v3 or greater)
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=on refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=on refcount_bits=16 compression_type=zlib
*** done
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: true
compatible_features [0]
autoclear_features []
refcount_order 4
-header_length 104
+header_length 112
Header extension:
magic 0x6803f857
-length 288
+length 336
data <binary>
magic 0x514649fb
compatible_features [0]
autoclear_features []
refcount_order 4
-header_length 104
+header_length 112
Header extension:
magic 0x6803f857
-length 288
+length 336
data <binary>
magic 0x514649fb
compatible_features [0]
autoclear_features []
refcount_order 4
-header_length 104
+header_length 112
Header extension:
magic 0x6803f857
-length 288
+length 336
data <binary>
ERROR cluster 5 refcount=0 reference=1
compatible_features [42]
autoclear_features [42]
refcount_order 4
-header_length 104
+header_length 112
Header extension:
magic 0x6803f857
-length 288
+length 336
data <binary>
magic 0x514649fb
compatible_features [0]
autoclear_features []
refcount_order 4
-header_length 104
+header_length 112
Header extension:
magic 0x6803f857
-length 288
+length 336
data <binary>
read 65536/65536 bytes at offset 44040192
compatible_features [0]
autoclear_features []
refcount_order 4
-header_length 104
+header_length 112
Header extension:
magic 0x6803f857
-length 288
+length 336
data <binary>
ERROR cluster 5 refcount=0 reference=1
compatible_features []
autoclear_features []
refcount_order 4
-header_length 104
+header_length 112
Header extension:
magic 0x6803f857
-length 288
+length 336
data <binary>
read 131072/131072 bytes at offset 0
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
refcount bits: 16
data file: TEST_DIR/t.IMGFMT.data
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
refcount bits: 16
data file: foo
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
refcount bits: 16
data file raw: false
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
refcount bits: 16
data file: TEST_DIR/t.IMGFMT.data
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
refcount bits: 16
data file: TEST_DIR/t.IMGFMT.data
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
refcount bits: 16
data file: TEST_DIR/t.IMGFMT.data
class TestQCow2(TestQemuImgInfo):
'''Testing a qcow2 version 2 image'''
img_options = 'compat=0.10'
- json_compare = { 'compat': '0.10', 'refcount-bits': 16 }
- human_compare = [ 'compat: 0.10', 'refcount bits: 16' ]
+ json_compare = { 'compat': '0.10', 'refcount-bits': 16,
+ 'compression-type': 'zlib' }
+ human_compare = [ 'compat: 0.10', 'compression type: zlib',
+ 'refcount bits: 16' ]
class TestQCow3NotLazy(TestQemuImgInfo):
'''Testing a qcow2 version 3 image with lazy refcounts disabled'''
img_options = 'compat=1.1,lazy_refcounts=off'
json_compare = { 'compat': '1.1', 'lazy-refcounts': False,
- 'refcount-bits': 16, 'corrupt': False }
- human_compare = [ 'compat: 1.1', 'lazy refcounts: false',
- 'refcount bits: 16', 'corrupt: false' ]
+ 'refcount-bits': 16, 'corrupt': False,
+ 'compression-type': 'zlib' }
+ human_compare = [ 'compat: 1.1', 'compression type: zlib',
+ 'lazy refcounts: false', 'refcount bits: 16',
+ 'corrupt: false' ]
class TestQCow3Lazy(TestQemuImgInfo):
'''Testing a qcow2 version 3 image with lazy refcounts enabled'''
img_options = 'compat=1.1,lazy_refcounts=on'
json_compare = { 'compat': '1.1', 'lazy-refcounts': True,
- 'refcount-bits': 16, 'corrupt': False }
- human_compare = [ 'compat: 1.1', 'lazy refcounts: true',
- 'refcount bits: 16', 'corrupt: false' ]
+ 'refcount-bits': 16, 'corrupt': False,
+ 'compression-type': 'zlib' }
+ human_compare = [ 'compat: 1.1', 'compression type: zlib',
+ 'lazy refcounts: true', 'refcount bits: 16',
+ 'corrupt: false' ]
class TestQCow3NotLazyQMP(TestQMP):
'''Testing a qcow2 version 3 image with lazy refcounts disabled, opening
img_options = 'compat=1.1,lazy_refcounts=off'
qemu_options = 'lazy-refcounts=on'
compare = { 'compat': '1.1', 'lazy-refcounts': False,
- 'refcount-bits': 16, 'corrupt': False }
+ 'refcount-bits': 16, 'corrupt': False,
+ 'compression-type': 'zlib' }
class TestQCow3LazyQMP(TestQMP):
img_options = 'compat=1.1,lazy_refcounts=on'
qemu_options = 'lazy-refcounts=off'
compare = { 'compat': '1.1', 'lazy-refcounts': True,
- 'refcount-bits': 16, 'corrupt': False }
+ 'refcount-bits': 16, 'corrupt': False,
+ 'compression-type': 'zlib' }
TestImageInfoSpecific = None
TestQemuImgInfo = None
# - This is generally a test for compat=1.1 images
_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file 'compat=0.10'
-header_size=104
+header_size=112
offset_backing_file_offset=8
offset_backing_file_size=16
=== create: Options specified more than once ===
Testing: create -f foo -f qcow2 TEST_DIR/t.qcow2 128M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 128 MiB (134217728 bytes)
cluster_size: 65536
Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 128M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=4096 lazy_refcounts=on refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=4096 lazy_refcounts=on refcount_bits=16 compression_type=zlib
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 128 MiB (134217728 bytes)
cluster_size: 4096
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: true
refcount bits: 16
corrupt: false
Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 128M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=on refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=on refcount_bits=16 compression_type=zlib
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 128 MiB (134217728 bytes)
cluster_size: 8192
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: true
refcount bits: 16
corrupt: false
Testing: create -f qcow2 -o cluster_size=4k,cluster_size=8k TEST_DIR/t.qcow2 128M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=off refcount_bits=16 compression_type=zlib
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 128 MiB (134217728 bytes)
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
size=<size> - Virtual disk size
Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 128M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,help cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,help cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,? TEST_DIR/t.qcow2 128M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,? cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,? cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2, -o help TEST_DIR/t.qcow2 128M
qemu-img: Invalid option list: backing_file=TEST_DIR/t.qcow2,
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
=== convert: Options specified more than once ===
Testing: create -f qcow2 TEST_DIR/t.qcow2 128M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
Testing: convert -f foo -f qcow2 TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
image: TEST_DIR/t.IMGFMT.base
cluster_size: 4096
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: true
refcount bits: 16
corrupt: false
cluster_size: 8192
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: true
refcount bits: 16
corrupt: false
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: true
refcount bits: 16
corrupt: false
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: true
refcount bits: 16
corrupt: false
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
+ compression_type=<str> - Compression method used for image cluster compression
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
=== Create a single snapshot on virtio0 ===
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/1-snapshot-v0.IMGFMT', 'format': 'IMGFMT' } }
-Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2.1 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2.1 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
{"return": {}}
=== Invalid command - missing device and nodename ===
=== Create several transactional group snapshots ===
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/2-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/2-snapshot-v1.IMGFMT' } } ] } }
-Formatting 'TEST_DIR/2-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/1-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
-Formatting 'TEST_DIR/2-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2.2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/2-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/1-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
+Formatting 'TEST_DIR/2-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2.2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
{"return": {}}
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/3-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/3-snapshot-v1.IMGFMT' } } ] } }
-Formatting 'TEST_DIR/3-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
-Formatting 'TEST_DIR/3-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/3-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
+Formatting 'TEST_DIR/3-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
{"return": {}}
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/4-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/4-snapshot-v1.IMGFMT' } } ] } }
-Formatting 'TEST_DIR/4-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
-Formatting 'TEST_DIR/4-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/4-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
+Formatting 'TEST_DIR/4-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
{"return": {}}
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/5-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/5-snapshot-v1.IMGFMT' } } ] } }
-Formatting 'TEST_DIR/5-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
-Formatting 'TEST_DIR/5-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/5-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
+Formatting 'TEST_DIR/5-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
{"return": {}}
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/6-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/6-snapshot-v1.IMGFMT' } } ] } }
-Formatting 'TEST_DIR/6-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
-Formatting 'TEST_DIR/6-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/6-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
+Formatting 'TEST_DIR/6-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
{"return": {}}
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/7-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/7-snapshot-v1.IMGFMT' } } ] } }
-Formatting 'TEST_DIR/7-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
-Formatting 'TEST_DIR/7-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/7-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
+Formatting 'TEST_DIR/7-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
{"return": {}}
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/8-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/8-snapshot-v1.IMGFMT' } } ] } }
-Formatting 'TEST_DIR/8-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
-Formatting 'TEST_DIR/8-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/8-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
+Formatting 'TEST_DIR/8-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
{"return": {}}
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/9-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/9-snapshot-v1.IMGFMT' } } ] } }
-Formatting 'TEST_DIR/9-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
-Formatting 'TEST_DIR/9-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/9-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
+Formatting 'TEST_DIR/9-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
{"return": {}}
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/10-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/10-snapshot-v1.IMGFMT' } } ] } }
-Formatting 'TEST_DIR/10-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
-Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/10-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
+Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
{"return": {}}
=== Create a couple of snapshots using blockdev-snapshot ===
{ 'execute': 'qmp_capabilities' }
{"return": {}}
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/tmp.IMGFMT', 'format': 'IMGFMT' } }
-Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
{"return": {}}
=== Performing block-commit on active layer ===
=== Performing Live Snapshot 2 ===
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/tmp2.IMGFMT', 'format': 'IMGFMT' } }
-Formatting 'TEST_DIR/tmp2.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/tmp2.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
{"return": {}}
*** done
{'execute': 'blockdev-add', 'arguments': { 'node-name': 'node0', 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT', 'locking': 'on' } }
{"return": {}}
{'execute': 'blockdev-snapshot-sync', 'arguments': { 'node-name': 'node0', 'snapshot-file': 'TEST_DIR/t.IMGFMT.overlay', 'snapshot-node-name': 'node1' } }
-Formatting 'TEST_DIR/t.qcow2.overlay', fmt=qcow2 size=197120 backing_file=TEST_DIR/t.qcow2 backing_fmt=file cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2.overlay', fmt=qcow2 size=197120 backing_file=TEST_DIR/t.qcow2 backing_fmt=file cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
{"return": {}}
{'execute': 'blockdev-add', 'arguments': { 'node-name': 'node1', 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT', 'locking': 'on' } }
{"return": {}}
=== Creating backing chain ===
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'disk', 'snapshot-file': 'TEST_DIR/t.IMGFMT.mid', 'format': 'IMGFMT', 'mode': 'absolute-paths' } }
-Formatting 'TEST_DIR/t.qcow2.mid', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.base backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2.mid', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.base backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
{"return": {}}
{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io disk "write 0 4M"' } }
wrote 4194304/4194304 bytes at offset 0
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": ""}
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'disk', 'snapshot-file': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'absolute-paths' } }
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.mid backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.mid backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
{"return": {}}
=== Start commit job and exit qemu ===
{ 'execute': 'qmp_capabilities' }
{"return": {}}
{ 'execute': 'drive-mirror', 'arguments': { 'device': 'disk', 'target': 'TEST_DIR/t.IMGFMT.copy', 'format': 'IMGFMT', 'sync': 'full', 'speed': 65536 } }
-Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}}
{"return": {}}
{ 'execute': 'qmp_capabilities' }
{"return": {}}
{ 'execute': 'drive-backup', 'arguments': { 'device': 'disk', 'target': 'TEST_DIR/t.IMGFMT.copy', 'format': 'IMGFMT', 'sync': 'full', 'speed': 65536 } }
-Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "disk"}}
file format: IMGFMT
virtual size: 16 MiB (16777216 bytes)
Format specific information:
+ compression type: zlib
encrypt:
ivgen alg: plain64
hash alg: sha256
virtual size: 16 MiB (16777216 bytes)
backing file: TEST_DIR/t.IMGFMT.base
Format specific information:
+ compression type: zlib
encrypt:
ivgen alg: plain64
hash alg: sha256
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
cluster_size: 2097152
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: true
refcount bits: 1
corrupt: false
backing file format: IMGFMT
Format specific information:
compat: 0.10
+ compression type: zlib
refcount bits: 16
=== Successful image creation (encrypted) ===
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
refcount bits: 16
encrypt:
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
bitmaps:
[0]:
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
bitmaps:
[0]:
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
bitmaps:
[0]:
cluster_size: 65536
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
bitmaps:
[0]:
=== Create backing chain and start VM ===
-Formatting 'TEST_DIR/PID-t.qcow2.mid', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-t.qcow2.mid', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
-Formatting 'TEST_DIR/PID-t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
=== Start background read requests ===
=== Create images and start VM ===
-Formatting 'TEST_DIR/PID-src.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-src.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
-Formatting 'TEST_DIR/PID-dst.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-dst.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
wrote 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== Commit tests ==
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
-Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
wrote 2097152/2097152 bytes at offset 0
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
backing file: TEST_DIR/PID-base
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
=== Testing HMP commit (top -> mid) ===
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
-Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
wrote 2097152/2097152 bytes at offset 0
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
backing file: TEST_DIR/PID-base
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
=== Testing QMP active commit (top -> mid) ===
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
-Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
wrote 2097152/2097152 bytes at offset 0
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
backing file: TEST_DIR/PID-base
Format specific information:
compat: 1.1
+ compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
== Resize tests ==
=== preallocation=off ===
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=6442450944 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=6442450944 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=1073741824 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=1073741824 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
wrote 65536/65536 bytes at offset 5368709120
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{ "start": 1073741824, "length": 7516192768, "depth": 0, "zero": true, "data": false}]
=== preallocation=metadata ===
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=34359738368 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=34359738368 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=32212254720 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=32212254720 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
wrote 65536/65536 bytes at offset 33285996544
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{ "start": 34896609280, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2685075456}]
=== preallocation=falloc ===
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=10485760 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=10485760 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=5242880 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=5242880 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
wrote 65536/65536 bytes at offset 9437184
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{ "start": 5242880, "length": 10485760, "depth": 0, "zero": false, "data": true, "offset": 327680}]
=== preallocation=full ===
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=8388608 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=8388608 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
wrote 65536/65536 bytes at offset 11534336
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{ "start": 8388608, "length": 4194304, "depth": 0, "zero": false, "data": true, "offset": 327680}]
=== preallocation=off ===
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=259072 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=259072 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
wrote 65536/65536 bytes at offset 259072
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
=== preallocation=off ===
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=409600 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=409600 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
wrote 65536/65536 bytes at offset 344064
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
=== preallocation=off ===
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=524288 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=524288 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
wrote 65536/65536 bytes at offset 446464
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
=== Launch VM ===
Enabling migration QMP events on VM...
--- /dev/null
+#!/usr/bin/env bash
+#
+# Test case for an image using zstd compression
+#
+# Copyright (c) 2020 Virtuozzo International GmbH
+#
+# 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/>.
+#
+
+# creator
+owner=dplotnikov@virtuozzo.com
+
+seq="$(basename $0)"
+echo "QA output created by $seq"
+
+status=1 # failure is the default!
+
+# standard environment
+. ./common.rc
+. ./common.filter
+
+# This tests qocw2-specific low-level functionality
+_supported_fmt qcow2
+_supported_proto file
+_supported_os Linux
+_unsupported_imgopts 'compat=0.10' data_file
+
+COMPR_IMG="$TEST_IMG.compressed"
+RAND_FILE="$TEST_DIR/rand_data"
+
+_cleanup()
+{
+ _cleanup_test_img
+ _rm_test_img "$COMPR_IMG"
+ rm -f "$RAND_FILE"
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# for all the cases
+CLUSTER_SIZE=65536
+
+# Check if we can run this test.
+if IMGOPTS='compression_type=zstd' _make_test_img 64M |
+ grep "Invalid parameter 'zstd'"; then
+ _notrun "ZSTD is disabled"
+fi
+
+echo
+echo "=== Testing compression type incompatible bit setting for zlib ==="
+echo
+_make_test_img -o compression_type=zlib 64M
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+
+echo
+echo "=== Testing compression type incompatible bit setting for zstd ==="
+echo
+_make_test_img -o compression_type=zstd 64M
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+
+echo
+echo "=== Testing zlib with incompatible bit set ==="
+echo
+_make_test_img -o compression_type=zlib 64M
+$PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 3
+# to make sure the bit was actually set
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+
+if $QEMU_IMG info "$TEST_IMG" >/dev/null 2>&1 ; then
+ echo "Error: The image opened successfully. The image must not be opened."
+fi
+
+echo
+echo "=== Testing zstd with incompatible bit unset ==="
+echo
+_make_test_img -o compression_type=zstd 64M
+$PYTHON qcow2.py "$TEST_IMG" set-header incompatible_features 0
+# to make sure the bit was actually unset
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+
+if $QEMU_IMG info "$TEST_IMG" >/dev/null 2>&1 ; then
+ echo "Error: The image opened successfully. The image must not be opened."
+fi
+
+echo
+echo "=== Testing compression type values ==="
+echo
+# zlib=0
+_make_test_img -o compression_type=zlib 64M
+peek_file_be "$TEST_IMG" 104 1
+echo
+
+# zstd=1
+_make_test_img -o compression_type=zstd 64M
+peek_file_be "$TEST_IMG" 104 1
+echo
+
+echo
+echo "=== Testing simple reading and writing with zstd ==="
+echo
+_make_test_img -o compression_type=zstd 64M
+$QEMU_IO -c "write -c -P 0xAC 64K 64K " "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -P 0xAC 64K 64K " "$TEST_IMG" | _filter_qemu_io
+# read on the cluster boundaries
+$QEMU_IO -c "read -v 131070 8 " "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -v 65534 8" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "=== Testing adjacent clusters reading and writing with zstd ==="
+echo
+_make_test_img -o compression_type=zstd 64M
+$QEMU_IO -c "write -c -P 0xAB 0 64K " "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "write -c -P 0xAC 64K 64K " "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "write -c -P 0xAD 128K 64K " "$TEST_IMG" | _filter_qemu_io
+
+$QEMU_IO -c "read -P 0xAB 0 64k " "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -P 0xAC 64K 64k " "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -P 0xAD 128K 64k " "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "=== Testing incompressible cluster processing with zstd ==="
+echo
+# create a 2M image and fill it with 1M likely incompressible data
+# and 1M compressible data
+dd if=/dev/urandom of="$RAND_FILE" bs=1M count=1 seek=1
+QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS_NO_FMT" \
+$QEMU_IO -f raw -c "write -P 0xFA 0 1M" "$RAND_FILE" | _filter_qemu_io
+
+$QEMU_IMG convert -f raw -O $IMGFMT -c \
+-o "$(_optstr_add "$IMGOPTS" "compression_type=zlib")" "$RAND_FILE" \
+"$TEST_IMG" | _filter_qemu_io
+
+$QEMU_IMG convert -O $IMGFMT -c \
+-o "$(_optstr_add "$IMGOPTS" "compression_type=zstd")" "$TEST_IMG" \
+"$COMPR_IMG" | _filter_qemu_io
+
+$QEMU_IMG compare "$TEST_IMG" "$COMPR_IMG"
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
--- /dev/null
+QA output created by 287
+
+=== Testing compression type incompatible bit setting for zlib ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+incompatible_features []
+
+=== Testing compression type incompatible bit setting for zstd ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+incompatible_features [3]
+
+=== Testing zlib with incompatible bit set ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+incompatible_features [3]
+
+=== Testing zstd with incompatible bit unset ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+incompatible_features []
+
+=== Testing compression type values ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+ 0
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+ 1
+
+=== Testing simple reading and writing with zstd ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+wrote 65536/65536 bytes at offset 65536
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 65536/65536 bytes at offset 65536
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+0001fffe: ac ac 00 00 00 00 00 00 ........
+read 8/8 bytes at offset 131070
+8 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+0000fffe: 00 00 ac ac ac ac ac ac ........
+read 8/8 bytes at offset 65534
+8 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+=== Testing adjacent clusters reading and writing with zstd ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+wrote 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset 65536
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset 131072
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 65536/65536 bytes at offset 65536
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 65536/65536 bytes at offset 131072
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+=== Testing incompressible cluster processing with zstd ===
+
+1+0 records in
+1+0 records out
+wrote 1048576/1048576 bytes at offset 0
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Images are identical.
+*** done
-e "s# refcount_bits=[0-9]\\+##g" \
-e "s# key-secret=[a-zA-Z0-9]\\+##g" \
-e "s# iter-time=[0-9]\\+##g" \
- -e "s# force_size=\\(on\\|off\\)##g"
+ -e "s# force_size=\\(on\\|off\\)##g" \
+ -e "s# compression_type=[a-zA-Z0-9]\\+##g"
}
_filter_img_info()
283 auto quick
284 rw
286 rw quick
+287 auto quick
288 quick
289 rw quick
290 rw auto quick
static void dynamic_instance_init(Object *obj)
{
object_property_add(obj, "prop1", "uint32", prop1_accessor, prop1_accessor,
- NULL, NULL, NULL);
+ NULL, NULL);
object_property_add(obj, "prop2", "uint32", prop2_accessor, prop2_accessor,
- NULL, NULL, NULL);
+ NULL, NULL);
}
static void dynamic_class_init(ObjectClass *oc, void *data)
object_property_add_link(obj, "device", TYPE_DEVICE,
(Object **)&s->device,
object_property_allow_set_link,
- OBJ_PROP_LINK_STRONG,
- &error_abort);
+ OBJ_PROP_LINK_STRONG);
object_property_add_uint32_ptr(obj, "head", &s->head,
- OBJ_PROP_FLAG_READ, &error_abort);
+ OBJ_PROP_FLAG_READ);
if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE) &&
(console_type == GRAPHIC_CONSOLE))) {
* doesn't change any more */
name = g_strdup_printf("console[%d]", con->index);
object_property_add_child(container_get(object_get_root(), "/backend"),
- name, OBJECT(con), &error_abort);
+ name, OBJECT(con));
g_free(name);
}
object_property_add_str(obj, "name",
input_barrier_get_name,
- input_barrier_set_name, NULL);
+ input_barrier_set_name);
object_property_add_str(obj, "server",
input_barrier_get_server,
- input_barrier_set_server, NULL);
+ input_barrier_set_server);
object_property_add_str(obj, "port",
input_barrier_get_port,
- input_barrier_set_port, NULL);
+ input_barrier_set_port);
object_property_add_str(obj, "x-origin",
input_barrier_get_x_origin,
- input_barrier_set_x_origin, NULL);
+ input_barrier_set_x_origin);
object_property_add_str(obj, "y-origin",
input_barrier_get_y_origin,
- input_barrier_set_y_origin, NULL);
+ input_barrier_set_y_origin);
object_property_add_str(obj, "width",
input_barrier_get_width,
- input_barrier_set_width, NULL);
+ input_barrier_set_width);
object_property_add_str(obj, "height",
input_barrier_get_height,
- input_barrier_set_height, NULL);
+ input_barrier_set_height);
}
static void input_barrier_class_init(ObjectClass *oc, void *data)
{
object_property_add_str(obj, "evdev",
input_linux_get_evdev,
- input_linux_set_evdev, NULL);
+ input_linux_set_evdev);
object_property_add_bool(obj, "grab_all",
input_linux_get_grab_all,
- input_linux_set_grab_all, NULL);
+ input_linux_set_grab_all);
object_property_add_bool(obj, "repeat",
input_linux_get_repeat,
- input_linux_set_repeat, NULL);
+ input_linux_set_repeat);
object_property_add_enum(obj, "grab-toggle", "GrabToggleKeys",
&GrabToggleKeys_lookup,
input_linux_get_grab_toggle,
- input_linux_set_grab_toggle, NULL);
+ input_linux_set_grab_toggle);
}
static void input_linux_class_init(ObjectClass *oc, void *data)