From 1986cc7b0fe1e69bcd0f51106f433bfe2d1f7db9 Mon Sep 17 00:00:00 2001 From: Mario Fetka Date: Fri, 23 Dec 2011 16:31:28 +0100 Subject: [PATCH] add qemu user --- app-emulation/qemu-user/ChangeLog | 171 + app-emulation/qemu-user/Manifest | 29 + .../files/0.14.1/0001-qemu-0.7.0-amd64.patch | 34 + .../0.14.1/0002-qemu-0.9.0.cvs-binfmt.patch | 82 + .../0.14.1/0003-qemu-cvs-alsa_bitfield.patch | 83 + .../0.14.1/0004-qemu-cvs-alsa_ioctl.patch | 3626 +++++++++ .../0.14.1/0005-qemu-cvs-alsa_mmap.patch | 47 + .../0.14.1/0006-qemu-cvs-gettimeofday.patch | 26 + .../0.14.1/0007-qemu-cvs-ioctl_debug.patch | 33 + .../0008-qemu-cvs-ioctl_nodirection.patch | 42 + .../0009-qemu-cvs-sched_getaffinity.patch | 56 + .../0.14.1/0010-qemu-cvs-mmap-amd64.patch | 74 + .../0.14.1/0011-qemu-img-vmdk-scsi.patch | 116 + .../0.14.1/0012-qemu-nonvoid_return.patch | 40 + .../0013-i386-linux-user-NPTL-support.patch | 64 + .../files/0.14.1/0015-S-390-support.patch | 6757 +++++++++++++++++ .../0016-fix-mipsn32-linux-user-builds.patch | 58 + .../files/0.14.1/0017-S-390-build-fix.patch | 129 + .../0.14.1/0018-qemu-0.14.1-mcast-udp.patch | 289 + .../0.14.1/0019-linux-user-fix-openat.patch | 52 + ...-linux-user-implement-reboot-syscall.patch | 40 + .../0021-implement-prlimit64-syscall.patch | 117 + .../files/0.14.1/0022-fixing-smp-races.patch | 34 + ...d-binfmt-wrapper-for-argv-0-handling.patch | 167 + ...25-add-syscall-numbers-from-2.6.39.2.patch | 357 + .../qemu-user/files/qemu-chroot.patch | 46 + app-emulation/qemu-user/files/qemu-user.initd | 137 + app-emulation/qemu-user/metadata.xml | 7 + .../qemu-user/qemu-user-0.14.1.ebuild | 71 + app-emulation/qemu/Manifest | 5 +- .../0024-fix-glibc-install-locales.patch | 460 -- ...25-add-syscall-numbers-from-2.6.39.2.patch | 126 +- app-emulation/qemu/qemu-0.14.1.ebuild | 201 + 33 files changed, 13038 insertions(+), 538 deletions(-) create mode 100644 app-emulation/qemu-user/ChangeLog create mode 100644 app-emulation/qemu-user/Manifest create mode 100644 app-emulation/qemu-user/files/0.14.1/0001-qemu-0.7.0-amd64.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0002-qemu-0.9.0.cvs-binfmt.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0003-qemu-cvs-alsa_bitfield.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0004-qemu-cvs-alsa_ioctl.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0005-qemu-cvs-alsa_mmap.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0006-qemu-cvs-gettimeofday.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0007-qemu-cvs-ioctl_debug.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0008-qemu-cvs-ioctl_nodirection.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0009-qemu-cvs-sched_getaffinity.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0010-qemu-cvs-mmap-amd64.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0011-qemu-img-vmdk-scsi.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0012-qemu-nonvoid_return.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0013-i386-linux-user-NPTL-support.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0015-S-390-support.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0016-fix-mipsn32-linux-user-builds.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0017-S-390-build-fix.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0018-qemu-0.14.1-mcast-udp.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0019-linux-user-fix-openat.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0020-linux-user-implement-reboot-syscall.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0021-implement-prlimit64-syscall.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0022-fixing-smp-races.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0023-linux-user-add-binfmt-wrapper-for-argv-0-handling.patch create mode 100644 app-emulation/qemu-user/files/0.14.1/0025-add-syscall-numbers-from-2.6.39.2.patch create mode 100644 app-emulation/qemu-user/files/qemu-chroot.patch create mode 100644 app-emulation/qemu-user/files/qemu-user.initd create mode 100644 app-emulation/qemu-user/metadata.xml create mode 100644 app-emulation/qemu-user/qemu-user-0.14.1.ebuild delete mode 100644 app-emulation/qemu/files/0.14.1/0024-fix-glibc-install-locales.patch create mode 100644 app-emulation/qemu/qemu-0.14.1.ebuild diff --git a/app-emulation/qemu-user/ChangeLog b/app-emulation/qemu-user/ChangeLog new file mode 100644 index 0000000..d63c6f7 --- /dev/null +++ b/app-emulation/qemu-user/ChangeLog @@ -0,0 +1,171 @@ +# ChangeLog for app-emulation/qemu-user +# Copyright 1999-2010 Gentoo Foundation; Distributed under the GPL v2 +# $Header: /var/cvsroot/gentoo-x86/app-emulation/qemu-user/ChangeLog,v 1.40 2010/10/15 14:21:23 flameeyes Exp $ + + 15 Oct 2010; Diego E. Pettenò + -qemu-user-0.10.0.ebuild, -qemu-user-0.10.1.ebuild: + Spring cleaning of ebuilds. + +*qemu-user-0.12.2 (14 Feb 2010) + + 14 Feb 2010; +qemu-user-0.12.2.ebuild: + -- bump qemu-user to current. Add static use flag for cross arch chroot + emulation. + + 14 Nov 2009; Tomáš Chvátal + -qemu-user-0.9.1.ebuild: + Drop old masked version. + +*qemu-user-0.10.1 (22 Mar 2009) + + 22 Mar 2009; Luca Barbato +qemu-user-0.10.1.ebuild: + Bugfix release + + 12 Mar 2009; Diego E. Pettenò + qemu-user-0.10.0.ebuild: + Remove binchecks restriction (package installs binaries!). + + 12 Mar 2009; Luca Barbato qemu-user-0.10.0.ebuild: + Simplify hardened support + + 10 Mar 2009; Luca Barbato qemu-user-0.10.0.ebuild: + Fix leftover from kvm ebuild import + +*qemu-user-0.10.0 (07 Mar 2009) + + 07 Mar 2009; Luca Barbato +qemu-user-0.10.0.ebuild: + New version + + 01 Feb 2008; Luca Barbato + -files/qemu-user-0.7.0-errno.patch, -files/qemu-0.8.0-gcc4-hacks.patch, + -files/qemu-0.8.0-stwbrx.patch, -files/qemu-ppc-dirty-hack.patch, + -qemu-user-0.8.0.ebuild, -qemu-user-0.8.0.20060329.ebuild, + -qemu-user-0.8.1.ebuild, -qemu-user-0.8.2.ebuild: + Remove qemu-0.8 series + +*qemu-user-0.9.1 (27 Jan 2008) + + 27 Jan 2008; Luca Barbato +qemu-user-0.9.1.ebuild: + Version bump + + 02 Jul 2007; Piotr Jaroszyński qemu-user-0.8.0.ebuild, + qemu-user-0.8.0.20060329.ebuild, qemu-user-0.8.1.ebuild, + qemu-user-0.8.2.ebuild, qemu-user-0.9.0.ebuild: + (QA) RESTRICT clean up. + + 20 May 2007; Christian Faulhammer + qemu-user-0.9.0.ebuild: + stable amd64, security bug 176674 + + 16 May 2007; Luca Barbato qemu-user-0.9.0.ebuild: + Marked ppc + + 08 May 2007; Markus Ullmann qemu-user-0.9.0.ebuild: + Stable on x86 wrt security bug #176674 + + 21 Feb 2007; Piotr Jaroszyński ChangeLog: + Transition to Manifest2. + + 10 Feb 2007; Luca Barbato qemu-user-0.9.0.ebuild: + Fix bug #164491 + +*qemu-user-0.9.0 (10 Feb 2007) + + 10 Feb 2007; Luca Barbato +qemu-user-0.9.0.ebuild: + New version + + 06 Feb 2007; Simon Stelling qemu-user-0.8.2.ebuild: + stable on amd64; bug 159522 + + 02 Jan 2007; Christian Faulhammer + qemu-user-0.8.2.ebuild: + stable x86, bug #159522 + + 31 Dec 2006; Luca Barbato qemu-user-0.8.2.ebuild: + Marked ppc + + 22 Nov 2006; Kevin F. Quinn qemu-user-0.8.2.ebuild: + Add QA variable indicating which files contain textrels; these are a feature + of how qemu works. + +*qemu-user-0.8.2 (16 Aug 2006) + + 16 Aug 2006; Luca Barbato + +files/qemu-0.7.0-ppc-linker.patch, +qemu-user-0.8.2.ebuild: + New version, I gave up about the sparc module (broken upstream) + Patch took from the debian patchset as pointed by David Gurvich + in bug #138655 + + 09 Jun 2006; Michael Sterrett + -qemu-user-0.7.0-r1.ebuild, -qemu-user-0.7.1.ebuild, + -qemu-user-0.7.2.ebuild: + clean out old versions + + 07 May 2006; Luca Barbato qemu-user-0.8.1.ebuild: + Fix errno again for x86, thanks to lothalev@gmail.com + +*qemu-user-0.8.1 (06 May 2006) + + 06 May 2006; Luca Barbato + +files/qemu-0.8.0-gcc4-hacks.patch, qemu-user-0.8.0.ebuild, + qemu-user-0.8.0.20060329.ebuild, +qemu-user-0.8.1.ebuild: + New version and added Mandrake patch for gcc4 on x86 + + 27 Apr 2006; Luca Barbato qemu-user-0.8.0.ebuild, + qemu-user-0.8.0.20060329.ebuild: + New target added: mips + + 23 Apr 2006; Luca Barbato + +files/qemu-0.8.0-stwbrx.patch, qemu-user-0.8.0.ebuild, + qemu-user-0.8.0.20060329.ebuild: + PPC fix, thanks to dimitrij wagner for providing it + + 19 Apr 2006; Daniel Gryniewicz qemu-user-0.8.0.ebuild: + Marked stable on amd64 per bug# 123972 + + 16 Apr 2006; Michael Hanselmann + qemu-user-0.8.0.ebuild: + Stable on ppc. + + 01 Apr 2006; Luca Barbato qemu-user-0.8.0.ebuild: + Restricted test feature + +*qemu-user-0.8.0.20060329 (29 Mar 2006) + + 29 Mar 2006; Luca Barbato + +qemu-user-0.8.0.20060329.ebuild: + New version + + 29 Mar 2006; Chris White qemu-user-0.8.0.ebuild: + x88 stable for qemu-user-0.8.0 bug #123972. + + 09 Jan 2006; Luca Barbato qemu-user-0.8.0.ebuild: + Disable gcc checks, thanks to Robert Führicht + +*qemu-user-0.8.0 (23 Dec 2005) + + 23 Dec 2005; Luca Barbato +qemu-user-0.8.0.ebuild: + New version + +*qemu-user-0.7.2 (11 Sep 2005) + + 11 Sep 2005; Luca Barbato +qemu-user-0.7.2.ebuild: + New release + + 06 Aug 2005; Luca Barbato + +files/qemu-ppc-dirty-hack.patch, qemu-user-0.7.1.ebuild: + Workaround to make it build with newer binutils, thanks to Andrew de Quincey + + +*qemu-user-0.7.1 (25 Jul 2005) + + 25 Jul 2005; Luca Barbato +qemu-user-0.7.1.ebuild: + New version + +*qemu-user-0.7.0-r1 (18 Jun 2005) + + 18 Jun 2005; Luca Barbato + +files/qemu-user-0.7.0-errno.patch, +metadata.xml, + +qemu-user-0.7.0-r1.ebuild: + qemu split ebuild, abi wrappers + diff --git a/app-emulation/qemu-user/Manifest b/app-emulation/qemu-user/Manifest new file mode 100644 index 0000000..684d816 --- /dev/null +++ b/app-emulation/qemu-user/Manifest @@ -0,0 +1,29 @@ +AUX 0.14.1/0001-qemu-0.7.0-amd64.patch 1475 RMD160 a1997077c9463e209b6717ec0e305f171282697d SHA1 befe5ae85f37e4ceaa15b8b701e26628685db7cc SHA256 25bda27f693ebb127d442205f46233318c1ea0c25e83494b3be077ceb01be509 +AUX 0.14.1/0002-qemu-0.9.0.cvs-binfmt.patch 8802 RMD160 d46805c0b265554e5073fffa50b807efe810aa6a SHA1 5e46438cd3d98e9c7da7da317b8a59d8092721c3 SHA256 ea60680268c2fa9ff1df3bb2ed823a27967193874750b29d35e417e2a639b2dc +AUX 0.14.1/0003-qemu-cvs-alsa_bitfield.patch 2461 RMD160 fbd6ca8650925404fb7031cc248e687e1f785650 SHA1 6599dda02adf122c0553e167d08d347f9105d8bf SHA256 5742477cb0aaf129fd120dee2adae795fe3ba4e6377b5e384159028faf42f625 +AUX 0.14.1/0004-qemu-cvs-alsa_ioctl.patch 134017 RMD160 bb5370db468a32695ef0f3d95c2324ff9642cee7 SHA1 fed07226b62ab12ee896f0e1d8f5dfa87804f721 SHA256 e710e46e56e340978d1ff9bff2c41dc8a6cdb6b1a27ad24aecf955cdc636b1f7 +AUX 0.14.1/0005-qemu-cvs-alsa_mmap.patch 1542 RMD160 c0b59c8585be031a4311944abf39458094783734 SHA1 7d3eac48e1ee92b5f01ec15fe89ec96357e2f5af SHA256 063c61a3cbd3d1fab92b340973754c7a3ee16653bfe7c603b5ff3f8b5f81a692 +AUX 0.14.1/0006-qemu-cvs-gettimeofday.patch 823 RMD160 16b15186f494c5b494f573d4304be6b3afe05213 SHA1 ce9932091b1192abbe6bbf5f4fb820c0d84a53f4 SHA256 0cbf3f7ef72e70633f1e10b453a8a5beafba5864a3c04ab89c211be5333685c8 +AUX 0.14.1/0007-qemu-cvs-ioctl_debug.patch 1432 RMD160 60e8a34301c7901ec6cc0c658243ad3f0e7d54e0 SHA1 46639e9baec2f6478941787aeab969123541d050 SHA256 fb6eeef6d5011fddb781da97dd05437ea46ac71a98c1d98a2a7567c79e8bcbe8 +AUX 0.14.1/0008-qemu-cvs-ioctl_nodirection.patch 1601 RMD160 d526d6ef7388870f3397c99878cc16367ead6c4d SHA1 6c233ea2d992fd11d4e3e6cf647a533d20e18a2e SHA256 05f7a3c3f041adbf1161291ba5df330863910b0fc2eb998d66a9ae461c023f44 +AUX 0.14.1/0009-qemu-cvs-sched_getaffinity.patch 1930 RMD160 f35786262802559ee3b74c7973ace7729ab86a9a SHA1 65e42415dc3fd078469ccf7e8cd03f484a3c6270 SHA256 0c7e4ed35b0b448cab3021a9903d5fbb7fa78e4aafd7df034baeeaf151827cc4 +AUX 0.14.1/0010-qemu-cvs-mmap-amd64.patch 3054 RMD160 63da0f1fc63c8a20c30a653a98c36157cff64c39 SHA1 796316da61db32ba75a26581256d9b4d5bfe1993 SHA256 e40ecfef55a57446936c76aa3a9c677c5e0e76bebf07faeaf50b2bab7450f424 +AUX 0.14.1/0011-qemu-img-vmdk-scsi.patch 4202 RMD160 0c9b9e6a166655414f9d43ae5483fc71166057c2 SHA1 8bb2bc3da9db327ba56e48542bf07feffca19384 SHA256 bef274ebc2ee4221ba3e7ee4ba226e7e6205050d9a5fb2e4dbb84b71671a2494 +AUX 0.14.1/0012-qemu-nonvoid_return.patch 1123 RMD160 5d77c2943d6e8e6e34b65e22566310a7d1cfa80e SHA1 319268438cd6ab68d35ff5bd4ef9ec279f488910 SHA256 0e4ac0b693052be9a358e66d36a9eb18f447c7309cfe57e602d13ae643f1ea3a +AUX 0.14.1/0013-i386-linux-user-NPTL-support.patch 2095 RMD160 db559b9b6540e21ef421a7187421687ce4bc4a92 SHA1 e072aac495c5df51f08efcd8b6073f1a62f37b14 SHA256 c4d367c3f564d4b51de2bb1960871caa4c05f783787df24d97cbd975539b166c +AUX 0.14.1/0015-S-390-support.patch 218653 RMD160 a6c71703b596b5dcb89a85e3666e4fde45b6bb69 SHA1 da575d8118e8190e524e4c38c56ca9d8670ba85f SHA256 1d89403a6cffa8a92f96c0b6a17214a618acd7cde5abf51ed10c11c659de5b64 +AUX 0.14.1/0016-fix-mipsn32-linux-user-builds.patch 1919 RMD160 45b3251fd74a078ea7f85d4253cd8f2577d152d3 SHA1 7ac33b6cd89283cec9357bdf34d7ff730a6e3537 SHA256 1b75963bfe30ffa6525ef4e14b635ac2997813e86027f4e7abd999be417af3f1 +AUX 0.14.1/0017-S-390-build-fix.patch 5784 RMD160 33604e52784141eefc1ee6c77e544b8e64edfcc6 SHA1 1bb2fd027c740cc0475289476bab0f9daa9158e8 SHA256 e90790afa0711b153ab3e0fd5a68052d4016499d8a6c6110eb25f7e0701fc9de +AUX 0.14.1/0018-qemu-0.14.1-mcast-udp.patch 10214 RMD160 1f8e767837a312d5ce912dad9551214d73b5e45b SHA1 c1fff0c9b7e60fd611973ddf9acb717e8edfa202 SHA256 182c72d1c2056ac7c5dafbb469dce58844e964949b2c9cbdb7d33edd1aca7567 +AUX 0.14.1/0019-linux-user-fix-openat.patch 1675 RMD160 6b28cb0e0b0e27e992e830994a0ed3f7e4a55497 SHA1 da19a1f0586850bc6655195a5c5e14366aac882c SHA256 8c753f00bd09594fb92625f029a6b2b04b6134b8132b8fdd753a4f835cd41582 +AUX 0.14.1/0020-linux-user-implement-reboot-syscall.patch 1403 RMD160 456a111c9681cb0d9c512c2865a3c213166533c7 SHA1 9c996094f1abbb5aae709eece617b3bfc86ca6d1 SHA256 7696d2ce0d3e311716aed420e11323d2ef83b93d7e82fac992361c3ca7d8e32b +AUX 0.14.1/0021-implement-prlimit64-syscall.patch 4175 RMD160 c31cd2e670c0fe3a8b2df462b1fb4b1e7c55cb9b SHA1 1bf72cfe09bb4bfb5101cd96fdade15bfe538926 SHA256 79d7e395b46430775f8f82b19890d2f73681d9fdfac46b807b3d148e83facf91 +AUX 0.14.1/0022-fixing-smp-races.patch 1224 RMD160 bcb627e31d677dd787c252d40da3faf45742e4bf SHA1 0b92b6b92eb8ebe92b465e0c5266ef74cf52e917 SHA256 cbb12a0cee1a123fc209b563968ee0c8b2111727adbf8b00644a24f23fbbce15 +AUX 0.14.1/0023-linux-user-add-binfmt-wrapper-for-argv-0-handling.patch 11904 RMD160 0165cdaf6a7307838993285f95c228d005ade149 SHA1 04d8c700314decb3759d530c27b5ba72d8c1c4d9 SHA256 cc2340c63ec2a216bc5d460d7419bf84f3869015fcfd73096530b43ce357ab45 +AUX 0.14.1/0025-add-syscall-numbers-from-2.6.39.2.patch 18328 RMD160 61a90462ad0109f2951d4ebb540c716861905220 SHA1 99834573cdc443c4118b6280c5e26433caa95624 SHA256 5aed07e1b71643d880eaa7432dfb99cc08958d275985d23b779cb796f1a73b18 +AUX qemu-chroot.patch 1708 RMD160 63d3b7eef95e42e31b2cce9ccd8d563836c4f822 SHA1 24e0de057661c1503f26cac9c959b8f153f1b097 SHA256 8f9de20aaf3c9e83c0aefe15c7a1d9c361540e78f874ffcf980b236276a8abf2 +AUX qemu-user.initd 7197 RMD160 7aa68863594277158abbf0b0002de738282e24cd SHA1 3e06b7857aab8876424f8ec16ca13f5aa0427c54 SHA256 9d3bc323ee5cfccf6a48e1f4f6a1ed0c9a1295e66318d790870e49cd8fdc37e1 +DIST qemu-0.14.1.tar.gz 5439697 RMD160 0601ff4e613fea0a6ce80907e2bfa11704048b36 SHA1 1a5003a03004b62b52562d1cbb8f50c5f135e0b8 SHA256 33ceae3fbe516f2cbb151dc98d16c8ccfec74b1056674ad715e75a2f7fed45c3 +EBUILD qemu-user-0.14.1.ebuild 1930 RMD160 de0949b7ef35c4b93481b2ff070f51d5c7ee235f SHA1 2c8416c1f54467b8db5f5b03a9bc9bdc73967d40 SHA256 fed2256426a6717f12d44ba7072a5e8b40ccec7c5fdb5eb4cdf5c74a112c0be8 +MISC ChangeLog 5771 RMD160 f5d5966e4739f7dfc1d7aa3bba9e5f29b29d8838 SHA1 7587a626c600a244b7004fe06413ac6b4643a2c3 SHA256 4166da87858c400f3774b676c0a58de35015c8dcca8a5a62a4edb810248b7714 +MISC metadata.xml 202 RMD160 1a73e85a81ce1045569a8b488999c0823756a0d9 SHA1 de56e79375b449ed9bdf49abd86aa9d28acd54ef SHA256 eda78eb836e5f76704299683d68168157f552076da6446e1a246b345aaa5811f diff --git a/app-emulation/qemu-user/files/0.14.1/0001-qemu-0.7.0-amd64.patch b/app-emulation/qemu-user/files/0.14.1/0001-qemu-0.7.0-amd64.patch new file mode 100644 index 0000000..55de4f8 --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0001-qemu-0.7.0-amd64.patch @@ -0,0 +1,34 @@ +From 4af9300d36f0975213b0fb967131629ad6b4c550 Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Tue, 14 Apr 2009 16:17:39 +0200 +Subject: [PATCH 01/17] qemu-0.7.0-amd64 + +No clue why this is necessary or useful, nothing found in any changelogs. +--- + x86_64.ld | 6 ++---- + 1 files changed, 2 insertions(+), 4 deletions(-) + +Index: qemu-0.14.1/x86_64.ld +=================================================================== +--- qemu-0.14.1.orig/x86_64.ld ++++ qemu-0.14.1/x86_64.ld +@@ -70,8 +70,6 @@ SECTIONS + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) } +- .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } +- .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1)); . = DATA_SEGMENT_ALIGN (0x100000, 0x1000); +@@ -97,8 +95,8 @@ SECTIONS + .data1 : { *(.data1) } + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } +- .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } +- .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table) } ++ .eh_frame : { KEEP (*(.eh_frame)) } ++ .gcc_except_table : { *(.gcc_except_table) } + .dynamic : { *(.dynamic) } + .ctors : + { diff --git a/app-emulation/qemu-user/files/0.14.1/0002-qemu-0.9.0.cvs-binfmt.patch b/app-emulation/qemu-user/files/0.14.1/0002-qemu-0.9.0.cvs-binfmt.patch new file mode 100644 index 0000000..69dd811 --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0002-qemu-0.9.0.cvs-binfmt.patch @@ -0,0 +1,82 @@ +From 8f16efecc00d3ee4615dcd2d5381b23df4465698 Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Tue, 14 Apr 2009 16:18:44 +0200 +Subject: [PATCH 02/17] qemu-0.9.0.cvs-binfmt + +Fixes binfmt_misc setup script: +- x86_64 is i386-compatible +- m68k signature fixed +- path to QEMU + +Signed-off-by: Ulrich Hecht +--- + scripts/qemu-binfmt-conf.sh | 35 +++++++++++++++++++---------------- + 1 files changed, 19 insertions(+), 16 deletions(-) + +diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh +index c50beb7..335ab05 100644 +--- a/scripts/qemu-binfmt-conf.sh ++++ b/scripts/qemu-binfmt-conf.sh +@@ -27,40 +27,43 @@ case "$cpu" in + armv[4-9]*) + cpu="arm" + ;; ++ sparc*) ++ cpu="sparc" ++ ;; + esac + + # register the interpreter for each cpu except for the native one + if [ $cpu != "i386" ] ; then +- echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register +- echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register ++ echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register ++ echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "alpha" ] ; then +- echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-alpha:' > /proc/sys/fs/binfmt_misc/register ++ echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-alpha:' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "arm" ] ; then +- echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register +- echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-armeb:' > /proc/sys/fs/binfmt_misc/register ++ echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register ++ echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-armeb:' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "sparc" ] ; then +- echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register ++ echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "ppc" ] ; then +- echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register ++ echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "m68k" ] ; then + echo 'Please check cpu value and header information for m68k!' +- echo ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register ++ echo ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "mips" ] ; then + # FIXME: We could use the other endianness on a MIPS host. +- echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register +- echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register +- echo ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mipsn32:' > /proc/sys/fs/binfmt_misc/register +- echo ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsn32el:' > /proc/sys/fs/binfmt_misc/register +- echo ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips64:' > /proc/sys/fs/binfmt_misc/register +- echo ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mips64el:' > /proc/sys/fs/binfmt_misc/register ++ echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register ++ echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register ++ echo ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mipsn32:' > /proc/sys/fs/binfmt_misc/register ++ echo ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsn32el:' > /proc/sys/fs/binfmt_misc/register ++ echo ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips64:' > /proc/sys/fs/binfmt_misc/register ++ echo ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mips64el:' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "sh" ] ; then +- echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-sh4:' > /proc/sys/fs/binfmt_misc/register +- echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sh4eb:' > /proc/sys/fs/binfmt_misc/register ++ echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-sh4:' > /proc/sys/fs/binfmt_misc/register ++ echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb:' > /proc/sys/fs/binfmt_misc/register + fi +-- +1.7.1 + diff --git a/app-emulation/qemu-user/files/0.14.1/0003-qemu-cvs-alsa_bitfield.patch b/app-emulation/qemu-user/files/0.14.1/0003-qemu-cvs-alsa_bitfield.patch new file mode 100644 index 0000000..b2c19ef --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0003-qemu-cvs-alsa_bitfield.patch @@ -0,0 +1,83 @@ +From 8a88b86cc9a3ad0bb6da52fb0f938fe5a085c027 Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Tue, 14 Apr 2009 16:20:50 +0200 +Subject: [PATCH 03/17] qemu-cvs-alsa_bitfield + +Implements TYPE_INTBITFIELD partially. (required for ALSA support) + +Signed-off-by: Ulrich Hecht +--- + thunk.c | 21 +++++++++++++++++++++ + thunk.h | 3 +++ + 2 files changed, 24 insertions(+), 0 deletions(-) + +diff --git a/thunk.c b/thunk.c +index 0657188..5638b2c 100644 +--- a/thunk.c ++++ b/thunk.c +@@ -41,6 +41,7 @@ static inline const argtype *thunk_type_next(const argtype *type_ptr) + case TYPE_CHAR: + case TYPE_SHORT: + case TYPE_INT: ++ case TYPE_INTBITFIELD: + case TYPE_LONGLONG: + case TYPE_ULONGLONG: + case TYPE_LONG: +@@ -139,6 +140,26 @@ const argtype *thunk_convert(void *dst, const void *src, + case TYPE_INT: + *(uint32_t *)dst = tswap32(*(uint32_t *)src); + break; ++ case TYPE_INTBITFIELD: ++#if defined(TARGET_I386) && defined(__powerpc__) ++ /* powerpc uses the MSB, whereas i386 uses the LSB ++ * to store the first bit in a field */ ++ { ++ unsigned char byte = *(uint8_t *)src; ++ *(uint8_t *)dst = ((byte >> 7) & 1) ++ | ((byte >> 5) & 2) ++ | ((byte >> 3) & 4) ++ | ((byte >> 1) & 8) ++ | ((byte << 1) & 16) ++ | ((byte << 3) & 32) ++ | ((byte << 5) & 64) ++ | ((byte << 7) & 128); ++ /* FIXME: implement for bitfields > 1 byte and other archs */ ++ } ++#else ++ *(uint32_t *)dst = tswap32(*(uint32_t *)src); ++#endif ++ break; + case TYPE_LONGLONG: + case TYPE_ULONGLONG: + *(uint64_t *)dst = tswap64(*(uint64_t *)src); +diff --git a/thunk.h b/thunk.h +index 109c541..55890f3 100644 +--- a/thunk.h ++++ b/thunk.h +@@ -37,6 +37,7 @@ typedef enum argtype { + TYPE_PTR, + TYPE_ARRAY, + TYPE_STRUCT, ++ TYPE_INTBITFIELD, + } argtype; + + #define MK_PTR(type) TYPE_PTR, type +@@ -90,6 +91,7 @@ static inline int thunk_type_size(const argtype *type_ptr, int is_host) + case TYPE_SHORT: + return 2; + case TYPE_INT: ++ case TYPE_INTBITFIELD: + return 4; + case TYPE_LONGLONG: + case TYPE_ULONGLONG: +@@ -127,6 +129,7 @@ static inline int thunk_type_align(const argtype *type_ptr, int is_host) + case TYPE_SHORT: + return 2; + case TYPE_INT: ++ case TYPE_INTBITFIELD: + return 4; + case TYPE_LONGLONG: + case TYPE_ULONGLONG: +-- +1.7.1 + diff --git a/app-emulation/qemu-user/files/0.14.1/0004-qemu-cvs-alsa_ioctl.patch b/app-emulation/qemu-user/files/0.14.1/0004-qemu-cvs-alsa_ioctl.patch new file mode 100644 index 0000000..46a0cbc --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0004-qemu-cvs-alsa_ioctl.patch @@ -0,0 +1,3626 @@ +From c5b614579d85877cfa39dfea8989040e43f9ba56 Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Tue, 14 Apr 2009 16:23:27 +0200 +Subject: [PATCH 04/17] qemu-cvs-alsa_ioctl + +Implements ALSA ioctls on PPC hosts. + +Signed-off-by: Ulrich Hecht +--- + linux-user/ioctls.h | 5 + + linux-user/ioctls_alsa.h | 467 ++++++++++ + linux-user/ioctls_alsa_structs.h | 1740 ++++++++++++++++++++++++++++++++++++++ + linux-user/syscall_defs.h | 1 + + linux-user/syscall_types.h | 5 + + linux-user/syscall_types_alsa.h | 1337 +++++++++++++++++++++++++++++ + 6 files changed, 3555 insertions(+), 0 deletions(-) + create mode 100644 linux-user/ioctls_alsa.h + create mode 100644 linux-user/ioctls_alsa_structs.h + create mode 100644 linux-user/syscall_types_alsa.h + +diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h +index acff781..13ff54f 100644 +--- a/linux-user/ioctls.h ++++ b/linux-user/ioctls.h +@@ -308,6 +308,11 @@ + IOCTL(VFAT_IOCTL_READDIR_BOTH, IOC_R, MK_PTR(MK_ARRAY(MK_STRUCT(STRUCT_dirent), 2))) + IOCTL(VFAT_IOCTL_READDIR_SHORT, IOC_R, MK_PTR(MK_ARRAY(MK_STRUCT(STRUCT_dirent), 2))) + ++/* FIXME: including these on x86 / x86_64 breaks qemu-i386 */ ++#ifdef __powerpc__ ++#include "ioctls_alsa.h" ++#endif ++ + IOCTL(LOOP_SET_FD, 0, TYPE_INT) + IOCTL(LOOP_CLR_FD, 0, TYPE_INT) + IOCTL(LOOP_SET_STATUS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info))) +diff --git a/linux-user/ioctls_alsa.h b/linux-user/ioctls_alsa.h +new file mode 100644 +index 0000000..c2aa542 +--- /dev/null ++++ b/linux-user/ioctls_alsa.h +@@ -0,0 +1,467 @@ ++#define SNDRV_SEQ_IOCTL_PVERSION _IOR ('S', 0x00, int) ++#define SNDRV_SEQ_IOCTL_CLIENT_ID _IOR ('S', 0x01, int) ++#define SNDRV_SEQ_IOCTL_SYSTEM_INFO _IOWR('S', 0x02, struct sndrv_seq_system_info) ++#define SNDRV_SEQ_IOCTL_RUNNING_MODE _IOWR('S', 0x03, struct sndrv_seq_running_info) ++#define SNDRV_SEQ_IOCTL_GET_CLIENT_INFO _IOWR('S', 0x10, struct sndrv_seq_client_info) ++#define SNDRV_SEQ_IOCTL_SET_CLIENT_INFO _IOW ('S', 0x11, struct sndrv_seq_client_info) ++#define SNDRV_SEQ_IOCTL_CREATE_PORT _IOWR('S', 0x20, struct sndrv_seq_port_info) ++#define SNDRV_SEQ_IOCTL_DELETE_PORT _IOW ('S', 0x21, struct sndrv_seq_port_info) ++#define SNDRV_SEQ_IOCTL_GET_PORT_INFO _IOWR('S', 0x22, struct sndrv_seq_port_info) ++#define SNDRV_SEQ_IOCTL_SET_PORT_INFO _IOW ('S', 0x23, struct sndrv_seq_port_info) ++#define SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT _IOW ('S', 0x30, struct sndrv_seq_port_subscribe) ++#define SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT _IOW ('S', 0x31, struct sndrv_seq_port_subscribe) ++#define SNDRV_SEQ_IOCTL_CREATE_QUEUE _IOWR('S', 0x32, struct sndrv_seq_queue_info) ++#define SNDRV_SEQ_IOCTL_DELETE_QUEUE _IOW ('S', 0x33, struct sndrv_seq_queue_info) ++#define SNDRV_SEQ_IOCTL_GET_QUEUE_INFO _IOWR('S', 0x34, struct sndrv_seq_queue_info) ++#define SNDRV_SEQ_IOCTL_SET_QUEUE_INFO _IOWR('S', 0x35, struct sndrv_seq_queue_info) ++#define SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE _IOWR('S', 0x36, struct sndrv_seq_queue_info) ++#define SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS _IOWR('S', 0x40, struct sndrv_seq_queue_status) ++#define SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO _IOWR('S', 0x41, struct sndrv_seq_queue_tempo) ++#define SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO _IOW ('S', 0x42, struct sndrv_seq_queue_tempo) ++#define SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER _IOWR('S', 0x43, struct sndrv_seq_queue_owner) ++#define SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER _IOW ('S', 0x44, struct sndrv_seq_queue_owner) ++#define SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER _IOWR('S', 0x45, struct sndrv_seq_queue_timer) ++#define SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER _IOW ('S', 0x46, struct sndrv_seq_queue_timer) ++#define SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC _IOWR('S', 0x53, struct sndrv_seq_queue_sync) ++#define SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC _IOW ('S', 0x54, struct sndrv_seq_queue_sync) ++#define SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT _IOWR('S', 0x49, struct sndrv_seq_queue_client) ++#define SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT _IOW ('S', 0x4a, struct sndrv_seq_queue_client) ++#define SNDRV_SEQ_IOCTL_GET_CLIENT_POOL _IOWR('S', 0x4b, struct sndrv_seq_client_pool) ++#define SNDRV_SEQ_IOCTL_SET_CLIENT_POOL _IOW ('S', 0x4c, struct sndrv_seq_client_pool) ++#define SNDRV_SEQ_IOCTL_REMOVE_EVENTS _IOW ('S', 0x4e, struct sndrv_seq_remove_events) ++#define SNDRV_SEQ_IOCTL_QUERY_SUBS _IOWR('S', 0x4f, struct sndrv_seq_query_subs) ++#define SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION _IOWR('S', 0x50, struct sndrv_seq_port_subscribe) ++#define SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT _IOWR('S', 0x51, struct sndrv_seq_client_info) ++#define SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT _IOWR('S', 0x52, struct sndrv_seq_port_info) ++#define SNDRV_DM_FM_IOCTL_INFO _IOR('H', 0x20, snd_dm_fm_info_t) ++#define SNDRV_DM_FM_IOCTL_RESET _IO ('H', 0x21) ++#define SNDRV_DM_FM_IOCTL_PLAY_NOTE _IOW('H', 0x22, snd_dm_fm_note_t) ++#define SNDRV_DM_FM_IOCTL_SET_VOICE _IOW('H', 0x23, snd_dm_fm_voice_t) ++#define SNDRV_DM_FM_IOCTL_SET_PARAMS _IOW('H', 0x24, snd_dm_fm_params_t) ++#define SNDRV_DM_FM_IOCTL_SET_MODE _IOW('H', 0x25, int) ++#define SNDRV_DM_FM_IOCTL_SET_CONNECTION _IOW('H', 0x26, int) ++#define SNDRV_DM_FM_OSS_IOCTL_RESET 0x20 ++#define SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE 0x21 ++#define SNDRV_DM_FM_OSS_IOCTL_SET_VOICE 0x22 ++#define SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS 0x23 ++#define SNDRV_DM_FM_OSS_IOCTL_SET_MODE 0x24 ++#define SNDRV_DM_FM_OSS_IOCTL_SET_OPL 0x25 ++#define SNDRV_HWDEP_IOCTL_PVERSION _IOR ('H', 0x00, int) ++#define SNDRV_HWDEP_IOCTL_INFO _IOR ('H', 0x01, struct sndrv_hwdep_info) ++#define SNDRV_HWDEP_IOCTL_DSP_STATUS _IOR('H', 0x02, struct sndrv_hwdep_dsp_status) ++#define SNDRV_HWDEP_IOCTL_DSP_LOAD _IOW('H', 0x03, struct sndrv_hwdep_dsp_image) ++#define SNDRV_PCM_IOCTL_PVERSION _IOR('A', 0x00, int) ++#define SNDRV_PCM_IOCTL_INFO _IOR('A', 0x01, struct sndrv_pcm_info) ++#define SNDRV_PCM_IOCTL_TSTAMP _IOW('A', 0x02, int) ++#define SNDRV_PCM_IOCTL_HW_REFINE _IOWR('A', 0x10, struct sndrv_pcm_hw_params) ++#define SNDRV_PCM_IOCTL_HW_PARAMS _IOWR('A', 0x11, struct sndrv_pcm_hw_params) ++#define SNDRV_PCM_IOCTL_HW_FREE _IO('A', 0x12) ++#define SNDRV_PCM_IOCTL_SW_PARAMS _IOWR('A', 0x13, struct sndrv_pcm_sw_params) ++#define SNDRV_PCM_IOCTL_STATUS _IOR('A', 0x20, struct sndrv_pcm_status) ++#define SNDRV_PCM_IOCTL_DELAY _IOR('A', 0x21, sndrv_pcm_sframes_t) ++#define SNDRV_PCM_IOCTL_HWSYNC _IO('A', 0x22) ++#define SNDRV_PCM_IOCTL_SYNC_PTR _IOWR('A', 0x23, struct sndrv_pcm_sync_ptr) ++#define SNDRV_PCM_IOCTL_CHANNEL_INFO _IOR('A', 0x32, struct sndrv_pcm_channel_info) ++#define SNDRV_PCM_IOCTL_PREPARE _IO('A', 0x40) ++#define SNDRV_PCM_IOCTL_RESET _IO('A', 0x41) ++#define SNDRV_PCM_IOCTL_START _IO('A', 0x42) ++#define SNDRV_PCM_IOCTL_DROP _IO('A', 0x43) ++#define SNDRV_PCM_IOCTL_DRAIN _IO('A', 0x44) ++#define SNDRV_PCM_IOCTL_PAUSE _IOW('A', 0x45, int) ++#define SNDRV_PCM_IOCTL_REWIND _IOW('A', 0x46, sndrv_pcm_uframes_t) ++#define SNDRV_PCM_IOCTL_RESUME _IO('A', 0x47) ++#define SNDRV_PCM_IOCTL_XRUN _IO('A', 0x48) ++#define SNDRV_PCM_IOCTL_FORWARD _IOW('A', 0x49, sndrv_pcm_uframes_t) ++#define SNDRV_PCM_IOCTL_WRITEI_FRAMES _IOW('A', 0x50, struct sndrv_xferi) ++#define SNDRV_PCM_IOCTL_READI_FRAMES _IOR('A', 0x51, struct sndrv_xferi) ++#define SNDRV_PCM_IOCTL_WRITEN_FRAMES _IOW('A', 0x52, struct sndrv_xfern) ++#define SNDRV_PCM_IOCTL_READN_FRAMES _IOR('A', 0x53, struct sndrv_xfern) ++#define SNDRV_PCM_IOCTL_LINK _IOW('A', 0x60, int) ++#define SNDRV_PCM_IOCTL_UNLINK _IO('A', 0x61) ++#define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int) ++#define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct sndrv_rawmidi_info) ++#define SNDRV_RAWMIDI_IOCTL_PARAMS _IOWR('W', 0x10, struct sndrv_rawmidi_params) ++#define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct sndrv_rawmidi_status) ++#define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int) ++#define SNDRV_RAWMIDI_IOCTL_DRAIN _IOW('W', 0x31, int) ++#define SNDRV_TIMER_IOCTL_PVERSION _IOR('T', 0x00, int) ++#define SNDRV_TIMER_IOCTL_NEXT_DEVICE _IOWR('T', 0x01, struct sndrv_timer_id) ++#define SNDRV_TIMER_IOCTL_TREAD _IOW('T', 0x02, int) ++#define SNDRV_TIMER_IOCTL_GINFO _IOWR('T', 0x03, struct sndrv_timer_ginfo) ++#define SNDRV_TIMER_IOCTL_GPARAMS _IOW('T', 0x04, struct sndrv_timer_gparams) ++#define SNDRV_TIMER_IOCTL_GSTATUS _IOWR('T', 0x05, struct sndrv_timer_gstatus) ++#define SNDRV_TIMER_IOCTL_SELECT _IOW('T', 0x10, struct sndrv_timer_select) ++#define SNDRV_TIMER_IOCTL_INFO _IOR('T', 0x11, struct sndrv_timer_info) ++#define SNDRV_TIMER_IOCTL_PARAMS _IOW('T', 0x12, struct sndrv_timer_params) ++#define SNDRV_TIMER_IOCTL_STATUS _IOR('T', 0x14, struct sndrv_timer_status) ++#define SNDRV_TIMER_IOCTL_START _IO('T', 0xa0) ++#define SNDRV_TIMER_IOCTL_STOP _IO('T', 0xa1) ++#define SNDRV_TIMER_IOCTL_CONTINUE _IO('T', 0xa2) ++#define SNDRV_TIMER_IOCTL_PAUSE _IO('T', 0xa3) ++#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int) ++#define SNDRV_CTL_IOCTL_CARD_INFO _IOR('U', 0x01, struct sndrv_ctl_card_info) ++#define SNDRV_CTL_IOCTL_ELEM_LIST _IOWR('U', 0x10, struct sndrv_ctl_elem_list) ++#define SNDRV_CTL_IOCTL_ELEM_INFO _IOWR('U', 0x11, struct sndrv_ctl_elem_info) ++#define SNDRV_CTL_IOCTL_ELEM_READ _IOWR('U', 0x12, struct sndrv_ctl_elem_value) ++#define SNDRV_CTL_IOCTL_ELEM_WRITE _IOWR('U', 0x13, struct sndrv_ctl_elem_value) ++#define SNDRV_CTL_IOCTL_ELEM_LOCK _IOW('U', 0x14, struct sndrv_ctl_elem_id) ++#define SNDRV_CTL_IOCTL_ELEM_UNLOCK _IOW('U', 0x15, struct sndrv_ctl_elem_id) ++#define SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS _IOWR('U', 0x16, int) ++#define SNDRV_CTL_IOCTL_ELEM_ADD _IOWR('U', 0x17, struct sndrv_ctl_elem_info) ++#define SNDRV_CTL_IOCTL_ELEM_REPLACE _IOWR('U', 0x18, struct sndrv_ctl_elem_info) ++#define SNDRV_CTL_IOCTL_ELEM_REMOVE _IOWR('U', 0x19, struct sndrv_ctl_elem_id) ++#define SNDRV_CTL_IOCTL_TLV_READ _IOWR('U', 0x1a, struct sndrv_ctl_tlv) ++#define SNDRV_CTL_IOCTL_TLV_WRITE _IOWR('U', 0x1b, struct sndrv_ctl_tlv) ++#define SNDRV_CTL_IOCTL_TLV_COMMAND _IOWR('U', 0x1c, struct sndrv_ctl_tlv) ++#define SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE _IOWR('U', 0x20, int) ++#define SNDRV_CTL_IOCTL_HWDEP_INFO _IOR('U', 0x21, struct sndrv_hwdep_info) ++#define SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE _IOR('U', 0x30, int) ++#define SNDRV_CTL_IOCTL_PCM_INFO _IOWR('U', 0x31, struct sndrv_pcm_info) ++#define SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE _IOW('U', 0x32, int) ++#define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int) ++#define SNDRV_CTL_IOCTL_RAWMIDI_INFO _IOWR('U', 0x41, struct sndrv_rawmidi_info) ++#define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int) ++#define SNDRV_CTL_IOCTL_POWER _IOWR('U', 0xd0, int) ++#define SNDRV_CTL_IOCTL_POWER_STATE _IOR('U', 0xd1, int) ++#define SNDRV_IOCTL_READV _IOW('K', 0x00, struct sndrv_xferv) ++#define SNDRV_IOCTL_WRITEV _IOW('K', 0x01, struct sndrv_xferv) ++#define SNDRV_EMU10K1_IOCTL_INFO _IOR ('H', 0x10, emu10k1_fx8010_info_t) ++#define SNDRV_EMU10K1_IOCTL_CODE_POKE _IOW ('H', 0x11, emu10k1_fx8010_code_t) ++#define SNDRV_EMU10K1_IOCTL_CODE_PEEK _IOWR('H', 0x12, emu10k1_fx8010_code_t) ++#define SNDRV_EMU10K1_IOCTL_TRAM_SETUP _IOW ('H', 0x20, int) ++#define SNDRV_EMU10K1_IOCTL_TRAM_POKE _IOW ('H', 0x21, emu10k1_fx8010_tram_t) ++#define SNDRV_EMU10K1_IOCTL_TRAM_PEEK _IOWR('H', 0x22, emu10k1_fx8010_tram_t) ++#define SNDRV_EMU10K1_IOCTL_PCM_POKE _IOW ('H', 0x30, emu10k1_fx8010_pcm_t) ++#define SNDRV_EMU10K1_IOCTL_PCM_PEEK _IOWR('H', 0x31, emu10k1_fx8010_pcm_t) ++#define SNDRV_EMU10K1_IOCTL_PVERSION _IOR ('H', 0x40, int) ++#define SNDRV_EMU10K1_IOCTL_STOP _IO ('H', 0x80) ++#define SNDRV_EMU10K1_IOCTL_CONTINUE _IO ('H', 0x81) ++#define SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER _IO ('H', 0x82) ++#define SNDRV_EMU10K1_IOCTL_SINGLE_STEP _IOW ('H', 0x83, int) ++#define SNDRV_EMU10K1_IOCTL_DBG_READ _IOR ('H', 0x84, int) ++#define SNDRV_HDSP_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, hdsp_peak_rms_t) ++#define SNDRV_HDSP_IOCTL_GET_CONFIG_INFO _IOR('H', 0x41, hdsp_config_info_t) ++#define SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE _IOW('H', 0x42, hdsp_firmware_t) ++#define SNDRV_HDSP_IOCTL_GET_VERSION _IOR('H', 0x43, hdsp_version_t) ++#define SNDRV_HDSP_IOCTL_GET_MIXER _IOR('H', 0x44, hdsp_mixer_t) ++#define SNDRV_HDSP_IOCTL_GET_9632_AEB _IOR('H', 0x45, hdsp_9632_aeb_t) ++#define SNDRV_SB_CSP_IOCTL_INFO _IOR('H', 0x10, snd_sb_csp_info_t) ++#define SNDRV_SB_CSP_IOCTL_LOAD_CODE _IOW('H', 0x11, snd_sb_csp_microcode_t) ++#define SNDRV_SB_CSP_IOCTL_UNLOAD_CODE _IO('H', 0x12) ++#define SNDRV_SB_CSP_IOCTL_START _IOW('H', 0x13, snd_sb_csp_start_t) ++#define SNDRV_SB_CSP_IOCTL_STOP _IO('H', 0x14) ++#define SNDRV_SB_CSP_IOCTL_PAUSE _IO('H', 0x15) ++#define SNDRV_SB_CSP_IOCTL_RESTART _IO('H', 0x16) ++#define SND_SSCAPE_LOAD_BOOTB _IOWR('P', 100, struct sscape_bootblock) ++#define SND_SSCAPE_LOAD_MCODE _IOW ('P', 101, struct sscape_microcode) ++ ++ ++#define TARGET_SNDRV_SEQ_IOCTL_PVERSION TARGET_IOR ('S', 0x00, int) ++#define TARGET_SNDRV_SEQ_IOCTL_CLIENT_ID TARGET_IOR ('S', 0x01, int) ++#define TARGET_SNDRV_SEQ_IOCTL_SYSTEM_INFO TARGET_IOWRU('S', 0x02) ++#define TARGET_SNDRV_SEQ_IOCTL_RUNNING_MODE TARGET_IOWRU('S', 0x03) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_CLIENT_INFO TARGET_IOWRU('S', 0x10) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_CLIENT_INFO TARGET_IOWU ('S', 0x11) ++#define TARGET_SNDRV_SEQ_IOCTL_CREATE_PORT TARGET_IOWRU('S', 0x20) ++#define TARGET_SNDRV_SEQ_IOCTL_DELETE_PORT TARGET_IOWU ('S', 0x21) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_PORT_INFO TARGET_IOWRU('S', 0x22) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_PORT_INFO TARGET_IOWU ('S', 0x23) ++#define TARGET_SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT TARGET_IOWU ('S', 0x30) ++#define TARGET_SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT TARGET_IOWU ('S', 0x31) ++#define TARGET_SNDRV_SEQ_IOCTL_CREATE_QUEUE TARGET_IOWRU('S', 0x32) ++#define TARGET_SNDRV_SEQ_IOCTL_DELETE_QUEUE TARGET_IOWU ('S', 0x33) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_INFO TARGET_IOWRU('S', 0x34) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_INFO TARGET_IOWRU('S', 0x35) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE TARGET_IOWRU('S', 0x36) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS TARGET_IOWRU('S', 0x40) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO TARGET_IOWRU('S', 0x41) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO TARGET_IOWU ('S', 0x42) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER TARGET_IOWRU('S', 0x43) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER TARGET_IOWU ('S', 0x44) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER TARGET_IOWRU('S', 0x45) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER TARGET_IOWU ('S', 0x46) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC TARGET_IOWRU('S', 0x53) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC TARGET_IOWU ('S', 0x54) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT TARGET_IOWRU('S', 0x49) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT TARGET_IOWU ('S', 0x4a) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_CLIENT_POOL TARGET_IOWRU('S', 0x4b) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_CLIENT_POOL TARGET_IOWU ('S', 0x4c) ++#define TARGET_SNDRV_SEQ_IOCTL_REMOVE_EVENTS TARGET_IOWU ('S', 0x4e) ++#define TARGET_SNDRV_SEQ_IOCTL_QUERY_SUBS TARGET_IOWRU('S', 0x4f) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION TARGET_IOWRU('S', 0x50) ++#define TARGET_SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT TARGET_IOWRU('S', 0x51) ++#define TARGET_SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT TARGET_IOWRU('S', 0x52) ++#define TARGET_SNDRV_DM_FM_IOCTL_INFO TARGET_IORU('H', 0x20) ++#define TARGET_SNDRV_DM_FM_IOCTL_RESET TARGET_IO ('H', 0x21) ++#define TARGET_SNDRV_DM_FM_IOCTL_PLAY_NOTE TARGET_IOWU('H', 0x22) ++#define TARGET_SNDRV_DM_FM_IOCTL_SET_VOICE TARGET_IOWU('H', 0x23) ++#define TARGET_SNDRV_DM_FM_IOCTL_SET_PARAMS TARGET_IOWU('H', 0x24) ++#define TARGET_SNDRV_DM_FM_IOCTL_SET_MODE TARGET_IOW('H', 0x25, int) ++#define TARGET_SNDRV_DM_FM_IOCTL_SET_CONNECTION TARGET_IOW('H', 0x26, int) ++#define TARGET_SNDRV_DM_FM_OSS_IOCTL_RESET 0x20 ++#define TARGET_SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE 0x21 ++#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_VOICE 0x22 ++#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS 0x23 ++#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_MODE 0x24 ++#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_OPL 0x25 ++#define TARGET_SNDRV_HWDEP_IOCTL_PVERSION TARGET_IOR ('H', 0x00, int) ++#define TARGET_SNDRV_HWDEP_IOCTL_INFO TARGET_IORU ('H', 0x01) ++#define TARGET_SNDRV_HWDEP_IOCTL_DSP_STATUS TARGET_IORU('H', 0x02) ++#define TARGET_SNDRV_HWDEP_IOCTL_DSP_LOAD TARGET_IOWU('H', 0x03) ++#define TARGET_SNDRV_PCM_IOCTL_PVERSION TARGET_IOR('A', 0x00, int) ++#define TARGET_SNDRV_PCM_IOCTL_INFO TARGET_IORU('A', 0x01) ++#define TARGET_SNDRV_PCM_IOCTL_TSTAMP TARGET_IOW('A', 0x02, int) ++#define TARGET_SNDRV_PCM_IOCTL_HW_REFINE TARGET_IOWRU('A', 0x10) ++#define TARGET_SNDRV_PCM_IOCTL_HW_PARAMS TARGET_IOWRU('A', 0x11) ++#define TARGET_SNDRV_PCM_IOCTL_HW_FREE TARGET_IO('A', 0x12) ++#define TARGET_SNDRV_PCM_IOCTL_SW_PARAMS TARGET_IOWRU('A', 0x13) ++#define TARGET_SNDRV_PCM_IOCTL_STATUS TARGET_IORU('A', 0x20) ++#define TARGET_SNDRV_PCM_IOCTL_DELAY TARGET_IORU('A', 0x21) ++#define TARGET_SNDRV_PCM_IOCTL_HWSYNC TARGET_IO('A', 0x22) ++#define TARGET_SNDRV_PCM_IOCTL_SYNC_PTR TARGET_IOWRU('A', 0x23) ++#define TARGET_SNDRV_PCM_IOCTL_CHANNEL_INFO TARGET_IORU('A', 0x32) ++#define TARGET_SNDRV_PCM_IOCTL_PREPARE TARGET_IO('A', 0x40) ++#define TARGET_SNDRV_PCM_IOCTL_RESET TARGET_IO('A', 0x41) ++#define TARGET_SNDRV_PCM_IOCTL_START TARGET_IO('A', 0x42) ++#define TARGET_SNDRV_PCM_IOCTL_DROP TARGET_IO('A', 0x43) ++#define TARGET_SNDRV_PCM_IOCTL_DRAIN TARGET_IO('A', 0x44) ++#define TARGET_SNDRV_PCM_IOCTL_PAUSE TARGET_IOW('A', 0x45, int) ++#define TARGET_SNDRV_PCM_IOCTL_REWIND TARGET_IOWU('A', 0x46) ++#define TARGET_SNDRV_PCM_IOCTL_RESUME TARGET_IO('A', 0x47) ++#define TARGET_SNDRV_PCM_IOCTL_XRUN TARGET_IO('A', 0x48) ++#define TARGET_SNDRV_PCM_IOCTL_FORWARD TARGET_IOWU('A', 0x49) ++#define TARGET_SNDRV_PCM_IOCTL_WRITEI_FRAMES TARGET_IOWU('A', 0x50) ++#define TARGET_SNDRV_PCM_IOCTL_READI_FRAMES TARGET_IORU('A', 0x51) ++#define TARGET_SNDRV_PCM_IOCTL_WRITEN_FRAMES TARGET_IOWU('A', 0x52) ++#define TARGET_SNDRV_PCM_IOCTL_READN_FRAMES TARGET_IORU('A', 0x53) ++#define TARGET_SNDRV_PCM_IOCTL_LINK TARGET_IOW('A', 0x60, int) ++#define TARGET_SNDRV_PCM_IOCTL_UNLINK TARGET_IO('A', 0x61) ++#define TARGET_SNDRV_RAWMIDI_IOCTL_PVERSION TARGET_IOR('W', 0x00, int) ++#define TARGET_SNDRV_RAWMIDI_IOCTL_INFO TARGET_IORU('W', 0x01) ++#define TARGET_SNDRV_RAWMIDI_IOCTL_PARAMS TARGET_IOWRU('W', 0x10) ++#define TARGET_SNDRV_RAWMIDI_IOCTL_STATUS TARGET_IOWRU('W', 0x20) ++#define TARGET_SNDRV_RAWMIDI_IOCTL_DROP TARGET_IOW('W', 0x30, int) ++#define TARGET_SNDRV_RAWMIDI_IOCTL_DRAIN TARGET_IOW('W', 0x31, int) ++#define TARGET_SNDRV_TIMER_IOCTL_PVERSION TARGET_IOR('T', 0x00, int) ++#define TARGET_SNDRV_TIMER_IOCTL_NEXT_DEVICE TARGET_IOWRU('T', 0x01) ++#define TARGET_SNDRV_TIMER_IOCTL_TREAD TARGET_IOW('T', 0x02, int) ++#define TARGET_SNDRV_TIMER_IOCTL_GINFO TARGET_IOWRU('T', 0x03) ++#define TARGET_SNDRV_TIMER_IOCTL_GPARAMS TARGET_IOWU('T', 0x04) ++#define TARGET_SNDRV_TIMER_IOCTL_GSTATUS TARGET_IOWRU('T', 0x05) ++#define TARGET_SNDRV_TIMER_IOCTL_SELECT TARGET_IOWU('T', 0x10) ++#define TARGET_SNDRV_TIMER_IOCTL_INFO TARGET_IORU('T', 0x11) ++#define TARGET_SNDRV_TIMER_IOCTL_PARAMS TARGET_IOWU('T', 0x12) ++#define TARGET_SNDRV_TIMER_IOCTL_STATUS TARGET_IORU('T', 0x14) ++#define TARGET_SNDRV_TIMER_IOCTL_START TARGET_IO('T', 0xa0) ++#define TARGET_SNDRV_TIMER_IOCTL_STOP TARGET_IO('T', 0xa1) ++#define TARGET_SNDRV_TIMER_IOCTL_CONTINUE TARGET_IO('T', 0xa2) ++#define TARGET_SNDRV_TIMER_IOCTL_PAUSE TARGET_IO('T', 0xa3) ++#define TARGET_SNDRV_CTL_IOCTL_PVERSION TARGET_IOR('U', 0x00, int) ++#define TARGET_SNDRV_CTL_IOCTL_CARD_INFO TARGET_IORU('U', 0x01) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_LIST TARGET_IOWRU('U', 0x10) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_INFO TARGET_IOWRU('U', 0x11) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_READ TARGET_IOWRU('U', 0x12) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_WRITE TARGET_IOWRU('U', 0x13) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_LOCK TARGET_IOWU('U', 0x14) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_UNLOCK TARGET_IOWU('U', 0x15) ++#define TARGET_SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS TARGET_IOWR('U', 0x16, int) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_ADD TARGET_IOWRU('U', 0x17) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_REPLACE TARGET_IOWRU('U', 0x18) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_REMOVE TARGET_IOWRU('U', 0x19) ++#define TARGET_SNDRV_CTL_IOCTL_TLV_READ TARGET_IOWRU('U', 0x1a) ++#define TARGET_SNDRV_CTL_IOCTL_TLV_WRITE TARGET_IOWRU('U', 0x1b) ++#define TARGET_SNDRV_CTL_IOCTL_TLV_COMMAND TARGET_IOWRU('U', 0x1c) ++#define TARGET_SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE TARGET_IOWR('U', 0x20, int) ++#define TARGET_SNDRV_CTL_IOCTL_HWDEP_INFO TARGET_IORU('U', 0x21) ++#define TARGET_SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE TARGET_IOR('U', 0x30, int) ++#define TARGET_SNDRV_CTL_IOCTL_PCM_INFO TARGET_IOWRU('U', 0x31) ++#define TARGET_SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE TARGET_IOW('U', 0x32, int) ++#define TARGET_SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE TARGET_IOWR('U', 0x40, int) ++#define TARGET_SNDRV_CTL_IOCTL_RAWMIDI_INFO TARGET_IOWRU('U', 0x41) ++#define TARGET_SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE TARGET_IOW('U', 0x42, int) ++#define TARGET_SNDRV_CTL_IOCTL_POWER TARGET_IOWR('U', 0xd0, int) ++#define TARGET_SNDRV_CTL_IOCTL_POWER_STATE TARGET_IOR('U', 0xd1, int) ++#define TARGET_SNDRV_IOCTL_READV TARGET_IOWU('K', 0x00) ++#define TARGET_SNDRV_IOCTL_WRITEV TARGET_IOWU('K', 0x01) ++#define TARGET_SNDRV_EMU10K1_IOCTL_INFO TARGET_IORU ('H', 0x10) ++#define TARGET_SNDRV_EMU10K1_IOCTL_CODE_POKE TARGET_IOWU ('H', 0x11) ++#define TARGET_SNDRV_EMU10K1_IOCTL_CODE_PEEK TARGET_IOWRU('H', 0x12) ++#define TARGET_SNDRV_EMU10K1_IOCTL_TRAM_SETUP TARGET_IOW ('H', 0x20, int) ++#define TARGET_SNDRV_EMU10K1_IOCTL_TRAM_POKE TARGET_IOWU ('H', 0x21) ++#define TARGET_SNDRV_EMU10K1_IOCTL_TRAM_PEEK TARGET_IOWRU('H', 0x22) ++#define TARGET_SNDRV_EMU10K1_IOCTL_PCM_POKE TARGET_IOWU ('H', 0x30) ++#define TARGET_SNDRV_EMU10K1_IOCTL_PCM_PEEK TARGET_IOWRU('H', 0x31) ++#define TARGET_SNDRV_EMU10K1_IOCTL_PVERSION TARGET_IOR ('H', 0x40, int) ++#define TARGET_SNDRV_EMU10K1_IOCTL_STOP TARGET_IO ('H', 0x80) ++#define TARGET_SNDRV_EMU10K1_IOCTL_CONTINUE TARGET_IO ('H', 0x81) ++#define TARGET_SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER TARGET_IO ('H', 0x82) ++#define TARGET_SNDRV_EMU10K1_IOCTL_SINGLE_STEP TARGET_IOW ('H', 0x83, int) ++#define TARGET_SNDRV_EMU10K1_IOCTL_DBG_READ TARGET_IOR ('H', 0x84, int) ++#define TARGET_SNDRV_HDSP_IOCTL_GET_PEAK_RMS TARGET_IORU('H', 0x40) ++#define TARGET_SNDRV_HDSP_IOCTL_GET_CONFIG_INFO TARGET_IORU('H', 0x41) ++#define TARGET_SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE TARGET_IOWU('H', 0x42) ++#define TARGET_SNDRV_HDSP_IOCTL_GET_VERSION TARGET_IORU('H', 0x43) ++#define TARGET_SNDRV_HDSP_IOCTL_GET_MIXER TARGET_IORU('H', 0x44) ++#define TARGET_SNDRV_HDSP_IOCTL_GET_9632_AEB TARGET_IORU('H', 0x45) ++#define TARGET_SNDRV_SB_CSP_IOCTL_INFO TARGET_IORU('H', 0x10) ++#define TARGET_SNDRV_SB_CSP_IOCTL_LOAD_CODE TARGET_IOWU('H', 0x11) ++#define TARGET_SNDRV_SB_CSP_IOCTL_UNLOAD_CODE TARGET_IO('H', 0x12) ++#define TARGET_SNDRV_SB_CSP_IOCTL_START TARGET_IOWU('H', 0x13) ++#define TARGET_SNDRV_SB_CSP_IOCTL_STOP TARGET_IO('H', 0x14) ++#define TARGET_SNDRV_SB_CSP_IOCTL_PAUSE TARGET_IO('H', 0x15) ++#define TARGET_SNDRV_SB_CSP_IOCTL_RESTART TARGET_IO('H', 0x16) ++#define TARGET_SND_SSCAPE_LOAD_BOOTB TARGET_IOWRU('P', 100) ++#define TARGET_SND_SSCAPE_LOAD_MCODE TARGET_IOWU ('P', 101) ++ ++IOCTL( SNDRV_SEQ_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_SEQ_IOCTL_CLIENT_ID , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_SEQ_IOCTL_SYSTEM_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_system_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_RUNNING_MODE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_running_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_CLIENT_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_SET_CLIENT_INFO , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_CREATE_PORT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_DELETE_PORT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_PORT_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_SET_PORT_INFO , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_subscribe)) ) ++IOCTL( SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_subscribe)) ) ++IOCTL( SNDRV_SEQ_IOCTL_CREATE_QUEUE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_DELETE_QUEUE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_status)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_tempo)) ) ++IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_tempo)) ) ++//IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_owner)) ) ++//IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_owner)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_timer)) ) ++IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_timer)) ) ++//IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_sync)) ) ++//IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_sync)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_client)) ) ++IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_client)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_CLIENT_POOL , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_pool)) ) ++IOCTL( SNDRV_SEQ_IOCTL_SET_CLIENT_POOL , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_pool)) ) ++IOCTL( SNDRV_SEQ_IOCTL_REMOVE_EVENTS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_remove_events)) ) ++IOCTL( SNDRV_SEQ_IOCTL_QUERY_SUBS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_query_subs)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_subscribe)) ) ++IOCTL( SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) ) ++IOCTL( SNDRV_DM_FM_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_info)) ) ++IOCTL( SNDRV_DM_FM_IOCTL_RESET , 0, TYPE_NULL ) ++IOCTL( SNDRV_DM_FM_IOCTL_PLAY_NOTE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_note)) ) ++IOCTL( SNDRV_DM_FM_IOCTL_SET_VOICE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_voice)) ) ++IOCTL( SNDRV_DM_FM_IOCTL_SET_PARAMS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_params)) ) ++IOCTL( SNDRV_DM_FM_IOCTL_SET_MODE , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_DM_FM_IOCTL_SET_CONNECTION , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_HWDEP_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_HWDEP_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_info)) ) ++IOCTL( SNDRV_HWDEP_IOCTL_DSP_STATUS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_dsp_status)) ) ++IOCTL( SNDRV_HWDEP_IOCTL_DSP_LOAD , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_dsp_image)) ) ++IOCTL( SNDRV_PCM_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_PCM_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_info)) ) ++IOCTL( SNDRV_PCM_IOCTL_TSTAMP , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_PCM_IOCTL_HW_REFINE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_hw_params)) ) ++IOCTL( SNDRV_PCM_IOCTL_HW_PARAMS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_hw_params)) ) ++IOCTL( SNDRV_PCM_IOCTL_HW_FREE , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_SW_PARAMS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_sw_params)) ) ++IOCTL( SNDRV_PCM_IOCTL_STATUS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_status)) ) ++IOCTL( SNDRV_PCM_IOCTL_DELAY , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_sframes)) ) ++IOCTL( SNDRV_PCM_IOCTL_HWSYNC , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_SYNC_PTR , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_sync_ptr)) ) ++IOCTL( SNDRV_PCM_IOCTL_CHANNEL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_channel_info)) ) ++IOCTL( SNDRV_PCM_IOCTL_PREPARE , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_RESET , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_START , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_DROP , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_DRAIN , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_PAUSE , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_PCM_IOCTL_REWIND , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_uframes)) ) ++IOCTL( SNDRV_PCM_IOCTL_RESUME , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_XRUN , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_FORWARD , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_uframes)) ) ++IOCTL( SNDRV_PCM_IOCTL_WRITEI_FRAMES , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferi)) ) ++IOCTL( SNDRV_PCM_IOCTL_READI_FRAMES , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferi)) ) ++IOCTL( SNDRV_PCM_IOCTL_WRITEN_FRAMES , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xfern)) ) ++IOCTL( SNDRV_PCM_IOCTL_READN_FRAMES , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_xfern)) ) ++IOCTL( SNDRV_PCM_IOCTL_LINK , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_PCM_IOCTL_UNLINK , 0, TYPE_NULL ) ++IOCTL( SNDRV_RAWMIDI_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_RAWMIDI_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_info)) ) ++IOCTL( SNDRV_RAWMIDI_IOCTL_PARAMS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_params)) ) ++IOCTL( SNDRV_RAWMIDI_IOCTL_STATUS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_status)) ) ++IOCTL( SNDRV_RAWMIDI_IOCTL_DROP , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_RAWMIDI_IOCTL_DRAIN , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_TIMER_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_TIMER_IOCTL_NEXT_DEVICE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_id)) ) ++IOCTL( SNDRV_TIMER_IOCTL_TREAD , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_TIMER_IOCTL_GINFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_ginfo)) ) ++IOCTL( SNDRV_TIMER_IOCTL_GPARAMS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_gparams)) ) ++IOCTL( SNDRV_TIMER_IOCTL_GSTATUS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_gstatus)) ) ++IOCTL( SNDRV_TIMER_IOCTL_SELECT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_select)) ) ++IOCTL( SNDRV_TIMER_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_info)) ) ++IOCTL( SNDRV_TIMER_IOCTL_PARAMS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_params)) ) ++IOCTL( SNDRV_TIMER_IOCTL_STATUS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_status)) ) ++IOCTL( SNDRV_TIMER_IOCTL_START , 0, TYPE_NULL ) ++IOCTL( SNDRV_TIMER_IOCTL_STOP , 0, TYPE_NULL ) ++IOCTL( SNDRV_TIMER_IOCTL_CONTINUE , 0, TYPE_NULL ) ++IOCTL( SNDRV_TIMER_IOCTL_PAUSE , 0, TYPE_NULL ) ++IOCTL( SNDRV_CTL_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_CTL_IOCTL_CARD_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_card_info)) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_LIST , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_list)) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_info)) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_READ , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_value)) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_WRITE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_value)) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_LOCK , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_id)) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_UNLOCK , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_id)) ) ++IOCTL( SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS , IOC_RW, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_ADD , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_info)) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_REPLACE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_info)) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_REMOVE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_id)) ) ++IOCTL( SNDRV_CTL_IOCTL_TLV_READ , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_tlv)) ) ++IOCTL( SNDRV_CTL_IOCTL_TLV_WRITE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_tlv)) ) ++IOCTL( SNDRV_CTL_IOCTL_TLV_COMMAND , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_tlv)) ) ++IOCTL( SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE , IOC_RW, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_CTL_IOCTL_HWDEP_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_info)) ) ++IOCTL( SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_CTL_IOCTL_PCM_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_info)) ) ++IOCTL( SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE , IOC_RW, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_CTL_IOCTL_RAWMIDI_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_info)) ) ++IOCTL( SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_CTL_IOCTL_POWER , IOC_RW, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_CTL_IOCTL_POWER_STATE , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_IOCTL_READV , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferv)) ) ++IOCTL( SNDRV_IOCTL_WRITEV , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferv)) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_info)) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_CODE_POKE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_code)) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_CODE_PEEK , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_code)) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_TRAM_SETUP , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_TRAM_POKE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_tram)) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_TRAM_PEEK , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_tram)) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_PCM_POKE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_pcm)) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_PCM_PEEK , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_pcm)) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_STOP , 0, TYPE_NULL ) ++IOCTL( SNDRV_EMU10K1_IOCTL_CONTINUE , 0, TYPE_NULL ) ++IOCTL( SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER , 0, TYPE_NULL ) ++IOCTL( SNDRV_EMU10K1_IOCTL_SINGLE_STEP , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_DBG_READ , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_HDSP_IOCTL_GET_PEAK_RMS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_peak_rms)) ) ++IOCTL( SNDRV_HDSP_IOCTL_GET_CONFIG_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_config_info)) ) ++IOCTL( SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_hdsp_firmware)) ) ++IOCTL( SNDRV_HDSP_IOCTL_GET_VERSION , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_version)) ) ++IOCTL( SNDRV_HDSP_IOCTL_GET_MIXER , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_mixer)) ) ++IOCTL( SNDRV_HDSP_IOCTL_GET_9632_AEB , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_9632_aeb)) ) ++IOCTL( SNDRV_SB_CSP_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_snd_sb_csp_info)) ) ++#if _IOC_SIZEBITS > 13 ++IOCTL( SNDRV_SB_CSP_IOCTL_LOAD_CODE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_sb_csp_microcode)) ) ++#endif ++IOCTL( SNDRV_SB_CSP_IOCTL_UNLOAD_CODE , 0, TYPE_NULL ) ++IOCTL( SNDRV_SB_CSP_IOCTL_START , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_sb_csp_start)) ) ++IOCTL( SNDRV_SB_CSP_IOCTL_STOP , 0, TYPE_NULL ) ++IOCTL( SNDRV_SB_CSP_IOCTL_PAUSE , 0, TYPE_NULL ) ++IOCTL( SNDRV_SB_CSP_IOCTL_RESTART , 0, TYPE_NULL ) ++IOCTL( SND_SSCAPE_LOAD_BOOTB , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sscape_bootblock)) ) ++IOCTL( SND_SSCAPE_LOAD_MCODE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sscape_microcode)) ) +diff --git a/linux-user/ioctls_alsa_structs.h b/linux-user/ioctls_alsa_structs.h +new file mode 100644 +index 0000000..3de8614 +--- /dev/null ++++ b/linux-user/ioctls_alsa_structs.h +@@ -0,0 +1,1740 @@ ++/* ++ * Advanced Linux Sound Architecture ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++ ++#ifndef __u8 ++#define __u8 uint8_t ++#define __u16 uint16_t ++#define __u32 uint32_t ++#define __s8 int8_t ++#define __s16 int16_t ++#define __s32 int32_t ++#endif ++ ++#define SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE 0x3000 ++#define HDSP_MATRIX_MIXER_SIZE 2048 ++#define SNDRV_MASK_MAX 256 ++ ++typedef struct fm_operator { ++ unsigned char am_vib; ++ unsigned char ksl_level; ++ unsigned char attack_decay; ++ unsigned char sustain_release; ++ unsigned char wave_select; ++} fm_operator_t; ++ ++typedef struct { ++ unsigned int share_id[4]; /* share id - zero = no sharing */ ++ unsigned char type; /* instrument type */ ++ ++ fm_operator_t op[4]; ++ unsigned char feedback_connection[2]; ++ ++ unsigned char echo_delay; ++ unsigned char echo_atten; ++ unsigned char chorus_spread; ++ unsigned char trnsps; ++ unsigned char fix_dur; ++ unsigned char modes; ++ unsigned char fix_key; ++} fm_instrument_t; ++ ++typedef struct fm_xoperator { ++ __u8 am_vib; ++ __u8 ksl_level; ++ __u8 attack_decay; ++ __u8 sustain_release; ++ __u8 wave_select; ++} fm_xoperator_t; ++ ++typedef struct fm_xinstrument { ++ __u32 stype; /* structure type */ ++ ++ __u32 share_id[4]; /* share id - zero = no sharing */ ++ __u8 type; /* instrument type */ ++ ++ fm_xoperator_t op[4]; /* fm operators */ ++ __u8 feedback_connection[2]; ++ ++ __u8 echo_delay; ++ __u8 echo_atten; ++ __u8 chorus_spread; ++ __u8 trnsps; ++ __u8 fix_dur; ++ __u8 modes; ++ __u8 fix_key; ++} fm_xinstrument_t; ++ ++typedef struct gf1_wave { ++ unsigned int share_id[4]; /* share id - zero = no sharing */ ++ unsigned int format; /* wave format */ ++ ++ struct { ++ unsigned int number; /* some other ID for this instrument */ ++ unsigned int memory; /* begin of waveform in onboard memory */ ++ unsigned char *ptr; /* pointer to waveform in system memory */ ++ } address; ++ ++ unsigned int size; /* size of waveform in samples */ ++ unsigned int start; /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned int loop_start; /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned int loop_end; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned short loop_repeat; /* loop repeat - 0 = forever */ ++ ++ unsigned char flags; /* GF1 patch flags */ ++ unsigned char pad; ++ unsigned int sample_rate; /* sample rate in Hz */ ++ unsigned int low_frequency; /* low frequency range */ ++ unsigned int high_frequency; /* high frequency range */ ++ unsigned int root_frequency; /* root frequency range */ ++ signed short tune; ++ unsigned char balance; ++ unsigned char envelope_rate[6]; ++ unsigned char envelope_offset[6]; ++ unsigned char tremolo_sweep; ++ unsigned char tremolo_rate; ++ unsigned char tremolo_depth; ++ unsigned char vibrato_sweep; ++ unsigned char vibrato_rate; ++ unsigned char vibrato_depth; ++ unsigned short scale_frequency; ++ unsigned short scale_factor; /* 0-2048 or 0-2 */ ++ ++ struct gf1_wave *next; ++} gf1_wave_t; ++ ++typedef struct { ++ unsigned short exclusion; ++ unsigned short exclusion_group; /* 0 - none, 1-65535 */ ++ ++ unsigned char effect1; /* effect 1 */ ++ unsigned char effect1_depth; /* 0-127 */ ++ unsigned char effect2; /* effect 2 */ ++ unsigned char effect2_depth; /* 0-127 */ ++ ++ gf1_wave_t *wave; /* first waveform */ ++} gf1_instrument_t; ++ ++typedef struct gf1_xwave { ++ __u32 stype; /* structure type */ ++ ++ __u32 share_id[4]; /* share id - zero = no sharing */ ++ __u32 format; /* wave format */ ++ ++ __u32 size; /* size of waveform in samples */ ++ __u32 start; /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u32 loop_start; /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u32 loop_end; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u16 loop_repeat; /* loop repeat - 0 = forever */ ++ ++ __u8 flags; /* GF1 patch flags */ ++ __u8 pad; ++ __u32 sample_rate; /* sample rate in Hz */ ++ __u32 low_frequency; /* low frequency range */ ++ __u32 high_frequency; /* high frequency range */ ++ __u32 root_frequency; /* root frequency range */ ++ __s16 tune; ++ __u8 balance; ++ __u8 envelope_rate[6]; ++ __u8 envelope_offset[6]; ++ __u8 tremolo_sweep; ++ __u8 tremolo_rate; ++ __u8 tremolo_depth; ++ __u8 vibrato_sweep; ++ __u8 vibrato_rate; ++ __u8 vibrato_depth; ++ __u16 scale_frequency; ++ __u16 scale_factor; /* 0-2048 or 0-2 */ ++} gf1_xwave_t; ++ ++typedef struct gf1_xinstrument { ++ __u32 stype; ++ ++ __u16 exclusion; ++ __u16 exclusion_group; /* 0 - none, 1-65535 */ ++ ++ __u8 effect1; /* effect 1 */ ++ __u8 effect1_depth; /* 0-127 */ ++ __u8 effect2; /* effect 2 */ ++ __u8 effect2_depth; /* 0-127 */ ++} gf1_xinstrument_t; ++ ++typedef struct gf1_info { ++ unsigned char flags; /* supported wave flags */ ++ unsigned char pad[3]; ++ unsigned int features; /* supported features */ ++ unsigned int max8_len; /* maximum 8-bit wave length */ ++ unsigned int max16_len; /* maximum 16-bit wave length */ ++} gf1_info_t; ++ ++typedef struct iwffff_wave { ++ unsigned int share_id[4]; /* share id - zero = no sharing */ ++ unsigned int format; /* wave format */ ++ ++ struct { ++ unsigned int number; /* some other ID for this wave */ ++ unsigned int memory; /* begin of waveform in onboard memory */ ++ unsigned char *ptr; /* pointer to waveform in system memory */ ++ } address; ++ ++ unsigned int size; /* size of waveform in samples */ ++ unsigned int start; /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned int loop_start; /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned int loop_end; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned short loop_repeat; /* loop repeat - 0 = forever */ ++ unsigned int sample_ratio; /* sample ratio (44100 * 1024 / rate) */ ++ unsigned char attenuation; /* 0 - 127 (no corresponding midi controller) */ ++ unsigned char low_note; /* lower frequency range for this waveform */ ++ unsigned char high_note; /* higher frequency range for this waveform */ ++ unsigned char pad; ++ ++ struct iwffff_wave *next; ++} iwffff_wave_t; ++ ++typedef struct iwffff_lfo { ++ unsigned short freq; /* (0-2047) 0.01Hz - 21.5Hz */ ++ signed short depth; /* volume +- (0-255) 0.48675dB/step */ ++ signed short sweep; /* 0 - 950 deciseconds */ ++ unsigned char shape; /* see to IWFFFF_LFO_SHAPE_XXXX */ ++ unsigned char delay; /* 0 - 255 deciseconds */ ++} iwffff_lfo_t; ++ ++typedef struct iwffff_env_point { ++ unsigned short offset; ++ unsigned short rate; ++} iwffff_env_point_t; ++ ++typedef struct iwffff_env_record { ++ unsigned short nattack; ++ unsigned short nrelease; ++ unsigned short sustain_offset; ++ unsigned short sustain_rate; ++ unsigned short release_rate; ++ unsigned char hirange; ++ unsigned char pad; ++ struct iwffff_env_record *next; ++ /* points are stored here */ ++ /* count of points = nattack + nrelease */ ++} iwffff_env_record_t; ++ ++typedef struct iwffff_env { ++ unsigned char flags; ++ unsigned char mode; ++ unsigned char index; ++ unsigned char pad; ++ struct iwffff_env_record *record; ++} iwffff_env_t; ++ ++typedef struct iwffff_layer { ++ unsigned char flags; ++ unsigned char velocity_mode; ++ unsigned char layer_event; ++ unsigned char low_range; /* range for layer based */ ++ unsigned char high_range; /* on either velocity or frequency */ ++ unsigned char pan; /* pan offset from CC1 (0 left - 127 right) */ ++ unsigned char pan_freq_scale; /* position based on frequency (0-127) */ ++ unsigned char attenuation; /* 0-127 (no corresponding midi controller) */ ++ iwffff_lfo_t tremolo; /* tremolo effect */ ++ iwffff_lfo_t vibrato; /* vibrato effect */ ++ unsigned short freq_scale; /* 0-2048, 1024 is equal to semitone scaling */ ++ unsigned char freq_center; /* center for keyboard frequency scaling */ ++ unsigned char pad; ++ iwffff_env_t penv; /* pitch envelope */ ++ iwffff_env_t venv; /* volume envelope */ ++ ++ iwffff_wave_t *wave; ++ struct iwffff_layer *next; ++} iwffff_layer_t; ++ ++typedef struct { ++ unsigned short exclusion; ++ unsigned short layer_type; ++ unsigned short exclusion_group; /* 0 - none, 1-65535 */ ++ ++ unsigned char effect1; /* effect 1 */ ++ unsigned char effect1_depth; /* 0-127 */ ++ unsigned char effect2; /* effect 2 */ ++ unsigned char effect2_depth; /* 0-127 */ ++ ++ iwffff_layer_t *layer; /* first layer */ ++} iwffff_instrument_t; ++ ++typedef struct iwffff_xwave { ++ __u32 stype; /* structure type */ ++ ++ __u32 share_id[4]; /* share id - zero = no sharing */ ++ ++ __u32 format; /* wave format */ ++ __u32 offset; /* offset to ROM (address) */ ++ ++ __u32 size; /* size of waveform in samples */ ++ __u32 start; /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u32 loop_start; /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u32 loop_end; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u16 loop_repeat; /* loop repeat - 0 = forever */ ++ __u32 sample_ratio; /* sample ratio (44100 * 1024 / rate) */ ++ __u8 attenuation; /* 0 - 127 (no corresponding midi controller) */ ++ __u8 low_note; /* lower frequency range for this waveform */ ++ __u8 high_note; /* higher frequency range for this waveform */ ++ __u8 pad; ++} iwffff_xwave_t; ++ ++typedef struct iwffff_xlfo { ++ __u16 freq; /* (0-2047) 0.01Hz - 21.5Hz */ ++ __s16 depth; /* volume +- (0-255) 0.48675dB/step */ ++ __s16 sweep; /* 0 - 950 deciseconds */ ++ __u8 shape; /* see to ULTRA_IW_LFO_SHAPE_XXXX */ ++ __u8 delay; /* 0 - 255 deciseconds */ ++} iwffff_xlfo_t; ++ ++typedef struct iwffff_xenv_point { ++ __u16 offset; ++ __u16 rate; ++} iwffff_xenv_point_t; ++ ++typedef struct iwffff_xenv_record { ++ __u32 stype; ++ __u16 nattack; ++ __u16 nrelease; ++ __u16 sustain_offset; ++ __u16 sustain_rate; ++ __u16 release_rate; ++ __u8 hirange; ++ __u8 pad; ++ /* points are stored here.. */ ++ /* count of points = nattack + nrelease */ ++} iwffff_xenv_record_t; ++ ++typedef struct iwffff_xenv { ++ __u8 flags; ++ __u8 mode; ++ __u8 index; ++ __u8 pad; ++} iwffff_xenv_t; ++ ++typedef struct iwffff_xlayer { ++ __u32 stype; ++ __u8 flags; ++ __u8 velocity_mode; ++ __u8 layer_event; ++ __u8 low_range; /* range for layer based */ ++ __u8 high_range; /* on either velocity or frequency */ ++ __u8 pan; /* pan offset from CC1 (0 left - 127 right) */ ++ __u8 pan_freq_scale; /* position based on frequency (0-127) */ ++ __u8 attenuation; /* 0-127 (no corresponding midi controller) */ ++ iwffff_xlfo_t tremolo; /* tremolo effect */ ++ iwffff_xlfo_t vibrato; /* vibrato effect */ ++ __u16 freq_scale; /* 0-2048, 1024 is equal to semitone scaling */ ++ __u8 freq_center; /* center for keyboard frequency scaling */ ++ __u8 pad; ++ iwffff_xenv_t penv; /* pitch envelope */ ++ iwffff_xenv_t venv; /* volume envelope */ ++} iwffff_xlayer_t; ++ ++typedef struct iwffff_xinstrument { ++ __u32 stype; ++ ++ __u16 exclusion; ++ __u16 layer_type; ++ __u16 exclusion_group; /* 0 - none, 1-65535 */ ++ ++ __u8 effect1; /* effect 1 */ ++ __u8 effect1_depth; /* 0-127 */ ++ __u8 effect2; /* effect 2 */ ++ __u8 effect2_depth; /* 0-127 */ ++} iwffff_xinstrument_t; ++ ++typedef struct { ++ __u8 iwave[8]; ++ __u8 revision; ++ __u8 series_number; ++ __u8 series_name[16]; ++ __u8 date[10]; ++ __u16 vendor_revision_major; ++ __u16 vendor_revision_minor; ++ __u32 rom_size; ++ __u8 copyright[128]; ++ __u8 vendor_name[64]; ++ __u8 description[128]; ++} iwffff_rom_header_t; ++ ++typedef struct iwffff_info { ++ unsigned int format; /* supported format bits */ ++ unsigned int effects; /* supported effects (1 << IWFFFF_EFFECT*) */ ++ unsigned int lfos; /* LFO effects */ ++ unsigned int max8_len; /* maximum 8-bit wave length */ ++ unsigned int max16_len; /* maximum 16-bit wave length */ ++} iwffff_info_t; ++ ++typedef struct simple_instrument_info { ++ unsigned int format; /* supported format bits */ ++ unsigned int effects; /* supported effects (1 << SIMPLE_EFFECT_*) */ ++ unsigned int max8_len; /* maximum 8-bit wave length */ ++ unsigned int max16_len; /* maximum 16-bit wave length */ ++} simple_instrument_info_t; ++ ++typedef struct { ++ unsigned int share_id[4]; /* share id - zero = no sharing */ ++ unsigned int format; /* wave format */ ++ ++ struct { ++ unsigned int number; /* some other ID for this instrument */ ++ unsigned int memory; /* begin of waveform in onboard memory */ ++ unsigned char *ptr; /* pointer to waveform in system memory */ ++ } address; ++ ++ unsigned int size; /* size of waveform in samples */ ++ unsigned int start; /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned int loop_start; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned int loop_end; /* loop end offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned short loop_repeat; /* loop repeat - 0 = forever */ ++ ++ unsigned char effect1; /* effect 1 */ ++ unsigned char effect1_depth; /* 0-127 */ ++ unsigned char effect2; /* effect 2 */ ++ unsigned char effect2_depth; /* 0-127 */ ++} simple_instrument_t; ++ ++typedef struct simple_xinstrument { ++ __u32 stype; ++ ++ __u32 share_id[4]; /* share id - zero = no sharing */ ++ __u32 format; /* wave format */ ++ ++ __u32 size; /* size of waveform in samples */ ++ __u32 start; /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u32 loop_start; /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u32 loop_end; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u16 loop_repeat; /* loop repeat - 0 = forever */ ++ ++ __u8 effect1; /* effect 1 */ ++ __u8 effect1_depth; /* 0-127 */ ++ __u8 effect2; /* effect 2 */ ++ __u8 effect2_depth; /* 0-127 */ ++} simple_xinstrument_t; ++ ++typedef unsigned char sndrv_seq_event_type_t; ++ ++/** event address */ ++struct sndrv_seq_addr { ++ unsigned char client; /**< Client number: 0..255, 255 = broadcast to all clients */ ++ unsigned char port; /**< Port within client: 0..255, 255 = broadcast to all ports */ ++}; ++ ++/** port connection */ ++struct sndrv_seq_connect { ++ struct sndrv_seq_addr sender; ++ struct sndrv_seq_addr dest; ++}; ++ ++struct sndrv_seq_ev_note { ++ unsigned char channel; ++ unsigned char note; ++ unsigned char velocity; ++ unsigned char off_velocity; /* only for SNDRV_SEQ_EVENT_NOTE */ ++ unsigned int duration; /* only for SNDRV_SEQ_EVENT_NOTE */ ++}; ++ ++ /* controller event */ ++struct sndrv_seq_ev_ctrl { ++ unsigned char channel; ++ unsigned char unused1, unused2, unused3; /* pad */ ++ unsigned int param; ++ signed int value; ++}; ++ ++ /* generic set of bytes (12x8 bit) */ ++struct sndrv_seq_ev_raw8 { ++ unsigned char d[12]; /* 8 bit value */ ++}; ++ ++ /* generic set of integers (3x32 bit) */ ++struct sndrv_seq_ev_raw32 { ++ unsigned int d[3]; /* 32 bit value */ ++}; ++ ++ /* external stored data */ ++struct sndrv_seq_ev_ext { ++ unsigned int len; /* length of data */ ++ void *ptr; /* pointer to data (note: maybe 64-bit) */ ++} __attribute__((packed)); ++ ++/* Instrument cluster type */ ++typedef unsigned int sndrv_seq_instr_cluster_t; ++ ++/* Instrument type */ ++struct sndrv_seq_instr { ++ sndrv_seq_instr_cluster_t cluster; ++ unsigned int std; /* the upper byte means a private instrument (owner - client #) */ ++ unsigned short bank; ++ unsigned short prg; ++}; ++ ++ /* sample number */ ++struct sndrv_seq_ev_sample { ++ unsigned int std; ++ unsigned short bank; ++ unsigned short prg; ++}; ++ ++ /* sample cluster */ ++struct sndrv_seq_ev_cluster { ++ sndrv_seq_instr_cluster_t cluster; ++}; ++ ++ /* sample position */ ++typedef unsigned int sndrv_seq_position_t; /* playback position (in samples) * 16 */ ++ ++ /* sample stop mode */ ++enum sndrv_seq_stop_mode { ++ SAMPLE_STOP_IMMEDIATELY = 0, /* terminate playing immediately */ ++ SAMPLE_STOP_VENVELOPE = 1, /* finish volume envelope */ ++ SAMPLE_STOP_LOOP = 2 /* terminate loop and finish wave */ ++}; ++ ++ /* sample frequency */ ++typedef int sndrv_seq_frequency_t; /* playback frequency in HZ * 16 */ ++ ++ /* sample volume control; if any value is set to -1 == do not change */ ++struct sndrv_seq_ev_volume { ++ signed short volume; /* range: 0-16383 */ ++ signed short lr; /* left-right balance; range: 0-16383 */ ++ signed short fr; /* front-rear balance; range: 0-16383 */ ++ signed short du; /* down-up balance; range: 0-16383 */ ++}; ++ ++ /* simple loop redefinition */ ++struct sndrv_seq_ev_loop { ++ unsigned int start; /* loop start (in samples) * 16 */ ++ unsigned int end; /* loop end (in samples) * 16 */ ++}; ++ ++struct sndrv_seq_ev_sample_control { ++ unsigned char channel; ++ unsigned char unused1, unused2, unused3; /* pad */ ++ union { ++ struct sndrv_seq_ev_sample sample; ++ struct sndrv_seq_ev_cluster cluster; ++ sndrv_seq_position_t position; ++ int stop_mode; ++ sndrv_seq_frequency_t frequency; ++ struct sndrv_seq_ev_volume volume; ++ struct sndrv_seq_ev_loop loop; ++ unsigned char raw8[8]; ++ } param; ++}; ++ ++ ++ ++/* INSTR_BEGIN event */ ++struct sndrv_seq_ev_instr_begin { ++ int timeout; /* zero = forever, otherwise timeout in ms */ ++}; ++ ++struct sndrv_seq_result { ++ int event; /* processed event type */ ++ int result; ++}; ++ ++ ++struct sndrv_seq_real_time { ++ unsigned int tv_sec; /* seconds */ ++ unsigned int tv_nsec; /* nanoseconds */ ++}; ++ ++typedef unsigned int sndrv_seq_tick_time_t; /* midi ticks */ ++ ++union sndrv_seq_timestamp { ++ sndrv_seq_tick_time_t tick; ++ struct sndrv_seq_real_time time; ++}; ++ ++struct sndrv_seq_queue_skew { ++ unsigned int value; ++ unsigned int base; ++}; ++ ++ /* queue timer control */ ++struct sndrv_seq_ev_queue_control { ++ unsigned char queue; /* affected queue */ ++ unsigned char pad[3]; /* reserved */ ++ union { ++ signed int value; /* affected value (e.g. tempo) */ ++ union sndrv_seq_timestamp time; /* time */ ++ unsigned int position; /* sync position */ ++ struct sndrv_seq_queue_skew skew; ++ unsigned int d32[2]; ++ unsigned char d8[8]; ++ } param; ++}; ++ ++ /* quoted event - inside the kernel only */ ++struct sndrv_seq_ev_quote { ++ struct sndrv_seq_addr origin; /* original sender */ ++ unsigned short value; /* optional data */ ++ struct sndrv_seq_event *event; /* quoted event */ ++} __attribute__((packed)); ++ ++ ++ /* sequencer event */ ++struct sndrv_seq_event { ++ sndrv_seq_event_type_t type; /* event type */ ++ unsigned char flags; /* event flags */ ++ char tag; ++ ++ unsigned char queue; /* schedule queue */ ++ union sndrv_seq_timestamp time; /* schedule time */ ++ ++ ++ struct sndrv_seq_addr source; /* source address */ ++ struct sndrv_seq_addr dest; /* destination address */ ++ ++ union { /* event data... */ ++ struct sndrv_seq_ev_note note; ++ struct sndrv_seq_ev_ctrl control; ++ struct sndrv_seq_ev_raw8 raw8; ++ struct sndrv_seq_ev_raw32 raw32; ++ struct sndrv_seq_ev_ext ext; ++ struct sndrv_seq_ev_queue_control queue; ++ union sndrv_seq_timestamp time; ++ struct sndrv_seq_addr addr; ++ struct sndrv_seq_connect connect; ++ struct sndrv_seq_result result; ++ struct sndrv_seq_ev_instr_begin instr_begin; ++ struct sndrv_seq_ev_sample_control sample; ++ struct sndrv_seq_ev_quote quote; ++ } data; ++}; ++ ++ ++/* ++ * bounce event - stored as variable size data ++ */ ++struct sndrv_seq_event_bounce { ++ int err; ++ struct sndrv_seq_event event; ++ /* external data follows here. */ ++}; ++ ++struct sndrv_seq_system_info { ++ int queues; /* maximum queues count */ ++ int clients; /* maximum clients count */ ++ int ports; /* maximum ports per client */ ++ int channels; /* maximum channels per port */ ++ int cur_clients; /* current clients */ ++ int cur_queues; /* current queues */ ++ char reserved[24]; ++}; ++ ++struct sndrv_seq_running_info { ++ unsigned char client; /* client id */ ++ unsigned char big_endian; /* 1 = big-endian */ ++ unsigned char cpu_mode; /* 4 = 32bit, 8 = 64bit */ ++ unsigned char pad; /* reserved */ ++ unsigned char reserved[12]; ++}; ++ ++enum sndrv_seq_client_type { ++ NO_CLIENT = 0, ++ USER_CLIENT = 1, ++ KERNEL_CLIENT = 2 ++}; ++ ++struct sndrv_seq_client_info { ++ int client; /* client number to inquire */ ++ int type; /* client type */ ++ char name[64]; /* client name */ ++ unsigned int filter; /* filter flags */ ++ unsigned char multicast_filter[8]; /* multicast filter bitmap */ ++ unsigned char event_filter[32]; /* event filter bitmap */ ++ int num_ports; /* RO: number of ports */ ++ int event_lost; /* number of lost events */ ++ char reserved[64]; /* for future use */ ++}; ++ ++struct sndrv_seq_client_pool { ++ int client; /* client number to inquire */ ++ int output_pool; /* outgoing (write) pool size */ ++ int input_pool; /* incoming (read) pool size */ ++ int output_room; /* minimum free pool size for select/blocking mode */ ++ int output_free; /* unused size */ ++ int input_free; /* unused size */ ++ char reserved[64]; ++}; ++ ++struct sndrv_seq_remove_events { ++ unsigned int remove_mode; /* Flags that determine what gets removed */ ++ ++ union sndrv_seq_timestamp time; ++ ++ unsigned char queue; /* Queue for REMOVE_DEST */ ++ struct sndrv_seq_addr dest; /* Address for REMOVE_DEST */ ++ unsigned char channel; /* Channel for REMOVE_DEST */ ++ ++ int type; /* For REMOVE_EVENT_TYPE */ ++ char tag; /* Tag for REMOVE_TAG */ ++ ++ int reserved[10]; /* To allow for future binary compatibility */ ++ ++}; ++ ++struct sndrv_seq_port_info { ++ struct sndrv_seq_addr addr; /* client/port numbers */ ++ char name[64]; /* port name */ ++ ++ unsigned int capability; /* port capability bits */ ++ unsigned int type; /* port type bits */ ++ int midi_channels; /* channels per MIDI port */ ++ int midi_voices; /* voices per MIDI port */ ++ int synth_voices; /* voices per SYNTH port */ ++ ++ int read_use; /* R/O: subscribers for output (from this port) */ ++ int write_use; /* R/O: subscribers for input (to this port) */ ++ ++ void *kernel; /* reserved for kernel use (must be NULL) */ ++ unsigned int flags; /* misc. conditioning */ ++ unsigned char time_queue; /* queue # for timestamping */ ++ char reserved[59]; /* for future use */ ++}; ++ ++struct sndrv_seq_queue_info { ++ int queue; /* queue id */ ++ ++ /* ++ * security settings, only owner of this queue can start/stop timer ++ * etc. if the queue is locked for other clients ++ */ ++ int owner; /* client id for owner of the queue */ ++ int locked:1; /* timing queue locked for other queues */ ++ char name[64]; /* name of this queue */ ++ unsigned int flags; /* flags */ ++ char reserved[60]; /* for future use */ ++ ++}; ++ ++struct sndrv_seq_queue_status { ++ int queue; /* queue id */ ++ int events; /* read-only - queue size */ ++ sndrv_seq_tick_time_t tick; /* current tick */ ++ struct sndrv_seq_real_time time; /* current time */ ++ int running; /* running state of queue */ ++ int flags; /* various flags */ ++ char reserved[64]; /* for the future */ ++}; ++ ++struct sndrv_seq_queue_tempo { ++ int queue; /* sequencer queue */ ++ unsigned int tempo; /* current tempo, us/tick */ ++ int ppq; /* time resolution, ticks/quarter */ ++ unsigned int skew_value; /* queue skew */ ++ unsigned int skew_base; /* queue skew base */ ++ char reserved[24]; /* for the future */ ++}; ++ ++struct sndrv_timer_id { ++ int dev_class; ++ int dev_sclass; ++ int card; ++ int device; ++ int subdevice; ++}; ++ ++struct sndrv_seq_queue_timer { ++ int queue; /* sequencer queue */ ++ int type; /* source timer type */ ++ union { ++ struct { ++ struct sndrv_timer_id id; /* ALSA's timer ID */ ++ unsigned int resolution; /* resolution in Hz */ ++ } alsa; ++ } u; ++ char reserved[64]; /* for the future use */ ++}; ++ ++struct sndrv_seq_queue_client { ++ int queue; /* sequencer queue */ ++ int client; /* sequencer client */ ++ int used; /* queue is used with this client ++ (must be set for accepting events) */ ++ /* per client watermarks */ ++ char reserved[64]; /* for future use */ ++}; ++ ++struct sndrv_seq_port_subscribe { ++ struct sndrv_seq_addr sender; /* sender address */ ++ struct sndrv_seq_addr dest; /* destination address */ ++ unsigned int voices; /* number of voices to be allocated (0 = don't care) */ ++ unsigned int flags; /* modes */ ++ unsigned char queue; /* input time-stamp queue (optional) */ ++ unsigned char pad[3]; /* reserved */ ++ char reserved[64]; ++}; ++ ++struct sndrv_seq_query_subs { ++ struct sndrv_seq_addr root; /* client/port id to be searched */ ++ int type; /* READ or WRITE */ ++ int index; /* 0..N-1 */ ++ int num_subs; /* R/O: number of subscriptions on this port */ ++ struct sndrv_seq_addr addr; /* R/O: result */ ++ unsigned char queue; /* R/O: result */ ++ unsigned int flags; /* R/O: result */ ++ char reserved[64]; /* for future use */ ++}; ++ ++/* size of ROM/RAM */ ++typedef unsigned int sndrv_seq_instr_size_t; ++ ++struct sndrv_seq_instr_info { ++ int result; /* operation result */ ++ unsigned int formats[8]; /* bitmap of supported formats */ ++ int ram_count; /* count of RAM banks */ ++ sndrv_seq_instr_size_t ram_sizes[16]; /* size of RAM banks */ ++ int rom_count; /* count of ROM banks */ ++ sndrv_seq_instr_size_t rom_sizes[8]; /* size of ROM banks */ ++ char reserved[128]; ++}; ++ ++struct sndrv_seq_instr_status { ++ int result; /* operation result */ ++ sndrv_seq_instr_size_t free_ram[16]; /* free RAM in banks */ ++ int instrument_count; /* count of downloaded instruments */ ++ char reserved[128]; ++}; ++ ++struct sndrv_seq_instr_format_info { ++ char format[16]; /* format identifier - SNDRV_SEQ_INSTR_ID_* */ ++ unsigned int len; /* max data length (without this structure) */ ++}; ++ ++struct sndrv_seq_instr_format_info_result { ++ int result; /* operation result */ ++ char format[16]; /* format identifier */ ++ unsigned int len; /* filled data length (without this structure) */ ++}; ++ ++struct sndrv_seq_instr_data { ++ char name[32]; /* instrument name */ ++ char reserved[16]; /* for the future use */ ++ int type; /* instrument type */ ++ union { ++ char format[16]; /* format identifier */ ++ struct sndrv_seq_instr alias; ++ } data; ++}; ++ ++struct sndrv_seq_instr_header { ++ union { ++ struct sndrv_seq_instr instr; ++ sndrv_seq_instr_cluster_t cluster; ++ } id; /* instrument identifier */ ++ unsigned int cmd; /* get/put/free command */ ++ unsigned int flags; /* query flags (only for get) */ ++ unsigned int len; /* real instrument data length (without header) */ ++ int result; /* operation result */ ++ char reserved[16]; /* for the future */ ++ struct sndrv_seq_instr_data data; /* instrument data (for put/get result) */ ++}; ++ ++struct sndrv_seq_instr_cluster_set { ++ sndrv_seq_instr_cluster_t cluster; /* cluster identifier */ ++ char name[32]; /* cluster name */ ++ int priority; /* cluster priority */ ++ char reserved[64]; /* for the future use */ ++}; ++ ++struct sndrv_seq_instr_cluster_get { ++ sndrv_seq_instr_cluster_t cluster; /* cluster identifier */ ++ char name[32]; /* cluster name */ ++ int priority; /* cluster priority */ ++ char reserved[64]; /* for the future use */ ++}; ++ ++typedef struct snd_dm_fm_info { ++ unsigned char fm_mode; /* OPL mode, see SNDRV_DM_FM_MODE_XXX */ ++ unsigned char rhythm; /* percussion mode flag */ ++} snd_dm_fm_info_t; ++ ++typedef struct snd_dm_fm_voice { ++ unsigned char op; /* operator cell (0 or 1) */ ++ unsigned char voice; /* FM voice (0 to 17) */ ++ ++ unsigned char am; /* amplitude modulation */ ++ unsigned char vibrato; /* vibrato effect */ ++ unsigned char do_sustain; /* sustain phase */ ++ unsigned char kbd_scale; /* keyboard scaling */ ++ unsigned char harmonic; /* 4 bits: harmonic and multiplier */ ++ unsigned char scale_level; /* 2 bits: decrease output freq rises */ ++ unsigned char volume; /* 6 bits: volume */ ++ ++ unsigned char attack; /* 4 bits: attack rate */ ++ unsigned char decay; /* 4 bits: decay rate */ ++ unsigned char sustain; /* 4 bits: sustain level */ ++ unsigned char release; /* 4 bits: release rate */ ++ ++ unsigned char feedback; /* 3 bits: feedback for op0 */ ++ unsigned char connection; /* 0 for serial, 1 for parallel */ ++ unsigned char left; /* stereo left */ ++ unsigned char right; /* stereo right */ ++ unsigned char waveform; /* 3 bits: waveform shape */ ++} snd_dm_fm_voice_t; ++ ++typedef struct snd_dm_fm_note { ++ unsigned char voice; /* 0-17 voice channel */ ++ unsigned char octave; /* 3 bits: what octave to play */ ++ unsigned int fnum; /* 10 bits: frequency number */ ++ unsigned char key_on; /* set for active, clear for silent */ ++} snd_dm_fm_note_t; ++ ++typedef struct snd_dm_fm_params { ++ unsigned char am_depth; /* amplitude modulation depth (1=hi) */ ++ unsigned char vib_depth; /* vibrato depth (1=hi) */ ++ unsigned char kbd_split; /* keyboard split */ ++ unsigned char rhythm; /* percussion mode select */ ++ ++ /* This block is the percussion instrument data */ ++ unsigned char bass; ++ unsigned char snare; ++ unsigned char tomtom; ++ unsigned char cymbal; ++ unsigned char hihat; ++} snd_dm_fm_params_t; ++ ++#include ++#if __BYTE_ORDER == __LITTLE_ENDIAN ++#define SNDRV_LITTLE_ENDIAN ++#elif __BYTE_ORDER == __BIG_ENDIAN ++#define SNDRV_BIG_ENDIAN ++#else ++#error "Unsupported endian..." ++#endif ++ ++#include ++#include ++ ++struct sndrv_aes_iec958 { ++ unsigned char status[24]; /* AES/IEC958 channel status bits */ ++ unsigned char subcode[147]; /* AES/IEC958 subcode bits */ ++ unsigned char pad; /* nothing */ ++ unsigned char dig_subframe[4]; /* AES/IEC958 subframe bits */ ++}; ++ ++enum sndrv_hwdep_iface { ++ SNDRV_HWDEP_IFACE_OPL2 = 0, ++ SNDRV_HWDEP_IFACE_OPL3, ++ SNDRV_HWDEP_IFACE_OPL4, ++ SNDRV_HWDEP_IFACE_SB16CSP, /* Creative Signal Processor */ ++ SNDRV_HWDEP_IFACE_EMU10K1, /* FX8010 processor in EMU10K1 chip */ ++ SNDRV_HWDEP_IFACE_YSS225, /* Yamaha FX processor */ ++ SNDRV_HWDEP_IFACE_ICS2115, /* Wavetable synth */ ++ SNDRV_HWDEP_IFACE_SSCAPE, /* Ensoniq SoundScape ISA card (MC68EC000) */ ++ SNDRV_HWDEP_IFACE_VX, /* Digigram VX cards */ ++ SNDRV_HWDEP_IFACE_MIXART, /* Digigram miXart cards */ ++ SNDRV_HWDEP_IFACE_USX2Y, /* Tascam US122, US224 & US428 usb */ ++ SNDRV_HWDEP_IFACE_EMUX_WAVETABLE, /* EmuX wavetable */ ++ SNDRV_HWDEP_IFACE_BLUETOOTH, /* Bluetooth audio */ ++ SNDRV_HWDEP_IFACE_USX2Y_PCM, /* Tascam US122, US224 & US428 rawusb pcm */ ++ SNDRV_HWDEP_IFACE_PCXHR, /* Digigram PCXHR */ ++ SNDRV_HWDEP_IFACE_SB_RC, /* SB Extigy/Audigy2NX remote control */ ++ ++ /* Don't forget to change the following: */ ++ SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_SB_RC ++}; ++ ++struct sndrv_hwdep_info { ++ unsigned int device; /* WR: device number */ ++ int card; /* R: card number */ ++ unsigned char id[64]; /* ID (user selectable) */ ++ unsigned char name[80]; /* hwdep name */ ++ int iface; /* hwdep interface */ ++ unsigned char reserved[64]; /* reserved for future */ ++}; ++ ++/* generic DSP loader */ ++struct sndrv_hwdep_dsp_status { ++ unsigned int version; /* R: driver-specific version */ ++ unsigned char id[32]; /* R: driver-specific ID string */ ++ unsigned int num_dsps; /* R: number of DSP images to transfer */ ++ unsigned int dsp_loaded; /* R: bit flags indicating the loaded DSPs */ ++ unsigned int chip_ready; /* R: 1 = initialization finished */ ++ unsigned char reserved[16]; /* reserved for future use */ ++}; ++ ++struct sndrv_hwdep_dsp_image { ++ unsigned int index; /* W: DSP index */ ++ unsigned char name[64]; /* W: ID (e.g. file name) */ ++ unsigned char *image; /* W: binary image */ ++ size_t length; /* W: size of image in bytes */ ++ unsigned long driver_data; /* W: driver-specific data */ ++}; ++ ++typedef unsigned long sndrv_pcm_uframes_t; ++typedef long sndrv_pcm_sframes_t; ++ ++enum sndrv_pcm_class { ++ SNDRV_PCM_CLASS_GENERIC = 0, /* standard mono or stereo device */ ++ SNDRV_PCM_CLASS_MULTI, /* multichannel device */ ++ SNDRV_PCM_CLASS_MODEM, /* software modem class */ ++ SNDRV_PCM_CLASS_DIGITIZER, /* digitizer class */ ++ /* Don't forget to change the following: */ ++ SNDRV_PCM_CLASS_LAST = SNDRV_PCM_CLASS_DIGITIZER, ++}; ++ ++enum sndrv_pcm_subclass { ++ SNDRV_PCM_SUBCLASS_GENERIC_MIX = 0, /* mono or stereo subdevices are mixed together */ ++ SNDRV_PCM_SUBCLASS_MULTI_MIX, /* multichannel subdevices are mixed together */ ++ /* Don't forget to change the following: */ ++ SNDRV_PCM_SUBCLASS_LAST = SNDRV_PCM_SUBCLASS_MULTI_MIX, ++}; ++ ++enum sndrv_pcm_stream { ++ SNDRV_PCM_STREAM_PLAYBACK = 0, ++ SNDRV_PCM_STREAM_CAPTURE, ++ SNDRV_PCM_STREAM_LAST = SNDRV_PCM_STREAM_CAPTURE, ++}; ++ ++enum sndrv_pcm_access { ++ SNDRV_PCM_ACCESS_MMAP_INTERLEAVED = 0, /* interleaved mmap */ ++ SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED, /* noninterleaved mmap */ ++ SNDRV_PCM_ACCESS_MMAP_COMPLEX, /* complex mmap */ ++ SNDRV_PCM_ACCESS_RW_INTERLEAVED, /* readi/writei */ ++ SNDRV_PCM_ACCESS_RW_NONINTERLEAVED, /* readn/writen */ ++ SNDRV_PCM_ACCESS_LAST = SNDRV_PCM_ACCESS_RW_NONINTERLEAVED, ++}; ++ ++enum sndrv_pcm_format { ++ SNDRV_PCM_FORMAT_S8 = 0, ++ SNDRV_PCM_FORMAT_U8, ++ SNDRV_PCM_FORMAT_S16_LE, ++ SNDRV_PCM_FORMAT_S16_BE, ++ SNDRV_PCM_FORMAT_U16_LE, ++ SNDRV_PCM_FORMAT_U16_BE, ++ SNDRV_PCM_FORMAT_S24_LE, /* low three bytes */ ++ SNDRV_PCM_FORMAT_S24_BE, /* low three bytes */ ++ SNDRV_PCM_FORMAT_U24_LE, /* low three bytes */ ++ SNDRV_PCM_FORMAT_U24_BE, /* low three bytes */ ++ SNDRV_PCM_FORMAT_S32_LE, ++ SNDRV_PCM_FORMAT_S32_BE, ++ SNDRV_PCM_FORMAT_U32_LE, ++ SNDRV_PCM_FORMAT_U32_BE, ++ SNDRV_PCM_FORMAT_FLOAT_LE, /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */ ++ SNDRV_PCM_FORMAT_FLOAT_BE, /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */ ++ SNDRV_PCM_FORMAT_FLOAT64_LE, /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */ ++ SNDRV_PCM_FORMAT_FLOAT64_BE, /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */ ++ SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE, /* IEC-958 subframe, Little Endian */ ++ SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE, /* IEC-958 subframe, Big Endian */ ++ SNDRV_PCM_FORMAT_MU_LAW, ++ SNDRV_PCM_FORMAT_A_LAW, ++ SNDRV_PCM_FORMAT_IMA_ADPCM, ++ SNDRV_PCM_FORMAT_MPEG, ++ SNDRV_PCM_FORMAT_GSM, ++ SNDRV_PCM_FORMAT_SPECIAL = 31, ++ SNDRV_PCM_FORMAT_S24_3LE = 32, /* in three bytes */ ++ SNDRV_PCM_FORMAT_S24_3BE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_U24_3LE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_U24_3BE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_S20_3LE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_S20_3BE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_U20_3LE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_U20_3BE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_S18_3LE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_S18_3BE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_U18_3LE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_U18_3BE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_LAST = SNDRV_PCM_FORMAT_U18_3BE, ++ ++#ifdef SNDRV_LITTLE_ENDIAN ++ SNDRV_PCM_FORMAT_S16 = SNDRV_PCM_FORMAT_S16_LE, ++ SNDRV_PCM_FORMAT_U16 = SNDRV_PCM_FORMAT_U16_LE, ++ SNDRV_PCM_FORMAT_S24 = SNDRV_PCM_FORMAT_S24_LE, ++ SNDRV_PCM_FORMAT_U24 = SNDRV_PCM_FORMAT_U24_LE, ++ SNDRV_PCM_FORMAT_S32 = SNDRV_PCM_FORMAT_S32_LE, ++ SNDRV_PCM_FORMAT_U32 = SNDRV_PCM_FORMAT_U32_LE, ++ SNDRV_PCM_FORMAT_FLOAT = SNDRV_PCM_FORMAT_FLOAT_LE, ++ SNDRV_PCM_FORMAT_FLOAT64 = SNDRV_PCM_FORMAT_FLOAT64_LE, ++ SNDRV_PCM_FORMAT_IEC958_SUBFRAME = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE, ++#endif ++#ifdef SNDRV_BIG_ENDIAN ++ SNDRV_PCM_FORMAT_S16 = SNDRV_PCM_FORMAT_S16_BE, ++ SNDRV_PCM_FORMAT_U16 = SNDRV_PCM_FORMAT_U16_BE, ++ SNDRV_PCM_FORMAT_S24 = SNDRV_PCM_FORMAT_S24_BE, ++ SNDRV_PCM_FORMAT_U24 = SNDRV_PCM_FORMAT_U24_BE, ++ SNDRV_PCM_FORMAT_S32 = SNDRV_PCM_FORMAT_S32_BE, ++ SNDRV_PCM_FORMAT_U32 = SNDRV_PCM_FORMAT_U32_BE, ++ SNDRV_PCM_FORMAT_FLOAT = SNDRV_PCM_FORMAT_FLOAT_BE, ++ SNDRV_PCM_FORMAT_FLOAT64 = SNDRV_PCM_FORMAT_FLOAT64_BE, ++ SNDRV_PCM_FORMAT_IEC958_SUBFRAME = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE, ++#endif ++}; ++ ++enum sndrv_pcm_subformat { ++ SNDRV_PCM_SUBFORMAT_STD = 0, ++ SNDRV_PCM_SUBFORMAT_LAST = SNDRV_PCM_SUBFORMAT_STD, ++}; ++ ++enum sndrv_pcm_state { ++ SNDRV_PCM_STATE_OPEN = 0, /* stream is open */ ++ SNDRV_PCM_STATE_SETUP, /* stream has a setup */ ++ SNDRV_PCM_STATE_PREPARED, /* stream is ready to start */ ++ SNDRV_PCM_STATE_RUNNING, /* stream is running */ ++ SNDRV_PCM_STATE_XRUN, /* stream reached an xrun */ ++ SNDRV_PCM_STATE_DRAINING, /* stream is draining */ ++ SNDRV_PCM_STATE_PAUSED, /* stream is paused */ ++ SNDRV_PCM_STATE_SUSPENDED, /* hardware is suspended */ ++ SNDRV_PCM_STATE_DISCONNECTED, /* hardware is disconnected */ ++ SNDRV_PCM_STATE_LAST = SNDRV_PCM_STATE_DISCONNECTED, ++}; ++ ++enum { ++ SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000, ++ SNDRV_PCM_MMAP_OFFSET_STATUS = 0x80000000, ++ SNDRV_PCM_MMAP_OFFSET_CONTROL = 0x81000000, ++}; ++ ++union sndrv_pcm_sync_id { ++ unsigned char id[16]; ++ unsigned short id16[8]; ++ unsigned int id32[4]; ++}; ++ ++struct sndrv_pcm_info { ++ unsigned int device; /* RO/WR (control): device number */ ++ unsigned int subdevice; /* RO/WR (control): subdevice number */ ++ int stream; /* RO/WR (control): stream number */ ++ int card; /* R: card number */ ++ unsigned char id[64]; /* ID (user selectable) */ ++ unsigned char name[80]; /* name of this device */ ++ unsigned char subname[32]; /* subdevice name */ ++ int dev_class; /* SNDRV_PCM_CLASS_* */ ++ int dev_subclass; /* SNDRV_PCM_SUBCLASS_* */ ++ unsigned int subdevices_count; ++ unsigned int subdevices_avail; ++ union sndrv_pcm_sync_id sync; /* hardware synchronization ID */ ++ unsigned char reserved[64]; /* reserved for future... */ ++}; ++ ++enum sndrv_pcm_hw_param { ++ SNDRV_PCM_HW_PARAM_ACCESS = 0, /* Access type */ ++ SNDRV_PCM_HW_PARAM_FIRST_MASK = SNDRV_PCM_HW_PARAM_ACCESS, ++ SNDRV_PCM_HW_PARAM_FORMAT, /* Format */ ++ SNDRV_PCM_HW_PARAM_SUBFORMAT, /* Subformat */ ++ SNDRV_PCM_HW_PARAM_LAST_MASK = SNDRV_PCM_HW_PARAM_SUBFORMAT, ++ ++ SNDRV_PCM_HW_PARAM_SAMPLE_BITS = 8, /* Bits per sample */ ++ SNDRV_PCM_HW_PARAM_FIRST_INTERVAL = SNDRV_PCM_HW_PARAM_SAMPLE_BITS, ++ SNDRV_PCM_HW_PARAM_FRAME_BITS, /* Bits per frame */ ++ SNDRV_PCM_HW_PARAM_CHANNELS, /* Channels */ ++ SNDRV_PCM_HW_PARAM_RATE, /* Approx rate */ ++ SNDRV_PCM_HW_PARAM_PERIOD_TIME, /* Approx distance between interrupts ++ in us */ ++ SNDRV_PCM_HW_PARAM_PERIOD_SIZE, /* Approx frames between interrupts */ ++ SNDRV_PCM_HW_PARAM_PERIOD_BYTES, /* Approx bytes between interrupts */ ++ SNDRV_PCM_HW_PARAM_PERIODS, /* Approx interrupts per buffer */ ++ SNDRV_PCM_HW_PARAM_BUFFER_TIME, /* Approx duration of buffer in us */ ++ SNDRV_PCM_HW_PARAM_BUFFER_SIZE, /* Size of buffer in frames */ ++ SNDRV_PCM_HW_PARAM_BUFFER_BYTES, /* Size of buffer in bytes */ ++ SNDRV_PCM_HW_PARAM_TICK_TIME, /* Approx tick duration in us */ ++ SNDRV_PCM_HW_PARAM_LAST_INTERVAL = SNDRV_PCM_HW_PARAM_TICK_TIME ++}; ++ ++struct sndrv_interval { ++ unsigned int min, max; ++ unsigned int openmin:1, ++ openmax:1, ++ integer:1, ++ empty:1; ++}; ++ ++struct sndrv_mask { ++ u_int32_t bits[(SNDRV_MASK_MAX+31)/32]; ++}; ++ ++struct sndrv_pcm_hw_params { ++ unsigned int flags; ++ struct sndrv_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - ++ SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; ++ struct sndrv_mask mres[5]; /* reserved masks */ ++ struct sndrv_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - ++ SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1]; ++ struct sndrv_interval ires[9]; /* reserved intervals */ ++ unsigned int rmask; /* W: requested masks */ ++ unsigned int cmask; /* R: changed masks */ ++ unsigned int info; /* R: Info flags for returned setup */ ++ unsigned int msbits; /* R: used most significant bits */ ++ unsigned int rate_num; /* R: rate numerator */ ++ unsigned int rate_den; /* R: rate denominator */ ++ sndrv_pcm_uframes_t fifo_size; /* R: chip FIFO size in frames */ ++ unsigned char reserved[64]; /* reserved for future */ ++}; ++ ++enum sndrv_pcm_tstamp { ++ SNDRV_PCM_TSTAMP_NONE = 0, ++ SNDRV_PCM_TSTAMP_MMAP, ++ SNDRV_PCM_TSTAMP_LAST = SNDRV_PCM_TSTAMP_MMAP, ++}; ++ ++struct sndrv_pcm_sw_params { ++ int tstamp_mode; /* timestamp mode */ ++ unsigned int period_step; ++ unsigned int sleep_min; /* min ticks to sleep */ ++ sndrv_pcm_uframes_t avail_min; /* min avail frames for wakeup */ ++ sndrv_pcm_uframes_t xfer_align; /* xfer size need to be a multiple */ ++ sndrv_pcm_uframes_t start_threshold; /* min hw_avail frames for automatic start */ ++ sndrv_pcm_uframes_t stop_threshold; /* min avail frames for automatic stop */ ++ sndrv_pcm_uframes_t silence_threshold; /* min distance from noise for silence filling */ ++ sndrv_pcm_uframes_t silence_size; /* silence block size */ ++ sndrv_pcm_uframes_t boundary; /* pointers wrap point */ ++ unsigned char reserved[64]; /* reserved for future */ ++}; ++ ++struct sndrv_pcm_channel_info { ++ unsigned int channel; ++ long int offset; /* mmap offset */ ++ unsigned int first; /* offset to first sample in bits */ ++ unsigned int step; /* samples distance in bits */ ++}; ++ ++struct sndrv_pcm_status { ++ int state; /* stream state */ ++ struct timespec trigger_tstamp; /* time when stream was started/stopped/paused */ ++ struct timespec tstamp; /* reference timestamp */ ++ sndrv_pcm_uframes_t appl_ptr; /* appl ptr */ ++ sndrv_pcm_uframes_t hw_ptr; /* hw ptr */ ++ sndrv_pcm_sframes_t delay; /* current delay in frames */ ++ sndrv_pcm_uframes_t avail; /* number of frames available */ ++ sndrv_pcm_uframes_t avail_max; /* max frames available on hw since last status */ ++ sndrv_pcm_uframes_t overrange; /* count of ADC (capture) overrange detections from last status */ ++ int suspended_state; /* suspended stream state */ ++ unsigned char reserved[60]; /* must be filled with zero */ ++}; ++ ++struct sndrv_pcm_mmap_status { ++ int state; /* RO: state - SNDRV_PCM_STATE_XXXX */ ++ int pad1; /* Needed for 64 bit alignment */ ++ sndrv_pcm_uframes_t hw_ptr; /* RO: hw ptr (0...boundary-1) */ ++ struct timespec tstamp; /* Timestamp */ ++ int suspended_state; /* RO: suspended stream state */ ++}; ++ ++struct sndrv_pcm_mmap_control { ++ sndrv_pcm_uframes_t appl_ptr; /* RW: appl ptr (0...boundary-1) */ ++ sndrv_pcm_uframes_t avail_min; /* RW: min available frames for wakeup */ ++}; ++ ++struct sndrv_pcm_sync_ptr { ++ unsigned int flags; ++ union { ++ struct sndrv_pcm_mmap_status status; ++ unsigned char reserved[64]; ++ } s; ++ union { ++ struct sndrv_pcm_mmap_control control; ++ unsigned char reserved[64]; ++ } c; ++}; ++ ++struct sndrv_xferi { ++ sndrv_pcm_sframes_t result; ++ void *buf; ++ sndrv_pcm_uframes_t frames; ++}; ++ ++struct sndrv_xfern { ++ sndrv_pcm_sframes_t result; ++ void **bufs; ++ sndrv_pcm_uframes_t frames; ++}; ++ ++enum sndrv_rawmidi_stream { ++ SNDRV_RAWMIDI_STREAM_OUTPUT = 0, ++ SNDRV_RAWMIDI_STREAM_INPUT, ++ SNDRV_RAWMIDI_STREAM_LAST = SNDRV_RAWMIDI_STREAM_INPUT, ++}; ++ ++struct sndrv_rawmidi_info { ++ unsigned int device; /* RO/WR (control): device number */ ++ unsigned int subdevice; /* RO/WR (control): subdevice number */ ++ int stream; /* WR: stream */ ++ int card; /* R: card number */ ++ unsigned int flags; /* SNDRV_RAWMIDI_INFO_XXXX */ ++ unsigned char id[64]; /* ID (user selectable) */ ++ unsigned char name[80]; /* name of device */ ++ unsigned char subname[32]; /* name of active or selected subdevice */ ++ unsigned int subdevices_count; ++ unsigned int subdevices_avail; ++ unsigned char reserved[64]; /* reserved for future use */ ++}; ++ ++struct sndrv_rawmidi_params { ++ int stream; ++ size_t buffer_size; /* queue size in bytes */ ++ size_t avail_min; /* minimum avail bytes for wakeup */ ++ unsigned int no_active_sensing: 1; /* do not send active sensing byte in close() */ ++ unsigned char reserved[16]; /* reserved for future use */ ++}; ++ ++struct sndrv_rawmidi_status { ++ int stream; ++ struct timespec tstamp; /* Timestamp */ ++ size_t avail; /* available bytes */ ++ size_t xruns; /* count of overruns since last status (in bytes) */ ++ unsigned char reserved[16]; /* reserved for future use */ ++}; ++ ++enum sndrv_timer_class { ++ SNDRV_TIMER_CLASS_NONE = -1, ++ SNDRV_TIMER_CLASS_SLAVE = 0, ++ SNDRV_TIMER_CLASS_GLOBAL, ++ SNDRV_TIMER_CLASS_CARD, ++ SNDRV_TIMER_CLASS_PCM, ++ SNDRV_TIMER_CLASS_LAST = SNDRV_TIMER_CLASS_PCM, ++}; ++ ++/* slave timer classes */ ++enum sndrv_timer_slave_class { ++ SNDRV_TIMER_SCLASS_NONE = 0, ++ SNDRV_TIMER_SCLASS_APPLICATION, ++ SNDRV_TIMER_SCLASS_SEQUENCER, /* alias */ ++ SNDRV_TIMER_SCLASS_OSS_SEQUENCER, /* alias */ ++ SNDRV_TIMER_SCLASS_LAST = SNDRV_TIMER_SCLASS_OSS_SEQUENCER, ++}; ++ ++struct sndrv_timer_ginfo { ++ struct sndrv_timer_id tid; /* requested timer ID */ ++ unsigned int flags; /* timer flags - SNDRV_TIMER_FLG_* */ ++ int card; /* card number */ ++ unsigned char id[64]; /* timer identification */ ++ unsigned char name[80]; /* timer name */ ++ unsigned long reserved0; /* reserved for future use */ ++ unsigned long resolution; /* average period resolution in ns */ ++ unsigned long resolution_min; /* minimal period resolution in ns */ ++ unsigned long resolution_max; /* maximal period resolution in ns */ ++ unsigned int clients; /* active timer clients */ ++ unsigned char reserved[32]; ++}; ++ ++struct sndrv_timer_gparams { ++ struct sndrv_timer_id tid; /* requested timer ID */ ++ unsigned long period_num; /* requested precise period duration (in seconds) - numerator */ ++ unsigned long period_den; /* requested precise period duration (in seconds) - denominator */ ++ unsigned char reserved[32]; ++}; ++ ++struct sndrv_timer_gstatus { ++ struct sndrv_timer_id tid; /* requested timer ID */ ++ unsigned long resolution; /* current period resolution in ns */ ++ unsigned long resolution_num; /* precise current period resolution (in seconds) - numerator */ ++ unsigned long resolution_den; /* precise current period resolution (in seconds) - denominator */ ++ unsigned char reserved[32]; ++}; ++ ++struct sndrv_timer_select { ++ struct sndrv_timer_id id; /* bind to timer ID */ ++ unsigned char reserved[32]; /* reserved */ ++}; ++ ++struct sndrv_timer_info { ++ unsigned int flags; /* timer flags - SNDRV_TIMER_FLG_* */ ++ int card; /* card number */ ++ unsigned char id[64]; /* timer identificator */ ++ unsigned char name[80]; /* timer name */ ++ unsigned long reserved0; /* reserved for future use */ ++ unsigned long resolution; /* average period resolution in ns */ ++ unsigned char reserved[64]; /* reserved */ ++}; ++ ++struct sndrv_timer_params { ++ unsigned int flags; /* flags - SNDRV_MIXER_PSFLG_* */ ++ unsigned int ticks; /* requested resolution in ticks */ ++ unsigned int queue_size; /* total size of queue (32-1024) */ ++ unsigned int reserved0; /* reserved, was: failure locations */ ++ unsigned int filter; /* event filter (bitmask of SNDRV_TIMER_EVENT_*) */ ++ unsigned char reserved[60]; /* reserved */ ++}; ++ ++struct sndrv_timer_status { ++ struct timespec tstamp; /* Timestamp - last update */ ++ unsigned int resolution; /* current period resolution in ns */ ++ unsigned int lost; /* counter of master tick lost */ ++ unsigned int overrun; /* count of read queue overruns */ ++ unsigned int queue; /* used queue size */ ++ unsigned char reserved[64]; /* reserved */ ++}; ++ ++struct sndrv_timer_read { ++ unsigned int resolution; ++ unsigned int ticks; ++}; ++ ++enum sndrv_timer_event { ++ SNDRV_TIMER_EVENT_RESOLUTION = 0, /* val = resolution in ns */ ++ SNDRV_TIMER_EVENT_TICK, /* val = ticks */ ++ SNDRV_TIMER_EVENT_START, /* val = resolution in ns */ ++ SNDRV_TIMER_EVENT_STOP, /* val = 0 */ ++ SNDRV_TIMER_EVENT_CONTINUE, /* val = resolution in ns */ ++ SNDRV_TIMER_EVENT_PAUSE, /* val = 0 */ ++ SNDRV_TIMER_EVENT_EARLY, /* val = 0, early event */ ++ SNDRV_TIMER_EVENT_SUSPEND, /* val = 0 */ ++ SNDRV_TIMER_EVENT_RESUME, /* val = resolution in ns */ ++ /* master timer events for slave timer instances */ ++ SNDRV_TIMER_EVENT_MSTART = SNDRV_TIMER_EVENT_START + 10, ++ SNDRV_TIMER_EVENT_MSTOP = SNDRV_TIMER_EVENT_STOP + 10, ++ SNDRV_TIMER_EVENT_MCONTINUE = SNDRV_TIMER_EVENT_CONTINUE + 10, ++ SNDRV_TIMER_EVENT_MPAUSE = SNDRV_TIMER_EVENT_PAUSE + 10, ++ SNDRV_TIMER_EVENT_MSUSPEND = SNDRV_TIMER_EVENT_SUSPEND + 10, ++ SNDRV_TIMER_EVENT_MRESUME = SNDRV_TIMER_EVENT_RESUME + 10, ++}; ++ ++struct sndrv_timer_tread { ++ int event; ++ struct timespec tstamp; ++ unsigned int val; ++}; ++ ++struct sndrv_ctl_card_info { ++ int card; /* card number */ ++ int pad; /* reserved for future (was type) */ ++ unsigned char id[16]; /* ID of card (user selectable) */ ++ unsigned char driver[16]; /* Driver name */ ++ unsigned char name[32]; /* Short name of soundcard */ ++ unsigned char longname[80]; /* name + info text about soundcard */ ++ unsigned char reserved_[16]; /* reserved for future (was ID of mixer) */ ++ unsigned char mixername[80]; /* visual mixer identification */ ++ unsigned char components[80]; /* card components / fine identification, delimited with one space (AC97 etc..) */ ++ unsigned char reserved[48]; /* reserved for future */ ++}; ++ ++enum sndrv_ctl_elem_type { ++ SNDRV_CTL_ELEM_TYPE_NONE = 0, /* invalid */ ++ SNDRV_CTL_ELEM_TYPE_BOOLEAN, /* boolean type */ ++ SNDRV_CTL_ELEM_TYPE_INTEGER, /* integer type */ ++ SNDRV_CTL_ELEM_TYPE_ENUMERATED, /* enumerated type */ ++ SNDRV_CTL_ELEM_TYPE_BYTES, /* byte array */ ++ SNDRV_CTL_ELEM_TYPE_IEC958, /* IEC958 (S/PDIF) setup */ ++ SNDRV_CTL_ELEM_TYPE_INTEGER64, /* 64-bit integer type */ ++ SNDRV_CTL_ELEM_TYPE_LAST = SNDRV_CTL_ELEM_TYPE_INTEGER64, ++}; ++ ++enum sndrv_ctl_elem_iface { ++ SNDRV_CTL_ELEM_IFACE_CARD = 0, /* global control */ ++ SNDRV_CTL_ELEM_IFACE_HWDEP, /* hardware dependent device */ ++ SNDRV_CTL_ELEM_IFACE_MIXER, /* virtual mixer device */ ++ SNDRV_CTL_ELEM_IFACE_PCM, /* PCM device */ ++ SNDRV_CTL_ELEM_IFACE_RAWMIDI, /* RawMidi device */ ++ SNDRV_CTL_ELEM_IFACE_TIMER, /* timer device */ ++ SNDRV_CTL_ELEM_IFACE_SEQUENCER, /* sequencer client */ ++ SNDRV_CTL_ELEM_IFACE_LAST = SNDRV_CTL_ELEM_IFACE_SEQUENCER, ++}; ++ ++struct sndrv_ctl_elem_id { ++ unsigned int numid; /* numeric identifier, zero = invalid */ ++ int iface; /* interface identifier */ ++ unsigned int device; /* device/client number */ ++ unsigned int subdevice; /* subdevice (substream) number */ ++ unsigned char name[44]; /* ASCII name of item */ ++ unsigned int index; /* index of item */ ++}; ++ ++struct sndrv_ctl_elem_list { ++ unsigned int offset; /* W: first element ID to get */ ++ unsigned int space; /* W: count of element IDs to get */ ++ unsigned int used; /* R: count of element IDs set */ ++ unsigned int count; /* R: count of all elements */ ++ struct sndrv_ctl_elem_id *pids; /* R: IDs */ ++ unsigned char reserved[50]; ++}; ++ ++struct sndrv_ctl_elem_info { ++ struct sndrv_ctl_elem_id id; /* W: element ID */ ++ int type; /* R: value type - SNDRV_CTL_ELEM_TYPE_* */ ++ unsigned int access; /* R: value access (bitmask) - SNDRV_CTL_ELEM_ACCESS_* */ ++ unsigned int count; /* count of values */ ++ pid_t owner; /* owner's PID of this control */ ++ union { ++ struct { ++ long min; /* R: minimum value */ ++ long max; /* R: maximum value */ ++ long step; /* R: step (0 variable) */ ++ } integer; ++ struct { ++ long long min; /* R: minimum value */ ++ long long max; /* R: maximum value */ ++ long long step; /* R: step (0 variable) */ ++ } integer64; ++ struct { ++ unsigned int items; /* R: number of items */ ++ unsigned int item; /* W: item number */ ++ char name[64]; /* R: value name */ ++ } enumerated; ++ unsigned char reserved[128]; ++ } value; ++ union { ++ unsigned short d[4]; /* dimensions */ ++ unsigned short *d_ptr; /* indirect */ ++ } dimen; ++ unsigned char reserved[64-4*sizeof(unsigned short)]; ++}; ++ ++struct sndrv_ctl_elem_value { ++ struct sndrv_ctl_elem_id id; /* W: element ID */ ++ unsigned int indirect: 1; /* W: use indirect pointer (xxx_ptr member) */ ++ union { ++ union { ++ long value[128]; ++ long *value_ptr; ++ } integer; ++ union { ++ long long value[64]; ++ long long *value_ptr; ++ } integer64; ++ union { ++ unsigned int item[128]; ++ unsigned int *item_ptr; ++ } enumerated; ++ union { ++ unsigned char data[512]; ++ unsigned char *data_ptr; ++ } bytes; ++ struct sndrv_aes_iec958 iec958; ++ } value; /* RO */ ++ struct timespec tstamp; ++ unsigned char reserved[128-sizeof(struct timespec)]; ++}; ++ ++struct sndrv_ctl_tlv { ++ unsigned int numid; /* control element numeric identification */ ++ unsigned int length; /* in bytes aligned to 4 */ ++ unsigned int tlv[0]; /* first TLV */ ++}; ++ ++enum sndrv_ctl_event_type { ++ SNDRV_CTL_EVENT_ELEM = 0, ++ SNDRV_CTL_EVENT_LAST = SNDRV_CTL_EVENT_ELEM, ++}; ++ ++struct sndrv_ctl_event { ++ int type; /* event type - SNDRV_CTL_EVENT_* */ ++ union { ++ struct { ++ unsigned int mask; ++ struct sndrv_ctl_elem_id id; ++ } elem; ++ unsigned char data8[60]; ++ } data; ++}; ++ ++struct sndrv_xferv { ++ const struct iovec *vector; ++ unsigned long count; ++}; ++ ++typedef struct { ++ unsigned int internal_tram_size; /* in samples */ ++ unsigned int external_tram_size; /* in samples */ ++ char fxbus_names[16][32]; /* names of FXBUSes */ ++ char extin_names[16][32]; /* names of external inputs */ ++ char extout_names[32][32]; /* names of external outputs */ ++ unsigned int gpr_controls; /* count of GPR controls */ ++} emu10k1_fx8010_info_t; ++ ++enum emu10k1_ctl_elem_iface { ++ EMU10K1_CTL_ELEM_IFACE_MIXER = 2, /* virtual mixer device */ ++ EMU10K1_CTL_ELEM_IFACE_PCM = 3, /* PCM device */ ++}; ++ ++typedef struct { ++ unsigned int pad; /* don't use */ ++ int iface; /* interface identifier */ ++ unsigned int device; /* device/client number */ ++ unsigned int subdevice; /* subdevice (substream) number */ ++ unsigned char name[44]; /* ASCII name of item */ ++ unsigned int index; /* index of item */ ++} emu10k1_ctl_elem_id_t; ++ ++typedef struct { ++ emu10k1_ctl_elem_id_t id; /* full control ID definition */ ++ unsigned int vcount; /* visible count */ ++ unsigned int count; /* count of GPR (1..16) */ ++ unsigned short gpr[32]; /* GPR number(s) */ ++ unsigned int value[32]; /* initial values */ ++ unsigned int min; /* minimum range */ ++ unsigned int max; /* maximum range */ ++ unsigned int translation; /* translation type (EMU10K1_GPR_TRANSLATION*) */ ++ unsigned int *tlv; ++} emu10k1_fx8010_control_gpr_t; ++ ++typedef struct { ++ char name[128]; ++ ++ unsigned long gpr_valid[0x200/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */ ++ uint32_t *gpr_map; /* initializers */ ++ ++ unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */ ++ emu10k1_fx8010_control_gpr_t *gpr_add_controls; /* GPR controls to add/replace */ ++ ++ unsigned int gpr_del_control_count; /* count of GPR controls to remove */ ++ emu10k1_ctl_elem_id_t *gpr_del_controls; /* IDs of GPR controls to remove */ ++ ++ unsigned int gpr_list_control_count; /* count of GPR controls to list */ ++ unsigned int gpr_list_control_total; /* total count of GPR controls */ ++ emu10k1_fx8010_control_gpr_t *gpr_list_controls; /* listed GPR controls */ ++ ++ unsigned long tram_valid[0x100/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */ ++ uint32_t *tram_data_map; /* data initializers */ ++ uint32_t *tram_addr_map; /* map initializers */ ++ ++ unsigned long code_valid[1024/(sizeof(unsigned long)*8)]; /* bitmask of valid instructions */ ++ uint32_t *code; /* one instruction - 64 bits */ ++} emu10k1_fx8010_code_t; ++ ++typedef struct { ++ unsigned int address; /* 31.bit == 1 -> external TRAM */ ++ unsigned int size; /* size in samples (4 bytes) */ ++ unsigned int *samples; /* pointer to samples (20-bit) */ ++ /* NULL->clear memory */ ++} emu10k1_fx8010_tram_t; ++ ++typedef struct { ++ unsigned int substream; /* substream number */ ++ unsigned int res1; /* reserved */ ++ unsigned int channels; /* 16-bit channels count, zero = remove this substream */ ++ unsigned int tram_start; /* ring buffer position in TRAM (in samples) */ ++ unsigned int buffer_size; /* count of buffered samples */ ++ unsigned short gpr_size; /* GPR containing size of ringbuffer in samples (host) */ ++ unsigned short gpr_ptr; /* GPR containing current pointer in the ring buffer (host = reset, FX8010) */ ++ unsigned short gpr_count; /* GPR containing count of samples between two interrupts (host) */ ++ unsigned short gpr_tmpcount; /* GPR containing current count of samples to interrupt (host = set, FX8010) */ ++ unsigned short gpr_trigger; /* GPR containing trigger (activate) information (host) */ ++ unsigned short gpr_running; /* GPR containing info if PCM is running (FX8010) */ ++ unsigned char pad; /* reserved */ ++ unsigned char etram[32]; /* external TRAM address & data (one per channel) */ ++ unsigned int res2; /* reserved */ ++} emu10k1_fx8010_pcm_t; ++ ++typedef enum { ++ Digiface, ++ Multiface, ++ H9652, ++ H9632, ++ Undefined, ++} HDSP_IO_Type; ++ ++typedef struct _snd_hdsp_peak_rms hdsp_peak_rms_t; ++ ++struct _snd_hdsp_peak_rms { ++ uint32_t input_peaks[26]; ++ uint32_t playback_peaks[26]; ++ uint32_t output_peaks[28]; ++ uint64_t input_rms[26]; ++ uint64_t playback_rms[26]; ++ /* These are only used for H96xx cards */ ++ uint64_t output_rms[26]; ++}; ++ ++typedef struct _snd_hdsp_config_info hdsp_config_info_t; ++ ++struct _snd_hdsp_config_info { ++ unsigned char pref_sync_ref; ++ unsigned char wordclock_sync_check; ++ unsigned char spdif_sync_check; ++ unsigned char adatsync_sync_check; ++ unsigned char adat_sync_check[3]; ++ unsigned char spdif_in; ++ unsigned char spdif_out; ++ unsigned char spdif_professional; ++ unsigned char spdif_emphasis; ++ unsigned char spdif_nonaudio; ++ unsigned int spdif_sample_rate; ++ unsigned int system_sample_rate; ++ unsigned int autosync_sample_rate; ++ unsigned char system_clock_mode; ++ unsigned char clock_source; ++ unsigned char autosync_ref; ++ unsigned char line_out; ++ unsigned char passthru; ++ unsigned char da_gain; ++ unsigned char ad_gain; ++ unsigned char phone_gain; ++ unsigned char xlr_breakout_cable; ++ unsigned char analog_extension_board; ++}; ++ ++typedef struct _snd_hdsp_firmware hdsp_firmware_t; ++ ++struct _snd_hdsp_firmware { ++ void *firmware_data; /* 24413 x 4 bytes */ ++}; ++ ++typedef struct _snd_hdsp_version hdsp_version_t; ++ ++struct _snd_hdsp_version { ++ HDSP_IO_Type io_type; ++ unsigned short firmware_rev; ++}; ++ ++typedef struct _snd_hdsp_mixer hdsp_mixer_t; ++ ++struct _snd_hdsp_mixer { ++ unsigned short matrix[HDSP_MATRIX_MIXER_SIZE]; ++}; ++ ++typedef struct _snd_hdsp_9632_aeb hdsp_9632_aeb_t; ++ ++struct _snd_hdsp_9632_aeb { ++ int aebi; ++ int aebo; ++}; ++ ++typedef struct snd_sb_csp_mc_header { ++ char codec_name[16]; /* id name of codec */ ++ unsigned short func_req; /* requested function */ ++} snd_sb_csp_mc_header_t; ++ ++typedef struct snd_sb_csp_microcode { ++ snd_sb_csp_mc_header_t info; ++ unsigned char data[SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE]; ++} snd_sb_csp_microcode_t; ++ ++typedef struct snd_sb_csp_start { ++ int sample_width; /* sample width, look above */ ++ int channels; /* channels, look above */ ++} snd_sb_csp_start_t; ++ ++typedef struct snd_sb_csp_info { ++ char codec_name[16]; /* id name of codec */ ++ unsigned short func_nr; /* function number */ ++ unsigned int acc_format; /* accepted PCM formats */ ++ unsigned short acc_channels; /* accepted channels */ ++ unsigned short acc_width; /* accepted sample width */ ++ unsigned short acc_rates; /* accepted sample rates */ ++ unsigned short csp_mode; /* CSP mode, see above */ ++ unsigned short run_channels; /* current channels */ ++ unsigned short run_width; /* current sample width */ ++ unsigned short version; /* version id: 0x10 - 0x1f */ ++ unsigned short state; /* state bits */ ++} snd_sb_csp_info_t; ++ ++struct sscape_bootblock ++{ ++ unsigned char code[256]; ++ unsigned version; ++}; ++ ++struct sscape_microcode ++{ ++ unsigned char *code; ++}; +diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h +index d02a9bf..be612ce 100644 +--- a/linux-user/syscall_defs.h ++++ b/linux-user/syscall_defs.h +@@ -2205,3 +2205,4 @@ struct target_mq_attr { + #define FUTEX_CLOCK_REALTIME 256 + #define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME) + ++#include "ioctls_alsa_structs.h" +diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h +index 0e67cd8..635fdef 100644 +--- a/linux-user/syscall_types.h ++++ b/linux-user/syscall_types.h +@@ -80,6 +80,11 @@ STRUCT(count_info, + STRUCT(mixer_info, + MK_ARRAY(TYPE_CHAR, 16), MK_ARRAY(TYPE_CHAR, 32), TYPE_INT, MK_ARRAY(TYPE_INT, 10)) + ++/* FIXME: including these on x86 / x86_64 breaks qemu-i386 */ ++#ifdef __powerpc__ ++#include "syscall_types_alsa.h" ++#endif ++ + /* loop device ioctls */ + STRUCT(loop_info, + TYPE_INT, /* lo_number */ +diff --git a/linux-user/syscall_types_alsa.h b/linux-user/syscall_types_alsa.h +new file mode 100644 +index 0000000..6dbc964 +--- /dev/null ++++ b/linux-user/syscall_types_alsa.h +@@ -0,0 +1,1337 @@ ++/* ++ * Advanced Linux Sound Architecture ++ * ++ * This program is free software, you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY, without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * aTYPE_LONG, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++ ++STRUCT (sndrv_pcm_sframes, TYPE_LONG) ++STRUCT (sndrv_seq_event_type, TYPE_CHAR) ++STRUCT (sndrv_seq_instr_cluster, TYPE_INT) ++STRUCT (sndrv_seq_position, TYPE_INT) ++STRUCT (sndrv_seq_frequency, TYPE_INT) ++STRUCT (sndrv_seq_tick_time, TYPE_INT) ++STRUCT (sndrv_seq_instr_size, TYPE_INT) ++STRUCT (sndrv_pcm_uframes, TYPE_ULONG) ++ ++ ++STRUCT (timespec, ++ TYPE_LONG, ++ TYPE_LONG ++ ) ++ ++STRUCT( fm_operator, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT(fm_instrument, ++ MK_ARRAY(TYPE_INT, 4), /* share id - zero = no sharing */ ++ TYPE_CHAR, /* instrument type */ ++ ++ MK_ARRAY(MK_STRUCT(STRUCT_fm_operator), 4), ++ MK_ARRAY(TYPE_CHAR, 2), ++ ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT( fm_xoperator, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT( fm_xinstrument, ++ TYPE_INT, /* structure type */ ++ ++ MK_ARRAY(TYPE_INT, 4), /* share id - zero = no sharing */ ++ TYPE_CHAR, /* instrument type */ ++ ++ MK_ARRAY(MK_STRUCT(STRUCT_fm_xoperator), 4), /* fm operators */ ++ MK_ARRAY(TYPE_CHAR, 2), ++ ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT( gf1_wave, ++ MK_ARRAY(TYPE_INT, 4), /* share id - zero = no sharing */ ++ TYPE_INT, /* wave format */ ++ ++ TYPE_INT, /* some other ID for this instrument */ ++ TYPE_INT, /* begin of waveform in onboard memory */ ++ TYPE_PTRVOID, /* poTYPE_INTer to waveform in system memory */ ++ ++ TYPE_INT, /* size of waveform in samples */ ++ TYPE_INT, /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_SHORT, /* loop repeat - 0 = forever */ ++ ++ TYPE_CHAR, /* GF1 patch flags */ ++ TYPE_CHAR, ++ TYPE_INT, /* sample rate in Hz */ ++ TYPE_INT, /* low frequency range */ ++ TYPE_INT, /* high frequency range */ ++ TYPE_INT, /* root frequency range */ ++ TYPE_SHORT, ++ TYPE_CHAR, ++ MK_ARRAY(TYPE_CHAR, 6), ++ MK_ARRAY(TYPE_CHAR, 6), ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_SHORT, ++ TYPE_SHORT, /* 0-2048 or 0-2 */ ++ ++ TYPE_PTRVOID ++) ++ ++STRUCT(gf1_instrument, ++ TYPE_SHORT, ++ TYPE_SHORT, /* 0 - none, 1-65535 */ ++ ++ TYPE_CHAR, /* effect 1 */ ++ TYPE_CHAR, /* 0-127 */ ++ TYPE_CHAR, /* effect 2 */ ++ TYPE_CHAR, /* 0-127 */ ++ ++ TYPE_PTRVOID /* first waveform */ ++) ++ ++STRUCT( gf1_xwave, ++ TYPE_INT, /* structure type */ ++ ++ MK_ARRAY(TYPE_INT, 4), /* share id - zero = no sharing */ ++ TYPE_INT, /* wave format */ ++ ++ TYPE_INT, /* size of waveform in samples */ ++ TYPE_INT, /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_SHORT, /* loop repeat - 0 = forever */ ++ ++ TYPE_CHAR, /* GF1 patch flags */ ++ TYPE_CHAR, ++ TYPE_INT, /* sample rate in Hz */ ++ TYPE_INT, /* low frequency range */ ++ TYPE_INT, /* high frequency range */ ++ TYPE_INT, /* root frequency range */ ++ TYPE_SHORT, ++ TYPE_CHAR, ++ MK_ARRAY(TYPE_CHAR, 6), ++ MK_ARRAY(TYPE_CHAR, 6), ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_SHORT, ++ TYPE_SHORT /* 0-2048 or 0-2 */ ++) ++ ++STRUCT( gf1_xinstrument, ++ TYPE_INT, ++ ++ TYPE_SHORT, ++ TYPE_SHORT, /* 0 - none, 1-65535 */ ++ ++ TYPE_CHAR, /* effect 1 */ ++ TYPE_CHAR, /* 0-127 */ ++ TYPE_CHAR, /* effect 2 */ ++ TYPE_CHAR /* 0-127 */ ++) ++ ++STRUCT( gf1_info, ++ TYPE_CHAR, /* supported wave flags */ ++ MK_ARRAY(TYPE_CHAR, 3), ++ TYPE_INT, /* supported features */ ++ TYPE_INT, /* maximum 8-bit wave length */ ++ TYPE_INT /* maximum 16-bit wave length */ ++) ++ ++STRUCT( iwffff_wave, ++ MK_ARRAY(TYPE_INT, 4), /* share id - zero = no sharing */ ++ TYPE_INT, /* wave format */ ++ ++ TYPE_INT, /* some other ID for this wave */ ++ TYPE_INT, /* begin of waveform in onboard memory */ ++ TYPE_PTRVOID, /* poTYPE_INTer to waveform in system memory */ ++ ++ TYPE_INT, /* size of waveform in samples */ ++ TYPE_INT, /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_SHORT, /* loop repeat - 0 = forever */ ++ TYPE_INT, /* sample ratio (44100 * 1024 / rate) */ ++ TYPE_CHAR, /* 0 - 127 (no corresponding midi controller) */ ++ TYPE_CHAR, /* lower frequency range for this waveform */ ++ TYPE_CHAR, /* higher frequency range for this waveform */ ++ TYPE_CHAR, ++ ++ TYPE_PTRVOID ++) ++ ++STRUCT( iwffff_lfo, ++ TYPE_SHORT, /* (0-2047) 0.01Hz - 21.5Hz */ ++ TYPE_SHORT, /* volume +- (0-255) 0.48675dB/step */ ++ TYPE_SHORT, /* 0 - 950 deciseconds */ ++ TYPE_CHAR, /* see to IWFFFF_LFO_SHAPE_XXXX */ ++ TYPE_CHAR /* 0 - 255 deciseconds */ ++) ++ ++STRUCT( iwffff_env_point, ++ TYPE_SHORT, ++ TYPE_SHORT ++) ++ ++STRUCT( iwffff_env_record, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_PTRVOID ++) ++ ++STRUCT( iwffff_env, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_PTRVOID // MK_STRUCT(STRUCT_iwffff_env_record) ++) ++ ++STRUCT( iwffff_layer, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, /* range for layer based */ ++ TYPE_CHAR, /* on either velocity or frequency */ ++ TYPE_CHAR, /* pan offset from CC1 (0 left - 127 right) */ ++ TYPE_CHAR, /* position based on frequency (0-127) */ ++ TYPE_CHAR, /* 0-127 (no corresponding midi controller) */ ++ MK_STRUCT(STRUCT_iwffff_lfo), /* tremolo effect */ ++ MK_STRUCT(STRUCT_iwffff_lfo), /* vibrato effect */ ++ TYPE_SHORT, /* 0-2048, 1024 is equal to semitone scaling */ ++ TYPE_CHAR, /* center for keyboard frequency scaling */ ++ TYPE_CHAR, ++ MK_STRUCT(STRUCT_iwffff_env), /* pitch envelope */ ++ MK_STRUCT(STRUCT_iwffff_env), /* volume envelope */ ++ ++ TYPE_PTRVOID, // iwffff_wave_t *wave, ++ TYPE_PTRVOID // MK_STRUCT(STRUCT_iwffff_layer) ++) ++ ++STRUCT(iwffff_instrument, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_SHORT, /* 0 - none, 1-65535 */ ++ ++ TYPE_CHAR, /* effect 1 */ ++ TYPE_CHAR, /* 0-127 */ ++ TYPE_CHAR, /* effect 2 */ ++ TYPE_CHAR, /* 0-127 */ ++ ++ TYPE_PTRVOID // iwffff_layer_t *layer, /* first layer */ ++) ++ ++STRUCT( iwffff_xwave, ++ TYPE_INT, /* structure type */ ++ ++ MK_ARRAY(TYPE_INT, 4), /* share id - zero = no sharing */ ++ ++ TYPE_INT, /* wave format */ ++ TYPE_INT, /* offset to ROM (address) */ ++ ++ TYPE_INT, /* size of waveform in samples */ ++ TYPE_INT, /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_SHORT, /* loop repeat - 0 = forever */ ++ TYPE_INT, /* sample ratio (44100 * 1024 / rate) */ ++ TYPE_CHAR, /* 0 - 127 (no corresponding midi controller) */ ++ TYPE_CHAR, /* lower frequency range for this waveform */ ++ TYPE_CHAR, /* higher frequency range for this waveform */ ++ TYPE_CHAR ++) ++ ++STRUCT( iwffff_xlfo, ++ TYPE_SHORT, /* (0-2047) 0.01Hz - 21.5Hz */ ++ TYPE_SHORT, /* volume +- (0-255) 0.48675dB/step */ ++ TYPE_SHORT, /* 0 - 950 deciseconds */ ++ TYPE_CHAR, /* see to ULTRA_IW_LFO_SHAPE_XXXX */ ++ TYPE_CHAR /* 0 - 255 deciseconds */ ++) ++ ++STRUCT( iwffff_xenv_point, ++ TYPE_SHORT, ++ TYPE_SHORT ++) ++ ++STRUCT( iwffff_xenv_record, ++ TYPE_INT, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT( iwffff_xenv, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT( iwffff_xlayer, ++ TYPE_INT, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, /* range for layer based */ ++ TYPE_CHAR, /* on either velocity or frequency */ ++ TYPE_CHAR, /* pan offset from CC1 (0 left - 127 right) */ ++ TYPE_CHAR, /* position based on frequency (0-127) */ ++ TYPE_CHAR, /* 0-127 (no corresponding midi controller) */ ++ MK_STRUCT(STRUCT_iwffff_xlfo), /* tremolo effect */ ++ MK_STRUCT(STRUCT_iwffff_xlfo), /* vibrato effect */ ++ TYPE_SHORT, /* 0-2048, 1024 is equal to semitone scaling */ ++ TYPE_CHAR, /* center for keyboard frequency scaling */ ++ TYPE_CHAR, ++ MK_STRUCT(STRUCT_iwffff_xenv), /* pitch envelope */ ++ MK_STRUCT(STRUCT_iwffff_xenv) /* volume envelope */ ++) ++ ++STRUCT( iwffff_xinstrument, ++ TYPE_INT, ++ ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_SHORT, /* 0 - none, 1-65535 */ ++ ++ TYPE_CHAR, /* effect 1 */ ++ TYPE_CHAR, /* 0-127 */ ++ TYPE_CHAR, /* effect 2 */ ++ TYPE_CHAR /* 0-127 */ ++) ++ ++STRUCT(iwffff_rom_header, ++ MK_ARRAY(TYPE_CHAR, 8), ++ TYPE_CHAR, ++ TYPE_CHAR, ++ MK_ARRAY(TYPE_CHAR, 16), ++ MK_ARRAY(TYPE_CHAR, 10), ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_INT, ++ MK_ARRAY(TYPE_CHAR, 128), ++ MK_ARRAY(TYPE_CHAR, 64), ++ MK_ARRAY(TYPE_CHAR, 128) ++) ++ ++STRUCT( iwffff_info, ++ TYPE_INT, /* supported format bits */ ++ TYPE_INT, /* supported effects (1 << IWFFFF_EFFECT*) */ ++ TYPE_INT, /* LFO effects */ ++ TYPE_INT, /* maximum 8-bit wave length */ ++ TYPE_INT /* maximum 16-bit wave length */ ++) ++ ++STRUCT( simple_instrument_info, ++ TYPE_INT, /* supported format bits */ ++ TYPE_INT, /* supported effects (1 << SIMPLE_EFFECT_*) */ ++ TYPE_INT, /* maximum 8-bit wave length */ ++ TYPE_INT /* maximum 16-bit wave length */ ++) ++ ++STRUCT(simple_instrument, ++ MK_ARRAY(TYPE_INT, 4), /* share id - zero = no sharing */ ++ TYPE_INT, /* wave format */ ++ ++ TYPE_INT, /* some other ID for this instrument */ ++ TYPE_INT, /* begin of waveform in onboard memory */ ++ TYPE_PTRVOID, /* poTYPE_INTer to waveform in system memory */ ++ ++ TYPE_INT, /* size of waveform in samples */ ++ TYPE_INT, /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* loop end offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_SHORT, /* loop repeat - 0 = forever */ ++ ++ TYPE_CHAR, /* effect 1 */ ++ TYPE_CHAR, /* 0-127 */ ++ TYPE_CHAR, /* effect 2 */ ++ TYPE_CHAR /* 0-127 */ ++) ++ ++STRUCT( simple_xinstrument, ++ TYPE_INT, ++ ++ MK_ARRAY(TYPE_INT, 4), /* share id - zero = no sharing */ ++ TYPE_INT, /* wave format */ ++ ++ TYPE_INT, /* size of waveform in samples */ ++ TYPE_INT, /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_SHORT, /* loop repeat - 0 = forever */ ++ ++ TYPE_CHAR, /* effect 1 */ ++ TYPE_CHAR, /* 0-127 */ ++ TYPE_CHAR, /* effect 2 */ ++ TYPE_CHAR /* 0-127 */ ++) ++ ++/** event address */ ++STRUCT( sndrv_seq_addr, ++ TYPE_CHAR, /**< Client number: 0..255, 255 = broadcast to all clients */ ++ TYPE_CHAR /**< Port within client: 0..255, 255 = broadcast to all ports */ ++) ++ ++/** port connection */ ++STRUCT( sndrv_seq_connect, ++ MK_STRUCT(STRUCT_sndrv_seq_addr), ++ MK_STRUCT(STRUCT_sndrv_seq_addr) ++) ++ ++STRUCT( sndrv_seq_ev_note, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, /* only for SNDRV_SEQ_EVENT_NOTE */ ++ TYPE_INT /* only for SNDRV_SEQ_EVENT_NOTE */ ++) ++ ++ /* controller event */ ++STRUCT( sndrv_seq_ev_ctrl, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, /* pad */ ++ TYPE_INT, ++ TYPE_INT ++) ++ ++ /* generic set of bytes (12x8 bit) */ ++STRUCT( sndrv_seq_ev_raw8, ++ MK_ARRAY(TYPE_CHAR, 12) /* 8 bit value */ ++) ++ ++ /* generic set of TYPE_INTegers (3x32 bit) */ ++STRUCT( sndrv_seq_ev_raw32, ++ MK_ARRAY(TYPE_INT, 3) /* 32 bit value */ ++) ++ ++ /* external stored data */ ++STRUCT( sndrv_seq_ev_ext, ++ TYPE_INT, /* length of data */ ++ TYPE_PTRVOID /* poTYPE_INTer to data (note: maybe 64-bit) */ ++) ++ ++/* Instrument type */ ++STRUCT( sndrv_seq_instr, ++ TYPE_INT, ++ TYPE_INT, /* the upper byte means a private instrument (owner - client #) */ ++ TYPE_SHORT, ++ TYPE_SHORT ++) ++ ++ /* sample number */ ++STRUCT( sndrv_seq_ev_sample, ++ TYPE_INT, ++ TYPE_SHORT, ++ TYPE_SHORT ++) ++ ++ /* sample cluster */ ++STRUCT( sndrv_seq_ev_cluster, ++ TYPE_INT ++) ++ ++ /* sample volume control, if any value is set to -1 == do not change */ ++STRUCT( sndrv_seq_ev_volume, ++ TYPE_SHORT, /* range: 0-16383 */ ++ TYPE_SHORT, /* left-right balance, range: 0-16383 */ ++ TYPE_SHORT, /* front-rear balance, range: 0-16383 */ ++ TYPE_SHORT /* down-up balance, range: 0-16383 */ ++) ++ ++ /* simple loop redefinition */ ++STRUCT( sndrv_seq_ev_loop, ++ TYPE_INT, /* loop start (in samples) * 16 */ ++ TYPE_INT /* loop end (in samples) * 16 */ ++) ++ ++STRUCT( sndrv_seq_ev_sample_control, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, /* pad */ ++ MK_ARRAY(TYPE_INT, 2) ++) ++ ++ ++ ++/* INSTR_BEGIN event */ ++STRUCT( sndrv_seq_ev_instr_begin, ++ TYPE_INT ++) ++ ++STRUCT( sndrv_seq_result, ++ TYPE_INT, ++ TYPE_INT ++) ++ ++ ++STRUCT( sndrv_seq_real_time, ++ TYPE_INT, ++ TYPE_INT ++) ++ ++STRUCT( sndrv_seq_queue_skew, ++ TYPE_INT, ++ TYPE_INT ++) ++ ++ /* queue timer control */ ++STRUCT( sndrv_seq_ev_queue_control, ++ TYPE_CHAR, /* affected queue */ ++ MK_ARRAY(TYPE_CHAR, 3), /* reserved */ ++ MK_ARRAY(TYPE_INT, 2) ++) ++ ++ /* quoted event - inside the kernel only */ ++STRUCT( sndrv_seq_ev_quote, ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* original sender */ ++ TYPE_SHORT, /* optional data */ ++ MK_STRUCT(STRUCT_sndrv_seq_event) /* quoted event */ ++) ++ ++ ++ /* sequencer event */ ++STRUCT( sndrv_seq_event, ++ TYPE_CHAR, /* event type */ ++ TYPE_CHAR, /* event flags */ ++ TYPE_CHAR, ++ ++ TYPE_CHAR, /* schedule queue */ ++ MK_STRUCT(STRUCT_sndrv_seq_real_time), /* schedule time */ ++ ++ ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* source address */ ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* destination address */ ++ ++ MK_ARRAY(TYPE_INT,3) ++) ++ ++ ++/* ++ * bounce event - stored as variable size data ++ */ ++STRUCT( sndrv_seq_event_bounce, ++ TYPE_INT, ++ MK_STRUCT(STRUCT_sndrv_seq_event) ++ /* external data follows here. */ ++) ++ ++STRUCT( sndrv_seq_system_info, ++ TYPE_INT, /* maximum queues count */ ++ TYPE_INT, /* maximum clients count */ ++ TYPE_INT, /* maximum ports per client */ ++ TYPE_INT, /* maximum channels per port */ ++ TYPE_INT, /* current clients */ ++ TYPE_INT, /* current queues */ ++ MK_ARRAY(TYPE_CHAR, 24) ++) ++ ++STRUCT( sndrv_seq_running_info, ++ TYPE_CHAR, /* client id */ ++ TYPE_CHAR, /* 1 = big-endian */ ++ TYPE_CHAR, ++ TYPE_CHAR, /* reserved */ ++ MK_ARRAY(TYPE_CHAR, 12) ++) ++ ++STRUCT( sndrv_seq_client_info, ++ TYPE_INT, /* client number to inquire */ ++ TYPE_INT, /* client type */ ++ MK_ARRAY(TYPE_CHAR, 64), /* client name */ ++ TYPE_INT, /* filter flags */ ++ MK_ARRAY(TYPE_CHAR, 8), /* multicast filter bitmap */ ++ MK_ARRAY(TYPE_CHAR, 32), /* event filter bitmap */ ++ TYPE_INT, /* RO: number of ports */ ++ TYPE_INT, /* number of lost events */ ++ MK_ARRAY(TYPE_CHAR, 64) /* for future use */ ++) ++ ++STRUCT( sndrv_seq_client_pool, ++ TYPE_INT, /* client number to inquire */ ++ TYPE_INT, /* outgoing (write) pool size */ ++ TYPE_INT, /* incoming (read) pool size */ ++ TYPE_INT, /* minimum free pool size for select/blocking mode */ ++ TYPE_INT, /* unused size */ ++ TYPE_INT, /* unused size */ ++ MK_ARRAY(TYPE_CHAR, 64) ++) ++ ++STRUCT( sndrv_seq_remove_events, ++ TYPE_INT, /* Flags that determine what gets removed */ ++ ++ MK_STRUCT(STRUCT_sndrv_seq_real_time), ++ ++ TYPE_CHAR, /* Queue for REMOVE_DEST */ ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* Address for REMOVE_DEST */ ++ TYPE_CHAR, /* Channel for REMOVE_DEST */ ++ ++ TYPE_INT, /* For REMOVE_EVENT_TYPE */ ++ TYPE_CHAR, /* Tag for REMOVE_TAG */ ++ ++ MK_ARRAY(TYPE_INT, 10) /* To allow for future binary compatibility */ ++ ++) ++ ++STRUCT( sndrv_seq_port_info, ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* client/port numbers */ ++ MK_ARRAY(TYPE_CHAR, 64), /* port name */ ++ ++ TYPE_INT, /* port capability bits */ ++ TYPE_INT, /* port type bits */ ++ TYPE_INT, /* channels per MIDI port */ ++ TYPE_INT, /* voices per MIDI port */ ++ TYPE_INT, /* voices per SYNTH port */ ++ ++ TYPE_INT, /* R/O: subscribers for output (from this port) */ ++ TYPE_INT, /* R/O: subscribers for input (to this port) */ ++ ++ TYPE_PTRVOID, /* reserved for kernel use (must be NULL) */ ++ TYPE_INT, /* misc. conditioning */ ++ TYPE_CHAR, /* queue # for timestamping */ ++ MK_ARRAY(TYPE_CHAR, 59) /* for future use */ ++) ++ ++STRUCT( sndrv_seq_queue_info, ++ TYPE_INT, /* queue id */ ++ ++ /* ++ * security settings, only owner of this queue can start/stop timer ++ * etc. if the queue is locked for other clients ++ */ ++ TYPE_INT, /* client id for owner of the queue */ ++ TYPE_INT, /* timing queue locked for other queues */ ++ MK_ARRAY(TYPE_CHAR, 64), /* name of this queue */ ++ TYPE_INT, /* flags */ ++ MK_ARRAY(TYPE_CHAR, 60) /* for future use */ ++ ++) ++ ++STRUCT( sndrv_seq_queue_status, ++ TYPE_INT, /* queue id */ ++ TYPE_INT, /* read-only - queue size */ ++ TYPE_INT, /* current tick */ ++ MK_STRUCT(STRUCT_sndrv_seq_real_time), /* current time */ ++ TYPE_INT, /* running state of queue */ ++ TYPE_INT, /* various flags */ ++ MK_ARRAY(TYPE_CHAR, 64) /* for the future */ ++) ++ ++STRUCT( sndrv_seq_queue_tempo, ++ TYPE_INT, /* sequencer queue */ ++ TYPE_INT, ++ TYPE_INT, ++ TYPE_INT, /* queue skew */ ++ TYPE_INT, /* queue skew base */ ++ MK_ARRAY(TYPE_CHAR, 24) /* for the future */ ++) ++ ++STRUCT( sndrv_timer_id, ++ TYPE_INT, ++ TYPE_INT, ++ TYPE_INT, ++ TYPE_INT, ++ TYPE_INT ++) ++ ++STRUCT( sndrv_seq_queue_timer, ++ TYPE_INT, /* sequencer queue */ ++ TYPE_INT, /* source timer type */ ++ MK_STRUCT(STRUCT_sndrv_timer_id), /* ALSA's timer ID */ ++ TYPE_INT, /* resolution in Hz */ ++ MK_ARRAY(TYPE_CHAR, 64) /* for the future use */ ++) ++ ++STRUCT( sndrv_seq_queue_client, ++ TYPE_INT, /* sequencer queue */ ++ TYPE_INT, /* sequencer client */ ++ TYPE_INT, /* queue is used with this client ++ (must be set for accepting events) */ ++ /* per client watermarks */ ++ MK_ARRAY(TYPE_CHAR, 64) /* for future use */ ++) ++ ++STRUCT( sndrv_seq_port_subscribe, ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* sender address */ ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* destination address */ ++ TYPE_INT, /* number of voices to be allocated (0 = don't care) */ ++ TYPE_INT, /* modes */ ++ TYPE_CHAR, /* input time-stamp queue (optional) */ ++ MK_ARRAY(TYPE_CHAR, 3), /* reserved */ ++ MK_ARRAY(TYPE_CHAR, 64) ++) ++ ++STRUCT( sndrv_seq_query_subs, ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* client/port id to be searched */ ++ TYPE_INT, /* READ or WRITE */ ++ TYPE_INT, /* 0..N-1 */ ++ TYPE_INT, /* R/O: number of subscriptions on this port */ ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* R/O: result */ ++ TYPE_CHAR, /* R/O: result */ ++ TYPE_INT, /* R/O: result */ ++ MK_ARRAY(TYPE_CHAR, 64) /* for future use */ ++) ++ ++STRUCT( sndrv_seq_instr_info, ++ TYPE_INT, /* operation result */ ++ MK_ARRAY(TYPE_INT, 8), /* bitmap of supported formats */ ++ TYPE_INT, /* count of RAM banks */ ++ MK_ARRAY(TYPE_INT, 16), /* size of RAM banks */ ++ TYPE_INT, /* count of ROM banks */ ++ MK_ARRAY(TYPE_INT, 8), /* size of ROM banks */ ++ MK_ARRAY(TYPE_CHAR, 128) ++) ++ ++STRUCT( sndrv_seq_instr_status, ++ TYPE_INT, /* operation result */ ++ MK_ARRAY(TYPE_INT, 16), /* free RAM in banks */ ++ TYPE_INT, /* count of downloaded instruments */ ++ MK_ARRAY(TYPE_CHAR, 128) ++) ++ ++STRUCT( sndrv_seq_instr_format_info, ++ MK_ARRAY(TYPE_CHAR, 16), /* format identifier - SNDRV_SEQ_INSTR_ID_* */ ++ TYPE_INT /* max data length (without this structure) */ ++) ++ ++STRUCT( sndrv_seq_instr_format_info_result, ++ TYPE_INT, /* operation result */ ++ MK_ARRAY(TYPE_CHAR, 16), /* format identifier */ ++ TYPE_INT /* filled data length (without this structure) */ ++) ++ ++STRUCT( sndrv_seq_instr_data, ++ MK_ARRAY(TYPE_CHAR, 32), /* instrument name */ ++ MK_ARRAY(TYPE_CHAR, 16), /* for the future use */ ++ TYPE_INT, /* instrument type */ ++ MK_STRUCT(STRUCT_sndrv_seq_instr), ++ MK_ARRAY(TYPE_CHAR, 4) /* fillup */ ++) ++ ++STRUCT( sndrv_seq_instr_header, ++ MK_STRUCT(STRUCT_sndrv_seq_instr), ++ TYPE_INT, /* get/put/free command */ ++ TYPE_INT, /* query flags (only for get) */ ++ TYPE_INT, /* real instrument data length (without header) */ ++ TYPE_INT, /* operation result */ ++ MK_ARRAY(TYPE_CHAR, 16), /* for the future */ ++ MK_STRUCT(STRUCT_sndrv_seq_instr_data) /* instrument data (for put/get result) */ ++) ++ ++STRUCT( sndrv_seq_instr_cluster_set, ++ TYPE_INT, /* cluster identifier */ ++ MK_ARRAY(TYPE_CHAR, 32), /* cluster name */ ++ TYPE_INT, /* cluster priority */ ++ MK_ARRAY(TYPE_CHAR, 64) /* for the future use */ ++) ++ ++STRUCT( sndrv_seq_instr_cluster_get, ++ TYPE_INT, /* cluster identifier */ ++ MK_ARRAY(TYPE_CHAR, 32), /* cluster name */ ++ TYPE_INT, /* cluster priority */ ++ MK_ARRAY(TYPE_CHAR, 64) /* for the future use */ ++) ++ ++STRUCT( snd_dm_fm_info, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT( snd_dm_fm_voice, ++ TYPE_CHAR, /* operator cell (0 or 1) */ ++ TYPE_CHAR, /* FM voice (0 to 17) */ ++ ++ TYPE_CHAR, /* amplitude modulation */ ++ TYPE_CHAR, /* vibrato effect */ ++ TYPE_CHAR, /* sustain phase */ ++ TYPE_CHAR, /* keyboard scaling */ ++ TYPE_CHAR, /* 4 bits: harmonic and multiplier */ ++ TYPE_CHAR, /* 2 bits: decrease output freq rises */ ++ TYPE_CHAR, /* 6 bits: volume */ ++ ++ TYPE_CHAR, /* 4 bits: attack rate */ ++ TYPE_CHAR, /* 4 bits: decay rate */ ++ TYPE_CHAR, /* 4 bits: sustain level */ ++ TYPE_CHAR, /* 4 bits: release rate */ ++ ++ TYPE_CHAR, /* 3 bits: feedback for op0 */ ++ TYPE_CHAR, ++ TYPE_CHAR, /* stereo left */ ++ TYPE_CHAR, /* stereo right */ ++ TYPE_CHAR /* 3 bits: waveform shape */ ++) ++ ++STRUCT( snd_dm_fm_note, ++ TYPE_CHAR, /* 0-17 voice channel */ ++ TYPE_CHAR, /* 3 bits: what octave to play */ ++ TYPE_INT, /* 10 bits: frequency number */ ++ TYPE_CHAR ++) ++ ++STRUCT( snd_dm_fm_params, ++ TYPE_CHAR, /* amplitude modulation depth (1=hi) */ ++ TYPE_CHAR, /* vibrato depth (1=hi) */ ++ TYPE_CHAR, /* keyboard split */ ++ TYPE_CHAR, /* percussion mode select */ ++ ++ /* This block is the percussion instrument data */ ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT( sndrv_aes_iec958, ++ MK_ARRAY(TYPE_CHAR, 24), /* AES/IEC958 channel status bits */ ++ MK_ARRAY(TYPE_CHAR, 147), /* AES/IEC958 subcode bits */ ++ TYPE_CHAR, /* nothing */ ++ MK_ARRAY(TYPE_CHAR, 4) /* AES/IEC958 subframe bits */ ++) ++ ++STRUCT( sndrv_hwdep_info, ++ TYPE_INT, /* WR: device number */ ++ TYPE_INT, /* R: card number */ ++ MK_ARRAY(TYPE_CHAR, 64), /* ID (user selectable) */ ++ MK_ARRAY(TYPE_CHAR, 80), /* hwdep name */ ++ TYPE_INT, /* hwdep interface */ ++ MK_ARRAY(TYPE_CHAR, 64) /* reserved for future */ ++) ++ ++/* generic DSP loader */ ++STRUCT( sndrv_hwdep_dsp_status, ++ TYPE_INT, /* R: driver-specific version */ ++ MK_ARRAY(TYPE_CHAR, 32), /* R: driver-specific ID string */ ++ TYPE_INT, /* R: number of DSP images to transfer */ ++ TYPE_INT, /* R: bit flags indicating the loaded DSPs */ ++ TYPE_INT, /* R: 1 = initialization finished */ ++ MK_ARRAY(TYPE_CHAR, 16) /* reserved for future use */ ++) ++ ++STRUCT( sndrv_hwdep_dsp_image, ++ TYPE_INT, /* W: DSP index */ ++ MK_ARRAY(TYPE_CHAR, 64), /* W: ID (e.g. file name) */ ++ TYPE_CHAR, /* W: binary image */ ++ TYPE_LONG, /* W: size of image in bytes */ ++ TYPE_LONG /* W: driver-specific data */ ++) ++ ++STRUCT( sndrv_pcm_info, ++ TYPE_INT, /* RO/WR (control): device number */ ++ TYPE_INT, /* RO/WR (control): subdevice number */ ++ TYPE_INT, /* RO/WR (control): stream number */ ++ TYPE_INT, /* R: card number */ ++ MK_ARRAY(TYPE_CHAR, 64), /* ID (user selectable) */ ++ MK_ARRAY(TYPE_CHAR, 80), /* name of this device */ ++ MK_ARRAY(TYPE_CHAR, 32), /* subdevice name */ ++ TYPE_INT, /* SNDRV_PCM_CLASS_* */ ++ TYPE_INT, /* SNDRV_PCM_SUBCLASS_* */ ++ TYPE_INT, ++ TYPE_INT, ++ MK_ARRAY(TYPE_INT, 4), ++ ++ MK_ARRAY(TYPE_CHAR, 64) /* reserved for future... */ ++) ++ ++STRUCT( sndrv_interval, ++ TYPE_INT, ++ TYPE_INT, ++ TYPE_INTBITFIELD ++) ++ ++STRUCT( sndrv_mask, ++ MK_ARRAY(TYPE_INT, (SNDRV_MASK_MAX+31)/32) ++) ++ ++STRUCT( sndrv_pcm_hw_params, ++ TYPE_INT, ++ MK_ARRAY(MK_STRUCT(STRUCT_sndrv_mask),SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1), ++ MK_ARRAY(MK_STRUCT(STRUCT_sndrv_mask), 5), /* reserved masks */ ++ MK_ARRAY(MK_STRUCT(STRUCT_sndrv_interval), SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1), ++ MK_ARRAY(MK_STRUCT(STRUCT_sndrv_interval), 9), /* reserved intervals */ ++ TYPE_INT, /* W: requested masks */ ++ TYPE_INT, /* R: changed masks */ ++ TYPE_INT, /* R: Info flags for returned setup */ ++ TYPE_INT, /* R: used most significant bits */ ++ TYPE_INT, /* R: rate numerator */ ++ TYPE_INT, /* R: rate denominator */ ++ TYPE_LONG, /* R: chip FIFO size in frames */ ++ MK_ARRAY(TYPE_CHAR, 64) /* reserved for future */ ++) ++ ++STRUCT( sndrv_pcm_sw_params, ++ TYPE_INT, /* timestamp mode */ ++ TYPE_INT, ++ TYPE_INT, /* min ticks to sleep */ ++ TYPE_LONG, /* min avail frames for wakeup */ ++ TYPE_LONG, /* xfer size need to be a multiple */ ++ TYPE_LONG, /* min hw_avail frames for automatic start */ ++ TYPE_LONG, /* min avail frames for automatic stop */ ++ TYPE_LONG, /* min distance from noise for silence filling */ ++ TYPE_LONG, /* silence block size */ ++ TYPE_LONG, /* poTYPE_INTers wrap point */ ++ MK_ARRAY(TYPE_CHAR, 64) /* reserved for future */ ++) ++ ++STRUCT( sndrv_pcm_channel_info, ++ TYPE_INT, ++ TYPE_LONG, /* mmap offset (FIXME) */ ++ TYPE_INT, /* offset to first sample in bits */ ++ TYPE_INT /* samples distance in bits */ ++) ++ ++ ++STRUCT( sndrv_pcm_status, ++ TYPE_INT, /* stream state */ ++ MK_STRUCT(STRUCT_timespec), /* time when stream was started/stopped/paused */ ++ MK_STRUCT(STRUCT_timespec), /* reference timestamp */ ++ TYPE_LONG, /* appl ptr */ ++ TYPE_LONG, /* hw ptr */ ++ TYPE_LONG, /* current delay in frames */ ++ TYPE_LONG, /* number of frames available */ ++ TYPE_LONG, /* max frames available on hw since last status */ ++ TYPE_LONG, /* count of ADC (capture) overrange detections from last status */ ++ TYPE_INT, /* suspended stream state */ ++ MK_ARRAY(TYPE_CHAR, 60) /* must be filled with zero */ ++) ++ ++STRUCT( sndrv_pcm_mmap_status, ++ TYPE_INT, /* RO: state - SNDRV_PCM_STATE_XXXX */ ++ TYPE_INT, /* Needed for 64 bit alignment */ ++ TYPE_LONG, /* RO: hw ptr (0...boundary-1) */ ++ MK_STRUCT(STRUCT_timespec), /* Timestamp */ ++ TYPE_INT /* RO: suspended stream state */ ++) ++ ++STRUCT( sndrv_pcm_mmap_control, ++ TYPE_LONG, /* RW: appl ptr (0...boundary-1) */ ++ TYPE_LONG /* RW: min available frames for wakeup */ ++) ++ ++STRUCT( sndrv_pcm_sync_ptr, ++ TYPE_INT, ++ // FIXME: does not work with 64-bit target ++ MK_STRUCT(STRUCT_sndrv_pcm_mmap_status), // 28 bytes on 32-bit target ++ MK_ARRAY(TYPE_CHAR, 64 - 24), // so we pad to 64 bytes (was a union) ++ ++ MK_STRUCT(STRUCT_sndrv_pcm_mmap_control), // 8 bytes on 32-bit target ++ MK_ARRAY(TYPE_CHAR, 64 - 8) // so we pad to 64 bytes (was a union)) ++) ++ ++STRUCT( sndrv_xferi, ++ TYPE_LONG, ++ TYPE_PTRVOID, ++ TYPE_LONG ++) ++ ++STRUCT( sndrv_xfern, ++ TYPE_LONG, ++ TYPE_PTRVOID, ++ TYPE_LONG ++) ++ ++STRUCT( sndrv_rawmidi_info, ++ TYPE_INT, /* RO/WR (control): device number */ ++ TYPE_INT, /* RO/WR (control): subdevice number */ ++ TYPE_INT, /* WR: stream */ ++ TYPE_INT, /* R: card number */ ++ TYPE_INT, /* SNDRV_RAWMIDI_INFO_XXXX */ ++ MK_ARRAY(TYPE_CHAR, 64), /* ID (user selectable) */ ++ MK_ARRAY(TYPE_CHAR, 80), /* name of device */ ++ MK_ARRAY(TYPE_CHAR, 32), /* name of active or selected subdevice */ ++ TYPE_INT, ++ TYPE_INT, ++ MK_ARRAY(TYPE_CHAR, 64) /* reserved for future use */ ++) ++ ++STRUCT( sndrv_rawmidi_params, ++ TYPE_INT, ++ TYPE_LONG, /* queue size in bytes */ ++ TYPE_LONG, /* minimum avail bytes for wakeup */ ++ TYPE_INT, /* do not send active sensing byte in close() */ ++ MK_ARRAY(TYPE_CHAR, 16) /* reserved for future use */ ++) ++ ++STRUCT( sndrv_rawmidi_status, ++ TYPE_INT, ++ MK_STRUCT(STRUCT_timespec), /* Timestamp */ ++ TYPE_LONG, /* available bytes */ ++ TYPE_LONG, /* count of overruns since last status (in bytes) */ ++ MK_ARRAY(TYPE_CHAR, 16) /* reserved for future use */ ++) ++ ++STRUCT( sndrv_timer_ginfo, ++ MK_STRUCT(STRUCT_sndrv_timer_id), /* requested timer ID */ ++ TYPE_INT, /* timer flags - SNDRV_TIMER_FLG_* */ ++ TYPE_INT, /* card number */ ++ MK_ARRAY(TYPE_CHAR, 64), /* timer identification */ ++ MK_ARRAY(TYPE_CHAR, 80), /* timer name */ ++ TYPE_LONG, /* reserved for future use */ ++ TYPE_LONG, /* average period resolution in ns */ ++ TYPE_LONG, /* minimal period resolution in ns */ ++ TYPE_LONG, /* maximal period resolution in ns */ ++ TYPE_INT, /* active timer clients */ ++ MK_ARRAY(TYPE_CHAR, 32) ++) ++ ++STRUCT( sndrv_timer_gparams, ++ MK_STRUCT(STRUCT_sndrv_timer_id), /* requested timer ID */ ++ TYPE_LONG, /* requested precise period duration (in seconds) - numerator */ ++ TYPE_LONG, /* requested precise period duration (in seconds) - denominator */ ++ MK_ARRAY(TYPE_CHAR, 32) ++) ++ ++STRUCT( sndrv_timer_gstatus, ++ MK_STRUCT(STRUCT_sndrv_timer_id), /* requested timer ID */ ++ TYPE_LONG, /* current period resolution in ns */ ++ TYPE_LONG, /* precise current period resolution (in seconds) - numerator */ ++ TYPE_LONG, /* precise current period resolution (in seconds) - denominator */ ++ MK_ARRAY(TYPE_CHAR, 32) ++) ++ ++STRUCT( sndrv_timer_select, ++ MK_STRUCT(STRUCT_sndrv_timer_id), /* bind to timer ID */ ++ MK_ARRAY(TYPE_CHAR, 32) /* reserved */ ++) ++ ++STRUCT( sndrv_timer_info, ++ TYPE_INT, /* timer flags - SNDRV_TIMER_FLG_* */ ++ TYPE_INT, /* card number */ ++ MK_ARRAY(TYPE_CHAR, 64), /* timer identificator */ ++ MK_ARRAY(TYPE_CHAR, 80), /* timer name */ ++ TYPE_LONG, /* reserved for future use */ ++ TYPE_LONG, /* average period resolution in ns */ ++ MK_ARRAY(TYPE_CHAR, 64) /* reserved */ ++) ++ ++STRUCT( sndrv_timer_params, ++ TYPE_INT, /* flags - SNDRV_MIXER_PSFLG_* */ ++ TYPE_INT, /* requested resolution in ticks */ ++ TYPE_INT, /* total size of queue (32-1024) */ ++ TYPE_INT, ++ TYPE_INT, /* event filter (bitmask of SNDRV_TIMER_EVENT_*) */ ++ MK_ARRAY(TYPE_CHAR, 60) /* reserved */ ++) ++ ++STRUCT( sndrv_timer_status, ++ MK_STRUCT(STRUCT_timespec), /* Timestamp - last update */ ++ TYPE_INT, /* current period resolution in ns */ ++ TYPE_INT, /* counter of master tick lost */ ++ TYPE_INT, /* count of read queue overruns */ ++ TYPE_INT, /* used queue size */ ++ MK_ARRAY(TYPE_CHAR, 64) /* reserved */ ++) ++ ++STRUCT( sndrv_timer_read, ++ TYPE_INT, ++ TYPE_INT ++) ++ ++STRUCT( sndrv_timer_tread, ++ TYPE_INT, ++ MK_STRUCT(STRUCT_timespec), ++ TYPE_INT ++) ++ ++STRUCT( sndrv_ctl_card_info, ++ TYPE_INT, /* card number */ ++ TYPE_INT, /* reserved for future (was type) */ ++ MK_ARRAY(TYPE_CHAR, 16), /* ID of card (user selectable) */ ++ MK_ARRAY(TYPE_CHAR, 16), /* Driver name */ ++ MK_ARRAY(TYPE_CHAR, 32), /* Short name of soundcard */ ++ MK_ARRAY(TYPE_CHAR, 80), /* name + info text about soundcard */ ++ MK_ARRAY(TYPE_CHAR, 16), /* reserved for future (was ID of mixer) */ ++ MK_ARRAY(TYPE_CHAR, 80), /* visual mixer identification */ ++ MK_ARRAY(TYPE_CHAR, 80), /* card components / fine identification, delimited with one space (AC97 etc..) */ ++ MK_ARRAY(TYPE_CHAR, 48) /* reserved for future */ ++) ++ ++STRUCT( sndrv_ctl_elem_id, ++ TYPE_INT, ++ TYPE_INT, /* interface identifier */ ++ TYPE_INT, /* device/client number */ ++ TYPE_INT, /* subdevice (substream) number */ ++ MK_ARRAY(TYPE_CHAR, 44), /* ASCII name of item */ ++ TYPE_INT /* index of item */ ++) ++ ++STRUCT( sndrv_ctl_elem_list, ++ TYPE_INT, /* W: first element ID to get */ ++ TYPE_INT, /* W: count of element IDs to get */ ++ TYPE_INT, /* R: count of element IDs set */ ++ TYPE_INT, /* R: count of all elements */ ++ MK_STRUCT(STRUCT_sndrv_ctl_elem_id), /* R: IDs */ ++ MK_ARRAY(TYPE_CHAR, 50) ++) ++ ++STRUCT( sndrv_ctl_elem_info, ++ MK_STRUCT(STRUCT_sndrv_ctl_elem_id), /* W: element ID */ ++ TYPE_INT, /* R: value type - SNDRV_CTL_ELEM_TYPE_* */ ++ TYPE_INT, /* R: value access (bitmask) - SNDRV_CTL_ELEM_ACCESS_* */ ++ TYPE_INT, /* count of values */ ++ TYPE_INT, /* owner's PID of this control */ ++ MK_ARRAY(TYPE_CHAR, 128), // FIXME: prone to break (was union) ++ MK_ARRAY(TYPE_SHORT, 4), /* dimensions */ ++ MK_ARRAY(TYPE_CHAR, 64-4*sizeof(unsigned short)) ++) ++ ++STRUCT( sndrv_ctl_elem_value, ++ MK_STRUCT(STRUCT_sndrv_ctl_elem_id), /* W: element ID */ ++ TYPE_INT, /* W: use indirect pointer (xxx_ptr member) */ ++ MK_ARRAY(TYPE_INT, 128), ++ MK_STRUCT(STRUCT_timespec), ++ MK_ARRAY(TYPE_CHAR, 128-sizeof(struct timespec)) // FIXME: breaks on 64-bit host ++) ++ ++STRUCT( sndrv_ctl_tlv, ++ TYPE_INT, /* control element numeric identification */ ++ TYPE_INT, /* in bytes aligned to 4 */ ++ MK_ARRAY(TYPE_INT, 0) /* first TLV */ // FIXME: what is this supposed to become? ++) ++ ++STRUCT( sndrv_ctl_event, ++ TYPE_INT, /* event type - SNDRV_CTL_EVENT_* */ ++ TYPE_INT, ++ MK_STRUCT(STRUCT_sndrv_ctl_elem_id) // 64 bytes ++) ++ ++STRUCT( iovec, ++ TYPE_PTRVOID, ++ TYPE_LONG ++ ) ++ ++ ++STRUCT( sndrv_xferv, ++ MK_STRUCT(STRUCT_iovec), ++ TYPE_LONG ++) ++ ++STRUCT(emu10k1_fx8010_info, ++ TYPE_INT, /* in samples */ ++ TYPE_INT, /* in samples */ ++ MK_ARRAY(MK_ARRAY(TYPE_CHAR, 32), 16), /* names of FXBUSes */ ++ MK_ARRAY(MK_ARRAY(TYPE_CHAR, 32), 16), /* names of external inputs */ ++ MK_ARRAY(MK_ARRAY(TYPE_CHAR, 32), 32), /* names of external outputs */ ++ TYPE_INT /* count of GPR controls */ ++) ++ ++STRUCT(emu10k1_ctl_elem_id, ++ TYPE_INT, /* don't use */ ++ TYPE_INT, /* interface identifier */ ++ TYPE_INT, /* device/client number */ ++ TYPE_INT, /* subdevice (substream) number */ ++ MK_ARRAY(TYPE_CHAR, 44), /* ASCII name of item */ ++ TYPE_INT /* index of item */ ++) ++ ++STRUCT(emu10k1_fx8010_control_gpr, ++ MK_STRUCT(STRUCT_emu10k1_ctl_elem_id), /* full control ID definition */ ++ TYPE_INT, /* visible count */ ++ TYPE_INT, /* count of GPR (1..16) */ ++ MK_ARRAY(TYPE_SHORT, 32), /* GPR number(s) */ ++ MK_ARRAY(TYPE_INT, 32), /* initial values */ ++ TYPE_INT, /* minimum range */ ++ TYPE_INT, /* maximum range */ ++ TYPE_INT, /* translation type (EMU10K1_GPR_TRANSLATION*) */ ++ TYPE_INT ++) ++ ++#ifndef TARGET_LONG_SIZE ++#define TARGET_LONG_SIZE 4 ++#endif ++ ++STRUCT(emu10k1_fx8010_code, ++ MK_ARRAY(TYPE_CHAR, 128), ++ ++ MK_ARRAY(TYPE_LONG, 0x200/(TARGET_LONG_SIZE*8)), /* bitmask of valid initializers */ ++ TYPE_PTRVOID, /* initializers */ ++ ++ TYPE_INT, /* count of GPR controls to add/replace */ ++ MK_STRUCT(STRUCT_emu10k1_fx8010_control_gpr), /* GPR controls to add/replace */ ++ ++ TYPE_INT, /* count of GPR controls to remove */ ++ MK_STRUCT(STRUCT_emu10k1_ctl_elem_id), /* IDs of GPR controls to remove */ ++ ++ TYPE_INT, /* count of GPR controls to list */ ++ TYPE_INT, /* total count of GPR controls */ ++ MK_STRUCT(STRUCT_emu10k1_fx8010_control_gpr), /* listed GPR controls */ ++ ++ MK_ARRAY(TYPE_LONG, 0x100/(TARGET_LONG_SIZE*8)), /* bitmask of valid initializers */ ++ TYPE_PTRVOID, /* data initializers */ ++ TYPE_PTRVOID, /* map initializers */ ++ ++ MK_ARRAY(TYPE_LONG, 1024/(TARGET_LONG_SIZE*8)), /* bitmask of valid instructions */ ++ TYPE_PTRVOID /* one instruction - 64 bits */ ++) ++ ++STRUCT(emu10k1_fx8010_tram, ++ TYPE_INT, /* 31.bit == 1 -> external TRAM */ ++ TYPE_INT, /* size in samples (4 bytes) */ ++ TYPE_INT /* pointer to samples (20-bit) */ ++ /* NULL->clear memory */ ++) ++ ++STRUCT(emu10k1_fx8010_pcm, ++ TYPE_INT, /* substream number */ ++ TYPE_INT, /* reserved */ ++ TYPE_INT, ++ TYPE_INT, /* ring buffer position in TRAM (in samples) */ ++ TYPE_INT, /* count of buffered samples */ ++ TYPE_SHORT, /* GPR containing size of ringbuffer in samples (host) */ ++ TYPE_SHORT, ++ TYPE_SHORT, /* GPR containing count of samples between two TYPE_INTerrupts (host) */ ++ TYPE_SHORT, ++ TYPE_SHORT, /* GPR containing trigger (activate) information (host) */ ++ TYPE_SHORT, /* GPR containing info if PCM is running (FX8010) */ ++ TYPE_CHAR, /* reserved */ ++ MK_ARRAY(TYPE_CHAR, 32), /* external TRAM address & data (one per channel) */ ++ TYPE_INT /* reserved */ ++) ++ ++STRUCT( hdsp_peak_rms, ++ MK_ARRAY(TYPE_INT, 26), ++ MK_ARRAY(TYPE_INT, 26), ++ MK_ARRAY(TYPE_INT, 28), ++ MK_ARRAY(TYPE_LONGLONG, 26), ++ MK_ARRAY(TYPE_LONGLONG, 26), ++ /* These are only used for H96xx cards */ ++ MK_ARRAY(TYPE_LONGLONG, 26) ++) ++ ++STRUCT( hdsp_config_info, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ MK_ARRAY(TYPE_CHAR, 3), ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_INT, ++ TYPE_INT, ++ TYPE_INT, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT( hdsp_firmware, ++ TYPE_PTRVOID /* 24413 x 4 bytes */ ++) ++ ++STRUCT( hdsp_version, ++ TYPE_INT, ++ TYPE_SHORT ++) ++ ++STRUCT( hdsp_mixer, ++ MK_ARRAY(TYPE_SHORT, HDSP_MATRIX_MIXER_SIZE) ++) ++ ++STRUCT( hdsp_9632_aeb, ++ TYPE_INT, ++ TYPE_INT ++) ++ ++STRUCT( snd_sb_csp_mc_header, ++ MK_ARRAY(TYPE_CHAR, 16), /* id name of codec */ ++ TYPE_SHORT /* requested function */ ++) ++ ++STRUCT( snd_sb_csp_microcode, ++ MK_STRUCT(STRUCT_snd_sb_csp_mc_header), ++ MK_ARRAY(TYPE_CHAR, SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE) ++) ++ ++STRUCT( snd_sb_csp_start, ++ TYPE_INT, ++ TYPE_INT ++) ++ ++STRUCT( snd_sb_csp_info, ++ MK_ARRAY(TYPE_CHAR, 16), /* id name of codec */ ++ TYPE_SHORT, /* function number */ ++ TYPE_INT, /* accepted PCM formats */ ++ TYPE_SHORT, /* accepted channels */ ++ TYPE_SHORT, /* accepted sample width */ ++ TYPE_SHORT, /* accepted sample rates */ ++ TYPE_SHORT, ++ TYPE_SHORT, /* current channels */ ++ TYPE_SHORT, /* current sample width */ ++ TYPE_SHORT, /* version id: 0x10 - 0x1f */ ++ TYPE_SHORT /* state bits */ ++) ++ ++STRUCT( sscape_bootblock, ++ MK_ARRAY(TYPE_CHAR, 256), ++ TYPE_INT ++) ++ ++STRUCT( sscape_microcode, ++ TYPE_PTRVOID ++) ++ +-- +1.7.1 + diff --git a/app-emulation/qemu-user/files/0.14.1/0005-qemu-cvs-alsa_mmap.patch b/app-emulation/qemu-user/files/0.14.1/0005-qemu-cvs-alsa_mmap.patch new file mode 100644 index 0000000..503b57b --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0005-qemu-cvs-alsa_mmap.patch @@ -0,0 +1,47 @@ +From 3848cba4ed22ebef70e59cbb542e71a37fe74d1d Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Tue, 14 Apr 2009 16:24:15 +0200 +Subject: [PATCH 05/17] qemu-cvs-alsa_mmap + +Hack to prevent ALSA from using mmap() interface to simplify emulation. + +Signed-off-by: Ulrich Hecht +--- + linux-user/mmap.c | 14 ++++++++++++++ + 1 files changed, 14 insertions(+), 0 deletions(-) + +diff --git a/linux-user/mmap.c b/linux-user/mmap.c +index abf21f6..e18c228 100644 +--- a/linux-user/mmap.c ++++ b/linux-user/mmap.c +@@ -360,6 +360,9 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) + } + } + ++#define SNDRV_PCM_MMAP_OFFSET_STATUS 0x80000000 ++#define SNDRV_PCM_MMAP_OFFSET_CONTROL 0x81000000 ++ + /* NOTE: all the constants are the HOST ones */ + abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, + int flags, int fd, abi_ulong offset) +@@ -395,6 +398,17 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, + } + #endif + ++ /* Alsa tries to communcate with the kernel via mmap. This usually ++ * is a good idea when user- and kernelspace are running on the ++ * same architecture but does not work out when not. To make alsa ++ * not to use mmap, we can just have it fail on the mmap calls that ++ * would initiate this. ++ */ ++ if(offset == SNDRV_PCM_MMAP_OFFSET_STATUS || offset == SNDRV_PCM_MMAP_OFFSET_CONTROL) { ++ errno = EINVAL; ++ return -1; ++ } ++ + if (offset & ~TARGET_PAGE_MASK) { + errno = EINVAL; + goto fail; +-- +1.7.1 + diff --git a/app-emulation/qemu-user/files/0.14.1/0006-qemu-cvs-gettimeofday.patch b/app-emulation/qemu-user/files/0.14.1/0006-qemu-cvs-gettimeofday.patch new file mode 100644 index 0000000..c260d76 --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0006-qemu-cvs-gettimeofday.patch @@ -0,0 +1,26 @@ +From da6cdca6cdbfccb4936f5df5e297a87fe1e4baa8 Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Tue, 14 Apr 2009 16:25:41 +0200 +Subject: [PATCH 06/17] qemu-cvs-gettimeofday + +No clue what this is for. +--- + linux-user/syscall.c | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +diff --git a/linux-user/syscall.c b/linux-user/syscall.c +index 499c4d7..92f2aa6 100644 +--- a/linux-user/syscall.c ++++ b/linux-user/syscall.c +@@ -5399,6 +5399,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, + case TARGET_NR_gettimeofday: + { + struct timeval tv; ++ if(copy_from_user_timeval(&tv, arg1)) ++ goto efault; + ret = get_errno(gettimeofday(&tv, NULL)); + if (!is_error(ret)) { + if (copy_to_user_timeval(arg1, &tv)) +-- +1.7.1 + diff --git a/app-emulation/qemu-user/files/0.14.1/0007-qemu-cvs-ioctl_debug.patch b/app-emulation/qemu-user/files/0.14.1/0007-qemu-cvs-ioctl_debug.patch new file mode 100644 index 0000000..114d85e --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0007-qemu-cvs-ioctl_debug.patch @@ -0,0 +1,33 @@ +From 1a883714ac7e953bab2bbdeba651d0696f49dd81 Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Tue, 14 Apr 2009 16:26:33 +0200 +Subject: [PATCH 07/17] qemu-cvs-ioctl_debug + +Extends unsupported ioctl debug output. + +Signed-off-by: Ulrich Hecht +--- + linux-user/syscall.c | 7 ++++++- + 1 files changed, 6 insertions(+), 1 deletions(-) + +diff --git a/linux-user/syscall.c b/linux-user/syscall.c +index 92f2aa6..04f77ef 100644 +--- a/linux-user/syscall.c ++++ b/linux-user/syscall.c +@@ -3100,7 +3100,12 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) + ie = ioctl_entries; + for(;;) { + if (ie->target_cmd == 0) { +- gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd); ++ int i; ++ gemu_log("Unsupported ioctl: cmd=0x%04lx (%x)\n", (unsigned long)cmd, (unsigned int)(cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT); ++ for(i=0;ioctl_entries[i].target_cmd;i++) { ++ if((ioctl_entries[i].target_cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) == (cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT))) ++ gemu_log("%p\t->\t%s (%x)\n", (void *)(unsigned long)ioctl_entries[i].host_cmd, ioctl_entries[i].name, (ioctl_entries[i].target_cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT); ++ } + return -TARGET_ENOSYS; + } + if (ie->target_cmd == cmd) +-- +1.7.1 + diff --git a/app-emulation/qemu-user/files/0.14.1/0008-qemu-cvs-ioctl_nodirection.patch b/app-emulation/qemu-user/files/0.14.1/0008-qemu-cvs-ioctl_nodirection.patch new file mode 100644 index 0000000..6d5ffb9 --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0008-qemu-cvs-ioctl_nodirection.patch @@ -0,0 +1,42 @@ +From d03d586aabc9000cabc56de7e327c5b5640f3179 Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Tue, 14 Apr 2009 16:27:36 +0200 +Subject: [PATCH 08/17] qemu-cvs-ioctl_nodirection + +the direction given in the ioctl should be correct so we can assume the +communication is uni-directional. The alsa developers did not like this +concept though and declared ioctls IOC_R and IOC_W even though they were +IOC_RW. + +Signed-off-by: Ulrich Hecht +--- + linux-user/syscall.c | 6 ++++++ + 1 files changed, 6 insertions(+), 0 deletions(-) + +diff --git a/linux-user/syscall.c b/linux-user/syscall.c +index 04f77ef..b51634b 100644 +--- a/linux-user/syscall.c ++++ b/linux-user/syscall.c +@@ -3134,6 +3134,11 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) + arg_type++; + target_size = thunk_type_size(arg_type, 0); + switch(ie->access) { ++ /* FIXME: actually the direction given in the ioctl should be ++ * correct so we can assume the communication is uni-directional. ++ * The alsa developers did not like this concept though and ++ * declared ioctls IOC_R and IOC_W even though they were IOC_RW.*/ ++/* + case IOC_R: + ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); + if (!is_error(ret)) { +@@ -3152,6 +3157,7 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) + unlock_user(argptr, arg, 0); + ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); + break; ++*/ + default: + case IOC_RW: + argptr = lock_user(VERIFY_READ, arg, target_size, 1); +-- +1.7.1 + diff --git a/app-emulation/qemu-user/files/0.14.1/0009-qemu-cvs-sched_getaffinity.patch b/app-emulation/qemu-user/files/0.14.1/0009-qemu-cvs-sched_getaffinity.patch new file mode 100644 index 0000000..105f2a3 --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0009-qemu-cvs-sched_getaffinity.patch @@ -0,0 +1,56 @@ +From 026ee1029cfeb6c802ee715372992fb3c847bd27 Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Tue, 14 Apr 2009 16:30:16 +0200 +Subject: [PATCH 09/17] qemu-cvs-sched_getaffinity + +Implements sched_getaffinity syscall. + +Signed-off-by: Ulrich Hecht +--- + linux-user/syscall.c | 16 ++++++++++++++++ + 1 files changed, 16 insertions(+), 0 deletions(-) + +diff --git a/linux-user/syscall.c b/linux-user/syscall.c +index b51634b..81bf1f0 100644 +--- a/linux-user/syscall.c ++++ b/linux-user/syscall.c +@@ -164,6 +164,7 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ + } + + ++#define __NR_sys_sched_getaffinity __NR_sched_getaffinity + #define __NR_sys_uname __NR_uname + #define __NR_sys_faccessat __NR_faccessat + #define __NR_sys_fchmodat __NR_fchmodat +@@ -223,6 +224,9 @@ _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig) + #if defined(TARGET_NR_tkill) && defined(__NR_tkill) + _syscall2(int,sys_tkill,int,tid,int,sig) + #endif ++#ifdef __NR_sys_sched_getaffinity ++_syscall3(int,sys_sched_getaffinity,pid_t,pid,unsigned int,cpusetsize,void*,mask) ++#endif + #ifdef __NR_exit_group + _syscall1(int,exit_group,int,error_code) + #endif +@@ -7505,6 +7509,18 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, + break; + #endif + #endif ++ ++#ifdef TARGET_NR_sched_getaffinity ++ case TARGET_NR_sched_getaffinity: ++ { ++ cpu_set_t *mask; ++ lock_user_struct(VERIFY_READ, mask, arg3, 1); ++ ret = get_errno(sys_sched_getaffinity((pid_t)arg1, (unsigned int)arg2, mask)); ++ unlock_user_struct(mask, arg3, 0); ++ break; ++ } ++#endif ++ + default: + unimplemented: + gemu_log("qemu: Unsupported syscall: %d\n", num); +-- +1.7.1 + diff --git a/app-emulation/qemu-user/files/0.14.1/0010-qemu-cvs-mmap-amd64.patch b/app-emulation/qemu-user/files/0.14.1/0010-qemu-cvs-mmap-amd64.patch new file mode 100644 index 0000000..cf85e32 --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0010-qemu-cvs-mmap-amd64.patch @@ -0,0 +1,74 @@ +From: Alexander Graf + +When executing 32-bit guest binaries on 64-bit hosts, mmap() can return +a 64-bit pointer. Tell mmap() to always map in 32-bit address space, so +we make 32-bit guest applications happy. + +This is a hack and should not go upstream in its current form! + +Signed-off-by: Alexander Graf +--- + linux-user/mmap.c | 12 ++++++------ + 1 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/linux-user/mmap.c b/linux-user/mmap.c +index 994c02b..e24b63a 100644 +--- a/linux-user/mmap.c ++++ b/linux-user/mmap.c +@@ -169,7 +169,7 @@ static int mmap_frag(abi_ulong real_start, + if (prot1 == 0) { + /* no page was there, so we allocate one */ + void *p = mmap(host_start, qemu_host_page_size, prot, +- flags | MAP_ANONYMOUS, -1, 0); ++ flags | MAP_ANONYMOUS | MAP_32BIT, -1, 0); + if (p == MAP_FAILED) + return -1; + prot1 = prot; +@@ -292,7 +292,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) + * - shmat() with SHM_REMAP flag + */ + ptr = mmap(g2h(addr), size, PROT_NONE, +- MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0); ++ MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE|MAP_32BIT, -1, 0); + + /* ENOMEM, if host address space has no memory */ + if (ptr == MAP_FAILED) { +@@ -454,14 +454,14 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, + especially important if qemu_host_page_size > + qemu_real_host_page_size */ + p = mmap(g2h(mmap_start), +- host_len, prot, flags | MAP_FIXED | MAP_ANONYMOUS, -1, 0); ++ host_len, prot, flags | MAP_FIXED | MAP_ANONYMOUS | MAP_32BIT, -1, 0); + if (p == MAP_FAILED) + goto fail; + /* update start so that it points to the file position at 'offset' */ + host_start = (unsigned long)p; + if (!(flags & MAP_ANONYMOUS)) { + p = mmap(g2h(mmap_start), len, prot, +- flags | MAP_FIXED, fd, host_offset); ++ flags | MAP_FIXED | MAP_32BIT, fd, host_offset); + host_start += offset - host_offset; + } + start = h2g(host_start); +@@ -547,7 +547,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, + else + offset1 = offset + real_start - start; + p = mmap(g2h(real_start), real_end - real_start, +- prot, flags, fd, offset1); ++ prot, flags | MAP_32BIT, fd, offset1); + if (p == MAP_FAILED) + goto fail; + } +@@ -603,7 +603,7 @@ static void mmap_reserve(abi_ulong start, abi_ulong size) + } + if (real_start != real_end) { + mmap(g2h(real_start), real_end - real_start, PROT_NONE, +- MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, ++ MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE | MAP_32BIT, + -1, 0); + } + } +-- +1.6.0.2 + + diff --git a/app-emulation/qemu-user/files/0.14.1/0011-qemu-img-vmdk-scsi.patch b/app-emulation/qemu-user/files/0.14.1/0011-qemu-img-vmdk-scsi.patch new file mode 100644 index 0000000..1902fe6 --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0011-qemu-img-vmdk-scsi.patch @@ -0,0 +1,116 @@ +From 09686f619707ec98e073bf671b0334a2f65934ad Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Tue, 14 Apr 2009 16:37:42 +0200 +Subject: [PATCH 11/17] qemu-img-vmdk-scsi + +Support creation of SCSI VMDK images in qemu-img. + +Signed-off-by: Ulrich Hecht +--- + block.c | 5 ++++- + block/vmdk.c | 7 +++++-- + block_int.h | 2 ++ + qemu-img.c | 8 +++++++- + 4 files changed, 18 insertions(+), 4 deletions(-) + +diff --git a/block.c b/block.c +index b476479..b77f09b 100644 +--- a/block.c ++++ b/block.c +@@ -2792,7 +2792,7 @@ int bdrv_img_create(const char *filename, const char *fmt, + char *options, uint64_t img_size, int flags) + { + QEMUOptionParameter *param = NULL, *create_options = NULL; +- QEMUOptionParameter *backing_fmt, *backing_file; ++ QEMUOptionParameter *backing_fmt, *backing_file, *scsi; + BlockDriverState *bs = NULL; + BlockDriver *drv, *proto_drv; + BlockDriver *backing_drv = NULL; +@@ -2901,6 +2901,9 @@ int bdrv_img_create(const char *filename, const char *fmt, + + printf("Formatting '%s', fmt=%s ", filename, fmt); + print_option_parameters(param); ++ scsi = get_option_parameter(param, BLOCK_OPT_SCSI); ++ if (scsi && scsi->value.n) ++ printf(", SCSI"); + puts(""); + + ret = bdrv_create(drv, filename, param); +diff --git a/block/vmdk.c b/block/vmdk.c +index 8fc9d67..8944173 100644 +--- a/block/vmdk.c ++++ b/block/vmdk.c +@@ -685,7 +685,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) + "ddb.geometry.cylinders = \"%" PRId64 "\"\n" + "ddb.geometry.heads = \"16\"\n" + "ddb.geometry.sectors = \"63\"\n" +- "ddb.adapterType = \"ide\"\n"; ++ "ddb.adapterType = \"%s\"\n"; + char desc[1024]; + const char *real_filename, *temp_str; + int64_t total_size = 0; +@@ -701,6 +701,8 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) + backing_file = options->value.s; + } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) { + flags |= options->value.n ? BLOCK_FLAG_COMPAT6: 0; ++ } else if (!strcmp(options->name, BLOCK_OPT_SCSI)) { ++ flags |= options->value.n ? BLOCK_FLAG_SCSI: 0; + } + options++; + } +@@ -798,7 +800,8 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) + snprintf(desc, sizeof(desc), desc_template, (unsigned int)time(NULL), + total_size, real_filename, + (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4), +- total_size / (int64_t)(63 * 16)); ++ total_size / (int64_t)(63 * 16), ++ flags & BLOCK_FLAG_SCSI ? "lsilogic" : "ide"); + + /* write the descriptor */ + lseek(fd, le64_to_cpu(header.desc_offset) << 9, SEEK_SET); +diff --git a/block_int.h b/block_int.h +index 545ad11..771fd91 100644 +--- a/block_int.h ++++ b/block_int.h +@@ -30,10 +30,12 @@ + + #define BLOCK_FLAG_ENCRYPT 1 + #define BLOCK_FLAG_COMPAT6 4 ++#define BLOCK_FLAG_SCSI 8 + + #define BLOCK_OPT_SIZE "size" + #define BLOCK_OPT_ENCRYPT "encryption" + #define BLOCK_OPT_COMPAT6 "compat6" ++#define BLOCK_OPT_SCSI "scsi" + #define BLOCK_OPT_BACKING_FILE "backing_file" + #define BLOCK_OPT_BACKING_FMT "backing_fmt" + #define BLOCK_OPT_CLUSTER_SIZE "cluster_size" +diff --git a/qemu-img.c b/qemu-img.c +index 4a37358..ed8cc08 100644 +--- a/qemu-img.c ++++ b/qemu-img.c +@@ -572,7 +572,7 @@ static int img_convert(int argc, char **argv) + const uint8_t *buf1; + BlockDriverInfo bdi; + QEMUOptionParameter *param = NULL, *create_options = NULL; +- QEMUOptionParameter *out_baseimg_param; ++ QEMUOptionParameter *out_baseimg_param, *scsi; + char *options = NULL; + const char *snapshot_name = NULL; + +@@ -727,6 +727,12 @@ static int img_convert(int argc, char **argv) + } + } + ++ if ((scsi = get_option_parameter(param, BLOCK_OPT_SCSI)) && scsi->value.n && strcmp(drv->format_name, "vmdk")) { ++ error_report("SCSI devices not supported for this file format"); ++ ret = -1; ++ goto out; ++ } ++ + /* Create the new image */ + ret = bdrv_create(drv, out_filename, param); + if (ret < 0) { +-- +1.7.1 + diff --git a/app-emulation/qemu-user/files/0.14.1/0012-qemu-nonvoid_return.patch b/app-emulation/qemu-user/files/0.14.1/0012-qemu-nonvoid_return.patch new file mode 100644 index 0000000..1daf047 --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0012-qemu-nonvoid_return.patch @@ -0,0 +1,40 @@ +From 75c51f45c127ebe4f549041aae98f510480429ae Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Tue, 14 Apr 2009 16:38:20 +0200 +Subject: [PATCH 12/17] qemu-nonvoid_return + +Squelches GCC warnings about undefined return values. + +Signed-off-by: Ulrich Hecht +--- + hw/mpcore.c | 1 + + target-m68k/translate.c | 1 + + 2 files changed, 2 insertions(+), 0 deletions(-) + +diff --git a/hw/mpcore.c b/hw/mpcore.c +index fc05215..7bdb495 100644 +--- a/hw/mpcore.c ++++ b/hw/mpcore.c +@@ -104,6 +104,7 @@ static uint32_t mpcore_timer_read(mpcore_timer_state *s, int offset) + default: + return 0; + } ++ return 0; + } + + static void mpcore_timer_write(mpcore_timer_state *s, int offset, +diff --git a/target-m68k/translate.c b/target-m68k/translate.c +index 6f72a2b..7d9492b 100644 +--- a/target-m68k/translate.c ++++ b/target-m68k/translate.c +@@ -440,6 +440,7 @@ static inline int opsize_bytes(int opsize) + qemu_assert(0, "bad operand size"); + return 0; + } ++ return 0; + } + + /* Assign value to a register. If the width is less than the register width +-- +1.7.1 + diff --git a/app-emulation/qemu-user/files/0.14.1/0013-i386-linux-user-NPTL-support.patch b/app-emulation/qemu-user/files/0.14.1/0013-i386-linux-user-NPTL-support.patch new file mode 100644 index 0000000..4666729 --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0013-i386-linux-user-NPTL-support.patch @@ -0,0 +1,64 @@ +From f44ecd4fcdb8e02e6bd58201a81f047d1e109508 Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Thu, 16 Apr 2009 15:14:12 +0200 +Subject: [PATCH 13/17] i386-linux-user NPTL support + +Makes NPTL binaries run by implementing TLS. + +Signed-off-by: Ulrich Hecht +--- + configure | 1 + + linux-user/syscall.c | 16 ++++++++++++++-- + 2 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/configure b/configure +index 598e8e1..95de763 100755 +--- a/configure ++++ b/configure +@@ -2910,6 +2910,7 @@ TARGET_ABI_DIR="" + case "$target_arch2" in + i386) + target_phys_bits=32 ++ target_nptl="yes" + ;; + x86_64) + TARGET_BASE_ARCH=i386 +diff --git a/linux-user/syscall.c b/linux-user/syscall.c +index 81bf1f0..1a98433 100644 +--- a/linux-user/syscall.c ++++ b/linux-user/syscall.c +@@ -3792,8 +3792,14 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, + ts->child_tidptr = child_tidptr; + } + +- if (nptl_flags & CLONE_SETTLS) ++ if (nptl_flags & CLONE_SETTLS) { ++#if defined(TARGET_I386) && defined(TARGET_ABI32) ++ do_set_thread_area(new_env, newtls); ++ cpu_x86_load_seg(new_env, R_GS, new_env->segs[R_GS].selector); ++#else + cpu_set_tls (new_env, newtls); ++#endif ++ } + + /* Grab a mutex so that thread setup appears atomic. */ + pthread_mutex_lock(&clone_lock); +@@ -3867,8 +3873,14 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, + if (flags & CLONE_PARENT_SETTID) + put_user_u32(gettid(), parent_tidptr); + ts = (TaskState *)env->opaque; +- if (flags & CLONE_SETTLS) ++ if (flags & CLONE_SETTLS) { ++#if defined(TARGET_I386) && defined(TARGET_ABI32) ++ do_set_thread_area(env, newtls); ++ cpu_x86_load_seg(env, R_GS, env->segs[R_GS].selector); ++#else + cpu_set_tls (env, newtls); ++#endif ++ } + if (flags & CLONE_CHILD_CLEARTID) + ts->child_tidptr = child_tidptr; + #endif +-- +1.7.1 + diff --git a/app-emulation/qemu-user/files/0.14.1/0015-S-390-support.patch b/app-emulation/qemu-user/files/0.14.1/0015-S-390-support.patch new file mode 100644 index 0000000..564583d --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0015-S-390-support.patch @@ -0,0 +1,6757 @@ +From c0218c03294d692613596cdf361badaa63a700d6 Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Tue, 24 Aug 2010 13:23:23 +0200 +Subject: [PATCH 15/17] S/390 support + +--- + configure | 2 + + cpu-all.h | 2 +- + cpu-defs.h | 8 + + cpu-exec.c | 14 +- + default-configs/s390x-linux-user.mak | 1 + + disas.c | 3 + + linux-user/elfload.c | 18 + + linux-user/main.c | 89 ++ + linux-user/s390x/syscall.h | 25 + + linux-user/s390x/syscall_nr.h | 348 +++++ + linux-user/s390x/target_signal.h | 26 + + linux-user/s390x/termbits.h | 283 ++++ + linux-user/signal.c | 314 ++++ + linux-user/syscall.c | 144 ++- + linux-user/syscall_defs.h | 56 +- + s390x.ld | 194 +++ + scripts/qemu-binfmt-conf.sh | 5 +- + target-s390x/cpu.h | 29 +- + target-s390x/exec.h | 8 + + target-s390x/helper.c | 25 +- + target-s390x/helpers.h | 127 ++ + target-s390x/op_helper.c | 1607 +++++++++++++++++++ + target-s390x/translate.c | 2795 ++++++++++++++++++++++++++++++++++ + tcg/tcg-op.h | 12 + + tcg/tcg-opc.h | 2 + + tcg/tcg.c | 6 + + 26 files changed, 6102 insertions(+), 41 deletions(-) + create mode 100644 default-configs/s390x-linux-user.mak + create mode 100644 linux-user/s390x/syscall.h + create mode 100644 linux-user/s390x/syscall_nr.h + create mode 100644 linux-user/s390x/target_signal.h + create mode 100644 linux-user/s390x/termbits.h + create mode 100644 s390x.ld + create mode 100644 target-s390x/helpers.h + +Index: qemu-0.14.1/configure +=================================================================== +--- qemu-0.14.1.orig/configure ++++ qemu-0.14.1/configure +@@ -1020,6 +1020,7 @@ sh4eb-linux-user \ + sparc-linux-user \ + sparc64-linux-user \ + sparc32plus-linux-user \ ++s390x-linux-user \ + " + fi + # the following are Darwin specific +@@ -3008,6 +3009,7 @@ case "$target_arch2" in + target_phys_bits=64 + ;; + s390x) ++ target_nptl="yes" + target_phys_bits=64 + ;; + *) +Index: qemu-0.14.1/cpu-all.h +=================================================================== +--- qemu-0.14.1.orig/cpu-all.h ++++ qemu-0.14.1/cpu-all.h +@@ -138,7 +138,7 @@ typedef union { + uint64_t ll; + } CPU_DoubleU; + +-#ifdef TARGET_SPARC ++#if defined(TARGET_SPARC) || defined(TARGET_S390X) + typedef union { + float128 q; + #if defined(HOST_WORDS_BIGENDIAN) \ +Index: qemu-0.14.1/cpu-defs.h +=================================================================== +--- qemu-0.14.1.orig/cpu-defs.h ++++ qemu-0.14.1/cpu-defs.h +@@ -148,6 +148,13 @@ typedef struct CPUWatchpoint { + } CPUWatchpoint; + + #define CPU_TEMP_BUF_NLONGS 128 ++ ++#ifdef CONFIG_USER_ONLY ++#define MULTITHREAD uint32_t multithreaded; ++#else ++#define MULTITHREAD ++#endif ++ + #define CPU_COMMON \ + struct TranslationBlock *current_tb; /* currently executing TB */ \ + /* soft mmu support */ \ +@@ -160,6 +167,7 @@ typedef struct CPUWatchpoint { + memory was accessed */ \ + uint32_t halted; /* Nonzero if the CPU is in suspend state */ \ + uint32_t interrupt_request; \ ++ MULTITHREAD /* needs locking when accessing TBs */ \ + volatile sig_atomic_t exit_request; \ + CPU_COMMON_TLB \ + struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \ +Index: qemu-0.14.1/cpu-exec.c +=================================================================== +--- qemu-0.14.1.orig/cpu-exec.c ++++ qemu-0.14.1/cpu-exec.c +@@ -229,6 +229,9 @@ int cpu_exec(CPUState *env1) + TranslationBlock *tb; + uint8_t *tc_ptr; + unsigned long next_tb; ++#ifdef CONFIG_USER_ONLY ++ uint32_t multithreaded; ++#endif + + if (cpu_halted(env1) == EXCP_HALTED) + return EXCP_HALTED; +@@ -573,7 +576,11 @@ int cpu_exec(CPUState *env1) + #endif + } + #endif /* DEBUG_DISAS || CONFIG_DEBUG_EXEC */ +- spin_lock(&tb_lock); ++#ifdef CONFIG_USER_ONLY ++ multithreaded = env->multithreaded; ++ if (multithreaded) ++#endif ++ spin_lock(&tb_lock); + tb = tb_find_fast(); + /* Note: we do it here to avoid a gcc bug on Mac OS X when + doing it in tb_find_slow */ +@@ -595,7 +602,10 @@ int cpu_exec(CPUState *env1) + if (next_tb != 0 && tb->page_addr[1] == -1) { + tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb); + } +- spin_unlock(&tb_lock); ++#ifdef CONFIG_USER_ONLY ++ if (multithreaded) ++#endif ++ spin_unlock(&tb_lock); + + /* cpu_interrupt might be called while translating the + TB, but before it is linked into a potentially +Index: qemu-0.14.1/default-configs/s390x-linux-user.mak +=================================================================== +--- /dev/null ++++ qemu-0.14.1/default-configs/s390x-linux-user.mak +@@ -0,0 +1 @@ ++# Default configuration for s390x-linux-user +Index: qemu-0.14.1/disas.c +=================================================================== +--- qemu-0.14.1.orig/disas.c ++++ qemu-0.14.1/disas.c +@@ -215,6 +215,9 @@ void target_disas(FILE *out, target_ulon + disasm_info.mach = bfd_mach_cris_v32; + print_insn = print_insn_crisv32; + } ++#elif defined(TARGET_S390X) ++ disasm_info.mach = bfd_mach_s390_64; ++ print_insn = print_insn_s390; + #elif defined(TARGET_MICROBLAZE) + disasm_info.mach = bfd_arch_microblaze; + print_insn = print_insn_microblaze; +Index: qemu-0.14.1/linux-user/elfload.c +=================================================================== +--- qemu-0.14.1.orig/linux-user/elfload.c ++++ qemu-0.14.1/linux-user/elfload.c +@@ -793,6 +793,24 @@ static inline void init_thread(struct ta + + #endif /* TARGET_ALPHA */ + ++#ifdef TARGET_S390X ++ ++#define ELF_START_MMAP (0x20000000000ULL) ++ ++#define elf_check_arch(x) ( (x) == ELF_ARCH ) ++ ++#define ELF_CLASS ELFCLASS64 ++#define ELF_DATA ELFDATA2MSB ++#define ELF_ARCH EM_S390 ++ ++static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) ++{ ++ regs->psw.addr = infop->entry; ++ regs->gprs[15] = infop->start_stack; ++} ++ ++#endif /* TARGET_S390X */ ++ + #ifndef ELF_PLATFORM + #define ELF_PLATFORM (NULL) + #endif +Index: qemu-0.14.1/linux-user/main.c +=================================================================== +--- qemu-0.14.1.orig/linux-user/main.c ++++ qemu-0.14.1/linux-user/main.c +@@ -2624,6 +2624,86 @@ void cpu_loop (CPUState *env) + } + #endif /* TARGET_ALPHA */ + ++#ifdef TARGET_S390X ++void cpu_loop(CPUS390XState *env) ++{ ++ int trapnr; ++ target_siginfo_t info; ++ ++ while (1) { ++ trapnr = cpu_s390x_exec (env); ++ ++ if ((trapnr & 0xffff0000) == EXCP_EXECUTE_SVC) { ++ int n = trapnr & 0xffff; ++ env->regs[2] = do_syscall(env, n, ++ env->regs[2], ++ env->regs[3], ++ env->regs[4], ++ env->regs[5], ++ env->regs[6], ++ env->regs[7]); ++ } ++ else switch (trapnr) { ++ case EXCP_INTERRUPT: ++ /* just indicate that signals should be handled asap */ ++ break; ++ case EXCP_DEBUG: ++ { ++ int sig; ++ ++ sig = gdb_handlesig (env, TARGET_SIGTRAP); ++ if (sig) { ++ info.si_signo = sig; ++ info.si_errno = 0; ++ info.si_code = TARGET_TRAP_BRKPT; ++ queue_signal(env, info.si_signo, &info); ++ } ++ } ++ break; ++ case EXCP_SVC: ++ { ++ int n = ldub(env->psw.addr - 1); ++ if (!n) n = env->regs[1]; /* syscalls > 255 */ ++ env->regs[2] = do_syscall(env, n, ++ env->regs[2], ++ env->regs[3], ++ env->regs[4], ++ env->regs[5], ++ env->regs[6], ++ env->regs[7]); ++ } ++ break; ++ case EXCP_ADDR: ++ { ++ info.si_signo = SIGSEGV; ++ info.si_errno = 0; ++ /* XXX: check env->error_code */ ++ info.si_code = TARGET_SEGV_MAPERR; ++ info._sifields._sigfault._addr = env->__excp_addr; ++ queue_signal(env, info.si_signo, &info); ++ } ++ break; ++ case EXCP_SPEC: ++ { ++ fprintf(stderr,"specification exception insn 0x%08x%04x\n", ldl(env->psw.addr), lduw(env->psw.addr + 4)); ++ info.si_signo = SIGILL; ++ info.si_errno = 0; ++ info.si_code = TARGET_ILL_ILLOPC; ++ info._sifields._sigfault._addr = env->__excp_addr; ++ queue_signal(env, info.si_signo, &info); ++ } ++ break; ++ default: ++ printf ("Unhandled trap: 0x%x\n", trapnr); ++ cpu_dump_state(env, stderr, fprintf, 0); ++ exit (1); ++ } ++ process_pending_signals (env); ++ } ++} ++ ++#endif /* TARGET_S390X */ ++ + static void usage(void) + { + printf("qemu-" TARGET_ARCH " version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n" +@@ -3354,6 +3434,15 @@ int main(int argc, char **argv, char **e + env->regs[15] = regs->acr; + env->pc = regs->erp; + } ++#elif defined(TARGET_S390X) ++ { ++ int i; ++ for (i = 0; i < 16; i++) { ++ env->regs[i] = regs->gprs[i]; ++ } ++ env->psw.mask = regs->psw.mask; ++ env->psw.addr = regs->psw.addr; ++ } + #else + #error unsupported target CPU + #endif +Index: qemu-0.14.1/linux-user/s390x/syscall.h +=================================================================== +--- /dev/null ++++ qemu-0.14.1/linux-user/s390x/syscall.h +@@ -0,0 +1,25 @@ ++/* this typedef defines how a Program Status Word looks like */ ++typedef struct ++{ ++ abi_ulong mask; ++ abi_ulong addr; ++} __attribute__ ((aligned(8))) target_psw_t; ++ ++/* ++ * The pt_regs struct defines the way the registers are stored on ++ * the stack during a system call. ++ */ ++ ++#define TARGET_NUM_GPRS 16 ++ ++struct target_pt_regs ++{ ++ abi_ulong args[1]; ++ target_psw_t psw; ++ abi_ulong gprs[TARGET_NUM_GPRS]; ++ abi_ulong orig_gpr2; ++ unsigned short ilc; ++ unsigned short trap; ++}; ++ ++#define UNAME_MACHINE "s390x" +Index: qemu-0.14.1/linux-user/s390x/syscall_nr.h +=================================================================== +--- /dev/null ++++ qemu-0.14.1/linux-user/s390x/syscall_nr.h +@@ -0,0 +1,348 @@ ++/* ++ * This file contains the system call numbers. ++ */ ++ ++#define TARGET_NR_exit 1 ++#define TARGET_NR_fork 2 ++#define TARGET_NR_read 3 ++#define TARGET_NR_write 4 ++#define TARGET_NR_open 5 ++#define TARGET_NR_close 6 ++#define TARGET_NR_restart_syscall 7 ++#define TARGET_NR_creat 8 ++#define TARGET_NR_link 9 ++#define TARGET_NR_unlink 10 ++#define TARGET_NR_execve 11 ++#define TARGET_NR_chdir 12 ++#define TARGET_NR_mknod 14 ++#define TARGET_NR_chmod 15 ++#define TARGET_NR_lseek 19 ++#define TARGET_NR_getpid 20 ++#define TARGET_NR_mount 21 ++#define TARGET_NR_umount 22 ++#define TARGET_NR_ptrace 26 ++#define TARGET_NR_alarm 27 ++#define TARGET_NR_pause 29 ++#define TARGET_NR_utime 30 ++#define TARGET_NR_access 33 ++#define TARGET_NR_nice 34 ++#define TARGET_NR_sync 36 ++#define TARGET_NR_kill 37 ++#define TARGET_NR_rename 38 ++#define TARGET_NR_mkdir 39 ++#define TARGET_NR_rmdir 40 ++#define TARGET_NR_dup 41 ++#define TARGET_NR_pipe 42 ++#define TARGET_NR_times 43 ++#define TARGET_NR_brk 45 ++#define TARGET_NR_signal 48 ++#define TARGET_NR_acct 51 ++#define TARGET_NR_umount2 52 ++#define TARGET_NR_ioctl 54 ++#define TARGET_NR_fcntl 55 ++#define TARGET_NR_setpgid 57 ++#define TARGET_NR_umask 60 ++#define TARGET_NR_chroot 61 ++#define TARGET_NR_ustat 62 ++#define TARGET_NR_dup2 63 ++#define TARGET_NR_getppid 64 ++#define TARGET_NR_getpgrp 65 ++#define TARGET_NR_setsid 66 ++#define TARGET_NR_sigaction 67 ++#define TARGET_NR_sigsuspend 72 ++#define TARGET_NR_sigpending 73 ++#define TARGET_NR_sethostname 74 ++#define TARGET_NR_setrlimit 75 ++#define TARGET_NR_getrusage 77 ++#define TARGET_NR_gettimeofday 78 ++#define TARGET_NR_settimeofday 79 ++#define TARGET_NR_symlink 83 ++#define TARGET_NR_readlink 85 ++#define TARGET_NR_uselib 86 ++#define TARGET_NR_swapon 87 ++#define TARGET_NR_reboot 88 ++#define TARGET_NR_readdir 89 ++#define TARGET_NR_mmap 90 ++#define TARGET_NR_munmap 91 ++#define TARGET_NR_truncate 92 ++#define TARGET_NR_ftruncate 93 ++#define TARGET_NR_fchmod 94 ++#define TARGET_NR_getpriority 96 ++#define TARGET_NR_setpriority 97 ++#define TARGET_NR_statfs 99 ++#define TARGET_NR_fstatfs 100 ++#define TARGET_NR_socketcall 102 ++#define TARGET_NR_syslog 103 ++#define TARGET_NR_setitimer 104 ++#define TARGET_NR_getitimer 105 ++#define TARGET_NR_stat 106 ++#define TARGET_NR_lstat 107 ++#define TARGET_NR_fstat 108 ++#define TARGET_NR_lookup_dcookie 110 ++#define TARGET_NR_vhangup 111 ++#define TARGET_NR_idle 112 ++#define TARGET_NR_wait4 114 ++#define TARGET_NR_swapoff 115 ++#define TARGET_NR_sysinfo 116 ++#define TARGET_NR_ipc 117 ++#define TARGET_NR_fsync 118 ++#define TARGET_NR_sigreturn 119 ++#define TARGET_NR_clone 120 ++#define TARGET_NR_setdomainname 121 ++#define TARGET_NR_uname 122 ++#define TARGET_NR_adjtimex 124 ++#define TARGET_NR_mprotect 125 ++#define TARGET_NR_sigprocmask 126 ++#define TARGET_NR_create_module 127 ++#define TARGET_NR_init_module 128 ++#define TARGET_NR_delete_module 129 ++#define TARGET_NR_get_kernel_syms 130 ++#define TARGET_NR_quotactl 131 ++#define TARGET_NR_getpgid 132 ++#define TARGET_NR_fchdir 133 ++#define TARGET_NR_bdflush 134 ++#define TARGET_NR_sysfs 135 ++#define TARGET_NR_personality 136 ++#define TARGET_NR_afs_syscall 137 /* Syscall for Andrew File System */ ++#define TARGET_NR_getdents 141 ++#define TARGET_NR_flock 143 ++#define TARGET_NR_msync 144 ++#define TARGET_NR_readv 145 ++#define TARGET_NR_writev 146 ++#define TARGET_NR_getsid 147 ++#define TARGET_NR_fdatasync 148 ++#define TARGET_NR__sysctl 149 ++#define TARGET_NR_mlock 150 ++#define TARGET_NR_munlock 151 ++#define TARGET_NR_mlockall 152 ++#define TARGET_NR_munlockall 153 ++#define TARGET_NR_sched_setparam 154 ++#define TARGET_NR_sched_getparam 155 ++#define TARGET_NR_sched_setscheduler 156 ++#define TARGET_NR_sched_getscheduler 157 ++#define TARGET_NR_sched_yield 158 ++#define TARGET_NR_sched_get_priority_max 159 ++#define TARGET_NR_sched_get_priority_min 160 ++#define TARGET_NR_sched_rr_get_interval 161 ++#define TARGET_NR_nanosleep 162 ++#define TARGET_NR_mremap 163 ++#define TARGET_NR_query_module 167 ++#define TARGET_NR_poll 168 ++#define TARGET_NR_nfsservctl 169 ++#define TARGET_NR_prctl 172 ++#define TARGET_NR_rt_sigreturn 173 ++#define TARGET_NR_rt_sigaction 174 ++#define TARGET_NR_rt_sigprocmask 175 ++#define TARGET_NR_rt_sigpending 176 ++#define TARGET_NR_rt_sigtimedwait 177 ++#define TARGET_NR_rt_sigqueueinfo 178 ++#define TARGET_NR_rt_sigsuspend 179 ++#define TARGET_NR_pread64 180 ++#define TARGET_NR_pwrite64 181 ++#define TARGET_NR_getcwd 183 ++#define TARGET_NR_capget 184 ++#define TARGET_NR_capset 185 ++#define TARGET_NR_sigaltstack 186 ++#define TARGET_NR_sendfile 187 ++#define TARGET_NR_getpmsg 188 ++#define TARGET_NR_putpmsg 189 ++#define TARGET_NR_vfork 190 ++#define TARGET_NR_pivot_root 217 ++#define TARGET_NR_mincore 218 ++#define TARGET_NR_madvise 219 ++#define TARGET_NR_getdents64 220 ++#define TARGET_NR_readahead 222 ++#define TARGET_NR_setxattr 224 ++#define TARGET_NR_lsetxattr 225 ++#define TARGET_NR_fsetxattr 226 ++#define TARGET_NR_getxattr 227 ++#define TARGET_NR_lgetxattr 228 ++#define TARGET_NR_fgetxattr 229 ++#define TARGET_NR_listxattr 230 ++#define TARGET_NR_llistxattr 231 ++#define TARGET_NR_flistxattr 232 ++#define TARGET_NR_removexattr 233 ++#define TARGET_NR_lremovexattr 234 ++#define TARGET_NR_fremovexattr 235 ++#define TARGET_NR_gettid 236 ++#define TARGET_NR_tkill 237 ++#define TARGET_NR_futex 238 ++#define TARGET_NR_sched_setaffinity 239 ++#define TARGET_NR_sched_getaffinity 240 ++#define TARGET_NR_tgkill 241 ++/* Number 242 is reserved for tux */ ++#define TARGET_NR_io_setup 243 ++#define TARGET_NR_io_destroy 244 ++#define TARGET_NR_io_getevents 245 ++#define TARGET_NR_io_submit 246 ++#define TARGET_NR_io_cancel 247 ++#define TARGET_NR_exit_group 248 ++#define TARGET_NR_epoll_create 249 ++#define TARGET_NR_epoll_ctl 250 ++#define TARGET_NR_epoll_wait 251 ++#define TARGET_NR_set_tid_address 252 ++#define TARGET_NR_fadvise64 253 ++#define TARGET_NR_timer_create 254 ++#define TARGET_NR_timer_settime (TARGET_NR_timer_create+1) ++#define TARGET_NR_timer_gettime (TARGET_NR_timer_create+2) ++#define TARGET_NR_timer_getoverrun (TARGET_NR_timer_create+3) ++#define TARGET_NR_timer_delete (TARGET_NR_timer_create+4) ++#define TARGET_NR_clock_settime (TARGET_NR_timer_create+5) ++#define TARGET_NR_clock_gettime (TARGET_NR_timer_create+6) ++#define TARGET_NR_clock_getres (TARGET_NR_timer_create+7) ++#define TARGET_NR_clock_nanosleep (TARGET_NR_timer_create+8) ++/* Number 263 is reserved for vserver */ ++#define TARGET_NR_statfs64 265 ++#define TARGET_NR_fstatfs64 266 ++#define TARGET_NR_remap_file_pages 267 ++/* Number 268 is reserved for new sys_mbind */ ++/* Number 269 is reserved for new sys_get_mempolicy */ ++/* Number 270 is reserved for new sys_set_mempolicy */ ++#define TARGET_NR_mq_open 271 ++#define TARGET_NR_mq_unlink 272 ++#define TARGET_NR_mq_timedsend 273 ++#define TARGET_NR_mq_timedreceive 274 ++#define TARGET_NR_mq_notify 275 ++#define TARGET_NR_mq_getsetattr 276 ++#define TARGET_NR_kexec_load 277 ++#define TARGET_NR_add_key 278 ++#define TARGET_NR_request_key 279 ++#define TARGET_NR_keyctl 280 ++#define TARGET_NR_waitid 281 ++#define TARGET_NR_ioprio_set 282 ++#define TARGET_NR_ioprio_get 283 ++#define TARGET_NR_inotify_init 284 ++#define TARGET_NR_inotify_add_watch 285 ++#define TARGET_NR_inotify_rm_watch 286 ++/* Number 287 is reserved for new sys_migrate_pages */ ++#define TARGET_NR_openat 288 ++#define TARGET_NR_mkdirat 289 ++#define TARGET_NR_mknodat 290 ++#define TARGET_NR_fchownat 291 ++#define TARGET_NR_futimesat 292 ++#define TARGET_NR_unlinkat 294 ++#define TARGET_NR_renameat 295 ++#define TARGET_NR_linkat 296 ++#define TARGET_NR_symlinkat 297 ++#define TARGET_NR_readlinkat 298 ++#define TARGET_NR_fchmodat 299 ++#define TARGET_NR_faccessat 300 ++#define TARGET_NR_pselect6 301 ++#define TARGET_NR_ppoll 302 ++#define TARGET_NR_unshare 303 ++#define TARGET_NR_set_robust_list 304 ++#define TARGET_NR_get_robust_list 305 ++#define TARGET_NR_splice 306 ++#define TARGET_NR_sync_file_range 307 ++#define TARGET_NR_tee 308 ++#define TARGET_NR_vmsplice 309 ++/* Number 310 is reserved for new sys_move_pages */ ++#define TARGET_NR_getcpu 311 ++#define TARGET_NR_epoll_pwait 312 ++#define TARGET_NR_utimes 313 ++#define TARGET_NR_fallocate 314 ++#define TARGET_NR_utimensat 315 ++#define TARGET_NR_signalfd 316 ++#define TARGET_NR_timerfd 317 ++#define TARGET_NR_eventfd 318 ++#define TARGET_NR_timerfd_create 319 ++#define TARGET_NR_timerfd_settime 320 ++#define TARGET_NR_timerfd_gettime 321 ++#define TARGET_NR_signalfd4 322 ++#define TARGET_NR_eventfd2 323 ++#define TARGET_NR_inotify_init1 324 ++#define TARGET_NR_pipe2 325 ++#define TARGET_NR_dup3 326 ++#define TARGET_NR_epoll_create1 327 ++#define NR_syscalls 328 ++ ++/* ++ * There are some system calls that are not present on 64 bit, some ++ * have a different name although they do the same (e.g. TARGET_NR_chown32 ++ * is TARGET_NR_chown on 64 bit). ++ */ ++#ifndef TARGET_S390X ++ ++#define TARGET_NR_time 13 ++#define TARGET_NR_lchown 16 ++#define TARGET_NR_setuid 23 ++#define TARGET_NR_getuid 24 ++#define TARGET_NR_stime 25 ++#define TARGET_NR_setgid 46 ++#define TARGET_NR_getgid 47 ++#define TARGET_NR_geteuid 49 ++#define TARGET_NR_getegid 50 ++#define TARGET_NR_setreuid 70 ++#define TARGET_NR_setregid 71 ++#define TARGET_NR_getrlimit 76 ++#define TARGET_NR_getgroups 80 ++#define TARGET_NR_setgroups 81 ++#define TARGET_NR_fchown 95 ++#define TARGET_NR_ioperm 101 ++#define TARGET_NR_setfsuid 138 ++#define TARGET_NR_setfsgid 139 ++#define TARGET_NR__llseek 140 ++#define TARGET_NR__newselect 142 ++#define TARGET_NR_setresuid 164 ++#define TARGET_NR_getresuid 165 ++#define TARGET_NR_setresgid 170 ++#define TARGET_NR_getresgid 171 ++#define TARGET_NR_chown 182 ++#define TARGET_NR_ugetrlimit 191 /* SuS compliant getrlimit */ ++#define TARGET_NR_mmap2 192 ++#define TARGET_NR_truncate64 193 ++#define TARGET_NR_ftruncate64 194 ++#define TARGET_NR_stat64 195 ++#define TARGET_NR_lstat64 196 ++#define TARGET_NR_fstat64 197 ++#define TARGET_NR_lchown32 198 ++#define TARGET_NR_getuid32 199 ++#define TARGET_NR_getgid32 200 ++#define TARGET_NR_geteuid32 201 ++#define TARGET_NR_getegid32 202 ++#define TARGET_NR_setreuid32 203 ++#define TARGET_NR_setregid32 204 ++#define TARGET_NR_getgroups32 205 ++#define TARGET_NR_setgroups32 206 ++#define TARGET_NR_fchown32 207 ++#define TARGET_NR_setresuid32 208 ++#define TARGET_NR_getresuid32 209 ++#define TARGET_NR_setresgid32 210 ++#define TARGET_NR_getresgid32 211 ++#define TARGET_NR_chown32 212 ++#define TARGET_NR_setuid32 213 ++#define TARGET_NR_setgid32 214 ++#define TARGET_NR_setfsuid32 215 ++#define TARGET_NR_setfsgid32 216 ++#define TARGET_NR_fcntl64 221 ++#define TARGET_NR_sendfile64 223 ++#define TARGET_NR_fadvise64_64 264 ++#define TARGET_NR_fstatat64 293 ++ ++#else ++ ++#define TARGET_NR_select 142 ++#define TARGET_NR_getrlimit 191 /* SuS compliant getrlimit */ ++#define TARGET_NR_lchown 198 ++#define TARGET_NR_getuid 199 ++#define TARGET_NR_getgid 200 ++#define TARGET_NR_geteuid 201 ++#define TARGET_NR_getegid 202 ++#define TARGET_NR_setreuid 203 ++#define TARGET_NR_setregid 204 ++#define TARGET_NR_getgroups 205 ++#define TARGET_NR_setgroups 206 ++#define TARGET_NR_fchown 207 ++#define TARGET_NR_setresuid 208 ++#define TARGET_NR_getresuid 209 ++#define TARGET_NR_setresgid 210 ++#define TARGET_NR_getresgid 211 ++#define TARGET_NR_chown 212 ++#define TARGET_NR_setuid 213 ++#define TARGET_NR_setgid 214 ++#define TARGET_NR_setfsuid 215 ++#define TARGET_NR_setfsgid 216 ++#define TARGET_NR_newfstatat 293 ++ ++#endif ++ +Index: qemu-0.14.1/linux-user/s390x/target_signal.h +=================================================================== +--- /dev/null ++++ qemu-0.14.1/linux-user/s390x/target_signal.h +@@ -0,0 +1,26 @@ ++#ifndef TARGET_SIGNAL_H ++#define TARGET_SIGNAL_H ++ ++#include "cpu.h" ++ ++typedef struct target_sigaltstack { ++ abi_ulong ss_sp; ++ int ss_flags; ++ abi_ulong ss_size; ++} target_stack_t; ++ ++/* ++ * sigaltstack controls ++ */ ++#define TARGET_SS_ONSTACK 1 ++#define TARGET_SS_DISABLE 2 ++ ++#define TARGET_MINSIGSTKSZ 2048 ++#define TARGET_SIGSTKSZ 8192 ++ ++static inline abi_ulong get_sp_from_cpustate(CPUS390XState *state) ++{ ++ return state->regs[15]; ++} ++ ++#endif /* TARGET_SIGNAL_H */ +Index: qemu-0.14.1/linux-user/s390x/termbits.h +=================================================================== +--- /dev/null ++++ qemu-0.14.1/linux-user/s390x/termbits.h +@@ -0,0 +1,283 @@ ++/* ++ * include/asm-s390/termbits.h ++ * ++ * S390 version ++ * ++ * Derived from "include/asm-i386/termbits.h" ++ */ ++ ++#define TARGET_NCCS 19 ++struct target_termios { ++ unsigned int c_iflag; /* input mode flags */ ++ unsigned int c_oflag; /* output mode flags */ ++ unsigned int c_cflag; /* control mode flags */ ++ unsigned int c_lflag; /* local mode flags */ ++ unsigned char c_line; /* line discipline */ ++ unsigned char c_cc[TARGET_NCCS]; /* control characters */ ++}; ++ ++struct target_termios2 { ++ unsigned int c_iflag; /* input mode flags */ ++ unsigned int c_oflag; /* output mode flags */ ++ unsigned int c_cflag; /* control mode flags */ ++ unsigned int c_lflag; /* local mode flags */ ++ unsigned char c_line; /* line discipline */ ++ unsigned char c_cc[TARGET_NCCS]; /* control characters */ ++ unsigned int c_ispeed; /* input speed */ ++ unsigned int c_ospeed; /* output speed */ ++}; ++ ++struct target_ktermios { ++ unsigned int c_iflag; /* input mode flags */ ++ unsigned int c_oflag; /* output mode flags */ ++ unsigned int c_cflag; /* control mode flags */ ++ unsigned int c_lflag; /* local mode flags */ ++ unsigned char c_line; /* line discipline */ ++ unsigned char c_cc[TARGET_NCCS]; /* control characters */ ++ unsigned int c_ispeed; /* input speed */ ++ unsigned int c_ospeed; /* output speed */ ++}; ++ ++/* c_cc characters */ ++#define TARGET_VINTR 0 ++#define TARGET_VQUIT 1 ++#define TARGET_VERASE 2 ++#define TARGET_VKILL 3 ++#define TARGET_VEOF 4 ++#define TARGET_VTIME 5 ++#define TARGET_VMIN 6 ++#define TARGET_VSWTC 7 ++#define TARGET_VSTART 8 ++#define TARGET_VSTOP 9 ++#define TARGET_VSUSP 10 ++#define TARGET_VEOL 11 ++#define TARGET_VREPRINT 12 ++#define TARGET_VDISCARD 13 ++#define TARGET_VWERASE 14 ++#define TARGET_VLNEXT 15 ++#define TARGET_VEOL2 16 ++ ++/* c_iflag bits */ ++#define TARGET_IGNBRK 0000001 ++#define TARGET_BRKINT 0000002 ++#define TARGET_IGNPAR 0000004 ++#define TARGET_PARMRK 0000010 ++#define TARGET_INPCK 0000020 ++#define TARGET_ISTRIP 0000040 ++#define TARGET_INLCR 0000100 ++#define TARGET_IGNCR 0000200 ++#define TARGET_ICRNL 0000400 ++#define TARGET_IUCLC 0001000 ++#define TARGET_IXON 0002000 ++#define TARGET_IXANY 0004000 ++#define TARGET_IXOFF 0010000 ++#define TARGET_IMAXBEL 0020000 ++#define TARGET_IUTF8 0040000 ++ ++/* c_oflag bits */ ++#define TARGET_OPOST 0000001 ++#define TARGET_OLCUC 0000002 ++#define TARGET_ONLCR 0000004 ++#define TARGET_OCRNL 0000010 ++#define TARGET_ONOCR 0000020 ++#define TARGET_ONLRET 0000040 ++#define TARGET_OFILL 0000100 ++#define TARGET_OFDEL 0000200 ++#define TARGET_NLDLY 0000400 ++#define TARGET_NL0 0000000 ++#define TARGET_NL1 0000400 ++#define TARGET_CRDLY 0003000 ++#define TARGET_CR0 0000000 ++#define TARGET_CR1 0001000 ++#define TARGET_CR2 0002000 ++#define TARGET_CR3 0003000 ++#define TARGET_TABDLY 0014000 ++#define TARGET_TAB0 0000000 ++#define TARGET_TAB1 0004000 ++#define TARGET_TAB2 0010000 ++#define TARGET_TAB3 0014000 ++#define TARGET_XTABS 0014000 ++#define TARGET_BSDLY 0020000 ++#define TARGET_BS0 0000000 ++#define TARGET_BS1 0020000 ++#define TARGET_VTDLY 0040000 ++#define TARGET_VT0 0000000 ++#define TARGET_VT1 0040000 ++#define TARGET_FFDLY 0100000 ++#define TARGET_FF0 0000000 ++#define TARGET_FF1 0100000 ++ ++/* c_cflag bit meaning */ ++#define TARGET_CBAUD 0010017 ++#define TARGET_B0 0000000 /* hang up */ ++#define TARGET_B50 0000001 ++#define TARGET_B75 0000002 ++#define TARGET_B110 0000003 ++#define TARGET_B134 0000004 ++#define TARGET_B150 0000005 ++#define TARGET_B200 0000006 ++#define TARGET_B300 0000007 ++#define TARGET_B600 0000010 ++#define TARGET_B1200 0000011 ++#define TARGET_B1800 0000012 ++#define TARGET_B2400 0000013 ++#define TARGET_B4800 0000014 ++#define TARGET_B9600 0000015 ++#define TARGET_B19200 0000016 ++#define TARGET_B38400 0000017 ++#define TARGET_EXTA B19200 ++#define TARGET_EXTB B38400 ++#define TARGET_CSIZE 0000060 ++#define TARGET_CS5 0000000 ++#define TARGET_CS6 0000020 ++#define TARGET_CS7 0000040 ++#define TARGET_CS8 0000060 ++#define TARGET_CSTOPB 0000100 ++#define TARGET_CREAD 0000200 ++#define TARGET_PARENB 0000400 ++#define TARGET_PARODD 0001000 ++#define TARGET_HUPCL 0002000 ++#define TARGET_CLOCAL 0004000 ++#define TARGET_CBAUDEX 0010000 ++#define TARGET_BOTHER 0010000 ++#define TARGET_B57600 0010001 ++#define TARGET_B115200 0010002 ++#define TARGET_B230400 0010003 ++#define TARGET_B460800 0010004 ++#define TARGET_B500000 0010005 ++#define TARGET_B576000 0010006 ++#define TARGET_B921600 0010007 ++#define TARGET_B1000000 0010010 ++#define TARGET_B1152000 0010011 ++#define TARGET_B1500000 0010012 ++#define TARGET_B2000000 0010013 ++#define TARGET_B2500000 0010014 ++#define TARGET_B3000000 0010015 ++#define TARGET_B3500000 0010016 ++#define TARGET_B4000000 0010017 ++#define TARGET_CIBAUD 002003600000 /* input baud rate */ ++#define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */ ++#define TARGET_CRTSCTS 020000000000 /* flow control */ ++ ++#define TARGET_IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ ++ ++/* c_lflag bits */ ++#define TARGET_ISIG 0000001 ++#define TARGET_ICANON 0000002 ++#define TARGET_XCASE 0000004 ++#define TARGET_ECHO 0000010 ++#define TARGET_ECHOE 0000020 ++#define TARGET_ECHOK 0000040 ++#define TARGET_ECHONL 0000100 ++#define TARGET_NOFLSH 0000200 ++#define TARGET_TOSTOP 0000400 ++#define TARGET_ECHOCTL 0001000 ++#define TARGET_ECHOPRT 0002000 ++#define TARGET_ECHOKE 0004000 ++#define TARGET_FLUSHO 0010000 ++#define TARGET_PENDIN 0040000 ++#define TARGET_IEXTEN 0100000 ++ ++/* tcflow() and TCXONC use these */ ++#define TARGET_TCOOFF 0 ++#define TARGET_TCOON 1 ++#define TARGET_TCIOFF 2 ++#define TARGET_TCION 3 ++ ++/* tcflush() and TCFLSH use these */ ++#define TARGET_TCIFLUSH 0 ++#define TARGET_TCOFLUSH 1 ++#define TARGET_TCIOFLUSH 2 ++ ++/* tcsetattr uses these */ ++#define TARGET_TCSANOW 0 ++#define TARGET_TCSADRAIN 1 ++#define TARGET_TCSAFLUSH 2 ++ ++/* ++ * include/asm-s390/ioctls.h ++ * ++ * S390 version ++ * ++ * Derived from "include/asm-i386/ioctls.h" ++ */ ++ ++/* 0x54 is just a magic number to make these relatively unique ('T') */ ++ ++#define TARGET_TCGETS 0x5401 ++#define TARGET_TCSETS 0x5402 ++#define TARGET_TCSETSW 0x5403 ++#define TARGET_TCSETSF 0x5404 ++#define TARGET_TCGETA 0x5405 ++#define TARGET_TCSETA 0x5406 ++#define TARGET_TCSETAW 0x5407 ++#define TARGET_TCSETAF 0x5408 ++#define TARGET_TCSBRK 0x5409 ++#define TARGET_TCXONC 0x540A ++#define TARGET_TCFLSH 0x540B ++#define TARGET_TIOCEXCL 0x540C ++#define TARGET_TIOCNXCL 0x540D ++#define TARGET_TIOCSCTTY 0x540E ++#define TARGET_TIOCGPGRP 0x540F ++#define TARGET_TIOCSPGRP 0x5410 ++#define TARGET_TIOCOUTQ 0x5411 ++#define TARGET_TIOCSTI 0x5412 ++#define TARGET_TIOCGWINSZ 0x5413 ++#define TARGET_TIOCSWINSZ 0x5414 ++#define TARGET_TIOCMGET 0x5415 ++#define TARGET_TIOCMBIS 0x5416 ++#define TARGET_TIOCMBIC 0x5417 ++#define TARGET_TIOCMSET 0x5418 ++#define TARGET_TIOCGSOFTCAR 0x5419 ++#define TARGET_TIOCSSOFTCAR 0x541A ++#define TARGET_FIONREAD 0x541B ++#define TARGET_TIOCINQ FIONREAD ++#define TARGET_TIOCLINUX 0x541C ++#define TARGET_TIOCCONS 0x541D ++#define TARGET_TIOCGSERIAL 0x541E ++#define TARGET_TIOCSSERIAL 0x541F ++#define TARGET_TIOCPKT 0x5420 ++#define TARGET_FIONBIO 0x5421 ++#define TARGET_TIOCNOTTY 0x5422 ++#define TARGET_TIOCSETD 0x5423 ++#define TARGET_TIOCGETD 0x5424 ++#define TARGET_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ ++#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */ ++#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */ ++#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */ ++#define TARGET_TCGETS2 _IOR('T',0x2A, struct termios2) ++#define TARGET_TCSETS2 _IOW('T',0x2B, struct termios2) ++#define TARGET_TCSETSW2 _IOW('T',0x2C, struct termios2) ++#define TARGET_TCSETSF2 _IOW('T',0x2D, struct termios2) ++#define TARGET_TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ ++#define TARGET_TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ ++#define TARGET_TIOCGDEV _IOR('T',0x32, unsigned int) /* Get real dev no below /dev/console */ ++ ++#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */ ++#define TARGET_FIOCLEX 0x5451 ++#define TARGET_FIOASYNC 0x5452 ++#define TARGET_TIOCSERCONFIG 0x5453 ++#define TARGET_TIOCSERGWILD 0x5454 ++#define TARGET_TIOCSERSWILD 0x5455 ++#define TARGET_TIOCGLCKTRMIOS 0x5456 ++#define TARGET_TIOCSLCKTRMIOS 0x5457 ++#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */ ++#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */ ++#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */ ++#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */ ++ ++#define TARGET_TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ ++#define TARGET_TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ ++#define TARGET_FIOQSIZE 0x545E ++ ++/* Used for packet mode */ ++#define TARGET_TIOCPKT_DATA 0 ++#define TARGET_TIOCPKT_FLUSHREAD 1 ++#define TARGET_TIOCPKT_FLUSHWRITE 2 ++#define TARGET_TIOCPKT_STOP 4 ++#define TARGET_TIOCPKT_START 8 ++#define TARGET_TIOCPKT_NOSTOP 16 ++#define TARGET_TIOCPKT_DOSTOP 32 ++ ++#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */ ++ +Index: qemu-0.14.1/linux-user/signal.c +=================================================================== +--- qemu-0.14.1.orig/linux-user/signal.c ++++ qemu-0.14.1/linux-user/signal.c +@@ -3614,6 +3614,320 @@ long do_rt_sigreturn(CPUState *env) + return -TARGET_ENOSYS; + } + ++#elif defined(TARGET_S390X) ++ ++#define __NUM_GPRS 16 ++#define __NUM_FPRS 16 ++#define __NUM_ACRS 16 ++ ++#define S390_SYSCALL_SIZE 2 ++#define __SIGNAL_FRAMESIZE 160 /* FIXME: 31-bit mode -> 96 */ ++ ++#define _SIGCONTEXT_NSIG 64 ++#define _SIGCONTEXT_NSIG_BPW 64 /* FIXME: 31-bit mode -> 32 */ ++#define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW) ++#define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS) ++#define PSW_ADDR_AMODE 0x0000000000000000UL /* 0x80000000UL for 31-bit */ ++#define S390_SYSCALL_OPCODE ((uint16_t)0x0a00) ++ ++typedef struct ++{ ++ target_psw_t psw; ++ target_ulong gprs[__NUM_GPRS]; ++ unsigned int acrs[__NUM_ACRS]; ++} target_s390_regs_common; ++ ++typedef struct ++{ ++ unsigned int fpc; ++ double fprs[__NUM_FPRS]; ++} target_s390_fp_regs; ++ ++typedef struct ++{ ++ target_s390_regs_common regs; ++ target_s390_fp_regs fpregs; ++} target_sigregs; ++ ++struct target_sigcontext ++{ ++ target_ulong oldmask[_SIGCONTEXT_NSIG_WORDS]; ++ target_sigregs *sregs; ++}; ++ ++typedef struct ++{ ++ uint8_t callee_used_stack[__SIGNAL_FRAMESIZE]; ++ struct target_sigcontext sc; ++ target_sigregs sregs; ++ int signo; ++ uint8_t retcode[S390_SYSCALL_SIZE]; ++} sigframe; ++ ++struct target_ucontext { ++ target_ulong uc_flags; ++ struct target_ucontext *uc_link; ++ target_stack_t uc_stack; ++ target_sigregs uc_mcontext; ++ target_sigset_t uc_sigmask; /* mask last for extensibility */ ++}; ++ ++typedef struct ++{ ++ uint8_t callee_used_stack[__SIGNAL_FRAMESIZE]; ++ uint8_t retcode[S390_SYSCALL_SIZE]; ++ struct target_siginfo info; ++ struct target_ucontext uc; ++} rt_sigframe; ++ ++static inline abi_ulong ++get_sigframe(struct target_sigaction *ka, CPUState *env, size_t frame_size) ++{ ++ abi_ulong sp; ++ ++ /* Default to using normal stack */ ++ sp = env->regs[15]; ++ ++ /* This is the X/Open sanctioned signal stack switching. */ ++ if (ka->sa_flags & TARGET_SA_ONSTACK) { ++ if (! sas_ss_flags(sp)) ++ sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; ++ } ++ ++ /* This is the legacy signal stack switching. */ ++ else if (/* FIXME !user_mode(regs) */ 0 && ++ !(ka->sa_flags & TARGET_SA_RESTORER) && ++ ka->sa_restorer) { ++ sp = (abi_ulong) ka->sa_restorer; ++ } ++ ++ return (sp - frame_size) & -8ul; ++} ++ ++static void save_sigregs(CPUState *env, target_sigregs *sregs) ++{ ++ int i; ++ //save_access_regs(current->thread.acrs); FIXME ++ ++ /* Copy a 'clean' PSW mask to the user to avoid leaking ++ information about whether PER is currently on. */ ++ __put_user(env->psw.mask, &sregs->regs.psw.mask); ++ __put_user(env->psw.addr, &sregs->regs.psw.addr); ++ for (i = 0; i < 16; i++) ++ __put_user(env->regs[i], &sregs->regs.gprs[i]); ++ for (i = 0; i < 16; i++) ++ __put_user(env->aregs[i], &sregs->regs.acrs[i]); ++ /* ++ * We have to store the fp registers to current->thread.fp_regs ++ * to merge them with the emulated registers. ++ */ ++ //save_fp_regs(¤t->thread.fp_regs); FIXME ++ for (i = 0; i < 16; i++) ++ __put_user(env->fregs[i].ll, &sregs->fpregs.fprs[i]); ++} ++ ++static void setup_frame(int sig, struct target_sigaction *ka, ++ target_sigset_t *set, CPUState *env) ++{ ++ sigframe *frame; ++ abi_ulong frame_addr; ++ ++ frame_addr = get_sigframe(ka, env, sizeof *frame); ++ qemu_log("%s: frame_addr 0x%lx\n", __FUNCTION__, frame_addr); ++ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) ++ goto give_sigsegv; ++ ++ qemu_log("%s: 1\n", __FUNCTION__); ++ if (__put_user(set->sig[0], &frame->sc.oldmask[0])) ++ goto give_sigsegv; ++ ++ save_sigregs(env, &frame->sregs); ++ ++ __put_user((abi_ulong)&frame->sregs, (abi_ulong *)&frame->sc.sregs); ++ ++ /* Set up to return from userspace. If provided, use a stub ++ already in userspace. */ ++ if (ka->sa_flags & TARGET_SA_RESTORER) { ++ env->regs[14] = (unsigned long) ++ ka->sa_restorer | PSW_ADDR_AMODE; ++ } else { ++ env->regs[14] = (unsigned long) ++ frame->retcode | PSW_ADDR_AMODE; ++ if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn, ++ (uint16_t *)(frame->retcode))) ++ goto give_sigsegv; ++ } ++ ++ /* Set up backchain. */ ++ if (__put_user(env->regs[15], (abi_ulong *) frame)) ++ goto give_sigsegv; ++ ++ /* Set up registers for signal handler */ ++ env->regs[15] = (target_ulong) frame; ++ env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE; ++ ++ env->regs[2] = sig; //map_signal(sig); ++ env->regs[3] = (target_ulong) &frame->sc; ++ ++ /* We forgot to include these in the sigcontext. ++ To avoid breaking binary compatibility, they are passed as args. */ ++ env->regs[4] = 0; // FIXME: no clue... current->thread.trap_no; ++ env->regs[5] = 0; // FIXME: no clue... current->thread.prot_addr; ++ ++ /* Place signal number on stack to allow backtrace from handler. */ ++ if (__put_user(env->regs[2], (int *) &frame->signo)) ++ goto give_sigsegv; ++ unlock_user_struct(frame, frame_addr, 1); ++ return; ++ ++give_sigsegv: ++ qemu_log("%s: give_sigsegv\n", __FUNCTION__); ++ unlock_user_struct(frame, frame_addr, 1); ++ force_sig(TARGET_SIGSEGV); ++} ++ ++static void setup_rt_frame(int sig, struct target_sigaction *ka, ++ target_siginfo_t *info, ++ target_sigset_t *set, CPUState *env) ++{ ++ int i; ++ rt_sigframe *frame; ++ abi_ulong frame_addr; ++ ++ frame_addr = get_sigframe(ka, env, sizeof *frame); ++ qemu_log("%s: frame_addr 0x%lx\n", __FUNCTION__, frame_addr); ++ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) ++ goto give_sigsegv; ++ ++ qemu_log("%s: 1\n", __FUNCTION__); ++ if (copy_siginfo_to_user(&frame->info, info)) ++ goto give_sigsegv; ++ ++ /* Create the ucontext. */ ++ __put_user(0, &frame->uc.uc_flags); ++ __put_user((abi_ulong)NULL, (abi_ulong*)&frame->uc.uc_link); ++ __put_user(target_sigaltstack_used.ss_sp, &frame->uc.uc_stack.ss_sp); ++ __put_user(sas_ss_flags(get_sp_from_cpustate(env)), ++ &frame->uc.uc_stack.ss_flags); ++ __put_user(target_sigaltstack_used.ss_size, &frame->uc.uc_stack.ss_size); ++ save_sigregs(env, &frame->uc.uc_mcontext); ++ for(i = 0; i < TARGET_NSIG_WORDS; i++) { ++ __put_user((abi_ulong)set->sig[i], (abi_ulong*)&frame->uc.uc_sigmask.sig[i]); ++ } ++ ++ /* Set up to return from userspace. If provided, use a stub ++ already in userspace. */ ++ if (ka->sa_flags & TARGET_SA_RESTORER) { ++ env->regs[14] = (unsigned long) ++ ka->sa_restorer | PSW_ADDR_AMODE; ++ } else { ++ env->regs[14] = (unsigned long) ++ frame->retcode | PSW_ADDR_AMODE; ++ if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn, ++ (uint16_t *)(frame->retcode))) ++ goto give_sigsegv; ++ } ++ ++ /* Set up backchain. */ ++ if (__put_user(env->regs[15], (abi_ulong *) frame)) ++ goto give_sigsegv; ++ ++ /* Set up registers for signal handler */ ++ env->regs[15] = (target_ulong) frame; ++ env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE; ++ ++ env->regs[2] = sig; //map_signal(sig); ++ env->regs[3] = (target_ulong) &frame->info; ++ env->regs[4] = (target_ulong) &frame->uc; ++ return; ++ ++give_sigsegv: ++ qemu_log("%s: give_sigsegv\n", __FUNCTION__); ++ unlock_user_struct(frame, frame_addr, 1); ++ force_sig(TARGET_SIGSEGV); ++} ++ ++static int ++restore_sigregs(CPUState *env, target_sigregs *sc) ++{ ++ int err = 0; ++ int i; ++ ++ for (i = 0; i < 16; i++) { ++ err |= __get_user(env->regs[i], &sc->regs.gprs[i]); ++ } ++ ++ err |= __get_user(env->psw.mask, &sc->regs.psw.mask); ++ qemu_log("%s: sc->regs.psw.addr 0x%lx env->psw.addr 0x%lx\n", __FUNCTION__, sc->regs.psw.addr, env->psw.addr); ++ err |= __get_user(env->psw.addr, &sc->regs.psw.addr); ++ /* FIXME: 31-bit -> | PSW_ADDR_AMODE */ ++ ++ for (i = 0; i < 16; i++) { ++ err |= __get_user(env->aregs[i], &sc->regs.acrs[i]); ++ } ++ for (i = 0; i < 16; i++) { ++ err |= __get_user(env->fregs[i].ll, &sc->fpregs.fprs[i]); ++ } ++ ++ return err; ++} ++ ++long do_sigreturn(CPUState *env) ++{ ++ sigframe *frame; ++ abi_ulong frame_addr = env->regs[15]; ++ qemu_log("%s: frame_addr 0x%lx\n", __FUNCTION__, frame_addr); ++ target_sigset_t target_set; ++ sigset_t set; ++ ++ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) ++ goto badframe; ++ if (__get_user(target_set.sig[0], &frame->sc.oldmask[0])) ++ goto badframe; ++ ++ target_to_host_sigset_internal(&set, &target_set); ++ sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */ ++ ++ if (restore_sigregs(env, &frame->sregs)) ++ goto badframe; ++ ++ unlock_user_struct(frame, frame_addr, 0); ++ return env->regs[2]; ++ ++badframe: ++ unlock_user_struct(frame, frame_addr, 0); ++ force_sig(TARGET_SIGSEGV); ++ return 0; ++} ++ ++long do_rt_sigreturn(CPUState *env) ++{ ++ rt_sigframe *frame; ++ abi_ulong frame_addr = env->regs[15]; ++ qemu_log("%s: frame_addr 0x%lx\n", __FUNCTION__, frame_addr); ++ sigset_t set; ++ ++ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) ++ goto badframe; ++ target_to_host_sigset(&set, &frame->uc.uc_sigmask); ++ ++ sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */ ++ ++ if (restore_sigregs(env, &frame->uc.uc_mcontext)) ++ goto badframe; ++ ++ if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.uc_stack), 0, ++ get_sp_from_cpustate(env)) == -EFAULT) ++ goto badframe; ++ unlock_user_struct(frame, frame_addr, 0); ++ return env->regs[2]; ++ ++badframe: ++ unlock_user_struct(frame, frame_addr, 0); ++ force_sig(TARGET_SIGSEGV); ++ return 0; ++} ++ + #elif defined(TARGET_PPC) && !defined(TARGET_PPC64) + + /* FIXME: Many of the structures are defined for both PPC and PPC64, but +Index: qemu-0.14.1/linux-user/syscall.c +=================================================================== +--- qemu-0.14.1.orig/linux-user/syscall.c ++++ qemu-0.14.1/linux-user/syscall.c +@@ -194,7 +194,7 @@ static type name (type1 arg1,type2 arg2, + #define __NR_sys_inotify_add_watch __NR_inotify_add_watch + #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch + +-#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) ++#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || defined(__s390x__) + #define __NR__llseek __NR_lseek + #endif + +@@ -323,7 +323,7 @@ static int sys_fchmodat(int dirfd, const + return (fchmodat(dirfd, pathname, mode, 0)); + } + #endif +-#if defined(TARGET_NR_fchownat) && defined(USE_UID16) ++#if defined(TARGET_NR_fchownat) + static int sys_fchownat(int dirfd, const char *pathname, uid_t owner, + gid_t group, int flags) + { +@@ -420,7 +420,7 @@ _syscall3(int,sys_faccessat,int,dirfd,co + #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat) + _syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode) + #endif +-#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16) ++#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) + _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname, + uid_t,owner,gid_t,group,int,flags) + #endif +@@ -3779,6 +3779,7 @@ static int do_fork(CPUState *env, unsign + #endif + ts = qemu_mallocz(sizeof(TaskState)); + init_task_state(ts); ++ env->multithreaded = 1; + /* we create a new CPU instance. */ + new_env = cpu_copy(env); + #if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC) +@@ -5448,7 +5449,7 @@ abi_long do_syscall(void *cpu_env, int n + ret = get_errno(settimeofday(&tv, NULL)); + } + break; +-#ifdef TARGET_NR_select ++#if defined(TARGET_NR_select) && !defined(TARGET_S390X) && !defined(TARGET_S390) + case TARGET_NR_select: + { + struct target_sel_arg_struct *sel; +@@ -5563,7 +5564,9 @@ abi_long do_syscall(void *cpu_env, int n + #endif + #ifdef TARGET_NR_mmap + case TARGET_NR_mmap: +-#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) ++#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || \ ++ defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \ ++ || defined(TARGET_S390X) + { + abi_ulong *v; + abi_ulong v1, v2, v3, v4, v5, v6; +@@ -6059,6 +6062,8 @@ abi_long do_syscall(void *cpu_env, int n + ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4)); + #elif defined(TARGET_CRIS) + ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5)); ++#elif defined(TARGET_S390X) ++ ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4)); + #else + ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5)); + #endif +@@ -6263,8 +6268,12 @@ abi_long do_syscall(void *cpu_env, int n + } + break; + #endif /* TARGET_NR_getdents64 */ +-#ifdef TARGET_NR__newselect ++#if defined(TARGET_NR__newselect) || defined(TARGET_S390X) ++#ifdef TARGET_S390X ++ case TARGET_NR_select: ++#else + case TARGET_NR__newselect: ++#endif + ret = do_select(arg1, arg2, arg3, arg4, arg5); + break; + #endif +@@ -6489,7 +6498,7 @@ abi_long do_syscall(void *cpu_env, int n + case TARGET_NR_sigaltstack: + #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \ + defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \ +- defined(TARGET_M68K) ++ defined(TARGET_M68K) || defined(TARGET_S390X) + ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env)); + break; + #else +@@ -6722,18 +6731,35 @@ abi_long do_syscall(void *cpu_env, int n + case TARGET_NR_setfsgid: + ret = get_errno(setfsgid(arg1)); + break; ++#else /* USE_UID16 */ ++#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) ++ case TARGET_NR_fchownat: ++ if (!(p = lock_user_string(arg2))) ++ goto efault; ++ ret = get_errno(sys_fchownat(arg1, p, arg3, arg4, arg5)); ++ unlock_user(p, arg2, 0); ++ break; ++#endif + #endif /* USE_UID16 */ + +-#ifdef TARGET_NR_lchown32 ++#if defined(TARGET_NR_lchown32) || !defined(USE_UID16) ++#if defined(TARGET_NR_lchown32) + case TARGET_NR_lchown32: ++#else ++ case TARGET_NR_lchown: ++#endif + if (!(p = lock_user_string(arg1))) + goto efault; + ret = get_errno(lchown(p, arg2, arg3)); + unlock_user(p, arg1, 0); + break; + #endif +-#ifdef TARGET_NR_getuid32 ++#if defined(TARGET_NR_getuid32) || (defined(TARGET_NR_getuid) && !defined(USE_UID16)) ++#if defined(TARGET_NR_getuid32) + case TARGET_NR_getuid32: ++#else ++ case TARGET_NR_getuid: ++#endif + ret = get_errno(getuid()); + break; + #endif +@@ -6878,33 +6904,57 @@ abi_long do_syscall(void *cpu_env, int n + break; + #endif + +-#ifdef TARGET_NR_getgid32 ++#if defined(TARGET_NR_getgid32) || (defined(TARGET_NR_getgid) && !defined(USE_UID16)) ++#if defined(TARGET_NR_getgid32) + case TARGET_NR_getgid32: ++#else ++ case TARGET_NR_getgid: ++#endif + ret = get_errno(getgid()); + break; + #endif +-#ifdef TARGET_NR_geteuid32 ++#if defined(TARGET_NR_geteuid32) || (defined(TARGET_NR_geteuid) && !defined(USE_UID16)) ++#if defined(TARGET_NR_geteuid32) + case TARGET_NR_geteuid32: ++#else ++ case TARGET_NR_geteuid: ++#endif + ret = get_errno(geteuid()); + break; + #endif +-#ifdef TARGET_NR_getegid32 ++#if defined(TARGET_NR_getegid32) || (defined(TARGET_NR_getegid) && !defined(USE_UID16)) ++#if defined(TARGET_NR_getegid32) + case TARGET_NR_getegid32: ++#else ++ case TARGET_NR_getegid: ++#endif + ret = get_errno(getegid()); + break; + #endif +-#ifdef TARGET_NR_setreuid32 ++#if defined(TARGET_NR_setreuid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setreuid32) + case TARGET_NR_setreuid32: ++#else ++ case TARGET_NR_setreuid: ++#endif + ret = get_errno(setreuid(arg1, arg2)); + break; + #endif +-#ifdef TARGET_NR_setregid32 ++#if defined(TARGET_NR_setregid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setregid32) + case TARGET_NR_setregid32: ++#else ++ case TARGET_NR_setregid: ++#endif + ret = get_errno(setregid(arg1, arg2)); + break; + #endif +-#ifdef TARGET_NR_getgroups32 ++#if defined(TARGET_NR_getgroups32) || !defined(USE_UID16) ++#if defined(TARGET_NR_getgroups32) + case TARGET_NR_getgroups32: ++#else ++ case TARGET_NR_getgroups: ++#endif + { + int gidsetsize = arg1; + uint32_t *target_grouplist; +@@ -6928,8 +6978,12 @@ abi_long do_syscall(void *cpu_env, int n + } + break; + #endif +-#ifdef TARGET_NR_setgroups32 ++#if defined(TARGET_NR_setgroups32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setgroups32) + case TARGET_NR_setgroups32: ++#else ++ case TARGET_NR_setgroups: ++#endif + { + int gidsetsize = arg1; + uint32_t *target_grouplist; +@@ -6949,18 +7003,30 @@ abi_long do_syscall(void *cpu_env, int n + } + break; + #endif +-#ifdef TARGET_NR_fchown32 ++#if defined(TARGET_NR_fchown32) || !defined(USE_UID16) ++#if defined(TARGET_NR_fchown32) + case TARGET_NR_fchown32: ++#else ++ case TARGET_NR_fchown: ++#endif + ret = get_errno(fchown(arg1, arg2, arg3)); + break; + #endif +-#ifdef TARGET_NR_setresuid32 ++#if defined(TARGET_NR_setresuid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setresuid32) + case TARGET_NR_setresuid32: ++#else ++ case TARGET_NR_setresuid: ++#endif + ret = get_errno(setresuid(arg1, arg2, arg3)); + break; + #endif +-#ifdef TARGET_NR_getresuid32 ++#if defined(TARGET_NR_getresuid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_getresuid32) + case TARGET_NR_getresuid32: ++#else ++ case TARGET_NR_getresuid: ++#endif + { + uid_t ruid, euid, suid; + ret = get_errno(getresuid(&ruid, &euid, &suid)); +@@ -6973,13 +7039,21 @@ abi_long do_syscall(void *cpu_env, int n + } + break; + #endif +-#ifdef TARGET_NR_setresgid32 ++#if defined(TARGET_NR_setresgid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setresgid32) + case TARGET_NR_setresgid32: ++#else ++ case TARGET_NR_setresgid: ++#endif + ret = get_errno(setresgid(arg1, arg2, arg3)); + break; + #endif ++#if defined(TARGET_NR_getresgid32) || !defined(USE_UID16) + #ifdef TARGET_NR_getresgid32 + case TARGET_NR_getresgid32: ++#else ++ case TARGET_NR_getresgid: ++#endif + { + gid_t rgid, egid, sgid; + ret = get_errno(getresgid(&rgid, &egid, &sgid)); +@@ -6992,31 +7066,51 @@ abi_long do_syscall(void *cpu_env, int n + } + break; + #endif +-#ifdef TARGET_NR_chown32 ++#if defined(TARGET_NR_chown32) || !defined(USE_UID16) ++#if defined(TARGET_NR_chown32) + case TARGET_NR_chown32: ++#else ++ case TARGET_NR_chown: ++#endif + if (!(p = lock_user_string(arg1))) + goto efault; + ret = get_errno(chown(p, arg2, arg3)); + unlock_user(p, arg1, 0); + break; + #endif +-#ifdef TARGET_NR_setuid32 ++#if defined(TARGET_NR_setuid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setuid32) + case TARGET_NR_setuid32: ++#else ++ case TARGET_NR_setuid: ++#endif + ret = get_errno(setuid(arg1)); + break; + #endif +-#ifdef TARGET_NR_setgid32 ++#if defined(TARGET_NR_setgid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setgid32) + case TARGET_NR_setgid32: ++#else ++ case TARGET_NR_setgid: ++#endif + ret = get_errno(setgid(arg1)); + break; + #endif +-#ifdef TARGET_NR_setfsuid32 ++#if defined(TARGET_NR_setfsuid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setfsuid32) + case TARGET_NR_setfsuid32: ++#else ++ case TARGET_NR_setfsuid: ++#endif + ret = get_errno(setfsuid(arg1)); + break; + #endif +-#ifdef TARGET_NR_setfsgid32 ++#if defined(TARGET_NR_setfsgid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setfsgid32) + case TARGET_NR_setfsgid32: ++#else ++ case TARGET_NR_setfsgid: ++#endif + ret = get_errno(setfsgid(arg1)); + break; + #endif +Index: qemu-0.14.1/linux-user/syscall_defs.h +=================================================================== +--- qemu-0.14.1.orig/linux-user/syscall_defs.h ++++ qemu-0.14.1/linux-user/syscall_defs.h +@@ -55,7 +55,7 @@ + #endif + + #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \ +- || defined(TARGET_M68K) || defined(TARGET_CRIS) ++ || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_S390X) + + #define TARGET_IOC_SIZEBITS 14 + #define TARGET_IOC_DIRBITS 2 +@@ -315,7 +315,10 @@ struct target_sigaction; + int do_sigaction(int sig, const struct target_sigaction *act, + struct target_sigaction *oact); + +-#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) ++#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || \ ++ defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || \ ++ defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \ ++ defined(TARGET_MICROBLAZE) || defined(TARGET_S390X) + + #if defined(TARGET_SPARC) + #define TARGET_SA_NOCLDSTOP 8u +@@ -1677,6 +1680,27 @@ struct target_stat { + + abi_long __unused[3]; + }; ++#elif defined(TARGET_S390X) ++struct target_stat { ++ abi_ulong st_dev; ++ abi_ulong st_ino; ++ abi_ulong st_nlink; ++ unsigned int st_mode; ++ unsigned int st_uid; ++ unsigned int st_gid; ++ unsigned int __pad1; ++ abi_ulong st_rdev; ++ abi_ulong st_size; ++ abi_ulong target_st_atime; ++ abi_ulong target_st_atime_nsec; ++ abi_ulong target_st_mtime; ++ abi_ulong target_st_mtime_nsec; ++ abi_ulong target_st_ctime; ++ abi_ulong target_st_ctime_nsec; ++ abi_ulong st_blksize; ++ abi_long st_blocks; ++ abi_ulong __unused[3]; ++}; + #else + #error unsupported CPU + #endif +@@ -1763,6 +1787,34 @@ struct target_statfs64 { + abi_long f_frsize; + abi_long f_spare[5]; + }; ++#elif defined(TARGET_S390X) ++struct target_statfs { ++ int32_t f_type; ++ int32_t f_bsize; ++ abi_long f_blocks; ++ abi_long f_bfree; ++ abi_long f_bavail; ++ abi_long f_files; ++ abi_long f_ffree; ++ kernel_fsid_t f_fsid; ++ int32_t f_namelen; ++ int32_t f_frsize; ++ int32_t f_spare[5]; ++}; ++ ++struct target_statfs64 { ++ int32_t f_type; ++ int32_t f_bsize; ++ abi_long f_blocks; ++ abi_long f_bfree; ++ abi_long f_bavail; ++ abi_long f_files; ++ abi_long f_ffree; ++ kernel_fsid_t f_fsid; ++ int32_t f_namelen; ++ int32_t f_frsize; ++ int32_t f_spare[5]; ++}; + #else + struct target_statfs { + uint32_t f_type; +Index: qemu-0.14.1/s390x.ld +=================================================================== +--- /dev/null ++++ qemu-0.14.1/s390x.ld +@@ -0,0 +1,194 @@ ++/* Default linker script, for normal executables */ ++OUTPUT_FORMAT("elf64-s390", "elf64-s390", ++ "elf64-s390") ++OUTPUT_ARCH(s390:64-bit) ++ENTRY(_start) ++SEARCH_DIR("/usr/s390x-suse-linux/lib64"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/s390x-suse-linux/lib"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); ++SECTIONS ++{ ++ /* Read-only sections, merged into text segment: */ ++ PROVIDE (__executable_start = 0x60000000); . = 0x60000000 + SIZEOF_HEADERS; ++ .interp : { *(.interp) } ++ .note.gnu.build-id : { *(.note.gnu.build-id) } ++ .hash : { *(.hash) } ++ .gnu.hash : { *(.gnu.hash) } ++ .dynsym : { *(.dynsym) } ++ .dynstr : { *(.dynstr) } ++ .gnu.version : { *(.gnu.version) } ++ .gnu.version_d : { *(.gnu.version_d) } ++ .gnu.version_r : { *(.gnu.version_r) } ++ .rel.init : { *(.rel.init) } ++ .rela.init : { *(.rela.init) } ++ .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } ++ .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } ++ .rel.fini : { *(.rel.fini) } ++ .rela.fini : { *(.rela.fini) } ++ .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } ++ .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } ++ .rel.data.rel.ro : { *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*) } ++ .rela.data.rel.ro : { *(.rela.data.rel.ro* .rela.gnu.linkonce.d.rel.ro.*) } ++ .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } ++ .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } ++ .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } ++ .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } ++ .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } ++ .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } ++ .rel.ctors : { *(.rel.ctors) } ++ .rela.ctors : { *(.rela.ctors) } ++ .rel.dtors : { *(.rel.dtors) } ++ .rela.dtors : { *(.rela.dtors) } ++ .rel.got : { *(.rel.got) } ++ .rela.got : { *(.rela.got) } ++ .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } ++ .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } ++ .rel.plt : { *(.rel.plt) } ++ .rela.plt : { *(.rela.plt) } ++ .init : ++ { ++ KEEP (*(.init)) ++ } =0x07070707 ++ .plt : { *(.plt) } ++ .text : ++ { ++ *(.text .stub .text.* .gnu.linkonce.t.*) ++ /* .gnu.warning sections are handled specially by elf32.em. */ ++ *(.gnu.warning) ++ } =0x07070707 ++ .fini : ++ { ++ KEEP (*(.fini)) ++ } =0x07070707 ++ PROVIDE (__etext = .); ++ PROVIDE (_etext = .); ++ PROVIDE (etext = .); ++ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } ++ .rodata1 : { *(.rodata1) } ++ .eh_frame_hdr : { *(.eh_frame_hdr) } ++ .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } ++ .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } ++ /* Adjust the address for the data segment. We want to adjust up to ++ the same address within the page on the next page up. */ ++ . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); ++ /* Exception handling */ ++ .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } ++ .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } ++ /* Thread Local Storage sections */ ++ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } ++ .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } ++ .preinit_array : ++ { ++ PROVIDE_HIDDEN (__preinit_array_start = .); ++ KEEP (*(.preinit_array)) ++ PROVIDE_HIDDEN (__preinit_array_end = .); ++ } ++ .init_array : ++ { ++ PROVIDE_HIDDEN (__init_array_start = .); ++ KEEP (*(SORT(.init_array.*))) ++ KEEP (*(.init_array)) ++ PROVIDE_HIDDEN (__init_array_end = .); ++ } ++ .fini_array : ++ { ++ PROVIDE_HIDDEN (__fini_array_start = .); ++ KEEP (*(.fini_array)) ++ KEEP (*(SORT(.fini_array.*))) ++ PROVIDE_HIDDEN (__fini_array_end = .); ++ } ++ .ctors : ++ { ++ /* gcc uses crtbegin.o to find the start of ++ the constructors, so we make sure it is ++ first. Because this is a wildcard, it ++ doesn't matter if the user does not ++ actually link against crtbegin.o; the ++ linker won't look for a file to match a ++ wildcard. The wildcard also means that it ++ doesn't matter which directory crtbegin.o ++ is in. */ ++ KEEP (*crtbegin.o(.ctors)) ++ KEEP (*crtbegin?.o(.ctors)) ++ /* We don't want to include the .ctor section from ++ the crtend.o file until after the sorted ctors. ++ The .ctor section from the crtend file contains the ++ end of ctors marker and it must be last */ ++ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) ++ KEEP (*(SORT(.ctors.*))) ++ KEEP (*(.ctors)) ++ } ++ .dtors : ++ { ++ KEEP (*crtbegin.o(.dtors)) ++ KEEP (*crtbegin?.o(.dtors)) ++ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) ++ KEEP (*(SORT(.dtors.*))) ++ KEEP (*(.dtors)) ++ } ++ .jcr : { KEEP (*(.jcr)) } ++ .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) } ++ .dynamic : { *(.dynamic) } ++ . = DATA_SEGMENT_RELRO_END (0, .); ++ .got : { *(.got.plt) *(.got) } ++ .data : ++ { ++ *(.data .data.* .gnu.linkonce.d.*) ++ SORT(CONSTRUCTORS) ++ } ++ .data1 : { *(.data1) } ++ _edata = .; PROVIDE (edata = .); ++ __bss_start = .; ++ .bss : ++ { ++ *(.dynbss) ++ *(.bss .bss.* .gnu.linkonce.b.*) ++ *(COMMON) ++ /* Align here to ensure that the .bss section occupies space up to ++ _end. Align after .bss to ensure correct alignment even if the ++ .bss section disappears because there are no input sections. ++ FIXME: Why do we need it? When there is no .bss section, we don't ++ pad the .data section. */ ++ . = ALIGN(. != 0 ? 64 / 8 : 1); ++ } ++ . = ALIGN(64 / 8); ++ . = ALIGN(64 / 8); ++ _end = .; PROVIDE (end = .); ++ . = DATA_SEGMENT_END (.); ++ /* Stabs debugging sections. */ ++ .stab 0 : { *(.stab) } ++ .stabstr 0 : { *(.stabstr) } ++ .stab.excl 0 : { *(.stab.excl) } ++ .stab.exclstr 0 : { *(.stab.exclstr) } ++ .stab.index 0 : { *(.stab.index) } ++ .stab.indexstr 0 : { *(.stab.indexstr) } ++ .comment 0 : { *(.comment) } ++ /* DWARF debug sections. ++ Symbols in the DWARF debugging sections are relative to the beginning ++ of the section so we begin them at 0. */ ++ /* DWARF 1 */ ++ .debug 0 : { *(.debug) } ++ .line 0 : { *(.line) } ++ /* GNU DWARF 1 extensions */ ++ .debug_srcinfo 0 : { *(.debug_srcinfo) } ++ .debug_sfnames 0 : { *(.debug_sfnames) } ++ /* DWARF 1.1 and DWARF 2 */ ++ .debug_aranges 0 : { *(.debug_aranges) } ++ .debug_pubnames 0 : { *(.debug_pubnames) } ++ /* DWARF 2 */ ++ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } ++ .debug_abbrev 0 : { *(.debug_abbrev) } ++ .debug_line 0 : { *(.debug_line) } ++ .debug_frame 0 : { *(.debug_frame) } ++ .debug_str 0 : { *(.debug_str) } ++ .debug_loc 0 : { *(.debug_loc) } ++ .debug_macinfo 0 : { *(.debug_macinfo) } ++ /* SGI/MIPS DWARF 2 extensions */ ++ .debug_weaknames 0 : { *(.debug_weaknames) } ++ .debug_funcnames 0 : { *(.debug_funcnames) } ++ .debug_typenames 0 : { *(.debug_typenames) } ++ .debug_varnames 0 : { *(.debug_varnames) } ++ /* DWARF 3 */ ++ .debug_pubtypes 0 : { *(.debug_pubtypes) } ++ .debug_ranges 0 : { *(.debug_ranges) } ++ .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } ++ /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) } ++} +Index: qemu-0.14.1/scripts/qemu-binfmt-conf.sh +=================================================================== +--- qemu-0.14.1.orig/scripts/qemu-binfmt-conf.sh ++++ qemu-0.14.1/scripts/qemu-binfmt-conf.sh +@@ -1,5 +1,5 @@ + #!/bin/sh +-# enable automatic i386/ARM/M68K/MIPS/SPARC/PPC program execution by the kernel ++# enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390 program execution by the kernel + + # load the binfmt_misc module + if [ ! -d /proc/sys/fs/binfmt_misc ]; then +@@ -67,3 +67,6 @@ if [ $cpu != "sh" ] ; then + echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-sh4-binfmt:P' > /proc/sys/fs/binfmt_misc/register + echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi ++if [ $cpu != "s390x" ] ; then ++ echo ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-s390x-binfmt:P' > /proc/sys/fs/binfmt_misc/register ++fi +Index: qemu-0.14.1/target-s390x/cpu.h +=================================================================== +--- qemu-0.14.1.orig/target-s390x/cpu.h ++++ qemu-0.14.1/target-s390x/cpu.h +@@ -26,6 +26,14 @@ + #define CPUState struct CPUS390XState + + #include "cpu-defs.h" ++#define TARGET_PAGE_BITS 12 ++ ++/* ??? This is certainly wrong for 64-bit s390x, but given that only KVM ++ emulation actually works, this is good enough for a placeholder. */ ++#define TARGET_PHYS_ADDR_SPACE_BITS 64 ++#define TARGET_VIRT_ADDR_SPACE_BITS 64 ++ ++#include "cpu-all.h" + + #include "softfloat.h" + +@@ -51,7 +59,7 @@ typedef struct CPUS390XState { + uint32_t aregs[16]; /* access registers */ + + uint32_t fpc; /* floating-point control register */ +- FPReg fregs[16]; /* FP registers */ ++ CPU_DoubleU fregs[16]; /* FP registers */ + float_status fpu_status; /* passed to softfloat lib */ + + struct { +@@ -85,8 +93,10 @@ static inline int cpu_mmu_index (CPUStat + } + + CPUS390XState *cpu_s390x_init(const char *cpu_model); ++void s390x_translate_init(void); + int cpu_s390x_exec(CPUS390XState *s); + void cpu_s390x_close(CPUS390XState *s); ++void do_interrupt (CPUState *env); + + /* you can call this signal handler from your SIGBUS and SIGSEGV + signal handlers to inform the virtual CPU of exceptions. non zero +@@ -97,29 +107,32 @@ int cpu_s390x_handle_mmu_fault (CPUS390X + int mmu_idx, int is_softmuu); + #define cpu_handle_mmu_fault cpu_s390x_handle_mmu_fault + +-#define TARGET_PAGE_BITS 12 +- +-/* ??? This is certainly wrong for 64-bit s390x, but given that only KVM +- emulation actually works, this is good enough for a placeholder. */ +-#define TARGET_PHYS_ADDR_SPACE_BITS 32 +-#define TARGET_VIRT_ADDR_SPACE_BITS 32 + + #ifndef CONFIG_USER_ONLY + int s390_virtio_hypercall(CPUState *env); + void kvm_s390_virtio_irq(CPUState *env, int config_change, uint64_t token); + CPUState *s390_cpu_addr2state(uint16_t cpu_addr); + #endif ++void cpu_lock(void); ++void cpu_unlock(void); + ++static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls) ++{ ++ env->aregs[0] = newtls >> 32; ++ env->aregs[1] = newtls & 0xffffffffULL; ++} + + #define cpu_init cpu_s390x_init + #define cpu_exec cpu_s390x_exec + #define cpu_gen_code cpu_s390x_gen_code ++#define cpu_signal_handler cpu_s390x_signal_handler + +-#include "cpu-all.h" ++#include "exec-all.h" + + #define EXCP_OPEX 1 /* operation exception (sigill) */ + #define EXCP_SVC 2 /* supervisor call (syscall) */ + #define EXCP_ADDR 5 /* addressing exception */ ++#define EXCP_SPEC 6 /* specification exception */ + #define EXCP_EXECUTE_SVC 0xff00000 /* supervisor call via execute insn */ + + static inline void cpu_get_tb_cpu_state(CPUState* env, target_ulong *pc, +Index: qemu-0.14.1/target-s390x/exec.h +=================================================================== +--- qemu-0.14.1.orig/target-s390x/exec.h ++++ qemu-0.14.1/target-s390x/exec.h +@@ -34,6 +34,14 @@ static inline int cpu_has_work(CPUState + return env->interrupt_request & CPU_INTERRUPT_HARD; // guess + } + ++static inline void regs_to_env(void) ++{ ++} ++ ++static inline void env_to_regs(void) ++{ ++} ++ + static inline int cpu_halted(CPUState *env) + { + if (!env->halted) { +Index: qemu-0.14.1/target-s390x/helper.c +=================================================================== +--- qemu-0.14.1.orig/target-s390x/helper.c ++++ qemu-0.14.1/target-s390x/helper.c +@@ -26,8 +26,10 @@ + #include "gdbstub.h" + #include "qemu-common.h" + ++#if !defined(CONFIG_USER_ONLY) + #include + #include "kvm.h" ++#endif + + CPUS390XState *cpu_s390x_init(const char *cpu_model) + { +@@ -38,6 +40,7 @@ CPUS390XState *cpu_s390x_init(const char + cpu_exec_init(env); + if (!inited) { + inited = 1; ++ s390x_translate_init(); + } + + env->cpu_model_str = cpu_model; +@@ -46,6 +49,24 @@ CPUS390XState *cpu_s390x_init(const char + return env; + } + ++#if defined(CONFIG_USER_ONLY) ++ ++void do_interrupt (CPUState *env) ++{ ++ env->exception_index = -1; ++} ++ ++int cpu_s390x_handle_mmu_fault (CPUState *env, target_ulong address, int rw, ++ int mmu_idx, int is_softmmu) ++{ ++ /* fprintf(stderr,"%s: address 0x%lx rw %d mmu_idx %d is_softmmu %d\n", __FUNCTION__, address, rw, mmu_idx, is_softmmu); */ ++ env->exception_index = EXCP_ADDR; ++ env->__excp_addr = address; /* FIXME: find out how this works on a real machine */ ++ return 1; ++} ++ ++#endif /* CONFIG_USER_ONLY */ ++ + void cpu_reset(CPUS390XState *env) + { + if (qemu_loglevel_mask(CPU_LOG_RESET)) { +@@ -58,13 +79,13 @@ void cpu_reset(CPUS390XState *env) + tlb_flush(env, 1); + } + ++#ifndef CONFIG_USER_ONLY ++ + target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) + { + return 0; + } + +-#ifndef CONFIG_USER_ONLY +- + int cpu_s390x_handle_mmu_fault (CPUState *env, target_ulong address, int rw, + int mmu_idx, int is_softmmu) + { +Index: qemu-0.14.1/target-s390x/helpers.h +=================================================================== +--- /dev/null ++++ qemu-0.14.1/target-s390x/helpers.h +@@ -0,0 +1,127 @@ ++#include "def-helper.h" ++ ++DEF_HELPER_1(exception, void, i32) ++DEF_HELPER_4(nc, i32, i32, i32, i32, i32) ++DEF_HELPER_4(oc, i32, i32, i32, i32, i32) ++DEF_HELPER_4(xc, i32, i32, i32, i32, i32) ++DEF_HELPER_4(mvc, void, i32, i32, i32, i32) ++DEF_HELPER_4(clc, i32, i32, i32, i32, i32) ++DEF_HELPER_4(lmg, void, i32, i32, i32, s32) ++DEF_HELPER_4(stmg, void, i32, i32, i32, s32) ++DEF_HELPER_FLAGS_1(set_cc_s32, TCG_CALL_PURE|TCG_CALL_CONST, i32, s32) ++DEF_HELPER_FLAGS_1(set_cc_s64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64) ++DEF_HELPER_FLAGS_1(set_cc_comp_s32, TCG_CALL_PURE|TCG_CALL_CONST, i32, s32) ++DEF_HELPER_FLAGS_1(set_cc_comp_s64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64) ++DEF_HELPER_FLAGS_1(set_cc_nz_u32, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32) ++DEF_HELPER_FLAGS_1(set_cc_nz_u64, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64) ++DEF_HELPER_FLAGS_2(set_cc_icm, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32) ++DEF_HELPER_3(brctg, void, i64, i64, s32) ++DEF_HELPER_3(brct, void, i32, i64, s32) ++DEF_HELPER_4(brcl, void, i32, i32, i64, s64) ++DEF_HELPER_4(bcr, void, i32, i32, i64, i64) ++DEF_HELPER_4(bc, void, i32, i32, i64, i64) ++DEF_HELPER_FLAGS_2(cmp_u64, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64, i64) ++DEF_HELPER_FLAGS_2(cmp_u32, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32) ++DEF_HELPER_FLAGS_2(cmp_s32, TCG_CALL_PURE|TCG_CALL_CONST, i32, s32, s32) ++DEF_HELPER_FLAGS_2(cmp_s64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64, s64) ++DEF_HELPER_3(clm, i32, i32, i32, i64) ++DEF_HELPER_3(stcm, void, i32, i32, i64) ++DEF_HELPER_2(mlg, void, i32, i64) ++DEF_HELPER_2(dlg, void, i32, i64) ++DEF_HELPER_FLAGS_3(set_cc_add64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64, s64, s64) ++DEF_HELPER_FLAGS_3(set_cc_addu64, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64, i64, i64) ++DEF_HELPER_FLAGS_3(set_cc_add32, TCG_CALL_PURE|TCG_CALL_CONST, i32, s32, s32, s32) ++DEF_HELPER_FLAGS_3(set_cc_addu32, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32, i32) ++DEF_HELPER_FLAGS_3(set_cc_sub64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64, s64, s64) ++DEF_HELPER_FLAGS_3(set_cc_subu64, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64, i64, i64) ++DEF_HELPER_FLAGS_3(set_cc_sub32, TCG_CALL_PURE|TCG_CALL_CONST, i32, s32, s32, s32) ++DEF_HELPER_FLAGS_3(set_cc_subu32, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32, i32) ++DEF_HELPER_3(srst, i32, i32, i32, i32) ++DEF_HELPER_3(clst, i32, i32, i32, i32) ++DEF_HELPER_3(mvst, i32, i32, i32, i32) ++DEF_HELPER_3(csg, i32, i32, i64, i32) ++DEF_HELPER_3(cdsg, i32, i32, i64, i32) ++DEF_HELPER_3(cs, i32, i32, i64, i32) ++DEF_HELPER_4(ex, i32, i32, i64, i64, i64) ++DEF_HELPER_FLAGS_2(tm, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32) ++DEF_HELPER_FLAGS_2(tmxx, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64, i32) ++DEF_HELPER_2(abs_i32, i32, i32, s32) ++DEF_HELPER_2(nabs_i32, i32, i32, s32) ++DEF_HELPER_2(abs_i64, i32, i32, s64) ++DEF_HELPER_2(nabs_i64, i32, i32, s64) ++DEF_HELPER_3(stcmh, i32, i32, i64, i32) ++DEF_HELPER_3(icmh, i32, i32, i64, i32) ++DEF_HELPER_2(ipm, void, i32, i32) ++DEF_HELPER_3(addc_u32, i32, i32, i32, i32) ++DEF_HELPER_FLAGS_3(set_cc_addc_u64, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64, i64, i64) ++DEF_HELPER_3(stam, void, i32, i64, i32) ++DEF_HELPER_3(mvcle, i32, i32, i64, i32) ++DEF_HELPER_3(clcle, i32, i32, i64, i32) ++DEF_HELPER_4(slb, i32, i32, i32, i32, i32) ++DEF_HELPER_4(slbg, i32, i32, i32, i64, i64) ++DEF_HELPER_2(cefbr, void, i32, s32) ++DEF_HELPER_2(cdfbr, void, i32, s32) ++DEF_HELPER_2(cxfbr, void, i32, s32) ++DEF_HELPER_2(cegbr, void, i32, s64) ++DEF_HELPER_2(cdgbr, void, i32, s64) ++DEF_HELPER_2(cxgbr, void, i32, s64) ++DEF_HELPER_2(adbr, i32, i32, i32) ++DEF_HELPER_2(aebr, i32, i32, i32) ++DEF_HELPER_2(sebr, i32, i32, i32) ++DEF_HELPER_2(sdbr, i32, i32, i32) ++DEF_HELPER_2(debr, void, i32, i32) ++DEF_HELPER_2(dxbr, void, i32, i32) ++DEF_HELPER_2(mdbr, void, i32, i32) ++DEF_HELPER_2(mxbr, void, i32, i32) ++DEF_HELPER_2(ldebr, void, i32, i32) ++DEF_HELPER_2(ldxbr, void, i32, i32) ++DEF_HELPER_2(lxdbr, void, i32, i32) ++DEF_HELPER_2(ledbr, void, i32, i32) ++DEF_HELPER_2(lexbr, void, i32, i32) ++DEF_HELPER_2(lpebr, i32, i32, i32) ++DEF_HELPER_2(lpdbr, i32, i32, i32) ++DEF_HELPER_2(lpxbr, i32, i32, i32) ++DEF_HELPER_2(ltebr, i32, i32, i32) ++DEF_HELPER_2(ltdbr, i32, i32, i32) ++DEF_HELPER_2(ltxbr, i32, i32, i32) ++DEF_HELPER_2(lcebr, i32, i32, i32) ++DEF_HELPER_2(lcdbr, i32, i32, i32) ++DEF_HELPER_2(lcxbr, i32, i32, i32) ++DEF_HELPER_2(ceb, i32, i32, i32) ++DEF_HELPER_2(aeb, i32, i32, i32) ++DEF_HELPER_2(deb, void, i32, i32) ++DEF_HELPER_2(meeb, void, i32, i32) ++DEF_HELPER_2(cdb, i32, i32, i64) ++DEF_HELPER_2(adb, i32, i32, i64) ++DEF_HELPER_2(seb, i32, i32, i32) ++DEF_HELPER_2(sdb, i32, i32, i64) ++DEF_HELPER_2(mdb, void, i32, i64) ++DEF_HELPER_2(ddb, void, i32, i64) ++DEF_HELPER_FLAGS_2(cebr, TCG_CALL_PURE, i32, i32, i32) ++DEF_HELPER_FLAGS_2(cdbr, TCG_CALL_PURE, i32, i32, i32) ++DEF_HELPER_FLAGS_2(cxbr, TCG_CALL_PURE, i32, i32, i32) ++DEF_HELPER_3(cgebr, i32, i32, i32, i32) ++DEF_HELPER_3(cgdbr, i32, i32, i32, i32) ++DEF_HELPER_3(cgxbr, i32, i32, i32, i32) ++DEF_HELPER_1(lzer, void, i32) ++DEF_HELPER_1(lzdr, void, i32) ++DEF_HELPER_1(lzxr, void, i32) ++DEF_HELPER_3(cfebr, i32, i32, i32, i32) ++DEF_HELPER_3(cfdbr, i32, i32, i32, i32) ++DEF_HELPER_3(cfxbr, i32, i32, i32, i32) ++DEF_HELPER_2(axbr, i32, i32, i32) ++DEF_HELPER_2(sxbr, i32, i32, i32) ++DEF_HELPER_2(meebr, void, i32, i32) ++DEF_HELPER_2(ddbr, void, i32, i32) ++DEF_HELPER_3(madb, void, i32, i64, i32) ++DEF_HELPER_3(maebr, void, i32, i32, i32) ++DEF_HELPER_3(madbr, void, i32, i32, i32) ++DEF_HELPER_3(msdbr, void, i32, i32, i32) ++DEF_HELPER_2(lxdb, void, i32, i64) ++DEF_HELPER_FLAGS_2(tceb, TCG_CALL_PURE, i32, i32, i64) ++DEF_HELPER_FLAGS_2(tcdb, TCG_CALL_PURE, i32, i32, i64) ++DEF_HELPER_FLAGS_2(tcxb, TCG_CALL_PURE, i32, i32, i64) ++DEF_HELPER_2(flogr, i32, i32, i64) ++DEF_HELPER_2(sqdbr, void, i32, i32) ++ ++#include "def-helper.h" +Index: qemu-0.14.1/target-s390x/op_helper.c +=================================================================== +--- qemu-0.14.1.orig/target-s390x/op_helper.c ++++ qemu-0.14.1/target-s390x/op_helper.c +@@ -1,6 +1,7 @@ + /* + * S/390 helper routines + * ++ * Copyright (c) 2009 Ulrich Hecht + * Copyright (c) 2009 Alexander Graf + * + * This library is free software; you can redistribute it and/or +@@ -18,6 +19,8 @@ + */ + + #include "exec.h" ++#include "helpers.h" ++#include + + /*****************************************************************************/ + /* Softmmu support */ +@@ -71,3 +74,1607 @@ void tlb_fill (target_ulong addr, int is + } + + #endif ++/* #define DEBUG_HELPER */ ++#ifdef DEBUG_HELPER ++#define HELPER_LOG(x...) qemu_log(x) ++#else ++#define HELPER_LOG(x...) ++#endif ++ ++/* raise an exception */ ++void HELPER(exception)(uint32_t excp) ++{ ++ HELPER_LOG("%s: exception %d\n", __FUNCTION__, excp); ++ env->exception_index = excp; ++ cpu_loop_exit(); ++} ++ ++/* and on array */ ++uint32_t HELPER(nc)(uint32_t l, uint32_t b, uint32_t d1, uint32_t d2) ++{ ++ uint64_t dest = env->regs[b >> 4] + d1; ++ uint64_t src = env->regs[b & 0xf] + d2; ++ int i; ++ unsigned char x; ++ uint32_t cc = 0; ++ HELPER_LOG("%s l %d b 0x%x d1 %d d2 %d\n", __FUNCTION__, l, b, d1, d2); ++ for (i = 0; i <= l; i++) { ++ x = ldub(dest + i) & ldub(src + i); ++ if (x) cc = 1; ++ stb(dest + i, x); ++ } ++ return cc; ++} ++ ++/* xor on array */ ++uint32_t HELPER(xc)(uint32_t l, uint32_t b, uint32_t d1, uint32_t d2) ++{ ++ uint64_t dest = env->regs[b >> 4] + d1; ++ uint64_t src = env->regs[b & 0xf] + d2; ++ int i; ++ unsigned char x; ++ uint32_t cc = 0; ++ HELPER_LOG("%s l %d b 0x%x d1 %d d2 %d\n", __FUNCTION__, l, b, d1, d2); ++ for (i = 0; i <= l; i++) { ++ x = ldub(dest + i) ^ ldub(src + i); ++ if (x) cc = 1; ++ stb(dest + i, x); ++ } ++ return cc; ++} ++ ++/* or on array */ ++uint32_t HELPER(oc)(uint32_t l, uint32_t b, uint32_t d1, uint32_t d2) ++{ ++ uint64_t dest = env->regs[b >> 4] + d1; ++ uint64_t src = env->regs[b & 0xf] + d2; ++ int i; ++ unsigned char x; ++ uint32_t cc = 0; ++ HELPER_LOG("%s l %d b 0x%x d1 %d d2 %d\n", __FUNCTION__, l, b, d1, d2); ++ for (i = 0; i <= l; i++) { ++ x = ldub(dest + i) | ldub(src + i); ++ if (x) cc = 1; ++ stb(dest + i, x); ++ } ++ return cc; ++} ++ ++/* memcopy */ ++void HELPER(mvc)(uint32_t l, uint32_t b, uint32_t d1, uint32_t d2) ++{ ++ uint64_t dest = env->regs[b >> 4] + d1; ++ uint64_t src = env->regs[b & 0xf] + d2; ++ int i; ++ HELPER_LOG("%s l %d b 0x%x d1 %d d2 %d\n", __FUNCTION__, l, b, d1, d2); ++ for (i = 0; i <= l; i++) { ++ stb(dest + i, ldub(src + i)); ++ } ++} ++ ++/* compare unsigned byte arrays */ ++uint32_t HELPER(clc)(uint32_t l, uint32_t b, uint32_t d1, uint32_t d2) ++{ ++ uint64_t s1 = env->regs[b >> 4] + d1; ++ uint64_t s2 = env->regs[b & 0xf] + d2; ++ int i; ++ unsigned char x,y; ++ uint32_t cc; ++ HELPER_LOG("%s l %d b 0x%x d1 %d d2 %d\n", __FUNCTION__, l, b, d1, d2); ++ for (i = 0; i <= l; i++) { ++ x = ldub(s1 + i); ++ y = ldub(s2 + i); ++ HELPER_LOG("%02x (%c)/%02x (%c) ", x, x, y, y); ++ if (x < y) { ++ cc = 1; ++ goto done; ++ } else if (x > y) { ++ cc = 2; ++ goto done; ++ } ++ } ++ cc = 0; ++done: ++ HELPER_LOG("\n"); ++ return cc; ++} ++ ++/* load multiple 64-bit registers from memory */ ++void HELPER(lmg)(uint32_t r1, uint32_t r3, uint32_t b2, int d2) ++{ ++ uint64_t src = env->regs[b2] + d2; ++ for (;;) { ++ env->regs[r1] = ldq(src); ++ src += 8; ++ if (r1 == r3) break; ++ r1 = (r1 + 1) & 15; ++ } ++} ++ ++/* store multiple 64-bit registers to memory */ ++void HELPER(stmg)(uint32_t r1, uint32_t r3, uint32_t b2, int d2) ++{ ++ uint64_t dest = env->regs[b2] + d2; ++ HELPER_LOG("%s: r1 %d r3 %d\n", __FUNCTION__, r1, r3); ++ for (;;) { ++ HELPER_LOG("storing r%d in 0x%lx\n", r1, dest); ++ stq(dest, env->regs[r1]); ++ dest += 8; ++ if (r1 == r3) break; ++ r1 = (r1 + 1) & 15; ++ } ++} ++ ++/* set condition code for signed 32-bit arithmetics */ ++uint32_t HELPER(set_cc_s32)(int32_t v) ++{ ++ if (v < 0) return 1; ++ else if (v > 0) return 2; ++ else return 0; ++} ++ ++/* set condition code for signed 64-bit arithmetics */ ++uint32_t HELPER(set_cc_s64)(int64_t v) ++{ ++ if (v < 0) return 1; ++ else if (v > 0) return 2; ++ else return 0; ++} ++ ++/* set condition code for signed 32-bit two's complement */ ++uint32_t HELPER(set_cc_comp_s32)(int32_t v) ++{ ++ if ((uint32_t)v == 0x80000000UL) return 3; ++ else if (v < 0) return 1; ++ else if (v > 0) return 2; ++ else return 0; ++} ++ ++/* set condition code for signed 64-bit two's complement */ ++uint32_t HELPER(set_cc_comp_s64)(int64_t v) ++{ ++ if ((uint64_t)v == 0x8000000000000000ULL) return 3; ++ else if (v < 0) return 1; ++ else if (v > 0) return 2; ++ else return 0; ++} ++ ++/* set negative/zero condition code for 32-bit logical op */ ++uint32_t HELPER(set_cc_nz_u32)(uint32_t v) ++{ ++ if (v) return 1; ++ else return 0; ++} ++ ++/* set negative/zero condition code for 64-bit logical op */ ++uint32_t HELPER(set_cc_nz_u64)(uint64_t v) ++{ ++ if (v) return 1; ++ else return 0; ++} ++ ++/* set condition code for insert character under mask insn */ ++uint32_t HELPER(set_cc_icm)(uint32_t mask, uint32_t val) ++{ ++ HELPER_LOG("%s: mask 0x%x val %d\n", __FUNCTION__, mask, val); ++ uint32_t cc; ++ if (!val || !mask) cc = 0; ++ else { ++ while (mask != 1) { ++ mask >>= 1; ++ val >>= 8; ++ } ++ if (val & 0x80) cc = 1; ++ else cc = 2; ++ } ++ return cc; ++} ++ ++/* branch relative on 64-bit count (condition is computed inline, this only ++ does the branch */ ++void HELPER(brctg)(uint64_t flag, uint64_t pc, int32_t offset) ++{ ++ if (flag) { ++ env->psw.addr = pc + offset; ++ } ++ else { ++ env->psw.addr = pc + 4; ++ } ++ HELPER_LOG("%s: pc 0x%lx flag %ld psw.addr 0x%lx\n", __FUNCTION__, pc, flag, ++ env->psw.addr); ++} ++ ++/* branch relative on 32-bit count (condition is computed inline, this only ++ does the branch */ ++void HELPER(brct)(uint32_t flag, uint64_t pc, int32_t offset) ++{ ++ if (flag) { ++ env->psw.addr = pc + offset; ++ } ++ else { ++ env->psw.addr = pc + 4; ++ } ++ HELPER_LOG("%s: pc 0x%lx flag %d psw.addr 0x%lx\n", __FUNCTION__, pc, flag, ++ env->psw.addr); ++} ++ ++/* relative conditional branch with long displacement */ ++void HELPER(brcl)(uint32_t cc, uint32_t mask, uint64_t pc, int64_t offset) ++{ ++ if ( mask & ( 1 << (3 - cc) ) ) { ++ env->psw.addr = pc + offset; ++ } ++ else { ++ env->psw.addr = pc + 6; ++ } ++ HELPER_LOG("%s: pc 0x%lx psw.addr 0x%lx\n", __FUNCTION__, pc, env->psw.addr); ++} ++ ++/* conditional branch to register (register content is passed as target) */ ++void HELPER(bcr)(uint32_t cc, uint32_t mask, uint64_t target, uint64_t pc) ++{ ++ if ( mask & ( 1 << (3 - cc) ) ) { ++ env->psw.addr = target; ++ } ++ else { ++ env->psw.addr = pc + 2; ++ } ++} ++ ++/* conditional branch to address (address is passed as target) */ ++void HELPER(bc)(uint32_t cc, uint32_t mask, uint64_t target, uint64_t pc) ++{ ++ if ( mask & ( 1 << (3 - cc) ) ) { ++ env->psw.addr = target; ++ } ++ else { ++ env->psw.addr = pc + 4; ++ } ++ HELPER_LOG("%s: pc 0x%lx psw.addr 0x%lx r2 0x%lx r5 0x%lx\n", __FUNCTION__, ++ pc, env->psw.addr, env->regs[2], env->regs[5]); ++} ++ ++/* 64-bit unsigned comparison */ ++uint32_t HELPER(cmp_u64)(uint64_t o1, uint64_t o2) ++{ ++ if (o1 < o2) return 1; ++ else if (o1 > o2) return 2; ++ else return 0; ++} ++ ++/* 32-bit unsigned comparison */ ++uint32_t HELPER(cmp_u32)(uint32_t o1, uint32_t o2) ++{ ++ HELPER_LOG("%s: o1 0x%x o2 0x%x\n", __FUNCTION__, o1, o2); ++ if (o1 < o2) return 1; ++ else if (o1 > o2) return 2; ++ else return 0; ++} ++ ++/* 64-bit signed comparison */ ++uint32_t HELPER(cmp_s64)(int64_t o1, int64_t o2) ++{ ++ HELPER_LOG("%s: o1 %ld o2 %ld\n", __FUNCTION__, o1, o2); ++ if (o1 < o2) return 1; ++ else if (o1 > o2) return 2; ++ else return 0; ++} ++ ++/* 32-bit signed comparison */ ++uint32_t HELPER(cmp_s32)(int32_t o1, int32_t o2) ++{ ++ if (o1 < o2) return 1; ++ else if (o1 > o2) return 2; ++ else return 0; ++} ++ ++/* compare logical under mask */ ++uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr) ++{ ++ uint8_t r,d; ++ uint32_t cc; ++ HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%lx\n",__FUNCTION__,r1,mask,addr); ++ cc = 0; ++ while (mask) { ++ if (mask & 8) { ++ d = ldub(addr); ++ r = (r1 & 0xff000000UL) >> 24; ++ HELPER_LOG("mask 0x%x %02x/%02x (0x%lx) ", mask, r, d, addr); ++ if (r < d) { ++ cc = 1; ++ break; ++ } ++ else if (r > d) { ++ cc = 2; ++ break; ++ } ++ addr++; ++ } ++ mask = (mask << 1) & 0xf; ++ r1 <<= 8; ++ } ++ HELPER_LOG("\n"); ++ return cc; ++} ++ ++/* store character under mask */ ++void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr) ++{ ++ uint8_t r; ++ HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%lx\n",__FUNCTION__,r1,mask,addr); ++ while (mask) { ++ if (mask & 8) { ++ r = (r1 & 0xff000000UL) >> 24; ++ stb(addr, r); ++ HELPER_LOG("mask 0x%x %02x (0x%lx) ", mask, r, addr); ++ addr++; ++ } ++ mask = (mask << 1) & 0xf; ++ r1 <<= 8; ++ } ++ HELPER_LOG("\n"); ++} ++ ++/* 64/64 -> 128 unsigned multiplication */ ++void HELPER(mlg)(uint32_t r1, uint64_t v2) ++{ ++#if TARGET_LONG_BITS == 64 && defined(__GNUC__) /* assuming 64-bit hosts have __uint128_t */ ++ __uint128_t res = (__uint128_t)env->regs[r1 + 1]; ++ res *= (__uint128_t)v2; ++ env->regs[r1] = (uint64_t)(res >> 64); ++ env->regs[r1 + 1] = (uint64_t)res; ++#else ++ mulu64(&env->regs[r1 + 1], &env->regs[r1], env->regs[r1 + 1], v2); ++#endif ++} ++ ++/* 128 -> 64/64 unsigned division */ ++void HELPER(dlg)(uint32_t r1, uint64_t v2) ++{ ++#if TARGET_LONG_BITS == 64 && defined(__GNUC__) /* assuming 64-bit hosts have __uint128_t */ ++ __uint128_t dividend = (((__uint128_t)env->regs[r1]) << 64) | ++ (env->regs[r1+1]); ++ uint64_t divisor = v2; ++ __uint128_t quotient = dividend / divisor; ++ env->regs[r1+1] = quotient; ++ __uint128_t remainder = dividend % divisor; ++ env->regs[r1] = remainder; ++ HELPER_LOG("%s: dividend 0x%016lx%016lx divisor 0x%lx quotient 0x%lx rem 0x%lx\n", ++ __FUNCTION__, (uint64_t)(dividend >> 64), (uint64_t)dividend, ++ divisor, (uint64_t)quotient, (uint64_t)remainder); ++#else ++ cpu_abort(env, "128 -> 64/64 division not implemented on this system\n"); ++#endif ++} ++ ++/* set condition code for 64-bit signed addition */ ++uint32_t HELPER(set_cc_add64)(int64_t a1, int64_t a2, int64_t ar) ++{ ++ if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) { ++ return 3; /* overflow */ ++ } else { ++ if (ar < 0) return 1; ++ else if (ar > 0) return 2; ++ else return 0; ++ } ++} ++ ++/* set condition code for 64-bit unsigned addition */ ++uint32_t HELPER(set_cc_addu64)(uint64_t a1, uint64_t a2, uint64_t ar) ++{ ++ if (ar == 0) { ++ if (a1) return 2; ++ else return 0; ++ } else { ++ if (ar < a1 || ar < a2) { ++ return 3; ++ } else { ++ return 1; ++ } ++ } ++} ++ ++/* set condition code for 32-bit signed addition */ ++uint32_t HELPER(set_cc_add32)(int32_t a1, int32_t a2, int32_t ar) ++{ ++ if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) { ++ return 3; /* overflow */ ++ } else { ++ if (ar < 0) return 1; ++ else if (ar > 0) return 2; ++ else return 0; ++ } ++} ++ ++/* set condition code for 32-bit unsigned addition */ ++uint32_t HELPER(set_cc_addu32)(uint32_t a1, uint32_t a2, uint32_t ar) ++{ ++ if (ar == 0) { ++ if (a1) return 2; ++ else return 0; ++ } else { ++ if (ar < a1 || ar < a2) { ++ return 3; ++ } else { ++ return 1; ++ } ++ } ++} ++ ++/* set condition code for 64-bit signed subtraction */ ++uint32_t HELPER(set_cc_sub64)(int64_t s1, int64_t s2, int64_t sr) ++{ ++ if ((s1 > 0 && s2 < 0 && sr < 0) || (s1 < 0 && s2 > 0 && sr > 0)) { ++ return 3; /* overflow */ ++ } else { ++ if (sr < 0) return 1; ++ else if (sr > 0) return 2; ++ else return 0; ++ } ++} ++ ++/* set condition code for 32-bit signed subtraction */ ++uint32_t HELPER(set_cc_sub32)(int32_t s1, int32_t s2, int32_t sr) ++{ ++ if ((s1 > 0 && s2 < 0 && sr < 0) || (s1 < 0 && s2 > 0 && sr > 0)) { ++ return 3; /* overflow */ ++ } else { ++ if (sr < 0) return 1; ++ else if (sr > 0) return 2; ++ else return 0; ++ } ++} ++ ++/* set condition code for 32-bit unsigned subtraction */ ++uint32_t HELPER(set_cc_subu32)(uint32_t s1, uint32_t s2, uint32_t sr) ++{ ++ if (sr == 0) return 2; ++ else { ++ if (s2 > s1) return 1; ++ else return 3; ++ } ++} ++ ++/* set condition code for 64-bit unsigned subtraction */ ++uint32_t HELPER(set_cc_subu64)(uint64_t s1, uint64_t s2, uint64_t sr) ++{ ++ if (sr == 0) return 2; ++ else { ++ if (s2 > s1) return 1; ++ else return 3; ++ } ++} ++ ++/* search string (c is byte to search, r2 is string, r1 end of string) */ ++uint32_t HELPER(srst)(uint32_t c, uint32_t r1, uint32_t r2) ++{ ++ HELPER_LOG("%s: c %d *r1 0x%lx *r2 0x%lx\n", __FUNCTION__, c, env->regs[r1], ++ env->regs[r2]); ++ uint64_t i; ++ uint32_t cc; ++ for (i = env->regs[r2]; i != env->regs[r1]; i++) { ++ if (ldub(i) == c) { ++ env->regs[r1] = i; ++ cc = 1; ++ return cc; ++ } ++ } ++ cc = 2; ++ return cc; ++} ++ ++/* unsigned string compare (c is string terminator) */ ++uint32_t HELPER(clst)(uint32_t c, uint32_t r1, uint32_t r2) ++{ ++ uint64_t s1 = env->regs[r1]; ++ uint64_t s2 = env->regs[r2]; ++ uint8_t v1, v2; ++ uint32_t cc; ++ c = c & 0xff; ++#ifdef CONFIG_USER_ONLY ++ if (!c) { ++ HELPER_LOG("%s: comparing '%s' and '%s'\n", ++ __FUNCTION__, (char*)s1, (char*)s2); ++ } ++#endif ++ for (;;) { ++ v1 = ldub(s1); ++ v2 = ldub(s2); ++ if (v1 == c || v2 == c) break; ++ if (v1 != v2) break; ++ s1++; s2++; ++ } ++ ++ if (v1 == v2) cc = 0; ++ else { ++ if (v1 < v2) cc = 1; ++ else cc = 2; ++ env->regs[r1] = s1; ++ env->regs[r2] = s2; ++ } ++ return cc; ++} ++ ++/* string copy (c is string terminator) */ ++uint32_t HELPER(mvst)(uint32_t c, uint32_t r1, uint32_t r2) ++{ ++ uint64_t dest = env->regs[r1]; ++ uint64_t src = env->regs[r2]; ++ uint8_t v; ++ c = c & 0xff; ++#ifdef CONFIG_USER_ONLY ++ if (!c) { ++ HELPER_LOG("%s: copying '%s' to 0x%lx\n", __FUNCTION__, (char*)src, dest); ++ } ++#endif ++ for (;;) { ++ v = ldub(src); ++ stb(dest, v); ++ if (v == c) break; ++ src++; dest++; ++ } ++ env->regs[r1] = dest; ++ return 1; ++} ++ ++/* compare and swap 64-bit */ ++uint32_t HELPER(csg)(uint32_t r1, uint64_t a2, uint32_t r3) ++{ ++ /* FIXME: locking? */ ++ uint32_t cc; ++ uint64_t v2 = ldq(a2); ++ if (env->regs[r1] == v2) { ++ cc = 0; ++ stq(a2, env->regs[r3]); ++ } else { ++ cc = 1; ++ env->regs[r1] = v2; ++ } ++ return cc; ++} ++ ++/* compare double and swap 64-bit */ ++uint32_t HELPER(cdsg)(uint32_t r1, uint64_t a2, uint32_t r3) ++{ ++ /* FIXME: locking? */ ++ uint32_t cc; ++ __uint128_t v2 = (((__uint128_t)ldq(a2)) << 64) | (__uint128_t)ldq(a2 + 8); ++ __uint128_t v1 = (((__uint128_t)env->regs[r1]) << 64) | (__uint128_t)env->regs[r1 + 1]; ++ if (v1 == v2) { ++ cc = 0; ++ stq(a2, env->regs[r3]); ++ stq(a2 + 8, env->regs[r3 + 1]); ++ } else { ++ cc = 1; ++ env->regs[r1] = v2 >> 64; ++ env->regs[r1 + 1] = v2 & 0xffffffffffffffffULL; ++ } ++ return cc; ++} ++ ++/* compare and swap 32-bit */ ++uint32_t HELPER(cs)(uint32_t r1, uint64_t a2, uint32_t r3) ++{ ++ /* FIXME: locking? */ ++ uint32_t cc; ++ HELPER_LOG("%s: r1 %d a2 0x%lx r3 %d\n", __FUNCTION__, r1, a2, r3); ++ uint32_t v2 = ldl(a2); ++ if (((uint32_t)env->regs[r1]) == v2) { ++ cc = 0; ++ stl(a2, (uint32_t)env->regs[r3]); ++ } else { ++ cc = 1; ++ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | v2; ++ } ++ return cc; ++} ++ ++/* execute instruction ++ this instruction executes an insn modified with the contents of r1 ++ it does not change the executed instruction in memory ++ it does not change the program counter ++ in other words: tricky... ++ currently implemented by interpreting the cases it is most commonly used in ++ */ ++uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret) ++{ ++ uint16_t insn = lduw(addr); ++ HELPER_LOG("%s: v1 0x%lx addr 0x%lx insn 0x%x\n", __FUNCTION__, v1, addr, ++ insn); ++ if ((insn & 0xf0ff) == 0xd000) { ++ uint32_t l, insn2, b, d1, d2; ++ l = v1 & 0xff; ++ insn2 = ldl_code(addr + 2); ++ b = (((insn2 >> 28) & 0xf) << 4) | ((insn2 >> 12) & 0xf); ++ d1 = (insn2 >> 16) & 0xfff; ++ d2 = insn2 & 0xfff; ++ switch (insn & 0xf00) { ++ case 0x200: helper_mvc(l, b, d1, d2); return cc; break; ++ case 0x500: return helper_clc(l, b, d1, d2); break; ++ case 0x700: return helper_xc(l, b, d1, d2); break; ++ default: goto abort; break; ++ } ++ } ++ else if ((insn & 0xff00) == 0x0a00) { /* supervisor call */ ++ HELPER_LOG("%s: svc %ld via execute\n", __FUNCTION__, (insn|v1) & 0xff); ++ env->psw.addr = ret; ++ helper_exception(EXCP_EXECUTE_SVC + ((insn | v1) & 0xff)); ++ } ++ else { ++abort: ++ cpu_abort(env, "EXECUTE on instruction prefix 0x%x not implemented\n", insn); ++ } ++ return cc; ++} ++ ++/* set condition code for test under mask */ ++uint32_t HELPER(tm)(uint32_t val, uint32_t mask) ++{ ++ HELPER_LOG("%s: val 0x%x mask 0x%x\n", __FUNCTION__, val, mask); ++ uint16_t r = val & mask; ++ if (r == 0) return 0; ++ else if (r == mask) return 3; ++ else return 1; ++} ++ ++/* set condition code for test under mask */ ++uint32_t HELPER(tmxx)(uint64_t val, uint32_t mask) ++{ ++ uint16_t r = val & mask; ++ HELPER_LOG("%s: val 0x%lx mask 0x%x r 0x%x\n", __FUNCTION__, val, mask, r); ++ if (r == 0) return 0; ++ else if (r == mask) return 3; ++ else { ++ while (!(mask & 0x8000)) { ++ mask <<= 1; ++ val <<= 1; ++ } ++ if (val & 0x8000) return 2; ++ else return 1; ++ } ++} ++ ++/* absolute value 32-bit */ ++uint32_t HELPER(abs_i32)(uint32_t reg, int32_t val) ++{ ++ uint32_t cc; ++ if (val == 0x80000000UL) cc = 3; ++ else if (val) cc = 1; ++ else cc = 0; ++ ++ if (val < 0) { ++ env->regs[reg] = -val; ++ } else { ++ env->regs[reg] = val; ++ } ++ return cc; ++} ++ ++/* negative absolute value 32-bit */ ++uint32_t HELPER(nabs_i32)(uint32_t reg, int32_t val) ++{ ++ uint32_t cc; ++ if (val) cc = 1; ++ else cc = 0; ++ ++ if (val < 0) { ++ env->regs[reg] = (env->regs[reg] & 0xffffffff00000000ULL) | val; ++ } else { ++ env->regs[reg] = (env->regs[reg] & 0xffffffff00000000ULL) | ((uint32_t)-val); ++ } ++ return cc; ++} ++ ++/* absolute value 64-bit */ ++uint32_t HELPER(abs_i64)(uint32_t reg, int64_t val) ++{ ++ uint32_t cc; ++ if (val == 0x8000000000000000ULL) cc = 3; ++ else if (val) cc = 1; ++ else cc = 0; ++ ++ if (val < 0) { ++ env->regs[reg] = -val; ++ } else { ++ env->regs[reg] = val; ++ } ++ return cc; ++} ++ ++/* negative absolute value 64-bit */ ++uint32_t HELPER(nabs_i64)(uint32_t reg, int64_t val) ++{ ++ uint32_t cc; ++ if (val) cc = 1; ++ else cc = 0; ++ ++ if (val < 0) { ++ env->regs[reg] = val; ++ } else { ++ env->regs[reg] = -val; ++ } ++ return cc; ++} ++ ++/* add with carry 32-bit unsigned */ ++uint32_t HELPER(addc_u32)(uint32_t cc, uint32_t r1, uint32_t v2) ++{ ++ uint32_t res; ++ uint32_t v1 = env->regs[r1] & 0xffffffffUL; ++ res = v1 + v2; ++ if (cc & 2) res++; ++ ++ if (res == 0) { ++ if (v1) cc = 2; ++ else cc = 0; ++ } else { ++ if (res < v1 || res < v2) { ++ cc = 3; ++ } else { ++ cc = 1; ++ } ++ } ++ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | res; ++ return cc; ++} ++ ++/* CC for add with carry 64-bit unsigned (isn't this a duplicate of some other CC function?) */ ++uint32_t HELPER(set_cc_addc_u64)(uint64_t v1, uint64_t v2, uint64_t res) ++{ ++ uint32_t cc; ++ if (res == 0) { ++ if (v1) cc = 2; ++ else cc = 0; ++ } else { ++ if (res < v1 || res < v2) { ++ cc = 3; ++ } else { ++ cc = 1; ++ } ++ } ++ return cc; ++} ++ ++/* store character under mask high ++ operates on the upper half of r1 */ ++uint32_t HELPER(stcmh)(uint32_t r1, uint64_t address, uint32_t mask) ++{ ++ int pos = 56; /* top of the upper half of r1 */ ++ ++ while (mask) { ++ if (mask & 8) { ++ stb(address, (env->regs[r1] >> pos) & 0xff); ++ address++; ++ } ++ mask = (mask << 1) & 0xf; ++ pos -= 8; ++ } ++ return 0; ++} ++ ++/* insert character under mask high ++ same as icm, but operates on the upper half of r1 */ ++uint32_t HELPER(icmh)(uint32_t r1, uint64_t address, uint32_t mask) ++{ ++ int pos = 56; /* top of the upper half of r1 */ ++ uint64_t rmask = 0xff00000000000000ULL; ++ uint8_t val = 0; ++ int ccd = 0; ++ uint32_t cc; ++ ++ cc = 0; ++ ++ while (mask) { ++ if (mask & 8) { ++ env->regs[r1] &= ~rmask; ++ val = ldub(address); ++ if ((val & 0x80) && !ccd) cc = 1; ++ ccd = 1; ++ if (val && cc == 0) cc = 2; ++ env->regs[r1] |= (uint64_t)val << pos; ++ address++; ++ } ++ mask = (mask << 1) & 0xf; ++ pos -= 8; ++ rmask >>= 8; ++ } ++ return cc; ++} ++ ++/* insert psw mask and condition code into r1 */ ++void HELPER(ipm)(uint32_t cc, uint32_t r1) ++{ ++ uint64_t r = env->regs[r1]; ++ r &= 0xffffffff00ffffffULL; ++ r |= (cc << 28) | ( (env->psw.mask >> 40) & 0xf ); ++ env->regs[r1] = r; ++ HELPER_LOG("%s: cc %d psw.mask 0x%lx r1 0x%lx\n", __FUNCTION__, cc, env->psw.mask, r); ++} ++ ++/* store access registers r1 to r3 in memory at a2 */ ++void HELPER(stam)(uint32_t r1, uint64_t a2, uint32_t r3) ++{ ++ int i; ++ for (i = r1; i != ((r3 + 1) & 15); i = (i + 1) & 15) { ++ stl(a2, env->aregs[i]); ++ a2 += 4; ++ } ++} ++ ++/* move long extended ++ another memcopy insn with more bells and whistles */ ++uint32_t HELPER(mvcle)(uint32_t r1, uint64_t a2, uint32_t r3) ++{ ++ uint64_t destlen = env->regs[r1 + 1]; ++ uint64_t dest = env->regs[r1]; ++ uint64_t srclen = env->regs[r3 + 1]; ++ uint64_t src = env->regs[r3]; ++ uint8_t pad = a2 & 0xff; ++ uint8_t v; ++ uint32_t cc; ++ if (destlen == srclen) cc = 0; ++ else if (destlen < srclen) cc = 1; ++ else cc = 2; ++ if (srclen > destlen) srclen = destlen; ++ for(;destlen && srclen;src++,dest++,destlen--,srclen--) { ++ v = ldub(src); ++ stb(dest, v); ++ } ++ for(;destlen;dest++,destlen--) { ++ stb(dest, pad); ++ } ++ env->regs[r1 + 1] = destlen; ++ env->regs[r3 + 1] -= src - env->regs[r3]; /* can't use srclen here, ++ we trunc'ed it */ ++ env->regs[r1] = dest; ++ env->regs[r3] = src; ++ ++ return cc; ++} ++ ++/* compare logical long extended ++ memcompare insn with padding */ ++uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3) ++{ ++ uint64_t destlen = env->regs[r1 + 1]; ++ uint64_t dest = env->regs[r1]; ++ uint64_t srclen = env->regs[r3 + 1]; ++ uint64_t src = env->regs[r3]; ++ uint8_t pad = a2 & 0xff; ++ uint8_t v1 = 0,v2 = 0; ++ uint32_t cc = 0; ++ if (!(destlen || srclen)) return cc; ++ if (srclen > destlen) srclen = destlen; ++ for(;destlen || srclen;src++,dest++,destlen--,srclen--) { ++ if (srclen) v1 = ldub(src); ++ else v1 = pad; ++ if (destlen) v2 = ldub(dest); ++ else v2 = pad; ++ if (v1 != v2) break; ++ } ++ ++ env->regs[r1 + 1] = destlen; ++ env->regs[r3 + 1] -= src - env->regs[r3]; /* can't use srclen here, ++ we trunc'ed it */ ++ env->regs[r1] = dest; ++ env->regs[r3] = src; ++ ++ if (v1 < v2) cc = 1; ++ else if (v1 > v2) cc = 2; ++ ++ return cc; ++} ++ ++/* subtract unsigned v2 from v1 with borrow */ ++uint32_t HELPER(slb)(uint32_t cc, uint32_t r1, uint32_t v1, uint32_t v2) ++{ ++ uint32_t res = v1 + (~v2) + (cc >> 1); ++ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | res; ++ if (cc & 2) { /* borrow */ ++ if (v1) return 1; ++ else return 0; ++ } else { ++ if (v1) return 3; ++ else return 2; ++ } ++} ++ ++/* subtract unsigned v2 from v1 with borrow */ ++uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2) ++{ ++ uint64_t res = v1 + (~v2) + (cc >> 1); ++ env->regs[r1] = res; ++ if (cc & 2) { /* borrow */ ++ if (v1) return 1; ++ else return 0; ++ } else { ++ if (v1) return 3; ++ else return 2; ++ } ++} ++ ++/* condition codes for binary FP ops */ ++static uint32_t set_cc_f32(float32 v1, float32 v2) ++{ ++ if (float32_is_nan(v1) || float32_is_nan(v2)) return 3; ++ else if (float32_eq(v1, v2, &env->fpu_status)) return 0; ++ else if (float32_lt(v1, v2, &env->fpu_status)) return 1; ++ else return 2; ++} ++ ++static uint32_t set_cc_f64(float64 v1, float64 v2) ++{ ++ if (float64_is_nan(v1) || float64_is_nan(v2)) return 3; ++ else if (float64_eq(v1, v2, &env->fpu_status)) return 0; ++ else if (float64_lt(v1, v2, &env->fpu_status)) return 1; ++ else return 2; ++} ++ ++/* condition codes for unary FP ops */ ++static uint32_t set_cc_nz_f32(float32 v) ++{ ++ if (float32_is_nan(v)) return 3; ++ else if (float32_is_zero(v)) return 0; ++ else if (float32_is_neg(v)) return 1; ++ else return 2; ++} ++ ++static uint32_t set_cc_nz_f64(float64 v) ++{ ++ if (float64_is_nan(v)) return 3; ++ else if (float64_is_zero(v)) return 0; ++ else if (float64_is_neg(v)) return 1; ++ else return 2; ++} ++ ++static uint32_t set_cc_nz_f128(float128 v) ++{ ++ if (float128_is_nan(v)) return 3; ++ else if (float128_is_zero(v)) return 0; ++ else if (float128_is_neg(v)) return 1; ++ else return 2; ++} ++ ++/* convert 32-bit int to 64-bit float */ ++void HELPER(cdfbr)(uint32_t f1, int32_t v2) ++{ ++ HELPER_LOG("%s: converting %d to f%d\n", __FUNCTION__, v2, f1); ++ env->fregs[f1].d = int32_to_float64(v2, &env->fpu_status); ++} ++ ++/* convert 32-bit int to 128-bit float */ ++void HELPER(cxfbr)(uint32_t f1, int32_t v2) ++{ ++ CPU_QuadU v1; ++ v1.q = int32_to_float128(v2, &env->fpu_status); ++ env->fregs[f1].ll = v1.ll.upper; ++ env->fregs[f1 + 2].ll = v1.ll.lower; ++} ++ ++/* convert 64-bit int to 32-bit float */ ++void HELPER(cegbr)(uint32_t f1, int64_t v2) ++{ ++ HELPER_LOG("%s: converting %ld to f%d\n", __FUNCTION__, v2, f1); ++ env->fregs[f1].l.upper = int64_to_float32(v2, &env->fpu_status); ++} ++ ++/* convert 64-bit int to 64-bit float */ ++void HELPER(cdgbr)(uint32_t f1, int64_t v2) ++{ ++ HELPER_LOG("%s: converting %ld to f%d\n", __FUNCTION__, v2, f1); ++ env->fregs[f1].d = int64_to_float64(v2, &env->fpu_status); ++} ++ ++/* convert 64-bit int to 128-bit float */ ++void HELPER(cxgbr)(uint32_t f1, int64_t v2) ++{ ++ CPU_QuadU x1; ++ x1.q = int64_to_float128(v2, &env->fpu_status); ++ HELPER_LOG("%s: converted %ld to 0x%lx and 0x%lx\n", __FUNCTION__, v2, x1.ll.upper, x1.l); ++ env->fregs[f1].ll = x1.ll.upper; ++ env->fregs[f1 + 2].ll = x1.ll.lower; ++} ++ ++/* convert 32-bit int to 32-bit float */ ++void HELPER(cefbr)(uint32_t f1, int32_t v2) ++{ ++ env->fregs[f1].l.upper = int32_to_float32(v2, &env->fpu_status); ++ HELPER_LOG("%s: converting %d to 0x%d in f%d\n", __FUNCTION__, v2, env->fregs[f1].l.upper, f1); ++} ++ ++/* 32-bit FP addition RR */ ++uint32_t HELPER(aebr)(uint32_t f1, uint32_t f2) ++{ ++ env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper, env->fregs[f2].l.upper, &env->fpu_status); ++ HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __FUNCTION__, env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1); ++ return set_cc_nz_f32(env->fregs[f1].l.upper); ++} ++ ++/* 64-bit FP addition RR */ ++uint32_t HELPER(adbr)(uint32_t f1, uint32_t f2) ++{ ++ env->fregs[f1].d = float64_add(env->fregs[f1].d, env->fregs[f2].d, &env->fpu_status); ++ HELPER_LOG("%s: adding 0x%ld resulting in 0x%ld in f%d\n", __FUNCTION__, env->fregs[f2].d, env->fregs[f1].d, f1); ++ return set_cc_nz_f64(env->fregs[f1].d); ++} ++ ++/* 32-bit FP subtraction RR */ ++uint32_t HELPER(sebr)(uint32_t f1, uint32_t f2) ++{ ++ env->fregs[f1].l.upper = float32_sub(env->fregs[f1].l.upper, env->fregs[f2].l.upper, &env->fpu_status); ++ HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __FUNCTION__, env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1); ++ return set_cc_nz_f32(env->fregs[f1].l.upper); ++} ++ ++/* 64-bit FP subtraction RR */ ++uint32_t HELPER(sdbr)(uint32_t f1, uint32_t f2) ++{ ++ env->fregs[f1].d = float64_sub(env->fregs[f1].d, env->fregs[f2].d, &env->fpu_status); ++ HELPER_LOG("%s: subtracting 0x%ld resulting in 0x%ld in f%d\n", __FUNCTION__, env->fregs[f2].d, env->fregs[f1].d, f1); ++ return set_cc_nz_f64(env->fregs[f1].d); ++} ++ ++/* 32-bit FP division RR */ ++void HELPER(debr)(uint32_t f1, uint32_t f2) ++{ ++ env->fregs[f1].l.upper = float32_div(env->fregs[f1].l.upper, env->fregs[f2].l.upper, &env->fpu_status); ++} ++ ++/* 128-bit FP division RR */ ++void HELPER(dxbr)(uint32_t f1, uint32_t f2) ++{ ++ CPU_QuadU v1; ++ v1.ll.upper = env->fregs[f1].ll; ++ v1.ll.lower = env->fregs[f1 + 2].ll; ++ CPU_QuadU v2; ++ v2.ll.upper = env->fregs[f2].ll; ++ v2.ll.lower = env->fregs[f2 + 2].ll; ++ CPU_QuadU res; ++ res.q = float128_div(v1.q, v2.q, &env->fpu_status); ++ env->fregs[f1].ll = res.ll.upper; ++ env->fregs[f1 + 2].ll = res.ll.lower; ++} ++ ++/* 64-bit FP multiplication RR */ ++void HELPER(mdbr)(uint32_t f1, uint32_t f2) ++{ ++ env->fregs[f1].d = float64_mul(env->fregs[f1].d, env->fregs[f2].d, &env->fpu_status); ++} ++ ++/* 128-bit FP multiplication RR */ ++void HELPER(mxbr)(uint32_t f1, uint32_t f2) ++{ ++ CPU_QuadU v1; ++ v1.ll.upper = env->fregs[f1].ll; ++ v1.ll.lower = env->fregs[f1 + 2].ll; ++ CPU_QuadU v2; ++ v2.ll.upper = env->fregs[f2].ll; ++ v2.ll.lower = env->fregs[f2 + 2].ll; ++ CPU_QuadU res; ++ res.q = float128_mul(v1.q, v2.q, &env->fpu_status); ++ env->fregs[f1].ll = res.ll.upper; ++ env->fregs[f1 + 2].ll = res.ll.lower; ++} ++ ++/* convert 32-bit float to 64-bit float */ ++void HELPER(ldebr)(uint32_t r1, uint32_t r2) ++{ ++ env->fregs[r1].d = float32_to_float64(env->fregs[r2].l.upper, &env->fpu_status); ++} ++ ++/* convert 128-bit float to 64-bit float */ ++void HELPER(ldxbr)(uint32_t f1, uint32_t f2) ++{ ++ CPU_QuadU x2; ++ x2.ll.upper = env->fregs[f2].ll; ++ x2.ll.lower = env->fregs[f2 + 2].ll; ++ env->fregs[f1].d = float128_to_float64(x2.q, &env->fpu_status); ++ HELPER_LOG("%s: to 0x%ld\n", __FUNCTION__, env->fregs[f1].d); ++} ++ ++/* convert 64-bit float to 128-bit float */ ++void HELPER(lxdbr)(uint32_t f1, uint32_t f2) ++{ ++ CPU_QuadU res; ++ res.q = float64_to_float128(env->fregs[f2].d, &env->fpu_status); ++ env->fregs[f1].ll = res.ll.upper; ++ env->fregs[f1 + 2].ll = res.ll.lower; ++} ++ ++/* convert 64-bit float to 32-bit float */ ++void HELPER(ledbr)(uint32_t f1, uint32_t f2) ++{ ++ float64 d2 = env->fregs[f2].d; ++ env->fregs[f1].l.upper = float64_to_float32(d2, &env->fpu_status); ++} ++ ++/* convert 128-bit float to 32-bit float */ ++void HELPER(lexbr)(uint32_t f1, uint32_t f2) ++{ ++ CPU_QuadU x2; ++ x2.ll.upper = env->fregs[f2].ll; ++ x2.ll.lower = env->fregs[f2 + 2].ll; ++ env->fregs[f1].l.upper = float128_to_float32(x2.q, &env->fpu_status); ++ HELPER_LOG("%s: to 0x%d\n", __FUNCTION__, env->fregs[f1].l.upper); ++} ++ ++/* absolute value of 32-bit float */ ++uint32_t HELPER(lpebr)(uint32_t f1, uint32_t f2) ++{ ++ float32 v1; ++ float32 v2 = env->fregs[f2].d; ++ v1 = float32_abs(v2); ++ env->fregs[f1].d = v1; ++ return set_cc_nz_f32(v1); ++} ++ ++/* absolute value of 64-bit float */ ++uint32_t HELPER(lpdbr)(uint32_t f1, uint32_t f2) ++{ ++ float64 v1; ++ float64 v2 = env->fregs[f2].d; ++ v1 = float64_abs(v2); ++ env->fregs[f1].d = v1; ++ return set_cc_nz_f64(v1); ++} ++ ++/* absolute value of 128-bit float */ ++uint32_t HELPER(lpxbr)(uint32_t f1, uint32_t f2) ++{ ++ CPU_QuadU v1; ++ CPU_QuadU v2; ++ v2.ll.upper = env->fregs[f2].ll; ++ v2.ll.lower = env->fregs[f2 + 2].ll; ++ v1.q = float128_abs(v2.q); ++ env->fregs[f1].ll = v1.ll.upper; ++ env->fregs[f1 + 2].ll = v1.ll.lower; ++ return set_cc_nz_f128(v1.q); ++} ++ ++/* load and test 64-bit float */ ++uint32_t HELPER(ltdbr)(uint32_t f1, uint32_t f2) ++{ ++ env->fregs[f1].d = env->fregs[f2].d; ++ return set_cc_nz_f64(env->fregs[f1].d); ++} ++ ++/* load and test 32-bit float */ ++uint32_t HELPER(ltebr)(uint32_t f1, uint32_t f2) ++{ ++ env->fregs[f1].l.upper = env->fregs[f2].l.upper; ++ return set_cc_nz_f32(env->fregs[f1].l.upper); ++} ++ ++/* load and test 128-bit float */ ++uint32_t HELPER(ltxbr)(uint32_t f1, uint32_t f2) ++{ ++ CPU_QuadU x; ++ x.ll.upper = env->fregs[f2].ll; ++ x.ll.lower = env->fregs[f2 + 2].ll; ++ env->fregs[f1].ll = x.ll.upper; ++ env->fregs[f1 + 2].ll = x.ll.lower; ++ return set_cc_nz_f128(x.q); ++} ++ ++/* negative absolute of 32-bit float */ ++uint32_t HELPER(lcebr)(uint32_t f1, uint32_t f2) ++{ ++ env->fregs[f1].l.upper = float32_sub(float32_zero, env->fregs[f2].l.upper, &env->fpu_status); ++ return set_cc_nz_f32(env->fregs[f1].l.upper); ++} ++ ++/* negative absolute of 64-bit float */ ++uint32_t HELPER(lcdbr)(uint32_t f1, uint32_t f2) ++{ ++ env->fregs[f1].d = float64_sub(float64_zero, env->fregs[f2].d, &env->fpu_status); ++ return set_cc_nz_f64(env->fregs[f1].d); ++} ++ ++/* convert 64-bit float to 128-bit float */ ++uint32_t HELPER(lcxbr)(uint32_t f1, uint32_t f2) ++{ ++ CPU_QuadU x1, x2; ++ x2.ll.upper = env->fregs[f2].ll; ++ x2.ll.lower = env->fregs[f2 + 2].ll; ++ x1.q = float128_sub(float64_to_float128(float64_zero, &env->fpu_status), x2.q, &env->fpu_status); ++ env->fregs[f1].ll = x1.ll.upper; ++ env->fregs[f1 + 2].ll = x1.ll.lower; ++ return set_cc_nz_f128(x1.q); ++} ++ ++/* 32-bit FP compare RM */ ++uint32_t HELPER(ceb)(uint32_t f1, uint32_t val) ++{ ++ float32 v1 = env->fregs[f1].l.upper; ++ CPU_FloatU v2; ++ v2.l = val; ++ HELPER_LOG("%s: comparing 0x%d from f%d and 0x%d\n", __FUNCTION__, v1, f1, v2.f); ++ return set_cc_f32(v1, v2.f); ++} ++ ++/* 32-bit FP addition RM */ ++uint32_t HELPER(aeb)(uint32_t f1, uint32_t val) ++{ ++ float32 v1 = env->fregs[f1].l.upper; ++ CPU_FloatU v2; ++ v2.l = val; ++ HELPER_LOG("%s: adding 0x%d from f%d and 0x%d\n", __FUNCTION__, v1, f1, v2.f); ++ env->fregs[f1].l.upper = float32_add(v1, v2.f, &env->fpu_status); ++ return set_cc_nz_f32(env->fregs[f1].l.upper); ++} ++ ++/* 32-bit FP division RM */ ++void HELPER(deb)(uint32_t f1, uint32_t val) ++{ ++ float32 v1 = env->fregs[f1].l.upper; ++ CPU_FloatU v2; ++ v2.l = val; ++ HELPER_LOG("%s: dividing 0x%d from f%d by 0x%d\n", __FUNCTION__, v1, f1, v2.f); ++ env->fregs[f1].l.upper = float32_div(v1, v2.f, &env->fpu_status); ++} ++ ++/* 32-bit FP multiplication RM */ ++void HELPER(meeb)(uint32_t f1, uint32_t val) ++{ ++ float32 v1 = env->fregs[f1].l.upper; ++ CPU_FloatU v2; ++ v2.l = val; ++ HELPER_LOG("%s: multiplying 0x%d from f%d and 0x%d\n", __FUNCTION__, v1, f1, v2.f); ++ env->fregs[f1].l.upper = float32_mul(v1, v2.f, &env->fpu_status); ++} ++ ++/* 32-bit FP compare RR */ ++uint32_t HELPER(cebr)(uint32_t f1, uint32_t f2) ++{ ++ float32 v1 = env->fregs[f1].l.upper; ++ float32 v2 = env->fregs[f2].l.upper;; ++ HELPER_LOG("%s: comparing 0x%d from f%d and 0x%d\n", __FUNCTION__, v1, f1, v2); ++ return set_cc_f32(v1, v2); ++} ++ ++/* 64-bit FP compare RR */ ++uint32_t HELPER(cdbr)(uint32_t f1, uint32_t f2) ++{ ++ float64 v1 = env->fregs[f1].d; ++ float64 v2 = env->fregs[f2].d;; ++ HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%ld\n", __FUNCTION__, v1, f1, v2); ++ return set_cc_f64(v1, v2); ++} ++ ++/* 128-bit FP compare RR */ ++uint32_t HELPER(cxbr)(uint32_t f1, uint32_t f2) ++{ ++ CPU_QuadU v1; ++ v1.ll.upper = env->fregs[f1].ll; ++ v1.ll.lower = env->fregs[f1 + 2].ll; ++ CPU_QuadU v2; ++ v2.ll.upper = env->fregs[f2].ll; ++ v2.ll.lower = env->fregs[f2 + 2].ll; ++ if (float128_is_nan(v1.q) || float128_is_nan(v2.q)) return 3; ++ else if (float128_eq(v1.q, v2.q, &env->fpu_status)) return 0; ++ else if (float128_lt(v1.q, v2.q, &env->fpu_status)) return 1; ++ else return 2; ++} ++ ++/* 64-bit FP compare RM */ ++uint32_t HELPER(cdb)(uint32_t f1, uint64_t a2) ++{ ++ float64 v1 = env->fregs[f1].d; ++ CPU_DoubleU v2; ++ v2.ll = ldq(a2); ++ HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%lx\n", __FUNCTION__, v1, f1, v2.d); ++ return set_cc_f64(v1, v2.d); ++} ++ ++/* 64-bit FP addition RM */ ++uint32_t HELPER(adb)(uint32_t f1, uint64_t a2) ++{ ++ float64 v1 = env->fregs[f1].d; ++ CPU_DoubleU v2; ++ v2.ll = ldq(a2); ++ HELPER_LOG("%s: adding 0x%lx from f%d and 0x%lx\n", __FUNCTION__, v1, f1, v2.d); ++ env->fregs[f1].d = v1 = float64_add(v1, v2.d, &env->fpu_status); ++ return set_cc_nz_f64(v1); ++} ++ ++/* 32-bit FP subtraction RM */ ++uint32_t HELPER(seb)(uint32_t f1, uint32_t val) ++{ ++ float32 v1 = env->fregs[f1].l.upper; ++ CPU_FloatU v2; ++ v2.l = val; ++ env->fregs[f1].l.upper = v1 = float32_sub(v1, v2.f, &env->fpu_status); ++ return set_cc_nz_f32(v1); ++} ++ ++/* 64-bit FP subtraction RM */ ++uint32_t HELPER(sdb)(uint32_t f1, uint64_t a2) ++{ ++ float64 v1 = env->fregs[f1].d; ++ CPU_DoubleU v2; ++ v2.ll = ldq(a2); ++ env->fregs[f1].d = v1 = float64_sub(v1, v2.d, &env->fpu_status); ++ return set_cc_nz_f64(v1); ++} ++ ++/* 64-bit FP multiplication RM */ ++void HELPER(mdb)(uint32_t f1, uint64_t a2) ++{ ++ float64 v1 = env->fregs[f1].d; ++ CPU_DoubleU v2; ++ v2.ll = ldq(a2); ++ HELPER_LOG("%s: multiplying 0x%lx from f%d and 0x%ld\n", __FUNCTION__, v1, f1, v2.d); ++ env->fregs[f1].d = float64_mul(v1, v2.d, &env->fpu_status); ++} ++ ++/* 64-bit FP division RM */ ++void HELPER(ddb)(uint32_t f1, uint64_t a2) ++{ ++ float64 v1 = env->fregs[f1].d; ++ CPU_DoubleU v2; ++ v2.ll = ldq(a2); ++ HELPER_LOG("%s: dividing 0x%lx from f%d by 0x%ld\n", __FUNCTION__, v1, f1, v2.d); ++ env->fregs[f1].d = float64_div(v1, v2.d, &env->fpu_status); ++} ++ ++static void set_round_mode(int m3) ++{ ++ switch (m3) { ++ case 0: break; /* current mode */ ++ case 1: /* biased round no nearest */ ++ case 4: /* round to nearest */ ++ set_float_rounding_mode(float_round_nearest_even, &env->fpu_status); ++ break; ++ case 5: /* round to zero */ ++ set_float_rounding_mode(float_round_to_zero, &env->fpu_status); ++ break; ++ case 6: /* round to +inf */ ++ set_float_rounding_mode(float_round_up, &env->fpu_status); ++ break; ++ case 7: /* round to -inf */ ++ set_float_rounding_mode(float_round_down, &env->fpu_status); ++ break; ++ } ++} ++ ++/* convert 32-bit float to 64-bit int */ ++uint32_t HELPER(cgebr)(uint32_t r1, uint32_t f2, uint32_t m3) ++{ ++ float32 v2 = env->fregs[f2].l.upper; ++ set_round_mode(m3); ++ env->regs[r1] = float32_to_int64(v2, &env->fpu_status); ++ return set_cc_nz_f32(v2); ++} ++ ++/* convert 64-bit float to 64-bit int */ ++uint32_t HELPER(cgdbr)(uint32_t r1, uint32_t f2, uint32_t m3) ++{ ++ float64 v2 = env->fregs[f2].d; ++ set_round_mode(m3); ++ env->regs[r1] = float64_to_int64(v2, &env->fpu_status); ++ return set_cc_nz_f64(v2); ++} ++ ++/* convert 128-bit float to 64-bit int */ ++uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3) ++{ ++ CPU_QuadU v2; ++ v2.ll.upper = env->fregs[f2].ll; ++ v2.ll.lower = env->fregs[f2 + 2].ll; ++ set_round_mode(m3); ++ env->regs[r1] = float128_to_int64(v2.q, &env->fpu_status); ++ if (float128_is_nan(v2.q)) return 3; ++ else if (float128_is_zero(v2.q)) return 0; ++ else if (float128_is_neg(v2.q)) return 1; ++ else return 2; ++} ++ ++/* convert 32-bit float to 32-bit int */ ++uint32_t HELPER(cfebr)(uint32_t r1, uint32_t f2, uint32_t m3) ++{ ++ float32 v2 = env->fregs[f2].l.upper; ++ set_round_mode(m3); ++ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | float32_to_int32(v2, &env->fpu_status); ++ return set_cc_nz_f32(v2); ++} ++ ++/* convert 64-bit float to 32-bit int */ ++uint32_t HELPER(cfdbr)(uint32_t r1, uint32_t f2, uint32_t m3) ++{ ++ float64 v2 = env->fregs[f2].d; ++ set_round_mode(m3); ++ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | float64_to_int32(v2, &env->fpu_status); ++ return set_cc_nz_f64(v2); ++} ++ ++/* convert 128-bit float to 32-bit int */ ++uint32_t HELPER(cfxbr)(uint32_t r1, uint32_t f2, uint32_t m3) ++{ ++ CPU_QuadU v2; ++ v2.ll.upper = env->fregs[f2].ll; ++ v2.ll.lower = env->fregs[f2 + 2].ll; ++ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | float128_to_int32(v2.q, &env->fpu_status); ++ return set_cc_nz_f128(v2.q); ++} ++ ++/* load 32-bit FP zero */ ++void HELPER(lzer)(uint32_t f1) ++{ ++ env->fregs[f1].l.upper = float32_zero; ++} ++ ++/* load 64-bit FP zero */ ++void HELPER(lzdr)(uint32_t f1) ++{ ++ env->fregs[f1].d = float64_zero; ++} ++ ++/* load 128-bit FP zero */ ++void HELPER(lzxr)(uint32_t f1) ++{ ++ CPU_QuadU x; ++ x.q = float64_to_float128(float64_zero, &env->fpu_status); ++ env->fregs[f1].ll = x.ll.upper; ++ env->fregs[f1 + 1].ll = x.ll.lower; ++} ++ ++/* 128-bit FP subtraction RR */ ++uint32_t HELPER(sxbr)(uint32_t f1, uint32_t f2) ++{ ++ CPU_QuadU v1; ++ v1.ll.upper = env->fregs[f1].ll; ++ v1.ll.lower = env->fregs[f1 + 2].ll; ++ CPU_QuadU v2; ++ v2.ll.upper = env->fregs[f2].ll; ++ v2.ll.lower = env->fregs[f2 + 2].ll; ++ CPU_QuadU res; ++ res.q = float128_sub(v1.q, v2.q, &env->fpu_status); ++ env->fregs[f1].ll = res.ll.upper; ++ env->fregs[f1 + 2].ll = res.ll.lower; ++ return set_cc_nz_f128(res.q); ++} ++ ++/* 128-bit FP addition RR */ ++uint32_t HELPER(axbr)(uint32_t f1, uint32_t f2) ++{ ++ CPU_QuadU v1; ++ v1.ll.upper = env->fregs[f1].ll; ++ v1.ll.lower = env->fregs[f1 + 2].ll; ++ CPU_QuadU v2; ++ v2.ll.upper = env->fregs[f2].ll; ++ v2.ll.lower = env->fregs[f2 + 2].ll; ++ CPU_QuadU res; ++ res.q = float128_add(v1.q, v2.q, &env->fpu_status); ++ env->fregs[f1].ll = res.ll.upper; ++ env->fregs[f1 + 2].ll = res.ll.lower; ++ return set_cc_nz_f128(res.q); ++} ++ ++/* 32-bit FP multiplication RR */ ++void HELPER(meebr)(uint32_t f1, uint32_t f2) ++{ ++ env->fregs[f1].l.upper = float32_mul(env->fregs[f1].l.upper, env->fregs[f2].l.upper, &env->fpu_status); ++} ++ ++/* 64-bit FP division RR */ ++void HELPER(ddbr)(uint32_t f1, uint32_t f2) ++{ ++ env->fregs[f1].d = float64_div(env->fregs[f1].d, env->fregs[f2].d, &env->fpu_status); ++} ++ ++/* 64-bit FP multiply and add RM */ ++void HELPER(madb)(uint32_t f1, uint64_t a2, uint32_t f3) ++{ ++ HELPER_LOG("%s: f1 %d a2 0x%lx f3 %d\n", __FUNCTION__, f1, a2, f3); ++ CPU_DoubleU v2; ++ v2.ll = ldq(a2); ++ env->fregs[f1].d = float64_add(env->fregs[f1].d, float64_mul(v2.d, env->fregs[f3].d, &env->fpu_status), &env->fpu_status); ++} ++ ++/* 64-bit FP multiply and add RR */ ++void HELPER(madbr)(uint32_t f1, uint32_t f3, uint32_t f2) ++{ ++ HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __FUNCTION__, f1, f2, f3); ++ env->fregs[f1].d = float64_add(float64_mul(env->fregs[f2].d, env->fregs[f3].d, &env->fpu_status), env->fregs[f1].d, &env->fpu_status); ++} ++ ++/* 64-bit FP multiply and subtract RR */ ++void HELPER(msdbr)(uint32_t f1, uint32_t f3, uint32_t f2) ++{ ++ HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __FUNCTION__, f1, f2, f3); ++ env->fregs[f1].d = float64_sub(float64_mul(env->fregs[f2].d, env->fregs[f3].d, &env->fpu_status), env->fregs[f1].d, &env->fpu_status); ++} ++ ++/* 32-bit FP multiply and add RR */ ++void HELPER(maebr)(uint32_t f1, uint32_t f3, uint32_t f2) ++{ ++ env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper, float32_mul(env->fregs[f2].l.upper, env->fregs[f3].l.upper, &env->fpu_status), &env->fpu_status); ++} ++ ++/* convert 64-bit float to 128-bit float */ ++void HELPER(lxdb)(uint32_t f1, uint64_t a2) ++{ ++ CPU_DoubleU v2; ++ v2.ll = ldq(a2); ++ CPU_QuadU v1; ++ v1.q = float64_to_float128(v2.d, &env->fpu_status); ++ env->fregs[f1].ll = v1.ll.upper; ++ env->fregs[f1 + 2].ll = v1.ll.lower; ++} ++ ++/* test data class 32-bit */ ++uint32_t HELPER(tceb)(uint32_t f1, uint64_t m2) ++{ ++ float32 v1 = env->fregs[f1].l.upper; ++ int neg = float32_is_neg(v1); ++ uint32_t cc = 0; ++ HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __FUNCTION__, v1, m2, neg); ++ if (float32_is_zero(v1) && (m2 & (1 << (11-neg)))) cc = 1; ++ else if (float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) cc = 1; ++ else if (float32_is_nan(v1) && (m2 & (1 << (3-neg)))) cc = 1; ++ else if (float32_is_signaling_nan(v1) && (m2 & (1 << (1-neg)))) cc = 1; ++ else /* assume normalized number */ if (m2 & (1 << (9-neg))) cc = 1; ++ /* FIXME: denormalized? */ ++ return cc; ++} ++ ++/* test data class 64-bit */ ++uint32_t HELPER(tcdb)(uint32_t f1, uint64_t m2) ++{ ++ float64 v1 = env->fregs[f1].d; ++ int neg = float64_is_neg(v1); ++ uint32_t cc = 0; ++ HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __FUNCTION__, v1, m2, neg); ++ if (float64_is_zero(v1) && (m2 & (1 << (11-neg)))) cc = 1; ++ else if (float64_is_infinity(v1) && (m2 & (1 << (5-neg)))) cc = 1; ++ else if (float64_is_nan(v1) && (m2 & (1 << (3-neg)))) cc = 1; ++ else if (float64_is_signaling_nan(v1) && (m2 & (1 << (1-neg)))) cc = 1; ++ else /* assume normalized number */ if (m2 & (1 << (9-neg))) cc = 1; ++ /* FIXME: denormalized? */ ++ return cc; ++} ++ ++/* test data class 128-bit */ ++uint32_t HELPER(tcxb)(uint32_t f1, uint64_t m2) ++{ ++ CPU_QuadU v1; ++ uint32_t cc = 0; ++ v1.ll.upper = env->fregs[f1].ll; ++ v1.ll.lower = env->fregs[f1 + 2].ll; ++ ++ int neg = float128_is_neg(v1.q); ++ if (float128_is_zero(v1.q) && (m2 & (1 << (11-neg)))) cc = 1; ++ else if (float128_is_infinity(v1.q) && (m2 & (1 << (5-neg)))) cc = 1; ++ else if (float128_is_nan(v1.q) && (m2 & (1 << (3-neg)))) cc = 1; ++ else if (float128_is_signaling_nan(v1.q) && (m2 & (1 << (1-neg)))) cc = 1; ++ else /* assume normalized number */ if (m2 & (1 << (9-neg))) cc = 1; ++ /* FIXME: denormalized? */ ++ return cc; ++} ++ ++/* find leftmost one */ ++uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2) ++{ ++ uint64_t res = 0; ++ uint64_t ov2 = v2; ++ while (!(v2 & 0x8000000000000000ULL) && v2) { ++ v2 <<= 1; ++ res++; ++ } ++ if (!v2) { ++ env->regs[r1] = 64; ++ env->regs[r1 + 1] = 0; ++ return 0; ++ } ++ else { ++ env->regs[r1] = res; ++ env->regs[r1 + 1] = ov2 & ~(0x8000000000000000ULL >> res); ++ return 2; ++ } ++} ++ ++/* square root 64-bit RR */ ++void HELPER(sqdbr)(uint32_t f1, uint32_t f2) ++{ ++ env->fregs[f1].d = float64_sqrt(env->fregs[f2].d, &env->fpu_status); ++} +Index: qemu-0.14.1/target-s390x/translate.c +=================================================================== +--- qemu-0.14.1.orig/target-s390x/translate.c ++++ qemu-0.14.1/target-s390x/translate.c +@@ -16,6 +16,18 @@ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ ++#include ++#include ++#include ++#include ++#include ++ ++#define S390X_DEBUG_DISAS ++#ifdef S390X_DEBUG_DISAS ++# define LOG_DISAS(...) qemu_log(__VA_ARGS__) ++#else ++# define LOG_DISAS(...) do { } while (0) ++#endif + + #include "cpu.h" + #include "exec-all.h" +@@ -23,6 +35,25 @@ + #include "tcg-op.h" + #include "qemu-log.h" + ++/* global register indexes */ ++static TCGv_ptr cpu_env; ++ ++#include "gen-icount.h" ++#include "helpers.h" ++#define GEN_HELPER 1 ++#include "helpers.h" ++ ++typedef struct DisasContext DisasContext; ++struct DisasContext { ++ uint64_t pc; ++ int is_jmp; ++ CPUS390XState *env; ++ struct TranslationBlock *tb; ++}; ++ ++#define DISAS_EXCP 4 ++#define DISAS_SVC 5 ++ + void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf, + int flags) + { +@@ -46,12 +77,2776 @@ void cpu_dump_state(CPUState *env, FILE + cpu_fprintf(f, "PSW=mask %016lx addr %016lx cc %02x\n", env->psw.mask, env->psw.addr, env->cc); + } + ++#define TCGREGS ++ ++static TCGv global_cc; ++#ifdef TCGREGS ++/* registers stored in TCG variables enhance performance */ ++static TCGv_i64 tcgregs[16]; ++static TCGv_i32 tcgregs32[16]; ++#endif ++static TCGv cc; ++static TCGv psw_addr; ++ ++void s390x_translate_init(void) ++{ ++ cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); ++ global_cc = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, cc), "global_cc"); ++#ifdef TCGREGS ++ int i; ++ char rn[4]; ++ for (i = 0; i < 16; i++) { ++ sprintf(rn, "R%d", i); ++ tcgregs[i] = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, regs[i]), strdup(rn)); ++ sprintf(rn, "r%d", i); ++ tcgregs32[i] = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, regs[i]) ++#ifdef HOST_WORDS_BIGENDIAN ++ + 4 ++#endif ++ , strdup(rn)); ++ } ++#endif ++ psw_addr = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, psw.addr), "psw_addr"); ++} ++ ++#ifdef TCGREGS ++static inline void sync_reg64(int reg) ++{ ++ tcg_gen_sync_i64(tcgregs[reg]); ++} ++static inline void sync_reg32(int reg) ++{ ++ tcg_gen_sync_i32(tcgregs32[reg]); ++} ++#endif ++ ++static TCGv load_reg(int reg) ++{ ++ TCGv r = tcg_temp_new_i64(); ++#ifdef TCGREGS ++ sync_reg32(reg); ++ tcg_gen_mov_i64(r, tcgregs[reg]); ++ return r; ++#else ++ tcg_gen_ld_i64(r, cpu_env, offsetof(CPUState, regs[reg])); ++ return r; ++#endif ++} ++ ++static TCGv load_freg(int reg) ++{ ++ TCGv r = tcg_temp_new_i64(); ++ tcg_gen_ld_i64(r, cpu_env, offsetof(CPUState, fregs[reg].d)); ++ return r; ++} ++ ++static TCGv_i32 load_freg32(int reg) ++{ ++ TCGv_i32 r = tcg_temp_new_i32(); ++ tcg_gen_ld_i32(r, cpu_env, offsetof(CPUState, fregs[reg].l.upper)); ++ return r; ++} ++ ++static void load_reg32_var(TCGv_i32 r, int reg) ++{ ++#ifdef TCGREGS ++ sync_reg64(reg); ++ tcg_gen_mov_i32(r, tcgregs32[reg]); ++#else ++#ifdef HOST_WORDS_BIGENDIAN ++ tcg_gen_ld_i32(r, cpu_env, offsetof(CPUState, regs[reg]) + 4); ++#else ++ tcg_gen_ld_i32(r, cpu_env, offsetof(CPUState, regs[reg])); ++#endif ++#endif ++} ++ ++static TCGv_i32 load_reg32(int reg) ++{ ++ TCGv_i32 r = tcg_temp_new_i32(); ++ load_reg32_var(r, reg); ++ return r; ++} ++ ++static void store_reg(int reg, TCGv v) ++{ ++#ifdef TCGREGS ++ sync_reg32(reg); ++ tcg_gen_mov_i64(tcgregs[reg], v); ++#else ++ tcg_gen_st_i64(v, cpu_env, offsetof(CPUState, regs[reg])); ++#endif ++} ++ ++static void store_freg(int reg, TCGv v) ++{ ++ tcg_gen_st_i64(v, cpu_env, offsetof(CPUState, fregs[reg].d)); ++} ++ ++static void store_reg32(int reg, TCGv_i32 v) ++{ ++#ifdef TCGREGS ++ sync_reg64(reg); ++ tcg_gen_mov_i32(tcgregs32[reg], v); ++#else ++#ifdef HOST_WORDS_BIGENDIAN ++ tcg_gen_st_i32(v, cpu_env, offsetof(CPUState, regs[reg]) + 4); ++#else ++ tcg_gen_st_i32(v, cpu_env, offsetof(CPUState, regs[reg])); ++#endif ++#endif ++} ++ ++static void store_reg8(int reg, TCGv_i32 v) ++{ ++#ifdef TCGREGS ++ TCGv_i32 tmp = tcg_temp_new_i32(); ++ sync_reg64(reg); ++ tcg_gen_andi_i32(tmp, tcgregs32[reg], 0xffffff00UL); ++ tcg_gen_or_i32(tcgregs32[reg], tmp, v); ++ tcg_temp_free(tmp); ++#else ++#ifdef HOST_WORDS_BIGENDIAN ++ tcg_gen_st8_i32(v, cpu_env, offsetof(CPUState, regs[reg]) + 7); ++#else ++ tcg_gen_st8_i32(v, cpu_env, offsetof(CPUState, regs[reg])); ++#endif ++#endif ++} ++ ++static void store_freg32(int reg, TCGv v) ++{ ++ tcg_gen_st_i32(v, cpu_env, offsetof(CPUState, fregs[reg].l.upper)); ++} ++ ++static void gen_illegal_opcode(DisasContext *s) ++{ ++ TCGv tmp = tcg_const_i64(EXCP_SPEC); ++ gen_helper_exception(tmp); ++ tcg_temp_free(tmp); ++ s->is_jmp = DISAS_EXCP; ++} ++ ++#define DEBUGINSN LOG_DISAS("insn: 0x%lx\n", insn); ++ ++static TCGv get_address(int x2, int b2, int d2) ++{ ++ TCGv tmp = 0, tmp2; ++ if (d2) tmp = tcg_const_i64(d2); ++ if (x2) { ++ if (d2) { ++ tmp2 = load_reg(x2); ++ tcg_gen_add_i64(tmp, tmp, tmp2); ++ tcg_temp_free(tmp2); ++ } ++ else { ++ tmp = load_reg(x2); ++ } ++ } ++ if (b2) { ++ if (d2 || x2) { ++ tmp2 = load_reg(b2); ++ tcg_gen_add_i64(tmp, tmp, tmp2); ++ tcg_temp_free(tmp2); ++ } ++ else { ++ tmp = load_reg(b2); ++ } ++ } ++ ++ if (!(d2 || x2 || b2)) tmp = tcg_const_i64(0); ++ ++ return tmp; ++} ++ ++static inline void set_cc_nz_u32(TCGv val) ++{ ++ gen_helper_set_cc_nz_u32(cc, val); ++} ++ ++static inline void set_cc_nz_u64(TCGv val) ++{ ++ gen_helper_set_cc_nz_u64(cc, val); ++} ++ ++static inline void set_cc_s32(TCGv val) ++{ ++ gen_helper_set_cc_s32(cc, val); ++} ++ ++static inline void set_cc_s64(TCGv val) ++{ ++ gen_helper_set_cc_s64(cc, val); ++} ++ ++static inline void cmp_s32(TCGv v1, TCGv v2) ++{ ++ gen_helper_cmp_s32(cc, v1, v2); ++} ++ ++static inline void cmp_u32(TCGv v1, TCGv v2) ++{ ++ gen_helper_cmp_u32(cc, v1, v2); ++} ++ ++/* this is a hysterical raisin */ ++static inline void cmp_s32c(TCGv v1, int32_t v2) ++{ ++ TCGv_i32 tmp = tcg_const_i32(v2); ++ gen_helper_cmp_s32(cc, v1, tmp); ++ tcg_temp_free(tmp); ++} ++static inline void cmp_u32c(TCGv v1, uint32_t v2) ++{ ++ TCGv_i32 tmp = tcg_const_i32(v2); ++ gen_helper_cmp_u32(cc, v1, tmp); ++ tcg_temp_free(tmp); ++} ++ ++ ++static inline void cmp_s64(TCGv v1, TCGv v2) ++{ ++ gen_helper_cmp_s64(cc, v1, v2); ++} ++ ++static inline void cmp_u64(TCGv v1, TCGv v2) ++{ ++ gen_helper_cmp_u64(cc, v1, v2); ++} ++ ++/* see cmp_[su]32c() */ ++static inline void cmp_s64c(TCGv v1, int64_t v2) ++{ ++ TCGv_i32 tmp = tcg_const_i64(v2); ++ gen_helper_cmp_s64(cc, v1, tmp); ++ tcg_temp_free(tmp); ++} ++static inline void cmp_u64c(TCGv v1, uint64_t v2) ++{ ++ TCGv_i32 tmp = tcg_const_i64(v2); ++ gen_helper_cmp_u64(cc, v1, tmp); ++ tcg_temp_free(tmp); ++} ++ ++static void gen_bcr(uint32_t mask, int tr, uint64_t offset) ++{ ++ TCGv target, o; ++ TCGv_i32 m; ++ if (mask == 0xf) { /* unconditional */ ++ target = load_reg(tr); ++ tcg_gen_mov_i64(psw_addr, target); ++ } ++ else { ++ m = tcg_const_i32(mask); ++ o = tcg_const_i64(offset); ++ gen_helper_bcr(cc, m, (target = load_reg(tr)), o); ++ tcg_temp_free(m); ++ tcg_temp_free(o); ++ } ++ tcg_temp_free(target); ++} ++ ++static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong pc) ++{ ++ TranslationBlock *tb; ++ ++ tb = s->tb; ++ /* NOTE: we handle the case where the TB spans two pages here */ ++ if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) || ++ (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK)) { ++ /* jump to same page: we can use a direct jump */ ++ tcg_gen_mov_i32(global_cc, cc); ++ tcg_gen_goto_tb(tb_num); ++ tcg_gen_movi_i64(psw_addr, pc); ++ tcg_gen_exit_tb((long)tb + tb_num); ++ } else { ++ /* jump to another page: currently not optimized */ ++ tcg_gen_movi_i64(psw_addr, pc); ++ tcg_gen_mov_i32(global_cc, cc); ++ tcg_gen_exit_tb(0); ++ } ++} ++ ++static void gen_brc(uint32_t mask, DisasContext *s, int32_t offset) ++{ ++ TCGv_i32 r; ++ TCGv_i32 tmp, tmp2; ++ int skip; ++ ++ if (mask == 0xf) { /* unconditional */ ++ //tcg_gen_movi_i64(psw_addr, s->pc + offset); ++ gen_goto_tb(s, 0, s->pc + offset); ++ } ++ else { ++ tmp = tcg_const_i32(3); ++ tcg_gen_sub_i32(tmp, tmp, cc); /* 3 - cc */ ++ tmp2 = tcg_const_i32(1); ++ tcg_gen_shl_i32(tmp2, tmp2, tmp); /* 1 << (3 - cc) */ ++ r = tcg_const_i32(mask); ++ tcg_gen_and_i32(r, r, tmp2); /* mask & (1 << (3 - cc)) */ ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ skip = gen_new_label(); ++ tcg_gen_brcondi_i32(TCG_COND_EQ, r, 0, skip); ++ gen_goto_tb(s, 0, s->pc + offset); ++ gen_set_label(skip); ++ gen_goto_tb(s, 1, s->pc + 4); ++ //tcg_gen_mov_i32(global_cc, cc); ++ tcg_temp_free(r); ++ } ++ s->is_jmp = DISAS_TB_JUMP; ++} ++ ++static void gen_set_cc_add64(TCGv v1, TCGv v2, TCGv vr) ++{ ++ gen_helper_set_cc_add64(cc, v1, v2, vr); ++} ++ ++static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2) ++{ ++ TCGv tmp, tmp2, tmp3; ++ ++ LOG_DISAS("disas_e3: op 0x%x r1 %d x2 %d b2 %d d2 %d\n", op, r1, x2, b2, d2); ++ tmp = get_address(x2, b2, d2); ++ switch (op) { ++ case 0x2: /* LTG R1,D2(X2,B2) [RXY] */ ++ case 0x4: /* lg r1,d2(x2,b2) */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld64(tmp2, tmp, 1); ++ store_reg(r1, tmp2); ++ if (op == 0x2) set_cc_s64(tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x12: /* LT R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32s(tmp2, tmp, 1); ++ store_reg32(r1, tmp2); ++ set_cc_s32(tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0xc: /* MSG R1,D2(X2,B2) [RXY] */ ++ case 0x1c: /* MSGF R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ if (op == 0xc) { ++ tcg_gen_qemu_ld64(tmp2, tmp, 1); ++ } ++ else { ++ tcg_gen_qemu_ld32s(tmp2, tmp, 1); ++ } ++ tcg_temp_free(tmp); ++ tmp = load_reg(r1); ++ tcg_gen_mul_i64(tmp, tmp, tmp2); ++ store_reg(r1, tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 0xd: /* DSG R1,D2(X2,B2) [RXY] */ ++ case 0x1d: /* DSGF R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ if (op == 0x1d) { ++ tcg_gen_qemu_ld32s(tmp2, tmp, 1); ++ } ++ else { ++ tcg_gen_qemu_ld64(tmp2, tmp, 1); ++ } ++ tcg_temp_free(tmp); ++ tmp = load_reg(r1 + 1); ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_div_i64(tmp3, tmp, tmp2); ++ store_reg(r1 + 1, tmp3); ++ tcg_gen_rem_i64(tmp3, tmp, tmp2); ++ store_reg(r1, tmp3); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x8: /* AG R1,D2(X2,B2) [RXY] */ ++ case 0xa: /* ALG R1,D2(X2,B2) [RXY] */ ++ case 0x18: /* AGF R1,D2(X2,B2) [RXY] */ ++ case 0x1a: /* ALGF R1,D2(X2,B2) [RXY] */ ++ if (op == 0x1a) { ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp2, tmp, 1); ++ } ++ else if (op == 0x18) { ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32s(tmp2, tmp, 1); ++ } ++ else { ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld64(tmp2, tmp, 1); ++ } ++ tcg_temp_free(tmp); ++ tmp = load_reg(r1); ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_add_i64(tmp3, tmp, tmp2); ++ store_reg(r1, tmp3); ++ switch (op) { ++ case 0x8: case 0x18: gen_set_cc_add64(tmp, tmp2, tmp3); break; ++ case 0xa: case 0x1a: gen_helper_set_cc_addu64(cc, tmp, tmp2, tmp3); break; ++ default: tcg_abort(); ++ } ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x9: /* SG R1,D2(X2,B2) [RXY] */ ++ case 0xb: /* SLG R1,D2(X2,B2) [RXY] */ ++ case 0x19: /* SGF R1,D2(X2,B2) [RXY] */ ++ case 0x1b: /* SLGF R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ if (op == 0x19) { ++ tcg_gen_qemu_ld32s(tmp2, tmp, 1); ++ } ++ else if (op == 0x1b) { ++ tcg_gen_qemu_ld32u(tmp2, tmp, 1); ++ } ++ else { ++ tcg_gen_qemu_ld64(tmp2, tmp, 1); ++ } ++ tcg_temp_free(tmp); ++ tmp = load_reg(r1); ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_sub_i64(tmp3, tmp, tmp2); ++ store_reg(r1, tmp3); ++ switch (op) { ++ case 0x9: case 0x19: gen_helper_set_cc_sub64(cc, tmp, tmp2, tmp3); break; ++ case 0xb: case 0x1b: gen_helper_set_cc_subu64(cc, tmp, tmp2, tmp3); break; ++ default: tcg_abort(); ++ } ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x14: /* LGF R1,D2(X2,B2) [RXY] */ ++ case 0x16: /* LLGF R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp2, tmp, 1); ++ switch (op) { ++ case 0x14: tcg_gen_ext32s_i64(tmp2, tmp2); break; ++ case 0x16: break; ++ default: tcg_abort(); ++ } ++ store_reg(r1, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x15: /* LGH R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld16s(tmp2, tmp, 1); ++ store_reg(r1, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x17: /* LLGT R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp2, tmp, 1); ++ tcg_gen_andi_i64(tmp2, tmp2, 0x7fffffffULL); ++ store_reg(r1, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x1e: /* LRV R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp2, tmp, 1); ++ tcg_gen_bswap32_i64(tmp2, tmp2); ++ store_reg32(r1, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x20: /* CG R1,D2(X2,B2) [RXY] */ ++ case 0x21: /* CLG R1,D2(X2,B2) */ ++ case 0x30: /* CGF R1,D2(X2,B2) [RXY] */ ++ case 0x31: /* CLGF R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ switch (op) { ++ case 0x20: ++ case 0x21: ++ tcg_gen_qemu_ld64(tmp2, tmp, 1); ++ break; ++ case 0x30: ++ tcg_gen_qemu_ld32s(tmp2, tmp, 1); ++ break; ++ case 0x31: ++ tcg_gen_qemu_ld32u(tmp2, tmp, 1); ++ break; ++ default: ++ tcg_abort(); ++ } ++ tcg_temp_free(tmp); ++ tmp = load_reg(r1); ++ switch (op) { ++ case 0x20: case 0x30: cmp_s64(tmp, tmp2); break; ++ case 0x21: case 0x31: cmp_u64(tmp, tmp2); break; ++ default: tcg_abort(); ++ } ++ tcg_temp_free(tmp2); ++ break; ++ case 0x24: /* stg r1, d2(x2,b2) */ ++ tmp2 = load_reg(r1); ++ tcg_gen_qemu_st64(tmp2, tmp, 1); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x3e: /* STRV R1,D2(X2,B2) [RXY] */ ++ tmp2 = load_reg32(r1); ++ tcg_gen_bswap32_i32(tmp2, tmp2); ++ tcg_gen_qemu_st32(tmp2, tmp, 1); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x50: /* STY R1,D2(X2,B2) [RXY] */ ++ tmp2 = load_reg32(r1); ++ tcg_gen_qemu_st32(tmp2, tmp, 1); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x57: /* XY R1,D2(X2,B2) [RXY] */ ++ tmp2 = load_reg32(r1); ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp3, tmp, 1); ++ tcg_gen_xor_i32(tmp, tmp2, tmp3); ++ store_reg32(r1, tmp); ++ set_cc_nz_u32(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x58: /* LY R1,D2(X2,B2) [RXY] */ ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp3, tmp, 1); ++ store_reg32(r1, tmp3); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x5a: /* AY R1,D2(X2,B2) [RXY] */ ++ case 0x5b: /* SY R1,D2(X2,B2) [RXY] */ ++ tmp2 = load_reg32(r1); ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32s(tmp3, tmp, 1); ++ switch (op) { ++ case 0x5a: tcg_gen_add_i32(tmp, tmp2, tmp3); break; ++ case 0x5b: tcg_gen_sub_i32(tmp, tmp2, tmp3); break; ++ default: tcg_abort(); ++ } ++ store_reg32(r1, tmp); ++ switch (op) { ++ case 0x5a: gen_helper_set_cc_add32(cc, tmp2, tmp3, tmp); break; ++ case 0x5b: gen_helper_set_cc_sub32(cc, tmp2, tmp3, tmp); break; ++ default: tcg_abort(); ++ } ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x71: /* LAY R1,D2(X2,B2) [RXY] */ ++ store_reg(r1, tmp); ++ break; ++ case 0x72: /* STCY R1,D2(X2,B2) [RXY] */ ++ tmp2 = load_reg32(r1); ++ tcg_gen_qemu_st8(tmp2, tmp, 1); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x73: /* ICY R1,D2(X2,B2) [RXY] */ ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld8u(tmp3, tmp, 1); ++ store_reg8(r1, tmp3); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x76: /* LB R1,D2(X2,B2) [RXY] */ ++ case 0x77: /* LGB R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld8s(tmp2, tmp, 1); ++ switch (op) { ++ case 0x76: ++ tcg_gen_ext8s_i64(tmp2, tmp2); ++ store_reg32(r1, tmp2); ++ break; ++ case 0x77: ++ tcg_gen_ext8s_i64(tmp2, tmp2); ++ store_reg(r1, tmp2); ++ break; ++ default: tcg_abort(); ++ } ++ tcg_temp_free(tmp2); ++ break; ++ case 0x78: /* LHY R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld16s(tmp2, tmp, 1); ++ store_reg32(r1, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x80: /* NG R1,D2(X2,B2) [RXY] */ ++ case 0x81: /* OG R1,D2(X2,B2) [RXY] */ ++ case 0x82: /* XG R1,D2(X2,B2) [RXY] */ ++ tmp2 = load_reg(r1); ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld64(tmp3, tmp, 1); ++ switch (op) { ++ case 0x80: tcg_gen_and_i64(tmp, tmp2, tmp3); break; ++ case 0x81: tcg_gen_or_i64(tmp, tmp2, tmp3); break; ++ case 0x82: tcg_gen_xor_i64(tmp, tmp2, tmp3); break; ++ default: tcg_abort(); ++ } ++ store_reg(r1, tmp); ++ set_cc_nz_u64(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x86: /* MLG R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld64(tmp2, tmp, 1); ++ tcg_temp_free(tmp); ++ tmp = tcg_const_i32(r1); ++ gen_helper_mlg(tmp, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x87: /* DLG R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld64(tmp2, tmp, 1); ++ tcg_temp_free(tmp); ++ tmp = tcg_const_i32(r1); ++ gen_helper_dlg(tmp, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x88: /* ALCG R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld64(tmp2, tmp, 1); ++ tcg_temp_free(tmp); ++ tmp = load_reg(r1); ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_shri_i64(tmp3, cc, 1); ++ tcg_gen_andi_i64(tmp3, tmp3, 1); ++ tcg_gen_add_i64(tmp3, tmp2, tmp3);; ++ tcg_gen_add_i64(tmp3, tmp, tmp3); ++ store_reg(r1, tmp3); ++ gen_helper_set_cc_addc_u64(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x89: /* SLBG R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld64(tmp2, tmp, 1); ++ tcg_temp_free(tmp); ++ tmp = load_reg(r1); ++ tmp3 = tcg_const_i32(r1); ++ gen_helper_slbg(cc, cc, tmp3, tmp, tmp2); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x90: /* LLGC R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld8u(tmp2, tmp, 1); ++ store_reg(r1, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x91: /* LLGH R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld16u(tmp2, tmp, 1); ++ store_reg(r1, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x94: /* LLC R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld8u(tmp2, tmp, 1); ++ store_reg32(r1, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x95: /* LLH R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld16u(tmp2, tmp, 1); ++ store_reg32(r1, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x98: /* ALC R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp2, tmp, 1); ++ tcg_temp_free(tmp); ++ tmp = tcg_const_i32(r1); ++ gen_helper_addc_u32(cc, cc, tmp, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x99: /* SLB R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp2, tmp, 1); ++ tcg_temp_free(tmp); ++ tmp = load_reg32(r1); ++ tmp3 = tcg_const_i32(r1); ++ gen_helper_slb(cc, cc, tmp3, tmp, tmp2); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ default: ++ LOG_DISAS("illegal e3 operation 0x%x\n", op); ++ gen_illegal_opcode(s); ++ break; ++ } ++ tcg_temp_free(tmp); ++} ++ ++static void disas_eb(DisasContext *s, int op, int r1, int r3, int b2, int d2) ++{ ++ TCGv tmp, tmp2, tmp3, tmp4; ++ int i; ++ ++ LOG_DISAS("disas_eb: op 0x%x r1 %d r3 %d b2 %d d2 0x%x\n", op, r1, r3, b2, d2); ++ switch (op) { ++ case 0xc: /* SRLG R1,R3,D2(B2) [RSY] */ ++ case 0xd: /* SLLG R1,R3,D2(B2) [RSY] */ ++ case 0xa: /* SRAG R1,R3,D2(B2) [RSY] */ ++ case 0x1c: /* RLLG R1,R3,D2(B2) [RSY] */ ++ if (b2) { ++ tmp = get_address(0, b2, d2); ++ tcg_gen_andi_i64(tmp, tmp, 0x3f); ++ } else { ++ tmp = tcg_const_i64(d2 & 0x3f); ++ } ++ tmp2 = load_reg(r3); ++ tmp3 = tcg_temp_new_i64(); ++ switch (op) { ++ case 0xc: tcg_gen_shr_i64(tmp3, tmp2, tmp); break; ++ case 0xd: tcg_gen_shl_i64(tmp3, tmp2, tmp); break; ++ case 0xa: tcg_gen_sar_i64(tmp3, tmp2, tmp); break; ++ case 0x1c: tcg_gen_rotl_i64(tmp3, tmp2, tmp); break; ++ default: tcg_abort(); break; ++ } ++ store_reg(r1, tmp3); ++ if (op == 0xa) set_cc_s64(tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x1d: /* RLL R1,R3,D2(B2) [RSY] */ ++ if (b2) { ++ tmp = get_address(0, b2, d2); ++ tcg_gen_andi_i64(tmp, tmp, 0x3f); ++ } else { ++ tmp = tcg_const_i64(d2 & 0x3f); ++ } ++ tmp2 = load_reg32(r3); ++ tmp3 = tcg_temp_new_i32(); ++ switch (op) { ++ case 0x1d: tcg_gen_rotl_i32(tmp3, tmp2, tmp); break; ++ default: tcg_abort(); break; ++ } ++ store_reg32(r1, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x4: /* LMG R1,R3,D2(B2) [RSY] */ ++ case 0x24: /* stmg */ ++ /* Apparently, unrolling lmg/stmg of any size gains performance - ++ even for very long ones... */ ++ if (r3 > r1) { ++ tmp = get_address(0, b2, d2); ++ for (i = r1; i <= r3; i++) { ++ if (op == 0x4) { ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld64(tmp2, tmp, 1); ++ store_reg(i, tmp2); ++ /* At least one register is usually read after an lmg ++ (br %rsomething), which is why freeing them is ++ detrimental to performance */ ++ } ++ else { ++ tmp2 = load_reg(i); ++ tcg_gen_qemu_st64(tmp2, tmp, 1); ++ /* R15 is usually read after an stmg; other registers ++ generally aren't and can be free'd */ ++ if (i != 15) tcg_temp_free(tmp2); ++ } ++ tcg_gen_addi_i64(tmp, tmp, 8); ++ } ++ } ++ else { ++ tmp = tcg_const_i32(r1); ++ tmp2 = tcg_const_i32(r3); ++ tmp3 = tcg_const_i32(b2); ++ tmp4 = tcg_const_i32(d2); ++ if (op == 0x4) gen_helper_lmg(tmp, tmp2, tmp3, tmp4); ++ else gen_helper_stmg(tmp, tmp2, tmp3, tmp4); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ tcg_temp_free(tmp4); ++ } ++ tcg_temp_free(tmp); ++ break; ++ case 0x2c: /* STCMH R1,M3,D2(B2) [RSY] */ ++ tmp2 = get_address(0, b2, d2); ++ tmp = tcg_const_i32(r1); ++ tmp3 = tcg_const_i32(r3); ++ gen_helper_stcmh(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x30: /* CSG R1,R3,D2(B2) [RSY] */ ++ tmp2 = get_address(0, b2, d2); ++ tmp = tcg_const_i32(r1); ++ tmp3 = tcg_const_i32(r3); ++ gen_helper_csg(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x3e: /* CDSG R1,R3,D2(B2) [RSY] */ ++ tmp2 = get_address(0, b2, d2); ++ tmp = tcg_const_i32(r1); ++ tmp3 = tcg_const_i32(r3); ++ gen_helper_cdsg(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x51: /* TMY D1(B1),I2 [SIY] */ ++ tmp = get_address(0, b2, d2); /* SIY -> this is the destination */ ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld8u(tmp2, tmp, 1); ++ tcg_temp_free(tmp); ++ tmp = tcg_const_i32((r1 << 4) | r3); ++ gen_helper_tm(cc, tmp2, tmp); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x52: /* MVIY D1(B1),I2 [SIY] */ ++ tmp2 = tcg_const_i32((r1 << 4) | r3); ++ tmp = get_address(0, b2, d2); /* SIY -> this is the destination */ ++ tcg_gen_qemu_st8(tmp2, tmp, 1); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x55: /* CLIY D1(B1),I2 [SIY] */ ++ tmp3 = get_address(0, b2, d2); /* SIY -> this is the 1st operand */ ++ tmp = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld8u(tmp, tmp3, 1); ++ cmp_u32c(tmp, (r1 << 4) | r3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x80: /* ICMH R1,M3,D2(B2) [RSY] */ ++ tmp2 = get_address(0, b2, d2); ++ tmp = tcg_const_i32(r1); ++ tmp3 = tcg_const_i32(r3); ++ gen_helper_icmh(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ default: ++ LOG_DISAS("illegal eb operation 0x%x\n", op); ++ gen_illegal_opcode(s); ++ break; ++ } ++} ++ ++static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2, int r1b) ++{ ++ TCGv_i32 tmp; ++ TCGv tmp2, tmp3; ++ tmp2 = get_address(x2, b2, d2); ++ tmp = tcg_const_i32(r1); ++ switch (op) { ++ case 0x5: /* LXDB R1,D2(X2,B2) [RXE] */ ++ gen_helper_lxdb(tmp, tmp2); ++ break; ++ case 0x9: /* CEB R1,D2(X2,B2) [RXE] */ ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp3, tmp2, 1); ++ gen_helper_ceb(cc, tmp, tmp3); ++ tcg_temp_free(tmp3); ++ break; ++ case 0xa: /* AEB R1,D2(X2,B2) [RXE] */ ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp3, tmp2, 1); ++ gen_helper_aeb(cc, tmp, tmp3); ++ tcg_temp_free(tmp3); ++ break; ++ case 0xb: /* SEB R1,D2(X2,B2) [RXE] */ ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp3, tmp2, 1); ++ gen_helper_seb(cc, tmp, tmp3); ++ tcg_temp_free(tmp3); ++ break; ++ case 0xd: /* DEB R1,D2(X2,B2) [RXE] */ ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp3, tmp2, 1); ++ gen_helper_deb(tmp, tmp3); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x10: /* TCEB R1,D2(X2,B2) [RXE] */ ++ gen_helper_tceb(cc, tmp, tmp2); ++ break; ++ case 0x11: /* TCDB R1,D2(X2,B2) [RXE] */ ++ gen_helper_tcdb(cc, tmp, tmp2); ++ break; ++ case 0x12: /* TCXB R1,D2(X2,B2) [RXE] */ ++ gen_helper_tcxb(cc, tmp, tmp2); ++ break; ++ case 0x17: /* MEEB R1,D2(X2,B2) [RXE] */ ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp3, tmp2, 1); ++ gen_helper_meeb(tmp, tmp3); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x19: /* CDB R1,D2(X2,B2) [RXE] */ ++ gen_helper_cdb(cc, tmp, tmp2); ++ break; ++ case 0x1a: /* ADB R1,D2(X2,B2) [RXE] */ ++ gen_helper_adb(cc, tmp, tmp2); ++ break; ++ case 0x1b: /* SDB R1,D2(X2,B2) [RXE] */ ++ gen_helper_sdb(cc, tmp, tmp2); ++ break; ++ case 0x1c: /* MDB R1,D2(X2,B2) [RXE] */ ++ gen_helper_mdb(tmp, tmp2); ++ break; ++ case 0x1d: /* DDB R1,D2(X2,B2) [RXE] */ ++ gen_helper_ddb(tmp, tmp2); ++ break; ++ case 0x1e: /* MADB R1,R3,D2(X2,B2) [RXF] */ ++ /* for RXF insns, r1 is R3 and r1b is R1 */ ++ tmp3 = tcg_const_i32(r1b); ++ gen_helper_madb(tmp3, tmp2, tmp); ++ tcg_temp_free(tmp3); ++ break; ++ default: ++ LOG_DISAS("illegal ed operation 0x%x\n", op); ++ gen_illegal_opcode(s); ++ return; ++ } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++} ++ ++static void disas_a5(DisasContext *s, int op, int r1, int i2) ++{ ++ TCGv tmp, tmp2; ++ uint64_t vtmp; ++ LOG_DISAS("disas_a5: op 0x%x r1 %d i2 0x%x\n", op, r1, i2); ++ switch (op) { ++ case 0x0: /* IIHH R1,I2 [RI] */ ++ case 0x1: /* IIHL R1,I2 [RI] */ ++ tmp = load_reg(r1); ++ vtmp = i2; ++ switch (op) { ++ case 0x0: tcg_gen_andi_i64(tmp, tmp, 0x0000ffffffffffffULL); vtmp <<= 48; break; ++ case 0x1: tcg_gen_andi_i64(tmp, tmp, 0xffff0000ffffffffULL); vtmp <<= 32; break; ++ default: tcg_abort(); ++ } ++ tcg_gen_ori_i64(tmp, tmp, vtmp); ++ store_reg(r1, tmp); ++ break; ++ case 0x4: /* NIHH R1,I2 [RI] */ ++ case 0x8: /* OIHH R1,I2 [RI] */ ++ tmp = load_reg(r1); ++ switch (op) { ++ case 0x4: ++ tmp2 = tcg_const_i64( (((uint64_t)i2) << 48) | 0x0000ffffffffffffULL); ++ tcg_gen_and_i64(tmp, tmp, tmp2); ++ break; ++ case 0x8: ++ tmp2 = tcg_const_i64(((uint64_t)i2) << 48); ++ tcg_gen_or_i64(tmp, tmp, tmp2); ++ break; ++ default: tcg_abort(); ++ } ++ store_reg(r1, tmp); ++ tcg_gen_shri_i64(tmp2, tmp, 48); ++ tcg_gen_trunc_i64_i32(tmp2, tmp2); ++ set_cc_nz_u32(tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x5: /* NIHL R1,I2 [RI] */ ++ case 0x9: /* OIHL R1,I2 [RI] */ ++ tmp = load_reg(r1); ++ switch (op) { ++ case 0x5: ++ tmp2 = tcg_const_i64( (((uint64_t)i2) << 32) | 0xffff0000ffffffffULL); ++ tcg_gen_and_i64(tmp, tmp, tmp2); ++ break; ++ case 0x9: ++ tmp2 = tcg_const_i64(((uint64_t)i2) << 32); ++ tcg_gen_or_i64(tmp, tmp, tmp2); ++ break; ++ default: tcg_abort(); ++ } ++ store_reg(r1, tmp); ++ tcg_gen_shri_i64(tmp2, tmp, 32); ++ tcg_gen_trunc_i64_i32(tmp2, tmp2); ++ tcg_gen_andi_i32(tmp2, tmp2, 0xffff); ++ set_cc_nz_u32(tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x6: /* NILH R1,I2 [RI] */ ++ case 0xa: /* OILH R1,I2 [RI] */ ++ tmp = load_reg(r1); ++ switch (op) { ++ case 0x6: ++ tmp2 = tcg_const_i64( (((uint64_t)i2) << 16) | 0xffffffff0000ffffULL); ++ tcg_gen_and_i64(tmp, tmp, tmp2); ++ break; ++ case 0xa: ++ tmp2 = tcg_const_i64(((uint64_t)i2) << 16); ++ tcg_gen_or_i64(tmp, tmp, tmp2); ++ break; ++ default: tcg_abort(); ++ } ++ store_reg(r1, tmp); ++ tcg_gen_shri_i64(tmp2, tmp, 16); ++ tcg_gen_trunc_i64_i32(tmp2, tmp2); ++ tcg_gen_andi_i32(tmp2, tmp2, 0xffff); ++ set_cc_nz_u32(tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x7: /* NILL R1,I2 [RI] */ ++ case 0xb: /* OILL R1,I2 [RI] */ ++ tmp = load_reg(r1); ++ switch (op) { ++ case 0x7: ++ tmp2 = tcg_const_i64(i2 | 0xffffffffffff0000ULL); ++ tcg_gen_and_i64(tmp, tmp, tmp2); ++ break; ++ case 0xb: ++ tmp2 = tcg_const_i64(i2); ++ tcg_gen_or_i64(tmp, tmp, tmp2); ++ break; ++ default: tcg_abort(); break; ++ } ++ store_reg(r1, tmp); ++ tcg_gen_trunc_i64_i32(tmp, tmp); ++ tcg_gen_andi_i32(tmp, tmp, 0xffff); ++ set_cc_nz_u32(tmp); /* signedness should not matter here */ ++ tcg_temp_free(tmp2); ++ break; ++ case 0xc: /* LLIHH R1,I2 [RI] */ ++ tmp = tcg_const_i64( ((uint64_t)i2) << 48 ); ++ store_reg(r1, tmp); ++ break; ++ case 0xd: /* LLIHL R1,I2 [RI] */ ++ tmp = tcg_const_i64( ((uint64_t)i2) << 32 ); ++ store_reg(r1, tmp); ++ break; ++ case 0xe: /* LLILH R1,I2 [RI] */ ++ tmp = tcg_const_i64( ((uint64_t)i2) << 16 ); ++ store_reg(r1, tmp); ++ break; ++ case 0xf: /* LLILL R1,I2 [RI] */ ++ tmp = tcg_const_i64(i2); ++ store_reg(r1, tmp); ++ break; ++ default: ++ LOG_DISAS("illegal a5 operation 0x%x\n", op); ++ gen_illegal_opcode(s); ++ return; ++ } ++ tcg_temp_free(tmp); ++} ++ ++static void disas_a7(DisasContext *s, int op, int r1, int i2) ++{ ++ TCGv tmp, tmp2, tmp3; ++ LOG_DISAS("disas_a7: op 0x%x r1 %d i2 0x%x\n", op, r1, i2); ++ switch (op) { ++ case 0x0: /* TMLH or TMH R1,I2 [RI] */ ++ tmp = load_reg(r1); ++ tcg_gen_shri_i64(tmp, tmp, 16); ++ tmp2 = tcg_const_i32((uint16_t)i2); ++ gen_helper_tmxx(cc, tmp, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x1: /* TMLL or TML R1,I2 [RI] */ ++ tmp = load_reg(r1); ++ tmp2 = tcg_const_i32((uint16_t)i2); ++ gen_helper_tmxx(cc, tmp, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x2: /* TMHH R1,I2 [RI] */ ++ tmp = load_reg(r1); ++ tcg_gen_shri_i64(tmp, tmp, 48); ++ tmp2 = tcg_const_i32((uint16_t)i2); ++ gen_helper_tmxx(cc, tmp, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x3: /* TMHL R1,I2 [RI] */ ++ tmp = load_reg(r1); ++ tcg_gen_shri_i64(tmp, tmp, 32); ++ tmp2 = tcg_const_i32((uint16_t)i2); ++ gen_helper_tmxx(cc, tmp, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x4: /* brc m1, i2 */ ++ gen_brc(r1, s, i2 * 2); ++ return; ++ case 0x5: /* BRAS R1,I2 [RI] */ ++ tmp = tcg_const_i64(s->pc + 4); ++ store_reg(r1, tmp); ++ tcg_temp_free(tmp); ++ tmp = tcg_const_i64(s->pc + i2 * 2); ++ tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, psw.addr)); ++ s->is_jmp = DISAS_JUMP; ++ break; ++ case 0x6: /* BRCT R1,I2 [RI] */ ++ tmp = load_reg32(r1); ++ tcg_gen_subi_i32(tmp, tmp, 1); ++ store_reg32(r1, tmp); ++ tmp2 = tcg_const_i64(s->pc); ++ tmp3 = tcg_const_i32(i2 * 2); ++ gen_helper_brct(tmp, tmp2, tmp3); ++ s->is_jmp = DISAS_JUMP; ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x7: /* BRCTG R1,I2 [RI] */ ++ tmp = load_reg(r1); ++ tcg_gen_subi_i64(tmp, tmp, 1); ++ store_reg(r1, tmp); ++ tmp2 = tcg_const_i64(s->pc); ++ tmp3 = tcg_const_i32(i2 * 2); ++ gen_helper_brctg(tmp, tmp2, tmp3); ++ s->is_jmp = DISAS_JUMP; ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x8: /* lhi r1, i2 */ ++ tmp = tcg_const_i32(i2); ++ store_reg32(r1, tmp); ++ break; ++ case 0x9: /* lghi r1, i2 */ ++ tmp = tcg_const_i64(i2); ++ store_reg(r1, tmp); ++ break; ++ case 0xa: /* AHI R1,I2 [RI] */ ++ tmp = load_reg32(r1); ++ tmp3 = tcg_temp_new_i32(); ++ tcg_gen_addi_i32(tmp3, tmp, i2); ++ store_reg32(r1, tmp3); ++ tmp2 = tcg_const_i32(i2); ++ gen_helper_set_cc_add32(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0xb: /* aghi r1, i2 */ ++ tmp = load_reg(r1); ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_addi_i64(tmp3, tmp, i2); ++ store_reg(r1, tmp3); ++ tmp2 = tcg_const_i64(i2); ++ gen_set_cc_add64(tmp, tmp2, tmp3); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0xc: /* MHI R1,I2 [RI] */ ++ tmp = load_reg32(r1); ++ tcg_gen_muli_i32(tmp, tmp, i2); ++ store_reg32(r1, tmp); ++ break; ++ case 0xd: /* MGHI R1,I2 [RI] */ ++ tmp = load_reg(r1); ++ tcg_gen_muli_i64(tmp, tmp, i2); ++ store_reg(r1, tmp); ++ break; ++ case 0xe: /* CHI R1,I2 [RI] */ ++ tmp = load_reg32(r1); ++ cmp_s32c(tmp, i2); ++ break; ++ case 0xf: /* CGHI R1,I2 [RI] */ ++ tmp = load_reg(r1); ++ cmp_s64c(tmp, i2); ++ break; ++ default: ++ LOG_DISAS("illegal a7 operation 0x%x\n", op); ++ gen_illegal_opcode(s); ++ return; ++ } ++ tcg_temp_free(tmp); ++} ++ ++static void disas_b2(DisasContext *s, int op, int r1, int r2) ++{ ++ TCGv_i32 tmp, tmp2, tmp3; ++ LOG_DISAS("disas_b2: op 0x%x r1 %d r2 %d\n", op, r1, r2); ++ switch (op) { ++ case 0x22: /* IPM R1 [RRE] */ ++ tmp = tcg_const_i32(r1); ++ gen_helper_ipm(cc, tmp); ++ break; ++ case 0x4e: /* SAR R1,R2 [RRE] */ ++ tmp = load_reg32(r2); ++ tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, aregs[r1])); ++ break; ++ case 0x4f: /* EAR R1,R2 [RRE] */ ++ tmp = tcg_temp_new_i32(); ++ tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUState, aregs[r2])); ++ store_reg32(r1, tmp); ++ break; ++ case 0x52: /* MSR R1,R2 [RRE] */ ++ tmp = load_reg32(r1); ++ tmp2 = load_reg32(r2); ++ tcg_gen_mul_i32(tmp, tmp, tmp2); ++ store_reg32(r1, tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x55: /* MVST R1,R2 [RRE] */ ++ tmp = load_reg32(0); ++ tmp2 = tcg_const_i32(r1); ++ tmp3 = tcg_const_i32(r2); ++ gen_helper_mvst(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x5d: /* CLST R1,R2 [RRE] */ ++ tmp = load_reg32(0); ++ tmp2 = tcg_const_i32(r1); ++ tmp3 = tcg_const_i32(r2); ++ gen_helper_clst(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x5e: /* SRST R1,R2 [RRE] */ ++ tmp = load_reg32(0); ++ tmp2 = tcg_const_i32(r1); ++ tmp3 = tcg_const_i32(r2); ++ gen_helper_srst(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ default: ++ LOG_DISAS("illegal b2 operation 0x%x\n", op); ++ gen_illegal_opcode(s); ++ return; ++ } ++ tcg_temp_free(tmp); ++} ++ ++static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2) ++{ ++ TCGv_i32 tmp, tmp2, tmp3; ++ LOG_DISAS("disas_b3: op 0x%x m3 0x%x r1 %d r2 %d\n", op, m3, r1, r2); ++#define FP_HELPER(i) \ ++ tmp = tcg_const_i32(r1); \ ++ tmp2 = tcg_const_i32(r2); \ ++ gen_helper_ ## i (tmp, tmp2); \ ++ tcg_temp_free(tmp); \ ++ tcg_temp_free(tmp2); ++ ++#define FP_HELPER_CC(i) \ ++ tmp = tcg_const_i32(r1); \ ++ tmp2 = tcg_const_i32(r2); \ ++ gen_helper_ ## i (cc, tmp, tmp2); \ ++ tcg_temp_free(tmp); \ ++ tcg_temp_free(tmp2); ++ ++ switch (op) { ++ case 0x0: /* LPEBR R1,R2 [RRE] */ ++ FP_HELPER_CC(lpebr); break; ++ case 0x2: /* LTEBR R1,R2 [RRE] */ ++ FP_HELPER_CC(ltebr); break; ++ case 0x3: /* LCEBR R1,R2 [RRE] */ ++ FP_HELPER_CC(lcebr); break; ++ case 0x4: /* LDEBR R1,R2 [RRE] */ ++ FP_HELPER(ldebr); break; ++ case 0x5: /* LXDBR R1,R2 [RRE] */ ++ FP_HELPER(lxdbr); break; ++ case 0x9: /* CEBR R1,R2 [RRE] */ ++ FP_HELPER_CC(cebr); break; ++ case 0xa: /* AEBR R1,R2 [RRE] */ ++ FP_HELPER_CC(aebr); break; ++ case 0xb: /* SEBR R1,R2 [RRE] */ ++ FP_HELPER_CC(sebr); break; ++ case 0xd: /* DEBR R1,R2 [RRE] */ ++ FP_HELPER(debr); break; ++ case 0x10: /* LPDBR R1,R2 [RRE] */ ++ FP_HELPER_CC(lpdbr); break; ++ case 0x12: /* LTDBR R1,R2 [RRE] */ ++ FP_HELPER_CC(ltdbr); break; ++ case 0x13: /* LCDBR R1,R2 [RRE] */ ++ FP_HELPER_CC(lcdbr); break; ++ case 0x15: /* SQBDR R1,R2 [RRE] */ ++ FP_HELPER(sqdbr); break; ++ case 0x17: /* MEEBR R1,R2 [RRE] */ ++ FP_HELPER(meebr); break; ++ case 0x19: /* CDBR R1,R2 [RRE] */ ++ FP_HELPER_CC(cdbr); break; ++ case 0x1a: /* ADBR R1,R2 [RRE] */ ++ FP_HELPER_CC(adbr); break; ++ case 0x1b: /* SDBR R1,R2 [RRE] */ ++ FP_HELPER_CC(sdbr); break; ++ case 0x1c: /* MDBR R1,R2 [RRE] */ ++ FP_HELPER(mdbr); break; ++ case 0x1d: /* DDBR R1,R2 [RRE] */ ++ FP_HELPER(ddbr); break; ++ case 0xe: /* MAEBR R1,R3,R2 [RRF] */ ++ case 0x1e: /* MADBR R1,R3,R2 [RRF] */ ++ case 0x1f: /* MSDBR R1,R3,R2 [RRF] */ ++ /* for RRF insns, m3 is R1, r1 is R3, and r2 is R2 */ ++ tmp = tcg_const_i32(m3); ++ tmp2 = tcg_const_i32(r2); ++ tmp3 = tcg_const_i32(r1); ++ switch (op) { ++ case 0xe: gen_helper_maebr(tmp, tmp3, tmp2); break; ++ case 0x1e: gen_helper_madbr(tmp, tmp3, tmp2); break; ++ case 0x1f: gen_helper_msdbr(tmp, tmp3, tmp2); break; ++ default: tcg_abort(); ++ } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x40: /* LPXBR R1,R2 [RRE] */ ++ FP_HELPER_CC(lpxbr); break; ++ case 0x42: /* LTXBR R1,R2 [RRE] */ ++ FP_HELPER_CC(ltxbr); break; ++ case 0x43: /* LCXBR R1,R2 [RRE] */ ++ FP_HELPER_CC(lcxbr); break; ++ case 0x44: /* LEDBR R1,R2 [RRE] */ ++ FP_HELPER(ledbr); break; ++ case 0x45: /* LDXBR R1,R2 [RRE] */ ++ FP_HELPER(ldxbr); break; ++ case 0x46: /* LEXBR R1,R2 [RRE] */ ++ FP_HELPER(lexbr); break; ++ case 0x49: /* CXBR R1,R2 [RRE] */ ++ FP_HELPER_CC(cxbr); break; ++ case 0x4a: /* AXBR R1,R2 [RRE] */ ++ FP_HELPER_CC(axbr); break; ++ case 0x4b: /* SXBR R1,R2 [RRE] */ ++ FP_HELPER_CC(sxbr); break; ++ case 0x4c: /* MXBR R1,R2 [RRE] */ ++ FP_HELPER(mxbr); break; ++ case 0x4d: /* DXBR R1,R2 [RRE] */ ++ FP_HELPER(dxbr); break; ++ case 0x65: /* LXR R1,R2 [RRE] */ ++ tmp = load_freg(r2); ++ store_freg(r1, tmp); ++ tcg_temp_free(tmp); ++ tmp = load_freg(r2 + 2); ++ store_freg(r1 + 2, tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0x74: /* LZER R1 [RRE] */ ++ tmp = tcg_const_i32(r1); ++ gen_helper_lzer(tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0x75: /* LZDR R1 [RRE] */ ++ tmp = tcg_const_i32(r1); ++ gen_helper_lzdr(tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0x76: /* LZXR R1 [RRE] */ ++ tmp = tcg_const_i32(r1); ++ gen_helper_lzxr(tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0x84: /* SFPC R1 [RRE] */ ++ tmp = load_reg32(r1); ++ tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, fpc)); ++ tcg_temp_free(tmp); ++ break; ++ case 0x8c: /* EFPC R1 [RRE] */ ++ tmp = tcg_temp_new_i32(); ++ tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUState, fpc)); ++ store_reg32(r1, tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0x94: /* CEFBR R1,R2 [RRE] */ ++ case 0x95: /* CDFBR R1,R2 [RRE] */ ++ case 0x96: /* CXFBR R1,R2 [RRE] */ ++ tmp = tcg_const_i32(r1); ++ tmp2 = load_reg32(r2); ++ switch (op) { ++ case 0x94: gen_helper_cefbr(tmp, tmp2); break; ++ case 0x95: gen_helper_cdfbr(tmp, tmp2); break; ++ case 0x96: gen_helper_cxfbr(tmp, tmp2); break; ++ default: tcg_abort(); ++ } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x98: /* CFEBR R1,R2 [RRE] */ ++ case 0x99: /* CFDBR R1,R2 [RRE] */ ++ case 0x9a: /* CFXBR R1,R2 [RRE] */ ++ tmp = tcg_const_i32(r1); ++ tmp2 = tcg_const_i32(r2); ++ tmp3 = tcg_const_i32(m3); ++ switch (op) { ++ case 0x98: gen_helper_cfebr(cc, tmp, tmp2, tmp3); break; ++ case 0x99: gen_helper_cfdbr(cc, tmp, tmp2, tmp3); break; ++ case 0x9a: gen_helper_cfxbr(cc, tmp, tmp2, tmp3); break; ++ default: tcg_abort(); ++ } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0xa4: /* CEGBR R1,R2 [RRE] */ ++ case 0xa5: /* CDGBR R1,R2 [RRE] */ ++ tmp = tcg_const_i32(r1); ++ tmp2 = load_reg(r2); ++ switch (op) { ++ case 0xa4: gen_helper_cegbr(tmp, tmp2); break; ++ case 0xa5: gen_helper_cdgbr(tmp, tmp2); break; ++ default: tcg_abort(); ++ } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 0xa6: /* CXGBR R1,R2 [RRE] */ ++ tmp = tcg_const_i32(r1); ++ tmp2 = load_reg(r2); ++ gen_helper_cxgbr(tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 0xa8: /* CGEBR R1,R2 [RRE] */ ++ tmp = tcg_const_i32(r1); ++ tmp2 = tcg_const_i32(r2); ++ tmp3 = tcg_const_i32(m3); ++ gen_helper_cgebr(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0xa9: /* CGDBR R1,R2 [RRE] */ ++ tmp = tcg_const_i32(r1); ++ tmp2 = tcg_const_i32(r2); ++ tmp3 = tcg_const_i32(m3); ++ gen_helper_cgdbr(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0xaa: /* CGXBR R1,R2 [RRE] */ ++ tmp = tcg_const_i32(r1); ++ tmp2 = tcg_const_i32(r2); ++ tmp3 = tcg_const_i32(m3); ++ gen_helper_cgxbr(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ default: ++ LOG_DISAS("illegal b3 operation 0x%x\n", op); ++ gen_illegal_opcode(s); ++ break; ++ } ++} ++ ++static void disas_b9(DisasContext *s, int op, int r1, int r2) ++{ ++ TCGv tmp, tmp2, tmp3; ++ LOG_DISAS("disas_b9: op 0x%x r1 %d r2 %d\n", op, r1, r2); ++ switch (op) { ++ case 0: /* LPGR R1,R2 [RRE] */ ++ case 0x10: /* LPGFR R1,R2 [RRE] */ ++ if (op == 0) { ++ tmp2 = load_reg(r2); ++ } ++ else { ++ tmp2 = load_reg32(r2); ++ tcg_gen_ext32s_i64(tmp2, tmp2); ++ } ++ tmp = tcg_const_i32(r1); ++ gen_helper_abs_i64(cc, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 1: /* LNGR R1,R2 [RRE] */ ++ tmp2 = load_reg(r2); ++ tmp = tcg_const_i32(r1); ++ gen_helper_nabs_i64(cc, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 2: /* LTGR R1,R2 [RRE] */ ++ tmp = load_reg(r2); ++ if (r1 != r2) store_reg(r1, tmp); ++ set_cc_s64(tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 3: /* LCGR R1,R2 [RRE] */ ++ case 0x13: /* LCGFR R1,R2 [RRE] */ ++ if (op == 0x13) { ++ tmp = load_reg32(r2); ++ tcg_gen_ext32s_i64(tmp, tmp); ++ } ++ else { ++ tmp = load_reg(r2); ++ } ++ tcg_gen_neg_i64(tmp, tmp); ++ store_reg(r1, tmp); ++ gen_helper_set_cc_comp_s64(cc, tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 4: /* LGR R1,R2 [RRE] */ ++ tmp = load_reg(r2); ++ store_reg(r1, tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0x6: /* LGBR R1,R2 [RRE] */ ++ tmp2 = load_reg(r2); ++ tcg_gen_ext8s_i64(tmp2, tmp2); ++ store_reg(r1, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 8: /* AGR R1,R2 [RRE] */ ++ case 0xa: /* ALGR R1,R2 [RRE] */ ++ tmp = load_reg(r1); ++ tmp2 = load_reg(r2); ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_add_i64(tmp3, tmp, tmp2); ++ store_reg(r1, tmp3); ++ switch (op) { ++ case 0x8: gen_set_cc_add64(tmp, tmp2, tmp3); break; ++ case 0xa: gen_helper_set_cc_addu64(cc, tmp, tmp2, tmp3); break; ++ default: tcg_abort(); ++ } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 9: /* SGR R1,R2 [RRE] */ ++ case 0xb: /* SLGR R1,R2 [RRE] */ ++ case 0x1b: /* SLGFR R1,R2 [RRE] */ ++ case 0x19: /* SGFR R1,R2 [RRE] */ ++ tmp = load_reg(r1); ++ switch (op) { ++ case 0x1b: case 0x19: ++ tmp2 = load_reg32(r2); ++ if (op == 0x19) tcg_gen_ext32s_i64(tmp2, tmp2); ++ else tcg_gen_ext32u_i64(tmp2, tmp2); ++ break; ++ default: ++ tmp2 = load_reg(r2); ++ break; ++ } ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_sub_i64(tmp3, tmp, tmp2); ++ store_reg(r1, tmp3); ++ switch (op) { ++ case 9: case 0x19: gen_helper_set_cc_sub64(cc, tmp,tmp2,tmp3); break; ++ case 0xb: case 0x1b: gen_helper_set_cc_subu64(cc, tmp, tmp2, tmp3); break; ++ default: tcg_abort(); ++ } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0xc: /* MSGR R1,R2 [RRE] */ ++ case 0x1c: /* MSGFR R1,R2 [RRE] */ ++ tmp = load_reg(r1); ++ tmp2 = load_reg(r2); ++ if (op == 0x1c) tcg_gen_ext32s_i64(tmp2, tmp2); ++ tcg_gen_mul_i64(tmp, tmp, tmp2); ++ store_reg(r1, tmp); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 0xd: /* DSGR R1,R2 [RRE] */ ++ case 0x1d: /* DSGFR R1,R2 [RRE] */ ++ tmp = load_reg(r1 + 1); ++ if (op == 0xd) { ++ tmp2 = load_reg(r2); ++ } ++ else { ++ tmp2 = load_reg32(r2); ++ tcg_gen_ext32s_i64(tmp2, tmp2); ++ } ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_div_i64(tmp3, tmp, tmp2); ++ store_reg(r1 + 1, tmp3); ++ tcg_gen_rem_i64(tmp3, tmp, tmp2); ++ store_reg(r1, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x14: /* LGFR R1,R2 [RRE] */ ++ tmp = load_reg32(r2); ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_ext32s_i64(tmp2, tmp); ++ store_reg(r1, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x16: /* LLGFR R1,R2 [RRE] */ ++ tmp = load_reg32(r2); ++ tcg_gen_ext32u_i64(tmp, tmp); ++ store_reg(r1, tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0x17: /* LLGTR R1,R2 [RRE] */ ++ tmp = load_reg32(r2); ++ tcg_gen_andi_i64(tmp, tmp, 0x7fffffffUL); ++ tcg_gen_ext32u_i64(tmp, tmp); ++ store_reg(r1, tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0x18: /* AGFR R1,R2 [RRE] */ ++ case 0x1a: /* ALGFR R1,R2 [RRE] */ ++ tmp2 = load_reg32(r2); ++ switch (op) { ++ case 0x18: tcg_gen_ext32s_i64(tmp2, tmp2); break; ++ case 0x1a: tcg_gen_ext32u_i64(tmp2, tmp2); break; ++ default: tcg_abort(); ++ } ++ tmp = load_reg(r1); ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_add_i64(tmp3, tmp, tmp2); ++ store_reg(r1, tmp3); ++ switch (op) { ++ case 0x18: gen_set_cc_add64(tmp, tmp2, tmp3); break; ++ case 0x1a: gen_helper_set_cc_addu64(cc, tmp, tmp2, tmp3); break; ++ default: tcg_abort(); ++ } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x20: /* CGR R1,R2 [RRE] */ ++ case 0x30: /* CGFR R1,R2 [RRE] */ ++ tmp2 = load_reg(r2); ++ if (op == 0x30) tcg_gen_ext32s_i64(tmp2, tmp2); ++ tmp = load_reg(r1); ++ cmp_s64(tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x21: /* CLGR R1,R2 [RRE] */ ++ case 0x31: /* CLGFR R1,R2 [RRE] */ ++ tmp2 = load_reg(r2); ++ if (op == 0x31) tcg_gen_ext32u_i64(tmp2, tmp2); ++ tmp = load_reg(r1); ++ cmp_u64(tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x26: /* LBR R1,R2 [RRE] */ ++ tmp2 = load_reg32(r2); ++ tcg_gen_ext8s_i32(tmp2, tmp2); ++ store_reg32(r1, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x27: /* LHR R1,R2 [RRE] */ ++ tmp2 = load_reg32(r2); ++ tcg_gen_ext16s_i32(tmp2, tmp2); ++ store_reg32(r1, tmp2); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x80: /* NGR R1,R2 [RRE] */ ++ case 0x81: /* OGR R1,R2 [RRE] */ ++ case 0x82: /* XGR R1,R2 [RRE] */ ++ tmp = load_reg(r1); ++ tmp2 = load_reg(r2); ++ switch (op) { ++ case 0x80: tcg_gen_and_i64(tmp, tmp, tmp2); break; ++ case 0x81: tcg_gen_or_i64(tmp, tmp, tmp2); break; ++ case 0x82: tcg_gen_xor_i64(tmp, tmp, tmp2); break; ++ default: tcg_abort(); ++ } ++ store_reg(r1, tmp); ++ set_cc_nz_u64(tmp); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x83: /* FLOGR R1,R2 [RRE] */ ++ tmp2 = load_reg(r2); ++ tmp = tcg_const_i32(r1); ++ gen_helper_flogr(cc, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x84: /* LLGCR R1,R2 [RRE] */ ++ tmp = load_reg(r2); ++ tcg_gen_andi_i64(tmp, tmp, 0xff); ++ store_reg(r1, tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0x85: /* LLGHR R1,R2 [RRE] */ ++ tmp = load_reg(r2); ++ tcg_gen_andi_i64(tmp, tmp, 0xffff); ++ store_reg(r1, tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0x87: /* DLGR R1,R2 [RRE] */ ++ tmp = tcg_const_i32(r1); ++ tmp2 = load_reg(r2); ++ gen_helper_dlg(tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x88: /* ALCGR R1,R2 [RRE] */ ++ tmp = load_reg(r1); ++ tmp2 = load_reg(r2); ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_shri_i64(tmp3, cc, 1); ++ tcg_gen_andi_i64(tmp3, tmp3, 1); ++ tcg_gen_add_i64(tmp3, tmp2, tmp3); ++ tcg_gen_add_i64(tmp3, tmp, tmp3); ++ store_reg(r1, tmp3); ++ gen_helper_set_cc_addc_u64(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x89: /* SLBGR R1,R2 [RRE] */ ++ tmp = load_reg(r1); ++ tmp2 = load_reg(r2); ++ tmp3 = tcg_const_i32(r1); ++ gen_helper_slbg(cc, cc, tmp3, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x94: /* LLCR R1,R2 [RRE] */ ++ tmp = load_reg32(r2); ++ tcg_gen_andi_i32(tmp, tmp, 0xff); ++ store_reg32(r1, tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0x95: /* LLHR R1,R2 [RRE] */ ++ tmp = load_reg32(r2); ++ tcg_gen_andi_i32(tmp, tmp, 0xffff); ++ store_reg32(r1, tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0x98: /* ALCR R1,R2 [RRE] */ ++ tmp = tcg_const_i32(r1); ++ tmp2 = load_reg32(r2); ++ gen_helper_addc_u32(cc, cc, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x99: /* SLBR R1,R2 [RRE] */ ++ tmp = load_reg32(r1); ++ tmp2 = load_reg32(r2); ++ tmp3 = tcg_const_i32(r1); ++ gen_helper_slb(cc, cc, tmp3, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ default: ++ LOG_DISAS("illegal b9 operation 0x%x\n", op); ++ gen_illegal_opcode(s); ++ break; ++ } ++} ++ ++static void disas_c0(DisasContext *s, int op, int r1, int i2) ++{ ++ TCGv tmp, tmp2, tmp3; ++ LOG_DISAS("disas_c0: op 0x%x r1 %d i2 %d\n", op, r1, i2); ++ uint64_t target = s->pc + i2 * 2; ++ /* FIXME: huh? */ target &= 0xffffffff; ++ switch (op) { ++ case 0: /* larl r1, i2 */ ++ tmp = tcg_const_i64(target); ++ store_reg(r1, tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0x1: /* LGFI R1,I2 [RIL] */ ++ tmp = tcg_const_i64((int64_t)i2); ++ store_reg(r1, tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0x4: /* BRCL M1,I2 [RIL] */ ++ tmp = tcg_const_i32(r1); /* aka m1 */ ++ tmp2 = tcg_const_i64(s->pc); ++ tmp3 = tcg_const_i64(i2 * 2); ++ gen_helper_brcl(cc, tmp, tmp2, tmp3); ++ s->is_jmp = DISAS_JUMP; ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x5: /* brasl r1, i2 */ ++ tmp = tcg_const_i64(s->pc + 6); ++ store_reg(r1, tmp); ++ tmp = tcg_const_i64(target); ++ tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, psw.addr)); ++ s->is_jmp = DISAS_JUMP; ++ tcg_temp_free(tmp); ++ break; ++ case 0x7: /* XILF R1,I2 [RIL] */ ++ case 0xb: /* NILF R1,I2 [RIL] */ ++ case 0xd: /* OILF R1,I2 [RIL] */ ++ tmp = load_reg32(r1); ++ switch (op) { ++ case 0x7: tcg_gen_xori_i32(tmp, tmp, (uint32_t)i2); break; ++ case 0xb: tcg_gen_andi_i32(tmp, tmp, (uint32_t)i2); break; ++ case 0xd: tcg_gen_ori_i32(tmp, tmp, (uint32_t)i2); break; ++ default: tcg_abort(); ++ } ++ store_reg32(r1, tmp); ++ tcg_gen_trunc_i64_i32(tmp, tmp); ++ set_cc_nz_u32(tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0x9: /* IILF R1,I2 [RIL] */ ++ tmp = tcg_const_i32((uint32_t)i2); ++ store_reg32(r1, tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0xa: /* NIHF R1,I2 [RIL] */ ++ tmp = load_reg(r1); ++ switch (op) { ++ case 0xa: tcg_gen_andi_i64(tmp, tmp, (((uint64_t)((uint32_t)i2)) << 32) | 0xffffffffULL); break; ++ default: tcg_abort(); ++ } ++ store_reg(r1, tmp); ++ tcg_gen_shr_i64(tmp, tmp, 32); ++ tcg_gen_trunc_i64_i32(tmp, tmp); ++ set_cc_nz_u32(tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0xe: /* LLIHF R1,I2 [RIL] */ ++ tmp = tcg_const_i64(((uint64_t)(uint32_t)i2) << 32); ++ store_reg(r1, tmp); ++ tcg_temp_free(tmp); ++ break; ++ case 0xf: /* LLILF R1,I2 [RIL] */ ++ tmp = tcg_const_i64((uint32_t)i2); ++ store_reg(r1, tmp); ++ tcg_temp_free(tmp); ++ break; ++ default: ++ LOG_DISAS("illegal c0 operation 0x%x\n", op); ++ gen_illegal_opcode(s); ++ break; ++ } ++} ++ ++static void disas_c2(DisasContext *s, int op, int r1, int i2) ++{ ++ TCGv tmp, tmp2, tmp3; ++ switch (op) { ++ case 0x4: /* SLGFI R1,I2 [RIL] */ ++ case 0xa: /* ALGFI R1,I2 [RIL] */ ++ tmp = load_reg(r1); ++ tmp2 = tcg_const_i64((uint64_t)(uint32_t)i2); ++ tmp3 = tcg_temp_new_i64(); ++ switch (op) { ++ case 0x4: ++ tcg_gen_sub_i64(tmp3, tmp, tmp2); ++ gen_helper_set_cc_subu64(cc, tmp, tmp2, tmp3); ++ break; ++ case 0xa: ++ tcg_gen_add_i64(tmp3, tmp, tmp2); ++ gen_helper_set_cc_addu64(cc, tmp, tmp2, tmp3); ++ break; ++ default: tcg_abort(); ++ } ++ store_reg(r1, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0x5: /* SLFI R1,I2 [RIL] */ ++ case 0xb: /* ALFI R1,I2 [RIL] */ ++ tmp = load_reg32(r1); ++ tmp2 = tcg_const_i32(i2); ++ tmp3 = tcg_temp_new_i32(); ++ switch (op) { ++ case 0x5: ++ tcg_gen_sub_i32(tmp3, tmp, tmp2); ++ gen_helper_set_cc_subu32(cc, tmp, tmp2, tmp3); ++ break; ++ case 0xb: ++ tcg_gen_add_i32(tmp3, tmp, tmp2); ++ gen_helper_set_cc_addu32(cc, tmp, tmp2, tmp3); ++ break; ++ default: tcg_abort(); ++ } ++ store_reg32(r1, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ break; ++ case 0xc: /* CGFI R1,I2 [RIL] */ ++ tmp = load_reg(r1); ++ cmp_s64c(tmp, (int64_t)i2); ++ tcg_temp_free(tmp); ++ break; ++ case 0xe: /* CLGFI R1,I2 [RIL] */ ++ tmp = load_reg(r1); ++ cmp_u64c(tmp, (uint64_t)(uint32_t)i2); ++ tcg_temp_free(tmp); ++ break; ++ case 0xd: /* CFI R1,I2 [RIL] */ ++ case 0xf: /* CLFI R1,I2 [RIL] */ ++ tmp = load_reg32(r1); ++ switch (op) { ++ case 0xd: cmp_s32c(tmp, i2); break; ++ case 0xf: cmp_u32c(tmp, i2); break; ++ default: tcg_abort(); ++ } ++ tcg_temp_free(tmp); ++ break; ++ default: ++ LOG_DISAS("illegal c2 operation 0x%x\n", op); ++ gen_illegal_opcode(s); ++ break; ++ } ++} ++ ++static inline uint64_t ld_code2(uint64_t pc) ++{ ++ return (uint64_t)lduw_code(pc); ++} ++ ++static inline uint64_t ld_code4(uint64_t pc) ++{ ++ return (uint64_t)ldl_code(pc); ++} ++ ++static inline uint64_t ld_code6(uint64_t pc) ++{ ++ uint64_t opc; ++ opc = (uint64_t)lduw_code(pc) << 32; ++ opc |= (uint64_t)(unsigned int)ldl_code(pc+2); ++ return opc; ++} ++ ++static void disas_s390_insn(CPUState *env, DisasContext *s) ++{ ++ TCGv tmp, tmp2, tmp3; ++ unsigned char opc; ++ uint64_t insn; ++ int op, r1, r2, r3, d1, d2, x2, b1, b2, i, i2, r1b; ++ TCGv vl, vd1, vd2, vb; ++ ++ opc = ldub_code(s->pc); ++ LOG_DISAS("opc 0x%x\n", opc); ++ ++#define FETCH_DECODE_RR \ ++ insn = ld_code2(s->pc); \ ++ DEBUGINSN \ ++ r1 = (insn >> 4) & 0xf; \ ++ r2 = insn & 0xf; ++ ++#define FETCH_DECODE_RX \ ++ insn = ld_code4(s->pc); \ ++ DEBUGINSN \ ++ r1 = (insn >> 20) & 0xf; \ ++ x2 = (insn >> 16) & 0xf; \ ++ b2 = (insn >> 12) & 0xf; \ ++ d2 = insn & 0xfff; \ ++ tmp = get_address(x2, b2, d2); ++ ++#define FREE_RX \ ++ tcg_temp_free(tmp); ++ ++#define FETCH_DECODE_RS \ ++ insn = ld_code4(s->pc); \ ++ DEBUGINSN \ ++ r1 = (insn >> 20) & 0xf; \ ++ r3 = (insn >> 16) & 0xf; /* aka m3 */ \ ++ b2 = (insn >> 12) & 0xf; \ ++ d2 = insn & 0xfff; ++ ++#define FETCH_DECODE_SI \ ++ insn = ld_code4(s->pc); \ ++ i2 = (insn >> 16) & 0xff; \ ++ b1 = (insn >> 12) & 0xf; \ ++ d1 = insn & 0xfff; \ ++ tmp = get_address(0, b1, d1); ++ ++#define FREE_SI \ ++ tcg_temp_free(tmp); ++ ++ switch (opc) { ++ case 0x7: /* BCR M1,R2 [RR] */ ++ FETCH_DECODE_RR ++ if (r2) { ++ gen_bcr(r1, r2, s->pc); ++ s->is_jmp = DISAS_JUMP; ++ } ++ else { ++ /* FIXME: "serialization and checkpoint-synchronization function"? */ ++ } ++ s->pc += 2; ++ break; ++ case 0xa: /* SVC I [RR] */ ++ insn = ld_code2(s->pc); ++ DEBUGINSN ++ i = insn & 0xff; ++ tmp = tcg_const_i64(s->pc); ++ tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, psw.addr)); ++ tcg_temp_free(tmp); ++ s->is_jmp = DISAS_SVC; ++ s->pc += 2; ++ break; ++ case 0xd: /* BASR R1,R2 [RR] */ ++ FETCH_DECODE_RR ++ tmp = tcg_const_i64(s->pc + 2); ++ store_reg(r1, tmp); ++ if (r2) { ++ tmp2 = load_reg(r2); ++ tcg_gen_st_i64(tmp2, cpu_env, offsetof(CPUState, psw.addr)); ++ tcg_temp_free(tmp2); ++ s->is_jmp = DISAS_JUMP; ++ } ++ tcg_temp_free(tmp); ++ s->pc += 2; ++ break; ++ case 0x10: /* LPR R1,R2 [RR] */ ++ FETCH_DECODE_RR ++ tmp2 = load_reg32(r2); ++ tmp = tcg_const_i32(r1); ++ gen_helper_abs_i32(cc, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ s->pc += 2; ++ break; ++ case 0x11: /* LNR R1,R2 [RR] */ ++ FETCH_DECODE_RR ++ tmp2 = load_reg32(r2); ++ tmp = tcg_const_i32(r1); ++ gen_helper_nabs_i32(cc, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ s->pc += 2; ++ break; ++ case 0x12: /* LTR R1,R2 [RR] */ ++ FETCH_DECODE_RR ++ tmp = load_reg32(r2); ++ if (r1 != r2) store_reg32(r1, tmp); ++ set_cc_s32(tmp); ++ tcg_temp_free(tmp); ++ s->pc += 2; ++ break; ++ case 0x13: /* LCR R1,R2 [RR] */ ++ FETCH_DECODE_RR ++ tmp = load_reg32(r2); ++ tcg_gen_neg_i32(tmp, tmp); ++ store_reg32(r1, tmp); ++ gen_helper_set_cc_comp_s32(cc, tmp); ++ tcg_temp_free(tmp); ++ s->pc += 2; ++ break; ++ case 0x14: /* NR R1,R2 [RR] */ ++ case 0x16: /* OR R1,R2 [RR] */ ++ case 0x17: /* XR R1,R2 [RR] */ ++ FETCH_DECODE_RR ++ tmp2 = load_reg32(r2); ++ tmp = load_reg32(r1); ++ switch (opc) { ++ case 0x14: tcg_gen_and_i32(tmp, tmp, tmp2); break; ++ case 0x16: tcg_gen_or_i32(tmp, tmp, tmp2); break; ++ case 0x17: tcg_gen_xor_i32(tmp, tmp, tmp2); break; ++ default: tcg_abort(); ++ } ++ store_reg32(r1, tmp); ++ set_cc_nz_u32(tmp); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ s->pc += 2; ++ break; ++ case 0x18: /* LR R1,R2 [RR] */ ++ FETCH_DECODE_RR ++ tmp = load_reg32(r2); ++ store_reg32(r1, tmp); ++ tcg_temp_free(tmp); ++ s->pc += 2; ++ break; ++ case 0x15: /* CLR R1,R2 [RR] */ ++ case 0x19: /* CR R1,R2 [RR] */ ++ FETCH_DECODE_RR ++ tmp = load_reg32(r1); ++ tmp2 = load_reg32(r2); ++ switch (opc) { ++ case 0x15: cmp_u32(tmp, tmp2); break; ++ case 0x19: cmp_s32(tmp, tmp2); break; ++ default: tcg_abort(); ++ } ++ s->pc += 2; ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x1a: /* AR R1,R2 [RR] */ ++ case 0x1e: /* ALR R1,R2 [RR] */ ++ FETCH_DECODE_RR ++ tmp = load_reg32(r1); ++ tmp2 = load_reg32(r2); ++ tmp3 = tcg_temp_new_i32(); ++ tcg_gen_add_i32(tmp3, tmp, tmp2); ++ store_reg32(r1, tmp3); ++ switch (opc) { ++ case 0x1a: gen_helper_set_cc_add32(cc, tmp, tmp2, tmp3); break; ++ case 0x1e: gen_helper_set_cc_addu32(cc, tmp, tmp2, tmp3); break; ++ default: tcg_abort(); ++ } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ s->pc += 2; ++ break; ++ case 0x1b: /* SR R1,R2 [RR] */ ++ case 0x1f: /* SLR R1,R2 [RR] */ ++ FETCH_DECODE_RR ++ tmp = load_reg32(r1); ++ tmp2 = load_reg32(r2); ++ tmp3 = tcg_temp_new_i32(); ++ tcg_gen_sub_i32(tmp3, tmp, tmp2); ++ store_reg32(r1, tmp3); ++ switch (opc) { ++ case 0x1b: gen_helper_set_cc_sub32(cc, tmp, tmp2, tmp3); break; ++ case 0x1f: gen_helper_set_cc_subu32(cc, tmp, tmp2, tmp3); break; ++ default: tcg_abort(); ++ } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ s->pc += 2; ++ break; ++ case 0x28: /* LDR R1,R2 [RR] */ ++ FETCH_DECODE_RR ++ tmp = load_freg(r2); ++ store_freg(r1, tmp); ++ tcg_temp_free(tmp); ++ s->pc += 2; ++ break; ++ case 0x38: /* LER R1,R2 [RR] */ ++ FETCH_DECODE_RR ++ tmp = load_freg32(r2); ++ store_freg32(r1, tmp); ++ tcg_temp_free(tmp); ++ s->pc += 2; ++ break; ++ case 0x40: /* STH R1,D2(X2,B2) [RX] */ ++ FETCH_DECODE_RX ++ tmp2 = load_reg32(r1); ++ tcg_gen_qemu_st16(tmp2, tmp, 1); ++ FREE_RX ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x41: /* la */ ++ FETCH_DECODE_RX ++ store_reg(r1, tmp); /* FIXME: 31/24-bit addressing */ ++ FREE_RX ++ s->pc += 4; ++ break; ++ case 0x42: /* STC R1,D2(X2,B2) [RX] */ ++ FETCH_DECODE_RX ++ tmp2 = load_reg32(r1); ++ tcg_gen_qemu_st8(tmp2, tmp, 1); ++ FREE_RX ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x43: /* IC R1,D2(X2,B2) [RX] */ ++ FETCH_DECODE_RX ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld8u(tmp2, tmp, 1); ++ store_reg8(r1, tmp2); ++ FREE_RX ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x44: /* EX R1,D2(X2,B2) [RX] */ ++ FETCH_DECODE_RX ++ tmp2 = load_reg(r1); ++ tmp3 = tcg_const_i64(s->pc + 4); ++ gen_helper_ex(cc, cc, tmp2, tmp, tmp3); ++ FREE_RX ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ s->pc += 4; ++ break; ++ case 0x47: /* BC M1,D2(X2,B2) [RX] */ ++ FETCH_DECODE_RX ++ /* FIXME: optimize m1 == 0xf (unconditional) case */ ++ tmp2 = tcg_const_i32(r1); /* aka m1 */ ++ tmp3 = tcg_const_i64(s->pc); ++ gen_helper_bc(cc, tmp2, tmp, tmp3); ++ FREE_RX ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ s->is_jmp = DISAS_JUMP; ++ s->pc += 4; ++ break; ++ case 0x48: /* LH R1,D2(X2,B2) [RX] */ ++ FETCH_DECODE_RX ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld16s(tmp2, tmp, 1); ++ store_reg32(r1, tmp2); ++ FREE_RX ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x49: /* CH R1,D2(X2,B2) [RX] */ ++ FETCH_DECODE_RX ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld16s(tmp2, tmp, 1); ++ FREE_RX ++ tmp = load_reg32(r1); ++ cmp_s32(tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x4a: /* AH R1,D2(X2,B2) [RX] */ ++ case 0x4b: /* SH R1,D2(X2,B2) [RX] */ ++ case 0x4c: /* MH R1,D2(X2,B2) [RX] */ ++ FETCH_DECODE_RX ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld16s(tmp2, tmp, 1); ++ FREE_RX ++ tmp = load_reg32(r1); ++ tmp3 = tcg_temp_new_i32(); ++ switch (opc) { ++ case 0x4a: ++ tcg_gen_add_i32(tmp3, tmp, tmp2); ++ gen_helper_set_cc_add32(cc, tmp, tmp2, tmp3); ++ break; ++ case 0x4b: ++ tcg_gen_sub_i32(tmp3, tmp, tmp2); ++ gen_helper_set_cc_sub32(cc, tmp, tmp2, tmp3); ++ break; ++ case 0x4c: ++ tcg_gen_mul_i32(tmp3, tmp, tmp2); ++ break; ++ default: tcg_abort(); ++ } ++ store_reg32(r1, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ s->pc += 4; ++ break; ++ case 0x50: /* st r1, d2(x2, b2) */ ++ FETCH_DECODE_RX ++ tmp2 = load_reg32(r1); ++ tcg_gen_qemu_st32(tmp2, tmp, 1); ++ s->pc += 4; ++ FREE_RX ++ tcg_temp_free(tmp2); ++ break; ++ case 0x55: /* CL R1,D2(X2,B2) [RX] */ ++ FETCH_DECODE_RX ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp2, tmp, 1); ++ FREE_RX ++ tmp = load_reg32(r1); ++ cmp_u32(tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x54: /* N R1,D2(X2,B2) [RX] */ ++ case 0x56: /* O R1,D2(X2,B2) [RX] */ ++ case 0x57: /* X R1,D2(X2,B2) [RX] */ ++ FETCH_DECODE_RX ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp2, tmp, 1); ++ FREE_RX ++ tmp = load_reg32(r1); ++ switch (opc) { ++ case 0x54: tcg_gen_and_i32(tmp, tmp, tmp2); break; ++ case 0x56: tcg_gen_or_i32(tmp, tmp, tmp2); break; ++ case 0x57: tcg_gen_xor_i32(tmp, tmp, tmp2); break; ++ default: tcg_abort(); ++ } ++ store_reg32(r1, tmp); ++ set_cc_nz_u32(tmp); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x58: /* l r1, d2(x2, b2) */ ++ FETCH_DECODE_RX ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp2, tmp, 1); ++ store_reg32(r1, tmp2); ++ FREE_RX ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x59: /* C R1,D2(X2,B2) [RX] */ ++ FETCH_DECODE_RX ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32s(tmp2, tmp, 1); ++ FREE_RX ++ tmp = load_reg32(r1); ++ cmp_s32(tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x5a: /* A R1,D2(X2,B2) [RX] */ ++ case 0x5b: /* S R1,D2(X2,B2) [RX] */ ++ case 0x5e: /* AL R1,D2(X2,B2) [RX] */ ++ case 0x5f: /* SL R1,D2(X2,B2) [RX] */ ++ FETCH_DECODE_RX ++ tmp2 = load_reg32(r1); ++ tcg_gen_qemu_ld32s(tmp, tmp, 1); ++ tmp3 = tcg_temp_new_i32(); ++ switch (opc) { ++ case 0x5a: case 0x5e: tcg_gen_add_i32(tmp3, tmp2, tmp); break; ++ case 0x5b: case 0x5f: tcg_gen_sub_i32(tmp3, tmp2, tmp); break; ++ default: tcg_abort(); ++ } ++ store_reg32(r1, tmp3); ++ switch (opc) { ++ case 0x5a: gen_helper_set_cc_add32(cc, tmp2, tmp, tmp3); break; ++ case 0x5e: gen_helper_set_cc_addu32(cc, tmp2, tmp, tmp3); break; ++ case 0x5b: gen_helper_set_cc_sub32(cc, tmp2, tmp, tmp3); break; ++ case 0x5f: gen_helper_set_cc_subu32(cc, tmp2, tmp, tmp3); break; ++ default: tcg_abort(); ++ } ++ FREE_RX ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ s->pc += 4; ++ break; ++ case 0x60: /* STD R1,D2(X2,B2) [RX] */ ++ FETCH_DECODE_RX ++ tmp2 = load_freg(r1); ++ tcg_gen_qemu_st64(tmp2, tmp, 1); ++ FREE_RX ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x68: /* LD R1,D2(X2,B2) [RX] */ ++ FETCH_DECODE_RX ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld64(tmp2, tmp, 1); ++ store_freg(r1, tmp2); ++ FREE_RX ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x70: /* STE R1,D2(X2,B2) [RX] */ ++ FETCH_DECODE_RX ++ tmp2 = load_freg32(r1); ++ tcg_gen_qemu_st32(tmp2, tmp, 1); ++ FREE_RX ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x71: /* MS R1,D2(X2,B2) [RX] */ ++ FETCH_DECODE_RX ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32s(tmp2, tmp, 1); ++ FREE_RX ++ tmp = load_reg(r1); ++ tcg_gen_mul_i32(tmp, tmp, tmp2); ++ store_reg(r1, tmp); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x78: /* LE R1,D2(X2,B2) [RX] */ ++ FETCH_DECODE_RX ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp2, tmp, 1); ++ store_freg32(r1, tmp2); ++ FREE_RX ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x88: /* SRL R1,D2(B2) [RS] */ ++ case 0x89: /* SLL R1,D2(B2) [RS] */ ++ case 0x8a: /* SRA R1,D2(B2) [RS] */ ++ FETCH_DECODE_RS ++ tmp = get_address(0, b2, d2); ++ tcg_gen_andi_i64(tmp, tmp, 0x3f); ++ tmp2 = load_reg32(r1); ++ switch (opc) { ++ case 0x88: tcg_gen_shr_i32(tmp2, tmp2, tmp); break; ++ case 0x89: tcg_gen_shl_i32(tmp2, tmp2, tmp); break; ++ case 0x8a: tcg_gen_sar_i32(tmp2, tmp2, tmp); break; ++ default: tcg_abort(); ++ } ++ store_reg32(r1, tmp2); ++ if (opc == 0x8a) set_cc_s32(tmp2); ++ s->pc += 4; ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ case 0x91: /* TM D1(B1),I2 [SI] */ ++ FETCH_DECODE_SI ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld8u(tmp2, tmp, 1); ++ FREE_SI ++ tmp = tcg_const_i32(i2); ++ gen_helper_tm(cc, tmp2, tmp); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x92: /* MVI D1(B1),I2 [SI] */ ++ FETCH_DECODE_SI ++ tmp2 = tcg_const_i32(i2); ++ tcg_gen_qemu_st8(tmp2, tmp, 1); ++ FREE_SI ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x94: /* NI D1(B1),I2 [SI] */ ++ case 0x96: /* OI D1(B1),I2 [SI] */ ++ case 0x97: /* XI D1(B1),I2 [SI] */ ++ FETCH_DECODE_SI ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld8u(tmp2, tmp, 1); ++ switch (opc) { ++ case 0x94: tcg_gen_andi_i32(tmp2, tmp2, i2); break; ++ case 0x96: tcg_gen_ori_i32(tmp2, tmp2, i2); break; ++ case 0x97: tcg_gen_xori_i32(tmp2, tmp2, i2); break; ++ default: tcg_abort(); ++ } ++ tcg_gen_qemu_st8(tmp2, tmp, 1); ++ set_cc_nz_u32(tmp2); ++ FREE_SI ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x95: /* CLI D1(B1),I2 [SI] */ ++ FETCH_DECODE_SI ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld8u(tmp2, tmp, 1); ++ cmp_u32c(tmp2, i2); ++ FREE_SI ++ tcg_temp_free(tmp2); ++ s->pc += 4; ++ break; ++ case 0x9b: /* STAM R1,R3,D2(B2) [RS] */ ++ FETCH_DECODE_RS ++ tmp = tcg_const_i32(r1); ++ tmp2 = get_address(0, b2, d2); ++ tmp3 = tcg_const_i32(r3); ++ gen_helper_stam(tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ s->pc += 4; ++ break; ++ case 0xa5: ++ insn = ld_code4(s->pc); ++ r1 = (insn >> 20) & 0xf; ++ op = (insn >> 16) & 0xf; ++ i2 = insn & 0xffff; ++ disas_a5(s, op, r1, i2); ++ s->pc += 4; ++ break; ++ case 0xa7: ++ insn = ld_code4(s->pc); ++ r1 = (insn >> 20) & 0xf; ++ op = (insn >> 16) & 0xf; ++ i2 = (short)insn; ++ disas_a7(s, op, r1, i2); ++ s->pc += 4; ++ break; ++ case 0xa8: /* MVCLE R1,R3,D2(B2) [RS] */ ++ FETCH_DECODE_RS ++ tmp = tcg_const_i32(r1); ++ tmp3 = tcg_const_i32(r3); ++ tmp2 = get_address(0, b2, d2); ++ gen_helper_mvcle(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ s->pc += 4; ++ break; ++ case 0xa9: /* CLCLE R1,R3,D2(B2) [RS] */ ++ FETCH_DECODE_RS ++ tmp = tcg_const_i32(r1); ++ tmp3 = tcg_const_i32(r3); ++ tmp2 = get_address(0, b2, d2); ++ gen_helper_clcle(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ s->pc += 4; ++ break; ++ case 0xb2: ++ insn = ld_code4(s->pc); ++ op = (insn >> 16) & 0xff; ++ switch (op) { ++ case 0x9c: /* STFPC D2(B2) [S] */ ++ d2 = insn & 0xfff; ++ b2 = (insn >> 12) & 0xf; ++ tmp = tcg_temp_new_i32(); ++ tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUState, fpc)); ++ tmp2 = get_address(0, b2, d2); ++ tcg_gen_qemu_st32(tmp, tmp2, 1); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ break; ++ default: ++ r1 = (insn >> 4) & 0xf; ++ r2 = insn & 0xf; ++ disas_b2(s, op, r1, r2); ++ break; ++ } ++ s->pc += 4; ++ break; ++ case 0xb3: ++ insn = ld_code4(s->pc); ++ op = (insn >> 16) & 0xff; ++ r3 = (insn >> 12) & 0xf; /* aka m3 */ ++ r1 = (insn >> 4) & 0xf; ++ r2 = insn & 0xf; ++ disas_b3(s, op, r3, r1, r2); ++ s->pc += 4; ++ break; ++ case 0xb9: ++ insn = ld_code4(s->pc); ++ r1 = (insn >> 4) & 0xf; ++ r2 = insn & 0xf; ++ op = (insn >> 16) & 0xff; ++ disas_b9(s, op, r1, r2); ++ s->pc += 4; ++ break; ++ case 0xba: /* CS R1,R3,D2(B2) [RS] */ ++ FETCH_DECODE_RS ++ tmp = tcg_const_i32(r1); ++ tmp2 = get_address(0, b2, d2); ++ tmp3 = tcg_const_i32(r3); ++ gen_helper_cs(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ s->pc += 4; ++ break; ++ case 0xbd: /* CLM R1,M3,D2(B2) [RS] */ ++ FETCH_DECODE_RS ++ tmp3 = get_address(0, b2, d2); ++ tmp2 = tcg_const_i32(r3); /* aka m3 */ ++ tmp = load_reg32(r1); ++ gen_helper_clm(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ s->pc += 4; ++ break; ++ case 0xbe: /* STCM R1,M3,D2(B2) [RS] */ ++ FETCH_DECODE_RS ++ tmp3 = get_address(0, b2, d2); ++ tmp2 = tcg_const_i32(r3); /* aka m3 */ ++ tmp = load_reg32(r1); ++ gen_helper_stcm(tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ s->pc += 4; ++ break; ++ case 0xbf: /* ICM R1,M3,D2(B2) [RS] */ ++ FETCH_DECODE_RS ++ if (r3 == 15) { /* effectively a 32-bit load */ ++ tmp = get_address(0, b2, d2); ++ tmp2 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp2, tmp, 1); ++ store_reg32(r1, tmp2); ++ tcg_temp_free(tmp); ++ tmp = tcg_const_i32(r3); ++ gen_helper_set_cc_icm(cc, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ } ++ else if (r3) { ++ uint32_t mask = 0x00ffffffUL; ++ uint32_t shift = 24; ++ int m3 = r3; ++ tmp3 = load_reg32(r1); ++ tmp = get_address(0, b2, d2); ++ tmp2 = tcg_temp_new_i64(); ++ while (m3) { ++ if (m3 & 8) { ++ tcg_gen_qemu_ld8u(tmp2, tmp, 1); ++ if (shift) tcg_gen_shli_i32(tmp2, tmp2, shift); ++ tcg_gen_andi_i32(tmp3, tmp3, mask); ++ tcg_gen_or_i32(tmp3, tmp3, tmp2); ++ tcg_gen_addi_i64(tmp, tmp, 1); ++ } ++ m3 = (m3 << 1) & 0xf; ++ mask = (mask >> 8) | 0xff000000UL; ++ shift -= 8; ++ } ++ store_reg32(r1, tmp3); ++ tcg_temp_free(tmp); ++ tmp = tcg_const_i32(r3); ++ gen_helper_set_cc_icm(cc, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ } ++ else { ++ tmp = tcg_const_i32(0); ++ gen_helper_set_cc_icm(cc, tmp, tmp); /* i.e. env->cc = 0 */ ++ tcg_temp_free(tmp); ++ } ++ s->pc += 4; ++ break; ++ case 0xc0: ++ case 0xc2: ++ insn = ld_code6(s->pc); ++ r1 = (insn >> 36) & 0xf; ++ op = (insn >> 32) & 0xf; ++ i2 = (int)insn; ++ switch (opc) { ++ case 0xc0: disas_c0(s, op, r1, i2); break; ++ case 0xc2: disas_c2(s, op, r1, i2); break; ++ default: tcg_abort(); ++ } ++ s->pc += 6; ++ break; ++ case 0xd2: /* mvc d1(l, b1), d2(b2) */ ++ case 0xd4: /* NC D1(L,B1),D2(B2) [SS] */ ++ case 0xd5: /* CLC D1(L,B1),D2(B2) [SS] */ ++ case 0xd6: /* OC D1(L,B1),D2(B2) [SS] */ ++ case 0xd7: /* xc d1(l, b1), d2(b2) */ ++ insn = ld_code6(s->pc); ++ vl = tcg_const_i32((insn >> 32) & 0xff); ++ b1 = (insn >> 28) & 0xf; ++ vd1 = tcg_const_i32((insn >> 16) & 0xfff); ++ b2 = (insn >> 12) & 0xf; ++ vd2 = tcg_const_i32(insn & 0xfff); ++ vb = tcg_const_i32((b1 << 4) | b2); ++ switch (opc) { ++ case 0xd2: gen_helper_mvc(vl, vb, vd1, vd2); break; ++ case 0xd4: gen_helper_nc(cc, vl, vb, vd1, vd2); break; ++ case 0xd5: gen_helper_clc(cc, vl, vb, vd1, vd2); break; ++ case 0xd6: gen_helper_oc(cc, vl, vb, vd1, vd2); break; ++ case 0xd7: gen_helper_xc(cc, vl, vb, vd1, vd2); break; ++ default: tcg_abort(); break; ++ } ++ s->pc += 6; ++ break; ++ case 0xe3: ++ insn = ld_code6(s->pc); ++ DEBUGINSN ++ d2 = ( (int) ( (((insn >> 16) & 0xfff) | ((insn << 4) & 0xff000)) << 12 ) ) >> 12; ++ disas_e3(s, /* op */ insn & 0xff, /* r1 */ (insn >> 36) & 0xf, /* x2 */ (insn >> 32) & 0xf, /* b2 */ (insn >> 28) & 0xf, d2 ); ++ s->pc += 6; ++ break; ++ case 0xeb: ++ insn = ld_code6(s->pc); ++ DEBUGINSN ++ op = insn & 0xff; ++ r1 = (insn >> 36) & 0xf; ++ r3 = (insn >> 32) & 0xf; ++ b2 = (insn >> 28) & 0xf; ++ d2 = ( (int) ( (((insn >> 16) & 0xfff) | ((insn << 4) & 0xff000)) << 12 ) ) >> 12; ++ disas_eb(s, op, r1, r3, b2, d2); ++ s->pc += 6; ++ break; ++ case 0xed: ++ insn = ld_code6(s->pc); ++ DEBUGINSN ++ op = insn & 0xff; ++ r1 = (insn >> 36) & 0xf; ++ x2 = (insn >> 32) & 0xf; ++ b2 = (insn >> 28) & 0xf; ++ d2 = (short)((insn >> 16) & 0xfff); ++ r1b = (insn >> 12) & 0xf; ++ disas_ed(s, op, r1, x2, b2, d2, r1b); ++ s->pc += 6; ++ break; ++ default: ++ LOG_DISAS("unimplemented opcode 0x%x\n", opc); ++ gen_illegal_opcode(s); ++ s->pc += 6; ++ break; ++ } ++} ++ ++static inline void gen_intermediate_code_internal (CPUState *env, ++ TranslationBlock *tb, ++ int search_pc) ++{ ++ DisasContext dc; ++ target_ulong pc_start; ++ uint64_t next_page_start; ++ uint16_t *gen_opc_end; ++ int j, lj = -1; ++ int num_insns, max_insns; ++ ++ pc_start = tb->pc; ++ ++ dc.pc = tb->pc; ++ dc.env = env; ++ dc.pc = pc_start; ++ dc.is_jmp = DISAS_NEXT; ++ dc.tb = tb; ++ ++ gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; ++ ++ next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; ++ ++ num_insns = 0; ++ max_insns = tb->cflags & CF_COUNT_MASK; ++ if (max_insns == 0) ++ max_insns = CF_COUNT_MASK; ++ ++ gen_icount_start(); ++ ++ /* using a temp for the condition code allows TCG to optimize away ++ any condition code calculations that are not actually used */ ++ cc = tcg_temp_local_new_i32(); ++ tcg_gen_mov_i32(cc, global_cc); ++ do { ++ if (search_pc) { ++ j = gen_opc_ptr - gen_opc_buf; ++ if (lj < j) { ++ lj++; ++ while (lj < j) ++ gen_opc_instr_start[lj++] = 0; ++ } ++ gen_opc_pc[lj] = dc.pc; ++ gen_opc_instr_start[lj] = 1; ++ gen_opc_icount[lj] = num_insns; ++ } ++ if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) ++ gen_io_start(); ++#if defined S390X_DEBUG_DISAS ++ LOG_DISAS("pc " TARGET_FMT_lx "\n", ++ dc.pc); ++#endif ++ disas_s390_insn(env, &dc); ++ ++ num_insns++; ++ } while (!dc.is_jmp && gen_opc_ptr < gen_opc_end && dc.pc < next_page_start ++ && num_insns < max_insns && !env->singlestep_enabled); ++ ++ if (dc.is_jmp != DISAS_TB_JUMP) { ++ tcg_gen_mov_i32(global_cc, cc); ++ tcg_temp_free(cc); ++ } ++ ++ if (!dc.is_jmp) { ++ tcg_gen_st_i64(tcg_const_i64(dc.pc), cpu_env, offsetof(CPUState, psw.addr)); ++ } ++ ++ if (dc.is_jmp == DISAS_SVC) { ++ tcg_gen_st_i64(tcg_const_i64(dc.pc), cpu_env, offsetof(CPUState, psw.addr)); ++ TCGv tmp = tcg_const_i32(EXCP_SVC); ++ gen_helper_exception(tmp); ++ } ++ ++ if (tb->cflags & CF_LAST_IO) ++ gen_io_end(); ++ /* Generate the return instruction */ ++ if (dc.is_jmp != DISAS_TB_JUMP) { ++ tcg_gen_exit_tb(0); ++ } ++ gen_icount_end(tb, num_insns); ++ *gen_opc_ptr = INDEX_op_end; ++ if (search_pc) { ++ j = gen_opc_ptr - gen_opc_buf; ++ lj++; ++ while (lj <= j) ++ gen_opc_instr_start[lj++] = 0; ++ } else { ++ tb->size = dc.pc - pc_start; ++ tb->icount = num_insns; ++ } ++#if defined S390X_DEBUG_DISAS ++ log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0); ++ if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { ++ qemu_log("IN: %s\n", lookup_symbol(pc_start)); ++ log_target_disas(pc_start, dc.pc - pc_start, 1); ++ qemu_log("\n"); ++ } ++#endif ++} ++ + void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb) + { ++ gen_intermediate_code_internal(env, tb, 0); + } + + void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) + { ++ gen_intermediate_code_internal(env, tb, 1); + } + + void gen_pc_load(CPUState *env, TranslationBlock *tb, +Index: qemu-0.14.1/tcg/tcg-op.h +=================================================================== +--- qemu-0.14.1.orig/tcg/tcg-op.h ++++ qemu-0.14.1/tcg/tcg-op.h +@@ -366,6 +366,18 @@ static inline void tcg_gen_br(int label) + tcg_gen_op1i(INDEX_op_br, label); + } + ++static inline void tcg_gen_sync_i32(TCGv_i32 arg) ++{ ++ tcg_gen_op1_i32(INDEX_op_sync_i32, arg); ++} ++ ++#if TCG_TARGET_REG_BITS == 64 ++static inline void tcg_gen_sync_i64(TCGv_i64 arg) ++{ ++ tcg_gen_op1_i64(INDEX_op_sync_i64, arg); ++} ++#endif ++ + static inline void tcg_gen_mov_i32(TCGv_i32 ret, TCGv_i32 arg) + { + if (!TCGV_EQUAL_I32(ret, arg)) +Index: qemu-0.14.1/tcg/tcg-opc.h +=================================================================== +--- qemu-0.14.1.orig/tcg/tcg-opc.h ++++ qemu-0.14.1/tcg/tcg-opc.h +@@ -41,6 +41,7 @@ DEF(call, 0, 1, 2, TCG_OPF_SIDE_EFFECTS) + DEF(jmp, 0, 1, 0, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) + DEF(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) + ++DEF(sync_i32, 0, 1, 0, 0) + DEF(mov_i32, 1, 1, 0, 0) + DEF(movi_i32, 1, 0, 1, 0) + DEF(setcond_i32, 1, 2, 1, 0) +@@ -131,6 +132,7 @@ DEF(nor_i32, 1, 2, 0, 0) + #endif + + #if TCG_TARGET_REG_BITS == 64 ++DEF(sync_i64, 0, 1, 0, 0) + DEF(mov_i64, 1, 1, 0, 0) + DEF(movi_i64, 1, 0, 1, 0) + DEF(setcond_i64, 1, 2, 1, 0) +Index: qemu-0.14.1/tcg/tcg.c +=================================================================== +--- qemu-0.14.1.orig/tcg/tcg.c ++++ qemu-0.14.1/tcg/tcg.c +@@ -2022,6 +2022,12 @@ static inline int tcg_gen_code_common(TC + // dump_regs(s); + #endif + switch(opc) { ++ case INDEX_op_sync_i32: ++#if TCG_TARGET_REG_BITS == 64 ++ case INDEX_op_sync_i64: ++#endif ++ temp_save(s, args[0], s->reserved_regs); ++ break; + case INDEX_op_mov_i32: + #if TCG_TARGET_REG_BITS == 64 + case INDEX_op_mov_i64: diff --git a/app-emulation/qemu-user/files/0.14.1/0016-fix-mipsn32-linux-user-builds.patch b/app-emulation/qemu-user/files/0.14.1/0016-fix-mipsn32-linux-user-builds.patch new file mode 100644 index 0000000..a413f38 --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0016-fix-mipsn32-linux-user-builds.patch @@ -0,0 +1,58 @@ +From 4569b209989e09bdebcb6cce809b3fed0f94142c Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Wed, 25 Aug 2010 14:23:43 +0200 +Subject: [PATCH 16/17] fix mipsn32*-linux-user builds + +Signed-off-by: Ulrich Hecht +--- + configure | 2 ++ + default-configs/mipsn32-linux-user.mak | 1 + + default-configs/mipsn32el-linux-user.mak | 1 + + linux-user/mipsn32/syscall.h | 3 ++- + 4 files changed, 6 insertions(+), 1 deletions(-) + create mode 100644 default-configs/mipsn32-linux-user.mak + create mode 100644 default-configs/mipsn32el-linux-user.mak + +diff --git a/configure b/configure +index bd1484b..6513d91 100755 +--- a/configure ++++ b/configure +@@ -1010,6 +1010,8 @@ m68k-linux-user \ + microblaze-linux-user \ + mips-linux-user \ + mipsel-linux-user \ ++mipsn32-linux-user \ ++mipsn32el-linux-user \ + ppc-linux-user \ + ppc64-linux-user \ + ppc64abi32-linux-user \ +diff --git a/default-configs/mipsn32-linux-user.mak b/default-configs/mipsn32-linux-user.mak +new file mode 100644 +index 0000000..31df570 +--- /dev/null ++++ b/default-configs/mipsn32-linux-user.mak +@@ -0,0 +1 @@ ++# Default configuration for mips-linux-user +diff --git a/default-configs/mipsn32el-linux-user.mak b/default-configs/mipsn32el-linux-user.mak +new file mode 100644 +index 0000000..4d0e4af +--- /dev/null ++++ b/default-configs/mipsn32el-linux-user.mak +@@ -0,0 +1 @@ ++# Default configuration for mipsel-linux-user +diff --git a/linux-user/mipsn32/syscall.h b/linux-user/mipsn32/syscall.h +index 4ec506c..beeeb3c 100644 +--- a/linux-user/mipsn32/syscall.h ++++ b/linux-user/mipsn32/syscall.h +@@ -216,6 +216,7 @@ struct target_pt_regs { + #undef TARGET_ENOTRECOVERABLE + #define TARGET_ENOTRECOVERABLE 166 /* State not recoverable */ + +- ++/* Nasty hack: define a fake errno value for use by sigreturn. */ ++#define TARGET_QEMU_ESIGRETURN 255 + + #define UNAME_MACHINE "mips64" +-- +1.7.1 + diff --git a/app-emulation/qemu-user/files/0.14.1/0017-S-390-build-fix.patch b/app-emulation/qemu-user/files/0.14.1/0017-S-390-build-fix.patch new file mode 100644 index 0000000..c232c1c --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0017-S-390-build-fix.patch @@ -0,0 +1,129 @@ +From 024f781ab4af31ba5e14882b5661d4586ae26988 Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Wed, 9 Feb 2011 18:35:21 +0100 +Subject: [PATCH 17/17] S/390 build fix + +--- + target-s390x/op_helper.c | 22 +++++++++++----------- + target-s390x/translate.c | 2 +- + 2 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c +index 20c83c5..46b71fc 100644 +--- a/target-s390x/op_helper.c ++++ b/target-s390x/op_helper.c +@@ -738,7 +738,7 @@ uint32_t HELPER(tmxx)(uint64_t val, uint32_t mask) + uint32_t HELPER(abs_i32)(uint32_t reg, int32_t val) + { + uint32_t cc; +- if (val == 0x80000000UL) cc = 3; ++ if ((uint32_t)val == 0x80000000UL) cc = 3; + else if (val) cc = 1; + else cc = 0; + +@@ -996,7 +996,7 @@ uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2) + /* condition codes for binary FP ops */ + static uint32_t set_cc_f32(float32 v1, float32 v2) + { +- if (float32_is_nan(v1) || float32_is_nan(v2)) return 3; ++ if (float32_is_any_nan(v1) || float32_is_any_nan(v2)) return 3; + else if (float32_eq(v1, v2, &env->fpu_status)) return 0; + else if (float32_lt(v1, v2, &env->fpu_status)) return 1; + else return 2; +@@ -1004,7 +1004,7 @@ static uint32_t set_cc_f32(float32 v1, float32 v2) + + static uint32_t set_cc_f64(float64 v1, float64 v2) + { +- if (float64_is_nan(v1) || float64_is_nan(v2)) return 3; ++ if (float64_is_any_nan(v1) || float64_is_any_nan(v2)) return 3; + else if (float64_eq(v1, v2, &env->fpu_status)) return 0; + else if (float64_lt(v1, v2, &env->fpu_status)) return 1; + else return 2; +@@ -1013,7 +1013,7 @@ static uint32_t set_cc_f64(float64 v1, float64 v2) + /* condition codes for unary FP ops */ + static uint32_t set_cc_nz_f32(float32 v) + { +- if (float32_is_nan(v)) return 3; ++ if (float32_is_any_nan(v)) return 3; + else if (float32_is_zero(v)) return 0; + else if (float32_is_neg(v)) return 1; + else return 2; +@@ -1021,7 +1021,7 @@ static uint32_t set_cc_nz_f32(float32 v) + + static uint32_t set_cc_nz_f64(float64 v) + { +- if (float64_is_nan(v)) return 3; ++ if (float64_is_any_nan(v)) return 3; + else if (float64_is_zero(v)) return 0; + else if (float64_is_neg(v)) return 1; + else return 2; +@@ -1029,7 +1029,7 @@ static uint32_t set_cc_nz_f64(float64 v) + + static uint32_t set_cc_nz_f128(float128 v) + { +- if (float128_is_nan(v)) return 3; ++ if (float128_is_any_nan(v)) return 3; + else if (float128_is_zero(v)) return 0; + else if (float128_is_neg(v)) return 1; + else return 2; +@@ -1350,7 +1350,7 @@ uint32_t HELPER(cxbr)(uint32_t f1, uint32_t f2) + CPU_QuadU v2; + v2.ll.upper = env->fregs[f2].ll; + v2.ll.lower = env->fregs[f2 + 2].ll; +- if (float128_is_nan(v1.q) || float128_is_nan(v2.q)) return 3; ++ if (float128_is_any_nan(v1.q) || float128_is_any_nan(v2.q)) return 3; + else if (float128_eq(v1.q, v2.q, &env->fpu_status)) return 0; + else if (float128_lt(v1.q, v2.q, &env->fpu_status)) return 1; + else return 2; +@@ -1463,7 +1463,7 @@ uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3) + v2.ll.lower = env->fregs[f2 + 2].ll; + set_round_mode(m3); + env->regs[r1] = float128_to_int64(v2.q, &env->fpu_status); +- if (float128_is_nan(v2.q)) return 3; ++ if (float128_is_any_nan(v2.q)) return 3; + else if (float128_is_zero(v2.q)) return 0; + else if (float128_is_neg(v2.q)) return 1; + else return 2; +@@ -1611,7 +1611,7 @@ uint32_t HELPER(tceb)(uint32_t f1, uint64_t m2) + HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __FUNCTION__, v1, m2, neg); + if (float32_is_zero(v1) && (m2 & (1 << (11-neg)))) cc = 1; + else if (float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) cc = 1; +- else if (float32_is_nan(v1) && (m2 & (1 << (3-neg)))) cc = 1; ++ else if (float32_is_quiet_nan(v1) && (m2 & (1 << (3-neg)))) cc = 1; + else if (float32_is_signaling_nan(v1) && (m2 & (1 << (1-neg)))) cc = 1; + else /* assume normalized number */ if (m2 & (1 << (9-neg))) cc = 1; + /* FIXME: denormalized? */ +@@ -1627,7 +1627,7 @@ uint32_t HELPER(tcdb)(uint32_t f1, uint64_t m2) + HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __FUNCTION__, v1, m2, neg); + if (float64_is_zero(v1) && (m2 & (1 << (11-neg)))) cc = 1; + else if (float64_is_infinity(v1) && (m2 & (1 << (5-neg)))) cc = 1; +- else if (float64_is_nan(v1) && (m2 & (1 << (3-neg)))) cc = 1; ++ else if (float64_is_quiet_nan(v1) && (m2 & (1 << (3-neg)))) cc = 1; + else if (float64_is_signaling_nan(v1) && (m2 & (1 << (1-neg)))) cc = 1; + else /* assume normalized number */ if (m2 & (1 << (9-neg))) cc = 1; + /* FIXME: denormalized? */ +@@ -1645,7 +1645,7 @@ uint32_t HELPER(tcxb)(uint32_t f1, uint64_t m2) + int neg = float128_is_neg(v1.q); + if (float128_is_zero(v1.q) && (m2 & (1 << (11-neg)))) cc = 1; + else if (float128_is_infinity(v1.q) && (m2 & (1 << (5-neg)))) cc = 1; +- else if (float128_is_nan(v1.q) && (m2 & (1 << (3-neg)))) cc = 1; ++ else if (float128_is_quiet_nan(v1.q) && (m2 & (1 << (3-neg)))) cc = 1; + else if (float128_is_signaling_nan(v1.q) && (m2 & (1 << (1-neg)))) cc = 1; + else /* assume normalized number */ if (m2 & (1 << (9-neg))) cc = 1; + /* FIXME: denormalized? */ +diff --git a/target-s390x/translate.c b/target-s390x/translate.c +index e08dcf4..189a60b 100644 +--- a/target-s390x/translate.c ++++ b/target-s390x/translate.c +@@ -67,7 +67,7 @@ void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf, + } + } + for (i = 0; i < 16; i++) { +- cpu_fprintf(f, "F%02d=%016lx", i, (long)env->fregs[i].i); ++ cpu_fprintf(f, "F%02d=%016lx", i, (long)env->fregs[i].ll); + if ((i % 4) == 3) { + cpu_fprintf(f, "\n"); + } else { +-- +1.7.1 + diff --git a/app-emulation/qemu-user/files/0.14.1/0018-qemu-0.14.1-mcast-udp.patch b/app-emulation/qemu-user/files/0.14.1/0018-qemu-0.14.1-mcast-udp.patch new file mode 100644 index 0000000..eb51ea3 --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0018-qemu-0.14.1-mcast-udp.patch @@ -0,0 +1,289 @@ +diff -uNr old-qemu-0.14.1//block/raw-win32.c qemu-0.14.1/block/raw-win32.c +--- old-qemu-0.14.1//block/raw-win32.c 2011-05-06 21:01:43.000000000 +0200 ++++ qemu-0.14.1/block/raw-win32.c 2011-05-11 15:41:45.744749392 +0200 +@@ -93,7 +93,7 @@ + else if (!(flags & BDRV_O_CACHE_WB)) + overlapped |= FILE_FLAG_WRITE_THROUGH; + s->hfile = CreateFile(filename, access_flags, +- FILE_SHARE_READ, NULL, ++ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, overlapped, NULL); + if (s->hfile == INVALID_HANDLE_VALUE) { + int err = GetLastError(); +@@ -354,7 +354,7 @@ + else if (!(flags & BDRV_O_CACHE_WB)) + overlapped |= FILE_FLAG_WRITE_THROUGH; + s->hfile = CreateFile(filename, access_flags, +- FILE_SHARE_READ, NULL, ++ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + create_flags, overlapped, NULL); + if (s->hfile == INVALID_HANDLE_VALUE) { + int err = GetLastError(); +diff -uNr old-qemu-0.14.1//hw/e1000.c qemu-0.14.1/hw/e1000.c +--- old-qemu-0.14.1//hw/e1000.c 2011-05-06 21:01:43.000000000 +0200 ++++ qemu-0.14.1/hw/e1000.c 2011-05-11 15:41:45.744749392 +0200 +@@ -573,7 +573,7 @@ + if (rctl & E1000_RCTL_UPE) // promiscuous + return 1; + +- if ((buf[0] & 1) && (rctl & E1000_RCTL_MPE)) // promiscuous mcast ++ if ((buf[0] & 1)) //&& (rctl & E1000_RCTL_MPE)) // promiscuous mcast + return 1; + + if ((rctl & E1000_RCTL_BAM) && !memcmp(buf, bcast, sizeof bcast)) +diff -uNr old-qemu-0.14.1//Makefile.objs qemu-0.14.1/Makefile.objs +--- old-qemu-0.14.1//Makefile.objs 2011-05-06 21:01:43.000000000 +0200 ++++ qemu-0.14.1/Makefile.objs 2011-05-11 15:41:45.751749392 +0200 +@@ -34,6 +34,7 @@ + net-nested-y = queue.o checksum.o util.o + net-nested-y += socket.o + net-nested-y += dump.o ++net-nested-y += udp.o + net-nested-$(CONFIG_POSIX) += tap.o + net-nested-$(CONFIG_LINUX) += tap-linux.o + net-nested-$(CONFIG_WIN32) += tap-win32.o +diff -uNr old-qemu-0.14.1//net/udp.c qemu-0.14.1/net/udp.c +--- old-qemu-0.14.1//net/udp.c 1970-01-01 01:00:00.000000000 +0100 ++++ qemu-0.14.1/net/udp.c 2011-05-11 15:41:45.752749392 +0200 +@@ -0,0 +1,138 @@ ++/* ++ * QEMU System Emulator ++ * ++ * Copyright (c) 2003-2008 Fabrice Bellard ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++#include "net/udp.h" ++ ++#include "config-host.h" ++ ++#ifndef _WIN32 ++#include ++#include ++#include ++#endif ++ ++#include "net.h" ++#include "qemu-char.h" ++#include "qemu-common.h" ++#include "qemu-option.h" ++#include "qemu_socket.h" ++#include "sysemu.h" ++ ++ ++typedef struct UDPState { ++ VLANClientState nc; ++ int rfd; ++ struct sockaddr_in sender; ++} UDPState; ++ ++static void udp_to_qemu(void *opaque) ++{ ++ UDPState *s = opaque; ++ uint8_t buf[4096]; ++ int size; ++ ++ size = recvfrom(s->rfd, (char *)buf, sizeof(buf), 0, NULL, NULL); ++ if (size > 0) { ++ qemu_send_packet(&s->nc, buf, size); ++ } ++} ++ ++static ssize_t udp_receive(VLANClientState *nc, const uint8_t *buf, size_t size) ++{ ++ UDPState *s = DO_UPCAST(UDPState, nc, nc); ++ int ret; ++ ++ do { ++ ret = sendto(s->rfd, (const char *)buf, size, 0, (struct sockaddr *)&s->sender, sizeof (s->sender)); ++ } while (ret < 0 && errno == EINTR); ++ ++ return ret; ++} ++ ++static void udp_cleanup(VLANClientState *nc) ++{ ++ UDPState *s = DO_UPCAST(UDPState, nc, nc); ++ qemu_set_fd_handler(s->rfd, NULL, NULL, NULL); ++ close(s->rfd); ++} ++ ++static NetClientInfo net_udp_info = { ++ .type = NET_CLIENT_TYPE_UDP, ++ .size = sizeof(UDPState), ++ .receive = udp_receive, ++ .cleanup = udp_cleanup, ++}; ++ ++static int net_udp_init(VLANState *vlan, const char *model, ++ const char *name, int sport, ++ const char *daddr, int dport) ++{ ++ VLANClientState *nc; ++ UDPState *s; ++ struct sockaddr_in receiver; ++ int ret; ++ ++ nc = qemu_new_net_client(&net_udp_info, vlan, NULL, model, name); ++ ++ snprintf(nc->info_str, sizeof(nc->info_str),"udp: %i->%s:%i", ++ sport, daddr, dport); ++ ++ s = DO_UPCAST(UDPState, nc, nc); ++ ++ s->rfd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); ++ receiver.sin_family = AF_INET; ++ receiver.sin_addr.s_addr = INADDR_ANY; ++ receiver.sin_port = htons(sport); ++ ret = bind(s->rfd, (struct sockaddr *)&receiver, sizeof(receiver)); ++ ++ if (ret == -1) { ++ fprintf (stderr, "bind error:%s\n", strerror(errno)); ++ return ret; ++ } ++ ++ memset((char*)&s->sender, 0,sizeof(s->sender)); ++ s->sender.sin_family = AF_INET; ++ s->sender.sin_port = htons(dport); ++ inet_aton(daddr, &s->sender.sin_addr); ++ ++ qemu_set_fd_handler(s->rfd, udp_to_qemu, NULL, s); ++ ++ return 0; ++} ++ ++int net_init_udp(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan) ++{ ++ const char *daddr; ++ int sport, dport; ++ ++ daddr = qemu_opt_get(opts, "daddr"); ++ ++ sport = qemu_opt_get_number(opts, "sport", 0); ++ dport = qemu_opt_get_number(opts, "dport", 0); ++ ++ if (net_udp_init(vlan, "udp", name, sport, daddr, dport) == -1) { ++ return -1; ++ } ++ ++ return 0; ++} +diff -uNr old-qemu-0.14.1//net/udp.h qemu-0.14.1/net/udp.h +--- old-qemu-0.14.1//net/udp.h 1970-01-01 01:00:00.000000000 +0100 ++++ qemu-0.14.1/net/udp.h 2011-05-11 15:41:45.752749392 +0200 +@@ -0,0 +1,32 @@ ++/* ++ * QEMU System Emulator ++ * ++ * Copyright (c) 2003-2008 Fabrice Bellard ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++#ifndef QEMU_NET_UDP_H ++#define QEMU_NET_UDP_H ++ ++#include "qemu-common.h" ++#include "qemu-option.h" ++ ++int net_init_udp(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan); ++ ++#endif /* QEMU_NET_UDP_H */ +diff -uNr old-qemu-0.14.1//net.c qemu-0.14.1/net.c +--- old-qemu-0.14.1//net.c 2011-05-06 21:01:44.000000000 +0200 ++++ qemu-0.14.1/net.c 2011-05-11 15:42:53.145749408 +0200 +@@ -30,6 +30,7 @@ + #include "net/dump.h" + #include "net/slirp.h" + #include "net/vde.h" ++#include "net/udp.h" + #include "net/util.h" + #include "monitor.h" + #include "sysemu.h" +@@ -1085,9 +1086,31 @@ + .help = "permissions for socket", + }, + { /* end of list */ } +- }, ++ }, + #endif + }, { ++ ++ .type = "udp", ++ .init = net_init_udp, ++ .desc = { ++ NET_COMMON_PARAMS_DESC, ++ { ++ .name = "sport", ++ .type = QEMU_OPT_NUMBER, ++ ++ .help = "source port number", ++ }, { ++ .name = "daddr", ++ .type = QEMU_OPT_STRING, ++ .help = "destination IP address", ++ }, { ++ .name = "dport", ++ .type = QEMU_OPT_NUMBER, ++ .help = "destination port number", ++ }, ++ { /* end of list */ } ++ }, ++ }, { + .type = "dump", + .init = net_init_dump, + .desc = { +diff -uNr old-qemu-0.14.1//net.h qemu-0.14.1/net.h +--- old-qemu-0.14.1//net.h 2011-05-06 21:01:44.000000000 +0200 ++++ qemu-0.14.1/net.h 2011-05-11 15:41:45.754749392 +0200 +@@ -35,6 +35,7 @@ + NET_CLIENT_TYPE_TAP, + NET_CLIENT_TYPE_SOCKET, + NET_CLIENT_TYPE_VDE, ++ NET_CLIENT_TYPE_UDP, + NET_CLIENT_TYPE_DUMP + } net_client_type; + +diff -uNr old-qemu-0.14.1//qemu-options.hx qemu-0.14.1/qemu-options.hx +--- old-qemu-0.14.1//qemu-options.hx 2011-05-06 21:01:44.000000000 +0200 ++++ qemu-0.14.1/qemu-options.hx 2011-05-11 15:41:45.755749392 +0200 +@@ -1070,6 +1070,8 @@ + "-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port[,localaddr=addr]]\n" + " connect the vlan 'n' to multicast maddr and port\n" + " use 'localaddr=addr' to specify the host address to send packets from\n" ++ "-net udp[,vlan=n]sport=sport,dport=dport,daddr=host\n" ++ " connect the vlan 'n' to a UDP tunnel (for Dynamips/GNS3)\n" + #ifdef CONFIG_VDE + "-net vde[,vlan=n][,name=str][,sock=socketpath][,port=n][,group=groupname][,mode=octalmode]\n" + " connect the vlan 'n' to port 'n' of a vde switch running\n" diff --git a/app-emulation/qemu-user/files/0.14.1/0019-linux-user-fix-openat.patch b/app-emulation/qemu-user/files/0.14.1/0019-linux-user-fix-openat.patch new file mode 100644 index 0000000..b142343 --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0019-linux-user-fix-openat.patch @@ -0,0 +1,52 @@ +From 39c6bee3d5023a3e339bafd8073bc2c920cd79c5 Mon Sep 17 00:00:00 2001 +From: Alexander Graf +Date: Sun, 25 Sep 2011 06:21:28 +0200 +Subject: [PATCH] linux-user: fix openat + +When running openat using qemu-arm, we stumbled over invalid permissions +on the created files. The reason for this is that the mode parameter gets +treates as an O_... flag, which it isn't - it's a permission bitmask. + +This patch removes the needless translation of the mode parameter, +rendering permission passing of openat() to work with linux-user. + +Reported-by: Dirk Mueller +Signed-off-by: Alexander Graf +--- + linux-user/syscall.c | 14 +------------- + 1 files changed, 1 insertions(+), 13 deletions(-) + +diff --git a/linux-user/syscall.c b/linux-user/syscall.c +index 6b73769..27970a4 100644 +--- a/linux-user/syscall.c ++++ b/linux-user/syscall.c +@@ -376,25 +376,13 @@ static int sys_mknodat(int dirfd, const char *pathname, mode_t mode, + } + #endif + #ifdef TARGET_NR_openat +-static int sys_openat(int dirfd, const char *pathname, int flags, ...) ++static int sys_openat(int dirfd, const char *pathname, int flags, mode_t mode) + { + /* + * open(2) has extra parameter 'mode' when called with + * flag O_CREAT. + */ + if ((flags & O_CREAT) != 0) { +- va_list ap; +- mode_t mode; +- +- /* +- * Get the 'mode' parameter and translate it to +- * host bits. +- */ +- va_start(ap, flags); +- mode = va_arg(ap, mode_t); +- mode = target_to_host_bitmask(mode, fcntl_flags_tbl); +- va_end(ap); +- + return (openat(dirfd, pathname, flags, mode)); + } + return (openat(dirfd, pathname, flags)); +-- +1.6.0.2 + diff --git a/app-emulation/qemu-user/files/0.14.1/0020-linux-user-implement-reboot-syscall.patch b/app-emulation/qemu-user/files/0.14.1/0020-linux-user-implement-reboot-syscall.patch new file mode 100644 index 0000000..97411d2 --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0020-linux-user-implement-reboot-syscall.patch @@ -0,0 +1,40 @@ +From: Alexander Graf + +For OBS, we're running a full cross-guest inside of a VM. When a build +is done there, we reboot the guest as shutdown mechanism. + +Unfortunately, reboot is not implemented in linux-user. So this mechanism +fails, spilling unpretty warnings. This patch implements sys_reboot() +emulation. + +Signed-off-by: Alexander Graf +--- + linux-user/syscall.c | 8 +++++++- + 1 files changed, 7 insertions(+), 1 deletions(-) + +Index: qemu-0.14.1/linux-user/syscall.c +=================================================================== +--- qemu-0.14.1.orig/linux-user/syscall.c ++++ qemu-0.14.1/linux-user/syscall.c +@@ -239,6 +239,8 @@ _syscall6(int,sys_futex,int *,uaddr,int, + const struct timespec *,timeout,int *,uaddr2,int,val3) + #endif + #endif ++_syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd, ++ void *, arg); + + static bitmask_transtbl fcntl_flags_tbl[] = { + { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, }, +@@ -5536,7 +5538,11 @@ abi_long do_syscall(void *cpu_env, int n + break; + #endif + case TARGET_NR_reboot: +- goto unimplemented; ++ if (!(p = lock_user_string(arg4))) ++ goto efault; ++ ret = reboot(arg1, arg2, arg3, p); ++ unlock_user(p, arg4, 0); ++ break; + #ifdef TARGET_NR_readdir + case TARGET_NR_readdir: + goto unimplemented; diff --git a/app-emulation/qemu-user/files/0.14.1/0021-implement-prlimit64-syscall.patch b/app-emulation/qemu-user/files/0.14.1/0021-implement-prlimit64-syscall.patch new file mode 100644 index 0000000..b942cd4 --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0021-implement-prlimit64-syscall.patch @@ -0,0 +1,117 @@ +From agraf@suse.de Thu, 29 Sep 2011 11:00:25 +0200 +Return-Path: +Received: from imap.suse.de ([unix socket]) + by imap-int (Cyrus v2.2.12) with LMTPA; + Thu, 29 Sep 2011 11:07:10 +0200 +X-Sieve: CMU Sieve 2.2 +Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) + (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) + (Client CN "relay.suse.de", Issuer "CAcert Class 3 Root" (verified OK)) + by imap.suse.de (Postfix) with ESMTPS id AF8563C539A9 + for ; Thu, 29 Sep 2011 11:07:10 +0200 (CEST) +Received: by relay2.suse.de (Postfix) + id A639118552E6; Thu, 29 Sep 2011 11:07:10 +0200 (CEST) +Received: from imap.suse.de (loadbalancer1.suse.de [149.44.160.248]) + (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) + (No client certificate requested) + by relay2.suse.de (Postfix) with ESMTPS id A573518552E1; + Thu, 29 Sep 2011 11:07:10 +0200 (CEST) +Received: from localhost.localdomain (charybdis-ext.suse.de [195.135.221.2]) + (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) + (Client did not present a certificate) + by imap.suse.de (Postfix) with ESMTPSA id 7AD993C539A9; + Thu, 29 Sep 2011 11:07:10 +0200 (CEST) +From: Alexander Graf +To: adrian@suse.de +Cc: Peter Maydell , Riku Voipio +Subject: [PATCH] linux-user: Implement prlimit64 syscall +Date: Thu, 29 Sep 2011 11:00:25 +0200 +Message-Id: <1317286825-2033-1-git-send-email-agraf@suse.de> +X-Mailer: git-send-email 1.6.0.2 + +From: Peter Maydell + +Implement the prlimit64 syscall. + +Slightly modified to apply upstream -Riku + +Signed-off-by: Peter Maydell +Signed-off-by: Riku Voipio + +Index: qemu-0.14.1/linux-user/syscall.c +=================================================================== +--- qemu-0.14.1.orig/linux-user/syscall.c ++++ qemu-0.14.1/linux-user/syscall.c +@@ -524,6 +524,21 @@ static int sys_inotify_init1(int flags) + #endif /* CONFIG_INOTIFY */ + + ++#if defined(TARGET_NR_prlimit64) ++#ifndef __NR_prlimit64 ++# define __NR_prlimit64 -1 ++#endif ++#define __NR_sys_prlimit64 __NR_prlimit64 ++/* The glibc rlimit structure may not be that used by the underlying syscall */ ++struct host_rlimit64 { ++ uint64_t rlim_cur; ++ uint64_t rlim_max; ++}; ++_syscall4(int, sys_prlimit64, pid_t, pid, int, resource, ++ const struct host_rlimit64 *, new_limit, ++ struct host_rlimit64 *, old_limit) ++#endif ++ + extern int personality(int); + extern int flock(int, int); + extern int setfsuid(int); +@@ -7620,6 +7635,34 @@ abi_long do_syscall(void *cpu_env, int n + break; + } + #endif ++#ifdef TARGET_NR_prlimit64 ++ case TARGET_NR_prlimit64: ++ { ++ /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */ ++ struct target_rlimit64 *target_rnew, *target_rold; ++ struct host_rlimit64 rnew, rold, *rnewp = 0; ++ if (arg3) { ++ if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) { ++ goto efault; ++ } ++ rnew.rlim_cur = tswap64(target_rnew->rlim_cur); ++ rnew.rlim_max = tswap64(target_rnew->rlim_max); ++ unlock_user_struct(target_rnew, arg3, 0); ++ rnewp = &rnew; ++ } ++ ++ ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0)); ++ if (!is_error(ret) && arg4) { ++ if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) { ++ goto efault; ++ } ++ target_rold->rlim_cur = tswap64(rold.rlim_cur); ++ target_rold->rlim_max = tswap64(rold.rlim_max); ++ unlock_user_struct(target_rold, arg4, 1); ++ } ++ break; ++ } ++#endif + + default: + unimplemented: +Index: qemu-0.14.1/linux-user/syscall_defs.h +=================================================================== +--- qemu-0.14.1.orig/linux-user/syscall_defs.h ++++ qemu-0.14.1/linux-user/syscall_defs.h +@@ -2237,6 +2237,11 @@ struct target_mq_attr { + abi_long mq_curmsgs; + }; + ++struct target_rlimit64 { ++ uint64_t rlim_cur; ++ uint64_t rlim_max; ++}; ++ + #include "socket.h" + + #include "errno_defs.h" diff --git a/app-emulation/qemu-user/files/0.14.1/0022-fixing-smp-races.patch b/app-emulation/qemu-user/files/0.14.1/0022-fixing-smp-races.patch new file mode 100644 index 0000000..adf4efd --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0022-fixing-smp-races.patch @@ -0,0 +1,34 @@ +From: Alexander Graf + +fixes some SMP races +--- + cpu-all.h | 2 +- + exec.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +Index: qemu-0.14.1/cpu-all.h +=================================================================== +--- qemu-0.14.1.orig/cpu-all.h ++++ qemu-0.14.1/cpu-all.h +@@ -775,7 +775,7 @@ void cpu_dump_statistics(CPUState *env, + void QEMU_NORETURN cpu_abort(CPUState *env, const char *fmt, ...) + GCC_FMT_ATTR(2, 3); + extern CPUState *first_cpu; +-extern CPUState *cpu_single_env; ++extern __thread CPUState *cpu_single_env; + + #define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */ + #define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */ +Index: qemu-0.14.1/exec.c +=================================================================== +--- qemu-0.14.1.orig/exec.c ++++ qemu-0.14.1/exec.c +@@ -112,7 +112,7 @@ RAMList ram_list = { .blocks = QLIST_HEA + CPUState *first_cpu; + /* current CPU in the current thread. It is only valid inside + cpu_exec() */ +-CPUState *cpu_single_env; ++__thread CPUState *cpu_single_env; + /* 0 = Do not count executed instructions. + 1 = Precise instruction counting. + 2 = Adaptive rate instruction counting. */ diff --git a/app-emulation/qemu-user/files/0.14.1/0023-linux-user-add-binfmt-wrapper-for-argv-0-handling.patch b/app-emulation/qemu-user/files/0.14.1/0023-linux-user-add-binfmt-wrapper-for-argv-0-handling.patch new file mode 100644 index 0000000..4563544 --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0023-linux-user-add-binfmt-wrapper-for-argv-0-handling.patch @@ -0,0 +1,167 @@ +From 864b2c7da05bc29a94b3e792b100dd5189576942 Mon Sep 17 00:00:00 2001 +From: Alexander Graf +Date: Fri, 30 Sep 2011 19:40:36 +0200 +Subject: [PATCH] linux-user: add binfmt wrapper for argv[0] handling + +When using qemu's linux-user binaries through binfmt, argv[0] gets lost +along the execution because qemu only gets passed in the full file name +to the executable while argv[0] can be something completely different. + +This breaks in some subtile situations, such as the grep and make test +suites. + +This patch adds a wrapper binary called qemu-$TARGET-binfmt that can be +used with binfmt's P flag which passes the full path _and_ argv[0] to +the binfmt handler. + +The binary would be smart enough to be versatile and only exist in the +system once, creating the qemu binary path names from its own argv[0]. +However, this seemed like it didn't fit the make system too well, so +we're currently creating a new binary for each target archictecture. + +CC: Reinhard Max +Signed-off-by: Alexander Graf +--- + Makefile.target | 8 ++++++++ + linux-user/binfmt.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + scripts/qemu-binfmt-conf.sh | 34 +++++++++++++++++----------------- + 3 files changed, 67 insertions(+), 17 deletions(-) + create mode 100644 linux-user/binfmt.c + +Index: qemu-0.14.1/Makefile.target +=================================================================== +--- qemu-0.14.1.orig/Makefile.target ++++ qemu-0.14.1/Makefile.target +@@ -33,6 +33,10 @@ endif + PROGS=$(QEMU_PROG) + STPFILES= + ++ifdef CONFIG_LINUX_USER ++PROGS+=$(QEMU_PROG)-binfmt ++endif ++ + ifndef CONFIG_HAIKU + LIBS+=-lm + endif +@@ -131,6 +135,8 @@ obj-y += $(addprefix ../libuser/, $(user + obj-y += $(addprefix ../libdis-user/, $(libdis-y)) + obj-y += $(libobj-y) + ++obj-binfmt-y += binfmt.o ++ + endif #CONFIG_LINUX_USER + + ######################################################### +@@ -346,6 +352,8 @@ obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml + $(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) + $(call LINK,$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)) + ++$(QEMU_PROG)-binfmt: $(obj-binfmt-y) ++ $(call LINK,$^) + + gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh + $(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES)," GEN $(TARGET_DIR)$@") +Index: qemu-0.14.1/linux-user/binfmt.c +=================================================================== +--- /dev/null ++++ qemu-0.14.1/linux-user/binfmt.c +@@ -0,0 +1,42 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++int main(int argc, char **argv, char **envp) ++{ ++ char *binfmt; ++ char **new_argv; ++ ++ /* ++ * Check if our file name ends with -binfmt ++ */ ++ binfmt = argv[0] + strlen(argv[0]) - strlen("-binfmt"); ++ if (strcmp(binfmt, "-binfmt")) { ++ fprintf(stderr, "%s: Invalid executable name\n", argv[0]); ++ exit(1); ++ } ++ if (argc < 3) { ++ fprintf(stderr, "%s: Please use me through binfmt with P flag\n", ++ argv[0]); ++ exit(1); ++ } ++ ++ binfmt[0] = '\0'; ++ /* Now argv[0] is the real qemu binary name */ ++ ++ new_argv = (char **)malloc((argc + 2) * sizeof(*new_argv)); ++ if (argc > 3) { ++ memcpy(&new_argv[4], &argv[3], (argc - 3) * sizeof(*new_argv)); ++ } ++ new_argv[0] = argv[0]; ++ new_argv[1] = (char *)"-0"; ++ new_argv[2] = argv[2]; ++ new_argv[3] = argv[1]; ++ new_argv[argc + 1] = NULL; ++ ++ return execve(new_argv[0], new_argv, envp); ++} +Index: qemu-0.14.1/scripts/qemu-binfmt-conf.sh +=================================================================== +--- qemu-0.14.1.orig/scripts/qemu-binfmt-conf.sh ++++ qemu-0.14.1/scripts/qemu-binfmt-conf.sh +@@ -34,36 +34,36 @@ esac + + # register the interpreter for each cpu except for the native one + if [ $cpu != "i386" ] ; then +- echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register +- echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register ++ echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386-binfmt:P' > /proc/sys/fs/binfmt_misc/register ++ echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "alpha" ] ; then +- echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-alpha:' > /proc/sys/fs/binfmt_misc/register ++ echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-alpha-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "arm" ] ; then +- echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register +- echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-armeb:' > /proc/sys/fs/binfmt_misc/register ++ echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm-binfmt:P' > /proc/sys/fs/binfmt_misc/register ++ echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-armeb-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "sparc" ] ; then +- echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register ++ echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sparc-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "ppc" ] ; then +- echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register ++ echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "m68k" ] ; then + echo 'Please check cpu value and header information for m68k!' +- echo ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register ++ echo ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-m68k-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "mips" ] ; then + # FIXME: We could use the other endianness on a MIPS host. +- echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register +- echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register +- echo ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mipsn32:' > /proc/sys/fs/binfmt_misc/register +- echo ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsn32el:' > /proc/sys/fs/binfmt_misc/register +- echo ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips64:' > /proc/sys/fs/binfmt_misc/register +- echo ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mips64el:' > /proc/sys/fs/binfmt_misc/register ++ echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips-binfmt:P' > /proc/sys/fs/binfmt_misc/register ++ echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsel-binfmt:P' > /proc/sys/fs/binfmt_misc/register ++ echo ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mipsn32-binfmt:P' > /proc/sys/fs/binfmt_misc/register ++ echo ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsn32el-binfmt:P' > /proc/sys/fs/binfmt_misc/register ++ echo ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips64-binfmt:P' > /proc/sys/fs/binfmt_misc/register ++ echo ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mips64el-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "sh" ] ; then +- echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-sh4:' > /proc/sys/fs/binfmt_misc/register +- echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb:' > /proc/sys/fs/binfmt_misc/register ++ echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-sh4-binfmt:P' > /proc/sys/fs/binfmt_misc/register ++ echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi diff --git a/app-emulation/qemu-user/files/0.14.1/0025-add-syscall-numbers-from-2.6.39.2.patch b/app-emulation/qemu-user/files/0.14.1/0025-add-syscall-numbers-from-2.6.39.2.patch new file mode 100644 index 0000000..0d9cf6e --- /dev/null +++ b/app-emulation/qemu-user/files/0.14.1/0025-add-syscall-numbers-from-2.6.39.2.patch @@ -0,0 +1,357 @@ +diff -uNr qemu-0.14.1.orig/linux-user/alpha/syscall_nr.h qemu-0.14.1/linux-user/alpha/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/alpha/syscall_nr.h 2011-11-24 22:21:09.636856616 +0100 ++++ qemu-0.14.1/linux-user/alpha/syscall_nr.h 2011-11-24 22:22:04.528478368 +0100 +@@ -411,7 +411,28 @@ + #define TARGET_NR_signalfd 476 + #define TARGET_NR_timerfd 477 + #define TARGET_NR_eventfd 478 +- ++#define TARGET_NR_recvmmsg 479 ++#define TARGET_NR_fallocate 480 ++#define TARGET_NR_timerfd_create 481 ++#define TARGET_NR_timerfd_settime 482 ++#define TARGET_NR_timerfd_gettime 483 ++#define TARGET_NR_signalfd4 484 ++#define TARGET_NR_eventfd2 485 ++#define TARGET_NR_epoll_create1 486 ++#define TARGET_NR_dup3 487 ++#define TARGET_NR_pipe2 488 ++#define TARGET_NR_inotify_init1 489 ++#define TARGET_NR_preadv 490 ++#define TARGET_NR_pwritev 491 ++#define TARGET_NR_rt_tgsigqueueinfo 492 ++#define TARGET_NR_perf_event_open 493 ++#define TARGET_NR_fanotify_init 494 ++#define TARGET_NR_fanotify_mark 495 ++#define TARGET_NR_prlimit64 496 ++#define TARGET_NR_name_to_handle_at 497 ++#define TARGET_NR_open_by_handle_at 498 ++#define TARGET_NR_clock_adjtime 499 ++#define TARGET_NR_syncfs 500 + /* The following aliases are defined in order to match up with the + standard i386 syscalls implemented in syscalls.c. */ + #define TARGET_NR_chown32 TARGET_NR_chown +diff -uNr qemu-0.14.1.orig/linux-user/arm/syscall_nr.h qemu-0.14.1/linux-user/arm/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/arm/syscall_nr.h 2011-11-24 22:21:09.627597287 +0100 ++++ qemu-0.14.1/linux-user/arm/syscall_nr.h 2011-11-24 22:21:41.762101277 +0100 +@@ -365,3 +365,16 @@ + #define TARGET_NR_dup3 (358) + #define TARGET_NR_pipe2 (359) + #define TARGET_NR_inotify_init1 (360) ++#define TARGET_NR_preadv (361) ++#define TARGET_NR_pwritev (362) ++#define TARGET_NR_rt_tgsigqueueinfo (363) ++#define TARGET_NR_perf_event_open (364) ++#define TARGET_NR_recvmmsg (365) ++#define TARGET_NR_accept4 (366) ++#define TARGET_NR_fanotify_init (367) ++#define TARGET_NR_fanotify_mark (368) ++#define TARGET_NR_prlimit64 (369) ++#define TARGET_NR_name_to_handle_at (370) ++#define TARGET_NR_open_by_handle_at (371) ++#define TARGET_NR_clock_adjtime (372) ++#define TARGET_NR_syncfs (373) +diff -uNr qemu-0.14.1.orig/linux-user/cris/syscall_nr.h qemu-0.14.1/linux-user/cris/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/cris/syscall_nr.h 2011-11-24 22:21:09.625282454 +0100 ++++ qemu-0.14.1/linux-user/cris/syscall_nr.h 2011-11-24 22:21:41.762101277 +0100 +@@ -333,3 +333,5 @@ + #define TARGET_NR_dup3 330 + #define TARGET_NR_pipe2 331 + #define TARGET_NR_inotify_init1 332 ++#define TARGET_NR_preadv 333 ++#define TARGET_NR_pwritev 334 +diff -uNr qemu-0.14.1.orig/linux-user/i386/syscall_nr.h qemu-0.14.1/linux-user/i386/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/i386/syscall_nr.h 2011-11-24 22:21:09.632226952 +0100 ++++ qemu-0.14.1/linux-user/i386/syscall_nr.h 2011-11-24 22:21:41.764416110 +0100 +@@ -335,3 +335,15 @@ + #define TARGET_NR_dup3 330 + #define TARGET_NR_pipe2 331 + #define TARGET_NR_inotify_init1 332 ++#define TARGET_NR_preadv 333 ++#define TARGET_NR_pwritev 334 ++#define TARGET_NR_rt_tgsigqueueinfo 335 ++#define TARGET_NR_perf_event_open 336 ++#define TARGET_NR_recvmmsg 337 ++#define TARGET_NR_fanotify_init 338 ++#define TARGET_NR_fanotify_mark 339 ++#define TARGET_NR_prlimit64 340 ++#define TARGET_NR_name_to_handle_at 341 ++#define TARGET_NR_open_by_handle_at 342 ++#define TARGET_NR_clock_adjtime 343 ++#define TARGET_NR_syncfs 344 +diff -uNr qemu-0.14.1.orig/linux-user/m68k/syscall_nr.h qemu-0.14.1/linux-user/m68k/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/m68k/syscall_nr.h 2011-11-24 22:21:09.629912120 +0100 ++++ qemu-0.14.1/linux-user/m68k/syscall_nr.h 2011-11-24 22:21:41.764416110 +0100 +@@ -328,3 +328,19 @@ + #define TARGET_NR_dup3 326 + #define TARGET_NR_pipe2 327 + #define TARGET_NR_inotify_init1 328 ++#define TARGET_NR_inotify_init1 328 ++#define TARGET_NR_preadv 329 ++#define TARGET_NR_pwritev 330 ++#define TARGET_NR_rt_tgsigqueueinfo 331 ++#define TARGET_NR_perf_event_open 332 ++#define TARGET_NR_get_thread_area 333 ++#define TARGET_NR_set_thread_area 334 ++#define TARGET_NR_atomic_cmpxchg_32 335 ++#define TARGET_NR_atomic_barrier 336 ++#define TARGET_NR_fanotify_init 337 ++#define TARGET_NR_fanotify_mark 338 ++#define TARGET_NR_prlimit64 339 ++#define TARGET_NR_name_to_handle_at 340 ++#define TARGET_NR_open_by_handle_at 341 ++#define TARGET_NR_clock_adjtime 342 ++#define TARGET_NR_syncfs 343 +diff -uNr qemu-0.14.1.orig/linux-user/main.c qemu-0.14.1/linux-user/main.c +--- qemu-0.14.1.orig/linux-user/main.c 2011-11-24 22:21:09.632226952 +0100 ++++ qemu-0.14.1/linux-user/main.c 2011-11-24 22:21:41.766730943 +0100 +@@ -1922,6 +1922,33 @@ + MIPS_SYS(sys_epoll_pwait, 6) + MIPS_SYS(sys_ioprio_set, 3) + MIPS_SYS(sys_ioprio_get, 2) ++ MIPS_SYS(sys_utimensat, 4) ++ MIPS_SYS(sys_signalfd, 3) ++ MIPS_SYS(sys_ni_syscall, 0) /* was timerfd */ ++ MIPS_SYS(sys_eventfd, 1) ++ MIPS_SYS(sys_fallocate, 6) /* 4320 */ ++ MIPS_SYS(sys_timerfd_create, 2) ++ MIPS_SYS(sys_timerfd_gettime, 2) ++ MIPS_SYS(sys_timerfd_settime, 4) ++ MIPS_SYS(sys_signalfd4, 4) ++ MIPS_SYS(sys_eventfd2, 2) /* 4325 */ ++ MIPS_SYS(sys_epoll_create1, 1) ++ MIPS_SYS(sys_dup3, 3) ++ MIPS_SYS(sys_pipe2, 2) ++ MIPS_SYS(sys_inotify_init1, 1) ++ MIPS_SYS(sys_preadv, 6) /* 4330 */ ++ MIPS_SYS(sys_pwritev, 6) ++ MIPS_SYS(sys_rt_tgsigqueueinfo, 4) ++ MIPS_SYS(sys_perf_event_open, 5) ++ MIPS_SYS(sys_accept4, 4) ++ MIPS_SYS(sys_recvmmsg, 5) /* 4335 */ ++ MIPS_SYS(sys_fanotify_init, 2) ++ MIPS_SYS(sys_fanotify_mark, 6) ++ MIPS_SYS(sys_prlimit64, 4) ++ MIPS_SYS(sys_name_to_handle_at, 5) ++ MIPS_SYS(sys_open_by_handle_at, 3) /* 4340 */ ++ MIPS_SYS(sys_clock_adjtime, 2) ++ MIPS_SYS(sys_syncfs, 1) + }; + + #undef MIPS_SYS +diff -uNr qemu-0.14.1.orig/linux-user/microblaze/syscall_nr.h qemu-0.14.1/linux-user/microblaze/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/microblaze/syscall_nr.h 2011-11-24 22:21:09.629912120 +0100 ++++ qemu-0.14.1/linux-user/microblaze/syscall_nr.h 2011-11-24 22:21:41.766730943 +0100 +@@ -364,6 +364,16 @@ + #define TARGET_NR_sendmsg 360 /* new */ + #define TARGET_NR_recvmsg 361 /* new */ + #define TARGET_NR_accept04 362 /* new */ +- +-#define TARGET_NR_syscalls 363 ++#define TARGET_NR_preadv 363 /* new */ ++#define TARGET_NR_pwritev 364 /* new */ ++#define TARGET_NR_rt_tgsigqueueinfo 365 /* new */ ++#define TARGET_NR_perf_event_open 366 /* new */ ++#define TARGET_NR_recvmmsg 367 /* new */ ++#define TARGET_NR_fanotify_init 368 ++#define TARGET_NR_fanotify_mark 369 ++#define TARGET_NR_prlimit64 370 ++#define TARGET_NR_name_to_handle_at 371 ++#define TARGET_NR_open_by_handle_at 372 ++#define TARGET_NR_clock_adjtime 373 ++#define TARGET_NR_syncfs 374 + +diff -uNr qemu-0.14.1.orig/linux-user/mips/syscall_nr.h qemu-0.14.1/linux-user/mips/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/mips/syscall_nr.h 2011-11-24 22:21:09.632226952 +0100 ++++ qemu-0.14.1/linux-user/mips/syscall_nr.h 2011-11-24 22:21:41.766730943 +0100 +@@ -332,3 +332,16 @@ + #define TARGET_NR_dup3 (TARGET_NR_Linux + 327) + #define TARGET_NR_pipe2 (TARGET_NR_Linux + 328) + #define TARGET_NR_inotify_init1 (TARGET_NR_Linux + 329) ++#define TARGET_NR_preadv (TARGET_NR_Linux + 330) ++#define TARGET_NR_pwritev (TARGET_NR_Linux + 331) ++#define TARGET_NR_rt_tgsigqueueinfo (TARGET_NR_Linux + 332) ++#define TARGET_NR_perf_event_open (TARGET_NR_Linux + 333) ++#define TARGET_NR_accept4 (TARGET_NR_Linux + 334) ++#define TARGET_NR_recvmmsg (TARGET_NR_Linux + 335) ++#define TARGET_NR_fanotify_init (TARGET_NR_Linux + 336) ++#define TARGET_NR_fanotify_mark (TARGET_NR_Linux + 337) ++#define TARGET_NR_prlimit64 (TARGET_NR_Linux + 338) ++#define TARGET_NR_name_to_handle_at (TARGET_NR_Linux + 339) ++#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 340) ++#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 341) ++#define TARGET_NR_syncfs (TARGET_NR_Linux + 342) +diff -uNr qemu-0.14.1.orig/linux-user/mips64/syscall_nr.h qemu-0.14.1/linux-user/mips64/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/mips64/syscall_nr.h 2011-11-24 22:21:09.627597287 +0100 ++++ qemu-0.14.1/linux-user/mips64/syscall_nr.h 2011-11-24 22:21:41.769045776 +0100 +@@ -291,3 +291,16 @@ + #define TARGET_NR_dup3 (TARGET_NR_Linux + 286) + #define TARGET_NR_pipe2 (TARGET_NR_Linux + 287) + #define TARGET_NR_inotify_init1 (TARGET_NR_Linux + 288) ++#define TARGET_NR_preadv (TARGET_NR_Linux + 289) ++#define TARGET_NR_pwritev (TARGET_NR_Linux + 290) ++#define TARGET_NR_rt_tgsigqueueinfo (TARGET_NR_Linux + 291) ++#define TARGET_NR_perf_event_open (TARGET_NR_Linux + 292) ++#define TARGET_NR_accept4 (TARGET_NR_Linux + 293) ++#define TARGET_NR_recvmmsg (TARGET_NR_Linux + 294) ++#define TARGET_NR_fanotify_init (TARGET_NR_Linux + 295) ++#define TARGET_NR_fanotify_mark (TARGET_NR_Linux + 296) ++#define TARGET_NR_prlimit64 (TARGET_NR_Linux + 297) ++#define TARGET_NR_name_to_handle_at (TARGET_NR_Linux + 298) ++#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 299) ++#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 300) ++#define TARGET_NR_syncfs (TARGET_NR_Linux + 301) +diff -uNr qemu-0.14.1.orig/linux-user/mipsn32/syscall_nr.h qemu-0.14.1/linux-user/mipsn32/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/mipsn32/syscall_nr.h 2011-11-24 22:21:09.634541784 +0100 ++++ qemu-0.14.1/linux-user/mipsn32/syscall_nr.h 2011-11-24 22:21:41.769045776 +0100 +@@ -295,3 +295,17 @@ + #define TARGET_NR_dup3 (TARGET_NR_Linux + 290) + #define TARGET_NR_pipe2 (TARGET_NR_Linux + 291) + #define TARGET_NR_inotify_init1 (TARGET_NR_Linux + 292) ++#define TARGET_NR_preadv (TARGET_NR_Linux + 293) ++#define TARGET_NR_pwritev (TARGET_NR_Linux + 294) ++#define TARGET_NR_rt_tgsigqueueinfo (TARGET_NR_Linux + 295) ++#define TARGET_NR_perf_event_open (TARGET_NR_Linux + 296) ++#define TARGET_NR_accept4 (TARGET_NR_Linux + 297) ++#define TARGET_NR_recvmmsg (TARGET_NR_Linux + 298) ++#define TARGET_NR_getdents64 (TARGET_NR_Linux + 299) ++#define TARGET_NR_fanotify_init (TARGET_NR_Linux + 300) ++#define TARGET_NR_fanotify_mark (TARGET_NR_Linux + 301) ++#define TARGET_NR_prlimit64 (TARGET_NR_Linux + 302) ++#define TARGET_NR_name_to_handle_at (TARGET_NR_Linux + 303) ++#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 304) ++#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 305) ++#define TARGET_NR_syncfs (TARGET_NR_Linux + 306) +diff -uNr qemu-0.14.1.orig/linux-user/ppc/syscall_nr.h qemu-0.14.1/linux-user/ppc/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/ppc/syscall_nr.h 2011-11-24 22:21:09.627597287 +0100 ++++ qemu-0.14.1/linux-user/ppc/syscall_nr.h 2011-11-24 22:21:41.769045776 +0100 +@@ -332,3 +332,33 @@ + #define TARGET_NR_dup3 316 + #define TARGET_NR_pipe2 317 + #define TARGET_NR_inotify_init1 318 ++#define TARGET_NR_perf_event_open 319 ++#define TARGET_NR_preadv 320 ++#define TARGET_NR_pwritev 321 ++#define TARGET_NR_rt_tgsigqueueinfo 322 ++#define TARGET_NR_fanotify_init 323 ++#define TARGET_NR_fanotify_mark 324 ++#define TARGET_NR_prlimit64 325 ++#define TARGET_NR_socket 326 ++#define TARGET_NR_bind 327 ++#define TARGET_NR_connect 328 ++#define TARGET_NR_listen 329 ++#define TARGET_NR_accept 330 ++#define TARGET_NR_getsockname 331 ++#define TARGET_NR_getpeername 332 ++#define TARGET_NR_socketpair 333 ++#define TARGET_NR_send 334 ++#define TARGET_NR_sendto 335 ++#define TARGET_NR_recv 336 ++#define TARGET_NR_recvfrom 337 ++#define TARGET_NR_shutdown 338 ++#define TARGET_NR_setsockopt 339 ++#define TARGET_NR_getsockopt 340 ++#define TARGET_NR_sendmsg 341 ++#define TARGET_NR_recvmsg 342 ++#define TARGET_NR_recvmmsg 343 ++#define TARGET_NR_accept4 344 ++#define TARGET_NR_name_to_handle_at 345 ++#define TARGET_NR_open_by_handle_at 346 ++#define TARGET_NR_clock_adjtime 347 ++#define TARGET_NR_syncfs 348 +diff -uNr qemu-0.14.1.orig/linux-user/sh4/syscall_nr.h qemu-0.14.1/linux-user/sh4/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/sh4/syscall_nr.h 2011-11-24 22:21:09.634541784 +0100 ++++ qemu-0.14.1/linux-user/sh4/syscall_nr.h 2011-11-24 22:21:41.769045776 +0100 +@@ -334,3 +334,35 @@ + #define TARGET_NR_dup3 330 + #define TARGET_NR_pipe2 331 + #define TARGET_NR_inotify_init1 332 ++#define TARGET_NR_preadv 333 ++#define TARGET_NR_pwritev 334 ++#define TARGET_NR_rt_tgsigqueueinfo 335 ++#define TARGET_NR_perf_event_open 336 ++#define TARGET_NR_fanotify_init 337 ++#define TARGET_NR_fanotify_mark 338 ++#define TARGET_NR_prlimit64 339 ++ ++/* Non-multiplexed socket family */ ++#define TARGET_NR_socket 340 ++#define TARGET_NR_bind 341 ++#define TARGET_NR_connect 342 ++#define TARGET_NR_listen 343 ++#define TARGET_NR_accept 344 ++#define TARGET_NR_getsockname 345 ++#define TARGET_NR_getpeername 346 ++#define TARGET_NR_socketpair 347 ++#define TARGET_NR_send 348 ++#define TARGET_NR_sendto 349 ++#define TARGET_NR_recv 350 ++#define TARGET_NR_recvfrom 351 ++#define TARGET_NR_shutdown 352 ++#define TARGET_NR_setsockopt 353 ++#define TARGET_NR_getsockopt 354 ++#define TARGET_NR_sendmsg 355 ++#define TARGET_NR_recvmsg 356 ++#define TARGET_NR_recvmmsg 357 ++#define TARGET_NR_accept4 358 ++#define TARGET_NR_name_to_handle_at 359 ++#define TARGET_NR_open_by_handle_at 360 ++#define TARGET_NR_clock_adjtime 361 ++#define TARGET_NR_syncfs 362 +diff -uNr qemu-0.14.1.orig/linux-user/sparc/syscall_nr.h qemu-0.14.1/linux-user/sparc/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/sparc/syscall_nr.h 2011-11-24 22:21:09.629912120 +0100 ++++ qemu-0.14.1/linux-user/sparc/syscall_nr.h 2011-11-24 22:21:41.769045776 +0100 +@@ -285,3 +285,15 @@ + #define TARGET_NR_pipe2 321 + #define TARGET_NR_inotify_init1 322 + #define TARGET_NR_accept4 323 ++#define TARGET_NR_preadv 324 ++#define TARGET_NR_pwritev 325 ++#define TARGET_NR_rt_tgsigqueueinfo 326 ++#define TARGET_NR_perf_event_open 327 ++#define TARGET_NR_recvmmsg 328 ++#define TARGET_NR_fanotify_init 329 ++#define TARGET_NR_fanotify_mark 330 ++#define TARGET_NR_prlimit64 331 ++#define TARGET_NR_name_to_handle_at 332 ++#define TARGET_NR_open_by_handle_at 333 ++#define TARGET_NR_clock_adjtime 334 ++#define TARGET_NR_syncfs 335 +diff -uNr qemu-0.14.1.orig/linux-user/sparc64/syscall_nr.h qemu-0.14.1/linux-user/sparc64/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/sparc64/syscall_nr.h 2011-11-24 22:21:09.632226952 +0100 ++++ qemu-0.14.1/linux-user/sparc64/syscall_nr.h 2011-11-24 22:21:41.771360608 +0100 +@@ -322,3 +322,15 @@ + #define TARGET_NR_pipe2 321 + #define TARGET_NR_inotify_init1 322 + #define TARGET_NR_accept4 323 ++#define TARGET_NR_preadv 324 ++#define TARGET_NR_pwritev 325 ++#define TARGET_NR_rt_tgsigqueueinfo 326 ++#define TARGET_NR_perf_event_open 327 ++#define TARGET_NR_recvmmsg 328 ++#define TARGET_NR_fanotify_init 329 ++#define TARGET_NR_fanotify_mark 330 ++#define TARGET_NR_prlimit64 331 ++#define TARGET_NR_name_to_handle_at 332 ++#define TARGET_NR_open_by_handle_at 333 ++#define TARGET_NR_clock_adjtime 334 ++#define TARGET_NR_syncfs 335 +diff -uNr qemu-0.14.1.orig/linux-user/x86_64/syscall_nr.h qemu-0.14.1/linux-user/x86_64/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/x86_64/syscall_nr.h 2011-11-24 22:21:09.625282454 +0100 ++++ qemu-0.14.1/linux-user/x86_64/syscall_nr.h 2011-11-24 22:21:41.771360608 +0100 +@@ -293,3 +293,15 @@ + #define TARGET_NR_dup3 292 + #define TARGET_NR_pipe2 293 + #define TARGET_NR_inotify_init1 294 ++#define TARGET_NR_preadv 295 ++#define TARGET_NR_pwritev 296 ++#define TARGET_NR_rt_tgsigqueueinfo 297 ++#define TARGET_NR_perf_event_open 298 ++#define TARGET_NR_recvmmsg 299 ++#define TARGET_NR_fanotify_init 300 ++#define TARGET_NR_fanotify_mark 301 ++#define TARGET_NR_prlimit64 302 ++#define TARGET_NR_name_to_handle_at 303 ++#define TARGET_NR_open_by_handle_at 304 ++#define TARGET_NR_clock_adjtime 305 ++#define TARGET_NR_syncfs 306 diff --git a/app-emulation/qemu-user/files/qemu-chroot.patch b/app-emulation/qemu-user/files/qemu-chroot.patch new file mode 100644 index 0000000..e89304f --- /dev/null +++ b/app-emulation/qemu-user/files/qemu-chroot.patch @@ -0,0 +1,46 @@ +diff --git a/linux-user/main.c b/linux-user/main.c +index 124b98c..b010fd2 100644 +--- a/linux-user/main.c ++++ b/linux-user/main.c +@@ -1905,6 +1905,10 @@ void usage(void) + "-cpu model select CPU (-cpu ? for list)\n" + "-drop-ld-preload drop LD_PRELOAD for target process\n" + "\n" ++ "Root options:\n" ++ "-chroot dir chroot to dir\n" ++ "-su uid:gid set numeric user and group IDs\n" ++ "\n" + "Debug options:\n" + "-d options activate log (logfile=%s)\n" + "-p pagesize set the host page size to 'pagesize'\n" +@@ -2011,6 +2015,28 @@ int main(int argc, char **argv) + drop_ld_preload = 1; + } else if (!strcmp(r, "strace")) { + do_strace = 1; ++ } else if (!strcmp(r, "chroot")) { ++ if (chdir(argv[optind++]) || chroot(".")) { ++ fprintf(stderr, "Can't chroot to '%s' (are you root?)\n", ++ argv[--optind]); ++ _exit(1); ++ } ++ } else if (!strcmp(r, "su")) { ++ int temp; ++ char *gid = strchr(argv[optind], ':'); ++ if (gid) { ++ temp = atoi(++gid); ++ if (setresgid(temp, temp, temp)) { ++ fprintf(stderr, "Can't set gid to %d (are you root?)\n", ++ temp); ++ _exit(1); ++ } ++ } ++ temp = atoi(argv[optind++]); ++ if (setresuid(temp, temp, temp)) { ++ fprintf(stderr, "Can't set uid to %d (are you root?)\n", temp); ++ _exit(1); ++ } + } else + { + usage(); + + diff --git a/app-emulation/qemu-user/files/qemu-user.initd b/app-emulation/qemu-user/files/qemu-user.initd new file mode 100644 index 0000000..51aa8d1 --- /dev/null +++ b/app-emulation/qemu-user/files/qemu-user.initd @@ -0,0 +1,137 @@ +#!/sbin/runscript +# Copyright 1999-2006 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +# enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390 program execution by the kernel + +depend() { + after procfs +} + +start() { + ebegin "Registering qemu-user binaries" + + if [[ ! -d /proc/sys/fs/binfmt_misc ]] ; then + eerror "You need support for \"misc binaries\" in your kernel!" + eend 1 + fi + + if [[ $(mount | grep -c binfmt_misc) -eq 0 ]] ; then + mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc &> /dev/null + local result=$? + + if [[ $result -ne 0 ]] ; then + eend $result + fi + fi + + # probe cpu type + cpu=`uname -m` + case "$cpu" in + i386|i486|i586|i686|i86pc|BePC|x86_64) + cpu="i386" + ;; + m68k) + cpu="m68k" + ;; + mips*) + cpu="mips" + ;; + "Power Macintosh"|ppc|ppc64) + cpu="ppc" + ;; + armv[4-9]*) + cpu="arm" + ;; + sparc*) + cpu="sparc" + ;; + esac + + # register the interpreter for each cpu except for the native one + if [ $cpu != "i386" ] ; then + echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386-binfmt:P' > /proc/sys/fs/binfmt_misc/register + echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "alpha" ] ; then + echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-alpha-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "arm" ] ; then + echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm-binfmt:P' > /proc/sys/fs/binfmt_misc/register + echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-armeb-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "sparc" ] ; then + echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sparc-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "ppc" ] ; then + echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "m68k" ] ; then + echo 'Please check cpu value and header information for m68k!' + echo ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-m68k-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "mips" ] ; then + # FIXME: We could use the other endianness on a MIPS host. + echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips-binfmt:P' > /proc/sys/fs/binfmt_misc/register + echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsel-binfmt:P' > /proc/sys/fs/binfmt_misc/register + echo ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mipsn32-binfmt:P' > /proc/sys/fs/binfmt_misc/register + echo ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsn32el-binfmt:P' > /proc/sys/fs/binfmt_misc/register + echo ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips64-binfmt:P' > /proc/sys/fs/binfmt_misc/register + echo ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mips64el-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "sh" ] ; then + echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-sh4-binfmt:P' > /proc/sys/fs/binfmt_misc/register + echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "s390x" ] ; then + echo ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-s390x-binfmt:P' > /proc/sys/fs/binfmt_misc/register + fi + eend $? +} + +stop() { + ebegin "Unregistering qemu-user binaries" + + if [[ -f /proc/sys/fs/binfmt_misc/i386 ]] ; then + echo '-1' > /proc/sys/fs/binfmt_misc/i386 + echo '-1' > /proc/sys/fs/binfmt_misc/i486 + fi + if [[ -f /proc/sys/fs/binfmt_misc/alpha ]] ; then + echo '-1' > /proc/sys/fs/binfmt_misc/alpha + fi + if [[ -f /proc/sys/fs/binfmt_misc/arm ]] ; then + echo '-1' > /proc/sys/fs/binfmt_misc/arm + echo '-1' > /proc/sys/fs/binfmt_misc/armeb + fi + if [[ -f /proc/sys/fs/binfmt_misc/sparc ]] ; then + echo '-1' > /proc/sys/fs/binfmt_misc/sparc + fi + if [[ -f /proc/sys/fs/binfmt_misc/ppc ]] ; then + echo '-1' > /proc/sys/fs/binfmt_misc/ppc + fi + if [[ -f /proc/sys/fs/binfmt_misc/m68k ]] ; then + echo '-1' > /proc/sys/fs/binfmt_misc/m68k + fi + if [[ -f /proc/sys/fs/binfmt_misc/misp ]] ; then + echo '-1' > /proc/sys/fs/binfmt_misc/mips + echo '-1' > /proc/sys/fs/binfmt_misc/mipsel + echo '-1' > /proc/sys/fs/binfmt_misc/mipsn32 + echo '-1' > /proc/sys/fs/binfmt_misc/mipsn32el + echo '-1' > /proc/sys/fs/binfmt_misc/mips64 + echo '-1' > /proc/sys/fs/binfmt_misc/mips64el + fi + if [[ -f /proc/sys/fs/binfmt_misc/sh4 ]] ; then + echo '-1' > /proc/sys/fs/binfmt_misc/sh4 + echo '-1' > /proc/sys/fs/binfmt_misc/sh4eb + fi + if [[ -f /proc/sys/fs/binfmt_misc/s390x ]] ; then + echo '-1' > /proc/sys/fs/binfmt_misc/s390x + fi + + eend $? +} + +# vim: ts=4 : + + diff --git a/app-emulation/qemu-user/metadata.xml b/app-emulation/qemu-user/metadata.xml new file mode 100644 index 0000000..2f3b630 --- /dev/null +++ b/app-emulation/qemu-user/metadata.xml @@ -0,0 +1,7 @@ + + + + + lu_zero@gentoo.org + + diff --git a/app-emulation/qemu-user/qemu-user-0.14.1.ebuild b/app-emulation/qemu-user/qemu-user-0.14.1.ebuild new file mode 100644 index 0000000..8ab26e8 --- /dev/null +++ b/app-emulation/qemu-user/qemu-user-0.14.1.ebuild @@ -0,0 +1,71 @@ +# Copyright 1999-2010 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/app-emulation/qemu-user/qemu-user-0.12.2.ebuild,v 1.1 2010/02/14 23:53:40 solar Exp $ + +inherit eutils flag-o-matic pax-utils toolchain-funcs + +MY_PN=${PN/-user/} +MY_P=${P/-user/} + +SRC_URI="http://savannah.nongnu.org/download/${MY_PN}/${MY_P}.tar.gz" + +DESCRIPTION="Open source dynamic translator" +HOMEPAGE="http://bellard.org/qemu/index.html" + +LICENSE="GPL-2 LGPL-2.1" +SLOT="0" +KEYWORDS="~amd64 ~ppc ~x86 ~ppc64" +IUSE="static" +RESTRICT="test" + +DEPEND="app-text/texi2html + !<=app-emulation/qemu-0.7.0" +RDEPEND="" + +S="${WORKDIR}/${MY_P}" + +src_unpack() { + unpack ${A} + + cd "${S}" + # prevent docs to get automatically installed + sed -i '/$(DESTDIR)$(docdir)/d' Makefile + # Alter target makefiles to accept CFLAGS set via flag-o + sed -i 's/^\(C\|OP_C\|HELPER_C\)FLAGS=/\1FLAGS+=/' \ + Makefile Makefile.target + EPATCH_SOURCE="${FILESDIR}/${PV}" EPATCH_SUFFIX="patch" \ + EPATCH_FORCE="yes" epatch + epatch "${FILESDIR}/qemu-chroot.patch" +} + +src_compile() { + local conf_opts + + conf_opts="--enable-linux-user --disable-strip" + conf_opts+=" --disable-darwin-user --disable-bsd-user" + conf_opts+=" --disable-system" + conf_opts+=" --disable-vnc-tls" + conf_opts+=" --disable-curses" + conf_opts+=" --disable-sdl" + conf_opts+=" --disable-vde" + conf_opts+=" --prefix=/usr --disable-bluez --disable-kvm" + conf_opts+=" --cc=$(tc-getCC) --host-cc=$(tc-getBUILD_CC)" + conf_opts+=" --extra-ldflags=-Wl,-z,execheap" + use static && conf_opts+=" --static" + + filter-flags -fpie -fstack-protector + + ./configure ${conf_opts} || die "econf failed" + + emake || die "emake qemu failed" + +} + +src_install() { + emake DESTDIR="${D}" install || die "make install failed" + pax-mark r "${D}"/usr/bin/qemu-* + rm -fR "${D}/usr/share" + dohtml qemu-doc.html + dohtml qemu-tech.html + newinitd "${FILESDIR}/qemu-user.initd" qemu-user +} diff --git a/app-emulation/qemu/Manifest b/app-emulation/qemu/Manifest index 9f8a45e..064fd45 100644 --- a/app-emulation/qemu/Manifest +++ b/app-emulation/qemu/Manifest @@ -65,8 +65,7 @@ AUX 0.14.1/0020-linux-user-implement-reboot-syscall.patch 1403 RMD160 456a111c96 AUX 0.14.1/0021-implement-prlimit64-syscall.patch 4175 RMD160 c31cd2e670c0fe3a8b2df462b1fb4b1e7c55cb9b SHA1 1bf72cfe09bb4bfb5101cd96fdade15bfe538926 SHA256 79d7e395b46430775f8f82b19890d2f73681d9fdfac46b807b3d148e83facf91 AUX 0.14.1/0022-fixing-smp-races.patch 1224 RMD160 bcb627e31d677dd787c252d40da3faf45742e4bf SHA1 0b92b6b92eb8ebe92b465e0c5266ef74cf52e917 SHA256 cbb12a0cee1a123fc209b563968ee0c8b2111727adbf8b00644a24f23fbbce15 AUX 0.14.1/0023-linux-user-add-binfmt-wrapper-for-argv-0-handling.patch 11904 RMD160 0165cdaf6a7307838993285f95c228d005ade149 SHA1 04d8c700314decb3759d530c27b5ba72d8c1c4d9 SHA256 cc2340c63ec2a216bc5d460d7419bf84f3869015fcfd73096530b43ce357ab45 -AUX 0.14.1/0024-fix-glibc-install-locales.patch 17811 RMD160 563366d547aeec28faf2602c48c09eaafbb44381 SHA1 ac8585ee6b334969fb79a6fd4844e8a415b6c717 SHA256 2a18ba91c190dc457fe1683af23d9b7814eee1ed5ba44362187756706d26c99c -AUX 0.14.1/0025-add-syscall-numbers-from-2.6.39.2.patch 17282 RMD160 8d5ff85efb34788680125a878495d86ec8c6f0d6 SHA1 7ee7fa50a7b7e862bff0c0221080349bc03d710f SHA256 c61c5fc6e9e849bb14548e5f80ec5abcf52c92b78d9c079a359d9d4b0cb55f1d +AUX 0.14.1/0025-add-syscall-numbers-from-2.6.39.2.patch 18328 RMD160 61a90462ad0109f2951d4ebb540c716861905220 SHA1 99834573cdc443c4118b6280c5e26433caa95624 SHA256 5aed07e1b71643d880eaa7432dfb99cc08958d275985d23b779cb796f1a73b18 AUX qemu-0.10.3-nopl-fix.patch 1118 RMD160 849e4b88ca7985dc3faae0a225181205043f0265 SHA1 70cf0727a7cbdd79243ae6768f34c07c6e9c5aec SHA256 24656137f1f38aed2c2661ebd20d9a6d86eaf9768c3e239b971f01418b396028 AUX qemu-0.11.0-mips64-user-fix.patch 313 RMD160 db016e0a48990a435dd6cf6e807145b33ada4908 SHA1 2ea913b1bcd29734a6d4011794bdb4aa3599a184 SHA256 b4173fc177bd0d0ba67f5551a3512047a19a9b2c0a122f968e32fbd834848d2f AUX qemu-arm-eabi-0.10.5.patch 21422 RMD160 a2ab6384938b08764324a4239fc30718161a3977 SHA1 2c7cec113b02e9f91226887257b393a3dfba2234 SHA256 b47327d7eab124617941e5403c5d4d0af2b21ce2278d5524677c521be462aa57 @@ -76,8 +75,10 @@ AUX qemu-ifup 554 RMD160 9769d79ab6456bdd7e3e689005f629e2a67b858d SHA1 dde2b27ac DIST qemu-0.10.6.tar.gz 3664559 RMD160 1321a10777d2e0c6b53887d0525a28cc1b36ec9b SHA1 9432738ba513e07c981097468945b2e3ad9cb81e SHA256 8725298d4fd937ae41d942d0dd4a22fc02561d8c57a9fdcdbfa56427915757c7 DIST qemu-0.11.1.tar.gz 3830070 RMD160 4da00fa6c01d7ff6af0ee781bc9260da577ea7d3 SHA1 7b983cd18f44c6e7627532b662f010389d3bcdff SHA256 2ecd2fc0af2ce5d96067ae82cc98a08275c596de53fc929484bedee1d6e7893a DIST qemu-0.12.5.tar.gz 4291741 RMD160 c4eba2e649b428e8dd432718443e986057e692d7 SHA1 596a673f3a6697ea8fd90f4f23981241cc13bdc3 SHA256 a6a7b30b53591e160b5c7fd9319985673174e9ea47b182dbe63bc99357741f58 +DIST qemu-0.14.1.tar.gz 5439697 RMD160 0601ff4e613fea0a6ce80907e2bfa11704048b36 SHA1 1a5003a03004b62b52562d1cbb8f50c5f135e0b8 SHA256 33ceae3fbe516f2cbb151dc98d16c8ccfec74b1056674ad715e75a2f7fed45c3 EBUILD qemu-0.10.6.ebuild 5000 RMD160 093eeeda7f4872bddeb83688daba67623eb26d01 SHA1 e5c5abf287914b222483cb32853bbcd658fa8fb6 SHA256 117e429849e1f55c17dd76837cb11c974ffccc19eba1b6ae5f33996a18c463c7 EBUILD qemu-0.11.1.ebuild 5090 RMD160 9889a49d89c968b9710a159004c0467a82e711f7 SHA1 f3389454f0508c9c9b903d35b2472d429a85a954 SHA256 6963ebb2f42ef4bee899e5c9554eb4b91de11e798c4f632111ae9b6850d801da EBUILD qemu-0.12.5.ebuild 5128 RMD160 7f1ca4fe533772771d753fdb45565cc62b1e1031 SHA1 bb9960710ea99fb224a5381aec95d11f0b3a4f8c SHA256 b097d506303e4856cb5819642f113162a17644fbc46ae3c483ed1b4fb297b632 +EBUILD qemu-0.14.1.ebuild 6140 RMD160 19c6177eddfbc169a6d185cd5f2cc6694919fa0e SHA1 406288d3fd6d19987b844354f9ce5dfe95c5f60d SHA256 4493e9517e939665d3f926edca6c1dc7ef3dbdf097537ccfca72eb0456cf621e MISC ChangeLog 11259 RMD160 6e119249ab4ffddf3dc6ef8da9fce0949fc91ad2 SHA1 0914e40152b37c48c175db6b9079eb7990814237 SHA256 db076339aadcd5266d3998d3314a1e1fb54cea58457f5c43cea5a40f3fe4999c MISC metadata.xml 910 RMD160 da1d7ba61d401bb22fc22be931b27be432d6d103 SHA1 6ffb7c25e19589933bd016d80a16284ae8df436c SHA256 6a27d48cbcc5a90f1464e302252ea10813317ddcb7bdd2e1e5cb927760a5640d diff --git a/app-emulation/qemu/files/0.14.1/0024-fix-glibc-install-locales.patch b/app-emulation/qemu/files/0.14.1/0024-fix-glibc-install-locales.patch deleted file mode 100644 index 9c70a8b..0000000 --- a/app-emulation/qemu/files/0.14.1/0024-fix-glibc-install-locales.patch +++ /dev/null @@ -1,460 +0,0 @@ -From bf858897b76926b56e948dbe7a1a491b68dccda7 Mon Sep 17 00:00:00 2001 -From: Richard Henderson -Date: Tue, 27 Jul 2010 17:25:38 +0000 -Subject: linux-user: Re-use load_elf_image for the main binary. - -This requires moving the PT_INTERP extraction and GUEST_BASE -handling into load_elf_image. Key this off a non-null pointer -argument to receive the interpreter name. - -Signed-off-by: Richard Henderson -Signed-off-by: Edgar E. Iglesias ---- -diff --git a/linux-user/elfload.c b/linux-user/elfload.c -index 0a3d084..a53285a 100644 ---- a/linux-user/elfload.c -+++ b/linux-user/elfload.c -@@ -829,9 +829,6 @@ struct exec - #define ZMAGIC 0413 - #define QMAGIC 0314 - --/* max code+data+bss+brk space allocated to ET_DYN executables */ --#define ET_DYN_MAP_SIZE (128 * 1024 * 1024) -- - /* Necessary parameters */ - #define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE - #define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1)) -@@ -1169,7 +1166,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, - On return: INFO values will be filled in, as necessary or available. */ - - static void load_elf_image(const char *image_name, int image_fd, -- struct image_info *info, -+ struct image_info *info, char **pinterp_name, - char bprm_buf[BPRM_BUF_SIZE]) - { - struct elfhdr *ehdr = (struct elfhdr *)bprm_buf; -@@ -1229,6 +1226,67 @@ static void load_elf_image(const char *image_name, int image_fd, - if (load_addr == -1) { - goto exit_perror; - } -+ } else if (pinterp_name != NULL) { -+ /* This is the main executable. Make sure that the low -+ address does not conflict with MMAP_MIN_ADDR or the -+ QEMU application itself. */ -+#if defined(CONFIG_USE_GUEST_BASE) -+ /* -+ * In case where user has not explicitly set the guest_base, we -+ * probe here that should we set it automatically. -+ */ -+ if (!have_guest_base && !reserved_va) { -+ unsigned long host_start, real_start, host_size; -+ -+ /* Round addresses to page boundaries. */ -+ loaddr &= qemu_host_page_mask; -+ hiaddr = HOST_PAGE_ALIGN(hiaddr); -+ -+ if (loaddr < mmap_min_addr) { -+ host_start = HOST_PAGE_ALIGN(mmap_min_addr); -+ } else { -+ host_start = loaddr; -+ if (host_start != loaddr) { -+ errmsg = "Address overflow loading ELF binary"; -+ goto exit_errmsg; -+ } -+ } -+ host_size = hiaddr - loaddr; -+ while (1) { -+ /* Do not use mmap_find_vma here because that is limited to the -+ guest address space. We are going to make the -+ guest address space fit whatever we're given. */ -+ real_start = (unsigned long) -+ mmap((void *)host_start, host_size, PROT_NONE, -+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0); -+ if (real_start == (unsigned long)-1) { -+ goto exit_perror; -+ } -+ if (real_start == host_start) { -+ break; -+ } -+ /* That address didn't work. Unmap and try a different one. -+ The address the host picked because is typically right at -+ the top of the host address space and leaves the guest with -+ no usable address space. Resort to a linear search. We -+ already compensated for mmap_min_addr, so this should not -+ happen often. Probably means we got unlucky and host -+ address space randomization put a shared library somewhere -+ inconvenient. */ -+ munmap((void *)real_start, host_size); -+ host_start += qemu_host_page_size; -+ if (host_start == loaddr) { -+ /* Theoretically possible if host doesn't have any suitably -+ aligned areas. Normally the first mmap will fail. */ -+ errmsg = "Unable to find space for application"; -+ goto exit_errmsg; -+ } -+ } -+ qemu_log("Relocating guest address space from 0x" -+ TARGET_ABI_FMT_lx " to 0x%lx\n", loaddr, real_start); -+ guest_base = real_start - loaddr; -+ } -+#endif - } - load_bias = load_addr - loaddr; - -@@ -1290,6 +1348,33 @@ static void load_elf_image(const char *image_name, int image_fd, - info->brk = vaddr_em; - } - } -+ } else if (eppnt->p_type == PT_INTERP && pinterp_name) { -+ char *interp_name; -+ -+ if (*pinterp_name) { -+ errmsg = "Multiple PT_INTERP entries"; -+ goto exit_errmsg; -+ } -+ interp_name = malloc(eppnt->p_filesz); -+ if (!interp_name) { -+ goto exit_perror; -+ } -+ -+ if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) { -+ memcpy(interp_name, bprm_buf + eppnt->p_offset, -+ eppnt->p_filesz); -+ } else { -+ retval = pread(image_fd, interp_name, eppnt->p_filesz, -+ eppnt->p_offset); -+ if (retval != eppnt->p_filesz) { -+ goto exit_perror; -+ } -+ } -+ if (interp_name[eppnt->p_filesz - 1] != 0) { -+ errmsg = "Invalid PT_INTERP entry"; -+ goto exit_errmsg; -+ } -+ *pinterp_name = interp_name; - } - } - -@@ -1336,7 +1421,7 @@ static void load_elf_interp(const char *filename, struct image_info *info, - memset(bprm_buf + retval, 0, BPRM_BUF_SIZE - retval); - } - -- load_elf_image(filename, fd, info, bprm_buf); -+ load_elf_image(filename, fd, info, NULL, bprm_buf); - return; - - exit_perror: -@@ -1480,291 +1565,31 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - { - struct image_info interp_info; - struct elfhdr elf_ex; -- abi_ulong load_addr, load_bias; -- int load_addr_set = 0; -- int i; -- struct elf_phdr * elf_ppnt; -- struct elf_phdr *elf_phdata; -- abi_ulong k, elf_brk; -- int retval; - char *elf_interpreter = NULL; -- abi_ulong elf_entry; -- int status; -- abi_ulong start_code, end_code, start_data, end_data; -- abi_ulong elf_stack; - -- status = 0; -- load_addr = 0; -- load_bias = 0; -- elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */ -+ info->start_mmap = (abi_ulong)ELF_START_MMAP; -+ info->mmap = 0; -+ info->rss = 0; - -- /* First of all, some simple consistency checks */ -- if (!elf_check_ident(&elf_ex)) { -- return -ENOEXEC; -- } -- bswap_ehdr(&elf_ex); -- if (!elf_check_ehdr(&elf_ex)) { -- return -ENOEXEC; -- } -+ load_elf_image(bprm->filename, bprm->fd, info, -+ &elf_interpreter, bprm->buf); -+ -+ /* ??? We need a copy of the elf header for passing to create_elf_tables. -+ If we do nothing, we'll have overwritten this when we re-use bprm->buf -+ when we load the interpreter. */ -+ elf_ex = *(struct elfhdr *)bprm->buf; - - bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p); - bprm->p = copy_elf_strings(bprm->envc,bprm->envp,bprm->page,bprm->p); - bprm->p = copy_elf_strings(bprm->argc,bprm->argv,bprm->page,bprm->p); - if (!bprm->p) { -- retval = -E2BIG; -- } -- -- /* Now read in all of the header information */ -- elf_phdata = (struct elf_phdr *) -- malloc(elf_ex.e_phnum * sizeof(struct elf_phdr)); -- if (elf_phdata == NULL) { -- return -ENOMEM; -- } -- -- i = elf_ex.e_phnum * sizeof(struct elf_phdr); -- if (elf_ex.e_phoff + i <= BPRM_BUF_SIZE) { -- memcpy(elf_phdata, bprm->buf + elf_ex.e_phoff, i); -- } else { -- retval = pread(bprm->fd, (char *) elf_phdata, i, elf_ex.e_phoff); -- if (retval != i) { -- perror("load_elf_binary"); -- exit(-1); -- } -- } -- bswap_phdr(elf_phdata, elf_ex.e_phnum); -- -- elf_brk = 0; -- elf_stack = ~((abi_ulong)0UL); -- start_code = ~((abi_ulong)0UL); -- end_code = 0; -- start_data = 0; -- end_data = 0; -- -- elf_ppnt = elf_phdata; -- for(i=0;i < elf_ex.e_phnum; i++) { -- if (elf_ppnt->p_type == PT_INTERP) { -- if (elf_ppnt->p_offset + elf_ppnt->p_filesz <= BPRM_BUF_SIZE) { -- elf_interpreter = bprm->buf + elf_ppnt->p_offset; -- } else { -- elf_interpreter = alloca(elf_ppnt->p_filesz); -- retval = pread(bprm->fd, elf_interpreter, elf_ppnt->p_filesz, -- elf_ppnt->p_offset); -- if (retval != elf_ppnt->p_filesz) { -- perror("load_elf_binary"); -- exit(-1); -- } -- } -- } -- elf_ppnt++; -- } -- -- /* OK, This is the point of no return */ -- info->end_data = 0; -- info->end_code = 0; -- info->start_mmap = (abi_ulong)ELF_START_MMAP; -- info->mmap = 0; -- elf_entry = (abi_ulong) elf_ex.e_entry; -- --#if defined(CONFIG_USE_GUEST_BASE) -- /* -- * In case where user has not explicitly set the guest_base, we -- * probe here that should we set it automatically. -- */ -- if (!(have_guest_base || reserved_va)) { -- /* -- * Go through ELF program header table and find the address -- * range used by loadable segments. Check that this is available on -- * the host, and if not find a suitable value for guest_base. */ -- abi_ulong app_start = ~0; -- abi_ulong app_end = 0; -- abi_ulong addr; -- unsigned long host_start; -- unsigned long real_start; -- unsigned long host_size; -- for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; -- i++, elf_ppnt++) { -- if (elf_ppnt->p_type != PT_LOAD) -- continue; -- addr = elf_ppnt->p_vaddr; -- if (addr < app_start) { -- app_start = addr; -- } -- addr += elf_ppnt->p_memsz; -- if (addr > app_end) { -- app_end = addr; -- } -- } -- -- /* If we don't have any loadable segments then something -- is very wrong. */ -- assert(app_start < app_end); -- -- /* Round addresses to page boundaries. */ -- app_start = app_start & qemu_host_page_mask; -- app_end = HOST_PAGE_ALIGN(app_end); -- if (app_start < mmap_min_addr) { -- host_start = HOST_PAGE_ALIGN(mmap_min_addr); -- } else { -- host_start = app_start; -- if (host_start != app_start) { -- fprintf(stderr, "qemu: Address overflow loading ELF binary\n"); -- abort(); -- } -- } -- host_size = app_end - app_start; -- while (1) { -- /* Do not use mmap_find_vma here because that is limited to the -- guest address space. We are going to make the -- guest address space fit whatever we're given. */ -- real_start = (unsigned long)mmap((void *)host_start, host_size, -- PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0); -- if (real_start == (unsigned long)-1) { -- fprintf(stderr, "qemu: Virtual memory exausted\n"); -- abort(); -- } -- if (real_start == host_start) { -- break; -- } -- /* That address didn't work. Unmap and try a different one. -- The address the host picked because is typically -- right at the top of the host address space and leaves the -- guest with no usable address space. Resort to a linear search. -- We already compensated for mmap_min_addr, so this should not -- happen often. Probably means we got unlucky and host address -- space randomization put a shared library somewhere -- inconvenient. */ -- munmap((void *)real_start, host_size); -- host_start += qemu_host_page_size; -- if (host_start == app_start) { -- /* Theoretically possible if host doesn't have any -- suitably aligned areas. Normally the first mmap will -- fail. */ -- fprintf(stderr, "qemu: Unable to find space for application\n"); -- abort(); -- } -- } -- qemu_log("Relocating guest address space from 0x" TARGET_ABI_FMT_lx -- " to 0x%lx\n", app_start, real_start); -- guest_base = real_start - app_start; -+ fprintf(stderr, "%s: %s\n", bprm->filename, strerror(E2BIG)); -+ exit(-1); - } --#endif /* CONFIG_USE_GUEST_BASE */ - - /* Do this so that we can load the interpreter, if need be. We will - change some of these later */ -- info->rss = 0; - bprm->p = setup_arg_pages(bprm->p, bprm, info); -- info->start_stack = bprm->p; -- -- /* Now we do a little grungy work by mmaping the ELF image into -- * the correct location in memory. At this point, we assume that -- * the image should be loaded at fixed address, not at a variable -- * address. -- */ -- -- for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) { -- int elf_prot = 0; -- int elf_flags = 0; -- abi_ulong error; -- -- if (elf_ppnt->p_type != PT_LOAD) -- continue; -- -- if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ; -- if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; -- if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC; -- elf_flags = MAP_PRIVATE | MAP_DENYWRITE; -- if (elf_ex.e_type == ET_EXEC || load_addr_set) { -- elf_flags |= MAP_FIXED; -- } else if (elf_ex.e_type == ET_DYN) { -- /* Try and get dynamic programs out of the way of the default mmap -- base, as well as whatever program they might try to exec. This -- is because the brk will follow the loader, and is not movable. */ -- /* NOTE: for qemu, we do a big mmap to get enough space -- without hardcoding any address */ -- error = target_mmap(0, ET_DYN_MAP_SIZE, -- PROT_NONE, MAP_PRIVATE | MAP_ANON, -- -1, 0); -- if (error == -1) { -- perror("mmap"); -- exit(-1); -- } -- load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr); -- } -- -- error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr), -- (elf_ppnt->p_filesz + -- TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)), -- elf_prot, -- (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE), -- bprm->fd, -- (elf_ppnt->p_offset - -- TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr))); -- if (error == -1) { -- perror("mmap"); -- exit(-1); -- } -- --#ifdef LOW_ELF_STACK -- if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack) -- elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr); --#endif -- -- if (!load_addr_set) { -- load_addr_set = 1; -- load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset; -- if (elf_ex.e_type == ET_DYN) { -- load_bias += error - -- TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr); -- load_addr += load_bias; -- } -- } -- k = elf_ppnt->p_vaddr; -- if (k < start_code) -- start_code = k; -- if (start_data < k) -- start_data = k; -- k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz; -- if ((elf_ppnt->p_flags & PF_X) && end_code < k) -- end_code = k; -- if (end_data < k) -- end_data = k; -- k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz; -- if (k > elf_brk) { -- elf_brk = TARGET_PAGE_ALIGN(k); -- } -- -- /* If the load segment requests extra zeros (e.g. bss), map it. */ -- if (elf_ppnt->p_filesz < elf_ppnt->p_memsz) { -- abi_ulong base = load_bias + elf_ppnt->p_vaddr; -- zero_bss(base + elf_ppnt->p_filesz, -- base + elf_ppnt->p_memsz, elf_prot); -- } -- } -- -- elf_entry += load_bias; -- elf_brk += load_bias; -- start_code += load_bias; -- end_code += load_bias; -- start_data += load_bias; -- end_data += load_bias; -- -- info->load_bias = load_bias; -- info->load_addr = load_addr; -- info->entry = elf_entry; -- info->start_brk = info->brk = elf_brk; -- info->end_code = end_code; -- info->start_code = start_code; -- info->start_data = start_data; -- info->end_data = end_data; -- info->personality = PER_LINUX; -- -- free(elf_phdata); -- -- if (qemu_log_enabled()) { -- load_symbols(&elf_ex, bprm->fd, load_bias); -- } -- -- close(bprm->fd); - - if (elf_interpreter) { - load_elf_interp(elf_interpreter, &interp_info, bprm->buf); -@@ -1796,6 +1621,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - if (elf_interpreter) { - info->load_addr = interp_info.load_addr; - info->entry = interp_info.entry; -+ free(elf_interpreter); - } - - #ifdef USE_ELF_CORE_DUMP --- -cgit v0.8.3.4 diff --git a/app-emulation/qemu/files/0.14.1/0025-add-syscall-numbers-from-2.6.39.2.patch b/app-emulation/qemu/files/0.14.1/0025-add-syscall-numbers-from-2.6.39.2.patch index 80f248d..0d9cf6e 100644 --- a/app-emulation/qemu/files/0.14.1/0025-add-syscall-numbers-from-2.6.39.2.patch +++ b/app-emulation/qemu/files/0.14.1/0025-add-syscall-numbers-from-2.6.39.2.patch @@ -1,22 +1,7 @@ -Removed s390x pieces. - -commit d979e8eb544da31df78bc76358a73f0d1c823c17 -Author: Peter Maydell -Date: Mon Jun 27 17:44:51 2011 +0100 - - linux-user: Add syscall numbers from kernel 2.6.39.2 - - Add syscall numbers for new syscall numbers; this brings us - into line with Linux 2.6.39.2. - - Signed-off-by: Peter Maydell - Signed-off-by: Riku Voipio - -diff --git a/linux-user/alpha/syscall_nr.h b/linux-user/alpha/syscall_nr.h -index e3127df..f6284db 100644 ---- a/linux-user/alpha/syscall_nr.h -+++ b/linux-user/alpha/syscall_nr.h -@@ -411,4 +411,25 @@ +diff -uNr qemu-0.14.1.orig/linux-user/alpha/syscall_nr.h qemu-0.14.1/linux-user/alpha/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/alpha/syscall_nr.h 2011-11-24 22:21:09.636856616 +0100 ++++ qemu-0.14.1/linux-user/alpha/syscall_nr.h 2011-11-24 22:22:04.528478368 +0100 +@@ -411,7 +411,28 @@ #define TARGET_NR_signalfd 476 #define TARGET_NR_timerfd 477 #define TARGET_NR_eventfd 478 @@ -43,10 +28,12 @@ index e3127df..f6284db 100644 +#define TARGET_NR_open_by_handle_at 498 +#define TARGET_NR_clock_adjtime 499 +#define TARGET_NR_syncfs 500 -diff --git a/linux-user/arm/syscall_nr.h b/linux-user/arm/syscall_nr.h -index 79a216a..7f05879 100644 ---- a/linux-user/arm/syscall_nr.h -+++ b/linux-user/arm/syscall_nr.h + /* The following aliases are defined in order to match up with the + standard i386 syscalls implemented in syscalls.c. */ + #define TARGET_NR_chown32 TARGET_NR_chown +diff -uNr qemu-0.14.1.orig/linux-user/arm/syscall_nr.h qemu-0.14.1/linux-user/arm/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/arm/syscall_nr.h 2011-11-24 22:21:09.627597287 +0100 ++++ qemu-0.14.1/linux-user/arm/syscall_nr.h 2011-11-24 22:21:41.762101277 +0100 @@ -365,3 +365,16 @@ #define TARGET_NR_dup3 (358) #define TARGET_NR_pipe2 (359) @@ -64,20 +51,18 @@ index 79a216a..7f05879 100644 +#define TARGET_NR_open_by_handle_at (371) +#define TARGET_NR_clock_adjtime (372) +#define TARGET_NR_syncfs (373) -diff --git a/linux-user/cris/syscall_nr.h b/linux-user/cris/syscall_nr.h -index 6132817..98f1a0b 100644 ---- a/linux-user/cris/syscall_nr.h -+++ b/linux-user/cris/syscall_nr.h +diff -uNr qemu-0.14.1.orig/linux-user/cris/syscall_nr.h qemu-0.14.1/linux-user/cris/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/cris/syscall_nr.h 2011-11-24 22:21:09.625282454 +0100 ++++ qemu-0.14.1/linux-user/cris/syscall_nr.h 2011-11-24 22:21:41.762101277 +0100 @@ -333,3 +333,5 @@ #define TARGET_NR_dup3 330 #define TARGET_NR_pipe2 331 #define TARGET_NR_inotify_init1 332 +#define TARGET_NR_preadv 333 +#define TARGET_NR_pwritev 334 -diff --git a/linux-user/i386/syscall_nr.h b/linux-user/i386/syscall_nr.h -index 3ef71ce..74abfca 100644 ---- a/linux-user/i386/syscall_nr.h -+++ b/linux-user/i386/syscall_nr.h +diff -uNr qemu-0.14.1.orig/linux-user/i386/syscall_nr.h qemu-0.14.1/linux-user/i386/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/i386/syscall_nr.h 2011-11-24 22:21:09.632226952 +0100 ++++ qemu-0.14.1/linux-user/i386/syscall_nr.h 2011-11-24 22:21:41.764416110 +0100 @@ -335,3 +335,15 @@ #define TARGET_NR_dup3 330 #define TARGET_NR_pipe2 331 @@ -94,10 +79,9 @@ index 3ef71ce..74abfca 100644 +#define TARGET_NR_open_by_handle_at 342 +#define TARGET_NR_clock_adjtime 343 +#define TARGET_NR_syncfs 344 -diff --git a/linux-user/m68k/syscall_nr.h b/linux-user/m68k/syscall_nr.h -index 1c0ba07..4d0937e 100644 ---- a/linux-user/m68k/syscall_nr.h -+++ b/linux-user/m68k/syscall_nr.h +diff -uNr qemu-0.14.1.orig/linux-user/m68k/syscall_nr.h qemu-0.14.1/linux-user/m68k/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/m68k/syscall_nr.h 2011-11-24 22:21:09.629912120 +0100 ++++ qemu-0.14.1/linux-user/m68k/syscall_nr.h 2011-11-24 22:21:41.764416110 +0100 @@ -328,3 +328,19 @@ #define TARGET_NR_dup3 326 #define TARGET_NR_pipe2 327 @@ -118,11 +102,10 @@ index 1c0ba07..4d0937e 100644 +#define TARGET_NR_open_by_handle_at 341 +#define TARGET_NR_clock_adjtime 342 +#define TARGET_NR_syncfs 343 -diff --git a/linux-user/main.c b/linux-user/main.c -index 289054b..48f0443 100644 ---- a/linux-user/main.c -+++ b/linux-user/main.c -@@ -1985,6 +1985,33 @@ static const uint8_t mips_syscall_args[] = { +diff -uNr qemu-0.14.1.orig/linux-user/main.c qemu-0.14.1/linux-user/main.c +--- qemu-0.14.1.orig/linux-user/main.c 2011-11-24 22:21:09.632226952 +0100 ++++ qemu-0.14.1/linux-user/main.c 2011-11-24 22:21:41.766730943 +0100 +@@ -1922,6 +1922,33 @@ MIPS_SYS(sys_epoll_pwait, 6) MIPS_SYS(sys_ioprio_set, 3) MIPS_SYS(sys_ioprio_get, 2) @@ -156,10 +139,9 @@ index 289054b..48f0443 100644 }; #undef MIPS_SYS -diff --git a/linux-user/microblaze/syscall_nr.h b/linux-user/microblaze/syscall_nr.h -index 3e641cd..f1fe0e7 100644 ---- a/linux-user/microblaze/syscall_nr.h -+++ b/linux-user/microblaze/syscall_nr.h +diff -uNr qemu-0.14.1.orig/linux-user/microblaze/syscall_nr.h qemu-0.14.1/linux-user/microblaze/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/microblaze/syscall_nr.h 2011-11-24 22:21:09.629912120 +0100 ++++ qemu-0.14.1/linux-user/microblaze/syscall_nr.h 2011-11-24 22:21:41.766730943 +0100 @@ -364,6 +364,16 @@ #define TARGET_NR_sendmsg 360 /* new */ #define TARGET_NR_recvmsg 361 /* new */ @@ -179,10 +161,9 @@ index 3e641cd..f1fe0e7 100644 +#define TARGET_NR_clock_adjtime 373 +#define TARGET_NR_syncfs 374 -diff --git a/linux-user/mips/syscall_nr.h b/linux-user/mips/syscall_nr.h -index 0595308..fbdc348 100644 ---- a/linux-user/mips/syscall_nr.h -+++ b/linux-user/mips/syscall_nr.h +diff -uNr qemu-0.14.1.orig/linux-user/mips/syscall_nr.h qemu-0.14.1/linux-user/mips/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/mips/syscall_nr.h 2011-11-24 22:21:09.632226952 +0100 ++++ qemu-0.14.1/linux-user/mips/syscall_nr.h 2011-11-24 22:21:41.766730943 +0100 @@ -332,3 +332,16 @@ #define TARGET_NR_dup3 (TARGET_NR_Linux + 327) #define TARGET_NR_pipe2 (TARGET_NR_Linux + 328) @@ -200,10 +181,9 @@ index 0595308..fbdc348 100644 +#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 340) +#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 341) +#define TARGET_NR_syncfs (TARGET_NR_Linux + 342) -diff --git a/linux-user/mips64/syscall_nr.h b/linux-user/mips64/syscall_nr.h -index ee1d134..36d27b5 100644 ---- a/linux-user/mips64/syscall_nr.h -+++ b/linux-user/mips64/syscall_nr.h +diff -uNr qemu-0.14.1.orig/linux-user/mips64/syscall_nr.h qemu-0.14.1/linux-user/mips64/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/mips64/syscall_nr.h 2011-11-24 22:21:09.627597287 +0100 ++++ qemu-0.14.1/linux-user/mips64/syscall_nr.h 2011-11-24 22:21:41.769045776 +0100 @@ -291,3 +291,16 @@ #define TARGET_NR_dup3 (TARGET_NR_Linux + 286) #define TARGET_NR_pipe2 (TARGET_NR_Linux + 287) @@ -221,10 +201,9 @@ index ee1d134..36d27b5 100644 +#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 299) +#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 300) +#define TARGET_NR_syncfs (TARGET_NR_Linux + 301) -diff --git a/linux-user/mipsn32/syscall_nr.h b/linux-user/mipsn32/syscall_nr.h -index 60a99dd..4e1aca3 100644 ---- a/linux-user/mipsn32/syscall_nr.h -+++ b/linux-user/mipsn32/syscall_nr.h +diff -uNr qemu-0.14.1.orig/linux-user/mipsn32/syscall_nr.h qemu-0.14.1/linux-user/mipsn32/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/mipsn32/syscall_nr.h 2011-11-24 22:21:09.634541784 +0100 ++++ qemu-0.14.1/linux-user/mipsn32/syscall_nr.h 2011-11-24 22:21:41.769045776 +0100 @@ -295,3 +295,17 @@ #define TARGET_NR_dup3 (TARGET_NR_Linux + 290) #define TARGET_NR_pipe2 (TARGET_NR_Linux + 291) @@ -243,10 +222,9 @@ index 60a99dd..4e1aca3 100644 +#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 304) +#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 305) +#define TARGET_NR_syncfs (TARGET_NR_Linux + 306) -diff --git a/linux-user/ppc/syscall_nr.h b/linux-user/ppc/syscall_nr.h -index cc84a4c..0673b7d 100644 ---- a/linux-user/ppc/syscall_nr.h -+++ b/linux-user/ppc/syscall_nr.h +diff -uNr qemu-0.14.1.orig/linux-user/ppc/syscall_nr.h qemu-0.14.1/linux-user/ppc/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/ppc/syscall_nr.h 2011-11-24 22:21:09.627597287 +0100 ++++ qemu-0.14.1/linux-user/ppc/syscall_nr.h 2011-11-24 22:21:41.769045776 +0100 @@ -332,3 +332,33 @@ #define TARGET_NR_dup3 316 #define TARGET_NR_pipe2 317 @@ -281,10 +259,9 @@ index cc84a4c..0673b7d 100644 +#define TARGET_NR_open_by_handle_at 346 +#define TARGET_NR_clock_adjtime 347 +#define TARGET_NR_syncfs 348 -diff --git a/linux-user/sh4/syscall_nr.h b/linux-user/sh4/syscall_nr.h -index 262b236..6173a7c 100644 ---- a/linux-user/sh4/syscall_nr.h -+++ b/linux-user/sh4/syscall_nr.h +diff -uNr qemu-0.14.1.orig/linux-user/sh4/syscall_nr.h qemu-0.14.1/linux-user/sh4/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/sh4/syscall_nr.h 2011-11-24 22:21:09.634541784 +0100 ++++ qemu-0.14.1/linux-user/sh4/syscall_nr.h 2011-11-24 22:21:41.769045776 +0100 @@ -334,3 +334,35 @@ #define TARGET_NR_dup3 330 #define TARGET_NR_pipe2 331 @@ -321,10 +298,9 @@ index 262b236..6173a7c 100644 +#define TARGET_NR_open_by_handle_at 360 +#define TARGET_NR_clock_adjtime 361 +#define TARGET_NR_syncfs 362 -diff --git a/linux-user/sparc/syscall_nr.h b/linux-user/sparc/syscall_nr.h -index 5d1ac21..be503f2 100644 ---- a/linux-user/sparc/syscall_nr.h -+++ b/linux-user/sparc/syscall_nr.h +diff -uNr qemu-0.14.1.orig/linux-user/sparc/syscall_nr.h qemu-0.14.1/linux-user/sparc/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/sparc/syscall_nr.h 2011-11-24 22:21:09.629912120 +0100 ++++ qemu-0.14.1/linux-user/sparc/syscall_nr.h 2011-11-24 22:21:41.769045776 +0100 @@ -285,3 +285,15 @@ #define TARGET_NR_pipe2 321 #define TARGET_NR_inotify_init1 322 @@ -341,10 +317,9 @@ index 5d1ac21..be503f2 100644 +#define TARGET_NR_open_by_handle_at 333 +#define TARGET_NR_clock_adjtime 334 +#define TARGET_NR_syncfs 335 -diff --git a/linux-user/sparc64/syscall_nr.h b/linux-user/sparc64/syscall_nr.h -index bdca2a7..70988b2 100644 ---- a/linux-user/sparc64/syscall_nr.h -+++ b/linux-user/sparc64/syscall_nr.h +diff -uNr qemu-0.14.1.orig/linux-user/sparc64/syscall_nr.h qemu-0.14.1/linux-user/sparc64/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/sparc64/syscall_nr.h 2011-11-24 22:21:09.632226952 +0100 ++++ qemu-0.14.1/linux-user/sparc64/syscall_nr.h 2011-11-24 22:21:41.771360608 +0100 @@ -322,3 +322,15 @@ #define TARGET_NR_pipe2 321 #define TARGET_NR_inotify_init1 322 @@ -361,10 +336,9 @@ index bdca2a7..70988b2 100644 +#define TARGET_NR_open_by_handle_at 333 +#define TARGET_NR_clock_adjtime 334 +#define TARGET_NR_syncfs 335 -diff --git a/linux-user/x86_64/syscall_nr.h b/linux-user/x86_64/syscall_nr.h -index 568a901..947e961 100644 ---- a/linux-user/x86_64/syscall_nr.h -+++ b/linux-user/x86_64/syscall_nr.h +diff -uNr qemu-0.14.1.orig/linux-user/x86_64/syscall_nr.h qemu-0.14.1/linux-user/x86_64/syscall_nr.h +--- qemu-0.14.1.orig/linux-user/x86_64/syscall_nr.h 2011-11-24 22:21:09.625282454 +0100 ++++ qemu-0.14.1/linux-user/x86_64/syscall_nr.h 2011-11-24 22:21:41.771360608 +0100 @@ -293,3 +293,15 @@ #define TARGET_NR_dup3 292 #define TARGET_NR_pipe2 293 diff --git a/app-emulation/qemu/qemu-0.14.1.ebuild b/app-emulation/qemu/qemu-0.14.1.ebuild new file mode 100644 index 0000000..38e2b5f --- /dev/null +++ b/app-emulation/qemu/qemu-0.14.1.ebuild @@ -0,0 +1,201 @@ +# Copyright 1999-2011 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/app-emulation/qemu/qemu-0.14.0.ebuild,v 1.3 2011/02/20 22:07:37 zmedico Exp $ + +EAPI="2" + +if [[ ${PV} = *9999* ]]; then + EGIT_REPO_URI="git://git.qemu.org/qemu.git" + GIT_ECLASS="git" +fi + +inherit eutils flag-o-matic ${GIT_ECLASS} linux-info toolchain-funcs + +if [[ ${PV} = *9999* ]]; then + SRC_URI="" + KEYWORDS="" +else + SRC_URI="http://download.savannah.gnu.org/releases/qemu/${P}.tar.gz" + KEYWORDS="~amd64 ~ppc ~ppc64 ~x86" +fi + +DESCRIPTION="QEMU emulator and ABI wrapper" +HOMEPAGE="http://www.qemu.org" + +LICENSE="GPL-2" +SLOT="0" +# xen is disabled until the deps are fixed +IUSE="+aio alsa bluetooth brltty curl esd fdt hardened jpeg ncurses \ +png pulseaudio qemu-ifup sasl sdl ssl static vde" + +COMMON_TARGETS="i386 x86_64 arm cris m68k microblaze mips mipsel ppc ppc64 sh4 sh4eb sparc sparc64" +IUSE_SOFTMMU_TARGETS="${COMMON_TARGETS} mips64 mips64el ppcemb" +IUSE_USER_TARGETS="${COMMON_TARGETS} alpha armeb ppc64abi32 sparc32plus" + +for target in ${IUSE_SOFTMMU_TARGETS}; do + IUSE="${IUSE} +qemu_softmmu_targets_${target}" +done + +for target in ${IUSE_USER_TARGETS}; do + IUSE="${IUSE} +qemu_user_targets_${target}" +done + +RESTRICT="test" + +RDEPEND=" + !app-emulation/qemu-kvm + !app-emulation/qemu-softmmu + !app-emulation/qemu-user + !app-emulation/qemu-kvm-spice + sys-apps/pciutils + >=sys-apps/util-linux-2.16.0 + sys-libs/zlib + aio? ( dev-libs/libaio ) + alsa? ( >=media-libs/alsa-lib-1.0.13 ) + bluetooth? ( net-wireless/bluez ) + brltty? ( app-accessibility/brltty ) + curl? ( net-misc/curl ) + esd? ( media-sound/esound ) + fdt? ( >=sys-apps/dtc-1.2.0 ) + jpeg? ( virtual/jpeg ) + ncurses? ( sys-libs/ncurses ) + png? ( media-libs/libpng ) + pulseaudio? ( media-sound/pulseaudio ) + qemu-ifup? ( sys-apps/iproute2 net-misc/bridge-utils ) + sasl? ( dev-libs/cyrus-sasl ) + sdl? ( >=media-libs/libsdl-1.2.11[X] ) + ssl? ( net-libs/gnutls ) + vde? ( net-misc/vde ) +" + +DEPEND="${RDEPEND} + app-text/texi2html + >=sys-kernel/linux-headers-2.6.29 + ssl? ( dev-util/pkgconfig ) +" + +pkg_setup() { + use qemu_softmmu_targets_x86_64 || ewarn "You disabled default target QEMU_SOFTMMU_TARGETS=x86_64" +} + +src_prepare() { + # prevent docs to get automatically installed + sed -i '/$(DESTDIR)$(docdir)/d' Makefile || die + # Alter target makefiles to accept CFLAGS set via flag-o + sed -i 's/^\(C\|OP_C\|HELPER_C\)FLAGS=/\1FLAGS+=/' \ + Makefile Makefile.target || die + # append CFLAGS while linking + sed -i 's/$(LDFLAGS)/$(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS)/' rules.mak || die + EPATCH_SOURCE="${FILESDIR}/0.14.1" EPATCH_SUFFIX="patch" \ + EPATCH_FORCE="yes" epatch + epatch "${FILESDIR}/qemu-chroot.patch" +} + +src_configure() { + local conf_opts audio_opts user_targets + + for target in ${IUSE_SOFTMMU_TARGETS} ; do + use "qemu_softmmu_targets_${target}" && \ + softmmu_targets="${softmmu_targets} ${target}-softmmu" + done + + for target in ${IUSE_USER_TARGETS} ; do + use "qemu_user_targets_${target}" && \ + user_targets="${user_targets} ${target}-linux-user" + done + + if [ -z "${softmmu_targets}" ]; then + conf_opts="${conf_opts} --disable-system" + else + einfo "Building the following softmmu targets: ${softmmu_targets}" + fi + + if [ ! -z "${user_targets}" ]; then + einfo "Building the following user targets: ${user_targets}" + conf_opts="${conf_opts} --enable-linux-user" + else + conf_opts="${conf_opts} --disable-linux-user" + fi + + # Fix QA issues. QEMU needs executable heaps and we need to mark it as such + conf_opts="${conf_opts} --extra-ldflags=-Wl,-z,execheap" + + # Add support for static builds + use static && conf_opts="${conf_opts} --static" + + # Fix the $(prefix)/etc issue + conf_opts="${conf_opts} --sysconfdir=/etc" + + #config options + conf_opts="${conf_opts} $(use_enable aio linux-aio)" + conf_opts="${conf_opts} $(use_enable bluetooth bluez)" + conf_opts="${conf_opts} $(use_enable brltty brlapi)" + conf_opts="${conf_opts} $(use_enable curl)" + conf_opts="${conf_opts} $(use_enable fdt)" + conf_opts="${conf_opts} $(use_enable hardened user-pie)" + conf_opts="${conf_opts} $(use_enable jpeg vnc-jpeg)" + conf_opts="${conf_opts} $(use_enable ncurses curses)" + conf_opts="${conf_opts} $(use_enable png vnc-png)" + conf_opts="${conf_opts} $(use_enable sasl vnc-sasl)" + conf_opts="${conf_opts} $(use_enable sdl)" + conf_opts="${conf_opts} $(use_enable ssl vnc-tls)" + conf_opts="${conf_opts} $(use_enable vde)" + conf_opts="${conf_opts} --disable-xen" + conf_opts="${conf_opts} --disable-darwin-user --disable-bsd-user" + + # audio options + audio_opts="oss" + use alsa && audio_opts="alsa ${audio_opts}" + use esd && audio_opts="esd ${audio_opts}" + use pulseaudio && audio_opts="pa ${audio_opts}" + use sdl && audio_opts="sdl ${audio_opts}" + ./configure --prefix=/usr \ + --disable-strip \ + --disable-werror \ + --disable-kvm \ + --enable-nptl \ + --enable-uuid \ + ${conf_opts} \ + --audio-drv-list="${audio_opts}" \ + --target-list="${softmmu_targets} ${user_targets}" \ + --cc="$(tc-getCC)" \ + --host-cc="$(tc-getBUILD_CC)" \ + || die "configure failed" + + # this is for qemu upstream's threaded support which is + # in development and broken + # the kvm project has its own support for threaded IO + # which is always on and works + # --enable-io-thread \ +} + +src_compile() { + # Restricting parallel build until we get a patch to fix this + emake || die +} + +src_install() { + emake DESTDIR="${D}" install || die "make install failed" + + if [ ! -z "${softmmu_targets}" ]; then + exeinto /etc/qemu + use qemu-ifup && { doexe \ + "${FILESDIR}/qemu-ifup" \ + "${FILESDIR}/qemu-ifdown" \ + || die "qemu interface scripts missing" ; } + fi + + dodoc Changelog MAINTAINERS TODO pci-ids.txt || die + newdoc pc-bios/README README.pc-bios || die + dohtml qemu-doc.html qemu-tech.html || die +} + +pkg_postinst() { + use qemu-ifup || return + elog "You will need the Universal TUN/TAP driver compiled into your" + elog "kernel or loaded as a module to use the virtual network device" + elog "if using -net tap. You will also need support for 802.1d" + elog "Ethernet Bridging and a configured bridge if using the provided" + elog "qemu-ifup script from /etc/qemu." + echo +}