diff options
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, },{ @@ -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 ## @@ -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; @@ -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; @@ -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 Binary files differindex 25537f8fe3..732660f348 100644 --- a/pc-bios/u-boot.e500 +++ b/pc-bios/u-boot.e500 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 @@ -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) @@ -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, @@ -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) @@ -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); |