mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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:
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
@@ -46,6 +46,11 @@ config USB_MUSB
|
||||
bool
|
||||
select USB
|
||||
|
||||
config USB_DWC2
|
||||
bool
|
||||
default y
|
||||
select USB
|
||||
|
||||
config TUSB6010
|
||||
bool
|
||||
select USB_MUSB
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
Reference in New Issue
Block a user