target-arm queue:

* tests/avocado: update firmware for sbsa-ref and use all cores
  * hw/arm/smmu-common: Replace smmu_iommu_mr with smmu_find_sdev
  * arm: Fix VCMLA Dd, Dn, Dm[idx]
  * arm: Fix SQDMULH (by element) with Q=0
  * arm: Fix FJCVTZS vs flush-to-zero
  * arm: More conversion of A64 AdvSIMD to decodetree
  * arm: Enable FEAT_Debugv8p8 for -cpu max
  * MAINTAINERS: Update family name for Patrick Leis
  * hw/arm/xilinx_zynq: Add boot-mode property
  * docs/system/arm: Add a doc for zynq board
  * hw/misc: In STM32L4x5 EXTI, correct configurable interrupts
  * tests/qtest: fix minor issues in STM32L4x5 tests
 -----BEGIN PGP SIGNATURE-----
 
 iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmaC1BMZHHBldGVyLm1h
 eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3nDOEACCoewjO2FJ4RFXMSmgr0Zf
 jxWliu7osw7oeG4ZNq1+xMiXeW0vyS54eW41TMki1f98N/yK8v55BM8kBBvDvZaz
 R5DUXpN+MtwD9A62md3B2c4mFXHqk1UOGbKi4btbtFj4lS8pV51mPmApzBUr2iTj
 w6dCLciLOt87NWgtLECXsZ3evn+VlTRc+Hmfp1M/C/Rf2Qx3zis/CFHGQsZLGwzG
 2WhTpU1BKeOfsQa1VbSX6un14d72/JATFZN3rSgMbOEbvsCEeP+rnkzX57ejGyxV
 4DUx69gEAqS5bOfkQHLwy82WsunD/oIgp+GpYaYgINHzh6UkEsPoymrHAaPgV1Vh
 g0TaBtbv2p89RFY1C2W2Mi4ICQ14a+oIV9FPvDsOE8Wq+wDAy/ZxZs7G6flxqods
 s4JvcMqB3kUNBZaMsFVXTKdqT1PufICS+gx0VsKdKDwXcOHwMS10nTlEOPzqvoBA
 phAsEbjnjWVhf03XTfCus+l5NT96lswCzPcUovb3CitSc2A1KUye3TyzHnxIqmOt
 Owcl+Oiso++cgYzr/BCveTAYKYoRZzVcq5jCl4bBUH/8sLrRDbT0cpFpcMk72eE9
 VhR00kbkDfL3nKrulLsG8FeUlisX5+oGb3G5AdPtU9sqJPJMmBGaF+KniI0wi7VN
 5teHq08upLMF5JAjiKzZIA==
 =faXD
 -----END PGP SIGNATURE-----

Merge tag 'pull-target-arm-20240701' of https://git.linaro.org/people/pmaydell/qemu-arm into staging

target-arm queue:
 * tests/avocado: update firmware for sbsa-ref and use all cores
 * hw/arm/smmu-common: Replace smmu_iommu_mr with smmu_find_sdev
 * arm: Fix VCMLA Dd, Dn, Dm[idx]
 * arm: Fix SQDMULH (by element) with Q=0
 * arm: Fix FJCVTZS vs flush-to-zero
 * arm: More conversion of A64 AdvSIMD to decodetree
 * arm: Enable FEAT_Debugv8p8 for -cpu max
 * MAINTAINERS: Update family name for Patrick Leis
 * hw/arm/xilinx_zynq: Add boot-mode property
 * docs/system/arm: Add a doc for zynq board
 * hw/misc: In STM32L4x5 EXTI, correct configurable interrupts
 * tests/qtest: fix minor issues in STM32L4x5 tests

# -----BEGIN PGP SIGNATURE-----
#
# iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmaC1BMZHHBldGVyLm1h
# eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3nDOEACCoewjO2FJ4RFXMSmgr0Zf
# jxWliu7osw7oeG4ZNq1+xMiXeW0vyS54eW41TMki1f98N/yK8v55BM8kBBvDvZaz
# R5DUXpN+MtwD9A62md3B2c4mFXHqk1UOGbKi4btbtFj4lS8pV51mPmApzBUr2iTj
# w6dCLciLOt87NWgtLECXsZ3evn+VlTRc+Hmfp1M/C/Rf2Qx3zis/CFHGQsZLGwzG
# 2WhTpU1BKeOfsQa1VbSX6un14d72/JATFZN3rSgMbOEbvsCEeP+rnkzX57ejGyxV
# 4DUx69gEAqS5bOfkQHLwy82WsunD/oIgp+GpYaYgINHzh6UkEsPoymrHAaPgV1Vh
# g0TaBtbv2p89RFY1C2W2Mi4ICQ14a+oIV9FPvDsOE8Wq+wDAy/ZxZs7G6flxqods
# s4JvcMqB3kUNBZaMsFVXTKdqT1PufICS+gx0VsKdKDwXcOHwMS10nTlEOPzqvoBA
# phAsEbjnjWVhf03XTfCus+l5NT96lswCzPcUovb3CitSc2A1KUye3TyzHnxIqmOt
# Owcl+Oiso++cgYzr/BCveTAYKYoRZzVcq5jCl4bBUH/8sLrRDbT0cpFpcMk72eE9
# VhR00kbkDfL3nKrulLsG8FeUlisX5+oGb3G5AdPtU9sqJPJMmBGaF+KniI0wi7VN
# 5teHq08upLMF5JAjiKzZIA==
# =faXD
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 01 Jul 2024 09:06:43 AM PDT
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full]
# gpg:                 aka "Peter Maydell <peter@archaic.org.uk>" [unknown]

* tag 'pull-target-arm-20240701' of https://git.linaro.org/people/pmaydell/qemu-arm: (29 commits)
  tests/qtest: Ensure STM32L4x5 EXTI state is correct at the end of QTests
  hw/misc: In STM32L4x5 EXTI, correct configurable interrupts
  tests/qtest: Fix STM32L4x5 SYSCFG irq line 15 state assumption
  docs/system/arm: Add a doc for zynq board
  hw/arm/xilinx_zynq: Add boot-mode property
  hw/misc/zynq_slcr: Add boot-mode property
  MAINTAINERS: Update my family name
  target/arm: Enable FEAT_Debugv8p8 for -cpu max
  target/arm: Move initialization of debug ID registers
  target/arm: Fix indentation
  target/arm: Delete dead code from disas_simd_indexed
  target/arm: Convert FCMLA to decodetree
  target/arm: Convert FCADD to decodetree
  target/arm: Add data argument to do_fp3_vector
  target/arm: Convert BFMMLA, SMMLA, UMMLA, USMMLA to decodetree
  target/arm: Convert BFMLALB, BFMLALT to decodetree
  target/arm: Convert BFDOT to decodetree
  target/arm: Convert SUDOT, USDOT to decodetree
  target/arm: Convert SDOT, UDOT to decodetree
  target/arm: Convert SQRDMLAH, SQRDMLSH to decodetree
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2024-07-01 10:41:45 -07:00
commit c80a339587
32 changed files with 967 additions and 641 deletions

View File

@ -1033,6 +1033,7 @@ F: hw/adc/zynq-xadc.c
F: include/hw/misc/zynq_slcr.h
F: include/hw/adc/zynq-xadc.h
X: hw/ssi/xilinx_*
F: docs/system/arm/xlnx-zynq.rst
Xilinx ZynqMP and Versal
M: Alistair Francis <alistair@alistair23.me>
@ -2496,7 +2497,7 @@ F: hw/net/tulip.c
F: hw/net/tulip.h
pca954x
M: Patrick Venture <venture@google.com>
M: Patrick Leis <venture@google.com>
S: Maintained
F: hw/i2c/i2c_mux_pca954x.c
F: include/hw/i2c/i2c_mux_pca954x.h

View File

