qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20200605' into staging

target-arm queue:
hw/ssi/imx_spi: Handle tx burst lengths other than 8 correctly
hw/input/pxa2xx_keypad: Replace hw_error() by qemu_log_mask()
hw/arm/pxa2xx: Replace printf() call by qemu_log_mask()
target/arm: Convert crypto insns to gvec
hw/adc/stm32f2xx_adc: Correct memory region size and access size
tests/acceptance: Add a boot test for the xlnx-versal-virt machine
docs/system: Document Aspeed boards
raspi: Add model of the USB controller
target/arm: Convert 2-reg-and-shift and 1-reg-imm Neon insns to decodetree

# gpg: Signature made Fri 05 Jun 2020 17:48:39 BST
# gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg: issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20200605: (29 commits)
target/arm: Convert Neon one-register-and-immediate insns to decodetree
target/arm: Convert VCVT fixed-point ops to decodetree
target/arm: Convert Neon VSHLL, VMOVL to decodetree
target/arm: Convert Neon narrowing shifts with op==9 to decodetree
target/arm: Convert Neon narrowing shifts with op==8 to decodetree
target/arm: Convert VQSHLU, VQSHL 2-reg-shift insns to decodetree
target/arm: Convert Neon VSRA, VSRI, VRSHR, VRSRA 2-reg-shift insns to decodetree
target/arm: Convert Neon VSHR 2-reg-shift insns to decodetree
target/arm: Convert Neon VSHL and VSLI 2-reg-shift insn to decodetree
raspi2 acceptance test: add test for dwc-hsotg (dwc2) USB host
wire in the dwc-hsotg (dwc2) USB host controller emulation
usb: add short-packet handling to usb-storage driver
dwc-hsotg (dwc2) USB host controller emulation
dwc-hsotg (dwc2) USB host controller state definitions
dwc-hsotg (dwc2) USB host controller register definitions
raspi: add BCM2835 SOC MPHI emulation
docs/system: Document Aspeed boards
tests/acceptance: Add a boot test for the xlnx-versal-virt machine
hw/adc/stm32f2xx_adc: Correct memory region size and access size
target/arm: Split helper_crypto_sm3tt
...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

