diff options
162 files changed, 2084 insertions, 1175 deletions
diff --git a/.mailmap b/.mailmap index b8e08297c9..0756a0bf66 100644 --- a/.mailmap +++ b/.mailmap @@ -1,23 +1,29 @@ # This mailmap fixes up author names/addresses. +# +# If you are adding to this file consider if a similar change needs to +# be made to contrib/gitdm/aliases. They are not however completely +# analogous. .mailmap is concerned with fixing up damaged author +# fields where as the gitdm equivalent is more concerned with making +# sure multiple email addresses get mapped onto the same author. +# +# From man git-shortlog the forms are: +# +# Proper Name <commit@email.xx> +# <proper@email.xx> <commit@email.xx> +# Proper Name <proper@email.xx> <commit@email.xx> +# Proper Name <proper@email.xx> Commit Name <commit@email.xx> +# # The first section translates weird addresses from the original git import # into proper addresses so that they are counted properly by git shortlog. Andrzej Zaborowski <balrogg@gmail.com> balrog <balrog@c046a42c-6fe2-441c-8c8c-71466251a162> Anthony Liguori <anthony@codemonkey.ws> aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162> -Anthony Liguori <anthony@codemonkey.ws> Anthony Liguori <aliguori@us.ibm.com> Aurelien Jarno <aurelien@aurel32.net> aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> Blue Swirl <blauwirbel@gmail.com> blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> Edgar E. Iglesias <edgar.iglesias@gmail.com> edgar_igl <edgar_igl@c046a42c-6fe2-441c-8c8c-71466251a162> Fabrice Bellard <fabrice@bellard.org> bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> -James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com> Jocelyn Mayer <l_indien@magic.fr> j_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162> Paul Brook <paul@codesourcery.com> pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> -Yongbok Kim <yongbok.kim@mips.com> <yongbok.kim@imgtec.com> -Aleksandar Markovic <amarkovic@wavecomp.com> <aleksandar.markovic@mips.com> -Aleksandar Markovic <amarkovic@wavecomp.com> <aleksandar.markovic@imgtec.com> -Paul Burton <pburton@wavecomp.com> <paul.burton@mips.com> -Paul Burton <pburton@wavecomp.com> <paul.burton@imgtec.com> -Paul Burton <pburton@wavecomp.com> <paul@archlinuxmips.org> Thiemo Seufer <ths@networkno.de> ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> malc <av1474@comtv.ru> malc <malc@c046a42c-6fe2-441c-8c8c-71466251a162> @@ -32,8 +38,123 @@ Ian McKellar <ianloic@google.com> Ian McKellar via Qemu-devel <qemu-devel@nongnu Julia Suvorova <jusual@mail.ru> Julia Suvorova via Qemu-devel <qemu-devel@nongnu.org> Justin Terry (VM) <juterry@microsoft.com> Justin Terry (VM) via Qemu-devel <qemu-devel@nongnu.org> +# Next, replace old addresses by a more recent one. +Anthony Liguori <anthony@codemonkey.ws> Anthony Liguori <aliguori@us.ibm.com> +James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com> +Aleksandar Markovic <amarkovic@wavecomp.com> <aleksandar.markovic@mips.com> +Aleksandar Markovic <amarkovic@wavecomp.com> <aleksandar.markovic@imgtec.com> +Paul Burton <pburton@wavecomp.com> <paul.burton@mips.com> +Paul Burton <pburton@wavecomp.com> <paul.burton@imgtec.com> +Paul Burton <pburton@wavecomp.com> <paul@archlinuxmips.org> +Philippe Mathieu-Daudé <philmd@redhat.com> <f4bug@amsat.org> +Yongbok Kim <yongbok.kim@mips.com> <yongbok.kim@imgtec.com> # Also list preferred name forms where people have changed their # git author config, or had utf8/latin1 encoding issues. +Aaron Lindsay <aaron@os.amperecomputing.com> +Alexey Gerasimenko <x1917x@gmail.com> +Alex Ivanov <void@aleksoft.net> +Andreas Färber <afaerber@suse.de> +Bandan Das <bsd@redhat.com> +Benjamin MARSILI <mlspirat42@gmail.com> +Benoît Canet <benoit.canet@gmail.com> +Benoît Canet <benoit.canet@irqsave.net> +Benoît Canet <benoit.canet@nodalink.com> +Boqun Feng <boqun.feng@gmail.com> +Boqun Feng <boqun.feng@intel.com> +Brad Smith <brad@comstyle.com> +Brijesh Singh <brijesh.singh@amd.com> +Brilly Wu <brillywu@viatech.com.cn> +Cédric Vincent <cedric.vincent@st.com> +CheneyLin <linzc@zju.edu.cn> +Chen Gang <chengang@emindsoft.com.cn> +Chen Gang <gang.chen.5i5j@gmail.com> +Chen Gang <gang.chen@sunrus.com.cn> +Chen Wei-Ren <chenwj@iis.sinica.edu.tw> +Christophe Lyon <christophe.lyon@st.com> +Collin L. Walling <walling@linux.ibm.com> Daniel P. Berrangé <berrange@redhat.com> +Eduardo Otubo <otubo@redhat.com> +Fabrice Desclaux <fabrice.desclaux@cea.fr> +Fernando Luis Vázquez Cao <fernando_b1@lab.ntt.co.jp> +Fernando Luis Vázquez Cao <fernando@oss.ntt.co.jp> +Gautham R. Shenoy <ego@in.ibm.com> +Gautham R. Shenoy <ego@linux.vnet.ibm.com> +Gonglei (Arei) <arei.gonglei@huawei.com> +Guang Wang <wang.guang55@zte.com.cn> +Hailiang Zhang <zhang.zhanghailiang@huawei.com> +Hervé Poussineau <hpoussin@reactos.org> +Jakub Jermář <jakub@jermar.eu> +Jakub Jermář <jakub.jermar@kernkonzept.com> +Jean-Christophe Dubois <jcd@tribudubois.net> +Jindřich Makovička <makovick@gmail.com> +John Arbuckle <programmingkidx@gmail.com> +Juha Riihimäki <juha.riihimaki@nokia.com> +Juha Riihimäki <Juha.Riihimaki@nokia.com> +Jun Li <junmuzi@gmail.com> +Laurent Vivier <Laurent@lvivier.info> +Leandro Lupori <leandro.lupori@gmail.com> +Li Guang <lig.fnst@cn.fujitsu.com> +Liming Wang <walimisdev@gmail.com> +linzhecheng <linzc@zju.edu.cn> +Liran Schour <lirans@il.ibm.com> +Liu Yu <yu.liu@freescale.com> +Liu Yu <Yu.Liu@freescale.com> +Li Zhang <zhlcindy@gmail.com> +Li Zhang <zhlcindy@linux.vnet.ibm.com> +Lluís Vilanova <vilanova@ac.upc.edu> +Lluís Vilanova <xscript@gmx.net> +Longpeng (Mike) <longpeng2@huawei.com> +Luc Michel <luc.michel@git.antfield.fr> +Luc Michel <luc.michel@greensocs.com> +Marc Marí <marc.mari.barcelo@gmail.com> +Marc Marí <markmb@redhat.com> +Michael Avdienko <whitearchey@gmail.com> +Michael S. Tsirkin <mst@redhat.com> +Munkyu Im <munkyu.im@samsung.com> +Nicholas Bellinger <nab@linux-iscsi.org> +Nicholas Thomas <nick@bytemark.co.uk> +Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> +Orit Wasserman <owasserm@redhat.com> +Paolo Bonzini <pbonzini@redhat.com> +Pavel Dovgaluk <dovgaluk@ispras.ru> +Pavel Dovgaluk <pavel.dovgaluk@gmail.com> +Pavel Dovgaluk <Pavel.Dovgaluk@ispras.ru> +Peter Crosthwaite <crosthwaite.peter@gmail.com> +Peter Crosthwaite <peter.crosthwaite@petalogix.com> +Peter Crosthwaite <peter.crosthwaite@xilinx.com> +Prasad J Pandit <pjp@fedoraproject.org> +Prasad J Pandit <ppandit@redhat.com> +Qiao Nuohan <qiaonuohan@cn.fujitsu.com> Reimar Döffinger <Reimar.Doeffinger@gmx.de> +Remy Noel <remy.noel@blade-group.com> +Roger Pau Monné <roger.pau@citrix.com> +Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp> +Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com> +Sochin Jiang <sochin.jiang@huawei.com> +Takashi Yoshii <takasi-y@ops.dti.ne.jp> +Thomas Huth <thuth@redhat.com> +Thomas Knych <thomaswk@google.com> +Timothy Baldwin <T.E.Baldwin99@members.leeds.ac.uk> +Tony Nguyen <tony.nguyen@bt.com> +Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com> +Vibi Sreenivasan <vibi_sreenivasan@cms.com> +Vijaya Kumar K <vijayak@cavium.com> +Vijaya Kumar K <Vijaya.Kumar@cavium.com> +Vijay Kumar <vijaykumar@bravegnu.org> +Vijay Kumar <vijaykumar@zilogic.com> +Wang Guang <wang.guang55@zte.com.cn> +Wenchao Xia <xiawenc@linux.vnet.ibm.com> +Wenshuang Ma <kevinnma@tencent.com> +Xiaoqiang Zhao <zxq_yx_007@163.com> +Xinhua Cao <caoxinhua@huawei.com> +Xiong Zhang <xiong.y.zhang@intel.com> +Yin Yin <yin.yin@cs2c.com.cn> +yuchenlin <npes87184@gmail.com> +YunQiang Su <syq@debian.org> +YunQiang Su <ysu@wavecomp.com> +Yuri Pudgorodskiy <yur@virtuozzo.com> +Zhengui Li <lizhengui@huawei.com> +Zhenwei Pi <pizhenwei@bytedance.com> +Zhenwei Pi <zhenwei.pi@youruncloud.com> +Zhuang Yanying <ann.zhuangyanying@huawei.com> diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h index 5aaf186253..df9c838817 100644 --- a/accel/tcg/atomic_template.h +++ b/accel/tcg/atomic_template.h @@ -284,7 +284,7 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr, #define GEN_ATOMIC_HELPER(X) \ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \ - ABI_TYPE val EXTRA_ARGS) \ + ABI_TYPE val EXTRA_ARGS) \ { \ ATOMIC_MMU_DECLS; \ DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \ diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c index 29e55c9195..ecc15e3eb0 100644 --- a/backends/hostmem-file.c +++ b/backends/hostmem-file.c @@ -67,12 +67,12 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) uint64_t size; size = qemu_get_pmem_size(fb->mem_path, &local_err); - if (!size) { + if (local_err) { error_propagate(errp, local_err); return; } - if (backend->size > size) { + if (size && backend->size > size) { error_setg(errp, "size property %" PRIu64 " is larger than " "pmem file \"%s\" size %" PRIu64, backend->size, fb->mem_path, size); diff --git a/block.c b/block.c index 874a29a983..5944124845 100644 --- a/block.c +++ b/block.c @@ -4165,7 +4165,6 @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to, { BdrvChild *c, *next; GSList *list = NULL, *p; - uint64_t old_perm, old_shared; uint64_t perm = 0, shared = BLK_PERM_ALL; int ret; @@ -4211,8 +4210,8 @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to, bdrv_unref(from); } - bdrv_get_cumulative_perm(to, &old_perm, &old_shared); - bdrv_set_perm(to, old_perm | perm, old_shared | shared); + bdrv_get_cumulative_perm(to, &perm, &shared); + bdrv_set_perm(to, perm, shared); out: g_slist_free(list); diff --git a/block/file-posix.c b/block/file-posix.c index fbeb0068db..71f168ee2f 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -380,7 +380,7 @@ static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp) for (i = 0; i < ARRAY_SIZE(alignments); i++) { align = alignments[i]; if (raw_is_io_aligned(fd, buf + align, max_align)) { - /* Fallback to request_aligment. */ + /* Fallback to request_alignment. */ s->buf_align = (align != 1) ? align : bs->bl.request_alignment; break; } @@ -1749,6 +1749,43 @@ static int handle_aiocb_discard(void *opaque) return ret; } +/* + * Help alignment probing by allocating the first block. + * + * When reading with direct I/O from unallocated area on Gluster backed by XFS, + * reading succeeds regardless of request length. In this case we fallback to + * safe alignment which is not optimal. Allocating the first block avoids this + * fallback. + * + * fd may be opened with O_DIRECT, but we don't know the buffer alignment or + * request alignment, so we use safe values. + * + * Returns: 0 on success, -errno on failure. Since this is an optimization, + * caller may ignore failures. + */ +static int allocate_first_block(int fd, size_t max_size) +{ + size_t write_size = (max_size < MAX_BLOCKSIZE) + ? BDRV_SECTOR_SIZE + : MAX_BLOCKSIZE; + size_t max_align = MAX(MAX_BLOCKSIZE, getpagesize()); + void *buf; + ssize_t n; + int ret; + + buf = qemu_memalign(max_align, write_size); + memset(buf, 0, write_size); + + do { + n = pwrite(fd, buf, write_size, 0); + } while (n == -1 && errno == EINTR); + + ret = (n == -1) ? -errno : 0; + + qemu_vfree(buf); + return ret; +} + static int handle_aiocb_truncate(void *opaque) { RawPosixAIOData *aiocb = opaque; @@ -1788,6 +1825,17 @@ static int handle_aiocb_truncate(void *opaque) /* posix_fallocate() doesn't set errno. */ error_setg_errno(errp, -result, "Could not preallocate new data"); + } else if (current_length == 0) { + /* + * posix_fallocate() uses fallocate() if the filesystem + * supports it, or fallback to manually writing zeroes. If + * fallocate() was used, unaligned reads from the fallocated + * area in raw_probe_alignment() will succeed, hence we need to + * allocate the first block. + * + * Optimize future alignment probing; ignore failures. + */ + allocate_first_block(fd, offset); } } else { result = 0; @@ -1849,6 +1897,9 @@ static int handle_aiocb_truncate(void *opaque) if (ftruncate(fd, offset) != 0) { result = -errno; error_setg_errno(errp, -result, "Could not resize file"); + } else if (current_length == 0 && offset > current_length) { + /* Optimize future alignment probing; ignore failures. */ + allocate_first_block(fd, offset); } return result; default: diff --git a/block/vmdk.c b/block/vmdk.c index fd78fd0ccf..fed3b50c8a 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1076,8 +1076,7 @@ static const char *next_line(const char *s) } static int vmdk_parse_extents(const char *desc, BlockDriverState *bs, - const char *desc_file_path, QDict *options, - Error **errp) + QDict *options, Error **errp) { int ret; int matches; @@ -1087,6 +1086,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs, const char *p, *np; int64_t sectors = 0; int64_t flat_offset; + char *desc_file_dir = NULL; char *extent_path; BdrvChild *extent_file; BDRVVmdkState *s = bs->opaque; @@ -1130,16 +1130,23 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs, continue; } - if (!path_is_absolute(fname) && !path_has_protocol(fname) && - !desc_file_path[0]) - { - bdrv_refresh_filename(bs->file->bs); - error_setg(errp, "Cannot use relative extent paths with VMDK " - "descriptor file '%s'", bs->file->bs->filename); - return -EINVAL; - } + if (path_is_absolute(fname)) { + extent_path = g_strdup(fname); + } else { + if (!desc_file_dir) { + desc_file_dir = bdrv_dirname(bs->file->bs, errp); + if (!desc_file_dir) { + bdrv_refresh_filename(bs->file->bs); + error_prepend(errp, "Cannot use relative paths with VMDK " + "descriptor file '%s': ", + bs->file->bs->filename); + ret = -EINVAL; + goto out; + } + } - extent_path = path_combine(desc_file_path, fname); + extent_path = g_strconcat(desc_file_dir, fname, NULL); + } ret = snprintf(extent_opt_prefix, 32, "extents.%d", s->num_extents); assert(ret < 32); @@ -1149,7 +1156,8 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs, g_free(extent_path); if (local_err) { error_propagate(errp, local_err); - return -EINVAL; + ret = -EINVAL; + goto out; } /* save to extents array */ @@ -1160,7 +1168,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs, 0, 0, 0, 0, 0, &extent, errp); if (ret < 0) { bdrv_unref_child(bs, extent_file); - return ret; + goto out; } extent->flat_start_offset = flat_offset << 9; } else if (!strcmp(type, "SPARSE") || !strcmp(type, "VMFSSPARSE")) { @@ -1175,24 +1183,27 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs, g_free(buf); if (ret) { bdrv_unref_child(bs, extent_file); - return ret; + goto out; } extent = &s->extents[s->num_extents - 1]; } else if (!strcmp(type, "SESPARSE")) { ret = vmdk_open_se_sparse(bs, extent_file, bs->open_flags, errp); if (ret) { bdrv_unref_child(bs, extent_file); - return ret; + goto out; } extent = &s->extents[s->num_extents - 1]; } else { error_setg(errp, "Unsupported extent type '%s'", type); bdrv_unref_child(bs, extent_file); - return -ENOTSUP; + ret = -ENOTSUP; + goto out; } extent->type = g_strdup(type); } - return 0; + + ret = 0; + goto out; invalid: np = next_line(p); @@ -1201,7 +1212,11 @@ invalid: np--; } error_setg(errp, "Invalid extent line: %.*s", (int)(np - p), p); - return -EINVAL; + ret = -EINVAL; + +out: + g_free(desc_file_dir); + return ret; } static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf, @@ -1228,8 +1243,7 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf, } s->create_type = g_strdup(ct); s->desc_offset = 0; - ret = vmdk_parse_extents(buf, bs, bs->file->bs->exact_filename, options, - errp); + ret = vmdk_parse_extents(buf, bs, options, errp); exit: return ret; } @@ -1720,6 +1734,16 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset, if (extent->compressed) { void *compressed_data; + /* Only whole clusters */ + if (offset_in_cluster || + n_bytes > (extent->cluster_sectors * SECTOR_SIZE) || + (n_bytes < (extent->cluster_sectors * SECTOR_SIZE) && + offset + n_bytes != extent->end_sector * SECTOR_SIZE)) + { + ret = -EINVAL; + goto out; + } + if (!extent->has_marker) { ret = -EINVAL; goto out; diff --git a/contrib/gitdm/aliases b/contrib/gitdm/aliases index 07fd3391a5..c1e744312f 100644 --- a/contrib/gitdm/aliases +++ b/contrib/gitdm/aliases @@ -1,6 +1,22 @@ # -# This is the email aliases file, mapping secondary addresses -# onto a single, canonical address. Duplicates some info from .mailmap +# This is the email aliases file, mapping secondary addresses onto a +# single, canonical address. It duplicates some info from .mailmap so +# if you are adding something here also consider if the .mailmap needs +# updating. +# +# If you just want to avoid gitdm complaining about author fields +# which are actually email addresses with the message: +# +# "...is an author name, probably not what you want" +# +# you can just apply --use-mailmap to you git-log command, e.g: +# +# git log --use-mailmap --numstat --since "last 2 years" | $GITDM +# +# however that will have the effect of squashing multiple addresses to +# a canonical address which will distort the stats of those who +# contribute in both personal and professional capacities from +# different addresses. # # weird commits diff --git a/contrib/gitdm/domain-map b/contrib/gitdm/domain-map index fa9d454473..9efe066ec9 100644 --- a/contrib/gitdm/domain-map +++ b/contrib/gitdm/domain-map @@ -18,6 +18,7 @@ nokia.com Nokia oracle.com Oracle proxmox.com Proxmox redhat.com Red Hat +rt-rk.com RT-RK siemens.com Siemens sifive.com SiFive suse.de SUSE diff --git a/contrib/gitdm/filetypes.txt b/contrib/gitdm/filetypes.txt index 165b71b3f9..2d5002fea0 100644 --- a/contrib/gitdm/filetypes.txt +++ b/contrib/gitdm/filetypes.txt @@ -34,7 +34,7 @@ # If there is an filetype which is not in order but has values, it will # be added at the end. # -order build,tests,code,documentation,devel-doc,blobs +order build,interface,tests,code,documentation,devel-doc,blobs # # diff --git a/contrib/gitdm/group-map-individuals b/contrib/gitdm/group-map-individuals index 05e355d30e..1c84717438 100644 --- a/contrib/gitdm/group-map-individuals +++ b/contrib/gitdm/group-map-individuals @@ -2,7 +2,8 @@ # Individual and personal contributors # # This is simply to allow prolific developers with no company -# affiliations to be grouped together in the summary stats. +# affiliations (or non-company related personal work) to be grouped +# together in the summary stats. # f4bug@amsat.org diff --git a/contrib/gitdm/group-map-redhat b/contrib/gitdm/group-map-redhat index 6d05c6b54f..d15db2d35e 100644 --- a/contrib/gitdm/group-map-redhat +++ b/contrib/gitdm/group-map-redhat @@ -5,3 +5,4 @@ david@gibson.dropbear.id.au laurent@vivier.eu pjp@fedoraproject.org +armbru@pond.sub.org diff --git a/exec.c b/exec.c index 1df966d17a..0d47788f5f 100644 --- a/exec.c +++ b/exec.c @@ -1750,6 +1750,7 @@ long qemu_minrampagesize(void) long hpsize = LONG_MAX; long mainrampagesize; Object *memdev_root; + MachineState *ms = MACHINE(qdev_get_machine()); mainrampagesize = qemu_mempath_getpagesize(mem_path); @@ -1777,7 +1778,9 @@ long qemu_minrampagesize(void) * so if its page size is smaller we have got to report that size instead. */ if (hpsize > mainrampagesize && - (nb_numa_nodes == 0 || numa_info[0].node_memdev == NULL)) { + (ms->numa_state == NULL || + ms->numa_state->num_nodes == 0 || + ms->numa_state->nodes[0].node_memdev == NULL)) { static bool warned; if (!warned) { error_report("Huge page support disabled (n/a for main memory)."); diff --git a/gdbstub.c b/gdbstub.c index b92ba59e4d..4cf8af365e 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1820,11 +1820,15 @@ static void handle_read_all_regs(GdbCmdContext *gdb_ctx, void *user_ctx) static void handle_file_io(GdbCmdContext *gdb_ctx, void *user_ctx) { - if (gdb_ctx->num_params >= 2 && gdb_ctx->s->current_syscall_cb) { + if (gdb_ctx->num_params >= 1 && gdb_ctx->s->current_syscall_cb) { target_ulong ret, err; ret = (target_ulong)gdb_ctx->params[0].val_ull; - err = (target_ulong)gdb_ctx->params[1].val_ull; + if (gdb_ctx->num_params >= 2) { + err = (target_ulong)gdb_ctx->params[1].val_ull; + } else { + err = 0; + } gdb_ctx->s->current_syscall_cb(gdb_ctx->s->c_cpu, ret, err); gdb_ctx->s->current_syscall_cb = NULL; } @@ -2588,7 +2592,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) break; } - run_cmd_parser(s, line_buf, cmd_parser); + if (cmd_parser) { + run_cmd_parser(s, line_buf, cmd_parser); + } return RS_IDLE; } diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 555c24f21d..78aee1a2f9 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -25,6 +25,7 @@ #include "qemu/bswap.h" #include "qemu/bitops.h" #include "sysemu/numa.h" +#include "hw/boards.h" static GArray *build_alloc_array(void) { @@ -1726,18 +1727,21 @@ void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base, * ACPI spec 5.2.17 System Locality Distance Information Table * (Revision 2.0 or later) */ -void build_slit(GArray *table_data, BIOSLinker *linker) +void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms) { int slit_start, i, j; slit_start = table_data->len; + int nb_numa_nodes = ms->numa_state->num_nodes; acpi_data_push(table_data, sizeof(AcpiTableHeader)); build_append_int_noprefix(table_data, nb_numa_nodes, 8); for (i = 0; i < nb_numa_nodes; i++) { for (j = 0; j < nb_numa_nodes; j++) { - assert(numa_info[i].distance[j]); - build_append_int_noprefix(table_data, numa_info[i].distance[j], 1); + assert(ms->numa_state->nodes[i].distance[j]); + build_append_int_noprefix(table_data, + ms->numa_state->nodes[i].distance[j], + 1); } } diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index 73810a4440..118032c8c7 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -30,7 +30,8 @@ static void aw_a10_init(Object *obj) AwA10State *s = AW_A10(obj); object_initialize_child(obj, "cpu", &s->cpu, sizeof(s->cpu), - "cortex-a8-" TYPE_ARM_CPU, &error_abort, NULL); + ARM_CPU_TYPE_NAME("cortex-a8"), + &error_abort, NULL); sysbus_init_child_obj(obj, "intc", &s->intc, sizeof(s->intc), TYPE_AW_A10_PIC); diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index 7a2e885e0b..13e208c78c 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -242,9 +242,6 @@ static void aspeed_board_init(MachineState *machine, write_boot_rom(drive0, FIRMWARE_ADDR, fl->size, &error_abort); } - aspeed_board_binfo.kernel_filename = machine->kernel_filename; - aspeed_board_binfo.initrd_filename = machine->initrd_filename; - aspeed_board_binfo.kernel_cmdline = machine->kernel_cmdline; aspeed_board_binfo.ram_size = ram_size; aspeed_board_binfo.loader_start = sc->info->memmap[ASPEED_SDRAM]; aspeed_board_binfo.nb_cpus = bmc->soc.num_cpus; @@ -253,7 +250,7 @@ static void aspeed_board_init(MachineState *machine, cfg->i2c_init(bmc); } - arm_load_kernel(ARM_CPU(first_cpu), &aspeed_board_binfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &aspeed_board_binfo); } static void palmetto_bmc_i2c_init(AspeedBoardState *bmc) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index eff89ab80e..bf97ef3e33 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -17,6 +17,7 @@ #include "sysemu/kvm.h" #include "sysemu/sysemu.h" #include "sysemu/numa.h" +#include "hw/boards.h" #include "sysemu/reset.h" #include "hw/loader.h" #include "elf.h" @@ -523,7 +524,7 @@ static void fdt_add_psci_node(void *fdt) } int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, - hwaddr addr_limit, AddressSpace *as) + hwaddr addr_limit, AddressSpace *as, MachineState *ms) { void *fdt = NULL; int size, rc, n = 0; @@ -597,10 +598,10 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, } g_strfreev(node_path); - if (nb_numa_nodes > 0) { + if (ms->numa_state != NULL && ms->numa_state->num_nodes > 0) { mem_base = binfo->loader_start; - for (i = 0; i < nb_numa_nodes; i++) { - mem_len = numa_info[i].node_mem; + for (i = 0; i < ms->numa_state->num_nodes; i++) { + mem_len = ms->numa_state->nodes[i].node_mem; rc = fdt_add_memory_node(fdt, acells, mem_base, scells, mem_len, i); if (rc < 0) { @@ -626,9 +627,9 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, qemu_fdt_add_subnode(fdt, "/chosen"); } - if (binfo->kernel_cmdline && *binfo->kernel_cmdline) { + if (ms->kernel_cmdline && *ms->kernel_cmdline) { rc = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", - binfo->kernel_cmdline); + ms->kernel_cmdline); if (rc < 0) { fprintf(stderr, "couldn't set /chosen/bootargs\n"); goto fail; @@ -1260,7 +1261,7 @@ static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info) */ } -void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) +void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info) { CPUState *cs; AddressSpace *as = arm_boot_address_space(cpu, info); @@ -1281,7 +1282,9 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) * doesn't support secure. */ assert(!(info->secure_board_setup && kvm_enabled())); - + info->kernel_filename = ms->kernel_filename; + info->kernel_cmdline = ms->kernel_cmdline; + info->initrd_filename = ms->initrd_filename; info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb"); info->dtb_limit = 0; @@ -1293,7 +1296,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) } if (!info->skip_dtb_autoload && have_dtb(info)) { - if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as) < 0) { + if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as, ms) < 0) { exit(1); } } diff --git a/hw/arm/collie.c b/hw/arm/collie.c index 219643c633..b1288ccea8 100644 --- a/hw/arm/collie.c +++ b/hw/arm/collie.c @@ -25,9 +25,6 @@ static struct arm_boot_info collie_binfo = { static void collie_init(MachineState *machine) { - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; StrongARMState *s; DriveInfo *dinfo; MemoryRegion *sysmem = get_system_memory(); @@ -46,11 +43,8 @@ static void collie_init(MachineState *machine) sysbus_create_simple("scoop", 0x40800000, NULL); - collie_binfo.kernel_filename = kernel_filename; - collie_binfo.kernel_cmdline = kernel_cmdline; - collie_binfo.initrd_filename = initrd_filename; collie_binfo.board_id = 0x208; - arm_load_kernel(s->cpu, &collie_binfo); + arm_load_kernel(s->cpu, machine, &collie_binfo); } static void collie_machine_init(MachineClass *mc) diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c index 38e0ca0f53..6dc2f1d6b6 100644 --- a/hw/arm/cubieboard.c +++ b/hw/arm/cubieboard.c @@ -73,15 +73,13 @@ static void cubieboard_init(MachineState *machine) /* TODO create and connect IDE devices for ide_drive_get() */ cubieboard_binfo.ram_size = machine->ram_size; - cubieboard_binfo.kernel_filename = machine->kernel_filename; - cubieboard_binfo.kernel_cmdline = machine->kernel_cmdline; - cubieboard_binfo.initrd_filename = machine->initrd_filename; - arm_load_kernel(&s->a10->cpu, &cubieboard_binfo); + arm_load_kernel(&s->a10->cpu, machine, &cubieboard_binfo); } static void cubieboard_machine_init(MachineClass *mc) { - mc->desc = "cubietech cubieboard"; + mc->desc = "cubietech cubieboard (Cortex-A9)"; + mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a9"); mc->init = cubieboard_init; mc->block_default_type = IF_IDE; mc->units_per_default_bus = 1; diff --git a/hw/arm/digic.c b/hw/arm/digic.c index 4f52465875..22434a65a2 100644 --- a/hw/arm/digic.c +++ b/hw/arm/digic.c @@ -37,7 +37,8 @@ static void digic_init(Object *obj) int i; object_initialize_child(obj, "cpu", &s->cpu, sizeof(s->cpu), - "arm946-" TYPE_ARM_CPU, &error_abort, NULL); + ARM_CPU_TYPE_NAME("arm946"), + &error_abort, NULL); for (i = 0; i < DIGIC4_NB_TIMERS; i++) { #define DIGIC_TIMER_NAME_MLEN 11 diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c index f69358a5ba..09da52876d 100644 --- a/hw/arm/exynos4_boards.c +++ b/hw/arm/exynos4_boards.c @@ -122,17 +122,14 @@ exynos4_boards_init_common(MachineState *machine, exynos4_board_binfo.board_id = exynos4_board_id[board_type]; exynos4_board_binfo.smp_bootreg_addr = exynos4_board_smp_bootreg_addr[board_type]; - exynos4_board_binfo.kernel_filename = machine->kernel_filename; - exynos4_board_binfo.initrd_filename = machine->initrd_filename; - exynos4_board_binfo.kernel_cmdline = machine->kernel_cmdline; exynos4_board_binfo.gic_cpu_if_addr = EXYNOS4210_SMP_PRIVATE_BASE_ADDR + 0x100; exynos4_boards_init_ram(s, get_system_memory(), exynos4_board_ram_size[board_type]); - object_initialize(&s->soc, sizeof(s->soc), TYPE_EXYNOS4210_SOC); - qdev_set_parent_bus(DEVICE(&s->soc), sysbus_get_default()); + sysbus_init_child_obj(OBJECT(machine), "soc", + &s->soc, sizeof(s->soc), TYPE_EXYNOS4210_SOC); object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal); @@ -143,7 +140,7 @@ static void nuri_init(MachineState *machine) { exynos4_boards_init_common(machine, EXYNOS4_BOARD_NURI); - arm_load_kernel(ARM_CPU(first_cpu), &exynos4_board_binfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &exynos4_board_binfo); } static void smdkc210_init(MachineState *machine) @@ -153,7 +150,7 @@ static void smdkc210_init(MachineState *machine) lan9215_init(SMDK_LAN9118_BASE_ADDR, qemu_irq_invert(s->soc.irq_table[exynos4210_get_irq(37, 1)])); - arm_load_kernel(ARM_CPU(first_cpu), &exynos4_board_binfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &exynos4_board_binfo); } static void nuri_class_init(ObjectClass *oc, void *data) diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c index 532d088298..3cb5a8fdfd 100644 --- a/hw/arm/fsl-imx25.c +++ b/hw/arm/fsl-imx25.c @@ -36,7 +36,9 @@ static void fsl_imx25_init(Object *obj) FslIMX25State *s = FSL_IMX25(obj); int i; - object_initialize(&s->cpu, sizeof(s->cpu), "arm926-" TYPE_ARM_CPU); + object_initialize_child(obj, "cpu", &s->cpu, sizeof(s->cpu), + ARM_CPU_TYPE_NAME("arm926"), + &error_abort, NULL); sysbus_init_child_obj(obj, "avic", &s->avic, sizeof(s->avic), TYPE_IMX_AVIC); diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c index 1a37a7b997..55e90d104b 100644 --- a/hw/arm/fsl-imx31.c +++ b/hw/arm/fsl-imx31.c @@ -33,7 +33,9 @@ static void fsl_imx31_init(Object *obj) FslIMX31State *s = FSL_IMX31(obj); int i; - object_initialize(&s->cpu, sizeof(s->cpu), "arm1136-" TYPE_ARM_CPU); + object_initialize_child(obj, "cpu", &s->cpu, sizeof(s->cpu), + ARM_CPU_TYPE_NAME("arm1136"), + &error_abort, NULL); sysbus_init_child_obj(obj, "avic", &s->avic, sizeof(s->avic), TYPE_IMX_AVIC); diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c index 8c397ef04b..552145b24e 100644 --- a/hw/arm/fsl-imx6.c +++ b/hw/arm/fsl-imx6.c @@ -43,7 +43,8 @@ static void fsl_imx6_init(Object *obj) for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX6_NUM_CPUS); i++) { snprintf(name, NAME_SIZE, "cpu%d", i); object_initialize_child(obj, name, &s->cpu[i], sizeof(s->cpu[i]), - "cortex-a9-" TYPE_ARM_CPU, &error_abort, NULL); + ARM_CPU_TYPE_NAME("cortex-a9"), + &error_abort, NULL); } sysbus_init_child_obj(obj, "a9mpcore", &s->a9mpcore, sizeof(s->a9mpcore), diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c index b074177a71..c405b68d1d 100644 --- a/hw/arm/fsl-imx6ul.c +++ b/hw/arm/fsl-imx6ul.c @@ -34,7 +34,7 @@ static void fsl_imx6ul_init(Object *obj) int i; object_initialize_child(obj, "cpu0", &s->cpu, sizeof(s->cpu), - "cortex-a7-" TYPE_ARM_CPU, &error_abort, NULL); + ARM_CPU_TYPE_NAME("cortex-a7"), &error_abort, NULL); /* * A7MPCORE diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c index 362e5ba044..f1724d6929 100644 --- a/hw/arm/highbank.c +++ b/hw/arm/highbank.c @@ -236,9 +236,6 @@ enum cxmachines { static void calxeda_init(MachineState *machine, enum cxmachines machine_id) { ram_addr_t ram_size = machine->ram_size; - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; DeviceState *dev = NULL; SysBusDevice *busdev; qemu_irq pic[128]; @@ -390,9 +387,6 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id) /* TODO create and connect IDE devices for ide_drive_get() */ highbank_binfo.ram_size = ram_size; - highbank_binfo.kernel_filename = kernel_filename; - highbank_binfo.kernel_cmdline = kernel_cmdline; - highbank_binfo.initrd_filename = initrd_filename; /* highbank requires a dtb in order to boot, and the dtb will override * the board ID. The following value is ignored, so set it to -1 to be * clear that the value is meaningless. @@ -412,7 +406,7 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id) "may not boot."); } - arm_load_kernel(ARM_CPU(first_cpu), &highbank_binfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &highbank_binfo); } static void highbank_init(MachineState *machine) diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c index 5d673e47bc..c76fc2bd94 100644 --- a/hw/arm/imx25_pdk.c +++ b/hw/arm/imx25_pdk.c @@ -116,9 +116,6 @@ static void imx25_pdk_init(MachineState *machine) } imx25_pdk_binfo.ram_size = machine->ram_size; - imx25_pdk_binfo.kernel_filename = machine->kernel_filename; - imx25_pdk_binfo.kernel_cmdline = machine->kernel_cmdline; - imx25_pdk_binfo.initrd_filename = machine->initrd_filename; imx25_pdk_binfo.loader_start = FSL_IMX25_SDRAM0_ADDR; imx25_pdk_binfo.board_id = 1771, imx25_pdk_binfo.nb_cpus = 1; @@ -129,7 +126,7 @@ static void imx25_pdk_init(MachineState *machine) * fail. */ if (!qtest_enabled()) { - arm_load_kernel(&s->soc.cpu, &imx25_pdk_binfo); + arm_load_kernel(&s->soc.cpu, machine, &imx25_pdk_binfo); } } diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c index 200568b42a..524970840d 100644 --- a/hw/arm/integratorcp.c +++ b/hw/arm/integratorcp.c @@ -582,9 +582,6 @@ static struct arm_boot_info integrator_binfo = { static void integratorcp_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; Object *cpuobj; ARMCPU *cpu; MemoryRegion *address_space_mem = get_system_memory(); @@ -654,10 +651,7 @@ static void integratorcp_init(MachineState *machine) sysbus_create_simple("pl110", 0xc0000000, pic[22]); integrator_binfo.ram_size = ram_size; - integrator_binfo.kernel_filename = kernel_filename; - integrator_binfo.kernel_cmdline = kernel_cmdline; - integrator_binfo.initrd_filename = initrd_filename; - arm_load_kernel(cpu, &integrator_binfo); + arm_load_kernel(cpu, machine, &integrator_binfo); } static void integratorcp_machine_init(MachineClass *mc) diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c index 2f052e1f8c..1d5ef289d5 100644 --- a/hw/arm/kzm.c +++ b/hw/arm/kzm.c @@ -127,13 +127,10 @@ static void kzm_init(MachineState *machine) } kzm_binfo.ram_size = machine->ram_size; - kzm_binfo.kernel_filename = machine->kernel_filename; - kzm_binfo.kernel_cmdline = machine->kernel_cmdline; - kzm_binfo.initrd_filename = machine->initrd_filename; kzm_binfo.nb_cpus = 1; if (!qtest_enabled()) { - arm_load_kernel(&s->soc.cpu, &kzm_binfo); + arm_load_kernel(&s->soc.cpu, machine, &kzm_binfo); } } diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c index 1bad1aea76..b01ce3ce08 100644 --- a/hw/arm/mainstone.c +++ b/hw/arm/mainstone.c @@ -176,11 +176,8 @@ static void mainstone_common_init(MemoryRegion *address_space_mem, smc91c111_init(&nd_table[0], MST_ETH_PHYS, qdev_get_gpio_in(mst_irq, ETHERNET_IRQ)); - mainstone_binfo.kernel_filename = machine->kernel_filename; - mainstone_binfo.kernel_cmdline = machine->kernel_cmdline; - mainstone_binfo.initrd_filename = machine->initrd_filename; mainstone_binfo.board_id = arm_id; - arm_load_kernel(mpu->cpu, &mainstone_binfo); + arm_load_kernel(mpu->cpu, machine, &mainstone_binfo); } static void mainstone_init(MachineState *machine) diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c index 0276875f02..e90b393a44 100644 --- a/hw/arm/mcimx6ul-evk.c +++ b/hw/arm/mcimx6ul-evk.c @@ -40,9 +40,6 @@ static void mcimx6ul_evk_init(MachineState *machine) .loader_start = FSL_IMX6UL_MMDC_ADDR, .board_id = -1, .ram_size = machine->ram_size, - .kernel_filename = machine->kernel_filename, - .kernel_cmdline = machine->kernel_cmdline, - .initrd_filename = machine->initrd_filename, .nb_cpus = machine->smp.cpus, }; @@ -72,7 +69,7 @@ static void mcimx6ul_evk_init(MachineState *machine) } if (!qtest_enabled()) { - arm_load_kernel(&s->soc.cpu, &boot_info); + arm_load_kernel(&s->soc.cpu, machine, &boot_info); } } diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c index 97b8bb788a..0d1f62d30a 100644 --- a/hw/arm/mcimx7d-sabre.c +++ b/hw/arm/mcimx7d-sabre.c @@ -30,7 +30,6 @@ static void mcimx7d_sabre_init(MachineState *machine) { static struct arm_boot_info boot_info; MCIMX7Sabre *s = g_new0(MCIMX7Sabre, 1); - Object *soc; int i; if (machine->ram_size > FSL_IMX7_MMDC_SIZE) { @@ -43,16 +42,13 @@ static void mcimx7d_sabre_init(MachineState *machine) .loader_start = FSL_IMX7_MMDC_ADDR, .board_id = -1, .ram_size = machine->ram_size, - .kernel_filename = machine->kernel_filename, - .kernel_cmdline = machine->kernel_cmdline, - .initrd_filename = machine->initrd_filename, .nb_cpus = machine->smp.cpus, }; - object_initialize(&s->soc, sizeof(s->soc), TYPE_FSL_IMX7); - soc = OBJECT(&s->soc); - object_property_add_child(OBJECT(machine), "soc", soc, &error_fatal); - object_property_set_bool(soc, true, "realized", &error_fatal); + object_initialize_child(OBJECT(machine), "soc", + &s->soc, sizeof(s->soc), + TYPE_FSL_IMX7, &error_fatal, NULL); + object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal); memory_region_allocate_system_memory(&s->ram, NULL, "mcimx7d-sabre.ram", machine->ram_size); @@ -75,7 +71,7 @@ static void mcimx7d_sabre_init(MachineState *machine) } if (!qtest_enabled()) { - arm_load_kernel(&s->soc.cpu[0], &boot_info); + arm_load_kernel(&s->soc.cpu[0], machine, &boot_info); } } diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c index d85dc2c4bd..6b24aaacde 100644 --- a/hw/arm/mps2-tz.c +++ b/hw/arm/mps2-tz.c @@ -427,10 +427,10 @@ static void mps2tz_common_init(MachineState *machine) /* The sec_resp_cfg output from the IoTKit must be split into multiple * lines, one for each of the PPCs we create here, plus one per MSC. */ - object_initialize(&mms->sec_resp_splitter, sizeof(mms->sec_resp_splitter), - TYPE_SPLIT_IRQ); - object_property_add_child(OBJECT(machine), "sec-resp-splitter", - OBJECT(&mms->sec_resp_splitter), &error_abort); + object_initialize_child(OBJECT(machine), "sec-resp-splitter", + &mms->sec_resp_splitter, + sizeof(mms->sec_resp_splitter), + TYPE_SPLIT_IRQ, &error_abort, NULL); object_property_set_int(OBJECT(&mms->sec_resp_splitter), ARRAY_SIZE(mms->ppc) + ARRAY_SIZE(mms->msc), "num-lines", &error_fatal); @@ -465,10 +465,9 @@ static void mps2tz_common_init(MachineState *machine) * Tx, Rx and "combined" IRQs are sent to the NVIC separately. * Create the OR gate for this. */ - object_initialize(&mms->uart_irq_orgate, sizeof(mms->uart_irq_orgate), - TYPE_OR_IRQ); - object_property_add_child(OBJECT(mms), "uart-irq-orgate", - OBJECT(&mms->uart_irq_orgate), &error_abort); + object_initialize_child(OBJECT(mms), "uart-irq-orgate", + &mms->uart_irq_orgate, sizeof(mms->uart_irq_orgate), + TYPE_OR_IRQ, &error_abort, NULL); object_property_set_int(OBJECT(&mms->uart_irq_orgate), 10, "num-lines", &error_fatal); object_property_set_bool(OBJECT(&mms->uart_irq_orgate), true, diff --git a/hw/arm/musca.c b/hw/arm/musca.c index ddd8842732..68db4b5b38 100644 --- a/hw/arm/musca.c +++ b/hw/arm/musca.c @@ -424,10 +424,11 @@ static void musca_init(MachineState *machine) * The sec_resp_cfg output from the SSE-200 must be split into multiple * lines, one for each of the PPCs we create here. */ - object_initialize(&mms->sec_resp_splitter, sizeof(mms->sec_resp_splitter), - TYPE_SPLIT_IRQ); - object_property_add_child(OBJECT(machine), "sec-resp-splitter", - OBJECT(&mms->sec_resp_splitter), &error_fatal); + object_initialize_child(OBJECT(machine), "sec-resp-splitter", + &mms->sec_resp_splitter, + sizeof(mms->sec_resp_splitter), + TYPE_SPLIT_IRQ, &error_fatal, NULL); + object_property_set_int(OBJECT(&mms->sec_resp_splitter), ARRAY_SIZE(mms->ppc), "num-lines", &error_fatal); object_property_set_bool(OBJECT(&mms->sec_resp_splitter), true, diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c index 8ae4751d75..246cbb1336 100644 --- a/hw/arm/musicpal.c +++ b/hw/arm/musicpal.c @@ -1573,9 +1573,6 @@ static struct arm_boot_info musicpal_binfo = { static void musicpal_init(MachineState *machine) { - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; ARMCPU *cpu; qemu_irq pic[32]; DeviceState *dev; @@ -1704,10 +1701,7 @@ static void musicpal_init(MachineState *machine) sysbus_connect_irq(s, 0, pic[MP_AUDIO_IRQ]); musicpal_binfo.ram_size = MP_RAM_DEFAULT_SIZE; - musicpal_binfo.kernel_filename = kernel_filename; - musicpal_binfo.kernel_cmdline = kernel_cmdline; - musicpal_binfo.initrd_filename = initrd_filename; - arm_load_kernel(cpu, &musicpal_binfo); + arm_load_kernel(cpu, machine, &musicpal_binfo); } static void musicpal_machine_init(MachineClass *mc) diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c index a6c4085337..a36971d39a 100644 --- a/hw/arm/nseries.c +++ b/hw/arm/nseries.c @@ -1361,10 +1361,7 @@ static void n8x0_init(MachineState *machine, if (machine->kernel_filename) { /* Or at the linux loader. */ - binfo->kernel_filename = machine->kernel_filename; - binfo->kernel_cmdline = machine->kernel_cmdline; - binfo->initrd_filename = machine->initrd_filename; - arm_load_kernel(s->mpu->cpu, binfo); + arm_load_kernel(s->mpu->cpu, machine, binfo); qemu_register_reset(n8x0_boot_init, s); } diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c index 75a05c36b0..c071197be7 100644 --- a/hw/arm/omap_sx1.c +++ b/hw/arm/omap_sx1.c @@ -195,10 +195,7 @@ static void sx1_init(MachineState *machine, const int version) } /* Load the kernel. */ - sx1_binfo.kernel_filename = machine->kernel_filename; - sx1_binfo.kernel_cmdline = machine->kernel_cmdline; - sx1_binfo.initrd_filename = machine->initrd_filename; - arm_load_kernel(mpu->cpu, &sx1_binfo); + arm_load_kernel(mpu->cpu, machine, &sx1_binfo); /* TODO: fix next line */ //~ qemu_console_resize(ds, 640, 480); diff --git a/hw/arm/palm.c b/hw/arm/palm.c index bea47b917d..02a3a82b9b 100644 --- a/hw/arm/palm.c +++ b/hw/arm/palm.c @@ -187,9 +187,6 @@ static struct arm_boot_info palmte_binfo = { static void palmte_init(MachineState *machine) { - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; MemoryRegion *address_space_mem = get_system_memory(); struct omap_mpu_state_s *mpu; int flash_size = 0x00800000; @@ -249,16 +246,13 @@ static void palmte_init(MachineState *machine) } } - if (!rom_loaded && !kernel_filename && !qtest_enabled()) { + if (!rom_loaded && !machine->kernel_filename && !qtest_enabled()) { fprintf(stderr, "Kernel or ROM image must be specified\n"); exit(1); } /* Load the kernel. */ - palmte_binfo.kernel_filename = kernel_filename; - palmte_binfo.kernel_cmdline = kernel_cmdline; - palmte_binfo.initrd_filename = initrd_filename; - arm_load_kernel(mpu->cpu, &palmte_binfo); + arm_load_kernel(mpu->cpu, machine, &palmte_binfo); } static void palmte_machine_init(MachineClass *mc) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 5b2620acb4..74c062d05e 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -157,13 +157,9 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size) binfo.entry = firmware_addr; binfo.firmware_loaded = true; - } else { - binfo.kernel_filename = machine->kernel_filename; - binfo.kernel_cmdline = machine->kernel_cmdline; - binfo.initrd_filename = machine->initrd_filename; } - arm_load_kernel(ARM_CPU(first_cpu), &binfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &binfo); } static void raspi_init(MachineState *machine, int version) diff --git a/hw/arm/realview.c b/hw/arm/realview.c index b108a9ab26..8fcdf75a2b 100644 --- a/hw/arm/realview.c +++ b/hw/arm/realview.c @@ -351,13 +351,10 @@ static void realview_init(MachineState *machine, memory_region_add_subregion(sysmem, SMP_BOOT_ADDR, ram_hack); realview_binfo.ram_size = ram_size; - realview_binfo.kernel_filename = machine->kernel_filename; - realview_binfo.kernel_cmdline = machine->kernel_cmdline; - realview_binfo.initrd_filename = machine->initrd_filename; realview_binfo.nb_cpus = smp_cpus; realview_binfo.board_id = realview_board_id[board_type]; realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0); - arm_load_kernel(ARM_CPU(first_cpu), &realview_binfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &realview_binfo); } static void realview_eb_init(MachineState *machine) diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c index a6185c169e..96cc455c5c 100644 --- a/hw/arm/sabrelite.c +++ b/hw/arm/sabrelite.c @@ -103,16 +103,13 @@ static void sabrelite_init(MachineState *machine) } sabrelite_binfo.ram_size = machine->ram_size; - sabrelite_binfo.kernel_filename = machine->kernel_filename; - sabrelite_binfo.kernel_cmdline = machine->kernel_cmdline; - sabrelite_binfo.initrd_filename = machine->initrd_filename; sabrelite_binfo.nb_cpus = machine->smp.cpus; sabrelite_binfo.secure_boot = true; sabrelite_binfo.write_secondary_boot = sabrelite_write_secondary; sabrelite_binfo.secondary_cpu_reset_hook = sabrelite_reset_secondary; if (!qtest_enabled()) { - arm_load_kernel(&s->soc.cpu[0], &sabrelite_binfo); + arm_load_kernel(&s->soc.cpu[0], machine, &sabrelite_binfo); } } diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c index e98e9a5170..27046cc284 100644 --- a/hw/arm/sbsa-ref.c +++ b/hw/arm/sbsa-ref.c @@ -146,6 +146,7 @@ static void create_fdt(SBSAMachineState *sms) { void *fdt = create_device_tree(&sms->fdt_size); const MachineState *ms = MACHINE(sms); + int nb_numa_nodes = ms->numa_state->num_nodes; int cpu; if (!fdt) { @@ -159,7 +160,7 @@ static void create_fdt(SBSAMachineState *sms) qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2); qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2); - if (have_numa_distance) { + if (ms->numa_state->have_numa_distance) { int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t); uint32_t *matrix = g_malloc0(size); int idx, i, j; @@ -169,7 +170,8 @@ static void create_fdt(SBSAMachineState *sms) idx = (i * nb_numa_nodes + j) * 3; matrix[idx + 0] = cpu_to_be32(i); matrix[idx + 1] = cpu_to_be32(j); - matrix[idx + 2] = cpu_to_be32(numa_info[i].distance[j]); + matrix[idx + 2] = + cpu_to_be32(ms->numa_state->nodes[i].distance[j]); } } @@ -711,13 +713,12 @@ static void sbsa_ref_init(MachineState *machine) create_pcie(sms, pic); sms->bootinfo.ram_size = machine->ram_size; - sms->bootinfo.kernel_filename = machine->kernel_filename; sms->bootinfo.nb_cpus = smp_cpus; sms->bootinfo.board_id = -1; sms->bootinfo.loader_start = sbsa_ref_memmap[SBSA_MEM].base; sms->bootinfo.get_dtb = sbsa_ref_dtb; sms->bootinfo.firmware_loaded = firmware_loaded; - arm_load_kernel(ARM_CPU(first_cpu), &sms->bootinfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &sms->bootinfo); } static uint64_t sbsa_ref_cpu_mp_affinity(SBSAMachineState *sms, int idx) @@ -763,7 +764,7 @@ sbsa_ref_cpu_index_to_props(MachineState *ms, unsigned cpu_index) static int64_t sbsa_ref_get_default_cpu_node_id(const MachineState *ms, int idx) { - return idx % nb_numa_nodes; + return idx % ms->numa_state->num_nodes; } static void sbsa_ref_instance_init(Object *obj) @@ -790,6 +791,7 @@ static void sbsa_ref_class_init(ObjectClass *oc, void *data) mc->possible_cpu_arch_ids = sbsa_ref_possible_cpu_arch_ids; mc->cpu_index_to_instance_props = sbsa_ref_cpu_index_to_props; mc->get_default_cpu_node_id = sbsa_ref_get_default_cpu_node_id; + mc->numa_mem_supported = true; } static const TypeInfo sbsa_ref_info = { diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h index b160289cd1..d190181ef1 100644 --- a/hw/arm/smmuv3-internal.h +++ b/hw/arm/smmuv3-internal.h @@ -381,6 +381,7 @@ typedef struct SMMUEventInfo { uint32_t sid; bool recorded; bool record_trans_faults; + bool inval_ste_allowed; union { struct { uint32_t ssid; diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 2eaf07fb5f..db051dcac8 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -320,6 +320,9 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg, uint32_t config; if (!STE_VALID(ste)) { + if (!event->inval_ste_allowed) { + qemu_log_mask(LOG_GUEST_ERROR, "invalid STE\n"); + } goto bad_ste; } @@ -406,8 +409,10 @@ static int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *ste, if (!span) { /* l2ptr is not valid */ - qemu_log_mask(LOG_GUEST_ERROR, - "invalid sid=%d (L1STD span=0)\n", sid); + if (!event->inval_ste_allowed) { + qemu_log_mask(LOG_GUEST_ERROR, + "invalid sid=%d (L1STD span=0)\n", sid); + } event->type = SMMU_EVT_C_BAD_STREAMID; return -EINVAL; } @@ -602,7 +607,9 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr, SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu); SMMUv3State *s = sdev->smmu; uint32_t sid = smmu_get_sid(sdev); - SMMUEventInfo event = {.type = SMMU_EVT_NONE, .sid = sid}; + SMMUEventInfo event = {.type = SMMU_EVT_NONE, + .sid = sid, + .inval_ste_allowed = false}; SMMUPTWEventInfo ptw_info = {}; SMMUTranslationStatus status; SMMUState *bs = ARM_SMMU(s); @@ -795,16 +802,13 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, dma_addr_t iova) { SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu); - SMMUEventInfo event = {}; + SMMUEventInfo event = {.inval_ste_allowed = true}; SMMUTransTableInfo *tt; SMMUTransCfg *cfg; IOMMUTLBEntry entry; cfg = smmuv3_get_config(sdev, &event); if (!cfg) { - qemu_log_mask(LOG_GUEST_ERROR, - "%s error decoding the configuration for iommu mr=%s\n", - __func__, mr->parent_obj.name); return; } diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c index 59348123b5..25bd0f5d9d 100644 --- a/hw/arm/spitz.c +++ b/hw/arm/spitz.c @@ -954,11 +954,8 @@ static void spitz_common_init(MachineState *machine, /* A 4.0 GB microdrive is permanently sitting in CF slot 0. */ spitz_microdrive_attach(mpu, 0); - spitz_binfo.kernel_filename = machine->kernel_filename; - spitz_binfo.kernel_cmdline = machine->kernel_cmdline; - spitz_binfo.initrd_filename = machine->initrd_filename; spitz_binfo.board_id = arm_id; - arm_load_kernel(mpu->cpu, &spitz_binfo); + arm_load_kernel(mpu->cpu, machine, &spitz_binfo); sl_bootparam_write(SL_PXA_PARAM_BASE); } diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c index e9627e356e..4d95a1f3e2 100644 --- a/hw/arm/tosa.c +++ b/hw/arm/tosa.c @@ -218,9 +218,6 @@ static struct arm_boot_info tosa_binfo = { static void tosa_init(MachineState *machine) { - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *rom = g_new(MemoryRegion, 1); PXA2xxState *mpu; @@ -245,11 +242,8 @@ static void tosa_init(MachineState *machine) tosa_tg_init(mpu); - tosa_binfo.kernel_filename = kernel_filename; - tosa_binfo.kernel_cmdline = kernel_cmdline; - tosa_binfo.initrd_filename = initrd_filename; tosa_binfo.board_id = 0x208; - arm_load_kernel(mpu->cpu, &tosa_binfo); + arm_load_kernel(mpu->cpu, machine, &tosa_binfo); sl_bootparam_write(SL_PXA_PARAM_BASE); } diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c index e25561705f..e86af01537 100644 --- a/hw/arm/versatilepb.c +++ b/hw/arm/versatilepb.c @@ -375,11 +375,8 @@ static void versatile_init(MachineState *machine, int board_id) } versatile_binfo.ram_size = machine->ram_size; - versatile_binfo.kernel_filename = machine->kernel_filename; - versatile_binfo.kernel_cmdline = machine->kernel_cmdline; - versatile_binfo.initrd_filename = machine->initrd_filename; versatile_binfo.board_id = board_id; - arm_load_kernel(cpu, &versatile_binfo); + arm_load_kernel(cpu, machine, &versatile_binfo); } static void vpb_init(MachineState *machine) diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c index 5d932c27c0..4673a88a8d 100644 --- a/hw/arm/vexpress.c +++ b/hw/arm/vexpress.c @@ -707,9 +707,6 @@ static void vexpress_common_init(MachineState *machine) } daughterboard->bootinfo.ram_size = machine->ram_size; - daughterboard->bootinfo.kernel_filename = machine->kernel_filename; - daughterboard->bootinfo.kernel_cmdline = machine->kernel_cmdline; - daughterboard->bootinfo.initrd_filename = machine->initrd_filename; daughterboard->bootinfo.nb_cpus = machine->smp.cpus; daughterboard->bootinfo.board_id = VEXPRESS_BOARD_ID; daughterboard->bootinfo.loader_start = daughterboard->loader_start; @@ -719,7 +716,7 @@ static void vexpress_common_init(MachineState *machine) daughterboard->bootinfo.modify_dtb = vexpress_modify_dtb; /* When booting Linux we should be in secure state if the CPU has one. */ daughterboard->bootinfo.secure_boot = vms->secure; - arm_load_kernel(ARM_CPU(first_cpu), &daughterboard->bootinfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &daughterboard->bootinfo); } static bool vexpress_get_secure(Object *obj, Error **errp) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index a8b2d97fe9..6cdf156cf5 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -517,7 +517,8 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) int i, srat_start; uint64_t mem_base; MachineClass *mc = MACHINE_GET_CLASS(vms); - const CPUArchIdList *cpu_list = mc->possible_cpu_arch_ids(MACHINE(vms)); + MachineState *ms = MACHINE(vms); + const CPUArchIdList *cpu_list = mc->possible_cpu_arch_ids(ms); srat_start = table_data->len; srat = acpi_data_push(table_data, sizeof(*srat)); @@ -533,12 +534,13 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) } mem_base = vms->memmap[VIRT_MEM].base; - for (i = 0; i < nb_numa_nodes; ++i) { - if (numa_info[i].node_mem > 0) { + for (i = 0; i < ms->numa_state->num_nodes; ++i) { + if (ms->numa_state->nodes[i].node_mem > 0) { numamem = acpi_data_push(table_data, sizeof(*numamem)); - build_srat_memory(numamem, mem_base, numa_info[i].node_mem, i, + build_srat_memory(numamem, mem_base, + ms->numa_state->nodes[i].node_mem, i, MEM_AFFINITY_ENABLED); - mem_base += numa_info[i].node_mem; + mem_base += ms->numa_state->nodes[i].node_mem; } } @@ -759,6 +761,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) GArray *table_offsets; unsigned dsdt, xsdt; GArray *tables_blob = tables->table_data; + MachineState *ms = MACHINE(vms); table_offsets = g_array_new(false, true /* clear */, sizeof(uint32_t)); @@ -793,12 +796,12 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) acpi_add_table(table_offsets, tables_blob); build_spcr(tables_blob, tables->linker, vms); - if (nb_numa_nodes > 0) { + if (ms->numa_state->num_nodes > 0) { acpi_add_table(table_offsets, tables_blob); build_srat(tables_blob, tables->linker, vms); - if (have_numa_distance) { + if (ms->numa_state->have_numa_distance) { acpi_add_table(table_offsets, tables_blob); - build_slit(tables_blob, tables->linker); + build_slit(tables_blob, tables->linker, ms); } } diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 0d1629ccb3..d74538b021 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -203,6 +203,8 @@ static bool cpu_type_valid(const char *cpu) static void create_fdt(VirtMachineState *vms) { + MachineState *ms = MACHINE(vms); + int nb_numa_nodes = ms->numa_state->num_nodes; void *fdt = create_device_tree(&vms->fdt_size); if (!fdt) { @@ -234,7 +236,7 @@ static void create_fdt(VirtMachineState *vms) "clk24mhz"); qemu_fdt_setprop_cell(fdt, "/apb-pclk", "phandle", vms->clock_phandle); - if (have_numa_distance) { + if (nb_numa_nodes > 0 && ms->numa_state->have_numa_distance) { int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t); uint32_t *matrix = g_malloc0(size); int idx, i, j; @@ -244,7 +246,8 @@ static void create_fdt(VirtMachineState *vms) idx = (i * nb_numa_nodes + j) * 3; matrix[idx + 0] = cpu_to_be32(i); matrix[idx + 1] = cpu_to_be32(j); - matrix[idx + 2] = cpu_to_be32(numa_info[i].distance[j]); + matrix[idx + 2] = + cpu_to_be32(ms->numa_state->nodes[i].distance[j]); } } @@ -1368,6 +1371,7 @@ void virt_machine_done(Notifier *notifier, void *data) { VirtMachineState *vms = container_of(notifier, VirtMachineState, machine_done); + MachineState *ms = MACHINE(vms); ARMCPU *cpu = ARM_CPU(first_cpu); struct arm_boot_info *info = &vms->bootinfo; AddressSpace *as = arm_boot_address_space(cpu, info); @@ -1385,7 +1389,7 @@ void virt_machine_done(Notifier *notifier, void *data) vms->memmap[VIRT_PLATFORM_BUS].size, vms->irqmap[VIRT_PLATFORM_BUS]); } - if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as) < 0) { + if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as, ms) < 0) { exit(1); } @@ -1711,16 +1715,13 @@ static void machvirt_init(MachineState *machine) create_platform_bus(vms, pic); vms->bootinfo.ram_size = machine->ram_size; - vms->bootinfo.kernel_filename = machine->kernel_filename; - vms->bootinfo.kernel_cmdline = machine->kernel_cmdline; - vms->bootinfo.initrd_filename = machine->initrd_filename; vms->bootinfo.nb_cpus = smp_cpus; vms->bootinfo.board_id = -1; vms->bootinfo.loader_start = vms->memmap[VIRT_MEM].base; vms->bootinfo.get_dtb = machvirt_dtb; vms->bootinfo.skip_dtb_autoload = true; vms->bootinfo.firmware_loaded = firmware_loaded; - arm_load_kernel(ARM_CPU(first_cpu), &vms->bootinfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &vms->bootinfo); vms->machine_done.notify = virt_machine_done; qemu_add_machine_init_done_notifier(&vms->machine_done); @@ -1848,7 +1849,7 @@ virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index) static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx) { - return idx % nb_numa_nodes; + return idx % ms->numa_state->num_nodes; } static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms) diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c index 89da34808b..c14774e542 100644 --- a/hw/arm/xilinx_zynq.c +++ b/hw/arm/xilinx_zynq.c @@ -158,9 +158,6 @@ static inline void zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq, static void zynq_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; ARMCPU *cpu; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *ext_ram = g_new(MemoryRegion, 1); @@ -303,16 +300,13 @@ static void zynq_init(MachineState *machine) sysbus_mmio_map(busdev, 0, 0xF8007000); zynq_binfo.ram_size = ram_size; - zynq_binfo.kernel_filename = kernel_filename; - zynq_binfo.kernel_cmdline = kernel_cmdline; - zynq_binfo.initrd_filename = initrd_filename; zynq_binfo.nb_cpus = 1; zynq_binfo.board_id = 0xd32; zynq_binfo.loader_start = 0; zynq_binfo.board_setup_addr = BOARD_SETUP_ADDR; zynq_binfo.write_board_setup = zynq_write_board_setup; - arm_load_kernel(ARM_CPU(first_cpu), &zynq_binfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &zynq_binfo); } static void zynq_machine_init(MachineClass *mc) diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c index f95fde2309..462493c467 100644 --- a/hw/arm/xlnx-versal-virt.c +++ b/hw/arm/xlnx-versal-virt.c @@ -441,14 +441,11 @@ static void versal_virt_init(MachineState *machine) 0, &s->soc.fpd.apu.mr, 0); s->binfo.ram_size = machine->ram_size; - s->binfo.kernel_filename = machine->kernel_filename; - s->binfo.kernel_cmdline = machine->kernel_cmdline; - s->binfo.initrd_filename = machine->initrd_filename; s->binfo.loader_start = 0x0; s->binfo.get_dtb = versal_virt_get_dtb; s->binfo.modify_dtb = versal_virt_modify_dtb; if (machine->kernel_filename) { - arm_load_kernel(s->soc.fpd.apu.cpu[0], &s->binfo); + arm_load_kernel(s->soc.fpd.apu.cpu[0], machine, &s->binfo); } else { AddressSpace *as = arm_boot_address_space(s->soc.fpd.apu.cpu[0], &s->binfo); @@ -457,7 +454,7 @@ static void versal_virt_init(MachineState *machine) s->binfo.loader_start = 0x1000; s->binfo.dtb_limit = 0x1000000; if (arm_load_dtb(s->binfo.loader_start, - &s->binfo, s->binfo.dtb_limit, as) < 0) { + &s->binfo, s->binfo.dtb_limit, as, machine) < 0) { exit(EXIT_FAILURE); } } diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c index 044d3394c0..53cfe7c1f1 100644 --- a/hw/arm/xlnx-zcu102.c +++ b/hw/arm/xlnx-zcu102.c @@ -171,11 +171,8 @@ static void xlnx_zcu102_init(MachineState *machine) /* TODO create and connect IDE devices for ide_drive_get() */ xlnx_zcu102_binfo.ram_size = ram_size; - xlnx_zcu102_binfo.kernel_filename = machine->kernel_filename; - xlnx_zcu102_binfo.kernel_cmdline = machine->kernel_cmdline; - xlnx_zcu102_binfo.initrd_filename = machine->initrd_filename; xlnx_zcu102_binfo.loader_start = 0; - arm_load_kernel(s->soc.boot_cpu_ptr, &xlnx_zcu102_binfo); + arm_load_kernel(s->soc.boot_cpu_ptr, machine, &xlnx_zcu102_binfo); } static void xlnx_zcu102_machine_instance_init(Object *obj) diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c index 0f587e63d3..fb03c60ebb 100644 --- a/hw/arm/xlnx-zynqmp.c +++ b/hw/arm/xlnx-zynqmp.c @@ -196,8 +196,8 @@ static void xlnx_zynqmp_create_rpu(MachineState *ms, XlnxZynqMPState *s, object_initialize_child(OBJECT(&s->rpu_cluster), "rpu-cpu[*]", &s->rpu_cpu[i], sizeof(s->rpu_cpu[i]), - "cortex-r5f-" TYPE_ARM_CPU, &error_abort, - NULL); + ARM_CPU_TYPE_NAME("cortex-r5f"), + &error_abort, NULL); name = object_get_canonical_path_component(OBJECT(&s->rpu_cpu[i])); if (strcmp(name, boot_cpu)) { @@ -237,8 +237,8 @@ static void xlnx_zynqmp_init(Object *obj) for (i = 0; i < num_apus; i++) { object_initialize_child(OBJECT(&s->apu_cluster), "apu-cpu[*]", &s->apu_cpu[i], sizeof(s->apu_cpu[i]), - "cortex-a53-" TYPE_ARM_CPU, &error_abort, - NULL); + ARM_CPU_TYPE_NAME("cortex-a53"), + &error_abort, NULL); } sysbus_init_child_obj(obj, "gic", &s->gic, sizeof(s->gic), diff --git a/hw/arm/z2.c b/hw/arm/z2.c index 3923b87e4c..34794fe3ae 100644 --- a/hw/arm/z2.c +++ b/hw/arm/z2.c @@ -296,9 +296,6 @@ static const TypeInfo aer915_info = { static void z2_init(MachineState *machine) { - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; MemoryRegion *address_space_mem = get_system_memory(); uint32_t sector_len = 0x10000; PXA2xxState *mpu; @@ -352,11 +349,8 @@ static void z2_init(MachineState *machine) qdev_connect_gpio_out(mpu->gpio, Z2_GPIO_LCD_CS, qemu_allocate_irq(z2_lcd_cs, z2_lcd, 0)); - z2_binfo.kernel_filename = kernel_filename; - z2_binfo.kernel_cmdline = kernel_cmdline; - z2_binfo.initrd_filename = initrd_filename; z2_binfo.board_id = 0x6dd; - arm_load_kernel(mpu->cpu, &z2_binfo); + arm_load_kernel(mpu->cpu, machine, &z2_binfo); } static void z2_machine_init(MachineClass *mc) diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c index 1f66bda346..cd970cc4c5 100644 --- a/hw/core/machine-hmp-cmds.c +++ b/hw/core/machine-hmp-cmds.c @@ -23,6 +23,7 @@ #include "qapi/string-output-visitor.h" #include "qemu/error-report.h" #include "sysemu/numa.h" +#include "hw/boards.h" void hmp_info_cpus(Monitor *mon, const QDict *qdict) { @@ -139,15 +140,21 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) void hmp_info_numa(Monitor *mon, const QDict *qdict) { - int i; + int i, nb_numa_nodes; NumaNodeMem *node_mem; CpuInfoList *cpu_list, *cpu; + MachineState *ms = MACHINE(qdev_get_machine()); + + nb_numa_nodes = ms->numa_state ? ms->numa_state->num_nodes : 0; + monitor_printf(mon, "%d nodes\n", nb_numa_nodes); + if (!nb_numa_nodes) { + return; + } cpu_list = qmp_query_cpus(&error_abort); node_mem = g_new0(NumaNodeMem, nb_numa_nodes); - query_numa_node_mem(node_mem); - monitor_printf(mon, "%d nodes\n", nb_numa_nodes); + query_numa_node_mem(node_mem, ms); for (i = 0; i < nb_numa_nodes; i++) { monitor_printf(mon, "node %d cpus:", i); for (cpu = cpu_list; cpu; cpu = cpu->next) { diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c index 15cf7c62e3..eed5aeb2f7 100644 --- a/hw/core/machine-qmp-cmds.c +++ b/hw/core/machine-qmp-cmds.c @@ -230,6 +230,10 @@ MachineInfoList *qmp_query_machines(Error **errp) info->hotpluggable_cpus = mc->has_hotpluggable_cpus; info->numa_mem_supported = mc->numa_mem_supported; info->deprecated = !!mc->deprecation_reason; + if (mc->default_cpu_type) { + info->default_cpu_type = g_strdup(mc->default_cpu_type); + info->has_default_cpu_type = true; + } entry = g_malloc0(sizeof(*entry)); entry->value = info; diff --git a/hw/core/machine.c b/hw/core/machine.c index 83cd1bfeec..c5e0d52fbc 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -956,6 +956,9 @@ static void machine_initfn(Object *obj) NULL); } + if (mc->numa_mem_supported) { + ms->numa_state = g_new0(NumaState, 1); + } /* Register notifier when init is done for sysbus sanity checks */ ms->sysbus_notifier.notify = machine_init_notify; @@ -976,6 +979,7 @@ static void machine_finalize(Object *obj) g_free(ms->firmware); g_free(ms->device_memory); g_free(ms->nvdimms_state); + g_free(ms->numa_state); } bool machine_usb(MachineState *machine) @@ -1050,7 +1054,7 @@ static void machine_numa_finish_cpu_init(MachineState *machine) MachineClass *mc = MACHINE_GET_CLASS(machine); const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(machine); - assert(nb_numa_nodes); + assert(machine->numa_state->num_nodes); for (i = 0; i < possible_cpus->len; i++) { if (possible_cpus->cpus[i].props.has_node_id) { break; @@ -1096,9 +1100,11 @@ void machine_run_board_init(MachineState *machine) { MachineClass *machine_class = MACHINE_GET_CLASS(machine); - numa_complete_configuration(machine); - if (nb_numa_nodes) { - machine_numa_finish_cpu_init(machine); + if (machine_class->numa_mem_supported) { + numa_complete_configuration(machine); + if (machine->numa_state->num_nodes) { + machine_numa_finish_cpu_init(machine); + } } /* If the machine supports the valid_cpu_types check and the user diff --git a/hw/core/numa.c b/hw/core/numa.c index 4f7e4628a0..4dfec5c95b 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -55,10 +55,6 @@ static int have_mem; static int max_numa_nodeid; /* Highest specified NUMA node ID, plus one. * For all nodes, nodeid < max_numa_nodeid */ -int nb_numa_nodes; -bool have_numa_distance; -NodeInfo numa_info[MAX_NODES]; - static void parse_numa_node(MachineState *ms, NumaNodeOptions *node, Error **errp) @@ -68,11 +64,12 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node, uint16List *cpus = NULL; MachineClass *mc = MACHINE_GET_CLASS(ms); unsigned int max_cpus = ms->smp.max_cpus; + NodeInfo *numa_info = ms->numa_state->nodes; if (node->has_nodeid) { nodenr = node->nodeid; } else { - nodenr = nb_numa_nodes; + nodenr = ms->numa_state->num_nodes; } if (nodenr >= MAX_NODES) { @@ -138,14 +135,16 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node, } numa_info[nodenr].present = true; max_numa_nodeid = MAX(max_numa_nodeid, nodenr + 1); - nb_numa_nodes++; + ms->numa_state->num_nodes++; } -static void parse_numa_distance(NumaDistOptions *dist, Error **errp) +static +void parse_numa_distance(MachineState *ms, NumaDistOptions *dist, Error **errp) { uint16_t src = dist->src; uint16_t dst = dist->dst; uint8_t val = dist->val; + NodeInfo *numa_info = ms->numa_state->nodes; if (src >= MAX_NODES || dst >= MAX_NODES) { error_setg(errp, "Parameter '%s' expects an integer between 0 and %d", @@ -173,12 +172,18 @@ static void parse_numa_distance(NumaDistOptions *dist, Error **errp) } numa_info[src].distance[dst] = val; - have_numa_distance = true; + ms->numa_state->have_numa_distance = true; } void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp) { Error *err = NULL; + MachineClass *mc = MACHINE_GET_CLASS(ms); + + if (!mc->numa_mem_supported) { + error_setg(errp, "NUMA is not supported by this machine-type"); + goto end; + } switch (object->type) { case NUMA_OPTIONS_TYPE_NODE: @@ -188,7 +193,7 @@ void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp) } break; case NUMA_OPTIONS_TYPE_DIST: - parse_numa_distance(&object->u.dist, &err); + parse_numa_distance(ms, &object->u.dist, &err); if (err) { goto end; } @@ -198,7 +203,7 @@ void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp) error_setg(&err, "Missing mandatory node-id property"); goto end; } - if (!numa_info[object->u.cpu.node_id].present) { + if (!ms->numa_state->nodes[object->u.cpu.node_id].present) { error_setg(&err, "Invalid node-id=%" PRId64 ", NUMA node must be " "defined with -numa node,nodeid=ID before it's used with " "-numa cpu,node-id=ID", object->u.cpu.node_id); @@ -253,10 +258,12 @@ end: * distance from a node to itself is always NUMA_DISTANCE_MIN, * so providing it is never necessary. */ -static void validate_numa_distance(void) +static void validate_numa_distance(MachineState *ms) { int src, dst; bool is_asymmetrical = false; + int nb_numa_nodes = ms->numa_state->num_nodes; + NodeInfo *numa_info = ms->numa_state->nodes; for (src = 0; src < nb_numa_nodes; src++) { for (dst = src; dst < nb_numa_nodes; dst++) { @@ -294,17 +301,18 @@ static void validate_numa_distance(void) } } -static void complete_init_numa_distance(void) +static void complete_init_numa_distance(MachineState *ms) { int src, dst; + NodeInfo *numa_info = ms->numa_state->nodes; /* Fixup NUMA distance by symmetric policy because if it is an * asymmetric distance table, it should be a complete table and * there would not be any missing distance except local node, which * is verified by validate_numa_distance above. */ - for (src = 0; src < nb_numa_nodes; src++) { - for (dst = 0; dst < nb_numa_nodes; dst++) { + for (src = 0; src < ms->numa_state->num_nodes; src++) { + for (dst = 0; dst < ms->numa_state->num_nodes; dst++) { if (numa_info[src].distance[dst] == 0) { if (src == dst) { numa_info[src].distance[dst] = NUMA_DISTANCE_MIN; @@ -356,6 +364,7 @@ void numa_complete_configuration(MachineState *ms) { int i; MachineClass *mc = MACHINE_GET_CLASS(ms); + NodeInfo *numa_info = ms->numa_state->nodes; /* * If memory hotplug is enabled (slots > 0) but without '-numa' @@ -370,7 +379,7 @@ void numa_complete_configuration(MachineState *ms) * * Enable NUMA implicitly by adding a new NUMA node automatically. */ - if (ms->ram_slots > 0 && nb_numa_nodes == 0 && + if (ms->ram_slots > 0 && ms->numa_state->num_nodes == 0 && mc->auto_enable_numa_with_memhp) { NumaNodeOptions node = { }; parse_numa_node(ms, &node, &error_abort); @@ -388,26 +397,27 @@ void numa_complete_configuration(MachineState *ms) } /* This must be always true if all nodes are present: */ - assert(nb_numa_nodes == max_numa_nodeid); + assert(ms->numa_state->num_nodes == max_numa_nodeid); - if (nb_numa_nodes > 0) { + if (ms->numa_state->num_nodes > 0) { uint64_t numa_total; - if (nb_numa_nodes > MAX_NODES) { - nb_numa_nodes = MAX_NODES; + if (ms->numa_state->num_nodes > MAX_NODES) { + ms->numa_state->num_nodes = MAX_NODES; } /* If no memory size is given for any node, assume the default case * and distribute the available memory equally across all nodes */ - for (i = 0; i < nb_numa_nodes; i++) { + for (i = 0; i < ms->numa_state->num_nodes; i++) { if (numa_info[i].node_mem != 0) { break; } } - if (i == nb_numa_nodes) { + if (i == ms->numa_state->num_nodes) { assert(mc->numa_auto_assign_ram); - mc->numa_auto_assign_ram(mc, numa_info, nb_numa_nodes, ram_size); + mc->numa_auto_assign_ram(mc, numa_info, + ms->numa_state->num_nodes, ram_size); if (!qtest_enabled()) { warn_report("Default splitting of RAM between nodes is deprecated," " Use '-numa node,memdev' to explictly define RAM" @@ -416,7 +426,7 @@ void numa_complete_configuration(MachineState *ms) } numa_total = 0; - for (i = 0; i < nb_numa_nodes; i++) { + for (i = 0; i < ms->numa_state->num_nodes; i++) { numa_total += numa_info[i].node_mem; } if (numa_total != ram_size) { @@ -438,12 +448,12 @@ void numa_complete_configuration(MachineState *ms) * asymmetric. In this case, the distances for both directions * of all node pairs are required. */ - if (have_numa_distance) { + if (ms->numa_state->have_numa_distance) { /* Validate enough NUMA distance information was provided. */ - validate_numa_distance(); + validate_numa_distance(ms); /* Validation succeeded, now fill in any missing distances. */ - complete_init_numa_distance(); + complete_init_numa_distance(ms); } } } @@ -510,16 +520,18 @@ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner, { uint64_t addr = 0; int i; + MachineState *ms = MACHINE(qdev_get_machine()); - if (nb_numa_nodes == 0 || !have_memdevs) { + if (ms->numa_state == NULL || + ms->numa_state->num_nodes == 0 || !have_memdevs) { allocate_system_memory_nonnuma(mr, owner, name, ram_size); return; } memory_region_init(mr, owner, name, ram_size); - for (i = 0; i < nb_numa_nodes; i++) { - uint64_t size = numa_info[i].node_mem; - HostMemoryBackend *backend = numa_info[i].node_memdev; + for (i = 0; i < ms->numa_state->num_nodes; i++) { + uint64_t size = ms->numa_state->nodes[i].node_mem; + HostMemoryBackend *backend = ms->numa_state->nodes[i].node_memdev; if (!backend) { continue; } @@ -575,17 +587,17 @@ static void numa_stat_memory_devices(NumaNodeMem node_mem[]) qapi_free_MemoryDeviceInfoList(info_list); } -void query_numa_node_mem(NumaNodeMem node_mem[]) +void query_numa_node_mem(NumaNodeMem node_mem[], MachineState *ms) { int i; - if (nb_numa_nodes <= 0) { + if (ms->numa_state == NULL || ms->numa_state->num_nodes <= 0) { return; } numa_stat_memory_devices(node_mem); - for (i = 0; i < nb_numa_nodes; i++) { - node_mem[i].node_mem += numa_info[i].node_mem; + for (i = 0; i < ms->numa_state->num_nodes; i++) { + node_mem[i].node_mem += ms->numa_state->nodes[i].node_mem; } } diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c index d176df6d44..a254275b64 100644 --- a/hw/dma/xilinx_axidma.c +++ b/hw/dma/xilinx_axidma.c @@ -566,14 +566,14 @@ static void xilinx_axidma_init(Object *obj) XilinxAXIDMA *s = XILINX_AXI_DMA(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); - object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev), - TYPE_XILINX_AXI_DMA_DATA_STREAM); - object_initialize(&s->rx_control_dev, sizeof(s->rx_control_dev), - TYPE_XILINX_AXI_DMA_CONTROL_STREAM); - object_property_add_child(OBJECT(s), "axistream-connected-target", - (Object *)&s->rx_data_dev, &error_abort); - object_property_add_child(OBJECT(s), "axistream-control-connected-target", - (Object *)&s->rx_control_dev, &error_abort); + object_initialize_child(OBJECT(s), "axistream-connected-target", + &s->rx_data_dev, sizeof(s->rx_data_dev), + TYPE_XILINX_AXI_DMA_DATA_STREAM, &error_abort, + NULL); + object_initialize_child(OBJECT(s), "axistream-control-connected-target", + &s->rx_control_dev, sizeof(s->rx_control_dev), + TYPE_XILINX_AXI_DMA_CONTROL_STREAM, &error_abort, + NULL); sysbus_init_irq(sbd, &s->streams[0].irq); sysbus_init_irq(sbd, &s->streams[1].irq); diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 034e413fd0..e54e571a75 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -2694,9 +2694,9 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) if (pcms->numa_nodes) { acpi_add_table(table_offsets, tables_blob); build_srat(tables_blob, tables->linker, machine); - if (have_numa_distance) { + if (machine->numa_state->have_numa_distance) { acpi_add_table(table_offsets, tables_blob); - build_slit(tables_blob, tables->linker); + build_slit(tables_blob, tables->linker, machine); } } if (acpi_get_mcfg(&mcfg)) { diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c index 80c133a724..2c59b6894b 100644 --- a/hw/i386/kvm/clock.c +++ b/hw/i386/kvm/clock.c @@ -41,6 +41,9 @@ typedef struct KVMClockState { uint64_t clock; bool clock_valid; + /* whether the 'clock' value was obtained in the 'paused' state */ + bool runstate_paused; + /* whether machine type supports reliable KVM_GET_CLOCK */ bool mach_use_reliable_get_clock; @@ -202,6 +205,8 @@ static void kvmclock_vm_state_change(void *opaque, int running, return; } + s->runstate_paused = runstate_check(RUN_STATE_PAUSED); + kvm_synchronize_all_tsc(); kvm_update_clock(s); @@ -260,9 +265,9 @@ static int kvmclock_pre_load(void *opaque) } /* - * When migrating, read the clock just before migration, - * so that the guest clock counts during the events - * between: + * When migrating a running guest, read the clock just + * before migration, so that the guest clock counts + * during the events between: * * * vm_stop() * * @@ -277,7 +282,9 @@ static int kvmclock_pre_save(void *opaque) { KVMClockState *s = opaque; - kvm_update_clock(s); + if (!s->runstate_paused) { + kvm_update_clock(s); + } return 0; } diff --git a/hw/i386/pc.c b/hw/i386/pc.c index c14ed86439..bad866fe44 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1002,6 +1002,8 @@ static FWCfgState *bochs_bios_init(AddressSpace *as, PCMachineState *pcms) int i; const CPUArchIdList *cpus; MachineClass *mc = MACHINE_GET_CLASS(pcms); + MachineState *ms = MACHINE(pcms); + int nb_numa_nodes = ms->numa_state->num_nodes; fw_cfg = fw_cfg_init_io_dma(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4, as); fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus); @@ -1044,7 +1046,7 @@ static FWCfgState *bochs_bios_init(AddressSpace *as, PCMachineState *pcms) } for (i = 0; i < nb_numa_nodes; i++) { numa_fw_cfg[pcms->apic_id_limit + 1 + i] = - cpu_to_le64(numa_info[i].node_mem); + cpu_to_le64(ms->numa_state->nodes[i].node_mem); } fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg, (1 + pcms->apic_id_limit + nb_numa_nodes) * @@ -1774,13 +1776,14 @@ void pc_machine_done(Notifier *notifier, void *data) void pc_guest_info_init(PCMachineState *pcms) { int i; + MachineState *ms = MACHINE(pcms); pcms->apic_xrupt_override = kvm_allows_irq0_override(); - pcms->numa_nodes = nb_numa_nodes; + pcms->numa_nodes = ms->numa_state->num_nodes; pcms->node_mem = g_malloc0(pcms->numa_nodes * sizeof *pcms->node_mem); - for (i = 0; i < nb_numa_nodes; i++) { - pcms->node_mem[i] = numa_info[i].node_mem; + for (i = 0; i < ms->numa_state->num_nodes; i++) { + pcms->node_mem[i] = ms->numa_state->nodes[i].node_mem; } pcms->machine_done.notify = pc_machine_done; @@ -2418,6 +2421,14 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, int max_socket = (ms->smp.max_cpus - 1) / smp_threads / smp_cores / pcms->smp_dies; + /* + * die-id was optional in QEMU 4.0 and older, so keep it optional + * if there's only one die per socket. + */ + if (cpu->die_id < 0 && pcms->smp_dies == 1) { + cpu->die_id = 0; + } + if (cpu->socket_id < 0) { error_setg(errp, "CPU socket-id is not set"); return; @@ -2425,9 +2436,13 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, error_setg(errp, "Invalid CPU socket-id: %u must be in range 0:%u", cpu->socket_id, max_socket); return; + } + if (cpu->die_id < 0) { + error_setg(errp, "CPU die-id is not set"); + return; } else if (cpu->die_id > pcms->smp_dies - 1) { error_setg(errp, "Invalid CPU die-id: %u must be in range 0:%u", - cpu->die_id, max_socket); + cpu->die_id, pcms->smp_dies - 1); return; } if (cpu->core_id < 0) { @@ -2869,7 +2884,7 @@ static int64_t pc_get_default_cpu_node_id(const MachineState *ms, int idx) x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id, pcms->smp_dies, ms->smp.cores, ms->smp.threads, &topo); - return topo.pkg_id % nb_numa_nodes; + return topo.pkg_id % ms->numa_state->num_nodes; } static const CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *ms) @@ -2901,8 +2916,10 @@ static const CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *ms) ms->smp.threads, &topo); ms->possible_cpus->cpus[i].props.has_socket_id = true; ms->possible_cpus->cpus[i].props.socket_id = topo.pkg_id; - ms->possible_cpus->cpus[i].props.has_die_id = true; - ms->possible_cpus->cpus[i].props.die_id = topo.die_id; + if (pcms->smp_dies > 1) { + ms->possible_cpus->cpus[i].props.has_die_id = true; + ms->possible_cpus->cpus[i].props.die_id = topo.die_id; + } ms->possible_cpus->cpus[i].props.has_core_id = true; ms->possible_cpus->cpus[i].props.core_id = topo.core_id; ms->possible_cpus->cpus[i].props.has_thread_id = true; diff --git a/hw/i386/vmmouse.c b/hw/i386/vmmouse.c index 012ab90396..41ad91ad53 100644 --- a/hw/i386/vmmouse.c +++ b/hw/i386/vmmouse.c @@ -258,6 +258,7 @@ static void vmmouse_reset(DeviceState *d) VMMouseState *s = VMMOUSE(d); s->queue_size = VMMOUSE_QUEUE_SIZE; + s->nb_queue = 0; vmmouse_disable(s); } diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index 7c324a1329..99e2faf01b 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -172,6 +172,8 @@ static void pc_dimm_realize(DeviceState *dev, Error **errp) { PCDIMMDevice *dimm = PC_DIMM(dev); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); + MachineState *ms = MACHINE(qdev_get_machine()); + int nb_numa_nodes = ms->numa_state->num_nodes; if (!dimm->hostmem) { error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property is not set"); diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c index d8716a1f73..2c8c065401 100644 --- a/hw/net/xilinx_axienet.c +++ b/hw/net/xilinx_axienet.c @@ -994,15 +994,14 @@ static void xilinx_enet_init(Object *obj) XilinxAXIEnet *s = XILINX_AXI_ENET(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); - object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev), - TYPE_XILINX_AXI_ENET_DATA_STREAM); - object_initialize(&s->rx_control_dev, sizeof(s->rx_control_dev), - TYPE_XILINX_AXI_ENET_CONTROL_STREAM); - object_property_add_child(OBJECT(s), "axistream-connected-target", - (Object *)&s->rx_data_dev, &error_abort); - object_property_add_child(OBJECT(s), "axistream-control-connected-target", - (Object *)&s->rx_control_dev, &error_abort); - + object_initialize_child(OBJECT(s), "axistream-connected-target", + &s->rx_data_dev, sizeof(s->rx_data_dev), + TYPE_XILINX_AXI_ENET_DATA_STREAM, &error_abort, + NULL); + object_initialize_child(OBJECT(s), "axistream-control-connected-target", + &s->rx_control_dev, sizeof(s->rx_control_dev), + TYPE_XILINX_AXI_ENET_CONTROL_STREAM, &error_abort, + NULL); sysbus_init_irq(sbd, &s->irq); memory_region_init_io(&s->iomem, OBJECT(s), &enet_ops, s, "enet", 0x40000); diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c index 06a7c018d7..0592818447 100644 --- a/hw/pci-bridge/pci_expander_bridge.c +++ b/hw/pci-bridge/pci_expander_bridge.c @@ -21,6 +21,7 @@ #include "qemu/error-report.h" #include "qemu/module.h" #include "sysemu/numa.h" +#include "hw/boards.h" #define TYPE_PXB_BUS "pxb-bus" #define PXB_BUS(obj) OBJECT_CHECK(PXBBus, (obj), TYPE_PXB_BUS) @@ -213,9 +214,15 @@ static void pxb_dev_realize_common(PCIDevice *dev, bool pcie, Error **errp) PCIBus *bus; const char *dev_name = NULL; Error *local_err = NULL; + MachineState *ms = MACHINE(qdev_get_machine()); + + if (ms->numa_state == NULL) { + error_setg(errp, "NUMA is not supported by this machine-type"); + return; + } if (pxb->numa_node != NUMA_NODE_UNASSIGNED && - pxb->numa_node >= nb_numa_nodes) { + pxb->numa_node >= ms->numa_state->num_nodes) { error_setg(errp, "Illegal numa node %d", pxb->numa_node); return; } diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index d95086fbbd..3f08db7b9e 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -434,9 +434,14 @@ static void pnv_dt_isa(PnvMachineState *pnv, void *fdt) .fdt = fdt, .offset = isa_offset, }; + uint32_t phandle; _FDT((fdt_setprop(fdt, isa_offset, "primary", NULL, 0))); + phandle = qemu_fdt_alloc_phandle(fdt); + assert(phandle > 0); + _FDT((fdt_setprop_cell(fdt, isa_offset, "phandle", phandle))); + /* ISA devices are not necessarily parented to the ISA bus so we * can not use object_child_foreach() */ qbus_walk_children(BUS(pnv->isa_bus), pnv_dt_isa_device, NULL, NULL, NULL, @@ -600,9 +605,20 @@ static void pnv_chip_power9_pic_print_info(PnvChip *chip, Monitor *mon) pnv_psi_pic_print_info(&chip9->psi, mon); } +static bool pnv_match_cpu(const char *default_type, const char *cpu_type) +{ + PowerPCCPUClass *ppc_default = + POWERPC_CPU_CLASS(object_class_by_name(default_type)); + PowerPCCPUClass *ppc = + POWERPC_CPU_CLASS(object_class_by_name(cpu_type)); + + return ppc_default->pvr_match(ppc_default, ppc->pvr); +} + static void pnv_init(MachineState *machine) { PnvMachineState *pnv = PNV_MACHINE(machine); + MachineClass *mc = MACHINE_GET_CLASS(machine); MemoryRegion *ram; char *fw_filename; long fw_size; @@ -662,13 +678,23 @@ static void pnv_init(MachineState *machine) } } + /* + * Check compatibility of the specified CPU with the machine + * default. + */ + if (!pnv_match_cpu(mc->default_cpu_type, machine->cpu_type)) { + error_report("invalid CPU model '%s' for %s machine", + machine->cpu_type, mc->name); + exit(1); + } + /* Create the processor chips */ i = strlen(machine->cpu_type) - strlen(POWERPC_CPU_TYPE_SUFFIX); chip_typename = g_strdup_printf(PNV_CHIP_TYPE_NAME("%.*s"), i, machine->cpu_type); if (!object_class_by_name(chip_typename)) { - error_report("invalid CPU model '%.*s' for %s machine", - i, machine->cpu_type, MACHINE_GET_CLASS(machine)->name); + error_report("invalid chip model '%.*s' for %s machine", + i, machine->cpu_type, mc->name); exit(1); } @@ -1346,25 +1372,47 @@ static void pnv_machine_class_props_init(ObjectClass *oc) NULL); } -static void pnv_machine_class_init(ObjectClass *oc, void *data) +static void pnv_machine_power8_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); XICSFabricClass *xic = XICS_FABRIC_CLASS(oc); + + mc->desc = "IBM PowerNV (Non-Virtualized) POWER8"; + mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0"); + + xic->icp_get = pnv_icp_get; + xic->ics_get = pnv_ics_get; + xic->ics_resend = pnv_ics_resend; +} + +static void pnv_machine_power9_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->desc = "IBM PowerNV (Non-Virtualized) POWER9"; + mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.0"); + + mc->alias = "powernv"; +} + +static void pnv_machine_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc); mc->desc = "IBM PowerNV (Non-Virtualized)"; mc->init = pnv_init; mc->reset = pnv_reset; mc->max_cpus = MAX_CPUS; - mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0"); mc->block_default_type = IF_IDE; /* Pnv provides a AHCI device for * storage */ mc->no_parallel = 1; mc->default_boot_order = NULL; - mc->default_ram_size = 1 * GiB; - xic->icp_get = pnv_icp_get; - xic->ics_get = pnv_ics_get; - xic->ics_resend = pnv_ics_resend; + /* + * RAM defaults to less than 2048 for 32-bit hosts, and large + * enough to fit the maximum initrd size at it's load address + */ + mc->default_ram_size = INITRD_LOAD_ADDR + INITRD_MAX_SIZE; ispc->print_info = pnv_pic_print_info; pnv_machine_class_props_init(oc); @@ -1384,10 +1432,27 @@ static void pnv_machine_class_init(ObjectClass *oc, void *data) .parent = TYPE_PNV9_CHIP, \ } +#define DEFINE_PNV_MACHINE_TYPE(cpu, class_initfn) \ + { \ + .name = MACHINE_TYPE_NAME(cpu), \ + .parent = TYPE_PNV_MACHINE, \ + .instance_size = sizeof(PnvMachineState), \ + .instance_init = pnv_machine_instance_init, \ + .class_init = class_initfn, \ + .interfaces = (InterfaceInfo[]) { \ + { TYPE_XICS_FABRIC }, \ + { TYPE_INTERRUPT_STATS_PROVIDER }, \ + { }, \ + }, \ + } + static const TypeInfo types[] = { + DEFINE_PNV_MACHINE_TYPE("powernv8", pnv_machine_power8_class_init), + DEFINE_PNV_MACHINE_TYPE("powernv9", pnv_machine_power9_class_init), { .name = TYPE_PNV_MACHINE, .parent = TYPE_MACHINE, + .abstract = true, .instance_size = sizeof(PnvMachineState), .instance_init = pnv_machine_instance_init, .class_init = pnv_machine_class_init, diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c index 0e31c5786b..67aab98fef 100644 --- a/hw/ppc/pnv_xscom.c +++ b/hw/ppc/pnv_xscom.c @@ -106,6 +106,16 @@ static uint64_t xscom_read_default(PnvChip *chip, uint32_t pcba) case 0x201302a: /* CAPP stuff */ case 0x2013801: /* CAPP stuff */ case 0x2013802: /* CAPP stuff */ + + /* P9 CAPP regs */ + case 0x2010841: + case 0x2010842: + case 0x201082a: + case 0x2010828: + case 0x4010841: + case 0x4010842: + case 0x401082a: + case 0x4010828: return 0; default: return -1; @@ -138,6 +148,16 @@ static bool xscom_write_default(PnvChip *chip, uint32_t pcba, uint64_t val) case 0x2013801: /* CAPP stuff */ case 0x2013802: /* CAPP stuff */ + /* P9 CAPP regs */ + case 0x2010841: + case 0x2010842: + case 0x201082a: + case 0x2010828: + case 0x4010841: + case 0x4010842: + case 0x401082a: + case 0x4010828: + /* P8 PRD registers */ case PRD_P8_IPOLL_REG_MASK: case PRD_P8_IPOLL_REG_STATUS: diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index baedadf20b..222a325056 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -336,7 +336,7 @@ static int spapr_fixup_cpu_dt(void *fdt, SpaprMachineState *spapr) return ret; } - if (nb_numa_nodes > 1) { + if (ms->numa_state->num_nodes > 1) { ret = spapr_fixup_cpu_numa_dt(fdt, offset, cpu); if (ret < 0) { return ret; @@ -356,11 +356,11 @@ static int spapr_fixup_cpu_dt(void *fdt, SpaprMachineState *spapr) static hwaddr spapr_node0_size(MachineState *machine) { - if (nb_numa_nodes) { + if (machine->numa_state->num_nodes) { int i; - for (i = 0; i < nb_numa_nodes; ++i) { - if (numa_info[i].node_mem) { - return MIN(pow2floor(numa_info[i].node_mem), + for (i = 0; i < machine->numa_state->num_nodes; ++i) { + if (machine->numa_state->nodes[i].node_mem) { + return MIN(pow2floor(machine->numa_state->nodes[i].node_mem), machine->ram_size); } } @@ -403,12 +403,12 @@ static int spapr_populate_memory(SpaprMachineState *spapr, void *fdt) { MachineState *machine = MACHINE(spapr); hwaddr mem_start, node_size; - int i, nb_nodes = nb_numa_nodes; - NodeInfo *nodes = numa_info; + int i, nb_nodes = machine->numa_state->num_nodes; + NodeInfo *nodes = machine->numa_state->nodes; NodeInfo ramnode; /* No NUMA nodes, assume there is just one node with whole RAM */ - if (!nb_numa_nodes) { + if (!nb_nodes) { nb_nodes = 1; ramnode.node_mem = machine->ram_size; nodes = &ramnode; @@ -559,7 +559,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset, _FDT((fdt_setprop(fdt, offset, "ibm,pft-size", pft_size_prop, sizeof(pft_size_prop)))); - if (nb_numa_nodes > 1) { + if (ms->numa_state->num_nodes > 1) { _FDT(spapr_fixup_cpu_numa_dt(fdt, offset, cpu)); } @@ -866,6 +866,7 @@ static int spapr_populate_drmem_v1(SpaprMachineState *spapr, void *fdt, static int spapr_populate_drconf_memory(SpaprMachineState *spapr, void *fdt) { MachineState *machine = MACHINE(spapr); + int nb_numa_nodes = machine->numa_state->num_nodes; int ret, i, offset; uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE; uint32_t prop_lmb_size[] = {0, cpu_to_be32(lmb_size)}; @@ -1168,6 +1169,7 @@ static void spapr_dt_ov5_platform_support(SpaprMachineState *spapr, void *fdt, static void spapr_dt_chosen(SpaprMachineState *spapr, void *fdt) { MachineState *machine = MACHINE(spapr); + SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine); int chosen; const char *boot_device = machine->boot_order; char *stdout_path = spapr_vio_stdout_path(spapr->vio_bus); @@ -1225,6 +1227,11 @@ static void spapr_dt_chosen(SpaprMachineState *spapr, void *fdt) _FDT(fdt_setprop_string(fdt, chosen, "stdout-path", stdout_path)); } + /* We can deal with BAR reallocation just fine, advertise it to the guest */ + if (smc->linux_pci_probe) { + _FDT(fdt_setprop_cell(fdt, chosen, "linux,pci-probe-only", 0)); + } + spapr_dt_ov5_platform_support(spapr, fdt, chosen); g_free(stdout_path); @@ -1741,7 +1748,7 @@ static void spapr_machine_reset(MachineState *machine) * The final value of spapr->gpu_numa_id is going to be written to * max-associativity-domains in spapr_build_fdt(). */ - spapr->gpu_numa_id = MAX(1, nb_numa_nodes); + spapr->gpu_numa_id = MAX(1, machine->numa_state->num_nodes); qemu_devices_reset(); /* @@ -1752,7 +1759,7 @@ static void spapr_machine_reset(MachineState *machine) spapr_ovec_cleanup(spapr->ov5_cas); spapr->ov5_cas = spapr_ovec_new(); - ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal); + ppc_set_compat_all(spapr->max_compat_pvr, &error_fatal); } /* @@ -2539,12 +2546,12 @@ static void spapr_validate_node_memory(MachineState *machine, Error **errp) return; } - for (i = 0; i < nb_numa_nodes; i++) { - if (numa_info[i].node_mem % SPAPR_MEMORY_BLOCK_SIZE) { + for (i = 0; i < machine->numa_state->num_nodes; i++) { + if (machine->numa_state->nodes[i].node_mem % SPAPR_MEMORY_BLOCK_SIZE) { error_setg(errp, "Node %d memory size 0x%" PRIx64 " is not aligned to %" PRIu64 " MiB", - i, numa_info[i].node_mem, + i, machine->numa_state->nodes[i].node_mem, SPAPR_MEMORY_BLOCK_SIZE / MiB); return; } @@ -3829,6 +3836,7 @@ static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev, CPUArchId *core_slot; int index; bool hotplugged = spapr_drc_hotplugged(dev); + int i; core_slot = spapr_find_cpu_slot(MACHINE(hotplug_dev), cc->core_id, &index); if (!core_slot) { @@ -3862,13 +3870,26 @@ static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev, core_slot->cpu = OBJECT(dev); if (smc->pre_2_10_has_unused_icps) { - int i; - for (i = 0; i < cc->nr_threads; i++) { cs = CPU(core->threads[i]); pre_2_10_vmstate_unregister_dummy_icp(cs->cpu_index); } } + + /* + * Set compatibility mode to match the boot CPU, which was either set + * by the machine reset code or by CAS. + */ + if (hotplugged) { + for (i = 0; i < cc->nr_threads; i++) { + ppc_set_compat(core->threads[i], POWERPC_CPU(first_cpu)->compat_pvr, + &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + } + } } static void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, @@ -4178,7 +4199,7 @@ spapr_cpu_index_to_props(MachineState *machine, unsigned cpu_index) static int64_t spapr_get_default_cpu_node_id(const MachineState *ms, int idx) { - return idx / ms->smp.cores % nb_numa_nodes; + return idx / ms->smp.cores % ms->numa_state->num_nodes; } static const CPUArchIdList *spapr_possible_cpu_arch_ids(MachineState *machine) @@ -4470,6 +4491,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) spapr_caps_add_properties(smc, &error_abort); smc->irq = &spapr_irq_dual; smc->dr_phb_enabled = true; + smc->linux_pci_probe = true; } static const TypeInfo spapr_machine_info = { @@ -4529,12 +4551,14 @@ DEFINE_SPAPR_MACHINE(4_2, "4.2", true); */ static void spapr_machine_4_1_class_options(MachineClass *mc) { + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); static GlobalProperty compat[] = { /* Only allow 4kiB and 64kiB IOMMU pagesizes */ { TYPE_SPAPR_PCI_HOST_BRIDGE, "pgsz", "0x11000" }, }; spapr_machine_4_2_class_options(mc); + smc->linux_pci_probe = false; compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len); compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); } diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index bf47fbdf6f..1d93de8161 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -41,11 +41,6 @@ static void spapr_cpu_reset(void *opaque) * using an RTAS call */ cs->halted = 1; - /* Set compatibility mode to match the boot CPU, which was either set - * by the machine reset code or by CAS. This should never fail. - */ - ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &error_abort); - env->spr[SPR_HIOR] = 0; lpcr = env->spr[SPR_LPCR]; diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index e20a946b99..23e4bdb829 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1811,7 +1811,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu, spapr_ovec_cleanup(ov5_updates); if (spapr->cas_reboot) { - qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); + qemu_system_reset_request(SHUTDOWN_CAUSE_SUBSYSTEM_RESET); } return H_SUCCESS; diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index deb0b0c80c..7b71ad7c74 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -280,7 +280,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, SpaprMachineState *spapr, unsigned int irq, max_irqs = 0; SpaprPhbState *phb = NULL; PCIDevice *pdev = NULL; - spapr_pci_msi *msi; + SpaprPciMsi *msi; int *config_addr_key; Error *err = NULL; int i; @@ -328,7 +328,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, SpaprMachineState *spapr, return; } - msi = (spapr_pci_msi *) g_hash_table_lookup(phb->msi, &config_addr); + msi = (SpaprPciMsi *) g_hash_table_lookup(phb->msi, &config_addr); /* Releasing MSIs */ if (!req_num) { @@ -415,7 +415,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, SpaprMachineState *spapr, irq, req_num); /* Add MSI device to cache */ - msi = g_new(spapr_pci_msi, 1); + msi = g_new(SpaprPciMsi, 1); msi->first_irq = irq; msi->num = req_num; config_addr_key = g_new(int, 1); @@ -446,7 +446,7 @@ static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu, unsigned int intr_src_num = -1, ioa_intr_num = rtas_ld(args, 3); SpaprPhbState *phb = NULL; PCIDevice *pdev = NULL; - spapr_pci_msi *msi; + SpaprPciMsi *msi; /* Find SpaprPhbState */ phb = spapr_pci_find_phb(spapr, buid); @@ -459,7 +459,7 @@ static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu, } /* Find device descriptor and start IRQ */ - msi = (spapr_pci_msi *) g_hash_table_lookup(phb->msi, &config_addr); + msi = (SpaprPciMsi *) g_hash_table_lookup(phb->msi, &config_addr); if (!msi || !msi->first_irq || !msi->num || (ioa_intr_num >= msi->num)) { trace_spapr_pci_msi("Failed to return vector", config_addr); rtas_st(rets, 0, RTAS_OUT_HW_ERROR); @@ -1700,11 +1700,13 @@ static void spapr_pci_unplug_request(HotplugHandler *plug_handler, state = func_drck->dr_entity_sense(func_drc); if (state == SPAPR_DR_ENTITY_SENSE_PRESENT && !spapr_drc_unplug_requested(func_drc)) { - error_setg(errp, - "PCI: slot %d, function %d still present. " - "Must unplug all non-0 functions first.", - slotnr, i); - return; + /* + * Attempting to remove function 0 of a multifunction + * device will will cascade into removing all child + * functions, even if their unplug weren't requested + * beforehand. + */ + spapr_drc_detach(func_drc); } } } @@ -1804,7 +1806,7 @@ static void spapr_phb_destroy_msi(gpointer opaque) { SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); - spapr_pci_msi *msi = opaque; + SpaprPciMsi *msi = opaque; if (!smc->legacy_irq_allocation) { spapr_irq_msi_free(spapr, msi->first_irq, msi->num); @@ -1825,6 +1827,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) SysBusDevice *s = SYS_BUS_DEVICE(dev); SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(s); PCIHostState *phb = PCI_HOST_BRIDGE(s); + MachineState *ms = MACHINE(spapr); char *namebuf; int i; PCIBus *bus; @@ -1877,7 +1880,8 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) } if (sphb->numa_node != -1 && - (sphb->numa_node >= MAX_NODES || !numa_info[sphb->numa_node].present)) { + (sphb->numa_node >= MAX_NODES || + !ms->numa_state->nodes[sphb->numa_node].present)) { error_setg(errp, "Invalid NUMA node ID for PCI host bridge"); return; } @@ -2118,7 +2122,7 @@ static const VMStateDescription vmstate_spapr_pci_lsi = { .version_id = 1, .minimum_version_id = 1, .fields = (VMStateField[]) { - VMSTATE_UINT32_EQUAL(irq, struct spapr_pci_lsi, NULL), + VMSTATE_UINT32_EQUAL(irq, SpaprPciLsi, NULL), VMSTATE_END_OF_LIST() }, @@ -2129,9 +2133,9 @@ static const VMStateDescription vmstate_spapr_pci_msi = { .version_id = 1, .minimum_version_id = 1, .fields = (VMStateField []) { - VMSTATE_UINT32(key, spapr_pci_msi_mig), - VMSTATE_UINT32(value.first_irq, spapr_pci_msi_mig), - VMSTATE_UINT32(value.num, spapr_pci_msi_mig), + VMSTATE_UINT32(key, SpaprPciMsiMig), + VMSTATE_UINT32(value.first_irq, SpaprPciMsiMig), + VMSTATE_UINT32(value.num, SpaprPciMsiMig), VMSTATE_END_OF_LIST() }, }; @@ -2163,12 +2167,12 @@ static int spapr_pci_pre_save(void *opaque) if (!sphb->msi_devs_num) { return 0; } - sphb->msi_devs = g_new(spapr_pci_msi_mig, sphb->msi_devs_num); + sphb->msi_devs = g_new(SpaprPciMsiMig, sphb->msi_devs_num); g_hash_table_iter_init(&iter, sphb->msi); for (i = 0; g_hash_table_iter_next(&iter, &key, &value); ++i) { sphb->msi_devs[i].key = *(uint32_t *) key; - sphb->msi_devs[i].value = *(spapr_pci_msi *) value; + sphb->msi_devs[i].value = *(SpaprPciMsi *) value; } return 0; @@ -2215,10 +2219,10 @@ static const VMStateDescription vmstate_spapr_pci = { VMSTATE_UINT64_TEST(mig_io_win_addr, SpaprPhbState, pre_2_8_migration), VMSTATE_UINT64_TEST(mig_io_win_size, SpaprPhbState, pre_2_8_migration), VMSTATE_STRUCT_ARRAY(lsi_table, SpaprPhbState, PCI_NUM_PINS, 0, - vmstate_spapr_pci_lsi, struct spapr_pci_lsi), + vmstate_spapr_pci_lsi, SpaprPciLsi), VMSTATE_INT32(msi_devs_num, SpaprPhbState), VMSTATE_STRUCT_VARRAY_ALLOC(msi_devs, SpaprPhbState, msi_devs_num, 0, - vmstate_spapr_pci_msi, spapr_pci_msi_mig), + vmstate_spapr_pci_msi, SpaprPciMsiMig), VMSTATE_END_OF_LIST() }, }; diff --git a/hw/ppc/spapr_pci_nvlink2.c b/hw/ppc/spapr_pci_nvlink2.c index eda8c752aa..4aa89ede23 100644 --- a/hw/ppc/spapr_pci_nvlink2.c +++ b/hw/ppc/spapr_pci_nvlink2.c @@ -39,11 +39,7 @@ #define SPAPR_GPU_NUMA_ID (cpu_to_be32(1)) -struct spapr_phb_pci_nvgpu_config { - uint64_t nv2_ram_current; - uint64_t nv2_atsd_current; - int num; /* number of non empty (i.e. tgt!=0) entries in slots[] */ - struct spapr_phb_pci_nvgpu_slot { +typedef struct SpaprPhbPciNvGpuSlot { uint64_t tgt; uint64_t gpa; unsigned numa_id; @@ -54,12 +50,18 @@ struct spapr_phb_pci_nvgpu_config { PCIDevice *npdev; uint32_t link_speed; } links[NVGPU_MAX_LINKS]; - } slots[NVGPU_MAX_NUM]; +} SpaprPhbPciNvGpuSlot; + +struct SpaprPhbPciNvGpuConfig { + uint64_t nv2_ram_current; + uint64_t nv2_atsd_current; + int num; /* number of non empty (i.e. tgt!=0) entries in slots[] */ + SpaprPhbPciNvGpuSlot slots[NVGPU_MAX_NUM]; Error *errp; }; -static struct spapr_phb_pci_nvgpu_slot * -spapr_nvgpu_get_slot(struct spapr_phb_pci_nvgpu_config *nvgpus, uint64_t tgt) +static SpaprPhbPciNvGpuSlot * +spapr_nvgpu_get_slot(SpaprPhbPciNvGpuConfig *nvgpus, uint64_t tgt) { int i; @@ -81,13 +83,13 @@ spapr_nvgpu_get_slot(struct spapr_phb_pci_nvgpu_config *nvgpus, uint64_t tgt) return &nvgpus->slots[i]; } -static void spapr_pci_collect_nvgpu(struct spapr_phb_pci_nvgpu_config *nvgpus, +static void spapr_pci_collect_nvgpu(SpaprPhbPciNvGpuConfig *nvgpus, PCIDevice *pdev, uint64_t tgt, MemoryRegion *mr, Error **errp) { MachineState *machine = MACHINE(qdev_get_machine()); SpaprMachineState *spapr = SPAPR_MACHINE(machine); - struct spapr_phb_pci_nvgpu_slot *nvslot = spapr_nvgpu_get_slot(nvgpus, tgt); + SpaprPhbPciNvGpuSlot *nvslot = spapr_nvgpu_get_slot(nvgpus, tgt); if (!nvslot) { error_setg(errp, "Found too many GPUs per vPHB"); @@ -102,11 +104,11 @@ static void spapr_pci_collect_nvgpu(struct spapr_phb_pci_nvgpu_config *nvgpus, ++spapr->gpu_numa_id; } -static void spapr_pci_collect_nvnpu(struct spapr_phb_pci_nvgpu_config *nvgpus, +static void spapr_pci_collect_nvnpu(SpaprPhbPciNvGpuConfig *nvgpus, PCIDevice *pdev, uint64_t tgt, MemoryRegion *mr, Error **errp) { - struct spapr_phb_pci_nvgpu_slot *nvslot = spapr_nvgpu_get_slot(nvgpus, tgt); + SpaprPhbPciNvGpuSlot *nvslot = spapr_nvgpu_get_slot(nvgpus, tgt); int j; if (!nvslot) { @@ -138,7 +140,7 @@ static void spapr_phb_pci_collect_nvgpu(PCIBus *bus, PCIDevice *pdev, if (tgt) { Error *local_err = NULL; - struct spapr_phb_pci_nvgpu_config *nvgpus = opaque; + SpaprPhbPciNvGpuConfig *nvgpus = opaque; Object *mr_gpu = object_property_get_link(po, "nvlink2-mr[0]", NULL); Object *mr_npu = object_property_get_link(po, "nvlink2-atsd-mr[0]", NULL); @@ -177,7 +179,7 @@ void spapr_phb_nvgpu_setup(SpaprPhbState *sphb, Error **errp) return; } - sphb->nvgpus = g_new0(struct spapr_phb_pci_nvgpu_config, 1); + sphb->nvgpus = g_new0(SpaprPhbPciNvGpuConfig, 1); sphb->nvgpus->nv2_ram_current = sphb->nv2_gpa_win_addr; sphb->nvgpus->nv2_atsd_current = sphb->nv2_atsd_win_addr; @@ -194,7 +196,7 @@ void spapr_phb_nvgpu_setup(SpaprPhbState *sphb, Error **errp) /* Add found GPU RAM and ATSD MRs if found */ for (i = 0, valid_gpu_num = 0; i < sphb->nvgpus->num; ++i) { Object *nvmrobj; - struct spapr_phb_pci_nvgpu_slot *nvslot = &sphb->nvgpus->slots[i]; + SpaprPhbPciNvGpuSlot *nvslot = &sphb->nvgpus->slots[i]; if (!nvslot->gpdev) { continue; @@ -242,7 +244,7 @@ void spapr_phb_nvgpu_free(SpaprPhbState *sphb) } for (i = 0; i < sphb->nvgpus->num; ++i) { - struct spapr_phb_pci_nvgpu_slot *nvslot = &sphb->nvgpus->slots[i]; + SpaprPhbPciNvGpuSlot *nvslot = &sphb->nvgpus->slots[i]; Object *nv_mrobj = object_property_get_link(OBJECT(nvslot->gpdev), "nvlink2-mr[0]", NULL); @@ -276,7 +278,7 @@ void spapr_phb_nvgpu_populate_dt(SpaprPhbState *sphb, void *fdt, int bus_off, } for (i = 0; (i < sphb->nvgpus->num) && (atsdnum < ARRAY_SIZE(atsd)); ++i) { - struct spapr_phb_pci_nvgpu_slot *nvslot = &sphb->nvgpus->slots[i]; + SpaprPhbPciNvGpuSlot *nvslot = &sphb->nvgpus->slots[i]; if (!nvslot->gpdev) { continue; @@ -354,7 +356,7 @@ void spapr_phb_nvgpu_ram_populate_dt(SpaprPhbState *sphb, void *fdt) /* Add memory nodes for GPU RAM and mark them unusable */ for (i = 0; i < sphb->nvgpus->num; ++i) { - struct spapr_phb_pci_nvgpu_slot *nvslot = &sphb->nvgpus->slots[i]; + SpaprPhbPciNvGpuSlot *nvslot = &sphb->nvgpus->slots[i]; Object *nv_mrobj = object_property_get_link(OBJECT(nvslot->gpdev), "nvlink2-mr[0]", NULL); uint32_t associativity[] = { @@ -398,7 +400,7 @@ void spapr_phb_nvgpu_populate_pcidev_dt(PCIDevice *dev, void *fdt, int offset, } for (i = 0; i < sphb->nvgpus->num; ++i) { - struct spapr_phb_pci_nvgpu_slot *nvslot = &sphb->nvgpus->slots[i]; + SpaprPhbPciNvGpuSlot *nvslot = &sphb->nvgpus->slots[i]; /* Skip "slot" without attached GPU */ if (!nvslot->gpdev) { diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 526b489297..bee3835214 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -266,6 +266,7 @@ static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu, target_ulong args, uint32_t nret, target_ulong rets) { + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); MachineState *ms = MACHINE(qdev_get_machine()); unsigned int max_cpus = ms->smp.max_cpus; target_ulong parameter = rtas_ld(args, 0); @@ -283,6 +284,20 @@ static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu, current_machine->ram_size / MiB, ms->smp.cpus, max_cpus); + if (pcc->n_host_threads > 0) { + char *hostthr_val, *old = param_val; + + /* + * Add HostThrs property. This property is not present in PAPR but + * is expected by some guests to communicate the number of physical + * host threads per core on the system so that they can scale + * information which varies based on the thread configuration. + */ + hostthr_val = g_strdup_printf(",HostThrs=%d", pcc->n_host_threads); + param_val = g_strconcat(param_val, hostthr_val, NULL); + g_free(hostthr_val); + g_free(old); + } ret = sysparm_st(buffer, length, param_val, strlen(param_val) + 1); g_free(param_val); break; diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c index ed81d5c44c..59c2bbeee6 100644 --- a/hw/timer/aspeed_timer.c +++ b/hw/timer/aspeed_timer.c @@ -44,6 +44,13 @@ enum timer_ctrl_op { op_pulse_enable }; +/* + * Minimum value of the reload register to filter out short period + * timers which have a noticeable impact in emulation. 5us should be + * enough, use 20us for "safety". + */ +#define TIMER_MIN_NS (20 * SCALE_US) + /** * Avoid mutual references between AspeedTimerCtrlState and AspeedTimer * structs, as it's a waste of memory. The ptimer BH callback needs to know @@ -98,6 +105,14 @@ static inline uint32_t calculate_ticks(struct AspeedTimer *t, uint64_t now_ns) return t->reload - MIN(t->reload, ticks); } +static uint32_t calculate_min_ticks(AspeedTimer *t, uint32_t value) +{ + uint32_t rate = calculate_rate(t); + uint32_t min_ticks = muldiv64(TIMER_MIN_NS, rate, NANOSECONDS_PER_SECOND); + + return value < min_ticks ? min_ticks : value; +} + static inline uint64_t calculate_time(struct AspeedTimer *t, uint32_t ticks) { uint64_t delta_ns; @@ -261,7 +276,7 @@ static void aspeed_timer_set_value(AspeedTimerCtrlState *s, int timer, int reg, switch (reg) { case TIMER_REG_RELOAD: old_reload = t->reload; - t->reload = value; + t->reload = calculate_min_ticks(t, value); /* If the reload value was not previously set, or zero, and * the current value is valid, try to start the timer if it is diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c index 9846e4b513..7c07295519 100644 --- a/hw/usb/dev-mtp.c +++ b/hw/usb/dev-mtp.c @@ -2038,26 +2038,36 @@ static void usb_mtp_realize(USBDevice *dev, Error **errp) { MTPState *s = USB_MTP(dev); - usb_desc_create_serial(dev); - usb_desc_init(dev); - QTAILQ_INIT(&s->objects); - if (s->desc == NULL) { - if (s->root == NULL) { - error_setg(errp, "usb-mtp: rootdir property must be configured"); - return; - } - s->desc = strrchr(s->root, '/'); - if (s->desc && s->desc[0]) { - s->desc = g_strdup(s->desc + 1); - } else { - s->desc = g_strdup("none"); - } + if ((s->root == NULL) || !g_path_is_absolute(s->root)) { + error_setg(errp, "usb-mtp: rootdir must be configured and be an absolute path"); + return; } + + if (access(s->root, R_OK) != 0) { + error_setg(errp, "usb-mtp: rootdir does not exist/not readable"); + return; + } else if (!s->readonly && access(s->root, W_OK) != 0) { + error_setg(errp, "usb-mtp: rootdir does not have write permissions"); + return; + } + /* Mark store as RW */ if (!s->readonly) { s->flags |= (1 << MTP_FLAG_WRITABLE); } + if (s->desc == NULL) { + /* + * This does not check if path exists + * but we have the checks above + */ + s->desc = g_path_get_basename(s->root); + } + + usb_desc_create_serial(dev); + usb_desc_init(dev); + QTAILQ_INIT(&s->objects); + } static const VMStateDescription vmstate_usb_mtp = { diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index f578264948..80988bb305 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -1914,6 +1914,7 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid) } usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); if (xfer->packet.status == USB_RET_NAK) { + xhci_xfer_unmap(xfer); return; } xhci_try_complete_packet(xfer); @@ -2161,6 +2162,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid, DeviceOutRequest | USB_REQ_SET_ADDRESS, slotid, 0, 0, NULL); assert(p.status != USB_RET_ASYNC); + usb_packet_cleanup(&p); } res = xhci_enable_ep(xhci, slotid, 1, octx+32, ep0_ctx); diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index 189709b6de..be946ba1ce 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -231,7 +231,7 @@ typedef struct CPUTLB { } CPUTLB; #endif /* !CONFIG_USER_ONLY && CONFIG_TCG */ /* - * This structure must be placed in ArchCPU immedately + * This structure must be placed in ArchCPU immediately * before CPUArchState, as a field named "neg". */ typedef struct CPUNegativeOffsetState { diff --git a/include/exec/memory.h b/include/exec/memory.h index fddc2ff48a..ecca388e69 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1087,16 +1087,6 @@ void memory_region_register_iommu_notifier(MemoryRegion *mr, void memory_region_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n); /** - * memory_region_iommu_replay_all: replay existing IOMMU translations - * to all the notifiers registered. - * - * Note: this is not related to record-and-replay functionality. - * - * @iommu_mr: the memory region to observe - */ -void memory_region_iommu_replay_all(IOMMUMemoryRegion *iommu_mr); - -/** * memory_region_unregister_iommu_notifier: unregister a notifier for * changes to IOMMU translation entries. * diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 1a563ad756..991cf05134 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -414,7 +414,7 @@ build_append_gas_from_struct(GArray *table, const struct AcpiGenericAddress *s) void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base, uint64_t len, int node, MemoryAffinityFlags flags); -void build_slit(GArray *table_data, BIOSLinker *linker); +void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms); void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f, const char *oem_id, const char *oem_table_id); diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h index 5714dea1a2..7f4d0ca7cd 100644 --- a/include/hw/arm/boot.h +++ b/include/hw/arm/boot.h @@ -131,7 +131,7 @@ struct arm_boot_info { * before sysbus-fdt arm_register_platform_bus_fdt_creator. Indeed the * machine init done notifiers are called in registration reverse order. */ -void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info); +void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info); AddressSpace *arm_boot_address_space(ARMCPU *cpu, const struct arm_boot_info *info); @@ -158,7 +158,7 @@ AddressSpace *arm_boot_address_space(ARMCPU *cpu, * Note: Must not be called unless have_dtb(binfo) is true. */ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, - hwaddr addr_limit, AddressSpace *as); + hwaddr addr_limit, AddressSpace *as, MachineState *ms); /* Write a secure board setup routine with a dummy handler for SMCs */ void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu, diff --git a/include/hw/boards.h b/include/hw/boards.h index ced86109ec..2289536e48 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -299,6 +299,7 @@ struct MachineState { CPUArchIdList *possible_cpus; CpuTopology smp; struct NVDIMMState *nvdimms_state; + struct NumaState *numa_state; }; #define DEFINE_MACHINE(namestr, machine_initfn) \ diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index 1b61162f91..abd87605b2 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -34,15 +34,21 @@ typedef struct SpaprPhbState SpaprPhbState; -typedef struct spapr_pci_msi { +typedef struct SpaprPciMsi { uint32_t first_irq; uint32_t num; -} spapr_pci_msi; +} SpaprPciMsi; -typedef struct spapr_pci_msi_mig { +typedef struct SpaprPciMsiMig { uint32_t key; - spapr_pci_msi value; -} spapr_pci_msi_mig; + SpaprPciMsi value; +} SpaprPciMsiMig; + +typedef struct SpaprPciLsi { + uint32_t irq; +} SpaprPciLsi; + +typedef struct SpaprPhbPciNvGpuConfig SpaprPhbPciNvGpuConfig; struct SpaprPhbState { PCIHostState parent_obj; @@ -63,14 +69,12 @@ struct SpaprPhbState { AddressSpace iommu_as; MemoryRegion iommu_root; - struct spapr_pci_lsi { - uint32_t irq; - } lsi_table[PCI_NUM_PINS]; + SpaprPciLsi lsi_table[PCI_NUM_PINS]; GHashTable *msi; /* Temporary cache for migration purposes */ int32_t msi_devs_num; - spapr_pci_msi_mig *msi_devs; + SpaprPciMsiMig *msi_devs; QLIST_ENTRY(SpaprPhbState) list; @@ -89,7 +93,7 @@ struct SpaprPhbState { hwaddr mig_io_win_addr, mig_io_win_size; hwaddr nv2_gpa_win_addr; hwaddr nv2_atsd_win_addr; - struct spapr_phb_pci_nvgpu_config *nvgpus; + SpaprPhbPciNvGpuConfig *nvgpus; }; #define SPAPR_PCI_MEM_WIN_BUS_OFFSET 0x80000000ULL diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index fa7c380edb..03111fd55b 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -121,6 +121,7 @@ struct SpaprMachineClass { bool legacy_irq_allocation; bool broken_host_serial_model; /* present real host info to the guest */ bool pre_4_1_migration; /* don't migrate hpt-max-page-size */ + bool linux_pci_probe; void (*phb_placement)(SpaprMachineState *spapr, uint32_t index, uint64_t *buid, hwaddr *pio, diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h index 7a4ce89765..ae9c41d02b 100644 --- a/include/sysemu/numa.h +++ b/include/sysemu/numa.h @@ -14,9 +14,6 @@ struct CPUArchId; #define NUMA_DISTANCE_MAX 254 #define NUMA_DISTANCE_UNREACHABLE 255 -extern int nb_numa_nodes; /* Number of NUMA nodes */ -extern bool have_numa_distance; - struct NodeInfo { uint64_t node_mem; struct HostMemoryBackend *node_memdev; @@ -29,12 +26,22 @@ struct NumaNodeMem { uint64_t node_plugged_mem; }; -extern NodeInfo numa_info[MAX_NODES]; +struct NumaState { + /* Number of NUMA nodes */ + int num_nodes; + + /* Allow setting NUMA distance for different NUMA nodes */ + bool have_numa_distance; + + /* NUMA nodes information */ + NodeInfo nodes[MAX_NODES]; +}; +typedef struct NumaState NumaState; void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp); void parse_numa_opts(MachineState *ms); void numa_complete_configuration(MachineState *ms); -void query_numa_node_mem(NumaNodeMem node_mem[]); +void query_numa_node_mem(NumaNodeMem node_mem[], MachineState *ms); extern QemuOptsList qemu_numa_opts; void numa_legacy_auto_assign_ram(MachineClass *mc, NodeInfo *nodes, int nb_nodes, ram_addr_t size); diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index d2c38f611a..44f18eb739 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -42,8 +42,6 @@ extern const char *keyboard_layout; extern int win2k_install_hack; extern int alt_grab; extern int ctrl_grab; -extern int smp_cpus; -extern unsigned int max_cpus; extern int cursor_hide; extern int graphic_rotate; extern int no_quit; diff --git a/memory.c b/memory.c index 7fd93b1d42..a23ff3cc2a 100644 --- a/memory.c +++ b/memory.c @@ -1922,15 +1922,6 @@ void memory_region_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n) } } -void memory_region_iommu_replay_all(IOMMUMemoryRegion *iommu_mr) -{ - IOMMUNotifier *notifier; - - IOMMU_NOTIFIER_FOREACH(notifier, iommu_mr) { - memory_region_iommu_replay(iommu_mr, notifier); - } -} - void memory_region_unregister_iommu_notifier(MemoryRegion *mr, IOMMUNotifier *n) { diff --git a/pc-bios/README b/pc-bios/README index d59cd25461..ad78f6dc49 100644 --- a/pc-bios/README +++ b/pc-bios/README @@ -17,7 +17,7 @@ - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware implementation for certain IBM POWER hardware. The sources are at https://github.com/aik/SLOF, and the image currently in qemu is - built from git tag qemu-slof-20190719. + built from git tag qemu-slof-20190827. - sgabios (the Serial Graphics Adapter option ROM) provides a means for legacy x86 software to communicate with an attached serial console as diff --git a/pc-bios/skiboot.lid b/pc-bios/skiboot.lid index 6d5966c3ae..504b95e8b6 100644 --- a/pc-bios/skiboot.lid +++ b/pc-bios/skiboot.lid Binary files differdiff --git a/pc-bios/slof.bin b/pc-bios/slof.bin index fb0837508b..a3a3e49332 100644 --- a/pc-bios/slof.bin +++ b/pc-bios/slof.bin Binary files differdiff --git a/qapi/machine.json b/qapi/machine.json index de5c742d72..ca26779f1a 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -348,13 +348,16 @@ # in future versions of QEMU according to the QEMU deprecation # policy (since 4.1.0) # +# @default-cpu-type: default CPU model typename if none is requested via +# the -cpu argument. (since 4.2) +# # Since: 1.2.0 ## { 'struct': 'MachineInfo', 'data': { 'name': 'str', '*alias': 'str', '*is-default': 'bool', 'cpu-max': 'int', 'hotpluggable-cpus': 'bool', 'numa-mem-supported': 'bool', - 'deprecated': 'bool' } } + 'deprecated': 'bool', '*default-cpu-type': 'str' } } ## # @query-machines: diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index 8904733961..d46fa166d3 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -350,6 +350,79 @@ static void qemu_io_free(void *p) qemu_vfree(p); } +/* + * qemu_io_alloc_from_file() + * + * Allocates the buffer and populates it with the content of the given file + * up to @len bytes. If the file length is less than @len, then the buffer + * is populated with the file content cyclically. + * + * @blk - the block backend where the buffer content is going to be written to + * @len - the buffer length + * @file_name - the file to read the content from + * + * Returns: the buffer pointer on success + * NULL on error + */ +static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len, + const char *file_name) +{ + char *buf, *buf_origin; + FILE *f = fopen(file_name, "r"); + int pattern_len; + + if (!f) { + perror(file_name); + return NULL; + } + + if (qemuio_misalign) { + len += MISALIGN_OFFSET; + } + + buf_origin = buf = blk_blockalign(blk, len); + + if (qemuio_misalign) { + buf_origin += MISALIGN_OFFSET; + buf += MISALIGN_OFFSET; + len -= MISALIGN_OFFSET; + } + + pattern_len = fread(buf_origin, 1, len, f); + + if (ferror(f)) { + perror(file_name); + goto error; + } + + if (pattern_len == 0) { + fprintf(stderr, "%s: file is empty\n", file_name); + goto error; + } + + fclose(f); + + if (len > pattern_len) { + len -= pattern_len; + buf += pattern_len; + + while (len > 0) { + size_t len_to_copy = MIN(pattern_len, len); + + memcpy(buf, buf_origin, len_to_copy); + + len -= len_to_copy; + buf += len_to_copy; + } + } + + return buf_origin; + +error: + qemu_io_free(buf_origin); + return NULL; +} + static void dump_buffer(const void *buffer, int64_t offset, int64_t len) { uint64_t i; @@ -948,6 +1021,7 @@ static void write_help(void) " -n, -- with -z, don't allow slow fallback\n" " -p, -- ignored for backwards compatibility\n" " -P, -- use different pattern to fill file\n" +" -s, -- use a pattern file to fill the write buffer\n" " -C, -- report statistics in a machine parsable format\n" " -q, -- quiet mode, do not show I/O statistics\n" " -u, -- with -z, allow unmapping\n" @@ -964,7 +1038,7 @@ static const cmdinfo_t write_cmd = { .perm = BLK_PERM_WRITE, .argmin = 2, .argmax = -1, - .args = "[-bcCfnquz] [-P pattern] off len", + .args = "[-bcCfnquz] [-P pattern | -s source_file] off len", .oneline = "writes a number of bytes at a specified offset", .help = write_help, }; @@ -973,7 +1047,7 @@ static int write_f(BlockBackend *blk, int argc, char **argv) { struct timespec t1, t2; bool Cflag = false, qflag = false, bflag = false; - bool Pflag = false, zflag = false, cflag = false; + bool Pflag = false, zflag = false, cflag = false, sflag = false; int flags = 0; int c, cnt, ret; char *buf = NULL; @@ -982,8 +1056,9 @@ static int write_f(BlockBackend *blk, int argc, char **argv) /* Some compilers get confused and warn if this is not initialized. */ int64_t total = 0; int pattern = 0xcd; + const char *file_name = NULL; - while ((c = getopt(argc, argv, "bcCfnpP:quz")) != -1) { + while ((c = getopt(argc, argv, "bcCfnpP:qs:uz")) != -1) { switch (c) { case 'b': bflag = true; @@ -1013,6 +1088,10 @@ static int write_f(BlockBackend *blk, int argc, char **argv) case 'q': qflag = true; break; + case 's': + sflag = true; + file_name = optarg; + break; case 'u': flags |= BDRV_REQ_MAY_UNMAP; break; @@ -1050,8 +1129,9 @@ static int write_f(BlockBackend *blk, int argc, char **argv) return -EINVAL; } - if (zflag && Pflag) { - printf("-z and -P cannot be specified at the same time\n"); + if (zflag + Pflag + sflag > 1) { + printf("Only one of -z, -P, and -s " + "can be specified at the same time\n"); return -EINVAL; } @@ -1087,7 +1167,14 @@ static int write_f(BlockBackend *blk, int argc, char **argv) } if (!zflag) { - buf = qemu_io_alloc(blk, count, pattern); + if (sflag) { + buf = qemu_io_alloc_from_file(blk, count, file_name); + if (!buf) { + return -EINVAL; + } + } else { + buf = qemu_io_alloc(blk, count, pattern); + } } clock_gettime(CLOCK_MONOTONIC, &t1); diff --git a/roms/SLOF b/roms/SLOF -Subproject 7bfe584e321946771692711ff83ad2b5850daca +Subproject ea221600a116883137ef90b2b7ab7d2472bc4f1 diff --git a/roms/skiboot b/roms/skiboot -Subproject 261ca8e779e5138869a45f174caa49be6a27450 +Subproject 3a6fdede6ce117facec0108afe716cf5d0472c3 diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 0981303170..297ad5e47a 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -2212,6 +2212,9 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid) * IO indicates that this register does I/O and therefore its accesses * need to be surrounded by gen_io_start()/gen_io_end(). In particular, * registers which implement clocks or timers require this. + * RAISES_EXC is for when the read or write hook might raise an exception; + * the generated code will synchronize the CPU state before calling the hook + * so that it is safe for the hook to call raise_exception(). */ #define ARM_CP_SPECIAL 0x0001 #define ARM_CP_CONST 0x0002 @@ -2230,10 +2233,11 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid) #define ARM_CP_FPU 0x1000 #define ARM_CP_SVE 0x2000 #define ARM_CP_NO_GDB 0x4000 +#define ARM_CP_RAISES_EXC 0x8000 /* Used only as a terminator for ARMCPRegInfo lists */ #define ARM_CP_SENTINEL 0xffff /* Mask of only the flag bits in a type field */ -#define ARM_CP_FLAG_MASK 0x70ff +#define ARM_CP_FLAG_MASK 0xf0ff /* Valid values for ARMCPRegInfo state field, indicating which of * the AArch32 and AArch64 execution states this register is visible in. diff --git a/target/arm/helper.c b/target/arm/helper.c index 7e0d5398ab..507026c915 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -2946,6 +2946,73 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value, ret = get_phys_addr(env, value, access_type, mmu_idx, &phys_addr, &attrs, &prot, &page_size, &fi, &cacheattrs); + if (ret) { + /* + * Some kinds of translation fault must cause exceptions rather + * than being reported in the PAR. + */ + int current_el = arm_current_el(env); + int target_el; + uint32_t syn, fsr, fsc; + bool take_exc = false; + + if (fi.s1ptw && current_el == 1 && !arm_is_secure(env) + && (mmu_idx == ARMMMUIdx_S1NSE1 || mmu_idx == ARMMMUIdx_S1NSE0)) { + /* + * Synchronous stage 2 fault on an access made as part of the + * translation table walk for AT S1E0* or AT S1E1* insn + * executed from NS EL1. If this is a synchronous external abort + * and SCR_EL3.EA == 1, then we take a synchronous external abort + * to EL3. Otherwise the fault is taken as an exception to EL2, + * and HPFAR_EL2 holds the faulting IPA. + */ + if (fi.type == ARMFault_SyncExternalOnWalk && + (env->cp15.scr_el3 & SCR_EA)) { + target_el = 3; + } else { + env->cp15.hpfar_el2 = extract64(fi.s2addr, 12, 47) << 4; + target_el = 2; + } + take_exc = true; + } else if (fi.type == ARMFault_SyncExternalOnWalk) { + /* + * Synchronous external aborts during a translation table walk + * are taken as Data Abort exceptions. + */ + if (fi.stage2) { + if (current_el == 3) { + target_el = 3; + } else { + target_el = 2; + } + } else { + target_el = exception_target_el(env); + } + take_exc = true; + } + + if (take_exc) { + /* Construct FSR and FSC using same logic as arm_deliver_fault() */ + if (target_el == 2 || arm_el_is_aa64(env, target_el) || + arm_s1_regime_using_lpae_format(env, mmu_idx)) { + fsr = arm_fi_to_lfsc(&fi); + fsc = extract32(fsr, 0, 6); + } else { + fsr = arm_fi_to_sfsc(&fi); + fsc = 0x3f; + } + /* + * 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, + fi.ea, 1, fi.s1ptw, 1, fsc); + env->exception.vaddress = value; + env->exception.fsr = fsr; + raise_exception(env, EXCP_DATA_ABORT, syn, target_el); + } + } + if (is_a64(env)) { format64 = true; } else if (arm_feature(env, ARM_FEATURE_LPAE)) { @@ -3150,7 +3217,7 @@ static const ARMCPRegInfo vapa_cp_reginfo[] = { /* This underdecoding is safe because the reginfo is NO_RAW. */ { .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W, .accessfn = ats_access, - .writefn = ats_write, .type = ARM_CP_NO_RAW }, + .writefn = ats_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC }, #endif REGINFO_SENTINEL }; @@ -4283,35 +4350,45 @@ static const ARMCPRegInfo v8_cp_reginfo[] = { /* 64 bit address translation operations */ { .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 0, - .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write64 }, { .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 1, - .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write64 }, { .name = "AT_S1E0R", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 2, - .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write64 }, { .name = "AT_S1E0W", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 3, - .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write64 }, { .name = "AT_S12E1R", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 4, - .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write64 }, { .name = "AT_S12E1W", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 5, - .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write64 }, { .name = "AT_S12E0R", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 6, - .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write64 }, { .name = "AT_S12E0W", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 7, - .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write64 }, /* AT S1E2* are elsewhere as they UNDEF from EL3 if EL2 is not present */ { .name = "AT_S1E3R", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 0, - .access = PL3_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + .access = PL3_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write64 }, { .name = "AT_S1E3W", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 1, - .access = PL3_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + .access = PL3_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write64 }, { .name = "PAR_EL1", .state = ARM_CP_STATE_AA64, .type = ARM_CP_ALIAS, .opc0 = 3, .opc1 = 0, .crn = 7, .crm = 4, .opc2 = 0, @@ -4893,11 +4970,11 @@ static const ARMCPRegInfo el2_cp_reginfo[] = { { .name = "AT_S1E2R", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0, .access = PL2_W, .accessfn = at_s1e2_access, - .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, .writefn = ats_write64 }, { .name = "AT_S1E2W", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1, .access = PL2_W, .accessfn = at_s1e2_access, - .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, .writefn = ats_write64 }, /* The AArch32 ATS1H* operations are CONSTRAINED UNPREDICTABLE * if EL2 is not implemented; we choose to UNDEF. Behaviour at EL3 * with SCR.NS == 0 outside Monitor mode is UNPREDICTABLE; we choose @@ -4905,10 +4982,10 @@ static const ARMCPRegInfo el2_cp_reginfo[] = { */ { .name = "ATS1HR", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0, .access = PL2_W, - .writefn = ats1h_write, .type = ARM_CP_NO_RAW }, + .writefn = ats1h_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC }, { .name = "ATS1HW", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1, .access = PL2_W, - .writefn = ats1h_write, .type = ARM_CP_NO_RAW }, + .writefn = ats1h_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC }, { .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0, /* ARMv7 requires bit 0 and 1 to reset to 1. ARMv8 defines the diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 6fd0b779d3..4d09ae6f42 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -338,6 +338,13 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest) } } +void unallocated_encoding(DisasContext *s) +{ + /* Unallocated and reserved encodings are uncategorized */ + gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), + default_exception_el(s)); +} + static void init_tmp_a64_array(DisasContext *s) { #ifdef CONFIG_DEBUG_TCG @@ -1707,6 +1714,12 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread, tcg_temp_free_ptr(tmpptr); tcg_temp_free_i32(tcg_syn); tcg_temp_free_i32(tcg_isread); + } else if (ri->type & ARM_CP_RAISES_EXC) { + /* + * The readfn or writefn might raise an exception; + * synchronize the CPU state in case it does. + */ + gen_a64_set_pc_im(s->pc_curr); } /* Handle special cases first */ diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h index 12ad8ac6ed..9cd2b3d238 100644 --- a/target/arm/translate-a64.h +++ b/target/arm/translate-a64.h @@ -18,6 +18,8 @@ #ifndef TARGET_ARM_TRANSLATE_A64_H #define TARGET_ARM_TRANSLATE_A64_H +void unallocated_encoding(DisasContext *s); + #define unsupported_encoding(s, insn) \ do { \ qemu_log_mask(LOG_UNIMP, \ diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c index 3e8ea80493..9ae980bef6 100644 --- a/target/arm/translate-vfp.inc.c +++ b/target/arm/translate-vfp.inc.c @@ -880,8 +880,10 @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a) /* gpreg to fpreg */ tmp = load_reg(s, a->rt); neon_store_reg32(tmp, a->vm); + tcg_temp_free_i32(tmp); tmp = load_reg(s, a->rt2); neon_store_reg32(tmp, a->vm + 1); + tcg_temp_free_i32(tmp); } return true; diff --git a/target/arm/translate.c b/target/arm/translate.c index cbe19b7a62..615859e23c 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -915,10 +915,27 @@ static inline void gen_bx(DisasContext *s, TCGv_i32 var) store_cpu_field(var, thumb); } -/* Set PC and Thumb state from var. var is marked as dead. +/* + * Set PC and Thumb state from var. var is marked as dead. * For M-profile CPUs, include logic to detect exception-return * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC, * and BX reg, and no others, and happens only for code in Handler mode. + * The Security Extension also requires us to check for the FNC_RETURN + * which signals a function return from non-secure state; this can happen + * in both Handler and Thread mode. + * To avoid having to do multiple comparisons in inline generated code, + * we make the check we do here loose, so it will match for EXC_RETURN + * in Thread mode. For system emulation do_v7m_exception_exit() checks + * for these spurious cases and returns without doing anything (giving + * the same behaviour as for a branch to a non-magic address). + * + * In linux-user mode it is unclear what the right behaviour for an + * attempted FNC_RETURN should be, because in real hardware this will go + * directly to Secure code (ie not the Linux kernel) which will then treat + * the error in any way it chooses. For QEMU we opt to make the FNC_RETURN + * attempt behave the way it would on a CPU without the security extension, + * which is to say "like a normal branch". That means we can simply treat + * all branches as normal with no magic address behaviour. */ static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var) { @@ -926,10 +943,12 @@ static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var) * s->base.is_jmp that we need to do the rest of the work later. */ gen_bx(s, var); +#ifndef CONFIG_USER_ONLY if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) || (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) { s->base.is_jmp = DISAS_BX_EXCRET; } +#endif } static inline void gen_bx_excret_final_code(DisasContext *s) @@ -1231,7 +1250,7 @@ static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn) s->base.is_jmp = DISAS_NORETURN; } -void unallocated_encoding(DisasContext *s) +static void unallocated_encoding(DisasContext *s) { /* Unallocated and reserved encodings are uncategorized */ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), @@ -7191,6 +7210,13 @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn) tcg_temp_free_ptr(tmpptr); tcg_temp_free_i32(tcg_syn); tcg_temp_free_i32(tcg_isread); + } else if (ri->type & ARM_CP_RAISES_EXC) { + /* + * The readfn or writefn might raise an exception; + * synchronize the CPU state in case it does. + */ + gen_set_condexec(s); + gen_set_pc_im(s, s->pc_curr); } /* Handle special cases first */ @@ -8824,7 +8850,16 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) if (rd != 15) { tmp3 = load_reg(s, rd); if (insn & (1 << 6)) { - tcg_gen_sub_i32(tmp, tmp, tmp3); + /* + * For SMMLS, we need a 64-bit subtract. + * Borrow caused by a non-zero multiplicand + * lowpart, and the correct result lowpart + * for rounding. + */ + TCGv_i32 zero = tcg_const_i32(0); + tcg_gen_sub2_i32(tmp2, tmp, zero, tmp3, + tmp2, tmp); + tcg_temp_free_i32(zero); } else { tcg_gen_add_i32(tmp, tmp, tmp3); } @@ -10068,7 +10103,14 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) if (insn & (1 << 20)) { tcg_gen_add_i32(tmp, tmp, tmp3); } else { - tcg_gen_sub_i32(tmp, tmp, tmp3); + /* + * For SMMLS, we need a 64-bit subtract. + * Borrow caused by a non-zero multiplicand lowpart, + * and the correct result lowpart for rounding. + */ + TCGv_i32 zero = tcg_const_i32(0); + tcg_gen_sub2_i32(tmp2, tmp, zero, tmp3, tmp2, tmp); + tcg_temp_free_i32(zero); } tcg_temp_free_i32(tmp3); } diff --git a/target/arm/translate.h b/target/arm/translate.h index 92ef790be9..64304c957e 100644 --- a/target/arm/translate.h +++ b/target/arm/translate.h @@ -99,8 +99,6 @@ typedef struct DisasCompare { bool value_global; } DisasCompare; -void unallocated_encoding(DisasContext *s); - /* Share the TCG temporaries common between 32 and 64 bit modes. */ extern TCGv_i32 cpu_NF, cpu_ZF, cpu_CF, cpu_VF; extern TCGv_i64 cpu_exclusive_addr; diff --git a/target/mips/cpu.h b/target/mips/cpu.h index 1fd4a180e1..ca00f41daf 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -192,14 +192,14 @@ typedef struct mips_def_t mips_def_t; * Register 16 Register 17 Register 18 Register 19 * ----------- ----------- ----------- ----------- * - * 0 Config LLAddr WatchLo WatchHi - * 1 Config1 MAAR WatchLo WatchHi - * 2 Config2 MAARI WatchLo WatchHi - * 3 Config3 WatchLo WatchHi - * 4 Config4 WatchLo WatchHi - * 5 Config5 WatchLo WatchHi - * 6 WatchLo WatchHi - * 7 WatchLo WatchHi + * 0 Config LLAddr WatchLo0 WatchHi + * 1 Config1 MAAR WatchLo1 WatchHi + * 2 Config2 MAARI WatchLo2 WatchHi + * 3 Config3 WatchLo3 WatchHi + * 4 Config4 WatchLo4 WatchHi + * 5 Config5 WatchLo5 WatchHi + * 6 WatchLo6 WatchHi + * 7 WatchLo7 WatchHi * * * Register 20 Register 21 Register 22 Register 23 @@ -233,12 +233,12 @@ typedef struct mips_def_t mips_def_t; * * 0 DataLo DataHi ErrorEPC DESAVE * 1 TagLo TagHi - * 2 DataLo DataHi KScratch<n> - * 3 TagLo TagHi KScratch<n> - * 4 DataLo DataHi KScratch<n> - * 5 TagLo TagHi KScratch<n> - * 6 DataLo DataHi KScratch<n> - * 7 TagLo TagHi KScratch<n> + * 2 DataLo1 DataHi1 KScratch<n> + * 3 TagLo1 TagHi1 KScratch<n> + * 4 DataLo2 DataHi2 KScratch<n> + * 5 TagLo2 TagHi2 KScratch<n> + * 6 DataLo3 DataHi3 KScratch<n> + * 7 TagLo3 TagHi3 KScratch<n> * */ #define CP0_REGISTER_00 0 @@ -277,29 +277,63 @@ typedef struct mips_def_t mips_def_t; /* CP0 Register 00 */ #define CP0_REG00__INDEX 0 +#define CP0_REG00__MVPCONTROL 1 +#define CP0_REG00__MVPCONF0 2 +#define CP0_REG00__MVPCONF1 3 #define CP0_REG00__VPCONTROL 4 /* CP0 Register 01 */ +#define CP0_REG01__RANDOM 0 +#define CP0_REG01__VPECONTROL 1 +#define CP0_REG01__VPECONF0 2 +#define CP0_REG01__VPECONF1 3 +#define CP0_REG01__YQMASK 4 +#define CP0_REG01__VPESCHEDULE 5 +#define CP0_REG01__VPESCHEFBACK 6 +#define CP0_REG01__VPEOPT 7 /* CP0 Register 02 */ #define CP0_REG02__ENTRYLO0 0 +#define CP0_REG02__TCSTATUS 1 +#define CP0_REG02__TCBIND 2 +#define CP0_REG02__TCRESTART 3 +#define CP0_REG02__TCHALT 4 +#define CP0_REG02__TCCONTEXT 5 +#define CP0_REG02__TCSCHEDULE 6 +#define CP0_REG02__TCSCHEFBACK 7 /* CP0 Register 03 */ #define CP0_REG03__ENTRYLO1 0 #define CP0_REG03__GLOBALNUM 1 +#define CP0_REG03__TCOPT 7 /* CP0 Register 04 */ #define CP0_REG04__CONTEXT 0 +#define CP0_REG04__CONTEXTCONFIG 1 #define CP0_REG04__USERLOCAL 2 +#define CP0_REG04__XCONTEXTCONFIG 3 #define CP0_REG04__DBGCONTEXTID 4 #define CP0_REG00__MMID 5 /* CP0 Register 05 */ #define CP0_REG05__PAGEMASK 0 #define CP0_REG05__PAGEGRAIN 1 +#define CP0_REG05__SEGCTL0 2 +#define CP0_REG05__SEGCTL1 3 +#define CP0_REG05__SEGCTL2 4 +#define CP0_REG05__PWBASE 5 +#define CP0_REG05__PWFIELD 6 +#define CP0_REG05__PWSIZE 7 /* CP0 Register 06 */ #define CP0_REG06__WIRED 0 +#define CP0_REG06__SRSCONF0 1 +#define CP0_REG06__SRSCONF1 2 +#define CP0_REG06__SRSCONF2 3 +#define CP0_REG06__SRSCONF3 4 +#define CP0_REG06__SRSCONF4 5 +#define CP0_REG06__PWCTL 6 /* CP0 Register 07 */ #define CP0_REG07__HWRENA 0 /* CP0 Register 08 */ #define CP0_REG08__BADVADDR 0 #define CP0_REG08__BADINSTR 1 #define CP0_REG08__BADINSTRP 2 +#define CP0_REG08__BADINSTRX 3 /* CP0 Register 09 */ #define CP0_REG09__COUNT 0 #define CP0_REG09__SAARI 6 @@ -308,6 +342,7 @@ typedef struct mips_def_t mips_def_t; #define CP0_REG10__ENTRYHI 0 #define CP0_REG10__GUESTCTL1 4 #define CP0_REG10__GUESTCTL2 5 +#define CP0_REG10__GUESTCTL3 6 /* CP0 Register 11 */ #define CP0_REG11__COMPARE 0 #define CP0_REG11__GUESTCTL0EXT 4 @@ -315,17 +350,24 @@ typedef struct mips_def_t mips_def_t; #define CP0_REG12__STATUS 0 #define CP0_REG12__INTCTL 1 #define CP0_REG12__SRSCTL 2 +#define CP0_REG12__SRSMAP 3 +#define CP0_REG12__VIEW_IPL 4 +#define CP0_REG12__SRSMAP2 5 #define CP0_REG12__GUESTCTL0 6 #define CP0_REG12__GTOFFSET 7 /* CP0 Register 13 */ #define CP0_REG13__CAUSE 0 +#define CP0_REG13__VIEW_RIPL 4 +#define CP0_REG13__NESTEDEXC 5 /* CP0 Register 14 */ #define CP0_REG14__EPC 0 +#define CP0_REG14__NESTEDEPC 2 /* CP0 Register 15 */ #define CP0_REG15__PRID 0 #define CP0_REG15__EBASE 1 #define CP0_REG15__CDMMBASE 2 #define CP0_REG15__CMGCRBASE 3 +#define CP0_REG15__BEVVA 4 /* CP0 Register 16 */ #define CP0_REG16__CONFIG 0 #define CP0_REG16__CONFIG1 1 @@ -333,7 +375,8 @@ typedef struct mips_def_t mips_def_t; #define CP0_REG16__CONFIG3 3 #define CP0_REG16__CONFIG4 4 #define CP0_REG16__CONFIG5 5 -#define CP0_REG00__CONFIG7 7 +#define CP0_REG16__CONFIG6 6 +#define CP0_REG16__CONFIG7 7 /* CP0 Register 17 */ #define CP0_REG17__LLADDR 0 #define CP0_REG17__MAAR 1 @@ -343,17 +386,31 @@ typedef struct mips_def_t mips_def_t; #define CP0_REG18__WATCHLO1 1 #define CP0_REG18__WATCHLO2 2 #define CP0_REG18__WATCHLO3 3 +#define CP0_REG18__WATCHLO4 4 +#define CP0_REG18__WATCHLO5 5 +#define CP0_REG18__WATCHLO6 6 +#define CP0_REG18__WATCHLO7 7 /* CP0 Register 19 */ #define CP0_REG19__WATCHHI0 0 #define CP0_REG19__WATCHHI1 1 #define CP0_REG19__WATCHHI2 2 #define CP0_REG19__WATCHHI3 3 +#define CP0_REG19__WATCHHI4 4 +#define CP0_REG19__WATCHHI5 5 +#define CP0_REG19__WATCHHI6 6 +#define CP0_REG19__WATCHHI7 7 /* CP0 Register 20 */ #define CP0_REG20__XCONTEXT 0 /* CP0 Register 21 */ /* CP0 Register 22 */ /* CP0 Register 23 */ #define CP0_REG23__DEBUG 0 +#define CP0_REG23__TRACECONTROL 1 +#define CP0_REG23__TRACECONTROL2 2 +#define CP0_REG23__USERTRACEDATA1 3 +#define CP0_REG23__TRACEIBPC 4 +#define CP0_REG23__TRACEDBPC 5 +#define CP0_REG23__DEBUG2 6 /* CP0 Register 24 */ #define CP0_REG24__DEPC 0 /* CP0 Register 25 */ @@ -366,17 +423,27 @@ typedef struct mips_def_t mips_def_t; #define CP0_REG25__PERFCTL3 6 #define CP0_REG25__PERFCNT3 7 /* CP0 Register 26 */ -#define CP0_REG00__ERRCTL 0 +#define CP0_REG26__ERRCTL 0 /* CP0 Register 27 */ #define CP0_REG27__CACHERR 0 /* CP0 Register 28 */ -#define CP0_REG28__ITAGLO 0 -#define CP0_REG28__IDATALO 1 -#define CP0_REG28__DTAGLO 2 -#define CP0_REG28__DDATALO 3 +#define CP0_REG28__TAGLO 0 +#define CP0_REG28__DATALO 1 +#define CP0_REG28__TAGLO1 2 +#define CP0_REG28__DATALO1 3 +#define CP0_REG28__TAGLO2 4 +#define CP0_REG28__DATALO2 5 +#define CP0_REG28__TAGLO3 6 +#define CP0_REG28__DATALO3 7 /* CP0 Register 29 */ -#define CP0_REG29__IDATAHI 1 -#define CP0_REG29__DDATAHI 3 +#define CP0_REG29__TAGHI 0 +#define CP0_REG29__DATAHI 1 +#define CP0_REG29__TAGHI1 2 +#define CP0_REG29__DATAHI1 3 +#define CP0_REG29__TAGHI2 4 +#define CP0_REG29__DATAHI2 5 +#define CP0_REG29__TAGHI3 6 +#define CP0_REG29__DATAHI3 7 /* CP0 Register 30 */ #define CP0_REG30__ERROREPC 0 /* CP0 Register 31 */ @@ -546,7 +613,6 @@ struct CPUMIPSState { * CP0 Register 4 */ target_ulong CP0_Context; - target_ulong CP0_KScratch[MIPS_KSCRATCH_NUM]; int32_t CP0_MemoryMapID; /* * CP0 Register 5 @@ -957,6 +1023,7 @@ struct CPUMIPSState { * CP0 Register 31 */ int32_t CP0_DESAVE; + target_ulong CP0_KScratch[MIPS_KSCRATCH_NUM]; /* We waste some space so we can handle shadow registers like TCs. */ TCState tcs[MIPS_SHADOW_SET_MAX]; diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index f88a3ab904..5b8bb203f0 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -4692,15 +4692,15 @@ void helper_msa_st_w(CPUMIPSState *env, uint32_t wd, ensure_writable_pages(env, addr, mmu_idx, GETPC()); #if !defined(CONFIG_USER_ONLY) #if !defined(HOST_WORDS_BIGENDIAN) - helper_ret_stl_mmu(env, addr + (0 << DF_WORD), oi, GETPC(), pwd->w[0]); - helper_ret_stl_mmu(env, addr + (1 << DF_WORD), oi, GETPC(), pwd->w[1]); - helper_ret_stl_mmu(env, addr + (2 << DF_WORD), oi, GETPC(), pwd->w[2]); - helper_ret_stl_mmu(env, addr + (3 << DF_WORD), oi, GETPC(), pwd->w[3]); + helper_ret_stl_mmu(env, addr + (0 << DF_WORD), pwd->w[0], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (1 << DF_WORD), pwd->w[1], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (2 << DF_WORD), pwd->w[2], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (3 << DF_WORD), pwd->w[3], oi, GETPC()); #else - helper_ret_stl_mmu(env, addr + (1 << DF_WORD), oi, GETPC(), pwd->w[0]); - helper_ret_stl_mmu(env, addr + (0 << DF_WORD), oi, GETPC(), pwd->w[1]); - helper_ret_stl_mmu(env, addr + (3 << DF_WORD), oi, GETPC(), pwd->w[2]); - helper_ret_stl_mmu(env, addr + (2 << DF_WORD), oi, GETPC(), pwd->w[3]); + helper_ret_stl_mmu(env, addr + (1 << DF_WORD), pwd->w[0], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (0 << DF_WORD), pwd->w[1], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (3 << DF_WORD), pwd->w[2], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (2 << DF_WORD), pwd->w[3], oi, GETPC()); #endif #else #if !defined(HOST_WORDS_BIGENDIAN) diff --git a/target/mips/translate.c b/target/mips/translate.c index 8ebde6ffee..f6d14245f1 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -6647,7 +6647,7 @@ static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_03: switch (sel) { - case 0: + case CP0_REG03__ENTRYLO1: CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); register_name = "EntryLo1"; @@ -6658,7 +6658,7 @@ static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_09: switch (sel) { - case 7: + case CP0_REG09__SAAR: CP0_CHECK(ctx->saar); gen_helper_mfhc0_saar(arg, cpu_env); register_name = "SAAR"; @@ -6669,12 +6669,12 @@ static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_17: switch (sel) { - case 0: + case CP0_REG17__LLADDR: gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr), ctx->CP0_LLAddr_shift); register_name = "LLAddr"; break; - case 1: + case CP0_REG17__MAAR: CP0_CHECK(ctx->mrp); gen_helper_mfhc0_maar(arg, cpu_env); register_name = "MAAR"; @@ -6728,7 +6728,7 @@ static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_03: switch (sel) { - case 0: + case CP0_REG03__ENTRYLO1: CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); tcg_gen_andi_tl(arg, arg, mask); gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); @@ -6740,7 +6740,7 @@ static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_09: switch (sel) { - case 7: + case CP0_REG09__SAAR: CP0_CHECK(ctx->saar); gen_helper_mthc0_saar(cpu_env, arg); register_name = "SAAR"; @@ -6751,7 +6751,7 @@ static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_17: switch (sel) { - case 0: + case CP0_REG17__LLADDR: /* * LLAddr is read-only (the only exception is bit 0 if LLB is * supported); the CP0_LLAddr_rw_bitmask does not seem to be @@ -6760,7 +6760,7 @@ static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) */ register_name = "LLAddr"; break; - case 1: + case CP0_REG17__MAAR: CP0_CHECK(ctx->mrp); gen_helper_mthc0_maar(cpu_env, arg); register_name = "MAAR"; @@ -6813,26 +6813,26 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) switch (reg) { case CP0_REGISTER_00: switch (sel) { - case 0: + case CP0_REG00__INDEX: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); register_name = "Index"; break; - case 1: + case CP0_REG00__MVPCONTROL: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mfc0_mvpcontrol(arg, cpu_env); register_name = "MVPControl"; break; - case 2: + case CP0_REG00__MVPCONF0: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mfc0_mvpconf0(arg, cpu_env); register_name = "MVPConf0"; break; - case 3: + case CP0_REG00__MVPCONF1: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mfc0_mvpconf1(arg, cpu_env); register_name = "MVPConf1"; break; - case 4: + case CP0_REG00__VPCONTROL: CP0_CHECK(ctx->vp); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); register_name = "VPControl"; @@ -6843,42 +6843,42 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_01: switch (sel) { - case 0: + case CP0_REG01__RANDOM: CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6)); gen_helper_mfc0_random(arg, cpu_env); register_name = "Random"; break; - case 1: + case CP0_REG01__VPECONTROL: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); register_name = "VPEControl"; break; - case 2: + case CP0_REG01__VPECONF0: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); register_name = "VPEConf0"; break; - case 3: + case CP0_REG01__VPECONF1: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); register_name = "VPEConf1"; break; - case 4: + case CP0_REG01__YQMASK: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask)); register_name = "YQMask"; break; - case 5: + case CP0_REG01__VPESCHEDULE: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); register_name = "VPESchedule"; break; - case 6: + case CP0_REG01__VPESCHEFBACK: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); register_name = "VPEScheFBack"; break; - case 7: + case CP0_REG01__VPEOPT: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); register_name = "VPEOpt"; @@ -6889,7 +6889,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_02: switch (sel) { - case 0: + case CP0_REG02__ENTRYLO0: { TCGv_i64 tmp = tcg_temp_new_i64(); tcg_gen_ld_i64(tmp, cpu_env, @@ -6906,37 +6906,37 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) } register_name = "EntryLo0"; break; - case 1: + case CP0_REG02__TCSTATUS: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mfc0_tcstatus(arg, cpu_env); register_name = "TCStatus"; break; - case 2: + case CP0_REG02__TCBIND: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mfc0_tcbind(arg, cpu_env); register_name = "TCBind"; break; - case 3: + case CP0_REG02__TCRESTART: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mfc0_tcrestart(arg, cpu_env); register_name = "TCRestart"; break; - case 4: + case CP0_REG02__TCHALT: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mfc0_tchalt(arg, cpu_env); register_name = "TCHalt"; break; - case 5: + case CP0_REG02__TCCONTEXT: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mfc0_tccontext(arg, cpu_env); register_name = "TCContext"; break; - case 6: + case CP0_REG02__TCSCHEDULE: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mfc0_tcschedule(arg, cpu_env); register_name = "TCSchedule"; break; - case 7: + case CP0_REG02__TCSCHEFBACK: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mfc0_tcschefback(arg, cpu_env); register_name = "TCScheFBack"; @@ -6947,7 +6947,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_03: switch (sel) { - case 0: + case CP0_REG03__ENTRYLO1: { TCGv_i64 tmp = tcg_temp_new_i64(); tcg_gen_ld_i64(tmp, cpu_env, @@ -6964,7 +6964,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) } register_name = "EntryLo1"; break; - case 1: + case CP0_REG03__GLOBALNUM: CP0_CHECK(ctx->vp); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); register_name = "GlobalNumber"; @@ -6975,16 +6975,17 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_04: switch (sel) { - case 0: + case CP0_REG04__CONTEXT: tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); tcg_gen_ext32s_tl(arg, arg); register_name = "Context"; break; - case 1: - /* gen_helper_mfc0_contextconfig(arg); - SmartMIPS ASE */ + case CP0_REG04__CONTEXTCONFIG: + /* SmartMIPS ASE */ + /* gen_helper_mfc0_contextconfig(arg); */ register_name = "ContextConfig"; goto cp0_unimplemented; - case 2: + case CP0_REG04__USERLOCAL: CP0_CHECK(ctx->ulri); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); @@ -6997,44 +6998,44 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_05: switch (sel) { - case 0: + case CP0_REG05__PAGEMASK: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); register_name = "PageMask"; break; - case 1: + case CP0_REG05__PAGEGRAIN: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); register_name = "PageGrain"; break; - case 2: + case CP0_REG05__SEGCTL0: CP0_CHECK(ctx->sc); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0)); tcg_gen_ext32s_tl(arg, arg); register_name = "SegCtl0"; break; - case 3: + case CP0_REG05__SEGCTL1: CP0_CHECK(ctx->sc); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1)); tcg_gen_ext32s_tl(arg, arg); register_name = "SegCtl1"; break; - case 4: + case CP0_REG05__SEGCTL2: CP0_CHECK(ctx->sc); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2)); tcg_gen_ext32s_tl(arg, arg); register_name = "SegCtl2"; break; - case 5: + case CP0_REG05__PWBASE: check_pw(ctx); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase)); register_name = "PWBase"; break; - case 6: + case CP0_REG05__PWFIELD: check_pw(ctx); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField)); register_name = "PWField"; break; - case 7: + case CP0_REG05__PWSIZE: check_pw(ctx); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize)); register_name = "PWSize"; @@ -7045,36 +7046,36 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_06: switch (sel) { - case 0: + case CP0_REG06__WIRED: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); register_name = "Wired"; break; - case 1: + case CP0_REG06__SRSCONF0: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); register_name = "SRSConf0"; break; - case 2: + case CP0_REG06__SRSCONF1: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); register_name = "SRSConf1"; break; - case 3: + case CP0_REG06__SRSCONF2: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); register_name = "SRSConf2"; break; - case 4: + case CP0_REG06__SRSCONF3: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); register_name = "SRSConf3"; break; - case 5: + case CP0_REG06__SRSCONF4: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); register_name = "SRSConf4"; break; - case 6: + case CP0_REG06__PWCTL: check_pw(ctx); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); register_name = "PWCtl"; @@ -7085,7 +7086,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_07: switch (sel) { - case 0: + case CP0_REG07__HWRENA: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); register_name = "HWREna"; @@ -7096,22 +7097,22 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_08: switch (sel) { - case 0: + case CP0_REG08__BADVADDR: tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); tcg_gen_ext32s_tl(arg, arg); register_name = "BadVAddr"; break; - case 1: + case CP0_REG08__BADINSTR: CP0_CHECK(ctx->bi); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); register_name = "BadInstr"; break; - case 2: + case CP0_REG08__BADINSTRP: CP0_CHECK(ctx->bp); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); register_name = "BadInstrP"; break; - case 3: + case CP0_REG08__BADINSTRX: CP0_CHECK(ctx->bi); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); tcg_gen_andi_tl(arg, arg, ~0xffff); @@ -7123,7 +7124,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_09: switch (sel) { - case 0: + case CP0_REG09__COUNT: /* Mark as an IO operation because we read the time. */ if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { gen_io_start(); @@ -7138,12 +7139,12 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) ctx->base.is_jmp = DISAS_EXIT; register_name = "Count"; break; - case 6: + case CP0_REG09__SAARI: CP0_CHECK(ctx->saar); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI)); register_name = "SAARI"; break; - case 7: + case CP0_REG09__SAAR: CP0_CHECK(ctx->saar); gen_helper_mfc0_saar(arg, cpu_env); register_name = "SAAR"; @@ -7154,7 +7155,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_10: switch (sel) { - case 0: + case CP0_REG10__ENTRYHI: tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); tcg_gen_ext32s_tl(arg, arg); register_name = "EntryHi"; @@ -7165,7 +7166,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_11: switch (sel) { - case 0: + case CP0_REG11__COMPARE: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); register_name = "Compare"; break; @@ -7176,21 +7177,21 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_12: switch (sel) { - case 0: + case CP0_REG12__STATUS: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); register_name = "Status"; break; - case 1: + case CP0_REG12__INTCTL: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); register_name = "IntCtl"; break; - case 2: + case CP0_REG12__SRSCTL: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); register_name = "SRSCtl"; break; - case 3: + case CP0_REG12__SRSMAP: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); register_name = "SRSMap"; @@ -7201,7 +7202,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_13: switch (sel) { - case 0: + case CP0_REG13__CAUSE: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); register_name = "Cause"; break; @@ -7211,7 +7212,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_14: switch (sel) { - case 0: + case CP0_REG14__EPC: tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); tcg_gen_ext32s_tl(arg, arg); register_name = "EPC"; @@ -7222,17 +7223,17 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_15: switch (sel) { - case 0: + case CP0_REG15__PRID: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); register_name = "PRid"; break; - case 1: + case CP0_REG15__EBASE: check_insn(ctx, ISA_MIPS32R2); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); tcg_gen_ext32s_tl(arg, arg); register_name = "EBase"; break; - case 3: + case CP0_REG15__CMGCRBASE: check_insn(ctx, ISA_MIPS32R2); CP0_CHECK(ctx->cmgcr); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); @@ -7245,36 +7246,36 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_16: switch (sel) { - case 0: + case CP0_REG16__CONFIG: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); register_name = "Config"; break; - case 1: + case CP0_REG16__CONFIG1: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); register_name = "Config1"; break; - case 2: + case CP0_REG16__CONFIG2: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); register_name = "Config2"; break; - case 3: + case CP0_REG16__CONFIG3: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); register_name = "Config3"; break; - case 4: + case CP0_REG16__CONFIG4: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); register_name = "Config4"; break; - case 5: + case CP0_REG16__CONFIG5: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); register_name = "Config5"; break; /* 6,7 are implementation dependent */ - case 6: + case CP0_REG16__CONFIG6: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); register_name = "Config6"; break; - case 7: + case CP0_REG16__CONFIG7: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); register_name = "Config7"; break; @@ -7284,16 +7285,16 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_17: switch (sel) { - case 0: + case CP0_REG17__LLADDR: gen_helper_mfc0_lladdr(arg, cpu_env); register_name = "LLAddr"; break; - case 1: + case CP0_REG17__MAAR: CP0_CHECK(ctx->mrp); gen_helper_mfc0_maar(arg, cpu_env); register_name = "MAAR"; break; - case 2: + case CP0_REG17__MAARI: CP0_CHECK(ctx->mrp); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); register_name = "MAARI"; @@ -7304,14 +7305,14 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_18: switch (sel) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: + case CP0_REG18__WATCHLO0: + case CP0_REG18__WATCHLO1: + case CP0_REG18__WATCHLO2: + case CP0_REG18__WATCHLO3: + case CP0_REG18__WATCHLO4: + case CP0_REG18__WATCHLO5: + case CP0_REG18__WATCHLO6: + case CP0_REG18__WATCHLO7: CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_1e0i(mfc0_watchlo, arg, sel); register_name = "WatchLo"; @@ -7322,14 +7323,14 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_19: switch (sel) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: + case CP0_REG19__WATCHHI0: + case CP0_REG19__WATCHHI1: + case CP0_REG19__WATCHHI2: + case CP0_REG19__WATCHHI3: + case CP0_REG19__WATCHHI4: + case CP0_REG19__WATCHHI5: + case CP0_REG19__WATCHHI6: + case CP0_REG19__WATCHHI7: CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_1e0i(mfc0_watchhi, arg, sel); register_name = "WatchHi"; @@ -7340,7 +7341,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_20: switch (sel) { - case 0: + case CP0_REG20__XCONTEXT: #if defined(TARGET_MIPS64) check_insn(ctx, ISA_MIPS3); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); @@ -7370,25 +7371,34 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_23: switch (sel) { - case 0: + case CP0_REG23__DEBUG: gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ register_name = "Debug"; break; - case 1: -// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */ + case CP0_REG23__TRACECONTROL: + /* PDtrace support */ + /* gen_helper_mfc0_tracecontrol(arg); */ register_name = "TraceControl"; goto cp0_unimplemented; - case 2: -// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */ + case CP0_REG23__TRACECONTROL2: + /* PDtrace support */ + /* gen_helper_mfc0_tracecontrol2(arg); */ register_name = "TraceControl2"; goto cp0_unimplemented; - case 3: -// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */ - register_name = "UserTraceData"; + case CP0_REG23__USERTRACEDATA1: + /* PDtrace support */ + /* gen_helper_mfc0_usertracedata1(arg);*/ + register_name = "UserTraceData1"; goto cp0_unimplemented; - case 4: -// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */ - register_name = "TraceBPC"; + case CP0_REG23__TRACEIBPC: + /* PDtrace support */ + /* gen_helper_mfc0_traceibpc(arg); */ + register_name = "TraceIBPC"; + goto cp0_unimplemented; + case CP0_REG23__TRACEDBPC: + /* PDtrace support */ + /* gen_helper_mfc0_tracedbpc(arg); */ + register_name = "TraceDBPC"; goto cp0_unimplemented; default: goto cp0_unimplemented; @@ -7396,7 +7406,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_24: switch (sel) { - case 0: + case CP0_REG24__DEPC: /* EJTAG support */ tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); tcg_gen_ext32s_tl(arg, arg); @@ -7408,35 +7418,35 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_25: switch (sel) { - case 0: + case CP0_REG25__PERFCTL0: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); register_name = "Performance0"; break; - case 1: + case CP0_REG25__PERFCNT0: /* gen_helper_mfc0_performance1(arg); */ register_name = "Performance1"; goto cp0_unimplemented; - case 2: + case CP0_REG25__PERFCTL1: /* gen_helper_mfc0_performance2(arg); */ register_name = "Performance2"; goto cp0_unimplemented; - case 3: + case CP0_REG25__PERFCNT1: /* gen_helper_mfc0_performance3(arg); */ register_name = "Performance3"; goto cp0_unimplemented; - case 4: + case CP0_REG25__PERFCTL2: /* gen_helper_mfc0_performance4(arg); */ register_name = "Performance4"; goto cp0_unimplemented; - case 5: + case CP0_REG25__PERFCNT2: /* gen_helper_mfc0_performance5(arg); */ register_name = "Performance5"; goto cp0_unimplemented; - case 6: + case CP0_REG25__PERFCTL3: /* gen_helper_mfc0_performance6(arg); */ register_name = "Performance6"; goto cp0_unimplemented; - case 7: + case CP0_REG25__PERFCNT3: /* gen_helper_mfc0_performance7(arg); */ register_name = "Performance7"; goto cp0_unimplemented; @@ -7446,7 +7456,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_26: switch (sel) { - case 0: + case CP0_REG26__ERRCTL: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); register_name = "ErrCtl"; break; @@ -7456,10 +7466,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_27: switch (sel) { - case 0: - case 1: - case 2: - case 3: + case CP0_REG27__CACHERR: tcg_gen_movi_tl(arg, 0); /* unimplemented */ register_name = "CacheErr"; break; @@ -7469,10 +7476,10 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_28: switch (sel) { - case 0: - case 2: - case 4: - case 6: + case CP0_REG28__TAGLO: + case CP0_REG28__TAGLO1: + case CP0_REG28__TAGLO2: + case CP0_REG28__TAGLO3: { TCGv_i64 tmp = tcg_temp_new_i64(); tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo)); @@ -7481,10 +7488,10 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) } register_name = "TagLo"; break; - case 1: - case 3: - case 5: - case 7: + case CP0_REG28__DATALO: + case CP0_REG28__DATALO1: + case CP0_REG28__DATALO2: + case CP0_REG28__DATALO3: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); register_name = "DataLo"; break; @@ -7494,17 +7501,17 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_29: switch (sel) { - case 0: - case 2: - case 4: - case 6: + case CP0_REG29__TAGHI: + case CP0_REG29__TAGHI1: + case CP0_REG29__TAGHI2: + case CP0_REG29__TAGHI3: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); register_name = "TagHi"; break; - case 1: - case 3: - case 5: - case 7: + case CP0_REG29__DATAHI: + case CP0_REG29__DATAHI1: + case CP0_REG29__DATAHI2: + case CP0_REG29__DATAHI3: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); register_name = "DataHi"; break; @@ -7514,7 +7521,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_30: switch (sel) { - case 0: + case CP0_REG30__ERROREPC: tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); tcg_gen_ext32s_tl(arg, arg); register_name = "ErrorEPC"; @@ -7525,17 +7532,17 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_31: switch (sel) { - case 0: + case CP0_REG31__DESAVE: /* EJTAG support */ gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); register_name = "DESAVE"; break; - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: + case CP0_REG31__KSCRATCH1: + case CP0_REG31__KSCRATCH2: + case CP0_REG31__KSCRATCH3: + case CP0_REG31__KSCRATCH4: + case CP0_REG31__KSCRATCH5: + case CP0_REG31__KSCRATCH6: CP0_CHECK(ctx->kscrexist & (1 << sel)); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_KScratch[sel-2])); @@ -7573,26 +7580,26 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) switch (reg) { case CP0_REGISTER_00: switch (sel) { - case 0: + case CP0_REG00__INDEX: gen_helper_mtc0_index(cpu_env, arg); register_name = "Index"; break; - case 1: + case CP0_REG00__MVPCONTROL: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_mvpcontrol(cpu_env, arg); register_name = "MVPControl"; break; - case 2: + case CP0_REG00__MVPCONF0: CP0_CHECK(ctx->insn_flags & ASE_MT); /* ignored */ register_name = "MVPConf0"; break; - case 3: + case CP0_REG00__MVPCONF1: CP0_CHECK(ctx->insn_flags & ASE_MT); /* ignored */ register_name = "MVPConf1"; break; - case 4: + case CP0_REG00__VPCONTROL: CP0_CHECK(ctx->vp); /* ignored */ register_name = "VPControl"; @@ -7603,43 +7610,43 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_01: switch (sel) { - case 0: + case CP0_REG01__RANDOM: /* ignored */ register_name = "Random"; break; - case 1: + case CP0_REG01__VPECONTROL: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_vpecontrol(cpu_env, arg); register_name = "VPEControl"; break; - case 2: + case CP0_REG01__VPECONF0: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_vpeconf0(cpu_env, arg); register_name = "VPEConf0"; break; - case 3: + case CP0_REG01__VPECONF1: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_vpeconf1(cpu_env, arg); register_name = "VPEConf1"; break; - case 4: + case CP0_REG01__YQMASK: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_yqmask(cpu_env, arg); register_name = "YQMask"; break; - case 5: + case CP0_REG01__VPESCHEDULE: CP0_CHECK(ctx->insn_flags & ASE_MT); tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule)); register_name = "VPESchedule"; break; - case 6: + case CP0_REG01__VPESCHEFBACK: CP0_CHECK(ctx->insn_flags & ASE_MT); tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack)); register_name = "VPEScheFBack"; break; - case 7: + case CP0_REG01__VPEOPT: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_vpeopt(cpu_env, arg); register_name = "VPEOpt"; @@ -7650,41 +7657,41 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_02: switch (sel) { - case 0: + case CP0_REG02__ENTRYLO0: gen_helper_mtc0_entrylo0(cpu_env, arg); register_name = "EntryLo0"; break; - case 1: + case CP0_REG02__TCSTATUS: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_tcstatus(cpu_env, arg); register_name = "TCStatus"; break; - case 2: + case CP0_REG02__TCBIND: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_tcbind(cpu_env, arg); register_name = "TCBind"; break; - case 3: + case CP0_REG02__TCRESTART: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_tcrestart(cpu_env, arg); register_name = "TCRestart"; break; - case 4: + case CP0_REG02__TCHALT: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_tchalt(cpu_env, arg); register_name = "TCHalt"; break; - case 5: + case CP0_REG02__TCCONTEXT: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_tccontext(cpu_env, arg); register_name = "TCContext"; break; - case 6: + case CP0_REG02__TCSCHEDULE: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_tcschedule(cpu_env, arg); register_name = "TCSchedule"; break; - case 7: + case CP0_REG02__TCSCHEFBACK: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_tcschefback(cpu_env, arg); register_name = "TCScheFBack"; @@ -7695,11 +7702,11 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_03: switch (sel) { - case 0: + case CP0_REG03__ENTRYLO1: gen_helper_mtc0_entrylo1(cpu_env, arg); register_name = "EntryLo1"; break; - case 1: + case CP0_REG03__GLOBALNUM: CP0_CHECK(ctx->vp); /* ignored */ register_name = "GlobalNumber"; @@ -7710,15 +7717,16 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_04: switch (sel) { - case 0: + case CP0_REG04__CONTEXT: gen_helper_mtc0_context(cpu_env, arg); register_name = "Context"; break; - case 1: -// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */ + case CP0_REG04__CONTEXTCONFIG: + /* SmartMIPS ASE */ + /* gen_helper_mtc0_contextconfig(arg); */ register_name = "ContextConfig"; goto cp0_unimplemented; - case 2: + case CP0_REG04__USERLOCAL: CP0_CHECK(ctx->ulri); tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); @@ -7730,42 +7738,42 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_05: switch (sel) { - case 0: + case CP0_REG05__PAGEMASK: gen_helper_mtc0_pagemask(cpu_env, arg); register_name = "PageMask"; break; - case 1: + case CP0_REG05__PAGEGRAIN: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_pagegrain(cpu_env, arg); register_name = "PageGrain"; ctx->base.is_jmp = DISAS_STOP; break; - case 2: + case CP0_REG05__SEGCTL0: CP0_CHECK(ctx->sc); gen_helper_mtc0_segctl0(cpu_env, arg); register_name = "SegCtl0"; break; - case 3: + case CP0_REG05__SEGCTL1: CP0_CHECK(ctx->sc); gen_helper_mtc0_segctl1(cpu_env, arg); register_name = "SegCtl1"; break; - case 4: + case CP0_REG05__SEGCTL2: CP0_CHECK(ctx->sc); gen_helper_mtc0_segctl2(cpu_env, arg); register_name = "SegCtl2"; break; - case 5: + case CP0_REG05__PWBASE: check_pw(ctx); gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase)); register_name = "PWBase"; break; - case 6: + case CP0_REG05__PWFIELD: check_pw(ctx); gen_helper_mtc0_pwfield(cpu_env, arg); register_name = "PWField"; break; - case 7: + case CP0_REG05__PWSIZE: check_pw(ctx); gen_helper_mtc0_pwsize(cpu_env, arg); register_name = "PWSize"; @@ -7776,36 +7784,36 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_06: switch (sel) { - case 0: + case CP0_REG06__WIRED: gen_helper_mtc0_wired(cpu_env, arg); register_name = "Wired"; break; - case 1: + case CP0_REG06__SRSCONF0: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_srsconf0(cpu_env, arg); register_name = "SRSConf0"; break; - case 2: + case CP0_REG06__SRSCONF1: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_srsconf1(cpu_env, arg); register_name = "SRSConf1"; break; - case 3: + case CP0_REG06__SRSCONF2: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_srsconf2(cpu_env, arg); register_name = "SRSConf2"; break; - case 4: + case CP0_REG06__SRSCONF3: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_srsconf3(cpu_env, arg); register_name = "SRSConf3"; break; - case 5: + case CP0_REG06__SRSCONF4: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_srsconf4(cpu_env, arg); register_name = "SRSConf4"; break; - case 6: + case CP0_REG06__PWCTL: check_pw(ctx); gen_helper_mtc0_pwctl(cpu_env, arg); register_name = "PWCtl"; @@ -7816,7 +7824,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_07: switch (sel) { - case 0: + case CP0_REG07__HWRENA: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_hwrena(cpu_env, arg); ctx->base.is_jmp = DISAS_STOP; @@ -7828,19 +7836,19 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_08: switch (sel) { - case 0: + case CP0_REG08__BADVADDR: /* ignored */ register_name = "BadVAddr"; break; - case 1: + case CP0_REG08__BADINSTR: /* ignored */ register_name = "BadInstr"; break; - case 2: + case CP0_REG08__BADINSTRP: /* ignored */ register_name = "BadInstrP"; break; - case 3: + case CP0_REG08__BADINSTRX: /* ignored */ register_name = "BadInstrX"; break; @@ -7850,16 +7858,16 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_09: switch (sel) { - case 0: + case CP0_REG09__COUNT: gen_helper_mtc0_count(cpu_env, arg); register_name = "Count"; break; - case 6: + case CP0_REG09__SAARI: CP0_CHECK(ctx->saar); gen_helper_mtc0_saari(cpu_env, arg); register_name = "SAARI"; break; - case 7: + case CP0_REG09__SAAR: CP0_CHECK(ctx->saar); gen_helper_mtc0_saar(cpu_env, arg); register_name = "SAAR"; @@ -7870,7 +7878,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_10: switch (sel) { - case 0: + case CP0_REG10__ENTRYHI: gen_helper_mtc0_entryhi(cpu_env, arg); register_name = "EntryHi"; break; @@ -7880,7 +7888,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_11: switch (sel) { - case 0: + case CP0_REG11__COMPARE: gen_helper_mtc0_compare(cpu_env, arg); register_name = "Compare"; break; @@ -7891,7 +7899,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_12: switch (sel) { - case 0: + case CP0_REG12__STATUS: save_cpu_state(ctx, 1); gen_helper_mtc0_status(cpu_env, arg); /* DISAS_STOP isn't good enough here, hflags may have changed. */ @@ -7899,21 +7907,21 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) ctx->base.is_jmp = DISAS_EXIT; register_name = "Status"; break; - case 1: + case CP0_REG12__INTCTL: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_intctl(cpu_env, arg); /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; register_name = "IntCtl"; break; - case 2: + case CP0_REG12__SRSCTL: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_srsctl(cpu_env, arg); /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; register_name = "SRSCtl"; break; - case 3: + case CP0_REG12__SRSMAP: check_insn(ctx, ISA_MIPS32R2); gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); /* Stop translation as we may have switched the execution mode */ @@ -7926,7 +7934,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_13: switch (sel) { - case 0: + case CP0_REG13__CAUSE: save_cpu_state(ctx, 1); gen_helper_mtc0_cause(cpu_env, arg); /* @@ -7944,7 +7952,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_14: switch (sel) { - case 0: + case CP0_REG14__EPC: tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); register_name = "EPC"; break; @@ -7954,11 +7962,11 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_15: switch (sel) { - case 0: + case CP0_REG15__PRID: /* ignored */ register_name = "PRid"; break; - case 1: + case CP0_REG15__EBASE: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_ebase(cpu_env, arg); register_name = "EBase"; @@ -7969,45 +7977,45 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_16: switch (sel) { - case 0: + case CP0_REG16__CONFIG: gen_helper_mtc0_config0(cpu_env, arg); register_name = "Config"; /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; break; - case 1: + case CP0_REG16__CONFIG1: /* ignored, read only */ register_name = "Config1"; break; - case 2: + case CP0_REG16__CONFIG2: gen_helper_mtc0_config2(cpu_env, arg); register_name = "Config2"; /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; break; - case 3: + case CP0_REG16__CONFIG3: gen_helper_mtc0_config3(cpu_env, arg); register_name = "Config3"; /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; break; - case 4: + case CP0_REG16__CONFIG4: gen_helper_mtc0_config4(cpu_env, arg); register_name = "Config4"; ctx->base.is_jmp = DISAS_STOP; break; - case 5: + case CP0_REG16__CONFIG5: gen_helper_mtc0_config5(cpu_env, arg); register_name = "Config5"; /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; break; /* 6,7 are implementation dependent */ - case 6: + case CP0_REG16__CONFIG6: /* ignored */ register_name = "Config6"; break; - case 7: + case CP0_REG16__CONFIG7: /* ignored */ register_name = "Config7"; break; @@ -8018,16 +8026,16 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_17: switch (sel) { - case 0: + case CP0_REG17__LLADDR: gen_helper_mtc0_lladdr(cpu_env, arg); register_name = "LLAddr"; break; - case 1: + case CP0_REG17__MAAR: CP0_CHECK(ctx->mrp); gen_helper_mtc0_maar(cpu_env, arg); register_name = "MAAR"; break; - case 2: + case CP0_REG17__MAARI: CP0_CHECK(ctx->mrp); gen_helper_mtc0_maari(cpu_env, arg); register_name = "MAARI"; @@ -8038,14 +8046,14 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_18: switch (sel) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: + case CP0_REG18__WATCHLO0: + case CP0_REG18__WATCHLO1: + case CP0_REG18__WATCHLO2: + case CP0_REG18__WATCHLO3: + case CP0_REG18__WATCHLO4: + case CP0_REG18__WATCHLO5: + case CP0_REG18__WATCHLO6: + case CP0_REG18__WATCHLO7: CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_0e1i(mtc0_watchlo, arg, sel); register_name = "WatchLo"; @@ -8056,14 +8064,14 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_19: switch (sel) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: + case CP0_REG19__WATCHHI0: + case CP0_REG19__WATCHHI1: + case CP0_REG19__WATCHHI2: + case CP0_REG19__WATCHHI3: + case CP0_REG19__WATCHHI4: + case CP0_REG19__WATCHHI5: + case CP0_REG19__WATCHHI6: + case CP0_REG19__WATCHHI7: CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_0e1i(mtc0_watchhi, arg, sel); register_name = "WatchHi"; @@ -8074,7 +8082,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_20: switch (sel) { - case 0: + case CP0_REG20__XCONTEXT: #if defined(TARGET_MIPS64) check_insn(ctx, ISA_MIPS3); gen_helper_mtc0_xcontext(cpu_env, arg); @@ -8103,38 +8111,49 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_23: switch (sel) { - case 0: + case CP0_REG23__DEBUG: gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ /* DISAS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->base.pc_next + 4); ctx->base.is_jmp = DISAS_EXIT; register_name = "Debug"; break; - case 1: -// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */ + case CP0_REG23__TRACECONTROL: + /* PDtrace support */ + /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */ register_name = "TraceControl"; /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; goto cp0_unimplemented; - case 2: -// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */ + case CP0_REG23__TRACECONTROL2: + /* PDtrace support */ + /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */ register_name = "TraceControl2"; /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; goto cp0_unimplemented; - case 3: + case CP0_REG23__USERTRACEDATA1: /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; -// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */ + /* PDtrace support */ + /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/ register_name = "UserTraceData"; /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; goto cp0_unimplemented; - case 4: -// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */ + case CP0_REG23__TRACEIBPC: + /* PDtrace support */ + /* gen_helper_mtc0_traceibpc(cpu_env, arg); */ /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; - register_name = "TraceBPC"; + register_name = "TraceIBPC"; + goto cp0_unimplemented; + case CP0_REG23__TRACEDBPC: + /* PDtrace support */ + /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */ + /* Stop translation as we may have switched the execution mode */ + ctx->base.is_jmp = DISAS_STOP; + register_name = "TraceDBPC"; goto cp0_unimplemented; default: goto cp0_unimplemented; @@ -8142,7 +8161,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_24: switch (sel) { - case 0: + case CP0_REG24__DEPC: /* EJTAG support */ tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); register_name = "DEPC"; @@ -8153,35 +8172,35 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_25: switch (sel) { - case 0: + case CP0_REG25__PERFCTL0: gen_helper_mtc0_performance0(cpu_env, arg); register_name = "Performance0"; break; - case 1: + case CP0_REG25__PERFCNT0: /* gen_helper_mtc0_performance1(arg); */ register_name = "Performance1"; goto cp0_unimplemented; - case 2: + case CP0_REG25__PERFCTL1: /* gen_helper_mtc0_performance2(arg); */ register_name = "Performance2"; goto cp0_unimplemented; - case 3: + case CP0_REG25__PERFCNT1: /* gen_helper_mtc0_performance3(arg); */ register_name = "Performance3"; goto cp0_unimplemented; - case 4: + case CP0_REG25__PERFCTL2: /* gen_helper_mtc0_performance4(arg); */ register_name = "Performance4"; goto cp0_unimplemented; - case 5: + case CP0_REG25__PERFCNT2: /* gen_helper_mtc0_performance5(arg); */ register_name = "Performance5"; goto cp0_unimplemented; - case 6: + case CP0_REG25__PERFCTL3: /* gen_helper_mtc0_performance6(arg); */ register_name = "Performance6"; goto cp0_unimplemented; - case 7: + case CP0_REG25__PERFCNT3: /* gen_helper_mtc0_performance7(arg); */ register_name = "Performance7"; goto cp0_unimplemented; @@ -8191,7 +8210,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_26: switch (sel) { - case 0: + case CP0_REG26__ERRCTL: gen_helper_mtc0_errctl(cpu_env, arg); ctx->base.is_jmp = DISAS_STOP; register_name = "ErrCtl"; @@ -8202,10 +8221,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_27: switch (sel) { - case 0: - case 1: - case 2: - case 3: + case CP0_REG27__CACHERR: /* ignored */ register_name = "CacheErr"; break; @@ -8215,17 +8231,17 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_28: switch (sel) { - case 0: - case 2: - case 4: - case 6: + case CP0_REG28__TAGLO: + case CP0_REG28__TAGLO1: + case CP0_REG28__TAGLO2: + case CP0_REG28__TAGLO3: gen_helper_mtc0_taglo(cpu_env, arg); register_name = "TagLo"; break; - case 1: - case 3: - case 5: - case 7: + case CP0_REG28__DATALO: + case CP0_REG28__DATALO1: + case CP0_REG28__DATALO2: + case CP0_REG28__DATALO3: gen_helper_mtc0_datalo(cpu_env, arg); register_name = "DataLo"; break; @@ -8235,17 +8251,17 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_29: switch (sel) { - case 0: - case 2: - case 4: - case 6: + case CP0_REG29__TAGHI: + case CP0_REG29__TAGHI1: + case CP0_REG29__TAGHI2: + case CP0_REG29__TAGHI3: gen_helper_mtc0_taghi(cpu_env, arg); register_name = "TagHi"; break; - case 1: - case 3: - case 5: - case 7: + case CP0_REG29__DATAHI: + case CP0_REG29__DATAHI1: + case CP0_REG29__DATAHI2: + case CP0_REG29__DATAHI3: gen_helper_mtc0_datahi(cpu_env, arg); register_name = "DataHi"; break; @@ -8256,7 +8272,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_30: switch (sel) { - case 0: + case CP0_REG30__ERROREPC: tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); register_name = "ErrorEPC"; break; @@ -8266,17 +8282,17 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_31: switch (sel) { - case 0: + case CP0_REG31__DESAVE: /* EJTAG support */ gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); register_name = "DESAVE"; break; - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: + case CP0_REG31__KSCRATCH1: + case CP0_REG31__KSCRATCH2: + case CP0_REG31__KSCRATCH3: + case CP0_REG31__KSCRATCH4: + case CP0_REG31__KSCRATCH5: + case CP0_REG31__KSCRATCH6: CP0_CHECK(ctx->kscrexist & (1 << sel)); tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_KScratch[sel-2])); @@ -8319,26 +8335,26 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) switch (reg) { case CP0_REGISTER_00: switch (sel) { - case 0: + case CP0_REG00__INDEX: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); register_name = "Index"; break; - case 1: + case CP0_REG00__MVPCONTROL: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mfc0_mvpcontrol(arg, cpu_env); register_name = "MVPControl"; break; - case 2: + case CP0_REG00__MVPCONF0: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mfc0_mvpconf0(arg, cpu_env); register_name = "MVPConf0"; break; - case 3: + case CP0_REG00__MVPCONF1: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mfc0_mvpconf1(arg, cpu_env); register_name = "MVPConf1"; break; - case 4: + case CP0_REG00__VPCONTROL: CP0_CHECK(ctx->vp); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); register_name = "VPControl"; @@ -8349,42 +8365,42 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_01: switch (sel) { - case 0: + case CP0_REG01__RANDOM: CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6)); gen_helper_mfc0_random(arg, cpu_env); register_name = "Random"; break; - case 1: + case CP0_REG01__VPECONTROL: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); register_name = "VPEControl"; break; - case 2: + case CP0_REG01__VPECONF0: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); register_name = "VPEConf0"; break; - case 3: + case CP0_REG01__VPECONF1: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); register_name = "VPEConf1"; break; - case 4: + case CP0_REG01__YQMASK: CP0_CHECK(ctx->insn_flags & ASE_MT); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask)); register_name = "YQMask"; break; - case 5: + case CP0_REG01__VPESCHEDULE: CP0_CHECK(ctx->insn_flags & ASE_MT); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule)); register_name = "VPESchedule"; break; - case 6: + case CP0_REG01__VPESCHEFBACK: CP0_CHECK(ctx->insn_flags & ASE_MT); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack)); register_name = "VPEScheFBack"; break; - case 7: + case CP0_REG01__VPEOPT: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); register_name = "VPEOpt"; @@ -8395,41 +8411,41 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_02: switch (sel) { - case 0: + case CP0_REG02__ENTRYLO0: tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0)); register_name = "EntryLo0"; break; - case 1: + case CP0_REG02__TCSTATUS: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mfc0_tcstatus(arg, cpu_env); register_name = "TCStatus"; break; - case 2: + case CP0_REG02__TCBIND: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mfc0_tcbind(arg, cpu_env); register_name = "TCBind"; break; - case 3: + case CP0_REG02__TCRESTART: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_dmfc0_tcrestart(arg, cpu_env); register_name = "TCRestart"; break; - case 4: + case CP0_REG02__TCHALT: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_dmfc0_tchalt(arg, cpu_env); register_name = "TCHalt"; break; - case 5: + case CP0_REG02__TCCONTEXT: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_dmfc0_tccontext(arg, cpu_env); register_name = "TCContext"; break; - case 6: + case CP0_REG02__TCSCHEDULE: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_dmfc0_tcschedule(arg, cpu_env); register_name = "TCSchedule"; break; - case 7: + case CP0_REG02__TCSCHEFBACK: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_dmfc0_tcschefback(arg, cpu_env); register_name = "TCScheFBack"; @@ -8440,11 +8456,11 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_03: switch (sel) { - case 0: + case CP0_REG03__ENTRYLO1: tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1)); register_name = "EntryLo1"; break; - case 1: + case CP0_REG03__GLOBALNUM: CP0_CHECK(ctx->vp); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); register_name = "GlobalNumber"; @@ -8455,15 +8471,16 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_04: switch (sel) { - case 0: + case CP0_REG04__CONTEXT: tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); register_name = "Context"; break; - case 1: -// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */ + case CP0_REG04__CONTEXTCONFIG: + /* SmartMIPS ASE */ + /* gen_helper_dmfc0_contextconfig(arg); */ register_name = "ContextConfig"; goto cp0_unimplemented; - case 2: + case CP0_REG04__USERLOCAL: CP0_CHECK(ctx->ulri); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); @@ -8475,41 +8492,41 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_05: switch (sel) { - case 0: + case CP0_REG05__PAGEMASK: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); register_name = "PageMask"; break; - case 1: + case CP0_REG05__PAGEGRAIN: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); register_name = "PageGrain"; break; - case 2: + case CP0_REG05__SEGCTL0: CP0_CHECK(ctx->sc); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0)); register_name = "SegCtl0"; break; - case 3: + case CP0_REG05__SEGCTL1: CP0_CHECK(ctx->sc); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1)); register_name = "SegCtl1"; break; - case 4: + case CP0_REG05__SEGCTL2: CP0_CHECK(ctx->sc); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2)); register_name = "SegCtl2"; break; - case 5: + case CP0_REG05__PWBASE: check_pw(ctx); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase)); register_name = "PWBase"; break; - case 6: + case CP0_REG05__PWFIELD: check_pw(ctx); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField)); register_name = "PWField"; break; - case 7: + case CP0_REG05__PWSIZE: check_pw(ctx); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize)); register_name = "PWSize"; @@ -8520,36 +8537,36 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_06: switch (sel) { - case 0: + case CP0_REG06__WIRED: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); register_name = "Wired"; break; - case 1: + case CP0_REG06__SRSCONF0: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); register_name = "SRSConf0"; break; - case 2: + case CP0_REG06__SRSCONF1: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); register_name = "SRSConf1"; break; - case 3: + case CP0_REG06__SRSCONF2: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); register_name = "SRSConf2"; break; - case 4: + case CP0_REG06__SRSCONF3: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); register_name = "SRSConf3"; break; - case 5: + case CP0_REG06__SRSCONF4: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); register_name = "SRSConf4"; break; - case 6: + case CP0_REG06__PWCTL: check_pw(ctx); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); register_name = "PWCtl"; @@ -8560,7 +8577,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_07: switch (sel) { - case 0: + case CP0_REG07__HWRENA: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); register_name = "HWREna"; @@ -8571,21 +8588,21 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_08: switch (sel) { - case 0: + case CP0_REG08__BADVADDR: tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); register_name = "BadVAddr"; break; - case 1: + case CP0_REG08__BADINSTR: CP0_CHECK(ctx->bi); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); register_name = "BadInstr"; break; - case 2: + case CP0_REG08__BADINSTRP: CP0_CHECK(ctx->bp); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); register_name = "BadInstrP"; break; - case 3: + case CP0_REG08__BADINSTRX: CP0_CHECK(ctx->bi); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); tcg_gen_andi_tl(arg, arg, ~0xffff); @@ -8597,7 +8614,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_09: switch (sel) { - case 0: + case CP0_REG09__COUNT: /* Mark as an IO operation because we read the time. */ if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { gen_io_start(); @@ -8612,12 +8629,12 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) ctx->base.is_jmp = DISAS_EXIT; register_name = "Count"; break; - case 6: + case CP0_REG09__SAARI: CP0_CHECK(ctx->saar); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI)); register_name = "SAARI"; break; - case 7: + case CP0_REG09__SAAR: CP0_CHECK(ctx->saar); gen_helper_dmfc0_saar(arg, cpu_env); register_name = "SAAR"; @@ -8628,7 +8645,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_10: switch (sel) { - case 0: + case CP0_REG10__ENTRYHI: tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); register_name = "EntryHi"; break; @@ -8638,7 +8655,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_11: switch (sel) { - case 0: + case CP0_REG11__COMPARE: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); register_name = "Compare"; break; @@ -8649,21 +8666,21 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_12: switch (sel) { - case 0: + case CP0_REG12__STATUS: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); register_name = "Status"; break; - case 1: + case CP0_REG12__INTCTL: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); register_name = "IntCtl"; break; - case 2: + case CP0_REG12__SRSCTL: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); register_name = "SRSCtl"; break; - case 3: + case CP0_REG12__SRSMAP: check_insn(ctx, ISA_MIPS32R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); register_name = "SRSMap"; @@ -8674,7 +8691,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_13: switch (sel) { - case 0: + case CP0_REG13__CAUSE: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); register_name = "Cause"; break; @@ -8684,7 +8701,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_14: switch (sel) { - case 0: + case CP0_REG14__EPC: tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); register_name = "EPC"; break; @@ -8694,16 +8711,16 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_15: switch (sel) { - case 0: + case CP0_REG15__PRID: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); register_name = "PRid"; break; - case 1: + case CP0_REG15__EBASE: check_insn(ctx, ISA_MIPS32R2); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); register_name = "EBase"; break; - case 3: + case CP0_REG15__CMGCRBASE: check_insn(ctx, ISA_MIPS32R2); CP0_CHECK(ctx->cmgcr); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); @@ -8715,36 +8732,36 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_16: switch (sel) { - case 0: + case CP0_REG16__CONFIG: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); register_name = "Config"; break; - case 1: + case CP0_REG16__CONFIG1: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); register_name = "Config1"; break; - case 2: + case CP0_REG16__CONFIG2: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); register_name = "Config2"; break; - case 3: + case CP0_REG16__CONFIG3: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); register_name = "Config3"; break; - case 4: + case CP0_REG16__CONFIG4: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); register_name = "Config4"; break; - case 5: + case CP0_REG16__CONFIG5: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); register_name = "Config5"; break; /* 6,7 are implementation dependent */ - case 6: + case CP0_REG16__CONFIG6: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); register_name = "Config6"; break; - case 7: + case CP0_REG16__CONFIG7: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); register_name = "Config7"; break; @@ -8754,16 +8771,16 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_17: switch (sel) { - case 0: + case CP0_REG17__LLADDR: gen_helper_dmfc0_lladdr(arg, cpu_env); register_name = "LLAddr"; break; - case 1: + case CP0_REG17__MAAR: CP0_CHECK(ctx->mrp); gen_helper_dmfc0_maar(arg, cpu_env); register_name = "MAAR"; break; - case 2: + case CP0_REG17__MAARI: CP0_CHECK(ctx->mrp); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); register_name = "MAARI"; @@ -8774,14 +8791,14 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_18: switch (sel) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: + case CP0_REG18__WATCHLO0: + case CP0_REG18__WATCHLO1: + case CP0_REG18__WATCHLO2: + case CP0_REG18__WATCHLO3: + case CP0_REG18__WATCHLO4: + case CP0_REG18__WATCHLO5: + case CP0_REG18__WATCHLO6: + case CP0_REG18__WATCHLO7: CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_1e0i(dmfc0_watchlo, arg, sel); register_name = "WatchLo"; @@ -8792,14 +8809,14 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_19: switch (sel) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: + case CP0_REG19__WATCHHI0: + case CP0_REG19__WATCHHI1: + case CP0_REG19__WATCHHI2: + case CP0_REG19__WATCHHI3: + case CP0_REG19__WATCHHI4: + case CP0_REG19__WATCHHI5: + case CP0_REG19__WATCHHI6: + case CP0_REG19__WATCHHI7: CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_1e0i(mfc0_watchhi, arg, sel); register_name = "WatchHi"; @@ -8810,7 +8827,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_20: switch (sel) { - case 0: + case CP0_REG20__XCONTEXT: check_insn(ctx, ISA_MIPS3); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); register_name = "XContext"; @@ -8837,25 +8854,34 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_23: switch (sel) { - case 0: + case CP0_REG23__DEBUG: gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ register_name = "Debug"; break; - case 1: -// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */ + case CP0_REG23__TRACECONTROL: + /* PDtrace support */ + /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */ register_name = "TraceControl"; goto cp0_unimplemented; - case 2: -// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */ + case CP0_REG23__TRACECONTROL2: + /* PDtrace support */ + /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */ register_name = "TraceControl2"; goto cp0_unimplemented; - case 3: -// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */ - register_name = "UserTraceData"; + case CP0_REG23__USERTRACEDATA1: + /* PDtrace support */ + /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/ + register_name = "UserTraceData1"; goto cp0_unimplemented; - case 4: -// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */ - register_name = "TraceBPC"; + case CP0_REG23__TRACEIBPC: + /* PDtrace support */ + /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */ + register_name = "TraceIBPC"; + goto cp0_unimplemented; + case CP0_REG23__TRACEDBPC: + /* PDtrace support */ + /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */ + register_name = "TraceDBPC"; goto cp0_unimplemented; default: goto cp0_unimplemented; @@ -8863,7 +8889,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_24: switch (sel) { - case 0: + case CP0_REG24__DEPC: /* EJTAG support */ tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); register_name = "DEPC"; @@ -8874,35 +8900,35 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_25: switch (sel) { - case 0: + case CP0_REG25__PERFCTL0: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); register_name = "Performance0"; break; - case 1: + case CP0_REG25__PERFCNT0: /* gen_helper_dmfc0_performance1(arg); */ register_name = "Performance1"; goto cp0_unimplemented; - case 2: + case CP0_REG25__PERFCTL1: /* gen_helper_dmfc0_performance2(arg); */ register_name = "Performance2"; goto cp0_unimplemented; - case 3: + case CP0_REG25__PERFCNT1: /* gen_helper_dmfc0_performance3(arg); */ register_name = "Performance3"; goto cp0_unimplemented; - case 4: + case CP0_REG25__PERFCTL2: /* gen_helper_dmfc0_performance4(arg); */ register_name = "Performance4"; goto cp0_unimplemented; - case 5: + case CP0_REG25__PERFCNT2: /* gen_helper_dmfc0_performance5(arg); */ register_name = "Performance5"; goto cp0_unimplemented; - case 6: + case CP0_REG25__PERFCTL3: /* gen_helper_dmfc0_performance6(arg); */ register_name = "Performance6"; goto cp0_unimplemented; - case 7: + case CP0_REG25__PERFCNT3: /* gen_helper_dmfc0_performance7(arg); */ register_name = "Performance7"; goto cp0_unimplemented; @@ -8912,7 +8938,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_26: switch (sel) { - case 0: + case CP0_REG26__ERRCTL: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); register_name = "ErrCtl"; break; @@ -8923,10 +8949,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case CP0_REGISTER_27: switch (sel) { /* ignored */ - case 0: - case 1: - case 2: - case 3: + case CP0_REG27__CACHERR: tcg_gen_movi_tl(arg, 0); /* unimplemented */ register_name = "CacheErr"; break; @@ -8936,17 +8959,17 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_28: switch (sel) { - case 0: - case 2: - case 4: - case 6: + case CP0_REG28__TAGLO: + case CP0_REG28__TAGLO1: + case CP0_REG28__TAGLO2: + case CP0_REG28__TAGLO3: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); register_name = "TagLo"; break; - case 1: - case 3: - case 5: - case 7: + case CP0_REG28__DATALO: + case CP0_REG28__DATALO1: + case CP0_REG28__DATALO2: + case CP0_REG28__DATALO3: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); register_name = "DataLo"; break; @@ -8956,17 +8979,17 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_29: switch (sel) { - case 0: - case 2: - case 4: - case 6: + case CP0_REG29__TAGHI: + case CP0_REG29__TAGHI1: + case CP0_REG29__TAGHI2: + case CP0_REG29__TAGHI3: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); register_name = "TagHi"; break; - case 1: - case 3: - case 5: - case 7: + case CP0_REG29__DATAHI: + case CP0_REG29__DATAHI1: + case CP0_REG29__DATAHI2: + case CP0_REG29__DATAHI3: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); register_name = "DataHi"; break; @@ -8976,7 +8999,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_30: switch (sel) { - case 0: + case CP0_REG30__ERROREPC: tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); register_name = "ErrorEPC"; break; @@ -8986,17 +9009,17 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_31: switch (sel) { - case 0: + case CP0_REG31__DESAVE: /* EJTAG support */ gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); register_name = "DESAVE"; break; - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: + case CP0_REG31__KSCRATCH1: + case CP0_REG31__KSCRATCH2: + case CP0_REG31__KSCRATCH3: + case CP0_REG31__KSCRATCH4: + case CP0_REG31__KSCRATCH5: + case CP0_REG31__KSCRATCH6: CP0_CHECK(ctx->kscrexist & (1 << sel)); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_KScratch[sel-2])); @@ -9033,26 +9056,26 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) switch (reg) { case CP0_REGISTER_00: switch (sel) { - case 0: + case CP0_REG00__INDEX: gen_helper_mtc0_index(cpu_env, arg); register_name = "Index"; break; - case 1: + case CP0_REG00__MVPCONTROL: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_mvpcontrol(cpu_env, arg); register_name = "MVPControl"; break; - case 2: + case CP0_REG00__MVPCONF0: CP0_CHECK(ctx->insn_flags & ASE_MT); /* ignored */ register_name = "MVPConf0"; break; - case 3: + case CP0_REG00__MVPCONF1: CP0_CHECK(ctx->insn_flags & ASE_MT); /* ignored */ register_name = "MVPConf1"; break; - case 4: + case CP0_REG00__VPCONTROL: CP0_CHECK(ctx->vp); /* ignored */ register_name = "VPControl"; @@ -9063,41 +9086,41 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_01: switch (sel) { - case 0: + case CP0_REG01__RANDOM: /* ignored */ register_name = "Random"; break; - case 1: + case CP0_REG01__VPECONTROL: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_vpecontrol(cpu_env, arg); register_name = "VPEControl"; break; - case 2: + case CP0_REG01__VPECONF0: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_vpeconf0(cpu_env, arg); register_name = "VPEConf0"; break; - case 3: + case CP0_REG01__VPECONF1: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_vpeconf1(cpu_env, arg); register_name = "VPEConf1"; break; - case 4: + case CP0_REG01__YQMASK: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_yqmask(cpu_env, arg); register_name = "YQMask"; break; - case 5: + case CP0_REG01__VPESCHEDULE: CP0_CHECK(ctx->insn_flags & ASE_MT); tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule)); register_name = "VPESchedule"; break; - case 6: + case CP0_REG01__VPESCHEFBACK: CP0_CHECK(ctx->insn_flags & ASE_MT); tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack)); register_name = "VPEScheFBack"; break; - case 7: + case CP0_REG01__VPEOPT: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_vpeopt(cpu_env, arg); register_name = "VPEOpt"; @@ -9108,41 +9131,41 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_02: switch (sel) { - case 0: + case CP0_REG02__ENTRYLO0: gen_helper_dmtc0_entrylo0(cpu_env, arg); register_name = "EntryLo0"; break; - case 1: + case CP0_REG02__TCSTATUS: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_tcstatus(cpu_env, arg); register_name = "TCStatus"; break; - case 2: + case CP0_REG02__TCBIND: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_tcbind(cpu_env, arg); register_name = "TCBind"; break; - case 3: + case CP0_REG02__TCRESTART: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_tcrestart(cpu_env, arg); register_name = "TCRestart"; break; - case 4: + case CP0_REG02__TCHALT: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_tchalt(cpu_env, arg); register_name = "TCHalt"; break; - case 5: + case CP0_REG02__TCCONTEXT: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_tccontext(cpu_env, arg); register_name = "TCContext"; break; - case 6: + case CP0_REG02__TCSCHEDULE: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_tcschedule(cpu_env, arg); register_name = "TCSchedule"; break; - case 7: + case CP0_REG02__TCSCHEFBACK: CP0_CHECK(ctx->insn_flags & ASE_MT); gen_helper_mtc0_tcschefback(cpu_env, arg); register_name = "TCScheFBack"; @@ -9153,11 +9176,11 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_03: switch (sel) { - case 0: + case CP0_REG03__ENTRYLO1: gen_helper_dmtc0_entrylo1(cpu_env, arg); register_name = "EntryLo1"; break; - case 1: + case CP0_REG03__GLOBALNUM: CP0_CHECK(ctx->vp); /* ignored */ register_name = "GlobalNumber"; @@ -9168,15 +9191,16 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_04: switch (sel) { - case 0: + case CP0_REG04__CONTEXT: gen_helper_mtc0_context(cpu_env, arg); register_name = "Context"; break; - case 1: -// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */ + case CP0_REG04__CONTEXTCONFIG: + /* SmartMIPS ASE */ + /* gen_helper_dmtc0_contextconfig(arg); */ register_name = "ContextConfig"; goto cp0_unimplemented; - case 2: + case CP0_REG04__USERLOCAL: CP0_CHECK(ctx->ulri); tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); @@ -9188,41 +9212,41 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_05: switch (sel) { - case 0: + case CP0_REG05__PAGEMASK: gen_helper_mtc0_pagemask(cpu_env, arg); register_name = "PageMask"; break; - case 1: + case CP0_REG05__PAGEGRAIN: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_pagegrain(cpu_env, arg); register_name = "PageGrain"; break; - case 2: + case CP0_REG05__SEGCTL0: CP0_CHECK(ctx->sc); gen_helper_mtc0_segctl0(cpu_env, arg); register_name = "SegCtl0"; break; - case 3: + case CP0_REG05__SEGCTL1: CP0_CHECK(ctx->sc); gen_helper_mtc0_segctl1(cpu_env, arg); register_name = "SegCtl1"; break; - case 4: + case CP0_REG05__SEGCTL2: CP0_CHECK(ctx->sc); gen_helper_mtc0_segctl2(cpu_env, arg); register_name = "SegCtl2"; break; - case 5: + case CP0_REG05__PWBASE: check_pw(ctx); tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase)); register_name = "PWBase"; break; - case 6: + case CP0_REG05__PWFIELD: check_pw(ctx); gen_helper_mtc0_pwfield(cpu_env, arg); register_name = "PWField"; break; - case 7: + case CP0_REG05__PWSIZE: check_pw(ctx); gen_helper_mtc0_pwsize(cpu_env, arg); register_name = "PWSize"; @@ -9233,36 +9257,36 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_06: switch (sel) { - case 0: + case CP0_REG06__WIRED: gen_helper_mtc0_wired(cpu_env, arg); register_name = "Wired"; break; - case 1: + case CP0_REG06__SRSCONF0: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_srsconf0(cpu_env, arg); register_name = "SRSConf0"; break; - case 2: + case CP0_REG06__SRSCONF1: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_srsconf1(cpu_env, arg); register_name = "SRSConf1"; break; - case 3: + case CP0_REG06__SRSCONF2: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_srsconf2(cpu_env, arg); register_name = "SRSConf2"; break; - case 4: + case CP0_REG06__SRSCONF3: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_srsconf3(cpu_env, arg); register_name = "SRSConf3"; break; - case 5: + case CP0_REG06__SRSCONF4: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_srsconf4(cpu_env, arg); register_name = "SRSConf4"; break; - case 6: + case CP0_REG06__PWCTL: check_pw(ctx); gen_helper_mtc0_pwctl(cpu_env, arg); register_name = "PWCtl"; @@ -9273,7 +9297,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_07: switch (sel) { - case 0: + case CP0_REG07__HWRENA: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_hwrena(cpu_env, arg); ctx->base.is_jmp = DISAS_STOP; @@ -9285,19 +9309,19 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_08: switch (sel) { - case 0: + case CP0_REG08__BADVADDR: /* ignored */ register_name = "BadVAddr"; break; - case 1: + case CP0_REG08__BADINSTR: /* ignored */ register_name = "BadInstr"; break; - case 2: + case CP0_REG08__BADINSTRP: /* ignored */ register_name = "BadInstrP"; break; - case 3: + case CP0_REG08__BADINSTRX: /* ignored */ register_name = "BadInstrX"; break; @@ -9307,16 +9331,16 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_09: switch (sel) { - case 0: + case CP0_REG09__COUNT: gen_helper_mtc0_count(cpu_env, arg); register_name = "Count"; break; - case 6: + case CP0_REG09__SAARI: CP0_CHECK(ctx->saar); gen_helper_mtc0_saari(cpu_env, arg); register_name = "SAARI"; break; - case 7: + case CP0_REG09__SAAR: CP0_CHECK(ctx->saar); gen_helper_mtc0_saar(cpu_env, arg); register_name = "SAAR"; @@ -9329,7 +9353,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_10: switch (sel) { - case 0: + case CP0_REG10__ENTRYHI: gen_helper_mtc0_entryhi(cpu_env, arg); register_name = "EntryHi"; break; @@ -9339,7 +9363,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_11: switch (sel) { - case 0: + case CP0_REG11__COMPARE: gen_helper_mtc0_compare(cpu_env, arg); register_name = "Compare"; break; @@ -9352,7 +9376,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_12: switch (sel) { - case 0: + case CP0_REG12__STATUS: save_cpu_state(ctx, 1); gen_helper_mtc0_status(cpu_env, arg); /* DISAS_STOP isn't good enough here, hflags may have changed. */ @@ -9360,21 +9384,21 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) ctx->base.is_jmp = DISAS_EXIT; register_name = "Status"; break; - case 1: + case CP0_REG12__INTCTL: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_intctl(cpu_env, arg); /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; register_name = "IntCtl"; break; - case 2: + case CP0_REG12__SRSCTL: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_srsctl(cpu_env, arg); /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; register_name = "SRSCtl"; break; - case 3: + case CP0_REG12__SRSMAP: check_insn(ctx, ISA_MIPS32R2); gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); /* Stop translation as we may have switched the execution mode */ @@ -9387,7 +9411,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_13: switch (sel) { - case 0: + case CP0_REG13__CAUSE: save_cpu_state(ctx, 1); gen_helper_mtc0_cause(cpu_env, arg); /* @@ -9405,7 +9429,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_14: switch (sel) { - case 0: + case CP0_REG14__EPC: tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); register_name = "EPC"; break; @@ -9415,11 +9439,11 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_15: switch (sel) { - case 0: + case CP0_REG15__PRID: /* ignored */ register_name = "PRid"; break; - case 1: + case CP0_REG15__EBASE: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_ebase(cpu_env, arg); register_name = "EBase"; @@ -9430,33 +9454,33 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_16: switch (sel) { - case 0: + case CP0_REG16__CONFIG: gen_helper_mtc0_config0(cpu_env, arg); register_name = "Config"; /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; break; - case 1: + case CP0_REG16__CONFIG1: /* ignored, read only */ register_name = "Config1"; break; - case 2: + case CP0_REG16__CONFIG2: gen_helper_mtc0_config2(cpu_env, arg); register_name = "Config2"; /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; break; - case 3: + case CP0_REG16__CONFIG3: gen_helper_mtc0_config3(cpu_env, arg); register_name = "Config3"; /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; break; - case 4: + case CP0_REG16__CONFIG4: /* currently ignored */ register_name = "Config4"; break; - case 5: + case CP0_REG16__CONFIG5: gen_helper_mtc0_config5(cpu_env, arg); register_name = "Config5"; /* Stop translation as we may have switched the execution mode */ @@ -9470,16 +9494,16 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_17: switch (sel) { - case 0: + case CP0_REG17__LLADDR: gen_helper_mtc0_lladdr(cpu_env, arg); register_name = "LLAddr"; break; - case 1: + case CP0_REG17__MAAR: CP0_CHECK(ctx->mrp); gen_helper_mtc0_maar(cpu_env, arg); register_name = "MAAR"; break; - case 2: + case CP0_REG17__MAARI: CP0_CHECK(ctx->mrp); gen_helper_mtc0_maari(cpu_env, arg); register_name = "MAARI"; @@ -9490,14 +9514,14 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_18: switch (sel) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: + case CP0_REG18__WATCHLO0: + case CP0_REG18__WATCHLO1: + case CP0_REG18__WATCHLO2: + case CP0_REG18__WATCHLO3: + case CP0_REG18__WATCHLO4: + case CP0_REG18__WATCHLO5: + case CP0_REG18__WATCHLO6: + case CP0_REG18__WATCHLO7: CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_0e1i(mtc0_watchlo, arg, sel); register_name = "WatchLo"; @@ -9508,14 +9532,14 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_19: switch (sel) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: + case CP0_REG19__WATCHHI0: + case CP0_REG19__WATCHHI1: + case CP0_REG19__WATCHHI2: + case CP0_REG19__WATCHHI3: + case CP0_REG19__WATCHHI4: + case CP0_REG19__WATCHHI5: + case CP0_REG19__WATCHHI6: + case CP0_REG19__WATCHHI7: CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_0e1i(mtc0_watchhi, arg, sel); register_name = "WatchHi"; @@ -9526,7 +9550,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_20: switch (sel) { - case 0: + case CP0_REG20__XCONTEXT: check_insn(ctx, ISA_MIPS3); gen_helper_mtc0_xcontext(cpu_env, arg); register_name = "XContext"; @@ -9553,36 +9577,47 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_23: switch (sel) { - case 0: + case CP0_REG23__DEBUG: gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ /* DISAS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->base.pc_next + 4); ctx->base.is_jmp = DISAS_EXIT; register_name = "Debug"; break; - case 1: -// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */ + case CP0_REG23__TRACECONTROL: + /* PDtrace support */ + /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */ /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; register_name = "TraceControl"; goto cp0_unimplemented; - case 2: -// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */ + case CP0_REG23__TRACECONTROL2: + /* PDtrace support */ + /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */ /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; register_name = "TraceControl2"; goto cp0_unimplemented; - case 3: -// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */ + case CP0_REG23__USERTRACEDATA1: + /* PDtrace support */ + /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/ /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; - register_name = "UserTraceData"; + register_name = "UserTraceData1"; goto cp0_unimplemented; - case 4: -// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */ + case CP0_REG23__TRACEIBPC: + /* PDtrace support */ + /* gen_helper_mtc0_traceibpc(cpu_env, arg); */ /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; - register_name = "TraceBPC"; + register_name = "TraceIBPC"; + goto cp0_unimplemented; + case CP0_REG23__TRACEDBPC: + /* PDtrace support */ + /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */ + /* Stop translation as we may have switched the execution mode */ + ctx->base.is_jmp = DISAS_STOP; + register_name = "TraceDBPC"; goto cp0_unimplemented; default: goto cp0_unimplemented; @@ -9590,7 +9625,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_24: switch (sel) { - case 0: + case CP0_REG24__DEPC: /* EJTAG support */ tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); register_name = "DEPC"; @@ -9601,35 +9636,35 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_25: switch (sel) { - case 0: + case CP0_REG25__PERFCTL0: gen_helper_mtc0_performance0(cpu_env, arg); register_name = "Performance0"; break; - case 1: + case CP0_REG25__PERFCNT0: /* gen_helper_mtc0_performance1(cpu_env, arg); */ register_name = "Performance1"; goto cp0_unimplemented; - case 2: + case CP0_REG25__PERFCTL1: /* gen_helper_mtc0_performance2(cpu_env, arg); */ register_name = "Performance2"; goto cp0_unimplemented; - case 3: + case CP0_REG25__PERFCNT1: /* gen_helper_mtc0_performance3(cpu_env, arg); */ register_name = "Performance3"; goto cp0_unimplemented; - case 4: + case CP0_REG25__PERFCTL2: /* gen_helper_mtc0_performance4(cpu_env, arg); */ register_name = "Performance4"; goto cp0_unimplemented; - case 5: + case CP0_REG25__PERFCNT2: /* gen_helper_mtc0_performance5(cpu_env, arg); */ register_name = "Performance5"; goto cp0_unimplemented; - case 6: + case CP0_REG25__PERFCTL3: /* gen_helper_mtc0_performance6(cpu_env, arg); */ register_name = "Performance6"; goto cp0_unimplemented; - case 7: + case CP0_REG25__PERFCNT3: /* gen_helper_mtc0_performance7(cpu_env, arg); */ register_name = "Performance7"; goto cp0_unimplemented; @@ -9639,7 +9674,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_26: switch (sel) { - case 0: + case CP0_REG26__ERRCTL: gen_helper_mtc0_errctl(cpu_env, arg); ctx->base.is_jmp = DISAS_STOP; register_name = "ErrCtl"; @@ -9650,10 +9685,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_27: switch (sel) { - case 0: - case 1: - case 2: - case 3: + case CP0_REG27__CACHERR: /* ignored */ register_name = "CacheErr"; break; @@ -9663,17 +9695,17 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_28: switch (sel) { - case 0: - case 2: - case 4: - case 6: + case CP0_REG28__TAGLO: + case CP0_REG28__TAGLO1: + case CP0_REG28__TAGLO2: + case CP0_REG28__TAGLO3: gen_helper_mtc0_taglo(cpu_env, arg); register_name = "TagLo"; break; - case 1: - case 3: - case 5: - case 7: + case CP0_REG28__DATALO: + case CP0_REG28__DATALO1: + case CP0_REG28__DATALO2: + case CP0_REG28__DATALO3: gen_helper_mtc0_datalo(cpu_env, arg); register_name = "DataLo"; break; @@ -9683,17 +9715,17 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_29: switch (sel) { - case 0: - case 2: - case 4: - case 6: + case CP0_REG29__TAGHI: + case CP0_REG29__TAGHI1: + case CP0_REG29__TAGHI2: + case CP0_REG29__TAGHI3: gen_helper_mtc0_taghi(cpu_env, arg); register_name = "TagHi"; break; - case 1: - case 3: - case 5: - case 7: + case CP0_REG29__DATAHI: + case CP0_REG29__DATAHI1: + case CP0_REG29__DATAHI2: + case CP0_REG29__DATAHI3: gen_helper_mtc0_datahi(cpu_env, arg); register_name = "DataHi"; break; @@ -9704,7 +9736,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_30: switch (sel) { - case 0: + case CP0_REG30__ERROREPC: tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); register_name = "ErrorEPC"; break; @@ -9714,17 +9746,17 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_31: switch (sel) { - case 0: + case CP0_REG31__DESAVE: /* EJTAG support */ gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); register_name = "DESAVE"; break; - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: + case CP0_REG31__KSCRATCH1: + case CP0_REG31__KSCRATCH2: + case CP0_REG31__KSCRATCH3: + case CP0_REG31__KSCRATCH4: + case CP0_REG31__KSCRATCH5: + case CP0_REG31__KSCRATCH6: CP0_CHECK(ctx->kscrexist & (1 << sel)); tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h index 7ffdb0a706..e499575dc8 100644 --- a/target/ppc/cpu-qom.h +++ b/target/ppc/cpu-qom.h @@ -191,6 +191,7 @@ typedef struct PowerPCCPUClass { const PPCHash64Options *hash64_opts; struct ppc_radix_page_info *radix_page_info; uint32_t lrg_decr_bits; + int n_host_threads; void (*init_proc)(CPUPPCState *env); int (*check_pow)(CPUPPCState *env); int (*handle_mmu_fault)(PowerPCCPU *cpu, vaddr eaddr, int rwx, int mmu_idx); diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index 07bc9051b0..4b1a2e6178 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -630,19 +630,15 @@ static void do_float_check_status(CPUPPCState *env, uintptr_t raddr) { CPUState *cs = env_cpu(env); int status = get_float_exception_flags(&env->fp_status); - bool inexact_happened = false; if (status & float_flag_overflow) { float_overflow_excp(env); } else if (status & float_flag_underflow) { float_underflow_excp(env); - } else if (status & float_flag_inexact) { - float_inexact_excp(env); - inexact_happened = true; } - - /* if the inexact flag was not set */ - if (inexact_happened == false) { + if (status & float_flag_inexact) { + float_inexact_excp(env); + } else { env->fpscr &= ~(1 << FPSCR_FI); /* clear the FPSCR[FI] bit */ } @@ -2887,12 +2883,40 @@ void helper_xscvqpdp(CPUPPCState *env, uint32_t opcode, uint64_t helper_xscvdpspn(CPUPPCState *env, uint64_t xb) { - uint64_t result; + uint64_t result, sign, exp, frac; float_status tstat = env->fp_status; set_float_exception_flags(0, &tstat); - result = (uint64_t)float64_to_float32(xb, &tstat); + sign = extract64(xb, 63, 1); + exp = extract64(xb, 52, 11); + frac = extract64(xb, 0, 52) | 0x10000000000000ULL; + + if (unlikely(exp == 0 && extract64(frac, 0, 52) != 0)) { + /* DP denormal operand. */ + /* Exponent override to DP min exp. */ + exp = 1; + /* Implicit bit override to 0. */ + frac = deposit64(frac, 53, 1, 0); + } + + if (unlikely(exp < 897 && frac != 0)) { + /* SP tiny operand. */ + if (897 - exp > 63) { + frac = 0; + } else { + /* Denormalize until exp = SP min exp. */ + frac >>= (897 - exp); + } + /* Exponent override to SP min exp - 1. */ + exp = 896; + } + + result = sign << 31; + result |= extract64(exp, 10, 1) << 30; + result |= extract64(exp, 0, 7) << 23; + result |= extract64(frac, 29, 23); + /* hardware replicates result to both words of the doubleword result. */ return (result << 32) | result; } diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 0d71c10428..2472a5217a 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -350,6 +350,28 @@ static void glue(gen_, name0##_##name1)(DisasContext *ctx) \ } \ } +/* + * We use this macro if one instruction is realized with direct + * translation, and second one with helper. + */ +#define GEN_VXFORM_TRANS_DUAL(name0, flg0, flg2_0, name1, flg1, flg2_1)\ +static void glue(gen_, name0##_##name1)(DisasContext *ctx) \ +{ \ + if ((Rc(ctx->opcode) == 0) && \ + ((ctx->insns_flags & flg0) || (ctx->insns_flags2 & flg2_0))) { \ + if (unlikely(!ctx->altivec_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VPU); \ + return; \ + } \ + trans_##name0(ctx); \ + } else if ((Rc(ctx->opcode) == 1) && \ + ((ctx->insns_flags & flg1) || (ctx->insns_flags2 & flg2_1))) { \ + gen_##name1(ctx); \ + } else { \ + gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \ + } \ +} + /* Adds support to provide invalid mask */ #define GEN_VXFORM_DUAL_EXT(name0, flg0, flg2_0, inval0, \ name1, flg1, flg2_1, inval1) \ @@ -431,20 +453,13 @@ GEN_VXFORM(vmrglb, 6, 4); GEN_VXFORM(vmrglh, 6, 5); GEN_VXFORM(vmrglw, 6, 6); -static void gen_vmrgew(DisasContext *ctx) +static void trans_vmrgew(DisasContext *ctx) { - TCGv_i64 tmp; - TCGv_i64 avr; - int VT, VA, VB; - if (unlikely(!ctx->altivec_enabled)) { - gen_exception(ctx, POWERPC_EXCP_VPU); - return; - } - VT = rD(ctx->opcode); - VA = rA(ctx->opcode); - VB = rB(ctx->opcode); - tmp = tcg_temp_new_i64(); - avr = tcg_temp_new_i64(); + int VT = rD(ctx->opcode); + int VA = rA(ctx->opcode); + int VB = rB(ctx->opcode); + TCGv_i64 tmp = tcg_temp_new_i64(); + TCGv_i64 avr = tcg_temp_new_i64(); get_avr64(avr, VB, true); tcg_gen_shri_i64(tmp, avr, 32); @@ -462,21 +477,14 @@ static void gen_vmrgew(DisasContext *ctx) tcg_temp_free_i64(avr); } -static void gen_vmrgow(DisasContext *ctx) +static void trans_vmrgow(DisasContext *ctx) { - TCGv_i64 t0, t1; - TCGv_i64 avr; - int VT, VA, VB; - if (unlikely(!ctx->altivec_enabled)) { - gen_exception(ctx, POWERPC_EXCP_VPU); - return; - } - VT = rD(ctx->opcode); - VA = rA(ctx->opcode); - VB = rB(ctx->opcode); - t0 = tcg_temp_new_i64(); - t1 = tcg_temp_new_i64(); - avr = tcg_temp_new_i64(); + int VT = rD(ctx->opcode); + int VA = rA(ctx->opcode); + int VB = rB(ctx->opcode); + TCGv_i64 t0 = tcg_temp_new_i64(); + TCGv_i64 t1 = tcg_temp_new_i64(); + TCGv_i64 avr = tcg_temp_new_i64(); get_avr64(t0, VB, true); get_avr64(t1, VA, true); @@ -936,14 +944,14 @@ GEN_VXFORM_ENV(vminfp, 5, 17); GEN_VXFORM_HETRO(vextublx, 6, 24) GEN_VXFORM_HETRO(vextuhlx, 6, 25) GEN_VXFORM_HETRO(vextuwlx, 6, 26) -GEN_VXFORM_DUAL(vmrgow, PPC_NONE, PPC2_ALTIVEC_207, +GEN_VXFORM_TRANS_DUAL(vmrgow, PPC_NONE, PPC2_ALTIVEC_207, vextuwlx, PPC_NONE, PPC2_ISA300) GEN_VXFORM_HETRO(vextubrx, 6, 28) GEN_VXFORM_HETRO(vextuhrx, 6, 29) GEN_VXFORM_HETRO(vextuwrx, 6, 30) GEN_VXFORM_TRANS(lvsl, 6, 31) GEN_VXFORM_TRANS(lvsr, 6, 32) -GEN_VXFORM_DUAL(vmrgew, PPC_NONE, PPC2_ALTIVEC_207, \ +GEN_VXFORM_TRANS_DUAL(vmrgew, PPC_NONE, PPC2_ALTIVEC_207, vextuwrx, PPC_NONE, PPC2_ISA300) #define GEN_VXRFORM1(opname, name, str, opc2, opc3) \ diff --git a/target/ppc/translate/vsx-impl.inc.c b/target/ppc/translate/vsx-impl.inc.c index 3922686ad6..8287e272f5 100644 --- a/target/ppc/translate/vsx-impl.inc.c +++ b/target/ppc/translate/vsx-impl.inc.c @@ -1308,7 +1308,7 @@ static void gen_##name(DisasContext *ctx) \ } \ xt = gen_vsr_ptr(xT(ctx->opcode)); \ xa = gen_vsr_ptr(xA(ctx->opcode)); \ - if (ctx->opcode & PPC_BIT(25)) { \ + if (ctx->opcode & PPC_BIT32(25)) { \ /* \ * AxT + B \ */ \ diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index 4a21ed7289..0fb11c7ac6 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -8770,6 +8770,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault; pcc->hash64_opts = &ppc_hash64_opts_POWER7; pcc->lrg_decr_bits = 32; + pcc->n_host_threads = 8; #endif pcc->excp_model = POWERPC_EXCP_POWER8; pcc->bus_model = PPC_FLAGS_INPUT_POWER7; @@ -8981,6 +8982,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) pcc->hash64_opts = &ppc_hash64_opts_POWER7; pcc->radix_page_info = &POWER9_radix_page_info; pcc->lrg_decr_bits = 56; + pcc->n_host_threads = 4; #endif pcc->excp_model = POWERPC_EXCP_POWER9; pcc->bus_model = PPC_FLAGS_INPUT_POWER9; @@ -10461,6 +10463,10 @@ static void ppc_cpu_reset(CPUState *s) s->exception_index = POWERPC_EXCP_NONE; env->error_code = 0; + /* tininess for underflow is detected before rounding */ + set_float_detect_tininess(float_tininess_before_rounding, + &env->fp_status); + for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) { ppc_spr_t *spr = &env->spr_cb[i]; diff --git a/tcg/README b/tcg/README index 21fcdf737f..ef9be5ba90 100644 --- a/tcg/README +++ b/tcg/README @@ -101,7 +101,7 @@ This can be overridden using the following function modifiers: canonical locations before calling the helper. - TCG_CALL_NO_WRITE_GLOBALS means that the helper does not modify any globals. They will only be saved to their canonical location before calling helpers, - but they won't be reloaded afterwise. + but they won't be reloaded afterwards. - TCG_CALL_NO_SIDE_EFFECTS means that the call to the function is removed if the return value is not used. diff --git a/tests/acceptance/pc_cpu_hotplug_props.py b/tests/acceptance/pc_cpu_hotplug_props.py new file mode 100644 index 0000000000..08b7e632c6 --- /dev/null +++ b/tests/acceptance/pc_cpu_hotplug_props.py @@ -0,0 +1,35 @@ +# +# Ensure CPU die-id can be omitted on -device +# +# Copyright (c) 2019 Red Hat Inc +# +# Author: +# Eduardo Habkost <ehabkost@redhat.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, see <http://www.gnu.org/licenses/>. +# + +from avocado_qemu import Test + +class OmittedCPUProps(Test): + """ + :avocado: tags=arch:x86_64 + """ + def test_no_die_id(self): + self.vm.add_args('-nodefaults', '-S') + self.vm.add_args('-smp', '1,sockets=2,cores=2,threads=2,maxcpus=8') + self.vm.add_args('-cpu', 'qemu64') + self.vm.add_args('-device', 'qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0') + self.vm.launch() + self.assertEquals(len(self.vm.command('query-cpus')), 2) diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c index 24852d4c7d..a54d007298 100644 --- a/tests/boot-serial-test.c +++ b/tests/boot-serial-test.c @@ -103,7 +103,8 @@ static testdef_t tests[] = { { "ppc64", "pseries", "-machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken", "Open Firmware" }, - { "ppc64", "powernv", "-cpu POWER8", "OPAL" }, + { "ppc64", "powernv8", "", "OPAL" }, + { "ppc64", "powernv9", "", "OPAL" }, { "ppc64", "sam460ex", "-device e1000", "8086 100e" }, { "i386", "isapc", "-cpu qemu32 -device sga", "SGABIOS" }, { "i386", "pc", "-device sga", "SGABIOS" }, diff --git a/tests/check-block.sh b/tests/check-block.sh index c8b6cec3f6..679aedec50 100755 --- a/tests/check-block.sh +++ b/tests/check-block.sh @@ -21,6 +21,11 @@ if grep -q "TARGET_GPROF=y" *-softmmu/config-target.mak 2>/dev/null ; then exit 0 fi +if grep -q "CFLAGS.*-fsanitize" config-host.mak 2>/dev/null ; then + echo "Sanitizers are enabled ==> Not running the qemu-iotests." + exit 0 +fi + if [ -z "$(find . -name 'qemu-system-*' -print)" ]; then echo "No qemu-system binary available ==> Not running the qemu-iotests." exit 0 diff --git a/tests/docker/docker.py b/tests/docker/docker.py index ac5baab4ca..4bba29e104 100755 --- a/tests/docker/docker.py +++ b/tests/docker/docker.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # # Docker controlling module # @@ -11,7 +11,6 @@ # or (at your option) any later version. See the COPYING file in # the top-level directory. -from __future__ import print_function import os import sys import subprocess @@ -25,10 +24,7 @@ import tempfile import re import signal from tarfile import TarFile, TarInfo -try: - from StringIO import StringIO -except ImportError: - from io import StringIO +from io import StringIO from shutil import copy, rmtree from pwd import getpwuid from datetime import datetime, timedelta @@ -62,11 +58,13 @@ USE_ENGINE = EngineEnum.AUTO def _text_checksum(text): """Calculate a digest string unique to the text content""" - return hashlib.sha1(text).hexdigest() + return hashlib.sha1(text.encode('utf-8')).hexdigest() +def _read_dockerfile(path): + return open(path, 'rt', encoding='utf-8').read() def _file_checksum(filename): - return _text_checksum(open(filename, 'rb').read()) + return _text_checksum(_read_dockerfile(filename)) def _guess_engine_command(): @@ -192,7 +190,7 @@ def _read_qemu_dockerfile(img_name): df = os.path.join(os.path.dirname(__file__), "dockerfiles", img_name + ".docker") - return open(df, "r").read() + return _read_dockerfile(df) def _dockerfile_preprocess(df): @@ -262,6 +260,7 @@ class Docker(object): def _output(self, cmd, **kwargs): return subprocess.check_output(self._command + cmd, stderr=subprocess.STDOUT, + encoding='utf-8', **kwargs) def inspect_tag(self, tag): @@ -283,7 +282,9 @@ class Docker(object): if argv is None: argv = [] - tmp_df = tempfile.NamedTemporaryFile(dir=docker_dir, suffix=".docker") + tmp_df = tempfile.NamedTemporaryFile(mode="w+t", + encoding='utf-8', + dir=docker_dir, suffix=".docker") tmp_df.write(dockerfile) if user: @@ -396,7 +397,7 @@ class BuildCommand(SubCommand): help="Dockerfile name") def run(self, args, argv): - dockerfile = open(args.dockerfile, "rb").read() + dockerfile = _read_dockerfile(args.dockerfile) tag = args.tag dkr = Docker() @@ -442,7 +443,7 @@ class BuildCommand(SubCommand): cksum += [(filename, _file_checksum(filename))] argv += ["--build-arg=" + k.lower() + "=" + v - for k, v in os.environ.iteritems() + for k, v in os.environ.items() if k.lower() in FILTERED_ENV_NAMES] dkr.build_image(tag, docker_dir, dockerfile, quiet=args.quiet, user=args.user, argv=argv, @@ -611,7 +612,7 @@ class CheckCommand(SubCommand): print("Need a dockerfile for tag:%s" % (tag)) return 1 - dockerfile = open(args.dockerfile, "rb").read() + dockerfile = _read_dockerfile(args.dockerfile) if dkr.image_matches_dockerfile(tag, dockerfile): if not args.quiet: diff --git a/tests/pnv-xscom-test.c b/tests/pnv-xscom-test.c index 63d464048d..9fddc7d5f9 100644 --- a/tests/pnv-xscom-test.c +++ b/tests/pnv-xscom-test.c @@ -77,9 +77,15 @@ static void test_xscom_cfam_id(QTestState *qts, const PnvChip *chip) static void test_cfam_id(const void *data) { const PnvChip *chip = data; + const char *machine = "powernv8"; QTestState *qts; - qts = qtest_initf("-M powernv,accel=tcg -cpu %s", chip->cpu_model); + if (chip->chip_type == PNV_CHIP_POWER9) { + machine = "powernv9"; + } + + qts = qtest_initf("-M %s,accel=tcg -cpu %s", + machine, chip->cpu_model); test_xscom_cfam_id(qts, chip); qtest_quit(qts); } @@ -113,8 +119,14 @@ static void test_core(const void *data) { const PnvChip *chip = data; QTestState *qts; + const char *machine = "powernv8"; + + if (chip->chip_type == PNV_CHIP_POWER9) { + machine = "powernv9"; + } - qts = qtest_initf("-M powernv,accel=tcg -cpu %s", chip->cpu_model); + qts = qtest_initf("-M %s,accel=tcg -cpu %s", + machine, chip->cpu_model); test_xscom_core(qts, chip); qtest_quit(qts); } diff --git a/tests/qemu-iotests/002 b/tests/qemu-iotests/002 index fd413bce48..1a0d411df5 100755 --- a/tests/qemu-iotests/002 +++ b/tests/qemu-iotests/002 @@ -38,6 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt generic _supported_proto generic +_unsupported_imgopts "subformat=streamOptimized" size=128M diff --git a/tests/qemu-iotests/003 b/tests/qemu-iotests/003 index ccd3a39dfb..33eeade0de 100755 --- a/tests/qemu-iotests/003 +++ b/tests/qemu-iotests/003 @@ -38,6 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt generic _supported_proto generic +_unsupported_imgopts "subformat=streamOptimized" size=128M offset=67M diff --git a/tests/qemu-iotests/005 b/tests/qemu-iotests/005 index 9c7681c19b..58442762fe 100755 --- a/tests/qemu-iotests/005 +++ b/tests/qemu-iotests/005 @@ -43,7 +43,8 @@ _supported_fmt generic _supported_proto generic _supported_os Linux _unsupported_imgopts "subformat=twoGbMaxExtentFlat" \ - "subformat=twoGbMaxExtentSparse" + "subformat=twoGbMaxExtentSparse" \ + "subformat=streamOptimized" # vpc is limited to 127GB, so we can't test it here if [ "$IMGFMT" = "vpc" ]; then diff --git a/tests/qemu-iotests/009 b/tests/qemu-iotests/009 index 51b200db1d..4dc7d210f9 100755 --- a/tests/qemu-iotests/009 +++ b/tests/qemu-iotests/009 @@ -38,6 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt generic _supported_proto generic +_unsupported_imgopts "subformat=streamOptimized" size=6G diff --git a/tests/qemu-iotests/010 b/tests/qemu-iotests/010 index 48c533f632..df809b3088 100755 --- a/tests/qemu-iotests/010 +++ b/tests/qemu-iotests/010 @@ -38,6 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt generic _supported_proto generic +_unsupported_imgopts "subformat=streamOptimized" size=6G diff --git a/tests/qemu-iotests/011 b/tests/qemu-iotests/011 index 56f704b5b9..57b99ae4a9 100755 --- a/tests/qemu-iotests/011 +++ b/tests/qemu-iotests/011 @@ -38,6 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt generic _supported_proto generic +_unsupported_imgopts "subformat=streamOptimized" size=6G diff --git a/tests/qemu-iotests/017 b/tests/qemu-iotests/017 index 79875de454..0a4b854e65 100755 --- a/tests/qemu-iotests/017 +++ b/tests/qemu-iotests/017 @@ -41,7 +41,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow qcow2 vmdk qed _supported_proto generic _unsupported_proto vxhs -_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" +_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \ + "subformat=streamOptimized" TEST_OFFSETS="0 4294967296" diff --git a/tests/qemu-iotests/018 b/tests/qemu-iotests/018 index 78169838ba..c69ce09209 100755 --- a/tests/qemu-iotests/018 +++ b/tests/qemu-iotests/018 @@ -41,7 +41,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow qcow2 vmdk qed _supported_proto file _supported_os Linux -_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" +_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \ + "streamOptimized" TEST_OFFSETS="0 4294967296" diff --git a/tests/qemu-iotests/019 b/tests/qemu-iotests/019 index a56dd30bed..b4f5234609 100755 --- a/tests/qemu-iotests/019 +++ b/tests/qemu-iotests/019 @@ -47,7 +47,8 @@ _supported_proto file _supported_os Linux _unsupported_imgopts "subformat=monolithicFlat" \ "subformat=twoGbMaxExtentFlat" \ - "subformat=twoGbMaxExtentSparse" + "subformat=twoGbMaxExtentSparse" \ + "subformat=streamOptimized" TEST_OFFSETS="0 4294967296" CLUSTER_SIZE=65536 diff --git a/tests/qemu-iotests/020 b/tests/qemu-iotests/020 index 6b0ebb37d2..f41b92f35f 100755 --- a/tests/qemu-iotests/020 +++ b/tests/qemu-iotests/020 @@ -44,7 +44,8 @@ _supported_fmt qcow qcow2 vmdk qed _supported_proto file _unsupported_imgopts "subformat=monolithicFlat" \ "subformat=twoGbMaxExtentFlat" \ - "subformat=twoGbMaxExtentSparse" + "subformat=twoGbMaxExtentSparse" \ + "subformat=streamOptimized" TEST_OFFSETS="0 4294967296" diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026 index e30243608b..ffb18ab6b5 100755 --- a/tests/qemu-iotests/026 +++ b/tests/qemu-iotests/026 @@ -41,8 +41,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 # Currently only qcow2 supports rebasing _supported_fmt qcow2 _supported_proto file -_default_cache_mode "writethrough" -_supported_cache_modes "writethrough" "none" +_default_cache_mode writethrough +_supported_cache_modes writethrough none # The refcount table tests expect a certain minimum width for refcount entries # (so that the refcount table actually needs to grow); that minimum is 16 bits, # being the default refcount entry width. diff --git a/tests/qemu-iotests/027 b/tests/qemu-iotests/027 index 4cb638022a..494be0921f 100755 --- a/tests/qemu-iotests/027 +++ b/tests/qemu-iotests/027 @@ -38,6 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt vmdk qcow qcow2 qed _supported_proto generic +_unsupported_imgopts "subformat=streamOptimized" size=128M diff --git a/tests/qemu-iotests/032 b/tests/qemu-iotests/032 index 988a8c5d8f..8337a4d825 100755 --- a/tests/qemu-iotests/032 +++ b/tests/qemu-iotests/032 @@ -42,6 +42,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 # This works for any image format (though unlikely to segfault for raw) _supported_fmt generic _supported_proto generic +_unsupported_imgopts "subformat=streamOptimized" echo echo === Prepare image === diff --git a/tests/qemu-iotests/033 b/tests/qemu-iotests/033 index 362a48c0a0..8b40991d55 100755 --- a/tests/qemu-iotests/033 +++ b/tests/qemu-iotests/033 @@ -38,6 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt generic _supported_proto generic +_unsupported_imgopts "subformat=streamOptimized" size=128M diff --git a/tests/qemu-iotests/034 b/tests/qemu-iotests/034 index 324bed28c6..da4cea1571 100755 --- a/tests/qemu-iotests/034 +++ b/tests/qemu-iotests/034 @@ -41,7 +41,8 @@ _supported_proto file _supported_os Linux _unsupported_imgopts "subformat=monolithicFlat" \ "subformat=twoGbMaxExtentFlat" \ - "subformat=twoGbMaxExtentSparse" + "subformat=twoGbMaxExtentSparse" \ + "subformat=streamOptimized" CLUSTER_SIZE=4k size=128M diff --git a/tests/qemu-iotests/037 b/tests/qemu-iotests/037 index 4946b9be92..e6517acbd4 100755 --- a/tests/qemu-iotests/037 +++ b/tests/qemu-iotests/037 @@ -40,7 +40,8 @@ _supported_fmt qcow qcow2 vmdk qed _supported_proto file _unsupported_imgopts "subformat=monolithicFlat" \ "subformat=twoGbMaxExtentFlat" \ - "subformat=twoGbMaxExtentSparse" + "subformat=twoGbMaxExtentSparse" \ + "subformat=streamOptimized" CLUSTER_SIZE=4k size=128M diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039 index 0d4e963bd4..7c730d94a7 100755 --- a/tests/qemu-iotests/039 +++ b/tests/qemu-iotests/039 @@ -42,8 +42,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow2 _supported_proto file _supported_os Linux -_default_cache_mode "writethrough" -_supported_cache_modes "writethrough" +_default_cache_mode writethrough +_supported_cache_modes writethrough size=128M diff --git a/tests/qemu-iotests/052 b/tests/qemu-iotests/052 index 6e2ecbfe21..45a140910d 100755 --- a/tests/qemu-iotests/052 +++ b/tests/qemu-iotests/052 @@ -40,7 +40,7 @@ _supported_fmt generic _supported_proto file # Don't do O_DIRECT on tmpfs -_supported_cache_modes "writeback" "writethrough" "unsafe" +_supported_cache_modes writeback writethrough unsafe size=128M _make_test_img $size diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059 index 279aee6815..10bfbaecec 100755 --- a/tests/qemu-iotests/059 +++ b/tests/qemu-iotests/059 @@ -114,11 +114,41 @@ $QEMU_IMG convert -f qcow2 -O vmdk -o subformat=streamOptimized "$TEST_IMG.qcow2 echo echo "=== Testing monolithicFlat with internally generated JSON file name ===" + +echo '--- blkdebug ---' +# Should work, because bdrv_dirname() works fine with blkdebug IMGOPTS="subformat=monolithicFlat" _make_test_img 64M -$QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TEST_IMG,file.inject-error.0.event=read_aio" 2>&1 \ - | _filter_testdir | _filter_imgfmt +$QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TEST_IMG,file.inject-error.0.event=read_aio" \ + -c info \ + 2>&1 \ + | _filter_testdir | _filter_imgfmt | _filter_img_info _cleanup_test_img +echo '--- quorum ---' +# Should not work, because bdrv_dirname() does not work with quorum +IMGOPTS="subformat=monolithicFlat" _make_test_img 64M +cp "$TEST_IMG" "$TEST_IMG.orig" + +filename="json:{ + \"driver\": \"$IMGFMT\", + \"file\": { + \"driver\": \"quorum\", + \"children\": [ { + \"driver\": \"file\", + \"filename\": \"$TEST_IMG\" + }, { + \"driver\": \"file\", + \"filename\": \"$TEST_IMG.orig\" + } ], + \"vote-threshold\": 1 + } }" + +filename=$(echo "$filename" | tr '\n' ' ' | sed -e 's/\s\+/ /g') +$QEMU_IMG info "$filename" 2>&1 \ + | sed -e "s/'json:[^']*'/\$QUORUM_FILE/g" \ + | _filter_testdir | _filter_imgfmt | _filter_img_info + + echo echo "=== Testing version 3 ===" _use_sample_img iotest-version3.vmdk.bz2 diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out index 4fab42a28c..39bf7e211d 100644 --- a/tests/qemu-iotests/059.out +++ b/tests/qemu-iotests/059.out @@ -13,21 +13,21 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 qemu-io: can't open device TEST_DIR/t.vmdk: L1 size too big === Testing monolithicFlat creation and opening === -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicFlat +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 image: TEST_DIR/t.IMGFMT file format: IMGFMT virtual size: 2 GiB (2147483648 bytes) === Testing monolithicFlat with zeroed_grain === qemu-img: TEST_DIR/t.IMGFMT: Flat image can't enable zeroed grain -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicFlat +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 === Testing big twoGbMaxExtentFlat === -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000 subformat=twoGbMaxExtentFlat +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000 image: TEST_DIR/t.vmdk file format: vmdk virtual size: 0.977 TiB (1073741824000 bytes) -disk size: 16 KiB +disk size: 1.97 MiB Format specific information: cid: XXXXXXXX parent cid: XXXXXXXX @@ -2038,7 +2038,7 @@ Format specific information: qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Invalid extent line: RW 12582912 VMFS "dummy.IMGFMT" 1 === Testing truncated sparse === -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=107374182400 subformat=monolithicSparse +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=107374182400 qemu-img: Could not open 'TEST_DIR/t.IMGFMT': File truncated, expecting at least 13172736 bytes === Converting to streamOptimized from image with small cluster size=== @@ -2049,8 +2049,14 @@ wrote 512/512 bytes at offset 10240 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === Testing monolithicFlat with internally generated JSON file name === -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 subformat=monolithicFlat -qemu-io: can't open: Cannot use relative extent paths with VMDK descriptor file 'json:{"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "read_aio"}' +--- blkdebug --- +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 +format name: IMGFMT +cluster size: 0 bytes +vm state offset: 0 bytes +--- quorum --- +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 +qemu-img: Could not open $QUORUM_FILE: Cannot use relative paths with VMDK descriptor file $QUORUM_FILE: Cannot generate a base directory for quorum nodes === Testing version 3 === image: TEST_DIR/iotest-version3.IMGFMT @@ -2259,7 +2265,7 @@ read 512/512 bytes at offset 64931328 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === Testing 4TB monolithicFlat creation and IO === -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4398046511104 subformat=monolithicFlat +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4398046511104 image: TEST_DIR/t.IMGFMT file format: IMGFMT virtual size: 4 TiB (4398046511104 bytes) @@ -2333,7 +2339,7 @@ read 1024/1024 bytes at offset 966367641600 1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === Testing qemu-img map on extents === -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544 subformat=monolithicSparse +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544 wrote 1024/1024 bytes at offset 65024 1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 1024/1024 bytes at offset 2147483136 @@ -2344,7 +2350,7 @@ Offset Length Mapped to File 0 0x20000 0x3f0000 TEST_DIR/t.vmdk 0x7fff0000 0x20000 0x410000 TEST_DIR/t.vmdk 0x140000000 0x10000 0x430000 TEST_DIR/t.vmdk -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544 subformat=twoGbMaxExtentSparse +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544 wrote 1024/1024 bytes at offset 65024 1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 1024/1024 bytes at offset 2147483136 diff --git a/tests/qemu-iotests/063 b/tests/qemu-iotests/063 index fe4892e467..7cf0427af4 100755 --- a/tests/qemu-iotests/063 +++ b/tests/qemu-iotests/063 @@ -43,7 +43,8 @@ _supported_fmt qcow qcow2 vmdk qed raw _supported_proto file _unsupported_imgopts "subformat=monolithicFlat" \ "subformat=twoGbMaxExtentFlat" \ - "subformat=twoGbMaxExtentSparse" + "subformat=twoGbMaxExtentSparse" \ + "subformat=streamOptimized" _make_test_img 4M diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071 index 1cca9233d0..fab526666b 100755 --- a/tests/qemu-iotests/071 +++ b/tests/qemu-iotests/071 @@ -38,6 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow2 _supported_proto file +_require_drivers blkdebug blkverify do_run_qemu() { diff --git a/tests/qemu-iotests/072 b/tests/qemu-iotests/072 index 661b36da2d..f0b73e7e65 100755 --- a/tests/qemu-iotests/072 +++ b/tests/qemu-iotests/072 @@ -38,6 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt vpc vmdk vhdx vdi qed qcow2 qcow _supported_proto file +_unsupported_imgopts "subformat=streamOptimized" IMG_SIZE=64M diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081 index c418bab093..85acdf76d4 100755 --- a/tests/qemu-iotests/081 +++ b/tests/qemu-iotests/081 @@ -41,6 +41,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt raw _supported_proto file _supported_os Linux +_require_drivers quorum do_run_qemu() { @@ -55,9 +56,6 @@ run_qemu() | _filter_qemu_io | _filter_generated_node_ids } -test_quorum=$($QEMU_IMG --help|grep quorum) -[ "$test_quorum" = "" ] && _supported_fmt quorum - quorum="driver=raw,file.driver=quorum,file.vote-threshold=2" quorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw" quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw" diff --git a/tests/qemu-iotests/091 b/tests/qemu-iotests/091 index d62ef18a02..f4b44659ae 100755 --- a/tests/qemu-iotests/091 +++ b/tests/qemu-iotests/091 @@ -46,8 +46,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow2 _supported_proto file _supported_os Linux -_default_cache_mode "none" -_supported_cache_modes "writethrough" "none" "writeback" +_default_cache_mode none +_supported_cache_modes writethrough none writeback size=1G diff --git a/tests/qemu-iotests/099 b/tests/qemu-iotests/099 index ae02f27afe..c3cf66798a 100755 --- a/tests/qemu-iotests/099 +++ b/tests/qemu-iotests/099 @@ -42,6 +42,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow qcow2 qed vdi vhdx vmdk vpc _supported_proto file _supported_os Linux +_require_drivers blkdebug blkverify _unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \ "subformat=twoGbMaxExtentSparse" diff --git a/tests/qemu-iotests/105 b/tests/qemu-iotests/105 index 3346e8cb25..4d55a2d3ef 100755 --- a/tests/qemu-iotests/105 +++ b/tests/qemu-iotests/105 @@ -39,7 +39,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow2 vmdk vhdx qed _supported_proto generic _unsupported_imgopts "subformat=twoGbMaxExtentFlat" \ - "subformat=twoGbMaxExtentSparse" + "subformat=twoGbMaxExtentSparse" \ + "subformat=streamOptimized" echo echo "creating large image" diff --git a/tests/qemu-iotests/110 b/tests/qemu-iotests/110 index 2cdc7c8a72..2ef516baf1 100755 --- a/tests/qemu-iotests/110 +++ b/tests/qemu-iotests/110 @@ -40,7 +40,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 # Any format supporting backing files _supported_fmt qed qcow qcow2 vmdk _supported_proto file -_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" +_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \ + "subformat=twoGbMaxExtentSparse" TEST_IMG_REL=$(basename "$TEST_IMG") diff --git a/tests/qemu-iotests/120 b/tests/qemu-iotests/120 index e9b4fbb009..2931a7550f 100755 --- a/tests/qemu-iotests/120 +++ b/tests/qemu-iotests/120 @@ -40,6 +40,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt generic _supported_proto file _unsupported_fmt luks +_require_drivers raw _make_test_img 64M diff --git a/tests/qemu-iotests/126 b/tests/qemu-iotests/126 index 9b0dcf9255..b7fce1e59d 100755 --- a/tests/qemu-iotests/126 +++ b/tests/qemu-iotests/126 @@ -33,6 +33,8 @@ status=1 # failure is the default! # Needs backing file support _supported_fmt qcow qcow2 qed vmdk +_unsupported_imgopts "subformat=monolithicFlat" \ + "subformat=twoGbMaxExtentFlat" # This is the default protocol (and we want to test the difference between # colons which separate a protocol prefix from the rest and colons which are # just part of the filename, so we cannot test protocols which require a prefix) diff --git a/tests/qemu-iotests/150.out b/tests/qemu-iotests/150.out.qcow2 index 2a54e8dcfa..2a54e8dcfa 100644 --- a/tests/qemu-iotests/150.out +++ b/tests/qemu-iotests/150.out.qcow2 diff --git a/tests/qemu-iotests/150.out.raw b/tests/qemu-iotests/150.out.raw new file mode 100644 index 0000000000..3cdc7727a5 --- /dev/null +++ b/tests/qemu-iotests/150.out.raw @@ -0,0 +1,12 @@ +QA output created by 150 + +=== Mapping sparse conversion === + +Offset Length File +0 0x1000 TEST_DIR/t.IMGFMT + +=== Mapping non-sparse conversion === + +Offset Length File +0 0x100000 TEST_DIR/t.IMGFMT +*** done diff --git a/tests/qemu-iotests/162 b/tests/qemu-iotests/162 index 4e5ed74fd5..2d719afbed 100755 --- a/tests/qemu-iotests/162 +++ b/tests/qemu-iotests/162 @@ -39,9 +39,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 . ./common.filter _supported_fmt generic - -test_ssh=$($QEMU_IMG --help | grep '^Supported formats:.* ssh\( \|$\)') -[ "$test_ssh" = "" ] && _notrun "ssh support required" +_require_drivers ssh echo echo '=== NBD ===' diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175 index 51e62c8276..55db2803ed 100755 --- a/tests/qemu-iotests/175 +++ b/tests/qemu-iotests/175 @@ -37,14 +37,33 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 # the file size. This function hides the resulting difference in the # stat -c '%b' output. # Parameter 1: Number of blocks an empty file occupies -# Parameter 2: Image size in bytes +# Parameter 2: Minimal number of blocks in an image +# Parameter 3: Image size in bytes _filter_blocks() { extra_blocks=$1 - img_size=$2 + min_blocks=$2 + img_size=$3 - sed -e "s/blocks=$extra_blocks\\(\$\\|[^0-9]\\)/nothing allocated/" \ - -e "s/blocks=$((extra_blocks + img_size / 512))\\(\$\\|[^0-9]\\)/everything allocated/" + sed -e "s/blocks=$min_blocks\\(\$\\|[^0-9]\\)/min allocation/" \ + -e "s/blocks=$((extra_blocks + img_size / 512))\\(\$\\|[^0-9]\\)/max allocation/" +} + +# Resize image using block_resize. +# Parameter 1: image path +# Parameter 2: new size +_block_resize() +{ + local path=$1 + local size=$2 + + $QEMU -qmp stdio -nographic -nodefaults \ + -blockdev file,node-name=file,filename=$path,cache.direct=on \ + <<EOF +{'execute': 'qmp_capabilities'} +{'execute': 'block_resize', 'arguments': {'node-name': 'file', 'size': $size}} +{'execute': 'quit'} +EOF } # get standard environment, filters and checks @@ -55,21 +74,37 @@ _supported_fmt raw _supported_proto file _supported_os Linux +_default_cache_mode none +_supported_cache_modes none directsync + size=$((1 * 1024 * 1024)) touch "$TEST_DIR/empty" extra_blocks=$(stat -c '%b' "$TEST_DIR/empty") +# We always write the first byte; check how many blocks this filesystem +# allocates to match empty image alloation. +printf "\0" > "$TEST_DIR/empty" +min_blocks=$(stat -c '%b' "$TEST_DIR/empty") + echo echo "== creating image with default preallocation ==" _make_test_img $size | _filter_imgfmt -stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $size +stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size for mode in off full falloc; do echo echo "== creating image with preallocation $mode ==" IMGOPTS=preallocation=$mode _make_test_img $size | _filter_imgfmt - stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $size + stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size +done + +for new_size in 4096 1048576; do + echo + echo "== resize empty image with block_resize ==" + _make_test_img 0 | _filter_imgfmt + _block_resize $TEST_IMG $new_size >/dev/null + stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $new_size done # success, all done diff --git a/tests/qemu-iotests/175.out b/tests/qemu-iotests/175.out index 6d9a5ed84e..39c2ee0f62 100644 --- a/tests/qemu-iotests/175.out +++ b/tests/qemu-iotests/175.out @@ -2,17 +2,25 @@ QA output created by 175 == creating image with default preallocation == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 -size=1048576, nothing allocated +size=1048576, min allocation == creating image with preallocation off == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=off -size=1048576, nothing allocated +size=1048576, min allocation == creating image with preallocation full == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=full -size=1048576, everything allocated +size=1048576, max allocation == creating image with preallocation falloc == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=falloc -size=1048576, everything allocated +size=1048576, max allocation + +== resize empty image with block_resize == +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0 +size=4096, min allocation + +== resize empty image with block_resize == +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0 +size=1048576, min allocation *** done diff --git a/tests/qemu-iotests/178.out.qcow2 b/tests/qemu-iotests/178.out.qcow2 index 55a8dc926f..9e7d8c44df 100644 --- a/tests/qemu-iotests/178.out.qcow2 +++ b/tests/qemu-iotests/178.out.qcow2 @@ -101,7 +101,7 @@ converted image file size in bytes: 196608 == raw input image with data (human) == Formatting 'TEST_DIR/t.qcow2', fmt=IMGFMT size=1073741824 -required size: 393216 +required size: 458752 fully allocated size: 1074135040 wrote 512/512 bytes at offset 512 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -257,7 +257,7 @@ converted image file size in bytes: 196608 Formatting 'TEST_DIR/t.qcow2', fmt=IMGFMT size=1073741824 { - "required": 393216, + "required": 458752, "fully-allocated": 1074135040 } wrote 512/512 bytes at offset 512 diff --git a/tests/qemu-iotests/184 b/tests/qemu-iotests/184 index cb0c181228..33dd8d2a4f 100755 --- a/tests/qemu-iotests/184 +++ b/tests/qemu-iotests/184 @@ -33,6 +33,7 @@ trap "exit \$status" 0 1 2 3 15 . ./common.filter _supported_os Linux +_require_drivers throttle do_run_qemu() { diff --git a/tests/qemu-iotests/186 b/tests/qemu-iotests/186 index 5f6b18c150..3ea0442d44 100755 --- a/tests/qemu-iotests/186 +++ b/tests/qemu-iotests/186 @@ -38,6 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow2 _supported_proto file +_require_drivers null-co if [ "$QEMU_DEFAULT_MACHINE" != "pc" ]; then _notrun "Requires a PC machine" diff --git a/tests/qemu-iotests/197 b/tests/qemu-iotests/197 index 383d7d7f61..1d4f6786db 100755 --- a/tests/qemu-iotests/197 +++ b/tests/qemu-iotests/197 @@ -53,6 +53,7 @@ _supported_fmt generic _supported_proto generic # LUKS support may be possible, but it complicates things. _unsupported_fmt luks +_unsupported_imgopts "subformat=streamOptimized" echo echo '=== Copy-on-read ===' diff --git a/tests/qemu-iotests/215 b/tests/qemu-iotests/215 index 958c14f5a0..2eb377d682 100755 --- a/tests/qemu-iotests/215 +++ b/tests/qemu-iotests/215 @@ -50,6 +50,7 @@ _supported_fmt generic _supported_proto generic # LUKS support may be possible, but it complicates things. _unsupported_fmt luks +_unsupported_imgopts "subformat=streamOptimized" echo echo '=== Copy-on-read ===' diff --git a/tests/qemu-iotests/221.out b/tests/qemu-iotests/221.out index 9f9dd52bb0..dca024a0c3 100644 --- a/tests/qemu-iotests/221.out +++ b/tests/qemu-iotests/221.out @@ -3,14 +3,18 @@ QA output created by 221 === Check mapping of unaligned raw image === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65537 -[{ "start": 0, "length": 66048, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] -[{ "start": 0, "length": 66048, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] +[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, +{ "start": 4096, "length": 61952, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] +[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, +{ "start": 4096, "length": 61952, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] wrote 1/1 bytes at offset 65536 1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -[{ "start": 0, "length": 65536, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, +[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, +{ "start": 4096, "length": 61440, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, { "start": 65536, "length": 1, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, { "start": 65537, "length": 511, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] -[{ "start": 0, "length": 65536, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, +[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, +{ "start": 4096, "length": 61440, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, { "start": 65536, "length": 1, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, { "start": 65537, "length": 511, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] *** done diff --git a/tests/qemu-iotests/251 b/tests/qemu-iotests/251 index 13f85de9cd..7918ba3559 100755 --- a/tests/qemu-iotests/251 +++ b/tests/qemu-iotests/251 @@ -40,6 +40,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt generic _supported_proto file _supported_os Linux +_unsupported_imgopts "subformat=streamOptimized" if [ "$IMGOPTSSYNTAX" = "true" ]; then # We use json:{} filenames here, so we cannot work with additional options. diff --git a/tests/qemu-iotests/253.out b/tests/qemu-iotests/253.out index 607c0baa0b..3d08b305d7 100644 --- a/tests/qemu-iotests/253.out +++ b/tests/qemu-iotests/253.out @@ -3,12 +3,16 @@ QA output created by 253 === Check mapping of unaligned raw image === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048575 -[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] -[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] +[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, +{ "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] +[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, +{ "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] wrote 65535/65535 bytes at offset 983040 63.999 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, +[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, +{ "start": 4096, "length": 978944, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, { "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}] -[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, +[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, +{ "start": 4096, "length": 978944, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, { "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}] *** done diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check index c24874ff4a..a58232eefb 100755 --- a/tests/qemu-iotests/check +++ b/tests/qemu-iotests/check @@ -581,13 +581,13 @@ export QEMU_PROG="$(type -p "$QEMU_PROG")" case "$QEMU_PROG" in *qemu-system-arm|*qemu-system-aarch64) - export QEMU_OPTIONS="-nodefaults -machine virt,accel=qtest" + export QEMU_OPTIONS="-nodefaults -display none -machine virt,accel=qtest" ;; *qemu-system-tricore) - export QEMU_OPTIONS="-nodefaults -machine tricore_testboard,accel=qtest" + export QEMU_OPTIONS="-nodefaults -display none -machine tricore_testboard,accel=qtest" ;; *) - export QEMU_OPTIONS="-nodefaults -machine accel=qtest" + export QEMU_OPTIONS="-nodefaults -display none -machine accel=qtest" ;; esac diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter index 8e9235d6fe..445a1c23e0 100644 --- a/tests/qemu-iotests/common.filter +++ b/tests/qemu-iotests/common.filter @@ -130,8 +130,8 @@ _filter_img_create() -e "s# compat6=\\(on\\|off\\)##g" \ -e "s# static=\\(on\\|off\\)##g" \ -e "s# zeroed_grain=\\(on\\|off\\)##g" \ - -e "s# subformat='[^']*'##g" \ - -e "s# adapter_type='[^']*'##g" \ + -e "s# subformat=[^ ]*##g" \ + -e "s# adapter_type=[^ ]*##g" \ -e "s# hwversion=[^ ]*##g" \ -e "s# lazy_refcounts=\\(on\\|off\\)##g" \ -e "s# block_size=[0-9]\\+##g" \ diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc index 5502c3da2f..ee20be8920 100644 --- a/tests/qemu-iotests/common.rc +++ b/tests/qemu-iotests/common.rc @@ -520,5 +520,19 @@ _require_command() [ -x "$c" ] || _notrun "$1 utility required, skipped this test" } +# Check that a set of drivers has been whitelisted in the QEMU binary +# +_require_drivers() +{ + available=$($QEMU -drive format=help | \ + sed -e '/Supported formats:/!d' -e 's/Supported formats://') + for driver + do + if ! echo "$available" | grep -q " $driver\( \|$\)"; then + _notrun "$driver not available" + fi + done +} + # make sure this script returns success true |