Re: [Qemu-devel] [PATCHv3 1/6] ui/vnc: introduce VNC_DIRTY_PIXELS_PER_BIT macro
On 06.01.2014 07:52, Wenchao Xia wrote: @@ -781,10 +784,10 @@ static void vnc_dpy_copy(DisplayChangeListener *dcl, if ((s = w - w_lim) == 0) break; } else if (!x) { -s = (16 - (dst_x % 16)); +s = (16 - (dst_x % VNC_DIRTY_PIXELS_PER_BIT)); Should it be s = (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT)); ? Thanks, you are right. Peter
Re: [Qemu-devel] [PATCH] hw/misc/blob-loader: add a generic blob loader
On 6 January 2014 07:56, Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: On Mon, Jan 6, 2014 at 5:41 PM, Peter Maydell peter.mayd...@linaro.org wrote: That raises some more general design questions: * how is this expected to interact with rom blob loading, -machine firmware=, etc? I guess it's not. The behavior of -machine firmware= is machine specific, so a machine specific undefined behavior will occur if you have overlap issues. The two should not in any way inhibit each other. They are independent mechanisms. What are the guidelines for when to use one or the other? -machine firmware= if you want to load a firmware blob in a board specific way. This if you want to place a blob in memory at an arbitrary location on reset. I guess I don't much like the way we're solving a problem by adding yet another mechanism here rather than trying to produce a design for blob loading that works for all the use cases we have. thanks -- PMM
Re: [Qemu-devel] [PATCH v1 2/3] qcow2: fix offset overflow
On Mon, Dec 30, 2013 at 01:29:08PM +0800, Hu Tao wrote: When cluster size is big enough it can lead offset overflow in qcow2_alloc_clusters_at(). This patch fixes it. ping. and be more descriptive: The allocation each time is stopped at L2 table boundary(see handle_alloc()), so the possible maximum bytes could be 2^(cluster_bits - 3 + cluster_bits) so int is safe for cluster_bits=17, unsafe otherwise. Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- block/qcow2-refcount.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index c974abe..b3ebb7f 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -676,7 +676,12 @@ int qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset, BDRVQcowState *s = bs-opaque; uint64_t cluster_index; uint64_t old_free_cluster_index; -int i, refcount, ret; +uint64_t i; +int refcount, ret; + +if (nb_clusters = 0) { +return 0; +} /* Check how many clusters there are free */ cluster_index = offset s-cluster_bits; -- 1.7.11.7
Re: [Qemu-devel] [PATCH resend] linux-user: Support the accept4 socketcall
Le 6 janvier 2014 à 02:57, André Hentschel n...@dawncrow.de a écrit : From: André Hentschel n...@dawncrow.de Cc: Riku Voipio riku.voi...@iki.fi Signed-off-by: André Hentschel n...@dawncrow.de [...] diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index cf08db5..b36f99c 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -27,6 +27,9 @@ #define SOCKOP_getsockopt 15 #define SOCKOP_sendmsg 16 #define SOCKOP_recvmsg 17 +#define SOCKOP_accept4 18 +#define SOCKOP_recvmmsg 19 +#define SOCKOP_sendmmsg 20 Don't add these both defines here as they are not used in this patch. Regards, Laurent
Re: [Qemu-devel] [PULL 0/2] OpenRISC patch queue for 1.8
ping~~ On Sat, Dec 21, 2013 at 9:47 AM, Jia Liu pro...@gmail.com wrote: Hi Anthony, This is my OpenRISC patch queue for 1.8, it have been well tested, please pull. Thanks to Richard Henderson, he made the LD/ST updated. Thanks to Stefan Weil, he fixed a typo. Regards, Jia The following changes since commit f8251db121c3f051b22a7536b97d160c30bcccd4: Merge remote-tracking branch 'agraf/tags/signed-ppc-for-upstream' into staging (2013-12-19 17:03:17 -0800) are available in the git repository at: git://github.com/J-Liu/qemu.git or32 for you to fetch changes up to 31ab4c235b7f7342f727fd835e732623753e1ffb: target-openrisc: Use new qemu_ld/st opcodes (2013-12-21 09:38:18 +0800) Richard Henderson (1): target-openrisc: Use new qemu_ld/st opcodes Stefan Weil (1): openrisc: Fix spelling in comment (transaltion - translation) target-openrisc/translate.c | 101 +++- 1 file changed, 33 insertions(+), 68 deletions(-)
Re: [Qemu-devel] [PATCH resend] linux-user: Support the accept4 socketcall
On 6 January 2014 08:45, Laurent Vivier laur...@vivier.eu wrote: Le 6 janvier 2014 à 02:57, André Hentschel n...@dawncrow.de a écrit : diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index cf08db5..b36f99c 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -27,6 +27,9 @@ #define SOCKOP_getsockopt 15 #define SOCKOP_sendmsg 16 #define SOCKOP_recvmsg 17 +#define SOCKOP_accept4 18 +#define SOCKOP_recvmmsg 19 +#define SOCKOP_sendmmsg 20 Don't add these both defines here as they are not used in this patch. It doesn't seem that unreasonable to add them. We add things to the main syscall number #define list even if we aren't actually implementing them, for example. thanks -- PMM
[Qemu-devel] [Bug 1265998] Re: vfio-pci passed Radeon 7870XT is unstable on first boot of a Windows 8.1 guest
Sorry, I propably just was lucky. It doesn't work without hugepages also. The only thing I can do to make the 7870XT operate correclty under guest is to make it show qemu-system-x86_64: vfio_dma_map(0x7f01db7deec0, 0xc, 0xaff4, 0x2aaac00c) = -16 (Device or resource busy) errors on start. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1265998 Title: vfio-pci passed Radeon 7870XT is unstable on first boot of a Windows 8.1 guest Status in QEMU: New Bug description: I'm passing a Radeon 7870XT to a Windows 8.1 guest. It works flawlessly (I tested it by a 12 hour Furmark run), but only on second lauch of the guest. On first launch after I get screen corruption on any 3D operation in guest (even showing a search box in Chrome) and the guest becomes unusable with constant driver resets to a point, when it grinds to a halt. At that moment I get about ~1K of log entries similar to sty 04 11:12:57 miner kernel: AMD-Vi: Event logged [IO_PAGE_FAULT device=01:00.0 domain=0x0002 address=0x7bc4c100 flags=0x0010] sty 04 11:12:57 miner kernel: AMD-Vi: Event logged [IO_PAGE_FAULT device=01:00.0 domain=0x0002 When I abort first launch of the quest with a monitor quit command during during guest BIOS initialisation, on a second launch I get the following errors in Qemu monitor: qemu-system-x86_64: vfio_dma_map(0x7f4b93fbbd40, 0x0, 0xb000, 0x2aaac000) = -16 (Device or resource busy) qemu-system-x86_64: vfio_dma_map(0x7f4b93fbbd40, 0xc, 0xaff4, 0x2aaac00c) = -16 (Device or resource busy) qemu-system-x86_64: vfio_dma_map(0x7f4b93fbbd40, 0xc8000, 0xaff38000, 0x2aaac00c8000) = -16 (Device or resource busy) qemu-system-x86_64: vfio_dma_map(0x7f4b93fbbd40, 0xd, 0xaff3, 0x2aaac00d) = -16 (Device or resource busy) and the following entries in the kernel log sty 01 22:04:53 miner kernel: vfio_ecap_init: :01:00.0 hiding ecap 0x1b@0x2d0 sty 01 22:04:55 miner kernel: [ cut here ] sty 01 22:04:55 miner kernel: WARNING: CPU: 3 PID: 1012 at drivers/vfio/vfio_iommu_type1.c:685 vfio_dma_do_map+0x43c/0x838 [vfio_iommu_type1]() sty 01 22:04:55 miner kernel: Modules linked in: tun bridge stp llc bnep vfio_pci vfio_iommu_type1 vfio fuse ts2020 ds3000 dvb_usb_dw2102 kvm_amd kvm crc32_pclmul c...luetooth rc_ sty 01 22:04:55 miner kernel: CPU: 3 PID: 1012 Comm: qemu-system-x86 Not tainted 3.13.0-2-mainline #1 sty 01 22:04:55 miner kernel: Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./FM2A85X Extreme6, BIOS P2.30 07/11/2013 sty 01 22:04:55 miner kernel: 0009 8804311b9d20 814ddc72 sty 01 22:04:55 miner kernel: 8804311b9d58 8105f2ed fff0 b000 sty 01 22:04:55 miner kernel: 000b b000 8804311b9d68 sty 01 22:04:55 miner kernel: Call Trace: sty 01 22:04:55 miner kernel: [814ddc72] dump_stack+0x4d/0x6f sty 01 22:04:55 miner kernel: [8105f2ed] warn_slowpath_common+0x7d/0xa0 sty 01 22:04:55 miner kernel: [8105f3ca] warn_slowpath_null+0x1a/0x20 sty 01 22:04:55 miner kernel: [a0ce9dec] vfio_dma_do_map+0x43c/0x838 [vfio_iommu_type1] sty 01 22:04:55 miner kernel: [a0cea3f9] vfio_iommu_type1_ioctl+0x211/0x288 [vfio_iommu_type1] sty 01 22:04:55 miner kernel: [a0ce0e28] vfio_fops_unl_ioctl+0x78/0x340
Re: [Qemu-devel] [PATCH v3 3/3] qmp: full introspection support for QMP
On 2014年01月05日 20:02, Amos Kong wrote: This patch introduces a new monitor command to query QMP schema information, the return data is a range of schema structs, which contains the useful metadata to help management to check supported features, QMP commands detail, etc. It parses all json definition in qapi-schema.json, and generate a dynamic struct tree, QMP infrastructure will convert the tree to json string and return to QMP client. I defined a 'DataObject' union in qapi-schema.json, it's used to describe the dynamic data struct. I also added a document about QMP full introspection support (docs/qmp-full-introspection.txt), it helps to use the new interface and understand the abstract method in describing the dynamic struct. TODO: Wenchao Xia is working to convert QMP events to qapi-schema.json, then event can also be queried by this interface. I will introduce another command 'query-qga-schema' to query QGA schema information, it's easy to add this support based on this patch. Signed-off-by: Amos Kong ak...@redhat.com --- I have a few comments on the current implementation below, there are a few things to improve. However I agree to what Eric suggested in reply to V2: it may be better to generate most of the response data in python code at compile time and simplify the logic in C. Because this implementation is slow and it is unnecessary runtime computation. It also duplicates much of existing qapi.py logic (data types and other semantics parsing). docs/qmp-full-introspection.txt | 97 ++ qapi-schema.json| 150 qmp-commands.hx | 43 - qmp.c | 382 4 files changed, 671 insertions(+), 1 deletion(-) create mode 100644 docs/qmp-full-introspection.txt diff --git a/docs/qmp-full-introspection.txt b/docs/qmp-full-introspection.txt new file mode 100644 index 000..1617df7 --- /dev/null +++ b/docs/qmp-full-introspection.txt @@ -0,0 +1,97 @@ += Full introspection support for QMP = + + +== Purpose == + +Add a new monitor command for management to query QMP schema +information, it returns a range of schema structs, which contain the +useful metadata to help management to check supported features, QMP +commands detail, etc. + +== Usage == + +Json schema: + { 'type': 'NameInfo', 'data': {'*name': 'str'} } + { 'command': 'query-name', 'returns': 'NameInfo' } + +Execute QMP command: + + { execute: query-qmp-schema } + +Returns: + + { return: [ + { + name: query-name, + type: command, + returns: { + name: NameInfo, + type: type, + data: [ + { + name: name, + optional: true, + recursive: false, + type: str + } + ] + } + }, + ... + } + +The whole schema information will be returned in one go, it contains +all the schema entries. It doesn't support to be filtered by type +or name. Currently it takes about 5 seconds to return about 1.5M string. + +== 'DataObject' union == + +{ 'union': 'DataObject', + 'base': 'DataObjectBase', + 'discriminator': 'type', + 'data': { +'anonymous-struct': 'DataObjectAnonymousStruct', +'command': 'DataObjectCommand', +'enumeration': 'DataObjectEnumeration', +'reference-type': 'String', +'type': 'DataObjectType', +'unionobj': 'DataObjectUnion' } } + +Currently we have schema difinitions for type, command, enumeration, +union. Some arbitrary structs (dictionary, list or string) and native +types are also used in the body of definitions. + +Here we use DataObject union to abstract all above schema. We want +to provide more useful metadata, and used some enum/unions to indicate +the dynamic type. In the output, some simple data is processed too +unwieldy. In another side, some complex data is described clearly. +It's also caused by some limitation of QAPI infrastructure. + +So we define 'DataObject' to be an union, it always has an object name +except anonymous struct. + +'command', 'enumeration', 'type', 'unionobj' are common schema type, +'union' is a build-in type, so I used unionobj here. + +'reference-type' will be used to describe native types and unextended +types. + +'anonymous-struct' will be used to describe arbitrary structs +(dictionary, list or string). + +== Avoid dead loop in recursive extending == + +We have four types (ImageInfo, BlockStats, PciDeviceInfo, ObjectData) +that uses themself in their own define data directly or indirectly, +we will not repeatedly extend them to avoid dead loop. + +We use a string to record the visit path, type index of each node +will be saved to the string, indexes are split by ':'. + +Push index to visit_path_str before extending, and pop index from +visit_path_str after extending. + +If the type was already extended in parent node, we
Re: [Qemu-devel] vhost-net issue: does not survive reboot on ppc64
On 12/27/2013 12:44 PM, Alexey Kardashevskiy wrote: On 12/27/2013 02:12 AM, Michael S. Tsirkin wrote: On Fri, Dec 27, 2013 at 01:59:19AM +1100, Alexey Kardashevskiy wrote: On 12/27/2013 12:48 AM, Michael S. Tsirkin wrote: On Thu, Dec 26, 2013 at 11:51:04PM +1100, Alexey Kardashevskiy wrote: On 12/26/2013 09:49 PM, Michael S. Tsirkin wrote: On Thu, Dec 26, 2013 at 09:13:31PM +1100, Alexey Kardashevskiy wrote: On 12/25/2013 08:52 PM, Michael S. Tsirkin wrote: On Wed, Dec 25, 2013 at 12:36:12PM +1100, Alexey Kardashevskiy wrote: On 12/25/2013 02:43 AM, Michael S. Tsirkin wrote: On Wed, Dec 25, 2013 at 01:15:29AM +1100, Alexey Kardashevskiy wrote: On 12/24/2013 08:40 PM, Michael S. Tsirkin wrote: On Tue, Dec 24, 2013 at 02:09:07PM +1100, Alexey Kardashevskiy wrote: On 12/24/2013 03:24 AM, Michael S. Tsirkin wrote: On Mon, Dec 23, 2013 at 02:01:13AM +1100, Alexey Kardashevskiy wrote: On 12/23/2013 01:46 AM, Alexey Kardashevskiy wrote: On 12/22/2013 09:56 PM, Michael S. Tsirkin wrote: On Sun, Dec 22, 2013 at 02:01:23AM +1100, Alexey Kardashevskiy wrote: Hi! I am having a problem with virtio-net + vhost on POWER7 machine - it does not survive reboot of the guest. Steps to reproduce: 1. boot the guest 2. configure eth0 and do ping - everything works 3. reboot the guest (i.e. type reboot) 4. when it is booted, eth0 can be configured but will not work at all. The test is: ifconfig eth0 172.20.1.2 up ping 172.20.1.23 If to run tcpdump on the host's tap-id3 interface, it shows no trafic coming from the guest. If to compare how it works before and after reboot, I can see the guest doing an ARP request for 172.20.1.23 and receives the response and it does the same after reboot but the answer does not come. So you see the arp packet in guest but not in host? Yes. One thing to try is to boot debug kernel - where pr_debug is enabled - then you might see some errors in the kernel log. Tried and added lot more debug printk myself, not clear at all what is happening there. One more hint - if I boot the guest and the guest does not bring eth0 up AND wait more than 200 seconds (and less than 210 seconds), then eth0 will not work at all. I.e. this script produces not-working-eth0: ifconfig eth0 172.20.1.2 down sleep 210 ifconfig eth0 172.20.1.2 up ping 172.20.1.23 s/210/200/ - and it starts working. No reboot is required to reproduce. No vhost == always works. The only difference I can see here is vhost's thread which may get suspended if not used for a while after the start and does not wake up but this is almost a blind guess. Yet another clue - this host kernel patch seems to help with the guest reboot but does not help with the initial 210 seconds delay: diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 69068e0..5e67650 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -162,10 +162,10 @@ void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work) list_add_tail(work-node, dev-work_list); work-queue_seq++; spin_unlock_irqrestore(dev-work_lock, flags); - wake_up_process(dev-worker); } else { spin_unlock_irqrestore(dev-work_lock, flags); } + wake_up_process(dev-worker); } EXPORT_SYMBOL_GPL(vhost_work_queue); Interesting. Some kind of race? A missing memory barrier somewhere? I do not see how. I boot the guest and just wait 210 seconds, nothing happens to cause races. Since it's all around startup, you can try kicking the host eventfd in vhost_net_start. How exactly? This did not help. Thanks. diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 006576d..407ecf2 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -229,6 +229,17 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs, if (r 0) { goto err; } + +VHostNetState *vn = tap_get_vhost_net(ncs[i].peer); +struct vhost_vring_file file = { +.index = i +}; +file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(dev-vq)); +r = ioctl(vn-dev.control, VHOST_SET_VRING_KICK, file); No, this sets the notifier, it does not kick. To kick you write 1 there: uint6_t v = 1; write(fd, v, sizeof v); Please, be precise. How/where do I get that @fd? Is what I do correct? Yes. What is uint6_t - uint8_t or uint16_t (neither works)? Sorry, should have been uint64_t. Oh, that I missed :-) Anyway, this does not make any difference. Is there any cheapdirty way to make vhost-net kernel thread always awake? Sending it signals from the user space does not work... You can run a timer in qemu and signal the eventfd from there periodically. Just to restate, tcpdump in guest shows that guest sends arp packet, but tcpdump in host on tun device does not show any
Re: [Qemu-devel] [PATCHv3 3/6] ui/vnc: optimize dirty bitmap tracking
于 2014/1/6 2:02, Peter Lieven 写道: vnc_update_client currently scans the dirty bitmap of each client bitwise which is a very costly operation if only few bits are dirty. vnc_refresh_server_surface does almost the same. this patch optimizes both by utilizing the heavily optimized function find_next_bit to find the offset of the next dirty bit in the dirty bitmaps. The following artifical test (just the bitmap operation part) running vnc_update_client 65536 times on a 2560x2048 surface illustrates the performance difference: All bits clean - vnc_update_client_new: 0.07 secs vnc_update_client_old: 10.98 secs All bits dirty - vnc_update_client_new: 11.26 secs vnc_update_client_old: 20.19 secs Few bits dirty - vnc_update_client_new: 0.08 secs vnc_update_client_old: 10.98 secs The case for all bits dirty is still rather slow, this is due to the implementation of find_and_clear_dirty_height. This will be addresses in a separate patch. Signed-off-by: Peter Lieven p...@kamp.de --- ui/vnc.c | 154 +- ui/vnc.h |4 ++ 2 files changed, 87 insertions(+), 71 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 1d2aa1a..6a0c03e 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -572,6 +572,14 @@ void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y) ptr += x * VNC_SERVER_FB_BYTES; return ptr; } +/* this sets only the visible pixels of a dirty bitmap */ +#define VNC_SET_VISIBLE_PIXELS_DIRTY(bitmap, w, h) {\ +int y;\ +memset(bitmap, 0x00, sizeof(bitmap));\ +for (y = 0; y h; y++) {\ +bitmap_set(bitmap[y], 0, w / VNC_DIRTY_PIXELS_PER_BIT);\ Will it be a problem when vnc's width % VNC_DIRTY_PIXELS_PER_BIT != 0? Although it is a rare case, but I think it is better round it up, since v and VNC_DIRTY_PIXELS_PER_BIT are variables. A macro computing it would be nice: #define VNC_DIRTY_BITS_FROM_WIDTH(w) (w + VNC_DIRTY_PIXELS_PER_BIT - 1/ VNC_DIRTY_PIXELS_PER_BIT) #define VNC_DIRTY_BITS (VNC_DIRTY_BITS_FROM_WIDTH(VNC_MAX_WIDTH) then here: bitmap_set(bitmap[y], 0, VNC_DIRTY_BITS_FROM_WIDTH(w)); Or simply warn or coredump when v % VNC_DIRTY_PIXELS_PER_BIT != 0. Also, in vnc.h: /* VNC_MAX_WIDTH must be a multiple of 16. */ #define VNC_MAX_WIDTH 2560 #define VNC_MAX_HEIGHT 2048 Maybe it should be updated as: /* VNC_MAX_WIDTH must be a multiple of VNC_DIRTY_PIXELS_PER_BIT. */ +} \ +} static void vnc_dpy_switch(DisplayChangeListener *dcl, DisplaySurface *surface) @@ -597,7 +605,9 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl, qemu_pixman_image_unref(vd-guest.fb); vd-guest.fb = pixman_image_ref(surface-image); vd-guest.format = surface-format; -memset(vd-guest.dirty, 0xFF, sizeof(vd-guest.dirty)); +VNC_SET_VISIBLE_PIXELS_DIRTY(vd-guest.dirty, + surface_width(vd-ds), + surface_height(vd-ds)); QTAILQ_FOREACH(vs, vd-clients, next) { vnc_colordepth(vs); @@ -605,7 +615,9 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl, if (vs-vd-cursor) { vnc_cursor_define(vs); } -memset(vs-dirty, 0xFF, sizeof(vs-dirty)); +VNC_SET_VISIBLE_PIXELS_DIRTY(vs-dirty, + surface_width(vd-ds), + surface_height(vd-ds)); } } @@ -889,10 +901,9 @@ static int vnc_update_client(VncState *vs, int has_dirty) VncDisplay *vd = vs-vd; VncJob *job; int y; -int width, height; +int height; int n = 0; - if (vs-output.offset !vs-audio_cap !vs-force_update) /* kernel send buffers are full - drop frames to throttle */ return 0; @@ -908,39 +919,27 @@ static int vnc_update_client(VncState *vs, int has_dirty) */ job = vnc_job_new(vs); -width = MIN(pixman_image_get_width(vd-server), vs-client_width); height = MIN(pixman_image_get_height(vd-server), vs-client_height); -for (y = 0; y height; y++) { -int x; -int last_x = -1; -for (x = 0; x width / VNC_DIRTY_PIXELS_PER_BIT; x++) { -if (test_and_clear_bit(x, vs-dirty[y])) { -if (last_x == -1) { -last_x = x; -} -} else { -if (last_x != -1) { -int h = find_and_clear_dirty_height(vs, y, last_x, x, -height); - -n += vnc_job_add_rect(job, - last_x * VNC_DIRTY_PIXELS_PER_BIT, -
Re: [Qemu-devel] [PATCHv2 04/18] qemu-iotests: fix test 013 to work with any protocol
On 2014年01月06日 14:48, Peter Lieven wrote: On 06.01.2014 06:31, Fam Zheng wrote: On 2014年01月06日 01:21, Peter Lieven wrote: Signed-off-by: Peter Lieven p...@kamp.de --- tests/qemu-iotests/013 |9 - tests/qemu-iotests/013.out |2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/qemu-iotests/013 b/tests/qemu-iotests/013 index ea3cab9..0dbc934 100755 --- a/tests/qemu-iotests/013 +++ b/tests/qemu-iotests/013 @@ -41,14 +41,14 @@ trap _cleanup; exit \$status 0 1 2 3 15 # much of this could be generic for any format supporting compression. _supported_fmt qcow qcow2 -_supported_proto file +_supported_proto generic _supported_os Linux TEST_OFFSETS=0 4294967296 TEST_OPS=writev read write readv CLUSTER_SIZE=4096 I think dropping these three TEST_IMG overriding change... -_make_test_img 6G +TEST_IMG=$TEST_IMG.orig _make_test_img 6G #1 echo Testing empty image echo @@ -56,16 +56,15 @@ echo for offset in $TEST_OFFSETS; do echo At offset $offset: for op in $TEST_OPS; do -io_test $op $offset $CLUSTER_SIZE 8 +TEST_IMG=$TEST_IMG.orig io_test $op $offset $CLUSTER_SIZE 8 #2 done -_check_test_img +TEST_IMG=$TEST_IMG.orig _check_test_img #3 done echo Compressing image echo -mv $TEST_IMG $TEST_IMG.orig and changing this to TEST_IMG=$TEST_IMG.orig _make_test_img 6G Should work. Unfortunately it doesn't. All subsequent commands will then work on $TEST_IMG.orig altough they shouldn't. In case of 013 this is io_test, _check_test_img and the cleanup at the end. Why? The overriding is temporary and subsequent commands are not affected. My proposal above doesn't work, though, because an empty new image doesn't contain the right data, what is needed here is copy. So maybe change the mv line to: $QEMU_IMG convert -f $IMGFMT -O $IMGFMT $TEST_IMG $TEST_IMG.orig could do the work, but I'm not sure if this fits every case. There are 3 options: - override it in every line that should use an alternate $TEST_IMG - save the original $TEST_IMG and restore it. - rework all commands to take the file as parameter and not use a global variable for it. I choosed the first one because it makes clear which $TEST_IMG is acutally used. You see from the output and the code that you are dealing with the file that is later used as $TEST_IMG.orig. If you see $TEST_IMG there you can't distinguish if its the backing or original file or the actual image. But I thought that this would be controversal. This is I why I splitted the patch into individual ones. So its possible to drop all these patches and still be able to proceed with the integration of the NFS protocol driver. I'll leave maintainers to decide. Fam
Re: [Qemu-devel] Communication between Windows 7 host and Linux guest
This is the command line: qemu-system-armw -M versatilepb -kernel ..\BaseQemu\zImage -hda ..\BaseQemu\rootfs.squashfs -hdb ..\BaseQemu\flash.ext3 -append root=/dev/sda r -net tap,ifname=TAP,script=no -net nic I talked with the developer here and it seems that the bad speed is mainly due to latency. We are investigating also on our side because we use a special environment: in fact, we use VisualGDB to debug from Visual studio into qemu. It seems that VisualGDB's ssh client has poor performances but I don't know yet where the latency come from. Sebastien -Message d'origine- De : Stefan Hajnoczi [mailto:stefa...@gmail.com] Envoyé : lundi 6 janvier 2014 03:15 À : Gripon Sébastien Cc : qemu-devel@nongnu.org Objet : Re: [Qemu-devel] Communication between Windows 7 host and Linux guest On Sun, Dec 22, 2013 at 07:15:18PM +, Gripon Sébastien wrote: I have the need to communicate efficiently between Windows 7 host and linux guest. I tried first to use an IP socket communication using TAP driver on Windows. Unfortunately, we reach a maximum of 4 Mbits/s where I would need faster communication (more than 10 Mb/s). I don’t know yet if the TAP driver is slow. That seems very slow, 100 Mbit/s should definitely be achievable. But I have never tried TAP on Windows. Can you share the QEMU command-line and the benchmark used to measure this result? Stefan
Re: [Qemu-devel] [PATCH v3 2/3] qapi: change qapi to convert schema json
On 2014年01月05日 20:02, Amos Kong wrote: QMP schema is defined in a json file, it will be parsed by qapi scripts and generate C files. We want to return the schema information to management, this patch converts the json file to a string table in a C head file, then we can use the json content in QEMU code. eg: (qmp-schema.h) const char *const qmp_schema_table[] = { { 'type': 'NameInfo', 'data': {'*name': 'str'} }, { 'command': 'query-name', 'returns': 'NameInfo' }, ... } Signed-off-by: Amos Kong ak...@redhat.com --- Makefile | 5 - scripts/qapi-commands.py | 2 +- scripts/qapi-types.py| 48 +--- scripts/qapi-visit.py| 2 +- scripts/qapi.py | 20 +++- 5 files changed, 66 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index bdff4e4..2c29755 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ endif endif GENERATED_HEADERS = config-host.h qemu-options.def -GENERATED_HEADERS += qmp-commands.h qapi-types.h qapi-visit.h +GENERATED_HEADERS += qmp-commands.h qapi-types.h qapi-visit.h qmp-schema.h GENERATED_SOURCES += qmp-marshal.c qapi-types.c qapi-visit.c GENERATED_HEADERS += trace/generated-events.h @@ -229,6 +229,9 @@ $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py) qmp-commands.h qmp-marshal.c :\ $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py) $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -m -o . $, GEN $@) +qmp-schema.h:\ +$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py) + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o . -s $@ $, GEN $@) It would be nice to also add this file to .gitignore together with this patch. Fam
Re: [Qemu-devel] [PATCH target-arm v2 00/11] Cadence UART cleanups and Tx path fixes
On 2 January 2014 01:57, Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: When using QEMU in some terminal environments, char back-ends for serial devices can return EAGAIN for non trivial periods. This coupled with use of qemu_chr_fe_write_all() is a leading cause of: main-loop: WARNING: I/O thread spun for 1000 iterations This series fixes this for cadence_uart by replacing the open loop tx-write logic with a proper closed-loop that is responsive to the back-end short return. Thanks; applied all to target-arm.next. -- PMM
Re: [Qemu-devel] [PATCH resend] linux-user: Support the accept4 socketcall
Le 6 janvier 2014 à 10:14, Peter Maydell peter.mayd...@linaro.org a écrit : On 6 January 2014 08:45, Laurent Vivier laur...@vivier.eu wrote: Le 6 janvier 2014 à 02:57, André Hentschel n...@dawncrow.de a écrit : diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index cf08db5..b36f99c 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -27,6 +27,9 @@ #define SOCKOP_getsockopt 15 #define SOCKOP_sendmsg 16 #define SOCKOP_recvmsg 17 +#define SOCKOP_accept4 18 +#define SOCKOP_recvmmsg 19 +#define SOCKOP_sendmmsg 20 Don't add these both defines here as they are not used in this patch. It doesn't seem that unreasonable to add them. We add things to the main syscall number #define list even if we aren't actually implementing them, for example. IMHO, you should not : if you implement these syscalls and then revert this patch (because it is broken, for instance), you will break the build. The defines must come with the implementation. Regards, Laurent
Re: [Qemu-devel] [RFC PATCH v4 0/8] Support arm-gic-kvm save/restore
On 21 December 2013 06:09, Christoffer Dall christoffer.d...@linaro.org wrote: Implement support to save/restore the ARM KVM VGIC state from the kernel. The basic appraoch is to transfer state from the in-kernel VGIC to the emulated arm-gic state representation and let the standard QEMU vmstate save/restore handle saving the arm-gic state. Restore works by reversing the process. The first patches adds missing features and fixes issues with the arm-gic implementation in qemu in preparation for the actual save/restore logic. I still need to review this series, but I'm going to take the first two patches into target-arm.next now since they're already reviewed and they're straightforward cleanup. thanks -- PMM
Re: [Qemu-devel] [PATCH] spapr-pci: remove io ports workaround
On Fri, 03 Jan 2014 09:08:21 +1100 Alexey Kardashevskiy a...@ozlabs.ru wrote: Please read the rest of this thread. It does not visibly break things but with this patch QEMU starts calling unassigned_mem_accepts() (normally silent) which is not a good sign. Hmm... this is only because this patch moves the PHB io region from the system IO to the system memory space, but the bogus(?) write to unassigned memory already exists. I have tested against the current ppc-next (62d529a), with no additional patch: qemu-system-ppc64 \ -snapshot -S -monitor stdio -serial pty \ -nographic -nodefaults \ -machine type=pseries,accel=kvm -smp 1 -m 4G \ -device virtio-blk-pci,id=virtioiblk0,drive=drive0,bootindex=20,ioeventfd=on \ -drive file=/local/greg/qemu/fedora-be.qcow2,if=none,id=drive0,readonly=off,\ format=qcow2,media=disk,werror=stop,rerror=stop,discard=on where fedora-be.qcow2 contains a stock fedora 19 for ppc64. I have attached gdb to qemu and set a breakpoint in unassigned_io_write(), and here is what I get again: (gdb) b unassigned_io_write Breakpoint 1 at 0x1045d308: file /home/greg/Work/ibm/linux/qemu-agraf/ioport.c, line 54. (gdb) c Continuing. [Thread 0x1c5deef0 (LWP 11946) exited] [New Thread 0x1c5deef0 (LWP 11955)] [Switching to Thread 0x1bdaeef0 (LWP 11947)] Breakpoint 1, unassigned_io_write (opaque=0x0, addr=82, val=128, size=1) at /home/greg/Work/ibm/linux/qemu-agraf/ioport.c:54 54 { (gdb) where #0 unassigned_io_write (opaque=0x0, addr=82, val=128, size=1) at /home/greg/Work/ibm/linux/qemu-agraf/ioport.c:54 #1 0x10468f38 in memory_region_write_accessor (mr=0x10027615940, addr=82, value=0x1bdadd68, size=1, shift=0, mask=255) at /home/greg/Work/ibm/linux/qemu-agraf/memory.c:440 #2 0x104690c4 in access_with_adjusted_size (addr=82, value=0x1bdadd68, size=1, access_size_min=1, access_size_max=4, access=@0x107ca670: 0x10468e5c memory_region_write_accessor, mr=0x10027615940) at /home/greg/Work/ibm/linux/qemu-agraf/memory.c:472 #3 0x1046bc64 in memory_region_dispatch_write (mr=0x10027615940, addr=82, data=128, size=1) at /home/greg/Work/ibm/linux/qemu-agraf/memory.c:984 #4 0x1046fdc4 in io_mem_write (mr=0x10027615940, addr=82, val=128, size=1) at /home/greg/Work/ibm/linux/qemu-agraf/memory.c:1749 #5 0x103aca0c in address_space_rw (as=0x10c19638 address_space_memory, addr=1101659111506, buf=0x1bdae117 \200, len=1, is_write=true) at /home/greg/Work/ibm/linux/qemu-agraf/exec.c:2002 #6 0x103acf3c in cpu_physical_memory_rw (addr=1101659111506, buf=0x1bdae117 \200, len=1, is_write=1) at /home/greg/Work/ibm/linux/qemu-agraf/exec.c:2071 #7 0x103a44c4 in cpu_physical_memory_write (addr=1101659111506, buf=0x1bdae117, len=1) at /home/greg/Work/ibm/linux/qemu-agraf/include/exec/cpu-common.h:68 #8 0x103aeb2c in stb_phys (addr=1101659111506, val=128) at /home/greg/Work/ibm/linux/qemu-agraf/exec.c:2600 #9 0x10438550 in h_logical_store (cpu=0x10027d0f0d0, spapr=0x100276bb210, opcode=64, args=0x1ff80030) at /home/greg/Work/ibm/linux/qemu-agraf/hw/ppc/spapr_hcall.c:564 #10 0x10438e74 in spapr_hypercall (cpu=0x10027d0f0d0, opcode=64, args=0x1ff80030) at /home/greg/Work/ibm/linux/qemu-agraf/hw/ppc/spapr_hcall.c:737 #11 0x104cf424 in kvm_arch_handle_exit (cs=0x10027d0f0d0, run=0x1ff8) at /home/greg/Work/ibm/linux/qemu-agraf/target-ppc/kvm.c:1223 #12 0x104648a4 in kvm_cpu_exec (cpu=0x10027d0f0d0) at /home/greg/Work/ibm/linux/qemu-agraf/kvm-all.c:1736 #13 0x10397f00 in qemu_kvm_cpu_thread_fn (arg=0x10027d0f0d0) at /home/greg/Work/ibm/linux/qemu-agraf/cpus.c:874 #14 0x1f92c29c in start_thread (arg=0x1bdaeef0) at pthread_create.c:310 #15 0x1de5de10 in .__clone () at ../sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S:111 All I can say for the moment, is that I don't get that if I run qemu with -kernel/-append/-initrd instead of following the grub2 path. Any clue ? Thanks. -- Gregory Kurz kurzg...@fr.ibm.com gk...@linux.vnet.ibm.com Software Engineer @ IBM/Meiosys http://www.ibm.com Tel +33 (0)562 165 496 Anarchy is about taking complete responsibility for yourself. Alan Moore.
[Qemu-devel] [PULL 15/52] target-arm: A64: Implement minimal set of EL0-visible sysregs
Implement an initial minimal set of EL0-visible system registers: * NZCV * FPCR * FPSR * CTR_EL0 * DCZID_EL0 Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net Reviewed-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- target-arm/cpu.h | 3 ++- target-arm/helper.c| 61 ++ target-arm/translate-a64.c | 52 +++ 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index b091426..ab8ef17 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -660,7 +660,8 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid) #define ARM_CP_IO 64 #define ARM_CP_NOP (ARM_CP_SPECIAL | (1 8)) #define ARM_CP_WFI (ARM_CP_SPECIAL | (2 8)) -#define ARM_LAST_SPECIAL ARM_CP_WFI +#define ARM_CP_NZCV (ARM_CP_SPECIAL | (3 8)) +#define ARM_LAST_SPECIAL ARM_CP_NZCV /* Used only as a terminator for ARMCPRegInfo lists */ #define ARM_CP_SENTINEL 0x /* Mask of only the flag bits in a type field */ diff --git a/target-arm/helper.c b/target-arm/helper.c index 66214293..868493d 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1560,6 +1560,64 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = { REGINFO_SENTINEL }; +static int aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t *value) +{ +*value = vfp_get_fpcr(env); +return 0; +} + +static int aa64_fpcr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ +vfp_set_fpcr(env, value); +return 0; +} + +static int aa64_fpsr_read(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t *value) +{ +*value = vfp_get_fpsr(env); +return 0; +} + +static int aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ +vfp_set_fpsr(env, value); +return 0; +} + +static const ARMCPRegInfo v8_cp_reginfo[] = { +/* Minimal set of EL0-visible registers. This will need to be expanded + * significantly for system emulation of AArch64 CPUs. + */ +{ .name = NZCV, .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 2, + .access = PL0_RW, .type = ARM_CP_NZCV }, +{ .name = FPCR, .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 4, + .access = PL0_RW, .readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write }, +{ .name = FPSR, .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 4, + .access = PL0_RW, .readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write }, +/* This claims a 32 byte cacheline size for icache and dcache, VIPT icache. + * It will eventually need to have a CPU-specified reset value. + */ +{ .name = CTR_EL0, .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0, + .access = PL0_R, .type = ARM_CP_CONST, + .resetvalue = 0x80030003 }, +/* Prohibit use of DC ZVA. OPTME: implement DC ZVA and allow its use. + * For system mode the DZP bit here will need to be computed, not constant. + */ +{ .name = DCZID_EL0, .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0, + .access = PL0_R, .type = ARM_CP_CONST, + .resetvalue = 0x10 }, +REGINFO_SENTINEL +}; + static int sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { env-cp15.c1_sys = value; @@ -1662,6 +1720,9 @@ void register_cp_regs_for_features(ARMCPU *cpu) } else { define_arm_cp_regs(cpu, not_v7_cp_reginfo); } +if (arm_feature(env, ARM_FEATURE_V8)) { +define_arm_cp_regs(cpu, v8_cp_reginfo); +} if (arm_feature(env, ARM_FEATURE_MPU)) { /* These are the MPU registers prior to PMSAv6. Any new * PMSA core later than the ARM946 will require that we diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 7a9ee82..c8ed799 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -733,6 +733,50 @@ static void handle_msr_i(DisasContext *s, uint32_t insn, unsupported_encoding(s, insn); } +static void gen_get_nzcv(TCGv_i64 tcg_rt) +{ +TCGv_i32 tmp = tcg_temp_new_i32(); +TCGv_i32 nzcv = tcg_temp_new_i32(); + +/* build bit 31, N */ +tcg_gen_andi_i32(nzcv, cpu_NF, (1 31)); +/* build bit 30, Z */ +tcg_gen_setcondi_i32(TCG_COND_EQ, tmp, cpu_ZF, 0); +tcg_gen_deposit_i32(nzcv, nzcv, tmp, 30, 1); +/* build bit 29, C */ +tcg_gen_deposit_i32(nzcv, nzcv, cpu_CF, 29, 1); +/* build bit 28, V */ +tcg_gen_shri_i32(tmp, cpu_VF, 31); +tcg_gen_deposit_i32(nzcv, nzcv, tmp, 28, 1); +/* generate result */ +tcg_gen_extu_i32_i64(tcg_rt, nzcv); + +tcg_temp_free_i32(nzcv); +tcg_temp_free_i32(tmp); +} + +static void gen_set_nzcv(TCGv_i64
[Qemu-devel] [PULL 18/52] target-arm: A64: add support for conditional compare insns
From: Claudio Fontana claudio.font...@linaro.org this patch adds support for C3.5.4 - C3.5.5 Conditional compare (both immediate and register) Signed-off-by: Claudio Fontana claudio.font...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 73 +- 1 file changed, 60 insertions(+), 13 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 9f508b9..538d69e 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -2483,16 +2483,67 @@ static void disas_adc_sbc(DisasContext *s, uint32_t insn) } } -/* Conditional compare (immediate) */ -static void disas_cc_imm(DisasContext *s, uint32_t insn) +/* C3.5.4 - C3.5.5 Conditional compare (immediate / register) + * 31 30 29 28 27 26 25 24 23 22 21 2016 15 12 11 10 9 5 4 3 0 + * +--+--+--+++--++--+--+--+-+ + * |sf|op| S| 1 1 0 1 0 0 1 0 |imm5/rm | cond |i/r |o2| Rn |o3|nzcv | + * +--+--+--+++--++--+--+--+-+ + *[1] y[0] [0] + */ +static void disas_cc(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); -} +unsigned int sf, op, y, cond, rn, nzcv, is_imm; +int label_continue = -1; +TCGv_i64 tcg_tmp, tcg_y, tcg_rn; -/* Conditional compare (register) */ -static void disas_cc_reg(DisasContext *s, uint32_t insn) -{ -unsupported_encoding(s, insn); +if (!extract32(insn, 29, 1)) { +unallocated_encoding(s); +return; +} +if (insn (1 10 | 1 4)) { +unallocated_encoding(s); +return; +} +sf = extract32(insn, 31, 1); +op = extract32(insn, 30, 1); +is_imm = extract32(insn, 11, 1); +y = extract32(insn, 16, 5); /* y = rm (reg) or imm5 (imm) */ +cond = extract32(insn, 12, 4); +rn = extract32(insn, 5, 5); +nzcv = extract32(insn, 0, 4); + +if (cond 0x0e) { /* not always */ +int label_match = gen_new_label(); +label_continue = gen_new_label(); +arm_gen_test_cc(cond, label_match); +/* nomatch: */ +tcg_tmp = tcg_temp_new_i64(); +tcg_gen_movi_i64(tcg_tmp, nzcv 28); +gen_set_nzcv(tcg_tmp); +tcg_temp_free_i64(tcg_tmp); +tcg_gen_br(label_continue); +gen_set_label(label_match); +} +/* match, or condition is always */ +if (is_imm) { +tcg_y = new_tmp_a64(s); +tcg_gen_movi_i64(tcg_y, y); +} else { +tcg_y = cpu_reg(s, y); +} +tcg_rn = cpu_reg(s, rn); + +tcg_tmp = tcg_temp_new_i64(); +if (op) { +gen_sub_CC(sf, tcg_tmp, tcg_rn, tcg_y); +} else { +gen_add_CC(sf, tcg_tmp, tcg_rn, tcg_y); +} +tcg_temp_free_i64(tcg_tmp); + +if (cond 0x0e) { /* continue */ +gen_set_label(label_continue); +} } /* C3.5.6 Conditional select @@ -2846,11 +2897,7 @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) disas_adc_sbc(s, insn); break; case 0x2: /* Conditional compare */ -if (insn (1 11)) { /* (immediate) */ -disas_cc_imm(s, insn); -} else {/* (register) */ -disas_cc_reg(s, insn); -} +disas_cc(s, insn); /* both imm and reg forms */ break; case 0x4: /* Conditional select */ disas_cond_select(s, insn); -- 1.8.5
[Qemu-devel] [PULL 49/52] arm/xilinx_zynq: Always instantiate the GEMs
From: Peter Crosthwaite peter.crosthwa...@xilinx.com Don't conditionalise GEM instantiation on networking attachments. The device should always be present even if not attached to a network. This allows for probing of the device by expectant guests (such as OS's). This is needed because sysbus (or AXI in Xilinx's real hw case) is not self identifying so the guest has no dynamic way of detecting device absence. Also allows for testing of the GEM in loopback mode with -net none. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Reviewed-by: Peter Maydell peter.mayd...@linaro.org Message-id: 55649779a68ee3ff54b24c339b6fdbdccd1f0ed7.1388800598.git.peter.crosthwa...@xilinx.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/arm/xilinx_zynq.c | 17 ++--- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c index 17251c7..98e0958 100644 --- a/hw/arm/xilinx_zynq.c +++ b/hw/arm/xilinx_zynq.c @@ -49,9 +49,11 @@ static void gem_init(NICInfo *nd, uint32_t base, qemu_irq irq) DeviceState *dev; SysBusDevice *s; -qemu_check_nic_model(nd, cadence_gem); dev = qdev_create(NULL, cadence_gem); -qdev_set_nic_properties(dev, nd); +if (nd-used) { +qemu_check_nic_model(nd, cadence_gem); +qdev_set_nic_properties(dev, nd); +} qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); sysbus_mmio_map(s, 0, base); @@ -113,7 +115,6 @@ static void zynq_init(QEMUMachineInitArgs *args) DeviceState *dev; SysBusDevice *busdev; qemu_irq pic[64]; -NICInfo *nd; Error *err = NULL; int n; @@ -190,14 +191,8 @@ static void zynq_init(QEMUMachineInitArgs *args) sysbus_create_varargs(cadence_ttc, 0xF8002000, pic[69-IRQ_OFFSET], pic[70-IRQ_OFFSET], pic[71-IRQ_OFFSET], NULL); -for (n = 0; n nb_nics; n++) { -nd = nd_table[n]; -if (n == 0) { -gem_init(nd, 0xE000B000, pic[54-IRQ_OFFSET]); -} else if (n == 1) { -gem_init(nd, 0xE000C000, pic[77-IRQ_OFFSET]); -} -} +gem_init(nd_table[0], 0xE000B000, pic[54-IRQ_OFFSET]); +gem_init(nd_table[1], 0xE000C000, pic[77-IRQ_OFFSET]); dev = qdev_create(NULL, generic-sdhci); qdev_init_nofail(dev); -- 1.8.5
[Qemu-devel] [PULL 51/52] arm_gic: Rename GIC_X_TRIGGER to GIC_X_EDGE_TRIGGER
From: Christoffer Dall christoffer.d...@linaro.org TRIGGER can really mean mean anything (e.g. was it triggered, is it level-triggered, is it edge-triggered, etc.). Rename to EDGE_TRIGGER to make the code comprehensible without looking up the data structure. Reviewed-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Christoffer Dall christoffer.d...@linaro.org Message-id: 1387606179-22709-2-git-send-email-christoffer.d...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/intc/arm_gic.c| 12 ++-- hw/intc/arm_gic_common.c | 4 ++-- hw/intc/gic_internal.h | 6 +++--- include/hw/intc/arm_gic_common.h | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index d431b7a..27c258a 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -128,7 +128,7 @@ static void gic_set_irq(void *opaque, int irq, int level) if (level) { GIC_SET_LEVEL(irq, cm); -if (GIC_TEST_TRIGGER(irq) || GIC_TEST_ENABLED(irq, cm)) { +if (GIC_TEST_EDGE_TRIGGER(irq) || GIC_TEST_ENABLED(irq, cm)) { DPRINTF(Set %d pending mask %x\n, irq, target); GIC_SET_PENDING(irq, target); } @@ -188,7 +188,7 @@ void gic_complete_irq(GICState *s, int cpu, int irq) return; /* No active IRQ. */ /* Mark level triggered interrupts as pending if they are still raised. */ -if (!GIC_TEST_TRIGGER(irq) GIC_TEST_ENABLED(irq, cm) +if (!GIC_TEST_EDGE_TRIGGER(irq) GIC_TEST_ENABLED(irq, cm) GIC_TEST_LEVEL(irq, cm) (GIC_TARGET(irq) cm) != 0) { DPRINTF(Set %d pending mask %x\n, irq, cm); GIC_SET_PENDING(irq, cm); @@ -311,7 +311,7 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset) for (i = 0; i 4; i++) { if (GIC_TEST_MODEL(irq + i)) res |= (1 (i * 2)); -if (GIC_TEST_TRIGGER(irq + i)) +if (GIC_TEST_EDGE_TRIGGER(irq + i)) res |= (2 (i * 2)); } } else if (offset 0xfe0) { @@ -386,7 +386,7 @@ static void gic_dist_writeb(void *opaque, hwaddr offset, /* If a raised level triggered IRQ enabled then mark is as pending. */ if (GIC_TEST_LEVEL(irq + i, mask) - !GIC_TEST_TRIGGER(irq + i)) { + !GIC_TEST_EDGE_TRIGGER(irq + i)) { DPRINTF(Set %d pending mask %x\n, irq + i, mask); GIC_SET_PENDING(irq + i, mask); } @@ -478,9 +478,9 @@ static void gic_dist_writeb(void *opaque, hwaddr offset, GIC_CLEAR_MODEL(irq + i); } if (value (2 (i * 2))) { -GIC_SET_TRIGGER(irq + i); +GIC_SET_EDGE_TRIGGER(irq + i); } else { -GIC_CLEAR_TRIGGER(irq + i); +GIC_CLEAR_EDGE_TRIGGER(irq + i); } } } else { diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c index c765850..710607b 100644 --- a/hw/intc/arm_gic_common.c +++ b/hw/intc/arm_gic_common.c @@ -51,7 +51,7 @@ static const VMStateDescription vmstate_gic_irq_state = { VMSTATE_UINT8(active, gic_irq_state), VMSTATE_UINT8(level, gic_irq_state), VMSTATE_BOOL(model, gic_irq_state), -VMSTATE_BOOL(trigger, gic_irq_state), +VMSTATE_BOOL(edge_trigger, gic_irq_state), VMSTATE_END_OF_LIST() } }; @@ -126,7 +126,7 @@ static void arm_gic_common_reset(DeviceState *dev) } for (i = 0; i 16; i++) { GIC_SET_ENABLED(i, ALL_CPU_MASK); -GIC_SET_TRIGGER(i); +GIC_SET_EDGE_TRIGGER(i); } if (s-num_cpu == 1) { /* For uniprocessor GICs all interrupts always target the sole CPU */ diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h index 3989fd1..efac78d 100644 --- a/hw/intc/gic_internal.h +++ b/hw/intc/gic_internal.h @@ -44,9 +44,9 @@ #define GIC_SET_LEVEL(irq, cm) s-irq_state[irq].level = (cm) #define GIC_CLEAR_LEVEL(irq, cm) s-irq_state[irq].level = ~(cm) #define GIC_TEST_LEVEL(irq, cm) ((s-irq_state[irq].level (cm)) != 0) -#define GIC_SET_TRIGGER(irq) s-irq_state[irq].trigger = true -#define GIC_CLEAR_TRIGGER(irq) s-irq_state[irq].trigger = false -#define GIC_TEST_TRIGGER(irq) s-irq_state[irq].trigger +#define GIC_SET_EDGE_TRIGGER(irq) s-irq_state[irq].edge_trigger = true +#define GIC_CLEAR_EDGE_TRIGGER(irq) s-irq_state[irq].edge_trigger = false +#define GIC_TEST_EDGE_TRIGGER(irq) (s-irq_state[irq].edge_trigger) #define GIC_GET_PRIORITY(irq, cpu) (((irq) GIC_INTERNAL) ?\ s-priority1[irq][cpu] :\ s-priority2[(irq) - GIC_INTERNAL]) diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h index 4f381bd..0d232df 100644 --- a/include/hw/intc/arm_gic_common.h
[Qemu-devel] [PULL 46/52] char/cadence_uart: Implement Tx flow control
From: Peter Crosthwaite peter.crosthwa...@xilinx.com If the UART back-end blocks, buffer in the Tx FIFO to try again later. This stops the IO-thread busy waiting on char back-ends (which causes all sorts of performance problems). Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Message-id: 4bea048b3ab38425701d82ccc1ab92545c26b79c.1388626249.git.peter.crosthwa...@xilinx.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/char/cadence_uart.c | 31 +-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index 8a9ef81..1012f1a 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -286,6 +286,34 @@ static void uart_write_rx_fifo(void *opaque, const uint8_t *buf, int size) uart_update_status(s); } +static gboolean cadence_uart_xmit(GIOChannel *chan, GIOCondition cond, + void *opaque) +{ +UartState *s = opaque; +int ret; + +/* instant drain the fifo when there's no back-end */ +if (!s-chr) { +s-tx_count = 0; +} + +if (!s-tx_count) { +return FALSE; +} + +ret = qemu_chr_fe_write(s-chr, s-tx_fifo, s-tx_count); +s-tx_count -= ret; +memmove(s-tx_fifo, s-tx_fifo + ret, s-tx_count); + +if (s-tx_count) { +int r = qemu_chr_fe_add_watch(s-chr, G_IO_OUT, cadence_uart_xmit, s); +assert(r); +} + +uart_update_status(s); +return FALSE; +} + static void uart_write_tx_fifo(UartState *s, const uint8_t *buf, int size) { if ((s-r[R_CR] UART_CR_TX_DIS) || !(s-r[R_CR] UART_CR_TX_EN)) { @@ -306,8 +334,7 @@ static void uart_write_tx_fifo(UartState *s, const uint8_t *buf, int size) memcpy(s-tx_fifo + s-tx_count, buf, size); s-tx_count += size; -qemu_chr_fe_write_all(s-chr, s-tx_fifo, s-tx_count); -s-tx_count = 0; +cadence_uart_xmit(NULL, G_IO_OUT, s); } static void uart_receive(void *opaque, const uint8_t *buf, int size) -- 1.8.5
[Qemu-devel] [PULL 52/52] hw: arm_gic: Introduce gic_set_priority function
From: Christoffer Dall christoffer.d...@linaro.org To make the code slightly cleaner to look at and make the save/restore code easier to understand, introduce this function to set the priority of interrupts. Reviewed-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Christoffer Dall christoffer.d...@linaro.org Message-id: 1387606179-22709-3-git-send-email-christoffer.d...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/intc/arm_gic.c | 15 ++- hw/intc/gic_internal.h | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 27c258a..6c59650 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -168,6 +168,15 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu) return new_irq; } +void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val) +{ +if (irq GIC_INTERNAL) { +s-priority1[irq][cpu] = val; +} else { +s-priority2[(irq) - GIC_INTERNAL] = val; +} +} + void gic_complete_irq(GICState *s, int cpu, int irq) { int update = 0; @@ -443,11 +452,7 @@ static void gic_dist_writeb(void *opaque, hwaddr offset, irq = (offset - 0x400) + GIC_BASE_IRQ; if (irq = s-num_irq) goto bad_reg; -if (irq GIC_INTERNAL) { -s-priority1[irq][cpu] = value; -} else { -s-priority2[irq - GIC_INTERNAL] = value; -} +gic_set_priority(s, cpu, irq, value); } else if (offset 0xc00) { /* Interrupt CPU Target. RAZ/WI on uniprocessor GICs, with the * annoying exception of the 11MPCore's GIC. diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h index efac78d..8c02d58 100644 --- a/hw/intc/gic_internal.h +++ b/hw/intc/gic_internal.h @@ -61,5 +61,6 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu); void gic_complete_irq(GICState *s, int cpu, int irq); void gic_update(GICState *s); void gic_init_irqs_and_distributor(GICState *s, int num_irq); +void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val); #endif /* !QEMU_ARM_GIC_INTERNAL_H */ -- 1.8.5
[Qemu-devel] [PULL 48/52] target-arm: remove raw_read|write duplication
From: Peter Crosthwaite peter.crosthwa...@xilinx.com There is an inline duplication of the raw_read and raw_write function bodies. Fix by just calling raw_read/raw_write instead. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Reviewed-by: Peter Maydell peter.mayd...@linaro.org Message-id: e69281b7e1462b346cb313cf0b89eedc0568125f.1388649290.git.peter.crosthwa...@xilinx.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/helper.c | 12 ++-- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index 4af2f9c..d27e528 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -142,11 +142,7 @@ static bool read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri, } else if (ri-readfn) { return (ri-readfn(env, ri, v) == 0); } else { -if (ri-type ARM_CP_64BIT) { -*v = CPREG_FIELD64(env, ri); -} else { -*v = CPREG_FIELD32(env, ri); -} +raw_read(env, ri, v); } return true; } @@ -167,11 +163,7 @@ static bool write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri, } else if (ri-writefn) { return (ri-writefn(env, ri, v) == 0); } else { -if (ri-type ARM_CP_64BIT) { -CPREG_FIELD64(env, ri) = v; -} else { -CPREG_FIELD32(env, ri) = v; -} +raw_write(env, ri, v); } return true; } -- 1.8.5
[Qemu-devel] [PULL 50/52] target-arm: fix build with gcc 4.8.2
From: Michael S. Tsirkin m...@redhat.com commit 5ce4f35781028ce1aee3341e6002f925fdc7aaf3 target-arm: A64: add set_pc cpu method introduces an array aarch64_cpus which is zero size if this code is built without CONFIG_USER_ONLY. In particular an attempt to iterate over this array produces a warning under gcc 4.8.2: CCaarch64-softmmu/target-arm/cpu64.o /scm/qemu/target-arm/cpu64.c: In function ‘aarch64_cpu_register_types’: /scm/qemu/target-arm/cpu64.c:124:5: error: comparison of unsigned expression 0 is always false [-Werror=type-limits] for (i = 0; i ARRAY_SIZE(aarch64_cpus); i++) { ^ cc1: all warnings being treated as errors This is the result of ARRAY_SIZE being an unsigned type, causing i to be promoted to unsigned int as well. As zero size arrays are a gcc extension, it seems cleanest to add a dummy element with NULL name, and test for it during registration. We'll be able to drop this when we add more CPUs. Cc: Alexander Graf ag...@suse.de Cc: Peter Maydell peter.mayd...@linaro.org Cc: Richard Henderson r...@twiddle.net Signed-off-by: Michael S. Tsirkin m...@redhat.com Reviewed-by: Stefan Weil s...@weilnetz.de Reviewed-by: Peter Maydell peter.mayd...@linaro.org Message-id: 20131223145216.ga22...@redhat.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/cpu64.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/target-arm/cpu64.c b/target-arm/cpu64.c index 04ce879..60acd24 100644 --- a/target-arm/cpu64.c +++ b/target-arm/cpu64.c @@ -58,6 +58,7 @@ static const ARMCPUInfo aarch64_cpus[] = { #ifdef CONFIG_USER_ONLY { .name = any, .initfn = aarch64_any_initfn }, #endif +{ .name = NULL } /* TODO: drop when we support more CPUs */ }; static void aarch64_cpu_initfn(Object *obj) @@ -100,6 +101,11 @@ static void aarch64_cpu_register(const ARMCPUInfo *info) .class_init = info-class_init, }; +/* TODO: drop when we support more CPUs - all entries will have name set */ +if (!info-name) { +return; +} + type_info.name = g_strdup_printf(%s- TYPE_ARM_CPU, info-name); type_register(type_info); g_free((void *)type_info.name); -- 1.8.5
[Qemu-devel] [PULL 45/52] char/cadence_uart: Delete redundant rx rst logic
From: Peter Crosthwaite peter.crosthwa...@xilinx.com uart_rx_reset() called immediately above already does this. Remove. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Message-id: 05e30826496cf2579084ed801ac0b2c0d0a3071f.1388626249.git.peter.crosthwa...@xilinx.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/char/cadence_uart.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index be32126..8a9ef81 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -438,8 +438,6 @@ static void cadence_uart_reset(DeviceState *dev) uart_rx_reset(s); uart_tx_reset(s); -s-rx_count = 0; -s-rx_wpos = 0; uart_update_status(s); } -- 1.8.5
[Qemu-devel] [PULL 31/52] target-arm: A64: Add fmov (scalar, immediate) instruction
From: Alexander Graf ag...@suse.de This patch adds emulation for the fmov instruction working on scalars with an immediate payload. Signed-off-by: Alexander Graf ag...@suse.de [WN: Commit message tweak, rebase and use new infrastructure.] Signed-off-by: Will Newton will.new...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 32 +++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 84497dc..bb36a66 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -3479,7 +3479,37 @@ static void disas_fp_3src(DisasContext *s, uint32_t insn) */ static void disas_fp_imm(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int rd = extract32(insn, 0, 5); +int imm8 = extract32(insn, 13, 8); +int is_double = extract32(insn, 22, 2); +uint64_t imm; +TCGv_i64 tcg_res; + +if (is_double 1) { +unallocated_encoding(s); +return; +} + +/* The imm8 encodes the sign bit, enough bits to represent + * an exponent in the range 011xx to 100xx, + * and the most significant 4 bits of the mantissa; see + * VFPExpandImm() in the v8 ARM ARM. + */ +if (is_double) { +imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) | +(extract32(imm8, 6, 1) ? 0x3fc0 : 0x4000) | +extract32(imm8, 0, 6); +imm = 48; +} else { +imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) | +(extract32(imm8, 6, 1) ? 0x3e00 : 0x4000) | +(extract32(imm8, 0, 6) 3); +imm = 16; +} + +tcg_res = tcg_const_i64(imm); +write_fp_dreg(s, rd, tcg_res); +tcg_temp_free_i64(tcg_res); } /* C3.6.29 Floating point - fixed point conversions -- 1.8.5
[Qemu-devel] [PULL 44/52] char/cadence_uart: Use the TX fifo for transmission
From: Peter Crosthwaite peter.crosthwa...@xilinx.com Populate the TxFIFO with the Tx data before sending. Prepares support for proper Tx flow control implementation. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Message-id: bdf7f8af2ef02839bea18665701bc2612f7baa6f.1388626249.git.peter.crosthwa...@xilinx.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/char/cadence_uart.c | 17 - 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index 3bcaf29..be32126 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -292,7 +292,22 @@ static void uart_write_tx_fifo(UartState *s, const uint8_t *buf, int size) return; } -qemu_chr_fe_write_all(s-chr, buf, size); +if (size TX_FIFO_SIZE - s-tx_count) { +size = TX_FIFO_SIZE - s-tx_count; +/* + * This can only be a guest error via a bad tx fifo register push, + * as can_receive() should stop remote loop and echo modes ever getting + * us to here. + */ +qemu_log_mask(LOG_GUEST_ERROR, cadence_uart: TxFIFO overflow); +s-r[R_CISR] |= UART_INTR_ROVR; +} + +memcpy(s-tx_fifo + s-tx_count, buf, size); +s-tx_count += size; + +qemu_chr_fe_write_all(s-chr, s-tx_fifo, s-tx_count); +s-tx_count = 0; } static void uart_receive(void *opaque, const uint8_t *buf, int size) -- 1.8.5
[Qemu-devel] [PULL 30/52] target-arm: A64: Add Floating-point data-processing (3 source) insns
From: Alexander Graf ag...@suse.de This patch adds emulation for the Floating-point data-processing (3 source) group of instructions. Signed-off-by: Alexander Graf ag...@suse.de [WN: Commit message tweak, merged single and double precision patches. Implement using muladd as suggested by Richard Henderson.] Signed-off-by: Will Newton will.new...@linaro.org [PMM: pull field decode up a level, use register accessors] Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 95 +- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index c406e2a..84497dc 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -3367,6 +3367,82 @@ static void disas_fp_2src(DisasContext *s, uint32_t insn) } } +/* C3.6.27 Floating-point data-processing (3 source) - single precision */ +static void handle_fp_3src_single(DisasContext *s, bool o0, bool o1, + int rd, int rn, int rm, int ra) +{ +TCGv_i32 tcg_op1, tcg_op2, tcg_op3; +TCGv_i32 tcg_res = tcg_temp_new_i32(); +TCGv_ptr fpst = get_fpstatus_ptr(); + +tcg_op1 = read_fp_sreg(s, rn); +tcg_op2 = read_fp_sreg(s, rm); +tcg_op3 = read_fp_sreg(s, ra); + +/* These are fused multiply-add, and must be done as one + * floating point operation with no rounding between the + * multiplication and addition steps. + * NB that doing the negations here as separate steps is + * correct : an input NaN should come out with its sign bit + * flipped if it is a negated-input. + */ +if (o1 == true) { +gen_helper_vfp_negs(tcg_op3, tcg_op3); +} + +if (o0 != o1) { +gen_helper_vfp_negs(tcg_op1, tcg_op1); +} + +gen_helper_vfp_muladds(tcg_res, tcg_op1, tcg_op2, tcg_op3, fpst); + +write_fp_sreg(s, rd, tcg_res); + +tcg_temp_free_ptr(fpst); +tcg_temp_free_i32(tcg_op1); +tcg_temp_free_i32(tcg_op2); +tcg_temp_free_i32(tcg_op3); +tcg_temp_free_i32(tcg_res); +} + +/* C3.6.27 Floating-point data-processing (3 source) - double precision */ +static void handle_fp_3src_double(DisasContext *s, bool o0, bool o1, + int rd, int rn, int rm, int ra) +{ +TCGv_i64 tcg_op1, tcg_op2, tcg_op3; +TCGv_i64 tcg_res = tcg_temp_new_i64(); +TCGv_ptr fpst = get_fpstatus_ptr(); + +tcg_op1 = read_fp_dreg(s, rn); +tcg_op2 = read_fp_dreg(s, rm); +tcg_op3 = read_fp_dreg(s, ra); + +/* These are fused multiply-add, and must be done as one + * floating point operation with no rounding between the + * multiplication and addition steps. + * NB that doing the negations here as separate steps is + * correct : an input NaN should come out with its sign bit + * flipped if it is a negated-input. + */ +if (o1 == true) { +gen_helper_vfp_negd(tcg_op3, tcg_op3); +} + +if (o0 != o1) { +gen_helper_vfp_negd(tcg_op1, tcg_op1); +} + +gen_helper_vfp_muladdd(tcg_res, tcg_op1, tcg_op2, tcg_op3, fpst); + +write_fp_dreg(s, rd, tcg_res); + +tcg_temp_free_ptr(fpst); +tcg_temp_free_i64(tcg_op1); +tcg_temp_free_i64(tcg_op2); +tcg_temp_free_i64(tcg_op3); +tcg_temp_free_i64(tcg_res); +} + /* C3.6.27 Floating point data-processing (3 source) * 31 30 29 28 24 23 22 21 20 16 15 14 10 95 40 * +---+---+---+---+--++--++--+--+--+ @@ -3375,7 +3451,24 @@ static void disas_fp_2src(DisasContext *s, uint32_t insn) */ static void disas_fp_3src(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int type = extract32(insn, 22, 2); +int rd = extract32(insn, 0, 5); +int rn = extract32(insn, 5, 5); +int ra = extract32(insn, 10, 5); +int rm = extract32(insn, 16, 5); +bool o0 = extract32(insn, 15, 1); +bool o1 = extract32(insn, 21, 1); + +switch (type) { +case 0: +handle_fp_3src_single(s, o0, o1, rd, rn, rm, ra); +break; +case 1: +handle_fp_3src_double(s, o0, o1, rd, rn, rm, ra); +break; +default: +unallocated_encoding(s); +} } /* C3.6.28 Floating point immediate -- 1.8.5
[Qemu-devel] [PULL 39/52] char/cadence_uart: s/r_fifo/rx_fifo
From: Peter Crosthwaite peter.crosthwa...@xilinx.com Rename this field to match the many other uses of rx. Xilinx docmentation (UG585) also refers to this as RxFIFO. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Message-id: 7386d7cee0ea175f7e53ed5ff045265528d34e32.1388626249.git.peter.crosthwa...@xilinx.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/char/cadence_uart.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index 7edc119..d6abc5b 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -116,7 +116,7 @@ typedef struct { MemoryRegion iomem; uint32_t r[R_MAX]; -uint8_t r_fifo[RX_FIFO_SIZE]; +uint8_t rx_fifo[RX_FIFO_SIZE]; uint32_t rx_wpos; uint32_t rx_count; uint64_t char_tx_time; @@ -280,7 +280,7 @@ static void uart_write_rx_fifo(void *opaque, const uint8_t *buf, int size) s-r[R_CISR] |= UART_INTR_ROVR; } else { for (i = 0; i size; i++) { -s-r_fifo[s-rx_wpos] = buf[i]; +s-rx_fifo[s-rx_wpos] = buf[i]; s-rx_wpos = (s-rx_wpos + 1) % RX_FIFO_SIZE; s-rx_count++; @@ -344,7 +344,7 @@ static void uart_read_rx_fifo(UartState *s, uint32_t *c) if (s-rx_count) { uint32_t rx_rpos = (RX_FIFO_SIZE + s-rx_wpos - s-rx_count) % RX_FIFO_SIZE; -*c = s-r_fifo[rx_rpos]; +*c = s-rx_fifo[rx_rpos]; s-rx_count--; if (!s-rx_count) { @@ -492,7 +492,7 @@ static const VMStateDescription vmstate_cadence_uart = { .post_load = cadence_uart_post_load, .fields = (VMStateField[]) { VMSTATE_UINT32_ARRAY(r, UartState, R_MAX), -VMSTATE_UINT8_ARRAY(r_fifo, UartState, RX_FIFO_SIZE), +VMSTATE_UINT8_ARRAY(rx_fifo, UartState, RX_FIFO_SIZE), VMSTATE_UINT32(rx_count, UartState), VMSTATE_UINT32(rx_wpos, UartState), VMSTATE_TIMER(fifo_trigger_handle, UartState), -- 1.8.5
[Qemu-devel] [PULL 04/52] target-arm: A64: add support for ld/st with index
From: Alex Bennée alex.ben...@linaro.org This adds support for the pre/post-index ld/st forms with immediate offsets as well as the un-scaled immediate form (which are all variations on the same 9-bit immediate instruction form). Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 125 - 1 file changed, 124 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 67efcf9..a2cc9f0 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -950,6 +950,110 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn) } /* + * C3.3.8 Load/store (immediate post-indexed) + * C3.3.9 Load/store (immediate pre-indexed) + * C3.3.12 Load/store (unscaled immediate) + * + * 31 30 29 27 26 25 24 23 22 21 2012 11 10 95 40 + * ++---+---+-+-+---++-+--+--+ + * |size| 1 1 1 | V | 0 0 | opc | 0 | imm9 | idx | Rn | Rt | + * ++---+---+-+-+---++-+--+--+ + * + * idx = 01 - post-indexed, 11 pre-indexed, 00 unscaled imm. (no writeback) + * V = 0 - non-vector + * size: 00 - 8 bit, 01 - 16 bit, 10 - 32 bit, 11 - 64bit + * opc: 00 - store, 01 - loadu, 10 - loads 64, 11 - loads 32 + */ +static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn) +{ +int rt = extract32(insn, 0, 5); +int rn = extract32(insn, 5, 5); +int imm9 = sextract32(insn, 12, 9); +int opc = extract32(insn, 22, 2); +int size = extract32(insn, 30, 2); +int idx = extract32(insn, 10, 2); +bool is_signed = false; +bool is_store = false; +bool is_extended = false; +bool is_vector = extract32(insn, 26, 1); +bool post_index; +bool writeback; + +TCGv_i64 tcg_addr; + +if (is_vector) { +size |= (opc 2) 1; +if (size 4) { +unallocated_encoding(s); +return; +} +is_store = ((opc 1) == 0); +} else { +if (size == 3 opc == 2) { +/* PRFM - prefetch */ +return; +} +if (opc == 3 size 1) { +unallocated_encoding(s); +return; +} +is_store = (opc == 0); +is_signed = opc (11); +is_extended = (size 3) (opc 1); +} + +switch (idx) { +case 0: +post_index = false; +writeback = false; +break; +case 1: +post_index = true; +writeback = true; +break; +case 3: +post_index = false; +writeback = true; +break; +case 2: +g_assert(false); +break; +} + +if (rn == 31) { +gen_check_sp_alignment(s); +} +tcg_addr = read_cpu_reg_sp(s, rn, 1); + +if (!post_index) { +tcg_gen_addi_i64(tcg_addr, tcg_addr, imm9); +} + +if (is_vector) { +if (is_store) { +do_fp_st(s, rt, tcg_addr, size); +} else { +do_fp_ld(s, rt, tcg_addr, size); +} +} else { +TCGv_i64 tcg_rt = cpu_reg(s, rt); +if (is_store) { +do_gpr_st(s, tcg_rt, tcg_addr, size); +} else { +do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended); +} +} + +if (writeback) { +TCGv_i64 tcg_rn = cpu_reg_sp(s, rn); +if (post_index) { +tcg_gen_addi_i64(tcg_addr, tcg_addr, imm9); +} +tcg_gen_mov_i64(tcg_rn, tcg_addr); +} +} + +/* * C3.3.10 Load/store (register offset) * * 31 30 29 27 26 25 24 23 22 21 20 16 15 13 12 11 10 9 5 4 0 @@ -1116,6 +1220,25 @@ static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn) } } +/* Load/store register (immediate forms) */ +static void disas_ldst_reg_imm(DisasContext *s, uint32_t insn) +{ +switch (extract32(insn, 10, 2)) { +case 0: case 1: case 3: +/* Load/store register (unscaled immediate) */ +/* Load/store immediate pre/post-indexed */ +disas_ldst_reg_imm9(s, insn); +break; +case 2: +/* Load/store register unprivileged */ +unsupported_encoding(s, insn); +break; +default: +unallocated_encoding(s); +break; +} +} + /* Load/store register (all forms) */ static void disas_ldst_reg(DisasContext *s, uint32_t insn) { @@ -1124,7 +1247,7 @@ static void disas_ldst_reg(DisasContext *s, uint32_t insn) if (extract32(insn, 21, 1) == 1 extract32(insn, 10, 2) == 2) { disas_ldst_reg_roffset(s, insn); } else { -unsupported_encoding(s, insn); +disas_ldst_reg_imm(s, insn); } break; case 1: -- 1.8.5
[Qemu-devel] [PULL 26/52] target-arm: A64: Add support for dumping AArch64 VFP register state
From: Alexander Graf ag...@suse.de When dumping the current CPU state, we can also get a request to dump the FPU state along with the CPU's integer state. Add support to dump the VFP state when that flag is set, so that we can properly debug code that modifies floating point registers. Signed-off-by: Alexander Graf ag...@suse.de [WN: Commit message tweak, rebased. Output all registers, two per-line.] Signed-off-by: Will Newton will.new...@linaro.org Reviewed-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 16 1 file changed, 16 insertions(+) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 40c6fc4..326f36d 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -119,6 +119,22 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f, psr PSTATE_C ? 'C' : '-', psr PSTATE_V ? 'V' : '-'); cpu_fprintf(f, \n); + +if (flags CPU_DUMP_FPU) { +int numvfpregs = 32; +for (i = 0; i numvfpregs; i += 2) { +uint64_t vlo = float64_val(env-vfp.regs[i * 2]); +uint64_t vhi = float64_val(env-vfp.regs[(i * 2) + 1]); +cpu_fprintf(f, q%02d=%016 PRIx64 :%016 PRIx64 , +i, vhi, vlo); +vlo = float64_val(env-vfp.regs[(i + 1) * 2]); +vhi = float64_val(env-vfp.regs[((i + 1) * 2) + 1]); +cpu_fprintf(f, q%02d=%016 PRIx64 :%016 PRIx64 \n, +i + 1, vhi, vlo); +} +cpu_fprintf(f, FPCR: %08x FPSR: %08x\n, +vfp_get_fpcr(env), vfp_get_fpsr(env)); +} } static int get_mem_index(DisasContext *s) -- 1.8.5
[Qemu-devel] [PULL 09/52] target-arm: A64: Add decoder skeleton for FP instructions
Add a top level decoder skeleton for FP instructions. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 170 - 1 file changed, 169 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 9ca6460..079c2f7 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -2670,10 +2670,178 @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) } } +/* C3.6.22 Floating point compare + * 31 30 29 28 24 23 22 21 20 16 15 14 13 1095 4 0 + * +---+---+---+---+--+---+--+-+-+--+---+ + * | M | 0 | S | 1 1 1 1 0 | type | 1 | Rm | op | 1 0 0 0 | Rn | op2 | + * +---+---+---+---+--+---+--+-+-+--+---+ + */ +static void disas_fp_compare(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + +/* C3.6.23 Floating point conditional compare + * 31 30 29 28 24 23 22 21 20 16 15 12 11 10 95 4 30 + * +---+---+---+---+--+---+--+--+-+--++--+ + * | M | 0 | S | 1 1 1 1 0 | type | 1 | Rm | cond | 0 1 | Rn | op | nzcv | + * +---+---+---+---+--+---+--+--+-+--++--+ + */ +static void disas_fp_ccomp(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + +/* C3.6.24 Floating point conditional select + * 31 30 29 28 24 23 22 21 20 16 15 12 11 10 95 40 + * +---+---+---+---+--+---+--+--+-+--+--+ + * | M | 0 | S | 1 1 1 1 0 | type | 1 | Rm | cond | 1 1 | Rn | Rd | + * +---+---+---+---+--+---+--+--+-+--+--+ + */ +static void disas_fp_csel(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + +/* C3.6.25 Floating point data-processing (1 source) + * 31 30 29 28 24 23 22 21 2015 14 10 95 40 + * +---+---+---+---+--+---++---+--+--+ + * | M | 0 | S | 1 1 1 1 0 | type | 1 | opcode | 1 0 0 0 0 | Rn | Rd | + * +---+---+---+---+--+---++---+--+--+ + */ +static void disas_fp_1src(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + +/* C3.6.26 Floating point data-processing (2 source) + * 31 30 29 28 24 23 22 21 20 16 1512 11 10 95 40 + * +---+---+---+---+--+---+--++-+--+--+ + * | M | 0 | S | 1 1 1 1 0 | type | 1 | Rm | opcode | 1 0 | Rn | Rd | + * +---+---+---+---+--+---+--++-+--+--+ + */ +static void disas_fp_2src(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + +/* C3.6.27 Floating point data-processing (3 source) + * 31 30 29 28 24 23 22 21 20 16 15 14 10 95 40 + * +---+---+---+---+--++--++--+--+--+ + * | M | 0 | S | 1 1 1 1 1 | type | o1 | Rm | o0 | Ra | Rn | Rd | + * +---+---+---+---+--++--++--+--+--+ + */ +static void disas_fp_3src(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + +/* C3.6.28 Floating point immediate + * 31 30 29 28 24 23 22 21 2013 12 10 95 40 + * +---+---+---+---+--+---++---+--+--+ + * | M | 0 | S | 1 1 1 1 0 | type | 1 |imm8| 1 0 0 | imm5 | Rd | + * +---+---+---+---+--+---++---+--+--+ + */ +static void disas_fp_imm(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + +/* C3.6.29 Floating point - fixed point conversions + * 31 30 29 28 24 23 22 21 20 19 1816 15 10 95 40 + * ++---+---+---+--+---+---++---+--+--+ + * | sf | 0 | S | 1 1 1 1 0 | type | 0 | rmode | opcode | scale | Rn | Rd | + * ++---+---+---+--+---+---++---+--+--+ + */ +static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + +/* C3.6.30 Floating point - integer conversions + * 31 30 29 28 24 23 22 21 20 19 18 16 15 10 9 5 4 0 + * ++---+---+---+--+---+---+-+-+++ + * | sf | 0 | S | 1 1 1 1 0 | type | 0 | rmode | opc | 0 0 0 0 0 0 | Rn | Rd | + * ++---+---+---+--+---+---+-+-+++ + */ +static void disas_fp_int_conv(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + +/* FP-specific subcases of table C3-6 (SIMD and FP data processing) + * 31 30 29 28 25 24 0 + * +---+---+---+-+-+ + * | | 0 | | 1 1 1 1 |
[Qemu-devel] [PULL 47/52] target-arm: use c13_context field for CONTEXTIDR
From: Sergey Fedorov s.fedo...@samsung.com Use c13_context field instead of c13_fcse for CONTEXTIDR register definition. Signed-off-by: Sergey Fedorov s.fedo...@samsung.com Reviewed-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Reviewed-by: Peter Maydell peter.mayd...@linaro.org Message-id: 1387521191-15350-1-git-send-email-s.fedo...@samsung.com Signed-off-by: Peter Maydell peter.mayd...@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 265675d..4af2f9c 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -397,7 +397,7 @@ static const ARMCPRegInfo cp_reginfo[] = { .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse), .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, }, { .name = CONTEXTIDR, .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 1, - .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse), + .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c13_context), .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, }, /* ??? This covers not just the impdef TLB lockdown registers but also * some v7VMSA registers relating to TEX remap, so it is overly broad. -- 1.8.5
[Qemu-devel] [PULL 36/52] char/cadence_uart: Mark struct fields as public/private
From: Peter Crosthwaite peter.crosthwa...@xilinx.com As per current QOM conventions. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Message-id: a1e31bd62e9709ffb9b3efc6c120f83f30b7a660.1388626249.git.peter.crosthwa...@xilinx.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/char/cadence_uart.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index f18db53..a7b2f21 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -110,7 +110,9 @@ #define CADENCE_UART(obj) OBJECT_CHECK(UartState, (obj), TYPE_CADENCE_UART) typedef struct { +/* private */ SysBusDevice parent_obj; +/* public */ MemoryRegion iomem; uint32_t r[R_MAX]; -- 1.8.5
[Qemu-devel] [PULL 42/52] char/cadence_uart: Remove TX timer add TX FIFO state
From: Peter Crosthwaite peter.crosthwa...@xilinx.com This tx timer implementation is flawed. Despite the controller attempting to time the guest visable assertion of the TX-empty status bit (and corresponding interrupt) the controller is still transmitting characters instantaneously. There is also no sense of multiple character delay. The only side effect of this timer is assertion of tx-empty status. So just remove the timer completely and hold tx-empty as permanently asserted (its reset status). This matches the actual behaviour of instantaneous transmission. While we are VMSD version bumping, add the tx_fifo as device state to prepare for upcomming TxFIFO flow control. Implement the interrupt generation logic for the TxFIFO occupancy. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Message-id: 7a208a7eb8d79d6429fe28b1396c3104371807b2.1388626249.git.peter.crosthwa...@xilinx.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/char/cadence_uart.c | 44 +--- 1 file changed, 13 insertions(+), 31 deletions(-) diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index 216eed7..3eeadb1 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -121,13 +121,14 @@ typedef struct { MemoryRegion iomem; uint32_t r[R_MAX]; uint8_t rx_fifo[RX_FIFO_SIZE]; +uint8_t tx_fifo[TX_FIFO_SIZE]; uint32_t rx_wpos; uint32_t rx_count; +uint32_t tx_count; uint64_t char_tx_time; CharDriverState *chr; qemu_irq irq; QEMUTimer *fifo_trigger_handle; -QEMUTimer *tx_time_handle; } UartState; static void uart_update_status(UartState *s) @@ -138,8 +139,12 @@ static void uart_update_status(UartState *s) s-r[R_SR] |= !s-rx_count ? UART_SR_INTR_REMPTY : 0; s-r[R_SR] |= s-rx_count = s-r[R_RTRIG] ? UART_SR_INTR_RTRIG : 0; -s-r[R_SR] |= UART_SR_INTR_TEMPTY; +s-r[R_SR] |= s-tx_count == TX_FIFO_SIZE ? UART_SR_INTR_TFUL : 0; +s-r[R_SR] |= !s-tx_count ? UART_SR_INTR_TEMPTY : 0; +s-r[R_SR] |= s-tx_count = s-r[R_TTRIG] ? UART_SR_TTRIG : 0; + s-r[R_CISR] |= s-r[R_SR] UART_SR_TO_CISR_MASK; +s-r[R_CISR] |= s-r[R_SR] UART_SR_TTRIG ? UART_INTR_TTRIG : 0; qemu_set_irq(s-irq, !!(s-r[R_IMR] s-r[R_CISR])); } @@ -152,24 +157,6 @@ static void fifo_trigger_update(void *opaque) uart_update_status(s); } -static void uart_tx_redo(UartState *s) -{ -uint64_t new_tx_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - -timer_mod(s-tx_time_handle, new_tx_time + s-char_tx_time); - -s-r[R_SR] |= UART_SR_INTR_TEMPTY; - -uart_update_status(s); -} - -static void uart_tx_write(void *opaque) -{ -UartState *s = (UartState *)opaque; - -uart_tx_redo(s); -} - static void uart_rx_reset(UartState *s) { s-rx_wpos = 0; @@ -181,6 +168,7 @@ static void uart_rx_reset(UartState *s) static void uart_tx_reset(UartState *s) { +s-tx_count = 0; } static void uart_send_breaks(UartState *s) @@ -261,10 +249,6 @@ static void uart_ctrl_update(UartState *s) s-r[R_CR] = ~(UART_CR_TXRST | UART_CR_RXRST); -if ((s-r[R_CR] UART_CR_TX_EN) !(s-r[R_CR] UART_CR_TX_DIS)) { -uart_tx_redo(s); -} - if (s-r[R_CR] UART_CR_STARTBRK !(s-r[R_CR] UART_CR_STOPBRK)) { uart_send_breaks(s); } @@ -447,9 +431,6 @@ static int cadence_uart_init(SysBusDevice *dev) s-fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL, (QEMUTimerCB *)fifo_trigger_update, s); -s-tx_time_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL, -(QEMUTimerCB *)uart_tx_write, s); - s-char_tx_time = (get_ticks_per_sec() / 9600) * 10; s-chr = qemu_char_get_next_serial(); @@ -473,17 +454,18 @@ static int cadence_uart_post_load(void *opaque, int version_id) static const VMStateDescription vmstate_cadence_uart = { .name = cadence_uart, -.version_id = 1, -.minimum_version_id = 1, -.minimum_version_id_old = 1, +.version_id = 2, +.minimum_version_id = 2, +.minimum_version_id_old = 2, .post_load = cadence_uart_post_load, .fields = (VMStateField[]) { VMSTATE_UINT32_ARRAY(r, UartState, R_MAX), VMSTATE_UINT8_ARRAY(rx_fifo, UartState, RX_FIFO_SIZE), +VMSTATE_UINT8_ARRAY(tx_fifo, UartState, RX_FIFO_SIZE), VMSTATE_UINT32(rx_count, UartState), +VMSTATE_UINT32(tx_count, UartState), VMSTATE_UINT32(rx_wpos, UartState), VMSTATE_TIMER(fifo_trigger_handle, UartState), -VMSTATE_TIMER(tx_time_handle, UartState), VMSTATE_END_OF_LIST() } }; -- 1.8.5
[Qemu-devel] [PULL 35/52] target-arm: Give the FPSCR rounding modes names
From: Alexander Graf ag...@suse.de When setting rounding modes we currently just hardcode the numeric values for rounding modes in a big switch statement. With AArch64 support coming, we will need to refer to these rounding modes at different places throughout the code though, so let's better give them names so we don't get confused by accident. Signed-off-by: Alexander Graf ag...@suse.de [WN: Commit message tweak, use names from ARM ARM.] Signed-off-by: Will Newton will.new...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/cpu.h| 9 + target-arm/helper.c | 8 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 7084a74..43ca572 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -487,6 +487,15 @@ static inline void vfp_set_fpcr(CPUARMState *env, uint32_t val) vfp_set_fpscr(env, new_fpscr); } +enum arm_fprounding { +FPROUNDING_TIEEVEN, +FPROUNDING_POSINF, +FPROUNDING_NEGINF, +FPROUNDING_ZERO, +FPROUNDING_TIEAWAY, +FPROUNDING_ODD +}; + enum arm_cpu_mode { ARM_CPU_MODE_USR = 0x10, ARM_CPU_MODE_FIQ = 0x11, diff --git a/target-arm/helper.c b/target-arm/helper.c index 74042b8..265675d 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -3815,16 +3815,16 @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val) if (changed (3 22)) { i = (val 22) 3; switch (i) { -case 0: +case FPROUNDING_TIEEVEN: i = float_round_nearest_even; break; -case 1: +case FPROUNDING_POSINF: i = float_round_up; break; -case 2: +case FPROUNDING_NEGINF: i = float_round_down; break; -case 3: +case FPROUNDING_ZERO: i = float_round_to_zero; break; } -- 1.8.5
[Qemu-devel] [PULL 22/52] linux-user: AArch64: define TARGET_CLONE_BACKWARDS
From: Claudio Fontana claudio.font...@linaro.org The AArch64 linux-user support was written before but merged after commit 4ce6243dc621 which cleaned up the handling of the clone() syscall argument order, so we failed to notice that AArch64 also needs TARGET_CLONE_BACKWARDS to be defined. Add this define so that clone and fork syscalls work correctly. Signed-off-by: Claudio Fontana claudio.font...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- linux-user/aarch64/syscall.h | 1 + 1 file changed, 1 insertion(+) diff --git a/linux-user/aarch64/syscall.h b/linux-user/aarch64/syscall.h index aef419e..18f44a8 100644 --- a/linux-user/aarch64/syscall.h +++ b/linux-user/aarch64/syscall.h @@ -7,3 +7,4 @@ struct target_pt_regs { #define UNAME_MACHINE aarch64 #define UNAME_MINIMUM_RELEASE 3.8.0 +#define TARGET_CLONE_BACKWARDS -- 1.8.5
[Qemu-devel] [PULL 34/52] target-arm: A64: Add support for floating point cond select
From: Claudio Fontana claudio.font...@linaro.org This adds decoding support for C3.6.24 FP conditional select. Signed-off-by: Claudio Fontana claudio.font...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 45 - 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 44d8a09..c9fbf0f 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -3304,6 +3304,20 @@ static void disas_fp_ccomp(DisasContext *s, uint32_t insn) } } +/* copy src FP register to dst FP register; type specifies single or double */ +static void gen_mov_fp2fp(DisasContext *s, int type, int dst, int src) +{ +if (type) { +TCGv_i64 v = read_fp_dreg(s, src); +write_fp_dreg(s, dst, v); +tcg_temp_free_i64(v); +} else { +TCGv_i32 v = read_fp_sreg(s, src); +write_fp_sreg(s, dst, v); +tcg_temp_free_i32(v); +} +} + /* C3.6.24 Floating point conditional select * 31 30 29 28 24 23 22 21 20 16 15 12 11 10 95 40 * +---+---+---+---+--+---+--+--+-+--+--+ @@ -3312,7 +3326,36 @@ static void disas_fp_ccomp(DisasContext *s, uint32_t insn) */ static void disas_fp_csel(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +unsigned int mos, type, rm, cond, rn, rd; +int label_continue = -1; + +mos = extract32(insn, 29, 3); +type = extract32(insn, 22, 2); /* 0 = single, 1 = double */ +rm = extract32(insn, 16, 5); +cond = extract32(insn, 12, 4); +rn = extract32(insn, 5, 5); +rd = extract32(insn, 0, 5); + +if (mos || type 1) { +unallocated_encoding(s); +return; +} + +if (cond 0x0e) { /* not always */ +int label_match = gen_new_label(); +label_continue = gen_new_label(); +arm_gen_test_cc(cond, label_match); +/* nomatch: */ +gen_mov_fp2fp(s, type, rd, rm); +tcg_gen_br(label_continue); +gen_set_label(label_match); +} + +gen_mov_fp2fp(s, type, rd, rn); + +if (cond 0x0e) { /* continue */ +gen_set_label(label_continue); +} } /* C3.6.25 Floating point data-processing (1 source) -- 1.8.5
[Qemu-devel] [PULL 08/52] target-arm: A64: implement SVC, BRK
From: Alexander Graf ag...@suse.de Add decoding for the exception generating instructions, and implement SVC (syscalls) and BRK (software breakpoint). Signed-off-by: Alexander Graf ag...@suse.de Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 51 -- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 3a9ffdf..9ca6460 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -808,10 +808,57 @@ static void disas_system(DisasContext *s, uint32_t insn) } } -/* Exception generation */ +/* C3.2.3 Exception generation + * + * 31 24 23 21 20 5 4 2 1 0 + * +-+-++-++ + * | 1 1 0 1 0 1 0 0 | opc | imm16 | op2 | LL | + * +---++--+ + */ static void disas_exc(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int opc = extract32(insn, 21, 3); +int op2_ll = extract32(insn, 0, 5); + +switch (opc) { +case 0: +/* SVC, HVC, SMC; since we don't support the Virtualization + * or TrustZone extensions these all UNDEF except SVC. + */ +if (op2_ll != 1) { +unallocated_encoding(s); +break; +} +gen_exception_insn(s, 0, EXCP_SWI); +break; +case 1: +if (op2_ll != 0) { +unallocated_encoding(s); +break; +} +/* BRK */ +gen_exception_insn(s, 0, EXCP_BKPT); +break; +case 2: +if (op2_ll != 0) { +unallocated_encoding(s); +break; +} +/* HLT */ +unsupported_encoding(s, insn); +break; +case 5: +if (op2_ll 1 || op2_ll 3) { +unallocated_encoding(s); +break; +} +/* DCPS1, DCPS2, DCPS3 */ +unsupported_encoding(s, insn); +break; +default: +unallocated_encoding(s); +break; +} } /* C3.2.7 Unconditional branch (register) -- 1.8.5
[Qemu-devel] [PULL 14/52] target-arm: A64: Implement MRS/MSR/SYS/SYSL
The AArch64 equivalent of the traditional AArch32 cp15 coprocessor registers is the set of instructions MRS/MSR/SYS/SYSL, which cover between them both true system registers and the operations with side effects such as cache maintenance which in AArch32 are mixed in with other cp15 registers. Implement these instructions to look in the cpregs hashtable for the register or operation. Since we don't yet populate the cpregs hashtable with any registers with the AA64 bit set, everything will still UNDEF at this point. MSR/MRS is the first user of is_jmp = DISAS_UPDATE, so fix an infelicity in its handling where the main loop was requiring the caller to do the update of PC rather than just doing it itself. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 112 + 1 file changed, 82 insertions(+), 30 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index e35d2f3..7a9ee82 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -733,28 +733,88 @@ static void handle_msr_i(DisasContext *s, uint32_t insn, unsupported_encoding(s, insn); } -/* C5.6.204 SYS */ -static void handle_sys(DisasContext *s, uint32_t insn, unsigned int l, - unsigned int op1, unsigned int op2, +/* C5.6.129 MRS - move from system register + * C5.6.131 MSR (register) - move to system register + * C5.6.204 SYS + * C5.6.205 SYSL + * These are all essentially the same insn in 'read' and 'write' + * versions, with varying op0 fields. + */ +static void handle_sys(DisasContext *s, uint32_t insn, bool isread, + unsigned int op0, unsigned int op1, unsigned int op2, unsigned int crn, unsigned int crm, unsigned int rt) { -unsupported_encoding(s, insn); -} +const ARMCPRegInfo *ri; +TCGv_i64 tcg_rt; -/* C5.6.129 MRS - move from system register */ -static void handle_mrs(DisasContext *s, uint32_t insn, unsigned int op0, - unsigned int op1, unsigned int op2, - unsigned int crn, unsigned int crm, unsigned int rt) -{ -unsupported_encoding(s, insn); -} +ri = get_arm_cp_reginfo(s-cp_regs, +ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP, + crn, crm, op0, op1, op2)); -/* C5.6.131 MSR (register) - move to system register */ -static void handle_msr(DisasContext *s, uint32_t insn, unsigned int op0, - unsigned int op1, unsigned int op2, - unsigned int crn, unsigned int crm, unsigned int rt) -{ -unsupported_encoding(s, insn); +if (!ri) { +/* Unknown register */ +unallocated_encoding(s); +return; +} + +/* Check access permissions */ +if (!cp_access_ok(s-current_pl, ri, isread)) { +unallocated_encoding(s); +return; +} + +/* Handle special cases first */ +switch (ri-type ~(ARM_CP_FLAG_MASK ~ARM_CP_SPECIAL)) { +case ARM_CP_NOP: +return; +default: +break; +} + +if (use_icount (ri-type ARM_CP_IO)) { +gen_io_start(); +} + +tcg_rt = cpu_reg(s, rt); + +if (isread) { +if (ri-type ARM_CP_CONST) { +tcg_gen_movi_i64(tcg_rt, ri-resetvalue); +} else if (ri-readfn) { +TCGv_ptr tmpptr; +gen_a64_set_pc_im(s-pc - 4); +tmpptr = tcg_const_ptr(ri); +gen_helper_get_cp_reg64(tcg_rt, cpu_env, tmpptr); +tcg_temp_free_ptr(tmpptr); +} else { +tcg_gen_ld_i64(tcg_rt, cpu_env, ri-fieldoffset); +} +} else { +if (ri-type ARM_CP_CONST) { +/* If not forbidden by access permissions, treat as WI */ +return; +} else if (ri-writefn) { +TCGv_ptr tmpptr; +gen_a64_set_pc_im(s-pc - 4); +tmpptr = tcg_const_ptr(ri); +gen_helper_set_cp_reg64(cpu_env, tmpptr, tcg_rt); +tcg_temp_free_ptr(tmpptr); +} else { +tcg_gen_st_i64(tcg_rt, cpu_env, ri-fieldoffset); +} +} + +if (use_icount (ri-type ARM_CP_IO)) { +/* I/O operations must end the TB here (whether read or write) */ +gen_io_end(); +s-is_jmp = DISAS_UPDATE; +} else if (!isread !(ri-type ARM_CP_SUPPRESS_TB_END)) { +/* We default to ending the TB on a coprocessor register write, + * but allow this to be suppressed by the register definition + * (usually only necessary to work around guest bugs). + */ +s-is_jmp = DISAS_UPDATE; +} } /* C3.2.4 System @@ -795,17 +855,7 @@ static void disas_system(DisasContext *s, uint32_t insn) } return; } - -if (op0 == 1) { -/* C5.6.204 SYS */ -handle_sys(s, insn, l, op1, op2, crn, crm, rt); -} else
[Qemu-devel] [PULL 25/52] default-configs: Add config for aarch64-linux-user
Add a config for aarch64-linux-user, thereby enabling it as a valid target. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Alexander Graf ag...@suse.de Reviewed-by: Richard Henderson r...@twiddle.net --- default-configs/aarch64-linux-user.mak | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 default-configs/aarch64-linux-user.mak diff --git a/default-configs/aarch64-linux-user.mak b/default-configs/aarch64-linux-user.mak new file mode 100644 index 000..3df7de5 --- /dev/null +++ b/default-configs/aarch64-linux-user.mak @@ -0,0 +1,3 @@ +# Default configuration for aarch64-linux-user + +CONFIG_GDBSTUB_XML=y -- 1.8.5
[Qemu-devel] [PULL 33/52] target-arm: A64: Add support for floating point conditional compare
From: Claudio Fontana claudio.font...@linaro.org This adds decoding support for C3.6.23 FP Conditional Compare. Signed-off-by: Claudio Fontana claudio.font...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 35 ++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index dc9cc14..44d8a09 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -3268,7 +3268,40 @@ static void disas_fp_compare(DisasContext *s, uint32_t insn) */ static void disas_fp_ccomp(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +unsigned int mos, type, rm, cond, rn, op, nzcv; +TCGv_i64 tcg_flags; +int label_continue = -1; + +mos = extract32(insn, 29, 3); +type = extract32(insn, 22, 2); /* 0 = single, 1 = double */ +rm = extract32(insn, 16, 5); +cond = extract32(insn, 12, 4); +rn = extract32(insn, 5, 5); +op = extract32(insn, 4, 1); +nzcv = extract32(insn, 0, 4); + +if (mos || type 1) { +unallocated_encoding(s); +return; +} + +if (cond 0x0e) { /* not always */ +int label_match = gen_new_label(); +label_continue = gen_new_label(); +arm_gen_test_cc(cond, label_match); +/* nomatch: */ +tcg_flags = tcg_const_i64(nzcv 28); +gen_set_nzcv(tcg_flags); +tcg_temp_free_i64(tcg_flags); +tcg_gen_br(label_continue); +gen_set_label(label_match); +} + +handle_fp_compare(s, type, rn, rm, false, op); + +if (cond 0x0e) { +gen_set_label(label_continue); +} } /* C3.6.24 Floating point conditional select -- 1.8.5
[Qemu-devel] [PULL 03/52] target-arm: A64: add support for ld/st with reg offset
From: Alex Bennée alex.ben...@linaro.org This adds support for the load/store forms using a register offset. Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 144 - 1 file changed, 143 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 0edcee1..67efcf9 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -404,6 +404,54 @@ static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size) tcg_temp_free_i64(tmphi); } +/* + * This utility function is for doing register extension with an + * optional shift. You will likely want to pass a temporary for the + * destination register. See DecodeRegExtend() in the ARM ARM. + */ +static void ext_and_shift_reg(TCGv_i64 tcg_out, TCGv_i64 tcg_in, + int option, unsigned int shift) +{ +int extsize = extract32(option, 0, 2); +bool is_signed = extract32(option, 2, 1); + +if (is_signed) { +switch (extsize) { +case 0: +tcg_gen_ext8s_i64(tcg_out, tcg_in); +break; +case 1: +tcg_gen_ext16s_i64(tcg_out, tcg_in); +break; +case 2: +tcg_gen_ext32s_i64(tcg_out, tcg_in); +break; +case 3: +tcg_gen_mov_i64(tcg_out, tcg_in); +break; +} +} else { +switch (extsize) { +case 0: +tcg_gen_ext8u_i64(tcg_out, tcg_in); +break; +case 1: +tcg_gen_ext16u_i64(tcg_out, tcg_in); +break; +case 2: +tcg_gen_ext32u_i64(tcg_out, tcg_in); +break; +case 3: +tcg_gen_mov_i64(tcg_out, tcg_in); +break; +} +} + +if (shift) { +tcg_gen_shli_i64(tcg_out, tcg_out, shift); +} +} + static inline void gen_check_sp_alignment(DisasContext *s) { /* The AArch64 architecture mandates that (if enabled via PSTATE @@ -902,6 +950,96 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn) } /* + * C3.3.10 Load/store (register offset) + * + * 31 30 29 27 26 25 24 23 22 21 20 16 15 13 12 11 10 9 5 4 0 + * ++---+---+-+-+---+--+-+--+-+++ + * |size| 1 1 1 | V | 0 0 | opc | 1 | Rm | opt | S| 1 0 | Rn | Rt | + * ++---+---+-+-+---+--+-+--+-+++ + * + * For non-vector: + * size: 00- byte, 01 - 16 bit, 10 - 32bit, 11 - 64bit + * opc: 00 - store, 01 - loadu, 10 - loads 64, 11 - loads 32 + * For vector: + * size is opc1:size1:0 so 100 - 128 bit; 110 and 111 unallocated + * opc0: 0 - store, 1 - load + * V: 1 - vector/simd + * opt: extend encoding (see DecodeRegExtend) + * S: if S=1 then scale (essentially index by sizeof(size)) + * Rt: register to transfer into/out of + * Rn: address register or SP for base + * Rm: offset register or ZR for offset + */ +static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn) +{ +int rt = extract32(insn, 0, 5); +int rn = extract32(insn, 5, 5); +int shift = extract32(insn, 12, 1); +int rm = extract32(insn, 16, 5); +int opc = extract32(insn, 22, 2); +int opt = extract32(insn, 13, 3); +int size = extract32(insn, 30, 2); +bool is_signed = false; +bool is_store = false; +bool is_extended = false; +bool is_vector = extract32(insn, 26, 1); + +TCGv_i64 tcg_rm; +TCGv_i64 tcg_addr; + +if (extract32(opt, 1, 1) == 0) { +unallocated_encoding(s); +return; +} + +if (is_vector) { +size |= (opc 2) 1; +if (size 4) { +unallocated_encoding(s); +return; +} +is_store = !extract32(opc, 0, 1); +} else { +if (size == 3 opc == 2) { +/* PRFM - prefetch */ +return; +} +if (opc == 3 size 1) { +unallocated_encoding(s); +return; +} +is_store = (opc == 0); +is_signed = extract32(opc, 1, 1); +is_extended = (size 3) extract32(opc, 0, 1); +} + +if (rn == 31) { +gen_check_sp_alignment(s); +} +tcg_addr = read_cpu_reg_sp(s, rn, 1); + +tcg_rm = read_cpu_reg(s, rm, 1); +ext_and_shift_reg(tcg_rm, tcg_rm, opt, shift ? size : 0); + +tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_rm); + +if (is_vector) { +if (is_store) { +do_fp_st(s, rt, tcg_addr, size); +} else { +do_fp_ld(s, rt, tcg_addr, size); +} +} else { +TCGv_i64 tcg_rt = cpu_reg(s, rt); +if (is_store) { +do_gpr_st(s, tcg_rt, tcg_addr, size); +} else { +do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended); +} +} +} + +/* * C3.3.13 Load/store (unsigned
[Qemu-devel] [PULL 06/52] target-arm: A64: add support for move wide instructions
From: Alex Bennée alex.ben...@linaro.org This patch adds emulation for the mov wide instructions (MOVN, MOVZ, MOVK). Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 51 -- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index c0057a2..dbc865a 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -1644,10 +1644,57 @@ static void disas_logic_imm(DisasContext *s, uint32_t insn) } } -/* Move wide (immediate) */ +/* + * C3.4.5 Move wide (immediate) + * + * 31 30 29 28 23 22 21 20 5 40 + * +--+-+-+-++--+ + * |sf| opc | 1 0 0 1 0 1 | hw | imm16 | Rd | + * +--+-+-+-++--+ + * + * sf: 0 - 32 bit, 1 - 64 bit + * opc: 00 - N, 10 - Z, 11 - K + * hw: shift/16 (0,16, and sf only 32, 48) + */ static void disas_movw_imm(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int rd = extract32(insn, 0, 5); +uint64_t imm = extract32(insn, 5, 16); +int sf = extract32(insn, 31, 1); +int opc = extract32(insn, 29, 2); +int pos = extract32(insn, 21, 2) 4; +TCGv_i64 tcg_rd = cpu_reg(s, rd); +TCGv_i64 tcg_imm; + +if (!sf (pos = 32)) { +unallocated_encoding(s); +return; +} + +switch (opc) { +case 0: /* MOVN */ +case 2: /* MOVZ */ +imm = pos; +if (opc == 0) { +imm = ~imm; +} +if (!sf) { +imm = 0xu; +} +tcg_gen_movi_i64(tcg_rd, imm); +break; +case 3: /* MOVK */ +tcg_imm = tcg_const_i64(imm); +tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_imm, pos, 16); +tcg_temp_free_i64(tcg_imm); +if (!sf) { +tcg_gen_ext32u_i64(tcg_rd, tcg_rd); +} +break; +default: +unallocated_encoding(s); +break; +} } /* C3.4.2 Bitfield -- 1.8.5
[Qemu-devel] [PULL 20/52] target-arm: Widen exclusive-access support struct fields to 64 bits
In preparation for adding support for A64 load/store exclusive instructions, widen the fields in the CPU state struct that deal with address and data values for exclusives from 32 to 64 bits. Although in practice AArch64 and AArch32 exclusive accesses will be generally separate there are some odd theoretical corner cases (eg you should be able to do the exclusive load in AArch32, take an exception to AArch64 and successfully do the store exclusive there), and it's also easier to reason about. The changes in semantics for the variables are: exclusive_addr - extended to 64 bits; -1ULL for monitor lost, otherwise always 2^32 for AArch32 exclusive_val - extended to 64 bits. 64 bit exclusives in AArch32 now use the high half of exclusive_val instead of a separate exclusive_high exclusive_high - is no longer used in AArch32; extended to 64 bits as it will be needed for AArch64's pair-of-64-bit-values exclusives. exclusive_test - extended to 64 bits, as it is an address. Since this is a linux-user-only field, in arm-linux-user it will always have the top 32 bits zero. exclusive_info - stays 32 bits, as it is neither data nor address, but simply holds register indexes etc. AArch64 will be able to fit all its information into 32 bits as well. Note that the refactoring of gen_store_exclusive() coincidentally fixes a minor bug where ldrexd would incorrectly update the first CPU register even if the load for the second register faulted. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- linux-user/main.c | 25 +++ target-arm/cpu.h | 8 +++ target-arm/machine.c | 12 +- target-arm/translate.c | 65 ++ 4 files changed, 64 insertions(+), 46 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index c0df8b5..20f9832 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -589,16 +589,21 @@ do_kernel_trap(CPUARMState *env) static int do_strex(CPUARMState *env) { -uint32_t val; +uint64_t val; int size; int rc = 1; int segv = 0; uint32_t addr; start_exclusive(); -addr = env-exclusive_addr; -if (addr != env-exclusive_test) { +if (env-exclusive_addr != env-exclusive_test) { goto fail; } +/* We know we're always AArch32 so the address is in uint32_t range + * unless it was the -1 exclusive-monitor-lost value (which won't + * match exclusive_test above). + */ +assert(extract64(env-exclusive_addr, 32, 32) == 0); +addr = env-exclusive_addr; size = env-exclusive_info 0xf; switch (size) { case 0: @@ -618,19 +623,19 @@ static int do_strex(CPUARMState *env) env-cp15.c6_data = addr; goto done; } -if (val != env-exclusive_val) { -goto fail; -} if (size == 3) { -segv = get_user_u32(val, addr + 4); +uint32_t valhi; +segv = get_user_u32(valhi, addr + 4); if (segv) { env-cp15.c6_data = addr + 4; goto done; } -if (val != env-exclusive_high) { -goto fail; -} +val = deposit64(val, 32, 32, valhi); +} +if (val != env-exclusive_val) { +goto fail; } + val = env-regs[(env-exclusive_info 8) 0xf]; switch (size) { case 0: diff --git a/target-arm/cpu.h b/target-arm/cpu.h index fc36514..7084a74 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -278,11 +278,11 @@ typedef struct CPUARMState { float_status fp_status; float_status standard_fp_status; } vfp; -uint32_t exclusive_addr; -uint32_t exclusive_val; -uint32_t exclusive_high; +uint64_t exclusive_addr; +uint64_t exclusive_val; +uint64_t exclusive_high; #if defined(CONFIG_USER_ONLY) -uint32_t exclusive_test; +uint64_t exclusive_test; uint32_t exclusive_info; #endif diff --git a/target-arm/machine.c b/target-arm/machine.c index 74f010f..8f9e7d4 100644 --- a/target-arm/machine.c +++ b/target-arm/machine.c @@ -222,9 +222,9 @@ static int cpu_post_load(void *opaque, int version_id) const VMStateDescription vmstate_arm_cpu = { .name = cpu, -.version_id = 13, -.minimum_version_id = 13, -.minimum_version_id_old = 13, +.version_id = 14, +.minimum_version_id = 14, +.minimum_version_id_old = 14, .pre_save = cpu_pre_save, .post_load = cpu_post_load, .fields = (VMStateField[]) { @@ -253,9 +253,9 @@ const VMStateDescription vmstate_arm_cpu = { VMSTATE_VARRAY_INT32(cpreg_vmstate_values, ARMCPU, cpreg_vmstate_array_len, 0, vmstate_info_uint64, uint64_t), -VMSTATE_UINT32(env.exclusive_addr, ARMCPU), -VMSTATE_UINT32(env.exclusive_val, ARMCPU), -VMSTATE_UINT32(env.exclusive_high, ARMCPU), +VMSTATE_UINT64(env.exclusive_addr,
[Qemu-devel] [PULL 27/52] target-arm: A64: Fix vector register access on bigendian hosts
The A64 128 bit vector registers are stored as a pair of uint64_t values in the register array. This means that if we're directly loading or storing a value of size less than 64 bits we must adjust the offset appropriately to account for whether the host is bigendian or not. Provide utility functions to abstract away the offsetof() calculations for the FP registers. For do_fp_st() we can sidestep most of the issues for 64 bit and smaller reg-to-mem transfers by always doing a 64 bit load from the register and writing just the piece we need to memory. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 69 +++--- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 326f36d..ba9573a 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -308,6 +308,26 @@ static TCGv_i64 read_cpu_reg_sp(DisasContext *s, int reg, int sf) return v; } +/* Return the offset into CPUARMState of a slice (from + * the least significant end) of FP register Qn (ie + * Dn, Sn, Hn or Bn). + * (Note that this is not the same mapping as for A32; see cpu.h) + */ +static inline int fp_reg_offset(int regno, TCGMemOp size) +{ +int offs = offsetof(CPUARMState, vfp.regs[regno * 2]); +#ifdef HOST_WORDS_BIGENDIAN +offs += (8 - (1 size)); +#endif +return offs; +} + +/* Offset of the high half of the 128 bit vector Qn */ +static inline int fp_reg_hi_offset(int regno) +{ +return offsetof(CPUARMState, vfp.regs[regno * 2 + 1]); +} + /* Set ZF and NF based on a 64 bit result. This is alas fiddlier * than the 32 bit equivalent. */ @@ -538,31 +558,15 @@ static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr, static void do_fp_st(DisasContext *s, int srcidx, TCGv_i64 tcg_addr, int size) { /* This writes the bottom N bits of a 128 bit wide vector to memory */ -int freg_offs = offsetof(CPUARMState, vfp.regs[srcidx * 2]); TCGv_i64 tmp = tcg_temp_new_i64(); - +tcg_gen_ld_i64(tmp, cpu_env, fp_reg_offset(srcidx, MO_64)); if (size 4) { -switch (size) { -case 0: -tcg_gen_ld8u_i64(tmp, cpu_env, freg_offs); -break; -case 1: -tcg_gen_ld16u_i64(tmp, cpu_env, freg_offs); -break; -case 2: -tcg_gen_ld32u_i64(tmp, cpu_env, freg_offs); -break; -case 3: -tcg_gen_ld_i64(tmp, cpu_env, freg_offs); -break; -} tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s), MO_TE + size); } else { TCGv_i64 tcg_hiaddr = tcg_temp_new_i64(); -tcg_gen_ld_i64(tmp, cpu_env, freg_offs); tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s), MO_TEQ); tcg_gen_qemu_st64(tmp, tcg_addr, get_mem_index(s)); -tcg_gen_ld_i64(tmp, cpu_env, freg_offs + sizeof(float64)); +tcg_gen_ld_i64(tmp, cpu_env, fp_reg_hi_offset(srcidx)); tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8); tcg_gen_qemu_st_i64(tmp, tcg_hiaddr, get_mem_index(s), MO_TEQ); tcg_temp_free_i64(tcg_hiaddr); @@ -577,7 +581,6 @@ static void do_fp_st(DisasContext *s, int srcidx, TCGv_i64 tcg_addr, int size) static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size) { /* This always zero-extends and writes to a full 128 bit wide vector */ -int freg_offs = offsetof(CPUARMState, vfp.regs[destidx * 2]); TCGv_i64 tmplo = tcg_temp_new_i64(); TCGv_i64 tmphi; @@ -596,8 +599,8 @@ static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size) tcg_temp_free_i64(tcg_hiaddr); } -tcg_gen_st_i64(tmplo, cpu_env, freg_offs); -tcg_gen_st_i64(tmphi, cpu_env, freg_offs + sizeof(float64)); +tcg_gen_st_i64(tmplo, cpu_env, fp_reg_offset(destidx, MO_64)); +tcg_gen_st_i64(tmphi, cpu_env, fp_reg_hi_offset(destidx)); tcg_temp_free_i64(tmplo); tcg_temp_free_i64(tmphi); @@ -3224,7 +3227,6 @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof) */ if (itof) { -int freg_offs = offsetof(CPUARMState, vfp.regs[rd * 2]); TCGv_i64 tcg_rn = cpu_reg(s, rn); switch (type) { @@ -3233,9 +3235,9 @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof) /* 32 bit */ TCGv_i64 tmp = tcg_temp_new_i64(); tcg_gen_ext32u_i64(tmp, tcg_rn); -tcg_gen_st_i64(tmp, cpu_env, freg_offs); +tcg_gen_st_i64(tmp, cpu_env, fp_reg_offset(rd, MO_64)); tcg_gen_movi_i64(tmp, 0); -tcg_gen_st_i64(tmp, cpu_env, freg_offs + sizeof(float64)); +tcg_gen_st_i64(tmp, cpu_env, fp_reg_hi_offset(rd)); tcg_temp_free_i64(tmp); break; } @@ -3243,32 +3245,31 @@ static void
[Qemu-devel] [PULL 32/52] target-arm: A64: Add support for floating point compare
From: Claudio Fontana claudio.font...@linaro.org Add decoding support for C3.6.22 Floating-point compare. Signed-off-by: Claudio Fontana claudio.font...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/helper-a64.c| 45 target-arm/helper-a64.h| 4 +++ target-arm/translate-a64.c | 65 +- 3 files changed, 113 insertions(+), 1 deletion(-) diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c index d3f7067..4ce0d01 100644 --- a/target-arm/helper-a64.c +++ b/target-arm/helper-a64.c @@ -77,3 +77,48 @@ uint64_t HELPER(rbit64)(uint64_t x) return x; } + +/* Convert a softfloat float_relation_ (as returned by + * the float*_compare functions) to the correct ARM + * NZCV flag state. + */ +static inline uint32_t float_rel_to_flags(int res) +{ +uint64_t flags; +switch (res) { +case float_relation_equal: +flags = PSTATE_Z | PSTATE_C; +break; +case float_relation_less: +flags = PSTATE_N; +break; +case float_relation_greater: +flags = PSTATE_C; +break; +case float_relation_unordered: +default: +flags = PSTATE_C | PSTATE_V; +break; +} +return flags; +} + +uint64_t HELPER(vfp_cmps_a64)(float32 x, float32 y, void *fp_status) +{ +return float_rel_to_flags(float32_compare_quiet(x, y, fp_status)); +} + +uint64_t HELPER(vfp_cmpes_a64)(float32 x, float32 y, void *fp_status) +{ +return float_rel_to_flags(float32_compare(x, y, fp_status)); +} + +uint64_t HELPER(vfp_cmpd_a64)(float64 x, float64 y, void *fp_status) +{ +return float_rel_to_flags(float64_compare_quiet(x, y, fp_status)); +} + +uint64_t HELPER(vfp_cmped_a64)(float64 x, float64 y, void *fp_status) +{ +return float_rel_to_flags(float64_compare(x, y, fp_status)); +} diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h index a163a94..bca19f3 100644 --- a/target-arm/helper-a64.h +++ b/target-arm/helper-a64.h @@ -22,3 +22,7 @@ DEF_HELPER_FLAGS_1(clz64, TCG_CALL_NO_RWG_SE, i64, i64) DEF_HELPER_FLAGS_1(cls64, TCG_CALL_NO_RWG_SE, i64, i64) DEF_HELPER_FLAGS_1(cls32, TCG_CALL_NO_RWG_SE, i32, i32) DEF_HELPER_FLAGS_1(rbit64, TCG_CALL_NO_RWG_SE, i64, i64) +DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr) +DEF_HELPER_3(vfp_cmpes_a64, i64, f32, f32, ptr) +DEF_HELPER_3(vfp_cmpd_a64, i64, f64, f64, ptr) +DEF_HELPER_3(vfp_cmped_a64, i64, f64, f64, ptr) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index bb36a66..dc9cc14 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -3186,6 +3186,54 @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) } } +static void handle_fp_compare(DisasContext *s, bool is_double, + unsigned int rn, unsigned int rm, + bool cmp_with_zero, bool signal_all_nans) +{ +TCGv_i64 tcg_flags = tcg_temp_new_i64(); +TCGv_ptr fpst = get_fpstatus_ptr(); + +if (is_double) { +TCGv_i64 tcg_vn, tcg_vm; + +tcg_vn = read_fp_dreg(s, rn); +if (cmp_with_zero) { +tcg_vm = tcg_const_i64(0); +} else { +tcg_vm = read_fp_dreg(s, rm); +} +if (signal_all_nans) { +gen_helper_vfp_cmped_a64(tcg_flags, tcg_vn, tcg_vm, fpst); +} else { +gen_helper_vfp_cmpd_a64(tcg_flags, tcg_vn, tcg_vm, fpst); +} +tcg_temp_free_i64(tcg_vn); +tcg_temp_free_i64(tcg_vm); +} else { +TCGv_i32 tcg_vn, tcg_vm; + +tcg_vn = read_fp_sreg(s, rn); +if (cmp_with_zero) { +tcg_vm = tcg_const_i32(0); +} else { +tcg_vm = read_fp_sreg(s, rm); +} +if (signal_all_nans) { +gen_helper_vfp_cmpes_a64(tcg_flags, tcg_vn, tcg_vm, fpst); +} else { +gen_helper_vfp_cmps_a64(tcg_flags, tcg_vn, tcg_vm, fpst); +} +tcg_temp_free_i32(tcg_vn); +tcg_temp_free_i32(tcg_vm); +} + +tcg_temp_free_ptr(fpst); + +gen_set_nzcv(tcg_flags); + +tcg_temp_free_i64(tcg_flags); +} + /* C3.6.22 Floating point compare * 31 30 29 28 24 23 22 21 20 16 15 14 13 1095 4 0 * +---+---+---+---+--+---+--+-+-+--+---+ @@ -3194,7 +3242,22 @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) */ static void disas_fp_compare(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +unsigned int mos, type, rm, op, rn, opc, op2r; + +mos = extract32(insn, 29, 3); +type = extract32(insn, 22, 2); /* 0 = single, 1 = double */ +rm = extract32(insn, 16, 5); +op = extract32(insn, 14, 2); +rn = extract32(insn, 5, 5); +opc = extract32(insn, 3, 2); +op2r = extract32(insn, 0, 3); + +if (mos || op || op2r || type 1) { +
Re: [Qemu-devel] [PATCH] acpi unit-test: resolved iasl crash
On Sun, Dec 29, 2013 at 02:32:50PM +0200, Marcel Apfelbaum wrote: It seems that iasl has an issue when disassembles some ACPI tables using the command line: iasl -e DSDT -e SSDT -d HPET I opened a bug on iasl project: https://github.com/acpica/acpica/issues/20 Modified the iasl command line to iasl -d HPET until the problem is solved. The command line remained the same for DSDT and SSDT tables. Reported-by:Michael S. Tsirkin m...@redhat.com space needed after : Signed-off-by: Marcel Apfelbaum marce...@redhat.com --- tests/acpi-test.c | 16 +--- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/acpi-test.c b/tests/acpi-test.c index 2d32b69..26d2e26 100644 --- a/tests/acpi-test.c +++ b/tests/acpi-test.c @@ -403,7 +403,7 @@ static void dump_aml_files(test_data *data, bool rebuild) } } -static void load_asl(GArray *sdts, AcpiSdtTable *sdt) +static void load_asl(GArray *sdts, AcpiSdtTable *sdt, bool referenceDsdt) { AcpiSdtTable *temp; GError *error = NULL; @@ -419,9 +419,11 @@ static void load_asl(GArray *sdts, AcpiSdtTable *sdt) /* build command line */ g_string_append_printf(command_line, -p %s , sdt-asl_file); -for (i = 0; i 2; ++i) { /* reference DSDT and SSDT */ -temp = g_array_index(sdts, AcpiSdtTable, i); -g_string_append_printf(command_line, -e %s , temp-aml_file); +if (referenceDsdt) { +for (i = 0; i 2; ++i) { /* reference DSDT and SSDT */ +temp = g_array_index(sdts, AcpiSdtTable, i); +g_string_append_printf(command_line, -e %s , temp-aml_file); +} } g_string_append_printf(command_line, -d %s, sdt-aml_file); @@ -510,14 +512,14 @@ static void test_acpi_asl(test_data *data) dump_aml_files(data, false); for (i = 0; i data-ssdt_tables-len; ++i) { GString *asl, *exp_asl; - +bool referenceDsdt = (i 2); /* only for DSDT and SSDT */ Please don't use camelCase for variables. Can we check the table signature instead of looking at the index? sdt = g_array_index(data-ssdt_tables, AcpiSdtTable, i); exp_sdt = g_array_index(exp_data.ssdt_tables, AcpiSdtTable, i); -load_asl(data-ssdt_tables, sdt); +load_asl(data-ssdt_tables, sdt, referenceDsdt); asl = normalize_asl(sdt-asl); -load_asl(exp_data.ssdt_tables, exp_sdt); +load_asl(exp_data.ssdt_tables, exp_sdt, referenceDsdt); exp_asl = normalize_asl(exp_sdt-asl); g_assert(!g_strcmp0(asl-str, exp_asl-str)); -- 1.8.3.1
[Qemu-devel] [PULL 19/52] target-arm: aarch64: add support for ld lit
From: Alexander Graf ag...@suse.de Adds support for Load Register (literal), both normal and SIMD/FP forms. Signed-off-by: Alexander Graf ag...@suse.de Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 47 -- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 538d69e..6197441 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -1112,10 +1112,53 @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn) unsupported_encoding(s, insn); } -/* Load register (literal) */ +/* + * C3.3.5 Load register (literal) + * + * 31 30 29 27 26 25 24 235 4 0 + * +-+---+---+-+---+---+ + * | opc | 0 1 1 | V | 0 0 | imm19 | Rt | + * +-+---+---+-+---+---+ + * + * V: 1 - vector (simd/fp) + * opc (non-vector): 00 - 32 bit, 01 - 64 bit, + * 10- 32 bit signed, 11 - prefetch + * opc (vector): 00 - 32 bit, 01 - 64 bit, 10 - 128 bit (11 unallocated) + */ static void disas_ld_lit(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int rt = extract32(insn, 0, 5); +int64_t imm = sextract32(insn, 5, 19) 2; +bool is_vector = extract32(insn, 26, 1); +int opc = extract32(insn, 30, 2); +bool is_signed = false; +int size = 2; +TCGv_i64 tcg_rt, tcg_addr; + +if (is_vector) { +if (opc == 3) { +unallocated_encoding(s); +return; +} +size = 2 + opc; +} else { +if (opc == 3) { +/* PRFM (literal) : prefetch */ +return; +} +size = 2 + extract32(opc, 0, 1); +is_signed = extract32(opc, 1, 1); +} + +tcg_rt = cpu_reg(s, rt); + +tcg_addr = tcg_const_i64((s-pc - 4) + imm); +if (is_vector) { +do_fp_ld(s, rt, tcg_addr, size); +} else { +do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false); +} +tcg_temp_free_i64(tcg_addr); } /* -- 1.8.5
Re: [Qemu-devel] [PATCH] hw/misc/blob-loader: add a generic blob loader
Il 06/01/2014 06:36, Li Guang ha scritto: dma_memory_write() work? what about cpu_physical_memory_write_rom ? Sorry, I missed that load_image_targphys is already doing the right thing on reset. Paolo
Re: [Qemu-devel] [PATCH] hw/misc/blob-loader: add a generic blob loader
Il 06/01/2014 08:56, Peter Crosthwaite ha scritto: What are the guidelines for when to use one or the other? -machine firmware= if you want to load a firmware blob in a board specific way. This if you want to place a blob in memory at an arbitrary location on reset. -machine firmware= is also a pretty bad design because it's not extensible and doesn't apply to most boards. We really should get per-board -machine options, so that you can have a less generic name than firmware. Paolo
Re: [Qemu-devel] [PATCHv2 04/18] qemu-iotests: fix test 013 to work with any protocol
On 06.01.2014 11:09, Fam Zheng wrote: On 2014年01月06日 14:48, Peter Lieven wrote: On 06.01.2014 06:31, Fam Zheng wrote: On 2014年01月06日 01:21, Peter Lieven wrote: Signed-off-by: Peter Lieven p...@kamp.de --- tests/qemu-iotests/013 |9 - tests/qemu-iotests/013.out |2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/qemu-iotests/013 b/tests/qemu-iotests/013 index ea3cab9..0dbc934 100755 --- a/tests/qemu-iotests/013 +++ b/tests/qemu-iotests/013 @@ -41,14 +41,14 @@ trap _cleanup; exit \$status 0 1 2 3 15 # much of this could be generic for any format supporting compression. _supported_fmt qcow qcow2 -_supported_proto file +_supported_proto generic _supported_os Linux TEST_OFFSETS=0 4294967296 TEST_OPS=writev read write readv CLUSTER_SIZE=4096 I think dropping these three TEST_IMG overriding change... -_make_test_img 6G +TEST_IMG=$TEST_IMG.orig _make_test_img 6G #1 echo Testing empty image echo @@ -56,16 +56,15 @@ echo for offset in $TEST_OFFSETS; do echo At offset $offset: for op in $TEST_OPS; do -io_test $op $offset $CLUSTER_SIZE 8 +TEST_IMG=$TEST_IMG.orig io_test $op $offset $CLUSTER_SIZE 8 #2 done -_check_test_img +TEST_IMG=$TEST_IMG.orig _check_test_img #3 done echo Compressing image echo -mv $TEST_IMG $TEST_IMG.orig and changing this to TEST_IMG=$TEST_IMG.orig _make_test_img 6G Should work. Unfortunately it doesn't. All subsequent commands will then work on $TEST_IMG.orig altough they shouldn't. In case of 013 this is io_test, _check_test_img and the cleanup at the end. Why? The overriding is temporary and subsequent commands are not affected. If you put in a singe TEST_IMG=$TEST_IMG.orig line, this affects all further commands in the same test script. If you put the TEST_IMG=$TEST_IMG.orig before a command it affectes only this single command. My proposal above doesn't work, though, because an empty new image doesn't contain the right data, what is needed here is copy. So maybe change the mv line to: $QEMU_IMG convert -f $IMGFMT -O $IMGFMT $TEST_IMG $TEST_IMG.orig could do the work, but I'm not sure if this fits every case. This is unnecessary (copy) overhead and in some cases it could falsify the test. The convert process does not guarantee to create identical copies. You could use raw format, but in this case the image can only be a multiple of 512 byte. There are 3 options: - override it in every line that should use an alternate $TEST_IMG - save the original $TEST_IMG and restore it. - rework all commands to take the file as parameter and not use a global variable for it. I choosed the first one because it makes clear which $TEST_IMG is acutally used. You see from the output and the code that you are dealing with the file that is later used as $TEST_IMG.orig. If you see $TEST_IMG there you can't distinguish if its the backing or original file or the actual image. But I thought that this would be controversal. This is I why I splitted the patch into individual ones. So its possible to drop all these patches and still be able to proceed with the integration of the NFS protocol driver. I'll leave maintainers to decide. That is the best. I from my perspective have checked that the NFS driver is working great and provided fixes for a lot of tests to make the iotests work with NFS and QCOW2/VMDK. Most of the tests are there to test the formats actually and errors are likely to happen with every protocol. I would be totally fine if maintainers pick up patches 1,2,3,16,17 and leave the rest as is. Peter
[Qemu-devel] [PATCH] xenfb: map framebuffer read-only and handle unmap errors
The framebuffer is needlessly mapped (PROT_READ | PROT_WRITE), map it PROT_READ instead. The framebuffer is unmapped by replacing the framebuffer pages with anonymous shared memory, calling mmap. Check for return errors and print a warning. Signed-off-by: Stefano Stabellini stefano.stabell...@eu.citrix.com CC: Gerd Hoffmann kra...@redhat.com CC: Paolo Bonzini pbonz...@redhat.com CC: Anthony Liguori anth...@codemonkey.ws CC: phco...@gmail.com diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c index f0333a0..cb9d456 100644 --- a/hw/display/xenfb.c +++ b/hw/display/xenfb.c @@ -495,7 +495,7 @@ static int xenfb_map_fb(struct XenFB *xenfb) munmap(map, n_fbdirs * XC_PAGE_SIZE); xenfb-pixels = xc_map_foreign_pages(xen_xc, xenfb-c.xendev.dom, -PROT_READ | PROT_WRITE, fbmfns, xenfb-fbpages); +PROT_READ, fbmfns, xenfb-fbpages); if (xenfb-pixels == NULL) goto out; @@ -903,6 +903,11 @@ static void fb_disconnect(struct XenDevice *xendev) fb-pixels = mmap(fb-pixels, fb-fbpages * XC_PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); +if (fb-pixels == MAP_FAILED) { +xen_be_printf(xendev, 0, +Couldn't replace the framebuffer with anonymous memory errno=%d\n, +errno); +} common_unbind(fb-c); fb-feature_update = 0; fb-bug_trigger= 0;
[Qemu-devel] [PULL 12/52] target-arm: Update generic cpreg code for AArch64
Update the generic cpreg support code to also handle AArch64: AArch64-visible registers coexist in the same hash table with AArch32-visible ones, with a bit in the hash key distinguishing them. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- target-arm/cpu.h| 78 --- target-arm/helper.c | 105 ++-- target-arm/kvm-consts.h | 37 + 3 files changed, 211 insertions(+), 9 deletions(-) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 56ed591..9430464 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -572,18 +572,43 @@ void armv7m_nvic_complete_irq(void *opaque, int irq); *or via MRRC/MCRR?) * We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field. * (In this case crn and opc2 should be zero.) + * For AArch64, there is no 32/64 bit size distinction; + * instead all registers have a 2 bit op0, 3 bit op1 and op2, + * and 4 bit CRn and CRm. The encoding patterns are chosen + * to be easy to convert to and from the KVM encodings, and also + * so that the hashtable can contain both AArch32 and AArch64 + * registers (to allow for interprocessing where we might run + * 32 bit code on a 64 bit core). */ +/* This bit is private to our hashtable cpreg; in KVM register + * IDs the AArch64/32 distinction is the KVM_REG_ARM/ARM64 + * in the upper bits of the 64 bit ID. + */ +#define CP_REG_AA64_SHIFT 28 +#define CP_REG_AA64_MASK (1 CP_REG_AA64_SHIFT) + #define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2) \ (((cp) 16) | ((is64) 15) | ((crn) 11) |\ ((crm) 7) | ((opc1) 3) | (opc2)) +#define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \ +(CP_REG_AA64_MASK | \ + ((cp) CP_REG_ARM_COPROC_SHIFT) |\ + ((op0) CP_REG_ARM64_SYSREG_OP0_SHIFT) | \ + ((op1) CP_REG_ARM64_SYSREG_OP1_SHIFT) | \ + ((crn) CP_REG_ARM64_SYSREG_CRN_SHIFT) | \ + ((crm) CP_REG_ARM64_SYSREG_CRM_SHIFT) | \ + ((op2) CP_REG_ARM64_SYSREG_OP2_SHIFT)) + /* Convert a full 64 bit KVM register ID to the truncated 32 bit * version used as a key for the coprocessor register hashtable */ static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid) { uint32_t cpregid = kvmid; -if ((kvmid CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) { +if ((kvmid CP_REG_ARCH_MASK) == CP_REG_ARM64) { +cpregid |= CP_REG_AA64_MASK; +} else if ((kvmid CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) { cpregid |= (1 15); } return cpregid; @@ -594,11 +619,18 @@ static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid) */ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid) { -uint64_t kvmid = cpregid ~(1 15); -if (cpregid (1 15)) { -kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM; +uint64_t kvmid; + +if (cpregid CP_REG_AA64_MASK) { +kvmid = cpregid ~CP_REG_AA64_MASK; +kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM64; } else { -kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM; +kvmid = cpregid ~(1 15); +if (cpregid (1 15)) { +kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM; +} else { +kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM; +} } return kvmid; } @@ -634,6 +666,21 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid) /* Mask of only the flag bits in a type field */ #define ARM_CP_FLAG_MASK 0x7f +/* Valid values for ARMCPRegInfo state field, indicating which of + * the AArch32 and AArch64 execution states this register is visible in. + * If the reginfo doesn't explicitly specify then it is AArch32 only. + * If the reginfo is declared to be visible in both states then a second + * reginfo is synthesised for the AArch32 view of the AArch64 register, + * such that the AArch32 view is the lower 32 bits of the AArch64 one. + * Note that we rely on the values of these enums as we iterate through + * the various states in some places. + */ +enum { +ARM_CP_STATE_AA32 = 0, +ARM_CP_STATE_AA64 = 1, +ARM_CP_STATE_BOTH = 2, +}; + /* Return true if cptype is a valid type field. This is used to try to * catch errors where the sentinel has been accidentally left off the end * of a list of registers. @@ -655,6 +702,8 @@ static inline bool cptype_valid(int cptype) * (ie anything visible in PL2 is visible in S-PL1, some things are only * visible in S-PL1) but Secure PL1 is a bit of a mouthful, we bend the * terminology a little and call this PL3. + * In AArch64 things are somewhat simpler as the PLx bits line up exactly + * with the ELx exception levels. * * If access permissions for a register are more complex than can be * described with these bits, then use a laxer set of restrictions, and @@ -676,6 +725,10 @@ static inline bool cptype_valid(int cptype) static inline int arm_current_pl(CPUARMState *env) { +
[Qemu-devel] [PULL 21/52] target-arm: A64: support for ld/st/cl exclusive
From: Michael Matz m...@suse.de This implement exclusive loads/stores for aarch64 along the lines of arm32 and ppc implementations. The exclusive load remembers the address and loaded value. The exclusive store throws an an exception which uses those values to check for equality in a proper exclusive region. This is not actually the architecture mandated semantics (for either AArch32 or AArch64) but it is close enough for typical guest code sequences to work correctly, and saves us from having to monitor all guest stores. It's fairly easy to come up with test cases where we don't behave like hardware - we don't for example model cache line behaviour. However in the common patterns this works, and the existing 32 bit ARM exclusive access implementation has the same limitations. AArch64 also implements new acquire/release loads/stores (which may be either exclusive or non-exclusive). These imposes extra ordering constraints on memory operations (ie they act as if they have an implicit barrier built into them). As TCG is single-threaded all our barriers are no-ops, so these just behave like normal loads and stores. Signed-off-by: Michael Matz m...@suse.de Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- linux-user/main.c | 127 +++- target-arm/translate-a64.c | 156 - 2 files changed, 277 insertions(+), 6 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 20f9832..cabc9e1 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -585,8 +585,8 @@ do_kernel_trap(CPUARMState *env) return 0; } -#endif +/* Store exclusive handling for AArch32 */ static int do_strex(CPUARMState *env) { uint64_t val; @@ -670,7 +670,6 @@ done: return segv; } -#ifdef TARGET_ABI32 void cpu_loop(CPUARMState *env) { CPUState *cs = CPU(arm_env_get_cpu(env)); @@ -885,6 +884,122 @@ void cpu_loop(CPUARMState *env) #else +/* + * Handle AArch64 store-release exclusive + * + * rs = gets the status result of store exclusive + * rt = is the register that is stored + * rt2 = is the second register store (in STP) + * + */ +static int do_strex_a64(CPUARMState *env) +{ +uint64_t val; +int size; +bool is_pair; +int rc = 1; +int segv = 0; +uint64_t addr; +int rs, rt, rt2; + +start_exclusive(); +/* size | is_pair 2 | (rs 4) | (rt 9) | (rt2 14)); */ +size = extract32(env-exclusive_info, 0, 2); +is_pair = extract32(env-exclusive_info, 2, 1); +rs = extract32(env-exclusive_info, 4, 5); +rt = extract32(env-exclusive_info, 9, 5); +rt2 = extract32(env-exclusive_info, 14, 5); + +addr = env-exclusive_addr; + +if (addr != env-exclusive_test) { +goto finish; +} + +switch (size) { +case 0: +segv = get_user_u8(val, addr); +break; +case 1: +segv = get_user_u16(val, addr); +break; +case 2: +segv = get_user_u32(val, addr); +break; +case 3: +segv = get_user_u64(val, addr); +break; +default: +abort(); +} +if (segv) { +env-cp15.c6_data = addr; +goto error; +} +if (val != env-exclusive_val) { +goto finish; +} +if (is_pair) { +if (size == 2) { +segv = get_user_u32(val, addr + 4); +} else { +segv = get_user_u64(val, addr + 8); +} +if (segv) { +env-cp15.c6_data = addr + (size == 2 ? 4 : 8); +goto error; +} +if (val != env-exclusive_high) { +goto finish; +} +} +val = env-xregs[rt]; +switch (size) { +case 0: +segv = put_user_u8(val, addr); +break; +case 1: +segv = put_user_u16(val, addr); +break; +case 2: +segv = put_user_u32(val, addr); +break; +case 3: +segv = put_user_u64(val, addr); +break; +} +if (segv) { +goto error; +} +if (is_pair) { +val = env-xregs[rt2]; +if (size == 2) { +segv = put_user_u32(val, addr + 4); +} else { +segv = put_user_u64(val, addr + 8); +} +if (segv) { +env-cp15.c6_data = addr + (size == 2 ? 4 : 8); +goto error; +} +} +rc = 0; +finish: +env-pc += 4; +/* rs == 31 encodes a write to the ZR, thus throwing away + * the status return. This is rather silly but valid. + */ +if (rs 31) { +env-xregs[rs] = rc; +} +error: +/* instruction faulted, PC does not advance */ +/* either way a strex releases any exclusive lock we have */ +env-exclusive_addr = -1; +end_exclusive(); +return segv; +} + /* AArch64 main loop */ void cpu_loop(CPUARMState *env) { @@ -944,7 +1059,7 @@ void cpu_loop(CPUARMState *env)
[Qemu-devel] [PULL 05/52] target-arm: A64: add support for add, addi, sub, subi
From: Alex Bennée alex.ben...@linaro.org Implement the non-carry forms of addition and subtraction (immediate, extended register and shifted register). This includes the code to calculate NZCV if the instruction calls for setting the flags. Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 292 - 1 file changed, 286 insertions(+), 6 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index a2cc9f0..c0057a2 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -297,6 +297,102 @@ static inline void gen_logic_CC(int sf, TCGv_i64 result) tcg_gen_movi_i32(cpu_VF, 0); } +/* dest = T0 + T1; compute C, N, V and Z flags */ +static void gen_add_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1) +{ +if (sf) { +TCGv_i64 result, flag, tmp; +result = tcg_temp_new_i64(); +flag = tcg_temp_new_i64(); +tmp = tcg_temp_new_i64(); + +tcg_gen_movi_i64(tmp, 0); +tcg_gen_add2_i64(result, flag, t0, tmp, t1, tmp); + +tcg_gen_trunc_i64_i32(cpu_CF, flag); + +gen_set_NZ64(result); + +tcg_gen_xor_i64(flag, result, t0); +tcg_gen_xor_i64(tmp, t0, t1); +tcg_gen_andc_i64(flag, flag, tmp); +tcg_temp_free_i64(tmp); +tcg_gen_shri_i64(flag, flag, 32); +tcg_gen_trunc_i64_i32(cpu_VF, flag); + +tcg_gen_mov_i64(dest, result); +tcg_temp_free_i64(result); +tcg_temp_free_i64(flag); +} else { +/* 32 bit arithmetic */ +TCGv_i32 t0_32 = tcg_temp_new_i32(); +TCGv_i32 t1_32 = tcg_temp_new_i32(); +TCGv_i32 tmp = tcg_temp_new_i32(); + +tcg_gen_movi_i32(tmp, 0); +tcg_gen_trunc_i64_i32(t0_32, t0); +tcg_gen_trunc_i64_i32(t1_32, t1); +tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, tmp, t1_32, tmp); +tcg_gen_mov_i32(cpu_ZF, cpu_NF); +tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32); +tcg_gen_xor_i32(tmp, t0_32, t1_32); +tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp); +tcg_gen_extu_i32_i64(dest, cpu_NF); + +tcg_temp_free_i32(tmp); +tcg_temp_free_i32(t0_32); +tcg_temp_free_i32(t1_32); +} +} + +/* dest = T0 - T1; compute C, N, V and Z flags */ +static void gen_sub_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1) +{ +if (sf) { +/* 64 bit arithmetic */ +TCGv_i64 result, flag, tmp; + +result = tcg_temp_new_i64(); +flag = tcg_temp_new_i64(); +tcg_gen_sub_i64(result, t0, t1); + +gen_set_NZ64(result); + +tcg_gen_setcond_i64(TCG_COND_GEU, flag, t0, t1); +tcg_gen_trunc_i64_i32(cpu_CF, flag); + +tcg_gen_xor_i64(flag, result, t0); +tmp = tcg_temp_new_i64(); +tcg_gen_xor_i64(tmp, t0, t1); +tcg_gen_and_i64(flag, flag, tmp); +tcg_temp_free_i64(tmp); +tcg_gen_shri_i64(flag, flag, 32); +tcg_gen_trunc_i64_i32(cpu_VF, flag); +tcg_gen_mov_i64(dest, result); +tcg_temp_free_i64(flag); +tcg_temp_free_i64(result); +} else { +/* 32 bit arithmetic */ +TCGv_i32 t0_32 = tcg_temp_new_i32(); +TCGv_i32 t1_32 = tcg_temp_new_i32(); +TCGv_i32 tmp; + +tcg_gen_trunc_i64_i32(t0_32, t0); +tcg_gen_trunc_i64_i32(t1_32, t1); +tcg_gen_sub_i32(cpu_NF, t0_32, t1_32); +tcg_gen_mov_i32(cpu_ZF, cpu_NF); +tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0_32, t1_32); +tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32); +tmp = tcg_temp_new_i32(); +tcg_gen_xor_i32(tmp, t0_32, t1_32); +tcg_temp_free_i32(t0_32); +tcg_temp_free_i32(t1_32); +tcg_gen_and_i32(cpu_VF, cpu_VF, tmp); +tcg_temp_free_i32(tmp); +tcg_gen_extu_i32_i64(dest, cpu_NF); +} +} + /* * Load/Store generators */ @@ -1328,10 +1424,68 @@ static void disas_pc_rel_adr(DisasContext *s, uint32_t insn) tcg_gen_movi_i64(cpu_reg(s, rd), base + offset); } -/* Add/subtract (immediate) */ +/* + * C3.4.1 Add/subtract (immediate) + * + * 31 30 29 28 24 23 22 21 10 9 5 4 0 + * +--+--+--+---+-+-+-+-+ + * |sf|op| S| 1 0 0 0 1 |shift|imm12| Rn | Rd | + * +--+--+--+---+-+-+-+-+ + * + *sf: 0 - 32bit, 1 - 64bit + *op: 0 - add , 1 - sub + * S: 1 - set flags + * shift: 00 - LSL imm by 0, 01 - LSL imm by 12 + */ static void disas_add_sub_imm(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int rd = extract32(insn, 0, 5); +int rn = extract32(insn, 5, 5); +uint64_t imm = extract32(insn, 10, 12); +int shift = extract32(insn, 22, 2); +bool setflags = extract32(insn, 29, 1); +bool sub_op = extract32(insn, 30, 1); +bool is_64bit = extract32(insn, 31, 1);
Re: [Qemu-devel] [PATCHv2 04/18] qemu-iotests: fix test 013 to work with any protocol
On 2014年01月06日 20:21, Peter Lieven wrote: On 06.01.2014 11:09, Fam Zheng wrote: On 2014年01月06日 14:48, Peter Lieven wrote: On 06.01.2014 06:31, Fam Zheng wrote: On 2014年01月06日 01:21, Peter Lieven wrote: Signed-off-by: Peter Lieven p...@kamp.de --- tests/qemu-iotests/013 |9 - tests/qemu-iotests/013.out |2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/qemu-iotests/013 b/tests/qemu-iotests/013 index ea3cab9..0dbc934 100755 --- a/tests/qemu-iotests/013 +++ b/tests/qemu-iotests/013 @@ -41,14 +41,14 @@ trap _cleanup; exit \$status 0 1 2 3 15 # much of this could be generic for any format supporting compression. _supported_fmt qcow qcow2 -_supported_proto file +_supported_proto generic _supported_os Linux TEST_OFFSETS=0 4294967296 TEST_OPS=writev read write readv CLUSTER_SIZE=4096 I think dropping these three TEST_IMG overriding change... -_make_test_img 6G +TEST_IMG=$TEST_IMG.orig _make_test_img 6G #1 echo Testing empty image echo @@ -56,16 +56,15 @@ echo for offset in $TEST_OFFSETS; do echo At offset $offset: for op in $TEST_OPS; do -io_test $op $offset $CLUSTER_SIZE 8 +TEST_IMG=$TEST_IMG.orig io_test $op $offset $CLUSTER_SIZE 8 #2 done -_check_test_img +TEST_IMG=$TEST_IMG.orig _check_test_img #3 done echo Compressing image echo -mv $TEST_IMG $TEST_IMG.orig and changing this to TEST_IMG=$TEST_IMG.orig _make_test_img 6G Should work. Unfortunately it doesn't. All subsequent commands will then work on $TEST_IMG.orig altough they shouldn't. In case of 013 this is io_test, _check_test_img and the cleanup at the end. Why? The overriding is temporary and subsequent commands are not affected. If you put in a singe TEST_IMG=$TEST_IMG.orig line, this affects all further commands in the same test script. If you put the TEST_IMG=$TEST_IMG.orig before a command it affectes only this single command. My proposal above doesn't work, though, because an empty new image doesn't contain the right data, what is needed here is copy. So maybe change the mv line to: $QEMU_IMG convert -f $IMGFMT -O $IMGFMT $TEST_IMG $TEST_IMG.orig could do the work, but I'm not sure if this fits every case. This is unnecessary (copy) overhead and in some cases it could falsify the test. The convert process does not guarantee to create identical copies. You could use raw format, but in this case the image can only be a multiple of 512 byte. OK, thanks for clarification. Fam
[Qemu-devel] [PULL 29/52] target-arm: A64: Add Floating-point data-processing (2 source) insns
From: Alexander Graf ag...@suse.de This patch adds emulation for the Floating-point data-processing (2 source) group of instructions. Signed-off-by: Alexander Graf ag...@suse.de [WN: Commit message tweak, merge single and double precision patches. Rebase and update to new infrastructure. Incorporate FMIN/FMAX support patch by Michael Matz.] Signed-off-by: Will Newton will.new...@linaro.org [PMM: * added convenience accessors for FP s and d regs * pulled the field decode and opcode validity check up a level] Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 182 - 1 file changed, 181 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index ba9573a..c406e2a 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -328,6 +328,60 @@ static inline int fp_reg_hi_offset(int regno) return offsetof(CPUARMState, vfp.regs[regno * 2 + 1]); } +/* Convenience accessors for reading and writing single and double + * FP registers. Writing clears the upper parts of the associated + * 128 bit vector register, as required by the architecture. + * Note that unlike the GP register accessors, the values returned + * by the read functions must be manually freed. + */ +static TCGv_i64 read_fp_dreg(DisasContext *s, int reg) +{ +TCGv_i64 v = tcg_temp_new_i64(); + +tcg_gen_ld_i64(v, cpu_env, fp_reg_offset(reg, MO_64)); +return v; +} + +static TCGv_i32 read_fp_sreg(DisasContext *s, int reg) +{ +TCGv_i32 v = tcg_temp_new_i32(); + +tcg_gen_ld_i32(v, cpu_env, fp_reg_offset(reg, MO_32)); +return v; +} + +static void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v) +{ +TCGv_i64 tcg_zero = tcg_const_i64(0); + +tcg_gen_st_i64(v, cpu_env, fp_reg_offset(reg, MO_64)); +tcg_gen_st_i64(tcg_zero, cpu_env, fp_reg_hi_offset(reg)); +tcg_temp_free_i64(tcg_zero); +} + +static void write_fp_sreg(DisasContext *s, int reg, TCGv_i32 v) +{ +TCGv_i64 tmp = tcg_temp_new_i64(); + +tcg_gen_extu_i32_i64(tmp, v); +write_fp_dreg(s, reg, tmp); +tcg_temp_free_i64(tmp); +} + +static TCGv_ptr get_fpstatus_ptr(void) +{ +TCGv_ptr statusptr = tcg_temp_new_ptr(); +int offset; + +/* In A64 all instructions (both FP and Neon) use the FPCR; + * there is no equivalent of the A32 Neon standard FPSCR value + * and all operations use vfp.fp_status. + */ +offset = offsetof(CPUARMState, vfp.fp_status); +tcg_gen_addi_ptr(statusptr, cpu_env, offset); +return statusptr; +} + /* Set ZF and NF based on a 64 bit result. This is alas fiddlier * than the 32 bit equivalent. */ @@ -3176,6 +3230,112 @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) unsupported_encoding(s, insn); } +/* C3.6.26 Floating-point data-processing (2 source) - single precision */ +static void handle_fp_2src_single(DisasContext *s, int opcode, + int rd, int rn, int rm) +{ +TCGv_i32 tcg_op1; +TCGv_i32 tcg_op2; +TCGv_i32 tcg_res; +TCGv_ptr fpst; + +tcg_res = tcg_temp_new_i32(); +fpst = get_fpstatus_ptr(); +tcg_op1 = read_fp_sreg(s, rn); +tcg_op2 = read_fp_sreg(s, rm); + +switch (opcode) { +case 0x0: /* FMUL */ +gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x1: /* FDIV */ +gen_helper_vfp_divs(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x2: /* FADD */ +gen_helper_vfp_adds(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x3: /* FSUB */ +gen_helper_vfp_subs(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x4: /* FMAX */ +gen_helper_vfp_maxs(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x5: /* FMIN */ +gen_helper_vfp_mins(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x6: /* FMAXNM */ +gen_helper_vfp_maxnums(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x7: /* FMINNM */ +gen_helper_vfp_minnums(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x8: /* FNMUL */ +gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst); +gen_helper_vfp_negs(tcg_res, tcg_res); +break; +} + +write_fp_sreg(s, rd, tcg_res); + +tcg_temp_free_ptr(fpst); +tcg_temp_free_i32(tcg_op1); +tcg_temp_free_i32(tcg_op2); +tcg_temp_free_i32(tcg_res); +} + +/* C3.6.26 Floating-point data-processing (2 source) - double precision */ +static void handle_fp_2src_double(DisasContext *s, int opcode, + int rd, int rn, int rm) +{ +TCGv_i64 tcg_op1; +TCGv_i64 tcg_op2; +TCGv_i64 tcg_res; +TCGv_ptr fpst; + +tcg_res = tcg_temp_new_i64(); +fpst = get_fpstatus_ptr(); +tcg_op1 = read_fp_dreg(s, rn); +tcg_op2 = read_fp_dreg(s, rm); + +switch (opcode) { +case 0x0: /* FMUL */ +
[Qemu-devel] [PATCH] Makefile: properly install bios-256k.bin
Commit bcf2b7d introduced new 256k seabios files. However, they were not installed. Signed-off-by: Peter Lieven p...@kamp.de --- Makefile |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index bdff4e4..807054b 100644 --- a/Makefile +++ b/Makefile @@ -290,7 +290,7 @@ common de-ch es fo fr-ca hu ja mk nl-be pt sl tr \ bepocz ifdef INSTALL_BLOBS -BLOBS=bios.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \ +BLOBS=bios.bin bios-256k.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \ vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin \ acpi-dsdt.aml q35-acpi-dsdt.aml \ ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc QEMU,tcx.bin \ -- 1.7.9.5
Re: [Qemu-devel] [V5 PATCH 02/22] softfloat: Add float32_to_uint64()
On 2 January 2014 22:21, Tom Musta tommu...@gmail.com wrote: This patch adds the float32_to_uint64() routine, which converts a 32-bit floating point number to an unsigned 64 bit number. This contribution can be licensed under either the softfloat-2a or -2b license. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Peter Maydell peter.mayd...@linaro.org thanks -- PMM
[Qemu-devel] Project idea: make QEMU more flexible
Hi all This idea is to modify QEMU's Makefiles, plus implementing some stubs to make it possible to tailor QEMU to a smaller binary. The current setup for Xen on X86 is to build i386-softmmu, and uses this single binary for two purposes: 1. serves as device emulator for HVM guest. 2. serves as PV driver backend for PV guest. Either case CPU emulation is never used because Xen handles that already. So we are in fact having a load of unused code in QEMU build. What I have in mind is to build a QEMU binary which: 1. does not include CPU emulation code at all. 2. only includes components that's useful (what's useful is TBD). And the rationales behind this idea are: 1. Reduce memory footprint. One usecase would be running Xen on embedded platform (X86 or ARM). We would expect the system has very limited resources. The smaller the binary, the better. 2. It doesn't make sense to have i386 emulation on ARM platform. Arguably nobody can prevent user from running i386 emulator on ARM platform, but it doesn't make sense in Xen's setup where QEMU is only used as PV device backend on ARM. 3. Security concern. It's much easier to audit small code base. Please note that I'm not proposing to invalidate all the other usecases. I'm only speaking with my Xen developer's hat on, aiming to make QEMU more flexible. Down to implementation level I only need to (hopefully) add a few stubs and create some new CONFIG_* options and move a few things around. It might not be as intrusive as one thinks. In fact I've already hacked a prototype during Christmas. What's I've done so far: 1. create target-null which only has some stubs to CPU emulation framework. 2. add a few lines to configure / Makefiles*, create default-configs/null-softmmu Finally I got a qemu-system-null. And the effect is immediately visible -- the size of QEMU binary shrinked from 13MB to 7.6MB. I haven't really looked at what device emulation code can be removed so the size can even be made smaller. What do you think about this idea? Thanks Wei.
[Qemu-devel] [PULL 43/52] char/cadence_uart: Fix can_receive logic
From: Peter Crosthwaite peter.crosthwa...@xilinx.com The can_receive logic was only taking into account the RxFIFO occupancy. RxFIFO population is only used for the echo and normal modes however. Improve the logic to correctly return the true number of receivable characters based on the current mode: Normal mode: RxFIFO vacancy. Remote loopback: TxFIFO vacancy. Echo mode: The min of the TxFIFO and RxFIFO vacancies. Local Loopback: Return non-zero (to implement droppage) Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Message-id: 36a58440c9ca5080151e95765c2c81342de8a8df.1388626249.git.peter.crosthwa...@xilinx.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/char/cadence_uart.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index 3eeadb1..3bcaf29 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -233,8 +233,16 @@ static void uart_parameters_setup(UartState *s) static int uart_can_receive(void *opaque) { UartState *s = (UartState *)opaque; +int ret = MAX(RX_FIFO_SIZE, TX_FIFO_SIZE); +uint32_t ch_mode = s-r[R_MR] UART_MR_CHMODE; -return RX_FIFO_SIZE - s-rx_count; +if (ch_mode == NORMAL_MODE || ch_mode == ECHO_MODE) { +ret = MIN(ret, RX_FIFO_SIZE - s-rx_count); +} +if (ch_mode == REMOTE_LOOPBACK || ch_mode == ECHO_MODE) { +ret = MIN(ret, TX_FIFO_SIZE - s-tx_count); +} +return ret; } static void uart_ctrl_update(UartState *s) -- 1.8.5
[Qemu-devel] [PULL 37/52] char/cadence_uart: Add missing uart_update_state
From: Peter Crosthwaite peter.crosthwa...@xilinx.com This should be rechecked on bus write accesses as such accesses may change the underlying state that generates the interrupt. Particular relevant for when the guest touches the interrupt status or mask. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Message-id: 1c250cd61b7b8de492fbc8b79b8370958a56d83b.1388626249.git.peter.crosthwa...@xilinx.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/char/cadence_uart.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index a7b2f21..fb9db89 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -403,6 +403,7 @@ static void uart_write(void *opaque, hwaddr offset, uart_parameters_setup(s); break; } +uart_update_status(s); } static uint64_t uart_read(void *opaque, hwaddr offset, -- 1.8.5
[Qemu-devel] [PULL 24/52] .travis.yml: Add aarch64-* targets
From: Alex Bennée alex.ben...@linaro.org Now the AArch64 targets are in mainline we can include them in our Travis test matrix. Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 90f1676..c7ff4da 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,7 @@ env: matrix: - TARGETS=alpha-softmmu,alpha-linux-user - TARGETS=arm-softmmu,arm-linux-user + - TARGETS=aarch64-softmmu,aarch64-linux-user - TARGETS=cris-softmmu - TARGETS=i386-softmmu,x86_64-softmmu - TARGETS=lm32-softmmu -- 1.8.5
[Qemu-devel] [PATCH v2 15/24] softfloat: Refactor code handling various rounding modes
Refactor the code in various functions which calculates rounding increments given the current rounding mode, so that instead of a set of nested if statements we have a simple switch statement. This will give us a clean place to add the case for the new tiesAway rounding mode. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- fpu/softfloat.c | 405 +--- 1 file changed, 241 insertions(+), 164 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 78f680f..42cb705 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -42,6 +42,9 @@ these four paragraphs for those parts of this code that are retained. #include fpu/softfloat.h +/* We only need stdlib for abort() */ +#include stdlib.h + /* | Primitive arithmetic functions, including multi-word arithmetic, and | division and square root approximations. (Can be specialized to target if @@ -106,20 +109,21 @@ static int32 roundAndPackInt32( flag zSign, uint64_t absZ STATUS_PARAM) roundingMode = STATUS(float_rounding_mode); roundNearestEven = ( roundingMode == float_round_nearest_even ); -roundIncrement = 0x40; -if ( ! roundNearestEven ) { -if ( roundingMode == float_round_to_zero ) { -roundIncrement = 0; -} -else { -roundIncrement = 0x7F; -if ( zSign ) { -if ( roundingMode == float_round_up ) roundIncrement = 0; -} -else { -if ( roundingMode == float_round_down ) roundIncrement = 0; -} -} +switch (roundingMode) { +case float_round_nearest_even: +roundIncrement = 0x40; +break; +case float_round_to_zero: +roundIncrement = 0; +break; +case float_round_up: +roundIncrement = zSign ? 0 : 0x7f; +break; +case float_round_down: +roundIncrement = zSign ? 0x7f : 0; +break; +default: +abort(); } roundBits = absZ 0x7F; absZ = ( absZ + roundIncrement )7; @@ -155,19 +159,21 @@ static int64 roundAndPackInt64( flag zSign, uint64_t absZ0, uint64_t absZ1 STATU roundingMode = STATUS(float_rounding_mode); roundNearestEven = ( roundingMode == float_round_nearest_even ); -increment = ( (int64_t) absZ1 0 ); -if ( ! roundNearestEven ) { -if ( roundingMode == float_round_to_zero ) { -increment = 0; -} -else { -if ( zSign ) { -increment = ( roundingMode == float_round_down ) absZ1; -} -else { -increment = ( roundingMode == float_round_up ) absZ1; -} -} +switch (roundingMode) { +case float_round_nearest_even: +increment = ((int64_t) absZ1 0); +break; +case float_round_to_zero: +increment = 0; +break; +case float_round_up: +increment = !zSign absZ1; +break; +case float_round_down: +increment = zSign absZ1; +break; +default: +abort(); } if ( increment ) { ++absZ0; @@ -206,17 +212,21 @@ static int64 roundAndPackUint64(flag zSign, uint64_t absZ0, roundingMode = STATUS(float_rounding_mode); roundNearestEven = (roundingMode == float_round_nearest_even); -increment = ((int64_t)absZ1 0); -if (!roundNearestEven) { -if (roundingMode == float_round_to_zero) { -increment = 0; -} else if (absZ1) { -if (zSign) { -increment = (roundingMode == float_round_down) absZ1; -} else { -increment = (roundingMode == float_round_up) absZ1; -} -} +switch (roundingMode) { +case float_round_nearest_even: +increment = ((int64_t)absZ1 0); +break; +case float_round_to_zero: +increment = 0; +break; +case float_round_up: +increment = !zSign absZ1; +break; +case float_round_down: +increment = zSign absZ1; +break; +default: +abort(); } if (increment) { ++absZ0; @@ -354,20 +364,22 @@ static float32 roundAndPackFloat32(flag zSign, int_fast16_t zExp, uint32_t zSig roundingMode = STATUS(float_rounding_mode); roundNearestEven = ( roundingMode == float_round_nearest_even ); -roundIncrement = 0x40; -if ( ! roundNearestEven ) { -if ( roundingMode == float_round_to_zero ) { -roundIncrement = 0; -} -else { -roundIncrement = 0x7F; -if ( zSign ) { -if ( roundingMode == float_round_up ) roundIncrement = 0; -} -else { -if ( roundingMode == float_round_down ) roundIncrement = 0; -} -} +switch (roundingMode) { +case float_round_nearest_even: +
Re: [Qemu-devel] [PATCH] Makefile: properly install bios-256k.bin
On 6 January 2014 12:54, Peter Lieven p...@kamp.de wrote: Commit bcf2b7d introduced new 256k seabios files. However, they were not installed. This is a dup of this patch by Eduardo from last month: http://patchwork.ozlabs.org/patch/299233/ thanks -- PMM
Re: [Qemu-devel] [PATCH] Add bios-256k.bin to BLOBS on Makefile
Ping -- who's going to take this patch? Maybe it should go via -trivial? thanks -- PMM On 9 December 2013 23:33, Eduardo Habkost ehabk...@redhat.com wrote: The default machine-type (pc-i440fx-2.0) now requires bios-256k.bin, but make install isn't installing it, so qemu-system-x86_64 won't run out of the box. Add it to BLOBS so it gets installed. Signed-off-by: Eduardo Habkost ehabk...@redhat.com --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index bdff4e4..807054b 100644 --- a/Makefile +++ b/Makefile @@ -290,7 +290,7 @@ common de-ch es fo fr-ca hu ja mk nl-be pt sl tr \ bepocz ifdef INSTALL_BLOBS -BLOBS=bios.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \ +BLOBS=bios.bin bios-256k.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \ vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin \ acpi-dsdt.aml q35-acpi-dsdt.aml \ ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc QEMU,tcx.bin \ -- 1.8.3.1
Re: [Qemu-devel] [PATCH] docs: qcow2 compat=1.1 is now the default
On 01/05/2014 09:39 PM, Stefan Hajnoczi wrote: Commit 9117b47717ad208b12786ce88eacb013f9b3dd1c (qcow2: Change default for new images to compat=1.1) changed the default qcow2 image format version but forgot to update qemu-doc.texi and qemu-img.texi. Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- qemu-doc.texi | 8 qemu-img.texi | 8 2 files changed, 8 insertions(+), 8 deletions(-) Reviewed-by: Eric Blake ebl...@redhat.com -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH] Makefile: properly install bios-256k.bin
On 6 January 2014 13:17, Peter Lieven p...@kamp.de wrote: On 06.01.2014 14:12, Peter Maydell wrote: On 6 January 2014 12:54, Peter Lieven p...@kamp.de wrote: Commit bcf2b7d introduced new 256k seabios files. However, they were not installed. This is a dup of this patch by Eduardo from last month: http://patchwork.ozlabs.org/patch/299233/ Thanks for the pointer. However, this patch is not in master atm. Yes, that's why I quoted a patchwork URL rather than a commit hash :-) In general, the first of several identical patches for a fix is the one that should be committed, and there's not much point in sending in duplicates (especially when the first patch already has review tags.) thanks -- PMM
Re: [Qemu-devel] [PATCH] Makefile: properly install bios-256k.bin
On 06.01.2014 14:17, Peter Maydell wrote: On 6 January 2014 13:17, Peter Lieven p...@kamp.de wrote: On 06.01.2014 14:12, Peter Maydell wrote: On 6 January 2014 12:54, Peter Lieven p...@kamp.de wrote: Commit bcf2b7d introduced new 256k seabios files. However, they were not installed. This is a dup of this patch by Eduardo from last month: http://patchwork.ozlabs.org/patch/299233/ Thanks for the pointer. However, this patch is not in master atm. Yes, that's why I quoted a patchwork URL rather than a commit hash :-) In general, the first of several identical patches for a fix is the one that should be committed, and there's not much point in sending in duplicates (especially when the first patch already has review tags.) thats clear. I did not want to have credit for this I have just not realized that there is already a patch. Peter
Re: [Qemu-devel] [PATCH] acpi unit-test: resolved iasl crash
On Mon, 2014-01-06 at 13:43 +0200, Michael S. Tsirkin wrote: On Sun, Dec 29, 2013 at 02:32:50PM +0200, Marcel Apfelbaum wrote: It seems that iasl has an issue when disassembles some ACPI tables using the command line: iasl -e DSDT -e SSDT -d HPET I opened a bug on iasl project: https://github.com/acpica/acpica/issues/20 Modified the iasl command line to iasl -d HPET until the problem is solved. The command line remained the same for DSDT and SSDT tables. Reported-by:Michael S. Tsirkin m...@redhat.com space needed after : Sure, missed that Signed-off-by: Marcel Apfelbaum marce...@redhat.com --- tests/acpi-test.c | 16 +--- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/acpi-test.c b/tests/acpi-test.c index 2d32b69..26d2e26 100644 --- a/tests/acpi-test.c +++ b/tests/acpi-test.c @@ -403,7 +403,7 @@ static void dump_aml_files(test_data *data, bool rebuild) } } -static void load_asl(GArray *sdts, AcpiSdtTable *sdt) +static void load_asl(GArray *sdts, AcpiSdtTable *sdt, bool referenceDsdt) { AcpiSdtTable *temp; GError *error = NULL; @@ -419,9 +419,11 @@ static void load_asl(GArray *sdts, AcpiSdtTable *sdt) /* build command line */ g_string_append_printf(command_line, -p %s , sdt-asl_file); -for (i = 0; i 2; ++i) { /* reference DSDT and SSDT */ -temp = g_array_index(sdts, AcpiSdtTable, i); -g_string_append_printf(command_line, -e %s , temp-aml_file); +if (referenceDsdt) { +for (i = 0; i 2; ++i) { /* reference DSDT and SSDT */ +temp = g_array_index(sdts, AcpiSdtTable, i); +g_string_append_printf(command_line, -e %s , temp-aml_file); +} } g_string_append_printf(command_line, -d %s, sdt-aml_file); @@ -510,14 +512,14 @@ static void test_acpi_asl(test_data *data) dump_aml_files(data, false); for (i = 0; i data-ssdt_tables-len; ++i) { GString *asl, *exp_asl; - +bool referenceDsdt = (i 2); /* only for DSDT and SSDT */ Please don't use camelCase for variables. Sure, no idea why I did that in the first place... Can we check the table signature instead of looking at the index? It is possible, but not really necessary because: 1. The array of expected tables it is created as a shadow of the original tables. (We load the expected tables in the exact order as the originals) 2. The loading is done based on table signatures. So going over the index in *this* case it means going over the signatures. Thanks for the review, Marcel sdt = g_array_index(data-ssdt_tables, AcpiSdtTable, i); exp_sdt = g_array_index(exp_data.ssdt_tables, AcpiSdtTable, i); -load_asl(data-ssdt_tables, sdt); +load_asl(data-ssdt_tables, sdt, referenceDsdt); asl = normalize_asl(sdt-asl); -load_asl(exp_data.ssdt_tables, exp_sdt); +load_asl(exp_data.ssdt_tables, exp_sdt, referenceDsdt); exp_asl = normalize_asl(exp_sdt-asl); g_assert(!g_strcmp0(asl-str, exp_asl-str)); -- 1.8.3.1
Re: [Qemu-devel] Project idea: make QEMU more flexible
On Mon, Jan 6, 2014 at 10:54 PM, Wei Liu wei.l...@citrix.com wrote: Hi all This idea is to modify QEMU's Makefiles, plus implementing some stubs to make it possible to tailor QEMU to a smaller binary. The current setup for Xen on X86 is to build i386-softmmu, and uses this single binary for two purposes: 1. serves as device emulator for HVM guest. 2. serves as PV driver backend for PV guest. Either case CPU emulation is never used because Xen handles that already. So we are in fact having a load of unused code in QEMU build. What I have in mind is to build a QEMU binary which: 1. does not include CPU emulation code at all. 2. only includes components that's useful (what's useful is TBD). And the rationales behind this idea are: 1. Reduce memory footprint. One usecase would be running Xen on embedded platform (X86 or ARM). We would expect the system has very limited resources. The smaller the binary, the better. 2. It doesn't make sense to have i386 emulation on ARM platform. Arguably nobody can prevent user from running i386 emulator on ARM platform, but it doesn't make sense in Xen's setup where QEMU is only used as PV device backend on ARM. 3. Security concern. It's much easier to audit small code base. Please note that I'm not proposing to invalidate all the other usecases. I'm only speaking with my Xen developer's hat on, aiming to make QEMU more flexible. Down to implementation level I only need to (hopefully) add a few stubs and create some new CONFIG_* options and move a few things around. It might not be as intrusive as one thinks. In fact I've already hacked a prototype during Christmas. What's I've done so far: 1. create target-null which only has some stubs to CPU emulation framework. 2. add a few lines to configure / Makefiles*, create default-configs/null-softmmu Your idea of aggressively reducing binary size may not really fit a defconfig at all. If you are going lean-and-mean based on a specific use-case I think you need to bring your own config. Finally I got a qemu-system-null. And the effect is immediately visible qemu-system-null has been on my wish-list in the past, although my reasons were slightly different to yours. Specifically, the goal was to test CPUs in an RTL simulator interacting with RAM and peripheral devices hosted in QEMU. -- the size of QEMU binary shrinked from 13MB to 7.6MB. I haven't really looked at what device emulation code can be removed so the size can even be made smaller. So what exactly is an appropriate device-suite for qemu-system-null is an open question. I would suggest that the correct default config for such a QEMU would actually be the full suite of devices, not less that whats already in i386. Free of CPU/arch restrictions, all devices are fair game. Regards, Peter What do you think about this idea? Thanks Wei.
Re: [Qemu-devel] [Xen-devel] Project idea: make QEMU more flexible
On Mon, 2014-01-06 at 12:54 +, Wei Liu wrote: Hi all This idea is to modify QEMU's Makefiles, plus implementing some stubs to make it possible to tailor QEMU to a smaller binary. The current setup for Xen on X86 is to build i386-softmmu, and uses this single binary for two purposes: 1. serves as device emulator for HVM guest. 2. serves as PV driver backend for PV guest. Perhaps even KVM would benefit too. Are you sure we don't emulate any instruction for other purposes? Either case CPU emulation is never used because Xen handles that already. So we are in fact having a load of unused code in QEMU build. What I have in mind is to build a QEMU binary which: 1. does not include CPU emulation code at all. 2. only includes components that's useful (what's useful is TBD). And the rationales behind this idea are: 1. Reduce memory footprint. One usecase would be running Xen on embedded platform (X86 or ARM). We would expect the system has very limited resources. The smaller the binary, the better. 2. It doesn't make sense to have i386 emulation on ARM platform. Arguably nobody can prevent user from running i386 emulator on ARM platform, but it doesn't make sense in Xen's setup where QEMU is only used as PV device backend on ARM. 3. Security concern. It's much easier to audit small code base. Please note that I'm not proposing to invalidate all the other usecases. I'm only speaking with my Xen developer's hat on, aiming to make QEMU more flexible. Down to implementation level I only need to (hopefully) add a few stubs and create some new CONFIG_* options and move a few things around. It might not be as intrusive as one thinks. In fact I've already hacked a prototype during Christmas. What's I've done so far: 1. create target-null which only has some stubs to CPU emulation framework. 2. add a few lines to configure / Makefiles*, create default-configs/null-softmmu Finally I got a qemu-system-null. And the effect is immediately visible -- the size of QEMU binary shrinked from 13MB to 7.6MB. I haven't really looked at what device emulation code can be removed so the size can even be made smaller. Well, I would prefer something like a i386-nocpu. The system qemu emulate is still specific to a given architecture. You can't emulate ARM with the same executable. So we'd add default-configs/arm-nocpu.mak and default-config/x86_64-nocpu.mak (i386 don't make much sense anymore). What do you think about this idea? Thanks Wei. Frediano
[Qemu-devel] [PULL 07/52] target-arm: A64: add support for 3 src data proc insns
From: Alexander Graf ag...@suse.de This patch adds emulation for the Data-processing (3 source) family of instructions, namely MADD, MSUB, SMADDL, SMSUBL, SMULH, UMADDL, UMSUBL, UMULH. Signed-off-by: Alexander Graf ag...@suse.de Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 97 +- 1 file changed, 95 insertions(+), 2 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index dbc865a..3a9ffdf 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -2128,10 +2128,103 @@ static void disas_add_sub_reg(DisasContext *s, uint32_t insn) tcg_temp_free_i64(tcg_result); } -/* Data-processing (3 source) */ +/* C3.5.9 Data-processing (3 source) + + 31 30 29 28 24 23 21 20 16 15 14 10 95 40 + +--+--+---+--+--++--+--+--+ + |sf| op54 | 1 1 0 1 1 | op31 | Rm | o0 | Ra | Rn | Rd | + +--+--+---+--+--++--+--+--+ + + */ static void disas_data_proc_3src(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int rd = extract32(insn, 0, 5); +int rn = extract32(insn, 5, 5); +int ra = extract32(insn, 10, 5); +int rm = extract32(insn, 16, 5); +int op_id = (extract32(insn, 29, 3) 4) | +(extract32(insn, 21, 3) 1) | +extract32(insn, 15, 1); +bool sf = extract32(insn, 31, 1); +bool is_sub = extract32(op_id, 0, 1); +bool is_high = extract32(op_id, 2, 1); +bool is_signed = false; +TCGv_i64 tcg_op1; +TCGv_i64 tcg_op2; +TCGv_i64 tcg_tmp; + +/* Note that op_id is sf:op54:op31:o0 so it includes the 32/64 size flag */ +switch (op_id) { +case 0x42: /* SMADDL */ +case 0x43: /* SMSUBL */ +case 0x44: /* SMULH */ +is_signed = true; +break; +case 0x0: /* MADD (32bit) */ +case 0x1: /* MSUB (32bit) */ +case 0x40: /* MADD (64bit) */ +case 0x41: /* MSUB (64bit) */ +case 0x4a: /* UMADDL */ +case 0x4b: /* UMSUBL */ +case 0x4c: /* UMULH */ +break; +default: +unallocated_encoding(s); +return; +} + +if (is_high) { +TCGv_i64 low_bits = tcg_temp_new_i64(); /* low bits discarded */ +TCGv_i64 tcg_rd = cpu_reg(s, rd); +TCGv_i64 tcg_rn = cpu_reg(s, rn); +TCGv_i64 tcg_rm = cpu_reg(s, rm); + +if (is_signed) { +tcg_gen_muls2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm); +} else { +tcg_gen_mulu2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm); +} + +tcg_temp_free_i64(low_bits); +return; +} + +tcg_op1 = tcg_temp_new_i64(); +tcg_op2 = tcg_temp_new_i64(); +tcg_tmp = tcg_temp_new_i64(); + +if (op_id 0x42) { +tcg_gen_mov_i64(tcg_op1, cpu_reg(s, rn)); +tcg_gen_mov_i64(tcg_op2, cpu_reg(s, rm)); +} else { +if (is_signed) { +tcg_gen_ext32s_i64(tcg_op1, cpu_reg(s, rn)); +tcg_gen_ext32s_i64(tcg_op2, cpu_reg(s, rm)); +} else { +tcg_gen_ext32u_i64(tcg_op1, cpu_reg(s, rn)); +tcg_gen_ext32u_i64(tcg_op2, cpu_reg(s, rm)); +} +} + +if (ra == 31 !is_sub) { +/* Special-case MADD with rA == XZR; it is the standard MUL alias */ +tcg_gen_mul_i64(cpu_reg(s, rd), tcg_op1, tcg_op2); +} else { +tcg_gen_mul_i64(tcg_tmp, tcg_op1, tcg_op2); +if (is_sub) { +tcg_gen_sub_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp); +} else { +tcg_gen_add_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp); +} +} + +if (!sf) { +tcg_gen_ext32u_i64(cpu_reg(s, rd), cpu_reg(s, rd)); +} + +tcg_temp_free_i64(tcg_op1); +tcg_temp_free_i64(tcg_op2); +tcg_temp_free_i64(tcg_tmp); } /* Add/subtract (with carry) */ -- 1.8.5
[Qemu-devel] [PATCH v2 22/24] target-arm: A64: Add floating-point-integer conversion instructions
From: Will Newton will.new...@linaro.org Add support for the AArch64 floating-point - integer conversion instructions to disas_fpintconv. In the process we can rearrange and simplify the detection of unallocated encodings a little. We also correct a typo in the instruction encoding diagram for this instruction group: bit 21 is 1, not 0. Signed-off-by: Will Newton will.new...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/translate-a64.c | 23 --- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index ec8abc7..9b23d37 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -3904,7 +3904,7 @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof) /* C3.6.30 Floating point - integer conversions * 31 30 29 28 24 23 22 21 20 19 18 16 15 10 9 5 4 0 * ++---+---+---+--+---+---+-+-+++ - * | sf | 0 | S | 1 1 1 1 0 | type | 0 | rmode | opc | 0 0 0 0 0 0 | Rn | Rd | + * | sf | 0 | S | 1 1 1 1 0 | type | 1 | rmode | opc | 0 0 0 0 0 0 | Rn | Rd | * ++---+---+---+--+---+---+-+-+++ */ static void disas_fp_int_conv(DisasContext *s, uint32_t insn) @@ -3917,10 +3917,20 @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn) bool sbit = extract32(insn, 29, 1); bool sf = extract32(insn, 31, 1); -if (!sbit (rmode 2) (opcode 5)) { +if (sbit) { +unallocated_encoding(s); +return; +} + +if (opcode 5) { /* FMOV */ bool itof = opcode 1; +if (rmode = 2) { +unallocated_encoding(s); +return; +} + switch (sf 3 | type 1 | rmode) { case 0x0: /* 32 bit */ case 0xa: /* 64 bit */ @@ -3935,7 +3945,14 @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn) handle_fmov(s, rd, rn, type, itof); } else { /* actual FP conversions */ -unsupported_encoding(s, insn); +bool itof = extract32(opcode, 1, 1); + +if (type 1 || (rmode != 0 opcode 1)) { +unallocated_encoding(s); +return; +} + +handle_fpfpcvt(s, rd, rn, opcode, itof, rmode, 64, sf, type); } } -- 1.8.5
[Qemu-devel] [PATCH v2 23/24] target-arm: A64: Add 1-source 32-to-32 and 64-to-64 FP instructions
This patch adds support for those instructions in the Floating-point data-processing (1 source) group which are simple 32-bit-to-32-bit or 64-bit-to-64-bit operations (ie everything except FCVT between single/double/half precision). We put the new round-to-int helpers in helper.c because they will also be used by the new ARMv8 A32/T32 rounding instructions. Signed-off-by: Alexander Graf ag...@suse.de [WN: Commit message tweak, merged single and double precision patches, updated to new infrastructure.] Signed-off-by: Will Newton will.new...@linaro.org [PMM: reworked decode, split FCVT out into their own patch] Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/helper.c| 45 ++ target-arm/helper.h| 5 ++ target-arm/translate-a64.c | 142 - 3 files changed, 191 insertions(+), 1 deletion(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index b832908..a0c1646 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -4353,3 +4353,48 @@ float64 VFP_HELPER(muladd, d)(float64 a, float64 b, float64 c, void *fpstp) float_status *fpst = fpstp; return float64_muladd(a, b, c, 0, fpst); } + +/* ARMv8 round to integral */ +float32 HELPER(rints_exact)(float32 x, void *fp_status) +{ +return float32_round_to_int(x, fp_status); +} + +float64 HELPER(rintd_exact)(float64 x, void *fp_status) +{ +return float64_round_to_int(x, fp_status); +} + +float32 HELPER(rints)(float32 x, void *fp_status) +{ +int old_flags = get_float_exception_flags(fp_status), new_flags; +float32 ret; + +ret = float32_round_to_int(x, fp_status); + +/* Suppress any inexact exceptions the conversion produced */ +if (!(old_flags float_flag_inexact)) { +new_flags = get_float_exception_flags(fp_status); +set_float_exception_flags(new_flags ~float_flag_inexact, fp_status); +} + +return ret; +} + +float64 HELPER(rintd)(float64 x, void *fp_status) +{ +int old_flags = get_float_exception_flags(fp_status), new_flags; +float64 ret; + +ret = float64_round_to_int(x, fp_status); + +new_flags = get_float_exception_flags(fp_status); + +/* Suppress any inexact exceptions the conversion produced */ +if (!(old_flags float_flag_inexact)) { +new_flags = get_float_exception_flags(fp_status); +set_float_exception_flags(new_flags ~float_flag_inexact, fp_status); +} + +return ret; +} diff --git a/target-arm/helper.h b/target-arm/helper.h index 25b6b4f..832ec12 100644 --- a/target-arm/helper.h +++ b/target-arm/helper.h @@ -171,6 +171,11 @@ DEF_HELPER_3(shr_cc, i32, env, i32, i32) DEF_HELPER_3(sar_cc, i32, env, i32, i32) DEF_HELPER_3(ror_cc, i32, env, i32, i32) +DEF_HELPER_FLAGS_2(rints_exact, TCG_CALL_NO_RWG_SE, f32, f32, ptr) +DEF_HELPER_FLAGS_2(rintd_exact, TCG_CALL_NO_RWG_SE, f64, f64, ptr) +DEF_HELPER_FLAGS_2(rints, TCG_CALL_NO_RWG_SE, f32, f32, ptr) +DEF_HELPER_FLAGS_2(rintd, TCG_CALL_NO_RWG_SE, f64, f64, ptr) + /* neon_helper.c */ DEF_HELPER_3(neon_qadd_u8, i32, env, i32, i32) DEF_HELPER_3(neon_qadd_s8, i32, env, i32, i32) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 9b23d37..345a47b 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -3386,6 +3386,118 @@ static void disas_fp_csel(DisasContext *s, uint32_t insn) } } +/* C3.6.25 Floating-point data-processing (1 source) - single precision */ +static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) +{ +TCGv_ptr fpst; +TCGv_i32 tcg_op; +TCGv_i32 tcg_res; + +fpst = get_fpstatus_ptr(); +tcg_op = read_fp_sreg(s, rn); +tcg_res = tcg_temp_new_i32(); + +switch (opcode) { +case 0x0: /* FMOV */ +tcg_gen_mov_i32(tcg_res, tcg_op); +break; +case 0x1: /* FABS */ +gen_helper_vfp_abss(tcg_res, tcg_op); +break; +case 0x2: /* FNEG */ +gen_helper_vfp_negs(tcg_res, tcg_op); +break; +case 0x3: /* FSQRT */ +gen_helper_vfp_sqrts(tcg_res, tcg_op, cpu_env); +break; +case 0x8: /* FRINTN */ +case 0x9: /* FRINTP */ +case 0xa: /* FRINTM */ +case 0xb: /* FRINTZ */ +case 0xc: /* FRINTA */ +{ +TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode 7)); + +gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); +gen_helper_rints(tcg_res, tcg_op, fpst); + +gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); +tcg_temp_free_i32(tcg_rmode); +break; +} +case 0xe: /* FRINTX */ +gen_helper_rints_exact(tcg_res, tcg_op, fpst); +break; +case 0xf: /* FRINTI */ +gen_helper_rints(tcg_res, tcg_op, fpst); +break; +default: +abort(); +} + +write_fp_sreg(s, rd, tcg_res); + +tcg_temp_free_ptr(fpst); +tcg_temp_free_i32(tcg_op); +tcg_temp_free_i32(tcg_res); +} + +/* C3.6.25 Floating-point data-processing (1
[Qemu-devel] [PULL 23/52] linux-user: AArch64: Use correct values for FPSR/FPCR in sigcontext
From: Will Newton will.new...@linaro.org Use the helpers provided for getting the correct FPSR and FPCR values for the signal context. Signed-off-by: Will Newton will.new...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- linux-user/signal.c | 10 +++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/linux-user/signal.c b/linux-user/signal.c index 4e7148a..6c74b18 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -1189,8 +1189,8 @@ static int target_setup_sigframe(struct target_rt_sigframe *sf, __put_user(env-vfp.regs[i * 2 + 1], aux-fpsimd.vregs[i * 2 + 1]); #endif } -__put_user(/*env-fpsr*/0, aux-fpsimd.fpsr); -__put_user(/*env-fpcr*/0, aux-fpsimd.fpcr); +__put_user(vfp_get_fpsr(env), aux-fpsimd.fpsr); +__put_user(vfp_get_fpcr(env), aux-fpsimd.fpcr); __put_user(TARGET_FPSIMD_MAGIC, aux-fpsimd.head.magic); __put_user(sizeof(struct target_fpsimd_context), aux-fpsimd.head.size); @@ -1209,7 +1209,7 @@ static int target_restore_sigframe(CPUARMState *env, int i; struct target_aux_context *aux = (struct target_aux_context *)sf-uc.tuc_mcontext.__reserved; -uint32_t magic, size; +uint32_t magic, size, fpsr, fpcr; uint64_t pstate; target_to_host_sigset(set, sf-uc.tuc_sigmask); @@ -1235,6 +1235,10 @@ static int target_restore_sigframe(CPUARMState *env, for (i = 0; i 32 * 2; i++) { __get_user(env-vfp.regs[i], aux-fpsimd.vregs[i]); } +__get_user(fpsr, aux-fpsimd.fpsr); +vfp_set_fpsr(env, fpsr); +__get_user(fpcr, aux-fpsimd.fpcr); +vfp_set_fpcr(env, fpcr); return 0; } -- 1.8.5
[Qemu-devel] [PATCH v2 21/24] target-arm: A64: Add Floating-point-fixed-point instructions
From: Alexander Graf ag...@suse.de This patch adds emulation for the instruction group labeled Floating-point - fixed-point conversions in the ARM ARM. Namely this includes the instructions SCVTF, UCVTF, FCVTZS, FCVTZU (scalar, fixed-point). Signed-off-by: Alexander Graf ag...@suse.de [WN: Commit message tweak, rebased, updated to new infrastructure. Applied bug fixes from Michael Matz and Janne Grunau.] Signed-off-by: Will Newton will.new...@linaro.org [PMM: significant cleanup] Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/helper.c| 13 target-arm/helper.h| 2 + target-arm/translate-a64.c | 186 - 3 files changed, 200 insertions(+), 1 deletion(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index 677db3f..b832908 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -4035,6 +4035,19 @@ VFP_CONV_FIX_A64(uq, s, 32, 64, uint64) #undef VFP_CONV_FIX_FLOAT #undef VFP_CONV_FLOAT_FIX_ROUND +/* Set the current fp rounding mode and return the old one. + * The argument is a softfloat float_round_ value. + */ +uint32_t HELPER(set_rmode)(uint32_t rmode, CPUARMState *env) +{ +float_status *fp_status = env-vfp.fp_status; + +uint32_t prev_rmode = get_float_rounding_mode(fp_status); +set_float_rounding_mode(rmode, fp_status); + +return prev_rmode; +} + /* Half precision conversions. */ static float32 do_fcvt_f16_to_f32(uint32_t a, CPUARMState *env, float_status *s) { diff --git a/target-arm/helper.h b/target-arm/helper.h index 2e1af46..25b6b4f 100644 --- a/target-arm/helper.h +++ b/target-arm/helper.h @@ -148,6 +148,8 @@ DEF_HELPER_3(vfp_uhtod, f64, i64, i32, ptr) DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr) DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr) +DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, env) + DEF_HELPER_2(vfp_fcvt_f16_to_f32, f32, i32, env) DEF_HELPER_2(vfp_fcvt_f32_to_f16, i32, f32, env) DEF_HELPER_2(neon_fcvt_f16_to_f32, f32, i32, env) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index c9fbf0f..ec8abc7 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -3186,6 +3186,34 @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) } } +/* Convert ARM rounding mode to softfloat */ +static inline int arm_rmode_to_sf(int rmode) +{ +switch (rmode) { +case FPROUNDING_TIEAWAY: +rmode = float_round_ties_away; +break; +case FPROUNDING_ODD: +/* FIXME: add support for TIEAWAY and ODD */ +qemu_log_mask(LOG_UNIMP, arm: unimplemented rounding mode: %d\n, + rmode); +case FPROUNDING_TIEEVEN: +default: +rmode = float_round_nearest_even; +break; +case FPROUNDING_POSINF: +rmode = float_round_up; +break; +case FPROUNDING_NEGINF: +rmode = float_round_down; +break; +case FPROUNDING_ZERO: +rmode = float_round_to_zero; +break; +} +return rmode; +} + static void handle_fp_compare(DisasContext *s, bool is_double, unsigned int rn, unsigned int rm, bool cmp_with_zero, bool signal_all_nans) @@ -3651,6 +3679,132 @@ static void disas_fp_imm(DisasContext *s, uint32_t insn) tcg_temp_free_i64(tcg_res); } +/* Handle floating point = fixed point conversions. Note that we can + * also deal with fp = integer conversions as a special case (scale == 64) + * OPTME: consider handling that special case specially or at least skipping + * the call to scalbn in the helpers for zero shifts. + */ +static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode, + bool itof, int rmode, int scale, int sf, int type) +{ +bool is_signed = !(opcode 1); +bool is_double = type; +TCGv_ptr tcg_fpstatus; +TCGv_i32 tcg_shift; + +tcg_fpstatus = get_fpstatus_ptr(); + +tcg_shift = tcg_const_i32(64 - scale); + +if (itof) { +TCGv_i64 tcg_int = cpu_reg(s, rn); +if (!sf) { +TCGv_i64 tcg_extend = new_tmp_a64(s); + +if (is_signed) { +tcg_gen_ext32s_i64(tcg_extend, tcg_int); +} else { +tcg_gen_ext32u_i64(tcg_extend, tcg_int); +} + +tcg_int = tcg_extend; +} + +if (is_double) { +TCGv_i64 tcg_double = tcg_temp_new_i64(); +if (is_signed) { +gen_helper_vfp_sqtod(tcg_double, tcg_int, + tcg_shift, tcg_fpstatus); +} else { +gen_helper_vfp_uqtod(tcg_double, tcg_int, + tcg_shift, tcg_fpstatus); +} +write_fp_dreg(s, rd, tcg_double); +tcg_temp_free_i64(tcg_double); +} else { +TCGv_i32 tcg_single = tcg_temp_new_i32(); +if (is_signed) { +
[Qemu-devel] [PATCH v2 03/24] softfloat: Add 16 bit integer to float conversions
Add the float to 16 bit integer conversion routines. These can be trivially implemented in terms of the int32_to_float* routines, but providing them makes our API more symmetrical and can simplify callers. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- include/fpu/softfloat.h | 21 + 1 file changed, 21 insertions(+) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index a9b8cd9..926d849 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -239,6 +239,27 @@ floatx80 int64_to_floatx80( int64 STATUS_PARAM ); float128 int64_to_float128( int64 STATUS_PARAM ); float128 uint64_to_float128( uint64 STATUS_PARAM ); +/* We provide the int16 versions for symmetry of API with float-to-int */ +INLINE float32 int16_to_float32(int16_t v STATUS_PARAM) +{ +return int32_to_float32(v STATUS_VAR); +} + +INLINE float32 uint16_to_float32(uint16_t v STATUS_PARAM) +{ +return uint32_to_float32(v STATUS_VAR); +} + +INLINE float64 int16_to_float64(int16_t v STATUS_PARAM) +{ +return int32_to_float64(v STATUS_VAR); +} + +INLINE float64 uint16_to_float64(uint16_t v STATUS_PARAM) +{ +return uint32_to_float64(v STATUS_VAR); +} + /* | Software half-precision conversion routines. **/ -- 1.8.5
[Qemu-devel] [PULL 02/52] target-arm: A64: add support for ld/st unsigned imm
From: Alex Bennée alex.ben...@linaro.org This adds support for the forms of ld/st with a 12 bit unsigned immediate offset. Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 89 +- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 0c3b994..0edcee1 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -901,10 +901,97 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn) } } +/* + * C3.3.13 Load/store (unsigned immediate) + * + * 31 30 29 27 26 25 24 23 22 2110 9 5 + * ++---+---+-+-++---+--+ + * |size| 1 1 1 | V | 0 1 | opc | imm12| Rn | Rt | + * ++---+---+-+-++---+--+ + * + * For non-vector: + * size: 00- byte, 01 - 16 bit, 10 - 32bit, 11 - 64bit + * opc: 00 - store, 01 - loadu, 10 - loads 64, 11 - loads 32 + * For vector: + * size is opc1:size1:0 so 100 - 128 bit; 110 and 111 unallocated + * opc0: 0 - store, 1 - load + * Rn: base address register (inc SP) + * Rt: target register + */ +static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn) +{ +int rt = extract32(insn, 0, 5); +int rn = extract32(insn, 5, 5); +unsigned int imm12 = extract32(insn, 10, 12); +bool is_vector = extract32(insn, 26, 1); +int size = extract32(insn, 30, 2); +int opc = extract32(insn, 22, 2); +unsigned int offset; + +TCGv_i64 tcg_addr; + +bool is_store; +bool is_signed = false; +bool is_extended = false; + +if (is_vector) { +size |= (opc 2) 1; +if (size 4) { +unallocated_encoding(s); +return; +} +is_store = !extract32(opc, 0, 1); +} else { +if (size == 3 opc == 2) { +/* PRFM - prefetch */ +return; +} +if (opc == 3 size 1) { +unallocated_encoding(s); +return; +} +is_store = (opc == 0); +is_signed = extract32(opc, 1, 1); +is_extended = (size 3) extract32(opc, 0, 1); +} + +if (rn == 31) { +gen_check_sp_alignment(s); +} +tcg_addr = read_cpu_reg_sp(s, rn, 1); +offset = imm12 size; +tcg_gen_addi_i64(tcg_addr, tcg_addr, offset); + +if (is_vector) { +if (is_store) { +do_fp_st(s, rt, tcg_addr, size); +} else { +do_fp_ld(s, rt, tcg_addr, size); +} +} else { +TCGv_i64 tcg_rt = cpu_reg(s, rt); +if (is_store) { +do_gpr_st(s, tcg_rt, tcg_addr, size); +} else { +do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended); +} +} +} + /* Load/store register (all forms) */ static void disas_ldst_reg(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +switch (extract32(insn, 24, 2)) { +case 0: +unsupported_encoding(s, insn); +break; +case 1: +disas_ldst_reg_unsigned_imm(s, insn); +break; +default: +unallocated_encoding(s); +break; +} } /* AdvSIMD load/store multiple structures */ -- 1.8.5
[Qemu-devel] [PATCH v2 20/24] target-arm: A64: Add extra VFP fixed point conversion helpers
From: Will Newton will.new...@linaro.org Define the full set of floating point to fixed point conversion helpers required to support AArch64. Signed-off-by: Will Newton will.new...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/helper.c | 11 ++- target-arm/helper.h | 16 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index 00476a8..677db3f 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -4012,16 +4012,25 @@ uint##isz##_t HELPER(vfp_to##name##p##round)(float##fsz x, \ #define VFP_CONV_FIX(name, p, fsz, isz, itype) \ VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \ -VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, _round_to_zero) +VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, _round_to_zero) \ +VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, ) + +#define VFP_CONV_FIX_A64(name, p, fsz, isz, itype) \ +VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \ +VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, ) VFP_CONV_FIX(sh, d, 64, 64, int16) VFP_CONV_FIX(sl, d, 64, 64, int32) +VFP_CONV_FIX_A64(sq, d, 64, 64, int64) VFP_CONV_FIX(uh, d, 64, 64, uint16) VFP_CONV_FIX(ul, d, 64, 64, uint32) +VFP_CONV_FIX_A64(uq, d, 64, 64, uint64) VFP_CONV_FIX(sh, s, 32, 32, int16) VFP_CONV_FIX(sl, s, 32, 32, int32) +VFP_CONV_FIX_A64(sq, s, 32, 64, int64) VFP_CONV_FIX(uh, s, 32, 32, uint16) VFP_CONV_FIX(ul, s, 32, 32, uint32) +VFP_CONV_FIX_A64(uq, s, 32, 64, uint64) #undef VFP_CONV_FIX #undef VFP_CONV_FIX_FLOAT #undef VFP_CONV_FLOAT_FIX_ROUND diff --git a/target-arm/helper.h b/target-arm/helper.h index b785623..2e1af46 100644 --- a/target-arm/helper.h +++ b/target-arm/helper.h @@ -123,14 +123,30 @@ DEF_HELPER_3(vfp_toshd_round_to_zero, i64, f64, i32, ptr) DEF_HELPER_3(vfp_tosld_round_to_zero, i64, f64, i32, ptr) DEF_HELPER_3(vfp_touhd_round_to_zero, i64, f64, i32, ptr) DEF_HELPER_3(vfp_tould_round_to_zero, i64, f64, i32, ptr) +DEF_HELPER_3(vfp_toshs, i32, f32, i32, ptr) +DEF_HELPER_3(vfp_tosls, i32, f32, i32, ptr) +DEF_HELPER_3(vfp_tosqs, i64, f32, i32, ptr) +DEF_HELPER_3(vfp_touhs, i32, f32, i32, ptr) +DEF_HELPER_3(vfp_touls, i32, f32, i32, ptr) +DEF_HELPER_3(vfp_touqs, i64, f32, i32, ptr) +DEF_HELPER_3(vfp_toshd, i64, f64, i32, ptr) +DEF_HELPER_3(vfp_tosld, i64, f64, i32, ptr) +DEF_HELPER_3(vfp_tosqd, i64, f64, i32, ptr) +DEF_HELPER_3(vfp_touhd, i64, f64, i32, ptr) +DEF_HELPER_3(vfp_tould, i64, f64, i32, ptr) +DEF_HELPER_3(vfp_touqd, i64, f64, i32, ptr) DEF_HELPER_3(vfp_shtos, f32, i32, i32, ptr) DEF_HELPER_3(vfp_sltos, f32, i32, i32, ptr) +DEF_HELPER_3(vfp_sqtos, f32, i64, i32, ptr) DEF_HELPER_3(vfp_uhtos, f32, i32, i32, ptr) DEF_HELPER_3(vfp_ultos, f32, i32, i32, ptr) +DEF_HELPER_3(vfp_uqtos, f32, i64, i32, ptr) DEF_HELPER_3(vfp_shtod, f64, i64, i32, ptr) DEF_HELPER_3(vfp_sltod, f64, i64, i32, ptr) +DEF_HELPER_3(vfp_sqtod, f64, i64, i32, ptr) DEF_HELPER_3(vfp_uhtod, f64, i64, i32, ptr) DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr) +DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr) DEF_HELPER_2(vfp_fcvt_f16_to_f32, f32, i32, env) DEF_HELPER_2(vfp_fcvt_f32_to_f16, i32, f32, env) -- 1.8.5
[Qemu-devel] [PATCH v2 08/24] softfloat: Add float32_to_uint64()
From: Tom Musta tommu...@gmail.com This patch adds the float32_to_uint64() routine, which converts a 32-bit floating point number to an unsigned 64 bit number. This contribution can be licensed under either the softfloat-2a or -2b license. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- fpu/softfloat.c | 46 ++ include/fpu/softfloat.h | 1 + 2 files changed, 47 insertions(+) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index d2e9095..55c3ce1 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1559,6 +1559,52 @@ int64 float32_to_int64( float32 a STATUS_PARAM ) /* | Returns the result of converting the single-precision floating-point value +| `a' to the 64-bit unsigned integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic---which means in particular that the conversion is rounded +| according to the current rounding mode. If `a' is a NaN, the largest +| unsigned integer is returned. Otherwise, if the conversion overflows, the +| largest unsigned integer is returned. If the 'a' is negative, the result +| is rounded and zero is returned; values that do not round to zero will +| raise the inexact exception flag. +**/ + +uint64 float32_to_uint64(float32 a STATUS_PARAM) +{ +flag aSign; +int_fast16_t aExp, shiftCount; +uint32_t aSig; +uint64_t aSig64, aSigExtra; +a = float32_squash_input_denormal(a STATUS_VAR); + +aSig = extractFloat32Frac(a); +aExp = extractFloat32Exp(a); +aSign = extractFloat32Sign(a); +if ((aSign) (aExp 126)) { +float_raise(float_flag_invalid STATUS_VAR); +if (float32_is_any_nan(a)) { +return (int64_t)LIT64(0x); +} else { +return 0; +} +} +shiftCount = 0xBE - aExp; +if (aExp) { +aSig |= 0x0080; +} +if (shiftCount 0) { +float_raise(float_flag_invalid STATUS_VAR); +return (int64_t)LIT64(0x); +} + +aSig64 = aSig; +aSig64 = 40; +shift64ExtraRightJamming(aSig64, 0, shiftCount, aSig64, aSigExtra); +return roundAndPackUint64(aSign, aSig64, aSigExtra STATUS_VAR); +} + +/* +| Returns the result of converting the single-precision floating-point value | `a' to the 64-bit two's complement integer format. The conversion is | performed according to the IEC/IEEE Standard for Binary Floating-Point | Arithmetic, except that the conversion is always rounded toward zero. If diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 78b1656..eb81c3b 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -295,6 +295,7 @@ int32 float32_to_int32_round_to_zero( float32 STATUS_PARAM ); uint32 float32_to_uint32( float32 STATUS_PARAM ); uint32 float32_to_uint32_round_to_zero( float32 STATUS_PARAM ); int64 float32_to_int64( float32 STATUS_PARAM ); +uint64 float32_to_uint64(float32 STATUS_PARAM); int64 float32_to_int64_round_to_zero( float32 STATUS_PARAM ); float64 float32_to_float64( float32 STATUS_PARAM ); floatx80 float32_to_floatx80( float32 STATUS_PARAM ); -- 1.8.5
[Qemu-devel] [PULL 00/52] target-arm queue
First target-arm pull request of the year; please pull. (Incidentally I like the way these pull requests have a broad distribution of patch authors. The last 62-patch monster had 9 different authors, this one has 10, and the one from earlier in December had 9...) thanks -- PMM The following changes since commit f976b09ea2493fd41c98aaf6512908db0bae: PPC: Fix compilation with TCG debug (2013-12-22 19:15:55 +0100) are available in the git repository at: git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20140106 for you to fetch changes up to 449d14c182dd5d2d8d06bc1c36074533309274b6: hw: arm_gic: Introduce gic_set_priority function (2014-01-06 11:16:48 +) target-arm queue: * further A64 decoder patches, including enabling the aarch64-linux-user target, since we can now run at least some programs (FP and Neon instruction support is not yet complete) * cadence UART model fixes * some minor bug fixes and cleanups Alex Bennée (6): target-arm: A64: add support for ld/st unsigned imm target-arm: A64: add support for ld/st with reg offset target-arm: A64: add support for ld/st with index target-arm: A64: add support for add, addi, sub, subi target-arm: A64: add support for move wide instructions .travis.yml: Add aarch64-* targets Alexander Graf (8): target-arm: A64: add support for 3 src data proc insns target-arm: A64: implement SVC, BRK target-arm: aarch64: add support for ld lit target-arm: A64: Add support for dumping AArch64 VFP register state target-arm: A64: Add Floating-point data-processing (2 source) insns target-arm: A64: Add Floating-point data-processing (3 source) insns target-arm: A64: Add fmov (scalar, immediate) instruction target-arm: Give the FPSCR rounding modes names Christoffer Dall (2): arm_gic: Rename GIC_X_TRIGGER to GIC_X_EDGE_TRIGGER hw: arm_gic: Introduce gic_set_priority function Claudio Fontana (6): target-arm: A64: add support for add/sub with carry target-arm: A64: add support for conditional compare insns linux-user: AArch64: define TARGET_CLONE_BACKWARDS target-arm: A64: Add support for floating point compare target-arm: A64: Add support for floating point conditional compare target-arm: A64: Add support for floating point cond select Michael Matz (1): target-arm: A64: support for ld/st/cl exclusive Michael S. Tsirkin (1): target-arm: fix build with gcc 4.8.2 Peter Crosthwaite (13): char/cadence_uart: Mark struct fields as public/private char/cadence_uart: Add missing uart_update_state char/cadence_uart: Fix reset. char/cadence_uart: s/r_fifo/rx_fifo char/cadence_uart: Simplify status generation char/cadence_uart: Define Missing SR/ISR fields char/cadence_uart: Remove TX timer add TX FIFO state char/cadence_uart: Fix can_receive logic char/cadence_uart: Use the TX fifo for transmission char/cadence_uart: Delete redundant rx rst logic char/cadence_uart: Implement Tx flow control target-arm: remove raw_read|write duplication arm/xilinx_zynq: Always instantiate the GEMs Peter Maydell (13): target-arm: A64: add support for ld/st pair target-arm: A64: Add decoder skeleton for FP instructions target-arm: A64: implement FMOV target-arm: Pull add one cpreg to hashtable into its own function target-arm: Update generic cpreg code for AArch64 target-arm: Remove ARMCPU/CPUARMState from cpregs APIs used by decoder target-arm: A64: Implement MRS/MSR/SYS/SYSL target-arm: A64: Implement minimal set of EL0-visible sysregs target-arm: Widen thread-local register state fields to 64 bits target-arm: Widen exclusive-access support struct fields to 64 bits default-configs: Add config for aarch64-linux-user target-arm: A64: Fix vector register access on bigendian hosts target-arm: Use VFP_BINOP macro for min, max, minnum, maxnum Sergey Fedorov (1): target-arm: use c13_context field for CONTEXTIDR Will Newton (1): linux-user: AArch64: Use correct values for FPSR/FPCR in sigcontext .travis.yml|1 + default-configs/aarch64-linux-user.mak |3 + hw/arm/xilinx_zynq.c | 17 +- hw/char/cadence_uart.c | 153 +- hw/intc/arm_gic.c | 27 +- hw/intc/arm_gic_common.c |4 +- hw/intc/gic_internal.h |7 +- include/hw/intc/arm_gic_common.h |2 +- linux-user/aarch64/syscall.h |1 + linux-user/aarch64/target_cpu.h|5 +- linux-user/arm/target_cpu.h|2 +- linux-user/main.c | 154 +- linux-user/signal.c
[Qemu-devel] [PULL 16/52] target-arm: Widen thread-local register state fields to 64 bits
The common pattern for system registers in a 64-bit capable ARM CPU is that when in AArch32 the cp15 register is a view of the bottom 32 bits of the 64-bit AArch64 system register; writes in AArch32 leave the top half unchanged. The most natural way to model this is to have the state field in the CPU struct be a 64 bit value, and simply have the AArch32 TCG code operate on a pointer to its lower half. For aarch64-linux-user the only registers we need to share like this are the thread-local-storage ones. Widen their fields to 64 bits and provide the 64 bit reginfo struct to make them visible in AArch64 state. Note that minor cleanup of the AArch64 system register encoding space means We can share the TPIDR_EL1 reginfo but need split encodings for TPIDR_EL0 and TPIDRRO_EL0. Since we're touching almost every line in QEMU that uses the c13_tls* fields in this patch anyway, we take the opportunity to rename them in line with the standard ARM architectural names for these registers. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- linux-user/aarch64/target_cpu.h | 5 - linux-user/arm/target_cpu.h | 2 +- linux-user/main.c | 2 +- target-arm/cpu.h| 18 +++--- target-arm/helper.c | 22 +++--- 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/linux-user/aarch64/target_cpu.h b/linux-user/aarch64/target_cpu.h index 6f5539b..21560ef 100644 --- a/linux-user/aarch64/target_cpu.h +++ b/linux-user/aarch64/target_cpu.h @@ -29,7 +29,10 @@ static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp) static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls) { -env-sr.tpidr_el0 = newtls; +/* Note that AArch64 Linux keeps the TLS pointer in TPIDR; this is + * different from AArch32 Linux, which uses TPIDRRO. + */ +env-cp15.tpidr_el0 = newtls; } #endif diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h index ed323c0..39d65b6 100644 --- a/linux-user/arm/target_cpu.h +++ b/linux-user/arm/target_cpu.h @@ -29,7 +29,7 @@ static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp) static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls) { -env-cp15.c13_tls2 = newtls; +env-cp15.tpidrro_el0 = newtls; } #endif diff --git a/linux-user/main.c b/linux-user/main.c index 54f71fe..c0df8b5 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -566,7 +566,7 @@ do_kernel_trap(CPUARMState *env) end_exclusive(); break; case 0x0fe0: /* __kernel_get_tls */ -env-regs[0] = env-cp15.c13_tls2; +env-regs[0] = env-cp15.tpidrro_el0; break; case 0x0f60: /* __kernel_cmpxchg64 */ arm_kernel_cmpxchg64_helper(env); diff --git a/target-arm/cpu.h b/target-arm/cpu.h index ab8ef17..fc36514 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -66,6 +66,18 @@ /* ARM-specific interrupt pending bits. */ #define CPU_INTERRUPT_FIQ CPU_INTERRUPT_TGT_EXT_1 +/* The usual mapping for an AArch64 system register to its AArch32 + * counterpart is for the 32 bit world to have access to the lower + * half only (with writes leaving the upper half untouched). It's + * therefore useful to be able to pass TCG the offset of the least + * significant half of a uint64_t struct member. + */ +#ifdef HOST_WORDS_BIGENDIAN +#define offsetoflow32(S, M) (offsetof(S, M + sizeof(uint32_t)) +#else +#define offsetoflow32(S, M) offsetof(S, M) +#endif + /* Meanings of the ARMCPU object's two inbound GPIO lines */ #define ARM_CPU_IRQ 0 #define ARM_CPU_FIQ 1 @@ -188,9 +200,9 @@ typedef struct CPUARMState { uint32_t c12_vbar; /* vector base address register */ uint32_t c13_fcse; /* FCSE PID. */ uint32_t c13_context; /* Context ID. */ -uint32_t c13_tls1; /* User RW Thread register. */ -uint32_t c13_tls2; /* User RO Thread register. */ -uint32_t c13_tls3; /* Privileged Thread register. */ +uint64_t tpidr_el0; /* User RW Thread register. */ +uint64_t tpidrro_el0; /* User RO Thread register. */ +uint64_t tpidr_el1; /* Privileged Thread register. */ uint32_t c14_cntfrq; /* Counter Frequency register */ uint32_t c14_cntkctl; /* Timer Control register */ ARMGenericTimer c14_timer[NUM_GTIMERS]; diff --git a/target-arm/helper.c b/target-arm/helper.c index 868493d..e7d88ea 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -740,18 +740,26 @@ static const ARMCPRegInfo t2ee_cp_reginfo[] = { }; static const ARMCPRegInfo v6k_cp_reginfo[] = { +{ .name = TPIDR_EL0, .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 2, .crn = 13, .crm = 0, + .access = PL0_RW, + .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el0), .resetvalue = 0 }, { .name = TPIDRURW, .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2,
[Qemu-devel] [PATCH v2 10/24] softfloat: Fix float64_to_uint32
From: Tom Musta tommu...@gmail.com The float64_to_uint32 has several flaws: - for numbers between 2**32 and 2**64, the inexact exception flag may get incorrectly set. In this case, only the invalid flag should be set. test pattern: 425F81378DC0CD1F / 0x1.f81378dc0cd1fp+38 - for numbers between 2**63 and 2**64, incorrect results may be produced: test pattern: 43EAAF73F1F0B8BD / 0x1.aaf73f1f0b8bdp+63 This patch re-implements float64_to_uint32 to re-use the float64_to_uint64 routine (instead of float64_to_int64). For the saturation case, we ignore any flags which the conversion routine has set and raise only the invalid flag. This contribution can be licensed under either the softfloat-2a or -2b license. Signed-off-by: Tom Musta tommu...@gmail.com Message-id: 1387397961-4894-5-git-send-email-tommu...@gmail.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- fpu/softfloat.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index c8e19b4..814cd01 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -6650,19 +6650,18 @@ uint_fast16_t float32_to_uint16_round_to_zero(float32 a STATUS_PARAM) uint32 float64_to_uint32( float64 a STATUS_PARAM ) { -int64_t v; +uint64_t v; uint32 res; +int old_exc_flags = get_float_exception_flags(status); -v = float64_to_int64(a STATUS_VAR); -if (v 0) { -res = 0; -float_raise( float_flag_invalid STATUS_VAR); -} else if (v 0x) { +v = float64_to_uint64(a STATUS_VAR); +if (v 0x) { res = 0x; -float_raise( float_flag_invalid STATUS_VAR); } else { -res = v; +return v; } +set_float_exception_flags(old_exc_flags, status); +float_raise(float_flag_invalid STATUS_VAR); return res; } -- 1.8.5
[Qemu-devel] [PATCH v2 05/24] softfloat: Fix float64_to_uint64
From: Tom Musta tommu...@gmail.com The comment preceding the float64_to_uint64 routine suggests that the implementation is broken. And this is, indeed, the case. This patch properly implements the conversion of a 64-bit floating point number to an unsigned, 64 bit integer. This contribution can be licensed under either the softfloat-2a or -2b license. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- fpu/softfloat.c | 101 +++- 1 file changed, 93 insertions(+), 8 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 3170b88..2364513 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -204,6 +204,56 @@ static int64 roundAndPackInt64( flag zSign, uint64_t absZ0, uint64_t absZ1 STATU } /* +| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and +| `absZ1', with binary point between bits 63 and 64 (between the input words), +| and returns the properly rounded 64-bit unsigned integer corresponding to the +| input. Ordinarily, the fixed-point input is simply rounded to an integer, +| with the inexact exception raised if the input cannot be represented exactly +| as an integer. However, if the fixed-point input is too large, the invalid +| exception is raised and the largest unsigned integer is returned. +**/ + +static int64 roundAndPackUint64(flag zSign, uint64_t absZ0, +uint64_t absZ1 STATUS_PARAM) +{ +int8 roundingMode; +flag roundNearestEven, increment; + +roundingMode = STATUS(float_rounding_mode); +roundNearestEven = (roundingMode == float_round_nearest_even); +increment = ((int64_t)absZ1 0); +if (!roundNearestEven) { +if (roundingMode == float_round_to_zero) { +increment = 0; +} else if (absZ1) { +if (zSign) { +increment = (roundingMode == float_round_down) absZ1; +} else { +increment = (roundingMode == float_round_up) absZ1; +} +} +} +if (increment) { +++absZ0; +if (absZ0 == 0) { +float_raise(float_flag_invalid STATUS_VAR); +return LIT64(0x); +} +absZ0 = ~(((uint64_t)(absZ11) == 0) roundNearestEven); +} + +if (zSign absZ0) { +float_raise(float_flag_invalid STATUS_VAR); +return 0; +} + +if (absZ1) { +STATUS(float_exception_flags) |= float_flag_inexact; +} +return absZ0; +} + +/* | Returns the fraction bits of the single-precision floating-point value `a'. **/ @@ -6643,16 +6693,51 @@ uint_fast16_t float64_to_uint16_round_to_zero(float64 a STATUS_PARAM) return res; } -/* FIXME: This looks broken. */ -uint64_t float64_to_uint64 (float64 a STATUS_PARAM) -{ -int64_t v; +/* +| Returns the result of converting the double-precision floating-point value +| `a' to the 64-bit unsigned integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic---which means in particular that the conversion is rounded +| according to the current rounding mode. If `a' is a NaN, the largest +| positive integer is returned. If the conversion overflows, the +| largest unsigned integer is returned. If 'a' is negative, the value is +| rounded and zero is returned; negative values that do not round to zero +| will raise the inexact exception. +**/ -v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR)); -v += float64_val(a); -v = float64_to_int64(make_float64(v) STATUS_VAR); +uint64_t float64_to_uint64(float64 a STATUS_PARAM) +{ +flag aSign; +int_fast16_t aExp, shiftCount; +uint64_t aSig, aSigExtra; +a = float64_squash_input_denormal(a STATUS_VAR); -return v - INT64_MIN; +aSig = extractFloat64Frac(a); +aExp = extractFloat64Exp(a); +aSign = extractFloat64Sign(a); +if (aSign (aExp 1022)) { +float_raise(float_flag_invalid STATUS_VAR); +if (float64_is_any_nan(a)) { +return LIT64(0x); +} else { +return 0; +} +} +if (aExp) { +aSig |= LIT64(0x0010); +} +shiftCount = 0x433 - aExp; +if (shiftCount = 0) { +if (0x43E aExp) { +float_raise(float_flag_invalid STATUS_VAR); +return LIT64(0x); +} +aSigExtra = 0; +
[Qemu-devel] [PATCH v2 13/24] softfloat: Factor out RoundAndPackFloat16 and NormalizeFloat16Subnormal
In preparation for adding conversions between float16 and float64, factor out code currently done inline in the float16=float32 conversion functions into functions RoundAndPackFloat16 and NormalizeFloat16Subnormal along the lines of the existing versions for the other float types. Note that we change the handling of zExp from the inline code to match the API of the other RoundAndPackFloat functions; however we leave the positioning of the binary point between bits 22 and 23 rather than shifting it up to the high end of the word. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- fpu/softfloat.c | 209 +--- 1 file changed, 125 insertions(+), 84 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index fa78f42..f095f82 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3086,6 +3086,127 @@ static float16 packFloat16(flag zSign, int_fast16_t zExp, uint16_t zSig) (((uint32_t)zSign) 15) + (((uint32_t)zExp) 10) + zSig); } +/* +| Takes an abstract floating-point value having sign `zSign', exponent `zExp', +| and significand `zSig', and returns the proper half-precision floating- +| point value corresponding to the abstract input. Ordinarily, the abstract +| value is simply rounded and packed into the half-precision format, with +| the inexact exception raised if the abstract input cannot be represented +| exactly. However, if the abstract value is too large, the overflow and +| inexact exceptions are raised and an infinity or maximal finite value is +| returned. If the abstract value is too small, the input value is rounded to +| a subnormal number, and the underflow and inexact exceptions are raised if +| the abstract input cannot be represented exactly as a subnormal half- +| precision floating-point number. +| The `ieee' flag indicates whether to use IEEE standard half precision, or +| ARM-style alternative representation, which omits the NaN and Inf +| encodings in order to raise the maximum representable exponent by one. +| The input significand `zSig' has its binary point between bits 22 +| and 23, which is 13 bits to the left of the usual location. This shifted +| significand must be normalized or smaller. If `zSig' is not normalized, +| `zExp' must be 0; in that case, the result returned is a subnormal number, +| and it must not require rounding. In the usual case that `zSig' is +| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent. +| Note the slightly odd position of the binary point in zSig compared with the +| other roundAndPackFloat functions. This should probably be fixed if we +| need to implement more float16 routines than just conversion. +| The handling of underflow and overflow follows the IEC/IEEE Standard for +| Binary Floating-Point Arithmetic. +**/ + +static float32 roundAndPackFloat16(flag zSign, int_fast16_t zExp, + uint32_t zSig, flag ieee STATUS_PARAM) +{ +int maxexp = ieee ? 29 : 30; +uint32_t mask; +uint32_t increment; +int8 roundingMode; +bool rounding_bumps_exp; +bool is_tiny = false; + +/* Calculate the mask of bits of the mantissa which are not + * representable in half-precision and will be lost. + */ +if (zExp 1) { +/* Will be denormal in halfprec */ +mask = 0x00ff; +if (zExp = -11) { +mask = 11 + zExp; +} +} else { +/* Normal number in halfprec */ +mask = 0x1fff; +} + +roundingMode = STATUS(float_rounding_mode); +switch (roundingMode) { +case float_round_nearest_even: +increment = (mask + 1) 1; +if ((zSig mask) == increment) { +increment = zSig (increment 1); +} +break; +case float_round_up: +increment = zSign ? 0 : mask; +break; +case float_round_down: +increment = zSign ? mask : 0; +break; +default: /* round_to_zero */ +increment = 0; +break; +} + +rounding_bumps_exp = (zSig + increment = 0x0100); + +if (zExp maxexp || (zExp == maxexp rounding_bumps_exp)) { +if (ieee) { +float_raise(float_flag_overflow | float_flag_inexact STATUS_VAR); +return packFloat16(zSign, 0x1f, 0); +} else { +float_raise(float_flag_invalid STATUS_VAR); +return packFloat16(zSign, 0x1f, 0x3ff); +} +} + +if (zExp 0) { +/* Note that flush-to-zero does not affect half-precision results */ +is_tiny = +(STATUS(float_detect_tininess) == float_tininess_before_rounding) +|| (zExp -1) +|| (!rounding_bumps_exp); +} +if (zSig mask) { +float_raise(float_flag_inexact STATUS_VAR); +if (is_tiny) { +
[Qemu-devel] [PATCH v2 11/24] softfloat: Fix float64_to_uint32_round_to_zero
From: Tom Musta tommu...@gmail.com The float64_to_uint32_round_to_zero routine is incorrect. For example, the following test pattern: 425F81378DC0CD1F / 0x1.f81378dc0cd1fp+38 will erroneously set the inexact flag. This patch re-implements the routine to use the float64_to_uint64_round_to_zero routine. If saturation occurs we ignore any flags set by the conversion function and raise only Invalid. This contribution can be licensed under either the softfloat-2a or -2b license. Signed-off-by: Tom Musta tommu...@gmail.com Message-id: 1387397961-4894-6-git-send-email-tommu...@gmail.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- fpu/softfloat.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 814cd01..758022c 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -6667,19 +6667,18 @@ uint32 float64_to_uint32( float64 a STATUS_PARAM ) uint32 float64_to_uint32_round_to_zero( float64 a STATUS_PARAM ) { -int64_t v; +uint64_t v; uint32 res; +int old_exc_flags = get_float_exception_flags(status); -v = float64_to_int64_round_to_zero(a STATUS_VAR); -if (v 0) { -res = 0; -float_raise( float_flag_invalid STATUS_VAR); -} else if (v 0x) { +v = float64_to_uint64_round_to_zero(a STATUS_VAR); +if (v 0x) { res = 0x; -float_raise( float_flag_invalid STATUS_VAR); } else { -res = v; +return v; } +set_float_exception_flags(old_exc_flags, status); +float_raise(float_flag_invalid STATUS_VAR); return res; } -- 1.8.5
[Qemu-devel] [PATCH v2 18/24] target-arm: Rename A32 VFP conversion helpers
From: Will Newton will.new...@linaro.org The VFP conversion helpers for A32 round to zero as this is the only rounding mode supported. Rename these helpers to make it clear that they round to zero and are not suitable for use in the AArch64 code. Signed-off-by: Will Newton will.new...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/helper.c| 19 ++- target-arm/helper.h| 16 target-arm/translate.c | 24 +--- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index 501d798..905abd3 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -3976,7 +3976,7 @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env) } /* VFP3 fixed point conversion. */ -#define VFP_CONV_FIX(name, p, fsz, isz, itype) \ +#define VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \ float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \ void *fpstp) \ { \ @@ -3984,9 +3984,12 @@ float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \ float##fsz tmp; \ tmp = itype##_to_##float##fsz(x, fpst); \ return float##fsz##_scalbn(tmp, -(int)shift, fpst); \ -} \ -uint##isz##_t HELPER(vfp_to##name##p)(float##fsz x, uint32_t shift, \ - void *fpstp) \ +} + +#define VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, round) \ +uint##isz##_t HELPER(vfp_to##name##p##round)(float##fsz x, \ + uint32_t shift, \ + void *fpstp) \ { \ float_status *fpst = fpstp; \ float##fsz tmp; \ @@ -3995,9 +3998,13 @@ uint##isz##_t HELPER(vfp_to##name##p)(float##fsz x, uint32_t shift, \ return 0; \ } \ tmp = float##fsz##_scalbn(x, shift, fpst); \ -return float##fsz##_to_##itype##_round_to_zero(tmp, fpst); \ +return float##fsz##_to_##itype##round(tmp, fpst); \ } +#define VFP_CONV_FIX(name, p, fsz, isz, itype) \ +VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \ +VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, _round_to_zero) + VFP_CONV_FIX(sh, d, 64, 64, int16) VFP_CONV_FIX(sl, d, 64, 64, int32) VFP_CONV_FIX(uh, d, 64, 64, uint16) @@ -4007,6 +4014,8 @@ VFP_CONV_FIX(sl, s, 32, 32, int32) VFP_CONV_FIX(uh, s, 32, 32, uint16) VFP_CONV_FIX(ul, s, 32, 32, uint32) #undef VFP_CONV_FIX +#undef VFP_CONV_FIX_FLOAT +#undef VFP_CONV_FLOAT_FIX_ROUND /* Half precision conversions. */ static float32 do_fcvt_f16_to_f32(uint32_t a, CPUARMState *env, float_status *s) diff --git a/target-arm/helper.h b/target-arm/helper.h index dd1160e..b785623 100644 --- a/target-arm/helper.h +++ b/target-arm/helper.h @@ -115,14 +115,14 @@ DEF_HELPER_2(vfp_tosid, i32, f64, ptr) DEF_HELPER_2(vfp_tosizs, i32, f32, ptr) DEF_HELPER_2(vfp_tosizd, i32, f64, ptr) -DEF_HELPER_3(vfp_toshs, i32, f32, i32, ptr) -DEF_HELPER_3(vfp_tosls, i32, f32, i32, ptr) -DEF_HELPER_3(vfp_touhs, i32, f32, i32, ptr) -DEF_HELPER_3(vfp_touls, i32, f32, i32, ptr) -DEF_HELPER_3(vfp_toshd, i64, f64, i32, ptr) -DEF_HELPER_3(vfp_tosld, i64, f64, i32, ptr) -DEF_HELPER_3(vfp_touhd, i64, f64, i32, ptr) -DEF_HELPER_3(vfp_tould, i64, f64, i32, ptr) +DEF_HELPER_3(vfp_toshs_round_to_zero, i32, f32, i32, ptr) +DEF_HELPER_3(vfp_tosls_round_to_zero, i32, f32, i32, ptr) +DEF_HELPER_3(vfp_touhs_round_to_zero, i32, f32, i32, ptr) +DEF_HELPER_3(vfp_touls_round_to_zero, i32, f32, i32, ptr) +DEF_HELPER_3(vfp_toshd_round_to_zero, i64, f64, i32, ptr) +DEF_HELPER_3(vfp_tosld_round_to_zero, i64, f64, i32, ptr) +DEF_HELPER_3(vfp_touhd_round_to_zero, i64, f64, i32, ptr) +DEF_HELPER_3(vfp_tould_round_to_zero, i64, f64, i32, ptr) DEF_HELPER_3(vfp_shtos, f32, i32, i32, ptr) DEF_HELPER_3(vfp_sltos, f32, i32, i32, ptr) DEF_HELPER_3(vfp_uhtos, f32, i32, i32, ptr) diff --git a/target-arm/translate.c b/target-arm/translate.c index d04fc9f..8d240e1 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -1098,27 +1098,29 @@ VFP_GEN_FTOI(tosi) VFP_GEN_FTOI(tosiz) #undef VFP_GEN_FTOI -#define VFP_GEN_FIX(name) \ +#define VFP_GEN_FIX(name, round) \ static inline void gen_vfp_##name(int dp, int shift, int neon) \ { \ TCGv_i32 tmp_shift = tcg_const_i32(shift); \ TCGv_ptr statusptr = get_fpstatus_ptr(neon); \ if (dp) { \ -gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \ +gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \ +statusptr); \ } else { \ -gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \ +gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \ +statusptr); \ } \ tcg_temp_free_i32(tmp_shift); \
[Qemu-devel] [PATCH v2 24/24] target-arm: A64: Add support for FCVT between half, single and double
Add support for FCVT between half, single and double precision. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/helper.c| 20 + target-arm/helper.h| 2 ++ target-arm/translate-a64.c | 75 +- 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index a0c1646..59e6208 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -4089,6 +4089,26 @@ uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, CPUARMState *env) return do_fcvt_f32_to_f16(a, env, env-vfp.fp_status); } +float64 HELPER(vfp_fcvt_f16_to_f64)(uint32_t a, CPUARMState *env) +{ +int ieee = (env-vfp.xregs[ARM_VFP_FPSCR] (1 26)) == 0; +float64 r = float16_to_float64(make_float16(a), ieee, env-vfp.fp_status); +if (ieee) { +return float64_maybe_silence_nan(r); +} +return r; +} + +uint32_t HELPER(vfp_fcvt_f64_to_f16)(float64 a, CPUARMState *env) +{ +int ieee = (env-vfp.xregs[ARM_VFP_FPSCR] (1 26)) == 0; +float16 r = float64_to_float16(a, ieee, env-vfp.fp_status); +if (ieee) { +r = float16_maybe_silence_nan(r); +} +return float16_val(r); +} + #define float32_two make_float32(0x4000) #define float32_three make_float32(0x4040) #define float32_one_point_five make_float32(0x3fc0) diff --git a/target-arm/helper.h b/target-arm/helper.h index 832ec12..213ccc6 100644 --- a/target-arm/helper.h +++ b/target-arm/helper.h @@ -154,6 +154,8 @@ DEF_HELPER_2(vfp_fcvt_f16_to_f32, f32, i32, env) DEF_HELPER_2(vfp_fcvt_f32_to_f16, i32, f32, env) DEF_HELPER_2(neon_fcvt_f16_to_f32, f32, i32, env) DEF_HELPER_2(neon_fcvt_f32_to_f16, i32, f32, env) +DEF_HELPER_FLAGS_2(vfp_fcvt_f16_to_f64, TCG_CALL_NO_RWG, f64, i32, env) +DEF_HELPER_FLAGS_2(vfp_fcvt_f64_to_f16, TCG_CALL_NO_RWG, i32, f64, env) DEF_HELPER_4(vfp_muladdd, f64, f64, f64, f64, ptr) DEF_HELPER_4(vfp_muladds, f32, f32, f32, f32, ptr) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 345a47b..cf80c46 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -3498,6 +3498,72 @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) tcg_temp_free_i64(tcg_res); } +static void handle_fp_fcvt(DisasContext *s, int opcode, + int rd, int rn, int dtype, int ntype) +{ +switch (ntype) { +case 0x0: +{ +TCGv_i32 tcg_rn = read_fp_sreg(s, rn); +if (dtype == 1) { +/* Single to double */ +TCGv_i64 tcg_rd = tcg_temp_new_i64(); +gen_helper_vfp_fcvtds(tcg_rd, tcg_rn, cpu_env); +write_fp_dreg(s, rd, tcg_rd); +tcg_temp_free_i64(tcg_rd); +} else { +/* Single to half */ +TCGv_i32 tcg_rd = tcg_temp_new_i32(); +gen_helper_vfp_fcvt_f32_to_f16(tcg_rd, tcg_rn, cpu_env); +/* write_fp_sreg is OK here because top half of tcg_rd is zero */ +write_fp_sreg(s, rd, tcg_rd); +tcg_temp_free_i32(tcg_rd); +} +tcg_temp_free_i32(tcg_rn); +break; +} +case 0x1: +{ +TCGv_i64 tcg_rn = read_fp_dreg(s, rn); +TCGv_i32 tcg_rd = tcg_temp_new_i32(); +if (dtype == 0) { +/* Double to single */ +gen_helper_vfp_fcvtsd(tcg_rd, tcg_rn, cpu_env); +} else { +/* Double to half */ +gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, cpu_env); +/* write_fp_sreg is OK here because top half of tcg_rd is zero */ +} +write_fp_sreg(s, rd, tcg_rd); +tcg_temp_free_i32(tcg_rd); +tcg_temp_free_i64(tcg_rn); +break; +} +case 0x3: +{ +TCGv_i32 tcg_rn = read_fp_sreg(s, rn); +tcg_gen_ext16u_i32(tcg_rn, tcg_rn); +if (dtype == 0) { +/* Half to single */ +TCGv_i32 tcg_rd = tcg_temp_new_i32(); +gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, cpu_env); +write_fp_sreg(s, rd, tcg_rd); +tcg_temp_free_i32(tcg_rd); +} else { +/* Half to double */ +TCGv_i64 tcg_rd = tcg_temp_new_i64(); +gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, cpu_env); +write_fp_dreg(s, rd, tcg_rd); +tcg_temp_free_i64(tcg_rd); +} +tcg_temp_free_i32(tcg_rn); +break; +} +default: +abort(); +} +} + /* C3.6.25 Floating point data-processing (1 source) * 31 30 29 28 24 23 22 21 2015 14 10 95 40 * +---+---+---+---+--+---++---+--+--+ @@ -3513,9 +3579,16 @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) switch (opcode) { case 0x4: case 0x5: case 0x7: +{ /* FCVT between half, single and double precision */ -unsupported_encoding(s, insn); +int dtype =
[Qemu-devel] [PATCH v2 00/24] A64 decoder patchset 6: rest of floating point
This patchset completes the FP emulation, leaving us with only Neon (and CRC32) to go to complete the user-mode emulation. Most of this is fixing issues and adding new features to softfloat. (As usual, all Linaro authored softfloat patches are licensed under either softfloat-2a or softfloat-2b, at your option.) We need Tom Musta's softfloat patches too, so I have included them here (updated to the latest versions with the issues fixed). Changes v1-v2: * updated versions of Tom Musta's patches Fix float64_to_uint64 and Add float32_to_uint64 * 16 bit int-to-float fns now take exact-width types * new patch: softfloat: Make the int-to-float functions take exact-width types, to make the other int-to-float functions consistent * Prepare VFP_CONV_FIX helpers for A64 uses now also drops the cast in the int_to_float call, since the above changes make it unnecessary * use 32 bit type as the intermediate when doing float-to-16-bit-int conversions * new patch: softfloat: Refactor code handling various rounding modes which is a pure refactoring of the rounding mode code to consistently use switches; this makes the ties-away support patch nicer and ends up with more readable code Alex: we should coordinate about whether these softfloat patches should go through my tree or yours, otherwise there's going to be a clash... thanks -- PMM Alexander Graf (1): target-arm: A64: Add Floating-point-fixed-point instructions Peter Maydell (13): softfloat: Fix exception flag handling for float32_to_float16() softfloat: Add 16 bit integer to float conversions softfloat: Make the int-to-float functions take exact-width types softfloat: Only raise Invalid when conversions to int are out of range softfloat: Fix factor 2 error for scalbn on denormal inputs softfloat: Provide complete set of accessors for fp state softfloat: Factor out RoundAndPackFloat16 and NormalizeFloat16Subnormal softfloat: Add float16 = float64 conversion functions softfloat: Refactor code handling various rounding modes softfloat: Add support for ties-away rounding target-arm: Ignore most exceptions from scalbn when doing fixpoint conversion target-arm: A64: Add 1-source 32-to-32 and 64-to-64 FP instructions target-arm: A64: Add support for FCVT between half, single and double Tom Musta (5): softfloat: Fix float64_to_uint64 softfloat: Add float32_to_uint64() softfloat: Fix float64_to_uint64_round_to_zero softfloat: Fix float64_to_uint32 softfloat: Fix float64_to_uint32_round_to_zero Will Newton (5): softfloat: Add float to 16bit integer conversions. target-arm: Prepare VFP_CONV_FIX helpers for A64 uses target-arm: Rename A32 VFP conversion helpers target-arm: A64: Add extra VFP fixed point conversion helpers target-arm: A64: Add floating-point-integer conversion instructions fpu/softfloat.c| 1055 include/fpu/softfloat.h| 96 +++- target-arm/helper.c| 141 +- target-arm/helper.h| 25 ++ target-arm/translate-a64.c | 424 +- target-arm/translate.c | 24 +- 6 files changed, 1428 insertions(+), 337 deletions(-) -- 1.8.5
[Qemu-devel] [PATCH v2 14/24] softfloat: Add float16 = float64 conversion functions
Add the conversion functions float16_to_float64() and float64_to_float16(), which will be needed for the ARM A64 instruction set. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- fpu/softfloat.c | 75 + include/fpu/softfloat.h | 2 ++ 2 files changed, 77 insertions(+) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index f095f82..78f680f 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3281,6 +3281,81 @@ float16 float32_to_float16(float32 a, flag ieee STATUS_PARAM) return roundAndPackFloat16(aSign, aExp, aSig, ieee STATUS_VAR); } +float64 float16_to_float64(float16 a, flag ieee STATUS_PARAM) +{ +flag aSign; +int_fast16_t aExp; +uint32_t aSig; + +aSign = extractFloat16Sign(a); +aExp = extractFloat16Exp(a); +aSig = extractFloat16Frac(a); + +if (aExp == 0x1f ieee) { +if (aSig) { +return commonNaNToFloat64( +float16ToCommonNaN(a STATUS_VAR) STATUS_VAR); +} +return packFloat64(aSign, 0x7ff, 0); +} +if (aExp == 0) { +if (aSig == 0) { +return packFloat64(aSign, 0, 0); +} + +normalizeFloat16Subnormal(aSig, aExp, aSig); +aExp--; +} +return packFloat64(aSign, aExp + 0x3f0, ((uint64_t)aSig) 42); +} + +float16 float64_to_float16(float64 a, flag ieee STATUS_PARAM) +{ +flag aSign; +int_fast16_t aExp; +uint64_t aSig; +uint32_t zSig; + +a = float64_squash_input_denormal(a STATUS_VAR); + +aSig = extractFloat64Frac(a); +aExp = extractFloat64Exp(a); +aSign = extractFloat64Sign(a); +if (aExp == 0x7FF) { +if (aSig) { +/* Input is a NaN */ +if (!ieee) { +float_raise(float_flag_invalid STATUS_VAR); +return packFloat16(aSign, 0, 0); +} +return commonNaNToFloat16( +float64ToCommonNaN(a STATUS_VAR) STATUS_VAR); +} +/* Infinity */ +if (!ieee) { +float_raise(float_flag_invalid STATUS_VAR); +return packFloat16(aSign, 0x1f, 0x3ff); +} +return packFloat16(aSign, 0x1f, 0); +} +shift64RightJamming(aSig, 29, aSig); +zSig = aSig; +if (aExp == 0 zSig == 0) { +return packFloat16(aSign, 0, 0); +} +/* Decimal point between bits 22 and 23. Note that we add the 1 bit + * even if the input is denormal; however this is harmless because + * the largest possible single-precision denormal is still smaller + * than the smallest representable half-precision denormal, and so we + * will end up ignoring aSig and returning via the always return zero + * codepath. + */ +zSig |= 0x0080; +aExp -= 0x3F1; + +return roundAndPackFloat16(aSign, aExp, zSig, ieee STATUS_VAR); +} + /* | Returns the result of converting the double-precision floating-point value | `a' to the extended double-precision floating-point format. The conversion diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index a634a4e..83d324a 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -298,6 +298,8 @@ INLINE float64 uint16_to_float64(uint16_t v STATUS_PARAM) **/ float16 float32_to_float16( float32, flag STATUS_PARAM ); float32 float16_to_float32( float16, flag STATUS_PARAM ); +float16 float64_to_float16(float64 a, flag ieee STATUS_PARAM); +float64 float16_to_float64(float16 a, flag ieee STATUS_PARAM); /* | Software half-precision operations. -- 1.8.5
[Qemu-devel] [PATCH v2 04/24] softfloat: Make the int-to-float functions take exact-width types
Currently the int-to-float functions take types which are specified as at least X bits wide, rather than exactly X bits wide. This is confusing and unhelpful since it means that the callers have to include an explicit cast to [u]intXX_t to ensure the correct behaviour. Fix them all to take the exactly-X-bits-wide types instead. Note that this doesn't change behaviour at all since at the moment we happen to define the 'int32' and 'uint32' types as exactly 32 bits wide, and the 'int64' and 'uint64' types as exactly 64 bits wide. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- fpu/softfloat.c | 26 +- include/fpu/softfloat.h | 26 +- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index dbaa32c..3170b88 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1121,7 +1121,7 @@ static float128 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. **/ -float32 int32_to_float32( int32 a STATUS_PARAM ) +float32 int32_to_float32(int32_t a STATUS_PARAM) { flag zSign; @@ -1138,7 +1138,7 @@ float32 int32_to_float32( int32 a STATUS_PARAM ) | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. **/ -float64 int32_to_float64( int32 a STATUS_PARAM ) +float64 int32_to_float64(int32_t a STATUS_PARAM) { flag zSign; uint32 absA; @@ -1161,7 +1161,7 @@ float64 int32_to_float64( int32 a STATUS_PARAM ) | Arithmetic. **/ -floatx80 int32_to_floatx80( int32 a STATUS_PARAM ) +floatx80 int32_to_floatx80(int32_t a STATUS_PARAM) { flag zSign; uint32 absA; @@ -1183,7 +1183,7 @@ floatx80 int32_to_floatx80( int32 a STATUS_PARAM ) | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. **/ -float128 int32_to_float128( int32 a STATUS_PARAM ) +float128 int32_to_float128(int32_t a STATUS_PARAM) { flag zSign; uint32 absA; @@ -1205,7 +1205,7 @@ float128 int32_to_float128( int32 a STATUS_PARAM ) | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. **/ -float32 int64_to_float32( int64 a STATUS_PARAM ) +float32 int64_to_float32(int64_t a STATUS_PARAM) { flag zSign; uint64 absA; @@ -1231,7 +1231,7 @@ float32 int64_to_float32( int64 a STATUS_PARAM ) } -float32 uint64_to_float32( uint64 a STATUS_PARAM ) +float32 uint64_to_float32(uint64_t a STATUS_PARAM) { int8 shiftCount; @@ -1258,7 +1258,7 @@ float32 uint64_to_float32( uint64 a STATUS_PARAM ) | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. **/ -float64 int64_to_float64( int64 a STATUS_PARAM ) +float64 int64_to_float64(int64_t a STATUS_PARAM) { flag zSign; @@ -1271,7 +1271,7 @@ float64 int64_to_float64( int64 a STATUS_PARAM ) } -float64 uint64_to_float64(uint64 a STATUS_PARAM) +float64 uint64_to_float64(uint64_t a STATUS_PARAM) { int exp = 0x43C; @@ -1292,7 +1292,7 @@ float64 uint64_to_float64(uint64 a STATUS_PARAM) | Arithmetic. **/ -floatx80 int64_to_floatx80( int64 a STATUS_PARAM ) +floatx80 int64_to_floatx80(int64_t a STATUS_PARAM) { flag zSign; uint64 absA; @@ -1312,7 +1312,7 @@ floatx80 int64_to_floatx80( int64 a STATUS_PARAM ) | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. **/ -float128 int64_to_float128( int64 a STATUS_PARAM ) +float128 int64_to_float128(int64_t a STATUS_PARAM) { flag zSign; uint64 absA; @@ -1339,7 +1339,7 @@ float128 int64_to_float128( int64 a STATUS_PARAM ) } -float128 uint64_to_float128(uint64 a STATUS_PARAM) +float128 uint64_to_float128(uint64_t a STATUS_PARAM) { if (a == 0) { return float128_zero; @@ -6445,12 +6445,12 @@ int float128_unordered_quiet( float128 a, float128 b STATUS_PARAM ) } /* misc functions */ -float32 uint32_to_float32( uint32 a STATUS_PARAM ) +float32 uint32_to_float32(uint32_t a STATUS_PARAM) { return int64_to_float32(a STATUS_VAR); } -float64 uint32_to_float64( uint32 a STATUS_PARAM ) +float64 uint32_to_float64(uint32_t a STATUS_PARAM) { return int64_to_float64(a STATUS_VAR); } diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 926d849..78b1656 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -225,19 +225,19 @@ enum {
[Qemu-devel] [PATCH v2 16/24] softfloat: Add support for ties-away rounding
IEEE754-2008 specifies a new rounding mode: roundTiesToAway: the floating-point number nearest to the infinitely precise result shall be delivered; if the two nearest floating-point numbers bracketing an unrepresentable infinitely precise result are equally near, the one with larger magnitude shall be delivered. Implement this new mode (it is needed for ARM). The general principle is that the required code is exactly like the ties-to-even code, except that we do not need to do the in case of exact tie clear LSB to round-to-even, because the rounding operation naturally causes the exact tie to round up in magnitude. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- fpu/softfloat.c | 54 + include/fpu/softfloat.h | 3 ++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 42cb705..49d90ef 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -111,6 +111,7 @@ static int32 roundAndPackInt32( flag zSign, uint64_t absZ STATUS_PARAM) roundNearestEven = ( roundingMode == float_round_nearest_even ); switch (roundingMode) { case float_round_nearest_even: +case float_round_ties_away: roundIncrement = 0x40; break; case float_round_to_zero: @@ -161,6 +162,7 @@ static int64 roundAndPackInt64( flag zSign, uint64_t absZ0, uint64_t absZ1 STATU roundNearestEven = ( roundingMode == float_round_nearest_even ); switch (roundingMode) { case float_round_nearest_even: +case float_round_ties_away: increment = ((int64_t) absZ1 0); break; case float_round_to_zero: @@ -214,6 +216,7 @@ static int64 roundAndPackUint64(flag zSign, uint64_t absZ0, roundNearestEven = (roundingMode == float_round_nearest_even); switch (roundingMode) { case float_round_nearest_even: +case float_round_ties_away: increment = ((int64_t)absZ1 0); break; case float_round_to_zero: @@ -366,6 +369,7 @@ static float32 roundAndPackFloat32(flag zSign, int_fast16_t zExp, uint32_t zSig roundNearestEven = ( roundingMode == float_round_nearest_even ); switch (roundingMode) { case float_round_nearest_even: +case float_round_ties_away: roundIncrement = 0x40; break; case float_round_to_zero: @@ -550,6 +554,7 @@ static float64 roundAndPackFloat64(flag zSign, int_fast16_t zExp, uint64_t zSig roundNearestEven = ( roundingMode == float_round_nearest_even ); switch (roundingMode) { case float_round_nearest_even: +case float_round_ties_away: roundIncrement = 0x200; break; case float_round_to_zero: @@ -734,6 +739,7 @@ static floatx80 zSig0 |= ( zSig1 != 0 ); switch (roundingMode) { case float_round_nearest_even: +case float_round_ties_away: break; case float_round_to_zero: roundIncrement = 0; @@ -794,6 +800,7 @@ static floatx80 precision80: switch (roundingMode) { case float_round_nearest_even: +case float_round_ties_away: increment = ((int64_t)zSig1 0); break; case float_round_to_zero: @@ -838,6 +845,7 @@ static floatx80 if ( zSig1 ) STATUS(float_exception_flags) |= float_flag_inexact; switch (roundingMode) { case float_round_nearest_even: +case float_round_ties_away: increment = ((int64_t)zSig1 0); break; case float_round_to_zero: @@ -1052,6 +1060,7 @@ static float128 roundNearestEven = ( roundingMode == float_round_nearest_even ); switch (roundingMode) { case float_round_nearest_even: +case float_round_ties_away: increment = ((int64_t)zSig2 0); break; case float_round_to_zero: @@ -1114,6 +1123,7 @@ static float128 if ( isTiny zSig2 ) float_raise( float_flag_underflow STATUS_VAR); switch (roundingMode) { case float_round_nearest_even: +case float_round_ties_away: increment = ((int64_t)zSig2 0); break; case float_round_to_zero: @@ -1785,6 +1795,11 @@ float32 float32_round_to_int( float32 a STATUS_PARAM) return packFloat32( aSign, 0x7F, 0 ); } break; +case float_round_ties_away: +if (aExp == 0x7E) { +return packFloat32(aSign, 0x7F, 0); +} +break; case float_round_down: return make_float32(aSign ? 0xBF80 : 0); case float_round_up: @@ -1803,6 +1818,9 @@ float32 float32_round_to_int( float32 a STATUS_PARAM) z = ~lastBitMask; } break; +case float_round_ties_away: +z += lastBitMask 1; +break; case float_round_to_zero: break; case float_round_up: @@ -3183,6 +3201,9 @@ static float32 roundAndPackFloat16(flag zSign, int_fast16_t
[Qemu-devel] [PATCH v2 02/24] softfloat: Add float to 16bit integer conversions.
From: Will Newton will.new...@linaro.org ARMv8 requires support for converting 32 and 64bit floating point values to signed and unsigned 16bit integers. Signed-off-by: Will Newton will.new...@linaro.org [PMM: updated not to incorrectly set Inexact for Invalid inputs] Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- fpu/softfloat.c | 80 + include/fpu/softfloat.h | 4 +++ 2 files changed, 84 insertions(+) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 6a6b656..dbaa32c 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -6491,6 +6491,46 @@ uint32 float32_to_uint32_round_to_zero( float32 a STATUS_PARAM ) return res; } +int_fast16_t float32_to_int16(float32 a STATUS_PARAM) +{ +int32_t v; +int_fast16_t res; +int old_exc_flags = get_float_exception_flags(status); + +v = float32_to_int32(a STATUS_VAR); +if (v -0x8000) { +res = -0x8000; +} else if (v 0x7fff) { +res = 0x7fff; +} else { +return v; +} + +set_float_exception_flags(old_exc_flags, status); +float_raise(float_flag_invalid STATUS_VAR); +return res; +} + +uint_fast16_t float32_to_uint16(float32 a STATUS_PARAM) +{ +int32_t v; +uint_fast16_t res; +int old_exc_flags = get_float_exception_flags(status); + +v = float32_to_int32(a STATUS_VAR); +if (v 0) { +res = 0; +} else if (v 0x) { +res = 0x; +} else { +return v; +} + +set_float_exception_flags(old_exc_flags, status); +float_raise(float_flag_invalid STATUS_VAR); +return res; +} + uint_fast16_t float32_to_uint16_round_to_zero(float32 a STATUS_PARAM) { int64_t v; @@ -6545,6 +6585,46 @@ uint32 float64_to_uint32_round_to_zero( float64 a STATUS_PARAM ) return res; } +int_fast16_t float64_to_int16(float64 a STATUS_PARAM) +{ +int64_t v; +int_fast16_t res; +int old_exc_flags = get_float_exception_flags(status); + +v = float64_to_int32(a STATUS_VAR); +if (v -0x8000) { +res = -0x8000; +} else if (v 0x7fff) { +res = 0x7fff; +} else { +return v; +} + +set_float_exception_flags(old_exc_flags, status); +float_raise(float_flag_invalid STATUS_VAR); +return res; +} + +uint_fast16_t float64_to_uint16(float64 a STATUS_PARAM) +{ +int64_t v; +uint_fast16_t res; +int old_exc_flags = get_float_exception_flags(status); + +v = float64_to_int32(a STATUS_VAR); +if (v 0) { +res = 0; +} else if (v 0x) { +res = 0x; +} else { +return v; +} + +set_float_exception_flags(old_exc_flags, status); +float_raise(float_flag_invalid STATUS_VAR); +return res; +} + uint_fast16_t float64_to_uint16_round_to_zero(float64 a STATUS_PARAM) { int64_t v; diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 2365274..a9b8cd9 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -265,6 +265,8 @@ extern const float16 float16_default_nan; /* | Software IEC/IEEE single-precision conversion routines. **/ +int_fast16_t float32_to_int16(float32 STATUS_PARAM); +uint_fast16_t float32_to_uint16(float32 STATUS_PARAM); int_fast16_t float32_to_int16_round_to_zero(float32 STATUS_PARAM); uint_fast16_t float32_to_uint16_round_to_zero(float32 STATUS_PARAM); int32 float32_to_int32( float32 STATUS_PARAM ); @@ -371,6 +373,8 @@ extern const float32 float32_default_nan; /* | Software IEC/IEEE double-precision conversion routines. **/ +int_fast16_t float64_to_int16(float64 STATUS_PARAM); +uint_fast16_t float64_to_uint16(float64 STATUS_PARAM); int_fast16_t float64_to_int16_round_to_zero(float64 STATUS_PARAM); uint_fast16_t float64_to_uint16_round_to_zero(float64 STATUS_PARAM); int32 float64_to_int32( float64 STATUS_PARAM ); -- 1.8.5
Re: [Qemu-devel] [PATCHv3 3/6] ui/vnc: optimize dirty bitmap tracking
On 06.01.2014 11:08, Wenchao Xia wrote: 于 2014/1/6 2:02, Peter Lieven 写道: vnc_update_client currently scans the dirty bitmap of each client bitwise which is a very costly operation if only few bits are dirty. vnc_refresh_server_surface does almost the same. this patch optimizes both by utilizing the heavily optimized function find_next_bit to find the offset of the next dirty bit in the dirty bitmaps. The following artifical test (just the bitmap operation part) running vnc_update_client 65536 times on a 2560x2048 surface illustrates the performance difference: All bits clean - vnc_update_client_new: 0.07 secs vnc_update_client_old: 10.98 secs All bits dirty - vnc_update_client_new: 11.26 secs vnc_update_client_old: 20.19 secs Few bits dirty - vnc_update_client_new: 0.08 secs vnc_update_client_old: 10.98 secs The case for all bits dirty is still rather slow, this is due to the implementation of find_and_clear_dirty_height. This will be addresses in a separate patch. Signed-off-by: Peter Lieven p...@kamp.de --- ui/vnc.c | 154 +- ui/vnc.h |4 ++ 2 files changed, 87 insertions(+), 71 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 1d2aa1a..6a0c03e 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -572,6 +572,14 @@ void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y) ptr += x * VNC_SERVER_FB_BYTES; return ptr; } +/* this sets only the visible pixels of a dirty bitmap */ +#define VNC_SET_VISIBLE_PIXELS_DIRTY(bitmap, w, h) {\ +int y;\ +memset(bitmap, 0x00, sizeof(bitmap));\ +for (y = 0; y h; y++) {\ +bitmap_set(bitmap[y], 0, w / VNC_DIRTY_PIXELS_PER_BIT);\ Will it be a problem when vnc's width % VNC_DIRTY_PIXELS_PER_BIT != 0? Although it is a rare case, but I think it is better round it up, since v and VNC_DIRTY_PIXELS_PER_BIT are variables. A macro computing it would be nice: Good point, I will use DIV_ROUND_UP here. #define VNC_DIRTY_BITS_FROM_WIDTH(w) (w + VNC_DIRTY_PIXELS_PER_BIT - 1/ VNC_DIRTY_PIXELS_PER_BIT) #define VNC_DIRTY_BITS (VNC_DIRTY_BITS_FROM_WIDTH(VNC_MAX_WIDTH) then here: bitmap_set(bitmap[y], 0, VNC_DIRTY_BITS_FROM_WIDTH(w)); Or simply warn or coredump when v % VNC_DIRTY_PIXELS_PER_BIT != 0. Also, in vnc.h: /* VNC_MAX_WIDTH must be a multiple of 16. */ #define VNC_MAX_WIDTH 2560 #define VNC_MAX_HEIGHT 2048 Maybe it should be updated as: /* VNC_MAX_WIDTH must be a multiple of VNC_DIRTY_PIXELS_PER_BIT. */ correct. will fix as well. +} \ +} static void vnc_dpy_switch(DisplayChangeListener *dcl, DisplaySurface *surface) @@ -597,7 +605,9 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl, qemu_pixman_image_unref(vd-guest.fb); vd-guest.fb = pixman_image_ref(surface-image); vd-guest.format = surface-format; -memset(vd-guest.dirty, 0xFF, sizeof(vd-guest.dirty)); +VNC_SET_VISIBLE_PIXELS_DIRTY(vd-guest.dirty, + surface_width(vd-ds), + surface_height(vd-ds)); QTAILQ_FOREACH(vs, vd-clients, next) { vnc_colordepth(vs); @@ -605,7 +615,9 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl, if (vs-vd-cursor) { vnc_cursor_define(vs); } -memset(vs-dirty, 0xFF, sizeof(vs-dirty)); +VNC_SET_VISIBLE_PIXELS_DIRTY(vs-dirty, + surface_width(vd-ds), + surface_height(vd-ds)); } } @@ -889,10 +901,9 @@ static int vnc_update_client(VncState *vs, int has_dirty) VncDisplay *vd = vs-vd; VncJob *job; int y; -int width, height; +int height; int n = 0; - if (vs-output.offset !vs-audio_cap !vs-force_update) /* kernel send buffers are full - drop frames to throttle */ return 0; @@ -908,39 +919,27 @@ static int vnc_update_client(VncState *vs, int has_dirty) */ job = vnc_job_new(vs); -width = MIN(pixman_image_get_width(vd-server), vs-client_width); height = MIN(pixman_image_get_height(vd-server), vs-client_height); -for (y = 0; y height; y++) { -int x; -int last_x = -1; -for (x = 0; x width / VNC_DIRTY_PIXELS_PER_BIT; x++) { -if (test_and_clear_bit(x, vs-dirty[y])) { -if (last_x == -1) { -last_x = x; -} -} else { -if (last_x != -1) { -int h = find_and_clear_dirty_height(vs, y, last_x, x, -height); - -n += vnc_job_add_rect(job, -
Re: [Qemu-devel] Project idea: make QEMU more flexible
On 6 January 2014 12:54, Wei Liu wei.l...@citrix.com wrote: In fact I've already hacked a prototype during Christmas. What's I've done so far: 1. create target-null which only has some stubs to CPU emulation framework. 2. add a few lines to configure / Makefiles*, create default-configs/null-softmmu I think it would be better to add support to allow you to configure with --disable-tcg. This would match the existing --disable/--enable switches for KVM and Xen, and then you could configure --disable-kvm --disable-tcg --enable-xen and get a qemu-system-i386 or qemu-system-arm with only the Xen support and none of the TCG emulation code. thanks -- PMM
[Qemu-devel] [PULL 28/52] target-arm: Use VFP_BINOP macro for min, max, minnum, maxnum
Use the VFP_BINOP macro to provide helpers for min, max, minnum and maxnum, rather than hand-rolling them. (The float64 max version is not used by A32 but will be needed for A64.) Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/helper.c | 29 - target-arm/helper.h | 15 --- target-arm/neon_helper.c | 12 target-arm/translate.c | 16 4 files changed, 20 insertions(+), 52 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index e7d88ea..74042b8 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -3864,6 +3864,10 @@ VFP_BINOP(add) VFP_BINOP(sub) VFP_BINOP(mul) VFP_BINOP(div) +VFP_BINOP(min) +VFP_BINOP(max) +VFP_BINOP(minnum) +VFP_BINOP(maxnum) #undef VFP_BINOP float32 VFP_HELPER(neg, s)(float32 a) @@ -4317,28 +4321,3 @@ float64 VFP_HELPER(muladd, d)(float64 a, float64 b, float64 c, void *fpstp) float_status *fpst = fpstp; return float64_muladd(a, b, c, 0, fpst); } - -/* ARMv8 VMAXNM/VMINNM */ -float32 VFP_HELPER(maxnm, s)(float32 a, float32 b, void *fpstp) -{ -float_status *fpst = fpstp; -return float32_maxnum(a, b, fpst); -} - -float64 VFP_HELPER(maxnm, d)(float64 a, float64 b, void *fpstp) -{ -float_status *fpst = fpstp; -return float64_maxnum(a, b, fpst); -} - -float32 VFP_HELPER(minnm, s)(float32 a, float32 b, void *fpstp) -{ -float_status *fpst = fpstp; -return float32_minnum(a, b, fpst); -} - -float64 VFP_HELPER(minnm, d)(float64 a, float64 b, void *fpstp) -{ -float_status *fpst = fpstp; -return float64_minnum(a, b, fpst); -} diff --git a/target-arm/helper.h b/target-arm/helper.h index 73d67dc..dd1160e 100644 --- a/target-arm/helper.h +++ b/target-arm/helper.h @@ -79,6 +79,14 @@ DEF_HELPER_3(vfp_muls, f32, f32, f32, ptr) DEF_HELPER_3(vfp_muld, f64, f64, f64, ptr) DEF_HELPER_3(vfp_divs, f32, f32, f32, ptr) DEF_HELPER_3(vfp_divd, f64, f64, f64, ptr) +DEF_HELPER_3(vfp_maxs, f32, f32, f32, ptr) +DEF_HELPER_3(vfp_maxd, f64, f64, f64, ptr) +DEF_HELPER_3(vfp_mins, f32, f32, f32, ptr) +DEF_HELPER_3(vfp_mind, f64, f64, f64, ptr) +DEF_HELPER_3(vfp_maxnums, f32, f32, f32, ptr) +DEF_HELPER_3(vfp_maxnumd, f64, f64, f64, ptr) +DEF_HELPER_3(vfp_minnums, f32, f32, f32, ptr) +DEF_HELPER_3(vfp_minnumd, f64, f64, f64, ptr) DEF_HELPER_1(vfp_negs, f32, f32) DEF_HELPER_1(vfp_negd, f64, f64) DEF_HELPER_1(vfp_abss, f32, f32) @@ -132,11 +140,6 @@ DEF_HELPER_2(neon_fcvt_f32_to_f16, i32, f32, env) DEF_HELPER_4(vfp_muladdd, f64, f64, f64, f64, ptr) DEF_HELPER_4(vfp_muladds, f32, f32, f32, f32, ptr) -DEF_HELPER_3(vfp_maxnmd, f64, f64, f64, ptr) -DEF_HELPER_3(vfp_maxnms, f32, f32, f32, ptr) -DEF_HELPER_3(vfp_minnmd, f64, f64, f64, ptr) -DEF_HELPER_3(vfp_minnms, f32, f32, f32, ptr) - DEF_HELPER_3(recps_f32, f32, f32, f32, env) DEF_HELPER_3(rsqrts_f32, f32, f32, f32, env) DEF_HELPER_2(recpe_f32, f32, f32, env) @@ -346,8 +349,6 @@ DEF_HELPER_2(neon_qneg_s8, i32, env, i32) DEF_HELPER_2(neon_qneg_s16, i32, env, i32) DEF_HELPER_2(neon_qneg_s32, i32, env, i32) -DEF_HELPER_3(neon_min_f32, i32, i32, i32, ptr) -DEF_HELPER_3(neon_max_f32, i32, i32, i32, ptr) DEF_HELPER_3(neon_abd_f32, i32, i32, i32, ptr) DEF_HELPER_3(neon_ceq_f32, i32, i32, i32, ptr) DEF_HELPER_3(neon_cge_f32, i32, i32, i32, ptr) diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c index b028cc2..be6fbd9 100644 --- a/target-arm/neon_helper.c +++ b/target-arm/neon_helper.c @@ -1765,18 +1765,6 @@ uint32_t HELPER(neon_qneg_s32)(CPUARMState *env, uint32_t x) } /* NEON Float helpers. */ -uint32_t HELPER(neon_min_f32)(uint32_t a, uint32_t b, void *fpstp) -{ -float_status *fpst = fpstp; -return float32_val(float32_min(make_float32(a), make_float32(b), fpst)); -} - -uint32_t HELPER(neon_max_f32)(uint32_t a, uint32_t b, void *fpstp) -{ -float_status *fpst = fpstp; -return float32_val(float32_max(make_float32(a), make_float32(b), fpst)); -} - uint32_t HELPER(neon_abd_f32)(uint32_t a, uint32_t b, void *fpstp) { float_status *fpst = fpstp; diff --git a/target-arm/translate.c b/target-arm/translate.c index 4387547..d04fc9f 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -2725,9 +2725,9 @@ static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn, tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn)); tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm)); if (vmin) { -gen_helper_vfp_minnmd(dest, frn, frm, fpst); +gen_helper_vfp_minnumd(dest, frn, frm, fpst); } else { -gen_helper_vfp_maxnmd(dest, frn, frm, fpst); +gen_helper_vfp_maxnumd(dest, frn, frm, fpst); } tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd)); tcg_temp_free_i64(frn); @@ -2743,9 +2743,9 @@ static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn, tcg_gen_ld_f32(frn, cpu_env,
[Qemu-devel] [PULL 11/52] target-arm: Pull add one cpreg to hashtable into its own function
define_one_arm_cp_reg_with_opaque() has a set of nested loops which insert a cpreg entry into the hashtable for each of the possible opc/crn/crm values allowed by wildcard specifications. We're about to add an extra loop to this nesting, so pull the core of the loop (which adds a single entry to the hashtable) out into its own function for clarity. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/helper.c | 94 + 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index 6ebd7dc..d833163 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1937,6 +1937,57 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp) return cpu_list; } +static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r, + void *opaque, int crm, int opc1, int opc2) +{ +/* Private utility function for define_one_arm_cp_reg_with_opaque(): + * add a single reginfo struct to the hash table. + */ +uint32_t *key = g_new(uint32_t, 1); +ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo)); +int is64 = (r-type ARM_CP_64BIT) ? 1 : 0; +*key = ENCODE_CP_REG(r-cp, is64, r-crn, crm, opc1, opc2); +if (opaque) { +r2-opaque = opaque; +} +/* Make sure reginfo passed to helpers for wildcarded regs + * has the correct crm/opc1/opc2 for this reg, not CP_ANY: + */ +r2-crm = crm; +r2-opc1 = opc1; +r2-opc2 = opc2; +/* By convention, for wildcarded registers only the first + * entry is used for migration; the others are marked as + * NO_MIGRATE so we don't try to transfer the register + * multiple times. Special registers (ie NOP/WFI) are + * never migratable. + */ +if ((r-type ARM_CP_SPECIAL) || +((r-crm == CP_ANY) crm != 0) || +((r-opc1 == CP_ANY) opc1 != 0) || +((r-opc2 == CP_ANY) opc2 != 0)) { +r2-type |= ARM_CP_NO_MIGRATE; +} + +/* Overriding of an existing definition must be explicitly + * requested. + */ +if (!(r-type ARM_CP_OVERRIDE)) { +ARMCPRegInfo *oldreg; +oldreg = g_hash_table_lookup(cpu-cp_regs, key); +if (oldreg !(oldreg-type ARM_CP_OVERRIDE)) { +fprintf(stderr, Register redefined: cp=%d %d bit +crn=%d crm=%d opc1=%d opc2=%d, +was %s, now %s\n, r2-cp, 32 + 32 * is64, +r2-crn, r2-crm, r2-opc1, r2-opc2, +oldreg-name, r2-name); +g_assert_not_reached(); +} +} +g_hash_table_insert(cpu-cp_regs, key, r2); +} + + void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu, const ARMCPRegInfo *r, void *opaque) { @@ -1977,48 +2028,7 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu, for (crm = crmmin; crm = crmmax; crm++) { for (opc1 = opc1min; opc1 = opc1max; opc1++) { for (opc2 = opc2min; opc2 = opc2max; opc2++) { -uint32_t *key = g_new(uint32_t, 1); -ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo)); -int is64 = (r-type ARM_CP_64BIT) ? 1 : 0; -*key = ENCODE_CP_REG(r-cp, is64, r-crn, crm, opc1, opc2); -if (opaque) { -r2-opaque = opaque; -} -/* Make sure reginfo passed to helpers for wildcarded regs - * has the correct crm/opc1/opc2 for this reg, not CP_ANY: - */ -r2-crm = crm; -r2-opc1 = opc1; -r2-opc2 = opc2; -/* By convention, for wildcarded registers only the first - * entry is used for migration; the others are marked as - * NO_MIGRATE so we don't try to transfer the register - * multiple times. Special registers (ie NOP/WFI) are - * never migratable. - */ -if ((r-type ARM_CP_SPECIAL) || -((r-crm == CP_ANY) crm != 0) || -((r-opc1 == CP_ANY) opc1 != 0) || -((r-opc2 == CP_ANY) opc2 != 0)) { -r2-type |= ARM_CP_NO_MIGRATE; -} - -/* Overriding of an existing definition must be explicitly - * requested. - */ -if (!(r-type ARM_CP_OVERRIDE)) { -ARMCPRegInfo *oldreg; -oldreg = g_hash_table_lookup(cpu-cp_regs, key); -if (oldreg !(oldreg-type ARM_CP_OVERRIDE)) { -fprintf(stderr, Register redefined: cp=%d %d bit -crn=%d crm=%d opc1=%d opc2=%d, -was %s, now %s\n, r2-cp, 32 + 32 * is64, -r2-crn,