Re: [Qemu-devel] [PATCH v0 0/7] Background snapshots
On Mon, Aug 13, 2018 at 08:00:19PM +0100, Dr. David Alan Gilbert wrote: > cc'ing in Mike*2 > * Denis Plotnikov (dplotni...@virtuozzo.com) wrote: > > > > > > On 26.07.2018 12:23, Peter Xu wrote: > > > On Thu, Jul 26, 2018 at 10:51:33AM +0200, Paolo Bonzini wrote: > > > > On 25/07/2018 22:04, Andrea Arcangeli wrote: > > > > > > > > > > It may look like the uffd-wp model is wish-feature similar to an > > > > > optimization, but without the uffd-wp model when the WP fault is > > > > > triggered by kernel code, the sigsegv model falls apart and requires > > > > > all kind of ad-hoc changes just for this single feature. Plus uffd-wp > > > > > has other benefits: it makes it all reliable in terms of not > > > > > increasing the number of vmas in use during the snapshot. Finally it > > > > > makes it faster too with no mmap_sem for reading and no sigsegv > > > > > signals. > > > > > > > > > > The non cooperative features got merged first because there was much > > > > > activity on the kernel side on that front, but this is just an ideal > > > > > time to nail down the remaining issues in uffd-wp I think. That I > > > > > believe is time better spent than trying to emulate it with sigsegv > > > > > and changing all drivers to send new events down to qemu specific to > > > > > the sigsegv handling. We considered this before doing uffd for > > > > > postcopy too but overall it's unreliable and more work (no single > > > > > change was then needed to KVM code with uffd to handle postcopy and > > > > > here it should be the same). > > > > > > > > I totally agree. The hard part in userfaultfd was the changes to the > > > > kernel get_user_pages API, but the payback was huge because _all_ kernel > > > > uses (KVM, vhost-net, syscalls, etc.) just work with userfaultfd. Going > > > > back to mprotect would be a huge mistake. > > > > > > Thanks for explaining the bits. I'd say I wasn't aware of the > > > difference before I started the investigation (and only until now I > > > noticed that major difference between mprotect and userfaultfd). I'm > > > really glad that it's much clear (at least for me) on which way we > > > should choose. > > > > > > Now I'm thinking whether we can move the userfault write protect work > > > forward. The latest discussion I saw so far is in 2016, when someone > > > from Huawei tried to use the write protect feature for that old > > > version of live snapshot but reported issue: > > > > > >https://lists.gnu.org/archive/html/qemu-devel/2016-12/msg01127.html > > > > > > Is that the latest status for userfaultfd wr-protect? > > > > > > If so, I'm thinking whether I can try to re-verify the work (I tried > > > his QEMU repository but I failed to compile somehow, so I plan to > > > write some even simpler code to try) to see whether I can get the same > > > KVM error he encountered. > > > > > > Thoughts? > > > > Just to sum up all being said before. > > > > Using mprotect is a bad idea because VM's memory can be accessed from the > > number of places (KVM, vhost, ...) which need their own special care > > of tracking memory accesses and notifying QEMU which makes the mprotect > > using unacceptable. > > > > Protected memory accesses tracking can be done via userfaultfd's WP mode > > which isn't available right now. > > > > So, the reasonable conclusion is to wait until the WP mode is available and > > build the background snapshot on top of userfaultfd-wp. > > But, works on adding the WP-mode is pending for a quite a long time already. > > > > Is there any way to estimate when it could be available? > > I think a question is whether anyone is actively working on it; I > suspect really it's on a TODO list rather than moving at the moment. > > What I don't really understand is what stage the last version got upto. I'm still testing that tree (though due to some reason I haven't yet continued... but I will; currently WP still not working in my test). My plan is that I'll try to dig into the WP work if it does not work as expected (after I'm sure there's nothing wrong with the userspace), though that of course won't be a trivial task. I'll see how far I can go with it. Anyone that would like to help with that would be greatly welcomed too. Regards, -- Peter Xu
Re: [Qemu-devel] [PATCH 2/4] tests: fix bdrv-drain leak
Max Reitz writes: > On 2018-08-13 08:15, Markus Armbruster wrote: >> Max Reitz writes: >> >>> On 2018-08-10 08:28, Markus Armbruster wrote: Marc-André Lureau writes: > Spotted by ASAN: > > = > ==5378==ERROR: LeakSanitizer: detected memory leaks > > Direct leak of 65536 byte(s) in 1 object(s) allocated from: > #0 0x7f788f83bc48 in malloc (/lib64/libasan.so.5+0xeec48) > #1 0x7f788c9923c5 in g_malloc (/lib64/libglib-2.0.so.0+0x523c5) > #2 0x5622a1fe37bc in coroutine_trampoline > /home/elmarco/src/qq/util/coroutine-ucontext.c:116 > #3 0x7f788a15d75f in __correctly_grouped_prefixwc > (/lib64/libc.so.6+0x4c75f) > > Signed-off-by: Marc-André Lureau > --- > tests/test-bdrv-drain.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c > index 17bb8508ae..abc8bbe6f0 100644 > --- a/tests/test-bdrv-drain.c > +++ b/tests/test-bdrv-drain.c > @@ -948,6 +948,7 @@ static void coroutine_fn test_co_delete_by_drain(void > *opaque) > } > > dbdd->done = true; > +g_free(buffer); > } > > /** Screwed up in commit 4c8158e359d. Max, could the coroutine's stack accomodate the buffer? >>> >>> I don't know. How big is a coroutine's stack? The buffer size >>> apparently is 64k. (Which is my opinion is generally too much to put on >>> any stack.) >> >> Even in tests? > > You have a point, but why do things differently in tests for no reason? > > (So I don't leak memory, yeah, sure, but why not write the test in Rust > then from the start? O:-P) Only 230 days to April 1st, better hurry. >>> But why would you want to put it on the stack anyway? It's not like it >>> would make the patch any simpler. >> >> If you like the patch as is, go merge it as is :) > > W-well, I wasn't CC-d! I fixed that :) > I take this as a request to take this one patch from the series and > merge it into my tree, so I will do that. O:-) Thanks!
[Qemu-devel] [Bug 1463143] Re: Kernel Panic on Guest VM
[Expired for QEMU because there has been no activity for 60 days.] ** Changed in: qemu Status: Incomplete => Expired -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1463143 Title: Kernel Panic on Guest VM Status in QEMU: Expired Bug description: Hi, I've recently attempted to move a stack to qemu vm's that I have run successfully on both hard metal and ec2. I'm not sure where to even begin debugging, could someone please point me in the right direction? [781785.483343] RIP: 0010:[] [] ata_sff_hsm_move+0x1b0/0x780 [781785.483345] RSP: :88007fd03dd0 EFLAGS: 00010097 [781785.483346] RAX: RBX: 8800374d RCX: 0050 [781785.483347] RDX: 0006 RSI: 8800374d0158 RDI: 8800374d [781785.483348] RBP: 88007fd03e20 R08: 0086 R09: 88007cc0 [781785.483349] R10: 0011 R11: 000b R12: 8800374d0158 [781785.483350] R13: R14: 8800374d0158 R15: 8800374d0208 [781785.483356] FS: 7f3882e75700() GS:88007fd0() knlGS: [781785.483357] CS: 0010 DS: ES: CR0: 80050033 [781785.483358] CR2: 7f37df39a000 CR3: 0b7a5000 CR4: 06e0 [781785.483369] Stack: [781785.483373] 8800373cb000 88007fd03e60 8108d7d2 88007fd03e28 [781785.483375] 8800374d2140 8800374d 8800374d0158 [781785.483378] 0050 88007fd03e50 81511e96 [781785.483378] Call Trace: [781785.483382] [781785.483396] [] ? run_posix_cpu_timers+0x42/0x5c0 [781785.483400] [] __ata_sff_port_intr+0x96/0x120 [781785.483403] [] ata_bmdma_port_intr+0x2d/0x120 [781785.483405] [] ata_bmdma_interrupt+0x183/0x1e0 [781785.483414] [] handle_irq_event_percpu+0x3e/0x1d0 [781785.483433] [] handle_irq_event+0x3d/0x60 [781785.483437] [] handle_edge_irq+0x77/0x130 [781785.483455] [] handle_irq+0x1e/0x30 [781785.483472] [] do_IRQ+0x4d/0xc0 [781785.483476] [] common_interrupt+0x6d/0x6d [781785.483478] [781785.483480] [] ? system_call_fastpath+0x1a/0x1f [781785.483498] Code: f9 ff ff 41 0f b6 46 28 3c 06 0f 84 0b 03 00 00 3c 07 0f 84 e3 02 00 00 3c 05 0f 84 c3 02 00 00 0f 0b 66 0f 1f 84 00 00 00 00 00 <0f> 0b 66 0f 1f 44 00 00 f6 c1 08 0f 84 19 05 00 00 f6 c1 21 0f [781785.483501] RIP [] ata_sff_hsm_move+0x1b0/0x780 [781785.483501] RSP [781785.484009] ---[ end trace 1b6ef3497a5641b3 ]--- [781785.484009] Kernel panic - not syncing: Fatal exception in interrupt [781785.484009] Shutting down cpus with NMI Thanks for any pointers. Ryan To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1463143/+subscriptions
[Qemu-devel] [Bug 1463463] Re: PCI devices on PCI to PCI bridges stopped being accessable from Xen with QEMU 2.3.0
[Expired for QEMU because there has been no activity for 60 days.] ** Changed in: qemu Status: Incomplete => Expired -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1463463 Title: PCI devices on PCI to PCI bridges stopped being accessable from Xen with QEMU 2.3.0 Status in QEMU: Expired Bug description: The change set: commit 3996e85c1822e05c50250f8d2d1e57b6bea1229d Author: Paul Durrant Date: Tue Jan 20 11:06:19 2015 + Xen: Use the ioreq-server API when available ... Added calls to xen_map_pcidev() when available. However these call are only done at startup, not when the guest configures the PCI to PCI bridge. So Xen 4.5.0 (which has these) using a QEMU 2.3.0 or later can no longer access PCI devices that are not on a root bridge. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1463463/+subscriptions
[Qemu-devel] [Bug 1462944] Re: vpc file causes qemu-img to consume lots of time and memory
[Expired for QEMU because there has been no activity for 60 days.] ** Changed in: qemu Status: Incomplete => Expired -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1462944 Title: vpc file causes qemu-img to consume lots of time and memory Status in QEMU: Expired Bug description: The attached vpc file causes 'qemu-img info' to consume 3 or 4 seconds of CPU time and 1.3 GB of heap, causing a minor denial of service. $ /usr/bin/time ~/d/qemu/qemu-img info afl12.img block-vpc: The header checksum of 'afl12.img' is incorrect. qemu-img: Could not open 'afl12.img': block-vpc: free_data_block_offset points after the end of file. The image has been truncated. 1.19user 3.15system 0:04.35elapsed 99%CPU (0avgtext+0avgdata 1324504maxresident)k 0inputs+0outputs (0major+327314minor)pagefaults 0swaps The file was found using american-fuzzy-lop. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1462944/+subscriptions
[Qemu-devel] [Bug 1437367] Re: Qemu guest fails to write files with raw disk (like \\.\PhysicalDrive1) on Windows host.
[Expired for QEMU because there has been no activity for 60 days.] ** Changed in: qemu Status: Incomplete => Expired -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1437367 Title: Qemu guest fails to write files with raw disk (like \\.\PhysicalDrive1) on Windows host. Status in QEMU: Expired Bug description: Qemu guest fails to write files with specifing raw disk like \\.\PhysicalDrive1 full command line is below. qemu-sysytem-i386.exe -kernel bzImage -drive file=rootfs.ext2,index=0,if=scsi -append root=/dev/sda -drive file=\\.\PhysicalDrive1,index=1,if=scsi I found the reason is below aio_worker returns -EIO when flush operation. https://github.com/qemu/qemu/blob/master/block/raw-win32.c#L95 static int aio_worker(void *arg) ... case QEMU_AIO_FLUSH: if (!FlushFileBuffers(aiocb->hfile)) { return -EIO; } FlushFileBuffers always fails with GetLastError() == ERROR_INVALID_FUNCTION I think this function doesn't support raw device. For flushing, you might have to issue scsi/ata command or use another way. Trying to just ignoring this error, writing function seems to be fine for me. Thanks hiroaki To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1437367/+subscriptions
Re: [Qemu-devel] [Qemu-arm] [PATCH v5 6/6] Add QTest testcase for the Intel Hexadecimal
Hi Su, Stefan, On 08/13/2018 03:46 PM, Stefan Hajnoczi wrote: > From: Su Hang > > 'test.hex' file is a memory test pattern stored in Hexadecimal Object > Format. It loads at 0x1 in RAM and contains values from 0 through > 255. Please add this comment in the source file. > > The test case verifies that the expected memory test pattern was loaded. > > Reviewed-by: Stefan Hajnoczi > Suggested-by: Steffen Gortz > Suggested-by: Stefan Hajnoczi > Signed-off-by: Su Hang > Signed-off-by: Stefan Hajnoczi > --- > MAINTAINERS | 6 > configure| 4 +++ > tests/Makefile.include | 2 ++ > tests/hexloader-test.c | 41 > tests/hex-loader-check-data/test.hex | 18 > 5 files changed, 71 insertions(+) > create mode 100644 tests/hexloader-test.c > create mode 100644 tests/hex-loader-check-data/test.hex > > diff --git a/MAINTAINERS b/MAINTAINERS > index 666e936812..c48d9271cf 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -1323,6 +1323,12 @@ F: hw/core/generic-loader.c > F: include/hw/core/generic-loader.h > F: docs/generic-loader.txt > > +Intel Hexadecimal Object File Loader > +M: Su Hang > +S: Maintained > +F: tests/hexloader-test.c > +F: tests/hex-loader-check-data/test.hex > + > CHRP NVRAM > M: Thomas Huth > S: Maintained > diff --git a/configure b/configure > index 2a7796ea80..db97930314 100755 > --- a/configure > +++ b/configure > @@ -7382,6 +7382,10 @@ for test_file in $(find > $source_path/tests/acpi-test-data -type f) > do > FILES="$FILES tests/acpi-test-data$(echo $test_file | sed -e > 's/.*acpi-test-data//')" > done > +for test_file in $(find $source_path/tests/hex-loader-check-data -type f) > +do > +FILES="$FILES tests/hex-loader-check-data$(echo $test_file | sed -e > 's/.*hex-loader-check-data//')" > +done > mkdir -p $DIRS > for f in $FILES ; do > if [ -e "$source_path/$f" ] && [ "$pwd_is_source_path" != "y" ]; then > diff --git a/tests/Makefile.include b/tests/Makefile.include > index a49282704e..760a0f18b6 100644 > --- a/tests/Makefile.include > +++ b/tests/Makefile.include > @@ -386,6 +386,7 @@ check-qtest-arm-y += tests/test-arm-mptimer$(EXESUF) > gcov-files-arm-y += hw/timer/arm_mptimer.c > check-qtest-arm-y += tests/boot-serial-test$(EXESUF) > check-qtest-arm-y += tests/sdhci-test$(EXESUF) > +check-qtest-arm-y += tests/hexloader-test$(EXESUF) > > check-qtest-aarch64-y = tests/numa-test$(EXESUF) > check-qtest-aarch64-y += tests/sdhci-test$(EXESUF) > @@ -773,6 +774,7 @@ tests/qmp-test$(EXESUF): tests/qmp-test.o > tests/device-introspect-test$(EXESUF): tests/device-introspect-test.o > tests/rtc-test$(EXESUF): tests/rtc-test.o > tests/m48t59-test$(EXESUF): tests/m48t59-test.o > +tests/hexloader-test$(EXESUF): tests/hexloader-test.o > tests/endianness-test$(EXESUF): tests/endianness-test.o > tests/spapr-phb-test$(EXESUF): tests/spapr-phb-test.o $(libqos-obj-y) > tests/prom-env-test$(EXESUF): tests/prom-env-test.o $(libqos-obj-y) > diff --git a/tests/hexloader-test.c b/tests/hexloader-test.c > new file mode 100644 > index 00..90e470e9db > --- /dev/null > +++ b/tests/hexloader-test.c > @@ -0,0 +1,41 @@ > +/* > + * QTest testcase for the Intel Hexadecimal Object File Loader > + * > + * Authors: > + * Su Hang 2018 > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or later. > + * See the COPYING file in the top-level directory. > + * > + */ > + > +#include "qemu/osdep.h" > +#include "libqtest.h" > + > +/* success if no crash or abort */ ... 'test.hex' file is a memory test pattern stored in Hexadecimal Object Format. It loads at 0x1 in RAM and contains values from 0 through 255. Funny =) Reviewed-by: Philippe Mathieu-Daudé > +static void hex_loader_test(void) > +{ > +unsigned int i; > +const unsigned int base_addr = 0x0001; > + > +QTestState *s = qtest_startf( > +"-M vexpress-a9 -nographic -device > loader,file=tests/hex-loader-check-data/test.hex"); > + > +for (i = 0; i < 256; ++i) { > +uint8_t val = qtest_readb(s, base_addr + i); > +g_assert_cmpuint(i, ==, val); > +} > +qtest_quit(s); > +} > + > +int main(int argc, char **argv) > +{ > +int ret; > + > +g_test_init(, , NULL); > + > +qtest_add_func("/tmp/hex_loader", hex_loader_test); > +ret = g_test_run(); > + > +return ret; > +} > diff --git a/tests/hex-loader-check-data/test.hex > b/tests/hex-loader-check-data/test.hex > new file mode 100644 > index 00..008a90bd4d > --- /dev/null > +++ b/tests/hex-loader-check-data/test.hex > @@ -0,0 +1,18 @@ > +:02040001F9 > +:100102030405060708090a0b0c0d0e0f78 > +:10001000101112131415161718191a1b1c1d1e1f68 > +:10002000202122232425262728292a2b2c2d2e2f58 > +:10003000303132333435363738393a3b3c3d3e3f48 > +:10004000404142434445464748494a4b4c4d4e4f38 > +:10005000505152535455565758595a5b5c5d5e5f28 >
Re: [Qemu-devel] [PATCH 03/17] mirror: Pull *_align_for_copy() from *_co_read()
On Mon, Aug 13, 2018 at 04:19:52AM +0200, Max Reitz wrote: > Signed-off-by: Max Reitz Reviewed-by: Jeff Cody > --- > block/mirror.c | 54 +- > 1 file changed, 36 insertions(+), 18 deletions(-) > > diff --git a/block/mirror.c b/block/mirror.c > index c28b6159d5..34cb8293b2 100644 > --- a/block/mirror.c > +++ b/block/mirror.c > @@ -305,42 +305,60 @@ static inline void coroutine_fn > mirror_co_wait_for_any_operation(s, false); > } > > -/* Perform a mirror copy operation. > +/* > + * Restrict *bytes to how much we can actually handle, and align the > + * [*offset, *bytes] range to clusters if COW is needed. > * > - * *op->bytes_handled is set to the number of bytes copied after and > + * *bytes_handled is set to the number of bytes copied after and > * including offset, excluding any bytes copied prior to offset due > - * to alignment. This will be op->bytes if no alignment is necessary, > - * or (new_end - op->offset) if the tail is rounded up or down due to > + * to alignment. This will be *bytes if no alignment is necessary, or > + * (new_end - *offset) if the tail is rounded up or down due to > * alignment or buffer limit. > */ > -static void coroutine_fn mirror_co_read(void *opaque) > +static void mirror_align_for_copy(MirrorBlockJob *s, > + int64_t *offset, uint64_t *bytes, > + int64_t *bytes_handled) > { > -MirrorOp *op = opaque; > -MirrorBlockJob *s = op->s; > -int nb_chunks; > -uint64_t ret; > uint64_t max_bytes; > > max_bytes = s->granularity * s->max_iov; > > /* We can only handle as much as buf_size at a time. */ > -op->bytes = MIN(s->buf_size, MIN(max_bytes, op->bytes)); > -assert(op->bytes); > -assert(op->bytes < BDRV_REQUEST_MAX_BYTES); > -*op->bytes_handled = op->bytes; > +*bytes = MIN(s->buf_size, MIN(max_bytes, *bytes)); > +assert(*bytes); > +assert(*bytes < BDRV_REQUEST_MAX_BYTES); > +*bytes_handled = *bytes; > > if (s->cow_bitmap) { > -*op->bytes_handled += mirror_cow_align(s, >offset, >bytes); > +*bytes_handled += mirror_cow_align(s, offset, bytes); > } > /* Cannot exceed BDRV_REQUEST_MAX_BYTES + INT_MAX */ > -assert(*op->bytes_handled <= UINT_MAX); > -assert(op->bytes <= s->buf_size); > +assert(*bytes_handled <= UINT_MAX); > +assert(*bytes <= s->buf_size); > /* The offset is granularity-aligned because: > * 1) Caller passes in aligned values; > * 2) mirror_cow_align is used only when target cluster is larger. */ > -assert(QEMU_IS_ALIGNED(op->offset, s->granularity)); > +assert(QEMU_IS_ALIGNED(*offset, s->granularity)); > /* The range is sector-aligned, since bdrv_getlength() rounds up. */ > -assert(QEMU_IS_ALIGNED(op->bytes, BDRV_SECTOR_SIZE)); > +assert(QEMU_IS_ALIGNED(*bytes, BDRV_SECTOR_SIZE)); > +} > + > +/* Perform a mirror copy operation. > + * > + * *op->bytes_handled is set to the number of bytes copied after and > + * including offset, excluding any bytes copied prior to offset due > + * to alignment. This will be op->bytes if no alignment is necessary, > + * or (new_end - op->offset) if the tail is rounded up or down due to > + * alignment or buffer limit. > + */ > +static void coroutine_fn mirror_co_read(void *opaque) > +{ > +MirrorOp *op = opaque; > +MirrorBlockJob *s = op->s; > +int nb_chunks; > +uint64_t ret; > + > +mirror_align_for_copy(s, >offset, >bytes, op->bytes_handled); > nb_chunks = DIV_ROUND_UP(op->bytes, s->granularity); > > while (s->buf_free_count < nb_chunks) { > -- > 2.17.1 >
Re: [Qemu-devel] [PATCH 01/17] iotests: Try reading while mirroring in 156
On Mon, Aug 13, 2018 at 04:19:50AM +0200, Max Reitz wrote: > Currently, we never test whether we can read from the source while > mirroring (that means, whether we can read from the mirror BDS). Add > such a test to 156 because it fits well. > > Signed-off-by: Max Reitz Reviewed-by: Jeff Cody > --- > tests/qemu-iotests/156 | 7 +++ > tests/qemu-iotests/156.out | 3 +++ > 2 files changed, 10 insertions(+) > > diff --git a/tests/qemu-iotests/156 b/tests/qemu-iotests/156 > index 0a9a09802e..99f7326158 100755 > --- a/tests/qemu-iotests/156 > +++ b/tests/qemu-iotests/156 > @@ -106,6 +106,13 @@ _send_qemu_cmd $QEMU_HANDLE \ >'qemu-io source \"write -P 4 192k 64k\"' } }" \ > 'return' > > +# Read it back (proving that we can read while mirroring) > +_send_qemu_cmd $QEMU_HANDLE \ > +"{ 'execute': 'human-monitor-command', > + 'arguments': { 'command-line': > + 'qemu-io source \"read -P 4 192k 64k\"' } }" \ > +'return' > + > # Copy source backing chain to the target before completing the job > cp "$TEST_IMG.backing" "$TEST_IMG.target.backing" > cp "$TEST_IMG" "$TEST_IMG.target" > diff --git a/tests/qemu-iotests/156.out b/tests/qemu-iotests/156.out > index 34c057b626..a591bd3a1e 100644 > --- a/tests/qemu-iotests/156.out > +++ b/tests/qemu-iotests/156.out > @@ -20,6 +20,9 @@ Formatting 'TEST_DIR/t.IMGFMT.target.overlay', fmt=IMGFMT > size=1048576 backing_f > wrote 65536/65536 bytes at offset 196608 > 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) > {"return": ""} > +read 65536/65536 bytes at offset 196608 > +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) > +{"return": ""} > {"return": {}} > {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": > "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "source"}} > {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": > "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "source"}} > -- > 2.17.1 >
Re: [Qemu-devel] [PATCH 02/17] mirror: Make wait_for_any_operation() coroutine_fn
On Mon, Aug 13, 2018 at 04:19:51AM +0200, Max Reitz wrote: > mirror_wait_for_any_operation() calls qemu_co_queue_wait(), which is a > coroutine_fn (technically it is a macro which resolves to a > coroutine_fn). Therefore, this function needs to be a coroutine_fn as > well. > > This patch makes it and all of its callers coroutine_fns. > It'd be nice if someday coroutine_fn was actually functional during compile. We can dream :) > Signed-off-by: Max Reitz Reviewed-by: Jeff Cody > --- > block/mirror.c | 30 -- > 1 file changed, 16 insertions(+), 14 deletions(-) > > diff --git a/block/mirror.c b/block/mirror.c > index 85f5742eae..c28b6159d5 100644 > --- a/block/mirror.c > +++ b/block/mirror.c > @@ -279,7 +279,8 @@ static int mirror_cow_align(MirrorBlockJob *s, int64_t > *offset, > return ret; > } > > -static inline void mirror_wait_for_any_operation(MirrorBlockJob *s, bool > active) > +static inline void coroutine_fn > +mirror_co_wait_for_any_operation(MirrorBlockJob *s, bool active) > { > MirrorOp *op; > > @@ -297,10 +298,11 @@ static inline void > mirror_wait_for_any_operation(MirrorBlockJob *s, bool active) > abort(); > } > > -static inline void mirror_wait_for_free_in_flight_slot(MirrorBlockJob *s) > +static inline void coroutine_fn > +mirror_co_wait_for_free_in_flight_slot(MirrorBlockJob *s) > { > /* Only non-active operations use up in-flight slots */ > -mirror_wait_for_any_operation(s, false); > +mirror_co_wait_for_any_operation(s, false); > } > > /* Perform a mirror copy operation. > @@ -343,7 +345,7 @@ static void coroutine_fn mirror_co_read(void *opaque) > > while (s->buf_free_count < nb_chunks) { > trace_mirror_yield_in_flight(s, op->offset, s->in_flight); > -mirror_wait_for_free_in_flight_slot(s); > +mirror_co_wait_for_free_in_flight_slot(s); > } > > /* Now make a QEMUIOVector taking enough granularity-sized chunks > @@ -549,7 +551,7 @@ static uint64_t coroutine_fn > mirror_iteration(MirrorBlockJob *s) > > while (s->in_flight >= MAX_IN_FLIGHT) { > trace_mirror_yield_in_flight(s, offset, s->in_flight); > -mirror_wait_for_free_in_flight_slot(s); > +mirror_co_wait_for_free_in_flight_slot(s); > } > > if (s->ret < 0) { > @@ -600,10 +602,10 @@ static void mirror_free_init(MirrorBlockJob *s) > * mirror_resume() because mirror_run() will begin iterating again > * when the job is resumed. > */ > -static void mirror_wait_for_all_io(MirrorBlockJob *s) > +static void coroutine_fn mirror_co_wait_for_all_io(MirrorBlockJob *s) > { > while (s->in_flight > 0) { > -mirror_wait_for_free_in_flight_slot(s); > +mirror_co_wait_for_free_in_flight_slot(s); > } > } > > @@ -762,7 +764,7 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob > *s) > if (s->in_flight >= MAX_IN_FLIGHT) { > trace_mirror_yield(s, UINT64_MAX, s->buf_free_count, > s->in_flight); > -mirror_wait_for_free_in_flight_slot(s); > +mirror_co_wait_for_free_in_flight_slot(s); > continue; > } > > @@ -770,7 +772,7 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob > *s) > offset += bytes; > } > > -mirror_wait_for_all_io(s); > +mirror_co_wait_for_all_io(s); > s->initial_zeroing_ongoing = false; > } > > @@ -916,7 +918,7 @@ static void coroutine_fn mirror_run(void *opaque) > /* Do not start passive operations while there are active > * writes in progress */ > while (s->in_active_write_counter) { > -mirror_wait_for_any_operation(s, true); > +mirror_co_wait_for_any_operation(s, true); > } > > if (s->ret < 0) { > @@ -942,7 +944,7 @@ static void coroutine_fn mirror_run(void *opaque) > if (s->in_flight >= MAX_IN_FLIGHT || s->buf_free_count == 0 || > (cnt == 0 && s->in_flight > 0)) { > trace_mirror_yield(s, cnt, s->buf_free_count, s->in_flight); > -mirror_wait_for_free_in_flight_slot(s); > +mirror_co_wait_for_free_in_flight_slot(s); > continue; > } else if (cnt != 0) { > delay_ns = mirror_iteration(s); > @@ -1028,7 +1030,7 @@ immediate_exit: > assert(ret < 0 || ((s->common.job.force_cancel || !s->synced) && > job_is_cancelled(>common.job))); > assert(need_drain); > -mirror_wait_for_all_io(s); > +mirror_co_wait_for_all_io(s); > } > > assert(s->in_flight == 0); > @@ -1098,11 +1100,11 @@ static void mirror_complete(Job *job, Error **errp) > job_enter(job); > } > > -static void mirror_pause(Job *job) > +static void coroutine_fn mirror_pause(Job *job) > { >
Re: [Qemu-devel] Question about dirty page statistics for live migration
2018-08-13 19:30 GMT+08:00 Dr. David Alan Gilbert : > * Li Qiang (liq...@gmail.com) wrote: > > 2018-08-13 17:35 GMT+08:00 Dr. David Alan Gilbert : > > > > > * Li Qiang (liq...@gmail.com) wrote: > > > > Hello Dave, Juan and all, > > > > > > > > It is useful to get the dirty page rates in guest to evaluate the > guest > > > > loads > > > > so that we can make a decide to live migrate it or not. So I think > we can > > > > add a on-demand qmp for showing the dirty page rates. > > > > > > > > I found someone has done this work in here: > > > > -->https://github.com/grivon/yabusame-qemu-dpt > > > > and here: > > > > https://github.com/btrplace/qemu-patch > > > > > > > > But seems not go to the upstream. > > > > > > > > I want to know your opinions about adding this qmp. > > > > > > Something like that could be good; > > > > one easy idea we had was > > > a 'migrate null:' uri and then you would use most of the existing > > > migration code to do the measurement; you would only have to > > > add a dummy file backend, > > > > > > As far as I understand, here dummy file backend just means the file > migrate > > to, right? > > Yes; because then if you have a dummy migration destination, the rest of > the migration code will run, sync the bitmap and clear the bits, and > give you an approximation of the dirty rate. > > It might still be worth having the separate code to measure it without > the overhead of the migration code; but then that's more complex - and > if you're trying to measure it to know how hard it is to migrate then > perhaps it's better to use the migration code anyway. > Agree But here is another issue, if we choice 'migrate null', then we will break the 'migrate' interface. the migrate doesn't return the info, so we need to uses 'info migrate'. However only we want is the dirty pages rates. It's too heavy for the user. Anyway we just want to get the only dirty page rates using one command. I will first try to implement a separate qmp. Thanks, Li Qiang > Dave > > > Thanks, > > Li Qiang > > > > > > > > > and something to stop the migration ever > > > terminating (maybe just set the downtime very low). > > > > > > > > > Dave > > > > > > > > > > Thanks, > > > > Li Qiang > > > -- > > > Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK > > > > -- > Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK >
Re: [Qemu-devel] [PATCH v3 0/2] Fix aio_notify_accept()
On Thu, 08/09 21:22, Fam Zheng wrote: > v3: Fix commit message's bug description. [Paolo] If there's no objection, I'm queuing this for 3.1. Fam
Re: [Qemu-devel] [PATCH] nvme: simplify plug/unplug
On Mon, 08/13 16:43, Paolo Bonzini wrote: > bdrv_io_plug/bdrv_io_unplug take care of keeping a nesting count, > so change s->plugged to just a bool. > > Signed-off-by: Paolo Bonzini Queued, thanks. Fam
Re: [Qemu-devel] [PATCH 0/3] expose VIRTIO_SCSI_F_T10_PI for vhost-scsi and vhost-user-scsi
On Wed, 08/08 13:52, Greg Edwards wrote: > Unify the get_features functions for vhost-scsi and vhost-user-scsi, including > their use of host_features, and expose a new 't10_pi' property to enable > negotiation of the VIRTIO_SCSI_F_T10_PI feature bit with the backend. > > Greg Edwards (3): > vhost-user-scsi: move host_features into VHostSCSICommon > vhost-scsi: unify vhost-scsi get_features implementations > vhost-scsi: expose 't10_pi' property for VIRTIO_SCSI_F_T10_PI > > hw/scsi/vhost-scsi-common.c | 3 +++ > hw/scsi/vhost-scsi.c | 3 +++ > hw/scsi/vhost-user-scsi.c | 28 ++- > include/hw/virtio/vhost-scsi-common.h | 1 + > include/hw/virtio/vhost-user-scsi.h | 1 - > 5 files changed, 17 insertions(+), 19 deletions(-) Reviewed-by: Fam Zheng
Re: [Qemu-devel] [PATCH] nvme: simplify code around completion
On Mon, 08/13 16:43, Paolo Bonzini wrote: > nvme_poll_queues is already protected by q->lock, and > AIO callbacks are invoked outside the AioContext lock. > So remove the acquire/release pair in nvme_handle_event. > > Remove unnecessary variable in in nvme_poll_cb. > > Signed-off-by: Paolo Bonzini > --- > block/nvme.c | 6 +- > 1 file changed, 1 insertion(+), 5 deletions(-) > > diff --git a/block/nvme.c b/block/nvme.c > index 6f71122bf5..df2e16fabe 100644 > --- a/block/nvme.c > +++ b/block/nvme.c > @@ -489,10 +489,8 @@ static void nvme_handle_event(EventNotifier *n) > BDRVNVMeState *s = container_of(n, BDRVNVMeState, irq_notifier); > > trace_nvme_handle_event(s); > -aio_context_acquire(s->aio_context); > event_notifier_test_and_clear(n); > nvme_poll_queues(s); > -aio_context_release(s->aio_context); > } > > static bool nvme_add_io_queue(BlockDriverState *bs, Error **errp) > @@ -539,11 +537,9 @@ static bool nvme_poll_cb(void *opaque) > { > EventNotifier *e = opaque; > BDRVNVMeState *s = container_of(e, BDRVNVMeState, irq_notifier); > -bool progress = false; > > trace_nvme_poll_cb(s); > -progress = nvme_poll_queues(s); > -return progress; > +return nvme_poll_queues(s); > } > > static int nvme_init(BlockDriverState *bs, const char *device, int namespace, > -- > 2.17.1 > Could you please split it into two patches? Because the significance of the two hunks feels overwhelmingly imbalanced to me. :) Fam
[Qemu-devel] [PATCH 1/4] hw/i386/pc: hold the BQL when calling cpu_get_ticks
Signed-off-by: Emilio G. Cota --- hw/i386/pc.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 83a72b..7371cd9960 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -158,7 +158,18 @@ static uint64_t ioportF0_read(void *opaque, hwaddr addr, unsigned size) /* TSC handling */ uint64_t cpu_get_tsc(CPUX86State *env) { -return cpu_get_ticks(); +uint64_t ret; +bool locked; + +locked = qemu_mutex_iothread_locked(); +if (!locked) { +qemu_mutex_lock_iothread(); +} +ret = cpu_get_ticks(); +if (!locked) { +qemu_mutex_unlock_iothread(); +} +return ret; } /* IRQ handling */ -- 2.17.1
[Qemu-devel] [PATCH 4/4] configure: enable mttcg for x86_64
Signed-off-by: Emilio G. Cota --- configure | 1 + 1 file changed, 1 insertion(+) diff --git a/configure b/configure index 2a7796ea80..db216bafb1 100755 --- a/configure +++ b/configure @@ -6935,6 +6935,7 @@ case "$target_name" in TARGET_BASE_ARCH=i386 gdb_xml_files="i386-64bit.xml i386-64bit-core.xml i386-64bit-sse.xml" target_compiler=$cross_cc_x86_64 +mttcg="yes" ;; alpha) mttcg="yes" -- 2.17.1
[Qemu-devel] [PATCH 0/4] x86_64 mttcg
With this series I can boot a busybox image and several Ubuntu images with various -smp's. The speedup we get is in line with what we get with other ISAs, e.g. -smp 4 takes 34s instead of 1min with thread=single. I've run this through the Valgrind race detectors, and the remaining races reported seem benign. I have not tested i386, so I'm not turning mttcg on for it yet. Patches 1-2 comply with cpu_get_ticks' documentation. I'm not too happy about effectively serializing rdtsc, since Linux guests call it very often (for each vCPU!). But as usual, correctness goes before performance or scalability. You can fetch the series from: https://github.com/cota/qemu/tree/x86_64-mttcg Thanks, Emilio
[Qemu-devel] [PATCH 3/4] target/i386/translate: use thread-local storage in !user-mode
Needed for MTTCG. Signed-off-by: Emilio G. Cota --- target/i386/translate.c | 24 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/target/i386/translate.c b/target/i386/translate.c index 07d185e7b6..f4c2a41f8f 100644 --- a/target/i386/translate.c +++ b/target/i386/translate.c @@ -71,26 +71,34 @@ //#define MACRO_TEST 1 +/* we need thread-local storage for mttcg */ +#ifdef CONFIG_USER_ONLY +#define I386_THREAD +#else +#define I386_THREAD __thread +#endif + /* global register indexes */ -static TCGv cpu_A0; -static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2, cpu_cc_srcT; +static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2; static TCGv_i32 cpu_cc_op; static TCGv cpu_regs[CPU_NB_REGS]; static TCGv cpu_seg_base[6]; static TCGv_i64 cpu_bndl[4]; static TCGv_i64 cpu_bndu[4]; /* local temps */ -static TCGv cpu_T0, cpu_T1; +static I386_THREAD TCGv cpu_cc_srcT; +static I386_THREAD TCGv cpu_A0; +static I386_THREAD TCGv cpu_T0, cpu_T1; /* local register indexes (only used inside old micro ops) */ -static TCGv cpu_tmp0, cpu_tmp4; -static TCGv_ptr cpu_ptr0, cpu_ptr1; -static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32; -static TCGv_i64 cpu_tmp1_i64; +static I386_THREAD TCGv cpu_tmp0, cpu_tmp4; +static I386_THREAD TCGv_ptr cpu_ptr0, cpu_ptr1; +static I386_THREAD TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32; +static I386_THREAD TCGv_i64 cpu_tmp1_i64; #include "exec/gen-icount.h" #ifdef TARGET_X86_64 -static int x86_64_hregs; +static I386_THREAD int x86_64_hregs; #endif typedef struct DisasContext { -- 2.17.1
[Qemu-devel] [PATCH 2/4] cpus: assert that the BQL is held in cpu_get_ticks
Signed-off-by: Emilio G. Cota --- cpus.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cpus.c b/cpus.c index b5844b7103..b23bf6fef7 100644 --- a/cpus.c +++ b/cpus.c @@ -308,6 +308,8 @@ int64_t cpu_get_ticks(void) { int64_t ticks; +g_assert(qemu_mutex_iothread_locked()); + if (use_icount) { return cpu_get_icount(); } -- 2.17.1
Re: [Qemu-devel] [PATCH 2/3] spapr: do not use CPU_FOREACH_REVERSE
On Mon, Aug 13, 2018 at 12:38:58PM -0400, Emilio G. Cota wrote: > This paves the way for implementing the CPU list with an RCU QLIST, > which cannot be traversed in reverse order. > > Note that this is the only caller of CPU_FOREACH_REVERSE. > > Signed-off-by: Emilio G. Cota Acked-by: David Gibson > --- > hw/ppc/spapr.c | 16 +++- > 1 file changed, 15 insertions(+), 1 deletion(-) > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > index 421b2dd09b..2ef5be2790 100644 > --- a/hw/ppc/spapr.c > +++ b/hw/ppc/spapr.c > @@ -622,9 +622,12 @@ static void spapr_populate_cpu_dt(CPUState *cs, void > *fdt, int offset, > > static void spapr_populate_cpus_dt_node(void *fdt, sPAPRMachineState *spapr) > { > +CPUState **rev; > CPUState *cs; > +int n_cpus; > int cpus_offset; > char *nodename; > +int i; > > cpus_offset = fdt_add_subnode(fdt, 0, "cpus"); > _FDT(cpus_offset); > @@ -635,8 +638,19 @@ static void spapr_populate_cpus_dt_node(void *fdt, > sPAPRMachineState *spapr) > * We walk the CPUs in reverse order to ensure that CPU DT nodes > * created by fdt_add_subnode() end up in the right order in FDT > * for the guest kernel the enumerate the CPUs correctly. > + * > + * The CPU list cannot be traversed in reverse order, so we need > + * to do extra work. > */ > -CPU_FOREACH_REVERSE(cs) { > +n_cpus = 0; > +rev = NULL; > +CPU_FOREACH(cs) { > +rev = g_renew(CPUState *, rev, n_cpus + 1); > +rev[n_cpus++] = cs; > +} > + > +for (i = n_cpus - 1; i >= 0; i--) { > +CPUState *cs = rev[i]; > PowerPCCPU *cpu = POWERPC_CPU(cs); > int index = spapr_get_vcpu_id(cpu); > DeviceClass *dc = DEVICE_GET_CLASS(cs); -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: PGP signature
[Qemu-devel] [PATCH 3/4] target/arm: Use the int-to-float-scale softfloat routines
Signed-off-by: Richard Henderson --- target/arm/helper.c | 29 + 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 61454a77ec..38439a2ee8 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11550,12 +11550,7 @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env) #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) \ -{ \ -float_status *fpst = fpstp; \ -float##fsz tmp; \ -tmp = itype##_to_##float##fsz(x, fpst); \ -return float##fsz##_scalbn(tmp, -(int)shift, fpst); \ -} +{ return itype##_to_##float##fsz##_scalbn(x, -shift, fpstp); } /* Notice that we want only input-denormal exception flags from the * scalbn operation: the other possible flags (overflow+inexact if @@ -11608,38 +11603,24 @@ VFP_CONV_FIX_A64(uq, s, 32, 64, uint64) #undef VFP_CONV_FLOAT_FIX_ROUND #undef VFP_CONV_FIX_A64 -/* Conversion to/from f16 can overflow to infinity before/after scaling. - * Therefore we convert to f64, scale, and then convert f64 to f16; or - * vice versa for conversion to integer. - * - * For 16- and 32-bit integers, the conversion to f64 never rounds. - * For 64-bit integers, any integer that would cause rounding will also - * overflow to f16 infinity, so there is no double rounding problem. - */ - -static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst) -{ -return float64_to_float16(float64_scalbn(f, -shift, fpst), true, fpst); -} - uint32_t HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst) { -return do_postscale_fp16(int32_to_float64(x, fpst), shift, fpst); +return int32_to_float16_scalbn(x, -shift, fpst); } uint32_t HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst) { -return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst); +return uint32_to_float16_scalbn(x, -shift, fpst); } uint32_t HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst) { -return do_postscale_fp16(int64_to_float64(x, fpst), shift, fpst); +return int64_to_float16_scalbn(x, -shift, fpst); } uint32_t HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst) { -return do_postscale_fp16(uint64_to_float64(x, fpst), shift, fpst); +return uint64_to_float16_scalbn(x, -shift, fpst); } static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst) -- 2.17.1
[Qemu-devel] [PATCH 1/4] softfloat: Add scaling int-to-float routines
Signed-off-by: Richard Henderson --- include/fpu/softfloat.h | 56 fpu/softfloat.c | 188 +--- 2 files changed, 179 insertions(+), 65 deletions(-) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 69f4dbc4db..038e375e71 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -190,22 +190,54 @@ enum { /* | Software IEC/IEEE integer-to-floating-point conversion routines. **/ + +float16 int16_to_float16_scalbn(int16_t a, int, float_status *status); +float16 int32_to_float16_scalbn(int32_t a, int, float_status *status); +float16 int64_to_float16_scalbn(int64_t a, int, float_status *status); +float16 uint16_to_float16_scalbn(uint16_t a, int, float_status *status); +float16 uint32_to_float16_scalbn(uint32_t a, int, float_status *status); +float16 uint64_to_float16_scalbn(uint64_t a, int, float_status *status); + +float16 int16_to_float16(int16_t a, float_status *status); +float16 int32_to_float16(int32_t a, float_status *status); +float16 int64_to_float16(int64_t a, float_status *status); +float16 uint16_to_float16(uint16_t a, float_status *status); +float16 uint32_to_float16(uint32_t a, float_status *status); +float16 uint64_to_float16(uint64_t a, float_status *status); + +float32 int16_to_float32_scalbn(int16_t, int, float_status *status); +float32 int32_to_float32_scalbn(int32_t, int, float_status *status); +float32 int64_to_float32_scalbn(int64_t, int, float_status *status); +float32 uint16_to_float32_scalbn(uint16_t, int, float_status *status); +float32 uint32_to_float32_scalbn(uint32_t, int, float_status *status); +float32 uint64_to_float32_scalbn(uint64_t, int, float_status *status); + float32 int16_to_float32(int16_t, float_status *status); float32 int32_to_float32(int32_t, float_status *status); -float64 int16_to_float64(int16_t, float_status *status); -float64 int32_to_float64(int32_t, float_status *status); +float32 int64_to_float32(int64_t, float_status *status); float32 uint16_to_float32(uint16_t, float_status *status); float32 uint32_to_float32(uint32_t, float_status *status); +float32 uint64_to_float32(uint64_t, float_status *status); + +float64 int16_to_float64_scalbn(int16_t, int, float_status *status); +float64 int32_to_float64_scalbn(int32_t, int, float_status *status); +float64 int64_to_float64_scalbn(int64_t, int, float_status *status); +float64 uint16_to_float64_scalbn(uint16_t, int, float_status *status); +float64 uint32_to_float64_scalbn(uint32_t, int, float_status *status); +float64 uint64_to_float64_scalbn(uint64_t, int, float_status *status); + +float64 int16_to_float64(int16_t, float_status *status); +float64 int32_to_float64(int32_t, float_status *status); +float64 int64_to_float64(int64_t, float_status *status); float64 uint16_to_float64(uint16_t, float_status *status); float64 uint32_to_float64(uint32_t, float_status *status); -floatx80 int32_to_floatx80(int32_t, float_status *status); -float128 int32_to_float128(int32_t, float_status *status); -float32 int64_to_float32(int64_t, float_status *status); -float64 int64_to_float64(int64_t, float_status *status); -floatx80 int64_to_floatx80(int64_t, float_status *status); -float128 int64_to_float128(int64_t, float_status *status); -float32 uint64_to_float32(uint64_t, float_status *status); float64 uint64_to_float64(uint64_t, float_status *status); + +floatx80 int32_to_floatx80(int32_t, float_status *status); +floatx80 int64_to_floatx80(int64_t, float_status *status); + +float128 int32_to_float128(int32_t, float_status *status); +float128 int64_to_float128(int64_t, float_status *status); float128 uint64_to_float128(uint64_t, float_status *status); /* @@ -227,12 +259,6 @@ int64_t float16_to_int64(float16, float_status *status); uint64_t float16_to_uint64(float16 a, float_status *status); int64_t float16_to_int64_round_to_zero(float16, float_status *status); uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *status); -float16 int16_to_float16(int16_t a, float_status *status); -float16 int32_to_float16(int32_t a, float_status *status); -float16 int64_to_float16(int64_t a, float_status *status); -float16 uint16_to_float16(uint16_t a, float_status *status); -float16 uint32_to_float16(uint32_t a, float_status *status); -float16 uint64_to_float16(uint64_t a, float_status *status); /* | Software half-precision operations. diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 7d63cffdeb..12f373cbad 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1603,81 +1603,122 @@ FLOAT_TO_UINT(64, 64) * to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. */ -static FloatParts int_to_float(int64_t a,
[Qemu-devel] [PATCH 2/4] softfloat: Add scaling float-to-int routines
Signed-off-by: Richard Henderson --- include/fpu/softfloat.h | 85 ++--- fpu/softfloat.c | 391 2 files changed, 379 insertions(+), 97 deletions(-) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 038e375e71..cc1b58b029 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -243,21 +243,34 @@ float128 uint64_to_float128(uint64_t, float_status *status); /* | Software half-precision conversion routines. **/ + float16 float32_to_float16(float32, bool ieee, float_status *status); float32 float16_to_float32(float16, bool ieee, float_status *status); float16 float64_to_float16(float64 a, bool ieee, float_status *status); float64 float16_to_float64(float16 a, bool ieee, float_status *status); + +int16_t float16_to_int16_scalbn(float16, int, int, float_status *status); +int32_t float16_to_int32_scalbn(float16, int, int, float_status *status); +int64_t float16_to_int64_scalbn(float16, int, int, float_status *status); + int16_t float16_to_int16(float16, float_status *status); -uint16_t float16_to_uint16(float16 a, float_status *status); -int16_t float16_to_int16_round_to_zero(float16, float_status *status); -uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *status); int32_t float16_to_int32(float16, float_status *status); -uint32_t float16_to_uint32(float16 a, float_status *status); -int32_t float16_to_int32_round_to_zero(float16, float_status *status); -uint32_t float16_to_uint32_round_to_zero(float16 a, float_status *status); int64_t float16_to_int64(float16, float_status *status); -uint64_t float16_to_uint64(float16 a, float_status *status); + +int16_t float16_to_int16_round_to_zero(float16, float_status *status); +int32_t float16_to_int32_round_to_zero(float16, float_status *status); int64_t float16_to_int64_round_to_zero(float16, float_status *status); + +uint16_t float16_to_uint16_scalbn(float16 a, int, int, float_status *status); +uint32_t float16_to_uint32_scalbn(float16 a, int, int, float_status *status); +uint64_t float16_to_uint64_scalbn(float16 a, int, int, float_status *status); + +uint16_t float16_to_uint16(float16 a, float_status *status); +uint32_t float16_to_uint32(float16 a, float_status *status); +uint64_t float16_to_uint64(float16 a, float_status *status); + +uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *status); +uint32_t float16_to_uint32_round_to_zero(float16 a, float_status *status); uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *status); /* @@ -347,18 +360,31 @@ float16 float16_default_nan(float_status *status); /* | Software IEC/IEEE single-precision conversion routines. **/ + +int16_t float32_to_int16_scalbn(float32, int, int, float_status *status); +int32_t float32_to_int32_scalbn(float32, int, int, float_status *status); +int64_t float32_to_int64_scalbn(float32, int, int, float_status *status); + int16_t float32_to_int16(float32, float_status *status); -uint16_t float32_to_uint16(float32, float_status *status); -int16_t float32_to_int16_round_to_zero(float32, float_status *status); -uint16_t float32_to_uint16_round_to_zero(float32, float_status *status); int32_t float32_to_int32(float32, float_status *status); -int32_t float32_to_int32_round_to_zero(float32, float_status *status); -uint32_t float32_to_uint32(float32, float_status *status); -uint32_t float32_to_uint32_round_to_zero(float32, float_status *status); int64_t float32_to_int64(float32, float_status *status); -uint64_t float32_to_uint64(float32, float_status *status); -uint64_t float32_to_uint64_round_to_zero(float32, float_status *status); + +int16_t float32_to_int16_round_to_zero(float32, float_status *status); +int32_t float32_to_int32_round_to_zero(float32, float_status *status); int64_t float32_to_int64_round_to_zero(float32, float_status *status); + +uint16_t float32_to_uint16_scalbn(float32, int, int, float_status *status); +uint32_t float32_to_uint32_scalbn(float32, int, int, float_status *status); +uint64_t float32_to_uint64_scalbn(float32, int, int, float_status *status); + +uint16_t float32_to_uint16(float32, float_status *status); +uint32_t float32_to_uint32(float32, float_status *status); +uint64_t float32_to_uint64(float32, float_status *status); + +uint16_t float32_to_uint16_round_to_zero(float32, float_status *status); +uint32_t float32_to_uint32_round_to_zero(float32, float_status *status); +uint64_t float32_to_uint64_round_to_zero(float32, float_status *status); + float64 float32_to_float64(float32, float_status *status); floatx80 float32_to_floatx80(float32,
[Qemu-devel] [PATCH 0/4] target/arm: Fix int64_to_float16 double-rounding
In 88808a022c0, I tried to fix an overflow problem that affected float16 scaling by coverting first to float64 and then rounding after that. However, Laurent reported that -0x3ff401 converted to float16 resulted in 0xfbfe instead of the expected 0xfbff. This is caused by the inexact conversion to float64. Rather than build more logic into target/arm to compensate, just add a function that takes a scaling parameter so that the whole thing is done all at once with only one rounding. I don't have a failing test case for the float-to-int paths, but it seemed best to apply the same solution. r~ Richard Henderson (4): softfloat: Add scaling int-to-float routines softfloat: Add scaling float-to-int routines target/arm: Use the int-to-float-scale softfloat routines target/arm: Use the float-to-int-scale softfloat routines include/fpu/softfloat.h | 169 fpu/softfloat.c | 579 +++- target/arm/helper.c | 130 - 3 files changed, 628 insertions(+), 250 deletions(-) -- 2.17.1
[Qemu-devel] [PATCH 4/4] target/arm: Use the float-to-int-scale softfloat routines
Signed-off-by: Richard Henderson --- target/arm/helper.c | 101 ++-- 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 38439a2ee8..e4a7d97805 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11552,38 +11552,28 @@ float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \ void *fpstp) \ { return itype##_to_##float##fsz##_scalbn(x, -shift, fpstp); } -/* Notice that we want only input-denormal exception flags from the - * scalbn operation: the other possible flags (overflow+inexact if - * we overflow to infinity, output-denormal) aren't correct for the - * complete scale-and-convert operation. - */ -#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; \ -int old_exc_flags = get_float_exception_flags(fpst); \ -float##fsz tmp; \ -if (float##fsz##_is_any_nan(x)) { \ -float_raise(float_flag_invalid, fpst); \ -return 0; \ -} \ -tmp = float##fsz##_scalbn(x, shift, fpst); \ -old_exc_flags |= get_float_exception_flags(fpst) \ -& float_flag_input_denormal; \ -set_float_exception_flags(old_exc_flags, fpst); \ -return float##fsz##_to_##itype##round(tmp, fpst); \ +#define VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, ROUND, suff) \ +uint##isz##_t HELPER(vfp_to##name##p##suff)(float##fsz x, uint32_t shift, \ +void *fpst) \ +{ \ +if (unlikely(float##fsz##_is_any_nan(x))) { \ +float_raise(float_flag_invalid, fpst);\ +return 0; \ +} \ +return float##fsz##_to_##itype##_scalbn(x, ROUND, shift, 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_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, ) +VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \ + float_round_to_zero, _round_to_zero)\ +VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \ + get_float_rounding_mode(fpst), ) #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_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \ + get_float_rounding_mode(fpst), ) VFP_CONV_FIX(sh, d, 64, 64, int16) VFP_CONV_FIX(sl, d, 64, 64, int32) @@ -11623,53 +11613,64 @@ uint32_t HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst) return uint64_to_float16_scalbn(x, -shift, fpst); } -static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst) -{ -if (unlikely(float16_is_any_nan(f))) { -float_raise(float_flag_invalid, fpst); -return 0; -} else { -int old_exc_flags = get_float_exception_flags(fpst); -float64 ret; - -ret = float16_to_float64(f, true, fpst); -ret = float64_scalbn(ret, shift, fpst); -old_exc_flags |= get_float_exception_flags(fpst) -& float_flag_input_denormal; -set_float_exception_flags(old_exc_flags, fpst); - -return ret; -} -} - uint32_t HELPER(vfp_toshh)(uint32_t x, uint32_t shift, void *fpst) { -return float64_to_int16(do_prescale_fp16(x, shift, fpst), fpst); +if (unlikely(float16_is_any_nan(x))) { +float_raise(float_flag_invalid, fpst); +return 0; +} +return float16_to_int16_scalbn(x, get_float_rounding_mode(fpst), + shift, fpst); } uint32_t HELPER(vfp_touhh)(uint32_t x, uint32_t shift, void *fpst) { -return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst); +if (unlikely(float16_is_any_nan(x))) { +float_raise(float_flag_invalid, fpst); +return 0; +} +return float16_to_uint16_scalbn(x, get_float_rounding_mode(fpst), +shift, fpst); } uint32_t HELPER(vfp_toslh)(uint32_t x, uint32_t shift, void *fpst) { -return float64_to_int32(do_prescale_fp16(x, shift, fpst), fpst); +if (unlikely(float16_is_any_nan(x))) { +float_raise(float_flag_invalid, fpst); +return 0; +} +return float16_to_int32_scalbn(x, get_float_rounding_mode(fpst), +
[Qemu-devel] [engineering.redhat.com #476336] seccomp blacklist is not applied to all threads
On Mon Aug 13 18:27:27 2018, ja...@google.com wrote: > On Mon, Aug 13, 2018 at 11:21 PM Red Hat Product Security > wrote: > > Hi Jann, > > > > Thanks for reporting this. I've asked our analysis team to check this. > > I'll update you on any progress. > > > > > > Regards > > -- > > Laura Pardo, Red Hat Product Security > > 3867 E074 DC5C FFA9 1AA7 EB7F 35A2 69F0 0073 71B6 > > [off-list reply] > > Hi Laura! > > I already privately reported this issue to this email alias, and was > asked by Prasad J Pandit to CC him when sending the issue to the > public list. I assume that this alias feeds into some sort of common > inbox or ticket system on your end - you may want to assign this one > to Prasad, or something like that. > > Hi Jann, thanks for letting me know. I've assigned this to Prasad directly to speed up the process. Regards -- Laura Pardo, Red Hat Product Security 3867 E074 DC5C FFA9 1AA7 EB7F 35A2 69F0 0073 71B6
[Qemu-devel] [engineering.redhat.com #476336] seccomp blacklist is not applied to all threads
Hi Jann, Thanks for reporting this. I've asked our analysis team to check this. I'll update you on any progress. Regards -- Laura Pardo, Red Hat Product Security 3867 E074 DC5C FFA9 1AA7 EB7F 35A2 69F0 0073 71B6
Re: [Qemu-devel] RAMBlocks and memory_region_init_ram_nomigrate
Ah got it, thanks for the replies / info! We're using a modified QEMU 2.12, and I don't see the migratable-only loops and field, so it either got missed in the rebase or was added after 2.12. Frank On Mon, Aug 13, 2018 at 9:45 AM Dr. David Alan Gilbert wrote: > * Paolo Bonzini (pbonz...@redhat.com) wrote: > > On 13/08/2018 18:16, Frank Yang wrote: > > > Hi Paolo, > > > > > > I see that migration/ram.c saves RAMBlocks associated with memory > > > regions initialized with nomigrate. Is this intended? > > > > Probably the name and size of the RAMBlocks must match but the contents > > need not (but honestly I haven't looked at the code to find the answer). > > CCing the qemu mailing list (always a good idea) and a couple people > > that might know. > > All the migration code should now be using RAMBLOCK_FOREACH_MIGRATABLE and > qemu_ram_is_migratable whenever it's iterating the ramblock list, > so that *shouldn't* happen these days. > Of course we could have messed it up somewhere; what are you seeing? > > Dave > > Paolo > -- > Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK >
Re: [Qemu-devel] Fwd: [Bug 1785698] Re: Solaris build error: unknown type name ‘gcry_error_t’
Well my gmake finally went all the way to the end building all of the guest architectures but I didn't see a qemu executable (unless it isn't called qemu). I ran gmake again to see what happened and all I got was this: # gmake mkdir -p dtc/libfdt mkdir -p dtc/tests Bad string # I then ran gmake V=1. That didn't really help:: (cd /export/home/denber/qemu-2.12.0; if test -n ""; then pkgvers=""; else if test -d .git; then pkgvers=$(git describe --match 'v*' 2>/dev/null | tr -d '\n'); if ! git diff-index --quiet HEAD &>/dev/null; then pkgvers="${pkgvers}-dirty"; fi; fi; fi; printf "#define QEMU_PKGVERSION \"${pkgvers}\"\n"; if test -n "${pkgvers}"; then printf '#define QEMU_FULL_VERSION QEMU_VERSION " (" QEMU_PKGVERSION ")"\n'; else printf '#define QEMU_FULL_VERSION QEMU_VERSION\n'; fi; ) > qemu-version.h.tmp if ! cmp -s qemu-version.h qemu-version.h.tmp; then mv qemu-version.h.tmp qemu-version.h; else rm qemu-version.h.tmp; fi mkdir -p dtc/libfdt mkdir -p dtc/tests gmake -I/export/home/denber/qemu-2.12.0/dtc VPATH=/export/home/denber/qemu-2.12.0/dtc -C dtc V="1" LIBFDT_srcdir=/export/home/denber/qemu-2.12.0/dtc/libfdt CPPFLAGS="-I/export/home/denber/qemu-2.12.0/build/dtc -I/export/home/denber/qemu-2.12.0/dtc -I/export/home/denber/qemu-2.12.0/dtc/libfdt" CFLAGS="-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g -I/opt/csw/include/pixman-1 -I/export/home/denber/qemu-2.12.0/dtc/libfdt -D_REENTRANT -D_PTHREADS -I/opt/csw/include/glib-2.0 -I/opt/csw/lib/glib-2.0/include -m32 -mv8plus -mcpu=ultrasparc -std=gnu99 -D__EXTENSIONS__ -D_XOPEN_SOURCE=600 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv -Wexpansion-to-defined -Wendif-labels -Wno-shift-negative-value -Wno-missing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-strong -I/opt/csw/include -I/usr/include/libpng12 -I/export/home/denber/qemu-2.12.0/capstone/include -I/export/home/denber/qemu-2.12.0/tests" LDFLAGS="-m32 -mv8plus -g " ARFLAGS="rv" CC="gcc" AR="ar" LD="ld" BUILD_DIR=/export/home/denber/qemu-2.12.0/build libfdt/libfdt.a gmake[1]: Entering directory '/export/home/denber/qemu-2.12.0/build/dtc' Bad string gmake[1]: 'libfdt/libfdt.a' is up to date. gmake[1]: Leaving directory '/export/home/denber/qemu-2.12.0/build/dtc' ... It doesn't say "Error: Bad string", it just says "Bad string". Is that even an error? A web search for this turned up nothing and the string "Bad string" does not seem to appear in the entire qemu directory. I'm not sure what's going on now. There seems to be something in the dtc subdirectory it doesn't like. - Michele -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1785698 Title: Solaris build error: unknown type name ‘gcry_error_t’ Status in QEMU: New Bug description: Building qemu 2.12.0 on a Sun Oracle Enterprise M3000 SPARC64 VII, Solaris 10 Update 11, opencsw toolchain and gcc 7.3.0, gmake fails with a bunch of related errors all in cypher-gcrypt.c: /export/home/denber/qemu-2.12.0/crypto/cipher-gcrypt.c:262:32: error: ‘gcry_cipher_hd_t’ undeclared (first use in this function); did you mean ‘gcry_cipher_info’? err = gcry_cipher_encrypt((gcry_cipher_hd_t)ctx, dst, length, src, length);^~~~ gcry_cipher_info /export/home/denber/qemu-2.12.0/crypto/cipher-gcrypt.c:262:49: error: expected ‘)’ before ‘ctx’ err = gcry_cipher_encrypt((gcry_cipher_hd_t)ctx, dst, length, src, length); ^~~ /export/home/denber/qemu-2.12.0/crypto/cipher-gcrypt.c:262:11: error: too few arguments to function ‘gcry_cipher_encrypt’ err = gcry_cipher_encrypt((gcry_cipher_hd_t)ctx, dst, length, src, length); ^~~ In file included from /export/home/denber/qemu-2.12.0/crypto/cipher-gcrypt.c:25:0, from /export/home/denber/qemu-2.12.0/crypto/cipher.c:153: /usr/include/gcrypt.h:566:5: note: declared here int gcry_cipher_encrypt (GcryCipherHd h, ^~~ In file included from /export/home/denber/qemu-2.12.0/crypto/cipher.c:153:0: /export/home/denber/qemu-2.12.0/crypto/cipher-gcrypt.c: In function ‘qcrypto_gcrypt_xts_decrypt’: /export/home/denber/qemu-2.12.0/crypto/cipher-gcrypt.c:271:5: error: unknown type name ‘gcry_error_t’; did you mean ‘g_error’? gcry_error_t err; ^~~~ g_error /export/home/denber/qemu-2.12.0/crypto/cipher-gcrypt.c:272:32: error: ‘gcry_cipher_hd_t’ undeclared (first use in this function); did you mean ‘gcry_cipher_info’? err =
Re: [Qemu-devel] [PATCH v1] exec: handle NULL pointer in flatview_read_continue
Am Fri, 10 Aug 2018 14:29:28 +0200 schrieb Paolo Bonzini : > On 10/08/2018 12:32, Olaf Hering wrote: > > Am Fri, 10 Aug 2018 12:25:09 +0200 > > schrieb Paolo Bonzini : > > So you mean that function must not return NULL? > > Or should the caller check for the result? > Either, but the former would of course be much simpler if possible. Since other callers already deal with NULL, that one has to cope as well. And since unavailable memory can not be zero, the memset 0xff is most likely correct as well. So, for me the patch is good as it is. The write part will get a separate change in a few days. Olaf pgpkxWwOj1cPY.pgp Description: Digitale Signatur von OpenPGP
Re: [Qemu-devel] [PATCH v4 00/14] fp-test + hardfloat
On Mon, Jun 11, 2018 at 21:48:46 -0400, Emilio G. Cota wrote: > Sending this respin (little more than a rebase) in case there's > reviewer bandwidth available until the soft-freeze in 3 weeks. *ping* Would be great to get this in for 3.1. BTW I have a paper under submission that covers this work among other improvements to QEMU. Reading this paper might ease a subsequent review of this patch series; ask me privately if you want to get a copy. Thanks, Emilio
Re: [Qemu-devel] QEMU on Solaris
On 08-13-2018 6:08 AM, Peter Tribble wrote: From the point of view of software such as qemu, divergences should be slight (there are going to be changes around packaging, shipped compilers, but that's true for different Linux distros in the same family). If it builds and works on Solaris, it'll build and work on one of the illumos distributions, and vice versa. (Although I note that's Solaris 10 mentioned above, which is now EOL, and may be a little more problematic due to its age.) I'm still using Solaris 10 because upgrading to Solaris 11 is a giant pain, and they did away with the Java Desktop Environment GUI in 11. I really like the JDE. However, I believe that Solaris 10 programs should also work in Solaris 11. And it looks like Solaris 11 may be the end of the line anyway. You can certainly run illumos (such as OpenIndiana or Tribblix) in a VM easily, and freely. I can help with that. That's for x86, of course. Building on a SPARC platform is a different matter entirely. (Although that's one of the reasons some of us are interested in qemu in the first place.) That's exactly why I'm interested. I'd like to declare my independence form Microsoft and Windows but I still have a few important Windows programs that won't run on anything else. One can debate Solaris vx. Linux, but I've made my choice. - Michele
Re: [Qemu-devel] QEMU on Solaris
On 08-13-2018 4:34 AM, Daniel P. Berrangé wrote: Copying Peter, as he would need access to a Solaris host to do GIT pre-merge build testing. Then there's the question of what ordinary developers would use for their own testing if they needed to work on some portability issue. We've got support in tree for running builds against VM images for the various *BSDs, and have mingw cross build toolchain for Windows. Is it possible to provide free-to-use VM disk images for Solaris build testing, or are software licensing requirements going to get in the way of developers using them ? Correct me if I'm wrong but I assume you're referring to the use of the Solaris OS itself. Solaris 10 and 11 are both available for free download from Oracle. I read the license agreement (http://www.oracle.com/technetwork/licenses/solaris-cluster-express-license-167852.html) and while I'm not a lawyer and do not even play one on the Internet, the relevant part seems to be: *"LICENSE RIGHTS * Except for any included software package or file that is licensed to you by Oracle under different license terms, we grant you a perpetual (unless terminated as provided in this agreement), nonexclusive, nontransferable, limited License to use the Programs only for the purpose of developing, testing, prototyping and demonstrating your applications, and not for any other purpose. If You are an educational institution vested with the power to confer official high school, associate, bachelor, master and/or doctorate degrees, or local equivalent, (“Degree(s)”), You may also use the Programs as part of Your educational curriculum for students enrolled in Your Degree program(s) solely as required for the conferral of such Degree (collectively “Educational Use”)." I /think /that means it's OK to use it. ??? There is OpenIndiana that forked off OpenSolaris, but I'm unclear how far OpenIndiana and commercial Solaris have diverged since then ? One problem with OpenIndiana is that it's not available for SPARC. However, they refer to Dilos, OpenSXCE and Tribblix, though I know nothing of any of those. - Michele
Re: [Qemu-devel] [PATCH v0 0/7] Background snapshots
cc'ing in Mike*2 * Denis Plotnikov (dplotni...@virtuozzo.com) wrote: > > > On 26.07.2018 12:23, Peter Xu wrote: > > On Thu, Jul 26, 2018 at 10:51:33AM +0200, Paolo Bonzini wrote: > > > On 25/07/2018 22:04, Andrea Arcangeli wrote: > > > > > > > > It may look like the uffd-wp model is wish-feature similar to an > > > > optimization, but without the uffd-wp model when the WP fault is > > > > triggered by kernel code, the sigsegv model falls apart and requires > > > > all kind of ad-hoc changes just for this single feature. Plus uffd-wp > > > > has other benefits: it makes it all reliable in terms of not > > > > increasing the number of vmas in use during the snapshot. Finally it > > > > makes it faster too with no mmap_sem for reading and no sigsegv > > > > signals. > > > > > > > > The non cooperative features got merged first because there was much > > > > activity on the kernel side on that front, but this is just an ideal > > > > time to nail down the remaining issues in uffd-wp I think. That I > > > > believe is time better spent than trying to emulate it with sigsegv > > > > and changing all drivers to send new events down to qemu specific to > > > > the sigsegv handling. We considered this before doing uffd for > > > > postcopy too but overall it's unreliable and more work (no single > > > > change was then needed to KVM code with uffd to handle postcopy and > > > > here it should be the same). > > > > > > I totally agree. The hard part in userfaultfd was the changes to the > > > kernel get_user_pages API, but the payback was huge because _all_ kernel > > > uses (KVM, vhost-net, syscalls, etc.) just work with userfaultfd. Going > > > back to mprotect would be a huge mistake. > > > > Thanks for explaining the bits. I'd say I wasn't aware of the > > difference before I started the investigation (and only until now I > > noticed that major difference between mprotect and userfaultfd). I'm > > really glad that it's much clear (at least for me) on which way we > > should choose. > > > > Now I'm thinking whether we can move the userfault write protect work > > forward. The latest discussion I saw so far is in 2016, when someone > > from Huawei tried to use the write protect feature for that old > > version of live snapshot but reported issue: > > > >https://lists.gnu.org/archive/html/qemu-devel/2016-12/msg01127.html > > > > Is that the latest status for userfaultfd wr-protect? > > > > If so, I'm thinking whether I can try to re-verify the work (I tried > > his QEMU repository but I failed to compile somehow, so I plan to > > write some even simpler code to try) to see whether I can get the same > > KVM error he encountered. > > > > Thoughts? > > Just to sum up all being said before. > > Using mprotect is a bad idea because VM's memory can be accessed from the > number of places (KVM, vhost, ...) which need their own special care > of tracking memory accesses and notifying QEMU which makes the mprotect > using unacceptable. > > Protected memory accesses tracking can be done via userfaultfd's WP mode > which isn't available right now. > > So, the reasonable conclusion is to wait until the WP mode is available and > build the background snapshot on top of userfaultfd-wp. > But, works on adding the WP-mode is pending for a quite a long time already. > > Is there any way to estimate when it could be available? I think a question is whether anyone is actively working on it; I suspect really it's on a TODO list rather than moving at the moment. What I don't really understand is what stage the last version got upto. Dave > > > > Regards, > > > > -- > Best, > Denis -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
Re: [Qemu-devel] [Qemu-arm] [PATCH v4 6/6] Add QTest testcase for the Intel Hexadecimal
On Fri, Aug 10, 2018 at 01:26:08AM -0300, Philippe Mathieu-Daudé wrote: > On 08/03/2018 11:47 AM, Stefan Hajnoczi wrote: > Can you add a comment providing the .S asm source and how to > build/generate this blob? (I think this is required to respect the GPLv2 > license in your header). I have resolved this by using a memory test pattern instead of an actual program. The test case uses -qtest anyway, so no guest code is executed. Stefan signature.asc Description: PGP signature
[Qemu-devel] [PATCH v5 6/6] Add QTest testcase for the Intel Hexadecimal
From: Su Hang 'test.hex' file is a memory test pattern stored in Hexadecimal Object Format. It loads at 0x1 in RAM and contains values from 0 through 255. The test case verifies that the expected memory test pattern was loaded. Reviewed-by: Stefan Hajnoczi Suggested-by: Steffen Gortz Suggested-by: Stefan Hajnoczi Signed-off-by: Su Hang Signed-off-by: Stefan Hajnoczi --- MAINTAINERS | 6 configure| 4 +++ tests/Makefile.include | 2 ++ tests/hexloader-test.c | 41 tests/hex-loader-check-data/test.hex | 18 5 files changed, 71 insertions(+) create mode 100644 tests/hexloader-test.c create mode 100644 tests/hex-loader-check-data/test.hex diff --git a/MAINTAINERS b/MAINTAINERS index 666e936812..c48d9271cf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1323,6 +1323,12 @@ F: hw/core/generic-loader.c F: include/hw/core/generic-loader.h F: docs/generic-loader.txt +Intel Hexadecimal Object File Loader +M: Su Hang +S: Maintained +F: tests/hexloader-test.c +F: tests/hex-loader-check-data/test.hex + CHRP NVRAM M: Thomas Huth S: Maintained diff --git a/configure b/configure index 2a7796ea80..db97930314 100755 --- a/configure +++ b/configure @@ -7382,6 +7382,10 @@ for test_file in $(find $source_path/tests/acpi-test-data -type f) do FILES="$FILES tests/acpi-test-data$(echo $test_file | sed -e 's/.*acpi-test-data//')" done +for test_file in $(find $source_path/tests/hex-loader-check-data -type f) +do +FILES="$FILES tests/hex-loader-check-data$(echo $test_file | sed -e 's/.*hex-loader-check-data//')" +done mkdir -p $DIRS for f in $FILES ; do if [ -e "$source_path/$f" ] && [ "$pwd_is_source_path" != "y" ]; then diff --git a/tests/Makefile.include b/tests/Makefile.include index a49282704e..760a0f18b6 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -386,6 +386,7 @@ check-qtest-arm-y += tests/test-arm-mptimer$(EXESUF) gcov-files-arm-y += hw/timer/arm_mptimer.c check-qtest-arm-y += tests/boot-serial-test$(EXESUF) check-qtest-arm-y += tests/sdhci-test$(EXESUF) +check-qtest-arm-y += tests/hexloader-test$(EXESUF) check-qtest-aarch64-y = tests/numa-test$(EXESUF) check-qtest-aarch64-y += tests/sdhci-test$(EXESUF) @@ -773,6 +774,7 @@ tests/qmp-test$(EXESUF): tests/qmp-test.o tests/device-introspect-test$(EXESUF): tests/device-introspect-test.o tests/rtc-test$(EXESUF): tests/rtc-test.o tests/m48t59-test$(EXESUF): tests/m48t59-test.o +tests/hexloader-test$(EXESUF): tests/hexloader-test.o tests/endianness-test$(EXESUF): tests/endianness-test.o tests/spapr-phb-test$(EXESUF): tests/spapr-phb-test.o $(libqos-obj-y) tests/prom-env-test$(EXESUF): tests/prom-env-test.o $(libqos-obj-y) diff --git a/tests/hexloader-test.c b/tests/hexloader-test.c new file mode 100644 index 00..90e470e9db --- /dev/null +++ b/tests/hexloader-test.c @@ -0,0 +1,41 @@ +/* + * QTest testcase for the Intel Hexadecimal Object File Loader + * + * Authors: + * Su Hang 2018 + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "libqtest.h" + +/* success if no crash or abort */ +static void hex_loader_test(void) +{ +unsigned int i; +const unsigned int base_addr = 0x0001; + +QTestState *s = qtest_startf( +"-M vexpress-a9 -nographic -device loader,file=tests/hex-loader-check-data/test.hex"); + +for (i = 0; i < 256; ++i) { +uint8_t val = qtest_readb(s, base_addr + i); +g_assert_cmpuint(i, ==, val); +} +qtest_quit(s); +} + +int main(int argc, char **argv) +{ +int ret; + +g_test_init(, , NULL); + +qtest_add_func("/tmp/hex_loader", hex_loader_test); +ret = g_test_run(); + +return ret; +} diff --git a/tests/hex-loader-check-data/test.hex b/tests/hex-loader-check-data/test.hex new file mode 100644 index 00..008a90bd4d --- /dev/null +++ b/tests/hex-loader-check-data/test.hex @@ -0,0 +1,18 @@ +:02040001F9 +:100102030405060708090a0b0c0d0e0f78 +:10001000101112131415161718191a1b1c1d1e1f68 +:10002000202122232425262728292a2b2c2d2e2f58 +:10003000303132333435363738393a3b3c3d3e3f48 +:10004000404142434445464748494a4b4c4d4e4f38 +:10005000505152535455565758595a5b5c5d5e5f28 +:10006000606162636465666768696a6b6c6d6e6f18 +:10007000707172737475767778797a7b7c7d7e7f08 +:10008000808182838485868788898a8b8c8d8e8ff8 +:10009000909192939495969798999a9b9c9d9e9fe8 +:1000a000a0a1a2a3a4a5a6a7a8a9aaabacadaeafd8 +:1000b000b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc8 +:1000c000c0c1c2c3c4c5c6c7c8c9cacbcccdcecfb8 +:1000d000d0d1d2d3d4d5d6d7d8d9dadbdcdddedfa8 +:1000e000e0e1e2e3e4e5e6e7e8e9eaebecedeeef98 +:1000f000f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff88 +:0001FF -- 2.17.1
[Qemu-devel] [PATCH v5 1/6] hw/arm: make bitbanded IO optional on ARMv7-M
Some ARM CPUs have bitbanded IO, a memory region that allows convenient bit access via 32-bit memory loads/stores. This eliminates the need for read-modify-update instruction sequences. This patch makes this optional feature an ARMv7MState qdev property, allowing boards to choose whether they want bitbanding or not. Status of boards: * iotkit (Cortex M33), no bitband * mps2 (Cortex M3), bitband * msf2 (Cortex M3), bitband * stellaris (Cortex M3), bitband * stm32f205 (Cortex M3), bitband As a side-effect of this patch, Peter Maydell noted that the Ethernet controller on mps2 board is now accessible. Previously they were hidden by the bitband region (which does not exist on the real board). Signed-off-by: Stefan Hajnoczi Reviewed-by: Philippe Mathieu-Daudé --- include/hw/arm/armv7m.h | 2 ++ hw/arm/armv7m.c | 37 - hw/arm/mps2.c | 1 + hw/arm/msf2-soc.c | 1 + hw/arm/stellaris.c | 1 + hw/arm/stm32f205_soc.c | 1 + 6 files changed, 26 insertions(+), 17 deletions(-) diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h index 78308d1484..2ba24953b6 100644 --- a/include/hw/arm/armv7m.h +++ b/include/hw/arm/armv7m.h @@ -43,6 +43,7 @@ typedef struct { * devices will be automatically layered on top of this view.) * + Property "idau": IDAU interface (forwarded to CPU object) * + Property "init-svtor": secure VTOR reset value (forwarded to CPU object) + * + Property "enable-bitband": expose bitbanded IO */ typedef struct ARMv7MState { /*< private >*/ @@ -63,6 +64,7 @@ typedef struct ARMv7MState { MemoryRegion *board_memory; Object *idau; uint32_t init_svtor; +bool enable_bitband; } ARMv7MState; #endif diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index 6b07666057..878613994d 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -211,25 +211,27 @@ static void armv7m_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(>container, 0xe000e000, sysbus_mmio_get_region(sbd, 0)); -for (i = 0; i < ARRAY_SIZE(s->bitband); i++) { -Object *obj = OBJECT(>bitband[i]); -SysBusDevice *sbd = SYS_BUS_DEVICE(>bitband[i]); +if (s->enable_bitband) { +for (i = 0; i < ARRAY_SIZE(s->bitband); i++) { +Object *obj = OBJECT(>bitband[i]); +SysBusDevice *sbd = SYS_BUS_DEVICE(>bitband[i]); -object_property_set_int(obj, bitband_input_addr[i], "base", ); -if (err != NULL) { -error_propagate(errp, err); -return; -} -object_property_set_link(obj, OBJECT(s->board_memory), - "source-memory", _abort); -object_property_set_bool(obj, true, "realized", ); -if (err != NULL) { -error_propagate(errp, err); -return; -} +object_property_set_int(obj, bitband_input_addr[i], "base", ); +if (err != NULL) { +error_propagate(errp, err); +return; +} +object_property_set_link(obj, OBJECT(s->board_memory), + "source-memory", _abort); +object_property_set_bool(obj, true, "realized", ); +if (err != NULL) { +error_propagate(errp, err); +return; +} -memory_region_add_subregion(>container, bitband_output_addr[i], -sysbus_mmio_get_region(sbd, 0)); +memory_region_add_subregion(>container, bitband_output_addr[i], +sysbus_mmio_get_region(sbd, 0)); +} } } @@ -239,6 +241,7 @@ static Property armv7m_properties[] = { MemoryRegion *), DEFINE_PROP_LINK("idau", ARMv7MState, idau, TYPE_IDAU_INTERFACE, Object *), DEFINE_PROP_UINT32("init-svtor", ARMv7MState, init_svtor, 0), +DEFINE_PROP_BOOL("enable-bitband", ARMv7MState, enable_bitband, false), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c index c3946da317..0a0ae867d9 100644 --- a/hw/arm/mps2.c +++ b/hw/arm/mps2.c @@ -186,6 +186,7 @@ static void mps2_common_init(MachineState *machine) g_assert_not_reached(); } qdev_prop_set_string(armv7m, "cpu-type", machine->cpu_type); +qdev_prop_set_bit(armv7m, "enable-bitband", true); object_property_set_link(OBJECT(>armv7m), OBJECT(system_memory), "memory", _abort); object_property_set_bool(OBJECT(>armv7m), true, "realized", diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c index dbefade644..2702e90b45 100644 --- a/hw/arm/msf2-soc.c +++ b/hw/arm/msf2-soc.c @@ -117,6 +117,7 @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp) armv7m = DEVICE(>armv7m); qdev_prop_set_uint32(armv7m, "num-irq", 81); qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type); +
[Qemu-devel] [PATCH v5 2/6] target/arm: add "cortex-m0" CPU model
Define a "cortex-m0" ARMv6-M CPU model. Most of the register reset values set by other CPU models are not relevant for the cut-down ARMv6-M architecture. Signed-off-by: Stefan Hajnoczi Reviewed-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé --- target/arm/cpu.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 3848ef46aa..7e477c0d23 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1255,6 +1255,15 @@ static void arm11mpcore_initfn(Object *obj) cpu->reset_auxcr = 1; } +static void cortex_m0_initfn(Object *obj) +{ +ARMCPU *cpu = ARM_CPU(obj); +set_feature(>env, ARM_FEATURE_V6); +set_feature(>env, ARM_FEATURE_M); + +cpu->midr = 0x410cc200; +} + static void cortex_m3_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); @@ -1845,6 +1854,8 @@ static const ARMCPUInfo arm_cpus[] = { { .name = "arm1136", .initfn = arm1136_initfn }, { .name = "arm1176", .initfn = arm1176_initfn }, { .name = "arm11mpcore", .initfn = arm11mpcore_initfn }, +{ .name = "cortex-m0", .initfn = cortex_m0_initfn, + .class_init = arm_v7m_class_init }, { .name = "cortex-m3", .initfn = cortex_m3_initfn, .class_init = arm_v7m_class_init }, { .name = "cortex-m4", .initfn = cortex_m4_initfn, -- 2.17.1
Re: [Qemu-devel] [Bug 1785698] Re: Solaris build error: unknown type name ‘gcry_error_t’
On 08-13-2018 4:14 AM, Thomas Huth wrote: > For providing a Solaris build machine, you best get in touch with Peter > Maydell (see MAINTAINERS file for his mail address). I notice he already checked in later in my inbox. I'll reply to that there. > > Now for your build problems, it seems like "libgcrypt-config --cflags" > already should add /opt/csw/include to the list of header search paths, > so I wonder why the "#include " does not pick up that file yet > and you had to add "#include " instead? Is > there maybe another gcrypt.h file somewhere else on your system which > conflicts with the one from /opt/csw/include ? Well this is odd but I was poking around trying to resolve a bunch of syntax errors in the Makefiles. This is usually the result of a wrong sh being called. I've had some luck in the past building other things by adding a line "!#/usr/xpg4/bin/sh" at the top of the sh file but that trick did not work for qemu. So I finally took the default sh, which is /usr/bin/sh (which is a link to /sbin/sh) and instead linked it directly to /usr/xpg4/bin/sh. That immediately took care of all the syntax errors and the gcrypt error too. I don't know why qemu is picky about POSIX, but there you have it. > > Concerning the "-lutil" problem - no clue where this is coming from. > Could you maybe try to compile with "gmake V=1" and post the line where > the executable is linked? Maybe that gives some more indication what is > going on here... This will probably make you cringe, but what I ended up doing was simply copying some random .so file in /opt/csw/lib and calling it libutil.so. The linker then seemed happy and that error went away. I figure that if someone is actually using lutil I will get a runtime error, once I get it running, if I ever get it running. Then I'll be able to tell who is calling it and what they're trying to do. It may be that no one is using it. I saw some post on the web to the effect that lutil should just be commented out in Solaris. I was unable to figure out from the linker error the source of lutil. I now have a new problem: dtc/checks.c won't compile because it can't find strnlen. So I put in #include . Still wouldn't compile. So I looked in /usr/include/string.h and sure enough, strnlen is missing. I'm like, what the heck? So I ended up providing the source code of strnlen at the top of checks.c. This was also a problem in fdt_ro.c. It's that sort of thing. Now it's compiling again. I configured without any target options, so it's making everything. And I forgot to give gmake a -j so it's taking a while. - Michele -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1785698 Title: Solaris build error: unknown type name ‘gcry_error_t’ Status in QEMU: New Bug description: Building qemu 2.12.0 on a Sun Oracle Enterprise M3000 SPARC64 VII, Solaris 10 Update 11, opencsw toolchain and gcc 7.3.0, gmake fails with a bunch of related errors all in cypher-gcrypt.c: /export/home/denber/qemu-2.12.0/crypto/cipher-gcrypt.c:262:32: error: ‘gcry_cipher_hd_t’ undeclared (first use in this function); did you mean ‘gcry_cipher_info’? err = gcry_cipher_encrypt((gcry_cipher_hd_t)ctx, dst, length, src, length);^~~~ gcry_cipher_info /export/home/denber/qemu-2.12.0/crypto/cipher-gcrypt.c:262:49: error: expected ‘)’ before ‘ctx’ err = gcry_cipher_encrypt((gcry_cipher_hd_t)ctx, dst, length, src, length); ^~~ /export/home/denber/qemu-2.12.0/crypto/cipher-gcrypt.c:262:11: error: too few arguments to function ‘gcry_cipher_encrypt’ err = gcry_cipher_encrypt((gcry_cipher_hd_t)ctx, dst, length, src, length); ^~~ In file included from /export/home/denber/qemu-2.12.0/crypto/cipher-gcrypt.c:25:0, from /export/home/denber/qemu-2.12.0/crypto/cipher.c:153: /usr/include/gcrypt.h:566:5: note: declared here int gcry_cipher_encrypt (GcryCipherHd h, ^~~ In file included from /export/home/denber/qemu-2.12.0/crypto/cipher.c:153:0: /export/home/denber/qemu-2.12.0/crypto/cipher-gcrypt.c: In function ‘qcrypto_gcrypt_xts_decrypt’: /export/home/denber/qemu-2.12.0/crypto/cipher-gcrypt.c:271:5: error: unknown type name ‘gcry_error_t’; did you mean ‘g_error’? gcry_error_t err; ^~~~ g_error /export/home/denber/qemu-2.12.0/crypto/cipher-gcrypt.c:272:32: error: ‘gcry_cipher_hd_t’ undeclared (first use in this function); did you mean ‘gcry_cipher_info’? err = gcry_cipher_decrypt((gcry_cipher_hd_t)ctx, dst, length, src, length);^~~~ gcry_cipher_info /export/home/denber/qemu-2.12.0/crypto/cipher-gcrypt.c:272:49:
Re: [Qemu-devel] [PATCH v8 10/87] target/mips: Fix MT ASE instructions' availability control
> From: Aleksandar Markovic > Sent: Monday, August 13, 2018 7:52 PM > To: qemu-devel@nongnu.org > > Subject: [PATCH v8 10/87] target/mips: Fix MT ASE instructions' availability > control > > From: Aleksandar Rikalo > > Use bits from configuration registers for availability control > of MT ASE instructions, rather than only ISA_MT bit in insn_flags. > > Signed-off-by: Aleksandar Markovic > Signed-off-by: Stefan Markovic > --- > target/mips/translate.c | 16 > 1 file changed, 8 insertions(+), 8 deletions(-) > > diff --git a/target/mips/translate.c b/target/mips/translate.c > index b73f434..af9714b 100644 > --- a/target/mips/translate.c > +++ b/target/mips/translate.c > @@ -8393,7 +8393,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext > *ctx, uint32_t opc, int rt, > opn = "mthc0"; > break; > case OPC_MFTR: > -check_insn(ctx, ASE_MT); > +check_cp0_enabled(ctx); > if (rd == 0) { > /* Treat as NOP. */ > return; > @@ -8403,7 +8403,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext > *ctx, uint32_t opc, int rt, > opn = "mftr"; > break; > case OPC_MTTR: > -check_insn(ctx, ASE_MT); > +check_cp0_enabled(ctx); > gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, > ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); > opn = "mttr"; > @@ -18619,7 +18619,7 @@ static void decode_opc_special3(CPUMIPSState *env, > DisasContext *ctx) > gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3)); > break; > case OPC_FORK: > -check_insn(ctx, ASE_MT); > +check_mt(ctx); > { > TCGv t0 = tcg_temp_new(); > TCGv t1 = tcg_temp_new(); > @@ -18632,7 +18632,7 @@ static void decode_opc_special3(CPUMIPSState *env, > DisasContext *ctx) > } > break; > case OPC_YIELD: > -check_insn(ctx, ASE_MT); > +check_mt(ctx); > { > TCGv t0 = tcg_temp_new(); > > @@ -19929,22 +19929,22 @@ static void decode_opc(CPUMIPSState *env, > DisasContext *ctx) > op2 = MASK_MFMC0(ctx->opcode); > switch (op2) { > case OPC_DMT: > -check_insn(ctx, ASE_MT); > +check_cp0_mt(ctx); > gen_helper_dmt(t0); > gen_store_gpr(t0, rt); > break; > case OPC_EMT: > -check_insn(ctx, ASE_MT); > +check_cp0_mt(ctx); > gen_helper_emt(t0); > gen_store_gpr(t0, rt); > break; > case OPC_DVPE: > -check_insn(ctx, ASE_MT); > +check_cp0_mt(ctx); > gen_helper_dvpe(t0, cpu_env); > gen_store_gpr(t0, rt); > break; > case OPC_EVPE: > -check_insn(ctx, ASE_MT); > +check_cp0_mt(ctx); > gen_helper_evpe(t0, cpu_env); > gen_store_gpr(t0, rt); > break; Reviewed-by: Aleksandar Markovic
[Qemu-devel] [PATCH v8 86/87] gdbstub: Add XML support for GDB for nanoMIPS
From: Stefan Markovic Add XML support files for GDB for nanoMIPS. Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- MAINTAINERS| 3 ++- gdb-xml/nanomips-cp0.xml | 13 + gdb-xml/nanomips-cpu.xml | 44 gdb-xml/nanomips-dsp.xml | 20 gdb-xml/nanomips-fpu.xml | 45 + gdb-xml/nanomips-linux.xml | 20 6 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 gdb-xml/nanomips-cp0.xml create mode 100644 gdb-xml/nanomips-cpu.xml create mode 100644 gdb-xml/nanomips-dsp.xml create mode 100644 gdb-xml/nanomips-fpu.xml create mode 100644 gdb-xml/nanomips-linux.xml diff --git a/MAINTAINERS b/MAINTAINERS index 7130807..a4907d0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -190,6 +190,8 @@ M: Aurelien Jarno M: Aleksandar Markovic S: Maintained F: target/mips/ +F: disas/mips.c +F: gdb-xml/*ips*.xml F: hw/mips/ F: hw/misc/mips_* F: hw/intc/mips_gic.c @@ -199,7 +201,6 @@ F: include/hw/misc/mips_* F: include/hw/intc/mips_gic.h F: include/hw/timer/mips_gictimer.h F: tests/tcg/mips/ -F: disas/mips.c Moxie M: Anthony Green diff --git a/gdb-xml/nanomips-cp0.xml b/gdb-xml/nanomips-cp0.xml new file mode 100644 index 000..8095dc6 --- /dev/null +++ b/gdb-xml/nanomips-cp0.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/gdb-xml/nanomips-cpu.xml b/gdb-xml/nanomips-cpu.xml new file mode 100644 index 000..6bba224 --- /dev/null +++ b/gdb-xml/nanomips-cpu.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb-xml/nanomips-dsp.xml b/gdb-xml/nanomips-dsp.xml new file mode 100644 index 000..950910f --- /dev/null +++ b/gdb-xml/nanomips-dsp.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + diff --git a/gdb-xml/nanomips-fpu.xml b/gdb-xml/nanomips-fpu.xml new file mode 100644 index 000..fd225a5 --- /dev/null +++ b/gdb-xml/nanomips-fpu.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb-xml/nanomips-linux.xml b/gdb-xml/nanomips-linux.xml new file mode 100644 index 000..8a04634 --- /dev/null +++ b/gdb-xml/nanomips-linux.xml @@ -0,0 +1,20 @@ + + + + + + nanomips + GNU/Linux + + + + + + + + + -- 2.7.4
[Qemu-devel] [PATCH v5 4/6] loader: add rom transaction API
Image file loaders may add a series of roms. If an error occurs partway through loading there is no easy way to drop previously added roms. This patch adds a transaction mechanism that works like this: rom_transaction_begin(); ...call rom_add_*()... rom_transaction_end(ok); If ok is false then roms added in this transaction are dropped. Signed-off-by: Stefan Hajnoczi --- include/hw/loader.h | 19 +++ hw/core/loader.c| 32 2 files changed, 51 insertions(+) diff --git a/include/hw/loader.h b/include/hw/loader.h index e98b84b8f9..5235f119a3 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -225,6 +225,25 @@ int rom_check_and_register_reset(void); void rom_set_fw(FWCfgState *f); void rom_set_order_override(int order); void rom_reset_order_override(void); + +/** + * rom_transaction_begin: + * + * Call this before of a series of rom_add_*() calls. Call + * rom_transaction_end() afterwards to commit or abort. These functions are + * useful for undoing a series of rom_add_*() calls if image file loading fails + * partway through. + */ +void rom_transaction_begin(void); + +/** + * rom_transaction_end: + * @commit: true to commit added roms, false to drop added roms + * + * Call this after a series of rom_add_*() calls. See rom_transaction_begin(). + */ +void rom_transaction_end(bool commit); + int rom_copy(uint8_t *dest, hwaddr addr, size_t size); void *rom_ptr(hwaddr addr, size_t size); void hmp_info_roms(Monitor *mon, const QDict *qdict); diff --git a/hw/core/loader.c b/hw/core/loader.c index 0c72e7c05a..612420b870 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -840,6 +840,8 @@ struct Rom { char *fw_dir; char *fw_file; +bool committed; + hwaddr addr; QTAILQ_ENTRY(Rom) next; }; @@ -877,6 +879,8 @@ static void rom_insert(Rom *rom) rom->as = _space_memory; } +rom->committed = false; + /* List is ordered by load address in the same address space */ QTAILQ_FOREACH(item, , next) { if (rom_order_compare(rom, item)) { @@ -1168,6 +1172,34 @@ void rom_reset_order_override(void) fw_cfg_reset_order_override(fw_cfg); } +void rom_transaction_begin(void) +{ +Rom *rom; + +/* Ignore ROMs added without the transaction API */ +QTAILQ_FOREACH(rom, , next) { +rom->committed = true; +} +} + +void rom_transaction_end(bool commit) +{ +Rom *rom; +Rom *tmp; + +QTAILQ_FOREACH_SAFE(rom, , next, tmp) { +if (rom->committed) { +continue; +} +if (commit) { +rom->committed = true; +} else { +QTAILQ_REMOVE(, rom, next); +rom_free(rom); +} +} +} + static Rom *find_rom(hwaddr addr, size_t size) { Rom *rom; -- 2.17.1
[Qemu-devel] [PATCH v8 85/87] gdbstub: Disable handling of nanoMIPS ISA bit in the MIPS gdbstub
From: James Hogan nanoMIPS has no ISA bit in the PC, so remove the handling of the low bit of the PC in the MIPS gdbstub for nanoMIPS. This prevents the PC being read as e.g. 0xbfc1, and prevents writing to the PC clearing MIPS_HFLAG_M16. Signed-off-by: James Hogan Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/gdbstub.c | 13 - 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/target/mips/gdbstub.c b/target/mips/gdbstub.c index 18e0e6d..559b69f 100644 --- a/target/mips/gdbstub.c +++ b/target/mips/gdbstub.c @@ -60,7 +60,8 @@ int mips_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) return gdb_get_regl(mem_buf, (int32_t)env->CP0_Cause); case 37: return gdb_get_regl(mem_buf, env->active_tc.PC | - !!(env->hflags & MIPS_HFLAG_M16)); + (!(env->insn_flags & ISA_NANOMIPS32) && + env->hflags & MIPS_HFLAG_M16)); case 72: return gdb_get_regl(mem_buf, 0); /* fp */ case 89: @@ -131,10 +132,12 @@ int mips_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) break; case 37: env->active_tc.PC = tmp & ~(target_ulong)1; -if (tmp & 1) { -env->hflags |= MIPS_HFLAG_M16; -} else { -env->hflags &= ~(MIPS_HFLAG_M16); +if (!(env->insn_flags & ISA_NANOMIPS32)) { +if (tmp & 1) { +env->hflags |= MIPS_HFLAG_M16; +} else { +env->hflags &= ~(MIPS_HFLAG_M16); +} } break; case 72: /* fp, ignored */ -- 2.7.4
[Qemu-devel] seccomp blacklist is not applied to all threads
Hi! I have noticed that when a QEMU build from git master is started with "-seccomp on", the seccomp policy is only applied to the main thread, the vcpu worker thread and the VNC thread (I'm using VNC in my config); the seccomp policy is not applied to e.g. the RCU thread because it is created before the seccomp policy is applied and SECCOMP_FILTER_FLAG_TSYNC isn't used. In practice, this makes the seccomp policy essentially useless. You'll probably want to add something like seccomp_attr_set(ctx, SCMP_FLTATR_CTL_TSYNC, 1) for systems with kernel >=3.17; if you have to support seccomp on older kernels, you'll have to either construct the other threads after initializing seccomp or manually activate seccomp on those threads. This shows up in strace as follows: $ strace -f -e trace=seccomp,clone,prctl x86_64-softmmu/qemu-system-x86_64 -enable-kvm -drive file=isos/debian-live-8.7.1-amd64-standard.iso,format=raw -m 4G -sandbox on -name testvm,debug-threads=on clone(child_stack=0x7f199af49bf0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f199af4a9d0, tls=0x7f199af4a700, child_tidptr=0x7f199af4a9d0) = 10948 strace: Process 10948 attached [pid 10947] prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0) = 0 [pid 10947] clone(child_stack=0x7f199a748bf0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f199a7499d0, tls=0x7f199a749700, child_tidptr=0x7f199a7499d0) = 10949 strace: Process 10949 attached [pid 10947] prctl(PR_SET_TIMERSLACK, 1) = 0 [pid 10947] prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) = 0 [pid 10947] seccomp(SECCOMP_SET_MODE_STRICT, 1, NULL) = -1 EINVAL (Invalid argument) [pid 10947] seccomp(SECCOMP_SET_MODE_FILTER, 0, {len=39, filter=0x55a968927830}) = 0 [pid 10947] clone(strace: Process 10950 attached child_stack=0x7f1999d65bf0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f1999d669d0, tls=0x7f1999d66700, child_tidptr=0x7f1999d669d0) = 10950 [pid 10950] prctl(PR_SET_NAME, "CPU 0/KVM") = 0 [pid 10947] clone(strace: Process 10952 attached child_stack=0x7f1993bfebf0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f1993bff9d0, tls=0x7f1993bff700, child_tidptr=0x7f1993bff9d0) = 10952 [pid 10952] prctl(PR_SET_NAME, "worker") = 0 [pid 10947] clone(strace: Process 10953 attached child_stack=0x7f19933fdbf0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f19933fe9d0, tls=0x7f19933fe700, child_tidptr=0x7f19933fe9d0) = 10953 [pid 10953] prctl(PR_SET_NAME, "vnc_worker") = 0 VNC server running on ::1:5900 [pid 10952] +++ exited with 0 +++ Checking in procfs confirms that two of the threads aren't sandboxed: $ for task in /proc/10947/task/*; do cat $task/comm; grep Seccomp $task/status; done qemu-system-x86 Seccomp: 2 qemu-system-x86 Seccomp: 0 qemu-system-x86 Seccomp: 0 CPU 0/KVM Seccomp: 2 vnc_worker Seccomp: 2
Re: [Qemu-devel] [PATCH] qemu-img.c: increase spacing between commands in documentation
On 08/13/2018 11:56 AM, Max Reitz wrote: Ah, hm, so much for that. Hm... I don't quite know what to think of this. It does indeed improve legibility. But the question is whether --help should be as condensed as possible, and if the user finds it hard to read, whether they should not just open the man page... Then again, our --help text already has 102 lines. Let me just think about it for a bit longer. :-) (And see whether others have opinions.) And I've already expressed my opinion that it is already rather long, where making it longer is not necessarily making it smarter. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org
[Qemu-devel] [PATCH v8 73/87] linux-user: Add target_syscall.h header for nanoMIPS
From: Aleksandar Rikalo Add target_syscall.h header for nanoMIPS. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/nanomips/target_syscall.h | 30 ++ 1 file changed, 30 insertions(+) create mode 100644 linux-user/nanomips/target_syscall.h diff --git a/linux-user/nanomips/target_syscall.h b/linux-user/nanomips/target_syscall.h new file mode 100644 index 000..b40e36b --- /dev/null +++ b/linux-user/nanomips/target_syscall.h @@ -0,0 +1,30 @@ +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct target_pt_regs { +/* Pad bytes for argument save space on the stack. */ +abi_ulong pad0[6]; + +/* Saved main processor registers. */ +abi_ulong regs[32]; + +/* Saved special registers. */ +abi_ulong cp0_status; +abi_ulong lo; +abi_ulong hi; +abi_ulong cp0_badvaddr; +abi_ulong cp0_cause; +abi_ulong cp0_epc; +}; + +/* Nasty hack: define a fake errno value for use by sigreturn. */ +#undef TARGET_QEMU_ESIGRETURN +#define TARGET_QEMU_ESIGRETURN 255 + +#define UNAME_MACHINE "nanomips" +#define UNAME_MINIMUM_RELEASE "2.6.32" + +#define TARGET_CLONE_BACKWARDS +#define TARGET_MINSIGSTKSZ 6144 +#define TARGET_MLOCKALL_MCL_CURRENT 1 +#define TARGET_MLOCKALL_MCL_FUTURE 2 -- 2.7.4
[Qemu-devel] [PATCH v5 3/6] loader: extract rom_free() function
The next patch will need to free a rom. There is already code to do this in rom_add_file(). Note that rom_add_file() uses: rom = g_malloc0(sizeof(*rom)); ... if (rom->fw_dir) { g_free(rom->fw_dir); g_free(rom->fw_file); } The conditional is unnecessary since g_free(NULL) is a no-op. Signed-off-by: Stefan Hajnoczi Reviewed-by: Alistair Francis Reviewed-by: Philippe Mathieu-Daudé --- hw/core/loader.c | 21 - 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/hw/core/loader.c b/hw/core/loader.c index bbb6e65bb5..0c72e7c05a 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -847,6 +847,17 @@ struct Rom { static FWCfgState *fw_cfg; static QTAILQ_HEAD(, Rom) roms = QTAILQ_HEAD_INITIALIZER(roms); +/* rom->data must be heap-allocated (do not use with rom_add_elf_program()) */ +static void rom_free(Rom *rom) +{ +g_free(rom->data); +g_free(rom->path); +g_free(rom->name); +g_free(rom->fw_dir); +g_free(rom->fw_file); +g_free(rom); +} + static inline bool rom_order_compare(Rom *rom, Rom *item) { return ((uintptr_t)(void *)rom->as > (uintptr_t)(void *)item->as) || @@ -995,15 +1006,7 @@ err: if (fd != -1) close(fd); -g_free(rom->data); -g_free(rom->path); -g_free(rom->name); -if (fw_dir) { -g_free(rom->fw_dir); -g_free(rom->fw_file); -} -g_free(rom); - +rom_free(rom); return -1; } -- 2.17.1
Re: [Qemu-devel] [PATCH v8 09/87] target/mips: Add support for availability control via bit MT
> From: Aleksandar Markovic > Sent: Monday, August 13, 2018 7:52 PM > > Subject: [PATCH v8 09/87] target/mips: Add support for availability control > via bit MT > > From: Aleksandar Rikalo > > Add a field in hflags for MT bit, and functions check_mt() and > check_cp0_mt(). > > Signed-off-by: Aleksandar Markovic > Signed-off-by: Stefan Markovic > --- > target/mips/cpu.h | 3 ++- > target/mips/internal.h | 6 +- > target/mips/translate.c | 29 + > 3 files changed, 36 insertions(+), 2 deletions(-) > > diff --git a/target/mips/cpu.h b/target/mips/cpu.h > ... > +/* > + * This code generates a "coprocessor unusable" if CP) is not > + * available, and, if that is not the case, generates a "reserved > + * instruction" exception if the Config5 MT bit is NOT set. > + * This is used for some of instructions in MT ASE. > + */ " "coprocessor unusable" if CP) " should be " "coprocessor unusable" exception if CP0 ". Otherwise: Reviewed-by: Aleksandar Markovic
[Qemu-devel] [PATCH v5 5/6] loader: Implement .hex file loader
From: Su Hang This patch adds Intel Hexadecimal Object File format support to the generic loader device. The file format specification is available here: http://www.piclist.com/techref/fileext/hex/intel.htm This file format is often used with microcontrollers such as the micro:bit, Arduino, STM32, etc. Users expect to be able to run .hex files directly with without first converting them to ELF. Most micro:bit code is developed in web-based IDEs without direct user access to binutils so it is important for QEMU to handle this file format natively. Signed-off-by: Su Hang Signed-off-by: Stefan Hajnoczi --- include/hw/loader.h | 12 ++ hw/core/generic-loader.c | 4 + hw/core/loader.c | 249 +++ 3 files changed, 265 insertions(+) diff --git a/include/hw/loader.h b/include/hw/loader.h index 5235f119a3..3c112975f4 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -28,6 +28,18 @@ ssize_t load_image_size(const char *filename, void *addr, size_t size); int load_image_targphys_as(const char *filename, hwaddr addr, uint64_t max_sz, AddressSpace *as); +/**load_targphys_hex_as: + * @filename: Path to the .hex file + * @entry: Store the entry point given by the .hex file + * @as: The AddressSpace to load the .hex file to. The value of + * address_space_memory is used if nothing is supplied here. + * + * Load a fixed .hex file into memory. + * + * Returns the size of the loaded .hex file on success, -1 otherwise. + */ +int load_targphys_hex_as(const char *filename, hwaddr *entry, AddressSpace *as); + /** load_image_targphys: * Same as load_image_targphys_as(), but doesn't allow the caller to specify * an AddressSpace. diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c index cb0e68486d..fde32cbda1 100644 --- a/hw/core/generic-loader.c +++ b/hw/core/generic-loader.c @@ -147,6 +147,10 @@ static void generic_loader_realize(DeviceState *dev, Error **errp) size = load_uimage_as(s->file, , NULL, NULL, NULL, NULL, as); } + +if (size < 0) { +size = load_targphys_hex_as(s->file, , as); +} } if (size < 0 || s->force_raw) { diff --git a/hw/core/loader.c b/hw/core/loader.c index 612420b870..390987a05c 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -1321,3 +1321,252 @@ void hmp_info_roms(Monitor *mon, const QDict *qdict) } } } + +typedef enum HexRecord HexRecord; +enum HexRecord { +DATA_RECORD = 0, +EOF_RECORD, +EXT_SEG_ADDR_RECORD, +START_SEG_ADDR_RECORD, +EXT_LINEAR_ADDR_RECORD, +START_LINEAR_ADDR_RECORD, +}; + +/* Each record contains a 16-bit address which is combined with the upper 16 + * bits of the implicit "next address" to form a 32-bit address. + */ +#define NEXT_ADDR_MASK 0x + +#define DATA_FIELD_MAX_LEN 0xff +#define LEN_EXCEPT_DATA 0x5 +/* 0x5 = sizeof(byte_count) + sizeof(address) + sizeof(record_type) + + * sizeof(checksum) */ +typedef struct { +uint8_t byte_count; +uint16_t address; +uint8_t record_type; +uint8_t data[DATA_FIELD_MAX_LEN]; +uint8_t checksum; +} HexLine; + +/* return 0 or -1 if error */ +static bool parse_record(HexLine *line, uint8_t *our_checksum, const uint8_t c, + uint32_t *index, const bool in_process) +{ +/* +---+---+---+-++ + * | byte | |record | || + * | count |address| type |data |checksum| + * +---+---+---+-++ + * ^ ^ ^ ^ ^^ + * |1 byte |2 bytes|1 byte | 0-255 bytes | 1 byte | + */ +uint8_t value = 0; +uint32_t idx = *index; +/* ignore space */ +if (g_ascii_isspace(c)) { +return true; +} +if (!g_ascii_isxdigit(c) || !in_process) { +return false; +} +value = g_ascii_xdigit_value(c); +value = (idx & 0x1) ? (value & 0xf) : (value << 4); +if (idx < 2) { +line->byte_count |= value; +} else if (2 <= idx && idx < 6) { +line->address <<= 4; +line->address += g_ascii_xdigit_value(c); +} else if (6 <= idx && idx < 8) { +line->record_type |= value; +} else if (8 <= idx && idx < 8 + 2 * line->byte_count) { +line->data[(idx - 8) >> 1] |= value; +} else if (8 + 2 * line->byte_count <= idx && + idx < 10 + 2 * line->byte_count) { +line->checksum |= value; +} else { +return false; +} +*our_checksum += value; +++(*index); +return true; +} + +typedef struct { +const char *filename; +HexLine line; +uint8_t *bin_buf; +hwaddr *start_addr; +int total_size; +uint32_t next_address_to_write; +uint32_t
[Qemu-devel] [PATCH v8 78/87] linux-user: Add support for nanoMIPS signal trampoline
From: Aleksandar Rikalo Add signal trampoline support for nanoMIPS. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/mips/signal.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/linux-user/mips/signal.c b/linux-user/mips/signal.c index ab66429..c6f5504 100644 --- a/linux-user/mips/signal.c +++ b/linux-user/mips/signal.c @@ -101,6 +101,17 @@ static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall) { int err = 0; +#if defined(TARGET_ABI_MIPSP32) +uint16_t *tramp16 = (uint16_t *)tramp; +/* + * li $2, __NR__foo_sigreturn + * syscall 0 + */ + __put_user(0x6040 , tramp16 + 0); + __put_user(syscall, tramp16 + 1); + __put_user(0 , tramp16 + 2); + __put_user(0x1008 , tramp16 + 3); +#else /* * Set up the return code ... * @@ -110,7 +121,7 @@ static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall) __put_user(0x2402 + syscall, tramp + 0); __put_user(0x000c , tramp + 1); - +#endif return err; } -- 2.7.4
[Qemu-devel] [PATCH v5 0/6] arm: add Cortex M0 CPU model and hex file loader
v5: * Implemented Phil's hex loader suggestions * Replaced Su Hang's test hex file with a simple memory test pattern, eliminating the need to distribute source [Phil] v4: * Drop ARMv7MState to ARMMProfileState rename because it causes a lot of code churn and is incomplete. Other parts of QEMU (like NVIC emulation) still refer to "v7m" although they apply to other architecture versions too. [Peter] * Use the generic loader device (-device loader,file=program.hex,cpu-num=1) instead of -kernel. -kernel is a legacy command-line option that is kept as a convenience, but it's not as flexible or predictable as the generic loader device. New image formats should be added to the generic loader device. [Peter] * Use hex/ASCII literals instead of decimal literals in hexloader-test.c. This makes the test case slightly easier to understand. [Philippe] v3: * Rename ARMv7MState to ARMMProfileState so a single class can cater for ARMv6-M, ARMv7-M, and ARMv8-M [Peter] * Make bitbanding optional via a qdev property [Peter] * Add hex file loader patches to reduce dependencies in upcoming patch series * Implement rollback if hex file loader fails partway through [Peter] * Update hex file loader test case to use an ARMv7-M board since hex file loading is only done for ARM M Profile boards This series contains the prerequistes for the "microbit" machine type that Joel Stanley has written. I have combined the Cortex M0 CPU model and hex loader work into one series to reduce the dependencies in upcoming patch series from Joel, Julia, and Steffen. This patch series: * Makes bitbanding optional on ARMv7MState. * Adds a "cortex-m0" cpu type which can be used with ARMMProfileState. This works thanks to Julia's Cortex M0 emulation patches, which are now all merged. * Adds Su Hang's Intel HEX file format loader so that micro:bit and other microcontroller firmware images can be run using -kernel. The micro:bit development tools typically only emit .hex files and not ELFs. Stefan Hajnoczi (4): hw/arm: make bitbanded IO optional on ARMv7-M target/arm: add "cortex-m0" CPU model loader: extract rom_free() function loader: add rom transaction API Su Hang (2): loader: Implement .hex file loader Add QTest testcase for the Intel Hexadecimal MAINTAINERS | 6 + configure| 4 + tests/Makefile.include | 2 + include/hw/arm/armv7m.h | 2 + include/hw/loader.h | 31 +++ hw/arm/armv7m.c | 37 ++-- hw/arm/mps2.c| 1 + hw/arm/msf2-soc.c| 1 + hw/arm/stellaris.c | 1 + hw/arm/stm32f205_soc.c | 1 + hw/core/generic-loader.c | 4 + hw/core/loader.c | 302 ++- target/arm/cpu.c | 11 + tests/hexloader-test.c | 41 tests/hex-loader-check-data/test.hex | 18 ++ 15 files changed, 436 insertions(+), 26 deletions(-) create mode 100644 tests/hexloader-test.c create mode 100644 tests/hex-loader-check-data/test.hex -- 2.17.1
[Qemu-devel] [PATCH v8 45/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 1
From: Stefan Markovic Add emulation of DSP ASE instructions for nanoMIPS - part 1. Reviewed-by: Aleksandar Markovic Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 556 1 file changed, 556 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index 7be2128..de10a07 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -17758,6 +17758,556 @@ static void gen_pool32f_nanomips_insn(DisasContext *ctx) } } +static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc, + int rd, int rs, int rt) +{ +int ret = rd; +TCGv t0 = tcg_temp_new(); +TCGv v1_t = tcg_temp_new(); +TCGv v2_t = tcg_temp_new(); + +gen_load_gpr(v1_t, rs); +gen_load_gpr(v2_t, rt); + +switch (opc) { +case NM_CMP_EQ_PH: +check_dsp(ctx); +gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env); +break; +case NM_CMP_LT_PH: +check_dsp(ctx); +gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env); +break; +case NM_CMP_LE_PH: +check_dsp(ctx); +gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env); +break; +case NM_CMPU_EQ_QB: +check_dsp(ctx); +gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env); +break; +case NM_CMPU_LT_QB: +check_dsp(ctx); +gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env); +break; +case NM_CMPU_LE_QB: +check_dsp(ctx); +gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env); +break; +case NM_CMPGU_EQ_QB: +check_dsp(ctx); +gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t); +gen_store_gpr(v1_t, ret); +break; +case NM_CMPGU_LT_QB: +check_dsp(ctx); +gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t); +gen_store_gpr(v1_t, ret); +break; +case NM_CMPGU_LE_QB: +check_dsp(ctx); +gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t); +gen_store_gpr(v1_t, ret); +break; +case NM_CMPGDU_EQ_QB: +check_dspr2(ctx); +gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t); +tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); +gen_store_gpr(v1_t, ret); +break; +case NM_CMPGDU_LT_QB: +check_dspr2(ctx); +gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t); +tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); +gen_store_gpr(v1_t, ret); +break; +case NM_CMPGDU_LE_QB: +check_dspr2(ctx); +gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t); +tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); +gen_store_gpr(v1_t, ret); +break; +case NM_PACKRL_PH: +check_dsp(ctx); +gen_helper_packrl_ph(v1_t, v1_t, v2_t); +gen_store_gpr(v1_t, ret); +break; +case NM_PICK_QB: +check_dsp(ctx); +gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env); +gen_store_gpr(v1_t, ret); +break; +case NM_PICK_PH: +check_dsp(ctx); +gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env); +gen_store_gpr(v1_t, ret); +break; +case NM_ADDQ_S_W: +check_dsp(ctx); +gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env); +gen_store_gpr(v1_t, ret); +break; +case NM_SUBQ_S_W: +check_dsp(ctx); +gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env); +gen_store_gpr(v1_t, ret); +break; +case NM_ADDSC: +check_dsp(ctx); +gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env); +gen_store_gpr(v1_t, ret); +break; +case NM_ADDWC: +check_dsp(ctx); +gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env); +gen_store_gpr(v1_t, ret); +break; +case NM_ADDQ_S_PH: +check_dsp(ctx); +switch (extract32(ctx->opcode, 10, 1)) { +case 0: +/* ADDQ_PH */ +gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env); +gen_store_gpr(v1_t, ret); +break; +case 1: +/* ADDQ_S_PH */ +gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env); +gen_store_gpr(v1_t, ret); +break; +} +break; +case NM_ADDQH_R_PH: +check_dspr2(ctx); +switch (extract32(ctx->opcode, 10, 1)) { +case 0: +/* ADDQH_PH */ +gen_helper_addqh_ph(v1_t, v1_t, v2_t); +gen_store_gpr(v1_t, ret); +break; +case 1: +/* ADDQH_R_PH */ +gen_helper_addqh_r_ph(v1_t, v1_t, v2_t); +gen_store_gpr(v1_t, ret); +break; +} +break; +case NM_ADDQH_R_W: +check_dspr2(ctx); +switch (extract32(ctx->opcode, 10, 1)) { +case 0: +/* ADDQH_W */ +gen_helper_addqh_w(v1_t, v1_t, v2_t); +gen_store_gpr(v1_t, ret); +break; +case 1: +/* ADDQH_R_W
[Qemu-devel] [PATCH v8 79/87] linux-user: Add cpu_loop.c for nanoMIPS
From: Dimitrije Nikolic Amend regular MIPS' cpu_loop.c to include nanoMIPS support. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/mips/cpu_loop.c | 8 +++- linux-user/nanomips/cpu_loop.c | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 linux-user/nanomips/cpu_loop.c diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c index c9c20cf..ada5a79 100644 --- a/linux-user/mips/cpu_loop.c +++ b/linux-user/mips/cpu_loop.c @@ -546,7 +546,7 @@ void cpu_loop(CPUMIPSState *env) arg5, arg6, arg7, arg8); } done_syscall: -# else +# else /* N32/N64 and P32 */ ret = do_syscall(env, env->active_tc.gpr[2], env->active_tc.gpr[4], env->active_tc.gpr[5], env->active_tc.gpr[6], env->active_tc.gpr[7], @@ -562,6 +562,7 @@ done_syscall: Avoid clobbering register state. */ break; } +#if !defined(TARGET_ABI_MIPSP32) if ((abi_ulong)ret >= (abi_ulong)-1133) { env->active_tc.gpr[7] = 1; /* error flag */ ret = -ret; @@ -569,6 +570,9 @@ done_syscall: env->active_tc.gpr[7] = 0; /* error flag */ } env->active_tc.gpr[2] = ret; +#else +env->active_tc.gpr[4] = ret; +#endif break; case EXCP_TLBL: case EXCP_TLBS: @@ -714,6 +718,8 @@ done_syscall: } else { code = ((trap_instr >> 6) & ((1 << 10) - 1)); } +} else if (env->insn_flags & ISA_NANOMIPS32) { +code = ((trap_instr >> 11) & ((1 << 5) - 1)); } if (do_break(env, , code) != 0) { diff --git a/linux-user/nanomips/cpu_loop.c b/linux-user/nanomips/cpu_loop.c new file mode 100644 index 000..da4949a --- /dev/null +++ b/linux-user/nanomips/cpu_loop.c @@ -0,0 +1 @@ +#include "../mips/cpu_loop.c" -- 2.7.4
[Qemu-devel] [PATCH v8 70/87] linux-user: Update syscall_defs.h header for nanoMIPS
From: Aleksandar Markovic Update constants and structures related to linux user syscall support in nanoMIPS. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/syscall_defs.h | 57 ++- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 40bb60e..abf94b8 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -374,7 +374,7 @@ struct target_dirent64 { #define TARGET_SIG_IGN ((abi_long)1) /* ignore signal */ #define TARGET_SIG_ERR ((abi_long)-1) /* error return from signal */ -#ifdef TARGET_MIPS +#if defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS) #define TARGET_NSIG 128 #else #define TARGET_NSIG 64 @@ -445,7 +445,7 @@ struct target_sigaction { target_sigset_t sa_mask; abi_ulong sa_restorer; }; -#elif defined(TARGET_MIPS) +#elif defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS) struct target_sigaction { uint32_tsa_flags; #if defined(TARGET_ABI_MIPSN32) @@ -459,6 +459,14 @@ struct target_sigaction { abi_ulong sa_restorer; #endif }; +#elif defined(TARGET_NANOMIPS) +struct target_sigaction { +abi_ulong _sa_handler; +abi_uint sa_flags; +target_sigset_t sa_mask; +abi_ulong sa_restorer; +}; + #else struct target_old_sigaction { abi_ulong _sa_handler; @@ -537,7 +545,7 @@ typedef struct { #define QEMU_SI_RT 5 typedef struct target_siginfo { -#ifdef TARGET_MIPS +#if defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS) int si_signo; int si_code; int si_errno; @@ -665,13 +673,16 @@ struct target_rlimit { #if defined(TARGET_ALPHA) #define TARGET_RLIM_INFINITY 0x7fffull -#elif defined(TARGET_MIPS) || (defined(TARGET_SPARC) && TARGET_ABI_BITS == 32) +#elif (defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS)) \ + || (defined(TARGET_SPARC) && TARGET_ABI_BITS == 32) #define TARGET_RLIM_INFINITY 0x7fffUL +#elif defined(TARGET_NANOMIPS) +#define TARGET_RLIM_INFINITY0x76ffeec4UL #else #define TARGET_RLIM_INFINITY ((abi_ulong)-1) #endif -#if defined(TARGET_MIPS) +#if defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS) #define TARGET_RLIMIT_CPU 0 #define TARGET_RLIMIT_FSIZE1 #define TARGET_RLIMIT_DATA 2 @@ -687,6 +698,22 @@ struct target_rlimit { #define TARGET_RLIMIT_MSGQUEUE 12 #define TARGET_RLIMIT_NICE 13 #define TARGET_RLIMIT_RTPRIO 14 +#elif defined(TARGET_NANOMIPS) +#define TARGET_RLIMIT_CPU 0 +#define TARGET_RLIMIT_FSIZE 1 +#define TARGET_RLIMIT_DATA 2 +#define TARGET_RLIMIT_STACK 3 +#define TARGET_RLIMIT_CORE 4 +#define TARGET_RLIMIT_RSS 5 +#define TARGET_RLIMIT_NPROC 6 +#define TARGET_RLIMIT_NOFILE7 +#define TARGET_RLIMIT_MEMLOCK 8 +#define TARGET_RLIMIT_AS9 +#define TARGET_RLIMIT_LOCKS 10 +#define TARGET_RLIMIT_SIGPENDING11 +#define TARGET_RLIMIT_MSGQUEUE 12 +#define TARGET_RLIMIT_NICE 13 +#define TARGET_RLIMIT_RTPRIO14 #else #define TARGET_RLIMIT_CPU 0 #define TARGET_RLIMIT_FSIZE1 @@ -1657,6 +1684,10 @@ struct target_stat64 { int64_t st_blocks; }; +#elif defined(TARGET_ABI_MIPSP32) + +/* No struct stat and struct stat64 structures */ + #elif defined(TARGET_ALPHA) struct target_stat { @@ -2009,6 +2040,22 @@ struct target_statfs { int32_t f_flags; int32_t f_spare[5]; }; +#elif defined(TARGET_ABI_MIPSP32) +struct target_statfs { +abi_longf_type; +abi_longf_bsize; +abi_longf_blocks; +abi_longf_bfree; +abi_longf_bavail; +abi_longf_files; +abi_longf_ffree; + +/* Linux specials */ +target_fsid_t f_fsid; +abi_longf_namelen; +abi_llong f_frsize; /* Fragment size - unsupported */ +abi_longf_spare[6]; +}; #else struct target_statfs { abi_longf_type; -- 2.7.4
[Qemu-devel] [PATCH v8 63/87] mips_malta: Add setting up GT64120 BARs to the nanoMIPS bootloader
From: Paul Burton Setup the GT64120 BARs in the nanoMIPS bootloader, in the same way that they are setup in the MIPS32 bootloader. This is necessary for Linux to be able to access peripherals, including the UART. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Aleksandar Markovic Signed-off-by: Paul Burton Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- hw/mips/mips_malta.c | 177 ++- 1 file changed, 160 insertions(+), 17 deletions(-) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 2e851d9..f261dd6 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -609,47 +609,190 @@ static void write_bootloader_nanomips(uint8_t *base, int64_t run_addr, #define NM_HI1(VAL) (((VAL) >> 16) & 0x1f) #define NM_HI2(VAL) \ -(((VAL) & 0xf000) | (((VAL) >> 19) & 0xffc) | (((VAL) >> 31) & 0x1)) + (((VAL) & 0xf000) | (((VAL) >> 19) & 0xffc) | (((VAL) >> 31) & 0x1)) #define NM_LO(VAL) ((VAL) & 0xfff) -stw_p(p++, 0x2800); stw_p(p++, 0x001c); /* bc to_here */ -stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ -stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ -stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ -stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ -stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ -stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ -stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ +stw_p(p++, 0x2800); stw_p(p++, 0x001c); +/* bc to_here */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); +/* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); +/* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); +/* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); +/* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); +/* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); +/* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); +/* nop */ /* to_here: */ -stw_p(p++, 0x0080); stw_p(p++, 0x0002); /* li a0,2 */ +stw_p(p++, 0x0080); stw_p(p++, 0x0002); +/* li a0,2 */ + stw_p(p++, 0xe3a0 | NM_HI1(ENVP_ADDR - 64)); + stw_p(p++, NM_HI2(ENVP_ADDR - 64)); -/* lui sp,%hi(ENVP_ADDR - 64) */ +/* lui sp,%hi(ENVP_ADDR - 64) */ + stw_p(p++, 0x83bd); stw_p(p++, NM_LO(ENVP_ADDR - 64)); /* ori sp,sp,%lo(ENVP_ADDR - 64) */ + stw_p(p++, 0xe0a0 | NM_HI1(ENVP_ADDR)); + stw_p(p++, NM_HI2(ENVP_ADDR)); -/* lui a1,%hi(ENVP_ADDR) */ +/* lui a1,%hi(ENVP_ADDR)*/ + stw_p(p++, 0x80a5); stw_p(p++, NM_LO(ENVP_ADDR)); -/* ori a1,a1,%lo(ENVP_ADDR) */ +/* ori a1,a1,%lo(ENVP_ADDR) */ + stw_p(p++, 0xe0c0 | NM_HI1(ENVP_ADDR + 8)); + stw_p(p++, NM_HI2(ENVP_ADDR + 8)); -/* lui a2,%hi(ENVP_ADDR + 8) */ +/* lui a2,%hi(ENVP_ADDR + 8)*/ + stw_p(p++, 0x80c6); stw_p(p++, NM_LO(ENVP_ADDR + 8)); /* ori a2,a2,%lo(ENVP_ADDR + 8) */ + stw_p(p++, 0xe0e0 | NM_HI1(loaderparams.ram_low_size)); + stw_p(p++, NM_HI2(loaderparams.ram_low_size)); /* lui a3,%hi(loaderparams.ram_low_size) */ + stw_p(p++, 0x80e7); stw_p(p++, NM_LO(loaderparams.ram_low_size)); /* ori a3,a3,%lo(loaderparams.ram_low_size) */ + +/* + * Load BAR registers as done by YAMON: + * + * - set up PCI0 I/O BARs from 0x1800 to 0x181f + * - set up PCI0 MEM0 at 0x1000, size 0x800 + * - set up PCI0 MEM1 at 0x1820, size 0xbe0 + * + */ +stw_p(p++, 0xe040); stw_p(p++, 0x0681); +/* lui t1, %hi(0xb400) */ + +#ifdef TARGET_WORDS_BIGENDIAN + +stw_p(p++, 0xe020); stw_p(p++, 0x0be1); +/* lui t0, %hi(0xdf00) */ + +/* 0x68 corresponds to GT_ISD (from hw/mips/gt64xxx_pci.c) */ +stw_p(p++, 0x8422); stw_p(p++, 0x9068); +/* sw t0, 0x68(t1) */ + +stw_p(p++, 0xe040); stw_p(p++, 0x077d); +/* lui t1, %hi(0xbbe0) */ + +stw_p(p++, 0xe020); stw_p(p++, 0x0801); +/* lui t0, %hi(0xc000) */ + +/* 0x48 corresponds to GT_PCI0IOLD */ +stw_p(p++, 0x8422); stw_p(p++, 0x9048); +/* sw t0, 0x48(t1) */ + +
[Qemu-devel] [PATCH v8 67/87] linux-user: Add syscall numbers for nanoMIPS
From: Aleksandar Rikalo Add syscall numbers for nanoMIPS. nanoMIPS redefines its ABI compared to preceding MIPS architectures, and its set of supported system calls is significantly different. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/nanomips/syscall_nr.h | 275 +++ 1 file changed, 275 insertions(+) create mode 100644 linux-user/nanomips/syscall_nr.h diff --git a/linux-user/nanomips/syscall_nr.h b/linux-user/nanomips/syscall_nr.h new file mode 100644 index 000..b826e5c --- /dev/null +++ b/linux-user/nanomips/syscall_nr.h @@ -0,0 +1,275 @@ +/* + * Linux mipsp32 style syscalls. + */ +#define TARGET_NR_io_setup 0 +#define TARGET_NR_io_destroy 1 +#define TARGET_NR_io_submit 2 +#define TARGET_NR_io_cancel 3 +#define TARGET_NR_io_getevents 4 +#define TARGET_NR_setxattr 5 +#define TARGET_NR_lsetxattr 6 +#define TARGET_NR_fsetxattr 7 +#define TARGET_NR_getxattr 8 +#define TARGET_NR_lgetxattr 9 +#define TARGET_NR_fgetxattr 10 +#define TARGET_NR_listxattr 11 +#define TARGET_NR_llistxattr 12 +#define TARGET_NR_flistxattr 13 +#define TARGET_NR_removexattr14 +#define TARGET_NR_lremovexattr 15 +#define TARGET_NR_fremovexattr 16 +#define TARGET_NR_getcwd 17 +#define TARGET_NR_lookup_dcookie 18 +#define TARGET_NR_eventfd2 19 +#define TARGET_NR_epoll_create1 20 +#define TARGET_NR_epoll_ctl 21 +#define TARGET_NR_epoll_pwait22 +#define TARGET_NR_dup23 +#define TARGET_NR_dup3 24 +#define TARGET_NR_fcntl6425 +#define TARGET_NR_inotify_init1 26 +#define TARGET_NR_inotify_add_watch 27 +#define TARGET_NR_inotify_rm_watch 28 +#define TARGET_NR_ioctl 29 +#define TARGET_NR_ioprio_set 30 +#define TARGET_NR_ioprio_get 31 +#define TARGET_NR_flock 32 +#define TARGET_NR_mknodat33 +#define TARGET_NR_mkdirat34 +#define TARGET_NR_unlinkat 35 +#define TARGET_NR_symlinkat 36 +#define TARGET_NR_linkat 37 +#define TARGET_NR_umount239 +#define TARGET_NR_mount 40 +#define TARGET_NR_pivot_root 41 +#define TARGET_NR_nfsservctl 42 +#define TARGET_NR_statfs64 43 +#define TARGET_NR_fstatfs64 44 +#define TARGET_NR_truncate64 45 +#define TARGET_NR_ftruncate6446 +#define TARGET_NR_fallocate 47 +#define TARGET_NR_faccessat 48 +#define TARGET_NR_chdir 49 +#define TARGET_NR_fchdir 50 +#define TARGET_NR_chroot 51 +#define TARGET_NR_fchmod 52 +#define TARGET_NR_fchmodat 53 +#define TARGET_NR_fchownat 54 +#define TARGET_NR_fchown 55 +#define TARGET_NR_openat 56 +#define TARGET_NR_close 57 +#define TARGET_NR_vhangup58 +#define TARGET_NR_pipe2 59 +#define TARGET_NR_quotactl 60 +#define TARGET_NR_getdents64 61 +#define TARGET_NR__llseek62 +#define TARGET_NR_read 63 +#define TARGET_NR_write 64 +#define TARGET_NR_readv 65 +#define TARGET_NR_writev 66 +#define TARGET_NR_pread6467 +#define TARGET_NR_pwrite64 68 +#define TARGET_NR_preadv 69 +#define TARGET_NR_pwritev70 +#define TARGET_NR_sendfile64 71 +#define TARGET_NR_pselect6 72 +#define TARGET_NR_ppoll 73 +#define TARGET_NR_signalfd4 74 +#define TARGET_NR_vmsplice 75 +#define TARGET_NR_splice 76 +#define TARGET_NR_tee77 +#define TARGET_NR_readlinkat 78 +#define TARGET_NR_sync 81 +#define TARGET_NR_fsync 82 +#define TARGET_NR_fdatasync 83 +#define TARGET_NR_sync_file_range2 84 +#define TARGET_NR_timerfd_create 85 +#define TARGET_NR_timerfd_settime86 +#define TARGET_NR_timerfd_gettime87 +#define TARGET_NR_utimensat 88 +#define TARGET_NR_acct 89 +#define TARGET_NR_capget
[Qemu-devel] [PATCH v8 71/87] linux-user: Add target_fcntl.h header for nanoMIPS
From: Aleksandar Rikalo Add fcntl-related constants and structures for nanoMIPS. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/nanomips/target_fcntl.h | 38 ++ 1 file changed, 38 insertions(+) create mode 100644 linux-user/nanomips/target_fcntl.h diff --git a/linux-user/nanomips/target_fcntl.h b/linux-user/nanomips/target_fcntl.h new file mode 100644 index 000..4203825 --- /dev/null +++ b/linux-user/nanomips/target_fcntl.h @@ -0,0 +1,38 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation, or (at your option) any + * later version. See the COPYING file in the top-level directory. + */ + +#ifndef NANOMIPS_TARGET_FCNTL_H +#define NANOMIPS_TARGET_FCNTL_H + +#define TARGET_O_APPEND 0x000400 +#define TARGET_O_DSYNC 0x001000 +#define TARGET_O_NONBLOCK 0x000800 +#define TARGET_O_CREAT 0x40 +#define TARGET_O_TRUNC 0x000200 +#define TARGET_O_EXCL 0x80 +#define TARGET_O_NOCTTY 0x000100 +#define TARGET_FASYNC 0x002000 +#define TARGET_O_LARGEFILE 0x008000 +#define TARGET___O_SYNC 0x101000 +#define TARGET_O_DIRECT 0x004000 +#define TARGET_O_CLOEXEC0x08 + +#define TARGET_F_GETLK 5 +#define TARGET_F_SETLK 6 +#define TARGET_F_SETLKW7 +#define TARGET_F_SETOWN8 /* for sockets. */ +#define TARGET_F_GETOWN9 /* for sockets. */ + +#define TARGET_ARCH_FLOCK_PAD abi_long pad[4]; +#define TARGET_ARCH_FLOCK64_PAD + +#define TARGET_F_GETLK64 12 /* using 'struct flock64' */ +#define TARGET_F_SETLK64 13 +#define TARGET_F_SETLKW64 14 + +#include "../generic/fcntl.h" +#endif -- 2.7.4
[Qemu-devel] [PATCH v8 76/87] linux-user: Add target_elf.h header for nanoMIPS
From: Dimitrije Nikolic This header includes common elf header, and adds cpu_get_model() function. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/nanomips/target_elf.h | 14 ++ 1 file changed, 14 insertions(+) create mode 100644 linux-user/nanomips/target_elf.h diff --git a/linux-user/nanomips/target_elf.h b/linux-user/nanomips/target_elf.h new file mode 100644 index 000..ca68dab --- /dev/null +++ b/linux-user/nanomips/target_elf.h @@ -0,0 +1,14 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation, or (at your option) any + * later version. See the COPYING file in the top-level directory. + */ + +#ifndef NANOMIPS_TARGET_ELF_H +#define NANOMIPS_TARGET_ELF_H +static inline const char *cpu_get_model(uint32_t eflags) +{ +return "I7200"; +} +#endif -- 2.7.4
[Qemu-devel] [PATCH v8 77/87] linux-user: Add signal.c for nanoMIPS
From: Dimitrije Nikolic Add signal.c as a redirection to regular mips' signal.c, but at the same time amend regular mips' signal.c with bits and pieces specific for nanoMIPS. This was done this way to avoid duplication of large pieces of code. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/mips/signal.c | 25 - linux-user/nanomips/signal.c | 1 + 2 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 linux-user/nanomips/signal.c diff --git a/linux-user/mips/signal.c b/linux-user/mips/signal.c index 6aa303e..ab66429 100644 --- a/linux-user/mips/signal.c +++ b/linux-user/mips/signal.c @@ -21,7 +21,15 @@ #include "signal-common.h" #include "linux-user/trace.h" -# if defined(TARGET_ABI_MIPSO32) +#if defined(TARGET_ABI_MIPSP32) +struct target_sigcontext { +uint64_t sc_regs[32]; +uint64_t sc_pc; +uint32_t sc_used_math; +uint32_t sc_reserved; +}; +#define TARGET_ALMASK (~15) +#elif defined(TARGET_ABI_MIPSO32) struct target_sigcontext { uint32_t sc_regmask; /* Unused */ uint32_t sc_status; @@ -43,6 +51,7 @@ struct target_sigcontext { target_ulong sc_hi3; target_ulong sc_lo3; }; +#define TARGET_ALMASK (~7) # else /* N32 || N64 */ struct target_sigcontext { uint64_t sc_regs[32]; @@ -61,6 +70,7 @@ struct target_sigcontext { uint32_t sc_dsp; uint32_t sc_reserved; }; +#define TARGET_ALMASK (~15) # endif /* O32 */ struct sigframe { @@ -100,6 +110,7 @@ static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall) __put_user(0x2402 + syscall, tramp + 0); __put_user(0x000c , tramp + 1); + return err; } @@ -116,6 +127,7 @@ static inline void setup_sigcontext(CPUMIPSState *regs, __put_user(regs->active_tc.gpr[i], >sc_regs[i]); } +#if !defined(TARGET_ABI_MIPSP32) __put_user(regs->active_tc.HI[0], >sc_mdhi); __put_user(regs->active_tc.LO[0], >sc_mdlo); @@ -137,6 +149,7 @@ static inline void setup_sigcontext(CPUMIPSState *regs, for (i = 0; i < 32; ++i) { __put_user(regs->active_fpu.fpr[i].d, >sc_fpregs[i]); } +#endif } static inline void @@ -146,13 +159,14 @@ restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc) __get_user(regs->CP0_EPC, >sc_pc); -__get_user(regs->active_tc.HI[0], >sc_mdhi); -__get_user(regs->active_tc.LO[0], >sc_mdlo); - for (i = 1; i < 32; ++i) { __get_user(regs->active_tc.gpr[i], >sc_regs[i]); } +#if !defined(TARGET_ABI_MIPSP32) +__get_user(regs->active_tc.HI[0], >sc_mdhi); +__get_user(regs->active_tc.LO[0], >sc_mdlo); + __get_user(regs->active_tc.HI[1], >sc_hi1); __get_user(regs->active_tc.HI[2], >sc_hi2); __get_user(regs->active_tc.HI[3], >sc_hi3); @@ -168,6 +182,7 @@ restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc) for (i = 0; i < 32; ++i) { __get_user(regs->active_fpu.fpr[i].d, >sc_fpregs[i]); } +#endif } /* @@ -185,7 +200,7 @@ get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size) */ sp = target_sigsp(get_sp_from_cpustate(regs) - 32, ka); -return (sp - frame_size) & ~7; +return (sp - frame_size) & TARGET_ALMASK; } static void mips_set_hflags_isa_mode_from_pc(CPUMIPSState *env) diff --git a/linux-user/nanomips/signal.c b/linux-user/nanomips/signal.c new file mode 100644 index 000..86efc21 --- /dev/null +++ b/linux-user/nanomips/signal.c @@ -0,0 +1 @@ +#include "../mips/signal.c" -- 2.7.4
[Qemu-devel] [PATCH v8 57/87] target/mips: Fix ERET/ERETNC behavior related to ADEL exception
From: Yongbok Kim Fix ERET/ERETNC so that ADEL exception can be raised. Reviewed-by: Aleksandar Markovic Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/op_helper.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index 53c1eea..65935e7 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -2430,10 +2430,12 @@ void helper_eretnc(CPUMIPSState *env) void helper_deret(CPUMIPSState *env) { debug_pre_eret(env); -set_pc(env, env->CP0_DEPC); env->hflags &= ~MIPS_HFLAG_DM; compute_hflags(env); + +set_pc(env, env->CP0_DEPC); + debug_post_eret(env); } #endif /* !CONFIG_USER_ONLY */ -- 2.7.4
[Qemu-devel] [PATCH v8 42/87] target/mips: Implement emulation of nanoMIPS LLWP/SCWP pair
From: Aleksandar Rikalo Implement support for nanoMIPS LLWP/SCWP instruction pair. Signed-off-by: Dimitrije Nikolic Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/mips/cpu_loop.c | 25 target/mips/cpu.h | 2 ++ target/mips/translate.c| 74 ++ 3 files changed, 96 insertions(+), 5 deletions(-) diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c index 084ad6a..1d3dc9e 100644 --- a/linux-user/mips/cpu_loop.c +++ b/linux-user/mips/cpu_loop.c @@ -397,10 +397,13 @@ static int do_store_exclusive(CPUMIPSState *env) target_ulong addr; target_ulong page_addr; target_ulong val; +uint32_t val_wp = 0; +uint32_t llnewval_wp = 0; int flags; int segv = 0; int reg; int d; +int wp; addr = env->lladdr; page_addr = addr & TARGET_PAGE_MASK; @@ -412,19 +415,31 @@ static int do_store_exclusive(CPUMIPSState *env) } else { reg = env->llreg & 0x1f; d = (env->llreg & 0x20) != 0; -if (d) { -segv = get_user_s64(val, addr); +wp = (env->llreg & 0x40) != 0; +if (!wp) { +if (d) { +segv = get_user_s64(val, addr); +} else { +segv = get_user_s32(val, addr); +} } else { segv = get_user_s32(val, addr); +segv |= get_user_s32(val_wp, addr); +llnewval_wp = env->llnewval_wp; } if (!segv) { -if (val != env->llval) { +if (val != env->llval && val_wp == llnewval_wp) { env->active_tc.gpr[reg] = 0; } else { -if (d) { -segv = put_user_u64(env->llnewval, addr); +if (!wp) { +if (d) { +segv = put_user_u64(env->llnewval, addr); +} else { +segv = put_user_u32(env->llnewval, addr); +} } else { segv = put_user_u32(env->llnewval, addr); +segv |= put_user_u32(env->llnewval_wp, addr + 4); } if (!segv) { env->active_tc.gpr[reg] = 1; diff --git a/target/mips/cpu.h b/target/mips/cpu.h index 8a8782b..bf9c634 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -506,6 +506,8 @@ struct CPUMIPSState { uint64_t lladdr; target_ulong llval; target_ulong llnewval; +uint64_t llval_wp; +uint32_t llnewval_wp; target_ulong llreg; uint64_t CP0_LLAddr_rw_bitmask; int CP0_LLAddr_shift; diff --git a/target/mips/translate.c b/target/mips/translate.c index 9f27aab..70785f2 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -2401,6 +2401,31 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, tcg_temp_free(t0); } +static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset, +uint32_t reg1, uint32_t reg2) +{ +TCGv taddr = tcg_temp_new(); +TCGv_i64 tval = tcg_temp_new_i64(); +TCGv tmp1 = tcg_temp_new(); +TCGv tmp2 = tcg_temp_new(); + +gen_base_offset_addr(ctx, taddr, base, offset); +tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx); +#ifdef TARGET_WORDS_BIGENDIAN +tcg_gen_extr_i64_tl(tmp2, tmp1, tval); +#else +tcg_gen_extr_i64_tl(tmp1, tmp2, tval); +#endif +gen_store_gpr(tmp1, reg1); +tcg_temp_free(tmp1); +gen_store_gpr(tmp2, reg2); +tcg_temp_free(tmp2); +tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp)); +tcg_temp_free_i64(tval); +tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr)); +tcg_temp_free(taddr); +} + /* Store */ static void gen_st (DisasContext *ctx, uint32_t opc, int rt, int base, int offset) @@ -2497,6 +2522,51 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt, tcg_temp_free(t0); } +static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset, +uint32_t reg1, uint32_t reg2) +{ +TCGv taddr = tcg_temp_local_new(); +TCGv lladdr = tcg_temp_local_new(); +TCGv_i64 tval = tcg_temp_new_i64(); +TCGv_i64 llval = tcg_temp_new_i64(); +TCGv_i64 val = tcg_temp_new_i64(); +TCGv tmp1 = tcg_temp_new(); +TCGv tmp2 = tcg_temp_new(); +TCGLabel *lab_fail = gen_new_label(); +TCGLabel *lab_done = gen_new_label(); + +gen_base_offset_addr(ctx, taddr, base, offset); + +tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr)); +tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail); + +gen_load_gpr(tmp1, reg1); +gen_load_gpr(tmp2, reg2); + +#ifdef TARGET_WORDS_BIGENDIAN +tcg_gen_concat_tl_i64(tval, tmp2, tmp1); +#else +tcg_gen_concat_tl_i64(tval, tmp1, tmp2); +#endif + +tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp)); +tcg_gen_atomic_cmpxchg_i64(val,
[Qemu-devel] [PATCH v8 83/87] linux-user: Add nanoMIPS linux user mode configuration support
From: Stefan Markovic Add new linux user mode configuration for nanoMIPS. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- configure | 13 - default-configs/nanomips-linux-user.mak | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 default-configs/nanomips-linux-user.mak diff --git a/configure b/configure index 2a7796e..86c8b28 100755 --- a/configure +++ b/configure @@ -742,6 +742,9 @@ case "$cpu" in supported_cpu="yes" cross_cc_mips=$host_cc ;; + nanomips*) +cpu="mips" + ;; sparc|sun4[cdmuv]) cpu="sparc" supported_cpu="yes" @@ -6883,7 +6886,7 @@ target_name=$(echo $target | cut -d '-' -f 1) target_bigendian="no" case "$target_name" in - armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb) + armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|nanomipseb|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb) target_bigendian=yes ;; esac @@ -6999,6 +7002,11 @@ case "$target_name" in moxie) target_compiler=$cross_cc_moxie ;; + nanomips|nanomipseb) +TARGET_ARCH=nanomips +TARGET_BASE_ARCH=mips +echo "TARGET_ABI_MIPSP32=y" >> $config_target_mak + ;; nios2) target_compiler=$cross_cc_nios2 ;; @@ -7256,6 +7264,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do moxie*) disas_config "MOXIE" ;; + nanomips*) +disas_config "MIPS" + ;; nios2) disas_config "NIOS2" ;; diff --git a/default-configs/nanomips-linux-user.mak b/default-configs/nanomips-linux-user.mak new file mode 100644 index 000..68fc1f7 --- /dev/null +++ b/default-configs/nanomips-linux-user.mak @@ -0,0 +1 @@ +# Default configuration for nanomips-linux-user -- 2.7.4
[Qemu-devel] [PATCH v8 81/87] linux-user: Add support for statx() syscall for all platforms
From: Aleksandar Rikalo Implement support for translation of system call statx(). The implementation includes invoking other (more mature) syscalls (from the same 'stat' family) on the host side. This way, problems of availability of statx() on the host side are avoided. Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/syscall.c | 121 +- linux-user/syscall_defs.h | 38 +++ 2 files changed, 158 insertions(+), 1 deletion(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index bced9b8..f1b6d71 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8002,7 +8002,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, abi_long ret; #if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) \ || defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64) \ -|| defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64) +|| defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64) \ +|| defined(TARGET_NR_statx) struct stat st; #endif #if defined(TARGET_NR_statfs) || defined(TARGET_NR_statfs64) \ @@ -10025,6 +10026,124 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } break; #endif +#if defined(TARGET_NR_statx) +case TARGET_NR_statx: +{ +struct target_statx *target_stx; +int dirfd = tswap32(arg1); +int flags = tswap32(arg3); + +p = lock_user_string(arg2); +if (p == NULL) { +goto efault; +} +#if defined(__NR_statx) +{ +/* We assume that struct statx is arhitecture independent */ +struct target_statx host_stx; +int mask = tswap32(arg4); + +ret = get_errno(syscall(__NR_statx, dirfd, p, flags, mask, +_stx)); +if (!is_error(ret)) { +unlock_user(p, arg2, 0); +if (!lock_user_struct(VERIFY_WRITE, target_stx, arg5, 0)) { +goto efault; +} +memset(target_stx, 0, sizeof(*target_stx)); + +__put_user(host_stx.stx_mask, _stx->stx_mask); +__put_user(host_stx.stx_blksize, _stx->stx_blksize); +__put_user(host_stx.stx_attributes, + _stx->stx_attributes); +__put_user(host_stx.stx_nlink, _stx->stx_nlink); +__put_user(host_stx.stx_uid, _stx->stx_uid); +__put_user(host_stx.stx_gid, _stx->stx_gid); +__put_user(host_stx.stx_mode, _stx->stx_mode); +__put_user(host_stx.stx_ino, _stx->stx_ino); +__put_user(host_stx.stx_size, _stx->stx_size); +__put_user(host_stx.stx_blocks, _stx->stx_blocks); +__put_user(host_stx.stx_attributes_mask, + _stx->stx_attributes_mask); +__put_user(host_stx.stx_atime.tv_sec, + _stx->stx_atime.tv_sec); +__put_user(host_stx.stx_atime.tv_nsec, + _stx->stx_atime.tv_nsec); +__put_user(host_stx.stx_btime.tv_sec, + _stx->stx_atime.tv_sec); +__put_user(host_stx.stx_btime.tv_nsec, + _stx->stx_atime.tv_nsec); +__put_user(host_stx.stx_ctime.tv_sec, + _stx->stx_atime.tv_sec); +__put_user(host_stx.stx_ctime.tv_nsec, + _stx->stx_atime.tv_nsec); +__put_user(host_stx.stx_mtime.tv_sec, + _stx->stx_atime.tv_sec); +__put_user(host_stx.stx_mtime.tv_nsec, + _stx->stx_atime.tv_nsec); +__put_user(host_stx.stx_rdev_major, + _stx->stx_rdev_major); +__put_user(host_stx.stx_rdev_minor, + _stx->stx_rdev_minor); +__put_user(host_stx.stx_dev_major, + _stx->stx_dev_major); +__put_user(host_stx.stx_dev_minor, + _stx->stx_dev_minor); +} + +if (ret != TARGET_ENOSYS) { +break; +} +} +#endif +if ((p == NULL) || (*((char *)p) == 0)) { +/* By file descriptor */ +ret = get_errno(fstat(dirfd, )); +unlock_user(p, arg2, 0); +} else if (*((char *)p) == '/') { +/* Absolute pathname */ +ret = get_errno(stat(path(p), )); +unlock_user(p, arg2, 0); +} else { +if (dirfd
[Qemu-devel] [PATCH v8 69/87] linux-user: Add termbits.h header for nanoMIPS
From: Aleksandar Rikalo Add termbits.h header for nanoMIPS. Reuse MIPS' termbits.h as the functionalities are almost identical. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/mips/termbits.h | 4 linux-user/nanomips/termbits.h | 1 + 2 files changed, 5 insertions(+) create mode 100644 linux-user/nanomips/termbits.h diff --git a/linux-user/mips/termbits.h b/linux-user/mips/termbits.h index 49a72c5..c7254f4 100644 --- a/linux-user/mips/termbits.h +++ b/linux-user/mips/termbits.h @@ -1,6 +1,10 @@ /* from asm/termbits.h */ +#ifdef TARGET_NANOMIPS +#define TARGET_NCCS 32 +#else #define TARGET_NCCS 23 +#endif struct target_termios { unsigned int c_iflag; /* input mode flags */ diff --git a/linux-user/nanomips/termbits.h b/linux-user/nanomips/termbits.h new file mode 100644 index 000..ea4e962 --- /dev/null +++ b/linux-user/nanomips/termbits.h @@ -0,0 +1 @@ +#include "../mips/termbits.h" -- 2.7.4
[Qemu-devel] [PATCH v8 49/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 5
From: Stefan Markovic Add emulation of DSP ASE instructions for nanoMIPS - part 5. Reviewed-by: Aleksandar Markovic Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 142 1 file changed, 142 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index 68b3599..00d1164 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -17639,6 +17639,144 @@ static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc, tcg_temp_free(v1_t); } +static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc, + int rt, int rs) +{ +int ret = rt; +TCGv t0 = tcg_temp_new(); +TCGv v0_t = tcg_temp_new(); + +gen_load_gpr(v0_t, rs); + +switch (opc) { +case NM_ABSQ_S_QB: +check_dspr2(ctx); +gen_helper_absq_s_qb(v0_t, v0_t, cpu_env); +gen_store_gpr(v0_t, ret); +break; +case NM_ABSQ_S_PH: +check_dsp(ctx); +gen_helper_absq_s_ph(v0_t, v0_t, cpu_env); +gen_store_gpr(v0_t, ret); +break; +case NM_ABSQ_S_W: +check_dsp(ctx); +gen_helper_absq_s_w(v0_t, v0_t, cpu_env); +gen_store_gpr(v0_t, ret); +break; +case NM_PRECEQ_W_PHL: +check_dsp(ctx); +tcg_gen_andi_tl(v0_t, v0_t, 0x); +tcg_gen_ext32s_tl(v0_t, v0_t); +gen_store_gpr(v0_t, ret); +break; +case NM_PRECEQ_W_PHR: +check_dsp(ctx); +tcg_gen_andi_tl(v0_t, v0_t, 0x); +tcg_gen_shli_tl(v0_t, v0_t, 16); +tcg_gen_ext32s_tl(v0_t, v0_t); +gen_store_gpr(v0_t, ret); +break; +case NM_PRECEQU_PH_QBL: +check_dsp(ctx); +gen_helper_precequ_ph_qbl(v0_t, v0_t); +gen_store_gpr(v0_t, ret); +break; +case NM_PRECEQU_PH_QBR: +check_dsp(ctx); +gen_helper_precequ_ph_qbr(v0_t, v0_t); +gen_store_gpr(v0_t, ret); +break; +case NM_PRECEQU_PH_QBLA: +check_dsp(ctx); +gen_helper_precequ_ph_qbla(v0_t, v0_t); +gen_store_gpr(v0_t, ret); +break; +case NM_PRECEQU_PH_QBRA: +check_dsp(ctx); +gen_helper_precequ_ph_qbra(v0_t, v0_t); +gen_store_gpr(v0_t, ret); +break; +case NM_PRECEU_PH_QBL: +check_dsp(ctx); +gen_helper_preceu_ph_qbl(v0_t, v0_t); +gen_store_gpr(v0_t, ret); +break; +case NM_PRECEU_PH_QBR: +check_dsp(ctx); +gen_helper_preceu_ph_qbr(v0_t, v0_t); +gen_store_gpr(v0_t, ret); +break; +case NM_PRECEU_PH_QBLA: +check_dsp(ctx); +gen_helper_preceu_ph_qbla(v0_t, v0_t); +gen_store_gpr(v0_t, ret); +break; +case NM_PRECEU_PH_QBRA: +check_dsp(ctx); +gen_helper_preceu_ph_qbra(v0_t, v0_t); +gen_store_gpr(v0_t, ret); +break; +case NM_REPLV_PH: +check_dsp(ctx); +tcg_gen_ext16u_tl(v0_t, v0_t); +tcg_gen_shli_tl(t0, v0_t, 16); +tcg_gen_or_tl(v0_t, v0_t, t0); +tcg_gen_ext32s_tl(v0_t, v0_t); +gen_store_gpr(v0_t, ret); +break; +case NM_REPLV_QB: +check_dsp(ctx); +tcg_gen_ext8u_tl(v0_t, v0_t); +tcg_gen_shli_tl(t0, v0_t, 8); +tcg_gen_or_tl(v0_t, v0_t, t0); +tcg_gen_shli_tl(t0, v0_t, 16); +tcg_gen_or_tl(v0_t, v0_t, t0); +tcg_gen_ext32s_tl(v0_t, v0_t); +gen_store_gpr(v0_t, ret); +break; +case NM_BITREV: +check_dsp(ctx); +gen_helper_bitrev(v0_t, v0_t); +gen_store_gpr(v0_t, ret); +break; +case NM_INSV: +check_dsp(ctx); +{ +TCGv tv0 = tcg_temp_new(); + +gen_load_gpr(tv0, rt); +gen_helper_insv(v0_t, cpu_env, v0_t, tv0); +gen_store_gpr(v0_t, ret); +tcg_temp_free(tv0); +} +break; +case NM_RADDU_W_QB: +check_dsp(ctx); +gen_helper_raddu_w_qb(v0_t, v0_t); +gen_store_gpr(v0_t, ret); +break; +case NM_BITSWAP: +gen_bitswap(ctx, OPC_BITSWAP, ret, rs); +break; +case NM_CLO: +gen_cl(ctx, OPC_CLO, ret, rs); +break; +case NM_CLZ: +gen_cl(ctx, OPC_CLZ, ret, rs); +break; +case NM_WSBH: +gen_bshfl(ctx, OPC_WSBH, ret, rs); +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} + +tcg_temp_free(v0_t); +tcg_temp_free(t0); +} + static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) { @@ -17660,6 +17798,10 @@ static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) } break; case NM_POOL32AXF_4: +{ +int32_t op1 = extract32(ctx->opcode, 9, 7); +gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs); +} break;
[Qemu-devel] [PATCH v8 84/87] linux-user: Add nanoMIPS support in scripts/qemu-binfmt-conf.sh
From: Aleksandar Rikalo Add support for nanomips[eb] variant in scripts/qemu-binfmt-conf.sh. Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- scripts/qemu-binfmt-conf.sh | 16 +++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh index b0dc8a7..adb96ac 100755 --- a/scripts/qemu-binfmt-conf.sh +++ b/scripts/qemu-binfmt-conf.sh @@ -2,7 +2,7 @@ # Enable automatic program execution by the kernel. qemu_target_list="i386 i486 alpha arm armeb sparc32plus ppc ppc64 ppc64le m68k \ -mips mipsel mipsn32 mipsn32el mips64 mips64el \ +mips mipsel mipsn32 mipsn32el mips64 mips64el nanomips nanomipseb \ sh4 sh4eb s390x aarch64 aarch64_be hppa riscv32 riscv64 xtensa xtensaeb \ microblaze microblazeel or1k" @@ -76,6 +76,14 @@ mips64el_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\ mips64el_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff' mips64el_family=mips +nanomips_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf9\x00' +nanomips_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' +nanomips_family=nanomips + +nanomipseb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf9' +nanomipseb_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' +nanomipseb_family=nanomipseb + sh4_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00' sh4_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff' sh4_family=sh4 @@ -137,6 +145,12 @@ qemu_get_family() { mips*) echo "mips" ;; +nanomips) +echo "nanomips" +;; +nanomipseb) +echo "nanomipseb" +;; "Power Macintosh"|ppc64|powerpc|ppc) echo "ppc" ;; -- 2.7.4
[Qemu-devel] [PATCH v8 82/87] linux-user: Add support for nanoMIPS core files
From: Aleksandar Rikalo nanoMIPs core files require value EF_NANOMIPS_ABI_P32 to be passed to the e_flags part of the core's elf header. Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/elfload.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 8638612..366ef3b 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1291,6 +1291,10 @@ static inline void init_thread(struct target_pt_regs *regs, #define ELF_CLASS ELFCLASS64 #endif +#ifdef TARGET_ABI_MIPSP32 +#define ELF_FLAGS EF_NANOMIPS_ABI_P32 +#endif + static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) { @@ -1400,6 +1404,10 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, #define ELF_HWCAP 0 #endif +#ifndef ELF_FLAGS +#define ELF_FLAGS 0 +#endif + #ifndef STACK_GROWS_DOWN #define STACK_GROWS_DOWN 1 #endif @@ -3432,7 +3440,7 @@ static int elf_core_dump(int signr, const CPUArchState *env) * Construct valid coredump ELF header. We also * add one more segment for notes. */ -fill_elf_header(, segs + 1, ELF_MACHINE, 0); +fill_elf_header(, segs + 1, ELF_MACHINE, ELF_FLAGS); if (dump_write(fd, , sizeof (elf)) != 0) goto out; -- 2.7.4
[Qemu-devel] [PATCH v8 75/87] linux-user: Add target_structs.h header for nanoMIPS
From: Dimitrije Nikolic Add target_structs.h header for nanoMIPS, that in fact only redirects to the corresponding MIPS header. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/nanomips/target_structs.h | 1 + 1 file changed, 1 insertion(+) create mode 100644 linux-user/nanomips/target_structs.h diff --git a/linux-user/nanomips/target_structs.h b/linux-user/nanomips/target_structs.h new file mode 100644 index 000..cc6c6ea --- /dev/null +++ b/linux-user/nanomips/target_structs.h @@ -0,0 +1 @@ +#include "../mips/target_structs.h" -- 2.7.4
[Qemu-devel] [PATCH v8 50/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 6
From: Stefan Markovic Add emulation of DSP ASE instructions for nanoMIPS - part 6. Reviewed-by: Aleksandar Markovic Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 62 + 1 file changed, 62 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index 00d1164..3282fca 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -1,6 +1,64 @@ static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc, tcg_temp_free(t0); } +static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc, + int rt, int rs, int rd) +{ +TCGv t0; +TCGv rs_t; + +if (rt == 0) { +/* Treat as NOP. */ +return; +} + +t0 = tcg_temp_new(); +rs_t = tcg_temp_new(); + +gen_load_gpr(rs_t, rs); + +switch (opc) { +case NM_SHRA_R_QB: +check_dspr2(ctx); +tcg_gen_movi_tl(t0, rd >> 2); +switch (extract32(ctx->opcode, 12, 1)) { +case 0: +/* NM_SHRA_QB */ +gen_helper_shra_qb(cpu_gpr[rt], t0, rs_t); +break; +case 1: +/* NM_SHRA_R_QB */ +gen_helper_shra_r_qb(cpu_gpr[rt], t0, rs_t); +break; +} +break; +case NM_SHRL_PH: +check_dspr2(ctx); +tcg_gen_movi_tl(t0, rd >> 1); +gen_helper_shrl_ph(cpu_gpr[rt], t0, rs_t); +break; +case NM_REPL_QB: +check_dsp(ctx); +{ +int16_t imm; +target_long result; +imm = extract32(ctx->opcode, 13, 8); +result = (uint32_t)imm << 24 | + (uint32_t)imm << 16 | + (uint32_t)imm << 8 | + (uint32_t)imm; +result = (int32_t)result; +tcg_gen_movi_tl(cpu_gpr[rt], result); +} +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} +tcg_temp_free(t0); +tcg_temp_free(rs_t); +} + static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) { @@ -17872,6 +17930,10 @@ static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) } break; case NM_POOL32AXF_7: +{ +int32_t op1 = extract32(ctx->opcode, 9, 3); +gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd); +} break; default: generate_exception_end(ctx, EXCP_RI); -- 2.7.4
[Qemu-devel] [PATCH v8 87/87] qemu-doc: Add nanoMIPS-related items
From: Aleksandar Markovic Add nanoMIPS-related items in qemu-doc.texi Reviewed-by: Thomas Huth Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- qemu-doc.texi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qemu-doc.texi b/qemu-doc.texi index 8ea6bfa..ab2471d 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -2705,6 +2705,8 @@ The binary format is detected automatically. @command{qemu-mipsn32el} executes 32-bit little endian MIPS binaries (MIPS N32 ABI). +@command{qemu-nanomips} executes 32-bit little endian nanoMIPS binaries (MIPS P32 ABI). + @cindex user mode (NiosII) @command{qemu-nios2} TODO. -- 2.7.4
[Qemu-devel] [PATCH v8 80/87] linux-user: Amend support for sigaction() syscall for nanoMIPS
From: Aleksandar Rikalo Amend sigaction syscall support for nanoMIPS. This must be done since nanoMIPS' signal handling is different than MIPS' signal handling. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/syscall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 3d57966..bced9b8 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8825,7 +8825,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, old_act->sa_flags = oact.sa_flags; unlock_user_struct(old_act, arg3, 1); } -#elif defined(TARGET_MIPS) +#elif defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS) struct target_sigaction act, oact, *pact, *old_act; if (arg2) { -- 2.7.4
[Qemu-devel] [PATCH v8 68/87] linux-user: Add target_signal.h header for nanoMIPS
From: Aleksandar Rikalo nanoMIPS signal handling is much closer to the signal handling in other mainstream platforms than to the signal handling in preceding MIPS platforms. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/nanomips/target_signal.h | 22 ++ 1 file changed, 22 insertions(+) create mode 100644 linux-user/nanomips/target_signal.h diff --git a/linux-user/nanomips/target_signal.h b/linux-user/nanomips/target_signal.h new file mode 100644 index 000..604e853 --- /dev/null +++ b/linux-user/nanomips/target_signal.h @@ -0,0 +1,22 @@ +#ifndef NANOMIPS_TARGET_SIGNAL_H +#define NANOMIPS_TARGET_SIGNAL_H + +#include "../generic/signal.h" +#undef TARGET_SIGRTMIN +#define TARGET_SIGRTMIN 35 + +/* this struct defines a stack used during syscall handling */ +typedef struct target_sigaltstack { +abi_long ss_sp; +abi_ulong ss_size; +abi_long ss_flags; +} target_stack_t; + +/* sigaltstack controls */ +#define TARGET_SS_ONSTACK 1 +#define TARGET_SS_DISABLE 2 + +#define TARGET_MINSIGSTKSZ6144 +#define TARGET_SIGSTKSZ 12288 + +#endif -- 2.7.4
[Qemu-devel] [PATCH v8 65/87] target/mips: Add definition of nanoMIPS I7200 CPU
From: Stefan Markovic Add definition of the first nanoMIPS processor in QEMU. Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate_init.inc.c | 39 +++ 1 file changed, 39 insertions(+) diff --git a/target/mips/translate_init.inc.c b/target/mips/translate_init.inc.c index c7ba6ee..b3320b9 100644 --- a/target/mips/translate_init.inc.c +++ b/target/mips/translate_init.inc.c @@ -449,6 +449,45 @@ const mips_def_t mips_defs[] = .insn_flags = CPU_MIPS32R6 | ASE_MICROMIPS, .mmu_type = MMU_TYPE_R4000, }, +{ +.name = "I7200", +.CP0_PRid = 0x0001, +.CP0_Config0 = MIPS_CONFIG0 | (1 << CP0C0_MM) | (0x2 << CP0C0_AR) | +(MMU_TYPE_R4000 << CP0C0_MT), +.CP0_Config1 = (1U << CP0C1_M) | (15 << CP0C1_MMU) | (2 << CP0C1_IS) | + (4 << CP0C1_IL) | (3 << CP0C1_IA) | (2 << CP0C1_DS) | + (4 << CP0C1_DL) | (3 << CP0C1_DA) | (1 << CP0C1_PC) | + (1 << CP0C1_EP), +.CP0_Config2 = MIPS_CONFIG2, +.CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_CMGCR) | + (1 << CP0C3_BI) | (1 << CP0C3_SC) | (3 << CP0C3_MMAR) | + (1 << CP0C3_ISA_ON_EXC) | (1 << CP0C3_ISA) | + (1 << CP0C3_ULRI) | (1 << CP0C3_RXI) | + (1 << CP0C3_DSP2P) | (1 << CP0C3_DSPP) | + (1 << CP0C3_CTXTC) | (1 << CP0C3_VInt) | + (1 << CP0C3_CDMM) | (1 << CP0C3_MT) | (1 << CP0C3_TL), +.CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) | + (2 << CP0C4_IE) | (1U << CP0C4_M), +.CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_MVH) | (1 << CP0C5_LLB), +.CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) | + (1 << CP0C5_UFE), +.CP0_LLAddr_rw_bitmask = 0, +.CP0_LLAddr_shift = 0, +.SYNCI_Step = 32, +.CCRes = 2, +.CP0_Status_rw_bitmask = 0x3158FF1F, +.CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) | + (1U << CP0PG_RIE), +.CP0_PageGrain_rw_bitmask = 0, +.CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) | +(1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | +(1 << FCR0_S) | (0x02 << FCR0_PRID) | (0x0 << FCR0_REV), +.CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), +.SEGBITS = 32, +.PABITS = 32, +.insn_flags = CPU_NANOMIPS32 | ASE_DSP | ASE_DSPR2 | ASE_MT, +.mmu_type = MMU_TYPE_R4000, +}, #if defined(TARGET_MIPS64) { .name = "R4000", -- 2.7.4
[Qemu-devel] [PATCH v8 52/87] target/mips: Add handling of branch delay slots for nanoMIPS
From: Matthew Fortune ISA mode bit (LSB of address) is no longer required but is also masked to allow for tools transition. The flag has_isa_mode has the key role in the implementation. Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 3282fca..e4427e4 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -1471,6 +1471,7 @@ typedef struct DisasContext { bool mrp; bool nan2008; bool abs2008; +bool has_isa_mode; } DisasContext; #define DISAS_STOP DISAS_TARGET_0 @@ -4674,7 +4675,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, if (blink > 0) { int post_delay = insn_bytes + delayslot_size; -int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16); +int lowbit = ctx->has_isa_mode && !!(ctx->hflags & MIPS_HFLAG_M16); tcg_gen_movi_tl(cpu_gpr[blink], ctx->base.pc_next + post_delay + lowbit); @@ -11171,7 +11172,7 @@ static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, int bcond_compute = 0; TCGv t0 = tcg_temp_new(); TCGv t1 = tcg_temp_new(); -int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0; +int m16_lowbit = ctx->has_isa_mode && ((ctx->hflags & MIPS_HFLAG_M16) != 0); if (ctx->hflags & MIPS_HFLAG_BMASK) { #ifdef MIPS_DEBUG_DISAS @@ -24970,6 +24971,7 @@ static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; +ctx->has_isa_mode = ((env->CP0_Config3 >> CP0C3_MMAR) & 0x7) < 3; restore_cpu_state(env, ctx); #ifdef CONFIG_USER_ONLY ctx->mem_idx = MIPS_HFLAG_UM; -- 2.7.4
[Qemu-devel] [PATCH v8 66/87] elf: Add nanoMIPS specific variations in ELF header fields
From: Aleksandar Rikalo Add nanoMIPS-related values in ELF header fields as specified in nanoMIPS' "ELF ABI Supplement". Reviewed-by: Aleksandar Markovic Acked-by: Richard Henderson Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- include/elf.h | 18 ++ 1 file changed, 18 insertions(+) diff --git a/include/elf.h b/include/elf.h index 312f68a..341960c 100644 --- a/include/elf.h +++ b/include/elf.h @@ -62,6 +62,24 @@ typedef int64_t Elf64_Sxword; #define EF_MIPS_FP64 0x0200 #define EF_MIPS_NAN2008 0x0400 +/* nanoMIPS architecture bits, EF_NANOMIPS_ARCH */ +#define EF_NANOMIPS_ARCH_32R6 0x /* 32-bit nanoMIPS Release 6 ISA */ +#define EF_NANOMIPS_ARCH_64R6 0x1000 /* 62-bit nanoMIPS Release 6 ISA */ + +/* nanoMIPS ABI bits, EF_NANOMIPS_ABI */ +#define EF_NANOMIPS_ABI_P32 0x1000 /* 32-bit nanoMIPS ABI */ +#define EF_NANOMIPS_ABI_P64 0x2000 /* 64-bit nanoMIPS ABI */ + +/* nanoMIPS processor specific flags, e_flags */ +#define EF_NANOMIPS_LINKRELAX 0x0001 /* Link-time relaxation*/ +#define EF_NANOMIPS_PIC 0x0002 /* Position independent code */ +#define EF_NANOMIPS_32BITMODE 0x0004 /* 32-bit object for 64-bit arch. */ +#define EF_NANOMIPS_PID 0x0008 /* Position independent data */ +#define EF_NANOMIPS_PCREL 0x0010 /* PC-relative mode*/ +#define EF_NANOMIPS_ABI 0xf000 /* nanoMIPS ABI*/ +#define EF_NANOMIPS_MACH 0x00ff /* Machine variant */ +#define EF_NANOMIPS_ARCH 0xf000 /* nanoMIPS architecture */ + /* MIPS machine variant */ #define EF_MIPS_MACH_NONE 0x /* A standard MIPS implementation */ #define EF_MIPS_MACH_3900 0x0081 /* Toshiba R3900 */ -- 2.7.4
[Qemu-devel] [PATCH v8 61/87] elf: On elf loading, treat both EM_MIPS and EM_NANOMIPS as legal for MIPS
From: Aleksandar Rikalo Modify load_elf32()/load_elf64() to treat EM_NANOMIPS as equal to EM_MIPS. Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- include/hw/elf_ops.h | 8 1 file changed, 8 insertions(+) diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index b6e19e3..81cecaf 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -327,6 +327,14 @@ static int glue(load_elf, SZ)(const char *name, int fd, } } break; +case EM_MIPS: +case EM_NANOMIPS: +if ((ehdr.e_machine != EM_MIPS) && +(ehdr.e_machine != EM_NANOMIPS)) { +ret = ELF_LOAD_WRONG_ARCH; +goto fail; +} +break; default: if (elf_machine != ehdr.e_machine) { ret = ELF_LOAD_WRONG_ARCH; -- 2.7.4
[Qemu-devel] [PATCH v8 62/87] mips_malta: Add basic nanoMIPS boot code for Malta board
From: Matthew Fortune Add basic nanoMIPS boot code for Malta. Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- hw/mips/mips_malta.c | 63 +--- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 3467451..2e851d9 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -599,6 +599,59 @@ static void network_init(PCIBus *pci_bus) } } +static void write_bootloader_nanomips(uint8_t *base, int64_t run_addr, + int64_t kernel_entry) +{ +uint16_t *p; + +/* Small bootloader */ +p = (uint16_t *)base; + +#define NM_HI1(VAL) (((VAL) >> 16) & 0x1f) +#define NM_HI2(VAL) \ +(((VAL) & 0xf000) | (((VAL) >> 19) & 0xffc) | (((VAL) >> 31) & 0x1)) +#define NM_LO(VAL) ((VAL) & 0xfff) + +stw_p(p++, 0x2800); stw_p(p++, 0x001c); /* bc to_here */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ + +/* to_here: */ +stw_p(p++, 0x0080); stw_p(p++, 0x0002); /* li a0,2 */ +stw_p(p++, 0xe3a0 | NM_HI1(ENVP_ADDR - 64)); +stw_p(p++, NM_HI2(ENVP_ADDR - 64)); +/* lui sp,%hi(ENVP_ADDR - 64) */ +stw_p(p++, 0x83bd); stw_p(p++, NM_LO(ENVP_ADDR - 64)); +/* ori sp,sp,%lo(ENVP_ADDR - 64) */ +stw_p(p++, 0xe0a0 | NM_HI1(ENVP_ADDR)); +stw_p(p++, NM_HI2(ENVP_ADDR)); +/* lui a1,%hi(ENVP_ADDR) */ +stw_p(p++, 0x80a5); stw_p(p++, NM_LO(ENVP_ADDR)); +/* ori a1,a1,%lo(ENVP_ADDR) */ +stw_p(p++, 0xe0c0 | NM_HI1(ENVP_ADDR + 8)); +stw_p(p++, NM_HI2(ENVP_ADDR + 8)); +/* lui a2,%hi(ENVP_ADDR + 8) */ +stw_p(p++, 0x80c6); stw_p(p++, NM_LO(ENVP_ADDR + 8)); +/* ori a2,a2,%lo(ENVP_ADDR + 8) */ +stw_p(p++, 0xe0e0 | NM_HI1(loaderparams.ram_low_size)); +stw_p(p++, NM_HI2(loaderparams.ram_low_size)); +/* lui a3,%hi(loaderparams.ram_low_size) */ +stw_p(p++, 0x80e7); stw_p(p++, NM_LO(loaderparams.ram_low_size)); +/* ori a3,a3,%lo(loaderparams.ram_low_size) */ +stw_p(p++, 0xe320 | NM_HI1(kernel_entry)); +stw_p(p++, NM_HI2(kernel_entry)); +/* lui t9,%hi(kernel_entry) */ +stw_p(p++, 0x8339); stw_p(p++, NM_LO(kernel_entry)); +/* ori t9,t9,%lo(kernel_entry) */ +stw_p(p++, 0x4bf9); stw_p(p++, 0x); +/* jalrc t8 */ +} + /* ROM and pseudo bootloader The following code implements a very very simple bootloader. It first @@ -620,7 +673,6 @@ static void network_init(PCIBus *pci_bus) a2 - 32-bit address of the environment variables table a3 - RAM size in bytes */ - static void write_bootloader(uint8_t *base, int64_t run_addr, int64_t kernel_entry) { @@ -1096,8 +1148,13 @@ void mips_malta_init(MachineState *machine) loaderparams.initrd_filename = initrd_filename; kernel_entry = load_kernel(); -write_bootloader(memory_region_get_ram_ptr(bios), - bootloader_run_addr, kernel_entry); +if (!cpu_supports_isa(machine->cpu_type, ISA_NANOMIPS32)) { +write_bootloader(memory_region_get_ram_ptr(bios), + bootloader_run_addr, kernel_entry); +} else { +write_bootloader_nanomips(memory_region_get_ram_ptr(bios), + bootloader_run_addr, kernel_entry); +} if (kvm_enabled()) { /* Write the bootloader code @ the end of RAM, 1MB reserved */ write_bootloader(memory_region_get_ram_ptr(ram_low_preio) + -- 2.7.4
[Qemu-devel] [PATCH v8 39/87] target/mips: Implement emulation of nanoMIPS ROTX instruction
From: Matthew Fortune Added a helper for ROTX based on the pseudocode from the architecture spec. This instraction was not present in previous MIPS instruction sets. Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic Reviewed-by: Aleksandar Markovic Reviewed-by: Richard Henderson --- target/mips/helper.h| 2 ++ target/mips/op_helper.c | 94 + target/mips/translate.c | 15 3 files changed, 111 insertions(+) diff --git a/target/mips/helper.h b/target/mips/helper.h index 5f49234..b2a780a 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -40,6 +40,8 @@ DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl) DEF_HELPER_FLAGS_1(dbitswap, TCG_CALL_NO_RWG_SE, tl, tl) #endif +DEF_HELPER_FLAGS_4(rotx, TCG_CALL_NO_RWG_SE, tl, tl, i32, i32, i32) + #ifndef CONFIG_USER_ONLY /* CP0 helpers */ DEF_HELPER_1(mfc0_mvpcontrol, tl, env) diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index 0b2663b..b3eef9f 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -249,6 +249,100 @@ target_ulong helper_bitswap(target_ulong rt) return (int32_t)bitswap(rt); } +target_ulong helper_rotx(target_ulong rs, uint32_t shift, uint32_t shiftx, +uint32_t stripe) +{ +int i; +uint64_t tmp0 = ((uint64_t)rs) << 32 | ((uint64_t)rs & 0x); +uint64_t tmp1 = tmp0; +for (i = 0; i <= 46; i++) { +int s; +if (i & 0x8) { +s = shift; +} else { +s = shiftx; +} + +if (stripe != 0 && !(i & 0x4)) { +s = ~s; +} +if (s & 0x10) { +if (tmp0 & (1LL << (i + 16))) { +tmp1 |= 1LL << i; +} else { +tmp1 &= ~(1LL << i); +} +} +} + +uint64_t tmp2 = tmp1; +for (i = 0; i <= 38; i++) { +int s; +if (i & 0x4) { +s = shift; +} else { +s = shiftx; +} + +if (s & 0x8) { +if (tmp1 & (1LL << (i + 8))) { +tmp2 |= 1LL << i; +} else { +tmp2 &= ~(1LL << i); +} +} +} + +uint64_t tmp3 = tmp2; +for (i = 0; i <= 34; i++) { +int s; +if (i & 0x2) { +s = shift; +} else { +s = shiftx; +} +if (s & 0x4) { +if (tmp2 & (1LL << (i + 4))) { +tmp3 |= 1LL << i; +} else { +tmp3 &= ~(1LL << i); +} +} +} + +uint64_t tmp4 = tmp3; +for (i = 0; i <= 32; i++) { +int s; +if (i & 0x1) { +s = shift; +} else { +s = shiftx; +} +if (s & 0x2) { +if (tmp3 & (1LL << (i + 2))) { +tmp4 |= 1LL << i; +} else { +tmp4 &= ~(1LL << i); +} +} +} + +uint64_t tmp5 = tmp4; +for (i = 0; i <= 31; i++) { +int s; +s = shift; +if (s & 0x1) { +if (tmp4 & (1LL << (i + 1))) { +tmp5 |= 1LL << i; +} else { +tmp5 &= ~(1LL << i); +} +} +} + +return (int64_t)(int32_t)(uint32_t)tmp5; +} + #ifndef CONFIG_USER_ONLY static inline hwaddr do_translate_address(CPUMIPSState *env, diff --git a/target/mips/translate.c b/target/mips/translate.c index a97a989..02c9813 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -17722,6 +17722,21 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) } break; case NM_P_ROTX: +if (rt != 0) { +TCGv t0 = tcg_temp_new(); +TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5)); +TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4) +<< 1); +TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1)); + +gen_load_gpr(t0, rs); +gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe); +tcg_temp_free(t0); + +tcg_temp_free_i32(shift); +tcg_temp_free_i32(shiftx); +tcg_temp_free_i32(stripe); +} break; case NM_P_INS: switch (((ctx->opcode >> 10) & 2) | -- 2.7.4
[Qemu-devel] [PATCH v8 60/87] elf: Don't check FCR31_NAN2008 bit for nanoMIPS
From: Aleksandar Markovic nanoMIPS is always NaN2008 compliant, and rules for checking FCR31's NAN2008 bit are obsoleted. Reviewed-by: Richard Henderson Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/mips/cpu_loop.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c index 1d3dc9e..c9c20cf 100644 --- a/linux-user/mips/cpu_loop.c +++ b/linux-user/mips/cpu_loop.c @@ -747,6 +747,9 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) if (regs->cp0_epc & 1) { env->hflags |= MIPS_HFLAG_M16; } +if (env->insn_flags & ISA_NANOMIPS32) { +return; +} if (((info->elf_flags & EF_MIPS_NAN2008) != 0) != ((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) != 0)) { if ((env->active_fpu.fcr31_rw_bitmask & -- 2.7.4
[Qemu-devel] [PATCH v8 56/87] target/mips: Adjust set_pc() for nanoMIPS
From: James Hogan ERET and ERETNC shouldn't clear MIPS_HFLAG_M16 for nanoMIPS since there is no ISA bit, so fix set_pc() to skip the hflags update. Signed-off-by: James Hogan Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic Reviewed-by: Aleksandar Markovic --- target/mips/op_helper.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index b3eef9f..53c1eea 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -2392,6 +2392,9 @@ static void debug_post_eret(CPUMIPSState *env) static void set_pc(CPUMIPSState *env, target_ulong error_pc) { env->active_tc.PC = error_pc & ~(target_ulong)1; +if (env->insn_flags & ISA_NANOMIPS32) { +return; +} if (error_pc & 1) { env->hflags |= MIPS_HFLAG_M16; } else { -- 2.7.4
[Qemu-devel] [PATCH v8 74/87] linux-user: Add target_cpu.h header for nanoMIPS
From: Dimitrije Nikolic Add target_cpu.h header for nanoMIPS. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/nanomips/target_cpu.h | 21 + 1 file changed, 21 insertions(+) create mode 100644 linux-user/nanomips/target_cpu.h diff --git a/linux-user/nanomips/target_cpu.h b/linux-user/nanomips/target_cpu.h new file mode 100644 index 000..bbb51de --- /dev/null +++ b/linux-user/nanomips/target_cpu.h @@ -0,0 +1,21 @@ +#ifndef NANOMIPS_TARGET_CPU_H +#define NANOMIPS_TARGET_CPU_H + +static inline void cpu_clone_regs(CPUMIPSState *env, target_ulong newsp) +{ +if (newsp) { +env->active_tc.gpr[29] = newsp; +} +env->active_tc.gpr[4] = 0; +} + +static inline void cpu_set_tls(CPUMIPSState *env, target_ulong newtls) +{ +env->active_tc.CP0_UserLocal = newtls; +} + +static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state) +{ +return state->active_tc.gpr[29]; +} +#endif -- 2.7.4
[Qemu-devel] [PATCH v8 41/87] target/mips: Add emulation of nanoMIPS 32-bit load and store instructions
From: Yongbok Kim Add emulation of various nanoMIPS load and store instructions. Reviewed-by: Richard Henderson Reviewed-by: Aleksandar Markovic Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 277 1 file changed, 277 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index 27f56c4..9f27aab 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -17814,10 +17814,287 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) } break; case NM_P_GP_BH: +{ +uint32_t u = extract32(ctx->opcode, 0, 18); + +switch (extract32(ctx->opcode, 18, 3)) { +case NM_LBGP: +gen_ld(ctx, OPC_LB, rt, 28, u); +break; +case NM_SBGP: +gen_st(ctx, OPC_SB, rt, 28, u); +break; +case NM_LBUGP: +gen_ld(ctx, OPC_LBU, rt, 28, u); +break; +case NM_ADDIUGP_B: +if (rt != 0) { +gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u); +} +break; +case NM_P_GP_LH: +u &= ~1; +switch (ctx->opcode & 1) { +case NM_LHGP: +gen_ld(ctx, OPC_LH, rt, 28, u); +break; +case NM_LHUGP: +gen_ld(ctx, OPC_LHU, rt, 28, u); +break; +} +break; +case NM_P_GP_SH: +u &= ~1; +switch (ctx->opcode & 1) { +case NM_SHGP: +gen_st(ctx, OPC_SH, rt, 28, u); +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} +break; +case NM_P_GP_CP1: +u &= ~0x3; +switch (ctx->opcode & 0x3) { +case NM_LWC1GP: +gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u); +break; +case NM_LDC1GP: +gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u); +break; +case NM_SWC1GP: +gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u); +break; +case NM_SDC1GP: +gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u); +break; +} +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} +} break; case NM_P_LS_U12: +{ +uint32_t u = extract32(ctx->opcode, 0, 12); + +switch (extract32(ctx->opcode, 12, 4)) { +case NM_P_PREFU12: +if (rt == 31) { +/* SYNCI */ +/* Break the TB to be able to sync copied instructions + immediately */ +ctx->base.is_jmp = DISAS_STOP; +} else { +/* PREF */ +/* Treat as NOP. */ +} +break; +case NM_LB: +gen_ld(ctx, OPC_LB, rt, rs, u); +break; +case NM_LH: +gen_ld(ctx, OPC_LH, rt, rs, u); +break; +case NM_LW: +gen_ld(ctx, OPC_LW, rt, rs, u); +break; +case NM_LBU: +gen_ld(ctx, OPC_LBU, rt, rs, u); +break; +case NM_LHU: +gen_ld(ctx, OPC_LHU, rt, rs, u); +break; +case NM_SB: +gen_st(ctx, OPC_SB, rt, rs, u); +break; +case NM_SH: +gen_st(ctx, OPC_SH, rt, rs, u); +break; +case NM_SW: +gen_st(ctx, OPC_SW, rt, rs, u); +break; +case NM_LWC1: +gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u); +break; +case NM_LDC1: +gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u); +break; +case NM_SWC1: +gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u); +break; +case NM_SDC1: +gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u); +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} +} break; case NM_P_LS_S9: +{ +int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) | +extract32(ctx->opcode, 0, 8); + +switch (extract32(ctx->opcode, 8, 3)) { +case NM_P_LS_S0: +switch
[Qemu-devel] [PATCH v8 72/87] linux-user: Add sockbits.h header for nanoMIPS
From: Aleksandar Rikalo Add sockbits.h header for nanoMIPS. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/nanomips/sockbits.h | 1 + 1 file changed, 1 insertion(+) create mode 100644 linux-user/nanomips/sockbits.h diff --git a/linux-user/nanomips/sockbits.h b/linux-user/nanomips/sockbits.h new file mode 100644 index 000..e6b6d31 --- /dev/null +++ b/linux-user/nanomips/sockbits.h @@ -0,0 +1 @@ +#include "../mips/sockbits.h" -- 2.7.4
[Qemu-devel] [PATCH v8 48/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 4
From: Stefan Markovic Add emulation of DSP ASE instructions for nanoMIPS - part 4. Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 363 1 file changed, 363 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index c03908b..68b3599 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -17280,6 +17280,365 @@ static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc, tcg_temp_free(v0_t); } +static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc, +TCGv v0, TCGv v1, int rd) +{ +TCGv_i32 t0; + +t0 = tcg_temp_new_i32(); + +tcg_gen_movi_i32(t0, rd >> 3); + +switch (opc) { +case NM_POOL32AXF_2_0_7: +switch (extract32(ctx->opcode, 9, 3)) { +case NM_DPA_W_PH: +check_dspr2(ctx); +gen_helper_dpa_w_ph(t0, v1, v0, cpu_env); +break; +case NM_DPAQ_S_W_PH: +check_dsp(ctx); +gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env); +break; +case NM_DPS_W_PH: +check_dspr2(ctx); +gen_helper_dps_w_ph(t0, v1, v0, cpu_env); +break; +case NM_DPSQ_S_W_PH: +check_dsp(ctx); +gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env); +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} +break; +case NM_POOL32AXF_2_8_15: +switch (extract32(ctx->opcode, 9, 3)) { +case NM_DPAX_W_PH: +check_dspr2(ctx); +gen_helper_dpax_w_ph(t0, v0, v1, cpu_env); +break; +case NM_DPAQ_SA_L_W: +check_dsp(ctx); +gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env); +break; +case NM_DPSX_W_PH: +check_dspr2(ctx); +gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env); +break; +case NM_DPSQ_SA_L_W: +check_dsp(ctx); +gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env); +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} +break; +case NM_POOL32AXF_2_16_23: +switch (extract32(ctx->opcode, 9, 3)) { +case NM_DPAU_H_QBL: +check_dsp(ctx); +gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env); +break; +case NM_DPAQX_S_W_PH: +check_dspr2(ctx); +gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env); +break; +case NM_DPSU_H_QBL: +check_dsp(ctx); +gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env); +break; +case NM_DPSQX_S_W_PH: +check_dspr2(ctx); +gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env); +break; +case NM_MULSA_W_PH: +check_dspr2(ctx); +gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env); +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} +break; +case NM_POOL32AXF_2_24_31: +switch (extract32(ctx->opcode, 9, 3)) { +case NM_DPAU_H_QBR: +check_dsp(ctx); +gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env); +break; +case NM_DPAQX_SA_W_PH: +check_dspr2(ctx); +gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env); +break; +case NM_DPSU_H_QBR: +check_dsp(ctx); +gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env); +break; +case NM_DPSQX_SA_W_PH: +check_dspr2(ctx); +gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env); +break; +case NM_MULSAQ_S_W_PH: +check_dsp(ctx); +gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env); +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} + +tcg_temp_free_i32(t0); +} + +static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc, + int rt, int rs, int rd) +{ +int ret = rt; +TCGv t0 = tcg_temp_new(); +TCGv t1 = tcg_temp_new(); +TCGv v0_t = tcg_temp_new(); +TCGv v1_t = tcg_temp_new(); + +gen_load_gpr(v0_t, rt); +gen_load_gpr(v1_t, rs); + +switch (opc) { +case NM_POOL32AXF_2_0_7: +switch (extract32(ctx->opcode, 9, 3)) { +case NM_DPA_W_PH: +case NM_DPAQ_S_W_PH: +case NM_DPS_W_PH: +case NM_DPSQ_S_W_PH: +gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); +break; +case NM_BALIGN: +check_dspr2(ctx); +if (rt != 0) { +gen_load_gpr(t0, rs); +rd &= 3; +
[Qemu-devel] [PATCH v8 21/87] target/mips: Add nanoMIPS base instruction set opcodes
From: Yongbok Kim Add nanoMIPS opcodes. nanoMIPS instruction are organized by so-called instruction pools. Each pool contains a set of opcodes, that in turn can be instruction opcodes or instruction pool opcodes. Reviewed-by: Richard Henderson Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 670 1 file changed, 670 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index e2ffdb0..5984ebd 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -15754,6 +15754,676 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx) return 2; } +/* + * + * nanoMIPS opcodes + * + */ + +/* MAJOR, P16, and P32 pools opcodes */ +enum { +NM_P_ADDIU = 0x00, +NM_ADDIUPC = 0x01, +NM_MOVE_BALC= 0x02, +NM_P16_MV = 0x04, +NM_LW16 = 0x05, +NM_BC16 = 0x06, +NM_P16_SR = 0x07, + +NM_POOL32A = 0x08, +NM_P_BAL= 0x0a, +NM_P16_SHIFT= 0x0c, +NM_LWSP16 = 0x0d, +NM_BALC16 = 0x0e, +NM_P16_4X4 = 0x0f, + +NM_P_GP_W = 0x10, +NM_P_GP_BH = 0x11, +NM_P_J = 0x12, +NM_P16C = 0x14, +NM_LWGP16 = 0x15, +NM_P16_LB = 0x17, + +NM_P48I = 0x18, +NM_P16_A1 = 0x1c, +NM_LW4X4= 0x1d, +NM_P16_LH = 0x1f, + +NM_P_U12= 0x20, +NM_P_LS_U12 = 0x21, +NM_P_BR1= 0x22, +NM_P16_A2 = 0x24, +NM_SW16 = 0x25, +NM_BEQZC16 = 0x26, + +NM_POOL32F = 0x28, +NM_P_LS_S9 = 0x29, +NM_P_BR2= 0x2a, + +NM_P16_ADDU = 0x2c, +NM_SWSP16 = 0x2d, +NM_BNEZC16 = 0x2e, +NM_MOVEP= 0x2f, + +NM_POOL32S = 0x30, +NM_P_BRI= 0x32, +NM_LI16 = 0x34, +NM_SWGP16 = 0x35, +NM_P16_BR = 0x36, + +NM_P_LUI= 0x38, +NM_ANDI16 = 0x3c, +NM_SW4X4= 0x3d, +NM_MOVEPREV = 0x3f, +}; + +/* POOL32A instruction pool */ +enum { +NM_POOL32A0= 0x00, +NM_SPECIAL2= 0x01, +NM_COP2_1 = 0x02, +NM_UDI = 0x03, +NM_POOL32A5= 0x05, +NM_POOL32A7= 0x07, +}; + +/* P.GP.W instruction pool */ +enum { +NM_ADDIUGP_W = 0x00, +NM_LWGP = 0x02, +NM_SWGP = 0x03, +}; + +/* P48I instruction pool */ +enum { +NM_LI48= 0x00, +NM_ADDIU48 = 0x01, +NM_ADDIUGP48 = 0x02, +NM_ADDIUPC48 = 0x03, +NM_LWPC48 = 0x0b, +NM_SWPC48 = 0x0f, +}; + +/* P.U12 instruction pool */ +enum { +NM_ORI = 0x00, +NM_XORI = 0x01, +NM_ANDI = 0x02, +NM_P_SR = 0x03, +NM_SLTI = 0x04, +NM_SLTIU= 0x05, +NM_SEQI = 0x06, +NM_ADDIUNEG = 0x08, +NM_P_SHIFT = 0x0c, +NM_P_ROTX = 0x0d, +NM_P_INS= 0x0e, +NM_P_EXT= 0x0f, +}; + +/* POOL32F instruction pool */ +enum { +NM_POOL32F_0 = 0x00, +NM_POOL32F_3 = 0x03, +NM_POOL32F_5 = 0x05, +}; + +/* POOL32S instruction pool */ +enum { +NM_POOL32S_0 = 0x00, +NM_POOL32S_4 = 0x04, +}; + +/* P.LUI instruction pool */ +enum { +NM_LUI = 0x00, +NM_ALUIPC = 0x01, +}; + +/* P.GP.BH instruction pool */ +enum { +NM_LBGP = 0x00, +NM_SBGP = 0x01, +NM_LBUGP = 0x02, +NM_ADDIUGP_B = 0x03, +NM_P_GP_LH = 0x04, +NM_P_GP_SH = 0x05, +NM_P_GP_CP1 = 0x06, +}; + +/* P.LS.U12 instruction pool */ +enum { +NM_LB= 0x00, +NM_SB= 0x01, +NM_LBU = 0x02, +NM_P_PREFU12 = 0x03, +NM_LH= 0x04, +NM_SH= 0x05, +NM_LHU = 0x06, +NM_LWU = 0x07, +NM_LW= 0x08, +NM_SW= 0x09, +NM_LWC1 = 0x0a, +NM_SWC1 = 0x0b, +NM_LDC1 = 0x0e, +NM_SDC1 = 0x0f, +}; + +/* P.LS.S9 instruction pool */ +enum { +NM_P_LS_S0 = 0x00, +NM_P_LS_S1 = 0x01, +NM_P_LS_E0 = 0x02, +NM_P_LS_WM = 0x04, +NM_P_LS_UAWM = 0x05, +}; + +/* P.BAL instruction pool */ +enum { +NM_BC = 0x00, +NM_BALC = 0x01, +}; + +/* P.J instruction pool */ +enum { +NM_JALRC= 0x00, +NM_JALRC_HB = 0x01, +NM_P_BALRSC = 0x08, +}; + +/* P.BR1 instruction pool */ +enum { +NM_BEQC = 0x00, +NM_P_BR3A = 0x01, +NM_BGEC = 0x02, +NM_BGEUC= 0x03, +}; + +/* P.BR2 instruction pool */ +enum { +NM_BNEC = 0x00, +NM_BLTC = 0x02, +NM_BLTUC= 0x03, +}; + +/* P.BRI instruction pool */ +enum { +NM_BEQIC= 0x00, +NM_BBEQZC = 0x01, +NM_BGEIC= 0x02, +NM_BGEIUC = 0x03, +NM_BNEIC= 0x04, +NM_BBNEZC = 0x05, +NM_BLTIC= 0x06, +NM_BLTIUC = 0x07, +}; + +/* P16.SHIFT instruction pool */ +enum { +NM_SLL16= 0x00,
[Qemu-devel] [PATCH v8 59/87] elf: Relax MIPS' elf_check_arch() to accept EM_NANOMIPS too
From: Aleksandar Markovic Starting from nanoMIPS introduction, machine variant can be EM_MIPS or EM_NANOMIPS. Reviewed-by: Richard Henderson Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/elfload.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index df07055..8638612 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -853,6 +853,8 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUPPCState *en #endif #define ELF_ARCHEM_MIPS +#define elf_check_arch(x) ((x) == EM_MIPS || (x) == EM_NANOMIPS) + static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) { -- 2.7.4
[Qemu-devel] [PATCH v8 64/87] mips_malta: Fix semihosting argument passing for nanoMIPS bare metal
From: Stefan Markovic Fix passing argument for nanoMIPS bare metal related to the semihosting regime. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Aleksandar Markovic Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- hw/mips/mips_malta.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index f261dd6..40041d5 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -630,8 +630,14 @@ static void write_bootloader_nanomips(uint8_t *base, int64_t run_addr, /* nop */ /* to_here: */ -stw_p(p++, 0x0080); stw_p(p++, 0x0002); +if (semihosting_get_argc()) { +/* Preserve a0 content as arguments have been passed*/ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); +/* nop */ +} else { +stw_p(p++, 0x0080); stw_p(p++, 0x0002); /* li a0,2 */ +} stw_p(p++, 0xe3a0 | NM_HI1(ENVP_ADDR - 64)); -- 2.7.4
[Qemu-devel] [PATCH v8 53/87] target/mips: Add updating BadInstr, BadInstrP, BadInstrX for nanoMIPS
From: Stefan Markovic Update BadInstr, BadInstrP,and BadInstrX registers for nanoMIPS. The same support for pre-nanoMIPS remains unimplemented. Reviewed-by: Aleksandar Markovic Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/helper.c | 25 + 1 file changed, 25 insertions(+) diff --git a/target/mips/helper.c b/target/mips/helper.c index e215af9..b25e000 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -682,6 +682,31 @@ static void set_hflags_for_handler (CPUMIPSState *env) static inline void set_badinstr_registers(CPUMIPSState *env) { +if (env->insn_flags & ISA_NANOMIPS32) { +if (env->CP0_Config3 & (1 << CP0C3_BI)) { +uint32_t instr = (cpu_lduw_code(env, env->active_tc.PC)) << 16; +if ((instr & 0x1000) == 0) { +instr |= cpu_lduw_code(env, env->active_tc.PC + 2); +} +env->CP0_BadInstr = instr; + +if ((instr & 0xFC00) == 0x6000) { +instr = cpu_lduw_code(env, env->active_tc.PC + 4) << 16; +env->CP0_BadInstrX = instr; +} +} +if ((env->CP0_Config3 & (1 << CP0C3_BP)) && +(env->hflags & MIPS_HFLAG_BMASK)) { +if (!(env->hflags & MIPS_HFLAG_B16)) { +env->CP0_BadInstrP = cpu_ldl_code(env, env->active_tc.PC - 4); +} else { +env->CP0_BadInstrP = +(cpu_lduw_code(env, env->active_tc.PC - 2)) << 16; +} +} +return; +} + if (env->hflags & MIPS_HFLAG_M16) { /* TODO: add BadInstr support for microMIPS */ return; -- 2.7.4
[Qemu-devel] [PATCH v8 46/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 2
From: Stefan Markovic Add emulation of DSP ASE instructions for nanoMIPS - part 2. Reviewed-by: Aleksandar Markovic Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index de10a07..0e2af0d 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -19017,6 +19017,16 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) case NM_BC1NEZC: gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rt, s, 0); break; +case NM_BPOSGE32C: +check_dspr2(ctx); +{ +int32_t imm = extract32(ctx->opcode, 1, 13) | + extract32(ctx->opcode, 0, 1) << 13; + +gen_compute_branch(ctx, OPC_BPOSGE32, 4, -1, -2, + imm, 4); +} +break; default: generate_exception_end(ctx, EXCP_RI); break; -- 2.7.4
[Qemu-devel] [PATCH v8 58/87] elf: Add EM_NANOMIPS value as a valid one for e_machine field
From: Aleksandar Rikalo Value 249 is registered as valid for usage for nanoMIPS executables. Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- include/elf.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/elf.h b/include/elf.h index 28a5a63..312f68a 100644 --- a/include/elf.h +++ b/include/elf.h @@ -143,6 +143,8 @@ typedef int64_t Elf64_Sxword; #define EM_RISCV243 /* RISC-V */ +#define EM_NANOMIPS 249 /* Wave Computing nanoMIPS */ + /* * This is an interim value that we will use until the committee comes * up with a final number. -- 2.7.4
[Qemu-devel] [PATCH v8 43/87] target/mips: Add emulation of nanoMIPS 32-bit branch instructions
From: Yongbok Kim Add emulation of various flavors of nanoMIPS 32-bit branch instructions. Reviewed-by: Aleksandar Markovic Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 262 1 file changed, 262 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index 70785f2..632fac5 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -17110,6 +17110,155 @@ static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) } } +/* Immediate Value Compact Branches */ +static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc, + int rt, int32_t imm, int32_t offset) +{ +TCGCond cond; +int bcond_compute = 0; +TCGv t0 = tcg_temp_new(); +TCGv t1 = tcg_temp_new(); + +if (ctx->hflags & MIPS_HFLAG_BMASK) { +#ifdef MIPS_DEBUG_DISAS +LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx + "\n", ctx->base.pc_next); +#endif +generate_exception_end(ctx, EXCP_RI); +goto out; +} + +gen_load_gpr(t0, rt); +tcg_gen_movi_tl(t1, imm); +ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); + +/* Load needed operands and calculate btarget */ +switch (opc) { +case NM_BEQIC: +if (rt == 0 && imm == 0) { +/* Unconditional branch */ +} else if (rt == 0 && imm != 0) { +/* Treat as NOP */ +goto out; +} else { +bcond_compute = 1; +cond = TCG_COND_EQ; +} +break; +case NM_BBEQZC: +case NM_BBNEZC: +if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) { +generate_exception_end(ctx, EXCP_RI); +goto out; +} else if (rt == 0 && opc == NM_BBEQZC) { +/* Unconditional branch */ +} else if (rt == 0 && opc == NM_BBNEZC) { +/* Treat as NOP */ +goto out; +} else { +tcg_gen_shri_tl(t0, t0, imm); +tcg_gen_andi_tl(t0, t0, 1); +tcg_gen_movi_tl(t1, 0); +bcond_compute = 1; +if (opc == NM_BBEQZC) { +cond = TCG_COND_EQ; +} else { +cond = TCG_COND_NE; +} +} +break; +case NM_BNEIC: +if (rt == 0 && imm == 0) { +/* Treat as NOP */ +goto out; +} else if (rt == 0 && imm != 0) { +/* Unconditional branch */ +} else { +bcond_compute = 1; +cond = TCG_COND_NE; +} +break; +case NM_BGEIC: +if (rt == 0 && imm == 0) { +/* Unconditional branch */ +} else { +bcond_compute = 1; +cond = TCG_COND_GE; +} +break; +case NM_BLTIC: +bcond_compute = 1; +cond = TCG_COND_LT; +break; +case NM_BGEIUC: +if (rt == 0 && imm == 0) { +/* Unconditional branch */ +} else { +bcond_compute = 1; +cond = TCG_COND_GEU; +} +break; +case NM_BLTIUC: +bcond_compute = 1; +cond = TCG_COND_LTU; +break; +default: +MIPS_INVAL("Immediate Value Compact branch"); +generate_exception_end(ctx, EXCP_RI); +goto out; +} + +if (bcond_compute == 0) { +/* Uncoditional compact branch */ +ctx->hflags |= MIPS_HFLAG_B; +/* Generating branch here as compact branches don't have delay slot */ +gen_branch(ctx, 4); +} else { +/* Conditional compact branch */ +TCGLabel *fs = gen_new_label(); +save_cpu_state(ctx, 0); + +tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs); + +/* Generating branch here as compact branches don't have delay slot */ +gen_goto_tb(ctx, 1, ctx->btarget); +gen_set_label(fs); + +ctx->hflags |= MIPS_HFLAG_FBNSLOT; +} + +out: +tcg_temp_free(t0); +tcg_temp_free(t1); +} + +/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */ +static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs, +int rt) +{ +TCGv t0 = tcg_temp_new(); +TCGv t1 = tcg_temp_new(); + +/* load rs */ +gen_load_gpr(t0, rs); + +/* link */ +if (rt != 0) { +tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4); +} + +/* calculate btarget */ +tcg_gen_shli_tl(t0, t0, 1); +tcg_gen_movi_tl(t1, ctx->base.pc_next + 4); +gen_op_addr_add(ctx, btarget, t1, t0); + +ctx->hflags |= MIPS_HFLAG_BR; +/* Generating branch here as compact branches don't have delay slot */ +gen_branch(ctx, 4); + +tcg_temp_free(t0); +tcg_temp_free(t1); +} static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt) { @@ -18171,16 +18320,129
[Qemu-devel] [PATCH v8 54/87] target/mips: Adjust exception_resume_pc() for nanoMIPS
From: James Hogan We shouldn't set the ISA bit in CP0_EPC for nanoMIPS. Signed-off-by: James Hogan Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/helper.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target/mips/helper.c b/target/mips/helper.c index b25e000..b429671 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -656,7 +656,8 @@ target_ulong exception_resume_pc (CPUMIPSState *env) target_ulong bad_pc; target_ulong isa_mode; -isa_mode = !!(env->hflags & MIPS_HFLAG_M16); +isa_mode = env->hflags & MIPS_HFLAG_M16 && +!(env->insn_flags & ISA_NANOMIPS32); bad_pc = env->active_tc.PC | isa_mode; if (env->hflags & MIPS_HFLAG_BMASK) { /* If the exception was raised from a delay slot, come back to -- 2.7.4
[Qemu-devel] [PATCH v8 35/87] target/mips: Add emulation of nanoMIPS FP instructions
From: Yongbok Kim Add emulation of basic floating point arithmetic for nanoMIPS. Reviewed-by: Richard Henderson Reviewed-by: Aleksandar Markovic Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 300 1 file changed, 300 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index 40da813..87bb2c2 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -16768,6 +16768,305 @@ static void gen_pool16c_nanomips_insn(DisasContext *ctx) } } +static void gen_pool32f_nanomips_insn(DisasContext *ctx) +{ +int rt, rs, rd; + +rt = extract32(ctx->opcode, 21, 5); +rs = extract32(ctx->opcode, 16, 5); +rd = extract32(ctx->opcode, 11, 5); + +if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) { +generate_exception_end(ctx, EXCP_RI); +return; +} +check_cp1_enabled(ctx); +switch (extract32(ctx->opcode, 0, 3)) { +case NM_POOL32F_0: +switch (extract32(ctx->opcode, 3, 7)) { +case NM_RINT_S: +gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0); +break; +case NM_RINT_D: +gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0); +break; +case NM_CLASS_S: +gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0); +break; +case NM_CLASS_D: +gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0); +break; +case NM_ADD_S: +gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0); +break; +case NM_ADD_D: +gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0); +break; +case NM_SUB_S: +gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0); +break; +case NM_SUB_D: +gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0); +break; +case NM_MUL_S: +gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0); +break; +case NM_MUL_D: +gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0); +break; +case NM_DIV_S: +gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0); +break; +case NM_DIV_D: +gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0); +break; +case NM_SELEQZ_S: +gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs); +break; +case NM_SELEQZ_D: +gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs); +break; +case NM_SELNEZ_S: +gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs); +break; +case NM_SELNEZ_D: +gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs); +break; +case NM_SEL_S: +gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs); +break; +case NM_SEL_D: +gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs); +break; +case NM_MADDF_S: +gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0); +break; +case NM_MADDF_D: +gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0); +break; +case NM_MSUBF_S: +gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0); +break; +case NM_MSUBF_D: +gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0); +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} +break; +case NM_POOL32F_3: +switch (extract32(ctx->opcode, 3, 3)) { +case NM_MIN_FMT: +switch (extract32(ctx->opcode, 9, 1)) { +case FMT_SDPS_S: +gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0); +break; +case FMT_SDPS_D: +gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0); +break; +} +break; +case NM_MAX_FMT: +switch (extract32(ctx->opcode, 9, 1)) { +case FMT_SDPS_S: +gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0); +break; +case FMT_SDPS_D: +gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0); +break; +} +break; +case NM_MINA_FMT: +switch (extract32(ctx->opcode, 9, 1)) { +case FMT_SDPS_S: +gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0); +break; +case FMT_SDPS_D: +gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0); +break; +} +break; +case NM_MAXA_FMT: +switch (extract32(ctx->opcode, 9, 1)) { +case FMT_SDPS_S: +gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0); +break; +case FMT_SDPS_D: +gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0); +break; +} +break; +case NM_POOL32FXF: +switch (extract32(ctx->opcode, 6, 8)) { +case NM_CFC1: +
[Qemu-devel] [PATCH v8 33/87] target/mips: Add emulation of nanoMIPS instructions MOVE.P and MOVE.PREV
From: Yongbok Kim Add emulation of nanoMIPS instructions MOVE.P and MOVE.PREV. Reviewed-by: Richard Henderson Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 33 - 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 6cd8cec..4e8994c 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -17349,8 +17349,39 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx) } break; case NM_MOVEP: -break; case NM_MOVEPREV: +{ +static const int gpr2reg1[] = {4, 5, 6, 7}; +static const int gpr2reg2[] = {5, 6, 7, 8}; +int re; +int rd2 = extract32(ctx->opcode, 3, 1) << 1 | + extract32(ctx->opcode, 8, 1); +int r1 = gpr2reg1[rd2]; +int r2 = gpr2reg2[rd2]; +int r3 = extract32(ctx->opcode, 4, 1) << 3 | + extract32(ctx->opcode, 0, 3); +int r4 = extract32(ctx->opcode, 9, 1) << 3 | + extract32(ctx->opcode, 5, 3); +TCGv t0 = tcg_temp_new(); +TCGv t1 = tcg_temp_new(); +if (op == NM_MOVEP) { +rd = r1; +re = r2; +rs = decode_gpr_gpr4_zero(r3); +rt = decode_gpr_gpr4_zero(r4); +} else { +rd = decode_gpr_gpr4(r3); +re = decode_gpr_gpr4(r4); +rs = r1; +rt = r2; +} +gen_load_gpr(t0, rs); +gen_load_gpr(t1, rt); +tcg_gen_mov_tl(cpu_gpr[rd], t0); +tcg_gen_mov_tl(cpu_gpr[re], t1); +tcg_temp_free(t0); +tcg_temp_free(t1); +} break; default: return decode_nanomips_32_48_opc(env, ctx); -- 2.7.4
[Qemu-devel] [PATCH v8 38/87] target/mips: Add emulation of misc nanoMIPS instructions (p_lsx)
From: Yongbok Kim Add emulation of nanoMIPS instructions situated in pool p_lsx, and emulation of LSA instruction as well. Reviewed-by: Aleksandar Markovic Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 132 +++- 1 file changed, 131 insertions(+), 1 deletion(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 63928eb..a97a989 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -17024,6 +17024,125 @@ static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) } } + +static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt) +{ +TCGv t0, t1; +t0 = tcg_temp_new(); +t1 = tcg_temp_new(); + +gen_load_gpr(t0, rs); +gen_load_gpr(t1, rt); + +if ((extract32(ctx->opcode, 6, 1)) == 1) { +/* PP.LSXS instructions require shifting */ +switch (extract32(ctx->opcode, 7, 4)) { +case NM_LHXS: +case NM_SHXS: +case NM_LHUXS: +tcg_gen_shli_tl(t0, t0, 1); +break; +case NM_LWXS: +case NM_SWXS: +case NM_LWC1XS: +case NM_SWC1XS: +tcg_gen_shli_tl(t0, t0, 2); +break; +case NM_LDC1XS: +case NM_SDC1XS: +tcg_gen_shli_tl(t0, t0, 3); +break; +} +} +gen_op_addr_add(ctx, t0, t0, t1); + +switch (extract32(ctx->opcode, 7, 4)) { +case NM_LBX: +tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, + MO_SB); +gen_store_gpr(t0, rd); +break; +case NM_LHX: +/*case NM_LHXS:*/ +tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, + MO_TESW); +gen_store_gpr(t0, rd); +break; +case NM_LWX: +/*case NM_LWXS:*/ +tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, + MO_TESL); +gen_store_gpr(t0, rd); +break; +case NM_LBUX: +tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, + MO_UB); +gen_store_gpr(t0, rd); +break; +case NM_LHUX: +/*case NM_LHUXS:*/ +tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, + MO_TEUW); +gen_store_gpr(t0, rd); +break; +case NM_SBX: +gen_load_gpr(t1, rd); +tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, + MO_8); +break; +case NM_SHX: +/*case NM_SHXS:*/ +gen_load_gpr(t1, rd); +tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, + MO_TEUW); +break; +case NM_SWX: +/*case NM_SWXS:*/ +gen_load_gpr(t1, rd); +tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, + MO_TEUL); +break; +case NM_LWC1X: +/*case NM_LWC1XS:*/ +case NM_LDC1X: +/*case NM_LDC1XS:*/ +case NM_SWC1X: +/*case NM_SWC1XS:*/ +case NM_SDC1X: +/*case NM_SDC1XS:*/ +if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { +check_cp1_enabled(ctx); +switch (extract32(ctx->opcode, 7, 4)) { +case NM_LWC1X: +/*case NM_LWC1XS:*/ +gen_flt_ldst(ctx, OPC_LWC1, rd, t0); +break; +case NM_LDC1X: +/*case NM_LDC1XS:*/ +gen_flt_ldst(ctx, OPC_LDC1, rd, t0); +break; +case NM_SWC1X: +/*case NM_SWC1XS:*/ +gen_flt_ldst(ctx, OPC_SWC1, rd, t0); +break; +case NM_SDC1X: +/*case NM_SDC1XS:*/ +gen_flt_ldst(ctx, OPC_SDC1, rd, t0); +break; +} +} else { +generate_exception_err(ctx, EXCP_CpU, 1); +} +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} + +tcg_temp_free(t0); +tcg_temp_free(t1); +} + static void gen_pool32f_nanomips_insn(DisasContext *ctx) { int rt, rs, rd; @@ -17327,7 +17446,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) { uint16_t insn; uint32_t op; -int rt, rs; +int rt, rs, rd; int offset; int imm; @@ -17336,6 +17455,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) rt = extract32(ctx->opcode, 21, 5); rs = extract32(ctx->opcode, 16, 5); +rd = extract32(ctx->opcode, 11, 5); op = extract32(ctx->opcode, 26, 6); switch (op) { @@ -17394,6 +17514,16 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) break; case NM_POOL32A7: switch (extract32(ctx->opcode, 3, 3)) { +case NM_P_LSX: +gen_p_lsx(ctx, rd, rs, rt); +break; +case NM_LSA: +/* In nanoMIPS, the shift field directly encodes the shift + * amount, meaning that the supported shift
[Qemu-devel] [PATCH v8 55/87] target/mips: Adjust set_hflags_for_handler() for nanoMIPS
From: James Hogan We shouldn't clear M16 mode when entering an interrupt on nanoMIPS, otherwise we'll start interpreting the code as normal MIPS code. Signed-off-by: James Hogan Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/helper.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/target/mips/helper.c b/target/mips/helper.c index b429671..0c15e65 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -671,6 +671,9 @@ target_ulong exception_resume_pc (CPUMIPSState *env) #if !defined(CONFIG_USER_ONLY) static void set_hflags_for_handler (CPUMIPSState *env) { +if (env->insn_flags & ISA_NANOMIPS32) { +return; +} /* Exception handlers are entered in 32-bit mode. */ env->hflags &= ~(MIPS_HFLAG_M16); /* ...except that microMIPS lets you choose. */ -- 2.7.4
[Qemu-devel] [PATCH v8 17/87] linux-user: Update MIPS syscall numbers up to kernel 4.18 headers
From: Aleksandar Markovic Synchronize content of linux-user/mips/syscall_nr.h and linux-user/mips64/syscall_nr.h with Linux kernel 4.18 headers. This adds 9 new syscall numbers, the last being NR_io_pgetevents. Reviewed-by: Laurent Vivier Reviewed-by: Richard Henderson Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/mips/syscall_nr.h | 9 + linux-user/mips64/syscall_nr.h | 18 ++ 2 files changed, 27 insertions(+) diff --git a/linux-user/mips/syscall_nr.h b/linux-user/mips/syscall_nr.h index ced3280..e70adfc 100644 --- a/linux-user/mips/syscall_nr.h +++ b/linux-user/mips/syscall_nr.h @@ -363,3 +363,12 @@ #define TARGET_NR_userfaultfd (TARGET_NR_Linux + 357) #define TARGET_NR_membarrier(TARGET_NR_Linux + 358) #define TARGET_NR_mlock2(TARGET_NR_Linux + 359) +#define TARGET_NR_copy_file_range (TARGET_NR_Linux + 360) +#define TARGET_NR_preadv2 (TARGET_NR_Linux + 361) +#define TARGET_NR_pwritev2 (TARGET_NR_Linux + 362) +#define TARGET_NR_pkey_mprotect (TARGET_NR_Linux + 363) +#define TARGET_NR_pkey_alloc(TARGET_NR_Linux + 364) +#define TARGET_NR_pkey_free (TARGET_NR_Linux + 365) +#define TARGET_NR_statx (TARGET_NR_Linux + 366) +#define TARGET_NR_rseq (TARGET_NR_Linux + 367) +#define TARGET_NR_io_pgetevents (TARGET_NR_Linux + 368) diff --git a/linux-user/mips64/syscall_nr.h b/linux-user/mips64/syscall_nr.h index 746cc26..ff218a9 100644 --- a/linux-user/mips64/syscall_nr.h +++ b/linux-user/mips64/syscall_nr.h @@ -327,6 +327,15 @@ #define TARGET_NR_userfaultfd (TARGET_NR_Linux + 321) #define TARGET_NR_membarrier(TARGET_NR_Linux + 322) #define TARGET_NR_mlock2(TARGET_NR_Linux + 323) +#define TARGET_NR_copy_file_range (TARGET_NR_Linux + 324) +#define TARGET_NR_preadv2 (TARGET_NR_Linux + 325) +#define TARGET_NR_pwritev2 (TARGET_NR_Linux + 326) +#define TARGET_NR_pkey_mprotect (TARGET_NR_Linux + 327) +#define TARGET_NR_pkey_alloc(TARGET_NR_Linux + 328) +#define TARGET_NR_pkey_free (TARGET_NR_Linux + 329) +#define TARGET_NR_statx (TARGET_NR_Linux + 330) +#define TARGET_NR_rseq (TARGET_NR_Linux + 331) +#define TARGET_NR_io_pgetevents (TARGET_NR_Linux + 332) #else /* @@ -653,4 +662,13 @@ #define TARGET_NR_userfaultfd (TARGET_NR_Linux + 317) #define TARGET_NR_membarrier(TARGET_NR_Linux + 318) #define TARGET_NR_mlock2(TARGET_NR_Linux + 319) +#define TARGET_NR_copy_file_range (TARGET_NR_Linux + 320) +#define TARGET_NR_preadv2 (TARGET_NR_Linux + 321) +#define TARGET_NR_pwritev2 (TARGET_NR_Linux + 322) +#define TARGET_NR_pkey_mprotect (TARGET_NR_Linux + 323) +#define TARGET_NR_pkey_alloc(TARGET_NR_Linux + 324) +#define TARGET_NR_pkey_free (TARGET_NR_Linux + 325) +#define TARGET_NR_statx (TARGET_NR_Linux + 326) +#define TARGET_NR_rseq (TARGET_NR_Linux + 327) +#define TARGET_NR_io_pgetevents (TARGET_NR_Linux + 328) #endif -- 2.7.4
[Qemu-devel] [PATCH v8 26/87] target/mips: Add emulation of nanoMIPS 16-bit branch instructions
From: Yongbok Kim Add emulation of nanoMIPS 16-bit branch instructions. Reviewed-by: Richard Henderson Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 36 1 file changed, 36 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index 85ecf23..0b9936f 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -16799,14 +16799,50 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx) case NM_SWGP16: break; case NM_BC16: +gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, + (sextract32(ctx->opcode, 0, 1) << 10) | + (extract32(ctx->opcode, 1, 9) << 1), 0); break; case NM_BALC16: +gen_compute_branch(ctx, OPC_BGEZAL, 2, 0, 0, + (sextract32(ctx->opcode, 0, 1) << 10) | + (extract32(ctx->opcode, 1, 9) << 1), 0); break; case NM_BEQZC16: +gen_compute_branch(ctx, OPC_BEQ, 2, rt, 0, + (sextract32(ctx->opcode, 0, 1) << 7) | + (extract32(ctx->opcode, 1, 6) << 1), 0); break; case NM_BNEZC16: +gen_compute_branch(ctx, OPC_BNE, 2, rt, 0, + (sextract32(ctx->opcode, 0, 1) << 7) | + (extract32(ctx->opcode, 1, 6) << 1), 0); break; case NM_P16_BR: +switch (ctx->opcode & 0xf) { +case 0: +/* P16.JRC */ +switch (extract32(ctx->opcode, 4, 1)) { +case NM_JRC: +gen_compute_branch(ctx, OPC_JR, 2, + extract32(ctx->opcode, 5, 5), 0, 0, 0); +break; +case NM_JALRC16: +gen_compute_branch(ctx, OPC_JALR, 2, + extract32(ctx->opcode, 5, 5), 31, 0, 0); +break; +} +break; +default: +{ +/* P16.BRI */ +uint32_t opc = extract32(ctx->opcode, 4, 3) < + extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE; +gen_compute_branch(ctx, opc, 2, rs, rt, + extract32(ctx->opcode, 0, 4) << 1, 0); +} +break; +} break; case NM_P16_SR: break; -- 2.7.4
[Qemu-devel] [PATCH v8 32/87] target/mips: Add emulation of some common nanoMIPS 32-bit instructions
From: Yongbok Kim Add emulation of SIGRIE, SYSCALL, BREAK, SDBBP, ADDIU, ADDIUPC, ADDIUGP.W, LWGP, SWGP, ORI, XORI, ANDI, and other instructions. Reviewed-by: Aleksandar Markovic Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 270 +++- 1 file changed, 269 insertions(+), 1 deletion(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 868535c..6cd8cec 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -16768,6 +16768,274 @@ static void gen_pool16c_nanomips_insn(DisasContext *ctx) } } +static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) +{ +uint16_t insn; +uint32_t op; +int rt, rs; +int offset; +int imm; + +insn = cpu_lduw_code(env, ctx->base.pc_next + 2); +ctx->opcode = (ctx->opcode << 16) | insn; + +rt = extract32(ctx->opcode, 21, 5); +rs = extract32(ctx->opcode, 16, 5); + +op = extract32(ctx->opcode, 26, 6); +switch (op) { +case NM_P_ADDIU: +if (rt == 0) { +/* P.RI */ +switch (extract32(ctx->opcode, 19, 2)) { +case NM_SIGRIE: +default: +generate_exception_end(ctx, EXCP_RI); +break; +case NM_P_SYSCALL: +if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) { +generate_exception_end(ctx, EXCP_SYSCALL); +} else { +generate_exception_end(ctx, EXCP_RI); +} +break; +case NM_BREAK: +generate_exception_end(ctx, EXCP_BREAK); +break; +case NM_SDBBP: +if (is_uhi(extract32(ctx->opcode, 0, 19))) { +gen_helper_do_semihosting(cpu_env); +} else { +if (ctx->hflags & MIPS_HFLAG_SBRI) { +generate_exception_end(ctx, EXCP_RI); +} else { +generate_exception_end(ctx, EXCP_DBp); +} +} +break; +} +} else { +imm = extract32(ctx->opcode, 0, 16); +if (rs != 0) { +tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm); +tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); +} else { +tcg_gen_movi_tl(cpu_gpr[rt], imm); +} +} +break; +case NM_ADDIUPC: +if (rt != 0) { +offset = sextract32(ctx->opcode, 0, 1) << 21 | + extract32(ctx->opcode, 1, 20) << 1; +target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset); +tcg_gen_movi_tl(cpu_gpr[rt], addr); +} +break; +case NM_POOL32A: +break; +case NM_P_GP_W: +switch (ctx->opcode & 0x03) { +case NM_ADDIUGP_W: +if (rt != 0) { +offset = extract32(ctx->opcode, 0, 21); +gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset); +} +break; +case NM_LWGP: +gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2); +break; +case NM_SWGP: +gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2); +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} +break; +case NM_P48I: +return 6; +case NM_P_U12: +switch (extract32(ctx->opcode, 12, 4)) { +case NM_ORI: +gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12)); +break; +case NM_XORI: +gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12)); +break; +case NM_ANDI: +gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12)); +break; +case NM_P_SR: +switch (extract32(ctx->opcode, 20, 1)) { +case NM_PP_SR: +switch (ctx->opcode & 3) { +case NM_SAVE: +gen_save(ctx, rt, extract32(ctx->opcode, 16, 4), + extract32(ctx->opcode, 2, 1), + extract32(ctx->opcode, 3, 9) << 3); +break; +case NM_RESTORE: +case NM_RESTORE_JRC: +gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4), +extract32(ctx->opcode, 2, 1), +extract32(ctx->opcode, 3, 9) << 3); +if ((ctx->opcode & 3) == NM_RESTORE_JRC) { +gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0); +} +break; +default: +generate_exception_end(ctx, EXCP_RI); +