aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--Makefile.objs3
-rw-r--r--Makefile.target11
-rw-r--r--accel/accel.c5
-rw-r--r--block/iscsi.c7
-rw-r--r--chardev/char-socket.c12
-rw-r--r--chardev/char.c3
-rwxr-xr-xconfigure13
-rw-r--r--contrib/elf2dmp/main.c6
-rw-r--r--default-configs/ppc-softmmu.mak2
-rw-r--r--docs/interop/firmware.json20
-rw-r--r--exec.c48
-rw-r--r--hw/acpi/piix4.c1
-rw-r--r--hw/arm/collie.c9
-rw-r--r--hw/arm/digic_boards.c3
-rw-r--r--hw/arm/gumstix.c10
-rw-r--r--hw/arm/mainstone.c5
-rw-r--r--hw/arm/musicpal.c8
-rw-r--r--hw/arm/omap_sx1.c10
-rw-r--r--hw/arm/versatilepb.c3
-rw-r--r--hw/arm/vexpress.c10
-rw-r--r--hw/arm/virt.c7
-rw-r--r--hw/arm/xilinx_zynq.c7
-rw-r--r--hw/arm/z2.c6
-rw-r--r--hw/block/pflash_cfi01.c128
-rw-r--r--hw/block/pflash_cfi02.c81
-rw-r--r--hw/char/spapr_vty.c58
-rw-r--r--hw/core/qdev.c21
-rw-r--r--hw/core/sysbus.c3
-rw-r--r--hw/display/Kconfig6
-rw-r--r--hw/display/Makefile.objs2
-rw-r--r--hw/display/ati.c865
-rw-r--r--hw/display/ati_2d.c167
-rw-r--r--hw/display/ati_dbg.c259
-rw-r--r--hw/display/ati_int.h96
-rw-r--r--hw/display/ati_regs.h461
-rw-r--r--hw/display/trace-events4
-rw-r--r--hw/display/virtio-gpu.c2
-rw-r--r--hw/display/virtio-vga.c17
-rw-r--r--hw/i2c/Kconfig4
-rw-r--r--hw/i2c/Makefile.objs1
-rw-r--r--hw/i2c/mpc_i2c.c357
-rw-r--r--hw/i386/amd_iommu.c2
-rw-r--r--hw/i386/amd_iommu.h2
-rw-r--r--hw/i386/pc.c22
-rw-r--r--hw/i386/pc_sysfw.c245
-rw-r--r--hw/intc/Makefile.objs2
-rw-r--r--hw/intc/pnv_xive.c1753
-rw-r--r--hw/intc/pnv_xive_regs.h248
-rw-r--r--hw/intc/spapr_xive.c86
-rw-r--r--hw/intc/xics_kvm.c4
-rw-r--r--hw/intc/xics_spapr.c24
-rw-r--r--hw/intc/xive.c113
-rw-r--r--hw/lm32/lm32_boards.c8
-rw-r--r--hw/lm32/milkymist.c5
-rw-r--r--hw/microblaze/petalogix_ml605_mmu.c6
-rw-r--r--hw/microblaze/petalogix_s3adsp1800_mmu.c5
-rw-r--r--hw/mips/mips_fulong2e.c7
-rw-r--r--hw/mips/mips_malta.c21
-rw-r--r--hw/mips/mips_r4k.c5
-rw-r--r--hw/net/spapr_llan.c110
-rw-r--r--hw/nvram/fw_cfg.c9
-rw-r--r--hw/nvram/spapr_nvram.c42
-rw-r--r--hw/ppc/e500.c54
-rw-r--r--hw/ppc/mac_newworld.c4
-rw-r--r--hw/ppc/mac_oldworld.c4
-rw-r--r--hw/ppc/pnv.c252
-rw-r--r--hw/ppc/pnv_core.c189
-rw-r--r--hw/ppc/pnv_lpc.c316
-rw-r--r--hw/ppc/pnv_occ.c127
-rw-r--r--hw/ppc/pnv_psi.c425
-rw-r--r--hw/ppc/pnv_xscom.c33
-rw-r--r--hw/ppc/ppc.c106
-rw-r--r--hw/ppc/ppc405_boards.c102
-rw-r--r--hw/ppc/sam460ex.c42
-rw-r--r--hw/ppc/spapr.c361
-rw-r--r--hw/ppc/spapr_caps.c254
-rw-r--r--hw/ppc/spapr_cpu_core.c52
-rw-r--r--hw/ppc/spapr_drc.c134
-rw-r--r--hw/ppc/spapr_events.c92
-rw-r--r--hw/ppc/spapr_hcall.c120
-rw-r--r--hw/ppc/spapr_iommu.c107
-rw-r--r--hw/ppc/spapr_irq.c104
-rw-r--r--hw/ppc/spapr_ovec.c46
-rw-r--r--hw/ppc/spapr_pci.c212
-rw-r--r--hw/ppc/spapr_pci_vfio.c14
-rw-r--r--hw/ppc/spapr_rng.c18
-rw-r--r--hw/ppc/spapr_rtas.c30
-rw-r--r--hw/ppc/spapr_rtas_ddw.c42
-rw-r--r--hw/ppc/spapr_rtc.c16
-rw-r--r--hw/ppc/spapr_vio.c116
-rw-r--r--hw/ppc/virtex_ml507.c5
-rw-r--r--hw/riscv/Kconfig3
-rw-r--r--hw/scsi/lsi53c895a.c170
-rw-r--r--hw/scsi/scsi-disk.c37
-rw-r--r--hw/scsi/spapr_vscsi.c14
-rw-r--r--hw/scsi/trace-events6
-rw-r--r--hw/scsi/virtio-scsi.c8
-rw-r--r--hw/sh4/r2d.c17
-rw-r--r--hw/vfio/Kconfig3
-rw-r--r--hw/vfio/common.c2
-rw-r--r--hw/vfio/display.c169
-rw-r--r--hw/vfio/pci.c12
-rw-r--r--hw/vfio/pci.h2
-rw-r--r--hw/vfio/spapr.c49
-rw-r--r--hw/vfio/trace-events9
-rw-r--r--hw/virtio/virtio-pci.c1
-rw-r--r--hw/virtio/virtio-pci.h1
-rw-r--r--hw/xtensa/xtfpga.c12
-rw-r--r--include/hw/block/flash.h58
-rw-r--r--include/hw/i386/pc.h6
-rw-r--r--include/hw/pci-host/spapr.h44
-rw-r--r--include/hw/ppc/pnv.h42
-rw-r--r--include/hw/ppc/pnv_core.h14
-rw-r--r--include/hw/ppc/pnv_lpc.h26
-rw-r--r--include/hw/ppc/pnv_occ.h17
-rw-r--r--include/hw/ppc/pnv_psi.h59
-rw-r--r--include/hw/ppc/pnv_xive.h93
-rw-r--r--include/hw/ppc/pnv_xscom.h21
-rw-r--r--include/hw/ppc/ppc.h1
-rw-r--r--include/hw/ppc/spapr.h194
-rw-r--r--include/hw/ppc/spapr_cpu_core.h24
-rw-r--r--include/hw/ppc/spapr_drc.h108
-rw-r--r--include/hw/ppc/spapr_irq.h58
-rw-r--r--include/hw/ppc/spapr_ovec.h30
-rw-r--r--include/hw/ppc/spapr_vio.h74
-rw-r--r--include/hw/ppc/spapr_xive.h18
-rw-r--r--include/hw/ppc/xics_spapr.h6
-rw-r--r--include/hw/ppc/xive.h4
-rw-r--r--include/hw/qdev-core.h2
-rw-r--r--include/hw/vfio/vfio-common.h6
-rw-r--r--include/hw/virtio/virtio-gpu.h1
-rw-r--r--include/qom/object.h3
-rw-r--r--include/sysemu/sysemu.h1
-rw-r--r--memory.c5
-rw-r--r--monitor.c23
-rw-r--r--pc-bios/u-boot.e500bin388672 -> 349148 bytes
-rw-r--r--qapi/char.json6
-rw-r--r--qemu-deprecated.texi11
-rw-r--r--qemu-options.hx45
-rw-r--r--qom/cpu.c3
-rw-r--r--qom/object.c39
m---------roms/u-boot0
-rw-r--r--scripts/qemu-gdb.py7
-rw-r--r--scripts/qemugdb/coroutine.py7
-rw-r--r--scripts/qemugdb/mtree.py7
-rw-r--r--scripts/qemugdb/tcg.py7
-rw-r--r--target/i386/Makefile.objs2
-rw-r--r--target/i386/cpu.c9
-rw-r--r--target/i386/cpu.h3
-rw-r--r--target/ppc/cpu-qom.h1
-rw-r--r--target/ppc/cpu.h59
-rw-r--r--target/ppc/excp_helper.c30
-rw-r--r--target/ppc/internal.h27
-rw-r--r--target/ppc/kvm.c206
-rw-r--r--target/ppc/kvm_ppc.h23
-rw-r--r--target/ppc/machine.c8
-rw-r--r--target/ppc/mmu-hash64.c2
-rw-r--r--target/ppc/translate.c22
-rw-r--r--target/ppc/translate/vmx-impl.inc.c27
-rw-r--r--target/ppc/translate/vsx-impl.inc.c65
-rw-r--r--target/ppc/translate_init.inc.c7
-rw-r--r--target/s390x/Makefile.objs1
-rw-r--r--target/s390x/cpu.h7
-rw-r--r--target/s390x/helper.h21
-rw-r--r--target/s390x/insn-data.def82
-rw-r--r--target/s390x/insn-format.def25
-rw-r--r--target/s390x/internal.h43
-rw-r--r--target/s390x/mem_helper.c26
-rw-r--r--target/s390x/translate.c61
-rw-r--r--target/s390x/translate_vx.inc.c935
-rw-r--r--target/s390x/vec.h101
-rw-r--r--target/s390x/vec_helper.c193
-rw-r--r--tests/boot-serial-test.c4
-rw-r--r--tests/pnv-xscom-test.c2
-rw-r--r--tests/prom-env-test.c13
-rw-r--r--tests/pxe-test.c19
-rw-r--r--tests/tcg/mips/include/test_inputs_128.h (renamed from tests/tcg/mips/include/test_inputs.h)8
-rw-r--r--tests/tcg/mips/include/test_utils_128.h (renamed from tests/tcg/mips/include/test_utils.h)8
-rw-r--r--tests/tcg/mips/include/wrappers_msa.h4
-rw-r--r--tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_b.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_d.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_h.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_w.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_b.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_d.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_h.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_w.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_b.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_d.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_h.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_w.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_b.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_d.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_h.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_w.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_b.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_d.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_h.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_w.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_s_d.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_s_h.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_s_w.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_u_d.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_u_h.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_u_w.c6
-rw-r--r--tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_s_b.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_s_d.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_s_h.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_s_w.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_u_b.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_u_d.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_u_h.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_u_w.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_s_b.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_s_d.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_s_h.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_s_w.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_u_b.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_u_d.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_u_h.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_u_w.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_s_b.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_s_d.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_s_h.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_s_w.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_u_b.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_u_d.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_u_h.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_u_w.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_s_d.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_s_h.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_s_w.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_u_d.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_u_h.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_u_w.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mul_q_h.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mul_q_w.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulr_q_h.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulr_q_w.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulv_b.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulv_d.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulv_h.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulv_w.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_s_b.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_s_d.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_s_h.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_s_w.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_u_b.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_u_d.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_u_h.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_u_w.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsus_u_b.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsus_u_d.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsus_u_h.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsus_u_w.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsuu_s_b.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsuu_s_d.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsuu_s_h.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsuu_s_w.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subv_b.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subv_d.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subv_h.c151
-rw-r--r--tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subv_w.c153
-rw-r--r--tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/logic/test_msa_and_v.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/logic/test_msa_nor_v.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/logic/test_msa_or_v.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/logic/test_msa_xor_v.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_w.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_b.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_d.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_h.c8
-rw-r--r--tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_w.c8
-rw-r--r--tests/test-qgraph.c3
-rw-r--r--thunk.c2
-rw-r--r--trace/Makefile.objs4
-rw-r--r--ui/curses.c79
-rw-r--r--ui/curses_keys.h113
-rw-r--r--ui/vnc.c64
-rw-r--r--util/oslib-posix.c12
-rw-r--r--vl.c127
360 files changed, 19657 insertions, 2834 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index cf09a4c127..d326756079 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -984,6 +984,7 @@ L: qemu-ppc@nongnu.org
S: Odd Fixes
F: hw/ppc/e500*
F: hw/gpio/mpc8xxx.c
+F: hw/i2c/mpc_i2c.c
F: hw/net/fsl_etsec/
F: hw/pci-host/ppce500.c
F: include/hw/ppc/ppc_e500.h
diff --git a/Makefile.objs b/Makefile.objs
index ef65a6c12e..31a84b7d41 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -13,7 +13,7 @@ authz-obj-y = authz/
#######################################################################
# block-obj-y is code used by both qemu system emulation and qemu-img
-block-obj-y += nbd/
+block-obj-y = nbd/
block-obj-y += block.o blockjob.o job.o
block-obj-y += block/ scsi/
block-obj-y += qemu-io-cmds.o
@@ -101,7 +101,6 @@ version-obj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.o
######################################################################
# tracing
util-obj-y += trace/
-target-obj-y += trace/
######################################################################
# guest agent
diff --git a/Makefile.target b/Makefile.target
index 40830c5646..d8048aab8f 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -105,6 +105,8 @@ all: $(PROGS) stap
# Dummy command so that make thinks it has done something
@true
+obj-y += trace/
+
#########################################################
# cpu emulator library
obj-y += exec.o
@@ -173,13 +175,7 @@ endif # CONFIG_SOFTMMU
dummy := $(call unnest-vars,,obj-y)
all-obj-y := $(obj-y)
-target-obj-y :=
-block-obj-y :=
-common-obj-y :=
-chardev-obj-y :=
include $(SRC_PATH)/Makefile.objs
-dummy := $(call unnest-vars,,target-obj-y)
-target-obj-y-save := $(target-obj-y)
dummy := $(call unnest-vars,.., \
authz-obj-y \
block-obj-y \
@@ -191,9 +187,7 @@ dummy := $(call unnest-vars,.., \
io-obj-y \
common-obj-y \
common-obj-m)
-target-obj-y := $(target-obj-y-save)
all-obj-y += $(common-obj-y)
-all-obj-y += $(target-obj-y)
all-obj-y += $(qom-obj-y)
all-obj-$(CONFIG_SOFTMMU) += $(authz-obj-y)
all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y) $(chardev-obj-y)
@@ -228,6 +222,7 @@ clean: clean-target
rm -f *.a *~ $(PROGS)
rm -f $(shell find . -name '*.[od]')
rm -f hmp-commands.h gdbstub-xml.c
+ rm -f trace/generated-helpers.c trace/generated-helpers.c-timestamp
ifdef CONFIG_TRACE_SYSTEMTAP
rm -f *.stp
endif
diff --git a/accel/accel.c b/accel/accel.c
index 68b6d56323..8deb475b5d 100644
--- a/accel/accel.c
+++ b/accel/accel.c
@@ -66,6 +66,7 @@ static int accel_init_machine(AccelClass *acc, MachineState *ms)
*(acc->allowed) = false;
object_unref(OBJECT(accel));
}
+ object_set_accelerator_compat_props(acc->compat_props);
return ret;
}
@@ -91,7 +92,9 @@ void configure_accelerator(MachineState *ms, const char *progname)
#elif defined(CONFIG_KVM)
accel = "kvm";
#else
-#error "No default accelerator available"
+ error_report("No accelerator selected and"
+ " no default accelerator available");
+ exit(1);
#endif
}
}
diff --git a/block/iscsi.c b/block/iscsi.c
index a0c0084837..f31c612d53 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -145,6 +145,8 @@ static const unsigned iscsi_retry_times[] = {8, 32, 128, 512, 2048, 8192, 32768}
* unallocated. */
#define ISCSI_CHECKALLOC_THRES 64
+#ifdef __linux__
+
static void
iscsi_bh_cb(void *p)
{
@@ -172,6 +174,8 @@ iscsi_schedule_bh(IscsiAIOCB *acb)
qemu_bh_schedule(acb->bh);
}
+#endif
+
static void iscsi_co_generic_bh_cb(void *opaque)
{
struct IscsiTask *iTask = opaque;
@@ -290,6 +294,8 @@ static void iscsi_co_init_iscsitask(IscsiLun *iscsilun, struct IscsiTask *iTask)
};
}
+#ifdef __linux__
+
/* Called (via iscsi_service) with QemuMutex held. */
static void
iscsi_abort_task_cb(struct iscsi_context *iscsi, int status, void *command_data,
@@ -338,6 +344,7 @@ static const AIOCBInfo iscsi_aiocb_info = {
.cancel_async = iscsi_aio_cancel,
};
+#endif
static void iscsi_process_read(void *arg);
static void iscsi_process_write(void *arg);
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 6d287babfb..3916505d67 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -59,6 +59,7 @@ typedef struct {
QIONetListener *listener;
GSource *hup_source;
QCryptoTLSCreds *tls_creds;
+ char *tls_authz;
TCPChardevState state;
int max_size;
int do_telnetopt;
@@ -807,7 +808,7 @@ static void tcp_chr_tls_init(Chardev *chr)
if (s->is_listen) {
tioc = qio_channel_tls_new_server(
s->ioc, s->tls_creds,
- NULL, /* XXX Use an ACL */
+ s->tls_authz,
&err);
} else {
tioc = qio_channel_tls_new_client(
@@ -1055,6 +1056,7 @@ static void char_socket_finalize(Object *obj)
if (s->tls_creds) {
object_unref(OBJECT(s->tls_creds));
}
+ g_free(s->tls_authz);
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
@@ -1242,6 +1244,11 @@ static bool qmp_chardev_validate_socket(ChardevSocket *sock,
break;
}
+ if (sock->has_tls_authz && !sock->has_tls_creds) {
+ error_setg(errp, "'tls_authz' option requires 'tls_creds' option");
+ return false;
+ }
+
/* Validate any options which have a dependancy on client vs server */
if (!sock->has_server || sock->server) {
if (sock->has_reconnect) {
@@ -1320,6 +1327,7 @@ static void qmp_chardev_open_socket(Chardev *chr,
}
}
}
+ s->tls_authz = g_strdup(sock->tls_authz);
s->addr = addr = socket_address_flatten(sock->addr);
@@ -1399,6 +1407,8 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
sock->reconnect = qemu_opt_get_number(opts, "reconnect", 0);
sock->has_tls_creds = qemu_opt_get(opts, "tls-creds");
sock->tls_creds = g_strdup(qemu_opt_get(opts, "tls-creds"));
+ sock->has_tls_authz = qemu_opt_get(opts, "tls-authz");
+ sock->tls_authz = g_strdup(qemu_opt_get(opts, "tls-authz"));
addr = g_new0(SocketAddressLegacy, 1);
if (path) {
diff --git a/chardev/char.c b/chardev/char.c
index f6d61fa5f8..514cd6b0c3 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -881,6 +881,9 @@ QemuOptsList qemu_chardev_opts = {
.name = "tls-creds",
.type = QEMU_OPT_STRING,
},{
+ .name = "tls-authz",
+ .type = QEMU_OPT_STRING,
+ },{
.name = "websocket",
.type = QEMU_OPT_BOOL,
},{
diff --git a/configure b/configure
index b354e74185..cab830a4c9 100755
--- a/configure
+++ b/configure
@@ -1836,7 +1836,7 @@ fi
# Consult white-list to determine whether to enable werror
# by default. Only enable by default for git builds
if test -z "$werror" ; then
- if test -d "$source_path/.git" && \
+ if test -e "$source_path/.git" && \
{ test "$linux" = "yes" || test "$mingw32" = "yes"; }; then
werror="yes"
else
@@ -5903,6 +5903,17 @@ if test "$mingw32" = "yes" ; then
done
fi
+# Disable OpenBSD W^X if available
+if test "$tcg" = "yes" && test "$targetos" = "OpenBSD"; then
+ cat > $TMPC <<EOF
+ int main(void) { return 0; }
+EOF
+ wx_ldflags="-Wl,-z,wxneeded"
+ if compile_prog "" "$wx_ldflags"; then
+ QEMU_LDFLAGS="$QEMU_LDFLAGS $wx_ldflags"
+ fi
+fi
+
qemu_confdir=$sysconfdir$confsuffix
qemu_moddir=$libdir$confsuffix
qemu_datadir=$datadir$confsuffix
diff --git a/contrib/elf2dmp/main.c b/contrib/elf2dmp/main.c
index 1a45eaf565..1bfeb89ba7 100644
--- a/contrib/elf2dmp/main.c
+++ b/contrib/elf2dmp/main.c
@@ -524,6 +524,12 @@ int main(int argc, char *argv[])
}
}
+ if (!nt_start_addr) {
+ eprintf("Failed to find NT kernel image\n");
+ err = 1;
+ goto out_ps;
+ }
+
printf("KernBase = 0x%016"PRIx64", signature is \'%.2s\'\n", KernBase,
(char *)nt_start_addr);
diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index 6ea36d4090..bf86128a0c 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -1,6 +1,8 @@
# Default configuration for ppc-softmmu
# For embedded PPCs:
+CONFIG_MPC_I2C=y
+CONFIG_DS1338=y
CONFIG_E500=y
CONFIG_PPC405=y
CONFIG_PPC440=y
diff --git a/docs/interop/firmware.json b/docs/interop/firmware.json
index 28f9bc1591..ff8c2ce5f2 100644
--- a/docs/interop/firmware.json
+++ b/docs/interop/firmware.json
@@ -212,9 +212,13 @@
#
# @executable: Identifies the firmware executable. The firmware
# executable may be shared by multiple virtual machine
-# definitions. The corresponding QEMU command line option
-# is "-drive
-# if=pflash,unit=0,readonly=on,file=@executable.@filename,format=@executable.@format".
+# definitions. The preferred corresponding QEMU command
+# line options are
+# -drive if=none,id=pflash0,readonly=on,file=@executable.@filename,format=@executable.@format
+# -machine pflash0=pflash0
+# or equivalent -blockdev instead of -drive.
+# With QEMU versions older than 4.0, you have to use
+# -drive if=pflash,unit=0,readonly=on,file=@executable.@filename,format=@executable.@format
#
# @nvram-template: Identifies the NVRAM template compatible with
# @executable. Management software instantiates an
@@ -225,9 +229,13 @@
# individual copies of it are. An NVRAM file is
# typically used for persistently storing the
# non-volatile UEFI variables of a virtual machine
-# definition. The corresponding QEMU command line
-# option is "-drive
-# if=pflash,unit=1,readonly=off,file=FILENAME_OF_PRIVATE_NVRAM_FILE,format=@nvram-template.@format".
+# definition. The preferred corresponding QEMU
+# command line options are
+# -drive if=none,id=pflash1,readonly=off,file=FILENAME_OF_PRIVATE_NVRAM_FILE,format=@nvram-template.@format
+# -machine pflash1=pflash1
+# or equivalent -blockdev instead of -drive.
+# With QEMU versions older than 4.0, you have to use
+# -drive if=pflash,unit=1,readonly=off,file=FILENAME_OF_PRIVATE_NVRAM_FILE,format=@nvram-template.@format
#
# Since: 3.0
##
diff --git a/exec.c b/exec.c
index 1d4f3784d6..86a38d3b3b 100644
--- a/exec.c
+++ b/exec.c
@@ -1599,35 +1599,49 @@ static void register_multipage(FlatView *fv,
phys_page_set(d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index);
}
+/*
+ * The range in *section* may look like this:
+ *
+ * |s|PPPPPPP|s|
+ *
+ * where s stands for subpage and P for page.
+ */
void flatview_add_to_dispatch(FlatView *fv, MemoryRegionSection *section)
{
- MemoryRegionSection now = *section, remain = *section;
+ MemoryRegionSection remain = *section;
Int128 page_size = int128_make64(TARGET_PAGE_SIZE);
- if (now.offset_within_address_space & ~TARGET_PAGE_MASK) {
- uint64_t left = TARGET_PAGE_ALIGN(now.offset_within_address_space)
- - now.offset_within_address_space;
+ /* register first subpage */
+ if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) {
+ uint64_t left = TARGET_PAGE_ALIGN(remain.offset_within_address_space)
+ - remain.offset_within_address_space;
+ MemoryRegionSection now = remain;
now.size = int128_min(int128_make64(left), now.size);
register_subpage(fv, &now);
- } else {
- now.size = int128_zero();
- }
- while (int128_ne(remain.size, now.size)) {
+ if (int128_eq(remain.size, now.size)) {
+ return;
+ }
remain.size = int128_sub(remain.size, now.size);
remain.offset_within_address_space += int128_get64(now.size);
remain.offset_within_region += int128_get64(now.size);
- now = remain;
- if (int128_lt(remain.size, page_size)) {
- register_subpage(fv, &now);
- } else if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) {
- now.size = page_size;
- register_subpage(fv, &now);
- } else {
- now.size = int128_and(now.size, int128_neg(page_size));
- register_multipage(fv, &now);
+ }
+
+ /* register whole pages */
+ if (int128_ge(remain.size, page_size)) {
+ MemoryRegionSection now = remain;
+ now.size = int128_and(now.size, int128_neg(page_size));
+ register_multipage(fv, &now);
+ if (int128_eq(remain.size, now.size)) {
+ return;
}
+ remain.size = int128_sub(remain.size, now.size);
+ remain.offset_within_address_space += int128_get64(now.size);
+ remain.offset_within_region += int128_get64(now.size);
}
+
+ /* register last subpage */
+ register_subpage(fv, &remain);
}
void qemu_flush_coalesced_mmio_buffer(void)
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 8fd25a5926..7b98121070 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -28,7 +28,6 @@
#include "sysemu/sysemu.h"
#include "qapi/error.h"
#include "qemu/range.h"
-#include "hw/nvram/fw_cfg.h"
#include "exec/address-spaces.h"
#include "hw/acpi/piix4.h"
#include "hw/acpi/pcihp.h"
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
index 3ca4e078fe..d12604c573 100644
--- a/hw/arm/collie.c
+++ b/hw/arm/collie.c
@@ -9,6 +9,7 @@
* GNU GPL, version 2 or (at your option) any later version.
*/
#include "qemu/osdep.h"
+#include "qemu/units.h"
#include "hw/hw.h"
#include "hw/sysbus.h"
#include "hw/boards.h"
@@ -35,14 +36,14 @@ static void collie_init(MachineState *machine)
s = sa1110_init(sysmem, collie_binfo.ram_size, machine->cpu_type);
dinfo = drive_get(IF_PFLASH, 0, 0);
- pflash_cfi01_register(SA_CS0, NULL, "collie.fl1", 0x02000000,
+ pflash_cfi01_register(SA_CS0, "collie.fl1", 0x02000000,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+ 64 * KiB, 4, 0x00, 0x00, 0x00, 0x00, 0);
dinfo = drive_get(IF_PFLASH, 0, 1);
- pflash_cfi01_register(SA_CS1, NULL, "collie.fl2", 0x02000000,
+ pflash_cfi01_register(SA_CS1, "collie.fl2", 0x02000000,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+ 64 * KiB, 4, 0x00, 0x00, 0x00, 0x00, 0);
sysbus_create_simple("scoop", 0x40800000, NULL);
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
index 9f11dcd11f..304e4d1a29 100644
--- a/hw/arm/digic_boards.c
+++ b/hw/arm/digic_boards.c
@@ -129,9 +129,8 @@ static void digic4_add_k8p3215uqb_rom(DigicBoardState *s, hwaddr addr,
#define FLASH_K8P3215UQB_SIZE (4 * 1024 * 1024)
#define FLASH_K8P3215UQB_SECTOR_SIZE (64 * 1024)
- pflash_cfi02_register(addr, NULL, "pflash", FLASH_K8P3215UQB_SIZE,
+ pflash_cfi02_register(addr, "pflash", FLASH_K8P3215UQB_SIZE,
NULL, FLASH_K8P3215UQB_SECTOR_SIZE,
- FLASH_K8P3215UQB_SIZE / FLASH_K8P3215UQB_SECTOR_SIZE,
DIGIC4_ROM_MAX_SIZE / FLASH_K8P3215UQB_SIZE,
4,
0x00EC, 0x007E, 0x0003, 0x0001,
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
index 56cb763c4e..79886ce378 100644
--- a/hw/arm/gumstix.c
+++ b/hw/arm/gumstix.c
@@ -72,10 +72,9 @@ static void connex_init(MachineState *machine)
#else
be = 0;
#endif
- if (!pflash_cfi01_register(0x00000000, NULL, "connext.rom", connex_rom,
+ if (!pflash_cfi01_register(0x00000000, "connext.rom", connex_rom,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- sector_len, connex_rom / sector_len,
- 2, 0, 0, 0, 0, be)) {
+ sector_len, 2, 0, 0, 0, 0, be)) {
error_report("Error registering flash memory");
exit(1);
}
@@ -109,10 +108,9 @@ static void verdex_init(MachineState *machine)
#else
be = 0;
#endif
- if (!pflash_cfi01_register(0x00000000, NULL, "verdex.rom", verdex_rom,
+ if (!pflash_cfi01_register(0x00000000, "verdex.rom", verdex_rom,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- sector_len, verdex_rom / sector_len,
- 2, 0, 0, 0, 0, be)) {
+ sector_len, 2, 0, 0, 0, 0, be)) {
error_report("Error registering flash memory");
exit(1);
}
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index 0beb5c426b..e96738ad26 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -148,12 +148,11 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
exit(1);
}
- if (!pflash_cfi01_register(mainstone_flash_base[i], NULL,
+ if (!pflash_cfi01_register(mainstone_flash_base[i],
i ? "mainstone.flash1" : "mainstone.flash0",
MAINSTONE_FLASH,
blk_by_legacy_dinfo(dinfo),
- sector_len, MAINSTONE_FLASH / sector_len,
- 4, 0, 0, 0, 0, be)) {
+ sector_len, 4, 0, 0, 0, 0, be)) {
error_report("Error registering flash memory");
exit(1);
}
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index de4a12e496..93ec3c5698 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -1635,16 +1635,16 @@ static void musicpal_init(MachineState *machine)
* image is smaller than 32 MB.
*/
#ifdef TARGET_WORDS_BIGENDIAN
- pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
+ pflash_cfi02_register(0x100000000ULL - MP_FLASH_SIZE_MAX,
"musicpal.flash", flash_size,
- blk, 0x10000, (flash_size + 0xffff) >> 16,
+ blk, 0x10000,
MP_FLASH_SIZE_MAX / flash_size,
2, 0x00BF, 0x236D, 0x0000, 0x0000,
0x5555, 0x2AAA, 1);
#else
- pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
+ pflash_cfi02_register(0x100000000ULL - MP_FLASH_SIZE_MAX,
"musicpal.flash", flash_size,
- blk, 0x10000, (flash_size + 0xffff) >> 16,
+ blk, 0x10000,
MP_FLASH_SIZE_MAX / flash_size,
2, 0x00BF, 0x236D, 0x0000, 0x0000,
0x5555, 0x2AAA, 0);
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
index 84550f0236..95a4fe7e7f 100644
--- a/hw/arm/omap_sx1.c
+++ b/hw/arm/omap_sx1.c
@@ -152,11 +152,10 @@ static void sx1_init(MachineState *machine, const int version)
#endif
if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
- if (!pflash_cfi01_register(OMAP_CS0_BASE, NULL,
+ if (!pflash_cfi01_register(OMAP_CS0_BASE,
"omap_sx1.flash0-1", flash_size,
blk_by_legacy_dinfo(dinfo),
- sector_size, flash_size / sector_size,
- 4, 0, 0, 0, 0, be)) {
+ sector_size, 4, 0, 0, 0, 0, be)) {
fprintf(stderr, "qemu: Error registering flash memory %d.\n",
fl_idx);
}
@@ -176,11 +175,10 @@ static void sx1_init(MachineState *machine, const int version)
memory_region_add_subregion(address_space,
OMAP_CS1_BASE + flash1_size, &cs[1]);
- if (!pflash_cfi01_register(OMAP_CS1_BASE, NULL,
+ if (!pflash_cfi01_register(OMAP_CS1_BASE,
"omap_sx1.flash1-1", flash1_size,
blk_by_legacy_dinfo(dinfo),
- sector_size, flash1_size / sector_size,
- 4, 0, 0, 0, 0, be)) {
+ sector_size, 4, 0, 0, 0, 0, be)) {
fprintf(stderr, "qemu: Error registering flash memory %d.\n",
fl_idx);
}
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index 22b09a1e61..d67181810a 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -365,11 +365,10 @@ static void versatile_init(MachineState *machine, int board_id)
/* 0x34000000 NOR Flash */
dinfo = drive_get(IF_PFLASH, 0, 0);
- if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, NULL, "versatile.flash",
+ if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, "versatile.flash",
VERSATILE_FLASH_SIZE,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
VERSATILE_FLASH_SECT_SIZE,
- VERSATILE_FLASH_SIZE / VERSATILE_FLASH_SECT_SIZE,
4, 0x0089, 0x0018, 0x0000, 0x0, 0)) {
fprintf(stderr, "qemu: Error registering flash memory.\n");
}
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index c02d18ee61..f07134c424 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -512,10 +512,10 @@ static void vexpress_modify_dtb(const struct arm_boot_info *info, void *fdt)
/* Open code a private version of pflash registration since we
* need to set non-default device width for VExpress platform.
*/
-static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name,
- DriveInfo *di)
+static PFlashCFI01 *ve_pflash_cfi01_register(hwaddr base, const char *name,
+ DriveInfo *di)
{
- DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
+ DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
if (di) {
qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(di),
@@ -536,7 +536,7 @@ static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name,
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
- return OBJECT_CHECK(pflash_t, (dev), "cfi.pflash01");
+ return PFLASH_CFI01(dev);
}
static void vexpress_common_init(MachineState *machine)
@@ -548,7 +548,7 @@ static void vexpress_common_init(MachineState *machine)
qemu_irq pic[64];
uint32_t sys_id;
DriveInfo *dinfo;
- pflash_t *pflash0;
+ PFlashCFI01 *pflash0;
I2CBus *i2c;
ram_addr_t vram_size, sram_size;
MemoryRegion *sysmem = get_system_memory();
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 7f66ddad89..ce2664a30b 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -35,6 +35,7 @@
#include "hw/arm/arm.h"
#include "hw/arm/primecell.h"
#include "hw/arm/virt.h"
+#include "hw/block/flash.h"
#include "hw/vfio/vfio-calxeda-xgmac.h"
#include "hw/vfio/vfio-amd-xgbe.h"
#include "hw/display/ramfb.h"
@@ -878,7 +879,7 @@ static void create_one_flash(const char *name, hwaddr flashbase,
* parameters as the flash devices on the Versatile Express board.
*/
DriveInfo *dinfo = drive_get_next(IF_PFLASH);
- DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
+ DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
const uint64_t sectorlength = 256 * 1024;
@@ -1281,10 +1282,6 @@ static void virt_build_smbios(VirtMachineState *vms)
size_t smbios_tables_len, smbios_anchor_len;
const char *product = "QEMU Virtual Machine";
- if (!vms->fw_cfg) {
- return;
- }
-
if (kvm_enabled()) {
product = "KVM Virtual Machine";
}
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 57497b0c4d..b3b8215759 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -205,12 +205,11 @@ static void zynq_init(MachineState *machine)
DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0);
/* AMD */
- pflash_cfi02_register(0xe2000000, NULL, "zynq.pflash", FLASH_SIZE,
+ pflash_cfi02_register(0xe2000000, "zynq.pflash", FLASH_SIZE,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- FLASH_SECTOR_SIZE,
- FLASH_SIZE/FLASH_SECTOR_SIZE, 1,
+ FLASH_SECTOR_SIZE, 1,
1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x2aa,
- 0);
+ 0);
dev = qdev_create(NULL, "xilinx,zynq_slcr");
qdev_init_nofail(dev);
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index 3b75d4b39d..1f906ef20b 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -323,11 +323,9 @@ static void z2_init(MachineState *machine)
exit(1);
}
- if (!pflash_cfi01_register(Z2_FLASH_BASE,
- NULL, "z2.flash0", Z2_FLASH_SIZE,
+ if (!pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- sector_len, Z2_FLASH_SIZE / sector_len,
- 4, 0, 0, 0, 0, be)) {
+ sector_len, 4, 0, 0, 0, 0, be)) {
error_report("Error registering flash memory");
exit(1);
}
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index bffb4c40e7..125f70b8e4 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -49,12 +49,6 @@
#include "sysemu/sysemu.h"
#include "trace.h"
-#define PFLASH_BUG(fmt, ...) \
-do { \
- fprintf(stderr, "PFLASH: Possible BUG - " fmt, ## __VA_ARGS__); \
- exit(1); \
-} while(0)
-
/* #define PFLASH_DEBUG */
#ifdef PFLASH_DEBUG
#define DPRINTF(fmt, ...) \
@@ -65,12 +59,10 @@ do { \
#define DPRINTF(fmt, ...) do { } while (0)
#endif
-#define CFI_PFLASH01(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH01)
-
#define PFLASH_BE 0
#define PFLASH_SECURE 1
-struct pflash_t {
+struct PFlashCFI01 {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
@@ -109,17 +101,17 @@ static const VMStateDescription vmstate_pflash = {
.minimum_version_id = 1,
.post_load = pflash_post_load,
.fields = (VMStateField[]) {
- VMSTATE_UINT8(wcycle, pflash_t),
- VMSTATE_UINT8(cmd, pflash_t),
- VMSTATE_UINT8(status, pflash_t),
- VMSTATE_UINT64(counter, pflash_t),
+ VMSTATE_UINT8(wcycle, PFlashCFI01),
+ VMSTATE_UINT8(cmd, PFlashCFI01),
+ VMSTATE_UINT8(status, PFlashCFI01),
+ VMSTATE_UINT64(counter, PFlashCFI01),
VMSTATE_END_OF_LIST()
}
};
static void pflash_timer (void *opaque)
{
- pflash_t *pfl = opaque;
+ PFlashCFI01 *pfl = opaque;
trace_pflash_timer_expired(pfl->cmd);
/* Reset flash */
@@ -133,7 +125,7 @@ static void pflash_timer (void *opaque)
* If this code is called we know we have a device_width set for
* this flash.
*/
-static uint32_t pflash_cfi_query(pflash_t *pfl, hwaddr offset)
+static uint32_t pflash_cfi_query(PFlashCFI01 *pfl, hwaddr offset)
{
int i;
uint32_t resp = 0;
@@ -193,7 +185,7 @@ static uint32_t pflash_cfi_query(pflash_t *pfl, hwaddr offset)
/* Perform a device id query based on the bank width of the flash. */
-static uint32_t pflash_devid_query(pflash_t *pfl, hwaddr offset)
+static uint32_t pflash_devid_query(PFlashCFI01 *pfl, hwaddr offset)
{
int i;
uint32_t resp;
@@ -241,7 +233,7 @@ static uint32_t pflash_devid_query(pflash_t *pfl, hwaddr offset)
return resp;
}
-static uint32_t pflash_data_read(pflash_t *pfl, hwaddr offset,
+static uint32_t pflash_data_read(PFlashCFI01 *pfl, hwaddr offset,
int width, int be)
{
uint8_t *p;
@@ -284,8 +276,8 @@ static uint32_t pflash_data_read(pflash_t *pfl, hwaddr offset,
return ret;
}
-static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
- int width, int be)
+static uint32_t pflash_read(PFlashCFI01 *pfl, hwaddr offset,
+ int width, int be)
{
hwaddr boff;
uint32_t ret;
@@ -398,7 +390,7 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
}
/* update flash content on disk */
-static void pflash_update(pflash_t *pfl, int offset,
+static void pflash_update(PFlashCFI01 *pfl, int offset,
int size)
{
int offset_end;
@@ -412,7 +404,7 @@ static void pflash_update(pflash_t *pfl, int offset,
}
}
-static inline void pflash_data_write(pflash_t *pfl, hwaddr offset,
+static inline void pflash_data_write(PFlashCFI01 *pfl, hwaddr offset,
uint32_t value, int width, int be)
{
uint8_t *p = pfl->storage;
@@ -448,7 +440,7 @@ static inline void pflash_data_write(pflash_t *pfl, hwaddr offset,
}
-static void pflash_write(pflash_t *pfl, hwaddr offset,
+static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
uint32_t value, int width, int be)
{
uint8_t *p;
@@ -507,6 +499,10 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
break;
case 0xe8: /* Write to buffer */
DPRINTF("%s: Write to buffer\n", __func__);
+ /* FIXME should save @offset, @width for case 1+ */
+ qemu_log_mask(LOG_UNIMP,
+ "%s: Write to buffer emulation is flawed\n",
+ __func__);
pfl->status |= 0x80; /* Ready! */
break;
case 0xf0: /* Probe for AMD flash */
@@ -550,6 +546,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
/* Mask writeblock size based on device width, or bank width if
* device width not specified.
*/
+ /* FIXME check @offset, @width */
if (pfl->device_width) {
value = extract32(value, 0, pfl->device_width * 8);
} else {
@@ -587,7 +584,13 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
case 2:
switch (pfl->cmd) {
case 0xe8: /* Block write */
+ /* FIXME check @offset, @width */
if (!pfl->ro) {
+ /*
+ * FIXME writing straight to memory is *wrong*. We
+ * should write to a buffer, and flush it to memory
+ * only on confirm command (see below).
+ */
pflash_data_write(pfl, offset, value, width, be);
} else {
pfl->status |= 0x10; /* Programming error */
@@ -603,6 +606,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
pfl->wcycle++;
if (!pfl->ro) {
/* Flush the entire write buffer onto backing storage. */
+ /* FIXME premature! */
pflash_update(pfl, offset & mask, pfl->writeblock_size);
} else {
pfl->status |= 0x10; /* Programming error */
@@ -619,11 +623,15 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
switch (pfl->cmd) {
case 0xe8: /* Block write */
if (cmd == 0xd0) {
+ /* FIXME this is where we should write out the buffer */
pfl->wcycle = 0;
pfl->status |= 0x80;
} else {
- DPRINTF("%s: unknown command for \"write block\"\n", __func__);
- PFLASH_BUG("Write block confirm");
+ qemu_log_mask(LOG_UNIMP,
+ "%s: Aborting write to buffer not implemented,"
+ " the data is already written to storage!\n"
+ "Flash device reset into READ mode.\n",
+ __func__);
goto reset_flash;
}
break;
@@ -654,7 +662,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
static MemTxResult pflash_mem_read_with_attrs(void *opaque, hwaddr addr, uint64_t *value,
unsigned len, MemTxAttrs attrs)
{
- pflash_t *pfl = opaque;
+ PFlashCFI01 *pfl = opaque;
bool be = !!(pfl->features & (1 << PFLASH_BE));
if ((pfl->features & (1 << PFLASH_SECURE)) && !attrs.secure) {
@@ -668,7 +676,7 @@ static MemTxResult pflash_mem_read_with_attrs(void *opaque, hwaddr addr, uint64_
static MemTxResult pflash_mem_write_with_attrs(void *opaque, hwaddr addr, uint64_t value,
unsigned len, MemTxAttrs attrs)
{
- pflash_t *pfl = opaque;
+ PFlashCFI01 *pfl = opaque;
bool be = !!(pfl->features & (1 << PFLASH_BE));
if ((pfl->features & (1 << PFLASH_SECURE)) && !attrs.secure) {
@@ -687,7 +695,7 @@ static const MemoryRegionOps pflash_cfi01_ops = {
static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
{
- pflash_t *pfl = CFI_PFLASH01(dev);
+ PFlashCFI01 *pfl = PFLASH_CFI01(dev);
uint64_t total_len;
int ret;
uint64_t blocks_per_device, sector_len_per_device, device_len;
@@ -864,14 +872,14 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
}
static Property pflash_cfi01_properties[] = {
- DEFINE_PROP_DRIVE("drive", struct pflash_t, blk),
+ DEFINE_PROP_DRIVE("drive", PFlashCFI01, blk),
/* num-blocks is the number of blocks actually visible to the guest,
* ie the total size of the device divided by the sector length.
* If we're emulating flash devices wired in parallel the actual
* number of blocks per indvidual device will differ.
*/
- DEFINE_PROP_UINT32("num-blocks", struct pflash_t, nb_blocs, 0),
- DEFINE_PROP_UINT64("sector-length", struct pflash_t, sector_len, 0),
+ DEFINE_PROP_UINT32("num-blocks", PFlashCFI01, nb_blocs, 0),
+ DEFINE_PROP_UINT64("sector-length", PFlashCFI01, sector_len, 0),
/* width here is the overall width of this QEMU device in bytes.
* The QEMU device may be emulating a number of flash devices
* wired up in parallel; the width of each individual flash
@@ -888,17 +896,17 @@ static Property pflash_cfi01_properties[] = {
* 16 bit devices making up a 32 bit wide QEMU device. This
* is deprecated for new uses of this device.
*/
- DEFINE_PROP_UINT8("width", struct pflash_t, bank_width, 0),
- DEFINE_PROP_UINT8("device-width", struct pflash_t, device_width, 0),
- DEFINE_PROP_UINT8("max-device-width", struct pflash_t, max_device_width, 0),
- DEFINE_PROP_BIT("big-endian", struct pflash_t, features, PFLASH_BE, 0),
- DEFINE_PROP_BIT("secure", struct pflash_t, features, PFLASH_SECURE, 0),
- DEFINE_PROP_UINT16("id0", struct pflash_t, ident0, 0),
- DEFINE_PROP_UINT16("id1", struct pflash_t, ident1, 0),
- DEFINE_PROP_UINT16("id2", struct pflash_t, ident2, 0),
- DEFINE_PROP_UINT16("id3", struct pflash_t, ident3, 0),
- DEFINE_PROP_STRING("name", struct pflash_t, name),
- DEFINE_PROP_BOOL("old-multiple-chip-handling", struct pflash_t,
+ DEFINE_PROP_UINT8("width", PFlashCFI01, bank_width, 0),
+ DEFINE_PROP_UINT8("device-width", PFlashCFI01, device_width, 0),
+ DEFINE_PROP_UINT8("max-device-width", PFlashCFI01, max_device_width, 0),
+ DEFINE_PROP_BIT("big-endian", PFlashCFI01, features, PFLASH_BE, 0),
+ DEFINE_PROP_BIT("secure", PFlashCFI01, features, PFLASH_SECURE, 0),
+ DEFINE_PROP_UINT16("id0", PFlashCFI01, ident0, 0),
+ DEFINE_PROP_UINT16("id1", PFlashCFI01, ident1, 0),
+ DEFINE_PROP_UINT16("id2", PFlashCFI01, ident2, 0),
+ DEFINE_PROP_UINT16("id3", PFlashCFI01, ident3, 0),
+ DEFINE_PROP_STRING("name", PFlashCFI01, name),
+ DEFINE_PROP_BOOL("old-multiple-chip-handling", PFlashCFI01,
old_multiple_chip_handling, false),
DEFINE_PROP_END_OF_LIST(),
};
@@ -915,9 +923,9 @@ static void pflash_cfi01_class_init(ObjectClass *klass, void *data)
static const TypeInfo pflash_cfi01_info = {
- .name = TYPE_CFI_PFLASH01,
+ .name = TYPE_PFLASH_CFI01,
.parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(struct pflash_t),
+ .instance_size = sizeof(PFlashCFI01),
.class_init = pflash_cfi01_class_init,
};
@@ -928,20 +936,23 @@ static void pflash_cfi01_register_types(void)
type_init(pflash_cfi01_register_types)
-pflash_t *pflash_cfi01_register(hwaddr base,
- DeviceState *qdev, const char *name,
- hwaddr size,
- BlockBackend *blk,
- uint32_t sector_len, int nb_blocs,
- int bank_width, uint16_t id0, uint16_t id1,
- uint16_t id2, uint16_t id3, int be)
+PFlashCFI01 *pflash_cfi01_register(hwaddr base,
+ const char *name,
+ hwaddr size,
+ BlockBackend *blk,
+ uint32_t sector_len,
+ int bank_width,
+ uint16_t id0, uint16_t id1,
+ uint16_t id2, uint16_t id3,
+ int be)
{
- DeviceState *dev = qdev_create(NULL, TYPE_CFI_PFLASH01);
+ DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
if (blk) {
qdev_prop_set_drive(dev, "drive", blk, &error_abort);
}
- qdev_prop_set_uint32(dev, "num-blocks", nb_blocs);
+ assert(size % sector_len == 0);
+ qdev_prop_set_uint32(dev, "num-blocks", size / sector_len);
qdev_prop_set_uint64(dev, "sector-length", sector_len);
qdev_prop_set_uint8(dev, "width", bank_width);
qdev_prop_set_bit(dev, "big-endian", !!be);
@@ -953,17 +964,22 @@ pflash_t *pflash_cfi01_register(hwaddr base,
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
- return CFI_PFLASH01(dev);
+ return PFLASH_CFI01(dev);
+}
+
+BlockBackend *pflash_cfi01_get_blk(PFlashCFI01 *fl)
+{
+ return fl->blk;
}
-MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl)
+MemoryRegion *pflash_cfi01_get_memory(PFlashCFI01 *fl)
{
return &fl->mem;
}
static void postload_update_cb(void *opaque, int running, RunState state)
{
- pflash_t *pfl = opaque;
+ PFlashCFI01 *pfl = opaque;
/* This is called after bdrv_invalidate_cache_all. */
qemu_del_vm_change_state_handler(pfl->vmstate);
@@ -975,7 +991,7 @@ static void postload_update_cb(void *opaque, int running, RunState state)
static int pflash_post_load(void *opaque, int version_id)
{
- pflash_t *pfl = opaque;
+ PFlashCFI01 *pfl = opaque;
if (!pfl->ro) {
pfl->vmstate = qemu_add_vm_change_state_handler(postload_update_cb,
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 1588aeff5a..c9db430611 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -57,9 +57,7 @@ do { \
#define PFLASH_LAZY_ROMD_THRESHOLD 42
-#define CFI_PFLASH02(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH02)
-
-struct pflash_t {
+struct PFlashCFI02 {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
@@ -101,7 +99,7 @@ struct pflash_t {
/*
* Set up replicated mappings of the same region.
*/
-static void pflash_setup_mappings(pflash_t *pfl)
+static void pflash_setup_mappings(PFlashCFI02 *pfl)
{
unsigned i;
hwaddr size = memory_region_size(&pfl->orig_mem);
@@ -115,7 +113,7 @@ static void pflash_setup_mappings(pflash_t *pfl)
}
}
-static void pflash_register_memory(pflash_t *pfl, int rom_mode)
+static void pflash_register_memory(PFlashCFI02 *pfl, int rom_mode)
{
memory_region_rom_device_set_romd(&pfl->orig_mem, rom_mode);
pfl->rom_mode = rom_mode;
@@ -123,7 +121,7 @@ static void pflash_register_memory(pflash_t *pfl, int rom_mode)
static void pflash_timer (void *opaque)
{
- pflash_t *pfl = opaque;
+ PFlashCFI02 *pfl = opaque;
trace_pflash_timer_expired(pfl->cmd);
/* Reset flash */
@@ -137,8 +135,8 @@ static void pflash_timer (void *opaque)
pfl->cmd = 0;
}
-static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
- int width, int be)
+static uint32_t pflash_read(PFlashCFI02 *pfl, hwaddr offset,
+ int width, int be)
{
hwaddr boff;
uint32_t ret;
@@ -246,7 +244,7 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
}
/* update flash content on disk */
-static void pflash_update(pflash_t *pfl, int offset,
+static void pflash_update(PFlashCFI02 *pfl, int offset,
int size)
{
int offset_end;
@@ -260,8 +258,8 @@ static void pflash_update(pflash_t *pfl, int offset,
}
}
-static void pflash_write (pflash_t *pfl, hwaddr offset,
- uint32_t value, int width, int be)
+static void pflash_write(PFlashCFI02 *pfl, hwaddr offset,
+ uint32_t value, int width, int be)
{
hwaddr boff;
uint8_t *p;
@@ -533,7 +531,7 @@ static const MemoryRegionOps pflash_cfi02_ops_le = {
static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
{
- pflash_t *pfl = CFI_PFLASH02(dev);
+ PFlashCFI02 *pfl = PFLASH_CFI02(dev);
uint32_t chip_len;
int ret;
Error *local_err = NULL;
@@ -679,25 +677,25 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
}
static Property pflash_cfi02_properties[] = {
- DEFINE_PROP_DRIVE("drive", struct pflash_t, blk),
- DEFINE_PROP_UINT32("num-blocks", struct pflash_t, nb_blocs, 0),
- DEFINE_PROP_UINT32("sector-length", struct pflash_t, sector_len, 0),
- DEFINE_PROP_UINT8("width", struct pflash_t, width, 0),
- DEFINE_PROP_UINT8("mappings", struct pflash_t, mappings, 0),
- DEFINE_PROP_UINT8("big-endian", struct pflash_t, be, 0),
- DEFINE_PROP_UINT16("id0", struct pflash_t, ident0, 0),
- DEFINE_PROP_UINT16("id1", struct pflash_t, ident1, 0),
- DEFINE_PROP_UINT16("id2", struct pflash_t, ident2, 0),
- DEFINE_PROP_UINT16("id3", struct pflash_t, ident3, 0),
- DEFINE_PROP_UINT16("unlock-addr0", struct pflash_t, unlock_addr0, 0),
- DEFINE_PROP_UINT16("unlock-addr1", struct pflash_t, unlock_addr1, 0),
- DEFINE_PROP_STRING("name", struct pflash_t, name),
+ DEFINE_PROP_DRIVE("drive", PFlashCFI02, blk),
+ DEFINE_PROP_UINT32("num-blocks", PFlashCFI02, nb_blocs, 0),
+ DEFINE_PROP_UINT32("sector-length", PFlashCFI02, sector_len, 0),
+ DEFINE_PROP_UINT8("width", PFlashCFI02, width, 0),
+ DEFINE_PROP_UINT8("mappings", PFlashCFI02, mappings, 0),
+ DEFINE_PROP_UINT8("big-endian", PFlashCFI02, be, 0),
+ DEFINE_PROP_UINT16("id0", PFlashCFI02, ident0, 0),
+ DEFINE_PROP_UINT16("id1", PFlashCFI02, ident1, 0),
+ DEFINE_PROP_UINT16("id2", PFlashCFI02, ident2, 0),
+ DEFINE_PROP_UINT16("id3", PFlashCFI02, ident3, 0),
+ DEFINE_PROP_UINT16("unlock-addr0", PFlashCFI02, unlock_addr0, 0),
+ DEFINE_PROP_UINT16("unlock-addr1", PFlashCFI02, unlock_addr1, 0),
+ DEFINE_PROP_STRING("name", PFlashCFI02, name),
DEFINE_PROP_END_OF_LIST(),
};
static void pflash_cfi02_unrealize(DeviceState *dev, Error **errp)
{
- pflash_t *pfl = CFI_PFLASH02(dev);
+ PFlashCFI02 *pfl = PFLASH_CFI02(dev);
timer_del(&pfl->timer);
}
@@ -712,9 +710,9 @@ static void pflash_cfi02_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo pflash_cfi02_info = {
- .name = TYPE_CFI_PFLASH02,
+ .name = TYPE_PFLASH_CFI02,
.parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(struct pflash_t),
+ .instance_size = sizeof(PFlashCFI02),
.class_init = pflash_cfi02_class_init,
};
@@ -725,22 +723,25 @@ static void pflash_cfi02_register_types(void)
type_init(pflash_cfi02_register_types)
-pflash_t *pflash_cfi02_register(hwaddr base,
- DeviceState *qdev, const char *name,
- hwaddr size,
- BlockBackend *blk, uint32_t sector_len,
- int nb_blocs, int nb_mappings, int width,
- uint16_t id0, uint16_t id1,
- uint16_t id2, uint16_t id3,
- uint16_t unlock_addr0, uint16_t unlock_addr1,
- int be)
+PFlashCFI02 *pflash_cfi02_register(hwaddr base,
+ const char *name,
+ hwaddr size,
+ BlockBackend *blk,
+ uint32_t sector_len,
+ int nb_mappings, int width,
+ uint16_t id0, uint16_t id1,
+ uint16_t id2, uint16_t id3,
+ uint16_t unlock_addr0,
+ uint16_t unlock_addr1,
+ int be)
{
- DeviceState *dev = qdev_create(NULL, TYPE_CFI_PFLASH02);
+ DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI02);
if (blk) {
qdev_prop_set_drive(dev, "drive", blk, &error_abort);
}
- qdev_prop_set_uint32(dev, "num-blocks", nb_blocs);
+ assert(size % sector_len == 0);
+ qdev_prop_set_uint32(dev, "num-blocks", size / sector_len);
qdev_prop_set_uint32(dev, "sector-length", sector_len);
qdev_prop_set_uint8(dev, "width", width);
qdev_prop_set_uint8(dev, "mappings", nb_mappings);
@@ -755,5 +756,5 @@ pflash_t *pflash_cfi02_register(hwaddr base,
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
- return CFI_PFLASH02(dev);
+ return PFLASH_CFI02(dev);
}
diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index 6748334ded..617303dbaf 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -10,27 +10,27 @@
#define VTERM_BUFSIZE 16
-typedef struct VIOsPAPRVTYDevice {
- VIOsPAPRDevice sdev;
+typedef struct SpaprVioVty {
+ SpaprVioDevice sdev;
CharBackend chardev;
uint32_t in, out;
uint8_t buf[VTERM_BUFSIZE];
-} VIOsPAPRVTYDevice;
+} SpaprVioVty;
#define TYPE_VIO_SPAPR_VTY_DEVICE "spapr-vty"
#define VIO_SPAPR_VTY_DEVICE(obj) \
- OBJECT_CHECK(VIOsPAPRVTYDevice, (obj), TYPE_VIO_SPAPR_VTY_DEVICE)
+ OBJECT_CHECK(SpaprVioVty, (obj), TYPE_VIO_SPAPR_VTY_DEVICE)
static int vty_can_receive(void *opaque)
{
- VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(opaque);
+ SpaprVioVty *dev = VIO_SPAPR_VTY_DEVICE(opaque);
return VTERM_BUFSIZE - (dev->in - dev->out);
}
static void vty_receive(void *opaque, const uint8_t *buf, int size)
{
- VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(opaque);
+ SpaprVioVty *dev = VIO_SPAPR_VTY_DEVICE(opaque);
int i;
if ((dev->in == dev->out) && size) {
@@ -51,9 +51,9 @@ static void vty_receive(void *opaque, const uint8_t *buf, int size)
}
}
-static int vty_getchars(VIOsPAPRDevice *sdev, uint8_t *buf, int max)
+static int vty_getchars(SpaprVioDevice *sdev, uint8_t *buf, int max)
{
- VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(sdev);
+ SpaprVioVty *dev = VIO_SPAPR_VTY_DEVICE(sdev);
int n = 0;
while ((n < max) && (dev->out != dev->in)) {
@@ -83,18 +83,18 @@ static int vty_getchars(VIOsPAPRDevice *sdev, uint8_t *buf, int max)
return n;
}
-void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len)
+void vty_putchars(SpaprVioDevice *sdev, uint8_t *buf, int len)
{
- VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(sdev);
+ SpaprVioVty *dev = VIO_SPAPR_VTY_DEVICE(sdev);
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
qemu_chr_fe_write_all(&dev->chardev, buf, len);
}
-static void spapr_vty_realize(VIOsPAPRDevice *sdev, Error **errp)
+static void spapr_vty_realize(SpaprVioDevice *sdev, Error **errp)
{
- VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(sdev);
+ SpaprVioVty *dev = VIO_SPAPR_VTY_DEVICE(sdev);
if (!qemu_chr_fe_backend_connected(&dev->chardev)) {
error_setg(errp, "chardev property not set");
@@ -106,14 +106,14 @@ static void spapr_vty_realize(VIOsPAPRDevice *sdev, Error **errp)
}
/* Forward declaration */
-static target_ulong h_put_term_char(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_put_term_char(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong reg = args[0];
target_ulong len = args[1];
target_ulong char0_7 = args[2];
target_ulong char8_15 = args[3];
- VIOsPAPRDevice *sdev;
+ SpaprVioDevice *sdev;
uint8_t buf[16];
sdev = vty_lookup(spapr, reg);
@@ -133,14 +133,14 @@ static target_ulong h_put_term_char(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-static target_ulong h_get_term_char(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_get_term_char(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong reg = args[0];
target_ulong *len = args + 0;
target_ulong *char0_7 = args + 1;
target_ulong *char8_15 = args + 2;
- VIOsPAPRDevice *sdev;
+ SpaprVioDevice *sdev;
uint8_t buf[16];
sdev = vty_lookup(spapr, reg);
@@ -159,7 +159,7 @@ static target_ulong h_get_term_char(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-void spapr_vty_create(VIOsPAPRBus *bus, Chardev *chardev)
+void spapr_vty_create(SpaprVioBus *bus, Chardev *chardev)
{
DeviceState *dev;
@@ -169,8 +169,8 @@ void spapr_vty_create(VIOsPAPRBus *bus, Chardev *chardev)
}
static Property spapr_vty_properties[] = {
- DEFINE_SPAPR_PROPERTIES(VIOsPAPRVTYDevice, sdev),
- DEFINE_PROP_CHR("chardev", VIOsPAPRVTYDevice, chardev),
+ DEFINE_SPAPR_PROPERTIES(SpaprVioVty, sdev),
+ DEFINE_PROP_CHR("chardev", SpaprVioVty, chardev),
DEFINE_PROP_END_OF_LIST(),
};
@@ -179,11 +179,11 @@ static const VMStateDescription vmstate_spapr_vty = {
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
- VMSTATE_SPAPR_VIO(sdev, VIOsPAPRVTYDevice),
+ VMSTATE_SPAPR_VIO(sdev, SpaprVioVty),
- VMSTATE_UINT32(in, VIOsPAPRVTYDevice),
- VMSTATE_UINT32(out, VIOsPAPRVTYDevice),
- VMSTATE_BUFFER(buf, VIOsPAPRVTYDevice),
+ VMSTATE_UINT32(in, SpaprVioVty),
+ VMSTATE_UINT32(out, SpaprVioVty),
+ VMSTATE_BUFFER(buf, SpaprVioVty),
VMSTATE_END_OF_LIST()
},
};
@@ -191,7 +191,7 @@ static const VMStateDescription vmstate_spapr_vty = {
static void spapr_vty_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
+ SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
k->realize = spapr_vty_realize;
k->dt_name = "vty";
@@ -205,13 +205,13 @@ static void spapr_vty_class_init(ObjectClass *klass, void *data)
static const TypeInfo spapr_vty_info = {
.name = TYPE_VIO_SPAPR_VTY_DEVICE,
.parent = TYPE_VIO_SPAPR_DEVICE,
- .instance_size = sizeof(VIOsPAPRVTYDevice),
+ .instance_size = sizeof(SpaprVioVty),
.class_init = spapr_vty_class_init,
};
-VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
+SpaprVioDevice *spapr_vty_get_default(SpaprVioBus *bus)
{
- VIOsPAPRDevice *sdev, *selected;
+ SpaprVioDevice *sdev, *selected;
BusChild *kid;
/*
@@ -246,9 +246,9 @@ VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
return selected;
}
-VIOsPAPRDevice *vty_lookup(sPAPRMachineState *spapr, target_ulong reg)
+SpaprVioDevice *vty_lookup(SpaprMachineState *spapr, target_ulong reg)
{
- VIOsPAPRDevice *sdev;
+ SpaprVioDevice *sdev;
sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
if (!sdev && reg == 0) {
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 512ce7ca7a..f9b6efe509 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -978,25 +978,12 @@ static void device_initfn(Object *obj)
QLIST_INIT(&dev->gpios);
}
-void object_apply_compat_props(Object *obj)
-{
- if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
- MachineState *m = MACHINE(qdev_get_machine());
- MachineClass *mc = MACHINE_GET_CLASS(m);
-
- if (m->accelerator) {
- AccelClass *ac = ACCEL_GET_CLASS(m->accelerator);
-
- if (ac->compat_props) {
- object_apply_global_props(obj, ac->compat_props, &error_abort);
- }
- }
- object_apply_global_props(obj, mc->compat_props, &error_abort);
- }
-}
-
static void device_post_init(Object *obj)
{
+ /*
+ * Note: ordered so that the user's global properties take
+ * precedence.
+ */
object_apply_compat_props(obj);
qdev_prop_set_globals(DEVICE(obj));
}
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index 9f9edbcab9..307cf90a51 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -357,9 +357,6 @@ static void main_system_bus_create(void)
qbus_create_inplace(main_system_bus, system_bus_info.instance_size,
TYPE_SYSTEM_BUS, NULL, "main-system-bus");
OBJECT(main_system_bus)->free = g_free;
- object_property_add_child(container_get(qdev_get_machine(),
- "/unattached"),
- "sysbus", OBJECT(main_system_bus), NULL);
}
BusState *sysbus_get_default(void)
diff --git a/hw/display/Kconfig b/hw/display/Kconfig
index a96ea763a8..86c1d544c5 100644
--- a/hw/display/Kconfig
+++ b/hw/display/Kconfig
@@ -106,3 +106,9 @@ config VIRTIO_VGA
config DPCD
bool
+
+config ATI_VGA
+ bool
+ default y if PCI_DEVICES
+ depends on PCI
+ select VGA
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
index 576fca4eb6..dbd453ab1b 100644
--- a/hw/display/Makefile.objs
+++ b/hw/display/Makefile.objs
@@ -51,3 +51,5 @@ virtio-gpu-3d.o-cflags := $(VIRGL_CFLAGS)
virtio-gpu-3d.o-libs += $(VIRGL_LIBS)
obj-$(CONFIG_DPCD) += dpcd.o
obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx_dp.o
+
+obj-$(CONFIG_ATI_VGA) += ati.o ati_2d.o ati_dbg.o
diff --git a/hw/display/ati.c b/hw/display/ati.c
new file mode 100644
index 0000000000..8322f52aff
--- /dev/null
+++ b/hw/display/ati.c
@@ -0,0 +1,865 @@
+/*
+ * QEMU ATI SVGA emulation
+ *
+ * Copyright (c) 2019 BALATON Zoltan
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ */
+
+/*
+ * WARNING:
+ * This is very incomplete and only enough for Linux console and some
+ * unaccelerated X output at the moment.
+ * Currently it's little more than a frame buffer with minimal functions,
+ * other more advanced features of the hardware are yet to be implemented.
+ * We only aim for Rage 128 Pro (and some RV100) and 2D only at first,
+ * No 3D at all yet (maybe after 2D works, but feel free to improve it)
+ */
+
+#include "ati_int.h"
+#include "ati_regs.h"
+#include "vga_regs.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+#include "hw/hw.h"
+#include "ui/console.h"
+#include "trace.h"
+
+#define ATI_DEBUG_HW_CURSOR 0
+
+static const struct {
+ const char *name;
+ uint16_t dev_id;
+} ati_model_aliases[] = {
+ { "rage128p", PCI_DEVICE_ID_ATI_RAGE128_PF },
+ { "rv100", PCI_DEVICE_ID_ATI_RADEON_QY },
+};
+
+enum { VGA_MODE, EXT_MODE };
+
+static void ati_vga_switch_mode(ATIVGAState *s)
+{
+ DPRINTF("%d -> %d\n",
+ s->mode, !!(s->regs.crtc_gen_cntl & CRTC2_EXT_DISP_EN));
+ if (s->regs.crtc_gen_cntl & CRTC2_EXT_DISP_EN) {
+ /* Extended mode enabled */
+ s->mode = EXT_MODE;
+ if (s->regs.crtc_gen_cntl & CRTC2_EN) {
+ /* CRT controller enabled, use CRTC values */
+ uint32_t offs = s->regs.crtc_offset & 0x07ffffff;
+ int stride = (s->regs.crtc_pitch & 0x7ff) * 8;
+ int bpp = 0;
+ int h, v;
+
+ if (s->regs.crtc_h_total_disp == 0) {
+ s->regs.crtc_h_total_disp = ((640 / 8) - 1) << 16;
+ }
+ if (s->regs.crtc_v_total_disp == 0) {
+ s->regs.crtc_v_total_disp = (480 - 1) << 16;
+ }
+ h = ((s->regs.crtc_h_total_disp >> 16) + 1) * 8;
+ v = (s->regs.crtc_v_total_disp >> 16) + 1;
+ switch (s->regs.crtc_gen_cntl & CRTC_PIX_WIDTH_MASK) {
+ case CRTC_PIX_WIDTH_4BPP:
+ bpp = 4;
+ break;
+ case CRTC_PIX_WIDTH_8BPP:
+ bpp = 8;
+ break;
+ case CRTC_PIX_WIDTH_15BPP:
+ bpp = 15;
+ break;
+ case CRTC_PIX_WIDTH_16BPP:
+ bpp = 16;
+ break;
+ case CRTC_PIX_WIDTH_24BPP:
+ bpp = 24;
+ break;
+ case CRTC_PIX_WIDTH_32BPP:
+ bpp = 32;
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "Unsupported bpp value\n");
+ }
+ assert(bpp != 0);
+ DPRINTF("Switching to %dx%d %d %d @ %x\n", h, v, stride, bpp, offs);
+ vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE);
+ vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_DISABLED);
+ /* reset VBE regs then set up mode */
+ s->vga.vbe_regs[VBE_DISPI_INDEX_XRES] = h;
+ s->vga.vbe_regs[VBE_DISPI_INDEX_YRES] = v;
+ s->vga.vbe_regs[VBE_DISPI_INDEX_BPP] = bpp;
+ /* enable mode via ioport so it updates vga regs */
+ vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE);
+ vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_ENABLED |
+ VBE_DISPI_LFB_ENABLED | VBE_DISPI_NOCLEARMEM |
+ (s->regs.dac_cntl & DAC_8BIT_EN ? VBE_DISPI_8BIT_DAC : 0));
+ /* now set offset and stride after enable as that resets these */
+ if (stride) {
+ vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_VIRT_WIDTH);
+ vbe_ioport_write_data(&s->vga, 0, stride);
+ if (offs % stride == 0) {
+ vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_Y_OFFSET);
+ vbe_ioport_write_data(&s->vga, 0, offs / stride);
+ } else {
+ /* FIXME what to do with this? */
+ error_report("VGA offset is not multiple of pitch, "
+ "expect bad picture");
+ }
+ }
+ }
+ } else {
+ /* VGA mode enabled */
+ s->mode = VGA_MODE;
+ vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE);
+ vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_DISABLED);
+ }
+}
+
+/* Used by host side hardware cursor */
+static void ati_cursor_define(ATIVGAState *s)
+{
+ uint8_t data[1024];
+ uint8_t *src;
+ int i, j, idx = 0;
+
+ if ((s->regs.cur_offset & BIT(31)) || s->cursor_guest_mode) {
+ return; /* Do not update cursor if locked or rendered by guest */
+ }
+ /* FIXME handle cur_hv_offs correctly */
+ src = s->vga.vram_ptr + (s->regs.crtc_offset & 0x07ffffff) +
+ s->regs.cur_offset - (s->regs.cur_hv_offs >> 16) -
+ (s->regs.cur_hv_offs & 0xffff) * 16;
+ for (i = 0; i < 64; i++) {
+ for (j = 0; j < 8; j++, idx++) {
+ data[idx] = src[i * 16 + j];
+ data[512 + idx] = src[i * 16 + j + 8];
+ }
+ }
+ if (!s->cursor) {
+ s->cursor = cursor_alloc(64, 64);
+ }
+ cursor_set_mono(s->cursor, s->regs.cur_color1, s->regs.cur_color0,
+ &data[512], 1, &data[0]);
+ dpy_cursor_define(s->vga.con, s->cursor);
+}
+
+/* Alternatively support guest rendered hardware cursor */
+static void ati_cursor_invalidate(VGACommonState *vga)
+{
+ ATIVGAState *s = container_of(vga, ATIVGAState, vga);
+ int size = (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) ? 64 : 0;
+
+ if (s->regs.cur_offset & BIT(31)) {
+ return; /* Do not update cursor if locked */
+ }
+ if (s->cursor_size != size ||
+ vga->hw_cursor_x != s->regs.cur_hv_pos >> 16 ||
+ vga->hw_cursor_y != (s->regs.cur_hv_pos & 0xffff) ||
+ s->cursor_offset != s->regs.cur_offset - (s->regs.cur_hv_offs >> 16) -
+ (s->regs.cur_hv_offs & 0xffff) * 16) {
+ /* Remove old cursor then update and show new one if needed */
+ vga_invalidate_scanlines(vga, vga->hw_cursor_y, vga->hw_cursor_y + 63);
+ vga->hw_cursor_x = s->regs.cur_hv_pos >> 16;
+ vga->hw_cursor_y = s->regs.cur_hv_pos & 0xffff;
+ s->cursor_offset = s->regs.cur_offset - (s->regs.cur_hv_offs >> 16) -
+ (s->regs.cur_hv_offs & 0xffff) * 16;
+ s->cursor_size = size;
+ if (size) {
+ vga_invalidate_scanlines(vga,
+ vga->hw_cursor_y, vga->hw_cursor_y + 63);
+ }
+ }
+}
+
+static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y)
+{
+ ATIVGAState *s = container_of(vga, ATIVGAState, vga);
+ uint8_t *src;
+ uint32_t *dp = (uint32_t *)d;
+ int i, j, h;
+
+ if (!(s->regs.crtc_gen_cntl & CRTC2_CUR_EN) ||
+ scr_y < vga->hw_cursor_y || scr_y >= vga->hw_cursor_y + 64 ||
+ scr_y > s->regs.crtc_v_total_disp >> 16) {
+ return;
+ }
+ /* FIXME handle cur_hv_offs correctly */
+ src = s->vga.vram_ptr + (s->regs.crtc_offset & 0x07ffffff) +
+ s->cursor_offset + (scr_y - vga->hw_cursor_y) * 16;
+ dp = &dp[vga->hw_cursor_x];
+ h = ((s->regs.crtc_h_total_disp >> 16) + 1) * 8;
+ for (i = 0; i < 8; i++) {
+ uint32_t color;
+ uint8_t abits = src[i];
+ uint8_t xbits = src[i + 8];
+ for (j = 0; j < 8; j++, abits <<= 1, xbits <<= 1) {
+ if (abits & BIT(7)) {
+ if (xbits & BIT(7)) {
+ color = dp[i * 8 + j] ^ 0xffffffff; /* complement */
+ } else {
+ continue; /* transparent, no change */
+ }
+ } else {
+ color = (xbits & BIT(7) ? s->regs.cur_color1 :
+ s->regs.cur_color0) << 8 | 0xff;
+ }
+ if (vga->hw_cursor_x + i * 8 + j >= h) {
+ return; /* end of screen, don't span to next line */
+ }
+ dp[i * 8 + j] = color;
+ }
+ }
+}
+
+static inline uint64_t ati_reg_read_offs(uint32_t reg, int offs,
+ unsigned int size)
+{
+ if (offs == 0 && size == 4) {
+ return reg;
+ } else {
+ return extract32(reg, offs * BITS_PER_BYTE, size * BITS_PER_BYTE);
+ }
+}
+
+static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
+{
+ ATIVGAState *s = opaque;
+ uint64_t val = 0;
+
+ switch (addr) {
+ case MM_INDEX:
+ val = s->regs.mm_index;
+ break;
+ case MM_DATA ... MM_DATA + 3:
+ /* indexed access to regs or memory */
+ if (s->regs.mm_index & BIT(31)) {
+ if (s->regs.mm_index <= s->vga.vram_size - size) {
+ int i = size - 1;
+ while (i >= 0) {
+ val <<= 8;
+ val |= s->vga.vram_ptr[s->regs.mm_index + i--];
+ }
+ }
+ } else {
+ val = ati_mm_read(s, s->regs.mm_index + addr - MM_DATA, size);
+ }
+ break;
+ case BIOS_0_SCRATCH ... BUS_CNTL - 1:
+ {
+ int i = (addr - BIOS_0_SCRATCH) / 4;
+ if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF && i > 3) {
+ break;
+ }
+ val = ati_reg_read_offs(s->regs.bios_scratch[i],
+ addr - (BIOS_0_SCRATCH + i * 4), size);
+ break;
+ }
+ case CRTC_GEN_CNTL ... CRTC_GEN_CNTL + 3:
+ val = ati_reg_read_offs(s->regs.crtc_gen_cntl,
+ addr - CRTC_GEN_CNTL, size);
+ break;
+ case CRTC_EXT_CNTL ... CRTC_EXT_CNTL + 3:
+ val = ati_reg_read_offs(s->regs.crtc_ext_cntl,
+ addr - CRTC_EXT_CNTL, size);
+ break;
+ case DAC_CNTL:
+ val = s->regs.dac_cntl;
+ break;
+/* case GPIO_MONID: FIXME hook up DDC I2C here */
+ case PALETTE_INDEX:
+ /* FIXME unaligned access */
+ val = vga_ioport_read(&s->vga, VGA_PEL_IR) << 16;
+ val |= vga_ioport_read(&s->vga, VGA_PEL_IW) & 0xff;
+ break;
+ case PALETTE_DATA:
+ val = vga_ioport_read(&s->vga, VGA_PEL_D);
+ break;
+ case CNFG_MEMSIZE:
+ val = s->vga.vram_size;
+ break;
+ case MC_STATUS:
+ val = 5;
+ break;
+ case RBBM_STATUS:
+ case GUI_STAT:
+ val = 64; /* free CMDFIFO entries */
+ break;
+ case CRTC_H_TOTAL_DISP:
+ val = s->regs.crtc_h_total_disp;
+ break;
+ case CRTC_H_SYNC_STRT_WID:
+ val = s->regs.crtc_h_sync_strt_wid;
+ break;
+ case CRTC_V_TOTAL_DISP:
+ val = s->regs.crtc_v_total_disp;
+ break;
+ case CRTC_V_SYNC_STRT_WID:
+ val = s->regs.crtc_v_sync_strt_wid;
+ break;
+ case CRTC_OFFSET:
+ val = s->regs.crtc_offset;
+ break;
+ case CRTC_OFFSET_CNTL:
+ val = s->regs.crtc_offset_cntl;
+ break;
+ case CRTC_PITCH:
+ val = s->regs.crtc_pitch;
+ break;
+ case 0xf00 ... 0xfff:
+ val = pci_default_read_config(&s->dev, addr - 0xf00, size);
+ break;
+ case CUR_OFFSET:
+ val = s->regs.cur_offset;
+ break;
+ case CUR_HORZ_VERT_POSN:
+ val = s->regs.cur_hv_pos;
+ val |= s->regs.cur_offset & BIT(31);
+ break;
+ case CUR_HORZ_VERT_OFF:
+ val = s->regs.cur_hv_offs;
+ val |= s->regs.cur_offset & BIT(31);
+ break;
+ case CUR_CLR0:
+ val = s->regs.cur_color0;
+ break;
+ case CUR_CLR1:
+ val = s->regs.cur_color1;
+ break;
+ case DST_OFFSET:
+ val = s->regs.dst_offset;
+ break;
+ case DST_PITCH:
+ val = s->regs.dst_pitch;
+ if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ val &= s->regs.dst_tile << 16;
+ }
+ break;
+ case DST_WIDTH:
+ val = s->regs.dst_width;
+ break;
+ case DST_HEIGHT:
+ val = s->regs.dst_height;
+ break;
+ case SRC_X:
+ val = s->regs.src_x;
+ break;
+ case SRC_Y:
+ val = s->regs.src_y;
+ break;
+ case DST_X:
+ val = s->regs.dst_x;
+ break;
+ case DST_Y:
+ val = s->regs.dst_y;
+ break;
+ case DP_GUI_MASTER_CNTL:
+ val = s->regs.dp_gui_master_cntl;
+ break;
+ case SRC_OFFSET:
+ val = s->regs.src_offset;
+ break;
+ case SRC_PITCH:
+ val = s->regs.src_pitch;
+ if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ val &= s->regs.src_tile << 16;
+ }
+ break;
+ case DP_BRUSH_BKGD_CLR:
+ val = s->regs.dp_brush_bkgd_clr;
+ break;
+ case DP_BRUSH_FRGD_CLR:
+ val = s->regs.dp_brush_frgd_clr;
+ break;
+ case DP_SRC_FRGD_CLR:
+ val = s->regs.dp_src_frgd_clr;
+ break;
+ case DP_SRC_BKGD_CLR:
+ val = s->regs.dp_src_bkgd_clr;
+ break;
+ case DP_CNTL:
+ val = s->regs.dp_cntl;
+ break;
+ case DP_DATATYPE:
+ val = s->regs.dp_datatype;
+ break;
+ case DP_MIX:
+ val = s->regs.dp_mix;
+ break;
+ case DP_WRITE_MASK:
+ val = s->regs.dp_write_mask;
+ break;
+ case DEFAULT_OFFSET:
+ val = s->regs.default_offset;
+ break;
+ case DEFAULT_PITCH:
+ val = s->regs.default_pitch;
+ break;
+ case DEFAULT_SC_BOTTOM_RIGHT:
+ val = s->regs.default_sc_bottom_right;
+ break;
+ default:
+ break;
+ }
+ if (addr < CUR_OFFSET || addr > CUR_CLR1 || ATI_DEBUG_HW_CURSOR) {
+ trace_ati_mm_read(size, addr, ati_reg_name(addr & ~3ULL), val);
+ }
+ return val;
+}
+
+static inline void ati_reg_write_offs(uint32_t *reg, int offs,
+ uint64_t data, unsigned int size)
+{
+ if (offs == 0 && size == 4) {
+ *reg = data;
+ } else {
+ *reg = deposit32(*reg, offs * BITS_PER_BYTE, size * BITS_PER_BYTE,
+ data);
+ }
+}
+
+static void ati_mm_write(void *opaque, hwaddr addr,
+ uint64_t data, unsigned int size)
+{
+ ATIVGAState *s = opaque;
+
+ if (addr < CUR_OFFSET || addr > CUR_CLR1 || ATI_DEBUG_HW_CURSOR) {
+ trace_ati_mm_write(size, addr, ati_reg_name(addr & ~3ULL), data);
+ }
+ switch (addr) {
+ case MM_INDEX:
+ s->regs.mm_index = data;
+ break;
+ case MM_DATA ... MM_DATA + 3:
+ /* indexed access to regs or memory */
+ if (s->regs.mm_index & BIT(31)) {
+ if (s->regs.mm_index <= s->vga.vram_size - size) {
+ int i = 0;
+ while (i < size) {
+ s->vga.vram_ptr[s->regs.mm_index + i] = data & 0xff;
+ data >>= 8;
+ }
+ }
+ } else {
+ ati_mm_write(s, s->regs.mm_index + addr - MM_DATA, data, size);
+ }
+ break;
+ case BIOS_0_SCRATCH ... BUS_CNTL - 1:
+ {
+ int i = (addr - BIOS_0_SCRATCH) / 4;
+ if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF && i > 3) {
+ break;
+ }
+ ati_reg_write_offs(&s->regs.bios_scratch[i],
+ addr - (BIOS_0_SCRATCH + i * 4), data, size);
+ break;
+ }
+ case CRTC_GEN_CNTL ... CRTC_GEN_CNTL + 3:
+ {
+ uint32_t val = s->regs.crtc_gen_cntl;
+ ati_reg_write_offs(&s->regs.crtc_gen_cntl,
+ addr - CRTC_GEN_CNTL, data, size);
+ if ((val & CRTC2_CUR_EN) != (s->regs.crtc_gen_cntl & CRTC2_CUR_EN)) {
+ if (s->cursor_guest_mode) {
+ s->vga.force_shadow = !!(s->regs.crtc_gen_cntl & CRTC2_CUR_EN);
+ } else {
+ if (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) {
+ ati_cursor_define(s);
+ }
+ dpy_mouse_set(s->vga.con, s->regs.cur_hv_pos >> 16,
+ s->regs.cur_hv_pos & 0xffff,
+ (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) != 0);
+ }
+ }
+ if ((val & (CRTC2_EXT_DISP_EN | CRTC2_EN)) !=
+ (s->regs.crtc_gen_cntl & (CRTC2_EXT_DISP_EN | CRTC2_EN))) {
+ ati_vga_switch_mode(s);
+ }
+ break;
+ }
+ case CRTC_EXT_CNTL ... CRTC_EXT_CNTL + 3:
+ {
+ uint32_t val = s->regs.crtc_ext_cntl;
+ ati_reg_write_offs(&s->regs.crtc_ext_cntl,
+ addr - CRTC_EXT_CNTL, data, size);
+ if (s->regs.crtc_ext_cntl & CRT_CRTC_DISPLAY_DIS) {
+ DPRINTF("Display disabled\n");
+ s->vga.ar_index &= ~BIT(5);
+ } else {
+ DPRINTF("Display enabled\n");
+ s->vga.ar_index |= BIT(5);
+ ati_vga_switch_mode(s);
+ }
+ if ((val & CRT_CRTC_DISPLAY_DIS) !=
+ (s->regs.crtc_ext_cntl & CRT_CRTC_DISPLAY_DIS)) {
+ ati_vga_switch_mode(s);
+ }
+ break;
+ }
+ case DAC_CNTL:
+ s->regs.dac_cntl = data & 0xffffe3ff;
+ s->vga.dac_8bit = !!(data & DAC_8BIT_EN);
+ break;
+/* case GPIO_MONID: FIXME hook up DDC I2C here */
+ case PALETTE_INDEX ... PALETTE_INDEX + 3:
+ if (size == 4) {
+ vga_ioport_write(&s->vga, VGA_PEL_IR, (data >> 16) & 0xff);
+ vga_ioport_write(&s->vga, VGA_PEL_IW, data & 0xff);
+ } else {
+ if (addr == PALETTE_INDEX) {
+ vga_ioport_write(&s->vga, VGA_PEL_IW, data & 0xff);
+ } else {
+ vga_ioport_write(&s->vga, VGA_PEL_IR, data & 0xff);
+ }
+ }
+ break;
+ case PALETTE_DATA ... PALETTE_DATA + 3:
+ data <<= addr - PALETTE_DATA;
+ data = bswap32(data) >> 8;
+ vga_ioport_write(&s->vga, VGA_PEL_D, data & 0xff);
+ data >>= 8;
+ vga_ioport_write(&s->vga, VGA_PEL_D, data & 0xff);
+ data >>= 8;
+ vga_ioport_write(&s->vga, VGA_PEL_D, data & 0xff);
+ break;
+ case CRTC_H_TOTAL_DISP:
+ s->regs.crtc_h_total_disp = data & 0x07ff07ff;
+ break;
+ case CRTC_H_SYNC_STRT_WID:
+ s->regs.crtc_h_sync_strt_wid = data & 0x17bf1fff;
+ break;
+ case CRTC_V_TOTAL_DISP:
+ s->regs.crtc_v_total_disp = data & 0x0fff0fff;
+ break;
+ case CRTC_V_SYNC_STRT_WID:
+ s->regs.crtc_v_sync_strt_wid = data & 0x9f0fff;
+ break;
+ case CRTC_OFFSET:
+ s->regs.crtc_offset = data & 0xc7ffffff;
+ break;
+ case CRTC_OFFSET_CNTL:
+ s->regs.crtc_offset_cntl = data; /* FIXME */
+ break;
+ case CRTC_PITCH:
+ s->regs.crtc_pitch = data & 0x07ff07ff;
+ break;
+ case 0xf00 ... 0xfff:
+ /* read-only copy of PCI config space so ignore writes */
+ break;
+ case CUR_OFFSET:
+ if (s->regs.cur_offset != (data & 0x87fffff0)) {
+ s->regs.cur_offset = data & 0x87fffff0;
+ ati_cursor_define(s);
+ }
+ break;
+ case CUR_HORZ_VERT_POSN:
+ s->regs.cur_hv_pos = data & 0x3fff0fff;
+ if (data & BIT(31)) {
+ s->regs.cur_offset |= data & BIT(31);
+ } else if (s->regs.cur_offset & BIT(31)) {
+ s->regs.cur_offset &= ~BIT(31);
+ ati_cursor_define(s);
+ }
+ if (!s->cursor_guest_mode &&
+ (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) && !(data & BIT(31))) {
+ dpy_mouse_set(s->vga.con, s->regs.cur_hv_pos >> 16,
+ s->regs.cur_hv_pos & 0xffff, 1);
+ }
+ break;
+ case CUR_HORZ_VERT_OFF:
+ s->regs.cur_hv_offs = data & 0x3f003f;
+ if (data & BIT(31)) {
+ s->regs.cur_offset |= data & BIT(31);
+ } else if (s->regs.cur_offset & BIT(31)) {
+ s->regs.cur_offset &= ~BIT(31);
+ ati_cursor_define(s);
+ }
+ break;
+ case CUR_CLR0:
+ if (s->regs.cur_color0 != (data & 0xffffff)) {
+ s->regs.cur_color0 = data & 0xffffff;
+ ati_cursor_define(s);
+ }
+ break;
+ case CUR_CLR1:
+ /*
+ * Update cursor unconditionally here because some clients set up
+ * other registers before actually writing cursor data to memory at
+ * offset so we would miss cursor change unless always updating here
+ */
+ s->regs.cur_color1 = data & 0xffffff;
+ ati_cursor_define(s);
+ break;
+ case DST_OFFSET:
+ if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ s->regs.dst_offset = data & 0xfffffff0;
+ } else {
+ s->regs.dst_offset = data & 0xfffffc00;
+ }
+ break;
+ case DST_PITCH:
+ if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ s->regs.dst_pitch = data & 0x3fff;
+ s->regs.dst_tile = (data >> 16) & 1;
+ } else {
+ s->regs.dst_pitch = data & 0x3ff0;
+ }
+ break;
+ case DST_TILE:
+ if (s->dev_id == PCI_DEVICE_ID_ATI_RADEON_QY) {
+ s->regs.dst_tile = data & 3;
+ }
+ break;
+ case DST_WIDTH:
+ s->regs.dst_width = data & 0x3fff;
+ ati_2d_blt(s);
+ break;
+ case DST_HEIGHT:
+ s->regs.dst_height = data & 0x3fff;
+ break;
+ case SRC_X:
+ s->regs.src_x = data & 0x3fff;
+ break;
+ case SRC_Y:
+ s->regs.src_y = data & 0x3fff;
+ break;
+ case DST_X:
+ s->regs.dst_x = data & 0x3fff;
+ break;
+ case DST_Y:
+ s->regs.dst_y = data & 0x3fff;
+ break;
+ case SRC_PITCH_OFFSET:
+ if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ s->regs.src_offset = (data & 0x1fffff) << 5;
+ s->regs.src_pitch = (data >> 21) & 0x3ff;
+ s->regs.src_tile = data >> 31;
+ } else {
+ s->regs.src_offset = (data & 0x3fffff) << 11;
+ s->regs.src_pitch = (data & 0x3fc00000) >> 16;
+ s->regs.src_tile = (data >> 30) & 1;
+ }
+ break;
+ case DST_PITCH_OFFSET:
+ if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ s->regs.dst_offset = (data & 0x1fffff) << 5;
+ s->regs.dst_pitch = (data >> 21) & 0x3ff;
+ s->regs.dst_tile = data >> 31;
+ } else {
+ s->regs.dst_offset = (data & 0x3fffff) << 11;
+ s->regs.dst_pitch = (data & 0x3fc00000) >> 16;
+ s->regs.dst_tile = data >> 30;
+ }
+ break;
+ case SRC_Y_X:
+ s->regs.src_x = data & 0x3fff;
+ s->regs.src_y = (data >> 16) & 0x3fff;
+ break;
+ case DST_Y_X:
+ s->regs.dst_x = data & 0x3fff;
+ s->regs.dst_y = (data >> 16) & 0x3fff;
+ break;
+ case DST_HEIGHT_WIDTH:
+ s->regs.dst_width = data & 0x3fff;
+ s->regs.dst_height = (data >> 16) & 0x3fff;
+ ati_2d_blt(s);
+ break;
+ case DP_GUI_MASTER_CNTL:
+ s->regs.dp_gui_master_cntl = data & 0xf800000f;
+ s->regs.dp_datatype = (data & 0x0f00) >> 8 | (data & 0x30f0) << 4 |
+ (data & 0x4000) << 16;
+ s->regs.dp_mix = (data & GMC_ROP3_MASK) | (data & 0x7000000) >> 16;
+ break;
+ case DST_WIDTH_X:
+ s->regs.dst_x = data & 0x3fff;
+ s->regs.dst_width = (data >> 16) & 0x3fff;
+ ati_2d_blt(s);
+ break;
+ case SRC_X_Y:
+ s->regs.src_y = data & 0x3fff;
+ s->regs.src_x = (data >> 16) & 0x3fff;
+ break;
+ case DST_X_Y:
+ s->regs.dst_y = data & 0x3fff;
+ s->regs.dst_x = (data >> 16) & 0x3fff;
+ break;
+ case DST_WIDTH_HEIGHT:
+ s->regs.dst_height = data & 0x3fff;
+ s->regs.dst_width = (data >> 16) & 0x3fff;
+ ati_2d_blt(s);
+ break;
+ case DST_HEIGHT_Y:
+ s->regs.dst_y = data & 0x3fff;
+ s->regs.dst_height = (data >> 16) & 0x3fff;
+ break;
+ case SRC_OFFSET:
+ if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ s->regs.src_offset = data & 0xfffffff0;
+ } else {
+ s->regs.src_offset = data & 0xfffffc00;
+ }
+ break;
+ case SRC_PITCH:
+ if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ s->regs.src_pitch = data & 0x3fff;
+ s->regs.src_tile = (data >> 16) & 1;
+ } else {
+ s->regs.src_pitch = data & 0x3ff0;
+ }
+ break;
+ case DP_BRUSH_BKGD_CLR:
+ s->regs.dp_brush_bkgd_clr = data;
+ break;
+ case DP_BRUSH_FRGD_CLR:
+ s->regs.dp_brush_frgd_clr = data;
+ break;
+ case DP_CNTL:
+ s->regs.dp_cntl = data;
+ break;
+ case DP_DATATYPE:
+ s->regs.dp_datatype = data & 0xe0070f0f;
+ break;
+ case DP_MIX:
+ s->regs.dp_mix = data & 0x00ff0700;
+ break;
+ case DP_WRITE_MASK:
+ s->regs.dp_write_mask = data;
+ break;
+ case DEFAULT_OFFSET:
+ data &= (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF ?
+ 0x03fffc00 : 0xfffffc00);
+ s->regs.default_offset = data;
+ break;
+ case DEFAULT_PITCH:
+ if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ s->regs.default_pitch = data & 0x103ff;
+ }
+ break;
+ case DEFAULT_SC_BOTTOM_RIGHT:
+ s->regs.default_sc_bottom_right = data & 0x3fff3fff;
+ break;
+ default:
+ break;
+ }
+}
+
+static const MemoryRegionOps ati_mm_ops = {
+ .read = ati_mm_read,
+ .write = ati_mm_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void ati_vga_realize(PCIDevice *dev, Error **errp)
+{
+ ATIVGAState *s = ATI_VGA(dev);
+ VGACommonState *vga = &s->vga;
+
+ if (s->model) {
+ int i;
+ for (i = 0; i < ARRAY_SIZE(ati_model_aliases); i++) {
+ if (!strcmp(s->model, ati_model_aliases[i].name)) {
+ s->dev_id = ati_model_aliases[i].dev_id;
+ break;
+ }
+ }
+ if (i >= ARRAY_SIZE(ati_model_aliases)) {
+ warn_report("Unknown ATI VGA model name, "
+ "using default rage128p");
+ }
+ }
+ if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF &&
+ s->dev_id != PCI_DEVICE_ID_ATI_RADEON_QY) {
+ error_setg(errp, "Unknown ATI VGA device id, "
+ "only 0x5046 and 0x5159 are supported");
+ return;
+ }
+ pci_set_word(dev->config + PCI_DEVICE_ID, s->dev_id);
+
+ if (s->dev_id == PCI_DEVICE_ID_ATI_RADEON_QY &&
+ s->vga.vram_size_mb < 16) {
+ warn_report("Too small video memory for device id");
+ s->vga.vram_size_mb = 16;
+ }
+
+ /* init vga bits */
+ vga_common_init(vga, OBJECT(s));
+ vga_init(vga, OBJECT(s), pci_address_space(dev),
+ pci_address_space_io(dev), true);
+ vga->con = graphic_console_init(DEVICE(s), 0, s->vga.hw_ops, &s->vga);
+ if (s->cursor_guest_mode) {
+ vga->cursor_invalidate = ati_cursor_invalidate;
+ vga->cursor_draw_line = ati_cursor_draw_line;
+ }
+
+ /* mmio register space */
+ memory_region_init_io(&s->mm, OBJECT(s), &ati_mm_ops, s,
+ "ati.mmregs", 0x4000);
+ /* io space is alias to beginning of mmregs */
+ memory_region_init_alias(&s->io, OBJECT(s), "ati.io", &s->mm, 0, 0x100);
+
+ pci_register_bar(dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &vga->vram);
+ pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
+ pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mm);
+}
+
+static void ati_vga_reset(DeviceState *dev)
+{
+ ATIVGAState *s = ATI_VGA(dev);
+
+ /* reset vga */
+ vga_common_reset(&s->vga);
+ s->mode = VGA_MODE;
+}
+
+static void ati_vga_exit(PCIDevice *dev)
+{
+ ATIVGAState *s = ATI_VGA(dev);
+
+ graphic_console_close(s->vga.con);
+}
+
+static Property ati_vga_properties[] = {
+ DEFINE_PROP_UINT32("vgamem_mb", ATIVGAState, vga.vram_size_mb, 16),
+ DEFINE_PROP_STRING("model", ATIVGAState, model),
+ DEFINE_PROP_UINT16("x-device-id", ATIVGAState, dev_id,
+ PCI_DEVICE_ID_ATI_RAGE128_PF),
+ DEFINE_PROP_BOOL("guest_hwcursor", ATIVGAState, cursor_guest_mode, false),
+ DEFINE_PROP_END_OF_LIST()
+};
+
+static void ati_vga_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+ dc->reset = ati_vga_reset;
+ dc->props = ati_vga_properties;
+ dc->hotpluggable = false;
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
+
+ k->class_id = PCI_CLASS_DISPLAY_VGA;
+ k->vendor_id = PCI_VENDOR_ID_ATI;
+ k->device_id = PCI_DEVICE_ID_ATI_RAGE128_PF;
+ k->romfile = "vgabios-stdvga.bin";
+ k->realize = ati_vga_realize;
+ k->exit = ati_vga_exit;
+}
+
+static const TypeInfo ati_vga_info = {
+ .name = TYPE_ATI_VGA,
+ .parent = TYPE_PCI_DEVICE,
+ .instance_size = sizeof(ATIVGAState),
+ .class_init = ati_vga_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+ { },
+ },
+};
+
+static void ati_vga_register_types(void)
+{
+ type_register_static(&ati_vga_info);
+}
+
+type_init(ati_vga_register_types)
diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c
new file mode 100644
index 0000000000..bc98ba6eeb
--- /dev/null
+++ b/hw/display/ati_2d.c
@@ -0,0 +1,167 @@
+/*
+ * QEMU ATI SVGA emulation
+ * 2D engine functions
+ *
+ * Copyright (c) 2019 BALATON Zoltan
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ */
+
+#include "ati_int.h"
+#include "ati_regs.h"
+#include "qemu/log.h"
+#include "ui/pixel_ops.h"
+
+/*
+ * NOTE:
+ * This is 2D _acceleration_ and supposed to be fast. Therefore, don't try to
+ * reinvent the wheel (unlikely to get better with a naive implementation than
+ * existing libraries) and avoid (poorly) reimplementing gfx primitives.
+ * That is unnecessary and would become a performance problem. Instead, try to
+ * map to and reuse existing optimised facilities (e.g. pixman) wherever
+ * possible.
+ */
+
+static int ati_bpp_from_datatype(ATIVGAState *s)
+{
+ switch (s->regs.dp_datatype & 0xf) {
+ case 2:
+ return 8;
+ case 3:
+ case 4:
+ return 16;
+ case 5:
+ return 24;
+ case 6:
+ return 32;
+ default:
+ qemu_log_mask(LOG_UNIMP, "Unknown dst datatype %d\n",
+ s->regs.dp_datatype & 0xf);
+ return 0;
+ }
+}
+
+void ati_2d_blt(ATIVGAState *s)
+{
+ /* FIXME it is probably more complex than this and may need to be */
+ /* rewritten but for now as a start just to get some output: */
+ DisplaySurface *ds = qemu_console_surface(s->vga.con);
+ DPRINTF("%p %u ds: %p %d %d rop: %x\n", s->vga.vram_ptr,
+ s->vga.vbe_start_addr, surface_data(ds), surface_stride(ds),
+ surface_bits_per_pixel(ds),
+ (s->regs.dp_mix & GMC_ROP3_MASK) >> 16);
+ DPRINTF("%d %d, %d %d, (%d,%d) -> (%d,%d) %dx%d\n", s->regs.src_offset,
+ s->regs.dst_offset, s->regs.src_pitch, s->regs.dst_pitch,
+ s->regs.src_x, s->regs.src_y, s->regs.dst_x, s->regs.dst_y,
+ s->regs.dst_width, s->regs.dst_height);
+ switch (s->regs.dp_mix & GMC_ROP3_MASK) {
+ case ROP3_SRCCOPY:
+ {
+ uint8_t *src_bits, *dst_bits, *end;
+ int src_stride, dst_stride, bpp = ati_bpp_from_datatype(s);
+ src_bits = s->vga.vram_ptr + s->regs.src_offset;
+ dst_bits = s->vga.vram_ptr + s->regs.dst_offset;
+ src_stride = s->regs.src_pitch;
+ dst_stride = s->regs.dst_pitch;
+
+ if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ src_bits += s->regs.crtc_offset & 0x07ffffff;
+ dst_bits += s->regs.crtc_offset & 0x07ffffff;
+ src_stride *= bpp;
+ dst_stride *= bpp;
+ }
+ src_stride /= sizeof(uint32_t);
+ dst_stride /= sizeof(uint32_t);
+
+ DPRINTF("pixman_blt(%p, %p, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)\n",
+ src_bits, dst_bits, src_stride, dst_stride, bpp, bpp,
+ s->regs.src_x, s->regs.src_y, s->regs.dst_x, s->regs.dst_y,
+ s->regs.dst_width, s->regs.dst_height);
+ end = s->vga.vram_ptr + s->vga.vram_size;
+ if (src_bits >= end || dst_bits >= end ||
+ src_bits + (s->regs.src_y + s->regs.dst_height) * src_stride +
+ s->regs.src_x >= end ||
+ dst_bits + (s->regs.dst_y + s->regs.dst_height) * dst_stride +
+ s->regs.dst_x >= end) {
+ qemu_log_mask(LOG_UNIMP, "blt outside vram not implemented\n");
+ return;
+ }
+ pixman_blt((uint32_t *)src_bits, (uint32_t *)dst_bits,
+ src_stride, dst_stride, bpp, bpp,
+ s->regs.src_x, s->regs.src_y,
+ s->regs.dst_x, s->regs.dst_y,
+ s->regs.dst_width, s->regs.dst_height);
+ if (dst_bits >= s->vga.vram_ptr + s->vga.vbe_start_addr &&
+ dst_bits < s->vga.vram_ptr + s->vga.vbe_start_addr +
+ s->vga.vbe_regs[VBE_DISPI_INDEX_YRES] * s->vga.vbe_line_offset) {
+ memory_region_set_dirty(&s->vga.vram, s->vga.vbe_start_addr +
+ s->regs.dst_offset +
+ s->regs.dst_y * surface_stride(ds),
+ s->regs.dst_height * surface_stride(ds));
+ }
+ s->regs.dst_x += s->regs.dst_width;
+ s->regs.dst_y += s->regs.dst_height;
+ break;
+ }
+ case ROP3_PATCOPY:
+ case ROP3_BLACKNESS:
+ case ROP3_WHITENESS:
+ {
+ uint8_t *dst_bits, *end;
+ int dst_stride, bpp = ati_bpp_from_datatype(s);
+ uint32_t filler = 0;
+ dst_bits = s->vga.vram_ptr + s->regs.dst_offset;
+ dst_stride = s->regs.dst_pitch;
+
+ if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ dst_bits += s->regs.crtc_offset & 0x07ffffff;
+ dst_stride *= bpp;
+ }
+ dst_stride /= sizeof(uint32_t);
+
+ switch (s->regs.dp_mix & GMC_ROP3_MASK) {
+ case ROP3_PATCOPY:
+ filler = bswap32(s->regs.dp_brush_frgd_clr);
+ break;
+ case ROP3_BLACKNESS:
+ filler = rgb_to_pixel32(s->vga.palette[0], s->vga.palette[1],
+ s->vga.palette[2]) << 8 | 0xff;
+ break;
+ case ROP3_WHITENESS:
+ filler = rgb_to_pixel32(s->vga.palette[3], s->vga.palette[4],
+ s->vga.palette[5]) << 8 | 0xff;
+ break;
+ }
+
+ DPRINTF("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n",
+ dst_bits, dst_stride, bpp,
+ s->regs.dst_x, s->regs.dst_y,
+ s->regs.dst_width, s->regs.dst_height,
+ filler);
+ end = s->vga.vram_ptr + s->vga.vram_size;
+ if (dst_bits >= end ||
+ dst_bits + (s->regs.dst_y + s->regs.dst_height) * dst_stride +
+ s->regs.dst_x >= end) {
+ qemu_log_mask(LOG_UNIMP, "blt outside vram not implemented\n");
+ return;
+ }
+ pixman_fill((uint32_t *)dst_bits, dst_stride, bpp,
+ s->regs.dst_x, s->regs.dst_y,
+ s->regs.dst_width, s->regs.dst_height,
+ filler);
+ if (dst_bits >= s->vga.vram_ptr + s->vga.vbe_start_addr &&
+ dst_bits < s->vga.vram_ptr + s->vga.vbe_start_addr +
+ s->vga.vbe_regs[VBE_DISPI_INDEX_YRES] * s->vga.vbe_line_offset) {
+ memory_region_set_dirty(&s->vga.vram, s->vga.vbe_start_addr +
+ s->regs.dst_offset +
+ s->regs.dst_y * surface_stride(ds),
+ s->regs.dst_height * surface_stride(ds));
+ }
+ s->regs.dst_y += s->regs.dst_height;
+ break;
+ }
+ default:
+ qemu_log_mask(LOG_UNIMP, "Unimplemented ati_2d blt op %x\n",
+ (s->regs.dp_mix & GMC_ROP3_MASK) >> 16);
+ }
+}
diff --git a/hw/display/ati_dbg.c b/hw/display/ati_dbg.c
new file mode 100644
index 0000000000..1e6c32624e
--- /dev/null
+++ b/hw/display/ati_dbg.c
@@ -0,0 +1,259 @@
+#include "ati_int.h"
+
+#ifdef DEBUG_ATI
+struct ati_regdesc {
+ const char *name;
+ int num;
+};
+
+static struct ati_regdesc ati_reg_names[] = {
+ {"MM_INDEX", 0x0000},
+ {"MM_DATA", 0x0004},
+ {"CLOCK_CNTL_INDEX", 0x0008},
+ {"CLOCK_CNTL_DATA", 0x000c},
+ {"BIOS_0_SCRATCH", 0x0010},
+ {"BUS_CNTL", 0x0030},
+ {"BUS_CNTL1", 0x0034},
+ {"GEN_INT_CNTL", 0x0040},
+ {"CRTC_GEN_CNTL", 0x0050},
+ {"CRTC_EXT_CNTL", 0x0054},
+ {"DAC_CNTL", 0x0058},
+ {"GPIO_MONID", 0x0068},
+ {"I2C_CNTL_1", 0x0094},
+ {"PALETTE_INDEX", 0x00b0},
+ {"PALETTE_DATA", 0x00b4},
+ {"CNFG_CNTL", 0x00e0},
+ {"GEN_RESET_CNTL", 0x00f0},
+ {"CNFG_MEMSIZE", 0x00f8},
+ {"MEM_CNTL", 0x0140},
+ {"MC_FB_LOCATION", 0x0148},
+ {"MC_AGP_LOCATION", 0x014C},
+ {"MC_STATUS", 0x0150},
+ {"MEM_POWER_MISC", 0x015c},
+ {"AGP_BASE", 0x0170},
+ {"AGP_CNTL", 0x0174},
+ {"AGP_APER_OFFSET", 0x0178},
+ {"PCI_GART_PAGE", 0x017c},
+ {"PC_NGUI_MODE", 0x0180},
+ {"PC_NGUI_CTLSTAT", 0x0184},
+ {"MPP_TB_CONFIG", 0x01C0},
+ {"MPP_GP_CONFIG", 0x01C8},
+ {"VIPH_CONTROL", 0x01D0},
+ {"CRTC_H_TOTAL_DISP", 0x0200},
+ {"CRTC_H_SYNC_STRT_WID", 0x0204},
+ {"CRTC_V_TOTAL_DISP", 0x0208},
+ {"CRTC_V_SYNC_STRT_WID", 0x020c},
+ {"CRTC_VLINE_CRNT_VLINE", 0x0210},
+ {"CRTC_CRNT_FRAME", 0x0214},
+ {"CRTC_GUI_TRIG_VLINE", 0x0218},
+ {"CRTC_OFFSET", 0x0224},
+ {"CRTC_OFFSET_CNTL", 0x0228},
+ {"CRTC_PITCH", 0x022c},
+ {"OVR_CLR", 0x0230},
+ {"OVR_WID_LEFT_RIGHT", 0x0234},
+ {"OVR_WID_TOP_BOTTOM", 0x0238},
+ {"CUR_OFFSET", 0x0260},
+ {"CUR_HORZ_VERT_POSN", 0x0264},
+ {"CUR_HORZ_VERT_OFF", 0x0268},
+ {"CUR_CLR0", 0x026c},
+ {"CUR_CLR1", 0x0270},
+ {"LVDS_GEN_CNTL", 0x02d0},
+ {"DDA_CONFIG", 0x02e0},
+ {"DDA_ON_OFF", 0x02e4},
+ {"VGA_DDA_CONFIG", 0x02e8},
+ {"VGA_DDA_ON_OFF", 0x02ec},
+ {"CRTC2_H_TOTAL_DISP", 0x0300},
+ {"CRTC2_H_SYNC_STRT_WID", 0x0304},
+ {"CRTC2_V_TOTAL_DISP", 0x0308},
+ {"CRTC2_V_SYNC_STRT_WID", 0x030c},
+ {"CRTC2_VLINE_CRNT_VLINE", 0x0310},
+ {"CRTC2_CRNT_FRAME", 0x0314},
+ {"CRTC2_GUI_TRIG_VLINE", 0x0318},
+ {"CRTC2_OFFSET", 0x0324},
+ {"CRTC2_OFFSET_CNTL", 0x0328},
+ {"CRTC2_PITCH", 0x032c},
+ {"DDA2_CONFIG", 0x03e0},
+ {"DDA2_ON_OFF", 0x03e4},
+ {"CRTC2_GEN_CNTL", 0x03f8},
+ {"CRTC2_STATUS", 0x03fc},
+ {"OV0_SCALE_CNTL", 0x0420},
+ {"SUBPIC_CNTL", 0x0540},
+ {"PM4_BUFFER_OFFSET", 0x0700},
+ {"PM4_BUFFER_CNTL", 0x0704},
+ {"PM4_BUFFER_WM_CNTL", 0x0708},
+ {"PM4_BUFFER_DL_RPTR_ADDR", 0x070c},
+ {"PM4_BUFFER_DL_RPTR", 0x0710},
+ {"PM4_BUFFER_DL_WPTR", 0x0714},
+ {"PM4_VC_FPU_SETUP", 0x071c},
+ {"PM4_FPU_CNTL", 0x0720},
+ {"PM4_VC_FORMAT", 0x0724},
+ {"PM4_VC_CNTL", 0x0728},
+ {"PM4_VC_I01", 0x072c},
+ {"PM4_VC_VLOFF", 0x0730},
+ {"PM4_VC_VLSIZE", 0x0734},
+ {"PM4_IW_INDOFF", 0x0738},
+ {"PM4_IW_INDSIZE", 0x073c},
+ {"PM4_FPU_FPX0", 0x0740},
+ {"PM4_FPU_FPY0", 0x0744},
+ {"PM4_FPU_FPX1", 0x0748},
+ {"PM4_FPU_FPY1", 0x074c},
+ {"PM4_FPU_FPX2", 0x0750},
+ {"PM4_FPU_FPY2", 0x0754},
+ {"PM4_FPU_FPY3", 0x0758},
+ {"PM4_FPU_FPY4", 0x075c},
+ {"PM4_FPU_FPY5", 0x0760},
+ {"PM4_FPU_FPY6", 0x0764},
+ {"PM4_FPU_FPR", 0x0768},
+ {"PM4_FPU_FPG", 0x076c},
+ {"PM4_FPU_FPB", 0x0770},
+ {"PM4_FPU_FPA", 0x0774},
+ {"PM4_FPU_INTXY0", 0x0780},
+ {"PM4_FPU_INTXY1", 0x0784},
+ {"PM4_FPU_INTXY2", 0x0788},
+ {"PM4_FPU_INTARGB", 0x078c},
+ {"PM4_FPU_FPTWICEAREA", 0x0790},
+ {"PM4_FPU_DMAJOR01", 0x0794},
+ {"PM4_FPU_DMAJOR12", 0x0798},
+ {"PM4_FPU_DMAJOR02", 0x079c},
+ {"PM4_FPU_STAT", 0x07a0},
+ {"PM4_STAT", 0x07b8},
+ {"PM4_TEST_CNTL", 0x07d0},
+ {"PM4_MICROCODE_ADDR", 0x07d4},
+ {"PM4_MICROCODE_RADDR", 0x07d8},
+ {"PM4_MICROCODE_DATAH", 0x07dc},
+ {"PM4_MICROCODE_DATAL", 0x07e0},
+ {"PM4_CMDFIFO_ADDR", 0x07e4},
+ {"PM4_CMDFIFO_DATAH", 0x07e8},
+ {"PM4_CMDFIFO_DATAL", 0x07ec},
+ {"PM4_BUFFER_ADDR", 0x07f0},
+ {"PM4_BUFFER_DATAH", 0x07f4},
+ {"PM4_BUFFER_DATAL", 0x07f8},
+ {"PM4_MICRO_CNTL", 0x07fc},
+ {"CAP0_TRIG_CNTL", 0x0950},
+ {"CAP1_TRIG_CNTL", 0x09c0},
+ {"RBBM_STATUS", 0x0e40},
+ {"PM4_FIFO_DATA_EVEN", 0x1000},
+ {"PM4_FIFO_DATA_ODD", 0x1004},
+ {"DST_OFFSET", 0x1404},
+ {"DST_PITCH", 0x1408},
+ {"DST_WIDTH", 0x140c},
+ {"DST_HEIGHT", 0x1410},
+ {"SRC_X", 0x1414},
+ {"SRC_Y", 0x1418},
+ {"DST_X", 0x141c},
+ {"DST_Y", 0x1420},
+ {"SRC_PITCH_OFFSET", 0x1428},
+ {"DST_PITCH_OFFSET", 0x142c},
+ {"SRC_Y_X", 0x1434},
+ {"DST_Y_X", 0x1438},
+ {"DST_HEIGHT_WIDTH", 0x143c},
+ {"DP_GUI_MASTER_CNTL", 0x146c},
+ {"BRUSH_SCALE", 0x1470},
+ {"BRUSH_Y_X", 0x1474},
+ {"DP_BRUSH_BKGD_CLR", 0x1478},
+ {"DP_BRUSH_FRGD_CLR", 0x147c},
+ {"DST_WIDTH_X", 0x1588},
+ {"DST_HEIGHT_WIDTH_8", 0x158c},
+ {"SRC_X_Y", 0x1590},
+ {"DST_X_Y", 0x1594},
+ {"DST_WIDTH_HEIGHT", 0x1598},
+ {"DST_WIDTH_X_INCY", 0x159c},
+ {"DST_HEIGHT_Y", 0x15a0},
+ {"DST_X_SUB", 0x15a4},
+ {"DST_Y_SUB", 0x15a8},
+ {"SRC_OFFSET", 0x15ac},
+ {"SRC_PITCH", 0x15b0},
+ {"DST_HEIGHT_WIDTH_BW", 0x15b4},
+ {"CLR_CMP_CNTL", 0x15c0},
+ {"CLR_CMP_CLR_SRC", 0x15c4},
+ {"CLR_CMP_CLR_DST", 0x15c8},
+ {"CLR_CMP_MASK", 0x15cc},
+ {"DP_SRC_FRGD_CLR", 0x15d8},
+ {"DP_SRC_BKGD_CLR", 0x15dc},
+ {"DST_BRES_ERR", 0x1628},
+ {"DST_BRES_INC", 0x162c},
+ {"DST_BRES_DEC", 0x1630},
+ {"DST_BRES_LNTH", 0x1634},
+ {"DST_BRES_LNTH_SUB", 0x1638},
+ {"SC_LEFT", 0x1640},
+ {"SC_RIGHT", 0x1644},
+ {"SC_TOP", 0x1648},
+ {"SC_BOTTOM", 0x164c},
+ {"SRC_SC_RIGHT", 0x1654},
+ {"SRC_SC_BOTTOM", 0x165c},
+ {"GUI_DEBUG0", 0x16a0},
+ {"GUI_DEBUG1", 0x16a4},
+ {"GUI_TIMEOUT", 0x16b0},
+ {"GUI_TIMEOUT0", 0x16b4},
+ {"GUI_TIMEOUT1", 0x16b8},
+ {"GUI_PROBE", 0x16bc},
+ {"DP_CNTL", 0x16c0},
+ {"DP_DATATYPE", 0x16c4},
+ {"DP_MIX", 0x16c8},
+ {"DP_WRITE_MASK", 0x16cc},
+ {"DP_CNTL_XDIR_YDIR_YMAJOR", 0x16d0},
+ {"DEFAULT_OFFSET", 0x16e0},
+ {"DEFAULT_PITCH", 0x16e4},
+ {"DEFAULT_SC_BOTTOM_RIGHT", 0x16e8},
+ {"SC_TOP_LEFT", 0x16ec},
+ {"SC_BOTTOM_RIGHT", 0x16f0},
+ {"SRC_SC_BOTTOM_RIGHT", 0x16f4},
+ {"DST_TILE", 0x1700},
+ {"WAIT_UNTIL", 0x1720},
+ {"CACHE_CNTL", 0x1724},
+ {"GUI_STAT", 0x1740},
+ {"PC_GUI_MODE", 0x1744},
+ {"PC_GUI_CTLSTAT", 0x1748},
+ {"PC_DEBUG_MODE", 0x1760},
+ {"BRES_DST_ERR_DEC", 0x1780},
+ {"TRAIL_BRES_T12_ERR_DEC", 0x1784},
+ {"TRAIL_BRES_T12_INC", 0x1788},
+ {"DP_T12_CNTL", 0x178c},
+ {"DST_BRES_T1_LNTH", 0x1790},
+ {"DST_BRES_T2_LNTH", 0x1794},
+ {"SCALE_SRC_HEIGHT_WIDTH", 0x1994},
+ {"SCALE_OFFSET_0", 0x1998},
+ {"SCALE_PITCH", 0x199c},
+ {"SCALE_X_INC", 0x19a0},
+ {"SCALE_Y_INC", 0x19a4},
+ {"SCALE_HACC", 0x19a8},
+ {"SCALE_VACC", 0x19ac},
+ {"SCALE_DST_X_Y", 0x19b0},
+ {"SCALE_DST_HEIGHT_WIDTH", 0x19b4},
+ {"SCALE_3D_CNTL", 0x1a00},
+ {"SCALE_3D_DATATYPE", 0x1a20},
+ {"SETUP_CNTL", 0x1bc4},
+ {"SOLID_COLOR", 0x1bc8},
+ {"WINDOW_XY_OFFSET", 0x1bcc},
+ {"DRAW_LINE_POINT", 0x1bd0},
+ {"SETUP_CNTL_PM4", 0x1bd4},
+ {"DST_PITCH_OFFSET_C", 0x1c80},
+ {"DP_GUI_MASTER_CNTL_C", 0x1c84},
+ {"SC_TOP_LEFT_C", 0x1c88},
+ {"SC_BOTTOM_RIGHT_C", 0x1c8c},
+ {"CLR_CMP_MASK_3D", 0x1A28},
+ {"MISC_3D_STATE_CNTL_REG", 0x1CA0},
+ {"MC_SRC1_CNTL", 0x19D8},
+ {"TEX_CNTL", 0x1800},
+ {"RAGE128_MPP_TB_CONFIG", 0x01c0},
+ {NULL, -1}
+};
+
+const char *ati_reg_name(int num)
+{
+ int i;
+
+ num &= ~3;
+ for (i = 0; ati_reg_names[i].name; i++) {
+ if (ati_reg_names[i].num == num) {
+ return ati_reg_names[i].name;
+ }
+ }
+ return "unknown";
+}
+#else
+const char *ati_reg_name(int num)
+{
+ return "";
+}
+#endif
diff --git a/hw/display/ati_int.h b/hw/display/ati_int.h
new file mode 100644
index 0000000000..a6f3e20e63
--- /dev/null
+++ b/hw/display/ati_int.h
@@ -0,0 +1,96 @@
+/*
+ * QEMU ATI SVGA emulation
+ *
+ * Copyright (c) 2019 BALATON Zoltan
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ */
+
+#ifndef ATI_INT_H
+#define ATI_INT_H
+
+#include "qemu/osdep.h"
+#include "hw/pci/pci.h"
+#include "vga_int.h"
+
+/*#define DEBUG_ATI*/
+
+#ifdef DEBUG_ATI
+#define DPRINTF(fmt, ...) printf("%s: " fmt, __func__, ## __VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...) do {} while (0)
+#endif
+
+#define PCI_VENDOR_ID_ATI 0x1002
+/* Rage128 Pro GL */
+#define PCI_DEVICE_ID_ATI_RAGE128_PF 0x5046
+/* Radeon RV100 (VE) */
+#define PCI_DEVICE_ID_ATI_RADEON_QY 0x5159
+
+#define TYPE_ATI_VGA "ati-vga"
+#define ATI_VGA(obj) OBJECT_CHECK(ATIVGAState, (obj), TYPE_ATI_VGA)
+
+typedef struct ATIVGARegs {
+ uint32_t mm_index;
+ uint32_t bios_scratch[8];
+ uint32_t crtc_gen_cntl;
+ uint32_t crtc_ext_cntl;
+ uint32_t dac_cntl;
+ uint32_t crtc_h_total_disp;
+ uint32_t crtc_h_sync_strt_wid;
+ uint32_t crtc_v_total_disp;
+ uint32_t crtc_v_sync_strt_wid;
+ uint32_t crtc_offset;
+ uint32_t crtc_offset_cntl;
+ uint32_t crtc_pitch;
+ uint32_t cur_offset;
+ uint32_t cur_hv_pos;
+ uint32_t cur_hv_offs;
+ uint32_t cur_color0;
+ uint32_t cur_color1;
+ uint32_t dst_offset;
+ uint32_t dst_pitch;
+ uint32_t dst_tile;
+ uint32_t dst_width;
+ uint32_t dst_height;
+ uint32_t src_offset;
+ uint32_t src_pitch;
+ uint32_t src_tile;
+ uint32_t src_x;
+ uint32_t src_y;
+ uint32_t dst_x;
+ uint32_t dst_y;
+ uint32_t dp_gui_master_cntl;
+ uint32_t dp_brush_bkgd_clr;
+ uint32_t dp_brush_frgd_clr;
+ uint32_t dp_src_frgd_clr;
+ uint32_t dp_src_bkgd_clr;
+ uint32_t dp_cntl;
+ uint32_t dp_datatype;
+ uint32_t dp_mix;
+ uint32_t dp_write_mask;
+ uint32_t default_offset;
+ uint32_t default_pitch;
+ uint32_t default_sc_bottom_right;
+} ATIVGARegs;
+
+typedef struct ATIVGAState {
+ PCIDevice dev;
+ VGACommonState vga;
+ char *model;
+ uint16_t dev_id;
+ uint8_t mode;
+ bool cursor_guest_mode;
+ uint16_t cursor_size;
+ uint32_t cursor_offset;
+ QEMUCursor *cursor;
+ MemoryRegion io;
+ MemoryRegion mm;
+ ATIVGARegs regs;
+} ATIVGAState;
+
+const char *ati_reg_name(int num);
+
+void ati_2d_blt(ATIVGAState *s);
+
+#endif /* ATI_INT_H */
diff --git a/hw/display/ati_regs.h b/hw/display/ati_regs.h
new file mode 100644
index 0000000000..923bfd33ce
--- /dev/null
+++ b/hw/display/ati_regs.h
@@ -0,0 +1,461 @@
+/*
+ * ATI VGA register definitions
+ *
+ * based on:
+ * linux/include/video/aty128.h
+ * Register definitions for ATI Rage128 boards
+ * Anthony Tong <atong@uiuc.edu>, 1999
+ * Brad Douglas <brad@neruo.com>, 2000
+ *
+ * and linux/include/video/radeon.h
+ *
+ * This work is licensed under the GNU GPL license version 2.
+ */
+
+/*
+ * Register mapping:
+ * 0x0000-0x00ff Misc regs also accessible via io and mmio space
+ * 0x0100-0x0eff Misc regs only accessible via mmio
+ * 0x0f00-0x0fff Read-only copy of PCI config regs
+ * 0x1000-0x13ff Concurrent Command Engine (CCE) regs
+ * 0x1400-0x1fff GUI (drawing engine) regs
+ */
+
+#ifndef ATI_REGS_H
+#define ATI_REGS_H
+
+#undef DEFAULT_PITCH /* needed for mingw builds */
+
+#define MM_INDEX 0x0000
+#define MM_DATA 0x0004
+#define CLOCK_CNTL_INDEX 0x0008
+#define CLOCK_CNTL_DATA 0x000c
+#define BIOS_0_SCRATCH 0x0010
+#define BUS_CNTL 0x0030
+#define BUS_CNTL1 0x0034
+#define GEN_INT_CNTL 0x0040
+#define CRTC_GEN_CNTL 0x0050
+#define CRTC_EXT_CNTL 0x0054
+#define DAC_CNTL 0x0058
+#define GPIO_MONID 0x0068
+#define I2C_CNTL_1 0x0094
+#define PALETTE_INDEX 0x00b0
+#define PALETTE_DATA 0x00b4
+#define CNFG_CNTL 0x00e0
+#define GEN_RESET_CNTL 0x00f0
+#define CNFG_MEMSIZE 0x00f8
+#define MEM_CNTL 0x0140
+#define MC_FB_LOCATION 0x0148
+#define MC_AGP_LOCATION 0x014C
+#define MC_STATUS 0x0150
+#define MEM_POWER_MISC 0x015c
+#define AGP_BASE 0x0170
+#define AGP_CNTL 0x0174
+#define AGP_APER_OFFSET 0x0178
+#define PCI_GART_PAGE 0x017c
+#define PC_NGUI_MODE 0x0180
+#define PC_NGUI_CTLSTAT 0x0184
+#define MPP_TB_CONFIG 0x01C0
+#define MPP_GP_CONFIG 0x01C8
+#define VIPH_CONTROL 0x01D0
+#define CRTC_H_TOTAL_DISP 0x0200
+#define CRTC_H_SYNC_STRT_WID 0x0204
+#define CRTC_V_TOTAL_DISP 0x0208
+#define CRTC_V_SYNC_STRT_WID 0x020c
+#define CRTC_VLINE_CRNT_VLINE 0x0210
+#define CRTC_CRNT_FRAME 0x0214
+#define CRTC_GUI_TRIG_VLINE 0x0218
+#define CRTC_OFFSET 0x0224
+#define CRTC_OFFSET_CNTL 0x0228
+#define CRTC_PITCH 0x022c
+#define OVR_CLR 0x0230
+#define OVR_WID_LEFT_RIGHT 0x0234
+#define OVR_WID_TOP_BOTTOM 0x0238
+#define CUR_OFFSET 0x0260
+#define CUR_HORZ_VERT_POSN 0x0264
+#define CUR_HORZ_VERT_OFF 0x0268
+#define CUR_CLR0 0x026c
+#define CUR_CLR1 0x0270
+#define LVDS_GEN_CNTL 0x02d0
+#define DDA_CONFIG 0x02e0
+#define DDA_ON_OFF 0x02e4
+#define VGA_DDA_CONFIG 0x02e8
+#define VGA_DDA_ON_OFF 0x02ec
+#define CRTC2_H_TOTAL_DISP 0x0300
+#define CRTC2_H_SYNC_STRT_WID 0x0304
+#define CRTC2_V_TOTAL_DISP 0x0308
+#define CRTC2_V_SYNC_STRT_WID 0x030c
+#define CRTC2_VLINE_CRNT_VLINE 0x0310
+#define CRTC2_CRNT_FRAME 0x0314
+#define CRTC2_GUI_TRIG_VLINE 0x0318
+#define CRTC2_OFFSET 0x0324
+#define CRTC2_OFFSET_CNTL 0x0328
+#define CRTC2_PITCH 0x032c
+#define DDA2_CONFIG 0x03e0
+#define DDA2_ON_OFF 0x03e4
+#define CRTC2_GEN_CNTL 0x03f8
+#define CRTC2_STATUS 0x03fc
+#define OV0_SCALE_CNTL 0x0420
+#define SUBPIC_CNTL 0x0540
+#define PM4_BUFFER_OFFSET 0x0700
+#define PM4_BUFFER_CNTL 0x0704
+#define PM4_BUFFER_WM_CNTL 0x0708
+#define PM4_BUFFER_DL_RPTR_ADDR 0x070c
+#define PM4_BUFFER_DL_RPTR 0x0710
+#define PM4_BUFFER_DL_WPTR 0x0714
+#define PM4_VC_FPU_SETUP 0x071c
+#define PM4_FPU_CNTL 0x0720
+#define PM4_VC_FORMAT 0x0724
+#define PM4_VC_CNTL 0x0728
+#define PM4_VC_I01 0x072c
+#define PM4_VC_VLOFF 0x0730
+#define PM4_VC_VLSIZE 0x0734
+#define PM4_IW_INDOFF 0x0738
+#define PM4_IW_INDSIZE 0x073c
+#define PM4_FPU_FPX0 0x0740
+#define PM4_FPU_FPY0 0x0744
+#define PM4_FPU_FPX1 0x0748
+#define PM4_FPU_FPY1 0x074c
+#define PM4_FPU_FPX2 0x0750
+#define PM4_FPU_FPY2 0x0754
+#define PM4_FPU_FPY3 0x0758
+#define PM4_FPU_FPY4 0x075c
+#define PM4_FPU_FPY5 0x0760
+#define PM4_FPU_FPY6 0x0764
+#define PM4_FPU_FPR 0x0768
+#define PM4_FPU_FPG 0x076c
+#define PM4_FPU_FPB 0x0770
+#define PM4_FPU_FPA 0x0774
+#define PM4_FPU_INTXY0 0x0780
+#define PM4_FPU_INTXY1 0x0784
+#define PM4_FPU_INTXY2 0x0788
+#define PM4_FPU_INTARGB 0x078c
+#define PM4_FPU_FPTWICEAREA 0x0790
+#define PM4_FPU_DMAJOR01 0x0794
+#define PM4_FPU_DMAJOR12 0x0798
+#define PM4_FPU_DMAJOR02 0x079c
+#define PM4_FPU_STAT 0x07a0
+#define PM4_STAT 0x07b8
+#define PM4_TEST_CNTL 0x07d0
+#define PM4_MICROCODE_ADDR 0x07d4
+#define PM4_MICROCODE_RADDR 0x07d8
+#define PM4_MICROCODE_DATAH 0x07dc
+#define PM4_MICROCODE_DATAL 0x07e0
+#define PM4_CMDFIFO_ADDR 0x07e4
+#define PM4_CMDFIFO_DATAH 0x07e8
+#define PM4_CMDFIFO_DATAL 0x07ec
+#define PM4_BUFFER_ADDR 0x07f0
+#define PM4_BUFFER_DATAH 0x07f4
+#define PM4_BUFFER_DATAL 0x07f8
+#define PM4_MICRO_CNTL 0x07fc
+#define CAP0_TRIG_CNTL 0x0950
+#define CAP1_TRIG_CNTL 0x09c0
+
+#define RBBM_STATUS 0x0e40
+
+/*
+ * GUI Block Memory Mapped Registers
+ * These registers are FIFOed.
+ */
+#define PM4_FIFO_DATA_EVEN 0x1000
+#define PM4_FIFO_DATA_ODD 0x1004
+
+#define DST_OFFSET 0x1404
+#define DST_PITCH 0x1408
+#define DST_WIDTH 0x140c
+#define DST_HEIGHT 0x1410
+#define SRC_X 0x1414
+#define SRC_Y 0x1418
+#define DST_X 0x141c
+#define DST_Y 0x1420
+#define SRC_PITCH_OFFSET 0x1428
+#define DST_PITCH_OFFSET 0x142c
+#define SRC_Y_X 0x1434
+#define DST_Y_X 0x1438
+#define DST_HEIGHT_WIDTH 0x143c
+#define DP_GUI_MASTER_CNTL 0x146c
+#define BRUSH_SCALE 0x1470
+#define BRUSH_Y_X 0x1474
+#define DP_BRUSH_BKGD_CLR 0x1478
+#define DP_BRUSH_FRGD_CLR 0x147c
+#define DST_WIDTH_X 0x1588
+#define DST_HEIGHT_WIDTH_8 0x158c
+#define SRC_X_Y 0x1590
+#define DST_X_Y 0x1594
+#define DST_WIDTH_HEIGHT 0x1598
+#define DST_WIDTH_X_INCY 0x159c
+#define DST_HEIGHT_Y 0x15a0
+#define DST_X_SUB 0x15a4
+#define DST_Y_SUB 0x15a8
+#define SRC_OFFSET 0x15ac
+#define SRC_PITCH 0x15b0
+#define DST_HEIGHT_WIDTH_BW 0x15b4
+#define CLR_CMP_CNTL 0x15c0
+#define CLR_CMP_CLR_SRC 0x15c4
+#define CLR_CMP_CLR_DST 0x15c8
+#define CLR_CMP_MASK 0x15cc
+#define DP_SRC_FRGD_CLR 0x15d8
+#define DP_SRC_BKGD_CLR 0x15dc
+#define DST_BRES_ERR 0x1628
+#define DST_BRES_INC 0x162c
+#define DST_BRES_DEC 0x1630
+#define DST_BRES_LNTH 0x1634
+#define DST_BRES_LNTH_SUB 0x1638
+#define SC_LEFT 0x1640
+#define SC_RIGHT 0x1644
+#define SC_TOP 0x1648
+#define SC_BOTTOM 0x164c
+#define SRC_SC_RIGHT 0x1654
+#define SRC_SC_BOTTOM 0x165c
+#define GUI_DEBUG0 0x16a0
+#define GUI_DEBUG1 0x16a4
+#define GUI_TIMEOUT 0x16b0
+#define GUI_TIMEOUT0 0x16b4
+#define GUI_TIMEOUT1 0x16b8
+#define GUI_PROBE 0x16bc
+#define DP_CNTL 0x16c0
+#define DP_DATATYPE 0x16c4
+#define DP_MIX 0x16c8
+#define DP_WRITE_MASK 0x16cc
+#define DP_CNTL_XDIR_YDIR_YMAJOR 0x16d0
+#define DEFAULT_OFFSET 0x16e0
+#define DEFAULT_PITCH 0x16e4
+#define DEFAULT_SC_BOTTOM_RIGHT 0x16e8
+#define SC_TOP_LEFT 0x16ec
+#define SC_BOTTOM_RIGHT 0x16f0
+#define SRC_SC_BOTTOM_RIGHT 0x16f4
+#define DST_TILE 0x1700
+#define WAIT_UNTIL 0x1720
+#define CACHE_CNTL 0x1724
+#define GUI_STAT 0x1740
+#define PC_GUI_MODE 0x1744
+#define PC_GUI_CTLSTAT 0x1748
+#define PC_DEBUG_MODE 0x1760
+#define BRES_DST_ERR_DEC 0x1780
+#define TRAIL_BRES_T12_ERR_DEC 0x1784
+#define TRAIL_BRES_T12_INC 0x1788
+#define DP_T12_CNTL 0x178c
+#define DST_BRES_T1_LNTH 0x1790
+#define DST_BRES_T2_LNTH 0x1794
+#define SCALE_SRC_HEIGHT_WIDTH 0x1994
+#define SCALE_OFFSET_0 0x1998
+#define SCALE_PITCH 0x199c
+#define SCALE_X_INC 0x19a0
+#define SCALE_Y_INC 0x19a4
+#define SCALE_HACC 0x19a8
+#define SCALE_VACC 0x19ac
+#define SCALE_DST_X_Y 0x19b0
+#define SCALE_DST_HEIGHT_WIDTH 0x19b4
+#define SCALE_3D_CNTL 0x1a00
+#define SCALE_3D_DATATYPE 0x1a20
+#define SETUP_CNTL 0x1bc4
+#define SOLID_COLOR 0x1bc8
+#define WINDOW_XY_OFFSET 0x1bcc
+#define DRAW_LINE_POINT 0x1bd0
+#define SETUP_CNTL_PM4 0x1bd4
+#define DST_PITCH_OFFSET_C 0x1c80
+#define DP_GUI_MASTER_CNTL_C 0x1c84
+#define SC_TOP_LEFT_C 0x1c88
+#define SC_BOTTOM_RIGHT_C 0x1c8c
+
+#define CLR_CMP_MASK_3D 0x1A28
+#define MISC_3D_STATE_CNTL_REG 0x1CA0
+#define MC_SRC1_CNTL 0x19D8
+#define TEX_CNTL 0x1800
+
+/* CONSTANTS */
+#define GUI_ACTIVE 0x80000000
+#define ENGINE_IDLE 0x0
+
+#define PLL_WR_EN 0x00000080
+
+#define CLK_PIN_CNTL 0x01
+#define PPLL_CNTL 0x02
+#define PPLL_REF_DIV 0x03
+#define PPLL_DIV_0 0x04
+#define PPLL_DIV_1 0x05
+#define PPLL_DIV_2 0x06
+#define PPLL_DIV_3 0x07
+#define VCLK_ECP_CNTL 0x08
+#define HTOTAL_CNTL 0x09
+#define X_MPLL_REF_FB_DIV 0x0a
+#define XPLL_CNTL 0x0b
+#define XDLL_CNTL 0x0c
+#define XCLK_CNTL 0x0d
+#define MPLL_CNTL 0x0e
+#define MCLK_CNTL 0x0f
+#define AGP_PLL_CNTL 0x10
+#define FCP_CNTL 0x12
+#define PLL_TEST_CNTL 0x13
+#define P2PLL_CNTL 0x2a
+#define P2PLL_REF_DIV 0x2b
+#define P2PLL_DIV_0 0x2b
+#define POWER_MANAGEMENT 0x2f
+
+#define PPLL_RESET 0x00000001
+#define PPLL_ATOMIC_UPDATE_EN 0x00010000
+#define PPLL_VGA_ATOMIC_UPDATE_EN 0x00020000
+#define PPLL_REF_DIV_MASK 0x000003FF
+#define PPLL_FB3_DIV_MASK 0x000007FF
+#define PPLL_POST3_DIV_MASK 0x00070000
+#define PPLL_ATOMIC_UPDATE_R 0x00008000
+#define PPLL_ATOMIC_UPDATE_W 0x00008000
+#define MEM_CFG_TYPE_MASK 0x00000003
+#define XCLK_SRC_SEL_MASK 0x00000007
+#define XPLL_FB_DIV_MASK 0x0000FF00
+#define X_MPLL_REF_DIV_MASK 0x000000FF
+
+/* Config control values (CONFIG_CNTL) */
+#define CFG_VGA_IO_DIS 0x00000400
+
+/* CRTC control values (CRTC_GEN_CNTL) */
+#define CRTC_CSYNC_EN 0x00000010
+
+#define CRTC2_DBL_SCAN_EN 0x00000001
+#define CRTC2_DISPLAY_DIS 0x00800000
+#define CRTC2_FIFO_EXTSENSE 0x00200000
+#define CRTC2_ICON_EN 0x00100000
+#define CRTC2_CUR_EN 0x00010000
+#define CRTC2_EXT_DISP_EN 0x01000000
+#define CRTC2_EN 0x02000000
+#define CRTC2_DISP_REQ_EN_B 0x04000000
+
+#define CRTC_PIX_WIDTH_MASK 0x00000700
+#define CRTC_PIX_WIDTH_4BPP 0x00000100
+#define CRTC_PIX_WIDTH_8BPP 0x00000200
+#define CRTC_PIX_WIDTH_15BPP 0x00000300
+#define CRTC_PIX_WIDTH_16BPP 0x00000400
+#define CRTC_PIX_WIDTH_24BPP 0x00000500
+#define CRTC_PIX_WIDTH_32BPP 0x00000600
+
+/* DAC_CNTL bit constants */
+#define DAC_8BIT_EN 0x00000100
+#define DAC_MASK 0xFF000000
+#define DAC_BLANKING 0x00000004
+#define DAC_RANGE_CNTL 0x00000003
+#define DAC_CLK_SEL 0x00000010
+#define DAC_PALETTE_ACCESS_CNTL 0x00000020
+#define DAC_PALETTE2_SNOOP_EN 0x00000040
+#define DAC_PDWN 0x00008000
+
+/* CRTC_EXT_CNTL */
+#define CRT_CRTC_DISPLAY_DIS 0x00000400
+#define CRT_CRTC_ON 0x00008000
+
+/* GEN_RESET_CNTL bit constants */
+#define SOFT_RESET_GUI 0x00000001
+#define SOFT_RESET_VCLK 0x00000100
+#define SOFT_RESET_PCLK 0x00000200
+#define SOFT_RESET_ECP 0x00000400
+#define SOFT_RESET_DISPENG_XCLK 0x00000800
+
+/* PC_GUI_CTLSTAT bit constants */
+#define PC_BUSY_INIT 0x10000000
+#define PC_BUSY_GUI 0x20000000
+#define PC_BUSY_NGUI 0x40000000
+#define PC_BUSY 0x80000000
+
+#define BUS_MASTER_DIS 0x00000040
+#define PM4_BUFFER_CNTL_NONPM4 0x00000000
+
+/* DP_DATATYPE bit constants */
+#define DST_8BPP 0x00000002
+#define DST_15BPP 0x00000003
+#define DST_16BPP 0x00000004
+#define DST_24BPP 0x00000005
+#define DST_32BPP 0x00000006
+
+#define BRUSH_SOLIDCOLOR 0x00000d00
+
+/* DP_GUI_MASTER_CNTL bit constants */
+#define GMC_SRC_PITCH_OFFSET_DEFAULT 0x00000000
+#define GMC_DST_PITCH_OFFSET_DEFAULT 0x00000000
+#define GMC_SRC_CLIP_DEFAULT 0x00000000
+#define GMC_DST_CLIP_DEFAULT 0x00000000
+#define GMC_BRUSH_SOLIDCOLOR 0x000000d0
+#define GMC_SRC_DSTCOLOR 0x00003000
+#define GMC_BYTE_ORDER_MSB_TO_LSB 0x00000000
+#define GMC_DP_SRC_RECT 0x02000000
+#define GMC_3D_FCN_EN_CLR 0x00000000
+#define GMC_AUX_CLIP_CLEAR 0x20000000
+#define GMC_DST_CLR_CMP_FCN_CLEAR 0x10000000
+#define GMC_WRITE_MASK_SET 0x40000000
+#define GMC_DP_CONVERSION_TEMP_6500 0x00000000
+
+/* DP_GUI_MASTER_CNTL ROP3 named constants */
+#define GMC_ROP3_MASK 0x00ff0000
+#define ROP3_BLACKNESS 0x00000000
+#define ROP3_SRCCOPY 0x00cc0000
+#define ROP3_PATCOPY 0x00f00000
+#define ROP3_WHITENESS 0x00ff0000
+
+#define SRC_DSTCOLOR 0x00030000
+
+/* DP_CNTL bit constants */
+#define DST_X_RIGHT_TO_LEFT 0x00000000
+#define DST_X_LEFT_TO_RIGHT 0x00000001
+#define DST_Y_BOTTOM_TO_TOP 0x00000000
+#define DST_Y_TOP_TO_BOTTOM 0x00000002
+#define DST_X_MAJOR 0x00000000
+#define DST_Y_MAJOR 0x00000004
+#define DST_X_TILE 0x00000008
+#define DST_Y_TILE 0x00000010
+#define DST_LAST_PEL 0x00000020
+#define DST_TRAIL_X_RIGHT_TO_LEFT 0x00000000
+#define DST_TRAIL_X_LEFT_TO_RIGHT 0x00000040
+#define DST_TRAP_FILL_RIGHT_TO_LEFT 0x00000000
+#define DST_TRAP_FILL_LEFT_TO_RIGHT 0x00000080
+#define DST_BRES_SIGN 0x00000100
+#define DST_HOST_BIG_ENDIAN_EN 0x00000200
+#define DST_POLYLINE_NONLAST 0x00008000
+#define DST_RASTER_STALL 0x00010000
+#define DST_POLY_EDGE 0x00040000
+
+/* DP_MIX bit constants */
+#define DP_SRC_RECT 0x00000200
+#define DP_SRC_HOST 0x00000300
+#define DP_SRC_HOST_BYTEALIGN 0x00000400
+
+/* LVDS_GEN_CNTL constants */
+#define LVDS_BL_MOD_LEVEL_MASK 0x0000ff00
+#define LVDS_BL_MOD_LEVEL_SHIFT 8
+#define LVDS_BL_MOD_EN 0x00010000
+#define LVDS_DIGION 0x00040000
+#define LVDS_BLON 0x00080000
+#define LVDS_ON 0x00000001
+#define LVDS_DISPLAY_DIS 0x00000002
+#define LVDS_PANEL_TYPE_2PIX_PER_CLK 0x00000004
+#define LVDS_PANEL_24BITS_TFT 0x00000008
+#define LVDS_FRAME_MOD_NO 0x00000000
+#define LVDS_FRAME_MOD_2_LEVELS 0x00000010
+#define LVDS_FRAME_MOD_4_LEVELS 0x00000020
+#define LVDS_RST_FM 0x00000040
+#define LVDS_EN 0x00000080
+
+/* CRTC2_GEN_CNTL constants */
+#define CRTC2_EN 0x02000000
+
+/* POWER_MANAGEMENT constants */
+#define PWR_MGT_ON 0x00000001
+#define PWR_MGT_MODE_MASK 0x00000006
+#define PWR_MGT_MODE_PIN 0x00000000
+#define PWR_MGT_MODE_REGISTER 0x00000002
+#define PWR_MGT_MODE_TIMER 0x00000004
+#define PWR_MGT_MODE_PCI 0x00000006
+#define PWR_MGT_AUTO_PWR_UP_EN 0x00000008
+#define PWR_MGT_ACTIVITY_PIN_ON 0x00000010
+#define PWR_MGT_STANDBY_POL 0x00000020
+#define PWR_MGT_SUSPEND_POL 0x00000040
+#define PWR_MGT_SELF_REFRESH 0x00000080
+#define PWR_MGT_ACTIVITY_PIN_EN 0x00000100
+#define PWR_MGT_KEYBD_SNOOP 0x00000200
+#define PWR_MGT_TRISTATE_MEM_EN 0x00000800
+#define PWR_MGT_SELW4MS 0x00001000
+#define PWR_MGT_SLOWDOWN_MCLK 0x00002000
+
+#define PMI_PMSCR_REG 0x60
+
+/* used by ATI bug fix for hardware ROM */
+#define RAGE128_MPP_TB_CONFIG 0x01c0
+
+#endif /* ATI_REGS_H */
diff --git a/hw/display/trace-events b/hw/display/trace-events
index 37d3264bb2..80993cc4d9 100644
--- a/hw/display/trace-events
+++ b/hw/display/trace-events
@@ -138,3 +138,7 @@ vga_cirrus_write_blt(uint32_t offset, uint32_t val) "offset 0x%x, val 0x%x"
sii9022_read_reg(uint8_t addr, uint8_t val) "addr 0x%02x, val 0x%02x"
sii9022_write_reg(uint8_t addr, uint8_t val) "addr 0x%02x, val 0x%02x"
sii9022_switch_mode(const char *mode) "mode: %s"
+
+# hw/display/ati*.c
+ati_mm_read(unsigned int size, uint64_t addr, const char *name, uint64_t val) "%u 0x%"HWADDR_PRIx " %s -> 0x%"PRIx64
+ati_mm_write(unsigned int size, uint64_t addr, const char *name, uint64_t val) "%u 0x%"HWADDR_PRIx " %s <- 0x%"PRIx64
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index a3627f58a9..4dbf48e424 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1346,7 +1346,7 @@ static void virtio_gpu_instance_init(Object *obj)
{
}
-void virtio_gpu_reset(VirtIODevice *vdev)
+static void virtio_gpu_reset(VirtIODevice *vdev)
{
VirtIOGPU *g = VIRTIO_GPU(vdev);
struct virtio_gpu_simple_resource *res, *tmp;
diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c
index 1e48009b74..a2b803b75f 100644
--- a/hw/display/virtio-vga.c
+++ b/hw/display/virtio-vga.c
@@ -12,6 +12,10 @@
#define TYPE_VIRTIO_VGA "virtio-vga"
#define VIRTIO_VGA(obj) \
OBJECT_CHECK(VirtIOVGA, (obj), TYPE_VIRTIO_VGA)
+#define VIRTIO_VGA_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(VirtIOVGAClass, obj, TYPE_VIRTIO_VGA)
+#define VIRTIO_VGA_CLASS(klass) \
+ OBJECT_CLASS_CHECK(VirtIOVGAClass, klass, TYPE_VIRTIO_VGA)
typedef struct VirtIOVGA {
VirtIOPCIProxy parent_obj;
@@ -20,6 +24,11 @@ typedef struct VirtIOVGA {
MemoryRegion vga_mrs[3];
} VirtIOVGA;
+typedef struct VirtIOVGAClass {
+ VirtioPCIClass parent_class;
+ DeviceReset parent_reset;
+} VirtIOVGAClass;
+
static void virtio_vga_invalidate_display(void *opaque)
{
VirtIOVGA *vvga = opaque;
@@ -168,10 +177,11 @@ static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
static void virtio_vga_reset(DeviceState *dev)
{
+ VirtIOVGAClass *klass = VIRTIO_VGA_GET_CLASS(dev);
VirtIOVGA *vvga = VIRTIO_VGA(dev);
/* reset virtio-gpu */
- virtio_gpu_reset(VIRTIO_DEVICE(&vvga->vdev));
+ klass->parent_reset(dev);
/* reset vga */
vga_common_reset(&vvga->vga);
@@ -187,13 +197,15 @@ static void virtio_vga_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+ VirtIOVGAClass *v = VIRTIO_VGA_CLASS(klass);
PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
dc->props = virtio_vga_properties;
- dc->reset = virtio_vga_reset;
dc->vmsd = &vmstate_virtio_vga;
dc->hotpluggable = false;
+ device_class_set_parent_reset(dc, virtio_vga_reset,
+ &v->parent_reset);
k->realize = virtio_vga_realize;
pcidev_k->romfile = "vgabios-virtio.bin";
@@ -212,6 +224,7 @@ static VirtioPCIDeviceTypeInfo virtio_vga_info = {
.generic_name = TYPE_VIRTIO_VGA,
.instance_size = sizeof(struct VirtIOVGA),
.instance_init = virtio_vga_inst_initfn,
+ .class_size = sizeof(struct VirtIOVGAClass),
.class_init = virtio_vga_class_init,
};
diff --git a/hw/i2c/Kconfig b/hw/i2c/Kconfig
index ef1caa6d89..820b24de5b 100644
--- a/hw/i2c/Kconfig
+++ b/hw/i2c/Kconfig
@@ -25,3 +25,7 @@ config BITBANG_I2C
config IMX_I2C
bool
select I2C
+
+config MPC_I2C
+ bool
+ select I2C
diff --git a/hw/i2c/Makefile.objs b/hw/i2c/Makefile.objs
index 2a3c106551..5f76b6a990 100644
--- a/hw/i2c/Makefile.objs
+++ b/hw/i2c/Makefile.objs
@@ -9,5 +9,6 @@ common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o
common-obj-$(CONFIG_IMX_I2C) += imx_i2c.o
common-obj-$(CONFIG_ASPEED_SOC) += aspeed_i2c.o
common-obj-$(CONFIG_NRF51_SOC) += microbit_i2c.o
+common-obj-$(CONFIG_MPC_I2C) += mpc_i2c.o
obj-$(CONFIG_OMAP) += omap_i2c.o
obj-$(CONFIG_PPC4XX) += ppc4xx_i2c.o
diff --git a/hw/i2c/mpc_i2c.c b/hw/i2c/mpc_i2c.c
new file mode 100644
index 0000000000..693ca7ef6b
--- /dev/null
+++ b/hw/i2c/mpc_i2c.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Amit Tomar, <Amit.Tomar@freescale.com>
+ *
+ * Description:
+ * This file is derived from IMX I2C controller,
+ * by Jean-Christophe DUBOIS .
+ *
+ * Thanks to Scott Wood and Alexander Graf for their kind help on this.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 or later,
+ * as published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/i2c/i2c.h"
+#include "qemu/log.h"
+#include "hw/sysbus.h"
+
+/* #define DEBUG_I2C */
+
+#ifdef DEBUG_I2C
+#define DPRINTF(fmt, ...) \
+ do { fprintf(stderr, "mpc_i2c[%s]: " fmt, __func__, ## __VA_ARGS__); \
+ } while (0)
+#else
+#define DPRINTF(fmt, ...) do {} while (0)
+#endif
+
+#define TYPE_MPC_I2C "mpc-i2c"
+#define MPC_I2C(obj) \
+ OBJECT_CHECK(MPCI2CState, (obj), TYPE_MPC_I2C)
+
+#define MPC_I2C_ADR 0x00
+#define MPC_I2C_FDR 0x04
+#define MPC_I2C_CR 0x08
+#define MPC_I2C_SR 0x0c
+#define MPC_I2C_DR 0x10
+#define MPC_I2C_DFSRR 0x14
+
+#define CCR_MEN (1 << 7)
+#define CCR_MIEN (1 << 6)
+#define CCR_MSTA (1 << 5)
+#define CCR_MTX (1 << 4)
+#define CCR_TXAK (1 << 3)
+#define CCR_RSTA (1 << 2)
+#define CCR_BCST (1 << 0)
+
+#define CSR_MCF (1 << 7)
+#define CSR_MAAS (1 << 6)
+#define CSR_MBB (1 << 5)
+#define CSR_MAL (1 << 4)
+#define CSR_SRW (1 << 2)
+#define CSR_MIF (1 << 1)
+#define CSR_RXAK (1 << 0)
+
+#define CADR_MASK 0xFE
+#define CFDR_MASK 0x3F
+#define CCR_MASK 0xFC
+#define CSR_MASK 0xED
+#define CDR_MASK 0xFF
+
+#define CYCLE_RESET 0xFF
+
+typedef struct MPCI2CState {
+ SysBusDevice parent_obj;
+
+ I2CBus *bus;
+ qemu_irq irq;
+ MemoryRegion iomem;
+
+ uint8_t address;
+ uint8_t adr;
+ uint8_t fdr;
+ uint8_t cr;
+ uint8_t sr;
+ uint8_t dr;
+ uint8_t dfssr;
+} MPCI2CState;
+
+static bool mpc_i2c_is_enabled(MPCI2CState *s)
+{
+ return s->cr & CCR_MEN;
+}
+
+static bool mpc_i2c_is_master(MPCI2CState *s)
+{
+ return s->cr & CCR_MSTA;
+}
+
+static bool mpc_i2c_direction_is_tx(MPCI2CState *s)
+{
+ return s->cr & CCR_MTX;
+}
+
+static bool mpc_i2c_irq_pending(MPCI2CState *s)
+{
+ return s->sr & CSR_MIF;
+}
+
+static bool mpc_i2c_irq_is_enabled(MPCI2CState *s)
+{
+ return s->cr & CCR_MIEN;
+}
+
+static void mpc_i2c_reset(DeviceState *dev)
+{
+ MPCI2CState *i2c = MPC_I2C(dev);
+
+ i2c->address = 0xFF;
+ i2c->adr = 0x00;
+ i2c->fdr = 0x00;
+ i2c->cr = 0x00;
+ i2c->sr = 0x81;
+ i2c->dr = 0x00;
+}
+
+static void mpc_i2c_irq(MPCI2CState *s)
+{
+ bool irq_active = false;
+
+ if (mpc_i2c_is_enabled(s) && mpc_i2c_irq_is_enabled(s)
+ && mpc_i2c_irq_pending(s)) {
+ irq_active = true;
+ }
+
+ if (irq_active) {
+ qemu_irq_raise(s->irq);
+ } else {
+ qemu_irq_lower(s->irq);
+ }
+}
+
+static void mpc_i2c_soft_reset(MPCI2CState *s)
+{
+ /* This is a soft reset. ADR is preserved during soft resets */
+ uint8_t adr = s->adr;
+ mpc_i2c_reset(DEVICE(s));
+ s->adr = adr;
+}
+
+static void mpc_i2c_address_send(MPCI2CState *s)
+{
+ /* if returns non zero slave address is not right */
+ if (i2c_start_transfer(s->bus, s->dr >> 1, s->dr & (0x01))) {
+ s->sr |= CSR_RXAK;
+ } else {
+ s->address = s->dr;
+ s->sr &= ~CSR_RXAK;
+ s->sr |= CSR_MCF; /* Set after Byte Transfer is completed */
+ s->sr |= CSR_MIF; /* Set after Byte Transfer is completed */
+ mpc_i2c_irq(s);
+ }
+}
+
+static void mpc_i2c_data_send(MPCI2CState *s)
+{
+ if (i2c_send(s->bus, s->dr)) {
+ /* End of transfer */
+ s->sr |= CSR_RXAK;
+ i2c_end_transfer(s->bus);
+ } else {
+ s->sr &= ~CSR_RXAK;
+ s->sr |= CSR_MCF; /* Set after Byte Transfer is completed */
+ s->sr |= CSR_MIF; /* Set after Byte Transfer is completed */
+ mpc_i2c_irq(s);
+ }
+}
+
+static void mpc_i2c_data_recive(MPCI2CState *s)
+{
+ int ret;
+ /* get the next byte */
+ ret = i2c_recv(s->bus);
+ if (ret >= 0) {
+ s->sr |= CSR_MCF; /* Set after Byte Transfer is completed */
+ s->sr |= CSR_MIF; /* Set after Byte Transfer is completed */
+ mpc_i2c_irq(s);
+ } else {
+ DPRINTF("read failed for device");
+ ret = 0xff;
+ }
+ s->dr = ret;
+}
+
+static uint64_t mpc_i2c_read(void *opaque, hwaddr addr, unsigned size)
+{
+ MPCI2CState *s = opaque;
+ uint8_t value;
+
+ switch (addr) {
+ case MPC_I2C_ADR:
+ value = s->adr;
+ break;
+ case MPC_I2C_FDR:
+ value = s->fdr;
+ break;
+ case MPC_I2C_CR:
+ value = s->cr;
+ break;
+ case MPC_I2C_SR:
+ value = s->sr;
+ break;
+ case MPC_I2C_DR:
+ value = s->dr;
+ if (mpc_i2c_is_master(s)) { /* master mode */
+ if (mpc_i2c_direction_is_tx(s)) {
+ DPRINTF("MTX is set not in recv mode\n");
+ } else {
+ mpc_i2c_data_recive(s);
+ }
+ }
+ break;
+ default:
+ value = 0;
+ DPRINTF("ERROR: Bad read addr 0x%x\n", (unsigned int)addr);
+ break;
+ }
+
+ DPRINTF("%s: addr " TARGET_FMT_plx " %02" PRIx32 "\n", __func__,
+ addr, value);
+ return (uint64_t)value;
+}
+
+static void mpc_i2c_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
+{
+ MPCI2CState *s = opaque;
+
+ DPRINTF("%s: addr " TARGET_FMT_plx " val %08" PRIx64 "\n", __func__,
+ addr, value);
+ switch (addr) {
+ case MPC_I2C_ADR:
+ s->adr = value & CADR_MASK;
+ break;
+ case MPC_I2C_FDR:
+ s->fdr = value & CFDR_MASK;
+ break;
+ case MPC_I2C_CR:
+ if (mpc_i2c_is_enabled(s) && ((value & CCR_MEN) == 0)) {
+ mpc_i2c_soft_reset(s);
+ break;
+ }
+ /* normal write */
+ s->cr = value & CCR_MASK;
+ if (mpc_i2c_is_master(s)) { /* master mode */
+ /* set the bus to busy after master is set as per RM */
+ s->sr |= CSR_MBB;
+ } else {
+ /* bus is not busy anymore */
+ s->sr &= ~CSR_MBB;
+ /* Reset the address for fresh write/read cycle */
+ if (s->address != CYCLE_RESET) {
+ i2c_end_transfer(s->bus);
+ s->address = CYCLE_RESET;
+ }
+ }
+ /* For restart end the onging transfer */
+ if (s->cr & CCR_RSTA) {
+ if (s->address != CYCLE_RESET) {
+ s->address = CYCLE_RESET;
+ i2c_end_transfer(s->bus);
+ s->cr &= ~CCR_RSTA;
+ }
+ }
+ break;
+ case MPC_I2C_SR:
+ s->sr = value & CSR_MASK;
+ /* Lower the interrupt */
+ if (!(s->sr & CSR_MIF) || !(s->sr & CSR_MAL)) {
+ mpc_i2c_irq(s);
+ }
+ break;
+ case MPC_I2C_DR:
+ /* if the device is not enabled, nothing to do */
+ if (!mpc_i2c_is_enabled(s)) {
+ break;
+ }
+ s->dr = value & CDR_MASK;
+ if (mpc_i2c_is_master(s)) { /* master mode */
+ if (s->address == CYCLE_RESET) {
+ mpc_i2c_address_send(s);
+ } else {
+ mpc_i2c_data_send(s);
+ }
+ }
+ break;
+ case MPC_I2C_DFSRR:
+ s->dfssr = value;
+ break;
+ default:
+ DPRINTF("ERROR: Bad write addr 0x%x\n", (unsigned int)addr);
+ break;
+ }
+}
+
+static const MemoryRegionOps i2c_ops = {
+ .read = mpc_i2c_read,
+ .write = mpc_i2c_write,
+ .valid.max_access_size = 1,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const VMStateDescription mpc_i2c_vmstate = {
+ .name = TYPE_MPC_I2C,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(address, MPCI2CState),
+ VMSTATE_UINT8(adr, MPCI2CState),
+ VMSTATE_UINT8(fdr, MPCI2CState),
+ VMSTATE_UINT8(cr, MPCI2CState),
+ VMSTATE_UINT8(sr, MPCI2CState),
+ VMSTATE_UINT8(dr, MPCI2CState),
+ VMSTATE_UINT8(dfssr, MPCI2CState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void mpc_i2c_realize(DeviceState *dev, Error **errp)
+{
+ MPCI2CState *i2c = MPC_I2C(dev);
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &i2c->irq);
+ memory_region_init_io(&i2c->iomem, OBJECT(i2c), &i2c_ops, i2c,
+ "mpc-i2c", 0x14);
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &i2c->iomem);
+ i2c->bus = i2c_init_bus(DEVICE(dev), "i2c");
+}
+
+static void mpc_i2c_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->vmsd = &mpc_i2c_vmstate ;
+ dc->reset = mpc_i2c_reset;
+ dc->realize = mpc_i2c_realize;
+ dc->desc = "MPC I2C Controller";
+}
+
+static const TypeInfo mpc_i2c_type_info = {
+ .name = TYPE_MPC_I2C,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(MPCI2CState),
+ .class_init = mpc_i2c_class_init,
+};
+
+static void mpc_i2c_register_types(void)
+{
+ type_register_static(&mpc_i2c_type_info);
+}
+
+type_init(mpc_i2c_register_types)
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index 8ad707aba0..6eabdf9917 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -2,7 +2,7 @@
* QEMU emulation of AMD IOMMU (AMD-Vi)
*
* Copyright (C) 2011 Eduard - Gabriel Munteanu
- * Copyright (C) 2015 David Kiarie, <davidkiarie4@gmail.com>
+ * Copyright (C) 2015, 2016 David Kiarie Kahurani
*
* 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
diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h
index c52886f3ed..0ff9095f32 100644
--- a/hw/i386/amd_iommu.h
+++ b/hw/i386/amd_iommu.h
@@ -2,7 +2,7 @@
* QEMU emulation of an AMD IOMMU (AMD-Vi)
*
* Copyright (C) 2011 Eduard - Gabriel Munteanu
- * Copyright (C) 2015 David Kiarie, <davidkiarie4@gmail.com>
+ * Copyright (C) 2015, 2016 David Kiarie Kahurani
*
* 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
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 71385cfac9..1cdaff5f4d 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -136,6 +136,7 @@ GlobalProperty pc_compat_3_1[] = {
{ "Icelake-Client" "-" TYPE_X86_CPU, "mpx", "on" },
{ "Icelake-Server" "-" TYPE_X86_CPU, "mpx", "on" },
{ "Cascadelake-Server" "-" TYPE_X86_CPU, "stepping", "5" },
+ { TYPE_X86_CPU, "x-intel-pt-auto-level", "off" },
};
const size_t pc_compat_3_1_len = G_N_ELEMENTS(pc_compat_3_1);
@@ -1210,6 +1211,17 @@ static void load_linux(PCMachineState *pcms,
protocol = lduw_p(header+0x206);
} else {
/*
+ * This could be a multiboot kernel. If it is, let's stop treating it
+ * like a Linux kernel.
+ * Note: some multiboot images could be in the ELF format (the same of
+ * PVH), so we try multiboot first since we check the multiboot magic
+ * header before to load it.
+ */
+ if (load_multiboot(fw_cfg, f, kernel_filename, initrd_filename,
+ kernel_cmdline, kernel_size, header)) {
+ return;
+ }
+ /*
* Check if the file is an uncompressed kernel file (ELF) and load it,
* saving the PVH entry point used by the x86/HVM direct boot ABI.
* If load_elfboot() is successful, populate the fw_cfg info.
@@ -1262,12 +1274,6 @@ static void load_linux(PCMachineState *pcms,
return;
}
- /* This looks like a multiboot kernel. If it is, let's stop
- treating it like a Linux kernel. */
- if (load_multiboot(fw_cfg, f, kernel_filename, initrd_filename,
- kernel_cmdline, kernel_size, header)) {
- return;
- }
protocol = 0;
}
@@ -1803,7 +1809,7 @@ void pc_memory_init(PCMachineState *pcms,
}
/* Initialize PC system firmware */
- pc_system_firmware_init(rom_memory, !pcmc->pci_enabled);
+ pc_system_firmware_init(pcms, rom_memory);
option_rom_mr = g_malloc(sizeof(*option_rom_mr));
memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE,
@@ -2602,6 +2608,8 @@ static void pc_machine_initfn(Object *obj)
pcms->smbus_enabled = true;
pcms->sata_enabled = true;
pcms->pit_enabled = true;
+
+ pc_system_flash_create(pcms);
}
static void pc_machine_reset(void)
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 091e22dd60..c628540774 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -40,10 +40,16 @@
#define BIOS_FILENAME "bios.bin"
-typedef struct PcSysFwDevice {
- SysBusDevice busdev;
- uint8_t isapc_ram_fw;
-} PcSysFwDevice;
+/*
+ * We don't have a theoretically justifiable exact lower bound on the base
+ * address of any flash mapping. In practice, the IO-APIC MMIO range is
+ * [0xFEE00000..0xFEE01000] -- see IO_APIC_DEFAULT_ADDRESS --, leaving free
+ * only 18MB-4KB below 4G. For now, restrict the cumulative mapping to 8MB in
+ * size.
+ */
+#define FLASH_SIZE_LIMIT (8 * MiB)
+
+#define FLASH_SECTOR_SIZE 4096
static void pc_isa_bios_init(MemoryRegion *rom_memory,
MemoryRegion *flash_mem,
@@ -76,100 +82,118 @@ static void pc_isa_bios_init(MemoryRegion *rom_memory,
memory_region_set_readonly(isa_bios, true);
}
-#define FLASH_MAP_UNIT_MAX 2
+static PFlashCFI01 *pc_pflash_create(PCMachineState *pcms,
+ const char *name,
+ const char *alias_prop_name)
+{
+ DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
-/* We don't have a theoretically justifiable exact lower bound on the base
- * address of any flash mapping. In practice, the IO-APIC MMIO range is
- * [0xFEE00000..0xFEE01000[ -- see IO_APIC_DEFAULT_ADDRESS --, leaving free
- * only 18MB-4KB below 4G. For now, restrict the cumulative mapping to 8MB in
- * size.
- */
-#define FLASH_MAP_BASE_MIN ((hwaddr)(4 * GiB - 8 * MiB))
+ qdev_prop_set_uint64(dev, "sector-length", FLASH_SECTOR_SIZE);
+ qdev_prop_set_uint8(dev, "width", 1);
+ qdev_prop_set_string(dev, "name", name);
+ object_property_add_child(OBJECT(pcms), name, OBJECT(dev),
+ &error_abort);
+ object_property_add_alias(OBJECT(pcms), alias_prop_name,
+ OBJECT(dev), "drive", &error_abort);
+ return PFLASH_CFI01(dev);
+}
-/* This function maps flash drives from 4G downward, in order of their unit
- * numbers. The mapping starts at unit#0, with unit number increments of 1, and
- * stops before the first missing flash drive, or before
- * unit#FLASH_MAP_UNIT_MAX, whichever is reached first.
- *
- * Addressing within one flash drive is of course not reversed.
- *
- * An error message is printed and the process exits if:
- * - the size of the backing file for a flash drive is non-positive, or not a
- * multiple of the required sector size, or
- * - the current mapping's base address would fall below FLASH_MAP_BASE_MIN.
+void pc_system_flash_create(PCMachineState *pcms)
+{
+ PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
+
+ if (pcmc->pci_enabled) {
+ pcms->flash[0] = pc_pflash_create(pcms, "system.flash0",
+ "pflash0");
+ pcms->flash[1] = pc_pflash_create(pcms, "system.flash1",
+ "pflash1");
+ }
+}
+
+static void pc_system_flash_cleanup_unused(PCMachineState *pcms)
+{
+ char *prop_name;
+ int i;
+ Object *dev_obj;
+
+ assert(PC_MACHINE_GET_CLASS(pcms)->pci_enabled);
+
+ for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) {
+ dev_obj = OBJECT(pcms->flash[i]);
+ if (!object_property_get_bool(dev_obj, "realized", &error_abort)) {
+ prop_name = g_strdup_printf("pflash%d", i);
+ object_property_del(OBJECT(pcms), prop_name, &error_abort);
+ g_free(prop_name);
+ object_unparent(dev_obj);
+ pcms->flash[i] = NULL;
+ }
+ }
+}
+
+/*
+ * Map the pcms->flash[] from 4GiB downward, and realize.
+ * Map them in descending order, i.e. pcms->flash[0] at the top,
+ * without gaps.
+ * Stop at the first pcms->flash[0] lacking a block backend.
+ * Set each flash's size from its block backend. Fatal error if the
+ * size isn't a non-zero multiple of 4KiB, or the total size exceeds
+ * FLASH_SIZE_LIMIT.
*
- * The drive with unit#0 (if available) is mapped at the highest address, and
- * it is passed to pc_isa_bios_init(). Merging several drives for isa-bios is
+ * If pcms->flash[0] has a block backend, its memory is passed to
+ * pc_isa_bios_init(). Merging several flash devices for isa-bios is
* not supported.
*/
-static void pc_system_flash_init(MemoryRegion *rom_memory)
+static void pc_system_flash_map(PCMachineState *pcms,
+ MemoryRegion *rom_memory)
{
- int unit;
- DriveInfo *pflash_drv;
+ hwaddr total_size = 0;
+ int i;
BlockBackend *blk;
int64_t size;
- char *fatal_errmsg = NULL;
- hwaddr phys_addr = 0x100000000ULL;
- int sector_bits, sector_size;
- pflash_t *system_flash;
+ PFlashCFI01 *system_flash;
MemoryRegion *flash_mem;
- char name[64];
void *flash_ptr;
int ret, flash_size;
- sector_bits = 12;
- sector_size = 1 << sector_bits;
+ assert(PC_MACHINE_GET_CLASS(pcms)->pci_enabled);
- for (unit = 0;
- (unit < FLASH_MAP_UNIT_MAX &&
- (pflash_drv = drive_get(IF_PFLASH, 0, unit)) != NULL);
- ++unit) {
- blk = blk_by_legacy_dinfo(pflash_drv);
+ for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) {
+ system_flash = pcms->flash[i];
+ blk = pflash_cfi01_get_blk(system_flash);
+ if (!blk) {
+ break;
+ }
size = blk_getlength(blk);
if (size < 0) {
- fatal_errmsg = g_strdup_printf("failed to get backing file size");
- } else if (size == 0) {
- fatal_errmsg = g_strdup_printf("PC system firmware (pflash) "
- "cannot have zero size");
- } else if ((size % sector_size) != 0) {
- fatal_errmsg = g_strdup_printf("PC system firmware (pflash) "
- "must be a multiple of 0x%x", sector_size);
- } else if (phys_addr < size || phys_addr - size < FLASH_MAP_BASE_MIN) {
- fatal_errmsg = g_strdup_printf("oversized backing file, pflash "
- "segments cannot be mapped under "
- TARGET_FMT_plx, FLASH_MAP_BASE_MIN);
+ error_report("can't get size of block device %s: %s",
+ blk_name(blk), strerror(-size));
+ exit(1);
}
- if (fatal_errmsg != NULL) {
- Location loc;
-
- /* push a new, "none" location on the location stack; overwrite its
- * contents with the location saved in the option; print the error
- * (includes location); pop the top
- */
- loc_push_none(&loc);
- if (pflash_drv->opts != NULL) {
- qemu_opts_loc_restore(pflash_drv->opts);
- }
- error_report("%s", fatal_errmsg);
- loc_pop(&loc);
- g_free(fatal_errmsg);
+ if (size == 0 || size % FLASH_SECTOR_SIZE != 0) {
+ error_report("system firmware block device %s has invalid size "
+ "%" PRId64,
+ blk_name(blk), size);
+ info_report("its size must be a non-zero multiple of 0x%x",
+ FLASH_SECTOR_SIZE);
exit(1);
}
+ if ((hwaddr)size != size
+ || total_size > HWADDR_MAX - size
+ || total_size + size > FLASH_SIZE_LIMIT) {
+ error_report("combined size of system firmware exceeds "
+ "%" PRIu64 " bytes",
+ FLASH_SIZE_LIMIT);
+ exit(1);
+ }
+
+ total_size += size;
+ qdev_prop_set_uint32(DEVICE(system_flash), "num-blocks",
+ size / FLASH_SECTOR_SIZE);
+ qdev_init_nofail(DEVICE(system_flash));
+ sysbus_mmio_map(SYS_BUS_DEVICE(system_flash), 0,
+ 0x100000000ULL - total_size);
- phys_addr -= size;
-
- /* pflash_cfi01_register() creates a deep copy of the name */
- snprintf(name, sizeof name, "system.flash%d", unit);
- system_flash = pflash_cfi01_register(phys_addr, NULL /* qdev */, name,
- size, blk, sector_size,
- size >> sector_bits,
- 1 /* width */,
- 0x0000 /* id0 */,
- 0x0000 /* id1 */,
- 0x0000 /* id2 */,
- 0x0000 /* id3 */,
- 0 /* be */);
- if (unit == 0) {
+ if (i == 0) {
flash_mem = pflash_cfi01_get_memory(system_flash);
pc_isa_bios_init(rom_memory, flash_mem, size);
@@ -240,24 +264,63 @@ static void old_pc_system_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
bios);
}
-void pc_system_firmware_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
+void pc_system_firmware_init(PCMachineState *pcms,
+ MemoryRegion *rom_memory)
{
+ PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
+ int i;
DriveInfo *pflash_drv;
+ BlockBackend *pflash_blk[ARRAY_SIZE(pcms->flash)];
+ Location loc;
- pflash_drv = drive_get(IF_PFLASH, 0, 0);
-
- if (isapc_ram_fw || pflash_drv == NULL) {
- /* When a pflash drive is not found, use rom-mode */
- old_pc_system_rom_init(rom_memory, isapc_ram_fw);
+ if (!pcmc->pci_enabled) {
+ old_pc_system_rom_init(rom_memory, true);
return;
}
- if (kvm_enabled() && !kvm_readonly_mem_enabled()) {
- /* Older KVM cannot execute from device memory. So, flash memory
- * cannot be used unless the readonly memory kvm capability is present. */
- fprintf(stderr, "qemu: pflash with kvm requires KVM readonly memory support\n");
- exit(1);
+ /* Map legacy -drive if=pflash to machine properties */
+ for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) {
+ pflash_blk[i] = pflash_cfi01_get_blk(pcms->flash[i]);
+ pflash_drv = drive_get(IF_PFLASH, 0, i);
+ if (!pflash_drv) {
+ continue;
+ }
+ loc_push_none(&loc);
+ qemu_opts_loc_restore(pflash_drv->opts);
+ if (pflash_blk[i]) {
+ error_report("clashes with -machine");
+ exit(1);
+ }
+ pflash_blk[i] = blk_by_legacy_dinfo(pflash_drv);
+ qdev_prop_set_drive(DEVICE(pcms->flash[i]),
+ "drive", pflash_blk[i], &error_fatal);
+ loc_pop(&loc);
+ }
+
+ /* Reject gaps */
+ for (i = 1; i < ARRAY_SIZE(pcms->flash); i++) {
+ if (pflash_blk[i] && !pflash_blk[i - 1]) {
+ error_report("pflash%d requires pflash%d", i, i - 1);
+ exit(1);
+ }
+ }
+
+ if (!pflash_blk[0]) {
+ /* Machine property pflash0 not set, use ROM mode */
+ old_pc_system_rom_init(rom_memory, false);
+ } else {
+ if (kvm_enabled() && !kvm_readonly_mem_enabled()) {
+ /*
+ * Older KVM cannot execute from device memory. So, flash
+ * memory cannot be used unless the readonly memory kvm
+ * capability is present.
+ */
+ error_report("pflash with kvm requires KVM readonly memory support");
+ exit(1);
+ }
+
+ pc_system_flash_map(pcms, rom_memory);
}
- pc_system_flash_init(rom_memory);
+ pc_system_flash_cleanup_unused(pcms);
}
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 301a8e972d..df712c3e6c 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -39,7 +39,7 @@ obj-$(CONFIG_XICS_SPAPR) += xics_spapr.o
obj-$(CONFIG_XICS_KVM) += xics_kvm.o
obj-$(CONFIG_XIVE) += xive.o
obj-$(CONFIG_XIVE_SPAPR) += spapr_xive.o
-obj-$(CONFIG_POWERNV) += xics_pnv.o
+obj-$(CONFIG_POWERNV) += xics_pnv.o pnv_xive.o
obj-$(CONFIG_ALLWINNER_A10_PIC) += allwinner-a10-pic.o
obj-$(CONFIG_S390_FLIC) += s390_flic.o
obj-$(CONFIG_S390_FLIC_KVM) += s390_flic_kvm.o
diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
new file mode 100644
index 0000000000..bb0877cbdf
--- /dev/null
+++ b/hw/intc/pnv_xive.c
@@ -0,0 +1,1753 @@
+/*
+ * QEMU PowerPC XIVE interrupt controller model
+ *
+ * Copyright (c) 2017-2019, IBM Corporation.
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "target/ppc/cpu.h"
+#include "sysemu/cpus.h"
+#include "sysemu/dma.h"
+#include "monitor/monitor.h"
+#include "hw/ppc/fdt.h"
+#include "hw/ppc/pnv.h"
+#include "hw/ppc/pnv_core.h"
+#include "hw/ppc/pnv_xscom.h"
+#include "hw/ppc/pnv_xive.h"
+#include "hw/ppc/xive_regs.h"
+#include "hw/ppc/ppc.h"
+
+#include <libfdt.h>
+
+#include "pnv_xive_regs.h"
+
+#define XIVE_DEBUG
+
+/*
+ * Virtual structures table (VST)
+ */
+#define SBE_PER_BYTE 4
+
+typedef struct XiveVstInfo {
+ const char *name;
+ uint32_t size;
+ uint32_t max_blocks;
+} XiveVstInfo;
+
+static const XiveVstInfo vst_infos[] = {
+ [VST_TSEL_IVT] = { "EAT", sizeof(XiveEAS), 16 },
+ [VST_TSEL_SBE] = { "SBE", 1, 16 },
+ [VST_TSEL_EQDT] = { "ENDT", sizeof(XiveEND), 16 },
+ [VST_TSEL_VPDT] = { "VPDT", sizeof(XiveNVT), 32 },
+
+ /*
+ * Interrupt fifo backing store table (not modeled) :
+ *
+ * 0 - IPI,
+ * 1 - HWD,
+ * 2 - First escalate,
+ * 3 - Second escalate,
+ * 4 - Redistribution,
+ * 5 - IPI cascaded queue ?
+ */
+ [VST_TSEL_IRQ] = { "IRQ", 1, 6 },
+};
+
+#define xive_error(xive, fmt, ...) \
+ qemu_log_mask(LOG_GUEST_ERROR, "XIVE[%x] - " fmt "\n", \
+ (xive)->chip->chip_id, ## __VA_ARGS__);
+
+/*
+ * QEMU version of the GETFIELD/SETFIELD macros
+ *
+ * TODO: It might be better to use the existing extract64() and
+ * deposit64() but this means that all the register definitions will
+ * change and become incompatible with the ones found in skiboot.
+ *
+ * Keep it as it is for now until we find a common ground.
+ */
+static inline uint64_t GETFIELD(uint64_t mask, uint64_t word)
+{
+ return (word & mask) >> ctz64(mask);
+}
+
+static inline uint64_t SETFIELD(uint64_t mask, uint64_t word,
+ uint64_t value)
+{
+ return (word & ~mask) | ((value << ctz64(mask)) & mask);
+}
+
+/*
+ * Remote access to controllers. HW uses MMIOs. For now, a simple scan
+ * of the chips is good enough.
+ *
+ * TODO: Block scope support
+ */
+static PnvXive *pnv_xive_get_ic(uint8_t blk)
+{
+ PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
+ int i;
+
+ for (i = 0; i < pnv->num_chips; i++) {
+ Pnv9Chip *chip9 = PNV9_CHIP(pnv->chips[i]);
+ PnvXive *xive = &chip9->xive;
+
+ if (xive->chip->chip_id == blk) {
+ return xive;
+ }
+ }
+ return NULL;
+}
+
+/*
+ * VST accessors for SBE, EAT, ENDT, NVT
+ *
+ * Indirect VST tables are arrays of VSDs pointing to a page (of same
+ * size). Each page is a direct VST table.
+ */
+
+#define XIVE_VSD_SIZE 8
+
+/* Indirect page size can be 4K, 64K, 2M, 16M. */
+static uint64_t pnv_xive_vst_page_size_allowed(uint32_t page_shift)
+{
+ return page_shift == 12 || page_shift == 16 ||
+ page_shift == 21 || page_shift == 24;
+}
+
+static uint64_t pnv_xive_vst_size(uint64_t vsd)
+{
+ uint64_t vst_tsize = 1ull << (GETFIELD(VSD_TSIZE, vsd) + 12);
+
+ /*
+ * Read the first descriptor to get the page size of the indirect
+ * table.
+ */
+ if (VSD_INDIRECT & vsd) {
+ uint32_t nr_pages = vst_tsize / XIVE_VSD_SIZE;
+ uint32_t page_shift;
+
+ vsd = ldq_be_dma(&address_space_memory, vsd & VSD_ADDRESS_MASK);
+ page_shift = GETFIELD(VSD_TSIZE, vsd) + 12;
+
+ if (!pnv_xive_vst_page_size_allowed(page_shift)) {
+ return 0;
+ }
+
+ return nr_pages * (1ull << page_shift);
+ }
+
+ return vst_tsize;
+}
+
+static uint64_t pnv_xive_vst_addr_direct(PnvXive *xive, uint32_t type,
+ uint64_t vsd, uint32_t idx)
+{
+ const XiveVstInfo *info = &vst_infos[type];
+ uint64_t vst_addr = vsd & VSD_ADDRESS_MASK;
+
+ return vst_addr + idx * info->size;
+}
+
+static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, uint32_t type,
+ uint64_t vsd, uint32_t idx)
+{
+ const XiveVstInfo *info = &vst_infos[type];
+ uint64_t vsd_addr;
+ uint32_t vsd_idx;
+ uint32_t page_shift;
+ uint32_t vst_per_page;
+
+ /* Get the page size of the indirect table. */
+ vsd_addr = vsd & VSD_ADDRESS_MASK;
+ vsd = ldq_be_dma(&address_space_memory, vsd_addr);
+
+ if (!(vsd & VSD_ADDRESS_MASK)) {
+ xive_error(xive, "VST: invalid %s entry %x !?", info->name, 0);
+ return 0;
+ }
+
+ page_shift = GETFIELD(VSD_TSIZE, vsd) + 12;
+
+ if (!pnv_xive_vst_page_size_allowed(page_shift)) {
+ xive_error(xive, "VST: invalid %s page shift %d", info->name,
+ page_shift);
+ return 0;
+ }
+
+ vst_per_page = (1ull << page_shift) / info->size;
+ vsd_idx = idx / vst_per_page;
+
+ /* Load the VSD we are looking for, if not already done */
+ if (vsd_idx) {
+ vsd_addr = vsd_addr + vsd_idx * XIVE_VSD_SIZE;
+ vsd = ldq_be_dma(&address_space_memory, vsd_addr);
+
+ if (!(vsd & VSD_ADDRESS_MASK)) {
+ xive_error(xive, "VST: invalid %s entry %x !?", info->name, 0);
+ return 0;
+ }
+
+ /*
+ * Check that the pages have a consistent size across the
+ * indirect table
+ */
+ if (page_shift != GETFIELD(VSD_TSIZE, vsd) + 12) {
+ xive_error(xive, "VST: %s entry %x indirect page size differ !?",
+ info->name, idx);
+ return 0;
+ }
+ }
+
+ return pnv_xive_vst_addr_direct(xive, type, vsd, (idx % vst_per_page));
+}
+
+static uint64_t pnv_xive_vst_addr(PnvXive *xive, uint32_t type, uint8_t blk,
+ uint32_t idx)
+{
+ const XiveVstInfo *info = &vst_infos[type];
+ uint64_t vsd;
+ uint32_t idx_max;
+
+ if (blk >= info->max_blocks) {
+ xive_error(xive, "VST: invalid block id %d for VST %s %d !?",
+ blk, info->name, idx);
+ return 0;
+ }
+
+ vsd = xive->vsds[type][blk];
+
+ /* Remote VST access */
+ if (GETFIELD(VSD_MODE, vsd) == VSD_MODE_FORWARD) {
+ xive = pnv_xive_get_ic(blk);
+
+ return xive ? pnv_xive_vst_addr(xive, type, blk, idx) : 0;
+ }
+
+ idx_max = pnv_xive_vst_size(vsd) / info->size - 1;
+ if (idx > idx_max) {
+#ifdef XIVE_DEBUG
+ xive_error(xive, "VST: %s entry %x/%x out of range [ 0 .. %x ] !?",
+ info->name, blk, idx, idx_max);
+#endif
+ return 0;
+ }
+
+ if (VSD_INDIRECT & vsd) {
+ return pnv_xive_vst_addr_indirect(xive, type, vsd, idx);
+ }
+
+ return pnv_xive_vst_addr_direct(xive, type, vsd, idx);
+}
+
+static int pnv_xive_vst_read(PnvXive *xive, uint32_t type, uint8_t blk,
+ uint32_t idx, void *data)
+{
+ const XiveVstInfo *info = &vst_infos[type];
+ uint64_t addr = pnv_xive_vst_addr(xive, type, blk, idx);
+
+ if (!addr) {
+ return -1;
+ }
+
+ cpu_physical_memory_read(addr, data, info->size);
+ return 0;
+}
+
+#define XIVE_VST_WORD_ALL -1
+
+static int pnv_xive_vst_write(PnvXive *xive, uint32_t type, uint8_t blk,
+ uint32_t idx, void *data, uint32_t word_number)
+{
+ const XiveVstInfo *info = &vst_infos[type];
+ uint64_t addr = pnv_xive_vst_addr(xive, type, blk, idx);
+
+ if (!addr) {
+ return -1;
+ }
+
+ if (word_number == XIVE_VST_WORD_ALL) {
+ cpu_physical_memory_write(addr, data, info->size);
+ } else {
+ cpu_physical_memory_write(addr + word_number * 4,
+ data + word_number * 4, 4);
+ }
+ return 0;
+}
+
+static int pnv_xive_get_end(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
+ XiveEND *end)
+{
+ return pnv_xive_vst_read(PNV_XIVE(xrtr), VST_TSEL_EQDT, blk, idx, end);
+}
+
+static int pnv_xive_write_end(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
+ XiveEND *end, uint8_t word_number)
+{
+ return pnv_xive_vst_write(PNV_XIVE(xrtr), VST_TSEL_EQDT, blk, idx, end,
+ word_number);
+}
+
+static int pnv_xive_end_update(PnvXive *xive, uint8_t blk, uint32_t idx)
+{
+ int i;
+ uint64_t eqc_watch[4];
+
+ for (i = 0; i < ARRAY_SIZE(eqc_watch); i++) {
+ eqc_watch[i] = cpu_to_be64(xive->regs[(VC_EQC_CWATCH_DAT0 >> 3) + i]);
+ }
+
+ return pnv_xive_vst_write(xive, VST_TSEL_EQDT, blk, idx, eqc_watch,
+ XIVE_VST_WORD_ALL);
+}
+
+static int pnv_xive_get_nvt(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
+ XiveNVT *nvt)
+{
+ return pnv_xive_vst_read(PNV_XIVE(xrtr), VST_TSEL_VPDT, blk, idx, nvt);
+}
+
+static int pnv_xive_write_nvt(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
+ XiveNVT *nvt, uint8_t word_number)
+{
+ return pnv_xive_vst_write(PNV_XIVE(xrtr), VST_TSEL_VPDT, blk, idx, nvt,
+ word_number);
+}
+
+static int pnv_xive_nvt_update(PnvXive *xive, uint8_t blk, uint32_t idx)
+{
+ int i;
+ uint64_t vpc_watch[8];
+
+ for (i = 0; i < ARRAY_SIZE(vpc_watch); i++) {
+ vpc_watch[i] = cpu_to_be64(xive->regs[(PC_VPC_CWATCH_DAT0 >> 3) + i]);
+ }
+
+ return pnv_xive_vst_write(xive, VST_TSEL_VPDT, blk, idx, vpc_watch,
+ XIVE_VST_WORD_ALL);
+}
+
+static int pnv_xive_get_eas(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
+ XiveEAS *eas)
+{
+ PnvXive *xive = PNV_XIVE(xrtr);
+
+ if (pnv_xive_get_ic(blk) != xive) {
+ xive_error(xive, "VST: EAS %x is remote !?", XIVE_SRCNO(blk, idx));
+ return -1;
+ }
+
+ return pnv_xive_vst_read(xive, VST_TSEL_IVT, blk, idx, eas);
+}
+
+static int pnv_xive_eas_update(PnvXive *xive, uint8_t blk, uint32_t idx)
+{
+ /* All done. */
+ return 0;
+}
+
+static XiveTCTX *pnv_xive_get_tctx(XiveRouter *xrtr, CPUState *cs)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ XiveTCTX *tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
+ PnvXive *xive = NULL;
+ CPUPPCState *env = &cpu->env;
+ int pir = env->spr_cb[SPR_PIR].default_value;
+
+ /*
+ * Perform an extra check on the HW thread enablement.
+ *
+ * The TIMA is shared among the chips and to identify the chip
+ * from which the access is being done, we extract the chip id
+ * from the PIR.
+ */
+ xive = pnv_xive_get_ic((pir >> 8) & 0xf);
+ if (!xive) {
+ return NULL;
+ }
+
+ if (!(xive->regs[PC_THREAD_EN_REG0 >> 3] & PPC_BIT(pir & 0x3f))) {
+ xive_error(PNV_XIVE(xrtr), "IC: CPU %x is not enabled", pir);
+ }
+
+ return tctx;
+}
+
+/*
+ * The internal sources (IPIs) of the interrupt controller have no
+ * knowledge of the XIVE chip on which they reside. Encode the block
+ * id in the source interrupt number before forwarding the source
+ * event notification to the Router. This is required on a multichip
+ * system.
+ */
+static void pnv_xive_notify(XiveNotifier *xn, uint32_t srcno)
+{
+ PnvXive *xive = PNV_XIVE(xn);
+ uint8_t blk = xive->chip->chip_id;
+
+ xive_router_notify(xn, XIVE_SRCNO(blk, srcno));
+}
+
+/*
+ * XIVE helpers
+ */
+
+static uint64_t pnv_xive_vc_size(PnvXive *xive)
+{
+ return (~xive->regs[CQ_VC_BARM >> 3] + 1) & CQ_VC_BARM_MASK;
+}
+
+static uint64_t pnv_xive_edt_shift(PnvXive *xive)
+{
+ return ctz64(pnv_xive_vc_size(xive) / XIVE_TABLE_EDT_MAX);
+}
+
+static uint64_t pnv_xive_pc_size(PnvXive *xive)
+{
+ return (~xive->regs[CQ_PC_BARM >> 3] + 1) & CQ_PC_BARM_MASK;
+}
+
+static uint32_t pnv_xive_nr_ipis(PnvXive *xive)
+{
+ uint8_t blk = xive->chip->chip_id;
+
+ return pnv_xive_vst_size(xive->vsds[VST_TSEL_SBE][blk]) * SBE_PER_BYTE;
+}
+
+static uint32_t pnv_xive_nr_ends(PnvXive *xive)
+{
+ uint8_t blk = xive->chip->chip_id;
+
+ return pnv_xive_vst_size(xive->vsds[VST_TSEL_EQDT][blk])
+ / vst_infos[VST_TSEL_EQDT].size;
+}
+
+/*
+ * EDT Table
+ *
+ * The Virtualization Controller MMIO region containing the IPI ESB
+ * pages and END ESB pages is sub-divided into "sets" which map
+ * portions of the VC region to the different ESB pages. It is
+ * configured at runtime through the EDT "Domain Table" to let the
+ * firmware decide how to split the VC address space between IPI ESB
+ * pages and END ESB pages.
+ */
+
+/*
+ * Computes the overall size of the IPI or the END ESB pages
+ */
+static uint64_t pnv_xive_edt_size(PnvXive *xive, uint64_t type)
+{
+ uint64_t edt_size = 1ull << pnv_xive_edt_shift(xive);
+ uint64_t size = 0;
+ int i;
+
+ for (i = 0; i < XIVE_TABLE_EDT_MAX; i++) {
+ uint64_t edt_type = GETFIELD(CQ_TDR_EDT_TYPE, xive->edt[i]);
+
+ if (edt_type == type) {
+ size += edt_size;
+ }
+ }
+
+ return size;
+}
+
+/*
+ * Maps an offset of the VC region in the IPI or END region using the
+ * layout defined by the EDT "Domaine Table"
+ */
+static uint64_t pnv_xive_edt_offset(PnvXive *xive, uint64_t vc_offset,
+ uint64_t type)
+{
+ int i;
+ uint64_t edt_size = 1ull << pnv_xive_edt_shift(xive);
+ uint64_t edt_offset = vc_offset;
+
+ for (i = 0; i < XIVE_TABLE_EDT_MAX && (i * edt_size) < vc_offset; i++) {
+ uint64_t edt_type = GETFIELD(CQ_TDR_EDT_TYPE, xive->edt[i]);
+
+ if (edt_type != type) {
+ edt_offset -= edt_size;
+ }
+ }
+
+ return edt_offset;
+}
+
+static void pnv_xive_edt_resize(PnvXive *xive)
+{
+ uint64_t ipi_edt_size = pnv_xive_edt_size(xive, CQ_TDR_EDT_IPI);
+ uint64_t end_edt_size = pnv_xive_edt_size(xive, CQ_TDR_EDT_EQ);
+
+ memory_region_set_size(&xive->ipi_edt_mmio, ipi_edt_size);
+ memory_region_add_subregion(&xive->ipi_mmio, 0, &xive->ipi_edt_mmio);
+
+ memory_region_set_size(&xive->end_edt_mmio, end_edt_size);
+ memory_region_add_subregion(&xive->end_mmio, 0, &xive->end_edt_mmio);
+}
+
+/*
+ * XIVE Table configuration. Only EDT is supported.
+ */
+static int pnv_xive_table_set_data(PnvXive *xive, uint64_t val)
+{
+ uint64_t tsel = xive->regs[CQ_TAR >> 3] & CQ_TAR_TSEL;
+ uint8_t tsel_index = GETFIELD(CQ_TAR_TSEL_INDEX, xive->regs[CQ_TAR >> 3]);
+ uint64_t *xive_table;
+ uint8_t max_index;
+
+ switch (tsel) {
+ case CQ_TAR_TSEL_BLK:
+ max_index = ARRAY_SIZE(xive->blk);
+ xive_table = xive->blk;
+ break;
+ case CQ_TAR_TSEL_MIG:
+ max_index = ARRAY_SIZE(xive->mig);
+ xive_table = xive->mig;
+ break;
+ case CQ_TAR_TSEL_EDT:
+ max_index = ARRAY_SIZE(xive->edt);
+ xive_table = xive->edt;
+ break;
+ case CQ_TAR_TSEL_VDT:
+ max_index = ARRAY_SIZE(xive->vdt);
+ xive_table = xive->vdt;
+ break;
+ default:
+ xive_error(xive, "IC: invalid table %d", (int) tsel);
+ return -1;
+ }
+
+ if (tsel_index >= max_index) {
+ xive_error(xive, "IC: invalid index %d", (int) tsel_index);
+ return -1;
+ }
+
+ xive_table[tsel_index] = val;
+
+ if (xive->regs[CQ_TAR >> 3] & CQ_TAR_TBL_AUTOINC) {
+ xive->regs[CQ_TAR >> 3] =
+ SETFIELD(CQ_TAR_TSEL_INDEX, xive->regs[CQ_TAR >> 3], ++tsel_index);
+ }
+
+ /*
+ * EDT configuration is complete. Resize the MMIO windows exposing
+ * the IPI and the END ESBs in the VC region.
+ */
+ if (tsel == CQ_TAR_TSEL_EDT && tsel_index == ARRAY_SIZE(xive->edt)) {
+ pnv_xive_edt_resize(xive);
+ }
+
+ return 0;
+}
+
+/*
+ * Virtual Structure Tables (VST) configuration
+ */
+static void pnv_xive_vst_set_exclusive(PnvXive *xive, uint8_t type,
+ uint8_t blk, uint64_t vsd)
+{
+ XiveENDSource *end_xsrc = &xive->end_source;
+ XiveSource *xsrc = &xive->ipi_source;
+ const XiveVstInfo *info = &vst_infos[type];
+ uint32_t page_shift = GETFIELD(VSD_TSIZE, vsd) + 12;
+ uint64_t vst_addr = vsd & VSD_ADDRESS_MASK;
+
+ /* Basic checks */
+
+ if (VSD_INDIRECT & vsd) {
+ if (!(xive->regs[VC_GLOBAL_CONFIG >> 3] & VC_GCONF_INDIRECT)) {
+ xive_error(xive, "VST: %s indirect tables are not enabled",
+ info->name);
+ return;
+ }
+
+ if (!pnv_xive_vst_page_size_allowed(page_shift)) {
+ xive_error(xive, "VST: invalid %s page shift %d", info->name,
+ page_shift);
+ return;
+ }
+ }
+
+ if (!QEMU_IS_ALIGNED(vst_addr, 1ull << page_shift)) {
+ xive_error(xive, "VST: %s table address 0x%"PRIx64" is not aligned with"
+ " page shift %d", info->name, vst_addr, page_shift);
+ return;
+ }
+
+ /* Record the table configuration (in SRAM on HW) */
+ xive->vsds[type][blk] = vsd;
+
+ /* Now tune the models with the configuration provided by the FW */
+
+ switch (type) {
+ case VST_TSEL_IVT: /* Nothing to be done */
+ break;
+
+ case VST_TSEL_EQDT:
+ /*
+ * Backing store pages for the END. Compute the number of ENDs
+ * provisioned by FW and resize the END ESB window accordingly.
+ */
+ memory_region_set_size(&end_xsrc->esb_mmio, pnv_xive_nr_ends(xive) *
+ (1ull << (end_xsrc->esb_shift + 1)));
+ memory_region_add_subregion(&xive->end_edt_mmio, 0,
+ &end_xsrc->esb_mmio);
+ break;
+
+ case VST_TSEL_SBE:
+ /*
+ * Backing store pages for the source PQ bits. The model does
+ * not use these PQ bits backed in RAM because the XiveSource
+ * model has its own. Compute the number of IRQs provisioned
+ * by FW and resize the IPI ESB window accordingly.
+ */
+ memory_region_set_size(&xsrc->esb_mmio, pnv_xive_nr_ipis(xive) *
+ (1ull << xsrc->esb_shift));
+ memory_region_add_subregion(&xive->ipi_edt_mmio, 0, &xsrc->esb_mmio);
+ break;
+
+ case VST_TSEL_VPDT: /* Not modeled */
+ case VST_TSEL_IRQ: /* Not modeled */
+ /*
+ * These tables contains the backing store pages for the
+ * interrupt fifos of the VC sub-engine in case of overflow.
+ */
+ break;
+
+ default:
+ g_assert_not_reached();
+ }
+}
+
+/*
+ * Both PC and VC sub-engines are configured as each use the Virtual
+ * Structure Tables : SBE, EAS, END and NVT.
+ */
+static void pnv_xive_vst_set_data(PnvXive *xive, uint64_t vsd, bool pc_engine)
+{
+ uint8_t mode = GETFIELD(VSD_MODE, vsd);
+ uint8_t type = GETFIELD(VST_TABLE_SELECT,
+ xive->regs[VC_VSD_TABLE_ADDR >> 3]);
+ uint8_t blk = GETFIELD(VST_TABLE_BLOCK,
+ xive->regs[VC_VSD_TABLE_ADDR >> 3]);
+ uint64_t vst_addr = vsd & VSD_ADDRESS_MASK;
+
+ if (type > VST_TSEL_IRQ) {
+ xive_error(xive, "VST: invalid table type %d", type);
+ return;
+ }
+
+ if (blk >= vst_infos[type].max_blocks) {
+ xive_error(xive, "VST: invalid block id %d for"
+ " %s table", blk, vst_infos[type].name);
+ return;
+ }
+
+ /*
+ * Only take the VC sub-engine configuration into account because
+ * the XiveRouter model combines both VC and PC sub-engines
+ */
+ if (pc_engine) {
+ return;
+ }
+
+ if (!vst_addr) {
+ xive_error(xive, "VST: invalid %s table address", vst_infos[type].name);
+ return;
+ }
+
+ switch (mode) {
+ case VSD_MODE_FORWARD:
+ xive->vsds[type][blk] = vsd;
+ break;
+
+ case VSD_MODE_EXCLUSIVE:
+ pnv_xive_vst_set_exclusive(xive, type, blk, vsd);
+ break;
+
+ default:
+ xive_error(xive, "VST: unsupported table mode %d", mode);
+ return;
+ }
+}
+
+/*
+ * Interrupt controller MMIO region. The layout is compatible between
+ * 4K and 64K pages :
+ *
+ * Page 0 sub-engine BARs
+ * 0x000 - 0x3FF IC registers
+ * 0x400 - 0x7FF PC registers
+ * 0x800 - 0xFFF VC registers
+ *
+ * Page 1 Notify page (writes only)
+ * 0x000 - 0x7FF HW interrupt triggers (PSI, PHB)
+ * 0x800 - 0xFFF forwards and syncs
+ *
+ * Page 2 LSI Trigger page (writes only) (not modeled)
+ * Page 3 LSI SB EOI page (reads only) (not modeled)
+ *
+ * Page 4-7 indirect TIMA
+ */
+
+/*
+ * IC - registers MMIO
+ */
+static void pnv_xive_ic_reg_write(void *opaque, hwaddr offset,
+ uint64_t val, unsigned size)
+{
+ PnvXive *xive = PNV_XIVE(opaque);
+ MemoryRegion *sysmem = get_system_memory();
+ uint32_t reg = offset >> 3;
+ bool is_chip0 = xive->chip->chip_id == 0;
+
+ switch (offset) {
+
+ /*
+ * XIVE CQ (PowerBus bridge) settings
+ */
+ case CQ_MSGSND: /* msgsnd for doorbells */
+ case CQ_FIRMASK_OR: /* FIR error reporting */
+ break;
+ case CQ_PBI_CTL:
+ if (val & CQ_PBI_PC_64K) {
+ xive->pc_shift = 16;
+ }
+ if (val & CQ_PBI_VC_64K) {
+ xive->vc_shift = 16;
+ }
+ break;
+ case CQ_CFG_PB_GEN: /* PowerBus General Configuration */
+ /*
+ * TODO: CQ_INT_ADDR_OPT for 1-block-per-chip mode
+ */
+ break;
+
+ /*
+ * XIVE Virtualization Controller settings
+ */
+ case VC_GLOBAL_CONFIG:
+ break;
+
+ /*
+ * XIVE Presenter Controller settings
+ */
+ case PC_GLOBAL_CONFIG:
+ /*
+ * PC_GCONF_CHIPID_OVR
+ * Overrides Int command Chip ID with the Chip ID field (DEBUG)
+ */
+ break;
+ case PC_TCTXT_CFG:
+ /*
+ * TODO: block group support
+ *
+ * PC_TCTXT_CFG_BLKGRP_EN
+ * PC_TCTXT_CFG_HARD_CHIPID_BLK :
+ * Moves the chipid into block field for hardwired CAM compares.
+ * Block offset value is adjusted to 0b0..01 & ThrdId
+ *
+ * Will require changes in xive_presenter_tctx_match(). I am
+ * not sure how to handle that yet.
+ */
+
+ /* Overrides hardwired chip ID with the chip ID field */
+ if (val & PC_TCTXT_CHIPID_OVERRIDE) {
+ xive->tctx_chipid = GETFIELD(PC_TCTXT_CHIPID, val);
+ }
+ break;
+ case PC_TCTXT_TRACK:
+ /*
+ * PC_TCTXT_TRACK_EN:
+ * enable block tracking and exchange of block ownership
+ * information between Interrupt controllers
+ */
+ break;
+
+ /*
+ * Misc settings
+ */
+ case VC_SBC_CONFIG: /* Store EOI configuration */
+ /*
+ * Configure store EOI if required by firwmare (skiboot has removed
+ * support recently though)
+ */
+ if (val & (VC_SBC_CONF_CPLX_CIST | VC_SBC_CONF_CIST_BOTH)) {
+ object_property_set_int(OBJECT(&xive->ipi_source),
+ XIVE_SRC_STORE_EOI, "flags", &error_fatal);
+ }
+ break;
+
+ case VC_EQC_CONFIG: /* TODO: silent escalation */
+ case VC_AIB_TX_ORDER_TAG2: /* relax ordering */
+ break;
+
+ /*
+ * XIVE BAR settings (XSCOM only)
+ */
+ case CQ_RST_CTL:
+ /* bit4: resets all BAR registers */
+ break;
+
+ case CQ_IC_BAR: /* IC BAR. 8 pages */
+ xive->ic_shift = val & CQ_IC_BAR_64K ? 16 : 12;
+ if (!(val & CQ_IC_BAR_VALID)) {
+ xive->ic_base = 0;
+ if (xive->regs[reg] & CQ_IC_BAR_VALID) {
+ memory_region_del_subregion(&xive->ic_mmio,
+ &xive->ic_reg_mmio);
+ memory_region_del_subregion(&xive->ic_mmio,
+ &xive->ic_notify_mmio);
+ memory_region_del_subregion(&xive->ic_mmio,
+ &xive->ic_lsi_mmio);
+ memory_region_del_subregion(&xive->ic_mmio,
+ &xive->tm_indirect_mmio);
+
+ memory_region_del_subregion(sysmem, &xive->ic_mmio);
+ }
+ } else {
+ xive->ic_base = val & ~(CQ_IC_BAR_VALID | CQ_IC_BAR_64K);
+ if (!(xive->regs[reg] & CQ_IC_BAR_VALID)) {
+ memory_region_add_subregion(sysmem, xive->ic_base,
+ &xive->ic_mmio);
+
+ memory_region_add_subregion(&xive->ic_mmio, 0,
+ &xive->ic_reg_mmio);
+ memory_region_add_subregion(&xive->ic_mmio,
+ 1ul << xive->ic_shift,
+ &xive->ic_notify_mmio);
+ memory_region_add_subregion(&xive->ic_mmio,
+ 2ul << xive->ic_shift,
+ &xive->ic_lsi_mmio);
+ memory_region_add_subregion(&xive->ic_mmio,
+ 4ull << xive->ic_shift,
+ &xive->tm_indirect_mmio);
+ }
+ }
+ break;
+
+ case CQ_TM1_BAR: /* TM BAR. 4 pages. Map only once */
+ case CQ_TM2_BAR: /* second TM BAR. for hotplug. Not modeled */
+ xive->tm_shift = val & CQ_TM_BAR_64K ? 16 : 12;
+ if (!(val & CQ_TM_BAR_VALID)) {
+ xive->tm_base = 0;
+ if (xive->regs[reg] & CQ_TM_BAR_VALID && is_chip0) {
+ memory_region_del_subregion(sysmem, &xive->tm_mmio);
+ }
+ } else {
+ xive->tm_base = val & ~(CQ_TM_BAR_VALID | CQ_TM_BAR_64K);
+ if (!(xive->regs[reg] & CQ_TM_BAR_VALID) && is_chip0) {
+ memory_region_add_subregion(sysmem, xive->tm_base,
+ &xive->tm_mmio);
+ }
+ }
+ break;
+
+ case CQ_PC_BARM:
+ xive->regs[reg] = val;
+ memory_region_set_size(&xive->pc_mmio, pnv_xive_pc_size(xive));
+ break;
+ case CQ_PC_BAR: /* From 32M to 512G */
+ if (!(val & CQ_PC_BAR_VALID)) {
+ xive->pc_base = 0;
+ if (xive->regs[reg] & CQ_PC_BAR_VALID) {
+ memory_region_del_subregion(sysmem, &xive->pc_mmio);
+ }
+ } else {
+ xive->pc_base = val & ~(CQ_PC_BAR_VALID);
+ if (!(xive->regs[reg] & CQ_PC_BAR_VALID)) {
+ memory_region_add_subregion(sysmem, xive->pc_base,
+ &xive->pc_mmio);
+ }
+ }
+ break;
+
+ case CQ_VC_BARM:
+ xive->regs[reg] = val;
+ memory_region_set_size(&xive->vc_mmio, pnv_xive_vc_size(xive));
+ break;
+ case CQ_VC_BAR: /* From 64M to 4TB */
+ if (!(val & CQ_VC_BAR_VALID)) {
+ xive->vc_base = 0;
+ if (xive->regs[reg] & CQ_VC_BAR_VALID) {
+ memory_region_del_subregion(sysmem, &xive->vc_mmio);
+ }
+ } else {
+ xive->vc_base = val & ~(CQ_VC_BAR_VALID);
+ if (!(xive->regs[reg] & CQ_VC_BAR_VALID)) {
+ memory_region_add_subregion(sysmem, xive->vc_base,
+ &xive->vc_mmio);
+ }
+ }
+ break;
+
+ /*
+ * XIVE Table settings.
+ */
+ case CQ_TAR: /* Table Address */
+ break;
+ case CQ_TDR: /* Table Data */
+ pnv_xive_table_set_data(xive, val);
+ break;
+
+ /*
+ * XIVE VC & PC Virtual Structure Table settings
+ */
+ case VC_VSD_TABLE_ADDR:
+ case PC_VSD_TABLE_ADDR: /* Virtual table selector */
+ break;
+ case VC_VSD_TABLE_DATA: /* Virtual table setting */
+ case PC_VSD_TABLE_DATA:
+ pnv_xive_vst_set_data(xive, val, offset == PC_VSD_TABLE_DATA);
+ break;
+
+ /*
+ * Interrupt fifo overflow in memory backing store (Not modeled)
+ */
+ case VC_IRQ_CONFIG_IPI:
+ case VC_IRQ_CONFIG_HW:
+ case VC_IRQ_CONFIG_CASCADE1:
+ case VC_IRQ_CONFIG_CASCADE2:
+ case VC_IRQ_CONFIG_REDIST:
+ case VC_IRQ_CONFIG_IPI_CASC:
+ break;
+
+ /*
+ * XIVE hardware thread enablement
+ */
+ case PC_THREAD_EN_REG0: /* Physical Thread Enable */
+ case PC_THREAD_EN_REG1: /* Physical Thread Enable (fused core) */
+ break;
+
+ case PC_THREAD_EN_REG0_SET:
+ xive->regs[PC_THREAD_EN_REG0 >> 3] |= val;
+ break;
+ case PC_THREAD_EN_REG1_SET:
+ xive->regs[PC_THREAD_EN_REG1 >> 3] |= val;
+ break;
+ case PC_THREAD_EN_REG0_CLR:
+ xive->regs[PC_THREAD_EN_REG0 >> 3] &= ~val;
+ break;
+ case PC_THREAD_EN_REG1_CLR:
+ xive->regs[PC_THREAD_EN_REG1 >> 3] &= ~val;
+ break;
+
+ /*
+ * Indirect TIMA access set up. Defines the PIR of the HW thread
+ * to use.
+ */
+ case PC_TCTXT_INDIR0 ... PC_TCTXT_INDIR3:
+ break;
+
+ /*
+ * XIVE PC & VC cache updates for EAS, NVT and END
+ */
+ case VC_IVC_SCRUB_MASK:
+ break;
+ case VC_IVC_SCRUB_TRIG:
+ pnv_xive_eas_update(xive, GETFIELD(PC_SCRUB_BLOCK_ID, val),
+ GETFIELD(VC_SCRUB_OFFSET, val));
+ break;
+
+ case VC_EQC_SCRUB_MASK:
+ case VC_EQC_CWATCH_SPEC:
+ case VC_EQC_CWATCH_DAT0 ... VC_EQC_CWATCH_DAT3:
+ break;
+ case VC_EQC_SCRUB_TRIG:
+ pnv_xive_end_update(xive, GETFIELD(VC_SCRUB_BLOCK_ID, val),
+ GETFIELD(VC_SCRUB_OFFSET, val));
+ break;
+
+ case PC_VPC_SCRUB_MASK:
+ case PC_VPC_CWATCH_SPEC:
+ case PC_VPC_CWATCH_DAT0 ... PC_VPC_CWATCH_DAT7:
+ break;
+ case PC_VPC_SCRUB_TRIG:
+ pnv_xive_nvt_update(xive, GETFIELD(PC_SCRUB_BLOCK_ID, val),
+ GETFIELD(PC_SCRUB_OFFSET, val));
+ break;
+
+
+ /*
+ * XIVE PC & VC cache invalidation
+ */
+ case PC_AT_KILL:
+ break;
+ case VC_AT_MACRO_KILL:
+ break;
+ case PC_AT_KILL_MASK:
+ case VC_AT_MACRO_KILL_MASK:
+ break;
+
+ default:
+ xive_error(xive, "IC: invalid write to reg=0x%"HWADDR_PRIx, offset);
+ return;
+ }
+
+ xive->regs[reg] = val;
+}
+
+static uint64_t pnv_xive_ic_reg_read(void *opaque, hwaddr offset, unsigned size)
+{
+ PnvXive *xive = PNV_XIVE(opaque);
+ uint64_t val = 0;
+ uint32_t reg = offset >> 3;
+
+ switch (offset) {
+ case CQ_CFG_PB_GEN:
+ case CQ_IC_BAR:
+ case CQ_TM1_BAR:
+ case CQ_TM2_BAR:
+ case CQ_PC_BAR:
+ case CQ_PC_BARM:
+ case CQ_VC_BAR:
+ case CQ_VC_BARM:
+ case CQ_TAR:
+ case CQ_TDR:
+ case CQ_PBI_CTL:
+
+ case PC_TCTXT_CFG:
+ case PC_TCTXT_TRACK:
+ case PC_TCTXT_INDIR0:
+ case PC_TCTXT_INDIR1:
+ case PC_TCTXT_INDIR2:
+ case PC_TCTXT_INDIR3:
+ case PC_GLOBAL_CONFIG:
+
+ case PC_VPC_SCRUB_MASK:
+ case PC_VPC_CWATCH_SPEC:
+ case PC_VPC_CWATCH_DAT0:
+ case PC_VPC_CWATCH_DAT1:
+ case PC_VPC_CWATCH_DAT2:
+ case PC_VPC_CWATCH_DAT3:
+ case PC_VPC_CWATCH_DAT4:
+ case PC_VPC_CWATCH_DAT5:
+ case PC_VPC_CWATCH_DAT6:
+ case PC_VPC_CWATCH_DAT7:
+
+ case VC_GLOBAL_CONFIG:
+ case VC_AIB_TX_ORDER_TAG2:
+
+ case VC_IRQ_CONFIG_IPI:
+ case VC_IRQ_CONFIG_HW:
+ case VC_IRQ_CONFIG_CASCADE1:
+ case VC_IRQ_CONFIG_CASCADE2:
+ case VC_IRQ_CONFIG_REDIST:
+ case VC_IRQ_CONFIG_IPI_CASC:
+
+ case VC_EQC_SCRUB_MASK:
+ case VC_EQC_CWATCH_DAT0:
+ case VC_EQC_CWATCH_DAT1:
+ case VC_EQC_CWATCH_DAT2:
+ case VC_EQC_CWATCH_DAT3:
+
+ case VC_EQC_CWATCH_SPEC:
+ case VC_IVC_SCRUB_MASK:
+ case VC_SBC_CONFIG:
+ case VC_AT_MACRO_KILL_MASK:
+ case VC_VSD_TABLE_ADDR:
+ case PC_VSD_TABLE_ADDR:
+ case VC_VSD_TABLE_DATA:
+ case PC_VSD_TABLE_DATA:
+ case PC_THREAD_EN_REG0:
+ case PC_THREAD_EN_REG1:
+ val = xive->regs[reg];
+ break;
+
+ /*
+ * XIVE hardware thread enablement
+ */
+ case PC_THREAD_EN_REG0_SET:
+ case PC_THREAD_EN_REG0_CLR:
+ val = xive->regs[PC_THREAD_EN_REG0 >> 3];
+ break;
+ case PC_THREAD_EN_REG1_SET:
+ case PC_THREAD_EN_REG1_CLR:
+ val = xive->regs[PC_THREAD_EN_REG1 >> 3];
+ break;
+
+ case CQ_MSGSND: /* Identifies which cores have msgsnd enabled. */
+ val = 0xffffff0000000000;
+ break;
+
+ /*
+ * XIVE PC & VC cache updates for EAS, NVT and END
+ */
+ case PC_VPC_SCRUB_TRIG:
+ case VC_IVC_SCRUB_TRIG:
+ case VC_EQC_SCRUB_TRIG:
+ xive->regs[reg] &= ~VC_SCRUB_VALID;
+ val = xive->regs[reg];
+ break;
+
+ /*
+ * XIVE PC & VC cache invalidation
+ */
+ case PC_AT_KILL:
+ xive->regs[reg] &= ~PC_AT_KILL_VALID;
+ val = xive->regs[reg];
+ break;
+ case VC_AT_MACRO_KILL:
+ xive->regs[reg] &= ~VC_KILL_VALID;
+ val = xive->regs[reg];
+ break;
+
+ /*
+ * XIVE synchronisation
+ */
+ case VC_EQC_CONFIG:
+ val = VC_EQC_SYNC_MASK;
+ break;
+
+ default:
+ xive_error(xive, "IC: invalid read reg=0x%"HWADDR_PRIx, offset);
+ }
+
+ return val;
+}
+
+static const MemoryRegionOps pnv_xive_ic_reg_ops = {
+ .read = pnv_xive_ic_reg_read,
+ .write = pnv_xive_ic_reg_write,
+ .endianness = DEVICE_BIG_ENDIAN,
+ .valid = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ },
+ .impl = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ },
+};
+
+/*
+ * IC - Notify MMIO port page (write only)
+ */
+#define PNV_XIVE_FORWARD_IPI 0x800 /* Forward IPI */
+#define PNV_XIVE_FORWARD_HW 0x880 /* Forward HW */
+#define PNV_XIVE_FORWARD_OS_ESC 0x900 /* Forward OS escalation */
+#define PNV_XIVE_FORWARD_HW_ESC 0x980 /* Forward Hyp escalation */
+#define PNV_XIVE_FORWARD_REDIS 0xa00 /* Forward Redistribution */
+#define PNV_XIVE_RESERVED5 0xa80 /* Cache line 5 PowerBUS operation */
+#define PNV_XIVE_RESERVED6 0xb00 /* Cache line 6 PowerBUS operation */
+#define PNV_XIVE_RESERVED7 0xb80 /* Cache line 7 PowerBUS operation */
+
+/* VC synchronisation */
+#define PNV_XIVE_SYNC_IPI 0xc00 /* Sync IPI */
+#define PNV_XIVE_SYNC_HW 0xc80 /* Sync HW */
+#define PNV_XIVE_SYNC_OS_ESC 0xd00 /* Sync OS escalation */
+#define PNV_XIVE_SYNC_HW_ESC 0xd80 /* Sync Hyp escalation */
+#define PNV_XIVE_SYNC_REDIS 0xe00 /* Sync Redistribution */
+
+/* PC synchronisation */
+#define PNV_XIVE_SYNC_PULL 0xe80 /* Sync pull context */
+#define PNV_XIVE_SYNC_PUSH 0xf00 /* Sync push context */
+#define PNV_XIVE_SYNC_VPC 0xf80 /* Sync remove VPC store */
+
+static void pnv_xive_ic_hw_trigger(PnvXive *xive, hwaddr addr, uint64_t val)
+{
+ /*
+ * Forward the source event notification directly to the Router.
+ * The source interrupt number should already be correctly encoded
+ * with the chip block id by the sending device (PHB, PSI).
+ */
+ xive_router_notify(XIVE_NOTIFIER(xive), val);
+}
+
+static void pnv_xive_ic_notify_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned size)
+{
+ PnvXive *xive = PNV_XIVE(opaque);
+
+ /* VC: HW triggers */
+ switch (addr) {
+ case 0x000 ... 0x7FF:
+ pnv_xive_ic_hw_trigger(opaque, addr, val);
+ break;
+
+ /* VC: Forwarded IRQs */
+ case PNV_XIVE_FORWARD_IPI:
+ case PNV_XIVE_FORWARD_HW:
+ case PNV_XIVE_FORWARD_OS_ESC:
+ case PNV_XIVE_FORWARD_HW_ESC:
+ case PNV_XIVE_FORWARD_REDIS:
+ /* TODO: forwarded IRQs. Should be like HW triggers */
+ xive_error(xive, "IC: forwarded at @0x%"HWADDR_PRIx" IRQ 0x%"PRIx64,
+ addr, val);
+ break;
+
+ /* VC syncs */
+ case PNV_XIVE_SYNC_IPI:
+ case PNV_XIVE_SYNC_HW:
+ case PNV_XIVE_SYNC_OS_ESC:
+ case PNV_XIVE_SYNC_HW_ESC:
+ case PNV_XIVE_SYNC_REDIS:
+ break;
+
+ /* PC syncs */
+ case PNV_XIVE_SYNC_PULL:
+ case PNV_XIVE_SYNC_PUSH:
+ case PNV_XIVE_SYNC_VPC:
+ break;
+
+ default:
+ xive_error(xive, "IC: invalid notify write @%"HWADDR_PRIx, addr);
+ }
+}
+
+static uint64_t pnv_xive_ic_notify_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ PnvXive *xive = PNV_XIVE(opaque);
+
+ /* loads are invalid */
+ xive_error(xive, "IC: invalid notify read @%"HWADDR_PRIx, addr);
+ return -1;
+}
+
+static const MemoryRegionOps pnv_xive_ic_notify_ops = {
+ .read = pnv_xive_ic_notify_read,
+ .write = pnv_xive_ic_notify_write,
+ .endianness = DEVICE_BIG_ENDIAN,
+ .valid = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ },
+ .impl = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ },
+};
+
+/*
+ * IC - LSI MMIO handlers (not modeled)
+ */
+
+static void pnv_xive_ic_lsi_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ PnvXive *xive = PNV_XIVE(opaque);
+
+ xive_error(xive, "IC: LSI invalid write @%"HWADDR_PRIx, addr);
+}
+
+static uint64_t pnv_xive_ic_lsi_read(void *opaque, hwaddr addr, unsigned size)
+{
+ PnvXive *xive = PNV_XIVE(opaque);
+
+ xive_error(xive, "IC: LSI invalid read @%"HWADDR_PRIx, addr);
+ return -1;
+}
+
+static const MemoryRegionOps pnv_xive_ic_lsi_ops = {
+ .read = pnv_xive_ic_lsi_read,
+ .write = pnv_xive_ic_lsi_write,
+ .endianness = DEVICE_BIG_ENDIAN,
+ .valid = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ },
+ .impl = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ },
+};
+
+/*
+ * IC - Indirect TIMA MMIO handlers
+ */
+
+/*
+ * When the TIMA is accessed from the indirect page, the thread id
+ * (PIR) has to be configured in the IC registers before. This is used
+ * for resets and for debug purpose also.
+ */
+static XiveTCTX *pnv_xive_get_indirect_tctx(PnvXive *xive)
+{
+ uint64_t tctxt_indir = xive->regs[PC_TCTXT_INDIR0 >> 3];
+ PowerPCCPU *cpu = NULL;
+ int pir;
+
+ if (!(tctxt_indir & PC_TCTXT_INDIR_VALID)) {
+ xive_error(xive, "IC: no indirect TIMA access in progress");
+ return NULL;
+ }
+
+ pir = GETFIELD(PC_TCTXT_INDIR_THRDID, tctxt_indir) & 0xff;
+ cpu = ppc_get_vcpu_by_pir(pir);
+ if (!cpu) {
+ xive_error(xive, "IC: invalid PIR %x for indirect access", pir);
+ return NULL;
+ }
+
+ /* Check that HW thread is XIVE enabled */
+ if (!(xive->regs[PC_THREAD_EN_REG0 >> 3] & PPC_BIT(pir & 0x3f))) {
+ xive_error(xive, "IC: CPU %x is not enabled", pir);
+ }
+
+ return XIVE_TCTX(pnv_cpu_state(cpu)->intc);
+}
+
+static void xive_tm_indirect_write(void *opaque, hwaddr offset,
+ uint64_t value, unsigned size)
+{
+ XiveTCTX *tctx = pnv_xive_get_indirect_tctx(PNV_XIVE(opaque));
+
+ xive_tctx_tm_write(tctx, offset, value, size);
+}
+
+static uint64_t xive_tm_indirect_read(void *opaque, hwaddr offset,
+ unsigned size)
+{
+ XiveTCTX *tctx = pnv_xive_get_indirect_tctx(PNV_XIVE(opaque));
+
+ return xive_tctx_tm_read(tctx, offset, size);
+}
+
+static const MemoryRegionOps xive_tm_indirect_ops = {
+ .read = xive_tm_indirect_read,
+ .write = xive_tm_indirect_write,
+ .endianness = DEVICE_BIG_ENDIAN,
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 8,
+ },
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 8,
+ },
+};
+
+/*
+ * Interrupt controller XSCOM region.
+ */
+static uint64_t pnv_xive_xscom_read(void *opaque, hwaddr addr, unsigned size)
+{
+ switch (addr >> 3) {
+ case X_VC_EQC_CONFIG:
+ /* FIXME (skiboot): This is the only XSCOM load. Bizarre. */
+ return VC_EQC_SYNC_MASK;
+ default:
+ return pnv_xive_ic_reg_read(opaque, addr, size);
+ }
+}
+
+static void pnv_xive_xscom_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ pnv_xive_ic_reg_write(opaque, addr, val, size);
+}
+
+static const MemoryRegionOps pnv_xive_xscom_ops = {
+ .read = pnv_xive_xscom_read,
+ .write = pnv_xive_xscom_write,
+ .endianness = DEVICE_BIG_ENDIAN,
+ .valid = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ },
+ .impl = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ }
+};
+
+/*
+ * Virtualization Controller MMIO region containing the IPI and END ESB pages
+ */
+static uint64_t pnv_xive_vc_read(void *opaque, hwaddr offset,
+ unsigned size)
+{
+ PnvXive *xive = PNV_XIVE(opaque);
+ uint64_t edt_index = offset >> pnv_xive_edt_shift(xive);
+ uint64_t edt_type = 0;
+ uint64_t edt_offset;
+ MemTxResult result;
+ AddressSpace *edt_as = NULL;
+ uint64_t ret = -1;
+
+ if (edt_index < XIVE_TABLE_EDT_MAX) {
+ edt_type = GETFIELD(CQ_TDR_EDT_TYPE, xive->edt[edt_index]);
+ }
+
+ switch (edt_type) {
+ case CQ_TDR_EDT_IPI:
+ edt_as = &xive->ipi_as;
+ break;
+ case CQ_TDR_EDT_EQ:
+ edt_as = &xive->end_as;
+ break;
+ default:
+ xive_error(xive, "VC: invalid EDT type for read @%"HWADDR_PRIx, offset);
+ return -1;
+ }
+
+ /* Remap the offset for the targeted address space */
+ edt_offset = pnv_xive_edt_offset(xive, offset, edt_type);
+
+ ret = address_space_ldq(edt_as, edt_offset, MEMTXATTRS_UNSPECIFIED,
+ &result);
+
+ if (result != MEMTX_OK) {
+ xive_error(xive, "VC: %s read failed at @0x%"HWADDR_PRIx " -> @0x%"
+ HWADDR_PRIx, edt_type == CQ_TDR_EDT_IPI ? "IPI" : "END",
+ offset, edt_offset);
+ return -1;
+ }
+
+ return ret;
+}
+
+static void pnv_xive_vc_write(void *opaque, hwaddr offset,
+ uint64_t val, unsigned size)
+{
+ PnvXive *xive = PNV_XIVE(opaque);
+ uint64_t edt_index = offset >> pnv_xive_edt_shift(xive);
+ uint64_t edt_type = 0;
+ uint64_t edt_offset;
+ MemTxResult result;
+ AddressSpace *edt_as = NULL;
+
+ if (edt_index < XIVE_TABLE_EDT_MAX) {
+ edt_type = GETFIELD(CQ_TDR_EDT_TYPE, xive->edt[edt_index]);
+ }
+
+ switch (edt_type) {
+ case CQ_TDR_EDT_IPI:
+ edt_as = &xive->ipi_as;
+ break;
+ case CQ_TDR_EDT_EQ:
+ edt_as = &xive->end_as;
+ break;
+ default:
+ xive_error(xive, "VC: invalid EDT type for write @%"HWADDR_PRIx,
+ offset);
+ return;
+ }
+
+ /* Remap the offset for the targeted address space */
+ edt_offset = pnv_xive_edt_offset(xive, offset, edt_type);
+
+ address_space_stq(edt_as, edt_offset, val, MEMTXATTRS_UNSPECIFIED, &result);
+ if (result != MEMTX_OK) {
+ xive_error(xive, "VC: write failed at @0x%"HWADDR_PRIx, edt_offset);
+ }
+}
+
+static const MemoryRegionOps pnv_xive_vc_ops = {
+ .read = pnv_xive_vc_read,
+ .write = pnv_xive_vc_write,
+ .endianness = DEVICE_BIG_ENDIAN,
+ .valid = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ },
+ .impl = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ },
+};
+
+/*
+ * Presenter Controller MMIO region. The Virtualization Controller
+ * updates the IPB in the NVT table when required. Not modeled.
+ */
+static uint64_t pnv_xive_pc_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ PnvXive *xive = PNV_XIVE(opaque);
+
+ xive_error(xive, "PC: invalid read @%"HWADDR_PRIx, addr);
+ return -1;
+}
+
+static void pnv_xive_pc_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
+{
+ PnvXive *xive = PNV_XIVE(opaque);
+
+ xive_error(xive, "PC: invalid write to VC @%"HWADDR_PRIx, addr);
+}
+
+static const MemoryRegionOps pnv_xive_pc_ops = {
+ .read = pnv_xive_pc_read,
+ .write = pnv_xive_pc_write,
+ .endianness = DEVICE_BIG_ENDIAN,
+ .valid = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ },
+ .impl = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ },
+};
+
+void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
+{
+ XiveRouter *xrtr = XIVE_ROUTER(xive);
+ uint8_t blk = xive->chip->chip_id;
+ uint32_t srcno0 = XIVE_SRCNO(blk, 0);
+ uint32_t nr_ipis = pnv_xive_nr_ipis(xive);
+ uint32_t nr_ends = pnv_xive_nr_ends(xive);
+ XiveEAS eas;
+ XiveEND end;
+ int i;
+
+ monitor_printf(mon, "XIVE[%x] Source %08x .. %08x\n", blk, srcno0,
+ srcno0 + nr_ipis - 1);
+ xive_source_pic_print_info(&xive->ipi_source, srcno0, mon);
+
+ monitor_printf(mon, "XIVE[%x] EAT %08x .. %08x\n", blk, srcno0,
+ srcno0 + nr_ipis - 1);
+ for (i = 0; i < nr_ipis; i++) {
+ if (xive_router_get_eas(xrtr, blk, i, &eas)) {
+ break;
+ }
+ if (!xive_eas_is_masked(&eas)) {
+ xive_eas_pic_print_info(&eas, i, mon);
+ }
+ }
+
+ monitor_printf(mon, "XIVE[%x] ENDT %08x .. %08x\n", blk, 0, nr_ends - 1);
+ for (i = 0; i < nr_ends; i++) {
+ if (xive_router_get_end(xrtr, blk, i, &end)) {
+ break;
+ }
+ xive_end_pic_print_info(&end, i, mon);
+ }
+}
+
+static void pnv_xive_reset(void *dev)
+{
+ PnvXive *xive = PNV_XIVE(dev);
+ XiveSource *xsrc = &xive->ipi_source;
+ XiveENDSource *end_xsrc = &xive->end_source;
+
+ /*
+ * Use the PnvChip id to identify the XIVE interrupt controller.
+ * It can be overriden by configuration at runtime.
+ */
+ xive->tctx_chipid = xive->chip->chip_id;
+
+ /* Default page size (Should be changed at runtime to 64k) */
+ xive->ic_shift = xive->vc_shift = xive->pc_shift = 12;
+
+ /* Clear subregions */
+ if (memory_region_is_mapped(&xsrc->esb_mmio)) {
+ memory_region_del_subregion(&xive->ipi_edt_mmio, &xsrc->esb_mmio);
+ }
+
+ if (memory_region_is_mapped(&xive->ipi_edt_mmio)) {
+ memory_region_del_subregion(&xive->ipi_mmio, &xive->ipi_edt_mmio);
+ }
+
+ if (memory_region_is_mapped(&end_xsrc->esb_mmio)) {
+ memory_region_del_subregion(&xive->end_edt_mmio, &end_xsrc->esb_mmio);
+ }
+
+ if (memory_region_is_mapped(&xive->end_edt_mmio)) {
+ memory_region_del_subregion(&xive->end_mmio, &xive->end_edt_mmio);
+ }
+}
+
+static void pnv_xive_init(Object *obj)
+{
+ PnvXive *xive = PNV_XIVE(obj);
+
+ object_initialize_child(obj, "ipi_source", &xive->ipi_source,
+ sizeof(xive->ipi_source), TYPE_XIVE_SOURCE,
+ &error_abort, NULL);
+ object_initialize_child(obj, "end_source", &xive->end_source,
+ sizeof(xive->end_source), TYPE_XIVE_END_SOURCE,
+ &error_abort, NULL);
+}
+
+/*
+ * Maximum number of IRQs and ENDs supported by HW
+ */
+#define PNV_XIVE_NR_IRQS (PNV9_XIVE_VC_SIZE / (1ull << XIVE_ESB_64K_2PAGE))
+#define PNV_XIVE_NR_ENDS (PNV9_XIVE_VC_SIZE / (1ull << XIVE_ESB_64K_2PAGE))
+
+static void pnv_xive_realize(DeviceState *dev, Error **errp)
+{
+ PnvXive *xive = PNV_XIVE(dev);
+ XiveSource *xsrc = &xive->ipi_source;
+ XiveENDSource *end_xsrc = &xive->end_source;
+ Error *local_err = NULL;
+ Object *obj;
+
+ obj = object_property_get_link(OBJECT(dev), "chip", &local_err);
+ if (!obj) {
+ error_propagate(errp, local_err);
+ error_prepend(errp, "required link 'chip' not found: ");
+ return;
+ }
+
+ /* The PnvChip id identifies the XIVE interrupt controller. */
+ xive->chip = PNV_CHIP(obj);
+
+ /*
+ * The XiveSource and XiveENDSource objects are realized with the
+ * maximum allowed HW configuration. The ESB MMIO regions will be
+ * resized dynamically when the controller is configured by the FW
+ * to limit accesses to resources not provisioned.
+ */
+ object_property_set_int(OBJECT(xsrc), PNV_XIVE_NR_IRQS, "nr-irqs",
+ &error_fatal);
+ object_property_add_const_link(OBJECT(xsrc), "xive", OBJECT(xive),
+ &error_fatal);
+ object_property_set_bool(OBJECT(xsrc), true, "realized", &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ object_property_set_int(OBJECT(end_xsrc), PNV_XIVE_NR_ENDS, "nr-ends",
+ &error_fatal);
+ object_property_add_const_link(OBJECT(end_xsrc), "xive", OBJECT(xive),
+ &error_fatal);
+ object_property_set_bool(OBJECT(end_xsrc), true, "realized", &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ /* Default page size. Generally changed at runtime to 64k */
+ xive->ic_shift = xive->vc_shift = xive->pc_shift = 12;
+
+ /* XSCOM region, used for initial configuration of the BARs */
+ memory_region_init_io(&xive->xscom_regs, OBJECT(dev), &pnv_xive_xscom_ops,
+ xive, "xscom-xive", PNV9_XSCOM_XIVE_SIZE << 3);
+
+ /* Interrupt controller MMIO regions */
+ memory_region_init(&xive->ic_mmio, OBJECT(dev), "xive-ic",
+ PNV9_XIVE_IC_SIZE);
+
+ memory_region_init_io(&xive->ic_reg_mmio, OBJECT(dev), &pnv_xive_ic_reg_ops,
+ xive, "xive-ic-reg", 1 << xive->ic_shift);
+ memory_region_init_io(&xive->ic_notify_mmio, OBJECT(dev),
+ &pnv_xive_ic_notify_ops,
+ xive, "xive-ic-notify", 1 << xive->ic_shift);
+
+ /* The Pervasive LSI trigger and EOI pages (not modeled) */
+ memory_region_init_io(&xive->ic_lsi_mmio, OBJECT(dev), &pnv_xive_ic_lsi_ops,
+ xive, "xive-ic-lsi", 2 << xive->ic_shift);
+
+ /* Thread Interrupt Management Area (Indirect) */
+ memory_region_init_io(&xive->tm_indirect_mmio, OBJECT(dev),
+ &xive_tm_indirect_ops,
+ xive, "xive-tima-indirect", PNV9_XIVE_TM_SIZE);
+ /*
+ * Overall Virtualization Controller MMIO region containing the
+ * IPI ESB pages and END ESB pages. The layout is defined by the
+ * EDT "Domain table" and the accesses are dispatched using
+ * address spaces for each.
+ */
+ memory_region_init_io(&xive->vc_mmio, OBJECT(xive), &pnv_xive_vc_ops, xive,
+ "xive-vc", PNV9_XIVE_VC_SIZE);
+
+ memory_region_init(&xive->ipi_mmio, OBJECT(xive), "xive-vc-ipi",
+ PNV9_XIVE_VC_SIZE);
+ address_space_init(&xive->ipi_as, &xive->ipi_mmio, "xive-vc-ipi");
+ memory_region_init(&xive->end_mmio, OBJECT(xive), "xive-vc-end",
+ PNV9_XIVE_VC_SIZE);
+ address_space_init(&xive->end_as, &xive->end_mmio, "xive-vc-end");
+
+ /*
+ * The MMIO windows exposing the IPI ESBs and the END ESBs in the
+ * VC region. Their size is configured by the FW in the EDT table.
+ */
+ memory_region_init(&xive->ipi_edt_mmio, OBJECT(xive), "xive-vc-ipi-edt", 0);
+ memory_region_init(&xive->end_edt_mmio, OBJECT(xive), "xive-vc-end-edt", 0);
+
+ /* Presenter Controller MMIO region (not modeled) */
+ memory_region_init_io(&xive->pc_mmio, OBJECT(xive), &pnv_xive_pc_ops, xive,
+ "xive-pc", PNV9_XIVE_PC_SIZE);
+
+ /* Thread Interrupt Management Area (Direct) */
+ memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &xive_tm_ops,
+ xive, "xive-tima", PNV9_XIVE_TM_SIZE);
+
+ qemu_register_reset(pnv_xive_reset, dev);
+}
+
+static int pnv_xive_dt_xscom(PnvXScomInterface *dev, void *fdt,
+ int xscom_offset)
+{
+ const char compat[] = "ibm,power9-xive-x";
+ char *name;
+ int offset;
+ uint32_t lpc_pcba = PNV9_XSCOM_XIVE_BASE;
+ uint32_t reg[] = {
+ cpu_to_be32(lpc_pcba),
+ cpu_to_be32(PNV9_XSCOM_XIVE_SIZE)
+ };
+
+ name = g_strdup_printf("xive@%x", lpc_pcba);
+ offset = fdt_add_subnode(fdt, xscom_offset, name);
+ _FDT(offset);
+ g_free(name);
+
+ _FDT((fdt_setprop(fdt, offset, "reg", reg, sizeof(reg))));
+ _FDT((fdt_setprop(fdt, offset, "compatible", compat,
+ sizeof(compat))));
+ return 0;
+}
+
+static Property pnv_xive_properties[] = {
+ DEFINE_PROP_UINT64("ic-bar", PnvXive, ic_base, 0),
+ DEFINE_PROP_UINT64("vc-bar", PnvXive, vc_base, 0),
+ DEFINE_PROP_UINT64("pc-bar", PnvXive, pc_base, 0),
+ DEFINE_PROP_UINT64("tm-bar", PnvXive, tm_base, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pnv_xive_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass);
+ XiveRouterClass *xrc = XIVE_ROUTER_CLASS(klass);
+ XiveNotifierClass *xnc = XIVE_NOTIFIER_CLASS(klass);
+
+ xdc->dt_xscom = pnv_xive_dt_xscom;
+
+ dc->desc = "PowerNV XIVE Interrupt Controller";
+ dc->realize = pnv_xive_realize;
+ dc->props = pnv_xive_properties;
+
+ xrc->get_eas = pnv_xive_get_eas;
+ xrc->get_end = pnv_xive_get_end;
+ xrc->write_end = pnv_xive_write_end;
+ xrc->get_nvt = pnv_xive_get_nvt;
+ xrc->write_nvt = pnv_xive_write_nvt;
+ xrc->get_tctx = pnv_xive_get_tctx;
+
+ xnc->notify = pnv_xive_notify;
+};
+
+static const TypeInfo pnv_xive_info = {
+ .name = TYPE_PNV_XIVE,
+ .parent = TYPE_XIVE_ROUTER,
+ .instance_init = pnv_xive_init,
+ .instance_size = sizeof(PnvXive),
+ .class_init = pnv_xive_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_PNV_XSCOM_INTERFACE },
+ { }
+ }
+};
+
+static void pnv_xive_register_types(void)
+{
+ type_register_static(&pnv_xive_info);
+}
+
+type_init(pnv_xive_register_types)
diff --git a/hw/intc/pnv_xive_regs.h b/hw/intc/pnv_xive_regs.h
new file mode 100644
index 0000000000..c78f030c02
--- /dev/null
+++ b/hw/intc/pnv_xive_regs.h
@@ -0,0 +1,248 @@
+/*
+ * QEMU PowerPC XIVE interrupt controller model
+ *
+ * Copyright (c) 2017-2018, IBM Corporation.
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ */
+
+#ifndef PPC_PNV_XIVE_REGS_H
+#define PPC_PNV_XIVE_REGS_H
+
+/* IC register offsets 0x0 - 0x400 */
+#define CQ_SWI_CMD_HIST 0x020
+#define CQ_SWI_CMD_POLL 0x028
+#define CQ_SWI_CMD_BCAST 0x030
+#define CQ_SWI_CMD_ASSIGN 0x038
+#define CQ_SWI_CMD_BLK_UPD 0x040
+#define CQ_SWI_RSP 0x048
+#define CQ_CFG_PB_GEN 0x050
+#define CQ_INT_ADDR_OPT PPC_BITMASK(14, 15)
+#define CQ_MSGSND 0x058
+#define CQ_CNPM_SEL 0x078
+#define CQ_IC_BAR 0x080
+#define CQ_IC_BAR_VALID PPC_BIT(0)
+#define CQ_IC_BAR_64K PPC_BIT(1)
+#define CQ_TM1_BAR 0x90
+#define CQ_TM2_BAR 0x0a0
+#define CQ_TM_BAR_VALID PPC_BIT(0)
+#define CQ_TM_BAR_64K PPC_BIT(1)
+#define CQ_PC_BAR 0x0b0
+#define CQ_PC_BAR_VALID PPC_BIT(0)
+#define CQ_PC_BARM 0x0b8
+#define CQ_PC_BARM_MASK PPC_BITMASK(26, 38)
+#define CQ_VC_BAR 0x0c0
+#define CQ_VC_BAR_VALID PPC_BIT(0)
+#define CQ_VC_BARM 0x0c8
+#define CQ_VC_BARM_MASK PPC_BITMASK(21, 37)
+#define CQ_TAR 0x0f0
+#define CQ_TAR_TBL_AUTOINC PPC_BIT(0)
+#define CQ_TAR_TSEL PPC_BITMASK(12, 15)
+#define CQ_TAR_TSEL_BLK PPC_BIT(12)
+#define CQ_TAR_TSEL_MIG PPC_BIT(13)
+#define CQ_TAR_TSEL_VDT PPC_BIT(14)
+#define CQ_TAR_TSEL_EDT PPC_BIT(15)
+#define CQ_TAR_TSEL_INDEX PPC_BITMASK(26, 31)
+#define CQ_TDR 0x0f8
+#define CQ_TDR_VDT_VALID PPC_BIT(0)
+#define CQ_TDR_VDT_BLK PPC_BITMASK(11, 15)
+#define CQ_TDR_VDT_INDEX PPC_BITMASK(28, 31)
+#define CQ_TDR_EDT_TYPE PPC_BITMASK(0, 1)
+#define CQ_TDR_EDT_INVALID 0
+#define CQ_TDR_EDT_IPI 1
+#define CQ_TDR_EDT_EQ 2
+#define CQ_TDR_EDT_BLK PPC_BITMASK(12, 15)
+#define CQ_TDR_EDT_INDEX PPC_BITMASK(26, 31)
+#define CQ_PBI_CTL 0x100
+#define CQ_PBI_PC_64K PPC_BIT(5)
+#define CQ_PBI_VC_64K PPC_BIT(6)
+#define CQ_PBI_LNX_TRIG PPC_BIT(7)
+#define CQ_PBI_FORCE_TM_LOCAL PPC_BIT(22)
+#define CQ_PBO_CTL 0x108
+#define CQ_AIB_CTL 0x110
+#define CQ_RST_CTL 0x118
+#define CQ_FIRMASK 0x198
+#define CQ_FIRMASK_AND 0x1a0
+#define CQ_FIRMASK_OR 0x1a8
+
+/* PC LBS1 register offsets 0x400 - 0x800 */
+#define PC_TCTXT_CFG 0x400
+#define PC_TCTXT_CFG_BLKGRP_EN PPC_BIT(0)
+#define PC_TCTXT_CFG_TARGET_EN PPC_BIT(1)
+#define PC_TCTXT_CFG_LGS_EN PPC_BIT(2)
+#define PC_TCTXT_CFG_STORE_ACK PPC_BIT(3)
+#define PC_TCTXT_CFG_HARD_CHIPID_BLK PPC_BIT(8)
+#define PC_TCTXT_CHIPID_OVERRIDE PPC_BIT(9)
+#define PC_TCTXT_CHIPID PPC_BITMASK(12, 15)
+#define PC_TCTXT_INIT_AGE PPC_BITMASK(30, 31)
+#define PC_TCTXT_TRACK 0x408
+#define PC_TCTXT_TRACK_EN PPC_BIT(0)
+#define PC_TCTXT_INDIR0 0x420
+#define PC_TCTXT_INDIR_VALID PPC_BIT(0)
+#define PC_TCTXT_INDIR_THRDID PPC_BITMASK(9, 15)
+#define PC_TCTXT_INDIR1 0x428
+#define PC_TCTXT_INDIR2 0x430
+#define PC_TCTXT_INDIR3 0x438
+#define PC_THREAD_EN_REG0 0x440
+#define PC_THREAD_EN_REG0_SET 0x448
+#define PC_THREAD_EN_REG0_CLR 0x450
+#define PC_THREAD_EN_REG1 0x460
+#define PC_THREAD_EN_REG1_SET 0x468
+#define PC_THREAD_EN_REG1_CLR 0x470
+#define PC_GLOBAL_CONFIG 0x480
+#define PC_GCONF_INDIRECT PPC_BIT(32)
+#define PC_GCONF_CHIPID_OVR PPC_BIT(40)
+#define PC_GCONF_CHIPID PPC_BITMASK(44, 47)
+#define PC_VSD_TABLE_ADDR 0x488
+#define PC_VSD_TABLE_DATA 0x490
+#define PC_AT_KILL 0x4b0
+#define PC_AT_KILL_VALID PPC_BIT(0)
+#define PC_AT_KILL_BLOCK_ID PPC_BITMASK(27, 31)
+#define PC_AT_KILL_OFFSET PPC_BITMASK(48, 60)
+#define PC_AT_KILL_MASK 0x4b8
+
+/* PC LBS2 register offsets */
+#define PC_VPC_CACHE_ENABLE 0x708
+#define PC_VPC_CACHE_EN_MASK PPC_BITMASK(0, 31)
+#define PC_VPC_SCRUB_TRIG 0x710
+#define PC_VPC_SCRUB_MASK 0x718
+#define PC_SCRUB_VALID PPC_BIT(0)
+#define PC_SCRUB_WANT_DISABLE PPC_BIT(1)
+#define PC_SCRUB_WANT_INVAL PPC_BIT(2)
+#define PC_SCRUB_BLOCK_ID PPC_BITMASK(27, 31)
+#define PC_SCRUB_OFFSET PPC_BITMASK(45, 63)
+#define PC_VPC_CWATCH_SPEC 0x738
+#define PC_VPC_CWATCH_CONFLICT PPC_BIT(0)
+#define PC_VPC_CWATCH_FULL PPC_BIT(8)
+#define PC_VPC_CWATCH_BLOCKID PPC_BITMASK(27, 31)
+#define PC_VPC_CWATCH_OFFSET PPC_BITMASK(45, 63)
+#define PC_VPC_CWATCH_DAT0 0x740
+#define PC_VPC_CWATCH_DAT1 0x748
+#define PC_VPC_CWATCH_DAT2 0x750
+#define PC_VPC_CWATCH_DAT3 0x758
+#define PC_VPC_CWATCH_DAT4 0x760
+#define PC_VPC_CWATCH_DAT5 0x768
+#define PC_VPC_CWATCH_DAT6 0x770
+#define PC_VPC_CWATCH_DAT7 0x778
+
+/* VC0 register offsets 0x800 - 0xFFF */
+#define VC_GLOBAL_CONFIG 0x800
+#define VC_GCONF_INDIRECT PPC_BIT(32)
+#define VC_VSD_TABLE_ADDR 0x808
+#define VC_VSD_TABLE_DATA 0x810
+#define VC_IVE_ISB_BLOCK_MODE 0x818
+#define VC_EQD_BLOCK_MODE 0x820
+#define VC_VPS_BLOCK_MODE 0x828
+#define VC_IRQ_CONFIG_IPI 0x840
+#define VC_IRQ_CONFIG_MEMB_EN PPC_BIT(45)
+#define VC_IRQ_CONFIG_MEMB_SZ PPC_BITMASK(46, 51)
+#define VC_IRQ_CONFIG_HW 0x848
+#define VC_IRQ_CONFIG_CASCADE1 0x850
+#define VC_IRQ_CONFIG_CASCADE2 0x858
+#define VC_IRQ_CONFIG_REDIST 0x860
+#define VC_IRQ_CONFIG_IPI_CASC 0x868
+#define VC_AIB_TX_ORDER_TAG2_REL_TF PPC_BIT(20)
+#define VC_AIB_TX_ORDER_TAG2 0x890
+#define VC_AT_MACRO_KILL 0x8b0
+#define VC_AT_MACRO_KILL_MASK 0x8b8
+#define VC_KILL_VALID PPC_BIT(0)
+#define VC_KILL_TYPE PPC_BITMASK(14, 15)
+#define VC_KILL_IRQ 0
+#define VC_KILL_IVC 1
+#define VC_KILL_SBC 2
+#define VC_KILL_EQD 3
+#define VC_KILL_BLOCK_ID PPC_BITMASK(27, 31)
+#define VC_KILL_OFFSET PPC_BITMASK(48, 60)
+#define VC_EQC_CACHE_ENABLE 0x908
+#define VC_EQC_CACHE_EN_MASK PPC_BITMASK(0, 15)
+#define VC_EQC_SCRUB_TRIG 0x910
+#define VC_EQC_SCRUB_MASK 0x918
+#define VC_EQC_CONFIG 0x920
+#define X_VC_EQC_CONFIG 0x214 /* XSCOM register */
+#define VC_EQC_CONF_SYNC_IPI PPC_BIT(32)
+#define VC_EQC_CONF_SYNC_HW PPC_BIT(33)
+#define VC_EQC_CONF_SYNC_ESC1 PPC_BIT(34)
+#define VC_EQC_CONF_SYNC_ESC2 PPC_BIT(35)
+#define VC_EQC_CONF_SYNC_REDI PPC_BIT(36)
+#define VC_EQC_CONF_EQP_INTERLEAVE PPC_BIT(38)
+#define VC_EQC_CONF_ENABLE_END_s_BIT PPC_BIT(39)
+#define VC_EQC_CONF_ENABLE_END_u_BIT PPC_BIT(40)
+#define VC_EQC_CONF_ENABLE_END_c_BIT PPC_BIT(41)
+#define VC_EQC_CONF_ENABLE_MORE_QSZ PPC_BIT(42)
+#define VC_EQC_CONF_SKIP_ESCALATE PPC_BIT(43)
+#define VC_EQC_CWATCH_SPEC 0x928
+#define VC_EQC_CWATCH_CONFLICT PPC_BIT(0)
+#define VC_EQC_CWATCH_FULL PPC_BIT(8)
+#define VC_EQC_CWATCH_BLOCKID PPC_BITMASK(28, 31)
+#define VC_EQC_CWATCH_OFFSET PPC_BITMASK(40, 63)
+#define VC_EQC_CWATCH_DAT0 0x930
+#define VC_EQC_CWATCH_DAT1 0x938
+#define VC_EQC_CWATCH_DAT2 0x940
+#define VC_EQC_CWATCH_DAT3 0x948
+#define VC_IVC_SCRUB_TRIG 0x990
+#define VC_IVC_SCRUB_MASK 0x998
+#define VC_SBC_SCRUB_TRIG 0xa10
+#define VC_SBC_SCRUB_MASK 0xa18
+#define VC_SCRUB_VALID PPC_BIT(0)
+#define VC_SCRUB_WANT_DISABLE PPC_BIT(1)
+#define VC_SCRUB_WANT_INVAL PPC_BIT(2) /* EQC and SBC only */
+#define VC_SCRUB_BLOCK_ID PPC_BITMASK(28, 31)
+#define VC_SCRUB_OFFSET PPC_BITMASK(40, 63)
+#define VC_IVC_CACHE_ENABLE 0x988
+#define VC_IVC_CACHE_EN_MASK PPC_BITMASK(0, 15)
+#define VC_SBC_CACHE_ENABLE 0xa08
+#define VC_SBC_CACHE_EN_MASK PPC_BITMASK(0, 15)
+#define VC_IVC_CACHE_SCRUB_TRIG 0x990
+#define VC_IVC_CACHE_SCRUB_MASK 0x998
+#define VC_SBC_CACHE_ENABLE 0xa08
+#define VC_SBC_CACHE_SCRUB_TRIG 0xa10
+#define VC_SBC_CACHE_SCRUB_MASK 0xa18
+#define VC_SBC_CONFIG 0xa20
+#define VC_SBC_CONF_CPLX_CIST PPC_BIT(44)
+#define VC_SBC_CONF_CIST_BOTH PPC_BIT(45)
+#define VC_SBC_CONF_NO_UPD_PRF PPC_BIT(59)
+
+/* VC1 register offsets */
+
+/* VSD Table address register definitions (shared) */
+#define VST_ADDR_AUTOINC PPC_BIT(0)
+#define VST_TABLE_SELECT PPC_BITMASK(13, 15)
+#define VST_TSEL_IVT 0
+#define VST_TSEL_SBE 1
+#define VST_TSEL_EQDT 2
+#define VST_TSEL_VPDT 3
+#define VST_TSEL_IRQ 4 /* VC only */
+#define VST_TABLE_BLOCK PPC_BITMASK(27, 31)
+
+/* Number of queue overflow pages */
+#define VC_QUEUE_OVF_COUNT 6
+
+/*
+ * Bits in a VSD entry.
+ *
+ * Note: the address is naturally aligned, we don't use a PPC_BITMASK,
+ * but just a mask to apply to the address before OR'ing it in.
+ *
+ * Note: VSD_FIRMWARE is a SW bit ! It hijacks an unused bit in the
+ * VSD and is only meant to be used in indirect mode !
+ */
+#define VSD_MODE PPC_BITMASK(0, 1)
+#define VSD_MODE_SHARED 1
+#define VSD_MODE_EXCLUSIVE 2
+#define VSD_MODE_FORWARD 3
+#define VSD_ADDRESS_MASK 0x0ffffffffffff000ull
+#define VSD_MIGRATION_REG PPC_BITMASK(52, 55)
+#define VSD_INDIRECT PPC_BIT(56)
+#define VSD_TSIZE PPC_BITMASK(59, 63)
+#define VSD_FIRMWARE PPC_BIT(2) /* Read warning above */
+
+#define VC_EQC_SYNC_MASK \
+ (VC_EQC_CONF_SYNC_IPI | \
+ VC_EQC_CONF_SYNC_HW | \
+ VC_EQC_CONF_SYNC_ESC1 | \
+ VC_EQC_CONF_SYNC_ESC2 | \
+ VC_EQC_CONF_SYNC_REDI)
+
+
+#endif /* PPC_PNV_XIVE_REGS_H */
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index e0e5cb5d8e..097f88d460 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -117,7 +117,7 @@ static int spapr_xive_target_to_end(uint32_t target, uint8_t prio,
* On sPAPR machines, use a simplified output for the XIVE END
* structure dumping only the information related to the OS EQ.
*/
-static void spapr_xive_end_pic_print_info(sPAPRXive *xive, XiveEND *end,
+static void spapr_xive_end_pic_print_info(SpaprXive *xive, XiveEND *end,
Monitor *mon)
{
uint32_t qindex = xive_get_field32(END_W1_PAGE_OFF, end->w1);
@@ -135,7 +135,7 @@ static void spapr_xive_end_pic_print_info(sPAPRXive *xive, XiveEND *end,
monitor_printf(mon, "]");
}
-void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon)
+void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon)
{
XiveSource *xsrc = &xive->source;
int i;
@@ -173,14 +173,14 @@ void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon)
}
}
-static void spapr_xive_map_mmio(sPAPRXive *xive)
+static void spapr_xive_map_mmio(SpaprXive *xive)
{
sysbus_mmio_map(SYS_BUS_DEVICE(xive), 0, xive->vc_base);
sysbus_mmio_map(SYS_BUS_DEVICE(xive), 1, xive->end_base);
sysbus_mmio_map(SYS_BUS_DEVICE(xive), 2, xive->tm_base);
}
-void spapr_xive_mmio_set_enabled(sPAPRXive *xive, bool enable)
+void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable)
{
memory_region_set_enabled(&xive->source.esb_mmio, enable);
memory_region_set_enabled(&xive->tm_mmio, enable);
@@ -216,7 +216,7 @@ static void spapr_xive_end_reset(XiveEND *end)
static void spapr_xive_reset(void *dev)
{
- sPAPRXive *xive = SPAPR_XIVE(dev);
+ SpaprXive *xive = SPAPR_XIVE(dev);
int i;
/*
@@ -242,7 +242,7 @@ static void spapr_xive_reset(void *dev)
static void spapr_xive_instance_init(Object *obj)
{
- sPAPRXive *xive = SPAPR_XIVE(obj);
+ SpaprXive *xive = SPAPR_XIVE(obj);
object_initialize_child(obj, "source", &xive->source, sizeof(xive->source),
TYPE_XIVE_SOURCE, &error_abort, NULL);
@@ -254,7 +254,7 @@ static void spapr_xive_instance_init(Object *obj)
static void spapr_xive_realize(DeviceState *dev, Error **errp)
{
- sPAPRXive *xive = SPAPR_XIVE(dev);
+ SpaprXive *xive = SPAPR_XIVE(dev);
XiveSource *xsrc = &xive->source;
XiveENDSource *end_xsrc = &xive->end_source;
Error *local_err = NULL;
@@ -325,7 +325,7 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp)
static int spapr_xive_get_eas(XiveRouter *xrtr, uint8_t eas_blk,
uint32_t eas_idx, XiveEAS *eas)
{
- sPAPRXive *xive = SPAPR_XIVE(xrtr);
+ SpaprXive *xive = SPAPR_XIVE(xrtr);
if (eas_idx >= xive->nr_irqs) {
return -1;
@@ -338,7 +338,7 @@ static int spapr_xive_get_eas(XiveRouter *xrtr, uint8_t eas_blk,
static int spapr_xive_get_end(XiveRouter *xrtr,
uint8_t end_blk, uint32_t end_idx, XiveEND *end)
{
- sPAPRXive *xive = SPAPR_XIVE(xrtr);
+ SpaprXive *xive = SPAPR_XIVE(xrtr);
if (end_idx >= xive->nr_ends) {
return -1;
@@ -352,7 +352,7 @@ static int spapr_xive_write_end(XiveRouter *xrtr, uint8_t end_blk,
uint32_t end_idx, XiveEND *end,
uint8_t word_number)
{
- sPAPRXive *xive = SPAPR_XIVE(xrtr);
+ SpaprXive *xive = SPAPR_XIVE(xrtr);
if (end_idx >= xive->nr_ends) {
return -1;
@@ -432,20 +432,20 @@ static const VMStateDescription vmstate_spapr_xive = {
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
- VMSTATE_UINT32_EQUAL(nr_irqs, sPAPRXive, NULL),
- VMSTATE_STRUCT_VARRAY_POINTER_UINT32(eat, sPAPRXive, nr_irqs,
+ VMSTATE_UINT32_EQUAL(nr_irqs, SpaprXive, NULL),
+ VMSTATE_STRUCT_VARRAY_POINTER_UINT32(eat, SpaprXive, nr_irqs,
vmstate_spapr_xive_eas, XiveEAS),
- VMSTATE_STRUCT_VARRAY_POINTER_UINT32(endt, sPAPRXive, nr_ends,
+ VMSTATE_STRUCT_VARRAY_POINTER_UINT32(endt, SpaprXive, nr_ends,
vmstate_spapr_xive_end, XiveEND),
VMSTATE_END_OF_LIST()
},
};
static Property spapr_xive_properties[] = {
- DEFINE_PROP_UINT32("nr-irqs", sPAPRXive, nr_irqs, 0),
- DEFINE_PROP_UINT32("nr-ends", sPAPRXive, nr_ends, 0),
- DEFINE_PROP_UINT64("vc-base", sPAPRXive, vc_base, SPAPR_XIVE_VC_BASE),
- DEFINE_PROP_UINT64("tm-base", sPAPRXive, tm_base, SPAPR_XIVE_TM_BASE),
+ DEFINE_PROP_UINT32("nr-irqs", SpaprXive, nr_irqs, 0),
+ DEFINE_PROP_UINT32("nr-ends", SpaprXive, nr_ends, 0),
+ DEFINE_PROP_UINT64("vc-base", SpaprXive, vc_base, SPAPR_XIVE_VC_BASE),
+ DEFINE_PROP_UINT64("tm-base", SpaprXive, tm_base, SPAPR_XIVE_TM_BASE),
DEFINE_PROP_END_OF_LIST(),
};
@@ -471,7 +471,7 @@ static const TypeInfo spapr_xive_info = {
.name = TYPE_SPAPR_XIVE,
.parent = TYPE_XIVE_ROUTER,
.instance_init = spapr_xive_instance_init,
- .instance_size = sizeof(sPAPRXive),
+ .instance_size = sizeof(SpaprXive),
.class_init = spapr_xive_class_init,
};
@@ -482,7 +482,7 @@ static void spapr_xive_register_types(void)
type_init(spapr_xive_register_types)
-bool spapr_xive_irq_claim(sPAPRXive *xive, uint32_t lisn, bool lsi)
+bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
{
XiveSource *xsrc = &xive->source;
@@ -497,7 +497,7 @@ bool spapr_xive_irq_claim(sPAPRXive *xive, uint32_t lisn, bool lsi)
return true;
}
-bool spapr_xive_irq_free(sPAPRXive *xive, uint32_t lisn)
+bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn)
{
if (lisn >= xive->nr_irqs) {
return false;
@@ -576,11 +576,11 @@ static bool spapr_xive_priority_is_reserved(uint8_t priority)
#define SPAPR_XIVE_SRC_STORE_EOI PPC_BIT(63) /* Store EOI support */
static target_ulong h_int_get_source_info(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
- sPAPRXive *xive = spapr->xive;
+ SpaprXive *xive = spapr->xive;
XiveSource *xsrc = &xive->source;
target_ulong flags = args[0];
target_ulong lisn = args[1];
@@ -686,11 +686,11 @@ static target_ulong h_int_get_source_info(PowerPCCPU *cpu,
#define SPAPR_XIVE_SRC_MASK PPC_BIT(63)
static target_ulong h_int_set_source_config(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
- sPAPRXive *xive = spapr->xive;
+ SpaprXive *xive = spapr->xive;
XiveEAS eas, new_eas;
target_ulong flags = args[0];
target_ulong lisn = args[1];
@@ -783,11 +783,11 @@ out:
* equivalent to the LISN if not changed by H_INT_SET_SOURCE_CONFIG)
*/
static target_ulong h_int_get_source_config(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
- sPAPRXive *xive = spapr->xive;
+ SpaprXive *xive = spapr->xive;
target_ulong flags = args[0];
target_ulong lisn = args[1];
XiveEAS eas;
@@ -856,11 +856,11 @@ static target_ulong h_int_get_source_config(PowerPCCPU *cpu,
* - R5: Power of 2 page size of the notification page
*/
static target_ulong h_int_get_queue_info(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
- sPAPRXive *xive = spapr->xive;
+ SpaprXive *xive = spapr->xive;
XiveENDSource *end_xsrc = &xive->end_source;
target_ulong flags = args[0];
target_ulong target = args[1];
@@ -942,11 +942,11 @@ static target_ulong h_int_get_queue_info(PowerPCCPU *cpu,
#define SPAPR_XIVE_END_ALWAYS_NOTIFY PPC_BIT(63)
static target_ulong h_int_set_queue_config(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
- sPAPRXive *xive = spapr->xive;
+ SpaprXive *xive = spapr->xive;
target_ulong flags = args[0];
target_ulong target = args[1];
target_ulong priority = args[2];
@@ -1095,11 +1095,11 @@ out:
#define SPAPR_XIVE_END_DEBUG PPC_BIT(63)
static target_ulong h_int_get_queue_config(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
- sPAPRXive *xive = spapr->xive;
+ SpaprXive *xive = spapr->xive;
target_ulong flags = args[0];
target_ulong target = args[1];
target_ulong priority = args[2];
@@ -1187,7 +1187,7 @@ static target_ulong h_int_get_queue_config(PowerPCCPU *cpu,
* - None
*/
static target_ulong h_int_set_os_reporting_line(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
@@ -1223,7 +1223,7 @@ static target_ulong h_int_set_os_reporting_line(PowerPCCPU *cpu,
* - R4: The logical real address of the reporting line if set, else -1
*/
static target_ulong h_int_get_os_reporting_line(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
@@ -1266,11 +1266,11 @@ static target_ulong h_int_get_os_reporting_line(PowerPCCPU *cpu,
#define SPAPR_XIVE_ESB_STORE PPC_BIT(63)
static target_ulong h_int_esb(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
- sPAPRXive *xive = spapr->xive;
+ SpaprXive *xive = spapr->xive;
XiveEAS eas;
target_ulong flags = args[0];
target_ulong lisn = args[1];
@@ -1334,11 +1334,11 @@ static target_ulong h_int_esb(PowerPCCPU *cpu,
* - None
*/
static target_ulong h_int_sync(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
- sPAPRXive *xive = spapr->xive;
+ SpaprXive *xive = spapr->xive;
XiveEAS eas;
target_ulong flags = args[0];
target_ulong lisn = args[1];
@@ -1388,11 +1388,11 @@ static target_ulong h_int_sync(PowerPCCPU *cpu,
* - None
*/
static target_ulong h_int_reset(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
- sPAPRXive *xive = spapr->xive;
+ SpaprXive *xive = spapr->xive;
target_ulong flags = args[0];
if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
@@ -1407,7 +1407,7 @@ static target_ulong h_int_reset(PowerPCCPU *cpu,
return H_SUCCESS;
}
-void spapr_xive_hcall_init(sPAPRMachineState *spapr)
+void spapr_xive_hcall_init(SpaprMachineState *spapr)
{
spapr_register_hypercall(H_INT_GET_SOURCE_INFO, h_int_get_source_info);
spapr_register_hypercall(H_INT_SET_SOURCE_CONFIG, h_int_set_source_config);
@@ -1424,10 +1424,10 @@ void spapr_xive_hcall_init(sPAPRMachineState *spapr)
spapr_register_hypercall(H_INT_RESET, h_int_reset);
}
-void spapr_dt_xive(sPAPRMachineState *spapr, uint32_t nr_servers, void *fdt,
+void spapr_dt_xive(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
uint32_t phandle)
{
- sPAPRXive *xive = spapr->xive;
+ SpaprXive *xive = spapr->xive;
int node;
uint64_t timas[2 * 2];
/* Interrupt number ranges for the IPIs */
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index c6e1b630a4..78a252e6df 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -291,7 +291,7 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
}
}
-static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_dummy(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token,
uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets)
@@ -300,7 +300,7 @@ static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
__func__);
}
-int xics_kvm_init(sPAPRMachineState *spapr, Error **errp)
+int xics_kvm_init(SpaprMachineState *spapr, Error **errp)
{
int rc;
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 53bda6661b..607e1c167b 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -41,7 +41,7 @@
* Guest interfaces
*/
-static target_ulong h_cppr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_cppr(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong cppr = args[0];
@@ -50,7 +50,7 @@ static target_ulong h_cppr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-static target_ulong h_ipi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_ipi(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong mfrr = args[1];
@@ -64,7 +64,7 @@ static target_ulong h_ipi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_xirr(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);
@@ -73,7 +73,7 @@ static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_xirr_x(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);
@@ -83,7 +83,7 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-static target_ulong h_eoi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_eoi(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong xirr = args[0];
@@ -92,7 +92,7 @@ static target_ulong h_eoi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_ipoll(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
uint32_t mfrr;
@@ -104,7 +104,7 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_set_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token,
uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets)
@@ -137,7 +137,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
-static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_get_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token,
uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets)
@@ -167,7 +167,7 @@ static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
rtas_st(rets, 2, ics->irqs[srcno].priority);
}
-static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_int_off(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token,
uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets)
@@ -198,7 +198,7 @@ static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
-static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token,
uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets)
@@ -230,7 +230,7 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
-void xics_spapr_init(sPAPRMachineState *spapr)
+void xics_spapr_init(SpaprMachineState *spapr)
{
/* Registration of global state belongs into realize */
spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive);
@@ -246,7 +246,7 @@ void xics_spapr_init(sPAPRMachineState *spapr)
spapr_register_hypercall(H_IPOLL, h_ipoll);
}
-void spapr_dt_xics(sPAPRMachineState *spapr, uint32_t nr_servers, void *fdt,
+void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
uint32_t phandle)
{
uint32_t interrupt_server_ranges_prop[] = {
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index daa7badc84..a0b87001da 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -54,6 +54,8 @@ static uint8_t exception_mask(uint8_t ring)
switch (ring) {
case TM_QW1_OS:
return TM_QW1_NSR_EO;
+ case TM_QW3_HV_PHYS:
+ return TM_QW3_NSR_HE;
default:
g_assert_not_reached();
}
@@ -88,7 +90,16 @@ static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring)
uint8_t *regs = &tctx->regs[ring];
if (regs[TM_PIPR] < regs[TM_CPPR]) {
- regs[TM_NSR] |= exception_mask(ring);
+ switch (ring) {
+ case TM_QW1_OS:
+ regs[TM_NSR] |= TM_QW1_NSR_EO;
+ break;
+ case TM_QW3_HV_PHYS:
+ regs[TM_NSR] |= (TM_QW3_NSR_HE_PHYS << 6);
+ break;
+ default:
+ g_assert_not_reached();
+ }
qemu_irq_raise(tctx->output);
}
}
@@ -109,6 +120,38 @@ static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, uint8_t cppr)
* XIVE Thread Interrupt Management Area (TIMA)
*/
+static void xive_tm_set_hv_cppr(XiveTCTX *tctx, hwaddr offset,
+ uint64_t value, unsigned size)
+{
+ xive_tctx_set_cppr(tctx, TM_QW3_HV_PHYS, value & 0xff);
+}
+
+static uint64_t xive_tm_ack_hv_reg(XiveTCTX *tctx, hwaddr offset, unsigned size)
+{
+ return xive_tctx_accept(tctx, TM_QW3_HV_PHYS);
+}
+
+static uint64_t xive_tm_pull_pool_ctx(XiveTCTX *tctx, hwaddr offset,
+ unsigned size)
+{
+ uint64_t ret;
+
+ ret = tctx->regs[TM_QW2_HV_POOL + TM_WORD2] & TM_QW2W2_POOL_CAM;
+ tctx->regs[TM_QW2_HV_POOL + TM_WORD2] &= ~TM_QW2W2_POOL_CAM;
+ return ret;
+}
+
+static void xive_tm_vt_push(XiveTCTX *tctx, hwaddr offset,
+ uint64_t value, unsigned size)
+{
+ tctx->regs[TM_QW3_HV_PHYS + TM_WORD2] = value & 0xff;
+}
+
+static uint64_t xive_tm_vt_poll(XiveTCTX *tctx, hwaddr offset, unsigned size)
+{
+ return tctx->regs[TM_QW3_HV_PHYS + TM_WORD2] & 0xff;
+}
+
/*
* Define an access map for each page of the TIMA that we will use in
* the memory region ops to filter values when doing loads and stores
@@ -288,10 +331,16 @@ static const XiveTmOp xive_tm_operations[] = {
* effects
*/
{ XIVE_TM_OS_PAGE, TM_QW1_OS + TM_CPPR, 1, xive_tm_set_os_cppr, NULL },
+ { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_CPPR, 1, xive_tm_set_hv_cppr, NULL },
+ { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, xive_tm_vt_push, NULL },
+ { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, NULL, xive_tm_vt_poll },
/* MMIOs above 2K : special operations with side effects */
{ XIVE_TM_OS_PAGE, TM_SPC_ACK_OS_REG, 2, NULL, xive_tm_ack_os_reg },
{ XIVE_TM_OS_PAGE, TM_SPC_SET_OS_PENDING, 1, xive_tm_set_os_pending, NULL },
+ { XIVE_TM_HV_PAGE, TM_SPC_ACK_HV_REG, 2, NULL, xive_tm_ack_hv_reg },
+ { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX, 4, NULL, xive_tm_pull_pool_ctx },
+ { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX, 8, NULL, xive_tm_pull_pool_ctx },
};
static const XiveTmOp *xive_tm_find_op(hwaddr offset, unsigned size, bool write)
@@ -317,14 +366,13 @@ static const XiveTmOp *xive_tm_find_op(hwaddr offset, unsigned size, bool write)
/*
* TIMA MMIO handlers
*/
-static void xive_tm_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
+void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,
+ unsigned size)
{
- XiveTCTX *tctx = xive_router_get_tctx(XIVE_ROUTER(opaque), current_cpu);
const XiveTmOp *xto;
/*
- * TODO: check V bit in Q[0-3]W2, check PTER bit associated with CPU
+ * TODO: check V bit in Q[0-3]W2
*/
/*
@@ -356,13 +404,12 @@ static void xive_tm_write(void *opaque, hwaddr offset,
xive_tm_raw_write(tctx, offset, value, size);
}
-static uint64_t xive_tm_read(void *opaque, hwaddr offset, unsigned size)
+uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size)
{
- XiveTCTX *tctx = xive_router_get_tctx(XIVE_ROUTER(opaque), current_cpu);
const XiveTmOp *xto;
/*
- * TODO: check V bit in Q[0-3]W2, check PTER bit associated with CPU
+ * TODO: check V bit in Q[0-3]W2
*/
/*
@@ -392,6 +439,21 @@ static uint64_t xive_tm_read(void *opaque, hwaddr offset, unsigned size)
return xive_tm_raw_read(tctx, offset, size);
}
+static void xive_tm_write(void *opaque, hwaddr offset,
+ uint64_t value, unsigned size)
+{
+ XiveTCTX *tctx = xive_router_get_tctx(XIVE_ROUTER(opaque), current_cpu);
+
+ xive_tctx_tm_write(tctx, offset, value, size);
+}
+
+static uint64_t xive_tm_read(void *opaque, hwaddr offset, unsigned size)
+{
+ XiveTCTX *tctx = xive_router_get_tctx(XIVE_ROUTER(opaque), current_cpu);
+
+ return xive_tctx_tm_read(tctx, offset, size);
+}
+
const MemoryRegionOps xive_tm_ops = {
.read = xive_tm_read,
.write = xive_tm_write,
@@ -459,6 +521,8 @@ static void xive_tctx_reset(void *dev)
*/
tctx->regs[TM_QW1_OS + TM_PIPR] =
ipb_to_pipr(tctx->regs[TM_QW1_OS + TM_IPB]);
+ tctx->regs[TM_QW3_HV_PHYS + TM_PIPR] =
+ ipb_to_pipr(tctx->regs[TM_QW3_HV_PHYS + TM_IPB]);
}
static void xive_tctx_realize(DeviceState *dev, Error **errp)
@@ -1113,6 +1177,30 @@ XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, CPUState *cs)
}
/*
+ * By default on P9, the HW CAM line (23bits) is hardwired to :
+ *
+ * 0x000||0b1||4Bit chip number||7Bit Thread number.
+ *
+ * When the block grouping is enabled, the CAM line is changed to :
+ *
+ * 4Bit chip number||0x001||7Bit Thread number.
+ */
+static uint32_t hw_cam_line(uint8_t chip_id, uint8_t tid)
+{
+ return 1 << 11 | (chip_id & 0xf) << 7 | (tid & 0x7f);
+}
+
+static bool xive_presenter_tctx_match_hw(XiveTCTX *tctx,
+ uint8_t nvt_blk, uint32_t nvt_idx)
+{
+ CPUPPCState *env = &POWERPC_CPU(tctx->cs)->env;
+ uint32_t pir = env->spr_cb[SPR_PIR].default_value;
+
+ return hw_cam_line((pir >> 8) & 0xf, pir & 0x7f) ==
+ hw_cam_line(nvt_blk, nvt_idx);
+}
+
+/*
* The thread context register words are in big-endian format.
*/
static int xive_presenter_tctx_match(XiveTCTX *tctx, uint8_t format,
@@ -1120,6 +1208,7 @@ static int xive_presenter_tctx_match(XiveTCTX *tctx, uint8_t format,
bool cam_ignore, uint32_t logic_serv)
{
uint32_t cam = xive_nvt_cam_line(nvt_blk, nvt_idx);
+ uint32_t qw3w2 = xive_tctx_word2(&tctx->regs[TM_QW3_HV_PHYS]);
uint32_t qw2w2 = xive_tctx_word2(&tctx->regs[TM_QW2_HV_POOL]);
uint32_t qw1w2 = xive_tctx_word2(&tctx->regs[TM_QW1_OS]);
uint32_t qw0w2 = xive_tctx_word2(&tctx->regs[TM_QW0_USER]);
@@ -1142,7 +1231,11 @@ static int xive_presenter_tctx_match(XiveTCTX *tctx, uint8_t format,
/* F=0 & i=0: Specific NVT notification */
- /* TODO (PowerNV) : PHYS ring */
+ /* PHYS ring */
+ if ((be32_to_cpu(qw3w2) & TM_QW3W2_VT) &&
+ xive_presenter_tctx_match_hw(tctx, nvt_blk, nvt_idx)) {
+ return TM_QW3_HV_PHYS;
+ }
/* HV POOL ring */
if ((be32_to_cpu(qw2w2) & TM_QW2W2_VP) &&
@@ -1362,7 +1455,7 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk,
/* TODO: Auto EOI. */
}
-static void xive_router_notify(XiveNotifier *xn, uint32_t lisn)
+void xive_router_notify(XiveNotifier *xn, uint32_t lisn)
{
XiveRouter *xrtr = XIVE_ROUTER(xn);
uint8_t eas_blk = XIVE_SRCNO_BLOCK(lisn);
diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
index 599e0d4923..b820c9114b 100644
--- a/hw/lm32/lm32_boards.c
+++ b/hw/lm32/lm32_boards.c
@@ -113,9 +113,9 @@ static void lm32_evr_init(MachineState *machine)
dinfo = drive_get(IF_PFLASH, 0, 0);
/* Spansion S29NS128P */
- pflash_cfi02_register(flash_base, NULL, "lm32_evr.flash", flash_size,
+ pflash_cfi02_register(flash_base, "lm32_evr.flash", flash_size,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- flash_sector_size, flash_size / flash_sector_size,
+ flash_sector_size,
1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
/* create irq lines */
@@ -206,9 +206,9 @@ static void lm32_uclinux_init(MachineState *machine)
dinfo = drive_get(IF_PFLASH, 0, 0);
/* Spansion S29NS128P */
- pflash_cfi02_register(flash_base, NULL, "lm32_uclinux.flash", flash_size,
+ pflash_cfi02_register(flash_base, "lm32_uclinux.flash", flash_size,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- flash_sector_size, flash_size / flash_sector_size,
+ flash_sector_size,
1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
/* create irq lines */
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index 538f33b946..689e633199 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -120,10 +120,9 @@ milkymist_init(MachineState *machine)
dinfo = drive_get(IF_PFLASH, 0, 0);
/* Numonyx JS28F256J3F105 */
- pflash_cfi01_register(flash_base, NULL, "milkymist.flash", flash_size,
+ pflash_cfi01_register(flash_base, "milkymist.flash", flash_size,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- flash_sector_size, flash_size / flash_sector_size,
- 2, 0x00, 0x89, 0x00, 0x1d, 1);
+ flash_sector_size, 2, 0x00, 0x89, 0x00, 0x1d, 1);
/* create irq lines */
env->pic_state = lm32_pic_init(qemu_allocate_irq(cpu_irq_handler, cpu, 0));
diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
index 18048d3555..a907604116 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -106,11 +106,9 @@ petalogix_ml605_init(MachineState *machine)
dinfo = drive_get(IF_PFLASH, 0, 0);
/* 5th parameter 2 means bank-width
* 10th paremeter 0 means little-endian */
- pflash_cfi01_register(FLASH_BASEADDR,
- NULL, "petalogix_ml605.flash", FLASH_SIZE,
+ pflash_cfi01_register(FLASH_BASEADDR, "petalogix_ml605.flash", FLASH_SIZE,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- 64 * KiB, FLASH_SIZE >> 16,
- 2, 0x89, 0x18, 0x0000, 0x0, 0);
+ 64 * KiB, 2, 0x89, 0x18, 0x0000, 0x0, 0);
dev = qdev_create(NULL, "xlnx.xps-intc");
diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
index a0edaf867c..88ce570f9a 100644
--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
+++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
@@ -87,10 +87,9 @@ petalogix_s3adsp1800_init(MachineState *machine)
dinfo = drive_get(IF_PFLASH, 0, 0);
pflash_cfi01_register(FLASH_BASEADDR,
- NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE,
+ "petalogix_s3adsp1800.flash", FLASH_SIZE,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- 64 * KiB, FLASH_SIZE >> 16,
- 1, 0x89, 0x18, 0x0000, 0x0, 1);
+ 64 * KiB, 1, 0x89, 0x18, 0x0000, 0x0, 1);
dev = qdev_create(NULL, "xlnx.xps-intc");
qdev_prop_set_uint32(dev, "kind-of-intr",
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index fbbc543eed..9d7480ed31 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -287,6 +287,7 @@ static void mips_fulong2e_init(MachineState *machine)
I2CBus *smbus;
MIPSCPU *cpu;
CPUMIPSState *env;
+ DeviceState *dev;
/* init CPUs */
cpu = MIPS_CPU(cpu_create(machine->cpu_type));
@@ -347,6 +348,12 @@ static void mips_fulong2e_init(MachineState *machine)
vt82c686b_southbridge_init(pci_bus, FULONG2E_VIA_SLOT, env->irq[5],
&smbus, &isa_bus);
+ /* GPU */
+ dev = DEVICE(pci_create(pci_bus, -1, "ati-vga"));
+ qdev_prop_set_uint32(dev, "vgamem_mb", 16);
+ qdev_prop_set_uint16(dev, "x-device-id", 0x5159);
+ qdev_init_nofail(dev);
+
/* Populate SPD eeprom data */
spd_data = spd_data_generate(DDR, ram_size, &err);
if (err) {
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 39aef4b6db..439665ab45 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -58,8 +58,6 @@
#include "exec/semihost.h"
#include "hw/mips/cps.h"
-//#define DEBUG_BOARD_INIT
-
#define ENVP_ADDR 0x80002000l
#define ENVP_NB_ENTRIES 16
#define ENVP_ENTRY_SIZE 256
@@ -1189,13 +1187,12 @@ void mips_malta_init(MachineState *machine)
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
char *filename;
- pflash_t *fl;
+ PFlashCFI01 *fl;
MemoryRegion *system_memory = get_system_memory();
MemoryRegion *ram_high = g_new(MemoryRegion, 1);
MemoryRegion *ram_low_preio = g_new(MemoryRegion, 1);
MemoryRegion *ram_low_postio;
MemoryRegion *bios, *bios_copy = g_new(MemoryRegion, 1);
- target_long bios_size = FLASH_SIZE;
const size_t smbus_eeprom_size = 8 * 256;
uint8_t *smbus_eeprom_buf = g_malloc0(smbus_eeprom_size);
int64_t kernel_entry, bootloader_run_addr;
@@ -1208,7 +1205,6 @@ void mips_malta_init(MachineState *machine)
DriveInfo *dinfo;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
int fl_idx = 0;
- int fl_sectors = bios_size >> 16;
int be;
DeviceState *dev = qdev_create(NULL, TYPE_MIPS_MALTA);
@@ -1265,18 +1261,10 @@ void mips_malta_init(MachineState *machine)
/* Load firmware in flash / BIOS. */
dinfo = drive_get(IF_PFLASH, 0, fl_idx);
-#ifdef DEBUG_BOARD_INIT
- if (dinfo) {
- printf("Register parallel flash %d size " TARGET_FMT_lx " at "
- "addr %08llx '%s' %x\n",
- fl_idx, bios_size, FLASH_ADDRESS,
- blk_name(dinfo->bdrv), fl_sectors);
- }
-#endif
- fl = pflash_cfi01_register(FLASH_ADDRESS, NULL, "mips_malta.bios",
- BIOS_SIZE,
+ fl = pflash_cfi01_register(FLASH_ADDRESS, "mips_malta.bios",
+ FLASH_SIZE,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- 65536, fl_sectors,
+ 65536,
4, 0x0000, 0x0000, 0x0000, 0x0000, be);
bios = pflash_cfi01_get_memory(fl);
fl_idx++;
@@ -1312,6 +1300,7 @@ void mips_malta_init(MachineState *machine)
bootloader_run_addr, kernel_entry);
}
} else {
+ target_long bios_size = FLASH_SIZE;
/* The flash region isn't executable from a KVM guest */
if (kvm_enabled()) {
error_report("KVM enabled but no -kernel argument was specified. "
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index a015a6d14e..93dbf76bb4 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -235,10 +235,9 @@ void mips_r4k_init(MachineState *machine)
load_image_targphys(filename, 0x1fc00000, BIOS_SIZE);
} else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
uint32_t mips_rom = 0x00400000;
- if (!pflash_cfi01_register(0x1fc00000, NULL, "mips_r4k.bios", mips_rom,
+ if (!pflash_cfi01_register(0x1fc00000, "mips_r4k.bios", mips_rom,
blk_by_legacy_dinfo(dinfo),
- sector_len, mips_rom / sector_len,
- 4, 0, 0, 0, 0, be)) {
+ sector_len, 4, 0, 0, 0, 0, be)) {
fprintf(stderr, "qemu: Error registering flash memory.\n");
}
} else if (!qtest_enabled()) {
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
index d239e4bd7d..63ba3929e9 100644
--- a/hw/net/spapr_llan.c
+++ b/hw/net/spapr_llan.c
@@ -84,7 +84,7 @@ typedef uint64_t vlan_bd_t;
#define TYPE_VIO_SPAPR_VLAN_DEVICE "spapr-vlan"
#define VIO_SPAPR_VLAN_DEVICE(obj) \
- OBJECT_CHECK(VIOsPAPRVLANDevice, (obj), TYPE_VIO_SPAPR_VLAN_DEVICE)
+ OBJECT_CHECK(SpaprVioVlan, (obj), TYPE_VIO_SPAPR_VLAN_DEVICE)
#define RX_POOL_MAX_BDS 4096
#define RX_MAX_POOLS 5
@@ -95,8 +95,8 @@ typedef struct {
vlan_bd_t bds[RX_POOL_MAX_BDS];
} RxBufPool;
-typedef struct VIOsPAPRVLANDevice {
- VIOsPAPRDevice sdev;
+typedef struct SpaprVioVlan {
+ SpaprVioDevice sdev;
NICConf nicconf;
NICState *nic;
MACAddr perm_mac;
@@ -107,11 +107,11 @@ typedef struct VIOsPAPRVLANDevice {
QEMUTimer *rxp_timer;
uint32_t compat_flags; /* Compatibility flags for migration */
RxBufPool *rx_pool[RX_MAX_POOLS]; /* Receive buffer descriptor pools */
-} VIOsPAPRVLANDevice;
+} SpaprVioVlan;
static int spapr_vlan_can_receive(NetClientState *nc)
{
- VIOsPAPRVLANDevice *dev = qemu_get_nic_opaque(nc);
+ SpaprVioVlan *dev = qemu_get_nic_opaque(nc);
return (dev->isopen && dev->rx_bufs > 0);
}
@@ -123,7 +123,7 @@ static int spapr_vlan_can_receive(NetClientState *nc)
* suitable receive buffer available. This function is used to increase
* this counter by one.
*/
-static void spapr_vlan_record_dropped_rx_frame(VIOsPAPRVLANDevice *dev)
+static void spapr_vlan_record_dropped_rx_frame(SpaprVioVlan *dev)
{
uint64_t cnt;
@@ -134,7 +134,7 @@ static void spapr_vlan_record_dropped_rx_frame(VIOsPAPRVLANDevice *dev)
/**
* Get buffer descriptor from one of our receive buffer pools
*/
-static vlan_bd_t spapr_vlan_get_rx_bd_from_pool(VIOsPAPRVLANDevice *dev,
+static vlan_bd_t spapr_vlan_get_rx_bd_from_pool(SpaprVioVlan *dev,
size_t size)
{
vlan_bd_t bd;
@@ -168,7 +168,7 @@ static vlan_bd_t spapr_vlan_get_rx_bd_from_pool(VIOsPAPRVLANDevice *dev,
* Get buffer descriptor from the receive buffer list page that has been
* supplied by the guest with the H_REGISTER_LOGICAL_LAN call
*/
-static vlan_bd_t spapr_vlan_get_rx_bd_from_page(VIOsPAPRVLANDevice *dev,
+static vlan_bd_t spapr_vlan_get_rx_bd_from_page(SpaprVioVlan *dev,
size_t size)
{
int buf_ptr = dev->use_buf_ptr;
@@ -203,8 +203,8 @@ static vlan_bd_t spapr_vlan_get_rx_bd_from_page(VIOsPAPRVLANDevice *dev,
static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf,
size_t size)
{
- VIOsPAPRVLANDevice *dev = qemu_get_nic_opaque(nc);
- VIOsPAPRDevice *sdev = VIO_SPAPR_DEVICE(dev);
+ SpaprVioVlan *dev = qemu_get_nic_opaque(nc);
+ SpaprVioDevice *sdev = VIO_SPAPR_DEVICE(dev);
vlan_bd_t rxq_bd = vio_ldq(sdev, dev->buf_list + VLAN_RXQ_BD_OFF);
vlan_bd_t bd;
uint64_t handle;
@@ -280,7 +280,7 @@ static NetClientInfo net_spapr_vlan_info = {
static void spapr_vlan_flush_rx_queue(void *opaque)
{
- VIOsPAPRVLANDevice *dev = opaque;
+ SpaprVioVlan *dev = opaque;
qemu_flush_queued_packets(qemu_get_queue(dev->nic));
}
@@ -296,9 +296,9 @@ static void spapr_vlan_reset_rx_pool(RxBufPool *rxp)
memset(rxp->bds, 0, sizeof(rxp->bds));
}
-static void spapr_vlan_reset(VIOsPAPRDevice *sdev)
+static void spapr_vlan_reset(SpaprVioDevice *sdev)
{
- VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
+ SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
int i;
dev->buf_list = 0;
@@ -316,9 +316,9 @@ static void spapr_vlan_reset(VIOsPAPRDevice *sdev)
qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
}
-static void spapr_vlan_realize(VIOsPAPRDevice *sdev, Error **errp)
+static void spapr_vlan_realize(SpaprVioDevice *sdev, Error **errp)
{
- VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
+ SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
qemu_macaddr_default_if_unset(&dev->nicconf.macaddr);
@@ -334,7 +334,7 @@ static void spapr_vlan_realize(VIOsPAPRDevice *sdev, Error **errp)
static void spapr_vlan_instance_init(Object *obj)
{
- VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(obj);
+ SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(obj);
int i;
device_add_bootindex_property(obj, &dev->nicconf.bootindex,
@@ -351,7 +351,7 @@ static void spapr_vlan_instance_init(Object *obj)
static void spapr_vlan_instance_finalize(Object *obj)
{
- VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(obj);
+ SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(obj);
int i;
if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
@@ -367,7 +367,7 @@ static void spapr_vlan_instance_finalize(Object *obj)
}
}
-void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd)
+void spapr_vlan_create(SpaprVioBus *bus, NICInfo *nd)
{
DeviceState *dev;
@@ -378,9 +378,9 @@ void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd)
qdev_init_nofail(dev);
}
-static int spapr_vlan_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
+static int spapr_vlan_devnode(SpaprVioDevice *dev, void *fdt, int node_off)
{
- VIOsPAPRVLANDevice *vdev = VIO_SPAPR_VLAN_DEVICE(dev);
+ SpaprVioVlan *vdev = VIO_SPAPR_VLAN_DEVICE(dev);
uint8_t padded_mac[8] = {0, 0};
int ret;
@@ -415,7 +415,7 @@ static int spapr_vlan_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
return 0;
}
-static int check_bd(VIOsPAPRVLANDevice *dev, vlan_bd_t bd,
+static int check_bd(SpaprVioVlan *dev, vlan_bd_t bd,
target_ulong alignment)
{
if ((VLAN_BD_ADDR(bd) % alignment)
@@ -434,7 +434,7 @@ static int check_bd(VIOsPAPRVLANDevice *dev, vlan_bd_t bd,
}
static target_ulong h_register_logical_lan(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
@@ -442,8 +442,8 @@ static target_ulong h_register_logical_lan(PowerPCCPU *cpu,
target_ulong buf_list = args[1];
target_ulong rec_queue = args[2];
target_ulong filter_list = args[3];
- VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
- VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
+ SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+ SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
vlan_bd_t filter_list_bd;
if (!dev) {
@@ -500,12 +500,12 @@ static target_ulong h_register_logical_lan(PowerPCCPU *cpu,
static target_ulong h_free_logical_lan(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong reg = args[0];
- VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
- VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
+ SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+ SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
if (!dev) {
return H_PARAMETER;
@@ -539,7 +539,7 @@ static int rx_pool_size_compare(const void *p1, const void *p2)
* Search for a matching buffer pool with exact matching size,
* or return -1 if no matching pool has been found.
*/
-static int spapr_vlan_get_rx_pool_id(VIOsPAPRVLANDevice *dev, int size)
+static int spapr_vlan_get_rx_pool_id(SpaprVioVlan *dev, int size)
{
int pool;
@@ -555,7 +555,7 @@ static int spapr_vlan_get_rx_pool_id(VIOsPAPRVLANDevice *dev, int size)
/**
* Enqueuing receive buffer by adding it to one of our receive buffer pools
*/
-static target_long spapr_vlan_add_rxbuf_to_pool(VIOsPAPRVLANDevice *dev,
+static target_long spapr_vlan_add_rxbuf_to_pool(SpaprVioVlan *dev,
target_ulong buf)
{
int size = VLAN_BD_LEN(buf);
@@ -602,7 +602,7 @@ static target_long spapr_vlan_add_rxbuf_to_pool(VIOsPAPRVLANDevice *dev,
* This is the old way of enqueuing receive buffers: Add it to the rx queue
* page that has been supplied by the guest (which is quite limited in size).
*/
-static target_long spapr_vlan_add_rxbuf_to_page(VIOsPAPRVLANDevice *dev,
+static target_long spapr_vlan_add_rxbuf_to_page(SpaprVioVlan *dev,
target_ulong buf)
{
vlan_bd_t bd;
@@ -628,14 +628,14 @@ static target_long spapr_vlan_add_rxbuf_to_page(VIOsPAPRVLANDevice *dev,
}
static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
target_ulong reg = args[0];
target_ulong buf = args[1];
- VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
- VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
+ SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+ SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
target_long ret;
trace_spapr_vlan_h_add_logical_lan_buffer(reg, buf);
@@ -678,14 +678,14 @@ static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu,
}
static target_ulong h_send_logical_lan(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong reg = args[0];
target_ulong *bufs = args + 1;
target_ulong continue_token = args[7];
- VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
- VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
+ SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+ SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
unsigned total_len;
uint8_t *lbuf, *p;
int i, nbufs;
@@ -745,11 +745,11 @@ static target_ulong h_send_logical_lan(PowerPCCPU *cpu,
return H_SUCCESS;
}
-static target_ulong h_multicast_ctrl(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_multicast_ctrl(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong reg = args[0];
- VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+ SpaprVioDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
if (!dev) {
return H_PARAMETER;
@@ -759,14 +759,14 @@ static target_ulong h_multicast_ctrl(PowerPCCPU *cpu, sPAPRMachineState *spapr,
}
static target_ulong h_change_logical_lan_mac(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
target_ulong reg = args[0];
target_ulong macaddr = args[1];
- VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
- VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
+ SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+ SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
int i;
for (i = 0; i < ETH_ALEN; i++) {
@@ -780,16 +780,16 @@ static target_ulong h_change_logical_lan_mac(PowerPCCPU *cpu,
}
static Property spapr_vlan_properties[] = {
- DEFINE_SPAPR_PROPERTIES(VIOsPAPRVLANDevice, sdev),
- DEFINE_NIC_PROPERTIES(VIOsPAPRVLANDevice, nicconf),
- DEFINE_PROP_BIT("use-rx-buffer-pools", VIOsPAPRVLANDevice,
+ DEFINE_SPAPR_PROPERTIES(SpaprVioVlan, sdev),
+ DEFINE_NIC_PROPERTIES(SpaprVioVlan, nicconf),
+ DEFINE_PROP_BIT("use-rx-buffer-pools", SpaprVioVlan,
compat_flags, SPAPRVLAN_FLAG_RX_BUF_POOLS_BIT, true),
DEFINE_PROP_END_OF_LIST(),
};
static bool spapr_vlan_rx_buffer_pools_needed(void *opaque)
{
- VIOsPAPRVLANDevice *dev = opaque;
+ SpaprVioVlan *dev = opaque;
return (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) != 0;
}
@@ -813,7 +813,7 @@ static const VMStateDescription vmstate_rx_pools = {
.minimum_version_id = 1,
.needed = spapr_vlan_rx_buffer_pools_needed,
.fields = (VMStateField[]) {
- VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(rx_pool, VIOsPAPRVLANDevice,
+ VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(rx_pool, SpaprVioVlan,
RX_MAX_POOLS, 1,
vmstate_rx_buffer_pool, RxBufPool),
VMSTATE_END_OF_LIST()
@@ -825,14 +825,14 @@ static const VMStateDescription vmstate_spapr_llan = {
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
- VMSTATE_SPAPR_VIO(sdev, VIOsPAPRVLANDevice),
+ VMSTATE_SPAPR_VIO(sdev, SpaprVioVlan),
/* LLAN state */
- VMSTATE_BOOL(isopen, VIOsPAPRVLANDevice),
- VMSTATE_UINT64(buf_list, VIOsPAPRVLANDevice),
- VMSTATE_UINT32(add_buf_ptr, VIOsPAPRVLANDevice),
- VMSTATE_UINT32(use_buf_ptr, VIOsPAPRVLANDevice),
- VMSTATE_UINT32(rx_bufs, VIOsPAPRVLANDevice),
- VMSTATE_UINT64(rxq_ptr, VIOsPAPRVLANDevice),
+ VMSTATE_BOOL(isopen, SpaprVioVlan),
+ VMSTATE_UINT64(buf_list, SpaprVioVlan),
+ VMSTATE_UINT32(add_buf_ptr, SpaprVioVlan),
+ VMSTATE_UINT32(use_buf_ptr, SpaprVioVlan),
+ VMSTATE_UINT32(rx_bufs, SpaprVioVlan),
+ VMSTATE_UINT64(rxq_ptr, SpaprVioVlan),
VMSTATE_END_OF_LIST()
},
@@ -845,7 +845,7 @@ static const VMStateDescription vmstate_spapr_llan = {
static void spapr_vlan_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
+ SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
k->realize = spapr_vlan_realize;
k->reset = spapr_vlan_reset;
@@ -863,7 +863,7 @@ static void spapr_vlan_class_init(ObjectClass *klass, void *data)
static const TypeInfo spapr_vlan_info = {
.name = TYPE_VIO_SPAPR_VLAN_DEVICE,
.parent = TYPE_VIO_SPAPR_DEVICE,
- .instance_size = sizeof(VIOsPAPRVLANDevice),
+ .instance_size = sizeof(SpaprVioVlan),
.class_init = spapr_vlan_class_init,
.instance_init = spapr_vlan_instance_init,
.instance_finalize = spapr_vlan_instance_finalize,
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 7fdf04adc9..5c3a46ce6f 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -85,7 +85,7 @@ static char *read_splashfile(char *filename, gsize *file_sizep,
}
/* check magic ID */
- filehead = ((content[0] & 0xff) + (content[1] << 8)) & 0xffff;
+ filehead = lduw_le_p(content);
if (filehead == 0xd8ff) {
file_type = JPG_FILE;
} else if (filehead == 0x4d42) {
@@ -96,7 +96,7 @@ static char *read_splashfile(char *filename, gsize *file_sizep,
/* check BMP bpp */
if (file_type == BMP_FILE) {
- bmp_bpp = (content[28] + (content[29] << 8)) & 0xffff;
+ bmp_bpp = lduw_le_p(&content[28]);
if (bmp_bpp != 24) {
goto error;
}
@@ -161,15 +161,14 @@ static void fw_cfg_bootsplash(FWCfgState *s)
}
g_free(boot_splash_filedata);
boot_splash_filedata = (uint8_t *)file_data;
- boot_splash_filedata_size = file_size;
/* insert data */
if (file_type == JPG_FILE) {
fw_cfg_add_file(s, "bootsplash.jpg",
- boot_splash_filedata, boot_splash_filedata_size);
+ boot_splash_filedata, file_size);
} else {
fw_cfg_add_file(s, "bootsplash.bmp",
- boot_splash_filedata, boot_splash_filedata_size);
+ boot_splash_filedata, file_size);
}
g_free(filename);
}
diff --git a/hw/nvram/spapr_nvram.c b/hw/nvram/spapr_nvram.c
index bed1557d83..c98c7576e6 100644
--- a/hw/nvram/spapr_nvram.c
+++ b/hw/nvram/spapr_nvram.c
@@ -36,28 +36,28 @@
#include "hw/ppc/spapr.h"
#include "hw/ppc/spapr_vio.h"
-typedef struct sPAPRNVRAM {
- VIOsPAPRDevice sdev;
+typedef struct SpaprNvram {
+ SpaprVioDevice sdev;
uint32_t size;
uint8_t *buf;
BlockBackend *blk;
VMChangeStateEntry *vmstate;
-} sPAPRNVRAM;
+} SpaprNvram;
#define TYPE_VIO_SPAPR_NVRAM "spapr-nvram"
#define VIO_SPAPR_NVRAM(obj) \
- OBJECT_CHECK(sPAPRNVRAM, (obj), TYPE_VIO_SPAPR_NVRAM)
+ OBJECT_CHECK(SpaprNvram, (obj), TYPE_VIO_SPAPR_NVRAM)
#define MIN_NVRAM_SIZE (8 * KiB)
#define DEFAULT_NVRAM_SIZE (64 * KiB)
#define MAX_NVRAM_SIZE (1 * MiB)
-static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_nvram_fetch(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
{
- sPAPRNVRAM *nvram = spapr->nvram;
+ SpaprNvram *nvram = spapr->nvram;
hwaddr offset, buffer, len;
void *membuf;
@@ -93,12 +93,12 @@ static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPRMachineState *spapr,
rtas_st(rets, 1, len);
}
-static void rtas_nvram_store(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_nvram_store(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
{
- sPAPRNVRAM *nvram = spapr->nvram;
+ SpaprNvram *nvram = spapr->nvram;
hwaddr offset, buffer, len;
int alen;
void *membuf;
@@ -139,9 +139,9 @@ static void rtas_nvram_store(PowerPCCPU *cpu, sPAPRMachineState *spapr,
rtas_st(rets, 1, (alen < 0) ? 0 : alen);
}
-static void spapr_nvram_realize(VIOsPAPRDevice *dev, Error **errp)
+static void spapr_nvram_realize(SpaprVioDevice *dev, Error **errp)
{
- sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(dev);
+ SpaprNvram *nvram = VIO_SPAPR_NVRAM(dev);
int ret;
if (nvram->blk) {
@@ -193,16 +193,16 @@ static void spapr_nvram_realize(VIOsPAPRDevice *dev, Error **errp)
spapr_rtas_register(RTAS_NVRAM_STORE, "nvram-store", rtas_nvram_store);
}
-static int spapr_nvram_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
+static int spapr_nvram_devnode(SpaprVioDevice *dev, void *fdt, int node_off)
{
- sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(dev);
+ SpaprNvram *nvram = VIO_SPAPR_NVRAM(dev);
return fdt_setprop_cell(fdt, node_off, "#bytes", nvram->size);
}
static int spapr_nvram_pre_load(void *opaque)
{
- sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(opaque);
+ SpaprNvram *nvram = VIO_SPAPR_NVRAM(opaque);
g_free(nvram->buf);
nvram->buf = NULL;
@@ -213,7 +213,7 @@ static int spapr_nvram_pre_load(void *opaque)
static void postload_update_cb(void *opaque, int running, RunState state)
{
- sPAPRNVRAM *nvram = opaque;
+ SpaprNvram *nvram = opaque;
/* This is called after bdrv_invalidate_cache_all. */
@@ -225,7 +225,7 @@ static void postload_update_cb(void *opaque, int running, RunState state)
static int spapr_nvram_post_load(void *opaque, int version_id)
{
- sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(opaque);
+ SpaprNvram *nvram = VIO_SPAPR_NVRAM(opaque);
if (nvram->blk) {
nvram->vmstate = qemu_add_vm_change_state_handler(postload_update_cb,
@@ -242,22 +242,22 @@ static const VMStateDescription vmstate_spapr_nvram = {
.pre_load = spapr_nvram_pre_load,
.post_load = spapr_nvram_post_load,
.fields = (VMStateField[]) {
- VMSTATE_UINT32(size, sPAPRNVRAM),
- VMSTATE_VBUFFER_ALLOC_UINT32(buf, sPAPRNVRAM, 1, NULL, size),
+ VMSTATE_UINT32(size, SpaprNvram),
+ VMSTATE_VBUFFER_ALLOC_UINT32(buf, SpaprNvram, 1, NULL, size),
VMSTATE_END_OF_LIST()
},
};
static Property spapr_nvram_properties[] = {
- DEFINE_SPAPR_PROPERTIES(sPAPRNVRAM, sdev),
- DEFINE_PROP_DRIVE("drive", sPAPRNVRAM, blk),
+ DEFINE_SPAPR_PROPERTIES(SpaprNvram, sdev),
+ DEFINE_PROP_DRIVE("drive", SpaprNvram, blk),
DEFINE_PROP_END_OF_LIST(),
};
static void spapr_nvram_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
+ SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
k->realize = spapr_nvram_realize;
k->devnode = spapr_nvram_devnode;
@@ -274,7 +274,7 @@ static void spapr_nvram_class_init(ObjectClass *klass, void *data)
static const TypeInfo spapr_nvram_type_info = {
.name = TYPE_VIO_SPAPR_NVRAM,
.parent = TYPE_VIO_SPAPR_DEVICE,
- .instance_size = sizeof(sPAPRNVRAM),
+ .instance_size = sizeof(SpaprNvram),
.class_init = spapr_nvram_class_init,
};
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 7553f674c9..beb2efd694 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -42,6 +42,7 @@
#include "qemu/error-report.h"
#include "hw/platform-bus.h"
#include "hw/net/fsl_etsec/etsec.h"
+#include "hw/i2c/i2c.h"
#define EPAPR_MAGIC (0x45504150)
#define BINARY_DEVICE_TREE_FILE "mpc8544ds.dtb"
@@ -63,7 +64,10 @@
#define MPC8544_PCI_REGS_SIZE 0x1000ULL
#define MPC8544_UTIL_OFFSET 0xe0000ULL
#define MPC8XXX_GPIO_OFFSET 0x000FF000ULL
+#define MPC8544_I2C_REGS_OFFSET 0x3000ULL
#define MPC8XXX_GPIO_IRQ 47
+#define MPC8544_I2C_IRQ 43
+#define RTC_REGS_OFFSET 0x68
struct boot_info
{
@@ -161,6 +165,39 @@ static void create_dt_mpc8xxx_gpio(void *fdt, const char *soc, const char *mpic)
g_free(poweroff);
}
+static void dt_rtc_create(void *fdt, const char *i2c, const char *alias)
+{
+ int offset = RTC_REGS_OFFSET;
+
+ gchar *rtc = g_strdup_printf("%s/rtc@%"PRIx32, i2c, offset);
+ qemu_fdt_add_subnode(fdt, rtc);
+ qemu_fdt_setprop_string(fdt, rtc, "compatible", "pericom,pt7c4338");
+ qemu_fdt_setprop_cells(fdt, rtc, "reg", offset);
+ qemu_fdt_setprop_string(fdt, "/aliases", alias, rtc);
+
+ g_free(rtc);
+}
+
+static void dt_i2c_create(void *fdt, const char *soc, const char *mpic,
+ const char *alias)
+{
+ hwaddr mmio0 = MPC8544_I2C_REGS_OFFSET;
+ int irq0 = MPC8544_I2C_IRQ;
+
+ gchar *i2c = g_strdup_printf("%s/i2c@%"PRIx64, soc, mmio0);
+ qemu_fdt_add_subnode(fdt, i2c);
+ qemu_fdt_setprop_string(fdt, i2c, "device_type", "i2c");
+ qemu_fdt_setprop_string(fdt, i2c, "compatible", "fsl-i2c");
+ qemu_fdt_setprop_cells(fdt, i2c, "reg", mmio0, 0x14);
+ qemu_fdt_setprop_cells(fdt, i2c, "cell-index", 0);
+ qemu_fdt_setprop_cells(fdt, i2c, "interrupts", irq0, 0x2);
+ qemu_fdt_setprop_phandle(fdt, i2c, "interrupt-parent", mpic);
+ qemu_fdt_setprop_string(fdt, "/aliases", alias, i2c);
+
+ g_free(i2c);
+}
+
+
typedef struct PlatformDevtreeData {
void *fdt;
const char *mpic;
@@ -464,6 +501,12 @@ static int ppce500_load_device_tree(PPCE500MachineState *pms,
soc, mpic, "serial0", 0, true);
}
+ /* i2c */
+ dt_i2c_create(fdt, soc, mpic, "i2c");
+
+ dt_rtc_create(fdt, "i2c", "rtc");
+
+
gutil = g_strdup_printf("%s/global-utilities@%llx", soc,
MPC8544_UTIL_OFFSET);
qemu_fdt_add_subnode(fdt, gutil);
@@ -812,6 +855,7 @@ void ppce500_init(MachineState *machine)
MemoryRegion *ccsr_addr_space;
SysBusDevice *s;
PPCE500CCSRState *ccsr;
+ I2CBus *i2c;
irqs = g_new0(IrqLines, smp_cpus);
for (i = 0; i < smp_cpus; i++) {
@@ -887,6 +931,16 @@ void ppce500_init(MachineState *machine)
0, qdev_get_gpio_in(mpicdev, 42), 399193,
serial_hd(1), DEVICE_BIG_ENDIAN);
}
+ /* I2C */
+ dev = qdev_create(NULL, "mpc-i2c");
+ s = SYS_BUS_DEVICE(dev);
+ qdev_init_nofail(dev);
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(mpicdev, MPC8544_I2C_IRQ));
+ memory_region_add_subregion(ccsr_addr_space, MPC8544_I2C_REGS_OFFSET,
+ sysbus_mmio_get_region(s, 0));
+ i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
+ i2c_create_slave(i2c, "ds1338", RTC_REGS_OFFSET);
+
/* General Utility device */
dev = qdev_create(NULL, "mpc8544-guts");
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 97e8817145..02d8559621 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -547,11 +547,11 @@ static char *core99_fw_dev_path(FWPathProvider *p, BusState *bus,
return g_strdup("cdrom");
}
- return g_strdup("hd");
+ return g_strdup("disk");
}
if (!strcmp(object_get_typename(OBJECT(dev)), "ide-hd")) {
- return g_strdup("hd");
+ return g_strdup("disk");
}
if (!strcmp(object_get_typename(OBJECT(dev)), "ide-cd")) {
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index cc1e463466..460cbc7923 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -402,11 +402,11 @@ static char *heathrow_fw_dev_path(FWPathProvider *p, BusState *bus,
return g_strdup("cdrom");
}
- return g_strdup("hd");
+ return g_strdup("disk");
}
if (!strcmp(object_get_typename(OBJECT(dev)), "ide-hd")) {
- return g_strdup("hd");
+ return g_strdup("disk");
}
if (!strcmp(object_get_typename(OBJECT(dev)), "ide-cd")) {
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 3d5dfef220..8be4d4cbf7 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -267,7 +267,7 @@ static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir,
g_free(reg);
}
-static void pnv_dt_chip(PnvChip *chip, void *fdt)
+static void pnv_chip_power8_dt_populate(PnvChip *chip, void *fdt)
{
const char *typename = pnv_chip_core_typename(chip);
size_t typesize = object_type_get_instance_size(typename);
@@ -289,6 +289,27 @@ static void pnv_dt_chip(PnvChip *chip, void *fdt)
}
}
+static void pnv_chip_power9_dt_populate(PnvChip *chip, void *fdt)
+{
+ const char *typename = pnv_chip_core_typename(chip);
+ size_t typesize = object_type_get_instance_size(typename);
+ int i;
+
+ pnv_dt_xscom(chip, fdt, 0);
+
+ for (i = 0; i < chip->nr_cores; i++) {
+ PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
+
+ pnv_dt_core(chip, pnv_core, fdt);
+ }
+
+ if (chip->ram_size) {
+ pnv_dt_memory(fdt, chip->chip_id, chip->ram_start, chip->ram_size);
+ }
+
+ pnv_dt_lpc(chip, fdt, 0);
+}
+
static void pnv_dt_rtc(ISADevice *d, void *fdt, int lpc_off)
{
uint32_t io_base = d->ioport_id;
@@ -398,24 +419,12 @@ static int pnv_dt_isa_device(DeviceState *dev, void *opaque)
return 0;
}
-static int pnv_chip_isa_offset(PnvChip *chip, void *fdt)
-{
- char *name;
- int offset;
-
- name = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x",
- (uint64_t) PNV_XSCOM_BASE(chip), PNV_XSCOM_LPC_BASE);
- offset = fdt_path_offset(fdt, name);
- g_free(name);
- return offset;
-}
-
/* The default LPC bus of a multichip system is on chip 0. It's
* recognized by the firmware (skiboot) using a "primary" property.
*/
static void pnv_dt_isa(PnvMachineState *pnv, void *fdt)
{
- int isa_offset = pnv_chip_isa_offset(pnv->chips[0], fdt);
+ int isa_offset = fdt_path_offset(fdt, pnv->chips[0]->dt_isa_nodename);
ForeachPopulateArgs args = {
.fdt = fdt,
.offset = isa_offset,
@@ -429,6 +438,16 @@ static void pnv_dt_isa(PnvMachineState *pnv, void *fdt)
&args);
}
+static void pnv_dt_power_mgt(void *fdt)
+{
+ int off;
+
+ off = fdt_add_subnode(fdt, 0, "ibm,opal");
+ off = fdt_add_subnode(fdt, off, "power-mgt");
+
+ _FDT(fdt_setprop_cell(fdt, off, "ibm,enabled-stop-levels", 0xc0000000));
+}
+
static void *pnv_dt_create(MachineState *machine)
{
const char plat_compat[] = "qemu,powernv\0ibm,powernv";
@@ -474,7 +493,7 @@ static void *pnv_dt_create(MachineState *machine)
/* Populate device tree for each chip */
for (i = 0; i < pnv->num_chips; i++) {
- pnv_dt_chip(pnv->chips[i], fdt);
+ PNV_CHIP_GET_CLASS(pnv->chips[i])->dt_populate(pnv->chips[i], fdt);
}
/* Populate ISA devices on chip 0 */
@@ -484,6 +503,11 @@ static void *pnv_dt_create(MachineState *machine)
pnv_dt_bmc_sensors(pnv->bmc, fdt);
}
+ /* Create an extra node for power management on Power9 */
+ if (pnv_is_power9(pnv)) {
+ pnv_dt_power_mgt(fdt);
+ }
+
return fdt;
}
@@ -540,7 +564,8 @@ static ISABus *pnv_chip_power8nvl_isa_create(PnvChip *chip, Error **errp)
static ISABus *pnv_chip_power9_isa_create(PnvChip *chip, Error **errp)
{
- return NULL;
+ Pnv9Chip *chip9 = PNV9_CHIP(chip);
+ return pnv_lpc_isa_create(&chip9->lpc, false, errp);
}
static ISABus *pnv_isa_create(PnvChip *chip, Error **errp)
@@ -548,6 +573,21 @@ static ISABus *pnv_isa_create(PnvChip *chip, Error **errp)
return PNV_CHIP_GET_CLASS(chip)->isa_create(chip, errp);
}
+static void pnv_chip_power8_pic_print_info(PnvChip *chip, Monitor *mon)
+{
+ Pnv8Chip *chip8 = PNV8_CHIP(chip);
+
+ ics_pic_print_info(&chip8->psi.ics, mon);
+}
+
+static void pnv_chip_power9_pic_print_info(PnvChip *chip, Monitor *mon)
+{
+ Pnv9Chip *chip9 = PNV9_CHIP(chip);
+
+ pnv_xive_pic_print_info(&chip9->xive, mon);
+ pnv_psi_pic_print_info(&chip9->psi, mon);
+}
+
static void pnv_init(MachineState *machine)
{
PnvMachineState *pnv = PNV_MACHINE(machine);
@@ -684,7 +724,7 @@ static void pnv_chip_power8_intc_create(PnvChip *chip, PowerPCCPU *cpu,
return;
}
- pnv_cpu->icp = ICP(obj);
+ pnv_cpu->intc = obj;
}
/*
@@ -705,7 +745,23 @@ static uint32_t pnv_chip_core_pir_p9(PnvChip *chip, uint32_t core_id)
static void pnv_chip_power9_intc_create(PnvChip *chip, PowerPCCPU *cpu,
Error **errp)
{
- return;
+ Pnv9Chip *chip9 = PNV9_CHIP(chip);
+ Error *local_err = NULL;
+ Object *obj;
+ PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
+
+ /*
+ * The core creates its interrupt presenter but the XIVE interrupt
+ * controller object is initialized afterwards. Hopefully, it's
+ * only used at runtime.
+ */
+ obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(&chip9->xive), errp);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ pnv_cpu->intc = obj;
}
/* Allowed core identifiers on a POWER8 Processor Chip :
@@ -739,17 +795,17 @@ static void pnv_chip_power8_instance_init(Object *obj)
Pnv8Chip *chip8 = PNV8_CHIP(obj);
object_initialize_child(obj, "psi", &chip8->psi, sizeof(chip8->psi),
- TYPE_PNV_PSI, &error_abort, NULL);
+ TYPE_PNV8_PSI, &error_abort, NULL);
object_property_add_const_link(OBJECT(&chip8->psi), "xics",
OBJECT(qdev_get_machine()), &error_abort);
object_initialize_child(obj, "lpc", &chip8->lpc, sizeof(chip8->lpc),
- TYPE_PNV_LPC, &error_abort, NULL);
+ TYPE_PNV8_LPC, &error_abort, NULL);
object_property_add_const_link(OBJECT(&chip8->lpc), "psi",
OBJECT(&chip8->psi), &error_abort);
object_initialize_child(obj, "occ", &chip8->occ, sizeof(chip8->occ),
- TYPE_PNV_OCC, &error_abort, NULL);
+ TYPE_PNV8_OCC, &error_abort, NULL);
object_property_add_const_link(OBJECT(&chip8->occ), "psi",
OBJECT(&chip8->psi), &error_abort);
}
@@ -791,6 +847,7 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
PnvChip *chip = PNV_CHIP(dev);
Pnv8Chip *chip8 = PNV8_CHIP(dev);
+ Pnv8Psi *psi8 = &chip8->psi;
Error *local_err = NULL;
pcc->parent_realize(dev, &local_err);
@@ -807,13 +864,18 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
error_propagate(errp, local_err);
return;
}
- pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE, &chip8->psi.xscom_regs);
+ pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE,
+ &PNV_PSI(psi8)->xscom_regs);
/* Create LPC controller */
object_property_set_bool(OBJECT(&chip8->lpc), true, "realized",
&error_fatal);
pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip8->lpc.xscom_regs);
+ chip->dt_isa_nodename = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x",
+ (uint64_t) PNV_XSCOM_BASE(chip),
+ PNV_XSCOM_LPC_BASE);
+
/* Interrupt Management Area. This is the memory region holding
* all the Interrupt Control Presenter (ICP) registers */
pnv_chip_icp_realize(chip8, &local_err);
@@ -842,6 +904,8 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
k->core_pir = pnv_chip_core_pir_p8;
k->intc_create = pnv_chip_power8_intc_create;
k->isa_create = pnv_chip_power8_isa_create;
+ k->dt_populate = pnv_chip_power8_dt_populate;
+ k->pic_print_info = pnv_chip_power8_pic_print_info;
k->xscom_base = 0x003fc0000000000ull;
dc->desc = "PowerNV Chip POWER8E";
@@ -860,6 +924,8 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data)
k->core_pir = pnv_chip_core_pir_p8;
k->intc_create = pnv_chip_power8_intc_create;
k->isa_create = pnv_chip_power8_isa_create;
+ k->dt_populate = pnv_chip_power8_dt_populate;
+ k->pic_print_info = pnv_chip_power8_pic_print_info;
k->xscom_base = 0x003fc0000000000ull;
dc->desc = "PowerNV Chip POWER8";
@@ -878,6 +944,8 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
k->core_pir = pnv_chip_core_pir_p8;
k->intc_create = pnv_chip_power8_intc_create;
k->isa_create = pnv_chip_power8nvl_isa_create;
+ k->dt_populate = pnv_chip_power8_dt_populate;
+ k->pic_print_info = pnv_chip_power8_pic_print_info;
k->xscom_base = 0x003fc0000000000ull;
dc->desc = "PowerNV Chip POWER8NVL";
@@ -887,11 +955,65 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
static void pnv_chip_power9_instance_init(Object *obj)
{
+ Pnv9Chip *chip9 = PNV9_CHIP(obj);
+
+ object_initialize_child(obj, "xive", &chip9->xive, sizeof(chip9->xive),
+ TYPE_PNV_XIVE, &error_abort, NULL);
+ object_property_add_const_link(OBJECT(&chip9->xive), "chip", obj,
+ &error_abort);
+
+ object_initialize_child(obj, "psi", &chip9->psi, sizeof(chip9->psi),
+ TYPE_PNV9_PSI, &error_abort, NULL);
+ object_property_add_const_link(OBJECT(&chip9->psi), "chip", obj,
+ &error_abort);
+
+ object_initialize_child(obj, "lpc", &chip9->lpc, sizeof(chip9->lpc),
+ TYPE_PNV9_LPC, &error_abort, NULL);
+ object_property_add_const_link(OBJECT(&chip9->lpc), "psi",
+ OBJECT(&chip9->psi), &error_abort);
+
+ object_initialize_child(obj, "occ", &chip9->occ, sizeof(chip9->occ),
+ TYPE_PNV9_OCC, &error_abort, NULL);
+ object_property_add_const_link(OBJECT(&chip9->occ), "psi",
+ OBJECT(&chip9->psi), &error_abort);
+}
+
+static void pnv_chip_quad_realize(Pnv9Chip *chip9, Error **errp)
+{
+ PnvChip *chip = PNV_CHIP(chip9);
+ const char *typename = pnv_chip_core_typename(chip);
+ size_t typesize = object_type_get_instance_size(typename);
+ int i;
+
+ chip9->nr_quads = DIV_ROUND_UP(chip->nr_cores, 4);
+ chip9->quads = g_new0(PnvQuad, chip9->nr_quads);
+
+ for (i = 0; i < chip9->nr_quads; i++) {
+ char eq_name[32];
+ PnvQuad *eq = &chip9->quads[i];
+ PnvCore *pnv_core = PNV_CORE(chip->cores + (i * 4) * typesize);
+ int core_id = CPU_CORE(pnv_core)->core_id;
+
+ object_initialize(eq, sizeof(*eq), TYPE_PNV_QUAD);
+ snprintf(eq_name, sizeof(eq_name), "eq[%d]", core_id);
+
+ object_property_add_child(OBJECT(chip), eq_name, OBJECT(eq),
+ &error_fatal);
+ object_property_set_int(OBJECT(eq), core_id, "id", &error_fatal);
+ object_property_set_bool(OBJECT(eq), true, "realized", &error_fatal);
+ object_unref(OBJECT(eq));
+
+ pnv_xscom_add_subregion(chip, PNV9_XSCOM_EQ_BASE(eq->id),
+ &eq->xscom_regs);
+ }
}
static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
{
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
+ Pnv9Chip *chip9 = PNV9_CHIP(dev);
+ PnvChip *chip = PNV_CHIP(dev);
+ Pnv9Psi *psi9 = &chip9->psi;
Error *local_err = NULL;
pcc->parent_realize(dev, &local_err);
@@ -899,6 +1021,61 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
error_propagate(errp, local_err);
return;
}
+
+ pnv_chip_quad_realize(chip9, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ /* XIVE interrupt controller (POWER9) */
+ object_property_set_int(OBJECT(&chip9->xive), PNV9_XIVE_IC_BASE(chip),
+ "ic-bar", &error_fatal);
+ object_property_set_int(OBJECT(&chip9->xive), PNV9_XIVE_VC_BASE(chip),
+ "vc-bar", &error_fatal);
+ object_property_set_int(OBJECT(&chip9->xive), PNV9_XIVE_PC_BASE(chip),
+ "pc-bar", &error_fatal);
+ object_property_set_int(OBJECT(&chip9->xive), PNV9_XIVE_TM_BASE(chip),
+ "tm-bar", &error_fatal);
+ object_property_set_bool(OBJECT(&chip9->xive), true, "realized",
+ &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ pnv_xscom_add_subregion(chip, PNV9_XSCOM_XIVE_BASE,
+ &chip9->xive.xscom_regs);
+
+ /* Processor Service Interface (PSI) Host Bridge */
+ object_property_set_int(OBJECT(&chip9->psi), PNV9_PSIHB_BASE(chip),
+ "bar", &error_fatal);
+ object_property_set_bool(OBJECT(&chip9->psi), true, "realized", &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ pnv_xscom_add_subregion(chip, PNV9_XSCOM_PSIHB_BASE,
+ &PNV_PSI(psi9)->xscom_regs);
+
+ /* LPC */
+ object_property_set_bool(OBJECT(&chip9->lpc), true, "realized", &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ memory_region_add_subregion(get_system_memory(), PNV9_LPCM_BASE(chip),
+ &chip9->lpc.xscom_regs);
+
+ chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0",
+ (uint64_t) PNV9_LPCM_BASE(chip));
+
+ /* Create the simplified OCC model */
+ object_property_set_bool(OBJECT(&chip9->occ), true, "realized", &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ pnv_xscom_add_subregion(chip, PNV9_XSCOM_OCC_BASE, &chip9->occ.xscom_regs);
}
static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
@@ -912,6 +1089,8 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
k->core_pir = pnv_chip_core_pir_p9;
k->intc_create = pnv_chip_power9_intc_create;
k->isa_create = pnv_chip_power9_isa_create;
+ k->dt_populate = pnv_chip_power9_dt_populate;
+ k->pic_print_info = pnv_chip_power9_pic_print_info;
k->xscom_base = 0x00603fc00000000ull;
dc->desc = "PowerNV Chip POWER9";
@@ -1007,7 +1186,7 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
if (!pnv_chip_is_power9(chip)) {
xscom_core_base = PNV_XSCOM_EX_BASE(core_hwid);
} else {
- xscom_core_base = PNV_XSCOM_P9_EC_BASE(core_hwid);
+ xscom_core_base = PNV9_XSCOM_EC_BASE(core_hwid);
}
pnv_xscom_add_subregion(chip, xscom_core_base,
@@ -1082,27 +1261,11 @@ static void pnv_ics_resend(XICSFabric *xi)
}
}
-static PowerPCCPU *ppc_get_vcpu_by_pir(int pir)
-{
- CPUState *cs;
-
- CPU_FOREACH(cs) {
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
-
- if (env->spr_cb[SPR_PIR].default_value == pir) {
- return cpu;
- }
- }
-
- return NULL;
-}
-
static ICPState *pnv_icp_get(XICSFabric *xi, int pir)
{
PowerPCCPU *cpu = ppc_get_vcpu_by_pir(pir);
- return cpu ? pnv_cpu_state(cpu)->icp : NULL;
+ return cpu ? ICP(pnv_cpu_state(cpu)->intc) : NULL;
}
static void pnv_pic_print_info(InterruptStatsProvider *obj,
@@ -1115,12 +1278,15 @@ static void pnv_pic_print_info(InterruptStatsProvider *obj,
CPU_FOREACH(cs) {
PowerPCCPU *cpu = POWERPC_CPU(cs);
- icp_pic_print_info(pnv_cpu_state(cpu)->icp, mon);
+ if (pnv_chip_is_power9(pnv->chips[0])) {
+ xive_tctx_pic_print_info(XIVE_TCTX(pnv_cpu_state(cpu)->intc), mon);
+ } else {
+ icp_pic_print_info(ICP(pnv_cpu_state(cpu)->intc), mon);
+ }
}
for (i = 0; i < pnv->num_chips; i++) {
- Pnv8Chip *chip8 = PNV8_CHIP(pnv->chips[i]);
- ics_pic_print_info(&chip8->psi.ics, mon);
+ PNV_CHIP_GET_CLASS(pnv->chips[i])->pic_print_info(pnv->chips[i], mon);
}
}
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 7c806da720..5feeed6bc4 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -60,8 +60,8 @@ static void pnv_cpu_reset(void *opaque)
#define PNV_XSCOM_EX_DTS_RESULT0 0x50000
#define PNV_XSCOM_EX_DTS_RESULT1 0x50001
-static uint64_t pnv_core_xscom_read(void *opaque, hwaddr addr,
- unsigned int width)
+static uint64_t pnv_core_power8_xscom_read(void *opaque, hwaddr addr,
+ unsigned int width)
{
uint32_t offset = addr >> 3;
uint64_t val = 0;
@@ -82,16 +82,74 @@ static uint64_t pnv_core_xscom_read(void *opaque, hwaddr addr,
return val;
}
-static void pnv_core_xscom_write(void *opaque, hwaddr addr, uint64_t val,
- unsigned int width)
+static void pnv_core_power8_xscom_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned int width)
{
qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx "\n",
addr);
}
-static const MemoryRegionOps pnv_core_xscom_ops = {
- .read = pnv_core_xscom_read,
- .write = pnv_core_xscom_write,
+static const MemoryRegionOps pnv_core_power8_xscom_ops = {
+ .read = pnv_core_power8_xscom_read,
+ .write = pnv_core_power8_xscom_write,
+ .valid.min_access_size = 8,
+ .valid.max_access_size = 8,
+ .impl.min_access_size = 8,
+ .impl.max_access_size = 8,
+ .endianness = DEVICE_BIG_ENDIAN,
+};
+
+
+/*
+ * POWER9 core controls
+ */
+#define PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_HYP 0xf010d
+#define PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR 0xf010a
+
+static uint64_t pnv_core_power9_xscom_read(void *opaque, hwaddr addr,
+ unsigned int width)
+{
+ uint32_t offset = addr >> 3;
+ uint64_t val = 0;
+
+ /* The result should be 38 C */
+ switch (offset) {
+ case PNV_XSCOM_EX_DTS_RESULT0:
+ val = 0x26f024f023f0000ull;
+ break;
+ case PNV_XSCOM_EX_DTS_RESULT1:
+ val = 0x24f000000000000ull;
+ break;
+ case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_HYP:
+ case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR:
+ val = 0x0;
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx "\n",
+ addr);
+ }
+
+ return val;
+}
+
+static void pnv_core_power9_xscom_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned int width)
+{
+ uint32_t offset = addr >> 3;
+
+ switch (offset) {
+ case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_HYP:
+ case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR:
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx "\n",
+ addr);
+ }
+}
+
+static const MemoryRegionOps pnv_core_power9_xscom_ops = {
+ .read = pnv_core_power9_xscom_read,
+ .write = pnv_core_power9_xscom_write,
.valid.min_access_size = 8,
.valid.max_access_size = 8,
.impl.min_access_size = 8,
@@ -138,6 +196,7 @@ static void pnv_realize_vcpu(PowerPCCPU *cpu, PnvChip *chip, Error **errp)
static void pnv_core_realize(DeviceState *dev, Error **errp)
{
PnvCore *pc = PNV_CORE(OBJECT(dev));
+ PnvCoreClass *pcc = PNV_CORE_GET_CLASS(pc);
CPUCore *cc = CPU_CORE(OBJECT(dev));
const char *typename = pnv_core_cpu_typename(pc);
Error *local_err = NULL;
@@ -180,7 +239,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
}
snprintf(name, sizeof(name), "xscom-core.%d", cc->core_id);
- pnv_xscom_region_init(&pc->xscom_regs, OBJECT(dev), &pnv_core_xscom_ops,
+ pnv_xscom_region_init(&pc->xscom_regs, OBJECT(dev), pcc->xscom_ops,
pc, name, PNV_XSCOM_EX_SIZE);
return;
@@ -198,7 +257,7 @@ static void pnv_unrealize_vcpu(PowerPCCPU *cpu)
PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
qemu_unregister_reset(pnv_cpu_reset, cpu);
- object_unparent(OBJECT(pnv_cpu_state(cpu)->icp));
+ object_unparent(OBJECT(pnv_cpu_state(cpu)->intc));
cpu_remove_sync(CPU(cpu));
cpu->machine_data = NULL;
g_free(pnv_cpu);
@@ -222,6 +281,20 @@ static Property pnv_core_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};
+static void pnv_core_power8_class_init(ObjectClass *oc, void *data)
+{
+ PnvCoreClass *pcc = PNV_CORE_CLASS(oc);
+
+ pcc->xscom_ops = &pnv_core_power8_xscom_ops;
+}
+
+static void pnv_core_power9_class_init(ObjectClass *oc, void *data)
+{
+ PnvCoreClass *pcc = PNV_CORE_CLASS(oc);
+
+ pcc->xscom_ops = &pnv_core_power9_xscom_ops;
+}
+
static void pnv_core_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
@@ -231,10 +304,11 @@ static void pnv_core_class_init(ObjectClass *oc, void *data)
dc->props = pnv_core_properties;
}
-#define DEFINE_PNV_CORE_TYPE(cpu_model) \
+#define DEFINE_PNV_CORE_TYPE(family, cpu_model) \
{ \
.parent = TYPE_PNV_CORE, \
.name = PNV_CORE_TYPE_NAME(cpu_model), \
+ .class_init = pnv_core_##family##_class_init, \
}
static const TypeInfo pnv_core_infos[] = {
@@ -246,10 +320,97 @@ static const TypeInfo pnv_core_infos[] = {
.class_init = pnv_core_class_init,
.abstract = true,
},
- DEFINE_PNV_CORE_TYPE("power8e_v2.1"),
- DEFINE_PNV_CORE_TYPE("power8_v2.0"),
- DEFINE_PNV_CORE_TYPE("power8nvl_v1.0"),
- DEFINE_PNV_CORE_TYPE("power9_v2.0"),
+ DEFINE_PNV_CORE_TYPE(power8, "power8e_v2.1"),
+ DEFINE_PNV_CORE_TYPE(power8, "power8_v2.0"),
+ DEFINE_PNV_CORE_TYPE(power8, "power8nvl_v1.0"),
+ DEFINE_PNV_CORE_TYPE(power9, "power9_v2.0"),
};
DEFINE_TYPES(pnv_core_infos)
+
+/*
+ * POWER9 Quads
+ */
+
+#define P9X_EX_NCU_SPEC_BAR 0x11010
+
+static uint64_t pnv_quad_xscom_read(void *opaque, hwaddr addr,
+ unsigned int width)
+{
+ uint32_t offset = addr >> 3;
+ uint64_t val = -1;
+
+ switch (offset) {
+ case P9X_EX_NCU_SPEC_BAR:
+ case P9X_EX_NCU_SPEC_BAR + 0x400: /* Second EX */
+ val = 0;
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "%s: writing @0x%08x\n", __func__,
+ offset);
+ }
+
+ return val;
+}
+
+static void pnv_quad_xscom_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned int width)
+{
+ uint32_t offset = addr >> 3;
+
+ switch (offset) {
+ case P9X_EX_NCU_SPEC_BAR:
+ case P9X_EX_NCU_SPEC_BAR + 0x400: /* Second EX */
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "%s: writing @0x%08x\n", __func__,
+ offset);
+ }
+}
+
+static const MemoryRegionOps pnv_quad_xscom_ops = {
+ .read = pnv_quad_xscom_read,
+ .write = pnv_quad_xscom_write,
+ .valid.min_access_size = 8,
+ .valid.max_access_size = 8,
+ .impl.min_access_size = 8,
+ .impl.max_access_size = 8,
+ .endianness = DEVICE_BIG_ENDIAN,
+};
+
+static void pnv_quad_realize(DeviceState *dev, Error **errp)
+{
+ PnvQuad *eq = PNV_QUAD(dev);
+ char name[32];
+
+ snprintf(name, sizeof(name), "xscom-quad.%d", eq->id);
+ pnv_xscom_region_init(&eq->xscom_regs, OBJECT(dev), &pnv_quad_xscom_ops,
+ eq, name, PNV9_XSCOM_EQ_SIZE);
+}
+
+static Property pnv_quad_properties[] = {
+ DEFINE_PROP_UINT32("id", PnvQuad, id, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pnv_quad_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ dc->realize = pnv_quad_realize;
+ dc->props = pnv_quad_properties;
+}
+
+static const TypeInfo pnv_quad_info = {
+ .name = TYPE_PNV_QUAD,
+ .parent = TYPE_DEVICE,
+ .instance_size = sizeof(PnvQuad),
+ .class_init = pnv_quad_class_init,
+};
+
+static void pnv_core_register_types(void)
+{
+ type_register_static(&pnv_quad_info);
+}
+
+type_init(pnv_core_register_types)
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index 172a915cfc..641e2046db 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -39,6 +39,8 @@ enum {
};
/* OPB Master LS registers */
+#define OPB_MASTER_LS_ROUTE0 0x8
+#define OPB_MASTER_LS_ROUTE1 0xC
#define OPB_MASTER_LS_IRQ_STAT 0x50
#define OPB_MASTER_IRQ_LPC 0x00000800
#define OPB_MASTER_LS_IRQ_MASK 0x54
@@ -89,10 +91,11 @@ enum {
#define LPC_FW_OPB_SIZE 0x10000000
#define LPC_OPB_REGS_OPB_ADDR 0xc0010000
-#define LPC_OPB_REGS_OPB_SIZE 0x00002000
+#define LPC_OPB_REGS_OPB_SIZE 0x00000060
+#define LPC_OPB_REGS_OPBA_ADDR 0xc0011000
+#define LPC_OPB_REGS_OPBA_SIZE 0x00000008
#define LPC_HC_REGS_OPB_ADDR 0xc0012000
-#define LPC_HC_REGS_OPB_SIZE 0x00001000
-
+#define LPC_HC_REGS_OPB_SIZE 0x00000100
static int pnv_lpc_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
{
@@ -117,6 +120,100 @@ static int pnv_lpc_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
return 0;
}
+/* POWER9 only */
+int pnv_dt_lpc(PnvChip *chip, void *fdt, int root_offset)
+{
+ const char compat[] = "ibm,power9-lpcm-opb\0simple-bus";
+ const char lpc_compat[] = "ibm,power9-lpc\0ibm,lpc";
+ char *name;
+ int offset, lpcm_offset;
+ uint64_t lpcm_addr = PNV9_LPCM_BASE(chip);
+ uint32_t opb_ranges[8] = { 0,
+ cpu_to_be32(lpcm_addr >> 32),
+ cpu_to_be32((uint32_t)lpcm_addr),
+ cpu_to_be32(PNV9_LPCM_SIZE / 2),
+ cpu_to_be32(PNV9_LPCM_SIZE / 2),
+ cpu_to_be32(lpcm_addr >> 32),
+ cpu_to_be32(PNV9_LPCM_SIZE / 2),
+ cpu_to_be32(PNV9_LPCM_SIZE / 2),
+ };
+ uint32_t opb_reg[4] = { cpu_to_be32(lpcm_addr >> 32),
+ cpu_to_be32((uint32_t)lpcm_addr),
+ cpu_to_be32(PNV9_LPCM_SIZE >> 32),
+ cpu_to_be32((uint32_t)PNV9_LPCM_SIZE),
+ };
+ uint32_t reg[2];
+
+ /*
+ * OPB bus
+ */
+ name = g_strdup_printf("lpcm-opb@%"PRIx64, lpcm_addr);
+ lpcm_offset = fdt_add_subnode(fdt, root_offset, name);
+ _FDT(lpcm_offset);
+ g_free(name);
+
+ _FDT((fdt_setprop(fdt, lpcm_offset, "reg", opb_reg, sizeof(opb_reg))));
+ _FDT((fdt_setprop_cell(fdt, lpcm_offset, "#address-cells", 1)));
+ _FDT((fdt_setprop_cell(fdt, lpcm_offset, "#size-cells", 1)));
+ _FDT((fdt_setprop(fdt, lpcm_offset, "compatible", compat, sizeof(compat))));
+ _FDT((fdt_setprop_cell(fdt, lpcm_offset, "ibm,chip-id", chip->chip_id)));
+ _FDT((fdt_setprop(fdt, lpcm_offset, "ranges", opb_ranges,
+ sizeof(opb_ranges))));
+
+ /*
+ * OPB Master registers
+ */
+ name = g_strdup_printf("opb-master@%x", LPC_OPB_REGS_OPB_ADDR);
+ offset = fdt_add_subnode(fdt, lpcm_offset, name);
+ _FDT(offset);
+ g_free(name);
+
+ reg[0] = cpu_to_be32(LPC_OPB_REGS_OPB_ADDR);
+ reg[1] = cpu_to_be32(LPC_OPB_REGS_OPB_SIZE);
+ _FDT((fdt_setprop(fdt, offset, "reg", reg, sizeof(reg))));
+ _FDT((fdt_setprop_string(fdt, offset, "compatible",
+ "ibm,power9-lpcm-opb-master")));
+
+ /*
+ * OPB arbitrer registers
+ */
+ name = g_strdup_printf("opb-arbitrer@%x", LPC_OPB_REGS_OPBA_ADDR);
+ offset = fdt_add_subnode(fdt, lpcm_offset, name);
+ _FDT(offset);
+ g_free(name);
+
+ reg[0] = cpu_to_be32(LPC_OPB_REGS_OPBA_ADDR);
+ reg[1] = cpu_to_be32(LPC_OPB_REGS_OPBA_SIZE);
+ _FDT((fdt_setprop(fdt, offset, "reg", reg, sizeof(reg))));
+ _FDT((fdt_setprop_string(fdt, offset, "compatible",
+ "ibm,power9-lpcm-opb-arbiter")));
+
+ /*
+ * LPC Host Controller registers
+ */
+ name = g_strdup_printf("lpc-controller@%x", LPC_HC_REGS_OPB_ADDR);
+ offset = fdt_add_subnode(fdt, lpcm_offset, name);
+ _FDT(offset);
+ g_free(name);
+
+ reg[0] = cpu_to_be32(LPC_HC_REGS_OPB_ADDR);
+ reg[1] = cpu_to_be32(LPC_HC_REGS_OPB_SIZE);
+ _FDT((fdt_setprop(fdt, offset, "reg", reg, sizeof(reg))));
+ _FDT((fdt_setprop_string(fdt, offset, "compatible",
+ "ibm,power9-lpc-controller")));
+
+ name = g_strdup_printf("lpc@0");
+ offset = fdt_add_subnode(fdt, lpcm_offset, name);
+ _FDT(offset);
+ g_free(name);
+ _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 2)));
+ _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 1)));
+ _FDT((fdt_setprop(fdt, offset, "compatible", lpc_compat,
+ sizeof(lpc_compat))));
+
+ return 0;
+}
+
/*
* These read/write handlers of the OPB address space should be common
* with the P9 LPC Controller which uses direct MMIOs.
@@ -241,9 +338,78 @@ static const MemoryRegionOps pnv_lpc_xscom_ops = {
.endianness = DEVICE_BIG_ENDIAN,
};
+static uint64_t pnv_lpc_mmio_read(void *opaque, hwaddr addr, unsigned size)
+{
+ PnvLpcController *lpc = PNV_LPC(opaque);
+ uint64_t val = 0;
+ uint32_t opb_addr = addr & ECCB_CTL_ADDR_MASK;
+ MemTxResult result;
+
+ switch (size) {
+ case 4:
+ val = address_space_ldl(&lpc->opb_as, opb_addr, MEMTXATTRS_UNSPECIFIED,
+ &result);
+ break;
+ case 1:
+ val = address_space_ldub(&lpc->opb_as, opb_addr, MEMTXATTRS_UNSPECIFIED,
+ &result);
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "OPB read failed at @0x%"
+ HWADDR_PRIx " invalid size %d\n", addr, size);
+ return 0;
+ }
+
+ if (result != MEMTX_OK) {
+ qemu_log_mask(LOG_GUEST_ERROR, "OPB read failed at @0x%"
+ HWADDR_PRIx "\n", addr);
+ }
+
+ return val;
+}
+
+static void pnv_lpc_mmio_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ PnvLpcController *lpc = PNV_LPC(opaque);
+ uint32_t opb_addr = addr & ECCB_CTL_ADDR_MASK;
+ MemTxResult result;
+
+ switch (size) {
+ case 4:
+ address_space_stl(&lpc->opb_as, opb_addr, val, MEMTXATTRS_UNSPECIFIED,
+ &result);
+ break;
+ case 1:
+ address_space_stb(&lpc->opb_as, opb_addr, val, MEMTXATTRS_UNSPECIFIED,
+ &result);
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "OPB write failed at @0x%"
+ HWADDR_PRIx " invalid size %d\n", addr, size);
+ return;
+ }
+
+ if (result != MEMTX_OK) {
+ qemu_log_mask(LOG_GUEST_ERROR, "OPB write failed at @0x%"
+ HWADDR_PRIx "\n", addr);
+ }
+}
+
+static const MemoryRegionOps pnv_lpc_mmio_ops = {
+ .read = pnv_lpc_mmio_read,
+ .write = pnv_lpc_mmio_write,
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 4,
+ },
+ .endianness = DEVICE_BIG_ENDIAN,
+};
+
static void pnv_lpc_eval_irqs(PnvLpcController *lpc)
{
bool lpc_to_opb_irq = false;
+ PnvLpcClass *plc = PNV_LPC_GET_CLASS(lpc);
/* Update LPC controller to OPB line */
if (lpc->lpc_hc_irqser_ctrl & LPC_HC_IRQSER_EN) {
@@ -266,7 +432,7 @@ static void pnv_lpc_eval_irqs(PnvLpcController *lpc)
lpc->opb_irq_stat |= lpc->opb_irq_input & lpc->opb_irq_mask;
/* Reflect the interrupt */
- pnv_psi_irq_set(lpc->psi, PSIHB_IRQ_LPC_I2C, lpc->opb_irq_stat != 0);
+ pnv_psi_irq_set(lpc->psi, plc->psi_irq, lpc->opb_irq_stat != 0);
}
static uint64_t lpc_hc_read(void *opaque, hwaddr addr, unsigned size)
@@ -294,7 +460,7 @@ static uint64_t lpc_hc_read(void *opaque, hwaddr addr, unsigned size)
val = lpc->lpc_hc_error_addr;
break;
default:
- qemu_log_mask(LOG_UNIMP, "LPC HC Unimplemented register: Ox%"
+ qemu_log_mask(LOG_UNIMP, "LPC HC Unimplemented register: 0x%"
HWADDR_PRIx "\n", addr);
}
return val;
@@ -332,7 +498,7 @@ static void lpc_hc_write(void *opaque, hwaddr addr, uint64_t val,
case LPC_HC_ERROR_ADDRESS:
break;
default:
- qemu_log_mask(LOG_UNIMP, "LPC HC Unimplemented register: Ox%"
+ qemu_log_mask(LOG_UNIMP, "LPC HC Unimplemented register: 0x%"
HWADDR_PRIx "\n", addr);
}
}
@@ -357,6 +523,12 @@ static uint64_t opb_master_read(void *opaque, hwaddr addr, unsigned size)
uint64_t val = 0xfffffffffffffffful;
switch (addr) {
+ case OPB_MASTER_LS_ROUTE0: /* TODO */
+ val = lpc->opb_irq_route0;
+ break;
+ case OPB_MASTER_LS_ROUTE1: /* TODO */
+ val = lpc->opb_irq_route1;
+ break;
case OPB_MASTER_LS_IRQ_STAT:
val = lpc->opb_irq_stat;
break;
@@ -370,7 +542,7 @@ static uint64_t opb_master_read(void *opaque, hwaddr addr, unsigned size)
val = lpc->opb_irq_input;
break;
default:
- qemu_log_mask(LOG_UNIMP, "OPB MASTER Unimplemented register: Ox%"
+ qemu_log_mask(LOG_UNIMP, "OPBM: read on unimplemented register: 0x%"
HWADDR_PRIx "\n", addr);
}
@@ -383,6 +555,12 @@ static void opb_master_write(void *opaque, hwaddr addr,
PnvLpcController *lpc = opaque;
switch (addr) {
+ case OPB_MASTER_LS_ROUTE0: /* TODO */
+ lpc->opb_irq_route0 = val;
+ break;
+ case OPB_MASTER_LS_ROUTE1: /* TODO */
+ lpc->opb_irq_route1 = val;
+ break;
case OPB_MASTER_LS_IRQ_STAT:
lpc->opb_irq_stat &= ~val;
pnv_lpc_eval_irqs(lpc);
@@ -399,8 +577,8 @@ static void opb_master_write(void *opaque, hwaddr addr,
/* Read only */
break;
default:
- qemu_log_mask(LOG_UNIMP, "OPB MASTER Unimplemented register: Ox%"
- HWADDR_PRIx "\n", addr);
+ qemu_log_mask(LOG_UNIMP, "OPBM: write on unimplemented register: 0x%"
+ HWADDR_PRIx " val=0x%08"PRIx64"\n", addr, val);
}
}
@@ -418,11 +596,102 @@ static const MemoryRegionOps opb_master_ops = {
},
};
+static void pnv_lpc_power8_realize(DeviceState *dev, Error **errp)
+{
+ PnvLpcController *lpc = PNV_LPC(dev);
+ PnvLpcClass *plc = PNV_LPC_GET_CLASS(dev);
+ Error *local_err = NULL;
+
+ plc->parent_realize(dev, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ /* P8 uses a XSCOM region for LPC registers */
+ pnv_xscom_region_init(&lpc->xscom_regs, OBJECT(lpc),
+ &pnv_lpc_xscom_ops, lpc, "xscom-lpc",
+ PNV_XSCOM_LPC_SIZE);
+}
+
+static void pnv_lpc_power8_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass);
+ PnvLpcClass *plc = PNV_LPC_CLASS(klass);
+
+ dc->desc = "PowerNV LPC Controller POWER8";
+
+ xdc->dt_xscom = pnv_lpc_dt_xscom;
+
+ plc->psi_irq = PSIHB_IRQ_LPC_I2C;
+
+ device_class_set_parent_realize(dc, pnv_lpc_power8_realize,
+ &plc->parent_realize);
+}
+
+static const TypeInfo pnv_lpc_power8_info = {
+ .name = TYPE_PNV8_LPC,
+ .parent = TYPE_PNV_LPC,
+ .instance_size = sizeof(PnvLpcController),
+ .class_init = pnv_lpc_power8_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_PNV_XSCOM_INTERFACE },
+ { }
+ }
+};
+
+static void pnv_lpc_power9_realize(DeviceState *dev, Error **errp)
+{
+ PnvLpcController *lpc = PNV_LPC(dev);
+ PnvLpcClass *plc = PNV_LPC_GET_CLASS(dev);
+ Error *local_err = NULL;
+
+ plc->parent_realize(dev, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ /* P9 uses a MMIO region */
+ memory_region_init_io(&lpc->xscom_regs, OBJECT(lpc), &pnv_lpc_mmio_ops,
+ lpc, "lpcm", PNV9_LPCM_SIZE);
+}
+
+static void pnv_lpc_power9_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PnvLpcClass *plc = PNV_LPC_CLASS(klass);
+
+ dc->desc = "PowerNV LPC Controller POWER9";
+
+ plc->psi_irq = PSIHB9_IRQ_LPCHC;
+
+ device_class_set_parent_realize(dc, pnv_lpc_power9_realize,
+ &plc->parent_realize);
+}
+
+static const TypeInfo pnv_lpc_power9_info = {
+ .name = TYPE_PNV9_LPC,
+ .parent = TYPE_PNV_LPC,
+ .instance_size = sizeof(PnvLpcController),
+ .class_init = pnv_lpc_power9_class_init,
+};
+
static void pnv_lpc_realize(DeviceState *dev, Error **errp)
{
PnvLpcController *lpc = PNV_LPC(dev);
Object *obj;
- Error *error = NULL;
+ Error *local_err = NULL;
+
+ obj = object_property_get_link(OBJECT(dev), "psi", &local_err);
+ if (!obj) {
+ error_propagate(errp, local_err);
+ error_prepend(errp, "required link 'psi' not found: ");
+ return;
+ }
+ /* The LPC controller needs PSI to generate interrupts */
+ lpc->psi = PNV_PSI(obj);
/* Reg inits */
lpc->lpc_hc_fw_rd_acc_size = LPC_HC_FW_RD_4B;
@@ -462,46 +731,29 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
"lpc-hc", LPC_HC_REGS_OPB_SIZE);
memory_region_add_subregion(&lpc->opb_mr, LPC_HC_REGS_OPB_ADDR,
&lpc->lpc_hc_regs);
-
- /* XScom region for LPC registers */
- pnv_xscom_region_init(&lpc->xscom_regs, OBJECT(dev),
- &pnv_lpc_xscom_ops, lpc, "xscom-lpc",
- PNV_XSCOM_LPC_SIZE);
-
- /* get PSI object from chip */
- obj = object_property_get_link(OBJECT(dev), "psi", &error);
- if (!obj) {
- error_setg(errp, "%s: required link 'psi' not found: %s",
- __func__, error_get_pretty(error));
- return;
- }
- lpc->psi = PNV_PSI(obj);
}
static void pnv_lpc_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass);
-
- xdc->dt_xscom = pnv_lpc_dt_xscom;
dc->realize = pnv_lpc_realize;
+ dc->desc = "PowerNV LPC Controller";
}
static const TypeInfo pnv_lpc_info = {
.name = TYPE_PNV_LPC,
.parent = TYPE_DEVICE,
- .instance_size = sizeof(PnvLpcController),
.class_init = pnv_lpc_class_init,
- .interfaces = (InterfaceInfo[]) {
- { TYPE_PNV_XSCOM_INTERFACE },
- { }
- }
+ .class_size = sizeof(PnvLpcClass),
+ .abstract = true,
};
static void pnv_lpc_register_types(void)
{
type_register_static(&pnv_lpc_info);
+ type_register_static(&pnv_lpc_power8_info);
+ type_register_static(&pnv_lpc_power9_info);
}
type_init(pnv_lpc_register_types)
diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c
index 04880f26d6..fdd9296e1b 100644
--- a/hw/ppc/pnv_occ.c
+++ b/hw/ppc/pnv_occ.c
@@ -34,15 +34,17 @@
static void pnv_occ_set_misc(PnvOCC *occ, uint64_t val)
{
bool irq_state;
+ PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
val &= 0xffff000000000000ull;
occ->occmisc = val;
irq_state = !!(val >> 63);
- pnv_psi_irq_set(occ->psi, PSIHB_IRQ_OCC, irq_state);
+ pnv_psi_irq_set(occ->psi, poc->psi_irq, irq_state);
}
-static uint64_t pnv_occ_xscom_read(void *opaque, hwaddr addr, unsigned size)
+static uint64_t pnv_occ_power8_xscom_read(void *opaque, hwaddr addr,
+ unsigned size)
{
PnvOCC *occ = PNV_OCC(opaque);
uint32_t offset = addr >> 3;
@@ -54,13 +56,13 @@ static uint64_t pnv_occ_xscom_read(void *opaque, hwaddr addr, unsigned size)
break;
default:
qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
- HWADDR_PRIx "\n", addr);
+ HWADDR_PRIx "\n", addr >> 3);
}
return val;
}
-static void pnv_occ_xscom_write(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
+static void pnv_occ_power8_xscom_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
{
PnvOCC *occ = PNV_OCC(opaque);
uint32_t offset = addr >> 3;
@@ -77,13 +79,13 @@ static void pnv_occ_xscom_write(void *opaque, hwaddr addr,
break;
default:
qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
- HWADDR_PRIx "\n", addr);
+ HWADDR_PRIx "\n", addr >> 3);
}
}
-static const MemoryRegionOps pnv_occ_xscom_ops = {
- .read = pnv_occ_xscom_read,
- .write = pnv_occ_xscom_write,
+static const MemoryRegionOps pnv_occ_power8_xscom_ops = {
+ .read = pnv_occ_power8_xscom_read,
+ .write = pnv_occ_power8_xscom_write,
.valid.min_access_size = 8,
.valid.max_access_size = 8,
.impl.min_access_size = 8,
@@ -91,27 +93,113 @@ static const MemoryRegionOps pnv_occ_xscom_ops = {
.endianness = DEVICE_BIG_ENDIAN,
};
+static void pnv_occ_power8_class_init(ObjectClass *klass, void *data)
+{
+ PnvOCCClass *poc = PNV_OCC_CLASS(klass);
+
+ poc->xscom_size = PNV_XSCOM_OCC_SIZE;
+ poc->xscom_ops = &pnv_occ_power8_xscom_ops;
+ poc->psi_irq = PSIHB_IRQ_OCC;
+}
+
+static const TypeInfo pnv_occ_power8_type_info = {
+ .name = TYPE_PNV8_OCC,
+ .parent = TYPE_PNV_OCC,
+ .instance_size = sizeof(PnvOCC),
+ .class_init = pnv_occ_power8_class_init,
+};
+
+#define P9_OCB_OCI_OCCMISC 0x6080
+#define P9_OCB_OCI_OCCMISC_CLEAR 0x6081
+#define P9_OCB_OCI_OCCMISC_OR 0x6082
+
+
+static uint64_t pnv_occ_power9_xscom_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ PnvOCC *occ = PNV_OCC(opaque);
+ uint32_t offset = addr >> 3;
+ uint64_t val = 0;
+
+ switch (offset) {
+ case P9_OCB_OCI_OCCMISC:
+ val = occ->occmisc;
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
+ HWADDR_PRIx "\n", addr >> 3);
+ }
+ return val;
+}
+
+static void pnv_occ_power9_xscom_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ PnvOCC *occ = PNV_OCC(opaque);
+ uint32_t offset = addr >> 3;
+
+ switch (offset) {
+ case P9_OCB_OCI_OCCMISC_CLEAR:
+ pnv_occ_set_misc(occ, 0);
+ break;
+ case P9_OCB_OCI_OCCMISC_OR:
+ pnv_occ_set_misc(occ, occ->occmisc | val);
+ break;
+ case P9_OCB_OCI_OCCMISC:
+ pnv_occ_set_misc(occ, val);
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
+ HWADDR_PRIx "\n", addr >> 3);
+ }
+}
+
+static const MemoryRegionOps pnv_occ_power9_xscom_ops = {
+ .read = pnv_occ_power9_xscom_read,
+ .write = pnv_occ_power9_xscom_write,
+ .valid.min_access_size = 8,
+ .valid.max_access_size = 8,
+ .impl.min_access_size = 8,
+ .impl.max_access_size = 8,
+ .endianness = DEVICE_BIG_ENDIAN,
+};
+
+static void pnv_occ_power9_class_init(ObjectClass *klass, void *data)
+{
+ PnvOCCClass *poc = PNV_OCC_CLASS(klass);
+
+ poc->xscom_size = PNV9_XSCOM_OCC_SIZE;
+ poc->xscom_ops = &pnv_occ_power9_xscom_ops;
+ poc->psi_irq = PSIHB9_IRQ_OCC;
+}
+
+static const TypeInfo pnv_occ_power9_type_info = {
+ .name = TYPE_PNV9_OCC,
+ .parent = TYPE_PNV_OCC,
+ .instance_size = sizeof(PnvOCC),
+ .class_init = pnv_occ_power9_class_init,
+};
static void pnv_occ_realize(DeviceState *dev, Error **errp)
{
PnvOCC *occ = PNV_OCC(dev);
+ PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
Object *obj;
- Error *error = NULL;
+ Error *local_err = NULL;
occ->occmisc = 0;
- /* get PSI object from chip */
- obj = object_property_get_link(OBJECT(dev), "psi", &error);
+ obj = object_property_get_link(OBJECT(dev), "psi", &local_err);
if (!obj) {
- error_setg(errp, "%s: required link 'psi' not found: %s",
- __func__, error_get_pretty(error));
+ error_propagate(errp, local_err);
+ error_prepend(errp, "required link 'psi' not found: ");
return;
}
occ->psi = PNV_PSI(obj);
/* XScom region for OCC registers */
- pnv_xscom_region_init(&occ->xscom_regs, OBJECT(dev), &pnv_occ_xscom_ops,
- occ, "xscom-occ", PNV_XSCOM_OCC_SIZE);
+ pnv_xscom_region_init(&occ->xscom_regs, OBJECT(dev), poc->xscom_ops,
+ occ, "xscom-occ", poc->xscom_size);
}
static void pnv_occ_class_init(ObjectClass *klass, void *data)
@@ -119,6 +207,7 @@ static void pnv_occ_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = pnv_occ_realize;
+ dc->desc = "PowerNV OCC Controller";
}
static const TypeInfo pnv_occ_type_info = {
@@ -126,11 +215,15 @@ static const TypeInfo pnv_occ_type_info = {
.parent = TYPE_DEVICE,
.instance_size = sizeof(PnvOCC),
.class_init = pnv_occ_class_init,
+ .class_size = sizeof(PnvOCCClass),
+ .abstract = true,
};
static void pnv_occ_register_types(void)
{
type_register_static(&pnv_occ_type_info);
+ type_register_static(&pnv_occ_power8_type_info);
+ type_register_static(&pnv_occ_power9_type_info);
}
-type_init(pnv_occ_register_types)
+type_init(pnv_occ_register_types);
diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index 44bc0cbf58..5a923e4151 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -22,6 +22,7 @@
#include "target/ppc/cpu.h"
#include "qemu/log.h"
#include "qapi/error.h"
+#include "monitor/monitor.h"
#include "exec/address-spaces.h"
@@ -114,12 +115,18 @@
#define PSIHB_BAR_MASK 0x0003fffffff00000ull
#define PSIHB_FSPBAR_MASK 0x0003ffff00000000ull
+#define PSIHB9_BAR_MASK 0x00fffffffff00000ull
+#define PSIHB9_FSPBAR_MASK 0x00ffffff00000000ull
+
+#define PSIHB_REG(addr) (((addr) >> 3) + PSIHB_XSCOM_BAR)
+
static void pnv_psi_set_bar(PnvPsi *psi, uint64_t bar)
{
+ PnvPsiClass *ppc = PNV_PSI_GET_CLASS(psi);
MemoryRegion *sysmem = get_system_memory();
uint64_t old = psi->regs[PSIHB_XSCOM_BAR];
- psi->regs[PSIHB_XSCOM_BAR] = bar & (PSIHB_BAR_MASK | PSIHB_BAR_EN);
+ psi->regs[PSIHB_XSCOM_BAR] = bar & (ppc->bar_mask | PSIHB_BAR_EN);
/* Update MR, always remove it first */
if (old & PSIHB_BAR_EN) {
@@ -128,7 +135,7 @@ static void pnv_psi_set_bar(PnvPsi *psi, uint64_t bar)
/* Then add it back if needed */
if (bar & PSIHB_BAR_EN) {
- uint64_t addr = bar & PSIHB_BAR_MASK;
+ uint64_t addr = bar & ppc->bar_mask;
memory_region_add_subregion(sysmem, addr, &psi->regs_mr);
}
}
@@ -152,7 +159,7 @@ static void pnv_psi_set_cr(PnvPsi *psi, uint64_t cr)
static void pnv_psi_set_irsn(PnvPsi *psi, uint64_t val)
{
- ICSState *ics = &psi->ics;
+ ICSState *ics = &PNV8_PSI(psi)->ics;
/* In this model we ignore the up/down enable bits for now
* as SW doesn't use them (other than setting them at boot).
@@ -205,7 +212,12 @@ static const uint64_t stat_bits[] = {
[PSIHB_IRQ_EXTERNAL] = PSIHB_IRQ_STAT_EXT,
};
-void pnv_psi_irq_set(PnvPsi *psi, PnvPsiIrq irq, bool state)
+void pnv_psi_irq_set(PnvPsi *psi, int irq, bool state)
+{
+ PNV_PSI_GET_CLASS(psi)->irq_set(psi, irq, state);
+}
+
+static void pnv_psi_power8_irq_set(PnvPsi *psi, int irq, bool state)
{
uint32_t xivr_reg;
uint32_t stat_reg;
@@ -260,7 +272,7 @@ void pnv_psi_irq_set(PnvPsi *psi, PnvPsiIrq irq, bool state)
static void pnv_psi_set_xivr(PnvPsi *psi, uint32_t reg, uint64_t val)
{
- ICSState *ics = &psi->ics;
+ ICSState *ics = &PNV8_PSI(psi)->ics;
uint16_t server;
uint8_t prio;
uint8_t src;
@@ -323,7 +335,7 @@ static uint64_t pnv_psi_reg_read(PnvPsi *psi, uint32_t offset, bool mmio)
val = psi->regs[offset];
break;
default:
- qemu_log_mask(LOG_UNIMP, "PSI: read at Ox%" PRIx32 "\n", offset);
+ qemu_log_mask(LOG_UNIMP, "PSI: read at 0x%" PRIx32 "\n", offset);
}
return val;
}
@@ -382,7 +394,7 @@ static void pnv_psi_reg_write(PnvPsi *psi, uint32_t offset, uint64_t val,
pnv_psi_set_irsn(psi, val);
break;
default:
- qemu_log_mask(LOG_UNIMP, "PSI: write at Ox%" PRIx32 "\n", offset);
+ qemu_log_mask(LOG_UNIMP, "PSI: write at 0x%" PRIx32 "\n", offset);
}
}
@@ -392,13 +404,13 @@ static void pnv_psi_reg_write(PnvPsi *psi, uint32_t offset, uint64_t val,
*/
static uint64_t pnv_psi_mmio_read(void *opaque, hwaddr addr, unsigned size)
{
- return pnv_psi_reg_read(opaque, (addr >> 3) + PSIHB_XSCOM_BAR, true);
+ return pnv_psi_reg_read(opaque, PSIHB_REG(addr), true);
}
static void pnv_psi_mmio_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
- pnv_psi_reg_write(opaque, (addr >> 3) + PSIHB_XSCOM_BAR, val, true);
+ pnv_psi_reg_write(opaque, PSIHB_REG(addr), val, true);
}
static const MemoryRegionOps psi_mmio_ops = {
@@ -440,11 +452,20 @@ static const MemoryRegionOps pnv_psi_xscom_ops = {
}
};
-static void pnv_psi_init(Object *obj)
+static void pnv_psi_reset(void *dev)
{
- PnvPsi *psi = PNV_PSI(obj);
+ PnvPsi *psi = PNV_PSI(dev);
+
+ memset(psi->regs, 0x0, sizeof(psi->regs));
- object_initialize_child(obj, "ics-psi", &psi->ics, sizeof(psi->ics),
+ psi->regs[PSIHB_XSCOM_BAR] = psi->bar | PSIHB_BAR_EN;
+}
+
+static void pnv_psi_power8_instance_init(Object *obj)
+{
+ Pnv8Psi *psi8 = PNV8_PSI(obj);
+
+ object_initialize_child(obj, "ics-psi", &psi8->ics, sizeof(psi8->ics),
TYPE_ICS_SIMPLE, &error_abort, NULL);
}
@@ -457,10 +478,10 @@ static const uint8_t irq_to_xivr[] = {
PSIHB_XSCOM_XIVR_EXT,
};
-static void pnv_psi_realize(DeviceState *dev, Error **errp)
+static void pnv_psi_power8_realize(DeviceState *dev, Error **errp)
{
PnvPsi *psi = PNV_PSI(dev);
- ICSState *ics = &psi->ics;
+ ICSState *ics = &PNV8_PSI(psi)->ics;
Object *obj;
Error *err = NULL;
unsigned int i;
@@ -509,30 +530,38 @@ static void pnv_psi_realize(DeviceState *dev, Error **errp)
psi->regs[xivr] = PSIHB_XIVR_PRIO_MSK |
((uint64_t) i << PSIHB_XIVR_SRC_SH);
}
+
+ qemu_register_reset(pnv_psi_reset, dev);
}
+static const char compat_p8[] = "ibm,power8-psihb-x\0ibm,psihb-x";
+static const char compat_p9[] = "ibm,power9-psihb-x\0ibm,psihb-x";
+
static int pnv_psi_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
{
- const char compat[] = "ibm,power8-psihb-x\0ibm,psihb-x";
+ PnvPsiClass *ppc = PNV_PSI_GET_CLASS(dev);
char *name;
int offset;
- uint32_t lpc_pcba = PNV_XSCOM_PSIHB_BASE;
uint32_t reg[] = {
- cpu_to_be32(lpc_pcba),
- cpu_to_be32(PNV_XSCOM_PSIHB_SIZE)
+ cpu_to_be32(ppc->xscom_pcba),
+ cpu_to_be32(ppc->xscom_size)
};
- name = g_strdup_printf("psihb@%x", lpc_pcba);
+ name = g_strdup_printf("psihb@%x", ppc->xscom_pcba);
offset = fdt_add_subnode(fdt, xscom_offset, name);
_FDT(offset);
g_free(name);
- _FDT((fdt_setprop(fdt, offset, "reg", reg, sizeof(reg))));
-
- _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 2)));
- _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 1)));
- _FDT((fdt_setprop(fdt, offset, "compatible", compat,
- sizeof(compat))));
+ _FDT(fdt_setprop(fdt, offset, "reg", reg, sizeof(reg)));
+ _FDT(fdt_setprop_cell(fdt, offset, "#address-cells", 2));
+ _FDT(fdt_setprop_cell(fdt, offset, "#size-cells", 1));
+ if (ppc->chip_type == PNV_CHIP_POWER9) {
+ _FDT(fdt_setprop(fdt, offset, "compatible", compat_p9,
+ sizeof(compat_p9)));
+ } else {
+ _FDT(fdt_setprop(fdt, offset, "compatible", compat_p8,
+ sizeof(compat_p8)));
+ }
return 0;
}
@@ -542,6 +571,331 @@ static Property pnv_psi_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};
+static void pnv_psi_power8_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PnvPsiClass *ppc = PNV_PSI_CLASS(klass);
+
+ dc->desc = "PowerNV PSI Controller POWER8";
+ dc->realize = pnv_psi_power8_realize;
+
+ ppc->chip_type = PNV_CHIP_POWER8;
+ ppc->xscom_pcba = PNV_XSCOM_PSIHB_BASE;
+ ppc->xscom_size = PNV_XSCOM_PSIHB_SIZE;
+ ppc->bar_mask = PSIHB_BAR_MASK;
+ ppc->irq_set = pnv_psi_power8_irq_set;
+}
+
+static const TypeInfo pnv_psi_power8_info = {
+ .name = TYPE_PNV8_PSI,
+ .parent = TYPE_PNV_PSI,
+ .instance_size = sizeof(Pnv8Psi),
+ .instance_init = pnv_psi_power8_instance_init,
+ .class_init = pnv_psi_power8_class_init,
+};
+
+
+/* Common registers */
+
+#define PSIHB9_CR 0x20
+#define PSIHB9_SEMR 0x28
+
+/* P9 registers */
+
+#define PSIHB9_INTERRUPT_CONTROL 0x58
+#define PSIHB9_IRQ_METHOD PPC_BIT(0)
+#define PSIHB9_IRQ_RESET PPC_BIT(1)
+#define PSIHB9_ESB_CI_BASE 0x60
+#define PSIHB9_ESB_CI_VALID 1
+#define PSIHB9_ESB_NOTIF_ADDR 0x68
+#define PSIHB9_ESB_NOTIF_VALID 1
+#define PSIHB9_IVT_OFFSET 0x70
+#define PSIHB9_IVT_OFF_SHIFT 32
+
+#define PSIHB9_IRQ_LEVEL 0x78 /* assertion */
+#define PSIHB9_IRQ_LEVEL_PSI PPC_BIT(0)
+#define PSIHB9_IRQ_LEVEL_OCC PPC_BIT(1)
+#define PSIHB9_IRQ_LEVEL_FSI PPC_BIT(2)
+#define PSIHB9_IRQ_LEVEL_LPCHC PPC_BIT(3)
+#define PSIHB9_IRQ_LEVEL_LOCAL_ERR PPC_BIT(4)
+#define PSIHB9_IRQ_LEVEL_GLOBAL_ERR PPC_BIT(5)
+#define PSIHB9_IRQ_LEVEL_TPM PPC_BIT(6)
+#define PSIHB9_IRQ_LEVEL_LPC_SIRQ1 PPC_BIT(7)
+#define PSIHB9_IRQ_LEVEL_LPC_SIRQ2 PPC_BIT(8)
+#define PSIHB9_IRQ_LEVEL_LPC_SIRQ3 PPC_BIT(9)
+#define PSIHB9_IRQ_LEVEL_LPC_SIRQ4 PPC_BIT(10)
+#define PSIHB9_IRQ_LEVEL_SBE_I2C PPC_BIT(11)
+#define PSIHB9_IRQ_LEVEL_DIO PPC_BIT(12)
+#define PSIHB9_IRQ_LEVEL_PSU PPC_BIT(13)
+#define PSIHB9_IRQ_LEVEL_I2C_C PPC_BIT(14)
+#define PSIHB9_IRQ_LEVEL_I2C_D PPC_BIT(15)
+#define PSIHB9_IRQ_LEVEL_I2C_E PPC_BIT(16)
+#define PSIHB9_IRQ_LEVEL_SBE PPC_BIT(19)
+
+#define PSIHB9_IRQ_STAT 0x80 /* P bit */
+#define PSIHB9_IRQ_STAT_PSI PPC_BIT(0)
+#define PSIHB9_IRQ_STAT_OCC PPC_BIT(1)
+#define PSIHB9_IRQ_STAT_FSI PPC_BIT(2)
+#define PSIHB9_IRQ_STAT_LPCHC PPC_BIT(3)
+#define PSIHB9_IRQ_STAT_LOCAL_ERR PPC_BIT(4)
+#define PSIHB9_IRQ_STAT_GLOBAL_ERR PPC_BIT(5)
+#define PSIHB9_IRQ_STAT_TPM PPC_BIT(6)
+#define PSIHB9_IRQ_STAT_LPC_SIRQ1 PPC_BIT(7)
+#define PSIHB9_IRQ_STAT_LPC_SIRQ2 PPC_BIT(8)
+#define PSIHB9_IRQ_STAT_LPC_SIRQ3 PPC_BIT(9)
+#define PSIHB9_IRQ_STAT_LPC_SIRQ4 PPC_BIT(10)
+#define PSIHB9_IRQ_STAT_SBE_I2C PPC_BIT(11)
+#define PSIHB9_IRQ_STAT_DIO PPC_BIT(12)
+#define PSIHB9_IRQ_STAT_PSU PPC_BIT(13)
+
+static void pnv_psi_notify(XiveNotifier *xf, uint32_t srcno)
+{
+ PnvPsi *psi = PNV_PSI(xf);
+ uint64_t notif_port = psi->regs[PSIHB_REG(PSIHB9_ESB_NOTIF_ADDR)];
+ bool valid = notif_port & PSIHB9_ESB_NOTIF_VALID;
+ uint64_t notify_addr = notif_port & ~PSIHB9_ESB_NOTIF_VALID;
+
+ uint32_t offset =
+ (psi->regs[PSIHB_REG(PSIHB9_IVT_OFFSET)] >> PSIHB9_IVT_OFF_SHIFT);
+ uint64_t lisn = cpu_to_be64(offset + srcno);
+
+ if (valid) {
+ cpu_physical_memory_write(notify_addr, &lisn, sizeof(lisn));
+ }
+}
+
+static uint64_t pnv_psi_p9_mmio_read(void *opaque, hwaddr addr, unsigned size)
+{
+ PnvPsi *psi = PNV_PSI(opaque);
+ uint32_t reg = PSIHB_REG(addr);
+ uint64_t val = -1;
+
+ switch (addr) {
+ case PSIHB9_CR:
+ case PSIHB9_SEMR:
+ /* FSP stuff */
+ case PSIHB9_INTERRUPT_CONTROL:
+ case PSIHB9_ESB_CI_BASE:
+ case PSIHB9_ESB_NOTIF_ADDR:
+ case PSIHB9_IVT_OFFSET:
+ val = psi->regs[reg];
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "PSI: read at 0x%" PRIx64 "\n", addr);
+ }
+
+ return val;
+}
+
+static void pnv_psi_p9_mmio_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ PnvPsi *psi = PNV_PSI(opaque);
+ Pnv9Psi *psi9 = PNV9_PSI(psi);
+ uint32_t reg = PSIHB_REG(addr);
+ MemoryRegion *sysmem = get_system_memory();
+
+ switch (addr) {
+ case PSIHB9_CR:
+ case PSIHB9_SEMR:
+ /* FSP stuff */
+ break;
+ case PSIHB9_INTERRUPT_CONTROL:
+ if (val & PSIHB9_IRQ_RESET) {
+ device_reset(DEVICE(&psi9->source));
+ }
+ psi->regs[reg] = val;
+ break;
+
+ case PSIHB9_ESB_CI_BASE:
+ if (!(val & PSIHB9_ESB_CI_VALID)) {
+ if (psi->regs[reg] & PSIHB9_ESB_CI_VALID) {
+ memory_region_del_subregion(sysmem, &psi9->source.esb_mmio);
+ }
+ } else {
+ if (!(psi->regs[reg] & PSIHB9_ESB_CI_VALID)) {
+ memory_region_add_subregion(sysmem,
+ val & ~PSIHB9_ESB_CI_VALID,
+ &psi9->source.esb_mmio);
+ }
+ }
+ psi->regs[reg] = val;
+ break;
+
+ case PSIHB9_ESB_NOTIF_ADDR:
+ psi->regs[reg] = val;
+ break;
+ case PSIHB9_IVT_OFFSET:
+ psi->regs[reg] = val;
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "PSI: write at 0x%" PRIx64 "\n", addr);
+ }
+}
+
+static const MemoryRegionOps pnv_psi_p9_mmio_ops = {
+ .read = pnv_psi_p9_mmio_read,
+ .write = pnv_psi_p9_mmio_write,
+ .endianness = DEVICE_BIG_ENDIAN,
+ .valid = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ },
+ .impl = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ },
+};
+
+static uint64_t pnv_psi_p9_xscom_read(void *opaque, hwaddr addr, unsigned size)
+{
+ /* No read are expected */
+ qemu_log_mask(LOG_GUEST_ERROR, "PSI: xscom read at 0x%" PRIx64 "\n", addr);
+ return -1;
+}
+
+static void pnv_psi_p9_xscom_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ PnvPsi *psi = PNV_PSI(opaque);
+
+ /* XSCOM is only used to set the PSIHB MMIO region */
+ switch (addr >> 3) {
+ case PSIHB_XSCOM_BAR:
+ pnv_psi_set_bar(psi, val);
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "PSI: xscom write at 0x%" PRIx64 "\n",
+ addr);
+ }
+}
+
+static const MemoryRegionOps pnv_psi_p9_xscom_ops = {
+ .read = pnv_psi_p9_xscom_read,
+ .write = pnv_psi_p9_xscom_write,
+ .endianness = DEVICE_BIG_ENDIAN,
+ .valid = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ },
+ .impl = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ }
+};
+
+static void pnv_psi_power9_irq_set(PnvPsi *psi, int irq, bool state)
+{
+ uint32_t irq_method = psi->regs[PSIHB_REG(PSIHB9_INTERRUPT_CONTROL)];
+
+ if (irq > PSIHB9_NUM_IRQS) {
+ qemu_log_mask(LOG_GUEST_ERROR, "PSI: Unsupported irq %d\n", irq);
+ return;
+ }
+
+ if (irq_method & PSIHB9_IRQ_METHOD) {
+ qemu_log_mask(LOG_GUEST_ERROR, "PSI: LSI IRQ method no supported\n");
+ return;
+ }
+
+ /* Update LSI levels */
+ if (state) {
+ psi->regs[PSIHB_REG(PSIHB9_IRQ_LEVEL)] |= PPC_BIT(irq);
+ } else {
+ psi->regs[PSIHB_REG(PSIHB9_IRQ_LEVEL)] &= ~PPC_BIT(irq);
+ }
+
+ qemu_set_irq(psi->qirqs[irq], state);
+}
+
+static void pnv_psi_power9_reset(void *dev)
+{
+ Pnv9Psi *psi = PNV9_PSI(dev);
+
+ pnv_psi_reset(dev);
+
+ if (memory_region_is_mapped(&psi->source.esb_mmio)) {
+ memory_region_del_subregion(get_system_memory(), &psi->source.esb_mmio);
+ }
+}
+
+static void pnv_psi_power9_instance_init(Object *obj)
+{
+ Pnv9Psi *psi = PNV9_PSI(obj);
+
+ object_initialize_child(obj, "source", &psi->source, sizeof(psi->source),
+ TYPE_XIVE_SOURCE, &error_abort, NULL);
+}
+
+static void pnv_psi_power9_realize(DeviceState *dev, Error **errp)
+{
+ PnvPsi *psi = PNV_PSI(dev);
+ XiveSource *xsrc = &PNV9_PSI(psi)->source;
+ Error *local_err = NULL;
+ int i;
+
+ /* This is the only device with 4k ESB pages */
+ object_property_set_int(OBJECT(xsrc), XIVE_ESB_4K, "shift",
+ &error_fatal);
+ object_property_set_int(OBJECT(xsrc), PSIHB9_NUM_IRQS, "nr-irqs",
+ &error_fatal);
+ object_property_add_const_link(OBJECT(xsrc), "xive", OBJECT(psi),
+ &error_fatal);
+ object_property_set_bool(OBJECT(xsrc), true, "realized", &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ for (i = 0; i < xsrc->nr_irqs; i++) {
+ xive_source_irq_set_lsi(xsrc, i);
+ }
+
+ psi->qirqs = qemu_allocate_irqs(xive_source_set_irq, xsrc, xsrc->nr_irqs);
+
+ /* XSCOM region for PSI registers */
+ pnv_xscom_region_init(&psi->xscom_regs, OBJECT(dev), &pnv_psi_p9_xscom_ops,
+ psi, "xscom-psi", PNV9_XSCOM_PSIHB_SIZE);
+
+ /* MMIO region for PSI registers */
+ memory_region_init_io(&psi->regs_mr, OBJECT(dev), &pnv_psi_p9_mmio_ops, psi,
+ "psihb", PNV9_PSIHB_SIZE);
+
+ pnv_psi_set_bar(psi, psi->bar | PSIHB_BAR_EN);
+
+ qemu_register_reset(pnv_psi_power9_reset, dev);
+}
+
+static void pnv_psi_power9_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PnvPsiClass *ppc = PNV_PSI_CLASS(klass);
+ XiveNotifierClass *xfc = XIVE_NOTIFIER_CLASS(klass);
+
+ dc->desc = "PowerNV PSI Controller POWER9";
+ dc->realize = pnv_psi_power9_realize;
+
+ ppc->chip_type = PNV_CHIP_POWER9;
+ ppc->xscom_pcba = PNV9_XSCOM_PSIHB_BASE;
+ ppc->xscom_size = PNV9_XSCOM_PSIHB_SIZE;
+ ppc->bar_mask = PSIHB9_BAR_MASK;
+ ppc->irq_set = pnv_psi_power9_irq_set;
+
+ xfc->notify = pnv_psi_notify;
+}
+
+static const TypeInfo pnv_psi_power9_info = {
+ .name = TYPE_PNV9_PSI,
+ .parent = TYPE_PNV_PSI,
+ .instance_size = sizeof(Pnv9Psi),
+ .instance_init = pnv_psi_power9_instance_init,
+ .class_init = pnv_psi_power9_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_XIVE_NOTIFIER },
+ { },
+ },
+};
+
static void pnv_psi_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -549,7 +903,7 @@ static void pnv_psi_class_init(ObjectClass *klass, void *data)
xdc->dt_xscom = pnv_psi_dt_xscom;
- dc->realize = pnv_psi_realize;
+ dc->desc = "PowerNV PSI Controller";
dc->props = pnv_psi_properties;
}
@@ -557,8 +911,9 @@ static const TypeInfo pnv_psi_info = {
.name = TYPE_PNV_PSI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PnvPsi),
- .instance_init = pnv_psi_init,
.class_init = pnv_psi_class_init,
+ .class_size = sizeof(PnvPsiClass),
+ .abstract = true,
.interfaces = (InterfaceInfo[]) {
{ TYPE_PNV_XSCOM_INTERFACE },
{ }
@@ -568,6 +923,20 @@ static const TypeInfo pnv_psi_info = {
static void pnv_psi_register_types(void)
{
type_register_static(&pnv_psi_info);
+ type_register_static(&pnv_psi_power8_info);
+ type_register_static(&pnv_psi_power9_info);
}
-type_init(pnv_psi_register_types)
+type_init(pnv_psi_register_types);
+
+void pnv_psi_pic_print_info(Pnv9Psi *psi9, Monitor *mon)
+{
+ PnvPsi *psi = PNV_PSI(psi9);
+
+ uint32_t offset =
+ (psi->regs[PSIHB_REG(PSIHB9_IVT_OFFSET)] >> PSIHB9_IVT_OFF_SHIFT);
+
+ monitor_printf(mon, "PSIHB Source %08x .. %08x\n",
+ offset, offset + psi9->source.nr_irqs - 1);
+ xive_source_pic_print_info(&psi9->source, offset, mon);
+}
diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index 46fae41f32..c285ef514e 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -64,11 +64,21 @@ static uint64_t xscom_read_default(PnvChip *chip, uint32_t pcba)
switch (pcba) {
case 0xf000f:
return PNV_CHIP_GET_CLASS(chip)->chip_cfam_id;
+ case 0x18002: /* ECID2 */
+ return 0;
+
case 0x1010c00: /* PIBAM FIR */
case 0x1010c03: /* PIBAM FIR MASK */
- case 0x2020007: /* ADU stuff */
- case 0x2020009: /* ADU stuff */
- case 0x202000f: /* ADU stuff */
+
+ /* P9 xscom reset */
+ case 0x0090018: /* Receive status reg */
+ case 0x0090012: /* log register */
+ case 0x0090013: /* error register */
+
+ /* P8 xscom reset */
+ case 0x2020007: /* ADU stuff, log register */
+ case 0x2020009: /* ADU stuff, error register */
+ case 0x202000f: /* ADU stuff, receive status register*/
return 0;
case 0x2013f00: /* PBA stuff */
case 0x2013f01: /* PBA stuff */
@@ -100,9 +110,20 @@ static bool xscom_write_default(PnvChip *chip, uint32_t pcba, uint64_t val)
case 0x1010c03: /* PIBAM FIR MASK */
case 0x1010c04: /* PIBAM FIR MASK */
case 0x1010c05: /* PIBAM FIR MASK */
- case 0x2020007: /* ADU stuff */
- case 0x2020009: /* ADU stuff */
- case 0x202000f: /* ADU stuff */
+ /* P9 xscom reset */
+ case 0x0090018: /* Receive status reg */
+ case 0x0090012: /* log register */
+ case 0x0090013: /* error register */
+
+ /* P8 xscom reset */
+ case 0x2020007: /* ADU stuff, log register */
+ case 0x2020009: /* ADU stuff, error register */
+ case 0x202000f: /* ADU stuff, receive status register*/
+
+ case 0x2013028: /* CAPP stuff */
+ case 0x201302a: /* CAPP stuff */
+ case 0x2013801: /* CAPP stuff */
+ case 0x2013802: /* CAPP stuff */
return true;
default:
return false;
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index d1e3d4cd20..49d57469fb 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -744,11 +744,10 @@ bool ppc_decr_clear_on_delivery(CPUPPCState *env)
return ((tb_env->flags & flags) == PPC_DECR_UNDERFLOW_TRIGGERED);
}
-static inline uint32_t _cpu_ppc_load_decr(CPUPPCState *env, uint64_t next)
+static inline int64_t _cpu_ppc_load_decr(CPUPPCState *env, uint64_t next)
{
ppc_tb_t *tb_env = env->tb_env;
- uint32_t decr;
- int64_t diff;
+ int64_t decr, diff;
diff = next - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
if (diff >= 0) {
@@ -758,27 +757,49 @@ static inline uint32_t _cpu_ppc_load_decr(CPUPPCState *env, uint64_t next)
} else {
decr = -muldiv64(-diff, tb_env->decr_freq, NANOSECONDS_PER_SECOND);
}
- LOG_TB("%s: %08" PRIx32 "\n", __func__, decr);
+ LOG_TB("%s: %016" PRIx64 "\n", __func__, decr);
return decr;
}
-uint32_t cpu_ppc_load_decr (CPUPPCState *env)
+target_ulong cpu_ppc_load_decr(CPUPPCState *env)
{
ppc_tb_t *tb_env = env->tb_env;
+ uint64_t decr;
if (kvm_enabled()) {
return env->spr[SPR_DECR];
}
- return _cpu_ppc_load_decr(env, tb_env->decr_next);
+ decr = _cpu_ppc_load_decr(env, tb_env->decr_next);
+
+ /*
+ * If large decrementer is enabled then the decrementer is signed extened
+ * to 64 bits, otherwise it is a 32 bit value.
+ */
+ if (env->spr[SPR_LPCR] & LPCR_LD) {
+ return decr;
+ }
+ return (uint32_t) decr;
}
-uint32_t cpu_ppc_load_hdecr (CPUPPCState *env)
+target_ulong cpu_ppc_load_hdecr(CPUPPCState *env)
{
+ PowerPCCPU *cpu = ppc_env_get_cpu(env);
+ PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
ppc_tb_t *tb_env = env->tb_env;
+ uint64_t hdecr;
+
+ hdecr = _cpu_ppc_load_decr(env, tb_env->hdecr_next);
- return _cpu_ppc_load_decr(env, tb_env->hdecr_next);
+ /*
+ * If we have a large decrementer (POWER9 or later) then hdecr is sign
+ * extended to 64 bits, otherwise it is 32 bits.
+ */
+ if (pcc->lrg_decr_bits > 32) {
+ return hdecr;
+ }
+ return (uint32_t) hdecr;
}
uint64_t cpu_ppc_load_purr (CPUPPCState *env)
@@ -832,13 +853,22 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
QEMUTimer *timer,
void (*raise_excp)(void *),
void (*lower_excp)(PowerPCCPU *),
- uint32_t decr, uint32_t value)
+ target_ulong decr, target_ulong value,
+ int nr_bits)
{
CPUPPCState *env = &cpu->env;
ppc_tb_t *tb_env = env->tb_env;
uint64_t now, next;
+ bool negative;
- LOG_TB("%s: %08" PRIx32 " => %08" PRIx32 "\n", __func__,
+ /* Truncate value to decr_width and sign extend for simplicity */
+ value &= ((1ULL << nr_bits) - 1);
+ negative = !!(value & (1ULL << (nr_bits - 1)));
+ if (negative) {
+ value |= (0xFFFFFFFFULL << nr_bits);
+ }
+
+ LOG_TB("%s: " TARGET_FMT_lx " => " TARGET_FMT_lx "\n", __func__,
decr, value);
if (kvm_enabled()) {
@@ -860,15 +890,15 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
* an edge interrupt, so raise it here too.
*/
if ((value < 3) ||
- ((tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL) && (value & 0x80000000)) ||
- ((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) && (value & 0x80000000)
- && !(decr & 0x80000000))) {
+ ((tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL) && negative) ||
+ ((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) && negative
+ && !(decr & (1ULL << (nr_bits - 1))))) {
(*raise_excp)(cpu);
return;
}
/* On MSB level based systems a 0 for the MSB stops interrupt delivery */
- if (!(value & 0x80000000) && (tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL)) {
+ if (!negative && (tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL)) {
(*lower_excp)(cpu);
}
@@ -881,21 +911,27 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
timer_mod(timer, next);
}
-static inline void _cpu_ppc_store_decr(PowerPCCPU *cpu, uint32_t decr,
- uint32_t value)
+static inline void _cpu_ppc_store_decr(PowerPCCPU *cpu, target_ulong decr,
+ target_ulong value, int nr_bits)
{
ppc_tb_t *tb_env = cpu->env.tb_env;
__cpu_ppc_store_decr(cpu, &tb_env->decr_next, tb_env->decr_timer,
tb_env->decr_timer->cb, &cpu_ppc_decr_lower, decr,
- value);
+ value, nr_bits);
}
-void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value)
+void cpu_ppc_store_decr(CPUPPCState *env, target_ulong value)
{
PowerPCCPU *cpu = ppc_env_get_cpu(env);
+ PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+ int nr_bits = 32;
+
+ if (env->spr[SPR_LPCR] & LPCR_LD) {
+ nr_bits = pcc->lrg_decr_bits;
+ }
- _cpu_ppc_store_decr(cpu, cpu_ppc_load_decr(env), value);
+ _cpu_ppc_store_decr(cpu, cpu_ppc_load_decr(env), value, nr_bits);
}
static void cpu_ppc_decr_cb(void *opaque)
@@ -905,23 +941,25 @@ static void cpu_ppc_decr_cb(void *opaque)
cpu_ppc_decr_excp(cpu);
}
-static inline void _cpu_ppc_store_hdecr(PowerPCCPU *cpu, uint32_t hdecr,
- uint32_t value)
+static inline void _cpu_ppc_store_hdecr(PowerPCCPU *cpu, target_ulong hdecr,
+ target_ulong value, int nr_bits)
{
ppc_tb_t *tb_env = cpu->env.tb_env;
if (tb_env->hdecr_timer != NULL) {
__cpu_ppc_store_decr(cpu, &tb_env->hdecr_next, tb_env->hdecr_timer,
tb_env->hdecr_timer->cb, &cpu_ppc_hdecr_lower,
- hdecr, value);
+ hdecr, value, nr_bits);
}
}
-void cpu_ppc_store_hdecr (CPUPPCState *env, uint32_t value)
+void cpu_ppc_store_hdecr(CPUPPCState *env, target_ulong value)
{
PowerPCCPU *cpu = ppc_env_get_cpu(env);
+ PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
- _cpu_ppc_store_hdecr(cpu, cpu_ppc_load_hdecr(env), value);
+ _cpu_ppc_store_hdecr(cpu, cpu_ppc_load_hdecr(env), value,
+ pcc->lrg_decr_bits);
}
static void cpu_ppc_hdecr_cb(void *opaque)
@@ -951,8 +989,8 @@ static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq)
* if a decrementer exception is pending when it enables msr_ee at startup,
* it's not ready to handle it...
*/
- _cpu_ppc_store_decr(cpu, 0xFFFFFFFF, 0xFFFFFFFF);
- _cpu_ppc_store_hdecr(cpu, 0xFFFFFFFF, 0xFFFFFFFF);
+ _cpu_ppc_store_decr(cpu, 0xFFFFFFFF, 0xFFFFFFFF, 32);
+ _cpu_ppc_store_hdecr(cpu, 0xFFFFFFFF, 0xFFFFFFFF, 32);
cpu_ppc_store_purr(cpu, 0x0000000000000000ULL);
}
@@ -1454,3 +1492,19 @@ void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val)
break;
}
}
+
+PowerPCCPU *ppc_get_vcpu_by_pir(int pir)
+{
+ CPUState *cs;
+
+ CPU_FOREACH(cs) {
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+
+ if (env->spr_cb[SPR_PIR].default_value == pir) {
+ return cpu;
+ }
+ }
+
+ return NULL;
+}
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index f47b15f10e..13318a9faf 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -48,8 +48,6 @@
#define USE_FLASH_BIOS
-//#define DEBUG_BOARD_INIT
-
/*****************************************************************************/
/* PPC405EP reference board (IBM) */
/* Standalone board with:
@@ -158,7 +156,7 @@ static void ref405ep_init(MachineState *machine)
target_ulong kernel_base, initrd_base;
long kernel_size, initrd_size;
int linux_boot;
- int fl_idx, fl_sectors, len;
+ int len;
DriveInfo *dinfo;
MemoryRegion *sysmem = get_system_memory();
@@ -171,9 +169,6 @@ static void ref405ep_init(MachineState *machine)
ram_bases[1] = 0x00000000;
ram_sizes[1] = 0x00000000;
ram_size = 128 * MiB;
-#ifdef DEBUG_BOARD_INIT
- printf("%s: register cpu\n", __func__);
-#endif
env = ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes,
33333333, &pic, kernel_filename == NULL ? 0 : 1);
/* allocate SRAM */
@@ -182,35 +177,19 @@ static void ref405ep_init(MachineState *machine)
&error_fatal);
memory_region_add_subregion(sysmem, 0xFFF00000, sram);
/* allocate and load BIOS */
-#ifdef DEBUG_BOARD_INIT
- printf("%s: register BIOS\n", __func__);
-#endif
- fl_idx = 0;
#ifdef USE_FLASH_BIOS
- dinfo = drive_get(IF_PFLASH, 0, fl_idx);
+ dinfo = drive_get(IF_PFLASH, 0, 0);
if (dinfo) {
- BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
-
- bios_size = blk_getlength(blk);
- fl_sectors = (bios_size + 65535) >> 16;
-#ifdef DEBUG_BOARD_INIT
- printf("Register parallel flash %d size %lx"
- " at addr %lx '%s' %d\n",
- fl_idx, bios_size, -bios_size,
- blk_name(blk), fl_sectors);
-#endif
+ bios_size = 8 * MiB;
pflash_cfi02_register((uint32_t)(-bios_size),
- NULL, "ef405ep.bios", bios_size,
- blk, 65536, fl_sectors, 1,
+ "ef405ep.bios", bios_size,
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
+ 64 * KiB, 1,
2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
1);
- fl_idx++;
} else
#endif
{
-#ifdef DEBUG_BOARD_INIT
- printf("Load BIOS from file\n");
-#endif
bios = g_new(MemoryRegion, 1);
memory_region_init_ram(bios, NULL, "ef405ep.bios", BIOS_SIZE,
&error_fatal);
@@ -239,21 +218,12 @@ static void ref405ep_init(MachineState *machine)
memory_region_set_readonly(bios, true);
}
/* Register FPGA */
-#ifdef DEBUG_BOARD_INIT
- printf("%s: register FPGA\n", __func__);
-#endif
ref405ep_fpga_init(sysmem, 0xF0300000);
/* Register NVRAM */
-#ifdef DEBUG_BOARD_INIT
- printf("%s: register NVRAM\n", __func__);
-#endif
m48t59_init(NULL, 0xF0000000, 0, 8192, 1968, 8);
/* Load kernel */
linux_boot = (kernel_filename != NULL);
if (linux_boot) {
-#ifdef DEBUG_BOARD_INIT
- printf("%s: load kernel\n", __func__);
-#endif
memset(&bd, 0, sizeof(bd));
bd.bi_memstart = 0x00000000;
bd.bi_memsize = ram_size;
@@ -325,10 +295,6 @@ static void ref405ep_init(MachineState *machine)
initrd_size = 0;
bdloc = 0;
}
-#ifdef DEBUG_BOARD_INIT
- printf("bdloc " RAM_ADDR_FMT "\n", bdloc);
- printf("%s: Done\n", __func__);
-#endif
}
static void ref405ep_class_init(ObjectClass *oc, void *data)
@@ -455,7 +421,7 @@ static void taihu_405ep_init(MachineState *machine)
target_ulong kernel_base, initrd_base;
long kernel_size, initrd_size;
int linux_boot;
- int fl_idx, fl_sectors;
+ int fl_idx;
DriveInfo *dinfo;
/* RAM is soldered to the board so the size cannot be changed */
@@ -473,43 +439,24 @@ static void taihu_405ep_init(MachineState *machine)
memory_region_init_alias(&ram_memories[1], NULL,
"taihu_405ep.ram-1", ram, ram_bases[1],
ram_sizes[1]);
-#ifdef DEBUG_BOARD_INIT
- printf("%s: register cpu\n", __func__);
-#endif
ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes,
33333333, &pic, kernel_filename == NULL ? 0 : 1);
/* allocate and load BIOS */
-#ifdef DEBUG_BOARD_INIT
- printf("%s: register BIOS\n", __func__);
-#endif
fl_idx = 0;
#if defined(USE_FLASH_BIOS)
dinfo = drive_get(IF_PFLASH, 0, fl_idx);
if (dinfo) {
- BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
-
- bios_size = blk_getlength(blk);
- /* XXX: should check that size is 2MB */
- // bios_size = 2 * 1024 * 1024;
- fl_sectors = (bios_size + 65535) >> 16;
-#ifdef DEBUG_BOARD_INIT
- printf("Register parallel flash %d size %lx"
- " at addr %lx '%s' %d\n",
- fl_idx, bios_size, -bios_size,
- blk_name(blk), fl_sectors);
-#endif
- pflash_cfi02_register((uint32_t)(-bios_size),
- NULL, "taihu_405ep.bios", bios_size,
- blk, 65536, fl_sectors, 1,
+ bios_size = 2 * MiB;
+ pflash_cfi02_register(0xFFE00000,
+ "taihu_405ep.bios", bios_size,
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
+ 64 * KiB, 1,
4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
1);
fl_idx++;
} else
#endif
{
-#ifdef DEBUG_BOARD_INIT
- printf("Load BIOS from file\n");
-#endif
if (bios_name == NULL)
bios_name = BIOS_FILENAME;
bios = g_new(MemoryRegion, 1);
@@ -536,35 +483,19 @@ static void taihu_405ep_init(MachineState *machine)
/* Register Linux flash */
dinfo = drive_get(IF_PFLASH, 0, fl_idx);
if (dinfo) {
- BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
-
- bios_size = blk_getlength(blk);
- /* XXX: should check that size is 32MB */
bios_size = 32 * MiB;
- fl_sectors = (bios_size + 65535) >> 16;
-#ifdef DEBUG_BOARD_INIT
- printf("Register parallel flash %d size %lx"
- " at addr " TARGET_FMT_lx " '%s'\n",
- fl_idx, bios_size, (target_ulong)0xfc000000,
- blk_name(blk));
-#endif
- pflash_cfi02_register(0xfc000000, NULL, "taihu_405ep.flash", bios_size,
- blk, 65536, fl_sectors, 1,
+ pflash_cfi02_register(0xfc000000, "taihu_405ep.flash", bios_size,
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
+ 64 * KiB, 1,
4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
1);
fl_idx++;
}
/* Register CLPD & LCD display */
-#ifdef DEBUG_BOARD_INIT
- printf("%s: register CPLD\n", __func__);
-#endif
taihu_cpld_init(sysmem, 0x50100000);
/* Load kernel */
linux_boot = (kernel_filename != NULL);
if (linux_boot) {
-#ifdef DEBUG_BOARD_INIT
- printf("%s: load kernel\n", __func__);
-#endif
kernel_base = KERNEL_LOAD_ADDR;
/* now we can load the kernel */
kernel_size = load_image_targphys(kernel_filename, kernel_base,
@@ -593,9 +524,6 @@ static void taihu_405ep_init(MachineState *machine)
initrd_base = 0;
initrd_size = 0;
}
-#ifdef DEBUG_BOARD_INIT
- printf("%s: Done\n", __func__);
-#endif
}
static void taihu_class_init(ObjectClass *oc, void *data)
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index d455c4bd07..fbcddc5b00 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -91,32 +91,42 @@ struct boot_info {
static int sam460ex_load_uboot(void)
{
+ /*
+ * This first creates 1MiB of flash memory mapped at the end of
+ * the 32-bit address space (0xFFF00000..0xFFFFFFFF).
+ *
+ * If_PFLASH unit 0 is defined, the flash memory is initialized
+ * from that block backend.
+ *
+ * Else, it's initialized to zero. And then 512KiB of ROM get
+ * mapped on top of its second half (0xFFF80000..0xFFFFFFFF),
+ * initialized from u-boot-sam460-20100605.bin.
+ *
+ * This doesn't smell right.
+ *
+ * The physical hardware appears to have 512KiB flash memory.
+ *
+ * TODO Figure out what we really need here, and clean this up.
+ */
+
DriveInfo *dinfo;
- BlockBackend *blk = NULL;
- hwaddr base = FLASH_BASE | ((hwaddr)FLASH_BASE_H << 32);
- long bios_size = FLASH_SIZE;
- int fl_sectors;
dinfo = drive_get(IF_PFLASH, 0, 0);
- if (dinfo) {
- blk = blk_by_legacy_dinfo(dinfo);
- bios_size = blk_getlength(blk);
- }
- fl_sectors = (bios_size + 65535) >> 16;
-
- if (!pflash_cfi01_register(base, NULL, "sam460ex.flash", bios_size,
- blk, 64 * KiB, fl_sectors,
- 1, 0x89, 0x18, 0x0000, 0x0, 1)) {
+ if (!pflash_cfi01_register(FLASH_BASE | ((hwaddr)FLASH_BASE_H << 32),
+ "sam460ex.flash", FLASH_SIZE,
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
+ 64 * KiB, 1, 0x89, 0x18, 0x0000, 0x0, 1)) {
error_report("Error registering flash memory");
/* XXX: return an error instead? */
exit(1);
}
- if (!blk) {
+ if (!dinfo) {
/*error_report("No flash image given with the 'pflash' parameter,"
" using default u-boot image");*/
- base = UBOOT_LOAD_BASE | ((hwaddr)FLASH_BASE_H << 32);
- rom_add_file_fixed(UBOOT_FILENAME, base, -1);
+ rom_add_file_fixed(UBOOT_FILENAME,
+ UBOOT_LOAD_BASE | ((hwaddr)FLASH_BASE_H << 32),
+ -1);
}
return 0;
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 9e01226e18..6c16d6cfaf 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -29,6 +29,7 @@
#include "qapi/visitor.h"
#include "sysemu/sysemu.h"
#include "sysemu/numa.h"
+#include "sysemu/qtest.h"
#include "hw/hw.h"
#include "qemu/log.h"
#include "hw/fw-path-provider.h"
@@ -102,13 +103,13 @@
* all and one to identify thread 0 of a VCORE. Any change to the first one
* is likely to have an impact on the second one, so let's keep them close.
*/
-static int spapr_vcpu_id(sPAPRMachineState *spapr, int cpu_index)
+static int spapr_vcpu_id(SpaprMachineState *spapr, int cpu_index)
{
assert(spapr->vsmt);
return
(cpu_index / smp_threads) * spapr->vsmt + cpu_index % smp_threads;
}
-static bool spapr_is_thread0_in_vcore(sPAPRMachineState *spapr,
+static bool spapr_is_thread0_in_vcore(SpaprMachineState *spapr,
PowerPCCPU *cpu)
{
assert(spapr->vsmt);
@@ -149,7 +150,7 @@ static void pre_2_10_vmstate_unregister_dummy_icp(int i)
(void *)(uintptr_t) i);
}
-int spapr_max_server_number(sPAPRMachineState *spapr)
+int spapr_max_server_number(SpaprMachineState *spapr)
{
assert(spapr->vsmt);
return DIV_ROUND_UP(max_cpus * spapr->vsmt, smp_threads);
@@ -204,7 +205,7 @@ static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, PowerPCCPU *cpu)
}
/* Populate the "ibm,pa-features" property */
-static void spapr_populate_pa_features(sPAPRMachineState *spapr,
+static void spapr_populate_pa_features(SpaprMachineState *spapr,
PowerPCCPU *cpu,
void *fdt, int offset,
bool legacy_guest)
@@ -283,7 +284,7 @@ static void spapr_populate_pa_features(sPAPRMachineState *spapr,
_FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, pa_size)));
}
-static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
+static int spapr_fixup_cpu_dt(void *fdt, SpaprMachineState *spapr)
{
int ret = 0, offset, cpus_offset;
CPUState *cs;
@@ -386,7 +387,7 @@ static int spapr_populate_memory_node(void *fdt, int nodeid, hwaddr start,
return off;
}
-static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt)
+static int spapr_populate_memory(SpaprMachineState *spapr, void *fdt)
{
MachineState *machine = MACHINE(spapr);
hwaddr mem_start, node_size;
@@ -438,7 +439,7 @@ static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt)
}
static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
- sPAPRMachineState *spapr)
+ SpaprMachineState *spapr)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *env = &cpu->env;
@@ -454,7 +455,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
uint32_t vcpus_per_socket = smp_threads * smp_cores;
uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
int compat_smt = MIN(smp_threads, ppc_compat_max_vthreads(cpu));
- sPAPRDRConnector *drc;
+ SpaprDrc *drc;
int drc_index;
uint32_t radix_AP_encodings[PPC_PAGE_SIZES_MAX_SZ];
int i;
@@ -557,9 +558,17 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
pcc->radix_page_info->count *
sizeof(radix_AP_encodings[0]))));
}
+
+ /*
+ * We set this property to let the guest know that it can use the large
+ * decrementer and its width in bits.
+ */
+ if (spapr_get_cap(spapr, SPAPR_CAP_LARGE_DECREMENTER) != SPAPR_CAP_OFF)
+ _FDT((fdt_setprop_u32(fdt, offset, "ibm,dec-bits",
+ pcc->lrg_decr_bits)));
}
-static void spapr_populate_cpus_dt_node(void *fdt, sPAPRMachineState *spapr)
+static void spapr_populate_cpus_dt_node(void *fdt, SpaprMachineState *spapr)
{
CPUState **rev;
CPUState *cs;
@@ -683,7 +692,7 @@ spapr_get_drconf_cell(uint32_t seq_lmbs, uint64_t base_addr,
}
/* ibm,dynamic-memory-v2 */
-static int spapr_populate_drmem_v2(sPAPRMachineState *spapr, void *fdt,
+static int spapr_populate_drmem_v2(SpaprMachineState *spapr, void *fdt,
int offset, MemoryDeviceInfoList *dimms)
{
MachineState *machine = MACHINE(spapr);
@@ -695,7 +704,7 @@ static int spapr_populate_drmem_v2(sPAPRMachineState *spapr, void *fdt,
uint64_t mem_end = machine->device_memory->base +
memory_region_size(&machine->device_memory->mr);
uint32_t node, buf_len, nr_entries = 0;
- sPAPRDRConnector *drc;
+ SpaprDrc *drc;
DrconfCellQueue *elem, *next;
MemoryDeviceInfoList *info;
QSIMPLEQ_HEAD(, DrconfCellQueue) drconf_queue
@@ -768,7 +777,7 @@ static int spapr_populate_drmem_v2(sPAPRMachineState *spapr, void *fdt,
}
/* ibm,dynamic-memory */
-static int spapr_populate_drmem_v1(sPAPRMachineState *spapr, void *fdt,
+static int spapr_populate_drmem_v1(SpaprMachineState *spapr, void *fdt,
int offset, MemoryDeviceInfoList *dimms)
{
MachineState *machine = MACHINE(spapr);
@@ -792,7 +801,7 @@ static int spapr_populate_drmem_v1(sPAPRMachineState *spapr, void *fdt,
uint32_t *dynamic_memory = cur_index;
if (i >= device_lmb_start) {
- sPAPRDRConnector *drc;
+ SpaprDrc *drc;
drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB, i);
g_assert(drc);
@@ -837,7 +846,7 @@ static int spapr_populate_drmem_v1(sPAPRMachineState *spapr, void *fdt,
* Refer to docs/specs/ppc-spapr-hotplug.txt for the documentation
* of this device tree node.
*/
-static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt)
+static int spapr_populate_drconf_memory(SpaprMachineState *spapr, void *fdt)
{
MachineState *machine = MACHINE(spapr);
int ret, i, offset;
@@ -908,10 +917,10 @@ static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt)
return ret;
}
-static int spapr_dt_cas_updates(sPAPRMachineState *spapr, void *fdt,
- sPAPROptionVector *ov5_updates)
+static int spapr_dt_cas_updates(SpaprMachineState *spapr, void *fdt,
+ SpaprOptionVector *ov5_updates)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
int ret = 0, offset;
/* Generate ibm,dynamic-reconfiguration-memory node if required */
@@ -957,12 +966,12 @@ static bool spapr_hotplugged_dev_before_cas(void)
return false;
}
-int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
+int spapr_h_cas_compose_response(SpaprMachineState *spapr,
target_ulong addr, target_ulong size,
- sPAPROptionVector *ov5_updates)
+ SpaprOptionVector *ov5_updates)
{
void *fdt, *fdt_skel;
- sPAPRDeviceTreeUpdateHeader hdr = { .version_id = 1 };
+ SpaprDeviceTreeUpdateHeader hdr = { .version_id = 1 };
if (spapr_hotplugged_dev_before_cas()) {
return 1;
@@ -1011,7 +1020,7 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
return 0;
}
-static void spapr_dt_rtas(sPAPRMachineState *spapr, void *fdt)
+static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
{
int rtas;
GString *hypertas = g_string_sized_new(256);
@@ -1100,7 +1109,7 @@ static void spapr_dt_rtas(sPAPRMachineState *spapr, void *fdt)
* and the XIVE features that the guest may request and thus the valid
* values for bytes 23..26 of option vector 5:
*/
-static void spapr_dt_ov5_platform_support(sPAPRMachineState *spapr, void *fdt,
+static void spapr_dt_ov5_platform_support(SpaprMachineState *spapr, void *fdt,
int chosen)
{
PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
@@ -1136,7 +1145,7 @@ static void spapr_dt_ov5_platform_support(sPAPRMachineState *spapr, void *fdt,
val, sizeof(val)));
}
-static void spapr_dt_chosen(sPAPRMachineState *spapr, void *fdt)
+static void spapr_dt_chosen(SpaprMachineState *spapr, void *fdt)
{
MachineState *machine = MACHINE(spapr);
int chosen;
@@ -1202,7 +1211,7 @@ static void spapr_dt_chosen(sPAPRMachineState *spapr, void *fdt)
g_free(bootlist);
}
-static void spapr_dt_hypervisor(sPAPRMachineState *spapr, void *fdt)
+static void spapr_dt_hypervisor(SpaprMachineState *spapr, void *fdt)
{
/* The /hypervisor node isn't in PAPR - this is a hack to allow PR
* KVM to work under pHyp with some guest co-operation */
@@ -1225,14 +1234,14 @@ static void spapr_dt_hypervisor(sPAPRMachineState *spapr, void *fdt)
}
}
-static void *spapr_build_fdt(sPAPRMachineState *spapr)
+static void *spapr_build_fdt(SpaprMachineState *spapr)
{
MachineState *machine = MACHINE(spapr);
MachineClass *mc = MACHINE_GET_CLASS(machine);
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
int ret;
void *fdt;
- sPAPRPHBState *phb;
+ SpaprPhbState *phb;
char *buf;
fdt = g_malloc0(FDT_MAX_SIZE);
@@ -1430,7 +1439,7 @@ void spapr_set_all_lpcrs(target_ulong value, target_ulong mask)
static void spapr_get_pate(PPCVirtualHypervisor *vhyp, ppc_v3_pate_t *entry)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
+ SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
/* Copy PATE1:GR into PATE0:HR */
entry->dw0 = spapr->patb_entry & PATE0_HR;
@@ -1446,7 +1455,7 @@ static void spapr_get_pate(PPCVirtualHypervisor *vhyp, ppc_v3_pate_t *entry)
/*
* Get the fd to access the kernel htab, re-opening it if necessary
*/
-static int get_htab_fd(sPAPRMachineState *spapr)
+static int get_htab_fd(SpaprMachineState *spapr)
{
Error *local_err = NULL;
@@ -1462,7 +1471,7 @@ static int get_htab_fd(sPAPRMachineState *spapr)
return spapr->htab_fd;
}
-void close_htab_fd(sPAPRMachineState *spapr)
+void close_htab_fd(SpaprMachineState *spapr)
{
if (spapr->htab_fd >= 0) {
close(spapr->htab_fd);
@@ -1472,14 +1481,14 @@ void close_htab_fd(sPAPRMachineState *spapr)
static hwaddr spapr_hpt_mask(PPCVirtualHypervisor *vhyp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
+ SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
return HTAB_SIZE(spapr) / HASH_PTEG_SIZE_64 - 1;
}
static target_ulong spapr_encode_hpt_for_kvm_pr(PPCVirtualHypervisor *vhyp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
+ SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
assert(kvm_enabled());
@@ -1493,7 +1502,7 @@ static target_ulong spapr_encode_hpt_for_kvm_pr(PPCVirtualHypervisor *vhyp)
static const ppc_hash_pte64_t *spapr_map_hptes(PPCVirtualHypervisor *vhyp,
hwaddr ptex, int n)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
+ SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
hwaddr pte_offset = ptex * HASH_PTE_SIZE_64;
if (!spapr->htab) {
@@ -1516,7 +1525,7 @@ static void spapr_unmap_hptes(PPCVirtualHypervisor *vhyp,
const ppc_hash_pte64_t *hptes,
hwaddr ptex, int n)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
+ SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
if (!spapr->htab) {
g_free((void *)hptes);
@@ -1528,7 +1537,7 @@ static void spapr_unmap_hptes(PPCVirtualHypervisor *vhyp,
static void spapr_store_hpte(PPCVirtualHypervisor *vhyp, hwaddr ptex,
uint64_t pte0, uint64_t pte1)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
+ SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
hwaddr offset = ptex * HASH_PTE_SIZE_64;
if (!spapr->htab) {
@@ -1569,7 +1578,7 @@ int spapr_hpt_shift_for_ramsize(uint64_t ramsize)
return shift;
}
-void spapr_free_hpt(sPAPRMachineState *spapr)
+void spapr_free_hpt(SpaprMachineState *spapr)
{
g_free(spapr->htab);
spapr->htab = NULL;
@@ -1577,7 +1586,7 @@ void spapr_free_hpt(sPAPRMachineState *spapr)
close_htab_fd(spapr);
}
-void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
+void spapr_reallocate_hpt(SpaprMachineState *spapr, int shift,
Error **errp)
{
long rc;
@@ -1623,10 +1632,11 @@ void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
}
}
/* We're setting up a hash table, so that means we're not radix */
+ spapr->patb_entry = 0;
spapr_set_all_lpcrs(0, LPCR_HR | LPCR_UPRT);
}
-void spapr_setup_hpt_and_vrma(sPAPRMachineState *spapr)
+void spapr_setup_hpt_and_vrma(SpaprMachineState *spapr)
{
int hpt_shift;
@@ -1650,8 +1660,8 @@ void spapr_setup_hpt_and_vrma(sPAPRMachineState *spapr)
static int spapr_reset_drcs(Object *child, void *opaque)
{
- sPAPRDRConnector *drc =
- (sPAPRDRConnector *) object_dynamic_cast(child,
+ SpaprDrc *drc =
+ (SpaprDrc *) object_dynamic_cast(child,
TYPE_SPAPR_DR_CONNECTOR);
if (drc) {
@@ -1664,7 +1674,7 @@ static int spapr_reset_drcs(Object *child, void *opaque)
static void spapr_machine_reset(void)
{
MachineState *machine = MACHINE(qdev_get_machine());
- sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
+ SpaprMachineState *spapr = SPAPR_MACHINE(machine);
PowerPCCPU *first_ppc_cpu;
uint32_t rtas_limit;
hwaddr rtas_addr, fdt_addr;
@@ -1711,6 +1721,16 @@ static void spapr_machine_reset(void)
*/
spapr_irq_reset(spapr, &error_fatal);
+ /*
+ * There is no CAS under qtest. Simulate one to please the code that
+ * depends on spapr->ov5_cas. This is especially needed to test device
+ * unplug, so we do that before resetting the DRCs.
+ */
+ if (qtest_enabled()) {
+ spapr_ovec_cleanup(spapr->ov5_cas);
+ spapr->ov5_cas = spapr_ovec_clone(spapr->ov5);
+ }
+
/* DRC reset may cause a device to be unplugged. This will cause troubles
* if this device is used by another device (eg, a running vhost backend
* will crash QEMU if the DIMM holding the vring goes away). To avoid such
@@ -1759,7 +1779,7 @@ static void spapr_machine_reset(void)
spapr->cas_reboot = false;
}
-static void spapr_create_nvram(sPAPRMachineState *spapr)
+static void spapr_create_nvram(SpaprMachineState *spapr)
{
DeviceState *dev = qdev_create(&spapr->vio_bus->bus, "spapr-nvram");
DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0);
@@ -1771,10 +1791,10 @@ static void spapr_create_nvram(sPAPRMachineState *spapr)
qdev_init_nofail(dev);
- spapr->nvram = (struct sPAPRNVRAM *)dev;
+ spapr->nvram = (struct SpaprNvram *)dev;
}
-static void spapr_rtc_create(sPAPRMachineState *spapr)
+static void spapr_rtc_create(SpaprMachineState *spapr)
{
object_initialize_child(OBJECT(spapr), "rtc",
&spapr->rtc, sizeof(spapr->rtc), TYPE_SPAPR_RTC,
@@ -1818,7 +1838,7 @@ static int spapr_pre_load(void *opaque)
static int spapr_post_load(void *opaque, int version_id)
{
- sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
+ SpaprMachineState *spapr = (SpaprMachineState *)opaque;
int err = 0;
err = spapr_caps_post_migration(spapr);
@@ -1885,7 +1905,7 @@ static bool version_before_3(void *opaque, int version_id)
static bool spapr_pending_events_needed(void *opaque)
{
- sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
+ SpaprMachineState *spapr = (SpaprMachineState *)opaque;
return !QTAILQ_EMPTY(&spapr->pending_events);
}
@@ -1894,9 +1914,9 @@ static const VMStateDescription vmstate_spapr_event_entry = {
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
- VMSTATE_UINT32(summary, sPAPREventLogEntry),
- VMSTATE_UINT32(extended_length, sPAPREventLogEntry),
- VMSTATE_VBUFFER_ALLOC_UINT32(extended_log, sPAPREventLogEntry, 0,
+ VMSTATE_UINT32(summary, SpaprEventLogEntry),
+ VMSTATE_UINT32(extended_length, SpaprEventLogEntry),
+ VMSTATE_VBUFFER_ALLOC_UINT32(extended_log, SpaprEventLogEntry, 0,
NULL, extended_length),
VMSTATE_END_OF_LIST()
},
@@ -1908,21 +1928,21 @@ static const VMStateDescription vmstate_spapr_pending_events = {
.minimum_version_id = 1,
.needed = spapr_pending_events_needed,
.fields = (VMStateField[]) {
- VMSTATE_QTAILQ_V(pending_events, sPAPRMachineState, 1,
- vmstate_spapr_event_entry, sPAPREventLogEntry, next),
+ VMSTATE_QTAILQ_V(pending_events, SpaprMachineState, 1,
+ vmstate_spapr_event_entry, SpaprEventLogEntry, next),
VMSTATE_END_OF_LIST()
},
};
static bool spapr_ov5_cas_needed(void *opaque)
{
- sPAPRMachineState *spapr = opaque;
- sPAPROptionVector *ov5_mask = spapr_ovec_new();
- sPAPROptionVector *ov5_legacy = spapr_ovec_new();
- sPAPROptionVector *ov5_removed = spapr_ovec_new();
+ SpaprMachineState *spapr = opaque;
+ SpaprOptionVector *ov5_mask = spapr_ovec_new();
+ SpaprOptionVector *ov5_legacy = spapr_ovec_new();
+ SpaprOptionVector *ov5_removed = spapr_ovec_new();
bool cas_needed;
- /* Prior to the introduction of sPAPROptionVector, we had two option
+ /* Prior to the introduction of SpaprOptionVector, we had two option
* vectors we dealt with: OV5_FORM1_AFFINITY, and OV5_DRCONF_MEMORY.
* Both of these options encode machine topology into the device-tree
* in such a way that the now-booted OS should still be able to interact
@@ -1972,15 +1992,15 @@ static const VMStateDescription vmstate_spapr_ov5_cas = {
.minimum_version_id = 1,
.needed = spapr_ov5_cas_needed,
.fields = (VMStateField[]) {
- VMSTATE_STRUCT_POINTER_V(ov5_cas, sPAPRMachineState, 1,
- vmstate_spapr_ovec, sPAPROptionVector),
+ VMSTATE_STRUCT_POINTER_V(ov5_cas, SpaprMachineState, 1,
+ vmstate_spapr_ovec, SpaprOptionVector),
VMSTATE_END_OF_LIST()
},
};
static bool spapr_patb_entry_needed(void *opaque)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
return !!spapr->patb_entry;
}
@@ -1991,14 +2011,14 @@ static const VMStateDescription vmstate_spapr_patb_entry = {
.minimum_version_id = 1,
.needed = spapr_patb_entry_needed,
.fields = (VMStateField[]) {
- VMSTATE_UINT64(patb_entry, sPAPRMachineState),
+ VMSTATE_UINT64(patb_entry, SpaprMachineState),
VMSTATE_END_OF_LIST()
},
};
static bool spapr_irq_map_needed(void *opaque)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
return spapr->irq_map && !bitmap_empty(spapr->irq_map, spapr->irq_map_nr);
}
@@ -2009,21 +2029,21 @@ static const VMStateDescription vmstate_spapr_irq_map = {
.minimum_version_id = 1,
.needed = spapr_irq_map_needed,
.fields = (VMStateField[]) {
- VMSTATE_BITMAP(irq_map, sPAPRMachineState, 0, irq_map_nr),
+ VMSTATE_BITMAP(irq_map, SpaprMachineState, 0, irq_map_nr),
VMSTATE_END_OF_LIST()
},
};
static bool spapr_dtb_needed(void *opaque)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(opaque);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(opaque);
return smc->update_dt_enabled;
}
static int spapr_dtb_pre_load(void *opaque)
{
- sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
+ SpaprMachineState *spapr = (SpaprMachineState *)opaque;
g_free(spapr->fdt_blob);
spapr->fdt_blob = NULL;
@@ -2039,9 +2059,9 @@ static const VMStateDescription vmstate_spapr_dtb = {
.needed = spapr_dtb_needed,
.pre_load = spapr_dtb_pre_load,
.fields = (VMStateField[]) {
- VMSTATE_UINT32(fdt_initial_size, sPAPRMachineState),
- VMSTATE_UINT32(fdt_size, sPAPRMachineState),
- VMSTATE_VBUFFER_ALLOC_UINT32(fdt_blob, sPAPRMachineState, 0, NULL,
+ VMSTATE_UINT32(fdt_initial_size, SpaprMachineState),
+ VMSTATE_UINT32(fdt_size, SpaprMachineState),
+ VMSTATE_VBUFFER_ALLOC_UINT32(fdt_blob, SpaprMachineState, 0, NULL,
fdt_size),
VMSTATE_END_OF_LIST()
},
@@ -2059,9 +2079,9 @@ static const VMStateDescription vmstate_spapr = {
VMSTATE_UNUSED_BUFFER(version_before_3, 0, 4),
/* RTC offset */
- VMSTATE_UINT64_TEST(rtc_offset, sPAPRMachineState, version_before_3),
+ VMSTATE_UINT64_TEST(rtc_offset, SpaprMachineState, version_before_3),
- VMSTATE_PPC_TIMEBASE_V(tb, sPAPRMachineState, 2),
+ VMSTATE_PPC_TIMEBASE_V(tb, SpaprMachineState, 2),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription*[]) {
@@ -2077,13 +2097,15 @@ static const VMStateDescription vmstate_spapr = {
&vmstate_spapr_irq_map,
&vmstate_spapr_cap_nested_kvm_hv,
&vmstate_spapr_dtb,
+ &vmstate_spapr_cap_large_decr,
+ &vmstate_spapr_cap_ccf_assist,
NULL
}
};
static int htab_save_setup(QEMUFile *f, void *opaque)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
/* "Iteration" header */
if (!spapr->htab_shift) {
@@ -2105,7 +2127,7 @@ static int htab_save_setup(QEMUFile *f, void *opaque)
return 0;
}
-static void htab_save_chunk(QEMUFile *f, sPAPRMachineState *spapr,
+static void htab_save_chunk(QEMUFile *f, SpaprMachineState *spapr,
int chunkstart, int n_valid, int n_invalid)
{
qemu_put_be32(f, chunkstart);
@@ -2122,7 +2144,7 @@ static void htab_save_end_marker(QEMUFile *f)
qemu_put_be16(f, 0);
}
-static void htab_save_first_pass(QEMUFile *f, sPAPRMachineState *spapr,
+static void htab_save_first_pass(QEMUFile *f, SpaprMachineState *spapr,
int64_t max_ns)
{
bool has_timeout = max_ns != -1;
@@ -2170,7 +2192,7 @@ static void htab_save_first_pass(QEMUFile *f, sPAPRMachineState *spapr,
spapr->htab_save_index = index;
}
-static int htab_save_later_pass(QEMUFile *f, sPAPRMachineState *spapr,
+static int htab_save_later_pass(QEMUFile *f, SpaprMachineState *spapr,
int64_t max_ns)
{
bool final = max_ns < 0;
@@ -2248,7 +2270,7 @@ static int htab_save_later_pass(QEMUFile *f, sPAPRMachineState *spapr,
static int htab_save_iterate(QEMUFile *f, void *opaque)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
int fd;
int rc = 0;
@@ -2285,7 +2307,7 @@ static int htab_save_iterate(QEMUFile *f, void *opaque)
static int htab_save_complete(QEMUFile *f, void *opaque)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
int fd;
/* Iteration header */
@@ -2325,7 +2347,7 @@ static int htab_save_complete(QEMUFile *f, void *opaque)
static int htab_load(QEMUFile *f, void *opaque, int version_id)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
uint32_t section_hdr;
int fd = -1;
Error *local_err = NULL;
@@ -2415,7 +2437,7 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id)
static void htab_save_cleanup(void *opaque)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
close_htab_fd(spapr);
}
@@ -2435,7 +2457,7 @@ static void spapr_boot_set(void *opaque, const char *boot_device,
machine->boot_order = g_strdup(boot_device);
}
-static void spapr_create_lmb_dr_connectors(sPAPRMachineState *spapr)
+static void spapr_create_lmb_dr_connectors(SpaprMachineState *spapr)
{
MachineState *machine = MACHINE(spapr);
uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE;
@@ -2502,7 +2524,7 @@ static CPUArchId *spapr_find_cpu_slot(MachineState *ms, uint32_t id, int *idx)
return &ms->possible_cpus->cpus[index];
}
-static void spapr_set_vsmt_mode(sPAPRMachineState *spapr, Error **errp)
+static void spapr_set_vsmt_mode(SpaprMachineState *spapr, Error **errp)
{
Error *local_err = NULL;
bool vsmt_user = !!spapr->vsmt;
@@ -2574,11 +2596,11 @@ out:
error_propagate(errp, local_err);
}
-static void spapr_init_cpus(sPAPRMachineState *spapr)
+static void spapr_init_cpus(SpaprMachineState *spapr)
{
MachineState *machine = MACHINE(spapr);
MachineClass *mc = MACHINE_GET_CLASS(machine);
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
const char *type = spapr_get_cpu_core_type(machine->cpu_type);
const CPUArchIdList *possible_cpus;
int boot_cores_nr = smp_cpus / smp_threads;
@@ -2657,8 +2679,8 @@ static PCIHostState *spapr_create_default_phb(void)
/* pSeries LPAR / sPAPR hardware init */
static void spapr_machine_init(MachineState *machine)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
+ SpaprMachineState *spapr = SPAPR_MACHINE(machine);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
const char *kernel_filename = machine->kernel_filename;
const char *initrd_filename = machine->initrd_filename;
PCIHostState *phb;
@@ -2800,6 +2822,9 @@ static void spapr_machine_init(MachineState *machine)
/* H_CLEAR_MOD/_REF are mandatory in PAPR, but off by default */
kvmppc_enable_clear_ref_mod_hcalls();
+
+ /* Enable H_PAGE_INIT */
+ kvmppc_enable_h_page_init();
}
/* allocate RAM */
@@ -3051,7 +3076,7 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus,
#define CAST(type, obj, name) \
((type *)object_dynamic_cast(OBJECT(obj), (name)))
SCSIDevice *d = CAST(SCSIDevice, dev, TYPE_SCSI_DEVICE);
- sPAPRPHBState *phb = CAST(sPAPRPHBState, dev, TYPE_SPAPR_PCI_HOST_BRIDGE);
+ SpaprPhbState *phb = CAST(SpaprPhbState, dev, TYPE_SPAPR_PCI_HOST_BRIDGE);
VHostSCSICommon *vsc = CAST(VHostSCSICommon, dev, TYPE_VHOST_SCSI_COMMON);
if (d) {
@@ -3131,14 +3156,14 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus,
static char *spapr_get_kvm_type(Object *obj, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
return g_strdup(spapr->kvm_type);
}
static void spapr_set_kvm_type(Object *obj, const char *value, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
g_free(spapr->kvm_type);
spapr->kvm_type = g_strdup(value);
@@ -3146,7 +3171,7 @@ static void spapr_set_kvm_type(Object *obj, const char *value, Error **errp)
static bool spapr_get_modern_hotplug_events(Object *obj, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
return spapr->use_hotplug_event_source;
}
@@ -3154,7 +3179,7 @@ static bool spapr_get_modern_hotplug_events(Object *obj, Error **errp)
static void spapr_set_modern_hotplug_events(Object *obj, bool value,
Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
spapr->use_hotplug_event_source = value;
}
@@ -3166,7 +3191,7 @@ static bool spapr_get_msix_emulation(Object *obj, Error **errp)
static char *spapr_get_resize_hpt(Object *obj, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
switch (spapr->resize_hpt) {
case SPAPR_RESIZE_HPT_DEFAULT:
@@ -3183,7 +3208,7 @@ static char *spapr_get_resize_hpt(Object *obj, Error **errp)
static void spapr_set_resize_hpt(Object *obj, const char *value, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
if (strcmp(value, "default") == 0) {
spapr->resize_hpt = SPAPR_RESIZE_HPT_DEFAULT;
@@ -3212,7 +3237,7 @@ static void spapr_set_vsmt(Object *obj, Visitor *v, const char *name,
static char *spapr_get_ic_mode(Object *obj, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
if (spapr->irq == &spapr_irq_xics_legacy) {
return g_strdup("legacy");
@@ -3228,7 +3253,7 @@ static char *spapr_get_ic_mode(Object *obj, Error **errp)
static void spapr_set_ic_mode(Object *obj, const char *value, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
error_setg(errp, "This machine only uses the legacy XICS backend, don't pass ic-mode");
@@ -3249,14 +3274,14 @@ static void spapr_set_ic_mode(Object *obj, const char *value, Error **errp)
static char *spapr_get_host_model(Object *obj, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
return g_strdup(spapr->host_model);
}
static void spapr_set_host_model(Object *obj, const char *value, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
g_free(spapr->host_model);
spapr->host_model = g_strdup(value);
@@ -3264,14 +3289,14 @@ static void spapr_set_host_model(Object *obj, const char *value, Error **errp)
static char *spapr_get_host_serial(Object *obj, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
return g_strdup(spapr->host_serial);
}
static void spapr_set_host_serial(Object *obj, const char *value, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
g_free(spapr->host_serial);
spapr->host_serial = g_strdup(value);
@@ -3279,8 +3304,8 @@ static void spapr_set_host_serial(Object *obj, const char *value, Error **errp)
static void spapr_instance_init(Object *obj)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
spapr->htab_fd = -1;
spapr->use_hotplug_event_source = true;
@@ -3337,7 +3362,7 @@ static void spapr_instance_init(Object *obj)
static void spapr_machine_finalizefn(Object *obj)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
g_free(spapr->kvm_type);
}
@@ -3357,7 +3382,7 @@ static void spapr_nmi(NMIState *n, int cpu_index, Error **errp)
}
}
-int spapr_lmb_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
+int spapr_lmb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
void *fdt, int *fdt_start_offset, Error **errp)
{
uint64_t addr;
@@ -3374,7 +3399,7 @@ int spapr_lmb_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size,
bool dedicated_hp_event_source, Error **errp)
{
- sPAPRDRConnector *drc;
+ SpaprDrc *drc;
uint32_t nr_lmbs = size/SPAPR_MEMORY_BLOCK_SIZE;
int i;
uint64_t addr = addr_start;
@@ -3423,7 +3448,7 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
Error *local_err = NULL;
- sPAPRMachineState *ms = SPAPR_MACHINE(hotplug_dev);
+ SpaprMachineState *ms = SPAPR_MACHINE(hotplug_dev);
PCDIMMDevice *dimm = PC_DIMM(dev);
uint64_t size, addr;
@@ -3457,8 +3482,8 @@ out:
static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
- const sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(hotplug_dev);
- sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
+ const SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(hotplug_dev);
+ SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
PCDIMMDevice *dimm = PC_DIMM(dev);
Error *local_err = NULL;
uint64_t size;
@@ -3494,16 +3519,16 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
pc_dimm_pre_plug(dimm, MACHINE(hotplug_dev), NULL, errp);
}
-struct sPAPRDIMMState {
+struct SpaprDimmState {
PCDIMMDevice *dimm;
uint32_t nr_lmbs;
- QTAILQ_ENTRY(sPAPRDIMMState) next;
+ QTAILQ_ENTRY(SpaprDimmState) next;
};
-static sPAPRDIMMState *spapr_pending_dimm_unplugs_find(sPAPRMachineState *s,
+static SpaprDimmState *spapr_pending_dimm_unplugs_find(SpaprMachineState *s,
PCDIMMDevice *dimm)
{
- sPAPRDIMMState *dimm_state = NULL;
+ SpaprDimmState *dimm_state = NULL;
QTAILQ_FOREACH(dimm_state, &s->pending_dimm_unplugs, next) {
if (dimm_state->dimm == dimm) {
@@ -3513,11 +3538,11 @@ static sPAPRDIMMState *spapr_pending_dimm_unplugs_find(sPAPRMachineState *s,
return dimm_state;
}
-static sPAPRDIMMState *spapr_pending_dimm_unplugs_add(sPAPRMachineState *spapr,
+static SpaprDimmState *spapr_pending_dimm_unplugs_add(SpaprMachineState *spapr,
uint32_t nr_lmbs,
PCDIMMDevice *dimm)
{
- sPAPRDIMMState *ds = NULL;
+ SpaprDimmState *ds = NULL;
/*
* If this request is for a DIMM whose removal had failed earlier
@@ -3527,7 +3552,7 @@ static sPAPRDIMMState *spapr_pending_dimm_unplugs_add(sPAPRMachineState *spapr,
*/
ds = spapr_pending_dimm_unplugs_find(spapr, dimm);
if (!ds) {
- ds = g_malloc0(sizeof(sPAPRDIMMState));
+ ds = g_malloc0(sizeof(SpaprDimmState));
ds->nr_lmbs = nr_lmbs;
ds->dimm = dimm;
QTAILQ_INSERT_HEAD(&spapr->pending_dimm_unplugs, ds, next);
@@ -3535,17 +3560,17 @@ static sPAPRDIMMState *spapr_pending_dimm_unplugs_add(sPAPRMachineState *spapr,
return ds;
}
-static void spapr_pending_dimm_unplugs_remove(sPAPRMachineState *spapr,
- sPAPRDIMMState *dimm_state)
+static void spapr_pending_dimm_unplugs_remove(SpaprMachineState *spapr,
+ SpaprDimmState *dimm_state)
{
QTAILQ_REMOVE(&spapr->pending_dimm_unplugs, dimm_state, next);
g_free(dimm_state);
}
-static sPAPRDIMMState *spapr_recover_pending_dimm_state(sPAPRMachineState *ms,
+static SpaprDimmState *spapr_recover_pending_dimm_state(SpaprMachineState *ms,
PCDIMMDevice *dimm)
{
- sPAPRDRConnector *drc;
+ SpaprDrc *drc;
uint64_t size = memory_device_get_region_size(MEMORY_DEVICE(dimm),
&error_abort);
uint32_t nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE;
@@ -3574,8 +3599,8 @@ static sPAPRDIMMState *spapr_recover_pending_dimm_state(sPAPRMachineState *ms,
void spapr_lmb_release(DeviceState *dev)
{
HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(dev);
- sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_ctrl);
- sPAPRDIMMState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev));
+ SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_ctrl);
+ SpaprDimmState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev));
/* This information will get lost if a migration occurs
* during the unplug process. In this case recover it. */
@@ -3600,8 +3625,8 @@ void spapr_lmb_release(DeviceState *dev)
static void spapr_memory_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
- sPAPRDIMMState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev));
+ SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
+ SpaprDimmState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev));
pc_dimm_unplug(PC_DIMM(dev), MACHINE(hotplug_dev));
object_property_set_bool(OBJECT(dev), false, "realized", NULL);
@@ -3611,13 +3636,13 @@ static void spapr_memory_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
+ SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
Error *local_err = NULL;
PCDIMMDevice *dimm = PC_DIMM(dev);
uint32_t nr_lmbs;
uint64_t size, addr_start, addr;
int i;
- sPAPRDRConnector *drc;
+ SpaprDrc *drc;
size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &error_abort);
nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE;
@@ -3674,12 +3699,12 @@ void spapr_core_release(DeviceState *dev)
static void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
{
MachineState *ms = MACHINE(hotplug_dev);
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(ms);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(ms);
CPUCore *cc = CPU_CORE(dev);
CPUArchId *core_slot = spapr_find_cpu_slot(ms, cc->core_id, NULL);
if (smc->pre_2_10_has_unused_icps) {
- sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
+ SpaprCpuCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
int i;
for (i = 0; i < cc->nr_threads; i++) {
@@ -3698,9 +3723,9 @@ static
void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
+ SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
int index;
- sPAPRDRConnector *drc;
+ SpaprDrc *drc;
CPUCore *cc = CPU_CORE(dev);
if (!spapr_find_cpu_slot(MACHINE(hotplug_dev), cc->core_id, &index)) {
@@ -3722,10 +3747,10 @@ void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev,
spapr_hotplug_req_remove_by_index(drc);
}
-int spapr_core_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
+int spapr_core_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
void *fdt, int *fdt_start_offset, Error **errp)
{
- sPAPRCPUCore *core = SPAPR_CPU_CORE(drc->dev);
+ SpaprCpuCore *core = SPAPR_CPU_CORE(drc->dev);
CPUState *cs = CPU(core->threads[0]);
PowerPCCPU *cpu = POWERPC_CPU(cs);
DeviceClass *dc = DEVICE_GET_CLASS(cs);
@@ -3746,13 +3771,13 @@ int spapr_core_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
+ SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
MachineClass *mc = MACHINE_GET_CLASS(spapr);
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
- sPAPRCPUCore *core = SPAPR_CPU_CORE(OBJECT(dev));
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprCpuCore *core = SPAPR_CPU_CORE(OBJECT(dev));
CPUCore *cc = CPU_CORE(dev);
CPUState *cs;
- sPAPRDRConnector *drc;
+ SpaprDrc *drc;
Error *local_err = NULL;
CPUArchId *core_slot;
int index;
@@ -3855,10 +3880,10 @@ out:
error_propagate(errp, local_err);
}
-int spapr_phb_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
+int spapr_phb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
void *fdt, int *fdt_start_offset, Error **errp)
{
- sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(drc->dev);
+ SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(drc->dev);
int intc_phandle;
intc_phandle = spapr_irq_get_phandle(spapr, spapr->fdt_blob, errp);
@@ -3881,9 +3906,9 @@ int spapr_phb_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
static void spapr_phb_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
- sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
+ SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
const unsigned windows_supported = spapr_phb_windows_supported(sphb);
if (dev->hotplugged && !smc->dr_phb_enabled) {
@@ -3909,10 +3934,10 @@ static void spapr_phb_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
static void spapr_phb_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
- sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
- sPAPRDRConnector *drc;
+ SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
+ SpaprDrc *drc;
bool hotplugged = spapr_drc_hotplugged(dev);
Error *local_err = NULL;
@@ -3953,8 +3978,8 @@ static void spapr_phb_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
static void spapr_phb_unplug_request(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
- sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
- sPAPRDRConnector *drc;
+ SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
+ SpaprDrc *drc;
drc = spapr_drc_by_id(TYPE_SPAPR_DRC_PHB, sphb->index);
assert(drc);
@@ -3992,9 +4017,9 @@ static void spapr_machine_device_unplug(HotplugHandler *hotplug_dev,
static void spapr_machine_device_unplug_request(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
- sPAPRMachineState *sms = SPAPR_MACHINE(OBJECT(hotplug_dev));
+ SpaprMachineState *sms = SPAPR_MACHINE(OBJECT(hotplug_dev));
MachineClass *mc = MACHINE_GET_CLASS(sms);
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
if (spapr_ovec_test(sms->ov5_cas, OV5_HP_EVT)) {
@@ -4101,7 +4126,7 @@ static const CPUArchIdList *spapr_possible_cpu_arch_ids(MachineState *machine)
return machine->possible_cpus;
}
-static void spapr_phb_placement(sPAPRMachineState *spapr, uint32_t index,
+static void spapr_phb_placement(SpaprMachineState *spapr, uint32_t index,
uint64_t *buid, hwaddr *pio,
hwaddr *mmio32, hwaddr *mmio64,
unsigned n_dma, uint32_t *liobns, Error **errp)
@@ -4153,14 +4178,14 @@ static void spapr_phb_placement(sPAPRMachineState *spapr, uint32_t index,
static ICSState *spapr_ics_get(XICSFabric *dev, int irq)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(dev);
+ SpaprMachineState *spapr = SPAPR_MACHINE(dev);
return ics_valid_irq(spapr->ics, irq) ? spapr->ics : NULL;
}
static void spapr_ics_resend(XICSFabric *dev)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(dev);
+ SpaprMachineState *spapr = SPAPR_MACHINE(dev);
ics_resend(spapr->ics);
}
@@ -4175,7 +4200,7 @@ static ICPState *spapr_icp_get(XICSFabric *xi, int vcpu_id)
static void spapr_pic_print_info(InterruptStatsProvider *obj,
Monitor *mon)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
spapr->irq->print_info(spapr, mon);
}
@@ -4187,7 +4212,7 @@ int spapr_get_vcpu_id(PowerPCCPU *cpu)
void spapr_set_vcpu_id(PowerPCCPU *cpu, int cpu_index, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+ SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
int vcpu_id;
vcpu_id = spapr_vcpu_id(spapr, cpu_index);
@@ -4221,7 +4246,7 @@ PowerPCCPU *spapr_find_cpu(int vcpu_id)
static void spapr_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(oc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(oc);
FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc);
NMIClass *nc = NMI_CLASS(oc);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
@@ -4286,11 +4311,13 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
smc->default_caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_ON;
smc->default_caps.caps[SPAPR_CAP_DFP] = SPAPR_CAP_ON;
- smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN;
- smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN;
- smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN;
+ smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND;
+ smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_WORKAROUND;
+ smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_WORKAROUND;
smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = 16; /* 64kiB */
smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF;
+ smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON;
+ smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF;
spapr_caps_add_properties(smc, &error_abort);
smc->irq = &spapr_irq_xics;
smc->dr_phb_enabled = true;
@@ -4300,10 +4327,10 @@ static const TypeInfo spapr_machine_info = {
.name = TYPE_SPAPR_MACHINE,
.parent = TYPE_MACHINE,
.abstract = true,
- .instance_size = sizeof(sPAPRMachineState),
+ .instance_size = sizeof(SpaprMachineState),
.instance_init = spapr_instance_init,
.instance_finalize = spapr_machine_finalizefn,
- .class_size = sizeof(sPAPRMachineClass),
+ .class_size = sizeof(SpaprMachineClass),
.class_init = spapr_machine_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_FW_PATH_PROVIDER },
@@ -4353,7 +4380,7 @@ DEFINE_SPAPR_MACHINE(4_0, "4.0", true);
*/
static void spapr_machine_3_1_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
static GlobalProperty compat[] = {
{ TYPE_SPAPR_MACHINE, "host-model", "passthrough" },
{ TYPE_SPAPR_MACHINE, "host-serial", "passthrough" },
@@ -4366,6 +4393,10 @@ static void spapr_machine_3_1_class_options(MachineClass *mc)
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
smc->update_dt_enabled = false;
smc->dr_phb_enabled = false;
+ smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN;
+ smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN;
+ smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN;
+ smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_OFF;
}
DEFINE_SPAPR_MACHINE(3_1, "3.1", false);
@@ -4376,7 +4407,7 @@ DEFINE_SPAPR_MACHINE(3_1, "3.1", false);
static void spapr_machine_3_0_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
spapr_machine_3_1_class_options(mc);
compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len);
@@ -4392,7 +4423,7 @@ DEFINE_SPAPR_MACHINE(3_0, "3.0", false);
*/
static void spapr_machine_2_12_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
static GlobalProperty compat[] = {
{ TYPE_POWERPC_CPU, "pre-3.0-migration", "on" },
{ TYPE_SPAPR_CPU_CORE, "pre-3.0-migration", "on" },
@@ -4414,7 +4445,7 @@ DEFINE_SPAPR_MACHINE(2_12, "2.12", false);
static void spapr_machine_2_12_sxxm_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
spapr_machine_2_12_class_options(mc);
smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND;
@@ -4430,7 +4461,7 @@ DEFINE_SPAPR_MACHINE(2_12_sxxm, "2.12-sxxm", false);
static void spapr_machine_2_11_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
spapr_machine_2_12_class_options(mc);
smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_ON;
@@ -4457,7 +4488,7 @@ DEFINE_SPAPR_MACHINE(2_10, "2.10", false);
static void spapr_machine_2_9_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
static GlobalProperty compat[] = {
{ TYPE_POWERPC_CPU, "pre-2.10-migration", "on" },
};
@@ -4494,7 +4525,7 @@ DEFINE_SPAPR_MACHINE(2_8, "2.8", false);
* pseries-2.7
*/
-static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index,
+static void phb_placement_2_7(SpaprMachineState *spapr, uint32_t index,
uint64_t *buid, hwaddr *pio,
hwaddr *mmio32, hwaddr *mmio64,
unsigned n_dma, uint32_t *liobns, Error **errp)
@@ -4545,7 +4576,7 @@ static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index,
static void spapr_machine_2_7_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
static GlobalProperty compat[] = {
{ TYPE_SPAPR_PCI_HOST_BRIDGE, "mem_win_size", "0xf80000000", },
{ TYPE_SPAPR_PCI_HOST_BRIDGE, "mem64_win_size", "0", },
@@ -4587,7 +4618,7 @@ DEFINE_SPAPR_MACHINE(2_6, "2.6", false);
static void spapr_machine_2_5_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
static GlobalProperty compat[] = {
{ "spapr-vlan", "use-rx-buffer-pools", "off" },
};
@@ -4606,7 +4637,7 @@ DEFINE_SPAPR_MACHINE(2_5, "2.5", false);
static void spapr_machine_2_4_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
spapr_machine_2_5_class_options(mc);
smc->dr_lmb_enabled = false;
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
index 64f98ae68d..edc5ed0e0c 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -31,10 +31,11 @@
#include "target/ppc/mmu-hash64.h"
#include "cpu-models.h"
#include "kvm_ppc.h"
+#include "sysemu/qtest.h"
#include "hw/ppc/spapr.h"
-typedef struct sPAPRCapPossible {
+typedef struct SpaprCapPossible {
int num; /* size of vals array below */
const char *help; /* help text for vals */
/*
@@ -46,9 +47,9 @@ typedef struct sPAPRCapPossible {
* point is observed
*/
const char *vals[];
-} sPAPRCapPossible;
+} SpaprCapPossible;
-typedef struct sPAPRCapabilityInfo {
+typedef struct SpaprCapabilityInfo {
const char *name;
const char *description;
int index;
@@ -58,18 +59,18 @@ typedef struct sPAPRCapabilityInfo {
ObjectPropertyAccessor *set;
const char *type;
/* Possible values if this is a custom string type */
- sPAPRCapPossible *possible;
+ SpaprCapPossible *possible;
/* Make sure the virtual hardware can support this capability */
- void (*apply)(sPAPRMachineState *spapr, uint8_t val, Error **errp);
- void (*cpu_apply)(sPAPRMachineState *spapr, PowerPCCPU *cpu,
+ void (*apply)(SpaprMachineState *spapr, uint8_t val, Error **errp);
+ void (*cpu_apply)(SpaprMachineState *spapr, PowerPCCPU *cpu,
uint8_t val, Error **errp);
-} sPAPRCapabilityInfo;
+} SpaprCapabilityInfo;
static void spapr_cap_get_bool(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- sPAPRCapabilityInfo *cap = opaque;
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprCapabilityInfo *cap = opaque;
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
bool value = spapr_get_cap(spapr, cap->index) == SPAPR_CAP_ON;
visit_type_bool(v, name, &value, errp);
@@ -78,8 +79,8 @@ static void spapr_cap_get_bool(Object *obj, Visitor *v, const char *name,
static void spapr_cap_set_bool(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- sPAPRCapabilityInfo *cap = opaque;
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprCapabilityInfo *cap = opaque;
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
bool value;
Error *local_err = NULL;
@@ -97,8 +98,8 @@ static void spapr_cap_set_bool(Object *obj, Visitor *v, const char *name,
static void spapr_cap_get_string(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- sPAPRCapabilityInfo *cap = opaque;
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprCapabilityInfo *cap = opaque;
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
char *val = NULL;
uint8_t value = spapr_get_cap(spapr, cap->index);
@@ -116,8 +117,8 @@ static void spapr_cap_get_string(Object *obj, Visitor *v, const char *name,
static void spapr_cap_set_string(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- sPAPRCapabilityInfo *cap = opaque;
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprCapabilityInfo *cap = opaque;
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
Error *local_err = NULL;
uint8_t i;
char *val;
@@ -149,8 +150,8 @@ out:
static void spapr_cap_get_pagesize(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- sPAPRCapabilityInfo *cap = opaque;
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprCapabilityInfo *cap = opaque;
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
uint8_t val = spapr_get_cap(spapr, cap->index);
uint64_t pagesize = (1ULL << val);
@@ -160,8 +161,8 @@ static void spapr_cap_get_pagesize(Object *obj, Visitor *v, const char *name,
static void spapr_cap_set_pagesize(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- sPAPRCapabilityInfo *cap = opaque;
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprCapabilityInfo *cap = opaque;
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
uint64_t pagesize;
uint8_t val;
Error *local_err = NULL;
@@ -182,7 +183,7 @@ static void spapr_cap_set_pagesize(Object *obj, Visitor *v, const char *name,
spapr->eff.caps[cap->index] = val;
}
-static void cap_htm_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
+static void cap_htm_apply(SpaprMachineState *spapr, uint8_t val, Error **errp)
{
if (!val) {
/* TODO: We don't support disabling htm yet */
@@ -198,7 +199,7 @@ static void cap_htm_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
}
}
-static void cap_vsx_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
+static void cap_vsx_apply(SpaprMachineState *spapr, uint8_t val, Error **errp)
{
PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
CPUPPCState *env = &cpu->env;
@@ -215,7 +216,7 @@ static void cap_vsx_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
}
}
-static void cap_dfp_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
+static void cap_dfp_apply(SpaprMachineState *spapr, uint8_t val, Error **errp)
{
PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
CPUPPCState *env = &cpu->env;
@@ -229,83 +230,97 @@ static void cap_dfp_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
}
}
-sPAPRCapPossible cap_cfpc_possible = {
+SpaprCapPossible cap_cfpc_possible = {
.num = 3,
.vals = {"broken", "workaround", "fixed"},
.help = "broken - no protection, workaround - workaround available,"
" fixed - fixed in hardware",
};
-static void cap_safe_cache_apply(sPAPRMachineState *spapr, uint8_t val,
+static void cap_safe_cache_apply(SpaprMachineState *spapr, uint8_t val,
Error **errp)
{
+ Error *local_err = NULL;
uint8_t kvm_val = kvmppc_get_cap_safe_cache();
if (tcg_enabled() && val) {
- /* TODO - for now only allow broken for TCG */
- error_setg(errp,
-"Requested safe cache capability level not supported by tcg, try a different value for cap-cfpc");
+ /* TCG only supports broken, allow other values and print a warning */
+ error_setg(&local_err,
+ "TCG doesn't support requested feature, cap-cfpc=%s",
+ cap_cfpc_possible.vals[val]);
} else if (kvm_enabled() && (val > kvm_val)) {
error_setg(errp,
"Requested safe cache capability level not supported by kvm, try cap-cfpc=%s",
cap_cfpc_possible.vals[kvm_val]);
}
+
+ if (local_err != NULL)
+ warn_report_err(local_err);
}
-sPAPRCapPossible cap_sbbc_possible = {
+SpaprCapPossible cap_sbbc_possible = {
.num = 3,
.vals = {"broken", "workaround", "fixed"},
.help = "broken - no protection, workaround - workaround available,"
" fixed - fixed in hardware",
};
-static void cap_safe_bounds_check_apply(sPAPRMachineState *spapr, uint8_t val,
+static void cap_safe_bounds_check_apply(SpaprMachineState *spapr, uint8_t val,
Error **errp)
{
+ Error *local_err = NULL;
uint8_t kvm_val = kvmppc_get_cap_safe_bounds_check();
if (tcg_enabled() && val) {
- /* TODO - for now only allow broken for TCG */
- error_setg(errp,
-"Requested safe bounds check capability level not supported by tcg, try a different value for cap-sbbc");
+ /* TCG only supports broken, allow other values and print a warning */
+ error_setg(&local_err,
+ "TCG doesn't support requested feature, cap-sbbc=%s",
+ cap_sbbc_possible.vals[val]);
} else if (kvm_enabled() && (val > kvm_val)) {
error_setg(errp,
"Requested safe bounds check capability level not supported by kvm, try cap-sbbc=%s",
cap_sbbc_possible.vals[kvm_val]);
}
+
+ if (local_err != NULL)
+ warn_report_err(local_err);
}
-sPAPRCapPossible cap_ibs_possible = {
- .num = 4,
+SpaprCapPossible cap_ibs_possible = {
+ .num = 5,
/* Note workaround only maintained for compatibility */
- .vals = {"broken", "workaround", "fixed-ibs", "fixed-ccd"},
- .help = "broken - no protection, fixed-ibs - indirect branch serialisation,"
- " fixed-ccd - cache count disabled",
+ .vals = {"broken", "workaround", "fixed-ibs", "fixed-ccd", "fixed-na"},
+ .help = "broken - no protection, workaround - count cache flush"
+ ", fixed-ibs - indirect branch serialisation,"
+ " fixed-ccd - cache count disabled,"
+ " fixed-na - fixed in hardware (no longer applicable)",
};
-static void cap_safe_indirect_branch_apply(sPAPRMachineState *spapr,
+static void cap_safe_indirect_branch_apply(SpaprMachineState *spapr,
uint8_t val, Error **errp)
{
+ Error *local_err = NULL;
uint8_t kvm_val = kvmppc_get_cap_safe_indirect_branch();
- if (val == SPAPR_CAP_WORKAROUND) { /* Can only be Broken or Fixed */
- error_setg(errp,
-"Requested safe indirect branch capability level \"workaround\" not valid, try cap-ibs=%s",
- cap_ibs_possible.vals[kvm_val]);
- } else if (tcg_enabled() && val) {
- /* TODO - for now only allow broken for TCG */
- error_setg(errp,
-"Requested safe indirect branch capability level not supported by tcg, try a different value for cap-ibs");
- } else if (kvm_enabled() && val && (val != kvm_val)) {
+ if (tcg_enabled() && val) {
+ /* TCG only supports broken, allow other values and print a warning */
+ error_setg(&local_err,
+ "TCG doesn't support requested feature, cap-ibs=%s",
+ cap_ibs_possible.vals[val]);
+ } else if (kvm_enabled() && (val > kvm_val)) {
error_setg(errp,
"Requested safe indirect branch capability level not supported by kvm, try cap-ibs=%s",
cap_ibs_possible.vals[kvm_val]);
}
+
+ if (local_err != NULL) {
+ warn_report_err(local_err);
+ }
}
#define VALUE_DESC_TRISTATE " (broken, workaround, fixed)"
-void spapr_check_pagesize(sPAPRMachineState *spapr, hwaddr pagesize,
+void spapr_check_pagesize(SpaprMachineState *spapr, hwaddr pagesize,
Error **errp)
{
hwaddr maxpagesize = (1ULL << spapr->eff.caps[SPAPR_CAP_HPT_MAXPAGESIZE]);
@@ -322,7 +337,7 @@ void spapr_check_pagesize(sPAPRMachineState *spapr, hwaddr pagesize,
}
}
-static void cap_hpt_maxpagesize_apply(sPAPRMachineState *spapr,
+static void cap_hpt_maxpagesize_apply(SpaprMachineState *spapr,
uint8_t val, Error **errp)
{
if (val < 12) {
@@ -359,7 +374,7 @@ static bool spapr_pagesize_cb(void *opaque, uint32_t seg_pshift,
return true;
}
-static void cap_hpt_maxpagesize_cpu_apply(sPAPRMachineState *spapr,
+static void cap_hpt_maxpagesize_cpu_apply(SpaprMachineState *spapr,
PowerPCCPU *cpu,
uint8_t val, Error **errp)
{
@@ -368,7 +383,7 @@ static void cap_hpt_maxpagesize_cpu_apply(sPAPRMachineState *spapr,
ppc_hash64_filter_pagesizes(cpu, spapr_pagesize_cb, &maxshift);
}
-static void cap_nested_kvm_hv_apply(sPAPRMachineState *spapr,
+static void cap_nested_kvm_hv_apply(SpaprMachineState *spapr,
uint8_t val, Error **errp)
{
if (!val) {
@@ -390,7 +405,75 @@ static void cap_nested_kvm_hv_apply(sPAPRMachineState *spapr,
}
}
-sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
+static void cap_large_decr_apply(SpaprMachineState *spapr,
+ uint8_t val, Error **errp)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
+ PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+
+ if (!val) {
+ return; /* Disabled by default */
+ }
+
+ if (tcg_enabled()) {
+ if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, 0,
+ spapr->max_compat_pvr)) {
+ error_setg(errp,
+ "Large decrementer only supported on POWER9, try -cpu POWER9");
+ return;
+ }
+ } else if (kvm_enabled()) {
+ int kvm_nr_bits = kvmppc_get_cap_large_decr();
+
+ if (!kvm_nr_bits) {
+ error_setg(errp,
+ "No large decrementer support, try cap-large-decr=off");
+ } else if (pcc->lrg_decr_bits != kvm_nr_bits) {
+ error_setg(errp,
+"KVM large decrementer size (%d) differs to model (%d), try -cap-large-decr=off",
+ kvm_nr_bits, pcc->lrg_decr_bits);
+ }
+ }
+}
+
+static void cap_large_decr_cpu_apply(SpaprMachineState *spapr,
+ PowerPCCPU *cpu,
+ uint8_t val, Error **errp)
+{
+ CPUPPCState *env = &cpu->env;
+ target_ulong lpcr = env->spr[SPR_LPCR];
+
+ if (kvm_enabled()) {
+ if (kvmppc_enable_cap_large_decr(cpu, val)) {
+ error_setg(errp,
+ "No large decrementer support, try cap-large-decr=off");
+ }
+ }
+
+ if (val) {
+ lpcr |= LPCR_LD;
+ } else {
+ lpcr &= ~LPCR_LD;
+ }
+ ppc_store_lpcr(cpu, lpcr);
+}
+
+static void cap_ccf_assist_apply(SpaprMachineState *spapr, uint8_t val,
+ Error **errp)
+{
+ uint8_t kvm_val = kvmppc_get_cap_count_cache_flush_assist();
+
+ if (tcg_enabled() && val) {
+ /* TODO - for now only allow broken for TCG */
+ error_setg(errp,
+"Requested count cache flush assist capability level not supported by tcg, try cap-ccf-assist=off");
+ } else if (kvm_enabled() && (val > kvm_val)) {
+ error_setg(errp,
+"Requested count cache flush assist capability level not supported by kvm, try cap-ccf-assist=off");
+ }
+}
+
+SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
[SPAPR_CAP_HTM] = {
.name = "htm",
.description = "Allow Hardware Transactional Memory (HTM)",
@@ -441,7 +524,8 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
[SPAPR_CAP_IBS] = {
.name = "ibs",
.description =
- "Indirect Branch Speculation (broken, fixed-ibs, fixed-ccd)",
+ "Indirect Branch Speculation (broken, workaround, fixed-ibs,"
+ "fixed-ccd, fixed-na)",
.index = SPAPR_CAP_IBS,
.get = spapr_cap_get_string,
.set = spapr_cap_set_string,
@@ -468,16 +552,40 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
.type = "bool",
.apply = cap_nested_kvm_hv_apply,
},
+ [SPAPR_CAP_LARGE_DECREMENTER] = {
+ .name = "large-decr",
+ .description = "Allow Large Decrementer",
+ .index = SPAPR_CAP_LARGE_DECREMENTER,
+ .get = spapr_cap_get_bool,
+ .set = spapr_cap_set_bool,
+ .type = "bool",
+ .apply = cap_large_decr_apply,
+ .cpu_apply = cap_large_decr_cpu_apply,
+ },
+ [SPAPR_CAP_CCF_ASSIST] = {
+ .name = "ccf-assist",
+ .description = "Count Cache Flush Assist via HW Instruction",
+ .index = SPAPR_CAP_CCF_ASSIST,
+ .get = spapr_cap_get_bool,
+ .set = spapr_cap_set_bool,
+ .type = "bool",
+ .apply = cap_ccf_assist_apply,
+ },
};
-static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
+static SpaprCapabilities default_caps_with_cpu(SpaprMachineState *spapr,
const char *cputype)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
- sPAPRCapabilities caps;
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ SpaprCapabilities caps;
caps = smc->default_caps;
+ if (!ppc_type_check_compat(cputype, CPU_POWERPC_LOGICAL_3_00,
+ 0, spapr->max_compat_pvr)) {
+ caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_OFF;
+ }
+
if (!ppc_type_check_compat(cputype, CPU_POWERPC_LOGICAL_2_07,
0, spapr->max_compat_pvr)) {
caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
@@ -514,7 +622,7 @@ static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
int spapr_caps_pre_load(void *opaque)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
/* Set to default so we can tell if this came in with the migration */
spapr->mig = spapr->def;
@@ -523,7 +631,7 @@ int spapr_caps_pre_load(void *opaque)
int spapr_caps_pre_save(void *opaque)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
spapr->mig = spapr->eff;
return 0;
@@ -533,12 +641,12 @@ int spapr_caps_pre_save(void *opaque)
* caps specific one. Otherwise it wouldn't be called when the source
* caps are all defaults, which could still conflict with overridden
* caps on the destination */
-int spapr_caps_post_migration(sPAPRMachineState *spapr)
+int spapr_caps_post_migration(SpaprMachineState *spapr)
{
int i;
bool ok = true;
- sPAPRCapabilities dstcaps = spapr->eff;
- sPAPRCapabilities srccaps;
+ SpaprCapabilities dstcaps = spapr->eff;
+ SpaprCapabilities srccaps;
srccaps = default_caps_with_cpu(spapr, MACHINE(spapr)->cpu_type);
for (i = 0; i < SPAPR_CAP_NUM; i++) {
@@ -549,7 +657,7 @@ int spapr_caps_post_migration(sPAPRMachineState *spapr)
}
for (i = 0; i < SPAPR_CAP_NUM; i++) {
- sPAPRCapabilityInfo *info = &capability_table[i];
+ SpaprCapabilityInfo *info = &capability_table[i];
if (srccaps.caps[i] > dstcaps.caps[i]) {
error_report("cap-%s higher level (%d) in incoming stream than on destination (%d)",
@@ -570,7 +678,7 @@ int spapr_caps_post_migration(sPAPRMachineState *spapr)
#define SPAPR_CAP_MIG_STATE(sname, cap) \
static bool spapr_cap_##sname##_needed(void *opaque) \
{ \
- sPAPRMachineState *spapr = opaque; \
+ SpaprMachineState *spapr = opaque; \
\
return spapr->cmd_line_caps[cap] && \
(spapr->eff.caps[cap] != \
@@ -584,7 +692,7 @@ const VMStateDescription vmstate_spapr_cap_##sname = { \
.needed = spapr_cap_##sname##_needed, \
.fields = (VMStateField[]) { \
VMSTATE_UINT8(mig.caps[cap], \
- sPAPRMachineState), \
+ SpaprMachineState), \
VMSTATE_END_OF_LIST() \
}, \
}
@@ -596,10 +704,12 @@ SPAPR_CAP_MIG_STATE(cfpc, SPAPR_CAP_CFPC);
SPAPR_CAP_MIG_STATE(sbbc, SPAPR_CAP_SBBC);
SPAPR_CAP_MIG_STATE(ibs, SPAPR_CAP_IBS);
SPAPR_CAP_MIG_STATE(nested_kvm_hv, SPAPR_CAP_NESTED_KVM_HV);
+SPAPR_CAP_MIG_STATE(large_decr, SPAPR_CAP_LARGE_DECREMENTER);
+SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST);
-void spapr_caps_init(sPAPRMachineState *spapr)
+void spapr_caps_init(SpaprMachineState *spapr)
{
- sPAPRCapabilities default_caps;
+ SpaprCapabilities default_caps;
int i;
/* Compute the actual set of caps we should run with */
@@ -615,12 +725,12 @@ void spapr_caps_init(sPAPRMachineState *spapr)
}
}
-void spapr_caps_apply(sPAPRMachineState *spapr)
+void spapr_caps_apply(SpaprMachineState *spapr)
{
int i;
for (i = 0; i < SPAPR_CAP_NUM; i++) {
- sPAPRCapabilityInfo *info = &capability_table[i];
+ SpaprCapabilityInfo *info = &capability_table[i];
/*
* If the apply function can't set the desired level and thinks it's
@@ -630,12 +740,12 @@ void spapr_caps_apply(sPAPRMachineState *spapr)
}
}
-void spapr_caps_cpu_apply(sPAPRMachineState *spapr, PowerPCCPU *cpu)
+void spapr_caps_cpu_apply(SpaprMachineState *spapr, PowerPCCPU *cpu)
{
int i;
for (i = 0; i < SPAPR_CAP_NUM; i++) {
- sPAPRCapabilityInfo *info = &capability_table[i];
+ SpaprCapabilityInfo *info = &capability_table[i];
/*
* If the apply function can't set the desired level and thinks it's
@@ -647,14 +757,14 @@ void spapr_caps_cpu_apply(sPAPRMachineState *spapr, PowerPCCPU *cpu)
}
}
-void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp)
+void spapr_caps_add_properties(SpaprMachineClass *smc, Error **errp)
{
Error *local_err = NULL;
ObjectClass *klass = OBJECT_CLASS(smc);
int i;
for (i = 0; i < ARRAY_SIZE(capability_table); i++) {
- sPAPRCapabilityInfo *cap = &capability_table[i];
+ SpaprCapabilityInfo *cap = &capability_table[i];
const char *name = g_strdup_printf("cap-%s", cap->name);
char *desc;
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index ef6cbb9c29..f04e06cdf6 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -28,7 +28,7 @@ static void spapr_cpu_reset(void *opaque)
CPUState *cs = CPU(cpu);
CPUPPCState *env = &cpu->env;
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
- sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
target_ulong lpcr;
cpu_reset(cs);
@@ -116,7 +116,7 @@ const char *spapr_get_cpu_core_type(const char *cpu_type)
static bool slb_shadow_needed(void *opaque)
{
- sPAPRCPUState *spapr_cpu = opaque;
+ SpaprCpuState *spapr_cpu = opaque;
return spapr_cpu->slb_shadow_addr != 0;
}
@@ -127,15 +127,15 @@ static const VMStateDescription vmstate_spapr_cpu_slb_shadow = {
.minimum_version_id = 1,
.needed = slb_shadow_needed,
.fields = (VMStateField[]) {
- VMSTATE_UINT64(slb_shadow_addr, sPAPRCPUState),
- VMSTATE_UINT64(slb_shadow_size, sPAPRCPUState),
+ VMSTATE_UINT64(slb_shadow_addr, SpaprCpuState),
+ VMSTATE_UINT64(slb_shadow_size, SpaprCpuState),
VMSTATE_END_OF_LIST()
}
};
static bool dtl_needed(void *opaque)
{
- sPAPRCPUState *spapr_cpu = opaque;
+ SpaprCpuState *spapr_cpu = opaque;
return spapr_cpu->dtl_addr != 0;
}
@@ -146,15 +146,15 @@ static const VMStateDescription vmstate_spapr_cpu_dtl = {
.minimum_version_id = 1,
.needed = dtl_needed,
.fields = (VMStateField[]) {
- VMSTATE_UINT64(dtl_addr, sPAPRCPUState),
- VMSTATE_UINT64(dtl_size, sPAPRCPUState),
+ VMSTATE_UINT64(dtl_addr, SpaprCpuState),
+ VMSTATE_UINT64(dtl_size, SpaprCpuState),
VMSTATE_END_OF_LIST()
}
};
static bool vpa_needed(void *opaque)
{
- sPAPRCPUState *spapr_cpu = opaque;
+ SpaprCpuState *spapr_cpu = opaque;
return spapr_cpu->vpa_addr != 0;
}
@@ -165,7 +165,7 @@ static const VMStateDescription vmstate_spapr_cpu_vpa = {
.minimum_version_id = 1,
.needed = vpa_needed,
.fields = (VMStateField[]) {
- VMSTATE_UINT64(vpa_addr, sPAPRCPUState),
+ VMSTATE_UINT64(vpa_addr, SpaprCpuState),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription * []) {
@@ -188,7 +188,7 @@ static const VMStateDescription vmstate_spapr_cpu_state = {
}
};
-static void spapr_unrealize_vcpu(PowerPCCPU *cpu, sPAPRCPUCore *sc)
+static void spapr_unrealize_vcpu(PowerPCCPU *cpu, SpaprCpuCore *sc)
{
if (!sc->pre_3_0_migration) {
vmstate_unregister(NULL, &vmstate_spapr_cpu_state, cpu->machine_data);
@@ -206,7 +206,7 @@ static void spapr_unrealize_vcpu(PowerPCCPU *cpu, sPAPRCPUCore *sc)
static void spapr_cpu_core_unrealize(DeviceState *dev, Error **errp)
{
- sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
+ SpaprCpuCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
CPUCore *cc = CPU_CORE(dev);
int i;
@@ -216,8 +216,8 @@ static void spapr_cpu_core_unrealize(DeviceState *dev, Error **errp)
g_free(sc->threads);
}
-static void spapr_realize_vcpu(PowerPCCPU *cpu, sPAPRMachineState *spapr,
- sPAPRCPUCore *sc, Error **errp)
+static void spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
+ SpaprCpuCore *sc, Error **errp)
{
CPUPPCState *env = &cpu->env;
CPUState *cs = CPU(cpu);
@@ -256,9 +256,9 @@ error:
error_propagate(errp, local_err);
}
-static PowerPCCPU *spapr_create_vcpu(sPAPRCPUCore *sc, int i, Error **errp)
+static PowerPCCPU *spapr_create_vcpu(SpaprCpuCore *sc, int i, Error **errp)
{
- sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(sc);
+ SpaprCpuCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(sc);
CPUCore *cc = CPU_CORE(sc);
Object *obj;
char *id;
@@ -285,7 +285,7 @@ static PowerPCCPU *spapr_create_vcpu(sPAPRCPUCore *sc, int i, Error **errp)
goto err;
}
- cpu->machine_data = g_new0(sPAPRCPUState, 1);
+ cpu->machine_data = g_new0(SpaprCpuState, 1);
object_unref(obj);
return cpu;
@@ -296,9 +296,9 @@ err:
return NULL;
}
-static void spapr_delete_vcpu(PowerPCCPU *cpu, sPAPRCPUCore *sc)
+static void spapr_delete_vcpu(PowerPCCPU *cpu, SpaprCpuCore *sc)
{
- sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
cpu->machine_data = NULL;
g_free(spapr_cpu);
@@ -310,10 +310,10 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
/* We don't use SPAPR_MACHINE() in order to exit gracefully if the user
* tries to add a sPAPR CPU core to a non-pseries machine.
*/
- sPAPRMachineState *spapr =
- (sPAPRMachineState *) object_dynamic_cast(qdev_get_machine(),
+ SpaprMachineState *spapr =
+ (SpaprMachineState *) object_dynamic_cast(qdev_get_machine(),
TYPE_SPAPR_MACHINE);
- sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
+ SpaprCpuCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
CPUCore *cc = CPU_CORE(OBJECT(dev));
Error *local_err = NULL;
int i, j;
@@ -352,8 +352,8 @@ err:
}
static Property spapr_cpu_core_properties[] = {
- DEFINE_PROP_INT32("node-id", sPAPRCPUCore, node_id, CPU_UNSET_NUMA_NODE_ID),
- DEFINE_PROP_BOOL("pre-3.0-migration", sPAPRCPUCore, pre_3_0_migration,
+ DEFINE_PROP_INT32("node-id", SpaprCpuCore, node_id, CPU_UNSET_NUMA_NODE_ID),
+ DEFINE_PROP_BOOL("pre-3.0-migration", SpaprCpuCore, pre_3_0_migration,
false),
DEFINE_PROP_END_OF_LIST()
};
@@ -361,7 +361,7 @@ static Property spapr_cpu_core_properties[] = {
static void spapr_cpu_core_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
- sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_CLASS(oc);
+ SpaprCpuCoreClass *scc = SPAPR_CPU_CORE_CLASS(oc);
dc->realize = spapr_cpu_core_realize;
dc->unrealize = spapr_cpu_core_unrealize;
@@ -382,8 +382,8 @@ static const TypeInfo spapr_cpu_core_type_infos[] = {
.name = TYPE_SPAPR_CPU_CORE,
.parent = TYPE_CPU_CORE,
.abstract = true,
- .instance_size = sizeof(sPAPRCPUCore),
- .class_size = sizeof(sPAPRCPUCoreClass),
+ .instance_size = sizeof(SpaprCpuCore),
+ .class_size = sizeof(SpaprCpuCoreClass),
},
DEFINE_SPAPR_CPU_CORE_TYPE("970_v2.2"),
DEFINE_SPAPR_CPU_CORE_TYPE("970mp_v1.0"),
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 2943cf47d4..597f236b9c 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -29,16 +29,16 @@
#define DRC_INDEX_TYPE_SHIFT 28
#define DRC_INDEX_ID_MASK ((1ULL << DRC_INDEX_TYPE_SHIFT) - 1)
-sPAPRDRConnectorType spapr_drc_type(sPAPRDRConnector *drc)
+SpaprDrcType spapr_drc_type(SpaprDrc *drc)
{
- sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+ SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
return 1 << drck->typeshift;
}
-uint32_t spapr_drc_index(sPAPRDRConnector *drc)
+uint32_t spapr_drc_index(SpaprDrc *drc)
{
- sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+ SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
/* no set format for a drc index: it only needs to be globally
* unique. this is how we encode the DRC type on bare-metal
@@ -48,7 +48,7 @@ uint32_t spapr_drc_index(sPAPRDRConnector *drc)
| (drc->id & DRC_INDEX_ID_MASK);
}
-static uint32_t drc_isolate_physical(sPAPRDRConnector *drc)
+static uint32_t drc_isolate_physical(SpaprDrc *drc)
{
switch (drc->state) {
case SPAPR_DRC_STATE_PHYSICAL_POWERON:
@@ -72,7 +72,7 @@ static uint32_t drc_isolate_physical(sPAPRDRConnector *drc)
return RTAS_OUT_SUCCESS;
}
-static uint32_t drc_unisolate_physical(sPAPRDRConnector *drc)
+static uint32_t drc_unisolate_physical(SpaprDrc *drc)
{
switch (drc->state) {
case SPAPR_DRC_STATE_PHYSICAL_UNISOLATE:
@@ -99,7 +99,7 @@ static uint32_t drc_unisolate_physical(sPAPRDRConnector *drc)
return RTAS_OUT_SUCCESS;
}
-static uint32_t drc_isolate_logical(sPAPRDRConnector *drc)
+static uint32_t drc_isolate_logical(SpaprDrc *drc)
{
switch (drc->state) {
case SPAPR_DRC_STATE_LOGICAL_AVAILABLE:
@@ -146,7 +146,7 @@ static uint32_t drc_isolate_logical(sPAPRDRConnector *drc)
return RTAS_OUT_SUCCESS;
}
-static uint32_t drc_unisolate_logical(sPAPRDRConnector *drc)
+static uint32_t drc_unisolate_logical(SpaprDrc *drc)
{
switch (drc->state) {
case SPAPR_DRC_STATE_LOGICAL_UNISOLATE:
@@ -170,7 +170,7 @@ static uint32_t drc_unisolate_logical(sPAPRDRConnector *drc)
return RTAS_OUT_SUCCESS;
}
-static uint32_t drc_set_usable(sPAPRDRConnector *drc)
+static uint32_t drc_set_usable(SpaprDrc *drc)
{
switch (drc->state) {
case SPAPR_DRC_STATE_LOGICAL_AVAILABLE:
@@ -202,7 +202,7 @@ static uint32_t drc_set_usable(sPAPRDRConnector *drc)
return RTAS_OUT_SUCCESS;
}
-static uint32_t drc_set_unusable(sPAPRDRConnector *drc)
+static uint32_t drc_set_unusable(SpaprDrc *drc)
{
switch (drc->state) {
case SPAPR_DRC_STATE_LOGICAL_UNUSABLE:
@@ -226,9 +226,9 @@ static uint32_t drc_set_unusable(sPAPRDRConnector *drc)
return RTAS_OUT_SUCCESS;
}
-static const char *spapr_drc_name(sPAPRDRConnector *drc)
+static const char *spapr_drc_name(SpaprDrc *drc)
{
- sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+ SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
/* human-readable name for a DRC to encode into the DT
* description. this is mainly only used within a guest in place
@@ -261,7 +261,7 @@ static const char *spapr_drc_name(sPAPRDRConnector *drc)
* based on the current allocation/indicator/power states
* for the DR connector.
*/
-static sPAPRDREntitySense physical_entity_sense(sPAPRDRConnector *drc)
+static SpaprDREntitySense physical_entity_sense(SpaprDrc *drc)
{
/* this assumes all PCI devices are assigned to a 'live insertion'
* power domain, where QEMU manages power state automatically as
@@ -272,7 +272,7 @@ static sPAPRDREntitySense physical_entity_sense(sPAPRDRConnector *drc)
: SPAPR_DR_ENTITY_SENSE_EMPTY;
}
-static sPAPRDREntitySense logical_entity_sense(sPAPRDRConnector *drc)
+static SpaprDREntitySense logical_entity_sense(SpaprDrc *drc)
{
switch (drc->state) {
case SPAPR_DRC_STATE_LOGICAL_UNUSABLE:
@@ -290,7 +290,7 @@ static sPAPRDREntitySense logical_entity_sense(sPAPRDRConnector *drc)
static void prop_get_index(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
+ SpaprDrc *drc = SPAPR_DR_CONNECTOR(obj);
uint32_t value = spapr_drc_index(drc);
visit_type_uint32(v, name, &value, errp);
}
@@ -298,7 +298,7 @@ static void prop_get_index(Object *obj, Visitor *v, const char *name,
static void prop_get_fdt(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
+ SpaprDrc *drc = SPAPR_DR_CONNECTOR(obj);
QNull *null = NULL;
Error *err = NULL;
int fdt_offset_next, fdt_offset, fdt_depth;
@@ -374,7 +374,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name,
} while (fdt_depth != 0);
}
-void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, Error **errp)
+void spapr_drc_attach(SpaprDrc *drc, DeviceState *d, Error **errp)
{
trace_spapr_drc_attach(spapr_drc_index(drc));
@@ -393,9 +393,9 @@ void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, Error **errp)
NULL, 0, NULL);
}
-static void spapr_drc_release(sPAPRDRConnector *drc)
+static void spapr_drc_release(SpaprDrc *drc)
{
- sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+ SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
drck->release(drc->dev);
@@ -407,9 +407,9 @@ static void spapr_drc_release(sPAPRDRConnector *drc)
drc->dev = NULL;
}
-void spapr_drc_detach(sPAPRDRConnector *drc)
+void spapr_drc_detach(SpaprDrc *drc)
{
- sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+ SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
trace_spapr_drc_detach(spapr_drc_index(drc));
@@ -425,9 +425,9 @@ void spapr_drc_detach(sPAPRDRConnector *drc)
spapr_drc_release(drc);
}
-void spapr_drc_reset(sPAPRDRConnector *drc)
+void spapr_drc_reset(SpaprDrc *drc)
{
- sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+ SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
trace_spapr_drc_reset(spapr_drc_index(drc));
@@ -456,8 +456,8 @@ void spapr_drc_reset(sPAPRDRConnector *drc)
bool spapr_drc_needed(void *opaque)
{
- sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque;
- sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+ SpaprDrc *drc = (SpaprDrc *)opaque;
+ SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
/* If no dev is plugged in there is no need to migrate the DRC state */
if (!drc->dev) {
@@ -477,14 +477,14 @@ static const VMStateDescription vmstate_spapr_drc = {
.minimum_version_id = 1,
.needed = spapr_drc_needed,
.fields = (VMStateField []) {
- VMSTATE_UINT32(state, sPAPRDRConnector),
+ VMSTATE_UINT32(state, SpaprDrc),
VMSTATE_END_OF_LIST()
}
};
static void realize(DeviceState *d, Error **errp)
{
- sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
+ SpaprDrc *drc = SPAPR_DR_CONNECTOR(d);
Object *root_container;
gchar *link_name;
gchar *child_name;
@@ -517,7 +517,7 @@ static void realize(DeviceState *d, Error **errp)
static void unrealize(DeviceState *d, Error **errp)
{
- sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
+ SpaprDrc *drc = SPAPR_DR_CONNECTOR(d);
Object *root_container;
gchar *name;
@@ -529,10 +529,10 @@ static void unrealize(DeviceState *d, Error **errp)
g_free(name);
}
-sPAPRDRConnector *spapr_dr_connector_new(Object *owner, const char *type,
+SpaprDrc *spapr_dr_connector_new(Object *owner, const char *type,
uint32_t id)
{
- sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(object_new(type));
+ SpaprDrc *drc = SPAPR_DR_CONNECTOR(object_new(type));
char *prop_name;
drc->id = id;
@@ -549,8 +549,8 @@ sPAPRDRConnector *spapr_dr_connector_new(Object *owner, const char *type,
static void spapr_dr_connector_instance_init(Object *obj)
{
- sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
- sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+ SpaprDrc *drc = SPAPR_DR_CONNECTOR(obj);
+ SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
object_property_add_uint32_ptr(obj, "id", &drc->id, NULL);
object_property_add(obj, "index", "uint32", prop_get_index,
@@ -574,8 +574,8 @@ static void spapr_dr_connector_class_init(ObjectClass *k, void *data)
static bool drc_physical_needed(void *opaque)
{
- sPAPRDRCPhysical *drcp = (sPAPRDRCPhysical *)opaque;
- sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(drcp);
+ SpaprDrcPhysical *drcp = (SpaprDrcPhysical *)opaque;
+ SpaprDrc *drc = SPAPR_DR_CONNECTOR(drcp);
if ((drc->dev && (drcp->dr_indicator == SPAPR_DR_INDICATOR_ACTIVE))
|| (!drc->dev && (drcp->dr_indicator == SPAPR_DR_INDICATOR_INACTIVE))) {
@@ -590,15 +590,15 @@ static const VMStateDescription vmstate_spapr_drc_physical = {
.minimum_version_id = 1,
.needed = drc_physical_needed,
.fields = (VMStateField []) {
- VMSTATE_UINT32(dr_indicator, sPAPRDRCPhysical),
+ VMSTATE_UINT32(dr_indicator, SpaprDrcPhysical),
VMSTATE_END_OF_LIST()
}
};
static void drc_physical_reset(void *opaque)
{
- sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(opaque);
- sPAPRDRCPhysical *drcp = SPAPR_DRC_PHYSICAL(drc);
+ SpaprDrc *drc = SPAPR_DR_CONNECTOR(opaque);
+ SpaprDrcPhysical *drcp = SPAPR_DRC_PHYSICAL(drc);
if (drc->dev) {
drcp->dr_indicator = SPAPR_DR_INDICATOR_ACTIVE;
@@ -609,7 +609,7 @@ static void drc_physical_reset(void *opaque)
static void realize_physical(DeviceState *d, Error **errp)
{
- sPAPRDRCPhysical *drcp = SPAPR_DRC_PHYSICAL(d);
+ SpaprDrcPhysical *drcp = SPAPR_DRC_PHYSICAL(d);
Error *local_err = NULL;
realize(d, &local_err);
@@ -625,7 +625,7 @@ static void realize_physical(DeviceState *d, Error **errp)
static void unrealize_physical(DeviceState *d, Error **errp)
{
- sPAPRDRCPhysical *drcp = SPAPR_DRC_PHYSICAL(d);
+ SpaprDrcPhysical *drcp = SPAPR_DRC_PHYSICAL(d);
Error *local_err = NULL;
unrealize(d, &local_err);
@@ -641,7 +641,7 @@ static void unrealize_physical(DeviceState *d, Error **errp)
static void spapr_drc_physical_class_init(ObjectClass *k, void *data)
{
DeviceClass *dk = DEVICE_CLASS(k);
- sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
+ SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
dk->realize = realize_physical;
dk->unrealize = unrealize_physical;
@@ -654,7 +654,7 @@ static void spapr_drc_physical_class_init(ObjectClass *k, void *data)
static void spapr_drc_logical_class_init(ObjectClass *k, void *data)
{
- sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
+ SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
drck->dr_entity_sense = logical_entity_sense;
drck->isolate = drc_isolate_logical;
@@ -665,7 +665,7 @@ static void spapr_drc_logical_class_init(ObjectClass *k, void *data)
static void spapr_drc_cpu_class_init(ObjectClass *k, void *data)
{
- sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
+ SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU;
drck->typename = "CPU";
@@ -676,7 +676,7 @@ static void spapr_drc_cpu_class_init(ObjectClass *k, void *data)
static void spapr_drc_pci_class_init(ObjectClass *k, void *data)
{
- sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
+ SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI;
drck->typename = "28";
@@ -687,7 +687,7 @@ static void spapr_drc_pci_class_init(ObjectClass *k, void *data)
static void spapr_drc_lmb_class_init(ObjectClass *k, void *data)
{
- sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
+ SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB;
drck->typename = "MEM";
@@ -698,7 +698,7 @@ static void spapr_drc_lmb_class_init(ObjectClass *k, void *data)
static void spapr_drc_phb_class_init(ObjectClass *k, void *data)
{
- sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
+ SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB;
drck->typename = "PHB";
@@ -710,9 +710,9 @@ static void spapr_drc_phb_class_init(ObjectClass *k, void *data)
static const TypeInfo spapr_dr_connector_info = {
.name = TYPE_SPAPR_DR_CONNECTOR,
.parent = TYPE_DEVICE,
- .instance_size = sizeof(sPAPRDRConnector),
+ .instance_size = sizeof(SpaprDrc),
.instance_init = spapr_dr_connector_instance_init,
- .class_size = sizeof(sPAPRDRConnectorClass),
+ .class_size = sizeof(SpaprDrcClass),
.class_init = spapr_dr_connector_class_init,
.abstract = true,
};
@@ -720,7 +720,7 @@ static const TypeInfo spapr_dr_connector_info = {
static const TypeInfo spapr_drc_physical_info = {
.name = TYPE_SPAPR_DRC_PHYSICAL,
.parent = TYPE_SPAPR_DR_CONNECTOR,
- .instance_size = sizeof(sPAPRDRCPhysical),
+ .instance_size = sizeof(SpaprDrcPhysical),
.class_init = spapr_drc_physical_class_init,
.abstract = true,
};
@@ -753,13 +753,13 @@ static const TypeInfo spapr_drc_lmb_info = {
static const TypeInfo spapr_drc_phb_info = {
.name = TYPE_SPAPR_DRC_PHB,
.parent = TYPE_SPAPR_DRC_LOGICAL,
- .instance_size = sizeof(sPAPRDRConnector),
+ .instance_size = sizeof(SpaprDrc),
.class_init = spapr_drc_phb_class_init,
};
/* helper functions for external users */
-sPAPRDRConnector *spapr_drc_by_index(uint32_t index)
+SpaprDrc *spapr_drc_by_index(uint32_t index)
{
Object *obj;
gchar *name;
@@ -771,9 +771,9 @@ sPAPRDRConnector *spapr_drc_by_index(uint32_t index)
return !obj ? NULL : SPAPR_DR_CONNECTOR(obj);
}
-sPAPRDRConnector *spapr_drc_by_id(const char *type, uint32_t id)
+SpaprDrc *spapr_drc_by_id(const char *type, uint32_t id)
{
- sPAPRDRConnectorClass *drck
+ SpaprDrcClass *drck
= SPAPR_DR_CONNECTOR_CLASS(object_class_by_name(type));
return spapr_drc_by_index(drck->typeshift << DRC_INDEX_TYPE_SHIFT
@@ -787,7 +787,7 @@ sPAPRDRConnector *spapr_drc_by_id(const char *type, uint32_t id)
* @path: path in the DT to generate properties
* @owner: parent Object/DeviceState for which to generate DRC
* descriptions for
- * @drc_type_mask: mask of sPAPRDRConnectorType values corresponding
+ * @drc_type_mask: mask of SpaprDrcType values corresponding
* to the types of DRCs to generate entries for
*
* generate OF properties to describe DRC topology/indices to guests
@@ -826,8 +826,8 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
object_property_iter_init(&iter, root_container);
while ((prop = object_property_iter_next(&iter))) {
Object *obj;
- sPAPRDRConnector *drc;
- sPAPRDRConnectorClass *drck;
+ SpaprDrc *drc;
+ SpaprDrcClass *drck;
uint32_t drc_index, drc_power_domain;
if (!strstart(prop->type, "link<", NULL)) {
@@ -918,8 +918,8 @@ out:
static uint32_t rtas_set_isolation_state(uint32_t idx, uint32_t state)
{
- sPAPRDRConnector *drc = spapr_drc_by_index(idx);
- sPAPRDRConnectorClass *drck;
+ SpaprDrc *drc = spapr_drc_by_index(idx);
+ SpaprDrcClass *drck;
if (!drc) {
return RTAS_OUT_NO_SUCH_INDICATOR;
@@ -943,7 +943,7 @@ static uint32_t rtas_set_isolation_state(uint32_t idx, uint32_t state)
static uint32_t rtas_set_allocation_state(uint32_t idx, uint32_t state)
{
- sPAPRDRConnector *drc = spapr_drc_by_index(idx);
+ SpaprDrc *drc = spapr_drc_by_index(idx);
if (!drc || !object_dynamic_cast(OBJECT(drc), TYPE_SPAPR_DRC_LOGICAL)) {
return RTAS_OUT_NO_SUCH_INDICATOR;
@@ -965,7 +965,7 @@ static uint32_t rtas_set_allocation_state(uint32_t idx, uint32_t state)
static uint32_t rtas_set_dr_indicator(uint32_t idx, uint32_t state)
{
- sPAPRDRConnector *drc = spapr_drc_by_index(idx);
+ SpaprDrc *drc = spapr_drc_by_index(idx);
if (!drc || !object_dynamic_cast(OBJECT(drc), TYPE_SPAPR_DRC_PHYSICAL)) {
return RTAS_OUT_NO_SUCH_INDICATOR;
@@ -982,7 +982,7 @@ static uint32_t rtas_set_dr_indicator(uint32_t idx, uint32_t state)
return RTAS_OUT_SUCCESS;
}
-static void rtas_set_indicator(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_set_indicator(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token,
uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets)
@@ -1017,7 +1017,7 @@ out:
rtas_st(rets, 0, ret);
}
-static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_get_sensor_state(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args, uint32_t nret,
target_ulong rets)
@@ -1025,8 +1025,8 @@ static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPRMachineState *spapr,
uint32_t sensor_type;
uint32_t sensor_index;
uint32_t sensor_state = 0;
- sPAPRDRConnector *drc;
- sPAPRDRConnectorClass *drck;
+ SpaprDrc *drc;
+ SpaprDrcClass *drck;
uint32_t ret = RTAS_OUT_SUCCESS;
if (nargs != 2 || nret != 2) {
@@ -1079,7 +1079,7 @@ static void configure_connector_st(target_ulong addr, target_ulong offset,
}
static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args, uint32_t nret,
target_ulong rets)
@@ -1087,9 +1087,9 @@ static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
uint64_t wa_addr;
uint64_t wa_offset;
uint32_t drc_index;
- sPAPRDRConnector *drc;
- sPAPRDRConnectorClass *drck;
- sPAPRDRCCResponse resp = SPAPR_DR_CC_RESPONSE_CONTINUE;
+ SpaprDrc *drc;
+ SpaprDrcClass *drck;
+ SpaprDRCCResponse resp = SPAPR_DR_CC_RESPONSE_CONTINUE;
int rc;
if (nargs != 2 || nret != 1) {
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index ab9a1f0063..ae0f093f59 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -229,18 +229,18 @@ static const char * const event_names[EVENT_CLASS_MAX] = {
[EVENT_CLASS_IO] = "ibm,io-events",
};
-struct sPAPREventSource {
+struct SpaprEventSource {
int irq;
uint32_t mask;
bool enabled;
};
-static sPAPREventSource *spapr_event_sources_new(void)
+static SpaprEventSource *spapr_event_sources_new(void)
{
- return g_new0(sPAPREventSource, EVENT_CLASS_MAX);
+ return g_new0(SpaprEventSource, EVENT_CLASS_MAX);
}
-static void spapr_event_sources_register(sPAPREventSource *event_sources,
+static void spapr_event_sources_register(SpaprEventSource *event_sources,
EventClassIndex index, int irq)
{
/* we only support 1 irq per event class at the moment */
@@ -251,8 +251,8 @@ static void spapr_event_sources_register(sPAPREventSource *event_sources,
event_sources[index].enabled = true;
}
-static const sPAPREventSource *
-spapr_event_sources_get_source(sPAPREventSource *event_sources,
+static const SpaprEventSource *
+spapr_event_sources_get_source(SpaprEventSource *event_sources,
EventClassIndex index)
{
g_assert(index < EVENT_CLASS_MAX);
@@ -261,11 +261,11 @@ spapr_event_sources_get_source(sPAPREventSource *event_sources,
return &event_sources[index];
}
-void spapr_dt_events(sPAPRMachineState *spapr, void *fdt)
+void spapr_dt_events(SpaprMachineState *spapr, void *fdt)
{
uint32_t irq_ranges[EVENT_CLASS_MAX * 2];
int i, count = 0, event_sources;
- sPAPREventSource *events = spapr->event_sources;
+ SpaprEventSource *events = spapr->event_sources;
g_assert(events);
@@ -274,7 +274,7 @@ void spapr_dt_events(sPAPRMachineState *spapr, void *fdt)
for (i = 0, count = 0; i < EVENT_CLASS_MAX; i++) {
int node_offset;
uint32_t interrupts[2];
- const sPAPREventSource *source =
+ const SpaprEventSource *source =
spapr_event_sources_get_source(events, i);
const char *source_name = event_names[i];
@@ -298,10 +298,10 @@ void spapr_dt_events(sPAPRMachineState *spapr, void *fdt)
irq_ranges, count * sizeof(uint32_t))));
}
-static const sPAPREventSource *
-rtas_event_log_to_source(sPAPRMachineState *spapr, int log_type)
+static const SpaprEventSource *
+rtas_event_log_to_source(SpaprMachineState *spapr, int log_type)
{
- const sPAPREventSource *source;
+ const SpaprEventSource *source;
g_assert(spapr->event_sources);
@@ -325,9 +325,9 @@ rtas_event_log_to_source(sPAPRMachineState *spapr, int log_type)
return source;
}
-static int rtas_event_log_to_irq(sPAPRMachineState *spapr, int log_type)
+static int rtas_event_log_to_irq(SpaprMachineState *spapr, int log_type)
{
- const sPAPREventSource *source;
+ const SpaprEventSource *source;
source = rtas_event_log_to_source(spapr, log_type);
g_assert(source);
@@ -336,24 +336,24 @@ static int rtas_event_log_to_irq(sPAPRMachineState *spapr, int log_type)
return source->irq;
}
-static uint32_t spapr_event_log_entry_type(sPAPREventLogEntry *entry)
+static uint32_t spapr_event_log_entry_type(SpaprEventLogEntry *entry)
{
return entry->summary & RTAS_LOG_TYPE_MASK;
}
-static void rtas_event_log_queue(sPAPRMachineState *spapr,
- sPAPREventLogEntry *entry)
+static void rtas_event_log_queue(SpaprMachineState *spapr,
+ SpaprEventLogEntry *entry)
{
QTAILQ_INSERT_TAIL(&spapr->pending_events, entry, next);
}
-static sPAPREventLogEntry *rtas_event_log_dequeue(sPAPRMachineState *spapr,
+static SpaprEventLogEntry *rtas_event_log_dequeue(SpaprMachineState *spapr,
uint32_t event_mask)
{
- sPAPREventLogEntry *entry = NULL;
+ SpaprEventLogEntry *entry = NULL;
QTAILQ_FOREACH(entry, &spapr->pending_events, next) {
- const sPAPREventSource *source =
+ const SpaprEventSource *source =
rtas_event_log_to_source(spapr,
spapr_event_log_entry_type(entry));
@@ -371,11 +371,11 @@ static sPAPREventLogEntry *rtas_event_log_dequeue(sPAPRMachineState *spapr,
static bool rtas_event_log_contains(uint32_t event_mask)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
- sPAPREventLogEntry *entry = NULL;
+ SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+ SpaprEventLogEntry *entry = NULL;
QTAILQ_FOREACH(entry, &spapr->pending_events, next) {
- const sPAPREventSource *source =
+ const SpaprEventSource *source =
rtas_event_log_to_source(spapr,
spapr_event_log_entry_type(entry));
@@ -401,7 +401,7 @@ static void spapr_init_v6hdr(struct rtas_event_log_v6 *v6hdr)
static void spapr_init_maina(struct rtas_event_log_v6_maina *maina,
int section_count)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+ SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
struct tm tm;
int year;
@@ -424,15 +424,15 @@ static void spapr_init_maina(struct rtas_event_log_v6_maina *maina,
static void spapr_powerdown_req(Notifier *n, void *opaque)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
- sPAPREventLogEntry *entry;
+ SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+ SpaprEventLogEntry *entry;
struct rtas_event_log_v6 *v6hdr;
struct rtas_event_log_v6_maina *maina;
struct rtas_event_log_v6_mainb *mainb;
struct rtas_event_log_v6_epow *epow;
struct epow_extended_log *new_epow;
- entry = g_new(sPAPREventLogEntry, 1);
+ entry = g_new(SpaprEventLogEntry, 1);
new_epow = g_malloc0(sizeof(*new_epow));
entry->extended_log = new_epow;
@@ -473,18 +473,18 @@ static void spapr_powerdown_req(Notifier *n, void *opaque)
}
static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action,
- sPAPRDRConnectorType drc_type,
+ SpaprDrcType drc_type,
union drc_identifier *drc_id)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
- sPAPREventLogEntry *entry;
+ SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+ SpaprEventLogEntry *entry;
struct hp_extended_log *new_hp;
struct rtas_event_log_v6 *v6hdr;
struct rtas_event_log_v6_maina *maina;
struct rtas_event_log_v6_mainb *mainb;
struct rtas_event_log_v6_hp *hp;
- entry = g_new(sPAPREventLogEntry, 1);
+ entry = g_new(SpaprEventLogEntry, 1);
new_hp = g_malloc0(sizeof(struct hp_extended_log));
entry->extended_log = new_hp;
@@ -558,9 +558,9 @@ static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action,
rtas_event_log_to_irq(spapr, RTAS_LOG_TYPE_HOTPLUG)));
}
-void spapr_hotplug_req_add_by_index(sPAPRDRConnector *drc)
+void spapr_hotplug_req_add_by_index(SpaprDrc *drc)
{
- sPAPRDRConnectorType drc_type = spapr_drc_type(drc);
+ SpaprDrcType drc_type = spapr_drc_type(drc);
union drc_identifier drc_id;
drc_id.index = spapr_drc_index(drc);
@@ -568,9 +568,9 @@ void spapr_hotplug_req_add_by_index(sPAPRDRConnector *drc)
RTAS_LOG_V6_HP_ACTION_ADD, drc_type, &drc_id);
}
-void spapr_hotplug_req_remove_by_index(sPAPRDRConnector *drc)
+void spapr_hotplug_req_remove_by_index(SpaprDrc *drc)
{
- sPAPRDRConnectorType drc_type = spapr_drc_type(drc);
+ SpaprDrcType drc_type = spapr_drc_type(drc);
union drc_identifier drc_id;
drc_id.index = spapr_drc_index(drc);
@@ -578,7 +578,7 @@ void spapr_hotplug_req_remove_by_index(sPAPRDRConnector *drc)
RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, &drc_id);
}
-void spapr_hotplug_req_add_by_count(sPAPRDRConnectorType drc_type,
+void spapr_hotplug_req_add_by_count(SpaprDrcType drc_type,
uint32_t count)
{
union drc_identifier drc_id;
@@ -588,7 +588,7 @@ void spapr_hotplug_req_add_by_count(sPAPRDRConnectorType drc_type,
RTAS_LOG_V6_HP_ACTION_ADD, drc_type, &drc_id);
}
-void spapr_hotplug_req_remove_by_count(sPAPRDRConnectorType drc_type,
+void spapr_hotplug_req_remove_by_count(SpaprDrcType drc_type,
uint32_t count)
{
union drc_identifier drc_id;
@@ -598,7 +598,7 @@ void spapr_hotplug_req_remove_by_count(sPAPRDRConnectorType drc_type,
RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, &drc_id);
}
-void spapr_hotplug_req_add_by_count_indexed(sPAPRDRConnectorType drc_type,
+void spapr_hotplug_req_add_by_count_indexed(SpaprDrcType drc_type,
uint32_t count, uint32_t index)
{
union drc_identifier drc_id;
@@ -609,7 +609,7 @@ void spapr_hotplug_req_add_by_count_indexed(sPAPRDRConnectorType drc_type,
RTAS_LOG_V6_HP_ACTION_ADD, drc_type, &drc_id);
}
-void spapr_hotplug_req_remove_by_count_indexed(sPAPRDRConnectorType drc_type,
+void spapr_hotplug_req_remove_by_count_indexed(SpaprDrcType drc_type,
uint32_t count, uint32_t index)
{
union drc_identifier drc_id;
@@ -620,14 +620,14 @@ void spapr_hotplug_req_remove_by_count_indexed(sPAPRDRConnectorType drc_type,
RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, &drc_id);
}
-static void check_exception(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void check_exception(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
{
uint32_t mask, buf, len, event_len;
uint64_t xinfo;
- sPAPREventLogEntry *event;
+ SpaprEventLogEntry *event;
struct rtas_error_log header;
int i;
@@ -671,7 +671,7 @@ static void check_exception(PowerPCCPU *cpu, sPAPRMachineState *spapr,
*/
for (i = 0; i < EVENT_CLASS_MAX; i++) {
if (rtas_event_log_contains(EVENT_CLASS_MASK(i))) {
- const sPAPREventSource *source =
+ const SpaprEventSource *source =
spapr_event_sources_get_source(spapr->event_sources, i);
g_assert(source->enabled);
@@ -685,7 +685,7 @@ out_no_events:
rtas_st(rets, 0, RTAS_OUT_NO_ERRORS_FOUND);
}
-static void event_scan(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void event_scan(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
@@ -697,9 +697,9 @@ static void event_scan(PowerPCCPU *cpu, sPAPRMachineState *spapr,
rtas_st(rets, 0, RTAS_OUT_NO_ERRORS_FOUND);
}
-void spapr_clear_pending_events(sPAPRMachineState *spapr)
+void spapr_clear_pending_events(SpaprMachineState *spapr)
{
- sPAPREventLogEntry *entry = NULL, *next_entry;
+ SpaprEventLogEntry *entry = NULL, *next_entry;
QTAILQ_FOREACH_SAFE(entry, &spapr->pending_events, next, next_entry) {
QTAILQ_REMOVE(&spapr->pending_events, entry, next);
@@ -708,7 +708,7 @@ void spapr_clear_pending_events(sPAPRMachineState *spapr)
}
}
-void spapr_events_init(sPAPRMachineState *spapr)
+void spapr_events_init(SpaprMachineState *spapr)
{
int epow_irq = SPAPR_IRQ_EPOW;
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 476bad6271..0761e10142 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -34,7 +34,7 @@ static inline bool valid_ptex(PowerPCCPU *cpu, target_ulong ptex)
return true;
}
-static bool is_ram_address(sPAPRMachineState *spapr, hwaddr addr)
+static bool is_ram_address(SpaprMachineState *spapr, hwaddr addr)
{
MachineState *machine = MACHINE(spapr);
DeviceMemoryState *dms = machine->device_memory;
@@ -50,7 +50,7 @@ static bool is_ram_address(sPAPRMachineState *spapr, hwaddr addr)
return false;
}
-static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_enter(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong flags = args[0];
@@ -160,7 +160,7 @@ static RemoveResult remove_hpte(PowerPCCPU *cpu, target_ulong ptex,
return REMOVE_SUCCESS;
}
-static target_ulong h_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_remove(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
CPUPPCState *env = &cpu->env;
@@ -208,7 +208,7 @@ static target_ulong h_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
#define H_BULK_REMOVE_MAX_BATCH 4
-static target_ulong h_bulk_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_bulk_remove(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
CPUPPCState *env = &cpu->env;
@@ -260,7 +260,7 @@ static target_ulong h_bulk_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return rc;
}
-static target_ulong h_protect(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_protect(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
CPUPPCState *env = &cpu->env;
@@ -299,7 +299,7 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-static target_ulong h_read(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_read(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong flags = args[0];
@@ -328,7 +328,7 @@ static target_ulong h_read(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-struct sPAPRPendingHPT {
+struct SpaprPendingHpt {
/* These fields are read-only after initialization */
int shift;
QemuThread thread;
@@ -342,7 +342,7 @@ struct sPAPRPendingHPT {
void *hpt;
};
-static void free_pending_hpt(sPAPRPendingHPT *pending)
+static void free_pending_hpt(SpaprPendingHpt *pending)
{
if (pending->hpt) {
qemu_vfree(pending->hpt);
@@ -353,7 +353,7 @@ static void free_pending_hpt(sPAPRPendingHPT *pending)
static void *hpt_prepare_thread(void *opaque)
{
- sPAPRPendingHPT *pending = opaque;
+ SpaprPendingHpt *pending = opaque;
size_t size = 1ULL << pending->shift;
pending->hpt = qemu_memalign(size, size);
@@ -379,9 +379,9 @@ static void *hpt_prepare_thread(void *opaque)
}
/* Must be called with BQL held */
-static void cancel_hpt_prepare(sPAPRMachineState *spapr)
+static void cancel_hpt_prepare(SpaprMachineState *spapr)
{
- sPAPRPendingHPT *pending = spapr->pending_hpt;
+ SpaprPendingHpt *pending = spapr->pending_hpt;
/* Let the thread know it's cancelled */
spapr->pending_hpt = NULL;
@@ -438,13 +438,13 @@ static target_ulong resize_hpt_convert_rc(int ret)
}
static target_ulong h_resize_hpt_prepare(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
target_ulong flags = args[0];
int shift = args[1];
- sPAPRPendingHPT *pending = spapr->pending_hpt;
+ SpaprPendingHpt *pending = spapr->pending_hpt;
uint64_t current_ram_size;
int rc;
@@ -503,7 +503,7 @@ static target_ulong h_resize_hpt_prepare(PowerPCCPU *cpu,
/* start new prepare */
- pending = g_new0(sPAPRPendingHPT, 1);
+ pending = g_new0(SpaprPendingHpt, 1);
pending->shift = shift;
pending->ret = H_HARDWARE;
@@ -672,7 +672,7 @@ static void do_push_sregs_to_kvm_pr(CPUState *cs, run_on_cpu_data data)
}
}
-static void push_sregs_to_kvm_pr(sPAPRMachineState *spapr)
+static void push_sregs_to_kvm_pr(SpaprMachineState *spapr)
{
CPUState *cs;
@@ -691,13 +691,13 @@ static void push_sregs_to_kvm_pr(sPAPRMachineState *spapr)
}
static target_ulong h_resize_hpt_commit(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
target_ulong flags = args[0];
target_ulong shift = args[1];
- sPAPRPendingHPT *pending = spapr->pending_hpt;
+ SpaprPendingHpt *pending = spapr->pending_hpt;
int rc;
size_t newsize;
@@ -759,7 +759,7 @@ static target_ulong h_resize_hpt_commit(PowerPCCPU *cpu,
return rc;
}
-static target_ulong h_set_sprg0(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_set_sprg0(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
cpu_synchronize_state(CPU(cpu));
@@ -768,7 +768,7 @@ static target_ulong h_set_sprg0(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-static target_ulong h_set_dabr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_set_dabr(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
if (!has_spr(cpu, SPR_DABR)) {
@@ -786,7 +786,7 @@ static target_ulong h_set_dabr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-static target_ulong h_set_xdabr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_set_xdabr(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong dabrx = args[1];
@@ -807,7 +807,7 @@ static target_ulong h_set_xdabr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-static target_ulong h_page_init(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_page_init(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong flags = args[0];
@@ -882,7 +882,7 @@ static target_ulong register_vpa(PowerPCCPU *cpu, target_ulong vpa)
{
CPUState *cs = CPU(cpu);
CPUPPCState *env = &cpu->env;
- sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
uint16_t size;
uint8_t tmp;
@@ -918,7 +918,7 @@ static target_ulong register_vpa(PowerPCCPU *cpu, target_ulong vpa)
static target_ulong deregister_vpa(PowerPCCPU *cpu, target_ulong vpa)
{
- sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
if (spapr_cpu->slb_shadow_addr) {
return H_RESOURCE;
@@ -934,7 +934,7 @@ static target_ulong deregister_vpa(PowerPCCPU *cpu, target_ulong vpa)
static target_ulong register_slb_shadow(PowerPCCPU *cpu, target_ulong addr)
{
- sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
uint32_t size;
if (addr == 0) {
@@ -963,7 +963,7 @@ static target_ulong register_slb_shadow(PowerPCCPU *cpu, target_ulong addr)
static target_ulong deregister_slb_shadow(PowerPCCPU *cpu, target_ulong addr)
{
- sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
spapr_cpu->slb_shadow_addr = 0;
spapr_cpu->slb_shadow_size = 0;
@@ -972,7 +972,7 @@ static target_ulong deregister_slb_shadow(PowerPCCPU *cpu, target_ulong addr)
static target_ulong register_dtl(PowerPCCPU *cpu, target_ulong addr)
{
- sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
uint32_t size;
if (addr == 0) {
@@ -998,7 +998,7 @@ static target_ulong register_dtl(PowerPCCPU *cpu, target_ulong addr)
static target_ulong deregister_dtl(PowerPCCPU *cpu, target_ulong addr)
{
- sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
spapr_cpu->dtl_addr = 0;
spapr_cpu->dtl_size = 0;
@@ -1006,7 +1006,7 @@ static target_ulong deregister_dtl(PowerPCCPU *cpu, target_ulong addr)
return H_SUCCESS;
}
-static target_ulong h_register_vpa(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_register_vpa(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong flags = args[0];
@@ -1049,7 +1049,7 @@ static target_ulong h_register_vpa(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return ret;
}
-static target_ulong h_cede(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
CPUPPCState *env = &cpu->env;
@@ -1065,7 +1065,7 @@ static target_ulong h_cede(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-static target_ulong h_rtas(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_rtas(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong rtas_r3 = args[0];
@@ -1077,7 +1077,7 @@ static target_ulong h_rtas(PowerPCCPU *cpu, sPAPRMachineState *spapr,
nret, rtas_r3 + 12 + 4*nargs);
}
-static target_ulong h_logical_load(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_logical_load(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
CPUState *cs = CPU(cpu);
@@ -1101,7 +1101,7 @@ static target_ulong h_logical_load(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_PARAMETER;
}
-static target_ulong h_logical_store(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_logical_store(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
CPUState *cs = CPU(cpu);
@@ -1127,7 +1127,7 @@ static target_ulong h_logical_store(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_PARAMETER;
}
-static target_ulong h_logical_memop(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_logical_memop(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
CPUState *cs = CPU(cpu);
@@ -1196,14 +1196,14 @@ static target_ulong h_logical_memop(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-static target_ulong h_logical_icbi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_logical_icbi(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
/* Nothing to do on emulation, KVM will trap this in the kernel */
return H_SUCCESS;
}
-static target_ulong h_logical_dcbf(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_logical_dcbf(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
/* Nothing to do on emulation, KVM will trap this in the kernel */
@@ -1263,7 +1263,7 @@ static target_ulong h_set_mode_resource_addr_trans_mode(PowerPCCPU *cpu,
return H_SUCCESS;
}
-static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_set_mode(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong resource = args[1];
@@ -1282,7 +1282,7 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return ret;
}
-static target_ulong h_clean_slb(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_clean_slb(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
qemu_log_mask(LOG_UNIMP, "Unimplemented SPAPR hcall 0x"TARGET_FMT_lx"%s\n",
@@ -1290,7 +1290,7 @@ static target_ulong h_clean_slb(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_FUNCTION;
}
-static target_ulong h_invalidate_pid(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_invalidate_pid(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
qemu_log_mask(LOG_UNIMP, "Unimplemented SPAPR hcall 0x"TARGET_FMT_lx"%s\n",
@@ -1298,7 +1298,7 @@ static target_ulong h_invalidate_pid(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_FUNCTION;
}
-static void spapr_check_setup_free_hpt(sPAPRMachineState *spapr,
+static void spapr_check_setup_free_hpt(SpaprMachineState *spapr,
uint64_t patbe_old, uint64_t patbe_new)
{
/*
@@ -1331,7 +1331,7 @@ static void spapr_check_setup_free_hpt(sPAPRMachineState *spapr,
#define FLAG_GTSE 0x01
static target_ulong h_register_process_table(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
@@ -1339,6 +1339,7 @@ static target_ulong h_register_process_table(PowerPCCPU *cpu,
target_ulong proc_tbl = args[1];
target_ulong page_size = args[2];
target_ulong table_size = args[3];
+ target_ulong update_lpcr = 0;
uint64_t cproc;
if (flags & ~FLAGS_MASK) { /* Check no reserved bits are set */
@@ -1394,10 +1395,13 @@ static target_ulong h_register_process_table(PowerPCCPU *cpu,
spapr->patb_entry = cproc; /* Save new process table */
/* Update the UPRT, HR and GTSE bits in the LPCR for all cpus */
- spapr_set_all_lpcrs(((flags & (FLAG_RADIX | FLAG_HASH_PROC_TBL)) ?
- (LPCR_UPRT | LPCR_HR) : 0) |
- ((flags & FLAG_GTSE) ? LPCR_GTSE : 0),
- LPCR_UPRT | LPCR_HR | LPCR_GTSE);
+ if (flags & FLAG_RADIX) /* Radix must use process tables, also set HR */
+ update_lpcr |= (LPCR_UPRT | LPCR_HR);
+ else if (flags & FLAG_HASH_PROC_TBL) /* Hash with process tables */
+ update_lpcr |= LPCR_UPRT;
+ if (flags & FLAG_GTSE) /* Guest translation shootdown enable */
+ update_lpcr |= FLAG_GTSE;
+ spapr_set_all_lpcrs(update_lpcr, LPCR_UPRT | LPCR_HR | LPCR_GTSE);
if (kvm_enabled()) {
return kvmppc_configure_v3_mmu(cpu, flags & FLAG_RADIX,
@@ -1410,7 +1414,7 @@ static target_ulong h_register_process_table(PowerPCCPU *cpu,
#define H_SIGNAL_SYS_RESET_ALLBUTSELF -2
static target_ulong h_signal_sys_reset(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_long target = args[0];
@@ -1445,7 +1449,7 @@ static target_ulong h_signal_sys_reset(PowerPCCPU *cpu,
}
}
-static uint32_t cas_check_pvr(sPAPRMachineState *spapr, PowerPCCPU *cpu,
+static uint32_t cas_check_pvr(SpaprMachineState *spapr, PowerPCCPU *cpu,
target_ulong *addr, bool *raw_mode_supported,
Error **errp)
{
@@ -1496,7 +1500,7 @@ static uint32_t cas_check_pvr(sPAPRMachineState *spapr, PowerPCCPU *cpu,
}
static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
@@ -1504,7 +1508,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
target_ulong addr = ppc64_phys_to_real(args[0]);
target_ulong ov_table;
uint32_t cas_pvr;
- sPAPROptionVector *ov1_guest, *ov5_guest, *ov5_cas_old, *ov5_updates;
+ SpaprOptionVector *ov1_guest, *ov5_guest, *ov5_cas_old, *ov5_updates;
bool guest_radix;
Error *local_err = NULL;
bool raw_mode_supported = false;
@@ -1647,7 +1651,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
}
static target_ulong h_home_node_associativity(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
@@ -1683,7 +1687,7 @@ static target_ulong h_home_node_associativity(PowerPCCPU *cpu,
}
static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
@@ -1693,6 +1697,8 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
uint8_t safe_cache = spapr_get_cap(spapr, SPAPR_CAP_CFPC);
uint8_t safe_bounds_check = spapr_get_cap(spapr, SPAPR_CAP_SBBC);
uint8_t safe_indirect_branch = spapr_get_cap(spapr, SPAPR_CAP_IBS);
+ uint8_t count_cache_flush_assist = spapr_get_cap(spapr,
+ SPAPR_CAP_CCF_ASSIST);
switch (safe_cache) {
case SPAPR_CAP_WORKAROUND:
@@ -1723,12 +1729,20 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
}
switch (safe_indirect_branch) {
+ case SPAPR_CAP_FIXED_NA:
+ break;
case SPAPR_CAP_FIXED_CCD:
characteristics |= H_CPU_CHAR_CACHE_COUNT_DIS;
break;
case SPAPR_CAP_FIXED_IBS:
characteristics |= H_CPU_CHAR_BCCTRL_SERIALISED;
break;
+ case SPAPR_CAP_WORKAROUND:
+ behaviour |= H_CPU_BEHAV_FLUSH_COUNT_CACHE;
+ if (count_cache_flush_assist) {
+ characteristics |= H_CPU_CHAR_BCCTR_FLUSH_ASSIST;
+ }
+ break;
default: /* broken */
assert(safe_indirect_branch == SPAPR_CAP_BROKEN);
break;
@@ -1739,13 +1753,13 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
return H_SUCCESS;
}
-static target_ulong h_update_dt(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_update_dt(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong dt = ppc64_phys_to_real(args[0]);
struct fdt_header hdr = { 0 };
unsigned cb;
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
void *fdt;
cpu_physical_memory_read(dt, &hdr, sizeof(hdr));
@@ -1804,7 +1818,7 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode,
target_ulong *args)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+ SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
if ((opcode <= MAX_HCALL_OPCODE)
&& ((opcode & 0x3) == 0)) {
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index 37e98f9321..5aff4d5a05 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -32,7 +32,7 @@
#include <libfdt.h>
-enum sPAPRTCEAccess {
+enum SpaprTceAccess {
SPAPR_TCE_FAULT = 0,
SPAPR_TCE_RO = 1,
SPAPR_TCE_WO = 2,
@@ -42,11 +42,11 @@ enum sPAPRTCEAccess {
#define IOMMU_PAGE_SIZE(shift) (1ULL << (shift))
#define IOMMU_PAGE_MASK(shift) (~(IOMMU_PAGE_SIZE(shift) - 1))
-static QLIST_HEAD(, sPAPRTCETable) spapr_tce_tables;
+static QLIST_HEAD(, SpaprTceTable) spapr_tce_tables;
-sPAPRTCETable *spapr_tce_find_by_liobn(target_ulong liobn)
+SpaprTceTable *spapr_tce_find_by_liobn(target_ulong liobn)
{
- sPAPRTCETable *tcet;
+ SpaprTceTable *tcet;
if (liobn & 0xFFFFFFFF00000000ULL) {
hcall_dprintf("Request for out-of-bounds LIOBN 0x" TARGET_FMT_lx "\n",
@@ -115,7 +115,7 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(IOMMUMemoryRegion *iommu,
IOMMUAccessFlags flag,
int iommu_idx)
{
- sPAPRTCETable *tcet = container_of(iommu, sPAPRTCETable, iommu);
+ SpaprTceTable *tcet = container_of(iommu, SpaprTceTable, iommu);
uint64_t tce;
IOMMUTLBEntry ret = {
.target_as = &address_space_memory,
@@ -141,9 +141,39 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(IOMMUMemoryRegion *iommu,
return ret;
}
+static void spapr_tce_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n)
+{
+ MemoryRegion *mr = MEMORY_REGION(iommu_mr);
+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr);
+ hwaddr addr, granularity;
+ IOMMUTLBEntry iotlb;
+ SpaprTceTable *tcet = container_of(iommu_mr, SpaprTceTable, iommu);
+
+ if (tcet->skipping_replay) {
+ return;
+ }
+
+ granularity = memory_region_iommu_get_min_page_size(iommu_mr);
+
+ for (addr = 0; addr < memory_region_size(mr); addr += granularity) {
+ iotlb = imrc->translate(iommu_mr, addr, IOMMU_NONE, n->iommu_idx);
+ if (iotlb.perm != IOMMU_NONE) {
+ n->notify(n, &iotlb);
+ }
+
+ /*
+ * if (2^64 - MR size) < granularity, it's possible to get an
+ * infinite loop here. This should catch such a wraparound.
+ */
+ if ((addr + granularity) < addr) {
+ break;
+ }
+ }
+}
+
static int spapr_tce_table_pre_save(void *opaque)
{
- sPAPRTCETable *tcet = SPAPR_TCE_TABLE(opaque);
+ SpaprTceTable *tcet = SPAPR_TCE_TABLE(opaque);
tcet->mig_table = tcet->table;
tcet->mig_nb_table = tcet->nb_table;
@@ -156,7 +186,7 @@ static int spapr_tce_table_pre_save(void *opaque)
static uint64_t spapr_tce_get_min_page_size(IOMMUMemoryRegion *iommu)
{
- sPAPRTCETable *tcet = container_of(iommu, sPAPRTCETable, iommu);
+ SpaprTceTable *tcet = container_of(iommu, SpaprTceTable, iommu);
return 1ULL << tcet->page_shift;
}
@@ -164,7 +194,7 @@ static uint64_t spapr_tce_get_min_page_size(IOMMUMemoryRegion *iommu)
static int spapr_tce_get_attr(IOMMUMemoryRegion *iommu,
enum IOMMUMemoryRegionAttr attr, void *data)
{
- sPAPRTCETable *tcet = container_of(iommu, sPAPRTCETable, iommu);
+ SpaprTceTable *tcet = container_of(iommu, SpaprTceTable, iommu);
if (attr == IOMMU_ATTR_SPAPR_TCE_FD && kvmppc_has_cap_spapr_vfio()) {
*(int *) data = tcet->fd;
@@ -178,7 +208,7 @@ static void spapr_tce_notify_flag_changed(IOMMUMemoryRegion *iommu,
IOMMUNotifierFlag old,
IOMMUNotifierFlag new)
{
- struct sPAPRTCETable *tbl = container_of(iommu, sPAPRTCETable, iommu);
+ struct SpaprTceTable *tbl = container_of(iommu, SpaprTceTable, iommu);
if (old == IOMMU_NOTIFIER_NONE && new != IOMMU_NOTIFIER_NONE) {
spapr_tce_set_need_vfio(tbl, true);
@@ -189,7 +219,7 @@ static void spapr_tce_notify_flag_changed(IOMMUMemoryRegion *iommu,
static int spapr_tce_table_post_load(void *opaque, int version_id)
{
- sPAPRTCETable *tcet = SPAPR_TCE_TABLE(opaque);
+ SpaprTceTable *tcet = SPAPR_TCE_TABLE(opaque);
uint32_t old_nb_table = tcet->nb_table;
uint64_t old_bus_offset = tcet->bus_offset;
uint32_t old_page_shift = tcet->page_shift;
@@ -223,7 +253,7 @@ static int spapr_tce_table_post_load(void *opaque, int version_id)
static bool spapr_tce_table_ex_needed(void *opaque)
{
- sPAPRTCETable *tcet = opaque;
+ SpaprTceTable *tcet = opaque;
return tcet->bus_offset || tcet->page_shift != 0xC;
}
@@ -234,8 +264,8 @@ static const VMStateDescription vmstate_spapr_tce_table_ex = {
.minimum_version_id = 1,
.needed = spapr_tce_table_ex_needed,
.fields = (VMStateField[]) {
- VMSTATE_UINT64(bus_offset, sPAPRTCETable),
- VMSTATE_UINT32(page_shift, sPAPRTCETable),
+ VMSTATE_UINT64(bus_offset, SpaprTceTable),
+ VMSTATE_UINT32(page_shift, SpaprTceTable),
VMSTATE_END_OF_LIST()
},
};
@@ -248,12 +278,12 @@ static const VMStateDescription vmstate_spapr_tce_table = {
.post_load = spapr_tce_table_post_load,
.fields = (VMStateField []) {
/* Sanity check */
- VMSTATE_UINT32_EQUAL(liobn, sPAPRTCETable, NULL),
+ VMSTATE_UINT32_EQUAL(liobn, SpaprTceTable, NULL),
/* IOMMU state */
- VMSTATE_UINT32(mig_nb_table, sPAPRTCETable),
- VMSTATE_BOOL(bypass, sPAPRTCETable),
- VMSTATE_VARRAY_UINT32_ALLOC(mig_table, sPAPRTCETable, mig_nb_table, 0,
+ VMSTATE_UINT32(mig_nb_table, SpaprTceTable),
+ VMSTATE_BOOL(bypass, SpaprTceTable),
+ VMSTATE_VARRAY_UINT32_ALLOC(mig_table, SpaprTceTable, mig_nb_table, 0,
vmstate_info_uint64, uint64_t),
VMSTATE_END_OF_LIST()
@@ -266,7 +296,7 @@ static const VMStateDescription vmstate_spapr_tce_table = {
static void spapr_tce_table_realize(DeviceState *dev, Error **errp)
{
- sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
+ SpaprTceTable *tcet = SPAPR_TCE_TABLE(dev);
Object *tcetobj = OBJECT(tcet);
gchar *tmp;
@@ -288,7 +318,7 @@ static void spapr_tce_table_realize(DeviceState *dev, Error **errp)
tcet);
}
-void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio)
+void spapr_tce_set_need_vfio(SpaprTceTable *tcet, bool need_vfio)
{
size_t table_size = tcet->nb_table * sizeof(uint64_t);
uint64_t *oldtable;
@@ -317,9 +347,9 @@ void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio)
tcet->fd = newfd;
}
-sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn)
+SpaprTceTable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn)
{
- sPAPRTCETable *tcet;
+ SpaprTceTable *tcet;
gchar *tmp;
if (spapr_tce_find_by_liobn(liobn)) {
@@ -341,7 +371,7 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn)
return tcet;
}
-void spapr_tce_table_enable(sPAPRTCETable *tcet,
+void spapr_tce_table_enable(SpaprTceTable *tcet,
uint32_t page_shift, uint64_t bus_offset,
uint32_t nb_table)
{
@@ -366,7 +396,7 @@ void spapr_tce_table_enable(sPAPRTCETable *tcet,
MEMORY_REGION(&tcet->iommu));
}
-void spapr_tce_table_disable(sPAPRTCETable *tcet)
+void spapr_tce_table_disable(SpaprTceTable *tcet)
{
if (!tcet->nb_table) {
return;
@@ -385,7 +415,7 @@ void spapr_tce_table_disable(sPAPRTCETable *tcet)
static void spapr_tce_table_unrealize(DeviceState *dev, Error **errp)
{
- sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
+ SpaprTceTable *tcet = SPAPR_TCE_TABLE(dev);
vmstate_unregister(DEVICE(tcet), &vmstate_spapr_tce_table, tcet);
@@ -394,14 +424,14 @@ static void spapr_tce_table_unrealize(DeviceState *dev, Error **errp)
spapr_tce_table_disable(tcet);
}
-MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet)
+MemoryRegion *spapr_tce_get_iommu(SpaprTceTable *tcet)
{
return &tcet->root;
}
static void spapr_tce_reset(DeviceState *dev)
{
- sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
+ SpaprTceTable *tcet = SPAPR_TCE_TABLE(dev);
size_t table_size = tcet->nb_table * sizeof(uint64_t);
if (tcet->nb_table) {
@@ -409,7 +439,7 @@ static void spapr_tce_reset(DeviceState *dev)
}
}
-static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
+static target_ulong put_tce_emu(SpaprTceTable *tcet, target_ulong ioba,
target_ulong tce)
{
IOMMUTLBEntry entry;
@@ -435,7 +465,7 @@ static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
}
static target_ulong h_put_tce_indirect(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
int i;
@@ -445,7 +475,7 @@ static target_ulong h_put_tce_indirect(PowerPCCPU *cpu,
target_ulong tce_list = args[2];
target_ulong npages = args[3];
target_ulong ret = H_PARAMETER, tce = 0;
- sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
+ SpaprTceTable *tcet = spapr_tce_find_by_liobn(liobn);
CPUState *cs = CPU(cpu);
hwaddr page_mask, page_size;
@@ -480,7 +510,7 @@ static target_ulong h_put_tce_indirect(PowerPCCPU *cpu,
return ret;
}
-static target_ulong h_stuff_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_stuff_tce(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
int i;
@@ -489,7 +519,7 @@ static target_ulong h_stuff_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
target_ulong tce_value = args[2];
target_ulong npages = args[3];
target_ulong ret = H_PARAMETER;
- sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
+ SpaprTceTable *tcet = spapr_tce_find_by_liobn(liobn);
hwaddr page_mask, page_size;
if (!tcet) {
@@ -519,14 +549,14 @@ static target_ulong h_stuff_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return ret;
}
-static target_ulong h_put_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_put_tce(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong liobn = args[0];
target_ulong ioba = args[1];
target_ulong tce = args[2];
target_ulong ret = H_PARAMETER;
- sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
+ SpaprTceTable *tcet = spapr_tce_find_by_liobn(liobn);
if (tcet) {
hwaddr page_mask = IOMMU_PAGE_MASK(tcet->page_shift);
@@ -544,7 +574,7 @@ static target_ulong h_put_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return ret;
}
-static target_ulong get_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
+static target_ulong get_tce_emu(SpaprTceTable *tcet, target_ulong ioba,
target_ulong *tce)
{
unsigned long index = (ioba - tcet->bus_offset) >> tcet->page_shift;
@@ -560,14 +590,14 @@ static target_ulong get_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
return H_SUCCESS;
}
-static target_ulong h_get_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_get_tce(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong liobn = args[0];
target_ulong ioba = args[1];
target_ulong tce = 0;
target_ulong ret = H_PARAMETER;
- sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
+ SpaprTceTable *tcet = spapr_tce_find_by_liobn(liobn);
if (tcet) {
hwaddr page_mask = IOMMU_PAGE_MASK(tcet->page_shift);
@@ -619,7 +649,7 @@ int spapr_dma_dt(void *fdt, int node_off, const char *propname,
}
int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname,
- sPAPRTCETable *tcet)
+ SpaprTceTable *tcet)
{
if (!tcet) {
return 0;
@@ -650,7 +680,7 @@ static void spapr_tce_table_class_init(ObjectClass *klass, void *data)
static TypeInfo spapr_tce_table_info = {
.name = TYPE_SPAPR_TCE_TABLE,
.parent = TYPE_DEVICE,
- .instance_size = sizeof(sPAPRTCETable),
+ .instance_size = sizeof(SpaprTceTable),
.class_init = spapr_tce_table_class_init,
};
@@ -659,6 +689,7 @@ static void spapr_iommu_memory_region_class_init(ObjectClass *klass, void *data)
IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
imrc->translate = spapr_tce_translate_iommu;
+ imrc->replay = spapr_tce_replay;
imrc->get_min_page_size = spapr_tce_get_min_page_size;
imrc->notify_flag_changed = spapr_tce_notify_flag_changed;
imrc->get_attr = spapr_tce_get_attr;
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 4145079d7f..253e4de7fd 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -20,13 +20,13 @@
#include "trace.h"
-void spapr_irq_msi_init(sPAPRMachineState *spapr, uint32_t nr_msis)
+void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis)
{
spapr->irq_map_nr = nr_msis;
spapr->irq_map = bitmap_new(spapr->irq_map_nr);
}
-int spapr_irq_msi_alloc(sPAPRMachineState *spapr, uint32_t num, bool align,
+int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
Error **errp)
{
int irq;
@@ -51,12 +51,12 @@ int spapr_irq_msi_alloc(sPAPRMachineState *spapr, uint32_t num, bool align,
return irq + SPAPR_IRQ_MSI;
}
-void spapr_irq_msi_free(sPAPRMachineState *spapr, int irq, uint32_t num)
+void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num)
{
bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num);
}
-void spapr_irq_msi_reset(sPAPRMachineState *spapr)
+void spapr_irq_msi_reset(SpaprMachineState *spapr)
{
bitmap_clear(spapr->irq_map, 0, spapr->irq_map_nr);
}
@@ -66,7 +66,7 @@ void spapr_irq_msi_reset(sPAPRMachineState *spapr)
* XICS IRQ backend.
*/
-static ICSState *spapr_ics_create(sPAPRMachineState *spapr,
+static ICSState *spapr_ics_create(SpaprMachineState *spapr,
int nr_irqs, Error **errp)
{
Error *local_err = NULL;
@@ -92,7 +92,7 @@ error:
return NULL;
}
-static void spapr_irq_init_xics(sPAPRMachineState *spapr, int nr_irqs,
+static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
Error **errp)
{
MachineState *machine = MACHINE(spapr);
@@ -126,7 +126,7 @@ error:
#define ICS_IRQ_FREE(ics, srcno) \
(!((ics)->irqs[(srcno)].flags & (XICS_FLAGS_IRQ_MASK)))
-static int spapr_irq_claim_xics(sPAPRMachineState *spapr, int irq, bool lsi,
+static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
Error **errp)
{
ICSState *ics = spapr->ics;
@@ -147,7 +147,7 @@ static int spapr_irq_claim_xics(sPAPRMachineState *spapr, int irq, bool lsi,
return 0;
}
-static void spapr_irq_free_xics(sPAPRMachineState *spapr, int irq, int num)
+static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq, int num)
{
ICSState *ics = spapr->ics;
uint32_t srcno = irq - ics->offset;
@@ -164,7 +164,7 @@ static void spapr_irq_free_xics(sPAPRMachineState *spapr, int irq, int num)
}
}
-static qemu_irq spapr_qirq_xics(sPAPRMachineState *spapr, int irq)
+static qemu_irq spapr_qirq_xics(SpaprMachineState *spapr, int irq)
{
ICSState *ics = spapr->ics;
uint32_t srcno = irq - ics->offset;
@@ -176,7 +176,7 @@ static qemu_irq spapr_qirq_xics(sPAPRMachineState *spapr, int irq)
return NULL;
}
-static void spapr_irq_print_info_xics(sPAPRMachineState *spapr, Monitor *mon)
+static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
{
CPUState *cs;
@@ -189,12 +189,12 @@ static void spapr_irq_print_info_xics(sPAPRMachineState *spapr, Monitor *mon)
ics_pic_print_info(spapr->ics, mon);
}
-static void spapr_irq_cpu_intc_create_xics(sPAPRMachineState *spapr,
+static void spapr_irq_cpu_intc_create_xics(SpaprMachineState *spapr,
PowerPCCPU *cpu, Error **errp)
{
Error *local_err = NULL;
Object *obj;
- sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
obj = icp_create(OBJECT(cpu), TYPE_ICP, XICS_FABRIC(spapr),
&local_err);
@@ -206,7 +206,7 @@ static void spapr_irq_cpu_intc_create_xics(sPAPRMachineState *spapr,
spapr_cpu->icp = ICP(obj);
}
-static int spapr_irq_post_load_xics(sPAPRMachineState *spapr, int version_id)
+static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
{
if (!kvm_irqchip_in_kernel()) {
CPUState *cs;
@@ -220,17 +220,17 @@ static int spapr_irq_post_load_xics(sPAPRMachineState *spapr, int version_id)
static void spapr_irq_set_irq_xics(void *opaque, int srcno, int val)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
ics_simple_set_irq(spapr->ics, srcno, val);
}
-static void spapr_irq_reset_xics(sPAPRMachineState *spapr, Error **errp)
+static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
{
/* TODO: create the KVM XICS device */
}
-static const char *spapr_irq_get_nodename_xics(sPAPRMachineState *spapr)
+static const char *spapr_irq_get_nodename_xics(SpaprMachineState *spapr)
{
return XICS_NODENAME;
}
@@ -239,7 +239,7 @@ static const char *spapr_irq_get_nodename_xics(sPAPRMachineState *spapr)
#define SPAPR_IRQ_XICS_NR_MSIS \
(XICS_IRQ_BASE + SPAPR_IRQ_XICS_NR_IRQS - SPAPR_IRQ_MSI)
-sPAPRIrq spapr_irq_xics = {
+SpaprIrq spapr_irq_xics = {
.nr_irqs = SPAPR_IRQ_XICS_NR_IRQS,
.nr_msis = SPAPR_IRQ_XICS_NR_MSIS,
.ov5 = SPAPR_OV5_XIVE_LEGACY,
@@ -260,7 +260,7 @@ sPAPRIrq spapr_irq_xics = {
/*
* XIVE IRQ backend.
*/
-static void spapr_irq_init_xive(sPAPRMachineState *spapr, int nr_irqs,
+static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_irqs,
Error **errp)
{
MachineState *machine = MACHINE(spapr);
@@ -294,7 +294,7 @@ static void spapr_irq_init_xive(sPAPRMachineState *spapr, int nr_irqs,
spapr_xive_hcall_init(spapr);
}
-static int spapr_irq_claim_xive(sPAPRMachineState *spapr, int irq, bool lsi,
+static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
Error **errp)
{
if (!spapr_xive_irq_claim(spapr->xive, irq, lsi)) {
@@ -304,7 +304,7 @@ static int spapr_irq_claim_xive(sPAPRMachineState *spapr, int irq, bool lsi,
return 0;
}
-static void spapr_irq_free_xive(sPAPRMachineState *spapr, int irq, int num)
+static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq, int num)
{
int i;
@@ -313,9 +313,9 @@ static void spapr_irq_free_xive(sPAPRMachineState *spapr, int irq, int num)
}
}
-static qemu_irq spapr_qirq_xive(sPAPRMachineState *spapr, int irq)
+static qemu_irq spapr_qirq_xive(SpaprMachineState *spapr, int irq)
{
- sPAPRXive *xive = spapr->xive;
+ SpaprXive *xive = spapr->xive;
if (irq >= xive->nr_irqs) {
return NULL;
@@ -327,7 +327,7 @@ static qemu_irq spapr_qirq_xive(sPAPRMachineState *spapr, int irq)
return spapr->qirqs[irq];
}
-static void spapr_irq_print_info_xive(sPAPRMachineState *spapr,
+static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
Monitor *mon)
{
CPUState *cs;
@@ -341,12 +341,12 @@ static void spapr_irq_print_info_xive(sPAPRMachineState *spapr,
spapr_xive_pic_print_info(spapr->xive, mon);
}
-static void spapr_irq_cpu_intc_create_xive(sPAPRMachineState *spapr,
+static void spapr_irq_cpu_intc_create_xive(SpaprMachineState *spapr,
PowerPCCPU *cpu, Error **errp)
{
Error *local_err = NULL;
Object *obj;
- sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(spapr->xive), &local_err);
if (local_err) {
@@ -363,12 +363,12 @@ static void spapr_irq_cpu_intc_create_xive(sPAPRMachineState *spapr,
spapr_xive_set_tctx_os_cam(spapr_cpu->tctx);
}
-static int spapr_irq_post_load_xive(sPAPRMachineState *spapr, int version_id)
+static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id)
{
return 0;
}
-static void spapr_irq_reset_xive(sPAPRMachineState *spapr, Error **errp)
+static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
{
CPUState *cs;
@@ -385,12 +385,12 @@ static void spapr_irq_reset_xive(sPAPRMachineState *spapr, Error **errp)
static void spapr_irq_set_irq_xive(void *opaque, int srcno, int val)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
xive_source_set_irq(&spapr->xive->source, srcno, val);
}
-static const char *spapr_irq_get_nodename_xive(sPAPRMachineState *spapr)
+static const char *spapr_irq_get_nodename_xive(SpaprMachineState *spapr)
{
return spapr->xive->nodename;
}
@@ -403,7 +403,7 @@ static const char *spapr_irq_get_nodename_xive(sPAPRMachineState *spapr)
#define SPAPR_IRQ_XIVE_NR_IRQS 0x2000
#define SPAPR_IRQ_XIVE_NR_MSIS (SPAPR_IRQ_XIVE_NR_IRQS - SPAPR_IRQ_MSI)
-sPAPRIrq spapr_irq_xive = {
+SpaprIrq spapr_irq_xive = {
.nr_irqs = SPAPR_IRQ_XIVE_NR_IRQS,
.nr_msis = SPAPR_IRQ_XIVE_NR_MSIS,
.ov5 = SPAPR_OV5_XIVE_EXPLOIT,
@@ -434,13 +434,13 @@ sPAPRIrq spapr_irq_xive = {
* Returns the sPAPR IRQ backend negotiated by CAS. XICS is the
* default.
*/
-static sPAPRIrq *spapr_irq_current(sPAPRMachineState *spapr)
+static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
{
return spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT) ?
&spapr_irq_xive : &spapr_irq_xics;
}
-static void spapr_irq_init_dual(sPAPRMachineState *spapr, int nr_irqs,
+static void spapr_irq_init_dual(SpaprMachineState *spapr, int nr_irqs,
Error **errp)
{
MachineState *machine = MACHINE(spapr);
@@ -464,7 +464,7 @@ static void spapr_irq_init_dual(sPAPRMachineState *spapr, int nr_irqs,
}
}
-static int spapr_irq_claim_dual(sPAPRMachineState *spapr, int irq, bool lsi,
+static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
Error **errp)
{
Error *local_err = NULL;
@@ -485,30 +485,30 @@ static int spapr_irq_claim_dual(sPAPRMachineState *spapr, int irq, bool lsi,
return ret;
}
-static void spapr_irq_free_dual(sPAPRMachineState *spapr, int irq, int num)
+static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq, int num)
{
spapr_irq_xics.free(spapr, irq, num);
spapr_irq_xive.free(spapr, irq, num);
}
-static qemu_irq spapr_qirq_dual(sPAPRMachineState *spapr, int irq)
+static qemu_irq spapr_qirq_dual(SpaprMachineState *spapr, int irq)
{
return spapr_irq_current(spapr)->qirq(spapr, irq);
}
-static void spapr_irq_print_info_dual(sPAPRMachineState *spapr, Monitor *mon)
+static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon)
{
spapr_irq_current(spapr)->print_info(spapr, mon);
}
-static void spapr_irq_dt_populate_dual(sPAPRMachineState *spapr,
+static void spapr_irq_dt_populate_dual(SpaprMachineState *spapr,
uint32_t nr_servers, void *fdt,
uint32_t phandle)
{
spapr_irq_current(spapr)->dt_populate(spapr, nr_servers, fdt, phandle);
}
-static void spapr_irq_cpu_intc_create_dual(sPAPRMachineState *spapr,
+static void spapr_irq_cpu_intc_create_dual(SpaprMachineState *spapr,
PowerPCCPU *cpu, Error **errp)
{
Error *local_err = NULL;
@@ -522,7 +522,7 @@ static void spapr_irq_cpu_intc_create_dual(sPAPRMachineState *spapr,
spapr_irq_xics.cpu_intc_create(spapr, cpu, errp);
}
-static int spapr_irq_post_load_dual(sPAPRMachineState *spapr, int version_id)
+static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
{
/*
* Force a reset of the XIVE backend after migration. The machine
@@ -535,7 +535,7 @@ static int spapr_irq_post_load_dual(sPAPRMachineState *spapr, int version_id)
return spapr_irq_current(spapr)->post_load(spapr, version_id);
}
-static void spapr_irq_reset_dual(sPAPRMachineState *spapr, Error **errp)
+static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp)
{
/*
* Deactivate the XIVE MMIOs. The XIVE backend will reenable them
@@ -548,12 +548,12 @@ static void spapr_irq_reset_dual(sPAPRMachineState *spapr, Error **errp)
static void spapr_irq_set_irq_dual(void *opaque, int srcno, int val)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
spapr_irq_current(spapr)->set_irq(spapr, srcno, val);
}
-static const char *spapr_irq_get_nodename_dual(sPAPRMachineState *spapr)
+static const char *spapr_irq_get_nodename_dual(SpaprMachineState *spapr)
{
return spapr_irq_current(spapr)->get_nodename(spapr);
}
@@ -564,7 +564,7 @@ static const char *spapr_irq_get_nodename_dual(sPAPRMachineState *spapr)
#define SPAPR_IRQ_DUAL_NR_IRQS 0x2000
#define SPAPR_IRQ_DUAL_NR_MSIS (SPAPR_IRQ_DUAL_NR_IRQS - SPAPR_IRQ_MSI)
-sPAPRIrq spapr_irq_dual = {
+SpaprIrq spapr_irq_dual = {
.nr_irqs = SPAPR_IRQ_DUAL_NR_IRQS,
.nr_msis = SPAPR_IRQ_DUAL_NR_MSIS,
.ov5 = SPAPR_OV5_XIVE_BOTH,
@@ -585,7 +585,7 @@ sPAPRIrq spapr_irq_dual = {
/*
* sPAPR IRQ frontend routines for devices
*/
-void spapr_irq_init(sPAPRMachineState *spapr, Error **errp)
+void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
{
MachineState *machine = MACHINE(spapr);
@@ -611,34 +611,34 @@ void spapr_irq_init(sPAPRMachineState *spapr, Error **errp)
spapr->irq->nr_irqs);
}
-int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp)
+int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
{
return spapr->irq->claim(spapr, irq, lsi, errp);
}
-void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num)
+void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
{
spapr->irq->free(spapr, irq, num);
}
-qemu_irq spapr_qirq(sPAPRMachineState *spapr, int irq)
+qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
{
return spapr->irq->qirq(spapr, irq);
}
-int spapr_irq_post_load(sPAPRMachineState *spapr, int version_id)
+int spapr_irq_post_load(SpaprMachineState *spapr, int version_id)
{
return spapr->irq->post_load(spapr, version_id);
}
-void spapr_irq_reset(sPAPRMachineState *spapr, Error **errp)
+void spapr_irq_reset(SpaprMachineState *spapr, Error **errp)
{
if (spapr->irq->reset) {
spapr->irq->reset(spapr, errp);
}
}
-int spapr_irq_get_phandle(sPAPRMachineState *spapr, void *fdt, Error **errp)
+int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp)
{
const char *nodename = spapr->irq->get_nodename(spapr);
int offset, phandle;
@@ -684,7 +684,7 @@ static int ics_find_free_block(ICSState *ics, int num, int alignnum)
return -1;
}
-int spapr_irq_find(sPAPRMachineState *spapr, int num, bool align, Error **errp)
+int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp)
{
ICSState *ics = spapr->ics;
int first = -1;
@@ -716,7 +716,7 @@ int spapr_irq_find(sPAPRMachineState *spapr, int num, bool align, Error **errp)
#define SPAPR_IRQ_XICS_LEGACY_NR_IRQS 0x400
-sPAPRIrq spapr_irq_xics_legacy = {
+SpaprIrq spapr_irq_xics_legacy = {
.nr_irqs = SPAPR_IRQ_XICS_LEGACY_NR_IRQS,
.nr_msis = SPAPR_IRQ_XICS_LEGACY_NR_IRQS,
.ov5 = SPAPR_OV5_XIVE_LEGACY,
diff --git a/hw/ppc/spapr_ovec.c b/hw/ppc/spapr_ovec.c
index 12510b236a..a65b7c7da9 100644
--- a/hw/ppc/spapr_ovec.c
+++ b/hw/ppc/spapr_ovec.c
@@ -16,7 +16,6 @@
#include "qemu/bitmap.h"
#include "exec/address-spaces.h"
#include "qemu/error-report.h"
-#include "sysemu/qtest.h"
#include "trace.h"
#include <libfdt.h>
@@ -27,7 +26,7 @@
* allows us to more safely make assumptions about the bitmap size and
* simplify the calling code somewhat
*/
-struct sPAPROptionVector {
+struct SpaprOptionVector {
unsigned long *bitmap;
int32_t bitmap_size; /* only used for migration */
};
@@ -37,25 +36,25 @@ const VMStateDescription vmstate_spapr_ovec = {
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
- VMSTATE_BITMAP(bitmap, sPAPROptionVector, 1, bitmap_size),
+ VMSTATE_BITMAP(bitmap, SpaprOptionVector, 1, bitmap_size),
VMSTATE_END_OF_LIST()
}
};
-sPAPROptionVector *spapr_ovec_new(void)
+SpaprOptionVector *spapr_ovec_new(void)
{
- sPAPROptionVector *ov;
+ SpaprOptionVector *ov;
- ov = g_new0(sPAPROptionVector, 1);
+ ov = g_new0(SpaprOptionVector, 1);
ov->bitmap = bitmap_new(OV_MAXBITS);
ov->bitmap_size = OV_MAXBITS;
return ov;
}
-sPAPROptionVector *spapr_ovec_clone(sPAPROptionVector *ov_orig)
+SpaprOptionVector *spapr_ovec_clone(SpaprOptionVector *ov_orig)
{
- sPAPROptionVector *ov;
+ SpaprOptionVector *ov;
g_assert(ov_orig);
@@ -65,9 +64,9 @@ sPAPROptionVector *spapr_ovec_clone(sPAPROptionVector *ov_orig)
return ov;
}
-void spapr_ovec_intersect(sPAPROptionVector *ov,
- sPAPROptionVector *ov1,
- sPAPROptionVector *ov2)
+void spapr_ovec_intersect(SpaprOptionVector *ov,
+ SpaprOptionVector *ov1,
+ SpaprOptionVector *ov2)
{
g_assert(ov);
g_assert(ov1);
@@ -77,9 +76,9 @@ void spapr_ovec_intersect(sPAPROptionVector *ov,
}
/* returns true if options bits were removed, false otherwise */
-bool spapr_ovec_diff(sPAPROptionVector *ov,
- sPAPROptionVector *ov_old,
- sPAPROptionVector *ov_new)
+bool spapr_ovec_diff(SpaprOptionVector *ov,
+ SpaprOptionVector *ov_old,
+ SpaprOptionVector *ov_new)
{
unsigned long *change_mask = bitmap_new(OV_MAXBITS);
unsigned long *removed_bits = bitmap_new(OV_MAXBITS);
@@ -103,7 +102,7 @@ bool spapr_ovec_diff(sPAPROptionVector *ov,
return bits_were_removed;
}
-void spapr_ovec_cleanup(sPAPROptionVector *ov)
+void spapr_ovec_cleanup(SpaprOptionVector *ov)
{
if (ov) {
g_free(ov->bitmap);
@@ -111,7 +110,7 @@ void spapr_ovec_cleanup(sPAPROptionVector *ov)
}
}
-void spapr_ovec_set(sPAPROptionVector *ov, long bitnr)
+void spapr_ovec_set(SpaprOptionVector *ov, long bitnr)
{
g_assert(ov);
g_assert(bitnr < OV_MAXBITS);
@@ -119,7 +118,7 @@ void spapr_ovec_set(sPAPROptionVector *ov, long bitnr)
set_bit(bitnr, ov->bitmap);
}
-void spapr_ovec_clear(sPAPROptionVector *ov, long bitnr)
+void spapr_ovec_clear(SpaprOptionVector *ov, long bitnr)
{
g_assert(ov);
g_assert(bitnr < OV_MAXBITS);
@@ -127,16 +126,11 @@ void spapr_ovec_clear(sPAPROptionVector *ov, long bitnr)
clear_bit(bitnr, ov->bitmap);
}
-bool spapr_ovec_test(sPAPROptionVector *ov, long bitnr)
+bool spapr_ovec_test(SpaprOptionVector *ov, long bitnr)
{
g_assert(ov);
g_assert(bitnr < OV_MAXBITS);
- /* support memory unplug for qtest */
- if (qtest_enabled() && bitnr == OV5_HP_EVT) {
- return true;
- }
-
return test_bit(bitnr, ov->bitmap) ? true : false;
}
@@ -184,9 +178,9 @@ static target_ulong vector_addr(target_ulong table_addr, int vector)
return table_addr;
}
-sPAPROptionVector *spapr_ovec_parse_vector(target_ulong table_addr, int vector)
+SpaprOptionVector *spapr_ovec_parse_vector(target_ulong table_addr, int vector)
{
- sPAPROptionVector *ov;
+ SpaprOptionVector *ov;
target_ulong addr;
uint16_t vector_len;
int i;
@@ -216,7 +210,7 @@ sPAPROptionVector *spapr_ovec_parse_vector(target_ulong table_addr, int vector)
}
int spapr_ovec_populate_dt(void *fdt, int fdt_offset,
- sPAPROptionVector *ov, const char *name)
+ SpaprOptionVector *ov, const char *name)
{
uint8_t vec[OV_MAXBYTES + 1];
uint16_t vec_len;
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 69059c36eb..20915d2b3c 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -61,9 +61,9 @@
#define RTAS_TYPE_MSI 1
#define RTAS_TYPE_MSIX 2
-sPAPRPHBState *spapr_pci_find_phb(sPAPRMachineState *spapr, uint64_t buid)
+SpaprPhbState *spapr_pci_find_phb(SpaprMachineState *spapr, uint64_t buid)
{
- sPAPRPHBState *sphb;
+ SpaprPhbState *sphb;
QLIST_FOREACH(sphb, &spapr->phbs, list) {
if (sphb->buid != buid) {
@@ -75,10 +75,10 @@ sPAPRPHBState *spapr_pci_find_phb(sPAPRMachineState *spapr, uint64_t buid)
return NULL;
}
-PCIDevice *spapr_pci_find_dev(sPAPRMachineState *spapr, uint64_t buid,
+PCIDevice *spapr_pci_find_dev(SpaprMachineState *spapr, uint64_t buid,
uint32_t config_addr)
{
- sPAPRPHBState *sphb = spapr_pci_find_phb(spapr, buid);
+ SpaprPhbState *sphb = spapr_pci_find_phb(spapr, buid);
PCIHostState *phb = PCI_HOST_BRIDGE(sphb);
int bus_num = (config_addr >> 16) & 0xFF;
int devfn = (config_addr >> 8) & 0xFF;
@@ -96,7 +96,7 @@ static uint32_t rtas_pci_cfgaddr(uint32_t arg)
return ((arg >> 20) & 0xf00) | (arg & 0xff);
}
-static void finish_read_pci_config(sPAPRMachineState *spapr, uint64_t buid,
+static void finish_read_pci_config(SpaprMachineState *spapr, uint64_t buid,
uint32_t addr, uint32_t size,
target_ulong rets)
{
@@ -126,7 +126,7 @@ static void finish_read_pci_config(sPAPRMachineState *spapr, uint64_t buid,
rtas_st(rets, 1, val);
}
-static void rtas_ibm_read_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_ibm_read_pci_config(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
@@ -146,7 +146,7 @@ static void rtas_ibm_read_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
finish_read_pci_config(spapr, buid, addr, size, rets);
}
-static void rtas_read_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_read_pci_config(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
@@ -164,7 +164,7 @@ static void rtas_read_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
finish_read_pci_config(spapr, 0, addr, size, rets);
}
-static void finish_write_pci_config(sPAPRMachineState *spapr, uint64_t buid,
+static void finish_write_pci_config(SpaprMachineState *spapr, uint64_t buid,
uint32_t addr, uint32_t size,
uint32_t val, target_ulong rets)
{
@@ -192,7 +192,7 @@ static void finish_write_pci_config(sPAPRMachineState *spapr, uint64_t buid,
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
-static void rtas_ibm_write_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_ibm_write_pci_config(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
@@ -213,7 +213,7 @@ static void rtas_ibm_write_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
finish_write_pci_config(spapr, buid, addr, size, val, rets);
}
-static void rtas_write_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_write_pci_config(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
@@ -262,12 +262,12 @@ static void spapr_msi_setmsg(PCIDevice *pdev, hwaddr addr, bool msix,
}
}
-static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_ibm_change_msi(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args, uint32_t nret,
target_ulong rets)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
uint32_t config_addr = rtas_ld(args, 0);
uint64_t buid = rtas_ldq(args, 1);
unsigned int func = rtas_ld(args, 3);
@@ -275,14 +275,14 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
unsigned int seq_num = rtas_ld(args, 5);
unsigned int ret_intr_type;
unsigned int irq, max_irqs = 0;
- sPAPRPHBState *phb = NULL;
+ SpaprPhbState *phb = NULL;
PCIDevice *pdev = NULL;
spapr_pci_msi *msi;
int *config_addr_key;
Error *err = NULL;
int i;
- /* Fins sPAPRPHBState */
+ /* Fins SpaprPhbState */
phb = spapr_pci_find_phb(spapr, buid);
if (phb) {
pdev = spapr_pci_find_dev(spapr, buid, config_addr);
@@ -439,7 +439,7 @@ out:
}
static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
uint32_t token,
uint32_t nargs,
target_ulong args,
@@ -449,11 +449,11 @@ static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
uint32_t config_addr = rtas_ld(args, 0);
uint64_t buid = rtas_ldq(args, 1);
unsigned int intr_src_num = -1, ioa_intr_num = rtas_ld(args, 3);
- sPAPRPHBState *phb = NULL;
+ SpaprPhbState *phb = NULL;
PCIDevice *pdev = NULL;
spapr_pci_msi *msi;
- /* Find sPAPRPHBState */
+ /* Find SpaprPhbState */
phb = spapr_pci_find_phb(spapr, buid);
if (phb) {
pdev = spapr_pci_find_dev(spapr, buid, config_addr);
@@ -480,12 +480,12 @@ static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
}
static void rtas_ibm_set_eeh_option(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args, uint32_t nret,
target_ulong rets)
{
- sPAPRPHBState *sphb;
+ SpaprPhbState *sphb;
uint32_t addr, option;
uint64_t buid;
int ret;
@@ -516,12 +516,12 @@ param_error_exit:
}
static void rtas_ibm_get_config_addr_info2(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args, uint32_t nret,
target_ulong rets)
{
- sPAPRPHBState *sphb;
+ SpaprPhbState *sphb;
PCIDevice *pdev;
uint32_t addr, option;
uint64_t buid;
@@ -570,12 +570,12 @@ param_error_exit:
}
static void rtas_ibm_read_slot_reset_state2(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args, uint32_t nret,
target_ulong rets)
{
- sPAPRPHBState *sphb;
+ SpaprPhbState *sphb;
uint64_t buid;
int state, ret;
@@ -612,12 +612,12 @@ param_error_exit:
}
static void rtas_ibm_set_slot_reset(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args, uint32_t nret,
target_ulong rets)
{
- sPAPRPHBState *sphb;
+ SpaprPhbState *sphb;
uint32_t option;
uint64_t buid;
int ret;
@@ -646,12 +646,12 @@ param_error_exit:
}
static void rtas_ibm_configure_pe(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args, uint32_t nret,
target_ulong rets)
{
- sPAPRPHBState *sphb;
+ SpaprPhbState *sphb;
uint64_t buid;
int ret;
@@ -679,12 +679,12 @@ param_error_exit:
/* To support it later */
static void rtas_ibm_slot_error_detail(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args, uint32_t nret,
target_ulong rets)
{
- sPAPRPHBState *sphb;
+ SpaprPhbState *sphb;
int option;
uint64_t buid;
@@ -741,7 +741,7 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, int level)
* Here we use the number returned by pci_spapr_map_irq to find a
* corresponding qemu_irq.
*/
- sPAPRPHBState *phb = opaque;
+ SpaprPhbState *phb = opaque;
trace_spapr_pci_lsi_set(phb->dtbusname, irq_num, phb->lsi_table[irq_num].irq);
qemu_set_irq(spapr_phb_lsi_qirq(phb, irq_num), level);
@@ -749,7 +749,7 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, int level)
static PCIINTxRoute spapr_route_intx_pin_to_irq(void *opaque, int pin)
{
- sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(opaque);
+ SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(opaque);
PCIINTxRoute route;
route.mode = PCI_INTX_ENABLED;
@@ -766,7 +766,7 @@ static PCIINTxRoute spapr_route_intx_pin_to_irq(void *opaque, int pin)
static void spapr_msi_write(void *opaque, hwaddr addr,
uint64_t data, unsigned size)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+ SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
uint32_t irq = data;
trace_spapr_pci_msi_write(addr, data, irq);
@@ -786,12 +786,12 @@ static const MemoryRegionOps spapr_msi_ops = {
*/
static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
{
- sPAPRPHBState *phb = opaque;
+ SpaprPhbState *phb = opaque;
return &phb->iommu_as;
}
-static char *spapr_phb_vfio_get_loc_code(sPAPRPHBState *sphb, PCIDevice *pdev)
+static char *spapr_phb_vfio_get_loc_code(SpaprPhbState *sphb, PCIDevice *pdev)
{
char *path = NULL, *buf = NULL, *host = NULL;
@@ -822,7 +822,7 @@ err_out:
return NULL;
}
-static char *spapr_phb_get_loc_code(sPAPRPHBState *sphb, PCIDevice *pdev)
+static char *spapr_phb_get_loc_code(SpaprPhbState *sphb, PCIDevice *pdev)
{
char *buf;
const char *devtype = "qemu";
@@ -1249,11 +1249,11 @@ static gchar *pci_get_node_name(PCIDevice *dev)
}
}
-static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb,
+static uint32_t spapr_phb_get_pci_drc_index(SpaprPhbState *phb,
PCIDevice *pdev);
static void spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset,
- sPAPRPHBState *sphb)
+ SpaprPhbState *sphb)
{
ResourceProps rp;
bool is_bridge = false;
@@ -1358,7 +1358,7 @@ static void spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset,
}
/* create OF node for pci device and required OF DT properties */
-static int spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev,
+static int spapr_create_pci_child_dt(SpaprPhbState *phb, PCIDevice *dev,
void *fdt, int node_offset)
{
int offset;
@@ -1382,7 +1382,7 @@ void spapr_phb_remove_pci_device_cb(DeviceState *dev)
object_unparent(OBJECT(dev));
}
-static sPAPRDRConnector *spapr_phb_get_pci_func_drc(sPAPRPHBState *phb,
+static SpaprDrc *spapr_phb_get_pci_func_drc(SpaprPhbState *phb,
uint32_t busnr,
int32_t devfn)
{
@@ -1390,17 +1390,17 @@ static sPAPRDRConnector *spapr_phb_get_pci_func_drc(sPAPRPHBState *phb,
(phb->index << 16) | (busnr << 8) | devfn);
}
-static sPAPRDRConnector *spapr_phb_get_pci_drc(sPAPRPHBState *phb,
+static SpaprDrc *spapr_phb_get_pci_drc(SpaprPhbState *phb,
PCIDevice *pdev)
{
uint32_t busnr = pci_bus_num(PCI_BUS(qdev_get_parent_bus(DEVICE(pdev))));
return spapr_phb_get_pci_func_drc(phb, busnr, pdev->devfn);
}
-static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb,
+static uint32_t spapr_phb_get_pci_drc_index(SpaprPhbState *phb,
PCIDevice *pdev)
{
- sPAPRDRConnector *drc = spapr_phb_get_pci_drc(phb, pdev);
+ SpaprDrc *drc = spapr_phb_get_pci_drc(phb, pdev);
if (!drc) {
return 0;
@@ -1409,11 +1409,11 @@ static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb,
return spapr_drc_index(drc);
}
-int spapr_pci_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
+int spapr_pci_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
void *fdt, int *fdt_start_offset, Error **errp)
{
HotplugHandler *plug_handler = qdev_get_hotplug_handler(drc->dev);
- sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(plug_handler);
+ SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(plug_handler);
PCIDevice *pdev = PCI_DEVICE(drc->dev);
*fdt_start_offset = spapr_create_pci_child_dt(sphb, pdev, fdt, 0);
@@ -1423,9 +1423,9 @@ int spapr_pci_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
static void spapr_pci_plug(HotplugHandler *plug_handler,
DeviceState *plugged_dev, Error **errp)
{
- sPAPRPHBState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
+ SpaprPhbState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
PCIDevice *pdev = PCI_DEVICE(plugged_dev);
- sPAPRDRConnector *drc = spapr_phb_get_pci_drc(phb, pdev);
+ SpaprDrc *drc = spapr_phb_get_pci_drc(phb, pdev);
Error *local_err = NULL;
PCIBus *bus = PCI_BUS(qdev_get_parent_bus(DEVICE(pdev)));
uint32_t slotnr = PCI_SLOT(pdev->devfn);
@@ -1472,9 +1472,9 @@ static void spapr_pci_plug(HotplugHandler *plug_handler,
int i;
for (i = 0; i < 8; i++) {
- sPAPRDRConnector *func_drc;
- sPAPRDRConnectorClass *func_drck;
- sPAPRDREntitySense state;
+ SpaprDrc *func_drc;
+ SpaprDrcClass *func_drck;
+ SpaprDREntitySense state;
func_drc = spapr_phb_get_pci_func_drc(phb, pci_bus_num(bus),
PCI_DEVFN(slotnr, i));
@@ -1513,9 +1513,9 @@ static void spapr_pci_unplug(HotplugHandler *plug_handler,
static void spapr_pci_unplug_request(HotplugHandler *plug_handler,
DeviceState *plugged_dev, Error **errp)
{
- sPAPRPHBState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
+ SpaprPhbState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
PCIDevice *pdev = PCI_DEVICE(plugged_dev);
- sPAPRDRConnector *drc = spapr_phb_get_pci_drc(phb, pdev);
+ SpaprDrc *drc = spapr_phb_get_pci_drc(phb, pdev);
if (!phb->dr_enabled) {
error_setg(errp, QERR_BUS_NO_HOTPLUG,
@@ -1529,9 +1529,9 @@ static void spapr_pci_unplug_request(HotplugHandler *plug_handler,
if (!spapr_drc_unplug_requested(drc)) {
PCIBus *bus = PCI_BUS(qdev_get_parent_bus(DEVICE(pdev)));
uint32_t slotnr = PCI_SLOT(pdev->devfn);
- sPAPRDRConnector *func_drc;
- sPAPRDRConnectorClass *func_drck;
- sPAPRDREntitySense state;
+ SpaprDrc *func_drc;
+ SpaprDrcClass *func_drck;
+ SpaprDREntitySense state;
int i;
/* ensure any other present functions are pending unplug */
@@ -1573,7 +1573,7 @@ static void spapr_pci_unplug_request(HotplugHandler *plug_handler,
static void spapr_phb_finalizefn(Object *obj)
{
- sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(obj);
+ SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(obj);
g_free(sphb->dtbusname);
sphb->dtbusname = NULL;
@@ -1581,11 +1581,11 @@ static void spapr_phb_finalizefn(Object *obj)
static void spapr_phb_unrealize(DeviceState *dev, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+ SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
SysBusDevice *s = SYS_BUS_DEVICE(dev);
PCIHostState *phb = PCI_HOST_BRIDGE(s);
- sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(phb);
- sPAPRTCETable *tcet;
+ SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(phb);
+ SpaprTceTable *tcet;
int i;
const unsigned windows_supported = spapr_phb_windows_supported(sphb);
@@ -1608,7 +1608,7 @@ static void spapr_phb_unrealize(DeviceState *dev, Error **errp)
if (sphb->dr_enabled) {
for (i = PCI_SLOT_MAX * 8 - 1; i >= 0; i--) {
- sPAPRDRConnector *drc = spapr_drc_by_id(TYPE_SPAPR_DRC_PCI,
+ SpaprDrc *drc = spapr_drc_by_id(TYPE_SPAPR_DRC_PCI,
(sphb->index << 16) | i);
if (drc) {
@@ -1645,18 +1645,18 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
/* We don't use SPAPR_MACHINE() in order to exit gracefully if the user
* tries to add a sPAPR PHB to a non-pseries machine.
*/
- sPAPRMachineState *spapr =
- (sPAPRMachineState *) object_dynamic_cast(qdev_get_machine(),
+ SpaprMachineState *spapr =
+ (SpaprMachineState *) object_dynamic_cast(qdev_get_machine(),
TYPE_SPAPR_MACHINE);
- sPAPRMachineClass *smc = spapr ? SPAPR_MACHINE_GET_CLASS(spapr) : NULL;
+ SpaprMachineClass *smc = spapr ? SPAPR_MACHINE_GET_CLASS(spapr) : NULL;
SysBusDevice *s = SYS_BUS_DEVICE(dev);
- sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s);
+ SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(s);
PCIHostState *phb = PCI_HOST_BRIDGE(s);
char *namebuf;
int i;
PCIBus *bus;
uint64_t msi_window_size = 4096;
- sPAPRTCETable *tcet;
+ SpaprTceTable *tcet;
const unsigned windows_supported = spapr_phb_windows_supported(sphb);
if (!spapr) {
@@ -1855,10 +1855,10 @@ static int spapr_phb_children_reset(Object *child, void *opaque)
return 0;
}
-void spapr_phb_dma_reset(sPAPRPHBState *sphb)
+void spapr_phb_dma_reset(SpaprPhbState *sphb)
{
int i;
- sPAPRTCETable *tcet;
+ SpaprTceTable *tcet;
for (i = 0; i < SPAPR_PCI_DMA_MAX_WINDOWS; ++i) {
tcet = spapr_tce_find_by_liobn(sphb->dma_liobn[i]);
@@ -1876,7 +1876,7 @@ void spapr_phb_dma_reset(sPAPRPHBState *sphb)
static void spapr_phb_reset(DeviceState *qdev)
{
- sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(qdev);
+ SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(qdev);
spapr_phb_dma_reset(sphb);
@@ -1889,27 +1889,27 @@ static void spapr_phb_reset(DeviceState *qdev)
}
static Property spapr_phb_properties[] = {
- DEFINE_PROP_UINT32("index", sPAPRPHBState, index, -1),
- DEFINE_PROP_UINT64("mem_win_size", sPAPRPHBState, mem_win_size,
+ DEFINE_PROP_UINT32("index", SpaprPhbState, index, -1),
+ DEFINE_PROP_UINT64("mem_win_size", SpaprPhbState, mem_win_size,
SPAPR_PCI_MEM32_WIN_SIZE),
- DEFINE_PROP_UINT64("mem64_win_size", sPAPRPHBState, mem64_win_size,
+ DEFINE_PROP_UINT64("mem64_win_size", SpaprPhbState, mem64_win_size,
SPAPR_PCI_MEM64_WIN_SIZE),
- DEFINE_PROP_UINT64("io_win_size", sPAPRPHBState, io_win_size,
+ DEFINE_PROP_UINT64("io_win_size", SpaprPhbState, io_win_size,
SPAPR_PCI_IO_WIN_SIZE),
- DEFINE_PROP_BOOL("dynamic-reconfiguration", sPAPRPHBState, dr_enabled,
+ DEFINE_PROP_BOOL("dynamic-reconfiguration", SpaprPhbState, dr_enabled,
true),
/* Default DMA window is 0..1GB */
- DEFINE_PROP_UINT64("dma_win_addr", sPAPRPHBState, dma_win_addr, 0),
- DEFINE_PROP_UINT64("dma_win_size", sPAPRPHBState, dma_win_size, 0x40000000),
- DEFINE_PROP_UINT64("dma64_win_addr", sPAPRPHBState, dma64_win_addr,
+ DEFINE_PROP_UINT64("dma_win_addr", SpaprPhbState, dma_win_addr, 0),
+ DEFINE_PROP_UINT64("dma_win_size", SpaprPhbState, dma_win_size, 0x40000000),
+ DEFINE_PROP_UINT64("dma64_win_addr", SpaprPhbState, dma64_win_addr,
0x800000000000000ULL),
- DEFINE_PROP_BOOL("ddw", sPAPRPHBState, ddw_enabled, true),
- DEFINE_PROP_UINT64("pgsz", sPAPRPHBState, page_size_mask,
+ DEFINE_PROP_BOOL("ddw", SpaprPhbState, ddw_enabled, true),
+ DEFINE_PROP_UINT64("pgsz", SpaprPhbState, page_size_mask,
(1ULL << 12) | (1ULL << 16)),
- DEFINE_PROP_UINT32("numa_node", sPAPRPHBState, numa_node, -1),
- DEFINE_PROP_BOOL("pre-2.8-migration", sPAPRPHBState,
+ DEFINE_PROP_UINT32("numa_node", SpaprPhbState, numa_node, -1),
+ DEFINE_PROP_BOOL("pre-2.8-migration", SpaprPhbState,
pre_2_8_migration, false),
- DEFINE_PROP_BOOL("pcie-extended-configuration-space", sPAPRPHBState,
+ DEFINE_PROP_BOOL("pcie-extended-configuration-space", SpaprPhbState,
pcie_ecs, true),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1939,7 +1939,7 @@ static const VMStateDescription vmstate_spapr_pci_msi = {
static int spapr_pci_pre_save(void *opaque)
{
- sPAPRPHBState *sphb = opaque;
+ SpaprPhbState *sphb = opaque;
GHashTableIter iter;
gpointer key, value;
int i;
@@ -1977,7 +1977,7 @@ static int spapr_pci_pre_save(void *opaque)
static int spapr_pci_post_load(void *opaque, int version_id)
{
- sPAPRPHBState *sphb = opaque;
+ SpaprPhbState *sphb = opaque;
gpointer key, value;
int i;
@@ -1997,7 +1997,7 @@ static int spapr_pci_post_load(void *opaque, int version_id)
static bool pre_2_8_migration(void *opaque, int version_id)
{
- sPAPRPHBState *sphb = opaque;
+ SpaprPhbState *sphb = opaque;
return sphb->pre_2_8_migration;
}
@@ -2009,16 +2009,16 @@ static const VMStateDescription vmstate_spapr_pci = {
.pre_save = spapr_pci_pre_save,
.post_load = spapr_pci_post_load,
.fields = (VMStateField[]) {
- VMSTATE_UINT64_EQUAL(buid, sPAPRPHBState, NULL),
- VMSTATE_UINT32_TEST(mig_liobn, sPAPRPHBState, pre_2_8_migration),
- VMSTATE_UINT64_TEST(mig_mem_win_addr, sPAPRPHBState, pre_2_8_migration),
- VMSTATE_UINT64_TEST(mig_mem_win_size, sPAPRPHBState, pre_2_8_migration),
- VMSTATE_UINT64_TEST(mig_io_win_addr, sPAPRPHBState, pre_2_8_migration),
- VMSTATE_UINT64_TEST(mig_io_win_size, sPAPRPHBState, pre_2_8_migration),
- VMSTATE_STRUCT_ARRAY(lsi_table, sPAPRPHBState, PCI_NUM_PINS, 0,
+ VMSTATE_UINT64_EQUAL(buid, SpaprPhbState, NULL),
+ VMSTATE_UINT32_TEST(mig_liobn, SpaprPhbState, pre_2_8_migration),
+ VMSTATE_UINT64_TEST(mig_mem_win_addr, SpaprPhbState, pre_2_8_migration),
+ VMSTATE_UINT64_TEST(mig_mem_win_size, SpaprPhbState, pre_2_8_migration),
+ VMSTATE_UINT64_TEST(mig_io_win_addr, SpaprPhbState, pre_2_8_migration),
+ VMSTATE_UINT64_TEST(mig_io_win_size, SpaprPhbState, pre_2_8_migration),
+ VMSTATE_STRUCT_ARRAY(lsi_table, SpaprPhbState, PCI_NUM_PINS, 0,
vmstate_spapr_pci_lsi, struct spapr_pci_lsi),
- VMSTATE_INT32(msi_devs_num, sPAPRPHBState),
- VMSTATE_STRUCT_VARRAY_ALLOC(msi_devs, sPAPRPHBState, msi_devs_num, 0,
+ VMSTATE_INT32(msi_devs_num, SpaprPhbState),
+ VMSTATE_STRUCT_VARRAY_ALLOC(msi_devs, SpaprPhbState, msi_devs_num, 0,
vmstate_spapr_pci_msi, spapr_pci_msi_mig),
VMSTATE_END_OF_LIST()
},
@@ -2027,7 +2027,7 @@ static const VMStateDescription vmstate_spapr_pci = {
static const char *spapr_phb_root_bus_path(PCIHostState *host_bridge,
PCIBus *rootbus)
{
- sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(host_bridge);
+ SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(host_bridge);
return sphb->dtbusname;
}
@@ -2055,7 +2055,7 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data)
static const TypeInfo spapr_phb_info = {
.name = TYPE_SPAPR_PCI_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
- .instance_size = sizeof(sPAPRPHBState),
+ .instance_size = sizeof(SpaprPhbState),
.instance_finalize = spapr_phb_finalizefn,
.class_init = spapr_phb_class_init,
.interfaces = (InterfaceInfo[]) {
@@ -2064,19 +2064,19 @@ static const TypeInfo spapr_phb_info = {
}
};
-typedef struct sPAPRFDT {
+typedef struct SpaprFdt {
void *fdt;
int node_off;
- sPAPRPHBState *sphb;
-} sPAPRFDT;
+ SpaprPhbState *sphb;
+} SpaprFdt;
static void spapr_populate_pci_devices_dt(PCIBus *bus, PCIDevice *pdev,
void *opaque)
{
PCIBus *sec_bus;
- sPAPRFDT *p = opaque;
+ SpaprFdt *p = opaque;
int offset;
- sPAPRFDT s_fdt;
+ SpaprFdt s_fdt;
offset = spapr_create_pci_child_dt(p->sphb, pdev, p->fdt, p->node_off);
if (!offset) {
@@ -2128,7 +2128,7 @@ static void spapr_phb_pci_enumerate_bridge(PCIBus *bus, PCIDevice *pdev,
pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, *bus_no, 1);
}
-static void spapr_phb_pci_enumerate(sPAPRPHBState *phb)
+static void spapr_phb_pci_enumerate(SpaprPhbState *phb)
{
PCIBus *bus = PCI_HOST_BRIDGE(phb)->bus;
unsigned int bus_no = 0;
@@ -2139,7 +2139,7 @@ static void spapr_phb_pci_enumerate(sPAPRPHBState *phb)
}
-int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t intc_phandle, void *fdt,
+int spapr_populate_pci_dt(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt,
uint32_t nr_msis, int *node_offset)
{
int bus_off, i, j, ret;
@@ -2187,10 +2187,10 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t intc_phandle, void *fdt,
cpu_to_be32(0x0),
cpu_to_be32(0x0),
cpu_to_be32(phb->numa_node)};
- sPAPRTCETable *tcet;
+ SpaprTceTable *tcet;
PCIBus *bus = PCI_HOST_BRIDGE(phb)->bus;
- sPAPRFDT s_fdt;
- sPAPRDRConnector *drc;
+ SpaprFdt s_fdt;
+ SpaprDrc *drc;
/* Start populating the FDT */
nodename = g_strdup_printf("pci@%" PRIx64, phb->buid);
@@ -2345,8 +2345,8 @@ static int spapr_switch_one_vga(DeviceState *dev, void *opaque)
void spapr_pci_switch_vga(bool big_endian)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
- sPAPRPHBState *sphb;
+ SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+ SpaprPhbState *sphb;
/*
* For backward compatibility with existing guests, we switch
diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c
index 71491dbd28..5f5dde567d 100644
--- a/hw/ppc/spapr_pci_vfio.c
+++ b/hw/ppc/spapr_pci_vfio.c
@@ -28,12 +28,12 @@
#include "qemu/error-report.h"
#include "sysemu/qtest.h"
-bool spapr_phb_eeh_available(sPAPRPHBState *sphb)
+bool spapr_phb_eeh_available(SpaprPhbState *sphb)
{
return vfio_eeh_as_ok(&sphb->iommu_as);
}
-static void spapr_phb_vfio_eeh_reenable(sPAPRPHBState *sphb)
+static void spapr_phb_vfio_eeh_reenable(SpaprPhbState *sphb)
{
vfio_eeh_as_op(&sphb->iommu_as, VFIO_EEH_PE_ENABLE);
}
@@ -49,7 +49,7 @@ void spapr_phb_vfio_reset(DeviceState *qdev)
spapr_phb_vfio_eeh_reenable(SPAPR_PCI_HOST_BRIDGE(qdev));
}
-int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
+int spapr_phb_vfio_eeh_set_option(SpaprPhbState *sphb,
unsigned int addr, int option)
{
uint32_t op;
@@ -96,7 +96,7 @@ int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
return RTAS_OUT_SUCCESS;
}
-int spapr_phb_vfio_eeh_get_state(sPAPRPHBState *sphb, int *state)
+int spapr_phb_vfio_eeh_get_state(SpaprPhbState *sphb, int *state)
{
int ret;
@@ -145,14 +145,14 @@ static void spapr_phb_vfio_eeh_clear_bus_msix(PCIBus *bus, void *opaque)
spapr_phb_vfio_eeh_clear_dev_msix, NULL);
}
-static void spapr_phb_vfio_eeh_pre_reset(sPAPRPHBState *sphb)
+static void spapr_phb_vfio_eeh_pre_reset(SpaprPhbState *sphb)
{
PCIHostState *phb = PCI_HOST_BRIDGE(sphb);
pci_for_each_bus(phb->bus, spapr_phb_vfio_eeh_clear_bus_msix, NULL);
}
-int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option)
+int spapr_phb_vfio_eeh_reset(SpaprPhbState *sphb, int option)
{
uint32_t op;
int ret;
@@ -181,7 +181,7 @@ int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option)
return RTAS_OUT_SUCCESS;
}
-int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb)
+int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb)
{
int ret;
diff --git a/hw/ppc/spapr_rng.c b/hw/ppc/spapr_rng.c
index 644bac96f8..4060987590 100644
--- a/hw/ppc/spapr_rng.c
+++ b/hw/ppc/spapr_rng.c
@@ -29,15 +29,15 @@
#include "kvm_ppc.h"
#define SPAPR_RNG(obj) \
- OBJECT_CHECK(sPAPRRngState, (obj), TYPE_SPAPR_RNG)
+ OBJECT_CHECK(SpaprRngState, (obj), TYPE_SPAPR_RNG)
-struct sPAPRRngState {
+struct SpaprRngState {
/*< private >*/
DeviceState ds;
RngBackend *backend;
bool use_kvm;
};
-typedef struct sPAPRRngState sPAPRRngState;
+typedef struct SpaprRngState SpaprRngState;
struct HRandomData {
QemuSemaphore sem;
@@ -64,10 +64,10 @@ static void random_recv(void *dest, const void *src, size_t size)
}
/* Handler for the H_RANDOM hypercall */
-static target_ulong h_random(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_random(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
- sPAPRRngState *rngstate;
+ SpaprRngState *rngstate;
HRandomData hrdata;
rngstate = SPAPR_RNG(object_resolve_path_type("", TYPE_SPAPR_RNG, NULL));
@@ -109,7 +109,7 @@ static void spapr_rng_instance_init(Object *obj)
static void spapr_rng_realize(DeviceState *dev, Error **errp)
{
- sPAPRRngState *rngstate = SPAPR_RNG(dev);
+ SpaprRngState *rngstate = SPAPR_RNG(dev);
if (rngstate->use_kvm) {
if (kvmppc_enable_hwrng() == 0) {
@@ -133,8 +133,8 @@ static void spapr_rng_realize(DeviceState *dev, Error **errp)
}
static Property spapr_rng_properties[] = {
- DEFINE_PROP_BOOL("use-kvm", sPAPRRngState, use_kvm, false),
- DEFINE_PROP_LINK("rng", sPAPRRngState, backend, TYPE_RNG_BACKEND,
+ DEFINE_PROP_BOOL("use-kvm", SpaprRngState, use_kvm, false),
+ DEFINE_PROP_LINK("rng", SpaprRngState, backend, TYPE_RNG_BACKEND,
RngBackend *),
DEFINE_PROP_END_OF_LIST(),
};
@@ -152,7 +152,7 @@ static void spapr_rng_class_init(ObjectClass *oc, void *data)
static const TypeInfo spapr_rng_info = {
.name = TYPE_SPAPR_RNG,
.parent = TYPE_DEVICE,
- .instance_size = sizeof(sPAPRRngState),
+ .instance_size = sizeof(SpaprRngState),
.instance_init = spapr_rng_instance_init,
.class_init = spapr_rng_class_init,
};
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 7a2cb786a3..24c45b12d4 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -50,13 +50,13 @@
#include "target/ppc/mmu-hash64.h"
#include "target/ppc/mmu-book3s-v3.h"
-static void rtas_display_character(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_display_character(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
{
uint8_t c = rtas_ld(args, 0);
- VIOsPAPRDevice *sdev = vty_lookup(spapr, 0);
+ SpaprVioDevice *sdev = vty_lookup(spapr, 0);
if (!sdev) {
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
@@ -66,7 +66,7 @@ static void rtas_display_character(PowerPCCPU *cpu, sPAPRMachineState *spapr,
}
}
-static void rtas_power_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_power_off(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets)
{
@@ -79,7 +79,7 @@ static void rtas_power_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
-static void rtas_system_reboot(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_system_reboot(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
@@ -93,7 +93,7 @@ static void rtas_system_reboot(PowerPCCPU *cpu, sPAPRMachineState *spapr,
}
static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
@@ -123,7 +123,7 @@ static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_,
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
}
-static void rtas_start_cpu(PowerPCCPU *callcpu, sPAPRMachineState *spapr,
+static void rtas_start_cpu(PowerPCCPU *callcpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
@@ -194,7 +194,7 @@ static void rtas_start_cpu(PowerPCCPU *callcpu, sPAPRMachineState *spapr,
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
-static void rtas_stop_self(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_stop_self(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
@@ -226,7 +226,7 @@ static inline int sysparm_st(target_ulong addr, target_ulong len,
}
static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
@@ -268,7 +268,7 @@ static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
}
static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
@@ -288,7 +288,7 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
}
static void rtas_ibm_os_term(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
@@ -298,7 +298,7 @@ static void rtas_ibm_os_term(PowerPCCPU *cpu,
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
-static void rtas_set_power_level(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_set_power_level(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args, uint32_t nret,
target_ulong rets)
@@ -323,7 +323,7 @@ static void rtas_set_power_level(PowerPCCPU *cpu, sPAPRMachineState *spapr,
rtas_st(rets, 1, 100);
}
-static void rtas_get_power_level(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_get_power_level(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args, uint32_t nret,
target_ulong rets)
@@ -353,7 +353,7 @@ static struct rtas_call {
spapr_rtas_fn fn;
} rtas_table[RTAS_TOKEN_MAX - RTAS_TOKEN_BASE];
-target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+target_ulong spapr_rtas_call(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets)
{
@@ -387,7 +387,7 @@ uint64_t qtest_rtas_call(char *cmd, uint32_t nargs, uint64_t args,
for (token = 0; token < RTAS_TOKEN_MAX - RTAS_TOKEN_BASE; token++) {
if (strcmp(cmd, rtas_table[token].name) == 0) {
- sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+ SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
rtas_table[token].fn(cpu, spapr, token + RTAS_TOKEN_BASE,
@@ -425,7 +425,7 @@ void spapr_dt_rtas_tokens(void *fdt, int rtas)
}
}
-void spapr_load_rtas(sPAPRMachineState *spapr, void *fdt, hwaddr addr)
+void spapr_load_rtas(SpaprMachineState *spapr, void *fdt, hwaddr addr)
{
int rtas_node;
int ret;
diff --git a/hw/ppc/spapr_rtas_ddw.c b/hw/ppc/spapr_rtas_ddw.c
index cb8a410359..f6538189f4 100644
--- a/hw/ppc/spapr_rtas_ddw.c
+++ b/hw/ppc/spapr_rtas_ddw.c
@@ -26,16 +26,16 @@
static int spapr_phb_get_active_win_num_cb(Object *child, void *opaque)
{
- sPAPRTCETable *tcet;
+ SpaprTceTable *tcet;
- tcet = (sPAPRTCETable *) object_dynamic_cast(child, TYPE_SPAPR_TCE_TABLE);
+ tcet = (SpaprTceTable *) object_dynamic_cast(child, TYPE_SPAPR_TCE_TABLE);
if (tcet && tcet->nb_table) {
++*(unsigned *)opaque;
}
return 0;
}
-static unsigned spapr_phb_get_active_win_num(sPAPRPHBState *sphb)
+static unsigned spapr_phb_get_active_win_num(SpaprPhbState *sphb)
{
unsigned ret = 0;
@@ -46,9 +46,9 @@ static unsigned spapr_phb_get_active_win_num(sPAPRPHBState *sphb)
static int spapr_phb_get_free_liobn_cb(Object *child, void *opaque)
{
- sPAPRTCETable *tcet;
+ SpaprTceTable *tcet;
- tcet = (sPAPRTCETable *) object_dynamic_cast(child, TYPE_SPAPR_TCE_TABLE);
+ tcet = (SpaprTceTable *) object_dynamic_cast(child, TYPE_SPAPR_TCE_TABLE);
if (tcet && !tcet->nb_table) {
*(uint32_t *)opaque = tcet->liobn;
return 1;
@@ -56,7 +56,7 @@ static int spapr_phb_get_free_liobn_cb(Object *child, void *opaque)
return 0;
}
-static unsigned spapr_phb_get_free_liobn(sPAPRPHBState *sphb)
+static unsigned spapr_phb_get_free_liobn(SpaprPhbState *sphb)
{
uint32_t liobn = 0;
@@ -90,12 +90,12 @@ static uint32_t spapr_page_mask_to_query_mask(uint64_t page_mask)
}
static void rtas_ibm_query_pe_dma_window(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
{
- sPAPRPHBState *sphb;
+ SpaprPhbState *sphb;
uint64_t buid;
uint32_t avail, addr, pgmask = 0;
@@ -129,13 +129,13 @@ param_error_exit:
}
static void rtas_ibm_create_pe_dma_window(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
{
- sPAPRPHBState *sphb;
- sPAPRTCETable *tcet = NULL;
+ SpaprPhbState *sphb;
+ SpaprTceTable *tcet = NULL;
uint32_t addr, page_shift, window_shift, liobn;
uint64_t buid, win_addr;
int windows;
@@ -171,8 +171,18 @@ static void rtas_ibm_create_pe_dma_window(PowerPCCPU *cpu,
}
win_addr = (windows == 0) ? sphb->dma_win_addr : sphb->dma64_win_addr;
+ /*
+ * We have just created a window, we know for the fact that it is empty,
+ * use a hack to avoid iterating over the table as it is quite possible
+ * to have billions of TCEs, all empty.
+ * Note that we cannot delay this to the first H_PUT_TCE as this hcall is
+ * mostly likely to be handled in KVM so QEMU just does not know if it
+ * happened.
+ */
+ tcet->skipping_replay = true;
spapr_tce_table_enable(tcet, page_shift, win_addr,
1ULL << (window_shift - page_shift));
+ tcet->skipping_replay = false;
if (!tcet->nb_table) {
goto hw_error_exit;
}
@@ -196,13 +206,13 @@ param_error_exit:
}
static void rtas_ibm_remove_pe_dma_window(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
{
- sPAPRPHBState *sphb;
- sPAPRTCETable *tcet;
+ SpaprPhbState *sphb;
+ SpaprTceTable *tcet;
uint32_t liobn;
if ((nargs != 1) || (nret != 1)) {
@@ -231,12 +241,12 @@ param_error_exit:
}
static void rtas_ibm_reset_pe_dma_window(PowerPCCPU *cpu,
- sPAPRMachineState *spapr,
+ SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
{
- sPAPRPHBState *sphb;
+ SpaprPhbState *sphb;
uint64_t buid;
uint32_t addr;
diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c
index eb95a7077d..d732a3ea95 100644
--- a/hw/ppc/spapr_rtc.c
+++ b/hw/ppc/spapr_rtc.c
@@ -34,7 +34,7 @@
#include "qapi/qapi-events-target.h"
#include "qemu/cutils.h"
-void spapr_rtc_read(sPAPRRTCState *rtc, struct tm *tm, uint32_t *ns)
+void spapr_rtc_read(SpaprRtcState *rtc, struct tm *tm, uint32_t *ns)
{
int64_t host_ns = qemu_clock_get_ns(rtc_clock);
int64_t guest_ns;
@@ -53,7 +53,7 @@ void spapr_rtc_read(sPAPRRTCState *rtc, struct tm *tm, uint32_t *ns)
}
}
-int spapr_rtc_import_offset(sPAPRRTCState *rtc, int64_t legacy_offset)
+int spapr_rtc_import_offset(SpaprRtcState *rtc, int64_t legacy_offset)
{
if (!rtc) {
return -ENODEV;
@@ -64,7 +64,7 @@ int spapr_rtc_import_offset(sPAPRRTCState *rtc, int64_t legacy_offset)
return 0;
}
-static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_get_time_of_day(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
@@ -89,12 +89,12 @@ static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPRMachineState *spapr,
rtas_st(rets, 7, ns);
}
-static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_set_time_of_day(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
{
- sPAPRRTCState *rtc = &spapr->rtc;
+ SpaprRtcState *rtc = &spapr->rtc;
struct tm tm;
time_t new_s;
int64_t host_ns;
@@ -134,7 +134,7 @@ static void spapr_rtc_qom_date(Object *obj, struct tm *current_tm, Error **errp)
static void spapr_rtc_realize(DeviceState *dev, Error **errp)
{
- sPAPRRTCState *rtc = SPAPR_RTC(dev);
+ SpaprRtcState *rtc = SPAPR_RTC(dev);
struct tm tm;
time_t host_s;
int64_t rtc_ns;
@@ -154,7 +154,7 @@ static const VMStateDescription vmstate_spapr_rtc = {
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
- VMSTATE_INT64(ns_offset, sPAPRRTCState),
+ VMSTATE_INT64(ns_offset, SpaprRtcState),
VMSTATE_END_OF_LIST()
},
};
@@ -177,7 +177,7 @@ static void spapr_rtc_class_init(ObjectClass *oc, void *data)
static const TypeInfo spapr_rtc_info = {
.name = TYPE_SPAPR_RTC,
.parent = TYPE_DEVICE,
- .instance_size = sizeof(sPAPRRTCState),
+ .instance_size = sizeof(SpaprRtcState),
.class_init = spapr_rtc_class_init,
};
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index 2b7e7ecac5..583c13deda 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -46,8 +46,8 @@
static char *spapr_vio_get_dev_name(DeviceState *qdev)
{
- VIOsPAPRDevice *dev = VIO_SPAPR_DEVICE(qdev);
- VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
+ SpaprVioDevice *dev = VIO_SPAPR_DEVICE(qdev);
+ SpaprVioDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
/* Device tree style name device@reg */
return g_strdup_printf("%s@%x", pc->dt_name, dev->reg);
@@ -65,16 +65,16 @@ static const TypeInfo spapr_vio_bus_info = {
.name = TYPE_SPAPR_VIO_BUS,
.parent = TYPE_BUS,
.class_init = spapr_vio_bus_class_init,
- .instance_size = sizeof(VIOsPAPRBus),
+ .instance_size = sizeof(SpaprVioBus),
};
-VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
+SpaprVioDevice *spapr_vio_find_by_reg(SpaprVioBus *bus, uint32_t reg)
{
BusChild *kid;
- VIOsPAPRDevice *dev = NULL;
+ SpaprVioDevice *dev = NULL;
QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
- dev = (VIOsPAPRDevice *)kid->child;
+ dev = (SpaprVioDevice *)kid->child;
if (dev->reg == reg) {
return dev;
}
@@ -83,10 +83,10 @@ VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
return NULL;
}
-static int vio_make_devnode(VIOsPAPRDevice *dev,
+static int vio_make_devnode(SpaprVioDevice *dev,
void *fdt)
{
- VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
+ SpaprVioDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
int vdevice_off, node_off, ret;
char *dt_name;
@@ -152,13 +152,13 @@ static int vio_make_devnode(VIOsPAPRDevice *dev,
/*
* CRQ handling
*/
-static target_ulong h_reg_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_reg_crq(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong reg = args[0];
target_ulong queue_addr = args[1];
target_ulong queue_len = args[2];
- VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+ SpaprVioDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
if (!dev) {
hcall_dprintf("Unit 0x" TARGET_FMT_lx " does not exist\n", reg);
@@ -197,7 +197,7 @@ static target_ulong h_reg_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-static target_ulong free_crq(VIOsPAPRDevice *dev)
+static target_ulong free_crq(SpaprVioDevice *dev)
{
dev->crq.qladdr = 0;
dev->crq.qsize = 0;
@@ -208,11 +208,11 @@ static target_ulong free_crq(VIOsPAPRDevice *dev)
return H_SUCCESS;
}
-static target_ulong h_free_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_free_crq(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong reg = args[0];
- VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+ SpaprVioDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
if (!dev) {
hcall_dprintf("Unit 0x" TARGET_FMT_lx " does not exist\n", reg);
@@ -222,13 +222,13 @@ static target_ulong h_free_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return free_crq(dev);
}
-static target_ulong h_send_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_send_crq(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong reg = args[0];
target_ulong msg_hi = args[1];
target_ulong msg_lo = args[2];
- VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+ SpaprVioDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
uint64_t crq_mangle[2];
if (!dev) {
@@ -245,11 +245,11 @@ static target_ulong h_send_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_HARDWARE;
}
-static target_ulong h_enable_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_enable_crq(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong reg = args[0];
- VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+ SpaprVioDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
if (!dev) {
hcall_dprintf("Unit 0x" TARGET_FMT_lx " does not exist\n", reg);
@@ -260,7 +260,7 @@ static target_ulong h_enable_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
}
/* Returns negative error, 0 success, or positive: queue full */
-int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq)
+int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq)
{
int rc;
uint8_t byte;
@@ -303,7 +303,7 @@ int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq)
/* "quiesce" handling */
-static void spapr_vio_quiesce_one(VIOsPAPRDevice *dev)
+static void spapr_vio_quiesce_one(SpaprVioDevice *dev)
{
if (dev->tcet) {
device_reset(DEVICE(dev->tcet));
@@ -311,7 +311,7 @@ static void spapr_vio_quiesce_one(VIOsPAPRDevice *dev)
free_crq(dev);
}
-void spapr_vio_set_bypass(VIOsPAPRDevice *dev, bool bypass)
+void spapr_vio_set_bypass(SpaprVioDevice *dev, bool bypass)
{
if (!dev->tcet) {
return;
@@ -323,13 +323,13 @@ void spapr_vio_set_bypass(VIOsPAPRDevice *dev, bool bypass)
dev->tcet->bypass = bypass;
}
-static void rtas_set_tce_bypass(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_set_tce_bypass(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token,
uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets)
{
- VIOsPAPRBus *bus = spapr->vio_bus;
- VIOsPAPRDevice *dev;
+ SpaprVioBus *bus = spapr->vio_bus;
+ SpaprVioDevice *dev;
uint32_t unit, enable;
if (nargs != 2) {
@@ -354,14 +354,14 @@ static void rtas_set_tce_bypass(PowerPCCPU *cpu, sPAPRMachineState *spapr,
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
-static void rtas_quiesce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static void rtas_quiesce(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token,
uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets)
{
- VIOsPAPRBus *bus = spapr->vio_bus;
+ SpaprVioBus *bus = spapr->vio_bus;
BusChild *kid;
- VIOsPAPRDevice *dev = NULL;
+ SpaprVioDevice *dev = NULL;
if (nargs != 0) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
@@ -369,18 +369,18 @@ static void rtas_quiesce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
}
QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
- dev = (VIOsPAPRDevice *)kid->child;
+ dev = (SpaprVioDevice *)kid->child;
spapr_vio_quiesce_one(dev);
}
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
-static VIOsPAPRDevice *reg_conflict(VIOsPAPRDevice *dev)
+static SpaprVioDevice *reg_conflict(SpaprVioDevice *dev)
{
- VIOsPAPRBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus);
+ SpaprVioBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus);
BusChild *kid;
- VIOsPAPRDevice *other;
+ SpaprVioDevice *other;
/*
* Check for a device other than the given one which is already
@@ -400,8 +400,8 @@ static VIOsPAPRDevice *reg_conflict(VIOsPAPRDevice *dev)
static void spapr_vio_busdev_reset(DeviceState *qdev)
{
- VIOsPAPRDevice *dev = VIO_SPAPR_DEVICE(qdev);
- VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
+ SpaprVioDevice *dev = VIO_SPAPR_DEVICE(qdev);
+ SpaprVioDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
/* Shut down the request queue and TCEs if necessary */
spapr_vio_quiesce_one(dev);
@@ -465,9 +465,9 @@ static inline uint32_t spapr_vio_reg_to_irq(uint32_t reg)
static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
- VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
- VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
+ SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+ SpaprVioDevice *dev = (SpaprVioDevice *)qdev;
+ SpaprVioDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
char *id;
Error *local_err = NULL;
@@ -478,7 +478,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
* rather than using spapr_vio_find_by_reg() because sdev
* itself is already in the list.
*/
- VIOsPAPRDevice *other = reg_conflict(dev);
+ SpaprVioDevice *other = reg_conflict(dev);
if (other) {
error_setg(errp, "%s and %s devices conflict at address %#x",
@@ -489,7 +489,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
}
} else {
/* Need to assign an address */
- VIOsPAPRBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus);
+ SpaprVioBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus);
do {
dev->reg = bus->next_reg++;
@@ -540,14 +540,14 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
pc->realize(dev, errp);
}
-static target_ulong h_vio_signal(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+static target_ulong h_vio_signal(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
target_ulong reg = args[0];
target_ulong mode = args[1];
- VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
- VIOsPAPRDeviceClass *pc;
+ SpaprVioDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+ SpaprVioDeviceClass *pc;
if (!dev) {
return H_PARAMETER;
@@ -564,9 +564,9 @@ static target_ulong h_vio_signal(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-VIOsPAPRBus *spapr_vio_bus_init(void)
+SpaprVioBus *spapr_vio_bus_init(void)
{
- VIOsPAPRBus *bus;
+ SpaprVioBus *bus;
BusState *qbus;
DeviceState *dev;
@@ -615,14 +615,14 @@ const VMStateDescription vmstate_spapr_vio = {
.minimum_version_id = 1,
.fields = (VMStateField[]) {
/* Sanity check */
- VMSTATE_UINT32_EQUAL(reg, VIOsPAPRDevice, NULL),
- VMSTATE_UINT32_EQUAL(irq, VIOsPAPRDevice, NULL),
+ VMSTATE_UINT32_EQUAL(reg, SpaprVioDevice, NULL),
+ VMSTATE_UINT32_EQUAL(irq, SpaprVioDevice, NULL),
/* General VIO device state */
- VMSTATE_UINT64(signal_state, VIOsPAPRDevice),
- VMSTATE_UINT64(crq.qladdr, VIOsPAPRDevice),
- VMSTATE_UINT32(crq.qsize, VIOsPAPRDevice),
- VMSTATE_UINT32(crq.qnext, VIOsPAPRDevice),
+ VMSTATE_UINT64(signal_state, SpaprVioDevice),
+ VMSTATE_UINT64(crq.qladdr, SpaprVioDevice),
+ VMSTATE_UINT32(crq.qsize, SpaprVioDevice),
+ VMSTATE_UINT32(crq.qnext, SpaprVioDevice),
VMSTATE_END_OF_LIST()
},
@@ -639,9 +639,9 @@ static void vio_spapr_device_class_init(ObjectClass *klass, void *data)
static const TypeInfo spapr_vio_type_info = {
.name = TYPE_VIO_SPAPR_DEVICE,
.parent = TYPE_DEVICE,
- .instance_size = sizeof(VIOsPAPRDevice),
+ .instance_size = sizeof(SpaprVioDevice),
.abstract = true,
- .class_size = sizeof(VIOsPAPRDeviceClass),
+ .class_size = sizeof(SpaprVioDeviceClass),
.class_init = vio_spapr_device_class_init,
};
@@ -656,10 +656,10 @@ type_init(spapr_vio_register_types)
static int compare_reg(const void *p1, const void *p2)
{
- VIOsPAPRDevice const *dev1, *dev2;
+ SpaprVioDevice const *dev1, *dev2;
- dev1 = (VIOsPAPRDevice *)*(DeviceState **)p1;
- dev2 = (VIOsPAPRDevice *)*(DeviceState **)p2;
+ dev1 = (SpaprVioDevice *)*(DeviceState **)p1;
+ dev2 = (SpaprVioDevice *)*(DeviceState **)p2;
if (dev1->reg < dev2->reg) {
return -1;
@@ -672,7 +672,7 @@ static int compare_reg(const void *p1, const void *p2)
return 1;
}
-void spapr_dt_vdevice(VIOsPAPRBus *bus, void *fdt)
+void spapr_dt_vdevice(SpaprVioBus *bus, void *fdt)
{
DeviceState *qdev, **qdevs;
BusChild *kid;
@@ -707,8 +707,8 @@ void spapr_dt_vdevice(VIOsPAPRBus *bus, void *fdt)
/* Hack alert. Give the devices to libfdt in reverse order, we happen
* to know that will mean they are in forward order in the tree. */
for (i = num - 1; i >= 0; i--) {
- VIOsPAPRDevice *dev = (VIOsPAPRDevice *)(qdevs[i]);
- VIOsPAPRDeviceClass *vdc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
+ SpaprVioDevice *dev = (SpaprVioDevice *)(qdevs[i]);
+ SpaprVioDeviceClass *vdc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
ret = vio_make_devnode(dev, fdt);
if (ret < 0) {
@@ -721,9 +721,9 @@ void spapr_dt_vdevice(VIOsPAPRBus *bus, void *fdt)
g_free(qdevs);
}
-gchar *spapr_vio_stdout_path(VIOsPAPRBus *bus)
+gchar *spapr_vio_stdout_path(SpaprVioBus *bus)
{
- VIOsPAPRDevice *dev;
+ SpaprVioDevice *dev;
char *name, *path;
dev = spapr_vty_get_default(bus);
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index 26e2312006..0e4c7409e0 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -226,10 +226,9 @@ static void virtex_init(MachineState *machine)
memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
dinfo = drive_get(IF_PFLASH, 0, 0);
- pflash_cfi01_register(PFLASH_BASEADDR, NULL, "virtex.flash", FLASH_SIZE,
+ pflash_cfi01_register(PFLASH_BASEADDR, "virtex.flash", FLASH_SIZE,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- 64 * KiB, FLASH_SIZE >> 16,
- 1, 0x89, 0x18, 0x0000, 0x0, 1);
+ 64 * KiB, 1, 0x89, 0x18, 0x0000, 0x0, 1);
cpu_irq = (qemu_irq *) &env->irq_inputs[PPC40x_INPUT_INT];
dev = qdev_create(NULL, "xlnx.xps-intc");
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index e0ee3043a6..8c7fc1f31d 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -26,6 +26,9 @@ config SPIKE
config RISCV_VIRT
bool
+ imply PCI_DEVICES
+ imply TEST_DEVICES
+ select PCI
select HART
select SERIAL
select VIRTIO_MMIO
diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 89def1421f..da7239d94f 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -160,6 +160,11 @@ static const char *names[] = {
#define LSI_CCNTL1_DDAC 0x08
#define LSI_CCNTL1_ZMOD 0x80
+#define LSI_SBCL_ATN 0x08
+#define LSI_SBCL_BSY 0x20
+#define LSI_SBCL_ACK 0x40
+#define LSI_SBCL_REQ 0x80
+
/* Enable Response to Reselection */
#define LSI_SCID_RRE 0x60
@@ -189,6 +194,20 @@ typedef struct lsi_request {
QTAILQ_ENTRY(lsi_request) next;
} lsi_request;
+enum {
+ LSI_NOWAIT, /* SCRIPTS are running or stopped */
+ LSI_WAIT_RESELECT, /* Wait Reselect instruction has been issued */
+ LSI_DMA_SCRIPTS, /* processing DMA from lsi_execute_script */
+ LSI_DMA_IN_PROGRESS, /* DMA operation is in progress */
+};
+
+enum {
+ LSI_MSG_ACTION_COMMAND = 0,
+ LSI_MSG_ACTION_DISCONNECT = 1,
+ LSI_MSG_ACTION_DOUT = 2,
+ LSI_MSG_ACTION_DIN = 3,
+};
+
typedef struct {
/*< private >*/
PCIDevice parent_obj;
@@ -202,15 +221,9 @@ typedef struct {
int carry; /* ??? Should this be an a visible register somewhere? */
int status;
- /* Action to take at the end of a MSG IN phase.
- 0 = COMMAND, 1 = disconnect, 2 = DATA OUT, 3 = DATA IN. */
int msg_action;
int msg_len;
uint8_t msg[LSI_MAX_MSGIN_LEN];
- /* 0 if SCRIPTS are running or stopped.
- * 1 if a Wait Reselect instruction has been issued.
- * 2 if processing DMA from lsi_execute_script.
- * 3 if a DMA operation is in progress. */
int waiting;
SCSIBus bus;
int current_lun;
@@ -258,6 +271,7 @@ typedef struct {
uint8_t sdid;
uint8_t ssid;
uint8_t sfbr;
+ uint8_t sbcl;
uint8_t stest1;
uint8_t stest2;
uint8_t stest3;
@@ -283,8 +297,7 @@ typedef struct {
uint8_t sbr;
uint32_t adder;
- /* Script ram is stored as 32-bit words in host byteorder. */
- uint32_t script_ram[2048];
+ uint8_t script_ram[2048 * sizeof(uint32_t)];
} LSIState;
#define TYPE_LSI53C810 "lsi53c810"
@@ -293,6 +306,22 @@ typedef struct {
#define LSI53C895A(obj) \
OBJECT_CHECK(LSIState, (obj), TYPE_LSI53C895A)
+static const char *scsi_phases[] = {
+ "DOUT",
+ "DIN",
+ "CMD",
+ "STATUS",
+ "RSVOUT",
+ "RSVIN",
+ "MSGOUT",
+ "MSGIN"
+};
+
+static const char *scsi_phase_name(int phase)
+{
+ return scsi_phases[phase & PHASE_MASK];
+}
+
static inline int lsi_irq_on_rsl(LSIState *s)
{
return (s->sien0 & LSI_SIST0_RSL) && (s->scid & LSI_SCID_RRE);
@@ -315,9 +344,9 @@ static void lsi_soft_reset(LSIState *s)
trace_lsi_reset();
s->carry = 0;
- s->msg_action = 0;
+ s->msg_action = LSI_MSG_ACTION_COMMAND;
s->msg_len = 0;
- s->waiting = 0;
+ s->waiting = LSI_NOWAIT;
s->dsa = 0;
s->dnad = 0;
s->dbc = 0;
@@ -356,6 +385,7 @@ static void lsi_soft_reset(LSIState *s)
s->socl = 0;
s->sdid = 0;
s->ssid = 0;
+ s->sbcl = 0;
s->stest1 = 0;
s->stest2 = 0;
s->stest3 = 0;
@@ -530,6 +560,8 @@ static void lsi_script_dma_interrupt(LSIState *s, int stat)
static inline void lsi_set_phase(LSIState *s, int phase)
{
+ s->sbcl &= ~PHASE_MASK;
+ s->sbcl |= phase | LSI_SBCL_REQ;
s->sstat1 = (s->sstat1 & ~PHASE_MASK) | phase;
}
@@ -556,10 +588,10 @@ static void lsi_bad_phase(LSIState *s, int out, int new_phase)
static void lsi_resume_script(LSIState *s)
{
if (s->waiting != 2) {
- s->waiting = 0;
+ s->waiting = LSI_NOWAIT;
lsi_execute_script(s);
} else {
- s->waiting = 0;
+ s->waiting = LSI_NOWAIT;
}
}
@@ -567,6 +599,7 @@ static void lsi_disconnect(LSIState *s)
{
s->scntl1 &= ~LSI_SCNTL1_CON;
s->sstat1 &= ~PHASE_MASK;
+ s->sbcl = 0;
}
static void lsi_bad_selection(LSIState *s, uint32_t id)
@@ -674,7 +707,7 @@ static void lsi_reselect(LSIState *s, lsi_request *p)
trace_lsi_reselect(id);
s->scntl1 |= LSI_SCNTL1_CON;
lsi_set_phase(s, PHASE_MI);
- s->msg_action = p->out ? 2 : 3;
+ s->msg_action = p->out ? LSI_MSG_ACTION_DOUT : LSI_MSG_ACTION_DIN;
s->current->dma_len = p->pending;
lsi_add_msg_byte(s, 0x80);
if (s->current->tag & LSI_TAG_VALID) {
@@ -735,7 +768,7 @@ static int lsi_queue_req(LSIState *s, SCSIRequest *req, uint32_t len)
Since no interrupt stacking is implemented in the emulation, it
is also required that there are no pending interrupts waiting
for service from the device driver. */
- if (s->waiting == 1 ||
+ if (s->waiting == LSI_WAIT_RESELECT ||
(lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) &&
!(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP)))) {
/* Reselect device. */
@@ -780,7 +813,7 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t len)
int out;
assert(req->hba_private);
- if (s->waiting == 1 || req->hba_private != s->current ||
+ if (s->waiting == LSI_WAIT_RESELECT || req->hba_private != s->current ||
(lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) {
if (lsi_queue_req(s, req, len)) {
return;
@@ -794,7 +827,7 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t len)
s->current->dma_len = len;
s->command_complete = 1;
if (s->waiting) {
- if (s->waiting == 1 || s->dbc == 0) {
+ if (s->waiting == LSI_WAIT_RESELECT || s->dbc == 0) {
lsi_resume_script(s);
} else {
lsi_do_dma(s, out);
@@ -845,7 +878,7 @@ static void lsi_do_command(LSIState *s)
lsi_add_msg_byte(s, 4); /* DISCONNECT */
/* wait data */
lsi_set_phase(s, PHASE_MI);
- s->msg_action = 1;
+ s->msg_action = LSI_MSG_ACTION_DISCONNECT;
lsi_queue_command(s);
} else {
/* wait command complete */
@@ -866,7 +899,7 @@ static void lsi_do_status(LSIState *s)
s->sfbr = status;
pci_dma_write(PCI_DEVICE(s), s->dnad, &status, 1);
lsi_set_phase(s, PHASE_MI);
- s->msg_action = 1;
+ s->msg_action = LSI_MSG_ACTION_DISCONNECT;
lsi_add_msg_byte(s, 0); /* COMMAND COMPLETE */
}
@@ -889,16 +922,16 @@ static void lsi_do_msgin(LSIState *s)
/* ??? Check if ATN (not yet implemented) is asserted and maybe
switch to PHASE_MO. */
switch (s->msg_action) {
- case 0:
+ case LSI_MSG_ACTION_COMMAND:
lsi_set_phase(s, PHASE_CMD);
break;
- case 1:
+ case LSI_MSG_ACTION_DISCONNECT:
lsi_disconnect(s);
break;
- case 2:
+ case LSI_MSG_ACTION_DOUT:
lsi_set_phase(s, PHASE_DO);
break;
- case 3:
+ case LSI_MSG_ACTION_DIN:
lsi_set_phase(s, PHASE_DI);
break;
default:
@@ -1050,7 +1083,7 @@ bad:
qemu_log_mask(LOG_UNIMP, "Unimplemented message 0x%02x\n", msg);
lsi_set_phase(s, PHASE_MI);
lsi_add_msg_byte(s, 7); /* MESSAGE REJECT */
- s->msg_action = 0;
+ s->msg_action = LSI_MSG_ACTION_COMMAND;
}
#define LSI_BUF_SIZE 4096
@@ -1084,7 +1117,7 @@ static void lsi_wait_reselect(LSIState *s)
lsi_reselect(s, p);
}
if (s->current == NULL) {
- s->waiting = 1;
+ s->waiting = LSI_WAIT_RESELECT;
}
}
@@ -1184,8 +1217,9 @@ again:
s->ia = s->dsp - 12;
}
if ((s->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) {
- trace_lsi_execute_script_blockmove_badphase(s->sstat1 & PHASE_MASK,
- (insn >> 24) & 7);
+ trace_lsi_execute_script_blockmove_badphase(
+ scsi_phase_name(s->sstat1),
+ scsi_phase_name(insn >> 24));
lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
break;
}
@@ -1193,16 +1227,16 @@ again:
s->dnad64 = addr_high;
switch (s->sstat1 & 0x7) {
case PHASE_DO:
- s->waiting = 2;
+ s->waiting = LSI_DMA_SCRIPTS;
lsi_do_dma(s, 1);
if (s->waiting)
- s->waiting = 3;
+ s->waiting = LSI_DMA_IN_PROGRESS;
break;
case PHASE_DI:
- s->waiting = 2;
+ s->waiting = LSI_DMA_SCRIPTS;
lsi_do_dma(s, 0);
if (s->waiting)
- s->waiting = 3;
+ s->waiting = LSI_DMA_IN_PROGRESS;
break;
case PHASE_CMD:
lsi_do_command(s);
@@ -1217,8 +1251,8 @@ again:
lsi_do_msgin(s);
break;
default:
- qemu_log_mask(LOG_UNIMP, "lsi_scsi: Unimplemented phase %d\n",
- s->sstat1 & PHASE_MASK);
+ qemu_log_mask(LOG_UNIMP, "lsi_scsi: Unimplemented phase %s\n",
+ scsi_phase_name(s->sstat1));
}
s->dfifo = s->dbc & 0xff;
s->ctest5 = (s->ctest5 & 0xfc) | ((s->dbc >> 8) & 3);
@@ -1265,8 +1299,11 @@ again:
s->scntl1 |= LSI_SCNTL1_CON;
if (insn & (1 << 3)) {
s->socl |= LSI_SOCL_ATN;
+ s->sbcl |= LSI_SBCL_ATN;
}
+ s->sbcl |= LSI_SBCL_BSY;
lsi_set_phase(s, PHASE_MO);
+ s->waiting = LSI_NOWAIT;
break;
case 1: /* Disconnect */
trace_lsi_execute_script_io_disconnect();
@@ -1285,8 +1322,10 @@ again:
}
break;
case 2: /* Wait Reselect */
- if (!lsi_irq_on_rsl(s)) {
- lsi_wait_reselect(s);
+ if (s->istat0 & LSI_ISTAT0_SIGP) {
+ s->dsp = s->dnad;
+ } else if (!lsi_irq_on_rsl(s)) {
+ lsi_wait_reselect(s);
}
break;
case 3: /* Set */
@@ -1297,8 +1336,14 @@ again:
insn & (1 << 10) ? " CC" : "");
if (insn & (1 << 3)) {
s->socl |= LSI_SOCL_ATN;
+ s->sbcl |= LSI_SBCL_ATN;
lsi_set_phase(s, PHASE_MO);
}
+
+ if (insn & (1 << 6)) {
+ s->sbcl |= LSI_SBCL_ACK;
+ }
+
if (insn & (1 << 9)) {
qemu_log_mask(LOG_UNIMP,
"lsi_scsi: Target mode not implemented\n");
@@ -1314,7 +1359,13 @@ again:
insn & (1 << 10) ? " CC" : "");
if (insn & (1 << 3)) {
s->socl &= ~LSI_SOCL_ATN;
+ s->sbcl &= ~LSI_SBCL_ATN;
+ }
+
+ if (insn & (1 << 6)) {
+ s->sbcl &= ~LSI_SBCL_ACK;
}
+
if (insn & (1 << 10))
s->carry = 0;
break;
@@ -1429,10 +1480,8 @@ again:
cond = s->carry != 0;
}
if (cond == jmp && (insn & (1 << 17))) {
- trace_lsi_execute_script_tc_compp(
- (s->sstat1 & PHASE_MASK),
- jmp ? '=' : '!',
- ((insn >> 24) & 7));
+ trace_lsi_execute_script_tc_compp(scsi_phase_name(s->sstat1),
+ jmp ? '=' : '!', scsi_phase_name(insn >> 24));
cond = (s->sstat1 & PHASE_MASK) == ((insn >> 24) & 7);
}
if (cond == jmp && (insn & (1 << 18))) {
@@ -1519,7 +1568,7 @@ again:
}
}
}
- if (insn_processed > 10000 && !s->waiting) {
+ if (insn_processed > 10000 && s->waiting == LSI_NOWAIT) {
/* Some windows drivers make the device spin waiting for a memory
location to change. If we have been executed a lot of code then
assume this is the case and force an unexpected device disconnect.
@@ -1531,7 +1580,7 @@ again:
}
lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
lsi_disconnect(s);
- } else if (s->istat1 & LSI_ISTAT1_SRUN && !s->waiting) {
+ } else if (s->istat1 & LSI_ISTAT1_SRUN && s->waiting == LSI_NOWAIT) {
if (s->dcntl & LSI_DCNTL_SSM) {
lsi_script_dma_interrupt(s, LSI_DSTAT_SSI);
} else {
@@ -1591,9 +1640,7 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset)
ret = s->ssid;
break;
case 0xb: /* SBCL */
- /* ??? This is not correct. However it's (hopefully) only
- used for diagnostics, so should be ok. */
- ret = 0;
+ ret = s->sbcl;
break;
case 0xc: /* DSTAT */
ret = s->dstat | LSI_DSTAT_DFE;
@@ -1641,7 +1688,7 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset)
break;
CASE_GET_REG32(temp, 0x1c)
case 0x20: /* DFIFO */
- ret = 0;
+ ret = s->dfifo;
break;
case 0x21: /* CTEST4 */
ret = s->ctest4;
@@ -1864,9 +1911,9 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
s->istat0 &= ~LSI_ISTAT0_INTF;
lsi_update_irq(s);
}
- if (s->waiting == 1 && val & LSI_ISTAT0_SIGP) {
+ if (s->waiting == LSI_WAIT_RESELECT && val & LSI_ISTAT0_SIGP) {
trace_lsi_awoken();
- s->waiting = 0;
+ s->waiting = LSI_NOWAIT;
s->dsp = s->dnad;
lsi_execute_script(s);
}
@@ -2037,14 +2084,13 @@ static uint64_t lsi_mmio_read(void *opaque, hwaddr addr,
unsigned size)
{
LSIState *s = opaque;
-
return lsi_reg_readb(s, addr & 0xff);
}
static const MemoryRegionOps lsi_mmio_ops = {
.read = lsi_mmio_read,
.write = lsi_mmio_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
+ .endianness = DEVICE_LITTLE_ENDIAN,
.impl = {
.min_access_size = 1,
.max_access_size = 1,
@@ -2055,35 +2101,20 @@ static void lsi_ram_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
LSIState *s = opaque;
- uint32_t newval;
- uint32_t mask;
- int shift;
-
- newval = s->script_ram[addr >> 2];
- shift = (addr & 3) * 8;
- mask = ((uint64_t)1 << (size * 8)) - 1;
- newval &= ~(mask << shift);
- newval |= val << shift;
- s->script_ram[addr >> 2] = newval;
+ stn_le_p(s->script_ram + addr, size, val);
}
static uint64_t lsi_ram_read(void *opaque, hwaddr addr,
unsigned size)
{
LSIState *s = opaque;
- uint32_t val;
- uint32_t mask;
-
- val = s->script_ram[addr >> 2];
- mask = ((uint64_t)1 << (size * 8)) - 1;
- val >>= (addr & 3) * 8;
- return val & mask;
+ return ldn_le_p(s->script_ram + addr, size);
}
static const MemoryRegionOps lsi_ram_ops = {
.read = lsi_ram_read,
.write = lsi_ram_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
+ .endianness = DEVICE_LITTLE_ENDIAN,
};
static uint64_t lsi_io_read(void *opaque, hwaddr addr,
@@ -2103,7 +2134,7 @@ static void lsi_io_write(void *opaque, hwaddr addr,
static const MemoryRegionOps lsi_io_ops = {
.read = lsi_io_read,
.write = lsi_io_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
+ .endianness = DEVICE_LITTLE_ENDIAN,
.impl = {
.min_access_size = 1,
.max_access_size = 1,
@@ -2143,7 +2174,7 @@ static int lsi_post_load(void *opaque, int version_id)
static const VMStateDescription vmstate_lsi_scsi = {
.name = "lsiscsi",
- .version_id = 0,
+ .version_id = 1,
.minimum_version_id = 0,
.pre_save = lsi_pre_save,
.post_load = lsi_post_load,
@@ -2202,6 +2233,7 @@ static const VMStateDescription vmstate_lsi_scsi = {
VMSTATE_UINT8(stime0, LSIState),
VMSTATE_UINT8(respid0, LSIState),
VMSTATE_UINT8(respid1, LSIState),
+ VMSTATE_UINT8_V(sbcl, LSIState, 1),
VMSTATE_UINT32(mmrs, LSIState),
VMSTATE_UINT32(mmws, LSIState),
VMSTATE_UINT32(sfs, LSIState),
@@ -2219,7 +2251,7 @@ static const VMStateDescription vmstate_lsi_scsi = {
VMSTATE_BUFFER_UNSAFE(scratch, LSIState, 0, 18 * sizeof(uint32_t)),
VMSTATE_UINT8(sbr, LSIState),
- VMSTATE_BUFFER_UNSAFE(script_ram, LSIState, 0, 2048 * sizeof(uint32_t)),
+ VMSTATE_BUFFER_UNSAFE(script_ram, LSIState, 0, 8192),
VMSTATE_END_OF_LIST()
}
};
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index d4e83aef0e..e7e865ab3b 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -296,22 +296,15 @@ static void scsi_dma_complete(void *opaque, int ret)
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
}
-static void scsi_read_complete(void * opaque, int ret)
+static void scsi_read_complete_noio(SCSIDiskReq *r, int ret)
{
- SCSIDiskReq *r = (SCSIDiskReq *)opaque;
- SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
- int n;
+ uint32_t n;
- assert(r->req.aiocb != NULL);
- r->req.aiocb = NULL;
- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
- if (scsi_disk_req_check_error(r, ret, true)) {
+ assert(r->req.aiocb == NULL);
+ if (scsi_disk_req_check_error(r, ret, false)) {
goto done;
}
- block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
- trace_scsi_disk_read_complete(r->req.tag, r->qiov.size);
-
n = r->qiov.size / 512;
r->sector += n;
r->sector_count -= n;
@@ -319,6 +312,24 @@ static void scsi_read_complete(void * opaque, int ret)
done:
scsi_req_unref(&r->req);
+}
+
+static void scsi_read_complete(void *opaque, int ret)
+{
+ SCSIDiskReq *r = (SCSIDiskReq *)opaque;
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
+
+ assert(r->req.aiocb != NULL);
+ r->req.aiocb = NULL;
+
+ aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
+ if (ret < 0) {
+ block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
+ } else {
+ block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
+ trace_scsi_disk_read_complete(r->req.tag, r->qiov.size);
+ }
+ scsi_read_complete_noio(r, ret);
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
}
@@ -395,12 +406,12 @@ static void scsi_read_data(SCSIRequest *req)
scsi_req_ref(&r->req);
if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
trace_scsi_disk_read_data_invalid();
- scsi_read_complete(r, -EINVAL);
+ scsi_read_complete_noio(r, -EINVAL);
return;
}
if (!blk_is_available(req->dev->conf.blk)) {
- scsi_read_complete(r, -ENOMEDIUM);
+ scsi_read_complete_noio(r, -ENOMEDIUM);
return;
}
diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
index a9e49c7cb5..26dfc0340f 100644
--- a/hw/scsi/spapr_vscsi.c
+++ b/hw/scsi/spapr_vscsi.c
@@ -91,7 +91,7 @@ typedef struct vscsi_req {
OBJECT_CHECK(VSCSIState, (obj), TYPE_VIO_SPAPR_VSCSI_DEVICE)
typedef struct {
- VIOsPAPRDevice vdev;
+ SpaprVioDevice vdev;
SCSIBus bus;
vscsi_req reqs[VSCSI_REQ_LIMIT];
} VSCSIState;
@@ -1115,7 +1115,7 @@ static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq)
}
-static int vscsi_do_crq(struct VIOsPAPRDevice *dev, uint8_t *crq_data)
+static int vscsi_do_crq(struct SpaprVioDevice *dev, uint8_t *crq_data)
{
VSCSIState *s = VIO_SPAPR_VSCSI_DEVICE(dev);
vscsi_crq crq;
@@ -1187,7 +1187,7 @@ static const struct SCSIBusInfo vscsi_scsi_info = {
.load_request = vscsi_load_request,
};
-static void spapr_vscsi_reset(VIOsPAPRDevice *dev)
+static void spapr_vscsi_reset(SpaprVioDevice *dev)
{
VSCSIState *s = VIO_SPAPR_VSCSI_DEVICE(dev);
int i;
@@ -1198,7 +1198,7 @@ static void spapr_vscsi_reset(VIOsPAPRDevice *dev)
}
}
-static void spapr_vscsi_realize(VIOsPAPRDevice *dev, Error **errp)
+static void spapr_vscsi_realize(SpaprVioDevice *dev, Error **errp)
{
VSCSIState *s = VIO_SPAPR_VSCSI_DEVICE(dev);
@@ -1208,7 +1208,7 @@ static void spapr_vscsi_realize(VIOsPAPRDevice *dev, Error **errp)
&vscsi_scsi_info, NULL);
}
-void spapr_vscsi_create(VIOsPAPRBus *bus)
+void spapr_vscsi_create(SpaprVioBus *bus)
{
DeviceState *dev;
@@ -1218,7 +1218,7 @@ void spapr_vscsi_create(VIOsPAPRBus *bus)
scsi_bus_legacy_handle_cmdline(&VIO_SPAPR_VSCSI_DEVICE(dev)->bus);
}
-static int spapr_vscsi_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
+static int spapr_vscsi_devnode(SpaprVioDevice *dev, void *fdt, int node_off)
{
int ret;
@@ -1256,7 +1256,7 @@ static const VMStateDescription vmstate_spapr_vscsi = {
static void spapr_vscsi_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
+ SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
k->realize = spapr_vscsi_realize;
k->reset = spapr_vscsi_reset;
diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events
index 29aaa752d1..09f3fc3086 100644
--- a/hw/scsi/trace-events
+++ b/hw/scsi/trace-events
@@ -268,7 +268,7 @@ lsi_memcpy(uint32_t dest, uint32_t src, int count) "memcpy dest 0x%"PRIx32" src
lsi_wait_reselect(void) "Wait Reselect"
lsi_execute_script(uint32_t dsp, uint32_t insn, uint32_t addr) "SCRIPTS dsp=0x%"PRIx32" opcode 0x%"PRIx32" arg 0x%"PRIx32
lsi_execute_script_blockmove_delayed(void) "Delayed select timeout"
-lsi_execute_script_blockmove_badphase(uint8_t phase, uint8_t expected) "Wrong phase got %d expected %d"
+lsi_execute_script_blockmove_badphase(const char *phase, const char *expected) "Wrong phase got %s expected %s"
lsi_execute_script_io_alreadyreselected(void) "Already reselected, jumping to alternative address"
lsi_execute_script_io_selected(uint8_t id, const char *atn) "Selected target %d%s"
lsi_execute_script_io_disconnect(void) "Wait Disconnect"
@@ -278,8 +278,8 @@ lsi_execute_script_io_opcode(const char *opcode, int reg, const char *opname, ui
lsi_execute_script_tc_nop(void) "NOP"
lsi_execute_script_tc_delayedselect_timeout(void) "Delayed select timeout"
lsi_execute_script_tc_compc(int result) "Compare carry %d"
-lsi_execute_script_tc_compp(uint8_t phase, int op, uint8_t insn_phase) "Compare phase %d %c= %d"
-lsi_execute_script_tc_compd(uint32_t sfbr, uint8_t mask, int op, int result) "Compare data 0x%"PRIx32" & 0x%x %c= 0x%x"
+lsi_execute_script_tc_compp(const char *phase, char op, const char *insn_phase) "Compare phase %s %c= %s"
+lsi_execute_script_tc_compd(uint32_t sfbr, uint8_t mask, char op, int result) "Compare data 0x%"PRIx32" & 0x%x %c= 0x%x"
lsi_execute_script_tc_jump(uint32_t addr) "Jump to 0x%"PRIx32
lsi_execute_script_tc_call(uint32_t addr) "Call 0x%"PRIx32
lsi_execute_script_tc_return(uint32_t addr) "Return to 0x%"PRIx32
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index ce99d288b0..839f120256 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -262,7 +262,13 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
/* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE". */
req->resp.tmf.response = VIRTIO_SCSI_S_OK;
- virtio_tswap32s(VIRTIO_DEVICE(s), &req->req.tmf.subtype);
+ /*
+ * req->req.tmf has the QEMU_PACKED attribute. Don't use virtio_tswap32s()
+ * to avoid compiler errors.
+ */
+ req->req.tmf.subtype =
+ virtio_tswap32(VIRTIO_DEVICE(s), req->req.tmf.subtype);
+
switch (req->req.tmf.subtype) {
case VIRTIO_SCSI_T_TMF_ABORT_TASK:
case VIRTIO_SCSI_T_TMF_QUERY_TASK:
diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
index 28ed6be05b..0bcb769c85 100644
--- a/hw/sh4/r2d.c
+++ b/hw/sh4/r2d.c
@@ -43,7 +43,7 @@
#include "exec/address-spaces.h"
#define FLASH_BASE 0x00000000
-#define FLASH_SIZE 0x02000000
+#define FLASH_SIZE (16 * MiB)
#define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */
#define SDRAM_SIZE 0x04000000
@@ -287,12 +287,19 @@ static void r2d_init(MachineState *machine)
sysbus_mmio_map(busdev, 1, 0x1400080c);
mmio_ide_init_drives(dev, dinfo, NULL);
- /* onboard flash memory */
+ /*
+ * Onboard flash memory
+ * According to the old board user document in Japanese (under
+ * NDA) what is referred to as FROM (Area0) is connected via a
+ * 32-bit bus and CS0 to CN8. The docs mention a Cypress
+ * S29PL127J60TFI130 chipsset. Per the 'S29PL-J 002-00615
+ * Rev. *E' datasheet, it is a 128Mbit NOR parallel flash
+ * addressable in words of 16bit.
+ */
dinfo = drive_get(IF_PFLASH, 0, 0);
- pflash_cfi02_register(0x0, NULL, "r2d.flash", FLASH_SIZE,
+ pflash_cfi02_register(0x0, "r2d.flash", FLASH_SIZE,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- 16 * KiB, FLASH_SIZE >> 16,
- 1, 4, 0x0000, 0x0000, 0x0000, 0x0000,
+ 64 * KiB, 1, 2, 0x0001, 0x227e, 0x2220, 0x2200,
0x555, 0x2aa, 0);
/* NIC: rtl8139 on-board, and 2 slots. */
diff --git a/hw/vfio/Kconfig b/hw/vfio/Kconfig
index ebda9fdf22..34da2a3cfd 100644
--- a/hw/vfio/Kconfig
+++ b/hw/vfio/Kconfig
@@ -4,8 +4,9 @@ config VFIO
config VFIO_PCI
bool
+ default y
select VFIO
- depends on LINUX
+ depends on LINUX && PCI
config VFIO_CCW
bool
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index df2b4721bf..4374cc6176 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -729,7 +729,7 @@ static void vfio_listener_release(VFIOContainer *container)
}
}
-static struct vfio_info_cap_header *
+struct vfio_info_cap_header *
vfio_get_region_info_cap(struct vfio_region_info *info, uint16_t id)
{
struct vfio_info_cap_header *hdr;
diff --git a/hw/vfio/display.c b/hw/vfio/display.c
index dead30e626..a3d9c8f5be 100644
--- a/hw/vfio/display.c
+++ b/hw/vfio/display.c
@@ -15,15 +15,181 @@
#include <sys/ioctl.h>
#include "sysemu/sysemu.h"
+#include "hw/display/edid.h"
#include "ui/console.h"
#include "qapi/error.h"
#include "pci.h"
+#include "trace.h"
#ifndef DRM_PLANE_TYPE_PRIMARY
# define DRM_PLANE_TYPE_PRIMARY 1
# define DRM_PLANE_TYPE_CURSOR 2
#endif
+#define pread_field(_fd, _reg, _ptr, _fld) \
+ (sizeof(_ptr->_fld) != \
+ pread(_fd, &(_ptr->_fld), sizeof(_ptr->_fld), \
+ _reg->offset + offsetof(typeof(*_ptr), _fld)))
+
+#define pwrite_field(_fd, _reg, _ptr, _fld) \
+ (sizeof(_ptr->_fld) != \
+ pwrite(_fd, &(_ptr->_fld), sizeof(_ptr->_fld), \
+ _reg->offset + offsetof(typeof(*_ptr), _fld)))
+
+
+static void vfio_display_edid_link_up(void *opaque)
+{
+ VFIOPCIDevice *vdev = opaque;
+ VFIODisplay *dpy = vdev->dpy;
+ int fd = vdev->vbasedev.fd;
+
+ dpy->edid_regs->link_state = VFIO_DEVICE_GFX_LINK_STATE_UP;
+ if (pwrite_field(fd, dpy->edid_info, dpy->edid_regs, link_state)) {
+ goto err;
+ }
+ trace_vfio_display_edid_link_up();
+ return;
+
+err:
+ trace_vfio_display_edid_write_error();
+}
+
+static void vfio_display_edid_update(VFIOPCIDevice *vdev, bool enabled,
+ int prefx, int prefy)
+{
+ VFIODisplay *dpy = vdev->dpy;
+ int fd = vdev->vbasedev.fd;
+ qemu_edid_info edid = {
+ .maxx = dpy->edid_regs->max_xres,
+ .maxy = dpy->edid_regs->max_yres,
+ .prefx = prefx ?: vdev->display_xres,
+ .prefy = prefy ?: vdev->display_yres,
+ };
+
+ timer_del(dpy->edid_link_timer);
+ dpy->edid_regs->link_state = VFIO_DEVICE_GFX_LINK_STATE_DOWN;
+ if (pwrite_field(fd, dpy->edid_info, dpy->edid_regs, link_state)) {
+ goto err;
+ }
+ trace_vfio_display_edid_link_down();
+
+ if (!enabled) {
+ return;
+ }
+
+ if (edid.maxx && edid.prefx > edid.maxx) {
+ edid.prefx = edid.maxx;
+ }
+ if (edid.maxy && edid.prefy > edid.maxy) {
+ edid.prefy = edid.maxy;
+ }
+ qemu_edid_generate(dpy->edid_blob,
+ dpy->edid_regs->edid_max_size,
+ &edid);
+ trace_vfio_display_edid_update(edid.prefx, edid.prefy);
+
+ dpy->edid_regs->edid_size = qemu_edid_size(dpy->edid_blob);
+ if (pwrite_field(fd, dpy->edid_info, dpy->edid_regs, edid_size)) {
+ goto err;
+ }
+ if (pwrite(fd, dpy->edid_blob, dpy->edid_regs->edid_size,
+ dpy->edid_info->offset + dpy->edid_regs->edid_offset)
+ != dpy->edid_regs->edid_size) {
+ goto err;
+ }
+
+ timer_mod(dpy->edid_link_timer,
+ qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 100);
+ return;
+
+err:
+ trace_vfio_display_edid_write_error();
+ return;
+}
+
+static int vfio_display_edid_ui_info(void *opaque, uint32_t idx,
+ QemuUIInfo *info)
+{
+ VFIOPCIDevice *vdev = opaque;
+ VFIODisplay *dpy = vdev->dpy;
+
+ if (!dpy->edid_regs) {
+ return 0;
+ }
+
+ if (info->width && info->height) {
+ vfio_display_edid_update(vdev, true, info->width, info->height);
+ } else {
+ vfio_display_edid_update(vdev, false, 0, 0);
+ }
+
+ return 0;
+}
+
+static void vfio_display_edid_init(VFIOPCIDevice *vdev)
+{
+ VFIODisplay *dpy = vdev->dpy;
+ int fd = vdev->vbasedev.fd;
+ int ret;
+
+ ret = vfio_get_dev_region_info(&vdev->vbasedev,
+ VFIO_REGION_TYPE_GFX,
+ VFIO_REGION_SUBTYPE_GFX_EDID,
+ &dpy->edid_info);
+ if (ret) {
+ return;
+ }
+
+ trace_vfio_display_edid_available();
+ dpy->edid_regs = g_new0(struct vfio_region_gfx_edid, 1);
+ if (pread_field(fd, dpy->edid_info, dpy->edid_regs, edid_offset)) {
+ goto err;
+ }
+ if (pread_field(fd, dpy->edid_info, dpy->edid_regs, edid_max_size)) {
+ goto err;
+ }
+ if (pread_field(fd, dpy->edid_info, dpy->edid_regs, max_xres)) {
+ goto err;
+ }
+ if (pread_field(fd, dpy->edid_info, dpy->edid_regs, max_yres)) {
+ goto err;
+ }
+
+ dpy->edid_blob = g_malloc0(dpy->edid_regs->edid_max_size);
+
+ /* if xres + yres properties are unset use the maximum resolution */
+ if (!vdev->display_xres) {
+ vdev->display_xres = dpy->edid_regs->max_xres;
+ }
+ if (!vdev->display_yres) {
+ vdev->display_yres = dpy->edid_regs->max_yres;
+ }
+
+ dpy->edid_link_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
+ vfio_display_edid_link_up, vdev);
+
+ vfio_display_edid_update(vdev, true, 0, 0);
+ return;
+
+err:
+ trace_vfio_display_edid_write_error();
+ g_free(dpy->edid_regs);
+ dpy->edid_regs = NULL;
+ return;
+}
+
+static void vfio_display_edid_exit(VFIODisplay *dpy)
+{
+ if (!dpy->edid_regs) {
+ return;
+ }
+
+ g_free(dpy->edid_regs);
+ g_free(dpy->edid_blob);
+ timer_del(dpy->edid_link_timer);
+ timer_free(dpy->edid_link_timer);
+}
+
static void vfio_display_update_cursor(VFIODMABuf *dmabuf,
struct vfio_device_gfx_plane_info *plane)
{
@@ -171,6 +337,7 @@ static void vfio_display_dmabuf_update(void *opaque)
static const GraphicHwOps vfio_display_dmabuf_ops = {
.gfx_update = vfio_display_dmabuf_update,
+ .ui_info = vfio_display_edid_ui_info,
};
static int vfio_display_dmabuf_init(VFIOPCIDevice *vdev, Error **errp)
@@ -187,6 +354,7 @@ static int vfio_display_dmabuf_init(VFIOPCIDevice *vdev, Error **errp)
if (vdev->enable_ramfb) {
vdev->dpy->ramfb = ramfb_setup(errp);
}
+ vfio_display_edid_init(vdev);
return 0;
}
@@ -366,5 +534,6 @@ void vfio_display_finalize(VFIOPCIDevice *vdev)
graphic_console_close(vdev->dpy->con);
vfio_display_dmabuf_exit(vdev->dpy);
vfio_display_region_exit(vdev->dpy);
+ vfio_display_edid_exit(vdev->dpy);
g_free(vdev->dpy);
}
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index dd12f36391..504019c458 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3068,6 +3068,16 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
error_setg(errp, "ramfb=on requires display=on");
goto out_teardown;
}
+ if (vdev->display_xres || vdev->display_yres) {
+ if (vdev->dpy == NULL) {
+ error_setg(errp, "xres and yres properties require display=on");
+ goto out_teardown;
+ }
+ if (vdev->dpy->edid_regs == NULL) {
+ error_setg(errp, "xres and yres properties need edid support");
+ goto out_teardown;
+ }
+ }
vfio_register_err_notifier(vdev);
vfio_register_req_notifier(vdev);
@@ -3182,6 +3192,8 @@ static Property vfio_pci_dev_properties[] = {
DEFINE_PROP_STRING("sysfsdev", VFIOPCIDevice, vbasedev.sysfsdev),
DEFINE_PROP_ON_OFF_AUTO("display", VFIOPCIDevice,
display, ON_OFF_AUTO_OFF),
+ DEFINE_PROP_UINT32("xres", VFIOPCIDevice, display_xres, 0),
+ DEFINE_PROP_UINT32("yres", VFIOPCIDevice, display_yres, 0),
DEFINE_PROP_UINT32("x-intx-mmap-timeout-ms", VFIOPCIDevice,
intx.mmap_timeout, 1100),
DEFINE_PROP_BIT("x-vga", VFIOPCIDevice, features,
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index b1ae4c0754..c11c3f1670 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -149,6 +149,8 @@ typedef struct VFIOPCIDevice {
#define VFIO_FEATURE_ENABLE_IGD_OPREGION \
(1 << VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT)
OnOffAuto display;
+ uint32_t display_xres;
+ uint32_t display_yres;
int32_t bootindex;
uint32_t igd_gms;
OffAutoPCIBAR msix_relo;
diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c
index becf71a3fc..57fe758e54 100644
--- a/hw/vfio/spapr.c
+++ b/hw/vfio/spapr.c
@@ -143,19 +143,19 @@ int vfio_spapr_create_window(VFIOContainer *container,
MemoryRegionSection *section,
hwaddr *pgsize)
{
- int ret;
+ int ret = 0;
IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr);
uint64_t pagesize = memory_region_iommu_get_min_page_size(iommu_mr);
- unsigned entries, pages;
+ unsigned entries, bits_total, bits_per_level, max_levels;
struct vfio_iommu_spapr_tce_create create = { .argsz = sizeof(create) };
- long systempagesize = qemu_getrampagesize();
+ long rampagesize = qemu_getrampagesize();
/*
* The host might not support the guest supported IOMMU page size,
* so we will use smaller physical IOMMU pages to back them.
*/
- if (pagesize > systempagesize) {
- pagesize = systempagesize;
+ if (pagesize > rampagesize) {
+ pagesize = rampagesize;
}
pagesize = 1ULL << (63 - clz64(container->pgsizes &
(pagesize | (pagesize - 1))));
@@ -176,16 +176,38 @@ int vfio_spapr_create_window(VFIOContainer *container,
create.window_size = int128_get64(section->size);
create.page_shift = ctz64(pagesize);
/*
- * SPAPR host supports multilevel TCE tables, there is some
- * heuristic to decide how many levels we want for our table:
- * 0..64 = 1; 65..4096 = 2; 4097..262144 = 3; 262145.. = 4
+ * SPAPR host supports multilevel TCE tables. We try to guess optimal
+ * levels number and if this fails (for example due to the host memory
+ * fragmentation), we increase levels. The DMA address structure is:
+ * rrrrrrrr rxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx iiiiiiii
+ * where:
+ * r = reserved (bits >= 55 are reserved in the existing hardware)
+ * i = IOMMU page offset (64K in this example)
+ * x = bits to index a TCE which can be split to equal chunks to index
+ * within the level.
+ * The aim is to split "x" to smaller possible number of levels.
*/
entries = create.window_size >> create.page_shift;
- pages = MAX((entries * sizeof(uint64_t)) / getpagesize(), 1);
- pages = MAX(pow2ceil(pages), 1); /* Round up */
- create.levels = ctz64(pages) / 6 + 1;
-
- ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_TCE_CREATE, &create);
+ /* bits_total is number of "x" needed */
+ bits_total = ctz64(entries * sizeof(uint64_t));
+ /*
+ * bits_per_level is a safe guess of how much we can allocate per level:
+ * 8 is the current minimum for CONFIG_FORCE_MAX_ZONEORDER and MAX_ORDER
+ * is usually bigger than that.
+ * Below we look at getpagesize() as TCEs are allocated from system pages.
+ */
+ bits_per_level = ctz64(getpagesize()) + 8;
+ create.levels = bits_total / bits_per_level;
+ if (bits_total % bits_per_level) {
+ ++create.levels;
+ }
+ max_levels = (64 - create.page_shift) / ctz64(getpagesize());
+ for ( ; create.levels <= max_levels; ++create.levels) {
+ ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_TCE_CREATE, &create);
+ if (!ret) {
+ break;
+ }
+ }
if (ret) {
error_report("Failed to create a window, ret = %d (%m)", ret);
return -errno;
@@ -200,6 +222,7 @@ int vfio_spapr_create_window(VFIOContainer *container,
return -EINVAL;
}
trace_vfio_spapr_create_window(create.page_shift,
+ create.levels,
create.window_size,
create.start_addr);
*pgsize = pagesize;
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index ed2f333ad7..22019728e0 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -129,6 +129,13 @@ vfio_prereg_listener_region_add_skip(uint64_t start, uint64_t end) "0x%"PRIx64"
vfio_prereg_listener_region_del_skip(uint64_t start, uint64_t end) "0x%"PRIx64" - 0x%"PRIx64
vfio_prereg_register(uint64_t va, uint64_t size, int ret) "va=0x%"PRIx64" size=0x%"PRIx64" ret=%d"
vfio_prereg_unregister(uint64_t va, uint64_t size, int ret) "va=0x%"PRIx64" size=0x%"PRIx64" ret=%d"
-vfio_spapr_create_window(int ps, uint64_t ws, uint64_t off) "pageshift=0x%x winsize=0x%"PRIx64" offset=0x%"PRIx64
+vfio_spapr_create_window(int ps, unsigned int levels, uint64_t ws, uint64_t off) "pageshift=0x%x levels=%u winsize=0x%"PRIx64" offset=0x%"PRIx64
vfio_spapr_remove_window(uint64_t off) "offset=0x%"PRIx64
vfio_spapr_group_attach(int groupfd, int tablefd) "Attached groupfd %d to liobn fd %d"
+
+# hw/vfio/display.c
+vfio_display_edid_available(void) ""
+vfio_display_edid_link_up(void) ""
+vfio_display_edid_link_down(void) ""
+vfio_display_edid_update(uint32_t prefx, uint32_t prefy) "%ux%u"
+vfio_display_edid_write_error(void) ""
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index e978bfe760..cb44e19b67 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1935,6 +1935,7 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t)
.parent = t->parent ? t->parent : TYPE_VIRTIO_PCI,
.instance_size = t->instance_size,
.instance_init = t->instance_init,
+ .class_size = t->class_size,
.class_init = virtio_pci_base_class_init,
.class_data = (void *)t,
.abstract = true,
diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index bd223a6e3b..18581854ca 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -230,6 +230,7 @@ typedef struct VirtioPCIDeviceTypeInfo {
/* Same as TypeInfo fields: */
size_t instance_size;
+ size_t class_size;
void (*instance_init)(Object *obj);
void (*class_init)(ObjectClass *klass, void *data);
} VirtioPCIDeviceTypeInfo;
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index ab3e52b415..e05ef75a75 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -162,12 +162,12 @@ static void xtfpga_net_init(MemoryRegion *address_space,
memory_region_add_subregion(address_space, buffers, ram);
}
-static pflash_t *xtfpga_flash_init(MemoryRegion *address_space,
- const XtfpgaBoardDesc *board,
- DriveInfo *dinfo, int be)
+static PFlashCFI01 *xtfpga_flash_init(MemoryRegion *address_space,
+ const XtfpgaBoardDesc *board,
+ DriveInfo *dinfo, int be)
{
SysBusDevice *s;
- DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
+ DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo),
&error_abort);
@@ -181,7 +181,7 @@ static pflash_t *xtfpga_flash_init(MemoryRegion *address_space,
s = SYS_BUS_DEVICE(dev);
memory_region_add_subregion(address_space, board->flash->base,
sysbus_mmio_get_region(s, 0));
- return OBJECT_CHECK(pflash_t, (dev), "cfi.pflash01");
+ return PFLASH_CFI01(dev);
}
static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
@@ -229,7 +229,7 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine)
XtensaMxPic *mx_pic = NULL;
qemu_irq *extints;
DriveInfo *dinfo;
- pflash_t *flash = NULL;
+ PFlashCFI01 *flash = NULL;
QemuOpts *machine_opts = qemu_get_machine_opts();
const char *kernel_filename = qemu_opt_get(machine_opts, "kernel");
const char *kernel_cmdline = qemu_opt_get(machine_opts, "append");
diff --git a/include/hw/block/flash.h b/include/hw/block/flash.h
index 67c3aa329e..a0f488732a 100644
--- a/include/hw/block/flash.h
+++ b/include/hw/block/flash.h
@@ -5,32 +5,46 @@
#include "exec/memory.h"
-#define TYPE_CFI_PFLASH01 "cfi.pflash01"
-#define TYPE_CFI_PFLASH02 "cfi.pflash02"
+/* pflash_cfi01.c */
-typedef struct pflash_t pflash_t;
+#define TYPE_PFLASH_CFI01 "cfi.pflash01"
+#define PFLASH_CFI01(obj) \
+ OBJECT_CHECK(PFlashCFI01, (obj), TYPE_PFLASH_CFI01)
-/* pflash_cfi01.c */
-pflash_t *pflash_cfi01_register(hwaddr base,
- DeviceState *qdev, const char *name,
- hwaddr size,
- BlockBackend *blk,
- uint32_t sector_len, int nb_blocs, int width,
- uint16_t id0, uint16_t id1,
- uint16_t id2, uint16_t id3, int be);
+typedef struct PFlashCFI01 PFlashCFI01;
+
+PFlashCFI01 *pflash_cfi01_register(hwaddr base,
+ const char *name,
+ hwaddr size,
+ BlockBackend *blk,
+ uint32_t sector_len,
+ int width,
+ uint16_t id0, uint16_t id1,
+ uint16_t id2, uint16_t id3,
+ int be);
+BlockBackend *pflash_cfi01_get_blk(PFlashCFI01 *fl);
+MemoryRegion *pflash_cfi01_get_memory(PFlashCFI01 *fl);
/* pflash_cfi02.c */
-pflash_t *pflash_cfi02_register(hwaddr base,
- DeviceState *qdev, const char *name,
- hwaddr size,
- BlockBackend *blk, uint32_t sector_len,
- int nb_blocs, int nb_mappings, int width,
- uint16_t id0, uint16_t id1,
- uint16_t id2, uint16_t id3,
- uint16_t unlock_addr0, uint16_t unlock_addr1,
- int be);
-
-MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl);
+
+#define TYPE_PFLASH_CFI02 "cfi.pflash02"
+#define PFLASH_CFI02(obj) \
+ OBJECT_CHECK(PFlashCFI02, (obj), TYPE_PFLASH_CFI02)
+
+typedef struct PFlashCFI02 PFlashCFI02;
+
+PFlashCFI02 *pflash_cfi02_register(hwaddr base,
+ const char *name,
+ hwaddr size,
+ BlockBackend *blk,
+ uint32_t sector_len,
+ int nb_mappings,
+ int width,
+ uint16_t id0, uint16_t id1,
+ uint16_t id2, uint16_t id3,
+ uint16_t unlock_addr0,
+ uint16_t unlock_addr1,
+ int be);
/* nand.c */
DeviceState *nand_init(BlockBackend *blk, int manf_id, int chip_id);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 263a6343ff..ca65ef18af 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -6,6 +6,7 @@
#include "hw/boards.h"
#include "hw/isa/isa.h"
#include "hw/block/fdc.h"
+#include "hw/block/flash.h"
#include "net/net.h"
#include "hw/i386/ioapic.h"
@@ -39,6 +40,7 @@ struct PCMachineState {
PCIBus *bus;
FWCfgState *fw_cfg;
qemu_irq *gsi;
+ PFlashCFI01 *flash[2];
/* Configuration options: */
uint64_t max_ram_below_4g;
@@ -273,8 +275,8 @@ extern PCIDevice *piix4_dev;
int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn);
/* pc_sysfw.c */
-void pc_system_firmware_init(MemoryRegion *rom_memory,
- bool isapc_ram_fw);
+void pc_system_flash_create(PCMachineState *pcms);
+void pc_system_firmware_init(PCMachineState *pcms, MemoryRegion *rom_memory);
/* acpi-build.c */
void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index ab0e3a0a6f..b4aad26798 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -28,11 +28,11 @@
#define TYPE_SPAPR_PCI_HOST_BRIDGE "spapr-pci-host-bridge"
#define SPAPR_PCI_HOST_BRIDGE(obj) \
- OBJECT_CHECK(sPAPRPHBState, (obj), TYPE_SPAPR_PCI_HOST_BRIDGE)
+ OBJECT_CHECK(SpaprPhbState, (obj), TYPE_SPAPR_PCI_HOST_BRIDGE)
#define SPAPR_PCI_DMA_MAX_WINDOWS 2
-typedef struct sPAPRPHBState sPAPRPHBState;
+typedef struct SpaprPhbState SpaprPhbState;
typedef struct spapr_pci_msi {
uint32_t first_irq;
@@ -44,7 +44,7 @@ typedef struct spapr_pci_msi_mig {
spapr_pci_msi value;
} spapr_pci_msi_mig;
-struct sPAPRPHBState {
+struct SpaprPhbState {
PCIHostState parent_obj;
uint32_t index;
@@ -72,7 +72,7 @@ struct sPAPRPHBState {
int32_t msi_devs_num;
spapr_pci_msi_mig *msi_devs;
- QLIST_ENTRY(sPAPRPHBState) list;
+ QLIST_ENTRY(SpaprPhbState) list;
bool ddw_enabled;
uint64_t page_size_mask;
@@ -105,56 +105,56 @@ struct sPAPRPHBState {
#define SPAPR_PCI_MSI_WINDOW 0x40000000000ULL
-static inline qemu_irq spapr_phb_lsi_qirq(struct sPAPRPHBState *phb, int pin)
+static inline qemu_irq spapr_phb_lsi_qirq(struct SpaprPhbState *phb, int pin)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+ SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
return spapr_qirq(spapr, phb->lsi_table[pin].irq);
}
-int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t intc_phandle, void *fdt,
+int spapr_populate_pci_dt(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt,
uint32_t nr_msis, int *node_offset);
void spapr_pci_rtas_init(void);
-sPAPRPHBState *spapr_pci_find_phb(sPAPRMachineState *spapr, uint64_t buid);
-PCIDevice *spapr_pci_find_dev(sPAPRMachineState *spapr, uint64_t buid,
+SpaprPhbState *spapr_pci_find_phb(SpaprMachineState *spapr, uint64_t buid);
+PCIDevice *spapr_pci_find_dev(SpaprMachineState *spapr, uint64_t buid,
uint32_t config_addr);
/* DRC callbacks */
void spapr_phb_remove_pci_device_cb(DeviceState *dev);
-int spapr_pci_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
+int spapr_pci_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
void *fdt, int *fdt_start_offset, Error **errp);
/* VFIO EEH hooks */
#ifdef CONFIG_LINUX
-bool spapr_phb_eeh_available(sPAPRPHBState *sphb);
-int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
+bool spapr_phb_eeh_available(SpaprPhbState *sphb);
+int spapr_phb_vfio_eeh_set_option(SpaprPhbState *sphb,
unsigned int addr, int option);
-int spapr_phb_vfio_eeh_get_state(sPAPRPHBState *sphb, int *state);
-int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option);
-int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb);
+int spapr_phb_vfio_eeh_get_state(SpaprPhbState *sphb, int *state);
+int spapr_phb_vfio_eeh_reset(SpaprPhbState *sphb, int option);
+int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb);
void spapr_phb_vfio_reset(DeviceState *qdev);
#else
-static inline bool spapr_phb_eeh_available(sPAPRPHBState *sphb)
+static inline bool spapr_phb_eeh_available(SpaprPhbState *sphb)
{
return false;
}
-static inline int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
+static inline int spapr_phb_vfio_eeh_set_option(SpaprPhbState *sphb,
unsigned int addr, int option)
{
return RTAS_OUT_HW_ERROR;
}
-static inline int spapr_phb_vfio_eeh_get_state(sPAPRPHBState *sphb,
+static inline int spapr_phb_vfio_eeh_get_state(SpaprPhbState *sphb,
int *state)
{
return RTAS_OUT_HW_ERROR;
}
-static inline int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option)
+static inline int spapr_phb_vfio_eeh_reset(SpaprPhbState *sphb, int option)
{
return RTAS_OUT_HW_ERROR;
}
-static inline int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb)
+static inline int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb)
{
return RTAS_OUT_HW_ERROR;
}
@@ -163,9 +163,9 @@ static inline void spapr_phb_vfio_reset(DeviceState *qdev)
}
#endif
-void spapr_phb_dma_reset(sPAPRPHBState *sphb);
+void spapr_phb_dma_reset(SpaprPhbState *sphb);
-static inline unsigned spapr_phb_windows_supported(sPAPRPHBState *sphb)
+static inline unsigned spapr_phb_windows_supported(SpaprPhbState *sphb)
{
return sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1;
}
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 6b65397b7e..e5b00d373e 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -25,6 +25,8 @@
#include "hw/ppc/pnv_lpc.h"
#include "hw/ppc/pnv_psi.h"
#include "hw/ppc/pnv_occ.h"
+#include "hw/ppc/pnv_xive.h"
+#include "hw/ppc/pnv_core.h"
#define TYPE_PNV_CHIP "pnv-chip"
#define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP)
@@ -57,6 +59,8 @@ typedef struct PnvChip {
MemoryRegion xscom_mmio;
MemoryRegion xscom;
AddressSpace xscom_as;
+
+ gchar *dt_isa_nodename;
} PnvChip;
#define TYPE_PNV8_CHIP "pnv8-chip"
@@ -70,7 +74,7 @@ typedef struct Pnv8Chip {
MemoryRegion icp_mmio;
PnvLpcController lpc;
- PnvPsi psi;
+ Pnv8Psi psi;
PnvOCC occ;
} Pnv8Chip;
@@ -82,6 +86,13 @@ typedef struct Pnv9Chip {
PnvChip parent_obj;
/*< public >*/
+ PnvXive xive;
+ Pnv9Psi psi;
+ PnvLpcController lpc;
+ PnvOCC occ;
+
+ uint32_t nr_quads;
+ PnvQuad *quads;
} Pnv9Chip;
typedef struct PnvChipClass {
@@ -100,6 +111,8 @@ typedef struct PnvChipClass {
uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id);
void (*intc_create)(PnvChip *chip, PowerPCCPU *cpu, Error **errp);
ISABus *(*isa_create)(PnvChip *chip, Error **errp);
+ void (*dt_populate)(PnvChip *chip, void *fdt);
+ void (*pic_print_info)(PnvChip *chip, Monitor *mon);
} PnvChipClass;
#define PNV_CHIP_TYPE_SUFFIX "-" TYPE_PNV_CHIP
@@ -215,4 +228,31 @@ void pnv_bmc_powerdown(IPMIBmc *bmc);
(0x0003ffe000000000ull + (uint64_t)PNV_CHIP_INDEX(chip) * \
PNV_PSIHB_FSP_SIZE)
+/*
+ * POWER9 MMIO base addresses
+ */
+#define PNV9_CHIP_BASE(chip, base) \
+ ((base) + ((uint64_t) (chip)->chip_id << 42))
+
+#define PNV9_XIVE_VC_SIZE 0x0000008000000000ull
+#define PNV9_XIVE_VC_BASE(chip) PNV9_CHIP_BASE(chip, 0x0006010000000000ull)
+
+#define PNV9_XIVE_PC_SIZE 0x0000001000000000ull
+#define PNV9_XIVE_PC_BASE(chip) PNV9_CHIP_BASE(chip, 0x0006018000000000ull)
+
+#define PNV9_LPCM_SIZE 0x0000000100000000ull
+#define PNV9_LPCM_BASE(chip) PNV9_CHIP_BASE(chip, 0x0006030000000000ull)
+
+#define PNV9_PSIHB_SIZE 0x0000000000100000ull
+#define PNV9_PSIHB_BASE(chip) PNV9_CHIP_BASE(chip, 0x0006030203000000ull)
+
+#define PNV9_XIVE_IC_SIZE 0x0000000000080000ull
+#define PNV9_XIVE_IC_BASE(chip) PNV9_CHIP_BASE(chip, 0x0006030203100000ull)
+
+#define PNV9_XIVE_TM_SIZE 0x0000000000040000ull
+#define PNV9_XIVE_TM_BASE(chip) PNV9_CHIP_BASE(chip, 0x0006030203180000ull)
+
+#define PNV9_PSIHB_ESB_SIZE 0x0000000000010000ull
+#define PNV9_PSIHB_ESB_BASE(chip) PNV9_CHIP_BASE(chip, 0x00060302031c0000ull)
+
#endif /* _PPC_PNV_H */
diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
index 9961ea3a92..50cdb2b358 100644
--- a/include/hw/ppc/pnv_core.h
+++ b/include/hw/ppc/pnv_core.h
@@ -42,13 +42,15 @@ typedef struct PnvCore {
typedef struct PnvCoreClass {
DeviceClass parent_class;
+
+ const MemoryRegionOps *xscom_ops;
} PnvCoreClass;
#define PNV_CORE_TYPE_SUFFIX "-" TYPE_PNV_CORE
#define PNV_CORE_TYPE_NAME(cpu_model) cpu_model PNV_CORE_TYPE_SUFFIX
typedef struct PnvCPUState {
- struct ICPState *icp;
+ Object *intc;
} PnvCPUState;
static inline PnvCPUState *pnv_cpu_state(PowerPCCPU *cpu)
@@ -56,4 +58,14 @@ static inline PnvCPUState *pnv_cpu_state(PowerPCCPU *cpu)
return (PnvCPUState *)cpu->machine_data;
}
+#define TYPE_PNV_QUAD "powernv-cpu-quad"
+#define PNV_QUAD(obj) \
+ OBJECT_CHECK(PnvQuad, (obj), TYPE_PNV_QUAD)
+
+typedef struct PnvQuad {
+ DeviceState parent_obj;
+
+ uint32_t id;
+ MemoryRegion xscom_regs;
+} PnvQuad;
#endif /* _PPC_PNV_CORE_H */
diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h
index d657489b07..413579792e 100644
--- a/include/hw/ppc/pnv_lpc.h
+++ b/include/hw/ppc/pnv_lpc.h
@@ -24,6 +24,11 @@
#define TYPE_PNV_LPC "pnv-lpc"
#define PNV_LPC(obj) \
OBJECT_CHECK(PnvLpcController, (obj), TYPE_PNV_LPC)
+#define TYPE_PNV8_LPC TYPE_PNV_LPC "-POWER8"
+#define PNV8_LPC(obj) OBJECT_CHECK(PnvLpcController, (obj), TYPE_PNV8_LPC)
+
+#define TYPE_PNV9_LPC TYPE_PNV_LPC "-POWER9"
+#define PNV9_LPC(obj) OBJECT_CHECK(PnvLpcController, (obj), TYPE_PNV9_LPC)
typedef struct PnvLpcController {
DeviceState parent;
@@ -50,6 +55,8 @@ typedef struct PnvLpcController {
MemoryRegion opb_master_regs;
/* OPB Master LS registers */
+ uint32_t opb_irq_route0;
+ uint32_t opb_irq_route1;
uint32_t opb_irq_stat;
uint32_t opb_irq_mask;
uint32_t opb_irq_pol;
@@ -70,6 +77,25 @@ typedef struct PnvLpcController {
PnvPsi *psi;
} PnvLpcController;
+#define PNV_LPC_CLASS(klass) \
+ OBJECT_CLASS_CHECK(PnvLpcClass, (klass), TYPE_PNV_LPC)
+#define PNV_LPC_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(PnvLpcClass, (obj), TYPE_PNV_LPC)
+
+typedef struct PnvLpcClass {
+ DeviceClass parent_class;
+
+ int psi_irq;
+
+ DeviceRealize parent_realize;
+} PnvLpcClass;
+
+/*
+ * Old compilers error on typdef forward declarations. Keep them happy.
+ */
+struct PnvChip;
+
ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp);
+int pnv_dt_lpc(struct PnvChip *chip, void *fdt, int root_offset);
#endif /* _PPC_PNV_LPC_H */
diff --git a/include/hw/ppc/pnv_occ.h b/include/hw/ppc/pnv_occ.h
index 82f299dc76..d22b65a71a 100644
--- a/include/hw/ppc/pnv_occ.h
+++ b/include/hw/ppc/pnv_occ.h
@@ -23,6 +23,10 @@
#define TYPE_PNV_OCC "pnv-occ"
#define PNV_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV_OCC)
+#define TYPE_PNV8_OCC TYPE_PNV_OCC "-POWER8"
+#define PNV8_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV8_OCC)
+#define TYPE_PNV9_OCC TYPE_PNV_OCC "-POWER9"
+#define PNV9_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV9_OCC)
typedef struct PnvOCC {
DeviceState xd;
@@ -35,4 +39,17 @@ typedef struct PnvOCC {
MemoryRegion xscom_regs;
} PnvOCC;
+#define PNV_OCC_CLASS(klass) \
+ OBJECT_CLASS_CHECK(PnvOCCClass, (klass), TYPE_PNV_OCC)
+#define PNV_OCC_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(PnvOCCClass, (obj), TYPE_PNV_OCC)
+
+typedef struct PnvOCCClass {
+ DeviceClass parent_class;
+
+ int xscom_size;
+ const MemoryRegionOps *xscom_ops;
+ int psi_irq;
+} PnvOCCClass;
+
#endif /* _PPC_PNV_OCC_H */
diff --git a/include/hw/ppc/pnv_psi.h b/include/hw/ppc/pnv_psi.h
index 64ac73512e..2c1b27e865 100644
--- a/include/hw/ppc/pnv_psi.h
+++ b/include/hw/ppc/pnv_psi.h
@@ -21,6 +21,7 @@
#include "hw/sysbus.h"
#include "hw/ppc/xics.h"
+#include "hw/ppc/xive.h"
#define TYPE_PNV_PSI "pnv-psi"
#define PNV_PSI(obj) \
@@ -39,7 +40,6 @@ typedef struct PnvPsi {
uint64_t fsp_bar;
/* Interrupt generation */
- ICSState ics;
qemu_irq *qirqs;
/* Registers */
@@ -48,6 +48,42 @@ typedef struct PnvPsi {
MemoryRegion xscom_regs;
} PnvPsi;
+#define TYPE_PNV8_PSI TYPE_PNV_PSI "-POWER8"
+#define PNV8_PSI(obj) \
+ OBJECT_CHECK(Pnv8Psi, (obj), TYPE_PNV8_PSI)
+
+typedef struct Pnv8Psi {
+ PnvPsi parent;
+
+ ICSState ics;
+} Pnv8Psi;
+
+#define TYPE_PNV9_PSI TYPE_PNV_PSI "-POWER9"
+#define PNV9_PSI(obj) \
+ OBJECT_CHECK(Pnv9Psi, (obj), TYPE_PNV9_PSI)
+
+typedef struct Pnv9Psi {
+ PnvPsi parent;
+
+ XiveSource source;
+} Pnv9Psi;
+
+#define PNV_PSI_CLASS(klass) \
+ OBJECT_CLASS_CHECK(PnvPsiClass, (klass), TYPE_PNV_PSI)
+#define PNV_PSI_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(PnvPsiClass, (obj), TYPE_PNV_PSI)
+
+typedef struct PnvPsiClass {
+ SysBusDeviceClass parent_class;
+
+ int chip_type;
+ uint32_t xscom_pcba;
+ uint32_t xscom_size;
+ uint64_t bar_mask;
+
+ void (*irq_set)(PnvPsi *psi, int, bool state);
+} PnvPsiClass;
+
/* The PSI and FSP interrupts are muxed on the same IRQ number */
typedef enum PnvPsiIrq {
PSIHB_IRQ_PSI, /* internal use only */
@@ -61,6 +97,25 @@ typedef enum PnvPsiIrq {
#define PSI_NUM_INTERRUPTS 6
-extern void pnv_psi_irq_set(PnvPsi *psi, PnvPsiIrq irq, bool state);
+void pnv_psi_irq_set(PnvPsi *psi, int irq, bool state);
+
+/* P9 PSI Interrupts */
+#define PSIHB9_IRQ_PSI 0
+#define PSIHB9_IRQ_OCC 1
+#define PSIHB9_IRQ_FSI 2
+#define PSIHB9_IRQ_LPCHC 3
+#define PSIHB9_IRQ_LOCAL_ERR 4
+#define PSIHB9_IRQ_GLOBAL_ERR 5
+#define PSIHB9_IRQ_TPM 6
+#define PSIHB9_IRQ_LPC_SIRQ0 7
+#define PSIHB9_IRQ_LPC_SIRQ1 8
+#define PSIHB9_IRQ_LPC_SIRQ2 9
+#define PSIHB9_IRQ_LPC_SIRQ3 10
+#define PSIHB9_IRQ_SBE_I2C 11
+#define PSIHB9_IRQ_DIO 12
+#define PSIHB9_IRQ_PSU 13
+#define PSIHB9_NUM_IRQS 14
+
+void pnv_psi_pic_print_info(Pnv9Psi *psi, Monitor *mon);
#endif /* _PPC_PNV_PSI_H */
diff --git a/include/hw/ppc/pnv_xive.h b/include/hw/ppc/pnv_xive.h
new file mode 100644
index 0000000000..4fdaa9247d
--- /dev/null
+++ b/include/hw/ppc/pnv_xive.h
@@ -0,0 +1,93 @@
+/*
+ * QEMU PowerPC XIVE interrupt controller model
+ *
+ * Copyright (c) 2017-2019, IBM Corporation.
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ */
+
+#ifndef PPC_PNV_XIVE_H
+#define PPC_PNV_XIVE_H
+
+#include "hw/ppc/xive.h"
+
+struct PnvChip;
+
+#define TYPE_PNV_XIVE "pnv-xive"
+#define PNV_XIVE(obj) OBJECT_CHECK(PnvXive, (obj), TYPE_PNV_XIVE)
+
+#define XIVE_BLOCK_MAX 16
+
+#define XIVE_TABLE_BLK_MAX 16 /* Block Scope Table (0-15) */
+#define XIVE_TABLE_MIG_MAX 16 /* Migration Register Table (1-15) */
+#define XIVE_TABLE_VDT_MAX 16 /* VDT Domain Table (0-15) */
+#define XIVE_TABLE_EDT_MAX 64 /* EDT Domain Table (0-63) */
+
+typedef struct PnvXive {
+ XiveRouter parent_obj;
+
+ /* Owning chip */
+ struct PnvChip *chip;
+
+ /* XSCOM addresses giving access to the controller registers */
+ MemoryRegion xscom_regs;
+
+ /* Main MMIO regions that can be configured by FW */
+ MemoryRegion ic_mmio;
+ MemoryRegion ic_reg_mmio;
+ MemoryRegion ic_notify_mmio;
+ MemoryRegion ic_lsi_mmio;
+ MemoryRegion tm_indirect_mmio;
+ MemoryRegion vc_mmio;
+ MemoryRegion pc_mmio;
+ MemoryRegion tm_mmio;
+
+ /*
+ * IPI and END address spaces modeling the EDT segmentation in the
+ * VC region
+ */
+ AddressSpace ipi_as;
+ MemoryRegion ipi_mmio;
+ MemoryRegion ipi_edt_mmio;
+
+ AddressSpace end_as;
+ MemoryRegion end_mmio;
+ MemoryRegion end_edt_mmio;
+
+ /* Shortcut values for the Main MMIO regions */
+ hwaddr ic_base;
+ uint32_t ic_shift;
+ hwaddr vc_base;
+ uint32_t vc_shift;
+ hwaddr pc_base;
+ uint32_t pc_shift;
+ hwaddr tm_base;
+ uint32_t tm_shift;
+
+ /* Our XIVE source objects for IPIs and ENDs */
+ XiveSource ipi_source;
+ XiveENDSource end_source;
+
+ /* Interrupt controller registers */
+ uint64_t regs[0x300];
+
+ /* Can be configured by FW */
+ uint32_t tctx_chipid;
+
+ /*
+ * Virtual Structure Descriptor tables : EAT, SBE, ENDT, NVTT, IRQ
+ * These are in a SRAM protected by ECC.
+ */
+ uint64_t vsds[5][XIVE_BLOCK_MAX];
+
+ /* Translation tables */
+ uint64_t blk[XIVE_TABLE_BLK_MAX];
+ uint64_t mig[XIVE_TABLE_MIG_MAX];
+ uint64_t vdt[XIVE_TABLE_VDT_MAX];
+ uint64_t edt[XIVE_TABLE_EDT_MAX];
+} PnvXive;
+
+void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon);
+
+#endif /* PPC_PNV_XIVE_H */
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 255b26a5aa..68dfae0dfe 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -60,10 +60,6 @@ typedef struct PnvXScomInterfaceClass {
(PNV_XSCOM_EX_CORE_BASE | ((uint64_t)(core) << 24))
#define PNV_XSCOM_EX_SIZE 0x100000
-#define PNV_XSCOM_P9_EC_BASE(core) \
- ((uint64_t)(((core) & 0x1F) + 0x20) << 24)
-#define PNV_XSCOM_P9_EC_SIZE 0x100000
-
#define PNV_XSCOM_LPC_BASE 0xb0020
#define PNV_XSCOM_LPC_SIZE 0x4
@@ -73,6 +69,23 @@ typedef struct PnvXScomInterfaceClass {
#define PNV_XSCOM_OCC_BASE 0x0066000
#define PNV_XSCOM_OCC_SIZE 0x6000
+#define PNV9_XSCOM_EC_BASE(core) \
+ ((uint64_t)(((core) & 0x1F) + 0x20) << 24)
+#define PNV9_XSCOM_EC_SIZE 0x100000
+
+#define PNV9_XSCOM_EQ_BASE(core) \
+ ((uint64_t)(((core) & 0x1C) + 0x40) << 22)
+#define PNV9_XSCOM_EQ_SIZE 0x100000
+
+#define PNV9_XSCOM_OCC_BASE PNV_XSCOM_OCC_BASE
+#define PNV9_XSCOM_OCC_SIZE 0x8000
+
+#define PNV9_XSCOM_PSIHB_BASE 0x5012900
+#define PNV9_XSCOM_PSIHB_SIZE 0x100
+
+#define PNV9_XSCOM_XIVE_BASE 0x5013000
+#define PNV9_XSCOM_XIVE_SIZE 0x300
+
extern void pnv_xscom_realize(PnvChip *chip, Error **errp);
extern int pnv_dt_xscom(PnvChip *chip, void *fdt, int offset);
diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h
index 746170f635..4bdcb8bacd 100644
--- a/include/hw/ppc/ppc.h
+++ b/include/hw/ppc/ppc.h
@@ -4,6 +4,7 @@
#include "target/ppc/cpu-qom.h"
void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level);
+PowerPCCPU *ppc_get_vcpu_by_pir(int pir);
/* PowerPC hardware exceptions management helpers */
typedef void (*clk_setup_cb)(void *opaque, uint32_t freq);
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 59073a7579..2b4c05a2ec 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -8,16 +8,16 @@
#include "hw/mem/pc-dimm.h"
#include "hw/ppc/spapr_ovec.h"
#include "hw/ppc/spapr_irq.h"
-#include "hw/ppc/spapr_xive.h" /* For sPAPRXive */
+#include "hw/ppc/spapr_xive.h" /* For SpaprXive */
#include "hw/ppc/xics.h" /* For ICSState */
-struct VIOsPAPRBus;
-struct sPAPRPHBState;
-struct sPAPRNVRAM;
+struct SpaprVioBus;
+struct SpaprPhbState;
+struct SpaprNvram;
-typedef struct sPAPREventLogEntry sPAPREventLogEntry;
-typedef struct sPAPREventSource sPAPREventSource;
-typedef struct sPAPRPendingHPT sPAPRPendingHPT;
+typedef struct SpaprEventLogEntry SpaprEventLogEntry;
+typedef struct SpaprEventSource SpaprEventSource;
+typedef struct SpaprPendingHpt SpaprPendingHpt;
#define HPTE64_V_HPTE_DIRTY 0x0000000000000040ULL
#define SPAPR_ENTRY_POINT 0x100
@@ -27,32 +27,32 @@ typedef struct sPAPRPendingHPT sPAPRPendingHPT;
#define TYPE_SPAPR_RTC "spapr-rtc"
#define SPAPR_RTC(obj) \
- OBJECT_CHECK(sPAPRRTCState, (obj), TYPE_SPAPR_RTC)
+ OBJECT_CHECK(SpaprRtcState, (obj), TYPE_SPAPR_RTC)
-typedef struct sPAPRRTCState sPAPRRTCState;
-struct sPAPRRTCState {
+typedef struct SpaprRtcState SpaprRtcState;
+struct SpaprRtcState {
/*< private >*/
DeviceState parent_obj;
int64_t ns_offset;
};
-typedef struct sPAPRDIMMState sPAPRDIMMState;
-typedef struct sPAPRMachineClass sPAPRMachineClass;
+typedef struct SpaprDimmState SpaprDimmState;
+typedef struct SpaprMachineClass SpaprMachineClass;
#define TYPE_SPAPR_MACHINE "spapr-machine"
#define SPAPR_MACHINE(obj) \
- OBJECT_CHECK(sPAPRMachineState, (obj), TYPE_SPAPR_MACHINE)
+ OBJECT_CHECK(SpaprMachineState, (obj), TYPE_SPAPR_MACHINE)
#define SPAPR_MACHINE_GET_CLASS(obj) \
- OBJECT_GET_CLASS(sPAPRMachineClass, obj, TYPE_SPAPR_MACHINE)
+ OBJECT_GET_CLASS(SpaprMachineClass, obj, TYPE_SPAPR_MACHINE)
#define SPAPR_MACHINE_CLASS(klass) \
- OBJECT_CLASS_CHECK(sPAPRMachineClass, klass, TYPE_SPAPR_MACHINE)
+ OBJECT_CLASS_CHECK(SpaprMachineClass, klass, TYPE_SPAPR_MACHINE)
typedef enum {
SPAPR_RESIZE_HPT_DEFAULT = 0,
SPAPR_RESIZE_HPT_DISABLED,
SPAPR_RESIZE_HPT_ENABLED,
SPAPR_RESIZE_HPT_REQUIRED,
-} sPAPRResizeHPT;
+} SpaprResizeHpt;
/**
* Capabilities
@@ -74,8 +74,12 @@ typedef enum {
#define SPAPR_CAP_HPT_MAXPAGESIZE 0x06
/* Nested KVM-HV */
#define SPAPR_CAP_NESTED_KVM_HV 0x07
+/* Large Decrementer */
+#define SPAPR_CAP_LARGE_DECREMENTER 0x08
+/* Count Cache Flush Assist HW Instruction */
+#define SPAPR_CAP_CCF_ASSIST 0x09
/* Num Caps */
-#define SPAPR_CAP_NUM (SPAPR_CAP_NESTED_KVM_HV + 1)
+#define SPAPR_CAP_NUM (SPAPR_CAP_CCF_ASSIST + 1)
/*
* Capability Values
@@ -83,22 +87,27 @@ typedef enum {
/* Bool Caps */
#define SPAPR_CAP_OFF 0x00
#define SPAPR_CAP_ON 0x01
+
/* Custom Caps */
+
+/* Generic */
#define SPAPR_CAP_BROKEN 0x00
#define SPAPR_CAP_WORKAROUND 0x01
#define SPAPR_CAP_FIXED 0x02
+/* SPAPR_CAP_IBS (cap-ibs) */
#define SPAPR_CAP_FIXED_IBS 0x02
#define SPAPR_CAP_FIXED_CCD 0x03
+#define SPAPR_CAP_FIXED_NA 0x10 /* Lets leave a bit of a gap... */
-typedef struct sPAPRCapabilities sPAPRCapabilities;
-struct sPAPRCapabilities {
+typedef struct SpaprCapabilities SpaprCapabilities;
+struct SpaprCapabilities {
uint8_t caps[SPAPR_CAP_NUM];
};
/**
- * sPAPRMachineClass:
+ * SpaprMachineClass:
*/
-struct sPAPRMachineClass {
+struct SpaprMachineClass {
/*< private >*/
MachineClass parent_class;
@@ -110,33 +119,33 @@ struct sPAPRMachineClass {
bool pre_2_10_has_unused_icps;
bool legacy_irq_allocation;
- void (*phb_placement)(sPAPRMachineState *spapr, uint32_t index,
+ void (*phb_placement)(SpaprMachineState *spapr, uint32_t index,
uint64_t *buid, hwaddr *pio,
hwaddr *mmio32, hwaddr *mmio64,
unsigned n_dma, uint32_t *liobns, Error **errp);
- sPAPRResizeHPT resize_hpt_default;
- sPAPRCapabilities default_caps;
- sPAPRIrq *irq;
+ SpaprResizeHpt resize_hpt_default;
+ SpaprCapabilities default_caps;
+ SpaprIrq *irq;
};
/**
- * sPAPRMachineState:
+ * SpaprMachineState:
*/
-struct sPAPRMachineState {
+struct SpaprMachineState {
/*< private >*/
MachineState parent_obj;
- struct VIOsPAPRBus *vio_bus;
- QLIST_HEAD(, sPAPRPHBState) phbs;
- struct sPAPRNVRAM *nvram;
+ struct SpaprVioBus *vio_bus;
+ QLIST_HEAD(, SpaprPhbState) phbs;
+ struct SpaprNvram *nvram;
ICSState *ics;
- sPAPRRTCState rtc;
+ SpaprRtcState rtc;
- sPAPRResizeHPT resize_hpt;
+ SpaprResizeHpt resize_hpt;
void *htab;
uint32_t htab_shift;
uint64_t patb_entry; /* Process tbl registed in H_REGISTER_PROCESS_TABLE */
- sPAPRPendingHPT *pending_hpt; /* in-progress resize */
+ SpaprPendingHpt *pending_hpt; /* in-progress resize */
hwaddr rma_size;
int vrma_adjust;
@@ -155,15 +164,15 @@ struct sPAPRMachineState {
uint32_t vsmt; /* Virtual SMT mode (KVM's "core stride") */
Notifier epow_notifier;
- QTAILQ_HEAD(, sPAPREventLogEntry) pending_events;
+ QTAILQ_HEAD(, SpaprEventLogEntry) pending_events;
bool use_hotplug_event_source;
- sPAPREventSource *event_sources;
+ SpaprEventSource *event_sources;
/* ibm,client-architecture-support option negotiation */
bool cas_reboot;
bool cas_legacy_guest_workaround;
- sPAPROptionVector *ov5; /* QEMU-supported option vectors */
- sPAPROptionVector *ov5_cas; /* negotiated (via CAS) option vectors */
+ SpaprOptionVector *ov5; /* QEMU-supported option vectors */
+ SpaprOptionVector *ov5_cas; /* negotiated (via CAS) option vectors */
uint32_t max_compat_pvr;
/* Migration state */
@@ -174,7 +183,7 @@ struct sPAPRMachineState {
/* Pending DIMM unplug cache. It is populated when a LMB
* unplug starts. It can be regenerated if a migration
* occurs during the unplug process. */
- QTAILQ_HEAD(, sPAPRDIMMState) pending_dimm_unplugs;
+ QTAILQ_HEAD(, SpaprDimmState) pending_dimm_unplugs;
/*< public >*/
char *kvm_type;
@@ -183,12 +192,12 @@ struct sPAPRMachineState {
int32_t irq_map_nr;
unsigned long *irq_map;
- sPAPRXive *xive;
- sPAPRIrq *irq;
+ SpaprXive *xive;
+ SpaprIrq *irq;
qemu_irq *qirqs;
bool cmd_line_caps[SPAPR_CAP_NUM];
- sPAPRCapabilities def, eff, mig;
+ SpaprCapabilities def, eff, mig;
};
#define H_SUCCESS 0
@@ -337,9 +346,11 @@ struct sPAPRMachineState {
#define H_CPU_CHAR_HON_BRANCH_HINTS PPC_BIT(5)
#define H_CPU_CHAR_THR_RECONF_TRIG PPC_BIT(6)
#define H_CPU_CHAR_CACHE_COUNT_DIS PPC_BIT(7)
+#define H_CPU_CHAR_BCCTR_FLUSH_ASSIST PPC_BIT(9)
#define H_CPU_BEHAV_FAVOUR_SECURITY PPC_BIT(0)
#define H_CPU_BEHAV_L1D_FLUSH_PR PPC_BIT(1)
#define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR PPC_BIT(2)
+#define H_CPU_BEHAV_FLUSH_COUNT_CACHE PPC_BIT(5)
/* Each control block has to be on a 4K boundary */
#define H_CB_ALIGNMENT 4096
@@ -492,16 +503,16 @@ struct sPAPRMachineState {
#define KVMPPC_H_UPDATE_DT (KVMPPC_HCALL_BASE + 0x3)
#define KVMPPC_HCALL_MAX KVMPPC_H_UPDATE_DT
-typedef struct sPAPRDeviceTreeUpdateHeader {
+typedef struct SpaprDeviceTreeUpdateHeader {
uint32_t version_id;
-} sPAPRDeviceTreeUpdateHeader;
+} SpaprDeviceTreeUpdateHeader;
#define hcall_dprintf(fmt, ...) \
do { \
qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt, __func__, ## __VA_ARGS__); \
} while (0)
-typedef target_ulong (*spapr_hcall_fn)(PowerPCCPU *cpu, sPAPRMachineState *sm,
+typedef target_ulong (*spapr_hcall_fn)(PowerPCCPU *cpu, SpaprMachineState *sm,
target_ulong opcode,
target_ulong *args);
@@ -655,16 +666,16 @@ static inline void rtas_st(target_ulong phys, int n, uint32_t val)
stl_be_phys(&address_space_memory, ppc64_phys_to_real(phys + 4*n), val);
}
-typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, sPAPRMachineState *sm,
+typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, SpaprMachineState *sm,
uint32_t token,
uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets);
void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn);
-target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPRMachineState *sm,
+target_ulong spapr_rtas_call(PowerPCCPU *cpu, SpaprMachineState *sm,
uint32_t token, uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets);
void spapr_dt_rtas_tokens(void *fdt, int rtas);
-void spapr_load_rtas(sPAPRMachineState *spapr, void *fdt, hwaddr addr);
+void spapr_load_rtas(SpaprMachineState *spapr, void *fdt, hwaddr addr);
#define SPAPR_TCE_PAGE_SHIFT 12
#define SPAPR_TCE_PAGE_SIZE (1ULL << SPAPR_TCE_PAGE_SHIFT)
@@ -691,17 +702,17 @@ static inline void spapr_dt_irq(uint32_t *intspec, int irq, bool is_lsi)
intspec[1] = is_lsi ? cpu_to_be32(1) : 0;
}
-typedef struct sPAPRTCETable sPAPRTCETable;
+typedef struct SpaprTceTable SpaprTceTable;
#define TYPE_SPAPR_TCE_TABLE "spapr-tce-table"
#define SPAPR_TCE_TABLE(obj) \
- OBJECT_CHECK(sPAPRTCETable, (obj), TYPE_SPAPR_TCE_TABLE)
+ OBJECT_CHECK(SpaprTceTable, (obj), TYPE_SPAPR_TCE_TABLE)
#define TYPE_SPAPR_IOMMU_MEMORY_REGION "spapr-iommu-memory-region"
#define SPAPR_IOMMU_MEMORY_REGION(obj) \
OBJECT_CHECK(IOMMUMemoryRegion, (obj), TYPE_SPAPR_IOMMU_MEMORY_REGION)
-struct sPAPRTCETable {
+struct SpaprTceTable {
DeviceState parent;
uint32_t liobn;
uint32_t nb_table;
@@ -712,76 +723,77 @@ struct sPAPRTCETable {
uint64_t *mig_table;
bool bypass;
bool need_vfio;
+ bool skipping_replay;
int fd;
MemoryRegion root;
IOMMUMemoryRegion iommu;
- struct VIOsPAPRDevice *vdev; /* for @bypass migration compatibility only */
- QLIST_ENTRY(sPAPRTCETable) list;
+ struct SpaprVioDevice *vdev; /* for @bypass migration compatibility only */
+ QLIST_ENTRY(SpaprTceTable) list;
};
-sPAPRTCETable *spapr_tce_find_by_liobn(target_ulong liobn);
+SpaprTceTable *spapr_tce_find_by_liobn(target_ulong liobn);
-struct sPAPREventLogEntry {
+struct SpaprEventLogEntry {
uint32_t summary;
uint32_t extended_length;
void *extended_log;
- QTAILQ_ENTRY(sPAPREventLogEntry) next;
+ QTAILQ_ENTRY(SpaprEventLogEntry) next;
};
-void spapr_events_init(sPAPRMachineState *sm);
-void spapr_dt_events(sPAPRMachineState *sm, void *fdt);
-int spapr_h_cas_compose_response(sPAPRMachineState *sm,
+void spapr_events_init(SpaprMachineState *sm);
+void spapr_dt_events(SpaprMachineState *sm, void *fdt);
+int spapr_h_cas_compose_response(SpaprMachineState *sm,
target_ulong addr, target_ulong size,
- sPAPROptionVector *ov5_updates);
-void close_htab_fd(sPAPRMachineState *spapr);
-void spapr_setup_hpt_and_vrma(sPAPRMachineState *spapr);
-void spapr_free_hpt(sPAPRMachineState *spapr);
-sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn);
-void spapr_tce_table_enable(sPAPRTCETable *tcet,
+ SpaprOptionVector *ov5_updates);
+void close_htab_fd(SpaprMachineState *spapr);
+void spapr_setup_hpt_and_vrma(SpaprMachineState *spapr);
+void spapr_free_hpt(SpaprMachineState *spapr);
+SpaprTceTable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn);
+void spapr_tce_table_enable(SpaprTceTable *tcet,
uint32_t page_shift, uint64_t bus_offset,
uint32_t nb_table);
-void spapr_tce_table_disable(sPAPRTCETable *tcet);
-void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio);
+void spapr_tce_table_disable(SpaprTceTable *tcet);
+void spapr_tce_set_need_vfio(SpaprTceTable *tcet, bool need_vfio);
-MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet);
+MemoryRegion *spapr_tce_get_iommu(SpaprTceTable *tcet);
int spapr_dma_dt(void *fdt, int node_off, const char *propname,
uint32_t liobn, uint64_t window, uint32_t size);
int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname,
- sPAPRTCETable *tcet);
+ SpaprTceTable *tcet);
void spapr_pci_switch_vga(bool big_endian);
-void spapr_hotplug_req_add_by_index(sPAPRDRConnector *drc);
-void spapr_hotplug_req_remove_by_index(sPAPRDRConnector *drc);
-void spapr_hotplug_req_add_by_count(sPAPRDRConnectorType drc_type,
+void spapr_hotplug_req_add_by_index(SpaprDrc *drc);
+void spapr_hotplug_req_remove_by_index(SpaprDrc *drc);
+void spapr_hotplug_req_add_by_count(SpaprDrcType drc_type,
uint32_t count);
-void spapr_hotplug_req_remove_by_count(sPAPRDRConnectorType drc_type,
+void spapr_hotplug_req_remove_by_count(SpaprDrcType drc_type,
uint32_t count);
-void spapr_hotplug_req_add_by_count_indexed(sPAPRDRConnectorType drc_type,
+void spapr_hotplug_req_add_by_count_indexed(SpaprDrcType drc_type,
uint32_t count, uint32_t index);
-void spapr_hotplug_req_remove_by_count_indexed(sPAPRDRConnectorType drc_type,
+void spapr_hotplug_req_remove_by_count_indexed(SpaprDrcType drc_type,
uint32_t count, uint32_t index);
int spapr_hpt_shift_for_ramsize(uint64_t ramsize);
-void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
+void spapr_reallocate_hpt(SpaprMachineState *spapr, int shift,
Error **errp);
-void spapr_clear_pending_events(sPAPRMachineState *spapr);
-int spapr_max_server_number(sPAPRMachineState *spapr);
+void spapr_clear_pending_events(SpaprMachineState *spapr);
+int spapr_max_server_number(SpaprMachineState *spapr);
/* DRC callbacks. */
void spapr_core_release(DeviceState *dev);
-int spapr_core_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
+int spapr_core_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
void *fdt, int *fdt_start_offset, Error **errp);
void spapr_lmb_release(DeviceState *dev);
-int spapr_lmb_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
+int spapr_lmb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
void *fdt, int *fdt_start_offset, Error **errp);
void spapr_phb_release(DeviceState *dev);
-int spapr_phb_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
+int spapr_phb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
void *fdt, int *fdt_start_offset, Error **errp);
-void spapr_rtc_read(sPAPRRTCState *rtc, struct tm *tm, uint32_t *ns);
-int spapr_rtc_import_offset(sPAPRRTCState *rtc, int64_t legacy_offset);
+void spapr_rtc_read(SpaprRtcState *rtc, struct tm *tm, uint32_t *ns);
+int spapr_rtc_import_offset(SpaprRtcState *rtc, int64_t legacy_offset);
#define TYPE_SPAPR_RNG "spapr-rng"
-#define SPAPR_MEMORY_BLOCK_SIZE (1 << 28) /* 256MB */
+#define SPAPR_MEMORY_BLOCK_SIZE ((hwaddr)1 << 28) /* 256MB */
/*
* This defines the maximum number of DIMM slots we can have for sPAPR
@@ -828,19 +840,21 @@ extern const VMStateDescription vmstate_spapr_cap_cfpc;
extern const VMStateDescription vmstate_spapr_cap_sbbc;
extern const VMStateDescription vmstate_spapr_cap_ibs;
extern const VMStateDescription vmstate_spapr_cap_nested_kvm_hv;
+extern const VMStateDescription vmstate_spapr_cap_large_decr;
+extern const VMStateDescription vmstate_spapr_cap_ccf_assist;
-static inline uint8_t spapr_get_cap(sPAPRMachineState *spapr, int cap)
+static inline uint8_t spapr_get_cap(SpaprMachineState *spapr, int cap)
{
return spapr->eff.caps[cap];
}
-void spapr_caps_init(sPAPRMachineState *spapr);
-void spapr_caps_apply(sPAPRMachineState *spapr);
-void spapr_caps_cpu_apply(sPAPRMachineState *spapr, PowerPCCPU *cpu);
-void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp);
-int spapr_caps_post_migration(sPAPRMachineState *spapr);
+void spapr_caps_init(SpaprMachineState *spapr);
+void spapr_caps_apply(SpaprMachineState *spapr);
+void spapr_caps_cpu_apply(SpaprMachineState *spapr, PowerPCCPU *cpu);
+void spapr_caps_add_properties(SpaprMachineClass *smc, Error **errp);
+int spapr_caps_post_migration(SpaprMachineState *spapr);
-void spapr_check_pagesize(sPAPRMachineState *spapr, hwaddr pagesize,
+void spapr_check_pagesize(SpaprMachineState *spapr, hwaddr pagesize,
Error **errp);
/*
* XIVE definitions
diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_core.h
index d64f86bc28..f9645a7290 100644
--- a/include/hw/ppc/spapr_cpu_core.h
+++ b/include/hw/ppc/spapr_cpu_core.h
@@ -16,43 +16,43 @@
#define TYPE_SPAPR_CPU_CORE "spapr-cpu-core"
#define SPAPR_CPU_CORE(obj) \
- OBJECT_CHECK(sPAPRCPUCore, (obj), TYPE_SPAPR_CPU_CORE)
+ OBJECT_CHECK(SpaprCpuCore, (obj), TYPE_SPAPR_CPU_CORE)
#define SPAPR_CPU_CORE_CLASS(klass) \
- OBJECT_CLASS_CHECK(sPAPRCPUCoreClass, (klass), TYPE_SPAPR_CPU_CORE)
+ OBJECT_CLASS_CHECK(SpaprCpuCoreClass, (klass), TYPE_SPAPR_CPU_CORE)
#define SPAPR_CPU_CORE_GET_CLASS(obj) \
- OBJECT_GET_CLASS(sPAPRCPUCoreClass, (obj), TYPE_SPAPR_CPU_CORE)
+ OBJECT_GET_CLASS(SpaprCpuCoreClass, (obj), TYPE_SPAPR_CPU_CORE)
#define SPAPR_CPU_CORE_TYPE_NAME(model) model "-" TYPE_SPAPR_CPU_CORE
-typedef struct sPAPRCPUCore {
+typedef struct SpaprCpuCore {
/*< private >*/
CPUCore parent_obj;
/*< public >*/
PowerPCCPU **threads;
int node_id;
- bool pre_3_0_migration; /* older machine don't know about sPAPRCPUState */
-} sPAPRCPUCore;
+ bool pre_3_0_migration; /* older machine don't know about SpaprCpuState */
+} SpaprCpuCore;
-typedef struct sPAPRCPUCoreClass {
+typedef struct SpaprCpuCoreClass {
DeviceClass parent_class;
const char *cpu_type;
-} sPAPRCPUCoreClass;
+} SpaprCpuCoreClass;
const char *spapr_get_cpu_core_type(const char *cpu_type);
void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip, target_ulong r3);
-typedef struct sPAPRCPUState {
+typedef struct SpaprCpuState {
uint64_t vpa_addr;
uint64_t slb_shadow_addr, slb_shadow_size;
uint64_t dtl_addr, dtl_size;
struct ICPState *icp;
struct XiveTCTX *tctx;
-} sPAPRCPUState;
+} SpaprCpuState;
-static inline sPAPRCPUState *spapr_cpu_state(PowerPCCPU *cpu)
+static inline SpaprCpuState *spapr_cpu_state(PowerPCCPU *cpu)
{
- return (sPAPRCPUState *)cpu->machine_data;
+ return (SpaprCpuState *)cpu->machine_data;
}
#endif
diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h
index 46b0f6216d..fad0a887f9 100644
--- a/include/hw/ppc/spapr_drc.h
+++ b/include/hw/ppc/spapr_drc.h
@@ -22,65 +22,65 @@
#define TYPE_SPAPR_DR_CONNECTOR "spapr-dr-connector"
#define SPAPR_DR_CONNECTOR_GET_CLASS(obj) \
- OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DR_CONNECTOR)
+ OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DR_CONNECTOR)
#define SPAPR_DR_CONNECTOR_CLASS(klass) \
- OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \
+ OBJECT_CLASS_CHECK(SpaprDrcClass, klass, \
TYPE_SPAPR_DR_CONNECTOR)
-#define SPAPR_DR_CONNECTOR(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
+#define SPAPR_DR_CONNECTOR(obj) OBJECT_CHECK(SpaprDrc, (obj), \
TYPE_SPAPR_DR_CONNECTOR)
#define TYPE_SPAPR_DRC_PHYSICAL "spapr-drc-physical"
#define SPAPR_DRC_PHYSICAL_GET_CLASS(obj) \
- OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_PHYSICAL)
+ OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_PHYSICAL)
#define SPAPR_DRC_PHYSICAL_CLASS(klass) \
- OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \
+ OBJECT_CLASS_CHECK(SpaprDrcClass, klass, \
TYPE_SPAPR_DRC_PHYSICAL)
-#define SPAPR_DRC_PHYSICAL(obj) OBJECT_CHECK(sPAPRDRCPhysical, (obj), \
+#define SPAPR_DRC_PHYSICAL(obj) OBJECT_CHECK(SpaprDrcPhysical, (obj), \
TYPE_SPAPR_DRC_PHYSICAL)
#define TYPE_SPAPR_DRC_LOGICAL "spapr-drc-logical"
#define SPAPR_DRC_LOGICAL_GET_CLASS(obj) \
- OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_LOGICAL)
+ OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_LOGICAL)
#define SPAPR_DRC_LOGICAL_CLASS(klass) \
- OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \
+ OBJECT_CLASS_CHECK(SpaprDrcClass, klass, \
TYPE_SPAPR_DRC_LOGICAL)
-#define SPAPR_DRC_LOGICAL(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
+#define SPAPR_DRC_LOGICAL(obj) OBJECT_CHECK(SpaprDrc, (obj), \
TYPE_SPAPR_DRC_LOGICAL)
#define TYPE_SPAPR_DRC_CPU "spapr-drc-cpu"
#define SPAPR_DRC_CPU_GET_CLASS(obj) \
- OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_CPU)
+ OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_CPU)
#define SPAPR_DRC_CPU_CLASS(klass) \
- OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_CPU)
-#define SPAPR_DRC_CPU(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
+ OBJECT_CLASS_CHECK(SpaprDrcClass, klass, TYPE_SPAPR_DRC_CPU)
+#define SPAPR_DRC_CPU(obj) OBJECT_CHECK(SpaprDrc, (obj), \
TYPE_SPAPR_DRC_CPU)
#define TYPE_SPAPR_DRC_PCI "spapr-drc-pci"
#define SPAPR_DRC_PCI_GET_CLASS(obj) \
- OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_PCI)
+ OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_PCI)
#define SPAPR_DRC_PCI_CLASS(klass) \
- OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_PCI)
-#define SPAPR_DRC_PCI(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
+ OBJECT_CLASS_CHECK(SpaprDrcClass, klass, TYPE_SPAPR_DRC_PCI)
+#define SPAPR_DRC_PCI(obj) OBJECT_CHECK(SpaprDrc, (obj), \
TYPE_SPAPR_DRC_PCI)
#define TYPE_SPAPR_DRC_LMB "spapr-drc-lmb"
#define SPAPR_DRC_LMB_GET_CLASS(obj) \
- OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_LMB)
+ OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_LMB)
#define SPAPR_DRC_LMB_CLASS(klass) \
- OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_LMB)
-#define SPAPR_DRC_LMB(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
+ OBJECT_CLASS_CHECK(SpaprDrcClass, klass, TYPE_SPAPR_DRC_LMB)
+#define SPAPR_DRC_LMB(obj) OBJECT_CHECK(SpaprDrc, (obj), \
TYPE_SPAPR_DRC_LMB)
#define TYPE_SPAPR_DRC_PHB "spapr-drc-phb"
#define SPAPR_DRC_PHB_GET_CLASS(obj) \
- OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_PHB)
+ OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_PHB)
#define SPAPR_DRC_PHB_CLASS(klass) \
- OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_PHB)
-#define SPAPR_DRC_PHB(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
+ OBJECT_CLASS_CHECK(SpaprDrcClass, klass, TYPE_SPAPR_DRC_PHB)
+#define SPAPR_DRC_PHB(obj) OBJECT_CHECK(SpaprDrc, (obj), \
TYPE_SPAPR_DRC_PHB)
/*
- * Various hotplug types managed by sPAPRDRConnector
+ * Various hotplug types managed by SpaprDrc
*
* these are somewhat arbitrary, but to make things easier
* when generating DRC indexes later we've aligned the bit
@@ -96,7 +96,7 @@ typedef enum {
SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO = 3,
SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI = 4,
SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB = 8,
-} sPAPRDRConnectorTypeShift;
+} SpaprDrcTypeShift;
typedef enum {
SPAPR_DR_CONNECTOR_TYPE_ANY = ~0,
@@ -105,7 +105,7 @@ typedef enum {
SPAPR_DR_CONNECTOR_TYPE_VIO = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO,
SPAPR_DR_CONNECTOR_TYPE_PCI = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI,
SPAPR_DR_CONNECTOR_TYPE_LMB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB,
-} sPAPRDRConnectorType;
+} SpaprDrcType;
/*
* set via set-indicator RTAS calls
@@ -117,7 +117,7 @@ typedef enum {
typedef enum {
SPAPR_DR_ISOLATION_STATE_ISOLATED = 0,
SPAPR_DR_ISOLATION_STATE_UNISOLATED = 1
-} sPAPRDRIsolationState;
+} SpaprDRIsolationState;
/*
* set via set-indicator RTAS calls
@@ -133,7 +133,7 @@ typedef enum {
SPAPR_DR_ALLOCATION_STATE_USABLE = 1,
SPAPR_DR_ALLOCATION_STATE_EXCHANGE = 2,
SPAPR_DR_ALLOCATION_STATE_RECOVER = 3
-} sPAPRDRAllocationState;
+} SpaprDRAllocationState;
/*
* DR-indicator (LED/visual indicator)
@@ -152,7 +152,7 @@ typedef enum {
SPAPR_DR_INDICATOR_ACTIVE = 1,
SPAPR_DR_INDICATOR_IDENTIFY = 2,
SPAPR_DR_INDICATOR_ACTION = 3,
-} sPAPRDRIndicatorState;
+} SpaprDRIndicatorState;
/*
* returned via get-sensor-state RTAS calls
@@ -170,7 +170,7 @@ typedef enum {
SPAPR_DR_ENTITY_SENSE_UNUSABLE = 2,
SPAPR_DR_ENTITY_SENSE_EXCHANGE = 3,
SPAPR_DR_ENTITY_SENSE_RECOVER = 4,
-} sPAPRDREntitySense;
+} SpaprDREntitySense;
typedef enum {
SPAPR_DR_CC_RESPONSE_NEXT_SIB = 1, /* currently unused */
@@ -181,7 +181,7 @@ typedef enum {
SPAPR_DR_CC_RESPONSE_ERROR = -1,
SPAPR_DR_CC_RESPONSE_CONTINUE = -2,
SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE = -9003,
-} sPAPRDRCCResponse;
+} SpaprDRCCResponse;
typedef enum {
/*
@@ -199,9 +199,9 @@ typedef enum {
SPAPR_DRC_STATE_PHYSICAL_POWERON = 6,
SPAPR_DRC_STATE_PHYSICAL_UNISOLATE = 7,
SPAPR_DRC_STATE_PHYSICAL_CONFIGURED = 8,
-} sPAPRDRCState;
+} SpaprDrcState;
-typedef struct sPAPRDRConnector {
+typedef struct SpaprDrc {
/*< private >*/
DeviceState parent;
@@ -220,60 +220,60 @@ typedef struct sPAPRDRConnector {
bool unplug_requested;
void *fdt;
int fdt_start_offset;
-} sPAPRDRConnector;
+} SpaprDrc;
-struct sPAPRMachineState;
+struct SpaprMachineState;
-typedef struct sPAPRDRConnectorClass {
+typedef struct SpaprDrcClass {
/*< private >*/
DeviceClass parent;
- sPAPRDRCState empty_state;
- sPAPRDRCState ready_state;
+ SpaprDrcState empty_state;
+ SpaprDrcState ready_state;
/*< public >*/
- sPAPRDRConnectorTypeShift typeshift;
+ SpaprDrcTypeShift typeshift;
const char *typename; /* used in device tree, PAPR 13.5.2.6 & C.6.1 */
const char *drc_name_prefix; /* used other places in device tree */
- sPAPRDREntitySense (*dr_entity_sense)(sPAPRDRConnector *drc);
- uint32_t (*isolate)(sPAPRDRConnector *drc);
- uint32_t (*unisolate)(sPAPRDRConnector *drc);
+ SpaprDREntitySense (*dr_entity_sense)(SpaprDrc *drc);
+ uint32_t (*isolate)(SpaprDrc *drc);
+ uint32_t (*unisolate)(SpaprDrc *drc);
void (*release)(DeviceState *dev);
- int (*dt_populate)(sPAPRDRConnector *drc, struct sPAPRMachineState *spapr,
+ int (*dt_populate)(SpaprDrc *drc, struct SpaprMachineState *spapr,
void *fdt, int *fdt_start_offset, Error **errp);
-} sPAPRDRConnectorClass;
+} SpaprDrcClass;
-typedef struct sPAPRDRCPhysical {
+typedef struct SpaprDrcPhysical {
/*< private >*/
- sPAPRDRConnector parent;
+ SpaprDrc parent;
/* DR-indicator */
uint32_t dr_indicator;
-} sPAPRDRCPhysical;
+} SpaprDrcPhysical;
static inline bool spapr_drc_hotplugged(DeviceState *dev)
{
return dev->hotplugged && !runstate_check(RUN_STATE_INMIGRATE);
}
-void spapr_drc_reset(sPAPRDRConnector *drc);
+void spapr_drc_reset(SpaprDrc *drc);
-uint32_t spapr_drc_index(sPAPRDRConnector *drc);
-sPAPRDRConnectorType spapr_drc_type(sPAPRDRConnector *drc);
+uint32_t spapr_drc_index(SpaprDrc *drc);
+SpaprDrcType spapr_drc_type(SpaprDrc *drc);
-sPAPRDRConnector *spapr_dr_connector_new(Object *owner, const char *type,
+SpaprDrc *spapr_dr_connector_new(Object *owner, const char *type,
uint32_t id);
-sPAPRDRConnector *spapr_drc_by_index(uint32_t index);
-sPAPRDRConnector *spapr_drc_by_id(const char *type, uint32_t id);
+SpaprDrc *spapr_drc_by_index(uint32_t index);
+SpaprDrc *spapr_drc_by_id(const char *type, uint32_t id);
int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
uint32_t drc_type_mask);
-void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, Error **errp);
-void spapr_drc_detach(sPAPRDRConnector *drc);
+void spapr_drc_attach(SpaprDrc *drc, DeviceState *d, Error **errp);
+void spapr_drc_detach(SpaprDrc *drc);
bool spapr_drc_needed(void *opaque);
-static inline bool spapr_drc_unplug_requested(sPAPRDRConnector *drc)
+static inline bool spapr_drc_unplug_requested(SpaprDrc *drc)
{
return drc->unplug_requested;
}
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index ec1ee64fa6..b855f74e44 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -22,51 +22,51 @@
#define SPAPR_IRQ_MSI 0x1300 /* Offset of the dynamic range covered
* by the bitmap allocator */
-typedef struct sPAPRMachineState sPAPRMachineState;
+typedef struct SpaprMachineState SpaprMachineState;
-void spapr_irq_msi_init(sPAPRMachineState *spapr, uint32_t nr_msis);
-int spapr_irq_msi_alloc(sPAPRMachineState *spapr, uint32_t num, bool align,
+void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
+int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
Error **errp);
-void spapr_irq_msi_free(sPAPRMachineState *spapr, int irq, uint32_t num);
-void spapr_irq_msi_reset(sPAPRMachineState *spapr);
+void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num);
+void spapr_irq_msi_reset(SpaprMachineState *spapr);
-typedef struct sPAPRIrq {
+typedef struct SpaprIrq {
uint32_t nr_irqs;
uint32_t nr_msis;
uint8_t ov5;
- void (*init)(sPAPRMachineState *spapr, int nr_irqs, Error **errp);
- int (*claim)(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp);
- void (*free)(sPAPRMachineState *spapr, int irq, int num);
- qemu_irq (*qirq)(sPAPRMachineState *spapr, int irq);
- void (*print_info)(sPAPRMachineState *spapr, Monitor *mon);
- void (*dt_populate)(sPAPRMachineState *spapr, uint32_t nr_servers,
+ void (*init)(SpaprMachineState *spapr, int nr_irqs, Error **errp);
+ int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
+ void (*free)(SpaprMachineState *spapr, int irq, int num);
+ qemu_irq (*qirq)(SpaprMachineState *spapr, int irq);
+ void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
+ void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
void *fdt, uint32_t phandle);
- void (*cpu_intc_create)(sPAPRMachineState *spapr, PowerPCCPU *cpu,
+ void (*cpu_intc_create)(SpaprMachineState *spapr, PowerPCCPU *cpu,
Error **errp);
- int (*post_load)(sPAPRMachineState *spapr, int version_id);
- void (*reset)(sPAPRMachineState *spapr, Error **errp);
+ int (*post_load)(SpaprMachineState *spapr, int version_id);
+ void (*reset)(SpaprMachineState *spapr, Error **errp);
void (*set_irq)(void *opaque, int srcno, int val);
- const char *(*get_nodename)(sPAPRMachineState *spapr);
-} sPAPRIrq;
+ const char *(*get_nodename)(SpaprMachineState *spapr);
+} SpaprIrq;
-extern sPAPRIrq spapr_irq_xics;
-extern sPAPRIrq spapr_irq_xics_legacy;
-extern sPAPRIrq spapr_irq_xive;
-extern sPAPRIrq spapr_irq_dual;
+extern SpaprIrq spapr_irq_xics;
+extern SpaprIrq spapr_irq_xics_legacy;
+extern SpaprIrq spapr_irq_xive;
+extern SpaprIrq spapr_irq_dual;
-void spapr_irq_init(sPAPRMachineState *spapr, Error **errp);
-int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp);
-void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num);
-qemu_irq spapr_qirq(sPAPRMachineState *spapr, int irq);
-int spapr_irq_post_load(sPAPRMachineState *spapr, int version_id);
-void spapr_irq_reset(sPAPRMachineState *spapr, Error **errp);
-int spapr_irq_get_phandle(sPAPRMachineState *spapr, void *fdt, Error **errp);
+void spapr_irq_init(SpaprMachineState *spapr, Error **errp);
+int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
+void spapr_irq_free(SpaprMachineState *spapr, int irq, int num);
+qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq);
+int spapr_irq_post_load(SpaprMachineState *spapr, int version_id);
+void spapr_irq_reset(SpaprMachineState *spapr, Error **errp);
+int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp);
/*
* XICS legacy routines
*/
-int spapr_irq_find(sPAPRMachineState *spapr, int num, bool align, Error **errp);
+int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp);
#define spapr_irq_findone(spapr, errp) spapr_irq_find(spapr, 1, false, errp)
#endif
diff --git a/include/hw/ppc/spapr_ovec.h b/include/hw/ppc/spapr_ovec.h
index 0f2d8d715d..188a9367e2 100644
--- a/include/hw/ppc/spapr_ovec.h
+++ b/include/hw/ppc/spapr_ovec.h
@@ -39,7 +39,7 @@
#include "cpu.h"
#include "migration/vmstate.h"
-typedef struct sPAPROptionVector sPAPROptionVector;
+typedef struct SpaprOptionVector SpaprOptionVector;
#define OV_BIT(byte, bit) ((byte - 1) * BITS_PER_BYTE + bit)
@@ -61,21 +61,21 @@ typedef struct sPAPROptionVector sPAPROptionVector;
#define OV5_MMU_RADIX_GTSE OV_BIT(26, 1) /* Radix GTSE */
/* interfaces */
-sPAPROptionVector *spapr_ovec_new(void);
-sPAPROptionVector *spapr_ovec_clone(sPAPROptionVector *ov_orig);
-void spapr_ovec_intersect(sPAPROptionVector *ov,
- sPAPROptionVector *ov1,
- sPAPROptionVector *ov2);
-bool spapr_ovec_diff(sPAPROptionVector *ov,
- sPAPROptionVector *ov_old,
- sPAPROptionVector *ov_new);
-void spapr_ovec_cleanup(sPAPROptionVector *ov);
-void spapr_ovec_set(sPAPROptionVector *ov, long bitnr);
-void spapr_ovec_clear(sPAPROptionVector *ov, long bitnr);
-bool spapr_ovec_test(sPAPROptionVector *ov, long bitnr);
-sPAPROptionVector *spapr_ovec_parse_vector(target_ulong table_addr, int vector);
+SpaprOptionVector *spapr_ovec_new(void);
+SpaprOptionVector *spapr_ovec_clone(SpaprOptionVector *ov_orig);
+void spapr_ovec_intersect(SpaprOptionVector *ov,
+ SpaprOptionVector *ov1,
+ SpaprOptionVector *ov2);
+bool spapr_ovec_diff(SpaprOptionVector *ov,
+ SpaprOptionVector *ov_old,
+ SpaprOptionVector *ov_new);
+void spapr_ovec_cleanup(SpaprOptionVector *ov);
+void spapr_ovec_set(SpaprOptionVector *ov, long bitnr);
+void spapr_ovec_clear(SpaprOptionVector *ov, long bitnr);
+bool spapr_ovec_test(SpaprOptionVector *ov, long bitnr);
+SpaprOptionVector *spapr_ovec_parse_vector(target_ulong table_addr, int vector);
int spapr_ovec_populate_dt(void *fdt, int fdt_offset,
- sPAPROptionVector *ov, const char *name);
+ SpaprOptionVector *ov, const char *name);
/* migration */
extern const VMStateDescription vmstate_spapr_ovec;
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index e8b006d18f..04609f214e 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -26,91 +26,91 @@
#define TYPE_VIO_SPAPR_DEVICE "vio-spapr-device"
#define VIO_SPAPR_DEVICE(obj) \
- OBJECT_CHECK(VIOsPAPRDevice, (obj), TYPE_VIO_SPAPR_DEVICE)
+ OBJECT_CHECK(SpaprVioDevice, (obj), TYPE_VIO_SPAPR_DEVICE)
#define VIO_SPAPR_DEVICE_CLASS(klass) \
- OBJECT_CLASS_CHECK(VIOsPAPRDeviceClass, (klass), TYPE_VIO_SPAPR_DEVICE)
+ OBJECT_CLASS_CHECK(SpaprVioDeviceClass, (klass), TYPE_VIO_SPAPR_DEVICE)
#define VIO_SPAPR_DEVICE_GET_CLASS(obj) \
- OBJECT_GET_CLASS(VIOsPAPRDeviceClass, (obj), TYPE_VIO_SPAPR_DEVICE)
+ OBJECT_GET_CLASS(SpaprVioDeviceClass, (obj), TYPE_VIO_SPAPR_DEVICE)
#define TYPE_SPAPR_VIO_BUS "spapr-vio-bus"
-#define SPAPR_VIO_BUS(obj) OBJECT_CHECK(VIOsPAPRBus, (obj), TYPE_SPAPR_VIO_BUS)
+#define SPAPR_VIO_BUS(obj) OBJECT_CHECK(SpaprVioBus, (obj), TYPE_SPAPR_VIO_BUS)
#define TYPE_SPAPR_VIO_BRIDGE "spapr-vio-bridge"
-typedef struct VIOsPAPR_CRQ {
+typedef struct SpaprVioCrq {
uint64_t qladdr;
uint32_t qsize;
uint32_t qnext;
- int(*SendFunc)(struct VIOsPAPRDevice *vdev, uint8_t *crq);
-} VIOsPAPR_CRQ;
+ int(*SendFunc)(struct SpaprVioDevice *vdev, uint8_t *crq);
+} SpaprVioCrq;
-typedef struct VIOsPAPRDevice VIOsPAPRDevice;
-typedef struct VIOsPAPRBus VIOsPAPRBus;
+typedef struct SpaprVioDevice SpaprVioDevice;
+typedef struct SpaprVioBus SpaprVioBus;
-typedef struct VIOsPAPRDeviceClass {
+typedef struct SpaprVioDeviceClass {
DeviceClass parent_class;
const char *dt_name, *dt_type, *dt_compatible;
target_ulong signal_mask;
uint32_t rtce_window_size;
- void (*realize)(VIOsPAPRDevice *dev, Error **errp);
- void (*reset)(VIOsPAPRDevice *dev);
- int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off);
-} VIOsPAPRDeviceClass;
+ void (*realize)(SpaprVioDevice *dev, Error **errp);
+ void (*reset)(SpaprVioDevice *dev);
+ int (*devnode)(SpaprVioDevice *dev, void *fdt, int node_off);
+} SpaprVioDeviceClass;
-struct VIOsPAPRDevice {
+struct SpaprVioDevice {
DeviceState qdev;
uint32_t reg;
uint32_t irq;
uint64_t signal_state;
- VIOsPAPR_CRQ crq;
+ SpaprVioCrq crq;
AddressSpace as;
MemoryRegion mrroot;
MemoryRegion mrbypass;
- sPAPRTCETable *tcet;
+ SpaprTceTable *tcet;
};
#define DEFINE_SPAPR_PROPERTIES(type, field) \
DEFINE_PROP_UINT32("reg", type, field.reg, -1)
-struct VIOsPAPRBus {
+struct SpaprVioBus {
BusState bus;
uint32_t next_reg;
};
-extern VIOsPAPRBus *spapr_vio_bus_init(void);
-extern VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg);
-void spapr_dt_vdevice(VIOsPAPRBus *bus, void *fdt);
-extern gchar *spapr_vio_stdout_path(VIOsPAPRBus *bus);
+extern SpaprVioBus *spapr_vio_bus_init(void);
+extern SpaprVioDevice *spapr_vio_find_by_reg(SpaprVioBus *bus, uint32_t reg);
+void spapr_dt_vdevice(SpaprVioBus *bus, void *fdt);
+extern gchar *spapr_vio_stdout_path(SpaprVioBus *bus);
-static inline qemu_irq spapr_vio_qirq(VIOsPAPRDevice *dev)
+static inline qemu_irq spapr_vio_qirq(SpaprVioDevice *dev)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+ SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
return spapr_qirq(spapr, dev->irq);
}
-static inline bool spapr_vio_dma_valid(VIOsPAPRDevice *dev, uint64_t taddr,
+static inline bool spapr_vio_dma_valid(SpaprVioDevice *dev, uint64_t taddr,
uint32_t size, DMADirection dir)
{
return dma_memory_valid(&dev->as, taddr, size, dir);
}
-static inline int spapr_vio_dma_read(VIOsPAPRDevice *dev, uint64_t taddr,
+static inline int spapr_vio_dma_read(SpaprVioDevice *dev, uint64_t taddr,
void *buf, uint32_t size)
{
return (dma_memory_read(&dev->as, taddr, buf, size) != 0) ?
H_DEST_PARM : H_SUCCESS;
}
-static inline int spapr_vio_dma_write(VIOsPAPRDevice *dev, uint64_t taddr,
+static inline int spapr_vio_dma_write(SpaprVioDevice *dev, uint64_t taddr,
const void *buf, uint32_t size)
{
return (dma_memory_write(&dev->as, taddr, buf, size) != 0) ?
H_DEST_PARM : H_SUCCESS;
}
-static inline int spapr_vio_dma_set(VIOsPAPRDevice *dev, uint64_t taddr,
+static inline int spapr_vio_dma_set(SpaprVioDevice *dev, uint64_t taddr,
uint8_t c, uint32_t size)
{
return (dma_memory_set(&dev->as, taddr, c, size) != 0) ?
@@ -123,21 +123,21 @@ static inline int spapr_vio_dma_set(VIOsPAPRDevice *dev, uint64_t taddr,
#define vio_stq(_dev, _addr, _val) (stq_be_dma(&(_dev)->as, (_addr), (_val)))
#define vio_ldq(_dev, _addr) (ldq_be_dma(&(_dev)->as, (_addr)))
-int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq);
+int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq);
-VIOsPAPRDevice *vty_lookup(sPAPRMachineState *spapr, target_ulong reg);
-void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len);
-void spapr_vty_create(VIOsPAPRBus *bus, Chardev *chardev);
-void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd);
-void spapr_vscsi_create(VIOsPAPRBus *bus);
+SpaprVioDevice *vty_lookup(SpaprMachineState *spapr, target_ulong reg);
+void vty_putchars(SpaprVioDevice *sdev, uint8_t *buf, int len);
+void spapr_vty_create(SpaprVioBus *bus, Chardev *chardev);
+void spapr_vlan_create(SpaprVioBus *bus, NICInfo *nd);
+void spapr_vscsi_create(SpaprVioBus *bus);
-VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus);
+SpaprVioDevice *spapr_vty_get_default(SpaprVioBus *bus);
extern const VMStateDescription vmstate_spapr_vio;
#define VMSTATE_SPAPR_VIO(_f, _s) \
- VMSTATE_STRUCT(_f, _s, 0, vmstate_spapr_vio, VIOsPAPRDevice)
+ VMSTATE_STRUCT(_f, _s, 0, vmstate_spapr_vio, SpaprVioDevice)
-void spapr_vio_set_bypass(VIOsPAPRDevice *dev, bool bypass);
+void spapr_vio_set_bypass(SpaprVioDevice *dev, bool bypass);
#endif /* HW_SPAPR_VIO_H */
diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
index 2d31f24e3b..fc3e9652f9 100644
--- a/include/hw/ppc/spapr_xive.h
+++ b/include/hw/ppc/spapr_xive.h
@@ -13,9 +13,9 @@
#include "hw/ppc/xive.h"
#define TYPE_SPAPR_XIVE "spapr-xive"
-#define SPAPR_XIVE(obj) OBJECT_CHECK(sPAPRXive, (obj), TYPE_SPAPR_XIVE)
+#define SPAPR_XIVE(obj) OBJECT_CHECK(SpaprXive, (obj), TYPE_SPAPR_XIVE)
-typedef struct sPAPRXive {
+typedef struct SpaprXive {
XiveRouter parent;
/* Internal interrupt source for IPIs and virtual devices */
@@ -38,16 +38,16 @@ typedef struct sPAPRXive {
/* TIMA mapping address */
hwaddr tm_base;
MemoryRegion tm_mmio;
-} sPAPRXive;
+} SpaprXive;
-bool spapr_xive_irq_claim(sPAPRXive *xive, uint32_t lisn, bool lsi);
-bool spapr_xive_irq_free(sPAPRXive *xive, uint32_t lisn);
-void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon);
+bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi);
+bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn);
+void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
-void spapr_xive_hcall_init(sPAPRMachineState *spapr);
-void spapr_dt_xive(sPAPRMachineState *spapr, uint32_t nr_servers, void *fdt,
+void spapr_xive_hcall_init(SpaprMachineState *spapr);
+void spapr_dt_xive(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
uint32_t phandle);
void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx);
-void spapr_xive_mmio_set_enabled(sPAPRXive *xive, bool enable);
+void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable);
#endif /* PPC_SPAPR_XIVE_H */
diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
index b8d924baf4..15a8dcff66 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -31,9 +31,9 @@
#define XICS_NODENAME "interrupt-controller"
-void spapr_dt_xics(sPAPRMachineState *spapr, uint32_t nr_servers, void *fdt,
+void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
uint32_t phandle);
-int xics_kvm_init(sPAPRMachineState *spapr, Error **errp);
-void xics_spapr_init(sPAPRMachineState *spapr);
+int xics_kvm_init(SpaprMachineState *spapr, Error **errp);
+void xics_spapr_init(SpaprMachineState *spapr);
#endif /* XICS_SPAPR_H */
diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index 13a487527b..c4f27742ca 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -364,6 +364,7 @@ int xive_router_get_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
int xive_router_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
XiveNVT *nvt, uint8_t word_number);
XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, CPUState *cs);
+void xive_router_notify(XiveNotifier *xn, uint32_t lisn);
/*
* XIVE END ESBs
@@ -410,6 +411,9 @@ void xive_end_queue_pic_print_info(XiveEND *end, uint32_t width, Monitor *mon);
#define XIVE_TM_USER_PAGE 0x3
extern const MemoryRegionOps xive_tm_ops;
+void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,
+ unsigned size);
+uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size);
void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp);
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 17f09aac72..33ed3b8dde 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -431,8 +431,6 @@ const char *qdev_fw_name(DeviceState *dev);
Object *qdev_get_machine(void);
-void object_apply_compat_props(Object *obj);
-
/* FIXME: make this a link<> */
void qdev_set_parent_bus(DeviceState *dev, BusState *bus);
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 7624c9f511..1155b79678 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -148,6 +148,10 @@ typedef struct VFIODMABuf {
typedef struct VFIODisplay {
QemuConsole *con;
RAMFBState *ramfb;
+ struct vfio_region_info *edid_info;
+ struct vfio_region_gfx_edid *edid_regs;
+ uint8_t *edid_blob;
+ QEMUTimer *edid_link_timer;
struct {
VFIORegion buffer;
DisplaySurface *surface;
@@ -189,6 +193,8 @@ int vfio_get_region_info(VFIODevice *vbasedev, int index,
int vfio_get_dev_region_info(VFIODevice *vbasedev, uint32_t type,
uint32_t subtype, struct vfio_region_info **info);
bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type);
+struct vfio_info_cap_header *
+vfio_get_region_info_cap(struct vfio_region_info *info, uint16_t id);
#endif
extern const MemoryListener vfio_prereg_listener;
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 98504f9075..ce0ca72171 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -148,7 +148,6 @@ extern const GraphicHwOps virtio_gpu_ops;
} while (0)
/* virtio-gpu.c */
-void virtio_gpu_reset(VirtIODevice *vdev);
void virtio_gpu_ctrl_response(VirtIOGPU *g,
struct virtio_gpu_ctrl_command *cmd,
struct virtio_gpu_ctrl_hdr *resp,
diff --git a/include/qom/object.h b/include/qom/object.h
index e0262962b5..288cdddf44 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -677,6 +677,9 @@ Object *object_new_with_propv(const char *typename,
void object_apply_global_props(Object *obj, const GPtrArray *props,
Error **errp);
+void object_set_machine_compat_props(GPtrArray *compat_props);
+void object_set_accelerator_compat_props(GPtrArray *compat_props);
+void object_apply_compat_props(Object *obj);
/**
* object_set_props:
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 89604a8328..6065d9e420 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -110,7 +110,6 @@ extern int old_param;
extern int boot_menu;
extern bool boot_strict;
extern uint8_t *boot_splash_filedata;
-extern size_t boot_splash_filedata_size;
extern bool enable_mlock;
extern bool enable_cpu_pm;
extern QEMUClockType rtc_clock;
diff --git a/memory.c b/memory.c
index 61d66e4441..e49369d85d 100644
--- a/memory.c
+++ b/memory.c
@@ -932,9 +932,7 @@ static void address_space_update_topology_pass(AddressSpace *as,
} else if (frold && frnew && flatrange_equal(frold, frnew)) {
/* In both and unchanged (except logging may have changed) */
- if (!adding) {
- flat_range_coalesced_io_del(frold, as);
- } else {
+ if (adding) {
MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, region_nop);
if (frnew->dirty_log_mask & ~frold->dirty_log_mask) {
MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, log_start,
@@ -946,7 +944,6 @@ static void address_space_update_topology_pass(AddressSpace *as,
frold->dirty_log_mask,
frnew->dirty_log_mask);
}
- flat_range_coalesced_io_add(frnew, as);
}
++iold;
diff --git a/monitor.c b/monitor.c
index defa129319..72061d5bae 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2032,6 +2032,19 @@ static QAuthZList *find_auth(Monitor *mon, const char *name)
return QAUTHZ_LIST(obj);
}
+static bool warn_acl;
+static void hmp_warn_acl(void)
+{
+ if (warn_acl) {
+ return;
+ }
+ error_report("The acl_show, acl_reset, acl_policy, acl_add, acl_remove "
+ "commands are deprecated with no replacement. Authorization "
+ "for VNC should be performed using the pluggable QAuthZ "
+ "objects");
+ warn_acl = true;
+}
+
static void hmp_acl_show(Monitor *mon, const QDict *qdict)
{
const char *aclname = qdict_get_str(qdict, "aclname");
@@ -2039,6 +2052,8 @@ static void hmp_acl_show(Monitor *mon, const QDict *qdict)
QAuthZListRuleList *rules;
size_t i = 0;
+ hmp_warn_acl();
+
if (!auth) {
return;
}
@@ -2062,6 +2077,8 @@ static void hmp_acl_reset(Monitor *mon, const QDict *qdict)
const char *aclname = qdict_get_str(qdict, "aclname");
QAuthZList *auth = find_auth(mon, aclname);
+ hmp_warn_acl();
+
if (!auth) {
return;
}
@@ -2080,6 +2097,8 @@ static void hmp_acl_policy(Monitor *mon, const QDict *qdict)
int val;
Error *err = NULL;
+ hmp_warn_acl();
+
if (!auth) {
return;
}
@@ -2124,6 +2143,8 @@ static void hmp_acl_add(Monitor *mon, const QDict *qdict)
QAuthZListFormat format;
size_t i = 0;
+ hmp_warn_acl();
+
if (!auth) {
return;
}
@@ -2169,6 +2190,8 @@ static void hmp_acl_remove(Monitor *mon, const QDict *qdict)
QAuthZList *auth = find_auth(mon, aclname);
ssize_t i = 0;
+ hmp_warn_acl();
+
if (!auth) {
return;
}
diff --git a/pc-bios/u-boot.e500 b/pc-bios/u-boot.e500
index 25537f8fe3..732660f348 100644
--- a/pc-bios/u-boot.e500
+++ b/pc-bios/u-boot.e500
Binary files differ
diff --git a/qapi/char.json b/qapi/char.json
index 77ed847972..a6e81ac7bc 100644
--- a/qapi/char.json
+++ b/qapi/char.json
@@ -248,6 +248,11 @@
# @addr: socket address to listen on (server=true)
# or connect to (server=false)
# @tls-creds: the ID of the TLS credentials object (since 2.6)
+# @tls-authz: the ID of the QAuthZ authorization object against which
+# the client's x509 distinguished name will be validated. This
+# object is only resolved at time of use, so can be deleted
+# and recreated on the fly while the chardev server is active.
+# If missing, it will default to denying access (since 4.0)
# @server: create server socket (default: true)
# @wait: wait for incoming connection on server
# sockets (default: false).
@@ -268,6 +273,7 @@
{ 'struct': 'ChardevSocket',
'data': { 'addr': 'SocketAddressLegacy',
'*tls-creds': 'str',
+ '*tls-authz' : 'str',
'*server': 'bool',
'*wait': 'bool',
'*nodelay': 'bool',
diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi
index 45c57952da..1e15f57e9c 100644
--- a/qemu-deprecated.texi
+++ b/qemu-deprecated.texi
@@ -60,6 +60,11 @@ Support for invalid topologies will be removed, the user must ensure
topologies described with -smp include all possible cpus, i.e.
@math{@var{sockets} * @var{cores} * @var{threads} = @var{maxcpus}}.
+@subsection -vnc acl (since 4.0.0)
+
+The @code{acl} option to the @code{-vnc} argument has been replaced
+by the @code{tls-authz} and @code{sasl-authz} options.
+
@section QEMU Machine Protocol (QMP) commands
@subsection block-dirty-bitmap-add "autoload" parameter (since 2.12.0)
@@ -99,6 +104,12 @@ The @option{[hub_id name]} parameter tuple of the 'hostfwd_add' and
Use ``device_add'' for hotplugging vCPUs instead of ``cpu-add''. See
documentation of ``query-hotpluggable-cpus'' for additional details.
+@subsection acl_show, acl_reset, acl_policy, acl_add, acl_remove (since 4.0.0)
+
+The ``acl_show'', ``acl_reset'', ``acl_policy'', ``acl_add'', and
+``acl_remove'' commands are deprecated with no replacement. Authorization
+for VNC should be performed using the pluggable QAuthZ objects.
+
@section System emulator devices
@subsection bluetooth (since 3.1)
diff --git a/qemu-options.hx b/qemu-options.hx
index 1cf9aac1fe..7118d90352 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1624,6 +1624,14 @@ will cause the VNC server socket to enable the VeNCrypt auth
mechanism. The credentials should have been previously created
using the @option{-object tls-creds} argument.
+@item tls-authz=@var{ID}
+
+Provides the ID of the QAuthZ authorization object against which
+the client's x509 distinguished name will validated. This object is
+only resolved at time of use, so can be deleted and recreated on the
+fly while the VNC server is active. If missing, it will default
+to denying access.
+
@item sasl
Require that the client use SASL to authenticate with the VNC server.
@@ -1639,18 +1647,25 @@ ensures a data encryption preventing compromise of authentication
credentials. See the @ref{vnc_security} section for details on using
SASL authentication.
+@item sasl-authz=@var{ID}
+
+Provides the ID of the QAuthZ authorization object against which
+the client's SASL username will validated. This object is
+only resolved at time of use, so can be deleted and recreated on the
+fly while the VNC server is active. If missing, it will default
+to denying access.
+
@item acl
-Turn on access control lists for checking of the x509 client certificate
-and SASL party. For x509 certs, the ACL check is made against the
-certificate's distinguished name. This is something that looks like
-@code{C=GB,O=ACME,L=Boston,CN=bob}. For SASL party, the ACL check is
-made against the username, which depending on the SASL plugin, may
-include a realm component, eg @code{bob} or @code{bob@@EXAMPLE.COM}.
-When the @option{acl} flag is set, the initial access list will be
-empty, with a @code{deny} policy. Thus no one will be allowed to
-use the VNC server until the ACLs have been loaded. This can be
-achieved using the @code{acl} monitor command.
+Legacy method for enabling authorization of clients against the
+x509 distinguished name and SASL username. It results in the creation
+of two @code{authz-list} objects with IDs of @code{vnc.username} and
+@code{vnc.x509dname}. The rules for these objects must be configured
+with the HMP ACL commands.
+
+This option is deprecated and should no longer be used. The new
+@option{sasl-authz} and @option{tls-authz} options are a
+replacement.
@item lossy
@@ -2413,7 +2428,7 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
"-chardev null,id=id[,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
"-chardev socket,id=id[,host=host],port=port[,to=to][,ipv4][,ipv6][,nodelay][,reconnect=seconds]\n"
" [,server][,nowait][,telnet][,websocket][,reconnect=seconds][,mux=on|off]\n"
- " [,logfile=PATH][,logappend=on|off][,tls-creds=ID] (tcp)\n"
+ " [,logfile=PATH][,logappend=on|off][,tls-creds=ID][,tls-authz=ID] (tcp)\n"
"-chardev socket,id=id,path=path[,server][,nowait][,telnet][,websocket][,reconnect=seconds]\n"
" [,mux=on|off][,logfile=PATH][,logappend=on|off] (unix)\n"
"-chardev udp,id=id[,host=host],port=port[,localaddr=localaddr]\n"
@@ -2542,7 +2557,7 @@ The available backends are:
A void device. This device will not emit any data, and will drop any data it
receives. The null backend does not take any options.
-@item -chardev socket,id=@var{id}[,@var{TCP options} or @var{unix options}][,server][,nowait][,telnet][,websocket][,reconnect=@var{seconds}][,tls-creds=@var{id}]
+@item -chardev socket,id=@var{id}[,@var{TCP options} or @var{unix options}][,server][,nowait][,telnet][,websocket][,reconnect=@var{seconds}][,tls-creds=@var{id}][,tls-authz=@var{id}]
Create a two-way stream socket, which can be either a TCP or a unix socket. A
unix socket will be created if @option{path} is specified. Behaviour is
@@ -2568,6 +2583,12 @@ and specifies the id of the TLS credentials to use for the handshake. The
credentials must be previously created with the @option{-object tls-creds}
argument.
+@option{tls-auth} provides the ID of the QAuthZ authorization object against
+which the client's x509 distinguished name will be validated. This object is
+only resolved at time of use, so can be deleted and recreated on the fly
+while the chardev server is active. If missing, it will default to denying
+access.
+
TCP and unix socket options are given below:
@table @option
diff --git a/qom/cpu.c b/qom/cpu.c
index f5579b1cd5..a8d2958956 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -380,6 +380,9 @@ static void cpu_common_initfn(Object *obj)
static void cpu_common_finalize(Object *obj)
{
+ CPUState *cpu = CPU(obj);
+
+ qemu_mutex_destroy(&cpu->work_mutex);
}
static int64_t cpu_common_get_arch_id(CPUState *cpu)
diff --git a/qom/object.c b/qom/object.c
index 05a8567041..e3206d6799 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -408,6 +408,45 @@ void object_apply_global_props(Object *obj, const GPtrArray *props, Error **errp
}
}
+/*
+ * Global property defaults
+ * Slot 0: accelerator's global property defaults
+ * Slot 1: machine's global property defaults
+ * Each is a GPtrArray of of GlobalProperty.
+ * Applied in order, later entries override earlier ones.
+ */
+static GPtrArray *object_compat_props[2];
+
+/*
+ * Set machine's global property defaults to @compat_props.
+ * May be called at most once.
+ */
+void object_set_machine_compat_props(GPtrArray *compat_props)
+{
+ assert(!object_compat_props[1]);
+ object_compat_props[1] = compat_props;
+}
+
+/*
+ * Set accelerator's global property defaults to @compat_props.
+ * May be called at most once.
+ */
+void object_set_accelerator_compat_props(GPtrArray *compat_props)
+{
+ assert(!object_compat_props[0]);
+ object_compat_props[0] = compat_props;
+}
+
+void object_apply_compat_props(Object *obj)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(object_compat_props); i++) {
+ object_apply_global_props(obj, object_compat_props[i],
+ &error_abort);
+ }
+}
+
static void object_initialize_with_type(void *data, size_t size, TypeImpl *type)
{
Object *obj = data;
diff --git a/roms/u-boot b/roms/u-boot
-Subproject d85ca029f257b53a96da6c2fb421e78a003a994
+Subproject d3689267f92c5956e09cc7d1baa4700141662bf
diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py
index 690827e6fc..f2a305c42e 100644
--- a/scripts/qemu-gdb.py
+++ b/scripts/qemu-gdb.py
@@ -7,11 +7,8 @@
# Authors:
# Avi Kivity <avi@redhat.com>
#
-# This work is licensed under the terms of the GNU GPL, version 2. See
-# the COPYING file in the top-level directory.
-#
-# Contributions after 2012-01-13 are licensed under the terms of the
-# GNU GPL, version 2 or (at your option) any later version.
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
# Usage:
# At the (gdb) prompt, type "source scripts/qemu-gdb.py".
diff --git a/scripts/qemugdb/coroutine.py b/scripts/qemugdb/coroutine.py
index 81f811ac00..41e079d0e2 100644
--- a/scripts/qemugdb/coroutine.py
+++ b/scripts/qemugdb/coroutine.py
@@ -7,11 +7,8 @@
# Authors:
# Avi Kivity <avi@redhat.com>
#
-# This work is licensed under the terms of the GNU GPL, version 2. See
-# the COPYING file in the top-level directory.
-#
-# Contributions after 2012-01-13 are licensed under the terms of the
-# GNU GPL, version 2 or (at your option) any later version.
+# This work is licensed under the terms of the GNU GPL, version 2
+# or later. See the COPYING file in the top-level directory.
import gdb
diff --git a/scripts/qemugdb/mtree.py b/scripts/qemugdb/mtree.py
index e6791b7885..3030a60d3f 100644
--- a/scripts/qemugdb/mtree.py
+++ b/scripts/qemugdb/mtree.py
@@ -7,11 +7,8 @@
# Authors:
# Avi Kivity <avi@redhat.com>
#
-# This work is licensed under the terms of the GNU GPL, version 2. See
-# the COPYING file in the top-level directory.
-#
-# Contributions after 2012-01-13 are licensed under the terms of the
-# GNU GPL, version 2 or (at your option) any later version.
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
# 'qemu mtree' -- display the memory hierarchy
diff --git a/scripts/qemugdb/tcg.py b/scripts/qemugdb/tcg.py
index 8c7f1d7454..18880fc9a7 100644
--- a/scripts/qemugdb/tcg.py
+++ b/scripts/qemugdb/tcg.py
@@ -8,11 +8,8 @@
# Authors:
# Alex Bennée <alex.bennee@linaro.org>
#
-# This work is licensed under the terms of the GNU GPL, version 2. See
-# the COPYING file in the top-level directory.
-#
-# Contributions after 2012-01-13 are licensed under the terms of the
-# GNU GPL, version 2 or (at your option) any later version.
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
# 'qemu tcg-lock-status' -- display the TCG lock status across threads
diff --git a/target/i386/Makefile.objs b/target/i386/Makefile.objs
index cb9c265525..48e0c28434 100644
--- a/target/i386/Makefile.objs
+++ b/target/i386/Makefile.objs
@@ -3,10 +3,10 @@ obj-$(CONFIG_TCG) += translate.o
obj-$(CONFIG_TCG) += bpt_helper.o cc_helper.o excp_helper.o fpu_helper.o
obj-$(CONFIG_TCG) += int_helper.o mem_helper.o misc_helper.o mpx_helper.o
obj-$(CONFIG_TCG) += seg_helper.o smm_helper.o svm_helper.o
+obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
ifeq ($(CONFIG_SOFTMMU),y)
obj-y += machine.o arch_memory_mapping.o arch_dump.o monitor.o
obj-$(CONFIG_KVM) += kvm.o
-obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
obj-$(CONFIG_HYPERV) += hyperv.o
obj-$(call lnot,$(CONFIG_HYPERV)) += hyperv-stub.o
ifeq ($(CONFIG_WIN32),y)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index d3aa6a815b..d90c01a059 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5031,6 +5031,13 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
x86_cpu_adjust_feat_level(cpu, FEAT_C000_0001_EDX);
x86_cpu_adjust_feat_level(cpu, FEAT_SVM);
x86_cpu_adjust_feat_level(cpu, FEAT_XSAVE);
+
+ /* Intel Processor Trace requires CPUID[0x14] */
+ if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) &&
+ kvm_enabled() && cpu->intel_pt_auto_level) {
+ x86_cpu_adjust_level(cpu, &cpu->env.cpuid_min_level, 0x14);
+ }
+
/* SVM requires CPUID[0x8000000A] */
if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000000A);
@@ -5824,6 +5831,8 @@ static Property x86_cpu_properties[] = {
DEFINE_PROP_INT32("x-hv-max-vps", X86CPU, hv_max_vps, -1),
DEFINE_PROP_BOOL("x-hv-synic-kvm-only", X86CPU, hyperv_synic_kvm_only,
false),
+ DEFINE_PROP_BOOL("x-intel-pt-auto-level", X86CPU, intel_pt_auto_level,
+ true),
DEFINE_PROP_END_OF_LIST()
};
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 95112b9118..83fb522554 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1454,6 +1454,9 @@ struct X86CPU {
/* Enable auto level-increase for all CPUID leaves */
bool full_cpuid_auto_level;
+ /* Enable auto level-increase for Intel Processor Trace leave */
+ bool intel_pt_auto_level;
+
/* if true fill the top bits of the MTRR_PHYSMASKn variable range */
bool fill_mtrr_mask;
diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
index ae51fe754e..be9b4c30c3 100644
--- a/target/ppc/cpu-qom.h
+++ b/target/ppc/cpu-qom.h
@@ -190,6 +190,7 @@ typedef struct PowerPCCPUClass {
#endif
const PPCHash64Options *hash64_opts;
struct ppc_radix_page_info *radix_page_info;
+ uint32_t lrg_decr_bits;
void (*init_proc)(CPUPPCState *env);
int (*check_pow)(CPUPPCState *env);
int (*handle_mmu_fault)(PowerPCCPU *cpu, vaddr eaddr, int rwx, int mmu_idx);
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 26604ddf98..fc12b4688e 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1321,10 +1321,10 @@ uint32_t cpu_ppc_load_atbu (CPUPPCState *env);
void cpu_ppc_store_atbl (CPUPPCState *env, uint32_t value);
void cpu_ppc_store_atbu (CPUPPCState *env, uint32_t value);
bool ppc_decr_clear_on_delivery(CPUPPCState *env);
-uint32_t cpu_ppc_load_decr (CPUPPCState *env);
-void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value);
-uint32_t cpu_ppc_load_hdecr (CPUPPCState *env);
-void cpu_ppc_store_hdecr (CPUPPCState *env, uint32_t value);
+target_ulong cpu_ppc_load_decr(CPUPPCState *env);
+void cpu_ppc_store_decr(CPUPPCState *env, target_ulong value);
+target_ulong cpu_ppc_load_hdecr(CPUPPCState *env);
+void cpu_ppc_store_hdecr(CPUPPCState *env, target_ulong value);
uint64_t cpu_ppc_load_purr (CPUPPCState *env);
uint32_t cpu_ppc601_load_rtcl (CPUPPCState *env);
uint32_t cpu_ppc601_load_rtcu (CPUPPCState *env);
@@ -2563,19 +2563,64 @@ static inline bool lsw_reg_in_range(int start, int nregs, int rx)
}
/* Accessors for FP, VMX and VSX registers */
+#if defined(HOST_WORDS_BIGENDIAN)
+#define VsrB(i) u8[i]
+#define VsrSB(i) s8[i]
+#define VsrH(i) u16[i]
+#define VsrSH(i) s16[i]
+#define VsrW(i) u32[i]
+#define VsrSW(i) s32[i]
+#define VsrD(i) u64[i]
+#define VsrSD(i) s64[i]
+#else
+#define VsrB(i) u8[15 - (i)]
+#define VsrSB(i) s8[15 - (i)]
+#define VsrH(i) u16[7 - (i)]
+#define VsrSH(i) s16[7 - (i)]
+#define VsrW(i) u32[3 - (i)]
+#define VsrSW(i) s32[3 - (i)]
+#define VsrD(i) u64[1 - (i)]
+#define VsrSD(i) s64[1 - (i)]
+#endif
+
+static inline int vsr64_offset(int i, bool high)
+{
+ return offsetof(CPUPPCState, vsr[i].VsrD(high ? 0 : 1));
+}
+
+static inline int vsr_full_offset(int i)
+{
+ return offsetof(CPUPPCState, vsr[i].u64[0]);
+}
+
+static inline int fpr_offset(int i)
+{
+ return vsr64_offset(i, true);
+}
+
static inline uint64_t *cpu_fpr_ptr(CPUPPCState *env, int i)
{
- return &env->vsr[i].u64[0];
+ return (uint64_t *)((uintptr_t)env + fpr_offset(i));
}
static inline uint64_t *cpu_vsrl_ptr(CPUPPCState *env, int i)
{
- return &env->vsr[i].u64[1];
+ return (uint64_t *)((uintptr_t)env + vsr64_offset(i, false));
+}
+
+static inline long avr64_offset(int i, bool high)
+{
+ return vsr64_offset(i + 32, high);
+}
+
+static inline int avr_full_offset(int i)
+{
+ return vsr_full_offset(i + 32);
}
static inline ppc_avr_t *cpu_avr_ptr(CPUPPCState *env, int i)
{
- return &env->vsr[32 + i];
+ return (ppc_avr_t *)((uintptr_t)env + avr_full_offset(i));
}
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 39bedbb11d..beafcf1ebd 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -107,6 +107,24 @@ static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp,
return POWERPC_EXCP_RESET;
}
+static uint64_t ppc_excp_vector_offset(CPUState *cs, int ail)
+{
+ uint64_t offset = 0;
+
+ switch (ail) {
+ case AIL_0001_8000:
+ offset = 0x18000;
+ break;
+ case AIL_C000_0000_0000_4000:
+ offset = 0xc000000000004000ull;
+ break;
+ default:
+ cpu_abort(cs, "Invalid AIL combination %d\n", ail);
+ break;
+ }
+
+ return offset;
+}
/* Note that this function should be greatly optimized
* when called with a constant excp, from ppc_hw_interrupt
@@ -708,17 +726,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
/* Handle AIL */
if (ail) {
new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
- switch(ail) {
- case AIL_0001_8000:
- vector |= 0x18000;
- break;
- case AIL_C000_0000_0000_4000:
- vector |= 0xc000000000004000ull;
- break;
- default:
- cpu_abort(cs, "Invalid AIL combination %d\n", ail);
- break;
- }
+ vector |= ppc_excp_vector_offset(cs, ail);
}
#if defined(TARGET_PPC64)
diff --git a/target/ppc/internal.h b/target/ppc/internal.h
index f26a71ffcf..fb6f64ed1e 100644
--- a/target/ppc/internal.h
+++ b/target/ppc/internal.h
@@ -204,35 +204,16 @@ EXTRACT_HELPER(IMM8, 11, 8);
EXTRACT_HELPER(DCMX, 16, 7);
EXTRACT_HELPER_SPLIT_3(DCMX_XV, 5, 16, 0, 1, 2, 5, 1, 6, 6);
-#if defined(HOST_WORDS_BIGENDIAN)
-#define VsrB(i) u8[i]
-#define VsrSB(i) s8[i]
-#define VsrH(i) u16[i]
-#define VsrSH(i) s16[i]
-#define VsrW(i) u32[i]
-#define VsrSW(i) s32[i]
-#define VsrD(i) u64[i]
-#define VsrSD(i) s64[i]
-#else
-#define VsrB(i) u8[15 - (i)]
-#define VsrSB(i) s8[15 - (i)]
-#define VsrH(i) u16[7 - (i)]
-#define VsrSH(i) s16[7 - (i)]
-#define VsrW(i) u32[3 - (i)]
-#define VsrSW(i) s32[3 - (i)]
-#define VsrD(i) u64[1 - (i)]
-#define VsrSD(i) s64[1 - (i)]
-#endif
static inline void getVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
{
- vsr->VsrD(0) = env->vsr[n].u64[0];
- vsr->VsrD(1) = env->vsr[n].u64[1];
+ vsr->VsrD(0) = env->vsr[n].VsrD(0);
+ vsr->VsrD(1) = env->vsr[n].VsrD(1);
}
static inline void putVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
{
- env->vsr[n].u64[0] = vsr->VsrD(0);
- env->vsr[n].u64[1] = vsr->VsrD(1);
+ env->vsr[n].VsrD(0) = vsr->VsrD(0);
+ env->vsr[n].VsrD(1) = vsr->VsrD(1);
}
void helper_compute_fprf_float16(CPUPPCState *env, float16 arg);
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index d01852fe31..2427c8ee13 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -90,7 +90,9 @@ static int cap_ppc_pvr_compat;
static int cap_ppc_safe_cache;
static int cap_ppc_safe_bounds_check;
static int cap_ppc_safe_indirect_branch;
+static int cap_ppc_count_cache_flush_assist;
static int cap_ppc_nested_kvm_hv;
+static int cap_large_decr;
static uint32_t debug_inst_opcode;
@@ -124,6 +126,7 @@ static bool kvmppc_is_pr(KVMState *ks)
static int kvm_ppc_register_host_cpu_type(MachineState *ms);
static void kvmppc_get_cpu_characteristics(KVMState *s);
+static int kvmppc_get_dec_bits(void);
int kvm_arch_init(MachineState *ms, KVMState *s)
{
@@ -151,6 +154,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
cap_resize_hpt = kvm_vm_check_extension(s, KVM_CAP_SPAPR_RESIZE_HPT);
kvmppc_get_cpu_characteristics(s);
cap_ppc_nested_kvm_hv = kvm_vm_check_extension(s, KVM_CAP_PPC_NESTED_HV);
+ cap_large_decr = kvmppc_get_dec_bits();
/*
* Note: setting it to false because there is not such capability
* in KVM at this moment.
@@ -752,7 +756,7 @@ static int kvm_get_fp(CPUState *cs)
static int kvm_get_vpa(CPUState *cs)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
- sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
struct kvm_one_reg reg;
int ret;
@@ -792,7 +796,7 @@ static int kvm_get_vpa(CPUState *cs)
static int kvm_put_vpa(CPUState *cs)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
- sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
struct kvm_one_reg reg;
int ret;
@@ -1593,70 +1597,93 @@ void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug *dbg)
}
}
-static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run)
+static int kvm_handle_hw_breakpoint(CPUState *cs,
+ struct kvm_debug_exit_arch *arch_info)
{
- CPUState *cs = CPU(cpu);
- CPUPPCState *env = &cpu->env;
- struct kvm_debug_exit_arch *arch_info = &run->debug.arch;
int handle = 0;
int n;
int flag = 0;
- if (cs->singlestep_enabled) {
- handle = 1;
- } else if (arch_info->status) {
- if (nb_hw_breakpoint + nb_hw_watchpoint > 0) {
- if (arch_info->status & KVMPPC_DEBUG_BREAKPOINT) {
- n = find_hw_breakpoint(arch_info->address, GDB_BREAKPOINT_HW);
- if (n >= 0) {
- handle = 1;
- }
- } else if (arch_info->status & (KVMPPC_DEBUG_WATCH_READ |
- KVMPPC_DEBUG_WATCH_WRITE)) {
- n = find_hw_watchpoint(arch_info->address, &flag);
- if (n >= 0) {
- handle = 1;
- cs->watchpoint_hit = &hw_watchpoint;
- hw_watchpoint.vaddr = hw_debug_points[n].addr;
- hw_watchpoint.flags = flag;
- }
+ if (nb_hw_breakpoint + nb_hw_watchpoint > 0) {
+ if (arch_info->status & KVMPPC_DEBUG_BREAKPOINT) {
+ n = find_hw_breakpoint(arch_info->address, GDB_BREAKPOINT_HW);
+ if (n >= 0) {
+ handle = 1;
+ }
+ } else if (arch_info->status & (KVMPPC_DEBUG_WATCH_READ |
+ KVMPPC_DEBUG_WATCH_WRITE)) {
+ n = find_hw_watchpoint(arch_info->address, &flag);
+ if (n >= 0) {
+ handle = 1;
+ cs->watchpoint_hit = &hw_watchpoint;
+ hw_watchpoint.vaddr = hw_debug_points[n].addr;
+ hw_watchpoint.flags = flag;
}
}
- } else if (kvm_find_sw_breakpoint(cs, arch_info->address)) {
- handle = 1;
- } else {
- /* QEMU is not able to handle debug exception, so inject
- * program exception to guest;
- * Yes program exception NOT debug exception !!
- * When QEMU is using debug resources then debug exception must
- * be always set. To achieve this we set MSR_DE and also set
- * MSRP_DEP so guest cannot change MSR_DE.
- * When emulating debug resource for guest we want guest
- * to control MSR_DE (enable/disable debug interrupt on need).
- * Supporting both configurations are NOT possible.
- * So the result is that we cannot share debug resources
- * between QEMU and Guest on BOOKE architecture.
- * In the current design QEMU gets the priority over guest,
- * this means that if QEMU is using debug resources then guest
- * cannot use them;
- * For software breakpoint QEMU uses a privileged instruction;
- * So there cannot be any reason that we are here for guest
- * set debug exception, only possibility is guest executed a
- * privileged / illegal instruction and that's why we are
- * injecting a program interrupt.
- */
+ }
+ return handle;
+}
- cpu_synchronize_state(cs);
- /* env->nip is PC, so increment this by 4 to use
- * ppc_cpu_do_interrupt(), which set srr0 = env->nip - 4.
- */
- env->nip += 4;
- cs->exception_index = POWERPC_EXCP_PROGRAM;
- env->error_code = POWERPC_EXCP_INVAL;
- ppc_cpu_do_interrupt(cs);
+static int kvm_handle_singlestep(void)
+{
+ return 1;
+}
+
+static int kvm_handle_sw_breakpoint(void)
+{
+ return 1;
+}
+
+static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run)
+{
+ CPUState *cs = CPU(cpu);
+ CPUPPCState *env = &cpu->env;
+ struct kvm_debug_exit_arch *arch_info = &run->debug.arch;
+
+ if (cs->singlestep_enabled) {
+ return kvm_handle_singlestep();
}
- return handle;
+ if (arch_info->status) {
+ return kvm_handle_hw_breakpoint(cs, arch_info);
+ }
+
+ if (kvm_find_sw_breakpoint(cs, arch_info->address)) {
+ return kvm_handle_sw_breakpoint();
+ }
+
+ /*
+ * QEMU is not able to handle debug exception, so inject
+ * program exception to guest;
+ * Yes program exception NOT debug exception !!
+ * When QEMU is using debug resources then debug exception must
+ * be always set. To achieve this we set MSR_DE and also set
+ * MSRP_DEP so guest cannot change MSR_DE.
+ * When emulating debug resource for guest we want guest
+ * to control MSR_DE (enable/disable debug interrupt on need).
+ * Supporting both configurations are NOT possible.
+ * So the result is that we cannot share debug resources
+ * between QEMU and Guest on BOOKE architecture.
+ * In the current design QEMU gets the priority over guest,
+ * this means that if QEMU is using debug resources then guest
+ * cannot use them;
+ * For software breakpoint QEMU uses a privileged instruction;
+ * So there cannot be any reason that we are here for guest
+ * set debug exception, only possibility is guest executed a
+ * privileged / illegal instruction and that's why we are
+ * injecting a program interrupt.
+ */
+ cpu_synchronize_state(cs);
+ /*
+ * env->nip is PC, so increment this by 4 to use
+ * ppc_cpu_do_interrupt(), which set srr0 = env->nip - 4.
+ */
+ env->nip += 4;
+ cs->exception_index = POWERPC_EXCP_PROGRAM;
+ env->error_code = POWERPC_EXCP_INVAL;
+ ppc_cpu_do_interrupt(cs);
+
+ return 0;
}
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
@@ -1927,6 +1954,16 @@ uint64_t kvmppc_get_clockfreq(void)
return kvmppc_read_int_cpu_dt("clock-frequency");
}
+static int kvmppc_get_dec_bits(void)
+{
+ int nr_bits = kvmppc_read_int_cpu_dt("ibm,dec-bits");
+
+ if (nr_bits > 0) {
+ return nr_bits;
+ }
+ return 0;
+}
+
static int kvmppc_get_pvinfo(CPUPPCState *env, struct kvm_ppc_pvinfo *pvinfo)
{
PowerPCCPU *cpu = ppc_env_get_cpu(env);
@@ -2007,6 +2044,11 @@ void kvmppc_enable_clear_ref_mod_hcalls(void)
kvmppc_enable_hcall(kvm_state, H_CLEAR_MOD);
}
+void kvmppc_enable_h_page_init(void)
+{
+ kvmppc_enable_hcall(kvm_state, H_PAGE_INIT);
+}
+
void kvmppc_set_papr(PowerPCCPU *cpu)
{
CPUState *cs = CPU(cpu);
@@ -2379,7 +2421,13 @@ static int parse_cap_ppc_safe_bounds_check(struct kvm_ppc_cpu_char c)
static int parse_cap_ppc_safe_indirect_branch(struct kvm_ppc_cpu_char c)
{
- if (c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) {
+ if ((~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_FLUSH_COUNT_CACHE) &&
+ (~c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) &&
+ (~c.character & c.character_mask & H_CPU_CHAR_BCCTRL_SERIALISED)) {
+ return SPAPR_CAP_FIXED_NA;
+ } else if (c.behaviour & c.behaviour_mask & H_CPU_BEHAV_FLUSH_COUNT_CACHE) {
+ return SPAPR_CAP_WORKAROUND;
+ } else if (c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) {
return SPAPR_CAP_FIXED_CCD;
} else if (c.character & c.character_mask & H_CPU_CHAR_BCCTRL_SERIALISED) {
return SPAPR_CAP_FIXED_IBS;
@@ -2388,6 +2436,14 @@ static int parse_cap_ppc_safe_indirect_branch(struct kvm_ppc_cpu_char c)
return 0;
}
+static int parse_cap_ppc_count_cache_flush_assist(struct kvm_ppc_cpu_char c)
+{
+ if (c.character & c.character_mask & H_CPU_CHAR_BCCTR_FLUSH_ASSIST) {
+ return 1;
+ }
+ return 0;
+}
+
static void kvmppc_get_cpu_characteristics(KVMState *s)
{
struct kvm_ppc_cpu_char c;
@@ -2410,6 +2466,8 @@ static void kvmppc_get_cpu_characteristics(KVMState *s)
cap_ppc_safe_cache = parse_cap_ppc_safe_cache(c);
cap_ppc_safe_bounds_check = parse_cap_ppc_safe_bounds_check(c);
cap_ppc_safe_indirect_branch = parse_cap_ppc_safe_indirect_branch(c);
+ cap_ppc_count_cache_flush_assist =
+ parse_cap_ppc_count_cache_flush_assist(c);
}
int kvmppc_get_cap_safe_cache(void)
@@ -2427,6 +2485,11 @@ int kvmppc_get_cap_safe_indirect_branch(void)
return cap_ppc_safe_indirect_branch;
}
+int kvmppc_get_cap_count_cache_flush_assist(void)
+{
+ return cap_ppc_count_cache_flush_assist;
+}
+
bool kvmppc_has_cap_nested_kvm_hv(void)
{
return !!cap_ppc_nested_kvm_hv;
@@ -2442,6 +2505,35 @@ bool kvmppc_has_cap_spapr_vfio(void)
return cap_spapr_vfio;
}
+int kvmppc_get_cap_large_decr(void)
+{
+ return cap_large_decr;
+}
+
+int kvmppc_enable_cap_large_decr(PowerPCCPU *cpu, int enable)
+{
+ CPUState *cs = CPU(cpu);
+ uint64_t lpcr;
+
+ kvm_get_one_reg(cs, KVM_REG_PPC_LPCR_64, &lpcr);
+ /* Do we need to modify the LPCR? */
+ if (!!(lpcr & LPCR_LD) != !!enable) {
+ if (enable) {
+ lpcr |= LPCR_LD;
+ } else {
+ lpcr &= ~LPCR_LD;
+ }
+ kvm_set_one_reg(cs, KVM_REG_PPC_LPCR_64, &lpcr);
+ kvm_get_one_reg(cs, KVM_REG_PPC_LPCR_64, &lpcr);
+
+ if (!!(lpcr & LPCR_LD) != !!enable) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void)
{
uint32_t host_pvr = mfpvr();
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index bdfaa4e70a..2c2ea30e87 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -23,6 +23,7 @@ int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level);
void kvmppc_enable_logical_ci_hcalls(void);
void kvmppc_enable_set_mode_hcall(void);
void kvmppc_enable_clear_ref_mod_hcalls(void);
+void kvmppc_enable_h_page_init(void);
void kvmppc_set_papr(PowerPCCPU *cpu);
int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr);
void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy);
@@ -62,8 +63,11 @@ bool kvmppc_has_cap_mmu_hash_v3(void);
int kvmppc_get_cap_safe_cache(void);
int kvmppc_get_cap_safe_bounds_check(void);
int kvmppc_get_cap_safe_indirect_branch(void);
+int kvmppc_get_cap_count_cache_flush_assist(void);
bool kvmppc_has_cap_nested_kvm_hv(void);
int kvmppc_set_cap_nested_kvm_hv(int enable);
+int kvmppc_get_cap_large_decr(void);
+int kvmppc_enable_cap_large_decr(PowerPCCPU *cpu, int enable);
int kvmppc_enable_hwrng(void);
int kvmppc_put_books_sregs(PowerPCCPU *cpu);
PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
@@ -135,6 +139,10 @@ static inline void kvmppc_enable_clear_ref_mod_hcalls(void)
{
}
+static inline void kvmppc_enable_h_page_init(void)
+{
+}
+
static inline void kvmppc_set_papr(PowerPCCPU *cpu)
{
}
@@ -322,6 +330,11 @@ static inline int kvmppc_get_cap_safe_indirect_branch(void)
return 0;
}
+static inline int kvmppc_get_cap_count_cache_flush_assist(void)
+{
+ return 0;
+}
+
static inline bool kvmppc_has_cap_nested_kvm_hv(void)
{
return false;
@@ -332,6 +345,16 @@ static inline int kvmppc_set_cap_nested_kvm_hv(int enable)
return -1;
}
+static inline int kvmppc_get_cap_large_decr(void)
+{
+ return 0;
+}
+
+static inline int kvmppc_enable_cap_large_decr(PowerPCCPU *cpu, int enable)
+{
+ return -1;
+}
+
static inline int kvmppc_enable_hwrng(void)
{
return -1;
diff --git a/target/ppc/machine.c b/target/ppc/machine.c
index 756b6d2971..a92d0ad3a3 100644
--- a/target/ppc/machine.c
+++ b/target/ppc/machine.c
@@ -150,7 +150,7 @@ static int get_fpr(QEMUFile *f, void *pv, size_t size,
{
ppc_vsr_t *v = pv;
- v->u64[0] = qemu_get_be64(f);
+ v->VsrD(0) = qemu_get_be64(f);
return 0;
}
@@ -160,7 +160,7 @@ static int put_fpr(QEMUFile *f, void *pv, size_t size,
{
ppc_vsr_t *v = pv;
- qemu_put_be64(f, v->u64[0]);
+ qemu_put_be64(f, v->VsrD(0));
return 0;
}
@@ -181,7 +181,7 @@ static int get_vsr(QEMUFile *f, void *pv, size_t size,
{
ppc_vsr_t *v = pv;
- v->u64[1] = qemu_get_be64(f);
+ v->VsrD(1) = qemu_get_be64(f);
return 0;
}
@@ -191,7 +191,7 @@ static int put_vsr(QEMUFile *f, void *pv, size_t size,
{
ppc_vsr_t *v = pv;
- qemu_put_be64(f, v->u64[1]);
+ qemu_put_be64(f, v->VsrD(1));
return 0;
}
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index c431303eff..a2b1ec5040 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -1109,7 +1109,7 @@ void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val)
case POWERPC_MMU_3_00: /* P9 */
lpcr = val & (LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
(LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
- LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR |
+ LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD |
(LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
LPCR_DEE | LPCR_OEE)) | LPCR_MER | LPCR_GTSE | LPCR_TC |
LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE);
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 819221f246..98b37cebc2 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -6677,34 +6677,22 @@ GEN_TM_PRIV_NOOP(trechkpt);
static inline void get_fpr(TCGv_i64 dst, int regno)
{
- tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState, vsr[regno].u64[0]));
+ tcg_gen_ld_i64(dst, cpu_env, fpr_offset(regno));
}
static inline void set_fpr(int regno, TCGv_i64 src)
{
- tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState, vsr[regno].u64[0]));
+ tcg_gen_st_i64(src, cpu_env, fpr_offset(regno));
}
static inline void get_avr64(TCGv_i64 dst, int regno, bool high)
{
-#ifdef HOST_WORDS_BIGENDIAN
- tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState,
- vsr[32 + regno].u64[(high ? 0 : 1)]));
-#else
- tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState,
- vsr[32 + regno].u64[(high ? 1 : 0)]));
-#endif
+ tcg_gen_ld_i64(dst, cpu_env, avr64_offset(regno, high));
}
static inline void set_avr64(int regno, TCGv_i64 src, bool high)
{
-#ifdef HOST_WORDS_BIGENDIAN
- tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState,
- vsr[32 + regno].u64[(high ? 0 : 1)]));
-#else
- tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState,
- vsr[32 + regno].u64[(high ? 1 : 0)]));
-#endif
+ tcg_gen_st_i64(src, cpu_env, avr64_offset(regno, high));
}
#include "translate/fp-impl.inc.c"
@@ -7417,7 +7405,7 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
#if !defined(NO_TIMER_DUMP)
cpu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
#if !defined(CONFIG_USER_ONLY)
- " DECR %08" PRIu32
+ " DECR " TARGET_FMT_lu
#endif
"\n",
cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c
index f1b15ae2cb..eb10c533ca 100644
--- a/target/ppc/translate/vmx-impl.inc.c
+++ b/target/ppc/translate/vmx-impl.inc.c
@@ -10,15 +10,10 @@
static inline TCGv_ptr gen_avr_ptr(int reg)
{
TCGv_ptr r = tcg_temp_new_ptr();
- tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, vsr[32 + reg].u64[0]));
+ tcg_gen_addi_ptr(r, cpu_env, avr_full_offset(reg));
return r;
}
-static inline long avr64_offset(int reg, bool high)
-{
- return offsetof(CPUPPCState, vsr[32 + reg].u64[(high ? 0 : 1)]);
-}
-
#define GEN_VR_LDX(name, opc2, opc3) \
static void glue(gen_, name)(DisasContext *ctx) \
{ \
@@ -205,7 +200,7 @@ static void gen_mtvscr(DisasContext *ctx)
}
val = tcg_temp_new_i32();
- bofs = avr64_offset(rB(ctx->opcode), true);
+ bofs = avr_full_offset(rB(ctx->opcode));
#ifdef HOST_WORDS_BIGENDIAN
bofs += 3 * 4;
#endif
@@ -284,9 +279,9 @@ static void glue(gen_, name)(DisasContext *ctx) \
} \
\
tcg_op(vece, \
- avr64_offset(rD(ctx->opcode), true), \
- avr64_offset(rA(ctx->opcode), true), \
- avr64_offset(rB(ctx->opcode), true), \
+ avr_full_offset(rD(ctx->opcode)), \
+ avr_full_offset(rA(ctx->opcode)), \
+ avr_full_offset(rB(ctx->opcode)), \
16, 16); \
}
@@ -578,10 +573,10 @@ static void glue(gen_, NAME)(DisasContext *ctx) \
gen_exception(ctx, POWERPC_EXCP_VPU); \
return; \
} \
- tcg_gen_gvec_4(avr64_offset(rD(ctx->opcode), true), \
+ tcg_gen_gvec_4(avr_full_offset(rD(ctx->opcode)), \
offsetof(CPUPPCState, vscr_sat), \
- avr64_offset(rA(ctx->opcode), true), \
- avr64_offset(rB(ctx->opcode), true), \
+ avr_full_offset(rA(ctx->opcode)), \
+ avr_full_offset(rB(ctx->opcode)), \
16, 16, &g); \
}
@@ -755,7 +750,7 @@ static void glue(gen_, name)(DisasContext *ctx) \
return; \
} \
simm = SIMM5(ctx->opcode); \
- tcg_op(avr64_offset(rD(ctx->opcode), true), 16, 16, simm); \
+ tcg_op(avr_full_offset(rD(ctx->opcode)), 16, 16, simm); \
}
GEN_VXFORM_DUPI(vspltisb, tcg_gen_gvec_dup8i, 6, 12);
@@ -850,8 +845,8 @@ static void gen_vsplt(DisasContext *ctx, int vece)
}
uimm = UIMM5(ctx->opcode);
- bofs = avr64_offset(rB(ctx->opcode), true);
- dofs = avr64_offset(rD(ctx->opcode), true);
+ bofs = avr_full_offset(rB(ctx->opcode));
+ dofs = avr_full_offset(rD(ctx->opcode));
/* Experimental testing shows that hardware masks the immediate. */
bofs += (uimm << vece) & 15;
diff --git a/target/ppc/translate/vsx-impl.inc.c b/target/ppc/translate/vsx-impl.inc.c
index e73197e717..508e9199c8 100644
--- a/target/ppc/translate/vsx-impl.inc.c
+++ b/target/ppc/translate/vsx-impl.inc.c
@@ -1,54 +1,23 @@
/*** VSX extension ***/
-static inline void get_vsr(TCGv_i64 dst, int n)
-{
- tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState, vsr[n].u64[1]));
-}
-
-static inline void set_vsr(int n, TCGv_i64 src)
-{
- tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState, vsr[n].u64[1]));
-}
-
-static inline int vsr_full_offset(int n)
-{
- return offsetof(CPUPPCState, vsr[n].u64[0]);
-}
-
static inline void get_cpu_vsrh(TCGv_i64 dst, int n)
{
- if (n < 32) {
- get_fpr(dst, n);
- } else {
- get_avr64(dst, n - 32, true);
- }
+ tcg_gen_ld_i64(dst, cpu_env, vsr64_offset(n, true));
}
static inline void get_cpu_vsrl(TCGv_i64 dst, int n)
{
- if (n < 32) {
- get_vsr(dst, n);
- } else {
- get_avr64(dst, n - 32, false);
- }
+ tcg_gen_ld_i64(dst, cpu_env, vsr64_offset(n, false));
}
static inline void set_cpu_vsrh(int n, TCGv_i64 src)
{
- if (n < 32) {
- set_fpr(n, src);
- } else {
- set_avr64(n - 32, src, true);
- }
+ tcg_gen_st_i64(src, cpu_env, vsr64_offset(n, true));
}
static inline void set_cpu_vsrl(int n, TCGv_i64 src)
{
- if (n < 32) {
- set_vsr(n, src);
- } else {
- set_avr64(n - 32, src, false);
- }
+ tcg_gen_st_i64(src, cpu_env, vsr64_offset(n, false));
}
#define VSX_LOAD_SCALAR(name, operation) \
@@ -1618,8 +1587,7 @@ static void gen_xsxsigdp(DisasContext *ctx)
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, zr, zr, t0);
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, nan, zr, t0);
get_cpu_vsrh(t1, xB(ctx->opcode));
- tcg_gen_andi_i64(rt, t1, 0x000FFFFFFFFFFFFF);
- tcg_gen_or_i64(rt, rt, t0);
+ tcg_gen_deposit_i64(rt, t0, t1, 0, 52);
tcg_temp_free_i64(t0);
tcg_temp_free_i64(t1);
@@ -1655,8 +1623,7 @@ static void gen_xsxsigqp(DisasContext *ctx)
tcg_gen_movi_i64(t0, 0x0001000000000000);
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, zr, zr, t0);
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, nan, zr, t0);
- tcg_gen_andi_i64(xth, xbh, 0x0000FFFFFFFFFFFF);
- tcg_gen_or_i64(xth, xth, t0);
+ tcg_gen_deposit_i64(xth, t0, xbh, 0, 48);
set_cpu_vsrh(rD(ctx->opcode) + 32, xth);
tcg_gen_mov_i64(xtl, xbl);
set_cpu_vsrl(rD(ctx->opcode) + 32, xtl);
@@ -1726,7 +1693,6 @@ static void gen_xviexpdp(DisasContext *ctx)
TCGv_i64 xal;
TCGv_i64 xbh;
TCGv_i64 xbl;
- TCGv_i64 t0;
if (unlikely(!ctx->vsx_enabled)) {
gen_exception(ctx, POWERPC_EXCP_VSXU);
@@ -1742,20 +1708,13 @@ static void gen_xviexpdp(DisasContext *ctx)
get_cpu_vsrl(xal, xA(ctx->opcode));
get_cpu_vsrh(xbh, xB(ctx->opcode));
get_cpu_vsrl(xbl, xB(ctx->opcode));
- t0 = tcg_temp_new_i64();
- tcg_gen_andi_i64(xth, xah, 0x800FFFFFFFFFFFFF);
- tcg_gen_andi_i64(t0, xbh, 0x7FF);
- tcg_gen_shli_i64(t0, t0, 52);
- tcg_gen_or_i64(xth, xth, t0);
+ tcg_gen_deposit_i64(xth, xah, xbh, 52, 11);
set_cpu_vsrh(xT(ctx->opcode), xth);
- tcg_gen_andi_i64(xtl, xal, 0x800FFFFFFFFFFFFF);
- tcg_gen_andi_i64(t0, xbl, 0x7FF);
- tcg_gen_shli_i64(t0, t0, 52);
- tcg_gen_or_i64(xtl, xtl, t0);
+
+ tcg_gen_deposit_i64(xtl, xal, xbl, 52, 11);
set_cpu_vsrl(xT(ctx->opcode), xtl);
- tcg_temp_free_i64(t0);
tcg_temp_free_i64(xth);
tcg_temp_free_i64(xtl);
tcg_temp_free_i64(xah);
@@ -1853,16 +1812,14 @@ static void gen_xvxsigdp(DisasContext *ctx)
tcg_gen_movi_i64(t0, 0x0010000000000000);
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, zr, zr, t0);
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, nan, zr, t0);
- tcg_gen_andi_i64(xth, xbh, 0x000FFFFFFFFFFFFF);
- tcg_gen_or_i64(xth, xth, t0);
+ tcg_gen_deposit_i64(xth, t0, xbh, 0, 52);
set_cpu_vsrh(xT(ctx->opcode), xth);
tcg_gen_extract_i64(exp, xbl, 52, 11);
tcg_gen_movi_i64(t0, 0x0010000000000000);
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, zr, zr, t0);
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, nan, zr, t0);
- tcg_gen_andi_i64(xtl, xbl, 0x000FFFFFFFFFFFFF);
- tcg_gen_or_i64(xtl, xtl, t0);
+ tcg_gen_deposit_i64(xth, t0, xbl, 0, 52);
set_cpu_vsrl(xT(ctx->opcode), xtl);
tcg_temp_free_i64(t0);
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 58542c0fe0..0bd555eb19 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -8376,6 +8376,7 @@ POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
#if defined(CONFIG_SOFTMMU)
pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
pcc->hash64_opts = &ppc_hash64_opts_basic;
+ pcc->lrg_decr_bits = 32;
#endif
pcc->excp_model = POWERPC_EXCP_970;
pcc->bus_model = PPC_FLAGS_INPUT_970;
@@ -8550,6 +8551,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
#if defined(CONFIG_SOFTMMU)
pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
pcc->hash64_opts = &ppc_hash64_opts_POWER7;
+ pcc->lrg_decr_bits = 32;
#endif
pcc->excp_model = POWERPC_EXCP_POWER7;
pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
@@ -8718,6 +8720,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
#if defined(CONFIG_SOFTMMU)
pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
pcc->hash64_opts = &ppc_hash64_opts_POWER7;
+ pcc->lrg_decr_bits = 32;
#endif
pcc->excp_model = POWERPC_EXCP_POWER8;
pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
@@ -8892,7 +8895,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
PPC_MEM_SYNC | PPC_MEM_EIEIO |
PPC_MEM_TLBSYNC |
- PPC_64B | PPC_64BX | PPC_ALTIVEC |
+ PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
PPC_SEGMENT_64B | PPC_SLBI |
PPC_POPCNTB | PPC_POPCNTWD |
PPC_CILDST;
@@ -8904,6 +8907,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL;
pcc->msr_mask = (1ull << MSR_SF) |
+ (1ull << MSR_SHV) |
(1ull << MSR_TM) |
(1ull << MSR_VR) |
(1ull << MSR_VSX) |
@@ -8926,6 +8930,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
/* segment page size remain the same */
pcc->hash64_opts = &ppc_hash64_opts_POWER7;
pcc->radix_page_info = &POWER9_radix_page_info;
+ pcc->lrg_decr_bits = 56;
#endif
pcc->excp_model = POWERPC_EXCP_POWER9;
pcc->bus_model = PPC_FLAGS_INPUT_POWER9;
diff --git a/target/s390x/Makefile.objs b/target/s390x/Makefile.objs
index 22a9a9927a..68eeee3d2f 100644
--- a/target/s390x/Makefile.objs
+++ b/target/s390x/Makefile.objs
@@ -1,6 +1,7 @@
obj-y += cpu.o cpu_models.o cpu_features.o gdbstub.o interrupt.o helper.o
obj-$(CONFIG_TCG) += translate.o cc_helper.o excp_helper.o fpu_helper.o
obj-$(CONFIG_TCG) += int_helper.o mem_helper.o misc_helper.o crypto_helper.o
+obj-$(CONFIG_TCG) += vec_helper.o
obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o diag.o
obj-$(CONFIG_SOFTMMU) += sigp.o
obj-$(CONFIG_KVM) += kvm.o
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index b71ac5183d..cb6d77053a 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -257,6 +257,7 @@ extern const struct VMStateDescription vmstate_s390_cpu;
/* PSW defines */
#undef PSW_MASK_PER
#undef PSW_MASK_UNUSED_2
+#undef PSW_MASK_UNUSED_3
#undef PSW_MASK_DAT
#undef PSW_MASK_IO
#undef PSW_MASK_EXT
@@ -276,6 +277,7 @@ extern const struct VMStateDescription vmstate_s390_cpu;
#define PSW_MASK_PER 0x4000000000000000ULL
#define PSW_MASK_UNUSED_2 0x2000000000000000ULL
+#define PSW_MASK_UNUSED_3 0x1000000000000000ULL
#define PSW_MASK_DAT 0x0400000000000000ULL
#define PSW_MASK_IO 0x0200000000000000ULL
#define PSW_MASK_EXT 0x0100000000000000ULL
@@ -323,12 +325,14 @@ extern const struct VMStateDescription vmstate_s390_cpu;
/* we'll use some unused PSW positions to store CR flags in tb flags */
#define FLAG_MASK_AFP (PSW_MASK_UNUSED_2 >> FLAG_MASK_PSW_SHIFT)
+#define FLAG_MASK_VECTOR (PSW_MASK_UNUSED_3 >> FLAG_MASK_PSW_SHIFT)
/* Control register 0 bits */
#define CR0_LOWPROT 0x0000000010000000ULL
#define CR0_SECONDARY 0x0000000004000000ULL
#define CR0_EDAT 0x0000000000800000ULL
#define CR0_AFP 0x0000000000040000ULL
+#define CR0_VECTOR 0x0000000000020000ULL
#define CR0_EMERGENCY_SIGNAL_SC 0x0000000000004000ULL
#define CR0_EXTERNAL_CALL_SC 0x0000000000002000ULL
#define CR0_CKC_SC 0x0000000000000800ULL
@@ -373,6 +377,9 @@ static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc,
if (env->cregs[0] & CR0_AFP) {
*flags |= FLAG_MASK_AFP;
}
+ if (env->cregs[0] & CR0_VECTOR) {
+ *flags |= FLAG_MASK_VECTOR;
+ }
}
/* PER bits from control register 9 */
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index bb659257f6..0b494a2fd2 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -123,6 +123,27 @@ DEF_HELPER_4(cu42, i32, env, i32, i32, i32)
DEF_HELPER_5(msa, i32, env, i32, i32, i32, i32)
DEF_HELPER_FLAGS_1(stpt, TCG_CALL_NO_RWG, i64, env)
DEF_HELPER_FLAGS_1(stck, TCG_CALL_NO_RWG_SE, i64, env)
+DEF_HELPER_FLAGS_3(probe_write_access, TCG_CALL_NO_WG, void, env, i64, i64)
+
+/* === Vector Support Instructions === */
+DEF_HELPER_FLAGS_4(vll, TCG_CALL_NO_WG, void, env, ptr, i64, i64)
+DEF_HELPER_FLAGS_4(gvec_vpk16, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_FLAGS_4(gvec_vpk32, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_FLAGS_4(gvec_vpk64, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_FLAGS_4(gvec_vpks16, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_FLAGS_4(gvec_vpks32, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_FLAGS_4(gvec_vpks64, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_5(gvec_vpks_cc16, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vpks_cc32, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vpks_cc64, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vpkls16, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_FLAGS_4(gvec_vpkls32, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_FLAGS_4(gvec_vpkls64, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_5(gvec_vpkls_cc16, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vpkls_cc32, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vpkls_cc64, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vperm, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, cptr, i32)
+DEF_HELPER_FLAGS_4(vstl, TCG_CALL_NO_WG, void, env, cptr, i64, i64)
#ifndef CONFIG_USER_ONLY
DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 61b750a855..71fa9b8d6c 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -972,6 +972,88 @@
D(0xb93e, KIMD, RRE, MSA, 0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_KIMD)
D(0xb93f, KLMD, RRE, MSA, 0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_KLMD)
+/* === Vector Support Instructions === */
+
+/* VECTOR GATHER ELEMENT */
+ E(0xe713, VGEF, VRV, V, la2, 0, 0, 0, vge, 0, ES_32, IF_VEC)
+ E(0xe712, VGEG, VRV, V, la2, 0, 0, 0, vge, 0, ES_64, IF_VEC)
+/* VECTOR GENERATE BYTE MASK */
+ F(0xe744, VGBM, VRI_a, V, 0, 0, 0, 0, vgbm, 0, IF_VEC)
+/* VECTOR GENERATE MASK */
+ F(0xe746, VGM, VRI_b, V, 0, 0, 0, 0, vgm, 0, IF_VEC)
+/* VECTOR LOAD */
+ F(0xe706, VL, VRX, V, la2, 0, 0, 0, vl, 0, IF_VEC)
+ F(0xe756, VLR, VRR_a, V, 0, 0, 0, 0, vlr, 0, IF_VEC)
+/* VECTOR LOAD AND REPLICATE */
+ F(0xe705, VLREP, VRX, V, la2, 0, 0, 0, vlrep, 0, IF_VEC)
+/* VECTOR LOAD ELEMENT */
+ E(0xe700, VLEB, VRX, V, la2, 0, 0, 0, vle, 0, ES_8, IF_VEC)
+ E(0xe701, VLEH, VRX, V, la2, 0, 0, 0, vle, 0, ES_16, IF_VEC)
+ E(0xe703, VLEF, VRX, V, la2, 0, 0, 0, vle, 0, ES_32, IF_VEC)
+ E(0xe702, VLEG, VRX, V, la2, 0, 0, 0, vle, 0, ES_64, IF_VEC)
+/* VECTOR LOAD ELEMENT IMMEDIATE */
+ E(0xe740, VLEIB, VRI_a, V, 0, 0, 0, 0, vlei, 0, ES_8, IF_VEC)
+ E(0xe741, VLEIH, VRI_a, V, 0, 0, 0, 0, vlei, 0, ES_16, IF_VEC)
+ E(0xe743, VLEIF, VRI_a, V, 0, 0, 0, 0, vlei, 0, ES_32, IF_VEC)
+ E(0xe742, VLEIG, VRI_a, V, 0, 0, 0, 0, vlei, 0, ES_64, IF_VEC)
+/* VECTOR LOAD GR FROM VR ELEMENT */
+ F(0xe721, VLGV, VRS_c, V, la2, 0, r1, 0, vlgv, 0, IF_VEC)
+/* VECTOR LOAD LOGICAL ELEMENT AND ZERO */
+ F(0xe704, VLLEZ, VRX, V, la2, 0, 0, 0, vllez, 0, IF_VEC)
+/* VECTOR LOAD MULTIPLE */
+ F(0xe736, VLM, VRS_a, V, la2, 0, 0, 0, vlm, 0, IF_VEC)
+/* VECTOR LOAD TO BLOCK BOUNDARY */
+ F(0xe707, VLBB, VRX, V, la2, 0, 0, 0, vlbb, 0, IF_VEC)
+/* VECTOR LOAD VR ELEMENT FROM GR */
+ F(0xe722, VLVG, VRS_b, V, la2, r3, 0, 0, vlvg, 0, IF_VEC)
+/* VECTOR LOAD VR FROM GRS DISJOINT */
+ F(0xe762, VLVGP, VRR_f, V, r2, r3, 0, 0, vlvgp, 0, IF_VEC)
+/* VECTOR LOAD WITH LENGTH */
+ F(0xe737, VLL, VRS_b, V, la2, r3_32u, 0, 0, vll, 0, IF_VEC)
+/* VECTOR MERGE HIGH */
+ F(0xe761, VMRH, VRR_c, V, 0, 0, 0, 0, vmr, 0, IF_VEC)
+/* VECTOR MERGE LOW */
+ F(0xe760, VMRL, VRR_c, V, 0, 0, 0, 0, vmr, 0, IF_VEC)
+/* VECTOR PACK */
+ F(0xe794, VPK, VRR_c, V, 0, 0, 0, 0, vpk, 0, IF_VEC)
+/* VECTOR PACK SATURATE */
+ F(0xe797, VPKS, VRR_b, V, 0, 0, 0, 0, vpk, 0, IF_VEC)
+/* VECTOR PACK LOGICAL SATURATE */
+ F(0xe795, VPKLS, VRR_b, V, 0, 0, 0, 0, vpk, 0, IF_VEC)
+ F(0xe78c, VPERM, VRR_e, V, 0, 0, 0, 0, vperm, 0, IF_VEC)
+/* VECTOR PERMUTE DOUBLEWORD IMMEDIATE */
+ F(0xe784, VPDI, VRR_c, V, 0, 0, 0, 0, vpdi, 0, IF_VEC)
+/* VECTOR REPLICATE */
+ F(0xe74d, VREP, VRI_c, V, 0, 0, 0, 0, vrep, 0, IF_VEC)
+/* VECTOR REPLICATE IMMEDIATE */
+ F(0xe745, VREPI, VRI_a, V, 0, 0, 0, 0, vrepi, 0, IF_VEC)
+/* VECTOR SCATTER ELEMENT */
+ E(0xe71b, VSCEF, VRV, V, la2, 0, 0, 0, vsce, 0, ES_32, IF_VEC)
+ E(0xe71a, VSCEG, VRV, V, la2, 0, 0, 0, vsce, 0, ES_64, IF_VEC)
+/* VECTOR SELECT */
+ F(0xe78d, VSEL, VRR_e, V, 0, 0, 0, 0, vsel, 0, IF_VEC)
+/* VECTOR SIGN EXTEND TO DOUBLEWORD */
+ F(0xe75f, VSEG, VRR_a, V, 0, 0, 0, 0, vseg, 0, IF_VEC)
+/* VECTOR STORE */
+ F(0xe70e, VST, VRX, V, la2, 0, 0, 0, vst, 0, IF_VEC)
+/* VECTOR STORE ELEMENT */
+ E(0xe708, VSTEB, VRX, V, la2, 0, 0, 0, vste, 0, ES_8, IF_VEC)
+ E(0xe709, VSTEH, VRX, V, la2, 0, 0, 0, vste, 0, ES_16, IF_VEC)
+ E(0xe70b, VSTEF, VRX, V, la2, 0, 0, 0, vste, 0, ES_32, IF_VEC)
+ E(0xe70a, VSTEG, VRX, V, la2, 0, 0, 0, vste, 0, ES_64, IF_VEC)
+/* VECTOR STORE MULTIPLE */
+ F(0xe73e, VSTM, VRS_a, V, la2, 0, 0, 0, vstm, 0, IF_VEC)
+/* VECTOR STORE WITH LENGTH */
+ F(0xe73f, VSTL, VRS_b, V, la2, r3_32u, 0, 0, vstl, 0, IF_VEC)
+/* VECTOR UNPACK HIGH */
+ F(0xe7d7, VUPH, VRR_a, V, 0, 0, 0, 0, vup, 0, IF_VEC)
+/* VECTOR UNPACK LOGICAL HIGH */
+ F(0xe7d5, VUPLH, VRR_a, V, 0, 0, 0, 0, vup, 0, IF_VEC)
+/* VECTOR UNPACK LOW */
+ F(0xe7d6, VUPL, VRR_a, V, 0, 0, 0, 0, vup, 0, IF_VEC)
+/* VECTOR UNPACK LOGICAL LOW */
+ F(0xe7d4, VUPLL, VRR_a, V, 0, 0, 0, 0, vup, 0, IF_VEC)
+
#ifndef CONFIG_USER_ONLY
/* COMPARE AND SWAP AND PURGE */
E(0xb250, CSP, RRE, Z, r1_32u, ra2, r1_P, 0, csp, 0, MO_TEUL, IF_PRIV)
diff --git a/target/s390x/insn-format.def b/target/s390x/insn-format.def
index 4297ff4165..6253edbd19 100644
--- a/target/s390x/insn-format.def
+++ b/target/s390x/insn-format.def
@@ -54,3 +54,28 @@ F4(SS_e, R(1, 8), BD(2,16,20), R(3,12), BD(4,32,36))
F3(SS_f, BD(1,16,20), L(2,8,8), BD(2,32,36))
F2(SSE, BD(1,16,20), BD(2,32,36))
F3(SSF, BD(1,16,20), BD(2,32,36), R(3,8))
+F3(VRI_a, V(1,8), I(2,16,16), M(3,32))
+F4(VRI_b, V(1,8), I(2,16,8), I(3,24,8), M(4,32))
+F4(VRI_c, V(1,8), V(3,12), I(2,16,16), M(4,32))
+F5(VRI_d, V(1,8), V(2,12), V(3,16), I(4,24,8), M(5,32))
+F5(VRI_e, V(1,8), V(2,12), I(3,16,12), M(5,28), M(4,32))
+F5(VRI_f, V(1,8), V(2,12), V(3,16), M(5,24), I(4,28,8))
+F5(VRI_g, V(1,8), V(2,12), I(4,16,8), M(5,24), I(3,28,8))
+F3(VRI_h, V(1,8), I(2,16,16), I(3,32,4))
+F4(VRI_i, V(1,8), R(2,12), M(4,24), I(3,28,8))
+F5(VRR_a, V(1,8), V(2,12), M(5,24), M(4,28), M(3,32))
+F5(VRR_b, V(1,8), V(2,12), V(3,16), M(5,24), M(4,32))
+F6(VRR_c, V(1,8), V(2,12), V(3,16), M(6,24), M(5,28), M(4,32))
+F6(VRR_d, V(1,8), V(2,12), V(3,16), M(5,20), M(6,24), V(4,32))
+F6(VRR_e, V(1,8), V(2,12), V(3,16), M(6,20), M(5,28), V(4,32))
+F3(VRR_f, V(1,8), R(2,12), R(3,16))
+F1(VRR_g, V(1,12))
+F3(VRR_h, V(1,12), V(2,16), M(3,24))
+F3(VRR_i, R(1,8), V(2,12), M(3,24))
+F4(VRS_a, V(1,8), V(3,12), BD(2,16,20), M(4,32))
+F4(VRS_b, V(1,8), R(3,12), BD(2,16,20), M(4,32))
+F4(VRS_c, R(1,8), V(3,12), BD(2,16,20), M(4,32))
+F3(VRS_d, R(3,12), BD(2,16,20), V(1,32))
+F4(VRV, V(1,8), V(2,12), BD(2,16,20), M(3,32))
+F3(VRX, V(1,8), BXD(2), M(3,32))
+F3(VSI, I(3,8,8), BD(2,16,20), V(1,32))
diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index 7baf0e2404..3b4855c175 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -63,45 +63,7 @@ typedef struct LowCore {
PSW program_new_psw; /* 0x1d0 */
PSW mcck_new_psw; /* 0x1e0 */
PSW io_new_psw; /* 0x1f0 */
- PSW return_psw; /* 0x200 */
- uint8_t irb[64]; /* 0x210 */
- uint64_t sync_enter_timer; /* 0x250 */
- uint64_t async_enter_timer; /* 0x258 */
- uint64_t exit_timer; /* 0x260 */
- uint64_t last_update_timer; /* 0x268 */
- uint64_t user_timer; /* 0x270 */
- uint64_t system_timer; /* 0x278 */
- uint64_t last_update_clock; /* 0x280 */
- uint64_t steal_clock; /* 0x288 */
- PSW return_mcck_psw; /* 0x290 */
- uint8_t pad9[0xc00 - 0x2a0]; /* 0x2a0 */
- /* System info area */
- uint64_t save_area[16]; /* 0xc00 */
- uint8_t pad10[0xd40 - 0xc80]; /* 0xc80 */
- uint64_t kernel_stack; /* 0xd40 */
- uint64_t thread_info; /* 0xd48 */
- uint64_t async_stack; /* 0xd50 */
- uint64_t kernel_asce; /* 0xd58 */
- uint64_t user_asce; /* 0xd60 */
- uint64_t panic_stack; /* 0xd68 */
- uint64_t user_exec_asce; /* 0xd70 */
- uint8_t pad11[0xdc0 - 0xd78]; /* 0xd78 */
-
- /* SMP info area: defined by DJB */
- uint64_t clock_comparator; /* 0xdc0 */
- uint64_t ext_call_fast; /* 0xdc8 */
- uint64_t percpu_offset; /* 0xdd0 */
- uint64_t current_task; /* 0xdd8 */
- uint32_t softirq_pending; /* 0xde0 */
- uint32_t pad_0x0de4; /* 0xde4 */
- uint64_t int_clock; /* 0xde8 */
- uint8_t pad12[0xe00 - 0xdf0]; /* 0xdf0 */
-
- /* 0xe00 is used as indicator for dump tools */
- /* whether the kernel died with panic() or not */
- uint32_t panic_magic; /* 0xe00 */
-
- uint8_t pad13[0x11b0 - 0xe04]; /* 0xe04 */
+ uint8_t pad13[0x11b0 - 0x200]; /* 0x200 */
uint64_t mcesad; /* 0x11B0 */
@@ -130,6 +92,7 @@ typedef struct LowCore {
uint8_t pad18[0x2000 - 0x1400]; /* 0x1400 */
} QEMU_PACKED LowCore;
+QEMU_BUILD_BUG_ON(sizeof(LowCore) != 8192);
#endif /* CONFIG_USER_ONLY */
#define MAX_ILEN 6
@@ -386,6 +349,8 @@ void ioinst_handle_sal(S390CPU *cpu, uint64_t reg1, uintptr_t ra);
/* mem_helper.c */
target_ulong mmu_real2abs(CPUS390XState *env, target_ulong raddr);
+void probe_write_access(CPUS390XState *env, uint64_t addr, uint64_t len,
+ uintptr_t ra);
/* mmu_helper.c */
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index a506d9ef99..3f76a8abfd 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -2623,3 +2623,29 @@ uint32_t HELPER(cu42)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t m3)
return convert_unicode(env, r1, r2, m3, GETPC(),
decode_utf32, encode_utf16);
}
+
+void probe_write_access(CPUS390XState *env, uint64_t addr, uint64_t len,
+ uintptr_t ra)
+{
+#ifdef CONFIG_USER_ONLY
+ if (!h2g_valid(addr) || !h2g_valid(addr + len - 1) ||
+ page_check_range(addr, len, PAGE_WRITE) < 0) {
+ s390_program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO, ra);
+ }
+#else
+ /* test the actual access, not just any access to the page due to LAP */
+ while (len) {
+ const uint64_t pagelen = -(addr | -TARGET_PAGE_MASK);
+ const uint64_t curlen = MIN(pagelen, len);
+
+ probe_write(env, addr, curlen, cpu_mmu_index(env, false), ra);
+ addr = wrap_address(env, addr + curlen);
+ len -= curlen;
+ }
+#endif
+}
+
+void HELPER(probe_write_access)(CPUS390XState *env, uint64_t addr, uint64_t len)
+{
+ probe_write_access(env, addr, len, GETPC());
+}
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index 41fb466bb4..0afa8f7ca5 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -34,6 +34,7 @@
#include "disas/disas.h"
#include "exec/exec-all.h"
#include "tcg-op.h"
+#include "tcg-op-gvec.h"
#include "qemu/log.h"
#include "qemu/host-utils.h"
#include "exec/cpu_ldst.h"
@@ -985,6 +986,7 @@ static void free_compare(DisasCompare *c)
#define F3(N, X1, X2, X3) F0(N)
#define F4(N, X1, X2, X3, X4) F0(N)
#define F5(N, X1, X2, X3, X4, X5) F0(N)
+#define F6(N, X1, X2, X3, X4, X5, X6) F0(N)
typedef enum {
#include "insn-format.def"
@@ -996,6 +998,7 @@ typedef enum {
#undef F3
#undef F4
#undef F5
+#undef F6
/* Define a structure to hold the decoded fields. We'll store each inside
an array indexed by an enum. In order to conserve memory, we'll arrange
@@ -1010,6 +1013,8 @@ enum DisasFieldIndexO {
FLD_O_m1,
FLD_O_m3,
FLD_O_m4,
+ FLD_O_m5,
+ FLD_O_m6,
FLD_O_b1,
FLD_O_b2,
FLD_O_b4,
@@ -1023,7 +1028,11 @@ enum DisasFieldIndexO {
FLD_O_i2,
FLD_O_i3,
FLD_O_i4,
- FLD_O_i5
+ FLD_O_i5,
+ FLD_O_v1,
+ FLD_O_v2,
+ FLD_O_v3,
+ FLD_O_v4,
};
enum DisasFieldIndexC {
@@ -1031,6 +1040,7 @@ enum DisasFieldIndexC {
FLD_C_m1 = 0,
FLD_C_b1 = 0,
FLD_C_i1 = 0,
+ FLD_C_v1 = 0,
FLD_C_r2 = 1,
FLD_C_b2 = 1,
@@ -1039,20 +1049,25 @@ enum DisasFieldIndexC {
FLD_C_r3 = 2,
FLD_C_m3 = 2,
FLD_C_i3 = 2,
+ FLD_C_v3 = 2,
FLD_C_m4 = 3,
FLD_C_b4 = 3,
FLD_C_i4 = 3,
FLD_C_l1 = 3,
+ FLD_C_v4 = 3,
FLD_C_i5 = 4,
FLD_C_d1 = 4,
+ FLD_C_m5 = 4,
FLD_C_d2 = 5,
+ FLD_C_m6 = 5,
FLD_C_d4 = 6,
FLD_C_x2 = 6,
FLD_C_l2 = 6,
+ FLD_C_v2 = 6,
NUM_C_FIELD = 7
};
@@ -1097,6 +1112,7 @@ typedef struct DisasFormatInfo {
#define R(N, B) { B, 4, 0, FLD_C_r##N, FLD_O_r##N }
#define M(N, B) { B, 4, 0, FLD_C_m##N, FLD_O_m##N }
+#define V(N, B) { B, 4, 3, FLD_C_v##N, FLD_O_v##N }
#define BD(N, BB, BD) { BB, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
{ BD, 12, 0, FLD_C_d##N, FLD_O_d##N }
#define BXD(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
@@ -1116,6 +1132,7 @@ typedef struct DisasFormatInfo {
#define F3(N, X1, X2, X3) { { X1, X2, X3 } },
#define F4(N, X1, X2, X3, X4) { { X1, X2, X3, X4 } },
#define F5(N, X1, X2, X3, X4, X5) { { X1, X2, X3, X4, X5 } },
+#define F6(N, X1, X2, X3, X4, X5, X6) { { X1, X2, X3, X4, X5, X6 } },
static const DisasFormatInfo format_info[] = {
#include "insn-format.def"
@@ -1127,8 +1144,10 @@ static const DisasFormatInfo format_info[] = {
#undef F3
#undef F4
#undef F5
+#undef F6
#undef R
#undef M
+#undef V
#undef BD
#undef BXD
#undef BDL
@@ -1185,6 +1204,7 @@ typedef struct {
#define IF_BFP 0x0008 /* binary floating point instruction */
#define IF_DFP 0x0010 /* decimal floating point instruction */
#define IF_PRIV 0x0020 /* privileged instruction */
+#define IF_VEC 0x0040 /* vector instruction */
struct DisasInsn {
unsigned opc:16;
@@ -5101,6 +5121,8 @@ static DisasJumpType op_mpcifc(DisasContext *s, DisasOps *o)
}
#endif
+#include "translate_vx.inc.c"
+
/* ====================================================================== */
/* The "Cc OUTput" generators. Given the generated output (and in some cases
the original inputs), update the various cc data structures in order to
@@ -5772,6 +5794,13 @@ static void in2_r3_sr32(DisasContext *s, DisasFields *f, DisasOps *o)
}
#define SPEC_in2_r3_sr32 0
+static void in2_r3_32u(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+ o->in2 = tcg_temp_new_i64();
+ tcg_gen_ext32u_i64(o->in2, regs[get_field(f, r3)]);
+}
+#define SPEC_in2_r3_32u 0
+
static void in2_r2_32s(DisasContext *s, DisasFields *f, DisasOps *o)
{
o->in2 = tcg_temp_new_i64();
@@ -6119,6 +6148,25 @@ static void extract_field(DisasFields *o, const DisasField *f, uint64_t insn)
case 2: /* dl+dh split, signed 20 bit. */
r = ((int8_t)r << 12) | (r >> 8);
break;
+ case 3: /* MSB stored in RXB */
+ g_assert(f->size == 4);
+ switch (f->beg) {
+ case 8:
+ r |= extract64(insn, 63 - 36, 1) << 4;
+ break;
+ case 12:
+ r |= extract64(insn, 63 - 37, 1) << 4;
+ break;
+ case 16:
+ r |= extract64(insn, 63 - 38, 1) << 4;
+ break;
+ case 32:
+ r |= extract64(insn, 63 - 39, 1) << 4;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ break;
default:
abort();
}
@@ -6300,11 +6348,22 @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
if (insn->flags & IF_DFP) {
dxc = 3;
}
+ if (insn->flags & IF_VEC) {
+ dxc = 0xfe;
+ }
if (dxc) {
gen_data_exception(dxc);
return DISAS_NORETURN;
}
}
+
+ /* if vector instructions not enabled, executing them is forbidden */
+ if (insn->flags & IF_VEC) {
+ if (!((s->base.tb->flags & FLAG_MASK_VECTOR))) {
+ gen_data_exception(0xfe);
+ return DISAS_NORETURN;
+ }
+ }
}
/* Check for insn specification exceptions. */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
new file mode 100644
index 0000000000..76f9a5d939
--- /dev/null
+++ b/target/s390x/translate_vx.inc.c
@@ -0,0 +1,935 @@
+/*
+ * QEMU TCG support -- s390x vector instruction translation functions
+ *
+ * Copyright (C) 2019 Red Hat Inc
+ *
+ * Authors:
+ * David Hildenbrand <david@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+/*
+ * For most instructions that use the same element size for reads and
+ * writes, we can use real gvec vector expansion, which potantially uses
+ * real host vector instructions. As they only work up to 64 bit elements,
+ * 128 bit elements (vector is a single element) have to be handled
+ * differently. Operations that are too complicated to encode via TCG ops
+ * are handled via gvec ool (out-of-line) handlers.
+ *
+ * As soon as instructions use different element sizes for reads and writes
+ * or access elements "out of their element scope" we expand them manually
+ * in fancy loops, as gvec expansion does not deal with actual element
+ * numbers and does also not support access to other elements.
+ *
+ * 128 bit elements:
+ * As we only have i32/i64, such elements have to be loaded into two
+ * i64 values and can then be processed e.g. by tcg_gen_add2_i64.
+ *
+ * Sizes:
+ * On s390x, the operand size (oprsz) and the maximum size (maxsz) are
+ * always 16 (128 bit). What gvec code calls "vece", s390x calls "es",
+ * a.k.a. "element size". These values nicely map to MO_8 ... MO_64. Only
+ * 128 bit element size has to be treated in a special way (MO_64 + 1).
+ * We will use ES_* instead of MO_* for this reason in this file.
+ *
+ * CC handling:
+ * As gvec ool-helpers can currently not return values (besides via
+ * pointers like vectors or cpu_env), whenever we have to set the CC and
+ * can't conclude the value from the result vector, we will directly
+ * set it in "env->cc_op" and mark it as static via set_cc_static()".
+ * Whenever this is done, the helper writes globals (cc_op).
+ */
+
+#define NUM_VEC_ELEMENT_BYTES(es) (1 << (es))
+#define NUM_VEC_ELEMENTS(es) (16 / NUM_VEC_ELEMENT_BYTES(es))
+#define NUM_VEC_ELEMENT_BITS(es) (NUM_VEC_ELEMENT_BYTES(es) * BITS_PER_BYTE)
+
+#define ES_8 MO_8
+#define ES_16 MO_16
+#define ES_32 MO_32
+#define ES_64 MO_64
+#define ES_128 4
+
+static inline bool valid_vec_element(uint8_t enr, TCGMemOp es)
+{
+ return !(enr & ~(NUM_VEC_ELEMENTS(es) - 1));
+}
+
+static void read_vec_element_i64(TCGv_i64 dst, uint8_t reg, uint8_t enr,
+ TCGMemOp memop)
+{
+ const int offs = vec_reg_offset(reg, enr, memop & MO_SIZE);
+
+ switch (memop) {
+ case ES_8:
+ tcg_gen_ld8u_i64(dst, cpu_env, offs);
+ break;
+ case ES_16:
+ tcg_gen_ld16u_i64(dst, cpu_env, offs);
+ break;
+ case ES_32:
+ tcg_gen_ld32u_i64(dst, cpu_env, offs);
+ break;
+ case ES_8 | MO_SIGN:
+ tcg_gen_ld8s_i64(dst, cpu_env, offs);
+ break;
+ case ES_16 | MO_SIGN:
+ tcg_gen_ld16s_i64(dst, cpu_env, offs);
+ break;
+ case ES_32 | MO_SIGN:
+ tcg_gen_ld32s_i64(dst, cpu_env, offs);
+ break;
+ case ES_64:
+ case ES_64 | MO_SIGN:
+ tcg_gen_ld_i64(dst, cpu_env, offs);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+
+static void write_vec_element_i64(TCGv_i64 src, int reg, uint8_t enr,
+ TCGMemOp memop)
+{
+ const int offs = vec_reg_offset(reg, enr, memop & MO_SIZE);
+
+ switch (memop) {
+ case ES_8:
+ tcg_gen_st8_i64(src, cpu_env, offs);
+ break;
+ case ES_16:
+ tcg_gen_st16_i64(src, cpu_env, offs);
+ break;
+ case ES_32:
+ tcg_gen_st32_i64(src, cpu_env, offs);
+ break;
+ case ES_64:
+ tcg_gen_st_i64(src, cpu_env, offs);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+
+
+static void get_vec_element_ptr_i64(TCGv_ptr ptr, uint8_t reg, TCGv_i64 enr,
+ uint8_t es)
+{
+ TCGv_i64 tmp = tcg_temp_new_i64();
+
+ /* mask off invalid parts from the element nr */
+ tcg_gen_andi_i64(tmp, enr, NUM_VEC_ELEMENTS(es) - 1);
+
+ /* convert it to an element offset relative to cpu_env (vec_reg_offset() */
+ tcg_gen_shli_i64(tmp, tmp, es);
+#ifndef HOST_WORDS_BIGENDIAN
+ tcg_gen_xori_i64(tmp, tmp, 8 - NUM_VEC_ELEMENT_BYTES(es));
+#endif
+ tcg_gen_addi_i64(tmp, tmp, vec_full_reg_offset(reg));
+
+ /* generate the final ptr by adding cpu_env */
+ tcg_gen_trunc_i64_ptr(ptr, tmp);
+ tcg_gen_add_ptr(ptr, ptr, cpu_env);
+
+ tcg_temp_free_i64(tmp);
+}
+
+#define gen_gvec_3_ool(v1, v2, v3, data, fn) \
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(v1), vec_full_reg_offset(v2), \
+ vec_full_reg_offset(v3), 16, 16, data, fn)
+#define gen_gvec_3_ptr(v1, v2, v3, ptr, data, fn) \
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(v1), vec_full_reg_offset(v2), \
+ vec_full_reg_offset(v3), ptr, 16, 16, data, fn)
+#define gen_gvec_4(v1, v2, v3, v4, gen) \
+ tcg_gen_gvec_4(vec_full_reg_offset(v1), vec_full_reg_offset(v2), \
+ vec_full_reg_offset(v3), vec_full_reg_offset(v4), \
+ 16, 16, gen)
+#define gen_gvec_4_ool(v1, v2, v3, v4, data, fn) \
+ tcg_gen_gvec_4_ool(vec_full_reg_offset(v1), vec_full_reg_offset(v2), \
+ vec_full_reg_offset(v3), vec_full_reg_offset(v4), \
+ 16, 16, data, fn)
+#define gen_gvec_dup_i64(es, v1, c) \
+ tcg_gen_gvec_dup_i64(es, vec_full_reg_offset(v1), 16, 16, c)
+#define gen_gvec_mov(v1, v2) \
+ tcg_gen_gvec_mov(0, vec_full_reg_offset(v1), vec_full_reg_offset(v2), 16, \
+ 16)
+#define gen_gvec_dup64i(v1, c) \
+ tcg_gen_gvec_dup64i(vec_full_reg_offset(v1), 16, 16, c)
+
+static void gen_gvec_dupi(uint8_t es, uint8_t reg, uint64_t c)
+{
+ switch (es) {
+ case ES_8:
+ tcg_gen_gvec_dup8i(vec_full_reg_offset(reg), 16, 16, c);
+ break;
+ case ES_16:
+ tcg_gen_gvec_dup16i(vec_full_reg_offset(reg), 16, 16, c);
+ break;
+ case ES_32:
+ tcg_gen_gvec_dup32i(vec_full_reg_offset(reg), 16, 16, c);
+ break;
+ case ES_64:
+ gen_gvec_dup64i(reg, c);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+
+static void zero_vec(uint8_t reg)
+{
+ tcg_gen_gvec_dup8i(vec_full_reg_offset(reg), 16, 16, 0);
+}
+
+static DisasJumpType op_vge(DisasContext *s, DisasOps *o)
+{
+ const uint8_t es = s->insn->data;
+ const uint8_t enr = get_field(s->fields, m3);
+ TCGv_i64 tmp;
+
+ if (!valid_vec_element(enr, es)) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ tmp = tcg_temp_new_i64();
+ read_vec_element_i64(tmp, get_field(s->fields, v2), enr, es);
+ tcg_gen_add_i64(o->addr1, o->addr1, tmp);
+ gen_addi_and_wrap_i64(s, o->addr1, o->addr1, 0);
+
+ tcg_gen_qemu_ld_i64(tmp, o->addr1, get_mem_index(s), MO_TE | es);
+ write_vec_element_i64(tmp, get_field(s->fields, v1), enr, es);
+ tcg_temp_free_i64(tmp);
+ return DISAS_NEXT;
+}
+
+static uint64_t generate_byte_mask(uint8_t mask)
+{
+ uint64_t r = 0;
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ if ((mask >> i) & 1) {
+ r |= 0xffull << (i * 8);
+ }
+ }
+ return r;
+}
+
+static DisasJumpType op_vgbm(DisasContext *s, DisasOps *o)
+{
+ const uint16_t i2 = get_field(s->fields, i2);
+
+ if (i2 == (i2 & 0xff) * 0x0101) {
+ /*
+ * Masks for both 64 bit elements of the vector are the same.
+ * Trust tcg to produce a good constant loading.
+ */
+ gen_gvec_dup64i(get_field(s->fields, v1),
+ generate_byte_mask(i2 & 0xff));
+ } else {
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ tcg_gen_movi_i64(t, generate_byte_mask(i2 >> 8));
+ write_vec_element_i64(t, get_field(s->fields, v1), 0, ES_64);
+ tcg_gen_movi_i64(t, generate_byte_mask(i2));
+ write_vec_element_i64(t, get_field(s->fields, v1), 1, ES_64);
+ tcg_temp_free_i64(t);
+ }
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vgm(DisasContext *s, DisasOps *o)
+{
+ const uint8_t es = get_field(s->fields, m4);
+ const uint8_t bits = NUM_VEC_ELEMENT_BITS(es);
+ const uint8_t i2 = get_field(s->fields, i2) & (bits - 1);
+ const uint8_t i3 = get_field(s->fields, i3) & (bits - 1);
+ uint64_t mask = 0;
+ int i;
+
+ if (es > ES_64) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ /* generate the mask - take care of wrapping */
+ for (i = i2; ; i = (i + 1) % bits) {
+ mask |= 1ull << (bits - i - 1);
+ if (i == i3) {
+ break;
+ }
+ }
+
+ gen_gvec_dupi(es, get_field(s->fields, v1), mask);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vl(DisasContext *s, DisasOps *o)
+{
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t1 = tcg_temp_new_i64();
+
+ tcg_gen_qemu_ld_i64(t0, o->addr1, get_mem_index(s), MO_TEQ);
+ gen_addi_and_wrap_i64(s, o->addr1, o->addr1, 8);
+ tcg_gen_qemu_ld_i64(t1, o->addr1, get_mem_index(s), MO_TEQ);
+ write_vec_element_i64(t0, get_field(s->fields, v1), 0, ES_64);
+ write_vec_element_i64(t1, get_field(s->fields, v1), 1, ES_64);
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vlr(DisasContext *s, DisasOps *o)
+{
+ gen_gvec_mov(get_field(s->fields, v1), get_field(s->fields, v2));
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vlrep(DisasContext *s, DisasOps *o)
+{
+ const uint8_t es = get_field(s->fields, m3);
+ TCGv_i64 tmp;
+
+ if (es > ES_64) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ tmp = tcg_temp_new_i64();
+ tcg_gen_qemu_ld_i64(tmp, o->addr1, get_mem_index(s), MO_TE | es);
+ gen_gvec_dup_i64(es, get_field(s->fields, v1), tmp);
+ tcg_temp_free_i64(tmp);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vle(DisasContext *s, DisasOps *o)
+{
+ const uint8_t es = s->insn->data;
+ const uint8_t enr = get_field(s->fields, m3);
+ TCGv_i64 tmp;
+
+ if (!valid_vec_element(enr, es)) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ tmp = tcg_temp_new_i64();
+ tcg_gen_qemu_ld_i64(tmp, o->addr1, get_mem_index(s), MO_TE | es);
+ write_vec_element_i64(tmp, get_field(s->fields, v1), enr, es);
+ tcg_temp_free_i64(tmp);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vlei(DisasContext *s, DisasOps *o)
+{
+ const uint8_t es = s->insn->data;
+ const uint8_t enr = get_field(s->fields, m3);
+ TCGv_i64 tmp;
+
+ if (!valid_vec_element(enr, es)) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ tmp = tcg_const_i64((int16_t)get_field(s->fields, i2));
+ write_vec_element_i64(tmp, get_field(s->fields, v1), enr, es);
+ tcg_temp_free_i64(tmp);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vlgv(DisasContext *s, DisasOps *o)
+{
+ const uint8_t es = get_field(s->fields, m4);
+ TCGv_ptr ptr;
+
+ if (es > ES_64) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ /* fast path if we don't need the register content */
+ if (!get_field(s->fields, b2)) {
+ uint8_t enr = get_field(s->fields, d2) & (NUM_VEC_ELEMENTS(es) - 1);
+
+ read_vec_element_i64(o->out, get_field(s->fields, v3), enr, es);
+ return DISAS_NEXT;
+ }
+
+ ptr = tcg_temp_new_ptr();
+ get_vec_element_ptr_i64(ptr, get_field(s->fields, v3), o->addr1, es);
+ switch (es) {
+ case ES_8:
+ tcg_gen_ld8u_i64(o->out, ptr, 0);
+ break;
+ case ES_16:
+ tcg_gen_ld16u_i64(o->out, ptr, 0);
+ break;
+ case ES_32:
+ tcg_gen_ld32u_i64(o->out, ptr, 0);
+ break;
+ case ES_64:
+ tcg_gen_ld_i64(o->out, ptr, 0);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ tcg_temp_free_ptr(ptr);
+
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vllez(DisasContext *s, DisasOps *o)
+{
+ uint8_t es = get_field(s->fields, m3);
+ uint8_t enr;
+ TCGv_i64 t;
+
+ switch (es) {
+ /* rightmost sub-element of leftmost doubleword */
+ case ES_8:
+ enr = 7;
+ break;
+ case ES_16:
+ enr = 3;
+ break;
+ case ES_32:
+ enr = 1;
+ break;
+ case ES_64:
+ enr = 0;
+ break;
+ /* leftmost sub-element of leftmost doubleword */
+ case 6:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ es = ES_32;
+ enr = 0;
+ break;
+ }
+ default:
+ /* fallthrough */
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ t = tcg_temp_new_i64();
+ tcg_gen_qemu_ld_i64(t, o->addr1, get_mem_index(s), MO_TE | es);
+ zero_vec(get_field(s->fields, v1));
+ write_vec_element_i64(t, get_field(s->fields, v1), enr, es);
+ tcg_temp_free_i64(t);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vlm(DisasContext *s, DisasOps *o)
+{
+ const uint8_t v3 = get_field(s->fields, v3);
+ uint8_t v1 = get_field(s->fields, v1);
+ TCGv_i64 t0, t1;
+
+ if (v3 < v1 || (v3 - v1 + 1) > 16) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ /*
+ * Check for possible access exceptions by trying to load the last
+ * element. The first element will be checked first next.
+ */
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i64();
+ gen_addi_and_wrap_i64(s, t0, o->addr1, (v3 - v1) * 16 + 8);
+ tcg_gen_qemu_ld_i64(t0, t0, get_mem_index(s), MO_TEQ);
+
+ for (;; v1++) {
+ tcg_gen_qemu_ld_i64(t1, o->addr1, get_mem_index(s), MO_TEQ);
+ write_vec_element_i64(t1, v1, 0, ES_64);
+ if (v1 == v3) {
+ break;
+ }
+ gen_addi_and_wrap_i64(s, o->addr1, o->addr1, 8);
+ tcg_gen_qemu_ld_i64(t1, o->addr1, get_mem_index(s), MO_TEQ);
+ write_vec_element_i64(t1, v1, 1, ES_64);
+ gen_addi_and_wrap_i64(s, o->addr1, o->addr1, 8);
+ }
+
+ /* Store the last element, loaded first */
+ write_vec_element_i64(t0, v1, 1, ES_64);
+
+ tcg_temp_free_i64(t0);
+ tcg_temp_free_i64(t1);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vlbb(DisasContext *s, DisasOps *o)
+{
+ const int64_t block_size = (1ull << (get_field(s->fields, m3) + 6));
+ const int v1_offs = vec_full_reg_offset(get_field(s->fields, v1));
+ TCGv_ptr a0;
+ TCGv_i64 bytes;
+
+ if (get_field(s->fields, m3) > 6) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ bytes = tcg_temp_new_i64();
+ a0 = tcg_temp_new_ptr();
+ /* calculate the number of bytes until the next block boundary */
+ tcg_gen_ori_i64(bytes, o->addr1, -block_size);
+ tcg_gen_neg_i64(bytes, bytes);
+
+ tcg_gen_addi_ptr(a0, cpu_env, v1_offs);
+ gen_helper_vll(cpu_env, a0, o->addr1, bytes);
+ tcg_temp_free_i64(bytes);
+ tcg_temp_free_ptr(a0);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vlvg(DisasContext *s, DisasOps *o)
+{
+ const uint8_t es = get_field(s->fields, m4);
+ TCGv_ptr ptr;
+
+ if (es > ES_64) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ /* fast path if we don't need the register content */
+ if (!get_field(s->fields, b2)) {
+ uint8_t enr = get_field(s->fields, d2) & (NUM_VEC_ELEMENTS(es) - 1);
+
+ write_vec_element_i64(o->in2, get_field(s->fields, v1), enr, es);
+ return DISAS_NEXT;
+ }
+
+ ptr = tcg_temp_new_ptr();
+ get_vec_element_ptr_i64(ptr, get_field(s->fields, v1), o->addr1, es);
+ switch (es) {
+ case ES_8:
+ tcg_gen_st8_i64(o->in2, ptr, 0);
+ break;
+ case ES_16:
+ tcg_gen_st16_i64(o->in2, ptr, 0);
+ break;
+ case ES_32:
+ tcg_gen_st32_i64(o->in2, ptr, 0);
+ break;
+ case ES_64:
+ tcg_gen_st_i64(o->in2, ptr, 0);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ tcg_temp_free_ptr(ptr);
+
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vlvgp(DisasContext *s, DisasOps *o)
+{
+ write_vec_element_i64(o->in1, get_field(s->fields, v1), 0, ES_64);
+ write_vec_element_i64(o->in2, get_field(s->fields, v1), 1, ES_64);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vll(DisasContext *s, DisasOps *o)
+{
+ const int v1_offs = vec_full_reg_offset(get_field(s->fields, v1));
+ TCGv_ptr a0 = tcg_temp_new_ptr();
+
+ /* convert highest index into an actual length */
+ tcg_gen_addi_i64(o->in2, o->in2, 1);
+ tcg_gen_addi_ptr(a0, cpu_env, v1_offs);
+ gen_helper_vll(cpu_env, a0, o->addr1, o->in2);
+ tcg_temp_free_ptr(a0);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vmr(DisasContext *s, DisasOps *o)
+{
+ const uint8_t v1 = get_field(s->fields, v1);
+ const uint8_t v2 = get_field(s->fields, v2);
+ const uint8_t v3 = get_field(s->fields, v3);
+ const uint8_t es = get_field(s->fields, m4);
+ int dst_idx, src_idx;
+ TCGv_i64 tmp;
+
+ if (es > ES_64) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ tmp = tcg_temp_new_i64();
+ if (s->fields->op2 == 0x61) {
+ /* iterate backwards to avoid overwriting data we might need later */
+ for (dst_idx = NUM_VEC_ELEMENTS(es) - 1; dst_idx >= 0; dst_idx--) {
+ src_idx = dst_idx / 2;
+ if (dst_idx % 2 == 0) {
+ read_vec_element_i64(tmp, v2, src_idx, es);
+ } else {
+ read_vec_element_i64(tmp, v3, src_idx, es);
+ }
+ write_vec_element_i64(tmp, v1, dst_idx, es);
+ }
+ } else {
+ /* iterate forward to avoid overwriting data we might need later */
+ for (dst_idx = 0; dst_idx < NUM_VEC_ELEMENTS(es); dst_idx++) {
+ src_idx = (dst_idx + NUM_VEC_ELEMENTS(es)) / 2;
+ if (dst_idx % 2 == 0) {
+ read_vec_element_i64(tmp, v2, src_idx, es);
+ } else {
+ read_vec_element_i64(tmp, v3, src_idx, es);
+ }
+ write_vec_element_i64(tmp, v1, dst_idx, es);
+ }
+ }
+ tcg_temp_free_i64(tmp);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vpk(DisasContext *s, DisasOps *o)
+{
+ const uint8_t v1 = get_field(s->fields, v1);
+ const uint8_t v2 = get_field(s->fields, v2);
+ const uint8_t v3 = get_field(s->fields, v3);
+ const uint8_t es = get_field(s->fields, m4);
+ static gen_helper_gvec_3 * const vpk[3] = {
+ gen_helper_gvec_vpk16,
+ gen_helper_gvec_vpk32,
+ gen_helper_gvec_vpk64,
+ };
+ static gen_helper_gvec_3 * const vpks[3] = {
+ gen_helper_gvec_vpks16,
+ gen_helper_gvec_vpks32,
+ gen_helper_gvec_vpks64,
+ };
+ static gen_helper_gvec_3_ptr * const vpks_cc[3] = {
+ gen_helper_gvec_vpks_cc16,
+ gen_helper_gvec_vpks_cc32,
+ gen_helper_gvec_vpks_cc64,
+ };
+ static gen_helper_gvec_3 * const vpkls[3] = {
+ gen_helper_gvec_vpkls16,
+ gen_helper_gvec_vpkls32,
+ gen_helper_gvec_vpkls64,
+ };
+ static gen_helper_gvec_3_ptr * const vpkls_cc[3] = {
+ gen_helper_gvec_vpkls_cc16,
+ gen_helper_gvec_vpkls_cc32,
+ gen_helper_gvec_vpkls_cc64,
+ };
+
+ if (es == ES_8 || es > ES_64) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ switch (s->fields->op2) {
+ case 0x97:
+ if (get_field(s->fields, m5) & 0x1) {
+ gen_gvec_3_ptr(v1, v2, v3, cpu_env, 0, vpks_cc[es - 1]);
+ set_cc_static(s);
+ } else {
+ gen_gvec_3_ool(v1, v2, v3, 0, vpks[es - 1]);
+ }
+ break;
+ case 0x95:
+ if (get_field(s->fields, m5) & 0x1) {
+ gen_gvec_3_ptr(v1, v2, v3, cpu_env, 0, vpkls_cc[es - 1]);
+ set_cc_static(s);
+ } else {
+ gen_gvec_3_ool(v1, v2, v3, 0, vpkls[es - 1]);
+ }
+ break;
+ case 0x94:
+ /* If sources and destination dont't overlap -> fast path */
+ if (v1 != v2 && v1 != v3) {
+ const uint8_t src_es = get_field(s->fields, m4);
+ const uint8_t dst_es = src_es - 1;
+ TCGv_i64 tmp = tcg_temp_new_i64();
+ int dst_idx, src_idx;
+
+ for (dst_idx = 0; dst_idx < NUM_VEC_ELEMENTS(dst_es); dst_idx++) {
+ src_idx = dst_idx;
+ if (src_idx < NUM_VEC_ELEMENTS(src_es)) {
+ read_vec_element_i64(tmp, v2, src_idx, src_es);
+ } else {
+ src_idx -= NUM_VEC_ELEMENTS(src_es);
+ read_vec_element_i64(tmp, v3, src_idx, src_es);
+ }
+ write_vec_element_i64(tmp, v1, dst_idx, dst_es);
+ }
+ tcg_temp_free_i64(tmp);
+ } else {
+ gen_gvec_3_ool(v1, v2, v3, 0, vpk[es - 1]);
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vperm(DisasContext *s, DisasOps *o)
+{
+ gen_gvec_4_ool(get_field(s->fields, v1), get_field(s->fields, v2),
+ get_field(s->fields, v3), get_field(s->fields, v4),
+ 0, gen_helper_gvec_vperm);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vpdi(DisasContext *s, DisasOps *o)
+{
+ const uint8_t i2 = extract32(get_field(s->fields, m4), 2, 1);
+ const uint8_t i3 = extract32(get_field(s->fields, m4), 0, 1);
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t1 = tcg_temp_new_i64();
+
+ read_vec_element_i64(t0, get_field(s->fields, v2), i2, ES_64);
+ read_vec_element_i64(t1, get_field(s->fields, v3), i3, ES_64);
+ write_vec_element_i64(t0, get_field(s->fields, v1), 0, ES_64);
+ write_vec_element_i64(t1, get_field(s->fields, v1), 1, ES_64);
+ tcg_temp_free_i64(t0);
+ tcg_temp_free_i64(t1);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vrep(DisasContext *s, DisasOps *o)
+{
+ const uint8_t enr = get_field(s->fields, i2);
+ const uint8_t es = get_field(s->fields, m4);
+
+ if (es > ES_64 || !valid_vec_element(enr, es)) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ tcg_gen_gvec_dup_mem(es, vec_full_reg_offset(get_field(s->fields, v1)),
+ vec_reg_offset(get_field(s->fields, v3), enr, es),
+ 16, 16);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vrepi(DisasContext *s, DisasOps *o)
+{
+ const int64_t data = (int16_t)get_field(s->fields, i2);
+ const uint8_t es = get_field(s->fields, m3);
+
+ if (es > ES_64) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ gen_gvec_dupi(es, get_field(s->fields, v1), data);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vsce(DisasContext *s, DisasOps *o)
+{
+ const uint8_t es = s->insn->data;
+ const uint8_t enr = get_field(s->fields, m3);
+ TCGv_i64 tmp;
+
+ if (!valid_vec_element(enr, es)) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ tmp = tcg_temp_new_i64();
+ read_vec_element_i64(tmp, get_field(s->fields, v2), enr, es);
+ tcg_gen_add_i64(o->addr1, o->addr1, tmp);
+ gen_addi_and_wrap_i64(s, o->addr1, o->addr1, 0);
+
+ read_vec_element_i64(tmp, get_field(s->fields, v1), enr, es);
+ tcg_gen_qemu_st_i64(tmp, o->addr1, get_mem_index(s), MO_TE | es);
+ tcg_temp_free_i64(tmp);
+ return DISAS_NEXT;
+}
+
+static void gen_sel_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b, TCGv_i64 c)
+{
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ /* bit in c not set -> copy bit from b */
+ tcg_gen_andc_i64(t, b, c);
+ /* bit in c set -> copy bit from a */
+ tcg_gen_and_i64(d, a, c);
+ /* merge the results */
+ tcg_gen_or_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_sel_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b,
+ TCGv_vec c)
+{
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
+
+ tcg_gen_andc_vec(vece, t, b, c);
+ tcg_gen_and_vec(vece, d, a, c);
+ tcg_gen_or_vec(vece, d, d, t);
+ tcg_temp_free_vec(t);
+}
+
+static DisasJumpType op_vsel(DisasContext *s, DisasOps *o)
+{
+ static const GVecGen4 gvec_op = {
+ .fni8 = gen_sel_i64,
+ .fniv = gen_sel_vec,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ };
+
+ gen_gvec_4(get_field(s->fields, v1), get_field(s->fields, v2),
+ get_field(s->fields, v3), get_field(s->fields, v4), &gvec_op);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vseg(DisasContext *s, DisasOps *o)
+{
+ const uint8_t es = get_field(s->fields, m3);
+ int idx1, idx2;
+ TCGv_i64 tmp;
+
+ switch (es) {
+ case ES_8:
+ idx1 = 7;
+ idx2 = 15;
+ break;
+ case ES_16:
+ idx1 = 3;
+ idx2 = 7;
+ break;
+ case ES_32:
+ idx1 = 1;
+ idx2 = 3;
+ break;
+ default:
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ tmp = tcg_temp_new_i64();
+ read_vec_element_i64(tmp, get_field(s->fields, v2), idx1, es | MO_SIGN);
+ write_vec_element_i64(tmp, get_field(s->fields, v1), 0, ES_64);
+ read_vec_element_i64(tmp, get_field(s->fields, v2), idx2, es | MO_SIGN);
+ write_vec_element_i64(tmp, get_field(s->fields, v1), 1, ES_64);
+ tcg_temp_free_i64(tmp);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vst(DisasContext *s, DisasOps *o)
+{
+ TCGv_i64 tmp = tcg_const_i64(16);
+
+ /* Probe write access before actually modifying memory */
+ gen_helper_probe_write_access(cpu_env, o->addr1, tmp);
+
+ read_vec_element_i64(tmp, get_field(s->fields, v1), 0, ES_64);
+ tcg_gen_qemu_st_i64(tmp, o->addr1, get_mem_index(s), MO_TEQ);
+ gen_addi_and_wrap_i64(s, o->addr1, o->addr1, 8);
+ read_vec_element_i64(tmp, get_field(s->fields, v1), 1, ES_64);
+ tcg_gen_qemu_st_i64(tmp, o->addr1, get_mem_index(s), MO_TEQ);
+ tcg_temp_free_i64(tmp);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vste(DisasContext *s, DisasOps *o)
+{
+ const uint8_t es = s->insn->data;
+ const uint8_t enr = get_field(s->fields, m3);
+ TCGv_i64 tmp;
+
+ if (!valid_vec_element(enr, es)) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ tmp = tcg_temp_new_i64();
+ read_vec_element_i64(tmp, get_field(s->fields, v1), enr, es);
+ tcg_gen_qemu_st_i64(tmp, o->addr1, get_mem_index(s), MO_TE | es);
+ tcg_temp_free_i64(tmp);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vstm(DisasContext *s, DisasOps *o)
+{
+ const uint8_t v3 = get_field(s->fields, v3);
+ uint8_t v1 = get_field(s->fields, v1);
+ TCGv_i64 tmp;
+
+ while (v3 < v1 || (v3 - v1 + 1) > 16) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ /* Probe write access before actually modifying memory */
+ tmp = tcg_const_i64((v3 - v1 + 1) * 16);
+ gen_helper_probe_write_access(cpu_env, o->addr1, tmp);
+
+ for (;; v1++) {
+ read_vec_element_i64(tmp, v1, 0, ES_64);
+ tcg_gen_qemu_st_i64(tmp, o->addr1, get_mem_index(s), MO_TEQ);
+ gen_addi_and_wrap_i64(s, o->addr1, o->addr1, 8);
+ read_vec_element_i64(tmp, v1, 1, ES_64);
+ tcg_gen_qemu_st_i64(tmp, o->addr1, get_mem_index(s), MO_TEQ);
+ if (v1 == v3) {
+ break;
+ }
+ gen_addi_and_wrap_i64(s, o->addr1, o->addr1, 8);
+ }
+ tcg_temp_free_i64(tmp);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vstl(DisasContext *s, DisasOps *o)
+{
+ const int v1_offs = vec_full_reg_offset(get_field(s->fields, v1));
+ TCGv_ptr a0 = tcg_temp_new_ptr();
+
+ /* convert highest index into an actual length */
+ tcg_gen_addi_i64(o->in2, o->in2, 1);
+ tcg_gen_addi_ptr(a0, cpu_env, v1_offs);
+ gen_helper_vstl(cpu_env, a0, o->addr1, o->in2);
+ tcg_temp_free_ptr(a0);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_vup(DisasContext *s, DisasOps *o)
+{
+ const bool logical = s->fields->op2 == 0xd4 || s->fields->op2 == 0xd5;
+ const uint8_t v1 = get_field(s->fields, v1);
+ const uint8_t v2 = get_field(s->fields, v2);
+ const uint8_t src_es = get_field(s->fields, m3);
+ const uint8_t dst_es = src_es + 1;
+ int dst_idx, src_idx;
+ TCGv_i64 tmp;
+
+ if (src_es > ES_32) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ tmp = tcg_temp_new_i64();
+ if (s->fields->op2 == 0xd7 || s->fields->op2 == 0xd5) {
+ /* iterate backwards to avoid overwriting data we might need later */
+ for (dst_idx = NUM_VEC_ELEMENTS(dst_es) - 1; dst_idx >= 0; dst_idx--) {
+ src_idx = dst_idx;
+ read_vec_element_i64(tmp, v2, src_idx,
+ src_es | (logical ? 0 : MO_SIGN));
+ write_vec_element_i64(tmp, v1, dst_idx, dst_es);
+ }
+
+ } else {
+ /* iterate forward to avoid overwriting data we might need later */
+ for (dst_idx = 0; dst_idx < NUM_VEC_ELEMENTS(dst_es); dst_idx++) {
+ src_idx = dst_idx + NUM_VEC_ELEMENTS(src_es) / 2;
+ read_vec_element_i64(tmp, v2, src_idx,
+ src_es | (logical ? 0 : MO_SIGN));
+ write_vec_element_i64(tmp, v1, dst_idx, dst_es);
+ }
+ }
+ tcg_temp_free_i64(tmp);
+ return DISAS_NEXT;
+}
diff --git a/target/s390x/vec.h b/target/s390x/vec.h
new file mode 100644
index 0000000000..3313fb43ee
--- /dev/null
+++ b/target/s390x/vec.h
@@ -0,0 +1,101 @@
+/*
+ * QEMU TCG support -- s390x vector utilitites
+ *
+ * Copyright (C) 2019 Red Hat Inc
+ *
+ * Authors:
+ * David Hildenbrand <david@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef S390X_VEC_H
+#define S390X_VEC_H
+
+typedef union S390Vector {
+ uint64_t doubleword[2];
+ uint32_t word[4];
+ uint16_t halfword[8];
+ uint8_t byte[16];
+} S390Vector;
+
+/*
+ * Each vector is stored as two 64bit host values. So when talking about
+ * byte/halfword/word numbers, we have to take care of proper translation
+ * between element numbers.
+ *
+ * Big Endian (target/possible host)
+ * B: [ 0][ 1][ 2][ 3][ 4][ 5][ 6][ 7] - [ 8][ 9][10][11][12][13][14][15]
+ * HW: [ 0][ 1][ 2][ 3] - [ 4][ 5][ 6][ 7]
+ * W: [ 0][ 1] - [ 2][ 3]
+ * DW: [ 0] - [ 1]
+ *
+ * Little Endian (possible host)
+ * B: [ 7][ 6][ 5][ 4][ 3][ 2][ 1][ 0] - [15][14][13][12][11][10][ 9][ 8]
+ * HW: [ 3][ 2][ 1][ 0] - [ 7][ 6][ 5][ 4]
+ * W: [ 1][ 0] - [ 3][ 2]
+ * DW: [ 0] - [ 1]
+ */
+#ifndef HOST_WORDS_BIGENDIAN
+#define H1(x) ((x) ^ 7)
+#define H2(x) ((x) ^ 3)
+#define H4(x) ((x) ^ 1)
+#else
+#define H1(x) (x)
+#define H2(x) (x)
+#define H4(x) (x)
+#endif
+
+static inline uint8_t s390_vec_read_element8(const S390Vector *v, uint8_t enr)
+{
+ g_assert(enr < 16);
+ return v->byte[H1(enr)];
+}
+
+static inline uint16_t s390_vec_read_element16(const S390Vector *v, uint8_t enr)
+{
+ g_assert(enr < 8);
+ return v->halfword[H2(enr)];
+}
+
+static inline uint32_t s390_vec_read_element32(const S390Vector *v, uint8_t enr)
+{
+ g_assert(enr < 4);
+ return v->word[H4(enr)];
+}
+
+static inline uint64_t s390_vec_read_element64(const S390Vector *v, uint8_t enr)
+{
+ g_assert(enr < 2);
+ return v->doubleword[enr];
+}
+
+static inline void s390_vec_write_element8(S390Vector *v, uint8_t enr,
+ uint8_t data)
+{
+ g_assert(enr < 16);
+ v->byte[H1(enr)] = data;
+}
+
+static inline void s390_vec_write_element16(S390Vector *v, uint8_t enr,
+ uint16_t data)
+{
+ g_assert(enr < 8);
+ v->halfword[H2(enr)] = data;
+}
+
+static inline void s390_vec_write_element32(S390Vector *v, uint8_t enr,
+ uint32_t data)
+{
+ g_assert(enr < 4);
+ v->word[H4(enr)] = data;
+}
+
+static inline void s390_vec_write_element64(S390Vector *v, uint8_t enr,
+ uint64_t data)
+{
+ g_assert(enr < 2);
+ v->doubleword[enr] = data;
+}
+
+#endif /* S390X_VEC_H */
diff --git a/target/s390x/vec_helper.c b/target/s390x/vec_helper.c
new file mode 100644
index 0000000000..bb4c9304f0
--- /dev/null
+++ b/target/s390x/vec_helper.c
@@ -0,0 +1,193 @@
+/*
+ * QEMU TCG support -- s390x vector support instructions
+ *
+ * Copyright (C) 2019 Red Hat Inc
+ *
+ * Authors:
+ * David Hildenbrand <david@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "internal.h"
+#include "vec.h"
+#include "tcg/tcg.h"
+#include "tcg/tcg-gvec-desc.h"
+#include "exec/helper-proto.h"
+#include "exec/cpu_ldst.h"
+#include "exec/exec-all.h"
+
+void HELPER(vll)(CPUS390XState *env, void *v1, uint64_t addr, uint64_t bytes)
+{
+ if (likely(bytes >= 16)) {
+ uint64_t t0, t1;
+
+ t0 = cpu_ldq_data_ra(env, addr, GETPC());
+ addr = wrap_address(env, addr + 8);
+ t1 = cpu_ldq_data_ra(env, addr, GETPC());
+ s390_vec_write_element64(v1, 0, t0);
+ s390_vec_write_element64(v1, 1, t1);
+ } else {
+ S390Vector tmp = {};
+ int i;
+
+ for (i = 0; i < bytes; i++) {
+ uint8_t byte = cpu_ldub_data_ra(env, addr, GETPC());
+
+ s390_vec_write_element8(&tmp, i, byte);
+ addr = wrap_address(env, addr + 1);
+ }
+ *(S390Vector *)v1 = tmp;
+ }
+}
+
+#define DEF_VPK_HFN(BITS, TBITS) \
+typedef uint##TBITS##_t (*vpk##BITS##_fn)(uint##BITS##_t, int *); \
+static int vpk##BITS##_hfn(S390Vector *v1, const S390Vector *v2, \
+ const S390Vector *v3, vpk##BITS##_fn fn) \
+{ \
+ int i, saturated = 0; \
+ S390Vector tmp; \
+ \
+ for (i = 0; i < (128 / TBITS); i++) { \
+ uint##BITS##_t src; \
+ \
+ if (i < (128 / BITS)) { \
+ src = s390_vec_read_element##BITS(v2, i); \
+ } else { \
+ src = s390_vec_read_element##BITS(v3, i - (128 / BITS)); \
+ } \
+ s390_vec_write_element##TBITS(&tmp, i, fn(src, &saturated)); \
+ } \
+ *v1 = tmp; \
+ return saturated; \
+}
+DEF_VPK_HFN(64, 32)
+DEF_VPK_HFN(32, 16)
+DEF_VPK_HFN(16, 8)
+
+#define DEF_VPK(BITS, TBITS) \
+static uint##TBITS##_t vpk##BITS##e(uint##BITS##_t src, int *saturated) \
+{ \
+ return src; \
+} \
+void HELPER(gvec_vpk##BITS)(void *v1, const void *v2, const void *v3, \
+ uint32_t desc) \
+{ \
+ vpk##BITS##_hfn(v1, v2, v3, vpk##BITS##e); \
+}
+DEF_VPK(64, 32)
+DEF_VPK(32, 16)
+DEF_VPK(16, 8)
+
+#define DEF_VPKS(BITS, TBITS) \
+static uint##TBITS##_t vpks##BITS##e(uint##BITS##_t src, int *saturated) \
+{ \
+ if ((int##BITS##_t)src > INT##TBITS##_MAX) { \
+ (*saturated)++; \
+ return INT##TBITS##_MAX; \
+ } else if ((int##BITS##_t)src < INT##TBITS##_MIN) { \
+ (*saturated)++; \
+ return INT##TBITS##_MIN; \
+ } \
+ return src; \
+} \
+void HELPER(gvec_vpks##BITS)(void *v1, const void *v2, const void *v3, \
+ uint32_t desc) \
+{ \
+ vpk##BITS##_hfn(v1, v2, v3, vpks##BITS##e); \
+} \
+void HELPER(gvec_vpks_cc##BITS)(void *v1, const void *v2, const void *v3, \
+ CPUS390XState *env, uint32_t desc) \
+{ \
+ int saturated = vpk##BITS##_hfn(v1, v2, v3, vpks##BITS##e); \
+ \
+ if (saturated == (128 / TBITS)) { \
+ env->cc_op = 3; \
+ } else if (saturated) { \
+ env->cc_op = 1; \
+ } else { \
+ env->cc_op = 0; \
+ } \
+}
+DEF_VPKS(64, 32)
+DEF_VPKS(32, 16)
+DEF_VPKS(16, 8)
+
+#define DEF_VPKLS(BITS, TBITS) \
+static uint##TBITS##_t vpkls##BITS##e(uint##BITS##_t src, int *saturated) \
+{ \
+ if (src > UINT##TBITS##_MAX) { \
+ (*saturated)++; \
+ return UINT##TBITS##_MAX; \
+ } \
+ return src; \
+} \
+void HELPER(gvec_vpkls##BITS)(void *v1, const void *v2, const void *v3, \
+ uint32_t desc) \
+{ \
+ vpk##BITS##_hfn(v1, v2, v3, vpkls##BITS##e); \
+} \
+void HELPER(gvec_vpkls_cc##BITS)(void *v1, const void *v2, const void *v3, \
+ CPUS390XState *env, uint32_t desc) \
+{ \
+ int saturated = vpk##BITS##_hfn(v1, v2, v3, vpkls##BITS##e); \
+ \
+ if (saturated == (128 / TBITS)) { \
+ env->cc_op = 3; \
+ } else if (saturated) { \
+ env->cc_op = 1; \
+ } else { \
+ env->cc_op = 0; \
+ } \
+}
+DEF_VPKLS(64, 32)
+DEF_VPKLS(32, 16)
+DEF_VPKLS(16, 8)
+
+void HELPER(gvec_vperm)(void *v1, const void *v2, const void *v3,
+ const void *v4, uint32_t desc)
+{
+ S390Vector tmp;
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ const uint8_t selector = s390_vec_read_element8(v4, i) & 0x1f;
+ uint8_t byte;
+
+ if (selector < 16) {
+ byte = s390_vec_read_element8(v2, selector);
+ } else {
+ byte = s390_vec_read_element8(v3, selector - 16);
+ }
+ s390_vec_write_element8(&tmp, i, byte);
+ }
+ *(S390Vector *)v1 = tmp;
+}
+
+void HELPER(vstl)(CPUS390XState *env, const void *v1, uint64_t addr,
+ uint64_t bytes)
+{
+ /* Probe write access before actually modifying memory */
+ probe_write_access(env, addr, bytes, GETPC());
+
+ if (likely(bytes >= 16)) {
+ cpu_stq_data_ra(env, addr, s390_vec_read_element64(v1, 0), GETPC());
+ addr = wrap_address(env, addr + 8);
+ cpu_stq_data_ra(env, addr, s390_vec_read_element64(v1, 1), GETPC());
+ } else {
+ S390Vector tmp = {};
+ int i;
+
+ for (i = 0; i < bytes; i++) {
+ uint8_t byte = s390_vec_read_element8(v1, i);
+
+ cpu_stb_data_ra(env, addr, byte, GETPC());
+ addr = wrap_address(env, addr + 1);
+ }
+ *(S390Vector *)v1 = tmp;
+ }
+}
diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c
index 58a48f39bf..c591748aaf 100644
--- a/tests/boot-serial-test.c
+++ b/tests/boot-serial-test.c
@@ -100,7 +100,9 @@ static testdef_t tests[] = {
{ "ppc64", "ppce500", "", "U-Boot" },
{ "ppc64", "40p", "-m 192", "Memory: 192M" },
{ "ppc64", "mac99", "", "PowerPC,970FX" },
- { "ppc64", "pseries", "", "Open Firmware" },
+ { "ppc64", "pseries",
+ "-machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken",
+ "Open Firmware" },
{ "ppc64", "powernv", "-cpu POWER8", "OPAL" },
{ "ppc64", "sam460ex", "-device e1000", "8086 100e" },
{ "i386", "isapc", "-cpu qemu32 -device sga", "SGABIOS" },
diff --git a/tests/pnv-xscom-test.c b/tests/pnv-xscom-test.c
index 974f8da5b2..63d464048d 100644
--- a/tests/pnv-xscom-test.c
+++ b/tests/pnv-xscom-test.c
@@ -39,7 +39,6 @@ static const PnvChip pnv_chips[] = {
.cfam_id = 0x120d304980000000ull,
.first_core = 0x1,
},
-#if 0 /* POWER9 support is not ready yet */
{
.chip_type = PNV_CHIP_POWER9,
.cpu_model = "POWER9",
@@ -47,7 +46,6 @@ static const PnvChip pnv_chips[] = {
.cfam_id = 0x220d104900008000ull,
.first_core = 0x0,
},
-#endif
};
static uint64_t pnv_xscom_addr(const PnvChip *chip, uint32_t pcba)
diff --git a/tests/prom-env-test.c b/tests/prom-env-test.c
index 4821254b7e..61bc1d1e7b 100644
--- a/tests/prom-env-test.c
+++ b/tests/prom-env-test.c
@@ -44,11 +44,18 @@ static void check_guest_memory(QTestState *qts)
static void test_machine(const void *machine)
{
- const char *extra_args;
+ const char *extra_args = "";
QTestState *qts;
- /* The pseries firmware boots much faster without the default devices */
- extra_args = strcmp(machine, "pseries") == 0 ? "-nodefaults" : "";
+ /*
+ * The pseries firmware boots much faster without the default
+ * devices, it also needs Spectre/Meltdown workarounds disabled to
+ * avoid warnings with TCG
+ */
+ if (strcmp(machine, "pseries") == 0) {
+ extra_args = "-nodefaults"
+ " -machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken";
+ }
qts = qtest_initf("-M %s,accel=tcg %s -prom-env 'use-nvramrc?=true' "
"-prom-env 'nvramrc=%x %x l!' ", (const char *)machine,
diff --git a/tests/pxe-test.c b/tests/pxe-test.c
index 73ac1d1c61..948b0fbdc7 100644
--- a/tests/pxe-test.c
+++ b/tests/pxe-test.c
@@ -25,6 +25,7 @@ static char disk[] = "tests/pxe-test-disk-XXXXXX";
typedef struct testdef {
const char *machine; /* Machine type */
const char *model; /* NIC device model */
+ const char *extra; /* Any additional parameters */
} testdef_t;
static testdef_t x86_tests[] = {
@@ -44,13 +45,16 @@ static testdef_t x86_tests_slow[] = {
};
static testdef_t ppc64_tests[] = {
- { "pseries", "spapr-vlan" },
- { "pseries", "virtio-net-pci", },
+ { "pseries", "spapr-vlan",
+ "-machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken" },
+ { "pseries", "virtio-net-pci",
+ "-machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken" },
{ NULL },
};
static testdef_t ppc64_tests_slow[] = {
- { "pseries", "e1000" },
+ { "pseries", "e1000",
+ "-machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken" },
{ NULL },
};
@@ -63,13 +67,18 @@ static void test_pxe_one(const testdef_t *test, bool ipv6)
{
QTestState *qts;
char *args;
+ const char *extra = test->extra;
+
+ if (!extra) {
+ extra = "";
+ }
args = g_strdup_printf(
"-machine %s,accel=kvm:tcg -nodefaults -boot order=n "
"-netdev user,id=" NETNAME ",tftp=./,bootfile=%s,ipv4=%s,ipv6=%s "
- "-device %s,bootindex=1,netdev=" NETNAME,
+ "-device %s,bootindex=1,netdev=" NETNAME " %s",
test->machine, disk, ipv6 ? "off" : "on", ipv6 ? "on" : "off",
- test->model);
+ test->model, extra);
qts = qtest_init(args);
boot_sector_test(qts);
diff --git a/tests/tcg/mips/include/test_inputs.h b/tests/tcg/mips/include/test_inputs_128.h
index 5406e4e2df..e4c22dde6e 100644
--- a/tests/tcg/mips/include/test_inputs.h
+++ b/tests/tcg/mips/include/test_inputs_128.h
@@ -1,8 +1,8 @@
/*
* Header file for pattern and random test inputs
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -19,8 +19,8 @@
*
*/
-#ifndef TEST_INPUTS_H
-#define TEST_INPUTS_H
+#ifndef TEST_INPUTS_128_H
+#define TEST_INPUTS_128_H
#include <stdint.h>
diff --git a/tests/tcg/mips/include/test_utils.h b/tests/tcg/mips/include/test_utils_128.h
index 9672903eb5..cfd7ad3188 100644
--- a/tests/tcg/mips/include/test_utils.h
+++ b/tests/tcg/mips/include/test_utils_128.h
@@ -1,8 +1,8 @@
/*
* Header file for test utilities
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -19,8 +19,8 @@
*
*/
-#ifndef TEST_UTILS_H
-#define TEST_UTILS_H
+#ifndef TEST_UTILS_128_H
+#define TEST_UTILS_128_H
#include <stdio.h>
#include <stdint.h>
diff --git a/tests/tcg/mips/include/wrappers_msa.h b/tests/tcg/mips/include/wrappers_msa.h
index 9cffd55591..254e215b8a 100644
--- a/tests/tcg/mips/include/wrappers_msa.h
+++ b/tests/tcg/mips/include/wrappers_msa.h
@@ -1,8 +1,8 @@
/*
* Header file for wrappers around MSA instructions assembler invocations
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
diff --git a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_b.c b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_b.c
index d62943123e..c73ed2464e 100644
--- a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_b.c
+++ b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction NLOC.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL (PATTERN_INPUTS_COUNT + RANDOM_INPUTS_COUNT)
diff --git a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_d.c b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_d.c
index fad220ce0f..b10fb23e88 100644
--- a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_d.c
+++ b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction NLOC.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL (PATTERN_INPUTS_COUNT + RANDOM_INPUTS_COUNT)
diff --git a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_h.c b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_h.c
index 84cf974635..c1dc0754e6 100644
--- a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_h.c
+++ b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction NLOC.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL (PATTERN_INPUTS_COUNT + RANDOM_INPUTS_COUNT)
diff --git a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_w.c b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_w.c
index a0ed2020d6..4f7a556dec 100644
--- a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_w.c
+++ b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nloc_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction NLOC.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL (PATTERN_INPUTS_COUNT + RANDOM_INPUTS_COUNT)
diff --git a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_b.c b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_b.c
index 9906eae987..c202ba4856 100644
--- a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_b.c
+++ b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction NLZC.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL (PATTERN_INPUTS_COUNT + RANDOM_INPUTS_COUNT)
diff --git a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_d.c b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_d.c
index 21222e30e8..1edead2860 100644
--- a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_d.c
+++ b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction NLZC.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL (PATTERN_INPUTS_COUNT + RANDOM_INPUTS_COUNT)
diff --git a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_h.c b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_h.c
index fbab9c3f3a..b2724c532e 100644
--- a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_h.c
+++ b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction NLZC.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL (PATTERN_INPUTS_COUNT + RANDOM_INPUTS_COUNT)
diff --git a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_w.c b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_w.c
index dc33366d9e..b547c73621 100644
--- a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_w.c
+++ b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_nlzc_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction NLZC.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL (PATTERN_INPUTS_COUNT + RANDOM_INPUTS_COUNT)
diff --git a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_b.c b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_b.c
index f9033c7ee1..5918e7fcf3 100644
--- a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_b.c
+++ b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction PCNT.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL (PATTERN_INPUTS_COUNT + RANDOM_INPUTS_COUNT)
diff --git a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_d.c b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_d.c
index 132b4d0f4d..667ca3112a 100644
--- a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_d.c
+++ b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction PCNT.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL (PATTERN_INPUTS_COUNT + RANDOM_INPUTS_COUNT)
diff --git a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_h.c b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_h.c
index f469c09e17..2951f86983 100644
--- a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_h.c
+++ b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction PCNT.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL (PATTERN_INPUTS_COUNT + RANDOM_INPUTS_COUNT)
diff --git a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_w.c b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_w.c
index d73eff7a88..ab43ea92cd 100644
--- a/tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_w.c
+++ b/tests/tcg/mips/user/ase/msa/bit-count/test_msa_pcnt_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction PCNT.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL (PATTERN_INPUTS_COUNT + RANDOM_INPUTS_COUNT)
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_b.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_b.c
index 9dca167638..d2ea54f43d 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_b.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_b.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADD_A.B
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_d.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_d.c
index 06a7a502a0..56b81f9090 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_d.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADD_A.D
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_h.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_h.c
index 5e591425aa..fe3c664997 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_h.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADD_A.H
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_w.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_w.c
index a12f9b9ac7..205117ea95 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_add_a_w.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADD_A.W
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_b.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_b.c
index 61b8e6e768..6939e91fe4 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_b.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_b.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADDS_A.B
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_d.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_d.c
index 8350f8f266..af0f3d3700 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_d.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADDS_A.D
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_h.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_h.c
index 952f9f892c..4d3774fef2 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_h.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADDS_A.H
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_w.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_w.c
index d058c64cc4..6f06fdc7cd 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_a_w.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADDS_A.W
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_b.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_b.c
index 63e27da626..e6cb9871f5 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_b.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_b.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADDS_S.B
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_d.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_d.c
index 2719cee6d6..2cda5d9661 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_d.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADDS_S.D
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_h.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_h.c
index 52740964a9..5539322423 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_h.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADDS_S.H
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_w.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_w.c
index c3a6292d89..4f2cc3862e 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_s_w.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADDS_S.W
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_b.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_b.c
index df5d85f2e9..e2d9be38e7 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_b.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_b.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADDS_U.B
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_d.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_d.c
index 10c665bcd7..8418c636b6 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_d.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADDS_U.D
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_h.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_h.c
index 1e32f000a8..8a3b5c5cf5 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_h.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADDS_U.H
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_w.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_w.c
index 938d2da8f4..b18bdc3ea0 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_adds_u_w.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADDS_U.W
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_b.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_b.c
index 5dba38661d..c86c99291e 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_b.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_b.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADDV.B
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_d.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_d.c
index 339878c608..0f301515b3 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_d.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADDV.D
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_h.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_h.c
index 3add379f19..c6b4cf697b 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_h.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADDV.H
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_w.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_w.c
index 41f86abb18..2a565e8ed4 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_addv_w.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction ADDV.W
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_s_d.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_s_d.c
index a6975e7931..7845dc0218 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_s_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_s_d.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction HADD_S.D
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_s_h.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_s_h.c
index 3b95551d4d..ddc2de3ff2 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_s_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_s_h.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction HADD_S.H
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_s_w.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_s_w.c
index 7a940b23cf..887cd1cd5c 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_s_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_s_w.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction HADD_S.W
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_u_d.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_u_d.c
index d4cbe44dfd..f0710f15de 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_u_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_u_d.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction HADD_U.D
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_u_h.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_u_h.c
index ca250575ed..fe55d3eaee 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_u_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_u_h.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction HADD_U.H
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_u_w.c b/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_u_w.c
index b302727f29..babe04d586 100644
--- a/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_u_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-add/test_msa_hadd_u_w.c
@@ -1,7 +1,7 @@
/*
* Test program for MSA instruction HADD_U.W
*
- * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
* Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_s_b.c b/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_s_b.c
new file mode 100644
index 0000000000..675fb90c72
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_s_b.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction AVE_S.B
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "AVE_S.B";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xd4d4d4d4d4d4d4d4ULL, 0xd4d4d4d4d4d4d4d4ULL, },
+ { 0x2a2a2a2a2a2a2a2aULL, 0x2a2a2a2a2a2a2a2aULL, },
+ { 0xe5e5e5e5e5e5e5e5ULL, 0xe5e5e5e5e5e5e5e5ULL, },
+ { 0x1919191919191919ULL, 0x1919191919191919ULL, },
+ { 0xf1c61bf1c61bf1c6ULL, 0x1bf1c61bf1c61bf1ULL, },
+ { 0x0d38e30d38e30d38ULL, 0xe30d38e30d38e30dULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd5d5d5d5d5d5d5d5ULL, 0xd5d5d5d5d5d5d5d5ULL, },
+ { 0x2a2a2a2a2a2a2a2aULL, 0x2a2a2a2a2a2a2a2aULL, },
+ { 0xe6e6e6e6e6e6e6e6ULL, 0xe6e6e6e6e6e6e6e6ULL, },
+ { 0x1919191919191919ULL, 0x1919191919191919ULL, },
+ { 0xf1c71cf1c71cf1c7ULL, 0x1cf1c71cf1c71cf1ULL, },
+ { 0x0e38e30e38e30e38ULL, 0xe30e38e30e38e30eULL, },
+ { 0xd4d4d4d4d4d4d4d4ULL, 0xd4d4d4d4d4d4d4d4ULL, }, /* 16 */
+ { 0xd5d5d5d5d5d5d5d5ULL, 0xd5d5d5d5d5d5d5d5ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0xeeeeeeeeeeeeeeeeULL, 0xeeeeeeeeeeeeeeeeULL, },
+ { 0xc69cf1c69cf1c69cULL, 0xf1c69cf1c69cf1c6ULL, },
+ { 0xe30db8e30db8e30dULL, 0xb8e30db8e30db8e3ULL, },
+ { 0x2a2a2a2a2a2a2a2aULL, 0x2a2a2a2a2a2a2a2aULL, }, /* 24 */
+ { 0x2a2a2a2a2a2a2a2aULL, 0x2a2a2a2a2a2a2a2aULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x1010101010101010ULL, 0x1010101010101010ULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x1cf1461cf1461cf1ULL, 0x461cf1461cf1461cULL, },
+ { 0x38630e38630e3863ULL, 0x0e38630e38630e38ULL, },
+ { 0xe5e5e5e5e5e5e5e5ULL, 0xe5e5e5e5e5e5e5e5ULL, }, /* 32 */
+ { 0xe6e6e6e6e6e6e6e6ULL, 0xe6e6e6e6e6e6e6e6ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x1010101010101010ULL, 0x1010101010101010ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xd7ad02d7ad02d7adULL, 0x02d7ad02d7ad02d7ULL, },
+ { 0xf41ec9f41ec9f41eULL, 0xc9f41ec9f41ec9f4ULL, },
+ { 0x1919191919191919ULL, 0x1919191919191919ULL, }, /* 40 */
+ { 0x1919191919191919ULL, 0x1919191919191919ULL, },
+ { 0xeeeeeeeeeeeeeeeeULL, 0xeeeeeeeeeeeeeeeeULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x0be0350be0350be0ULL, 0x350be0350be0350bULL, },
+ { 0x2752fd2752fd2752ULL, 0xfd2752fd2752fd27ULL, },
+ { 0xf1c61bf1c61bf1c6ULL, 0x1bf1c61bf1c61bf1ULL, }, /* 48 */
+ { 0xf1c71cf1c71cf1c7ULL, 0x1cf1c71cf1c71cf1ULL, },
+ { 0xc69cf1c69cf1c69cULL, 0xf1c69cf1c69cf1c6ULL, },
+ { 0x1cf1461cf1461cf1ULL, 0x461cf1461cf1461cULL, },
+ { 0xd7ad02d7ad02d7adULL, 0x02d7ad02d7ad02d7ULL, },
+ { 0x0be0350be0350be0ULL, 0x350be0350be0350bULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0d38e30d38e30d38ULL, 0xe30d38e30d38e30dULL, }, /* 56 */
+ { 0x0e38e30e38e30e38ULL, 0xe30e38e30e38e30eULL, },
+ { 0xe30db8e30db8e30dULL, 0xb8e30db8e30db8e3ULL, },
+ { 0x38630e38630e3863ULL, 0x0e38630e38630e38ULL, },
+ { 0xf41ec9f41ec9f41eULL, 0xc9f41ec9f41ec9f4ULL, },
+ { 0x2752fd2752fd2752ULL, 0xfd2752fd2752fd27ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0xc114f3173afa0e24ULL, 0x2e2fe33c095d0104ULL, },
+ { 0x9a62cabbf018f0e0ULL, 0x391fe82ed453ea10ULL, },
+ { 0xfc5cfe0c43491b47ULL, 0xec2cc91bd35ec9d6ULL, },
+ { 0xc114f3173afa0e24ULL, 0x2e2fe33c095d0104ULL, },
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xd30cd70603b1a9c4ULL, 0x1ce7c00ce0353b08ULL, },
+ { 0x35060b5855e2d42bULL, 0xcff4a1f9df401aceULL, },
+ { 0x9a62cabbf018f0e0ULL, 0x391fe82ed453ea10ULL, }, /* 72 */
+ { 0xd30cd70603b1a9c4ULL, 0x1ce7c00ce0353b08ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x0e54e2fb0b00b6e7ULL, 0xdae4a7ebaa3603daULL, },
+ { 0xfc5cfe0c43491b47ULL, 0xec2cc91bd35ec9d6ULL, },
+ { 0x35060b5855e2d42bULL, 0xcff4a1f9df401aceULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVE_S_B(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVE_S_B(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_s_d.c b/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_s_d.c
new file mode 100644
index 0000000000..e87d414b5f
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_s_d.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction AVE_S.D
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "AVE_S.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xd555555555555554ULL, 0xd555555555555554ULL, },
+ { 0x2aaaaaaaaaaaaaaaULL, 0x2aaaaaaaaaaaaaaaULL, },
+ { 0xe666666666666665ULL, 0xe666666666666665ULL, },
+ { 0x1999999999999999ULL, 0x1999999999999999ULL, },
+ { 0xf1c71c71c71c71c6ULL, 0x1c71c71c71c71c71ULL, },
+ { 0x0e38e38e38e38e38ULL, 0xe38e38e38e38e38dULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd555555555555555ULL, 0xd555555555555555ULL, },
+ { 0x2aaaaaaaaaaaaaaaULL, 0x2aaaaaaaaaaaaaaaULL, },
+ { 0xe666666666666666ULL, 0xe666666666666666ULL, },
+ { 0x1999999999999999ULL, 0x1999999999999999ULL, },
+ { 0xf1c71c71c71c71c7ULL, 0x1c71c71c71c71c71ULL, },
+ { 0x0e38e38e38e38e38ULL, 0xe38e38e38e38e38eULL, },
+ { 0xd555555555555554ULL, 0xd555555555555554ULL, }, /* 16 */
+ { 0xd555555555555555ULL, 0xd555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0xeeeeeeeeeeeeeeeeULL, 0xeeeeeeeeeeeeeeeeULL, },
+ { 0xc71c71c71c71c71cULL, 0xf1c71c71c71c71c6ULL, },
+ { 0xe38e38e38e38e38dULL, 0xb8e38e38e38e38e3ULL, },
+ { 0x2aaaaaaaaaaaaaaaULL, 0x2aaaaaaaaaaaaaaaULL, }, /* 24 */
+ { 0x2aaaaaaaaaaaaaaaULL, 0x2aaaaaaaaaaaaaaaULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x1111111111111110ULL, 0x1111111111111110ULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x1c71c71c71c71c71ULL, 0x471c71c71c71c71cULL, },
+ { 0x38e38e38e38e38e3ULL, 0x0e38e38e38e38e38ULL, },
+ { 0xe666666666666665ULL, 0xe666666666666665ULL, }, /* 32 */
+ { 0xe666666666666666ULL, 0xe666666666666666ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x1111111111111110ULL, 0x1111111111111110ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xd82d82d82d82d82dULL, 0x02d82d82d82d82d7ULL, },
+ { 0xf49f49f49f49f49eULL, 0xc9f49f49f49f49f4ULL, },
+ { 0x1999999999999999ULL, 0x1999999999999999ULL, }, /* 40 */
+ { 0x1999999999999999ULL, 0x1999999999999999ULL, },
+ { 0xeeeeeeeeeeeeeeeeULL, 0xeeeeeeeeeeeeeeeeULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x0b60b60b60b60b60ULL, 0x360b60b60b60b60bULL, },
+ { 0x27d27d27d27d27d2ULL, 0xfd27d27d27d27d27ULL, },
+ { 0xf1c71c71c71c71c6ULL, 0x1c71c71c71c71c71ULL, }, /* 48 */
+ { 0xf1c71c71c71c71c7ULL, 0x1c71c71c71c71c71ULL, },
+ { 0xc71c71c71c71c71cULL, 0xf1c71c71c71c71c6ULL, },
+ { 0x1c71c71c71c71c71ULL, 0x471c71c71c71c71cULL, },
+ { 0xd82d82d82d82d82dULL, 0x02d82d82d82d82d7ULL, },
+ { 0x0b60b60b60b60b60ULL, 0x360b60b60b60b60bULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0e38e38e38e38e38ULL, 0xe38e38e38e38e38dULL, }, /* 56 */
+ { 0x0e38e38e38e38e38ULL, 0xe38e38e38e38e38eULL, },
+ { 0xe38e38e38e38e38dULL, 0xb8e38e38e38e38e3ULL, },
+ { 0x38e38e38e38e38e3ULL, 0x0e38e38e38e38e38ULL, },
+ { 0xf49f49f49f49f49eULL, 0xc9f49f49f49f49f4ULL, },
+ { 0x27d27d27d27d27d2ULL, 0xfd27d27d27d27d27ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0xc2147397bafb0e24ULL, 0x2f2f633c89dd8184ULL, },
+ { 0x9a62cabb7118f060ULL, 0x399fe92f54d36a90ULL, },
+ { 0xfc5cfe8cc34a1bc7ULL, 0xecac4a1bd3df4956ULL, },
+ { 0xc2147397bafb0e24ULL, 0x2f2f633c89dd8184ULL, },
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xd40c578703b1a944ULL, 0x1d68410ce0353c08ULL, },
+ { 0x36068b5855e2d4abULL, 0xd074a1f95f411aceULL, },
+ { 0x9a62cabb7118f060ULL, 0x399fe92f54d36a90ULL, }, /* 72 */
+ { 0xd40c578703b1a944ULL, 0x1d68410ce0353c08ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x0e54e27c0c00b6e7ULL, 0xdae527ec2a3703daULL, },
+ { 0xfc5cfe8cc34a1bc7ULL, 0xecac4a1bd3df4956ULL, },
+ { 0x36068b5855e2d4abULL, 0xd074a1f95f411aceULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVE_S_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVE_S_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_s_h.c b/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_s_h.c
new file mode 100644
index 0000000000..c850543587
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_s_h.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction AVE_S.H
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "AVE_S.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xd554d554d554d554ULL, 0xd554d554d554d554ULL, },
+ { 0x2aaa2aaa2aaa2aaaULL, 0x2aaa2aaa2aaa2aaaULL, },
+ { 0xe665e665e665e665ULL, 0xe665e665e665e665ULL, },
+ { 0x1999199919991999ULL, 0x1999199919991999ULL, },
+ { 0xf1c61c71c71bf1c6ULL, 0x1c71c71bf1c61c71ULL, },
+ { 0x0e38e38d38e30e38ULL, 0xe38d38e30e38e38dULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd555d555d555d555ULL, 0xd555d555d555d555ULL, },
+ { 0x2aaa2aaa2aaa2aaaULL, 0x2aaa2aaa2aaa2aaaULL, },
+ { 0xe666e666e666e666ULL, 0xe666e666e666e666ULL, },
+ { 0x1999199919991999ULL, 0x1999199919991999ULL, },
+ { 0xf1c71c71c71cf1c7ULL, 0x1c71c71cf1c71c71ULL, },
+ { 0x0e38e38e38e30e38ULL, 0xe38e38e30e38e38eULL, },
+ { 0xd554d554d554d554ULL, 0xd554d554d554d554ULL, }, /* 16 */
+ { 0xd555d555d555d555ULL, 0xd555d555d555d555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0xeeeeeeeeeeeeeeeeULL, 0xeeeeeeeeeeeeeeeeULL, },
+ { 0xc71cf1c69c71c71cULL, 0xf1c69c71c71cf1c6ULL, },
+ { 0xe38db8e30e38e38dULL, 0xb8e30e38e38db8e3ULL, },
+ { 0x2aaa2aaa2aaa2aaaULL, 0x2aaa2aaa2aaa2aaaULL, }, /* 24 */
+ { 0x2aaa2aaa2aaa2aaaULL, 0x2aaa2aaa2aaa2aaaULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x1110111011101110ULL, 0x1110111011101110ULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x1c71471cf1c61c71ULL, 0x471cf1c61c71471cULL, },
+ { 0x38e30e38638e38e3ULL, 0x0e38638e38e30e38ULL, },
+ { 0xe665e665e665e665ULL, 0xe665e665e665e665ULL, }, /* 32 */
+ { 0xe666e666e666e666ULL, 0xe666e666e666e666ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x1110111011101110ULL, 0x1110111011101110ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xd82d02d7ad82d82dULL, 0x02d7ad82d82d02d7ULL, },
+ { 0xf49ec9f41f49f49eULL, 0xc9f41f49f49ec9f4ULL, },
+ { 0x1999199919991999ULL, 0x1999199919991999ULL, }, /* 40 */
+ { 0x1999199919991999ULL, 0x1999199919991999ULL, },
+ { 0xeeeeeeeeeeeeeeeeULL, 0xeeeeeeeeeeeeeeeeULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x0b60360be0b50b60ULL, 0x360be0b50b60360bULL, },
+ { 0x27d2fd27527d27d2ULL, 0xfd27527d27d2fd27ULL, },
+ { 0xf1c61c71c71bf1c6ULL, 0x1c71c71bf1c61c71ULL, }, /* 48 */
+ { 0xf1c71c71c71cf1c7ULL, 0x1c71c71cf1c71c71ULL, },
+ { 0xc71cf1c69c71c71cULL, 0xf1c69c71c71cf1c6ULL, },
+ { 0x1c71471cf1c61c71ULL, 0x471cf1c61c71471cULL, },
+ { 0xd82d02d7ad82d82dULL, 0x02d7ad82d82d02d7ULL, },
+ { 0x0b60360be0b50b60ULL, 0x360be0b50b60360bULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0e38e38d38e30e38ULL, 0xe38d38e30e38e38dULL, }, /* 56 */
+ { 0x0e38e38e38e30e38ULL, 0xe38e38e30e38e38eULL, },
+ { 0xe38db8e30e38e38dULL, 0xb8e30e38e38db8e3ULL, },
+ { 0x38e30e38638e38e3ULL, 0x0e38638e38e30e38ULL, },
+ { 0xf49ec9f41f49f49eULL, 0xc9f41f49f49ec9f4ULL, },
+ { 0x27d2fd27527d27d2ULL, 0xfd27527d27d2fd27ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0xc214f3973afa0e24ULL, 0x2f2fe33c09dd0184ULL, },
+ { 0x9a62cabbf118f060ULL, 0x399fe92ed4d3ea90ULL, },
+ { 0xfc5cfe8c43491bc7ULL, 0xecacca1bd3dec956ULL, },
+ { 0xc214f3973afa0e24ULL, 0x2f2fe33c09dd0184ULL, },
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xd40cd78603b1a944ULL, 0x1d67c10ce0353c08ULL, },
+ { 0x36060b5855e2d4abULL, 0xd074a1f9df401aceULL, },
+ { 0x9a62cabbf118f060ULL, 0x399fe92ed4d3ea90ULL, }, /* 72 */
+ { 0xd40cd78603b1a944ULL, 0x1d67c10ce0353c08ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x0e54e27b0c00b6e7ULL, 0xdae4a7ebaa3603daULL, },
+ { 0xfc5cfe8c43491bc7ULL, 0xecacca1bd3dec956ULL, },
+ { 0x36060b5855e2d4abULL, 0xd074a1f9df401aceULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVE_S_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVE_S_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_s_w.c b/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_s_w.c
new file mode 100644
index 0000000000..3220574ca0
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_s_w.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction AVE_S.W
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "AVE_S.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xd5555554d5555554ULL, 0xd5555554d5555554ULL, },
+ { 0x2aaaaaaa2aaaaaaaULL, 0x2aaaaaaa2aaaaaaaULL, },
+ { 0xe6666665e6666665ULL, 0xe6666665e6666665ULL, },
+ { 0x1999999919999999ULL, 0x1999999919999999ULL, },
+ { 0xf1c71c71c71c71c6ULL, 0x1c71c71bf1c71c71ULL, },
+ { 0x0e38e38d38e38e38ULL, 0xe38e38e30e38e38dULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd5555555d5555555ULL, 0xd5555555d5555555ULL, },
+ { 0x2aaaaaaa2aaaaaaaULL, 0x2aaaaaaa2aaaaaaaULL, },
+ { 0xe6666666e6666666ULL, 0xe6666666e6666666ULL, },
+ { 0x1999999919999999ULL, 0x1999999919999999ULL, },
+ { 0xf1c71c71c71c71c7ULL, 0x1c71c71cf1c71c71ULL, },
+ { 0x0e38e38e38e38e38ULL, 0xe38e38e30e38e38eULL, },
+ { 0xd5555554d5555554ULL, 0xd5555554d5555554ULL, }, /* 16 */
+ { 0xd5555555d5555555ULL, 0xd5555555d5555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0xeeeeeeeeeeeeeeeeULL, 0xeeeeeeeeeeeeeeeeULL, },
+ { 0xc71c71c69c71c71cULL, 0xf1c71c71c71c71c6ULL, },
+ { 0xe38e38e30e38e38dULL, 0xb8e38e38e38e38e3ULL, },
+ { 0x2aaaaaaa2aaaaaaaULL, 0x2aaaaaaa2aaaaaaaULL, }, /* 24 */
+ { 0x2aaaaaaa2aaaaaaaULL, 0x2aaaaaaa2aaaaaaaULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x1111111011111110ULL, 0x1111111011111110ULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x1c71c71cf1c71c71ULL, 0x471c71c61c71c71cULL, },
+ { 0x38e38e38638e38e3ULL, 0x0e38e38e38e38e38ULL, },
+ { 0xe6666665e6666665ULL, 0xe6666665e6666665ULL, }, /* 32 */
+ { 0xe6666666e6666666ULL, 0xe6666666e6666666ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x1111111011111110ULL, 0x1111111011111110ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xd82d82d7ad82d82dULL, 0x02d82d82d82d82d7ULL, },
+ { 0xf49f49f41f49f49eULL, 0xc9f49f49f49f49f4ULL, },
+ { 0x1999999919999999ULL, 0x1999999919999999ULL, }, /* 40 */
+ { 0x1999999919999999ULL, 0x1999999919999999ULL, },
+ { 0xeeeeeeeeeeeeeeeeULL, 0xeeeeeeeeeeeeeeeeULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x0b60b60be0b60b60ULL, 0x360b60b50b60b60bULL, },
+ { 0x27d27d27527d27d2ULL, 0xfd27d27d27d27d27ULL, },
+ { 0xf1c71c71c71c71c6ULL, 0x1c71c71bf1c71c71ULL, }, /* 48 */
+ { 0xf1c71c71c71c71c7ULL, 0x1c71c71cf1c71c71ULL, },
+ { 0xc71c71c69c71c71cULL, 0xf1c71c71c71c71c6ULL, },
+ { 0x1c71c71cf1c71c71ULL, 0x471c71c61c71c71cULL, },
+ { 0xd82d82d7ad82d82dULL, 0x02d82d82d82d82d7ULL, },
+ { 0x0b60b60be0b60b60ULL, 0x360b60b50b60b60bULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0e38e38d38e38e38ULL, 0xe38e38e30e38e38dULL, }, /* 56 */
+ { 0x0e38e38e38e38e38ULL, 0xe38e38e30e38e38eULL, },
+ { 0xe38e38e30e38e38dULL, 0xb8e38e38e38e38e3ULL, },
+ { 0x38e38e38638e38e3ULL, 0x0e38e38e38e38e38ULL, },
+ { 0xf49f49f41f49f49eULL, 0xc9f49f49f49f49f4ULL, },
+ { 0x27d27d27527d27d2ULL, 0xfd27d27d27d27d27ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0xc21473973afb0e24ULL, 0x2f2f633c09dd8184ULL, },
+ { 0x9a62cabbf118f060ULL, 0x399fe92ed4d36a90ULL, },
+ { 0xfc5cfe8c434a1bc7ULL, 0xecac4a1bd3df4956ULL, },
+ { 0xc21473973afb0e24ULL, 0x2f2f633c09dd8184ULL, },
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xd40c578603b1a944ULL, 0x1d68410ce0353c08ULL, },
+ { 0x36068b5855e2d4abULL, 0xd074a1f9df411aceULL, },
+ { 0x9a62cabbf118f060ULL, 0x399fe92ed4d36a90ULL, }, /* 72 */
+ { 0xd40c578603b1a944ULL, 0x1d68410ce0353c08ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x0e54e27b0c00b6e7ULL, 0xdae527ebaa3703daULL, },
+ { 0xfc5cfe8c434a1bc7ULL, 0xecac4a1bd3df4956ULL, },
+ { 0x36068b5855e2d4abULL, 0xd074a1f9df411aceULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVE_S_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVE_S_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_u_b.c b/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_u_b.c
new file mode 100644
index 0000000000..c3f96a6a5f
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_u_b.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction AVE_U.B
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "AVE_U.B";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0x7f7f7f7f7f7f7f7fULL, 0x7f7f7f7f7f7f7f7fULL, },
+ { 0xd4d4d4d4d4d4d4d4ULL, 0xd4d4d4d4d4d4d4d4ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xe5e5e5e5e5e5e5e5ULL, 0xe5e5e5e5e5e5e5e5ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xf1c69bf1c69bf1c6ULL, 0x9bf1c69bf1c69bf1ULL, },
+ { 0x8db8e38db8e38db8ULL, 0xe38db8e38db8e38dULL, },
+ { 0x7f7f7f7f7f7f7f7fULL, 0x7f7f7f7f7f7f7f7fULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x2a2a2a2a2a2a2a2aULL, 0x2a2a2a2a2a2a2a2aULL, },
+ { 0x6666666666666666ULL, 0x6666666666666666ULL, },
+ { 0x1919191919191919ULL, 0x1919191919191919ULL, },
+ { 0x71471c71471c7147ULL, 0x1c71471c71471c71ULL, },
+ { 0x0e38630e38630e38ULL, 0x630e38630e38630eULL, },
+ { 0xd4d4d4d4d4d4d4d4ULL, 0xd4d4d4d4d4d4d4d4ULL, }, /* 16 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x7f7f7f7f7f7f7f7fULL, 0x7f7f7f7f7f7f7f7fULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x6e6e6e6e6e6e6e6eULL, 0x6e6e6e6e6e6e6e6eULL, },
+ { 0xc69c71c69c71c69cULL, 0x71c69c71c69c71c6ULL, },
+ { 0x638db8638db8638dULL, 0xb8638db8638db863ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 24 */
+ { 0x2a2a2a2a2a2a2a2aULL, 0x2a2a2a2a2a2a2a2aULL, },
+ { 0x7f7f7f7f7f7f7f7fULL, 0x7f7f7f7f7f7f7f7fULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x9090909090909090ULL, 0x9090909090909090ULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x9c71469c71469c71ULL, 0x469c71469c71469cULL, },
+ { 0x38638e38638e3863ULL, 0x8e38638e38638e38ULL, },
+ { 0xe5e5e5e5e5e5e5e5ULL, 0xe5e5e5e5e5e5e5e5ULL, }, /* 32 */
+ { 0x6666666666666666ULL, 0x6666666666666666ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x9090909090909090ULL, 0x9090909090909090ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x7f7f7f7f7f7f7f7fULL, 0x7f7f7f7f7f7f7f7fULL, },
+ { 0xd7ad82d7ad82d7adULL, 0x82d7ad82d7ad82d7ULL, },
+ { 0x749ec9749ec9749eULL, 0xc9749ec9749ec974ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, }, /* 40 */
+ { 0x1919191919191919ULL, 0x1919191919191919ULL, },
+ { 0x6e6e6e6e6e6e6e6eULL, 0x6e6e6e6e6e6e6e6eULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x7f7f7f7f7f7f7f7fULL, 0x7f7f7f7f7f7f7f7fULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8b60358b60358b60ULL, 0x358b60358b60358bULL, },
+ { 0x27527d27527d2752ULL, 0x7d27527d27527d27ULL, },
+ { 0xf1c69bf1c69bf1c6ULL, 0x9bf1c69bf1c69bf1ULL, }, /* 48 */
+ { 0x71471c71471c7147ULL, 0x1c71471c71471c71ULL, },
+ { 0xc69c71c69c71c69cULL, 0x71c69c71c69c71c6ULL, },
+ { 0x9c71469c71469c71ULL, 0x469c71469c71469cULL, },
+ { 0xd7ad82d7ad82d7adULL, 0x82d7ad82d7ad82d7ULL, },
+ { 0x8b60358b60358b60ULL, 0x358b60358b60358bULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x7f7f7f7f7f7f7f7fULL, 0x7f7f7f7f7f7f7f7fULL, },
+ { 0x8db8e38db8e38db8ULL, 0xe38db8e38db8e38dULL, }, /* 56 */
+ { 0x0e38630e38630e38ULL, 0x630e38630e38630eULL, },
+ { 0x638db8638db8638dULL, 0xb8638db8638db863ULL, },
+ { 0x38638e38638e3863ULL, 0x8e38638e38638e38ULL, },
+ { 0x749ec9749ec9749eULL, 0xc9749ec9749ec974ULL, },
+ { 0x27527d27527d2752ULL, 0x7d27527d27527d27ULL, },
+ { 0x7f7f7f7f7f7f7f7fULL, 0x7f7f7f7f7f7f7f7fULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0xc19473973a7a8e24ULL, 0x2eaf633c895d8184ULL, },
+ { 0x9a62cabb70987060ULL, 0x399f68aed4536a10ULL, },
+ { 0x7c5c7e8c43499b47ULL, 0x6cac499bd35ec956ULL, },
+ { 0xc19473973a7a8e24ULL, 0x2eaf633c895d8184ULL, },
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xd38c578683b1a944ULL, 0x1ce7c08c60353b88ULL, },
+ { 0xb5860b585562d42bULL, 0x4ff4a1795f409aceULL, },
+ { 0x9a62cabb70987060ULL, 0x399f68aed4536a10ULL, }, /* 72 */
+ { 0xd38c578683b1a944ULL, 0x1ce7c08c60353b88ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x8e54627b8b80b667ULL, 0x5ae4a7ebaa36835aULL, },
+ { 0x7c5c7e8c43499b47ULL, 0x6cac499bd35ec956ULL, },
+ { 0xb5860b585562d42bULL, 0x4ff4a1795f409aceULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVE_U_B(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVE_U_B(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_u_d.c b/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_u_d.c
new file mode 100644
index 0000000000..3a78629cd8
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_u_d.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction AVE_U.D
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "AVE_U.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL, },
+ { 0xd555555555555554ULL, 0xd555555555555554ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xe666666666666665ULL, 0xe666666666666665ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xf1c71c71c71c71c6ULL, 0x9c71c71c71c71c71ULL, },
+ { 0x8e38e38e38e38e38ULL, 0xe38e38e38e38e38dULL, },
+ { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x2aaaaaaaaaaaaaaaULL, 0x2aaaaaaaaaaaaaaaULL, },
+ { 0x6666666666666666ULL, 0x6666666666666666ULL, },
+ { 0x1999999999999999ULL, 0x1999999999999999ULL, },
+ { 0x71c71c71c71c71c7ULL, 0x1c71c71c71c71c71ULL, },
+ { 0x0e38e38e38e38e38ULL, 0x638e38e38e38e38eULL, },
+ { 0xd555555555555554ULL, 0xd555555555555554ULL, }, /* 16 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x6eeeeeeeeeeeeeeeULL, 0x6eeeeeeeeeeeeeeeULL, },
+ { 0xc71c71c71c71c71cULL, 0x71c71c71c71c71c6ULL, },
+ { 0x638e38e38e38e38dULL, 0xb8e38e38e38e38e3ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 24 */
+ { 0x2aaaaaaaaaaaaaaaULL, 0x2aaaaaaaaaaaaaaaULL, },
+ { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x9111111111111110ULL, 0x9111111111111110ULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x9c71c71c71c71c71ULL, 0x471c71c71c71c71cULL, },
+ { 0x38e38e38e38e38e3ULL, 0x8e38e38e38e38e38ULL, },
+ { 0xe666666666666665ULL, 0xe666666666666665ULL, }, /* 32 */
+ { 0x6666666666666666ULL, 0x6666666666666666ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x9111111111111110ULL, 0x9111111111111110ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL, },
+ { 0xd82d82d82d82d82dULL, 0x82d82d82d82d82d7ULL, },
+ { 0x749f49f49f49f49eULL, 0xc9f49f49f49f49f4ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, }, /* 40 */
+ { 0x1999999999999999ULL, 0x1999999999999999ULL, },
+ { 0x6eeeeeeeeeeeeeeeULL, 0x6eeeeeeeeeeeeeeeULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8b60b60b60b60b60ULL, 0x360b60b60b60b60bULL, },
+ { 0x27d27d27d27d27d2ULL, 0x7d27d27d27d27d27ULL, },
+ { 0xf1c71c71c71c71c6ULL, 0x9c71c71c71c71c71ULL, }, /* 48 */
+ { 0x71c71c71c71c71c7ULL, 0x1c71c71c71c71c71ULL, },
+ { 0xc71c71c71c71c71cULL, 0x71c71c71c71c71c6ULL, },
+ { 0x9c71c71c71c71c71ULL, 0x471c71c71c71c71cULL, },
+ { 0xd82d82d82d82d82dULL, 0x82d82d82d82d82d7ULL, },
+ { 0x8b60b60b60b60b60ULL, 0x360b60b60b60b60bULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL, },
+ { 0x8e38e38e38e38e38ULL, 0xe38e38e38e38e38dULL, }, /* 56 */
+ { 0x0e38e38e38e38e38ULL, 0x638e38e38e38e38eULL, },
+ { 0x638e38e38e38e38dULL, 0xb8e38e38e38e38e3ULL, },
+ { 0x38e38e38e38e38e3ULL, 0x8e38e38e38e38e38ULL, },
+ { 0x749f49f49f49f49eULL, 0xc9f49f49f49f49f4ULL, },
+ { 0x27d27d27d27d27d2ULL, 0x7d27d27d27d27d27ULL, },
+ { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0xc2147397bafb0e24ULL, 0x2f2f633c89dd8184ULL, },
+ { 0x9a62cabb7118f060ULL, 0x399fe92f54d36a90ULL, },
+ { 0x7c5cfe8cc34a1bc7ULL, 0x6cac4a1bd3df4956ULL, },
+ { 0xc2147397bafb0e24ULL, 0x2f2f633c89dd8184ULL, },
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xd40c578703b1a944ULL, 0x1d68410ce0353c08ULL, },
+ { 0xb6068b5855e2d4abULL, 0x5074a1f95f411aceULL, },
+ { 0x9a62cabb7118f060ULL, 0x399fe92f54d36a90ULL, }, /* 72 */
+ { 0xd40c578703b1a944ULL, 0x1d68410ce0353c08ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x8e54e27c0c00b6e7ULL, 0x5ae527ec2a3703daULL, },
+ { 0x7c5cfe8cc34a1bc7ULL, 0x6cac4a1bd3df4956ULL, },
+ { 0xb6068b5855e2d4abULL, 0x5074a1f95f411aceULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVE_U_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVE_U_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_u_h.c b/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_u_h.c
new file mode 100644
index 0000000000..b7db518afb
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_u_h.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction AVE_U.H
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "AVE_U.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0x7fff7fff7fff7fffULL, 0x7fff7fff7fff7fffULL, },
+ { 0xd554d554d554d554ULL, 0xd554d554d554d554ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xe665e665e665e665ULL, 0xe665e665e665e665ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xf1c69c71c71bf1c6ULL, 0x9c71c71bf1c69c71ULL, },
+ { 0x8e38e38db8e38e38ULL, 0xe38db8e38e38e38dULL, },
+ { 0x7fff7fff7fff7fffULL, 0x7fff7fff7fff7fffULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x2aaa2aaa2aaa2aaaULL, 0x2aaa2aaa2aaa2aaaULL, },
+ { 0x6666666666666666ULL, 0x6666666666666666ULL, },
+ { 0x1999199919991999ULL, 0x1999199919991999ULL, },
+ { 0x71c71c71471c71c7ULL, 0x1c71471c71c71c71ULL, },
+ { 0x0e38638e38e30e38ULL, 0x638e38e30e38638eULL, },
+ { 0xd554d554d554d554ULL, 0xd554d554d554d554ULL, }, /* 16 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x7fff7fff7fff7fffULL, 0x7fff7fff7fff7fffULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x6eee6eee6eee6eeeULL, 0x6eee6eee6eee6eeeULL, },
+ { 0xc71c71c69c71c71cULL, 0x71c69c71c71c71c6ULL, },
+ { 0x638db8e38e38638dULL, 0xb8e38e38638db8e3ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 24 */
+ { 0x2aaa2aaa2aaa2aaaULL, 0x2aaa2aaa2aaa2aaaULL, },
+ { 0x7fff7fff7fff7fffULL, 0x7fff7fff7fff7fffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x9110911091109110ULL, 0x9110911091109110ULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x9c71471c71c69c71ULL, 0x471c71c69c71471cULL, },
+ { 0x38e38e38638e38e3ULL, 0x8e38638e38e38e38ULL, },
+ { 0xe665e665e665e665ULL, 0xe665e665e665e665ULL, }, /* 32 */
+ { 0x6666666666666666ULL, 0x6666666666666666ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x9110911091109110ULL, 0x9110911091109110ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x7fff7fff7fff7fffULL, 0x7fff7fff7fff7fffULL, },
+ { 0xd82d82d7ad82d82dULL, 0x82d7ad82d82d82d7ULL, },
+ { 0x749ec9f49f49749eULL, 0xc9f49f49749ec9f4ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, }, /* 40 */
+ { 0x1999199919991999ULL, 0x1999199919991999ULL, },
+ { 0x6eee6eee6eee6eeeULL, 0x6eee6eee6eee6eeeULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x7fff7fff7fff7fffULL, 0x7fff7fff7fff7fffULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8b60360b60b58b60ULL, 0x360b60b58b60360bULL, },
+ { 0x27d27d27527d27d2ULL, 0x7d27527d27d27d27ULL, },
+ { 0xf1c69c71c71bf1c6ULL, 0x9c71c71bf1c69c71ULL, }, /* 48 */
+ { 0x71c71c71471c71c7ULL, 0x1c71471c71c71c71ULL, },
+ { 0xc71c71c69c71c71cULL, 0x71c69c71c71c71c6ULL, },
+ { 0x9c71471c71c69c71ULL, 0x471c71c69c71471cULL, },
+ { 0xd82d82d7ad82d82dULL, 0x82d7ad82d82d82d7ULL, },
+ { 0x8b60360b60b58b60ULL, 0x360b60b58b60360bULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x7fff7fff7fff7fffULL, 0x7fff7fff7fff7fffULL, },
+ { 0x8e38e38db8e38e38ULL, 0xe38db8e38e38e38dULL, }, /* 56 */
+ { 0x0e38638e38e30e38ULL, 0x638e38e30e38638eULL, },
+ { 0x638db8e38e38638dULL, 0xb8e38e38638db8e3ULL, },
+ { 0x38e38e38638e38e3ULL, 0x8e38638e38e38e38ULL, },
+ { 0x749ec9f49f49749eULL, 0xc9f49f49749ec9f4ULL, },
+ { 0x27d27d27527d27d2ULL, 0x7d27527d27d27d27ULL, },
+ { 0x7fff7fff7fff7fffULL, 0x7fff7fff7fff7fffULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0xc21473973afa8e24ULL, 0x2f2f633c89dd8184ULL, },
+ { 0x9a62cabb71187060ULL, 0x399f692ed4d36a90ULL, },
+ { 0x7c5c7e8c43499bc7ULL, 0x6cac4a1bd3dec956ULL, },
+ { 0xc21473973afa8e24ULL, 0x2f2f633c89dd8184ULL, },
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xd40c578683b1a944ULL, 0x1d67c10c60353c08ULL, },
+ { 0xb6060b5855e2d4abULL, 0x5074a1f95f409aceULL, },
+ { 0x9a62cabb71187060ULL, 0x399f692ed4d36a90ULL, }, /* 72 */
+ { 0xd40c578683b1a944ULL, 0x1d67c10c60353c08ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x8e54627b8c00b6e7ULL, 0x5ae4a7ebaa3683daULL, },
+ { 0x7c5c7e8c43499bc7ULL, 0x6cac4a1bd3dec956ULL, },
+ { 0xb6060b5855e2d4abULL, 0x5074a1f95f409aceULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVE_U_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVE_U_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_u_w.c b/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_u_w.c
new file mode 100644
index 0000000000..75e2409f1f
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-average/test_msa_ave_u_w.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction AVE_U.W
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "AVE_U.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0x7fffffff7fffffffULL, 0x7fffffff7fffffffULL, },
+ { 0xd5555554d5555554ULL, 0xd5555554d5555554ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xe6666665e6666665ULL, 0xe6666665e6666665ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xf1c71c71c71c71c6ULL, 0x9c71c71bf1c71c71ULL, },
+ { 0x8e38e38db8e38e38ULL, 0xe38e38e38e38e38dULL, },
+ { 0x7fffffff7fffffffULL, 0x7fffffff7fffffffULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x2aaaaaaa2aaaaaaaULL, 0x2aaaaaaa2aaaaaaaULL, },
+ { 0x6666666666666666ULL, 0x6666666666666666ULL, },
+ { 0x1999999919999999ULL, 0x1999999919999999ULL, },
+ { 0x71c71c71471c71c7ULL, 0x1c71c71c71c71c71ULL, },
+ { 0x0e38e38e38e38e38ULL, 0x638e38e30e38e38eULL, },
+ { 0xd5555554d5555554ULL, 0xd5555554d5555554ULL, }, /* 16 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x7fffffff7fffffffULL, 0x7fffffff7fffffffULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x6eeeeeee6eeeeeeeULL, 0x6eeeeeee6eeeeeeeULL, },
+ { 0xc71c71c69c71c71cULL, 0x71c71c71c71c71c6ULL, },
+ { 0x638e38e38e38e38dULL, 0xb8e38e38638e38e3ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 24 */
+ { 0x2aaaaaaa2aaaaaaaULL, 0x2aaaaaaa2aaaaaaaULL, },
+ { 0x7fffffff7fffffffULL, 0x7fffffff7fffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x9111111091111110ULL, 0x9111111091111110ULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x9c71c71c71c71c71ULL, 0x471c71c69c71c71cULL, },
+ { 0x38e38e38638e38e3ULL, 0x8e38e38e38e38e38ULL, },
+ { 0xe6666665e6666665ULL, 0xe6666665e6666665ULL, }, /* 32 */
+ { 0x6666666666666666ULL, 0x6666666666666666ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x9111111091111110ULL, 0x9111111091111110ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x7fffffff7fffffffULL, 0x7fffffff7fffffffULL, },
+ { 0xd82d82d7ad82d82dULL, 0x82d82d82d82d82d7ULL, },
+ { 0x749f49f49f49f49eULL, 0xc9f49f49749f49f4ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, }, /* 40 */
+ { 0x1999999919999999ULL, 0x1999999919999999ULL, },
+ { 0x6eeeeeee6eeeeeeeULL, 0x6eeeeeee6eeeeeeeULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x7fffffff7fffffffULL, 0x7fffffff7fffffffULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8b60b60b60b60b60ULL, 0x360b60b58b60b60bULL, },
+ { 0x27d27d27527d27d2ULL, 0x7d27d27d27d27d27ULL, },
+ { 0xf1c71c71c71c71c6ULL, 0x9c71c71bf1c71c71ULL, }, /* 48 */
+ { 0x71c71c71471c71c7ULL, 0x1c71c71c71c71c71ULL, },
+ { 0xc71c71c69c71c71cULL, 0x71c71c71c71c71c6ULL, },
+ { 0x9c71c71c71c71c71ULL, 0x471c71c69c71c71cULL, },
+ { 0xd82d82d7ad82d82dULL, 0x82d82d82d82d82d7ULL, },
+ { 0x8b60b60b60b60b60ULL, 0x360b60b58b60b60bULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x7fffffff7fffffffULL, 0x7fffffff7fffffffULL, },
+ { 0x8e38e38db8e38e38ULL, 0xe38e38e38e38e38dULL, }, /* 56 */
+ { 0x0e38e38e38e38e38ULL, 0x638e38e30e38e38eULL, },
+ { 0x638e38e38e38e38dULL, 0xb8e38e38638e38e3ULL, },
+ { 0x38e38e38638e38e3ULL, 0x8e38e38e38e38e38ULL, },
+ { 0x749f49f49f49f49eULL, 0xc9f49f49749f49f4ULL, },
+ { 0x27d27d27527d27d2ULL, 0x7d27d27d27d27d27ULL, },
+ { 0x7fffffff7fffffffULL, 0x7fffffff7fffffffULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0xc21473973afb0e24ULL, 0x2f2f633c89dd8184ULL, },
+ { 0x9a62cabb7118f060ULL, 0x399fe92ed4d36a90ULL, },
+ { 0x7c5cfe8c434a1bc7ULL, 0x6cac4a1bd3df4956ULL, },
+ { 0xc21473973afb0e24ULL, 0x2f2f633c89dd8184ULL, },
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xd40c578683b1a944ULL, 0x1d68410c60353c08ULL, },
+ { 0xb6068b5855e2d4abULL, 0x5074a1f95f411aceULL, },
+ { 0x9a62cabb7118f060ULL, 0x399fe92ed4d36a90ULL, }, /* 72 */
+ { 0xd40c578683b1a944ULL, 0x1d68410c60353c08ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x8e54e27b8c00b6e7ULL, 0x5ae527ebaa3703daULL, },
+ { 0x7c5cfe8c434a1bc7ULL, 0x6cac4a1bd3df4956ULL, },
+ { 0xb6068b5855e2d4abULL, 0x5074a1f95f411aceULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVE_U_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVE_U_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_s_b.c b/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_s_b.c
new file mode 100644
index 0000000000..59bba28d2e
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_s_b.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction AVER_S.B
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "AVER_S.B";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd5d5d5d5d5d5d5d5ULL, 0xd5d5d5d5d5d5d5d5ULL, },
+ { 0x2a2a2a2a2a2a2a2aULL, 0x2a2a2a2a2a2a2a2aULL, },
+ { 0xe6e6e6e6e6e6e6e6ULL, 0xe6e6e6e6e6e6e6e6ULL, },
+ { 0x1919191919191919ULL, 0x1919191919191919ULL, },
+ { 0xf1c71cf1c71cf1c7ULL, 0x1cf1c71cf1c71cf1ULL, },
+ { 0x0e38e30e38e30e38ULL, 0xe30e38e30e38e30eULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd5d5d5d5d5d5d5d5ULL, 0xd5d5d5d5d5d5d5d5ULL, },
+ { 0x2b2b2b2b2b2b2b2bULL, 0x2b2b2b2b2b2b2b2bULL, },
+ { 0xe6e6e6e6e6e6e6e6ULL, 0xe6e6e6e6e6e6e6e6ULL, },
+ { 0x1a1a1a1a1a1a1a1aULL, 0x1a1a1a1a1a1a1a1aULL, },
+ { 0xf2c71cf2c71cf2c7ULL, 0x1cf2c71cf2c71cf2ULL, },
+ { 0x0e39e40e39e40e39ULL, 0xe40e39e40e39e40eULL, },
+ { 0xd5d5d5d5d5d5d5d5ULL, 0xd5d5d5d5d5d5d5d5ULL, }, /* 16 */
+ { 0xd5d5d5d5d5d5d5d5ULL, 0xd5d5d5d5d5d5d5d5ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0xefefefefefefefefULL, 0xefefefefefefefefULL, },
+ { 0xc79cf1c79cf1c79cULL, 0xf1c79cf1c79cf1c7ULL, },
+ { 0xe30eb9e30eb9e30eULL, 0xb9e30eb9e30eb9e3ULL, },
+ { 0x2a2a2a2a2a2a2a2aULL, 0x2a2a2a2a2a2a2a2aULL, }, /* 24 */
+ { 0x2b2b2b2b2b2b2b2bULL, 0x2b2b2b2b2b2b2b2bULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x1111111111111111ULL, 0x1111111111111111ULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x1cf2471cf2471cf2ULL, 0x471cf2471cf2471cULL, },
+ { 0x39630e39630e3963ULL, 0x0e39630e39630e39ULL, },
+ { 0xe6e6e6e6e6e6e6e6ULL, 0xe6e6e6e6e6e6e6e6ULL, }, /* 32 */
+ { 0xe6e6e6e6e6e6e6e6ULL, 0xe6e6e6e6e6e6e6e6ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x1111111111111111ULL, 0x1111111111111111ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd8ad02d8ad02d8adULL, 0x02d8ad02d8ad02d8ULL, },
+ { 0xf41fcaf41fcaf41fULL, 0xcaf41fcaf41fcaf4ULL, },
+ { 0x1919191919191919ULL, 0x1919191919191919ULL, }, /* 40 */
+ { 0x1a1a1a1a1a1a1a1aULL, 0x1a1a1a1a1a1a1a1aULL, },
+ { 0xefefefefefefefefULL, 0xefefefefefefefefULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x0be1360be1360be1ULL, 0x360be1360be1360bULL, },
+ { 0x2852fd2852fd2852ULL, 0xfd2852fd2852fd28ULL, },
+ { 0xf1c71cf1c71cf1c7ULL, 0x1cf1c71cf1c71cf1ULL, }, /* 48 */
+ { 0xf2c71cf2c71cf2c7ULL, 0x1cf2c71cf2c71cf2ULL, },
+ { 0xc79cf1c79cf1c79cULL, 0xf1c79cf1c79cf1c7ULL, },
+ { 0x1cf2471cf2471cf2ULL, 0x471cf2471cf2471cULL, },
+ { 0xd8ad02d8ad02d8adULL, 0x02d8ad02d8ad02d8ULL, },
+ { 0x0be1360be1360be1ULL, 0x360be1360be1360bULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0e38e30e38e30e38ULL, 0xe30e38e30e38e30eULL, }, /* 56 */
+ { 0x0e39e40e39e40e39ULL, 0xe40e39e40e39e40eULL, },
+ { 0xe30eb9e30eb9e30eULL, 0xb9e30eb9e30eb9e3ULL, },
+ { 0x39630e39630e3963ULL, 0x0e39630e39630e39ULL, },
+ { 0xf41fcaf41fcaf41fULL, 0xcaf41fcaf41fcaf4ULL, },
+ { 0x2852fd2852fd2852ULL, 0xfd2852fd2852fd28ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0xc214f3183bfb0e24ULL, 0x2f2fe33c0a5d0104ULL, },
+ { 0x9a62cabbf119f0e0ULL, 0x3920e92fd553eb10ULL, },
+ { 0xfc5dfe0d434a1c47ULL, 0xec2cca1bd45fc9d6ULL, },
+ { 0xc214f3183bfb0e24ULL, 0x2f2fe33c0a5d0104ULL, },
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xd40cd70703b1a9c4ULL, 0x1de8c10de0353c08ULL, },
+ { 0x36070b5856e2d52bULL, 0xd0f4a2f9df411aceULL, },
+ { 0x9a62cabbf119f0e0ULL, 0x3920e92fd553eb10ULL, }, /* 72 */
+ { 0xd40cd70703b1a9c4ULL, 0x1de8c10de0353c08ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x0e55e2fc0c00b7e7ULL, 0xdae5a7ecaa3704daULL, },
+ { 0xfc5dfe0d434a1c47ULL, 0xec2cca1bd45fc9d6ULL, },
+ { 0x36070b5856e2d52bULL, 0xd0f4a2f9df411aceULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVER_S_B(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVER_S_B(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_s_d.c b/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_s_d.c
new file mode 100644
index 0000000000..435c09f9bf
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_s_d.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction AVER_S.D
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "AVER_S.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd555555555555555ULL, 0xd555555555555555ULL, },
+ { 0x2aaaaaaaaaaaaaaaULL, 0x2aaaaaaaaaaaaaaaULL, },
+ { 0xe666666666666666ULL, 0xe666666666666666ULL, },
+ { 0x1999999999999999ULL, 0x1999999999999999ULL, },
+ { 0xf1c71c71c71c71c7ULL, 0x1c71c71c71c71c71ULL, },
+ { 0x0e38e38e38e38e38ULL, 0xe38e38e38e38e38eULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd555555555555555ULL, 0xd555555555555555ULL, },
+ { 0x2aaaaaaaaaaaaaabULL, 0x2aaaaaaaaaaaaaabULL, },
+ { 0xe666666666666666ULL, 0xe666666666666666ULL, },
+ { 0x199999999999999aULL, 0x199999999999999aULL, },
+ { 0xf1c71c71c71c71c7ULL, 0x1c71c71c71c71c72ULL, },
+ { 0x0e38e38e38e38e39ULL, 0xe38e38e38e38e38eULL, },
+ { 0xd555555555555555ULL, 0xd555555555555555ULL, }, /* 16 */
+ { 0xd555555555555555ULL, 0xd555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0xeeeeeeeeeeeeeeefULL, 0xeeeeeeeeeeeeeeefULL, },
+ { 0xc71c71c71c71c71cULL, 0xf1c71c71c71c71c7ULL, },
+ { 0xe38e38e38e38e38eULL, 0xb8e38e38e38e38e3ULL, },
+ { 0x2aaaaaaaaaaaaaaaULL, 0x2aaaaaaaaaaaaaaaULL, }, /* 24 */
+ { 0x2aaaaaaaaaaaaaabULL, 0x2aaaaaaaaaaaaaabULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x1111111111111111ULL, 0x1111111111111111ULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x1c71c71c71c71c72ULL, 0x471c71c71c71c71cULL, },
+ { 0x38e38e38e38e38e3ULL, 0x0e38e38e38e38e39ULL, },
+ { 0xe666666666666666ULL, 0xe666666666666666ULL, }, /* 32 */
+ { 0xe666666666666666ULL, 0xe666666666666666ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x1111111111111111ULL, 0x1111111111111111ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd82d82d82d82d82dULL, 0x02d82d82d82d82d8ULL, },
+ { 0xf49f49f49f49f49fULL, 0xc9f49f49f49f49f4ULL, },
+ { 0x1999999999999999ULL, 0x1999999999999999ULL, }, /* 40 */
+ { 0x199999999999999aULL, 0x199999999999999aULL, },
+ { 0xeeeeeeeeeeeeeeefULL, 0xeeeeeeeeeeeeeeefULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x0b60b60b60b60b61ULL, 0x360b60b60b60b60bULL, },
+ { 0x27d27d27d27d27d2ULL, 0xfd27d27d27d27d28ULL, },
+ { 0xf1c71c71c71c71c7ULL, 0x1c71c71c71c71c71ULL, }, /* 48 */
+ { 0xf1c71c71c71c71c7ULL, 0x1c71c71c71c71c72ULL, },
+ { 0xc71c71c71c71c71cULL, 0xf1c71c71c71c71c7ULL, },
+ { 0x1c71c71c71c71c72ULL, 0x471c71c71c71c71cULL, },
+ { 0xd82d82d82d82d82dULL, 0x02d82d82d82d82d8ULL, },
+ { 0x0b60b60b60b60b61ULL, 0x360b60b60b60b60bULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0e38e38e38e38e38ULL, 0xe38e38e38e38e38eULL, }, /* 56 */
+ { 0x0e38e38e38e38e39ULL, 0xe38e38e38e38e38eULL, },
+ { 0xe38e38e38e38e38eULL, 0xb8e38e38e38e38e3ULL, },
+ { 0x38e38e38e38e38e3ULL, 0x0e38e38e38e38e39ULL, },
+ { 0xf49f49f49f49f49fULL, 0xc9f49f49f49f49f4ULL, },
+ { 0x27d27d27d27d27d2ULL, 0xfd27d27d27d27d28ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0xc2147397bafb0e24ULL, 0x2f2f633c89dd8184ULL, },
+ { 0x9a62cabb7118f060ULL, 0x399fe92f54d36a90ULL, },
+ { 0xfc5cfe8cc34a1bc7ULL, 0xecac4a1bd3df4956ULL, },
+ { 0xc2147397bafb0e24ULL, 0x2f2f633c89dd8184ULL, },
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xd40c578703b1a944ULL, 0x1d68410ce0353c08ULL, },
+ { 0x36068b5855e2d4abULL, 0xd074a1f95f411aceULL, },
+ { 0x9a62cabb7118f060ULL, 0x399fe92f54d36a90ULL, }, /* 72 */
+ { 0xd40c578703b1a944ULL, 0x1d68410ce0353c08ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x0e54e27c0c00b6e7ULL, 0xdae527ec2a3703daULL, },
+ { 0xfc5cfe8cc34a1bc7ULL, 0xecac4a1bd3df4956ULL, },
+ { 0x36068b5855e2d4abULL, 0xd074a1f95f411aceULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVER_S_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVER_S_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_s_h.c b/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_s_h.c
new file mode 100644
index 0000000000..0902e508ec
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_s_h.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction AVER_S.H
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "AVER_S.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd555d555d555d555ULL, 0xd555d555d555d555ULL, },
+ { 0x2aaa2aaa2aaa2aaaULL, 0x2aaa2aaa2aaa2aaaULL, },
+ { 0xe666e666e666e666ULL, 0xe666e666e666e666ULL, },
+ { 0x1999199919991999ULL, 0x1999199919991999ULL, },
+ { 0xf1c71c71c71cf1c7ULL, 0x1c71c71cf1c71c71ULL, },
+ { 0x0e38e38e38e30e38ULL, 0xe38e38e30e38e38eULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd555d555d555d555ULL, 0xd555d555d555d555ULL, },
+ { 0x2aab2aab2aab2aabULL, 0x2aab2aab2aab2aabULL, },
+ { 0xe666e666e666e666ULL, 0xe666e666e666e666ULL, },
+ { 0x199a199a199a199aULL, 0x199a199a199a199aULL, },
+ { 0xf1c71c72c71cf1c7ULL, 0x1c72c71cf1c71c72ULL, },
+ { 0x0e39e38e38e40e39ULL, 0xe38e38e40e39e38eULL, },
+ { 0xd555d555d555d555ULL, 0xd555d555d555d555ULL, }, /* 16 */
+ { 0xd555d555d555d555ULL, 0xd555d555d555d555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0xeeefeeefeeefeeefULL, 0xeeefeeefeeefeeefULL, },
+ { 0xc71cf1c79c71c71cULL, 0xf1c79c71c71cf1c7ULL, },
+ { 0xe38eb8e30e39e38eULL, 0xb8e30e39e38eb8e3ULL, },
+ { 0x2aaa2aaa2aaa2aaaULL, 0x2aaa2aaa2aaa2aaaULL, }, /* 24 */
+ { 0x2aab2aab2aab2aabULL, 0x2aab2aab2aab2aabULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x1111111111111111ULL, 0x1111111111111111ULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x1c72471cf1c71c72ULL, 0x471cf1c71c72471cULL, },
+ { 0x38e30e39638e38e3ULL, 0x0e39638e38e30e39ULL, },
+ { 0xe666e666e666e666ULL, 0xe666e666e666e666ULL, }, /* 32 */
+ { 0xe666e666e666e666ULL, 0xe666e666e666e666ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x1111111111111111ULL, 0x1111111111111111ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd82d02d8ad82d82dULL, 0x02d8ad82d82d02d8ULL, },
+ { 0xf49fc9f41f4af49fULL, 0xc9f41f4af49fc9f4ULL, },
+ { 0x1999199919991999ULL, 0x1999199919991999ULL, }, /* 40 */
+ { 0x199a199a199a199aULL, 0x199a199a199a199aULL, },
+ { 0xeeefeeefeeefeeefULL, 0xeeefeeefeeefeeefULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x0b61360be0b60b61ULL, 0x360be0b60b61360bULL, },
+ { 0x27d2fd28527d27d2ULL, 0xfd28527d27d2fd28ULL, },
+ { 0xf1c71c71c71cf1c7ULL, 0x1c71c71cf1c71c71ULL, }, /* 48 */
+ { 0xf1c71c72c71cf1c7ULL, 0x1c72c71cf1c71c72ULL, },
+ { 0xc71cf1c79c71c71cULL, 0xf1c79c71c71cf1c7ULL, },
+ { 0x1c72471cf1c71c72ULL, 0x471cf1c71c72471cULL, },
+ { 0xd82d02d8ad82d82dULL, 0x02d8ad82d82d02d8ULL, },
+ { 0x0b61360be0b60b61ULL, 0x360be0b60b61360bULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0e38e38e38e30e38ULL, 0xe38e38e30e38e38eULL, }, /* 56 */
+ { 0x0e39e38e38e40e39ULL, 0xe38e38e40e39e38eULL, },
+ { 0xe38eb8e30e39e38eULL, 0xb8e30e39e38eb8e3ULL, },
+ { 0x38e30e39638e38e3ULL, 0x0e39638e38e30e39ULL, },
+ { 0xf49fc9f41f4af49fULL, 0xc9f41f4af49fc9f4ULL, },
+ { 0x27d2fd28527d27d2ULL, 0xfd28527d27d2fd28ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0xc214f3983afb0e24ULL, 0x2f2fe33c09dd0184ULL, },
+ { 0x9a62cabbf119f060ULL, 0x39a0e92fd4d3ea90ULL, },
+ { 0xfc5dfe8d434a1bc7ULL, 0xecacca1bd3dfc956ULL, },
+ { 0xc214f3983afb0e24ULL, 0x2f2fe33c09dd0184ULL, },
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xd40cd78703b1a944ULL, 0x1d68c10de0353c08ULL, },
+ { 0x36070b5855e2d4abULL, 0xd074a1f9df411aceULL, },
+ { 0x9a62cabbf119f060ULL, 0x39a0e92fd4d3ea90ULL, }, /* 72 */
+ { 0xd40cd78703b1a944ULL, 0x1d68c10de0353c08ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x0e55e27c0c00b6e7ULL, 0xdae5a7ecaa3703daULL, },
+ { 0xfc5dfe8d434a1bc7ULL, 0xecacca1bd3dfc956ULL, },
+ { 0x36070b5855e2d4abULL, 0xd074a1f9df411aceULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVER_S_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVER_S_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_s_w.c b/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_s_w.c
new file mode 100644
index 0000000000..31f4553916
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_s_w.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction AVER_S.W
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "AVER_S.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd5555555d5555555ULL, 0xd5555555d5555555ULL, },
+ { 0x2aaaaaaa2aaaaaaaULL, 0x2aaaaaaa2aaaaaaaULL, },
+ { 0xe6666666e6666666ULL, 0xe6666666e6666666ULL, },
+ { 0x1999999919999999ULL, 0x1999999919999999ULL, },
+ { 0xf1c71c71c71c71c7ULL, 0x1c71c71cf1c71c71ULL, },
+ { 0x0e38e38e38e38e38ULL, 0xe38e38e30e38e38eULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd5555555d5555555ULL, 0xd5555555d5555555ULL, },
+ { 0x2aaaaaab2aaaaaabULL, 0x2aaaaaab2aaaaaabULL, },
+ { 0xe6666666e6666666ULL, 0xe6666666e6666666ULL, },
+ { 0x1999999a1999999aULL, 0x1999999a1999999aULL, },
+ { 0xf1c71c72c71c71c7ULL, 0x1c71c71cf1c71c72ULL, },
+ { 0x0e38e38e38e38e39ULL, 0xe38e38e40e38e38eULL, },
+ { 0xd5555555d5555555ULL, 0xd5555555d5555555ULL, }, /* 16 */
+ { 0xd5555555d5555555ULL, 0xd5555555d5555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0xeeeeeeefeeeeeeefULL, 0xeeeeeeefeeeeeeefULL, },
+ { 0xc71c71c79c71c71cULL, 0xf1c71c71c71c71c7ULL, },
+ { 0xe38e38e30e38e38eULL, 0xb8e38e39e38e38e3ULL, },
+ { 0x2aaaaaaa2aaaaaaaULL, 0x2aaaaaaa2aaaaaaaULL, }, /* 24 */
+ { 0x2aaaaaab2aaaaaabULL, 0x2aaaaaab2aaaaaabULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x1111111111111111ULL, 0x1111111111111111ULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x1c71c71cf1c71c72ULL, 0x471c71c71c71c71cULL, },
+ { 0x38e38e39638e38e3ULL, 0x0e38e38e38e38e39ULL, },
+ { 0xe6666666e6666666ULL, 0xe6666666e6666666ULL, }, /* 32 */
+ { 0xe6666666e6666666ULL, 0xe6666666e6666666ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x1111111111111111ULL, 0x1111111111111111ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd82d82d8ad82d82dULL, 0x02d82d82d82d82d8ULL, },
+ { 0xf49f49f41f49f49fULL, 0xc9f49f4af49f49f4ULL, },
+ { 0x1999999919999999ULL, 0x1999999919999999ULL, }, /* 40 */
+ { 0x1999999a1999999aULL, 0x1999999a1999999aULL, },
+ { 0xeeeeeeefeeeeeeefULL, 0xeeeeeeefeeeeeeefULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x0b60b60be0b60b61ULL, 0x360b60b60b60b60bULL, },
+ { 0x27d27d28527d27d2ULL, 0xfd27d27d27d27d28ULL, },
+ { 0xf1c71c71c71c71c7ULL, 0x1c71c71cf1c71c71ULL, }, /* 48 */
+ { 0xf1c71c72c71c71c7ULL, 0x1c71c71cf1c71c72ULL, },
+ { 0xc71c71c79c71c71cULL, 0xf1c71c71c71c71c7ULL, },
+ { 0x1c71c71cf1c71c72ULL, 0x471c71c71c71c71cULL, },
+ { 0xd82d82d8ad82d82dULL, 0x02d82d82d82d82d8ULL, },
+ { 0x0b60b60be0b60b61ULL, 0x360b60b60b60b60bULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0e38e38e38e38e38ULL, 0xe38e38e30e38e38eULL, }, /* 56 */
+ { 0x0e38e38e38e38e39ULL, 0xe38e38e40e38e38eULL, },
+ { 0xe38e38e30e38e38eULL, 0xb8e38e39e38e38e3ULL, },
+ { 0x38e38e39638e38e3ULL, 0x0e38e38e38e38e39ULL, },
+ { 0xf49f49f41f49f49fULL, 0xc9f49f4af49f49f4ULL, },
+ { 0x27d27d28527d27d2ULL, 0xfd27d27d27d27d28ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0xc21473983afb0e24ULL, 0x2f2f633c09dd8184ULL, },
+ { 0x9a62cabbf118f060ULL, 0x399fe92fd4d36a90ULL, },
+ { 0xfc5cfe8d434a1bc7ULL, 0xecac4a1bd3df4956ULL, },
+ { 0xc21473983afb0e24ULL, 0x2f2f633c09dd8184ULL, },
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xd40c578703b1a944ULL, 0x1d68410de0353c08ULL, },
+ { 0x36068b5855e2d4abULL, 0xd074a1f9df411aceULL, },
+ { 0x9a62cabbf118f060ULL, 0x399fe92fd4d36a90ULL, }, /* 72 */
+ { 0xd40c578703b1a944ULL, 0x1d68410de0353c08ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x0e54e27c0c00b6e7ULL, 0xdae527ecaa3703daULL, },
+ { 0xfc5cfe8d434a1bc7ULL, 0xecac4a1bd3df4956ULL, },
+ { 0x36068b5855e2d4abULL, 0xd074a1f9df411aceULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVER_S_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVER_S_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_u_b.c b/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_u_b.c
new file mode 100644
index 0000000000..8aa7ec6a41
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_u_b.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction AVER_U.B
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "AVER_U.B";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, },
+ { 0xd5d5d5d5d5d5d5d5ULL, 0xd5d5d5d5d5d5d5d5ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xe6e6e6e6e6e6e6e6ULL, 0xe6e6e6e6e6e6e6e6ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xf1c79cf1c79cf1c7ULL, 0x9cf1c79cf1c79cf1ULL, },
+ { 0x8eb8e38eb8e38eb8ULL, 0xe38eb8e38eb8e38eULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x2b2b2b2b2b2b2b2bULL, 0x2b2b2b2b2b2b2b2bULL, },
+ { 0x6666666666666666ULL, 0x6666666666666666ULL, },
+ { 0x1a1a1a1a1a1a1a1aULL, 0x1a1a1a1a1a1a1a1aULL, },
+ { 0x72471c72471c7247ULL, 0x1c72471c72471c72ULL, },
+ { 0x0e39640e39640e39ULL, 0x640e39640e39640eULL, },
+ { 0xd5d5d5d5d5d5d5d5ULL, 0xd5d5d5d5d5d5d5d5ULL, }, /* 16 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x6f6f6f6f6f6f6f6fULL, 0x6f6f6f6f6f6f6f6fULL, },
+ { 0xc79c71c79c71c79cULL, 0x71c79c71c79c71c7ULL, },
+ { 0x638eb9638eb9638eULL, 0xb9638eb9638eb963ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 24 */
+ { 0x2b2b2b2b2b2b2b2bULL, 0x2b2b2b2b2b2b2b2bULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x9191919191919191ULL, 0x9191919191919191ULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x9c72479c72479c72ULL, 0x479c72479c72479cULL, },
+ { 0x39638e39638e3963ULL, 0x8e39638e39638e39ULL, },
+ { 0xe6e6e6e6e6e6e6e6ULL, 0xe6e6e6e6e6e6e6e6ULL, }, /* 32 */
+ { 0x6666666666666666ULL, 0x6666666666666666ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x9191919191919191ULL, 0x9191919191919191ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, },
+ { 0xd8ad82d8ad82d8adULL, 0x82d8ad82d8ad82d8ULL, },
+ { 0x749fca749fca749fULL, 0xca749fca749fca74ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, }, /* 40 */
+ { 0x1a1a1a1a1a1a1a1aULL, 0x1a1a1a1a1a1a1a1aULL, },
+ { 0x6f6f6f6f6f6f6f6fULL, 0x6f6f6f6f6f6f6f6fULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8b61368b61368b61ULL, 0x368b61368b61368bULL, },
+ { 0x28527d28527d2852ULL, 0x7d28527d28527d28ULL, },
+ { 0xf1c79cf1c79cf1c7ULL, 0x9cf1c79cf1c79cf1ULL, }, /* 48 */
+ { 0x72471c72471c7247ULL, 0x1c72471c72471c72ULL, },
+ { 0xc79c71c79c71c79cULL, 0x71c79c71c79c71c7ULL, },
+ { 0x9c72479c72479c72ULL, 0x479c72479c72479cULL, },
+ { 0xd8ad82d8ad82d8adULL, 0x82d8ad82d8ad82d8ULL, },
+ { 0x8b61368b61368b61ULL, 0x368b61368b61368bULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, },
+ { 0x8eb8e38eb8e38eb8ULL, 0xe38eb8e38eb8e38eULL, }, /* 56 */
+ { 0x0e39640e39640e39ULL, 0x640e39640e39640eULL, },
+ { 0x638eb9638eb9638eULL, 0xb9638eb9638eb963ULL, },
+ { 0x39638e39638e3963ULL, 0x8e39638e39638e39ULL, },
+ { 0x749fca749fca749fULL, 0xca749fca749fca74ULL, },
+ { 0x28527d28527d2852ULL, 0x7d28527d28527d28ULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0xc29473983b7b8e24ULL, 0x2faf633c8a5d8184ULL, },
+ { 0x9a62cabb71997060ULL, 0x39a069afd5536b10ULL, },
+ { 0x7c5d7e8d434a9c47ULL, 0x6cac4a9bd45fc956ULL, },
+ { 0xc29473983b7b8e24ULL, 0x2faf633c8a5d8184ULL, },
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xd48c578783b1a944ULL, 0x1de8c18d60353c88ULL, },
+ { 0xb6870b585662d52bULL, 0x50f4a2795f419aceULL, },
+ { 0x9a62cabb71997060ULL, 0x39a069afd5536b10ULL, }, /* 72 */
+ { 0xd48c578783b1a944ULL, 0x1de8c18d60353c88ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x8e55627c8c80b767ULL, 0x5ae5a7ecaa37845aULL, },
+ { 0x7c5d7e8d434a9c47ULL, 0x6cac4a9bd45fc956ULL, },
+ { 0xb6870b585662d52bULL, 0x50f4a2795f419aceULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVER_U_B(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVER_U_B(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_u_d.c b/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_u_d.c
new file mode 100644
index 0000000000..9b16e1250f
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_u_d.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction AVER_U.D
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "AVER_U.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0x8000000000000000ULL, 0x8000000000000000ULL, },
+ { 0xd555555555555555ULL, 0xd555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xe666666666666666ULL, 0xe666666666666666ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xf1c71c71c71c71c7ULL, 0x9c71c71c71c71c71ULL, },
+ { 0x8e38e38e38e38e38ULL, 0xe38e38e38e38e38eULL, },
+ { 0x8000000000000000ULL, 0x8000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x2aaaaaaaaaaaaaabULL, 0x2aaaaaaaaaaaaaabULL, },
+ { 0x6666666666666666ULL, 0x6666666666666666ULL, },
+ { 0x199999999999999aULL, 0x199999999999999aULL, },
+ { 0x71c71c71c71c71c7ULL, 0x1c71c71c71c71c72ULL, },
+ { 0x0e38e38e38e38e39ULL, 0x638e38e38e38e38eULL, },
+ { 0xd555555555555555ULL, 0xd555555555555555ULL, }, /* 16 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x8000000000000000ULL, 0x8000000000000000ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x6eeeeeeeeeeeeeefULL, 0x6eeeeeeeeeeeeeefULL, },
+ { 0xc71c71c71c71c71cULL, 0x71c71c71c71c71c7ULL, },
+ { 0x638e38e38e38e38eULL, 0xb8e38e38e38e38e3ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 24 */
+ { 0x2aaaaaaaaaaaaaabULL, 0x2aaaaaaaaaaaaaabULL, },
+ { 0x8000000000000000ULL, 0x8000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x9111111111111111ULL, 0x9111111111111111ULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x9c71c71c71c71c72ULL, 0x471c71c71c71c71cULL, },
+ { 0x38e38e38e38e38e3ULL, 0x8e38e38e38e38e39ULL, },
+ { 0xe666666666666666ULL, 0xe666666666666666ULL, }, /* 32 */
+ { 0x6666666666666666ULL, 0x6666666666666666ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x9111111111111111ULL, 0x9111111111111111ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x8000000000000000ULL, 0x8000000000000000ULL, },
+ { 0xd82d82d82d82d82dULL, 0x82d82d82d82d82d8ULL, },
+ { 0x749f49f49f49f49fULL, 0xc9f49f49f49f49f4ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, }, /* 40 */
+ { 0x199999999999999aULL, 0x199999999999999aULL, },
+ { 0x6eeeeeeeeeeeeeefULL, 0x6eeeeeeeeeeeeeefULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x8000000000000000ULL, 0x8000000000000000ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8b60b60b60b60b61ULL, 0x360b60b60b60b60bULL, },
+ { 0x27d27d27d27d27d2ULL, 0x7d27d27d27d27d28ULL, },
+ { 0xf1c71c71c71c71c7ULL, 0x9c71c71c71c71c71ULL, }, /* 48 */
+ { 0x71c71c71c71c71c7ULL, 0x1c71c71c71c71c72ULL, },
+ { 0xc71c71c71c71c71cULL, 0x71c71c71c71c71c7ULL, },
+ { 0x9c71c71c71c71c72ULL, 0x471c71c71c71c71cULL, },
+ { 0xd82d82d82d82d82dULL, 0x82d82d82d82d82d8ULL, },
+ { 0x8b60b60b60b60b61ULL, 0x360b60b60b60b60bULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x8000000000000000ULL, 0x8000000000000000ULL, },
+ { 0x8e38e38e38e38e38ULL, 0xe38e38e38e38e38eULL, }, /* 56 */
+ { 0x0e38e38e38e38e39ULL, 0x638e38e38e38e38eULL, },
+ { 0x638e38e38e38e38eULL, 0xb8e38e38e38e38e3ULL, },
+ { 0x38e38e38e38e38e3ULL, 0x8e38e38e38e38e39ULL, },
+ { 0x749f49f49f49f49fULL, 0xc9f49f49f49f49f4ULL, },
+ { 0x27d27d27d27d27d2ULL, 0x7d27d27d27d27d28ULL, },
+ { 0x8000000000000000ULL, 0x8000000000000000ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0xc2147397bafb0e24ULL, 0x2f2f633c89dd8184ULL, },
+ { 0x9a62cabb7118f060ULL, 0x399fe92f54d36a90ULL, },
+ { 0x7c5cfe8cc34a1bc7ULL, 0x6cac4a1bd3df4956ULL, },
+ { 0xc2147397bafb0e24ULL, 0x2f2f633c89dd8184ULL, },
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xd40c578703b1a944ULL, 0x1d68410ce0353c08ULL, },
+ { 0xb6068b5855e2d4abULL, 0x5074a1f95f411aceULL, },
+ { 0x9a62cabb7118f060ULL, 0x399fe92f54d36a90ULL, }, /* 72 */
+ { 0xd40c578703b1a944ULL, 0x1d68410ce0353c08ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x8e54e27c0c00b6e7ULL, 0x5ae527ec2a3703daULL, },
+ { 0x7c5cfe8cc34a1bc7ULL, 0x6cac4a1bd3df4956ULL, },
+ { 0xb6068b5855e2d4abULL, 0x5074a1f95f411aceULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVER_U_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVER_U_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_u_h.c b/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_u_h.c
new file mode 100644
index 0000000000..191e4acbdc
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_u_h.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction AVER_U.H
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "AVER_U.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0x8000800080008000ULL, 0x8000800080008000ULL, },
+ { 0xd555d555d555d555ULL, 0xd555d555d555d555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xe666e666e666e666ULL, 0xe666e666e666e666ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xf1c79c71c71cf1c7ULL, 0x9c71c71cf1c79c71ULL, },
+ { 0x8e38e38eb8e38e38ULL, 0xe38eb8e38e38e38eULL, },
+ { 0x8000800080008000ULL, 0x8000800080008000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x2aab2aab2aab2aabULL, 0x2aab2aab2aab2aabULL, },
+ { 0x6666666666666666ULL, 0x6666666666666666ULL, },
+ { 0x199a199a199a199aULL, 0x199a199a199a199aULL, },
+ { 0x71c71c72471c71c7ULL, 0x1c72471c71c71c72ULL, },
+ { 0x0e39638e38e40e39ULL, 0x638e38e40e39638eULL, },
+ { 0xd555d555d555d555ULL, 0xd555d555d555d555ULL, }, /* 16 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x8000800080008000ULL, 0x8000800080008000ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x6eef6eef6eef6eefULL, 0x6eef6eef6eef6eefULL, },
+ { 0xc71c71c79c71c71cULL, 0x71c79c71c71c71c7ULL, },
+ { 0x638eb8e38e39638eULL, 0xb8e38e39638eb8e3ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 24 */
+ { 0x2aab2aab2aab2aabULL, 0x2aab2aab2aab2aabULL, },
+ { 0x8000800080008000ULL, 0x8000800080008000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x9111911191119111ULL, 0x9111911191119111ULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x9c72471c71c79c72ULL, 0x471c71c79c72471cULL, },
+ { 0x38e38e39638e38e3ULL, 0x8e39638e38e38e39ULL, },
+ { 0xe666e666e666e666ULL, 0xe666e666e666e666ULL, }, /* 32 */
+ { 0x6666666666666666ULL, 0x6666666666666666ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x9111911191119111ULL, 0x9111911191119111ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x8000800080008000ULL, 0x8000800080008000ULL, },
+ { 0xd82d82d8ad82d82dULL, 0x82d8ad82d82d82d8ULL, },
+ { 0x749fc9f49f4a749fULL, 0xc9f49f4a749fc9f4ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, }, /* 40 */
+ { 0x199a199a199a199aULL, 0x199a199a199a199aULL, },
+ { 0x6eef6eef6eef6eefULL, 0x6eef6eef6eef6eefULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x8000800080008000ULL, 0x8000800080008000ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8b61360b60b68b61ULL, 0x360b60b68b61360bULL, },
+ { 0x27d27d28527d27d2ULL, 0x7d28527d27d27d28ULL, },
+ { 0xf1c79c71c71cf1c7ULL, 0x9c71c71cf1c79c71ULL, }, /* 48 */
+ { 0x71c71c72471c71c7ULL, 0x1c72471c71c71c72ULL, },
+ { 0xc71c71c79c71c71cULL, 0x71c79c71c71c71c7ULL, },
+ { 0x9c72471c71c79c72ULL, 0x471c71c79c72471cULL, },
+ { 0xd82d82d8ad82d82dULL, 0x82d8ad82d82d82d8ULL, },
+ { 0x8b61360b60b68b61ULL, 0x360b60b68b61360bULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x8000800080008000ULL, 0x8000800080008000ULL, },
+ { 0x8e38e38eb8e38e38ULL, 0xe38eb8e38e38e38eULL, }, /* 56 */
+ { 0x0e39638e38e40e39ULL, 0x638e38e40e39638eULL, },
+ { 0x638eb8e38e39638eULL, 0xb8e38e39638eb8e3ULL, },
+ { 0x38e38e39638e38e3ULL, 0x8e39638e38e38e39ULL, },
+ { 0x749fc9f49f4a749fULL, 0xc9f49f4a749fc9f4ULL, },
+ { 0x27d27d28527d27d2ULL, 0x7d28527d27d27d28ULL, },
+ { 0x8000800080008000ULL, 0x8000800080008000ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0xc21473983afb8e24ULL, 0x2f2f633c89dd8184ULL, },
+ { 0x9a62cabb71197060ULL, 0x39a0692fd4d36a90ULL, },
+ { 0x7c5d7e8d434a9bc7ULL, 0x6cac4a1bd3dfc956ULL, },
+ { 0xc21473983afb8e24ULL, 0x2f2f633c89dd8184ULL, },
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xd40c578783b1a944ULL, 0x1d68c10d60353c08ULL, },
+ { 0xb6070b5855e2d4abULL, 0x5074a1f95f419aceULL, },
+ { 0x9a62cabb71197060ULL, 0x39a0692fd4d36a90ULL, }, /* 72 */
+ { 0xd40c578783b1a944ULL, 0x1d68c10d60353c08ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x8e55627c8c00b6e7ULL, 0x5ae5a7ecaa3783daULL, },
+ { 0x7c5d7e8d434a9bc7ULL, 0x6cac4a1bd3dfc956ULL, },
+ { 0xb6070b5855e2d4abULL, 0x5074a1f95f419aceULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVER_U_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVER_U_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_u_w.c b/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_u_w.c
new file mode 100644
index 0000000000..e0d6b177c4
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-average/test_msa_aver_u_w.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction AVER_U.W
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "AVER_U.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0x8000000080000000ULL, 0x8000000080000000ULL, },
+ { 0xd5555555d5555555ULL, 0xd5555555d5555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xe6666666e6666666ULL, 0xe6666666e6666666ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xf1c71c71c71c71c7ULL, 0x9c71c71cf1c71c71ULL, },
+ { 0x8e38e38eb8e38e38ULL, 0xe38e38e38e38e38eULL, },
+ { 0x8000000080000000ULL, 0x8000000080000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x2aaaaaab2aaaaaabULL, 0x2aaaaaab2aaaaaabULL, },
+ { 0x6666666666666666ULL, 0x6666666666666666ULL, },
+ { 0x1999999a1999999aULL, 0x1999999a1999999aULL, },
+ { 0x71c71c72471c71c7ULL, 0x1c71c71c71c71c72ULL, },
+ { 0x0e38e38e38e38e39ULL, 0x638e38e40e38e38eULL, },
+ { 0xd5555555d5555555ULL, 0xd5555555d5555555ULL, }, /* 16 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x8000000080000000ULL, 0x8000000080000000ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x6eeeeeef6eeeeeefULL, 0x6eeeeeef6eeeeeefULL, },
+ { 0xc71c71c79c71c71cULL, 0x71c71c71c71c71c7ULL, },
+ { 0x638e38e38e38e38eULL, 0xb8e38e39638e38e3ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 24 */
+ { 0x2aaaaaab2aaaaaabULL, 0x2aaaaaab2aaaaaabULL, },
+ { 0x8000000080000000ULL, 0x8000000080000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x9111111191111111ULL, 0x9111111191111111ULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x9c71c71c71c71c72ULL, 0x471c71c79c71c71cULL, },
+ { 0x38e38e39638e38e3ULL, 0x8e38e38e38e38e39ULL, },
+ { 0xe6666666e6666666ULL, 0xe6666666e6666666ULL, }, /* 32 */
+ { 0x6666666666666666ULL, 0x6666666666666666ULL, },
+ { 0xbbbbbbbbbbbbbbbbULL, 0xbbbbbbbbbbbbbbbbULL, },
+ { 0x9111111191111111ULL, 0x9111111191111111ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x8000000080000000ULL, 0x8000000080000000ULL, },
+ { 0xd82d82d8ad82d82dULL, 0x82d82d82d82d82d8ULL, },
+ { 0x749f49f49f49f49fULL, 0xc9f49f4a749f49f4ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, }, /* 40 */
+ { 0x1999999a1999999aULL, 0x1999999a1999999aULL, },
+ { 0x6eeeeeef6eeeeeefULL, 0x6eeeeeef6eeeeeefULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x8000000080000000ULL, 0x8000000080000000ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8b60b60b60b60b61ULL, 0x360b60b68b60b60bULL, },
+ { 0x27d27d28527d27d2ULL, 0x7d27d27d27d27d28ULL, },
+ { 0xf1c71c71c71c71c7ULL, 0x9c71c71cf1c71c71ULL, }, /* 48 */
+ { 0x71c71c72471c71c7ULL, 0x1c71c71c71c71c72ULL, },
+ { 0xc71c71c79c71c71cULL, 0x71c71c71c71c71c7ULL, },
+ { 0x9c71c71c71c71c72ULL, 0x471c71c79c71c71cULL, },
+ { 0xd82d82d8ad82d82dULL, 0x82d82d82d82d82d8ULL, },
+ { 0x8b60b60b60b60b61ULL, 0x360b60b68b60b60bULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x8000000080000000ULL, 0x8000000080000000ULL, },
+ { 0x8e38e38eb8e38e38ULL, 0xe38e38e38e38e38eULL, }, /* 56 */
+ { 0x0e38e38e38e38e39ULL, 0x638e38e40e38e38eULL, },
+ { 0x638e38e38e38e38eULL, 0xb8e38e39638e38e3ULL, },
+ { 0x38e38e39638e38e3ULL, 0x8e38e38e38e38e39ULL, },
+ { 0x749f49f49f49f49fULL, 0xc9f49f4a749f49f4ULL, },
+ { 0x27d27d28527d27d2ULL, 0x7d27d27d27d27d28ULL, },
+ { 0x8000000080000000ULL, 0x8000000080000000ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0xc21473983afb0e24ULL, 0x2f2f633c89dd8184ULL, },
+ { 0x9a62cabb7118f060ULL, 0x399fe92fd4d36a90ULL, },
+ { 0x7c5cfe8d434a1bc7ULL, 0x6cac4a1bd3df4956ULL, },
+ { 0xc21473983afb0e24ULL, 0x2f2f633c89dd8184ULL, },
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xd40c578783b1a944ULL, 0x1d68410d60353c08ULL, },
+ { 0xb6068b5855e2d4abULL, 0x5074a1f95f411aceULL, },
+ { 0x9a62cabb7118f060ULL, 0x399fe92fd4d36a90ULL, }, /* 72 */
+ { 0xd40c578783b1a944ULL, 0x1d68410d60353c08ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x8e54e27c8c00b6e7ULL, 0x5ae527ecaa3703daULL, },
+ { 0x7c5cfe8d434a1bc7ULL, 0x6cac4a1bd3df4956ULL, },
+ { 0xb6068b5855e2d4abULL, 0x5074a1f95f411aceULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVER_U_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_AVER_U_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_b.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_b.c
index b47b42e76e..bb884ee752 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_b.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CEQ.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_d.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_d.c
index e169bdc320..ef13f7d05d 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CEQ.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_h.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_h.c
index 9f03cb0b2b..1c43d40ee1 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CEQ.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_w.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_w.c
index a927d96a89..1297d41f29 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_ceq_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CEQ.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_b.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_b.c
index 1c1cb3bc4a..afd5f635f0 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_b.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CLE_S.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_d.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_d.c
index b51907cbc0..04d58d103c 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CLE_S.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_h.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_h.c
index 20ebbfbafb..ed1a1e21bd 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CLE_S.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_w.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_w.c
index 4a78cce460..ea4dc1a30b 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_s_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CLE_S.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_b.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_b.c
index 9990a5b08a..6e4fdd83ec 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_b.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CLE_U.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_d.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_d.c
index cde86d824a..b2b2f557b8 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CLE_U.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_h.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_h.c
index 70e4b48de5..b2267752eb 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CLE_U.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_w.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_w.c
index f38feacef2..00e930c0c7 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_cle_u_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CLE_U.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_b.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_b.c
index b81b569498..4a52ebe491 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_b.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CLT_S.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_d.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_d.c
index 393457a3c1..cc945cdf8d 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CLT_S.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_h.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_h.c
index 56860d7bcc..b228dfe7f5 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CLT_S.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_w.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_w.c
index 346b2939bb..6cb192a851 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_s_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CLT_S.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_b.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_b.c
index be79646b45..b6189d6b72 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_b.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CLT_U.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_d.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_d.c
index afbe4904f8..4f547d8f0b 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CLT_U.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_h.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_h.c
index 126597af9d..9fcd81c653 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CLT_U.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_w.c b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_w.c
index b4059292cd..8f648afa62 100644
--- a/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-compare/test_msa_clt_u_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction CLT_U.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_s_b.c b/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_s_b.c
new file mode 100644
index 0000000000..38e3670422
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_s_b.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction DIV_S.B
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "DIV_S.B";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, }, /* 0 */
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5656565656565656ULL, 0x5656565656565656ULL, }, /* 16 */
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0200ff0200ff0200ULL, 0xff0200ff0200ff02ULL, },
+ { 0xfd0001fd0001fd00ULL, 0x01fd0001fd0001fdULL, },
+ { 0xababababababababULL, 0xababababababababULL, }, /* 24 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0xfe0001fe0001fe00ULL, 0x01fe0001fe0001feULL, },
+ { 0x0300ff0300ff0300ULL, 0xff0300ff0300ff03ULL, },
+ { 0x3434343434343434ULL, 0x3434343434343434ULL, }, /* 32 */
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0100000100000100ULL, 0x0001000001000001ULL, },
+ { 0xff0000ff0000ff00ULL, 0x00ff0000ff0000ffULL, },
+ { 0xcdcdcdcdcdcdcdcdULL, 0xcdcdcdcdcdcdcdcdULL, }, /* 40 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0xff0000ff0000ff00ULL, 0x00ff0000ff0000ffULL, },
+ { 0x0100000100000100ULL, 0x0001000001000001ULL, },
+ { 0x1d72c81d72c81d72ULL, 0xc81d72c81d72c81dULL, }, /* 48 */
+ { 0x0101ff0101ff0101ULL, 0xff0101ff0101ff01ULL, },
+ { 0x0001000001000001ULL, 0x0000010000010000ULL, },
+ { 0x00ff0000ff0000ffULL, 0x0000ff0000ff0000ULL, },
+ { 0x0002ff0002ff0002ULL, 0xff0002ff0002ff00ULL, },
+ { 0x00fe0100fe0100feULL, 0x0100fe0100fe0100ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0xffff00ffff00ffffULL, 0x00ffff00ffff00ffULL, },
+ { 0xe48f39e48f39e48fULL, 0x39e48f39e48f39e4ULL, }, /* 56 */
+ { 0xffff01ffff01ffffULL, 0x01ffff01ffff01ffULL, },
+ { 0x00ff0000ff0000ffULL, 0x0000ff0000ff0000ULL, },
+ { 0x0001000001000001ULL, 0x0000010000010000ULL, },
+ { 0x00fe0100fe0100feULL, 0x0100fe0100fe0100ULL, },
+ { 0x0002ff0002ff0002ULL, 0xff0002ff0002ff00ULL, },
+ { 0x0000ff0000ff0000ULL, 0xff0000ff0000ff00ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, }, /* 64 */
+ { 0x18ff01000000ff08ULL, 0x04f50003000100fdULL, },
+ { 0x0101000000fe0000ULL, 0x01fe00a20002fe00ULL, },
+ { 0xff01ff000002fe00ULL, 0x00fa00fe00010200ULL, },
+ { 0x000000ff01ff0000ULL, 0x0000fa00f600ff00ULL, },
+ { 0x0101ff0101010101ULL, 0x0101010101010101ULL, },
+ { 0x000000ffff020000ULL, 0x000001e600010200ULL, },
+ { 0x0000000100fe0100ULL, 0x000000000000fe00ULL, },
+ { 0x00000301ff00fffeULL, 0x0000fb002a000001ULL, }, /* 72 */
+ { 0x10ff0100000002f0ULL, 0x02040000fc0000fbULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0x0001fdff00ff03ffULL, 0x000200000000ff00ULL, },
+ { 0x000000ff02000001ULL, 0xff00f6002b0000f8ULL, },
+ { 0xeaffff0001000009ULL, 0xfa0101fffc010018ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DIV_S_B(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DIV_S_B(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_s_d.c b/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_s_d.c
new file mode 100644
index 0000000000..d92b6953e8
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_s_d.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction DIV_S.D
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "DIV_S.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, }, /* 0 */
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555556ULL, 0x5555555555555556ULL, }, /* 16 */
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000003ULL, 0xffffffffffffffffULL, },
+ { 0xfffffffffffffffdULL, 0x0000000000000001ULL, },
+ { 0xaaaaaaaaaaaaaaabULL, 0xaaaaaaaaaaaaaaabULL, }, /* 24 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0xfffffffffffffffeULL, 0x0000000000000001ULL, },
+ { 0x0000000000000003ULL, 0xffffffffffffffffULL, },
+ { 0x3333333333333334ULL, 0x3333333333333334ULL, }, /* 32 */
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0xffffffffffffffffULL, 0x0000000000000000ULL, },
+ { 0xcccccccccccccccdULL, 0xcccccccccccccccdULL, }, /* 40 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0xffffffffffffffffULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0x1c71c71c71c71c72ULL, 0xc71c71c71c71c71dULL, }, /* 48 */
+ { 0x0000000000000001ULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0xffffffffffffffffULL, 0x0000000000000000ULL, },
+ { 0xe38e38e38e38e38fULL, 0x38e38e38e38e38e4ULL, }, /* 56 */
+ { 0xffffffffffffffffULL, 0x0000000000000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000000ULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, }, /* 64 */
+ { 0x000000000000001cULL, 0x0000000000000003ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0xffffffffffffffffULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 72 */
+ { 0x0000000000000013ULL, 0x0000000000000002ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffe6ULL, 0xfffffffffffffffaULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DIV_S_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DIV_S_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_s_h.c b/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_s_h.c
new file mode 100644
index 0000000000..f191b985b1
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_s_h.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction DIV_S.H
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "DIV_S.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, }, /* 0 */
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5556555655565556ULL, 0x5556555655565556ULL, }, /* 16 */
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0003ffff00000003ULL, 0xffff00000003ffffULL, },
+ { 0xfffd00010000fffdULL, 0x00010000fffd0001ULL, },
+ { 0xaaabaaabaaabaaabULL, 0xaaabaaabaaabaaabULL, }, /* 24 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0xfffe00010000fffeULL, 0x00010000fffe0001ULL, },
+ { 0x0003ffff00000003ULL, 0xffff00000003ffffULL, },
+ { 0x3334333433343334ULL, 0x3334333433343334ULL, }, /* 32 */
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0001000000000001ULL, 0x0000000000010000ULL, },
+ { 0xffff00000000ffffULL, 0x00000000ffff0000ULL, },
+ { 0xcccdcccdcccdcccdULL, 0xcccdcccdcccdcccdULL, }, /* 40 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0xffff00000000ffffULL, 0x00000000ffff0000ULL, },
+ { 0x0001000000000001ULL, 0x0000000000010000ULL, },
+ { 0x1c72c71d71c81c72ULL, 0xc71d71c81c72c71dULL, }, /* 48 */
+ { 0x0001ffff00010001ULL, 0xffff00010001ffffULL, },
+ { 0x0000000000010000ULL, 0x0000000100000000ULL, },
+ { 0x00000000ffff0000ULL, 0x0000ffff00000000ULL, },
+ { 0x0000ffff00020000ULL, 0xffff00020000ffffULL, },
+ { 0x00000001fffe0000ULL, 0x0001fffe00000001ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0xffff0000ffffffffULL, 0x0000ffffffff0000ULL, },
+ { 0xe38f38e48e39e38fULL, 0x38e48e39e38f38e4ULL, }, /* 56 */
+ { 0xffff0001ffffffffULL, 0x0001ffffffff0001ULL, },
+ { 0x00000000ffff0000ULL, 0x0000ffff00000000ULL, },
+ { 0x0000000000010000ULL, 0x0000000100000000ULL, },
+ { 0x00000001fffe0000ULL, 0x0001fffe00000001ULL, },
+ { 0x0000ffff00020000ULL, 0xffff00020000ffffULL, },
+ { 0x0000ffff00000000ULL, 0xffff00000000ffffULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, }, /* 64 */
+ { 0x001cffbf0000ffffULL, 0x0003000000000000ULL, },
+ { 0x0001000000000000ULL, 0x000100000000fffeULL, },
+ { 0xffffffff0000fffeULL, 0x0000000000000002ULL, },
+ { 0x0000000000010000ULL, 0x0000fffafff3ffffULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x00000000ffff0000ULL, 0x0000000100000002ULL, },
+ { 0x0000000000000001ULL, 0x000000000000fffeULL, },
+ { 0x00000003ffffffffULL, 0x0000fffb00370000ULL, }, /* 72 */
+ { 0x0013ff2e00000002ULL, 0x00020000fffd0000ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0000fffd00000003ULL, 0x000000000000ffffULL, },
+ { 0x0000000000020000ULL, 0xfffffff600390000ULL, },
+ { 0xffe6003900010000ULL, 0xfffa0001fffc0000ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DIV_S_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DIV_S_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_s_w.c b/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_s_w.c
new file mode 100644
index 0000000000..0baaff10f9
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_s_w.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction DIV_S.W
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "DIV_S.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, }, /* 0 */
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555655555556ULL, 0x5555555655555556ULL, }, /* 16 */
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000200000000ULL, 0xffffffff00000002ULL, },
+ { 0xfffffffd00000000ULL, 0x00000001fffffffdULL, },
+ { 0xaaaaaaabaaaaaaabULL, 0xaaaaaaabaaaaaaabULL, }, /* 24 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0xfffffffe00000000ULL, 0x00000001fffffffeULL, },
+ { 0x0000000300000000ULL, 0xffffffff00000003ULL, },
+ { 0x3333333433333334ULL, 0x3333333433333334ULL, }, /* 32 */
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000100000000ULL, 0x0000000000000001ULL, },
+ { 0xffffffff00000000ULL, 0x00000000ffffffffULL, },
+ { 0xcccccccdcccccccdULL, 0xcccccccdcccccccdULL, }, /* 40 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0xffffffff00000000ULL, 0x00000000ffffffffULL, },
+ { 0x0000000100000000ULL, 0x0000000000000001ULL, },
+ { 0x1c71c71d71c71c72ULL, 0xc71c71c81c71c71dULL, }, /* 48 */
+ { 0x0000000100000001ULL, 0xffffffff00000001ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0x00000000ffffffffULL, 0x0000000000000000ULL, },
+ { 0x0000000000000002ULL, 0xffffffff00000000ULL, },
+ { 0x00000000fffffffeULL, 0x0000000100000000ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0xffffffffffffffffULL, 0x00000000ffffffffULL, },
+ { 0xe38e38e48e38e38fULL, 0x38e38e39e38e38e4ULL, }, /* 56 */
+ { 0xffffffffffffffffULL, 0x00000001ffffffffULL, },
+ { 0x00000000ffffffffULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0x00000000fffffffeULL, 0x0000000100000000ULL, },
+ { 0x0000000000000002ULL, 0xffffffff00000000ULL, },
+ { 0x0000000000000000ULL, 0xffffffff00000000ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, }, /* 64 */
+ { 0x0000001c00000000ULL, 0x0000000300000000ULL, },
+ { 0x0000000100000000ULL, 0x0000000100000000ULL, },
+ { 0xffffffff00000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x00000000fffffff2ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x00000000ffffffffULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x00000000ffffffffULL, 0x0000000000000037ULL, }, /* 72 */
+ { 0x0000001300000000ULL, 0x00000002fffffffdULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000002ULL, 0xffffffff00000039ULL, },
+ { 0xffffffe600000001ULL, 0xfffffffafffffffcULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DIV_S_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DIV_S_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_u_b.c b/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_u_b.c
new file mode 100644
index 0000000000..770544a2de
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_u_b.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction DIV_U.B
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "DIV_U.B";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0x0303030303030303ULL, 0x0303030303030303ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0x0505050505050505ULL, 0x0505050505050505ULL, },
+ { 0x0101040101040101ULL, 0x0401010401010401ULL, },
+ { 0x0902010902010902ULL, 0x0109020109020109ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 16 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0x0202020202020202ULL, 0x0202020202020202ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0303030303030303ULL, 0x0303030303030303ULL, },
+ { 0x0001030001030001ULL, 0x0300010300010300ULL, },
+ { 0x0601000601000601ULL, 0x0006010006010006ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 24 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0x0000010000010000ULL, 0x0100000100000100ULL, },
+ { 0x0300000300000300ULL, 0x0003000003000003ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 32 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0x0202020202020202ULL, 0x0202020202020202ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0x0404040404040404ULL, 0x0404040404040404ULL, },
+ { 0x0001030001030001ULL, 0x0300010300010300ULL, },
+ { 0x0701010701010701ULL, 0x0107010107010107ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 40 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0100000100000100ULL, 0x0001000001000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 48 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0100000100000100ULL, 0x0001000001000001ULL, },
+ { 0x0201000201000201ULL, 0x0002010002010002ULL, },
+ { 0x0100000100000100ULL, 0x0001000001000001ULL, },
+ { 0x0402010402010402ULL, 0x0104020104020104ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0x0801000801000801ULL, 0x0008010008010008ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 56 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000010000010000ULL, 0x0100000100000100ULL, },
+ { 0x0001020001020001ULL, 0x0200010200010200ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0002030002030002ULL, 0x0300020300020300ULL, },
+ { 0x0000030000030000ULL, 0x0300000300000300ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, }, /* 64 */
+ { 0x0000ff0200000008ULL, 0x040000030c010200ULL, },
+ { 0x0001010100000000ULL, 0x0100000001020400ULL, },
+ { 0x01010a0200020000ULL, 0x0000000001010000ULL, },
+ { 0x0101000001010200ULL, 0x0002110000000015ULL, },
+ { 0x0101ff0101010101ULL, 0x0101010101010101ULL, },
+ { 0x0102000000000100ULL, 0x000100000001020cULL, },
+ { 0x0202000100030000ULL, 0x0001010000000001ULL, },
+ { 0x0100000004020102ULL, 0x0002120200000001ULL, }, /* 72 */
+ { 0x0000ff0102010010ULL, 0x0200010908000000ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0x0101070201040001ULL, 0x0000010101000000ULL, },
+ { 0x0000000002000201ULL, 0x01020c020000010dULL, },
+ { 0x0000ff0001000109ULL, 0x0700000808010200ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DIV_U_B(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DIV_U_B(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_u_d.c b/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_u_d.c
new file mode 100644
index 0000000000..9653e7db5c
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_u_d.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction DIV_U.D
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "DIV_U.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000003ULL, 0x0000000000000003ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000005ULL, 0x0000000000000005ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000004ULL, },
+ { 0x0000000000000009ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 16 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000002ULL, 0x0000000000000002ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000003ULL, 0x0000000000000003ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000003ULL, },
+ { 0x0000000000000006ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 24 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000003ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 32 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000002ULL, 0x0000000000000002ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000004ULL, 0x0000000000000004ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000003ULL, },
+ { 0x0000000000000007ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 40 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 48 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000002ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000004ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000008ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 56 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000002ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000003ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000003ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, }, /* 64 */
+ { 0x0000000000000000ULL, 0x0000000000000003ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000002ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, }, /* 72 */
+ { 0x0000000000000000ULL, 0x0000000000000002ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000007ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DIV_U_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DIV_U_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_u_h.c b/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_u_h.c
new file mode 100644
index 0000000000..3dcd30bee9
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_u_h.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction DIV_U.H
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "DIV_U.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0003000300030003ULL, 0x0003000300030003ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0005000500050005ULL, 0x0005000500050005ULL, },
+ { 0x0001000400010001ULL, 0x0004000100010004ULL, },
+ { 0x0009000100020009ULL, 0x0001000200090001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 16 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0002000200020002ULL, 0x0002000200020002ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0003000300030003ULL, 0x0003000300030003ULL, },
+ { 0x0000000300010000ULL, 0x0003000100000003ULL, },
+ { 0x0006000000010006ULL, 0x0000000100060000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 24 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0000000100000000ULL, 0x0001000000000001ULL, },
+ { 0x0003000000000003ULL, 0x0000000000030000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 32 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0002000200020002ULL, 0x0002000200020002ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0004000400040004ULL, 0x0004000400040004ULL, },
+ { 0x0000000300010000ULL, 0x0003000100000003ULL, },
+ { 0x0007000100010007ULL, 0x0001000100070001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 40 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0001000000000001ULL, 0x0000000000010000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 48 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0001000000000001ULL, 0x0000000000010000ULL, },
+ { 0x0002000000010002ULL, 0x0000000100020000ULL, },
+ { 0x0001000000000001ULL, 0x0000000000010000ULL, },
+ { 0x0004000100020004ULL, 0x0001000200040001ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0008000000010008ULL, 0x0000000100080000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 56 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000100000000ULL, 0x0001000000000001ULL, },
+ { 0x0000000200010000ULL, 0x0002000100000002ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000300020000ULL, 0x0003000200000003ULL, },
+ { 0x0000000300000000ULL, 0x0003000000000003ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, }, /* 64 */
+ { 0x0000025400000000ULL, 0x00030000000b0002ULL, },
+ { 0x0000000100000000ULL, 0x0001000000010004ULL, },
+ { 0x0001000a00000000ULL, 0x0000000000010000ULL, },
+ { 0x0001000000010002ULL, 0x0000001000000000ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0001000000000001ULL, 0x0000000000000002ULL, },
+ { 0x0002000000000000ULL, 0x0000000100000000ULL, },
+ { 0x0001000000040001ULL, 0x0000001100000000ULL, }, /* 72 */
+ { 0x000001c300020000ULL, 0x0002000100080000ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0001000700010000ULL, 0x0000000100010000ULL, },
+ { 0x0000000000020002ULL, 0x0001000c00000001ULL, },
+ { 0x0000003900010001ULL, 0x0007000000070002ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DIV_U_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DIV_U_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_u_w.c b/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_u_w.c
new file mode 100644
index 0000000000..fd395ef5e9
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-divide/test_msa_div_u_w.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction DIV_U.W
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "DIV_U.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000300000003ULL, 0x0000000300000003ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000500000005ULL, 0x0000000500000005ULL, },
+ { 0x0000000100000001ULL, 0x0000000400000001ULL, },
+ { 0x0000000900000002ULL, 0x0000000100000009ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 16 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000200000002ULL, 0x0000000200000002ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000300000003ULL, 0x0000000300000003ULL, },
+ { 0x0000000000000001ULL, 0x0000000300000000ULL, },
+ { 0x0000000600000001ULL, 0x0000000000000006ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 24 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000100000000ULL, },
+ { 0x0000000300000000ULL, 0x0000000000000003ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 32 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000200000002ULL, 0x0000000200000002ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000400000004ULL, 0x0000000400000004ULL, },
+ { 0x0000000000000001ULL, 0x0000000300000000ULL, },
+ { 0x0000000700000001ULL, 0x0000000100000007ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 40 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000100000000ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 48 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000100000000ULL, 0x0000000000000001ULL, },
+ { 0x0000000200000001ULL, 0x0000000000000002ULL, },
+ { 0x0000000100000000ULL, 0x0000000000000001ULL, },
+ { 0x0000000400000002ULL, 0x0000000100000004ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000800000001ULL, 0x0000000000000008ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 56 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000100000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000200000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000002ULL, 0x0000000300000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000300000000ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, }, /* 64 */
+ { 0x0000000000000000ULL, 0x000000030000000bULL, },
+ { 0x0000000000000000ULL, 0x0000000100000001ULL, },
+ { 0x0000000100000000ULL, 0x0000000000000001ULL, },
+ { 0x0000000100000001ULL, 0x0000000000000000ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000100000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000200000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000100000004ULL, 0x0000000000000000ULL, }, /* 72 */
+ { 0x0000000000000002ULL, 0x0000000200000008ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000100000001ULL, 0x0000000000000001ULL, },
+ { 0x0000000000000002ULL, 0x0000000100000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000700000007ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DIV_U_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DIV_U_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_s_d.c b/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_s_d.c
new file mode 100644
index 0000000000..af8d609bea
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_s_d.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction DOTP_S.D
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "DOTP_S.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000002ULL, 0x0000000000000002ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x00000000aaaaaaacULL, 0x00000000aaaaaaacULL, },
+ { 0xffffffff55555556ULL, 0xffffffff55555556ULL, },
+ { 0x0000000066666668ULL, 0x0000000066666668ULL, },
+ { 0xffffffff9999999aULL, 0xffffffff9999999aULL, },
+ { 0x000000008e38e38fULL, 0xffffffffe38e38e5ULL, },
+ { 0xffffffff71c71c73ULL, 0x000000001c71c71dULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x00000000aaaaaaacULL, 0x00000000aaaaaaacULL, }, /* 16 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x38e38e39c71c71c8ULL, 0x38e38e39c71c71c8ULL, },
+ { 0xc71c71c6e38e38e4ULL, 0xc71c71c6e38e38e4ULL, },
+ { 0x22222222eeeeeef0ULL, 0x22222222eeeeeef0ULL, },
+ { 0xddddddddbbbbbbbcULL, 0xddddddddbbbbbbbcULL, },
+ { 0x2f684bdab425ed0aULL, 0xf684bda197b425eeULL, },
+ { 0xd097b425f684bda2ULL, 0x097b425f12f684beULL, },
+ { 0xffffffff55555556ULL, 0xffffffff55555556ULL, }, /* 24 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc71c71c6e38e38e4ULL, 0xc71c71c6e38e38e4ULL, },
+ { 0x38e38e3871c71c72ULL, 0x38e38e3871c71c72ULL, },
+ { 0xdddddddd77777778ULL, 0xdddddddd77777778ULL, },
+ { 0x22222221dddddddeULL, 0x22222221dddddddeULL, },
+ { 0xd097b425da12f685ULL, 0x097b425e4bda12f7ULL, },
+ { 0x2f684bd97b425ed1ULL, 0xf684bda1097b425fULL, },
+ { 0x0000000066666668ULL, 0x0000000066666668ULL, }, /* 32 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x22222222eeeeeef0ULL, 0x22222222eeeeeef0ULL, },
+ { 0xdddddddd77777778ULL, 0xdddddddd77777778ULL, },
+ { 0x147ae14851eb8520ULL, 0x147ae14851eb8520ULL, },
+ { 0xeb851eb8147ae148ULL, 0xeb851eb8147ae148ULL, },
+ { 0x1c71c71d0b60b60cULL, 0xfa4fa4fa82d82d84ULL, },
+ { 0xe38e38e35b05b05cULL, 0x05b05b05e38e38e4ULL, },
+ { 0xffffffff9999999aULL, 0xffffffff9999999aULL, }, /* 40 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xddddddddbbbbbbbcULL, 0xddddddddbbbbbbbcULL, },
+ { 0x22222221dddddddeULL, 0x22222221dddddddeULL, },
+ { 0xeb851eb8147ae148ULL, 0xeb851eb8147ae148ULL, },
+ { 0x147ae147851eb852ULL, 0x147ae147851eb852ULL, },
+ { 0xe38e38e382d82d83ULL, 0x05b05b0560b60b61ULL, },
+ { 0x1c71c71c16c16c17ULL, 0xfa4fa4fa38e38e39ULL, },
+ { 0x000000008e38e38fULL, 0xffffffffe38e38e5ULL, }, /* 48 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x2f684bdab425ed0aULL, 0xf684bda197b425eeULL, },
+ { 0xd097b425da12f685ULL, 0x097b425e4bda12f7ULL, },
+ { 0x1c71c71d0b60b60cULL, 0xfa4fa4fa82d82d84ULL, },
+ { 0xe38e38e382d82d83ULL, 0x05b05b0560b60b61ULL, },
+ { 0x35ba78199add3c0dULL, 0x0fcd6e9dc0ca4589ULL, },
+ { 0xca4587e6f35ba782ULL, 0xf032916222c3f35cULL, },
+ { 0xffffffff71c71c73ULL, 0x000000001c71c71dULL, }, /* 56 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd097b425f684bda2ULL, 0x097b425f12f684beULL, },
+ { 0x2f684bd97b425ed1ULL, 0xf684bda1097b425fULL, },
+ { 0xe38e38e35b05b05cULL, 0x05b05b05e38e38e4ULL, },
+ { 0x1c71c71c16c16c17ULL, 0xfa4fa4fa38e38e39ULL, },
+ { 0xca4587e6f35ba782ULL, 0xf032916222c3f35cULL, },
+ { 0x35ba78187e6b74f1ULL, 0x0fcd6e9df9add3c1ULL, },
+ { 0x3e3ad4ae1266c290ULL, 0x1637d725aebdb714ULL, }, /* 64 */
+ { 0x0e3a0c27f7d6aae4ULL, 0x0575fbb7f08ff55cULL, },
+ { 0x1c00082337c84b78ULL, 0x0c3d39640fde8392ULL, },
+ { 0xda65cd5e9f696cdcULL, 0xdeeb6bec644a26d0ULL, },
+ { 0x0e3a0c27f7d6aae4ULL, 0x0575fbb7f08ff55cULL, },
+ { 0x17945c09b2e19689ULL, 0x032b395187d966b4ULL, },
+ { 0xec1f0e54b5aa67beULL, 0xfbe95b6e67ae6296ULL, },
+ { 0x1aad30609bff5437ULL, 0xf059a43d01b40370ULL, },
+ { 0x1c00082337c84b78ULL, 0x0c3d39640fde8392ULL, }, /* 72 */
+ { 0xec1f0e54b5aa67beULL, 0xfbe95b6e67ae6296ULL, },
+ { 0x2e9326619bb7c8e4ULL, 0x225024d84d163b91ULL, },
+ { 0xc17a5d0372a2a622ULL, 0x0afd6368668933a8ULL, },
+ { 0xda65cd5e9f696cdcULL, 0xdeeb6bec644a26d0ULL, },
+ { 0x1aad30609bff5437ULL, 0xf059a43d01b40370ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DOTP_S_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DOTP_S_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_s_h.c b/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_s_h.c
new file mode 100644
index 0000000000..40de72ae97
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_s_h.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction DOTP_S.H
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "DOTP_S.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0002000200020002ULL, 0x0002000200020002ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x00ac00ac00ac00acULL, 0x00ac00ac00ac00acULL, },
+ { 0xff56ff56ff56ff56ULL, 0xff56ff56ff56ff56ULL, },
+ { 0x0068006800680068ULL, 0x0068006800680068ULL, },
+ { 0xff9aff9aff9aff9aULL, 0xff9aff9aff9aff9aULL, },
+ { 0x008fffe5003a008fULL, 0xffe5003a008fffe5ULL, },
+ { 0xff73001dffc8ff73ULL, 0x001dffc8ff73001dULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x00ac00ac00ac00acULL, 0x00ac00ac00ac00acULL, }, /* 16 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x39c839c839c839c8ULL, 0x39c839c839c839c8ULL, },
+ { 0xc6e4c6e4c6e4c6e4ULL, 0xc6e4c6e4c6e4c6e4ULL, },
+ { 0x22f022f022f022f0ULL, 0x22f022f022f022f0ULL, },
+ { 0xddbcddbcddbcddbcULL, 0xddbcddbcddbcddbcULL, },
+ { 0x300af6ee137c300aULL, 0xf6ee137c300af6eeULL, },
+ { 0xd0a209beed30d0a2ULL, 0x09beed30d0a209beULL, },
+ { 0xff56ff56ff56ff56ULL, 0xff56ff56ff56ff56ULL, }, /* 24 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc6e4c6e4c6e4c6e4ULL, 0xc6e4c6e4c6e4c6e4ULL, },
+ { 0x3872387238723872ULL, 0x3872387238723872ULL, },
+ { 0xdd78dd78dd78dd78ULL, 0xdd78dd78dd78dd78ULL, },
+ { 0x21de21de21de21deULL, 0x21de21de21de21deULL, },
+ { 0xd08508f7ecbed085ULL, 0x08f7ecbed08508f7ULL, },
+ { 0x2ed1f65f12982ed1ULL, 0xf65f12982ed1f65fULL, },
+ { 0x0068006800680068ULL, 0x0068006800680068ULL, }, /* 32 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x22f022f022f022f0ULL, 0x22f022f022f022f0ULL, },
+ { 0xdd78dd78dd78dd78ULL, 0xdd78dd78dd78dd78ULL, },
+ { 0x1520152015201520ULL, 0x1520152015201520ULL, },
+ { 0xeb48eb48eb48eb48ULL, 0xeb48eb48eb48eb48ULL, },
+ { 0x1d0cfa840bc81d0cULL, 0xfa840bc81d0cfa84ULL, },
+ { 0xe35c05e4f4a0e35cULL, 0x05e4f4a0e35c05e4ULL, },
+ { 0xff9aff9aff9aff9aULL, 0xff9aff9aff9aff9aULL, }, /* 40 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xddbcddbcddbcddbcULL, 0xddbcddbcddbcddbcULL, },
+ { 0x21de21de21de21deULL, 0x21de21de21de21deULL, },
+ { 0xeb48eb48eb48eb48ULL, 0xeb48eb48eb48eb48ULL, },
+ { 0x1452145214521452ULL, 0x1452145214521452ULL, },
+ { 0xe3830561f472e383ULL, 0x0561f472e3830561ULL, },
+ { 0x1c17fa390b281c17ULL, 0xfa390b281c17fa39ULL, },
+ { 0x008fffe5003a008fULL, 0xffe5003a008fffe5ULL, }, /* 48 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x300af6ee137c300aULL, 0xf6ee137c300af6eeULL, },
+ { 0xd08508f7ecbed085ULL, 0x08f7ecbed08508f7ULL, },
+ { 0x1d0cfa840bc81d0cULL, 0xfa840bc81d0cfa84ULL, },
+ { 0xe3830561f472e383ULL, 0x0561f472e3830561ULL, },
+ { 0x360d0f893f04360dULL, 0x0f893f04360d0f89ULL, },
+ { 0xca82f05cc136ca82ULL, 0xf05cc136ca82f05cULL, },
+ { 0xff73001dffc8ff73ULL, 0x001dffc8ff73001dULL, }, /* 56 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xd0a209beed30d0a2ULL, 0x09beed30d0a209beULL, },
+ { 0x2ed1f65f12982ed1ULL, 0xf65f12982ed1f65fULL, },
+ { 0xe35c05e4f4a0e35cULL, 0x05e4f4a0e35c05e4ULL, },
+ { 0x1c17fa390b281c17ULL, 0xfa390b281c17fa39ULL, },
+ { 0xca82f05cc136ca82ULL, 0xf05cc136ca82f05cULL, },
+ { 0x34f10fc13e9234f1ULL, 0x0fc13e9234f10fc1ULL, },
+ { 0x64240d342bc42c39ULL, 0x3f6a22fd3b1d1990ULL, }, /* 64 */
+ { 0xe704ebe4e24eef13ULL, 0x01a706951e1be630ULL, },
+ { 0x4ca419cce226b927ULL, 0xfb55fd241553f560ULL, },
+ { 0xec36ee202172098aULL, 0xd846ec28206404e0ULL, },
+ { 0xe704ebe4e24eef13ULL, 0x01a706951e1be630ULL, },
+ { 0x111d264945920cf1ULL, 0x0195153d113a1a54ULL, },
+ { 0xea70debeff82160dULL, 0x04260f88039c0b8aULL, },
+ { 0xe9721dc70769091eULL, 0xf8711c48091bf7e4ULL, },
+ { 0x4ca419cce226b927ULL, 0xfb55fd241553f560ULL, }, /* 72 */
+ { 0xea70debeff82160dULL, 0x04260f88039c0b8aULL, },
+ { 0x3b3437281d127579ULL, 0x0c310d25237206e9ULL, },
+ { 0xf706df16dc8de6b6ULL, 0xf0d31b5827f9f42aULL, },
+ { 0xec36ee202172098aULL, 0xd846ec28206404e0ULL, },
+ { 0xe9721dc70769091eULL, 0xf8711c48091bf7e4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DOTP_S_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DOTP_S_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_s_w.c b/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_s_w.c
new file mode 100644
index 0000000000..2f1d23be6f
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_s_w.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction DOTP_S.W
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "DOTP_S.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000200000002ULL, 0x0000000200000002ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000aaac0000aaacULL, 0x0000aaac0000aaacULL, },
+ { 0xffff5556ffff5556ULL, 0xffff5556ffff5556ULL, },
+ { 0x0000666800006668ULL, 0x0000666800006668ULL, },
+ { 0xffff999affff999aULL, 0xffff999affff999aULL, },
+ { 0xffffe38f00008e3aULL, 0x000038e5ffffe38fULL, },
+ { 0x00001c73ffff71c8ULL, 0xffffc71d00001c73ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000aaac0000aaacULL, 0x0000aaac0000aaacULL, }, /* 16 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x38e471c838e471c8ULL, 0x38e471c838e471c8ULL, },
+ { 0xc71c38e4c71c38e4ULL, 0xc71c38e4c71c38e4ULL, },
+ { 0x2222eef02222eef0ULL, 0x2222eef02222eef0ULL, },
+ { 0xddddbbbcddddbbbcULL, 0xddddbbbcddddbbbcULL, },
+ { 0xf684ed0a2f69097cULL, 0x12f725eef684ed0aULL, },
+ { 0x097bbda2d097a130ULL, 0xed0984be097bbda2ULL, },
+ { 0xffff5556ffff5556ULL, 0xffff5556ffff5556ULL, }, /* 24 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc71c38e4c71c38e4ULL, 0xc71c38e4c71c38e4ULL, },
+ { 0x38e31c7238e31c72ULL, 0x38e31c7238e31c72ULL, },
+ { 0xdddd7778dddd7778ULL, 0xdddd7778dddd7778ULL, },
+ { 0x2221ddde2221dddeULL, 0x2221ddde2221dddeULL, },
+ { 0x097af685d09784beULL, 0xed0912f7097af685ULL, },
+ { 0xf6845ed12f67d098ULL, 0x12f6425ff6845ed1ULL, },
+ { 0x0000666800006668ULL, 0x0000666800006668ULL, }, /* 32 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x2222eef02222eef0ULL, 0x2222eef02222eef0ULL, },
+ { 0xdddd7778dddd7778ULL, 0xdddd7778dddd7778ULL, },
+ { 0x147b8520147b8520ULL, 0x147b8520147b8520ULL, },
+ { 0xeb84e148eb84e148ULL, 0xeb84e148eb84e148ULL, },
+ { 0xfa4fb60c1c7271c8ULL, 0x0b612d84fa4fb60cULL, },
+ { 0x05b0b05ce38df4a0ULL, 0xf49f38e405b0b05cULL, },
+ { 0xffff999affff999aULL, 0xffff999affff999aULL, }, /* 40 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xddddbbbcddddbbbcULL, 0xddddbbbcddddbbbcULL, },
+ { 0x2221ddde2221dddeULL, 0x2221ddde2221dddeULL, },
+ { 0xeb84e148eb84e148ULL, 0xeb84e148eb84e148ULL, },
+ { 0x147ab852147ab852ULL, 0x147ab852147ab852ULL, },
+ { 0x05b02d83e38e1c72ULL, 0xf49f0b6105b02d83ULL, },
+ { 0xfa4f6c171c717d28ULL, 0x0b608e39fa4f6c17ULL, },
+ { 0xffffe38f00008e3aULL, 0x000038e5ffffe38fULL, }, /* 48 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xf684ed0a2f69097cULL, 0x12f725eef684ed0aULL, },
+ { 0x097af685d09784beULL, 0xed0912f7097af685ULL, },
+ { 0xfa4fb60c1c7271c8ULL, 0x0b612d84fa4fb60cULL, },
+ { 0x05b02d83e38e1c72ULL, 0xf49f0b6105b02d83ULL, },
+ { 0x0fcd3c0d35bb4f04ULL, 0x3f3645890fcd3c0dULL, },
+ { 0xf032a782ca453f36ULL, 0xc0c9f35cf032a782ULL, },
+ { 0x00001c73ffff71c8ULL, 0xffffc71d00001c73ULL, }, /* 56 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x097bbda2d097a130ULL, 0xed0984be097bbda2ULL, },
+ { 0xf6845ed12f67d098ULL, 0x12f6425ff6845ed1ULL, },
+ { 0x05b0b05ce38df4a0ULL, 0xf49f38e405b0b05cULL, },
+ { 0xfa4f6c171c717d28ULL, 0x0b608e39fa4f6c17ULL, },
+ { 0xf032a782ca453f36ULL, 0xc0c9f35cf032a782ULL, },
+ { 0x0fcd74f135ba3292ULL, 0x3f35d3c10fcd74f1ULL, },
+ { 0x3a57fe7422c25584ULL, 0x16b6b9f518facfa9ULL, }, /* 64 */
+ { 0x01f36d90f9441446ULL, 0x0286cfede5f4db15ULL, },
+ { 0x2f1518bcce21d93eULL, 0x0934568af4ec6499ULL, },
+ { 0xc9576c1204f83042ULL, 0xd91d3e4709b06e36ULL, },
+ { 0x01f36d90f9441446ULL, 0x0286cfede5f4db15ULL, },
+ { 0x0012474d242f32a9ULL, 0x13f2a8f51ca9cd91ULL, },
+ { 0x0144b48a04a7d0ddULL, 0x124b1c4e04fa8e45ULL, },
+ { 0xfe2a6f6923268793ULL, 0x179e9377ef4766beULL, },
+ { 0x2f1518bcce21d93eULL, 0x0934568af4ec6499ULL, }, /* 72 */
+ { 0x0144b48a04a7d0ddULL, 0x124b1c4e04fa8e45ULL, },
+ { 0x352c988848431561ULL, 0x12e4f841217b42c9ULL, },
+ { 0xd437b4e8f3b0139fULL, 0x08c7d980187d5896ULL, },
+ { 0xc9576c1204f83042ULL, 0xd91d3e4709b06e36ULL, },
+ { 0xfe2a6f6923268793ULL, 0x179e9377ef4766beULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DOTP_S_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DOTP_S_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_u_d.c b/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_u_d.c
new file mode 100644
index 0000000000..e998e00410
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_u_d.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction DOTP_U.D
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "DOTP_U.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xfffffffc00000002ULL, 0xfffffffc00000002ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x55555552aaaaaaacULL, 0x55555552aaaaaaacULL, },
+ { 0xaaaaaaa955555556ULL, 0xaaaaaaa955555556ULL, },
+ { 0x9999999666666668ULL, 0x9999999666666668ULL, },
+ { 0x666666659999999aULL, 0x666666659999999aULL, },
+ { 0x71c71c6f8e38e38fULL, 0x1c71c719e38e38e5ULL, },
+ { 0x8e38e38c71c71c73ULL, 0xe38e38e21c71c71dULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x55555552aaaaaaacULL, 0x55555552aaaaaaacULL, }, /* 16 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xe38e38e1c71c71c8ULL, 0xe38e38e1c71c71c8ULL, },
+ { 0x71c71c70e38e38e4ULL, 0x71c71c70e38e38e4ULL, },
+ { 0x1111110eeeeeeef0ULL, 0x1111110eeeeeeef0ULL, },
+ { 0x44444443bbbbbbbcULL, 0x44444443bbbbbbbcULL, },
+ { 0xf684bd9fb425ed0aULL, 0xbda12f6697b425eeULL, },
+ { 0x5ed097b2f684bda2ULL, 0x97b425ec12f684beULL, },
+ { 0xaaaaaaa955555556ULL, 0xaaaaaaa955555556ULL, }, /* 24 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x71c71c70e38e38e4ULL, 0x71c71c70e38e38e4ULL, },
+ { 0x38e38e3871c71c72ULL, 0x38e38e3871c71c72ULL, },
+ { 0x8888888777777778ULL, 0x8888888777777778ULL, },
+ { 0x22222221dddddddeULL, 0x22222221dddddddeULL, },
+ { 0x7b425ecfda12f685ULL, 0x5ed097b34bda12f7ULL, },
+ { 0x2f684bd97b425ed1ULL, 0x4bda12f6097b425fULL, },
+ { 0x9999999666666668ULL, 0x9999999666666668ULL, }, /* 32 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x1111110eeeeeeef0ULL, 0x1111110eeeeeeef0ULL, },
+ { 0x8888888777777778ULL, 0x8888888777777778ULL, },
+ { 0x47ae147851eb8520ULL, 0x47ae147851eb8520ULL, },
+ { 0x51eb851e147ae148ULL, 0x51eb851e147ae148ULL, },
+ { 0x27d27d260b60b60cULL, 0xe38e38e182d82d84ULL, },
+ { 0x71c71c705b05b05cULL, 0xb60b60b4e38e38e4ULL, },
+ { 0x666666659999999aULL, 0x666666659999999aULL, }, /* 40 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x44444443bbbbbbbcULL, 0x44444443bbbbbbbcULL, },
+ { 0x22222221dddddddeULL, 0x22222221dddddddeULL, },
+ { 0x51eb851e147ae148ULL, 0x51eb851e147ae148ULL, },
+ { 0x147ae147851eb852ULL, 0x147ae147851eb852ULL, },
+ { 0x49f49f4982d82d83ULL, 0x38e38e3860b60b61ULL, },
+ { 0x1c71c71c16c16c17ULL, 0x2d82d82d38e38e39ULL, },
+ { 0x71c71c6f8e38e38fULL, 0x1c71c719e38e38e5ULL, }, /* 48 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xf684bd9fb425ed0aULL, 0xbda12f6697b425eeULL, },
+ { 0x7b425ecfda12f685ULL, 0x5ed097b34bda12f7ULL, },
+ { 0x27d27d260b60b60cULL, 0xe38e38e182d82d84ULL, },
+ { 0x49f49f4982d82d83ULL, 0x38e38e3860b60b61ULL, },
+ { 0x1948b0fb9add3c0dULL, 0xd6e9e063c0ca4589ULL, },
+ { 0x587e6b73f35ba782ULL, 0x4587e6b622c3f35cULL, },
+ { 0x8e38e38c71c71c73ULL, 0xe38e38e21c71c71dULL, }, /* 56 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5ed097b2f684bda2ULL, 0x97b425ec12f684beULL, },
+ { 0x2f684bd97b425ed1ULL, 0x4bda12f6097b425fULL, },
+ { 0x71c71c705b05b05cULL, 0xb60b60b4e38e38e4ULL, },
+ { 0x1c71c71c16c16c17ULL, 0x2d82d82d38e38e39ULL, },
+ { 0x587e6b73f35ba782ULL, 0x4587e6b622c3f35cULL, },
+ { 0x35ba78187e6b74f1ULL, 0x9e06522bf9add3c1ULL, },
+ { 0x4f10a2461266c290ULL, 0x132f373daebdb714ULL, }, /* 64 */
+ { 0x9262f356f7d6aae4ULL, 0x1ab54eb3f08ff55cULL, },
+ { 0x7927f2d937c84b78ULL, 0xb5e40e840fde8392ULL, },
+ { 0x4ab4e3ab9f696cdcULL, 0xd21109f6644a26d0ULL, },
+ { 0x9262f356f7d6aae4ULL, 0x1ab54eb3f08ff55cULL, },
+ { 0x0f105ccfb2e19689ULL, 0x032b395187d966b4ULL, },
+ { 0xe1cb8469b5aa67beULL, 0x1128ae6a67ae6296ULL, },
+ { 0x8afc46ad9bff5437ULL, 0x1890b25301b40370ULL, },
+ { 0x7927f2d937c84b78ULL, 0xb5e40e840fde8392ULL, }, /* 72 */
+ { 0xe1cb8469b5aa67beULL, 0x1128ae6a67ae6296ULL, },
+ { 0xfae79ab59bb7c8e4ULL, 0x78a66f004d163b91ULL, },
+ { 0x8ffb559e72a2a622ULL, 0x8744321b668933a8ULL, },
+ { 0x4ab4e3ab9f696cdcULL, 0xd21109f6644a26d0ULL, },
+ { 0x8afc46ad9bff5437ULL, 0x1890b25301b40370ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DOTP_U_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DOTP_U_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_u_h.c b/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_u_h.c
new file mode 100644
index 0000000000..e8db601a74
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_u_h.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction DOTP_U.H
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "DOTP_U.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xfc02fc02fc02fc02ULL, 0xfc02fc02fc02fc02ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x52ac52ac52ac52acULL, 0x52ac52ac52ac52acULL, },
+ { 0xa956a956a956a956ULL, 0xa956a956a956a956ULL, },
+ { 0x9668966896689668ULL, 0x9668966896689668ULL, },
+ { 0x659a659a659a659aULL, 0x659a659a659a659aULL, },
+ { 0x6f8f19e5c53a6f8fULL, 0x19e5c53a6f8f19e5ULL, },
+ { 0x8c73e21d36c88c73ULL, 0xe21d36c88c73e21dULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x52ac52ac52ac52acULL, 0x52ac52ac52ac52acULL, }, /* 16 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xe1c8e1c8e1c8e1c8ULL, 0xe1c8e1c8e1c8e1c8ULL, },
+ { 0x70e470e470e470e4ULL, 0x70e470e470e470e4ULL, },
+ { 0x0ef00ef00ef00ef0ULL, 0x0ef00ef00ef00ef0ULL, },
+ { 0x43bc43bc43bc43bcULL, 0x43bc43bc43bc43bcULL, },
+ { 0xf50abbee837cf50aULL, 0xbbee837cf50abbeeULL, },
+ { 0x5da296becf305da2ULL, 0x96becf305da296beULL, },
+ { 0xa956a956a956a956ULL, 0xa956a956a956a956ULL, }, /* 24 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x70e470e470e470e4ULL, 0x70e470e470e470e4ULL, },
+ { 0x3872387238723872ULL, 0x3872387238723872ULL, },
+ { 0x8778877887788778ULL, 0x8778877887788778ULL, },
+ { 0x21de21de21de21deULL, 0x21de21de21de21deULL, },
+ { 0x7a855df741be7a85ULL, 0x5df741be7a855df7ULL, },
+ { 0x2ed14b5f67982ed1ULL, 0x4b5f67982ed14b5fULL, },
+ { 0x9668966896689668ULL, 0x9668966896689668ULL, }, /* 32 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0ef00ef00ef00ef0ULL, 0x0ef00ef00ef00ef0ULL, },
+ { 0x8778877887788778ULL, 0x8778877887788778ULL, },
+ { 0x4520452045204520ULL, 0x4520452045204520ULL, },
+ { 0x5148514851485148ULL, 0x5148514851485148ULL, },
+ { 0x260ce1849dc8260cULL, 0xe1849dc8260ce184ULL, },
+ { 0x705cb4e4f8a0705cULL, 0xb4e4f8a0705cb4e4ULL, },
+ { 0x659a659a659a659aULL, 0x659a659a659a659aULL, }, /* 40 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x43bc43bc43bc43bcULL, 0x43bc43bc43bc43bcULL, },
+ { 0x21de21de21de21deULL, 0x21de21de21de21deULL, },
+ { 0x5148514851485148ULL, 0x5148514851485148ULL, },
+ { 0x1452145214521452ULL, 0x1452145214521452ULL, },
+ { 0x4983386127724983ULL, 0x3861277249833861ULL, },
+ { 0x1c172d393e281c17ULL, 0x2d393e281c172d39ULL, },
+ { 0x6f8f19e5c53a6f8fULL, 0x19e5c53a6f8f19e5ULL, }, /* 48 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xf50abbee837cf50aULL, 0xbbee837cf50abbeeULL, },
+ { 0x7a855df741be7a85ULL, 0x5df741be7a855df7ULL, },
+ { 0x260ce1849dc8260cULL, 0xe1849dc8260ce184ULL, },
+ { 0x4983386127724983ULL, 0x3861277249833861ULL, },
+ { 0x180dd5895b04180dULL, 0xd5895b04180dd589ULL, },
+ { 0x5782445c6a365782ULL, 0x445c6a365782445cULL, },
+ { 0x8c73e21d36c88c73ULL, 0xe21d36c88c73e21dULL, }, /* 56 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5da296becf305da2ULL, 0x96becf305da296beULL, },
+ { 0x2ed14b5f67982ed1ULL, 0x4b5f67982ed14b5fULL, },
+ { 0x705cb4e4f8a0705cULL, 0xb4e4f8a0705cb4e4ULL, },
+ { 0x1c172d393e281c17ULL, 0x2d393e281c172d39ULL, },
+ { 0x5782445c6a365782ULL, 0x445c6a365782445cULL, },
+ { 0x34f19dc1cc9234f1ULL, 0x9dc1cc9234f19dc1ULL, },
+ { 0x742471342bc42c39ULL, 0x3f6a22fd371d7990ULL, }, /* 64 */
+ { 0xd4044ee4444e4413ULL, 0x68a71195331b4430ULL, },
+ { 0x80a423cc6c264e27ULL, 0x62556624be531a60ULL, },
+ { 0x5c36512021725e8aULL, 0x8a465528c764a2e0ULL, },
+ { 0xd4044ee4444e4413ULL, 0x68a71195331b4430ULL, },
+ { 0x831d26496b929af1ULL, 0xef958b3d113a1254ULL, },
+ { 0xeb7041beae82700dULL, 0xd326aa88189c1f8aULL, },
+ { 0xa8721dc73869b21eULL, 0xf27179481e1be5e4ULL, },
+ { 0x80a423cc6c264e27ULL, 0x62556624be531a60ULL, }, /* 72 */
+ { 0xeb7041beae82700dULL, 0xd326aa88189c1f8aULL, },
+ { 0x9334e7282d128b79ULL, 0xbc319725797206e9ULL, },
+ { 0x670642166b8da1b6ULL, 0xe0d340587bf92d2aULL, },
+ { 0x5c36512021725e8aULL, 0x8a465528c764a2e0ULL, },
+ { 0xa8721dc73869b21eULL, 0xf27179481e1be5e4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DOTP_U_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DOTP_U_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_u_w.c b/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_u_w.c
new file mode 100644
index 0000000000..cf5bd13f48
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-dot-product/test_msa_dotp_u_w.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction DOTP_U.W
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "DOTP_U.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xfffc0002fffc0002ULL, 0xfffc0002fffc0002ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5552aaac5552aaacULL, 0x5552aaac5552aaacULL, },
+ { 0xaaa95556aaa95556ULL, 0xaaa95556aaa95556ULL, },
+ { 0x9996666899966668ULL, 0x9996666899966668ULL, },
+ { 0x6665999a6665999aULL, 0x6665999a6665999aULL, },
+ { 0x1c6fe38f71c48e3aULL, 0xc71a38e51c6fe38fULL, },
+ { 0xe38c1c738e3771c8ULL, 0x38e1c71de38c1c73ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5552aaac5552aaacULL, 0x5552aaac5552aaacULL, }, /* 16 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xe38c71c8e38c71c8ULL, 0xe38c71c8e38c71c8ULL, },
+ { 0x71c638e471c638e4ULL, 0x71c638e471c638e4ULL, },
+ { 0x110eeef0110eeef0ULL, 0x110eeef0110eeef0ULL, },
+ { 0x4443bbbc4443bbbcULL, 0x4443bbbc4443bbbcULL, },
+ { 0xbd9fed0af683097cULL, 0x84bc25eebd9fed0aULL, },
+ { 0x97b2bda25ecfa130ULL, 0xd09684be97b2bda2ULL, },
+ { 0xaaa95556aaa95556ULL, 0xaaa95556aaa95556ULL, }, /* 24 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x71c638e471c638e4ULL, 0x71c638e471c638e4ULL, },
+ { 0x38e31c7238e31c72ULL, 0x38e31c7238e31c72ULL, },
+ { 0x8887777888877778ULL, 0x8887777888877778ULL, },
+ { 0x2221ddde2221dddeULL, 0x2221ddde2221dddeULL, },
+ { 0x5ecff6857b4184beULL, 0x425e12f75ecff685ULL, },
+ { 0x4bd95ed12f67d098ULL, 0x684b425f4bd95ed1ULL, },
+ { 0x9996666899966668ULL, 0x9996666899966668ULL, }, /* 32 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x110eeef0110eeef0ULL, 0x110eeef0110eeef0ULL, },
+ { 0x8887777888877778ULL, 0x8887777888877778ULL, },
+ { 0x47ab852047ab8520ULL, 0x47ab852047ab8520ULL, },
+ { 0x51eae14851eae148ULL, 0x51eae14851eae148ULL, },
+ { 0xe38cb60c27d071c8ULL, 0x9f482d84e38cb60cULL, },
+ { 0xb609b05c71c5f4a0ULL, 0xfa4e38e4b609b05cULL, },
+ { 0x6665999a6665999aULL, 0x6665999a6665999aULL, }, /* 40 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4443bbbc4443bbbcULL, 0x4443bbbc4443bbbcULL, },
+ { 0x2221ddde2221dddeULL, 0x2221ddde2221dddeULL, },
+ { 0x51eae14851eae148ULL, 0x51eae14851eae148ULL, },
+ { 0x147ab852147ab852ULL, 0x147ab852147ab852ULL, },
+ { 0x38e32d8349f41c72ULL, 0x27d20b6138e32d83ULL, },
+ { 0x2d826c171c717d28ULL, 0x3e938e392d826c17ULL, },
+ { 0x1c6fe38f71c48e3aULL, 0xc71a38e51c6fe38fULL, }, /* 48 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xbd9fed0af683097cULL, 0x84bc25eebd9fed0aULL, },
+ { 0x5ecff6857b4184beULL, 0x425e12f75ecff685ULL, },
+ { 0xe38cb60c27d071c8ULL, 0x9f482d84e38cb60cULL, },
+ { 0x38e32d8349f41c72ULL, 0x27d20b6138e32d83ULL, },
+ { 0xd6e93c0d19474f04ULL, 0x5ba64589d6e93c0dULL, },
+ { 0x4586a782587d3f36ULL, 0x6b73f35c4586a782ULL, },
+ { 0xe38c1c738e3771c8ULL, 0x38e1c71de38c1c73ULL, }, /* 56 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x97b2bda25ecfa130ULL, 0xd09684be97b2bda2ULL, },
+ { 0x4bd95ed12f67d098ULL, 0x684b425f4bd95ed1ULL, },
+ { 0xb609b05c71c5f4a0ULL, 0xfa4e38e4b609b05cULL, },
+ { 0x2d826c171c717d28ULL, 0x3e938e392d826c17ULL, },
+ { 0x4586a782587d3f36ULL, 0x6b73f35c4586a782ULL, },
+ { 0x9e0574f135ba3292ULL, 0xcd6dd3c19e0574f1ULL, },
+ { 0x18c3fe7422c25584ULL, 0x16b6b9f57608cfa9ULL, }, /* 64 */
+ { 0x867e6d904e841446ULL, 0x0de4cfed4e2fdb15ULL, },
+ { 0xf94f18bc4bc3d93eULL, 0x1492568ac3a66499ULL, },
+ { 0x4ff36c125a383042ULL, 0x2fe23e4744196e36ULL, },
+ { 0x867e6d904e841446ULL, 0x0de4cfed4e2fdb15ULL, },
+ { 0xf78e474db23f32a9ULL, 0x8a26a8f51ca9cd91ULL, },
+ { 0xa9bfb48aa4c2d0ddULL, 0x94641c4e1a398e45ULL, },
+ { 0x6e796f69cc7c8793ULL, 0x6e879377578266beULL, },
+ { 0xf94f18bc4bc3d93eULL, 0x1492568ac3a66499ULL, }, /* 72 */
+ { 0xa9bfb48aa4c2d0ddULL, 0x94641c4e1a398e45ULL, },
+ { 0xeb349888d2e11561ULL, 0xa0e2f84177d142c9ULL, },
+ { 0x5ad3b4e8bfaf139fULL, 0x8076d98091fe5896ULL, },
+ { 0x4ff36c125a383042ULL, 0x2fe23e4744196e36ULL, },
+ { 0x6e796f69cc7c8793ULL, 0x6e879377578266beULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DOTP_U_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DOTP_U_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_b.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_b.c
index b7a9a61548..5fa2644c30 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_b.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MAX_A.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_d.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_d.c
index dfffaf5b5e..9d97982ab5 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MAX_A.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_h.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_h.c
index e0c1bd4c4b..3365f726a2 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MAX_A.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_w.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_w.c
index 40c30c5569..b33f4b7d79 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_a_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MAX_A.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_b.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_b.c
index ab50eee187..71e571d0c4 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_b.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MAX_S.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_d.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_d.c
index 2957db4abc..e088ab99e3 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MAX_S.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_h.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_h.c
index e101764d73..6d1b81a119 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MAX_S.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_w.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_w.c
index 119f03ffba..bd64294322 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_s_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MAX_S.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_b.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_b.c
index d18b6bf0cc..206d907a26 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_b.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MAX_U.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_d.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_d.c
index 1396e740ff..4dd247f54a 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MAX_U.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_h.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_h.c
index c7dff10709..0e6a7651eb 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MAX_U.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_w.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_w.c
index 910dbfc0ca..db61440551 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_max_u_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MAX_U.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_b.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_b.c
index c632fe974f..d2a93a2e44 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_b.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MIN_A.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_d.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_d.c
index 5f9a9d4706..69fd3c7662 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MIN_A.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_h.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_h.c
index dc73927bb7..9f45b55539 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MIN_A.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_w.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_w.c
index 67b33f3751..b08231d65f 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_a_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MIN_A.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_b.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_b.c
index 76bb133da7..80b5201be1 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_b.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MIN_S.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_d.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_d.c
index 8ef57a9533..0ed319024c 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MIN_S.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_h.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_h.c
index e206040f98..b049054d9f 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MIN_S.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_w.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_w.c
index 7532bce550..2bcd0a00ef 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_s_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MIN_S.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_b.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_b.c
index 1f611453a2..2a06b43379 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_b.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MIN_U.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_d.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_d.c
index 4626c62354..37924f3038 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_d.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MIN_U.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_h.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_h.c
index 5eeb8d034b..1846995ce4 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_h.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MIN_U.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_w.c b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_w.c
index e70964afa8..8b20c05440 100644
--- a/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_w.c
+++ b/tests/tcg/mips/user/ase/msa/int-max-min/test_msa_min_u_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction MIN_U.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mul_q_h.c b/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mul_q_h.c
new file mode 100644
index 0000000000..f1526087fa
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mul_q_h.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction MUL_Q.H
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "MUL_Q.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000ffff00000000ULL, 0xffff00000000ffffULL, },
+ { 0xffff0000ffffffffULL, 0x0000ffffffff0000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 16 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x38e438e438e438e4ULL, 0x38e438e438e438e4ULL, },
+ { 0xc71cc71cc71cc71cULL, 0xc71cc71cc71cc71cULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0xddddddddddddddddULL, 0xddddddddddddddddULL, },
+ { 0x12f6da134bdb12f6ULL, 0xda134bdb12f6da13ULL, },
+ { 0xed0925edb425ed09ULL, 0x25edb425ed0925edULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 24 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc71cc71cc71cc71cULL, 0xc71cc71cc71cc71cULL, },
+ { 0x38e338e338e338e3ULL, 0x38e338e338e338e3ULL, },
+ { 0xddddddddddddddddULL, 0xddddddddddddddddULL, },
+ { 0x2221222122212221ULL, 0x2221222122212221ULL, },
+ { 0xed0925ecb425ed09ULL, 0x25ecb425ed0925ecULL, },
+ { 0x12f5da124bd912f5ULL, 0xda124bd912f5da12ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 32 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0xddddddddddddddddULL, 0xddddddddddddddddULL, },
+ { 0x147b147b147b147bULL, 0x147b147b147b147bULL, },
+ { 0xeb84eb84eb84eb84ULL, 0xeb84eb84eb84eb84ULL, },
+ { 0x0b60e93e2d830b60ULL, 0xe93e2d830b60e93eULL, },
+ { 0xf49f16c1d27cf49fULL, 0x16c1d27cf49f16c1ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 40 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xddddddddddddddddULL, 0xddddddddddddddddULL, },
+ { 0x2221222122212221ULL, 0x2221222122212221ULL, },
+ { 0xeb84eb84eb84eb84ULL, 0xeb84eb84eb84eb84ULL, },
+ { 0x147a147a147a147aULL, 0x147a147a147a147aULL, },
+ { 0xf49f16c1d27cf49fULL, 0x16c1d27cf49f16c1ULL, },
+ { 0x0b60e93e2d820b60ULL, 0xe93e2d820b60e93eULL, },
+ { 0x0000ffff00000000ULL, 0xffff00000000ffffULL, }, /* 48 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x12f6da134bdb12f6ULL, 0xda134bdb12f6da13ULL, },
+ { 0xed0925ecb425ed09ULL, 0x25ecb425ed0925ecULL, },
+ { 0x0b60e93e2d830b60ULL, 0xe93e2d830b60e93eULL, },
+ { 0xf49f16c1d27cf49fULL, 0x16c1d27cf49f16c1ULL, },
+ { 0x0652194865240652ULL, 0x1948652406521948ULL, },
+ { 0xf9ade6b79adcf9adULL, 0xe6b79adcf9ade6b7ULL, },
+ { 0xffff0000ffffffffULL, 0x0000ffffffff0000ULL, }, /* 56 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xed0925edb425ed09ULL, 0x25edb425ed0925edULL, },
+ { 0x12f5da124bd912f5ULL, 0xda124bd912f5da12ULL, },
+ { 0xf49f16c1d27cf49fULL, 0x16c1d27cf49f16c1ULL, },
+ { 0x0b60e93e2d820b60ULL, 0xe93e2d820b60e93eULL, },
+ { 0xf9ade6b79adcf9adULL, 0xe6b79adcf9ade6b7ULL, },
+ { 0x0651194965220651ULL, 0x1949652206511949ULL, },
+ { 0x6fb904f60cbd38c7ULL, 0x2c6b0102000431f1ULL, }, /* 64 */
+ { 0x03faffec1879da0eULL, 0x0b2bf9e1ffbfcc2aULL, },
+ { 0x4e261003e9dab268ULL, 0x1778faf00101e8d6ULL, },
+ { 0x9712fb9b1db7ec38ULL, 0xbccff56b01071259ULL, },
+ { 0x03faffec1879da0eULL, 0x0b2bf9e1ffbfcc2aULL, },
+ { 0x002400002f03195aULL, 0x02cf2515038635ccULL, },
+ { 0x02c8ffc1d57533d9ULL, 0x05e71eaef1eb1809ULL, },
+ { 0xfc43001139150d37ULL, 0xef194023f19aecf4ULL, },
+ { 0x4e261003e9dab268ULL, 0x1778faf00101e8d6ULL, }, /* 72 */
+ { 0x02c8ffc1d57533d9ULL, 0x05e71eaef1eb1809ULL, },
+ { 0x36aa33af267d6a08ULL, 0x0c67196238380abdULL, },
+ { 0xb69bf1d4cc591b07ULL, 0xdc7e3510397df77dULL, },
+ { 0x9712fb9b1db7ec38ULL, 0xbccff56b01071259ULL, },
+ { 0xfc43001139150d37ULL, 0xef194023f19aecf4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MUL_Q_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MUL_Q_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mul_q_w.c b/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mul_q_w.c
new file mode 100644
index 0000000000..df815ee9da
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mul_q_w.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction MUL_Q.W
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "MUL_Q.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0xffffffff00000000ULL, },
+ { 0xffffffffffffffffULL, 0x00000000ffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 16 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x38e38e3938e38e39ULL, 0x38e38e3938e38e39ULL, },
+ { 0xc71c71c6c71c71c6ULL, 0xc71c71c6c71c71c6ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0xddddddddddddddddULL, 0xddddddddddddddddULL, },
+ { 0x12f684be4bda12f7ULL, 0xda12f68512f684beULL, },
+ { 0xed097b42b425ed09ULL, 0x25ed097bed097b42ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 24 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc71c71c6c71c71c6ULL, 0xc71c71c6c71c71c6ULL, },
+ { 0x38e38e3838e38e38ULL, 0x38e38e3838e38e38ULL, },
+ { 0xddddddddddddddddULL, 0xddddddddddddddddULL, },
+ { 0x2222222122222221ULL, 0x2222222122222221ULL, },
+ { 0xed097b42b425ed09ULL, 0x25ed097aed097b42ULL, },
+ { 0x12f684bd4bda12f5ULL, 0xda12f68412f684bdULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 32 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0xddddddddddddddddULL, 0xddddddddddddddddULL, },
+ { 0x147ae148147ae148ULL, 0x147ae148147ae148ULL, },
+ { 0xeb851eb8eb851eb8ULL, 0xeb851eb8eb851eb8ULL, },
+ { 0x0b60b60b2d82d82eULL, 0xe93e93e90b60b60bULL, },
+ { 0xf49f49f4d27d27d2ULL, 0x16c16c17f49f49f4ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 40 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xddddddddddddddddULL, 0xddddddddddddddddULL, },
+ { 0x2222222122222221ULL, 0x2222222122222221ULL, },
+ { 0xeb851eb8eb851eb8ULL, 0xeb851eb8eb851eb8ULL, },
+ { 0x147ae147147ae147ULL, 0x147ae147147ae147ULL, },
+ { 0xf49f49f4d27d27d2ULL, 0x16c16c16f49f49f4ULL, },
+ { 0x0b60b60b2d82d82dULL, 0xe93e93e90b60b60bULL, },
+ { 0x0000000000000000ULL, 0xffffffff00000000ULL, }, /* 48 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x12f684be4bda12f7ULL, 0xda12f68512f684beULL, },
+ { 0xed097b42b425ed09ULL, 0x25ed097aed097b42ULL, },
+ { 0x0b60b60b2d82d82eULL, 0xe93e93e90b60b60bULL, },
+ { 0xf49f49f4d27d27d2ULL, 0x16c16c16f49f49f4ULL, },
+ { 0x06522c3f6522c3f3ULL, 0x1948b0fc06522c3fULL, },
+ { 0xf9add3c09add3c0dULL, 0xe6b74f03f9add3c0ULL, },
+ { 0xffffffffffffffffULL, 0x00000000ffffffffULL, }, /* 56 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xed097b42b425ed09ULL, 0x25ed097bed097b42ULL, },
+ { 0x12f684bd4bda12f5ULL, 0xda12f68412f684bdULL, },
+ { 0xf49f49f4d27d27d2ULL, 0x16c16c17f49f49f4ULL, },
+ { 0x0b60b60b2d82d82dULL, 0xe93e93e90b60b60bULL, },
+ { 0xf9add3c09add3c0dULL, 0xe6b74f03f9add3c0ULL, },
+ { 0x06522c3f6522c3f1ULL, 0x1948b0fc06522c3fULL, },
+ { 0x6fb7e8890cbdc0d2ULL, 0x2c6b144600049a04ULL, }, /* 64 */
+ { 0x03fa514e1879c701ULL, 0x0b2c6ca9ffbf8ac6ULL, },
+ { 0x4e252086e9daefbfULL, 0x1779189301015a34ULL, },
+ { 0x9713a7171db7f3a5ULL, 0xbccfb4690107236fULL, },
+ { 0x03fa514e1879c701ULL, 0x0b2c6ca9ffbf8ac6ULL, },
+ { 0x002442012f047611ULL, 0x02cf8c140386e68eULL, },
+ { 0x02c84b87d575d121ULL, 0x05e79a8af1eb1c52ULL, },
+ { 0xfc439edc3916c1e4ULL, 0xef19389cf19a0fddULL, },
+ { 0x4e252086e9daefbfULL, 0x1779189301015a34ULL, }, /* 72 */
+ { 0x02c84b87d575d121ULL, 0x05e79a8af1eb1c52ULL, },
+ { 0x36a93aff267d11c3ULL, 0x0c6788643838c14cULL, },
+ { 0xb69baa39cc590fcdULL, 0xdc7e6df7397c58d9ULL, },
+ { 0x9713a7171db7f3a5ULL, 0xbccfb4690107236fULL, },
+ { 0xfc439edc3916c1e4ULL, 0xef19389cf19a0fddULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MUL_Q_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MUL_Q_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulr_q_h.c b/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulr_q_h.c
new file mode 100644
index 0000000000..fd0a5fa7a8
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulr_q_h.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction MULR_Q.H
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "MULR_Q.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000010000ULL, 0x0000000100000000ULL, },
+ { 0x00000000ffff0000ULL, 0x0000ffff00000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, }, /* 16 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x38e438e438e438e4ULL, 0x38e438e438e438e4ULL, },
+ { 0xc71cc71cc71cc71cULL, 0xc71cc71cc71cc71cULL, },
+ { 0x2223222322232223ULL, 0x2223222322232223ULL, },
+ { 0xdddedddedddedddeULL, 0xdddedddedddedddeULL, },
+ { 0x12f7da134bdb12f7ULL, 0xda134bdb12f7da13ULL, },
+ { 0xed0a25eeb425ed0aULL, 0x25eeb425ed0a25eeULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 24 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc71cc71cc71cc71cULL, 0xc71cc71cc71cc71cULL, },
+ { 0x38e338e338e338e3ULL, 0x38e338e338e338e3ULL, },
+ { 0xddddddddddddddddULL, 0xddddddddddddddddULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0xed0925edb426ed09ULL, 0x25edb426ed0925edULL, },
+ { 0x12f6da134bda12f6ULL, 0xda134bda12f6da13ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 32 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x2223222322232223ULL, 0x2223222322232223ULL, },
+ { 0xddddddddddddddddULL, 0xddddddddddddddddULL, },
+ { 0x147c147c147c147cULL, 0x147c147c147c147cULL, },
+ { 0xeb85eb85eb85eb85ULL, 0xeb85eb85eb85eb85ULL, },
+ { 0x0b61e93e2d840b61ULL, 0xe93e2d840b61e93eULL, },
+ { 0xf49f16c2d27cf49fULL, 0x16c2d27cf49f16c2ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 40 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xdddedddedddedddeULL, 0xdddedddedddedddeULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0xeb85eb85eb85eb85ULL, 0xeb85eb85eb85eb85ULL, },
+ { 0x147b147b147b147bULL, 0x147b147b147b147bULL, },
+ { 0xf49f16c1d27df49fULL, 0x16c1d27df49f16c1ULL, },
+ { 0x0b60e93e2d830b60ULL, 0xe93e2d830b60e93eULL, },
+ { 0x0000000000010000ULL, 0x0000000100000000ULL, }, /* 48 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x12f7da134bdb12f7ULL, 0xda134bdb12f7da13ULL, },
+ { 0xed0925edb426ed09ULL, 0x25edb426ed0925edULL, },
+ { 0x0b61e93e2d840b61ULL, 0xe93e2d840b61e93eULL, },
+ { 0xf49f16c1d27df49fULL, 0x16c1d27df49f16c1ULL, },
+ { 0x0652194865240652ULL, 0x1948652406521948ULL, },
+ { 0xf9aee6b79addf9aeULL, 0xe6b79addf9aee6b7ULL, },
+ { 0x00000000ffff0000ULL, 0x0000ffff00000000ULL, }, /* 56 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xed0a25eeb425ed0aULL, 0x25eeb425ed0a25eeULL, },
+ { 0x12f6da134bda12f6ULL, 0xda134bda12f6da13ULL, },
+ { 0xf49f16c2d27cf49fULL, 0x16c2d27cf49f16c2ULL, },
+ { 0x0b60e93e2d830b60ULL, 0xe93e2d830b60e93eULL, },
+ { 0xf9aee6b79addf9aeULL, 0xe6b79addf9aee6b7ULL, },
+ { 0x0652194965230652ULL, 0x1949652306521949ULL, },
+ { 0x6fba04f60cbe38c7ULL, 0x2c6b0102000531f1ULL, }, /* 64 */
+ { 0x03faffed1879da0fULL, 0x0b2cf9e2ffbfcc2aULL, },
+ { 0x4e261004e9dbb269ULL, 0x1779faf00102e8d7ULL, },
+ { 0x9713fb9c1db7ec39ULL, 0xbccff56b01081259ULL, },
+ { 0x03faffed1879da0fULL, 0x0b2cf9e2ffbfcc2aULL, },
+ { 0x002400002f04195bULL, 0x02cf2516038735cdULL, },
+ { 0x02c8ffc1d57633daULL, 0x05e71eaff1eb180aULL, },
+ { 0xfc44001139160d37ULL, 0xef1a4023f19aecf5ULL, },
+ { 0x4e261004e9dbb269ULL, 0x1779faf00102e8d7ULL, }, /* 72 */
+ { 0x02c8ffc1d57633daULL, 0x05e71eaff1eb180aULL, },
+ { 0x36aa33af267e6a09ULL, 0x0c67196338390abeULL, },
+ { 0xb69bf1d4cc591b07ULL, 0xdc7f3511397df77eULL, },
+ { 0x9713fb9c1db7ec39ULL, 0xbccff56b01081259ULL, },
+ { 0xfc44001139160d37ULL, 0xef1a4023f19aecf5ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MULR_Q_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MULR_Q_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulr_q_w.c b/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulr_q_w.c
new file mode 100644
index 0000000000..f28b0d0a20
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulr_q_w.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction MULR_Q.W
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "MULR_Q.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0x00000000ffffffffULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, }, /* 16 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x38e38e3a38e38e3aULL, 0x38e38e3a38e38e3aULL, },
+ { 0xc71c71c7c71c71c7ULL, 0xc71c71c7c71c71c7ULL, },
+ { 0x2222222322222223ULL, 0x2222222322222223ULL, },
+ { 0xdddddddedddddddeULL, 0xdddddddedddddddeULL, },
+ { 0x12f684be4bda12f7ULL, 0xda12f68512f684beULL, },
+ { 0xed097b43b425ed09ULL, 0x25ed097ced097b43ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 24 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc71c71c7c71c71c7ULL, 0xc71c71c7c71c71c7ULL, },
+ { 0x38e38e3838e38e38ULL, 0x38e38e3838e38e38ULL, },
+ { 0xddddddddddddddddULL, 0xddddddddddddddddULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0xed097b42b425ed0aULL, 0x25ed097bed097b42ULL, },
+ { 0x12f684bd4bda12f6ULL, 0xda12f68512f684bdULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 32 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x2222222322222223ULL, 0x2222222322222223ULL, },
+ { 0xddddddddddddddddULL, 0xddddddddddddddddULL, },
+ { 0x147ae148147ae148ULL, 0x147ae148147ae148ULL, },
+ { 0xeb851eb8eb851eb8ULL, 0xeb851eb8eb851eb8ULL, },
+ { 0x0b60b60c2d82d82eULL, 0xe93e93e90b60b60cULL, },
+ { 0xf49f49f5d27d27d2ULL, 0x16c16c17f49f49f5ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 40 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xdddddddedddddddeULL, 0xdddddddedddddddeULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0xeb851eb8eb851eb8ULL, 0xeb851eb8eb851eb8ULL, },
+ { 0x147ae148147ae148ULL, 0x147ae148147ae148ULL, },
+ { 0xf49f49f4d27d27d3ULL, 0x16c16c16f49f49f4ULL, },
+ { 0x0b60b60b2d82d82dULL, 0xe93e93e90b60b60bULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, }, /* 48 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x12f684be4bda12f7ULL, 0xda12f68512f684beULL, },
+ { 0xed097b42b425ed0aULL, 0x25ed097bed097b42ULL, },
+ { 0x0b60b60c2d82d82eULL, 0xe93e93e90b60b60cULL, },
+ { 0xf49f49f4d27d27d3ULL, 0x16c16c16f49f49f4ULL, },
+ { 0x06522c3f6522c3f4ULL, 0x1948b0fc06522c3fULL, },
+ { 0xf9add3c19add3c0dULL, 0xe6b74f04f9add3c1ULL, },
+ { 0x00000000ffffffffULL, 0x0000000000000000ULL, }, /* 56 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xed097b43b425ed09ULL, 0x25ed097ced097b43ULL, },
+ { 0x12f684bd4bda12f6ULL, 0xda12f68512f684bdULL, },
+ { 0xf49f49f5d27d27d2ULL, 0x16c16c17f49f49f5ULL, },
+ { 0x0b60b60b2d82d82dULL, 0xe93e93e90b60b60bULL, },
+ { 0xf9add3c19add3c0dULL, 0xe6b74f04f9add3c1ULL, },
+ { 0x06522c3f6522c3f2ULL, 0x1948b0fd06522c3fULL, },
+ { 0x6fb7e8890cbdc0d3ULL, 0x2c6b144600049a05ULL, }, /* 64 */
+ { 0x03fa514e1879c702ULL, 0x0b2c6ca9ffbf8ac7ULL, },
+ { 0x4e252087e9daefc0ULL, 0x1779189301015a35ULL, },
+ { 0x9713a7171db7f3a6ULL, 0xbccfb46a0107236fULL, },
+ { 0x03fa514e1879c702ULL, 0x0b2c6ca9ffbf8ac7ULL, },
+ { 0x002442012f047612ULL, 0x02cf8c140386e68fULL, },
+ { 0x02c84b88d575d121ULL, 0x05e79a8bf1eb1c52ULL, },
+ { 0xfc439edd3916c1e4ULL, 0xef19389cf19a0fdeULL, },
+ { 0x4e252087e9daefc0ULL, 0x1779189301015a35ULL, }, /* 72 */
+ { 0x02c84b88d575d121ULL, 0x05e79a8bf1eb1c52ULL, },
+ { 0x36a93aff267d11c4ULL, 0x0c6788643838c14cULL, },
+ { 0xb69baa3acc590fcdULL, 0xdc7e6df7397c58daULL, },
+ { 0x9713a7171db7f3a6ULL, 0xbccfb46a0107236fULL, },
+ { 0xfc439edd3916c1e4ULL, 0xef19389cf19a0fdeULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MULR_Q_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MULR_Q_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulv_b.c b/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulv_b.c
new file mode 100644
index 0000000000..6beeda906d
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulv_b.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction MULV.B
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "MULV.B";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5656565656565656ULL, 0x5656565656565656ULL, },
+ { 0xababababababababULL, 0xababababababababULL, },
+ { 0x3434343434343434ULL, 0x3434343434343434ULL, },
+ { 0xcdcdcdcdcdcdcdcdULL, 0xcdcdcdcdcdcdcdcdULL, },
+ { 0x1d72c81d72c81d72ULL, 0xc81d72c81d72c81dULL, },
+ { 0xe48f39e48f39e48fULL, 0x39e48f39e48f39e4ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5656565656565656ULL, 0x5656565656565656ULL, }, /* 16 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xe4e4e4e4e4e4e4e4ULL, 0xe4e4e4e4e4e4e4e4ULL, },
+ { 0x7272727272727272ULL, 0x7272727272727272ULL, },
+ { 0x7878787878787878ULL, 0x7878787878787878ULL, },
+ { 0xdedededededededeULL, 0xdedededededededeULL, },
+ { 0xbe4c30be4c30be4cULL, 0x30be4c30be4c30beULL, },
+ { 0x980a26980a26980aULL, 0x26980a26980a2698ULL, },
+ { 0xababababababababULL, 0xababababababababULL, }, /* 24 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7272727272727272ULL, 0x7272727272727272ULL, },
+ { 0x3939393939393939ULL, 0x3939393939393939ULL, },
+ { 0xbcbcbcbcbcbcbcbcULL, 0xbcbcbcbcbcbcbcbcULL, },
+ { 0xefefefefefefefefULL, 0xefefefefefefefefULL, },
+ { 0x5f26985f26985f26ULL, 0x985f26985f26985fULL, },
+ { 0x4c85134c85134c85ULL, 0x134c85134c85134cULL, },
+ { 0x3434343434343434ULL, 0x3434343434343434ULL, }, /* 32 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7878787878787878ULL, 0x7878787878787878ULL, },
+ { 0xbcbcbcbcbcbcbcbcULL, 0xbcbcbcbcbcbcbcbcULL, },
+ { 0x9090909090909090ULL, 0x9090909090909090ULL, },
+ { 0xa4a4a4a4a4a4a4a4ULL, 0xa4a4a4a4a4a4a4a4ULL, },
+ { 0xe428a0e428a0e428ULL, 0xa0e428a0e428a0e4ULL, },
+ { 0x500c94500c94500cULL, 0x94500c94500c9450ULL, },
+ { 0xcdcdcdcdcdcdcdcdULL, 0xcdcdcdcdcdcdcdcdULL, }, /* 40 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xdedededededededeULL, 0xdedededededededeULL, },
+ { 0xefefefefefefefefULL, 0xefefefefefefefefULL, },
+ { 0xa4a4a4a4a4a4a4a4ULL, 0xa4a4a4a4a4a4a4a4ULL, },
+ { 0x2929292929292929ULL, 0x2929292929292929ULL, },
+ { 0x394a28394a28394aULL, 0x28394a28394a2839ULL, },
+ { 0x9483a59483a59483ULL, 0xa59483a59483a594ULL, },
+ { 0x1d72c81d72c81d72ULL, 0xc81d72c81d72c81dULL, }, /* 48 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xbe4c30be4c30be4cULL, 0x30be4c30be4c30beULL, },
+ { 0x5f26985f26985f26ULL, 0x985f26985f26985fULL, },
+ { 0xe428a0e428a0e428ULL, 0xa0e428a0e428a0e4ULL, },
+ { 0x394a28394a28394aULL, 0x28394a28394a2839ULL, },
+ { 0x49c44049c44049c4ULL, 0x4049c44049c44049ULL, },
+ { 0xd4ae88d4ae88d4aeULL, 0x88d4ae88d4ae88d4ULL, },
+ { 0xe48f39e48f39e48fULL, 0x39e48f39e48f39e4ULL, }, /* 56 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x980a26980a26980aULL, 0x26980a26980a2698ULL, },
+ { 0x4c85134c85134c85ULL, 0x134c85134c85134cULL, },
+ { 0x500c94500c94500cULL, 0x94500c94500c9450ULL, },
+ { 0x9483a59483a59483ULL, 0xa59483a59483a594ULL, },
+ { 0xd4ae88d4ae88d4aeULL, 0x88d4ae88d4ae88d4ULL, },
+ { 0x10e1b110e1b110e1ULL, 0xb110e1b110e1b110ULL, },
+ { 0x40e4a49040843900ULL, 0xf971798404190090ULL, }, /* 64 */
+ { 0x58ac00e408461300ULL, 0x4661098cd64560d0ULL, },
+ { 0x60445478e83e2700ULL, 0x6de882a2aaa970f0ULL, },
+ { 0x80b6c45cb0c20a80ULL, 0x4ff7d850aeb66080ULL, },
+ { 0x58ac00e408461300ULL, 0x4661098cd64560d0ULL, },
+ { 0x190400492969b140ULL, 0x445199a4b9814410ULL, },
+ { 0xa4cc00bea5dd0d00ULL, 0xbe68a2e60795dab0ULL, },
+ { 0xd0a200c74623ae70ULL, 0xea8758f0dd3e6480ULL, },
+ { 0x60445478e83e2700ULL, 0x6de882a2aaa970f0ULL, }, /* 72 */
+ { 0xa4cc00bea5dd0d00ULL, 0xbe68a2e60795dab0ULL, },
+ { 0x90a444e4b1617900ULL, 0xf140240139395990ULL, },
+ { 0x40c6f422ee9fb600ULL, 0x7b583028e316aa80ULL, },
+ { 0x80b6c45cb0c20a80ULL, 0x4ff7d850aeb66080ULL, },
+ { 0xd0a200c74623ae70ULL, 0xea8758f0dd3e6480ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MULV_B(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MULV_B(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulv_d.c b/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulv_d.c
new file mode 100644
index 0000000000..3205d4b378
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulv_d.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction MULV.D
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "MULV.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555556ULL, 0x5555555555555556ULL, },
+ { 0xaaaaaaaaaaaaaaabULL, 0xaaaaaaaaaaaaaaabULL, },
+ { 0x3333333333333334ULL, 0x3333333333333334ULL, },
+ { 0xcccccccccccccccdULL, 0xcccccccccccccccdULL, },
+ { 0x1c71c71c71c71c72ULL, 0xc71c71c71c71c71dULL, },
+ { 0xe38e38e38e38e38fULL, 0x38e38e38e38e38e4ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555556ULL, 0x5555555555555556ULL, }, /* 16 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x38e38e38e38e38e4ULL, 0x38e38e38e38e38e4ULL, },
+ { 0x1c71c71c71c71c72ULL, 0x1c71c71c71c71c72ULL, },
+ { 0x7777777777777778ULL, 0x7777777777777778ULL, },
+ { 0xdddddddddddddddeULL, 0xdddddddddddddddeULL, },
+ { 0x12f684bda12f684cULL, 0x2f684bda12f684beULL, },
+ { 0x425ed097b425ed0aULL, 0x25ed097b425ed098ULL, },
+ { 0xaaaaaaaaaaaaaaabULL, 0xaaaaaaaaaaaaaaabULL, }, /* 24 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x1c71c71c71c71c72ULL, 0x1c71c71c71c71c72ULL, },
+ { 0x8e38e38e38e38e39ULL, 0x8e38e38e38e38e39ULL, },
+ { 0xbbbbbbbbbbbbbbbcULL, 0xbbbbbbbbbbbbbbbcULL, },
+ { 0xeeeeeeeeeeeeeeefULL, 0xeeeeeeeeeeeeeeefULL, },
+ { 0x097b425ed097b426ULL, 0x97b425ed097b425fULL, },
+ { 0xa12f684bda12f685ULL, 0x12f684bda12f684cULL, },
+ { 0x3333333333333334ULL, 0x3333333333333334ULL, }, /* 32 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7777777777777778ULL, 0x7777777777777778ULL, },
+ { 0xbbbbbbbbbbbbbbbcULL, 0xbbbbbbbbbbbbbbbcULL, },
+ { 0xf5c28f5c28f5c290ULL, 0xf5c28f5c28f5c290ULL, },
+ { 0x3d70a3d70a3d70a4ULL, 0x3d70a3d70a3d70a4ULL, },
+ { 0x7d27d27d27d27d28ULL, 0x38e38e38e38e38e4ULL, },
+ { 0xb60b60b60b60b60cULL, 0xfa4fa4fa4fa4fa50ULL, },
+ { 0xcccccccccccccccdULL, 0xcccccccccccccccdULL, }, /* 40 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xdddddddddddddddeULL, 0xdddddddddddddddeULL, },
+ { 0xeeeeeeeeeeeeeeefULL, 0xeeeeeeeeeeeeeeefULL, },
+ { 0x3d70a3d70a3d70a4ULL, 0x3d70a3d70a3d70a4ULL, },
+ { 0x8f5c28f5c28f5c29ULL, 0x8f5c28f5c28f5c29ULL, },
+ { 0x9f49f49f49f49f4aULL, 0x8e38e38e38e38e39ULL, },
+ { 0x2d82d82d82d82d83ULL, 0x3e93e93e93e93e94ULL, },
+ { 0x1c71c71c71c71c72ULL, 0xc71c71c71c71c71dULL, }, /* 48 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x12f684bda12f684cULL, 0x2f684bda12f684beULL, },
+ { 0x097b425ed097b426ULL, 0x97b425ed097b425fULL, },
+ { 0x7d27d27d27d27d28ULL, 0x38e38e38e38e38e4ULL, },
+ { 0x9f49f49f49f49f4aULL, 0x8e38e38e38e38e39ULL, },
+ { 0xb0fcd6e9e06522c4ULL, 0x522c3f35ba781949ULL, },
+ { 0x6b74f0329161f9aeULL, 0x74f0329161f9add4ULL, },
+ { 0xe38e38e38e38e38fULL, 0x38e38e38e38e38e4ULL, }, /* 56 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x425ed097b425ed0aULL, 0x25ed097b425ed098ULL, },
+ { 0xa12f684bda12f685ULL, 0x12f684bda12f684cULL, },
+ { 0xb60b60b60b60b60cULL, 0xfa4fa4fa4fa4fa50ULL, },
+ { 0x2d82d82d82d82d83ULL, 0x3e93e93e93e93e94ULL, },
+ { 0x6b74f0329161f9aeULL, 0x74f0329161f9add4ULL, },
+ { 0x781948b0fcd6e9e1ULL, 0xc3f35ba781948b10ULL, },
+ { 0xad45be6961639000ULL, 0x3297fdea74988090ULL, }, /* 64 */
+ { 0xefa7a5a0e7176a00ULL, 0xb8110a1f6f1923d0ULL, },
+ { 0x08c6139fc4346000ULL, 0xab209f86581f7cf0ULL, },
+ { 0xfbe1883aee787980ULL, 0x821d25438dd09f80ULL, },
+ { 0xefa7a5a0e7176a00ULL, 0xb8110a1f6f1923d0ULL, },
+ { 0x37ae2b38fded7040ULL, 0x682476774aee6810ULL, },
+ { 0x6acb3d68be6cdc00ULL, 0xafdad2311444e7b0ULL, },
+ { 0xedbf72842143b470ULL, 0x7f8223caefce5580ULL, },
+ { 0x08c6139fc4346000ULL, 0xab209f86581f7cf0ULL, }, /* 72 */
+ { 0x6acb3d68be6cdc00ULL, 0xafdad2311444e7b0ULL, },
+ { 0x8624e5e1e5044000ULL, 0xd98178a63216c990ULL, },
+ { 0x76a5ab8089e38100ULL, 0xa1019a60d4dad480ULL, },
+ { 0xfbe1883aee787980ULL, 0x821d25438dd09f80ULL, },
+ { 0xedbf72842143b470ULL, 0x7f8223caefce5580ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MULV_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MULV_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulv_h.c b/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulv_h.c
new file mode 100644
index 0000000000..e7bd985ae1
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulv_h.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction MULV.H
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "MULV.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5556555655565556ULL, 0x5556555655565556ULL, },
+ { 0xaaabaaabaaabaaabULL, 0xaaabaaabaaabaaabULL, },
+ { 0x3334333433343334ULL, 0x3334333433343334ULL, },
+ { 0xcccdcccdcccdcccdULL, 0xcccdcccdcccdcccdULL, },
+ { 0x1c72c71d71c81c72ULL, 0xc71d71c81c72c71dULL, },
+ { 0xe38f38e48e39e38fULL, 0x38e48e39e38f38e4ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5556555655565556ULL, 0x5556555655565556ULL, }, /* 16 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x38e438e438e438e4ULL, 0x38e438e438e438e4ULL, },
+ { 0x1c721c721c721c72ULL, 0x1c721c721c721c72ULL, },
+ { 0x7778777877787778ULL, 0x7778777877787778ULL, },
+ { 0xdddedddedddedddeULL, 0xdddedddedddedddeULL, },
+ { 0x684c84bea130684cULL, 0x84bea130684c84beULL, },
+ { 0xed0ad098b426ed0aULL, 0xd098b426ed0ad098ULL, },
+ { 0xaaabaaabaaabaaabULL, 0xaaabaaabaaabaaabULL, }, /* 24 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x1c721c721c721c72ULL, 0x1c721c721c721c72ULL, },
+ { 0x8e398e398e398e39ULL, 0x8e398e398e398e39ULL, },
+ { 0xbbbcbbbcbbbcbbbcULL, 0xbbbcbbbcbbbcbbbcULL, },
+ { 0xeeefeeefeeefeeefULL, 0xeeefeeefeeefeeefULL, },
+ { 0xb426425fd098b426ULL, 0x425fd098b426425fULL, },
+ { 0xf685684cda13f685ULL, 0x684cda13f685684cULL, },
+ { 0x3334333433343334ULL, 0x3334333433343334ULL, }, /* 32 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7778777877787778ULL, 0x7778777877787778ULL, },
+ { 0xbbbcbbbcbbbcbbbcULL, 0xbbbcbbbcbbbcbbbcULL, },
+ { 0xc290c290c290c290ULL, 0xc290c290c290c290ULL, },
+ { 0x70a470a470a470a4ULL, 0x70a470a470a470a4ULL, },
+ { 0x7d2838e4f4a07d28ULL, 0x38e4f4a07d2838e4ULL, },
+ { 0xb60cfa503e94b60cULL, 0xfa503e94b60cfa50ULL, },
+ { 0xcccdcccdcccdcccdULL, 0xcccdcccdcccdcccdULL, }, /* 40 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xdddedddedddedddeULL, 0xdddedddedddedddeULL, },
+ { 0xeeefeeefeeefeeefULL, 0xeeefeeefeeefeeefULL, },
+ { 0x70a470a470a470a4ULL, 0x70a470a470a470a4ULL, },
+ { 0x5c295c295c295c29ULL, 0x5c295c295c295c29ULL, },
+ { 0x9f4a8e397d289f4aULL, 0x8e397d289f4a8e39ULL, },
+ { 0x2d833e944fa52d83ULL, 0x3e944fa52d833e94ULL, },
+ { 0x1c72c71d71c81c72ULL, 0xc71d71c81c72c71dULL, }, /* 48 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x684c84bea130684cULL, 0x84bea130684c84beULL, },
+ { 0xb426425fd098b426ULL, 0x425fd098b426425fULL, },
+ { 0x7d2838e4f4a07d28ULL, 0x38e4f4a07d2838e4ULL, },
+ { 0x9f4a8e397d289f4aULL, 0x8e397d289f4a8e39ULL, },
+ { 0x22c419492c4022c4ULL, 0x19492c4022c41949ULL, },
+ { 0xf9aeadd44588f9aeULL, 0xadd44588f9aeadd4ULL, },
+ { 0xe38f38e48e39e38fULL, 0x38e48e39e38f38e4ULL, }, /* 56 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xed0ad098b426ed0aULL, 0xd098b426ed0ad098ULL, },
+ { 0xf685684cda13f685ULL, 0x684cda13f685684cULL, },
+ { 0xb60cfa503e94b60cULL, 0xfa503e94b60cfa50ULL, },
+ { 0x2d833e944fa52d83ULL, 0x3e944fa52d833e94ULL, },
+ { 0xf9aeadd44588f9aeULL, 0xadd44588f9aeadd4ULL, },
+ { 0xe9e18b1048b1e9e1ULL, 0x8b1048b1e9e18b10ULL, },
+ { 0xcbe43290c5849000ULL, 0x837136844f198090ULL, }, /* 64 */
+ { 0x2cac40e4aa466a00ULL, 0xfe61d18cb74523d0ULL, },
+ { 0x2d44eb78793e6000ULL, 0x4fe806a2e7a97cf0ULL, },
+ { 0x78b6f35cb6c27980ULL, 0xb6f78750ceb69f80ULL, },
+ { 0x2cac40e4aa466a00ULL, 0xfe61d18cb74523d0ULL, },
+ { 0x21042649c2697040ULL, 0xaa51fea465816810ULL, },
+ { 0x28cc8bbef4dddc00ULL, 0xa1687ae6a695e7b0ULL, },
+ { 0xcfa29fc7d323b470ULL, 0xe587adf0113e5580ULL, },
+ { 0x2d44eb78793e6000ULL, 0x4fe806a2e7a97cf0ULL, }, /* 72 */
+ { 0x28cc8bbef4dddc00ULL, 0xa1687ae6a695e7b0ULL, },
+ { 0x0fa488e4d5614000ULL, 0x864072017939c990ULL, },
+ { 0x8fc62522929f8100ULL, 0x7a585f288416d480ULL, },
+ { 0x78b6f35cb6c27980ULL, 0xb6f78750ceb69f80ULL, },
+ { 0xcfa29fc7d323b470ULL, 0xe587adf0113e5580ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MULV_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MULV_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulv_w.c b/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulv_w.c
new file mode 100644
index 0000000000..9c318b3fbb
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-multiply/test_msa_mulv_w.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction MULV.W
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "MULV.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555655555556ULL, 0x5555555655555556ULL, },
+ { 0xaaaaaaabaaaaaaabULL, 0xaaaaaaabaaaaaaabULL, },
+ { 0x3333333433333334ULL, 0x3333333433333334ULL, },
+ { 0xcccccccdcccccccdULL, 0xcccccccdcccccccdULL, },
+ { 0x1c71c71d71c71c72ULL, 0xc71c71c81c71c71dULL, },
+ { 0xe38e38e48e38e38fULL, 0x38e38e39e38e38e4ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555655555556ULL, 0x5555555655555556ULL, }, /* 16 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xe38e38e4e38e38e4ULL, 0xe38e38e4e38e38e4ULL, },
+ { 0x71c71c7271c71c72ULL, 0x71c71c7271c71c72ULL, },
+ { 0x7777777877777778ULL, 0x7777777877777778ULL, },
+ { 0xdddddddedddddddeULL, 0xdddddddedddddddeULL, },
+ { 0x12f684bea12f684cULL, 0x84bda13012f684beULL, },
+ { 0x425ed098b425ed0aULL, 0xd097b426425ed098ULL, },
+ { 0xaaaaaaabaaaaaaabULL, 0xaaaaaaabaaaaaaabULL, }, /* 24 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x71c71c7271c71c72ULL, 0x71c71c7271c71c72ULL, },
+ { 0x38e38e3938e38e39ULL, 0x38e38e3938e38e39ULL, },
+ { 0xbbbbbbbcbbbbbbbcULL, 0xbbbbbbbcbbbbbbbcULL, },
+ { 0xeeeeeeefeeeeeeefULL, 0xeeeeeeefeeeeeeefULL, },
+ { 0x097b425fd097b426ULL, 0x425ed098097b425fULL, },
+ { 0xa12f684cda12f685ULL, 0x684bda13a12f684cULL, },
+ { 0x3333333433333334ULL, 0x3333333433333334ULL, }, /* 32 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7777777877777778ULL, 0x7777777877777778ULL, },
+ { 0xbbbbbbbcbbbbbbbcULL, 0xbbbbbbbcbbbbbbbcULL, },
+ { 0x28f5c29028f5c290ULL, 0x28f5c29028f5c290ULL, },
+ { 0x0a3d70a40a3d70a4ULL, 0x0a3d70a40a3d70a4ULL, },
+ { 0xe38e38e427d27d28ULL, 0x9f49f4a0e38e38e4ULL, },
+ { 0x4fa4fa500b60b60cULL, 0x93e93e944fa4fa50ULL, },
+ { 0xcccccccdcccccccdULL, 0xcccccccdcccccccdULL, }, /* 40 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xdddddddedddddddeULL, 0xdddddddedddddddeULL, },
+ { 0xeeeeeeefeeeeeeefULL, 0xeeeeeeefeeeeeeefULL, },
+ { 0x0a3d70a40a3d70a4ULL, 0x0a3d70a40a3d70a4ULL, },
+ { 0xc28f5c29c28f5c29ULL, 0xc28f5c29c28f5c29ULL, },
+ { 0x38e38e3949f49f4aULL, 0x27d27d2838e38e39ULL, },
+ { 0x93e93e9482d82d83ULL, 0xa4fa4fa593e93e94ULL, },
+ { 0x1c71c71d71c71c72ULL, 0xc71c71c81c71c71dULL, }, /* 48 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x12f684bea12f684cULL, 0x84bda13012f684beULL, },
+ { 0x097b425fd097b426ULL, 0x425ed098097b425fULL, },
+ { 0xe38e38e427d27d28ULL, 0x9f49f4a0e38e38e4ULL, },
+ { 0x38e38e3949f49f4aULL, 0x27d27d2838e38e39ULL, },
+ { 0xba781949e06522c4ULL, 0x06522c40ba781949ULL, },
+ { 0x61f9add49161f9aeULL, 0xc0ca458861f9add4ULL, },
+ { 0xe38e38e48e38e38fULL, 0x38e38e39e38e38e4ULL, }, /* 56 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x425ed098b425ed0aULL, 0xd097b426425ed098ULL, },
+ { 0xa12f684cda12f685ULL, 0x684bda13a12f684cULL, },
+ { 0x4fa4fa500b60b60cULL, 0x93e93e944fa4fa50ULL, },
+ { 0x93e93e9482d82d83ULL, 0xa4fa4fa593e93e94ULL, },
+ { 0x61f9add49161f9aeULL, 0xc0ca458861f9add4ULL, },
+ { 0x81948b10fcd6e9e1ULL, 0x781948b181948b10ULL, },
+ { 0xb103329061639000ULL, 0x3a25368474988090ULL, }, /* 64 */
+ { 0x10bf40e4e7176a00ULL, 0x8176d18c6f1923d0ULL, },
+ { 0x7393eb78c4346000ULL, 0xb7bf06a2581f7cf0ULL, },
+ { 0xb0f0f35cee787980ULL, 0xd67987508dd09f80ULL, },
+ { 0x10bf40e4e7176a00ULL, 0x8176d18c6f1923d0ULL, },
+ { 0xb4f42649fded7040ULL, 0x3ceafea44aee6810ULL, },
+ { 0xf73d8bbebe6cdc00ULL, 0x53697ae61444e7b0ULL, },
+ { 0x7abb9fc72143b470ULL, 0x11e5adf0efce5580ULL, },
+ { 0x7393eb78c4346000ULL, 0xb7bf06a2581f7cf0ULL, }, /* 72 */
+ { 0xf73d8bbebe6cdc00ULL, 0x53697ae61444e7b0ULL, },
+ { 0xb6b388e4e5044000ULL, 0x1aff72013216c990ULL, },
+ { 0xe8bf252289e38100ULL, 0x91ae5f28d4dad480ULL, },
+ { 0xb0f0f35cee787980ULL, 0xd67987508dd09f80ULL, },
+ { 0x7abb9fc72143b470ULL, 0x11e5adf0efce5580ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MULV_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MULV_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_s_b.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_s_b.c
new file mode 100644
index 0000000000..04e6159fc7
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_s_b.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBS_S.B
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBS_S.B";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5656565656565656ULL, 0x5656565656565656ULL, },
+ { 0xababababababababULL, 0xababababababababULL, },
+ { 0x3434343434343434ULL, 0x3434343434343434ULL, },
+ { 0xcdcdcdcdcdcdcdcdULL, 0xcdcdcdcdcdcdcdcdULL, },
+ { 0x1d72c81d72c81d72ULL, 0xc81d72c81d72c81dULL, },
+ { 0xe48f39e48f39e48fULL, 0x39e48f39e48f39e4ULL, },
+ { 0xababababababababULL, 0xababababababababULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, },
+ { 0xdedededededededeULL, 0xdedededededededeULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, },
+ { 0xc71c80c71c80c71cULL, 0x80c71c80c71c80c7ULL, },
+ { 0x8e80e38e80e38e80ULL, 0xe38e80e38e80e38eULL, },
+ { 0x5656565656565656ULL, 0x5656565656565656ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x7f7f7f7f7f7f7f7fULL, 0x7f7f7f7f7f7f7f7fULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7f7f7f7f7f7f7f7fULL, 0x7f7f7f7f7f7f7f7fULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x727f1d727f1d727fULL, 0x1d727f1d727f1d72ULL, },
+ { 0x39e47f39e47f39e4ULL, 0x7f39e47f39e47f39ULL, },
+ { 0xcdcdcdcdcdcdcdcdULL, 0xcdcdcdcdcdcdcdcdULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xe93e94e93e94e93eULL, 0x94e93e94e93e94e9ULL, },
+ { 0xb08005b08005b080ULL, 0x05b08005b08005b0ULL, },
+ { 0x3434343434343434ULL, 0x3434343434343434ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x7f7f7f7f7f7f7f7fULL, 0x7f7f7f7f7f7f7f7fULL, },
+ { 0xdedededededededeULL, 0xdedededededededeULL, },
+ { 0x6767676767676767ULL, 0x6767676767676767ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x507ffb507ffb507fULL, 0xfb507ffb507ffb50ULL, },
+ { 0x17c26c17c26c17c2ULL, 0x6c17c26c17c26c17ULL, },
+ { 0xe48f39e48f39e48fULL, 0x39e48f39e48f39e4ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x39e47f39e47f39e4ULL, 0x7f39e47f39e47f39ULL, },
+ { 0x8e80e38e80e38e80ULL, 0xe38e80e38e80e38eULL, },
+ { 0x17c26c17c26c17c2ULL, 0x6c17c26c17c26c17ULL, },
+ { 0xb08005b08005b080ULL, 0x05b08005b08005b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc78071c78071c780ULL, 0x71c78071c78071c7ULL, },
+ { 0x1d72c81d72c81d72ULL, 0xc81d72c81d72c81dULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x727f1d727f1d727fULL, 0x1d727f1d727f1d72ULL, },
+ { 0xc71c80c71c80c71cULL, 0x80c71c80c71c80c7ULL, },
+ { 0x507ffb507ffb507fULL, 0xfb507ffb507ffb50ULL, },
+ { 0xe93e94e93e94e93eULL, 0x94e93e94e93e94e9ULL, },
+ { 0x397f8f397f8f397fULL, 0x8f397f8f397f8f39ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 64 */
+ { 0x8d7fe680db7f7f38ULL, 0x39705044e93c8010ULL, },
+ { 0xdc1038226f7f7f7fULL, 0x247f455f53508bf8ULL, },
+ { 0x801bd080ca3173f2ULL, 0x7f767f7f5539ce6cULL, },
+ { 0x73801a7f258080c8ULL, 0xc790b0bc17c47ff0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4f80527f7fc43c7fULL, 0xeb1ff51b6a142de8ULL, },
+ { 0x8b80ea16ef80e5baULL, 0x7f0633426cfd705cULL, },
+ { 0x24f0c8de91808080ULL, 0xdc80bba1adb07508ULL, }, /* 72 */
+ { 0xb17fae80803cc480ULL, 0x15e10be596ecd318ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x800b9880809ea980ULL, 0x7fe73e2702e94374ULL, },
+ { 0x7fe5307f36cf8d0eULL, 0x808a8080abc73294ULL, },
+ { 0x757f16ea117f1b46ULL, 0x80facdbe940390a4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBS_S_B(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBS_S_B(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_s_d.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_s_d.c
new file mode 100644
index 0000000000..195137f41f
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_s_d.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBS_S.D
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBS_S.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555556ULL, 0x5555555555555556ULL, },
+ { 0xaaaaaaaaaaaaaaabULL, 0xaaaaaaaaaaaaaaabULL, },
+ { 0x3333333333333334ULL, 0x3333333333333334ULL, },
+ { 0xcccccccccccccccdULL, 0xcccccccccccccccdULL, },
+ { 0x1c71c71c71c71c72ULL, 0xc71c71c71c71c71dULL, },
+ { 0xe38e38e38e38e38fULL, 0x38e38e38e38e38e4ULL, },
+ { 0xaaaaaaaaaaaaaaabULL, 0xaaaaaaaaaaaaaaabULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8000000000000000ULL, 0x8000000000000000ULL, },
+ { 0xdddddddddddddddeULL, 0xdddddddddddddddeULL, },
+ { 0x8000000000000000ULL, 0x8000000000000000ULL, },
+ { 0xc71c71c71c71c71cULL, 0x8000000000000000ULL, },
+ { 0x8e38e38e38e38e39ULL, 0xe38e38e38e38e38eULL, },
+ { 0x5555555555555556ULL, 0x5555555555555556ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x71c71c71c71c71c7ULL, 0x1c71c71c71c71c72ULL, },
+ { 0x38e38e38e38e38e4ULL, 0x7fffffffffffffffULL, },
+ { 0xcccccccccccccccdULL, 0xcccccccccccccccdULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x8000000000000000ULL, 0x8000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xe93e93e93e93e93eULL, 0x93e93e93e93e93e9ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x3333333333333334ULL, 0x3333333333333334ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL, },
+ { 0xdddddddddddddddeULL, 0xdddddddddddddddeULL, },
+ { 0x6666666666666667ULL, 0x6666666666666667ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4fa4fa4fa4fa4fa5ULL, 0xfa4fa4fa4fa4fa50ULL, },
+ { 0x16c16c16c16c16c2ULL, 0x6c16c16c16c16c17ULL, },
+ { 0xe38e38e38e38e38fULL, 0x38e38e38e38e38e4ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x38e38e38e38e38e4ULL, 0x7fffffffffffffffULL, },
+ { 0x8e38e38e38e38e39ULL, 0xe38e38e38e38e38eULL, },
+ { 0x16c16c16c16c16c2ULL, 0x6c16c16c16c16c17ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc71c71c71c71c71dULL, 0x71c71c71c71c71c7ULL, },
+ { 0x1c71c71c71c71c72ULL, 0xc71c71c71c71c71dULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x71c71c71c71c71c7ULL, 0x1c71c71c71c71c72ULL, },
+ { 0xc71c71c71c71c71cULL, 0x8000000000000000ULL, },
+ { 0x4fa4fa4fa4fa4fa5ULL, 0xfa4fa4fa4fa4fa50ULL, },
+ { 0xe93e93e93e93e93eULL, 0x93e93e93e93e93e9ULL, },
+ { 0x38e38e38e38e38e3ULL, 0x8e38e38e38e38e39ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 64 */
+ { 0x8cace668dace8e38ULL, 0x386f5044e93c5d10ULL, },
+ { 0xdc1038216e92c9c0ULL, 0x238e445f53508af8ULL, },
+ { 0x8000000000000000ULL, 0x7fffffffffffffffULL, },
+ { 0x73531997253171c8ULL, 0xc790afbb16c3a2f0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4f6351b893c43b88ULL, 0xeb1ef41a6a142de8ULL, },
+ { 0x8b6eea15ef61e4baULL, 0x7fffffffffffffffULL, },
+ { 0x23efc7de916d3640ULL, 0xdc71bba0acaf7508ULL, }, /* 72 */
+ { 0xb09cae476c3bc478ULL, 0x14e10be595ebd218ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8000000000000000ULL, 0x7fffffffffffffffULL, },
+ { 0x7fffffffffffffffULL, 0x8000000000000000ULL, },
+ { 0x749115ea109e1b46ULL, 0x8000000000000000ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBS_S_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBS_S_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_s_h.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_s_h.c
new file mode 100644
index 0000000000..c57238d31a
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_s_h.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBS_S.H
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBS_S.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5556555655565556ULL, 0x5556555655565556ULL, },
+ { 0xaaabaaabaaabaaabULL, 0xaaabaaabaaabaaabULL, },
+ { 0x3334333433343334ULL, 0x3334333433343334ULL, },
+ { 0xcccdcccdcccdcccdULL, 0xcccdcccdcccdcccdULL, },
+ { 0x1c72c71d71c81c72ULL, 0xc71d71c81c72c71dULL, },
+ { 0xe38f38e48e39e38fULL, 0x38e48e39e38f38e4ULL, },
+ { 0xaaabaaabaaabaaabULL, 0xaaabaaabaaabaaabULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8000800080008000ULL, 0x8000800080008000ULL, },
+ { 0xdddedddedddedddeULL, 0xdddedddedddedddeULL, },
+ { 0x8000800080008000ULL, 0x8000800080008000ULL, },
+ { 0xc71c80001c72c71cULL, 0x80001c72c71c8000ULL, },
+ { 0x8e39e38e80008e39ULL, 0xe38e80008e39e38eULL, },
+ { 0x5556555655565556ULL, 0x5556555655565556ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x7fff7fff7fff7fffULL, 0x7fff7fff7fff7fffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7fff7fff7fff7fffULL, 0x7fff7fff7fff7fffULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x71c71c727fff71c7ULL, 0x1c727fff71c71c72ULL, },
+ { 0x38e47fffe38e38e4ULL, 0x7fffe38e38e47fffULL, },
+ { 0xcccdcccdcccdcccdULL, 0xcccdcccdcccdcccdULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x8000800080008000ULL, 0x8000800080008000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xe93e93e93e94e93eULL, 0x93e93e94e93e93e9ULL, },
+ { 0xb05b05b08000b05bULL, 0x05b08000b05b05b0ULL, },
+ { 0x3334333433343334ULL, 0x3334333433343334ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x7fff7fff7fff7fffULL, 0x7fff7fff7fff7fffULL, },
+ { 0xdddedddedddedddeULL, 0xdddedddedddedddeULL, },
+ { 0x6667666766676667ULL, 0x6667666766676667ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4fa5fa507fff4fa5ULL, 0xfa507fff4fa5fa50ULL, },
+ { 0x16c26c17c16c16c2ULL, 0x6c17c16c16c26c17ULL, },
+ { 0xe38f38e48e39e38fULL, 0x38e48e39e38f38e4ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x38e47fffe38e38e4ULL, 0x7fffe38e38e47fffULL, },
+ { 0x8e39e38e80008e39ULL, 0xe38e80008e39e38eULL, },
+ { 0x16c26c17c16c16c2ULL, 0x6c17c16c16c26c17ULL, },
+ { 0xb05b05b08000b05bULL, 0x05b08000b05b05b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc71d71c78000c71dULL, 0x71c78000c71d71c7ULL, },
+ { 0x1c72c71d71c81c72ULL, 0xc71d71c81c72c71dULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x71c71c727fff71c7ULL, 0x1c727fff71c71c72ULL, },
+ { 0xc71c80001c72c71cULL, 0x80001c72c71c8000ULL, },
+ { 0x4fa5fa507fff4fa5ULL, 0xfa507fff4fa5fa50ULL, },
+ { 0xe93e93e93e94e93eULL, 0x93e93e94e93e93e9ULL, },
+ { 0x38e38e397fff38e3ULL, 0x8e397fff38e38e39ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 64 */
+ { 0x8cace669dacf7fffULL, 0x38705044e93c8000ULL, },
+ { 0xdc1038226e937fffULL, 0x238f445f53508af8ULL, },
+ { 0x8000d07fca3172f2ULL, 0x7fff7fff5539cd6cULL, },
+ { 0x7354199725318000ULL, 0xc790afbc16c47fffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4f6451b97fff3b88ULL, 0xeb1ff41b6a142de8ULL, },
+ { 0x8b6fea16ef62e4baULL, 0x7fff32426bfd705cULL, },
+ { 0x23f0c7de916d8000ULL, 0xdc71bba1acb07508ULL, }, /* 72 */
+ { 0xb09cae478000c478ULL, 0x14e10be595ecd218ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8000985d8000a932ULL, 0x7fff3e2701e94274ULL, },
+ { 0x7fff2f8135cf8d0eULL, 0x80008000aac73294ULL, },
+ { 0x749115ea109e1b46ULL, 0x8000cdbe94038fa4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBS_S_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBS_S_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_s_w.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_s_w.c
new file mode 100644
index 0000000000..1cded65a7e
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_s_w.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBS_S.W
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBS_S.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555655555556ULL, 0x5555555655555556ULL, },
+ { 0xaaaaaaabaaaaaaabULL, 0xaaaaaaabaaaaaaabULL, },
+ { 0x3333333433333334ULL, 0x3333333433333334ULL, },
+ { 0xcccccccdcccccccdULL, 0xcccccccdcccccccdULL, },
+ { 0x1c71c71d71c71c72ULL, 0xc71c71c81c71c71dULL, },
+ { 0xe38e38e48e38e38fULL, 0x38e38e39e38e38e4ULL, },
+ { 0xaaaaaaabaaaaaaabULL, 0xaaaaaaabaaaaaaabULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8000000080000000ULL, 0x8000000080000000ULL, },
+ { 0xdddddddedddddddeULL, 0xdddddddedddddddeULL, },
+ { 0x8000000080000000ULL, 0x8000000080000000ULL, },
+ { 0xc71c71c71c71c71cULL, 0x80000000c71c71c7ULL, },
+ { 0x8e38e38e80000000ULL, 0xe38e38e38e38e38eULL, },
+ { 0x5555555655555556ULL, 0x5555555655555556ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x7fffffff7fffffffULL, 0x7fffffff7fffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7fffffff7fffffffULL, 0x7fffffff7fffffffULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x71c71c727fffffffULL, 0x1c71c71d71c71c72ULL, },
+ { 0x38e38e39e38e38e4ULL, 0x7fffffff38e38e39ULL, },
+ { 0xcccccccdcccccccdULL, 0xcccccccdcccccccdULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x8000000080000000ULL, 0x8000000080000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xe93e93e93e93e93eULL, 0x93e93e94e93e93e9ULL, },
+ { 0xb05b05b080000000ULL, 0x05b05b05b05b05b0ULL, },
+ { 0x3333333433333334ULL, 0x3333333433333334ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x7fffffff7fffffffULL, 0x7fffffff7fffffffULL, },
+ { 0xdddddddedddddddeULL, 0xdddddddedddddddeULL, },
+ { 0x6666666766666667ULL, 0x6666666766666667ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4fa4fa507fffffffULL, 0xfa4fa4fb4fa4fa50ULL, },
+ { 0x16c16c17c16c16c2ULL, 0x6c16c16c16c16c17ULL, },
+ { 0xe38e38e48e38e38fULL, 0x38e38e39e38e38e4ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x38e38e39e38e38e4ULL, 0x7fffffff38e38e39ULL, },
+ { 0x8e38e38e80000000ULL, 0xe38e38e38e38e38eULL, },
+ { 0x16c16c17c16c16c2ULL, 0x6c16c16c16c16c17ULL, },
+ { 0xb05b05b080000000ULL, 0x05b05b05b05b05b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc71c71c780000000ULL, 0x71c71c71c71c71c7ULL, },
+ { 0x1c71c71d71c71c72ULL, 0xc71c71c81c71c71dULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x71c71c727fffffffULL, 0x1c71c71d71c71c72ULL, },
+ { 0xc71c71c71c71c71cULL, 0x80000000c71c71c7ULL, },
+ { 0x4fa4fa507fffffffULL, 0xfa4fa4fb4fa4fa50ULL, },
+ { 0xe93e93e93e93e93eULL, 0x93e93e94e93e93e9ULL, },
+ { 0x38e38e397fffffffULL, 0x8e38e38f38e38e39ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 64 */
+ { 0x8cace669dace8e38ULL, 0x386f5044e93c5d10ULL, },
+ { 0xdc1038226e92c9c0ULL, 0x238e445f53508af8ULL, },
+ { 0x80000000ca3072f2ULL, 0x7fffffff5538cd6cULL, },
+ { 0x73531997253171c8ULL, 0xc790afbc16c3a2f0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4f6351b97fffffffULL, 0xeb1ef41b6a142de8ULL, },
+ { 0x8b6eea16ef61e4baULL, 0x7fffffff6bfc705cULL, },
+ { 0x23efc7de916d3640ULL, 0xdc71bba1acaf7508ULL, }, /* 72 */
+ { 0xb09cae4780000000ULL, 0x14e10be595ebd218ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8000000080000000ULL, 0x7fffffff01e84274ULL, },
+ { 0x7fffffff35cf8d0eULL, 0x80000000aac73294ULL, },
+ { 0x749115ea109e1b46ULL, 0x8000000094038fa4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBS_S_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBS_S_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_u_b.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_u_b.c
new file mode 100644
index 0000000000..cb38f033a6
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_u_b.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBS_U.B
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBS_U.B";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0x001c72001c72001cULL, 0x72001c72001c7200ULL, },
+ { 0x8e39008e39008e39ULL, 0x008e39008e39008eULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x00001d00001d0000ULL, 0x1d00001d00001d00ULL, },
+ { 0x3900003900003900ULL, 0x0039000039000039ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0x003e94003e94003eULL, 0x94003e94003e9400ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x1700001700001700ULL, 0x0017000017000017ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x3900003900003900ULL, 0x0039000039000039ULL, },
+ { 0x8e39008e39008e39ULL, 0x008e39008e39008eULL, },
+ { 0x1700001700001700ULL, 0x0017000017000017ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc71d00c71d00c71dULL, 0x00c71d00c71d00c7ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x00001d00001d0000ULL, 0x1d00001d00001d00ULL, },
+ { 0x001c72001c72001cULL, 0x72001c72001c7200ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x003e94003e94003eULL, 0x94003e94003e9400ULL, },
+ { 0x00008f00008f0000ULL, 0x8f00008f00008f00ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 64 */
+ { 0x0000e66900000038ULL, 0x39000044e93c5e00ULL, },
+ { 0x0010382200000000ULL, 0x2400000053508b00ULL, },
+ { 0x181bd07f00310000ULL, 0x0000000055390000ULL, },
+ { 0x7354000025317200ULL, 0x0090b000000000f0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4f64000000003c00ULL, 0x001f000000142de8ULL, },
+ { 0x8b6f001600620000ULL, 0x000633000000005cULL, },
+ { 0x24000000916d3640ULL, 0x0071bba100000008ULL, }, /* 72 */
+ { 0x0000ae476c3c0078ULL, 0x15000be596000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3c0b985d5b9e0032ULL, 0x00003e2702000000ULL, },
+ { 0x0000000036008d0eULL, 0x428a7d7a00003294ULL, },
+ { 0x0000160011001b46ULL, 0x7b0000be94039000ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBS_U_B(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBS_U_B(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_u_d.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_u_d.c
new file mode 100644
index 0000000000..2685b2fe7e
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_u_d.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBS_U.D
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBS_U.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0x0000000000000000ULL, 0x71c71c71c71c71c7ULL, },
+ { 0x8e38e38e38e38e39ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x0000000000000000ULL, 0x1c71c71c71c71c72ULL, },
+ { 0x38e38e38e38e38e4ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0x0000000000000000ULL, 0x93e93e93e93e93e9ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x16c16c16c16c16c2ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x38e38e38e38e38e4ULL, 0x0000000000000000ULL, },
+ { 0x8e38e38e38e38e39ULL, 0x0000000000000000ULL, },
+ { 0x16c16c16c16c16c2ULL, 0x0000000000000000ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc71c71c71c71c71dULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x0000000000000000ULL, 0x1c71c71c71c71c72ULL, },
+ { 0x0000000000000000ULL, 0x71c71c71c71c71c7ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x93e93e93e93e93e9ULL, },
+ { 0x0000000000000000ULL, 0x8e38e38e38e38e39ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 64 */
+ { 0x0000000000000000ULL, 0x386f5044e93c5d10ULL, },
+ { 0x0000000000000000ULL, 0x238e445f53508af8ULL, },
+ { 0x181bd07eca3072f2ULL, 0x0000000000000000ULL, },
+ { 0x73531997253171c8ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4f6351b893c43b88ULL, 0x0000000000000000ULL, },
+ { 0x8b6eea15ef61e4baULL, 0x0000000000000000ULL, },
+ { 0x23efc7de916d3640ULL, 0x0000000000000000ULL, }, /* 72 */
+ { 0x0000000000000000ULL, 0x14e10be595ebd218ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3c0b985d5b9da932ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x428a7d79aac73294ULL, },
+ { 0x0000000000000000ULL, 0x7af9cdbe94038fa4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBS_U_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBS_U_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_u_h.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_u_h.c
new file mode 100644
index 0000000000..ca6dd38b69
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_u_h.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBS_U.H
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBS_U.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0x000071c71c720000ULL, 0x71c71c72000071c7ULL, },
+ { 0x8e39000038e38e39ULL, 0x000038e38e390000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x00001c7200000000ULL, 0x1c72000000001c72ULL, },
+ { 0x38e40000000038e4ULL, 0x0000000038e40000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0x000093e93e940000ULL, 0x93e93e94000093e9ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x16c20000000016c2ULL, 0x0000000016c20000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x38e40000000038e4ULL, 0x0000000038e40000ULL, },
+ { 0x8e39000038e38e39ULL, 0x000038e38e390000ULL, },
+ { 0x16c20000000016c2ULL, 0x0000000016c20000ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc71d00001c71c71dULL, 0x00001c71c71d0000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x00001c7200000000ULL, 0x1c72000000001c72ULL, },
+ { 0x000071c71c720000ULL, 0x71c71c72000071c7ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x000093e93e940000ULL, 0x93e93e94000093e9ULL, },
+ { 0x00008e3900000000ULL, 0x8e39000000008e39ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 64 */
+ { 0x0000e66900000000ULL, 0x38700000e93c5d10ULL, },
+ { 0x0000382200000000ULL, 0x238f000053508af8ULL, },
+ { 0x181bd07f00000000ULL, 0x0000000055390000ULL, },
+ { 0x73540000253171c8ULL, 0x0000afbc00000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4f64000000003b88ULL, 0x0000000000002de8ULL, },
+ { 0x8b6f000000000000ULL, 0x0000324200000000ULL, },
+ { 0x23f00000916d3640ULL, 0x0000bba100000000ULL, }, /* 72 */
+ { 0x0000ae476c3c0000ULL, 0x14e10be595ec0000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3c0b985d5b9e0000ULL, 0x00003e2701e90000ULL, },
+ { 0x0000000035cf8d0eULL, 0x428a7d7a00003294ULL, },
+ { 0x000015ea109e1b46ULL, 0x7afa000094038fa4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBS_U_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBS_U_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_u_w.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_u_w.c
new file mode 100644
index 0000000000..42ebddb408
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subs_u_w.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBS_U.W
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBS_U.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0x000000001c71c71cULL, 0x71c71c7200000000ULL, },
+ { 0x8e38e38e38e38e39ULL, 0x000000008e38e38eULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x0000000000000000ULL, 0x1c71c71d00000000ULL, },
+ { 0x38e38e3900000000ULL, 0x0000000038e38e39ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0x000000003e93e93eULL, 0x93e93e9400000000ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x16c16c1700000000ULL, 0x0000000016c16c17ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x38e38e3900000000ULL, 0x0000000038e38e39ULL, },
+ { 0x8e38e38e38e38e39ULL, 0x000000008e38e38eULL, },
+ { 0x16c16c1700000000ULL, 0x0000000016c16c17ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc71c71c71c71c71dULL, 0x00000000c71c71c7ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x0000000000000000ULL, 0x1c71c71d00000000ULL, },
+ { 0x000000001c71c71cULL, 0x71c71c7200000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x000000003e93e93eULL, 0x93e93e9400000000ULL, },
+ { 0x0000000000000000ULL, 0x8e38e38f00000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 64 */
+ { 0x0000000000000000ULL, 0x386f5044e93c5d10ULL, },
+ { 0x0000000000000000ULL, 0x238e445f53508af8ULL, },
+ { 0x181bd07f00000000ULL, 0x000000005538cd6cULL, },
+ { 0x73531997253171c8ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4f6351b900000000ULL, 0x0000000000000000ULL, },
+ { 0x8b6eea1600000000ULL, 0x0000000000000000ULL, },
+ { 0x23efc7de916d3640ULL, 0x0000000000000000ULL, }, /* 72 */
+ { 0x000000006c3bc478ULL, 0x14e10be595ebd218ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3c0b985d5b9da932ULL, 0x0000000001e84274ULL, },
+ { 0x0000000035cf8d0eULL, 0x428a7d7a00000000ULL, },
+ { 0x00000000109e1b46ULL, 0x7af9cdbe94038fa4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBS_U_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBS_U_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsus_u_b.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsus_u_b.c
new file mode 100644
index 0000000000..dac20cc769
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsus_u_b.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBSUS_U.B
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBSUS_U.B";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xffffc7ffffc7ffffULL, 0xc7ffffc7ffffc7ffULL, },
+ { 0xe38effe38effe38eULL, 0xffe38effe38effe3ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5656565656565656ULL, 0x5656565656565656ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3434343434343434ULL, 0x3434343434343434ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x1d72001d72001d72ULL, 0x001d72001d72001dULL, },
+ { 0x0000390000390000ULL, 0x3900003900003900ULL, },
+ { 0xababababababababULL, 0xababababababababULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xdedededededededeULL, 0xdedededededededeULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0xc7ff72c7ff72c7ffULL, 0x72c7ff72c7ff72c7ULL, },
+ { 0x8e39e38e39e38e39ULL, 0xe38e39e38e39e38eULL, },
+ { 0x5656565656565656ULL, 0x5656565656565656ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xababababababababULL, 0xababababababababULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8989898989898989ULL, 0x8989898989898989ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x72c71d72c71d72c7ULL, 0x1d72c71d72c71d72ULL, },
+ { 0x39008e39008e3900ULL, 0x8e39008e39008e39ULL, },
+ { 0xcdcdcdcdcdcdcdcdULL, 0xcdcdcdcdcdcdcdcdULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xe9ff94e9ff94e9ffULL, 0x94e9ff94e9ff94e9ULL, },
+ { 0xb05bffb05bffb05bULL, 0xffb05bffb05bffb0ULL, },
+ { 0x3434343434343434ULL, 0x3434343434343434ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8989898989898989ULL, 0x8989898989898989ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x6767676767676767ULL, 0x6767676767676767ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x50a50050a50050a5ULL, 0x0050a50050a50050ULL, },
+ { 0x17006c17006c1700ULL, 0x6c17006c17006c17ULL, },
+ { 0xe48f39e48f39e48fULL, 0x39e48f39e48f39e4ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xffe48effe48effe4ULL, 0x8effe48effe48effULL, },
+ { 0x8e39008e39008e39ULL, 0x008e39008e39008eULL, },
+ { 0xffc26cffc26cffc2ULL, 0x6cffc26cffc26cffULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0xffff00ffff00ffffULL, 0x00ffff00ffff00ffULL, },
+ { 0xc71d71c71d71c71dULL, 0x71c71d71c71d71c7ULL, },
+ { 0x1d72c81d72c81d72ULL, 0xc81d72c81d72c81dULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x72c7ff72c7ff72c7ULL, 0xff72c7ff72c7ff72ULL, },
+ { 0x001c72001c72001cULL, 0x72001c72001c7200ULL, },
+ { 0x50a5fb50a5fb50a5ULL, 0xfb50a5fb50a5fb50ULL, },
+ { 0x003e94003e94003eULL, 0x94003e94003e9400ULL, },
+ { 0x39e38f39e38f39e3ULL, 0x8f39e38f39e38f39ULL, },
+ { 0x0000ff0000ff0000ULL, 0xff0000ff0000ff00ULL, },
+ { 0xff00ffff00000000ULL, 0x00000000ff00ff00ULL, }, /* 64 */
+ { 0x8dace66900cf8e38ULL, 0x39705044e93c5e10ULL, },
+ { 0xdc10ffff6f93cac0ULL, 0x248f455fff508b00ULL, },
+ { 0x181bd07f00317300ULL, 0xbe768386ff39ce6cULL, },
+ { 0xff541a9725317200ULL, 0x0090b0001700a2f0ULL, },
+ { 0xffff000000ffff00ULL, 0x00ffff00000000ffULL, },
+ { 0xff6452b994c4ff88ULL, 0x00fff51b6a142de8ULL, },
+ { 0x8b6f00160062e500ULL, 0x85ffff426c0070ffULL, },
+ { 0xff00c8de916d3640ULL, 0x0071bba1ad007508ULL, }, /* 72 */
+ { 0xb19cae476cffc478ULL, 0x15e1ffe596000018ULL, },
+ { 0xff00ffffffffffffULL, 0x00ffffffff000000ULL, },
+ { 0x3c0b985d5b9ea932ULL, 0x9ae7ffffff004374ULL, },
+ { 0xe800308136008d0eULL, 0x428a7d7aab00ff94ULL, },
+ { 0x75911600119eff46ULL, 0x7bfacdbe940390a4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBSUS_U_B(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBSUS_U_B(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsus_u_d.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsus_u_d.c
new file mode 100644
index 0000000000..4485502c1c
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsus_u_d.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBSUS_U.D
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBSUS_U.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xffffffffffffffffULL, 0xc71c71c71c71c71cULL, },
+ { 0xe38e38e38e38e38eULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555556ULL, 0x5555555555555556ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3333333333333334ULL, 0x3333333333333334ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x1c71c71c71c71c72ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x38e38e38e38e38e4ULL, },
+ { 0xaaaaaaaaaaaaaaabULL, 0xaaaaaaaaaaaaaaabULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xdddddddddddddddeULL, 0xdddddddddddddddeULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0xc71c71c71c71c71cULL, 0x71c71c71c71c71c7ULL, },
+ { 0x8e38e38e38e38e39ULL, 0xe38e38e38e38e38eULL, },
+ { 0x5555555555555556ULL, 0x5555555555555556ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaabULL, 0xaaaaaaaaaaaaaaabULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8888888888888889ULL, 0x8888888888888889ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x71c71c71c71c71c7ULL, 0x1c71c71c71c71c72ULL, },
+ { 0x38e38e38e38e38e4ULL, 0x8e38e38e38e38e39ULL, },
+ { 0xcccccccccccccccdULL, 0xcccccccccccccccdULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xe93e93e93e93e93eULL, 0x93e93e93e93e93e9ULL, },
+ { 0xb05b05b05b05b05bULL, 0xffffffffffffffffULL, },
+ { 0x3333333333333334ULL, 0x3333333333333334ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8888888888888889ULL, 0x8888888888888889ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x6666666666666667ULL, 0x6666666666666667ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4fa4fa4fa4fa4fa5ULL, 0x0000000000000000ULL, },
+ { 0x16c16c16c16c16c2ULL, 0x6c16c16c16c16c17ULL, },
+ { 0xe38e38e38e38e38fULL, 0x38e38e38e38e38e4ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xffffffffffffffffULL, 0x8e38e38e38e38e39ULL, },
+ { 0x8e38e38e38e38e39ULL, 0x0000000000000000ULL, },
+ { 0xffffffffffffffffULL, 0x6c16c16c16c16c17ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0xffffffffffffffffULL, 0x0000000000000000ULL, },
+ { 0xc71c71c71c71c71dULL, 0x71c71c71c71c71c7ULL, },
+ { 0x1c71c71c71c71c72ULL, 0xc71c71c71c71c71dULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x71c71c71c71c71c7ULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x71c71c71c71c71c7ULL, },
+ { 0x4fa4fa4fa4fa4fa5ULL, 0xfa4fa4fa4fa4fa50ULL, },
+ { 0x0000000000000000ULL, 0x93e93e93e93e93e9ULL, },
+ { 0x38e38e38e38e38e3ULL, 0x8e38e38e38e38e39ULL, },
+ { 0x0000000000000000ULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0x0000000000000000ULL, }, /* 64 */
+ { 0x8cace668dace8e38ULL, 0x386f5044e93c5d10ULL, },
+ { 0xdc1038216e92c9c0ULL, 0x238e445f53508af8ULL, },
+ { 0x181bd07eca3072f2ULL, 0xbd7582865538cd6cULL, },
+ { 0xffffffffffffffffULL, 0x0000000000000000ULL, },
+ { 0xffffffffffffffffULL, 0x0000000000000000ULL, },
+ { 0xffffffffffffffffULL, 0x0000000000000000ULL, },
+ { 0x8b6eea15ef61e4baULL, 0x850632416bfc705cULL, },
+ { 0xffffffffffffffffULL, 0x0000000000000000ULL, }, /* 72 */
+ { 0xb09cae476c3bc478ULL, 0x14e10be595ebd218ULL, },
+ { 0xffffffffffffffffULL, 0x0000000000000000ULL, },
+ { 0x3c0b985d5b9da932ULL, 0x99e73e2701e84274ULL, },
+ { 0xe7e42f8135cf8d0eULL, 0x428a7d79aac73294ULL, },
+ { 0x749115ea109e1b46ULL, 0x7af9cdbe94038fa4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBSUS_U_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBSUS_U_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsus_u_h.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsus_u_h.c
new file mode 100644
index 0000000000..9e99aeefc5
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsus_u_h.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBSUS_U.H
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBSUS_U.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xffffc71cffffffffULL, 0xc71cffffffffc71cULL, },
+ { 0xe38effff8e38e38eULL, 0xffff8e38e38effffULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5556555655565556ULL, 0x5556555655565556ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3334333433343334ULL, 0x3334333433343334ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x1c72000071c81c72ULL, 0x000071c81c720000ULL, },
+ { 0x000038e400000000ULL, 0x38e40000000038e4ULL, },
+ { 0xaaabaaabaaabaaabULL, 0xaaabaaabaaabaaabULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xdddedddedddedddeULL, 0xdddedddedddedddeULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0xc71c71c7ffffc71cULL, 0x71c7ffffc71c71c7ULL, },
+ { 0x8e39e38e38e38e39ULL, 0xe38e38e38e39e38eULL, },
+ { 0x5556555655565556ULL, 0x5556555655565556ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaabaaabaaabaaabULL, 0xaaabaaabaaabaaabULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8889888988898889ULL, 0x8889888988898889ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x71c71c72c71d71c7ULL, 0x1c72c71d71c71c72ULL, },
+ { 0x38e48e39000038e4ULL, 0x8e39000038e48e39ULL, },
+ { 0xcccdcccdcccdcccdULL, 0xcccdcccdcccdcccdULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xe93e93e9ffffe93eULL, 0x93e9ffffe93e93e9ULL, },
+ { 0xb05bffff5b05b05bULL, 0xffff5b05b05bffffULL, },
+ { 0x3334333433343334ULL, 0x3334333433343334ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8889888988898889ULL, 0x8889888988898889ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x6667666766676667ULL, 0x6667666766676667ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4fa50000a4fb4fa5ULL, 0x0000a4fb4fa50000ULL, },
+ { 0x16c26c17000016c2ULL, 0x6c17000016c26c17ULL, },
+ { 0xe38f38e48e39e38fULL, 0x38e48e39e38f38e4ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xffff8e39e38effffULL, 0x8e39e38effff8e39ULL, },
+ { 0x8e39000038e38e39ULL, 0x000038e38e390000ULL, },
+ { 0xffff6c17c16cffffULL, 0x6c17c16cffff6c17ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0xffff0000ffffffffULL, 0x0000ffffffff0000ULL, },
+ { 0xc71d71c71c71c71dULL, 0x71c71c71c71d71c7ULL, },
+ { 0x1c72c71d71c81c72ULL, 0xc71d71c81c72c71dULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x71c7ffffc71d71c7ULL, 0xffffc71d71c7ffffULL, },
+ { 0x000071c71c720000ULL, 0x71c71c72000071c7ULL, },
+ { 0x4fa5fa50a4fb4fa5ULL, 0xfa50a4fb4fa5fa50ULL, },
+ { 0x000093e93e940000ULL, 0x93e93e94000093e9ULL, },
+ { 0x38e38e39e38f38e3ULL, 0x8e39e38f38e38e39ULL, },
+ { 0x0000ffff00000000ULL, 0xffff00000000ffffULL, },
+ { 0xffffffff00000000ULL, 0x00000000ffffffffULL, }, /* 64 */
+ { 0x8cace66900008e38ULL, 0x38705044e93c5d10ULL, },
+ { 0xdc10ffff6e93c9c0ULL, 0x238f445fffff8af8ULL, },
+ { 0x181bd07f000072f2ULL, 0xbd768286ffffcd6cULL, },
+ { 0xffff1997253171c8ULL, 0x0000afbc16c4a2f0ULL, },
+ { 0xffff00000000ffffULL, 0x0000ffff00000000ULL, },
+ { 0xffff51b993c4ffffULL, 0x0000f41b6a142de8ULL, },
+ { 0x8b6f00000000e4baULL, 0x8506ffff6bfd705cULL, },
+ { 0xffffc7de916d3640ULL, 0x0000bba1acb07508ULL, }, /* 72 */
+ { 0xb09cae476c3cc478ULL, 0x14e1ffff95ec0000ULL, },
+ { 0xffffffffffffffffULL, 0x0000ffffffff0000ULL, },
+ { 0x3c0b985d5b9ea932ULL, 0x99e7ffffffff4274ULL, },
+ { 0xe7e52f8135cf8d0eULL, 0x428a7d7aaac7ffffULL, },
+ { 0x749115ea109effffULL, 0x7afacdbe94038fa4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBSUS_U_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBSUS_U_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsus_u_w.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsus_u_w.c
new file mode 100644
index 0000000000..53a9acac1b
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsus_u_w.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBSUS_U.W
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBSUS_U.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xffffffffffffffffULL, 0xc71c71c7ffffffffULL, },
+ { 0xe38e38e38e38e38eULL, 0xffffffffe38e38e3ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555655555556ULL, 0x5555555655555556ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3333333433333334ULL, 0x3333333433333334ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x1c71c71d71c71c72ULL, 0x000000001c71c71dULL, },
+ { 0x0000000000000000ULL, 0x38e38e3900000000ULL, },
+ { 0xaaaaaaabaaaaaaabULL, 0xaaaaaaabaaaaaaabULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xdddddddedddddddeULL, 0xdddddddedddddddeULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0xc71c71c7ffffffffULL, 0x71c71c72c71c71c7ULL, },
+ { 0x8e38e38e38e38e39ULL, 0xe38e38e38e38e38eULL, },
+ { 0x5555555655555556ULL, 0x5555555655555556ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaabaaaaaaabULL, 0xaaaaaaabaaaaaaabULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8888888988888889ULL, 0x8888888988888889ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x71c71c72c71c71c7ULL, 0x1c71c71d71c71c72ULL, },
+ { 0x38e38e3900000000ULL, 0x8e38e38e38e38e39ULL, },
+ { 0xcccccccdcccccccdULL, 0xcccccccdcccccccdULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xe93e93e9ffffffffULL, 0x93e93e94e93e93e9ULL, },
+ { 0xb05b05b05b05b05bULL, 0xffffffffb05b05b0ULL, },
+ { 0x3333333433333334ULL, 0x3333333433333334ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8888888988888889ULL, 0x8888888988888889ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x6666666766666667ULL, 0x6666666766666667ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4fa4fa50a4fa4fa5ULL, 0x000000004fa4fa50ULL, },
+ { 0x16c16c1700000000ULL, 0x6c16c16c16c16c17ULL, },
+ { 0xe38e38e48e38e38fULL, 0x38e38e39e38e38e4ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xffffffffe38e38e4ULL, 0x8e38e38effffffffULL, },
+ { 0x8e38e38e38e38e39ULL, 0x000000008e38e38eULL, },
+ { 0xffffffffc16c16c2ULL, 0x6c16c16cffffffffULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0xffffffffffffffffULL, 0x00000000ffffffffULL, },
+ { 0xc71c71c71c71c71dULL, 0x71c71c71c71c71c7ULL, },
+ { 0x1c71c71d71c71c72ULL, 0xc71c71c81c71c71dULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x71c71c72c71c71c7ULL, 0xffffffff71c71c72ULL, },
+ { 0x000000001c71c71cULL, 0x71c71c7200000000ULL, },
+ { 0x4fa4fa50a4fa4fa5ULL, 0xfa4fa4fb4fa4fa50ULL, },
+ { 0x000000003e93e93eULL, 0x93e93e9400000000ULL, },
+ { 0x38e38e39e38e38e3ULL, 0x8e38e38f38e38e39ULL, },
+ { 0x0000000000000000ULL, 0xffffffff00000000ULL, },
+ { 0xffffffff00000000ULL, 0x00000000ffffffffULL, }, /* 64 */
+ { 0x8cace66900000000ULL, 0x386f5044e93c5d10ULL, },
+ { 0xdc1038226e92c9c0ULL, 0x238e445fffffffffULL, },
+ { 0x181bd07f00000000ULL, 0xbd758286ffffffffULL, },
+ { 0xffffffff253171c8ULL, 0x0000000016c3a2f0ULL, },
+ { 0xffffffff00000000ULL, 0x0000000000000000ULL, },
+ { 0xffffffff93c43b88ULL, 0x000000006a142de8ULL, },
+ { 0x8b6eea1600000000ULL, 0x850632426bfc705cULL, },
+ { 0xffffffff916d3640ULL, 0x00000000acaf7508ULL, }, /* 72 */
+ { 0xb09cae476c3bc478ULL, 0x14e10be595ebd218ULL, },
+ { 0xffffffffffffffffULL, 0x00000000ffffffffULL, },
+ { 0x3c0b985d5b9da932ULL, 0x99e73e27ffffffffULL, },
+ { 0xe7e42f8135cf8d0eULL, 0x428a7d7aaac73294ULL, },
+ { 0x749115ea109e1b46ULL, 0x7af9cdbe94038fa4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBSUS_U_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBSUS_U_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsuu_s_b.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsuu_s_b.c
new file mode 100644
index 0000000000..86fb4f3e26
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsuu_s_b.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBSUU_S.B
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBSUU_S.B";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0x7f7f7f7f7f7f7f7fULL, 0x7f7f7f7f7f7f7f7fULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x7f7f7f7f7f7f7f7fULL, 0x7f7f7f7f7f7f7f7fULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x7f7f7f7f7f7f7f7fULL, 0x7f7f7f7f7f7f7f7fULL, },
+ { 0x1c717f1c717f1c71ULL, 0x7f1c717f1c717f1cULL, },
+ { 0x7f7f387f7f387f7fULL, 0x387f7f387f7f387fULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, },
+ { 0xababababababababULL, 0xababababababababULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, },
+ { 0xcdcdcdcdcdcdcdcdULL, 0xcdcdcdcdcdcdcdcdULL, },
+ { 0x8080c88080c88080ULL, 0xc88080c88080c880ULL, },
+ { 0xe48f80e48f80e48fULL, 0x80e48f80e48f80e4ULL, },
+ { 0xababababababababULL, 0xababababababababULL, }, /* 16 */
+ { 0x7f7f7f7f7f7f7f7fULL, 0x7f7f7f7f7f7f7f7fULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xdedededededededeULL, 0xdedededededededeULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0xc71c72c71c72c71cULL, 0x72c71c72c71c72c7ULL, },
+ { 0x7f39e37f39e37f39ULL, 0xe37f39e37f39e37fULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xababababababababULL, 0xababababababababULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8989898989898989ULL, 0x8989898989898989ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x80c71d80c71d80c7ULL, 0x1d80c71d80c71d80ULL, },
+ { 0x39e48e39e48e39e4ULL, 0x8e39e48e39e48e39ULL, },
+ { 0xcdcdcdcdcdcdcdcdULL, 0xcdcdcdcdcdcdcdcdULL, }, /* 32 */
+ { 0x7f7f7f7f7f7f7f7fULL, 0x7f7f7f7f7f7f7f7fULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7f7f7f7f7f7f7f7fULL, 0x7f7f7f7f7f7f7f7fULL, },
+ { 0xe93e7fe93e7fe93eULL, 0x7fe93e7fe93e7fe9ULL, },
+ { 0x7f5b057f5b057f5bULL, 0x057f5b057f5b057fULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8989898989898989ULL, 0x8989898989898989ULL, },
+ { 0xdedededededededeULL, 0xdedededededededeULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x80a5fb80a5fb80a5ULL, 0xfb80a5fb80a5fb80ULL, },
+ { 0x17c28017c28017c2ULL, 0x8017c28017c28017ULL, },
+ { 0xe48f80e48f80e48fULL, 0x80e48f80e48f80e4ULL, }, /* 48 */
+ { 0x7f7f387f7f387f7fULL, 0x387f7f387f7f387fULL, },
+ { 0x39e48e39e48e39e4ULL, 0x8e39e48e39e48e39ULL, },
+ { 0x7f39e37f39e37f39ULL, 0xe37f39e37f39e37fULL, },
+ { 0x17c28017c28017c2ULL, 0x8017c28017c28017ULL, },
+ { 0x7f5b057f5b057f5bULL, 0x057f5b057f5b057fULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7f1d807f1d807f1dULL, 0x807f1d807f1d807fULL, },
+ { 0x8080c88080c88080ULL, 0xc88080c88080c880ULL, }, /* 56 */
+ { 0x1c717f1c717f1c71ULL, 0x7f1c717f1c717f1cULL, },
+ { 0x80c71d80c71d80c7ULL, 0x1d80c71d80c71d80ULL, },
+ { 0xc71c72c71c72c71cULL, 0x72c71c72c71c72c7ULL, },
+ { 0x80a5fb80a5fb80a5ULL, 0xfb80a5fb80a5fb80ULL, },
+ { 0xe93e7fe93e7fe93eULL, 0x7fe93e7fe93e7fe9ULL, },
+ { 0x80e37f80e37f80e3ULL, 0x7f80e37f80e37f80ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 64 */
+ { 0x8dac7f69dbcf8e38ULL, 0x398080447f3c5e80ULL, },
+ { 0xdc1038228093cac0ULL, 0x248f808053507ff8ULL, },
+ { 0x181b7f7fca3180f2ULL, 0xbe8083865539ce80ULL, },
+ { 0x73548097253172c8ULL, 0xc77f7fbc80c4a27fULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4f6480b994c43c88ULL, 0xeb1ff58080142d7fULL, },
+ { 0x7f6fea16ef62e5baULL, 0x8506338080fd805cULL, },
+ { 0x24f0c8de7f6d3640ULL, 0xdc717f7fadb08008ULL, }, /* 72 */
+ { 0xb19c7f476c3cc478ULL, 0x15e10b7f7fecd380ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3c0b7f5d5b7fa932ULL, 0x9ae73e2702e98080ULL, },
+ { 0xe8e5808136cf7f0eULL, 0x427f7d7aabc7327fULL, },
+ { 0x809116ea119e1b46ULL, 0x7bfacd7f7f037fa4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBSUU_S_B(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBSUU_S_B(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsuu_s_d.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsuu_s_d.c
new file mode 100644
index 0000000000..45a1eb3094
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsuu_s_d.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBSUU_S.D
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBSUU_S.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL, },
+ { 0x1c71c71c71c71c71ULL, 0x7fffffffffffffffULL, },
+ { 0x7fffffffffffffffULL, 0x38e38e38e38e38e3ULL, },
+ { 0x8000000000000000ULL, 0x8000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8000000000000000ULL, 0x8000000000000000ULL, },
+ { 0xaaaaaaaaaaaaaaabULL, 0xaaaaaaaaaaaaaaabULL, },
+ { 0x8000000000000000ULL, 0x8000000000000000ULL, },
+ { 0xcccccccccccccccdULL, 0xcccccccccccccccdULL, },
+ { 0x8000000000000000ULL, 0xc71c71c71c71c71dULL, },
+ { 0xe38e38e38e38e38fULL, 0x8000000000000000ULL, },
+ { 0xaaaaaaaaaaaaaaabULL, 0xaaaaaaaaaaaaaaabULL, }, /* 16 */
+ { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xdddddddddddddddeULL, 0xdddddddddddddddeULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0xc71c71c71c71c71cULL, 0x71c71c71c71c71c7ULL, },
+ { 0x7fffffffffffffffULL, 0xe38e38e38e38e38eULL, },
+ { 0x8000000000000000ULL, 0x8000000000000000ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaabULL, 0xaaaaaaaaaaaaaaabULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8888888888888889ULL, 0x8888888888888889ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x8000000000000000ULL, 0x1c71c71c71c71c72ULL, },
+ { 0x38e38e38e38e38e4ULL, 0x8e38e38e38e38e39ULL, },
+ { 0xcccccccccccccccdULL, 0xcccccccccccccccdULL, }, /* 32 */
+ { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL, },
+ { 0xe93e93e93e93e93eULL, 0x7fffffffffffffffULL, },
+ { 0x7fffffffffffffffULL, 0x05b05b05b05b05b0ULL, },
+ { 0x8000000000000000ULL, 0x8000000000000000ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8888888888888889ULL, 0x8888888888888889ULL, },
+ { 0xdddddddddddddddeULL, 0xdddddddddddddddeULL, },
+ { 0x8000000000000000ULL, 0x8000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8000000000000000ULL, 0xfa4fa4fa4fa4fa50ULL, },
+ { 0x16c16c16c16c16c2ULL, 0x8000000000000000ULL, },
+ { 0xe38e38e38e38e38fULL, 0x8000000000000000ULL, }, /* 48 */
+ { 0x7fffffffffffffffULL, 0x38e38e38e38e38e3ULL, },
+ { 0x38e38e38e38e38e4ULL, 0x8e38e38e38e38e39ULL, },
+ { 0x7fffffffffffffffULL, 0xe38e38e38e38e38eULL, },
+ { 0x16c16c16c16c16c2ULL, 0x8000000000000000ULL, },
+ { 0x7fffffffffffffffULL, 0x05b05b05b05b05b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7fffffffffffffffULL, 0x8000000000000000ULL, },
+ { 0x8000000000000000ULL, 0xc71c71c71c71c71dULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0x7fffffffffffffffULL, },
+ { 0x8000000000000000ULL, 0x1c71c71c71c71c72ULL, },
+ { 0xc71c71c71c71c71cULL, 0x71c71c71c71c71c7ULL, },
+ { 0x8000000000000000ULL, 0xfa4fa4fa4fa4fa50ULL, },
+ { 0xe93e93e93e93e93eULL, 0x7fffffffffffffffULL, },
+ { 0x8000000000000000ULL, 0x7fffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 64 */
+ { 0x8cace668dace8e38ULL, 0x386f5044e93c5d10ULL, },
+ { 0xdc1038216e92c9c0ULL, 0x238e445f53508af8ULL, },
+ { 0x181bd07eca3072f2ULL, 0xbd7582865538cd6cULL, },
+ { 0x73531997253171c8ULL, 0xc790afbb16c3a2f0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4f6351b893c43b88ULL, 0xeb1ef41a6a142de8ULL, },
+ { 0x7fffffffffffffffULL, 0x850632416bfc705cULL, },
+ { 0x23efc7de916d3640ULL, 0xdc71bba0acaf7508ULL, }, /* 72 */
+ { 0xb09cae476c3bc478ULL, 0x14e10be595ebd218ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3c0b985d5b9da932ULL, 0x99e73e2701e84274ULL, },
+ { 0xe7e42f8135cf8d0eULL, 0x428a7d79aac73294ULL, },
+ { 0x8000000000000000ULL, 0x7af9cdbe94038fa4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBSUU_S_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBSUU_S_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsuu_s_h.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsuu_s_h.c
new file mode 100644
index 0000000000..14ac7def29
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsuu_s_h.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBSUU_S.H
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBSUU_S.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0x7fff7fff7fff7fffULL, 0x7fff7fff7fff7fffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x7fff7fff7fff7fffULL, 0x7fff7fff7fff7fffULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x7fff7fff7fff7fffULL, 0x7fff7fff7fff7fffULL, },
+ { 0x1c717fff71c71c71ULL, 0x7fff71c71c717fffULL, },
+ { 0x7fff38e37fff7fffULL, 0x38e37fff7fff38e3ULL, },
+ { 0x8000800080008000ULL, 0x8000800080008000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8000800080008000ULL, 0x8000800080008000ULL, },
+ { 0xaaabaaabaaabaaabULL, 0xaaabaaabaaabaaabULL, },
+ { 0x8000800080008000ULL, 0x8000800080008000ULL, },
+ { 0xcccdcccdcccdcccdULL, 0xcccdcccdcccdcccdULL, },
+ { 0x8000c71d80008000ULL, 0xc71d80008000c71dULL, },
+ { 0xe38f80008e39e38fULL, 0x80008e39e38f8000ULL, },
+ { 0xaaabaaabaaabaaabULL, 0xaaabaaabaaabaaabULL, }, /* 16 */
+ { 0x7fff7fff7fff7fffULL, 0x7fff7fff7fff7fffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xdddedddedddedddeULL, 0xdddedddedddedddeULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0xc71c71c71c72c71cULL, 0x71c71c72c71c71c7ULL, },
+ { 0x7fffe38e38e37fffULL, 0xe38e38e37fffe38eULL, },
+ { 0x8000800080008000ULL, 0x8000800080008000ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaabaaabaaabaaabULL, 0xaaabaaabaaabaaabULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8889888988898889ULL, 0x8889888988898889ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x80001c72c71d8000ULL, 0x1c72c71d80001c72ULL, },
+ { 0x38e48e39e38e38e4ULL, 0x8e39e38e38e48e39ULL, },
+ { 0xcccdcccdcccdcccdULL, 0xcccdcccdcccdcccdULL, }, /* 32 */
+ { 0x7fff7fff7fff7fffULL, 0x7fff7fff7fff7fffULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7fff7fff7fff7fffULL, 0x7fff7fff7fff7fffULL, },
+ { 0xe93e7fff3e94e93eULL, 0x7fff3e94e93e7fffULL, },
+ { 0x7fff05b05b057fffULL, 0x05b05b057fff05b0ULL, },
+ { 0x8000800080008000ULL, 0x8000800080008000ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8889888988898889ULL, 0x8889888988898889ULL, },
+ { 0xdddedddedddedddeULL, 0xdddedddedddedddeULL, },
+ { 0x8000800080008000ULL, 0x8000800080008000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8000fa50a4fb8000ULL, 0xfa50a4fb8000fa50ULL, },
+ { 0x16c28000c16c16c2ULL, 0x8000c16c16c28000ULL, },
+ { 0xe38f80008e39e38fULL, 0x80008e39e38f8000ULL, }, /* 48 */
+ { 0x7fff38e37fff7fffULL, 0x38e37fff7fff38e3ULL, },
+ { 0x38e48e39e38e38e4ULL, 0x8e39e38e38e48e39ULL, },
+ { 0x7fffe38e38e37fffULL, 0xe38e38e37fffe38eULL, },
+ { 0x16c28000c16c16c2ULL, 0x8000c16c16c28000ULL, },
+ { 0x7fff05b05b057fffULL, 0x05b05b057fff05b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7fff80001c717fffULL, 0x80001c717fff8000ULL, },
+ { 0x8000c71d80008000ULL, 0xc71d80008000c71dULL, }, /* 56 */
+ { 0x1c717fff71c71c71ULL, 0x7fff71c71c717fffULL, },
+ { 0x80001c72c71d8000ULL, 0x1c72c71d80001c72ULL, },
+ { 0xc71c71c71c72c71cULL, 0x71c71c72c71c71c7ULL, },
+ { 0x8000fa50a4fb8000ULL, 0xfa50a4fb8000fa50ULL, },
+ { 0xe93e7fff3e94e93eULL, 0x7fff3e94e93e7fffULL, },
+ { 0x80007fffe38f8000ULL, 0x7fffe38f80007fffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 64 */
+ { 0x8cac7fffdacf8e38ULL, 0x387080007fff5d10ULL, },
+ { 0xdc1038228000c9c0ULL, 0x238f800053507fffULL, },
+ { 0x181b7fffca318000ULL, 0xbd7682865539cd6cULL, },
+ { 0x73548000253171c8ULL, 0xc7907fff8000a2f0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4f64800093c43b88ULL, 0xeb1ff41b80002de8ULL, },
+ { 0x7fffea16ef62e4baULL, 0x8506324280008000ULL, },
+ { 0x23f0c7de7fff3640ULL, 0xdc717fffacb08000ULL, }, /* 72 */
+ { 0xb09c7fff6c3cc478ULL, 0x14e10be57fffd218ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3c0b7fff5b9ea932ULL, 0x99e73e2701e98000ULL, },
+ { 0xe7e5800035cf7fffULL, 0x428a7d7aaac73294ULL, },
+ { 0x800015ea109e1b46ULL, 0x7afacdbe7fff7fffULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBSUU_S_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBSUU_S_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsuu_s_w.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsuu_s_w.c
new file mode 100644
index 0000000000..688f469cd0
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subsuu_s_w.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBSUU_S.W
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBSUU_S.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0x7fffffff7fffffffULL, 0x7fffffff7fffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x7fffffff7fffffffULL, 0x7fffffff7fffffffULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x7fffffff7fffffffULL, 0x7fffffff7fffffffULL, },
+ { 0x1c71c71c71c71c71ULL, 0x7fffffff1c71c71cULL, },
+ { 0x7fffffff7fffffffULL, 0x38e38e387fffffffULL, },
+ { 0x8000000080000000ULL, 0x8000000080000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8000000080000000ULL, 0x8000000080000000ULL, },
+ { 0xaaaaaaabaaaaaaabULL, 0xaaaaaaabaaaaaaabULL, },
+ { 0x8000000080000000ULL, 0x8000000080000000ULL, },
+ { 0xcccccccdcccccccdULL, 0xcccccccdcccccccdULL, },
+ { 0x8000000080000000ULL, 0xc71c71c880000000ULL, },
+ { 0xe38e38e48e38e38fULL, 0x80000000e38e38e4ULL, },
+ { 0xaaaaaaabaaaaaaabULL, 0xaaaaaaabaaaaaaabULL, }, /* 16 */
+ { 0x7fffffff7fffffffULL, 0x7fffffff7fffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xdddddddedddddddeULL, 0xdddddddedddddddeULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0xc71c71c71c71c71cULL, 0x71c71c72c71c71c7ULL, },
+ { 0x7fffffff38e38e39ULL, 0xe38e38e37fffffffULL, },
+ { 0x8000000080000000ULL, 0x8000000080000000ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaabaaaaaaabULL, 0xaaaaaaabaaaaaaabULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8888888988888889ULL, 0x8888888988888889ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x80000000c71c71c7ULL, 0x1c71c71d80000000ULL, },
+ { 0x38e38e39e38e38e4ULL, 0x8e38e38e38e38e39ULL, },
+ { 0xcccccccdcccccccdULL, 0xcccccccdcccccccdULL, }, /* 32 */
+ { 0x7fffffff7fffffffULL, 0x7fffffff7fffffffULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7fffffff7fffffffULL, 0x7fffffff7fffffffULL, },
+ { 0xe93e93e93e93e93eULL, 0x7fffffffe93e93e9ULL, },
+ { 0x7fffffff5b05b05bULL, 0x05b05b057fffffffULL, },
+ { 0x8000000080000000ULL, 0x8000000080000000ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8888888988888889ULL, 0x8888888988888889ULL, },
+ { 0xdddddddedddddddeULL, 0xdddddddedddddddeULL, },
+ { 0x8000000080000000ULL, 0x8000000080000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x80000000a4fa4fa5ULL, 0xfa4fa4fb80000000ULL, },
+ { 0x16c16c17c16c16c2ULL, 0x8000000016c16c17ULL, },
+ { 0xe38e38e48e38e38fULL, 0x80000000e38e38e4ULL, }, /* 48 */
+ { 0x7fffffff7fffffffULL, 0x38e38e387fffffffULL, },
+ { 0x38e38e39e38e38e4ULL, 0x8e38e38e38e38e39ULL, },
+ { 0x7fffffff38e38e39ULL, 0xe38e38e37fffffffULL, },
+ { 0x16c16c17c16c16c2ULL, 0x8000000016c16c17ULL, },
+ { 0x7fffffff5b05b05bULL, 0x05b05b057fffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x7fffffff1c71c71dULL, 0x800000007fffffffULL, },
+ { 0x8000000080000000ULL, 0xc71c71c880000000ULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0x7fffffff1c71c71cULL, },
+ { 0x80000000c71c71c7ULL, 0x1c71c71d80000000ULL, },
+ { 0xc71c71c71c71c71cULL, 0x71c71c72c71c71c7ULL, },
+ { 0x80000000a4fa4fa5ULL, 0xfa4fa4fb80000000ULL, },
+ { 0xe93e93e93e93e93eULL, 0x7fffffffe93e93e9ULL, },
+ { 0x80000000e38e38e3ULL, 0x7fffffff80000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 64 */
+ { 0x8cace669dace8e38ULL, 0x386f50447fffffffULL, },
+ { 0xdc10382280000000ULL, 0x238e445f53508af8ULL, },
+ { 0x181bd07fca3072f2ULL, 0xbd7582865538cd6cULL, },
+ { 0x73531997253171c8ULL, 0xc790afbc80000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4f6351b993c43b88ULL, 0xeb1ef41b80000000ULL, },
+ { 0x7fffffffef61e4baULL, 0x8506324280000000ULL, },
+ { 0x23efc7de7fffffffULL, 0xdc71bba1acaf7508ULL, }, /* 72 */
+ { 0xb09cae476c3bc478ULL, 0x14e10be57fffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3c0b985d5b9da932ULL, 0x99e73e2701e84274ULL, },
+ { 0xe7e42f8135cf8d0eULL, 0x428a7d7aaac73294ULL, },
+ { 0x80000000109e1b46ULL, 0x7af9cdbe7fffffffULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBSUU_S_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBSUU_S_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subv_b.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subv_b.c
new file mode 100644
index 0000000000..d0964dcd59
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subv_b.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBV.B
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBV.B";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5656565656565656ULL, 0x5656565656565656ULL, },
+ { 0xababababababababULL, 0xababababababababULL, },
+ { 0x3434343434343434ULL, 0x3434343434343434ULL, },
+ { 0xcdcdcdcdcdcdcdcdULL, 0xcdcdcdcdcdcdcdcdULL, },
+ { 0x1d72c81d72c81d72ULL, 0xc81d72c81d72c81dULL, },
+ { 0xe48f39e48f39e48fULL, 0x39e48f39e48f39e4ULL, },
+ { 0xababababababababULL, 0xababababababababULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xdedededededededeULL, 0xdedededededededeULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0xc71c72c71c72c71cULL, 0x72c71c72c71c72c7ULL, },
+ { 0x8e39e38e39e38e39ULL, 0xe38e39e38e39e38eULL, },
+ { 0x5656565656565656ULL, 0x5656565656565656ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xababababababababULL, 0xababababababababULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8989898989898989ULL, 0x8989898989898989ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x72c71d72c71d72c7ULL, 0x1d72c71d72c71d72ULL, },
+ { 0x39e48e39e48e39e4ULL, 0x8e39e48e39e48e39ULL, },
+ { 0xcdcdcdcdcdcdcdcdULL, 0xcdcdcdcdcdcdcdcdULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xe93e94e93e94e93eULL, 0x94e93e94e93e94e9ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x3434343434343434ULL, 0x3434343434343434ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8989898989898989ULL, 0x8989898989898989ULL, },
+ { 0xdedededededededeULL, 0xdedededededededeULL, },
+ { 0x6767676767676767ULL, 0x6767676767676767ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x50a5fb50a5fb50a5ULL, 0xfb50a5fb50a5fb50ULL, },
+ { 0x17c26c17c26c17c2ULL, 0x6c17c26c17c26c17ULL, },
+ { 0xe48f39e48f39e48fULL, 0x39e48f39e48f39e4ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x39e48e39e48e39e4ULL, 0x8e39e48e39e48e39ULL, },
+ { 0x8e39e38e39e38e39ULL, 0xe38e39e38e39e38eULL, },
+ { 0x17c26c17c26c17c2ULL, 0x6c17c26c17c26c17ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc71d71c71d71c71dULL, 0x71c71d71c71d71c7ULL, },
+ { 0x1d72c81d72c81d72ULL, 0xc81d72c81d72c81dULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x72c71d72c71d72c7ULL, 0x1d72c71d72c71d72ULL, },
+ { 0xc71c72c71c72c71cULL, 0x72c71c72c71c72c7ULL, },
+ { 0x50a5fb50a5fb50a5ULL, 0xfb50a5fb50a5fb50ULL, },
+ { 0xe93e94e93e94e93eULL, 0x94e93e94e93e94e9ULL, },
+ { 0x39e38f39e38f39e3ULL, 0x8f39e38f39e38f39ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 64 */
+ { 0x8dace669dbcf8e38ULL, 0x39705044e93c5e10ULL, },
+ { 0xdc1038226f93cac0ULL, 0x248f455f53508bf8ULL, },
+ { 0x181bd07fca3173f2ULL, 0xbe7683865539ce6cULL, },
+ { 0x73541a97253172c8ULL, 0xc790b0bc17c4a2f0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4f6452b994c43c88ULL, 0xeb1ff51b6a142de8ULL, },
+ { 0x8b6fea16ef62e5baULL, 0x850633426cfd705cULL, },
+ { 0x24f0c8de916d3640ULL, 0xdc71bba1adb07508ULL, }, /* 72 */
+ { 0xb19cae476c3cc478ULL, 0x15e10be596ecd318ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3c0b985d5b9ea932ULL, 0x9ae73e2702e94374ULL, },
+ { 0xe8e5308136cf8d0eULL, 0x428a7d7aabc73294ULL, },
+ { 0x759116ea119e1b46ULL, 0x7bfacdbe940390a4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBV_B(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBV_B(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subv_d.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subv_d.c
new file mode 100644
index 0000000000..ec26a8e0c6
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subv_d.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBV.D
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBV.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555556ULL, 0x5555555555555556ULL, },
+ { 0xaaaaaaaaaaaaaaabULL, 0xaaaaaaaaaaaaaaabULL, },
+ { 0x3333333333333334ULL, 0x3333333333333334ULL, },
+ { 0xcccccccccccccccdULL, 0xcccccccccccccccdULL, },
+ { 0x1c71c71c71c71c72ULL, 0xc71c71c71c71c71dULL, },
+ { 0xe38e38e38e38e38fULL, 0x38e38e38e38e38e4ULL, },
+ { 0xaaaaaaaaaaaaaaabULL, 0xaaaaaaaaaaaaaaabULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xdddddddddddddddeULL, 0xdddddddddddddddeULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0xc71c71c71c71c71cULL, 0x71c71c71c71c71c7ULL, },
+ { 0x8e38e38e38e38e39ULL, 0xe38e38e38e38e38eULL, },
+ { 0x5555555555555556ULL, 0x5555555555555556ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaabULL, 0xaaaaaaaaaaaaaaabULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8888888888888889ULL, 0x8888888888888889ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x71c71c71c71c71c7ULL, 0x1c71c71c71c71c72ULL, },
+ { 0x38e38e38e38e38e4ULL, 0x8e38e38e38e38e39ULL, },
+ { 0xcccccccccccccccdULL, 0xcccccccccccccccdULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xe93e93e93e93e93eULL, 0x93e93e93e93e93e9ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x3333333333333334ULL, 0x3333333333333334ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8888888888888889ULL, 0x8888888888888889ULL, },
+ { 0xdddddddddddddddeULL, 0xdddddddddddddddeULL, },
+ { 0x6666666666666667ULL, 0x6666666666666667ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4fa4fa4fa4fa4fa5ULL, 0xfa4fa4fa4fa4fa50ULL, },
+ { 0x16c16c16c16c16c2ULL, 0x6c16c16c16c16c17ULL, },
+ { 0xe38e38e38e38e38fULL, 0x38e38e38e38e38e4ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x38e38e38e38e38e4ULL, 0x8e38e38e38e38e39ULL, },
+ { 0x8e38e38e38e38e39ULL, 0xe38e38e38e38e38eULL, },
+ { 0x16c16c16c16c16c2ULL, 0x6c16c16c16c16c17ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc71c71c71c71c71dULL, 0x71c71c71c71c71c7ULL, },
+ { 0x1c71c71c71c71c72ULL, 0xc71c71c71c71c71dULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x71c71c71c71c71c7ULL, 0x1c71c71c71c71c72ULL, },
+ { 0xc71c71c71c71c71cULL, 0x71c71c71c71c71c7ULL, },
+ { 0x4fa4fa4fa4fa4fa5ULL, 0xfa4fa4fa4fa4fa50ULL, },
+ { 0xe93e93e93e93e93eULL, 0x93e93e93e93e93e9ULL, },
+ { 0x38e38e38e38e38e3ULL, 0x8e38e38e38e38e39ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 64 */
+ { 0x8cace668dace8e38ULL, 0x386f5044e93c5d10ULL, },
+ { 0xdc1038216e92c9c0ULL, 0x238e445f53508af8ULL, },
+ { 0x181bd07eca3072f2ULL, 0xbd7582865538cd6cULL, },
+ { 0x73531997253171c8ULL, 0xc790afbb16c3a2f0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4f6351b893c43b88ULL, 0xeb1ef41a6a142de8ULL, },
+ { 0x8b6eea15ef61e4baULL, 0x850632416bfc705cULL, },
+ { 0x23efc7de916d3640ULL, 0xdc71bba0acaf7508ULL, }, /* 72 */
+ { 0xb09cae476c3bc478ULL, 0x14e10be595ebd218ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3c0b985d5b9da932ULL, 0x99e73e2701e84274ULL, },
+ { 0xe7e42f8135cf8d0eULL, 0x428a7d79aac73294ULL, },
+ { 0x749115ea109e1b46ULL, 0x7af9cdbe94038fa4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBV_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBV_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subv_h.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subv_h.c
new file mode 100644
index 0000000000..420422ecf1
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subv_h.c
@@ -0,0 +1,151 @@
+/*
+ * Test program for MSA instruction SUBV.H
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBV.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5556555655565556ULL, 0x5556555655565556ULL, },
+ { 0xaaabaaabaaabaaabULL, 0xaaabaaabaaabaaabULL, },
+ { 0x3334333433343334ULL, 0x3334333433343334ULL, },
+ { 0xcccdcccdcccdcccdULL, 0xcccdcccdcccdcccdULL, },
+ { 0x1c72c71d71c81c72ULL, 0xc71d71c81c72c71dULL, },
+ { 0xe38f38e48e39e38fULL, 0x38e48e39e38f38e4ULL, },
+ { 0xaaabaaabaaabaaabULL, 0xaaabaaabaaabaaabULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xdddedddedddedddeULL, 0xdddedddedddedddeULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0xc71c71c71c72c71cULL, 0x71c71c72c71c71c7ULL, },
+ { 0x8e39e38e38e38e39ULL, 0xe38e38e38e39e38eULL, },
+ { 0x5556555655565556ULL, 0x5556555655565556ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaabaaabaaabaaabULL, 0xaaabaaabaaabaaabULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8889888988898889ULL, 0x8889888988898889ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x71c71c72c71d71c7ULL, 0x1c72c71d71c71c72ULL, },
+ { 0x38e48e39e38e38e4ULL, 0x8e39e38e38e48e39ULL, },
+ { 0xcccdcccdcccdcccdULL, 0xcccdcccdcccdcccdULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xe93e93e93e94e93eULL, 0x93e93e94e93e93e9ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x3334333433343334ULL, 0x3334333433343334ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8889888988898889ULL, 0x8889888988898889ULL, },
+ { 0xdddedddedddedddeULL, 0xdddedddedddedddeULL, },
+ { 0x6667666766676667ULL, 0x6667666766676667ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4fa5fa50a4fb4fa5ULL, 0xfa50a4fb4fa5fa50ULL, },
+ { 0x16c26c17c16c16c2ULL, 0x6c17c16c16c26c17ULL, },
+ { 0xe38f38e48e39e38fULL, 0x38e48e39e38f38e4ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x38e48e39e38e38e4ULL, 0x8e39e38e38e48e39ULL, },
+ { 0x8e39e38e38e38e39ULL, 0xe38e38e38e39e38eULL, },
+ { 0x16c26c17c16c16c2ULL, 0x6c17c16c16c26c17ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc71d71c71c71c71dULL, 0x71c71c71c71d71c7ULL, },
+ { 0x1c72c71d71c81c72ULL, 0xc71d71c81c72c71dULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x71c71c72c71d71c7ULL, 0x1c72c71d71c71c72ULL, },
+ { 0xc71c71c71c72c71cULL, 0x71c71c72c71c71c7ULL, },
+ { 0x4fa5fa50a4fb4fa5ULL, 0xfa50a4fb4fa5fa50ULL, },
+ { 0xe93e93e93e94e93eULL, 0x93e93e94e93e93e9ULL, },
+ { 0x38e38e39e38f38e3ULL, 0x8e39e38f38e38e39ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 64 */
+ { 0x8cace669dacf8e38ULL, 0x38705044e93c5d10ULL, },
+ { 0xdc1038226e93c9c0ULL, 0x238f445f53508af8ULL, },
+ { 0x181bd07fca3172f2ULL, 0xbd7682865539cd6cULL, },
+ { 0x73541997253171c8ULL, 0xc790afbc16c4a2f0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4f6451b993c43b88ULL, 0xeb1ff41b6a142de8ULL, },
+ { 0x8b6fea16ef62e4baULL, 0x850632426bfd705cULL, },
+ { 0x23f0c7de916d3640ULL, 0xdc71bba1acb07508ULL, }, /* 72 */
+ { 0xb09cae476c3cc478ULL, 0x14e10be595ecd218ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3c0b985d5b9ea932ULL, 0x99e73e2701e94274ULL, },
+ { 0xe7e52f8135cf8d0eULL, 0x428a7d7aaac73294ULL, },
+ { 0x749115ea109e1b46ULL, 0x7afacdbe94038fa4ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBV_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBV_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subv_w.c b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subv_w.c
new file mode 100644
index 0000000000..3e97005815
--- /dev/null
+++ b/tests/tcg/mips/user/ase/msa/int-subtract/test_msa_subv_w.c
@@ -0,0 +1,153 @@
+/*
+ * Test program for MSA instruction SUBV.W
+ *
+ * Copyright (C) 2018 Wave Computing, Inc.
+ * Copyright (C) 2018 Mateja Marjanovic <mateja.marjanovic@rt-rk.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs.h"
+#include "../../../../include/test_utils.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *instruction_name = "SUBV.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555655555556ULL, 0x5555555655555556ULL, },
+ { 0xaaaaaaabaaaaaaabULL, 0xaaaaaaabaaaaaaabULL, },
+ { 0x3333333433333334ULL, 0x3333333433333334ULL, },
+ { 0xcccccccdcccccccdULL, 0xcccccccdcccccccdULL, },
+ { 0x1c71c71d71c71c72ULL, 0xc71c71c81c71c71dULL, },
+ { 0xe38e38e48e38e38fULL, 0x38e38e39e38e38e4ULL, },
+ { 0xaaaaaaabaaaaaaabULL, 0xaaaaaaabaaaaaaabULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xdddddddedddddddeULL, 0xdddddddedddddddeULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0xc71c71c71c71c71cULL, 0x71c71c72c71c71c7ULL, },
+ { 0x8e38e38e38e38e39ULL, 0xe38e38e38e38e38eULL, },
+ { 0x5555555655555556ULL, 0x5555555655555556ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xaaaaaaabaaaaaaabULL, 0xaaaaaaabaaaaaaabULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8888888988888889ULL, 0x8888888988888889ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x71c71c72c71c71c7ULL, 0x1c71c71d71c71c72ULL, },
+ { 0x38e38e39e38e38e4ULL, 0x8e38e38e38e38e39ULL, },
+ { 0xcccccccdcccccccdULL, 0xcccccccdcccccccdULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x7777777777777777ULL, 0x7777777777777777ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x9999999999999999ULL, 0x9999999999999999ULL, },
+ { 0xe93e93e93e93e93eULL, 0x93e93e94e93e93e9ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x3333333433333334ULL, 0x3333333433333334ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x8888888988888889ULL, 0x8888888988888889ULL, },
+ { 0xdddddddedddddddeULL, 0xdddddddedddddddeULL, },
+ { 0x6666666766666667ULL, 0x6666666766666667ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4fa4fa50a4fa4fa5ULL, 0xfa4fa4fb4fa4fa50ULL, },
+ { 0x16c16c17c16c16c2ULL, 0x6c16c16c16c16c17ULL, },
+ { 0xe38e38e48e38e38fULL, 0x38e38e39e38e38e4ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x38e38e39e38e38e4ULL, 0x8e38e38e38e38e39ULL, },
+ { 0x8e38e38e38e38e39ULL, 0xe38e38e38e38e38eULL, },
+ { 0x16c16c17c16c16c2ULL, 0x6c16c16c16c16c17ULL, },
+ { 0xb05b05b05b05b05bULL, 0x05b05b05b05b05b0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xc71c71c71c71c71dULL, 0x71c71c71c71c71c7ULL, },
+ { 0x1c71c71d71c71c72ULL, 0xc71c71c81c71c71dULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x71c71c72c71c71c7ULL, 0x1c71c71d71c71c72ULL, },
+ { 0xc71c71c71c71c71cULL, 0x71c71c72c71c71c7ULL, },
+ { 0x4fa4fa50a4fa4fa5ULL, 0xfa4fa4fb4fa4fa50ULL, },
+ { 0xe93e93e93e93e93eULL, 0x93e93e94e93e93e9ULL, },
+ { 0x38e38e39e38e38e3ULL, 0x8e38e38f38e38e39ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 64 */
+ { 0x8cace669dace8e38ULL, 0x386f5044e93c5d10ULL, },
+ { 0xdc1038226e92c9c0ULL, 0x238e445f53508af8ULL, },
+ { 0x181bd07fca3072f2ULL, 0xbd7582865538cd6cULL, },
+ { 0x73531997253171c8ULL, 0xc790afbc16c3a2f0ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4f6351b993c43b88ULL, 0xeb1ef41b6a142de8ULL, },
+ { 0x8b6eea16ef61e4baULL, 0x850632426bfc705cULL, },
+ { 0x23efc7de916d3640ULL, 0xdc71bba1acaf7508ULL, }, /* 72 */
+ { 0xb09cae476c3bc478ULL, 0x14e10be595ebd218ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3c0b985d5b9da932ULL, 0x99e73e2701e84274ULL, },
+ { 0xe7e42f8135cf8d0eULL, 0x428a7d7aaac73294ULL, },
+ { 0x749115ea109e1b46ULL, 0x7af9cdbe94038fa4ULL, },
+ { 0xc3f467a3a46256ceULL, 0x6618c1d9fe17bd8cULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+};
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBV_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_SUBV_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results(instruction_name, TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_b.c b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_b.c
index 5cf862756a..d720dc30a5 100644
--- a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_b.c
+++ b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction ILVEV.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_d.c b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_d.c
index d3600e96b4..83239949af 100644
--- a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_d.c
+++ b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction ILVEV.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_h.c b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_h.c
index 9a80fac8eb..3f6fc265d2 100644
--- a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_h.c
+++ b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction ILVEV.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_w.c b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_w.c
index 8f62d4700a..30d2e3802d 100644
--- a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_w.c
+++ b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvev_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction ILVEV.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_b.c b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_b.c
index f7e6dc0503..c771287a71 100644
--- a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_b.c
+++ b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction ILVL.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_d.c b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_d.c
index 0f4c048ff6..b7d5fcdc18 100644
--- a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_d.c
+++ b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction ILVL.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_h.c b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_h.c
index 6c1c6d9f36..af72876236 100644
--- a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_h.c
+++ b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction ILVL.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_w.c b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_w.c
index d22d96558d..e06c9d94ca 100644
--- a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_w.c
+++ b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvl_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction ILVL.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_b.c b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_b.c
index c55f3a4d7d..8e7f1c4706 100644
--- a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_b.c
+++ b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction ILVOD.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_d.c b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_d.c
index d03e7b4eca..acbd94a68d 100644
--- a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_d.c
+++ b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction ILVOD.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_h.c b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_h.c
index f64d8b5fc9..8a82def407 100644
--- a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_h.c
+++ b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction ILVOD.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_w.c b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_w.c
index 4ae75f85f8..e19170c364 100644
--- a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_w.c
+++ b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvod_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction ILVOD.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_b.c b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_b.c
index f2cc7bf414..1e519e6e9e 100644
--- a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_b.c
+++ b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction ILVR.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_d.c b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_d.c
index f5ff947c0b..be760430c7 100644
--- a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_d.c
+++ b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction ILVR.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_h.c b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_h.c
index 5a2986dca6..cbd4685eca 100644
--- a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_h.c
+++ b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction ILVR.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_w.c b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_w.c
index fa0d6ea900..5f4cfd0377 100644
--- a/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_w.c
+++ b/tests/tcg/mips/user/ase/msa/interleave/test_msa_ilvr_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction ILVR.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/logic/test_msa_and_v.c b/tests/tcg/mips/user/ase/msa/logic/test_msa_and_v.c
index 51b256fa50..534c4201a8 100644
--- a/tests/tcg/mips/user/ase/msa/logic/test_msa_and_v.c
+++ b/tests/tcg/mips/user/ase/msa/logic/test_msa_and_v.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction AND.V
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/logic/test_msa_nor_v.c b/tests/tcg/mips/user/ase/msa/logic/test_msa_nor_v.c
index 90ca19843c..f781a8bb9d 100644
--- a/tests/tcg/mips/user/ase/msa/logic/test_msa_nor_v.c
+++ b/tests/tcg/mips/user/ase/msa/logic/test_msa_nor_v.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction NOR.V
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/logic/test_msa_or_v.c b/tests/tcg/mips/user/ase/msa/logic/test_msa_or_v.c
index 4ad5366dfb..924f216e41 100644
--- a/tests/tcg/mips/user/ase/msa/logic/test_msa_or_v.c
+++ b/tests/tcg/mips/user/ase/msa/logic/test_msa_or_v.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction OR.V
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/logic/test_msa_xor_v.c b/tests/tcg/mips/user/ase/msa/logic/test_msa_xor_v.c
index 54effeda63..f0442e6577 100644
--- a/tests/tcg/mips/user/ase/msa/logic/test_msa_xor_v.c
+++ b/tests/tcg/mips/user/ase/msa/logic/test_msa_xor_v.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction XOR.V
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_b.c b/tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_b.c
index d98dd224d7..409773d7f2 100644
--- a/tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_b.c
+++ b/tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction PCKEV.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_d.c b/tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_d.c
index 543fb6ae5e..8e89716416 100644
--- a/tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_d.c
+++ b/tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction PCKEV.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_h.c b/tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_h.c
index 64a18c02f0..b389587dfe 100644
--- a/tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_h.c
+++ b/tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction PCKEV.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_w.c b/tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_w.c
index a0acacdf26..d393ad5066 100644
--- a/tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_w.c
+++ b/tests/tcg/mips/user/ase/msa/pack/test_msa_pckev_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction PCKEV.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_b.c b/tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_b.c
index 7bf86fccbd..ab363a0cdc 100644
--- a/tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_b.c
+++ b/tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction PCKOD.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_d.c b/tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_d.c
index 3c4d55b694..09a61408bc 100644
--- a/tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_d.c
+++ b/tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction PCKOD.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_h.c b/tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_h.c
index 5c3c529f22..d7a8c5b5af 100644
--- a/tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_h.c
+++ b/tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction PCKOD.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_w.c b/tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_w.c
index 9275890214..4b732d0359 100644
--- a/tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_w.c
+++ b/tests/tcg/mips/user/ase/msa/pack/test_msa_pckod_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction PCKOD.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_b.c b/tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_b.c
index fcf857a6c0..d9ccf575fa 100644
--- a/tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_b.c
+++ b/tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_b.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction VSHF.B
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_d.c b/tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_d.c
index 700c1596a2..6c555fbb23 100644
--- a/tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_d.c
+++ b/tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_d.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction VSHF.D
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_h.c b/tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_h.c
index 3d6c1dc5be..9dfcb51fe5 100644
--- a/tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_h.c
+++ b/tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_h.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction VSHF.H
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_w.c b/tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_w.c
index 6030762855..97074c0924 100644
--- a/tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_w.c
+++ b/tests/tcg/mips/user/ase/msa/pack/test_msa_vshf_w.c
@@ -1,8 +1,8 @@
/*
* Test program for MSA instruction VSHF.W
*
- * Copyright (C) 2018 Wave Computing, Inc.
- * Copyright (C) 2018 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.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
@@ -23,8 +23,8 @@
#include <stdint.h>
#include "../../../../include/wrappers_msa.h"
-#include "../../../../include/test_inputs.h"
-#include "../../../../include/test_utils.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
#define TEST_COUNT_TOTAL ( \
(PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
diff --git a/tests/test-qgraph.c b/tests/test-qgraph.c
index f6a6565e31..5c7e457075 100644
--- a/tests/test-qgraph.c
+++ b/tests/test-qgraph.c
@@ -122,7 +122,7 @@ static void check_driver(const char *driver)
static void check_test(const char *test, const char *interface)
{
QOSGraphEdge *edge;
- const char *full_name = g_strdup_printf("%s-tests/%s", interface, test);
+ char *full_name = g_strdup_printf("%s-tests/%s", interface, test);
qos_add_test(test, interface, testfunct, NULL);
g_assert_cmpint(qos_graph_has_machine(test), ==, FALSE);
@@ -138,6 +138,7 @@ static void check_test(const char *test, const char *interface)
g_assert_cmpint(qos_graph_get_node_availability(full_name), ==, TRUE);
qos_graph_node_set_availability(full_name, FALSE);
g_assert_cmpint(qos_graph_get_node_availability(full_name), ==, FALSE);
+ g_free(full_name);
}
static void count_each_test(QOSGraphNode *path, int len)
diff --git a/thunk.c b/thunk.c
index 17f3d320bb..7f31cffe09 100644
--- a/thunk.c
+++ b/thunk.c
@@ -86,7 +86,7 @@ void thunk_register_struct(int id, const char *name, const argtype *types)
#endif
/* now we can alloc the data */
- for(i = 0;i < 2; i++) {
+ for (i = 0; i < ARRAY_SIZE(se->field_offsets); i++) {
offset = 0;
max_align = 1;
se->field_offsets[i] = g_new(int, nb_fields);
diff --git a/trace/Makefile.objs b/trace/Makefile.objs
index afd571c3ec..c544509adf 100644
--- a/trace/Makefile.objs
+++ b/trace/Makefile.objs
@@ -36,7 +36,7 @@ $(obj)/generated-helpers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/conf
$(obj)/generated-helpers.o: $(obj)/generated-helpers.c
-target-obj-y += generated-helpers.o
+obj-y += generated-helpers.o
$(obj)/generated-tcg-tracers.h: $(obj)/generated-tcg-tracers.h-timestamp
@@ -55,5 +55,5 @@ $(obj)/generated-tcg-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/
util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o
util-obj-$(CONFIG_TRACE_FTRACE) += ftrace.o
util-obj-y += control.o
-target-obj-y += control-target.o
+obj-y += control-target.o
util-obj-y += qmp.o
diff --git a/ui/curses.c b/ui/curses.c
index 6e0091c3b2..37954ce1b0 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -42,6 +42,12 @@
#define FONT_HEIGHT 16
#define FONT_WIDTH 8
+enum maybe_keycode {
+ CURSES_KEYCODE,
+ CURSES_CHAR,
+ CURSES_CHAR_OR_KEYCODE,
+};
+
static DisplayChangeListener *dcl;
static console_ch_t screen[160 * 100];
static WINDOW *screenpad = NULL;
@@ -194,9 +200,54 @@ static void curses_cursor_position(DisplayChangeListener *dcl,
static kbd_layout_t *kbd_layout = NULL;
+static wint_t console_getch(enum maybe_keycode *maybe_keycode)
+{
+ wint_t ret;
+ switch (get_wch(&ret)) {
+ case KEY_CODE_YES:
+ *maybe_keycode = CURSES_KEYCODE;
+ break;
+ case OK:
+ *maybe_keycode = CURSES_CHAR;
+ break;
+ case ERR:
+ ret = -1;
+ break;
+ }
+ return ret;
+}
+
+static int curses2foo(const int _curses2foo[], const int _curseskey2foo[],
+ int chr, enum maybe_keycode maybe_keycode)
+{
+ int ret = -1;
+ if (maybe_keycode == CURSES_CHAR) {
+ if (chr < CURSES_CHARS) {
+ ret = _curses2foo[chr];
+ }
+ } else {
+ if (chr < CURSES_KEYS) {
+ ret = _curseskey2foo[chr];
+ }
+ if (ret == -1 && maybe_keycode == CURSES_CHAR_OR_KEYCODE &&
+ chr < CURSES_CHARS) {
+ ret = _curses2foo[chr];
+ }
+ }
+ return ret;
+}
+
+#define curses2keycode(chr, maybe_keycode) \
+ curses2foo(_curses2keycode, _curseskey2keycode, chr, maybe_keycode)
+#define curses2keysym(chr, maybe_keycode) \
+ curses2foo(_curses2keysym, _curseskey2keysym, chr, maybe_keycode)
+#define curses2qemu(chr, maybe_keycode) \
+ curses2foo(_curses2qemu, _curseskey2qemu, chr, maybe_keycode)
+
static void curses_refresh(DisplayChangeListener *dcl)
{
int chr, keysym, keycode, keycode_alt;
+ enum maybe_keycode maybe_keycode;
curses_winch_check();
@@ -212,14 +263,14 @@ static void curses_refresh(DisplayChangeListener *dcl)
while (1) {
/* while there are any pending key strokes to process */
- chr = getch();
+ chr = console_getch(&maybe_keycode);
- if (chr == ERR)
+ if (chr == -1)
break;
#ifdef KEY_RESIZE
/* this shouldn't occur when we use a custom SIGWINCH handler */
- if (chr == KEY_RESIZE) {
+ if (maybe_keycode != CURSES_CHAR && chr == KEY_RESIZE) {
clear();
refresh();
curses_calc_pad();
@@ -228,17 +279,19 @@ static void curses_refresh(DisplayChangeListener *dcl)
}
#endif
- keycode = curses2keycode[chr];
+ keycode = curses2keycode(chr, maybe_keycode);
keycode_alt = 0;
- /* alt key */
+ /* alt or esc key */
if (keycode == 1) {
- int nextchr = getch();
+ enum maybe_keycode next_maybe_keycode;
+ int nextchr = console_getch(&next_maybe_keycode);
- if (nextchr != ERR) {
+ if (nextchr != -1) {
chr = nextchr;
+ maybe_keycode = next_maybe_keycode;
keycode_alt = ALT;
- keycode = curses2keycode[chr];
+ keycode = curses2keycode(chr, maybe_keycode);
if (keycode != -1) {
keycode |= ALT;
@@ -258,9 +311,7 @@ static void curses_refresh(DisplayChangeListener *dcl)
}
if (kbd_layout) {
- keysym = -1;
- if (chr < CURSES_KEYS)
- keysym = curses2keysym[chr];
+ keysym = curses2keysym(chr, maybe_keycode);
if (keysym == -1) {
if (chr < ' ') {
@@ -326,10 +377,7 @@ static void curses_refresh(DisplayChangeListener *dcl)
qemu_input_event_send_key_delay(0);
}
} else {
- keysym = -1;
- if (chr < CURSES_KEYS) {
- keysym = curses2qemu[chr];
- }
+ keysym = curses2qemu(chr, maybe_keycode);
if (keysym == -1)
keysym = chr;
@@ -361,6 +409,7 @@ static void curses_setup(void)
initscr(); noecho(); intrflush(stdscr, FALSE);
nodelay(stdscr, TRUE); nonl(); keypad(stdscr, TRUE);
start_color(); raw(); scrollok(stdscr, FALSE);
+ set_escdelay(25);
/* Make color pair to match color format (3bits bg:3bits fg) */
for (i = 0; i < 64; i++) {
diff --git a/ui/curses_keys.h b/ui/curses_keys.h
index e9195a1671..71e04acdc7 100644
--- a/ui/curses_keys.h
+++ b/ui/curses_keys.h
@@ -49,22 +49,28 @@
/* curses won't detect a Control + Alt + 1, so use Alt + 1 */
#define QEMU_KEY_CONSOLE0 (2 | ALT) /* (curses2keycode['1'] | ALT) */
+#define CURSES_CHARS 0x100 /* Support latin1 only */
#define CURSES_KEYS KEY_MAX /* KEY_MAX defined in <curses.h> */
-static const int curses2keysym[CURSES_KEYS] = {
- [0 ... (CURSES_KEYS - 1)] = -1,
+static const int _curses2keysym[CURSES_CHARS] = {
+ [0 ... (CURSES_CHARS - 1)] = -1,
[0x7f] = KEY_BACKSPACE,
['\r'] = KEY_ENTER,
['\n'] = KEY_ENTER,
[27] = 27,
+};
+
+static const int _curseskey2keysym[CURSES_KEYS] = {
+ [0 ... (CURSES_KEYS - 1)] = -1,
+
[KEY_BTAB] = '\t' | KEYSYM_SHIFT,
[KEY_SPREVIOUS] = KEY_PPAGE | KEYSYM_SHIFT,
[KEY_SNEXT] = KEY_NPAGE | KEYSYM_SHIFT,
};
-static const int curses2keycode[CURSES_KEYS] = {
- [0 ... (CURSES_KEYS - 1)] = -1,
+static const int _curses2keycode[CURSES_CHARS] = {
+ [0 ... (CURSES_CHARS - 1)] = -1,
[0x01b] = 1, /* Escape */
['1'] = 2,
@@ -80,7 +86,6 @@ static const int curses2keycode[CURSES_KEYS] = {
['-'] = 12,
['='] = 13,
[0x07f] = 14, /* Backspace */
- [KEY_BACKSPACE] = 14, /* Backspace */
['\t'] = 15, /* Tab */
['q'] = 16,
@@ -97,7 +102,6 @@ static const int curses2keycode[CURSES_KEYS] = {
[']'] = 27,
['\n'] = 28, /* Return */
['\r'] = 28, /* Return */
- [KEY_ENTER] = 28, /* Return */
['a'] = 30,
['s'] = 31,
@@ -126,33 +130,6 @@ static const int curses2keycode[CURSES_KEYS] = {
[' '] = 57,
- [KEY_F(1)] = 59, /* Function Key 1 */
- [KEY_F(2)] = 60, /* Function Key 2 */
- [KEY_F(3)] = 61, /* Function Key 3 */
- [KEY_F(4)] = 62, /* Function Key 4 */
- [KEY_F(5)] = 63, /* Function Key 5 */
- [KEY_F(6)] = 64, /* Function Key 6 */
- [KEY_F(7)] = 65, /* Function Key 7 */
- [KEY_F(8)] = 66, /* Function Key 8 */
- [KEY_F(9)] = 67, /* Function Key 9 */
- [KEY_F(10)] = 68, /* Function Key 10 */
- [KEY_F(11)] = 87, /* Function Key 11 */
- [KEY_F(12)] = 88, /* Function Key 12 */
-
- [KEY_HOME] = 71 | GREY, /* Home */
- [KEY_UP] = 72 | GREY, /* Up Arrow */
- [KEY_PPAGE] = 73 | GREY, /* Page Up */
- [KEY_LEFT] = 75 | GREY, /* Left Arrow */
- [KEY_RIGHT] = 77 | GREY, /* Right Arrow */
- [KEY_END] = 79 | GREY, /* End */
- [KEY_DOWN] = 80 | GREY, /* Down Arrow */
- [KEY_NPAGE] = 81 | GREY, /* Page Down */
- [KEY_IC] = 82 | GREY, /* Insert */
- [KEY_DC] = 83 | GREY, /* Delete */
-
- [KEY_SPREVIOUS] = 73 | GREY | SHIFT, /* Shift + Page Up */
- [KEY_SNEXT] = 81 | GREY | SHIFT, /* Shift + Page Down */
-
['!'] = 2 | SHIFT,
['@'] = 3 | SHIFT,
['#'] = 4 | SHIFT,
@@ -166,7 +143,6 @@ static const int curses2keycode[CURSES_KEYS] = {
['_'] = 12 | SHIFT,
['+'] = 13 | SHIFT,
- [KEY_BTAB] = 15 | SHIFT, /* Shift + Tab */
['Q'] = 16 | SHIFT,
['W'] = 17 | SHIFT,
['E'] = 18 | SHIFT,
@@ -205,19 +181,6 @@ static const int curses2keycode[CURSES_KEYS] = {
['>'] = 52 | SHIFT,
['?'] = 53 | SHIFT,
- [KEY_F(13)] = 59 | SHIFT, /* Shift + Function Key 1 */
- [KEY_F(14)] = 60 | SHIFT, /* Shift + Function Key 2 */
- [KEY_F(15)] = 61 | SHIFT, /* Shift + Function Key 3 */
- [KEY_F(16)] = 62 | SHIFT, /* Shift + Function Key 4 */
- [KEY_F(17)] = 63 | SHIFT, /* Shift + Function Key 5 */
- [KEY_F(18)] = 64 | SHIFT, /* Shift + Function Key 6 */
- [KEY_F(19)] = 65 | SHIFT, /* Shift + Function Key 7 */
- [KEY_F(20)] = 66 | SHIFT, /* Shift + Function Key 8 */
- [KEY_F(21)] = 67 | SHIFT, /* Shift + Function Key 9 */
- [KEY_F(22)] = 68 | SHIFT, /* Shift + Function Key 10 */
- [KEY_F(23)] = 69 | SHIFT, /* Shift + Function Key 11 */
- [KEY_F(24)] = 70 | SHIFT, /* Shift + Function Key 12 */
-
['Q' - '@'] = 16 | CNTRL, /* Control + q */
['W' - '@'] = 17 | CNTRL, /* Control + w */
['E' - '@'] = 18 | CNTRL, /* Control + e */
@@ -249,13 +212,67 @@ static const int curses2keycode[CURSES_KEYS] = {
};
-static const int curses2qemu[CURSES_KEYS] = {
+static const int _curseskey2keycode[CURSES_KEYS] = {
[0 ... (CURSES_KEYS - 1)] = -1,
+ [KEY_BACKSPACE] = 14, /* Backspace */
+
+ [KEY_ENTER] = 28, /* Return */
+
+ [KEY_F(1)] = 59, /* Function Key 1 */
+ [KEY_F(2)] = 60, /* Function Key 2 */
+ [KEY_F(3)] = 61, /* Function Key 3 */
+ [KEY_F(4)] = 62, /* Function Key 4 */
+ [KEY_F(5)] = 63, /* Function Key 5 */
+ [KEY_F(6)] = 64, /* Function Key 6 */
+ [KEY_F(7)] = 65, /* Function Key 7 */
+ [KEY_F(8)] = 66, /* Function Key 8 */
+ [KEY_F(9)] = 67, /* Function Key 9 */
+ [KEY_F(10)] = 68, /* Function Key 10 */
+ [KEY_F(11)] = 87, /* Function Key 11 */
+ [KEY_F(12)] = 88, /* Function Key 12 */
+
+ [KEY_HOME] = 71 | GREY, /* Home */
+ [KEY_UP] = 72 | GREY, /* Up Arrow */
+ [KEY_PPAGE] = 73 | GREY, /* Page Up */
+ [KEY_LEFT] = 75 | GREY, /* Left Arrow */
+ [KEY_RIGHT] = 77 | GREY, /* Right Arrow */
+ [KEY_END] = 79 | GREY, /* End */
+ [KEY_DOWN] = 80 | GREY, /* Down Arrow */
+ [KEY_NPAGE] = 81 | GREY, /* Page Down */
+ [KEY_IC] = 82 | GREY, /* Insert */
+ [KEY_DC] = 83 | GREY, /* Delete */
+
+ [KEY_SPREVIOUS] = 73 | GREY | SHIFT, /* Shift + Page Up */
+ [KEY_SNEXT] = 81 | GREY | SHIFT, /* Shift + Page Down */
+
+ [KEY_BTAB] = 15 | SHIFT, /* Shift + Tab */
+
+ [KEY_F(13)] = 59 | SHIFT, /* Shift + Function Key 1 */
+ [KEY_F(14)] = 60 | SHIFT, /* Shift + Function Key 2 */
+ [KEY_F(15)] = 61 | SHIFT, /* Shift + Function Key 3 */
+ [KEY_F(16)] = 62 | SHIFT, /* Shift + Function Key 4 */
+ [KEY_F(17)] = 63 | SHIFT, /* Shift + Function Key 5 */
+ [KEY_F(18)] = 64 | SHIFT, /* Shift + Function Key 6 */
+ [KEY_F(19)] = 65 | SHIFT, /* Shift + Function Key 7 */
+ [KEY_F(20)] = 66 | SHIFT, /* Shift + Function Key 8 */
+ [KEY_F(21)] = 67 | SHIFT, /* Shift + Function Key 9 */
+ [KEY_F(22)] = 68 | SHIFT, /* Shift + Function Key 10 */
+ [KEY_F(23)] = 69 | SHIFT, /* Shift + Function Key 11 */
+ [KEY_F(24)] = 70 | SHIFT, /* Shift + Function Key 12 */
+};
+
+static const int _curses2qemu[CURSES_CHARS] = {
+ [0 ... (CURSES_CHARS - 1)] = -1,
+
['\n'] = '\n',
['\r'] = '\n',
[0x07f] = QEMU_KEY_BACKSPACE,
+};
+
+static const int _curseskey2qemu[CURSES_KEYS] = {
+ [0 ... (CURSES_KEYS - 1)] = -1,
[KEY_DOWN] = QEMU_KEY_DOWN,
[KEY_UP] = QEMU_KEY_UP,
diff --git a/ui/vnc.c b/ui/vnc.c
index da4a21d4ce..2d9e8f43b0 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -700,6 +700,12 @@ static void vnc_abort_display_jobs(VncDisplay *vd)
}
QTAILQ_FOREACH(vs, &vd->clients, next) {
vnc_lock_output(vs);
+ if (vs->update == VNC_STATE_UPDATE_NONE &&
+ vs->job_update != VNC_STATE_UPDATE_NONE) {
+ /* job aborted before completion */
+ vs->update = vs->job_update;
+ vs->job_update = VNC_STATE_UPDATE_NONE;
+ }
vs->abort = false;
vnc_unlock_output(vs);
}
@@ -3358,6 +3364,12 @@ static QemuOptsList qemu_vnc_opts = {
.name = "acl",
.type = QEMU_OPT_BOOL,
},{
+ .name = "tls-authz",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "sasl-authz",
+ .type = QEMU_OPT_STRING,
+ },{
.name = "lossy",
.type = QEMU_OPT_BOOL,
},{
@@ -3796,6 +3808,8 @@ void vnc_display_open(const char *id, Error **errp)
const char *credid;
bool sasl = false;
int acl = 0;
+ const char *tlsauthz;
+ const char *saslauthz;
int lock_key_sync = 1;
int key_delay_ms;
@@ -3867,7 +3881,33 @@ void vnc_display_open(const char *id, Error **errp)
goto fail;
}
}
+ if (qemu_opt_get(opts, "acl")) {
+ error_report("The 'acl' option to -vnc is deprecated. "
+ "Please use the 'tls-authz' and 'sasl-authz' "
+ "options instead");
+ }
acl = qemu_opt_get_bool(opts, "acl", false);
+ tlsauthz = qemu_opt_get(opts, "tls-authz");
+ if (acl && tlsauthz) {
+ error_setg(errp, "'acl' option is mutually exclusive with the "
+ "'tls-authz' option");
+ goto fail;
+ }
+ if (tlsauthz && !vd->tlscreds) {
+ error_setg(errp, "'tls-authz' provided but TLS is not enabled");
+ goto fail;
+ }
+
+ saslauthz = qemu_opt_get(opts, "sasl-authz");
+ if (acl && saslauthz) {
+ error_setg(errp, "'acl' option is mutually exclusive with the "
+ "'sasl-authz' option");
+ goto fail;
+ }
+ if (saslauthz && !sasl) {
+ error_setg(errp, "'sasl-authz' provided but SASL auth is not enabled");
+ goto fail;
+ }
share = qemu_opt_get(opts, "share");
if (share) {
@@ -3897,7 +3937,9 @@ void vnc_display_open(const char *id, Error **errp)
vd->non_adaptive = true;
}
- if (acl) {
+ if (tlsauthz) {
+ vd->tlsauthzid = g_strdup(tlsauthz);
+ } else if (acl) {
if (strcmp(vd->id, "default") == 0) {
vd->tlsauthzid = g_strdup("vnc.x509dname");
} else {
@@ -3908,15 +3950,19 @@ void vnc_display_open(const char *id, Error **errp)
&error_abort));
}
#ifdef CONFIG_VNC_SASL
- if (acl && sasl) {
- if (strcmp(vd->id, "default") == 0) {
- vd->sasl.authzid = g_strdup("vnc.username");
- } else {
- vd->sasl.authzid = g_strdup_printf("vnc.%s.username", vd->id);
+ if (sasl) {
+ if (saslauthz) {
+ vd->sasl.authzid = g_strdup(saslauthz);
+ } else if (acl) {
+ if (strcmp(vd->id, "default") == 0) {
+ vd->sasl.authzid = g_strdup("vnc.username");
+ } else {
+ vd->sasl.authzid = g_strdup_printf("vnc.%s.username", vd->id);
+ }
+ vd->sasl.authz = QAUTHZ(qauthz_list_new(vd->sasl.authzid,
+ QAUTHZ_LIST_POLICY_DENY,
+ &error_abort));
}
- vd->sasl.authz = QAUTHZ(qauthz_list_new(vd->sasl.authzid,
- QAUTHZ_LIST_POLICY_DENY,
- &error_abort));
}
#endif
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 10d90d1783..88dda9cd39 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -244,7 +244,19 @@ void qemu_set_nonblock(int fd)
f = fcntl(fd, F_GETFL);
assert(f != -1);
f = fcntl(fd, F_SETFL, f | O_NONBLOCK);
+#ifdef __OpenBSD__
+ if (f == -1) {
+ /*
+ * Previous to OpenBSD 6.3, fcntl(F_SETFL) is not permitted on
+ * memory devices and sets errno to ENODEV.
+ * It's OK if we fail to set O_NONBLOCK on devices like /dev/null,
+ * because they will never block anyway.
+ */
+ assert(errno == ENODEV);
+ }
+#else
assert(f != -1);
+#endif
}
int socket_set_fast_reuse(int fd)
diff --git a/vl.c b/vl.c
index 4a350de5cd..5616208ea0 100644
--- a/vl.c
+++ b/vl.c
@@ -185,7 +185,6 @@ const char *prom_envs[MAX_PROM_ENVS];
int boot_menu;
bool boot_strict;
uint8_t *boot_splash_filedata;
-size_t boot_splash_filedata_size;
bool wakeup_suspend_enabled;
int icount_align_option;
@@ -237,6 +236,7 @@ static struct {
{ .driver = "vmware-svga", .flag = &default_vga },
{ .driver = "qxl-vga", .flag = &default_vga },
{ .driver = "virtio-vga", .flag = &default_vga },
+ { .driver = "ati-vga", .flag = &default_vga },
};
static QemuOptsList qemu_rtc_opts = {
@@ -1190,6 +1190,55 @@ static void default_drive(int enable, int snapshot, BlockInterfaceType type,
}
+typedef struct BlockdevOptionsQueueEntry {
+ BlockdevOptions *bdo;
+ Location loc;
+ QSIMPLEQ_ENTRY(BlockdevOptionsQueueEntry) entry;
+} BlockdevOptionsQueueEntry;
+
+typedef QSIMPLEQ_HEAD(, BlockdevOptionsQueueEntry) BlockdevOptionsQueue;
+
+static void configure_blockdev(BlockdevOptionsQueue *bdo_queue,
+ MachineClass *machine_class, int snapshot)
+{
+ /*
+ * If the currently selected machine wishes to override the
+ * units-per-bus property of its default HBA interface type, do so
+ * now.
+ */
+ if (machine_class->units_per_default_bus) {
+ override_max_devs(machine_class->block_default_type,
+ machine_class->units_per_default_bus);
+ }
+
+ /* open the virtual block devices */
+ while (!QSIMPLEQ_EMPTY(bdo_queue)) {
+ BlockdevOptionsQueueEntry *bdo = QSIMPLEQ_FIRST(bdo_queue);
+
+ QSIMPLEQ_REMOVE_HEAD(bdo_queue, entry);
+ loc_push_restore(&bdo->loc);
+ qmp_blockdev_add(bdo->bdo, &error_fatal);
+ loc_pop(&bdo->loc);
+ qapi_free_BlockdevOptions(bdo->bdo);
+ g_free(bdo);
+ }
+ if (snapshot || replay_mode != REPLAY_MODE_NONE) {
+ qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot,
+ NULL, NULL);
+ }
+ if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func,
+ &machine_class->block_default_type, &error_fatal)) {
+ /* We printed help */
+ exit(0);
+ }
+
+ default_drive(default_cdrom, snapshot, machine_class->block_default_type, 2,
+ CDROM_OPTS);
+ default_drive(default_floppy, snapshot, IF_FLOPPY, 0, FD_OPTS);
+ default_drive(default_sdcard, snapshot, IF_SD, 0, SD_OPTS);
+
+}
+
static QemuOptsList qemu_smp_opts = {
.name = "smp-opts",
.implied_opt_name = "cpus",
@@ -2936,17 +2985,6 @@ static void user_register_global_props(void)
global_init_func, NULL, NULL);
}
-/*
- * Note: we should see that these properties are actually having a
- * priority: accel < machine < user. This means e.g. when user
- * specifies something in "-global", it'll always be used with highest
- * priority than either machine/accelerator compat properties.
- */
-static void register_global_properties(MachineState *ms)
-{
- user_register_global_props();
-}
-
int main(int argc, char **argv, char **envp)
{
int i;
@@ -2981,13 +3019,7 @@ int main(int argc, char **argv, char **envp)
Error *err = NULL;
bool list_data_dirs = false;
char *dir, **dirs;
- typedef struct BlockdevOptions_queue {
- BlockdevOptions *bdo;
- Location loc;
- QSIMPLEQ_ENTRY(BlockdevOptions_queue) entry;
- } BlockdevOptions_queue;
- QSIMPLEQ_HEAD(, BlockdevOptions_queue) bdo_queue
- = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
+ BlockdevOptionsQueue bdo_queue = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
module_call_init(MODULE_INIT_TRACE);
@@ -3111,12 +3143,12 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_blockdev:
{
Visitor *v;
- BlockdevOptions_queue *bdo;
+ BlockdevOptionsQueueEntry *bdo;
v = qobject_input_visitor_new_str(optarg, "driver",
&error_fatal);
- bdo = g_new(BlockdevOptions_queue, 1);
+ bdo = g_new(BlockdevOptionsQueueEntry, 1);
visit_type_BlockdevOptions(v, NULL, &bdo->bdo,
&error_fatal);
visit_free(v);
@@ -3941,6 +3973,8 @@ int main(int argc, char **argv, char **envp)
*/
loc_set_none();
+ user_register_global_props();
+
replay_configure(icount_opts);
if (incoming && !preconfig_exit_requested) {
@@ -3952,6 +3986,7 @@ int main(int argc, char **argv, char **envp)
configure_rtc(qemu_find_opts_singleton("rtc"));
machine_class = select_machine();
+ object_set_machine_compat_props(machine_class->compat_props);
set_memory_options(&ram_slots, &maxram_size, machine_class);
@@ -3996,6 +4031,10 @@ int main(int argc, char **argv, char **envp)
}
object_property_add_child(object_get_root(), "machine",
OBJECT(current_machine), &error_abort);
+ object_property_add_child(container_get(OBJECT(current_machine),
+ "/unattached"),
+ "sysbus", OBJECT(sysbus_get_default()),
+ NULL);
if (machine_class->minimum_page_bits) {
if (!set_preferred_target_page_bits(machine_class->minimum_page_bits)) {
@@ -4234,6 +4273,13 @@ int main(int argc, char **argv, char **envp)
exit(0);
}
+ /*
+ * Note: we need to create block backends before
+ * machine_set_property(), so machine properties can refer to
+ * them.
+ */
+ configure_blockdev(&bdo_queue, machine_class, snapshot);
+
machine_opts = qemu_get_machine_opts();
qemu_opt_foreach(machine_opts, machine_set_property, current_machine,
&error_fatal);
@@ -4249,12 +4295,6 @@ int main(int argc, char **argv, char **envp)
}
/*
- * Register all the global properties, including accel properties,
- * machine properties, and user-specified ones.
- */
- register_global_properties(current_machine);
-
- /*
* Migration object can only be created after global properties
* are applied correctly.
*/
@@ -4366,39 +4406,6 @@ int main(int argc, char **argv, char **envp)
ram_mig_init();
dirty_bitmap_mig_init();
- /* If the currently selected machine wishes to override the units-per-bus
- * property of its default HBA interface type, do so now. */
- if (machine_class->units_per_default_bus) {
- override_max_devs(machine_class->block_default_type,
- machine_class->units_per_default_bus);
- }
-
- /* open the virtual block devices */
- while (!QSIMPLEQ_EMPTY(&bdo_queue)) {
- BlockdevOptions_queue *bdo = QSIMPLEQ_FIRST(&bdo_queue);
-
- QSIMPLEQ_REMOVE_HEAD(&bdo_queue, entry);
- loc_push_restore(&bdo->loc);
- qmp_blockdev_add(bdo->bdo, &error_fatal);
- loc_pop(&bdo->loc);
- qapi_free_BlockdevOptions(bdo->bdo);
- g_free(bdo);
- }
- if (snapshot || replay_mode != REPLAY_MODE_NONE) {
- qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot,
- NULL, NULL);
- }
- if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func,
- &machine_class->block_default_type, &error_fatal)) {
- /* We printed help */
- exit(0);
- }
-
- default_drive(default_cdrom, snapshot, machine_class->block_default_type, 2,
- CDROM_OPTS);
- default_drive(default_floppy, snapshot, IF_FLOPPY, 0, FD_OPTS);
- default_drive(default_sdcard, snapshot, IF_SD, 0, SD_OPTS);
-
qemu_opts_foreach(qemu_find_opts("mon"),
mon_init_func, NULL, &error_fatal);