@ -41,6 +41,7 @@ the following architecture extensions:
- FEAT_Debugv8p1 (Debug with VHE)
- FEAT_Debugv8p2 (Debug changes for v8.2)
- FEAT_Debugv8p4 (Debug changes for v8.4)
- FEAT_Debugv8p8 (Debug changes for v8.8)
- FEAT_DotProd (Advanced SIMD dot product instructions)
- FEAT_DoubleFault (Double Fault Extension)
- FEAT_E0PD (Preventing EL0 access to halves of address maps)

View File

@ -0,0 +1,47 @@
Xilinx Zynq board (``xilinx-zynq-a9``)
======================================
The Zynq 7000 family is based on the AMD SoC architecture. These products
integrate a feature-rich dual or single-core Arm Cortex-A9 MPCore based
processing system (PS) and AMD programmable logic (PL) in a single device.
More details here:
https://docs.amd.com/r/en-US/ug585-zynq-7000-SoC-TRM/Zynq-7000-SoC-Technical-Reference-Manual
QEMU xilinx-zynq-a9 board supports following devices:
- A9 MPCORE
- cortex-a9
- GIC v1
- Generic timer
- wdt
- OCM 256KB
- SMC SRAM@0xe2000000 64MB
- Zynq SLCR
- SPI x2
- QSPI
- UART
- TTC x2
- Gigabit Ethernet Controller x2
- SD Controller x2
- XADC
- Arm PrimeCell DMA Controller
- DDR Memory
- USB 2.0 x2
Running
"""""""
Direct Linux boot of a generic ARM upstream Linux kernel:
.. code-block:: bash
$ qemu-system-aarch64 -M xilinx-zynq-a9 \
-dtb zynq-zc702.dtb -serial null -serial mon:stdio \
-display none -m 1024 \
-initrd rootfs.cpio.gz -kernel zImage
For configuring the boot-mode provide the following on the command line:
.. code-block:: bash
-machine boot-mode=qspi
Supported values are jtag, sd, qspi, nor.

View File

@ -109,6 +109,7 @@ undocumented; you can get a complete list by running
arm/virt
arm/xenpvh
arm/xlnx-versal-virt
arm/xlnx-zynq
Emulated CPU architecture support
=================================

View File

@ -116,6 +116,10 @@ static void raspi_peripherals_base_init(Object *obj)
object_property_add_const_link(OBJECT(&s->fb), "dma-mr",
OBJECT(&s->gpu_bus_mr));
/* OTP */
object_initialize_child(obj, "bcm2835-otp", &s->otp,
TYPE_BCM2835_OTP);
/* Property channel */
object_initialize_child(obj, "property", &s->property,
TYPE_BCM2835_PROPERTY);
@ -128,6 +132,8 @@ static void raspi_peripherals_base_init(Object *obj)
OBJECT(&s->fb));
object_property_add_const_link(OBJECT(&s->property), "dma-mr",
OBJECT(&s->gpu_bus_mr));
object_property_add_const_link(OBJECT(&s->property), "otp",
OBJECT(&s->otp));
/* Extended Mass Media Controller */
object_initialize_child(obj, "sdhci", &s->sdhci, TYPE_SYSBUS_SDHCI);
@ -374,6 +380,14 @@ void bcm_soc_peripherals_common_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->fb), 0,
qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_FB));
/* OTP */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->otp), errp)) {
return;
}
memory_region_add_subregion(&s->peri_mr, OTP_OFFSET,
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->otp), 0));
/* Property channel */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->property), errp)) {
return;
@ -500,7 +514,6 @@ void bcm_soc_peripherals_common_realize(DeviceState *dev, Error **errp)
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
create_unimp(s, &s->bscsl, "bcm2835-spis", BSC_SL_OFFSET, 0x100);
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->v3d, "bcm2835-v3d", V3D_OFFSET, 0x1000);

View File

@ -620,20 +620,16 @@ static const PCIIOMMUOps smmu_ops = {
.get_address_space = smmu_find_add_as,
};
IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid)
SMMUDevice *smmu_find_sdev(SMMUState *s, uint32_t sid)
{
uint8_t bus_n, devfn;
SMMUPciBus *smmu_bus;
SMMUDevice *smmu;
bus_n = PCI_BUS_NUM(sid);
smmu_bus = smmu_find_smmu_pcibus(s, bus_n);
if (smmu_bus) {
devfn = SMMU_PCI_DEVFN(sid);
smmu = smmu_bus->pbdev[devfn];
if (smmu) {
return &smmu->iommu;
}
return smmu_bus->pbdev[devfn];
}
return NULL;
}

View File

