Re: [PATCH v2] block/snapshot: Fix compiler warning with -Wshadow=local
On 10/24/23 13:51, Thomas Huth wrote: On 24/10/2023 12.37, Markus Armbruster wrote: Markus Armbruster writes: Thomas Huth writes: No need to declare a new variable in the the inner code block here, we can re-use the "ret" variable that has been declared at the beginning of the function. With this change, the code can now be successfully compiled with -Wshadow=local again. Fixes: a32e781838 ("Mark bdrv_snapshot_fallback() and callers GRAPH_RDLOCK") Signed-off-by: Thomas Huth --- v2: Assign "ret" only in one spot block/snapshot.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/block/snapshot.c b/block/snapshot.c index 6e16eb803a..55974273ae 100644 --- a/block/snapshot.c +++ b/block/snapshot.c @@ -629,7 +629,6 @@ int bdrv_all_goto_snapshot(const char *name, while (iterbdrvs) { BlockDriverState *bs = iterbdrvs->data; AioContext *ctx = bdrv_get_aio_context(bs); - int ret = 0; bool all_snapshots_includes_bs; aio_context_acquire(ctx); @@ -637,9 +636,8 @@ int bdrv_all_goto_snapshot(const char *name, all_snapshots_includes_bs = bdrv_all_snapshots_includes_bs(bs); bdrv_graph_rdunlock_main_loop(); - if (devices || all_snapshots_includes_bs) { - ret = bdrv_snapshot_goto(bs, name, errp); - } + ret = (devices || all_snapshots_includes_bs) ? + bdrv_snapshot_goto(bs, name, errp) : 0; aio_context_release(ctx); if (ret < 0) { bdrv_graph_rdlock_main_loop(); Better. Unconditional assignment to @ret right before it's checked is how we should use @ret. Reviewed-by: Markus Armbruster And queued. Thanks! Mind if I drop the Fixes: tag? Nothing broken until we enable -Wshadow=local... Fine for me! This looks like the last remaining warning. Are we going to activate -Wshadow=local next ? Thanks, C.
Re: [PATCH 0/2] Some biosbits avocado test fixes
> On 27-Oct-2023, at 8:51 AM, Ani Sinha wrote: > > Included are couple of bios bits test fixes. > 32-bit SMBIOS entry point is enforced. > Console logging is enabled. > > I have tested these changes in the CI pipeline here and the test seems > to pass: > > https://gitlab.com/anisinha/qemu/-/jobs/5380627517 MST, are you going to queue this? > Log: > > https://cdn.artifacts.gitlab-static.net/8a/b0/8ab0aa629e9c43a80356e27a440985f41da9ad10b120a410d9f070bed092fea6/2023_10_26/5380627517/5862985776/job.log?response-content-type=text%2Fplain%3B%20charset%3Dutf-8&response-content-disposition=inline&Expires=1698376660&KeyName=gprd-artifacts-cdn&Signature=ln7fYsTb8t6ch0Trsa7SHAN01QY= > > CC: js...@redhat.com > CC: jus...@redhat.com > CC: imamm...@redhat.com > CC: m...@redhat.com > CC: qemu-devel@nongnu.org > CC: cr...@redhat.com > CC: phi...@linaro.org > CC: Wainer dos Santos Moschetta > CC: Beraldo Leal > > Ani Sinha (2): > acpi/tests/avocado/bits: enforce 32-bit SMBIOS entry point > acpi/tests/avocado/bits: enable console logging from bits VM > > tests/avocado/acpi-bits.py | 33 ++--- > 1 file changed, 22 insertions(+), 11 deletions(-) > > -- > 2.42.0 >
Re: [PATCH] system/qdev-monitor: move drain_call_rcu call under if (!dev) in qmp_device_add()
On Fri, Nov 03, 2023 at 01:56:02PM +0300, Dmitrii Gavrilov wrote: > Original goal of addition of drain_call_rcu to qmp_device_add was to cover > the failure case of qdev_device_add. It seems call of drain_call_rcu was > misplaced in 7bed89958bfbf40df what led to waiting for pending RCU callbacks > under happy path too. What led to overall performance degradation of > qmp_device_add. > > In this patch call of drain_call_rcu moved under handling of failure of > qdev_device_add. Suggested-by: Michael S. Tsirkin Reviewed-by: Michael S. Tsirkin Also: Fixes: 7bed89958b ("device_core: use drain_call_rcu in in qmp_device_add") Cc: "Maxim Levitsky" > > Signed-off-by: Dmitrii Gavrilov > --- > system/qdev-monitor.c | 23 +++ > 1 file changed, 11 insertions(+), 12 deletions(-) > > diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c > index 1b8005a..dc7b02d 100644 > --- a/system/qdev-monitor.c > +++ b/system/qdev-monitor.c > @@ -856,19 +856,18 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, > Error **errp) > return; > } > dev = qdev_device_add(opts, errp); > - > -/* > - * Drain all pending RCU callbacks. This is done because > - * some bus related operations can delay a device removal > - * (in this case this can happen if device is added and then > - * removed due to a configuration error) > - * to a RCU callback, but user might expect that this interface > - * will finish its job completely once qmp command returns result > - * to the user > - */ > -drain_call_rcu(); > - > if (!dev) { > +/* > + * Drain all pending RCU callbacks. This is done because > + * some bus related operations can delay a device removal > + * (in this case this can happen if device is added and then > + * removed due to a configuration error) > + * to a RCU callback, but user might expect that this interface > + * will finish its job completely once qmp command returns result > + * to the user > + */ > +drain_call_rcu(); > + > qemu_opts_del(opts); > return; > } > -- > 2.34.1 > >
Re: [PATCH v6 1/6] virtio: split into vhost-user-base and vhost-user-device
On Mon, Nov 06, 2023 at 07:15:10PM +, Alex Bennée wrote: > Lets keep a cleaner split between the base class and the derived > vhost-user-device which we can use for generic vhost-user stubs. This > includes an update to introduce the vq_size property so the number of > entries in a virtq can be defined. > > Signed-off-by: Alex Bennée > Message-Id: <20231009095937.195728-2-alex.ben...@linaro.org> Please do not put Message-Id tags in patches you post. These are used to map patches to email - this patch was In-Reply-To: <20231106191515.2801863-2-alex.ben...@linaro.org> > --- > v5 > - s/parent/parent_obj/ > - remove left over vhost-user-device.h > - use DEFINE_TYPES > v6 > - rebase and set .abstrace = true for vhost-user-device > --- > ...{vhost-user-device.h => vhost-user-base.h} | 21 +- > hw/virtio/vhost-user-base.c | 345 ++ > hw/virtio/vhost-user-device-pci.c | 10 +- > hw/virtio/vhost-user-device.c | 337 + > hw/virtio/meson.build | 1 + > 5 files changed, 372 insertions(+), 342 deletions(-) > rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%) > create mode 100644 hw/virtio/vhost-user-base.c > > diff --git a/include/hw/virtio/vhost-user-device.h > b/include/hw/virtio/vhost-user-base.h > similarity index 71% > rename from include/hw/virtio/vhost-user-device.h > rename to include/hw/virtio/vhost-user-base.h > index 3ddf88a146..51d0968b89 100644 > --- a/include/hw/virtio/vhost-user-device.h > +++ b/include/hw/virtio/vhost-user-base.h > @@ -6,8 +6,8 @@ > * SPDX-License-Identifier: GPL-2.0-or-later > */ > > -#ifndef QEMU_VHOST_USER_DEVICE_H > -#define QEMU_VHOST_USER_DEVICE_H > +#ifndef QEMU_VHOST_USER_BASE_H > +#define QEMU_VHOST_USER_BASE_H > > #include "hw/virtio/vhost.h" > #include "hw/virtio/vhost-user.h" > @@ -17,11 +17,13 @@ > OBJECT_DECLARE_TYPE(VHostUserBase, VHostUserBaseClass, VHOST_USER_BASE) > > struct VHostUserBase { > -VirtIODevice parent; > +VirtIODevice parent_obj; > + > /* Properties */ > CharBackend chardev; > uint16_t virtio_id; > uint32_t num_vqs; > +uint32_t vq_size; /* can't exceed VIRTIO_QUEUE_MAX */ > uint32_t config_size; > /* State tracking */ > VhostUserState vhost_user; > @@ -31,16 +33,17 @@ struct VHostUserBase { > bool connected; > }; > > -/* needed so we can use the base realize after specialisation > - tweaks */ > +/* > + * Needed so we can use the base realize after specialisation > + * tweaks > + */ > struct VHostUserBaseClass { > -/*< private >*/ > VirtioDeviceClass parent_class; > -/*< public >*/ > + > DeviceRealize parent_realize; > }; > > -/* shared for the benefit of the derived pci class */ > + > #define TYPE_VHOST_USER_DEVICE "vhost-user-device" > > -#endif /* QEMU_VHOST_USER_DEVICE_H */ > +#endif /* QEMU_VHOST_USER_BASE_H */ > diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c > new file mode 100644 > index 00..ebb4795ebf > --- /dev/null > +++ b/hw/virtio/vhost-user-base.c > @@ -0,0 +1,345 @@ > +/* > + * Base vhost-user-base implementation. This can be used to derive a > + * more fully specified vhost-user backend either generically (see > + * vhost-user-device) or via a specific stub for a device which > + * encapsulates some fixed parameters. > + * > + * Copyright (c) 2023 Linaro Ltd > + * Author: Alex Bennée > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#include "qemu/osdep.h" > +#include "qapi/error.h" > +#include "hw/qdev-properties.h" > +#include "hw/virtio/virtio-bus.h" > +#include "hw/virtio/vhost-user-base.h" > +#include "qemu/error-report.h" > + > +static void vub_start(VirtIODevice *vdev) > +{ > +BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); > +VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); > +VHostUserBase *vub = VHOST_USER_BASE(vdev); > +int ret, i; > + > +if (!k->set_guest_notifiers) { > +error_report("binding does not support guest notifiers"); > +return; > +} > + > +ret = vhost_dev_enable_notifiers(&vub->vhost_dev, vdev); > +if (ret < 0) { > +error_report("Error enabling host notifiers: %d", -ret); > +return; > +} > + > +ret = k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, true); > +if (ret < 0) { > +error_report("Error binding guest notifier: %d", -ret); > +goto err_host_notifiers; > +} > + > +vub->vhost_dev.acked_features = vdev->guest_features; > + > +ret = vhost_dev_start(&vub->vhost_dev, vdev, true); > +if (ret < 0) { > +error_report("Error starting vhost-user-base: %d", -ret); > +goto err_guest_notifiers; > +} > + > +/* > + * guest_notifier_mask/pending not used yet, so just unmask > + * everything here. virtio-pci will do the right thing by > + * enabling/disabling irqfd. > +
Re: [PATCH] system/qdev-monitor: move drain_call_rcu call under if (!dev) in qmp_device_add()
[add Michael] On 03.11.23 13:56, Dmitrii Gavrilov wrote: Original goal of addition of drain_call_rcu to qmp_device_add was to cover the failure case of qdev_device_add. It seems call of drain_call_rcu was misplaced in 7bed89958bfbf40df what led to waiting for pending RCU callbacks under happy path too. What led to overall performance degradation of qmp_device_add. In this patch call of drain_call_rcu moved under handling of failure of qdev_device_add. Signed-off-by: Dmitrii Gavrilov Reviewed-by: Vladimir Sementsov-Ogievskiy --- system/qdev-monitor.c | 23 +++ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c index 1b8005a..dc7b02d 100644 --- a/system/qdev-monitor.c +++ b/system/qdev-monitor.c @@ -856,19 +856,18 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp) return; } dev = qdev_device_add(opts, errp); - -/* - * Drain all pending RCU callbacks. This is done because - * some bus related operations can delay a device removal - * (in this case this can happen if device is added and then - * removed due to a configuration error) - * to a RCU callback, but user might expect that this interface - * will finish its job completely once qmp command returns result - * to the user - */ -drain_call_rcu(); - if (!dev) { +/* + * Drain all pending RCU callbacks. This is done because + * some bus related operations can delay a device removal + * (in this case this can happen if device is added and then + * removed due to a configuration error) + * to a RCU callback, but user might expect that this interface + * will finish its job completely once qmp command returns result + * to the user + */ +drain_call_rcu(); + qemu_opts_del(opts); return; } -- Best regards, Vladimir
Re: [PATCH v8 23/24] hw/display/ati: allow compiling without PIXMAN
HI Zoltan On Tue, Nov 7, 2023 at 11:21 AM wrote: > > From: Marc-André Lureau > > Change the "x-pixman" property default value and use the fallback path > when PIXMAN support is disabled. > > Signed-off-by: Marc-André Lureau please review today :) thanks > --- > hw/display/ati.c | 16 +++- > hw/display/ati_2d.c| 11 +++ > hw/display/meson.build | 2 +- > 3 files changed, 23 insertions(+), 6 deletions(-) > > diff --git a/hw/display/ati.c b/hw/display/ati.c > index 9a87a5504a..51a3b156ac 100644 > --- a/hw/display/ati.c > +++ b/hw/display/ati.c > @@ -32,6 +32,13 @@ > > #define ATI_DEBUG_HW_CURSOR 0 > > +#ifdef CONFIG_PIXMAN > +#define DEFAULT_X_PIXMAN 3 > +#else > +#define DEFAULT_X_PIXMAN 0 > +#endif > + > + > static const struct { > const char *name; > uint16_t dev_id; > @@ -946,6 +953,12 @@ static void ati_vga_realize(PCIDevice *dev, Error **errp) > ATIVGAState *s = ATI_VGA(dev); > VGACommonState *vga = &s->vga; > > +#ifndef CONFIG_PIXMAN > +if (s->use_pixman != 0) { > +warn_report("x-pixman != 0, not effective without PIXMAN"); > +} > +#endif > + > if (s->model) { > int i; > for (i = 0; i < ARRAY_SIZE(ati_model_aliases); i++) { > @@ -1033,7 +1046,8 @@ static Property ati_vga_properties[] = { > DEFINE_PROP_UINT16("x-device-id", ATIVGAState, dev_id, > PCI_DEVICE_ID_ATI_RAGE128_PF), > DEFINE_PROP_BOOL("guest_hwcursor", ATIVGAState, cursor_guest_mode, > false), > -DEFINE_PROP_UINT8("x-pixman", ATIVGAState, use_pixman, 3), > +/* this a debug option, prefer PROP_UINT over PROP_BIT for simplicity */ > +DEFINE_PROP_UINT8("x-pixman", ATIVGAState, use_pixman, DEFAULT_X_PIXMAN), > DEFINE_PROP_END_OF_LIST() > }; > > diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c > index 0e6b8e4367..e58acd0802 100644 > --- a/hw/display/ati_2d.c > +++ b/hw/display/ati_2d.c > @@ -92,7 +92,7 @@ void ati_2d_blt(ATIVGAState *s) > switch (s->regs.dp_mix & GMC_ROP3_MASK) { > case ROP3_SRCCOPY: > { > -bool fallback = false; > +bool fallback = true; > unsigned src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ? > s->regs.src_x : s->regs.src_x + 1 - > s->regs.dst_width); > unsigned src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ? > @@ -119,6 +119,7 @@ void ati_2d_blt(ATIVGAState *s) > > src_stride /= sizeof(uint32_t); > dst_stride /= sizeof(uint32_t); > +#ifdef CONFIG_PIXMAN > DPRINTF("pixman_blt(%p, %p, %d, %d, %d, %d, %d, %d, %d, %d, %d, > %d)\n", > src_bits, dst_bits, src_stride, dst_stride, bpp, bpp, > src_x, src_y, dst_x, dst_y, > @@ -147,9 +148,8 @@ void ati_2d_blt(ATIVGAState *s) > s->regs.dst_width, > s->regs.dst_height); > } > g_free(tmp); > -} else { > -fallback = true; > } > +#endif > if (fallback) { > unsigned int y, i, j, bypp = bpp / 8; > unsigned int src_pitch = src_stride * sizeof(uint32_t); > @@ -203,12 +203,15 @@ void ati_2d_blt(ATIVGAState *s) > } > > dst_stride /= sizeof(uint32_t); > +#ifdef CONFIG_PIXMAN > DPRINTF("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n", > dst_bits, dst_stride, bpp, dst_x, dst_y, > s->regs.dst_width, s->regs.dst_height, filler); > if (!(s->use_pixman & BIT(0)) || > !pixman_fill((uint32_t *)dst_bits, dst_stride, bpp, dst_x, dst_y, > -s->regs.dst_width, s->regs.dst_height, filler)) { > +s->regs.dst_width, s->regs.dst_height, filler)) > +#endif > +{ > /* fallback when pixman failed or we don't want to call it */ > unsigned int x, y, i, bypp = bpp / 8; > unsigned int dst_pitch = dst_stride * sizeof(uint32_t); > diff --git a/hw/display/meson.build b/hw/display/meson.build > index 9c06aaee20..344dfe3d8c 100644 > --- a/hw/display/meson.build > +++ b/hw/display/meson.build > @@ -62,7 +62,7 @@ system_ss.add(when: 'CONFIG_XLNX_DISPLAYPORT', if_true: > files('xlnx_dp.c')) > > system_ss.add(when: 'CONFIG_ARTIST', if_true: files('artist.c')) > > -system_ss.add(when: [pixman, 'CONFIG_ATI_VGA'], if_true: files('ati.c', > 'ati_2d.c', 'ati_dbg.c')) > +system_ss.add(when: 'CONFIG_ATI_VGA', if_true: [files('ati.c', 'ati_2d.c', > 'ati_dbg.c'), pixman]) > > > if config_all_devices.has_key('CONFIG_VIRTIO_GPU') > -- > 2.41.0 >
[PATCH v8 03/24] ui: compile out some qemu-pixman functions when !PIXMAN
From: Marc-André Lureau Those functions require the PIXMAN library. Signed-off-by: Marc-André Lureau Reviewed-by: Thomas Huth --- include/ui/qemu-pixman.h | 7 +-- ui/qemu-pixman.c | 6 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h index 4bfa8fae0c..c140cd84b6 100644 --- a/include/ui/qemu-pixman.h +++ b/include/ui/qemu-pixman.h @@ -72,17 +72,17 @@ pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian); pixman_format_code_t qemu_drm_format_to_pixman(uint32_t drm_format); uint32_t qemu_pixman_to_drm_format(pixman_format_code_t pixman); int qemu_pixman_get_type(int rshift, int gshift, int bshift); -pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf); bool qemu_pixman_check_format(DisplayChangeListener *dcl, pixman_format_code_t format); +#ifdef CONFIG_PIXMAN +pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf); pixman_image_t *qemu_pixman_linebuf_create(pixman_format_code_t format, int width); void qemu_pixman_linebuf_fill(pixman_image_t *linebuf, pixman_image_t *fb, int width, int x, int y); pixman_image_t *qemu_pixman_mirror_create(pixman_format_code_t format, pixman_image_t *image); -void qemu_pixman_image_unref(pixman_image_t *image); pixman_image_t *qemu_pixman_glyph_from_vgafont(int height, const uint8_t *font, unsigned int ch); @@ -91,6 +91,9 @@ void qemu_pixman_glyph_render(pixman_image_t *glyph, pixman_color_t *fgcol, pixman_color_t *bgcol, int x, int y, int cw, int ch); +#endif + +void qemu_pixman_image_unref(pixman_image_t *image); G_DEFINE_AUTOPTR_CLEANUP_FUNC(pixman_image_t, qemu_pixman_image_unref) diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c index b43ec38bf0..5ca55dd199 100644 --- a/ui/qemu-pixman.c +++ b/ui/qemu-pixman.c @@ -145,6 +145,7 @@ int qemu_pixman_get_type(int rshift, int gshift, int bshift) return type; } +#ifdef CONFIG_PIXMAN pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf) { pixman_format_code_t format; @@ -158,6 +159,7 @@ pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf) } return format; } +#endif /* * Return true for known-good pixman conversions. @@ -186,6 +188,7 @@ bool qemu_pixman_check_format(DisplayChangeListener *dcl, } } +#ifdef CONFIG_PIXMAN pixman_image_t *qemu_pixman_linebuf_create(pixman_format_code_t format, int width) { @@ -211,6 +214,7 @@ pixman_image_t *qemu_pixman_mirror_create(pixman_format_code_t format, NULL, pixman_image_get_stride(image)); } +#endif void qemu_pixman_image_unref(pixman_image_t *image) { @@ -220,6 +224,7 @@ void qemu_pixman_image_unref(pixman_image_t *image) pixman_image_unref(image); } +#ifdef CONFIG_PIXMAN pixman_image_t *qemu_pixman_glyph_from_vgafont(int height, const uint8_t *font, unsigned int ch) { @@ -262,3 +267,4 @@ void qemu_pixman_glyph_render(pixman_image_t *glyph, pixman_image_unref(ifg); pixman_image_unref(ibg); } +#endif /* CONFIG_PIXMAN */ -- 2.41.0
[PATCH v8 14/24] vhost-user-gpu: skip VHOST_USER_GPU_UPDATE when !PIXMAN
From: Marc-André Lureau This simply means that 2d drawing updates won't be handled, but 3d should work. Signed-off-by: Marc-André Lureau Acked-by: Michael S. Tsirkin --- hw/display/vhost-user-gpu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c index 1150521d9d..709c8a02a1 100644 --- a/hw/display/vhost-user-gpu.c +++ b/hw/display/vhost-user-gpu.c @@ -307,6 +307,7 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg) dpy_gl_update(con, m->x, m->y, m->width, m->height); break; } +#ifdef CONFIG_PIXMAN case VHOST_USER_GPU_UPDATE: { VhostUserGpuUpdate *m = &msg->payload.update; @@ -334,6 +335,7 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg) } break; } +#endif default: g_warning("unhandled message %d %d", msg->request, msg->size); } -- 2.41.0
[PATCH v8 11/24] qmp/hmp: disable screendump if PIXMAN is missing
From: Marc-André Lureau The command requires color conversion and line-by-line feeding. We could have a simple fallback for simple formats though. Signed-off-by: Marc-André Lureau Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Thomas Huth --- qapi/ui.json | 3 ++- ui/ui-hmp-cmds.c | 2 ++ ui/ui-qmp-cmds.c | 2 ++ hmp-commands.hx | 2 ++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/qapi/ui.json b/qapi/ui.json index 006616aa77..e74cc3efb6 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -200,7 +200,8 @@ { 'command': 'screendump', 'data': {'filename': 'str', '*device': 'str', '*head': 'int', '*format': 'ImageFormat'}, - 'coroutine': true } + 'coroutine': true, + 'if': 'CONFIG_PIXMAN' } ## # == Spice diff --git a/ui/ui-hmp-cmds.c b/ui/ui-hmp-cmds.c index c671389473..26c8ced1f2 100644 --- a/ui/ui-hmp-cmds.c +++ b/ui/ui-hmp-cmds.c @@ -437,6 +437,7 @@ void sendkey_completion(ReadLineState *rs, int nb_args, const char *str) } } +#ifdef CONFIG_PIXMAN void coroutine_fn hmp_screendump(Monitor *mon, const QDict *qdict) { @@ -458,6 +459,7 @@ hmp_screendump(Monitor *mon, const QDict *qdict) end: hmp_handle_error(mon, err); } +#endif void hmp_client_migrate_info(Monitor *mon, const QDict *qdict) { diff --git a/ui/ui-qmp-cmds.c b/ui/ui-qmp-cmds.c index debc07d678..d772e1cb7f 100644 --- a/ui/ui-qmp-cmds.c +++ b/ui/ui-qmp-cmds.c @@ -212,6 +212,7 @@ void qmp_client_migrate_info(const char *protocol, const char *hostname, error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "protocol", "'spice'"); } +#ifdef CONFIG_PIXMAN #ifdef CONFIG_PNG /** * png_save: Take a screenshot as PNG @@ -391,3 +392,4 @@ qmp_screendump(const char *filename, const char *device, } } } +#endif /* CONFIG_PIXMAN */ diff --git a/hmp-commands.hx b/hmp-commands.hx index c0a27688b6..765349ed14 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -252,6 +252,7 @@ SRST ERST +#ifdef CONFIG_PIXMAN { .name = "screendump", .args_type = "filename:F,format:-fs,device:s?,head:i?", @@ -267,6 +268,7 @@ SRST ``screendump`` *filename* Save screen into PPM image *filename*. ERST +#endif { .name = "logfile", -- 2.41.0
[PATCH v8 13/24] ui/console: when PIXMAN is unavailable, don't draw placeholder msg
From: Marc-André Lureau When we can't draw text, simply show a blank display. Signed-off-by: Marc-André Lureau Reviewed-by: Thomas Huth --- ui/console.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/console.c b/ui/console.c index a72c495b5a..8e688d3569 100644 --- a/ui/console.c +++ b/ui/console.c @@ -584,6 +584,7 @@ DisplaySurface *qemu_create_placeholder_surface(int w, int h, const char *msg) { DisplaySurface *surface = qemu_create_displaysurface(w, h); +#ifdef CONFIG_PIXMAN pixman_color_t bg = QEMU_PIXMAN_COLOR_BLACK; pixman_color_t fg = QEMU_PIXMAN_COLOR_GRAY; pixman_image_t *glyph; @@ -598,6 +599,7 @@ DisplaySurface *qemu_create_placeholder_surface(int w, int h, x+i, y, FONT_WIDTH, FONT_HEIGHT); qemu_pixman_image_unref(glyph); } +#endif surface->flags |= QEMU_PLACEHOLDER_FLAG; return surface; } -- 2.41.0
[PATCH v8 22/24] hw/mips: FULOONG depends on VT82C686
From: Marc-André Lureau Signed-off-by: Marc-André Lureau Reviewed-by: Philippe Mathieu-Daudé --- hw/mips/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig index ac1eb06a51..66ec536e06 100644 --- a/hw/mips/Kconfig +++ b/hw/mips/Kconfig @@ -33,6 +33,7 @@ config JAZZ config FULOONG bool select PCI_BONITO +select VT82C686 config LOONGSON3V bool -- 2.41.0
[PATCH v8 17/24] ui/spice: SPICE/QXL requires PIXMAN
From: Marc-André Lureau Signed-off-by: Marc-André Lureau Reviewed-by: Thomas Huth --- meson.build| 6 +- hw/display/Kconfig | 2 +- ui/meson.build | 10 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/meson.build b/meson.build index 3e60f42f94..0f578ddbf4 100644 --- a/meson.build +++ b/meson.build @@ -1015,7 +1015,11 @@ if not get_option('spice_protocol').auto() or have_system method: 'pkg-config') endif spice = not_found -if not get_option('spice').auto() or have_system +if get_option('spice') \ + .disable_auto_if(not have_system) \ + .require(pixman.found(), + error_message: 'cannot enable SPICE if pixman is not available') \ + .allowed() spice = dependency('spice-server', version: '>=0.14.0', required: get_option('spice'), method: 'pkg-config') diff --git a/hw/display/Kconfig b/hw/display/Kconfig index 7b3da68d1c..4d8b0cec40 100644 --- a/hw/display/Kconfig +++ b/hw/display/Kconfig @@ -93,7 +93,7 @@ config VGA config QXL bool -depends on SPICE && PCI +depends on SPICE && PCI && PIXMAN select VGA config VIRTIO_GPU diff --git a/ui/meson.build b/ui/meson.build index 19723188b5..024f494faf 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -141,12 +141,12 @@ if spice.found() 'spice-display.c' )) ui_modules += {'spice-core' : spice_core_ss} -endif -if spice.found() and gio.found() - spice_ss = ss.source_set() - spice_ss.add(spice, gio, pixman, files('spice-app.c')) - ui_modules += {'spice-app': spice_ss} + if gio.found() +spice_ss = ss.source_set() +spice_ss.add(spice, gio, pixman, files('spice-app.c')) +ui_modules += {'spice-app': spice_ss} + endif endif keymaps = [ -- 2.41.0
[PATCH v8 12/24] virtio-gpu: replace PIXMAN for region/rect test
From: Marc-André Lureau Use a simpler implementation for rectangle geometry & intersect, drop the need for (more complex) PIXMAN functions. Signed-off-by: Marc-André Lureau Acked-by: Michael S. Tsirkin --- include/ui/rect.h | 59 + hw/display/virtio-gpu.c | 30 - 2 files changed, 70 insertions(+), 19 deletions(-) create mode 100644 include/ui/rect.h diff --git a/include/ui/rect.h b/include/ui/rect.h new file mode 100644 index 00..94898f92d0 --- /dev/null +++ b/include/ui/rect.h @@ -0,0 +1,59 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef QEMU_RECT_H +#define QEMU_RECT_H + +#include +#include + +typedef struct QemuRect { +int16_t x; +int16_t y; +uint16_t width; +uint16_t height; +} QemuRect; + +static inline void qemu_rect_init(QemuRect *rect, + int16_t x, int16_t y, + uint16_t width, uint16_t height) +{ +rect->x = x; +rect->y = x; +rect->width = width; +rect->height = height; +} + +static inline void qemu_rect_translate(QemuRect *rect, + int16_t dx, int16_t dy) +{ +rect->x += dx; +rect->y += dy; +} + +static inline bool qemu_rect_intersect(const QemuRect *a, const QemuRect *b, + QemuRect *res) +{ +int16_t x1, x2, y1, y2; + +x1 = MAX(a->x, b->x); +y1 = MAX(a->y, b->y); +x2 = MIN(a->x + a->width, b->x + b->width); +y2 = MIN(a->y + a->height, b->y + b->height); + +if (x1 >= x2 || y1 >= y2) { +if (res) { +qemu_rect_init(res, 0, 0, 0, 0); +} + +return false; +} + +if (res) { +qemu_rect_init(res, x1, y1, x2 - x1, y2 - y1); +} + +return true; +} + +#endif diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index 2707bceea8..b016d3bac8 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -16,6 +16,7 @@ #include "qemu/iov.h" #include "sysemu/cpus.h" #include "ui/console.h" +#include "ui/rect.h" #include "trace.h" #include "sysemu/dma.h" #include "sysemu/sysemu.h" @@ -503,7 +504,7 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g, struct virtio_gpu_simple_resource *res; struct virtio_gpu_resource_flush rf; struct virtio_gpu_scanout *scanout; -pixman_region16_t flush_region; +QemuRect flush_rect; bool within_bounds = false; bool update_submitted = false; int i; @@ -565,34 +566,25 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g, return; } -pixman_region_init_rect(&flush_region, -rf.r.x, rf.r.y, rf.r.width, rf.r.height); +qemu_rect_init(&flush_rect, rf.r.x, rf.r.y, rf.r.width, rf.r.height); for (i = 0; i < g->parent_obj.conf.max_outputs; i++) { -pixman_region16_t region, finalregion; -pixman_box16_t *extents; +QemuRect rect; if (!(res->scanout_bitmask & (1 << i))) { continue; } scanout = &g->parent_obj.scanout[i]; -pixman_region_init(&finalregion); -pixman_region_init_rect(®ion, scanout->x, scanout->y, -scanout->width, scanout->height); +qemu_rect_init(&rect, scanout->x, scanout->y, + scanout->width, scanout->height); -pixman_region_intersect(&finalregion, &flush_region, ®ion); -pixman_region_translate(&finalregion, -scanout->x, -scanout->y); -extents = pixman_region_extents(&finalregion); /* work out the area we need to update for each console */ -dpy_gfx_update(g->parent_obj.scanout[i].con, - extents->x1, extents->y1, - extents->x2 - extents->x1, - extents->y2 - extents->y1); - -pixman_region_fini(®ion); -pixman_region_fini(&finalregion); +if (qemu_rect_intersect(&flush_rect, &rect, &rect)) { +qemu_rect_translate(&rect, -scanout->x, -scanout->y); +dpy_gfx_update(g->parent_obj.scanout[i].con, + rect.x, rect.y, rect.width, rect.height); +} } -pixman_region_fini(&flush_region); } static void virtio_unref_resource(pixman_image_t *image, void *data) -- 2.41.0
[PATCH v8 05/24] vl: drop needless -spice checks
From: Marc-André Lureau Since commit 5324e3e958e ("qemu-options: define -spice only #ifdef CONFIG_SPICE"), it is unnecessary to check at runtime for "-spice" option. Signed-off-by: Marc-André Lureau Reviewed-by: Thomas Huth --- system/vl.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/system/vl.c b/system/vl.c index 3fb569254a..fb0389e4d0 100644 --- a/system/vl.c +++ b/system/vl.c @@ -3475,12 +3475,7 @@ void qemu_init(int argc, char **argv) break; #ifdef CONFIG_SPICE case QEMU_OPTION_spice: -olist = qemu_find_opts_err("spice", NULL); -if (!olist) { -error_report("spice support is disabled"); -exit(1); -} -opts = qemu_opts_parse_noisily(olist, optarg, false); +opts = qemu_opts_parse_noisily(qemu_find_opts("spice"), optarg, false); if (!opts) { exit(1); } -- 2.41.0
[PATCH v8 09/24] ui/console: allow to override the default VC
From: Marc-André Lureau If a display is backed by a specialized VC, allow to override the default "vc:80Cx24C". As suggested by Paolo, if the display doesn't implement a VC (get_vc() returns NULL), use a fallback that will use a muxed console on stdio. This changes the behaviour of "qemu -display none", to create a muxed serial/monitor by default (on TTY & not daemonized). Signed-off-by: Marc-André Lureau Reviewed-by: Thomas Huth --- include/ui/console.h | 2 ++ system/vl.c | 27 +-- ui/console.c | 14 ++ 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index acb61a7f15..a4a49ffc64 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -462,12 +462,14 @@ struct QemuDisplay { DisplayType type; void (*early_init)(DisplayOptions *opts); void (*init)(DisplayState *ds, DisplayOptions *opts); +const char *vc; }; void qemu_display_register(QemuDisplay *ui); bool qemu_display_find_default(DisplayOptions *opts); void qemu_display_early_init(DisplayOptions *opts); void qemu_display_init(DisplayState *ds, DisplayOptions *opts); +const char *qemu_display_get_vc(DisplayOptions *opts); void qemu_display_help(void); /* vnc.c */ diff --git a/system/vl.c b/system/vl.c index cf46e438cc..bd7fad770b 100644 --- a/system/vl.c +++ b/system/vl.c @@ -1372,6 +1372,7 @@ static void qemu_setup_display(void) static void qemu_create_default_devices(void) { MachineClass *machine_class = MACHINE_GET_CLASS(current_machine); +const char *vc = qemu_display_get_vc(&dpy); if (is_daemonized()) { /* According to documentation and historically, -nographic redirects @@ -1390,24 +1391,30 @@ static void qemu_create_default_devices(void) } } -if (nographic) { -if (default_parallel) +if (nographic || (!vc && !is_daemonized() && isatty(STDOUT_FILENO))) { +if (default_parallel) { add_device_config(DEV_PARALLEL, "null"); +} if (default_serial && default_monitor) { add_device_config(DEV_SERIAL, "mon:stdio"); } else { -if (default_serial) +if (default_serial) { add_device_config(DEV_SERIAL, "stdio"); -if (default_monitor) +} +if (default_monitor) { monitor_parse("stdio", "readline", false); +} } } else { -if (default_serial) -add_device_config(DEV_SERIAL, "vc:80Cx24C"); -if (default_parallel) -add_device_config(DEV_PARALLEL, "vc:80Cx24C"); -if (default_monitor) -monitor_parse("vc:80Cx24C", "readline", false); +if (default_serial) { +add_device_config(DEV_SERIAL, vc ?: "null"); +} +if (default_parallel) { +add_device_config(DEV_PARALLEL, vc ?: "null"); +} +if (default_monitor && vc) { +monitor_parse(vc, "readline", false); +} } if (default_net) { diff --git a/ui/console.c b/ui/console.c index 8ee66d10c5..a758ed62ad 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1675,6 +1675,20 @@ void qemu_display_init(DisplayState *ds, DisplayOptions *opts) dpys[opts->type]->init(ds, opts); } +const char *qemu_display_get_vc(DisplayOptions *opts) +{ +assert(opts->type < DISPLAY_TYPE__MAX); +if (opts->type == DISPLAY_TYPE_NONE) { +return NULL; +} +assert(dpys[opts->type] != NULL); +if (dpys[opts->type]->vc) { +return dpys[opts->type]->vc; +} else { +return "vc:80Cx24C"; +} +} + void qemu_display_help(void) { int idx; -- 2.41.0
[PATCH v8 24/24] build-sys: make pixman actually optional
From: Marc-André Lureau Signed-off-by: Marc-André Lureau Reviewed-by: Thomas Huth --- meson.build | 3 --- 1 file changed, 3 deletions(-) diff --git a/meson.build b/meson.build index 8422e7da0c..4848930680 100644 --- a/meson.build +++ b/meson.build @@ -817,9 +817,6 @@ if not get_option('pixman').auto() or have_system or have_tools pixman = dependency('pixman-1', required: get_option('pixman'), version:'>=0.21.8', method: 'pkg-config') endif -if not pixman.found() and (have_system or have_tools) - error('FIXME: pixman is currently required') -endif zlib = dependency('zlib', required: true) -- 2.41.0
[PATCH v8 16/24] ui/vnc: VNC requires PIXMAN
From: Marc-André Lureau Signed-off-by: Marc-André Lureau Reviewed-by: Thomas Huth --- meson.build| 6 +- ui/meson.build | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 505cc591b9..3e60f42f94 100644 --- a/meson.build +++ b/meson.build @@ -1560,7 +1560,11 @@ endif vnc = not_found jpeg = not_found sasl = not_found -if get_option('vnc').allowed() and have_system +if get_option('vnc') \ + .disable_auto_if(not have_system) \ + .require(pixman.found(), + error_message: 'cannot enable VNC if pixman is not available') \ + .allowed() vnc = declare_dependency() # dummy dependency jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'), method: 'pkg-config') diff --git a/ui/meson.build b/ui/meson.build index 7c99613950..19723188b5 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -46,7 +46,7 @@ vnc_ss.add(files( )) vnc_ss.add(zlib, jpeg, gnutls) vnc_ss.add(when: sasl, if_true: files('vnc-auth-sasl.c')) -system_ss.add_all(when: vnc, if_true: vnc_ss) +system_ss.add_all(when: [vnc, pixman], if_true: vnc_ss) system_ss.add(when: vnc, if_false: files('vnc-stubs.c')) ui_modules = {} -- 2.41.0
[PATCH v8 20/24] arm/kconfig: XLNX_ZYNQMP_ARM depends on PIXMAN
From: Marc-André Lureau The Display Port has some strong PIXMAN dependency. Signed-off-by: Marc-André Lureau Reviewed-by: Thomas Huth --- hw/arm/Kconfig | 3 ++- hw/display/Kconfig | 5 + hw/display/meson.build | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index e35007ed41..8ce288a40c 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -451,7 +451,7 @@ config STM32F405_SOC config XLNX_ZYNQMP_ARM bool default y -depends on TCG && AARCH64 +depends on TCG && AARCH64 && PIXMAN select AHCI select ARM_GIC select CADENCE @@ -463,6 +463,7 @@ config XLNX_ZYNQMP_ARM select XILINX_AXI select XILINX_SPIPS select XLNX_CSU_DMA +select XLNX_DISPLAYPORT select XLNX_ZYNQMP select XLNX_ZDMA select USB_DWC3 diff --git a/hw/display/Kconfig b/hw/display/Kconfig index 4d8b0cec40..1aafe1923d 100644 --- a/hw/display/Kconfig +++ b/hw/display/Kconfig @@ -134,3 +134,8 @@ config MACFB bool select FRAMEBUFFER depends on NUBUS + +config XLNX_DISPLAYPORT +bool +# defaults to "N", enabled by specific boards +depends on PIXMAN diff --git a/hw/display/meson.build b/hw/display/meson.build index 2b64fd9f9d..9c06aaee20 100644 --- a/hw/display/meson.build +++ b/hw/display/meson.build @@ -58,7 +58,7 @@ if config_all_devices.has_key('CONFIG_QXL') endif system_ss.add(when: 'CONFIG_DPCD', if_true: files('dpcd.c')) -system_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx_dp.c')) +system_ss.add(when: 'CONFIG_XLNX_DISPLAYPORT', if_true: files('xlnx_dp.c')) system_ss.add(when: 'CONFIG_ARTIST', if_true: files('artist.c')) -- 2.41.0
[PATCH v8 18/24] ui/gtk: -display gtk requires PIXMAN
From: Marc-André Lureau Signed-off-by: Marc-André Lureau Reviewed-by: Thomas Huth --- meson.build | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 0f578ddbf4..8422e7da0c 100644 --- a/meson.build +++ b/meson.build @@ -1531,7 +1531,11 @@ gtkx11 = not_found vte = not_found have_gtk_clipboard = get_option('gtk_clipboard').enabled() -if not get_option('gtk').auto() or have_system +if get_option('gtk') \ + .disable_auto_if(not have_system) \ + .require(pixman.found(), + error_message: 'cannot enable GTK if pixman is not available') \ + .allowed() gtk = dependency('gtk+-3.0', version: '>=3.22.0', method: 'pkg-config', required: get_option('gtk')) -- 2.41.0
[PATCH v8 01/24] build-sys: add a "pixman" feature
From: Marc-André Lureau For now, pixman is mandatory, but we set config_host.h and Kconfig. Once compilation is fixed, "pixman" will become actually optional. Signed-off-by: Marc-André Lureau Reviewed-by: Thomas Huth --- meson.build | 10 -- include/ui/qemu-pixman.h | 2 ++ Kconfig.host | 3 +++ meson_options.txt | 2 ++ scripts/meson-buildoptions.sh | 3 +++ 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 51a51075db..505cc591b9 100644 --- a/meson.build +++ b/meson.build @@ -813,10 +813,14 @@ if 'ust' in get_option('trace_backends') method: 'pkg-config') endif pixman = not_found -if have_system or have_tools - pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8', +if not get_option('pixman').auto() or have_system or have_tools + pixman = dependency('pixman-1', required: get_option('pixman'), version:'>=0.21.8', method: 'pkg-config') endif +if not pixman.found() and (have_system or have_tools) + error('FIXME: pixman is currently required') +endif + zlib = dependency('zlib', required: true) libaio = not_found @@ -2149,6 +2153,7 @@ config_host_data.set('CONFIG_SECCOMP', seccomp.found()) if seccomp.found() config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc) endif +config_host_data.set('CONFIG_PIXMAN', pixman.found()) config_host_data.set('CONFIG_SNAPPY', snappy.found()) config_host_data.set('CONFIG_SOLARIS', targetos == 'sunos') if get_option('tcg').allowed() @@ -2868,6 +2873,7 @@ have_ivshmem = config_host_data.get('CONFIG_EVENTFD') host_kconfig = \ (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \ (have_tpm ? ['CONFIG_TPM=y'] : []) + \ + (pixman.found() ? ['CONFIG_PIXMAN=y'] : []) + \ (spice.found() ? ['CONFIG_SPICE=y'] : []) + \ (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \ (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \ diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h index e587c48b1f..d37feb5e3c 100644 --- a/include/ui/qemu-pixman.h +++ b/include/ui/qemu-pixman.h @@ -6,11 +6,13 @@ #ifndef QEMU_PIXMAN_H #define QEMU_PIXMAN_H +#ifdef CONFIG_PIXMAN /* pixman-0.16.0 headers have a redundant declaration */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wredundant-decls" #include #pragma GCC diagnostic pop +#endif /* * pixman image formats are defined to be native endian, diff --git a/Kconfig.host b/Kconfig.host index 2ee71578f3..f496475f8e 100644 --- a/Kconfig.host +++ b/Kconfig.host @@ -11,6 +11,9 @@ config OPENGL config X11 bool +config PIXMAN +bool + config SPICE bool diff --git a/meson_options.txt b/meson_options.txt index 5c212fcd45..c9baeda639 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -226,6 +226,8 @@ option('l2tpv3', type : 'feature', value : 'auto', description: 'l2tpv3 network backend support') option('netmap', type : 'feature', value : 'auto', description: 'netmap network backend support') +option('pixman', type : 'feature', value : 'auto', + description: 'pixman support') option('slirp', type: 'feature', value: 'auto', description: 'libslirp user mode network backend support') option('vde', type : 'feature', value : 'auto', diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh index e9d6d39279..680fa3f581 100644 --- a/scripts/meson-buildoptions.sh +++ b/scripts/meson-buildoptions.sh @@ -160,6 +160,7 @@ meson_options_help() { printf "%s\n" ' pa PulseAudio sound support' printf "%s\n" ' parallels parallels image format support' printf "%s\n" ' pipewirePipeWire sound support' + printf "%s\n" ' pixman pixman support' printf "%s\n" ' plugins TCG plugins via shared library loading' printf "%s\n" ' png PNG support with libpng' printf "%s\n" ' pvrdma Enable PVRDMA support' @@ -419,6 +420,8 @@ _meson_option_parse() { --disable-parallels) printf "%s" -Dparallels=disabled ;; --enable-pipewire) printf "%s" -Dpipewire=enabled ;; --disable-pipewire) printf "%s" -Dpipewire=disabled ;; +--enable-pixman) printf "%s" -Dpixman=enabled ;; +--disable-pixman) printf "%s" -Dpixman=disabled ;; --with-pkgversion=*) quote_sh "-Dpkgversion=$2" ;; --enable-plugins) printf "%s" -Dplugins=true ;; --disable-plugins) printf "%s" -Dplugins=false ;; -- 2.41.0
[PATCH v8 23/24] hw/display/ati: allow compiling without PIXMAN
From: Marc-André Lureau Change the "x-pixman" property default value and use the fallback path when PIXMAN support is disabled. Signed-off-by: Marc-André Lureau --- hw/display/ati.c | 16 +++- hw/display/ati_2d.c| 11 +++ hw/display/meson.build | 2 +- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/hw/display/ati.c b/hw/display/ati.c index 9a87a5504a..51a3b156ac 100644 --- a/hw/display/ati.c +++ b/hw/display/ati.c @@ -32,6 +32,13 @@ #define ATI_DEBUG_HW_CURSOR 0 +#ifdef CONFIG_PIXMAN +#define DEFAULT_X_PIXMAN 3 +#else +#define DEFAULT_X_PIXMAN 0 +#endif + + static const struct { const char *name; uint16_t dev_id; @@ -946,6 +953,12 @@ static void ati_vga_realize(PCIDevice *dev, Error **errp) ATIVGAState *s = ATI_VGA(dev); VGACommonState *vga = &s->vga; +#ifndef CONFIG_PIXMAN +if (s->use_pixman != 0) { +warn_report("x-pixman != 0, not effective without PIXMAN"); +} +#endif + if (s->model) { int i; for (i = 0; i < ARRAY_SIZE(ati_model_aliases); i++) { @@ -1033,7 +1046,8 @@ static Property ati_vga_properties[] = { DEFINE_PROP_UINT16("x-device-id", ATIVGAState, dev_id, PCI_DEVICE_ID_ATI_RAGE128_PF), DEFINE_PROP_BOOL("guest_hwcursor", ATIVGAState, cursor_guest_mode, false), -DEFINE_PROP_UINT8("x-pixman", ATIVGAState, use_pixman, 3), +/* this a debug option, prefer PROP_UINT over PROP_BIT for simplicity */ +DEFINE_PROP_UINT8("x-pixman", ATIVGAState, use_pixman, DEFAULT_X_PIXMAN), DEFINE_PROP_END_OF_LIST() }; diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c index 0e6b8e4367..e58acd0802 100644 --- a/hw/display/ati_2d.c +++ b/hw/display/ati_2d.c @@ -92,7 +92,7 @@ void ati_2d_blt(ATIVGAState *s) switch (s->regs.dp_mix & GMC_ROP3_MASK) { case ROP3_SRCCOPY: { -bool fallback = false; +bool fallback = true; unsigned src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ? s->regs.src_x : s->regs.src_x + 1 - s->regs.dst_width); unsigned src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ? @@ -119,6 +119,7 @@ void ati_2d_blt(ATIVGAState *s) src_stride /= sizeof(uint32_t); dst_stride /= sizeof(uint32_t); +#ifdef CONFIG_PIXMAN DPRINTF("pixman_blt(%p, %p, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)\n", src_bits, dst_bits, src_stride, dst_stride, bpp, bpp, src_x, src_y, dst_x, dst_y, @@ -147,9 +148,8 @@ void ati_2d_blt(ATIVGAState *s) s->regs.dst_width, s->regs.dst_height); } g_free(tmp); -} else { -fallback = true; } +#endif if (fallback) { unsigned int y, i, j, bypp = bpp / 8; unsigned int src_pitch = src_stride * sizeof(uint32_t); @@ -203,12 +203,15 @@ void ati_2d_blt(ATIVGAState *s) } dst_stride /= sizeof(uint32_t); +#ifdef CONFIG_PIXMAN DPRINTF("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n", dst_bits, dst_stride, bpp, dst_x, dst_y, s->regs.dst_width, s->regs.dst_height, filler); if (!(s->use_pixman & BIT(0)) || !pixman_fill((uint32_t *)dst_bits, dst_stride, bpp, dst_x, dst_y, -s->regs.dst_width, s->regs.dst_height, filler)) { +s->regs.dst_width, s->regs.dst_height, filler)) +#endif +{ /* fallback when pixman failed or we don't want to call it */ unsigned int x, y, i, bypp = bpp / 8; unsigned int dst_pitch = dst_stride * sizeof(uint32_t); diff --git a/hw/display/meson.build b/hw/display/meson.build index 9c06aaee20..344dfe3d8c 100644 --- a/hw/display/meson.build +++ b/hw/display/meson.build @@ -62,7 +62,7 @@ system_ss.add(when: 'CONFIG_XLNX_DISPLAYPORT', if_true: files('xlnx_dp.c')) system_ss.add(when: 'CONFIG_ARTIST', if_true: files('artist.c')) -system_ss.add(when: [pixman, 'CONFIG_ATI_VGA'], if_true: files('ati.c', 'ati_2d.c', 'ati_dbg.c')) +system_ss.add(when: 'CONFIG_ATI_VGA', if_true: [files('ati.c', 'ati_2d.c', 'ati_dbg.c'), pixman]) if config_all_devices.has_key('CONFIG_VIRTIO_GPU') -- 2.41.0
[PATCH v8 21/24] hw/sm501: allow compiling without PIXMAN
From: Marc-André Lureau Change the "x-pixman" property default value and use the fallback path when PIXMAN support is disabled. Signed-off-by: Marc-André Lureau Reviewed-by: BALATON Zoltan --- hw/display/sm501.c | 46 +- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/hw/display/sm501.c b/hw/display/sm501.c index 0eecd00701..33fd08955d 100644 --- a/hw/display/sm501.c +++ b/hw/display/sm501.c @@ -438,6 +438,12 @@ #define SM501_HWC_WIDTH 64 #define SM501_HWC_HEIGHT64 +#ifdef CONFIG_PIXMAN +#define DEFAULT_X_PIXMAN 7 +#else +#define DEFAULT_X_PIXMAN 0 +#endif + /* SM501 local memory size taken from "linux/drivers/mfd/sm501.c" */ static const uint32_t sm501_mem_local_size[] = { [0] = 4 * MiB, @@ -730,7 +736,6 @@ static void sm501_2d_operation(SM501State *s) switch (cmd) { case 0: /* BitBlt */ { -static uint32_t tmp_buf[16384]; unsigned int src_x = (s->twoD_source >> 16) & 0x01FFF; unsigned int src_y = s->twoD_source & 0x; uint32_t src_base = s->twoD_source_base & 0x03FF; @@ -828,9 +833,11 @@ static void sm501_2d_operation(SM501State *s) de = db + (width + (height - 1) * dst_pitch) * bypp; overlap = (db < se && sb < de); } +#ifdef CONFIG_PIXMAN if (overlap && (s->use_pixman & BIT(2))) { /* pixman can't do reverse blit: copy via temporary */ int tmp_stride = DIV_ROUND_UP(width * bypp, sizeof(uint32_t)); +static uint32_t tmp_buf[16384]; uint32_t *tmp = tmp_buf; if (tmp_stride * sizeof(uint32_t) * height > sizeof(tmp_buf)) { @@ -860,9 +867,12 @@ static void sm501_2d_operation(SM501State *s) dst_pitch * bypp / sizeof(uint32_t), 8 * bypp, 8 * bypp, src_x, src_y, dst_x, dst_y, width, height); -} else { +} else +#else +{ fallback = true; } +#endif if (fallback) { uint8_t *sp = s->local_mem + src_base; uint8_t *d = s->local_mem + dst_base; @@ -894,20 +904,23 @@ static void sm501_2d_operation(SM501State *s) color = cpu_to_le16(color); } +#ifdef CONFIG_PIXMAN if (!(s->use_pixman & BIT(0)) || (width == 1 && height == 1) || !pixman_fill((uint32_t *)&s->local_mem[dst_base], dst_pitch * bypp / sizeof(uint32_t), 8 * bypp, - dst_x, dst_y, width, height, color)) { -/* fallback when pixman failed or we don't want to call it */ -uint8_t *d = s->local_mem + dst_base; -unsigned int x, y, i; -for (y = 0; y < height; y++) { -i = (dst_x + (dst_y + y) * dst_pitch) * bypp; -for (x = 0; x < width; x++, i += bypp) { -stn_he_p(&d[i], bypp, color); + dst_x, dst_y, width, height, color)) +#endif +{ +/* fallback when pixman failed or we don't want to call it */ +uint8_t *d = s->local_mem + dst_base; +unsigned int x, y, i; +for (y = 0; y < height; y++) { +i = (dst_x + (dst_y + y) * dst_pitch) * bypp; +for (x = 0; x < width; x++, i += bypp) { +stn_he_p(&d[i], bypp, color); +} } } -} break; } default: @@ -1878,6 +1891,12 @@ static void sm501_reset(SM501State *s) static void sm501_init(SM501State *s, DeviceState *dev, uint32_t local_mem_bytes) { +#ifndef CONFIG_PIXMAN +if (s->use_pixman != 0) { +warn_report("x-pixman != 0, not effective without PIXMAN"); +} +#endif + s->local_mem_size_index = get_local_mem_size_index(local_mem_bytes); /* local memory */ @@ -2038,7 +2057,8 @@ static void sm501_realize_sysbus(DeviceState *dev, Error **errp) static Property sm501_sysbus_properties[] = { DEFINE_PROP_UINT32("vram-size", SM501SysBusState, vram_size, 0), -DEFINE_PROP_UINT8("x-pixman", SM501SysBusState, state.use_pixman, 7), +/* this a debug option, prefer PROP_UINT over PROP_BIT for simplicity */ +DEFINE_PROP_UINT8("x-pixman", SM501SysBusState, state.use_pixman, DEFAULT_X_PIXMAN), DEFINE_PROP_END_OF_LIST(), }; @@ -2126,7 +2146,7 @@ static void sm501_realize_pci(PCIDevice *dev, Error **errp) static Property sm501_pci_properties[] = { DEFINE_PROP_UINT32("vram-size", SM501PCIState, vram_size, 64 * MiB), -DEFINE_PROP_UINT8("x-pixman", SM501PCIState, state.use_pixman, 7), +DEFINE_PROP_UINT8("x-pixman", SM501PCIState, state.use_pixman, DEFAULT_X_PIXMAN), DEFINE_PROP_END_OF_LIST(), }; --
[PATCH v8 08/24] vl: move display early init before default devices
From: Marc-André Lureau The next commit needs to have the display registered itself before creating the default VCs. Signed-off-by: Marc-André Lureau Reviewed-by: Thomas Huth --- system/vl.c | 31 ++- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/system/vl.c b/system/vl.c index e9819408df..cf46e438cc 100644 --- a/system/vl.c +++ b/system/vl.c @@ -1352,6 +1352,23 @@ static void qemu_disable_default_devices(void) } } +static void qemu_setup_display(void) +{ +if (dpy.type == DISPLAY_TYPE_DEFAULT && !display_remote) { +if (!qemu_display_find_default(&dpy)) { +dpy.type = DISPLAY_TYPE_NONE; +#if defined(CONFIG_VNC) +vnc_parse("localhost:0,to=99,id=default"); +#endif +} +} +if (dpy.type == DISPLAY_TYPE_DEFAULT) { +dpy.type = DISPLAY_TYPE_NONE; +} + +qemu_display_early_init(&dpy); +} + static void qemu_create_default_devices(void) { MachineClass *machine_class = MACHINE_GET_CLASS(current_machine); @@ -1401,18 +1418,6 @@ static void qemu_create_default_devices(void) #endif } -if (dpy.type == DISPLAY_TYPE_DEFAULT && !display_remote) { -if (!qemu_display_find_default(&dpy)) { -dpy.type = DISPLAY_TYPE_NONE; -#if defined(CONFIG_VNC) -vnc_parse("localhost:0,to=99,id=default"); -#endif -} -} -if (dpy.type == DISPLAY_TYPE_DEFAULT) { -dpy.type = DISPLAY_TYPE_NONE; -} - /* If no default VGA is requested, the default is "none". */ if (default_vga) { vga_model = get_default_vga_model(machine_class); @@ -1937,7 +1942,6 @@ static void qemu_create_early_backends(void) "ignoring option"); } -qemu_display_early_init(&dpy); qemu_console_early_init(); if (dpy.has_gl && dpy.gl != DISPLAYGL_MODE_OFF && display_opengl == 0) { @@ -3666,6 +3670,7 @@ void qemu_init(int argc, char **argv) suspend_mux_open(); qemu_disable_default_devices(); +qemu_setup_display(); qemu_create_default_devices(); qemu_create_early_backends(); -- 2.41.0
[PATCH v8 15/24] ui/gl: opengl doesn't require PIXMAN
From: Marc-André Lureau The QEMU fallback covers the requirements. We still need the flags of header inclusion with CONFIG_PIXMAN. Signed-off-by: Marc-André Lureau --- ui/meson.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/meson.build b/ui/meson.build index 3085e10a72..7c99613950 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -60,8 +60,8 @@ endif system_ss.add(opengl) if opengl.found() opengl_ss = ss.source_set() - opengl_ss.add(gbm) - opengl_ss.add(when: [opengl, pixman], + opengl_ss.add(gbm, pixman) + opengl_ss.add(when: [opengl], if_true: files('shader.c', 'console-gl.c', 'egl-helpers.c', 'egl-context.c')) ui_modules += {'opengl' : opengl_ss} endif -- 2.41.0
[PATCH v8 10/24] ui/vc: console-vc requires PIXMAN
From: Marc-André Lureau Add stubs for the fallback paths. get_vc() now returns NULL by default if !PIXMAN. Signed-off-by: Marc-André Lureau Reviewed-by: Thomas Huth --- ui/console-vc-stubs.c | 33 + ui/console.c | 3 +++ ui/meson.build| 2 +- 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 ui/console-vc-stubs.c diff --git a/ui/console-vc-stubs.c b/ui/console-vc-stubs.c new file mode 100644 index 00..2afc52329f --- /dev/null +++ b/ui/console-vc-stubs.c @@ -0,0 +1,33 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * QEMU VC stubs + */ +#include "qemu/osdep.h" + +#include "qapi/error.h" +#include "qemu/error-report.h" +#include "qemu/option.h" +#include "chardev/char.h" +#include "ui/console-priv.h" + +void qemu_text_console_select(QemuTextConsole *c) +{ +} + +const char * +qemu_text_console_get_label(QemuTextConsole *c) +{ +return NULL; +} + +void qemu_text_console_update_cursor(void) +{ +} + +void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym) +{ +} + +void qemu_console_early_init(void) +{ +} diff --git a/ui/console.c b/ui/console.c index a758ed62ad..a72c495b5a 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1685,8 +1685,11 @@ const char *qemu_display_get_vc(DisplayOptions *opts) if (dpys[opts->type]->vc) { return dpys[opts->type]->vc; } else { +#ifdef CONFIG_PIXMAN return "vc:80Cx24C"; +#endif } +return NULL; } void qemu_display_help(void) diff --git a/ui/meson.build b/ui/meson.build index 0a1e8272a3..3085e10a72 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -6,7 +6,6 @@ system_ss.add(png) system_ss.add(files( 'clipboard.c', 'console.c', - 'console-vc.c', 'cursor.c', 'input-keymap.c', 'input-legacy.c', @@ -19,6 +18,7 @@ system_ss.add(files( 'ui-qmp-cmds.c', 'util.c', )) +system_ss.add(when: pixman, if_true: files('console-vc.c'), if_false: files('console-vc-stubs.c')) if dbus_display system_ss.add(files('dbus-module.c')) endif -- 2.41.0
[PATCH v8 19/24] ui/dbus: do not require PIXMAN
From: Marc-André Lureau Implement a fallback path for region 2D update. Signed-off-by: Marc-André Lureau --- ui/dbus-listener.c | 90 -- ui/meson.build | 4 +-- 2 files changed, 65 insertions(+), 29 deletions(-) diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c index 36548a7f52..18f556aa73 100644 --- a/ui/dbus-listener.c +++ b/ui/dbus-listener.c @@ -26,9 +26,6 @@ #include "qapi/error.h" #include "sysemu/sysemu.h" #include "dbus.h" -#ifdef CONFIG_OPENGL -#include -#endif #ifdef G_OS_UNIX #include #endif @@ -41,6 +38,7 @@ #include "ui/shader.h" #include "ui/egl-helpers.h" #include "ui/egl-context.h" +#include "ui/qemu-pixman.h" #endif #include "trace.h" @@ -62,9 +60,11 @@ struct _DBusDisplayListener { QemuDBusDisplay1Listener *proxy; -#ifdef CONFIG_OPENGL +#ifdef CONFIG_PIXMAN /* Keep track of the damage region */ pixman_region32_t gl_damage; +#else +int gl_damage; #endif DisplayChangeListener dcl; @@ -545,6 +545,7 @@ static void dbus_gl_refresh(DisplayChangeListener *dcl) return; } +#ifdef CONFIG_PIXMAN int n_rects = pixman_region32_n_rects(&ddl->gl_damage); for (int i = 0; i < n_rects; i++) { @@ -555,6 +556,13 @@ static void dbus_gl_refresh(DisplayChangeListener *dcl) box->x2 - box->x1, box->y2 - box->y1); } pixman_region32_clear(&ddl->gl_damage); +#else +if (ddl->gl_damage) { +dbus_call_update_gl(dcl, 0, 0, +surface_width(ddl->ds), surface_height(ddl->ds)); +ddl->gl_damage = 0; +} +#endif } #endif /* OPENGL */ @@ -569,20 +577,64 @@ static void dbus_gl_gfx_update(DisplayChangeListener *dcl, { DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl); +#ifdef CONFIG_PIXMAN pixman_region32_t rect_region; pixman_region32_init_rect(&rect_region, x, y, w, h); pixman_region32_union(&ddl->gl_damage, &ddl->gl_damage, &rect_region); pixman_region32_fini(&rect_region); +#else +ddl->gl_damage++; +#endif } #endif +static void dbus_gfx_update_sub(DBusDisplayListener *ddl, +int x, int y, int w, int h) +{ +pixman_image_t *img; +size_t stride; +GVariant *v_data; + +/* make a copy, since gvariant only handles linear data */ +stride = w * DIV_ROUND_UP(PIXMAN_FORMAT_BPP(surface_format(ddl->ds)), 8); +img = pixman_image_create_bits(surface_format(ddl->ds), + w, h, NULL, stride); +#ifdef CONFIG_PIXMAN +pixman_image_composite(PIXMAN_OP_SRC, ddl->ds->image, NULL, img, + x, y, 0, 0, 0, 0, w, h); +#else +{ +uint8_t *src = (uint8_t *)pixman_image_get_data(ddl->ds->image); +uint8_t *dst = (uint8_t *)pixman_image_get_data(img); +int bp = PIXMAN_FORMAT_BPP(surface_format(ddl->ds)) / 8; +int hh; + +for (hh = 0; hh < h; hh++) { +memcpy(&dst[stride * hh], + &src[surface_stride(ddl->ds) * (hh + y) + x * bp], + stride); +} +} +#endif +v_data = g_variant_new_from_data( +G_VARIANT_TYPE("ay"), +pixman_image_get_data(img), +pixman_image_get_stride(img) * h, +TRUE, +(GDestroyNotify)pixman_image_unref, +img); +qemu_dbus_display1_listener_call_update(ddl->proxy, +x, y, w, h, pixman_image_get_stride(img), pixman_image_get_format(img), +v_data, +G_DBUS_CALL_FLAGS_NONE, +DBUS_DEFAULT_TIMEOUT, NULL, NULL, NULL); +} + static void dbus_gfx_update(DisplayChangeListener *dcl, int x, int y, int w, int h) { DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl); -pixman_image_t *img; GVariant *v_data; -size_t stride; assert(ddl->ds); @@ -619,25 +671,7 @@ static void dbus_gfx_update(DisplayChangeListener *dcl, return; } -/* make a copy, since gvariant only handles linear data */ -stride = w * DIV_ROUND_UP(PIXMAN_FORMAT_BPP(surface_format(ddl->ds)), 8); -img = pixman_image_create_bits(surface_format(ddl->ds), - w, h, NULL, stride); -pixman_image_composite(PIXMAN_OP_SRC, ddl->ds->image, NULL, img, - x, y, 0, 0, 0, 0, w, h); - -v_data = g_variant_new_from_data( -G_VARIANT_TYPE("ay"), -pixman_image_get_data(img), -pixman_image_get_stride(img) * h, -TRUE, -(GDestroyNotify)pixman_image_unref, -img); -qemu_dbus_display1_listener_call_update(ddl->proxy, -x, y, w, h, pixman_image_get_stride(img), pixman_image_get_format(img), -v_data, -G_DBUS_CALL_FLAGS_NONE, -DBUS_DEFAULT_TIMEOUT, NULL, NULL, NULL); +dbus_gfx_update_sub(ddl, x, y, w, h); } #ifdef CONFIG_OPENGL @@ -751,8 +785,10 @@ dbus_display_listener_dispose(GObject *object)
[PATCH v8 07/24] vl: simplify display_remote logic
From: Marc-André Lureau Bump the display_remote variable when the -vnc option is parsed, just like -spice. Signed-off-by: Marc-André Lureau Reviewed-by: Thomas Huth --- system/vl.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/system/vl.c b/system/vl.c index 19aef762e4..e9819408df 100644 --- a/system/vl.c +++ b/system/vl.c @@ -1401,11 +1401,6 @@ static void qemu_create_default_devices(void) #endif } -#if defined(CONFIG_VNC) -if (!QTAILQ_EMPTY(&(qemu_find_opts("vnc")->head))) { -display_remote++; -} -#endif if (dpy.type == DISPLAY_TYPE_DEFAULT && !display_remote) { if (!qemu_display_find_default(&dpy)) { dpy.type = DISPLAY_TYPE_NONE; @@ -3350,6 +3345,7 @@ void qemu_init(int argc, char **argv) #ifdef CONFIG_VNC case QEMU_OPTION_vnc: vnc_parse(optarg); +display_remote++; break; #endif case QEMU_OPTION_no_acpi: -- 2.41.0
[PATCH v8 04/24] ui: add pixman-minimal.h
From: Marc-André Lureau This is a tiny subset of PIXMAN API that is used pervasively in QEMU codebase to manage images and identify the underlying format. It doesn't seems worth to wrap this in a QEMU-specific API. Signed-off-by: Marc-André Lureau Acked-by: Thomas Huth --- include/ui/pixman-minimal.h | 195 include/ui/qemu-pixman.h| 2 + 2 files changed, 197 insertions(+) create mode 100644 include/ui/pixman-minimal.h diff --git a/include/ui/pixman-minimal.h b/include/ui/pixman-minimal.h new file mode 100644 index 00..efcf570c9e --- /dev/null +++ b/include/ui/pixman-minimal.h @@ -0,0 +1,195 @@ +/* + * SPDX-License-Identifier: MIT + * + * Tiny subset of PIXMAN API commonly used by QEMU. + * + * Copyright 1987, 1988, 1989, 1998 The Open Group + * Copyright 1987, 1988, 1989 Digital Equipment Corporation + * Copyright 1999, 2004, 2008 Keith Packard + * Copyright 2000 SuSE, Inc. + * Copyright 2000 Keith Packard, member of The XFree86 Project, Inc. + * Copyright 2004, 2005, 2007, 2008, 2009, 2010 Red Hat, Inc. + * Copyright 2004 Nicholas Miell + * Copyright 2005 Lars Knoll & Zack Rusin, Trolltech + * Copyright 2005 Trolltech AS + * Copyright 2007 Luca Barbato + * Copyright 2008 Aaron Plattner, NVIDIA Corporation + * Copyright 2008 Rodrigo Kumpera + * Copyright 2008 André Tupinambá + * Copyright 2008 Mozilla Corporation + * Copyright 2008 Frederic Plourde + * Copyright 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright 2009, 2010 Nokia Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef PIXMAN_MINIMAL_H +#define PIXMAN_MINIMAL_H + +#define PIXMAN_TYPE_OTHER 0 +#define PIXMAN_TYPE_ARGB2 +#define PIXMAN_TYPE_ABGR3 +#define PIXMAN_TYPE_BGRA8 +#define PIXMAN_TYPE_RGBA9 + +#define PIXMAN_FORMAT(bpp, type, a, r, g, b) (((bpp) << 24) | \ + ((type) << 16) | \ + ((a) << 12) | \ + ((r) << 8) | \ + ((g) << 4) | \ + ((b))) + +#define PIXMAN_FORMAT_RESHIFT(val, ofs, num)\ +(((val >> (ofs)) & ((1 << (num)) - 1)) << ((val >> 22) & 3)) + +#define PIXMAN_FORMAT_BPP(f)PIXMAN_FORMAT_RESHIFT(f, 24, 8) +#define PIXMAN_FORMAT_TYPE(f) (((f) >> 16) & 0x3f) +#define PIXMAN_FORMAT_A(f) PIXMAN_FORMAT_RESHIFT(f, 12, 4) +#define PIXMAN_FORMAT_R(f) PIXMAN_FORMAT_RESHIFT(f, 8, 4) +#define PIXMAN_FORMAT_G(f) PIXMAN_FORMAT_RESHIFT(f, 4, 4) +#define PIXMAN_FORMAT_B(f) PIXMAN_FORMAT_RESHIFT(f, 0, 4) +#define PIXMAN_FORMAT_DEPTH(f) (PIXMAN_FORMAT_A(f) + \ + PIXMAN_FORMAT_R(f) + \ + PIXMAN_FORMAT_G(f) + \ + PIXMAN_FORMAT_B(f)) + +typedef enum { +/* 32bpp formats */ +PIXMAN_a8r8g8b8 =PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 8, 8, 8, 8), +PIXMAN_x8r8g8b8 =PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8), +PIXMAN_a8b8g8r8 =PIXMAN_FORMAT(32, PIXMAN_TYPE_ABGR, 8, 8, 8, 8), +PIXMAN_x8b8g8r8 =PIXMAN_FORMAT(32, PIXMAN_TYPE_ABGR, 0, 8, 8, 8), +PIXMAN_b8g8r8a8 =PIXMAN_FORMAT(32, PIXMAN_TYPE_BGRA, 8, 8, 8, 8), +PIXMAN_b8g8r8x8 =PIXMAN_FORMAT(32, PIXMAN_TYPE_BGRA, 0, 8, 8, 8), +PIXMAN_r8g8b8a8 =PIXMAN_FORMAT(32, PIXMAN_TYPE_RGBA, 8, 8, 8, 8), +PIXMAN_r8g8b8x8 =PIXMAN_FORMAT(32, PIXMAN_TYPE_RGBA, 0, 8, 8, 8), +/* 24bpp formats */ +PIXMAN_r8g8b8 = PIXMAN_FORMAT(24, PIXMAN_TYPE_ARGB, 0, 8, 8, 8), +PIXMAN_b8g8r8 = PIXMAN_FORMAT(24, PIXMAN_TYPE_ABGR, 0, 8, 8, 8), +/* 16bpp formats */ +PIXMAN_r5g6b5 = PIXMAN_FORMAT(16, PIXMAN_TYPE_ARGB, 0, 5, 6, 5), +PIXMAN_a1r5g5b5 =
[PATCH v8 00/24] Make Pixman an optional dependency
From: Marc-André Lureau Hi, QEMU system emulators can be made to compile and work without Pixman. Only a few devices and options actually require it (VNC, Gtk, Spice for ex) and will have to be compiled out. However, most of QEMU graphics-related code is based on pixman_image_t and format. If we want to provide mostly compatible QEMU machines with or without Pixman, all we need to do is to have a small compatibility header with just the bare minimum for those types (see "ui: add pixman-compat.h"). There are a limited number of operations related to geometry that are slightly better implemented in QEMU (without Pixman, see "virtio-gpu: replace PIXMAN for region/rect test"). Without this simple compatibility header approach, QEMU at runtime becomes a very different emulator (without graphics device/board, display etc) and full of "if PIXMAN" conditions in the code. This is a much worse outcome imho, compared to this small header maintainance and compatibility story. Fixes: https://gitlab.com/qemu-project/qemu/-/issues/1172 v8: - rebased - replace "hw/display: make ATI_VGA depend on PIXMAN" with "hw/display/ati: allow compiling without PIXMAN" - add some r-b v7: - make FULOONG depend on VT82C686 - various r-b/a-b v6: - add "build-sys: drop needless warning pragmas for old pixman" - rename pixman-compat.h -> pixman-minimal.h - add "vl: drop needless -spice checks" - add "qemu-options: define -vnc only #ifdef CONFIG_VNC" - add "vl: simplify display_remote logic" - in "vl: move display early init before default devices", rename the introduced function qemu_setup_display() - adapt "hw/sm501: allow compiling without PIXMAN" following Zoltan review, using warn_report(), droping Error argument - various r-b/a-b v5: - fixed "vl: move display early init before default devices" patch v4: - added "vl: move display early init before default devices" patch - code style fixes - a-b from Zoltan v3: - improve transient meson condition in first patch (Paolo) - use muxed console as fallback by default (Paolo) - make pixman-compat.h closer to original API - keep "x-pixman" property for sm501 (Zoltan) Marc-André Lureau (24): build-sys: add a "pixman" feature build-sys: drop needless warning pragmas for old pixman ui: compile out some qemu-pixman functions when !PIXMAN ui: add pixman-minimal.h vl: drop needless -spice checks qemu-options: define -vnc only #ifdef CONFIG_VNC vl: simplify display_remote logic vl: move display early init before default devices ui/console: allow to override the default VC ui/vc: console-vc requires PIXMAN qmp/hmp: disable screendump if PIXMAN is missing virtio-gpu: replace PIXMAN for region/rect test ui/console: when PIXMAN is unavailable, don't draw placeholder msg vhost-user-gpu: skip VHOST_USER_GPU_UPDATE when !PIXMAN ui/gl: opengl doesn't require PIXMAN ui/vnc: VNC requires PIXMAN ui/spice: SPICE/QXL requires PIXMAN ui/gtk: -display gtk requires PIXMAN ui/dbus: do not require PIXMAN arm/kconfig: XLNX_ZYNQMP_ARM depends on PIXMAN hw/sm501: allow compiling without PIXMAN hw/mips: FULOONG depends on VT82C686 hw/display/ati: allow compiling without PIXMAN build-sys: make pixman actually optional meson.build | 25 - qapi/ui.json | 3 +- include/ui/console.h | 2 + include/ui/pixman-minimal.h | 195 ++ include/ui/qemu-pixman.h | 15 +-- include/ui/rect.h | 59 ++ hw/display/ati.c | 16 ++- hw/display/ati_2d.c | 11 +- hw/display/sm501.c| 46 +--- hw/display/vhost-user-gpu.c | 2 + hw/display/virtio-gpu.c | 30 ++ system/vl.c | 84 --- ui/console-vc-stubs.c | 33 ++ ui/console.c | 19 ui/dbus-listener.c| 90 +++- ui/qemu-pixman.c | 6 ++ ui/ui-hmp-cmds.c | 2 + ui/ui-qmp-cmds.c | 2 + ui/vnc-stubs.c| 12 --- Kconfig.host | 3 + hmp-commands.hx | 2 + hw/arm/Kconfig| 3 +- hw/display/Kconfig| 7 +- hw/display/meson.build| 4 +- hw/mips/Kconfig | 1 + meson_options.txt | 2 + qemu-options.hx | 2 + scripts/meson-buildoptions.sh | 3 + ui/meson.build| 22 ++-- 29 files changed, 560 insertions(+), 141 deletions(-) create mode 100644 include/ui/pixman-minimal.h create mode 100644 include/ui/rect.h create mode 100644 ui/console-vc-stubs.c -- 2.41.0
[PATCH v8 06/24] qemu-options: define -vnc only #ifdef CONFIG_VNC
From: Marc-André Lureau Signed-off-by: Marc-André Lureau Reviewed-by: Thomas Huth --- system/vl.c | 13 + ui/vnc-stubs.c | 12 qemu-options.hx | 2 ++ 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/system/vl.c b/system/vl.c index fb0389e4d0..19aef762e4 100644 --- a/system/vl.c +++ b/system/vl.c @@ -1095,13 +1095,14 @@ DisplayOptions *qmp_query_display_options(Error **errp) static void parse_display(const char *p) { -const char *opts; - if (is_help_option(p)) { qemu_display_help(); exit(0); } +#ifdef CONFIG_VNC +const char *opts; + if (strstart(p, "vnc", &opts)) { /* * vnc isn't a (local) DisplayType but a protocol for remote @@ -1113,9 +1114,11 @@ static void parse_display(const char *p) error_report("VNC requires a display argument vnc="); exit(1); } -} else { -parse_display_qapi(p); +return; } +#endif + +parse_display_qapi(p); } static inline bool nonempty_str(const char *str) @@ -3344,9 +3347,11 @@ void qemu_init(int argc, char **argv) machine_parse_property_opt(qemu_find_opts("smp-opts"), "smp", optarg); break; +#ifdef CONFIG_VNC case QEMU_OPTION_vnc: vnc_parse(optarg); break; +#endif case QEMU_OPTION_no_acpi: warn_report("-no-acpi is deprecated, use '-machine acpi=off' instead"); qdict_put_str(machine_opts_dict, "acpi", "off"); diff --git a/ui/vnc-stubs.c b/ui/vnc-stubs.c index b4eb3ce718..a96bc86236 100644 --- a/ui/vnc-stubs.c +++ b/ui/vnc-stubs.c @@ -10,15 +10,3 @@ int vnc_display_pw_expire(const char *id, time_t expires) { return -ENODEV; }; -void vnc_parse(const char *str) -{ -if (strcmp(str, "none") == 0) { -return; -} -error_setg(&error_fatal, "VNC support is disabled"); -} -int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp) -{ -error_setg(errp, "VNC support is disabled"); -return -1; -} diff --git a/qemu-options.hx b/qemu-options.hx index 7809036d8c..5b6d16ed58 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2428,8 +2428,10 @@ SRST OBP. ERST +#ifdef CONFIG_VNC DEF("vnc", HAS_ARG, QEMU_OPTION_vnc , "-vnc shorthand for -display vnc=\n", QEMU_ARCH_ALL) +#endif SRST ``-vnc display[,option[,option[,...]]]`` Normally, if QEMU is compiled with graphical window support, it -- 2.41.0
[PATCH v8 02/24] build-sys: drop needless warning pragmas for old pixman
From: Marc-André Lureau Since commit 236f282c1c7 ("configure: check for pixman-1 version"), QEMU requires >= 0.21.8. Suggested-by: Thomas Huth Signed-off-by: Marc-André Lureau Reviewed-by: Thomas Huth --- include/ui/qemu-pixman.h | 4 1 file changed, 4 deletions(-) diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h index d37feb5e3c..4bfa8fae0c 100644 --- a/include/ui/qemu-pixman.h +++ b/include/ui/qemu-pixman.h @@ -7,11 +7,7 @@ #define QEMU_PIXMAN_H #ifdef CONFIG_PIXMAN -/* pixman-0.16.0 headers have a redundant declaration */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wredundant-decls" #include -#pragma GCC diagnostic pop #endif /* -- 2.41.0
Re: [PATCH v6 1/6] virtio: split into vhost-user-base and vhost-user-device
On Mon, Nov 06, 2023 at 07:15:10PM +, Alex Bennée wrote: > Lets keep a cleaner split between the base class and the derived > vhost-user-device which we can use for generic vhost-user stubs. This > includes an update to introduce the vq_size property so the number of > entries in a virtq can be defined. > > Signed-off-by: Alex Bennée > Message-Id: <20231009095937.195728-2-alex.ben...@linaro.org> > > --- > v5 > - s/parent/parent_obj/ > - remove left over vhost-user-device.h > - use DEFINE_TYPES > v6 > - rebase and set .abstrace = true for vhost-user-device abstract :) ... > +static const TypeInfo vub_types[] = { > +{ > +.name = TYPE_VHOST_USER_BASE, > +.parent = TYPE_VIRTIO_DEVICE, > +.instance_size = sizeof(VHostUserBase), > +.class_init = vub_class_init, > +.class_size = sizeof(VHostUserBaseClass), > +.abstract = true I suspect it's this change that breaks CI: https://gitlab.com/mstredhat/qemu/-/jobs/5472898562 WARNING: qemu received signal 6; command: "./qemu-system-ppc -display none -vga none -chardev socket,id=mon,fd=3 -mon chardev=mon,mode=control -S -machine g3beige,accel=tcg -device vhost-user-device-pci" CRITICAL: failed: binary=./qemu-system-ppc accel=tcg machine=g3beige device=vhost-user-device-pci CRITICAL: cmdline: ./qemu-system-ppc -S -machine g3beige,accel=tcg -device vhost-user-device-pci CRITICAL: log: ** CRITICAL: log: ERROR:../qom/object.c:524:object_initialize_with_type: assertion failed: (type->abstract == false) CRITICAL: log: Bail out! ERROR:../qom/object.c:524:object_initialize_with_type: assertion failed: (type->abstract == false) CRITICAL: exit code: -6 146/395 qemu:qtest+qtest-mips / qtest-mips/device-introspect-test ERROR 1.27s killed by signal 6 SIGABRT 153/395 qemu:qtest+qtest-xtensa / qtest-xtensa/device-introspect-test ERROR 1.56s killed by signal 6 SIGABRT 171/395 qemu:qtest+qtest-riscv32 / qtest-riscv32/device-introspect-test ERROR 1.40s killed by signal 6 SIGABRT 184/395 qemu:qtest+qtest-ppc / qtest-ppc/device-introspect-test ERROR 1.51s killed by signal 6 SIGABRT 195/395 qemu:qtest+qtest-sparc64 / qtest-sparc64/device-introspect-test ERROR 1.35s killed by signal 6 SIGABRT I dropped this .abstract = true line for now and the part about it in docs. Pls send patch on top once pull is merged. -- MST
Re: [PATCH 24/29] plugins: add an API to read registers
On 2023/11/06 20:40, Alex Bennée wrote: Akihiko Odaki writes: (re-adding qemu-devel which my mail client dropped a few messages ago, sorry) On 2023/11/06 19:46, Alex Bennée wrote: Akihiko Odaki writes: On 2023/11/06 18:30, Alex Bennée wrote: Akihiko Odaki writes: On 2023/11/04 4:59, Alex Bennée wrote: We can only request a list of registers once the vCPU has been initialised so the user needs to use either call the find function on vCPU initialisation or during the translation phase. We don't expose the reg number to the plugin instead hiding it behind an opaque handle. This allows for a bit of future proofing should the internals need to be changed while also being hashed against the CPUClass so we can handle different register sets per-vCPU in hetrogenous situations. Having an internal state within the plugins also allows us to expand the interface in future (for example providing callbacks on register change if the translator can track changes). Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1706 Cc: Akihiko Odaki Based-on: <20231025093128.33116-18-akihiko.od...@daynix.com> Signed-off-by: Alex Bennée +struct qemu_plugin_register; + +/** + * typedef qemu_plugin_reg_descriptor - register descriptions + * + * @name: register name + * @handle: opaque handle for retrieving value with qemu_plugin_read_register + * @feature: optional feature descriptor, can be NULL + */ +typedef struct { +char name[32]; +struct qemu_plugin_register *handle; +const char *feature; +} qemu_plugin_reg_descriptor; + +/** + * qemu_plugin_find_registers() - return register list + * @vcpu_index: vcpu to query + * @reg_pattern: register name pattern + * + * Returns a GArray of qemu_plugin_reg_descriptor or NULL. Caller + * frees. As the register set of a given vCPU is only available once + * the vCPU is initialised if you want to monitor registers from the + * start you should call this from a qemu_plugin_register_vcpu_init_cb() + * callback. + */ +GArray * qemu_plugin_find_registers(unsigned int vcpu_index, const char *reg_pattern); A pattern may be convenient for humans but not for machine. My motivation to introduce the feature is to generate traces consumable by trace-based simulators. Such a plugin needs an exact match of registers. That's true - but we don't have any such users in the code base. However for exact matches the details are in qemu_plugin_reg_descriptor so you can always filter there if you want. I designed the feature to read registers for users outside of the code base so the code base has no practical user. I added the feature to log register values to execlog but it's only for demonstration and it is useless for practical use; I wouldn't say its useless - and it is important to have in-tree code to exercise the various parts of the API we expose. I mean it is useless except for demonstration. Having some code for demonstration is good but we shouldn't overfit the API to it. To be clear is your objection just to the way qemu_plugin_find_registers() works or the whole concept of using a handle instead of the register number? I'm certainly open to better ways of doing the former but as explained in the commit I think the handle based approach is a more hygienic interface that gives us scope to improve it going forward. Yes, my major concern is that the pattern matching. OK. Another potential consumer I thought about during implementing the internal API was HMP which would also benefit from a more human wildcard type search. So I think the resolution of this is having two APIs, one returning a list of qemu_plugin_reg_descriptor and one returning a single descriptor only with an exact match. I don't think qemu_plugin_find_registers() is so versetile that it should be a public API. What is appropriate as a user interface depends more on the context. For HMP, it may be better to implement command completion instead of having a wildcard. Some may want regular expressions instead of GLib patterns. Some may want POSIX-compliant glob instead of GLib-specific pattern match (the quirks of GLib pattern is documented at https://gitlab.gnome.org/GNOME/glib/-/blob/2.78.1/glib/gpattern.c#L33). I think it's better to expose an array of register names and let the plugin do the pattern match in a way appropriate for the specific use case. I thought exposing features and registers in two calls was a bit clunky though so how about: struct qemu_plugin_reg_descriptor * qemu_plugin_find_register(unsigned int vcpu_index, const char *name, const char *gdb_feature); which will only reply on an exact match (although I still think register names are unique enough you can get away without gdb_feature). I'm fine with the use of a pointer instead of the register number. A pointer is indeed more random for each run so it will prevent the user from hardcoding it. As we are so close to soft-freeze I sugges
Re: [PATCH] dump:Add close fd on error return to avoid resource leak
On Tue, Nov 7, 2023 at 10:07 AM Zongmin Zhou wrote: > > Signed-off-by: Zongmin Zhou Reviewed-by: Marc-André Lureau > --- > dump/dump.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/dump/dump.c b/dump/dump.c > index 1c304cadfd..ad5294e853 100644 > --- a/dump/dump.c > +++ b/dump/dump.c > @@ -2160,6 +2160,7 @@ void qmp_dump_guest_memory(bool paging, const char > *protocol, > return; > } > if (kdump_raw && lseek(fd, 0, SEEK_CUR) == (off_t) -1) { > +close(fd); > error_setg(errp, "kdump-raw formats require a seekable file"); > return; > } > -- > 2.34.1 > > -- Marc-André Lureau
Re: [PATCH v13 00/11] Add VIRTIO sound card
On Tue, 7 Nov 2023 at 02:44, Michael S. Tsirkin wrote: > > On Mon, Oct 23, 2023 at 03:03:17PM +0300, Manos Pitsidianakis wrote: > > This patch series adds an audio device implementing the recent virtio > > sound spec (1.2) and a corresponding PCI wrapper device. > > > Pls send patches on top to fix checkpatch warnings. > > https://gitlab.com/mstredhat/qemu/-/jobs/5470533893 Do you mean this one? 6583087d531f2e37a2e2ba2cef7d123e21f8b0ad:214: ERROR: spaces required around that ':' (ctx:VxE) total: 1 errors, 0 warnings, 674 lines checked If yes, it's a false warning. It's a switch statement with a macro and it confuses it with the ternary operator.
[PATCH] dump:Add close fd on error return to avoid resource leak
Signed-off-by: Zongmin Zhou --- dump/dump.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dump/dump.c b/dump/dump.c index 1c304cadfd..ad5294e853 100644 --- a/dump/dump.c +++ b/dump/dump.c @@ -2160,6 +2160,7 @@ void qmp_dump_guest_memory(bool paging, const char *protocol, return; } if (kdump_raw && lseek(fd, 0, SEEK_CUR) == (off_t) -1) { +close(fd); error_setg(errp, "kdump-raw formats require a seekable file"); return; } -- 2.34.1
[PATCH] Implementation of SJA1000 CAN-bus devices that support MSI (PCI capability 0x05). - Implementation of multiple MSI vector support for SJA1000 devices. - Added can_pcm26d2ca_pci.c; support for
Signed-off-by: Deniz Eren --- hw/net/can/can_pcm26d2ca_pci.c | 281 + hw/net/can/can_sja1000.c | 91 +++ hw/net/can/can_sja1000.h | 12 ++ hw/net/can/meson.build | 1 + 4 files changed, 385 insertions(+) create mode 100644 hw/net/can/can_pcm26d2ca_pci.c diff --git a/hw/net/can/can_pcm26d2ca_pci.c b/hw/net/can/can_pcm26d2ca_pci.c new file mode 100644 index 00..af1dd4c7bb --- /dev/null +++ b/hw/net/can/can_pcm26d2ca_pci.c @@ -0,0 +1,281 @@ +/* + * PCM-26D2CA PCIe CAN device (SJA1000 based) emulation + * + * Advantech iDoor Module: 2-Ports Isolated CANBus mPCIe, DB9 + * + * Copyright (c) 2023 Deniz Eren (deniz.e...@icloud.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/units.h" +#include "qemu/osdep.h" +#include "qemu/event_notifier.h" +#include "qemu/module.h" +#include "qemu/thread.h" +#include "qemu/sockets.h" +#include "qapi/error.h" +#include "chardev/char.h" +#include "hw/irq.h" +#include "hw/pci/pci_device.h" +#include "hw/qdev-properties.h" +#include "hw/pci/msi.h" +#include "migration/vmstate.h" +#include "net/can_emu.h" + +#include "can_sja1000.h" +#include "qom/object.h" + +#define TYPE_CAN_PCI_DEV "pcm26d2ca_pci" + +typedef struct Pcm26D2CAPCIeState Pcm26D2CAPCIeState; +DECLARE_INSTANCE_CHECKER(Pcm26D2CAPCIeState, PCM26D2CA_PCI_DEV, + TYPE_CAN_PCI_DEV) + +/* the PCI device and vendor IDs */ +#ifndef PCM26D2CA_PCI_VENDOR_ID1 +#define PCM26D2CA_PCI_VENDOR_ID10x13fe +#endif + +#ifndef PCM26D2CA_PCI_DEVICE_ID1 +#define PCM26D2CA_PCI_DEVICE_ID10x00d7 +#endif + +#define PCM26D2CA_PCI_SJA_COUNT 2 +#define PCM26D2CA_PCI_SJA_RANGE 0x400 + +#define PCM26D2CA_PCI_BYTES_PER_SJA 0x80 + +#define PCM26D2CA_IO_IDX0 + +#define PCM26D2CA_MSI_VEC_NUM (8) +#define PCM26D2CA_MSI_RI_ENTRY (0) /* Receive interrupt */ +#define PCM26D2CA_MSI_TI_ENTRY (1) /* Transmit interrupt */ +#define PCM26D2CA_MSI_EI_ENTRY (2) /* Error warning interrupt */ +#define PCM26D2CA_MSI_DOI_ENTRY (3) /* Data overrun interrupt */ +#define PCM26D2CA_MSI_WUI_ENTRY (4) /* Wakeup interrupt */ +#define PCM26D2CA_MSI_EPI_ENTRY (5) /* Error passive */ +#define PCM26D2CA_MSI_ALI_ENTRY (6) /* Arbitration lost */ +#define PCM26D2CA_MSI_BEI_ENTRY (7) /* Bus error interrupt */ + +struct Pcm26D2CAPCIeState { +/*< private >*/ +PCIDevice dev; +/*< public >*/ +MemoryRegionio; + +CanSJA1000State sja_state[PCM26D2CA_PCI_SJA_COUNT]; +qemu_irqirq; + +char*model; /* The model that support, only SJA1000 now. */ +CanBusState *canbus[PCM26D2CA_PCI_SJA_COUNT]; +}; + +static void pcm26d2ca_pci_reset(DeviceState *dev) +{ +Pcm26D2CAPCIeState *d = PCM26D2CA_PCI_DEV(dev); +int i; + +for (i = 0 ; i < PCM26D2CA_PCI_SJA_COUNT; i++) { +can_sja_hardware_reset(&d->sja_state[i]); +} +} + +static uint64_t pcm26d2ca_pci_io_read(void *opaque, hwaddr addr, unsigned size) +{ +Pcm26D2CAPCIeState *d = opaque; +CanSJA1000State *s = &d->sja_state[0]; +hwaddr _addr = addr; + +if (addr >= PCM26D2CA_PCI_SJA_RANGE) { +s = &d->sja_state[1]; +_addr -= PCM26D2CA_PCI_SJA_RANGE; +} + +if (_addr >= PCM26D2CA_PCI_BYTES_PER_SJA) { +return 0; +} + +return can_sja_mem_read(s, _addr >> 2, size); +} + +static void pcm26d2ca_pci_io_write(void *opaque, hwaddr addr, uint64_t data, + unsigned size) +{ +Pcm26D2CAPCIeState *d = opaque; +CanSJA1000State *s = &d->sja_state[0]; +hwaddr _addr = addr; + +if (addr >= PCM26D2CA_PCI_SJA_RANGE) { +s = &d->sja_state[1]; +_addr -= PCM26D2CA_PCI_SJA_RANGE; +} + +if (_addr >= PCM26D2CA_PCI_BYTES_PER_SJA) { +return; +} + +can_sja_mem_write(s, _addr >> 2, data, size); +} + +static const MemoryRegionOps pcm26d2ca_pci_io_ops =
[PATCH] Fix Windows 2000 and XP HDAudio Support
Change the ID to be a Realtek ALC885 so that both Windows 2000 and up (including XP) and macOS (on a later patch for HDEF ACPI Fixes) support HDA HDA is supported for ALC885 on macOS AppleHDA.kext and 2K people can use the following file to get sound working (MD5sum): 959c6ad895ee22d0003fe24b6ce1b150 WDM_R269.exe for Vista+, the following can be used for EQ or if the native one doesn't work OOTB (MD5sum): fb0aaffcfc620b70b7f3c3b1381d08e5 Vista_Win7_Win8_R270.exe A Note for the Vista+ Driver: You need to go to playback settings, under the Speaker, Advanced, change the Hz to one that is valid, so sound actually plays, though you may need to enable under the Enhancements tab, check Disable All then change the Hz, and uncheck Disable All Under Enhancements, applying after each of the tasks, due to a bug in the stock Realtek Driver, also note, newer drivers don't work at all, even on real machines, this is the latest confirmed to work at the moment! Signed-off-by: Christopher Lentocha --- hw/audio/hda-codec-common.h | 66 + hw/audio/hda-codec.c | 8 +++-- 2 files changed, 36 insertions(+), 38 deletions(-) diff --git a/hw/audio/hda-codec-common.h b/hw/audio/hda-codec-common.h index b4fdb51e8b..ef57a1b98d 100644 --- a/hw/audio/hda-codec-common.h +++ b/hw/audio/hda-codec-common.h @@ -24,19 +24,15 @@ * HDA codec descriptions */ +#define QEMU_HDA_ID 0x10EC0885 + #ifdef HDA_MIXER -#define QEMU_HDA_ID_OUTPUT ((QEMU_HDA_ID_VENDOR << 16) | 0x12) -#define QEMU_HDA_ID_DUPLEX ((QEMU_HDA_ID_VENDOR << 16) | 0x22) -#define QEMU_HDA_ID_MICRO ((QEMU_HDA_ID_VENDOR << 16) | 0x32) #define QEMU_HDA_AMP_CAPS \ (AC_AMPCAP_MUTE | \ (QEMU_HDA_AMP_STEPS << AC_AMPCAP_OFFSET_SHIFT) | \ (QEMU_HDA_AMP_STEPS << AC_AMPCAP_NUM_STEPS_SHIFT) | \ (3 << AC_AMPCAP_STEP_SIZE_SHIFT)) #else -#define QEMU_HDA_ID_OUTPUT ((QEMU_HDA_ID_VENDOR << 16) | 0x11) -#define QEMU_HDA_ID_DUPLEX ((QEMU_HDA_ID_VENDOR << 16) | 0x21) -#define QEMU_HDA_ID_MICRO ((QEMU_HDA_ID_VENDOR << 16) | 0x31) #define QEMU_HDA_AMP_CAPS QEMU_HDA_AMP_NONE #endif @@ -137,10 +133,10 @@ static const desc_param glue(common_params_audio_linein_, PARAM)[] = { static const desc_param glue(output_params_root_, PARAM)[] = { { .id = AC_PAR_VENDOR_ID, - .val = QEMU_HDA_ID_OUTPUT, + .val = QEMU_HDA_ID, },{ .id = AC_PAR_SUBSYSTEM_ID, - .val = QEMU_HDA_ID_OUTPUT, + .val = QEMU_HDA_ID, },{ .id = AC_PAR_REV_ID, .val = 0x00100101, @@ -157,7 +153,7 @@ static const desc_param glue(output_params_audio_func_, PARAM)[] = { .val = AC_GRP_AUDIO_FUNCTION, },{ .id = AC_PAR_SUBSYSTEM_ID, - .val = QEMU_HDA_ID_OUTPUT, + .val = QEMU_HDA_ID, },{ .id = AC_PAR_NODE_COUNT, .val = 0x00020002, @@ -208,9 +204,9 @@ static const desc_node glue(output_nodes_, PARAM)[] = { .name = "out", .params = glue(common_params_audio_lineout_, PARAM), .nparams = ARRAY_SIZE(glue(common_params_audio_lineout_, PARAM)), - .config = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) | - (AC_JACK_LINE_OUT << AC_DEFCFG_DEVICE_SHIFT) | - (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) | + .config = ((AC_JACK_PORT_FIXED << AC_DEFCFG_PORT_CONN_SHIFT) | + (AC_JACK_SPEAKER << AC_DEFCFG_DEVICE_SHIFT) | + (AC_JACK_CONN_1_8 << AC_DEFCFG_CONN_TYPE_SHIFT) | (AC_JACK_COLOR_GREEN << AC_DEFCFG_COLOR_SHIFT) | 0x10), .pinctl = AC_PINCTL_OUT_EN, @@ -221,7 +217,7 @@ static const desc_node glue(output_nodes_, PARAM)[] = { /* output: codec */ static const desc_codec glue(output_, PARAM) = { .name = "output", - .iid = QEMU_HDA_ID_OUTPUT, + .iid = QEMU_HDA_ID, .nodes = glue(output_nodes_, PARAM), .nnodes = ARRAY_SIZE(glue(output_nodes_, PARAM)), }; @@ -230,10 +226,10 @@ static const desc_codec glue(output_, PARAM) = { static const desc_param glue(duplex_params_root_, PARAM)[] = { { .id = AC_PAR_VENDOR_ID, - .val = QEMU_HDA_ID_DUPLEX, + .val = QEMU_HDA_ID, },{ .id = AC_PAR_SUBSYSTEM_ID, - .val = QEMU_HDA_ID_DUPLEX, + .val = QEMU_HDA_ID, },{ .id = AC_PAR_REV_ID, .val = 0x00100101, @@ -250,7 +246,7 @@ static const desc_param glue(duplex_params_audio_func_, PARAM)[] = { .val = AC_GRP_AUDIO_FUNCTION, },{ .id = AC_PAR_SUBSYSTEM_ID, - .val = QEMU_HDA_ID_DUPLEX, + .val = QEMU_HDA_ID, },{ .id = AC_PAR_NODE_COUNT, .val = 0x00020004, @@ -301,9 +297,9 @@ static const desc_node glue(duplex_nodes_, PARAM)[] = { .name = "out", .params = glue(common_params_audio_lineout_, PARAM), .nparams = ARRAY_SIZE(glue(common_params_audio_lineout_, PARAM)), - .config = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) | - (AC_JACK_LINE_OUT << AC_DEFCFG_DEVICE_SHIFT) | - (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) | + .config = ((AC_JACK_PORT_FIXED << AC_DEFCFG_PORT_CONN_SHIFT) | + (AC_JACK_SPEAKER << AC_DEFCFG_DEVICE_SHIFT) | + (AC_JACK_CONN_1_8 << AC_DEFCFG_CONN_TYPE_SHIFT) | (AC_JACK_COLOR_GREEN << AC_DEFCFG_COLOR_SHIFT) | 0x10), .pinctl = AC_PINCTL_OUT_EN, @@ -320,10 +316,10 @@ static const desc_node glue(duplex_nodes_, PARAM)[] = { .name = "in", .params = glue(common_params_audio_linein_, PARAM), .nparams = ARRAY_SIZE
Re: [PATCH 00/35] tcg patch queue
Applied, thanks. Please update the changelog at https://wiki.qemu.org/ChangeLog/8.2 for any user-visible changes. signature.asc Description: PGP signature
Re: [PULL 00/49] riscv-to-apply queue
Applied, thanks. Please update the changelog at https://wiki.qemu.org/ChangeLog/8.2 for any user-visible changes. signature.asc Description: PGP signature
[PATCH v2] tests/acpi/bios-tables-test: do not write new blobs unless there are changes
When dumping table blobs using rebuild-expected-aml.sh, table blobs from all test variants are dumped regardless of whether there are any actual changes to the tables or not. This creates lot of new files for various test variants that are not part of the git repository. This is because we do not check in all table blobs for all test variants into the repository. Only those blobs for those variants that are different from the generic test-variant agnostic blob are checked in. This change makes the test smarter by checking if at all there are any changes in the tables from the checked-in gold master blobs and take actions accordingly. When there are no changes: - No new table blobs would be written. - Existing table blobs will be refreshed (git diff will show no changes). When there are changes: - New table blob files will be dumped. - Existing table blobs will be refreshed (git diff will show that the files changed, asl diff will show the actual changes). When new tables are introduced: - Zero byte empty file blobs for new tables as instructed in the header of bios-tables-test.c will be regenerated to actual table blobs. This would make analyzing changes to tables less confusing and there would be no need to clean useless untracked files when there are no table changes. CC: peter.mayd...@linaro.org Signed-off-by: Ani Sinha --- tests/qtest/bios-tables-test.c | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) changelog: v2: commit description updated to make things a little clearer. No actual changes. diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c index 9f4bc15aab..743b509e93 100644 --- a/tests/qtest/bios-tables-test.c +++ b/tests/qtest/bios-tables-test.c @@ -109,6 +109,7 @@ static const char *iasl; #endif static int verbosity_level; +static GArray *load_expected_aml(test_data *data); static bool compare_signature(const AcpiSdtTable *sdt, const char *signature) { @@ -241,21 +242,32 @@ static void test_acpi_fadt_table(test_data *data) static void dump_aml_files(test_data *data, bool rebuild) { -AcpiSdtTable *sdt; +AcpiSdtTable *sdt, *exp_sdt; GError *error = NULL; gchar *aml_file = NULL; +test_data exp_data = {}; gint fd; ssize_t ret; int i; +exp_data.tables = load_expected_aml(data); for (i = 0; i < data->tables->len; ++i) { const char *ext = data->variant ? data->variant : ""; sdt = &g_array_index(data->tables, AcpiSdtTable, i); +exp_sdt = &g_array_index(exp_data.tables, AcpiSdtTable, i); g_assert(sdt->aml); +g_assert(exp_sdt->aml); if (rebuild) { aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine, sdt->aml, ext); +if (!g_file_test(aml_file, G_FILE_TEST_EXISTS) && +sdt->aml_len == exp_sdt->aml_len && +!memcmp(sdt->aml, exp_sdt->aml, sdt->aml_len)) { +/* identical tables, no need to write new files */ +g_free(aml_file); +continue; +} fd = g_open(aml_file, O_WRONLY|O_TRUNC|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); if (fd < 0) { -- 2.42.0
Re: [PULL 81/94] target/sparc: Move FDMULQ to decodetree
On 11/6/23 14:02, Mark Cave-Ayland wrote: I was working through my SPARC boot tests for your latest target/sparc series when I spotted a segfault on my FreeBSD SPARC64 image. A git bisect indicated that this was the patch that originally introduced the error, something I must have missed when testing the original decodetree conversion series. The reproducer is: ./qemu-system-sparc64 -m 256 -cdrom FreeBSD-10.3-RELEASE-sparc64-bootonly.iso \ -boot d -nographic and the error is a segfault in devd: ... ... Trying to mount root from cd9660:/dev/iso9660/10_3_RELEASE_SPARC64_BO [ro]... Entropy harvesting: interrupts ethernet point_to_point swi. Starting file system checks: Mounting local file systems:. Writing entropy file:. /etc/rc: WARNING: $hostname is not set -- see rc.conf(5). Starting Network: lo0 hme0. lo0: flags=8049 metric 0 mtu 16384 options=63 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 inet 127.0.0.1 netmask 0xff00 nd6 options=21 hme0: flags=8802 metric 0 mtu 1500 options=8000b ether 52:54:00:12:34:56 nd6 options=29 media: Ethernet autoselect Starting devd. pid 246 (ps), uid 0: exited on signal 11 Segmentation fault ^^ I certainly can't imagine that FdMULq is really at fault, because it's not implemented on real hardware (and thus I really doubt FreeBSD attempted to use it), and CPU_FEATURE_FLOAT128 is not enabled by your command-line. The only thing that I can imagine is that this is some sort of timing related issue and bisect behaved randomly. All that said, I can't replicate this with master. Can you, now? r~
Re: [PATCH 07/22] tests/avocado: update the tcg_plugins test
On 11/6/23 10:50, Alex Bennée wrote: There are a number of things that are broken on the test currently so lets fix that up: - replace retired Debian kernel for tuxrun_baseline one - remove "detected repeat instructions test" since ea185a55 - log total counted instructions/memory accesses Signed-off-by: Alex Bennée Message-Id: <20231103195956.1998255-8-alex.ben...@linaro.org> --- tests/avocado/tcg_plugins.py | 28 ++-- 1 file changed, 18 insertions(+), 10 deletions(-) Acked-by: Richard Henderson r~
Re: [PATCH 03/22] target/arm: hide the 32bit version of PAR from gdbstub
On 11/6/23 10:50, Alex Bennée wrote: This is a slightly hacky way to avoid duplicate PAR's in the system register XML we send to gdb which causes an alias. However the other alternative would be to post process ARMCPRegInfo once all registers have been defined looking for textual duplicates. And that seems like overkill. Signed-off-by: Alex Bennée Message-Id: <20231103195956.1998255-4-alex.ben...@linaro.org> --- target/arm/helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 5dc0d20a84..104f9378b4 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -3727,7 +3727,7 @@ static const ARMCPRegInfo vapa_cp_reginfo[] = { .access = PL1_RW, .resetvalue = 0, .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.par_s), offsetoflow32(CPUARMState, cp15.par_ns) }, - .writefn = par_write }, + .writefn = par_write, .type = ARM_CP_NO_GDB }, #ifndef CONFIG_USER_ONLY /* This underdecoding is safe because the reginfo is NO_RAW. */ { .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = CP_ANY, If the implementation includes LPAE, this is an alias of the full 64-bit register (the "other PAR", and so type should contain ARM_CP_ALIAS. If the implementation does not include LPAE, this should not be ARM_CP_NO_GDB because there is no 64-bit alternate. r~
Re: [PATCH v2 0/2] virtio-blk: add iothread-vq-mapping parameter
On Thu, Nov 02, 2023 at 03:10:52PM +0100, Kevin Wolf wrote: > Am 18.09.2023 um 18:16 hat Stefan Hajnoczi geschrieben: > > virtio-blk and virtio-scsi devices need a way to specify the mapping between > > IOThreads and virtqueues. At the moment all virtqueues are assigned to a > > single > > IOThread or the main loop. This single thread can be a CPU bottleneck, so > > it is > > necessary to allow finer-grained assignment to spread the load. With this > > series applied, "pidstat -t 1" shows that guests with -smp 2 or higher are > > able > > to exploit multiple IOThreads. > > > > This series introduces command-line syntax for the new iothread-vq-mapping > > property is as follows: > > > > --device > > '{"driver":"virtio-blk-pci","iothread-vq-mapping":[{"iothread":"iothread0","vqs":[0,1,2]},...]},...' > > > > IOThreads are specified by name and virtqueues are specified by 0-based > > index. > > > > It will be common to simply assign virtqueues round-robin across a set > > of IOThreads. A convenient syntax that does not require specifying > > individual virtqueue indices is available: > > > > --device > > '{"driver":"virtio-blk-pci","iothread-vq-mapping":[{"iothread":"iothread0"},{"iothread":"iothread1"},...]},...' > > > > There is no way to reassign virtqueues at runtime and I expect that to be a > > very rare requirement. > > > > Note that JSON --device syntax is required for the iothread-vq-mapping > > parameter because it's non-scalar. > > > > Based-on: 20230912231037.826804-1-stefa...@redhat.com ("[PATCH v3 0/5] > > block-backend: process I/O in the current AioContext") > > Does this strictly depend on patch 5/5 of that series, or would it just > be a missed opportunity for optimisation by unnecessarily running some > requests from a different thread? I looked at the issue with PATCH 5/5 more and didn't find a minimal solution that I can implement today for soft freeze. There are too much inconsistency between blk_remove_bs() in whether or not the AioContext is acquired: block/block-backend.c:blk_remove_bs(blk); <- blk_unref (can't tell if AioContext is acquired) block/block-backend.c:blk_remove_bs(blk); (acquired) block/monitor/block-hmp-cmds.c:blk_remove_bs(blk); (acquired) block/qapi-sysemu.c:blk_remove_bs(blk); (acquired) block/qapi-sysemu.c:blk_remove_bs(blk); (not acquired) qemu-nbd.c:blk_remove_bs(blk); (not acquired) tests/unit/test-block-iothread.c:blk_remove_bs(blk); (acquired) tests/unit/test-blockjob.c:blk_remove_bs(blk); (sometimes acquired, sometimes not) They usually get away with it because BDRV_WAIT_WHILE() only unlocks the AioContext when the BlockDriverState's AioContext is not the current thread's home context. This means main loop code works when the AioContext is not acquired as long as the BDS AioContext is the main loop AioContext. The solution I have confidence in is to stop using the AioContext lock, but it will take more time to refactor the SCSI layer (the last real user of the AioContext). I'm afraid iothread-vq-mapping can't make it into QEMU 8.2. Stefan signature.asc Description: PGP signature
Re: [PATCH 04/22] target/arm: hide all versions of DBGD[RS]AR from gdbstub
On 11/6/23 10:50, Alex Bennée wrote: This avoids two duplicates being presented to gdbstub. As the registers are RAZ anyway it is unlikely their value would be of use to someone using gdbstub anyway. Signed-off-by: Alex Bennée Message-Id: <20231103195956.1998255-5-alex.ben...@linaro.org> --- target/arm/debug_helper.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) Acked-by: Richard Henderson r~ diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c index 79a3659c0c..dc783adba5 100644 --- a/target/arm/debug_helper.c +++ b/target/arm/debug_helper.c @@ -937,14 +937,14 @@ static const ARMCPRegInfo debug_cp_reginfo[] = { */ { .name = "DBGDRAR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0, .access = PL0_R, .accessfn = access_tdra, - .type = ARM_CP_CONST, .resetvalue = 0 }, + .type = ARM_CP_CONST | ARM_CP_NO_GDB, .resetvalue = 0 }, { .name = "MDRAR_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0, .access = PL1_R, .accessfn = access_tdra, .type = ARM_CP_CONST, .resetvalue = 0 }, { .name = "DBGDSAR", .cp = 14, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0, .access = PL0_R, .accessfn = access_tdra, - .type = ARM_CP_CONST, .resetvalue = 0 }, + .type = ARM_CP_CONST | ARM_CP_NO_GDB, .resetvalue = 0 }, /* Monitor debug system control register; the 32-bit alias is DBGDSCRext. */ { .name = "MDSCR_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2, @@ -1065,9 +1065,9 @@ static const ARMCPRegInfo debug_cp_reginfo[] = { static const ARMCPRegInfo debug_lpae_cp_reginfo[] = { /* 64 bit access versions of the (dummy) debug registers */ { .name = "DBGDRAR", .cp = 14, .crm = 1, .opc1 = 0, - .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, + .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT | ARM_CP_NO_GDB, .resetvalue = 0 }, { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0, - .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, + .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT | ARM_CP_NO_GDB, .resetvalue = 0 }, }; static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
Re: [PATCH 01/22] default-configs: Add TARGET_XML_FILES definition
On 11/6/23 10:50, Alex Bennée wrote: From: Akihiko Odaki loongarch64-linux-user has references to XML files so include them. Fixes: d32688ecdb ("default-configs: Add loongarch linux-user support") Signed-off-by: Akihiko Odaki Message-Id: <20231030054834.39145-6-akihiko.od...@daynix.com> Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20231103195956.1998255-2-alex.ben...@linaro.org> [AJB: remove base32 from list] Signed-off-by: Alex Bennée --- configs/targets/loongarch64-linux-user.mak | 1 + 1 file changed, 1 insertion(+) Reviewed-by: Richard Henderson r~ diff --git a/configs/targets/loongarch64-linux-user.mak b/configs/targets/loongarch64-linux-user.mak index 7d1b964020..d878e5a113 100644 --- a/configs/targets/loongarch64-linux-user.mak +++ b/configs/targets/loongarch64-linux-user.mak @@ -1,3 +1,4 @@ # Default configuration for loongarch64-linux-user TARGET_ARCH=loongarch64 TARGET_BASE_ARCH=loongarch +TARGET_XML_FILES=gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml
[PULL 59/85] target/hppa: Use tcg_temp_new_i64 not tcg_temp_new
Signed-off-by: Richard Henderson --- target/hppa/translate.c | 162 1 file changed, 82 insertions(+), 80 deletions(-) diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 0024c38c84..c8c702ac03 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -32,6 +32,8 @@ #include "exec/helper-info.c.inc" #undef HELPER_H +/* Choose to use explicit sizes within this file. */ +#undef tcg_temp_new typedef struct DisasCond { TCGCond c; @@ -269,15 +271,15 @@ static DisasCond cond_make_0_tmp(TCGCond c, TCGv_i64 a0) static DisasCond cond_make_0(TCGCond c, TCGv_i64 a0) { -TCGv_i64 tmp = tcg_temp_new(); +TCGv_i64 tmp = tcg_temp_new_i64(); tcg_gen_mov_i64(tmp, a0); return cond_make_0_tmp(c, tmp); } static DisasCond cond_make(TCGCond c, TCGv_i64 a0, TCGv_i64 a1) { -TCGv_i64 t0 = tcg_temp_new(); -TCGv_i64 t1 = tcg_temp_new(); +TCGv_i64 t0 = tcg_temp_new_i64(); +TCGv_i64 t1 = tcg_temp_new_i64(); tcg_gen_mov_i64(t0, a0); tcg_gen_mov_i64(t1, a1); @@ -302,7 +304,7 @@ static void cond_free(DisasCond *cond) static TCGv_i64 load_gpr(DisasContext *ctx, unsigned reg) { if (reg == 0) { -TCGv_i64 t = tcg_temp_new(); +TCGv_i64 t = tcg_temp_new_i64(); tcg_gen_movi_i64(t, 0); return t; } else { @@ -313,7 +315,7 @@ static TCGv_i64 load_gpr(DisasContext *ctx, unsigned reg) static TCGv_i64 dest_gpr(DisasContext *ctx, unsigned reg) { if (reg == 0 || ctx->null_cond.c != TCG_COND_NEVER) { -return tcg_temp_new(); +return tcg_temp_new_i64(); } else { return cpu_gr[reg]; } @@ -437,7 +439,7 @@ static void nullify_over(DisasContext *ctx) /* If we're using PSW[N], copy it to a temp because... */ if (ctx->null_cond.a0 == cpu_psw_n) { -ctx->null_cond.a0 = tcg_temp_new(); +ctx->null_cond.a0 = tcg_temp_new_i64(); tcg_gen_mov_i64(ctx->null_cond.a0, cpu_psw_n); } /* ... we clear it before branching over the implementation, @@ -657,14 +659,14 @@ static DisasCond do_cond(DisasContext *ctx, unsigned cf, bool d, break; case 1: /* = / <>(Z / !Z) */ if (cond_need_ext(ctx, d)) { -tmp = tcg_temp_new(); +tmp = tcg_temp_new_i64(); tcg_gen_ext32u_i64(tmp, res); res = tmp; } cond = cond_make_0(TCG_COND_EQ, res); break; case 2: /* < / >=(N ^ V / !(N ^ V) */ -tmp = tcg_temp_new(); +tmp = tcg_temp_new_i64(); tcg_gen_xor_i64(tmp, res, sv); if (cond_need_ext(ctx, d)) { tcg_gen_ext32s_i64(tmp, tmp); @@ -681,7 +683,7 @@ static DisasCond do_cond(DisasContext *ctx, unsigned cf, bool d, * !(~(res ^ sv) >> 31) | !res * !(~(res ^ sv) >> 31 & res) */ -tmp = tcg_temp_new(); +tmp = tcg_temp_new_i64(); tcg_gen_eqv_i64(tmp, res, sv); if (cond_need_ext(ctx, d)) { tcg_gen_sextract_i64(tmp, tmp, 31, 1); @@ -698,7 +700,7 @@ static DisasCond do_cond(DisasContext *ctx, unsigned cf, bool d, cond = cond_make_0(TCG_COND_EQ, cb_msb); break; case 5: /* ZNV / VNZ (!C | Z / C & !Z) */ -tmp = tcg_temp_new(); +tmp = tcg_temp_new_i64(); tcg_gen_neg_i64(tmp, cb_msb); tcg_gen_and_i64(tmp, tmp, res); if (cond_need_ext(ctx, d)) { @@ -708,14 +710,14 @@ static DisasCond do_cond(DisasContext *ctx, unsigned cf, bool d, break; case 6: /* SV / NSV (V / !V) */ if (cond_need_ext(ctx, d)) { -tmp = tcg_temp_new(); +tmp = tcg_temp_new_i64(); tcg_gen_ext32s_i64(tmp, sv); sv = tmp; } cond = cond_make_0(TCG_COND_LT, sv); break; case 7: /* OD / EV */ -tmp = tcg_temp_new(); +tmp = tcg_temp_new_i64(); tcg_gen_andi_i64(tmp, res, 1); cond = cond_make_0_tmp(TCG_COND_NE, tmp); break; @@ -769,8 +771,8 @@ static DisasCond do_sub_cond(DisasContext *ctx, unsigned cf, bool d, tc = tcg_invert_cond(tc); } if (cond_need_ext(ctx, d)) { -TCGv_i64 t1 = tcg_temp_new(); -TCGv_i64 t2 = tcg_temp_new(); +TCGv_i64 t1 = tcg_temp_new_i64(); +TCGv_i64 t2 = tcg_temp_new_i64(); if (ext_uns) { tcg_gen_ext32u_i64(t1, in1); @@ -846,7 +848,7 @@ static DisasCond do_log_cond(DisasContext *ctx, unsigned cf, bool d, } if (cond_need_ext(ctx, d)) { -TCGv_i64 tmp = tcg_temp_new(); +TCGv_i64 tmp = tcg_temp_new_i64(); if (ext_uns) { tcg_gen_ext32u_i64(tmp, res); @@ -891,8 +893,8 @@ static DisasCond do_unit_cond(unsigned cf, bool d, TCGv_i64 res, * do our normal thing and compute carry-in of bit B+1 since that * leaves us with carry bits spread acr
[PULL 63/85] target/hppa: Implement HAVG
Signed-off-by: Richard Henderson --- target/hppa/helper.h | 1 + target/hppa/insns.decode | 2 ++ target/hppa/op_helper.c | 14 ++ target/hppa/translate.c | 5 + 4 files changed, 22 insertions(+) diff --git a/target/hppa/helper.h b/target/hppa/helper.h index 64fd1ef1ef..3b3a543216 100644 --- a/target/hppa/helper.h +++ b/target/hppa/helper.h @@ -16,6 +16,7 @@ DEF_HELPER_FLAGS_1(ldc_check, TCG_CALL_NO_RWG, void, tl) DEF_HELPER_FLAGS_2(hadd_ss, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(hadd_us, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(havg, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(hsub_ss, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(hsub_us, TCG_CALL_NO_RWG_SE, i64, i64, i64) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index 29b49c6cf4..6959555bf3 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -214,6 +214,8 @@ hadd10 . . 0011 11 0 . @rrr hadd_ss 10 . . 0011 01 0 . @rrr hadd_us 10 . . 0011 00 0 . @rrr +havg10 . . 0010 11 0 . @rrr + hsub10 . . 0001 11 0 . @rrr hsub_ss 10 . . 0001 01 0 . @rrr hsub_us 10 . . 0001 00 0 . @rrr diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c index de51905428..e76f201472 100644 --- a/target/hppa/op_helper.c +++ b/target/hppa/op_helper.c @@ -410,6 +410,20 @@ uint64_t HELPER(hadd_us)(uint64_t r1, uint64_t r2) return ret; } +uint64_t HELPER(havg)(uint64_t r1, uint64_t r2) +{ +uint64_t ret = 0; + +for (int i = 0; i < 64; i += 16) { +int f1 = extract64(r1, i, 16); +int f2 = extract64(r2, i, 16); +int fr = f1 + f2; + +ret = deposit64(ret, i, 16, (fr >> 1) | (fr & 1)); +} +return ret; +} + uint64_t HELPER(hsub_ss)(uint64_t r1, uint64_t r2) { uint64_t ret = 0; diff --git a/target/hppa/translate.c b/target/hppa/translate.c index e5a3873d25..e20ce40fe3 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -2804,6 +2804,11 @@ static bool trans_hadd_us(DisasContext *ctx, arg_rrr *a) return do_multimedia(ctx, a, gen_helper_hadd_us); } +static bool trans_havg(DisasContext *ctx, arg_rrr *a) +{ +return do_multimedia(ctx, a, gen_helper_havg); +} + static bool trans_hsub(DisasContext *ctx, arg_rrr *a) { return do_multimedia(ctx, a, tcg_gen_vec_sub16_i64); -- 2.34.1
[PULL 34/85] target/hppa: Pass d to do_unit_cond
Hoist the resolution of d up one level above do_unit_cond. All computations are logical, and are simplified by using a mask of the correct width, after which the result may be compared with zero. Signed-off-by: Richard Henderson --- target/hppa/translate.c | 20 +++- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/target/hppa/translate.c b/target/hppa/translate.c index eb4605a9c7..41f4e06841 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -1069,11 +1069,12 @@ static DisasCond do_sed_cond(DisasContext *ctx, unsigned orig, bool d, /* Similar, but for unit conditions. */ -static DisasCond do_unit_cond(unsigned cf, TCGv_reg res, +static DisasCond do_unit_cond(unsigned cf, bool d, TCGv_reg res, TCGv_reg in1, TCGv_reg in2) { DisasCond cond; TCGv_reg tmp, cb = NULL; +target_ureg d_repl = d ? 0x00010001ull : 1; if (cf & 8) { /* Since we want to test lots of carry-out bits all at once, do not @@ -1100,32 +1101,32 @@ static DisasCond do_unit_cond(unsigned cf, TCGv_reg res, * https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord */ tmp = tcg_temp_new(); -tcg_gen_subi_reg(tmp, res, 0x01010101u); +tcg_gen_subi_reg(tmp, res, d_repl * 0x01010101u); tcg_gen_andc_reg(tmp, tmp, res); -tcg_gen_andi_reg(tmp, tmp, 0x80808080u); +tcg_gen_andi_reg(tmp, tmp, d_repl * 0x80808080u); cond = cond_make_0(TCG_COND_NE, tmp); break; case 3: /* SHZ / NHZ */ tmp = tcg_temp_new(); -tcg_gen_subi_reg(tmp, res, 0x00010001u); +tcg_gen_subi_reg(tmp, res, d_repl * 0x00010001u); tcg_gen_andc_reg(tmp, tmp, res); -tcg_gen_andi_reg(tmp, tmp, 0x80008000u); +tcg_gen_andi_reg(tmp, tmp, d_repl * 0x80008000u); cond = cond_make_0(TCG_COND_NE, tmp); break; case 4: /* SDC / NDC */ -tcg_gen_andi_reg(cb, cb, 0xu); +tcg_gen_andi_reg(cb, cb, d_repl * 0xu); cond = cond_make_0(TCG_COND_NE, cb); break; case 6: /* SBC / NBC */ -tcg_gen_andi_reg(cb, cb, 0x80808080u); +tcg_gen_andi_reg(cb, cb, d_repl * 0x80808080u); cond = cond_make_0(TCG_COND_NE, cb); break; case 7: /* SHC / NHC */ -tcg_gen_andi_reg(cb, cb, 0x80008000u); +tcg_gen_andi_reg(cb, cb, d_repl * 0x80008000u); cond = cond_make_0(TCG_COND_NE, cb); break; @@ -1441,6 +1442,7 @@ static void do_unit(DisasContext *ctx, unsigned rt, TCGv_reg in1, { TCGv_reg dest; DisasCond cond; +bool d = false; if (cf == 0) { dest = dest_gpr(ctx, rt); @@ -1451,7 +1453,7 @@ static void do_unit(DisasContext *ctx, unsigned rt, TCGv_reg in1, dest = tcg_temp_new(); fn(dest, in1, in2); -cond = do_unit_cond(cf, dest, in1, in2); +cond = do_unit_cond(cf, d, dest, in1, in2); if (is_tc) { TCGv_reg tmp = tcg_temp_new(); -- 2.34.1
Re: [PATCH 23/29] plugins: Use different helpers when reading registers
On 11/3/23 12:59, Alex Bennée wrote: --- a/plugins/api.c +++ b/plugins/api.c @@ -89,7 +89,11 @@ void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb, void *udata) { if (!tb->mem_only) { -plugin_register_dyn_cb__udata(&tb->cbs[PLUGIN_CB_REGULAR], +int index = flags == QEMU_PLUGIN_CB_R_REGS || +flags == QEMU_PLUGIN_CB_RW_REGS ? +PLUGIN_CB_REGULAR_R : PLUGIN_CB_REGULAR; + I'd really rather you reject QEMU_PLUGIN_CB_RW_REGS entirely, rather than implement it with incorrect semantics. Otherwise, Reviewed-by: Richard Henderson +plugin_register_dyn_cb__udata(&tb->cbs[index], cb, flags, udata); } } @@ -109,7 +113,11 @@ void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn, void *udata) { if (!insn->mem_only) { - plugin_register_dyn_cb__udata(&insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_REGULAR], +int index = flags == QEMU_PLUGIN_CB_R_REGS || +flags == QEMU_PLUGIN_CB_RW_REGS ? +PLUGIN_CB_REGULAR_R : PLUGIN_CB_REGULAR; + +plugin_register_dyn_cb__udata(&insn->cbs[PLUGIN_CB_INSN][index], cb, flags, udata); } }
[PULL 78/85] target/hppa: Add unwind_breg to CPUHPPAState
Fill in the insn_start value during form_gva, and copy it out to the env field in hppa_restore_state_to_opc. The value is not yet consumed. Signed-off-by: Richard Henderson --- target/hppa/cpu.h | 8 +++- target/hppa/cpu.c | 1 + target/hppa/translate.c | 13 - 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index ea8e7e99a4..144794d089 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -45,7 +45,7 @@ #define MMU_IDX_TO_P(MIDX) (((MIDX) - MMU_KERNEL_IDX) & 1) #define PRIV_P_TO_MMU_IDX(PRIV, P) ((PRIV) * 2 + !!(P) + MMU_KERNEL_IDX) -#define TARGET_INSN_START_EXTRA_WORDS 1 +#define TARGET_INSN_START_EXTRA_WORDS 2 /* No need to flush MMU_PHYS_IDX */ #define HPPA_MMU_FLUSH_MASK \ @@ -208,6 +208,12 @@ typedef struct CPUArchState { target_ulong cr_back[2]; /* back of cr17/cr18 */ target_ulong shadow[7]; /* shadow registers */ +/* + * During unwind of a memory insn, the base register of the address. + * This is used to construct CR_IOR for pa2.0. + */ +uint32_t unwind_breg; + /* * ??? The number of entries isn't specified by the architecture. * BTLBs are not supported in 64-bit machines. diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index e1597ba8a5..04de1689d7 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c @@ -80,6 +80,7 @@ static void hppa_restore_state_to_opc(CPUState *cs, if (data[1] != (target_ulong)-1) { cpu->env.iaoq_b = data[1]; } +cpu->env.unwind_breg = data[2]; /* * Since we were executing the instruction at IAOQ_F, and took some * sort of action that provoked the cpu_restore_state, we can infer diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 4102f5faf3..bcce65d587 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -44,6 +44,7 @@ typedef struct DisasCond { typedef struct DisasContext { DisasContextBase base; CPUState *cs; +TCGOp *insn_start; uint64_t iaoq_f; uint64_t iaoq_b; @@ -234,6 +235,13 @@ void hppa_translate_init(void) "iasq_b"); } +static void set_insn_breg(DisasContext *ctx, int breg) +{ +assert(ctx->insn_start != NULL); +tcg_set_insn_start_param(ctx->insn_start, 2, breg); +ctx->insn_start = NULL; +} + static DisasCond cond_make_f(void) { return (DisasCond){ @@ -1324,6 +1332,8 @@ static void form_gva(DisasContext *ctx, TCGv_i64 *pgva, TCGv_i64 *pofs, TCGv_i64 ofs; TCGv_i64 addr; +set_insn_breg(ctx, rb); + /* Note that RX is mutually exclusive with DISP. */ if (rx) { ofs = tcg_temp_new_i64(); @@ -4458,7 +4468,8 @@ static void hppa_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) { DisasContext *ctx = container_of(dcbase, DisasContext, base); -tcg_gen_insn_start(ctx->iaoq_f, ctx->iaoq_b); +tcg_gen_insn_start(ctx->iaoq_f, ctx->iaoq_b, 0); +ctx->insn_start = tcg_last_op(); } static void hppa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) -- 2.34.1
[PULL 61/85] target/hppa: Implement HADD
Signed-off-by: Richard Henderson --- target/hppa/helper.h | 3 +++ target/hppa/insns.decode | 8 +++- target/hppa/op_helper.c | 32 target/hppa/translate.c | 37 + 4 files changed, 79 insertions(+), 1 deletion(-) diff --git a/target/hppa/helper.h b/target/hppa/helper.h index 57ea5447b6..db662f0c33 100644 --- a/target/hppa/helper.h +++ b/target/hppa/helper.h @@ -14,6 +14,9 @@ DEF_HELPER_FLAGS_3(stdby_e_parallel, TCG_CALL_NO_WG, void, env, tl, tl) DEF_HELPER_FLAGS_1(ldc_check, TCG_CALL_NO_RWG, void, tl) +DEF_HELPER_FLAGS_2(hadd_ss, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(hadd_us, TCG_CALL_NO_RWG_SE, i64, i64, i64) + DEF_HELPER_FLAGS_4(probe, TCG_CALL_NO_WG, tl, env, tl, i32, i32) DEF_HELPER_FLAGS_1(loaded_fr0, TCG_CALL_NO_RWG, void, env) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index 820049b0c5..4bcfc94b1c 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -65,6 +65,7 @@ &ldst t b x disp sp m scale size &rr_cf_dt r cf d +&rrrt r1 r2 &rrr_cf t r1 r2 cf &rrr_cf_d t r1 r2 cf d &rrr_cf_d_sht r1 r2 cf d sh @@ -81,6 +82,7 @@ @rr_cf_d.. r:5 . cf:4 .. d:1 t:5&rr_cf_d +@rrr.. r2:5 r1:5 ... t:5 &rrr @rrr_cf .. r2:5 r1:5 cf:4 ... t:5 &rrr_cf @rrr_cf_d .. r2:5 r1:5 cf:4 .. d:1 t:5&rrr_cf_d @rrr_cf_d_sh.. r2:5 r1:5 cf:4 sh:2 d:1 t:5 &rrr_cf_d_sh @@ -208,6 +210,10 @@ subi_tsv100101 . . 1 ... @rri_cf cmpiclr 100100 . . . ... @rri_cf_d +hadd10 . . 0011 11 0 . @rrr +hadd_ss 10 . . 0011 01 0 . @rrr +hadd_us 10 . . 0011 00 0 . @rrr + # Index Mem @@ -429,7 +435,7 @@ fmpyfadd_d 101110 rm1:5 rm2:5 ... 0 1 ..0 0 0 neg:1 t:5ra3=%rc32 @f0e_f_3.. . . ... .0 110 ..0 .\ &fclass3 r1=%ra64 r2=%rb64 t=%rt64 -@f0e_d_3.. r1:5 r2:5 ... 01 110 000 t:5 +@f0e_d_3.. r1:5 r2:5 ... 01 110 000 t:5 &fclass3 # Floating point class 0 diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c index a25e6df7e4..d93801ca47 100644 --- a/target/hppa/op_helper.c +++ b/target/hppa/op_helper.c @@ -377,3 +377,35 @@ target_ulong HELPER(read_interval_timer)(void) return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >> 2; #endif } + +uint64_t HELPER(hadd_ss)(uint64_t r1, uint64_t r2) +{ +uint64_t ret = 0; + +for (int i = 0; i < 64; i += 16) { +int f1 = sextract64(r1, i, 16); +int f2 = sextract64(r2, i, 16); +int fr = f1 + f2; + +fr = MIN(fr, INT16_MAX); +fr = MAX(fr, INT16_MIN); +ret = deposit64(ret, i, 16, fr); +} +return ret; +} + +uint64_t HELPER(hadd_us)(uint64_t r1, uint64_t r2) +{ +uint64_t ret = 0; + +for (int i = 0; i < 64; i += 16) { +int f1 = extract64(r1, i, 16); +int f2 = sextract64(r2, i, 16); +int fr = f1 + f2; + +fr = MIN(fr, UINT16_MAX); +fr = MAX(fr, 0); +ret = deposit64(ret, i, 16, fr); +} +return ret; +} diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 1d749e2a78..dc8e37f99c 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -23,6 +23,7 @@ #include "qemu/host-utils.h" #include "exec/exec-all.h" #include "tcg/tcg-op.h" +#include "tcg/tcg-op-gvec.h" #include "exec/helper-proto.h" #include "exec/helper-gen.h" #include "exec/translator.h" @@ -2767,6 +2768,42 @@ static bool trans_cmpiclr(DisasContext *ctx, arg_rri_cf_d *a) return nullify_end(ctx); } +static bool do_multimedia(DisasContext *ctx, arg_rrr *a, + void (*fn)(TCGv_i64, TCGv_i64, TCGv_i64)) +{ +TCGv_i64 r1, r2, dest; + +if (!ctx->is_pa20) { +return false; +} + +nullify_over(ctx); + +r1 = load_gpr(ctx, a->r1); +r2 = load_gpr(ctx, a->r2); +dest = dest_gpr(ctx, a->t); + +fn(dest, r1, r2); +save_gpr(ctx, a->t, dest); + +return nullify_end(ctx); +} + +static bool trans_hadd(DisasContext *ctx, arg_rrr *a) +{ +return do_multimedia(ctx, a, tcg_gen_vec_add16_i64); +} + +static bool trans_hadd_ss(DisasContext *ctx, arg_rrr *a) +{ +return do_multimedia(ctx, a, gen_helper_hadd_ss); +} + +static bool trans_hadd_us(DisasContext *ctx, arg_rrr *a) +{ +return do_multimedia(ctx, a, gen_helper_hadd_us); +} + static bool trans_ld(DisasContext *ctx, arg_ldst *a) { if (!ctx->is_pa20 && a->size > MO_32) { -- 2.34.1
[PULL 36/85] target/hppa: Drop attempted gdbstub support for hppa64
There is no support for hppa64 in gdb. Any attempt to provide the data for the larger hppa64 registers results in an error from gdb. Mask CR_SAR writes to the width of the register: 5 or 6 bits. Signed-off-by: Richard Henderson --- target/hppa/gdbstub.c | 32 +--- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/target/hppa/gdbstub.c b/target/hppa/gdbstub.c index 48a514384f..4a965b38d7 100644 --- a/target/hppa/gdbstub.c +++ b/target/hppa/gdbstub.c @@ -21,11 +21,16 @@ #include "cpu.h" #include "gdbstub/helpers.h" +/* + * GDB 15 only supports PA1.0 via the remote protocol, and ignores + * any provided xml. Which means that any attempt to provide more + * data results in "Remote 'g' packet reply is too long". + */ + int hppa_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { -HPPACPU *cpu = HPPA_CPU(cs); -CPUHPPAState *env = &cpu->env; -target_ureg val; +CPUHPPAState *env = cpu_env(cs); +uint32_t val; switch (n) { case 0: @@ -139,24 +144,13 @@ int hppa_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) break; } -if (TARGET_REGISTER_BITS == 64) { -return gdb_get_reg64(mem_buf, val); -} else { -return gdb_get_reg32(mem_buf, val); -} +return gdb_get_reg32(mem_buf, val); } int hppa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { -HPPACPU *cpu = HPPA_CPU(cs); -CPUHPPAState *env = &cpu->env; -target_ureg val; - -if (TARGET_REGISTER_BITS == 64) { -val = ldq_p(mem_buf); -} else { -val = ldl_p(mem_buf); -} +CPUHPPAState *env = cpu_env(cs); +uint32_t val = ldl_p(mem_buf); switch (n) { case 0: @@ -166,7 +160,7 @@ int hppa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) env->gr[n] = val; break; case 32: -env->cr[CR_SAR] = val; +env->cr[CR_SAR] = val & (hppa_is_pa20(env) ? 63 : 31); break; case 33: env->iaoq_f = val; @@ -278,5 +272,5 @@ int hppa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) } break; } -return sizeof(target_ureg); +return 4; } -- 2.34.1
[PULL 43/85] target/hppa: Decode d for bb instructions
Manipulate the shift count so that the bit to be tested is always placed at the MSB. Signed-off-by: Richard Henderson --- target/hppa/insns.decode | 4 ++-- target/hppa/translate.c | 6 ++ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index ad454adcbb..b185523021 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -290,8 +290,8 @@ fmpysub_d 100110 . . . . 1 . @mpyadd # Conditional Branches -bb_sar 11 0 r:5 c:1 10 ... n:1 . disp=%assemble_12 -bb_imm 110001 p:5 r:5 c:1 10 ... n:1 . disp=%assemble_12 +bb_sar 11 0 r:5 c:1 1 d:1 ... n:1 . disp=%assemble_12 +bb_imm 110001 p:5 r:5 c:1 1 d:1 ... n:1 . disp=%assemble_12 movb110010 . . ... ... . . @rrb_cf f=0 movbi 110011 . . ... ... . . @rib_cf f=0 diff --git a/target/hppa/translate.c b/target/hppa/translate.c index f2b2933c88..e326f63866 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -3172,13 +3172,12 @@ static bool trans_bb_sar(DisasContext *ctx, arg_bb_sar *a) { TCGv_reg tmp, tcg_r; DisasCond cond; -bool d = false; nullify_over(ctx); tmp = tcg_temp_new(); tcg_r = load_gpr(ctx, a->r); -if (cond_need_ext(ctx, d)) { +if (cond_need_ext(ctx, a->d)) { /* Force shift into [32,63] */ tcg_gen_ori_reg(tmp, cpu_sar, 32); tcg_gen_shl_reg(tmp, tcg_r, tmp); @@ -3194,14 +3193,13 @@ static bool trans_bb_imm(DisasContext *ctx, arg_bb_imm *a) { TCGv_reg tmp, tcg_r; DisasCond cond; -bool d = false; int p; nullify_over(ctx); tmp = tcg_temp_new(); tcg_r = load_gpr(ctx, a->r); -p = a->p | (cond_need_ext(ctx, d) ? 32 : 0); +p = a->p | (cond_need_ext(ctx, a->d) ? 32 : 0); tcg_gen_shli_reg(tmp, tcg_r, p); cond = cond_make_0(a->c ? TCG_COND_GE : TCG_COND_LT, tmp); -- 2.34.1
[PULL 58/85] target/hppa: Adjust vmstate_env for pa2.0 tlb
Split out the tlb to a subsection so that it can be separately versioned -- the format is only partially following the architecture and is partially guided by the qemu implementation. Signed-off-by: Richard Henderson --- target/hppa/machine.c | 93 ++- 1 file changed, 57 insertions(+), 36 deletions(-) diff --git a/target/hppa/machine.c b/target/hppa/machine.c index f6df4deac5..2f8e8cc5a1 100644 --- a/target/hppa/machine.c +++ b/target/hppa/machine.c @@ -44,28 +44,30 @@ static const VMStateInfo vmstate_psw = { .put = put_psw, }; -/* FIXME: Use the PA2.0 format, which is a superset of the PA1.1 format. */ static int get_tlb(QEMUFile *f, void *opaque, size_t size, const VMStateField *field) { HPPATLBEntry *ent = opaque; -uint32_t val; +uint64_t val; ent->itree.start = qemu_get_be64(f); +ent->itree.last = qemu_get_be64(f); ent->pa = qemu_get_be64(f); -val = qemu_get_be32(f); +val = qemu_get_be64(f); -ent->entry_valid = extract32(val, 0, 1); -ent->access_id = extract32(val, 1, 18); -ent->u = extract32(val, 19, 1); -ent->ar_pl2 = extract32(val, 20, 2); -ent->ar_pl1 = extract32(val, 22, 2); -ent->ar_type = extract32(val, 24, 3); -ent->b = extract32(val, 27, 1); -ent->d = extract32(val, 28, 1); -ent->t = extract32(val, 29, 1); - -ent->itree.last = ent->itree.start + TARGET_PAGE_SIZE - 1; +if (val) { +ent->t = extract64(val, 61, 1); +ent->d = extract64(val, 60, 1); +ent->b = extract64(val, 59, 1); +ent->ar_type = extract64(val, 56, 3); +ent->ar_pl1 = extract64(val, 54, 2); +ent->ar_pl2 = extract64(val, 52, 2); +ent->u = extract64(val, 51, 1); +/* o = bit 50 */ +/* p = bit 49 */ +ent->access_id = extract64(val, 1, 31); +ent->entry_valid = 1; +} return 0; } @@ -73,27 +75,30 @@ static int put_tlb(QEMUFile *f, void *opaque, size_t size, const VMStateField *field, JSONWriter *vmdesc) { HPPATLBEntry *ent = opaque; -uint32_t val = 0; +uint64_t val = 0; if (ent->entry_valid) { val = 1; -val = deposit32(val, 1, 18, ent->access_id); -val = deposit32(val, 19, 1, ent->u); -val = deposit32(val, 20, 2, ent->ar_pl2); -val = deposit32(val, 22, 2, ent->ar_pl1); -val = deposit32(val, 24, 3, ent->ar_type); -val = deposit32(val, 27, 1, ent->b); -val = deposit32(val, 28, 1, ent->d); -val = deposit32(val, 29, 1, ent->t); +val = deposit64(val, 61, 1, ent->t); +val = deposit64(val, 60, 1, ent->d); +val = deposit64(val, 59, 1, ent->b); +val = deposit64(val, 56, 3, ent->ar_type); +val = deposit64(val, 54, 2, ent->ar_pl1); +val = deposit64(val, 52, 2, ent->ar_pl2); +val = deposit64(val, 51, 1, ent->u); +/* o = bit 50 */ +/* p = bit 49 */ +val = deposit64(val, 1, 31, ent->access_id); } qemu_put_be64(f, ent->itree.start); +qemu_put_be64(f, ent->itree.last); qemu_put_be64(f, ent->pa); -qemu_put_be32(f, val); +qemu_put_be64(f, val); return 0; } -static const VMStateInfo vmstate_tlb = { +static const VMStateInfo vmstate_tlb_entry = { .name = "tlb entry", .get = get_tlb, .put = put_tlb, @@ -147,7 +152,24 @@ static int tlb_post_load(void *opaque, int version_id) return 0; } -static VMStateField vmstate_env_fields[] = { +static const VMStateField vmstate_tlb_fields[] = { +VMSTATE_ARRAY(tlb, CPUHPPAState, + ARRAY_SIZE(((CPUHPPAState *)0)->tlb), + 0, vmstate_tlb_entry, HPPATLBEntry), +VMSTATE_UINT32(tlb_last, CPUHPPAState), +VMSTATE_END_OF_LIST() +}; + +static const VMStateDescription vmstate_tlb = { +.name = "env/tlb", +.version_id = 1, +.minimum_version_id = 1, +.fields = vmstate_tlb_fields, +.pre_load = tlb_pre_load, +.post_load = tlb_post_load, +}; + +static const VMStateField vmstate_env_fields[] = { VMSTATE_UINT64_ARRAY(gr, CPUHPPAState, 32), VMSTATE_UINT64_ARRAY(fr, CPUHPPAState, 32), VMSTATE_UINT64_ARRAY(sr, CPUHPPAState, 8), @@ -176,24 +198,23 @@ static VMStateField vmstate_env_fields[] = { VMSTATE_UINT64(iasq_b, CPUHPPAState), VMSTATE_UINT32(fr0_shadow, CPUHPPAState), - -VMSTATE_ARRAY(tlb, CPUHPPAState, ARRAY_SIZE(((CPUHPPAState *)0)->tlb), - 0, vmstate_tlb, HPPATLBEntry), -VMSTATE_UINT32(tlb_last, CPUHPPAState), - VMSTATE_END_OF_LIST() }; +static const VMStateDescription *vmstate_env_subsections[] = { +&vmstate_tlb, +NULL +}; + static const VMStateDescription vmstate_env = { .name = "env", -.version_id = 2, -.minimum_version_id = 2, +.version_id = 3, +.minimum_version_id = 3, .fields = vmstate_env_fields, -.pre_load = tlb_pre_load, -.post_load = tlb_post_load, +.su
[PULL 55/85] target/hppa: Remove TARGET_REGISTER_BITS
Rely only on TARGET_LONG_BITS, fixed at 64, and hppa_is_pa20. Signed-off-by: Richard Henderson --- target/hppa/cpu-param.h | 1 - target/hppa/cpu.h| 50 --- target/hppa/helper.h | 51 +-- target/hppa/cpu.c| 2 +- target/hppa/helper.c | 32 +++ target/hppa/int_helper.c | 17 ++-- target/hppa/machine.c| 45 +++--- target/hppa/mem_helper.c | 16 ++-- target/hppa/op_helper.c | 30 +++ target/hppa/sys_helper.c | 4 +- target/hppa/translate.c | 186 --- 11 files changed, 135 insertions(+), 299 deletions(-) diff --git a/target/hppa/cpu-param.h b/target/hppa/cpu-param.h index 2fb8e7924b..6746869a3b 100644 --- a/target/hppa/cpu-param.h +++ b/target/hppa/cpu-param.h @@ -9,7 +9,6 @@ #define HPPA_CPU_PARAM_H #define TARGET_LONG_BITS 64 -#define TARGET_REGISTER_BITS 64 #if defined(CONFIG_USER_ONLY) && defined(TARGET_ABI32) # define TARGET_PHYS_ADDR_SPACE_BITS 32 diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index 77ddb20ac2..ea676ba062 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -154,25 +154,13 @@ #define CR_IPSW 22 #define CR_EIRR 23 -#if TARGET_REGISTER_BITS == 32 -typedef uint32_t target_ureg; -typedef int32_t target_sreg; -#define TREG_FMT_lx "%08"PRIx32 -#define TREG_FMT_ld "%"PRId32 -#else -typedef uint64_t target_ureg; -typedef int64_t target_sreg; -#define TREG_FMT_lx "%016"PRIx64 -#define TREG_FMT_ld "%"PRId64 -#endif - typedef struct HPPATLBEntry { union { IntervalTreeNode itree; struct HPPATLBEntry *unused_next; }; -target_ureg pa; +target_ulong pa; unsigned entry_valid : 1; @@ -187,16 +175,16 @@ typedef struct HPPATLBEntry { } HPPATLBEntry; typedef struct CPUArchState { -target_ureg iaoq_f; /* front */ -target_ureg iaoq_b; /* back, aka next instruction */ +target_ulong iaoq_f; /* front */ +target_ulong iaoq_b; /* back, aka next instruction */ -target_ureg gr[32]; +target_ulong gr[32]; uint64_t fr[32]; uint64_t sr[8]; /* stored shifted into place for gva */ -target_ureg psw; /* All psw bits except the following: */ -target_ureg psw_n; /* boolean */ -target_sreg psw_v; /* in most significant bit */ +target_ulong psw;/* All psw bits except the following: */ +target_ulong psw_n; /* boolean */ +target_long psw_v; /* in most significant bit */ /* Splitting the carry-borrow field into the MSB and "the rest", allows * for "the rest" to be deleted when it is unused, but the MSB is in use. @@ -205,8 +193,8 @@ typedef struct CPUArchState { * host has the appropriate add-with-carry insn to compute the msb). * Therefore the carry bits are stored as: cb_msb : cb & 0x1110. */ -target_ureg psw_cb; /* in least significant bit of next nibble */ -target_ureg psw_cb_msb; /* boolean */ +target_ulong psw_cb; /* in least significant bit of next nibble */ +target_ulong psw_cb_msb; /* boolean */ uint64_t iasq_f; uint64_t iasq_b; @@ -214,9 +202,9 @@ typedef struct CPUArchState { uint32_t fr0_shadow; /* flags, c, ca/cq, rm, d, enables */ float_status fp_status; -target_ureg cr[32]; /* control registers */ -target_ureg cr_back[2]; /* back of cr17/cr18 */ -target_ureg shadow[7]; /* shadow registers */ +target_ulong cr[32]; /* control registers */ +target_ulong cr_back[2]; /* back of cr17/cr18 */ +target_ulong shadow[7]; /* shadow registers */ /* * ??? The number of entries isn't specified by the architecture. @@ -287,8 +275,8 @@ void hppa_translate_init(void); #define CPU_RESOLVING_TYPE TYPE_HPPA_CPU -static inline target_ulong hppa_form_gva_psw(target_ureg psw, uint64_t spc, - target_ureg off) +static inline target_ulong hppa_form_gva_psw(target_ulong psw, uint64_t spc, + target_ulong off) { #ifdef CONFIG_USER_ONLY return off; @@ -299,7 +287,7 @@ static inline target_ulong hppa_form_gva_psw(target_ureg psw, uint64_t spc, } static inline target_ulong hppa_form_gva(CPUHPPAState *env, uint64_t spc, - target_ureg off) + target_ulong off) { return hppa_form_gva_psw(env->psw, spc, off); } @@ -343,8 +331,8 @@ static inline void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc, which is the primary case we care about -- using goto_tb within a page. Failure is indicated by a zero difference. */ if (env->iasq_f == env->iasq_b) { -target_sreg diff = env->iaoq_b - env->iaoq_f; -if (TARGET_REGISTER_BITS == 32 || diff == (int32_t)diff) { +target_long diff = env->iaoq_b - env->iaoq_f; +if (diff == (in
[PULL 70/85] target/hppa: Return zero for r0 from load_gpr
Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/hppa/translate.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/target/hppa/translate.c b/target/hppa/translate.c index b04a5bc444..ba15cf6ab8 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -307,9 +307,7 @@ static void cond_free(DisasCond *cond) static TCGv_i64 load_gpr(DisasContext *ctx, unsigned reg) { if (reg == 0) { -TCGv_i64 t = tcg_temp_new_i64(); -tcg_gen_movi_i64(t, 0); -return t; +return ctx->zero; } else { return cpu_gr[reg]; } -- 2.34.1
[PULL 67/85] target/hppa: Implement PERMH
Signed-off-by: Richard Henderson --- target/hppa/insns.decode | 2 ++ target/hppa/translate.c | 29 + 2 files changed, 31 insertions(+) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index 22ec07f892..19e537df24 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -238,6 +238,8 @@ mixh_r 10 . . 1 10 0010 . @rrr mixw_l 10 . . 1 00 . @rrr mixw_r 10 . . 1 10 . @rrr +permh 10 r1:5 r2:5 0 c0:2 0 c1:2 c2:2 c3:2 0 t:5 + # Index Mem diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 2b471444d0..ffdd306d31 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -2946,6 +2946,35 @@ static bool trans_mixw_r(DisasContext *ctx, arg_rrr *a) return do_multimedia(ctx, a, gen_mixw_r); } +static bool trans_permh(DisasContext *ctx, arg_permh *a) +{ +TCGv_i64 r, t0, t1, t2, t3; + +if (!ctx->is_pa20) { +return false; +} + +nullify_over(ctx); + +r = load_gpr(ctx, a->r1); +t0 = tcg_temp_new_i64(); +t1 = tcg_temp_new_i64(); +t2 = tcg_temp_new_i64(); +t3 = tcg_temp_new_i64(); + +tcg_gen_extract_i64(t0, r, (3 - a->c0) * 16, 16); +tcg_gen_extract_i64(t1, r, (3 - a->c1) * 16, 16); +tcg_gen_extract_i64(t2, r, (3 - a->c2) * 16, 16); +tcg_gen_extract_i64(t3, r, (3 - a->c3) * 16, 16); + +tcg_gen_deposit_i64(t0, t1, t0, 16, 48); +tcg_gen_deposit_i64(t2, t3, t2, 16, 48); +tcg_gen_deposit_i64(t0, t2, t0, 32, 32); + +save_gpr(ctx, a->t, t0); +return nullify_end(ctx); +} + static bool trans_ld(DisasContext *ctx, arg_ldst *a) { if (!ctx->is_pa20 && a->size > MO_32) { -- 2.34.1
[PULL 64/85] target/hppa: Implement HSHL, HSHR
Signed-off-by: Richard Henderson --- target/hppa/insns.decode | 5 + target/hppa/translate.c | 35 +++ 2 files changed, 40 insertions(+) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index 6959555bf3..bb5cd267b0 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -69,6 +69,7 @@ &rrr_cf t r1 r2 cf &rrr_cf_d t r1 r2 cf d &rrr_cf_d_sht r1 r2 cf d sh +&rrit r i &rri_cf t r i cf &rri_cf_d t r i cf d @@ -216,6 +217,10 @@ hadd_us 10 . . 0011 00 0 . @rrr havg10 . . 0010 11 0 . @rrr +hshl10 0 r:5 100010 i:4 0 t:5&rri +hshr_s 10 r:5 0 110011 i:4 0 t:5&rri +hshr_u 10 r:5 0 110010 i:4 0 t:5&rri + hsub10 . . 0001 11 0 . @rrr hsub_ss 10 . . 0001 01 0 . @rrr hsub_us 10 . . 0001 00 0 . @rrr diff --git a/target/hppa/translate.c b/target/hppa/translate.c index e20ce40fe3..a3a12d63f8 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -2789,6 +2789,26 @@ static bool do_multimedia(DisasContext *ctx, arg_rrr *a, return nullify_end(ctx); } +static bool do_multimedia_sh(DisasContext *ctx, arg_rri *a, + void (*fn)(TCGv_i64, TCGv_i64, int64_t)) +{ +TCGv_i64 r, dest; + +if (!ctx->is_pa20) { +return false; +} + +nullify_over(ctx); + +r = load_gpr(ctx, a->r); +dest = dest_gpr(ctx, a->t); + +fn(dest, r, a->i); +save_gpr(ctx, a->t, dest); + +return nullify_end(ctx); +} + static bool trans_hadd(DisasContext *ctx, arg_rrr *a) { return do_multimedia(ctx, a, tcg_gen_vec_add16_i64); @@ -2809,6 +2829,21 @@ static bool trans_havg(DisasContext *ctx, arg_rrr *a) return do_multimedia(ctx, a, gen_helper_havg); } +static bool trans_hshl(DisasContext *ctx, arg_rri *a) +{ +return do_multimedia_sh(ctx, a, tcg_gen_vec_shl16i_i64); +} + +static bool trans_hshr_s(DisasContext *ctx, arg_rri *a) +{ +return do_multimedia_sh(ctx, a, tcg_gen_vec_sar16i_i64); +} + +static bool trans_hshr_u(DisasContext *ctx, arg_rri *a) +{ +return do_multimedia_sh(ctx, a, tcg_gen_vec_shr16i_i64); +} + static bool trans_hsub(DisasContext *ctx, arg_rrr *a) { return do_multimedia(ctx, a, tcg_gen_vec_sub16_i64); -- 2.34.1
[PULL 69/85] target/hppa: Precompute zero into DisasContext
Reduce the number of times we look for the constant 0. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/hppa/translate.c | 34 ++ 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/target/hppa/translate.c b/target/hppa/translate.c index ffdd306d31..b04a5bc444 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -53,6 +53,8 @@ typedef struct DisasContext { DisasCond null_cond; TCGLabel *null_lab; +TCGv_i64 zero; + uint32_t insn; uint32_t tb_flags; int mmu_idx; @@ -1017,14 +1019,13 @@ static void do_add(DisasContext *ctx, unsigned rt, TCGv_i64 in1, } if (!is_l || cond_need_cb(c)) { -TCGv_i64 zero = tcg_constant_i64(0); cb_msb = tcg_temp_new_i64(); cb = tcg_temp_new_i64(); -tcg_gen_add2_i64(dest, cb_msb, in1, zero, in2, zero); +tcg_gen_add2_i64(dest, cb_msb, in1, ctx->zero, in2, ctx->zero); if (is_c) { tcg_gen_add2_i64(dest, cb_msb, dest, cb_msb, - get_psw_carry(ctx, d), zero); + get_psw_carry(ctx, d), ctx->zero); } tcg_gen_xor_i64(cb, in1, in2); tcg_gen_xor_i64(cb, cb, dest); @@ -1102,7 +1103,7 @@ static void do_sub(DisasContext *ctx, unsigned rt, TCGv_i64 in1, TCGv_i64 in2, bool is_tsv, bool is_b, bool is_tc, unsigned cf, bool d) { -TCGv_i64 dest, sv, cb, cb_msb, zero, tmp; +TCGv_i64 dest, sv, cb, cb_msb, tmp; unsigned c = cf >> 1; DisasCond cond; @@ -1110,12 +,12 @@ static void do_sub(DisasContext *ctx, unsigned rt, TCGv_i64 in1, cb = tcg_temp_new_i64(); cb_msb = tcg_temp_new_i64(); -zero = tcg_constant_i64(0); if (is_b) { /* DEST,C = IN1 + ~IN2 + C. */ tcg_gen_not_i64(cb, in2); -tcg_gen_add2_i64(dest, cb_msb, in1, zero, get_psw_carry(ctx, d), zero); -tcg_gen_add2_i64(dest, cb_msb, dest, cb_msb, cb, zero); +tcg_gen_add2_i64(dest, cb_msb, in1, ctx->zero, + get_psw_carry(ctx, d), ctx->zero); +tcg_gen_add2_i64(dest, cb_msb, dest, cb_msb, cb, ctx->zero); tcg_gen_xor_i64(cb, cb, in1); tcg_gen_xor_i64(cb, cb, dest); } else { @@ -1124,7 +1125,7 @@ static void do_sub(DisasContext *ctx, unsigned rt, TCGv_i64 in1, * operations by seeding the high word with 1 and subtracting. */ TCGv_i64 one = tcg_constant_i64(1); -tcg_gen_sub2_i64(dest, cb_msb, in1, one, in2, zero); +tcg_gen_sub2_i64(dest, cb_msb, in1, one, in2, ctx->zero); tcg_gen_eqv_i64(cb, in1, in2); tcg_gen_xor_i64(cb, cb, dest); } @@ -2458,7 +2459,7 @@ static bool trans_lci(DisasContext *ctx, arg_lci *a) physical address. Two addresses with the same CI have a coherent view of the cache. Our implementation is to return 0 for all, since the entire address space is coherent. */ -save_gpr(ctx, a->t, tcg_constant_i64(0)); +save_gpr(ctx, a->t, ctx->zero); cond_free(&ctx->null_cond); return true; @@ -2667,7 +2668,7 @@ static bool trans_dcor_i(DisasContext *ctx, arg_rr_cf_d *a) static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a) { -TCGv_i64 dest, add1, add2, addc, zero, in1, in2; +TCGv_i64 dest, add1, add2, addc, in1, in2; TCGv_i64 cout; nullify_over(ctx); @@ -2679,7 +2680,6 @@ static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a) add2 = tcg_temp_new_i64(); addc = tcg_temp_new_i64(); dest = tcg_temp_new_i64(); -zero = tcg_constant_i64(0); /* Form R1 << 1 | PSW[CB]{8}. */ tcg_gen_add_i64(add1, in1, in1); @@ -2695,8 +2695,9 @@ static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a) tcg_gen_xor_i64(add2, in2, addc); tcg_gen_andi_i64(addc, addc, 1); -tcg_gen_add2_i64(dest, cpu_psw_cb_msb, add1, zero, add2, zero); -tcg_gen_add2_i64(dest, cpu_psw_cb_msb, dest, cpu_psw_cb_msb, addc, zero); +tcg_gen_add2_i64(dest, cpu_psw_cb_msb, add1, ctx->zero, add2, ctx->zero); +tcg_gen_add2_i64(dest, cpu_psw_cb_msb, dest, cpu_psw_cb_msb, + addc, ctx->zero); /* Write back the result register. */ save_gpr(ctx, a->t, dest); @@ -2996,7 +2997,7 @@ static bool trans_st(DisasContext *ctx, arg_ldst *a) static bool trans_ldc(DisasContext *ctx, arg_ldst *a) { MemOp mop = MO_TE | MO_ALIGN | a->size; -TCGv_i64 zero, dest, ofs; +TCGv_i64 dest, ofs; TCGv_i64 addr; if (!ctx->is_pa20 && a->size > MO_32) { @@ -3026,8 +3027,7 @@ static bool trans_ldc(DisasContext *ctx, arg_ldst *a) */ gen_helper_ldc_check(addr); -zero = tcg_constant_i64(0); -tcg_gen_atomic_xchg_i64(dest, addr, zero, ctx->mmu_idx, mop); +tcg_gen_atomic_xchg_i64(dest, addr, ctx->zero, ctx->mmu_idx, mop); if (a->m) { save_gpr(ctx, a->b, ofs); @@ -4383,6 +4383,8 @@ static void
[PULL 54/85] hw/hppa: Use uint32_t instead of target_ureg
The size of target_ureg is going to change. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- hw/hppa/machine.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index 85682e6bab..1f09b4b490 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -391,9 +391,9 @@ static void machine_HP_common_init_tail(MachineState *machine, PCIBus *pci_bus) true, EM_PARISC, 0, 0); /* Unfortunately, load_elf sign-extends reading elf32. */ -firmware_entry = (target_ureg)firmware_entry; -firmware_low = (target_ureg)firmware_low; -firmware_high = (target_ureg)firmware_high; +firmware_entry = (uint32_t)firmware_entry; +firmware_low = (uint32_t)firmware_low; +firmware_high = (uint32_t)firmware_high; if (size < 0) { error_report("could not load firmware '%s'", firmware_filename); @@ -420,9 +420,9 @@ static void machine_HP_common_init_tail(MachineState *machine, PCIBus *pci_bus) true, EM_PARISC, 0, 0); /* Unfortunately, load_elf sign-extends reading elf32. */ -kernel_entry = (target_ureg) cpu_hppa_to_phys(NULL, kernel_entry); -kernel_low = (target_ureg)kernel_low; -kernel_high = (target_ureg)kernel_high; +kernel_entry = (uint32_t) cpu_hppa_to_phys(NULL, kernel_entry); +kernel_low = (uint32_t)kernel_low; +kernel_high = (uint32_t)kernel_high; if (size < 0) { error_report("could not load kernel '%s'", kernel_filename); -- 2.34.1
[PULL 81/85] target/hppa: Improve interrupt logging
Signed-off-by: Richard Henderson --- target/hppa/int_helper.c | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c index 54875442e7..467ee7daf5 100644 --- a/target/hppa/int_helper.c +++ b/target/hppa/int_helper.c @@ -258,14 +258,10 @@ void hppa_cpu_do_interrupt(CPUState *cs) snprintf(unknown, sizeof(unknown), "unknown %d", i); name = unknown; } -qemu_log("INT %6d: %s @ " TARGET_FMT_lx "," TARGET_FMT_lx - " -> " TARGET_FMT_lx " " TARGET_FMT_lx "\n", - ++count, name, - hppa_form_gva(env, env->iasq_f, env->iaoq_f), - hppa_form_gva(env, env->iasq_b, env->iaoq_b), - env->iaoq_f, - hppa_form_gva(env, (uint64_t)env->cr[CR_ISR] << 32, - env->cr[CR_IOR])); +qemu_log("INT %6d: %s @ " TARGET_FMT_lx ":" TARGET_FMT_lx + " for " TARGET_FMT_lx ":" TARGET_FMT_lx "\n", + ++count, name, env->cr[CR_IIASQ], env->cr[CR_IIAOQ], + env->cr[CR_ISR], env->cr[CR_IOR]); } cs->exception_index = -1; } -- 2.34.1
[PULL 66/85] target/hppa: Implement MIXH, MIXW
Signed-off-by: Richard Henderson --- target/hppa/insns.decode | 5 target/hppa/translate.c | 55 2 files changed, 60 insertions(+) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index 87db726d9e..22ec07f892 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -233,6 +233,11 @@ hsub10 . . 0001 11 0 . @rrr hsub_ss 10 . . 0001 01 0 . @rrr hsub_us 10 . . 0001 00 0 . @rrr +mixh_l 10 . . 1 00 0010 . @rrr +mixh_r 10 . . 1 10 0010 . @rrr +mixw_l 10 . . 1 00 . @rrr +mixw_r 10 . . 1 10 . @rrr + # Index Mem diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 648c37fb28..2b471444d0 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -2891,6 +2891,61 @@ static bool trans_hsub_us(DisasContext *ctx, arg_rrr *a) return do_multimedia(ctx, a, gen_helper_hsub_us); } +static void gen_mixh_l(TCGv_i64 dst, TCGv_i64 r1, TCGv_i64 r2) +{ +uint64_t mask = 0xull; +TCGv_i64 tmp = tcg_temp_new_i64(); + +tcg_gen_andi_i64(tmp, r2, mask); +tcg_gen_andi_i64(dst, r1, mask); +tcg_gen_shri_i64(tmp, tmp, 16); +tcg_gen_or_i64(dst, dst, tmp); +} + +static bool trans_mixh_l(DisasContext *ctx, arg_rrr *a) +{ +return do_multimedia(ctx, a, gen_mixh_l); +} + +static void gen_mixh_r(TCGv_i64 dst, TCGv_i64 r1, TCGv_i64 r2) +{ +uint64_t mask = 0xull; +TCGv_i64 tmp = tcg_temp_new_i64(); + +tcg_gen_andi_i64(tmp, r1, mask); +tcg_gen_andi_i64(dst, r2, mask); +tcg_gen_shli_i64(tmp, tmp, 16); +tcg_gen_or_i64(dst, dst, tmp); +} + +static bool trans_mixh_r(DisasContext *ctx, arg_rrr *a) +{ +return do_multimedia(ctx, a, gen_mixh_r); +} + +static void gen_mixw_l(TCGv_i64 dst, TCGv_i64 r1, TCGv_i64 r2) +{ +TCGv_i64 tmp = tcg_temp_new_i64(); + +tcg_gen_shri_i64(tmp, r2, 32); +tcg_gen_deposit_i64(dst, r1, tmp, 0, 32); +} + +static bool trans_mixw_l(DisasContext *ctx, arg_rrr *a) +{ +return do_multimedia(ctx, a, gen_mixw_l); +} + +static void gen_mixw_r(TCGv_i64 dst, TCGv_i64 r1, TCGv_i64 r2) +{ +tcg_gen_deposit_i64(dst, r2, r1, 32, 32); +} + +static bool trans_mixw_r(DisasContext *ctx, arg_rrr *a) +{ +return do_multimedia(ctx, a, gen_mixw_r); +} + static bool trans_ld(DisasContext *ctx, arg_ldst *a) { if (!ctx->is_pa20 && a->size > MO_32) { -- 2.34.1
[PULL 83/85] hw/pci-host/astro: Trigger CPU irq on CPU HPA in high memory
From: Helge Deller The CPU HPA is in the high F-region on PA2.0 CPUs, so use F_EXTEND() to trigger interrupt request at the right CPU HPA address. Note that the cpu_hpa value comes out of the IRT, which doesn't store the higher addresss bits. Signed-off-by: Helge Deller --- hw/pci-host/astro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/pci-host/astro.c b/hw/pci-host/astro.c index df61386bd9..b19f0917c5 100644 --- a/hw/pci-host/astro.c +++ b/hw/pci-host/astro.c @@ -384,7 +384,7 @@ static void elroy_set_irq(void *opaque, int irq, int level) uint32_t ena = bit & ~old_ilr; s->ilr = old_ilr | bit; if (ena != 0) { -stl_be_phys(&address_space_memory, cpu_hpa, val & 63); +stl_be_phys(&address_space_memory, F_EXTEND(cpu_hpa), val & 63); } } else { s->ilr = old_ilr & ~bit; -- 2.34.1
[PULL 68/85] target/hppa: Fix interruption based on default PSW
From: Helge Deller The default PSW is set by the operating system with the PDC_PSW firmware call. Use that setting to decide if wide mode is to be enabled for interruptions and EIRR usage. Signed-off-by: Helge Deller Reviewed-by: Richard Henderson Signed-off-by: Richard Henderson --- target/hppa/cpu.h| 2 ++ target/hppa/int_helper.c | 18 ++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index ea676ba062..ea8e7e99a4 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -137,6 +137,8 @@ #define PSW_SM_W 0x200 /* PA2.0 only : Enable Wide Mode */ #define CR_RC0 +#define CR_PSW_DEFAULT 6 /* see SeaBIOS PDC_PSW firmware call */ +#define PDC_PSW_WIDE_BIT 2 #define CR_PID1 8 #define CR_PID2 9 #define CR_PID3 12 diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c index f355c4c76b..a11d607b31 100644 --- a/target/hppa/int_helper.c +++ b/target/hppa/int_helper.c @@ -52,9 +52,17 @@ static void io_eir_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) { HPPACPU *cpu = opaque; -int le_bit = ~data & 31; +CPUHPPAState *env = &cpu->env; +int widthm1 = 31; +int le_bit; -cpu->env.cr[CR_EIRR] |= (target_ulong)1 << le_bit; +/* The default PSW.W controls the width of EIRR. */ +if (hppa_is_pa20(env) && env->cr[CR_PSW_DEFAULT] & PDC_PSW_WIDE_BIT) { +widthm1 = 63; +} +le_bit = ~data & widthm1; + +env->cr[CR_EIRR] |= 1ull << le_bit; eval_interrupt(cpu); } @@ -104,8 +112,10 @@ void hppa_cpu_do_interrupt(CPUState *cs) /* step 1 */ env->cr[CR_IPSW] = old_psw = cpu_hppa_get_psw(env); -/* step 2 -- note PSW_W == 0 for !HPPA64. */ -cpu_hppa_put_psw(env, PSW_W | (i == EXCP_HPMC ? PSW_M : 0)); +/* step 2 -- Note PSW_W is masked out again for pa1.x */ +cpu_hppa_put_psw(env, + (env->cr[CR_PSW_DEFAULT] & PDC_PSW_WIDE_BIT ? PSW_W : 0) | + (i == EXCP_HPMC ? PSW_M : 0)); /* step 3 */ env->cr[CR_IIASQ] = iasq_f >> 32; -- 2.34.1
[PULL 41/85] target/hppa: Decode d for add instructions
Signed-off-by: Richard Henderson --- target/hppa/insns.decode | 16 target/hppa/translate.c | 21 +++-- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index d4a03b0299..0f29869949 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -62,7 +62,7 @@ &rr_cf_dt r cf d &rrr_cf t r1 r2 cf &rrr_cf_d t r1 r2 cf d -&rrr_cf_sh t r1 r2 cf sh +&rrr_cf_d_sht r1 r2 cf d sh &rri_cf t r i cf &rri_cf_d t r i cf d @@ -76,8 +76,8 @@ @rr_cf_d.. r:5 . cf:4 .. d:1 t:5&rr_cf_d @rrr_cf .. r2:5 r1:5 cf:4 ... t:5 &rrr_cf @rrr_cf_d .. r2:5 r1:5 cf:4 .. d:1 t:5&rrr_cf_d -@rrr_cf_sh .. r2:5 r1:5 cf:4 sh:2 . t:5 &rrr_cf_sh -@rrr_cf_sh0 .. r2:5 r1:5 cf:4 ... t:5 &rrr_cf_sh sh=0 +@rrr_cf_d_sh.. r2:5 r1:5 cf:4 sh:2 d:1 t:5 &rrr_cf_d_sh +@rrr_cf_d_sh0 .. r2:5 r1:5 cf:4 .. d:1 t:5&rrr_cf_d_sh sh=0 @rri_cf .. r:5 t:5 cf:4 . ... &rri_cf i=%lowsign_11 @rri_cf_d .. r:5 t:5 cf:4 d:1 ... &rri_cf_d i=%lowsign_11 @@ -166,11 +166,11 @@ uaddcm_tc 10 . . 100111 . . @rrr_cf_d dcor10 . 0 101110 . . @rr_cf_d dcor_i 10 . 0 10 . . @rr_cf_d -add 10 . . 0110.. - . @rrr_cf_sh -add_l 10 . . 1010.. 0 . @rrr_cf_sh -add_tsv 10 . . 1110.. 0 . @rrr_cf_sh -add_c 10 . . 011100 0 . @rrr_cf_sh0 -add_c_tsv 10 . . 00 0 . @rrr_cf_sh0 +add 10 . . 0110.. . . @rrr_cf_d_sh +add_l 10 . . 1010.. . . @rrr_cf_d_sh +add_tsv 10 . . 1110.. . . @rrr_cf_d_sh +add_c 10 . . 011100 . . @rrr_cf_d_sh0 +add_c_tsv 10 . . 00 . . @rrr_cf_d_sh0 sub 10 . . 01 - . @rrr_cf sub_tsv 10 . . 11 0 . @rrr_cf diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 8301d007ff..2f5cc597ad 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -1186,12 +1186,11 @@ static TCGv_reg do_sub_sv(DisasContext *ctx, TCGv_reg res, static void do_add(DisasContext *ctx, unsigned rt, TCGv_reg in1, TCGv_reg in2, unsigned shift, bool is_l, - bool is_tsv, bool is_tc, bool is_c, unsigned cf) + bool is_tsv, bool is_tc, bool is_c, unsigned cf, bool d) { TCGv_reg dest, cb, cb_msb, cb_cond, sv, tmp; unsigned c = cf >> 1; DisasCond cond; -bool d = false; dest = tcg_temp_new(); cb = NULL; @@ -1256,7 +1255,7 @@ static void do_add(DisasContext *ctx, unsigned rt, TCGv_reg in1, ctx->null_cond = cond; } -static bool do_add_reg(DisasContext *ctx, arg_rrr_cf_sh *a, +static bool do_add_reg(DisasContext *ctx, arg_rrr_cf_d_sh *a, bool is_l, bool is_tsv, bool is_tc, bool is_c) { TCGv_reg tcg_r1, tcg_r2; @@ -1266,7 +1265,8 @@ static bool do_add_reg(DisasContext *ctx, arg_rrr_cf_sh *a, } tcg_r1 = load_gpr(ctx, a->r1); tcg_r2 = load_gpr(ctx, a->r2); -do_add(ctx, a->t, tcg_r1, tcg_r2, a->sh, is_l, is_tsv, is_tc, is_c, a->cf); +do_add(ctx, a->t, tcg_r1, tcg_r2, a->sh, is_l, + is_tsv, is_tc, is_c, a->cf, a->d); return nullify_end(ctx); } @@ -1280,7 +1280,8 @@ static bool do_add_imm(DisasContext *ctx, arg_rri_cf *a, } tcg_im = tcg_constant_reg(a->i); tcg_r2 = load_gpr(ctx, a->r); -do_add(ctx, a->t, tcg_im, tcg_r2, 0, 0, is_tsv, is_tc, 0, a->cf); +/* All ADDI conditions are 32-bit. */ +do_add(ctx, a->t, tcg_im, tcg_r2, 0, 0, is_tsv, is_tc, 0, a->cf, false); return nullify_end(ctx); } @@ -2635,27 +2636,27 @@ static bool trans_lci(DisasContext *ctx, arg_lci *a) return true; } -static bool trans_add(DisasContext *ctx, arg_rrr_cf_sh *a) +static bool trans_add(DisasContext *ctx, arg_rrr_cf_d_sh *a) { return do_add_reg(ctx, a, false, false, false, false); } -static bool trans_add_l(DisasContext *ctx, arg_rrr_cf_sh *a) +static bool trans_add_l(DisasContext *ctx, arg_rrr_cf_d_sh *a) { return do_add_reg(ctx, a, true, false, false, false); } -static bool trans_add_tsv(DisasContext *ctx, arg_rrr_cf_sh *a) +static bool trans_add_tsv(DisasContext *ctx, arg_rrr_cf_d_sh *a) { return do_add_reg(ctx, a, false, true, false, false); } -static bool trans_add_c(DisasContext *ctx, arg_rrr_cf_sh *a) +static bool trans_add_c(DisasContext *ctx, arg_rrr_cf_d_sh *a) { return do_add_reg(ctx, a, false, false, false, true); } -static bool trans_add_c_tsv(DisasCont
[PULL 56/85] target/hppa: Remove most of the TARGET_REGISTER_BITS redirections
Remove all but those intended to change type to or from i64. Signed-off-by: Richard Henderson --- target/hppa/translate.c | 910 ++-- 1 file changed, 406 insertions(+), 504 deletions(-) diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 0172c2f898..ec3f70e46e 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -36,110 +36,15 @@ /* Since we have a distinction between register size and address size, we need to redefine all of these. */ -#undef TCGv -#undef tcg_temp_new -#undef tcg_global_mem_new - -#define TCGv_tl TCGv_i64 -#define tcg_temp_new_tl tcg_temp_new_i64 #define tcg_gen_extu_reg_tl tcg_gen_mov_i64 - -#define TCGv_reg TCGv_i64 - -#define tcg_temp_new tcg_temp_new_i64 -#define tcg_global_mem_new tcg_global_mem_new_i64 - -#define tcg_gen_movi_reg tcg_gen_movi_i64 -#define tcg_gen_mov_reg tcg_gen_mov_i64 -#define tcg_gen_ld8u_reg tcg_gen_ld8u_i64 -#define tcg_gen_ld8s_reg tcg_gen_ld8s_i64 -#define tcg_gen_ld16u_regtcg_gen_ld16u_i64 -#define tcg_gen_ld16s_regtcg_gen_ld16s_i64 -#define tcg_gen_ld32u_regtcg_gen_ld32u_i64 -#define tcg_gen_ld32s_regtcg_gen_ld32s_i64 -#define tcg_gen_ld_reg tcg_gen_ld_i64 -#define tcg_gen_st8_reg tcg_gen_st8_i64 -#define tcg_gen_st16_reg tcg_gen_st16_i64 -#define tcg_gen_st32_reg tcg_gen_st32_i64 -#define tcg_gen_st_reg tcg_gen_st_i64 -#define tcg_gen_add_reg tcg_gen_add_i64 -#define tcg_gen_addi_reg tcg_gen_addi_i64 -#define tcg_gen_sub_reg tcg_gen_sub_i64 -#define tcg_gen_neg_reg tcg_gen_neg_i64 -#define tcg_gen_subfi_regtcg_gen_subfi_i64 -#define tcg_gen_subi_reg tcg_gen_subi_i64 -#define tcg_gen_and_reg tcg_gen_and_i64 -#define tcg_gen_andi_reg tcg_gen_andi_i64 -#define tcg_gen_or_reg tcg_gen_or_i64 -#define tcg_gen_ori_reg tcg_gen_ori_i64 -#define tcg_gen_xor_reg tcg_gen_xor_i64 -#define tcg_gen_xori_reg tcg_gen_xori_i64 -#define tcg_gen_not_reg tcg_gen_not_i64 -#define tcg_gen_shl_reg tcg_gen_shl_i64 -#define tcg_gen_shli_reg tcg_gen_shli_i64 -#define tcg_gen_shr_reg tcg_gen_shr_i64 -#define tcg_gen_shri_reg tcg_gen_shri_i64 -#define tcg_gen_sar_reg tcg_gen_sar_i64 -#define tcg_gen_sari_reg tcg_gen_sari_i64 -#define tcg_gen_brcond_reg tcg_gen_brcond_i64 -#define tcg_gen_brcondi_reg tcg_gen_brcondi_i64 -#define tcg_gen_setcond_reg tcg_gen_setcond_i64 -#define tcg_gen_setcondi_reg tcg_gen_setcondi_i64 -#define tcg_gen_mul_reg tcg_gen_mul_i64 -#define tcg_gen_muli_reg tcg_gen_muli_i64 -#define tcg_gen_div_reg tcg_gen_div_i64 -#define tcg_gen_rem_reg tcg_gen_rem_i64 -#define tcg_gen_divu_reg tcg_gen_divu_i64 -#define tcg_gen_remu_reg tcg_gen_remu_i64 -#define tcg_gen_discard_reg tcg_gen_discard_i64 -#define tcg_gen_trunc_reg_i32 tcg_gen_extrl_i64_i32 #define tcg_gen_trunc_i64_reg tcg_gen_mov_i64 -#define tcg_gen_extu_i32_reg tcg_gen_extu_i32_i64 -#define tcg_gen_ext_i32_reg tcg_gen_ext_i32_i64 #define tcg_gen_extu_reg_i64 tcg_gen_mov_i64 #define tcg_gen_ext_reg_i64 tcg_gen_mov_i64 -#define tcg_gen_ext8u_regtcg_gen_ext8u_i64 -#define tcg_gen_ext8s_regtcg_gen_ext8s_i64 -#define tcg_gen_ext16u_reg tcg_gen_ext16u_i64 -#define tcg_gen_ext16s_reg tcg_gen_ext16s_i64 -#define tcg_gen_ext32u_reg tcg_gen_ext32u_i64 -#define tcg_gen_ext32s_reg tcg_gen_ext32s_i64 -#define tcg_gen_bswap16_reg tcg_gen_bswap16_i64 -#define tcg_gen_bswap32_reg tcg_gen_bswap32_i64 -#define tcg_gen_bswap64_reg tcg_gen_bswap64_i64 -#define tcg_gen_concat_reg_i64 tcg_gen_concat32_i64 -#define tcg_gen_andc_reg tcg_gen_andc_i64 -#define tcg_gen_eqv_reg tcg_gen_eqv_i64 -#define tcg_gen_nand_reg tcg_gen_nand_i64 -#define tcg_gen_nor_reg tcg_gen_nor_i64 -#define tcg_gen_orc_reg tcg_gen_orc_i64 -#define tcg_gen_clz_reg tcg_gen_clz_i64 -#define tcg_gen_ctz_reg tcg_gen_ctz_i64 -#define tcg_gen_clzi_reg tcg_gen_clzi_i64 -#define tcg_gen_ctzi_reg tcg_gen_ctzi_i64 -#define tcg_gen_clrsb_regtcg_gen_clrsb_i64 -#define tcg_gen_ctpop_regtcg_gen_ctpop_i64 -#define tcg_gen_rotl_reg tcg_gen_rotl_i64 -#define tcg_gen_rotli_regtcg_gen_rotli_i64 -#define tcg_gen_rotr_reg tcg_gen_rotr_i64 -#define tcg_gen_rotri_regtcg_gen_rotri_i64 -#define tcg_gen_deposit_reg tcg_gen_deposit_i64 -#define tcg_gen_deposit_z_reg tcg_gen_deposit_z_i64 -#define tcg_gen_extract_reg tcg_gen_extract_i64 -#define tcg_gen_sextract_reg tcg_gen_sextract_i64 -#define tcg_gen_extract2_reg tcg_gen_extract2_i64 -#define tcg_constant_reg tcg_constant_i64 -#define tcg_gen_movcond_reg tcg_gen_movcond_i64 -#define tcg_gen_add2_reg tcg_gen_add2_i64 -#define tcg_gen_sub2_reg tcg_gen_sub2_i64 -#define tcg_gen_qemu_ld_reg tcg_gen_qemu_ld_i64 -#define tcg_gen_qemu_st_reg tcg_gen_qemu_st_i64 -#define tcg_gen_atomic_xchg_reg tcg_gen_atomic_xchg_i64 -#define tcg_gen_trunc
[PULL 85/85] hw/hppa: Allow C3700 with 64-bit and B160L with 32-bit CPU only
From: Helge Deller Prevent that users try to boot a 64-bit only C3700 machine with a 32-bit CPU, and to boot a 32-bit only B160L machine with a 64-bit CPU. Signed-off-by: Helge Deller --- hw/hppa/machine.c | 24 1 file changed, 24 insertions(+) diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index da9ca85806..a3222d3a96 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -528,6 +528,12 @@ static void machine_HP_B160L_init(MachineState *machine) /* Create CPUs and RAM. */ translate = machine_HP_common_init_cpus(machine); +if (hppa_is_pa20(&cpu[0]->env)) { +error_report("The HP B160L workstation requires a 32-bit " + "CPU. Use '-machine C3700' instead."); +exit(1); +} + /* Init Lasi chip */ lasi_dev = DEVICE(lasi_init()); memory_region_add_subregion(addr_space, translate(NULL, LASI_HPA), @@ -602,6 +608,12 @@ static void machine_HP_C3700_init(MachineState *machine) /* Create CPUs and RAM. */ translate = machine_HP_common_init_cpus(machine); +if (!hppa_is_pa20(&cpu[0]->env)) { +error_report("The HP C3000 workstation requires a 64-bit CPU. " + "Use '-machine B160L' instead."); +exit(1); +} + /* Init Astro and the Elroys (PCI host bus chips). */ astro = astro_init(); astro_dev = DEVICE(astro); @@ -659,6 +671,11 @@ static void hppa_nmi(NMIState *n, int cpu_index, Error **errp) } } +static const char *HP_B160L_machine_valid_cpu_types[] = { +TYPE_HPPA_CPU, +NULL +}; + static void HP_B160L_machine_init_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -666,6 +683,7 @@ static void HP_B160L_machine_init_class_init(ObjectClass *oc, void *data) mc->desc = "HP B160L workstation"; mc->default_cpu_type = TYPE_HPPA_CPU; +mc->valid_cpu_types = HP_B160L_machine_valid_cpu_types; mc->init = machine_HP_B160L_init; mc->reset = hppa_machine_reset; mc->block_default_type = IF_SCSI; @@ -690,6 +708,11 @@ static const TypeInfo HP_B160L_machine_init_typeinfo = { }, }; +static const char *HP_C3700_machine_valid_cpu_types[] = { +TYPE_HPPA64_CPU, +NULL +}; + static void HP_C3700_machine_init_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -697,6 +720,7 @@ static void HP_C3700_machine_init_class_init(ObjectClass *oc, void *data) mc->desc = "HP C3700 workstation"; mc->default_cpu_type = TYPE_HPPA64_CPU; +mc->valid_cpu_types = HP_C3700_machine_valid_cpu_types; mc->init = machine_HP_C3700_init; mc->reset = hppa_machine_reset; mc->block_default_type = IF_SCSI; -- 2.34.1
[PULL 42/85] target/hppa: Decode d for sub instructions
Signed-off-by: Richard Henderson --- target/hppa/insns.decode | 12 ++-- target/hppa/translate.c | 22 +++--- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index 0f29869949..ad454adcbb 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -172,12 +172,12 @@ add_tsv 10 . . 1110.. . . @rrr_cf_d_sh add_c 10 . . 011100 . . @rrr_cf_d_sh0 add_c_tsv 10 . . 00 . . @rrr_cf_d_sh0 -sub 10 . . 01 - . @rrr_cf -sub_tsv 10 . . 11 0 . @rrr_cf -sub_tc 10 . . 010011 0 . @rrr_cf -sub_tsv_tc 10 . . 110011 0 . @rrr_cf -sub_b 10 . . 010100 0 . @rrr_cf -sub_b_tsv 10 . . 110100 0 . @rrr_cf +sub 10 . . 01 . . @rrr_cf_d +sub_tsv 10 . . 11 . . @rrr_cf_d +sub_tc 10 . . 010011 . . @rrr_cf_d +sub_tsv_tc 10 . . 110011 . . @rrr_cf_d +sub_b 10 . . 010100 . . @rrr_cf_d +sub_b_tsv 10 . . 110100 . . @rrr_cf_d ldil001000 t:5 .i=%assemble_21 addil 001010 r:5 .i=%assemble_21 diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 2f5cc597ad..f2b2933c88 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -1287,12 +1287,11 @@ static bool do_add_imm(DisasContext *ctx, arg_rri_cf *a, static void do_sub(DisasContext *ctx, unsigned rt, TCGv_reg in1, TCGv_reg in2, bool is_tsv, bool is_b, - bool is_tc, unsigned cf) + bool is_tc, unsigned cf, bool d) { TCGv_reg dest, sv, cb, cb_msb, zero, tmp; unsigned c = cf >> 1; DisasCond cond; -bool d = false; dest = tcg_temp_new(); cb = tcg_temp_new(); @@ -1350,7 +1349,7 @@ static void do_sub(DisasContext *ctx, unsigned rt, TCGv_reg in1, ctx->null_cond = cond; } -static bool do_sub_reg(DisasContext *ctx, arg_rrr_cf *a, +static bool do_sub_reg(DisasContext *ctx, arg_rrr_cf_d *a, bool is_tsv, bool is_b, bool is_tc) { TCGv_reg tcg_r1, tcg_r2; @@ -1360,7 +1359,7 @@ static bool do_sub_reg(DisasContext *ctx, arg_rrr_cf *a, } tcg_r1 = load_gpr(ctx, a->r1); tcg_r2 = load_gpr(ctx, a->r2); -do_sub(ctx, a->t, tcg_r1, tcg_r2, is_tsv, is_b, is_tc, a->cf); +do_sub(ctx, a->t, tcg_r1, tcg_r2, is_tsv, is_b, is_tc, a->cf, a->d); return nullify_end(ctx); } @@ -1373,7 +1372,8 @@ static bool do_sub_imm(DisasContext *ctx, arg_rri_cf *a, bool is_tsv) } tcg_im = tcg_constant_reg(a->i); tcg_r2 = load_gpr(ctx, a->r); -do_sub(ctx, a->t, tcg_im, tcg_r2, is_tsv, 0, 0, a->cf); +/* All SUBI conditions are 32-bit. */ +do_sub(ctx, a->t, tcg_im, tcg_r2, is_tsv, 0, 0, a->cf, false); return nullify_end(ctx); } @@ -2661,32 +2661,32 @@ static bool trans_add_c_tsv(DisasContext *ctx, arg_rrr_cf_d_sh *a) return do_add_reg(ctx, a, false, true, false, true); } -static bool trans_sub(DisasContext *ctx, arg_rrr_cf *a) +static bool trans_sub(DisasContext *ctx, arg_rrr_cf_d *a) { return do_sub_reg(ctx, a, false, false, false); } -static bool trans_sub_tsv(DisasContext *ctx, arg_rrr_cf *a) +static bool trans_sub_tsv(DisasContext *ctx, arg_rrr_cf_d *a) { return do_sub_reg(ctx, a, true, false, false); } -static bool trans_sub_tc(DisasContext *ctx, arg_rrr_cf *a) +static bool trans_sub_tc(DisasContext *ctx, arg_rrr_cf_d *a) { return do_sub_reg(ctx, a, false, false, true); } -static bool trans_sub_tsv_tc(DisasContext *ctx, arg_rrr_cf *a) +static bool trans_sub_tsv_tc(DisasContext *ctx, arg_rrr_cf_d *a) { return do_sub_reg(ctx, a, true, false, true); } -static bool trans_sub_b(DisasContext *ctx, arg_rrr_cf *a) +static bool trans_sub_b(DisasContext *ctx, arg_rrr_cf_d *a) { return do_sub_reg(ctx, a, false, true, false); } -static bool trans_sub_b_tsv(DisasContext *ctx, arg_rrr_cf *a) +static bool trans_sub_b_tsv(DisasContext *ctx, arg_rrr_cf_d *a) { return do_sub_reg(ctx, a, true, true, false); } -- 2.34.1
[PULL 47/85] target/hppa: Implement LDD, LDCD, LDDA, STD, STDA
Signed-off-by: Richard Henderson --- target/hppa/insns.decode | 15 +++ target/hppa/translate.c | 4 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index 48f09c9b06..33eec3f4c3 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -215,9 +215,14 @@ ld 11 . . .. . 0 -- 00 size:2 .. @ldstx st 11 . . .. . 1 -- 10 size:2 .. @stim5 ldc 11 . . .. . 1 -- 0111 .. @ldim5 size=2 ldc 11 . . .. . 0 -- 0111 .. @ldstx size=2 +ldc 11 . . .. . 1 -- 0101 .. @ldim5 size=3 +ldc 11 . . .. . 0 -- 0101 .. @ldstx size=3 lda 11 . . .. . 1 -- 0110 .. @ldim5 size=2 lda 11 . . .. . 0 -- 0110 .. @ldstx size=2 +lda 11 . . .. . 1 -- 0100 .. @ldim5 size=3 +lda 11 . . .. . 0 -- 0100 .. @ldstx size=3 sta 11 . . .. . 1 -- 1110 .. @stim5 size=2 +sta 11 . . .. . 1 -- .. @stim5 size=3 stby11 b:5 r:5 sp:2 a:1 1 -- 1100 m:1 . disp=%im5_0 @fldstwx.. b:5 x:5 sp:2 scale:1 ... m:1 . \ @@ -244,6 +249,8 @@ fstd001011 . . .. . 1 -- 100 0 . . @fldstdi # Offset Mem +@ldstim11 .. b:5 t:5 sp:2 .. \ +&ldst disp=%assemble_11a m=%ma2_to_m x=0 scale=0 size=3 @ldstim14 .. b:5 t:5 sp:2 .. \ &ldst disp=%lowsign_14 x=0 scale=0 m=0 @ldstim14m .. b:5 t:5 sp:2 .. \ @@ -275,11 +282,11 @@ fstw00 b:5 . sp:2 ..\ fstw01 b:5 . sp:2 ...0..\ &ldst disp=%assemble_12a t=%rm64 m=0 x=0 scale=0 size=2 -fldd010100 b:5 t:5 sp:2 .. .. 1 . \ -&ldst disp=%assemble_11a m=%ma2_to_m x=0 scale=0 size=3 +ld 010100 . . .. 0.@ldstim11 +fldd010100 . . .. 1.@ldstim11 -fstd011100 b:5 t:5 sp:2 .. .. 1 . \ -&ldst disp=%assemble_11a m=%ma2_to_m x=0 scale=0 size=3 +st 011100 . . .. 0.@ldstim11 +fstd011100 . . .. 1.@ldstim11 # Floating-point Multiply Add diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 1b4fa401ba..4562f865f4 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -2972,6 +2972,10 @@ static bool trans_ldc(DisasContext *ctx, arg_ldst *a) TCGv_reg zero, dest, ofs; TCGv_tl addr; +if (unlikely(TARGET_REGISTER_BITS == 32 && a->size > MO_32)) { +return gen_illegal(ctx); +} + nullify_over(ctx); if (a->m) { -- 2.34.1
[PULL 50/85] target/hppa: Implement SHRPD
Signed-off-by: Richard Henderson --- target/hppa/insns.decode | 6 ++- target/hppa/translate.c | 97 2 files changed, 72 insertions(+), 31 deletions(-) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index 7b51f39b9e..6f0c3f6ea5 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -332,8 +332,10 @@ addbi 101011 . . ... ... . . @rib_cf f=1 # Shift, Extract, Deposit -shrpw_sar 110100 r2:5 r1:5 c:3 00 00 t:5 -shrpw_imm 110100 r2:5 r1:5 c:3 01 0cpos:5 t:5 +shrp_sar110100 r2:5 r1:5 c:3 00 0 d:1 t:5 +shrp_imm110100 r2:5 r1:5 c:3 01 0 cpos:5t:5 d=0 +shrp_imm110100 r2:5 r1:5 c:3 0. 1 . t:5 \ +d=1 cpos=%cpos6_11 extr_sar110100 r:5 t:5 c:3 10 se:1 00 000 . d=0 len=%len5 extr_sar110100 r:5 t:5 c:3 10 se:1 1. 000 . d=1 len=%len6_8 diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 533e29879e..897b44d7e3 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -3279,34 +3279,64 @@ static bool trans_movbi(DisasContext *ctx, arg_movbi *a) return do_cbranch(ctx, a->disp, a->n, &cond); } -static bool trans_shrpw_sar(DisasContext *ctx, arg_shrpw_sar *a) +static bool trans_shrp_sar(DisasContext *ctx, arg_shrp_sar *a) { -TCGv_reg dest; +TCGv_reg dest, src2; +if (!ctx->is_pa20 && a->d) { +return false; +} if (a->c) { nullify_over(ctx); } dest = dest_gpr(ctx, a->t); +src2 = load_gpr(ctx, a->r2); if (a->r1 == 0) { -tcg_gen_ext32u_reg(dest, load_gpr(ctx, a->r2)); -tcg_gen_shr_reg(dest, dest, cpu_sar); +if (a->d) { +tcg_gen_shr_reg(dest, src2, cpu_sar); +} else { +TCGv_reg tmp = tcg_temp_new(); + +tcg_gen_ext32u_reg(dest, src2); +tcg_gen_andi_reg(tmp, cpu_sar, 31); +tcg_gen_shr_reg(dest, dest, tmp); +} } else if (a->r1 == a->r2) { -TCGv_i32 t32 = tcg_temp_new_i32(); -TCGv_i32 s32 = tcg_temp_new_i32(); +if (a->d) { +tcg_gen_rotr_reg(dest, src2, cpu_sar); +} else { +TCGv_i32 t32 = tcg_temp_new_i32(); +TCGv_i32 s32 = tcg_temp_new_i32(); -tcg_gen_trunc_reg_i32(t32, load_gpr(ctx, a->r2)); -tcg_gen_trunc_reg_i32(s32, cpu_sar); -tcg_gen_rotr_i32(t32, t32, s32); -tcg_gen_extu_i32_reg(dest, t32); +tcg_gen_trunc_reg_i32(t32, src2); +tcg_gen_trunc_reg_i32(s32, cpu_sar); +tcg_gen_andi_i32(s32, s32, 31); +tcg_gen_rotr_i32(t32, t32, s32); +tcg_gen_extu_i32_reg(dest, t32); +} } else { -TCGv_i64 t = tcg_temp_new_i64(); -TCGv_i64 s = tcg_temp_new_i64(); +TCGv_reg src1 = load_gpr(ctx, a->r1); -tcg_gen_concat_reg_i64(t, load_gpr(ctx, a->r2), load_gpr(ctx, a->r1)); -tcg_gen_extu_reg_i64(s, cpu_sar); -tcg_gen_shr_i64(t, t, s); -tcg_gen_trunc_i64_reg(dest, t); +if (a->d) { +TCGv_reg t = tcg_temp_new(); +TCGv_reg n = tcg_temp_new(); + +tcg_gen_xori_reg(n, cpu_sar, 63); +tcg_gen_shl_reg(t, src2, n); +tcg_gen_shli_reg(t, t, 1); +tcg_gen_shr_reg(dest, src1, cpu_sar); +tcg_gen_or_reg(dest, dest, t); +} else { +TCGv_i64 t = tcg_temp_new_i64(); +TCGv_i64 s = tcg_temp_new_i64(); + +tcg_gen_concat_reg_i64(t, src2, src1); +tcg_gen_extu_reg_i64(s, cpu_sar); +tcg_gen_andi_i64(s, s, 31); +tcg_gen_shr_i64(t, t, s); +tcg_gen_trunc_i64_reg(dest, t); +} } save_gpr(ctx, a->t, dest); @@ -3318,31 +3348,40 @@ static bool trans_shrpw_sar(DisasContext *ctx, arg_shrpw_sar *a) return nullify_end(ctx); } -static bool trans_shrpw_imm(DisasContext *ctx, arg_shrpw_imm *a) +static bool trans_shrp_imm(DisasContext *ctx, arg_shrp_imm *a) { -unsigned sa = 31 - a->cpos; +unsigned width, sa; TCGv_reg dest, t2; +if (!ctx->is_pa20 && a->d) { +return false; +} if (a->c) { nullify_over(ctx); } +width = a->d ? 64 : 32; +sa = width - 1 - a->cpos; + dest = dest_gpr(ctx, a->t); t2 = load_gpr(ctx, a->r2); if (a->r1 == 0) { -tcg_gen_extract_reg(dest, t2, sa, 32 - sa); -} else if (TARGET_REGISTER_BITS == 32) { +tcg_gen_extract_reg(dest, t2, sa, width - sa); +} else if (width == TARGET_REGISTER_BITS) { tcg_gen_extract2_reg(dest, t2, cpu_gr[a->r1], sa); -} else if (a->r1 == a->r2) { -TCGv_i32 t32 = tcg_temp_new_i32(); -tcg_gen_trunc_reg_i32(t32, t2); -tcg_gen_rotri_i32(t32, t32, sa); -tcg_gen_extu_i32_reg(dest, t32); } else { -TCGv_i64 t64 = tcg_temp_new_i
[PULL 74/85] target/hppa: Implement pa2.0 data prefetch instructions
These are aliased onto the normal integer loads to %g0. Since we don't emulate caches, prefetch is a nop. Signed-off-by: Richard Henderson --- target/hppa/translate.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/target/hppa/translate.c b/target/hppa/translate.c index ba15cf6ab8..e7f379d648 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -2976,7 +2976,15 @@ static bool trans_permh(DisasContext *ctx, arg_permh *a) static bool trans_ld(DisasContext *ctx, arg_ldst *a) { -if (!ctx->is_pa20 && a->size > MO_32) { +if (ctx->is_pa20) { + /* +* With pa20, LDB, LDH, LDW, LDD to %g0 are prefetches. +* Any base modification still occurs. +*/ +if (a->t == 0) { +return trans_nop_addrx(ctx, a); +} +} else if (a->size > MO_32) { return gen_illegal(ctx); } return do_load(ctx, a->t, a->b, a->x, a->scale ? a->size : 0, -- 2.34.1
[PULL 44/85] target/hppa: Decode d for cmpb instructions
Signed-off-by: Richard Henderson --- target/hppa/insns.decode | 9 +++-- target/hppa/translate.c | 12 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index b185523021..fc327e2bb3 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -67,6 +67,7 @@ &rri_cf_d t r i cf d &rrb_c_fdisp n c f r1 r2 +&rrb_c_d_f disp n c d f r1 r2 &rib_c_fdisp n c f r i @@ -83,6 +84,8 @@ @rrb_cf .. r2:5 r1:5 c:3 ... n:1 . \ &rrb_c_f disp=%assemble_12 +@rrb_cdf.. r2:5 r1:5 c:3 ... n:1 . \ +&rrb_c_d_f disp=%assemble_12 @rib_cf .. r:5 . c:3 ... n:1 . \ &rib_c_f disp=%assemble_12 i=%im5_16 @@ -296,8 +299,10 @@ bb_imm 110001 p:5 r:5 c:1 1 d:1 ... n:1 . disp=%assemble_12 movb110010 . . ... ... . . @rrb_cf f=0 movbi 110011 . . ... ... . . @rib_cf f=0 -cmpb10 . . ... ... . . @rrb_cf f=0 -cmpb100010 . . ... ... . . @rrb_cf f=1 +cmpb10 . . ... ... . . @rrb_cdf d=0 f=0 +cmpb100010 . . ... ... . . @rrb_cdf d=0 f=1 +cmpb100111 . . ... ... . . @rrb_cdf d=1 f=0 +cmpb10 . . ... ... . . @rrb_cdf d=1 f=1 cmpbi 11 . . ... ... . . @rib_cf f=0 cmpbi 100011 . . ... ... . . @rib_cf f=1 diff --git a/target/hppa/translate.c b/target/hppa/translate.c index e326f63866..6cd06fbc0d 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -3091,11 +3091,10 @@ static bool trans_ldo(DisasContext *ctx, arg_ldo *a) } static bool do_cmpb(DisasContext *ctx, unsigned r, TCGv_reg in1, -unsigned c, unsigned f, unsigned n, int disp) +unsigned c, unsigned f, bool d, unsigned n, int disp) { TCGv_reg dest, in2, sv; DisasCond cond; -bool d = false; in2 = load_gpr(ctx, r); dest = tcg_temp_new(); @@ -3113,14 +3112,19 @@ static bool do_cmpb(DisasContext *ctx, unsigned r, TCGv_reg in1, static bool trans_cmpb(DisasContext *ctx, arg_cmpb *a) { +if (!ctx->is_pa20 && a->d) { +return false; +} nullify_over(ctx); -return do_cmpb(ctx, a->r2, load_gpr(ctx, a->r1), a->c, a->f, a->n, a->disp); +return do_cmpb(ctx, a->r2, load_gpr(ctx, a->r1), + a->c, a->f, a->d, a->n, a->disp); } static bool trans_cmpbi(DisasContext *ctx, arg_cmpbi *a) { nullify_over(ctx); -return do_cmpb(ctx, a->r, tcg_constant_reg(a->i), a->c, a->f, a->n, a->disp); +return do_cmpb(ctx, a->r, tcg_constant_reg(a->i), + a->c, a->f, false, a->n, a->disp); } static bool do_addb(DisasContext *ctx, unsigned r, TCGv_reg in1, -- 2.34.1
[PULL 49/85] target/hppa: Implement EXTRD
Signed-off-by: Richard Henderson --- target/hppa/insns.decode | 7 +-- target/hppa/translate.c | 42 +--- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index 12684b590e..7b51f39b9e 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -335,8 +335,11 @@ addbi 101011 . . ... ... . . @rib_cf f=1 shrpw_sar 110100 r2:5 r1:5 c:3 00 00 t:5 shrpw_imm 110100 r2:5 r1:5 c:3 01 0cpos:5 t:5 -extrw_sar 110100 r:5 t:5 c:3 10 se:1 0 clen:5 -extrw_imm 110100 r:5 t:5 c:3 11 se:1 pos:5 clen:5 +extr_sar110100 r:5 t:5 c:3 10 se:1 00 000 . d=0 len=%len5 +extr_sar110100 r:5 t:5 c:3 10 se:1 1. 000 . d=1 len=%len6_8 +extr_imm110100 r:5 t:5 c:3 11 se:1 pos:5 . d=0 len=%len5 +extr_imm110110 r:5 t:5 c:3 .. se:1 . . \ +d=1 len=%len6_12 pos=%cpos6_11 dep_sar 110101 t:5 r:5 c:3 00 nz:1 00 000 . d=0 len=%len5 dep_sar 110101 t:5 r:5 c:3 00 nz:1 1. 000 . d=1 len=%len6_8 diff --git a/target/hppa/translate.c b/target/hppa/translate.c index ea2150cc55..533e29879e 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -3354,11 +3354,14 @@ static bool trans_shrpw_imm(DisasContext *ctx, arg_shrpw_imm *a) return nullify_end(ctx); } -static bool trans_extrw_sar(DisasContext *ctx, arg_extrw_sar *a) +static bool trans_extr_sar(DisasContext *ctx, arg_extr_sar *a) { -unsigned len = 32 - a->clen; +unsigned widthm1 = a->d ? 63 : 31; TCGv_reg dest, src, tmp; +if (!ctx->is_pa20 && a->d) { +return false; +} if (a->c) { nullify_over(ctx); } @@ -3368,36 +3371,53 @@ static bool trans_extrw_sar(DisasContext *ctx, arg_extrw_sar *a) tmp = tcg_temp_new(); /* Recall that SAR is using big-endian bit numbering. */ -tcg_gen_andi_reg(tmp, cpu_sar, 31); -tcg_gen_xori_reg(tmp, tmp, 31); +tcg_gen_andi_reg(tmp, cpu_sar, widthm1); +tcg_gen_xori_reg(tmp, tmp, widthm1); if (a->se) { +if (!a->d) { +tcg_gen_ext32s_reg(dest, src); +src = dest; +} tcg_gen_sar_reg(dest, src, tmp); -tcg_gen_sextract_reg(dest, dest, 0, len); +tcg_gen_sextract_reg(dest, dest, 0, a->len); } else { +if (!a->d) { +tcg_gen_ext32u_reg(dest, src); +src = dest; +} tcg_gen_shr_reg(dest, src, tmp); -tcg_gen_extract_reg(dest, dest, 0, len); +tcg_gen_extract_reg(dest, dest, 0, a->len); } save_gpr(ctx, a->t, dest); /* Install the new nullification. */ cond_free(&ctx->null_cond); if (a->c) { -ctx->null_cond = do_sed_cond(ctx, a->c, false, dest); +ctx->null_cond = do_sed_cond(ctx, a->c, a->d, dest); } return nullify_end(ctx); } -static bool trans_extrw_imm(DisasContext *ctx, arg_extrw_imm *a) +static bool trans_extr_imm(DisasContext *ctx, arg_extr_imm *a) { -unsigned len = 32 - a->clen; -unsigned cpos = 31 - a->pos; +unsigned len, cpos, width; TCGv_reg dest, src; +if (!ctx->is_pa20 && a->d) { +return false; +} if (a->c) { nullify_over(ctx); } +len = a->len; +width = a->d ? 64 : 32; +cpos = width - 1 - a->pos; +if (cpos + len > width) { +len = width - cpos; +} + dest = dest_gpr(ctx, a->t); src = load_gpr(ctx, a->r); if (a->se) { @@ -3410,7 +3430,7 @@ static bool trans_extrw_imm(DisasContext *ctx, arg_extrw_imm *a) /* Install the new nullification. */ cond_free(&ctx->null_cond); if (a->c) { -ctx->null_cond = do_sed_cond(ctx, a->c, false, dest); +ctx->null_cond = do_sed_cond(ctx, a->c, a->d, dest); } return nullify_end(ctx); } -- 2.34.1
[PULL 45/85] target/hppa: Decode CMPIB double-word
Signed-off-by: Richard Henderson --- target/hppa/insns.decode | 10 -- target/hppa/translate.c | 11 ++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index fc327e2bb3..48f09c9b06 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -51,6 +51,7 @@ %pos_to_m 0:1 !function=pos_to_m %neg_to_m 0:1 !function=neg_to_m %a_to_m 2:1 !function=neg_to_m +%cmpbid_c 13:2 !function=cmpbid_c # Argument set definitions @@ -69,6 +70,7 @@ &rrb_c_fdisp n c f r1 r2 &rrb_c_d_f disp n c d f r1 r2 &rib_c_fdisp n c f r i +&rib_c_d_f disp n c d f r i # Format definitions @@ -88,6 +90,8 @@ &rrb_c_d_f disp=%assemble_12 @rib_cf .. r:5 . c:3 ... n:1 . \ &rib_c_f disp=%assemble_12 i=%im5_16 +@rib_cdf.. r:5 . c:3 ... n:1 . \ +&rib_c_d_f disp=%assemble_12 i=%im5_16 # System @@ -303,8 +307,10 @@ cmpb10 . . ... ... . . @rrb_cdf d=0 f=0 cmpb100010 . . ... ... . . @rrb_cdf d=0 f=1 cmpb100111 . . ... ... . . @rrb_cdf d=1 f=0 cmpb10 . . ... ... . . @rrb_cdf d=1 f=1 -cmpbi 11 . . ... ... . . @rib_cf f=0 -cmpbi 100011 . . ... ... . . @rib_cf f=1 +cmpbi 11 . . ... ... . . @rib_cdf d=0 f=0 +cmpbi 100011 . . ... ... . . @rib_cdf d=0 f=1 +cmpbi 111011 r:5 . f:1 .. ... n:1 . \ +&rib_c_d_f d=1 disp=%assemble_12 c=%cmpbid_c i=%im5_16 addb101000 . . ... ... . . @rrb_cf f=0 addb101010 . . ... ... . . @rrb_cf f=1 diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 6cd06fbc0d..7f767fea64 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -329,6 +329,12 @@ static int expand_shl11(DisasContext *ctx, int val) return val << 11; } +/* Translate CMPI doubleword conditions to standard. */ +static int cmpbid_c(DisasContext *ctx, int val) +{ +return val ? val : 4; /* 0 == "*<<" */ +} + /* Include the auto-generated decoder. */ #include "decode-insns.c.inc" @@ -3122,9 +3128,12 @@ static bool trans_cmpb(DisasContext *ctx, arg_cmpb *a) static bool trans_cmpbi(DisasContext *ctx, arg_cmpbi *a) { +if (!ctx->is_pa20 && a->d) { +return false; +} nullify_over(ctx); return do_cmpb(ctx, a->r, tcg_constant_reg(a->i), - a->c, a->f, false, a->n, a->disp); + a->c, a->f, a->d, a->n, a->disp); } static bool do_addb(DisasContext *ctx, unsigned r, TCGv_reg in1, -- 2.34.1
[PULL 51/85] target/hppa: Implement CLRBTS, POPBTS, PUSHBTS, PUSHNOM
Signed-off-by: Richard Henderson --- target/hppa/insns.decode | 2 ++ target/hppa/translate.c | 6 ++ 2 files changed, 8 insertions(+) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index 6f0c3f6ea5..ba7731b517 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -381,6 +381,8 @@ bl 111010 . . 101 ... n:1 . &BL l=2 \ disp=%assemble_22 b_gate 111010 . . 001 ... . .@bl blr 111010 l:5 x:5 010 000 n:1 0 +nopbts 111010 0 0 010 0-1 0 1# clrbts/popbts +nopbts 111010 0 - 010 000 0 1# pushbts/pushnom bv 111010 b:5 x:5 110 000 n:1 0 bve 111010 b:5 0 110 100 n:1 -l=0 bve 111010 b:5 0 111 100 n:1 -l=2 diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 897b44d7e3..91249d89ca 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -3782,6 +3782,12 @@ static bool trans_bve(DisasContext *ctx, arg_bve *a) #endif } +static bool trans_nopbts(DisasContext *ctx, arg_nopbts *a) +{ +/* All branch target stack instructions implement as nop. */ +return ctx->is_pa20; +} + /* * Float class 0 */ -- 2.34.1
[PULL 71/85] include/hw/elf: Remove truncating signed casts
There's nothing about elf that specifically requires signed vs unsigned. This is very much a target-specific preference. In the meantime, casting low and high from uint64_t back to Elf_SWord to uint64_t discards high bits that might have been set by translate_fn. Signed-off-by: Richard Henderson --- include/hw/elf_ops.h | 17 ++--- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index dffb0e73d2..0a5c258fe6 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -385,10 +385,11 @@ static ssize_t glue(load_elf, SZ)(const char *name, int fd, } if (pflags) { -*pflags = (elf_word)ehdr.e_flags; +*pflags = ehdr.e_flags; +} +if (pentry) { +*pentry = ehdr.e_entry; } -if (pentry) -*pentry = (uint64_t)(elf_sword)ehdr.e_entry; glue(load_symbols, SZ)(&ehdr, fd, must_swab, clear_lsb, sym_cb); @@ -610,10 +611,12 @@ static ssize_t glue(load_elf, SZ)(const char *name, int fd, } } -if (lowaddr) -*lowaddr = (uint64_t)(elf_sword)low; -if (highaddr) -*highaddr = (uint64_t)(elf_sword)high; +if (lowaddr) { +*lowaddr = low; +} +if (highaddr) { +*highaddr = high; +} ret = total_size; fail: if (mapped_file) { -- 2.34.1
[PULL 53/85] target/hppa: Implement IDTLBT, IITLBT
Rename the existing insert tlb helpers to emphasize that they are for pa1.1 cpus. Implement a combined i/d tlb for pa2.0. Still missing is the new 'P' tlb bit. Signed-off-by: Richard Henderson --- target/hppa/helper.h | 6 ++-- target/hppa/insns.decode | 4 +++ target/hppa/mem_helper.c | 61 target/hppa/translate.c | 42 +++ 4 files changed, 100 insertions(+), 13 deletions(-) diff --git a/target/hppa/helper.h b/target/hppa/helper.h index 9920d38ded..0b346e24f3 100644 --- a/target/hppa/helper.h +++ b/target/hppa/helper.h @@ -94,8 +94,10 @@ DEF_HELPER_FLAGS_2(write_interval_timer, TCG_CALL_NO_RWG, void, env, tr) DEF_HELPER_FLAGS_2(write_eirr, TCG_CALL_NO_RWG, void, env, tr) DEF_HELPER_FLAGS_2(write_eiem, TCG_CALL_NO_RWG, void, env, tr) DEF_HELPER_FLAGS_2(swap_system_mask, TCG_CALL_NO_RWG, tr, env, tr) -DEF_HELPER_FLAGS_3(itlba, TCG_CALL_NO_RWG, void, env, tl, tr) -DEF_HELPER_FLAGS_3(itlbp, TCG_CALL_NO_RWG, void, env, tl, tr) +DEF_HELPER_FLAGS_3(itlba_pa11, TCG_CALL_NO_RWG, void, env, tl, tr) +DEF_HELPER_FLAGS_3(itlbp_pa11, TCG_CALL_NO_RWG, void, env, tl, tr) +DEF_HELPER_FLAGS_3(idtlbt_pa20, TCG_CALL_NO_RWG, void, env, tr, tr) +DEF_HELPER_FLAGS_3(iitlbt_pa20, TCG_CALL_NO_RWG, void, env, tr, tr) DEF_HELPER_FLAGS_2(ptlb, TCG_CALL_NO_RWG, void, env, tl) DEF_HELPER_FLAGS_1(ptlbe, TCG_CALL_NO_RWG, void, env) DEF_HELPER_FLAGS_2(lpa, TCG_CALL_NO_WG, tr, env, tl) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index 9d8c6a1a16..820049b0c5 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -145,6 +145,7 @@ nop_addrx 01 . . -- 01001110 . 0 @addrx # pdc probe 01 b:5 ri:5 sp:2 imm:1 100011 write:1 0 t:5 +# pa1.x tlb insert instructions ixtlbx 01 b:5 r:5 sp:2 010 addr:1 0 0 data=1 ixtlbx 01 b:5 r:5 ... 00 addr:1 0 0\ sp=%assemble_sr3x data=0 @@ -152,6 +153,9 @@ ixtlbx 01 b:5 r:5 ... 00 addr:1 0 0 \ # pcxl and pcxl2 Fast TLB Insert instructions ixtlbxf 01 0 r:5 00 0 data:1 01000 addr:1 0 0 +# pa2.0 tlb insert idtlbt and iitlbt instructions +ixtlbt 01 r2:5 r1:5 000 data:1 10 0 0# idtlbt + pxtlbx 01 b:5 x:5 sp:2 0100100 local:1 m:1 - data=1 pxtlbx 01 b:5 x:5 ... 000100 local:1 m:1 - \ sp=%assemble_sr3x data=0 diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c index 420b43a0f6..d5d2d62f4a 100644 --- a/target/hppa/mem_helper.c +++ b/target/hppa/mem_helper.c @@ -344,7 +344,7 @@ bool hppa_cpu_tlb_fill(CPUState *cs, vaddr addr, int size, } /* Insert (Insn/Data) TLB Address. Note this is PA 1.1 only. */ -void HELPER(itlba)(CPUHPPAState *env, target_ulong addr, target_ureg reg) +void HELPER(itlba_pa11)(CPUHPPAState *env, target_ulong addr, target_ureg reg) { HPPATLBEntry *ent; @@ -365,7 +365,8 @@ void HELPER(itlba)(CPUHPPAState *env, target_ulong addr, target_ureg reg) trace_hppa_tlb_itlba(env, ent, ent->itree.start, ent->itree.last, ent->pa); } -static void set_access_bits(CPUHPPAState *env, HPPATLBEntry *ent, target_ureg reg) +static void set_access_bits_pa11(CPUHPPAState *env, HPPATLBEntry *ent, + target_ureg reg) { ent->access_id = extract32(reg, 1, 18); ent->u = extract32(reg, 19, 1); @@ -383,20 +384,70 @@ static void set_access_bits(CPUHPPAState *env, HPPATLBEntry *ent, target_ureg re } /* Insert (Insn/Data) TLB Protection. Note this is PA 1.1 only. */ -void HELPER(itlbp)(CPUHPPAState *env, target_ulong addr, target_ureg reg) +void HELPER(itlbp_pa11)(CPUHPPAState *env, target_ulong addr, target_ureg reg) { HPPATLBEntry *ent = env->tlb_partial; if (ent) { env->tlb_partial = NULL; if (ent->itree.start <= addr && addr <= ent->itree.last) { -set_access_bits(env, ent, reg); +set_access_bits_pa11(env, ent, reg); return; } } qemu_log_mask(LOG_GUEST_ERROR, "ITLBP not following ITLBA\n"); } +static void itlbt_pa20(CPUHPPAState *env, target_ureg r1, + target_ureg r2, vaddr va_b) +{ +HPPATLBEntry *ent; +vaddr va_e; +uint64_t va_size; +int mask_shift; + +mask_shift = 2 * (r1 & 0xf); +va_size = TARGET_PAGE_SIZE << mask_shift; +va_b &= -va_size; +va_e = va_b + va_size - 1; + +hppa_flush_tlb_range(env, va_b, va_e); +ent = hppa_alloc_tlb_ent(env); + +ent->itree.start = va_b; +ent->itree.last = va_e; +ent->pa = (r1 << 7) & (TARGET_PAGE_MASK << mask_shift); +ent->t = extract64(r2, 61, 1); +ent->d = extract64(r2, 60, 1); +ent->b = extract64(r2, 59, 1); +ent->ar_type = extract64(r2, 56, 3); +ent->ar_pl1 = extract64(r2, 54, 2); +ent->ar_pl2 = extract64(r2, 52, 2); +ent->u = extract64(r2, 51, 1); +/*
RE: [PATCH v4 30/41] vfio/iommufd: Add support for iova_ranges
>-Original Message- >From: Cédric Le Goater >Sent: Tuesday, November 7, 2023 1:19 AM >Subject: Re: [PATCH v4 30/41] vfio/iommufd: Add support for iova_ranges > >On 11/2/23 08:12, Zhenzhong Duan wrote: >> Some vIOMMU such as virtio-iommu use iova ranges from host side to >> setup reserved ranges for passthrough device, so that guest will not >> use an iova range beyond host support. >> >> Use an uAPI of IOMMUFD to get iova ranges of host side and pass to >> vIOMMU just like the legacy backend. >> >> Signed-off-by: Zhenzhong Duan >> --- >> v4: fix build error in 32bit fedora >> >> hw/vfio/iommufd.c | 47 >+++ >> 1 file changed, 47 insertions(+) >> >> diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c >> index 1bb55ca2c4..22f02f92a9 100644 >> --- a/hw/vfio/iommufd.c >> +++ b/hw/vfio/iommufd.c >> @@ -341,6 +341,52 @@ static int iommufd_ram_block_discard_disable(bool >state) >> return ram_block_uncoordinated_discard_disable(state); >> } >> >> +static int vfio_get_info_iova_range(VFIOIOMMUFDContainer *container, >> +uint32_t ioas_id) >> +{ >> +VFIOContainerBase *bcontainer = &container->bcontainer; >> +struct iommu_ioas_iova_ranges *info; >> +struct iommu_iova_range *iova_ranges; >> +int ret, sz, fd = container->be->fd; >> + >> +info = g_malloc0(sizeof(*info)); >> +info->size = sizeof(*info); >> +info->ioas_id = ioas_id; >> + >> +ret = ioctl(fd, IOMMU_IOAS_IOVA_RANGES, info); >> +if (ret && errno != EMSGSIZE) { >> +goto error; >> +} >> + >> +sz = info->num_iovas * sizeof(struct iommu_iova_range); >> +info = g_realloc(info, sizeof(*info) + sz); >> +info->allowed_iovas = (uintptr_t)(info + 1); >> + >> +ret = ioctl(fd, IOMMU_IOAS_IOVA_RANGES, info); >> +if (ret) { >> +goto error; >> +} >> + >> +iova_ranges = (struct iommu_iova_range *)info->allowed_iovas; > >iova_ranges = (struct iommu_iova_range *)(uintptr_t)info->allowed_iovas; Will fix, thanks for point out. BRs. Zhenzhong
[PULL 30/85] target/hppa: Pass d to do_cond
Hoist the resolution of d up one level above do_cond. Signed-off-by: Richard Henderson --- target/hppa/translate.c | 82 +++-- 1 file changed, 54 insertions(+), 28 deletions(-) diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 1694b988ae..7b0e48c42b 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -827,7 +827,7 @@ static bool cond_need_cb(int c) /* Need extensions from TCGv_i32 to TCGv_reg. */ static bool cond_need_ext(DisasContext *ctx, bool d) { -return TARGET_REGISTER_BITS == 64 && !d; +return TARGET_REGISTER_BITS == 64 && !(ctx->is_pa20 && d); } /* @@ -835,8 +835,8 @@ static bool cond_need_ext(DisasContext *ctx, bool d) * the Parisc 1.1 Architecture Reference Manual for details. */ -static DisasCond do_cond(unsigned cf, TCGv_reg res, - TCGv_reg cb_msb, TCGv_reg sv) +static DisasCond do_cond(DisasContext *ctx, unsigned cf, bool d, + TCGv_reg res, TCGv_reg cb_msb, TCGv_reg sv) { DisasCond cond; TCGv_reg tmp; @@ -846,11 +846,19 @@ static DisasCond do_cond(unsigned cf, TCGv_reg res, cond = cond_make_f(); break; case 1: /* = / <>(Z / !Z) */ +if (cond_need_ext(ctx, d)) { +tmp = tcg_temp_new(); +tcg_gen_ext32u_reg(tmp, res); +res = tmp; +} cond = cond_make_0(TCG_COND_EQ, res); break; case 2: /* < / >=(N ^ V / !(N ^ V) */ tmp = tcg_temp_new(); tcg_gen_xor_reg(tmp, res, sv); +if (cond_need_ext(ctx, d)) { +tcg_gen_ext32s_reg(tmp, tmp); +} cond = cond_make_0_tmp(TCG_COND_LT, tmp); break; case 3: /* <= / >(N ^ V) | Z / !((N ^ V) | Z) */ @@ -865,20 +873,35 @@ static DisasCond do_cond(unsigned cf, TCGv_reg res, */ tmp = tcg_temp_new(); tcg_gen_eqv_reg(tmp, res, sv); -tcg_gen_sari_reg(tmp, tmp, TARGET_REGISTER_BITS - 1); -tcg_gen_and_reg(tmp, tmp, res); +if (cond_need_ext(ctx, d)) { +tcg_gen_sextract_reg(tmp, tmp, 31, 1); +tcg_gen_and_reg(tmp, tmp, res); +tcg_gen_ext32u_reg(tmp, tmp); +} else { +tcg_gen_sari_reg(tmp, tmp, TARGET_REGISTER_BITS - 1); +tcg_gen_and_reg(tmp, tmp, res); +} cond = cond_make_0_tmp(TCG_COND_EQ, tmp); break; case 4: /* NUV / UV (!C / C) */ +/* Only bit 0 of cb_msb is ever set. */ cond = cond_make_0(TCG_COND_EQ, cb_msb); break; case 5: /* ZNV / VNZ (!C | Z / C & !Z) */ tmp = tcg_temp_new(); tcg_gen_neg_reg(tmp, cb_msb); tcg_gen_and_reg(tmp, tmp, res); +if (cond_need_ext(ctx, d)) { +tcg_gen_ext32u_reg(tmp, tmp); +} cond = cond_make_0_tmp(TCG_COND_EQ, tmp); break; case 6: /* SV / NSV (V / !V) */ +if (cond_need_ext(ctx, d)) { +tmp = tcg_temp_new(); +tcg_gen_ext32s_reg(tmp, sv); +sv = tmp; +} cond = cond_make_0(TCG_COND_LT, sv); break; case 7: /* OD / EV */ @@ -900,10 +923,11 @@ static DisasCond do_cond(unsigned cf, TCGv_reg res, can use the inputs directly. This can allow other computation to be deleted as unused. */ -static DisasCond do_sub_cond(unsigned cf, TCGv_reg res, +static DisasCond do_sub_cond(DisasContext *ctx, unsigned cf, TCGv_reg res, TCGv_reg in1, TCGv_reg in2, TCGv_reg sv) { DisasCond cond; +bool d = false; switch (cf >> 1) { case 1: /* = / <> */ @@ -922,7 +946,7 @@ static DisasCond do_sub_cond(unsigned cf, TCGv_reg res, cond = cond_make(TCG_COND_LEU, in1, in2); break; default: -return do_cond(cf, res, NULL, sv); +return do_cond(ctx, cf, d, res, NULL, sv); } if (cf & 1) { cond.c = tcg_invert_cond(cond.c); @@ -940,8 +964,10 @@ static DisasCond do_sub_cond(unsigned cf, TCGv_reg res, * how cases c={2,3} are treated. */ -static DisasCond do_log_cond(unsigned cf, TCGv_reg res) +static DisasCond do_log_cond(DisasContext *ctx, unsigned cf, TCGv_reg res) { +bool d = false; + switch (cf) { case 0: /* never */ case 9: /* undef, C */ @@ -970,7 +996,7 @@ static DisasCond do_log_cond(unsigned cf, TCGv_reg res) case 14: /* OD */ case 15: /* EV */ -return do_cond(cf, res, NULL, NULL); +return do_cond(ctx, cf, d, res, NULL, NULL); default: g_assert_not_reached(); @@ -979,7 +1005,7 @@ static DisasCond do_log_cond(unsigned cf, TCGv_reg res) /* Similar, but for shift/extract/deposit conditions. */ -static DisasCond do_sed_cond(unsigned orig, TCGv_reg res) +static DisasCond do_sed_cond(DisasContext *ctx, unsigned orig, TCGv_reg res) { unsigned c, f; @@ -992,7 +1018,7 @@ static DisasCond do_sed_cond(unsigned orig
[PULL 75/85] target/hppa: Add pa2.0 cpu local tlb flushes
From: Helge Deller The previous decoding misnamed the bit it called "local". Other than the name, the implementation was correct for pa1.x. Rename this field to "tlbe". PA2.0 adds (a real) local bit to PxTLB, and also adds a range of pages to flush in GR[b]. Signed-off-by: Helge Deller Signed-off-by: Richard Henderson --- target/hppa/helper.h | 1 + target/hppa/insns.decode | 20 ++--- target/hppa/mem_helper.c | 26 ++ target/hppa/translate.c | 48 +++- target/hppa/trace-events | 1 + 5 files changed, 84 insertions(+), 12 deletions(-) diff --git a/target/hppa/helper.h b/target/hppa/helper.h index d586be3f15..20698f68ed 100644 --- a/target/hppa/helper.h +++ b/target/hppa/helper.h @@ -98,6 +98,7 @@ DEF_HELPER_FLAGS_3(itlbp_pa11, TCG_CALL_NO_RWG, void, env, tl, tl) DEF_HELPER_FLAGS_3(idtlbt_pa20, TCG_CALL_NO_RWG, void, env, tl, tl) DEF_HELPER_FLAGS_3(iitlbt_pa20, TCG_CALL_NO_RWG, void, env, tl, tl) DEF_HELPER_FLAGS_2(ptlb, TCG_CALL_NO_RWG, void, env, tl) +DEF_HELPER_FLAGS_2(ptlb_l, TCG_CALL_NO_RWG, void, env, tl) DEF_HELPER_FLAGS_1(ptlbe, TCG_CALL_NO_RWG, void, env) DEF_HELPER_FLAGS_2(lpa, TCG_CALL_NO_WG, tl, env, tl) DEF_HELPER_FLAGS_1(change_prot_id, TCG_CALL_NO_RWG, void, env) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index 19e537df24..f5a3f02fd1 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -161,9 +161,23 @@ ixtlbxf 01 0 r:5 00 0 data:1 01000 addr:1 0 0 # pa2.0 tlb insert idtlbt and iitlbt instructions ixtlbt 01 r2:5 r1:5 000 data:1 10 0 0# idtlbt -pxtlbx 01 b:5 x:5 sp:2 0100100 local:1 m:1 - data=1 -pxtlbx 01 b:5 x:5 ... 000100 local:1 m:1 - \ -sp=%assemble_sr3x data=0 +# pdtlb, pitlb +pxtlb 01 b:5 x:5 sp:2 01001000 m:1 - \ +&ldst disp=0 scale=0 size=0 t=0 +pxtlb 01 b:5 x:5 ... 0001000 m:1 - \ +&ldst disp=0 scale=0 size=0 t=0 sp=%assemble_sr3x + +# ... pa20 local +pxtlb_l 01 b:5 x:5 sp:2 01011000 m:1 - \ +&ldst disp=0 scale=0 size=0 t=0 +pxtlb_l 01 b:5 x:5 ... 0011000 m:1 - \ +&ldst disp=0 scale=0 size=0 t=0 sp=%assemble_sr3x + +# pdtlbe, pitlbe +pxtlbe 01 b:5 x:5 sp:2 01001001 m:1 - \ +&ldst disp=0 scale=0 size=0 t=0 +pxtlbe 01 b:5 x:5 ... 0001001 m:1 - \ +&ldst disp=0 scale=0 size=0 t=0 sp=%assemble_sr3x lpa 01 b:5 x:5 sp:2 01001101 m:1 t:5\ &ldst disp=0 scale=0 size=0 diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c index 9be68b860b..7132ea221c 100644 --- a/target/hppa/mem_helper.c +++ b/target/hppa/mem_helper.c @@ -448,16 +448,34 @@ void HELPER(iitlbt_pa20)(CPUHPPAState *env, target_ulong r1, target_ulong r2) itlbt_pa20(env, r1, r2, va_b); } -/* Purge (Insn/Data) TLB. This is explicitly page-based, and is - synchronous across all processors. */ +/* Purge (Insn/Data) TLB. */ static void ptlb_work(CPUState *cpu, run_on_cpu_data data) { CPUHPPAState *env = cpu_env(cpu); -target_ulong addr = (target_ulong) data.target_ptr; +vaddr start = data.target_ptr; +vaddr end; -hppa_flush_tlb_range(env, addr, addr); +/* + * PA2.0 allows a range of pages encoded into GR[b], which we have + * copied into the bottom bits of the otherwise page-aligned address. + * PA1.x will always provide zero here, for a single page flush. + */ +end = start & 0xf; +start &= TARGET_PAGE_MASK; +end = TARGET_PAGE_SIZE << (2 * end); +end = start + end - 1; + +hppa_flush_tlb_range(env, start, end); } +/* This is local to the current cpu. */ +void HELPER(ptlb_l)(CPUHPPAState *env, target_ulong addr) +{ +trace_hppa_tlb_ptlb_local(env); +ptlb_work(env_cpu(env), RUN_ON_CPU_TARGET_PTR(addr)); +} + +/* This is synchronous across all processors. */ void HELPER(ptlb)(CPUHPPAState *env, target_ulong addr) { CPUState *src = env_cpu(env); diff --git a/target/hppa/translate.c b/target/hppa/translate.c index e7f379d648..9f129a230b 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -2320,7 +2320,7 @@ static bool trans_ixtlbx(DisasContext *ctx, arg_ixtlbx *a) #endif } -static bool trans_pxtlbx(DisasContext *ctx, arg_pxtlbx *a) +static bool do_pxtlb(DisasContext *ctx, arg_ldst *a, bool local) { CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR); #ifndef CONFIG_USER_ONLY @@ -2330,15 +2330,53 @@ static bool trans_pxtlbx(DisasContext *ctx, arg_pxtlbx *a) nullify_over(ctx); form_gva(ctx, &addr, &ofs, a->b, a->x, 0, 0, a->sp, a->m, false); -if (a->m) { -save_gpr(ctx, a->b, ofs); + +/* + * Page align now, rather than later, so that we can add in the + * page_size field from pa2.0 from the low 4 bits of GR[b]. + */
[PULL 00/85] target/hppa patch queue
The following changes since commit 3e01f1147a16ca566694b97eafc941d62fa1e8d8: Merge tag 'pull-sp-20231105' of https://gitlab.com/rth7680/qemu into staging (2023-11-06 09:34:22 +0800) are available in the Git repository at: https://gitlab.com/rth7680/qemu.git tags/pull-pa-20231106 for you to fetch changes up to 3d1611bfa129182d2e867e8a9da7d2fc6efefce5: hw/hppa: Allow C3700 with 64-bit and B160L with 32-bit CPU only (2023-11-06 18:49:34 -0800) target/hppa: Implement PA2.0 instructions hw/hppa: Map astro chip 64-bit I/O mem hw/hppa: Turn on 64-bit cpu for C3700 Helge Deller (8): target/hppa: sar register allows only 5 bits on 32-bit CPU target/hppa: Fix interruption based on default PSW target/hppa: Add pa2.0 cpu local tlb flushes target/hppa: Clear upper bits in mtctl for pa1.x hw/pci-host/astro: Map Astro chip into 64-bit I/O memory region hw/pci-host/astro: Trigger CPU irq on CPU HPA in high memory hw/hppa: Turn on 64-bit CPU for C3700 machine hw/hppa: Allow C3700 with 64-bit and B160L with 32-bit CPU only Richard Henderson (77): target/hppa: Include PSW_P in tb flags and mmu index target/hppa: Rename hppa_tlb_entry to HPPATLBEntry target/hppa: Use IntervalTreeNode in HPPATLBEntry target/hppa: Always report one page to tlb_set_page target/hppa: Split out hppa_flush_tlb_range target/hppa: Populate an interval tree with valid tlb entries target/hppa: Remove get_temp target/hppa: Remove get_temp_tl target/hppa: Remove load_const target/hppa: Fix hppa64 case in machine.c target/hppa: Fix load in do_load_32 target/hppa: Truncate rotate count in trans_shrpw_sar target/hppa: Fix trans_ds for hppa64 target/hppa: Fix do_add, do_sub for hppa64 target/hppa: Fix bb_sar for hppa64 target/hppa: Fix extrw and depw with sar for hppa64 target/hppa: Introduce TYPE_HPPA64_CPU target/hppa: Make HPPA_BTLB_ENTRIES variable target/hppa: Implement cpu_list target/hppa: Implement hppa_cpu_class_by_name target/hppa: Update cpu_hppa_get/put_psw for hppa64 target/hppa: Handle absolute addresses for pa2.0 target/hppa: Adjust hppa_cpu_dump_state for hppa64 target/hppa: Fix hppa64 addressing target/hppa: Pass DisasContext to copy_iaoq_entry target/hppa: Always use copy_iaoq_entry to set cpu_iaoq_[fb] target/hppa: Use copy_iaoq_entry for link in do_ibranch target/hppa: Mask inputs in copy_iaoq_entry target/hppa: Pass d to do_cond target/hppa: Pass d to do_sub_cond target/hppa: Pass d to do_log_cond target/hppa: Pass d to do_sed_cond target/hppa: Pass d to do_unit_cond linux-user/hppa: Fixes for TARGET_ABI32 target/hppa: Drop attempted gdbstub support for hppa64 target/hppa: Remove TARGET_HPPA64 target/hppa: Decode d for logical instructions target/hppa: Decode d for unit instructions target/hppa: Decode d for cmpclr instructions target/hppa: Decode d for add instructions target/hppa: Decode d for sub instructions target/hppa: Decode d for bb instructions target/hppa: Decode d for cmpb instructions target/hppa: Decode CMPIB double-word target/hppa: Decode ADDB double-word target/hppa: Implement LDD, LDCD, LDDA, STD, STDA target/hppa: Implement DEPD, DEPDI target/hppa: Implement EXTRD target/hppa: Implement SHRPD target/hppa: Implement CLRBTS, POPBTS, PUSHBTS, PUSHNOM target/hppa: Implement STDBY target/hppa: Implement IDTLBT, IITLBT hw/hppa: Use uint32_t instead of target_ureg target/hppa: Remove TARGET_REGISTER_BITS target/hppa: Remove most of the TARGET_REGISTER_BITS redirections target/hppa: Remove remaining TARGET_REGISTER_BITS redirections target/hppa: Adjust vmstate_env for pa2.0 tlb target/hppa: Use tcg_temp_new_i64 not tcg_temp_new target/hppa: Replace tcg_gen_*_tl with tcg_gen_*_i64 target/hppa: Implement HADD target/hppa: Implement HSUB target/hppa: Implement HAVG target/hppa: Implement HSHL, HSHR target/hppa: Implement HSHLADD, HSHRADD target/hppa: Implement MIXH, MIXW target/hppa: Implement PERMH target/hppa: Precompute zero into DisasContext target/hppa: Return zero for r0 from load_gpr include/hw/elf: Remove truncating signed casts hw/hppa: Translate phys addresses for the cpu linux-user/hppa: Drop EXCP_DUMP from handled exceptions target/hppa: Implement pa2.0 data prefetch instructions target/hppa: Avoid async_safe_run_on_cpu on uniprocessor system target/hppa: Add unwind_breg to CPUHPPAState target/hppa: Create raise_exception_with_ior target/hppa: Update IIAOQ, IIASQ
[PULL 82/85] hw/pci-host/astro: Map Astro chip into 64-bit I/O memory region
From: Helge Deller Map Astro into high F-region and add alias for 32-bit OS in low region. Signed-off-by: Helge Deller --- hw/pci-host/astro.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/hw/pci-host/astro.c b/hw/pci-host/astro.c index 4b2d7caf2d..df61386bd9 100644 --- a/hw/pci-host/astro.c +++ b/hw/pci-host/astro.c @@ -19,6 +19,8 @@ #define TYPE_ASTRO_IOMMU_MEMORY_REGION "astro-iommu-memory-region" +#define F_EXTEND(addr) ((addr) | MAKE_64BIT_MASK(32, 32)) + #include "qemu/osdep.h" #include "qemu/module.h" #include "qemu/units.h" @@ -821,15 +823,16 @@ static void astro_realize(DeviceState *obj, Error **errp) /* map elroys mmio */ map_size = LMMIO_DIST_BASE_SIZE / ROPES_PER_IOC; -map_addr = (uint32_t) (LMMIO_DIST_BASE_ADDR + rope * map_size); +map_addr = F_EXTEND(LMMIO_DIST_BASE_ADDR + rope * map_size); memory_region_init_alias(&elroy->pci_mmio_alias, OBJECT(elroy), "pci-mmio-alias", - &elroy->pci_mmio, map_addr, map_size); + &elroy->pci_mmio, (uint32_t) map_addr, map_size); memory_region_add_subregion(get_system_memory(), map_addr, &elroy->pci_mmio_alias); +/* map elroys io */ map_size = IOS_DIST_BASE_SIZE / ROPES_PER_IOC; -map_addr = (uint32_t) (IOS_DIST_BASE_ADDR + rope * map_size); +map_addr = F_EXTEND(IOS_DIST_BASE_ADDR + rope * map_size); memory_region_add_subregion(get_system_memory(), map_addr, &elroy->pci_io); -- 2.34.1
[PULL 72/85] hw/hppa: Translate phys addresses for the cpu
Hack the machine to use pa2.0 physical layout when required, using the PSW.W=0 absolute to physical mapping. Signed-off-by: Richard Henderson --- hw/hppa/machine.c | 117 -- 1 file changed, 71 insertions(+), 46 deletions(-) diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index 1f09b4b490..43c7afb89d 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -87,7 +87,7 @@ static const MemoryRegionOps hppa_pci_ignore_ops = { }, }; -static ISABus *hppa_isa_bus(void) +static ISABus *hppa_isa_bus(hwaddr addr) { ISABus *isa_bus; qemu_irq *isa_irqs; @@ -96,8 +96,7 @@ static ISABus *hppa_isa_bus(void) isa_region = g_new(MemoryRegion, 1); memory_region_init_io(isa_region, NULL, &hppa_pci_ignore_ops, NULL, "isa-io", 0x800); -memory_region_add_subregion(get_system_memory(), IDE_HPA, -isa_region); +memory_region_add_subregion(get_system_memory(), addr, isa_region); isa_bus = isa_bus_new(NULL, get_system_memory(), isa_region, &error_abort); @@ -163,13 +162,24 @@ static const MemoryRegionOps hppa_io_helper_ops = { }, }; +typedef uint64_t TranslateFn(void *opaque, uint64_t addr); -static uint64_t cpu_hppa_to_phys(void *opaque, uint64_t addr) +static uint64_t linux_kernel_virt_to_phys(void *opaque, uint64_t addr) { addr &= (0x1000 - 1); return addr; } +static uint64_t translate_pa10(void *dummy, uint64_t addr) +{ +return (uint32_t)addr; +} + +static uint64_t translate_pa20(void *dummy, uint64_t addr) +{ +return hppa_abs_to_phys_pa2_w0(addr); +} + static HPPACPU *cpu[HPPA_MAX_CPUS]; static uint64_t firmware_entry; @@ -179,7 +189,8 @@ static void fw_cfg_boot_set(void *opaque, const char *boot_device, fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]); } -static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus) +static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus, + hwaddr addr) { FWCfgState *fw_cfg; uint64_t val; @@ -188,7 +199,7 @@ static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus) int btlb_entries = HPPA_BTLB_ENTRIES(&cpu[0]->env); int len; -fw_cfg = fw_cfg_init_mem(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4); +fw_cfg = fw_cfg_init_mem(addr, addr + 4); fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, ms->smp.cpus); fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, HPPA_MAX_CPUS); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, ms->ram_size); @@ -258,32 +269,45 @@ static DinoState *dino_init(MemoryRegion *addr_space) /* * Step 1: Create CPUs and Memory */ -static void machine_HP_common_init_cpus(MachineState *machine) +static TranslateFn *machine_HP_common_init_cpus(MachineState *machine) { MemoryRegion *addr_space = get_system_memory(); -MemoryRegion *cpu_region; -long i; unsigned int smp_cpus = machine->smp.cpus; -char *name; +TranslateFn *translate; +MemoryRegion *cpu_region; /* Create CPUs. */ -for (i = 0; i < smp_cpus; i++) { -name = g_strdup_printf("cpu%ld-io-eir", i); +for (unsigned int i = 0; i < smp_cpus; i++) { cpu[i] = HPPA_CPU(cpu_create(machine->cpu_type)); +} + +/* + * For now, treat address layout as if PSW_W is clear. + * TODO: create a proper hppa64 board model and load elf64 firmware. + */ +if (hppa_is_pa20(&cpu[0]->env)) { +translate = translate_pa20; +} else { +translate = translate_pa10; +} + +for (unsigned int i = 0; i < smp_cpus; i++) { +g_autofree char *name = g_strdup_printf("cpu%u-io-eir", i); cpu_region = g_new(MemoryRegion, 1); memory_region_init_io(cpu_region, OBJECT(cpu[i]), &hppa_io_eir_ops, cpu[i], name, 4); -memory_region_add_subregion(addr_space, CPU_HPA + i * 0x1000, +memory_region_add_subregion(addr_space, +translate(NULL, CPU_HPA + i * 0x1000), cpu_region); -g_free(name); } /* RTC and DebugOutputPort on CPU #0 */ cpu_region = g_new(MemoryRegion, 1); memory_region_init_io(cpu_region, OBJECT(cpu[0]), &hppa_io_helper_ops, cpu[0], "cpu0-io-rtc", 2 * sizeof(uint64_t)); -memory_region_add_subregion(addr_space, CPU_HPA + 16, cpu_region); +memory_region_add_subregion(addr_space, translate(NULL, CPU_HPA + 16), +cpu_region); /* Main memory region. */ if (machine->ram_size > 3 * GiB) { @@ -291,12 +315,15 @@ static void machine_HP_common_init_cpus(MachineState *machine) exit(EXIT_FAILURE); } memory_region_add_subregion_overlap(addr_space, 0, machine->ram, -1); + +return translate; } /* * Last creation step: Add SCSI discs, NICs, graphics & load firmware */ -static void machin
[PULL 80/85] target/hppa: Update IIAOQ, IIASQ for pa2.0
These registers have a different format for pa2.0. Signed-off-by: Richard Henderson --- target/hppa/int_helper.c | 46 target/hppa/sys_helper.c | 10 + 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c index a11d607b31..54875442e7 100644 --- a/target/hppa/int_helper.c +++ b/target/hppa/int_helper.c @@ -102,11 +102,7 @@ void hppa_cpu_do_interrupt(CPUState *cs) HPPACPU *cpu = HPPA_CPU(cs); CPUHPPAState *env = &cpu->env; int i = cs->exception_index; -target_ulong iaoq_f = env->iaoq_f; -target_ulong iaoq_b = env->iaoq_b; -uint64_t iasq_f = env->iasq_f; -uint64_t iasq_b = env->iasq_b; -target_ulong old_psw; +uint64_t old_psw; /* As documented in pa2.0 -- interruption handling. */ /* step 1 */ @@ -118,10 +114,25 @@ void hppa_cpu_do_interrupt(CPUState *cs) (i == EXCP_HPMC ? PSW_M : 0)); /* step 3 */ -env->cr[CR_IIASQ] = iasq_f >> 32; -env->cr_back[0] = iasq_b >> 32; -env->cr[CR_IIAOQ] = iaoq_f; -env->cr_back[1] = iaoq_b; +/* + * For pa1.x, IIASQ is simply a copy of IASQ. + * For pa2.0, IIASQ is the top bits of the virtual address, + *or zero if translation is disabled. + */ +if (!hppa_is_pa20(env)) { +env->cr[CR_IIASQ] = env->iasq_f >> 32; +env->cr_back[0] = env->iasq_b >> 32; +} else if (old_psw & PSW_C) { +env->cr[CR_IIASQ] = +hppa_form_gva_psw(old_psw, env->iasq_f, env->iaoq_f) >> 32; +env->cr_back[0] = +hppa_form_gva_psw(old_psw, env->iasq_f, env->iaoq_f) >> 32; +} else { +env->cr[CR_IIASQ] = 0; +env->cr_back[0] = 0; +} +env->cr[CR_IIAOQ] = env->iaoq_f; +env->cr_back[1] = env->iaoq_b; if (old_psw & PSW_Q) { /* step 5 */ @@ -154,14 +165,13 @@ void hppa_cpu_do_interrupt(CPUState *cs) /* ??? An alternate fool-proof method would be to store the instruction data into the unwind info. That's probably a bit too much in the way of extra storage required. */ -vaddr vaddr; -hwaddr paddr; +vaddr vaddr = env->iaoq_f & -4; +hwaddr paddr = vaddr; -paddr = vaddr = iaoq_f & -4; if (old_psw & PSW_C) { int prot, t; -vaddr = hppa_form_gva_psw(old_psw, iasq_f, vaddr); +vaddr = hppa_form_gva_psw(old_psw, env->iasq_f, vaddr); t = hppa_get_physical_address(env, vaddr, MMU_KERNEL_IDX, 0, &paddr, &prot, NULL); if (t >= 0) { @@ -191,14 +201,14 @@ void hppa_cpu_do_interrupt(CPUState *cs) /* step 7 */ if (i == EXCP_TOC) { -env->iaoq_f = FIRMWARE_START; +env->iaoq_f = hppa_form_gva(env, 0, FIRMWARE_START); /* help SeaBIOS and provide iaoq_b and iasq_back in shadow regs */ env->gr[24] = env->cr_back[0]; env->gr[25] = env->cr_back[1]; } else { -env->iaoq_f = env->cr[CR_IVA] + 32 * i; +env->iaoq_f = hppa_form_gva(env, 0, env->cr[CR_IVA] + 32 * i); } -env->iaoq_b = env->iaoq_f + 4; +env->iaoq_b = hppa_form_gva(env, 0, env->iaoq_f + 4); env->iasq_f = 0; env->iasq_b = 0; @@ -251,8 +261,8 @@ void hppa_cpu_do_interrupt(CPUState *cs) qemu_log("INT %6d: %s @ " TARGET_FMT_lx "," TARGET_FMT_lx " -> " TARGET_FMT_lx " " TARGET_FMT_lx "\n", ++count, name, - hppa_form_gva(env, iasq_f, iaoq_f), - hppa_form_gva(env, iasq_b, iaoq_b), + hppa_form_gva(env, env->iasq_f, env->iaoq_f), + hppa_form_gva(env, env->iasq_b, env->iaoq_b), env->iaoq_f, hppa_form_gva(env, (uint64_t)env->cr[CR_ISR] << 32, env->cr[CR_IOR])); diff --git a/target/hppa/sys_helper.c b/target/hppa/sys_helper.c index 8850576ac3..a59245eed3 100644 --- a/target/hppa/sys_helper.c +++ b/target/hppa/sys_helper.c @@ -80,6 +80,16 @@ void HELPER(rfi)(CPUHPPAState *env) env->iasq_b = (uint64_t)env->cr_back[0] << 32; env->iaoq_f = env->cr[CR_IIAOQ]; env->iaoq_b = env->cr_back[1]; + +/* + * For pa2.0, IIASQ is the top bits of the virtual address. + * To recreate the space identifier, remove the offset bits. + */ +if (hppa_is_pa20(env)) { +env->iasq_f &= ~env->iaoq_f; +env->iasq_b &= ~env->iaoq_b; +} + cpu_hppa_put_psw(env, env->cr[CR_IPSW]); } -- 2.34.1
[PULL 84/85] hw/hppa: Turn on 64-bit CPU for C3700 machine
From: Helge Deller Signed-off-by: Helge Deller --- hw/hppa/machine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index 43c7afb89d..da9ca85806 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -696,7 +696,7 @@ static void HP_C3700_machine_init_class_init(ObjectClass *oc, void *data) NMIClass *nc = NMI_CLASS(oc); mc->desc = "HP C3700 workstation"; -mc->default_cpu_type = TYPE_HPPA_CPU; +mc->default_cpu_type = TYPE_HPPA64_CPU; mc->init = machine_HP_C3700_init; mc->reset = hppa_machine_reset; mc->block_default_type = IF_SCSI; -- 2.34.1
[PULL 06/85] target/hppa: Populate an interval tree with valid tlb entries
Complete the data structure conversion started earlier. This reduces the perf overhead of hppa_get_physical_address from ~5% to ~0.25%. Signed-off-by: Richard Henderson --- target/hppa/cpu.h| 24 +- target/hppa/cpu.c| 2 + target/hppa/machine.c| 51 - target/hppa/mem_helper.c | 161 +++ 4 files changed, 167 insertions(+), 71 deletions(-) diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index 1480d0237a..08de894393 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -176,7 +176,10 @@ typedef int64_t target_sreg; #endif typedef struct HPPATLBEntry { -IntervalTreeNode itree; +union { +IntervalTreeNode itree; +struct HPPATLBEntry *unused_next; +}; target_ureg pa; @@ -234,10 +237,22 @@ typedef struct CPUArchState { #define HPPA_TLB_ENTRIES256 #define HPPA_BTLB_ENTRIES (HPPA_BTLB_FIXED + HPPA_BTLB_VARIABLE) -/* ??? Implement a unified itlb/dtlb for the moment. */ -/* ??? We should use a more intelligent data structure. */ -HPPATLBEntry tlb[HPPA_TLB_ENTRIES]; +/* Index for round-robin tlb eviction. */ uint32_t tlb_last; + +/* + * For pa1.x, the partial initialized, still invalid tlb entry + * which has had ITLBA performed, but not yet ITLBP. + */ +HPPATLBEntry *tlb_partial; + +/* Linked list of all invalid (unused) tlb entries. */ +HPPATLBEntry *tlb_unused; + +/* Root of the search tree for all valid tlb entries. */ +IntervalTreeRoot tlb_root; + +HPPATLBEntry tlb[HPPA_TLB_ENTRIES]; } CPUHPPAState; /** @@ -356,6 +371,7 @@ int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void hppa_cpu_dump_state(CPUState *cs, FILE *f, int); #ifndef CONFIG_USER_ONLY +void hppa_ptlbe(CPUHPPAState *env); hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr); bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx, diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index 1644297bf8..5e1240c631 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c @@ -137,8 +137,10 @@ static void hppa_cpu_realizefn(DeviceState *dev, Error **errp) #ifndef CONFIG_USER_ONLY { HPPACPU *cpu = HPPA_CPU(cs); + cpu->alarm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, hppa_cpu_alarm_timer, cpu); +hppa_ptlbe(&cpu->env); } #endif } diff --git a/target/hppa/machine.c b/target/hppa/machine.c index 4535195ca2..ab3e8c81fa 100644 --- a/target/hppa/machine.c +++ b/target/hppa/machine.c @@ -72,8 +72,6 @@ static int get_tlb(QEMUFile *f, void *opaque, size_t size, HPPATLBEntry *ent = opaque; uint32_t val; -memset(ent, 0, sizeof(*ent)); - ent->itree.start = qemu_get_be64(f); ent->pa = qemu_get_betr(f); val = qemu_get_be32(f); @@ -122,6 +120,53 @@ static const VMStateInfo vmstate_tlb = { .put = put_tlb, }; +static int tlb_pre_load(void *opaque) +{ +CPUHPPAState *env = opaque; + +/* + * Zap the entire tlb, on-the-side data structures and all. + * Each tlb entry will have data re-filled by put_tlb. + */ +memset(env->tlb, 0, sizeof(env->tlb)); +memset(&env->tlb_root, 0, sizeof(env->tlb_root)); +env->tlb_unused = NULL; +env->tlb_partial = NULL; + +return 0; +} + +static int tlb_post_load(void *opaque, int version_id) +{ +CPUHPPAState *env = opaque; +HPPATLBEntry **unused = &env->tlb_unused; +HPPATLBEntry *partial = NULL; + +/* + * Re-create the interval tree from the valid entries. + * Truely invalid entries should have start == end == 0. + * Otherwise it should be the in-flight tlb_partial entry. + */ +for (uint32_t i = 0; i < ARRAY_SIZE(env->tlb); ++i) { +HPPATLBEntry *e = &env->tlb[i]; + +if (e->entry_valid) { +interval_tree_insert(&e->itree, &env->tlb_root); +} else if (i < HPPA_BTLB_ENTRIES) { +/* btlb not in unused list */ +} else if (partial == NULL && e->itree.start < e->itree.last) { +partial = e; +} else { +*unused = e; +unused = &e->unused_next; +} +} +env->tlb_partial = partial; +*unused = NULL; + +return 0; +} + static VMStateField vmstate_env_fields[] = { VMSTATE_UINTTR_ARRAY(gr, CPUHPPAState, 32), VMSTATE_UINT64_ARRAY(fr, CPUHPPAState, 32), @@ -164,6 +209,8 @@ static const VMStateDescription vmstate_env = { .version_id = 1, .minimum_version_id = 1, .fields = vmstate_env_fields, +.pre_load = tlb_pre_load, +.post_load = tlb_post_load, }; static VMStateField vmstate_cpu_fields[] = { diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c index 828cceb29c..b1773ece61 100644 --- a/target/hppa/mem_helper.c +++ b/target/hppa/mem
[PULL 76/85] target/hppa: Avoid async_safe_run_on_cpu on uniprocessor system
Signed-off-by: Richard Henderson --- target/hppa/mem_helper.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c index 7132ea221c..602e6c809f 100644 --- a/target/hppa/mem_helper.c +++ b/target/hppa/mem_helper.c @@ -480,6 +480,7 @@ void HELPER(ptlb)(CPUHPPAState *env, target_ulong addr) { CPUState *src = env_cpu(env); CPUState *cpu; +bool wait = false; trace_hppa_tlb_ptlb(env); run_on_cpu_data data = RUN_ON_CPU_TARGET_PTR(addr); @@ -487,9 +488,14 @@ void HELPER(ptlb)(CPUHPPAState *env, target_ulong addr) CPU_FOREACH(cpu) { if (cpu != src) { async_run_on_cpu(cpu, ptlb_work, data); +wait = true; } } -async_safe_run_on_cpu(src, ptlb_work, data); +if (wait) { +async_safe_run_on_cpu(src, ptlb_work, data); +} else { +ptlb_work(src, data); +} } void hppa_ptlbe(CPUHPPAState *env) -- 2.34.1
[PULL 57/85] target/hppa: Remove remaining TARGET_REGISTER_BITS redirections
The conversions to/from i64 can be eliminated entirely, folding computation into adjacent operations. Signed-off-by: Richard Henderson --- target/hppa/translate.c | 46 - 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/target/hppa/translate.c b/target/hppa/translate.c index ec3f70e46e..0024c38c84 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -33,15 +33,6 @@ #undef HELPER_H -/* Since we have a distinction between register size and address size, - we need to redefine all of these. */ - -#define tcg_gen_extu_reg_tl tcg_gen_mov_i64 -#define tcg_gen_trunc_i64_reg tcg_gen_mov_i64 -#define tcg_gen_extu_reg_i64 tcg_gen_mov_i64 -#define tcg_gen_ext_reg_i64 tcg_gen_mov_i64 - - typedef struct DisasCond { TCGCond c; TCGv_i64 a0, a1; @@ -1345,8 +1336,7 @@ static void form_gva(DisasContext *ctx, TCGv_i64 *pgva, TCGv_i64 *pofs, *pofs = ofs; *pgva = addr = tcg_temp_new_i64(); -tcg_gen_extu_reg_tl(addr, modify <= 0 ? ofs : base); -tcg_gen_andi_tl(addr, addr, gva_offset_mask(ctx)); +tcg_gen_andi_tl(addr, modify <= 0 ? ofs : base, gva_offset_mask(ctx)); #ifndef CONFIG_USER_ONLY if (!is_phys) { tcg_gen_or_tl(addr, addr, space_select(ctx, sp, base)); @@ -1966,13 +1956,11 @@ static bool trans_mfsp(DisasContext *ctx, arg_mfsp *a) unsigned rt = a->t; unsigned rs = a->sp; TCGv_i64 t0 = tcg_temp_new_i64(); -TCGv_i64 t1 = tcg_temp_new(); load_spr(ctx, t0, rs); tcg_gen_shri_i64(t0, t0, 32); -tcg_gen_trunc_i64_reg(t1, t0); -save_gpr(ctx, rt, t1); +save_gpr(ctx, rt, t0); cond_free(&ctx->null_cond); return true; @@ -2029,22 +2017,21 @@ static bool trans_mtsp(DisasContext *ctx, arg_mtsp *a) { unsigned rr = a->r; unsigned rs = a->sp; -TCGv_i64 t64; +TCGv_i64 tmp; if (rs >= 5) { CHECK_MOST_PRIVILEGED(EXCP_PRIV_REG); } nullify_over(ctx); -t64 = tcg_temp_new_i64(); -tcg_gen_extu_reg_i64(t64, load_gpr(ctx, rr)); -tcg_gen_shli_i64(t64, t64, 32); +tmp = tcg_temp_new_i64(); +tcg_gen_shli_i64(tmp, load_gpr(ctx, rr), 32); if (rs >= 4) { -tcg_gen_st_i64(t64, tcg_env, offsetof(CPUHPPAState, sr[rs])); +tcg_gen_st_i64(tmp, tcg_env, offsetof(CPUHPPAState, sr[rs])); ctx->tb_flags &= ~TB_FLAG_SR_SAME; } else { -tcg_gen_mov_i64(cpu_sr[rs], t64); +tcg_gen_mov_i64(cpu_sr[rs], tmp); } return nullify_end(ctx); @@ -2135,11 +2122,8 @@ static bool trans_ldsid(DisasContext *ctx, arg_ldsid *a) /* We don't implement space registers in user mode. */ tcg_gen_movi_i64(dest, 0); #else -TCGv_i64 t0 = tcg_temp_new_i64(); - -tcg_gen_mov_i64(t0, space_select(ctx, a->sp, load_gpr(ctx, a->b))); -tcg_gen_shri_i64(t0, t0, 32); -tcg_gen_trunc_i64_reg(dest, t0); +tcg_gen_mov_i64(dest, space_select(ctx, a->sp, load_gpr(ctx, a->b))); +tcg_gen_shri_i64(dest, dest, 32); #endif save_gpr(ctx, a->t, dest); @@ -3188,10 +3172,8 @@ static bool trans_shrp_sar(DisasContext *ctx, arg_shrp_sar *a) TCGv_i64 s = tcg_temp_new_i64(); tcg_gen_concat32_i64(t, src2, src1); -tcg_gen_extu_reg_i64(s, cpu_sar); -tcg_gen_andi_i64(s, s, 31); -tcg_gen_shr_i64(t, t, s); -tcg_gen_trunc_i64_reg(dest, t); +tcg_gen_andi_i64(s, cpu_sar, 31); +tcg_gen_shr_i64(dest, t, s); } } save_gpr(ctx, a->t, dest); @@ -3233,10 +3215,8 @@ static bool trans_shrp_imm(DisasContext *ctx, arg_shrp_imm *a) tcg_gen_rotri_i32(t32, t32, sa); tcg_gen_extu_i32_i64(dest, t32); } else { -TCGv_i64 t64 = tcg_temp_new_i64(); -tcg_gen_concat32_i64(t64, t2, cpu_gr[a->r1]); -tcg_gen_shri_i64(t64, t64, sa); -tcg_gen_trunc_i64_reg(dest, t64); +tcg_gen_concat32_i64(dest, t2, cpu_gr[a->r1]); +tcg_gen_extract_i64(dest, dest, sa, 32); } } save_gpr(ctx, a->t, dest); -- 2.34.1
[PULL 40/85] target/hppa: Decode d for cmpclr instructions
Signed-off-by: Richard Henderson --- target/hppa/insns.decode | 6 -- target/hppa/translate.c | 11 +-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index 03b1a11cac..d4a03b0299 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -64,6 +64,7 @@ &rrr_cf_d t r1 r2 cf d &rrr_cf_sh t r1 r2 cf sh &rri_cf t r i cf +&rri_cf_d t r i cf d &rrb_c_fdisp n c f r1 r2 &rib_c_fdisp n c f r i @@ -78,6 +79,7 @@ @rrr_cf_sh .. r2:5 r1:5 cf:4 sh:2 . t:5 &rrr_cf_sh @rrr_cf_sh0 .. r2:5 r1:5 cf:4 ... t:5 &rrr_cf_sh sh=0 @rri_cf .. r:5 t:5 cf:4 . ... &rri_cf i=%lowsign_11 +@rri_cf_d .. r:5 t:5 cf:4 d:1 ... &rri_cf_d i=%lowsign_11 @rrb_cf .. r2:5 r1:5 c:3 ... n:1 . \ &rrb_c_f disp=%assemble_12 @@ -158,7 +160,7 @@ or 10 . . 001001 . . @rrr_cf_d xor 10 . . 001010 . . @rrr_cf_d uxor10 . . 001110 . . @rrr_cf_d ds 10 . . 010001 0 . @rrr_cf -cmpclr 10 . . 100010 0 . @rrr_cf +cmpclr 10 . . 100010 . . @rrr_cf_d uaddcm 10 . . 100110 . . @rrr_cf_d uaddcm_tc 10 . . 100111 . . @rrr_cf_d dcor10 . 0 101110 . . @rr_cf_d @@ -189,7 +191,7 @@ addi_tc_tsv 101100 . . 1 ... @rri_cf subi100101 . . 0 ... @rri_cf subi_tsv100101 . . 1 ... @rri_cf -cmpiclr 100100 . . 0 ... @rri_cf +cmpiclr 100100 . . . ... @rri_cf_d # Index Mem diff --git a/target/hppa/translate.c b/target/hppa/translate.c index a0785bb32c..8301d007ff 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -1377,11 +1377,10 @@ static bool do_sub_imm(DisasContext *ctx, arg_rri_cf *a, bool is_tsv) } static void do_cmpclr(DisasContext *ctx, unsigned rt, TCGv_reg in1, - TCGv_reg in2, unsigned cf) + TCGv_reg in2, unsigned cf, bool d) { TCGv_reg dest, sv; DisasCond cond; -bool d = false; dest = tcg_temp_new(); tcg_gen_sub_reg(dest, in1, in2); @@ -2758,7 +2757,7 @@ static bool trans_xor(DisasContext *ctx, arg_rrr_cf_d *a) return do_log_reg(ctx, a, tcg_gen_xor_reg); } -static bool trans_cmpclr(DisasContext *ctx, arg_rrr_cf *a) +static bool trans_cmpclr(DisasContext *ctx, arg_rrr_cf_d *a) { TCGv_reg tcg_r1, tcg_r2; @@ -2767,7 +2766,7 @@ static bool trans_cmpclr(DisasContext *ctx, arg_rrr_cf *a) } tcg_r1 = load_gpr(ctx, a->r1); tcg_r2 = load_gpr(ctx, a->r2); -do_cmpclr(ctx, a->t, tcg_r1, tcg_r2, a->cf); +do_cmpclr(ctx, a->t, tcg_r1, tcg_r2, a->cf, a->d); return nullify_end(ctx); } @@ -2925,7 +2924,7 @@ static bool trans_subi_tsv(DisasContext *ctx, arg_rri_cf *a) return do_sub_imm(ctx, a, true); } -static bool trans_cmpiclr(DisasContext *ctx, arg_rri_cf *a) +static bool trans_cmpiclr(DisasContext *ctx, arg_rri_cf_d *a) { TCGv_reg tcg_im, tcg_r2; @@ -2935,7 +2934,7 @@ static bool trans_cmpiclr(DisasContext *ctx, arg_rri_cf *a) tcg_im = tcg_constant_reg(a->i); tcg_r2 = load_gpr(ctx, a->r); -do_cmpclr(ctx, a->t, tcg_im, tcg_r2, a->cf); +do_cmpclr(ctx, a->t, tcg_im, tcg_r2, a->cf, a->d); return nullify_end(ctx); } -- 2.34.1
[PULL 09/85] target/hppa: Remove load_const
Replace with tcg_constant_reg. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/hppa/translate.c | 21 +++-- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 3c4a759628..c8384fccd9 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -488,13 +488,6 @@ static void cond_free(DisasCond *cond) } } -static TCGv_reg load_const(DisasContext *ctx, target_sreg v) -{ -TCGv_reg t = tcg_temp_new(); -tcg_gen_movi_reg(t, v); -return t; -} - static TCGv_reg load_gpr(DisasContext *ctx, unsigned reg) { if (reg == 0) { @@ -1164,7 +1157,7 @@ static bool do_add_imm(DisasContext *ctx, arg_rri_cf *a, if (a->cf) { nullify_over(ctx); } -tcg_im = load_const(ctx, a->i); +tcg_im = tcg_constant_reg(a->i); tcg_r2 = load_gpr(ctx, a->r); do_add(ctx, a->t, tcg_im, tcg_r2, 0, 0, is_tsv, is_tc, 0, a->cf); return nullify_end(ctx); @@ -1253,7 +1246,7 @@ static bool do_sub_imm(DisasContext *ctx, arg_rri_cf *a, bool is_tsv) if (a->cf) { nullify_over(ctx); } -tcg_im = load_const(ctx, a->i); +tcg_im = tcg_constant_reg(a->i); tcg_r2 = load_gpr(ctx, a->r); do_sub(ctx, a->t, tcg_im, tcg_r2, is_tsv, 0, 0, a->cf); return nullify_end(ctx); @@ -2808,7 +2801,7 @@ static bool trans_cmpiclr(DisasContext *ctx, arg_rri_cf *a) nullify_over(ctx); } -tcg_im = load_const(ctx, a->i); +tcg_im = tcg_constant_reg(a->i); tcg_r2 = load_gpr(ctx, a->r); do_cmpclr(ctx, a->t, tcg_im, tcg_r2, a->cf); @@ -2994,7 +2987,7 @@ static bool trans_cmpb(DisasContext *ctx, arg_cmpb *a) static bool trans_cmpbi(DisasContext *ctx, arg_cmpbi *a) { nullify_over(ctx); -return do_cmpb(ctx, a->r, load_const(ctx, a->i), a->c, a->f, a->n, a->disp); +return do_cmpb(ctx, a->r, tcg_constant_reg(a->i), a->c, a->f, a->n, a->disp); } static bool do_addb(DisasContext *ctx, unsigned r, TCGv_reg in1, @@ -3033,7 +3026,7 @@ static bool trans_addb(DisasContext *ctx, arg_addb *a) static bool trans_addbi(DisasContext *ctx, arg_addbi *a) { nullify_over(ctx); -return do_addb(ctx, a->r, load_const(ctx, a->i), a->c, a->f, a->n, a->disp); +return do_addb(ctx, a->r, tcg_constant_reg(a->i), a->c, a->f, a->n, a->disp); } static bool trans_bb_sar(DisasContext *ctx, arg_bb_sar *a) @@ -3345,7 +3338,7 @@ static bool trans_depwi_sar(DisasContext *ctx, arg_depwi_sar *a) if (a->c) { nullify_over(ctx); } -return do_depw_sar(ctx, a->t, a->c, a->nz, a->clen, load_const(ctx, a->i)); +return do_depw_sar(ctx, a->t, a->c, a->nz, a->clen, tcg_constant_reg(a->i)); } static bool trans_be(DisasContext *ctx, arg_be *a) @@ -3852,7 +3845,7 @@ static bool trans_ftest(DisasContext *ctx, arg_ftest *a) return true; } if (inv) { -TCGv_reg c = load_const(ctx, mask); +TCGv_reg c = tcg_constant_reg(mask); tcg_gen_or_reg(t, t, c); ctx->null_cond = cond_make(TCG_COND_EQ, t, c); } else { -- 2.34.1
[PULL 65/85] target/hppa: Implement HSHLADD, HSHRADD
Signed-off-by: Richard Henderson --- target/hppa/helper.h | 2 ++ target/hppa/insns.decode | 12 ++-- target/hppa/op_helper.c | 32 target/hppa/translate.c | 32 4 files changed, 76 insertions(+), 2 deletions(-) diff --git a/target/hppa/helper.h b/target/hppa/helper.h index 3b3a543216..d586be3f15 100644 --- a/target/hppa/helper.h +++ b/target/hppa/helper.h @@ -17,6 +17,8 @@ DEF_HELPER_FLAGS_1(ldc_check, TCG_CALL_NO_RWG, void, tl) DEF_HELPER_FLAGS_2(hadd_ss, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(hadd_us, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(havg, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_3(hshladd, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32) +DEF_HELPER_FLAGS_3(hshradd, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32) DEF_HELPER_FLAGS_2(hsub_ss, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(hsub_us, TCG_CALL_NO_RWG_SE, i64, i64, i64) diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index bb5cd267b0..87db726d9e 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -68,6 +68,7 @@ &rrrt r1 r2 &rrr_cf t r1 r2 cf &rrr_cf_d t r1 r2 cf d +&rrr_sh t r1 r2 sh &rrr_cf_d_sht r1 r2 cf d sh &rrit r i &rri_cf t r i cf @@ -86,6 +87,7 @@ @rrr.. r2:5 r1:5 ... t:5 &rrr @rrr_cf .. r2:5 r1:5 cf:4 ... t:5 &rrr_cf @rrr_cf_d .. r2:5 r1:5 cf:4 .. d:1 t:5&rrr_cf_d +@rrr_sh .. r2:5 r1:5 sh:2 . t:5&rrr_sh @rrr_cf_d_sh.. r2:5 r1:5 cf:4 sh:2 d:1 t:5 &rrr_cf_d_sh @rrr_cf_d_sh0 .. r2:5 r1:5 cf:4 .. d:1 t:5&rrr_cf_d_sh sh=0 @rri_cf .. r:5 t:5 cf:4 . ... &rri_cf i=%lowsign_11 @@ -187,14 +189,20 @@ dcor_i 10 . 0 10 . . @rr_cf_d add 10 . . 0110.. . . @rrr_cf_d_sh add_l 10 . . 1010.. . . @rrr_cf_d_sh add_tsv 10 . . 1110.. . . @rrr_cf_d_sh -add_c 10 . . 011100 . . @rrr_cf_d_sh0 +{ + add_c 10 . . 011100 . . @rrr_cf_d_sh0 + hshladd 10 . . 0111.. 0 . @rrr_sh +} add_c_tsv 10 . . 00 . . @rrr_cf_d_sh0 sub 10 . . 01 . . @rrr_cf_d sub_tsv 10 . . 11 . . @rrr_cf_d sub_tc 10 . . 010011 . . @rrr_cf_d sub_tsv_tc 10 . . 110011 . . @rrr_cf_d -sub_b 10 . . 010100 . . @rrr_cf_d +{ + sub_b 10 . . 010100 . . @rrr_cf_d + hshradd 10 . . 0101.. 0 . @rrr_sh +} sub_b_tsv 10 . . 110100 . . @rrr_cf_d ldil001000 t:5 .i=%assemble_21 diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c index e76f201472..a0e31c0c25 100644 --- a/target/hppa/op_helper.c +++ b/target/hppa/op_helper.c @@ -455,3 +455,35 @@ uint64_t HELPER(hsub_us)(uint64_t r1, uint64_t r2) } return ret; } + +uint64_t HELPER(hshladd)(uint64_t r1, uint64_t r2, uint32_t sh) +{ +uint64_t ret = 0; + +for (int i = 0; i < 64; i += 16) { +int f1 = sextract64(r1, i, 16); +int f2 = sextract64(r2, i, 16); +int fr = (f1 << sh) + f2; + +fr = MIN(fr, INT16_MAX); +fr = MAX(fr, INT16_MIN); +ret = deposit64(ret, i, 16, fr); +} +return ret; +} + +uint64_t HELPER(hshradd)(uint64_t r1, uint64_t r2, uint32_t sh) +{ +uint64_t ret = 0; + +for (int i = 0; i < 64; i += 16) { +int f1 = sextract64(r1, i, 16); +int f2 = sextract64(r2, i, 16); +int fr = (f1 >> sh) + f2; + +fr = MIN(fr, INT16_MAX); +fr = MAX(fr, INT16_MIN); +ret = deposit64(ret, i, 16, fr); +} +return ret; +} diff --git a/target/hppa/translate.c b/target/hppa/translate.c index a3a12d63f8..648c37fb28 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -2809,6 +2809,28 @@ static bool do_multimedia_sh(DisasContext *ctx, arg_rri *a, return nullify_end(ctx); } +static bool do_multimedia_shadd(DisasContext *ctx, arg_rrr_sh *a, +void (*fn)(TCGv_i64, TCGv_i64, + TCGv_i64, TCGv_i32)) +{ +TCGv_i64 r1, r2, dest; + +if (!ctx->is_pa20) { +return false; +} + +nullify_over(ctx); + +r1 = load_gpr(ctx, a->r1); +r2 = load_gpr(ctx, a->r2); +dest = dest_gpr(ctx, a->t); + +fn(dest, r1, r2, tcg_constant_i32(a->sh)); +save_gpr(ctx, a->t, dest); + +return nullify_end(ctx); +} + static bool trans_hadd(DisasContext *ctx, arg_rrr *a) { return do_multimedia(ctx, a, tcg_gen_vec_
Re: [PULL 00/35] tcg patch queue
On Tue, 7 Nov 2023 at 10:56, Richard Henderson wrote: > > Dangit, forgot the PULL tag. Okay, thanks for pointing it out. I've added this to the staging branch. Stefan > > r~ > > On 11/6/23 18:48, Richard Henderson wrote: > > The following changes since commit 3e01f1147a16ca566694b97eafc941d62fa1e8d8: > > > >Merge tag 'pull-sp-20231105' of https://gitlab.com/rth7680/qemu into > > staging (2023-11-06 09:34:22 +0800) > > > > are available in the Git repository at: > > > >https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20231106 > > > > for you to fetch changes up to d36ce28be424385fc9f7273bf5c15ce815b5cf4e: > > > >tcg/sparc64: Implement tcg_out_extrl_i64_i32 (2023-11-06 10:48:46 -0800) > > > > > > util: Add cpuinfo for loongarch64 > > tcg/loongarch64: Use cpuinfo.h > > tcg/loongarch64: Improve register allocation for INDEX_op_qemu_ld_a*_i128 > > host/include/loongarch64: Add atomic16 load and store > > tcg: Move expanders out of line > > tcg/mips: Always implement movcond > > tcg/mips: Implement neg opcodes > > tcg/loongarch64: Implement neg opcodes > > tcg: Make movcond and neg required opcodes > > tcg: Optimize env memory operations > > tcg: Canonicalize sub of immediate to add > > tcg/sparc64: Implement tcg_out_extrl_i64_i32 > > > > > > Richard Henderson (35): > >accel/tcg: Move HMP info jit and info opcount code > >tcg: Add C_N2_I1 > >tcg/loongarch64: Use C_N2_I1 for INDEX_op_qemu_ld_a*_i128 > >util: Add cpuinfo for loongarch64 > >tcg/loongarch64: Use cpuinfo.h > >host/include/loongarch64: Add atomic16 load and store > >accel/tcg: Remove redundant case in store_atom_16 > >accel/tcg: Fix condition for store_atom_insert_al16 > >tcg: Mark tcg_gen_op* as noinline > >tcg: Move tcg_gen_op* out of line > >tcg: Move generic expanders out of line > >tcg: Move 32-bit expanders out of line > >tcg: Move 64-bit expanders out of line > >tcg: Move vec_gen_* declarations to tcg-internal.h > >tcg: Move tcg_gen_opN declarations to tcg-internal.h > >tcg: Unexport tcg_gen_op*_{i32,i64} > >tcg: Move tcg_constant_* out of line > >tcg: Move tcg_temp_new_*, tcg_global_mem_new_* out of line > >tcg: Move tcg_temp_free_* out of line > >tcg/mips: Split out tcg_out_setcond_int > >tcg/mips: Always implement movcond > >tcg: Remove TCG_TARGET_HAS_movcond_{i32,i64} > >tcg/mips: Implement neg opcodes > >tcg/loongarch64: Implement neg opcodes > >tcg: Remove TCG_TARGET_HAS_neg_{i32,i64} > >tcg: Don't free vector results > >tcg/optimize: Pipe OptContext into reset_ts > >tcg/optimize: Split out cmp_better_copy > >tcg/optimize: Optimize env memory operations > >tcg: Eliminate duplicate env store operations > >tcg/optimize: Split out arg_new_constant > >tcg: Canonicalize subi to addi during opcode generation > >tcg/optimize: Canonicalize subi to addi during optimization > >tcg/optimize: Canonicalize sub2 with constants to add2 > >tcg/sparc64: Implement tcg_out_extrl_i64_i32 > > > > accel/tcg/internal-common.h| 2 - > > host/include/loongarch64/host/atomic128-ldst.h | 52 ++ > > host/include/loongarch64/host/cpuinfo.h| 21 + > > .../loongarch64/host/load-extract-al16-al8.h | 39 ++ > > host/include/loongarch64/host/store-insert-al16.h | 12 + > > include/exec/cputlb.h | 1 - > > include/tcg/tcg-op-common.h| 538 ++--- > > include/tcg/tcg-opc.h | 8 +- > > include/tcg/tcg-temp-internal.h| 56 +- > > include/tcg/tcg.h | 82 --- > > tcg/aarch64/tcg-target.h | 4 - > > tcg/arm/tcg-target.h | 2 - > > tcg/i386/tcg-target.h | 4 - > > tcg/loongarch64/tcg-target-con-set.h | 2 +- > > tcg/loongarch64/tcg-target.h | 12 +- > > tcg/mips/tcg-target.h | 4 - > > tcg/ppc/tcg-target.h | 4 - > > tcg/ri
[PULL 60/85] target/hppa: Replace tcg_gen_*_tl with tcg_gen_*_i64
Signed-off-by: Richard Henderson --- target/hppa/translate.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/target/hppa/translate.c b/target/hppa/translate.c index c8c702ac03..1d749e2a78 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -1338,10 +1338,10 @@ static void form_gva(DisasContext *ctx, TCGv_i64 *pgva, TCGv_i64 *pofs, *pofs = ofs; *pgva = addr = tcg_temp_new_i64(); -tcg_gen_andi_tl(addr, modify <= 0 ? ofs : base, gva_offset_mask(ctx)); +tcg_gen_andi_i64(addr, modify <= 0 ? ofs : base, gva_offset_mask(ctx)); #ifndef CONFIG_USER_ONLY if (!is_phys) { -tcg_gen_or_tl(addr, addr, space_select(ctx, sp, base)); +tcg_gen_or_i64(addr, addr, space_select(ctx, sp, base)); } #endif } @@ -2382,7 +2382,7 @@ static bool trans_ixtlbxf(DisasContext *ctx, arg_ixtlbxf *a) a->data ? offsetof(CPUHPPAState, cr[CR_IOR]) : offsetof(CPUHPPAState, cr[CR_IIAOQ])); tcg_gen_shli_i64(stl, stl, 32); -tcg_gen_or_tl(addr, atl, stl); +tcg_gen_or_i64(addr, atl, stl); reg = load_gpr(ctx, a->r); if (a->addr) { @@ -2942,7 +2942,7 @@ static bool trans_ldo(DisasContext *ctx, arg_ldo *a) TCGv_i64 tcg_rt = dest_gpr(ctx, a->t); /* Special case rb == 0, for the LDI pseudo-op. - The COPY pseudo-op is handled for free within tcg_gen_addi_tl. */ + The COPY pseudo-op is handled for free within tcg_gen_addi_i64. */ if (a->b == 0) { tcg_gen_movi_i64(tcg_rt, a->i); } else { -- 2.34.1
[PULL 79/85] target/hppa: Create raise_exception_with_ior
Handle pa2.0 logic for filling in ISR+IOR. Signed-off-by: Richard Henderson --- target/hppa/mem_helper.c | 64 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c index 602e6c809f..858ce6ec7f 100644 --- a/target/hppa/mem_helper.c +++ b/target/hppa/mem_helper.c @@ -289,6 +289,53 @@ hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) return excp == EXCP_DTLB_MISS ? -1 : phys; } +G_NORETURN static void +raise_exception_with_ior(CPUHPPAState *env, int excp, uintptr_t retaddr, + vaddr addr, bool mmu_disabled) +{ +CPUState *cs = env_cpu(env); + +cs->exception_index = excp; + +if (env->psw & PSW_Q) { +/* + * For pa1.x, the offset and space never overlap, and so we + * simply extract the high and low part of the virtual address. + * + * For pa2.0, the formation of these are described in section + * "Interruption Parameter Registers", page 2-15. + */ +env->cr[CR_IOR] = (uint32_t)addr; +env->cr[CR_ISR] = addr >> 32; + +if (hppa_is_pa20(env)) { +if (mmu_disabled) { +/* + * If data translation was disabled, the ISR contains + * the upper portion of the abs address, zero-extended. + */ +env->cr[CR_ISR] &= 0x3fff; +} else { +/* + * If data translation was enabled, the upper two bits + * of the IOR (the b field) are equal to the two space + * bits from the base register used to form the gva. + */ +uint64_t b; + +cpu_restore_state(cs, retaddr); + +b = env->gr[env->unwind_breg]; +b >>= (env->psw & PSW_W ? 62 : 30); +env->cr[CR_IOR] |= b << 62; + +cpu_loop_exit(cs); +} +} +} +cpu_loop_exit_restore(cs, retaddr); +} + bool hppa_cpu_tlb_fill(CPUState *cs, vaddr addr, int size, MMUAccessType type, int mmu_idx, bool probe, uintptr_t retaddr) @@ -318,14 +365,10 @@ bool hppa_cpu_tlb_fill(CPUState *cs, vaddr addr, int size, return false; } trace_hppa_tlb_fill_excp(env, addr, size, type, mmu_idx); + /* Failure. Raise the indicated exception. */ -cs->exception_index = excp; -if (cpu->env.psw & PSW_Q) { -/* ??? Needs tweaking for hppa64. */ -cpu->env.cr[CR_IOR] = addr; -cpu->env.cr[CR_ISR] = addr >> 32; -} -cpu_loop_exit_restore(cs, retaddr); +raise_exception_with_ior(env, excp, retaddr, + addr, mmu_idx == MMU_PHYS_IDX); } trace_hppa_tlb_fill_success(env, addr & TARGET_PAGE_MASK, @@ -553,16 +596,11 @@ target_ulong HELPER(lpa)(CPUHPPAState *env, target_ulong addr) excp = hppa_get_physical_address(env, addr, MMU_KERNEL_IDX, 0, &phys, &prot, NULL); if (excp >= 0) { -if (env->psw & PSW_Q) { -/* ??? Needs tweaking for hppa64. */ -env->cr[CR_IOR] = addr; -env->cr[CR_ISR] = addr >> 32; -} if (excp == EXCP_DTLB_MISS) { excp = EXCP_NA_DTLB_MISS; } trace_hppa_tlb_lpa_failed(env, addr); -hppa_dynamic_excp(env, excp, GETPC()); +raise_exception_with_ior(env, excp, GETPC(), addr, false); } trace_hppa_tlb_lpa_success(env, addr, phys); return phys; -- 2.34.1
[PULL 73/85] linux-user/hppa: Drop EXCP_DUMP from handled exceptions
Signed-off-by: Richard Henderson --- linux-user/hppa/cpu_loop.c | 4 1 file changed, 4 deletions(-) diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c index 8ab1335106..d5232f37fe 100644 --- a/linux-user/hppa/cpu_loop.c +++ b/linux-user/hppa/cpu_loop.c @@ -147,12 +147,10 @@ void cpu_loop(CPUHPPAState *env) force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR, env->iaoq_f); break; case EXCP_ILL: -EXCP_DUMP(env, "qemu: EXCP_ILL exception %#x\n", trapnr); force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->iaoq_f); break; case EXCP_PRIV_OPR: /* check for glibc ABORT_INSTRUCTION "iitlbp %r0,(%sr0, %r0)" */ -EXCP_DUMP(env, "qemu: EXCP_PRIV_OPR exception %#x\n", trapnr); if (env->cr[CR_IIR] == 0x0400) { force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->iaoq_f); } else { @@ -160,7 +158,6 @@ void cpu_loop(CPUHPPAState *env) } break; case EXCP_PRIV_REG: -EXCP_DUMP(env, "qemu: EXCP_PRIV_REG exception %#x\n", trapnr); force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVREG, env->iaoq_f); break; case EXCP_OVERFLOW: @@ -173,7 +170,6 @@ void cpu_loop(CPUHPPAState *env) force_sig_fault(TARGET_SIGFPE, 0, env->iaoq_f); break; case EXCP_BREAK: -EXCP_DUMP(env, "qemu: EXCP_BREAK exception %#x\n", trapnr); force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->iaoq_f & ~3); break; case EXCP_DEBUG: -- 2.34.1
[PULL 46/85] target/hppa: Decode ADDB double-word
Signed-off-by: Richard Henderson --- target/hppa/translate.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 7f767fea64..1b4fa401ba 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -3143,6 +3143,17 @@ static bool do_addb(DisasContext *ctx, unsigned r, TCGv_reg in1, DisasCond cond; bool d = false; +/* + * For hppa64, the ADDB conditions change with PSW.W, + * dropping ZNV, SV, OD in favor of double-word EQ, LT, LE. + */ +if (ctx->tb_flags & PSW_W) { +d = c >= 5; +if (d) { +c &= 3; +} +} + in2 = load_gpr(ctx, r); dest = tcg_temp_new(); sv = NULL; -- 2.34.1
[PULL 23/85] target/hppa: Adjust hppa_cpu_dump_state for hppa64
Dump all 64 bits for pa2.0 and low 32 bits for pa1.x. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/hppa/helper.c | 28 +++- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/target/hppa/helper.c b/target/hppa/helper.c index fa17fe6931..c973b65bea 100644 --- a/target/hppa/helper.c +++ b/target/hppa/helper.c @@ -111,18 +111,26 @@ void cpu_hppa_put_psw(CPUHPPAState *env, target_ureg psw) void hppa_cpu_dump_state(CPUState *cs, FILE *f, int flags) { -HPPACPU *cpu = HPPA_CPU(cs); -CPUHPPAState *env = &cpu->env; +CPUHPPAState *env = cpu_env(cs); target_ureg psw = cpu_hppa_get_psw(env); target_ureg psw_cb; char psw_c[20]; -int i; +int i, w; +uint64_t m; + +if (hppa_is_pa20(env)) { +w = 16; +m = UINT64_MAX; +} else { +w = 8; +m = UINT32_MAX; +} qemu_fprintf(f, "IA_F " TARGET_FMT_lx " IA_B " TARGET_FMT_lx - " IIR " TREG_FMT_lx "\n", + " IIR %0*" PRIx64 "\n", hppa_form_gva_psw(psw, env->iasq_f, env->iaoq_f), hppa_form_gva_psw(psw, env->iasq_b, env->iaoq_b), - env->cr[CR_IIR]); + w, m & env->cr[CR_IIR]); psw_c[0] = (psw & PSW_W ? 'W' : '-'); psw_c[1] = (psw & PSW_E ? 'E' : '-'); @@ -143,13 +151,15 @@ void hppa_cpu_dump_state(CPUState *cs, FILE *f, int flags) psw_c[16] = (psw & PSW_D ? 'D' : '-'); psw_c[17] = (psw & PSW_I ? 'I' : '-'); psw_c[18] = '\0'; -psw_cb = ((env->psw_cb >> 4) & 0x0111) | (env->psw_cb_msb << 28); +psw_cb = ((env->psw_cb >> 4) & ((target_ureg)-1 / 0xf)) + | (env->psw_cb_msb << (TARGET_REGISTER_BITS - 4)); -qemu_fprintf(f, "PSW " TREG_FMT_lx " CB " TREG_FMT_lx " %s\n", - psw, psw_cb, psw_c); +qemu_fprintf(f, "PSW %0*" PRIx64 " CB %0*" PRIx64 " %s\n", + w, m & psw, w, m & psw_cb, psw_c); for (i = 0; i < 32; i++) { -qemu_fprintf(f, "GR%02d " TREG_FMT_lx "%c", i, env->gr[i], +qemu_fprintf(f, "GR%02d %0*" PRIx64 "%c", + i, w, m & env->gr[i], (i & 3) == 3 ? '\n' : ' '); } #ifndef CONFIG_USER_ONLY -- 2.34.1
[PULL 37/85] target/hppa: Remove TARGET_HPPA64
Allow both user-only and system mode to run pa2.0 cpus. Avoid creating a separate qemu-system-hppa64 binary; force the qemu-hppa binary to use TARGET_ABI32. Signed-off-by: Richard Henderson --- configs/targets/hppa-linux-user.mak | 1 + target/hppa/cpu-param.h | 23 +++ target/hppa/cpu.h | 9 - target/hppa/cpu.c | 2 -- target/hppa/translate.c | 2 -- 5 files changed, 8 insertions(+), 29 deletions(-) diff --git a/configs/targets/hppa-linux-user.mak b/configs/targets/hppa-linux-user.mak index 361ea39d71..8e0a80492f 100644 --- a/configs/targets/hppa-linux-user.mak +++ b/configs/targets/hppa-linux-user.mak @@ -1,4 +1,5 @@ TARGET_ARCH=hppa +TARGET_ABI32=y TARGET_SYSTBL_ABI=common,32 TARGET_SYSTBL=syscall.tbl TARGET_BIG_ENDIAN=y diff --git a/target/hppa/cpu-param.h b/target/hppa/cpu-param.h index c2791ae5f2..2fb8e7924b 100644 --- a/target/hppa/cpu-param.h +++ b/target/hppa/cpu-param.h @@ -8,26 +8,17 @@ #ifndef HPPA_CPU_PARAM_H #define HPPA_CPU_PARAM_H -#ifdef TARGET_HPPA64 -# define TARGET_LONG_BITS 64 -# define TARGET_REGISTER_BITS 64 -# define TARGET_VIRT_ADDR_SPACE_BITS 64 -# define TARGET_PHYS_ADDR_SPACE_BITS 64 -#elif defined(CONFIG_USER_ONLY) -# define TARGET_LONG_BITS 32 -# define TARGET_REGISTER_BITS 32 +#define TARGET_LONG_BITS 64 +#define TARGET_REGISTER_BITS 64 + +#if defined(CONFIG_USER_ONLY) && defined(TARGET_ABI32) +# define TARGET_PHYS_ADDR_SPACE_BITS 32 # define TARGET_VIRT_ADDR_SPACE_BITS 32 -# define TARGET_PHYS_ADDR_SPACE_BITS 32 #else -/* - * In order to form the GVA from space:offset, - * we need a 64-bit virtual address space. - */ -# define TARGET_LONG_BITS 64 -# define TARGET_REGISTER_BITS 32 +# define TARGET_PHYS_ADDR_SPACE_BITS 64 # define TARGET_VIRT_ADDR_SPACE_BITS 64 -# define TARGET_PHYS_ADDR_SPACE_BITS 32 #endif + #define TARGET_PAGE_BITS 12 #endif diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index cb838defb0..77ddb20ac2 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -120,11 +120,7 @@ #define PSW_T0x0100 #define PSW_S0x0200 #define PSW_E0x0400 -#ifdef TARGET_HPPA64 #define PSW_W0x0800 /* PA2.0 only */ -#else -#define PSW_W0 -#endif #define PSW_Z0x4000 /* PA1.x only */ #define PSW_Y0x8000 /* PA1.x only */ @@ -137,13 +133,8 @@ #define PSW_SM_P PSW_P #define PSW_SM_Q PSW_Q /* Enable Interrupt State Collection */ #define PSW_SM_R PSW_R /* Enable Recover Counter Trap */ -#ifdef TARGET_HPPA64 #define PSW_SM_E 0x100 #define PSW_SM_W 0x200 /* PA2.0 only : Enable Wide Mode */ -#else -#define PSW_SM_E 0 -#define PSW_SM_W 0 -#endif #define CR_RC0 #define CR_PID1 8 diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index 70ce0c3b99..9582619be2 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c @@ -252,12 +252,10 @@ static const TypeInfo hppa_cpu_type_infos[] = { .class_size = sizeof(HPPACPUClass), .class_init = hppa_cpu_class_init, }, -#ifdef TARGET_HPPA64 { .name = TYPE_HPPA64_CPU, .parent = TYPE_HPPA_CPU, }, -#endif }; DEFINE_TYPES(hppa_cpu_type_infos) diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 41f4e06841..187d47f4c3 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -2177,7 +2177,6 @@ static bool trans_mfctl(DisasContext *ctx, arg_mfctl *a) switch (ctl) { case CR_SAR: -#ifdef TARGET_HPPA64 if (a->e == 0) { /* MFSAR without ,W masks low 5 bits. */ tmp = dest_gpr(ctx, rt); @@ -2185,7 +2184,6 @@ static bool trans_mfctl(DisasContext *ctx, arg_mfctl *a) save_gpr(ctx, rt, tmp); goto done; } -#endif save_gpr(ctx, rt, cpu_sar); goto done; case CR_IT: /* Interval Timer */ -- 2.34.1