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
32 changed files with 967 additions and 641 deletions
+2 -1
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
+1
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)
+47
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.
+1
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
=================================
+14 -1
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);
+2 -6
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;
}
+4 -8
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;
}
+31
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 = {
+87
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);
+13 -15
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()
}
};
+21 -1
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
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)
+1
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'))
+2 -1
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;
+2
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,
+2 -2
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
+2
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;
+2
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];
};
+68
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
+2
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)

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