@ -1218,20 +1218,18 @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
case SMMU_CMD_CFGI_STE:
{
uint32_t sid = CMD_SID(&cmd);
IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid);
SMMUDevice *sdev;
SMMUDevice *sdev = smmu_find_sdev(bs, sid);
if (CMD_SSEC(&cmd)) {
cmd_error = SMMU_CERROR_ILL;
break;
}
if (!mr) {
if (!sdev) {
break;
}
trace_smmuv3_cmdq_cfgi_ste(sid);
sdev = container_of(mr, SMMUDevice, iommu);
smmuv3_flush_config(sdev);
break;
@ -1260,20 +1258,18 @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
case SMMU_CMD_CFGI_CD_ALL:
{
uint32_t sid = CMD_SID(&cmd);
IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid);
SMMUDevice *sdev;
SMMUDevice *sdev = smmu_find_sdev(bs, sid);
if (CMD_SSEC(&cmd)) {
cmd_error = SMMU_CERROR_ILL;
break;
}
if (!mr) {
if (!sdev) {
break;
}
trace_smmuv3_cmdq_cfgi_cd(sid);
sdev = container_of(mr, SMMUDevice, iommu);
smmuv3_flush_config(sdev);
break;
}

View File

@ -38,6 +38,7 @@
#include "qom/object.h"
#include "exec/tswap.h"
#include "target/arm/cpu-qom.h"
#include "qapi/visitor.h"
#define TYPE_ZYNQ_MACHINE MACHINE_TYPE_NAME("xilinx-zynq-a9")
OBJECT_DECLARE_SIMPLE_TYPE(ZynqMachineState, ZYNQ_MACHINE)
@ -90,6 +91,7 @@ struct ZynqMachineState {
MachineState parent;
Clock *ps_clk;
ARMCPU *cpu[ZYNQ_MAX_CPUS];
uint8_t boot_mode;
};
static void zynq_write_board_setup(ARMCPU *cpu,
@ -176,6 +178,27 @@ static inline int zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq,
return unit;
}
static void zynq_set_boot_mode(Object *obj, const char *str,
Error **errp)
{
ZynqMachineState *m = ZYNQ_MACHINE(obj);
uint8_t mode = 0;
if (!strncasecmp(str, "qspi", 4)) {
mode = 1;
} else if (!strncasecmp(str, "sd", 2)) {
mode = 5;
} else if (!strncasecmp(str, "nor", 3)) {
mode = 2;
} else if (!strncasecmp(str, "jtag", 4)) {
mode = 0;
} else {
error_setg(errp, "%s boot mode not supported", str);
return;
}
m->boot_mode = mode;
}
static void zynq_init(MachineState *machine)
{
ZynqMachineState *zynq_machine = ZYNQ_MACHINE(machine);
@ -241,6 +264,7 @@ static void zynq_init(MachineState *machine)
/* Create slcr, keep a pointer to connect clocks */
slcr = qdev_new("xilinx-zynq_slcr");
qdev_connect_clock_in(slcr, "ps_clk", zynq_machine->ps_clk);
qdev_prop_set_uint8(slcr, "boot-mode", zynq_machine->boot_mode);
sysbus_realize_and_unref(SYS_BUS_DEVICE(slcr), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(slcr), 0, 0xF8000000);
@ -373,6 +397,7 @@ static void zynq_machine_class_init(ObjectClass *oc, void *data)
NULL
};
MachineClass *mc = MACHINE_CLASS(oc);
ObjectProperty *prop;
mc->desc = "Xilinx Zynq Platform Baseboard for Cortex-A9";
mc->init = zynq_init;
mc->max_cpus = ZYNQ_MAX_CPUS;
@ -380,6 +405,12 @@ static void zynq_machine_class_init(ObjectClass *oc, void *data)
mc->ignore_memory_transaction_failures = true;
mc->valid_cpu_types = valid_cpu_types;
mc->default_ram_id = "zynq.ext_ram";
prop = object_class_property_add_str(oc, "boot-mode", NULL,
zynq_set_boot_mode);
object_class_property_set_description(oc, "boot-mode",
"Supported boot modes:"
" jtag qspi sd nor");
object_property_set_default_str(prop, "qspi");
}
static const TypeInfo zynq_machine_type = {

View File

@ -32,6 +32,7 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
uint32_t tmp;
int n;
uint32_t offset, length, color;
uint32_t start_num, number, otp_row;
/*
* Copy the current state of the framebuffer config; we will update
@ -322,6 +323,89 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
0);
resplen = VCHI_BUSADDR_SIZE;
break;
/* Customer OTP */
case RPI_FWREQ_GET_CUSTOMER_OTP:
start_num = ldl_le_phys(&s->dma_as, value + 12);
number = ldl_le_phys(&s->dma_as, value + 16);
resplen = 8 + 4 * number;
for (n = start_num; n < start_num + number &&
n < BCM2835_OTP_CUSTOMER_OTP_LEN; n++) {
otp_row = bcm2835_otp_get_row(s->otp,
BCM2835_OTP_CUSTOMER_OTP + n);
stl_le_phys(&s->dma_as,
value + 20 + ((n - start_num) << 2), otp_row);
}
break;
case RPI_FWREQ_SET_CUSTOMER_OTP:
start_num = ldl_le_phys(&s->dma_as, value + 12);
number = ldl_le_phys(&s->dma_as, value + 16);
resplen = 4;
/* Magic numbers to permanently lock customer OTP */
if (start_num == BCM2835_OTP_LOCK_NUM1 &&
number == BCM2835_OTP_LOCK_NUM2) {
bcm2835_otp_set_row(s->otp,
BCM2835_OTP_ROW_32,
BCM2835_OTP_ROW_32_LOCK);
break;
}
/* If row 32 has the lock bit, don't allow further writes */
if (bcm2835_otp_get_row(s->otp, BCM2835_OTP_ROW_32) &
BCM2835_OTP_ROW_32_LOCK) {
break;
}
for (n = start_num; n < start_num + number &&
n < BCM2835_OTP_CUSTOMER_OTP_LEN; n++) {
otp_row = ldl_le_phys(&s->dma_as,
value + 20 + ((n - start_num) << 2));
bcm2835_otp_set_row(s->otp,
BCM2835_OTP_CUSTOMER_OTP + n, otp_row);
}
break;
/* Device-specific private key */
case RPI_FWREQ_GET_PRIVATE_KEY:
start_num = ldl_le_phys(&s->dma_as, value + 12);
number = ldl_le_phys(&s->dma_as, value + 16);
resplen = 8 + 4 * number;
for (n = start_num; n < start_num + number &&
n < BCM2835_OTP_PRIVATE_KEY_LEN; n++) {
otp_row = bcm2835_otp_get_row(s->otp,
BCM2835_OTP_PRIVATE_KEY + n);
stl_le_phys(&s->dma_as,
value + 20 + ((n - start_num) << 2), otp_row);
}
break;
case RPI_FWREQ_SET_PRIVATE_KEY:
start_num = ldl_le_phys(&s->dma_as, value + 12);
number = ldl_le_phys(&s->dma_as, value + 16);
resplen = 4;
/* If row 32 has the lock bit, don't allow further writes */
if (bcm2835_otp_get_row(s->otp, BCM2835_OTP_ROW_32) &
BCM2835_OTP_ROW_32_LOCK) {
break;
}
for (n = start_num; n < start_num + number &&
n < BCM2835_OTP_PRIVATE_KEY_LEN; n++) {
otp_row = ldl_le_phys(&s->dma_as,
value + 20 + ((n - start_num) << 2));
bcm2835_otp_set_row(s->otp,
BCM2835_OTP_PRIVATE_KEY + n, otp_row);
}
break;
default:
qemu_log_mask(LOG_UNIMP,
"bcm2835_property: unhandled tag 0x%08x\n", tag);
@ -449,6 +533,9 @@ static void bcm2835_property_realize(DeviceState *dev, Error **errp)
s->dma_mr = MEMORY_REGION(obj);
address_space_init(&s->dma_as, s->dma_mr, TYPE_BCM2835_PROPERTY "-memory");
obj = object_property_get_link(OBJECT(dev), "otp", &error_abort);
s->otp = BCM2835_OTP(obj);
/* TODO: connect to MAC address of USB NIC device, once we emulate it */
qemu_macaddr_default_if_unset(&s->macaddr);

View File

@ -88,6 +88,7 @@ static void stm32l4x5_exti_reset_hold(Object *obj, ResetType type)
s->ftsr[bank] = 0x00000000;
s->swier[bank] = 0x00000000;
s->pr[bank] = 0x00000000;
s->irq_levels[bank] = 0x00000000;
}
}
@ -102,27 +103,23 @@ static void stm32l4x5_exti_set_irq(void *opaque, int irq, int level)
/* Shift the value to enable access in x2 registers. */
irq %= EXTI_MAX_IRQ_PER_BANK;
if (level == extract32(s->irq_levels[bank], irq, 1)) {
/* No change in IRQ line state: do nothing */
return;
}
s->irq_levels[bank] = deposit32(s->irq_levels[bank], irq, 1, level);
/* If the interrupt is masked, pr won't be raised */
if (!extract32(s->imr[bank], irq, 1)) {
return;
}
if (((1 << irq) & s->rtsr[bank]) && level) {
/* Rising Edge */
s->pr[bank] |= 1 << irq;
qemu_irq_pulse(s->irq[oirq]);
} else if (((1 << irq) & s->ftsr[bank]) && !level) {
/* Falling Edge */
if ((level && extract32(s->rtsr[bank], irq, 1)) ||
(!level && extract32(s->ftsr[bank], irq, 1))) {
s->pr[bank] |= 1 << irq;
qemu_irq_pulse(s->irq[oirq]);
}
/*
* In the following situations :
* - falling edge but rising trigger selected
* - rising edge but falling trigger selected
* - no trigger selected
* No action is required
*/
}
static uint64_t stm32l4x5_exti_read(void *opaque, hwaddr addr,
@ -255,8 +252,8 @@ static void stm32l4x5_exti_init(Object *obj)
static const VMStateDescription vmstate_stm32l4x5_exti = {
.name = TYPE_STM32L4X5_EXTI,
.version_id = 1,
.minimum_version_id = 1,
.version_id = 2,
.minimum_version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(imr, Stm32l4x5ExtiState, EXTI_NUM_REGISTER),
VMSTATE_UINT32_ARRAY(emr, Stm32l4x5ExtiState, EXTI_NUM_REGISTER),
@ -264,6 +261,7 @@ static const VMStateDescription vmstate_stm32l4x5_exti = {
VMSTATE_UINT32_ARRAY(ftsr, Stm32l4x5ExtiState, EXTI_NUM_REGISTER),
VMSTATE_UINT32_ARRAY(swier, Stm32l4x5ExtiState, EXTI_NUM_REGISTER),
VMSTATE_UINT32_ARRAY(pr, Stm32l4x5ExtiState, EXTI_NUM_REGISTER),
VMSTATE_UINT32_ARRAY(irq_levels, Stm32l4x5ExtiState, EXTI_NUM_REGISTER),
VMSTATE_END_OF_LIST()
}
};

View File

@ -24,6 +24,8 @@
#include "hw/registerfields.h"
#include "hw/qdev-clock.h"
#include "qom/object.h"
#include "hw/qdev-properties.h"
#include "qapi/error.h"
#ifndef ZYNQ_SLCR_ERR_DEBUG
#define ZYNQ_SLCR_ERR_DEBUG 0
@ -121,6 +123,7 @@ REG32(RST_REASON, 0x250)
REG32(REBOOT_STATUS, 0x258)
REG32(BOOT_MODE, 0x25c)
FIELD(BOOT_MODE, BOOT_MODE, 0, 4)
REG32(APU_CTRL, 0x300)
REG32(WDT_CLK_SEL, 0x304)
@ -195,6 +198,7 @@ struct ZynqSLCRState {
Clock *ps_clk;
Clock *uart0_ref_clk;
Clock *uart1_ref_clk;
uint8_t boot_mode;
};
/*
@ -371,7 +375,7 @@ static void zynq_slcr_reset_init(Object *obj, ResetType type)
s->regs[R_FPGA_RST_CTRL] = 0x01F33F0F;
s->regs[R_RST_REASON] = 0x00000040;
s->regs[R_BOOT_MODE] = 0x00000001;
s->regs[R_BOOT_MODE] = s->boot_mode & R_BOOT_MODE_BOOT_MODE_MASK;
/* 0x700 - 0x7D4 */
for (i = 0; i < 54; i++) {
@ -588,6 +592,15 @@ static const ClockPortInitArray zynq_slcr_clocks = {
QDEV_CLOCK_END
};
static void zynq_slcr_realize(DeviceState *dev, Error **errp)
{
ZynqSLCRState *s = ZYNQ_SLCR(dev);
if (s->boot_mode > 0xF) {
error_setg(errp, "Invalid boot mode %d specified", s->boot_mode);
}
}
static void zynq_slcr_init(Object *obj)
{
ZynqSLCRState *s = ZYNQ_SLCR(obj);
@ -610,15 +623,22 @@ static const VMStateDescription vmstate_zynq_slcr = {
}
};
static Property zynq_slcr_props[] = {
DEFINE_PROP_UINT8("boot-mode", ZynqSLCRState, boot_mode, 1),
DEFINE_PROP_END_OF_LIST(),
};
static void zynq_slcr_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
ResettableClass *rc = RESETTABLE_CLASS(klass);
dc->vmsd = &vmstate_zynq_slcr;
dc->realize = zynq_slcr_realize;
rc->phases.enter = zynq_slcr_reset_init;
rc->phases.hold = zynq_slcr_reset_hold;
rc->phases.exit = zynq_slcr_reset_exit;
device_class_set_props(dc, zynq_slcr_props);
}
static const TypeInfo zynq_slcr_info = {

187
hw/nvram/bcm2835_otp.c Normal file
View File

@ -0,0 +1,187 @@
/*
* BCM2835 One-Time Programmable (OTP) Memory
*
* The OTP implementation is mostly a stub except for the OTP rows
* which are accessed directly by other peripherals such as the mailbox.
*
* The OTP registers are unimplemented due to lack of documentation.
*
* Copyright (c) 2024 Rayhan Faizel <rayhan.faizel@gmail.com>
*
* SPDX-License-Identifier: MIT
*/
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/nvram/bcm2835_otp.h"
#include "migration/vmstate.h"
/* OTP rows are 1-indexed */
uint32_t bcm2835_otp_get_row(BCM2835OTPState *s, unsigned int row)
{
assert(row <= BCM2835_OTP_ROW_COUNT && row >= 1);
return s->otp_rows[row - 1];
}
void bcm2835_otp_set_row(BCM2835OTPState *s, unsigned int row,
uint32_t value)
{
assert(row <= BCM2835_OTP_ROW_COUNT && row >= 1);
/* Real OTP rows work as e-fuses */
s->otp_rows[row - 1] |= value;
}
static uint64_t bcm2835_otp_read(void *opaque, hwaddr addr, unsigned size)
{
switch (addr) {
case BCM2835_OTP_BOOTMODE_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_BOOTMODE_REG\n");
break;
case BCM2835_OTP_CONFIG_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_CONFIG_REG\n");
break;
case BCM2835_OTP_CTRL_LO_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_CTRL_LO_REG\n");
break;
case BCM2835_OTP_CTRL_HI_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_CTRL_HI_REG\n");
break;
case BCM2835_OTP_STATUS_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_STATUS_REG\n");
break;
case BCM2835_OTP_BITSEL_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_BITSEL_REG\n");
break;
case BCM2835_OTP_DATA_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_DATA_REG\n");
break;
case BCM2835_OTP_ADDR_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_ADDR_REG\n");
break;
case BCM2835_OTP_WRITE_DATA_READ_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_WRITE_DATA_READ_REG\n");
break;
case BCM2835_OTP_INIT_STATUS_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_INIT_STATUS_REG\n");
break;
default:
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr);
}
return 0;
}
static void bcm2835_otp_write(void *opaque, hwaddr addr,
uint64_t value, unsigned int size)
{
switch (addr) {
case BCM2835_OTP_BOOTMODE_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_BOOTMODE_REG\n");
break;
case BCM2835_OTP_CONFIG_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_CONFIG_REG\n");
break;
case BCM2835_OTP_CTRL_LO_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_CTRL_LO_REG\n");
break;
case BCM2835_OTP_CTRL_HI_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_CTRL_HI_REG\n");
break;
case BCM2835_OTP_STATUS_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_STATUS_REG\n");
break;
case BCM2835_OTP_BITSEL_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_BITSEL_REG\n");
break;
case BCM2835_OTP_DATA_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_DATA_REG\n");
break;
case BCM2835_OTP_ADDR_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_ADDR_REG\n");
break;
case BCM2835_OTP_WRITE_DATA_READ_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_WRITE_DATA_READ_REG\n");
break;
case BCM2835_OTP_INIT_STATUS_REG:
qemu_log_mask(LOG_UNIMP,
"bcm2835_otp: BCM2835_OTP_INIT_STATUS_REG\n");
break;
default:
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr);
}
}
static const MemoryRegionOps bcm2835_otp_ops = {
.read = bcm2835_otp_read,
.write = bcm2835_otp_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 4,
.max_access_size = 4,
},
};
static void bcm2835_otp_realize(DeviceState *dev, Error **errp)
{
BCM2835OTPState *s = BCM2835_OTP(dev);
memory_region_init_io(&s->iomem, OBJECT(dev), &bcm2835_otp_ops, s,
TYPE_BCM2835_OTP, 0x80);
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
memset(s->otp_rows, 0x00, sizeof(s->otp_rows));
}
static const VMStateDescription vmstate_bcm2835_otp = {
.name = TYPE_BCM2835_OTP,
.version_id = 1,
.minimum_version_id = 1,
.fields = (const VMStateField[]) {
VMSTATE_UINT32_ARRAY(otp_rows, BCM2835OTPState, BCM2835_OTP_ROW_COUNT),
VMSTATE_END_OF_LIST()
}
};
static void bcm2835_otp_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = bcm2835_otp_realize;
dc->vmsd = &vmstate_bcm2835_otp;
}
static const TypeInfo bcm2835_otp_info = {
.name = TYPE_BCM2835_OTP,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(BCM2835OTPState),
.class_init = bcm2835_otp_class_init,
};
static void bcm2835_otp_register_types(void)
{
type_register_static(&bcm2835_otp_info);
}
type_init(bcm2835_otp_register_types)