+4257 -909
+85
docs/system/arm/aspeed.rst
··· 1 + Aspeed family boards (``*-bmc``, ``ast2500-evb``, ``ast2600-evb``) 2 + ================================================================== 3 + 4 + The QEMU Aspeed machines model BMCs of various OpenPOWER systems and 5 + Aspeed evaluation boards. They are based on different releases of the 6 + Aspeed SoC : the AST2400 integrating an ARM926EJ-S CPU (400MHz), the 7 + AST2500 with an ARM1176JZS CPU (800MHz) and more recently the AST2600 8 + with dual cores ARM Cortex A7 CPUs (1.2GHz). 9 + 10 + The SoC comes with RAM, Gigabit ethernet, USB, SD/MMC, USB, SPI, I2C, 11 + etc. 12 + 13 + AST2400 SoC based machines : 14 + 15 + - ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC 16 + 17 + AST2500 SoC based machines : 18 + 19 + - ``ast2500-evb`` Aspeed AST2500 Evaluation board 20 + - ``romulus-bmc`` OpenPOWER Romulus POWER9 BMC 21 + - ``witherspoon-bmc`` OpenPOWER Witherspoon POWER9 BMC 22 + - ``sonorapass-bmc`` OCP SonoraPass BMC 23 + - ``swift-bmc`` OpenPOWER Swift BMC POWER9 24 + 25 + AST2600 SoC based machines : 26 + 27 + - ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex A7) 28 + - ``tacoma-bmc`` OpenPOWER Witherspoon POWER9 AST2600 BMC 29 + 30 + Supported devices 31 + ----------------- 32 + 33 + * SMP (for the AST2600 Cortex-A7) 34 + * Interrupt Controller (VIC) 35 + * Timer Controller 36 + * RTC Controller 37 + * I2C Controller 38 + * System Control Unit (SCU) 39 + * SRAM mapping 40 + * X-DMA Controller (basic interface) 41 + * Static Memory Controller (SMC or FMC) - Only SPI Flash support 42 + * SPI Memory Controller 43 + * USB 2.0 Controller 44 + * SD/MMC storage controllers 45 + * SDRAM controller (dummy interface for basic settings and training) 46 + * Watchdog Controller 47 + * GPIO Controller (Master only) 48 + * UART 49 + * Ethernet controllers 50 + 51 + 52 + Missing devices 53 + --------------- 54 + 55 + * Coprocessor support 56 + * ADC (out of tree implementation) 57 + * PWM and Fan Controller 58 + * LPC Bus Controller 59 + * Slave GPIO Controller 60 + * Super I/O Controller 61 + * Hash/Crypto Engine 62 + * PCI-Express 1 Controller 63 + * Graphic Display Controller 64 + * PECI Controller 65 + * MCTP Controller 66 + * Mailbox Controller 67 + * Virtual UART 68 + * eSPI Controller 69 + * I3C Controller 70 + 71 + Boot options 72 + ------------ 73 + 74 + The Aspeed machines can be started using the -kernel option to load a 75 + Linux kernel or from a firmare image which can be downloaded from the 76 + OpenPOWER jenkins : 77 + 78 + https://openpower.xyz/ 79 + 80 + The image should be attached as an MTD drive. Run : 81 + 82 + .. code-block:: bash 83 + 84 + $ qemu-system-arm -M romulus-bmc -nic user \ 85 + -drive file=flash-romulus,format=raw,if=mtd -nographic
+1
docs/system/target-arm.rst
··· 81 81 arm/realview 82 82 arm/versatile 83 83 arm/vexpress 84 + arm/aspeed 84 85 arm/musicpal 85 86 arm/nseries 86 87 arm/orangepi
+3 -1
hw/adc/stm32f2xx_adc.c
··· 246 246 .read = stm32f2xx_adc_read, 247 247 .write = stm32f2xx_adc_write, 248 248 .endianness = DEVICE_NATIVE_ENDIAN, 249 + .impl.min_access_size = 4, 250 + .impl.max_access_size = 4, 249 251 }; 250 252 251 253 static const VMStateDescription vmstate_stm32f2xx_adc = { ··· 278 280 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq); 279 281 280 282 memory_region_init_io(&s->mmio, obj, &stm32f2xx_adc_ops, s, 281 - TYPE_STM32F2XX_ADC, 0xFF); 283 + TYPE_STM32F2XX_ADC, 0x100); 282 284 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); 283 285 } 284 286
+37 -1
hw/arm/bcm2835_peripherals.c
··· 125 125 OBJECT(&s->sdhci.sdbus)); 126 126 object_property_add_const_link(OBJECT(&s->gpio), "sdbus-sdhost", 127 127 OBJECT(&s->sdhost.sdbus)); 128 + 129 + /* Mphi */ 130 + sysbus_init_child_obj(obj, "mphi", &s->mphi, sizeof(s->mphi), 131 + TYPE_BCM2835_MPHI); 132 + 133 + /* DWC2 */ 134 + sysbus_init_child_obj(obj, "dwc2", &s->dwc2, sizeof(s->dwc2), 135 + TYPE_DWC2_USB); 136 + 137 + object_property_add_const_link(OBJECT(&s->dwc2), "dma-mr", 138 + OBJECT(&s->gpu_bus_mr)); 128 139 } 129 140 130 141 static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) ··· 360 371 361 372 object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->gpio), "sd-bus"); 362 373 374 + /* Mphi */ 375 + object_property_set_bool(OBJECT(&s->mphi), true, "realized", &err); 376 + if (err) { 377 + error_propagate(errp, err); 378 + return; 379 + } 380 + 381 + memory_region_add_subregion(&s->peri_mr, MPHI_OFFSET, 382 + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mphi), 0)); 383 + sysbus_connect_irq(SYS_BUS_DEVICE(&s->mphi), 0, 384 + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, 385 + INTERRUPT_HOSTPORT)); 386 + 387 + /* DWC2 */ 388 + object_property_set_bool(OBJECT(&s->dwc2), true, "realized", &err); 389 + if (err) { 390 + error_propagate(errp, err); 391 + return; 392 + } 393 + 394 + memory_region_add_subregion(&s->peri_mr, USB_OTG_OFFSET, 395 + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dwc2), 0)); 396 + sysbus_connect_irq(SYS_BUS_DEVICE(&s->dwc2), 0, 397 + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, 398 + INTERRUPT_USB)); 399 + 363 400 create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40); 364 401 create_unimp(s, &s->cprman, "bcm2835-cprman", CPRMAN_OFFSET, 0x1000); 365 402 create_unimp(s, &s->a2w, "bcm2835-a2w", A2W_OFFSET, 0x1000); ··· 373 410 create_unimp(s, &s->otp, "bcm2835-otp", OTP_OFFSET, 0x80); 374 411 create_unimp(s, &s->dbus, "bcm2835-dbus", DBUS_OFFSET, 0x8000); 375 412 create_unimp(s, &s->ave0, "bcm2835-ave0", AVE0_OFFSET, 0x8000); 376 - create_unimp(s, &s->dwc2, "dwc-usb2", USB_OTG_OFFSET, 0x1000); 377 413 create_unimp(s, &s->sdramc, "bcm2835-sdramc", SDRAMC_OFFSET, 0x100); 378 414 } 379 415
+49 -17
hw/arm/pxa2xx.c
··· 26 26 #include "sysemu/blockdev.h" 27 27 #include "sysemu/qtest.h" 28 28 #include "qemu/cutils.h" 29 + #include "qemu/log.h" 29 30 30 31 static struct { 31 32 hwaddr io_base; ··· 112 113 return s->pm_regs[addr >> 2]; 113 114 default: 114 115 fail: 115 - printf("%s: Bad register " REG_FMT "\n", __func__, addr); 116 + qemu_log_mask(LOG_GUEST_ERROR, 117 + "%s: Bad read offset 0x%"HWADDR_PRIx"\n", 118 + __func__, addr); 116 119 break; 117 120 } 118 121 return 0; ··· 143 146 s->pm_regs[addr >> 2] = value; 144 147 break; 145 148 } 146 - 147 - printf("%s: Bad register " REG_FMT "\n", __func__, addr); 149 + qemu_log_mask(LOG_GUEST_ERROR, 150 + "%s: Bad write offset 0x%"HWADDR_PRIx"\n", 151 + __func__, addr); 148 152 break; 149 153 } 150 154 } ··· 185 189 return s->cm_regs[CCCR >> 2] | (3 << 28); 186 190 187 191 default: 188 - printf("%s: Bad register " REG_FMT "\n", __func__, addr); 192 + qemu_log_mask(LOG_GUEST_ERROR, 193 + "%s: Bad read offset 0x%"HWADDR_PRIx"\n", 194 + __func__, addr); 189 195 break; 190 196 } 191 197 return 0; ··· 210 216 break; 211 217 212 218 default: 213 - printf("%s: Bad register " REG_FMT "\n", __func__, addr); 219 + qemu_log_mask(LOG_GUEST_ERROR, 220 + "%s: Bad write offset 0x%"HWADDR_PRIx"\n", 221 + __func__, addr); 214 222 break; 215 223 } 216 224 } ··· 415 423 return s->mm_regs[addr >> 2]; 416 424 /* fall through */ 417 425 default: 418 - printf("%s: Bad register " REG_FMT "\n", __func__, addr); 426 + qemu_log_mask(LOG_GUEST_ERROR, 427 + "%s: Bad read offset 0x%"HWADDR_PRIx"\n", 428 + __func__, addr); 419 429 break; 420 430 } 421 431 return 0; ··· 434 444 } 435 445 436 446 default: 437 - printf("%s: Bad register " REG_FMT "\n", __func__, addr); 447 + qemu_log_mask(LOG_GUEST_ERROR, 448 + "%s: Bad write offset 0x%"HWADDR_PRIx"\n", 449 + __func__, addr); 438 450 break; 439 451 } 440 452 } ··· 641 653 case SSACD: 642 654 return s->ssacd; 643 655 default: 644 - printf("%s: Bad register " REG_FMT "\n", __func__, addr); 656 + qemu_log_mask(LOG_GUEST_ERROR, 657 + "%s: Bad read offset 0x%"HWADDR_PRIx"\n", 658 + __func__, addr); 645 659 break; 646 660 } 647 661 return 0; ··· 733 747 break; 734 748 735 749 default: 736 - printf("%s: Bad register " REG_FMT "\n", __func__, addr); 750 + qemu_log_mask(LOG_GUEST_ERROR, 751 + "%s: Bad write offset 0x%"HWADDR_PRIx"\n", 752 + __func__, addr); 737 753 break; 738 754 } 739 755 } ··· 995 1011 else 996 1012 return s->last_swcr; 997 1013 default: 998 - printf("%s: Bad register " REG_FMT "\n", __func__, addr); 1014 + qemu_log_mask(LOG_GUEST_ERROR, 1015 + "%s: Bad read offset 0x%"HWADDR_PRIx"\n", 1016 + __func__, addr); 999 1017 break; 1000 1018 } 1001 1019 return 0; ··· 1101 1119 break; 1102 1120 1103 1121 default: 1104 - printf("%s: Bad register " REG_FMT "\n", __func__, addr); 1122 + qemu_log_mask(LOG_GUEST_ERROR, 1123 + "%s: Bad write offset 0x%"HWADDR_PRIx"\n", 1124 + __func__, addr); 1105 1125 } 1106 1126 } 1107 1127 ··· 1354 1374 s->ibmr = 0; 1355 1375 return s->ibmr; 1356 1376 default: 1357 - printf("%s: Bad register " REG_FMT "\n", __func__, addr); 1377 + qemu_log_mask(LOG_GUEST_ERROR, 1378 + "%s: Bad read offset 0x%"HWADDR_PRIx"\n", 1379 + __func__, addr); 1358 1380 break; 1359 1381 } 1360 1382 return 0; ··· 1427 1449 break; 1428 1450 1429 1451 default: 1430 - printf("%s: Bad register " REG_FMT "\n", __func__, addr); 1452 + qemu_log_mask(LOG_GUEST_ERROR, 1453 + "%s: Bad write offset 0x%"HWADDR_PRIx"\n", 1454 + __func__, addr); 1431 1455 } 1432 1456 } 1433 1457 ··· 1628 1652 } 1629 1653 return 0; 1630 1654 default: 1631 - printf("%s: Bad register " REG_FMT "\n", __func__, addr); 1655 + qemu_log_mask(LOG_GUEST_ERROR, 1656 + "%s: Bad read offset 0x%"HWADDR_PRIx"\n", 1657 + __func__, addr); 1632 1658 break; 1633 1659 } 1634 1660 return 0; ··· 1685 1711 } 1686 1712 break; 1687 1713 default: 1688 - printf("%s: Bad register " REG_FMT "\n", __func__, addr); 1714 + qemu_log_mask(LOG_GUEST_ERROR, 1715 + "%s: Bad write offset 0x%"HWADDR_PRIx"\n", 1716 + __func__, addr); 1689 1717 } 1690 1718 } 1691 1719 ··· 1870 1898 case ICFOR: 1871 1899 return s->rx_len; 1872 1900 default: 1873 - printf("%s: Bad register " REG_FMT "\n", __func__, addr); 1901 + qemu_log_mask(LOG_GUEST_ERROR, 1902 + "%s: Bad read offset 0x%"HWADDR_PRIx"\n", 1903 + __func__, addr); 1874 1904 break; 1875 1905 } 1876 1906 return 0; ··· 1922 1952 case ICFOR: 1923 1953 break; 1924 1954 default: 1925 - printf("%s: Bad register " REG_FMT "\n", __func__, addr); 1955 + qemu_log_mask(LOG_GUEST_ERROR, 1956 + "%s: Bad write offset 0x%"HWADDR_PRIx"\n", 1957 + __func__, addr); 1926 1958 } 1927 1959 } 1928 1960
+7 -3
hw/input/pxa2xx_keypad.c
··· 12 12 */ 13 13 14 14 #include "qemu/osdep.h" 15 - #include "hw/hw.h" 15 + #include "qemu/log.h" 16 16 #include "hw/irq.h" 17 17 #include "migration/vmstate.h" 18 18 #include "hw/arm/pxa.h" ··· 233 233 return s->kpkdi; 234 234 break; 235 235 default: 236 - hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset); 236 + qemu_log_mask(LOG_GUEST_ERROR, 237 + "%s: Bad read offset 0x%"HWADDR_PRIx"\n", 238 + __func__, offset); 237 239 } 238 240 239 241 return 0; ··· 280 282 break; 281 283 282 284 default: 283 - hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset); 285 + qemu_log_mask(LOG_GUEST_ERROR, 286 + "%s: Bad write offset 0x%"HWADDR_PRIx"\n", 287 + __func__, offset); 284 288 } 285 289 } 286 290
+1
hw/misc/Makefile.objs
··· 56 56 common-obj-$(CONFIG_OMAP) += omap_sdrc.o 57 57 common-obj-$(CONFIG_OMAP) += omap_tap.o 58 58 common-obj-$(CONFIG_RASPI) += bcm2835_mbox.o 59 + common-obj-$(CONFIG_RASPI) += bcm2835_mphi.o 59 60 common-obj-$(CONFIG_RASPI) += bcm2835_property.o 60 61 common-obj-$(CONFIG_RASPI) += bcm2835_rng.o 61 62 common-obj-$(CONFIG_RASPI) += bcm2835_thermal.o
+191
hw/misc/bcm2835_mphi.c
··· 1 + /* 2 + * BCM2835 SOC MPHI emulation 3 + * 4 + * Very basic emulation, only providing the FIQ interrupt needed to 5 + * allow the dwc-otg USB host controller driver in the Raspbian kernel 6 + * to function. 7 + * 8 + * Copyright (c) 2020 Paul Zimmerman <pauldzim@gmail.com> 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License as published by 12 + * the Free Software Foundation; either version 2 of the License, or 13 + * (at your option) any later version. 14 + * 15 + * This program is distributed in the hope that it will be useful, 16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 + * GNU General Public License for more details. 19 + */ 20 + 21 + #include "qemu/osdep.h" 22 + #include "qapi/error.h" 23 + #include "hw/misc/bcm2835_mphi.h" 24 + #include "migration/vmstate.h" 25 + #include "qemu/error-report.h" 26 + #include "qemu/log.h" 27 + #include "qemu/main-loop.h" 28 + 29 + static inline void mphi_raise_irq(BCM2835MphiState *s) 30 + { 31 + qemu_set_irq(s->irq, 1); 32 + } 33 + 34 + static inline void mphi_lower_irq(BCM2835MphiState *s) 35 + { 36 + qemu_set_irq(s->irq, 0); 37 + } 38 + 39 + static uint64_t mphi_reg_read(void *ptr, hwaddr addr, unsigned size) 40 + { 41 + BCM2835MphiState *s = ptr; 42 + uint32_t val = 0; 43 + 44 + switch (addr) { 45 + case 0x28: /* outdda */ 46 + val = s->outdda; 47 + break; 48 + case 0x2c: /* outddb */ 49 + val = s->outddb; 50 + break; 51 + case 0x4c: /* ctrl */ 52 + val = s->ctrl; 53 + val |= 1 << 17; 54 + break; 55 + case 0x50: /* intstat */ 56 + val = s->intstat; 57 + break; 58 + case 0x1f0: /* swirq_set */ 59 + val = s->swirq; 60 + break; 61 + case 0x1f4: /* swirq_clr */ 62 + val = s->swirq; 63 + break; 64 + default: 65 + qemu_log_mask(LOG_UNIMP, "read from unknown register"); 66 + break; 67 + } 68 + 69 + return val; 70 + } 71 + 72 + static void mphi_reg_write(void *ptr, hwaddr addr, uint64_t val, unsigned size) 73 + { 74 + BCM2835MphiState *s = ptr; 75 + int do_irq = 0; 76 + 77 + switch (addr) { 78 + case 0x28: /* outdda */ 79 + s->outdda = val; 80 + break; 81 + case 0x2c: /* outddb */ 82 + s->outddb = val; 83 + if (val & (1 << 29)) { 84 + do_irq = 1; 85 + } 86 + break; 87 + case 0x4c: /* ctrl */ 88 + s->ctrl = val; 89 + if (val & (1 << 16)) { 90 + do_irq = -1; 91 + } 92 + break; 93 + case 0x50: /* intstat */ 94 + s->intstat = val; 95 + if (val & ((1 << 16) | (1 << 29))) { 96 + do_irq = -1; 97 + } 98 + break; 99 + case 0x1f0: /* swirq_set */ 100 + s->swirq |= val; 101 + do_irq = 1; 102 + break; 103 + case 0x1f4: /* swirq_clr */ 104 + s->swirq &= ~val; 105 + do_irq = -1; 106 + break; 107 + default: 108 + qemu_log_mask(LOG_UNIMP, "write to unknown register"); 109 + return; 110 + } 111 + 112 + if (do_irq > 0) { 113 + mphi_raise_irq(s); 114 + } else if (do_irq < 0) { 115 + mphi_lower_irq(s); 116 + } 117 + } 118 + 119 + static const MemoryRegionOps mphi_mmio_ops = { 120 + .read = mphi_reg_read, 121 + .write = mphi_reg_write, 122 + .impl.min_access_size = 4, 123 + .impl.max_access_size = 4, 124 + .endianness = DEVICE_LITTLE_ENDIAN, 125 + }; 126 + 127 + static void mphi_reset(DeviceState *dev) 128 + { 129 + BCM2835MphiState *s = BCM2835_MPHI(dev); 130 + 131 + s->outdda = 0; 132 + s->outddb = 0; 133 + s->ctrl = 0; 134 + s->intstat = 0; 135 + s->swirq = 0; 136 + } 137 + 138 + static void mphi_realize(DeviceState *dev, Error **errp) 139 + { 140 + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 141 + BCM2835MphiState *s = BCM2835_MPHI(dev); 142 + 143 + sysbus_init_irq(sbd, &s->irq); 144 + } 145 + 146 + static void mphi_init(Object *obj) 147 + { 148 + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 149 + BCM2835MphiState *s = BCM2835_MPHI(obj); 150 + 151 + memory_region_init_io(&s->iomem, obj, &mphi_mmio_ops, s, "mphi", MPHI_MMIO_SIZE); 152 + sysbus_init_mmio(sbd, &s->iomem); 153 + } 154 + 155 + const VMStateDescription vmstate_mphi_state = { 156 + .name = "mphi", 157 + .version_id = 1, 158 + .minimum_version_id = 1, 159 + .fields = (VMStateField[]) { 160 + VMSTATE_UINT32(outdda, BCM2835MphiState), 161 + VMSTATE_UINT32(outddb, BCM2835MphiState), 162 + VMSTATE_UINT32(ctrl, BCM2835MphiState), 163 + VMSTATE_UINT32(intstat, BCM2835MphiState), 164 + VMSTATE_UINT32(swirq, BCM2835MphiState), 165 + VMSTATE_END_OF_LIST() 166 + } 167 + }; 168 + 169 + static void mphi_class_init(ObjectClass *klass, void *data) 170 + { 171 + DeviceClass *dc = DEVICE_CLASS(klass); 172 + 173 + dc->realize = mphi_realize; 174 + dc->reset = mphi_reset; 175 + dc->vmsd = &vmstate_mphi_state; 176 + } 177 + 178 + static const TypeInfo bcm2835_mphi_type_info = { 179 + .name = TYPE_BCM2835_MPHI, 180 + .parent = TYPE_SYS_BUS_DEVICE, 181 + .instance_size = sizeof(BCM2835MphiState), 182 + .instance_init = mphi_init, 183 + .class_init = mphi_class_init, 184 + }; 185 + 186 + static void bcm2835_mphi_register_types(void) 187 + { 188 + type_register_static(&bcm2835_mphi_type_info); 189 + } 190 + 191 + type_init(bcm2835_mphi_register_types)
+2 -2
hw/ssi/imx_spi.c
··· 182 182 183 183 rx = 0; 184 184 185 - while (tx_burst) { 185 + while (tx_burst > 0) { 186 186 uint8_t byte = tx & 0xff; 187 187 188 188 DPRINTF("writing 0x%02x\n", (uint32_t)byte); ··· 206 206 if (fifo32_is_full(&s->rx_fifo)) { 207 207 s->regs[ECSPI_STATREG] |= ECSPI_STATREG_RO; 208 208 } else { 209 - fifo32_push(&s->rx_fifo, (uint8_t)rx); 209 + fifo32_push(&s->rx_fifo, rx); 210 210 } 211 211 212 212 if (s->burst_length <= 0) {
+5
hw/usb/Kconfig
··· 46 46 bool 47 47 select USB 48 48 49 + config USB_DWC2 50 + bool 51 + default y 52 + select USB 53 + 49 54 config TUSB6010 50 55 bool 51 56 select USB_MUSB
+1
hw/usb/Makefile.objs
··· 12 12 common-obj-$(CONFIG_USB_XHCI) += hcd-xhci.o 13 13 common-obj-$(CONFIG_USB_XHCI_NEC) += hcd-xhci-nec.o 14 14 common-obj-$(CONFIG_USB_MUSB) += hcd-musb.o 15 + common-obj-$(CONFIG_USB_DWC2) += hcd-dwc2.o 15 16 16 17 common-obj-$(CONFIG_TUSB6010) += tusb6010.o 17 18 common-obj-$(CONFIG_IMX) += chipidea.o
+14 -1
hw/usb/dev-storage.c
··· 229 229 usb_packet_copy(p, scsi_req_get_buf(s->req) + s->scsi_off, len); 230 230 s->scsi_len -= len; 231 231 s->scsi_off += len; 232 + if (len > s->data_len) { 233 + len = s->data_len; 234 + } 232 235 s->data_len -= len; 233 236 if (s->scsi_len == 0 || s->data_len == 0) { 234 237 scsi_req_continue(s->req); ··· 303 306 if (s->data_len) { 304 307 int len = (p->iov.size - p->actual_length); 305 308 usb_packet_skip(p, len); 309 + if (len > s->data_len) { 310 + len = s->data_len; 311 + } 306 312 s->data_len -= len; 307 313 } 308 314 if (s->data_len == 0) { ··· 469 475 int len = p->iov.size - p->actual_length; 470 476 if (len) { 471 477 usb_packet_skip(p, len); 478 + if (len > s->data_len) { 479 + len = s->data_len; 480 + } 472 481 s->data_len -= len; 473 482 if (s->data_len == 0) { 474 483 s->mode = USB_MSDM_CSW; ··· 528 537 int len = p->iov.size - p->actual_length; 529 538 if (len) { 530 539 usb_packet_skip(p, len); 540 + if (len > s->data_len) { 541 + len = s->data_len; 542 + } 531 543 s->data_len -= len; 532 544 if (s->data_len == 0) { 533 545 s->mode = USB_MSDM_CSW; 534 546 } 535 547 } 536 548 } 537 - if (p->actual_length < p->iov.size) { 549 + if (p->actual_length < p->iov.size && (p->short_not_ok || 550 + s->scsi_len >= p->ep->max_packet_size)) { 538 551 DPRINTF("Deferring packet %p [wait data-in]\n", p); 539 552 s->packet = p; 540 553 p->status = USB_RET_ASYNC;
+1417
hw/usb/hcd-dwc2.c
··· 1 + /* 2 + * dwc-hsotg (dwc2) USB host controller emulation 3 + * 4 + * Based on hw/usb/hcd-ehci.c and hw/usb/hcd-ohci.c 5 + * 6 + * Note that to use this emulation with the dwc-otg driver in the 7 + * Raspbian kernel, you must pass the option "dwc_otg.fiq_fsm_enable=0" 8 + * on the kernel command line. 9 + * 10 + * Some useful documentation used to develop this emulation can be 11 + * found online (as of April 2020) at: 12 + * 13 + * http://www.capital-micro.com/PDF/CME-M7_Family_User_Guide_EN.pdf 14 + * which has a pretty complete description of the controller starting 15 + * on page 370. 16 + * 17 + * https://sourceforge.net/p/wive-ng/wive-ng-mt/ci/master/tree/docs/DataSheets/RT3050_5x_V2.0_081408_0902.pdf 18 + * which has a description of the controller registers starting on 19 + * page 130. 20 + * 21 + * Copyright (c) 2020 Paul Zimmerman <pauldzim@gmail.com> 22 + * 23 + * This program is free software; you can redistribute it and/or modify 24 + * it under the terms of the GNU General Public License as published by 25 + * the Free Software Foundation; either version 2 of the License, or 26 + * (at your option) any later version. 27 + * 28 + * This program is distributed in the hope that it will be useful, 29 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 30 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 31 + * GNU General Public License for more details. 32 + */ 33 + 34 + #include "qemu/osdep.h" 35 + #include "qemu/units.h" 36 + #include "qapi/error.h" 37 + #include "hw/usb/dwc2-regs.h" 38 + #include "hw/usb/hcd-dwc2.h" 39 + #include "migration/vmstate.h" 40 + #include "trace.h" 41 + #include "qemu/log.h" 42 + #include "qemu/error-report.h" 43 + #include "qemu/main-loop.h" 44 + #include "hw/qdev-properties.h" 45 + 46 + #define USB_HZ_FS 12000000 47 + #define USB_HZ_HS 96000000 48 + #define USB_FRMINTVL 12000 49 + 50 + /* nifty macros from Arnon's EHCI version */ 51 + #define get_field(data, field) \ 52 + (((data) & field##_MASK) >> field##_SHIFT) 53 + 54 + #define set_field(data, newval, field) do { \ 55 + uint32_t val = *(data); \ 56 + val &= ~field##_MASK; \ 57 + val |= ((newval) << field##_SHIFT) & field##_MASK; \ 58 + *(data) = val; \ 59 + } while (0) 60 + 61 + #define get_bit(data, bitmask) \ 62 + (!!((data) & (bitmask))) 63 + 64 + /* update irq line */ 65 + static inline void dwc2_update_irq(DWC2State *s) 66 + { 67 + static int oldlevel; 68 + int level = 0; 69 + 70 + if ((s->gintsts & s->gintmsk) && (s->gahbcfg & GAHBCFG_GLBL_INTR_EN)) { 71 + level = 1; 72 + } 73 + if (level != oldlevel) { 74 + oldlevel = level; 75 + trace_usb_dwc2_update_irq(level); 76 + qemu_set_irq(s->irq, level); 77 + } 78 + } 79 + 80 + /* flag interrupt condition */ 81 + static inline void dwc2_raise_global_irq(DWC2State *s, uint32_t intr) 82 + { 83 + if (!(s->gintsts & intr)) { 84 + s->gintsts |= intr; 85 + trace_usb_dwc2_raise_global_irq(intr); 86 + dwc2_update_irq(s); 87 + } 88 + } 89 + 90 + static inline void dwc2_lower_global_irq(DWC2State *s, uint32_t intr) 91 + { 92 + if (s->gintsts & intr) { 93 + s->gintsts &= ~intr; 94 + trace_usb_dwc2_lower_global_irq(intr); 95 + dwc2_update_irq(s); 96 + } 97 + } 98 + 99 + static inline void dwc2_raise_host_irq(DWC2State *s, uint32_t host_intr) 100 + { 101 + if (!(s->haint & host_intr)) { 102 + s->haint |= host_intr; 103 + s->haint &= 0xffff; 104 + trace_usb_dwc2_raise_host_irq(host_intr); 105 + if (s->haint & s->haintmsk) { 106 + dwc2_raise_global_irq(s, GINTSTS_HCHINT); 107 + } 108 + } 109 + } 110 + 111 + static inline void dwc2_lower_host_irq(DWC2State *s, uint32_t host_intr) 112 + { 113 + if (s->haint & host_intr) { 114 + s->haint &= ~host_intr; 115 + trace_usb_dwc2_lower_host_irq(host_intr); 116 + if (!(s->haint & s->haintmsk)) { 117 + dwc2_lower_global_irq(s, GINTSTS_HCHINT); 118 + } 119 + } 120 + } 121 + 122 + static inline void dwc2_update_hc_irq(DWC2State *s, int index) 123 + { 124 + uint32_t host_intr = 1 << (index >> 3); 125 + 126 + if (s->hreg1[index + 2] & s->hreg1[index + 3]) { 127 + dwc2_raise_host_irq(s, host_intr); 128 + } else { 129 + dwc2_lower_host_irq(s, host_intr); 130 + } 131 + } 132 + 133 + /* set a timer for EOF */ 134 + static void dwc2_eof_timer(DWC2State *s) 135 + { 136 + timer_mod(s->eof_timer, s->sof_time + s->usb_frame_time); 137 + } 138 + 139 + /* Set a timer for EOF and generate SOF event */ 140 + static void dwc2_sof(DWC2State *s) 141 + { 142 + s->sof_time += s->usb_frame_time; 143 + trace_usb_dwc2_sof(s->sof_time); 144 + dwc2_eof_timer(s); 145 + dwc2_raise_global_irq(s, GINTSTS_SOF); 146 + } 147 + 148 + /* Do frame processing on frame boundary */ 149 + static void dwc2_frame_boundary(void *opaque) 150 + { 151 + DWC2State *s = opaque; 152 + int64_t now; 153 + uint16_t frcnt; 154 + 155 + now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 156 + 157 + /* Frame boundary, so do EOF stuff here */ 158 + 159 + /* Increment frame number */ 160 + frcnt = (uint16_t)((now - s->sof_time) / s->fi); 161 + s->frame_number = (s->frame_number + frcnt) & 0xffff; 162 + s->hfnum = s->frame_number & HFNUM_MAX_FRNUM; 163 + 164 + /* Do SOF stuff here */ 165 + dwc2_sof(s); 166 + } 167 + 168 + /* Start sending SOF tokens on the USB bus */ 169 + static void dwc2_bus_start(DWC2State *s) 170 + { 171 + trace_usb_dwc2_bus_start(); 172 + s->sof_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 173 + dwc2_eof_timer(s); 174 + } 175 + 176 + /* Stop sending SOF tokens on the USB bus */ 177 + static void dwc2_bus_stop(DWC2State *s) 178 + { 179 + trace_usb_dwc2_bus_stop(); 180 + timer_del(s->eof_timer); 181 + } 182 + 183 + static USBDevice *dwc2_find_device(DWC2State *s, uint8_t addr) 184 + { 185 + USBDevice *dev; 186 + 187 + trace_usb_dwc2_find_device(addr); 188 + 189 + if (!(s->hprt0 & HPRT0_ENA)) { 190 + trace_usb_dwc2_port_disabled(0); 191 + } else { 192 + dev = usb_find_device(&s->uport, addr); 193 + if (dev != NULL) { 194 + trace_usb_dwc2_device_found(0); 195 + return dev; 196 + } 197 + } 198 + 199 + trace_usb_dwc2_device_not_found(); 200 + return NULL; 201 + } 202 + 203 + static const char *pstatus[] = { 204 + "USB_RET_SUCCESS", "USB_RET_NODEV", "USB_RET_NAK", "USB_RET_STALL", 205 + "USB_RET_BABBLE", "USB_RET_IOERROR", "USB_RET_ASYNC", 206 + "USB_RET_ADD_TO_QUEUE", "USB_RET_REMOVE_FROM_QUEUE" 207 + }; 208 + 209 + static uint32_t pintr[] = { 210 + HCINTMSK_XFERCOMPL, HCINTMSK_XACTERR, HCINTMSK_NAK, HCINTMSK_STALL, 211 + HCINTMSK_BBLERR, HCINTMSK_XACTERR, HCINTMSK_XACTERR, HCINTMSK_XACTERR, 212 + HCINTMSK_XACTERR 213 + }; 214 + 215 + static const char *types[] = { 216 + "Ctrl", "Isoc", "Bulk", "Intr" 217 + }; 218 + 219 + static const char *dirs[] = { 220 + "Out", "In" 221 + }; 222 + 223 + static void dwc2_handle_packet(DWC2State *s, uint32_t devadr, USBDevice *dev, 224 + USBEndpoint *ep, uint32_t index, bool send) 225 + { 226 + DWC2Packet *p; 227 + uint32_t hcchar = s->hreg1[index]; 228 + uint32_t hctsiz = s->hreg1[index + 4]; 229 + uint32_t hcdma = s->hreg1[index + 5]; 230 + uint32_t chan, epnum, epdir, eptype, mps, pid, pcnt, len, tlen, intr = 0; 231 + uint32_t tpcnt, stsidx, actual = 0; 232 + bool do_intr = false, done = false; 233 + 234 + epnum = get_field(hcchar, HCCHAR_EPNUM); 235 + epdir = get_bit(hcchar, HCCHAR_EPDIR); 236 + eptype = get_field(hcchar, HCCHAR_EPTYPE); 237 + mps = get_field(hcchar, HCCHAR_MPS); 238 + pid = get_field(hctsiz, TSIZ_SC_MC_PID); 239 + pcnt = get_field(hctsiz, TSIZ_PKTCNT); 240 + len = get_field(hctsiz, TSIZ_XFERSIZE); 241 + assert(len <= DWC2_MAX_XFER_SIZE); 242 + chan = index >> 3; 243 + p = &s->packet[chan]; 244 + 245 + trace_usb_dwc2_handle_packet(chan, dev, &p->packet, epnum, types[eptype], 246 + dirs[epdir], mps, len, pcnt); 247 + 248 + if (eptype == USB_ENDPOINT_XFER_CONTROL && pid == TSIZ_SC_MC_PID_SETUP) { 249 + pid = USB_TOKEN_SETUP; 250 + } else { 251 + pid = epdir ? USB_TOKEN_IN : USB_TOKEN_OUT; 252 + } 253 + 254 + if (send) { 255 + tlen = len; 256 + if (p->small) { 257 + if (tlen > mps) { 258 + tlen = mps; 259 + } 260 + } 261 + 262 + if (pid != USB_TOKEN_IN) { 263 + trace_usb_dwc2_memory_read(hcdma, tlen); 264 + if (dma_memory_read(&s->dma_as, hcdma, 265 + s->usb_buf[chan], tlen) != MEMTX_OK) { 266 + qemu_log_mask(LOG_GUEST_ERROR, "%s: dma_memory_read failed\n", 267 + __func__); 268 + } 269 + } 270 + 271 + usb_packet_init(&p->packet); 272 + usb_packet_setup(&p->packet, pid, ep, 0, hcdma, 273 + pid != USB_TOKEN_IN, true); 274 + usb_packet_addbuf(&p->packet, s->usb_buf[chan], tlen); 275 + p->async = DWC2_ASYNC_NONE; 276 + usb_handle_packet(dev, &p->packet); 277 + } else { 278 + tlen = p->len; 279 + } 280 + 281 + stsidx = -p->packet.status; 282 + assert(stsidx < sizeof(pstatus) / sizeof(*pstatus)); 283 + actual = p->packet.actual_length; 284 + trace_usb_dwc2_packet_status(pstatus[stsidx], actual); 285 + 286 + babble: 287 + if (p->packet.status != USB_RET_SUCCESS && 288 + p->packet.status != USB_RET_NAK && 289 + p->packet.status != USB_RET_STALL && 290 + p->packet.status != USB_RET_ASYNC) { 291 + trace_usb_dwc2_packet_error(pstatus[stsidx]); 292 + } 293 + 294 + if (p->packet.status == USB_RET_ASYNC) { 295 + trace_usb_dwc2_async_packet(&p->packet, chan, dev, epnum, 296 + dirs[epdir], tlen); 297 + usb_device_flush_ep_queue(dev, ep); 298 + assert(p->async != DWC2_ASYNC_INFLIGHT); 299 + p->devadr = devadr; 300 + p->epnum = epnum; 301 + p->epdir = epdir; 302 + p->mps = mps; 303 + p->pid = pid; 304 + p->index = index; 305 + p->pcnt = pcnt; 306 + p->len = tlen; 307 + p->async = DWC2_ASYNC_INFLIGHT; 308 + p->needs_service = false; 309 + return; 310 + } 311 + 312 + if (p->packet.status == USB_RET_SUCCESS) { 313 + if (actual > tlen) { 314 + p->packet.status = USB_RET_BABBLE; 315 + goto babble; 316 + } 317 + 318 + if (pid == USB_TOKEN_IN) { 319 + trace_usb_dwc2_memory_write(hcdma, actual); 320 + if (dma_memory_write(&s->dma_as, hcdma, s->usb_buf[chan], 321 + actual) != MEMTX_OK) { 322 + qemu_log_mask(LOG_GUEST_ERROR, "%s: dma_memory_write failed\n", 323 + __func__); 324 + } 325 + } 326 + 327 + tpcnt = actual / mps; 328 + if (actual % mps) { 329 + tpcnt++; 330 + if (pid == USB_TOKEN_IN) { 331 + done = true; 332 + } 333 + } 334 + 335 + pcnt -= tpcnt < pcnt ? tpcnt : pcnt; 336 + set_field(&hctsiz, pcnt, TSIZ_PKTCNT); 337 + len -= actual < len ? actual : len; 338 + set_field(&hctsiz, len, TSIZ_XFERSIZE); 339 + s->hreg1[index + 4] = hctsiz; 340 + hcdma += actual; 341 + s->hreg1[index + 5] = hcdma; 342 + 343 + if (!pcnt || len == 0 || actual == 0) { 344 + done = true; 345 + } 346 + } else { 347 + intr |= pintr[stsidx]; 348 + if (p->packet.status == USB_RET_NAK && 349 + (eptype == USB_ENDPOINT_XFER_CONTROL || 350 + eptype == USB_ENDPOINT_XFER_BULK)) { 351 + /* 352 + * for ctrl/bulk, automatically retry on NAK, 353 + * but send the interrupt anyway 354 + */ 355 + intr &= ~HCINTMSK_RESERVED14_31; 356 + s->hreg1[index + 2] |= intr; 357 + do_intr = true; 358 + } else { 359 + intr |= HCINTMSK_CHHLTD; 360 + done = true; 361 + } 362 + } 363 + 364 + usb_packet_cleanup(&p->packet); 365 + 366 + if (done) { 367 + hcchar &= ~HCCHAR_CHENA; 368 + s->hreg1[index] = hcchar; 369 + if (!(intr & HCINTMSK_CHHLTD)) { 370 + intr |= HCINTMSK_CHHLTD | HCINTMSK_XFERCOMPL; 371 + } 372 + intr &= ~HCINTMSK_RESERVED14_31; 373 + s->hreg1[index + 2] |= intr; 374 + p->needs_service = false; 375 + trace_usb_dwc2_packet_done(pstatus[stsidx], actual, len, pcnt); 376 + dwc2_update_hc_irq(s, index); 377 + return; 378 + } 379 + 380 + p->devadr = devadr; 381 + p->epnum = epnum; 382 + p->epdir = epdir; 383 + p->mps = mps; 384 + p->pid = pid; 385 + p->index = index; 386 + p->pcnt = pcnt; 387 + p->len = len; 388 + p->needs_service = true; 389 + trace_usb_dwc2_packet_next(pstatus[stsidx], len, pcnt); 390 + if (do_intr) { 391 + dwc2_update_hc_irq(s, index); 392 + } 393 + } 394 + 395 + /* Attach or detach a device on root hub */ 396 + 397 + static const char *speeds[] = { 398 + "low", "full", "high" 399 + }; 400 + 401 + static void dwc2_attach(USBPort *port) 402 + { 403 + DWC2State *s = port->opaque; 404 + int hispd = 0; 405 + 406 + trace_usb_dwc2_attach(port); 407 + assert(port->index == 0); 408 + 409 + if (!port->dev || !port->dev->attached) { 410 + return; 411 + } 412 + 413 + assert(port->dev->speed <= USB_SPEED_HIGH); 414 + trace_usb_dwc2_attach_speed(speeds[port->dev->speed]); 415 + s->hprt0 &= ~HPRT0_SPD_MASK; 416 + 417 + switch (port->dev->speed) { 418 + case USB_SPEED_LOW: 419 + s->hprt0 |= HPRT0_SPD_LOW_SPEED << HPRT0_SPD_SHIFT; 420 + break; 421 + case USB_SPEED_FULL: 422 + s->hprt0 |= HPRT0_SPD_FULL_SPEED << HPRT0_SPD_SHIFT; 423 + break; 424 + case USB_SPEED_HIGH: 425 + s->hprt0 |= HPRT0_SPD_HIGH_SPEED << HPRT0_SPD_SHIFT; 426 + hispd = 1; 427 + break; 428 + } 429 + 430 + if (hispd) { 431 + s->usb_frame_time = NANOSECONDS_PER_SECOND / 8000; /* 125000 */ 432 + if (NANOSECONDS_PER_SECOND >= USB_HZ_HS) { 433 + s->usb_bit_time = NANOSECONDS_PER_SECOND / USB_HZ_HS; /* 10.4 */ 434 + } else { 435 + s->usb_bit_time = 1; 436 + } 437 + } else { 438 + s->usb_frame_time = NANOSECONDS_PER_SECOND / 1000; /* 1000000 */ 439 + if (NANOSECONDS_PER_SECOND >= USB_HZ_FS) { 440 + s->usb_bit_time = NANOSECONDS_PER_SECOND / USB_HZ_FS; /* 83.3 */ 441 + } else { 442 + s->usb_bit_time = 1; 443 + } 444 + } 445 + 446 + s->fi = USB_FRMINTVL - 1; 447 + s->hprt0 |= HPRT0_CONNDET | HPRT0_CONNSTS; 448 + 449 + dwc2_bus_start(s); 450 + dwc2_raise_global_irq(s, GINTSTS_PRTINT); 451 + } 452 + 453 + static void dwc2_detach(USBPort *port) 454 + { 455 + DWC2State *s = port->opaque; 456 + 457 + trace_usb_dwc2_detach(port); 458 + assert(port->index == 0); 459 + 460 + dwc2_bus_stop(s); 461 + 462 + s->hprt0 &= ~(HPRT0_SPD_MASK | HPRT0_SUSP | HPRT0_ENA | HPRT0_CONNSTS); 463 + s->hprt0 |= HPRT0_CONNDET | HPRT0_ENACHG; 464 + 465 + dwc2_raise_global_irq(s, GINTSTS_PRTINT); 466 + } 467 + 468 + static void dwc2_child_detach(USBPort *port, USBDevice *child) 469 + { 470 + trace_usb_dwc2_child_detach(port, child); 471 + assert(port->index == 0); 472 + } 473 + 474 + static void dwc2_wakeup(USBPort *port) 475 + { 476 + DWC2State *s = port->opaque; 477 + 478 + trace_usb_dwc2_wakeup(port); 479 + assert(port->index == 0); 480 + 481 + if (s->hprt0 & HPRT0_SUSP) { 482 + s->hprt0 |= HPRT0_RES; 483 + dwc2_raise_global_irq(s, GINTSTS_PRTINT); 484 + } 485 + 486 + qemu_bh_schedule(s->async_bh); 487 + } 488 + 489 + static void dwc2_async_packet_complete(USBPort *port, USBPacket *packet) 490 + { 491 + DWC2State *s = port->opaque; 492 + DWC2Packet *p; 493 + USBDevice *dev; 494 + USBEndpoint *ep; 495 + 496 + assert(port->index == 0); 497 + p = container_of(packet, DWC2Packet, packet); 498 + dev = dwc2_find_device(s, p->devadr); 499 + ep = usb_ep_get(dev, p->pid, p->epnum); 500 + trace_usb_dwc2_async_packet_complete(port, packet, p->index >> 3, dev, 501 + p->epnum, dirs[p->epdir], p->len); 502 + assert(p->async == DWC2_ASYNC_INFLIGHT); 503 + 504 + if (packet->status == USB_RET_REMOVE_FROM_QUEUE) { 505 + usb_cancel_packet(packet); 506 + usb_packet_cleanup(packet); 507 + return; 508 + } 509 + 510 + dwc2_handle_packet(s, p->devadr, dev, ep, p->index, false); 511 + 512 + p->async = DWC2_ASYNC_FINISHED; 513 + qemu_bh_schedule(s->async_bh); 514 + } 515 + 516 + static USBPortOps dwc2_port_ops = { 517 + .attach = dwc2_attach, 518 + .detach = dwc2_detach, 519 + .child_detach = dwc2_child_detach, 520 + .wakeup = dwc2_wakeup, 521 + .complete = dwc2_async_packet_complete, 522 + }; 523 + 524 + static uint32_t dwc2_get_frame_remaining(DWC2State *s) 525 + { 526 + uint32_t fr = 0; 527 + int64_t tks; 528 + 529 + tks = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->sof_time; 530 + if (tks < 0) { 531 + tks = 0; 532 + } 533 + 534 + /* avoid muldiv if possible */ 535 + if (tks >= s->usb_frame_time) { 536 + goto out; 537 + } 538 + if (tks < s->usb_bit_time) { 539 + fr = s->fi; 540 + goto out; 541 + } 542 + 543 + /* tks = number of ns since SOF, divided by 83 (fs) or 10 (hs) */ 544 + tks = tks / s->usb_bit_time; 545 + if (tks >= (int64_t)s->fi) { 546 + goto out; 547 + } 548 + 549 + /* remaining = frame interval minus tks */ 550 + fr = (uint32_t)((int64_t)s->fi - tks); 551 + 552 + out: 553 + return fr; 554 + } 555 + 556 + static void dwc2_work_bh(void *opaque) 557 + { 558 + DWC2State *s = opaque; 559 + DWC2Packet *p; 560 + USBDevice *dev; 561 + USBEndpoint *ep; 562 + int64_t t_now, expire_time; 563 + int chan; 564 + bool found = false; 565 + 566 + trace_usb_dwc2_work_bh(); 567 + if (s->working) { 568 + return; 569 + } 570 + s->working = true; 571 + 572 + t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 573 + chan = s->next_chan; 574 + 575 + do { 576 + p = &s->packet[chan]; 577 + if (p->needs_service) { 578 + dev = dwc2_find_device(s, p->devadr); 579 + ep = usb_ep_get(dev, p->pid, p->epnum); 580 + trace_usb_dwc2_work_bh_service(s->next_chan, chan, dev, p->epnum); 581 + dwc2_handle_packet(s, p->devadr, dev, ep, p->index, true); 582 + found = true; 583 + } 584 + if (++chan == DWC2_NB_CHAN) { 585 + chan = 0; 586 + } 587 + if (found) { 588 + s->next_chan = chan; 589 + trace_usb_dwc2_work_bh_next(chan); 590 + } 591 + } while (chan != s->next_chan); 592 + 593 + if (found) { 594 + expire_time = t_now + NANOSECONDS_PER_SECOND / 4000; 595 + timer_mod(s->frame_timer, expire_time); 596 + } 597 + s->working = false; 598 + } 599 + 600 + static void dwc2_enable_chan(DWC2State *s, uint32_t index) 601 + { 602 + USBDevice *dev; 603 + USBEndpoint *ep; 604 + uint32_t hcchar; 605 + uint32_t hctsiz; 606 + uint32_t devadr, epnum, epdir, eptype, pid, len; 607 + DWC2Packet *p; 608 + 609 + assert((index >> 3) < DWC2_NB_CHAN); 610 + p = &s->packet[index >> 3]; 611 + hcchar = s->hreg1[index]; 612 + hctsiz = s->hreg1[index + 4]; 613 + devadr = get_field(hcchar, HCCHAR_DEVADDR); 614 + epnum = get_field(hcchar, HCCHAR_EPNUM); 615 + epdir = get_bit(hcchar, HCCHAR_EPDIR); 616 + eptype = get_field(hcchar, HCCHAR_EPTYPE); 617 + pid = get_field(hctsiz, TSIZ_SC_MC_PID); 618 + len = get_field(hctsiz, TSIZ_XFERSIZE); 619 + 620 + dev = dwc2_find_device(s, devadr); 621 + 622 + trace_usb_dwc2_enable_chan(index >> 3, dev, &p->packet, epnum); 623 + if (dev == NULL) { 624 + return; 625 + } 626 + 627 + if (eptype == USB_ENDPOINT_XFER_CONTROL && pid == TSIZ_SC_MC_PID_SETUP) { 628 + pid = USB_TOKEN_SETUP; 629 + } else { 630 + pid = epdir ? USB_TOKEN_IN : USB_TOKEN_OUT; 631 + } 632 + 633 + ep = usb_ep_get(dev, pid, epnum); 634 + 635 + /* 636 + * Hack: Networking doesn't like us delivering large transfers, it kind 637 + * of works but the latency is horrible. So if the transfer is <= the mtu 638 + * size, we take that as a hint that this might be a network transfer, 639 + * and do the transfer packet-by-packet. 640 + */ 641 + if (len > 1536) { 642 + p->small = false; 643 + } else { 644 + p->small = true; 645 + } 646 + 647 + dwc2_handle_packet(s, devadr, dev, ep, index, true); 648 + qemu_bh_schedule(s->async_bh); 649 + } 650 + 651 + static const char *glbregnm[] = { 652 + "GOTGCTL ", "GOTGINT ", "GAHBCFG ", "GUSBCFG ", "GRSTCTL ", 653 + "GINTSTS ", "GINTMSK ", "GRXSTSR ", "GRXSTSP ", "GRXFSIZ ", 654 + "GNPTXFSIZ", "GNPTXSTS ", "GI2CCTL ", "GPVNDCTL ", "GGPIO ", 655 + "GUID ", "GSNPSID ", "GHWCFG1 ", "GHWCFG2 ", "GHWCFG3 ", 656 + "GHWCFG4 ", "GLPMCFG ", "GPWRDN ", "GDFIFOCFG", "GADPCTL ", 657 + "GREFCLK ", "GINTMSK2 ", "GINTSTS2 " 658 + }; 659 + 660 + static uint64_t dwc2_glbreg_read(void *ptr, hwaddr addr, int index, 661 + unsigned size) 662 + { 663 + DWC2State *s = ptr; 664 + uint32_t val; 665 + 666 + assert(addr <= GINTSTS2); 667 + val = s->glbreg[index]; 668 + 669 + switch (addr) { 670 + case GRSTCTL: 671 + /* clear any self-clearing bits that were set */ 672 + val &= ~(GRSTCTL_TXFFLSH | GRSTCTL_RXFFLSH | GRSTCTL_IN_TKNQ_FLSH | 673 + GRSTCTL_FRMCNTRRST | GRSTCTL_HSFTRST | GRSTCTL_CSFTRST); 674 + s->glbreg[index] = val; 675 + break; 676 + default: 677 + break; 678 + } 679 + 680 + trace_usb_dwc2_glbreg_read(addr, glbregnm[index], val); 681 + return val; 682 + } 683 + 684 + static void dwc2_glbreg_write(void *ptr, hwaddr addr, int index, uint64_t val, 685 + unsigned size) 686 + { 687 + DWC2State *s = ptr; 688 + uint64_t orig = val; 689 + uint32_t *mmio; 690 + uint32_t old; 691 + int iflg = 0; 692 + 693 + assert(addr <= GINTSTS2); 694 + mmio = &s->glbreg[index]; 695 + old = *mmio; 696 + 697 + switch (addr) { 698 + case GOTGCTL: 699 + /* don't allow setting of read-only bits */ 700 + val &= ~(GOTGCTL_MULT_VALID_BC_MASK | GOTGCTL_BSESVLD | 701 + GOTGCTL_ASESVLD | GOTGCTL_DBNC_SHORT | GOTGCTL_CONID_B | 702 + GOTGCTL_HSTNEGSCS | GOTGCTL_SESREQSCS); 703 + /* don't allow clearing of read-only bits */ 704 + val |= old & (GOTGCTL_MULT_VALID_BC_MASK | GOTGCTL_BSESVLD | 705 + GOTGCTL_ASESVLD | GOTGCTL_DBNC_SHORT | GOTGCTL_CONID_B | 706 + GOTGCTL_HSTNEGSCS | GOTGCTL_SESREQSCS); 707 + break; 708 + case GAHBCFG: 709 + if ((val & GAHBCFG_GLBL_INTR_EN) && !(old & GAHBCFG_GLBL_INTR_EN)) { 710 + iflg = 1; 711 + } 712 + break; 713 + case GRSTCTL: 714 + val |= GRSTCTL_AHBIDLE; 715 + val &= ~GRSTCTL_DMAREQ; 716 + if (!(old & GRSTCTL_TXFFLSH) && (val & GRSTCTL_TXFFLSH)) { 717 + /* TODO - TX fifo flush */ 718 + qemu_log_mask(LOG_UNIMP, "Tx FIFO flush not implemented\n"); 719 + } 720 + if (!(old & GRSTCTL_RXFFLSH) && (val & GRSTCTL_RXFFLSH)) { 721 + /* TODO - RX fifo flush */ 722 + qemu_log_mask(LOG_UNIMP, "Rx FIFO flush not implemented\n"); 723 + } 724 + if (!(old & GRSTCTL_IN_TKNQ_FLSH) && (val & GRSTCTL_IN_TKNQ_FLSH)) { 725 + /* TODO - device IN token queue flush */ 726 + qemu_log_mask(LOG_UNIMP, "Token queue flush not implemented\n"); 727 + } 728 + if (!(old & GRSTCTL_FRMCNTRRST) && (val & GRSTCTL_FRMCNTRRST)) { 729 + /* TODO - host frame counter reset */ 730 + qemu_log_mask(LOG_UNIMP, "Frame counter reset not implemented\n"); 731 + } 732 + if (!(old & GRSTCTL_HSFTRST) && (val & GRSTCTL_HSFTRST)) { 733 + /* TODO - host soft reset */ 734 + qemu_log_mask(LOG_UNIMP, "Host soft reset not implemented\n"); 735 + } 736 + if (!(old & GRSTCTL_CSFTRST) && (val & GRSTCTL_CSFTRST)) { 737 + /* TODO - core soft reset */ 738 + qemu_log_mask(LOG_UNIMP, "Core soft reset not implemented\n"); 739 + } 740 + /* don't allow clearing of self-clearing bits */ 741 + val |= old & (GRSTCTL_TXFFLSH | GRSTCTL_RXFFLSH | 742 + GRSTCTL_IN_TKNQ_FLSH | GRSTCTL_FRMCNTRRST | 743 + GRSTCTL_HSFTRST | GRSTCTL_CSFTRST); 744 + break; 745 + case GINTSTS: 746 + /* clear the write-1-to-clear bits */ 747 + val |= ~old; 748 + val = ~val; 749 + /* don't allow clearing of read-only bits */ 750 + val |= old & (GINTSTS_PTXFEMP | GINTSTS_HCHINT | GINTSTS_PRTINT | 751 + GINTSTS_OEPINT | GINTSTS_IEPINT | GINTSTS_GOUTNAKEFF | 752 + GINTSTS_GINNAKEFF | GINTSTS_NPTXFEMP | GINTSTS_RXFLVL | 753 + GINTSTS_OTGINT | GINTSTS_CURMODE_HOST); 754 + iflg = 1; 755 + break; 756 + case GINTMSK: 757 + iflg = 1; 758 + break; 759 + default: 760 + break; 761 + } 762 + 763 + trace_usb_dwc2_glbreg_write(addr, glbregnm[index], orig, old, val); 764 + *mmio = val; 765 + 766 + if (iflg) { 767 + dwc2_update_irq(s); 768 + } 769 + } 770 + 771 + static uint64_t dwc2_fszreg_read(void *ptr, hwaddr addr, int index, 772 + unsigned size) 773 + { 774 + DWC2State *s = ptr; 775 + uint32_t val; 776 + 777 + assert(addr == HPTXFSIZ); 778 + val = s->fszreg[index]; 779 + 780 + trace_usb_dwc2_fszreg_read(addr, val); 781 + return val; 782 + } 783 + 784 + static void dwc2_fszreg_write(void *ptr, hwaddr addr, int index, uint64_t val, 785 + unsigned size) 786 + { 787 + DWC2State *s = ptr; 788 + uint64_t orig = val; 789 + uint32_t *mmio; 790 + uint32_t old; 791 + 792 + assert(addr == HPTXFSIZ); 793 + mmio = &s->fszreg[index]; 794 + old = *mmio; 795 + 796 + trace_usb_dwc2_fszreg_write(addr, orig, old, val); 797 + *mmio = val; 798 + } 799 + 800 + static const char *hreg0nm[] = { 801 + "HCFG ", "HFIR ", "HFNUM ", "<rsvd> ", "HPTXSTS ", 802 + "HAINT ", "HAINTMSK ", "HFLBADDR ", "<rsvd> ", "<rsvd> ", 803 + "<rsvd> ", "<rsvd> ", "<rsvd> ", "<rsvd> ", "<rsvd> ", 804 + "<rsvd> ", "HPRT0 " 805 + }; 806 + 807 + static uint64_t dwc2_hreg0_read(void *ptr, hwaddr addr, int index, 808 + unsigned size) 809 + { 810 + DWC2State *s = ptr; 811 + uint32_t val; 812 + 813 + assert(addr >= HCFG && addr <= HPRT0); 814 + val = s->hreg0[index]; 815 + 816 + switch (addr) { 817 + case HFNUM: 818 + val = (dwc2_get_frame_remaining(s) << HFNUM_FRREM_SHIFT) | 819 + (s->hfnum << HFNUM_FRNUM_SHIFT); 820 + break; 821 + default: 822 + break; 823 + } 824 + 825 + trace_usb_dwc2_hreg0_read(addr, hreg0nm[index], val); 826 + return val; 827 + } 828 + 829 + static void dwc2_hreg0_write(void *ptr, hwaddr addr, int index, uint64_t val, 830 + unsigned size) 831 + { 832 + DWC2State *s = ptr; 833 + USBDevice *dev = s->uport.dev; 834 + uint64_t orig = val; 835 + uint32_t *mmio; 836 + uint32_t tval, told, old; 837 + int prst = 0; 838 + int iflg = 0; 839 + 840 + assert(addr >= HCFG && addr <= HPRT0); 841 + mmio = &s->hreg0[index]; 842 + old = *mmio; 843 + 844 + switch (addr) { 845 + case HFIR: 846 + break; 847 + case HFNUM: 848 + case HPTXSTS: 849 + case HAINT: 850 + qemu_log_mask(LOG_GUEST_ERROR, "%s: write to read-only register\n", 851 + __func__); 852 + return; 853 + case HAINTMSK: 854 + val &= 0xffff; 855 + break; 856 + case HPRT0: 857 + /* don't allow clearing of read-only bits */ 858 + val |= old & (HPRT0_SPD_MASK | HPRT0_LNSTS_MASK | HPRT0_OVRCURRACT | 859 + HPRT0_CONNSTS); 860 + /* don't allow clearing of self-clearing bits */ 861 + val |= old & (HPRT0_SUSP | HPRT0_RES); 862 + /* don't allow setting of self-setting bits */ 863 + if (!(old & HPRT0_ENA) && (val & HPRT0_ENA)) { 864 + val &= ~HPRT0_ENA; 865 + } 866 + /* clear the write-1-to-clear bits */ 867 + tval = val & (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA | 868 + HPRT0_CONNDET); 869 + told = old & (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA | 870 + HPRT0_CONNDET); 871 + tval |= ~told; 872 + tval = ~tval; 873 + tval &= (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA | 874 + HPRT0_CONNDET); 875 + val &= ~(HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA | 876 + HPRT0_CONNDET); 877 + val |= tval; 878 + if (!(val & HPRT0_RST) && (old & HPRT0_RST)) { 879 + if (dev && dev->attached) { 880 + val |= HPRT0_ENA | HPRT0_ENACHG; 881 + prst = 1; 882 + } 883 + } 884 + if (val & (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_CONNDET)) { 885 + iflg = 1; 886 + } else { 887 + iflg = -1; 888 + } 889 + break; 890 + default: 891 + break; 892 + } 893 + 894 + if (prst) { 895 + trace_usb_dwc2_hreg0_write(addr, hreg0nm[index], orig, old, 896 + val & ~HPRT0_CONNDET); 897 + trace_usb_dwc2_hreg0_action("call usb_port_reset"); 898 + usb_port_reset(&s->uport); 899 + val &= ~HPRT0_CONNDET; 900 + } else { 901 + trace_usb_dwc2_hreg0_write(addr, hreg0nm[index], orig, old, val); 902 + } 903 + 904 + *mmio = val; 905 + 906 + if (iflg > 0) { 907 + trace_usb_dwc2_hreg0_action("enable PRTINT"); 908 + dwc2_raise_global_irq(s, GINTSTS_PRTINT); 909 + } else if (iflg < 0) { 910 + trace_usb_dwc2_hreg0_action("disable PRTINT"); 911 + dwc2_lower_global_irq(s, GINTSTS_PRTINT); 912 + } 913 + } 914 + 915 + static const char *hreg1nm[] = { 916 + "HCCHAR ", "HCSPLT ", "HCINT ", "HCINTMSK", "HCTSIZ ", "HCDMA ", 917 + "<rsvd> ", "HCDMAB " 918 + }; 919 + 920 + static uint64_t dwc2_hreg1_read(void *ptr, hwaddr addr, int index, 921 + unsigned size) 922 + { 923 + DWC2State *s = ptr; 924 + uint32_t val; 925 + 926 + assert(addr >= HCCHAR(0) && addr <= HCDMAB(DWC2_NB_CHAN - 1)); 927 + val = s->hreg1[index]; 928 + 929 + trace_usb_dwc2_hreg1_read(addr, hreg1nm[index & 7], addr >> 5, val); 930 + return val; 931 + } 932 + 933 + static void dwc2_hreg1_write(void *ptr, hwaddr addr, int index, uint64_t val, 934 + unsigned size) 935 + { 936 + DWC2State *s = ptr; 937 + uint64_t orig = val; 938 + uint32_t *mmio; 939 + uint32_t old; 940 + int iflg = 0; 941 + int enflg = 0; 942 + int disflg = 0; 943 + 944 + assert(addr >= HCCHAR(0) && addr <= HCDMAB(DWC2_NB_CHAN - 1)); 945 + mmio = &s->hreg1[index]; 946 + old = *mmio; 947 + 948 + switch (HSOTG_REG(0x500) + (addr & 0x1c)) { 949 + case HCCHAR(0): 950 + if ((val & HCCHAR_CHDIS) && !(old & HCCHAR_CHDIS)) { 951 + val &= ~(HCCHAR_CHENA | HCCHAR_CHDIS); 952 + disflg = 1; 953 + } else { 954 + val |= old & HCCHAR_CHDIS; 955 + if ((val & HCCHAR_CHENA) && !(old & HCCHAR_CHENA)) { 956 + val &= ~HCCHAR_CHDIS; 957 + enflg = 1; 958 + } else { 959 + val |= old & HCCHAR_CHENA; 960 + } 961 + } 962 + break; 963 + case HCINT(0): 964 + /* clear the write-1-to-clear bits */ 965 + val |= ~old; 966 + val = ~val; 967 + val &= ~HCINTMSK_RESERVED14_31; 968 + iflg = 1; 969 + break; 970 + case HCINTMSK(0): 971 + val &= ~HCINTMSK_RESERVED14_31; 972 + iflg = 1; 973 + break; 974 + case HCDMAB(0): 975 + qemu_log_mask(LOG_GUEST_ERROR, "%s: write to read-only register\n", 976 + __func__); 977 + return; 978 + default: 979 + break; 980 + } 981 + 982 + trace_usb_dwc2_hreg1_write(addr, hreg1nm[index & 7], index >> 3, orig, 983 + old, val); 984 + *mmio = val; 985 + 986 + if (disflg) { 987 + /* set ChHltd in HCINT */ 988 + s->hreg1[(index & ~7) + 2] |= HCINTMSK_CHHLTD; 989 + iflg = 1; 990 + } 991 + 992 + if (enflg) { 993 + dwc2_enable_chan(s, index & ~7); 994 + } 995 + 996 + if (iflg) { 997 + dwc2_update_hc_irq(s, index & ~7); 998 + } 999 + } 1000 + 1001 + static const char *pcgregnm[] = { 1002 + "PCGCTL ", "PCGCCTL1 " 1003 + }; 1004 + 1005 + static uint64_t dwc2_pcgreg_read(void *ptr, hwaddr addr, int index, 1006 + unsigned size) 1007 + { 1008 + DWC2State *s = ptr; 1009 + uint32_t val; 1010 + 1011 + assert(addr >= PCGCTL && addr <= PCGCCTL1); 1012 + val = s->pcgreg[index]; 1013 + 1014 + trace_usb_dwc2_pcgreg_read(addr, pcgregnm[index], val); 1015 + return val; 1016 + } 1017 + 1018 + static void dwc2_pcgreg_write(void *ptr, hwaddr addr, int index, 1019 + uint64_t val, unsigned size) 1020 + { 1021 + DWC2State *s = ptr; 1022 + uint64_t orig = val; 1023 + uint32_t *mmio; 1024 + uint32_t old; 1025 + 1026 + assert(addr >= PCGCTL && addr <= PCGCCTL1); 1027 + mmio = &s->pcgreg[index]; 1028 + old = *mmio; 1029 + 1030 + trace_usb_dwc2_pcgreg_write(addr, pcgregnm[index], orig, old, val); 1031 + *mmio = val; 1032 + } 1033 + 1034 + static uint64_t dwc2_hsotg_read(void *ptr, hwaddr addr, unsigned size) 1035 + { 1036 + uint64_t val; 1037 + 1038 + switch (addr) { 1039 + case HSOTG_REG(0x000) ... HSOTG_REG(0x0fc): 1040 + val = dwc2_glbreg_read(ptr, addr, (addr - HSOTG_REG(0x000)) >> 2, size); 1041 + break; 1042 + case HSOTG_REG(0x100): 1043 + val = dwc2_fszreg_read(ptr, addr, (addr - HSOTG_REG(0x100)) >> 2, size); 1044 + break; 1045 + case HSOTG_REG(0x104) ... HSOTG_REG(0x3fc): 1046 + /* Gadget-mode registers, just return 0 for now */ 1047 + val = 0; 1048 + break; 1049 + case HSOTG_REG(0x400) ... HSOTG_REG(0x4fc): 1050 + val = dwc2_hreg0_read(ptr, addr, (addr - HSOTG_REG(0x400)) >> 2, size); 1051 + break; 1052 + case HSOTG_REG(0x500) ... HSOTG_REG(0x7fc): 1053 + val = dwc2_hreg1_read(ptr, addr, (addr - HSOTG_REG(0x500)) >> 2, size); 1054 + break; 1055 + case HSOTG_REG(0x800) ... HSOTG_REG(0xdfc): 1056 + /* Gadget-mode registers, just return 0 for now */ 1057 + val = 0; 1058 + break; 1059 + case HSOTG_REG(0xe00) ... HSOTG_REG(0xffc): 1060 + val = dwc2_pcgreg_read(ptr, addr, (addr - HSOTG_REG(0xe00)) >> 2, size); 1061 + break; 1062 + default: 1063 + g_assert_not_reached(); 1064 + } 1065 + 1066 + return val; 1067 + } 1068 + 1069 + static void dwc2_hsotg_write(void *ptr, hwaddr addr, uint64_t val, 1070 + unsigned size) 1071 + { 1072 + switch (addr) { 1073 + case HSOTG_REG(0x000) ... HSOTG_REG(0x0fc): 1074 + dwc2_glbreg_write(ptr, addr, (addr - HSOTG_REG(0x000)) >> 2, val, size); 1075 + break; 1076 + case HSOTG_REG(0x100): 1077 + dwc2_fszreg_write(ptr, addr, (addr - HSOTG_REG(0x100)) >> 2, val, size); 1078 + break; 1079 + case HSOTG_REG(0x104) ... HSOTG_REG(0x3fc): 1080 + /* Gadget-mode registers, do nothing for now */ 1081 + break; 1082 + case HSOTG_REG(0x400) ... HSOTG_REG(0x4fc): 1083 + dwc2_hreg0_write(ptr, addr, (addr - HSOTG_REG(0x400)) >> 2, val, size); 1084 + break; 1085 + case HSOTG_REG(0x500) ... HSOTG_REG(0x7fc): 1086 + dwc2_hreg1_write(ptr, addr, (addr - HSOTG_REG(0x500)) >> 2, val, size); 1087 + break; 1088 + case HSOTG_REG(0x800) ... HSOTG_REG(0xdfc): 1089 + /* Gadget-mode registers, do nothing for now */ 1090 + break; 1091 + case HSOTG_REG(0xe00) ... HSOTG_REG(0xffc): 1092 + dwc2_pcgreg_write(ptr, addr, (addr - HSOTG_REG(0xe00)) >> 2, val, size); 1093 + break; 1094 + default: 1095 + g_assert_not_reached(); 1096 + } 1097 + } 1098 + 1099 + static const MemoryRegionOps dwc2_mmio_hsotg_ops = { 1100 + .read = dwc2_hsotg_read, 1101 + .write = dwc2_hsotg_write, 1102 + .impl.min_access_size = 4, 1103 + .impl.max_access_size = 4, 1104 + .endianness = DEVICE_LITTLE_ENDIAN, 1105 + }; 1106 + 1107 + static uint64_t dwc2_hreg2_read(void *ptr, hwaddr addr, unsigned size) 1108 + { 1109 + /* TODO - implement FIFOs to support slave mode */ 1110 + trace_usb_dwc2_hreg2_read(addr, addr >> 12, 0); 1111 + qemu_log_mask(LOG_UNIMP, "FIFO read not implemented\n"); 1112 + return 0; 1113 + } 1114 + 1115 + static void dwc2_hreg2_write(void *ptr, hwaddr addr, uint64_t val, 1116 + unsigned size) 1117 + { 1118 + uint64_t orig = val; 1119 + 1120 + /* TODO - implement FIFOs to support slave mode */ 1121 + trace_usb_dwc2_hreg2_write(addr, addr >> 12, orig, 0, val); 1122 + qemu_log_mask(LOG_UNIMP, "FIFO write not implemented\n"); 1123 + } 1124 + 1125 + static const MemoryRegionOps dwc2_mmio_hreg2_ops = { 1126 + .read = dwc2_hreg2_read, 1127 + .write = dwc2_hreg2_write, 1128 + .impl.min_access_size = 4, 1129 + .impl.max_access_size = 4, 1130 + .endianness = DEVICE_LITTLE_ENDIAN, 1131 + }; 1132 + 1133 + static void dwc2_wakeup_endpoint(USBBus *bus, USBEndpoint *ep, 1134 + unsigned int stream) 1135 + { 1136 + DWC2State *s = container_of(bus, DWC2State, bus); 1137 + 1138 + trace_usb_dwc2_wakeup_endpoint(ep, stream); 1139 + 1140 + /* TODO - do something here? */ 1141 + qemu_bh_schedule(s->async_bh); 1142 + } 1143 + 1144 + static USBBusOps dwc2_bus_ops = { 1145 + .wakeup_endpoint = dwc2_wakeup_endpoint, 1146 + }; 1147 + 1148 + static void dwc2_work_timer(void *opaque) 1149 + { 1150 + DWC2State *s = opaque; 1151 + 1152 + trace_usb_dwc2_work_timer(); 1153 + qemu_bh_schedule(s->async_bh); 1154 + } 1155 + 1156 + static void dwc2_reset_enter(Object *obj, ResetType type) 1157 + { 1158 + DWC2Class *c = DWC2_GET_CLASS(obj); 1159 + DWC2State *s = DWC2_USB(obj); 1160 + int i; 1161 + 1162 + trace_usb_dwc2_reset_enter(); 1163 + 1164 + if (c->parent_phases.enter) { 1165 + c->parent_phases.enter(obj, type); 1166 + } 1167 + 1168 + timer_del(s->frame_timer); 1169 + qemu_bh_cancel(s->async_bh); 1170 + 1171 + if (s->uport.dev && s->uport.dev->attached) { 1172 + usb_detach(&s->uport); 1173 + } 1174 + 1175 + dwc2_bus_stop(s); 1176 + 1177 + s->gotgctl = GOTGCTL_BSESVLD | GOTGCTL_ASESVLD | GOTGCTL_CONID_B; 1178 + s->gotgint = 0; 1179 + s->gahbcfg = 0; 1180 + s->gusbcfg = 5 << GUSBCFG_USBTRDTIM_SHIFT; 1181 + s->grstctl = GRSTCTL_AHBIDLE; 1182 + s->gintsts = GINTSTS_CONIDSTSCHNG | GINTSTS_PTXFEMP | GINTSTS_NPTXFEMP | 1183 + GINTSTS_CURMODE_HOST; 1184 + s->gintmsk = 0; 1185 + s->grxstsr = 0; 1186 + s->grxstsp = 0; 1187 + s->grxfsiz = 1024; 1188 + s->gnptxfsiz = 1024 << FIFOSIZE_DEPTH_SHIFT; 1189 + s->gnptxsts = (4 << FIFOSIZE_DEPTH_SHIFT) | 1024; 1190 + s->gi2cctl = GI2CCTL_I2CDATSE0 | GI2CCTL_ACK; 1191 + s->gpvndctl = 0; 1192 + s->ggpio = 0; 1193 + s->guid = 0; 1194 + s->gsnpsid = 0x4f54294a; 1195 + s->ghwcfg1 = 0; 1196 + s->ghwcfg2 = (8 << GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT) | 1197 + (4 << GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT) | 1198 + (4 << GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT) | 1199 + GHWCFG2_DYNAMIC_FIFO | 1200 + GHWCFG2_PERIO_EP_SUPPORTED | 1201 + ((DWC2_NB_CHAN - 1) << GHWCFG2_NUM_HOST_CHAN_SHIFT) | 1202 + (GHWCFG2_INT_DMA_ARCH << GHWCFG2_ARCHITECTURE_SHIFT) | 1203 + (GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST << GHWCFG2_OP_MODE_SHIFT); 1204 + s->ghwcfg3 = (4096 << GHWCFG3_DFIFO_DEPTH_SHIFT) | 1205 + (4 << GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT) | 1206 + (4 << GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT); 1207 + s->ghwcfg4 = 0; 1208 + s->glpmcfg = 0; 1209 + s->gpwrdn = GPWRDN_PWRDNRSTN; 1210 + s->gdfifocfg = 0; 1211 + s->gadpctl = 0; 1212 + s->grefclk = 0; 1213 + s->gintmsk2 = 0; 1214 + s->gintsts2 = 0; 1215 + 1216 + s->hptxfsiz = 500 << FIFOSIZE_DEPTH_SHIFT; 1217 + 1218 + s->hcfg = 2 << HCFG_RESVALID_SHIFT; 1219 + s->hfir = 60000; 1220 + s->hfnum = 0x3fff; 1221 + s->hptxsts = (16 << TXSTS_QSPCAVAIL_SHIFT) | 32768; 1222 + s->haint = 0; 1223 + s->haintmsk = 0; 1224 + s->hprt0 = 0; 1225 + 1226 + memset(s->hreg1, 0, sizeof(s->hreg1)); 1227 + memset(s->pcgreg, 0, sizeof(s->pcgreg)); 1228 + 1229 + s->sof_time = 0; 1230 + s->frame_number = 0; 1231 + s->fi = USB_FRMINTVL - 1; 1232 + s->next_chan = 0; 1233 + s->working = false; 1234 + 1235 + for (i = 0; i < DWC2_NB_CHAN; i++) { 1236 + s->packet[i].needs_service = false; 1237 + } 1238 + } 1239 + 1240 + static void dwc2_reset_hold(Object *obj) 1241 + { 1242 + DWC2Class *c = DWC2_GET_CLASS(obj); 1243 + DWC2State *s = DWC2_USB(obj); 1244 + 1245 + trace_usb_dwc2_reset_hold(); 1246 + 1247 + if (c->parent_phases.hold) { 1248 + c->parent_phases.hold(obj); 1249 + } 1250 + 1251 + dwc2_update_irq(s); 1252 + } 1253 + 1254 + static void dwc2_reset_exit(Object *obj) 1255 + { 1256 + DWC2Class *c = DWC2_GET_CLASS(obj); 1257 + DWC2State *s = DWC2_USB(obj); 1258 + 1259 + trace_usb_dwc2_reset_exit(); 1260 + 1261 + if (c->parent_phases.exit) { 1262 + c->parent_phases.exit(obj); 1263 + } 1264 + 1265 + s->hprt0 = HPRT0_PWR; 1266 + if (s->uport.dev && s->uport.dev->attached) { 1267 + usb_attach(&s->uport); 1268 + usb_device_reset(s->uport.dev); 1269 + } 1270 + } 1271 + 1272 + static void dwc2_realize(DeviceState *dev, Error **errp) 1273 + { 1274 + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 1275 + DWC2State *s = DWC2_USB(dev); 1276 + Object *obj; 1277 + Error *err = NULL; 1278 + 1279 + obj = object_property_get_link(OBJECT(dev), "dma-mr", &err); 1280 + if (err) { 1281 + error_setg(errp, "dwc2: required dma-mr link not found: %s", 1282 + error_get_pretty(err)); 1283 + return; 1284 + } 1285 + assert(obj != NULL); 1286 + 1287 + s->dma_mr = MEMORY_REGION(obj); 1288 + address_space_init(&s->dma_as, s->dma_mr, "dwc2"); 1289 + 1290 + usb_bus_new(&s->bus, sizeof(s->bus), &dwc2_bus_ops, dev); 1291 + usb_register_port(&s->bus, &s->uport, s, 0, &dwc2_port_ops, 1292 + USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL | 1293 + (s->usb_version == 2 ? USB_SPEED_MASK_HIGH : 0)); 1294 + s->uport.dev = 0; 1295 + 1296 + s->usb_frame_time = NANOSECONDS_PER_SECOND / 1000; /* 1000000 */ 1297 + if (NANOSECONDS_PER_SECOND >= USB_HZ_FS) { 1298 + s->usb_bit_time = NANOSECONDS_PER_SECOND / USB_HZ_FS; /* 83.3 */ 1299 + } else { 1300 + s->usb_bit_time = 1; 1301 + } 1302 + 1303 + s->fi = USB_FRMINTVL - 1; 1304 + s->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_frame_boundary, s); 1305 + s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_work_timer, s); 1306 + s->async_bh = qemu_bh_new(dwc2_work_bh, s); 1307 + 1308 + sysbus_init_irq(sbd, &s->irq); 1309 + } 1310 + 1311 + static void dwc2_init(Object *obj) 1312 + { 1313 + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 1314 + DWC2State *s = DWC2_USB(obj); 1315 + 1316 + memory_region_init(&s->container, obj, "dwc2", DWC2_MMIO_SIZE); 1317 + sysbus_init_mmio(sbd, &s->container); 1318 + 1319 + memory_region_init_io(&s->hsotg, obj, &dwc2_mmio_hsotg_ops, s, 1320 + "dwc2-io", 4 * KiB); 1321 + memory_region_add_subregion(&s->container, 0x0000, &s->hsotg); 1322 + 1323 + memory_region_init_io(&s->fifos, obj, &dwc2_mmio_hreg2_ops, s, 1324 + "dwc2-fifo", 64 * KiB); 1325 + memory_region_add_subregion(&s->container, 0x1000, &s->fifos); 1326 + } 1327 + 1328 + static const VMStateDescription vmstate_dwc2_state_packet = { 1329 + .name = "dwc2/packet", 1330 + .version_id = 1, 1331 + .minimum_version_id = 1, 1332 + .fields = (VMStateField[]) { 1333 + VMSTATE_UINT32(devadr, DWC2Packet), 1334 + VMSTATE_UINT32(epnum, DWC2Packet), 1335 + VMSTATE_UINT32(epdir, DWC2Packet), 1336 + VMSTATE_UINT32(mps, DWC2Packet), 1337 + VMSTATE_UINT32(pid, DWC2Packet), 1338 + VMSTATE_UINT32(index, DWC2Packet), 1339 + VMSTATE_UINT32(pcnt, DWC2Packet), 1340 + VMSTATE_UINT32(len, DWC2Packet), 1341 + VMSTATE_INT32(async, DWC2Packet), 1342 + VMSTATE_BOOL(small, DWC2Packet), 1343 + VMSTATE_BOOL(needs_service, DWC2Packet), 1344 + VMSTATE_END_OF_LIST() 1345 + }, 1346 + }; 1347 + 1348 + const VMStateDescription vmstate_dwc2_state = { 1349 + .name = "dwc2", 1350 + .version_id = 1, 1351 + .minimum_version_id = 1, 1352 + .fields = (VMStateField[]) { 1353 + VMSTATE_UINT32_ARRAY(glbreg, DWC2State, 1354 + DWC2_GLBREG_SIZE / sizeof(uint32_t)), 1355 + VMSTATE_UINT32_ARRAY(fszreg, DWC2State, 1356 + DWC2_FSZREG_SIZE / sizeof(uint32_t)), 1357 + VMSTATE_UINT32_ARRAY(hreg0, DWC2State, 1358 + DWC2_HREG0_SIZE / sizeof(uint32_t)), 1359 + VMSTATE_UINT32_ARRAY(hreg1, DWC2State, 1360 + DWC2_HREG1_SIZE / sizeof(uint32_t)), 1361 + VMSTATE_UINT32_ARRAY(pcgreg, DWC2State, 1362 + DWC2_PCGREG_SIZE / sizeof(uint32_t)), 1363 + 1364 + VMSTATE_TIMER_PTR(eof_timer, DWC2State), 1365 + VMSTATE_TIMER_PTR(frame_timer, DWC2State), 1366 + VMSTATE_INT64(sof_time, DWC2State), 1367 + VMSTATE_INT64(usb_frame_time, DWC2State), 1368 + VMSTATE_INT64(usb_bit_time, DWC2State), 1369 + VMSTATE_UINT32(usb_version, DWC2State), 1370 + VMSTATE_UINT16(frame_number, DWC2State), 1371 + VMSTATE_UINT16(fi, DWC2State), 1372 + VMSTATE_UINT16(next_chan, DWC2State), 1373 + VMSTATE_BOOL(working, DWC2State), 1374 + 1375 + VMSTATE_STRUCT_ARRAY(packet, DWC2State, DWC2_NB_CHAN, 1, 1376 + vmstate_dwc2_state_packet, DWC2Packet), 1377 + VMSTATE_UINT8_2DARRAY(usb_buf, DWC2State, DWC2_NB_CHAN, 1378 + DWC2_MAX_XFER_SIZE), 1379 + 1380 + VMSTATE_END_OF_LIST() 1381 + } 1382 + }; 1383 + 1384 + static Property dwc2_usb_properties[] = { 1385 + DEFINE_PROP_UINT32("usb_version", DWC2State, usb_version, 2), 1386 + DEFINE_PROP_END_OF_LIST(), 1387 + }; 1388 + 1389 + static void dwc2_class_init(ObjectClass *klass, void *data) 1390 + { 1391 + DeviceClass *dc = DEVICE_CLASS(klass); 1392 + DWC2Class *c = DWC2_CLASS(klass); 1393 + ResettableClass *rc = RESETTABLE_CLASS(klass); 1394 + 1395 + dc->realize = dwc2_realize; 1396 + dc->vmsd = &vmstate_dwc2_state; 1397 + set_bit(DEVICE_CATEGORY_USB, dc->categories); 1398 + device_class_set_props(dc, dwc2_usb_properties); 1399 + resettable_class_set_parent_phases(rc, dwc2_reset_enter, dwc2_reset_hold, 1400 + dwc2_reset_exit, &c->parent_phases); 1401 + } 1402 + 1403 + static const TypeInfo dwc2_usb_type_info = { 1404 + .name = TYPE_DWC2_USB, 1405 + .parent = TYPE_SYS_BUS_DEVICE, 1406 + .instance_size = sizeof(DWC2State), 1407 + .instance_init = dwc2_init, 1408 + .class_size = sizeof(DWC2Class), 1409 + .class_init = dwc2_class_init, 1410 + }; 1411 + 1412 + static void dwc2_usb_register_types(void) 1413 + { 1414 + type_register_static(&dwc2_usb_type_info); 1415 + } 1416 + 1417 + type_init(dwc2_usb_register_types)
+190
hw/usb/hcd-dwc2.h
··· 1 + /* 2 + * dwc-hsotg (dwc2) USB host controller state definitions 3 + * 4 + * Based on hw/usb/hcd-ehci.h 5 + * 6 + * Copyright (c) 2020 Paul Zimmerman <pauldzim@gmail.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License as published by 10 + * the Free Software Foundation; either version 2 of the License, or 11 + * (at your option) any later version. 12 + * 13 + * This program is distributed in the hope that it will be useful, 14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 + * GNU General Public License for more details. 17 + */ 18 + 19 + #ifndef HW_USB_DWC2_H 20 + #define HW_USB_DWC2_H 21 + 22 + #include "qemu/timer.h" 23 + #include "hw/irq.h" 24 + #include "hw/sysbus.h" 25 + #include "hw/usb.h" 26 + #include "sysemu/dma.h" 27 + 28 + #define DWC2_MMIO_SIZE 0x11000 29 + 30 + #define DWC2_NB_CHAN 8 /* Number of host channels */ 31 + #define DWC2_MAX_XFER_SIZE 65536 /* Max transfer size expected in HCTSIZ */ 32 + 33 + typedef struct DWC2Packet DWC2Packet; 34 + typedef struct DWC2State DWC2State; 35 + typedef struct DWC2Class DWC2Class; 36 + 37 + enum async_state { 38 + DWC2_ASYNC_NONE = 0, 39 + DWC2_ASYNC_INITIALIZED, 40 + DWC2_ASYNC_INFLIGHT, 41 + DWC2_ASYNC_FINISHED, 42 + }; 43 + 44 + struct DWC2Packet { 45 + USBPacket packet; 46 + uint32_t devadr; 47 + uint32_t epnum; 48 + uint32_t epdir; 49 + uint32_t mps; 50 + uint32_t pid; 51 + uint32_t index; 52 + uint32_t pcnt; 53 + uint32_t len; 54 + int32_t async; 55 + bool small; 56 + bool needs_service; 57 + }; 58 + 59 + struct DWC2State { 60 + /*< private >*/ 61 + SysBusDevice parent_obj; 62 + 63 + /*< public >*/ 64 + USBBus bus; 65 + qemu_irq irq; 66 + MemoryRegion *dma_mr; 67 + AddressSpace dma_as; 68 + MemoryRegion container; 69 + MemoryRegion hsotg; 70 + MemoryRegion fifos; 71 + 72 + union { 73 + #define DWC2_GLBREG_SIZE 0x70 74 + uint32_t glbreg[DWC2_GLBREG_SIZE / sizeof(uint32_t)]; 75 + struct { 76 + uint32_t gotgctl; /* 00 */ 77 + uint32_t gotgint; /* 04 */ 78 + uint32_t gahbcfg; /* 08 */ 79 + uint32_t gusbcfg; /* 0c */ 80 + uint32_t grstctl; /* 10 */ 81 + uint32_t gintsts; /* 14 */ 82 + uint32_t gintmsk; /* 18 */ 83 + uint32_t grxstsr; /* 1c */ 84 + uint32_t grxstsp; /* 20 */ 85 + uint32_t grxfsiz; /* 24 */ 86 + uint32_t gnptxfsiz; /* 28 */ 87 + uint32_t gnptxsts; /* 2c */ 88 + uint32_t gi2cctl; /* 30 */ 89 + uint32_t gpvndctl; /* 34 */ 90 + uint32_t ggpio; /* 38 */ 91 + uint32_t guid; /* 3c */ 92 + uint32_t gsnpsid; /* 40 */ 93 + uint32_t ghwcfg1; /* 44 */ 94 + uint32_t ghwcfg2; /* 48 */ 95 + uint32_t ghwcfg3; /* 4c */ 96 + uint32_t ghwcfg4; /* 50 */ 97 + uint32_t glpmcfg; /* 54 */ 98 + uint32_t gpwrdn; /* 58 */ 99 + uint32_t gdfifocfg; /* 5c */ 100 + uint32_t gadpctl; /* 60 */ 101 + uint32_t grefclk; /* 64 */ 102 + uint32_t gintmsk2; /* 68 */ 103 + uint32_t gintsts2; /* 6c */ 104 + }; 105 + }; 106 + 107 + union { 108 + #define DWC2_FSZREG_SIZE 0x04 109 + uint32_t fszreg[DWC2_FSZREG_SIZE / sizeof(uint32_t)]; 110 + struct { 111 + uint32_t hptxfsiz; /* 100 */ 112 + }; 113 + }; 114 + 115 + union { 116 + #define DWC2_HREG0_SIZE 0x44 117 + uint32_t hreg0[DWC2_HREG0_SIZE / sizeof(uint32_t)]; 118 + struct { 119 + uint32_t hcfg; /* 400 */ 120 + uint32_t hfir; /* 404 */ 121 + uint32_t hfnum; /* 408 */ 122 + uint32_t rsvd0; /* 40c */ 123 + uint32_t hptxsts; /* 410 */ 124 + uint32_t haint; /* 414 */ 125 + uint32_t haintmsk; /* 418 */ 126 + uint32_t hflbaddr; /* 41c */ 127 + uint32_t rsvd1[8]; /* 420-43c */ 128 + uint32_t hprt0; /* 440 */ 129 + }; 130 + }; 131 + 132 + #define DWC2_HREG1_SIZE (0x20 * DWC2_NB_CHAN) 133 + uint32_t hreg1[DWC2_HREG1_SIZE / sizeof(uint32_t)]; 134 + 135 + #define hcchar(_ch) hreg1[((_ch) << 3) + 0] /* 500, 520, ... */ 136 + #define hcsplt(_ch) hreg1[((_ch) << 3) + 1] /* 504, 524, ... */ 137 + #define hcint(_ch) hreg1[((_ch) << 3) + 2] /* 508, 528, ... */ 138 + #define hcintmsk(_ch) hreg1[((_ch) << 3) + 3] /* 50c, 52c, ... */ 139 + #define hctsiz(_ch) hreg1[((_ch) << 3) + 4] /* 510, 530, ... */ 140 + #define hcdma(_ch) hreg1[((_ch) << 3) + 5] /* 514, 534, ... */ 141 + #define hcdmab(_ch) hreg1[((_ch) << 3) + 7] /* 51c, 53c, ... */ 142 + 143 + union { 144 + #define DWC2_PCGREG_SIZE 0x08 145 + uint32_t pcgreg[DWC2_PCGREG_SIZE / sizeof(uint32_t)]; 146 + struct { 147 + uint32_t pcgctl; /* e00 */ 148 + uint32_t pcgcctl1; /* e04 */ 149 + }; 150 + }; 151 + 152 + /* TODO - implement FIFO registers for slave mode */ 153 + #define DWC2_HFIFO_SIZE (0x1000 * DWC2_NB_CHAN) 154 + 155 + /* 156 + * Internal state 157 + */ 158 + QEMUTimer *eof_timer; 159 + QEMUTimer *frame_timer; 160 + QEMUBH *async_bh; 161 + int64_t sof_time; 162 + int64_t usb_frame_time; 163 + int64_t usb_bit_time; 164 + uint32_t usb_version; 165 + uint16_t frame_number; 166 + uint16_t fi; 167 + uint16_t next_chan; 168 + bool working; 169 + USBPort uport; 170 + DWC2Packet packet[DWC2_NB_CHAN]; /* one packet per chan */ 171 + uint8_t usb_buf[DWC2_NB_CHAN][DWC2_MAX_XFER_SIZE]; /* one buffer per chan */ 172 + }; 173 + 174 + struct DWC2Class { 175 + /*< private >*/ 176 + SysBusDeviceClass parent_class; 177 + ResettablePhases parent_phases; 178 + 179 + /*< public >*/ 180 + }; 181 + 182 + #define TYPE_DWC2_USB "dwc2-usb" 183 + #define DWC2_USB(obj) \ 184 + OBJECT_CHECK(DWC2State, (obj), TYPE_DWC2_USB) 185 + #define DWC2_CLASS(klass) \ 186 + OBJECT_CLASS_CHECK(DWC2Class, (klass), TYPE_DWC2_USB) 187 + #define DWC2_GET_CLASS(obj) \ 188 + OBJECT_GET_CLASS(DWC2Class, (obj), TYPE_DWC2_USB) 189 + 190 + #endif
+50
hw/usb/trace-events
··· 176 176 usb_xhci_unimplemented(const char *item, int nr) "%s (0x%x)" 177 177 usb_xhci_enforced_limit(const char *item) "%s" 178 178 179 + # hcd-dwc2.c 180 + usb_dwc2_update_irq(uint32_t level) "level=%d" 181 + usb_dwc2_raise_global_irq(uint32_t intr) "0x%08x" 182 + usb_dwc2_lower_global_irq(uint32_t intr) "0x%08x" 183 + usb_dwc2_raise_host_irq(uint32_t intr) "0x%04x" 184 + usb_dwc2_lower_host_irq(uint32_t intr) "0x%04x" 185 + usb_dwc2_sof(int64_t next) "next SOF %" PRId64 186 + usb_dwc2_bus_start(void) "start SOFs" 187 + usb_dwc2_bus_stop(void) "stop SOFs" 188 + usb_dwc2_find_device(uint8_t addr) "%d" 189 + usb_dwc2_port_disabled(uint32_t pnum) "port %d disabled" 190 + usb_dwc2_device_found(uint32_t pnum) "device found on port %d" 191 + usb_dwc2_device_not_found(void) "device not found" 192 + usb_dwc2_handle_packet(uint32_t chan, void *dev, void *pkt, uint32_t ep, const char *type, const char *dir, uint32_t mps, uint32_t len, uint32_t pcnt) "ch %d dev %p pkt %p ep %d type %s dir %s mps %d len %d pcnt %d" 193 + usb_dwc2_memory_read(uint32_t addr, uint32_t len) "addr %d len %d" 194 + usb_dwc2_packet_status(const char *status, uint32_t len) "status %s len %d" 195 + usb_dwc2_packet_error(const char *status) "ERROR %s" 196 + usb_dwc2_async_packet(void *pkt, uint32_t chan, void *dev, uint32_t ep, const char *dir, uint32_t len) "pkt %p ch %d dev %p ep %d %s len %d" 197 + usb_dwc2_memory_write(uint32_t addr, uint32_t len) "addr %d len %d" 198 + usb_dwc2_packet_done(const char *status, uint32_t actual, uint32_t len, uint32_t pcnt) "status %s actual %d len %d pcnt %d" 199 + usb_dwc2_packet_next(const char *status, uint32_t len, uint32_t pcnt) "status %s len %d pcnt %d" 200 + usb_dwc2_attach(void *port) "port %p" 201 + usb_dwc2_attach_speed(const char *speed) "%s-speed device attached" 202 + usb_dwc2_detach(void *port) "port %p" 203 + usb_dwc2_child_detach(void *port, void *child) "port %p child %p" 204 + usb_dwc2_wakeup(void *port) "port %p" 205 + usb_dwc2_async_packet_complete(void *port, void *pkt, uint32_t chan, void *dev, uint32_t ep, const char *dir, uint32_t len) "port %p packet %p ch %d dev %p ep %d %s len %d" 206 + usb_dwc2_work_bh(void) "" 207 + usb_dwc2_work_bh_service(uint32_t first, uint32_t current, void *dev, uint32_t ep) "first %d servicing %d dev %p ep %d" 208 + usb_dwc2_work_bh_next(uint32_t chan) "next %d" 209 + usb_dwc2_enable_chan(uint32_t chan, void *dev, void *pkt, uint32_t ep) "ch %d dev %p pkt %p ep %d" 210 + usb_dwc2_glbreg_read(uint64_t addr, const char *reg, uint32_t val) " 0x%04" PRIx64 " %s val 0x%08x" 211 + usb_dwc2_glbreg_write(uint64_t addr, const char *reg, uint64_t val, uint32_t old, uint64_t result) "0x%04" PRIx64 " %s val 0x%08" PRIx64 " old 0x%08x result 0x%08" PRIx64 212 + usb_dwc2_fszreg_read(uint64_t addr, uint32_t val) " 0x%04" PRIx64 " HPTXFSIZ val 0x%08x" 213 + usb_dwc2_fszreg_write(uint64_t addr, uint64_t val, uint32_t old, uint64_t result) "0x%04" PRIx64 " HPTXFSIZ val 0x%08" PRIx64 " old 0x%08x result 0x%08" PRIx64 214 + usb_dwc2_hreg0_read(uint64_t addr, const char *reg, uint32_t val) " 0x%04" PRIx64 " %s val 0x%08x" 215 + usb_dwc2_hreg0_write(uint64_t addr, const char *reg, uint64_t val, uint32_t old, uint64_t result) " 0x%04" PRIx64 " %s val 0x%08" PRIx64 " old 0x%08x result 0x%08" PRIx64 216 + usb_dwc2_hreg1_read(uint64_t addr, const char *reg, uint64_t chan, uint32_t val) " 0x%04" PRIx64 " %s%" PRId64 " val 0x%08x" 217 + usb_dwc2_hreg1_write(uint64_t addr, const char *reg, uint64_t chan, uint64_t val, uint32_t old, uint64_t result) " 0x%04" PRIx64 " %s%" PRId64 " val 0x%08" PRIx64 " old 0x%08x result 0x%08" PRIx64 218 + usb_dwc2_pcgreg_read(uint64_t addr, const char *reg, uint32_t val) " 0x%04" PRIx64 " %s val 0x%08x" 219 + usb_dwc2_pcgreg_write(uint64_t addr, const char *reg, uint64_t val, uint32_t old, uint64_t result) "0x%04" PRIx64 " %s val 0x%08" PRIx64 " old 0x%08x result 0x%08" PRIx64 220 + usb_dwc2_hreg2_read(uint64_t addr, uint64_t fifo, uint32_t val) " 0x%04" PRIx64 " FIFO%" PRId64 " val 0x%08x" 221 + usb_dwc2_hreg2_write(uint64_t addr, uint64_t fifo, uint64_t val, uint32_t old, uint64_t result) " 0x%04" PRIx64 " FIFO%" PRId64 " val 0x%08" PRIx64 " old 0x%08x result 0x%08" PRIx64 222 + usb_dwc2_hreg0_action(const char *s) "%s" 223 + usb_dwc2_wakeup_endpoint(void *ep, uint32_t stream) "endp %p stream %d" 224 + usb_dwc2_work_timer(void) "" 225 + usb_dwc2_reset_enter(void) "=== RESET enter ===" 226 + usb_dwc2_reset_hold(void) "=== RESET hold ===" 227 + usb_dwc2_reset_exit(void) "=== RESET exit ===" 228 + 179 229 # desc.c 180 230 usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d" 181 231 usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device qualifier, len %d, ret %d"
+4 -1
include/hw/arm/bcm2835_peripherals.h
··· 21 21 #include "hw/misc/bcm2835_property.h" 22 22 #include "hw/misc/bcm2835_rng.h" 23 23 #include "hw/misc/bcm2835_mbox.h" 24 + #include "hw/misc/bcm2835_mphi.h" 24 25 #include "hw/misc/bcm2835_thermal.h" 25 26 #include "hw/sd/sdhci.h" 26 27 #include "hw/sd/bcm2835_sdhost.h" 27 28 #include "hw/gpio/bcm2835_gpio.h" 28 29 #include "hw/timer/bcm2835_systmr.h" 30 + #include "hw/usb/hcd-dwc2.h" 29 31 #include "hw/misc/unimp.h" 30 32 31 33 #define TYPE_BCM2835_PERIPHERALS "bcm2835-peripherals" ··· 42 44 qemu_irq irq, fiq; 43 45 44 46 BCM2835SystemTimerState systmr; 47 + BCM2835MphiState mphi; 45 48 UnimplementedDeviceState armtmr; 46 49 UnimplementedDeviceState cprman; 47 50 UnimplementedDeviceState a2w; ··· 65 68 UnimplementedDeviceState ave0; 66 69 UnimplementedDeviceState bscsl; 67 70 UnimplementedDeviceState smi; 68 - UnimplementedDeviceState dwc2; 71 + DWC2State dwc2; 69 72 UnimplementedDeviceState sdramc; 70 73 } BCM2835PeripheralState; 71 74
+44
include/hw/misc/bcm2835_mphi.h
··· 1 + /* 2 + * BCM2835 SOC MPHI state definitions 3 + * 4 + * Copyright (c) 2020 Paul Zimmerman <pauldzim@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + */ 16 + 17 + #ifndef HW_MISC_BCM2835_MPHI_H 18 + #define HW_MISC_BCM2835_MPHI_H 19 + 20 + #include "hw/irq.h" 21 + #include "hw/sysbus.h" 22 + 23 + #define MPHI_MMIO_SIZE 0x1000 24 + 25 + typedef struct BCM2835MphiState BCM2835MphiState; 26 + 27 + struct BCM2835MphiState { 28 + SysBusDevice parent_obj; 29 + qemu_irq irq; 30 + MemoryRegion iomem; 31 + 32 + uint32_t outdda; 33 + uint32_t outddb; 34 + uint32_t ctrl; 35 + uint32_t intstat; 36 + uint32_t swirq; 37 + }; 38 + 39 + #define TYPE_BCM2835_MPHI "bcm2835-mphi" 40 + 41 + #define BCM2835_MPHI(obj) \ 42 + OBJECT_CHECK(BCM2835MphiState, (obj), TYPE_BCM2835_MPHI) 43 + 44 + #endif
+899
include/hw/usb/dwc2-regs.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ 2 + /* 3 + * Imported from the Linux kernel file drivers/usb/dwc2/hw.h, commit 4 + * a89bae709b3492b478480a2c9734e7e9393b279c ("usb: dwc2: Move 5 + * UTMI_PHY_DATA defines closer") 6 + * 7 + * hw.h - DesignWare HS OTG Controller hardware definitions 8 + * 9 + * Copyright 2004-2013 Synopsys, Inc. 10 + * 11 + * Redistribution and use in source and binary forms, with or without 12 + * modification, are permitted provided that the following conditions 13 + * are met: 14 + * 1. Redistributions of source code must retain the above copyright 15 + * notice, this list of conditions, and the following disclaimer, 16 + * without modification. 17 + * 2. Redistributions in binary form must reproduce the above copyright 18 + * notice, this list of conditions and the following disclaimer in the 19 + * documentation and/or other materials provided with the distribution. 20 + * 3. The names of the above-listed copyright holders may not be used 21 + * to endorse or promote products derived from this software without 22 + * specific prior written permission. 23 + * 24 + * ALTERNATIVELY, this software may be distributed under the terms of the 25 + * GNU General Public License ("GPL") as published by the Free Software 26 + * Foundation; either version 2 of the License, or (at your option) any 27 + * later version. 28 + * 29 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 30 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 31 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 32 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 33 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 34 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 35 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 36 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 37 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 38 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 39 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 + */ 41 + 42 + #ifndef __DWC2_HW_H__ 43 + #define __DWC2_HW_H__ 44 + 45 + #define HSOTG_REG(x) (x) 46 + 47 + #define GOTGCTL HSOTG_REG(0x000) 48 + #define GOTGCTL_CHIRPEN BIT(27) 49 + #define GOTGCTL_MULT_VALID_BC_MASK (0x1f << 22) 50 + #define GOTGCTL_MULT_VALID_BC_SHIFT 22 51 + #define GOTGCTL_OTGVER BIT(20) 52 + #define GOTGCTL_BSESVLD BIT(19) 53 + #define GOTGCTL_ASESVLD BIT(18) 54 + #define GOTGCTL_DBNC_SHORT BIT(17) 55 + #define GOTGCTL_CONID_B BIT(16) 56 + #define GOTGCTL_DBNCE_FLTR_BYPASS BIT(15) 57 + #define GOTGCTL_DEVHNPEN BIT(11) 58 + #define GOTGCTL_HSTSETHNPEN BIT(10) 59 + #define GOTGCTL_HNPREQ BIT(9) 60 + #define GOTGCTL_HSTNEGSCS BIT(8) 61 + #define GOTGCTL_SESREQ BIT(1) 62 + #define GOTGCTL_SESREQSCS BIT(0) 63 + 64 + #define GOTGINT HSOTG_REG(0x004) 65 + #define GOTGINT_DBNCE_DONE BIT(19) 66 + #define GOTGINT_A_DEV_TOUT_CHG BIT(18) 67 + #define GOTGINT_HST_NEG_DET BIT(17) 68 + #define GOTGINT_HST_NEG_SUC_STS_CHNG BIT(9) 69 + #define GOTGINT_SES_REQ_SUC_STS_CHNG BIT(8) 70 + #define GOTGINT_SES_END_DET BIT(2) 71 + 72 + #define GAHBCFG HSOTG_REG(0x008) 73 + #define GAHBCFG_AHB_SINGLE BIT(23) 74 + #define GAHBCFG_NOTI_ALL_DMA_WRIT BIT(22) 75 + #define GAHBCFG_REM_MEM_SUPP BIT(21) 76 + #define GAHBCFG_P_TXF_EMP_LVL BIT(8) 77 + #define GAHBCFG_NP_TXF_EMP_LVL BIT(7) 78 + #define GAHBCFG_DMA_EN BIT(5) 79 + #define GAHBCFG_HBSTLEN_MASK (0xf << 1) 80 + #define GAHBCFG_HBSTLEN_SHIFT 1 81 + #define GAHBCFG_HBSTLEN_SINGLE 0 82 + #define GAHBCFG_HBSTLEN_INCR 1 83 + #define GAHBCFG_HBSTLEN_INCR4 3 84 + #define GAHBCFG_HBSTLEN_INCR8 5 85 + #define GAHBCFG_HBSTLEN_INCR16 7 86 + #define GAHBCFG_GLBL_INTR_EN BIT(0) 87 + #define GAHBCFG_CTRL_MASK (GAHBCFG_P_TXF_EMP_LVL | \ 88 + GAHBCFG_NP_TXF_EMP_LVL | \ 89 + GAHBCFG_DMA_EN | \ 90 + GAHBCFG_GLBL_INTR_EN) 91 + 92 + #define GUSBCFG HSOTG_REG(0x00C) 93 + #define GUSBCFG_FORCEDEVMODE BIT(30) 94 + #define GUSBCFG_FORCEHOSTMODE BIT(29) 95 + #define GUSBCFG_TXENDDELAY BIT(28) 96 + #define GUSBCFG_ICTRAFFICPULLREMOVE BIT(27) 97 + #define GUSBCFG_ICUSBCAP BIT(26) 98 + #define GUSBCFG_ULPI_INT_PROT_DIS BIT(25) 99 + #define GUSBCFG_INDICATORPASSTHROUGH BIT(24) 100 + #define GUSBCFG_INDICATORCOMPLEMENT BIT(23) 101 + #define GUSBCFG_TERMSELDLPULSE BIT(22) 102 + #define GUSBCFG_ULPI_INT_VBUS_IND BIT(21) 103 + #define GUSBCFG_ULPI_EXT_VBUS_DRV BIT(20) 104 + #define GUSBCFG_ULPI_CLK_SUSP_M BIT(19) 105 + #define GUSBCFG_ULPI_AUTO_RES BIT(18) 106 + #define GUSBCFG_ULPI_FS_LS BIT(17) 107 + #define GUSBCFG_OTG_UTMI_FS_SEL BIT(16) 108 + #define GUSBCFG_PHY_LP_CLK_SEL BIT(15) 109 + #define GUSBCFG_USBTRDTIM_MASK (0xf << 10) 110 + #define GUSBCFG_USBTRDTIM_SHIFT 10 111 + #define GUSBCFG_HNPCAP BIT(9) 112 + #define GUSBCFG_SRPCAP BIT(8) 113 + #define GUSBCFG_DDRSEL BIT(7) 114 + #define GUSBCFG_PHYSEL BIT(6) 115 + #define GUSBCFG_FSINTF BIT(5) 116 + #define GUSBCFG_ULPI_UTMI_SEL BIT(4) 117 + #define GUSBCFG_PHYIF16 BIT(3) 118 + #define GUSBCFG_PHYIF8 (0 << 3) 119 + #define GUSBCFG_TOUTCAL_MASK (0x7 << 0) 120 + #define GUSBCFG_TOUTCAL_SHIFT 0 121 + #define GUSBCFG_TOUTCAL_LIMIT 0x7 122 + #define GUSBCFG_TOUTCAL(_x) ((_x) << 0) 123 + 124 + #define GRSTCTL HSOTG_REG(0x010) 125 + #define GRSTCTL_AHBIDLE BIT(31) 126 + #define GRSTCTL_DMAREQ BIT(30) 127 + #define GRSTCTL_TXFNUM_MASK (0x1f << 6) 128 + #define GRSTCTL_TXFNUM_SHIFT 6 129 + #define GRSTCTL_TXFNUM_LIMIT 0x1f 130 + #define GRSTCTL_TXFNUM(_x) ((_x) << 6) 131 + #define GRSTCTL_TXFFLSH BIT(5) 132 + #define GRSTCTL_RXFFLSH BIT(4) 133 + #define GRSTCTL_IN_TKNQ_FLSH BIT(3) 134 + #define GRSTCTL_FRMCNTRRST BIT(2) 135 + #define GRSTCTL_HSFTRST BIT(1) 136 + #define GRSTCTL_CSFTRST BIT(0) 137 + 138 + #define GINTSTS HSOTG_REG(0x014) 139 + #define GINTMSK HSOTG_REG(0x018) 140 + #define GINTSTS_WKUPINT BIT(31) 141 + #define GINTSTS_SESSREQINT BIT(30) 142 + #define GINTSTS_DISCONNINT BIT(29) 143 + #define GINTSTS_CONIDSTSCHNG BIT(28) 144 + #define GINTSTS_LPMTRANRCVD BIT(27) 145 + #define GINTSTS_PTXFEMP BIT(26) 146 + #define GINTSTS_HCHINT BIT(25) 147 + #define GINTSTS_PRTINT BIT(24) 148 + #define GINTSTS_RESETDET BIT(23) 149 + #define GINTSTS_FET_SUSP BIT(22) 150 + #define GINTSTS_INCOMPL_IP BIT(21) 151 + #define GINTSTS_INCOMPL_SOOUT BIT(21) 152 + #define GINTSTS_INCOMPL_SOIN BIT(20) 153 + #define GINTSTS_OEPINT BIT(19) 154 + #define GINTSTS_IEPINT BIT(18) 155 + #define GINTSTS_EPMIS BIT(17) 156 + #define GINTSTS_RESTOREDONE BIT(16) 157 + #define GINTSTS_EOPF BIT(15) 158 + #define GINTSTS_ISOUTDROP BIT(14) 159 + #define GINTSTS_ENUMDONE BIT(13) 160 + #define GINTSTS_USBRST BIT(12) 161 + #define GINTSTS_USBSUSP BIT(11) 162 + #define GINTSTS_ERLYSUSP BIT(10) 163 + #define GINTSTS_I2CINT BIT(9) 164 + #define GINTSTS_ULPI_CK_INT BIT(8) 165 + #define GINTSTS_GOUTNAKEFF BIT(7) 166 + #define GINTSTS_GINNAKEFF BIT(6) 167 + #define GINTSTS_NPTXFEMP BIT(5) 168 + #define GINTSTS_RXFLVL BIT(4) 169 + #define GINTSTS_SOF BIT(3) 170 + #define GINTSTS_OTGINT BIT(2) 171 + #define GINTSTS_MODEMIS BIT(1) 172 + #define GINTSTS_CURMODE_HOST BIT(0) 173 + 174 + #define GRXSTSR HSOTG_REG(0x01C) 175 + #define GRXSTSP HSOTG_REG(0x020) 176 + #define GRXSTS_FN_MASK (0x7f << 25) 177 + #define GRXSTS_FN_SHIFT 25 178 + #define GRXSTS_PKTSTS_MASK (0xf << 17) 179 + #define GRXSTS_PKTSTS_SHIFT 17 180 + #define GRXSTS_PKTSTS_GLOBALOUTNAK 1 181 + #define GRXSTS_PKTSTS_OUTRX 2 182 + #define GRXSTS_PKTSTS_HCHIN 2 183 + #define GRXSTS_PKTSTS_OUTDONE 3 184 + #define GRXSTS_PKTSTS_HCHIN_XFER_COMP 3 185 + #define GRXSTS_PKTSTS_SETUPDONE 4 186 + #define GRXSTS_PKTSTS_DATATOGGLEERR 5 187 + #define GRXSTS_PKTSTS_SETUPRX 6 188 + #define GRXSTS_PKTSTS_HCHHALTED 7 189 + #define GRXSTS_HCHNUM_MASK (0xf << 0) 190 + #define GRXSTS_HCHNUM_SHIFT 0 191 + #define GRXSTS_DPID_MASK (0x3 << 15) 192 + #define GRXSTS_DPID_SHIFT 15 193 + #define GRXSTS_BYTECNT_MASK (0x7ff << 4) 194 + #define GRXSTS_BYTECNT_SHIFT 4 195 + #define GRXSTS_EPNUM_MASK (0xf << 0) 196 + #define GRXSTS_EPNUM_SHIFT 0 197 + 198 + #define GRXFSIZ HSOTG_REG(0x024) 199 + #define GRXFSIZ_DEPTH_MASK (0xffff << 0) 200 + #define GRXFSIZ_DEPTH_SHIFT 0 201 + 202 + #define GNPTXFSIZ HSOTG_REG(0x028) 203 + /* Use FIFOSIZE_* constants to access this register */ 204 + 205 + #define GNPTXSTS HSOTG_REG(0x02C) 206 + #define GNPTXSTS_NP_TXQ_TOP_MASK (0x7f << 24) 207 + #define GNPTXSTS_NP_TXQ_TOP_SHIFT 24 208 + #define GNPTXSTS_NP_TXQ_SPC_AVAIL_MASK (0xff << 16) 209 + #define GNPTXSTS_NP_TXQ_SPC_AVAIL_SHIFT 16 210 + #define GNPTXSTS_NP_TXQ_SPC_AVAIL_GET(_v) (((_v) >> 16) & 0xff) 211 + #define GNPTXSTS_NP_TXF_SPC_AVAIL_MASK (0xffff << 0) 212 + #define GNPTXSTS_NP_TXF_SPC_AVAIL_SHIFT 0 213 + #define GNPTXSTS_NP_TXF_SPC_AVAIL_GET(_v) (((_v) >> 0) & 0xffff) 214 + 215 + #define GI2CCTL HSOTG_REG(0x0030) 216 + #define GI2CCTL_BSYDNE BIT(31) 217 + #define GI2CCTL_RW BIT(30) 218 + #define GI2CCTL_I2CDATSE0 BIT(28) 219 + #define GI2CCTL_I2CDEVADDR_MASK (0x3 << 26) 220 + #define GI2CCTL_I2CDEVADDR_SHIFT 26 221 + #define GI2CCTL_I2CSUSPCTL BIT(25) 222 + #define GI2CCTL_ACK BIT(24) 223 + #define GI2CCTL_I2CEN BIT(23) 224 + #define GI2CCTL_ADDR_MASK (0x7f << 16) 225 + #define GI2CCTL_ADDR_SHIFT 16 226 + #define GI2CCTL_REGADDR_MASK (0xff << 8) 227 + #define GI2CCTL_REGADDR_SHIFT 8 228 + #define GI2CCTL_RWDATA_MASK (0xff << 0) 229 + #define GI2CCTL_RWDATA_SHIFT 0 230 + 231 + #define GPVNDCTL HSOTG_REG(0x0034) 232 + #define GGPIO HSOTG_REG(0x0038) 233 + #define GGPIO_STM32_OTG_GCCFG_PWRDWN BIT(16) 234 + 235 + #define GUID HSOTG_REG(0x003c) 236 + #define GSNPSID HSOTG_REG(0x0040) 237 + #define GHWCFG1 HSOTG_REG(0x0044) 238 + #define GSNPSID_ID_MASK GENMASK(31, 16) 239 + 240 + #define GHWCFG2 HSOTG_REG(0x0048) 241 + #define GHWCFG2_OTG_ENABLE_IC_USB BIT(31) 242 + #define GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK (0x1f << 26) 243 + #define GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT 26 244 + #define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK (0x3 << 24) 245 + #define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT 24 246 + #define GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK (0x3 << 22) 247 + #define GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT 22 248 + #define GHWCFG2_MULTI_PROC_INT BIT(20) 249 + #define GHWCFG2_DYNAMIC_FIFO BIT(19) 250 + #define GHWCFG2_PERIO_EP_SUPPORTED BIT(18) 251 + #define GHWCFG2_NUM_HOST_CHAN_MASK (0xf << 14) 252 + #define GHWCFG2_NUM_HOST_CHAN_SHIFT 14 253 + #define GHWCFG2_NUM_DEV_EP_MASK (0xf << 10) 254 + #define GHWCFG2_NUM_DEV_EP_SHIFT 10 255 + #define GHWCFG2_FS_PHY_TYPE_MASK (0x3 << 8) 256 + #define GHWCFG2_FS_PHY_TYPE_SHIFT 8 257 + #define GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED 0 258 + #define GHWCFG2_FS_PHY_TYPE_DEDICATED 1 259 + #define GHWCFG2_FS_PHY_TYPE_SHARED_UTMI 2 260 + #define GHWCFG2_FS_PHY_TYPE_SHARED_ULPI 3 261 + #define GHWCFG2_HS_PHY_TYPE_MASK (0x3 << 6) 262 + #define GHWCFG2_HS_PHY_TYPE_SHIFT 6 263 + #define GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0 264 + #define GHWCFG2_HS_PHY_TYPE_UTMI 1 265 + #define GHWCFG2_HS_PHY_TYPE_ULPI 2 266 + #define GHWCFG2_HS_PHY_TYPE_UTMI_ULPI 3 267 + #define GHWCFG2_POINT2POINT BIT(5) 268 + #define GHWCFG2_ARCHITECTURE_MASK (0x3 << 3) 269 + #define GHWCFG2_ARCHITECTURE_SHIFT 3 270 + #define GHWCFG2_SLAVE_ONLY_ARCH 0 271 + #define GHWCFG2_EXT_DMA_ARCH 1 272 + #define GHWCFG2_INT_DMA_ARCH 2 273 + #define GHWCFG2_OP_MODE_MASK (0x7 << 0) 274 + #define GHWCFG2_OP_MODE_SHIFT 0 275 + #define GHWCFG2_OP_MODE_HNP_SRP_CAPABLE 0 276 + #define GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE 1 277 + #define GHWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE 2 278 + #define GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3 279 + #define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4 280 + #define GHWCFG2_OP_MODE_SRP_CAPABLE_HOST 5 281 + #define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6 282 + #define GHWCFG2_OP_MODE_UNDEFINED 7 283 + 284 + #define GHWCFG3 HSOTG_REG(0x004c) 285 + #define GHWCFG3_DFIFO_DEPTH_MASK (0xffff << 16) 286 + #define GHWCFG3_DFIFO_DEPTH_SHIFT 16 287 + #define GHWCFG3_OTG_LPM_EN BIT(15) 288 + #define GHWCFG3_BC_SUPPORT BIT(14) 289 + #define GHWCFG3_OTG_ENABLE_HSIC BIT(13) 290 + #define GHWCFG3_ADP_SUPP BIT(12) 291 + #define GHWCFG3_SYNCH_RESET_TYPE BIT(11) 292 + #define GHWCFG3_OPTIONAL_FEATURES BIT(10) 293 + #define GHWCFG3_VENDOR_CTRL_IF BIT(9) 294 + #define GHWCFG3_I2C BIT(8) 295 + #define GHWCFG3_OTG_FUNC BIT(7) 296 + #define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK (0x7 << 4) 297 + #define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT 4 298 + #define GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK (0xf << 0) 299 + #define GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT 0 300 + 301 + #define GHWCFG4 HSOTG_REG(0x0050) 302 + #define GHWCFG4_DESC_DMA_DYN BIT(31) 303 + #define GHWCFG4_DESC_DMA BIT(30) 304 + #define GHWCFG4_NUM_IN_EPS_MASK (0xf << 26) 305 + #define GHWCFG4_NUM_IN_EPS_SHIFT 26 306 + #define GHWCFG4_DED_FIFO_EN BIT(25) 307 + #define GHWCFG4_DED_FIFO_SHIFT 25 308 + #define GHWCFG4_SESSION_END_FILT_EN BIT(24) 309 + #define GHWCFG4_B_VALID_FILT_EN BIT(23) 310 + #define GHWCFG4_A_VALID_FILT_EN BIT(22) 311 + #define GHWCFG4_VBUS_VALID_FILT_EN BIT(21) 312 + #define GHWCFG4_IDDIG_FILT_EN BIT(20) 313 + #define GHWCFG4_NUM_DEV_MODE_CTRL_EP_MASK (0xf << 16) 314 + #define GHWCFG4_NUM_DEV_MODE_CTRL_EP_SHIFT 16 315 + #define GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK (0x3 << 14) 316 + #define GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT 14 317 + #define GHWCFG4_UTMI_PHY_DATA_WIDTH_8 0 318 + #define GHWCFG4_UTMI_PHY_DATA_WIDTH_16 1 319 + #define GHWCFG4_UTMI_PHY_DATA_WIDTH_8_OR_16 2 320 + #define GHWCFG4_ACG_SUPPORTED BIT(12) 321 + #define GHWCFG4_IPG_ISOC_SUPPORTED BIT(11) 322 + #define GHWCFG4_SERVICE_INTERVAL_SUPPORTED BIT(10) 323 + #define GHWCFG4_XHIBER BIT(7) 324 + #define GHWCFG4_HIBER BIT(6) 325 + #define GHWCFG4_MIN_AHB_FREQ BIT(5) 326 + #define GHWCFG4_POWER_OPTIMIZ BIT(4) 327 + #define GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK (0xf << 0) 328 + #define GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT 0 329 + 330 + #define GLPMCFG HSOTG_REG(0x0054) 331 + #define GLPMCFG_INVSELHSIC BIT(31) 332 + #define GLPMCFG_HSICCON BIT(30) 333 + #define GLPMCFG_RSTRSLPSTS BIT(29) 334 + #define GLPMCFG_ENBESL BIT(28) 335 + #define GLPMCFG_LPM_RETRYCNT_STS_MASK (0x7 << 25) 336 + #define GLPMCFG_LPM_RETRYCNT_STS_SHIFT 25 337 + #define GLPMCFG_SNDLPM BIT(24) 338 + #define GLPMCFG_RETRY_CNT_MASK (0x7 << 21) 339 + #define GLPMCFG_RETRY_CNT_SHIFT 21 340 + #define GLPMCFG_LPM_REJECT_CTRL_CONTROL BIT(21) 341 + #define GLPMCFG_LPM_ACCEPT_CTRL_ISOC BIT(22) 342 + #define GLPMCFG_LPM_CHNL_INDX_MASK (0xf << 17) 343 + #define GLPMCFG_LPM_CHNL_INDX_SHIFT 17 344 + #define GLPMCFG_L1RESUMEOK BIT(16) 345 + #define GLPMCFG_SLPSTS BIT(15) 346 + #define GLPMCFG_COREL1RES_MASK (0x3 << 13) 347 + #define GLPMCFG_COREL1RES_SHIFT 13 348 + #define GLPMCFG_HIRD_THRES_MASK (0x1f << 8) 349 + #define GLPMCFG_HIRD_THRES_SHIFT 8 350 + #define GLPMCFG_HIRD_THRES_EN (0x10 << 8) 351 + #define GLPMCFG_ENBLSLPM BIT(7) 352 + #define GLPMCFG_BREMOTEWAKE BIT(6) 353 + #define GLPMCFG_HIRD_MASK (0xf << 2) 354 + #define GLPMCFG_HIRD_SHIFT 2 355 + #define GLPMCFG_APPL1RES BIT(1) 356 + #define GLPMCFG_LPMCAP BIT(0) 357 + 358 + #define GPWRDN HSOTG_REG(0x0058) 359 + #define GPWRDN_MULT_VAL_ID_BC_MASK (0x1f << 24) 360 + #define GPWRDN_MULT_VAL_ID_BC_SHIFT 24 361 + #define GPWRDN_ADP_INT BIT(23) 362 + #define GPWRDN_BSESSVLD BIT(22) 363 + #define GPWRDN_IDSTS BIT(21) 364 + #define GPWRDN_LINESTATE_MASK (0x3 << 19) 365 + #define GPWRDN_LINESTATE_SHIFT 19 366 + #define GPWRDN_STS_CHGINT_MSK BIT(18) 367 + #define GPWRDN_STS_CHGINT BIT(17) 368 + #define GPWRDN_SRP_DET_MSK BIT(16) 369 + #define GPWRDN_SRP_DET BIT(15) 370 + #define GPWRDN_CONNECT_DET_MSK BIT(14) 371 + #define GPWRDN_CONNECT_DET BIT(13) 372 + #define GPWRDN_DISCONN_DET_MSK BIT(12) 373 + #define GPWRDN_DISCONN_DET BIT(11) 374 + #define GPWRDN_RST_DET_MSK BIT(10) 375 + #define GPWRDN_RST_DET BIT(9) 376 + #define GPWRDN_LNSTSCHG_MSK BIT(8) 377 + #define GPWRDN_LNSTSCHG BIT(7) 378 + #define GPWRDN_DIS_VBUS BIT(6) 379 + #define GPWRDN_PWRDNSWTCH BIT(5) 380 + #define GPWRDN_PWRDNRSTN BIT(4) 381 + #define GPWRDN_PWRDNCLMP BIT(3) 382 + #define GPWRDN_RESTORE BIT(2) 383 + #define GPWRDN_PMUACTV BIT(1) 384 + #define GPWRDN_PMUINTSEL BIT(0) 385 + 386 + #define GDFIFOCFG HSOTG_REG(0x005c) 387 + #define GDFIFOCFG_EPINFOBASE_MASK (0xffff << 16) 388 + #define GDFIFOCFG_EPINFOBASE_SHIFT 16 389 + #define GDFIFOCFG_GDFIFOCFG_MASK (0xffff << 0) 390 + #define GDFIFOCFG_GDFIFOCFG_SHIFT 0 391 + 392 + #define ADPCTL HSOTG_REG(0x0060) 393 + #define ADPCTL_AR_MASK (0x3 << 27) 394 + #define ADPCTL_AR_SHIFT 27 395 + #define ADPCTL_ADP_TMOUT_INT_MSK BIT(26) 396 + #define ADPCTL_ADP_SNS_INT_MSK BIT(25) 397 + #define ADPCTL_ADP_PRB_INT_MSK BIT(24) 398 + #define ADPCTL_ADP_TMOUT_INT BIT(23) 399 + #define ADPCTL_ADP_SNS_INT BIT(22) 400 + #define ADPCTL_ADP_PRB_INT BIT(21) 401 + #define ADPCTL_ADPENA BIT(20) 402 + #define ADPCTL_ADPRES BIT(19) 403 + #define ADPCTL_ENASNS BIT(18) 404 + #define ADPCTL_ENAPRB BIT(17) 405 + #define ADPCTL_RTIM_MASK (0x7ff << 6) 406 + #define ADPCTL_RTIM_SHIFT 6 407 + #define ADPCTL_PRB_PER_MASK (0x3 << 4) 408 + #define ADPCTL_PRB_PER_SHIFT 4 409 + #define ADPCTL_PRB_DELTA_MASK (0x3 << 2) 410 + #define ADPCTL_PRB_DELTA_SHIFT 2 411 + #define ADPCTL_PRB_DSCHRG_MASK (0x3 << 0) 412 + #define ADPCTL_PRB_DSCHRG_SHIFT 0 413 + 414 + #define GREFCLK HSOTG_REG(0x0064) 415 + #define GREFCLK_REFCLKPER_MASK (0x1ffff << 15) 416 + #define GREFCLK_REFCLKPER_SHIFT 15 417 + #define GREFCLK_REF_CLK_MODE BIT(14) 418 + #define GREFCLK_SOF_CNT_WKUP_ALERT_MASK (0x3ff) 419 + #define GREFCLK_SOF_CNT_WKUP_ALERT_SHIFT 0 420 + 421 + #define GINTMSK2 HSOTG_REG(0x0068) 422 + #define GINTMSK2_WKUP_ALERT_INT_MSK BIT(0) 423 + 424 + #define GINTSTS2 HSOTG_REG(0x006c) 425 + #define GINTSTS2_WKUP_ALERT_INT BIT(0) 426 + 427 + #define HPTXFSIZ HSOTG_REG(0x100) 428 + /* Use FIFOSIZE_* constants to access this register */ 429 + 430 + #define DPTXFSIZN(_a) HSOTG_REG(0x104 + (((_a) - 1) * 4)) 431 + /* Use FIFOSIZE_* constants to access this register */ 432 + 433 + /* These apply to the GNPTXFSIZ, HPTXFSIZ and DPTXFSIZN registers */ 434 + #define FIFOSIZE_DEPTH_MASK (0xffff << 16) 435 + #define FIFOSIZE_DEPTH_SHIFT 16 436 + #define FIFOSIZE_STARTADDR_MASK (0xffff << 0) 437 + #define FIFOSIZE_STARTADDR_SHIFT 0 438 + #define FIFOSIZE_DEPTH_GET(_x) (((_x) >> 16) & 0xffff) 439 + 440 + /* Device mode registers */ 441 + 442 + #define DCFG HSOTG_REG(0x800) 443 + #define DCFG_DESCDMA_EN BIT(23) 444 + #define DCFG_EPMISCNT_MASK (0x1f << 18) 445 + #define DCFG_EPMISCNT_SHIFT 18 446 + #define DCFG_EPMISCNT_LIMIT 0x1f 447 + #define DCFG_EPMISCNT(_x) ((_x) << 18) 448 + #define DCFG_IPG_ISOC_SUPPORDED BIT(17) 449 + #define DCFG_PERFRINT_MASK (0x3 << 11) 450 + #define DCFG_PERFRINT_SHIFT 11 451 + #define DCFG_PERFRINT_LIMIT 0x3 452 + #define DCFG_PERFRINT(_x) ((_x) << 11) 453 + #define DCFG_DEVADDR_MASK (0x7f << 4) 454 + #define DCFG_DEVADDR_SHIFT 4 455 + #define DCFG_DEVADDR_LIMIT 0x7f 456 + #define DCFG_DEVADDR(_x) ((_x) << 4) 457 + #define DCFG_NZ_STS_OUT_HSHK BIT(2) 458 + #define DCFG_DEVSPD_MASK (0x3 << 0) 459 + #define DCFG_DEVSPD_SHIFT 0 460 + #define DCFG_DEVSPD_HS 0 461 + #define DCFG_DEVSPD_FS 1 462 + #define DCFG_DEVSPD_LS 2 463 + #define DCFG_DEVSPD_FS48 3 464 + 465 + #define DCTL HSOTG_REG(0x804) 466 + #define DCTL_SERVICE_INTERVAL_SUPPORTED BIT(19) 467 + #define DCTL_PWRONPRGDONE BIT(11) 468 + #define DCTL_CGOUTNAK BIT(10) 469 + #define DCTL_SGOUTNAK BIT(9) 470 + #define DCTL_CGNPINNAK BIT(8) 471 + #define DCTL_SGNPINNAK BIT(7) 472 + #define DCTL_TSTCTL_MASK (0x7 << 4) 473 + #define DCTL_TSTCTL_SHIFT 4 474 + #define DCTL_GOUTNAKSTS BIT(3) 475 + #define DCTL_GNPINNAKSTS BIT(2) 476 + #define DCTL_SFTDISCON BIT(1) 477 + #define DCTL_RMTWKUPSIG BIT(0) 478 + 479 + #define DSTS HSOTG_REG(0x808) 480 + #define DSTS_SOFFN_MASK (0x3fff << 8) 481 + #define DSTS_SOFFN_SHIFT 8 482 + #define DSTS_SOFFN_LIMIT 0x3fff 483 + #define DSTS_SOFFN(_x) ((_x) << 8) 484 + #define DSTS_ERRATICERR BIT(3) 485 + #define DSTS_ENUMSPD_MASK (0x3 << 1) 486 + #define DSTS_ENUMSPD_SHIFT 1 487 + #define DSTS_ENUMSPD_HS 0 488 + #define DSTS_ENUMSPD_FS 1 489 + #define DSTS_ENUMSPD_LS 2 490 + #define DSTS_ENUMSPD_FS48 3 491 + #define DSTS_SUSPSTS BIT(0) 492 + 493 + #define DIEPMSK HSOTG_REG(0x810) 494 + #define DIEPMSK_NAKMSK BIT(13) 495 + #define DIEPMSK_BNAININTRMSK BIT(9) 496 + #define DIEPMSK_TXFIFOUNDRNMSK BIT(8) 497 + #define DIEPMSK_TXFIFOEMPTY BIT(7) 498 + #define DIEPMSK_INEPNAKEFFMSK BIT(6) 499 + #define DIEPMSK_INTKNEPMISMSK BIT(5) 500 + #define DIEPMSK_INTKNTXFEMPMSK BIT(4) 501 + #define DIEPMSK_TIMEOUTMSK BIT(3) 502 + #define DIEPMSK_AHBERRMSK BIT(2) 503 + #define DIEPMSK_EPDISBLDMSK BIT(1) 504 + #define DIEPMSK_XFERCOMPLMSK BIT(0) 505 + 506 + #define DOEPMSK HSOTG_REG(0x814) 507 + #define DOEPMSK_BNAMSK BIT(9) 508 + #define DOEPMSK_BACK2BACKSETUP BIT(6) 509 + #define DOEPMSK_STSPHSERCVDMSK BIT(5) 510 + #define DOEPMSK_OUTTKNEPDISMSK BIT(4) 511 + #define DOEPMSK_SETUPMSK BIT(3) 512 + #define DOEPMSK_AHBERRMSK BIT(2) 513 + #define DOEPMSK_EPDISBLDMSK BIT(1) 514 + #define DOEPMSK_XFERCOMPLMSK BIT(0) 515 + 516 + #define DAINT HSOTG_REG(0x818) 517 + #define DAINTMSK HSOTG_REG(0x81C) 518 + #define DAINT_OUTEP_SHIFT 16 519 + #define DAINT_OUTEP(_x) (1 << ((_x) + 16)) 520 + #define DAINT_INEP(_x) (1 << (_x)) 521 + 522 + #define DTKNQR1 HSOTG_REG(0x820) 523 + #define DTKNQR2 HSOTG_REG(0x824) 524 + #define DTKNQR3 HSOTG_REG(0x830) 525 + #define DTKNQR4 HSOTG_REG(0x834) 526 + #define DIEPEMPMSK HSOTG_REG(0x834) 527 + 528 + #define DVBUSDIS HSOTG_REG(0x828) 529 + #define DVBUSPULSE HSOTG_REG(0x82C) 530 + 531 + #define DIEPCTL0 HSOTG_REG(0x900) 532 + #define DIEPCTL(_a) HSOTG_REG(0x900 + ((_a) * 0x20)) 533 + 534 + #define DOEPCTL0 HSOTG_REG(0xB00) 535 + #define DOEPCTL(_a) HSOTG_REG(0xB00 + ((_a) * 0x20)) 536 + 537 + /* EP0 specialness: 538 + * bits[29..28] - reserved (no SetD0PID, SetD1PID) 539 + * bits[25..22] - should always be zero, this isn't a periodic endpoint 540 + * bits[10..0] - MPS setting different for EP0 541 + */ 542 + #define D0EPCTL_MPS_MASK (0x3 << 0) 543 + #define D0EPCTL_MPS_SHIFT 0 544 + #define D0EPCTL_MPS_64 0 545 + #define D0EPCTL_MPS_32 1 546 + #define D0EPCTL_MPS_16 2 547 + #define D0EPCTL_MPS_8 3 548 + 549 + #define DXEPCTL_EPENA BIT(31) 550 + #define DXEPCTL_EPDIS BIT(30) 551 + #define DXEPCTL_SETD1PID BIT(29) 552 + #define DXEPCTL_SETODDFR BIT(29) 553 + #define DXEPCTL_SETD0PID BIT(28) 554 + #define DXEPCTL_SETEVENFR BIT(28) 555 + #define DXEPCTL_SNAK BIT(27) 556 + #define DXEPCTL_CNAK BIT(26) 557 + #define DXEPCTL_TXFNUM_MASK (0xf << 22) 558 + #define DXEPCTL_TXFNUM_SHIFT 22 559 + #define DXEPCTL_TXFNUM_LIMIT 0xf 560 + #define DXEPCTL_TXFNUM(_x) ((_x) << 22) 561 + #define DXEPCTL_STALL BIT(21) 562 + #define DXEPCTL_SNP BIT(20) 563 + #define DXEPCTL_EPTYPE_MASK (0x3 << 18) 564 + #define DXEPCTL_EPTYPE_CONTROL (0x0 << 18) 565 + #define DXEPCTL_EPTYPE_ISO (0x1 << 18) 566 + #define DXEPCTL_EPTYPE_BULK (0x2 << 18) 567 + #define DXEPCTL_EPTYPE_INTERRUPT (0x3 << 18) 568 + 569 + #define DXEPCTL_NAKSTS BIT(17) 570 + #define DXEPCTL_DPID BIT(16) 571 + #define DXEPCTL_EOFRNUM BIT(16) 572 + #define DXEPCTL_USBACTEP BIT(15) 573 + #define DXEPCTL_NEXTEP_MASK (0xf << 11) 574 + #define DXEPCTL_NEXTEP_SHIFT 11 575 + #define DXEPCTL_NEXTEP_LIMIT 0xf 576 + #define DXEPCTL_NEXTEP(_x) ((_x) << 11) 577 + #define DXEPCTL_MPS_MASK (0x7ff << 0) 578 + #define DXEPCTL_MPS_SHIFT 0 579 + #define DXEPCTL_MPS_LIMIT 0x7ff 580 + #define DXEPCTL_MPS(_x) ((_x) << 0) 581 + 582 + #define DIEPINT(_a) HSOTG_REG(0x908 + ((_a) * 0x20)) 583 + #define DOEPINT(_a) HSOTG_REG(0xB08 + ((_a) * 0x20)) 584 + #define DXEPINT_SETUP_RCVD BIT(15) 585 + #define DXEPINT_NYETINTRPT BIT(14) 586 + #define DXEPINT_NAKINTRPT BIT(13) 587 + #define DXEPINT_BBLEERRINTRPT BIT(12) 588 + #define DXEPINT_PKTDRPSTS BIT(11) 589 + #define DXEPINT_BNAINTR BIT(9) 590 + #define DXEPINT_TXFIFOUNDRN BIT(8) 591 + #define DXEPINT_OUTPKTERR BIT(8) 592 + #define DXEPINT_TXFEMP BIT(7) 593 + #define DXEPINT_INEPNAKEFF BIT(6) 594 + #define DXEPINT_BACK2BACKSETUP BIT(6) 595 + #define DXEPINT_INTKNEPMIS BIT(5) 596 + #define DXEPINT_STSPHSERCVD BIT(5) 597 + #define DXEPINT_INTKNTXFEMP BIT(4) 598 + #define DXEPINT_OUTTKNEPDIS BIT(4) 599 + #define DXEPINT_TIMEOUT BIT(3) 600 + #define DXEPINT_SETUP BIT(3) 601 + #define DXEPINT_AHBERR BIT(2) 602 + #define DXEPINT_EPDISBLD BIT(1) 603 + #define DXEPINT_XFERCOMPL BIT(0) 604 + 605 + #define DIEPTSIZ0 HSOTG_REG(0x910) 606 + #define DIEPTSIZ0_PKTCNT_MASK (0x3 << 19) 607 + #define DIEPTSIZ0_PKTCNT_SHIFT 19 608 + #define DIEPTSIZ0_PKTCNT_LIMIT 0x3 609 + #define DIEPTSIZ0_PKTCNT(_x) ((_x) << 19) 610 + #define DIEPTSIZ0_XFERSIZE_MASK (0x7f << 0) 611 + #define DIEPTSIZ0_XFERSIZE_SHIFT 0 612 + #define DIEPTSIZ0_XFERSIZE_LIMIT 0x7f 613 + #define DIEPTSIZ0_XFERSIZE(_x) ((_x) << 0) 614 + 615 + #define DOEPTSIZ0 HSOTG_REG(0xB10) 616 + #define DOEPTSIZ0_SUPCNT_MASK (0x3 << 29) 617 + #define DOEPTSIZ0_SUPCNT_SHIFT 29 618 + #define DOEPTSIZ0_SUPCNT_LIMIT 0x3 619 + #define DOEPTSIZ0_SUPCNT(_x) ((_x) << 29) 620 + #define DOEPTSIZ0_PKTCNT BIT(19) 621 + #define DOEPTSIZ0_XFERSIZE_MASK (0x7f << 0) 622 + #define DOEPTSIZ0_XFERSIZE_SHIFT 0 623 + 624 + #define DIEPTSIZ(_a) HSOTG_REG(0x910 + ((_a) * 0x20)) 625 + #define DOEPTSIZ(_a) HSOTG_REG(0xB10 + ((_a) * 0x20)) 626 + #define DXEPTSIZ_MC_MASK (0x3 << 29) 627 + #define DXEPTSIZ_MC_SHIFT 29 628 + #define DXEPTSIZ_MC_LIMIT 0x3 629 + #define DXEPTSIZ_MC(_x) ((_x) << 29) 630 + #define DXEPTSIZ_PKTCNT_MASK (0x3ff << 19) 631 + #define DXEPTSIZ_PKTCNT_SHIFT 19 632 + #define DXEPTSIZ_PKTCNT_LIMIT 0x3ff 633 + #define DXEPTSIZ_PKTCNT_GET(_v) (((_v) >> 19) & 0x3ff) 634 + #define DXEPTSIZ_PKTCNT(_x) ((_x) << 19) 635 + #define DXEPTSIZ_XFERSIZE_MASK (0x7ffff << 0) 636 + #define DXEPTSIZ_XFERSIZE_SHIFT 0 637 + #define DXEPTSIZ_XFERSIZE_LIMIT 0x7ffff 638 + #define DXEPTSIZ_XFERSIZE_GET(_v) (((_v) >> 0) & 0x7ffff) 639 + #define DXEPTSIZ_XFERSIZE(_x) ((_x) << 0) 640 + 641 + #define DIEPDMA(_a) HSOTG_REG(0x914 + ((_a) * 0x20)) 642 + #define DOEPDMA(_a) HSOTG_REG(0xB14 + ((_a) * 0x20)) 643 + 644 + #define DTXFSTS(_a) HSOTG_REG(0x918 + ((_a) * 0x20)) 645 + 646 + #define PCGCTL HSOTG_REG(0x0e00) 647 + #define PCGCTL_IF_DEV_MODE BIT(31) 648 + #define PCGCTL_P2HD_PRT_SPD_MASK (0x3 << 29) 649 + #define PCGCTL_P2HD_PRT_SPD_SHIFT 29 650 + #define PCGCTL_P2HD_DEV_ENUM_SPD_MASK (0x3 << 27) 651 + #define PCGCTL_P2HD_DEV_ENUM_SPD_SHIFT 27 652 + #define PCGCTL_MAC_DEV_ADDR_MASK (0x7f << 20) 653 + #define PCGCTL_MAC_DEV_ADDR_SHIFT 20 654 + #define PCGCTL_MAX_TERMSEL BIT(19) 655 + #define PCGCTL_MAX_XCVRSELECT_MASK (0x3 << 17) 656 + #define PCGCTL_MAX_XCVRSELECT_SHIFT 17 657 + #define PCGCTL_PORT_POWER BIT(16) 658 + #define PCGCTL_PRT_CLK_SEL_MASK (0x3 << 14) 659 + #define PCGCTL_PRT_CLK_SEL_SHIFT 14 660 + #define PCGCTL_ESS_REG_RESTORED BIT(13) 661 + #define PCGCTL_EXTND_HIBER_SWITCH BIT(12) 662 + #define PCGCTL_EXTND_HIBER_PWRCLMP BIT(11) 663 + #define PCGCTL_ENBL_EXTND_HIBER BIT(10) 664 + #define PCGCTL_RESTOREMODE BIT(9) 665 + #define PCGCTL_RESETAFTSUSP BIT(8) 666 + #define PCGCTL_DEEP_SLEEP BIT(7) 667 + #define PCGCTL_PHY_IN_SLEEP BIT(6) 668 + #define PCGCTL_ENBL_SLEEP_GATING BIT(5) 669 + #define PCGCTL_RSTPDWNMODULE BIT(3) 670 + #define PCGCTL_PWRCLMP BIT(2) 671 + #define PCGCTL_GATEHCLK BIT(1) 672 + #define PCGCTL_STOPPCLK BIT(0) 673 + 674 + #define PCGCCTL1 HSOTG_REG(0xe04) 675 + #define PCGCCTL1_TIMER (0x3 << 1) 676 + #define PCGCCTL1_GATEEN BIT(0) 677 + 678 + #define EPFIFO(_a) HSOTG_REG(0x1000 + ((_a) * 0x1000)) 679 + 680 + /* Host Mode Registers */ 681 + 682 + #define HCFG HSOTG_REG(0x0400) 683 + #define HCFG_MODECHTIMEN BIT(31) 684 + #define HCFG_PERSCHEDENA BIT(26) 685 + #define HCFG_FRLISTEN_MASK (0x3 << 24) 686 + #define HCFG_FRLISTEN_SHIFT 24 687 + #define HCFG_FRLISTEN_8 (0 << 24) 688 + #define FRLISTEN_8_SIZE 8 689 + #define HCFG_FRLISTEN_16 BIT(24) 690 + #define FRLISTEN_16_SIZE 16 691 + #define HCFG_FRLISTEN_32 (2 << 24) 692 + #define FRLISTEN_32_SIZE 32 693 + #define HCFG_FRLISTEN_64 (3 << 24) 694 + #define FRLISTEN_64_SIZE 64 695 + #define HCFG_DESCDMA BIT(23) 696 + #define HCFG_RESVALID_MASK (0xff << 8) 697 + #define HCFG_RESVALID_SHIFT 8 698 + #define HCFG_ENA32KHZ BIT(7) 699 + #define HCFG_FSLSSUPP BIT(2) 700 + #define HCFG_FSLSPCLKSEL_MASK (0x3 << 0) 701 + #define HCFG_FSLSPCLKSEL_SHIFT 0 702 + #define HCFG_FSLSPCLKSEL_30_60_MHZ 0 703 + #define HCFG_FSLSPCLKSEL_48_MHZ 1 704 + #define HCFG_FSLSPCLKSEL_6_MHZ 2 705 + 706 + #define HFIR HSOTG_REG(0x0404) 707 + #define HFIR_FRINT_MASK (0xffff << 0) 708 + #define HFIR_FRINT_SHIFT 0 709 + #define HFIR_RLDCTRL BIT(16) 710 + 711 + #define HFNUM HSOTG_REG(0x0408) 712 + #define HFNUM_FRREM_MASK (0xffff << 16) 713 + #define HFNUM_FRREM_SHIFT 16 714 + #define HFNUM_FRNUM_MASK (0xffff << 0) 715 + #define HFNUM_FRNUM_SHIFT 0 716 + #define HFNUM_MAX_FRNUM 0x3fff 717 + 718 + #define HPTXSTS HSOTG_REG(0x0410) 719 + #define TXSTS_QTOP_ODD BIT(31) 720 + #define TXSTS_QTOP_CHNEP_MASK (0xf << 27) 721 + #define TXSTS_QTOP_CHNEP_SHIFT 27 722 + #define TXSTS_QTOP_TOKEN_MASK (0x3 << 25) 723 + #define TXSTS_QTOP_TOKEN_SHIFT 25 724 + #define TXSTS_QTOP_TERMINATE BIT(24) 725 + #define TXSTS_QSPCAVAIL_MASK (0xff << 16) 726 + #define TXSTS_QSPCAVAIL_SHIFT 16 727 + #define TXSTS_FSPCAVAIL_MASK (0xffff << 0) 728 + #define TXSTS_FSPCAVAIL_SHIFT 0 729 + 730 + #define HAINT HSOTG_REG(0x0414) 731 + #define HAINTMSK HSOTG_REG(0x0418) 732 + #define HFLBADDR HSOTG_REG(0x041c) 733 + 734 + #define HPRT0 HSOTG_REG(0x0440) 735 + #define HPRT0_SPD_MASK (0x3 << 17) 736 + #define HPRT0_SPD_SHIFT 17 737 + #define HPRT0_SPD_HIGH_SPEED 0 738 + #define HPRT0_SPD_FULL_SPEED 1 739 + #define HPRT0_SPD_LOW_SPEED 2 740 + #define HPRT0_TSTCTL_MASK (0xf << 13) 741 + #define HPRT0_TSTCTL_SHIFT 13 742 + #define HPRT0_PWR BIT(12) 743 + #define HPRT0_LNSTS_MASK (0x3 << 10) 744 + #define HPRT0_LNSTS_SHIFT 10 745 + #define HPRT0_RST BIT(8) 746 + #define HPRT0_SUSP BIT(7) 747 + #define HPRT0_RES BIT(6) 748 + #define HPRT0_OVRCURRCHG BIT(5) 749 + #define HPRT0_OVRCURRACT BIT(4) 750 + #define HPRT0_ENACHG BIT(3) 751 + #define HPRT0_ENA BIT(2) 752 + #define HPRT0_CONNDET BIT(1) 753 + #define HPRT0_CONNSTS BIT(0) 754 + 755 + #define HCCHAR(_ch) HSOTG_REG(0x0500 + 0x20 * (_ch)) 756 + #define HCCHAR_CHENA BIT(31) 757 + #define HCCHAR_CHDIS BIT(30) 758 + #define HCCHAR_ODDFRM BIT(29) 759 + #define HCCHAR_DEVADDR_MASK (0x7f << 22) 760 + #define HCCHAR_DEVADDR_SHIFT 22 761 + #define HCCHAR_MULTICNT_MASK (0x3 << 20) 762 + #define HCCHAR_MULTICNT_SHIFT 20 763 + #define HCCHAR_EPTYPE_MASK (0x3 << 18) 764 + #define HCCHAR_EPTYPE_SHIFT 18 765 + #define HCCHAR_LSPDDEV BIT(17) 766 + #define HCCHAR_EPDIR BIT(15) 767 + #define HCCHAR_EPNUM_MASK (0xf << 11) 768 + #define HCCHAR_EPNUM_SHIFT 11 769 + #define HCCHAR_MPS_MASK (0x7ff << 0) 770 + #define HCCHAR_MPS_SHIFT 0 771 + 772 + #define HCSPLT(_ch) HSOTG_REG(0x0504 + 0x20 * (_ch)) 773 + #define HCSPLT_SPLTENA BIT(31) 774 + #define HCSPLT_COMPSPLT BIT(16) 775 + #define HCSPLT_XACTPOS_MASK (0x3 << 14) 776 + #define HCSPLT_XACTPOS_SHIFT 14 777 + #define HCSPLT_XACTPOS_MID 0 778 + #define HCSPLT_XACTPOS_END 1 779 + #define HCSPLT_XACTPOS_BEGIN 2 780 + #define HCSPLT_XACTPOS_ALL 3 781 + #define HCSPLT_HUBADDR_MASK (0x7f << 7) 782 + #define HCSPLT_HUBADDR_SHIFT 7 783 + #define HCSPLT_PRTADDR_MASK (0x7f << 0) 784 + #define HCSPLT_PRTADDR_SHIFT 0 785 + 786 + #define HCINT(_ch) HSOTG_REG(0x0508 + 0x20 * (_ch)) 787 + #define HCINTMSK(_ch) HSOTG_REG(0x050c + 0x20 * (_ch)) 788 + #define HCINTMSK_RESERVED14_31 (0x3ffff << 14) 789 + #define HCINTMSK_FRM_LIST_ROLL BIT(13) 790 + #define HCINTMSK_XCS_XACT BIT(12) 791 + #define HCINTMSK_BNA BIT(11) 792 + #define HCINTMSK_DATATGLERR BIT(10) 793 + #define HCINTMSK_FRMOVRUN BIT(9) 794 + #define HCINTMSK_BBLERR BIT(8) 795 + #define HCINTMSK_XACTERR BIT(7) 796 + #define HCINTMSK_NYET BIT(6) 797 + #define HCINTMSK_ACK BIT(5) 798 + #define HCINTMSK_NAK BIT(4) 799 + #define HCINTMSK_STALL BIT(3) 800 + #define HCINTMSK_AHBERR BIT(2) 801 + #define HCINTMSK_CHHLTD BIT(1) 802 + #define HCINTMSK_XFERCOMPL BIT(0) 803 + 804 + #define HCTSIZ(_ch) HSOTG_REG(0x0510 + 0x20 * (_ch)) 805 + #define TSIZ_DOPNG BIT(31) 806 + #define TSIZ_SC_MC_PID_MASK (0x3 << 29) 807 + #define TSIZ_SC_MC_PID_SHIFT 29 808 + #define TSIZ_SC_MC_PID_DATA0 0 809 + #define TSIZ_SC_MC_PID_DATA2 1 810 + #define TSIZ_SC_MC_PID_DATA1 2 811 + #define TSIZ_SC_MC_PID_MDATA 3 812 + #define TSIZ_SC_MC_PID_SETUP 3 813 + #define TSIZ_PKTCNT_MASK (0x3ff << 19) 814 + #define TSIZ_PKTCNT_SHIFT 19 815 + #define TSIZ_NTD_MASK (0xff << 8) 816 + #define TSIZ_NTD_SHIFT 8 817 + #define TSIZ_SCHINFO_MASK (0xff << 0) 818 + #define TSIZ_SCHINFO_SHIFT 0 819 + #define TSIZ_XFERSIZE_MASK (0x7ffff << 0) 820 + #define TSIZ_XFERSIZE_SHIFT 0 821 + 822 + #define HCDMA(_ch) HSOTG_REG(0x0514 + 0x20 * (_ch)) 823 + 824 + #define HCDMAB(_ch) HSOTG_REG(0x051c + 0x20 * (_ch)) 825 + 826 + #define HCFIFO(_ch) HSOTG_REG(0x1000 + 0x1000 * (_ch)) 827 + 828 + /** 829 + * struct dwc2_dma_desc - DMA descriptor structure, 830 + * used for both host and gadget modes 831 + * 832 + * @status: DMA descriptor status quadlet 833 + * @buf: DMA descriptor data buffer pointer 834 + * 835 + * DMA Descriptor structure contains two quadlets: 836 + * Status quadlet and Data buffer pointer. 837 + */ 838 + struct dwc2_dma_desc { 839 + uint32_t status; 840 + uint32_t buf; 841 + } __packed; 842 + 843 + /* Host Mode DMA descriptor status quadlet */ 844 + 845 + #define HOST_DMA_A BIT(31) 846 + #define HOST_DMA_STS_MASK (0x3 << 28) 847 + #define HOST_DMA_STS_SHIFT 28 848 + #define HOST_DMA_STS_PKTERR BIT(28) 849 + #define HOST_DMA_EOL BIT(26) 850 + #define HOST_DMA_IOC BIT(25) 851 + #define HOST_DMA_SUP BIT(24) 852 + #define HOST_DMA_ALT_QTD BIT(23) 853 + #define HOST_DMA_QTD_OFFSET_MASK (0x3f << 17) 854 + #define HOST_DMA_QTD_OFFSET_SHIFT 17 855 + #define HOST_DMA_ISOC_NBYTES_MASK (0xfff << 0) 856 + #define HOST_DMA_ISOC_NBYTES_SHIFT 0 857 + #define HOST_DMA_NBYTES_MASK (0x1ffff << 0) 858 + #define HOST_DMA_NBYTES_SHIFT 0 859 + #define HOST_DMA_NBYTES_LIMIT 131071 860 + 861 + /* Device Mode DMA descriptor status quadlet */ 862 + 863 + #define DEV_DMA_BUFF_STS_MASK (0x3 << 30) 864 + #define DEV_DMA_BUFF_STS_SHIFT 30 865 + #define DEV_DMA_BUFF_STS_HREADY 0 866 + #define DEV_DMA_BUFF_STS_DMABUSY 1 867 + #define DEV_DMA_BUFF_STS_DMADONE 2 868 + #define DEV_DMA_BUFF_STS_HBUSY 3 869 + #define DEV_DMA_STS_MASK (0x3 << 28) 870 + #define DEV_DMA_STS_SHIFT 28 871 + #define DEV_DMA_STS_SUCC 0 872 + #define DEV_DMA_STS_BUFF_FLUSH 1 873 + #define DEV_DMA_STS_BUFF_ERR 3 874 + #define DEV_DMA_L BIT(27) 875 + #define DEV_DMA_SHORT BIT(26) 876 + #define DEV_DMA_IOC BIT(25) 877 + #define DEV_DMA_SR BIT(24) 878 + #define DEV_DMA_MTRF BIT(23) 879 + #define DEV_DMA_ISOC_PID_MASK (0x3 << 23) 880 + #define DEV_DMA_ISOC_PID_SHIFT 23 881 + #define DEV_DMA_ISOC_PID_DATA0 0 882 + #define DEV_DMA_ISOC_PID_DATA2 1 883 + #define DEV_DMA_ISOC_PID_DATA1 2 884 + #define DEV_DMA_ISOC_PID_MDATA 3 885 + #define DEV_DMA_ISOC_FRNUM_MASK (0x7ff << 12) 886 + #define DEV_DMA_ISOC_FRNUM_SHIFT 12 887 + #define DEV_DMA_ISOC_TX_NBYTES_MASK (0xfff << 0) 888 + #define DEV_DMA_ISOC_TX_NBYTES_LIMIT 0xfff 889 + #define DEV_DMA_ISOC_RX_NBYTES_MASK (0x7ff << 0) 890 + #define DEV_DMA_ISOC_RX_NBYTES_LIMIT 0x7ff 891 + #define DEV_DMA_ISOC_NBYTES_SHIFT 0 892 + #define DEV_DMA_NBYTES_MASK (0xffff << 0) 893 + #define DEV_DMA_NBYTES_SHIFT 0 894 + #define DEV_DMA_NBYTES_LIMIT 0xffff 895 + 896 + #define MAX_DMA_DESC_NUM_GENERIC 64 897 + #define MAX_DMA_DESC_NUM_HS_ISOC 256 898 + 899 + #endif /* __DWC2_HW_H__ */
+192 -75
target/arm/crypto_helper.c
··· 13 13 14 14 #include "cpu.h" 15 15 #include "exec/helper-proto.h" 16 + #include "tcg/tcg-gvec-desc.h" 16 17 #include "crypto/aes.h" 18 + #include "vec_internal.h" 17 19 18 20 union CRYPTO_STATE { 19 21 uint8_t bytes[16]; ··· 22 24 }; 23 25 24 26 #ifdef HOST_WORDS_BIGENDIAN 25 - #define CR_ST_BYTE(state, i) (state.bytes[(15 - (i)) ^ 8]) 26 - #define CR_ST_WORD(state, i) (state.words[(3 - (i)) ^ 2]) 27 + #define CR_ST_BYTE(state, i) ((state).bytes[(15 - (i)) ^ 8]) 28 + #define CR_ST_WORD(state, i) ((state).words[(3 - (i)) ^ 2]) 27 29 #else 28 - #define CR_ST_BYTE(state, i) (state.bytes[i]) 29 - #define CR_ST_WORD(state, i) (state.words[i]) 30 + #define CR_ST_BYTE(state, i) ((state).bytes[i]) 31 + #define CR_ST_WORD(state, i) ((state).words[i]) 30 32 #endif 31 33 32 - void HELPER(crypto_aese)(void *vd, void *vm, uint32_t decrypt) 34 + /* 35 + * The caller has not been converted to full gvec, and so only 36 + * modifies the low 16 bytes of the vector register. 37 + */ 38 + static void clear_tail_16(void *vd, uint32_t desc) 39 + { 40 + int opr_sz = simd_oprsz(desc); 41 + int max_sz = simd_maxsz(desc); 42 + 43 + assert(opr_sz == 16); 44 + clear_tail(vd, opr_sz, max_sz); 45 + } 46 + 47 + static void do_crypto_aese(uint64_t *rd, uint64_t *rn, 48 + uint64_t *rm, bool decrypt) 33 49 { 34 50 static uint8_t const * const sbox[2] = { AES_sbox, AES_isbox }; 35 51 static uint8_t const * const shift[2] = { AES_shifts, AES_ishifts }; 36 - uint64_t *rd = vd; 37 - uint64_t *rm = vm; 38 52 union CRYPTO_STATE rk = { .l = { rm[0], rm[1] } }; 39 - union CRYPTO_STATE st = { .l = { rd[0], rd[1] } }; 53 + union CRYPTO_STATE st = { .l = { rn[0], rn[1] } }; 40 54 int i; 41 - 42 - assert(decrypt < 2); 43 55 44 56 /* xor state vector with round key */ 45 57 rk.l[0] ^= st.l[0]; ··· 54 66 rd[1] = st.l[1]; 55 67 } 56 68 57 - void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t decrypt) 69 + void HELPER(crypto_aese)(void *vd, void *vn, void *vm, uint32_t desc) 70 + { 71 + intptr_t i, opr_sz = simd_oprsz(desc); 72 + bool decrypt = simd_data(desc); 73 + 74 + for (i = 0; i < opr_sz; i += 16) { 75 + do_crypto_aese(vd + i, vn + i, vm + i, decrypt); 76 + } 77 + clear_tail(vd, opr_sz, simd_maxsz(desc)); 78 + } 79 + 80 + static void do_crypto_aesmc(uint64_t *rd, uint64_t *rm, bool decrypt) 58 81 { 59 82 static uint32_t const mc[][256] = { { 60 83 /* MixColumns lookup table */ ··· 190 213 0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d, 191 214 } }; 192 215 193 - uint64_t *rd = vd; 194 - uint64_t *rm = vm; 195 216 union CRYPTO_STATE st = { .l = { rm[0], rm[1] } }; 196 217 int i; 197 - 198 - assert(decrypt < 2); 199 218 200 219 for (i = 0; i < 16; i += 4) { 201 220 CR_ST_WORD(st, i >> 2) = ··· 209 228 rd[1] = st.l[1]; 210 229 } 211 230 231 + void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t desc) 232 + { 233 + intptr_t i, opr_sz = simd_oprsz(desc); 234 + bool decrypt = simd_data(desc); 235 + 236 + for (i = 0; i < opr_sz; i += 16) { 237 + do_crypto_aesmc(vd + i, vm + i, decrypt); 238 + } 239 + clear_tail(vd, opr_sz, simd_maxsz(desc)); 240 + } 241 + 212 242 /* 213 243 * SHA-1 logical functions 214 244 */ ··· 228 258 return (x & y) | ((x | y) & z); 229 259 } 230 260 231 - void HELPER(crypto_sha1_3reg)(void *vd, void *vn, void *vm, uint32_t op) 261 + void HELPER(crypto_sha1su0)(void *vd, void *vn, void *vm, uint32_t desc) 232 262 { 233 - uint64_t *rd = vd; 234 - uint64_t *rn = vn; 235 - uint64_t *rm = vm; 263 + uint64_t *d = vd, *n = vn, *m = vm; 264 + uint64_t d0, d1; 265 + 266 + d0 = d[1] ^ d[0] ^ m[0]; 267 + d1 = n[0] ^ d[1] ^ m[1]; 268 + d[0] = d0; 269 + d[1] = d1; 270 + 271 + clear_tail_16(vd, desc); 272 + } 273 + 274 + static inline void crypto_sha1_3reg(uint64_t *rd, uint64_t *rn, 275 + uint64_t *rm, uint32_t desc, 276 + uint32_t (*fn)(union CRYPTO_STATE *d)) 277 + { 236 278 union CRYPTO_STATE d = { .l = { rd[0], rd[1] } }; 237 279 union CRYPTO_STATE n = { .l = { rn[0], rn[1] } }; 238 280 union CRYPTO_STATE m = { .l = { rm[0], rm[1] } }; 281 + int i; 239 282 240 - if (op == 3) { /* sha1su0 */ 241 - d.l[0] ^= d.l[1] ^ m.l[0]; 242 - d.l[1] ^= n.l[0] ^ m.l[1]; 243 - } else { 244 - int i; 283 + for (i = 0; i < 4; i++) { 284 + uint32_t t = fn(&d); 245 285 246 - for (i = 0; i < 4; i++) { 247 - uint32_t t; 286 + t += rol32(CR_ST_WORD(d, 0), 5) + CR_ST_WORD(n, 0) 287 + + CR_ST_WORD(m, i); 248 288 249 - switch (op) { 250 - case 0: /* sha1c */ 251 - t = cho(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3)); 252 - break; 253 - case 1: /* sha1p */ 254 - t = par(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3)); 255 - break; 256 - case 2: /* sha1m */ 257 - t = maj(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3)); 258 - break; 259 - default: 260 - g_assert_not_reached(); 261 - } 262 - t += rol32(CR_ST_WORD(d, 0), 5) + CR_ST_WORD(n, 0) 263 - + CR_ST_WORD(m, i); 264 - 265 - CR_ST_WORD(n, 0) = CR_ST_WORD(d, 3); 266 - CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2); 267 - CR_ST_WORD(d, 2) = ror32(CR_ST_WORD(d, 1), 2); 268 - CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0); 269 - CR_ST_WORD(d, 0) = t; 270 - } 289 + CR_ST_WORD(n, 0) = CR_ST_WORD(d, 3); 290 + CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2); 291 + CR_ST_WORD(d, 2) = ror32(CR_ST_WORD(d, 1), 2); 292 + CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0); 293 + CR_ST_WORD(d, 0) = t; 271 294 } 272 295 rd[0] = d.l[0]; 273 296 rd[1] = d.l[1]; 297 + 298 + clear_tail_16(rd, desc); 299 + } 300 + 301 + static uint32_t do_sha1c(union CRYPTO_STATE *d) 302 + { 303 + return cho(CR_ST_WORD(*d, 1), CR_ST_WORD(*d, 2), CR_ST_WORD(*d, 3)); 274 304 } 275 305 276 - void HELPER(crypto_sha1h)(void *vd, void *vm) 306 + void HELPER(crypto_sha1c)(void *vd, void *vn, void *vm, uint32_t desc) 307 + { 308 + crypto_sha1_3reg(vd, vn, vm, desc, do_sha1c); 309 + } 310 + 311 + static uint32_t do_sha1p(union CRYPTO_STATE *d) 312 + { 313 + return par(CR_ST_WORD(*d, 1), CR_ST_WORD(*d, 2), CR_ST_WORD(*d, 3)); 314 + } 315 + 316 + void HELPER(crypto_sha1p)(void *vd, void *vn, void *vm, uint32_t desc) 317 + { 318 + crypto_sha1_3reg(vd, vn, vm, desc, do_sha1p); 319 + } 320 + 321 + static uint32_t do_sha1m(union CRYPTO_STATE *d) 322 + { 323 + return maj(CR_ST_WORD(*d, 1), CR_ST_WORD(*d, 2), CR_ST_WORD(*d, 3)); 324 + } 325 + 326 + void HELPER(crypto_sha1m)(void *vd, void *vn, void *vm, uint32_t desc) 327 + { 328 + crypto_sha1_3reg(vd, vn, vm, desc, do_sha1m); 329 + } 330 + 331 + void HELPER(crypto_sha1h)(void *vd, void *vm, uint32_t desc) 277 332 { 278 333 uint64_t *rd = vd; 279 334 uint64_t *rm = vm; ··· 284 339 285 340 rd[0] = m.l[0]; 286 341 rd[1] = m.l[1]; 342 + 343 + clear_tail_16(vd, desc); 287 344 } 288 345 289 - void HELPER(crypto_sha1su1)(void *vd, void *vm) 346 + void HELPER(crypto_sha1su1)(void *vd, void *vm, uint32_t desc) 290 347 { 291 348 uint64_t *rd = vd; 292 349 uint64_t *rm = vm; ··· 300 357 301 358 rd[0] = d.l[0]; 302 359 rd[1] = d.l[1]; 360 + 361 + clear_tail_16(vd, desc); 303 362 } 304 363 305 364 /* ··· 327 386 return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10); 328 387 } 329 388 330 - void HELPER(crypto_sha256h)(void *vd, void *vn, void *vm) 389 + void HELPER(crypto_sha256h)(void *vd, void *vn, void *vm, uint32_t desc) 331 390 { 332 391 uint64_t *rd = vd; 333 392 uint64_t *rn = vn; ··· 358 417 359 418 rd[0] = d.l[0]; 360 419 rd[1] = d.l[1]; 420 + 421 + clear_tail_16(vd, desc); 361 422 } 362 423 363 - void HELPER(crypto_sha256h2)(void *vd, void *vn, void *vm) 424 + void HELPER(crypto_sha256h2)(void *vd, void *vn, void *vm, uint32_t desc) 364 425 { 365 426 uint64_t *rd = vd; 366 427 uint64_t *rn = vn; ··· 383 444 384 445 rd[0] = d.l[0]; 385 446 rd[1] = d.l[1]; 447 + 448 + clear_tail_16(vd, desc); 386 449 } 387 450 388 - void HELPER(crypto_sha256su0)(void *vd, void *vm) 451 + void HELPER(crypto_sha256su0)(void *vd, void *vm, uint32_t desc) 389 452 { 390 453 uint64_t *rd = vd; 391 454 uint64_t *rm = vm; ··· 399 462 400 463 rd[0] = d.l[0]; 401 464 rd[1] = d.l[1]; 465 + 466 + clear_tail_16(vd, desc); 402 467 } 403 468 404 - void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm) 469 + void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm, uint32_t desc) 405 470 { 406 471 uint64_t *rd = vd; 407 472 uint64_t *rn = vn; ··· 417 482 418 483 rd[0] = d.l[0]; 419 484 rd[1] = d.l[1]; 485 + 486 + clear_tail_16(vd, desc); 420 487 } 421 488 422 489 /* ··· 453 520 return ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6); 454 521 } 455 522 456 - void HELPER(crypto_sha512h)(void *vd, void *vn, void *vm) 523 + void HELPER(crypto_sha512h)(void *vd, void *vn, void *vm, uint32_t desc) 457 524 { 458 525 uint64_t *rd = vd; 459 526 uint64_t *rn = vn; ··· 466 533 467 534 rd[0] = d0; 468 535 rd[1] = d1; 536 + 537 + clear_tail_16(vd, desc); 469 538 } 470 539 471 - void HELPER(crypto_sha512h2)(void *vd, void *vn, void *vm) 540 + void HELPER(crypto_sha512h2)(void *vd, void *vn, void *vm, uint32_t desc) 472 541 { 473 542 uint64_t *rd = vd; 474 543 uint64_t *rn = vn; ··· 481 550 482 551 rd[0] = d0; 483 552 rd[1] = d1; 553 + 554 + clear_tail_16(vd, desc); 484 555 } 485 556 486 - void HELPER(crypto_sha512su0)(void *vd, void *vn) 557 + void HELPER(crypto_sha512su0)(void *vd, void *vn, uint32_t desc) 487 558 { 488 559 uint64_t *rd = vd; 489 560 uint64_t *rn = vn; ··· 495 566 496 567 rd[0] = d0; 497 568 rd[1] = d1; 569 + 570 + clear_tail_16(vd, desc); 498 571 } 499 572 500 - void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm) 573 + void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm, uint32_t desc) 501 574 { 502 575 uint64_t *rd = vd; 503 576 uint64_t *rn = vn; ··· 505 578 506 579 rd[0] += s1_512(rn[0]) + rm[0]; 507 580 rd[1] += s1_512(rn[1]) + rm[1]; 581 + 582 + clear_tail_16(vd, desc); 508 583 } 509 584 510 - void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm) 585 + void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm, uint32_t desc) 511 586 { 512 587 uint64_t *rd = vd; 513 588 uint64_t *rn = vn; ··· 531 606 532 607 rd[0] = d.l[0]; 533 608 rd[1] = d.l[1]; 609 + 610 + clear_tail_16(vd, desc); 534 611 } 535 612 536 - void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm) 613 + void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm, uint32_t desc) 537 614 { 538 615 uint64_t *rd = vd; 539 616 uint64_t *rn = vn; ··· 551 628 552 629 rd[0] = d.l[0]; 553 630 rd[1] = d.l[1]; 631 + 632 + clear_tail_16(vd, desc); 554 633 } 555 634 556 - void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2, 557 - uint32_t opcode) 635 + static inline void QEMU_ALWAYS_INLINE 636 + crypto_sm3tt(uint64_t *rd, uint64_t *rn, uint64_t *rm, 637 + uint32_t desc, uint32_t opcode) 558 638 { 559 - uint64_t *rd = vd; 560 - uint64_t *rn = vn; 561 - uint64_t *rm = vm; 562 639 union CRYPTO_STATE d = { .l = { rd[0], rd[1] } }; 563 640 union CRYPTO_STATE n = { .l = { rn[0], rn[1] } }; 564 641 union CRYPTO_STATE m = { .l = { rm[0], rm[1] } }; 642 + uint32_t imm2 = simd_data(desc); 565 643 uint32_t t; 566 644 567 645 assert(imm2 < 4); ··· 576 654 /* SM3TT2B */ 577 655 t = cho(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1)); 578 656 } else { 579 - g_assert_not_reached(); 657 + qemu_build_not_reached(); 580 658 } 581 659 582 660 t += CR_ST_WORD(d, 0) + CR_ST_WORD(m, imm2); ··· 601 679 602 680 rd[0] = d.l[0]; 603 681 rd[1] = d.l[1]; 682 + 683 + clear_tail_16(rd, desc); 604 684 } 605 685 686 + #define DO_SM3TT(NAME, OPCODE) \ 687 + void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \ 688 + { crypto_sm3tt(vd, vn, vm, desc, OPCODE); } 689 + 690 + DO_SM3TT(crypto_sm3tt1a, 0) 691 + DO_SM3TT(crypto_sm3tt1b, 1) 692 + DO_SM3TT(crypto_sm3tt2a, 2) 693 + DO_SM3TT(crypto_sm3tt2b, 3) 694 + 695 + #undef DO_SM3TT 696 + 606 697 static uint8_t const sm4_sbox[] = { 607 698 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 608 699 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05, ··· 638 729 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48, 639 730 }; 640 731 641 - void HELPER(crypto_sm4e)(void *vd, void *vn) 732 + static void do_crypto_sm4e(uint64_t *rd, uint64_t *rn, uint64_t *rm) 642 733 { 643 - uint64_t *rd = vd; 644 - uint64_t *rn = vn; 645 - union CRYPTO_STATE d = { .l = { rd[0], rd[1] } }; 646 - union CRYPTO_STATE n = { .l = { rn[0], rn[1] } }; 734 + union CRYPTO_STATE d = { .l = { rn[0], rn[1] } }; 735 + union CRYPTO_STATE n = { .l = { rm[0], rm[1] } }; 647 736 uint32_t t, i; 648 737 649 738 for (i = 0; i < 4; i++) { ··· 665 754 rd[1] = d.l[1]; 666 755 } 667 756 668 - void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm) 757 + void HELPER(crypto_sm4e)(void *vd, void *vn, void *vm, uint32_t desc) 669 758 { 670 - uint64_t *rd = vd; 671 - uint64_t *rn = vn; 672 - uint64_t *rm = vm; 759 + intptr_t i, opr_sz = simd_oprsz(desc); 760 + 761 + for (i = 0; i < opr_sz; i += 16) { 762 + do_crypto_sm4e(vd + i, vn + i, vm + i); 763 + } 764 + clear_tail(vd, opr_sz, simd_maxsz(desc)); 765 + } 766 + 767 + static void do_crypto_sm4ekey(uint64_t *rd, uint64_t *rn, uint64_t *rm) 768 + { 673 769 union CRYPTO_STATE d; 674 770 union CRYPTO_STATE n = { .l = { rn[0], rn[1] } }; 675 771 union CRYPTO_STATE m = { .l = { rm[0], rm[1] } }; ··· 693 789 rd[0] = d.l[0]; 694 790 rd[1] = d.l[1]; 695 791 } 792 + 793 + void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm, uint32_t desc) 794 + { 795 + intptr_t i, opr_sz = simd_oprsz(desc); 796 + 797 + for (i = 0; i < opr_sz; i += 16) { 798 + do_crypto_sm4ekey(vd + i, vn + i, vm + i); 799 + } 800 + clear_tail(vd, opr_sz, simd_maxsz(desc)); 801 + } 802 + 803 + void HELPER(crypto_rax1)(void *vd, void *vn, void *vm, uint32_t desc) 804 + { 805 + intptr_t i, opr_sz = simd_oprsz(desc); 806 + uint64_t *d = vd, *n = vn, *m = vm; 807 + 808 + for (i = 0; i < opr_sz / 8; ++i) { 809 + d[i] = n[i] ^ rol64(m[i], 1); 810 + } 811 + clear_tail(vd, opr_sz, simd_maxsz(desc)); 812 + }
+28 -17
target/arm/helper.h
··· 510 510 DEF_HELPER_FLAGS_2(neon_qzip16, TCG_CALL_NO_RWG, void, ptr, ptr) 511 511 DEF_HELPER_FLAGS_2(neon_qzip32, TCG_CALL_NO_RWG, void, ptr, ptr) 512 512 513 - DEF_HELPER_FLAGS_3(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, i32) 513 + DEF_HELPER_FLAGS_4(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 514 514 DEF_HELPER_FLAGS_3(crypto_aesmc, TCG_CALL_NO_RWG, void, ptr, ptr, i32) 515 515 516 - DEF_HELPER_FLAGS_4(crypto_sha1_3reg, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 517 - DEF_HELPER_FLAGS_2(crypto_sha1h, TCG_CALL_NO_RWG, void, ptr, ptr) 518 - DEF_HELPER_FLAGS_2(crypto_sha1su1, TCG_CALL_NO_RWG, void, ptr, ptr) 516 + DEF_HELPER_FLAGS_4(crypto_sha1su0, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 517 + DEF_HELPER_FLAGS_4(crypto_sha1c, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 518 + DEF_HELPER_FLAGS_4(crypto_sha1p, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 519 + DEF_HELPER_FLAGS_4(crypto_sha1m, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 520 + DEF_HELPER_FLAGS_3(crypto_sha1h, TCG_CALL_NO_RWG, void, ptr, ptr, i32) 521 + DEF_HELPER_FLAGS_3(crypto_sha1su1, TCG_CALL_NO_RWG, void, ptr, ptr, i32) 522 + 523 + DEF_HELPER_FLAGS_4(crypto_sha256h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 524 + DEF_HELPER_FLAGS_4(crypto_sha256h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 525 + DEF_HELPER_FLAGS_3(crypto_sha256su0, TCG_CALL_NO_RWG, void, ptr, ptr, i32) 526 + DEF_HELPER_FLAGS_4(crypto_sha256su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 519 527 520 - DEF_HELPER_FLAGS_3(crypto_sha256h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr) 521 - DEF_HELPER_FLAGS_3(crypto_sha256h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr) 522 - DEF_HELPER_FLAGS_2(crypto_sha256su0, TCG_CALL_NO_RWG, void, ptr, ptr) 523 - DEF_HELPER_FLAGS_3(crypto_sha256su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr) 528 + DEF_HELPER_FLAGS_4(crypto_sha512h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 529 + DEF_HELPER_FLAGS_4(crypto_sha512h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 530 + DEF_HELPER_FLAGS_3(crypto_sha512su0, TCG_CALL_NO_RWG, void, ptr, ptr, i32) 531 + DEF_HELPER_FLAGS_4(crypto_sha512su1, TCG_CALL_NO_RWG, 532 + void, ptr, ptr, ptr, i32) 524 533 525 - DEF_HELPER_FLAGS_3(crypto_sha512h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr) 526 - DEF_HELPER_FLAGS_3(crypto_sha512h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr) 527 - DEF_HELPER_FLAGS_2(crypto_sha512su0, TCG_CALL_NO_RWG, void, ptr, ptr) 528 - DEF_HELPER_FLAGS_3(crypto_sha512su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr) 534 + DEF_HELPER_FLAGS_4(crypto_sm3tt1a, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 535 + DEF_HELPER_FLAGS_4(crypto_sm3tt1b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 536 + DEF_HELPER_FLAGS_4(crypto_sm3tt2a, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 537 + DEF_HELPER_FLAGS_4(crypto_sm3tt2b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 538 + DEF_HELPER_FLAGS_4(crypto_sm3partw1, TCG_CALL_NO_RWG, 539 + void, ptr, ptr, ptr, i32) 540 + DEF_HELPER_FLAGS_4(crypto_sm3partw2, TCG_CALL_NO_RWG, 541 + void, ptr, ptr, ptr, i32) 529 542 530 - DEF_HELPER_FLAGS_5(crypto_sm3tt, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, i32) 531 - DEF_HELPER_FLAGS_3(crypto_sm3partw1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr) 532 - DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr) 543 + DEF_HELPER_FLAGS_4(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 544 + DEF_HELPER_FLAGS_4(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 533 545 534 - DEF_HELPER_FLAGS_2(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr) 535 - DEF_HELPER_FLAGS_3(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr) 546 + DEF_HELPER_FLAGS_4(crypto_rax1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) 536 547 537 548 DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32) 538 549 DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
+206 -8
target/arm/neon-dp.decode
··· 165 165 166 166 VQRDMLAH_3s 1111 001 1 0 . .. .... .... 1011 ... 1 .... @3same 167 167 168 - SHA1_3s 1111 001 0 0 . optype:2 .... .... 1100 . 1 . 0 .... \ 169 - vm=%vm_dp vn=%vn_dp vd=%vd_dp 170 - SHA256H_3s 1111 001 1 0 . 00 .... .... 1100 . 1 . 0 .... \ 171 - vm=%vm_dp vn=%vn_dp vd=%vd_dp 172 - SHA256H2_3s 1111 001 1 0 . 01 .... .... 1100 . 1 . 0 .... \ 173 - vm=%vm_dp vn=%vn_dp vd=%vd_dp 174 - SHA256SU1_3s 1111 001 1 0 . 10 .... .... 1100 . 1 . 0 .... \ 175 - vm=%vm_dp vn=%vn_dp vd=%vd_dp 168 + @3same_crypto .... .... .... .... .... .... .... .... \ 169 + &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0 q=1 170 + 171 + SHA1C_3s 1111 001 0 0 . 00 .... .... 1100 . 1 . 0 .... @3same_crypto 172 + SHA1P_3s 1111 001 0 0 . 01 .... .... 1100 . 1 . 0 .... @3same_crypto 173 + SHA1M_3s 1111 001 0 0 . 10 .... .... 1100 . 1 . 0 .... @3same_crypto 174 + SHA1SU0_3s 1111 001 0 0 . 11 .... .... 1100 . 1 . 0 .... @3same_crypto 175 + SHA256H_3s 1111 001 1 0 . 00 .... .... 1100 . 1 . 0 .... @3same_crypto 176 + SHA256H2_3s 1111 001 1 0 . 01 .... .... 1100 . 1 . 0 .... @3same_crypto 177 + SHA256SU1_3s 1111 001 1 0 . 10 .... .... 1100 . 1 . 0 .... @3same_crypto 176 178 177 179 VFMA_fp_3s 1111 001 0 0 . 0 . .... .... 1100 ... 1 .... @3same_fp 178 180 VFMS_fp_3s 1111 001 0 0 . 1 . .... .... 1100 ... 1 .... @3same_fp ··· 199 201 VRSQRTS_fp_3s 1111 001 0 0 . 1 . .... .... 1111 ... 1 .... @3same_fp 200 202 VMAXNM_fp_3s 1111 001 1 0 . 0 . .... .... 1111 ... 1 .... @3same_fp 201 203 VMINNM_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 1 .... @3same_fp 204 + 205 + ###################################################################### 206 + # 2-reg-and-shift grouping: 207 + # 1111 001 U 1 D immH:3 immL:3 Vd:4 opc:4 L Q M 1 Vm:4 208 + ###################################################################### 209 + &2reg_shift vm vd q shift size 210 + 211 + # Right shifts are encoded as N - shift, where N is the element size in bits. 212 + %neon_rshift_i6 16:6 !function=rsub_64 213 + %neon_rshift_i5 16:5 !function=rsub_32 214 + %neon_rshift_i4 16:4 !function=rsub_16 215 + %neon_rshift_i3 16:3 !function=rsub_8 216 + 217 + @2reg_shr_d .... ... . . . ...... .... .... 1 q:1 . . .... \ 218 + &2reg_shift vm=%vm_dp vd=%vd_dp size=3 shift=%neon_rshift_i6 219 + @2reg_shr_s .... ... . . . 1 ..... .... .... 0 q:1 . . .... \ 220 + &2reg_shift vm=%vm_dp vd=%vd_dp size=2 shift=%neon_rshift_i5 221 + @2reg_shr_h .... ... . . . 01 .... .... .... 0 q:1 . . .... \ 222 + &2reg_shift vm=%vm_dp vd=%vd_dp size=1 shift=%neon_rshift_i4 223 + @2reg_shr_b .... ... . . . 001 ... .... .... 0 q:1 . . .... \ 224 + &2reg_shift vm=%vm_dp vd=%vd_dp size=0 shift=%neon_rshift_i3 225 + 226 + @2reg_shl_d .... ... . . . shift:6 .... .... 1 q:1 . . .... \ 227 + &2reg_shift vm=%vm_dp vd=%vd_dp size=3 228 + @2reg_shl_s .... ... . . . 1 shift:5 .... .... 0 q:1 . . .... \ 229 + &2reg_shift vm=%vm_dp vd=%vd_dp size=2 230 + @2reg_shl_h .... ... . . . 01 shift:4 .... .... 0 q:1 . . .... \ 231 + &2reg_shift vm=%vm_dp vd=%vd_dp size=1 232 + @2reg_shl_b .... ... . . . 001 shift:3 .... .... 0 q:1 . . .... \ 233 + &2reg_shift vm=%vm_dp vd=%vd_dp size=0 234 + 235 + # Narrowing right shifts: here the Q bit is part of the opcode decode 236 + @2reg_shrn_d .... ... . . . 1 ..... .... .... 0 . . . .... \ 237 + &2reg_shift vm=%vm_dp vd=%vd_dp size=3 q=0 \ 238 + shift=%neon_rshift_i5 239 + @2reg_shrn_s .... ... . . . 01 .... .... .... 0 . . . .... \ 240 + &2reg_shift vm=%vm_dp vd=%vd_dp size=2 q=0 \ 241 + shift=%neon_rshift_i4 242 + @2reg_shrn_h .... ... . . . 001 ... .... .... 0 . . . .... \ 243 + &2reg_shift vm=%vm_dp vd=%vd_dp size=1 q=0 \ 244 + shift=%neon_rshift_i3 245 + 246 + # Long left shifts: again Q is part of opcode decode 247 + @2reg_shll_s .... ... . . . 1 shift:5 .... .... 0 . . . .... \ 248 + &2reg_shift vm=%vm_dp vd=%vd_dp size=2 q=0 249 + @2reg_shll_h .... ... . . . 01 shift:4 .... .... 0 . . . .... \ 250 + &2reg_shift vm=%vm_dp vd=%vd_dp size=1 q=0 251 + @2reg_shll_b .... ... . . . 001 shift:3 .... .... 0 . . . .... \ 252 + &2reg_shift vm=%vm_dp vd=%vd_dp size=0 q=0 253 + 254 + # We use size=0 for fp32 and size=1 for fp16 to match the 3-same encodings. 255 + @2reg_vcvt .... ... . . . 1 ..... .... .... . q:1 . . .... \ 256 + &2reg_shift vm=%vm_dp vd=%vd_dp size=0 shift=%neon_rshift_i5 257 + 258 + VSHR_S_2sh 1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_d 259 + VSHR_S_2sh 1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_s 260 + VSHR_S_2sh 1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_h 261 + VSHR_S_2sh 1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_b 262 + 263 + VSHR_U_2sh 1111 001 1 1 . ...... .... 0000 . . . 1 .... @2reg_shr_d 264 + VSHR_U_2sh 1111 001 1 1 . ...... .... 0000 . . . 1 .... @2reg_shr_s 265 + VSHR_U_2sh 1111 001 1 1 . ...... .... 0000 . . . 1 .... @2reg_shr_h 266 + VSHR_U_2sh 1111 001 1 1 . ...... .... 0000 . . . 1 .... @2reg_shr_b 267 + 268 + VSRA_S_2sh 1111 001 0 1 . ...... .... 0001 . . . 1 .... @2reg_shr_d 269 + VSRA_S_2sh 1111 001 0 1 . ...... .... 0001 . . . 1 .... @2reg_shr_s 270 + VSRA_S_2sh 1111 001 0 1 . ...... .... 0001 . . . 1 .... @2reg_shr_h 271 + VSRA_S_2sh 1111 001 0 1 . ...... .... 0001 . . . 1 .... @2reg_shr_b 272 + 273 + VSRA_U_2sh 1111 001 1 1 . ...... .... 0001 . . . 1 .... @2reg_shr_d 274 + VSRA_U_2sh 1111 001 1 1 . ...... .... 0001 . . . 1 .... @2reg_shr_s 275 + VSRA_U_2sh 1111 001 1 1 . ...... .... 0001 . . . 1 .... @2reg_shr_h 276 + VSRA_U_2sh 1111 001 1 1 . ...... .... 0001 . . . 1 .... @2reg_shr_b 277 + 278 + VRSHR_S_2sh 1111 001 0 1 . ...... .... 0010 . . . 1 .... @2reg_shr_d 279 + VRSHR_S_2sh 1111 001 0 1 . ...... .... 0010 . . . 1 .... @2reg_shr_s 280 + VRSHR_S_2sh 1111 001 0 1 . ...... .... 0010 . . . 1 .... @2reg_shr_h 281 + VRSHR_S_2sh 1111 001 0 1 . ...... .... 0010 . . . 1 .... @2reg_shr_b 282 + 283 + VRSHR_U_2sh 1111 001 1 1 . ...... .... 0010 . . . 1 .... @2reg_shr_d 284 + VRSHR_U_2sh 1111 001 1 1 . ...... .... 0010 . . . 1 .... @2reg_shr_s 285 + VRSHR_U_2sh 1111 001 1 1 . ...... .... 0010 . . . 1 .... @2reg_shr_h 286 + VRSHR_U_2sh 1111 001 1 1 . ...... .... 0010 . . . 1 .... @2reg_shr_b 287 + 288 + VRSRA_S_2sh 1111 001 0 1 . ...... .... 0011 . . . 1 .... @2reg_shr_d 289 + VRSRA_S_2sh 1111 001 0 1 . ...... .... 0011 . . . 1 .... @2reg_shr_s 290 + VRSRA_S_2sh 1111 001 0 1 . ...... .... 0011 . . . 1 .... @2reg_shr_h 291 + VRSRA_S_2sh 1111 001 0 1 . ...... .... 0011 . . . 1 .... @2reg_shr_b 292 + 293 + VRSRA_U_2sh 1111 001 1 1 . ...... .... 0011 . . . 1 .... @2reg_shr_d 294 + VRSRA_U_2sh 1111 001 1 1 . ...... .... 0011 . . . 1 .... @2reg_shr_s 295 + VRSRA_U_2sh 1111 001 1 1 . ...... .... 0011 . . . 1 .... @2reg_shr_h 296 + VRSRA_U_2sh 1111 001 1 1 . ...... .... 0011 . . . 1 .... @2reg_shr_b 297 + 298 + VSRI_2sh 1111 001 1 1 . ...... .... 0100 . . . 1 .... @2reg_shr_d 299 + VSRI_2sh 1111 001 1 1 . ...... .... 0100 . . . 1 .... @2reg_shr_s 300 + VSRI_2sh 1111 001 1 1 . ...... .... 0100 . . . 1 .... @2reg_shr_h 301 + VSRI_2sh 1111 001 1 1 . ...... .... 0100 . . . 1 .... @2reg_shr_b 302 + 303 + VSHL_2sh 1111 001 0 1 . ...... .... 0101 . . . 1 .... @2reg_shl_d 304 + VSHL_2sh 1111 001 0 1 . ...... .... 0101 . . . 1 .... @2reg_shl_s 305 + VSHL_2sh 1111 001 0 1 . ...... .... 0101 . . . 1 .... @2reg_shl_h 306 + VSHL_2sh 1111 001 0 1 . ...... .... 0101 . . . 1 .... @2reg_shl_b 307 + 308 + VSLI_2sh 1111 001 1 1 . ...... .... 0101 . . . 1 .... @2reg_shl_d 309 + VSLI_2sh 1111 001 1 1 . ...... .... 0101 . . . 1 .... @2reg_shl_s 310 + VSLI_2sh 1111 001 1 1 . ...... .... 0101 . . . 1 .... @2reg_shl_h 311 + VSLI_2sh 1111 001 1 1 . ...... .... 0101 . . . 1 .... @2reg_shl_b 312 + 313 + VQSHLU_64_2sh 1111 001 1 1 . ...... .... 0110 . . . 1 .... @2reg_shl_d 314 + VQSHLU_2sh 1111 001 1 1 . ...... .... 0110 . . . 1 .... @2reg_shl_s 315 + VQSHLU_2sh 1111 001 1 1 . ...... .... 0110 . . . 1 .... @2reg_shl_h 316 + VQSHLU_2sh 1111 001 1 1 . ...... .... 0110 . . . 1 .... @2reg_shl_b 317 + 318 + VQSHL_S_64_2sh 1111 001 0 1 . ...... .... 0111 . . . 1 .... @2reg_shl_d 319 + VQSHL_S_2sh 1111 001 0 1 . ...... .... 0111 . . . 1 .... @2reg_shl_s 320 + VQSHL_S_2sh 1111 001 0 1 . ...... .... 0111 . . . 1 .... @2reg_shl_h 321 + VQSHL_S_2sh 1111 001 0 1 . ...... .... 0111 . . . 1 .... @2reg_shl_b 322 + 323 + VQSHL_U_64_2sh 1111 001 1 1 . ...... .... 0111 . . . 1 .... @2reg_shl_d 324 + VQSHL_U_2sh 1111 001 1 1 . ...... .... 0111 . . . 1 .... @2reg_shl_s 325 + VQSHL_U_2sh 1111 001 1 1 . ...... .... 0111 . . . 1 .... @2reg_shl_h 326 + VQSHL_U_2sh 1111 001 1 1 . ...... .... 0111 . . . 1 .... @2reg_shl_b 327 + 328 + VSHRN_64_2sh 1111 001 0 1 . ...... .... 1000 . 0 . 1 .... @2reg_shrn_d 329 + VSHRN_32_2sh 1111 001 0 1 . ...... .... 1000 . 0 . 1 .... @2reg_shrn_s 330 + VSHRN_16_2sh 1111 001 0 1 . ...... .... 1000 . 0 . 1 .... @2reg_shrn_h 331 + 332 + VRSHRN_64_2sh 1111 001 0 1 . ...... .... 1000 . 1 . 1 .... @2reg_shrn_d 333 + VRSHRN_32_2sh 1111 001 0 1 . ...... .... 1000 . 1 . 1 .... @2reg_shrn_s 334 + VRSHRN_16_2sh 1111 001 0 1 . ...... .... 1000 . 1 . 1 .... @2reg_shrn_h 335 + 336 + VQSHRUN_64_2sh 1111 001 1 1 . ...... .... 1000 . 0 . 1 .... @2reg_shrn_d 337 + VQSHRUN_32_2sh 1111 001 1 1 . ...... .... 1000 . 0 . 1 .... @2reg_shrn_s 338 + VQSHRUN_16_2sh 1111 001 1 1 . ...... .... 1000 . 0 . 1 .... @2reg_shrn_h 339 + 340 + VQRSHRUN_64_2sh 1111 001 1 1 . ...... .... 1000 . 1 . 1 .... @2reg_shrn_d 341 + VQRSHRUN_32_2sh 1111 001 1 1 . ...... .... 1000 . 1 . 1 .... @2reg_shrn_s 342 + VQRSHRUN_16_2sh 1111 001 1 1 . ...... .... 1000 . 1 . 1 .... @2reg_shrn_h 343 + 344 + # VQSHRN with signed input 345 + VQSHRN_S64_2sh 1111 001 0 1 . ...... .... 1001 . 0 . 1 .... @2reg_shrn_d 346 + VQSHRN_S32_2sh 1111 001 0 1 . ...... .... 1001 . 0 . 1 .... @2reg_shrn_s 347 + VQSHRN_S16_2sh 1111 001 0 1 . ...... .... 1001 . 0 . 1 .... @2reg_shrn_h 348 + 349 + # VQRSHRN with signed input 350 + VQRSHRN_S64_2sh 1111 001 0 1 . ...... .... 1001 . 1 . 1 .... @2reg_shrn_d 351 + VQRSHRN_S32_2sh 1111 001 0 1 . ...... .... 1001 . 1 . 1 .... @2reg_shrn_s 352 + VQRSHRN_S16_2sh 1111 001 0 1 . ...... .... 1001 . 1 . 1 .... @2reg_shrn_h 353 + 354 + # VQSHRN with unsigned input 355 + VQSHRN_U64_2sh 1111 001 1 1 . ...... .... 1001 . 0 . 1 .... @2reg_shrn_d 356 + VQSHRN_U32_2sh 1111 001 1 1 . ...... .... 1001 . 0 . 1 .... @2reg_shrn_s 357 + VQSHRN_U16_2sh 1111 001 1 1 . ...... .... 1001 . 0 . 1 .... @2reg_shrn_h 358 + 359 + # VQRSHRN with unsigned input 360 + VQRSHRN_U64_2sh 1111 001 1 1 . ...... .... 1001 . 1 . 1 .... @2reg_shrn_d 361 + VQRSHRN_U32_2sh 1111 001 1 1 . ...... .... 1001 . 1 . 1 .... @2reg_shrn_s 362 + VQRSHRN_U16_2sh 1111 001 1 1 . ...... .... 1001 . 1 . 1 .... @2reg_shrn_h 363 + 364 + VSHLL_S_2sh 1111 001 0 1 . ...... .... 1010 . 0 . 1 .... @2reg_shll_s 365 + VSHLL_S_2sh 1111 001 0 1 . ...... .... 1010 . 0 . 1 .... @2reg_shll_h 366 + VSHLL_S_2sh 1111 001 0 1 . ...... .... 1010 . 0 . 1 .... @2reg_shll_b 367 + 368 + VSHLL_U_2sh 1111 001 1 1 . ...... .... 1010 . 0 . 1 .... @2reg_shll_s 369 + VSHLL_U_2sh 1111 001 1 1 . ...... .... 1010 . 0 . 1 .... @2reg_shll_h 370 + VSHLL_U_2sh 1111 001 1 1 . ...... .... 1010 . 0 . 1 .... @2reg_shll_b 371 + 372 + # VCVT fixed<->float conversions 373 + # TODO: FP16 fixed<->float conversions are opc==0b1100 and 0b1101 374 + VCVT_SF_2sh 1111 001 0 1 . ...... .... 1110 0 . . 1 .... @2reg_vcvt 375 + VCVT_UF_2sh 1111 001 1 1 . ...... .... 1110 0 . . 1 .... @2reg_vcvt 376 + VCVT_FS_2sh 1111 001 0 1 . ...... .... 1111 0 . . 1 .... @2reg_vcvt 377 + VCVT_FU_2sh 1111 001 1 1 . ...... .... 1111 0 . . 1 .... @2reg_vcvt 378 + 379 + ###################################################################### 380 + # 1-reg-and-modified-immediate grouping: 381 + # 1111 001 i 1 D 000 imm:3 Vd:4 cmode:4 0 Q op 1 Vm:4 382 + ###################################################################### 383 + 384 + &1reg_imm vd q imm cmode op 385 + 386 + %asimd_imm_value 24:1 16:3 0:4 387 + 388 + @1reg_imm .... ... . . . ... ... .... .... . q:1 . . .... \ 389 + &1reg_imm imm=%asimd_imm_value vd=%vd_dp 390 + 391 + # The cmode/op bits here decode VORR/VBIC/VMOV/VMNV, but 392 + # not in a way we can conveniently represent in decodetree without 393 + # a lot of repetition: 394 + # VORR: op=0, (cmode & 1) && cmode < 12 395 + # VBIC: op=1, (cmode & 1) && cmode < 12 396 + # VMOV: everything else 397 + # So we have a single decode line and check the cmode/op in the 398 + # trans function. 399 + Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
+84 -114
target/arm/translate-a64.c
··· 571 571 is_q ? 16 : 8, vec_full_reg_size(s)); 572 572 } 573 573 574 + /* Expand a 2-operand operation using an out-of-line helper. */ 575 + static void gen_gvec_op2_ool(DisasContext *s, bool is_q, int rd, 576 + int rn, int data, gen_helper_gvec_2 *fn) 577 + { 578 + tcg_gen_gvec_2_ool(vec_full_reg_offset(s, rd), 579 + vec_full_reg_offset(s, rn), 580 + is_q ? 16 : 8, vec_full_reg_size(s), data, fn); 581 + } 582 + 574 583 /* Expand a 3-operand operation using an out-of-line helper. */ 575 584 static void gen_gvec_op3_ool(DisasContext *s, bool is_q, int rd, 576 585 int rn, int rm, int data, gen_helper_gvec_3 *fn) ··· 13403 13412 int rn = extract32(insn, 5, 5); 13404 13413 int rd = extract32(insn, 0, 5); 13405 13414 int decrypt; 13406 - TCGv_ptr tcg_rd_ptr, tcg_rn_ptr; 13407 - TCGv_i32 tcg_decrypt; 13408 - CryptoThreeOpIntFn *genfn; 13415 + gen_helper_gvec_2 *genfn2 = NULL; 13416 + gen_helper_gvec_3 *genfn3 = NULL; 13409 13417 13410 13418 if (!dc_isar_feature(aa64_aes, s) || size != 0) { 13411 13419 unallocated_encoding(s); ··· 13415 13423 switch (opcode) { 13416 13424 case 0x4: /* AESE */ 13417 13425 decrypt = 0; 13418 - genfn = gen_helper_crypto_aese; 13426 + genfn3 = gen_helper_crypto_aese; 13419 13427 break; 13420 13428 case 0x6: /* AESMC */ 13421 13429 decrypt = 0; 13422 - genfn = gen_helper_crypto_aesmc; 13430 + genfn2 = gen_helper_crypto_aesmc; 13423 13431 break; 13424 13432 case 0x5: /* AESD */ 13425 13433 decrypt = 1; 13426 - genfn = gen_helper_crypto_aese; 13434 + genfn3 = gen_helper_crypto_aese; 13427 13435 break; 13428 13436 case 0x7: /* AESIMC */ 13429 13437 decrypt = 1; 13430 - genfn = gen_helper_crypto_aesmc; 13438 + genfn2 = gen_helper_crypto_aesmc; 13431 13439 break; 13432 13440 default: 13433 13441 unallocated_encoding(s); ··· 13437 13445 if (!fp_access_check(s)) { 13438 13446 return; 13439 13447 } 13440 - 13441 - tcg_rd_ptr = vec_full_reg_ptr(s, rd); 13442 - tcg_rn_ptr = vec_full_reg_ptr(s, rn); 13443 - tcg_decrypt = tcg_const_i32(decrypt); 13444 - 13445 - genfn(tcg_rd_ptr, tcg_rn_ptr, tcg_decrypt); 13446 - 13447 - tcg_temp_free_ptr(tcg_rd_ptr); 13448 - tcg_temp_free_ptr(tcg_rn_ptr); 13449 - tcg_temp_free_i32(tcg_decrypt); 13448 + if (genfn2) { 13449 + gen_gvec_op2_ool(s, true, rd, rn, decrypt, genfn2); 13450 + } else { 13451 + gen_gvec_op3_ool(s, true, rd, rd, rn, decrypt, genfn3); 13452 + } 13450 13453 } 13451 13454 13452 13455 /* Crypto three-reg SHA ··· 13462 13465 int rm = extract32(insn, 16, 5); 13463 13466 int rn = extract32(insn, 5, 5); 13464 13467 int rd = extract32(insn, 0, 5); 13465 - CryptoThreeOpFn *genfn; 13466 - TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr; 13468 + gen_helper_gvec_3 *genfn; 13467 13469 bool feature; 13468 13470 13469 13471 if (size != 0) { ··· 13473 13475 13474 13476 switch (opcode) { 13475 13477 case 0: /* SHA1C */ 13478 + genfn = gen_helper_crypto_sha1c; 13479 + feature = dc_isar_feature(aa64_sha1, s); 13480 + break; 13476 13481 case 1: /* SHA1P */ 13482 + genfn = gen_helper_crypto_sha1p; 13483 + feature = dc_isar_feature(aa64_sha1, s); 13484 + break; 13477 13485 case 2: /* SHA1M */ 13486 + genfn = gen_helper_crypto_sha1m; 13487 + feature = dc_isar_feature(aa64_sha1, s); 13488 + break; 13478 13489 case 3: /* SHA1SU0 */ 13479 - genfn = NULL; 13490 + genfn = gen_helper_crypto_sha1su0; 13480 13491 feature = dc_isar_feature(aa64_sha1, s); 13481 13492 break; 13482 13493 case 4: /* SHA256H */ ··· 13504 13515 if (!fp_access_check(s)) { 13505 13516 return; 13506 13517 } 13507 - 13508 - tcg_rd_ptr = vec_full_reg_ptr(s, rd); 13509 - tcg_rn_ptr = vec_full_reg_ptr(s, rn); 13510 - tcg_rm_ptr = vec_full_reg_ptr(s, rm); 13511 - 13512 - if (genfn) { 13513 - genfn(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr); 13514 - } else { 13515 - TCGv_i32 tcg_opcode = tcg_const_i32(opcode); 13516 - 13517 - gen_helper_crypto_sha1_3reg(tcg_rd_ptr, tcg_rn_ptr, 13518 - tcg_rm_ptr, tcg_opcode); 13519 - tcg_temp_free_i32(tcg_opcode); 13520 - } 13521 - 13522 - tcg_temp_free_ptr(tcg_rd_ptr); 13523 - tcg_temp_free_ptr(tcg_rn_ptr); 13524 - tcg_temp_free_ptr(tcg_rm_ptr); 13518 + gen_gvec_op3_ool(s, true, rd, rn, rm, 0, genfn); 13525 13519 } 13526 13520 13527 13521 /* Crypto two-reg SHA ··· 13536 13530 int opcode = extract32(insn, 12, 5); 13537 13531 int rn = extract32(insn, 5, 5); 13538 13532 int rd = extract32(insn, 0, 5); 13539 - CryptoTwoOpFn *genfn; 13533 + gen_helper_gvec_2 *genfn; 13540 13534 bool feature; 13541 - TCGv_ptr tcg_rd_ptr, tcg_rn_ptr; 13542 13535 13543 13536 if (size != 0) { 13544 13537 unallocated_encoding(s); ··· 13571 13564 if (!fp_access_check(s)) { 13572 13565 return; 13573 13566 } 13567 + gen_gvec_op2_ool(s, true, rd, rn, 0, genfn); 13568 + } 13574 13569 13575 - tcg_rd_ptr = vec_full_reg_ptr(s, rd); 13576 - tcg_rn_ptr = vec_full_reg_ptr(s, rn); 13570 + static void gen_rax1_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m) 13571 + { 13572 + tcg_gen_rotli_i64(d, m, 1); 13573 + tcg_gen_xor_i64(d, d, n); 13574 + } 13577 13575 13578 - genfn(tcg_rd_ptr, tcg_rn_ptr); 13576 + static void gen_rax1_vec(unsigned vece, TCGv_vec d, TCGv_vec n, TCGv_vec m) 13577 + { 13578 + tcg_gen_rotli_vec(vece, d, m, 1); 13579 + tcg_gen_xor_vec(vece, d, d, n); 13580 + } 13579 13581 13580 - tcg_temp_free_ptr(tcg_rd_ptr); 13581 - tcg_temp_free_ptr(tcg_rn_ptr); 13582 + void gen_gvec_rax1(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, 13583 + uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz) 13584 + { 13585 + static const TCGOpcode vecop_list[] = { INDEX_op_rotli_vec, 0 }; 13586 + static const GVecGen3 op = { 13587 + .fni8 = gen_rax1_i64, 13588 + .fniv = gen_rax1_vec, 13589 + .opt_opc = vecop_list, 13590 + .fno = gen_helper_crypto_rax1, 13591 + .vece = MO_64, 13592 + }; 13593 + tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &op); 13582 13594 } 13583 13595 13584 13596 /* Crypto three-reg SHA512 ··· 13595 13607 int rn = extract32(insn, 5, 5); 13596 13608 int rd = extract32(insn, 0, 5); 13597 13609 bool feature; 13598 - CryptoThreeOpFn *genfn; 13610 + gen_helper_gvec_3 *oolfn = NULL; 13611 + GVecGen3Fn *gvecfn = NULL; 13599 13612 13600 13613 if (o == 0) { 13601 13614 switch (opcode) { 13602 13615 case 0: /* SHA512H */ 13603 13616 feature = dc_isar_feature(aa64_sha512, s); 13604 - genfn = gen_helper_crypto_sha512h; 13617 + oolfn = gen_helper_crypto_sha512h; 13605 13618 break; 13606 13619 case 1: /* SHA512H2 */ 13607 13620 feature = dc_isar_feature(aa64_sha512, s); 13608 - genfn = gen_helper_crypto_sha512h2; 13621 + oolfn = gen_helper_crypto_sha512h2; 13609 13622 break; 13610 13623 case 2: /* SHA512SU1 */ 13611 13624 feature = dc_isar_feature(aa64_sha512, s); 13612 - genfn = gen_helper_crypto_sha512su1; 13625 + oolfn = gen_helper_crypto_sha512su1; 13613 13626 break; 13614 13627 case 3: /* RAX1 */ 13615 13628 feature = dc_isar_feature(aa64_sha3, s); 13616 - genfn = NULL; 13629 + gvecfn = gen_gvec_rax1; 13617 13630 break; 13618 13631 default: 13619 13632 g_assert_not_reached(); ··· 13622 13635 switch (opcode) { 13623 13636 case 0: /* SM3PARTW1 */ 13624 13637 feature = dc_isar_feature(aa64_sm3, s); 13625 - genfn = gen_helper_crypto_sm3partw1; 13638 + oolfn = gen_helper_crypto_sm3partw1; 13626 13639 break; 13627 13640 case 1: /* SM3PARTW2 */ 13628 13641 feature = dc_isar_feature(aa64_sm3, s); 13629 - genfn = gen_helper_crypto_sm3partw2; 13642 + oolfn = gen_helper_crypto_sm3partw2; 13630 13643 break; 13631 13644 case 2: /* SM4EKEY */ 13632 13645 feature = dc_isar_feature(aa64_sm4, s); 13633 - genfn = gen_helper_crypto_sm4ekey; 13646 + oolfn = gen_helper_crypto_sm4ekey; 13634 13647 break; 13635 13648 default: 13636 13649 unallocated_encoding(s); ··· 13647 13660 return; 13648 13661 } 13649 13662 13650 - if (genfn) { 13651 - TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr; 13652 - 13653 - tcg_rd_ptr = vec_full_reg_ptr(s, rd); 13654 - tcg_rn_ptr = vec_full_reg_ptr(s, rn); 13655 - tcg_rm_ptr = vec_full_reg_ptr(s, rm); 13656 - 13657 - genfn(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr); 13658 - 13659 - tcg_temp_free_ptr(tcg_rd_ptr); 13660 - tcg_temp_free_ptr(tcg_rn_ptr); 13661 - tcg_temp_free_ptr(tcg_rm_ptr); 13663 + if (oolfn) { 13664 + gen_gvec_op3_ool(s, true, rd, rn, rm, 0, oolfn); 13662 13665 } else { 13663 - TCGv_i64 tcg_op1, tcg_op2, tcg_res[2]; 13664 - int pass; 13665 - 13666 - tcg_op1 = tcg_temp_new_i64(); 13667 - tcg_op2 = tcg_temp_new_i64(); 13668 - tcg_res[0] = tcg_temp_new_i64(); 13669 - tcg_res[1] = tcg_temp_new_i64(); 13670 - 13671 - for (pass = 0; pass < 2; pass++) { 13672 - read_vec_element(s, tcg_op1, rn, pass, MO_64); 13673 - read_vec_element(s, tcg_op2, rm, pass, MO_64); 13674 - 13675 - tcg_gen_rotli_i64(tcg_res[pass], tcg_op2, 1); 13676 - tcg_gen_xor_i64(tcg_res[pass], tcg_res[pass], tcg_op1); 13677 - } 13678 - write_vec_element(s, tcg_res[0], rd, 0, MO_64); 13679 - write_vec_element(s, tcg_res[1], rd, 1, MO_64); 13680 - 13681 - tcg_temp_free_i64(tcg_op1); 13682 - tcg_temp_free_i64(tcg_op2); 13683 - tcg_temp_free_i64(tcg_res[0]); 13684 - tcg_temp_free_i64(tcg_res[1]); 13666 + gen_gvec_fn3(s, true, rd, rn, rm, gvecfn, MO_64); 13685 13667 } 13686 13668 } 13687 13669 ··· 13696 13678 int opcode = extract32(insn, 10, 2); 13697 13679 int rn = extract32(insn, 5, 5); 13698 13680 int rd = extract32(insn, 0, 5); 13699 - TCGv_ptr tcg_rd_ptr, tcg_rn_ptr; 13700 13681 bool feature; 13701 - CryptoTwoOpFn *genfn; 13702 13682 13703 13683 switch (opcode) { 13704 13684 case 0: /* SHA512SU0 */ 13705 13685 feature = dc_isar_feature(aa64_sha512, s); 13706 - genfn = gen_helper_crypto_sha512su0; 13707 13686 break; 13708 13687 case 1: /* SM4E */ 13709 13688 feature = dc_isar_feature(aa64_sm4, s); 13710 - genfn = gen_helper_crypto_sm4e; 13711 13689 break; 13712 13690 default: 13713 13691 unallocated_encoding(s); ··· 13723 13701 return; 13724 13702 } 13725 13703 13726 - tcg_rd_ptr = vec_full_reg_ptr(s, rd); 13727 - tcg_rn_ptr = vec_full_reg_ptr(s, rn); 13728 - 13729 - genfn(tcg_rd_ptr, tcg_rn_ptr); 13730 - 13731 - tcg_temp_free_ptr(tcg_rd_ptr); 13732 - tcg_temp_free_ptr(tcg_rn_ptr); 13704 + switch (opcode) { 13705 + case 0: /* SHA512SU0 */ 13706 + gen_gvec_op2_ool(s, true, rd, rn, 0, gen_helper_crypto_sha512su0); 13707 + break; 13708 + case 1: /* SM4E */ 13709 + gen_gvec_op3_ool(s, true, rd, rd, rn, 0, gen_helper_crypto_sm4e); 13710 + break; 13711 + default: 13712 + g_assert_not_reached(); 13713 + } 13733 13714 } 13734 13715 13735 13716 /* Crypto four-register ··· 13885 13866 */ 13886 13867 static void disas_crypto_three_reg_imm2(DisasContext *s, uint32_t insn) 13887 13868 { 13869 + static gen_helper_gvec_3 * const fns[4] = { 13870 + gen_helper_crypto_sm3tt1a, gen_helper_crypto_sm3tt1b, 13871 + gen_helper_crypto_sm3tt2a, gen_helper_crypto_sm3tt2b, 13872 + }; 13888 13873 int opcode = extract32(insn, 10, 2); 13889 13874 int imm2 = extract32(insn, 12, 2); 13890 13875 int rm = extract32(insn, 16, 5); 13891 13876 int rn = extract32(insn, 5, 5); 13892 13877 int rd = extract32(insn, 0, 5); 13893 - TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr; 13894 - TCGv_i32 tcg_imm2, tcg_opcode; 13895 13878 13896 13879 if (!dc_isar_feature(aa64_sm3, s)) { 13897 13880 unallocated_encoding(s); ··· 13902 13885 return; 13903 13886 } 13904 13887 13905 - tcg_rd_ptr = vec_full_reg_ptr(s, rd); 13906 - tcg_rn_ptr = vec_full_reg_ptr(s, rn); 13907 - tcg_rm_ptr = vec_full_reg_ptr(s, rm); 13908 - tcg_imm2 = tcg_const_i32(imm2); 13909 - tcg_opcode = tcg_const_i32(opcode); 13910 - 13911 - gen_helper_crypto_sm3tt(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr, tcg_imm2, 13912 - tcg_opcode); 13913 - 13914 - tcg_temp_free_ptr(tcg_rd_ptr); 13915 - tcg_temp_free_ptr(tcg_rn_ptr); 13916 - tcg_temp_free_ptr(tcg_rm_ptr); 13917 - tcg_temp_free_i32(tcg_imm2); 13918 - tcg_temp_free_i32(tcg_opcode); 13888 + gen_gvec_op3_ool(s, true, rd, rn, rm, imm2, fns[opcode]); 13919 13889 } 13920 13890 13921 13891 /* C3.6 Data processing - SIMD, inc Crypto
+3
target/arm/translate-a64.h
··· 115 115 116 116 bool disas_sve(DisasContext *, uint32_t); 117 117 118 + void gen_gvec_rax1(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, 119 + uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz); 120 + 118 121 #endif /* TARGET_ARM_TRANSLATE_A64_H */
+655 -139
target/arm/translate-neon.inc.c
··· 31 31 return x + 1; 32 32 } 33 33 34 + static inline int rsub_64(DisasContext *s, int x) 35 + { 36 + return 64 - x; 37 + } 38 + 39 + static inline int rsub_32(DisasContext *s, int x) 40 + { 41 + return 32 - x; 42 + } 43 + static inline int rsub_16(DisasContext *s, int x) 44 + { 45 + return 16 - x; 46 + } 47 + static inline int rsub_8(DisasContext *s, int x) 48 + { 49 + return 8 - x; 50 + } 51 + 34 52 /* Include the generated Neon decoder */ 35 53 #include "decode-neon-dp.inc.c" 36 54 #include "decode-neon-ls.inc.c" ··· 661 679 DO_3SAME_CMP(VCGE_U, TCG_COND_GEU) 662 680 DO_3SAME_CMP(VCEQ, TCG_COND_EQ) 663 681 664 - static void gen_VMUL_p_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, 665 - uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz) 666 - { 667 - tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, 668 - 0, gen_helper_gvec_pmul_b); 669 - } 682 + #define WRAP_OOL_FN(WRAPNAME, FUNC) \ 683 + static void WRAPNAME(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, \ 684 + uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz) \ 685 + { \ 686 + tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, 0, FUNC); \ 687 + } 688 + 689 + WRAP_OOL_FN(gen_VMUL_p_3s, gen_helper_gvec_pmul_b) 670 690 671 691 static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a) 672 692 { ··· 691 711 DO_VQRDMLAH(VQRDMLAH, gen_gvec_sqrdmlah_qc) 692 712 DO_VQRDMLAH(VQRDMLSH, gen_gvec_sqrdmlsh_qc) 693 713 694 - static bool trans_SHA1_3s(DisasContext *s, arg_SHA1_3s *a) 695 - { 696 - TCGv_ptr ptr1, ptr2, ptr3; 697 - TCGv_i32 tmp; 698 - 699 - if (!arm_dc_feature(s, ARM_FEATURE_NEON) || 700 - !dc_isar_feature(aa32_sha1, s)) { 701 - return false; 702 - } 703 - 704 - /* UNDEF accesses to D16-D31 if they don't exist. */ 705 - if (!dc_isar_feature(aa32_simd_r32, s) && 706 - ((a->vd | a->vn | a->vm) & 0x10)) { 707 - return false; 714 + #define DO_SHA1(NAME, FUNC) \ 715 + WRAP_OOL_FN(gen_##NAME##_3s, FUNC) \ 716 + static bool trans_##NAME##_3s(DisasContext *s, arg_3same *a) \ 717 + { \ 718 + if (!dc_isar_feature(aa32_sha1, s)) { \ 719 + return false; \ 720 + } \ 721 + return do_3same(s, a, gen_##NAME##_3s); \ 708 722 } 709 723 710 - if ((a->vn | a->vm | a->vd) & 1) { 711 - return false; 712 - } 724 + DO_SHA1(SHA1C, gen_helper_crypto_sha1c) 725 + DO_SHA1(SHA1P, gen_helper_crypto_sha1p) 726 + DO_SHA1(SHA1M, gen_helper_crypto_sha1m) 727 + DO_SHA1(SHA1SU0, gen_helper_crypto_sha1su0) 713 728 714 - if (!vfp_access_check(s)) { 715 - return true; 729 + #define DO_SHA2(NAME, FUNC) \ 730 + WRAP_OOL_FN(gen_##NAME##_3s, FUNC) \ 731 + static bool trans_##NAME##_3s(DisasContext *s, arg_3same *a) \ 732 + { \ 733 + if (!dc_isar_feature(aa32_sha2, s)) { \ 734 + return false; \ 735 + } \ 736 + return do_3same(s, a, gen_##NAME##_3s); \ 716 737 } 717 738 718 - ptr1 = vfp_reg_ptr(true, a->vd); 719 - ptr2 = vfp_reg_ptr(true, a->vn); 720 - ptr3 = vfp_reg_ptr(true, a->vm); 721 - tmp = tcg_const_i32(a->optype); 722 - gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp); 723 - tcg_temp_free_i32(tmp); 724 - tcg_temp_free_ptr(ptr1); 725 - tcg_temp_free_ptr(ptr2); 726 - tcg_temp_free_ptr(ptr3); 727 - 728 - return true; 729 - } 730 - 731 - static bool trans_SHA256H_3s(DisasContext *s, arg_SHA256H_3s *a) 732 - { 733 - TCGv_ptr ptr1, ptr2, ptr3; 734 - 735 - if (!arm_dc_feature(s, ARM_FEATURE_NEON) || 736 - !dc_isar_feature(aa32_sha2, s)) { 737 - return false; 738 - } 739 - 740 - /* UNDEF accesses to D16-D31 if they don't exist. */ 741 - if (!dc_isar_feature(aa32_simd_r32, s) && 742 - ((a->vd | a->vn | a->vm) & 0x10)) { 743 - return false; 744 - } 745 - 746 - if ((a->vn | a->vm | a->vd) & 1) { 747 - return false; 748 - } 749 - 750 - if (!vfp_access_check(s)) { 751 - return true; 752 - } 753 - 754 - ptr1 = vfp_reg_ptr(true, a->vd); 755 - ptr2 = vfp_reg_ptr(true, a->vn); 756 - ptr3 = vfp_reg_ptr(true, a->vm); 757 - gen_helper_crypto_sha256h(ptr1, ptr2, ptr3); 758 - tcg_temp_free_ptr(ptr1); 759 - tcg_temp_free_ptr(ptr2); 760 - tcg_temp_free_ptr(ptr3); 761 - 762 - return true; 763 - } 764 - 765 - static bool trans_SHA256H2_3s(DisasContext *s, arg_SHA256H2_3s *a) 766 - { 767 - TCGv_ptr ptr1, ptr2, ptr3; 768 - 769 - if (!arm_dc_feature(s, ARM_FEATURE_NEON) || 770 - !dc_isar_feature(aa32_sha2, s)) { 771 - return false; 772 - } 773 - 774 - /* UNDEF accesses to D16-D31 if they don't exist. */ 775 - if (!dc_isar_feature(aa32_simd_r32, s) && 776 - ((a->vd | a->vn | a->vm) & 0x10)) { 777 - return false; 778 - } 779 - 780 - if ((a->vn | a->vm | a->vd) & 1) { 781 - return false; 782 - } 783 - 784 - if (!vfp_access_check(s)) { 785 - return true; 786 - } 787 - 788 - ptr1 = vfp_reg_ptr(true, a->vd); 789 - ptr2 = vfp_reg_ptr(true, a->vn); 790 - ptr3 = vfp_reg_ptr(true, a->vm); 791 - gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3); 792 - tcg_temp_free_ptr(ptr1); 793 - tcg_temp_free_ptr(ptr2); 794 - tcg_temp_free_ptr(ptr3); 795 - 796 - return true; 797 - } 798 - 799 - static bool trans_SHA256SU1_3s(DisasContext *s, arg_SHA256SU1_3s *a) 800 - { 801 - TCGv_ptr ptr1, ptr2, ptr3; 802 - 803 - if (!arm_dc_feature(s, ARM_FEATURE_NEON) || 804 - !dc_isar_feature(aa32_sha2, s)) { 805 - return false; 806 - } 807 - 808 - /* UNDEF accesses to D16-D31 if they don't exist. */ 809 - if (!dc_isar_feature(aa32_simd_r32, s) && 810 - ((a->vd | a->vn | a->vm) & 0x10)) { 811 - return false; 812 - } 813 - 814 - if ((a->vn | a->vm | a->vd) & 1) { 815 - return false; 816 - } 817 - 818 - if (!vfp_access_check(s)) { 819 - return true; 820 - } 821 - 822 - ptr1 = vfp_reg_ptr(true, a->vd); 823 - ptr2 = vfp_reg_ptr(true, a->vn); 824 - ptr3 = vfp_reg_ptr(true, a->vm); 825 - gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3); 826 - tcg_temp_free_ptr(ptr1); 827 - tcg_temp_free_ptr(ptr2); 828 - tcg_temp_free_ptr(ptr3); 829 - 830 - return true; 831 - } 739 + DO_SHA2(SHA256H, gen_helper_crypto_sha256h) 740 + DO_SHA2(SHA256H2, gen_helper_crypto_sha256h2) 741 + DO_SHA2(SHA256SU1, gen_helper_crypto_sha256su1) 832 742 833 743 #define DO_3SAME_64(INSN, FUNC) \ 834 744 static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \ ··· 1310 1220 DO_3S_FP_PAIR(VPADD, gen_helper_vfp_adds) 1311 1221 DO_3S_FP_PAIR(VPMAX, gen_helper_vfp_maxs) 1312 1222 DO_3S_FP_PAIR(VPMIN, gen_helper_vfp_mins) 1223 + 1224 + static bool do_vector_2sh(DisasContext *s, arg_2reg_shift *a, GVecGen2iFn *fn) 1225 + { 1226 + /* Handle a 2-reg-shift insn which can be vectorized. */ 1227 + int vec_size = a->q ? 16 : 8; 1228 + int rd_ofs = neon_reg_offset(a->vd, 0); 1229 + int rm_ofs = neon_reg_offset(a->vm, 0); 1230 + 1231 + if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { 1232 + return false; 1233 + } 1234 + 1235 + /* UNDEF accesses to D16-D31 if they don't exist. */ 1236 + if (!dc_isar_feature(aa32_simd_r32, s) && 1237 + ((a->vd | a->vm) & 0x10)) { 1238 + return false; 1239 + } 1240 + 1241 + if ((a->vm | a->vd) & a->q) { 1242 + return false; 1243 + } 1244 + 1245 + if (!vfp_access_check(s)) { 1246 + return true; 1247 + } 1248 + 1249 + fn(a->size, rd_ofs, rm_ofs, a->shift, vec_size, vec_size); 1250 + return true; 1251 + } 1252 + 1253 + #define DO_2SH(INSN, FUNC) \ 1254 + static bool trans_##INSN##_2sh(DisasContext *s, arg_2reg_shift *a) \ 1255 + { \ 1256 + return do_vector_2sh(s, a, FUNC); \ 1257 + } \ 1258 + 1259 + DO_2SH(VSHL, tcg_gen_gvec_shli) 1260 + DO_2SH(VSLI, gen_gvec_sli) 1261 + DO_2SH(VSRI, gen_gvec_sri) 1262 + DO_2SH(VSRA_S, gen_gvec_ssra) 1263 + DO_2SH(VSRA_U, gen_gvec_usra) 1264 + DO_2SH(VRSHR_S, gen_gvec_srshr) 1265 + DO_2SH(VRSHR_U, gen_gvec_urshr) 1266 + DO_2SH(VRSRA_S, gen_gvec_srsra) 1267 + DO_2SH(VRSRA_U, gen_gvec_ursra) 1268 + 1269 + static bool trans_VSHR_S_2sh(DisasContext *s, arg_2reg_shift *a) 1270 + { 1271 + /* Signed shift out of range results in all-sign-bits */ 1272 + a->shift = MIN(a->shift, (8 << a->size) - 1); 1273 + return do_vector_2sh(s, a, tcg_gen_gvec_sari); 1274 + } 1275 + 1276 + static void gen_zero_rd_2sh(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs, 1277 + int64_t shift, uint32_t oprsz, uint32_t maxsz) 1278 + { 1279 + tcg_gen_gvec_dup_imm(vece, rd_ofs, oprsz, maxsz, 0); 1280 + } 1281 + 1282 + static bool trans_VSHR_U_2sh(DisasContext *s, arg_2reg_shift *a) 1283 + { 1284 + /* Shift out of range is architecturally valid and results in zero. */ 1285 + if (a->shift >= (8 << a->size)) { 1286 + return do_vector_2sh(s, a, gen_zero_rd_2sh); 1287 + } else { 1288 + return do_vector_2sh(s, a, tcg_gen_gvec_shri); 1289 + } 1290 + } 1291 + 1292 + static bool do_2shift_env_64(DisasContext *s, arg_2reg_shift *a, 1293 + NeonGenTwo64OpEnvFn *fn) 1294 + { 1295 + /* 1296 + * 2-reg-and-shift operations, size == 3 case, where the 1297 + * function needs to be passed cpu_env. 1298 + */ 1299 + TCGv_i64 constimm; 1300 + int pass; 1301 + 1302 + if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { 1303 + return false; 1304 + } 1305 + 1306 + /* UNDEF accesses to D16-D31 if they don't exist. */ 1307 + if (!dc_isar_feature(aa32_simd_r32, s) && 1308 + ((a->vd | a->vm) & 0x10)) { 1309 + return false; 1310 + } 1311 + 1312 + if ((a->vm | a->vd) & a->q) { 1313 + return false; 1314 + } 1315 + 1316 + if (!vfp_access_check(s)) { 1317 + return true; 1318 + } 1319 + 1320 + /* 1321 + * To avoid excessive duplication of ops we implement shift 1322 + * by immediate using the variable shift operations. 1323 + */ 1324 + constimm = tcg_const_i64(dup_const(a->size, a->shift)); 1325 + 1326 + for (pass = 0; pass < a->q + 1; pass++) { 1327 + TCGv_i64 tmp = tcg_temp_new_i64(); 1328 + 1329 + neon_load_reg64(tmp, a->vm + pass); 1330 + fn(tmp, cpu_env, tmp, constimm); 1331 + neon_store_reg64(tmp, a->vd + pass); 1332 + } 1333 + tcg_temp_free_i64(constimm); 1334 + return true; 1335 + } 1336 + 1337 + static bool do_2shift_env_32(DisasContext *s, arg_2reg_shift *a, 1338 + NeonGenTwoOpEnvFn *fn) 1339 + { 1340 + /* 1341 + * 2-reg-and-shift operations, size < 3 case, where the 1342 + * helper needs to be passed cpu_env. 1343 + */ 1344 + TCGv_i32 constimm; 1345 + int pass; 1346 + 1347 + if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { 1348 + return false; 1349 + } 1350 + 1351 + /* UNDEF accesses to D16-D31 if they don't exist. */ 1352 + if (!dc_isar_feature(aa32_simd_r32, s) && 1353 + ((a->vd | a->vm) & 0x10)) { 1354 + return false; 1355 + } 1356 + 1357 + if ((a->vm | a->vd) & a->q) { 1358 + return false; 1359 + } 1360 + 1361 + if (!vfp_access_check(s)) { 1362 + return true; 1363 + } 1364 + 1365 + /* 1366 + * To avoid excessive duplication of ops we implement shift 1367 + * by immediate using the variable shift operations. 1368 + */ 1369 + constimm = tcg_const_i32(dup_const(a->size, a->shift)); 1370 + 1371 + for (pass = 0; pass < (a->q ? 4 : 2); pass++) { 1372 + TCGv_i32 tmp = neon_load_reg(a->vm, pass); 1373 + fn(tmp, cpu_env, tmp, constimm); 1374 + neon_store_reg(a->vd, pass, tmp); 1375 + } 1376 + tcg_temp_free_i32(constimm); 1377 + return true; 1378 + } 1379 + 1380 + #define DO_2SHIFT_ENV(INSN, FUNC) \ 1381 + static bool trans_##INSN##_64_2sh(DisasContext *s, arg_2reg_shift *a) \ 1382 + { \ 1383 + return do_2shift_env_64(s, a, gen_helper_neon_##FUNC##64); \ 1384 + } \ 1385 + static bool trans_##INSN##_2sh(DisasContext *s, arg_2reg_shift *a) \ 1386 + { \ 1387 + static NeonGenTwoOpEnvFn * const fns[] = { \ 1388 + gen_helper_neon_##FUNC##8, \ 1389 + gen_helper_neon_##FUNC##16, \ 1390 + gen_helper_neon_##FUNC##32, \ 1391 + }; \ 1392 + assert(a->size < ARRAY_SIZE(fns)); \ 1393 + return do_2shift_env_32(s, a, fns[a->size]); \ 1394 + } 1395 + 1396 + DO_2SHIFT_ENV(VQSHLU, qshlu_s) 1397 + DO_2SHIFT_ENV(VQSHL_U, qshl_u) 1398 + DO_2SHIFT_ENV(VQSHL_S, qshl_s) 1399 + 1400 + static bool do_2shift_narrow_64(DisasContext *s, arg_2reg_shift *a, 1401 + NeonGenTwo64OpFn *shiftfn, 1402 + NeonGenNarrowEnvFn *narrowfn) 1403 + { 1404 + /* 2-reg-and-shift narrowing-shift operations, size == 3 case */ 1405 + TCGv_i64 constimm, rm1, rm2; 1406 + TCGv_i32 rd; 1407 + 1408 + if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { 1409 + return false; 1410 + } 1411 + 1412 + /* UNDEF accesses to D16-D31 if they don't exist. */ 1413 + if (!dc_isar_feature(aa32_simd_r32, s) && 1414 + ((a->vd | a->vm) & 0x10)) { 1415 + return false; 1416 + } 1417 + 1418 + if (a->vm & 1) { 1419 + return false; 1420 + } 1421 + 1422 + if (!vfp_access_check(s)) { 1423 + return true; 1424 + } 1425 + 1426 + /* 1427 + * This is always a right shift, and the shiftfn is always a 1428 + * left-shift helper, which thus needs the negated shift count. 1429 + */ 1430 + constimm = tcg_const_i64(-a->shift); 1431 + rm1 = tcg_temp_new_i64(); 1432 + rm2 = tcg_temp_new_i64(); 1433 + 1434 + /* Load both inputs first to avoid potential overwrite if rm == rd */ 1435 + neon_load_reg64(rm1, a->vm); 1436 + neon_load_reg64(rm2, a->vm + 1); 1437 + 1438 + shiftfn(rm1, rm1, constimm); 1439 + rd = tcg_temp_new_i32(); 1440 + narrowfn(rd, cpu_env, rm1); 1441 + neon_store_reg(a->vd, 0, rd); 1442 + 1443 + shiftfn(rm2, rm2, constimm); 1444 + rd = tcg_temp_new_i32(); 1445 + narrowfn(rd, cpu_env, rm2); 1446 + neon_store_reg(a->vd, 1, rd); 1447 + 1448 + tcg_temp_free_i64(rm1); 1449 + tcg_temp_free_i64(rm2); 1450 + tcg_temp_free_i64(constimm); 1451 + 1452 + return true; 1453 + } 1454 + 1455 + static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a, 1456 + NeonGenTwoOpFn *shiftfn, 1457 + NeonGenNarrowEnvFn *narrowfn) 1458 + { 1459 + /* 2-reg-and-shift narrowing-shift operations, size < 3 case */ 1460 + TCGv_i32 constimm, rm1, rm2, rm3, rm4; 1461 + TCGv_i64 rtmp; 1462 + uint32_t imm; 1463 + 1464 + if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { 1465 + return false; 1466 + } 1467 + 1468 + /* UNDEF accesses to D16-D31 if they don't exist. */ 1469 + if (!dc_isar_feature(aa32_simd_r32, s) && 1470 + ((a->vd | a->vm) & 0x10)) { 1471 + return false; 1472 + } 1473 + 1474 + if (a->vm & 1) { 1475 + return false; 1476 + } 1477 + 1478 + if (!vfp_access_check(s)) { 1479 + return true; 1480 + } 1481 + 1482 + /* 1483 + * This is always a right shift, and the shiftfn is always a 1484 + * left-shift helper, which thus needs the negated shift count 1485 + * duplicated into each lane of the immediate value. 1486 + */ 1487 + if (a->size == 1) { 1488 + imm = (uint16_t)(-a->shift); 1489 + imm |= imm << 16; 1490 + } else { 1491 + /* size == 2 */ 1492 + imm = -a->shift; 1493 + } 1494 + constimm = tcg_const_i32(imm); 1495 + 1496 + /* Load all inputs first to avoid potential overwrite */ 1497 + rm1 = neon_load_reg(a->vm, 0); 1498 + rm2 = neon_load_reg(a->vm, 1); 1499 + rm3 = neon_load_reg(a->vm + 1, 0); 1500 + rm4 = neon_load_reg(a->vm + 1, 1); 1501 + rtmp = tcg_temp_new_i64(); 1502 + 1503 + shiftfn(rm1, rm1, constimm); 1504 + shiftfn(rm2, rm2, constimm); 1505 + 1506 + tcg_gen_concat_i32_i64(rtmp, rm1, rm2); 1507 + tcg_temp_free_i32(rm2); 1508 + 1509 + narrowfn(rm1, cpu_env, rtmp); 1510 + neon_store_reg(a->vd, 0, rm1); 1511 + 1512 + shiftfn(rm3, rm3, constimm); 1513 + shiftfn(rm4, rm4, constimm); 1514 + tcg_temp_free_i32(constimm); 1515 + 1516 + tcg_gen_concat_i32_i64(rtmp, rm3, rm4); 1517 + tcg_temp_free_i32(rm4); 1518 + 1519 + narrowfn(rm3, cpu_env, rtmp); 1520 + tcg_temp_free_i64(rtmp); 1521 + neon_store_reg(a->vd, 1, rm3); 1522 + return true; 1523 + } 1524 + 1525 + #define DO_2SN_64(INSN, FUNC, NARROWFUNC) \ 1526 + static bool trans_##INSN##_2sh(DisasContext *s, arg_2reg_shift *a) \ 1527 + { \ 1528 + return do_2shift_narrow_64(s, a, FUNC, NARROWFUNC); \ 1529 + } 1530 + #define DO_2SN_32(INSN, FUNC, NARROWFUNC) \ 1531 + static bool trans_##INSN##_2sh(DisasContext *s, arg_2reg_shift *a) \ 1532 + { \ 1533 + return do_2shift_narrow_32(s, a, FUNC, NARROWFUNC); \ 1534 + } 1535 + 1536 + static void gen_neon_narrow_u32(TCGv_i32 dest, TCGv_ptr env, TCGv_i64 src) 1537 + { 1538 + tcg_gen_extrl_i64_i32(dest, src); 1539 + } 1540 + 1541 + static void gen_neon_narrow_u16(TCGv_i32 dest, TCGv_ptr env, TCGv_i64 src) 1542 + { 1543 + gen_helper_neon_narrow_u16(dest, src); 1544 + } 1545 + 1546 + static void gen_neon_narrow_u8(TCGv_i32 dest, TCGv_ptr env, TCGv_i64 src) 1547 + { 1548 + gen_helper_neon_narrow_u8(dest, src); 1549 + } 1550 + 1551 + DO_2SN_64(VSHRN_64, gen_ushl_i64, gen_neon_narrow_u32) 1552 + DO_2SN_32(VSHRN_32, gen_ushl_i32, gen_neon_narrow_u16) 1553 + DO_2SN_32(VSHRN_16, gen_helper_neon_shl_u16, gen_neon_narrow_u8) 1554 + 1555 + DO_2SN_64(VRSHRN_64, gen_helper_neon_rshl_u64, gen_neon_narrow_u32) 1556 + DO_2SN_32(VRSHRN_32, gen_helper_neon_rshl_u32, gen_neon_narrow_u16) 1557 + DO_2SN_32(VRSHRN_16, gen_helper_neon_rshl_u16, gen_neon_narrow_u8) 1558 + 1559 + DO_2SN_64(VQSHRUN_64, gen_sshl_i64, gen_helper_neon_unarrow_sat32) 1560 + DO_2SN_32(VQSHRUN_32, gen_sshl_i32, gen_helper_neon_unarrow_sat16) 1561 + DO_2SN_32(VQSHRUN_16, gen_helper_neon_shl_s16, gen_helper_neon_unarrow_sat8) 1562 + 1563 + DO_2SN_64(VQRSHRUN_64, gen_helper_neon_rshl_s64, gen_helper_neon_unarrow_sat32) 1564 + DO_2SN_32(VQRSHRUN_32, gen_helper_neon_rshl_s32, gen_helper_neon_unarrow_sat16) 1565 + DO_2SN_32(VQRSHRUN_16, gen_helper_neon_rshl_s16, gen_helper_neon_unarrow_sat8) 1566 + DO_2SN_64(VQSHRN_S64, gen_sshl_i64, gen_helper_neon_narrow_sat_s32) 1567 + DO_2SN_32(VQSHRN_S32, gen_sshl_i32, gen_helper_neon_narrow_sat_s16) 1568 + DO_2SN_32(VQSHRN_S16, gen_helper_neon_shl_s16, gen_helper_neon_narrow_sat_s8) 1569 + 1570 + DO_2SN_64(VQRSHRN_S64, gen_helper_neon_rshl_s64, gen_helper_neon_narrow_sat_s32) 1571 + DO_2SN_32(VQRSHRN_S32, gen_helper_neon_rshl_s32, gen_helper_neon_narrow_sat_s16) 1572 + DO_2SN_32(VQRSHRN_S16, gen_helper_neon_rshl_s16, gen_helper_neon_narrow_sat_s8) 1573 + 1574 + DO_2SN_64(VQSHRN_U64, gen_ushl_i64, gen_helper_neon_narrow_sat_u32) 1575 + DO_2SN_32(VQSHRN_U32, gen_ushl_i32, gen_helper_neon_narrow_sat_u16) 1576 + DO_2SN_32(VQSHRN_U16, gen_helper_neon_shl_u16, gen_helper_neon_narrow_sat_u8) 1577 + 1578 + DO_2SN_64(VQRSHRN_U64, gen_helper_neon_rshl_u64, gen_helper_neon_narrow_sat_u32) 1579 + DO_2SN_32(VQRSHRN_U32, gen_helper_neon_rshl_u32, gen_helper_neon_narrow_sat_u16) 1580 + DO_2SN_32(VQRSHRN_U16, gen_helper_neon_rshl_u16, gen_helper_neon_narrow_sat_u8) 1581 + 1582 + static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a, 1583 + NeonGenWidenFn *widenfn, bool u) 1584 + { 1585 + TCGv_i64 tmp; 1586 + TCGv_i32 rm0, rm1; 1587 + uint64_t widen_mask = 0; 1588 + 1589 + if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { 1590 + return false; 1591 + } 1592 + 1593 + /* UNDEF accesses to D16-D31 if they don't exist. */ 1594 + if (!dc_isar_feature(aa32_simd_r32, s) && 1595 + ((a->vd | a->vm) & 0x10)) { 1596 + return false; 1597 + } 1598 + 1599 + if (a->vd & 1) { 1600 + return false; 1601 + } 1602 + 1603 + if (!vfp_access_check(s)) { 1604 + return true; 1605 + } 1606 + 1607 + /* 1608 + * This is a widen-and-shift operation. The shift is always less 1609 + * than the width of the source type, so after widening the input 1610 + * vector we can simply shift the whole 64-bit widened register, 1611 + * and then clear the potential overflow bits resulting from left 1612 + * bits of the narrow input appearing as right bits of the left 1613 + * neighbour narrow input. Calculate a mask of bits to clear. 1614 + */ 1615 + if ((a->shift != 0) && (a->size < 2 || u)) { 1616 + int esize = 8 << a->size; 1617 + widen_mask = MAKE_64BIT_MASK(0, esize); 1618 + widen_mask >>= esize - a->shift; 1619 + widen_mask = dup_const(a->size + 1, widen_mask); 1620 + } 1621 + 1622 + rm0 = neon_load_reg(a->vm, 0); 1623 + rm1 = neon_load_reg(a->vm, 1); 1624 + tmp = tcg_temp_new_i64(); 1625 + 1626 + widenfn(tmp, rm0); 1627 + if (a->shift != 0) { 1628 + tcg_gen_shli_i64(tmp, tmp, a->shift); 1629 + tcg_gen_andi_i64(tmp, tmp, ~widen_mask); 1630 + } 1631 + neon_store_reg64(tmp, a->vd); 1632 + 1633 + widenfn(tmp, rm1); 1634 + if (a->shift != 0) { 1635 + tcg_gen_shli_i64(tmp, tmp, a->shift); 1636 + tcg_gen_andi_i64(tmp, tmp, ~widen_mask); 1637 + } 1638 + neon_store_reg64(tmp, a->vd + 1); 1639 + tcg_temp_free_i64(tmp); 1640 + return true; 1641 + } 1642 + 1643 + static bool trans_VSHLL_S_2sh(DisasContext *s, arg_2reg_shift *a) 1644 + { 1645 + NeonGenWidenFn *widenfn[] = { 1646 + gen_helper_neon_widen_s8, 1647 + gen_helper_neon_widen_s16, 1648 + tcg_gen_ext_i32_i64, 1649 + }; 1650 + return do_vshll_2sh(s, a, widenfn[a->size], false); 1651 + } 1652 + 1653 + static bool trans_VSHLL_U_2sh(DisasContext *s, arg_2reg_shift *a) 1654 + { 1655 + NeonGenWidenFn *widenfn[] = { 1656 + gen_helper_neon_widen_u8, 1657 + gen_helper_neon_widen_u16, 1658 + tcg_gen_extu_i32_i64, 1659 + }; 1660 + return do_vshll_2sh(s, a, widenfn[a->size], true); 1661 + } 1662 + 1663 + static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a, 1664 + NeonGenTwoSingleOPFn *fn) 1665 + { 1666 + /* FP operations in 2-reg-and-shift group */ 1667 + TCGv_i32 tmp, shiftv; 1668 + TCGv_ptr fpstatus; 1669 + int pass; 1670 + 1671 + if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { 1672 + return false; 1673 + } 1674 + 1675 + /* UNDEF accesses to D16-D31 if they don't exist. */ 1676 + if (!dc_isar_feature(aa32_simd_r32, s) && 1677 + ((a->vd | a->vm) & 0x10)) { 1678 + return false; 1679 + } 1680 + 1681 + if ((a->vm | a->vd) & a->q) { 1682 + return false; 1683 + } 1684 + 1685 + if (!vfp_access_check(s)) { 1686 + return true; 1687 + } 1688 + 1689 + fpstatus = get_fpstatus_ptr(1); 1690 + shiftv = tcg_const_i32(a->shift); 1691 + for (pass = 0; pass < (a->q ? 4 : 2); pass++) { 1692 + tmp = neon_load_reg(a->vm, pass); 1693 + fn(tmp, tmp, shiftv, fpstatus); 1694 + neon_store_reg(a->vd, pass, tmp); 1695 + } 1696 + tcg_temp_free_ptr(fpstatus); 1697 + tcg_temp_free_i32(shiftv); 1698 + return true; 1699 + } 1700 + 1701 + #define DO_FP_2SH(INSN, FUNC) \ 1702 + static bool trans_##INSN##_2sh(DisasContext *s, arg_2reg_shift *a) \ 1703 + { \ 1704 + return do_fp_2sh(s, a, FUNC); \ 1705 + } 1706 + 1707 + DO_FP_2SH(VCVT_SF, gen_helper_vfp_sltos) 1708 + DO_FP_2SH(VCVT_UF, gen_helper_vfp_ultos) 1709 + DO_FP_2SH(VCVT_FS, gen_helper_vfp_tosls_round_to_zero) 1710 + DO_FP_2SH(VCVT_FU, gen_helper_vfp_touls_round_to_zero) 1711 + 1712 + static uint64_t asimd_imm_const(uint32_t imm, int cmode, int op) 1713 + { 1714 + /* 1715 + * Expand the encoded constant. 1716 + * Note that cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE. 1717 + * We choose to not special-case this and will behave as if a 1718 + * valid constant encoding of 0 had been given. 1719 + * cmode = 15 op = 1 must UNDEF; we assume decode has handled that. 1720 + */ 1721 + switch (cmode) { 1722 + case 0: case 1: 1723 + /* no-op */ 1724 + break; 1725 + case 2: case 3: 1726 + imm <<= 8; 1727 + break; 1728 + case 4: case 5: 1729 + imm <<= 16; 1730 + break; 1731 + case 6: case 7: 1732 + imm <<= 24; 1733 + break; 1734 + case 8: case 9: 1735 + imm |= imm << 16; 1736 + break; 1737 + case 10: case 11: 1738 + imm = (imm << 8) | (imm << 24); 1739 + break; 1740 + case 12: 1741 + imm = (imm << 8) | 0xff; 1742 + break; 1743 + case 13: 1744 + imm = (imm << 16) | 0xffff; 1745 + break; 1746 + case 14: 1747 + if (op) { 1748 + /* 1749 + * This is the only case where the top and bottom 32 bits 1750 + * of the encoded constant differ. 1751 + */ 1752 + uint64_t imm64 = 0; 1753 + int n; 1754 + 1755 + for (n = 0; n < 8; n++) { 1756 + if (imm & (1 << n)) { 1757 + imm64 |= (0xffULL << (n * 8)); 1758 + } 1759 + } 1760 + return imm64; 1761 + } 1762 + imm |= (imm << 8) | (imm << 16) | (imm << 24); 1763 + break; 1764 + case 15: 1765 + imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19) 1766 + | ((imm & 0x40) ? (0x1f << 25) : (1 << 30)); 1767 + break; 1768 + } 1769 + if (op) { 1770 + imm = ~imm; 1771 + } 1772 + return dup_const(MO_32, imm); 1773 + } 1774 + 1775 + static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a, 1776 + GVecGen2iFn *fn) 1777 + { 1778 + uint64_t imm; 1779 + int reg_ofs, vec_size; 1780 + 1781 + if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { 1782 + return false; 1783 + } 1784 + 1785 + /* UNDEF accesses to D16-D31 if they don't exist. */ 1786 + if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) { 1787 + return false; 1788 + } 1789 + 1790 + if (a->vd & a->q) { 1791 + return false; 1792 + } 1793 + 1794 + if (!vfp_access_check(s)) { 1795 + return true; 1796 + } 1797 + 1798 + reg_ofs = neon_reg_offset(a->vd, 0); 1799 + vec_size = a->q ? 16 : 8; 1800 + imm = asimd_imm_const(a->imm, a->cmode, a->op); 1801 + 1802 + fn(MO_64, reg_ofs, reg_ofs, imm, vec_size, vec_size); 1803 + return true; 1804 + } 1805 + 1806 + static void gen_VMOV_1r(unsigned vece, uint32_t dofs, uint32_t aofs, 1807 + int64_t c, uint32_t oprsz, uint32_t maxsz) 1808 + { 1809 + tcg_gen_gvec_dup_imm(MO_64, dofs, oprsz, maxsz, c); 1810 + } 1811 + 1812 + static bool trans_Vimm_1r(DisasContext *s, arg_1reg_imm *a) 1813 + { 1814 + /* Handle decode of cmode/op here between VORR/VBIC/VMOV */ 1815 + GVecGen2iFn *fn; 1816 + 1817 + if ((a->cmode & 1) && a->cmode < 12) { 1818 + /* for op=1, the imm will be inverted, so BIC becomes AND. */ 1819 + fn = a->op ? tcg_gen_gvec_andi : tcg_gen_gvec_ori; 1820 + } else { 1821 + /* There is one unallocated cmode/op combination in this space */ 1822 + if (a->cmode == 15 && a->op == 1) { 1823 + return false; 1824 + } 1825 + fn = gen_VMOV_1r; 1826 + } 1827 + return do_1reg_imm(s, a, fn); 1828 + }
+22 -517
target/arm/translate.c
··· 3011 3011 } 3012 3012 } 3013 3013 3014 - #define GEN_NEON_INTEGER_OP_ENV(name) do { \ 3015 - switch ((size << 1) | u) { \ 3016 - case 0: \ 3017 - gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \ 3018 - break; \ 3019 - case 1: \ 3020 - gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \ 3021 - break; \ 3022 - case 2: \ 3023 - gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \ 3024 - break; \ 3025 - case 3: \ 3026 - gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \ 3027 - break; \ 3028 - case 4: \ 3029 - gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \ 3030 - break; \ 3031 - case 5: \ 3032 - gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \ 3033 - break; \ 3034 - default: return 1; \ 3035 - }} while (0) 3036 - 3037 3014 static TCGv_i32 neon_load_scratch(int scratch) 3038 3015 { 3039 3016 TCGv_i32 tmp = tcg_temp_new_i32(); ··· 3221 3198 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break; 3222 3199 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break; 3223 3200 default: abort(); 3224 - } 3225 - } 3226 - 3227 - static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift, 3228 - int q, int u) 3229 - { 3230 - if (q) { 3231 - if (u) { 3232 - switch (size) { 3233 - case 1: gen_helper_neon_rshl_u16(var, var, shift); break; 3234 - case 2: gen_helper_neon_rshl_u32(var, var, shift); break; 3235 - default: abort(); 3236 - } 3237 - } else { 3238 - switch (size) { 3239 - case 1: gen_helper_neon_rshl_s16(var, var, shift); break; 3240 - case 2: gen_helper_neon_rshl_s32(var, var, shift); break; 3241 - default: abort(); 3242 - } 3243 - } 3244 - } else { 3245 - if (u) { 3246 - switch (size) { 3247 - case 1: gen_helper_neon_shl_u16(var, var, shift); break; 3248 - case 2: gen_ushl_i32(var, var, shift); break; 3249 - default: abort(); 3250 - } 3251 - } else { 3252 - switch (size) { 3253 - case 1: gen_helper_neon_shl_s16(var, var, shift); break; 3254 - case 2: gen_sshl_i32(var, var, shift); break; 3255 - default: abort(); 3256 - } 3257 - } 3258 3201 } 3259 3202 } 3260 3203 ··· 5250 5193 int q; 5251 5194 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs; 5252 5195 int size; 5253 - int shift; 5254 5196 int pass; 5255 - int count; 5256 5197 int u; 5257 5198 int vec_size; 5258 5199 uint32_t imm; 5259 5200 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5; 5260 - TCGv_ptr ptr1, ptr2; 5201 + TCGv_ptr ptr1; 5261 5202 TCGv_i64 tmp64; 5262 5203 5263 5204 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { ··· 5291 5232 /* Three register same length: handled by decodetree */ 5292 5233 return 1; 5293 5234 } else if (insn & (1 << 4)) { 5294 - if ((insn & 0x00380080) != 0) { 5295 - /* Two registers and shift. */ 5296 - op = (insn >> 8) & 0xf; 5297 - if (insn & (1 << 7)) { 5298 - /* 64-bit shift. */ 5299 - if (op > 7) { 5300 - return 1; 5301 - } 5302 - size = 3; 5303 - } else { 5304 - size = 2; 5305 - while ((insn & (1 << (size + 19))) == 0) 5306 - size--; 5307 - } 5308 - shift = (insn >> 16) & ((1 << (3 + size)) - 1); 5309 - if (op < 8) { 5310 - /* Shift by immediate: 5311 - VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */ 5312 - if (q && ((rd | rm) & 1)) { 5313 - return 1; 5314 - } 5315 - if (!u && (op == 4 || op == 6)) { 5316 - return 1; 5317 - } 5318 - /* Right shifts are encoded as N - shift, where N is the 5319 - element size in bits. */ 5320 - if (op <= 4) { 5321 - shift = shift - (1 << (size + 3)); 5322 - } 5323 - 5324 - switch (op) { 5325 - case 0: /* VSHR */ 5326 - /* Right shift comes here negative. */ 5327 - shift = -shift; 5328 - /* Shifts larger than the element size are architecturally 5329 - * valid. Unsigned results in all zeros; signed results 5330 - * in all sign bits. 5331 - */ 5332 - if (!u) { 5333 - tcg_gen_gvec_sari(size, rd_ofs, rm_ofs, 5334 - MIN(shift, (8 << size) - 1), 5335 - vec_size, vec_size); 5336 - } else if (shift >= 8 << size) { 5337 - tcg_gen_gvec_dup_imm(MO_8, rd_ofs, vec_size, 5338 - vec_size, 0); 5339 - } else { 5340 - tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift, 5341 - vec_size, vec_size); 5342 - } 5343 - return 0; 5344 - 5345 - case 1: /* VSRA */ 5346 - /* Right shift comes here negative. */ 5347 - shift = -shift; 5348 - if (u) { 5349 - gen_gvec_usra(size, rd_ofs, rm_ofs, shift, 5350 - vec_size, vec_size); 5351 - } else { 5352 - gen_gvec_ssra(size, rd_ofs, rm_ofs, shift, 5353 - vec_size, vec_size); 5354 - } 5355 - return 0; 5356 - 5357 - case 2: /* VRSHR */ 5358 - /* Right shift comes here negative. */ 5359 - shift = -shift; 5360 - if (u) { 5361 - gen_gvec_urshr(size, rd_ofs, rm_ofs, shift, 5362 - vec_size, vec_size); 5363 - } else { 5364 - gen_gvec_srshr(size, rd_ofs, rm_ofs, shift, 5365 - vec_size, vec_size); 5366 - } 5367 - return 0; 5368 - 5369 - case 3: /* VRSRA */ 5370 - /* Right shift comes here negative. */ 5371 - shift = -shift; 5372 - if (u) { 5373 - gen_gvec_ursra(size, rd_ofs, rm_ofs, shift, 5374 - vec_size, vec_size); 5375 - } else { 5376 - gen_gvec_srsra(size, rd_ofs, rm_ofs, shift, 5377 - vec_size, vec_size); 5378 - } 5379 - return 0; 5380 - 5381 - case 4: /* VSRI */ 5382 - if (!u) { 5383 - return 1; 5384 - } 5385 - /* Right shift comes here negative. */ 5386 - shift = -shift; 5387 - gen_gvec_sri(size, rd_ofs, rm_ofs, shift, 5388 - vec_size, vec_size); 5389 - return 0; 5390 - 5391 - case 5: /* VSHL, VSLI */ 5392 - if (u) { /* VSLI */ 5393 - gen_gvec_sli(size, rd_ofs, rm_ofs, shift, 5394 - vec_size, vec_size); 5395 - } else { /* VSHL */ 5396 - tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift, 5397 - vec_size, vec_size); 5398 - } 5399 - return 0; 5400 - } 5401 - 5402 - if (size == 3) { 5403 - count = q + 1; 5404 - } else { 5405 - count = q ? 4: 2; 5406 - } 5407 - 5408 - /* To avoid excessive duplication of ops we implement shift 5409 - * by immediate using the variable shift operations. 5410 - */ 5411 - imm = dup_const(size, shift); 5412 - 5413 - for (pass = 0; pass < count; pass++) { 5414 - if (size == 3) { 5415 - neon_load_reg64(cpu_V0, rm + pass); 5416 - tcg_gen_movi_i64(cpu_V1, imm); 5417 - switch (op) { 5418 - case 6: /* VQSHLU */ 5419 - gen_helper_neon_qshlu_s64(cpu_V0, cpu_env, 5420 - cpu_V0, cpu_V1); 5421 - break; 5422 - case 7: /* VQSHL */ 5423 - if (u) { 5424 - gen_helper_neon_qshl_u64(cpu_V0, cpu_env, 5425 - cpu_V0, cpu_V1); 5426 - } else { 5427 - gen_helper_neon_qshl_s64(cpu_V0, cpu_env, 5428 - cpu_V0, cpu_V1); 5429 - } 5430 - break; 5431 - default: 5432 - g_assert_not_reached(); 5433 - } 5434 - neon_store_reg64(cpu_V0, rd + pass); 5435 - } else { /* size < 3 */ 5436 - /* Operands in T0 and T1. */ 5437 - tmp = neon_load_reg(rm, pass); 5438 - tmp2 = tcg_temp_new_i32(); 5439 - tcg_gen_movi_i32(tmp2, imm); 5440 - switch (op) { 5441 - case 6: /* VQSHLU */ 5442 - switch (size) { 5443 - case 0: 5444 - gen_helper_neon_qshlu_s8(tmp, cpu_env, 5445 - tmp, tmp2); 5446 - break; 5447 - case 1: 5448 - gen_helper_neon_qshlu_s16(tmp, cpu_env, 5449 - tmp, tmp2); 5450 - break; 5451 - case 2: 5452 - gen_helper_neon_qshlu_s32(tmp, cpu_env, 5453 - tmp, tmp2); 5454 - break; 5455 - default: 5456 - abort(); 5457 - } 5458 - break; 5459 - case 7: /* VQSHL */ 5460 - GEN_NEON_INTEGER_OP_ENV(qshl); 5461 - break; 5462 - default: 5463 - g_assert_not_reached(); 5464 - } 5465 - tcg_temp_free_i32(tmp2); 5466 - neon_store_reg(rd, pass, tmp); 5467 - } 5468 - } /* for pass */ 5469 - } else if (op < 10) { 5470 - /* Shift by immediate and narrow: 5471 - VSHRN, VRSHRN, VQSHRN, VQRSHRN. */ 5472 - int input_unsigned = (op == 8) ? !u : u; 5473 - if (rm & 1) { 5474 - return 1; 5475 - } 5476 - shift = shift - (1 << (size + 3)); 5477 - size++; 5478 - if (size == 3) { 5479 - tmp64 = tcg_const_i64(shift); 5480 - neon_load_reg64(cpu_V0, rm); 5481 - neon_load_reg64(cpu_V1, rm + 1); 5482 - for (pass = 0; pass < 2; pass++) { 5483 - TCGv_i64 in; 5484 - if (pass == 0) { 5485 - in = cpu_V0; 5486 - } else { 5487 - in = cpu_V1; 5488 - } 5489 - if (q) { 5490 - if (input_unsigned) { 5491 - gen_helper_neon_rshl_u64(cpu_V0, in, tmp64); 5492 - } else { 5493 - gen_helper_neon_rshl_s64(cpu_V0, in, tmp64); 5494 - } 5495 - } else { 5496 - if (input_unsigned) { 5497 - gen_ushl_i64(cpu_V0, in, tmp64); 5498 - } else { 5499 - gen_sshl_i64(cpu_V0, in, tmp64); 5500 - } 5501 - } 5502 - tmp = tcg_temp_new_i32(); 5503 - gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0); 5504 - neon_store_reg(rd, pass, tmp); 5505 - } /* for pass */ 5506 - tcg_temp_free_i64(tmp64); 5507 - } else { 5508 - if (size == 1) { 5509 - imm = (uint16_t)shift; 5510 - imm |= imm << 16; 5511 - } else { 5512 - /* size == 2 */ 5513 - imm = (uint32_t)shift; 5514 - } 5515 - tmp2 = tcg_const_i32(imm); 5516 - tmp4 = neon_load_reg(rm + 1, 0); 5517 - tmp5 = neon_load_reg(rm + 1, 1); 5518 - for (pass = 0; pass < 2; pass++) { 5519 - if (pass == 0) { 5520 - tmp = neon_load_reg(rm, 0); 5521 - } else { 5522 - tmp = tmp4; 5523 - } 5524 - gen_neon_shift_narrow(size, tmp, tmp2, q, 5525 - input_unsigned); 5526 - if (pass == 0) { 5527 - tmp3 = neon_load_reg(rm, 1); 5528 - } else { 5529 - tmp3 = tmp5; 5530 - } 5531 - gen_neon_shift_narrow(size, tmp3, tmp2, q, 5532 - input_unsigned); 5533 - tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3); 5534 - tcg_temp_free_i32(tmp); 5535 - tcg_temp_free_i32(tmp3); 5536 - tmp = tcg_temp_new_i32(); 5537 - gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0); 5538 - neon_store_reg(rd, pass, tmp); 5539 - } /* for pass */ 5540 - tcg_temp_free_i32(tmp2); 5541 - } 5542 - } else if (op == 10) { 5543 - /* VSHLL, VMOVL */ 5544 - if (q || (rd & 1)) { 5545 - return 1; 5546 - } 5547 - tmp = neon_load_reg(rm, 0); 5548 - tmp2 = neon_load_reg(rm, 1); 5549 - for (pass = 0; pass < 2; pass++) { 5550 - if (pass == 1) 5551 - tmp = tmp2; 5552 - 5553 - gen_neon_widen(cpu_V0, tmp, size, u); 5554 - 5555 - if (shift != 0) { 5556 - /* The shift is less than the width of the source 5557 - type, so we can just shift the whole register. */ 5558 - tcg_gen_shli_i64(cpu_V0, cpu_V0, shift); 5559 - /* Widen the result of shift: we need to clear 5560 - * the potential overflow bits resulting from 5561 - * left bits of the narrow input appearing as 5562 - * right bits of left the neighbour narrow 5563 - * input. */ 5564 - if (size < 2 || !u) { 5565 - uint64_t imm64; 5566 - if (size == 0) { 5567 - imm = (0xffu >> (8 - shift)); 5568 - imm |= imm << 16; 5569 - } else if (size == 1) { 5570 - imm = 0xffff >> (16 - shift); 5571 - } else { 5572 - /* size == 2 */ 5573 - imm = 0xffffffff >> (32 - shift); 5574 - } 5575 - if (size < 2) { 5576 - imm64 = imm | (((uint64_t)imm) << 32); 5577 - } else { 5578 - imm64 = imm; 5579 - } 5580 - tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64); 5581 - } 5582 - } 5583 - neon_store_reg64(cpu_V0, rd + pass); 5584 - } 5585 - } else if (op >= 14) { 5586 - /* VCVT fixed-point. */ 5587 - TCGv_ptr fpst; 5588 - TCGv_i32 shiftv; 5589 - VFPGenFixPointFn *fn; 5590 - 5591 - if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) { 5592 - return 1; 5593 - } 5594 - 5595 - if (!(op & 1)) { 5596 - if (u) { 5597 - fn = gen_helper_vfp_ultos; 5598 - } else { 5599 - fn = gen_helper_vfp_sltos; 5600 - } 5601 - } else { 5602 - if (u) { 5603 - fn = gen_helper_vfp_touls_round_to_zero; 5604 - } else { 5605 - fn = gen_helper_vfp_tosls_round_to_zero; 5606 - } 5607 - } 5608 - 5609 - /* We have already masked out the must-be-1 top bit of imm6, 5610 - * hence this 32-shift where the ARM ARM has 64-imm6. 5611 - */ 5612 - shift = 32 - shift; 5613 - fpst = get_fpstatus_ptr(1); 5614 - shiftv = tcg_const_i32(shift); 5615 - for (pass = 0; pass < (q ? 4 : 2); pass++) { 5616 - TCGv_i32 tmpf = neon_load_reg(rm, pass); 5617 - fn(tmpf, tmpf, shiftv, fpst); 5618 - neon_store_reg(rd, pass, tmpf); 5619 - } 5620 - tcg_temp_free_ptr(fpst); 5621 - tcg_temp_free_i32(shiftv); 5622 - } else { 5623 - return 1; 5624 - } 5625 - } else { /* (insn & 0x00380080) == 0 */ 5626 - int invert, reg_ofs, vec_size; 5627 - 5628 - if (q && (rd & 1)) { 5629 - return 1; 5630 - } 5631 - 5632 - op = (insn >> 8) & 0xf; 5633 - /* One register and immediate. */ 5634 - imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf); 5635 - invert = (insn & (1 << 5)) != 0; 5636 - /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE. 5637 - * We choose to not special-case this and will behave as if a 5638 - * valid constant encoding of 0 had been given. 5639 - */ 5640 - switch (op) { 5641 - case 0: case 1: 5642 - /* no-op */ 5643 - break; 5644 - case 2: case 3: 5645 - imm <<= 8; 5646 - break; 5647 - case 4: case 5: 5648 - imm <<= 16; 5649 - break; 5650 - case 6: case 7: 5651 - imm <<= 24; 5652 - break; 5653 - case 8: case 9: 5654 - imm |= imm << 16; 5655 - break; 5656 - case 10: case 11: 5657 - imm = (imm << 8) | (imm << 24); 5658 - break; 5659 - case 12: 5660 - imm = (imm << 8) | 0xff; 5661 - break; 5662 - case 13: 5663 - imm = (imm << 16) | 0xffff; 5664 - break; 5665 - case 14: 5666 - imm |= (imm << 8) | (imm << 16) | (imm << 24); 5667 - if (invert) { 5668 - imm = ~imm; 5669 - } 5670 - break; 5671 - case 15: 5672 - if (invert) { 5673 - return 1; 5674 - } 5675 - imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19) 5676 - | ((imm & 0x40) ? (0x1f << 25) : (1 << 30)); 5677 - break; 5678 - } 5679 - if (invert) { 5680 - imm = ~imm; 5681 - } 5682 - 5683 - reg_ofs = neon_reg_offset(rd, 0); 5684 - vec_size = q ? 16 : 8; 5685 - 5686 - if (op & 1 && op < 12) { 5687 - if (invert) { 5688 - /* The immediate value has already been inverted, 5689 - * so BIC becomes AND. 5690 - */ 5691 - tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm, 5692 - vec_size, vec_size); 5693 - } else { 5694 - tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm, 5695 - vec_size, vec_size); 5696 - } 5697 - } else { 5698 - /* VMOV, VMVN. */ 5699 - if (op == 14 && invert) { 5700 - TCGv_i64 t64 = tcg_temp_new_i64(); 5701 - 5702 - for (pass = 0; pass <= q; ++pass) { 5703 - uint64_t val = 0; 5704 - int n; 5705 - 5706 - for (n = 0; n < 8; n++) { 5707 - if (imm & (1 << (n + pass * 8))) { 5708 - val |= 0xffull << (n * 8); 5709 - } 5710 - } 5711 - tcg_gen_movi_i64(t64, val); 5712 - neon_store_reg64(t64, rd + pass); 5713 - } 5714 - tcg_temp_free_i64(t64); 5715 - } else { 5716 - tcg_gen_gvec_dup_imm(MO_32, reg_ofs, vec_size, 5717 - vec_size, imm); 5718 - } 5719 - } 5720 - } 5235 + /* Two registers and shift or reg and imm: handled by decodetree */ 5236 + return 1; 5721 5237 } else { /* (insn & 0x00800010 == 0x00800000) */ 5722 5238 if (size != 3) { 5723 5239 op = (insn >> 8) & 0xf; ··· 6350 5866 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) { 6351 5867 return 1; 6352 5868 } 6353 - ptr1 = vfp_reg_ptr(true, rd); 6354 - ptr2 = vfp_reg_ptr(true, rm); 6355 - 6356 - /* Bit 6 is the lowest opcode bit; it distinguishes between 6357 - * encryption (AESE/AESMC) and decryption (AESD/AESIMC) 6358 - */ 6359 - tmp3 = tcg_const_i32(extract32(insn, 6, 1)); 6360 - 5869 + /* 5870 + * Bit 6 is the lowest opcode bit; it distinguishes 5871 + * between encryption (AESE/AESMC) and decryption 5872 + * (AESD/AESIMC). 5873 + */ 6361 5874 if (op == NEON_2RM_AESE) { 6362 - gen_helper_crypto_aese(ptr1, ptr2, tmp3); 5875 + tcg_gen_gvec_3_ool(vfp_reg_offset(true, rd), 5876 + vfp_reg_offset(true, rd), 5877 + vfp_reg_offset(true, rm), 5878 + 16, 16, extract32(insn, 6, 1), 5879 + gen_helper_crypto_aese); 6363 5880 } else { 6364 - gen_helper_crypto_aesmc(ptr1, ptr2, tmp3); 5881 + tcg_gen_gvec_2_ool(vfp_reg_offset(true, rd), 5882 + vfp_reg_offset(true, rm), 5883 + 16, 16, extract32(insn, 6, 1), 5884 + gen_helper_crypto_aesmc); 6365 5885 } 6366 - tcg_temp_free_ptr(ptr1); 6367 - tcg_temp_free_ptr(ptr2); 6368 - tcg_temp_free_i32(tmp3); 6369 5886 break; 6370 5887 case NEON_2RM_SHA1H: 6371 5888 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) { 6372 5889 return 1; 6373 5890 } 6374 - ptr1 = vfp_reg_ptr(true, rd); 6375 - ptr2 = vfp_reg_ptr(true, rm); 6376 - 6377 - gen_helper_crypto_sha1h(ptr1, ptr2); 6378 - 6379 - tcg_temp_free_ptr(ptr1); 6380 - tcg_temp_free_ptr(ptr2); 5891 + tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, 16, 16, 0, 5892 + gen_helper_crypto_sha1h); 6381 5893 break; 6382 5894 case NEON_2RM_SHA1SU1: 6383 5895 if ((rm | rd) & 1) { ··· 6391 5903 } else if (!dc_isar_feature(aa32_sha1, s)) { 6392 5904 return 1; 6393 5905 } 6394 - ptr1 = vfp_reg_ptr(true, rd); 6395 - ptr2 = vfp_reg_ptr(true, rm); 6396 - if (q) { 6397 - gen_helper_crypto_sha256su0(ptr1, ptr2); 6398 - } else { 6399 - gen_helper_crypto_sha1su1(ptr1, ptr2); 6400 - } 6401 - tcg_temp_free_ptr(ptr1); 6402 - tcg_temp_free_ptr(ptr2); 5906 + tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, 16, 16, 0, 5907 + q ? gen_helper_crypto_sha256su0 5908 + : gen_helper_crypto_sha1su1); 6403 5909 break; 6404 - 6405 5910 case NEON_2RM_VMVN: 6406 5911 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size); 6407 5912 break;
+1 -11
target/arm/vec_helper.c
··· 22 22 #include "exec/helper-proto.h" 23 23 #include "tcg/tcg-gvec-desc.h" 24 24 #include "fpu/softfloat.h" 25 - 25 + #include "vec_internal.h" 26 26 27 27 /* Note that vector data is stored in host-endian 64-bit chunks, 28 28 so addressing units smaller than that needs a host-endian fixup. */ ··· 35 35 #define H2(x) (x) 36 36 #define H4(x) (x) 37 37 #endif 38 - 39 - static void clear_tail(void *vd, uintptr_t opr_sz, uintptr_t max_sz) 40 - { 41 - uint64_t *d = vd + opr_sz; 42 - uintptr_t i; 43 - 44 - for (i = opr_sz; i < max_sz; i += 8) { 45 - *d++ = 0; 46 - } 47 - } 48 38 49 39 /* Signed saturating rounding doubling multiply-accumulate high half, 16-bit */ 50 40 static int16_t inl_qrdmlah_s16(int16_t src1, int16_t src2,
+33
target/arm/vec_internal.h
··· 1 + /* 2 + * ARM AdvSIMD / SVE Vector Helpers 3 + * 4 + * Copyright (c) 2020 Linaro 5 + * 6 + * This library is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU Lesser General Public 8 + * License as published by the Free Software Foundation; either 9 + * version 2 of the License, or (at your option) any later version. 10 + * 11 + * This library is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 + * Lesser General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU Lesser General Public 17 + * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + #ifndef TARGET_ARM_VEC_INTERNALS_H 21 + #define TARGET_ARM_VEC_INTERNALS_H 22 + 23 + static inline void clear_tail(void *vd, uintptr_t opr_sz, uintptr_t max_sz) 24 + { 25 + uint64_t *d = vd + opr_sz; 26 + uintptr_t i; 27 + 28 + for (i = opr_sz; i < max_sz; i += 8) { 29 + *d++ = 0; 30 + } 31 + } 32 + 33 + #endif /* TARGET_ARM_VEC_INTERNALS_H */
+33 -2
tests/acceptance/boot_linux_console.py
··· 308 308 console_pattern = 'Kernel command line: %s' % kernel_command_line 309 309 self.wait_for_console_pattern(console_pattern) 310 310 311 + def test_aarch64_xlnx_versal_virt(self): 312 + """ 313 + :avocado: tags=arch:aarch64 314 + :avocado: tags=machine:xlnx-versal-virt 315 + :avocado: tags=device:pl011 316 + :avocado: tags=device:arm_gicv3 317 + """ 318 + kernel_url = ('http://ports.ubuntu.com/ubuntu-ports/dists/' 319 + 'bionic-updates/main/installer-arm64/current/images/' 320 + 'netboot/ubuntu-installer/arm64/linux') 321 + kernel_hash = '5bfc54cf7ed8157d93f6e5b0241e727b6dc22c50' 322 + kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) 323 + 324 + initrd_url = ('http://ports.ubuntu.com/ubuntu-ports/dists/' 325 + 'bionic-updates/main/installer-arm64/current/images/' 326 + 'netboot/ubuntu-installer/arm64/initrd.gz') 327 + initrd_hash = 'd385d3e88d53e2004c5d43cbe668b458a094f772' 328 + initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash) 329 + 330 + self.vm.set_console() 331 + self.vm.add_args('-m', '2G', 332 + '-kernel', kernel_path, 333 + '-initrd', initrd_path) 334 + self.vm.launch() 335 + self.wait_for_console_pattern('Checked W+X mappings: passed') 336 + 311 337 def test_arm_virt(self): 312 338 """ 313 339 :avocado: tags=arch:arm ··· 379 405 380 406 self.vm.set_console() 381 407 kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + 382 - serial_kernel_cmdline[uart_id]) 408 + serial_kernel_cmdline[uart_id] + 409 + ' root=/dev/mmcblk0p2 rootwait ' + 410 + 'dwc_otg.fiq_fsm_enable=0') 383 411 self.vm.add_args('-kernel', kernel_path, 384 412 '-dtb', dtb_path, 385 - '-append', kernel_command_line) 413 + '-append', kernel_command_line, 414 + '-device', 'usb-kbd') 386 415 self.vm.launch() 387 416 console_pattern = 'Kernel command line: %s' % kernel_command_line 417 + self.wait_for_console_pattern(console_pattern) 418 + console_pattern = 'Product: QEMU USB Keyboard' 388 419 self.wait_for_console_pattern(console_pattern) 389 420 390 421 def test_arm_raspi2_uart0(self):