[Qemu-devel] [PATCH target-arm v1 1/1] target-arm/helper: remove raw_read|write duplication
There is an inline duplication of the raw_read and raw_write function bodies. Fix by just calling raw_read/raw_write instead. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- target-arm/helper.c | 12 ++-- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index 6ebd7dc..1534f75 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -142,11 +142,7 @@ static bool read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri, } else if (ri-readfn) { return (ri-readfn(env, ri, v) == 0); } else { -if (ri-type ARM_CP_64BIT) { -*v = CPREG_FIELD64(env, ri); -} else { -*v = CPREG_FIELD32(env, ri); -} +raw_read(env, ri, v); } return true; } @@ -167,11 +163,7 @@ static bool write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri, } else if (ri-writefn) { return (ri-writefn(env, ri, v) == 0); } else { -if (ri-type ARM_CP_64BIT) { -CPREG_FIELD64(env, ri) = v; -} else { -CPREG_FIELD32(env, ri) = v; -} +raw_write(env, ri, v); } return true; } -- 1.8.5.2
Re: [Qemu-devel] [PATCH v2 1/1] qtest: Fix the bug about disabling vnc causes make check hang
Il 31/12/2013 05:42, Kewei Yu ha scritto: When we disabling vnc from ./configure, the qemu can't use the vnc option. So qtest can't use the vnc -none , otherwise make check will hang. Signed-off-by: Kewei Yu kewe...@gmail.com --- v2: Consolidate VNC macro's #ifdef'ery to one central point (tests/libqtest.c). What happens if qtest instead uses -display none? Paolo
Re: [Qemu-devel] [PATCH] hw/misc/blob-loader: add a generic blob loader
Il 02/01/2014 06:50, Peter Crosthwaite ha scritto: On Thu, Jan 2, 2014 at 3:35 PM, Li Guang lig.f...@cn.fujitsu.com wrote: this blob loader will be used to load a specified blob into a specified RAM address. Suggested-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Signed-off-by: Li Guang lig.f...@cn.fujitsu.com --- it can be used now for allwinner-a10, like: -device blob-loader,addr=0x4300,file=/path/script.bin reference: http://linux-sunxi.org/Sunxi-tools script file address: http://dl.dbank.com/c00aonvlmw Thanks to Peter Crosthwaite for the idea! --- default-configs/arm-softmmu.mak |2 + hw/misc/Makefile.objs |2 + hw/misc/blob-loader.c | 75 +++ 3 files changed, 79 insertions(+), 0 deletions(-) create mode 100644 hw/misc/blob-loader.c diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index ce1d620..50c71a6 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -87,3 +87,5 @@ CONFIG_INTEGRATOR_DEBUG=y CONFIG_ALLWINNER_A10_PIT=y CONFIG_ALLWINNER_A10_PIC=y CONFIG_ALLWINNER_A10=y + +CONFIG_BLOB_LOADER=y This shouldn't be arm specific. I would make the argument that the blob loader has global validity. diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index f674365..df28288 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -42,3 +42,5 @@ obj-$(CONFIG_SLAVIO) += slavio_misc.o obj-$(CONFIG_ZYNQ) += zynq_slcr.o obj-$(CONFIG_PVPANIC) += pvpanic.o + +obj-$(CONFIG_BLOB_LOADER) += blob-loader.o diff --git a/hw/misc/blob-loader.c b/hw/misc/blob-loader.c new file mode 100644 index 000..d7f1408 --- /dev/null +++ b/hw/misc/blob-loader.c @@ -0,0 +1,75 @@ +#include hw/sysbus.h +#include hw/devices.h +#include hw/loader.h +#include qemu/error-report.h + +typedef struct BlobLoaderState { /* private /* +DeviceState qdev; parent_obj; /* public /* +uint32_t addr; uint64_t or hwaddr. Blob loading shouldn't be limited to 32 bit. +char *file; +} BlobLoaderState; + +#define TYPE_BLOB_LOADER blob-loader +#define BLOB_LOADER(obj) OBJECT_CHECK(BlobLoaderState, (obj), TYPE_BLOB_LOADER) + +static Property blob_loader_props[] = { +DEFINE_PROP_UINT32(addr, BlobLoaderState, addr, 0), +DEFINE_PROP_STRING(file, BlobLoaderState, file), +DEFINE_PROP_END_OF_LIST(), +}; + +static void do_blob_load(BlobLoaderState *s) +{ +char *file_name; +int file_size; + +if (s-file == NULL) { +error_report(please spicify a file for blob loader\n); +return; Should you exit(1)? Better yet, return true for error and .. +} +file_name = qemu_find_file(QEMU_FILE_TYPE_BIOS, s-file); +if (file_name == NULL) { +error_report(can't find %s\n, s-file); +return; +} +file_size = get_image_size(file_name); +if (file_size 0) { +error_report(can't get file size of %s\n, file_name); +return; +} +if (load_image_targphys(file_name, s-addr, file_size) 0) { +error_report(can't load %s\n, file_name); +return; +} +} + +static int blob_loader_init(DeviceState *dev) +{ +BlobLoaderState *s = BLOB_LOADER(dev); + +do_blob_load(s); exit(1) here. No, please use realize and avoid init. This way you can use an Error* to report the error. Also, the actual load_image_targphys call probably should be done in a reset handler, not at realize time. Paolo +return 0; +} + +static void blob_loader_class_init(ObjectClass *klass, void *data) s/klass/oc. Actually klass is quite commonly used. Paolo +{ +DeviceClass *dc = DEVICE_CLASS(klass); + +dc-props = blob_loader_props; +dc-desc = blob loader; +dc-init = blob_loader_init; I'm wondering whether blob loading is actually a reset step not an init. Will doing it at init will play foul with VMSD, as your blob loader will trample non-reset state on machine restore? Regards, Peter +} + +static TypeInfo blob_loader_info = { +.name = TYPE_BLOB_LOADER, +.parent= TYPE_DEVICE, +.instance_size = sizeof(BlobLoaderState), +.class_init= blob_loader_class_init, +}; + +static void blob_loader_register_type(void) +{ +type_register_static(blob_loader_info); +} + +type_init(blob_loader_register_type) -- 1.7.2.5
Re: [Qemu-devel] [PATCH] HMP: snapshot_blkdev can not consider //root/sn1 and /root/sn1 as the same file
On Tue, Dec 10, 2013 at 09:58:44PM +0800, lijun wrote: On 12/09/2013 08:17 PM, Stefan Hajnoczi wrote: On Mon, Dec 09, 2013 at 02:06:21PM +0800, jun muzi wrote: My question was about the bug. What is the problem you are seeing and how do you reproduce it (including the HMP commands)? Now I am seeing is how to distinguish network storage file mounted on different dir is the same file or not. Reproduce this bug using nfs mounted in different directories: Create a nfs server, and mount it as followings: # mount $IP:/home/ /mnt/dir1 # mount $IP:/home/ /mnt/dir2 (qemu) snapshot_blkdev drive-scsi0-0-0 /mnt/dir1/sn1 Formatting '/mnt/dir1/sn1', fmt=qcow2 size=32212254720 backing_file='/home/juli/RHEL-7.0-20131127.1.qcow2_v3' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off (qemu) snapshot_blkdev drive-scsi0-0-0 /mnt/dir2/sn1 Formatting '/mnt/dir2/sn1', fmt=qcow2 size=32212254720 backing_file='/mnt/dir1/sn1' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off (qemu) info block drive-scsi0-0-0: removable=0 io-status=ok file=/mnt/dir2/sn1 backing_file=/mnt/dir1/sn1 backing_file_depth=2 ro=0 drv=qcow2 encrypted=0 bps=0 bps_rd=0 bps_wr=0 iops=0 iops_rd=0 iops_wr=0 drive-virtio-disk1: removable=0 io-status=ok file=/home/juli/data_disk.qcow2_v3 ro=0 drv=qcow2 encrypted=0 bps=0 bps_rd=0 bps_wr=0 iops=0 iops_rd=0 iops_wr=0 ide1-cd0: removable=1 locked=0 tray-open=0 io-status=ok [not inserted] floppy0: removable=1 locked=0 tray-open=0 [not inserted] sd0: removable=1 locked=0 tray-open=0 [not inserted] (qemu) snapshot_blkdev drive-scsi0-0-0 /mnt/dir2/sn2 Could not open '/mnt/dir2/sn1': Could not set AIO state: Too many open files: Too many open files Okay, I think we got side-tracked worrying about identifying identical files. The problem in your example is more fundamental. Here is what should have happened: (qemu) snapshot_blkdev drive-scsi0-0-0 /mnt/dir2/sn1 Could not create '/mnt/dir2/sn1': File exists The file was previously created with the name /mnt/dir1/sn1. Running snapshot_blkdev with /mnt/dir2/sn1 clobbers the file in your example. This is bad because it corrupts the backing chain. If QEMU uses O_CREAT | O_EXCL open(2) flags then creating the snapshot file fails and the user will not mistakingly overwrite sn1. However, QEMU does not use O_EXCL to create image files anywhere today (qemu-img or QEMU monitor commands). Returning an error is not backwards-compatible since existing users might rely on clobbering files (there are safe cases where it can be useful). We could add an option to commands that create files but I'm not sure if it's worth the effort since human users who are most at risk probably won't provide this new option... That said, if you want to add an O_EXCL option to bdrv_img_create(), qemu-img commands, and monitor commands, I'm happy to review patches. Stefan
[Qemu-devel] [PATCH 0/2] hw/arm: add ethernet support to Allwinner A10
This patch series adds support for the EMAC Fast Ethernet controller found on Allwinner SoCs to the Allwinner A10. Beniamino Galvani (2): hw/net: add support for Allwinner EMAC Fast Ethernet controller hw/arm/allwinner-a10: initialize EMAC default-configs/arm-softmmu.mak |1 + hw/arm/allwinner-a10.c | 20 ++ hw/net/Makefile.objs|1 + hw/net/allwinner_emac.c | 466 +++ include/hw/arm/allwinner-a10.h |4 + include/hw/net/allwinner_emac.h | 204 + 6 files changed, 696 insertions(+) create mode 100644 hw/net/allwinner_emac.c create mode 100644 include/hw/net/allwinner_emac.h -- 1.7.10.4
[Qemu-devel] [PATCH 2/2] hw/arm/allwinner-a10: initialize EMAC
Signed-off-by: Beniamino Galvani b.galv...@gmail.com --- hw/arm/allwinner-a10.c | 20 include/hw/arm/allwinner-a10.h |4 2 files changed, 24 insertions(+) diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index 4658e19..155e026 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -22,6 +22,7 @@ static void aw_a10_init(Object *obj) { AwA10State *s = AW_A10(obj); +DeviceState *dev; object_initialize(s-cpu, sizeof(s-cpu), cortex-a8- TYPE_ARM_CPU); object_property_add_child(obj, cpu, OBJECT(s-cpu), NULL); @@ -31,6 +32,14 @@ static void aw_a10_init(Object *obj) object_initialize(s-timer, sizeof(s-timer), TYPE_AW_A10_PIT); qdev_set_parent_bus(DEVICE(s-timer), sysbus_get_default()); + +if (nd_table[0].used) { +qemu_check_nic_model(nd_table[0], allwinner_emac); +object_initialize(s-emac, sizeof(s-emac), TYPE_AW_EMAC); +dev = DEVICE(s-emac); +qdev_set_nic_properties(dev, nd_table[0]); +qdev_set_parent_bus(dev, sysbus_get_default()); +} } static void aw_a10_realize(DeviceState *dev, Error **errp) @@ -76,6 +85,17 @@ static void aw_a10_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(sysbusdev, 4, s-irq[67]); sysbus_connect_irq(sysbusdev, 5, s-irq[68]); +if (nd_table[0].used) { +object_property_set_bool(OBJECT(s-emac), true, realized, err); +if (err != NULL) { +error_propagate(errp, err); +return; +} +sysbusdev = SYS_BUS_DEVICE(s-emac); +sysbus_mmio_map(sysbusdev, 0, AW_A10_EMAC_BASE); +sysbus_connect_irq(sysbusdev, 0, s-irq[55]); +} + serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2, s-irq[1], 115200, serial_hds[0], DEVICE_NATIVE_ENDIAN); } diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h index da36647..6ea5988 100644 --- a/include/hw/arm/allwinner-a10.h +++ b/include/hw/arm/allwinner-a10.h @@ -6,6 +6,7 @@ #include hw/arm/arm.h #include hw/timer/allwinner-a10-pit.h #include hw/intc/allwinner-a10-pic.h +#include hw/net/allwinner_emac.h #include sysemu/sysemu.h #include exec/address-spaces.h @@ -14,9 +15,11 @@ #define AW_A10_PIC_REG_BASE 0x01c20400 #define AW_A10_PIT_REG_BASE 0x01c20c00 #define AW_A10_UART0_REG_BASE 0x01c28000 +#define AW_A10_EMAC_BASE0x01c0b000 #define AW_A10_SDRAM_BASE 0x4000 + #define TYPE_AW_A10 allwinner-a10 #define AW_A10(obj) OBJECT_CHECK(AwA10State, (obj), TYPE_AW_A10) @@ -29,6 +32,7 @@ typedef struct AwA10State { qemu_irq irq[AW_A10_PIC_INT_NR]; AwA10PITState timer; AwA10PICState intc; +AwEmacState emac; } AwA10State; #define ALLWINNER_H_ -- 1.7.10.4
[Qemu-devel] [PATCH 1/2] hw/net: add support for Allwinner EMAC Fast Ethernet controller
This patch adds support for the Fast Ethernet MAC found on Allwinner SoCs, together with a basic emulation of Realtek RTL8201CP PHY. Since there is no public documentation of the Allwinner controller, the implementation is based on Linux kernel driver. Signed-off-by: Beniamino Galvani b.galv...@gmail.com --- default-configs/arm-softmmu.mak |1 + hw/net/Makefile.objs|1 + hw/net/allwinner_emac.c | 466 +++ include/hw/net/allwinner_emac.h | 204 + 4 files changed, 672 insertions(+) create mode 100644 hw/net/allwinner_emac.c create mode 100644 include/hw/net/allwinner_emac.h diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index ce1d620..f3513fa 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -27,6 +27,7 @@ CONFIG_SSI_SD=y CONFIG_SSI_M25P80=y CONFIG_LAN9118=y CONFIG_SMC91C111=y +CONFIG_ALLWINNER_EMAC=y CONFIG_DS1338=y CONFIG_PFLASH_CFI01=y CONFIG_PFLASH_CFI02=y diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs index 951cca3..75e80c2 100644 --- a/hw/net/Makefile.objs +++ b/hw/net/Makefile.objs @@ -18,6 +18,7 @@ common-obj-$(CONFIG_OPENCORES_ETH) += opencores_eth.o common-obj-$(CONFIG_XGMAC) += xgmac.o common-obj-$(CONFIG_MIPSNET) += mipsnet.o common-obj-$(CONFIG_XILINX_AXI) += xilinx_axienet.o +common-obj-$(CONFIG_ALLWINNER_EMAC) += allwinner_emac.o common-obj-$(CONFIG_CADENCE) += cadence_gem.o common-obj-$(CONFIG_STELLARIS_ENET) += stellaris_enet.o diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c new file mode 100644 index 000..9791be4 --- /dev/null +++ b/hw/net/allwinner_emac.c @@ -0,0 +1,466 @@ +/* + * Emulation of Allwinner EMAC Fast Ethernet controller and + * Realtek RTL8201CP PHY + * + * Copyright (C) 2013 Beniamino Galvani b.galv...@gmail.com + * + * 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. + * + */ +#include hw/sysbus.h +#include net/net.h +#include hw/net/allwinner_emac.h +#include zlib.h + +#undef AW_EMAC_DEBUG + +#ifdef AW_EMAC_DEBUG +#define debug(...) \ +do {\ +fprintf(stderr, allwinner_emac : %s: , __func__);\ +fprintf(stderr, ## __VA_ARGS__);\ +} while (0) +#else +#define debug(...) do {} while (0) +#endif + +static void mii_set_link(AwEmacMii *mii, bool link_ok) +{ +if (link_ok) { +mii-bmsr |= MII_BMSR_LINK_ST; +mii-anlpar |= MII_ANAR_TXFD | MII_ANAR_TX | MII_ANAR_10FD | + MII_ANAR_10 | MII_ANAR_CSMACD; +} else { +mii-bmsr = ~MII_BMSR_LINK_ST; +mii-anlpar = MII_ANAR_TX; +} +mii-link_ok = link_ok; +} + +static void mii_reset(AwEmacMii *mii) +{ +mii-bmcr = MII_BMCR_FD | MII_BMCR_AUTOEN | MII_BMCR_SPEED; +mii-bmsr = MII_BMSR_100TX_FD | MII_BMSR_100TX_HD | MII_BMSR_10T_FD | +MII_BMSR_10T_HD | MII_BMSR_MFPS | MII_BMSR_AUTONEG; +mii-anar = MII_ANAR_TXFD | MII_ANAR_TX | MII_ANAR_10FD | MII_ANAR_10 | +MII_ANAR_CSMACD; +mii-anlpar = MII_ANAR_TX; +mii_set_link(mii, mii-link_ok); +} + +static uint16_t mii_read(AwEmacMii *mii, uint8_t phy_addr, uint8_t reg) +{ +uint16_t ret = 0x; + +if (phy_addr == BOARD_PHY_ADDRESS) { +switch (reg) { +case MII_BMCR: +ret = mii-bmcr; +break; +case MII_BMSR: +ret = mii-bmsr; +break; +case MII_PHYID1: +ret = RTL8201CP_PHYID1; +break; +case MII_PHYID2: +ret = RTL8201CP_PHYID2; +break; +case MII_ANAR: +ret = mii-anar; +break; +case MII_ANLPAR: +ret = mii-anlpar; +break; +default: +debug(unknown mii register %x\n, reg); +ret = 0; +} +} +return ret; +} + +static void mii_write(AwEmacMii *mii, uint8_t phy_addr, uint8_t reg, + uint16_t value) +{ +if (phy_addr == BOARD_PHY_ADDRESS) { +switch (reg) { +case MII_BMCR: +if (value MII_BMCR_RESET) { +mii_reset(mii); +} else { +mii-bmcr = value; +} +break; +case MII_BMSR: +case MII_PHYID1: +case MII_PHYID2: +case MII_ANLPAR: +qemu_log_mask(LOG_GUEST_ERROR, %s: write to mii register %x\n, +
Re: [Qemu-devel] [PATCH 3/3] qemu-iotests: Clean up all extents for vmdk
On Tue, Nov 26, 2013 at 02:40:34PM +0800, Fam Zheng wrote: This modifies _cleanup_test_img to remove all the extent files listed by qemu-img info's format specific information. Signed-off-by: Fam Zheng f...@redhat.com --- tests/qemu-iotests/common.rc | 17 ++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc index d465c48..fd635a0 100644 --- a/tests/qemu-iotests/common.rc +++ b/tests/qemu-iotests/common.rc @@ -170,6 +170,17 @@ _make_test_img() fi } +_rm_test_img() +{ +local img=$1 +if [ $IMGFMT = vmdk ]; then +# Remove all the extents for vmdk +$QEMU_IMG info $img 2/dev/null | grep 'filename:' | cut -f 2 -d: \ +| xargs -I {} rm -f {} +fi +rm -f $img +} It would be nice to simply rm -rf $TEST_DIR instead of picking individual files. Not sure if anything prevents us from doing that. Anyway, this patch is okay for now. Stefan
Re: [Qemu-devel] [PATCH 0/3] qemu-iotests: Improvements for vmdk
On Tue, Nov 26, 2013 at 02:40:31PM +0800, Fam Zheng wrote: Patch 1 and 2 add _unsupported_imgopts declaration for vmdk subformats, so the cases can be skipped if the subformat is not supported. Patch 3 adds clean up for vmdk extents. Fam Zheng (3): qemu-iotests: Introduce _unsupported_imgopts qemu-iotests: Add _unsupported_imgopts for vmdk subformats qemu-iotests: Clean up all extents for vmdk tests/qemu-iotests/017 | 1 + tests/qemu-iotests/018 | 1 + tests/qemu-iotests/019 | 3 +++ tests/qemu-iotests/020 | 3 +++ tests/qemu-iotests/034 | 3 +++ tests/qemu-iotests/037 | 3 +++ tests/qemu-iotests/059 | 3 +++ tests/qemu-iotests/063 | 3 +++ tests/qemu-iotests/069 | 1 + tests/qemu-iotests/common.rc | 28 +--- 10 files changed, 46 insertions(+), 3 deletions(-) Thanks, applied to my block-next tree: https://github.com/stefanha/qemu/commits/block-next Stefan
Re: [Qemu-devel] [PATCH v2 1/1] qtest: Fix the bug about disabling vnc causes make check hang
The fail is caused by -vnc none, we can't use it when disable vnc from ./configure. Faithfully yours Kewei Yu 2014/1/2 Paolo Bonzini pbonz...@redhat.com Il 31/12/2013 05:42, Kewei Yu ha scritto: When we disabling vnc from ./configure, the qemu can't use the vnc option. So qtest can't use the vnc -none , otherwise make check will hang. Signed-off-by: Kewei Yu kewe...@gmail.com --- v2: Consolidate VNC macro's #ifdef'ery to one central point (tests/libqtest.c). What happens if qtest instead uses -display none? Paolo
Re: [Qemu-devel] [PATCH 2/2] hw/arm/allwinner-a10: initialize EMAC
On Thu, Jan 2, 2014 at 7:18 PM, Beniamino Galvani b.galv...@gmail.com wrote: Signed-off-by: Beniamino Galvani b.galv...@gmail.com --- hw/arm/allwinner-a10.c | 20 include/hw/arm/allwinner-a10.h |4 2 files changed, 24 insertions(+) diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index 4658e19..155e026 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -22,6 +22,7 @@ static void aw_a10_init(Object *obj) { AwA10State *s = AW_A10(obj); +DeviceState *dev; For consistency with surrounding code, you could just cast to DEVICE include and drop the new local var. object_initialize(s-cpu, sizeof(s-cpu), cortex-a8- TYPE_ARM_CPU); object_property_add_child(obj, cpu, OBJECT(s-cpu), NULL); @@ -31,6 +32,14 @@ static void aw_a10_init(Object *obj) object_initialize(s-timer, sizeof(s-timer), TYPE_AW_A10_PIT); qdev_set_parent_bus(DEVICE(s-timer), sysbus_get_default()); + +if (nd_table[0].used) { So with SoC MACs, they are always there. I think this conditional should be removed, and the MAC is always instantiated. ... +qemu_check_nic_model(nd_table[0], allwinner_emac); +object_initialize(s-emac, sizeof(s-emac), TYPE_AW_EMAC); +dev = DEVICE(s-emac); +qdev_set_nic_properties(dev, nd_table[0]); ... and then only this is conditional on nd_table.used. The mac model itself then of course needs to be hardened against a null netargs. +qdev_set_parent_bus(dev, sysbus_get_default()); +} } static void aw_a10_realize(DeviceState *dev, Error **errp) @@ -76,6 +85,17 @@ static void aw_a10_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(sysbusdev, 4, s-irq[67]); sysbus_connect_irq(sysbusdev, 5, s-irq[68]); +if (nd_table[0].used) { +object_property_set_bool(OBJECT(s-emac), true, realized, err); +if (err != NULL) { +error_propagate(errp, err); +return; +} +sysbusdev = SYS_BUS_DEVICE(s-emac); +sysbus_mmio_map(sysbusdev, 0, AW_A10_EMAC_BASE); +sysbus_connect_irq(sysbusdev, 0, s-irq[55]); +} + serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2, s-irq[1], 115200, serial_hds[0], DEVICE_NATIVE_ENDIAN); } diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h index da36647..6ea5988 100644 --- a/include/hw/arm/allwinner-a10.h +++ b/include/hw/arm/allwinner-a10.h @@ -6,6 +6,7 @@ #include hw/arm/arm.h #include hw/timer/allwinner-a10-pit.h #include hw/intc/allwinner-a10-pic.h +#include hw/net/allwinner_emac.h #include sysemu/sysemu.h #include exec/address-spaces.h @@ -14,9 +15,11 @@ #define AW_A10_PIC_REG_BASE 0x01c20400 #define AW_A10_PIT_REG_BASE 0x01c20c00 #define AW_A10_UART0_REG_BASE 0x01c28000 +#define AW_A10_EMAC_BASE0x01c0b000 #define AW_A10_SDRAM_BASE 0x4000 + This whitespace change intended? Regards, Peter #define TYPE_AW_A10 allwinner-a10 #define AW_A10(obj) OBJECT_CHECK(AwA10State, (obj), TYPE_AW_A10) @@ -29,6 +32,7 @@ typedef struct AwA10State { qemu_irq irq[AW_A10_PIC_INT_NR]; AwA10PITState timer; AwA10PICState intc; +AwEmacState emac; } AwA10State; #define ALLWINNER_H_ -- 1.7.10.4
Re: [Qemu-devel] [PATCH 2/2] hw/arm/allwinner-a10: initialize EMAC
On Thu, Jan 2, 2014 at 8:20 PM, Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: On Thu, Jan 2, 2014 at 7:18 PM, Beniamino Galvani b.galv...@gmail.com wrote: Signed-off-by: Beniamino Galvani b.galv...@gmail.com --- hw/arm/allwinner-a10.c | 20 include/hw/arm/allwinner-a10.h |4 2 files changed, 24 insertions(+) diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index 4658e19..155e026 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -22,6 +22,7 @@ static void aw_a10_init(Object *obj) { AwA10State *s = AW_A10(obj); +DeviceState *dev; For consistency with surrounding code, you could just cast to DEVICE include and drop the new local var. inline* not include Sorry, Peter object_initialize(s-cpu, sizeof(s-cpu), cortex-a8- TYPE_ARM_CPU); object_property_add_child(obj, cpu, OBJECT(s-cpu), NULL); @@ -31,6 +32,14 @@ static void aw_a10_init(Object *obj) object_initialize(s-timer, sizeof(s-timer), TYPE_AW_A10_PIT); qdev_set_parent_bus(DEVICE(s-timer), sysbus_get_default()); + +if (nd_table[0].used) { So with SoC MACs, they are always there. I think this conditional should be removed, and the MAC is always instantiated. ... +qemu_check_nic_model(nd_table[0], allwinner_emac); +object_initialize(s-emac, sizeof(s-emac), TYPE_AW_EMAC); +dev = DEVICE(s-emac); +qdev_set_nic_properties(dev, nd_table[0]); ... and then only this is conditional on nd_table.used. The mac model itself then of course needs to be hardened against a null netargs. +qdev_set_parent_bus(dev, sysbus_get_default()); +} } static void aw_a10_realize(DeviceState *dev, Error **errp) @@ -76,6 +85,17 @@ static void aw_a10_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(sysbusdev, 4, s-irq[67]); sysbus_connect_irq(sysbusdev, 5, s-irq[68]); +if (nd_table[0].used) { +object_property_set_bool(OBJECT(s-emac), true, realized, err); +if (err != NULL) { +error_propagate(errp, err); +return; +} +sysbusdev = SYS_BUS_DEVICE(s-emac); +sysbus_mmio_map(sysbusdev, 0, AW_A10_EMAC_BASE); +sysbus_connect_irq(sysbusdev, 0, s-irq[55]); +} + serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2, s-irq[1], 115200, serial_hds[0], DEVICE_NATIVE_ENDIAN); } diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h index da36647..6ea5988 100644 --- a/include/hw/arm/allwinner-a10.h +++ b/include/hw/arm/allwinner-a10.h @@ -6,6 +6,7 @@ #include hw/arm/arm.h #include hw/timer/allwinner-a10-pit.h #include hw/intc/allwinner-a10-pic.h +#include hw/net/allwinner_emac.h #include sysemu/sysemu.h #include exec/address-spaces.h @@ -14,9 +15,11 @@ #define AW_A10_PIC_REG_BASE 0x01c20400 #define AW_A10_PIT_REG_BASE 0x01c20c00 #define AW_A10_UART0_REG_BASE 0x01c28000 +#define AW_A10_EMAC_BASE0x01c0b000 #define AW_A10_SDRAM_BASE 0x4000 + This whitespace change intended? Regards, Peter #define TYPE_AW_A10 allwinner-a10 #define AW_A10(obj) OBJECT_CHECK(AwA10State, (obj), TYPE_AW_A10) @@ -29,6 +32,7 @@ typedef struct AwA10State { qemu_irq irq[AW_A10_PIC_INT_NR]; AwA10PITState timer; AwA10PICState intc; +AwEmacState emac; } AwA10State; #define ALLWINNER_H_ -- 1.7.10.4
Re: [Qemu-devel] [PATCH v2 12/25] target-arm: Update generic cpreg code for AArch64
On 2 January 2014 01:51, Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: On Mon, Dec 23, 2013 at 8:49 AM, Peter Maydell peter.mayd...@linaro.org wrote: +/* Valid values for ARMCPRegInfo state field, indicating which of + * the AArch32 and AArch64 execution states this register is visible in. + * If the reginfo doesn't explicitly specify then it is AArch32 only. + * If the reginfo is declared to be visible in both states then a second + * reginfo is synthesised for the AArch32 view of the AArch64 register, + * such that the AArch32 view is the lower 32 bits of the AArch64 one. + */ +#define ARM_CP_STATE_AA32 0 +#define ARM_CP_STATE_AA64 1 +#define ARM_CP_STATE_BOTH 2 You iterator below depends on this specific encoding ordering, so maybe this should be enumified. Could do. I'm a bit old-school about using #defines rather than enum :-) + /* Return true if cptype is a valid type field. This is used to try to * catch errors where the sentinel has been accidentally left off the end * of a list of registers. @@ -655,6 +698,8 @@ static inline bool cptype_valid(int cptype) * (ie anything visible in PL2 is visible in S-PL1, some things are only * visible in S-PL1) but Secure PL1 is a bit of a mouthful, we bend the * terminology a little and call this PL3. + * In AArch64 things are somewhat simpler as the PLx bits line up exactly + * with the ELx exception levels. * * If access permissions for a register are more complex than can be * described with these bits, then use a laxer set of restrictions, and @@ -676,6 +721,10 @@ static inline bool cptype_valid(int cptype) static inline int arm_current_pl(CPUARMState *env) { +if (env-aarch64) { +return extract32(env-pstate, 2, 2); +} + This does seem a little out of scope of this patch and more valid as a patch in its own right (Adding aarch64 support to arm_current_pl globally). arm_current_pl() is only used by the cpreg code, so making it work with aarch64 seemed to me to fit with the rest of the make cpreg code work with aarch64 changes. if ((env-uncached_cpsr 0x1f) == ARM_CPU_MODE_USR) { return 0; } @@ -713,12 +762,22 @@ struct ARMCPRegInfo { * then behave differently on read/write if necessary. * For 64 bit registers, only crm and opc1 are relevant; crn and opc2 * must both be zero. + * For AArch64-visible registers, opc0 is also used. + * Since there are no coprocessors in AArch64, cp is purely used as a + * way to distinguish (for KVM's benefit) guest-visible system registers + * from demuxed ones provided to preserve the no side effects on + * KVM register read/write from QEMU semantics. cp==0x13 is guest + * visible (to match KVM's encoding); cp==0 will be converted to + * cp==0x13 when the ARMCPRegInfo is registered, for convenience. */ uint8_t cp; uint8_t crn; uint8_t crm; +uint8_t opc0; uint8_t opc1; uint8_t opc2; +/* Execution state in which this register is visible: ARM_CP_STATE_* */ +int state; /* Register type: ARM_CP_* bits/values */ int type; /* Access rights: PL*_[RW] */ @@ -798,6 +857,11 @@ int arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri, /* CPReadFn that can be used for read-as-zero behaviour */ int arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t *value); +/* CPResetFn that does nothing, for use if no reset is required even + * if fieldoffset is non zero. + */ +void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque); + static inline bool cp_access_ok(CPUARMState *env, const ARMCPRegInfo *ri, int isread) { diff --git a/target-arm/helper.c b/target-arm/helper.c index d833163..3dac694 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1938,7 +1938,8 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp) } static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r, - void *opaque, int crm, int opc1, int opc2) + void *opaque, int state, + int crm, int opc1, int opc2) { /* Private utility function for define_one_arm_cp_reg_with_opaque(): * add a single reginfo struct to the hash table. @@ -1946,7 +1947,34 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r, uint32_t *key = g_new(uint32_t, 1); ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo)); int is64 = (r-type ARM_CP_64BIT) ? 1 : 0; -*key = ENCODE_CP_REG(r-cp, is64, r-crn, crm, opc1, opc2); +if (r-state == ARM_CP_STATE_BOTH state == ARM_CP_STATE_AA32) { +/* The AArch32 view of a shared register sees the lower 32 bits + * of a 64 bit backing field. It is not migratable as the AArch64 + * view handles that. AArch64 also
Re: [Qemu-devel] [PATCH 1/2] hw/net: add support for Allwinner EMAC Fast Ethernet controller
Hi Beniamino, On Thu, Jan 2, 2014 at 7:18 PM, Beniamino Galvani b.galv...@gmail.com wrote: This patch adds support for the Fast Ethernet MAC found on Allwinner SoCs, together with a basic emulation of Realtek RTL8201CP PHY. More a comment for net in general, but I think sooner or later we need to move towards a split between phy and mac on the device level. continuing the phy-within-mac philosophy is going to make the socification efforts awkward. Are MII and friends a busses (as in TYPE_BUS) in their own right, and connection of mac and phy has to happen on the board level? Since there is no public documentation of the Allwinner controller, the implementation is based on Linux kernel driver. Signed-off-by: Beniamino Galvani b.galv...@gmail.com --- default-configs/arm-softmmu.mak |1 + hw/net/Makefile.objs|1 + hw/net/allwinner_emac.c | 466 +++ include/hw/net/allwinner_emac.h | 204 + 4 files changed, 672 insertions(+) create mode 100644 hw/net/allwinner_emac.c create mode 100644 include/hw/net/allwinner_emac.h diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index ce1d620..f3513fa 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -27,6 +27,7 @@ CONFIG_SSI_SD=y CONFIG_SSI_M25P80=y CONFIG_LAN9118=y CONFIG_SMC91C111=y +CONFIG_ALLWINNER_EMAC=y CONFIG_DS1338=y CONFIG_PFLASH_CFI01=y CONFIG_PFLASH_CFI02=y diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs index 951cca3..75e80c2 100644 --- a/hw/net/Makefile.objs +++ b/hw/net/Makefile.objs @@ -18,6 +18,7 @@ common-obj-$(CONFIG_OPENCORES_ETH) += opencores_eth.o common-obj-$(CONFIG_XGMAC) += xgmac.o common-obj-$(CONFIG_MIPSNET) += mipsnet.o common-obj-$(CONFIG_XILINX_AXI) += xilinx_axienet.o +common-obj-$(CONFIG_ALLWINNER_EMAC) += allwinner_emac.o common-obj-$(CONFIG_CADENCE) += cadence_gem.o common-obj-$(CONFIG_STELLARIS_ENET) += stellaris_enet.o diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c new file mode 100644 index 000..9791be4 --- /dev/null +++ b/hw/net/allwinner_emac.c @@ -0,0 +1,466 @@ +/* + * Emulation of Allwinner EMAC Fast Ethernet controller and + * Realtek RTL8201CP PHY + * + * Copyright (C) 2013 Beniamino Galvani b.galv...@gmail.com + * + * 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. + * + */ +#include hw/sysbus.h +#include net/net.h +#include hw/net/allwinner_emac.h +#include zlib.h + +#undef AW_EMAC_DEBUG + +#ifdef AW_EMAC_DEBUG +#define debug(...) \ +do {\ +fprintf(stderr, allwinner_emac : %s: , __func__);\ +fprintf(stderr, ## __VA_ARGS__);\ +} while (0) +#else +#define debug(...) do {} while (0) +#endif For debug macros, its better to use a regular if (DEBUG_SYMBOL) so the body of the macro always gets compile tested. We have had incidences where major change patterns break stripped debug instrumentation because the code is compiled out. + +static void mii_set_link(AwEmacMii *mii, bool link_ok) +{ +if (link_ok) { +mii-bmsr |= MII_BMSR_LINK_ST; +mii-anlpar |= MII_ANAR_TXFD | MII_ANAR_TX | MII_ANAR_10FD | + MII_ANAR_10 | MII_ANAR_CSMACD; +} else { +mii-bmsr = ~MII_BMSR_LINK_ST; +mii-anlpar = MII_ANAR_TX; +} +mii-link_ok = link_ok; +} + +static void mii_reset(AwEmacMii *mii) +{ +mii-bmcr = MII_BMCR_FD | MII_BMCR_AUTOEN | MII_BMCR_SPEED; +mii-bmsr = MII_BMSR_100TX_FD | MII_BMSR_100TX_HD | MII_BMSR_10T_FD | +MII_BMSR_10T_HD | MII_BMSR_MFPS | MII_BMSR_AUTONEG; +mii-anar = MII_ANAR_TXFD | MII_ANAR_TX | MII_ANAR_10FD | MII_ANAR_10 | +MII_ANAR_CSMACD; +mii-anlpar = MII_ANAR_TX; +mii_set_link(mii, mii-link_ok); +} + +static uint16_t mii_read(AwEmacMii *mii, uint8_t phy_addr, uint8_t reg) +{ +uint16_t ret = 0x; + +if (phy_addr == BOARD_PHY_ADDRESS) { +switch (reg) { +case MII_BMCR: +ret = mii-bmcr; +break; +case MII_BMSR: +ret = mii-bmsr; +break; +case MII_PHYID1: +ret = RTL8201CP_PHYID1; +break; +case MII_PHYID2: +ret = RTL8201CP_PHYID2; +break; +case MII_ANAR: +
Re: [Qemu-devel] [PATCH target-arm v1 1/1] target-arm/helper: remove raw_read|write duplication
On 2 January 2014 07:58, Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: There is an inline duplication of the raw_read and raw_write function bodies. Fix by just calling raw_read/raw_write instead. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Reviewed-by: Peter Maydell peter.mayd...@linaro.org thanks -- PMM
Re: [Qemu-devel] [PATCH] hw/misc/blob-loader: add a generic blob loader
On Thu, Jan 2, 2014 at 6:21 PM, Paolo Bonzini pbonz...@redhat.com wrote: Il 02/01/2014 06:50, Peter Crosthwaite ha scritto: On Thu, Jan 2, 2014 at 3:35 PM, Li Guang lig.f...@cn.fujitsu.com wrote: this blob loader will be used to load a specified blob into a specified RAM address. Suggested-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Signed-off-by: Li Guang lig.f...@cn.fujitsu.com --- it can be used now for allwinner-a10, like: -device blob-loader,addr=0x4300,file=/path/script.bin reference: http://linux-sunxi.org/Sunxi-tools script file address: http://dl.dbank.com/c00aonvlmw Thanks to Peter Crosthwaite for the idea! --- default-configs/arm-softmmu.mak |2 + hw/misc/Makefile.objs |2 + hw/misc/blob-loader.c | 75 +++ 3 files changed, 79 insertions(+), 0 deletions(-) create mode 100644 hw/misc/blob-loader.c diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index ce1d620..50c71a6 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -87,3 +87,5 @@ CONFIG_INTEGRATOR_DEBUG=y CONFIG_ALLWINNER_A10_PIT=y CONFIG_ALLWINNER_A10_PIC=y CONFIG_ALLWINNER_A10=y + +CONFIG_BLOB_LOADER=y This shouldn't be arm specific. I would make the argument that the blob loader has global validity. diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index f674365..df28288 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -42,3 +42,5 @@ obj-$(CONFIG_SLAVIO) += slavio_misc.o obj-$(CONFIG_ZYNQ) += zynq_slcr.o obj-$(CONFIG_PVPANIC) += pvpanic.o + +obj-$(CONFIG_BLOB_LOADER) += blob-loader.o diff --git a/hw/misc/blob-loader.c b/hw/misc/blob-loader.c new file mode 100644 index 000..d7f1408 --- /dev/null +++ b/hw/misc/blob-loader.c @@ -0,0 +1,75 @@ +#include hw/sysbus.h +#include hw/devices.h +#include hw/loader.h +#include qemu/error-report.h + +typedef struct BlobLoaderState { /* private /* +DeviceState qdev; parent_obj; /* public /* +uint32_t addr; uint64_t or hwaddr. Blob loading shouldn't be limited to 32 bit. +char *file; +} BlobLoaderState; + +#define TYPE_BLOB_LOADER blob-loader +#define BLOB_LOADER(obj) OBJECT_CHECK(BlobLoaderState, (obj), TYPE_BLOB_LOADER) + +static Property blob_loader_props[] = { +DEFINE_PROP_UINT32(addr, BlobLoaderState, addr, 0), +DEFINE_PROP_STRING(file, BlobLoaderState, file), +DEFINE_PROP_END_OF_LIST(), +}; + +static void do_blob_load(BlobLoaderState *s) +{ +char *file_name; +int file_size; + +if (s-file == NULL) { +error_report(please spicify a file for blob loader\n); +return; Should you exit(1)? Better yet, return true for error and .. +} +file_name = qemu_find_file(QEMU_FILE_TYPE_BIOS, s-file); +if (file_name == NULL) { +error_report(can't find %s\n, s-file); +return; +} +file_size = get_image_size(file_name); +if (file_size 0) { +error_report(can't get file size of %s\n, file_name); +return; +} +if (load_image_targphys(file_name, s-addr, file_size) 0) { +error_report(can't load %s\n, file_name); +return; +} +} + +static int blob_loader_init(DeviceState *dev) +{ +BlobLoaderState *s = BLOB_LOADER(dev); + +do_blob_load(s); exit(1) here. No, please use realize and avoid init. This way you can use an Error* to report the error. Also, the actual load_image_targphys call probably should be done in a reset handler, not at realize time. Ok I think that settles it. The actual blobbing needs to happen at reset time. Perhaps the correct approach is to do as much as possible (file-path / address sanitsation etc) at realize time, then only the actual blob load happens at reset. Going on what Paolo said, I think for this device ::init is actually a nop. Paolo +return 0; +} + +static void blob_loader_class_init(ObjectClass *klass, void *data) s/klass/oc. Actually klass is quite commonly used. Yeh, I remember being told off for that one though :) Regards, Peter Paolo +{ +DeviceClass *dc = DEVICE_CLASS(klass); + +dc-props = blob_loader_props; +dc-desc = blob loader; +dc-init = blob_loader_init; I'm wondering whether blob loading is actually a reset step not an init. Will doing it at init will play foul with VMSD, as your blob loader will trample non-reset state on machine restore? Regards, Peter +} + +static TypeInfo blob_loader_info = { +.name = TYPE_BLOB_LOADER, +.parent= TYPE_DEVICE, +.instance_size = sizeof(BlobLoaderState), +.class_init= blob_loader_class_init, +}; + +static void blob_loader_register_type(void) +{ +type_register_static(blob_loader_info); +} + +type_init(blob_loader_register_type) -- 1.7.2.5
[Qemu-devel] Query on Qemu 1.7.0 GDB server version
Hi All, Which version of gdbserver is implemented in the QEMU 1.7.0 ? We tried to connect ARM-DS5 debugger to Qemu with -s -S option enabled, but it did not work. I am getting following error when i try to connect from ARM DS-5 and run gdb command *continue* : ERROR(CMD441-TAD8-NAL60): ! Continuing failed ! Unable to run device gdbserver ! Remote gdbserver did not recognize message Regards, shabarish
Re: [Qemu-devel] [PATCH] hw/misc/blob-loader: add a generic blob loader
Il 02/01/2014 11:51, Peter Crosthwaite ha scritto: No, please use realize and avoid init. This way you can use an Error* to report the error. Also, the actual load_image_targphys call probably should be done in a reset handler, not at realize time. Ok I think that settles it. The actual blobbing needs to happen at reset time. Perhaps the correct approach is to do as much as possible (file-path / address sanitsation etc) at realize time, then only the actual blob load happens at reset. Going on what Paolo said, I think for this device ::init is actually a nop. Yeah, also because init is in fact a legacy interface to realize. Paolo
Re: [Qemu-devel] Query on Qemu 1.7.0 GDB server version
On 2 January 2014 12:13, shabarish s shabarish.sun...@gmail.com wrote: Which version of gdbserver is implemented in the QEMU 1.7.0 ? It's a custom implementation of the gdbstub protocol. There is no version number specified by the gdbstub protocol. The protocol design is that it is always backwards compatible, so older stubs will return a failure response for new commands they don't implement, and new stubs continue to support all the old commands. The debugger is expected to be either able to fall back to working in a way that works with old stubs, or to stop with a helpful error message (which is what it sounds like DS-5 has done here): ERROR(CMD441-TAD8-NAL60): ! Continuing failed ! Unable to run device gdbserver ! Remote gdbserver did not recognize message If you want to debug this further to see what DS-5 is actually trying to do, you need to find a way to dump the raw gdbstub packets it is sending and receiving. Then you can determine whether the problem is a bug in DS-5 (not implementing a good fallback for older debug stubs) or if it would be easier to implement some new feature in QEMU's debug stub. thanks -- PMM
Re: [Qemu-devel] [PATCH] HMP: snapshot_blkdev can not consider //root/sn1 and /root/sn1 as the same file
On 01/02/2014 01:55 AM, Stefan Hajnoczi wrote: Okay, I think we got side-tracked worrying about identifying identical files. The problem in your example is more fundamental. Here is what should have happened: (qemu) snapshot_blkdev drive-scsi0-0-0 /mnt/dir2/sn1 Could not create '/mnt/dir2/sn1': File exists The file was previously created with the name /mnt/dir1/sn1. Running snapshot_blkdev with /mnt/dir2/sn1 clobbers the file in your example. This is bad because it corrupts the backing chain. If QEMU uses O_CREAT | O_EXCL open(2) flags then creating the snapshot file fails and the user will not mistakingly overwrite sn1. However, QEMU does not use O_EXCL to create image files anywhere today (qemu-img or QEMU monitor commands). Returning an error is not backwards-compatible since existing users might rely on clobbering files (there are safe cases where it can be useful). In fact, libvirt _requires_ that you clobber existing image files - when libvirt drives qemu with SELinux labelling enabled, then qemu cannot create files, but can only open already existing files that have already been labelled. So libvirt would need a way to avoid O_EXCL, even if you add it and make it default (and if you change the default to O_EXCL, you also need to provide a way to probe for the new switch that can bypass that new default). We could add an option to commands that create files but I'm not sure if it's worth the effort since human users who are most at risk probably won't provide this new option... Changing to be safe by default and requiring a new option to allow reuse of existing files might be okay; but it will be backwards incompatible. Keeping existing behavior and requiring a new option to turn on O_EXCL for safety is back-compat friendly, but is the very situation where users aren't going to know they need to use the new option, so you've gained no safety. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
[Qemu-devel] ignore plz, for test
RT
Re: [Qemu-devel] Vhost and vhost-net support for userspace based backends
Hi I had saw that user-space vhost is being developed, It is really a great job, I had tried to do same work but failed. I want to do same test for estimating benefit of it. Is there any vhost-api that demo-thread could call? Or Is there any test result that could see?
Re: [Qemu-devel] [PATCH v2 1/1] qtest: Fix the bug about disabling vnc causes make check hang
Am 02.01.2014 09:15, schrieb Paolo Bonzini: Il 31/12/2013 05:42, Kewei Yu ha scritto: When we disabling vnc from ./configure, the qemu can't use the vnc option. So qtest can't use the vnc -none , otherwise make check will hang. Signed-off-by: Kewei Yu kewe...@gmail.com --- v2: Consolidate VNC macro's #ifdef'ery to one central point (tests/libqtest.c). What happens if qtest instead uses -display none? It does use that, since the commit I pointed to in v1. :) Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH v2 1/1] qtest: Fix the bug about disabling vnc causes make check hang
Am 01.01.2014 05:40, schrieb Peter Crosthwaite: On Tue, Dec 31, 2013 at 11:29 PM, Kewei Yu kewe...@gmail.com wrote: 2013/12/31 Peter Crosthwaite peter.crosthwa...@xilinx.com On Tue, Dec 31, 2013 at 2:42 PM, Kewei Yu kewe...@gmail.com wrote: When we disabling vnc from ./configure, the qemu can't use the vnc option. [...] So qtest can't use the vnc -none , otherwise make check will hang. Curious, why exactly does make check hang? Shouldn't it just fail with an error result in this case? Yeah, there is an error result VNC support is disabled. I think its just terminology then. s/hangs/fails. Actually no. When qtest gets an unsupported command line argument, so that QEMU exits right away, then qtest hangs, waiting for the process. This was easily reproducible by mistyping machine names in my qom-test. That's a separate issue though. Regards, Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH 1/2] hw/net: add support for Allwinner EMAC Fast Ethernet controller
On Thu, Jan 02, 2014 at 08:25:10PM +1000, Peter Crosthwaite wrote: +#undef AW_EMAC_DEBUG + +#ifdef AW_EMAC_DEBUG +#define debug(...) \ +do {\ +fprintf(stderr, allwinner_emac : %s: , __func__);\ +fprintf(stderr, ## __VA_ARGS__);\ +} while (0) +#else +#define debug(...) do {} while (0) +#endif For debug macros, its better to use a regular if (DEBUG_SYMBOL) so the body of the macro always gets compile tested. We have had incidences where major change patterns break stripped debug instrumentation because the code is compiled out. Ok. + +static void mii_set_link(AwEmacMii *mii, bool link_ok) +{ +if (link_ok) { +mii-bmsr |= MII_BMSR_LINK_ST; +mii-anlpar |= MII_ANAR_TXFD | MII_ANAR_TX | MII_ANAR_10FD | + MII_ANAR_10 | MII_ANAR_CSMACD; +} else { +mii-bmsr = ~MII_BMSR_LINK_ST; +mii-anlpar = MII_ANAR_TX; +} +mii-link_ok = link_ok; +} + +static void mii_reset(AwEmacMii *mii) +{ +mii-bmcr = MII_BMCR_FD | MII_BMCR_AUTOEN | MII_BMCR_SPEED; +mii-bmsr = MII_BMSR_100TX_FD | MII_BMSR_100TX_HD | MII_BMSR_10T_FD | +MII_BMSR_10T_HD | MII_BMSR_MFPS | MII_BMSR_AUTONEG; +mii-anar = MII_ANAR_TXFD | MII_ANAR_TX | MII_ANAR_10FD | MII_ANAR_10 | +MII_ANAR_CSMACD; +mii-anlpar = MII_ANAR_TX; +mii_set_link(mii, mii-link_ok); +} + +static uint16_t mii_read(AwEmacMii *mii, uint8_t phy_addr, uint8_t reg) +{ +uint16_t ret = 0x; + +if (phy_addr == BOARD_PHY_ADDRESS) { +switch (reg) { +case MII_BMCR: +ret = mii-bmcr; +break; +case MII_BMSR: +ret = mii-bmsr; +break; +case MII_PHYID1: +ret = RTL8201CP_PHYID1; +break; +case MII_PHYID2: +ret = RTL8201CP_PHYID2; +break; +case MII_ANAR: +ret = mii-anar; +break; +case MII_ANLPAR: +ret = mii-anlpar; +break; +default: +debug(unknown mii register %x\n, reg); +ret = 0; +} +} +return ret; +} + +static void mii_write(AwEmacMii *mii, uint8_t phy_addr, uint8_t reg, + uint16_t value) +{ +if (phy_addr == BOARD_PHY_ADDRESS) { +switch (reg) { +case MII_BMCR: +if (value MII_BMCR_RESET) { +mii_reset(mii); +} else { +mii-bmcr = value; +} +break; +case MII_BMSR: +case MII_PHYID1: +case MII_PHYID2: +case MII_ANLPAR: +qemu_log_mask(LOG_GUEST_ERROR, %s: write to mii register %x\n, + __func__, reg); +break; +case MII_ANAR: +mii-anar = value; +break; +default: +debug(unknown mii register %x\n, reg); +} +} +} + +static void aw_emac_update_irq(AwEmacState *s) +{ +qemu_set_irq(s-irq, (s-int_sta s-int_ctl) != 0); +} + +static int aw_emac_can_receive(NetClientState *nc) +{ +AwEmacState *s = qemu_get_nic_opaque(nc); + +return (s-ctl EMAC_CTL_RX_EN) (s-num_rx MAX_RX); If you return false from a can_recieve(), you need to explictly flush queued packets (qemu_flush_queued_packets()) when the blocking condition is lifted, heres a good example a bugfix patch addressing this issue for another mac: http://lists.gnu.org/archive/html/qemu-devel/2013-11/msg02255.html Ok. +} + +static ssize_t aw_emac_receive(NetClientState *nc, const uint8_t *buf, + size_t size) +{ +AwEmacState *s = qemu_get_nic_opaque(nc); +uint32_t *fifo; +uint32_t crc; +char *dest; + +if (s-num_rx = MAX_RX) { +debug(rx queue full - packed dropped\n); +return -1; +} + +if (size + RX_HDR_SIZE FIFO_SIZE) { +debug(packet too big\n); +return -1; +} + +fifo = s-rx_fifos[(s-first_rx + s-num_rx) % MAX_RX]; +dest = (char *)fifo[2]; +s-num_rx++; + +memcpy(dest, buf, size); + +/* Fill to minimum frame length */ +if (size 60) { +memset(dest + size, 0, 60 - size); +size = 60; +} + +/* Append FCS */ +crc = crc32(~0, buf, size); +memcpy(dest + size, crc, 4); + +fifo[0] = EMAC_UNDOCUMENTED_MAGIC; +fifo[1] = EMAC_RX_HEADER(size + 4, EMAC_RX_IO_DATA_STATUS_OK); + +/* Set rx interrupt flag */ +s-int_sta |= EMAC_INT_RX; +aw_emac_update_irq(s); + +return size; +} + +static void
Re: [Qemu-devel] [PATCH] spapr_vscsi: Fix REPORT_LUNS handling
On 12/02/13 12:58, Paolo Bonzini wrote: Il 02/12/2013 18:51, Nathan Whitehorn ha scritto: Any news on this? FreeBSD is unbootable from CDROM devices in QEMU/pseries without this patch. -Nathan Acked-by: Paolo Bonzini pbonz...@redhat.com Alex, can you pick it up? Any updates? -Nathan
[Qemu-devel] [PATCH] Add the ability to vary Spice playback and record rates, to facilitate Opus support.
Signed-off-by: Jeremy White jwh...@codeweavers.com --- audio/spiceaudio.c | 27 +-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index 5af436c..fceee50 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -25,8 +25,17 @@ #include audio.h #include audio_int.h -#define LINE_IN_SAMPLES 1024 -#define LINE_OUT_SAMPLES 1024 +#if SPICE_INTERFACE_PLAYBACK_MAJOR 1 || SPICE_INTERFACE_PLAYBACK_MINOR = 3 +#define LINE_OUT_SAMPLES (480 * 4) +#else +#define LINE_OUT_SAMPLES (256 * 4) +#endif + +#if SPICE_INTERFACE_RECORD_MAJOR 2 || SPICE_INTERFACE_RECORD_MINOR = 3 +#define LINE_IN_SAMPLES (480 * 4) +#else +#define LINE_IN_SAMPLES (256 * 4) +#endif typedef struct SpiceRateCtl { int64_t start_ticks; @@ -111,7 +120,11 @@ static int line_out_init (HWVoiceOut *hw, struct audsettings *as) SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw); struct audsettings settings; +#if SPICE_INTERFACE_PLAYBACK_MAJOR 1 || SPICE_INTERFACE_PLAYBACK_MINOR = 3 +settings.freq = spice_server_get_best_playback_rate(NULL); +#else settings.freq = SPICE_INTERFACE_PLAYBACK_FREQ; +#endif settings.nchannels = SPICE_INTERFACE_PLAYBACK_CHAN; settings.fmt= AUD_FMT_S16; settings.endianness = AUDIO_HOST_ENDIANNESS; @@ -122,6 +135,9 @@ static int line_out_init (HWVoiceOut *hw, struct audsettings *as) out-sin.base.sif = playback_sif.base; qemu_spice_add_interface (out-sin.base); +#if SPICE_INTERFACE_PLAYBACK_MAJOR 1 || SPICE_INTERFACE_PLAYBACK_MINOR = 3 +spice_server_set_playback_rate(out-sin, settings.freq); +#endif return 0; } @@ -232,7 +248,11 @@ static int line_in_init (HWVoiceIn *hw, struct audsettings *as) SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw); struct audsettings settings; +#if SPICE_INTERFACE_RECORD_MAJOR 2 || SPICE_INTERFACE_RECORD_MINOR = 3 +settings.freq = spice_server_get_best_record_rate(NULL); +#else settings.freq = SPICE_INTERFACE_RECORD_FREQ; +#endif settings.nchannels = SPICE_INTERFACE_RECORD_CHAN; settings.fmt= AUD_FMT_S16; settings.endianness = AUDIO_HOST_ENDIANNESS; @@ -243,6 +263,9 @@ static int line_in_init (HWVoiceIn *hw, struct audsettings *as) in-sin.base.sif = record_sif.base; qemu_spice_add_interface (in-sin.base); +#if SPICE_INTERFACE_RECORD_MAJOR 2 || SPICE_INTERFACE_RECORD_MINOR = 3 +spice_server_set_record_rate(in-sin, settings.freq); +#endif return 0; } -- 1.7.10.4
Re: [Qemu-devel] [PATCH] spapr_vscsi: Fix REPORT_LUNS handling
On 18.10.2013, at 14:33, Nathan Whitehorn nwhiteh...@freebsd.org wrote: Intercept REPORT_LUNS commands addressed either to SRP LUN 0 or the well-known LUN for REPORT_LUNS commands. This is required to implement the SAM and SPC specifications. Since SRP implements only a single SCSI target port per connection, the SRP target is required to report all available LUNs in response to a REPORT_LUNS command addressed either to LUN 0 or the well-known LUN. Instead, QEMU was forwarding such requests to the first QEMU SCSI target, with the result that initiators that relied on this feature would only see LUNs on the first QEMU SCSI target. Behavior for REPORT_LUNS commands addressed to any other LUN is not specified by the standard and so is left unchanged. This preserves behavior under Linux and SLOF, which enumerate possible LUNs by hand and so address no commands either to LUN 0 or the well-known REPORT_LUNS LUN. Signed-off-by: Nathan Whitehorn nwhiteh...@freebsd.org This patch fails on checkpatch.pl. Please fix those warnings up :). WARNING: braces {} are necessary for all arms of this statement #65: FILE: hw/scsi/spapr_vscsi.c:738: +if (dev-channel == 0 dev-id == 0 dev-lun == 0) [...] WARNING: braces {} are necessary for all arms of this statement #81: FILE: hw/scsi/spapr_vscsi.c:754: +if (dev-id == 0 dev-channel == 0) [...] +else [...] WARNING: line over 80 characters #108: FILE: hw/scsi/spapr_vscsi.c:781: +if ((srp-cmd.lun == 0 || be64_to_cpu(srp-cmd.lun) == SRP_REPORT_LUNS_WLUN) srp-cmd.cdb[0] == REPORT_LUNS) { total: 0 errors, 3 warnings, 75 lines checked Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. --- hw/scsi/spapr_vscsi.c | 57 +++ 1 file changed, 57 insertions(+) diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index 2a26042..87e0fb3 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -63,6 +63,8 @@ #define SCSI_SENSE_BUF_SIZE 96 #define SRP_RSP_SENSE_DATA_LEN 18 +#define SRP_REPORT_LUNS_WLUN0xc101000 + typedef union vscsi_crq { struct viosrp_crq s; uint8_t raw[16]; @@ -720,12 +722,67 @@ static void vscsi_inquiry_no_target(VSCSIState *s, vscsi_req *req) } } +static void vscsi_report_luns(VSCSIState *s, vscsi_req *req) +{ +BusChild *kid; +int i, len, n, rc; +uint8_t *resp_data; +bool found_lun0; + +n = 0; +found_lun0 = false; +QTAILQ_FOREACH(kid, s-bus.qbus.children, sibling) { +SCSIDevice *dev = SCSI_DEVICE(kid-child); + +n += 8; +if (dev-channel == 0 dev-id == 0 dev-lun == 0) +found_lun0 = true; +} +if (!found_lun0) { +n += 8; +} +len = n+8; Let me try to grasp what you're doing here. You're trying to figure out how many devices there are attached to the bus. For every device you reserve a buffer block. Lun0 is mandatory, all others are optional. First off, I think the code would be easier to grasp if you'd count number of entries rather than number of bytes. That way we don't have to mentally deal with the 8 byte block granularity. Then IIUC you're jumping through a lot of hoops to count lun0 if it's there, but keep it reserved when it's not there. Why don't you just always reserve entry 0 for lun0? In the loop where you're actually filling in data you just skip lun0. Or is lun0 a terminator and always has to come last? + +resp_data = malloc(len); g_malloc0 +memset(resp_data, 0, len); +stl_be_p(resp_data, n); +i = found_lun0 ? 8 : 16; +QTAILQ_FOREACH(kid, s-bus.qbus.children, sibling) { +DeviceState *qdev = kid-child; +SCSIDevice *dev = SCSI_DEVICE(qdev); + +if (dev-id == 0 dev-channel == 0) +resp_data[i] = 0; +else +resp_data[i] = (2 6); +resp_data[i] |= dev-id; +resp_data[i+1] = (dev-channel 5); +resp_data[i+1] |= dev-lun; +i += 8; +} + +vscsi_preprocess_desc(req); +rc = vscsi_srp_transfer_data(s, req, 0, resp_data, len); +free(resp_data); g_free Alex +if (rc 0) { +vscsi_makeup_sense(s, req, HARDWARE_ERROR, 0, 0); +vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0); +} else { +vscsi_send_rsp(s, req, 0, len - rc, 0); +} +} + static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req) { union srp_iu *srp = req-iu.srp; SCSIDevice *sdev; int n, lun; +if ((srp-cmd.lun == 0 || be64_to_cpu(srp-cmd.lun) == SRP_REPORT_LUNS_WLUN) srp-cmd.cdb[0] == REPORT_LUNS) { +vscsi_report_luns(s, req); +return 0; +} + sdev = vscsi_device_find(s-bus, be64_to_cpu(srp-cmd.lun), lun); if (!sdev) { DPRINTF(VSCSI: Command for lun %08 PRIx64 with no
Re: [Qemu-devel] [Qemu-ppc] [PATCH] spapr_vscsi: Fix REPORT_LUNS handling
On 02.01.2014, at 16:31, Alexander Graf ag...@suse.de wrote: On 18.10.2013, at 14:33, Nathan Whitehorn nwhiteh...@freebsd.org wrote: Intercept REPORT_LUNS commands addressed either to SRP LUN 0 or the well-known LUN for REPORT_LUNS commands. This is required to implement the SAM and SPC specifications. Since SRP implements only a single SCSI target port per connection, the SRP target is required to report all available LUNs in response to a REPORT_LUNS command addressed either to LUN 0 or the well-known LUN. Instead, QEMU was forwarding such requests to the first QEMU SCSI target, with the result that initiators that relied on this feature would only see LUNs on the first QEMU SCSI target. Behavior for REPORT_LUNS commands addressed to any other LUN is not specified by the standard and so is left unchanged. This preserves behavior under Linux and SLOF, which enumerate possible LUNs by hand and so address no commands either to LUN 0 or the well-known REPORT_LUNS LUN. Signed-off-by: Nathan Whitehorn nwhiteh...@freebsd.org This patch fails on checkpatch.pl. Please fix those warnings up :). WARNING: braces {} are necessary for all arms of this statement #65: FILE: hw/scsi/spapr_vscsi.c:738: +if (dev-channel == 0 dev-id == 0 dev-lun == 0) [...] WARNING: braces {} are necessary for all arms of this statement #81: FILE: hw/scsi/spapr_vscsi.c:754: +if (dev-id == 0 dev-channel == 0) [...] +else [...] WARNING: line over 80 characters #108: FILE: hw/scsi/spapr_vscsi.c:781: +if ((srp-cmd.lun == 0 || be64_to_cpu(srp-cmd.lun) == SRP_REPORT_LUNS_WLUN) srp-cmd.cdb[0] == REPORT_LUNS) { total: 0 errors, 3 warnings, 75 lines checked Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. --- hw/scsi/spapr_vscsi.c | 57 +++ 1 file changed, 57 insertions(+) diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index 2a26042..87e0fb3 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -63,6 +63,8 @@ #define SCSI_SENSE_BUF_SIZE 96 #define SRP_RSP_SENSE_DATA_LEN 18 +#define SRP_REPORT_LUNS_WLUN0xc101000 + typedef union vscsi_crq { struct viosrp_crq s; uint8_t raw[16]; @@ -720,12 +722,67 @@ static void vscsi_inquiry_no_target(VSCSIState *s, vscsi_req *req) } } +static void vscsi_report_luns(VSCSIState *s, vscsi_req *req) +{ +BusChild *kid; +int i, len, n, rc; +uint8_t *resp_data; +bool found_lun0; + +n = 0; +found_lun0 = false; +QTAILQ_FOREACH(kid, s-bus.qbus.children, sibling) { +SCSIDevice *dev = SCSI_DEVICE(kid-child); + +n += 8; +if (dev-channel == 0 dev-id == 0 dev-lun == 0) +found_lun0 = true; +} +if (!found_lun0) { +n += 8; +} +len = n+8; Let me try to grasp what you're doing here. You're trying to figure out how many devices there are attached to the bus. For every device you reserve a buffer block. Lun0 is mandatory, all others are optional. First off, I think the code would be easier to grasp if you'd count number of entries rather than number of bytes. That way we don't have to mentally deal with the 8 byte block granularity. Then IIUC you're jumping through a lot of hoops to count lun0 if it's there, but keep it reserved when it's not there. Why don't you just always reserve entry 0 for lun0? In the loop where you're actually filling in data you just skip lun0. Or is lun0 a terminator and always has to come last? + +resp_data = malloc(len); g_malloc0 +memset(resp_data, 0, len); +stl_be_p(resp_data, n); +i = found_lun0 ? 8 : 16; +QTAILQ_FOREACH(kid, s-bus.qbus.children, sibling) { +DeviceState *qdev = kid-child; +SCSIDevice *dev = SCSI_DEVICE(qdev); + +if (dev-id == 0 dev-channel == 0) +resp_data[i] = 0; +else +resp_data[i] = (2 6); Ah, I almost forgot this one. Please convert that into something more verbose through a define. Whatever that bit means ... :). +resp_data[i] |= dev-id; +resp_data[i+1] = (dev-channel 5); +resp_data[i+1] |= dev-lun; What are the other 6 bytes reserved for? Alex
[Qemu-devel] Query on Qemu 1.7.0 GDB Server version
Hi All, Which version of gdbserver is implemented in the QEMU 1.7.0 ? We tried to connect ARM-DS5 debugger to Qemu with -s -S option enabled, but it did not work. I am getting following error when i try to connect from ARM DS-5 and run gdb command *continue* : ERROR(CMD441-TAD8-NAL60): ! Continuing failed ! Unable to run device gdbserver ! Remote gdbserver did not recognize message Regards, shabarish
Re: [Qemu-devel] [Qemu-ppc] [PATCH] spapr_vscsi: Fix REPORT_LUNS handling
On Thu, Jan 2, 2014 at 7:41 AM, Alexander Graf ag...@suse.de wrote: On 02.01.2014, at 16:31, Alexander Graf ag...@suse.de wrote: On 18.10.2013, at 14:33, Nathan Whitehorn nwhiteh...@freebsd.org wrote: Intercept REPORT_LUNS commands addressed either to SRP LUN 0 or the well-known LUN for REPORT_LUNS commands. This is required to implement the SAM and SPC specifications. Since SRP implements only a single SCSI target port per connection, the SRP target is required to report all available LUNs in response to a REPORT_LUNS command addressed either to LUN 0 or the well-known LUN. Instead, QEMU was forwarding such requests to the first QEMU SCSI target, with the result that initiators that relied on this feature would only see LUNs on the first QEMU SCSI target. Behavior for REPORT_LUNS commands addressed to any other LUN is not specified by the standard and so is left unchanged. This preserves behavior under Linux and SLOF, which enumerate possible LUNs by hand and so address no commands either to LUN 0 or the well-known REPORT_LUNS LUN. Signed-off-by: Nathan Whitehorn nwhiteh...@freebsd.org This patch fails on checkpatch.pl. Please fix those warnings up :). WARNING: braces {} are necessary for all arms of this statement #65: FILE: hw/scsi/spapr_vscsi.c:738: +if (dev-channel == 0 dev-id == 0 dev-lun == 0) [...] WARNING: braces {} are necessary for all arms of this statement #81: FILE: hw/scsi/spapr_vscsi.c:754: +if (dev-id == 0 dev-channel == 0) [...] +else [...] WARNING: line over 80 characters #108: FILE: hw/scsi/spapr_vscsi.c:781: +if ((srp-cmd.lun == 0 || be64_to_cpu(srp-cmd.lun) == SRP_REPORT_LUNS_WLUN) srp-cmd.cdb[0] == REPORT_LUNS) { total: 0 errors, 3 warnings, 75 lines checked Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. --- hw/scsi/spapr_vscsi.c | 57 +++ 1 file changed, 57 insertions(+) diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index 2a26042..87e0fb3 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -63,6 +63,8 @@ #define SCSI_SENSE_BUF_SIZE 96 #define SRP_RSP_SENSE_DATA_LEN 18 +#define SRP_REPORT_LUNS_WLUN0xc101000 + typedef union vscsi_crq { struct viosrp_crq s; uint8_t raw[16]; @@ -720,12 +722,67 @@ static void vscsi_inquiry_no_target(VSCSIState *s, vscsi_req *req) } } +static void vscsi_report_luns(VSCSIState *s, vscsi_req *req) +{ +BusChild *kid; +int i, len, n, rc; +uint8_t *resp_data; +bool found_lun0; + +n = 0; +found_lun0 = false; +QTAILQ_FOREACH(kid, s-bus.qbus.children, sibling) { +SCSIDevice *dev = SCSI_DEVICE(kid-child); + +n += 8; +if (dev-channel == 0 dev-id == 0 dev-lun == 0) +found_lun0 = true; +} +if (!found_lun0) { +n += 8; +} +len = n+8; Let me try to grasp what you're doing here. You're trying to figure out how many devices there are attached to the bus. For every device you reserve a buffer block. Lun0 is mandatory, all others are optional. First off, I think the code would be easier to grasp if you'd count number of entries rather than number of bytes. That way we don't have to mentally deal with the 8 byte block granularity. Then IIUC you're jumping through a lot of hoops to count lun0 if it's there, but keep it reserved when it's not there. Why don't you just always reserve entry 0 for lun0? In the loop where you're actually filling in data you just skip lun0. Or is lun0 a terminator and always has to come last? + +resp_data = malloc(len); g_malloc0 +memset(resp_data, 0, len); +stl_be_p(resp_data, n); +i = found_lun0 ? 8 : 16; +QTAILQ_FOREACH(kid, s-bus.qbus.children, sibling) { +DeviceState *qdev = kid-child; +SCSIDevice *dev = SCSI_DEVICE(qdev); + +if (dev-id == 0 dev-channel == 0) +resp_data[i] = 0; +else +resp_data[i] = (2 6); This looks odd. Shouldn't this rather be resp_data[i] = (1 6); to set the LUN address method to 01b meaning Single Level LUN structure. (SAM5 4.7.3) He is setting the address method to 10b but there is no such address method afaik. Ah, I almost forgot this one. Please convert that into something more verbose through a define. Whatever that bit means ... :). +resp_data[i] |= dev-id; He should do something like : resp_data[i] |= dev-id 0x3f; here to avoid a dev-id 63 from spilling into the address method field. Or probably should have a check for if dev-id 3 then fail +resp_data[i+1] = (dev-channel 5); +resp_data[i+1] |= dev-lun; What are the other 6 bytes reserved for? Alex
Re: [Qemu-devel] TRIM/DISCARD/UNMAP support on qemu-nbd
On Mon, Dec 30, 2013 at 07:58:29PM +0800, Teng-Feng Yang wrote: I have been studying QCOW2 file format for a couple of days, and I am a little bit confused about whether QCOW2 supports UNMAP or not. As I surf through internet, some mailing list discussion had mentioned that qemu-nbd and nbd module both support UNMAP command. So I follow the steps below on my machine (Ubuntu 13.10 with linux kernel 3.12) to test if qemu-nbd and QCOW2 do support UNMAP. 1. Create a qcow2 file via qemu-img sudo qemu-img create -f qcow2 -o cluster_size=524288 base.qcow2 1G 2. Connect this qcow2 file with qemu-nbd sudo qemu-nbd -c /dev/nbd0 base.qcow2 --discard=unmap 3. Use sg_unmap command to issue UNMAP command to this NBD sudo sg_unmap --lba=0 --num=1 /dev/nbd0 Everytime I get the following error message: unmap cdb: 42 00 00 00 00 00 00 00 18 00 unmap: pass through os error: Inappropriate ioctl for device UNMAP failed (use '-v' to get more information) I also try to format this nbd device with EXT4 and mount it, but still cannot perform fstrim on the mount point. Have I done anything wrong? There are a lot of factors for getting unmap/discard/trim to work, including: - guest tools (sg_unmap) or guest filesystem must support it - guest kernel must support it - host qemu must support it - host filesystem/etc must support it My (possibly weak) understanding of the upstream qemu code is that unmap/discard/trim is not supported in qcow2. It is only supported in raw files when using a POSIX-like host OS which has either of: - block devices supporting BLKDISCARDZEROES - files on XFS - files on other filesystems that support FALLOC_FL_PUNCH_HOLE (eg ext4) Having said that, I did some tests using libguestfs and I could not show that unmap was working, either using raw or qcow2 (both on ext4), with virtio-scsi, and recent kernel qemu. I did not see any errors, but also I don't see what I'm doing wrong. Attached is my test script. You will need to compile libguestfs with: ./configure --with-extra-packages=sg3_utils The results on my machine are: $ /tmp/sparsetest.sh 0 /tmp/test1 0 /tmp/test2 Read Capacity results: Protection: prot_en=0, p_type=0, p_i_exponent=0 Logical block provisioning: lbpme=1, lbprz=0 Last logical block address=204799 (0x31fff), Number of logical blocks=204800 Logical block length=512 bytes Logical blocks per physical block exponent=0 Lowest aligned logical block address=0 Hence: Device size: 104857600 bytes, 100.0 MiB, 0.10 GB Block limits VPD page (SBC): Write same no zero (WSNZ): 1 Maximum compare and write length: 0 blocks Optimal transfer length granularity: 0 blocks Maximum transfer length: 0 blocks Optimal transfer length: 0 blocks Maximum prefetch length: 0 blocks Maximum unmap LBA count: 0 Maximum unmap block descriptor count: 0 Optimal unmap granularity: 8 Unmap granularity alignment valid: 0 Unmap granularity alignment: 0 Maximum write same length: 0x0 blocks 16M /tmp/test1 --- note no sparseness is created 16M /tmp/test2 Please let us know if you get this working, because I'd really like to fix virt-sparsify so it can work in-place! Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v sparsetest.sh Description: Bourne shell script
[Qemu-devel] [PATCH] migration: qmp_migrate(): keep working after syntax error
If a user or QMP client enter a bad syntax for the migrate command in QMP/HMP, then the migrate command will never succeed from that point on. For example, if you enter: (qemu) migrate tcp;0: migrate: Parameter 'uri' expects a valid migration protocol Then the migrate command will always fail from now on: (qemu) migrate tcp:0: migrate: There's a migration process in progress The problem is that qmp_migrate() sets the migration status to MIG_STATE_SETUP and doesn't reset it on syntax error. This bug was introduced by commit 29ae8a4133082e16970c9d4be09f4b6a15034617. Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- migration.c | 1 + 1 file changed, 1 insertion(+) diff --git a/migration.c b/migration.c index 2b1ab20..557195a 100644 --- a/migration.c +++ b/migration.c @@ -437,6 +437,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, #endif } else { error_set(errp, QERR_INVALID_PARAMETER_VALUE, uri, a valid migration protocol); +s-state = MIG_STATE_ERROR; return; } -- 1.8.1.4
Re: [Qemu-devel] [PATCH 2/2] hw/arm/allwinner-a10: initialize EMAC
On Thu, Jan 02, 2014 at 08:20:12PM +1000, Peter Crosthwaite wrote: On Thu, Jan 2, 2014 at 7:18 PM, Beniamino Galvani b.galv...@gmail.com wrote: Signed-off-by: Beniamino Galvani b.galv...@gmail.com --- hw/arm/allwinner-a10.c | 20 include/hw/arm/allwinner-a10.h |4 2 files changed, 24 insertions(+) diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index 4658e19..155e026 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -22,6 +22,7 @@ static void aw_a10_init(Object *obj) { AwA10State *s = AW_A10(obj); +DeviceState *dev; For consistency with surrounding code, you could just cast to DEVICE include and drop the new local var. Ok. object_initialize(s-cpu, sizeof(s-cpu), cortex-a8- TYPE_ARM_CPU); object_property_add_child(obj, cpu, OBJECT(s-cpu), NULL); @@ -31,6 +32,14 @@ static void aw_a10_init(Object *obj) object_initialize(s-timer, sizeof(s-timer), TYPE_AW_A10_PIT); qdev_set_parent_bus(DEVICE(s-timer), sysbus_get_default()); + +if (nd_table[0].used) { So with SoC MACs, they are always there. I think this conditional should be removed, and the MAC is always instantiated. ... +qemu_check_nic_model(nd_table[0], allwinner_emac); +object_initialize(s-emac, sizeof(s-emac), TYPE_AW_EMAC); +dev = DEVICE(s-emac); +qdev_set_nic_properties(dev, nd_table[0]); ... and then only this is conditional on nd_table.used. The mac model itself then of course needs to be hardened against a null netargs. +qdev_set_parent_bus(dev, sysbus_get_default()); +} } So, if I understand correctly, the part under the condition should be: qdev_set_parent_bus(dev, sysbus_get_default()); right? static void aw_a10_realize(DeviceState *dev, Error **errp) @@ -76,6 +85,17 @@ static void aw_a10_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(sysbusdev, 4, s-irq[67]); sysbus_connect_irq(sysbusdev, 5, s-irq[68]); +if (nd_table[0].used) { +object_property_set_bool(OBJECT(s-emac), true, realized, err); +if (err != NULL) { +error_propagate(errp, err); +return; +} +sysbusdev = SYS_BUS_DEVICE(s-emac); +sysbus_mmio_map(sysbusdev, 0, AW_A10_EMAC_BASE); +sysbus_connect_irq(sysbusdev, 0, s-irq[55]); +} + serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2, s-irq[1], 115200, serial_hds[0], DEVICE_NATIVE_ENDIAN); } diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h index da36647..6ea5988 100644 --- a/include/hw/arm/allwinner-a10.h +++ b/include/hw/arm/allwinner-a10.h @@ -6,6 +6,7 @@ #include hw/arm/arm.h #include hw/timer/allwinner-a10-pit.h #include hw/intc/allwinner-a10-pic.h +#include hw/net/allwinner_emac.h #include sysemu/sysemu.h #include exec/address-spaces.h @@ -14,9 +15,11 @@ #define AW_A10_PIC_REG_BASE 0x01c20400 #define AW_A10_PIT_REG_BASE 0x01c20c00 #define AW_A10_UART0_REG_BASE 0x01c28000 +#define AW_A10_EMAC_BASE0x01c0b000 #define AW_A10_SDRAM_BASE 0x4000 + This whitespace change intended? No, a leftover. Thanks, Beniamino
Re: [Qemu-devel] [Qemu-ppc] [PATCH] spapr_vscsi: Fix REPORT_LUNS handling
On 01/02/14 10:41, Alexander Graf wrote: On 02.01.2014, at 16:31, Alexander Graf ag...@suse.de wrote: On 18.10.2013, at 14:33, Nathan Whitehorn nwhiteh...@freebsd.org wrote: Intercept REPORT_LUNS commands addressed either to SRP LUN 0 or the well-known LUN for REPORT_LUNS commands. This is required to implement the SAM and SPC specifications. Since SRP implements only a single SCSI target port per connection, the SRP target is required to report all available LUNs in response to a REPORT_LUNS command addressed either to LUN 0 or the well-known LUN. Instead, QEMU was forwarding such requests to the first QEMU SCSI target, with the result that initiators that relied on this feature would only see LUNs on the first QEMU SCSI target. Behavior for REPORT_LUNS commands addressed to any other LUN is not specified by the standard and so is left unchanged. This preserves behavior under Linux and SLOF, which enumerate possible LUNs by hand and so address no commands either to LUN 0 or the well-known REPORT_LUNS LUN. Signed-off-by: Nathan Whitehorn nwhiteh...@freebsd.org This patch fails on checkpatch.pl. Please fix those warnings up :). WARNING: braces {} are necessary for all arms of this statement #65: FILE: hw/scsi/spapr_vscsi.c:738: +if (dev-channel == 0 dev-id == 0 dev-lun == 0) [...] WARNING: braces {} are necessary for all arms of this statement #81: FILE: hw/scsi/spapr_vscsi.c:754: +if (dev-id == 0 dev-channel == 0) [...] +else [...] WARNING: line over 80 characters #108: FILE: hw/scsi/spapr_vscsi.c:781: +if ((srp-cmd.lun == 0 || be64_to_cpu(srp-cmd.lun) == SRP_REPORT_LUNS_WLUN) srp-cmd.cdb[0] == REPORT_LUNS) { total: 0 errors, 3 warnings, 75 lines checked Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. --- hw/scsi/spapr_vscsi.c | 57 +++ 1 file changed, 57 insertions(+) diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index 2a26042..87e0fb3 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -63,6 +63,8 @@ #define SCSI_SENSE_BUF_SIZE 96 #define SRP_RSP_SENSE_DATA_LEN 18 +#define SRP_REPORT_LUNS_WLUN0xc101000 + typedef union vscsi_crq { struct viosrp_crq s; uint8_t raw[16]; @@ -720,12 +722,67 @@ static void vscsi_inquiry_no_target(VSCSIState *s, vscsi_req *req) } } +static void vscsi_report_luns(VSCSIState *s, vscsi_req *req) +{ +BusChild *kid; +int i, len, n, rc; +uint8_t *resp_data; +bool found_lun0; + +n = 0; +found_lun0 = false; +QTAILQ_FOREACH(kid, s-bus.qbus.children, sibling) { +SCSIDevice *dev = SCSI_DEVICE(kid-child); + +n += 8; +if (dev-channel == 0 dev-id == 0 dev-lun == 0) +found_lun0 = true; +} +if (!found_lun0) { +n += 8; +} +len = n+8; Let me try to grasp what you're doing here. You're trying to figure out how many devices there are attached to the bus. For every device you reserve a buffer block. Lun0 is mandatory, all others are optional. First off, I think the code would be easier to grasp if you'd count number of entries rather than number of bytes. That way we don't have to mentally deal with the 8 byte block granularity. Then IIUC you're jumping through a lot of hoops to count lun0 if it's there, but keep it reserved when it's not there. Why don't you just always reserve entry 0 for lun0? In the loop where you're actually filling in data you just skip lun0. Or is lun0 a terminator and always has to come last? + +resp_data = malloc(len); g_malloc0 +memset(resp_data, 0, len); +stl_be_p(resp_data, n); +i = found_lun0 ? 8 : 16; +QTAILQ_FOREACH(kid, s-bus.qbus.children, sibling) { +DeviceState *qdev = kid-child; +SCSIDevice *dev = SCSI_DEVICE(qdev); + +if (dev-id == 0 dev-channel == 0) +resp_data[i] = 0; +else +resp_data[i] = (2 6); Ah, I almost forgot this one. Please convert that into something more verbose through a define. Whatever that bit means ... :). I've tried to maintain the existing (questionable) style here. See vscsi_device_find() for instance. This seemed like a bad occasion for a global style cleanup. +resp_data[i] |= dev-id; +resp_data[i+1] = (dev-channel 5); +resp_data[i+1] |= dev-lun; What are the other 6 bytes reserved for? It's the hierarchical LUN fields. vscsi_device_find() defines the LUN format used by this module if you are curious. -Nathan
Re: [Qemu-devel] [PATCH] spapr_vscsi: Fix REPORT_LUNS handling
On 01/02/14 10:31, Alexander Graf wrote: On 18.10.2013, at 14:33, Nathan Whitehorn nwhiteh...@freebsd.org wrote: Intercept REPORT_LUNS commands addressed either to SRP LUN 0 or the well-known LUN for REPORT_LUNS commands. This is required to implement the SAM and SPC specifications. Since SRP implements only a single SCSI target port per connection, the SRP target is required to report all available LUNs in response to a REPORT_LUNS command addressed either to LUN 0 or the well-known LUN. Instead, QEMU was forwarding such requests to the first QEMU SCSI target, with the result that initiators that relied on this feature would only see LUNs on the first QEMU SCSI target. Behavior for REPORT_LUNS commands addressed to any other LUN is not specified by the standard and so is left unchanged. This preserves behavior under Linux and SLOF, which enumerate possible LUNs by hand and so address no commands either to LUN 0 or the well-known REPORT_LUNS LUN. Signed-off-by: Nathan Whitehorn nwhiteh...@freebsd.org This patch fails on checkpatch.pl. Please fix those warnings up :). WARNING: braces {} are necessary for all arms of this statement #65: FILE: hw/scsi/spapr_vscsi.c:738: +if (dev-channel == 0 dev-id == 0 dev-lun == 0) [...] WARNING: braces {} are necessary for all arms of this statement #81: FILE: hw/scsi/spapr_vscsi.c:754: +if (dev-id == 0 dev-channel == 0) [...] +else [...] WARNING: line over 80 characters #108: FILE: hw/scsi/spapr_vscsi.c:781: +if ((srp-cmd.lun == 0 || be64_to_cpu(srp-cmd.lun) == SRP_REPORT_LUNS_WLUN) srp-cmd.cdb[0] == REPORT_LUNS) { total: 0 errors, 3 warnings, 75 lines checked Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. Will do. I'm traveling at the moment, so it may take a little while. If you felt like fixing it yourself, I'd appreciate it. --- hw/scsi/spapr_vscsi.c | 57 +++ 1 file changed, 57 insertions(+) diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index 2a26042..87e0fb3 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -63,6 +63,8 @@ #define SCSI_SENSE_BUF_SIZE 96 #define SRP_RSP_SENSE_DATA_LEN 18 +#define SRP_REPORT_LUNS_WLUN0xc101000 + typedef union vscsi_crq { struct viosrp_crq s; uint8_t raw[16]; @@ -720,12 +722,67 @@ static void vscsi_inquiry_no_target(VSCSIState *s, vscsi_req *req) } } +static void vscsi_report_luns(VSCSIState *s, vscsi_req *req) +{ +BusChild *kid; +int i, len, n, rc; +uint8_t *resp_data; +bool found_lun0; + +n = 0; +found_lun0 = false; +QTAILQ_FOREACH(kid, s-bus.qbus.children, sibling) { +SCSIDevice *dev = SCSI_DEVICE(kid-child); + +n += 8; +if (dev-channel == 0 dev-id == 0 dev-lun == 0) +found_lun0 = true; +} +if (!found_lun0) { +n += 8; +} +len = n+8; Let me try to grasp what you're doing here. You're trying to figure out how many devices there are attached to the bus. For every device you reserve a buffer block. Lun0 is mandatory, all others are optional. First off, I think the code would be easier to grasp if you'd count number of entries rather than number of bytes. That way we don't have to mentally deal with the 8 byte block granularity. Then IIUC you're jumping through a lot of hoops to count lun0 if it's there, but keep it reserved when it's not there. Why don't you just always reserve entry 0 for lun0? In the loop where you're actually filling in data you just skip lun0. Or is lun0 a terminator and always has to come last? This is a duplicate of the logic (and code) in scsi_target_emulate_report_luns() in scsi-bus.c. I tried to keep them as similar as possible for maintenance reasons. LUN 0 doesn't actually even need to exist to follow SAM-5, but QEMU seems to add it (and doing so is non-harmful), so I've kept that. The whole code should probably be refactored anyway to support things like hierarchical LUNs in the SCSI core, which this SRP driver is trying to emulate for one level by wrapping the SCSI core, but that's a larger project. + +resp_data = malloc(len); g_malloc0 +memset(resp_data, 0, len); +stl_be_p(resp_data, n); +i = found_lun0 ? 8 : 16; +QTAILQ_FOREACH(kid, s-bus.qbus.children, sibling) { +DeviceState *qdev = kid-child; +SCSIDevice *dev = SCSI_DEVICE(qdev); + +if (dev-id == 0 dev-channel == 0) +resp_data[i] = 0; +else +resp_data[i] = (2 6); +resp_data[i] |= dev-id; +resp_data[i+1] = (dev-channel 5); +resp_data[i+1] |= dev-lun; +i += 8; +} + +vscsi_preprocess_desc(req); +rc = vscsi_srp_transfer_data(s, req, 0, resp_data, len); +
Re: [Qemu-devel] [Qemu-ppc] [PATCH] spapr_vscsi: Fix REPORT_LUNS handling
On 01/02/14 10:56, ronnie sahlberg wrote: On Thu, Jan 2, 2014 at 7:41 AM, Alexander Graf ag...@suse.de wrote: On 02.01.2014, at 16:31, Alexander Graf ag...@suse.de wrote: On 18.10.2013, at 14:33, Nathan Whitehorn nwhiteh...@freebsd.org wrote: Intercept REPORT_LUNS commands addressed either to SRP LUN 0 or the well-known LUN for REPORT_LUNS commands. This is required to implement the SAM and SPC specifications. Since SRP implements only a single SCSI target port per connection, the SRP target is required to report all available LUNs in response to a REPORT_LUNS command addressed either to LUN 0 or the well-known LUN. Instead, QEMU was forwarding such requests to the first QEMU SCSI target, with the result that initiators that relied on this feature would only see LUNs on the first QEMU SCSI target. Behavior for REPORT_LUNS commands addressed to any other LUN is not specified by the standard and so is left unchanged. This preserves behavior under Linux and SLOF, which enumerate possible LUNs by hand and so address no commands either to LUN 0 or the well-known REPORT_LUNS LUN. Signed-off-by: Nathan Whitehorn nwhiteh...@freebsd.org This patch fails on checkpatch.pl. Please fix those warnings up :). WARNING: braces {} are necessary for all arms of this statement #65: FILE: hw/scsi/spapr_vscsi.c:738: +if (dev-channel == 0 dev-id == 0 dev-lun == 0) [...] WARNING: braces {} are necessary for all arms of this statement #81: FILE: hw/scsi/spapr_vscsi.c:754: +if (dev-id == 0 dev-channel == 0) [...] +else [...] WARNING: line over 80 characters #108: FILE: hw/scsi/spapr_vscsi.c:781: +if ((srp-cmd.lun == 0 || be64_to_cpu(srp-cmd.lun) == SRP_REPORT_LUNS_WLUN) srp-cmd.cdb[0] == REPORT_LUNS) { total: 0 errors, 3 warnings, 75 lines checked Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. --- hw/scsi/spapr_vscsi.c | 57 +++ 1 file changed, 57 insertions(+) diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index 2a26042..87e0fb3 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -63,6 +63,8 @@ #define SCSI_SENSE_BUF_SIZE 96 #define SRP_RSP_SENSE_DATA_LEN 18 +#define SRP_REPORT_LUNS_WLUN0xc101000 + typedef union vscsi_crq { struct viosrp_crq s; uint8_t raw[16]; @@ -720,12 +722,67 @@ static void vscsi_inquiry_no_target(VSCSIState *s, vscsi_req *req) } } +static void vscsi_report_luns(VSCSIState *s, vscsi_req *req) +{ +BusChild *kid; +int i, len, n, rc; +uint8_t *resp_data; +bool found_lun0; + +n = 0; +found_lun0 = false; +QTAILQ_FOREACH(kid, s-bus.qbus.children, sibling) { +SCSIDevice *dev = SCSI_DEVICE(kid-child); + +n += 8; +if (dev-channel == 0 dev-id == 0 dev-lun == 0) +found_lun0 = true; +} +if (!found_lun0) { +n += 8; +} +len = n+8; Let me try to grasp what you're doing here. You're trying to figure out how many devices there are attached to the bus. For every device you reserve a buffer block. Lun0 is mandatory, all others are optional. First off, I think the code would be easier to grasp if you'd count number of entries rather than number of bytes. That way we don't have to mentally deal with the 8 byte block granularity. Then IIUC you're jumping through a lot of hoops to count lun0 if it's there, but keep it reserved when it's not there. Why don't you just always reserve entry 0 for lun0? In the loop where you're actually filling in data you just skip lun0. Or is lun0 a terminator and always has to come last? + +resp_data = malloc(len); g_malloc0 +memset(resp_data, 0, len); +stl_be_p(resp_data, n); +i = found_lun0 ? 8 : 16; +QTAILQ_FOREACH(kid, s-bus.qbus.children, sibling) { +DeviceState *qdev = kid-child; +SCSIDevice *dev = SCSI_DEVICE(qdev); + +if (dev-id == 0 dev-channel == 0) +resp_data[i] = 0; +else +resp_data[i] = (2 6); This looks odd. Shouldn't this rather be resp_data[i] = (1 6); to set the LUN address method to 01b meaning Single Level LUN structure. (SAM5 4.7.3) He is setting the address method to 10b but there is no such address method afaik There is. This uses the Logical unit addressing method of SAM5 section 4.7.7.4, following the rest of the code in this module. Ah, I almost forgot this one. Please convert that into something more verbose through a define. Whatever that bit means ... :). +resp_data[i] |= dev-id; He should do something like : resp_data[i] |= dev-id 0x3f; here to avoid a dev-id 63 from spilling into the address method field. Or probably should have a check for if dev-id 3 then fail OK. +resp_data[i+1]
Re: [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point
On 12/31/2013 7:35 AM, Peter Maydell wrote: We need Tom Musta's softfloat patches too, so I have included them here. Note that two of these still have outstanding issues identified in code review : see the notes in their commit messages (and I haven't applied my signed-off-by line to them). Peter: I have been out but am back. I hope to publish revisions to my patches yet today.
Re: [Qemu-devel] [PATCH] spapr-pci: remove io ports workaround
On 11.12.2013, at 07:47, Alexey Kardashevskiy a...@ozlabs.ru wrote: On 12/10/2013 06:47 PM, Greg Kurz wrote: On Tue, 10 Dec 2013 13:43:05 +1100 Alexey Kardashevskiy a...@ozlabs.ru wrote: On 12/10/2013 03:33 AM, Greg Kurz wrote: In the past, IO space could not be mapped into the memory address space so we introduced a workaround for that. Nowadays it does not look necessary so we can remove the workaround and make sPAPR PCI configuration simplier. This workaround has also an evil side effect with virtio devices: because all PHBs have their .io region at the same address, the devices get mapped in the .io-alias region of every PHB (AKA. mapped multiple times). This breaks the ioeventfd feature and causes qemu to abort() when running with KVM and asking for more than one PHB: $ qemu-system-ppc64 -machine type=pseries,accel=kvm -smp 1 -m 4G \ -hda /local/greg/images/fedora-be.qcow2 \ -device virtio-9p-pci,fsdev=fsdev0,mount_tag=share,bus=pci,ioeventfd=on \ -fsdev local,security_model=none,id=fsdev0,path=$HOME/share1 \ -device spapr-pci-host-bridge,index=15 kvm_mem_ioeventfd_add: error adding ioeventfd: File exists Aborted This will prevent to use virtio and VFIO passthrough at the same time, since VFIO needs a dedicated PHB to work on ppc. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru I have not seen this version yet so please remove me from SOB. The patch you replied to was eventually reworked and went to upstream as 66aab867cedd2a2d81b4d64eff7c3e0f6f272bbf Hi Alex, I agree you have not seen this version yet... The patch I replied to was my primary source of inspiration and contains these bits, hence the SOB. Anyway, the SOB is now removed until you decide to add one yourself. :) This one might be correct too but I want to try this first :) Well, I hope it is. Please try it. Yep. Tried. Looks good, did not break a thing as far as I can tell, even VGA works :) Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru Thanks, applied to ppc-next. Alex
Re: [Qemu-devel] [Qemu-ppc] [PATCH] spapr_vscsi: Fix REPORT_LUNS handling
Il 02/01/2014 19:14, Nathan Whitehorn ha scritto: He should do something like : resp_data[i] |= dev-id 0x3f; here to avoid a dev-id 63 from spilling into the address method field. Or probably should have a check for if dev-id 3 then fail OK. No need for that: .max_channel = 7, /* logical unit addressing format */ .max_target = 63, .max_lun = 31, dev-id is thus bounded to 0..63. Paolo
Re: [Qemu-devel] [PATCH] spapr-pci: remove io ports workaround
On 01/03/2014 08:04 AM, Alexander Graf wrote: On 11.12.2013, at 07:47, Alexey Kardashevskiy a...@ozlabs.ru wrote: On 12/10/2013 06:47 PM, Greg Kurz wrote: On Tue, 10 Dec 2013 13:43:05 +1100 Alexey Kardashevskiy a...@ozlabs.ru wrote: On 12/10/2013 03:33 AM, Greg Kurz wrote: In the past, IO space could not be mapped into the memory address space so we introduced a workaround for that. Nowadays it does not look necessary so we can remove the workaround and make sPAPR PCI configuration simplier. This workaround has also an evil side effect with virtio devices: because all PHBs have their .io region at the same address, the devices get mapped in the .io-alias region of every PHB (AKA. mapped multiple times). This breaks the ioeventfd feature and causes qemu to abort() when running with KVM and asking for more than one PHB: $ qemu-system-ppc64 -machine type=pseries,accel=kvm -smp 1 -m 4G \ -hda /local/greg/images/fedora-be.qcow2 \ -device virtio-9p-pci,fsdev=fsdev0,mount_tag=share,bus=pci,ioeventfd=on \ -fsdev local,security_model=none,id=fsdev0,path=$HOME/share1 \ -device spapr-pci-host-bridge,index=15 kvm_mem_ioeventfd_add: error adding ioeventfd: File exists Aborted This will prevent to use virtio and VFIO passthrough at the same time, since VFIO needs a dedicated PHB to work on ppc. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru I have not seen this version yet so please remove me from SOB. The patch you replied to was eventually reworked and went to upstream as 66aab867cedd2a2d81b4d64eff7c3e0f6f272bbf Hi Alex, I agree you have not seen this version yet... The patch I replied to was my primary source of inspiration and contains these bits, hence the SOB. Anyway, the SOB is now removed until you decide to add one yourself. :) This one might be correct too but I want to try this first :) Well, I hope it is. Please try it. Yep. Tried. Looks good, did not break a thing as far as I can tell, even VGA works :) Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru Thanks, applied to ppc-next. Please read the rest of this thread. It does not visibly break things but with this patch QEMU starts calling unassigned_mem_accepts() (normally silent) which is not a good sign. -- Alexey
Re: [Qemu-devel] [PATCH] spapr-pci: remove io ports workaround
On 02.01.2014, at 23:08, Alexey Kardashevskiy a...@ozlabs.ru wrote: On 01/03/2014 08:04 AM, Alexander Graf wrote: On 11.12.2013, at 07:47, Alexey Kardashevskiy a...@ozlabs.ru wrote: On 12/10/2013 06:47 PM, Greg Kurz wrote: On Tue, 10 Dec 2013 13:43:05 +1100 Alexey Kardashevskiy a...@ozlabs.ru wrote: On 12/10/2013 03:33 AM, Greg Kurz wrote: In the past, IO space could not be mapped into the memory address space so we introduced a workaround for that. Nowadays it does not look necessary so we can remove the workaround and make sPAPR PCI configuration simplier. This workaround has also an evil side effect with virtio devices: because all PHBs have their .io region at the same address, the devices get mapped in the .io-alias region of every PHB (AKA. mapped multiple times). This breaks the ioeventfd feature and causes qemu to abort() when running with KVM and asking for more than one PHB: $ qemu-system-ppc64 -machine type=pseries,accel=kvm -smp 1 -m 4G \ -hda /local/greg/images/fedora-be.qcow2 \ -device virtio-9p-pci,fsdev=fsdev0,mount_tag=share,bus=pci,ioeventfd=on \ -fsdev local,security_model=none,id=fsdev0,path=$HOME/share1 \ -device spapr-pci-host-bridge,index=15 kvm_mem_ioeventfd_add: error adding ioeventfd: File exists Aborted This will prevent to use virtio and VFIO passthrough at the same time, since VFIO needs a dedicated PHB to work on ppc. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru I have not seen this version yet so please remove me from SOB. The patch you replied to was eventually reworked and went to upstream as 66aab867cedd2a2d81b4d64eff7c3e0f6f272bbf Hi Alex, I agree you have not seen this version yet... The patch I replied to was my primary source of inspiration and contains these bits, hence the SOB. Anyway, the SOB is now removed until you decide to add one yourself. :) This one might be correct too but I want to try this first :) Well, I hope it is. Please try it. Yep. Tried. Looks good, did not break a thing as far as I can tell, even VGA works :) Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru Thanks, applied to ppc-next. Please read the rest of this thread. It does not visibly break things but with this patch QEMU starts calling unassigned_mem_accepts() (normally silent) which is not a good sign. Oops, I thought your comment meant this was fixed. I took it off the queue again :). Alex
[Qemu-devel] [V5 PATCH 02/22] softfloat: Add float32_to_uint64()
This patch adds the float32_to_uint64() routine, which converts a 32-bit floating point number to an unsigned 64 bit number. This contribution can be licensed under either the softfloat-2a or -2b license. Signed-off-by: Tom Musta tommu...@gmail.com --- V2: Reduced patch to just this single routine per feedback from Peter Maydell. V4: Now passing sign to roundAndPackUint64() V5: Proper handling of small negatives and negative NaNs. fpu/softfloat.c | 46 ++ include/fpu/softfloat.h |1 + 2 files changed, 47 insertions(+), 0 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 05e2877..9f42a5b 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1558,6 +1558,52 @@ int64 float32_to_int64( float32 a STATUS_PARAM ) /* | Returns the result of converting the single-precision floating-point value +| `a' to the 64-bit unsigned integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic---which means in particular that the conversion is rounded +| according to the current rounding mode. If `a' is a NaN, the largest +| unsigned integer is returned. Otherwise, if the conversion overflows, the +| largest unsigned integer is returned. If the 'a' is negative, the result +| is rounded and zero is returned; values that do not round to zero will +| raise the inexact exception flag. +**/ + +uint64 float32_to_uint64(float32 a STATUS_PARAM) +{ +flag aSign; +int_fast16_t aExp, shiftCount; +uint32_t aSig; +uint64_t aSig64, aSigExtra; +a = float32_squash_input_denormal(a STATUS_VAR); + +aSig = extractFloat32Frac(a); +aExp = extractFloat32Exp(a); +aSign = extractFloat32Sign(a); +if ((aSign) (aExp 126)) { +float_raise(float_flag_invalid STATUS_VAR); +if (float32_is_any_nan(a)) { +return (int64_t)LIT64(0x); +} else { +return 0; +} +} +shiftCount = 0xBE - aExp; +if (aExp) { +aSig |= 0x0080; +} +if (shiftCount 0) { +float_raise(float_flag_invalid STATUS_VAR); +return (int64_t)LIT64(0x); +} + +aSig64 = aSig; +aSig64 = 40; +shift64ExtraRightJamming(aSig64, 0, shiftCount, aSig64, aSigExtra); +return roundAndPackUint64(aSign, aSig64, aSigExtra STATUS_VAR); +} + +/* +| Returns the result of converting the single-precision floating-point value | `a' to the 64-bit two's complement integer format. The conversion is | performed according to the IEC/IEEE Standard for Binary Floating-Point | Arithmetic, except that the conversion is always rounded toward zero. If diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 2365274..080b36d 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -272,6 +272,7 @@ int32 float32_to_int32_round_to_zero( float32 STATUS_PARAM ); uint32 float32_to_uint32( float32 STATUS_PARAM ); uint32 float32_to_uint32_round_to_zero( float32 STATUS_PARAM ); int64 float32_to_int64( float32 STATUS_PARAM ); +uint64 float32_to_uint64(float32 STATUS_PARAM); int64 float32_to_int64_round_to_zero( float32 STATUS_PARAM ); float64 float32_to_float64( float32 STATUS_PARAM ); floatx80 float32_to_floatx80( float32 STATUS_PARAM ); -- 1.7.1
[Qemu-devel] [V5 PATCH 00/22] target-ppc: PowerPC VSX Stage 3
This is the third series of patches to add PowerPC VSX emulation support to QEMU. This series adds the floating point arithmetic, compare, conversion and rounding instructions. Instructions are implemented using helpers and wherever practical, existing floating point code such as the softfloat library and the existing PowerPC floating point helper code. As with the previous series, the Power ISA V2.06 instructions are added but the V2.07 instructions are not. The latter will be implemented in a future patch series. V2: Implemented changes based on feedback from Richard Henderson and Peter Maydell: - Included float64_to_uint64() patch in this series rather than just cite it as a pre-requesite. - Isolated float32_to_uint64() in its own patch. - Re-implemented helpers and eliminated the need for some of the proposed softfloat routines (float*_is_denormal, float*_get_unbiased_exp). - Re-implemented severy helpers so that corner cases (e.g. invalid operations) are detected by softfloat. - Re-implemented fused multiply-add to use the softfloat muladd routines. - Re-implemented the min/max instructions to used the softfloat min/max functions. - assorted style fixes V3: re-submitting due to patch corruption. V4: Folded in softfloat bug fixes per Peter Maydell's request. V5: Additional comments from Peter Maydell and Richard Henderson: - proper handling of NaNs with negative signs in conversion routines. - proper rounding of small negatives in float32_to_uint64 - simplification of max/min instructions using new softfloat routines. - assorted commentary changes. Tom Musta (22): softfloat: Fix float64_to_uint64 softfloat: Add float32_to_uint64() softfloat: Fix float64_to_uint64_round_to_zero softfloat: Fix float64_to_uint32 softfloat: Fix float64_to_uint32_round_to_zero target-ppc: Add set_fprf Argument to fload_invalid_op_excp() target-ppc: General Support for VSX Helpers target-ppc: Add VSX ISA2.06 xadd/xsub Instructions target-ppc: Add VSX ISA2.06 xmul Instructions target-ppc: Add VSX ISA2.06 xdiv Instructions target-ppc: Add VSX ISA2.06 xre Instructions target-ppc: Add VSX ISA2.06 xsqrt Instructions target-ppc: Add VSX ISA2.06 xrsqrte Instructions target-ppc: Add VSX ISA2.06 xtdiv Instructions target-ppc: Add VSX ISA2.06 xtsqrt Instructions target-ppc: Add VSX ISA2.06 Multiply Add Instructions target-ppc: Add VSX xscmp*dp Instructions target-ppc: Add VSX xmax/xmin Instructions target-ppc: Add VSX Vector Compare Instructions target-ppc: Add VSX Floating Point to Floating Point Conversion Instructions target-ppc: Add VSX ISA2.06 Integer Conversion Instructions target-ppc: Add VSX Rounding Instructions fpu/softfloat.c | 191 -- include/fpu/softfloat.h |1 + target-ppc/fpu_helper.c | 991 --- target-ppc/helper.h | 109 ++ target-ppc/translate.c | 243 5 files changed, 1455 insertions(+), 80 deletions(-)
[Qemu-devel] [V5 PATCH 05/22] softfloat: Fix float64_to_uint32_round_to_zero
The float64_to_uint32_round_to_zero routine is incorrect. For example, the following test pattern: 425F81378DC0CD1F / 0x1.f81378dc0cd1fp+38 will erroneously set the inexact flag. This patch re-implements the routine to use the float64_to_uint64_round_to_zero routine. If saturation occurs the invalid exception flag is raised (but not the inexact flag). This contribution can be licensed under either the softfloat-2a or -2b license. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Peter Maydell address@hidden --- V4: Correct commit commentary. Corrected code to properly handle the stickiness of the inexact flag. fpu/softfloat.c | 15 +++ 1 files changed, 7 insertions(+), 8 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 640cd71..2c598ca 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -6596,19 +6596,18 @@ uint32 float64_to_uint32( float64 a STATUS_PARAM ) uint32 float64_to_uint32_round_to_zero( float64 a STATUS_PARAM ) { -int64_t v; +uint64_t v; uint32 res; +int old_exc_flags = get_float_exception_flags(status); -v = float64_to_int64_round_to_zero(a STATUS_VAR); -if (v 0) { -res = 0; -float_raise( float_flag_invalid STATUS_VAR); -} else if (v 0x) { +v = float64_to_uint64_round_to_zero(a STATUS_VAR); +if (v 0x) { res = 0x; -float_raise( float_flag_invalid STATUS_VAR); } else { -res = v; +return v; } +set_float_exception_flags(old_exc_flags, status); +float_raise(float_flag_invalid STATUS_VAR); return res; } -- 1.7.1
[Qemu-devel] [V5 PATCH 01/22] softfloat: Fix float64_to_uint64
The comment preceding the float64_to_uint64 routine suggests that the implementation is broken. And this is, indeed, the case. This patch properly implements the conversion of a 64-bit floating point number to an unsigned, 64 bit integer. This contribution can be licensed under either the softfloat-2a or -2b license. Signed-off-by: Tom Musta tommu...@gmail.com --- V2: Added softfloat license statement. V3: Modified to meet QEMU coding conventions. V4: Fixed incorrect handling of small negatives, which, if rounded up to zero should not set the inexact flag. V5: Clarified handling of negatives. Fixed incorrect handling of negative NaNs. fpu/softfloat.c | 103 ++- 1 files changed, 94 insertions(+), 9 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index dbda61b..05e2877 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -161,7 +161,6 @@ static int32 roundAndPackInt32( flag zSign, uint64_t absZ STATUS_PARAM) | exception is raised and the largest positive or negative integer is | returned. **/ - static int64 roundAndPackInt64( flag zSign, uint64_t absZ0, uint64_t absZ1 STATUS_PARAM) { int8 roundingMode; @@ -204,6 +203,56 @@ static int64 roundAndPackInt64( flag zSign, uint64_t absZ0, uint64_t absZ1 STATU } /* +| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and +| `absZ1', with binary point between bits 63 and 64 (between the input words), +| and returns the properly rounded 64-bit unsigned integer corresponding to the +| input. Ordinarily, the fixed-point input is simply rounded to an integer, +| with the inexact exception raised if the input cannot be represented exactly +| as an integer. However, if the fixed-point input is too large, the invalid +| exception is raised and the largest unsigned integer is returned. +**/ + +static int64 roundAndPackUint64(flag zSign, uint64_t absZ0, +uint64_t absZ1 STATUS_PARAM) +{ +int8 roundingMode; +flag roundNearestEven, increment; + +roundingMode = STATUS(float_rounding_mode); +roundNearestEven = (roundingMode == float_round_nearest_even); +increment = ((int64_t)absZ1 0); +if (!roundNearestEven) { +if (roundingMode == float_round_to_zero) { +increment = 0; +} else if (absZ1) { +if (zSign) { +increment = (roundingMode == float_round_down) absZ1; +} else { +increment = (roundingMode == float_round_up) absZ1; +} +} +} +if (increment) { +++absZ0; +if (absZ0 == 0) { +float_raise(float_flag_invalid STATUS_VAR); +return LIT64(0x); +} +absZ0 = ~(((uint64_t)(absZ11) == 0) roundNearestEven); +} + +if (zSign absZ0) { +float_raise(float_flag_invalid STATUS_VAR); +return 0; +} + +if (absZ1) { +STATUS(float_exception_flags) |= float_flag_inexact; +} +return absZ0; +} + +/* | Returns the fraction bits of the single-precision floating-point value `a'. **/ @@ -6536,18 +6585,54 @@ uint_fast16_t float64_to_uint16_round_to_zero(float64 a STATUS_PARAM) return res; } -/* FIXME: This looks broken. */ -uint64_t float64_to_uint64 (float64 a STATUS_PARAM) -{ -int64_t v; +/* +| Returns the result of converting the double-precision floating-point value +| `a' to the 64-bit unsigned integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic---which means in particular that the conversion is rounded +| according to the current rounding mode. If `a' is a NaN, the largest +| positive integer is returned. If the conversion overflows, the +| largest unsigned integer is returned. If 'a' is negative, the value is +| rounded and zero is returned; negative values that do not round to zero +| will raise the inexact exception. +**/ -v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR)); -v += float64_val(a); -v = float64_to_int64(make_float64(v) STATUS_VAR); +uint64_t float64_to_uint64(float64 a STATUS_PARAM) +{ +flag aSign; +int_fast16_t aExp, shiftCount; +uint64_t aSig, aSigExtra; +a = float64_squash_input_denormal(a STATUS_VAR); -return v - INT64_MIN; +aSig = extractFloat64Frac(a); +aExp = extractFloat64Exp(a); +aSign = extractFloat64Sign(a); +
[Qemu-devel] [V5 PATCH 03/22] softfloat: Fix float64_to_uint64_round_to_zero
The float64_to_uint64_round_to_zero routine is incorrect. For example, the following test pattern: 46697351FF4AEC29 / 0x1.97351ff4aec29p+103 currently produces 8000 instead of . This patch re-implements the routine to temporarily force the rounding mode and use the float64_to_uint64 routine. This contribution can be licensed under either the softfloat-2a or -2b license. Signed-off-by: Tom Musta tommu...@gmail.com --- fpu/softfloat.c | 12 +--- 1 files changed, 5 insertions(+), 7 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 9f42a5b..67ee37b 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -6681,13 +6681,11 @@ uint64_t float64_to_uint64(float64 a STATUS_PARAM) uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM) { -int64_t v; - -v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR)); -v += float64_val(a); -v = float64_to_int64_round_to_zero(make_float64(v) STATUS_VAR); - -return v - INT64_MIN; +signed char current_rounding_mode = STATUS(float_rounding_mode); +set_float_rounding_mode(float_round_to_zero STATUS_VAR); +int64_t v = float64_to_uint64(a STATUS_VAR); +set_float_rounding_mode(current_rounding_mode STATUS_VAR); +return v; } #define COMPARE(s, nan_exp) \ -- 1.7.1
[Qemu-devel] [V5 PATCH 12/22] target-ppc: Add VSX ISA2.06 xsqrt Instructions
This patch adds the VSX floating point square root instructions defined by V2.06 of the PowerPC ISA: xssqrtdp, xvsqrtdp, xvsqrtsp. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Richard Henderson address@hidden --- V2: re-implemented the VSX_SQRT macro. target-ppc/fpu_helper.c | 44 target-ppc/helper.h |3 +++ target-ppc/translate.c |6 ++ 3 files changed, 53 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index 5908e41..060e6a0 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -1939,3 +1939,47 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ VSX_RE(xsredp, 1, float64, f64, 1) VSX_RE(xvredp, 2, float64, f64, 0) VSX_RE(xvresp, 4, float32, f32, 0) + +/* VSX_SQRT - VSX floating point square root + * op- instruction mnemonic + * nels - number of elements (1, 2 or 4) + * tp- type (float32 or float64) + * fld - vsr_t field (f32 or f64) + * sfprf - set FPRF + */ +#define VSX_SQRT(op, nels, tp, fld, sfprf) \ +void helper_##op(CPUPPCState *env, uint32_t opcode) \ +{\ +ppc_vsr_t xt, xb;\ +int i; \ + \ +getVSR(xB(opcode), xb, env);\ +getVSR(xT(opcode), xt, env);\ +helper_reset_fpstatus(env); \ + \ +for (i = 0; i nels; i++) { \ +float_status tstat = env-fp_status; \ +set_float_exception_flags(0, tstat);\ +xt.fld[i] = tp##_sqrt(xb.fld[i], tstat);\ +env-fp_status.float_exception_flags |= tstat.float_exception_flags; \ + \ +if (unlikely(tstat.float_exception_flags float_flag_invalid)) {\ +if (tp##_is_neg(xb.fld[i]) !tp##_is_zero(xb.fld[i])) {\ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf); \ +} else if (tp##_is_signaling_nan(xb.fld[i])) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ +}\ +}\ + \ +if (sfprf) { \ +helper_compute_fprf(env, xt.fld[i], sfprf); \ +}\ +}\ + \ +putVSR(xT(opcode), xt, env);\ +helper_float_check_status(env); \ +} + +VSX_SQRT(xssqrtdp, 1, float64, f64, 1) +VSX_SQRT(xvsqrtdp, 2, float64, f64, 0) +VSX_SQRT(xvsqrtsp, 4, float32, f32, 0) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index fe5b61c..a6e7e62 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -256,18 +256,21 @@ DEF_HELPER_2(xssubdp, void, env, i32) DEF_HELPER_2(xsmuldp, void, env, i32) DEF_HELPER_2(xsdivdp, void, env, i32) DEF_HELPER_2(xsredp, void, env, i32) +DEF_HELPER_2(xssqrtdp, void, env, i32) DEF_HELPER_2(xvadddp, void, env, i32) DEF_HELPER_2(xvsubdp, void, env, i32) DEF_HELPER_2(xvmuldp, void, env, i32) DEF_HELPER_2(xvdivdp, void, env, i32) DEF_HELPER_2(xvredp, void, env, i32) +DEF_HELPER_2(xvsqrtdp, void, env, i32) DEF_HELPER_2(xvaddsp, void, env, i32) DEF_HELPER_2(xvsubsp, void, env, i32) DEF_HELPER_2(xvmulsp, void, env, i32) DEF_HELPER_2(xvdivsp, void, env, i32) DEF_HELPER_2(xvresp, void, env, i32) +DEF_HELPER_2(xvsqrtsp, void, env, i32) DEF_HELPER_2(efscfsi, i32, env, i32) DEF_HELPER_2(efscfui, i32, env, i32) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index fb442c8..b89daf1 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7309,18 +7309,21 @@ GEN_VSX_HELPER_2(xssubdp, 0x00, 0x05, 0, PPC2_VSX) GEN_VSX_HELPER_2(xsmuldp, 0x00, 0x06, 0, PPC2_VSX) GEN_VSX_HELPER_2(xsdivdp, 0x00, 0x07, 0, PPC2_VSX) GEN_VSX_HELPER_2(xsredp, 0x14, 0x05, 0, PPC2_VSX) +GEN_VSX_HELPER_2(xssqrtdp, 0x16, 0x04, 0, PPC2_VSX)
[Qemu-devel] [V5 PATCH 04/22] softfloat: Fix float64_to_uint32
The float64_to_uint32 has several flaws: - for numbers between 2**32 and 2**64, the inexact exception flag may get incorrectly set. In this case, only the invalid flag should be set. test pattern: 425F81378DC0CD1F / 0x1.f81378dc0cd1fp+38 - for numbers between 2**63 and 2**64, incorrect results may be produced: test pattern: 43EAAF73F1F0B8BD / 0x1.aaf73f1f0b8bdp+63 This patch re-implements float64_to_uint32 to re-use the float64_to_uint64 routine (instead of float64_to_int64). For the saturation case, only the invalid exception flag is raised. This contribution can be licensed under either the softfloat-2a or -2b license. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Peter Maydell addresshidden --- V4: Fixed handling of stickiness of the inexact bit per comments from Peter Maydell. fpu/softfloat.c | 15 +++ 1 files changed, 7 insertions(+), 8 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 67ee37b..640cd71 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -6579,19 +6579,18 @@ uint_fast16_t float32_to_uint16_round_to_zero(float32 a STATUS_PARAM) uint32 float64_to_uint32( float64 a STATUS_PARAM ) { -int64_t v; +uint64_t v; uint32 res; +int old_exc_flags = get_float_exception_flags(status); -v = float64_to_int64(a STATUS_VAR); -if (v 0) { -res = 0; -float_raise( float_flag_invalid STATUS_VAR); -} else if (v 0x) { +v = float64_to_uint64(a STATUS_VAR); +if (v 0x) { res = 0x; -float_raise( float_flag_invalid STATUS_VAR); } else { -res = v; +return v; } +set_float_exception_flags(old_exc_flags, status); +float_raise(float_flag_invalid STATUS_VAR); return res; } -- 1.7.1
[Qemu-devel] [V5 PATCH 08/22] target-ppc: Add VSX ISA2.06 xadd/xsub Instructions
This patch adds the floating point addition and subtraction instructions defined by V2.06 of the PowerPC ISA: xssubdp, xvsubdp and xvsubsp. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Richard Henderson address@hidden --- V2: re-implemented helper macro and combined add and substract. target-ppc/fpu_helper.c | 51 +++ target-ppc/helper.h |9 target-ppc/translate.c | 18 3 files changed, 78 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index cea94ac..a577d28 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -1758,3 +1758,54 @@ static void putVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env) } #define float64_to_float64(x, env) x + + +/* VSX_ADD_SUB - VSX floating point add/subract + * name - instruction mnemonic + * op- operation (add or sub) + * nels - number of elements (1, 2 or 4) + * tp- type (float32 or float64) + * fld - vsr_t field (f32 or f64) + * sfprf - set FPRF + */ +#define VSX_ADD_SUB(name, op, nels, tp, fld, sfprf) \ +void helper_##name(CPUPPCState *env, uint32_t opcode)\ +{\ +ppc_vsr_t xt, xa, xb;\ +int i; \ + \ +getVSR(xA(opcode), xa, env);\ +getVSR(xB(opcode), xb, env);\ +getVSR(xT(opcode), xt, env);\ +helper_reset_fpstatus(env); \ + \ +for (i = 0; i nels; i++) { \ +float_status tstat = env-fp_status; \ +set_float_exception_flags(0, tstat);\ +xt.fld[i] = tp##_##op(xa.fld[i], xb.fld[i], tstat); \ +env-fp_status.float_exception_flags |= tstat.float_exception_flags; \ + \ +if (unlikely(tstat.float_exception_flags float_flag_invalid)) {\ +if (tp##_is_infinity(xa.fld[i]) tp##_is_infinity(xb.fld[i])) {\ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf);\ +} else if (tp##_is_signaling_nan(xa.fld[i]) || \ + tp##_is_signaling_nan(xb.fld[i])) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ +}\ +}\ + \ +if (sfprf) { \ +helper_compute_fprf(env, xt.fld[i], sfprf); \ +}\ +}\ +putVSR(xT(opcode), xt, env);\ +helper_float_check_status(env); \ +} + +VSX_ADD_SUB(xsadddp, add, 1, float64, f64, 1) +VSX_ADD_SUB(xvadddp, add, 2, float64, f64, 0) +VSX_ADD_SUB(xvaddsp, add, 4, float32, f32, 0) +VSX_ADD_SUB(xssubdp, sub, 1, float64, f64, 1) +VSX_ADD_SUB(xvsubdp, sub, 2, float64, f64, 0) +VSX_ADD_SUB(xvsubsp, sub, 4, float32, f32, 0) + diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 6d282bb..966200d 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -251,6 +251,15 @@ DEF_HELPER_4(vcfsx, void, env, avr, avr, i32) DEF_HELPER_4(vctuxs, void, env, avr, avr, i32) DEF_HELPER_4(vctsxs, void, env, avr, avr, i32) +DEF_HELPER_2(xsadddp, void, env, i32) +DEF_HELPER_2(xssubdp, void, env, i32) + +DEF_HELPER_2(xvadddp, void, env, i32) +DEF_HELPER_2(xvsubdp, void, env, i32) + +DEF_HELPER_2(xvaddsp, void, env, i32) +DEF_HELPER_2(xvsubsp, void, env, i32) + DEF_HELPER_2(efscfsi, i32, env, i32) DEF_HELPER_2(efscfui, i32, env, i32) DEF_HELPER_2(efscfuf, i32, env, i32) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 2060b1c..a2f2801 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7304,6 +7304,15 @@ static void gen_##name(DisasContext * ctx) \ tcg_temp_free_i32(opc); \ } +GEN_VSX_HELPER_2(xsadddp, 0x00, 0x04, 0, PPC2_VSX) +GEN_VSX_HELPER_2(xssubdp, 0x00,
[Qemu-devel] [V5 PATCH 11/22] target-ppc: Add VSX ISA2.06 xre Instructions
This patch adds the VSX floating point reciprocal estimate instructions defined by V2.06 of the PowerPC ISA: xsredp, xvredp, xvresp. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Richard Henderson address@hidden --- target-ppc/fpu_helper.c | 35 +++ target-ppc/helper.h |3 +++ target-ppc/translate.c |6 ++ 3 files changed, 44 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index c84f432..5908e41 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -1904,3 +1904,38 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ VSX_DIV(xsdivdp, 1, float64, f64, 1) VSX_DIV(xvdivdp, 2, float64, f64, 0) VSX_DIV(xvdivsp, 4, float32, f32, 0) + +/* VSX_RE - VSX floating point reciprocal estimate + * op- instruction mnemonic + * nels - number of elements (1, 2 or 4) + * tp- type (float32 or float64) + * fld - vsr_t field (f32 or f64) + * sfprf - set FPRF + */ +#define VSX_RE(op, nels, tp, fld, sfprf) \ +void helper_##op(CPUPPCState *env, uint32_t opcode) \ +{ \ +ppc_vsr_t xt, xb; \ +int i;\ + \ +getVSR(xB(opcode), xb, env); \ +getVSR(xT(opcode), xt, env); \ +helper_reset_fpstatus(env); \ + \ +for (i = 0; i nels; i++) { \ +if (unlikely(tp##_is_signaling_nan(xb.fld[i]))) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);\ +} \ +xt.fld[i] = tp##_div(tp##_one, xb.fld[i], env-fp_status); \ +if (sfprf) { \ +helper_compute_fprf(env, xt.fld[0], sfprf); \ +} \ +} \ + \ +putVSR(xT(opcode), xt, env); \ +helper_float_check_status(env); \ +} + +VSX_RE(xsredp, 1, float64, f64, 1) +VSX_RE(xvredp, 2, float64, f64, 0) +VSX_RE(xvresp, 4, float32, f32, 0) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 6ede7ea..fe5b61c 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -255,16 +255,19 @@ DEF_HELPER_2(xsadddp, void, env, i32) DEF_HELPER_2(xssubdp, void, env, i32) DEF_HELPER_2(xsmuldp, void, env, i32) DEF_HELPER_2(xsdivdp, void, env, i32) +DEF_HELPER_2(xsredp, void, env, i32) DEF_HELPER_2(xvadddp, void, env, i32) DEF_HELPER_2(xvsubdp, void, env, i32) DEF_HELPER_2(xvmuldp, void, env, i32) DEF_HELPER_2(xvdivdp, void, env, i32) +DEF_HELPER_2(xvredp, void, env, i32) DEF_HELPER_2(xvaddsp, void, env, i32) DEF_HELPER_2(xvsubsp, void, env, i32) DEF_HELPER_2(xvmulsp, void, env, i32) DEF_HELPER_2(xvdivsp, void, env, i32) +DEF_HELPER_2(xvresp, void, env, i32) DEF_HELPER_2(efscfsi, i32, env, i32) DEF_HELPER_2(efscfui, i32, env, i32) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index d2a326b..fb442c8 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7308,16 +7308,19 @@ GEN_VSX_HELPER_2(xsadddp, 0x00, 0x04, 0, PPC2_VSX) GEN_VSX_HELPER_2(xssubdp, 0x00, 0x05, 0, PPC2_VSX) GEN_VSX_HELPER_2(xsmuldp, 0x00, 0x06, 0, PPC2_VSX) GEN_VSX_HELPER_2(xsdivdp, 0x00, 0x07, 0, PPC2_VSX) +GEN_VSX_HELPER_2(xsredp, 0x14, 0x05, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvmuldp, 0x00, 0x0E, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvdivdp, 0x00, 0x0F, 0, PPC2_VSX) +GEN_VSX_HELPER_2(xvredp, 0x14, 0x0D, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvmulsp, 0x00, 0x0A, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvdivsp, 0x00, 0x0B, 0, PPC2_VSX) +GEN_VSX_HELPER_2(xvresp, 0x14, 0x09, 0, PPC2_VSX) #define VSX_LOGICAL(name, tcg_op)\ static void glue(gen_, name)(DisasContext * ctx) \ @@ -10004,16 +10007,19 @@ GEN_XX3FORM(xsadddp, 0x00, 0x04, PPC2_VSX), GEN_XX3FORM(xssubdp, 0x00, 0x05, PPC2_VSX), GEN_XX3FORM(xsmuldp, 0x00, 0x06,
[Qemu-devel] [V5 PATCH 06/22] target-ppc: Add set_fprf Argument to fload_invalid_op_excp()
The fload_invalid_op_excp() function sets assorted invalid operation status bits. However, it also implicitly modifies the FPRF field of the PowerPC FPSCR. Many VSX instructions set invalid operation bits but do not alter FPRF. Thus the function is more generally useful if the setting of the FPRF field is made conditional via a parameter. All invocations of this routine in existing instructions are modified to pass 1 and thus retain their current behavior. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Richard Henderson address@hidden --- target-ppc/fpu_helper.c | 103 +-- 1 files changed, 55 insertions(+), 48 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index 4f60218..f0b0a49 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -106,7 +106,8 @@ uint32_t helper_compute_fprf(CPUPPCState *env, uint64_t arg, uint32_t set_fprf) } /* Floating-point invalid operations exception */ -static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op) +static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op, + int set_fpcc) { uint64_t ret = 0; int ve; @@ -138,8 +139,10 @@ static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op) case POWERPC_EXCP_FP_VXVC: /* Ordered comparison of NaN */ env-fpscr |= 1 FPSCR_VXVC; -env-fpscr = ~(0xF FPSCR_FPCC); -env-fpscr |= 0x11 FPSCR_FPCC; +if (set_fpcc) { +env-fpscr = ~(0xF FPSCR_FPCC); +env-fpscr |= 0x11 FPSCR_FPCC; +} /* We must update the target FPR before raising the exception */ if (ve != 0) { env-exception_index = POWERPC_EXCP_PROGRAM; @@ -158,8 +161,10 @@ static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op) if (ve == 0) { /* Set the result to quiet NaN */ ret = 0x7FF8ULL; -env-fpscr = ~(0xF FPSCR_FPCC); -env-fpscr |= 0x11 FPSCR_FPCC; +if (set_fpcc) { +env-fpscr = ~(0xF FPSCR_FPCC); +env-fpscr |= 0x11 FPSCR_FPCC; +} } break; case POWERPC_EXCP_FP_VXCVI: @@ -169,8 +174,10 @@ static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op) if (ve == 0) { /* Set the result to quiet NaN */ ret = 0x7FF8ULL; -env-fpscr = ~(0xF FPSCR_FPCC); -env-fpscr |= 0x11 FPSCR_FPCC; +if (set_fpcc) { +env-fpscr = ~(0xF FPSCR_FPCC); +env-fpscr |= 0x11 FPSCR_FPCC; +} } break; } @@ -505,12 +512,12 @@ uint64_t helper_fadd(CPUPPCState *env, uint64_t arg1, uint64_t arg2) if (unlikely(float64_is_infinity(farg1.d) float64_is_infinity(farg2.d) float64_is_neg(farg1.d) != float64_is_neg(farg2.d))) { /* Magnitude subtraction of infinities */ -farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI); +farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1); } else { if (unlikely(float64_is_signaling_nan(farg1.d) || float64_is_signaling_nan(farg2.d))) { /* sNaN addition */ -fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN); +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); } farg1.d = float64_add(farg1.d, farg2.d, env-fp_status); } @@ -529,12 +536,12 @@ uint64_t helper_fsub(CPUPPCState *env, uint64_t arg1, uint64_t arg2) if (unlikely(float64_is_infinity(farg1.d) float64_is_infinity(farg2.d) float64_is_neg(farg1.d) == float64_is_neg(farg2.d))) { /* Magnitude subtraction of infinities */ -farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI); +farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1); } else { if (unlikely(float64_is_signaling_nan(farg1.d) || float64_is_signaling_nan(farg2.d))) { /* sNaN subtraction */ -fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN); +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); } farg1.d = float64_sub(farg1.d, farg2.d, env-fp_status); } @@ -553,12 +560,12 @@ uint64_t helper_fmul(CPUPPCState *env, uint64_t arg1, uint64_t arg2) if (unlikely((float64_is_infinity(farg1.d) float64_is_zero(farg2.d)) || (float64_is_zero(farg1.d) float64_is_infinity(farg2.d { /* Multiplication of zero by infinity */ -farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ); +farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1); } else { if (unlikely(float64_is_signaling_nan(farg1.d) || float64_is_signaling_nan(farg2.d)))
[Qemu-devel] [V5 PATCH 09/22] target-ppc: Add VSX ISA2.06 xmul Instructions
This patch adds the VSX floating point multiply instructions defined by V2.06 of the PowerPC ISA: xsmuldp, xvmuldp, xvmulsp. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Richard Henderson address@hidden --- V2: re-implemented VSX_MUL macro. target-ppc/fpu_helper.c | 46 ++ target-ppc/helper.h |3 +++ target-ppc/translate.c |6 ++ 3 files changed, 55 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index a577d28..51ca589 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -1809,3 +1809,49 @@ VSX_ADD_SUB(xssubdp, sub, 1, float64, f64, 1) VSX_ADD_SUB(xvsubdp, sub, 2, float64, f64, 0) VSX_ADD_SUB(xvsubsp, sub, 4, float32, f32, 0) +/* VSX_MUL - VSX floating point multiply + * op- instruction mnemonic + * nels - number of elements (1, 2 or 4) + * tp- type (float32 or float64) + * fld - vsr_t field (f32 or f64) + * sfprf - set FPRF + */ +#define VSX_MUL(op, nels, tp, fld, sfprf)\ +void helper_##op(CPUPPCState *env, uint32_t opcode) \ +{\ +ppc_vsr_t xt, xa, xb;\ +int i; \ + \ +getVSR(xA(opcode), xa, env);\ +getVSR(xB(opcode), xb, env);\ +getVSR(xT(opcode), xt, env);\ +helper_reset_fpstatus(env); \ + \ +for (i = 0; i nels; i++) { \ +float_status tstat = env-fp_status; \ +set_float_exception_flags(0, tstat);\ +xt.fld[i] = tp##_mul(xa.fld[i], xb.fld[i], tstat); \ +env-fp_status.float_exception_flags |= tstat.float_exception_flags; \ + \ +if (unlikely(tstat.float_exception_flags float_flag_invalid)) {\ +if ((tp##_is_infinity(xa.fld[i]) tp##_is_zero(xb.fld[i])) || \ +(tp##_is_infinity(xb.fld[i]) tp##_is_zero(xa.fld[i]))) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, sfprf);\ +} else if (tp##_is_signaling_nan(xa.fld[i]) || \ + tp##_is_signaling_nan(xb.fld[i])) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ +}\ +}\ + \ +if (sfprf) { \ +helper_compute_fprf(env, xt.fld[i], sfprf); \ +}\ +}\ + \ +putVSR(xT(opcode), xt, env);\ +helper_float_check_status(env); \ +} + +VSX_MUL(xsmuldp, 1, float64, f64, 1) +VSX_MUL(xvmuldp, 2, float64, f64, 0) +VSX_MUL(xvmulsp, 4, float32, f32, 0) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 966200d..ecb900f 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -253,12 +253,15 @@ DEF_HELPER_4(vctsxs, void, env, avr, avr, i32) DEF_HELPER_2(xsadddp, void, env, i32) DEF_HELPER_2(xssubdp, void, env, i32) +DEF_HELPER_2(xsmuldp, void, env, i32) DEF_HELPER_2(xvadddp, void, env, i32) DEF_HELPER_2(xvsubdp, void, env, i32) +DEF_HELPER_2(xvmuldp, void, env, i32) DEF_HELPER_2(xvaddsp, void, env, i32) DEF_HELPER_2(xvsubsp, void, env, i32) +DEF_HELPER_2(xvmulsp, void, env, i32) DEF_HELPER_2(efscfsi, i32, env, i32) DEF_HELPER_2(efscfui, i32, env, i32) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index a2f2801..752dcb9 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7306,12 +7306,15 @@ static void gen_##name(DisasContext * ctx) \ GEN_VSX_HELPER_2(xsadddp, 0x00, 0x04, 0, PPC2_VSX) GEN_VSX_HELPER_2(xssubdp, 0x00, 0x05, 0, PPC2_VSX) +GEN_VSX_HELPER_2(xsmuldp, 0x00, 0x06, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
[Qemu-devel] [V5 PATCH 10/22] target-ppc: Add VSX ISA2.06 xdiv Instructions
This patch adds the VSX floating point divide instructions defined by V2.06 of the PowerPC ISA: xsdivdp, xvdivdp, xvdivsp. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Richard Henderson address@hidden --- V2: re-implemented the VSX_DIV macro. target-ppc/fpu_helper.c | 49 +++ target-ppc/helper.h |3 ++ target-ppc/translate.c |6 + 3 files changed, 58 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index 51ca589..c84f432 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -1855,3 +1855,52 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ VSX_MUL(xsmuldp, 1, float64, f64, 1) VSX_MUL(xvmuldp, 2, float64, f64, 0) VSX_MUL(xvmulsp, 4, float32, f32, 0) + +/* VSX_DIV - VSX floating point divide + * op- instruction mnemonic + * nels - number of elements (1, 2 or 4) + * tp- type (float32 or float64) + * fld - vsr_t field (f32 or f64) + * sfprf - set FPRF + */ +#define VSX_DIV(op, nels, tp, fld, sfprf) \ +void helper_##op(CPUPPCState *env, uint32_t opcode) \ +{ \ +ppc_vsr_t xt, xa, xb; \ +int i;\ + \ +getVSR(xA(opcode), xa, env); \ +getVSR(xB(opcode), xb, env); \ +getVSR(xT(opcode), xt, env); \ +helper_reset_fpstatus(env); \ + \ +for (i = 0; i nels; i++) { \ +float_status tstat = env-fp_status; \ +set_float_exception_flags(0, tstat); \ +xt.fld[i] = tp##_div(xa.fld[i], xb.fld[i], tstat); \ +env-fp_status.float_exception_flags |= tstat.float_exception_flags; \ + \ +if (unlikely(tstat.float_exception_flags float_flag_invalid)) { \ +if (tp##_is_infinity(xa.fld[i]) tp##_is_infinity(xb.fld[i])) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, sfprf); \ +} else if (tp##_is_zero(xa.fld[i]) \ +tp##_is_zero(xb.fld[i])) {\ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, sfprf); \ +} else if (tp##_is_signaling_nan(xa.fld[i]) ||\ +tp##_is_signaling_nan(xb.fld[i])) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);\ +} \ +} \ + \ +if (sfprf) { \ +helper_compute_fprf(env, xt.fld[i], sfprf); \ +} \ +} \ + \ +putVSR(xT(opcode), xt, env); \ +helper_float_check_status(env); \ +} + +VSX_DIV(xsdivdp, 1, float64, f64, 1) +VSX_DIV(xvdivdp, 2, float64, f64, 0) +VSX_DIV(xvdivsp, 4, float32, f32, 0) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index ecb900f..6ede7ea 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -254,14 +254,17 @@ DEF_HELPER_4(vctsxs, void, env, avr, avr, i32) DEF_HELPER_2(xsadddp, void, env, i32) DEF_HELPER_2(xssubdp, void, env, i32) DEF_HELPER_2(xsmuldp, void, env, i32) +DEF_HELPER_2(xsdivdp, void, env, i32) DEF_HELPER_2(xvadddp, void, env, i32) DEF_HELPER_2(xvsubdp, void, env, i32) DEF_HELPER_2(xvmuldp, void, env, i32) +DEF_HELPER_2(xvdivdp, void, env, i32) DEF_HELPER_2(xvaddsp, void, env, i32) DEF_HELPER_2(xvsubsp, void, env, i32) DEF_HELPER_2(xvmulsp, void, env, i32) +DEF_HELPER_2(xvdivsp, void, env, i32) DEF_HELPER_2(efscfsi, i32, env, i32) DEF_HELPER_2(efscfui, i32, env, i32) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 752dcb9..d2a326b 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7307,14
[Qemu-devel] [V5 PATCH 13/22] target-ppc: Add VSX ISA2.06 xrsqrte Instructions
This patch adds the VSX floating point reciprocal square root estimate instructions defined by V2.06 of the PowerPC ISA: xsrsqrtedp, xvrsqrtedp, xvrsqrtesp. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Richard Henderson address@hidden --- V2: re-implemented VSX_RSQRTE macro. target-ppc/fpu_helper.c | 45 + target-ppc/helper.h |3 +++ target-ppc/translate.c |6 ++ 3 files changed, 54 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index 060e6a0..31669f1 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -1983,3 +1983,48 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ VSX_SQRT(xssqrtdp, 1, float64, f64, 1) VSX_SQRT(xvsqrtdp, 2, float64, f64, 0) VSX_SQRT(xvsqrtsp, 4, float32, f32, 0) + +/* VSX_RSQRTE - VSX floating point reciprocal square root estimate + * op- instruction mnemonic + * nels - number of elements (1, 2 or 4) + * tp- type (float32 or float64) + * fld - vsr_t field (f32 or f64) + * sfprf - set FPRF + */ +#define VSX_RSQRTE(op, nels, tp, fld, sfprf) \ +void helper_##op(CPUPPCState *env, uint32_t opcode) \ +{\ +ppc_vsr_t xt, xb;\ +int i; \ + \ +getVSR(xB(opcode), xb, env);\ +getVSR(xT(opcode), xt, env);\ +helper_reset_fpstatus(env); \ + \ +for (i = 0; i nels; i++) { \ +float_status tstat = env-fp_status; \ +set_float_exception_flags(0, tstat);\ +xt.fld[i] = tp##_sqrt(xb.fld[i], tstat);\ +xt.fld[i] = tp##_div(tp##_one, xt.fld[i], tstat); \ +env-fp_status.float_exception_flags |= tstat.float_exception_flags; \ + \ +if (unlikely(tstat.float_exception_flags float_flag_invalid)) {\ +if (tp##_is_neg(xb.fld[i]) !tp##_is_zero(xb.fld[i])) {\ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf); \ +} else if (tp##_is_signaling_nan(xb.fld[i])) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ +}\ +}\ + \ +if (sfprf) { \ +helper_compute_fprf(env, xt.fld[i], sfprf); \ +}\ +}\ + \ +putVSR(xT(opcode), xt, env);\ +helper_float_check_status(env); \ +} + +VSX_RSQRTE(xsrsqrtedp, 1, float64, f64, 1) +VSX_RSQRTE(xvrsqrtedp, 2, float64, f64, 0) +VSX_RSQRTE(xvrsqrtesp, 4, float32, f32, 0) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index a6e7e62..4d5e31b 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -257,6 +257,7 @@ DEF_HELPER_2(xsmuldp, void, env, i32) DEF_HELPER_2(xsdivdp, void, env, i32) DEF_HELPER_2(xsredp, void, env, i32) DEF_HELPER_2(xssqrtdp, void, env, i32) +DEF_HELPER_2(xsrsqrtedp, void, env, i32) DEF_HELPER_2(xvadddp, void, env, i32) DEF_HELPER_2(xvsubdp, void, env, i32) @@ -264,6 +265,7 @@ DEF_HELPER_2(xvmuldp, void, env, i32) DEF_HELPER_2(xvdivdp, void, env, i32) DEF_HELPER_2(xvredp, void, env, i32) DEF_HELPER_2(xvsqrtdp, void, env, i32) +DEF_HELPER_2(xvrsqrtedp, void, env, i32) DEF_HELPER_2(xvaddsp, void, env, i32) DEF_HELPER_2(xvsubsp, void, env, i32) @@ -271,6 +273,7 @@ DEF_HELPER_2(xvmulsp, void, env, i32) DEF_HELPER_2(xvdivsp, void, env, i32) DEF_HELPER_2(xvresp, void, env, i32) DEF_HELPER_2(xvsqrtsp, void, env, i32) +DEF_HELPER_2(xvrsqrtesp, void, env, i32) DEF_HELPER_2(efscfsi, i32, env, i32) DEF_HELPER_2(efscfui, i32, env, i32) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index b89daf1..2b17dfd 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7310,6
[Qemu-devel] [V5 PATCH 18/22] target-ppc: Add VSX xmax/xmin Instructions
This patch adds the VSX floating point maximum and minimum instructions: - xsmaxdp, xvmaxdp, xvmaxsp - xsmindp, xvmindp, xvminsp Because of the Power ISA definitions of maximum and minimum on various boundary cases, the standard softfloat comparison routines (e.g. float64_lt) do not work as well as one might think. Therefore specific routines for comparing 64 and 32 bit floating point numbers are implemented in the PowerPC helper code. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Richard Henderson address@hidden --- V2: consolidated into a single macro, using the softfloat float*_max/float*_min routines. V5: Simplified implementation with new maxnum/minnum support in softfloat. target-ppc/fpu_helper.c | 39 +++ target-ppc/helper.h |6 ++ target-ppc/translate.c | 12 3 files changed, 57 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index eb5d878..8ece966 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -2288,3 +2288,42 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ VSX_SCALAR_CMP(xscmpodp, 1) VSX_SCALAR_CMP(xscmpudp, 0) + +#define float64_snan_to_qnan(x) ((x) | 0x0008ul) +#define float32_snan_to_qnan(x) ((x) | 0x0040) + +/* VSX_MAX_MIN - VSX floating point maximum/minimum + * name - instruction mnemonic + * op- operation (max or min) + * nels - number of elements (1, 2 or 4) + * tp- type (float32 or float64) + * fld - vsr_t field (f32 or f64) + */ +#define VSX_MAX_MIN(name, op, nels, tp, fld) \ +void helper_##name(CPUPPCState *env, uint32_t opcode) \ +{ \ +ppc_vsr_t xt, xa, xb; \ +int i;\ + \ +getVSR(xA(opcode), xa, env); \ +getVSR(xB(opcode), xb, env); \ +getVSR(xT(opcode), xt, env); \ + \ +for (i = 0; i nels; i++) { \ +xt.fld[i] = tp##_##op(xa.fld[i], xb.fld[i], env-fp_status); \ +if (unlikely(tp##_is_signaling_nan(xa.fld[i]) || \ + tp##_is_signaling_nan(xb.fld[i]))) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);\ +} \ +} \ + \ +putVSR(xT(opcode), xt, env); \ +helper_float_check_status(env); \ +} + +VSX_MAX_MIN(xsmaxdp, maxnum, 1, float64, f64) +VSX_MAX_MIN(xvmaxdp, maxnum, 2, float64, f64) +VSX_MAX_MIN(xvmaxsp, maxnum, 4, float32, f32) +VSX_MAX_MIN(xsmindp, minnum, 1, float64, f64) +VSX_MAX_MIN(xvmindp, minnum, 2, float64, f64) +VSX_MAX_MIN(xvminsp, minnum, 4, float32, f32) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index cd72388..4a65d39 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -270,6 +270,8 @@ DEF_HELPER_2(xsnmsubadp, void, env, i32) DEF_HELPER_2(xsnmsubmdp, void, env, i32) DEF_HELPER_2(xscmpodp, void, env, i32) DEF_HELPER_2(xscmpudp, void, env, i32) +DEF_HELPER_2(xsmaxdp, void, env, i32) +DEF_HELPER_2(xsmindp, void, env, i32) DEF_HELPER_2(xvadddp, void, env, i32) DEF_HELPER_2(xvsubdp, void, env, i32) @@ -288,6 +290,8 @@ DEF_HELPER_2(xvnmaddadp, void, env, i32) DEF_HELPER_2(xvnmaddmdp, void, env, i32) DEF_HELPER_2(xvnmsubadp, void, env, i32) DEF_HELPER_2(xvnmsubmdp, void, env, i32) +DEF_HELPER_2(xvmaxdp, void, env, i32) +DEF_HELPER_2(xvmindp, void, env, i32) DEF_HELPER_2(xvaddsp, void, env, i32) DEF_HELPER_2(xvsubsp, void, env, i32) @@ -306,6 +310,8 @@ DEF_HELPER_2(xvnmaddasp, void, env, i32) DEF_HELPER_2(xvnmaddmsp, void, env, i32) DEF_HELPER_2(xvnmsubasp, void, env, i32) DEF_HELPER_2(xvnmsubmsp, void, env, i32) +DEF_HELPER_2(xvmaxsp, void, env, i32) +DEF_HELPER_2(xvminsp, void, env, i32) DEF_HELPER_2(efscfsi, i32, env, i32) DEF_HELPER_2(efscfui, i32, env, i32) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 9325a4c..5cf2335 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7323,6 +7323,8 @@ GEN_VSX_HELPER_2(xsnmsubadp, 0x04, 0x16, 0, PPC2_VSX) GEN_VSX_HELPER_2(xsnmsubmdp, 0x04, 0x17, 0, PPC2_VSX) GEN_VSX_HELPER_2(xscmpodp, 0x0C, 0x05, 0,
[Qemu-devel] [V5 PATCH 15/22] target-ppc: Add VSX ISA2.06 xtsqrt Instructions
This patch adds the VSX floating point test for software square root instructions defined by V2.06 of the PowerPC ISA: xstsqrtdp, xvtsqrtdp, xvtsqrtsp. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Richard Henderson address@hidden --- V2: (a) using locally implemented ppc_float*_get_unbiased_exp routines (b) eliminated dependency on float*_is_denormal(). target-ppc/fpu_helper.c | 54 +++ target-ppc/helper.h |3 ++ target-ppc/translate.c |6 + 3 files changed, 63 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index ee03942..73227b7 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -2095,3 +2095,57 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ VSX_TDIV(xstdivdp, 1, float64, f64, -1022, 1023, 52) VSX_TDIV(xvtdivdp, 2, float64, f64, -1022, 1023, 52) VSX_TDIV(xvtdivsp, 4, float32, f32, -126, 127, 23) + +/* VSX_TSQRT - VSX floating point test for square root + * op- instruction mnemonic + * nels - number of elements (1, 2 or 4) + * tp- type (float32 or float64) + * fld - vsr_t field (f32 or f64) + * emin - minimum unbiased exponent + * emax - maximum unbiased exponent + * nbits - number of fraction bits + */ +#define VSX_TSQRT(op, nels, tp, fld, emin, nbits) \ +void helper_##op(CPUPPCState *env, uint32_t opcode) \ +{ \ +ppc_vsr_t xa, xb; \ +int i; \ +int fe_flag = 0;\ +int fg_flag = 0;\ +\ +getVSR(xA(opcode), xa, env); \ +getVSR(xB(opcode), xb, env); \ +\ +for (i = 0; i nels; i++) {\ +if (unlikely(tp##_is_infinity(xb.fld[i]) || \ + tp##_is_zero(xb.fld[i]))) {\ +fe_flag = 1;\ +fg_flag = 1;\ +} else {\ +int e_b = ppc_##tp##_get_unbiased_exp(xb.fld[i]); \ +\ +if (unlikely(tp##_is_any_nan(xb.fld[i]))) { \ +fe_flag = 1;\ +} else if (unlikely(tp##_is_zero(xb.fld[i]))) { \ +fe_flag = 1;\ +} else if (unlikely(tp##_is_neg(xb.fld[i]))) { \ +fe_flag = 1;\ +} else if (!tp##_is_zero(xb.fld[i]) \ + (e_b = (emin+nbits))) { \ +fe_flag = 1;\ +} \ +\ +if (unlikely(tp##_is_zero_or_denormal(xb.fld[i]))) {\ +/* XB is not zero because of the above check and */ \ +/* therefore must be denormalized. */ \ +fg_flag = 1;\ +} \ +} \ +} \ +\ +env-crf[BF(opcode)] = 0x8 | (fg_flag ? 4 : 0) | (fe_flag ? 2 : 0); \ +} + +VSX_TSQRT(xstsqrtdp, 1, float64, f64, -1022, 52) +VSX_TSQRT(xvtsqrtdp, 2, float64, f64, -1022, 52) +VSX_TSQRT(xvtsqrtsp, 4, float32, f32, -126, 23) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 80cffc9..c413c98 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -259,6 +259,7 @@ DEF_HELPER_2(xsredp, void, env, i32) DEF_HELPER_2(xssqrtdp, void, env, i32) DEF_HELPER_2(xsrsqrtedp, void, env, i32) DEF_HELPER_2(xstdivdp, void, env, i32) +DEF_HELPER_2(xstsqrtdp, void, env, i32) DEF_HELPER_2(xvadddp, void, env, i32) DEF_HELPER_2(xvsubdp, void, env, i32) @@ -268,6 +269,7 @@ DEF_HELPER_2(xvredp, void, env, i32) DEF_HELPER_2(xvsqrtdp, void, env, i32) DEF_HELPER_2(xvrsqrtedp, void, env, i32) DEF_HELPER_2(xvtdivdp,
[Qemu-devel] [V5 PATCH 22/22] target-ppc: Add VSX Rounding Instructions
This patch adds the VSX Round to Floating Point Integer instructions: - xsrdpi, xsrdpic, xsrdpim, xsrdpip, xsrdpiz - xvrdpi, xvrdpic, xvrdpim, xvrdpip, xvrdpiz - xvrspi, xvrspic, xvrspim, xvrspip, xvrspiz Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Richard Henderson address@hidden --- target-ppc/fpu_helper.c | 68 +++ target-ppc/helper.h | 15 ++ target-ppc/translate.c | 30 3 files changed, 113 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index 3970652..3165ef0 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -2537,3 +2537,71 @@ VSX_CVT_INT_TO_FP(xvcvuxdsp, 2, uint64, float32, u64[i], f32[j], \ 2*i + JOFFSET, 0) VSX_CVT_INT_TO_FP(xvcvsxwsp, 4, int32, float32, u32[j], f32[i], i, 0) VSX_CVT_INT_TO_FP(xvcvuxwsp, 4, uint32, float32, u32[j], f32[i], i, 0) + +/* For use current rounding mode, define a value that will not be one of + * the existing rounding model enums. + */ +#define FLOAT_ROUND_CURRENT (float_round_nearest_even + float_round_down + \ + float_round_up + float_round_to_zero) + +/* VSX_ROUND - VSX floating point round + * op- instruction mnemonic + * nels - number of elements (1, 2 or 4) + * tp- type (float32 or float64) + * fld - vsr_t field (f32 or f64) + * rmode - rounding mode + * sfprf - set FPRF + */ +#define VSX_ROUND(op, nels, tp, fld, rmode, sfprf) \ +void helper_##op(CPUPPCState *env, uint32_t opcode)\ +{ \ +ppc_vsr_t xt, xb; \ +int i; \ +getVSR(xB(opcode), xb, env); \ +getVSR(xT(opcode), xt, env); \ + \ +if (rmode != FLOAT_ROUND_CURRENT) {\ +set_float_rounding_mode(rmode, env-fp_status); \ +} \ + \ +for (i = 0; i nels; i++) { \ +if (unlikely(tp##_is_signaling_nan(xb.fld[i]))) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ +xt.fld[i] = tp##_snan_to_qnan(xb.fld[i]); \ +} else { \ +xt.fld[i] = tp##_round_to_int(xb.fld[i], env-fp_status); \ +} \ +if (sfprf) { \ +helper_compute_fprf(env, xt.fld[i], sfprf);\ +} \ +} \ + \ +/* If this is not a use current rounding mode instruction, \ + * then inhibit setting of the XX bit and restore rounding \ + * mode from FPSCR */ \ +if (rmode != FLOAT_ROUND_CURRENT) {\ +fpscr_set_rounding_mode(env); \ +env-fp_status.float_exception_flags = ~float_flag_inexact; \ +} \ + \ +putVSR(xT(opcode), xt, env); \ +helper_float_check_status(env);\ +} + +VSX_ROUND(xsrdpi, 1, float64, f64, float_round_nearest_even, 1) +VSX_ROUND(xsrdpic, 1, float64, f64, FLOAT_ROUND_CURRENT, 1) +VSX_ROUND(xsrdpim, 1, float64, f64, float_round_down, 1) +VSX_ROUND(xsrdpip, 1, float64, f64, float_round_up, 1) +VSX_ROUND(xsrdpiz, 1, float64, f64, float_round_to_zero, 1) + +VSX_ROUND(xvrdpi, 2, float64, f64, float_round_nearest_even, 0) +VSX_ROUND(xvrdpic, 2, float64, f64, FLOAT_ROUND_CURRENT, 0) +VSX_ROUND(xvrdpim, 2, float64, f64, float_round_down, 0) +VSX_ROUND(xvrdpip, 2, float64, f64, float_round_up, 0) +VSX_ROUND(xvrdpiz, 2, float64, f64, float_round_to_zero, 0) + +VSX_ROUND(xvrspi, 4, float32, f32, float_round_nearest_even, 0) +VSX_ROUND(xvrspic, 4, float32, f32, FLOAT_ROUND_CURRENT, 0) +VSX_ROUND(xvrspim, 4, float32, f32, float_round_down, 0) +VSX_ROUND(xvrspip, 4, float32, f32, float_round_up, 0) +VSX_ROUND(xvrspiz, 4, float32, f32, float_round_to_zero, 0) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index de46b6f..0276b02 100644 --- a/target-ppc/helper.h +++
[Qemu-devel] [V5 PATCH 21/22] target-ppc: Add VSX ISA2.06 Integer Conversion Instructions
This patch adds the VSX Integer Conversion instructions defined by V2.06 of the PowerPC ISA: - xscvdpsxds, xscvdpsxws, xscvdpuxds, xscvdpuxws - xvcvdpsxds, xvcvdpsxws, xvcvdpuxds, xvcvdpuxws - xvcvspsxds, xvcvspsxws, xvcvspuxds, xvcvspuxws - xscvsxddp, xscvuxddp - xvcvsxddp, xscvsxwdp, xvcvuxddp, xvcvuxwdp - xvcvsxdsp, xscvsxwsp, xvcvuxdsp, xvcvuxwsp Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Richard Henderson address@hidden --- target-ppc/fpu_helper.c | 107 +++ target-ppc/helper.h | 22 ++ target-ppc/translate.c | 44 +++ 3 files changed, 173 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index 6a428c9..3970652 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -2430,3 +2430,110 @@ VSX_CVT_FP_TO_FP(xscvdpsp, 1, float64, float32, f64[i], f32[j], 1) VSX_CVT_FP_TO_FP(xscvspdp, 1, float32, float64, f32[j], f64[i], 1) VSX_CVT_FP_TO_FP(xvcvdpsp, 2, float64, float32, f64[i], f32[j], 0) VSX_CVT_FP_TO_FP(xvcvspdp, 2, float32, float64, f32[j], f64[i], 0) + +/* VSX_CVT_FP_TO_INT - VSX floating point to integer conversion + * op- instruction mnemonic + * nels - number of elements (1, 2 or 4) + * stp - source type (float32 or float64) + * ttp - target type (int32, uint32, int64 or uint64) + * sfld - source vsr_t field + * tfld - target vsr_t field + * jdef - definition of the j index (i or 2*i) + * rnan - resulting NaN + */ +#define VSX_CVT_FP_TO_INT(op, nels, stp, ttp, sfld, tfld, jdef, rnan)\ +void helper_##op(CPUPPCState *env, uint32_t opcode) \ +{\ +ppc_vsr_t xt, xb;\ +int i; \ + \ +getVSR(xB(opcode), xb, env);\ +getVSR(xT(opcode), xt, env);\ + \ +for (i = 0; i nels; i++) { \ +int j = jdef;\ +if (unlikely(stp##_is_any_nan(xb.sfld))) { \ +if (stp##_is_signaling_nan(xb.sfld)) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ +}\ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0);\ +xt.tfld = rnan; \ +} else { \ +xt.tfld = stp##_to_##ttp(xb.sfld, env-fp_status); \ +if (env-fp_status.float_exception_flags float_flag_invalid) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0);\ +}\ +}\ +}\ + \ +putVSR(xT(opcode), xt, env);\ +helper_float_check_status(env); \ +} + +VSX_CVT_FP_TO_INT(xscvdpsxds, 1, float64, int64, f64[j], u64[i], i, \ + 0x8000ul) +VSX_CVT_FP_TO_INT(xscvdpsxws, 1, float64, int32, f64[i], u32[j], \ + 2*i + JOFFSET, 0x8000l) +VSX_CVT_FP_TO_INT(xscvdpuxds, 1, float64, uint64, f64[j], u64[i], i, 0ul) +VSX_CVT_FP_TO_INT(xscvdpuxws, 1, float64, uint32, f64[i], u32[j], \ + 2*i + JOFFSET, 0) +VSX_CVT_FP_TO_INT(xvcvdpsxds, 2, float64, int64, f64[j], u64[i], i, \ + 0x8000ul) +VSX_CVT_FP_TO_INT(xvcvdpsxws, 2, float64, int32, f64[i], u32[j], \ + 2*i + JOFFSET, 0x8000l) +VSX_CVT_FP_TO_INT(xvcvdpuxds, 2, float64, uint64, f64[j], u64[i], i, 0ul) +VSX_CVT_FP_TO_INT(xvcvdpuxws, 2, float64, uint32, f64[i], u32[j], \ + 2*i + JOFFSET, 0) +VSX_CVT_FP_TO_INT(xvcvspsxds, 2, float32, int64, f32[j], u64[i], \ + 2*i + JOFFSET, 0x8000ul) +VSX_CVT_FP_TO_INT(xvcvspsxws, 4, float32, int32, f32[j], u32[j], i, \ + 0x8000l) +VSX_CVT_FP_TO_INT(xvcvspuxds, 2, float32, uint64, f32[j], u64[i], \ + 2*i + JOFFSET, 0ul) +VSX_CVT_FP_TO_INT(xvcvspuxws, 4, float32, uint32, f32[j], u32[i], i, 0) + +/* VSX_CVT_INT_TO_FP - VSX integer to floating point conversion + * op
[Qemu-devel] [V5 PATCH 17/22] target-ppc: Add VSX xscmp*dp Instructions
This patch adds the VSX scalar floating point compare ordered and unordered instructions. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Richard Henderson address@hidden --- target-ppc/fpu_helper.c | 39 +++ target-ppc/helper.h |2 ++ target-ppc/translate.c |4 3 files changed, 45 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index 54c47c8..eb5d878 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -2249,3 +2249,42 @@ VSX_MADD(xvnmaddasp, 4, float32, f32, NMADD_FLGS, 1, 0) VSX_MADD(xvnmaddmsp, 4, float32, f32, NMADD_FLGS, 0, 0) VSX_MADD(xvnmsubasp, 4, float32, f32, NMSUB_FLGS, 1, 0) VSX_MADD(xvnmsubmsp, 4, float32, f32, NMSUB_FLGS, 0, 0) + +#define VSX_SCALAR_CMP(op, ordered) \ +void helper_##op(CPUPPCState *env, uint32_t opcode) \ +{\ +ppc_vsr_t xa, xb;\ +uint32_t cc = 0; \ + \ +getVSR(xA(opcode), xa, env);\ +getVSR(xB(opcode), xb, env);\ + \ +if (unlikely(float64_is_any_nan(xa.f64[0]) ||\ + float64_is_any_nan(xb.f64[0]))) { \ +if (float64_is_signaling_nan(xa.f64[0]) || \ +float64_is_signaling_nan(xb.f64[0])) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ +}\ +if (ordered) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); \ +}\ +cc = 1; \ +} else { \ +if (float64_lt(xa.f64[0], xb.f64[0], env-fp_status)) { \ +cc = 8; \ +} else if (!float64_le(xa.f64[0], xb.f64[0], env-fp_status)) { \ +cc = 4; \ +} else { \ +cc = 2; \ +}\ +}\ + \ +env-fpscr = ~(0x0F FPSCR_FPRF); \ +env-fpscr |= cc FPSCR_FPRF; \ +env-crf[BF(opcode)] = cc; \ + \ +helper_float_check_status(env); \ +} + +VSX_SCALAR_CMP(xscmpodp, 1) +VSX_SCALAR_CMP(xscmpudp, 0) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 7368908..cd72388 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -268,6 +268,8 @@ DEF_HELPER_2(xsnmaddadp, void, env, i32) DEF_HELPER_2(xsnmaddmdp, void, env, i32) DEF_HELPER_2(xsnmsubadp, void, env, i32) DEF_HELPER_2(xsnmsubmdp, void, env, i32) +DEF_HELPER_2(xscmpodp, void, env, i32) +DEF_HELPER_2(xscmpudp, void, env, i32) DEF_HELPER_2(xvadddp, void, env, i32) DEF_HELPER_2(xvsubdp, void, env, i32) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 1b47099..9325a4c 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7321,6 +7321,8 @@ GEN_VSX_HELPER_2(xsnmaddadp, 0x04, 0x14, 0, PPC2_VSX) GEN_VSX_HELPER_2(xsnmaddmdp, 0x04, 0x15, 0, PPC2_VSX) GEN_VSX_HELPER_2(xsnmsubadp, 0x04, 0x16, 0, PPC2_VSX) GEN_VSX_HELPER_2(xsnmsubmdp, 0x04, 0x17, 0, PPC2_VSX) +GEN_VSX_HELPER_2(xscmpodp, 0x0C, 0x05, 0, PPC2_VSX) +GEN_VSX_HELPER_2(xscmpudp, 0x0C, 0x04, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX) @@ -10056,6 +10058,8 @@ GEN_XX3FORM(xsnmaddadp, 0x04, 0x14, PPC2_VSX), GEN_XX3FORM(xsnmaddmdp, 0x04, 0x15, PPC2_VSX), GEN_XX3FORM(xsnmsubadp, 0x04, 0x16, PPC2_VSX), GEN_XX3FORM(xsnmsubmdp, 0x04, 0x17, PPC2_VSX), +GEN_XX2FORM(xscmpodp, 0x0C, 0x05, PPC2_VSX), +GEN_XX2FORM(xscmpudp, 0x0C, 0x04, PPC2_VSX), GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX), GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX), -- 1.7.1
[Qemu-devel] [V5 PATCH 20/22] target-ppc: Add VSX Floating Point to Floating Point Conversion Instructions
This patch adds the VSX instructions that convert between floating point formats: xscvdpsp, xscvspdp, xvcvdpsp, xvcvspdp. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Richard Henderson address@hidden --- target-ppc/fpu_helper.c | 45 + target-ppc/helper.h |4 target-ppc/translate.c |8 3 files changed, 57 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index dafc41c..6a428c9 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -2385,3 +2385,48 @@ VSX_CMP(xvcmpeqsp, 4, float32, f32, eq, 0) VSX_CMP(xvcmpgesp, 4, float32, f32, le, 1) VSX_CMP(xvcmpgtsp, 4, float32, f32, lt, 1) +#if defined(HOST_WORDS_BIGENDIAN) +#define JOFFSET 0 +#else +#define JOFFSET 1 +#endif + +/* VSX_CVT_FP_TO_FP - VSX floating point/floating point conversion + * op- instruction mnemonic + * nels - number of elements (1, 2 or 4) + * stp - source type (float32 or float64) + * ttp - target type (float32 or float64) + * sfld - source vsr_t field + * tfld - target vsr_t field (f32 or f64) + * sfprf - set FPRF + */ +#define VSX_CVT_FP_TO_FP(op, nels, stp, ttp, sfld, tfld, sfprf)\ +void helper_##op(CPUPPCState *env, uint32_t opcode)\ +{ \ +ppc_vsr_t xt, xb; \ +int i; \ + \ +getVSR(xB(opcode), xb, env); \ +getVSR(xT(opcode), xt, env); \ + \ +for (i = 0; i nels; i++) { \ +int j = 2*i + JOFFSET; \ +xt.tfld = stp##_to_##ttp(xb.sfld, env-fp_status);\ +if (unlikely(stp##_is_signaling_nan(xb.sfld))) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ +xt.tfld = ttp##_snan_to_qnan(xt.tfld); \ +} \ +if (sfprf) { \ +helper_compute_fprf(env, ttp##_to_float64(xt.tfld, \ +env-fp_status), sfprf); \ +} \ +} \ + \ +putVSR(xT(opcode), xt, env); \ +helper_float_check_status(env);\ +} + +VSX_CVT_FP_TO_FP(xscvdpsp, 1, float64, float32, f64[i], f32[j], 1) +VSX_CVT_FP_TO_FP(xscvspdp, 1, float32, float64, f32[j], f64[i], 1) +VSX_CVT_FP_TO_FP(xvcvdpsp, 2, float64, float32, f64[i], f32[j], 0) +VSX_CVT_FP_TO_FP(xvcvspdp, 2, float32, float64, f32[j], f64[i], 0) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 35389c5..dd9518c 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -272,6 +272,8 @@ DEF_HELPER_2(xscmpodp, void, env, i32) DEF_HELPER_2(xscmpudp, void, env, i32) DEF_HELPER_2(xsmaxdp, void, env, i32) DEF_HELPER_2(xsmindp, void, env, i32) +DEF_HELPER_2(xscvdpsp, void, env, i32) +DEF_HELPER_2(xscvspdp, void, env, i32) DEF_HELPER_2(xvadddp, void, env, i32) DEF_HELPER_2(xvsubdp, void, env, i32) @@ -295,6 +297,7 @@ DEF_HELPER_2(xvmindp, void, env, i32) DEF_HELPER_2(xvcmpeqdp, void, env, i32) DEF_HELPER_2(xvcmpgedp, void, env, i32) DEF_HELPER_2(xvcmpgtdp, void, env, i32) +DEF_HELPER_2(xvcvdpsp, void, env, i32) DEF_HELPER_2(xvaddsp, void, env, i32) DEF_HELPER_2(xvsubsp, void, env, i32) @@ -318,6 +321,7 @@ DEF_HELPER_2(xvminsp, void, env, i32) DEF_HELPER_2(xvcmpeqsp, void, env, i32) DEF_HELPER_2(xvcmpgesp, void, env, i32) DEF_HELPER_2(xvcmpgtsp, void, env, i32) +DEF_HELPER_2(xvcvspdp, void, env, i32) DEF_HELPER_2(efscfsi, i32, env, i32) DEF_HELPER_2(efscfui, i32, env, i32) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 4638b6c..8abeb22 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7325,6 +7325,8 @@ GEN_VSX_HELPER_2(xscmpodp, 0x0C, 0x05, 0, PPC2_VSX) GEN_VSX_HELPER_2(xscmpudp, 0x0C, 0x04, 0, PPC2_VSX) GEN_VSX_HELPER_2(xsmaxdp, 0x00, 0x14, 0, PPC2_VSX) GEN_VSX_HELPER_2(xsmindp, 0x00, 0x15, 0, PPC2_VSX) +GEN_VSX_HELPER_2(xscvdpsp, 0x12, 0x10, 0, PPC2_VSX) +GEN_VSX_HELPER_2(xscvspdp, 0x12, 0x14, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX) @@ -7348,6 +7350,7 @@ GEN_VSX_HELPER_2(xvmindp, 0x00, 0x1D, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvcmpeqdp, 0x0C, 0x0C, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvcmpgtdp, 0x0C, 0x0D, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvcmpgedp,
Re: [Qemu-devel] [PATCH 2/2] hw/arm/allwinner-a10: initialize EMAC
On Fri, Jan 3, 2014 at 3:19 AM, Beniamino Galvani b.galv...@gmail.com wrote: On Thu, Jan 02, 2014 at 08:20:12PM +1000, Peter Crosthwaite wrote: On Thu, Jan 2, 2014 at 7:18 PM, Beniamino Galvani b.galv...@gmail.com wrote: Signed-off-by: Beniamino Galvani b.galv...@gmail.com --- hw/arm/allwinner-a10.c | 20 include/hw/arm/allwinner-a10.h |4 2 files changed, 24 insertions(+) diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index 4658e19..155e026 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -22,6 +22,7 @@ static void aw_a10_init(Object *obj) { AwA10State *s = AW_A10(obj); +DeviceState *dev; For consistency with surrounding code, you could just cast to DEVICE include and drop the new local var. Ok. object_initialize(s-cpu, sizeof(s-cpu), cortex-a8- TYPE_ARM_CPU); object_property_add_child(obj, cpu, OBJECT(s-cpu), NULL); @@ -31,6 +32,14 @@ static void aw_a10_init(Object *obj) object_initialize(s-timer, sizeof(s-timer), TYPE_AW_A10_PIT); qdev_set_parent_bus(DEVICE(s-timer), sysbus_get_default()); + +if (nd_table[0].used) { So with SoC MACs, they are always there. I think this conditional should be removed, and the MAC is always instantiated. ... +qemu_check_nic_model(nd_table[0], allwinner_emac); +object_initialize(s-emac, sizeof(s-emac), TYPE_AW_EMAC); +dev = DEVICE(s-emac); +qdev_set_nic_properties(dev, nd_table[0]); ... and then only this is conditional on nd_table.used. The mac model itself then of course needs to be hardened against a null netargs. +qdev_set_parent_bus(dev, sysbus_get_default()); +} } So, if I understand correctly, the part under the condition should be: qdev_set_parent_bus(dev, sysbus_get_default()); No, I meant the line above, qdev_set_nic_properties. This corresponds to attaching the always-present NIC to an emulated network. Regards, Peter right? static void aw_a10_realize(DeviceState *dev, Error **errp) @@ -76,6 +85,17 @@ static void aw_a10_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(sysbusdev, 4, s-irq[67]); sysbus_connect_irq(sysbusdev, 5, s-irq[68]); +if (nd_table[0].used) { +object_property_set_bool(OBJECT(s-emac), true, realized, err); +if (err != NULL) { +error_propagate(errp, err); +return; +} +sysbusdev = SYS_BUS_DEVICE(s-emac); +sysbus_mmio_map(sysbusdev, 0, AW_A10_EMAC_BASE); +sysbus_connect_irq(sysbusdev, 0, s-irq[55]); +} + serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2, s-irq[1], 115200, serial_hds[0], DEVICE_NATIVE_ENDIAN); } diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h index da36647..6ea5988 100644 --- a/include/hw/arm/allwinner-a10.h +++ b/include/hw/arm/allwinner-a10.h @@ -6,6 +6,7 @@ #include hw/arm/arm.h #include hw/timer/allwinner-a10-pit.h #include hw/intc/allwinner-a10-pic.h +#include hw/net/allwinner_emac.h #include sysemu/sysemu.h #include exec/address-spaces.h @@ -14,9 +15,11 @@ #define AW_A10_PIC_REG_BASE 0x01c20400 #define AW_A10_PIT_REG_BASE 0x01c20c00 #define AW_A10_UART0_REG_BASE 0x01c28000 +#define AW_A10_EMAC_BASE0x01c0b000 #define AW_A10_SDRAM_BASE 0x4000 + This whitespace change intended? No, a leftover. Thanks, Beniamino
[Qemu-devel] [V5 PATCH 19/22] target-ppc: Add VSX Vector Compare Instructions
This patch adds the VSX floating point compare vector instructions: - xvcmpeqdp[.], xvcmpgedp[.], xvcmpgtdp[.] - xvcmpeqsp[.], xvcmpgesp[.], xvcmpgtsp[.] Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Richard Henderson address@hidden --- target-ppc/fpu_helper.c | 58 +++ target-ppc/helper.h |6 + target-ppc/translate.c | 23 ++ 3 files changed, 87 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index 8ece966..dafc41c 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -2327,3 +2327,61 @@ VSX_MAX_MIN(xvmaxsp, maxnum, 4, float32, f32) VSX_MAX_MIN(xsmindp, minnum, 1, float64, f64) VSX_MAX_MIN(xvmindp, minnum, 2, float64, f64) VSX_MAX_MIN(xvminsp, minnum, 4, float32, f32) + +/* VSX_CMP - VSX floating point compare + * op- instruction mnemonic + * nels - number of elements (1, 2 or 4) + * tp- type (float32 or float64) + * fld - vsr_t field (f32 or f64) + * cmp - comparison operation + * svxvc - set VXVC bit + */ +#define VSX_CMP(op, nels, tp, fld, cmp, svxvc)\ +void helper_##op(CPUPPCState *env, uint32_t opcode) \ +{ \ +ppc_vsr_t xt, xa, xb; \ +int i;\ +int all_true = 1; \ +int all_false = 1;\ + \ +getVSR(xA(opcode), xa, env); \ +getVSR(xB(opcode), xb, env); \ +getVSR(xT(opcode), xt, env); \ + \ +for (i = 0; i nels; i++) { \ +if (unlikely(tp##_is_any_nan(xa.fld[i]) ||\ + tp##_is_any_nan(xb.fld[i]))) { \ +if (tp##_is_signaling_nan(xa.fld[i]) || \ +tp##_is_signaling_nan(xb.fld[i])) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);\ +} \ +if (svxvc) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); \ +} \ +xt.fld[i] = 0;\ +all_true = 0; \ +} else { \ +if (tp##_##cmp(xb.fld[i], xa.fld[i], env-fp_status) == 1) { \ +xt.fld[i] = -1; \ +all_false = 0;\ +} else { \ +xt.fld[i] = 0;\ +all_true = 0; \ +} \ +} \ +} \ + \ +putVSR(xT(opcode), xt, env); \ +if ((opcode (31-21)) 1) {\ +env-crf[6] = (all_true ? 0x8 : 0) | (all_false ? 0x2 : 0); \ +} \ +helper_float_check_status(env); \ + } + +VSX_CMP(xvcmpeqdp, 2, float64, f64, eq, 0) +VSX_CMP(xvcmpgedp, 2, float64, f64, le, 1) +VSX_CMP(xvcmpgtdp, 2, float64, f64, lt, 1) +VSX_CMP(xvcmpeqsp, 4, float32, f32, eq, 0) +VSX_CMP(xvcmpgesp, 4, float32, f32, le, 1) +VSX_CMP(xvcmpgtsp, 4, float32, f32, lt, 1) + diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 4a65d39..35389c5 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -292,6 +292,9 @@ DEF_HELPER_2(xvnmsubadp, void, env, i32) DEF_HELPER_2(xvnmsubmdp, void, env, i32) DEF_HELPER_2(xvmaxdp, void, env, i32) DEF_HELPER_2(xvmindp, void, env, i32) +DEF_HELPER_2(xvcmpeqdp, void, env, i32) +DEF_HELPER_2(xvcmpgedp, void, env, i32) +DEF_HELPER_2(xvcmpgtdp, void, env, i32) DEF_HELPER_2(xvaddsp, void, env, i32) DEF_HELPER_2(xvsubsp, void, env, i32) @@ -312,6 +315,9 @@
[Qemu-devel] [V5 PATCH 14/22] target-ppc: Add VSX ISA2.06 xtdiv Instructions
This patch adds the VSX floating point test for software divide instructions defined by V2.06 of the PowerPC ISA: xstdivdp, xvtdivdp, and xvtdivsp. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Richard Henderson address@hidden --- V2: added ppc_float*_get_unbiased_exp() routines (pulled back from softfloat). Eliminated dependency on float*_is_denormalized() routines. target-ppc/fpu_helper.c | 67 +++ target-ppc/helper.h |3 ++ target-ppc/translate.c |6 3 files changed, 76 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index 31669f1..ee03942 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -2028,3 +2028,70 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ VSX_RSQRTE(xsrsqrtedp, 1, float64, f64, 1) VSX_RSQRTE(xvrsqrtedp, 2, float64, f64, 0) VSX_RSQRTE(xvrsqrtesp, 4, float32, f32, 0) + +static inline int ppc_float32_get_unbiased_exp(float32 f) +{ +return ((f 23) 0xFF) - 127; +} + +static inline int ppc_float64_get_unbiased_exp(float64 f) +{ +return ((f 52) 0x7FF) - 1023; +} + +/* VSX_TDIV - VSX floating point test for divide + * op- instruction mnemonic + * nels - number of elements (1, 2 or 4) + * tp- type (float32 or float64) + * fld - vsr_t field (f32 or f64) + * emin - minimum unbiased exponent + * emax - maximum unbiased exponent + * nbits - number of fraction bits + */ +#define VSX_TDIV(op, nels, tp, fld, emin, emax, nbits) \ +void helper_##op(CPUPPCState *env, uint32_t opcode) \ +{ \ +ppc_vsr_t xa, xb; \ +int i; \ +int fe_flag = 0;\ +int fg_flag = 0;\ +\ +getVSR(xA(opcode), xa, env); \ +getVSR(xB(opcode), xb, env); \ +\ +for (i = 0; i nels; i++) {\ +if (unlikely(tp##_is_infinity(xa.fld[i]) || \ + tp##_is_infinity(xb.fld[i]) || \ + tp##_is_zero(xb.fld[i]))) {\ +fe_flag = 1;\ +fg_flag = 1;\ +} else {\ +int e_a = ppc_##tp##_get_unbiased_exp(xa.fld[i]); \ +int e_b = ppc_##tp##_get_unbiased_exp(xb.fld[i]); \ +\ +if (unlikely(tp##_is_any_nan(xa.fld[i]) || \ + tp##_is_any_nan(xb.fld[i]))) { \ +fe_flag = 1;\ +} else if ((e_b = emin) || (e_b = (emax-2))) {\ +fe_flag = 1;\ +} else if (!tp##_is_zero(xa.fld[i]) \ + (((e_a - e_b) = emax) ||\ +((e_a - e_b) = (emin+1)) ||\ + (e_a = (emin+nbits { \ +fe_flag = 1;\ +} \ +\ +if (unlikely(tp##_is_zero_or_denormal(xb.fld[i]))) {\ +/* XB is not zero because of the above check and */ \ +/* so must be denormalized. */ \ +fg_flag = 1;\ +} \ +} \ +} \ +\ +env-crf[BF(opcode)] = 0x8 | (fg_flag ? 4 : 0) | (fe_flag ? 2 : 0); \ +} + +VSX_TDIV(xstdivdp, 1, float64, f64, -1022, 1023, 52) +VSX_TDIV(xvtdivdp, 2, float64, f64, -1022, 1023, 52) +VSX_TDIV(xvtdivsp, 4, float32, f32, -126, 127, 23) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 4d5e31b..80cffc9 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -258,6 +258,7 @@ DEF_HELPER_2(xsdivdp,
[Qemu-devel] [V5 PATCH 07/22] target-ppc: General Support for VSX Helpers
This patch adds general support that will be used by the VSX helper routines: - a union describing the various VSR subfields. - access routines to get and set VSRs - VSX decoders - a general routine to generate a handler that invokes a VSX helper. Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Richard Henderson address@hidden --- target-ppc/fpu_helper.c | 41 + target-ppc/translate.c | 14 ++ 2 files changed, 55 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index f0b0a49..cea94ac 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -1717,3 +1717,44 @@ uint32_t helper_efdcmpeq(CPUPPCState *env, uint64_t op1, uint64_t op2) /* XXX: TODO: test special values (NaN, infinites, ...) */ return helper_efdtsteq(env, op1, op2); } + +#define DECODE_SPLIT(opcode, shift1, nb1, shift2, nb2) \ +(opcode) (shift1)) ((1 (nb1)) - 1)) nb2) |\ + (((opcode) (shift2)) ((1 (nb2)) - 1))) + +#define xT(opcode) DECODE_SPLIT(opcode, 0, 1, 21, 5) +#define xA(opcode) DECODE_SPLIT(opcode, 2, 1, 16, 5) +#define xB(opcode) DECODE_SPLIT(opcode, 1, 1, 11, 5) +#define xC(opcode) DECODE_SPLIT(opcode, 3, 1, 6, 5) +#define BF(opcode) (((opcode) (31-8)) 7) + +typedef union _ppc_vsr_t { +uint64_t u64[2]; +uint32_t u32[4]; +float32 f32[4]; +float64 f64[2]; +} ppc_vsr_t; + +static void getVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env) +{ +if (n 32) { +vsr-f64[0] = env-fpr[n]; +vsr-u64[1] = env-vsr[n]; +} else { +vsr-u64[0] = env-avr[n-32].u64[0]; +vsr-u64[1] = env-avr[n-32].u64[1]; +} +} + +static void putVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env) +{ +if (n 32) { +env-fpr[n] = vsr-f64[0]; +env-vsr[n] = vsr-u64[1]; +} else { +env-avr[n-32].u64[0] = vsr-u64[0]; +env-avr[n-32].u64[1] = vsr-u64[1]; +} +} + +#define float64_to_float64(x, env) x diff --git a/target-ppc/translate.c b/target-ppc/translate.c index c5c1108..2060b1c 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7289,6 +7289,20 @@ VSX_VECTOR_MOVE(xvnabssp, OP_NABS, SGN_MASK_SP) VSX_VECTOR_MOVE(xvnegsp, OP_NEG, SGN_MASK_SP) VSX_VECTOR_MOVE(xvcpsgnsp, OP_CPSGN, SGN_MASK_SP) +#define GEN_VSX_HELPER_2(name, op1, op2, inval, type) \ +static void gen_##name(DisasContext * ctx)\ +{ \ +TCGv_i32 opc; \ +if (unlikely(!ctx-vsx_enabled)) {\ +gen_exception(ctx, POWERPC_EXCP_VSXU);\ +return; \ +} \ +/* NIP cannot be restored if the memory exception comes from an helper */ \ +gen_update_nip(ctx, ctx-nip - 4);\ +opc = tcg_const_i32(ctx-opcode); \ +gen_helper_##name(cpu_env, opc); \ +tcg_temp_free_i32(opc); \ +} #define VSX_LOGICAL(name, tcg_op)\ static void glue(gen_, name)(DisasContext * ctx) \ -- 1.7.1
[Qemu-devel] [V5 PATCH 16/22] target-ppc: Add VSX ISA2.06 Multiply Add Instructions
This patch adds the VSX floating point multiply/add instructions defined by V2.06 of the PowerPC ISA: - xsmaddadp, xvmaddadp, xvmaddasp - xsmaddmdp, xvmaddmdp, xvmaddmsp - xsmsubadp, xvmsubadp, xvmsubasp - xsmsubmdp, xvmsubmdp, xvmsubmsp - xsnmaddadp, xvnmaddadp, xvnmaddasp - xsnmaddmdp, xvnmaddmdp, xvnmaddmsp - xsnmsubadp, xvnmsubadp, xvnmsubasp - xsnmsubmdp, xvnmsubmdp, xvnmsubmsp Signed-off-by: Tom Musta tommu...@gmail.com Reviewed-by: Richard Henderson address@hidden --- V2: reworked implementation per comments from Richard Henderson and Peter Maydell. target-ppc/fpu_helper.c | 100 +++ target-ppc/helper.h | 24 +++ target-ppc/translate.c | 48 ++ 3 files changed, 172 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index 73227b7..54c47c8 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -2149,3 +2149,103 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ VSX_TSQRT(xstsqrtdp, 1, float64, f64, -1022, 52) VSX_TSQRT(xvtsqrtdp, 2, float64, f64, -1022, 52) VSX_TSQRT(xvtsqrtsp, 4, float32, f32, -126, 23) + +/* VSX_MADD - VSX floating point muliply/add variations + * op- instruction mnemonic + * nels - number of elements (1, 2 or 4) + * tp- type (float32 or float64) + * fld - vsr_t field (f32 or f64) + * maddflgs - flags for the float*muladd routine that control the + * various forms (madd, msub, nmadd, nmsub) + * afrm - A form (1=A, 0=M) + * sfprf - set FPRF + */ +#define VSX_MADD(op, nels, tp, fld, maddflgs, afrm, sfprf)\ +void helper_##op(CPUPPCState *env, uint32_t opcode) \ +{ \ +ppc_vsr_t xt_in, xa, xb, xt_out; \ +ppc_vsr_t *b, *c; \ +int i;\ + \ +if (afrm) { /* AxB + T */ \ +b = xb; \ +c = xt_in; \ +} else { /* AxT + B */\ +b = xt_in; \ +c = xb; \ +} \ + \ +getVSR(xA(opcode), xa, env); \ +getVSR(xB(opcode), xb, env); \ +getVSR(xT(opcode), xt_in, env); \ + \ +xt_out = xt_in; \ + \ +helper_reset_fpstatus(env); \ + \ +for (i = 0; i nels; i++) { \ +float_status tstat = env-fp_status; \ +set_float_exception_flags(0, tstat); \ +xt_out.fld[i] = tp##_muladd(xa.fld[i], b-fld[i], c-fld[i], \ + maddflgs, tstat); \ +env-fp_status.float_exception_flags |= tstat.float_exception_flags; \ + \ +if (unlikely(tstat.float_exception_flags float_flag_invalid)) { \ +if (tp##_is_signaling_nan(xa.fld[i]) || \ +tp##_is_signaling_nan(b-fld[i]) || \ +tp##_is_signaling_nan(c-fld[i])) { \ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);\ +tstat.float_exception_flags = ~float_flag_invalid; \ +} \ +if ((tp##_is_infinity(xa.fld[i]) tp##_is_zero(b-fld[i])) || \ +(tp##_is_zero(xa.fld[i]) tp##_is_infinity(b-fld[i]))) { \ +xt_out.fld[i] = float64_to_##tp(fload_invalid_op_excp(env,\ +POWERPC_EXCP_FP_VXIMZ, sfprf), env-fp_status); \ +tstat.float_exception_flags = ~float_flag_invalid;
Re: [Qemu-devel] [PATCH 1/2] hw/net: add support for Allwinner EMAC Fast Ethernet controller
On Fri, Jan 3, 2014 at 12:58 AM, Beniamino Galvani b.galv...@gmail.com wrote: On Thu, Jan 02, 2014 at 08:25:10PM +1000, Peter Crosthwaite wrote: +#undef AW_EMAC_DEBUG + +#ifdef AW_EMAC_DEBUG +#define debug(...) \ +do {\ +fprintf(stderr, allwinner_emac : %s: , __func__);\ +fprintf(stderr, ## __VA_ARGS__);\ +} while (0) +#else +#define debug(...) do {} while (0) +#endif For debug macros, its better to use a regular if (DEBUG_SYMBOL) so the body of the macro always gets compile tested. We have had incidences where major change patterns break stripped debug instrumentation because the code is compiled out. Ok. + +static void mii_set_link(AwEmacMii *mii, bool link_ok) +{ +if (link_ok) { +mii-bmsr |= MII_BMSR_LINK_ST; +mii-anlpar |= MII_ANAR_TXFD | MII_ANAR_TX | MII_ANAR_10FD | + MII_ANAR_10 | MII_ANAR_CSMACD; +} else { +mii-bmsr = ~MII_BMSR_LINK_ST; +mii-anlpar = MII_ANAR_TX; +} +mii-link_ok = link_ok; +} + +static void mii_reset(AwEmacMii *mii) +{ +mii-bmcr = MII_BMCR_FD | MII_BMCR_AUTOEN | MII_BMCR_SPEED; +mii-bmsr = MII_BMSR_100TX_FD | MII_BMSR_100TX_HD | MII_BMSR_10T_FD | +MII_BMSR_10T_HD | MII_BMSR_MFPS | MII_BMSR_AUTONEG; +mii-anar = MII_ANAR_TXFD | MII_ANAR_TX | MII_ANAR_10FD | MII_ANAR_10 | +MII_ANAR_CSMACD; +mii-anlpar = MII_ANAR_TX; +mii_set_link(mii, mii-link_ok); +} + +static uint16_t mii_read(AwEmacMii *mii, uint8_t phy_addr, uint8_t reg) +{ +uint16_t ret = 0x; + +if (phy_addr == BOARD_PHY_ADDRESS) { +switch (reg) { +case MII_BMCR: +ret = mii-bmcr; +break; +case MII_BMSR: +ret = mii-bmsr; +break; +case MII_PHYID1: +ret = RTL8201CP_PHYID1; +break; +case MII_PHYID2: +ret = RTL8201CP_PHYID2; +break; +case MII_ANAR: +ret = mii-anar; +break; +case MII_ANLPAR: +ret = mii-anlpar; +break; +default: +debug(unknown mii register %x\n, reg); +ret = 0; +} +} +return ret; +} + +static void mii_write(AwEmacMii *mii, uint8_t phy_addr, uint8_t reg, + uint16_t value) +{ +if (phy_addr == BOARD_PHY_ADDRESS) { +switch (reg) { +case MII_BMCR: +if (value MII_BMCR_RESET) { +mii_reset(mii); +} else { +mii-bmcr = value; +} +break; +case MII_BMSR: +case MII_PHYID1: +case MII_PHYID2: +case MII_ANLPAR: +qemu_log_mask(LOG_GUEST_ERROR, %s: write to mii register %x\n, + __func__, reg); +break; +case MII_ANAR: +mii-anar = value; +break; +default: +debug(unknown mii register %x\n, reg); +} +} +} + +static void aw_emac_update_irq(AwEmacState *s) +{ +qemu_set_irq(s-irq, (s-int_sta s-int_ctl) != 0); +} + +static int aw_emac_can_receive(NetClientState *nc) +{ +AwEmacState *s = qemu_get_nic_opaque(nc); + +return (s-ctl EMAC_CTL_RX_EN) (s-num_rx MAX_RX); If you return false from a can_recieve(), you need to explictly flush queued packets (qemu_flush_queued_packets()) when the blocking condition is lifted, heres a good example a bugfix patch addressing this issue for another mac: http://lists.gnu.org/archive/html/qemu-devel/2013-11/msg02255.html Ok. +} + +static ssize_t aw_emac_receive(NetClientState *nc, const uint8_t *buf, + size_t size) +{ +AwEmacState *s = qemu_get_nic_opaque(nc); +uint32_t *fifo; +uint32_t crc; +char *dest; + +if (s-num_rx = MAX_RX) { +debug(rx queue full - packed dropped\n); +return -1; +} + +if (size + RX_HDR_SIZE FIFO_SIZE) { +debug(packet too big\n); +return -1; +} + +fifo = s-rx_fifos[(s-first_rx + s-num_rx) % MAX_RX]; +dest = (char *)fifo[2]; +s-num_rx++; + +memcpy(dest, buf, size); + +/* Fill to minimum frame length */ +if (size 60) { +memset(dest + size, 0, 60 - size); +size = 60; +} + +/* Append FCS */ +crc = crc32(~0, buf, size); +memcpy(dest + size, crc, 4); + +fifo[0] = EMAC_UNDOCUMENTED_MAGIC; +fifo[1] = EMAC_RX_HEADER(size + 4, EMAC_RX_IO_DATA_STATUS_OK); + +/* Set rx interrupt flag */ +s-int_sta |= EMAC_INT_RX; +
Re: [Qemu-devel] [PATCH] migration: qmp_migrate(): keep working after syntax error
On 01/03/2014 12:17 AM, Luiz Capitulino wrote: If a user or QMP client enter a bad syntax for the migrate command in QMP/HMP, then the migrate command will never succeed from that point on. For example, if you enter: (qemu) migrate tcp;0: migrate: Parameter 'uri' expects a valid migration protocol Then the migrate command will always fail from now on: (qemu) migrate tcp:0: migrate: There's a migration process in progress The problem is that qmp_migrate() sets the migration status to MIG_STATE_SETUP and doesn't reset it on syntax error. This bug was introduced by commit 29ae8a4133082e16970c9d4be09f4b6a15034617. Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- migration.c | 1 + 1 file changed, 1 insertion(+) diff --git a/migration.c b/migration.c index 2b1ab20..557195a 100644 --- a/migration.c +++ b/migration.c @@ -437,6 +437,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, #endif } else { error_set(errp, QERR_INVALID_PARAMETER_VALUE, uri, a valid migration protocol); +s-state = MIG_STATE_ERROR; return; } Reviewed-by: Michael R. Hines mrhi...@us.ibm.com
[Qemu-devel] [RFC v1 0/2] Generalise FIFO to more integer types
There is a utility helper for dealing with 8 bit fifos. This should be applicable to other integer widths as well. These two patches generalise this FIFO to work for 16, 32 and 64 bit ints. Peter Crosthwaite (2): util/fifo: s/fifo8/fifo globally util/fifo: Generalise for common integer widths hw/char/serial.c | 30 +- hw/ssi/xilinx_spi.c | 42 ++--- hw/ssi/xilinx_spips.c| 66 ++-- include/hw/char/serial.h | 6 +- include/qemu/fifo.h | 104 include/qemu/fifo8.h | 99 -- util/Makefile.objs | 2 +- util/fifo.c | 152 +++ util/fifo8.c | 79 9 files changed, 329 insertions(+), 251 deletions(-) create mode 100644 include/qemu/fifo.h delete mode 100644 include/qemu/fifo8.h create mode 100644 util/fifo.c delete mode 100644 util/fifo8.c -- 1.8.5.2
[Qemu-devel] [RFC v1 1/2] util/fifo: s/fifo8/fifo globally
This prepares support for generalising FIFO support to more integer widths. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- hw/char/serial.c | 30 +- hw/ssi/xilinx_spi.c | 42 - hw/ssi/xilinx_spips.c| 66 include/hw/char/serial.h | 6 ++-- include/qemu/{fifo8.h = fifo.h} | 58 +-- util/Makefile.objs | 2 +- util/{fifo8.c = fifo.c} | 24 +++ 7 files changed, 114 insertions(+), 114 deletions(-) rename include/qemu/{fifo8.h = fifo.h} (50%) rename util/{fifo8.c = fifo.c} (73%) diff --git a/hw/char/serial.c b/hw/char/serial.c index 27dab7d..9b43e36 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -108,8 +108,8 @@ static void serial_receive1(void *opaque, const uint8_t *buf, int size); static inline void recv_fifo_put(SerialState *s, uint8_t chr) { /* Receive overruns do not overwrite FIFO contents. */ -if (!fifo8_is_full(s-recv_fifo)) { -fifo8_push(s-recv_fifo, chr); +if (!fifo_is_full(s-recv_fifo)) { +fifo_push(s-recv_fifo, chr); } else { s-lsr |= UART_LSR_OE; } @@ -225,8 +225,8 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque) if (s-tsr_retry = 0) { if (s-fcr UART_FCR_FE) { -s-tsr = fifo8_is_full(s-xmit_fifo) ? -0 : fifo8_pop(s-xmit_fifo); +s-tsr = fifo_is_full(s-xmit_fifo) ? +0 : fifo_pop(s-xmit_fifo); if (!s-xmit_fifo.num) { s-lsr |= UART_LSR_THRE; } @@ -282,10 +282,10 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val, s-thr = (uint8_t) val; if(s-fcr UART_FCR_FE) { /* xmit overruns overwrite data, so make space if needed */ -if (fifo8_is_full(s-xmit_fifo)) { -fifo8_pop(s-xmit_fifo); +if (fifo_is_full(s-xmit_fifo)) { +fifo_pop(s-xmit_fifo); } -fifo8_push(s-xmit_fifo, s-thr); +fifo_push(s-xmit_fifo, s-thr); s-lsr = ~UART_LSR_TEMT; } s-thr_ipending = 0; @@ -332,11 +332,11 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val, if (val UART_FCR_RFR) { timer_del(s-fifo_timeout_timer); s-timeout_ipending=0; -fifo8_reset(s-recv_fifo); +fifo_reset(s-recv_fifo); } if (val UART_FCR_XFR) { -fifo8_reset(s-xmit_fifo); +fifo_reset(s-xmit_fifo); } if (val UART_FCR_FE) { @@ -425,8 +425,8 @@ static uint64_t serial_ioport_read(void *opaque, hwaddr addr, unsigned size) ret = s-divider 0xff; } else { if(s-fcr UART_FCR_FE) { -ret = fifo8_is_empty(s-recv_fifo) ? -0 : fifo8_pop(s-recv_fifo); +ret = fifo_is_empty(s-recv_fifo) ? +0 : fifo_pop(s-recv_fifo); if (s-recv_fifo.num == 0) { s-lsr = ~(UART_LSR_DR | UART_LSR_BI); } else { @@ -633,8 +633,8 @@ static void serial_reset(void *opaque) s-char_transmit_time = (get_ticks_per_sec() / 9600) * 10; s-poll_msl = 0; -fifo8_reset(s-recv_fifo); -fifo8_reset(s-xmit_fifo); +fifo_reset(s-recv_fifo); +fifo_reset(s-xmit_fifo); s-last_xmit_ts = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); @@ -657,8 +657,8 @@ void serial_realize_core(SerialState *s, Error **errp) qemu_chr_add_handlers(s-chr, serial_can_receive1, serial_receive1, serial_event, s); -fifo8_create(s-recv_fifo, UART_FIFO_LENGTH); -fifo8_create(s-xmit_fifo, UART_FIFO_LENGTH); +fifo_create(s-recv_fifo, UART_FIFO_LENGTH); +fifo_create(s-xmit_fifo, UART_FIFO_LENGTH); } void serial_exit_core(SerialState *s) diff --git a/hw/ssi/xilinx_spi.c b/hw/ssi/xilinx_spi.c index d44caae..8fe3072 100644 --- a/hw/ssi/xilinx_spi.c +++ b/hw/ssi/xilinx_spi.c @@ -27,7 +27,7 @@ #include hw/sysbus.h #include sysemu/sysemu.h #include qemu/log.h -#include qemu/fifo8.h +#include qemu/fifo.h #include hw/ssi.h @@ -89,15 +89,15 @@ typedef struct XilinxSPI { SSIBus *spi; -Fifo8 rx_fifo; -Fifo8 tx_fifo; +Fifo rx_fifo; +Fifo tx_fifo; uint32_t regs[R_MAX]; } XilinxSPI; static void txfifo_reset(XilinxSPI *s) { -fifo8_reset(s-tx_fifo); +fifo_reset(s-tx_fifo); s-regs[R_SPISR] = ~SR_TX_FULL; s-regs[R_SPISR] |= SR_TX_EMPTY; @@ -105,7 +105,7 @@ static void txfifo_reset(XilinxSPI *s) static void rxfifo_reset(XilinxSPI *s) { -fifo8_reset(s-rx_fifo); +fifo_reset(s-rx_fifo); s-regs[R_SPISR] |= SR_RX_EMPTY;
[Qemu-devel] [RFC v1 2/2] util/fifo: Generalise for common integer widths
Add support for 16, 32 and 64 bit width FIFOs. The push and pop functions are patched to accept uint64_t always to support up to 64bit integer elements. The element width is set at creation time. The backing storage for all element types is still uint8_t regardless of element width so some save-load logic is needed to handle endianess issue WRT VMSD. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- hw/char/serial.c | 4 +-- hw/ssi/xilinx_spi.c | 4 +-- hw/ssi/xilinx_spips.c | 4 +-- include/qemu/fifo.h | 15 ++--- util/fifo.c | 91 ++- 5 files changed, 98 insertions(+), 20 deletions(-) diff --git a/hw/char/serial.c b/hw/char/serial.c index 9b43e36..cc71249 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -657,8 +657,8 @@ void serial_realize_core(SerialState *s, Error **errp) qemu_chr_add_handlers(s-chr, serial_can_receive1, serial_receive1, serial_event, s); -fifo_create(s-recv_fifo, UART_FIFO_LENGTH); -fifo_create(s-xmit_fifo, UART_FIFO_LENGTH); +fifo_create(s-recv_fifo, UART_FIFO_LENGTH, 8); +fifo_create(s-xmit_fifo, UART_FIFO_LENGTH, 8); } void serial_exit_core(SerialState *s) diff --git a/hw/ssi/xilinx_spi.c b/hw/ssi/xilinx_spi.c index 8fe3072..cac666b 100644 --- a/hw/ssi/xilinx_spi.c +++ b/hw/ssi/xilinx_spi.c @@ -341,8 +341,8 @@ static int xilinx_spi_init(SysBusDevice *sbd) s-irqline = -1; -fifo_create(s-tx_fifo, FIFO_CAPACITY); -fifo_create(s-rx_fifo, FIFO_CAPACITY); +fifo_create(s-tx_fifo, FIFO_CAPACITY, 8); +fifo_create(s-rx_fifo, FIFO_CAPACITY, 8); return 0; } diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c index c3d9c05..aeff06c 100644 --- a/hw/ssi/xilinx_spips.c +++ b/hw/ssi/xilinx_spips.c @@ -669,8 +669,8 @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp) s-irqline = -1; -fifo_create(s-rx_fifo, xsc-rx_fifo_size); -fifo_create(s-tx_fifo, xsc-tx_fifo_size); +fifo_create(s-rx_fifo, xsc-rx_fifo_size, 8); +fifo_create(s-tx_fifo, xsc-tx_fifo_size, 8); } static void xilinx_qspips_realize(DeviceState *dev, Error **errp) diff --git a/include/qemu/fifo.h b/include/qemu/fifo.h index e488387..a1737c3 100644 --- a/include/qemu/fifo.h +++ b/include/qemu/fifo.h @@ -5,8 +5,12 @@ typedef struct { /* All fields are private */ +int width; /* byte width each each element */ +uint32_t capacity; /* number of elements */ + uint8_t *data; -uint32_t capacity; +uint32_t buffer_size; + uint32_t head; uint32_t num; } Fifo; @@ -14,13 +18,14 @@ typedef struct { /** * fifo_create: * @fifo: struct Fifo to initialise with new FIFO - * @capacity: capacity of the newly created FIFO + * @capacity: capacity (number of elements) of the newly created FIFO + * @width: integer width of each element. Must be 8, 16, 32 or 64. * * Create a FIFO of the specified size. Clients should call fifo_destroy() * when finished using the fifo. The FIFO is initially empty. */ -void fifo_create(Fifo *fifo, uint32_t capacity); +void fifo_create(Fifo *fifo, uint32_t capacity, int width); /** * fifo_destroy: @@ -41,7 +46,7 @@ void fifo_destroy(Fifo *fifo); * Clients are responsible for checking for fullness using fifo_is_full(). */ -void fifo_push(Fifo *fifo, uint8_t data); +void fifo_push(Fifo *fifo, uint64_t data); /** * fifo_pop: @@ -53,7 +58,7 @@ void fifo_push(Fifo *fifo, uint8_t data); * Returns: The popped data value. */ -uint8_t fifo_pop(Fifo *fifo); +uint64_t fifo_pop(Fifo *fifo); /** * fifo_reset: diff --git a/util/fifo.c b/util/fifo.c index 1adaa11..33356ee 100644 --- a/util/fifo.c +++ b/util/fifo.c @@ -15,9 +15,11 @@ #include qemu-common.h #include qemu/fifo.h -void fifo_create(Fifo *fifo, uint32_t capacity) +void fifo_create(Fifo *fifo, uint32_t capacity, int width) { -fifo-data = g_new(uint8_t, capacity); +assert(width == 8 || width == 16 || width == 32 || width == 64); +fifo-width = width / 8; +fifo-data = g_new(uint8_t, capacity * fifo-width); fifo-capacity = capacity; fifo-head = 0; fifo-num = 0; @@ -28,26 +30,55 @@ void fifo_destroy(Fifo *fifo) g_free(fifo-data); } -void fifo_push(Fifo *fifo, uint8_t data) +void fifo_push(Fifo *fifo, uint64_t data) { +uint32_t next_idx = (fifo-head + fifo-num) % fifo-capacity; + if (fifo-num == fifo-capacity) { abort(); } -fifo-data[(fifo-head + fifo-num) % fifo-capacity] = data; +switch (fifo-width) { +case(1): +((uint8_t *)fifo-data)[next_idx] = data; +break; +case(2): +((uint16_t *)fifo-data)[next_idx] = data; +break; +case(4): +((uint32_t *)fifo-data)[next_idx] = data; +break; +case(8): +((uint64_t *)fifo-data)[next_idx] = data; +break; +default: +abort(); +} fifo-num++; } -uint8_t fifo_pop(Fifo
[Qemu-devel] [BUGFIX][PATCH v2] configure: Disable libtool if -fPIE does not work with it (bug #1257099)
Adjust TMPO and added TMPB, TMPL, and TMPA. libtool needs the names to be fixed (TMPB). Add new functions do_libtool and libtool_prog. Add check for broken gcc and libtool. Signed-off-by: Don Slutz dsl...@verizon.com --- Was posted as an attachment. https://lists.gnu.org/archive/html/qemu-devel/2013-12/msg02678.html configure | 63 ++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/configure b/configure index edfea95..852d021 100755 --- a/configure +++ b/configure @@ -12,7 +12,10 @@ else fi TMPC=${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.c -TMPO=${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.o +TMPB=qemu-conf-${RANDOM}-$$-${RANDOM} +TMPO=${TMPDIR1}/${TMPB}.o +TMPL=${TMPDIR1}/${TMPB}.lo +TMPA=${TMPDIR1}/lib${TMPB}.la TMPE=${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.exe # NB: do not call exit in the trap handler; this is buggy with some shells; @@ -86,6 +89,38 @@ compile_prog() { do_cc $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags } +do_libtool() { +local mode=$1 +shift +# Run the compiler, capturing its output to the log. +echo $libtool $mode --tag=CC $cc $@ config.log +$libtool $mode --tag=CC $cc $@ config.log 21 || return $? +# Test passed. If this is an --enable-werror build, rerun +# the test with -Werror and bail out if it fails. This +# makes warning-generating-errors in configure test code +# obvious to developers. +if test $werror != yes; then +return 0 +fi +# Don't bother rerunning the compile if we were already using -Werror +case $* in +*-Werror*) + return 0 +;; +esac +echo $libtool $mode --tag=CC $cc -Werror $@ config.log +$libtool $mode --tag=CC $cc -Werror $@ config.log 21 return $? +error_exit configure test passed without -Werror but failed with -Werror. \ +This is probably a bug in the configure script. The failing command \ +will be at the bottom of config.log. \ +You can run configure with --disable-werror to bypass this check. +} + +libtool_prog() { +do_libtool --mode=compile $QEMU_CFLAGS -c -fPIE -DPIE -o $TMPO $TMPC || return $? +do_libtool --mode=link $LDFLAGS -o $TMPA $TMPL -rpath /usr/local/lib +} + # symbolically link $1 to $2. Portable version of ln -sf. symlink() { rm -rf $2 @@ -1367,6 +1402,32 @@ EOF fi fi +# check for broken gcc and libtool in RHEL5 +if test -n $libtool -a $pie != no ; then + cat $TMPC EOF + +void *f(unsigned char *buf, int len); +void *g(unsigned char *buf, int len); + +void * +f(unsigned char *buf, int len) +{ +return (void*)0L; +} + +void * +g(unsigned char *buf, int len) +{ +return f(buf, len); +} + +EOF + if ! libtool_prog; then +echo Disabling libtool due to broken toolchain support +libtool= + fi +fi + ## # __sync_fetch_and_and requires at least -march=i486. Many toolchains # use i686 as default anyway, but for those that don't, an explicit -- 1.8.2.1
Re: [Qemu-devel] [PATCH v2 1/1] qtest: Fix the bug about disabling vnc causes make check hang
2014/1/2 Andreas Färber afaer...@suse.de Am 01.01.2014 05:40, schrieb Peter Crosthwaite: On Tue, Dec 31, 2013 at 11:29 PM, Kewei Yu kewe...@gmail.com wrote: 2013/12/31 Peter Crosthwaite peter.crosthwa...@xilinx.com On Tue, Dec 31, 2013 at 2:42 PM, Kewei Yu kewe...@gmail.com wrote: When we disabling vnc from ./configure, the qemu can't use the vnc option. [...] So qtest can't use the vnc -none , otherwise make check will hang. Curious, why exactly does make check hang? Shouldn't it just fail with an error result in this case? Yeah, there is an error result VNC support is disabled. I think its just terminology then. s/hangs/fails. Actually no. When qtest gets an unsupported command line argument, so that QEMU exits right away, then qtest hangs, waiting for the process. This was easily reproducible by mistyping machine names in my qom-test. That's a separate issue though. Yeah, It actually waits for the a handler and doesn't exit from make check. Maybe I didn't show a detailed description. So, Should I submit the patch v4? Regards, Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH v2 1/1] qtest: Fix the bug about disabling vnc causes make check hang
On Fri, Jan 3, 2014 at 1:01 PM, Kewei Yu kewe...@gmail.com wrote: 2014/1/2 Andreas Färber afaer...@suse.de Am 01.01.2014 05:40, schrieb Peter Crosthwaite: On Tue, Dec 31, 2013 at 11:29 PM, Kewei Yu kewe...@gmail.com wrote: 2013/12/31 Peter Crosthwaite peter.crosthwa...@xilinx.com On Tue, Dec 31, 2013 at 2:42 PM, Kewei Yu kewe...@gmail.com wrote: When we disabling vnc from ./configure, the qemu can't use the vnc option. [...] So qtest can't use the vnc -none , otherwise make check will hang. Curious, why exactly does make check hang? Shouldn't it just fail with an error result in this case? Yeah, there is an error result VNC support is disabled. I think its just terminology then. s/hangs/fails. Actually no. When qtest gets an unsupported command line argument, so that QEMU exits right away, then qtest hangs, waiting for the process. This was easily reproducible by mistyping machine names in my qom-test. That's a separate issue though. Yeah, It actually waits for the a handler and doesn't exit from make check. Maybe I didn't show a detailed description. So, Should I submit the patch v4? Probably not just for this. fails is fine. Regards, Peter Regards, Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
[Qemu-devel] [PATCH target-arm v1 1/1] arm/xilinx_zynq: Always instantiate the GEMs
Don't conditionalise GEM instantiation on networking attachments. The device should always be present even if not attached to a network. This allows for probing of the device by expectant guests (such as OS's). This is needed because sysbus (or AXI in Xilinx's real hw case) is not self identifying so the guest has no dynamic way of detecting device absence. Also allows for testing of the GEM in loopback mode with -net none. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- hw/arm/xilinx_zynq.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c index 17251c7..9f2e0f5 100644 --- a/hw/arm/xilinx_zynq.c +++ b/hw/arm/xilinx_zynq.c @@ -49,9 +49,11 @@ static void gem_init(NICInfo *nd, uint32_t base, qemu_irq irq) DeviceState *dev; SysBusDevice *s; -qemu_check_nic_model(nd, cadence_gem); dev = qdev_create(NULL, cadence_gem); -qdev_set_nic_properties(dev, nd); +if (nd) { +qemu_check_nic_model(nd, cadence_gem); +qdev_set_nic_properties(dev, nd); +} qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); sysbus_mmio_map(s, 0, base); @@ -113,7 +115,6 @@ static void zynq_init(QEMUMachineInitArgs *args) DeviceState *dev; SysBusDevice *busdev; qemu_irq pic[64]; -NICInfo *nd; Error *err = NULL; int n; @@ -190,8 +191,8 @@ static void zynq_init(QEMUMachineInitArgs *args) sysbus_create_varargs(cadence_ttc, 0xF8002000, pic[69-IRQ_OFFSET], pic[70-IRQ_OFFSET], pic[71-IRQ_OFFSET], NULL); -for (n = 0; n nb_nics; n++) { -nd = nd_table[n]; +for (n = 0; n 2; n++) { +NICInfo *nd = n nb_nics ? nd_table[n] : NULL; if (n == 0) { gem_init(nd, 0xE000B000, pic[54-IRQ_OFFSET]); } else if (n == 1) { -- 1.8.5.2
[Qemu-devel] [RFC PATCH V2 2/5] qapi: add event helper functions
This file hold some functions that do not need to be generated. Signed-off-by: Wenchao Xia xiaw...@linux.vnet.ibm.com --- include/qapi/qmp-event.h | 22 ++ qapi/Makefile.objs |1 + qapi/qmp-event.c | 56 ++ 3 files changed, 79 insertions(+), 0 deletions(-) create mode 100644 include/qapi/qmp-event.h create mode 100644 qapi/qmp-event.c diff --git a/include/qapi/qmp-event.h b/include/qapi/qmp-event.h new file mode 100644 index 000..2baf093 --- /dev/null +++ b/include/qapi/qmp-event.h @@ -0,0 +1,22 @@ +/* + * QMP Event related + * + * Copyright IBM, Corp. 2014 + * + * Authors: + * Wenchao Xia xiaw...@linux.vnet.ibm.com + * + * This work is licensed under the terms of the GNU GPLv2+ or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#ifndef QMP_EVENT_H +#define QMP_EVENT_H + +#include qapi/error.h +#include qapi/qmp/qdict.h + +QDict *qmp_event_build_dict(const char *event_name); + +#endif diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs index 1f9c973..d14b769 100644 --- a/qapi/Makefile.objs +++ b/qapi/Makefile.objs @@ -3,3 +3,4 @@ util-obj-y += qmp-output-visitor.o qmp-registry.o qmp-dispatch.o util-obj-y += string-input-visitor.o string-output-visitor.o util-obj-y += opts-visitor.o +util-obj-y += qmp-event.o diff --git a/qapi/qmp-event.c b/qapi/qmp-event.c new file mode 100644 index 000..dc81ec2 --- /dev/null +++ b/qapi/qmp-event.c @@ -0,0 +1,56 @@ +/* + * QMP Event related + * + * Copyright IBM, Corp. 2014 + * + * Authors: + * Wenchao Xia xiaw...@linux.vnet.ibm.com + * + * This work is licensed under the terms of the GNU GPLv2+ or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include inttypes.h + +#include qemu-common.h +#include qapi/qmp-event.h +#include qapi/qmp/qstring.h +#include qapi/qmp/qjson.h + +#ifdef _WIN32 +#include sysemu/os-win32.h +#endif + +#ifdef CONFIG_POSIX +#include sysemu/os-posix.h +#endif + +static void timestamp_put(QDict *qdict) +{ +int err; +QObject *obj; +qemu_timeval tv; + +err = qemu_gettimeofday(tv); +if (err 0) { +return; +} + +obj = qobject_from_jsonf({ 'seconds': % PRId64 , +'microseconds': % PRId64 }, +(int64_t) tv.tv_sec, (int64_t) tv.tv_usec); +qdict_put_obj(qdict, timestamp, obj); +} + +/* + * Build a QDict, then fill event name and time stamp, caller should free the + * QDict after usage. + */ +QDict *qmp_event_build_dict(const char *event_name) +{ +QDict *dict = qdict_new(); +qdict_put(dict, event, qstring_from_str(event_name)); +timestamp_put(dict); +return dict; +} -- 1.7.1
[Qemu-devel] [RFC PATCH V2 3/5] qapi script: add event support by qapi-event.py
qapi-event.py will parse the schema and generate qapi-event.c, then the API in qapi-event.c can be used to handle event in qemu code. All API have prefix qapi_event, all types have prefix QAPIEvent. Examples can be found in following patches. The script mainly include three parts: generate API for each event define, generate an enum type for all defined event, generate behavior control functions. Since in some case the real emit behavior may change, for example, qemu-img would not send a event, a callback layer is added to control the behavior. As a result, the stubs at compile time can be saved, the binding of block layer code and monitor code will become looser. Signed-off-by: Wenchao Xia xiaw...@linux.vnet.ibm.com --- Makefile |9 +- Makefile.objs |2 +- scripts/qapi-event.py | 432 + 3 files changed, 439 insertions(+), 4 deletions(-) create mode 100644 scripts/qapi-event.py diff --git a/Makefile b/Makefile index bdff4e4..fa59765 100644 --- a/Makefile +++ b/Makefile @@ -45,8 +45,8 @@ endif endif GENERATED_HEADERS = config-host.h qemu-options.def -GENERATED_HEADERS += qmp-commands.h qapi-types.h qapi-visit.h -GENERATED_SOURCES += qmp-marshal.c qapi-types.c qapi-visit.c +GENERATED_HEADERS += qmp-commands.h qapi-types.h qapi-visit.h qapi-event.h +GENERATED_SOURCES += qmp-marshal.c qapi-types.c qapi-visit.c qapi-event.c GENERATED_HEADERS += trace/generated-events.h GENERATED_SOURCES += trace/generated-events.c @@ -185,7 +185,7 @@ Makefile: $(version-obj-y) $(version-lobj-y) # Build libraries libqemustub.a: $(stub-obj-y) -libqemuutil.a: $(util-obj-y) qapi-types.o qapi-visit.o +libqemuutil.a: $(util-obj-y) qapi-types.o qapi-visit.o qapi-event.o ## @@ -226,6 +226,9 @@ $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py) qapi-visit.c qapi-visit.h :\ $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py) $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o . -b $, GEN $@) +qapi-event.c qapi-event.h :\ +$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-event.py $(qapi-py) + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-event.py $(gen-out-type) -o . -b $, GEN $@) qmp-commands.h qmp-marshal.c :\ $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py) $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -m -o . $, GEN $@) diff --git a/Makefile.objs b/Makefile.objs index 2b6c1fe..33f5950 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -12,7 +12,7 @@ block-obj-y += main-loop.o iohandler.o qemu-timer.o block-obj-$(CONFIG_POSIX) += aio-posix.o block-obj-$(CONFIG_WIN32) += aio-win32.o block-obj-y += block/ -block-obj-y += qapi-types.o qapi-visit.o +block-obj-y += qapi-types.o qapi-visit.o qapi-event.o block-obj-y += qemu-io-cmds.o block-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py new file mode 100644 index 000..7526366 --- /dev/null +++ b/scripts/qapi-event.py @@ -0,0 +1,432 @@ +# +# QAPI event generator +# +# Copyright IBM, Corp. 2014 +# +# Authors: +# Wenchao Xia xiaw...@linux.vnet.ibm.com +# +# This work is licensed under the terms of the GNU GPLv2+ or later. +# See the COPYING.LIB file in the top-level directory. + +from ordereddict import OrderedDict +from qapi import * +import sys +import os +import getopt +import errno + +def _generate_event_api_name(event_name, params): +api_name = void qapi_event_send_%s( % c_fun(event_name).lower(); +l = len(api_name) + +if params: +for argname, argentry, optional, structured in parse_args(params): +if structured: +sys.stderr.write(Nested structure define in event is not + supported now, event '%s', argname '%s'\n % + (event_name, argname)) +sys.exit(1) +continue + +if optional: +api_name += bool has_%s,\n % c_var(argname) +api_name += .ljust(l) + +if argentry == str: +api_name += const +api_name += %s %s,\n % (c_type(argentry), c_var(argname)) +api_name += .ljust(l) + +api_name += Error **errp) +return api_name; + + +# Following are the core functions that transate user input into a qdict going +# to be emitted in the wire. + +def generate_event_declaration(api_name): +return mcgen(''' + +%(api_name)s; +''', + api_name = api_name) + +def generate_event_implement(api_name, event_name, params): +# step 1: declare and variables +ret = mcgen( + +%(api_name)s +{ +QDict *qmp; +Error *local_err = NULL; +QAPIEventFuncEmit emit; +, +api_name =
[Qemu-devel] [RFC PATCH V2 4/5] test: add test cases for qapi event
These cases will verify whether the expected qdict is built. Signed-off-by: Wenchao Xia xiaw...@linux.vnet.ibm.com --- tests/Makefile | 14 ++- tests/qapi-schema/qapi-schema-test.json | 12 ++ tests/qapi-schema/qapi-schema-test.out | 10 +- tests/test-qmp-event.c | 254 +++ 4 files changed, 285 insertions(+), 5 deletions(-) create mode 100644 tests/test-qmp-event.c diff --git a/tests/Makefile b/tests/Makefile index 8d25878..e83ff71 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -23,6 +23,8 @@ check-unit-y += tests/test-string-input-visitor$(EXESUF) gcov-files-test-string-input-visitor-y = qapi/string-input-visitor.c check-unit-y += tests/test-string-output-visitor$(EXESUF) gcov-files-test-string-output-visitor-y = qapi/string-output-visitor.c +check-unit-y += tests/test-qmp-event$(EXESUF) +gcov-files-test-qmp-event-y += qapi/qmp-event.c check-unit-y += tests/test-opts-visitor$(EXESUF) gcov-files-test-opts-visitor-y = qapi/opts-visitor.c check-unit-y += tests/test-coroutine$(EXESUF) @@ -123,7 +125,8 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \ trailing-comma-list.json trailing-comma-object.json \ unclosed-list.json unclosed-object.json unclosed-string.json) -GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h tests/test-qmp-commands.h +GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h \ + tests/test-qapi-event.h tests/test-qmp-commands.h test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \ tests/check-qlist.o tests/check-qfloat.o tests/check-qjson.o \ @@ -132,9 +135,10 @@ test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \ tests/test-qmp-input-visitor.o tests/test-qmp-input-strict.o \ tests/test-qmp-commands.o tests/test-visitor-serialization.o \ tests/test-x86-cpuid.o tests/test-mul64.o tests/test-int128.o \ - tests/test-opts-visitor.o + tests/test-opts-visitor.o tests/test-qmp-event.o -test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o +test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o \ + tests/test-qapi-event.o $(test-obj-y): QEMU_INCLUDES += -Itests QEMU_CFLAGS += -I$(SRC_PATH)/tests @@ -170,12 +174,16 @@ $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-typ tests/test-qapi-visit.c tests/test-qapi-visit.h :\ $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o tests -p test- $, GEN $@) +tests/test-qapi-event.c tests/test-qapi-event.h :\ +$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-event.py + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-event.py $(gen-out-type) -o tests -p test- $, GEN $@) tests/test-qmp-commands.h tests/test-qmp-marshal.c :\ $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -o tests -p test- $, GEN $@) tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a +tests/test-qmp-event$(EXESUF): tests/test-qmp-event.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a tests/test-qmp-output-visitor$(EXESUF): tests/test-qmp-output-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a tests/test-qmp-input-visitor$(EXESUF): tests/test-qmp-input-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a tests/test-qmp-input-strict$(EXESUF): tests/test-qmp-input-strict.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 0bc58ac..547cc88 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -88,3 +88,15 @@ '*u16' : [ 'uint16' ], '*i64x': 'int' , '*u64x': 'uint64' } } + +# testing event +{ 'type': 'EventStructOne', + 'data': { 'struct1': 'UserDefOne', 'string': 'str', '*enum2': 'EnumOne' } } + +{ 'event': 'EVENT_A' } +{ 'event': 'EVENT_B', + 'data': { } } +{ 'event': 'EVENT_C', + 'data': { '*a': 'int', '*b': 'UserDefOne', 'c': 'str' } } +{ 'event': 'EVENT_D', + 'data': { 'a' : 'EventStructOne', 'b' : 'str', '*c': 'str', '*enum3': 'EnumOne' } } diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 80edf10..b2204af 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -15,7 +15,12 @@ OrderedDict([('command', 'user_def_cmd'), ('data', OrderedDict())]),
[Qemu-devel] [RFC PATCH V2 1/5] os-posix: include sys/time.h
Since gettimeofday() is used in this header file as a macro define, include the function's define header file, to avoid compile warning when other file include os-posix.h. Signed-off-by: Wenchao Xia xiaw...@linux.vnet.ibm.com Reviewed-by: Eric Blake ebl...@redhat.com --- include/sysemu/os-posix.h |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h index 25d0b2a..f131521 100644 --- a/include/sysemu/os-posix.h +++ b/include/sysemu/os-posix.h @@ -26,6 +26,8 @@ #ifndef QEMU_OS_POSIX_H #define QEMU_OS_POSIX_H +#include sys/time.h + void os_set_line_buffering(void); void os_set_proc_name(const char *s); void os_setup_signal_handling(void); -- 1.7.1
[Qemu-devel] [RFC PATCH V2 0/5] add direct support of event in qapi schema
This series add support for tag/keyword 'event' in qapi-schema. A new file was created to store some helper functions in patch 2, patch 4 is the test case, patch 5 is a convert example. The implemention is done by generate API and a batch of parameters for each event define, it doesn't generate a struture and visit function in the background for every event, so it doesn't support nested structure in the define to avoid trouble. A callback layer is added to control the behavior. More detail can be found in patch 3's message and incode comments. Since it is also touching qapi script, it is on top of series: http://lists.nongnu.org/archive/html/qemu-devel/2013-12/msg03840.html v2: Address Luiz's comments: patch 3: rename *err to *local_err, do not initialize *qmp = NULL, create a new function qmp_build_evet_dict(). Other change: reorgnized script in patch 3, it have a clear three steps, see patch 3's incode comments. Luiz, I have following change a bit different with your comments, please have a review: docs/writing-qmp-commands.txt is still missing, I will add that patch when this approach get positive feedback. Patch 3: API name is qapi_event_send_***(), instead of qapi_send_event_***(), to keep unified api prefix. when qapi_event_function.emit == NULL, still return instead of core dump or error. Before this series, the event function does invalid work silently, my patch change it to skip invalid work silently. If core dump code is there, then it still have a silently invalid work as before, since caller will set a emtpy emit function. Some code is still kepted in generated file, see incode comments for those code. Wenchao Xia (5): 1 os-posix: include sys/time.h 2 qapi: add event helper functions 3 qapi script: add event support by qapi-event.py 4 test: add test cases for qapi event 5 qapi event: convert RTC_CHANGE Makefile|9 +- Makefile.objs |2 +- include/qapi/qmp-event.h| 22 ++ include/sysemu/os-posix.h |2 + monitor.c | 14 + qapi-schema.json|3 + qapi/Makefile.objs |1 + qapi/qmp-event.c| 56 scripts/qapi-event.py | 432 +++ tests/Makefile | 14 +- tests/qapi-schema/qapi-schema-test.json | 12 + tests/qapi-schema/qapi-schema-test.out | 10 +- tests/test-qmp-event.c | 254 ++ vl.c|7 +- 14 files changed, 824 insertions(+), 14 deletions(-) create mode 100644 include/qapi/qmp-event.h create mode 100644 qapi/qmp-event.c create mode 100644 scripts/qapi-event.py create mode 100644 tests/test-qmp-event.c
[Qemu-devel] [RFC PATCH V2 5/5] qapi event: convert RTC_CHANGE
This is just an example of how to use qapi event API, and it bypassed the event throttle queue. A complete convert should be first define all events in qapi-schema.json, use qapi event types in monitor functions, then change calller one by one. Signed-off-by: Wenchao Xia xiaw...@linux.vnet.ibm.com --- monitor.c| 14 ++ qapi-schema.json |3 +++ vl.c |7 ++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/monitor.c b/monitor.c index 845f608..8dca027 100644 --- a/monitor.c +++ b/monitor.c @@ -74,6 +74,8 @@ #endif #include hw/lm32/lm32_pic.h +#include qapi-event.h + //#define DEBUG //#define DEBUG_COMPLETION @@ -628,6 +630,16 @@ monitor_protocol_event_throttle(MonitorEvent event, evstate-data = NULL; } +static void monitor_event_emit(QAPIEvent ev, QDict *d, Error **errp) +{ +Monitor *mon; + +QLIST_FOREACH(mon, mon_list, entry) { +if (monitor_ctrl_mode(mon) qmp_cmd_mode(mon)) { +monitor_json_emitter(mon, QOBJECT(d)); +} +} +} /* Global, one-time initializer to configure the rate limiting * and initialize state */ @@ -637,6 +649,8 @@ static void monitor_protocol_event_init(void) monitor_protocol_event_throttle(QEVENT_RTC_CHANGE, 1000); monitor_protocol_event_throttle(QEVENT_BALLOON_CHANGE, 1000); monitor_protocol_event_throttle(QEVENT_WATCHDOG, 1000); + +qapi_event_set_func_emit(monitor_event_emit); } /** diff --git a/qapi-schema.json b/qapi-schema.json index 9b51dcc..60ddf44 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -4247,3 +4247,6 @@ # Since: 1.7 ## { 'command': 'blockdev-add', 'data': { 'options': 'BlockdevOptions' } } + +{ 'event': 'RTC_CHANGE', + 'data': { 'offset' : 'int' } } diff --git a/vl.c b/vl.c index 7511e70..7726116 100644 --- a/vl.c +++ b/vl.c @@ -170,6 +170,7 @@ int main(int argc, char **argv) #include ui/qemu-spice.h #include qapi/string-input-visitor.h +#include qapi-event.h //#define DEBUG_NET //#define DEBUG_SLIRP @@ -743,11 +744,7 @@ int qemu_timedate_diff(struct tm *tm) void rtc_change_mon_event(struct tm *tm) { -QObject *data; - -data = qobject_from_jsonf({ 'offset': %d }, qemu_timedate_diff(tm)); -monitor_protocol_event(QEVENT_RTC_CHANGE, data); -qobject_decref(data); +qapi_event_send_rtc_change(qemu_timedate_diff(tm), NULL); } static void configure_rtc_date_offset(const char *startdate, int legacy) -- 1.7.1
Re: [Qemu-devel] [PATCH] spapr-pci: remove io ports workaround
On 03.01.2014 9:09, Alexander Graf wrote: On 02.01.2014, at 23:08, Alexey Kardashevskiy a...@ozlabs.ru wrote: On 01/03/2014 08:04 AM, Alexander Graf wrote: On 11.12.2013, at 07:47, Alexey Kardashevskiy a...@ozlabs.ru wrote: On 12/10/2013 06:47 PM, Greg Kurz wrote: On Tue, 10 Dec 2013 13:43:05 +1100 Alexey Kardashevskiy a...@ozlabs.ru wrote: On 12/10/2013 03:33 AM, Greg Kurz wrote: In the past, IO space could not be mapped into the memory address space so we introduced a workaround for that. Nowadays it does not look necessary so we can remove the workaround and make sPAPR PCI configuration simplier. This workaround has also an evil side effect with virtio devices: because all PHBs have their .io region at the same address, the devices get mapped in the .io-alias region of every PHB (AKA. mapped multiple times). This breaks the ioeventfd feature and causes qemu to abort() when running with KVM and asking for more than one PHB: $ qemu-system-ppc64 -machine type=pseries,accel=kvm -smp 1 -m 4G \ -hda /local/greg/images/fedora-be.qcow2 \ -device virtio-9p-pci,fsdev=fsdev0,mount_tag=share,bus=pci,ioeventfd=on \ -fsdev local,security_model=none,id=fsdev0,path=$HOME/share1 \ -device spapr-pci-host-bridge,index=15 kvm_mem_ioeventfd_add: error adding ioeventfd: File exists Aborted This will prevent to use virtio and VFIO passthrough at the same time, since VFIO needs a dedicated PHB to work on ppc. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru I have not seen this version yet so please remove me from SOB. The patch you replied to was eventually reworked and went to upstream as 66aab867cedd2a2d81b4d64eff7c3e0f6f272bbf Hi Alex, I agree you have not seen this version yet... The patch I replied to was my primary source of inspiration and contains these bits, hence the SOB. Anyway, the SOB is now removed until you decide to add one yourself. :) This one might be correct too but I want to try this first :) Well, I hope it is. Please try it. Yep. Tried. Looks good, did not break a thing as far as I can tell, even VGA works :) Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru Thanks, applied to ppc-next. Please read the rest of this thread. It does not visibly break things but with this patch QEMU starts calling unassigned_mem_accepts() (normally silent) which is not a good sign. Oops, I thought your comment meant this was fixed. I took it off the queue again :). Thanks :) And I have another bug like that - SPR registers are never saved/restored via KVM's set-one-reg mechanism (with the loop through all 1024 SPRs) because one_reg_id in SPR's descriptor is never initialized (the macro misses assignment) and I made a patch for that but cannot post it as some registers (AMR?) breaks HV KVM :) -- With best regards Alexey Kardashevskiy -- icq: 52150396