View File

@ -1,5 +1,6 @@
system_ss.add(files('fw_cfg-interface.c'))
system_ss.add(files('fw_cfg.c'))
system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_otp.c'))
system_ss.add(when: 'CONFIG_CHRP_NVRAM', if_true: files('chrp_nvram.c'))
system_ss.add(when: 'CONFIG_DS1225Y', if_true: files('ds1225y.c'))
system_ss.add(when: 'CONFIG_NMC93XX_EEPROM', if_true: files('eeprom93xx.c'))

View File

@ -33,6 +33,7 @@
#include "hw/usb/hcd-dwc2.h"
#include "hw/ssi/bcm2835_spi.h"
#include "hw/i2c/bcm2835_i2c.h"
#include "hw/nvram/bcm2835_otp.h"
#include "hw/misc/unimp.h"
#include "qom/object.h"
@ -71,7 +72,7 @@ struct BCMSocPeripheralBaseState {
BCM2835SPIState spi[1];
BCM2835I2CState i2c[3];
OrIRQState orgated_i2c_irq;
UnimplementedDeviceState otp;
BCM2835OTPState otp;
UnimplementedDeviceState dbus;
UnimplementedDeviceState ave0;
UnimplementedDeviceState v3d;

View File

@ -56,6 +56,7 @@ enum rpi_firmware_property_tag {
RPI_FWREQ_GET_THROTTLED = 0x00030046,
RPI_FWREQ_GET_CLOCK_MEASURED = 0x00030047,
RPI_FWREQ_NOTIFY_REBOOT = 0x00030048,
RPI_FWREQ_GET_PRIVATE_KEY = 0x00030081,
RPI_FWREQ_SET_CLOCK_STATE = 0x00038001,
RPI_FWREQ_SET_CLOCK_RATE = 0x00038002,
RPI_FWREQ_SET_VOLTAGE = 0x00038003,
@ -73,6 +74,7 @@ enum rpi_firmware_property_tag {
RPI_FWREQ_SET_PERIPH_REG = 0x00038045,
RPI_FWREQ_GET_POE_HAT_VAL = 0x00030049,
RPI_FWREQ_SET_POE_HAT_VAL = 0x00038049,
RPI_FWREQ_SET_PRIVATE_KEY = 0x00038081,
RPI_FWREQ_SET_POE_HAT_VAL_OLD = 0x00030050,
RPI_FWREQ_NOTIFY_XHCI_RESET = 0x00030058,
RPI_FWREQ_GET_REBOOT_FLAGS = 0x00030064,

View File

@ -182,8 +182,8 @@ int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
*/
SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova);
/* Return the iommu mr associated to @sid, or NULL if none */
IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid);
/* Return the SMMUDevice associated to @sid, or NULL if none */
SMMUDevice *smmu_find_sdev(SMMUState *s, uint32_t sid);
#define SMMU_IOTLB_MAX_SIZE 256

View File

@ -11,6 +11,7 @@
#include "hw/sysbus.h"
#include "net/net.h"
#include "hw/display/bcm2835_fb.h"
#include "hw/nvram/bcm2835_otp.h"
#include "qom/object.h"
#define TYPE_BCM2835_PROPERTY "bcm2835-property"
@ -26,6 +27,7 @@ struct BCM2835PropertyState {
MemoryRegion iomem;
qemu_irq mbox_irq;
BCM2835FBState *fbdev;
BCM2835OTPState *otp;
MACAddr macaddr;
uint32_t board_rev;

View File

@ -45,6 +45,8 @@ struct Stm32l4x5ExtiState {
uint32_t swier[EXTI_NUM_REGISTER];
uint32_t pr[EXTI_NUM_REGISTER];
/* used for edge detection */
uint32_t irq_levels[EXTI_NUM_REGISTER];
qemu_irq irq[EXTI_NUM_INTERRUPT_OUT_LINES];
};

View File

@ -0,0 +1,68 @@
/*
* BCM2835 One-Time Programmable (OTP) Memory
*
* Copyright (c) 2024 Rayhan Faizel <rayhan.faizel@gmail.com>
*
* SPDX-License-Identifier: MIT
*/
#ifndef BCM2835_OTP_H
#define BCM2835_OTP_H
#include "hw/sysbus.h"
#include "qom/object.h"
#define TYPE_BCM2835_OTP "bcm2835-otp"
OBJECT_DECLARE_SIMPLE_TYPE(BCM2835OTPState, BCM2835_OTP)
#define BCM2835_OTP_ROW_COUNT 66
/* https://elinux.org/BCM2835_registers#OTP */
#define BCM2835_OTP_BOOTMODE_REG 0x00
#define BCM2835_OTP_CONFIG_REG 0x04
#define BCM2835_OTP_CTRL_LO_REG 0x08
#define BCM2835_OTP_CTRL_HI_REG 0x0c
#define BCM2835_OTP_STATUS_REG 0x10
#define BCM2835_OTP_BITSEL_REG 0x14
#define BCM2835_OTP_DATA_REG 0x18
#define BCM2835_OTP_ADDR_REG 0x1c
#define BCM2835_OTP_WRITE_DATA_READ_REG 0x20
#define BCM2835_OTP_INIT_STATUS_REG 0x24
/* -- Row 32: Undocumented -- */
#define BCM2835_OTP_ROW_32 32
/* Lock OTP Programming (Customer OTP and private key) */
#define BCM2835_OTP_ROW_32_LOCK BIT(6)
/* -- Row 36-43: Customer OTP -- */
#define BCM2835_OTP_CUSTOMER_OTP 36
#define BCM2835_OTP_CUSTOMER_OTP_LEN 8
/* Magic numbers to lock programming of customer OTP and private key */
#define BCM2835_OTP_LOCK_NUM1 0xffffffff
#define BCM2835_OTP_LOCK_NUM2 0xaffe0000
/* -- Row 56-63: Device-specific private key -- */
#define BCM2835_OTP_PRIVATE_KEY 56
#define BCM2835_OTP_PRIVATE_KEY_LEN 8
struct BCM2835OTPState {
/* <private> */
SysBusDevice parent_obj;
/* <public> */
MemoryRegion iomem;
uint32_t otp_rows[BCM2835_OTP_ROW_COUNT];
};
uint32_t bcm2835_otp_get_row(BCM2835OTPState *s, unsigned int row);
void bcm2835_otp_set_row(BCM2835OTPState *s, unsigned int row, uint32_t value);
#endif

View File

@ -2299,6 +2299,8 @@ FIELD(DBGDEVID, DOUBLELOCK, 20, 4)
FIELD(DBGDEVID, AUXREGS, 24, 4)
FIELD(DBGDEVID, CIDMASK, 28, 4)
FIELD(DBGDEVID1, PCSROFFSET, 0, 4)
FIELD(MVFR0, SIMDREG, 0, 4)
FIELD(MVFR0, FPSP, 4, 4)
FIELD(MVFR0, FPDP, 8, 4)

View File

@ -979,6 +979,16 @@ DEF_HELPER_FLAGS_5(neon_sqrdmulh_idx_h, TCG_CALL_NO_RWG,
DEF_HELPER_FLAGS_5(neon_sqrdmulh_idx_s, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(neon_sqrdmlah_idx_h, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(neon_sqrdmlah_idx_s, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(neon_sqrdmlsh_idx_h, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(neon_sqrdmlsh_idx_s, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(sve2_sqdmulh_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(sve2_sqdmulh_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(sve2_sqdmulh_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)

View File

@ -61,6 +61,7 @@
@qrrr_b . q:1 ...... ... rm:5 ...... rn:5 rd:5 &qrrr_e esz=0
@qrrr_h . q:1 ...... ... rm:5 ...... rn:5 rd:5 &qrrr_e esz=1
@qrrr_s . q:1 ...... ... rm:5 ...... rn:5 rd:5 &qrrr_e esz=2
@qrrr_sd . q:1 ...... ... rm:5 ...... rn:5 rd:5 &qrrr_e esz=%esz_sd
@qrrr_e . q:1 ...... esz:2 . rm:5 ...... rn:5 rd:5 &qrrr_e
@qr2r_e . q:1 ...... esz:2 . ..... ...... rm:5 rd:5 &qrrr_e rn=%rd
@ -781,6 +782,8 @@ CMEQ_s 0111 1110 111 ..... 10001 1 ..... ..... @rrr_d
SQDMULH_s 0101 1110 ..1 ..... 10110 1 ..... ..... @rrr_e
SQRDMULH_s 0111 1110 ..1 ..... 10110 1 ..... ..... @rrr_e
SQRDMLAH_s 0111 1110 ..0 ..... 10000 1 ..... ..... @rrr_e
SQRDMLSH_s 0111 1110 ..0 ..... 10001 1 ..... ..... @rrr_e
### Advanced SIMD scalar pairwise
@ -941,6 +944,23 @@ MLS_v 0.10 1110 ..1 ..... 10010 1 ..... ..... @qrrr_e
SQDMULH_v 0.00 1110 ..1 ..... 10110 1 ..... ..... @qrrr_e
SQRDMULH_v 0.10 1110 ..1 ..... 10110 1 ..... ..... @qrrr_e
SQRDMLAH_v 0.10 1110 ..0 ..... 10000 1 ..... ..... @qrrr_e
SQRDMLSH_v 0.10 1110 ..0 ..... 10001 1 ..... ..... @qrrr_e
SDOT_v 0.00 1110 100 ..... 10010 1 ..... ..... @qrrr_s
UDOT_v 0.10 1110 100 ..... 10010 1 ..... ..... @qrrr_s
USDOT_v 0.00 1110 100 ..... 10011 1 ..... ..... @qrrr_s
BFDOT_v 0.10 1110 010 ..... 11111 1 ..... ..... @qrrr_s
BFMLAL_v 0.10 1110 110 ..... 11111 1 ..... ..... @qrrr_h
BFMMLA 0110 1110 010 ..... 11101 1 ..... ..... @rrr_q1e0
SMMLA 0100 1110 100 ..... 10100 1 ..... ..... @rrr_q1e0
UMMLA 0110 1110 100 ..... 10100 1 ..... ..... @rrr_q1e0
USMMLA 0100 1110 100 ..... 10101 1 ..... ..... @rrr_q1e0
FCADD_90 0.10 1110 ..0 ..... 11100 1 ..... ..... @qrrr_e
FCADD_270 0.10 1110 ..0 ..... 11110 1 ..... ..... @qrrr_e
FCMLA_v 0 q:1 10 1110 esz:2 0 rm:5 110 rot:2 1 rn:5 rd:5
### Advanced SIMD scalar x indexed element
@ -966,6 +986,12 @@ SQDMULH_si 0101 1111 10 .. .... 1100 . 0 ..... ..... @rrx_s
SQRDMULH_si 0101 1111 01 .. .... 1101 . 0 ..... ..... @rrx_h
SQRDMULH_si 0101 1111 10 . ..... 1101 . 0 ..... ..... @rrx_s
SQRDMLAH_si 0111 1111 01 .. .... 1101 . 0 ..... ..... @rrx_h
SQRDMLAH_si 0111 1111 10 .. .... 1101 . 0 ..... ..... @rrx_s
SQRDMLSH_si 0111 1111 01 .. .... 1111 . 0 ..... ..... @rrx_h
SQRDMLSH_si 0111 1111 10 .. .... 1111 . 0 ..... ..... @rrx_s
### Advanced SIMD vector x indexed element
FMUL_vi 0.00 1111 00 .. .... 1001 . 0 ..... ..... @qrrx_h
@ -1004,6 +1030,23 @@ SQDMULH_vi 0.00 1111 10 . ..... 1100 . 0 ..... ..... @qrrx_s
SQRDMULH_vi 0.00 1111 01 .. .... 1101 . 0 ..... ..... @qrrx_h
SQRDMULH_vi 0.00 1111 10 . ..... 1101 . 0 ..... ..... @qrrx_s
SQRDMLAH_vi 0.10 1111 01 .. .... 1101 . 0 ..... ..... @qrrx_h
SQRDMLAH_vi 0.10 1111 10 .. .... 1101 . 0 ..... ..... @qrrx_s
SQRDMLSH_vi 0.10 1111 01 .. .... 1111 . 0 ..... ..... @qrrx_h
SQRDMLSH_vi 0.10 1111 10 .. .... 1111 . 0 ..... ..... @qrrx_s
SDOT_vi 0.00 1111 10 .. .... 1110 . 0 ..... ..... @qrrx_s
UDOT_vi 0.10 1111 10 .. .... 1110 . 0 ..... ..... @qrrx_s
SUDOT_vi 0.00 1111 00 .. .... 1111 . 0 ..... ..... @qrrx_s
USDOT_vi 0.00 1111 10 .. .... 1111 . 0 ..... ..... @qrrx_s
BFDOT_vi 0.00 1111 01 .. .... 1111 . 0 ..... ..... @qrrx_s
BFMLAL_vi 0.00 1111 11 .. .... 1111 . 0 ..... ..... @qrrx_h
FCMLA_vi 0 0 10 1111 01 idx:1 rm:5 0 rot:2 1 0 0 rn:5 rd:5 esz=1 q=0
FCMLA_vi 0 1 10 1111 01 . rm:5 0 rot:2 1 . 0 rn:5 rd:5 esz=1 idx=%hl q=1
FCMLA_vi 0 1 10 1111 10 0 rm:5 0 rot:2 1 idx:1 0 rn:5 rd:5 esz=2 q=1
# Floating-point conditional select
FCSEL 0001 1110 .. 1 rm:5 cond:4 11 rn:5 rd:5 esz=%esz_hsd

View File

@ -82,11 +82,39 @@ void aa32_max_features(ARMCPU *cpu)
cpu->isar.id_pfr2 = t;
t = cpu->isar.id_dfr0;
t = FIELD_DP32(t, ID_DFR0, COPDBG, 9); /* FEAT_Debugv8p4 */
t = FIELD_DP32(t, ID_DFR0, COPSDBG, 9); /* FEAT_Debugv8p4 */
t = FIELD_DP32(t, ID_DFR0, COPDBG, 10); /* FEAT_Debugv8p8 */
t = FIELD_DP32(t, ID_DFR0, COPSDBG, 10); /* FEAT_Debugv8p8 */
t = FIELD_DP32(t, ID_DFR0, PERFMON, 6); /* FEAT_PMUv3p5 */
cpu->isar.id_dfr0 = t;
/* Debug ID registers. */
/* Bit[15] is RES1, Bit[13] and Bits[11:0] are RES0. */
t = 0x00008000;
t = FIELD_DP32(t, DBGDIDR, SE_IMP, 1);
t = FIELD_DP32(t, DBGDIDR, NSUHD_IMP, 1);
t = FIELD_DP32(t, DBGDIDR, VERSION, 10); /* FEAT_Debugv8p8 */
t = FIELD_DP32(t, DBGDIDR, CTX_CMPS, 1);
t = FIELD_DP32(t, DBGDIDR, BRPS, 5);
t = FIELD_DP32(t, DBGDIDR, WRPS, 3);
cpu->isar.dbgdidr = t;
t = 0;
t = FIELD_DP32(t, DBGDEVID, PCSAMPLE, 3);
t = FIELD_DP32(t, DBGDEVID, WPADDRMASK, 1);
t = FIELD_DP32(t, DBGDEVID, BPADDRMASK, 15);
t = FIELD_DP32(t, DBGDEVID, VECTORCATCH, 0);
t = FIELD_DP32(t, DBGDEVID, VIRTEXTNS, 1);
t = FIELD_DP32(t, DBGDEVID, DOUBLELOCK, 1);
t = FIELD_DP32(t, DBGDEVID, AUXREGS, 0);
t = FIELD_DP32(t, DBGDEVID, CIDMASK, 0);
cpu->isar.dbgdevid = t;
/* Bits[31:4] are RES0. */
t = 0;
t = FIELD_DP32(t, DBGDEVID1, PCSROFFSET, 2);
cpu->isar.dbgdevid1 = t;
t = cpu->isar.id_dfr1;
t = FIELD_DP32(t, ID_DFR1, HPMN0, 1); /* FEAT_HPMN0 */
cpu->isar.id_dfr1 = t;
@ -955,9 +983,6 @@ static void arm_max_initfn(Object *obj)
cpu->isar.id_isar4 = 0x00011142;
cpu->isar.id_isar5 = 0x00011121;
cpu->isar.id_isar6 = 0;
cpu->isar.dbgdidr = 0x3516d000;
cpu->isar.dbgdevid = 0x00110f13;
cpu->isar.dbgdevid1 = 0x2;
cpu->isar.reset_pmcr_el0 = 0x41013000;
cpu->clidr = 0x0a200023;
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */

View File

@ -1167,7 +1167,7 @@ void aarch64_max_tcg_initfn(Object *obj)
t = cpu->isar.id_aa64isar2;
t = FIELD_DP64(t, ID_AA64ISAR2, MOPS, 1); /* FEAT_MOPS */
t = FIELD_DP64(t, ID_AA64ISAR2, BC, 1); /* FEAT_HBC */
t = FIELD_DP64(t, ID_AA64ISAR2, BC, 1); /* FEAT_HBC */
t = FIELD_DP64(t, ID_AA64ISAR2, WFXT, 2); /* FEAT_WFxT */
cpu->isar.id_aa64isar2 = t;
@ -1253,7 +1253,7 @@ void aarch64_max_tcg_initfn(Object *obj)
cpu->isar.id_aa64zfr0 = t;
t = cpu->isar.id_aa64dfr0;
t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 9); /* FEAT_Debugv8p4 */
t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 10); /* FEAT_Debugv8p8 */
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 6); /* FEAT_PMUv3p5 */
t = FIELD_DP64(t, ID_AA64DFR0, HPMN0, 1); /* FEAT_HPMN0 */
cpu->isar.id_aa64dfr0 = t;

File diff suppressed because it is too large Load Diff

View File

@ -317,10 +317,12 @@ void HELPER(neon_sqdmulh_idx_h)(void *vd, void *vn, void *vm,
intptr_t i, j, opr_sz = simd_oprsz(desc);
int idx = simd_data(desc);
int16_t *d = vd, *n = vn, *m = (int16_t *)vm + H2(idx);
intptr_t elements = opr_sz / 2;
intptr_t eltspersegment = MIN(16 / 2, elements);
for (i = 0; i < opr_sz / 2; i += 16 / 2) {
for (i = 0; i < elements; i += 16 / 2) {
int16_t mm = m[i];
for (j = 0; j < 16 / 2; ++j) {
for (j = 0; j < eltspersegment; ++j) {
d[i + j] = do_sqrdmlah_h(n[i + j], mm, 0, false, false, vq);
}
}
@ -333,16 +335,54 @@ void HELPER(neon_sqrdmulh_idx_h)(void *vd, void *vn, void *vm,
intptr_t i, j, opr_sz = simd_oprsz(desc);
int idx = simd_data(desc);
int16_t *d = vd, *n = vn, *m = (int16_t *)vm + H2(idx);
intptr_t elements = opr_sz / 2;
intptr_t eltspersegment = MIN(16 / 2, elements);
for (i = 0; i < opr_sz / 2; i += 16 / 2) {
for (i = 0; i < elements; i += 16 / 2) {
int16_t mm = m[i];
for (j = 0; j < 16 / 2; ++j) {
for (j = 0; j < eltspersegment; ++j) {
d[i + j] = do_sqrdmlah_h(n[i + j], mm, 0, false, true, vq);
}
}
clear_tail(d, opr_sz, simd_maxsz(desc));
}
void HELPER(neon_sqrdmlah_idx_h)(void *vd, void *vn, void *vm,
void *vq, uint32_t desc)
{
intptr_t i, j, opr_sz = simd_oprsz(desc);
int idx = simd_data(desc);
int16_t *d = vd, *n = vn, *m = (int16_t *)vm + H2(idx);
intptr_t elements = opr_sz / 2;
intptr_t eltspersegment = MIN(16 / 2, elements);
for (i = 0; i < elements; i += 16 / 2) {
int16_t mm = m[i];
for (j = 0; j < eltspersegment; ++j) {
d[i + j] = do_sqrdmlah_h(n[i + j], mm, d[i + j], false, true, vq);
}
}
clear_tail(d, opr_sz, simd_maxsz(desc));
}
void HELPER(neon_sqrdmlsh_idx_h)(void *vd, void *vn, void *vm,
void *vq, uint32_t desc)
{
intptr_t i, j, opr_sz = simd_oprsz(desc);
int idx = simd_data(desc);
int16_t *d = vd, *n = vn, *m = (int16_t *)vm + H2(idx);
intptr_t elements = opr_sz / 2;
intptr_t eltspersegment = MIN(16 / 2, elements);
for (i = 0; i < elements; i += 16 / 2) {
int16_t mm = m[i];
for (j = 0; j < eltspersegment; ++j) {
d[i + j] = do_sqrdmlah_h(n[i + j], mm, d[i + j], true, true, vq);
}
}
clear_tail(d, opr_sz, simd_maxsz(desc));
}
void HELPER(sve2_sqrdmlah_h)(void *vd, void *vn, void *vm,
void *va, uint32_t desc)
{
@ -512,10 +552,12 @@ void HELPER(neon_sqdmulh_idx_s)(void *vd, void *vn, void *vm,
intptr_t i, j, opr_sz = simd_oprsz(desc);
int idx = simd_data(desc);
int32_t *d = vd, *n = vn, *m = (int32_t *)vm + H4(idx);
intptr_t elements = opr_sz / 4;
intptr_t eltspersegment = MIN(16 / 4, elements);
for (i = 0; i < opr_sz / 4; i += 16 / 4) {
for (i = 0; i < elements; i += 16 / 4) {
int32_t mm = m[i];
for (j = 0; j < 16 / 4; ++j) {
for (j = 0; j < eltspersegment; ++j) {
d[i + j] = do_sqrdmlah_s(n[i + j], mm, 0, false, false, vq);
}
}
@ -528,16 +570,54 @@ void HELPER(neon_sqrdmulh_idx_s)(void *vd, void *vn, void *vm,
intptr_t i, j, opr_sz = simd_oprsz(desc);
int idx = simd_data(desc);
int32_t *d = vd, *n = vn, *m = (int32_t *)vm + H4(idx);
intptr_t elements = opr_sz / 4;
intptr_t eltspersegment = MIN(16 / 4, elements);
for (i = 0; i < opr_sz / 4; i += 16 / 4) {
for (i = 0; i < elements; i += 16 / 4) {
int32_t mm = m[i];
for (j = 0; j < 16 / 4; ++j) {
for (j = 0; j < eltspersegment; ++j) {
d[i + j] = do_sqrdmlah_s(n[i + j], mm, 0, false, true, vq);
}
}
clear_tail(d, opr_sz, simd_maxsz(desc));
}
void HELPER(neon_sqrdmlah_idx_s)(void *vd, void *vn, void *vm,
void *vq, uint32_t desc)
{
intptr_t i, j, opr_sz = simd_oprsz(desc);
int idx = simd_data(desc);
int32_t *d = vd, *n = vn, *m = (int32_t *)vm + H4(idx);
intptr_t elements = opr_sz / 4;
intptr_t eltspersegment = MIN(16 / 4, elements);
for (i = 0; i < elements; i += 16 / 4) {
int32_t mm = m[i];
for (j = 0; j < eltspersegment; ++j) {
d[i + j] = do_sqrdmlah_s(n[i + j], mm, d[i + j], false, true, vq);
}
}
clear_tail(d, opr_sz, simd_maxsz(desc));
}
void HELPER(neon_sqrdmlsh_idx_s)(void *vd, void *vn, void *vm,
void *vq, uint32_t desc)
{
intptr_t i, j, opr_sz = simd_oprsz(desc);
int idx = simd_data(desc);
int32_t *d = vd, *n = vn, *m = (int32_t *)vm + H4(idx);
intptr_t elements = opr_sz / 4;
intptr_t eltspersegment = MIN(16 / 4, elements);
for (i = 0; i < elements; i += 16 / 4) {
int32_t mm = m[i];
for (j = 0; j < eltspersegment; ++j) {
d[i + j] = do_sqrdmlah_s(n[i + j], mm, d[i + j], true, true, vq);
}
}
clear_tail(d, opr_sz, simd_maxsz(desc));
}
void HELPER(sve2_sqrdmlah_s)(void *vd, void *vn, void *vm,
void *va, uint32_t desc)
{
@ -907,7 +987,7 @@ void HELPER(gvec_fcmlah_idx)(void *vd, void *vn, void *vm, void *va,
intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
uint32_t neg_real = flip ^ neg_imag;
intptr_t elements = opr_sz / sizeof(float16);
intptr_t eltspersegment = 16 / sizeof(float16);
intptr_t eltspersegment = MIN(16 / sizeof(float16), elements);
intptr_t i, j;
/* Shift boolean to the sign bit so we can xor to negate. */
@ -969,7 +1049,7 @@ void HELPER(gvec_fcmlas_idx)(void *vd, void *vn, void *vm, void *va,
intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
uint32_t neg_real = flip ^ neg_imag;
intptr_t elements = opr_sz / sizeof(float32);
intptr_t eltspersegment = 16 / sizeof(float32);
intptr_t eltspersegment = MIN(16 / sizeof(float32), elements);
intptr_t i, j;
/* Shift boolean to the sign bit so we can xor to negate. */

View File

@ -1091,8 +1091,8 @@ const FloatRoundMode arm_rmode_to_sf_map[] = {
uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus)
{
float_status *status = vstatus;
uint32_t inexact, frac;
uint32_t e_old, e_new;
uint32_t frac, e_old, e_new;
bool inexact;
e_old = get_float_exception_flags(status);
set_float_exception_flags(0, status);
@ -1100,13 +1100,13 @@ uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus)
e_new = get_float_exception_flags(status);
set_float_exception_flags(e_old | e_new, status);
if (value == float64_chs(float64_zero)) {
/* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
inexact = 1;
} else {
/* Normal inexact or overflow or NaN */
inexact = e_new & (float_flag_inexact | float_flag_invalid);
}
/* Normal inexact, denormal with flush-to-zero, or overflow or NaN */
inexact = e_new & (float_flag_inexact |
float_flag_input_denormal |
float_flag_invalid);
/* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
inexact |= value == float64_chs(float64_zero);
/* Pack the result and the env->ZF representation of Z together. */
return deposit64(frac, 32, 32, inexact);

View File

@ -37,18 +37,18 @@ class Aarch64SbsarefMachine(QemuSystemTest):
Used components:
- Trusted Firmware 2.11.0
- Tianocore EDK2 stable202405
- Tianocore EDK2-platforms commit 4bbd0ed
- Trusted Firmware v2.11.0
- Tianocore EDK2 4d4f569924
- Tianocore EDK2-platforms 3f08401
"""
# Secure BootRom (TF-A code)
fs0_xz_url = (
"https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/"
"20240528-140808/edk2/SBSA_FLASH0.fd.xz"
"20240619-148232/edk2/SBSA_FLASH0.fd.xz"
)
fs0_xz_hash = "fa6004900b67172914c908b78557fec4d36a5f784f4c3dd08f49adb75e1892a9"
fs0_xz_hash = "0c954842a590988f526984de22e21ae0ab9cb351a0c99a8a58e928f0c7359cf7"
tar_xz_path = self.fetch_asset(fs0_xz_url, asset_hash=fs0_xz_hash,
algorithm='sha256')
archive.extract(tar_xz_path, self.workdir)
@ -57,9 +57,9 @@ class Aarch64SbsarefMachine(QemuSystemTest):
# Non-secure rom (UEFI and EFI variables)
fs1_xz_url = (
"https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/"
"20240528-140808/edk2/SBSA_FLASH1.fd.xz"
"20240619-148232/edk2/SBSA_FLASH1.fd.xz"
)
fs1_xz_hash = "5f3747d4000bc416d9641e33ff4ac60c3cc8cb74ca51b6e932e58531c62eb6f7"
fs1_xz_hash = "c6ec39374c4d79bb9e9cdeeb6db44732d90bb4a334cec92002b3f4b9cac4b5ee"
tar_xz_path = self.fetch_asset(fs1_xz_url, asset_hash=fs1_xz_hash,
algorithm='sha256')
archive.extract(tar_xz_path, self.workdir)
@ -75,8 +75,6 @@ class Aarch64SbsarefMachine(QemuSystemTest):
f"if=pflash,file={fs0_path},format=raw",
"-drive",
f"if=pflash,file={fs1_path},format=raw",
"-smp",
"1",
"-machine",
"sbsa-ref",
)

View File

@ -448,6 +448,9 @@ static void test_masked_interrupt(void)
g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
/* Check that the interrupt isn't pending in NVIC */
g_assert_false(check_nvic_pending(EXTI1_IRQ));
/* Clean EXTI */
exti_set_irq(1, 0);
}
static void test_interrupt(void)
@ -498,6 +501,9 @@ static void test_interrupt(void)
/* Clean NVIC */
unpend_nvic_irq(EXTI1_IRQ);
g_assert_false(check_nvic_pending(EXTI1_IRQ));
/* Clean EXTI */
exti_set_irq(1, 0);
}
static void test_orred_interrupts(void)
@ -531,6 +537,8 @@ static void test_orred_interrupts(void)
unpend_nvic_irq(EXTI5_9_IRQ);
g_assert_false(check_nvic_pending(EXTI5_9_IRQ));
exti_set_irq(i, 0);
}
}

View File

@ -221,10 +221,10 @@ static void test_interrupt(void)
g_assert_true(get_irq(1));
/* Clean the test */
syscfg_writel(SYSCFG_EXTICR1, 0x00000000);
syscfg_set_irq(0, 0);
syscfg_set_irq(15, 0);
/* irq 15 is high at reset because GPIOA15 is high at reset */
syscfg_set_irq(17, 0);
syscfg_writel(SYSCFG_EXTICR1, 0x00000000);
}
static void test_irq_pin_multiplexer(void)
@ -237,21 +237,21 @@ static void test_irq_pin_multiplexer(void)
syscfg_set_irq(0, 1);
/* Check that irq 0 was set and irq 15 wasn't */
/* Check that irq 0 was set and irq 2 wasn't */
g_assert_true(get_irq(0));
g_assert_false(get_irq(15));
g_assert_false(get_irq(2));
/* Clean the test */
syscfg_set_irq(0, 0);
syscfg_set_irq(15, 1);
syscfg_set_irq(2, 1);
/* Check that irq 15 was set and irq 0 wasn't */
g_assert_true(get_irq(15));
/* Check that irq 2 was set and irq 0 wasn't */
g_assert_true(get_irq(2));
g_assert_false(get_irq(0));
/* Clean the test */
syscfg_set_irq(15, 0);
syscfg_set_irq(2, 0);
}
static void test_irq_gpio_multiplexer(void)

View File

@ -41,8 +41,9 @@ endif
# Pauth Tests
ifneq ($(CROSS_CC_HAS_ARMV8_3),)
AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5
AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5 test-2375
pauth-%: CFLAGS += -march=armv8.3-a
test-2375: CFLAGS += -march=armv8.3-a
run-pauth-1: QEMU_OPTS += -cpu max
run-pauth-2: QEMU_OPTS += -cpu max
# Choose a cpu with FEAT_Pauth but without FEAT_FPAC for pauth-[45].

View File

@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Copyright (c) 2024 Linaro Ltd */
/* See https://gitlab.com/qemu-project/qemu/-/issues/2375 */
#include <assert.h>
int main(void)
{
int r, z;
asm("msr fpcr, %2\n\t"
"fjcvtzs %w0, %d3\n\t"
"cset %1, eq"
: "=r"(r), "=r"(z)
: "r"(0x01000000L), /* FZ = 1 */
"w"(0xfcff00L)); /* denormal */
assert(r == 0);
assert(z == 0);
return 0;
}