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>
This commit is contained in:
Peter Maydell
2020-06-05 23:31:31 +01:00
28 changed files with 4258 additions and 910 deletions
+85
View File
@@ -0,0 +1,85 @@
Aspeed family boards (``*-bmc``, ``ast2500-evb``, ``ast2600-evb``)
==================================================================
The QEMU Aspeed machines model BMCs of various OpenPOWER systems and
Aspeed evaluation boards. They are based on different releases of the
Aspeed SoC : the AST2400 integrating an ARM926EJ-S CPU (400MHz), the
AST2500 with an ARM1176JZS CPU (800MHz) and more recently the AST2600
with dual cores ARM Cortex A7 CPUs (1.2GHz).
The SoC comes with RAM, Gigabit ethernet, USB, SD/MMC, USB, SPI, I2C,
etc.
AST2400 SoC based machines :
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
AST2500 SoC based machines :
- ``ast2500-evb`` Aspeed AST2500 Evaluation board
- ``romulus-bmc`` OpenPOWER Romulus POWER9 BMC
- ``witherspoon-bmc`` OpenPOWER Witherspoon POWER9 BMC
- ``sonorapass-bmc`` OCP SonoraPass BMC
- ``swift-bmc`` OpenPOWER Swift BMC POWER9
AST2600 SoC based machines :
- ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex A7)
- ``tacoma-bmc`` OpenPOWER Witherspoon POWER9 AST2600 BMC
Supported devices
-----------------
* SMP (for the AST2600 Cortex-A7)
* Interrupt Controller (VIC)
* Timer Controller
* RTC Controller
* I2C Controller
* System Control Unit (SCU)
* SRAM mapping
* X-DMA Controller (basic interface)
* Static Memory Controller (SMC or FMC) - Only SPI Flash support
* SPI Memory Controller
* USB 2.0 Controller
* SD/MMC storage controllers
* SDRAM controller (dummy interface for basic settings and training)
* Watchdog Controller
* GPIO Controller (Master only)
* UART
* Ethernet controllers
Missing devices
---------------
* Coprocessor support
* ADC (out of tree implementation)
* PWM and Fan Controller
* LPC Bus Controller
* Slave GPIO Controller
* Super I/O Controller
* Hash/Crypto Engine
* PCI-Express 1 Controller
* Graphic Display Controller
* PECI Controller
* MCTP Controller
* Mailbox Controller
* Virtual UART
* eSPI Controller
* I3C Controller
Boot options
------------
The Aspeed machines can be started using the -kernel option to load a
Linux kernel or from a firmare image which can be downloaded from the
OpenPOWER jenkins :
https://openpower.xyz/
The image should be attached as an MTD drive. Run :
.. code-block:: bash
$ qemu-system-arm -M romulus-bmc -nic user \
-drive file=flash-romulus,format=raw,if=mtd -nographic
+1
View File
@@ -81,6 +81,7 @@ undocumented; you can get a complete list by running
arm/realview
arm/versatile
arm/vexpress
arm/aspeed
arm/musicpal
arm/nseries
arm/orangepi
+3 -1
View File
@@ -246,6 +246,8 @@ static const MemoryRegionOps stm32f2xx_adc_ops = {
.read = stm32f2xx_adc_read,
.write = stm32f2xx_adc_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl.min_access_size = 4,
.impl.max_access_size = 4,
};
static const VMStateDescription vmstate_stm32f2xx_adc = {
@@ -278,7 +280,7 @@ static void stm32f2xx_adc_init(Object *obj)
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
memory_region_init_io(&s->mmio, obj, &stm32f2xx_adc_ops, s,
TYPE_STM32F2XX_ADC, 0xFF);
TYPE_STM32F2XX_ADC, 0x100);
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
}
+37 -1
View File
@@ -125,6 +125,17 @@ static void bcm2835_peripherals_init(Object *obj)
OBJECT(&s->sdhci.sdbus));
object_property_add_const_link(OBJECT(&s->gpio), "sdbus-sdhost",
OBJECT(&s->sdhost.sdbus));
/* Mphi */
sysbus_init_child_obj(obj, "mphi", &s->mphi, sizeof(s->mphi),
TYPE_BCM2835_MPHI);
/* DWC2 */
sysbus_init_child_obj(obj, "dwc2", &s->dwc2, sizeof(s->dwc2),
TYPE_DWC2_USB);
object_property_add_const_link(OBJECT(&s->dwc2), "dma-mr",
OBJECT(&s->gpu_bus_mr));
}
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
@@ -360,6 +371,32 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->gpio), "sd-bus");
/* Mphi */
object_property_set_bool(OBJECT(&s->mphi), true, "realized", &err);
if (err) {
error_propagate(errp, err);
return;
}
memory_region_add_subregion(&s->peri_mr, MPHI_OFFSET,
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mphi), 0));
sysbus_connect_irq(SYS_BUS_DEVICE(&s->mphi), 0,
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
INTERRUPT_HOSTPORT));
/* DWC2 */
object_property_set_bool(OBJECT(&s->dwc2), true, "realized", &err);
if (err) {
error_propagate(errp, err);
return;
}
memory_region_add_subregion(&s->peri_mr, USB_OTG_OFFSET,
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dwc2), 0));
sysbus_connect_irq(SYS_BUS_DEVICE(&s->dwc2), 0,
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
INTERRUPT_USB));
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
create_unimp(s, &s->cprman, "bcm2835-cprman", CPRMAN_OFFSET, 0x1000);
create_unimp(s, &s->a2w, "bcm2835-a2w", A2W_OFFSET, 0x1000);
@@ -373,7 +410,6 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
create_unimp(s, &s->otp, "bcm2835-otp", OTP_OFFSET, 0x80);
create_unimp(s, &s->dbus, "bcm2835-dbus", DBUS_OFFSET, 0x8000);
create_unimp(s, &s->ave0, "bcm2835-ave0", AVE0_OFFSET, 0x8000);
create_unimp(s, &s->dwc2, "dwc-usb2", USB_OTG_OFFSET, 0x1000);
create_unimp(s, &s->sdramc, "bcm2835-sdramc", SDRAMC_OFFSET, 0x100);
}
+49 -17
View File
@@ -26,6 +26,7 @@
#include "sysemu/blockdev.h"
#include "sysemu/qtest.h"
#include "qemu/cutils.h"
#include "qemu/log.h"
static struct {
hwaddr io_base;
@@ -112,7 +113,9 @@ static uint64_t pxa2xx_pm_read(void *opaque, hwaddr addr,
return s->pm_regs[addr >> 2];
default:
fail:
printf("%s: Bad register " REG_FMT "\n", __func__, addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad read offset 0x%"HWADDR_PRIx"\n",
__func__, addr);
break;
}
return 0;
@@ -143,8 +146,9 @@ static void pxa2xx_pm_write(void *opaque, hwaddr addr,
s->pm_regs[addr >> 2] = value;
break;
}
printf("%s: Bad register " REG_FMT "\n", __func__, addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad write offset 0x%"HWADDR_PRIx"\n",
__func__, addr);
break;
}
}
@@ -185,7 +189,9 @@ static uint64_t pxa2xx_cm_read(void *opaque, hwaddr addr,
return s->cm_regs[CCCR >> 2] | (3 << 28);
default:
printf("%s: Bad register " REG_FMT "\n", __func__, addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad read offset 0x%"HWADDR_PRIx"\n",
__func__, addr);
break;
}
return 0;
@@ -210,7 +216,9 @@ static void pxa2xx_cm_write(void *opaque, hwaddr addr,
break;
default:
printf("%s: Bad register " REG_FMT "\n", __func__, addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad write offset 0x%"HWADDR_PRIx"\n",
__func__, addr);
break;
}
}
@@ -415,7 +423,9 @@ static uint64_t pxa2xx_mm_read(void *opaque, hwaddr addr,
return s->mm_regs[addr >> 2];
/* fall through */
default:
printf("%s: Bad register " REG_FMT "\n", __func__, addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad read offset 0x%"HWADDR_PRIx"\n",
__func__, addr);
break;
}
return 0;
@@ -434,7 +444,9 @@ static void pxa2xx_mm_write(void *opaque, hwaddr addr,
}
default:
printf("%s: Bad register " REG_FMT "\n", __func__, addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad write offset 0x%"HWADDR_PRIx"\n",
__func__, addr);
break;
}
}
@@ -641,7 +653,9 @@ static uint64_t pxa2xx_ssp_read(void *opaque, hwaddr addr,
case SSACD:
return s->ssacd;
default:
printf("%s: Bad register " REG_FMT "\n", __func__, addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad read offset 0x%"HWADDR_PRIx"\n",
__func__, addr);
break;
}
return 0;
@@ -733,7 +747,9 @@ static void pxa2xx_ssp_write(void *opaque, hwaddr addr,
break;
default:
printf("%s: Bad register " REG_FMT "\n", __func__, addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad write offset 0x%"HWADDR_PRIx"\n",
__func__, addr);
break;
}
}
@@ -995,7 +1011,9 @@ static uint64_t pxa2xx_rtc_read(void *opaque, hwaddr addr,
else
return s->last_swcr;
default:
printf("%s: Bad register " REG_FMT "\n", __func__, addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad read offset 0x%"HWADDR_PRIx"\n",
__func__, addr);
break;
}
return 0;
@@ -1101,7 +1119,9 @@ static void pxa2xx_rtc_write(void *opaque, hwaddr addr,
break;
default:
printf("%s: Bad register " REG_FMT "\n", __func__, addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad write offset 0x%"HWADDR_PRIx"\n",
__func__, addr);
}
}
@@ -1354,7 +1374,9 @@ static uint64_t pxa2xx_i2c_read(void *opaque, hwaddr addr,
s->ibmr = 0;
return s->ibmr;
default:
printf("%s: Bad register " REG_FMT "\n", __func__, addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad read offset 0x%"HWADDR_PRIx"\n",
__func__, addr);
break;
}
return 0;
@@ -1427,7 +1449,9 @@ static void pxa2xx_i2c_write(void *opaque, hwaddr addr,
break;
default:
printf("%s: Bad register " REG_FMT "\n", __func__, addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad write offset 0x%"HWADDR_PRIx"\n",
__func__, addr);
}
}
@@ -1628,7 +1652,9 @@ static uint64_t pxa2xx_i2s_read(void *opaque, hwaddr addr,
}
return 0;
default:
printf("%s: Bad register " REG_FMT "\n", __func__, addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad read offset 0x%"HWADDR_PRIx"\n",
__func__, addr);
break;
}
return 0;
@@ -1685,7 +1711,9 @@ static void pxa2xx_i2s_write(void *opaque, hwaddr addr,
}
break;
default:
printf("%s: Bad register " REG_FMT "\n", __func__, addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad write offset 0x%"HWADDR_PRIx"\n",
__func__, addr);
}
}
@@ -1870,7 +1898,9 @@ static uint64_t pxa2xx_fir_read(void *opaque, hwaddr addr,
case ICFOR:
return s->rx_len;
default:
printf("%s: Bad register " REG_FMT "\n", __func__, addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad read offset 0x%"HWADDR_PRIx"\n",
__func__, addr);
break;
}
return 0;
@@ -1922,7 +1952,9 @@ static void pxa2xx_fir_write(void *opaque, hwaddr addr,
case ICFOR:
break;
default:
printf("%s: Bad register " REG_FMT "\n", __func__, addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad write offset 0x%"HWADDR_PRIx"\n",
__func__, addr);
}
}
+7 -3
View File
@@ -12,7 +12,7 @@
*/
#include "qemu/osdep.h"
#include "hw/hw.h"
#include "qemu/log.h"
#include "hw/irq.h"
#include "migration/vmstate.h"
#include "hw/arm/pxa.h"
@@ -233,7 +233,9 @@ static uint64_t pxa2xx_keypad_read(void *opaque, hwaddr offset,
return s->kpkdi;
break;
default:
hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad read offset 0x%"HWADDR_PRIx"\n",
__func__, offset);
}
return 0;
@@ -280,7 +282,9 @@ static void pxa2xx_keypad_write(void *opaque, hwaddr offset,
break;
default:
hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad write offset 0x%"HWADDR_PRIx"\n",
__func__, offset);
}
}
+1
View File
@@ -56,6 +56,7 @@ common-obj-$(CONFIG_OMAP) += omap_l4.o
common-obj-$(CONFIG_OMAP) += omap_sdrc.o
common-obj-$(CONFIG_OMAP) += omap_tap.o
common-obj-$(CONFIG_RASPI) += bcm2835_mbox.o
common-obj-$(CONFIG_RASPI) += bcm2835_mphi.o
common-obj-$(CONFIG_RASPI) += bcm2835_property.o
common-obj-$(CONFIG_RASPI) += bcm2835_rng.o
common-obj-$(CONFIG_RASPI) += bcm2835_thermal.o
+191
View File
@@ -0,0 +1,191 @@
/*
* BCM2835 SOC MPHI emulation
*
* Very basic emulation, only providing the FIQ interrupt needed to
* allow the dwc-otg USB host controller driver in the Raspbian kernel
* to function.
*
* Copyright (c) 2020 Paul Zimmerman <pauldzim@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/misc/bcm2835_mphi.h"
#include "migration/vmstate.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
static inline void mphi_raise_irq(BCM2835MphiState *s)
{
qemu_set_irq(s->irq, 1);
}
static inline void mphi_lower_irq(BCM2835MphiState *s)
{
qemu_set_irq(s->irq, 0);
}
static uint64_t mphi_reg_read(void *ptr, hwaddr addr, unsigned size)
{
BCM2835MphiState *s = ptr;
uint32_t val = 0;
switch (addr) {
case 0x28: /* outdda */
val = s->outdda;
break;
case 0x2c: /* outddb */
val = s->outddb;
break;
case 0x4c: /* ctrl */
val = s->ctrl;
val |= 1 << 17;
break;
case 0x50: /* intstat */
val = s->intstat;
break;
case 0x1f0: /* swirq_set */
val = s->swirq;
break;
case 0x1f4: /* swirq_clr */
val = s->swirq;
break;
default:
qemu_log_mask(LOG_UNIMP, "read from unknown register");
break;
}
return val;
}
static void mphi_reg_write(void *ptr, hwaddr addr, uint64_t val, unsigned size)
{
BCM2835MphiState *s = ptr;
int do_irq = 0;
switch (addr) {
case 0x28: /* outdda */
s->outdda = val;
break;
case 0x2c: /* outddb */
s->outddb = val;
if (val & (1 << 29)) {
do_irq = 1;
}
break;
case 0x4c: /* ctrl */
s->ctrl = val;
if (val & (1 << 16)) {
do_irq = -1;
}
break;
case 0x50: /* intstat */
s->intstat = val;
if (val & ((1 << 16) | (1 << 29))) {
do_irq = -1;
}
break;
case 0x1f0: /* swirq_set */
s->swirq |= val;
do_irq = 1;
break;
case 0x1f4: /* swirq_clr */
s->swirq &= ~val;
do_irq = -1;
break;
default:
qemu_log_mask(LOG_UNIMP, "write to unknown register");
return;
}
if (do_irq > 0) {
mphi_raise_irq(s);
} else if (do_irq < 0) {
mphi_lower_irq(s);
}
}
static const MemoryRegionOps mphi_mmio_ops = {
.read = mphi_reg_read,
.write = mphi_reg_write,
.impl.min_access_size = 4,
.impl.max_access_size = 4,
.endianness = DEVICE_LITTLE_ENDIAN,
};
static void mphi_reset(DeviceState *dev)
{
BCM2835MphiState *s = BCM2835_MPHI(dev);
s->outdda = 0;
s->outddb = 0;
s->ctrl = 0;
s->intstat = 0;
s->swirq = 0;
}
static void mphi_realize(DeviceState *dev, Error **errp)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
BCM2835MphiState *s = BCM2835_MPHI(dev);
sysbus_init_irq(sbd, &s->irq);
}
static void mphi_init(Object *obj)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
BCM2835MphiState *s = BCM2835_MPHI(obj);
memory_region_init_io(&s->iomem, obj, &mphi_mmio_ops, s, "mphi", MPHI_MMIO_SIZE);
sysbus_init_mmio(sbd, &s->iomem);
}
const VMStateDescription vmstate_mphi_state = {
.name = "mphi",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32(outdda, BCM2835MphiState),
VMSTATE_UINT32(outddb, BCM2835MphiState),
VMSTATE_UINT32(ctrl, BCM2835MphiState),
VMSTATE_UINT32(intstat, BCM2835MphiState),
VMSTATE_UINT32(swirq, BCM2835MphiState),
VMSTATE_END_OF_LIST()
}
};
static void mphi_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = mphi_realize;
dc->reset = mphi_reset;
dc->vmsd = &vmstate_mphi_state;
}
static const TypeInfo bcm2835_mphi_type_info = {
.name = TYPE_BCM2835_MPHI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(BCM2835MphiState),
.instance_init = mphi_init,
.class_init = mphi_class_init,
};
static void bcm2835_mphi_register_types(void)
{
type_register_static(&bcm2835_mphi_type_info);
}
type_init(bcm2835_mphi_register_types)
+2 -2
View File
@@ -182,7 +182,7 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
rx = 0;
while (tx_burst) {
while (tx_burst > 0) {
uint8_t byte = tx & 0xff;
DPRINTF("writing 0x%02x\n", (uint32_t)byte);
@@ -206,7 +206,7 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
if (fifo32_is_full(&s->rx_fifo)) {
s->regs[ECSPI_STATREG] |= ECSPI_STATREG_RO;
} else {
fifo32_push(&s->rx_fifo, (uint8_t)rx);
fifo32_push(&s->rx_fifo, rx);
}
if (s->burst_length <= 0) {
+5
View File
@@ -46,6 +46,11 @@ config USB_MUSB
bool
select USB
config USB_DWC2
bool
default y
select USB
config TUSB6010
bool
select USB_MUSB
+1
View File
@@ -12,6 +12,7 @@ common-obj-$(CONFIG_USB_EHCI_SYSBUS) += hcd-ehci-sysbus.o
common-obj-$(CONFIG_USB_XHCI) += hcd-xhci.o
common-obj-$(CONFIG_USB_XHCI_NEC) += hcd-xhci-nec.o
common-obj-$(CONFIG_USB_MUSB) += hcd-musb.o
common-obj-$(CONFIG_USB_DWC2) += hcd-dwc2.o
common-obj-$(CONFIG_TUSB6010) += tusb6010.o
common-obj-$(CONFIG_IMX) += chipidea.o
+14 -1
View File
@@ -229,6 +229,9 @@ static void usb_msd_copy_data(MSDState *s, USBPacket *p)
usb_packet_copy(p, scsi_req_get_buf(s->req) + s->scsi_off, len);
s->scsi_len -= len;
s->scsi_off += len;
if (len > s->data_len) {
len = s->data_len;
}
s->data_len -= len;
if (s->scsi_len == 0 || s->data_len == 0) {
scsi_req_continue(s->req);
@@ -303,6 +306,9 @@ static void usb_msd_command_complete(SCSIRequest *req, uint32_t status, size_t r
if (s->data_len) {
int len = (p->iov.size - p->actual_length);
usb_packet_skip(p, len);
if (len > s->data_len) {
len = s->data_len;
}
s->data_len -= len;
}
if (s->data_len == 0) {
@@ -469,6 +475,9 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
int len = p->iov.size - p->actual_length;
if (len) {
usb_packet_skip(p, len);
if (len > s->data_len) {
len = s->data_len;
}
s->data_len -= len;
if (s->data_len == 0) {
s->mode = USB_MSDM_CSW;
@@ -528,13 +537,17 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
int len = p->iov.size - p->actual_length;
if (len) {
usb_packet_skip(p, len);
if (len > s->data_len) {
len = s->data_len;
}
s->data_len -= len;
if (s->data_len == 0) {
s->mode = USB_MSDM_CSW;
}
}
}
if (p->actual_length < p->iov.size) {
if (p->actual_length < p->iov.size && (p->short_not_ok ||
s->scsi_len >= p->ep->max_packet_size)) {
DPRINTF("Deferring packet %p [wait data-in]\n", p);
s->packet = p;
p->status = USB_RET_ASYNC;
+1417
View File
File diff suppressed because it is too large Load Diff
+190
View File
@@ -0,0 +1,190 @@
/*
* dwc-hsotg (dwc2) USB host controller state definitions
*
* Based on hw/usb/hcd-ehci.h
*
* Copyright (c) 2020 Paul Zimmerman <pauldzim@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef HW_USB_DWC2_H
#define HW_USB_DWC2_H
#include "qemu/timer.h"
#include "hw/irq.h"
#include "hw/sysbus.h"
#include "hw/usb.h"
#include "sysemu/dma.h"
#define DWC2_MMIO_SIZE 0x11000
#define DWC2_NB_CHAN 8 /* Number of host channels */
#define DWC2_MAX_XFER_SIZE 65536 /* Max transfer size expected in HCTSIZ */
typedef struct DWC2Packet DWC2Packet;
typedef struct DWC2State DWC2State;
typedef struct DWC2Class DWC2Class;
enum async_state {
DWC2_ASYNC_NONE = 0,
DWC2_ASYNC_INITIALIZED,
DWC2_ASYNC_INFLIGHT,
DWC2_ASYNC_FINISHED,
};
struct DWC2Packet {
USBPacket packet;
uint32_t devadr;
uint32_t epnum;
uint32_t epdir;
uint32_t mps;
uint32_t pid;
uint32_t index;
uint32_t pcnt;
uint32_t len;
int32_t async;
bool small;
bool needs_service;
};
struct DWC2State {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
USBBus bus;
qemu_irq irq;
MemoryRegion *dma_mr;
AddressSpace dma_as;
MemoryRegion container;
MemoryRegion hsotg;
MemoryRegion fifos;
union {
#define DWC2_GLBREG_SIZE 0x70
uint32_t glbreg[DWC2_GLBREG_SIZE / sizeof(uint32_t)];
struct {
uint32_t gotgctl; /* 00 */
uint32_t gotgint; /* 04 */
uint32_t gahbcfg; /* 08 */
uint32_t gusbcfg; /* 0c */
uint32_t grstctl; /* 10 */
uint32_t gintsts; /* 14 */
uint32_t gintmsk; /* 18 */
uint32_t grxstsr; /* 1c */
uint32_t grxstsp; /* 20 */
uint32_t grxfsiz; /* 24 */
uint32_t gnptxfsiz; /* 28 */
uint32_t gnptxsts; /* 2c */
uint32_t gi2cctl; /* 30 */
uint32_t gpvndctl; /* 34 */
uint32_t ggpio; /* 38 */
uint32_t guid; /* 3c */
uint32_t gsnpsid; /* 40 */
uint32_t ghwcfg1; /* 44 */
uint32_t ghwcfg2; /* 48 */
uint32_t ghwcfg3; /* 4c */
uint32_t ghwcfg4; /* 50 */
uint32_t glpmcfg; /* 54 */
uint32_t gpwrdn; /* 58 */
uint32_t gdfifocfg; /* 5c */
uint32_t gadpctl; /* 60 */
uint32_t grefclk; /* 64 */
uint32_t gintmsk2; /* 68 */
uint32_t gintsts2; /* 6c */
};
};
union {
#define DWC2_FSZREG_SIZE 0x04
uint32_t fszreg[DWC2_FSZREG_SIZE / sizeof(uint32_t)];
struct {
uint32_t hptxfsiz; /* 100 */
};
};
union {
#define DWC2_HREG0_SIZE 0x44
uint32_t hreg0[DWC2_HREG0_SIZE / sizeof(uint32_t)];
struct {
uint32_t hcfg; /* 400 */
uint32_t hfir; /* 404 */
uint32_t hfnum; /* 408 */
uint32_t rsvd0; /* 40c */
uint32_t hptxsts; /* 410 */
uint32_t haint; /* 414 */
uint32_t haintmsk; /* 418 */
uint32_t hflbaddr; /* 41c */
uint32_t rsvd1[8]; /* 420-43c */
uint32_t hprt0; /* 440 */
};
};
#define DWC2_HREG1_SIZE (0x20 * DWC2_NB_CHAN)
uint32_t hreg1[DWC2_HREG1_SIZE / sizeof(uint32_t)];
#define hcchar(_ch) hreg1[((_ch) << 3) + 0] /* 500, 520, ... */
#define hcsplt(_ch) hreg1[((_ch) << 3) + 1] /* 504, 524, ... */
#define hcint(_ch) hreg1[((_ch) << 3) + 2] /* 508, 528, ... */
#define hcintmsk(_ch) hreg1[((_ch) << 3) + 3] /* 50c, 52c, ... */
#define hctsiz(_ch) hreg1[((_ch) << 3) + 4] /* 510, 530, ... */
#define hcdma(_ch) hreg1[((_ch) << 3) + 5] /* 514, 534, ... */
#define hcdmab(_ch) hreg1[((_ch) << 3) + 7] /* 51c, 53c, ... */
union {
#define DWC2_PCGREG_SIZE 0x08
uint32_t pcgreg[DWC2_PCGREG_SIZE / sizeof(uint32_t)];
struct {
uint32_t pcgctl; /* e00 */
uint32_t pcgcctl1; /* e04 */
};
};
/* TODO - implement FIFO registers for slave mode */
#define DWC2_HFIFO_SIZE (0x1000 * DWC2_NB_CHAN)
/*
* Internal state
*/
QEMUTimer *eof_timer;
QEMUTimer *frame_timer;
QEMUBH *async_bh;
int64_t sof_time;
int64_t usb_frame_time;
int64_t usb_bit_time;
uint32_t usb_version;
uint16_t frame_number;
uint16_t fi;
uint16_t next_chan;
bool working;
USBPort uport;
DWC2Packet packet[DWC2_NB_CHAN]; /* one packet per chan */
uint8_t usb_buf[DWC2_NB_CHAN][DWC2_MAX_XFER_SIZE]; /* one buffer per chan */
};
struct DWC2Class {
/*< private >*/
SysBusDeviceClass parent_class;
ResettablePhases parent_phases;
/*< public >*/
};
#define TYPE_DWC2_USB "dwc2-usb"
#define DWC2_USB(obj) \
OBJECT_CHECK(DWC2State, (obj), TYPE_DWC2_USB)
#define DWC2_CLASS(klass) \
OBJECT_CLASS_CHECK(DWC2Class, (klass), TYPE_DWC2_USB)
#define DWC2_GET_CLASS(obj) \
OBJECT_GET_CLASS(DWC2Class, (obj), TYPE_DWC2_USB)
#endif
+50
View File
@@ -176,6 +176,56 @@ usb_xhci_xfer_error(void *xfer, uint32_t ret) "%p: ret %d"
usb_xhci_unimplemented(const char *item, int nr) "%s (0x%x)"
usb_xhci_enforced_limit(const char *item) "%s"
# hcd-dwc2.c
usb_dwc2_update_irq(uint32_t level) "level=%d"
usb_dwc2_raise_global_irq(uint32_t intr) "0x%08x"
usb_dwc2_lower_global_irq(uint32_t intr) "0x%08x"
usb_dwc2_raise_host_irq(uint32_t intr) "0x%04x"
usb_dwc2_lower_host_irq(uint32_t intr) "0x%04x"
usb_dwc2_sof(int64_t next) "next SOF %" PRId64
usb_dwc2_bus_start(void) "start SOFs"
usb_dwc2_bus_stop(void) "stop SOFs"
usb_dwc2_find_device(uint8_t addr) "%d"
usb_dwc2_port_disabled(uint32_t pnum) "port %d disabled"
usb_dwc2_device_found(uint32_t pnum) "device found on port %d"
usb_dwc2_device_not_found(void) "device not found"
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"
usb_dwc2_memory_read(uint32_t addr, uint32_t len) "addr %d len %d"
usb_dwc2_packet_status(const char *status, uint32_t len) "status %s len %d"
usb_dwc2_packet_error(const char *status) "ERROR %s"
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"
usb_dwc2_memory_write(uint32_t addr, uint32_t len) "addr %d len %d"
usb_dwc2_packet_done(const char *status, uint32_t actual, uint32_t len, uint32_t pcnt) "status %s actual %d len %d pcnt %d"
usb_dwc2_packet_next(const char *status, uint32_t len, uint32_t pcnt) "status %s len %d pcnt %d"
usb_dwc2_attach(void *port) "port %p"
usb_dwc2_attach_speed(const char *speed) "%s-speed device attached"
usb_dwc2_detach(void *port) "port %p"
usb_dwc2_child_detach(void *port, void *child) "port %p child %p"
usb_dwc2_wakeup(void *port) "port %p"
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"
usb_dwc2_work_bh(void) ""
usb_dwc2_work_bh_service(uint32_t first, uint32_t current, void *dev, uint32_t ep) "first %d servicing %d dev %p ep %d"
usb_dwc2_work_bh_next(uint32_t chan) "next %d"
usb_dwc2_enable_chan(uint32_t chan, void *dev, void *pkt, uint32_t ep) "ch %d dev %p pkt %p ep %d"
usb_dwc2_glbreg_read(uint64_t addr, const char *reg, uint32_t val) " 0x%04" PRIx64 " %s val 0x%08x"
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
usb_dwc2_fszreg_read(uint64_t addr, uint32_t val) " 0x%04" PRIx64 " HPTXFSIZ val 0x%08x"
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
usb_dwc2_hreg0_read(uint64_t addr, const char *reg, uint32_t val) " 0x%04" PRIx64 " %s val 0x%08x"
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
usb_dwc2_hreg1_read(uint64_t addr, const char *reg, uint64_t chan, uint32_t val) " 0x%04" PRIx64 " %s%" PRId64 " val 0x%08x"
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
usb_dwc2_pcgreg_read(uint64_t addr, const char *reg, uint32_t val) " 0x%04" PRIx64 " %s val 0x%08x"
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
usb_dwc2_hreg2_read(uint64_t addr, uint64_t fifo, uint32_t val) " 0x%04" PRIx64 " FIFO%" PRId64 " val 0x%08x"
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
usb_dwc2_hreg0_action(const char *s) "%s"
usb_dwc2_wakeup_endpoint(void *ep, uint32_t stream) "endp %p stream %d"
usb_dwc2_work_timer(void) ""
usb_dwc2_reset_enter(void) "=== RESET enter ==="
usb_dwc2_reset_hold(void) "=== RESET hold ==="
usb_dwc2_reset_exit(void) "=== RESET exit ==="
# desc.c
usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d"
usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device qualifier, len %d, ret %d"
+4 -1
View File
@@ -21,11 +21,13 @@
#include "hw/misc/bcm2835_property.h"
#include "hw/misc/bcm2835_rng.h"
#include "hw/misc/bcm2835_mbox.h"
#include "hw/misc/bcm2835_mphi.h"
#include "hw/misc/bcm2835_thermal.h"
#include "hw/sd/sdhci.h"
#include "hw/sd/bcm2835_sdhost.h"
#include "hw/gpio/bcm2835_gpio.h"
#include "hw/timer/bcm2835_systmr.h"
#include "hw/usb/hcd-dwc2.h"
#include "hw/misc/unimp.h"
#define TYPE_BCM2835_PERIPHERALS "bcm2835-peripherals"
@@ -42,6 +44,7 @@ typedef struct BCM2835PeripheralState {
qemu_irq irq, fiq;
BCM2835SystemTimerState systmr;
BCM2835MphiState mphi;
UnimplementedDeviceState armtmr;
UnimplementedDeviceState cprman;
UnimplementedDeviceState a2w;
@@ -65,7 +68,7 @@ typedef struct BCM2835PeripheralState {
UnimplementedDeviceState ave0;
UnimplementedDeviceState bscsl;
UnimplementedDeviceState smi;
UnimplementedDeviceState dwc2;
DWC2State dwc2;
UnimplementedDeviceState sdramc;
} BCM2835PeripheralState;
+44
View File
@@ -0,0 +1,44 @@
/*
* BCM2835 SOC MPHI state definitions
*
* Copyright (c) 2020 Paul Zimmerman <pauldzim@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef HW_MISC_BCM2835_MPHI_H
#define HW_MISC_BCM2835_MPHI_H
#include "hw/irq.h"
#include "hw/sysbus.h"
#define MPHI_MMIO_SIZE 0x1000
typedef struct BCM2835MphiState BCM2835MphiState;
struct BCM2835MphiState {
SysBusDevice parent_obj;
qemu_irq irq;
MemoryRegion iomem;
uint32_t outdda;
uint32_t outddb;
uint32_t ctrl;
uint32_t intstat;
uint32_t swirq;
};
#define TYPE_BCM2835_MPHI "bcm2835-mphi"
#define BCM2835_MPHI(obj) \
OBJECT_CHECK(BCM2835MphiState, (obj), TYPE_BCM2835_MPHI)
#endif
File diff suppressed because it is too large Load Diff
+192 -75
View File
@@ -13,7 +13,9 @@
#include "cpu.h"
#include "exec/helper-proto.h"
#include "tcg/tcg-gvec-desc.h"
#include "crypto/aes.h"
#include "vec_internal.h"
union CRYPTO_STATE {
uint8_t bytes[16];
@@ -22,25 +24,35 @@ union CRYPTO_STATE {
};
#ifdef HOST_WORDS_BIGENDIAN
#define CR_ST_BYTE(state, i) (state.bytes[(15 - (i)) ^ 8])
#define CR_ST_WORD(state, i) (state.words[(3 - (i)) ^ 2])
#define CR_ST_BYTE(state, i) ((state).bytes[(15 - (i)) ^ 8])
#define CR_ST_WORD(state, i) ((state).words[(3 - (i)) ^ 2])
#else
#define CR_ST_BYTE(state, i) (state.bytes[i])
#define CR_ST_WORD(state, i) (state.words[i])
#define CR_ST_BYTE(state, i) ((state).bytes[i])
#define CR_ST_WORD(state, i) ((state).words[i])
#endif
void HELPER(crypto_aese)(void *vd, void *vm, uint32_t decrypt)
/*
* The caller has not been converted to full gvec, and so only
* modifies the low 16 bytes of the vector register.
*/
static void clear_tail_16(void *vd, uint32_t desc)
{
int opr_sz = simd_oprsz(desc);
int max_sz = simd_maxsz(desc);
assert(opr_sz == 16);
clear_tail(vd, opr_sz, max_sz);
}
static void do_crypto_aese(uint64_t *rd, uint64_t *rn,
uint64_t *rm, bool decrypt)
{
static uint8_t const * const sbox[2] = { AES_sbox, AES_isbox };
static uint8_t const * const shift[2] = { AES_shifts, AES_ishifts };
uint64_t *rd = vd;
uint64_t *rm = vm;
union CRYPTO_STATE rk = { .l = { rm[0], rm[1] } };
union CRYPTO_STATE st = { .l = { rd[0], rd[1] } };
union CRYPTO_STATE st = { .l = { rn[0], rn[1] } };
int i;
assert(decrypt < 2);
/* xor state vector with round key */
rk.l[0] ^= st.l[0];
rk.l[1] ^= st.l[1];
@@ -54,7 +66,18 @@ void HELPER(crypto_aese)(void *vd, void *vm, uint32_t decrypt)
rd[1] = st.l[1];
}
void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t decrypt)
void HELPER(crypto_aese)(void *vd, void *vn, void *vm, uint32_t desc)
{
intptr_t i, opr_sz = simd_oprsz(desc);
bool decrypt = simd_data(desc);
for (i = 0; i < opr_sz; i += 16) {
do_crypto_aese(vd + i, vn + i, vm + i, decrypt);
}
clear_tail(vd, opr_sz, simd_maxsz(desc));
}
static void do_crypto_aesmc(uint64_t *rd, uint64_t *rm, bool decrypt)
{
static uint32_t const mc[][256] = { {
/* MixColumns lookup table */
@@ -190,13 +213,9 @@ void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t decrypt)
0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d,
} };
uint64_t *rd = vd;
uint64_t *rm = vm;
union CRYPTO_STATE st = { .l = { rm[0], rm[1] } };
int i;
assert(decrypt < 2);
for (i = 0; i < 16; i += 4) {
CR_ST_WORD(st, i >> 2) =
mc[decrypt][CR_ST_BYTE(st, i)] ^
@@ -209,6 +228,17 @@ void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t decrypt)
rd[1] = st.l[1];
}
void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t desc)
{
intptr_t i, opr_sz = simd_oprsz(desc);
bool decrypt = simd_data(desc);
for (i = 0; i < opr_sz; i += 16) {
do_crypto_aesmc(vd + i, vm + i, decrypt);
}
clear_tail(vd, opr_sz, simd_maxsz(desc));
}
/*
* SHA-1 logical functions
*/
@@ -228,52 +258,77 @@ static uint32_t maj(uint32_t x, uint32_t y, uint32_t z)
return (x & y) | ((x | y) & z);
}
void HELPER(crypto_sha1_3reg)(void *vd, void *vn, void *vm, uint32_t op)
void HELPER(crypto_sha1su0)(void *vd, void *vn, void *vm, uint32_t desc)
{
uint64_t *d = vd, *n = vn, *m = vm;
uint64_t d0, d1;
d0 = d[1] ^ d[0] ^ m[0];
d1 = n[0] ^ d[1] ^ m[1];
d[0] = d0;
d[1] = d1;
clear_tail_16(vd, desc);
}
static inline void crypto_sha1_3reg(uint64_t *rd, uint64_t *rn,
uint64_t *rm, uint32_t desc,
uint32_t (*fn)(union CRYPTO_STATE *d))
{
uint64_t *rd = vd;
uint64_t *rn = vn;
uint64_t *rm = vm;
union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
int i;
if (op == 3) { /* sha1su0 */
d.l[0] ^= d.l[1] ^ m.l[0];
d.l[1] ^= n.l[0] ^ m.l[1];
} else {
int i;
for (i = 0; i < 4; i++) {
uint32_t t = fn(&d);
for (i = 0; i < 4; i++) {
uint32_t t;
t += rol32(CR_ST_WORD(d, 0), 5) + CR_ST_WORD(n, 0)
+ CR_ST_WORD(m, i);
switch (op) {
case 0: /* sha1c */
t = cho(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
break;
case 1: /* sha1p */
t = par(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
break;
case 2: /* sha1m */
t = maj(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
break;
default:
g_assert_not_reached();
}
t += rol32(CR_ST_WORD(d, 0), 5) + CR_ST_WORD(n, 0)
+ CR_ST_WORD(m, i);
CR_ST_WORD(n, 0) = CR_ST_WORD(d, 3);
CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2);
CR_ST_WORD(d, 2) = ror32(CR_ST_WORD(d, 1), 2);
CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0);
CR_ST_WORD(d, 0) = t;
}
CR_ST_WORD(n, 0) = CR_ST_WORD(d, 3);
CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2);
CR_ST_WORD(d, 2) = ror32(CR_ST_WORD(d, 1), 2);
CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0);
CR_ST_WORD(d, 0) = t;
}
rd[0] = d.l[0];
rd[1] = d.l[1];
clear_tail_16(rd, desc);
}
void HELPER(crypto_sha1h)(void *vd, void *vm)
static uint32_t do_sha1c(union CRYPTO_STATE *d)
{
return cho(CR_ST_WORD(*d, 1), CR_ST_WORD(*d, 2), CR_ST_WORD(*d, 3));
}
void HELPER(crypto_sha1c)(void *vd, void *vn, void *vm, uint32_t desc)
{
crypto_sha1_3reg(vd, vn, vm, desc, do_sha1c);
}
static uint32_t do_sha1p(union CRYPTO_STATE *d)
{
return par(CR_ST_WORD(*d, 1), CR_ST_WORD(*d, 2), CR_ST_WORD(*d, 3));
}
void HELPER(crypto_sha1p)(void *vd, void *vn, void *vm, uint32_t desc)
{
crypto_sha1_3reg(vd, vn, vm, desc, do_sha1p);
}
static uint32_t do_sha1m(union CRYPTO_STATE *d)
{
return maj(CR_ST_WORD(*d, 1), CR_ST_WORD(*d, 2), CR_ST_WORD(*d, 3));
}
void HELPER(crypto_sha1m)(void *vd, void *vn, void *vm, uint32_t desc)
{
crypto_sha1_3reg(vd, vn, vm, desc, do_sha1m);
}
void HELPER(crypto_sha1h)(void *vd, void *vm, uint32_t desc)
{
uint64_t *rd = vd;
uint64_t *rm = vm;
@@ -284,9 +339,11 @@ void HELPER(crypto_sha1h)(void *vd, void *vm)
rd[0] = m.l[0];
rd[1] = m.l[1];
clear_tail_16(vd, desc);
}
void HELPER(crypto_sha1su1)(void *vd, void *vm)
void HELPER(crypto_sha1su1)(void *vd, void *vm, uint32_t desc)
{
uint64_t *rd = vd;
uint64_t *rm = vm;
@@ -300,6 +357,8 @@ void HELPER(crypto_sha1su1)(void *vd, void *vm)
rd[0] = d.l[0];
rd[1] = d.l[1];
clear_tail_16(vd, desc);
}
/*
@@ -327,7 +386,7 @@ static uint32_t s1(uint32_t x)
return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10);
}
void HELPER(crypto_sha256h)(void *vd, void *vn, void *vm)
void HELPER(crypto_sha256h)(void *vd, void *vn, void *vm, uint32_t desc)
{
uint64_t *rd = vd;
uint64_t *rn = vn;
@@ -358,9 +417,11 @@ void HELPER(crypto_sha256h)(void *vd, void *vn, void *vm)
rd[0] = d.l[0];
rd[1] = d.l[1];
clear_tail_16(vd, desc);
}
void HELPER(crypto_sha256h2)(void *vd, void *vn, void *vm)
void HELPER(crypto_sha256h2)(void *vd, void *vn, void *vm, uint32_t desc)
{
uint64_t *rd = vd;
uint64_t *rn = vn;
@@ -383,9 +444,11 @@ void HELPER(crypto_sha256h2)(void *vd, void *vn, void *vm)
rd[0] = d.l[0];
rd[1] = d.l[1];
clear_tail_16(vd, desc);
}
void HELPER(crypto_sha256su0)(void *vd, void *vm)
void HELPER(crypto_sha256su0)(void *vd, void *vm, uint32_t desc)
{
uint64_t *rd = vd;
uint64_t *rm = vm;
@@ -399,9 +462,11 @@ void HELPER(crypto_sha256su0)(void *vd, void *vm)
rd[0] = d.l[0];
rd[1] = d.l[1];
clear_tail_16(vd, desc);
}
void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm)
void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm, uint32_t desc)
{
uint64_t *rd = vd;
uint64_t *rn = vn;
@@ -417,6 +482,8 @@ void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm)
rd[0] = d.l[0];
rd[1] = d.l[1];
clear_tail_16(vd, desc);
}
/*
@@ -453,7 +520,7 @@ static uint64_t s1_512(uint64_t x)
return ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6);
}
void HELPER(crypto_sha512h)(void *vd, void *vn, void *vm)
void HELPER(crypto_sha512h)(void *vd, void *vn, void *vm, uint32_t desc)
{
uint64_t *rd = vd;
uint64_t *rn = vn;
@@ -466,9 +533,11 @@ void HELPER(crypto_sha512h)(void *vd, void *vn, void *vm)
rd[0] = d0;
rd[1] = d1;
clear_tail_16(vd, desc);
}
void HELPER(crypto_sha512h2)(void *vd, void *vn, void *vm)
void HELPER(crypto_sha512h2)(void *vd, void *vn, void *vm, uint32_t desc)
{
uint64_t *rd = vd;
uint64_t *rn = vn;
@@ -481,9 +550,11 @@ void HELPER(crypto_sha512h2)(void *vd, void *vn, void *vm)
rd[0] = d0;
rd[1] = d1;
clear_tail_16(vd, desc);
}
void HELPER(crypto_sha512su0)(void *vd, void *vn)
void HELPER(crypto_sha512su0)(void *vd, void *vn, uint32_t desc)
{
uint64_t *rd = vd;
uint64_t *rn = vn;
@@ -495,9 +566,11 @@ void HELPER(crypto_sha512su0)(void *vd, void *vn)
rd[0] = d0;
rd[1] = d1;
clear_tail_16(vd, desc);
}
void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm)
void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm, uint32_t desc)
{
uint64_t *rd = vd;
uint64_t *rn = vn;
@@ -505,9 +578,11 @@ void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm)
rd[0] += s1_512(rn[0]) + rm[0];
rd[1] += s1_512(rn[1]) + rm[1];
clear_tail_16(vd, desc);
}
void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm)
void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm, uint32_t desc)
{
uint64_t *rd = vd;
uint64_t *rn = vn;
@@ -531,9 +606,11 @@ void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm)
rd[0] = d.l[0];
rd[1] = d.l[1];
clear_tail_16(vd, desc);
}
void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm)
void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm, uint32_t desc)
{
uint64_t *rd = vd;
uint64_t *rn = vn;
@@ -551,17 +628,18 @@ void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm)
rd[0] = d.l[0];
rd[1] = d.l[1];
clear_tail_16(vd, desc);
}
void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
uint32_t opcode)
static inline void QEMU_ALWAYS_INLINE
crypto_sm3tt(uint64_t *rd, uint64_t *rn, uint64_t *rm,
uint32_t desc, uint32_t opcode)
{
uint64_t *rd = vd;
uint64_t *rn = vn;
uint64_t *rm = vm;
union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
uint32_t imm2 = simd_data(desc);
uint32_t t;
assert(imm2 < 4);
@@ -576,7 +654,7 @@ void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
/* SM3TT2B */
t = cho(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
} else {
g_assert_not_reached();
qemu_build_not_reached();
}
t += CR_ST_WORD(d, 0) + CR_ST_WORD(m, imm2);
@@ -601,8 +679,21 @@ void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
rd[0] = d.l[0];
rd[1] = d.l[1];
clear_tail_16(rd, desc);
}
#define DO_SM3TT(NAME, OPCODE) \
void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
{ crypto_sm3tt(vd, vn, vm, desc, OPCODE); }
DO_SM3TT(crypto_sm3tt1a, 0)
DO_SM3TT(crypto_sm3tt1b, 1)
DO_SM3TT(crypto_sm3tt2a, 2)
DO_SM3TT(crypto_sm3tt2b, 3)
#undef DO_SM3TT
static uint8_t const sm4_sbox[] = {
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7,
0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
@@ -638,12 +729,10 @@ static uint8_t const sm4_sbox[] = {
0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
};
void HELPER(crypto_sm4e)(void *vd, void *vn)
static void do_crypto_sm4e(uint64_t *rd, uint64_t *rn, uint64_t *rm)
{
uint64_t *rd = vd;
uint64_t *rn = vn;
union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
union CRYPTO_STATE d = { .l = { rn[0], rn[1] } };
union CRYPTO_STATE n = { .l = { rm[0], rm[1] } };
uint32_t t, i;
for (i = 0; i < 4; i++) {
@@ -665,11 +754,18 @@ void HELPER(crypto_sm4e)(void *vd, void *vn)
rd[1] = d.l[1];
}
void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm)
void HELPER(crypto_sm4e)(void *vd, void *vn, void *vm, uint32_t desc)
{
intptr_t i, opr_sz = simd_oprsz(desc);
for (i = 0; i < opr_sz; i += 16) {
do_crypto_sm4e(vd + i, vn + i, vm + i);
}
clear_tail(vd, opr_sz, simd_maxsz(desc));
}
static void do_crypto_sm4ekey(uint64_t *rd, uint64_t *rn, uint64_t *rm)
{
uint64_t *rd = vd;
uint64_t *rn = vn;
uint64_t *rm = vm;
union CRYPTO_STATE d;
union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
@@ -693,3 +789,24 @@ void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm)
rd[0] = d.l[0];
rd[1] = d.l[1];
}
void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm, uint32_t desc)
{
intptr_t i, opr_sz = simd_oprsz(desc);
for (i = 0; i < opr_sz; i += 16) {
do_crypto_sm4ekey(vd + i, vn + i, vm + i);
}
clear_tail(vd, opr_sz, simd_maxsz(desc));
}
void HELPER(crypto_rax1)(void *vd, void *vn, void *vm, uint32_t desc)
{
intptr_t i, opr_sz = simd_oprsz(desc);
uint64_t *d = vd, *n = vn, *m = vm;
for (i = 0; i < opr_sz / 8; ++i) {
d[i] = n[i] ^ rol64(m[i], 1);
}
clear_tail(vd, opr_sz, simd_maxsz(desc));
}
+28 -17
View File
@@ -510,29 +510,40 @@ DEF_HELPER_FLAGS_2(neon_qzip8, TCG_CALL_NO_RWG, void, ptr, ptr)
DEF_HELPER_FLAGS_2(neon_qzip16, TCG_CALL_NO_RWG, void, ptr, ptr)
DEF_HELPER_FLAGS_2(neon_qzip32, TCG_CALL_NO_RWG, void, ptr, ptr)
DEF_HELPER_FLAGS_3(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(crypto_aesmc, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(crypto_sha1_3reg, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_2(crypto_sha1h, TCG_CALL_NO_RWG, void, ptr, ptr)
DEF_HELPER_FLAGS_2(crypto_sha1su1, TCG_CALL_NO_RWG, void, ptr, ptr)
DEF_HELPER_FLAGS_4(crypto_sha1su0, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(crypto_sha1c, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(crypto_sha1p, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(crypto_sha1m, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(crypto_sha1h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(crypto_sha1su1, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(crypto_sha256h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
DEF_HELPER_FLAGS_3(crypto_sha256h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
DEF_HELPER_FLAGS_2(crypto_sha256su0, TCG_CALL_NO_RWG, void, ptr, ptr)
DEF_HELPER_FLAGS_3(crypto_sha256su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
DEF_HELPER_FLAGS_4(crypto_sha256h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(crypto_sha256h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(crypto_sha256su0, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(crypto_sha256su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(crypto_sha512h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
DEF_HELPER_FLAGS_3(crypto_sha512h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
DEF_HELPER_FLAGS_2(crypto_sha512su0, TCG_CALL_NO_RWG, void, ptr, ptr)
DEF_HELPER_FLAGS_3(crypto_sha512su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
DEF_HELPER_FLAGS_4(crypto_sha512h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(crypto_sha512h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(crypto_sha512su0, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(crypto_sha512su1, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(crypto_sm3tt, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, i32)
DEF_HELPER_FLAGS_3(crypto_sm3partw1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
DEF_HELPER_FLAGS_4(crypto_sm3tt1a, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(crypto_sm3tt1b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(crypto_sm3tt2a, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(crypto_sm3tt2b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(crypto_sm3partw1, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(crypto_sm3partw2, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_2(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr)
DEF_HELPER_FLAGS_3(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
DEF_HELPER_FLAGS_4(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(crypto_rax1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)

Some files were not shown because too many files have changed in this diff Show More