1
Nothing too exciting in this lot :-)
1
Hi; here's the latest round of arm patches. I have included also
2
my patchset for the RTC devices to avoid keeping time_t and
3
time_t diffs in 32-bit variables.
2
4
3
The following changes since commit ba0fa56bc06e563de68d2a2bf3ddb0cfea1be4f9:
5
thanks
6
-- PMM
4
7
5
Merge remote-tracking branch 'remotes/vivier/tags/q800-for-6.2-pull-request' into staging (2021-09-29 21:20:49 +0100)
8
The following changes since commit 156618d9ea67f2f2e31d9dedd97f2dcccbe6808c:
9
10
Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2023-08-30 09:20:27 -0400)
6
11
7
are available in the Git repository at:
12
are available in the Git repository at:
8
13
9
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210930
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230831
10
15
11
for you to fetch changes up to 1f4b2ec701b9d73d3fa7bb90c8b4376bc7d3c42b:
16
for you to fetch changes up to e73b8bb8a3e9a162f70e9ffbf922d4fafc96bbfb:
12
17
13
hw/arm: sabrelite: Connect SPI flash CS line to GPIO3_19 (2021-09-30 13:44:13 +0100)
18
hw/arm: Set number of MPU regions correctly for an505, an521, an524 (2023-08-31 11:07:02 +0100)
14
19
15
----------------------------------------------------------------
20
----------------------------------------------------------------
16
target-arm queue:
21
target-arm queue:
17
* allwinner-h3: Switch to SMC as PSCI conduit
22
* Some of the preliminary patches for Cortex-A710 support
18
* arm: tcg: Adhere to SMCCC 1.3 section 5.2
23
* i.MX7 and i.MX6UL refactoring
19
* xlnx-zcu102, xlnx-versal-virt: Support BBRAM and eFUSE devices
24
* Implement SRC device for i.MX7
20
* gdbstub related code cleanups
25
* Catch illegal-exception-return from EL3 with bad NSE/NS
21
* Don't put FPEXC and FPSID in org.gnu.gdb.arm.vfp XML
26
* Use 64-bit offsets for holding time_t differences in RTC devices
22
* Use _init vs _new convention in bus creation function names
27
* Model correct number of MPU regions for an505, an521, an524 boards
23
* sabrelite: Connect SPI flash CS line to GPIO3_19
24
28
25
----------------------------------------------------------------
29
----------------------------------------------------------------
26
Alexander Graf (2):
30
Alex Bennée (1):
27
allwinner-h3: Switch to SMC as PSCI conduit
31
target/arm: properly document FEAT_CRC32
28
arm: tcg: Adhere to SMCCC 1.3 section 5.2
29
32
30
Peter Maydell (10):
33
Jean-Christophe Dubois (6):
31
configs: Don't include 32-bit-only GDB XML in aarch64 linux configs
34
Remove i.MX7 IOMUX GPR device from i.MX6UL
32
target/arm: Fix coding style issues in gdbstub code in helper.c
35
Refactor i.MX6UL processor code
33
target/arm: Move gdbstub related code out of helper.c
36
Add i.MX6UL missing devices.
34
target/arm: Don't put FPEXC and FPSID in org.gnu.gdb.arm.vfp XML
37
Refactor i.MX7 processor code
35
scsi: Replace scsi_bus_new() with scsi_bus_init(), scsi_bus_init_named()
38
Add i.MX7 missing TZ devices and memory regions
36
ipack: Rename ipack_bus_new_inplace() to ipack_bus_init()
39
Add i.MX7 SRC device implementation
37
pci: Rename pci_root_bus_new_inplace() to pci_root_bus_init()
38
qbus: Rename qbus_create_inplace() to qbus_init()
39
qbus: Rename qbus_create() to qbus_new()
40
ide: Rename ide_bus_new() to ide_bus_init()
41
40
42
Tong Ho (9):
41
Peter Maydell (8):
43
hw/nvram: Introduce Xilinx eFuse QOM
42
target/arm: Catch illegal-exception-return from EL3 with bad NSE/NS
44
hw/nvram: Introduce Xilinx Versal eFuse device
43
hw/rtc/m48t59: Use 64-bit arithmetic in set_alarm()
45
hw/nvram: Introduce Xilinx ZynqMP eFuse device
44
hw/rtc/twl92230: Use int64_t for sec_offset and alm_sec
46
hw/nvram: Introduce Xilinx battery-backed ram
45
hw/rtc/aspeed_rtc: Use 64-bit offset for holding time_t difference
47
hw/arm: xlnx-versal-virt: Add Xilinx BBRAM device
46
rtc: Use time_t for passing and returning time offsets
48
hw/arm: xlnx-versal-virt: Add Xilinx eFUSE device
47
target/arm: Do all "ARM_FEATURE_X implies Y" checks in post_init
49
hw/arm: xlnx-zcu102: Add Xilinx BBRAM device
48
hw/arm/armv7m: Add mpu-ns-regions and mpu-s-regions properties
50
hw/arm: xlnx-zcu102: Add Xilinx eFUSE device
49
hw/arm: Set number of MPU regions correctly for an505, an521, an524
51
docs/system/arm: xlnx-versal-virt: BBRAM and eFUSE Usage
52
50
53
Xuzhou Cheng (1):
51
Richard Henderson (9):
54
hw/arm: sabrelite: Connect SPI flash CS line to GPIO3_19
52
target/arm: Reduce dcz_blocksize to uint8_t
53
target/arm: Allow cpu to configure GM blocksize
54
target/arm: Support more GM blocksizes
55
target/arm: When tag memory is not present, set MTE=1
56
target/arm: Introduce make_ccsidr64
57
target/arm: Apply access checks to neoverse-n1 special registers
58
target/arm: Apply access checks to neoverse-v1 special registers
59
target/arm: Suppress FEAT_TRBE (Trace Buffer Extension)
60
target/arm: Implement FEAT_HPDS2 as a no-op
55
61
56
docs/system/arm/xlnx-versal-virt.rst | 49 ++
62
docs/system/arm/emulation.rst | 2 +
57
configs/targets/aarch64-linux-user.mak | 2 +-
63
include/hw/arm/armsse.h | 5 +
58
configs/targets/aarch64-softmmu.mak | 2 +-
64
include/hw/arm/armv7m.h | 8 +
59
configs/targets/aarch64_be-linux-user.mak | 2 +-
65
include/hw/arm/fsl-imx6ul.h | 158 ++++++++++++++++---
60
configs/targets/arm-linux-user.mak | 2 +-
66
include/hw/arm/fsl-imx7.h | 338 ++++++++++++++++++++++++++++++-----------
61
configs/targets/arm-softmmu.mak | 2 +-
67
include/hw/misc/imx7_src.h | 66 ++++++++
62
configs/targets/armeb-linux-user.mak | 2 +-
68
include/hw/rtc/aspeed_rtc.h | 2 +-
63
include/hw/arm/xlnx-versal.h | 15 +
69
include/sysemu/rtc.h | 4 +-
64
include/hw/arm/xlnx-zynqmp.h | 5 +
70
target/arm/cpregs.h | 2 +
65
include/hw/ide/internal.h | 4 +-
71
target/arm/cpu.h | 5 +-
66
include/hw/ipack/ipack.h | 8 +-
72
target/arm/internals.h | 6 -
67
include/hw/nvram/xlnx-bbram.h | 54 ++
73
target/arm/tcg/translate.h | 2 +
68
include/hw/nvram/xlnx-efuse.h | 132 +++++
74
hw/arm/armsse.c | 16 ++
69
include/hw/nvram/xlnx-versal-efuse.h | 68 +++
75
hw/arm/armv7m.c | 21 +++
70
include/hw/nvram/xlnx-zynqmp-efuse.h | 44 ++
76
hw/arm/fsl-imx6ul.c | 174 +++++++++++++--------
71
include/hw/pci/pci.h | 10 +-
77
hw/arm/fsl-imx7.c | 201 +++++++++++++++++++-----
72
include/hw/qdev-core.h | 6 +-
78
hw/arm/mps2-tz.c | 29 ++++
73
include/hw/scsi/scsi.h | 30 +-
79
hw/misc/imx7_src.c | 276 +++++++++++++++++++++++++++++++++
74
target/arm/internals.h | 7 +
80
hw/rtc/aspeed_rtc.c | 5 +-
75
hw/arm/allwinner-h3.c | 2 +-
81
hw/rtc/m48t59.c | 2 +-
76
hw/arm/sabrelite.c | 2 +-
82
hw/rtc/twl92230.c | 4 +-
77
hw/arm/xlnx-versal-virt.c | 88 +++
83
softmmu/rtc.c | 4 +-
78
hw/arm/xlnx-versal.c | 57 ++
84
target/arm/cpu.c | 207 ++++++++++++++-----------
79
hw/arm/xlnx-zcu102.c | 30 ++
85
target/arm/helper.c | 15 +-
80
hw/arm/xlnx-zynqmp.c | 49 ++
86
target/arm/tcg/cpu32.c | 2 +-
81
hw/audio/intel-hda.c | 2 +-
87
target/arm/tcg/cpu64.c | 102 +++++++++----
82
hw/block/fdc.c | 2 +-
88
target/arm/tcg/helper-a64.c | 9 ++
83
hw/block/swim.c | 3 +-
89
target/arm/tcg/mte_helper.c | 90 ++++++++---
84
hw/char/virtio-serial-bus.c | 4 +-
90
target/arm/tcg/translate-a64.c | 5 +-
85
hw/core/bus.c | 13 +-
91
hw/misc/meson.build | 1 +
86
hw/core/sysbus.c | 10 +-
92
hw/misc/trace-events | 4 +
87
hw/gpio/bcm2835_gpio.c | 3 +-
93
31 files changed, 1393 insertions(+), 372 deletions(-)
88
hw/hyperv/vmbus.c | 2 +-
94
create mode 100644 include/hw/misc/imx7_src.h
89
hw/i2c/core.c | 2 +-
95
create mode 100644 hw/misc/imx7_src.c
90
hw/ide/ahci.c | 2 +-
91
hw/ide/cmd646.c | 2 +-
92
hw/ide/isa.c | 2 +-
93
hw/ide/macio.c | 2 +-
94
hw/ide/microdrive.c | 2 +-
95
hw/ide/mmio.c | 2 +-
96
hw/ide/piix.c | 2 +-
97
hw/ide/qdev.c | 4 +-
98
hw/ide/sii3112.c | 2 +-
99
hw/ide/via.c | 2 +-
100
hw/ipack/ipack.c | 10 +-
101
hw/ipack/tpci200.c | 4 +-
102
hw/isa/isa-bus.c | 2 +-
103
hw/misc/auxbus.c | 2 +-
104
hw/misc/mac_via.c | 4 +-
105
hw/misc/macio/cuda.c | 4 +-
106
hw/misc/macio/macio.c | 4 +-
107
hw/misc/macio/pmu.c | 4 +-
108
hw/nubus/nubus-bridge.c | 2 +-
109
hw/nvme/ctrl.c | 4 +-
110
hw/nvme/subsys.c | 3 +-
111
hw/nvram/xlnx-bbram.c | 545 +++++++++++++++++++
112
hw/nvram/xlnx-efuse-crc.c | 119 +++++
113
hw/nvram/xlnx-efuse.c | 280 ++++++++++
114
hw/nvram/xlnx-versal-efuse-cache.c | 114 ++++
115
hw/nvram/xlnx-versal-efuse-ctrl.c | 783 +++++++++++++++++++++++++++
116
hw/nvram/xlnx-zynqmp-efuse.c | 855 ++++++++++++++++++++++++++++++
117
hw/pci-host/raven.c | 4 +-
118
hw/pci-host/versatile.c | 6 +-
119
hw/pci/pci.c | 30 +-
120
hw/pci/pci_bridge.c | 4 +-
121
hw/ppc/spapr_vio.c | 2 +-
122
hw/s390x/ap-bridge.c | 2 +-
123
hw/s390x/css-bridge.c | 2 +-
124
hw/s390x/event-facility.c | 4 +-
125
hw/s390x/s390-pci-bus.c | 2 +-
126
hw/s390x/virtio-ccw.c | 3 +-
127
hw/scsi/esp-pci.c | 2 +-
128
hw/scsi/esp.c | 2 +-
129
hw/scsi/lsi53c895a.c | 2 +-
130
hw/scsi/megasas.c | 3 +-
131
hw/scsi/mptsas.c | 2 +-
132
hw/scsi/scsi-bus.c | 6 +-
133
hw/scsi/spapr_vscsi.c | 3 +-
134
hw/scsi/virtio-scsi.c | 4 +-
135
hw/scsi/vmw_pvscsi.c | 3 +-
136
hw/sd/allwinner-sdhost.c | 4 +-
137
hw/sd/bcm2835_sdhost.c | 4 +-
138
hw/sd/pl181.c | 3 +-
139
hw/sd/pxa2xx_mmci.c | 4 +-
140
hw/sd/sdhci.c | 3 +-
141
hw/sd/ssi-sd.c | 3 +-
142
hw/ssi/ssi.c | 2 +-
143
hw/usb/bus.c | 2 +-
144
hw/usb/dev-smartcard-reader.c | 3 +-
145
hw/usb/dev-storage-bot.c | 3 +-
146
hw/usb/dev-storage-classic.c | 4 +-
147
hw/usb/dev-uas.c | 3 +-
148
hw/virtio/virtio-mmio.c | 3 +-
149
hw/virtio/virtio-pci.c | 3 +-
150
hw/xen/xen-bus.c | 2 +-
151
hw/xen/xen-legacy-backend.c | 2 +-
152
target/arm/gdbstub.c | 154 ++++++
153
target/arm/gdbstub64.c | 140 +++++
154
target/arm/helper.c | 262 ---------
155
target/arm/psci.c | 35 +-
156
gdb-xml/arm-neon.xml | 2 -
157
gdb-xml/arm-vfp-sysregs.xml | 17 +
158
gdb-xml/arm-vfp.xml | 2 -
159
gdb-xml/arm-vfp3.xml | 2 -
160
hw/Kconfig | 2 +
161
hw/arm/Kconfig | 2 +
162
hw/nvram/Kconfig | 19 +
163
hw/nvram/meson.build | 8 +
164
108 files changed, 3806 insertions(+), 447 deletions(-)
165
create mode 100644 include/hw/nvram/xlnx-bbram.h
166
create mode 100644 include/hw/nvram/xlnx-efuse.h
167
create mode 100644 include/hw/nvram/xlnx-versal-efuse.h
168
create mode 100644 include/hw/nvram/xlnx-zynqmp-efuse.h
169
create mode 100644 hw/nvram/xlnx-bbram.c
170
create mode 100644 hw/nvram/xlnx-efuse-crc.c
171
create mode 100644 hw/nvram/xlnx-efuse.c
172
create mode 100644 hw/nvram/xlnx-versal-efuse-cache.c
173
create mode 100644 hw/nvram/xlnx-versal-efuse-ctrl.c
174
create mode 100644 hw/nvram/xlnx-zynqmp-efuse.c
175
create mode 100644 gdb-xml/arm-vfp-sysregs.xml
176
96
diff view generated by jsdifflib
1
From: Tong Ho <tong.ho@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Connect the support for Xilinx ZynqMP Battery-Backed RAM (BBRAM)
3
This value is only 4 bits wide.
4
4
5
The command argument:
6
-drive if=pflash,index=2,...
7
Can be used to optionally connect the bbram to a backend
8
storage, such that field-programmed values in one
9
invocation can be made available to next invocation.
10
11
The backend storage must be a seekable binary file, and
12
its size must be 36 bytes or larger. A file with all
13
binary 0's is a 'blank'.
14
15
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
16
Message-id: 20210917052400.1249094-8-tong.ho@xilinx.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20230811214031.171020-2-richard.henderson@linaro.org
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
10
---
20
include/hw/arm/xlnx-zynqmp.h | 2 ++
11
target/arm/cpu.h | 3 ++-
21
hw/arm/xlnx-zcu102.c | 15 +++++++++++++++
12
1 file changed, 2 insertions(+), 1 deletion(-)
22
hw/arm/xlnx-zynqmp.c | 20 ++++++++++++++++++++
23
hw/Kconfig | 1 +
24
4 files changed, 38 insertions(+)
25
13
26
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
27
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/arm/xlnx-zynqmp.h
16
--- a/target/arm/cpu.h
29
+++ b/include/hw/arm/xlnx-zynqmp.h
17
+++ b/target/arm/cpu.h
30
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
31
#include "qom/object.h"
19
bool prop_lpa2;
32
#include "net/can_emu.h"
20
33
#include "hw/dma/xlnx_csu_dma.h"
21
/* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
34
+#include "hw/nvram/xlnx-bbram.h"
22
- uint32_t dcz_blocksize;
35
23
+ uint8_t dcz_blocksize;
36
#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
37
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
38
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
39
40
MemoryRegion *ddr_ram;
41
MemoryRegion ddr_ram_low, ddr_ram_high;
42
+ XlnxBBRam bbram;
43
44
MemoryRegion mr_unimp[XLNX_ZYNQMP_NUM_UNIMP_AREAS];
45
46
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/xlnx-zcu102.c
49
+++ b/hw/arm/xlnx-zcu102.c
50
@@ -XXX,XX +XXX,XX @@ static void zcu102_modify_dtb(const struct arm_boot_info *binfo, void *fdt)
51
}
52
}
53
54
+static void bbram_attach_drive(XlnxBBRam *dev)
55
+{
56
+ DriveInfo *dinfo;
57
+ BlockBackend *blk;
58
+
24
+
59
+ dinfo = drive_get_by_index(IF_PFLASH, 2);
25
uint64_t rvbar_prop; /* Property/input signals. */
60
+ blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
26
61
+ if (blk) {
27
/* Configurable aspects of GIC cpu interface (which is part of the CPU) */
62
+ qdev_prop_set_drive(DEVICE(dev), "drive", blk);
63
+ }
64
+}
65
+
66
static void xlnx_zcu102_init(MachineState *machine)
67
{
68
XlnxZCU102 *s = ZCU102_MACHINE(machine);
69
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_init(MachineState *machine)
70
71
qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
72
73
+ /* Attach bbram backend, if given */
74
+ bbram_attach_drive(&s->soc.bbram);
75
+
76
/* Create and plug in the SD cards */
77
for (i = 0; i < XLNX_ZYNQMP_NUM_SDHCI; i++) {
78
BusState *bus;
79
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/arm/xlnx-zynqmp.c
82
+++ b/hw/arm/xlnx-zynqmp.c
83
@@ -XXX,XX +XXX,XX @@
84
#define RTC_ADDR 0xffa60000
85
#define RTC_IRQ 26
86
87
+#define BBRAM_ADDR 0xffcd0000
88
+#define BBRAM_IRQ 11
89
+
90
#define SDHCI_CAPABILITIES 0x280737ec6481 /* Datasheet: UG1085 (v1.7) */
91
92
static const uint64_t gem_addr[XLNX_ZYNQMP_NUM_GEMS] = {
93
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_rpu(MachineState *ms, XlnxZynqMPState *s,
94
qdev_realize(DEVICE(&s->rpu_cluster), NULL, &error_fatal);
95
}
96
97
+static void xlnx_zynqmp_create_bbram(XlnxZynqMPState *s, qemu_irq *gic)
98
+{
99
+ SysBusDevice *sbd;
100
+
101
+ object_initialize_child_with_props(OBJECT(s), "bbram", &s->bbram,
102
+ sizeof(s->bbram), TYPE_XLNX_BBRAM,
103
+ &error_fatal,
104
+ "crc-zpads", "1",
105
+ NULL);
106
+ sbd = SYS_BUS_DEVICE(&s->bbram);
107
+
108
+ sysbus_realize(sbd, &error_fatal);
109
+ sysbus_mmio_map(sbd, 0, BBRAM_ADDR);
110
+ sysbus_connect_irq(sbd, 0, gic[BBRAM_IRQ]);
111
+}
112
+
113
static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
114
{
115
static const struct UnimpInfo {
116
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
117
sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, RTC_ADDR);
118
sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, gic_spi[RTC_IRQ]);
119
120
+ xlnx_zynqmp_create_bbram(s, gic_spi);
121
xlnx_zynqmp_create_unimp_mmio(s);
122
123
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
124
diff --git a/hw/Kconfig b/hw/Kconfig
125
index XXXXXXX..XXXXXXX 100644
126
--- a/hw/Kconfig
127
+++ b/hw/Kconfig
128
@@ -XXX,XX +XXX,XX @@ config XLNX_ZYNQMP
129
select REGISTER
130
select CAN_BUS
131
select PTIMER
132
+ select XLNX_BBRAM
133
--
28
--
134
2.20.1
29
2.34.1
135
30
136
31
diff view generated by jsdifflib
1
Currently helper.c includes some code which is part of the arm
1
From: Richard Henderson <richard.henderson@linaro.org>
2
target's gdbstub support. This code has a better home: in gdbstub.c
2
3
and gdbstub64.c. Move it there.
3
Previously we hard-coded the blocksize with GMID_EL1_BS.
4
4
But the value we choose for -cpu max does not match the
5
Because aarch64_fpu_gdb_get_reg() and aarch64_fpu_gdb_set_reg() move
5
value that cortex-a710 uses.
6
into gdbstub64.c, this means that they're now compiled only for
6
7
TARGET_AARCH64 rather than always. That is the only case when they
7
Mirror the way we handle dcz_blocksize.
8
would ever be used, but it does mean that the ifdef in
8
9
arm_cpu_register_gdb_regs_for_features() needs to be adjusted to
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
match.
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
11
Message-id: 20230811214031.171020-3-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20210921162901.17508-4-peter.maydell@linaro.org
16
---
13
---
17
target/arm/internals.h | 7 ++
14
target/arm/cpu.h | 2 ++
18
target/arm/gdbstub.c | 130 ++++++++++++++++++++
15
target/arm/internals.h | 6 -----
19
target/arm/gdbstub64.c | 140 +++++++++++++++++++++
16
target/arm/tcg/translate.h | 2 ++
20
target/arm/helper.c | 271 -----------------------------------------
17
target/arm/helper.c | 11 +++++---
21
4 files changed, 277 insertions(+), 271 deletions(-)
18
target/arm/tcg/cpu64.c | 1 +
22
19
target/arm/tcg/mte_helper.c | 46 ++++++++++++++++++++++------------
20
target/arm/tcg/translate-a64.c | 5 ++--
21
7 files changed, 45 insertions(+), 28 deletions(-)
22
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/cpu.h
26
+++ b/target/arm/cpu.h
27
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
28
29
/* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
30
uint8_t dcz_blocksize;
31
+ /* GM blocksize, in log_2(words), ie low 4 bits of GMID_EL0 */
32
+ uint8_t gm_blocksize;
33
34
uint64_t rvbar_prop; /* Property/input signals. */
35
23
diff --git a/target/arm/internals.h b/target/arm/internals.h
36
diff --git a/target/arm/internals.h b/target/arm/internals.h
24
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/internals.h
38
--- a/target/arm/internals.h
26
+++ b/target/arm/internals.h
39
+++ b/target/arm/internals.h
27
@@ -XXX,XX +XXX,XX @@ static inline uint64_t pmu_counter_mask(CPUARMState *env)
40
@@ -XXX,XX +XXX,XX @@ void arm_log_exception(CPUState *cs);
28
return (1 << 31) | ((1 << pmu_num_counters(env)) - 1);
41
29
}
42
#endif /* !CONFIG_USER_ONLY */
30
43
31
+#ifdef TARGET_AARCH64
44
-/*
32
+int arm_gdb_get_svereg(CPUARMState *env, GByteArray *buf, int reg);
45
- * The log2 of the words in the tag block, for GMID_EL1.BS.
33
+int arm_gdb_set_svereg(CPUARMState *env, uint8_t *buf, int reg);
46
- * The is the maximum, 256 bytes, which manipulates 64-bits of tags.
34
+int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg);
47
- */
35
+int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg);
48
-#define GMID_EL1_BS 6
36
+#endif
49
-
37
+
50
/*
38
#endif
51
* SVE predicates are 1/8 the size of SVE vectors, and cannot use
39
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
52
* the same simd_desc() encoding due to restrictions on size.
40
index XXXXXXX..XXXXXXX 100644
53
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
41
--- a/target/arm/gdbstub.c
54
index XXXXXXX..XXXXXXX 100644
42
+++ b/target/arm/gdbstub.c
55
--- a/target/arm/tcg/translate.h
43
@@ -XXX,XX +XXX,XX @@
56
+++ b/target/arm/tcg/translate.h
44
*/
57
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
45
#include "qemu/osdep.h"
58
int8_t btype;
46
#include "cpu.h"
59
/* A copy of cpu->dcz_blocksize. */
47
+#include "internals.h"
60
uint8_t dcz_blocksize;
48
#include "exec/gdbstub.h"
61
+ /* A copy of cpu->gm_blocksize. */
49
62
+ uint8_t gm_blocksize;
50
typedef struct RegisterSysregXmlParam {
63
/* True if this page is guarded. */
51
@@ -XXX,XX +XXX,XX @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
64
bool guarded_page;
52
return 0;
65
/* Bottom two bits of XScale c15_cpar coprocessor access control reg */
53
}
54
55
+static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
56
+{
57
+ ARMCPU *cpu = env_archcpu(env);
58
+ int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
59
+
60
+ /* VFP data registers are always little-endian. */
61
+ if (reg < nregs) {
62
+ return gdb_get_reg64(buf, *aa32_vfp_dreg(env, reg));
63
+ }
64
+ if (arm_feature(env, ARM_FEATURE_NEON)) {
65
+ /* Aliases for Q regs. */
66
+ nregs += 16;
67
+ if (reg < nregs) {
68
+ uint64_t *q = aa32_vfp_qreg(env, reg - 32);
69
+ return gdb_get_reg128(buf, q[0], q[1]);
70
+ }
71
+ }
72
+ switch (reg - nregs) {
73
+ case 0:
74
+ return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]);
75
+ case 1:
76
+ return gdb_get_reg32(buf, vfp_get_fpscr(env));
77
+ case 2:
78
+ return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]);
79
+ }
80
+ return 0;
81
+}
82
+
83
+static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
84
+{
85
+ ARMCPU *cpu = env_archcpu(env);
86
+ int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
87
+
88
+ if (reg < nregs) {
89
+ *aa32_vfp_dreg(env, reg) = ldq_le_p(buf);
90
+ return 8;
91
+ }
92
+ if (arm_feature(env, ARM_FEATURE_NEON)) {
93
+ nregs += 16;
94
+ if (reg < nregs) {
95
+ uint64_t *q = aa32_vfp_qreg(env, reg - 32);
96
+ q[0] = ldq_le_p(buf);
97
+ q[1] = ldq_le_p(buf + 8);
98
+ return 16;
99
+ }
100
+ }
101
+ switch (reg - nregs) {
102
+ case 0:
103
+ env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf);
104
+ return 4;
105
+ case 1:
106
+ vfp_set_fpscr(env, ldl_p(buf));
107
+ return 4;
108
+ case 2:
109
+ env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30);
110
+ return 4;
111
+ }
112
+ return 0;
113
+}
114
+
115
+/**
116
+ * arm_get/set_gdb_*: get/set a gdb register
117
+ * @env: the CPU state
118
+ * @buf: a buffer to copy to/from
119
+ * @reg: register number (offset from start of group)
120
+ *
121
+ * We return the number of bytes copied
122
+ */
123
+
124
+static int arm_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg)
125
+{
126
+ ARMCPU *cpu = env_archcpu(env);
127
+ const ARMCPRegInfo *ri;
128
+ uint32_t key;
129
+
130
+ key = cpu->dyn_sysreg_xml.data.cpregs.keys[reg];
131
+ ri = get_arm_cp_reginfo(cpu->cp_regs, key);
132
+ if (ri) {
133
+ if (cpreg_field_is_64bit(ri)) {
134
+ return gdb_get_reg64(buf, (uint64_t)read_raw_cp_reg(env, ri));
135
+ } else {
136
+ return gdb_get_reg32(buf, (uint32_t)read_raw_cp_reg(env, ri));
137
+ }
138
+ }
139
+ return 0;
140
+}
141
+
142
+static int arm_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg)
143
+{
144
+ return 0;
145
+}
146
+
147
static void arm_gen_one_xml_sysreg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml,
148
ARMCPRegInfo *ri, uint32_t ri_key,
149
int bitsize, int regnum)
150
@@ -XXX,XX +XXX,XX @@ const char *arm_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname)
151
}
152
return NULL;
153
}
154
+
155
+void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
156
+{
157
+ CPUState *cs = CPU(cpu);
158
+ CPUARMState *env = &cpu->env;
159
+
160
+ if (arm_feature(env, ARM_FEATURE_AARCH64)) {
161
+ /*
162
+ * The lower part of each SVE register aliases to the FPU
163
+ * registers so we don't need to include both.
164
+ */
165
+#ifdef TARGET_AARCH64
166
+ if (isar_feature_aa64_sve(&cpu->isar)) {
167
+ gdb_register_coprocessor(cs, arm_gdb_get_svereg, arm_gdb_set_svereg,
168
+ arm_gen_dynamic_svereg_xml(cs, cs->gdb_num_regs),
169
+ "sve-registers.xml", 0);
170
+ } else {
171
+ gdb_register_coprocessor(cs, aarch64_fpu_gdb_get_reg,
172
+ aarch64_fpu_gdb_set_reg,
173
+ 34, "aarch64-fpu.xml", 0);
174
+ }
175
+#endif
176
+ } else if (arm_feature(env, ARM_FEATURE_NEON)) {
177
+ gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
178
+ 51, "arm-neon.xml", 0);
179
+ } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
180
+ gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
181
+ 35, "arm-vfp3.xml", 0);
182
+ } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
183
+ gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
184
+ 19, "arm-vfp.xml", 0);
185
+ }
186
+ gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
187
+ arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs),
188
+ "system-registers.xml", 0);
189
+
190
+}
191
diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c
192
index XXXXXXX..XXXXXXX 100644
193
--- a/target/arm/gdbstub64.c
194
+++ b/target/arm/gdbstub64.c
195
@@ -XXX,XX +XXX,XX @@
196
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
197
*/
198
#include "qemu/osdep.h"
199
+#include "qemu/log.h"
200
#include "cpu.h"
201
+#include "internals.h"
202
#include "exec/gdbstub.h"
203
204
int aarch64_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
205
@@ -XXX,XX +XXX,XX @@ int aarch64_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
206
/* Unknown register. */
207
return 0;
208
}
209
+
210
+int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
211
+{
212
+ switch (reg) {
213
+ case 0 ... 31:
214
+ {
215
+ /* 128 bit FP register - quads are in LE order */
216
+ uint64_t *q = aa64_vfp_qreg(env, reg);
217
+ return gdb_get_reg128(buf, q[1], q[0]);
218
+ }
219
+ case 32:
220
+ /* FPSR */
221
+ return gdb_get_reg32(buf, vfp_get_fpsr(env));
222
+ case 33:
223
+ /* FPCR */
224
+ return gdb_get_reg32(buf, vfp_get_fpcr(env));
225
+ default:
226
+ return 0;
227
+ }
228
+}
229
+
230
+int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
231
+{
232
+ switch (reg) {
233
+ case 0 ... 31:
234
+ /* 128 bit FP register */
235
+ {
236
+ uint64_t *q = aa64_vfp_qreg(env, reg);
237
+ q[0] = ldq_le_p(buf);
238
+ q[1] = ldq_le_p(buf + 8);
239
+ return 16;
240
+ }
241
+ case 32:
242
+ /* FPSR */
243
+ vfp_set_fpsr(env, ldl_p(buf));
244
+ return 4;
245
+ case 33:
246
+ /* FPCR */
247
+ vfp_set_fpcr(env, ldl_p(buf));
248
+ return 4;
249
+ default:
250
+ return 0;
251
+ }
252
+}
253
+
254
+int arm_gdb_get_svereg(CPUARMState *env, GByteArray *buf, int reg)
255
+{
256
+ ARMCPU *cpu = env_archcpu(env);
257
+
258
+ switch (reg) {
259
+ /* The first 32 registers are the zregs */
260
+ case 0 ... 31:
261
+ {
262
+ int vq, len = 0;
263
+ for (vq = 0; vq < cpu->sve_max_vq; vq++) {
264
+ len += gdb_get_reg128(buf,
265
+ env->vfp.zregs[reg].d[vq * 2 + 1],
266
+ env->vfp.zregs[reg].d[vq * 2]);
267
+ }
268
+ return len;
269
+ }
270
+ case 32:
271
+ return gdb_get_reg32(buf, vfp_get_fpsr(env));
272
+ case 33:
273
+ return gdb_get_reg32(buf, vfp_get_fpcr(env));
274
+ /* then 16 predicates and the ffr */
275
+ case 34 ... 50:
276
+ {
277
+ int preg = reg - 34;
278
+ int vq, len = 0;
279
+ for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
280
+ len += gdb_get_reg64(buf, env->vfp.pregs[preg].p[vq / 4]);
281
+ }
282
+ return len;
283
+ }
284
+ case 51:
285
+ {
286
+ /*
287
+ * We report in Vector Granules (VG) which is 64bit in a Z reg
288
+ * while the ZCR works in Vector Quads (VQ) which is 128bit chunks.
289
+ */
290
+ int vq = sve_zcr_len_for_el(env, arm_current_el(env)) + 1;
291
+ return gdb_get_reg64(buf, vq * 2);
292
+ }
293
+ default:
294
+ /* gdbstub asked for something out our range */
295
+ qemu_log_mask(LOG_UNIMP, "%s: out of range register %d", __func__, reg);
296
+ break;
297
+ }
298
+
299
+ return 0;
300
+}
301
+
302
+int arm_gdb_set_svereg(CPUARMState *env, uint8_t *buf, int reg)
303
+{
304
+ ARMCPU *cpu = env_archcpu(env);
305
+
306
+ /* The first 32 registers are the zregs */
307
+ switch (reg) {
308
+ /* The first 32 registers are the zregs */
309
+ case 0 ... 31:
310
+ {
311
+ int vq, len = 0;
312
+ uint64_t *p = (uint64_t *) buf;
313
+ for (vq = 0; vq < cpu->sve_max_vq; vq++) {
314
+ env->vfp.zregs[reg].d[vq * 2 + 1] = *p++;
315
+ env->vfp.zregs[reg].d[vq * 2] = *p++;
316
+ len += 16;
317
+ }
318
+ return len;
319
+ }
320
+ case 32:
321
+ vfp_set_fpsr(env, *(uint32_t *)buf);
322
+ return 4;
323
+ case 33:
324
+ vfp_set_fpcr(env, *(uint32_t *)buf);
325
+ return 4;
326
+ case 34 ... 50:
327
+ {
328
+ int preg = reg - 34;
329
+ int vq, len = 0;
330
+ uint64_t *p = (uint64_t *) buf;
331
+ for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
332
+ env->vfp.pregs[preg].p[vq / 4] = *p++;
333
+ len += 8;
334
+ }
335
+ return len;
336
+ }
337
+ case 51:
338
+ /* cannot set vg via gdbstub */
339
+ return 0;
340
+ default:
341
+ /* gdbstub asked for something out our range */
342
+ break;
343
+ }
344
+
345
+ return 0;
346
+}
347
diff --git a/target/arm/helper.c b/target/arm/helper.c
66
diff --git a/target/arm/helper.c b/target/arm/helper.c
348
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
349
--- a/target/arm/helper.c
68
--- a/target/arm/helper.c
350
+++ b/target/arm/helper.c
69
+++ b/target/arm/helper.c
351
@@ -XXX,XX +XXX,XX @@
70
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_reginfo[] = {
352
#include "trace.h"
71
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 6,
353
#include "cpu.h"
72
.access = PL1_RW, .accessfn = access_mte,
354
#include "internals.h"
73
.fieldoffset = offsetof(CPUARMState, cp15.gcr_el1) },
355
-#include "exec/gdbstub.h"
74
- { .name = "GMID_EL1", .state = ARM_CP_STATE_AA64,
356
#include "exec/helper-proto.h"
75
- .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 4,
357
#include "qemu/host-utils.h"
76
- .access = PL1_R, .accessfn = access_aa64_tid5,
358
#include "qemu/main-loop.h"
77
- .type = ARM_CP_CONST, .resetvalue = GMID_EL1_BS },
359
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
78
{ .name = "TCO", .state = ARM_CP_STATE_AA64,
360
static void switch_mode(CPUARMState *env, int mode);
79
.opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 7,
361
static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx);
80
.type = ARM_CP_NO_RAW,
362
81
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
363
-static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
82
* then define only a RAZ/WI version of PSTATE.TCO.
364
-{
83
*/
365
- ARMCPU *cpu = env_archcpu(env);
84
if (cpu_isar_feature(aa64_mte, cpu)) {
366
- int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
85
+ ARMCPRegInfo gmid_reginfo = {
367
-
86
+ .name = "GMID_EL1", .state = ARM_CP_STATE_AA64,
368
- /* VFP data registers are always little-endian. */
87
+ .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 4,
369
- if (reg < nregs) {
88
+ .access = PL1_R, .accessfn = access_aa64_tid5,
370
- return gdb_get_reg64(buf, *aa32_vfp_dreg(env, reg));
89
+ .type = ARM_CP_CONST, .resetvalue = cpu->gm_blocksize,
371
- }
90
+ };
372
- if (arm_feature(env, ARM_FEATURE_NEON)) {
91
+ define_one_arm_cp_reg(cpu, &gmid_reginfo);
373
- /* Aliases for Q regs. */
92
define_arm_cp_regs(cpu, mte_reginfo);
374
- nregs += 16;
93
define_arm_cp_regs(cpu, mte_el0_cacheop_reginfo);
375
- if (reg < nregs) {
94
} else if (cpu_isar_feature(aa64_mte_insn_reg, cpu)) {
376
- uint64_t *q = aa32_vfp_qreg(env, reg - 32);
95
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
377
- return gdb_get_reg128(buf, q[0], q[1]);
96
index XXXXXXX..XXXXXXX 100644
378
- }
97
--- a/target/arm/tcg/cpu64.c
379
- }
98
+++ b/target/arm/tcg/cpu64.c
380
- switch (reg - nregs) {
99
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
381
- case 0:
100
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
382
- return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]);
101
cpu->dcz_blocksize = 7; /* 512 bytes */
383
- case 1:
102
#endif
384
- return gdb_get_reg32(buf, vfp_get_fpscr(env));
103
+ cpu->gm_blocksize = 6; /* 256 bytes */
385
- case 2:
104
386
- return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]);
105
cpu->sve_vq.supported = MAKE_64BIT_MASK(0, ARM_MAX_VQ);
387
- }
106
cpu->sme_vq.supported = SVE_VQ_POW2_MAP;
388
- return 0;
107
diff --git a/target/arm/tcg/mte_helper.c b/target/arm/tcg/mte_helper.c
389
-}
108
index XXXXXXX..XXXXXXX 100644
390
-
109
--- a/target/arm/tcg/mte_helper.c
391
-static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
110
+++ b/target/arm/tcg/mte_helper.c
392
-{
111
@@ -XXX,XX +XXX,XX @@ void HELPER(st2g_stub)(CPUARMState *env, uint64_t ptr)
393
- ARMCPU *cpu = env_archcpu(env);
394
- int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
395
-
396
- if (reg < nregs) {
397
- *aa32_vfp_dreg(env, reg) = ldq_le_p(buf);
398
- return 8;
399
- }
400
- if (arm_feature(env, ARM_FEATURE_NEON)) {
401
- nregs += 16;
402
- if (reg < nregs) {
403
- uint64_t *q = aa32_vfp_qreg(env, reg - 32);
404
- q[0] = ldq_le_p(buf);
405
- q[1] = ldq_le_p(buf + 8);
406
- return 16;
407
- }
408
- }
409
- switch (reg - nregs) {
410
- case 0:
411
- env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf);
412
- return 4;
413
- case 1:
414
- vfp_set_fpscr(env, ldl_p(buf));
415
- return 4;
416
- case 2:
417
- env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30);
418
- return 4;
419
- }
420
- return 0;
421
-}
422
-
423
-static int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
424
-{
425
- switch (reg) {
426
- case 0 ... 31:
427
- {
428
- /* 128 bit FP register - quads are in LE order */
429
- uint64_t *q = aa64_vfp_qreg(env, reg);
430
- return gdb_get_reg128(buf, q[1], q[0]);
431
- }
432
- case 32:
433
- /* FPSR */
434
- return gdb_get_reg32(buf, vfp_get_fpsr(env));
435
- case 33:
436
- /* FPCR */
437
- return gdb_get_reg32(buf, vfp_get_fpcr(env));
438
- default:
439
- return 0;
440
- }
441
-}
442
-
443
-static int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
444
-{
445
- switch (reg) {
446
- case 0 ... 31:
447
- /* 128 bit FP register */
448
- {
449
- uint64_t *q = aa64_vfp_qreg(env, reg);
450
- q[0] = ldq_le_p(buf);
451
- q[1] = ldq_le_p(buf + 8);
452
- return 16;
453
- }
454
- case 32:
455
- /* FPSR */
456
- vfp_set_fpsr(env, ldl_p(buf));
457
- return 4;
458
- case 33:
459
- /* FPCR */
460
- vfp_set_fpcr(env, ldl_p(buf));
461
- return 4;
462
- default:
463
- return 0;
464
- }
465
-}
466
-
467
static uint64_t raw_read(CPUARMState *env, const ARMCPRegInfo *ri)
468
{
469
assert(ri->fieldoffset);
470
@@ -XXX,XX +XXX,XX @@ static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
471
}
112
}
472
}
113
}
473
114
474
-/**
115
-#define LDGM_STGM_SIZE (4 << GMID_EL1_BS)
475
- * arm_get/set_gdb_*: get/set a gdb register
476
- * @env: the CPU state
477
- * @buf: a buffer to copy to/from
478
- * @reg: register number (offset from start of group)
479
- *
480
- * We return the number of bytes copied
481
- */
482
-
116
-
483
-static int arm_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg)
117
uint64_t HELPER(ldgm)(CPUARMState *env, uint64_t ptr)
484
-{
485
- ARMCPU *cpu = env_archcpu(env);
486
- const ARMCPRegInfo *ri;
487
- uint32_t key;
488
-
489
- key = cpu->dyn_sysreg_xml.data.cpregs.keys[reg];
490
- ri = get_arm_cp_reginfo(cpu->cp_regs, key);
491
- if (ri) {
492
- if (cpreg_field_is_64bit(ri)) {
493
- return gdb_get_reg64(buf, (uint64_t)read_raw_cp_reg(env, ri));
494
- } else {
495
- return gdb_get_reg32(buf, (uint32_t)read_raw_cp_reg(env, ri));
496
- }
497
- }
498
- return 0;
499
-}
500
-
501
-static int arm_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg)
502
-{
503
- return 0;
504
-}
505
-
506
-#ifdef TARGET_AARCH64
507
-static int arm_gdb_get_svereg(CPUARMState *env, GByteArray *buf, int reg)
508
-{
509
- ARMCPU *cpu = env_archcpu(env);
510
-
511
- switch (reg) {
512
- /* The first 32 registers are the zregs */
513
- case 0 ... 31:
514
- {
515
- int vq, len = 0;
516
- for (vq = 0; vq < cpu->sve_max_vq; vq++) {
517
- len += gdb_get_reg128(buf,
518
- env->vfp.zregs[reg].d[vq * 2 + 1],
519
- env->vfp.zregs[reg].d[vq * 2]);
520
- }
521
- return len;
522
- }
523
- case 32:
524
- return gdb_get_reg32(buf, vfp_get_fpsr(env));
525
- case 33:
526
- return gdb_get_reg32(buf, vfp_get_fpcr(env));
527
- /* then 16 predicates and the ffr */
528
- case 34 ... 50:
529
- {
530
- int preg = reg - 34;
531
- int vq, len = 0;
532
- for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
533
- len += gdb_get_reg64(buf, env->vfp.pregs[preg].p[vq / 4]);
534
- }
535
- return len;
536
- }
537
- case 51:
538
- {
539
- /*
540
- * We report in Vector Granules (VG) which is 64bit in a Z reg
541
- * while the ZCR works in Vector Quads (VQ) which is 128bit chunks.
542
- */
543
- int vq = sve_zcr_len_for_el(env, arm_current_el(env)) + 1;
544
- return gdb_get_reg64(buf, vq * 2);
545
- }
546
- default:
547
- /* gdbstub asked for something out our range */
548
- qemu_log_mask(LOG_UNIMP, "%s: out of range register %d", __func__, reg);
549
- break;
550
- }
551
-
552
- return 0;
553
-}
554
-
555
-static int arm_gdb_set_svereg(CPUARMState *env, uint8_t *buf, int reg)
556
-{
557
- ARMCPU *cpu = env_archcpu(env);
558
-
559
- /* The first 32 registers are the zregs */
560
- switch (reg) {
561
- /* The first 32 registers are the zregs */
562
- case 0 ... 31:
563
- {
564
- int vq, len = 0;
565
- uint64_t *p = (uint64_t *) buf;
566
- for (vq = 0; vq < cpu->sve_max_vq; vq++) {
567
- env->vfp.zregs[reg].d[vq * 2 + 1] = *p++;
568
- env->vfp.zregs[reg].d[vq * 2] = *p++;
569
- len += 16;
570
- }
571
- return len;
572
- }
573
- case 32:
574
- vfp_set_fpsr(env, *(uint32_t *)buf);
575
- return 4;
576
- case 33:
577
- vfp_set_fpcr(env, *(uint32_t *)buf);
578
- return 4;
579
- case 34 ... 50:
580
- {
581
- int preg = reg - 34;
582
- int vq, len = 0;
583
- uint64_t *p = (uint64_t *) buf;
584
- for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
585
- env->vfp.pregs[preg].p[vq / 4] = *p++;
586
- len += 8;
587
- }
588
- return len;
589
- }
590
- case 51:
591
- /* cannot set vg via gdbstub */
592
- return 0;
593
- default:
594
- /* gdbstub asked for something out our range */
595
- break;
596
- }
597
-
598
- return 0;
599
-}
600
-#endif /* TARGET_AARCH64 */
601
-
602
static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
603
{
118
{
604
/* Return true if the regdef would cause an assertion if you called
119
int mmu_idx = cpu_mmu_index(env, false);
605
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
120
uintptr_t ra = GETPC();
606
#endif
121
+ int gm_bs = env_archcpu(env)->gm_blocksize;
122
+ int gm_bs_bytes = 4 << gm_bs;
123
void *tag_mem;
124
125
- ptr = QEMU_ALIGN_DOWN(ptr, LDGM_STGM_SIZE);
126
+ ptr = QEMU_ALIGN_DOWN(ptr, gm_bs_bytes);
127
128
/* Trap if accessing an invalid page. */
129
tag_mem = allocation_tag_mem(env, mmu_idx, ptr, MMU_DATA_LOAD,
130
- LDGM_STGM_SIZE, MMU_DATA_LOAD,
131
- LDGM_STGM_SIZE / (2 * TAG_GRANULE), ra);
132
+ gm_bs_bytes, MMU_DATA_LOAD,
133
+ gm_bs_bytes / (2 * TAG_GRANULE), ra);
134
135
/* The tag is squashed to zero if the page does not support tags. */
136
if (!tag_mem) {
137
return 0;
138
}
139
140
- QEMU_BUILD_BUG_ON(GMID_EL1_BS != 6);
141
/*
142
- * We are loading 64-bits worth of tags. The ordering of elements
143
- * within the word corresponds to a 64-bit little-endian operation.
144
+ * The ordering of elements within the word corresponds to
145
+ * a little-endian operation.
146
*/
147
- return ldq_le_p(tag_mem);
148
+ switch (gm_bs) {
149
+ case 6:
150
+ /* 256 bytes -> 16 tags -> 64 result bits */
151
+ return ldq_le_p(tag_mem);
152
+ default:
153
+ /* cpu configured with unsupported gm blocksize. */
154
+ g_assert_not_reached();
155
+ }
607
}
156
}
608
157
609
-void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
158
void HELPER(stgm)(CPUARMState *env, uint64_t ptr, uint64_t val)
610
-{
611
- CPUState *cs = CPU(cpu);
612
- CPUARMState *env = &cpu->env;
613
-
614
- if (arm_feature(env, ARM_FEATURE_AARCH64)) {
615
- /*
616
- * The lower part of each SVE register aliases to the FPU
617
- * registers so we don't need to include both.
618
- */
619
-#ifdef TARGET_AARCH64
620
- if (isar_feature_aa64_sve(&cpu->isar)) {
621
- gdb_register_coprocessor(cs, arm_gdb_get_svereg, arm_gdb_set_svereg,
622
- arm_gen_dynamic_svereg_xml(cs, cs->gdb_num_regs),
623
- "sve-registers.xml", 0);
624
- } else
625
-#endif
626
- {
627
- gdb_register_coprocessor(cs, aarch64_fpu_gdb_get_reg,
628
- aarch64_fpu_gdb_set_reg,
629
- 34, "aarch64-fpu.xml", 0);
630
- }
631
- } else if (arm_feature(env, ARM_FEATURE_NEON)) {
632
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
633
- 51, "arm-neon.xml", 0);
634
- } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
635
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
636
- 35, "arm-vfp3.xml", 0);
637
- } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
638
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
639
- 19, "arm-vfp.xml", 0);
640
- }
641
- gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
642
- arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs),
643
- "system-registers.xml", 0);
644
-
645
-}
646
-
647
/* Sort alphabetically by type name, except for "any". */
648
static gint arm_cpu_list_compare(gconstpointer a, gconstpointer b)
649
{
159
{
160
int mmu_idx = cpu_mmu_index(env, false);
161
uintptr_t ra = GETPC();
162
+ int gm_bs = env_archcpu(env)->gm_blocksize;
163
+ int gm_bs_bytes = 4 << gm_bs;
164
void *tag_mem;
165
166
- ptr = QEMU_ALIGN_DOWN(ptr, LDGM_STGM_SIZE);
167
+ ptr = QEMU_ALIGN_DOWN(ptr, gm_bs_bytes);
168
169
/* Trap if accessing an invalid page. */
170
tag_mem = allocation_tag_mem(env, mmu_idx, ptr, MMU_DATA_STORE,
171
- LDGM_STGM_SIZE, MMU_DATA_LOAD,
172
- LDGM_STGM_SIZE / (2 * TAG_GRANULE), ra);
173
+ gm_bs_bytes, MMU_DATA_LOAD,
174
+ gm_bs_bytes / (2 * TAG_GRANULE), ra);
175
176
/*
177
* Tag store only happens if the page support tags,
178
@@ -XXX,XX +XXX,XX @@ void HELPER(stgm)(CPUARMState *env, uint64_t ptr, uint64_t val)
179
return;
180
}
181
182
- QEMU_BUILD_BUG_ON(GMID_EL1_BS != 6);
183
/*
184
- * We are storing 64-bits worth of tags. The ordering of elements
185
- * within the word corresponds to a 64-bit little-endian operation.
186
+ * The ordering of elements within the word corresponds to
187
+ * a little-endian operation.
188
*/
189
- stq_le_p(tag_mem, val);
190
+ switch (gm_bs) {
191
+ case 6:
192
+ stq_le_p(tag_mem, val);
193
+ break;
194
+ default:
195
+ /* cpu configured with unsupported gm blocksize. */
196
+ g_assert_not_reached();
197
+ }
198
}
199
200
void HELPER(stzgm_tags)(CPUARMState *env, uint64_t ptr, uint64_t val)
201
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
202
index XXXXXXX..XXXXXXX 100644
203
--- a/target/arm/tcg/translate-a64.c
204
+++ b/target/arm/tcg/translate-a64.c
205
@@ -XXX,XX +XXX,XX @@ static bool trans_STGM(DisasContext *s, arg_ldst_tag *a)
206
gen_helper_stgm(cpu_env, addr, tcg_rt);
207
} else {
208
MMUAccessType acc = MMU_DATA_STORE;
209
- int size = 4 << GMID_EL1_BS;
210
+ int size = 4 << s->gm_blocksize;
211
212
clean_addr = clean_data_tbi(s, addr);
213
tcg_gen_andi_i64(clean_addr, clean_addr, -size);
214
@@ -XXX,XX +XXX,XX @@ static bool trans_LDGM(DisasContext *s, arg_ldst_tag *a)
215
gen_helper_ldgm(tcg_rt, cpu_env, addr);
216
} else {
217
MMUAccessType acc = MMU_DATA_LOAD;
218
- int size = 4 << GMID_EL1_BS;
219
+ int size = 4 << s->gm_blocksize;
220
221
clean_addr = clean_data_tbi(s, addr);
222
tcg_gen_andi_i64(clean_addr, clean_addr, -size);
223
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
224
dc->cp_regs = arm_cpu->cp_regs;
225
dc->features = env->features;
226
dc->dcz_blocksize = arm_cpu->dcz_blocksize;
227
+ dc->gm_blocksize = arm_cpu->gm_blocksize;
228
229
#ifdef CONFIG_USER_ONLY
230
/* In sve_probe_page, we assume TBI is enabled. */
650
--
231
--
651
2.20.1
232
2.34.1
652
653
diff view generated by jsdifflib
1
Rename the "allocate and return" qbus creation function to
1
From: Richard Henderson <richard.henderson@linaro.org>
2
qbus_new(), to bring it into line with our _init vs _new convention.
3
2
3
Support all of the easy GM block sizes.
4
Use direct memory operations, since the pointers are aligned.
5
6
While BS=2 (16 bytes, 1 tag) is a legal setting, that requires
7
an atomic store of one nibble. This is not difficult, but there
8
is also no point in supporting it until required.
9
10
Note that cortex-a710 sets GM blocksize to match its cacheline
11
size of 64 bytes. I expect many implementations will also
12
match the cacheline, which makes 16 bytes very unlikely.
13
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Message-id: 20230811214031.171020-4-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
7
Reviewed-by: Corey Minyard <cminyard@mvista.com>
8
Message-id: 20210923121153.23754-6-peter.maydell@linaro.org
9
---
18
---
10
include/hw/qdev-core.h | 2 +-
19
target/arm/cpu.c | 18 +++++++++---
11
hw/core/bus.c | 2 +-
20
target/arm/tcg/mte_helper.c | 56 +++++++++++++++++++++++++++++++------
12
hw/hyperv/vmbus.c | 2 +-
21
2 files changed, 62 insertions(+), 12 deletions(-)
13
hw/i2c/core.c | 2 +-
14
hw/isa/isa-bus.c | 2 +-
15
hw/misc/auxbus.c | 2 +-
16
hw/pci/pci.c | 2 +-
17
hw/ppc/spapr_vio.c | 2 +-
18
hw/s390x/ap-bridge.c | 2 +-
19
hw/s390x/css-bridge.c | 2 +-
20
hw/s390x/s390-pci-bus.c | 2 +-
21
hw/ssi/ssi.c | 2 +-
22
hw/xen/xen-bus.c | 2 +-
23
hw/xen/xen-legacy-backend.c | 2 +-
24
14 files changed, 14 insertions(+), 14 deletions(-)
25
22
26
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
23
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
27
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/qdev-core.h
25
--- a/target/arm/cpu.c
29
+++ b/include/hw/qdev-core.h
26
+++ b/target/arm/cpu.c
30
@@ -XXX,XX +XXX,XX @@ typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque);
27
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
31
28
ID_PFR1, VIRTUALIZATION, 0);
32
void qbus_init(void *bus, size_t size, const char *typename,
29
}
33
DeviceState *parent, const char *name);
30
34
-BusState *qbus_create(const char *typename, DeviceState *parent, const char *name);
31
+ if (cpu_isar_feature(aa64_mte, cpu)) {
35
+BusState *qbus_new(const char *typename, DeviceState *parent, const char *name);
32
+ /*
36
bool qbus_realize(BusState *bus, Error **errp);
33
+ * The architectural range of GM blocksize is 2-6, however qemu
37
void qbus_unrealize(BusState *bus);
34
+ * doesn't support blocksize of 2 (see HELPER(ldgm)).
38
35
+ */
39
diff --git a/hw/core/bus.c b/hw/core/bus.c
36
+ if (tcg_enabled()) {
37
+ assert(cpu->gm_blocksize >= 3 && cpu->gm_blocksize <= 6);
38
+ }
39
+
40
#ifndef CONFIG_USER_ONLY
41
- if (cpu->tag_memory == NULL && cpu_isar_feature(aa64_mte, cpu)) {
42
/*
43
* Disable the MTE feature bits if we do not have tag-memory
44
* provided by the machine.
45
*/
46
- cpu->isar.id_aa64pfr1 =
47
- FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 0);
48
- }
49
+ if (cpu->tag_memory == NULL) {
50
+ cpu->isar.id_aa64pfr1 =
51
+ FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 0);
52
+ }
53
#endif
54
+ }
55
56
if (tcg_enabled()) {
57
/*
58
diff --git a/target/arm/tcg/mte_helper.c b/target/arm/tcg/mte_helper.c
40
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/core/bus.c
60
--- a/target/arm/tcg/mte_helper.c
42
+++ b/hw/core/bus.c
61
+++ b/target/arm/tcg/mte_helper.c
43
@@ -XXX,XX +XXX,XX @@ void qbus_init(void *bus, size_t size, const char *typename,
62
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(ldgm)(CPUARMState *env, uint64_t ptr)
44
qbus_init_internal(bus, parent, name);
63
int gm_bs = env_archcpu(env)->gm_blocksize;
64
int gm_bs_bytes = 4 << gm_bs;
65
void *tag_mem;
66
+ uint64_t ret;
67
+ int shift;
68
69
ptr = QEMU_ALIGN_DOWN(ptr, gm_bs_bytes);
70
71
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(ldgm)(CPUARMState *env, uint64_t ptr)
72
73
/*
74
* The ordering of elements within the word corresponds to
75
- * a little-endian operation.
76
+ * a little-endian operation. Computation of shift comes from
77
+ *
78
+ * index = address<LOG2_TAG_GRANULE+3:LOG2_TAG_GRANULE>
79
+ * data<index*4+3:index*4> = tag
80
+ *
81
+ * Because of the alignment of ptr above, BS=6 has shift=0.
82
+ * All memory operations are aligned. Defer support for BS=2,
83
+ * requiring insertion or extraction of a nibble, until we
84
+ * support a cpu that requires it.
85
*/
86
switch (gm_bs) {
87
+ case 3:
88
+ /* 32 bytes -> 2 tags -> 8 result bits */
89
+ ret = *(uint8_t *)tag_mem;
90
+ break;
91
+ case 4:
92
+ /* 64 bytes -> 4 tags -> 16 result bits */
93
+ ret = cpu_to_le16(*(uint16_t *)tag_mem);
94
+ break;
95
+ case 5:
96
+ /* 128 bytes -> 8 tags -> 32 result bits */
97
+ ret = cpu_to_le32(*(uint32_t *)tag_mem);
98
+ break;
99
case 6:
100
/* 256 bytes -> 16 tags -> 64 result bits */
101
- return ldq_le_p(tag_mem);
102
+ return cpu_to_le64(*(uint64_t *)tag_mem);
103
default:
104
- /* cpu configured with unsupported gm blocksize. */
105
+ /*
106
+ * CPU configured with unsupported/invalid gm blocksize.
107
+ * This is detected early in arm_cpu_realizefn.
108
+ */
109
g_assert_not_reached();
110
}
111
+ shift = extract64(ptr, LOG2_TAG_GRANULE, 4) * 4;
112
+ return ret << shift;
45
}
113
}
46
114
47
-BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
115
void HELPER(stgm)(CPUARMState *env, uint64_t ptr, uint64_t val)
48
+BusState *qbus_new(const char *typename, DeviceState *parent, const char *name)
116
@@ -XXX,XX +XXX,XX @@ void HELPER(stgm)(CPUARMState *env, uint64_t ptr, uint64_t val)
49
{
117
int gm_bs = env_archcpu(env)->gm_blocksize;
50
BusState *bus;
118
int gm_bs_bytes = 4 << gm_bs;
51
119
void *tag_mem;
52
diff --git a/hw/hyperv/vmbus.c b/hw/hyperv/vmbus.c
120
+ int shift;
53
index XXXXXXX..XXXXXXX 100644
121
54
--- a/hw/hyperv/vmbus.c
122
ptr = QEMU_ALIGN_DOWN(ptr, gm_bs_bytes);
55
+++ b/hw/hyperv/vmbus.c
123
56
@@ -XXX,XX +XXX,XX @@ static void vmbus_bridge_realize(DeviceState *dev, Error **errp)
124
@@ -XXX,XX +XXX,XX @@ void HELPER(stgm)(CPUARMState *env, uint64_t ptr, uint64_t val)
57
return;
125
return;
58
}
126
}
59
127
60
- bridge->bus = VMBUS(qbus_create(TYPE_VMBUS, dev, "vmbus"));
128
- /*
61
+ bridge->bus = VMBUS(qbus_new(TYPE_VMBUS, dev, "vmbus"));
129
- * The ordering of elements within the word corresponds to
62
}
130
- * a little-endian operation.
63
131
- */
64
static char *vmbus_bridge_ofw_unit_address(const SysBusDevice *dev)
132
+ /* See LDGM for comments on BS and on shift. */
65
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
133
+ shift = extract64(ptr, LOG2_TAG_GRANULE, 4) * 4;
66
index XXXXXXX..XXXXXXX 100644
134
+ val >>= shift;
67
--- a/hw/i2c/core.c
135
switch (gm_bs) {
68
+++ b/hw/i2c/core.c
136
+ case 3:
69
@@ -XXX,XX +XXX,XX @@ I2CBus *i2c_init_bus(DeviceState *parent, const char *name)
137
+ /* 32 bytes -> 2 tags -> 8 result bits */
70
{
138
+ *(uint8_t *)tag_mem = val;
71
I2CBus *bus;
139
+ break;
72
140
+ case 4:
73
- bus = I2C_BUS(qbus_create(TYPE_I2C_BUS, parent, name));
141
+ /* 64 bytes -> 4 tags -> 16 result bits */
74
+ bus = I2C_BUS(qbus_new(TYPE_I2C_BUS, parent, name));
142
+ *(uint16_t *)tag_mem = cpu_to_le16(val);
75
QLIST_INIT(&bus->current_devs);
143
+ break;
76
vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_i2c_bus, bus);
144
+ case 5:
77
return bus;
145
+ /* 128 bytes -> 8 tags -> 32 result bits */
78
diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
146
+ *(uint32_t *)tag_mem = cpu_to_le32(val);
79
index XXXXXXX..XXXXXXX 100644
147
+ break;
80
--- a/hw/isa/isa-bus.c
148
case 6:
81
+++ b/hw/isa/isa-bus.c
149
- stq_le_p(tag_mem, val);
82
@@ -XXX,XX +XXX,XX @@ ISABus *isa_bus_new(DeviceState *dev, MemoryRegion* address_space,
150
+ /* 256 bytes -> 16 tags -> 64 result bits */
83
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
151
+ *(uint64_t *)tag_mem = cpu_to_le64(val);
84
}
152
break;
85
153
default:
86
- isabus = ISA_BUS(qbus_create(TYPE_ISA_BUS, dev, NULL));
154
/* cpu configured with unsupported gm blocksize. */
87
+ isabus = ISA_BUS(qbus_new(TYPE_ISA_BUS, dev, NULL));
88
isabus->address_space = address_space;
89
isabus->address_space_io = address_space_io;
90
return isabus;
91
diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/hw/misc/auxbus.c
94
+++ b/hw/misc/auxbus.c
95
@@ -XXX,XX +XXX,XX @@ AUXBus *aux_bus_init(DeviceState *parent, const char *name)
96
AUXBus *bus;
97
Object *auxtoi2c;
98
99
- bus = AUX_BUS(qbus_create(TYPE_AUX_BUS, parent, name));
100
+ bus = AUX_BUS(qbus_new(TYPE_AUX_BUS, parent, name));
101
auxtoi2c = object_new_with_props(TYPE_AUXTOI2C, OBJECT(bus), "i2c",
102
&error_abort, NULL);
103
104
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/hw/pci/pci.c
107
+++ b/hw/pci/pci.c
108
@@ -XXX,XX +XXX,XX @@ PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
109
{
110
PCIBus *bus;
111
112
- bus = PCI_BUS(qbus_create(typename, parent, name));
113
+ bus = PCI_BUS(qbus_new(typename, parent, name));
114
pci_root_bus_internal_init(bus, parent, address_space_mem,
115
address_space_io, devfn_min);
116
return bus;
117
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/hw/ppc/spapr_vio.c
120
+++ b/hw/ppc/spapr_vio.c
121
@@ -XXX,XX +XXX,XX @@ SpaprVioBus *spapr_vio_bus_init(void)
122
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
123
124
/* Create bus on bridge device */
125
- qbus = qbus_create(TYPE_SPAPR_VIO_BUS, dev, "spapr-vio");
126
+ qbus = qbus_new(TYPE_SPAPR_VIO_BUS, dev, "spapr-vio");
127
bus = SPAPR_VIO_BUS(qbus);
128
bus->next_reg = SPAPR_VIO_REG_BASE;
129
130
diff --git a/hw/s390x/ap-bridge.c b/hw/s390x/ap-bridge.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/hw/s390x/ap-bridge.c
133
+++ b/hw/s390x/ap-bridge.c
134
@@ -XXX,XX +XXX,XX @@ void s390_init_ap(void)
135
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
136
137
/* Create bus on bridge device */
138
- bus = qbus_create(TYPE_AP_BUS, dev, TYPE_AP_BUS);
139
+ bus = qbus_new(TYPE_AP_BUS, dev, TYPE_AP_BUS);
140
141
/* Enable hotplugging */
142
qbus_set_hotplug_handler(bus, OBJECT(dev));
143
diff --git a/hw/s390x/css-bridge.c b/hw/s390x/css-bridge.c
144
index XXXXXXX..XXXXXXX 100644
145
--- a/hw/s390x/css-bridge.c
146
+++ b/hw/s390x/css-bridge.c
147
@@ -XXX,XX +XXX,XX @@ VirtualCssBus *virtual_css_bus_init(void)
148
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
149
150
/* Create bus on bridge device */
151
- bus = qbus_create(TYPE_VIRTUAL_CSS_BUS, dev, "virtual-css");
152
+ bus = qbus_new(TYPE_VIRTUAL_CSS_BUS, dev, "virtual-css");
153
cbus = VIRTUAL_CSS_BUS(bus);
154
155
/* Enable hotplugging */
156
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
157
index XXXXXXX..XXXXXXX 100644
158
--- a/hw/s390x/s390-pci-bus.c
159
+++ b/hw/s390x/s390-pci-bus.c
160
@@ -XXX,XX +XXX,XX @@ static void s390_pcihost_realize(DeviceState *dev, Error **errp)
161
qbus_set_hotplug_handler(bus, OBJECT(dev));
162
phb->bus = b;
163
164
- s->bus = S390_PCI_BUS(qbus_create(TYPE_S390_PCI_BUS, dev, NULL));
165
+ s->bus = S390_PCI_BUS(qbus_new(TYPE_S390_PCI_BUS, dev, NULL));
166
qbus_set_hotplug_handler(BUS(s->bus), OBJECT(dev));
167
168
s->iommu_table = g_hash_table_new_full(g_int64_hash, g_int64_equal,
169
diff --git a/hw/ssi/ssi.c b/hw/ssi/ssi.c
170
index XXXXXXX..XXXXXXX 100644
171
--- a/hw/ssi/ssi.c
172
+++ b/hw/ssi/ssi.c
173
@@ -XXX,XX +XXX,XX @@ DeviceState *ssi_create_peripheral(SSIBus *bus, const char *name)
174
SSIBus *ssi_create_bus(DeviceState *parent, const char *name)
175
{
176
BusState *bus;
177
- bus = qbus_create(TYPE_SSI_BUS, parent, name);
178
+ bus = qbus_new(TYPE_SSI_BUS, parent, name);
179
return SSI_BUS(bus);
180
}
181
182
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
183
index XXXXXXX..XXXXXXX 100644
184
--- a/hw/xen/xen-bus.c
185
+++ b/hw/xen/xen-bus.c
186
@@ -XXX,XX +XXX,XX @@ type_init(xen_register_types)
187
void xen_bus_init(void)
188
{
189
DeviceState *dev = qdev_new(TYPE_XEN_BRIDGE);
190
- BusState *bus = qbus_create(TYPE_XEN_BUS, dev, NULL);
191
+ BusState *bus = qbus_new(TYPE_XEN_BUS, dev, NULL);
192
193
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
194
qbus_set_bus_hotplug_handler(bus);
195
diff --git a/hw/xen/xen-legacy-backend.c b/hw/xen/xen-legacy-backend.c
196
index XXXXXXX..XXXXXXX 100644
197
--- a/hw/xen/xen-legacy-backend.c
198
+++ b/hw/xen/xen-legacy-backend.c
199
@@ -XXX,XX +XXX,XX @@ int xen_be_init(void)
200
201
xen_sysdev = qdev_new(TYPE_XENSYSDEV);
202
sysbus_realize_and_unref(SYS_BUS_DEVICE(xen_sysdev), &error_fatal);
203
- xen_sysbus = qbus_create(TYPE_XENSYSBUS, xen_sysdev, "xen-sysbus");
204
+ xen_sysbus = qbus_new(TYPE_XENSYSBUS, xen_sysdev, "xen-sysbus");
205
qbus_set_bus_hotplug_handler(xen_sysbus);
206
207
return 0;
208
--
155
--
209
2.20.1
156
2.34.1
210
211
diff view generated by jsdifflib
1
From: Xuzhou Cheng <xuzhou.cheng@windriver.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The Linux spi-imx driver does not work on QEMU. The reason is that the
3
When the cpu support MTE, but the system does not, reduce cpu
4
state of m25p80 loops in STATE_READING_DATA state after receiving
4
support to user instructions at EL0 instead of completely
5
RDSR command, the new command is ignored. Before sending a new command,
5
disabling MTE. If we encounter a cpu implementation which does
6
CS line should be pulled high to make the state of m25p80 back to IDLE.
6
something else, we can revisit this setting.
7
7
8
Currently the SPI flash CS line is connected to the SPI controller, but
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
on the real board, it's connected to GPIO3_19. This matches the ecspi1
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
device node in the board dts.
10
Message-id: 20230811214031.171020-5-richard.henderson@linaro.org
11
12
ecspi1 node in imx6qdl-sabrelite.dtsi:
13
&ecspi1 {
14
cs-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;
15
pinctrl-names = "default";
16
pinctrl-0 = <&pinctrl_ecspi1>;
17
status = "okay";
18
19
flash: m25p80@0 {
20
compatible = "sst,sst25vf016b", "jedec,spi-nor";
21
spi-max-frequency = <20000000>;
22
reg = <0>;
23
};
24
};
25
26
Should connect the SSI_GPIO_CS to GPIO3_19 when adding a spi-nor to
27
spi1 on sabrelite machine.
28
29
Verified this patch on Linux v5.14.
30
31
Logs:
32
# echo "01234567899876543210" > test
33
# mtd_debug erase /dev/mtd0 0x0 0x1000
34
Erased 4096 bytes from address 0x00000000 in flash
35
# mtd_debug write /dev/mtdblock0 0x0 20 test
36
Copied 20 bytes from test to address 0x00000000 in flash
37
# mtd_debug read /dev/mtdblock0 0x0 20 test_out
38
Copied 20 bytes from address 0x00000000 in flash to test_out
39
# cat test_out
40
01234567899876543210#
41
42
Signed-off-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
43
Reported-by: Guenter Roeck <linux@roeck-us.net>
44
Reviewed-by: Bin Meng <bin.meng@windriver.com>
45
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
46
Message-id: 20210927142825.491-1-xchengl.cn@gmail.com
47
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
---
12
---
49
hw/arm/sabrelite.c | 2 +-
13
target/arm/cpu.c | 7 ++++---
50
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 4 insertions(+), 3 deletions(-)
51
15
52
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
16
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
53
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/arm/sabrelite.c
18
--- a/target/arm/cpu.c
55
+++ b/hw/arm/sabrelite.c
19
+++ b/target/arm/cpu.c
56
@@ -XXX,XX +XXX,XX @@ static void sabrelite_init(MachineState *machine)
20
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
57
qdev_realize_and_unref(flash_dev, BUS(spi_bus), &error_fatal);
21
58
22
#ifndef CONFIG_USER_ONLY
59
cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
23
/*
60
- sysbus_connect_irq(SYS_BUS_DEVICE(spi_dev), 1, cs_line);
24
- * Disable the MTE feature bits if we do not have tag-memory
61
+ qdev_connect_gpio_out(DEVICE(&s->gpio[2]), 19, cs_line);
25
- * provided by the machine.
62
}
26
+ * If we do not have tag-memory provided by the machine,
27
+ * reduce MTE support to instructions enabled at EL0.
28
+ * This matches Cortex-A710 BROADCASTMTE input being LOW.
29
*/
30
if (cpu->tag_memory == NULL) {
31
cpu->isar.id_aa64pfr1 =
32
- FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 0);
33
+ FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 1);
63
}
34
}
35
#endif
64
}
36
}
65
--
37
--
66
2.20.1
38
2.34.1
67
68
diff view generated by jsdifflib
1
From: Tong Ho <tong.ho@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Connect the support for ZynqMP eFUSE one-time field-programmable
3
Do not hard-code the constants for Neoverse V1.
4
bit array.
5
4
6
The command argument:
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
-drive if=pflash,index=3,...
8
Can be used to optionally connect the bit array to a
9
backend storage, such that field-programmed values
10
in one invocation can be made available to next
11
invocation.
12
13
The backend storage must be a seekable binary file, and
14
its size must be 768 bytes or larger. A file with all
15
binary 0's is a 'blank'.
16
17
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
18
Message-id: 20210917052400.1249094-9-tong.ho@xilinx.com
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20230811214031.171020-6-richard.henderson@linaro.org
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
9
---
22
include/hw/arm/xlnx-zynqmp.h | 3 +++
10
target/arm/tcg/cpu64.c | 48 ++++++++++++++++++++++++++++--------------
23
hw/arm/xlnx-zcu102.c | 15 +++++++++++++++
11
1 file changed, 32 insertions(+), 16 deletions(-)
24
hw/arm/xlnx-zynqmp.c | 29 +++++++++++++++++++++++++++++
25
hw/Kconfig | 1 +
26
4 files changed, 48 insertions(+)
27
12
28
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
13
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
29
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/arm/xlnx-zynqmp.h
15
--- a/target/arm/tcg/cpu64.c
31
+++ b/include/hw/arm/xlnx-zynqmp.h
16
+++ b/target/arm/tcg/cpu64.c
32
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@
33
#include "net/can_emu.h"
18
#include "qemu/module.h"
34
#include "hw/dma/xlnx_csu_dma.h"
19
#include "qapi/visitor.h"
35
#include "hw/nvram/xlnx-bbram.h"
20
#include "hw/qdev-properties.h"
36
+#include "hw/nvram/xlnx-zynqmp-efuse.h"
21
+#include "qemu/units.h"
37
22
#include "internals.h"
38
#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
23
#include "cpregs.h"
39
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
24
40
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
25
+static uint64_t make_ccsidr64(unsigned assoc, unsigned linesize,
41
MemoryRegion *ddr_ram;
26
+ unsigned cachesize)
42
MemoryRegion ddr_ram_low, ddr_ram_high;
43
XlnxBBRam bbram;
44
+ XlnxEFuse efuse;
45
+ XlnxZynqMPEFuse efuse_ctrl;
46
47
MemoryRegion mr_unimp[XLNX_ZYNQMP_NUM_UNIMP_AREAS];
48
49
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/xlnx-zcu102.c
52
+++ b/hw/arm/xlnx-zcu102.c
53
@@ -XXX,XX +XXX,XX @@ static void bbram_attach_drive(XlnxBBRam *dev)
54
}
55
}
56
57
+static void efuse_attach_drive(XlnxEFuse *dev)
58
+{
27
+{
59
+ DriveInfo *dinfo;
28
+ unsigned lg_linesize = ctz32(linesize);
60
+ BlockBackend *blk;
29
+ unsigned sets;
61
+
30
+
62
+ dinfo = drive_get_by_index(IF_PFLASH, 3);
31
+ /*
63
+ blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
32
+ * The 64-bit CCSIDR_EL1 format is:
64
+ if (blk) {
33
+ * [55:32] number of sets - 1
65
+ qdev_prop_set_drive(DEVICE(dev), "drive", blk);
34
+ * [23:3] associativity - 1
66
+ }
35
+ * [2:0] log2(linesize) - 4
36
+ * so 0 == 16 bytes, 1 == 32 bytes, 2 == 64 bytes, etc
37
+ */
38
+ assert(assoc != 0);
39
+ assert(is_power_of_2(linesize));
40
+ assert(lg_linesize >= 4 && lg_linesize <= 7 + 4);
41
+
42
+ /* sets * associativity * linesize == cachesize. */
43
+ sets = cachesize / (assoc * linesize);
44
+ assert(cachesize % (assoc * linesize) == 0);
45
+
46
+ return ((uint64_t)(sets - 1) << 32)
47
+ | ((assoc - 1) << 3)
48
+ | (lg_linesize - 4);
67
+}
49
+}
68
+
50
+
69
static void xlnx_zcu102_init(MachineState *machine)
51
static void aarch64_a35_initfn(Object *obj)
70
{
52
{
71
XlnxZCU102 *s = ZCU102_MACHINE(machine);
53
ARMCPU *cpu = ARM_CPU(obj);
72
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_init(MachineState *machine)
54
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_v1_initfn(Object *obj)
73
/* Attach bbram backend, if given */
55
* The Neoverse-V1 r1p2 TRM lists 32-bit format CCSIDR_EL1 values,
74
bbram_attach_drive(&s->soc.bbram);
56
* but also says it implements CCIDX, which means they should be
75
57
* 64-bit format. So we here use values which are based on the textual
76
+ /* Attach efuse backend, if given */
58
- * information in chapter 2 of the TRM (and on the fact that
77
+ efuse_attach_drive(&s->soc.efuse);
59
- * sets * associativity * linesize == cachesize).
78
+
60
- *
79
/* Create and plug in the SD cards */
61
- * The 64-bit CCSIDR_EL1 format is:
80
for (i = 0; i < XLNX_ZYNQMP_NUM_SDHCI; i++) {
62
- * [55:32] number of sets - 1
81
BusState *bus;
63
- * [23:3] associativity - 1
82
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
64
- * [2:0] log2(linesize) - 4
83
index XXXXXXX..XXXXXXX 100644
65
- * so 0 == 16 bytes, 1 == 32 bytes, 2 == 64 bytes, etc
84
--- a/hw/arm/xlnx-zynqmp.c
66
- *
85
+++ b/hw/arm/xlnx-zynqmp.c
67
- * L1: 4-way set associative 64-byte line size, total size 64K,
86
@@ -XXX,XX +XXX,XX @@
68
- * so sets is 256.
87
#define BBRAM_ADDR 0xffcd0000
69
+ * information in chapter 2 of the TRM:
88
#define BBRAM_IRQ 11
70
*
89
71
+ * L1: 4-way set associative 64-byte line size, total size 64K.
90
+#define EFUSE_ADDR 0xffcc0000
72
* L2: 8-way set associative, 64 byte line size, either 512K or 1MB.
91
+#define EFUSE_IRQ 87
73
- * We pick 1MB, so this has 2048 sets.
92
+
74
- *
93
#define SDHCI_CAPABILITIES 0x280737ec6481 /* Datasheet: UG1085 (v1.7) */
75
* L3: No L3 (this matches the CLIDR_EL1 value).
94
76
*/
95
static const uint64_t gem_addr[XLNX_ZYNQMP_NUM_GEMS] = {
77
- cpu->ccsidr[0] = 0x000000ff0000001aull; /* 64KB L1 dcache */
96
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_bbram(XlnxZynqMPState *s, qemu_irq *gic)
78
- cpu->ccsidr[1] = 0x000000ff0000001aull; /* 64KB L1 icache */
97
sysbus_connect_irq(sbd, 0, gic[BBRAM_IRQ]);
79
- cpu->ccsidr[2] = 0x000007ff0000003aull; /* 1MB L2 cache */
98
}
80
+ cpu->ccsidr[0] = make_ccsidr64(4, 64, 64 * KiB); /* L1 dcache */
99
81
+ cpu->ccsidr[1] = cpu->ccsidr[0]; /* L1 icache */
100
+static void xlnx_zynqmp_create_efuse(XlnxZynqMPState *s, qemu_irq *gic)
82
+ cpu->ccsidr[2] = make_ccsidr64(8, 64, 1 * MiB); /* L2 cache */
101
+{
83
102
+ Object *bits = OBJECT(&s->efuse);
84
/* From 3.2.115 SCTLR_EL3 */
103
+ Object *ctrl = OBJECT(&s->efuse_ctrl);
85
cpu->reset_sctlr = 0x30c50838;
104
+ SysBusDevice *sbd;
105
+
106
+ object_initialize_child(OBJECT(s), "efuse-ctrl", &s->efuse_ctrl,
107
+ TYPE_XLNX_ZYNQMP_EFUSE);
108
+
109
+ object_initialize_child_with_props(ctrl, "xlnx-efuse@0", bits,
110
+ sizeof(s->efuse),
111
+ TYPE_XLNX_EFUSE, &error_abort,
112
+ "efuse-nr", "3",
113
+ "efuse-size", "2048",
114
+ NULL);
115
+
116
+ qdev_realize(DEVICE(bits), NULL, &error_abort);
117
+ object_property_set_link(ctrl, "efuse", bits, &error_abort);
118
+
119
+ sbd = SYS_BUS_DEVICE(ctrl);
120
+ sysbus_realize(sbd, &error_abort);
121
+ sysbus_mmio_map(sbd, 0, EFUSE_ADDR);
122
+ sysbus_connect_irq(sbd, 0, gic[EFUSE_IRQ]);
123
+}
124
+
125
static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
126
{
127
static const struct UnimpInfo {
128
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
129
sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, gic_spi[RTC_IRQ]);
130
131
xlnx_zynqmp_create_bbram(s, gic_spi);
132
+ xlnx_zynqmp_create_efuse(s, gic_spi);
133
xlnx_zynqmp_create_unimp_mmio(s);
134
135
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
136
diff --git a/hw/Kconfig b/hw/Kconfig
137
index XXXXXXX..XXXXXXX 100644
138
--- a/hw/Kconfig
139
+++ b/hw/Kconfig
140
@@ -XXX,XX +XXX,XX @@ config XLNX_ZYNQMP
141
select CAN_BUS
142
select PTIMER
143
select XLNX_BBRAM
144
+ select XLNX_EFUSE_ZYNQMP
145
--
86
--
146
2.20.1
87
2.34.1
147
148
diff view generated by jsdifflib
1
We're going to move this code to a different file; fix the coding
1
From: Richard Henderson <richard.henderson@linaro.org>
2
style first so checkpatch doesn't complain. This includes deleting
3
the spurious 'break' statements after returns in the
4
vfp_gdb_get_reg() function.
5
2
3
Access to many of the special registers is enabled or disabled
4
by ACTLR_EL[23], which we implement as constant 0, which means
5
that all writes outside EL3 should trap.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20230811214031.171020-7-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210921162901.17508-3-peter.maydell@linaro.org
10
---
11
---
11
target/arm/helper.c | 23 ++++++++++++++++-------
12
target/arm/cpregs.h | 2 ++
12
1 file changed, 16 insertions(+), 7 deletions(-)
13
target/arm/helper.c | 4 ++--
14
target/arm/tcg/cpu64.c | 46 +++++++++++++++++++++++++++++++++---------
15
3 files changed, 41 insertions(+), 11 deletions(-)
13
16
17
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpregs.h
20
+++ b/target/arm/cpregs.h
21
@@ -XXX,XX +XXX,XX @@ static inline void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) { }
22
void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu);
23
#endif
24
25
+CPAccessResult access_tvm_trvm(CPUARMState *, const ARMCPRegInfo *, bool);
26
+
27
#endif /* TARGET_ARM_CPREGS_H */
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
30
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
31
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
32
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tpm(CPUARMState *env, const ARMCPRegInfo *ri,
19
}
20
}
21
switch (reg - nregs) {
22
- case 0: return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]); break;
23
- case 1: return gdb_get_reg32(buf, vfp_get_fpscr(env)); break;
24
- case 2: return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]); break;
25
+ case 0:
26
+ return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]);
27
+ case 1:
28
+ return gdb_get_reg32(buf, vfp_get_fpscr(env));
29
+ case 2:
30
+ return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]);
31
}
32
return 0;
33
}
33
}
34
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
34
35
}
35
/* Check for traps from EL1 due to HCR_EL2.TVM and HCR_EL2.TRVM. */
36
}
36
-static CPAccessResult access_tvm_trvm(CPUARMState *env, const ARMCPRegInfo *ri,
37
switch (reg - nregs) {
37
- bool isread)
38
- case 0: env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); return 4;
38
+CPAccessResult access_tvm_trvm(CPUARMState *env, const ARMCPRegInfo *ri,
39
- case 1: vfp_set_fpscr(env, ldl_p(buf)); return 4;
39
+ bool isread)
40
- case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30); return 4;
40
{
41
+ case 0:
41
if (arm_current_el(env) == 1) {
42
+ env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf);
42
uint64_t trap = isread ? HCR_TRVM : HCR_TVM;
43
+ return 4;
43
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
44
+ case 1:
44
index XXXXXXX..XXXXXXX 100644
45
+ vfp_set_fpscr(env, ldl_p(buf));
45
--- a/target/arm/tcg/cpu64.c
46
+ return 4;
46
+++ b/target/arm/tcg/cpu64.c
47
+ case 2:
47
@@ -XXX,XX +XXX,XX @@ static void aarch64_a64fx_initfn(Object *obj)
48
+ env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30);
48
/* TODO: Add A64FX specific HPC extension registers */
49
+ return 4;
50
}
51
return 0;
52
}
49
}
53
@@ -XXX,XX +XXX,XX @@ static int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
50
54
return gdb_get_reg32(buf, vfp_get_fpsr(env));
51
+static CPAccessResult access_actlr_w(CPUARMState *env, const ARMCPRegInfo *r,
55
case 33:
52
+ bool read)
56
/* FPCR */
53
+{
57
- return gdb_get_reg32(buf,vfp_get_fpcr(env));
54
+ if (!read) {
58
+ return gdb_get_reg32(buf, vfp_get_fpcr(env));
55
+ int el = arm_current_el(env);
59
default:
56
+
60
return 0;
57
+ /* Because ACTLR_EL2 is constant 0, writes below EL2 trap to EL2. */
61
}
58
+ if (el < 2 && arm_is_el2_enabled(env)) {
59
+ return CP_ACCESS_TRAP_EL2;
60
+ }
61
+ /* Because ACTLR_EL3 is constant 0, writes below EL3 trap to EL3. */
62
+ if (el < 3 && arm_feature(env, ARM_FEATURE_EL3)) {
63
+ return CP_ACCESS_TRAP_EL3;
64
+ }
65
+ }
66
+ return CP_ACCESS_OK;
67
+}
68
+
69
static const ARMCPRegInfo neoverse_n1_cp_reginfo[] = {
70
{ .name = "ATCR_EL1", .state = ARM_CP_STATE_AA64,
71
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 7, .opc2 = 0,
72
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
73
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
74
+ /* Traps and enables are the same as for TCR_EL1. */
75
+ .accessfn = access_tvm_trvm, .fgt = FGT_TCR_EL1, },
76
{ .name = "ATCR_EL2", .state = ARM_CP_STATE_AA64,
77
.opc0 = 3, .opc1 = 4, .crn = 15, .crm = 7, .opc2 = 0,
78
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
79
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo neoverse_n1_cp_reginfo[] = {
80
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
81
{ .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64,
82
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 0,
83
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
84
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
85
+ .accessfn = access_actlr_w },
86
{ .name = "CPUACTLR2_EL1", .state = ARM_CP_STATE_AA64,
87
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 1,
88
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
89
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
90
+ .accessfn = access_actlr_w },
91
{ .name = "CPUACTLR3_EL1", .state = ARM_CP_STATE_AA64,
92
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 2,
93
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
94
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
95
+ .accessfn = access_actlr_w },
96
/*
97
* Report CPUCFR_EL1.SCU as 1, as we do not implement the DSU
98
* (and in particular its system registers).
99
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo neoverse_n1_cp_reginfo[] = {
100
.access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 4 },
101
{ .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64,
102
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 4,
103
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0x961563010 },
104
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0x961563010,
105
+ .accessfn = access_actlr_w },
106
{ .name = "CPUPCR_EL3", .state = ARM_CP_STATE_AA64,
107
.opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 1,
108
.access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
109
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo neoverse_n1_cp_reginfo[] = {
110
.access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
111
{ .name = "CPUPWRCTLR_EL1", .state = ARM_CP_STATE_AA64,
112
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 7,
113
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
114
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
115
+ .accessfn = access_actlr_w },
116
{ .name = "ERXPFGCDN_EL1", .state = ARM_CP_STATE_AA64,
117
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 2,
118
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
119
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
120
+ .accessfn = access_actlr_w },
121
{ .name = "ERXPFGCTL_EL1", .state = ARM_CP_STATE_AA64,
122
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 1,
123
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
124
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
125
+ .accessfn = access_actlr_w },
126
{ .name = "ERXPFGF_EL1", .state = ARM_CP_STATE_AA64,
127
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 0,
128
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
129
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
130
+ .accessfn = access_actlr_w },
131
};
132
133
static void define_neoverse_n1_cp_reginfo(ARMCPU *cpu)
62
--
134
--
63
2.20.1
135
2.34.1
64
65
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
There is only one additional EL1 register modeled, which
4
also needs to use access_actlr_w.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230811214031.171020-8-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/tcg/cpu64.c | 3 ++-
12
1 file changed, 2 insertions(+), 1 deletion(-)
13
14
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/tcg/cpu64.c
17
+++ b/target/arm/tcg/cpu64.c
18
@@ -XXX,XX +XXX,XX @@ static void define_neoverse_n1_cp_reginfo(ARMCPU *cpu)
19
static const ARMCPRegInfo neoverse_v1_cp_reginfo[] = {
20
{ .name = "CPUECTLR2_EL1", .state = ARM_CP_STATE_AA64,
21
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 5,
22
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
23
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
24
+ .accessfn = access_actlr_w },
25
{ .name = "CPUPPMCR_EL3", .state = ARM_CP_STATE_AA64,
26
.opc0 = 3, .opc1 = 6, .crn = 15, .crm = 2, .opc2 = 0,
27
.access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
28
--
29
2.34.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Like FEAT_TRF (Self-hosted Trace Extension), suppress tracing
4
external to the cpu, which is out of scope for QEMU.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230811214031.171020-10-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/cpu.c | 3 +++
12
1 file changed, 3 insertions(+)
13
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
19
/* FEAT_SPE (Statistical Profiling Extension) */
20
cpu->isar.id_aa64dfr0 =
21
FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMSVER, 0);
22
+ /* FEAT_TRBE (Trace Buffer Extension) */
23
+ cpu->isar.id_aa64dfr0 =
24
+ FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEBUFFER, 0);
25
/* FEAT_TRF (Self-hosted Trace Extension) */
26
cpu->isar.id_aa64dfr0 =
27
FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEFILT, 0);
28
--
29
2.34.1
diff view generated by jsdifflib
1
From: Tong Ho <tong.ho@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add BBRAM and eFUSE usage to the Xilinx Versal Virt board
3
This feature allows the operating system to set TCR_ELx.HWU*
4
document.
4
to allow the implementation to use the PBHA bits from the
5
block and page descriptors for for IMPLEMENTATION DEFINED
6
purposes. Since QEMU has no need to use these bits, we may
7
simply ignore them.
5
8
6
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210917052400.1249094-10-tong.ho@xilinx.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20230811214031.171020-11-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
docs/system/arm/xlnx-versal-virt.rst | 49 ++++++++++++++++++++++++++++
14
docs/system/arm/emulation.rst | 1 +
12
1 file changed, 49 insertions(+)
15
target/arm/tcg/cpu32.c | 2 +-
16
target/arm/tcg/cpu64.c | 2 +-
17
3 files changed, 3 insertions(+), 2 deletions(-)
13
18
14
diff --git a/docs/system/arm/xlnx-versal-virt.rst b/docs/system/arm/xlnx-versal-virt.rst
19
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/xlnx-versal-virt.rst
21
--- a/docs/system/arm/emulation.rst
17
+++ b/docs/system/arm/xlnx-versal-virt.rst
22
+++ b/docs/system/arm/emulation.rst
18
@@ -XXX,XX +XXX,XX @@ Implemented devices:
23
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
19
- OCM (256KB of On Chip Memory)
24
- FEAT_HAFDBS (Hardware management of the access flag and dirty bit state)
20
- XRAM (4MB of on chip Accelerator RAM)
25
- FEAT_HCX (Support for the HCRX_EL2 register)
21
- DDR memory
26
- FEAT_HPDS (Hierarchical permission disables)
22
+- BBRAM (36 bytes of Battery-backed RAM)
27
+- FEAT_HPDS2 (Translation table page-based hardware attributes)
23
+- eFUSE (3072 bytes of one-time field-programmable bit array)
28
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
24
29
- FEAT_IDST (ID space trap handling)
25
QEMU does not yet model any other devices, including the PL and the AI Engine.
30
- FEAT_IESB (Implicit error synchronization event)
26
31
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
27
@@ -XXX,XX +XXX,XX @@ Run the following at the U-Boot prompt:
32
index XXXXXXX..XXXXXXX 100644
28
fdt set /chosen/dom0 reg <0x00000000 0x40000000 0x0 0x03100000>
33
--- a/target/arm/tcg/cpu32.c
29
booti 30000000 - 20000000
34
+++ b/target/arm/tcg/cpu32.c
30
35
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
31
+BBRAM File Backend
36
cpu->isar.id_mmfr3 = t;
32
+""""""""""""""""""
37
33
+BBRAM can have an optional file backend, which must be a seekable
38
t = cpu->isar.id_mmfr4;
34
+binary file with a size of 36 bytes or larger. A file with all
39
- t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* FEAT_AA32HPD */
35
+binary 0s is a 'blank'.
40
+ t = FIELD_DP32(t, ID_MMFR4, HPDS, 2); /* FEAT_HPDS2 */
36
+
41
t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
37
+To add a file-backend for the BBRAM:
42
t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* FEAT_TTCNP */
38
+
43
t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* FEAT_XNX */
39
+.. code-block:: bash
44
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
40
+
45
index XXXXXXX..XXXXXXX 100644
41
+ -drive if=pflash,index=0,file=versal-bbram.bin,format=raw
46
--- a/target/arm/tcg/cpu64.c
42
+
47
+++ b/target/arm/tcg/cpu64.c
43
+To use a different index value, N, from default of 0, add:
48
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
44
+
49
t = FIELD_DP64(t, ID_AA64MMFR1, HAFDBS, 2); /* FEAT_HAFDBS */
45
+.. code-block:: bash
50
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* FEAT_VMID16 */
46
+
51
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */
47
+ -global xlnx,bbram-ctrl.drive-index=N
52
- t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* FEAT_HPDS */
48
+
53
+ t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 2); /* FEAT_HPDS2 */
49
+eFUSE File Backend
54
t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); /* FEAT_LOR */
50
+""""""""""""""""""
55
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 3); /* FEAT_PAN3 */
51
+eFUSE can have an optional file backend, which must be a seekable
56
t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* FEAT_XNX */
52
+binary file with a size of 3072 bytes or larger. A file with all
53
+binary 0s is a 'blank'.
54
+
55
+To add a file-backend for the eFUSE:
56
+
57
+.. code-block:: bash
58
+
59
+ -drive if=pflash,index=1,file=versal-efuse.bin,format=raw
60
+
61
+To use a different index value, N, from default of 1, add:
62
+
63
+.. code-block:: bash
64
+
65
+ -global xlnx,efuse.drive-index=N
66
+
67
+.. warning::
68
+ In actual physical Versal, BBRAM and eFUSE contain sensitive data.
69
+ The QEMU device models do **not** encrypt nor obfuscate any data
70
+ when holding them in models' memory or when writing them to their
71
+ file backends.
72
+
73
+ Thus, a file backend should be used with caution, and 'format=luks'
74
+ is highly recommended (albeit with usage complexity).
75
+
76
+ Better yet, do not use actual product data when running guest image
77
+ on this Xilinx Versal Virt board.
78
--
57
--
79
2.20.1
58
2.34.1
80
81
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
The Allwinner H3 SoC uses Cortex-A7 cores which support virtualization.
3
This is a mandatory feature for Armv8.1 architectures but we don't
4
However, today we are configuring QEMU to use HVC as PSCI conduit.
4
state the feature clearly in our emulation list. Also include
5
FEAT_CRC32 comment in aarch64_max_tcg_initfn for ease of grepping.
5
6
6
That means HVC calls get trapped into QEMU instead of the guest's own
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
emulated CPU and thus break the guest's ability to execute virtualization.
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
9
Message-id: 20230824075406.1515566-1-alex.bennee@linaro.org
9
Fix this by moving to SMC as conduit, freeing up HYP completely to the VM.
10
Cc: qemu-stable@nongnu.org
10
11
Message-Id: <20230222110104.3996971-1-alex.bennee@linaro.org>
11
Signed-off-by: Alexander Graf <agraf@csgraf.de>
12
[PMM: pluralize 'instructions' in docs]
12
Message-id: 20210920203931.66527-1-agraf@csgraf.de
13
Fixes: 740dafc0ba0 ("hw/arm: add Allwinner H3 System-on-Chip")
14
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
15
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
14
---
20
hw/arm/allwinner-h3.c | 2 +-
15
docs/system/arm/emulation.rst | 1 +
21
1 file changed, 1 insertion(+), 1 deletion(-)
16
target/arm/tcg/cpu64.c | 2 +-
17
2 files changed, 2 insertions(+), 1 deletion(-)
22
18
23
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
19
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
24
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/allwinner-h3.c
21
--- a/docs/system/arm/emulation.rst
26
+++ b/hw/arm/allwinner-h3.c
22
+++ b/docs/system/arm/emulation.rst
27
@@ -XXX,XX +XXX,XX @@ static void allwinner_h3_realize(DeviceState *dev, Error **errp)
23
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
28
24
- FEAT_BBM at level 2 (Translation table break-before-make levels)
29
/* Provide Power State Coordination Interface */
25
- FEAT_BF16 (AArch64 BFloat16 instructions)
30
qdev_prop_set_int32(DEVICE(&s->cpus[i]), "psci-conduit",
26
- FEAT_BTI (Branch Target Identification)
31
- QEMU_PSCI_CONDUIT_HVC);
27
+- FEAT_CRC32 (CRC32 instructions)
32
+ QEMU_PSCI_CONDUIT_SMC);
28
- FEAT_CSV2 (Cache speculation variant 2)
33
29
- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
34
/* Disable secondary CPUs */
30
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
35
qdev_prop_set_bit(DEVICE(&s->cpus[i]), "start-powered-off",
31
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/tcg/cpu64.c
34
+++ b/target/arm/tcg/cpu64.c
35
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
36
t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* FEAT_PMULL */
37
t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); /* FEAT_SHA1 */
38
t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* FEAT_SHA512 */
39
- t = FIELD_DP64(t, ID_AA64ISAR0, CRC32, 1);
40
+ t = FIELD_DP64(t, ID_AA64ISAR0, CRC32, 1); /* FEAT_CRC32 */
41
t = FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2); /* FEAT_LSE */
42
t = FIELD_DP64(t, ID_AA64ISAR0, RDM, 1); /* FEAT_RDM */
43
t = FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1); /* FEAT_SHA3 */
36
--
44
--
37
2.20.1
45
2.34.1
38
46
39
47
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
The SMCCC 1.3 spec section 5.2 says
3
i.MX7 IOMUX GPR device is not equivalent to i.MX6UL IOMUXC GPR device.
4
In particular, register 22 is not present on i.MX6UL and this is actualy
5
The only register that is really emulated in the i.MX7 IOMUX GPR device.
4
6
5
The Unknown SMC Function Identifier is a sign-extended value of (-1)
7
Note: The i.MX6UL code is actually also implementing the IOMUX GPR device
6
that is returned in the R0, W0 or X0 registers. An implementation must
8
as an unimplemented device at the same bus adress and the 2 instantiations
7
return this error code when it receives:
9
were actualy colliding. So we go back to the unimplemented device for now.
8
10
9
* An SMC or HVC call with an unknown Function Identifier
11
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
10
* An SMC or HVC call for a removed Function Identifier
12
Message-id: 48681bf51ee97646479bb261bee19abebbc8074e.1692964892.git.jcd@tribudubois.net
11
* An SMC64/HVC64 call from AArch32 state
12
13
To comply with these statements, let's always return -1 when we encounter
14
an unknown HVC or SMC call.
15
16
Signed-off-by: Alexander Graf <agraf@csgraf.de>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
15
---
20
target/arm/psci.c | 35 ++++++-----------------------------
16
include/hw/arm/fsl-imx6ul.h | 2 --
21
1 file changed, 6 insertions(+), 29 deletions(-)
17
hw/arm/fsl-imx6ul.c | 11 -----------
18
2 files changed, 13 deletions(-)
22
19
23
diff --git a/target/arm/psci.c b/target/arm/psci.c
20
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
24
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/psci.c
22
--- a/include/hw/arm/fsl-imx6ul.h
26
+++ b/target/arm/psci.c
23
+++ b/include/hw/arm/fsl-imx6ul.h
27
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
28
25
#include "hw/misc/imx6ul_ccm.h"
29
bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
26
#include "hw/misc/imx6_src.h"
30
{
27
#include "hw/misc/imx7_snvs.h"
31
- /* Return true if the r0/x0 value indicates a PSCI call and
28
-#include "hw/misc/imx7_gpr.h"
32
- * the exception type matches the configured PSCI conduit. This is
29
#include "hw/intc/imx_gpcv2.h"
33
- * called before the SMC/HVC instruction is executed, to decide whether
30
#include "hw/watchdog/wdt_imx2.h"
34
- * we should treat it as a PSCI call or with the architecturally
31
#include "hw/gpio/imx_gpio.h"
35
+ /*
32
@@ -XXX,XX +XXX,XX @@ struct FslIMX6ULState {
36
+ * Return true if the exception type matches the configured PSCI conduit.
33
IMX6SRCState src;
37
+ * This is called before the SMC/HVC instruction is executed, to decide
34
IMX7SNVSState snvs;
38
+ * whether we should treat it as a PSCI call or with the architecturally
35
IMXGPCv2State gpcv2;
39
* defined behaviour for an SMC or HVC (which might be UNDEF or trap
36
- IMX7GPRState gpr;
40
* to EL2 or to EL3).
37
IMXSPIState spi[FSL_IMX6UL_NUM_ECSPIS];
38
IMXI2CState i2c[FSL_IMX6UL_NUM_I2CS];
39
IMXSerialState uart[FSL_IMX6UL_NUM_UARTS];
40
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/arm/fsl-imx6ul.c
43
+++ b/hw/arm/fsl-imx6ul.c
44
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
41
*/
45
*/
42
- CPUARMState *env = &cpu->env;
46
object_initialize_child(obj, "snvs", &s->snvs, TYPE_IMX7_SNVS);
43
- uint64_t param = is_a64(env) ? env->xregs[0] : env->regs[0];
47
44
48
- /*
45
switch (excp_type) {
49
- * GPR
46
case EXCP_HVC:
50
- */
47
@@ -XXX,XX +XXX,XX @@ bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
51
- object_initialize_child(obj, "gpr", &s->gpr, TYPE_IMX7_GPR);
48
return false;
52
-
53
/*
54
* GPIOs 1 to 5
55
*/
56
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
57
FSL_IMX6UL_WDOGn_IRQ[i]));
49
}
58
}
50
59
51
- switch (param) {
60
- /*
52
- case QEMU_PSCI_0_2_FN_PSCI_VERSION:
61
- * GPR
53
- case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
62
- */
54
- case QEMU_PSCI_0_2_FN_AFFINITY_INFO:
63
- sysbus_realize(SYS_BUS_DEVICE(&s->gpr), &error_abort);
55
- case QEMU_PSCI_0_2_FN64_AFFINITY_INFO:
64
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX6UL_IOMUXC_GPR_ADDR);
56
- case QEMU_PSCI_0_2_FN_SYSTEM_RESET:
65
-
57
- case QEMU_PSCI_0_2_FN_SYSTEM_OFF:
66
/*
58
- case QEMU_PSCI_0_1_FN_CPU_ON:
67
* SDMA
59
- case QEMU_PSCI_0_2_FN_CPU_ON:
68
*/
60
- case QEMU_PSCI_0_2_FN64_CPU_ON:
61
- case QEMU_PSCI_0_1_FN_CPU_OFF:
62
- case QEMU_PSCI_0_2_FN_CPU_OFF:
63
- case QEMU_PSCI_0_1_FN_CPU_SUSPEND:
64
- case QEMU_PSCI_0_2_FN_CPU_SUSPEND:
65
- case QEMU_PSCI_0_2_FN64_CPU_SUSPEND:
66
- case QEMU_PSCI_0_1_FN_MIGRATE:
67
- case QEMU_PSCI_0_2_FN_MIGRATE:
68
- return true;
69
- default:
70
- return false;
71
- }
72
+ return true;
73
}
74
75
void arm_handle_psci_call(ARMCPU *cpu)
76
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
77
break;
78
case QEMU_PSCI_0_1_FN_MIGRATE:
79
case QEMU_PSCI_0_2_FN_MIGRATE:
80
+ default:
81
ret = QEMU_PSCI_RET_NOT_SUPPORTED;
82
break;
83
- default:
84
- g_assert_not_reached();
85
}
86
87
err:
88
--
69
--
89
2.20.1
70
2.34.1
90
91
diff view generated by jsdifflib
1
From: Tong Ho <tong.ho@xilinx.com>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
Connect the support for Versal eFUSE one-time field-programmable
3
* Add Addr and size definition for most i.MX6UL devices in i.MX6UL header file.
4
bit array.
4
* Use those newly defined named constants whenever possible.
5
* Standardize the way we init a familly of unimplemented devices
6
- SAI
7
- PWM
8
- CAN
9
* Add/rework few comments
5
10
6
The command argument:
11
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
7
-drive if=pflash,index=1,...
12
Message-id: d579043fbd4e4b490370783fda43fc02c8e9be75.1692964892.git.jcd@tribudubois.net
8
Can be used to optionally connect the bit array to a
9
backend storage, such that field-programmed values
10
in one invocation can be made available to next
11
invocation.
12
13
The backend storage must be a seekable binary file, and
14
its size must be 3072 bytes or larger. A file with all
15
binary 0's is a 'blank'.
16
17
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
18
Message-id: 20210917052400.1249094-7-tong.ho@xilinx.com
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
15
---
22
include/hw/arm/xlnx-versal.h | 10 +++++++
16
include/hw/arm/fsl-imx6ul.h | 156 +++++++++++++++++++++++++++++++-----
23
hw/arm/xlnx-versal-virt.c | 52 ++++++++++++++++++++++++++++++++++++
17
hw/arm/fsl-imx6ul.c | 147 ++++++++++++++++++++++-----------
24
hw/arm/xlnx-versal.c | 39 +++++++++++++++++++++++++++
18
2 files changed, 232 insertions(+), 71 deletions(-)
25
hw/arm/Kconfig | 1 +
26
4 files changed, 102 insertions(+)
27
19
28
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
20
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
29
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/arm/xlnx-versal.h
22
--- a/include/hw/arm/fsl-imx6ul.h
31
+++ b/include/hw/arm/xlnx-versal.h
23
+++ b/include/hw/arm/fsl-imx6ul.h
32
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
33
#include "hw/usb/xlnx-usb-subsystem.h"
25
#include "exec/memory.h"
34
#include "hw/misc/xlnx-versal-xramc.h"
26
#include "cpu.h"
35
#include "hw/nvram/xlnx-bbram.h"
27
#include "qom/object.h"
36
+#include "hw/nvram/xlnx-versal-efuse.h"
28
+#include "qemu/units.h"
37
29
38
#define TYPE_XLNX_VERSAL "xlnx-versal"
30
#define TYPE_FSL_IMX6UL "fsl-imx6ul"
39
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
31
OBJECT_DECLARE_SIMPLE_TYPE(FslIMX6ULState, FSL_IMX6UL)
40
@@ -XXX,XX +XXX,XX @@ struct Versal {
32
@@ -XXX,XX +XXX,XX @@ enum FslIMX6ULConfiguration {
41
33
FSL_IMX6UL_NUM_ADCS = 2,
42
XlnxZynqMPRTC rtc;
34
FSL_IMX6UL_NUM_USB_PHYS = 2,
43
XlnxBBRam bbram;
35
FSL_IMX6UL_NUM_USBS = 2,
44
+ XlnxEFuse efuse;
36
+ FSL_IMX6UL_NUM_SAIS = 3,
45
+ XlnxVersalEFuseCtrl efuse_ctrl;
37
+ FSL_IMX6UL_NUM_CANS = 2,
46
+ XlnxVersalEFuseCache efuse_cache;
38
+ FSL_IMX6UL_NUM_PWMS = 4,
47
} pmc;
39
};
48
40
49
struct {
41
struct FslIMX6ULState {
50
@@ -XXX,XX +XXX,XX @@ struct Versal {
42
@@ -XXX,XX +XXX,XX @@ struct FslIMX6ULState {
51
#define VERSAL_BBRAM_APB_IRQ_0 121
43
52
#define VERSAL_RTC_APB_ERR_IRQ 121
44
enum FslIMX6ULMemoryMap {
53
#define VERSAL_SD0_IRQ_0 126
45
FSL_IMX6UL_MMDC_ADDR = 0x80000000,
54
+#define VERSAL_EFUSE_IRQ 139
46
- FSL_IMX6UL_MMDC_SIZE = 2 * 1024 * 1024 * 1024UL,
55
#define VERSAL_RTC_ALARM_IRQ 142
47
+ FSL_IMX6UL_MMDC_SIZE = (2 * GiB),
56
#define VERSAL_RTC_SECONDS_IRQ 143
48
57
49
FSL_IMX6UL_QSPI1_MEM_ADDR = 0x60000000,
58
@@ -XXX,XX +XXX,XX @@ struct Versal {
50
- FSL_IMX6UL_EIM_ALIAS_ADDR = 0x58000000,
59
#define MM_PMC_SD0_SIZE 0x10000
51
- FSL_IMX6UL_EIM_CS_ADDR = 0x50000000,
60
#define MM_PMC_BBRAM_CTRL 0xf11f0000
52
- FSL_IMX6UL_AES_ENCRYPT_ADDR = 0x10000000,
61
#define MM_PMC_BBRAM_CTRL_SIZE 0x00050
53
- FSL_IMX6UL_QSPI1_RX_ADDR = 0x0C000000,
62
+#define MM_PMC_EFUSE_CTRL 0xf1240000
54
+ FSL_IMX6UL_QSPI1_MEM_SIZE = (256 * MiB),
63
+#define MM_PMC_EFUSE_CTRL_SIZE 0x00104
55
64
+#define MM_PMC_EFUSE_CACHE 0xf1250000
56
- /* AIPS-2 */
65
+#define MM_PMC_EFUSE_CACHE_SIZE 0x00C00
57
+ FSL_IMX6UL_EIM_ALIAS_ADDR = 0x58000000,
66
+
58
+ FSL_IMX6UL_EIM_ALIAS_SIZE = (128 * MiB),
67
#define MM_PMC_CRP 0xf1260000U
59
+
68
#define MM_PMC_CRP_SIZE 0x10000
60
+ FSL_IMX6UL_EIM_CS_ADDR = 0x50000000,
69
#define MM_PMC_RTC 0xf12a0000
61
+ FSL_IMX6UL_EIM_CS_SIZE = (128 * MiB),
70
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
62
+
63
+ FSL_IMX6UL_AES_ENCRYPT_ADDR = 0x10000000,
64
+ FSL_IMX6UL_AES_ENCRYPT_SIZE = (1 * MiB),
65
+
66
+ FSL_IMX6UL_QSPI1_RX_ADDR = 0x0C000000,
67
+ FSL_IMX6UL_QSPI1_RX_SIZE = (32 * MiB),
68
+
69
+ /* AIPS-2 Begin */
70
FSL_IMX6UL_UART6_ADDR = 0x021FC000,
71
+
72
FSL_IMX6UL_I2C4_ADDR = 0x021F8000,
73
+
74
FSL_IMX6UL_UART5_ADDR = 0x021F4000,
75
FSL_IMX6UL_UART4_ADDR = 0x021F0000,
76
FSL_IMX6UL_UART3_ADDR = 0x021EC000,
77
FSL_IMX6UL_UART2_ADDR = 0x021E8000,
78
+
79
FSL_IMX6UL_WDOG3_ADDR = 0x021E4000,
80
+
81
FSL_IMX6UL_QSPI_ADDR = 0x021E0000,
82
+ FSL_IMX6UL_QSPI_SIZE = 0x500,
83
+
84
FSL_IMX6UL_SYS_CNT_CTRL_ADDR = 0x021DC000,
85
+ FSL_IMX6UL_SYS_CNT_CTRL_SIZE = (16 * KiB),
86
+
87
FSL_IMX6UL_SYS_CNT_CMP_ADDR = 0x021D8000,
88
+ FSL_IMX6UL_SYS_CNT_CMP_SIZE = (16 * KiB),
89
+
90
FSL_IMX6UL_SYS_CNT_RD_ADDR = 0x021D4000,
91
+ FSL_IMX6UL_SYS_CNT_RD_SIZE = (16 * KiB),
92
+
93
FSL_IMX6UL_TZASC_ADDR = 0x021D0000,
94
+ FSL_IMX6UL_TZASC_SIZE = (16 * KiB),
95
+
96
FSL_IMX6UL_PXP_ADDR = 0x021CC000,
97
+ FSL_IMX6UL_PXP_SIZE = (16 * KiB),
98
+
99
FSL_IMX6UL_LCDIF_ADDR = 0x021C8000,
100
+ FSL_IMX6UL_LCDIF_SIZE = 0x100,
101
+
102
FSL_IMX6UL_CSI_ADDR = 0x021C4000,
103
+ FSL_IMX6UL_CSI_SIZE = 0x100,
104
+
105
FSL_IMX6UL_CSU_ADDR = 0x021C0000,
106
+ FSL_IMX6UL_CSU_SIZE = (16 * KiB),
107
+
108
FSL_IMX6UL_OCOTP_CTRL_ADDR = 0x021BC000,
109
+ FSL_IMX6UL_OCOTP_CTRL_SIZE = (4 * KiB),
110
+
111
FSL_IMX6UL_EIM_ADDR = 0x021B8000,
112
+ FSL_IMX6UL_EIM_SIZE = 0x100,
113
+
114
FSL_IMX6UL_SIM2_ADDR = 0x021B4000,
115
+
116
FSL_IMX6UL_MMDC_CFG_ADDR = 0x021B0000,
117
+ FSL_IMX6UL_MMDC_CFG_SIZE = (4 * KiB),
118
+
119
FSL_IMX6UL_ROMCP_ADDR = 0x021AC000,
120
+ FSL_IMX6UL_ROMCP_SIZE = 0x300,
121
+
122
FSL_IMX6UL_I2C3_ADDR = 0x021A8000,
123
FSL_IMX6UL_I2C2_ADDR = 0x021A4000,
124
FSL_IMX6UL_I2C1_ADDR = 0x021A0000,
125
+
126
FSL_IMX6UL_ADC2_ADDR = 0x0219C000,
127
FSL_IMX6UL_ADC1_ADDR = 0x02198000,
128
+ FSL_IMX6UL_ADCn_SIZE = 0x100,
129
+
130
FSL_IMX6UL_USDHC2_ADDR = 0x02194000,
131
FSL_IMX6UL_USDHC1_ADDR = 0x02190000,
132
- FSL_IMX6UL_SIM1_ADDR = 0x0218C000,
133
- FSL_IMX6UL_ENET1_ADDR = 0x02188000,
134
- FSL_IMX6UL_USBO2_USBMISC_ADDR = 0x02184800,
135
- FSL_IMX6UL_USBO2_USB_ADDR = 0x02184000,
136
- FSL_IMX6UL_USBO2_PL301_ADDR = 0x02180000,
137
- FSL_IMX6UL_AIPS2_CFG_ADDR = 0x0217C000,
138
- FSL_IMX6UL_CAAM_ADDR = 0x02140000,
139
- FSL_IMX6UL_A7MPCORE_DAP_ADDR = 0x02100000,
140
141
- /* AIPS-1 */
142
+ FSL_IMX6UL_SIM1_ADDR = 0x0218C000,
143
+ FSL_IMX6UL_SIMn_SIZE = (16 * KiB),
144
+
145
+ FSL_IMX6UL_ENET1_ADDR = 0x02188000,
146
+
147
+ FSL_IMX6UL_USBO2_USBMISC_ADDR = 0x02184800,
148
+ FSL_IMX6UL_USBO2_USB1_ADDR = 0x02184000,
149
+ FSL_IMX6UL_USBO2_USB2_ADDR = 0x02184200,
150
+
151
+ FSL_IMX6UL_USBO2_PL301_ADDR = 0x02180000,
152
+ FSL_IMX6UL_USBO2_PL301_SIZE = (16 * KiB),
153
+
154
+ FSL_IMX6UL_AIPS2_CFG_ADDR = 0x0217C000,
155
+ FSL_IMX6UL_AIPS2_CFG_SIZE = 0x100,
156
+
157
+ FSL_IMX6UL_CAAM_ADDR = 0x02140000,
158
+ FSL_IMX6UL_CAAM_SIZE = (16 * KiB),
159
+
160
+ FSL_IMX6UL_A7MPCORE_DAP_ADDR = 0x02100000,
161
+ FSL_IMX6UL_A7MPCORE_DAP_SIZE = (4 * KiB),
162
+ /* AIPS-2 End */
163
+
164
+ /* AIPS-1 Begin */
165
FSL_IMX6UL_PWM8_ADDR = 0x020FC000,
166
FSL_IMX6UL_PWM7_ADDR = 0x020F8000,
167
FSL_IMX6UL_PWM6_ADDR = 0x020F4000,
168
FSL_IMX6UL_PWM5_ADDR = 0x020F0000,
169
+
170
FSL_IMX6UL_SDMA_ADDR = 0x020EC000,
171
+ FSL_IMX6UL_SDMA_SIZE = 0x300,
172
+
173
FSL_IMX6UL_GPT2_ADDR = 0x020E8000,
174
+
175
FSL_IMX6UL_IOMUXC_GPR_ADDR = 0x020E4000,
176
+ FSL_IMX6UL_IOMUXC_GPR_SIZE = 0x40,
177
+
178
FSL_IMX6UL_IOMUXC_ADDR = 0x020E0000,
179
+ FSL_IMX6UL_IOMUXC_SIZE = 0x700,
180
+
181
FSL_IMX6UL_GPC_ADDR = 0x020DC000,
182
+
183
FSL_IMX6UL_SRC_ADDR = 0x020D8000,
184
+
185
FSL_IMX6UL_EPIT2_ADDR = 0x020D4000,
186
FSL_IMX6UL_EPIT1_ADDR = 0x020D0000,
187
+
188
FSL_IMX6UL_SNVS_HP_ADDR = 0x020CC000,
189
+
190
FSL_IMX6UL_USBPHY2_ADDR = 0x020CA000,
191
- FSL_IMX6UL_USBPHY2_SIZE = (4 * 1024),
192
FSL_IMX6UL_USBPHY1_ADDR = 0x020C9000,
193
- FSL_IMX6UL_USBPHY1_SIZE = (4 * 1024),
194
+
195
FSL_IMX6UL_ANALOG_ADDR = 0x020C8000,
196
+ FSL_IMX6UL_ANALOG_SIZE = 0x300,
197
+
198
FSL_IMX6UL_CCM_ADDR = 0x020C4000,
199
+
200
FSL_IMX6UL_WDOG2_ADDR = 0x020C0000,
201
FSL_IMX6UL_WDOG1_ADDR = 0x020BC000,
202
+
203
FSL_IMX6UL_KPP_ADDR = 0x020B8000,
204
+ FSL_IMX6UL_KPP_SIZE = 0x10,
205
+
206
FSL_IMX6UL_ENET2_ADDR = 0x020B4000,
207
+
208
FSL_IMX6UL_SNVS_LP_ADDR = 0x020B0000,
209
+ FSL_IMX6UL_SNVS_LP_SIZE = (16 * KiB),
210
+
211
FSL_IMX6UL_GPIO5_ADDR = 0x020AC000,
212
FSL_IMX6UL_GPIO4_ADDR = 0x020A8000,
213
FSL_IMX6UL_GPIO3_ADDR = 0x020A4000,
214
FSL_IMX6UL_GPIO2_ADDR = 0x020A0000,
215
FSL_IMX6UL_GPIO1_ADDR = 0x0209C000,
216
+
217
FSL_IMX6UL_GPT1_ADDR = 0x02098000,
218
+
219
FSL_IMX6UL_CAN2_ADDR = 0x02094000,
220
FSL_IMX6UL_CAN1_ADDR = 0x02090000,
221
+ FSL_IMX6UL_CANn_SIZE = (4 * KiB),
222
+
223
FSL_IMX6UL_PWM4_ADDR = 0x0208C000,
224
FSL_IMX6UL_PWM3_ADDR = 0x02088000,
225
FSL_IMX6UL_PWM2_ADDR = 0x02084000,
226
FSL_IMX6UL_PWM1_ADDR = 0x02080000,
227
+ FSL_IMX6UL_PWMn_SIZE = 0x20,
228
+
229
FSL_IMX6UL_AIPS1_CFG_ADDR = 0x0207C000,
230
+ FSL_IMX6UL_AIPS1_CFG_SIZE = (16 * KiB),
231
+
232
FSL_IMX6UL_BEE_ADDR = 0x02044000,
233
+ FSL_IMX6UL_BEE_SIZE = (16 * KiB),
234
+
235
FSL_IMX6UL_TOUCH_CTRL_ADDR = 0x02040000,
236
+ FSL_IMX6UL_TOUCH_CTRL_SIZE = 0x100,
237
+
238
FSL_IMX6UL_SPBA_ADDR = 0x0203C000,
239
+ FSL_IMX6UL_SPBA_SIZE = 0x100,
240
+
241
FSL_IMX6UL_ASRC_ADDR = 0x02034000,
242
+ FSL_IMX6UL_ASRC_SIZE = 0x100,
243
+
244
FSL_IMX6UL_SAI3_ADDR = 0x02030000,
245
FSL_IMX6UL_SAI2_ADDR = 0x0202C000,
246
FSL_IMX6UL_SAI1_ADDR = 0x02028000,
247
+ FSL_IMX6UL_SAIn_SIZE = 0x200,
248
+
249
FSL_IMX6UL_UART8_ADDR = 0x02024000,
250
FSL_IMX6UL_UART1_ADDR = 0x02020000,
251
FSL_IMX6UL_UART7_ADDR = 0x02018000,
252
+
253
FSL_IMX6UL_ECSPI4_ADDR = 0x02014000,
254
FSL_IMX6UL_ECSPI3_ADDR = 0x02010000,
255
FSL_IMX6UL_ECSPI2_ADDR = 0x0200C000,
256
FSL_IMX6UL_ECSPI1_ADDR = 0x02008000,
257
+
258
FSL_IMX6UL_SPDIF_ADDR = 0x02004000,
259
+ FSL_IMX6UL_SPDIF_SIZE = 0x100,
260
+ /* AIPS-1 End */
261
+
262
+ FSL_IMX6UL_BCH_ADDR = 0x01808000,
263
+ FSL_IMX6UL_BCH_SIZE = 0x200,
264
+
265
+ FSL_IMX6UL_GPMI_ADDR = 0x01806000,
266
+ FSL_IMX6UL_GPMI_SIZE = 0x200,
267
268
FSL_IMX6UL_APBH_DMA_ADDR = 0x01804000,
269
- FSL_IMX6UL_APBH_DMA_SIZE = (32 * 1024),
270
+ FSL_IMX6UL_APBH_DMA_SIZE = (4 * KiB),
271
272
FSL_IMX6UL_A7MPCORE_ADDR = 0x00A00000,
273
274
FSL_IMX6UL_OCRAM_ALIAS_ADDR = 0x00920000,
275
- FSL_IMX6UL_OCRAM_ALIAS_SIZE = 0x00060000,
276
+ FSL_IMX6UL_OCRAM_ALIAS_SIZE = (384 * KiB),
277
+
278
FSL_IMX6UL_OCRAM_MEM_ADDR = 0x00900000,
279
- FSL_IMX6UL_OCRAM_MEM_SIZE = 0x00020000,
280
+ FSL_IMX6UL_OCRAM_MEM_SIZE = (128 * KiB),
281
+
282
FSL_IMX6UL_CAAM_MEM_ADDR = 0x00100000,
283
- FSL_IMX6UL_CAAM_MEM_SIZE = 0x00008000,
284
+ FSL_IMX6UL_CAAM_MEM_SIZE = (32 * KiB),
285
+
286
FSL_IMX6UL_ROM_ADDR = 0x00000000,
287
- FSL_IMX6UL_ROM_SIZE = 0x00018000,
288
+ FSL_IMX6UL_ROM_SIZE = (96 * KiB),
289
};
290
291
enum FslIMX6ULIRQs {
292
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
71
index XXXXXXX..XXXXXXX 100644
293
index XXXXXXX..XXXXXXX 100644
72
--- a/hw/arm/xlnx-versal-virt.c
294
--- a/hw/arm/fsl-imx6ul.c
73
+++ b/hw/arm/xlnx-versal-virt.c
295
+++ b/hw/arm/fsl-imx6ul.c
74
@@ -XXX,XX +XXX,XX @@ static void fdt_add_bbram_node(VersalVirt *s)
296
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
75
g_free(name);
297
object_initialize_child(obj, "snvs", &s->snvs, TYPE_IMX7_SNVS);
76
}
298
77
299
/*
78
+static void fdt_add_efuse_ctrl_node(VersalVirt *s)
300
- * GPIOs 1 to 5
79
+{
301
+ * GPIOs
80
+ const char compat[] = TYPE_XLNX_VERSAL_EFUSE_CTRL;
302
*/
81
+ const char interrupt_names[] = "pmc_efuse";
303
for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
82
+ char *name = g_strdup_printf("/pmc_efuse@%x", MM_PMC_EFUSE_CTRL);
304
snprintf(name, NAME_SIZE, "gpio%d", i);
83
+
305
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
84
+ qemu_fdt_add_subnode(s->fdt, name);
306
}
85
+
307
86
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
308
/*
87
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_EFUSE_IRQ,
309
- * GPT 1, 2
88
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
310
+ * GPTs
89
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
311
*/
90
+ interrupt_names, sizeof(interrupt_names));
312
for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
91
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
313
snprintf(name, NAME_SIZE, "gpt%d", i);
92
+ 2, MM_PMC_EFUSE_CTRL,
314
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
93
+ 2, MM_PMC_EFUSE_CTRL_SIZE);
315
}
94
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
316
95
+ g_free(name);
317
/*
96
+}
318
- * EPIT 1, 2
97
+
319
+ * EPITs
98
+static void fdt_add_efuse_cache_node(VersalVirt *s)
320
*/
99
+{
321
for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
100
+ const char compat[] = TYPE_XLNX_VERSAL_EFUSE_CACHE;
322
snprintf(name, NAME_SIZE, "epit%d", i + 1);
101
+ char *name = g_strdup_printf("/xlnx_pmc_efuse_cache@%x",
323
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
102
+ MM_PMC_EFUSE_CACHE);
324
}
103
+
325
104
+ qemu_fdt_add_subnode(s->fdt, name);
326
/*
105
+
327
- * eCSPI
106
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
328
+ * eCSPIs
107
+ 2, MM_PMC_EFUSE_CACHE,
329
*/
108
+ 2, MM_PMC_EFUSE_CACHE_SIZE);
330
for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
109
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
331
snprintf(name, NAME_SIZE, "spi%d", i + 1);
110
+ g_free(name);
332
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
111
+}
333
}
112
+
334
113
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
335
/*
114
{
336
- * I2C
115
Error *err = NULL;
337
+ * I2Cs
116
@@ -XXX,XX +XXX,XX @@ static void bbram_attach_drive(XlnxBBRam *dev)
338
*/
117
}
339
for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
118
}
340
snprintf(name, NAME_SIZE, "i2c%d", i + 1);
119
341
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
120
+static void efuse_attach_drive(XlnxEFuse *dev)
342
}
121
+{
343
122
+ DriveInfo *dinfo;
344
/*
123
+ BlockBackend *blk;
345
- * UART
124
+
346
+ * UARTs
125
+ dinfo = drive_get_by_index(IF_PFLASH, 1);
347
*/
126
+ blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
348
for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
127
+ if (blk) {
349
snprintf(name, NAME_SIZE, "uart%d", i);
128
+ qdev_prop_set_drive(DEVICE(dev), "drive", blk);
350
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
351
}
352
353
/*
354
- * Ethernet
355
+ * Ethernets
356
*/
357
for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
358
snprintf(name, NAME_SIZE, "eth%d", i);
359
object_initialize_child(obj, name, &s->eth[i], TYPE_IMX_ENET);
360
}
361
362
- /* USB */
363
+ /*
364
+ * USB PHYs
365
+ */
366
for (i = 0; i < FSL_IMX6UL_NUM_USB_PHYS; i++) {
367
snprintf(name, NAME_SIZE, "usbphy%d", i);
368
object_initialize_child(obj, name, &s->usbphy[i], TYPE_IMX_USBPHY);
369
}
370
+
371
+ /*
372
+ * USBs
373
+ */
374
for (i = 0; i < FSL_IMX6UL_NUM_USBS; i++) {
375
snprintf(name, NAME_SIZE, "usb%d", i);
376
object_initialize_child(obj, name, &s->usb[i], TYPE_CHIPIDEA);
377
}
378
379
/*
380
- * SDHCI
381
+ * SDHCIs
382
*/
383
for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
384
snprintf(name, NAME_SIZE, "usdhc%d", i);
385
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
386
}
387
388
/*
389
- * Watchdog
390
+ * Watchdogs
391
*/
392
for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
393
snprintf(name, NAME_SIZE, "wdt%d", i);
394
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
395
* A7MPCORE DAP
396
*/
397
create_unimplemented_device("a7mpcore-dap", FSL_IMX6UL_A7MPCORE_DAP_ADDR,
398
- 0x100000);
399
+ FSL_IMX6UL_A7MPCORE_DAP_SIZE);
400
401
/*
402
- * GPT 1, 2
403
+ * GPTs
404
*/
405
for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
406
static const hwaddr FSL_IMX6UL_GPTn_ADDR[FSL_IMX6UL_NUM_GPTS] = {
407
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
408
}
409
410
/*
411
- * EPIT 1, 2
412
+ * EPITs
413
*/
414
for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
415
static const hwaddr FSL_IMX6UL_EPITn_ADDR[FSL_IMX6UL_NUM_EPITS] = {
416
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
417
}
418
419
/*
420
- * GPIO
421
+ * GPIOs
422
*/
423
for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
424
static const hwaddr FSL_IMX6UL_GPIOn_ADDR[FSL_IMX6UL_NUM_GPIOS] = {
425
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
426
}
427
428
/*
429
- * IOMUXC and IOMUXC_GPR
430
+ * IOMUXC
431
*/
432
- for (i = 0; i < 1; i++) {
433
- static const hwaddr FSL_IMX6UL_IOMUXCn_ADDR[FSL_IMX6UL_NUM_IOMUXCS] = {
434
- FSL_IMX6UL_IOMUXC_ADDR,
435
- FSL_IMX6UL_IOMUXC_GPR_ADDR,
436
- };
437
-
438
- snprintf(name, NAME_SIZE, "iomuxc%d", i);
439
- create_unimplemented_device(name, FSL_IMX6UL_IOMUXCn_ADDR[i], 0x4000);
440
- }
441
+ create_unimplemented_device("iomuxc", FSL_IMX6UL_IOMUXC_ADDR,
442
+ FSL_IMX6UL_IOMUXC_SIZE);
443
+ create_unimplemented_device("iomuxc_gpr", FSL_IMX6UL_IOMUXC_GPR_ADDR,
444
+ FSL_IMX6UL_IOMUXC_GPR_SIZE);
445
446
/*
447
* CCM
448
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
449
sysbus_realize(SYS_BUS_DEVICE(&s->gpcv2), &error_abort);
450
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX6UL_GPC_ADDR);
451
452
- /* Initialize all ECSPI */
453
+ /*
454
+ * ECSPIs
455
+ */
456
for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
457
static const hwaddr FSL_IMX6UL_SPIn_ADDR[FSL_IMX6UL_NUM_ECSPIS] = {
458
FSL_IMX6UL_ECSPI1_ADDR,
459
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
460
}
461
462
/*
463
- * I2C
464
+ * I2Cs
465
*/
466
for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
467
static const hwaddr FSL_IMX6UL_I2Cn_ADDR[FSL_IMX6UL_NUM_I2CS] = {
468
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
469
}
470
471
/*
472
- * UART
473
+ * UARTs
474
*/
475
for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
476
static const hwaddr FSL_IMX6UL_UARTn_ADDR[FSL_IMX6UL_NUM_UARTS] = {
477
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
478
}
479
480
/*
481
- * Ethernet
482
+ * Ethernets
483
*
484
* We must use two loops since phy_connected affects the other interface
485
* and we have to set all properties before calling sysbus_realize().
486
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
487
FSL_IMX6UL_ENETn_TIMER_IRQ[i]));
488
}
489
490
- /* USB */
491
+ /*
492
+ * USB PHYs
493
+ */
494
for (i = 0; i < FSL_IMX6UL_NUM_USB_PHYS; i++) {
495
+ static const hwaddr
496
+ FSL_IMX6UL_USB_PHYn_ADDR[FSL_IMX6UL_NUM_USB_PHYS] = {
497
+ FSL_IMX6UL_USBPHY1_ADDR,
498
+ FSL_IMX6UL_USBPHY2_ADDR,
499
+ };
500
+
501
sysbus_realize(SYS_BUS_DEVICE(&s->usbphy[i]), &error_abort);
502
sysbus_mmio_map(SYS_BUS_DEVICE(&s->usbphy[i]), 0,
503
- FSL_IMX6UL_USBPHY1_ADDR + i * 0x1000);
504
+ FSL_IMX6UL_USB_PHYn_ADDR[i]);
505
}
506
507
+ /*
508
+ * USBs
509
+ */
510
for (i = 0; i < FSL_IMX6UL_NUM_USBS; i++) {
511
+ static const hwaddr FSL_IMX6UL_USB02_USBn_ADDR[FSL_IMX6UL_NUM_USBS] = {
512
+ FSL_IMX6UL_USBO2_USB1_ADDR,
513
+ FSL_IMX6UL_USBO2_USB2_ADDR,
514
+ };
515
+
516
static const int FSL_IMX6UL_USBn_IRQ[] = {
517
FSL_IMX6UL_USB1_IRQ,
518
FSL_IMX6UL_USB2_IRQ,
519
};
520
+
521
sysbus_realize(SYS_BUS_DEVICE(&s->usb[i]), &error_abort);
522
sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0,
523
- FSL_IMX6UL_USBO2_USB_ADDR + i * 0x200);
524
+ FSL_IMX6UL_USB02_USBn_ADDR[i]);
525
sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0,
526
qdev_get_gpio_in(DEVICE(&s->a7mpcore),
527
FSL_IMX6UL_USBn_IRQ[i]));
528
}
529
530
/*
531
- * USDHC
532
+ * USDHCs
533
*/
534
for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
535
static const hwaddr FSL_IMX6UL_USDHCn_ADDR[FSL_IMX6UL_NUM_USDHCS] = {
536
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
537
sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX6UL_SNVS_HP_ADDR);
538
539
/*
540
- * Watchdog
541
+ * Watchdogs
542
*/
543
for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
544
static const hwaddr FSL_IMX6UL_WDOGn_ADDR[FSL_IMX6UL_NUM_WDTS] = {
545
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
546
FSL_IMX6UL_WDOG2_ADDR,
547
FSL_IMX6UL_WDOG3_ADDR,
548
};
549
+
550
static const int FSL_IMX6UL_WDOGn_IRQ[FSL_IMX6UL_NUM_WDTS] = {
551
FSL_IMX6UL_WDOG1_IRQ,
552
FSL_IMX6UL_WDOG2_IRQ,
553
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
554
/*
555
* SDMA
556
*/
557
- create_unimplemented_device("sdma", FSL_IMX6UL_SDMA_ADDR, 0x4000);
558
+ create_unimplemented_device("sdma", FSL_IMX6UL_SDMA_ADDR,
559
+ FSL_IMX6UL_SDMA_SIZE);
560
561
/*
562
- * SAI (Audio SSI (Synchronous Serial Interface))
563
+ * SAIs (Audio SSI (Synchronous Serial Interface))
564
*/
565
- create_unimplemented_device("sai1", FSL_IMX6UL_SAI1_ADDR, 0x4000);
566
- create_unimplemented_device("sai2", FSL_IMX6UL_SAI2_ADDR, 0x4000);
567
- create_unimplemented_device("sai3", FSL_IMX6UL_SAI3_ADDR, 0x4000);
568
+ for (i = 0; i < FSL_IMX6UL_NUM_SAIS; i++) {
569
+ static const hwaddr FSL_IMX6UL_SAIn_ADDR[FSL_IMX6UL_NUM_SAIS] = {
570
+ FSL_IMX6UL_SAI1_ADDR,
571
+ FSL_IMX6UL_SAI2_ADDR,
572
+ FSL_IMX6UL_SAI3_ADDR,
573
+ };
574
+
575
+ snprintf(name, NAME_SIZE, "sai%d", i);
576
+ create_unimplemented_device(name, FSL_IMX6UL_SAIn_ADDR[i],
577
+ FSL_IMX6UL_SAIn_SIZE);
129
+ }
578
+ }
130
+}
579
131
+
580
/*
132
static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
581
- * PWM
133
{
582
+ * PWMs
134
BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
583
*/
135
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
584
- create_unimplemented_device("pwm1", FSL_IMX6UL_PWM1_ADDR, 0x4000);
136
fdt_add_sd_nodes(s);
585
- create_unimplemented_device("pwm2", FSL_IMX6UL_PWM2_ADDR, 0x4000);
137
fdt_add_rtc_node(s);
586
- create_unimplemented_device("pwm3", FSL_IMX6UL_PWM3_ADDR, 0x4000);
138
fdt_add_bbram_node(s);
587
- create_unimplemented_device("pwm4", FSL_IMX6UL_PWM4_ADDR, 0x4000);
139
+ fdt_add_efuse_ctrl_node(s);
588
+ for (i = 0; i < FSL_IMX6UL_NUM_PWMS; i++) {
140
+ fdt_add_efuse_cache_node(s);
589
+ static const hwaddr FSL_IMX6UL_PWMn_ADDR[FSL_IMX6UL_NUM_PWMS] = {
141
fdt_add_cpu_nodes(s, psci_conduit);
590
+ FSL_IMX6UL_PWM1_ADDR,
142
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
591
+ FSL_IMX6UL_PWM2_ADDR,
143
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
592
+ FSL_IMX6UL_PWM3_ADDR,
144
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
593
+ FSL_IMX6UL_PWM4_ADDR,
145
/* Attach bbram backend, if given */
594
+ };
146
bbram_attach_drive(&s->soc.pmc.bbram);
595
+
147
596
+ snprintf(name, NAME_SIZE, "pwm%d", i);
148
+ /* Attach efuse backend, if given */
597
+ create_unimplemented_device(name, FSL_IMX6UL_PWMn_ADDR[i],
149
+ efuse_attach_drive(&s->soc.pmc.efuse);
598
+ FSL_IMX6UL_PWMn_SIZE);
150
+
599
+ }
151
/* Plugin SD cards. */
600
152
for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
601
/*
153
sd_plugin_card(&s->soc.pmc.iou.sd[i], drive_get_next(IF_SD));
602
* Audio ASRC (asynchronous sample rate converter)
154
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
603
*/
155
index XXXXXXX..XXXXXXX 100644
604
- create_unimplemented_device("asrc", FSL_IMX6UL_ASRC_ADDR, 0x4000);
156
--- a/hw/arm/xlnx-versal.c
605
+ create_unimplemented_device("asrc", FSL_IMX6UL_ASRC_ADDR,
157
+++ b/hw/arm/xlnx-versal.c
606
+ FSL_IMX6UL_ASRC_SIZE);
158
@@ -XXX,XX +XXX,XX @@ static void versal_create_bbram(Versal *s, qemu_irq *pic)
607
159
sysbus_connect_irq(sbd, 0, pic[VERSAL_BBRAM_APB_IRQ_0]);
608
/*
160
}
609
- * CAN
161
610
+ * CANs
162
+static void versal_realize_efuse_part(Versal *s, Object *dev, hwaddr base)
611
*/
163
+{
612
- create_unimplemented_device("can1", FSL_IMX6UL_CAN1_ADDR, 0x4000);
164
+ SysBusDevice *part = SYS_BUS_DEVICE(dev);
613
- create_unimplemented_device("can2", FSL_IMX6UL_CAN2_ADDR, 0x4000);
165
+
614
+ for (i = 0; i < FSL_IMX6UL_NUM_CANS; i++) {
166
+ object_property_set_link(OBJECT(part), "efuse",
615
+ static const hwaddr FSL_IMX6UL_CANn_ADDR[FSL_IMX6UL_NUM_CANS] = {
167
+ OBJECT(&s->pmc.efuse), &error_abort);
616
+ FSL_IMX6UL_CAN1_ADDR,
168
+
617
+ FSL_IMX6UL_CAN2_ADDR,
169
+ sysbus_realize(part, &error_abort);
618
+ };
170
+ memory_region_add_subregion(&s->mr_ps, base,
619
+
171
+ sysbus_mmio_get_region(part, 0));
620
+ snprintf(name, NAME_SIZE, "can%d", i);
172
+}
621
+ create_unimplemented_device(name, FSL_IMX6UL_CANn_ADDR[i],
173
+
622
+ FSL_IMX6UL_CANn_SIZE);
174
+static void versal_create_efuse(Versal *s, qemu_irq *pic)
623
+ }
175
+{
624
176
+ Object *bits = OBJECT(&s->pmc.efuse);
625
/*
177
+ Object *ctrl = OBJECT(&s->pmc.efuse_ctrl);
626
* APHB_DMA
178
+ Object *cache = OBJECT(&s->pmc.efuse_cache);
627
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
179
+
628
};
180
+ object_initialize_child(OBJECT(s), "efuse-ctrl", &s->pmc.efuse_ctrl,
629
181
+ TYPE_XLNX_VERSAL_EFUSE_CTRL);
630
snprintf(name, NAME_SIZE, "adc%d", i);
182
+
631
- create_unimplemented_device(name, FSL_IMX6UL_ADCn_ADDR[i], 0x4000);
183
+ object_initialize_child(OBJECT(s), "efuse-cache", &s->pmc.efuse_cache,
632
+ create_unimplemented_device(name, FSL_IMX6UL_ADCn_ADDR[i],
184
+ TYPE_XLNX_VERSAL_EFUSE_CACHE);
633
+ FSL_IMX6UL_ADCn_SIZE);
185
+
634
}
186
+ object_initialize_child_with_props(ctrl, "xlnx-efuse@0", bits,
635
187
+ sizeof(s->pmc.efuse),
636
/*
188
+ TYPE_XLNX_EFUSE, &error_abort,
637
* LCD
189
+ "efuse-nr", "3",
638
*/
190
+ "efuse-size", "8192",
639
- create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR, 0x4000);
191
+ NULL);
640
+ create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR,
192
+
641
+ FSL_IMX6UL_LCDIF_SIZE);
193
+ qdev_realize(DEVICE(bits), NULL, &error_abort);
642
194
+ versal_realize_efuse_part(s, ctrl, MM_PMC_EFUSE_CTRL);
643
/*
195
+ versal_realize_efuse_part(s, cache, MM_PMC_EFUSE_CACHE);
644
* ROM memory
196
+
197
+ sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]);
198
+}
199
+
200
/* This takes the board allocated linear DDR memory and creates aliases
201
* for each split DDR range/aperture on the Versal address map.
202
*/
203
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
204
versal_create_rtc(s, pic);
205
versal_create_xrams(s, pic);
206
versal_create_bbram(s, pic);
207
+ versal_create_efuse(s, pic);
208
versal_map_ddr(s);
209
versal_unimp(s);
210
211
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
212
index XXXXXXX..XXXXXXX 100644
213
--- a/hw/arm/Kconfig
214
+++ b/hw/arm/Kconfig
215
@@ -XXX,XX +XXX,XX @@ config XLNX_VERSAL
216
select XLNX_ZYNQMP
217
select OR_IRQ
218
select XLNX_BBRAM
219
+ select XLNX_EFUSE_VERSAL
220
221
config NPCM7XX
222
bool
223
--
645
--
224
2.20.1
646
2.34.1
225
226
diff view generated by jsdifflib
1
From: Tong Ho <tong.ho@xilinx.com>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
This implements the Xilinx ZynqMP eFuse, an one-time
3
* Add TZASC as unimplemented device.
4
field-programmable non-volatile storage device. There is
4
- Allow bare metal application to access this (unimplemented) device
5
only one such device in the Xilinx ZynqMP product family.
5
* Add CSU as unimplemented device.
6
- Allow bare metal application to access this (unimplemented) device
7
* Add 4 missing PWM devices
6
8
7
Co-authored-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
8
Co-authored-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
11
Message-id: 59e4dc56e14eccfefd379275ec19048dff9c10b3.1692964892.git.jcd@tribudubois.net
10
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
12
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
13
Message-id: 20210917052400.1249094-4-tong.ho@xilinx.com
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
13
---
17
include/hw/nvram/xlnx-zynqmp-efuse.h | 44 ++
14
include/hw/arm/fsl-imx6ul.h | 2 +-
18
hw/nvram/xlnx-zynqmp-efuse.c | 855 +++++++++++++++++++++++++++
15
hw/arm/fsl-imx6ul.c | 16 ++++++++++++++++
19
hw/nvram/Kconfig | 4 +
16
2 files changed, 17 insertions(+), 1 deletion(-)
20
hw/nvram/meson.build | 2 +
21
4 files changed, 905 insertions(+)
22
create mode 100644 include/hw/nvram/xlnx-zynqmp-efuse.h
23
create mode 100644 hw/nvram/xlnx-zynqmp-efuse.c
24
17
25
diff --git a/include/hw/nvram/xlnx-zynqmp-efuse.h b/include/hw/nvram/xlnx-zynqmp-efuse.h
18
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
26
new file mode 100644
19
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX
20
--- a/include/hw/arm/fsl-imx6ul.h
28
--- /dev/null
21
+++ b/include/hw/arm/fsl-imx6ul.h
29
+++ b/include/hw/nvram/xlnx-zynqmp-efuse.h
22
@@ -XXX,XX +XXX,XX @@ enum FslIMX6ULConfiguration {
30
@@ -XXX,XX +XXX,XX @@
23
FSL_IMX6UL_NUM_USBS = 2,
31
+/*
24
FSL_IMX6UL_NUM_SAIS = 3,
32
+ * Copyright (c) 2021 Xilinx Inc.
25
FSL_IMX6UL_NUM_CANS = 2,
33
+ *
26
- FSL_IMX6UL_NUM_PWMS = 4,
34
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
27
+ FSL_IMX6UL_NUM_PWMS = 8,
35
+ * of this software and associated documentation files (the "Software"), to deal
28
};
36
+ * in the Software without restriction, including without limitation the rights
29
37
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
30
struct FslIMX6ULState {
38
+ * copies of the Software, and to permit persons to whom the Software is
31
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
39
+ * furnished to do so, subject to the following conditions:
32
index XXXXXXX..XXXXXXX 100644
40
+ *
33
--- a/hw/arm/fsl-imx6ul.c
41
+ * The above copyright notice and this permission notice shall be included in
34
+++ b/hw/arm/fsl-imx6ul.c
42
+ * all copies or substantial portions of the Software.
35
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
43
+ *
36
FSL_IMX6UL_PWM2_ADDR,
44
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37
FSL_IMX6UL_PWM3_ADDR,
45
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38
FSL_IMX6UL_PWM4_ADDR,
46
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
39
+ FSL_IMX6UL_PWM5_ADDR,
47
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
40
+ FSL_IMX6UL_PWM6_ADDR,
48
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
41
+ FSL_IMX6UL_PWM7_ADDR,
49
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
42
+ FSL_IMX6UL_PWM8_ADDR,
50
+ * THE SOFTWARE.
43
};
51
+ */
44
52
+#ifndef XLNX_ZYNQMP_EFUSE_H
45
snprintf(name, NAME_SIZE, "pwm%d", i);
53
+#define XLNX_ZYNQMP_EFUSE_H
46
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
54
+
47
create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR,
55
+#include "hw/irq.h"
48
FSL_IMX6UL_LCDIF_SIZE);
56
+#include "hw/sysbus.h"
49
57
+#include "hw/register.h"
50
+ /*
58
+#include "hw/nvram/xlnx-efuse.h"
51
+ * CSU
59
+
52
+ */
60
+#define XLNX_ZYNQMP_EFUSE_R_MAX ((0x10fc / 4) + 1)
53
+ create_unimplemented_device("csu", FSL_IMX6UL_CSU_ADDR,
61
+
54
+ FSL_IMX6UL_CSU_SIZE);
62
+#define TYPE_XLNX_ZYNQMP_EFUSE "xlnx,zynqmp-efuse"
63
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPEFuse, XLNX_ZYNQMP_EFUSE);
64
+
65
+struct XlnxZynqMPEFuse {
66
+ SysBusDevice parent_obj;
67
+ qemu_irq irq;
68
+
69
+ XlnxEFuse *efuse;
70
+ uint32_t regs[XLNX_ZYNQMP_EFUSE_R_MAX];
71
+ RegisterInfo regs_info[XLNX_ZYNQMP_EFUSE_R_MAX];
72
+};
73
+
74
+#endif
75
diff --git a/hw/nvram/xlnx-zynqmp-efuse.c b/hw/nvram/xlnx-zynqmp-efuse.c
76
new file mode 100644
77
index XXXXXXX..XXXXXXX
78
--- /dev/null
79
+++ b/hw/nvram/xlnx-zynqmp-efuse.c
80
@@ -XXX,XX +XXX,XX @@
81
+/*
82
+ * QEMU model of the ZynqMP eFuse
83
+ *
84
+ * Copyright (c) 2015 Xilinx Inc.
85
+ *
86
+ * Written by Edgar E. Iglesias <edgari@xilinx.com>
87
+ *
88
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
89
+ * of this software and associated documentation files (the "Software"), to deal
90
+ * in the Software without restriction, including without limitation the rights
91
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
92
+ * copies of the Software, and to permit persons to whom the Software is
93
+ * furnished to do so, subject to the following conditions:
94
+ *
95
+ * The above copyright notice and this permission notice shall be included in
96
+ * all copies or substantial portions of the Software.
97
+ *
98
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
99
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
100
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
101
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
102
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
103
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
104
+ * THE SOFTWARE.
105
+ */
106
+
107
+#include "qemu/osdep.h"
108
+#include "hw/nvram/xlnx-zynqmp-efuse.h"
109
+
110
+#include "qemu/log.h"
111
+#include "qapi/error.h"
112
+#include "migration/vmstate.h"
113
+#include "hw/qdev-properties.h"
114
+
115
+#ifndef ZYNQMP_EFUSE_ERR_DEBUG
116
+#define ZYNQMP_EFUSE_ERR_DEBUG 0
117
+#endif
118
+
119
+REG32(WR_LOCK, 0x0)
120
+ FIELD(WR_LOCK, LOCK, 0, 16)
121
+REG32(CFG, 0x4)
122
+ FIELD(CFG, SLVERR_ENABLE, 5, 1)
123
+ FIELD(CFG, MARGIN_RD, 2, 2)
124
+ FIELD(CFG, PGM_EN, 1, 1)
125
+ FIELD(CFG, EFUSE_CLK_SEL, 0, 1)
126
+REG32(STATUS, 0x8)
127
+ FIELD(STATUS, AES_CRC_PASS, 7, 1)
128
+ FIELD(STATUS, AES_CRC_DONE, 6, 1)
129
+ FIELD(STATUS, CACHE_DONE, 5, 1)
130
+ FIELD(STATUS, CACHE_LOAD, 4, 1)
131
+ FIELD(STATUS, EFUSE_3_TBIT, 2, 1)
132
+ FIELD(STATUS, EFUSE_2_TBIT, 1, 1)
133
+ FIELD(STATUS, EFUSE_0_TBIT, 0, 1)
134
+REG32(EFUSE_PGM_ADDR, 0xc)
135
+ FIELD(EFUSE_PGM_ADDR, EFUSE, 11, 2)
136
+ FIELD(EFUSE_PGM_ADDR, ROW, 5, 6)
137
+ FIELD(EFUSE_PGM_ADDR, COLUMN, 0, 5)
138
+REG32(EFUSE_RD_ADDR, 0x10)
139
+ FIELD(EFUSE_RD_ADDR, EFUSE, 11, 2)
140
+ FIELD(EFUSE_RD_ADDR, ROW, 5, 6)
141
+REG32(EFUSE_RD_DATA, 0x14)
142
+REG32(TPGM, 0x18)
143
+ FIELD(TPGM, VALUE, 0, 16)
144
+REG32(TRD, 0x1c)
145
+ FIELD(TRD, VALUE, 0, 8)
146
+REG32(TSU_H_PS, 0x20)
147
+ FIELD(TSU_H_PS, VALUE, 0, 8)
148
+REG32(TSU_H_PS_CS, 0x24)
149
+ FIELD(TSU_H_PS_CS, VALUE, 0, 8)
150
+REG32(TSU_H_CS, 0x2c)
151
+ FIELD(TSU_H_CS, VALUE, 0, 4)
152
+REG32(EFUSE_ISR, 0x30)
153
+ FIELD(EFUSE_ISR, APB_SLVERR, 31, 1)
154
+ FIELD(EFUSE_ISR, CACHE_ERROR, 4, 1)
155
+ FIELD(EFUSE_ISR, RD_ERROR, 3, 1)
156
+ FIELD(EFUSE_ISR, RD_DONE, 2, 1)
157
+ FIELD(EFUSE_ISR, PGM_ERROR, 1, 1)
158
+ FIELD(EFUSE_ISR, PGM_DONE, 0, 1)
159
+REG32(EFUSE_IMR, 0x34)
160
+ FIELD(EFUSE_IMR, APB_SLVERR, 31, 1)
161
+ FIELD(EFUSE_IMR, CACHE_ERROR, 4, 1)
162
+ FIELD(EFUSE_IMR, RD_ERROR, 3, 1)
163
+ FIELD(EFUSE_IMR, RD_DONE, 2, 1)
164
+ FIELD(EFUSE_IMR, PGM_ERROR, 1, 1)
165
+ FIELD(EFUSE_IMR, PGM_DONE, 0, 1)
166
+REG32(EFUSE_IER, 0x38)
167
+ FIELD(EFUSE_IER, APB_SLVERR, 31, 1)
168
+ FIELD(EFUSE_IER, CACHE_ERROR, 4, 1)
169
+ FIELD(EFUSE_IER, RD_ERROR, 3, 1)
170
+ FIELD(EFUSE_IER, RD_DONE, 2, 1)
171
+ FIELD(EFUSE_IER, PGM_ERROR, 1, 1)
172
+ FIELD(EFUSE_IER, PGM_DONE, 0, 1)
173
+REG32(EFUSE_IDR, 0x3c)
174
+ FIELD(EFUSE_IDR, APB_SLVERR, 31, 1)
175
+ FIELD(EFUSE_IDR, CACHE_ERROR, 4, 1)
176
+ FIELD(EFUSE_IDR, RD_ERROR, 3, 1)
177
+ FIELD(EFUSE_IDR, RD_DONE, 2, 1)
178
+ FIELD(EFUSE_IDR, PGM_ERROR, 1, 1)
179
+ FIELD(EFUSE_IDR, PGM_DONE, 0, 1)
180
+REG32(EFUSE_CACHE_LOAD, 0x40)
181
+ FIELD(EFUSE_CACHE_LOAD, LOAD, 0, 1)
182
+REG32(EFUSE_PGM_LOCK, 0x44)
183
+ FIELD(EFUSE_PGM_LOCK, SPK_ID_LOCK, 0, 1)
184
+REG32(EFUSE_AES_CRC, 0x48)
185
+REG32(EFUSE_TBITS_PRGRMG_EN, 0x100)
186
+ FIELD(EFUSE_TBITS_PRGRMG_EN, TBITS_PRGRMG_EN, 3, 1)
187
+REG32(DNA_0, 0x100c)
188
+REG32(DNA_1, 0x1010)
189
+REG32(DNA_2, 0x1014)
190
+REG32(IPDISABLE, 0x1018)
191
+ FIELD(IPDISABLE, VCU_DIS, 8, 1)
192
+ FIELD(IPDISABLE, GPU_DIS, 5, 1)
193
+ FIELD(IPDISABLE, APU3_DIS, 3, 1)
194
+ FIELD(IPDISABLE, APU2_DIS, 2, 1)
195
+ FIELD(IPDISABLE, APU1_DIS, 1, 1)
196
+ FIELD(IPDISABLE, APU0_DIS, 0, 1)
197
+REG32(SYSOSC_CTRL, 0x101c)
198
+ FIELD(SYSOSC_CTRL, SYSOSC_EN, 0, 1)
199
+REG32(USER_0, 0x1020)
200
+REG32(USER_1, 0x1024)
201
+REG32(USER_2, 0x1028)
202
+REG32(USER_3, 0x102c)
203
+REG32(USER_4, 0x1030)
204
+REG32(USER_5, 0x1034)
205
+REG32(USER_6, 0x1038)
206
+REG32(USER_7, 0x103c)
207
+REG32(MISC_USER_CTRL, 0x1040)
208
+ FIELD(MISC_USER_CTRL, FPD_SC_EN_0, 14, 1)
209
+ FIELD(MISC_USER_CTRL, LPD_SC_EN_0, 11, 1)
210
+ FIELD(MISC_USER_CTRL, LBIST_EN, 10, 1)
211
+ FIELD(MISC_USER_CTRL, USR_WRLK_7, 7, 1)
212
+ FIELD(MISC_USER_CTRL, USR_WRLK_6, 6, 1)
213
+ FIELD(MISC_USER_CTRL, USR_WRLK_5, 5, 1)
214
+ FIELD(MISC_USER_CTRL, USR_WRLK_4, 4, 1)
215
+ FIELD(MISC_USER_CTRL, USR_WRLK_3, 3, 1)
216
+ FIELD(MISC_USER_CTRL, USR_WRLK_2, 2, 1)
217
+ FIELD(MISC_USER_CTRL, USR_WRLK_1, 1, 1)
218
+ FIELD(MISC_USER_CTRL, USR_WRLK_0, 0, 1)
219
+REG32(ROM_RSVD, 0x1044)
220
+ FIELD(ROM_RSVD, PBR_BOOT_ERROR, 0, 3)
221
+REG32(PUF_CHASH, 0x1050)
222
+REG32(PUF_MISC, 0x1054)
223
+ FIELD(PUF_MISC, REGISTER_DIS, 31, 1)
224
+ FIELD(PUF_MISC, SYN_WRLK, 30, 1)
225
+ FIELD(PUF_MISC, SYN_INVLD, 29, 1)
226
+ FIELD(PUF_MISC, TEST2_DIS, 28, 1)
227
+ FIELD(PUF_MISC, UNUSED27, 27, 1)
228
+ FIELD(PUF_MISC, UNUSED26, 26, 1)
229
+ FIELD(PUF_MISC, UNUSED25, 25, 1)
230
+ FIELD(PUF_MISC, UNUSED24, 24, 1)
231
+ FIELD(PUF_MISC, AUX, 0, 24)
232
+REG32(SEC_CTRL, 0x1058)
233
+ FIELD(SEC_CTRL, PPK1_INVLD, 30, 2)
234
+ FIELD(SEC_CTRL, PPK1_WRLK, 29, 1)
235
+ FIELD(SEC_CTRL, PPK0_INVLD, 27, 2)
236
+ FIELD(SEC_CTRL, PPK0_WRLK, 26, 1)
237
+ FIELD(SEC_CTRL, RSA_EN, 11, 15)
238
+ FIELD(SEC_CTRL, SEC_LOCK, 10, 1)
239
+ FIELD(SEC_CTRL, PROG_GATE_2, 9, 1)
240
+ FIELD(SEC_CTRL, PROG_GATE_1, 8, 1)
241
+ FIELD(SEC_CTRL, PROG_GATE_0, 7, 1)
242
+ FIELD(SEC_CTRL, DFT_DIS, 6, 1)
243
+ FIELD(SEC_CTRL, JTAG_DIS, 5, 1)
244
+ FIELD(SEC_CTRL, ERROR_DIS, 4, 1)
245
+ FIELD(SEC_CTRL, BBRAM_DIS, 3, 1)
246
+ FIELD(SEC_CTRL, ENC_ONLY, 2, 1)
247
+ FIELD(SEC_CTRL, AES_WRLK, 1, 1)
248
+ FIELD(SEC_CTRL, AES_RDLK, 0, 1)
249
+REG32(SPK_ID, 0x105c)
250
+REG32(PPK0_0, 0x10a0)
251
+REG32(PPK0_1, 0x10a4)
252
+REG32(PPK0_2, 0x10a8)
253
+REG32(PPK0_3, 0x10ac)
254
+REG32(PPK0_4, 0x10b0)
255
+REG32(PPK0_5, 0x10b4)
256
+REG32(PPK0_6, 0x10b8)
257
+REG32(PPK0_7, 0x10bc)
258
+REG32(PPK0_8, 0x10c0)
259
+REG32(PPK0_9, 0x10c4)
260
+REG32(PPK0_10, 0x10c8)
261
+REG32(PPK0_11, 0x10cc)
262
+REG32(PPK1_0, 0x10d0)
263
+REG32(PPK1_1, 0x10d4)
264
+REG32(PPK1_2, 0x10d8)
265
+REG32(PPK1_3, 0x10dc)
266
+REG32(PPK1_4, 0x10e0)
267
+REG32(PPK1_5, 0x10e4)
268
+REG32(PPK1_6, 0x10e8)
269
+REG32(PPK1_7, 0x10ec)
270
+REG32(PPK1_8, 0x10f0)
271
+REG32(PPK1_9, 0x10f4)
272
+REG32(PPK1_10, 0x10f8)
273
+REG32(PPK1_11, 0x10fc)
274
+
275
+#define BIT_POS(ROW, COLUMN) (ROW * 32 + COLUMN)
276
+#define R_MAX (R_PPK1_11 + 1)
277
+
278
+/* #define EFUSE_XOSC 26 */
279
+
280
+/*
281
+ * eFUSE layout references:
282
+ * ZynqMP: UG1085 (v2.1) August 21, 2019, p.277, Table 12-13
283
+ */
284
+#define EFUSE_AES_RDLK BIT_POS(22, 0)
285
+#define EFUSE_AES_WRLK BIT_POS(22, 1)
286
+#define EFUSE_ENC_ONLY BIT_POS(22, 2)
287
+#define EFUSE_BBRAM_DIS BIT_POS(22, 3)
288
+#define EFUSE_ERROR_DIS BIT_POS(22, 4)
289
+#define EFUSE_JTAG_DIS BIT_POS(22, 5)
290
+#define EFUSE_DFT_DIS BIT_POS(22, 6)
291
+#define EFUSE_PROG_GATE_0 BIT_POS(22, 7)
292
+#define EFUSE_PROG_GATE_1 BIT_POS(22, 7)
293
+#define EFUSE_PROG_GATE_2 BIT_POS(22, 9)
294
+#define EFUSE_SEC_LOCK BIT_POS(22, 10)
295
+#define EFUSE_RSA_EN BIT_POS(22, 11)
296
+#define EFUSE_RSA_EN14 BIT_POS(22, 25)
297
+#define EFUSE_PPK0_WRLK BIT_POS(22, 26)
298
+#define EFUSE_PPK0_INVLD BIT_POS(22, 27)
299
+#define EFUSE_PPK0_INVLD_1 BIT_POS(22, 28)
300
+#define EFUSE_PPK1_WRLK BIT_POS(22, 29)
301
+#define EFUSE_PPK1_INVLD BIT_POS(22, 30)
302
+#define EFUSE_PPK1_INVLD_1 BIT_POS(22, 31)
303
+
304
+/* Areas. */
305
+#define EFUSE_TRIM_START BIT_POS(1, 0)
306
+#define EFUSE_TRIM_END BIT_POS(1, 30)
307
+#define EFUSE_DNA_START BIT_POS(3, 0)
308
+#define EFUSE_DNA_END BIT_POS(5, 31)
309
+#define EFUSE_AES_START BIT_POS(24, 0)
310
+#define EFUSE_AES_END BIT_POS(31, 31)
311
+#define EFUSE_ROM_START BIT_POS(17, 0)
312
+#define EFUSE_ROM_END BIT_POS(17, 31)
313
+#define EFUSE_IPDIS_START BIT_POS(6, 0)
314
+#define EFUSE_IPDIS_END BIT_POS(6, 31)
315
+#define EFUSE_USER_START BIT_POS(8, 0)
316
+#define EFUSE_USER_END BIT_POS(15, 31)
317
+#define EFUSE_BISR_START BIT_POS(32, 0)
318
+#define EFUSE_BISR_END BIT_POS(39, 31)
319
+
320
+#define EFUSE_USER_CTRL_START BIT_POS(16, 0)
321
+#define EFUSE_USER_CTRL_END BIT_POS(16, 16)
322
+#define EFUSE_USER_CTRL_MASK ((uint32_t)MAKE_64BIT_MASK(0, 17))
323
+
324
+#define EFUSE_PUF_CHASH_START BIT_POS(20, 0)
325
+#define EFUSE_PUF_CHASH_END BIT_POS(20, 31)
326
+#define EFUSE_PUF_MISC_START BIT_POS(21, 0)
327
+#define EFUSE_PUF_MISC_END BIT_POS(21, 31)
328
+#define EFUSE_PUF_SYN_WRLK BIT_POS(21, 30)
329
+
330
+#define EFUSE_SPK_START BIT_POS(23, 0)
331
+#define EFUSE_SPK_END BIT_POS(23, 31)
332
+
333
+#define EFUSE_PPK0_START BIT_POS(40, 0)
334
+#define EFUSE_PPK0_END BIT_POS(51, 31)
335
+#define EFUSE_PPK1_START BIT_POS(52, 0)
336
+#define EFUSE_PPK1_END BIT_POS(63, 31)
337
+
338
+#define EFUSE_CACHE_FLD(s, reg, field) \
339
+ ARRAY_FIELD_DP32((s)->regs, reg, field, \
340
+ (xlnx_efuse_get_row((s->efuse), EFUSE_ ## field) \
341
+ >> (EFUSE_ ## field % 32)))
342
+
343
+#define EFUSE_CACHE_BIT(s, reg, field) \
344
+ ARRAY_FIELD_DP32((s)->regs, reg, field, xlnx_efuse_get_bit((s->efuse), \
345
+ EFUSE_ ## field))
346
+
347
+#define FBIT_UNKNOWN (~0)
348
+
349
+QEMU_BUILD_BUG_ON(R_MAX != ARRAY_SIZE(((XlnxZynqMPEFuse *)0)->regs));
350
+
351
+static void update_tbit_status(XlnxZynqMPEFuse *s)
352
+{
353
+ unsigned int check = xlnx_efuse_tbits_check(s->efuse);
354
+ uint32_t val = s->regs[R_STATUS];
355
+
356
+ val = FIELD_DP32(val, STATUS, EFUSE_0_TBIT, !!(check & (1 << 0)));
357
+ val = FIELD_DP32(val, STATUS, EFUSE_2_TBIT, !!(check & (1 << 1)));
358
+ val = FIELD_DP32(val, STATUS, EFUSE_3_TBIT, !!(check & (1 << 2)));
359
+
360
+ s->regs[R_STATUS] = val;
361
+}
362
+
363
+/* Update the u32 array from efuse bits. Slow but simple approach. */
364
+static void cache_sync_u32(XlnxZynqMPEFuse *s, unsigned int r_start,
365
+ unsigned int f_start, unsigned int f_end,
366
+ unsigned int f_written)
367
+{
368
+ uint32_t *u32 = &s->regs[r_start];
369
+ unsigned int fbit, wbits = 0, u32_off = 0;
370
+
371
+ /* Avoid working on bits that are not relevant. */
372
+ if (f_written != FBIT_UNKNOWN
373
+ && (f_written < f_start || f_written > f_end)) {
374
+ return;
375
+ }
376
+
377
+ for (fbit = f_start; fbit <= f_end; fbit++, wbits++) {
378
+ if (wbits == 32) {
379
+ /* Update the key offset. */
380
+ u32_off += 1;
381
+ wbits = 0;
382
+ }
383
+ u32[u32_off] |= xlnx_efuse_get_bit(s->efuse, fbit) << wbits;
384
+ }
385
+}
386
+
387
+/*
388
+ * Keep the syncs in bit order so we can bail out for the
389
+ * slower ones.
390
+ */
391
+static void zynqmp_efuse_sync_cache(XlnxZynqMPEFuse *s, unsigned int bit)
392
+{
393
+ EFUSE_CACHE_BIT(s, SEC_CTRL, AES_RDLK);
394
+ EFUSE_CACHE_BIT(s, SEC_CTRL, AES_WRLK);
395
+ EFUSE_CACHE_BIT(s, SEC_CTRL, ENC_ONLY);
396
+ EFUSE_CACHE_BIT(s, SEC_CTRL, BBRAM_DIS);
397
+ EFUSE_CACHE_BIT(s, SEC_CTRL, ERROR_DIS);
398
+ EFUSE_CACHE_BIT(s, SEC_CTRL, JTAG_DIS);
399
+ EFUSE_CACHE_BIT(s, SEC_CTRL, DFT_DIS);
400
+ EFUSE_CACHE_BIT(s, SEC_CTRL, PROG_GATE_0);
401
+ EFUSE_CACHE_BIT(s, SEC_CTRL, PROG_GATE_1);
402
+ EFUSE_CACHE_BIT(s, SEC_CTRL, PROG_GATE_2);
403
+ EFUSE_CACHE_BIT(s, SEC_CTRL, SEC_LOCK);
404
+ EFUSE_CACHE_BIT(s, SEC_CTRL, PPK0_WRLK);
405
+ EFUSE_CACHE_BIT(s, SEC_CTRL, PPK1_WRLK);
406
+
407
+ EFUSE_CACHE_FLD(s, SEC_CTRL, RSA_EN);
408
+ EFUSE_CACHE_FLD(s, SEC_CTRL, PPK0_INVLD);
409
+ EFUSE_CACHE_FLD(s, SEC_CTRL, PPK1_INVLD);
410
+
411
+ /* Update the tbits. */
412
+ update_tbit_status(s);
413
+
414
+ /* Sync the various areas. */
415
+ s->regs[R_MISC_USER_CTRL] = xlnx_efuse_get_row(s->efuse,
416
+ EFUSE_USER_CTRL_START)
417
+ & EFUSE_USER_CTRL_MASK;
418
+ s->regs[R_PUF_CHASH] = xlnx_efuse_get_row(s->efuse, EFUSE_PUF_CHASH_START);
419
+ s->regs[R_PUF_MISC] = xlnx_efuse_get_row(s->efuse, EFUSE_PUF_MISC_START);
420
+
421
+ cache_sync_u32(s, R_DNA_0, EFUSE_DNA_START, EFUSE_DNA_END, bit);
422
+
423
+ if (bit < EFUSE_AES_START) {
424
+ return;
425
+ }
426
+
427
+ cache_sync_u32(s, R_ROM_RSVD, EFUSE_ROM_START, EFUSE_ROM_END, bit);
428
+ cache_sync_u32(s, R_IPDISABLE, EFUSE_IPDIS_START, EFUSE_IPDIS_END, bit);
429
+ cache_sync_u32(s, R_USER_0, EFUSE_USER_START, EFUSE_USER_END, bit);
430
+ cache_sync_u32(s, R_SPK_ID, EFUSE_SPK_START, EFUSE_SPK_END, bit);
431
+ cache_sync_u32(s, R_PPK0_0, EFUSE_PPK0_START, EFUSE_PPK0_END, bit);
432
+ cache_sync_u32(s, R_PPK1_0, EFUSE_PPK1_START, EFUSE_PPK1_END, bit);
433
+}
434
+
435
+static void zynqmp_efuse_update_irq(XlnxZynqMPEFuse *s)
436
+{
437
+ bool pending = s->regs[R_EFUSE_ISR] & s->regs[R_EFUSE_IMR];
438
+ qemu_set_irq(s->irq, pending);
439
+}
440
+
441
+static void zynqmp_efuse_isr_postw(RegisterInfo *reg, uint64_t val64)
442
+{
443
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
444
+ zynqmp_efuse_update_irq(s);
445
+}
446
+
447
+static uint64_t zynqmp_efuse_ier_prew(RegisterInfo *reg, uint64_t val64)
448
+{
449
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
450
+ uint32_t val = val64;
451
+
452
+ s->regs[R_EFUSE_IMR] |= val;
453
+ zynqmp_efuse_update_irq(s);
454
+ return 0;
455
+}
456
+
457
+static uint64_t zynqmp_efuse_idr_prew(RegisterInfo *reg, uint64_t val64)
458
+{
459
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
460
+ uint32_t val = val64;
461
+
462
+ s->regs[R_EFUSE_IMR] &= ~val;
463
+ zynqmp_efuse_update_irq(s);
464
+ return 0;
465
+}
466
+
467
+static void zynqmp_efuse_pgm_addr_postw(RegisterInfo *reg, uint64_t val64)
468
+{
469
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
470
+ unsigned bit = val64;
471
+ unsigned page = FIELD_EX32(bit, EFUSE_PGM_ADDR, EFUSE);
472
+ bool puf_prot = false;
473
+ const char *errmsg = NULL;
474
+
475
+ /* Allow only valid array, and adjust for skipped array 1 */
476
+ switch (page) {
477
+ case 0:
478
+ break;
479
+ case 2 ... 3:
480
+ bit = FIELD_DP32(bit, EFUSE_PGM_ADDR, EFUSE, page - 1);
481
+ puf_prot = xlnx_efuse_get_bit(s->efuse, EFUSE_PUF_SYN_WRLK);
482
+ break;
483
+ default:
484
+ errmsg = "Invalid address";
485
+ goto pgm_done;
486
+ }
487
+
488
+ if (ARRAY_FIELD_EX32(s->regs, WR_LOCK, LOCK)) {
489
+ errmsg = "Array write-locked";
490
+ goto pgm_done;
491
+ }
492
+
493
+ if (!ARRAY_FIELD_EX32(s->regs, CFG, PGM_EN)) {
494
+ errmsg = "Array pgm-disabled";
495
+ goto pgm_done;
496
+ }
497
+
498
+ if (puf_prot) {
499
+ errmsg = "PUF_HD-store write-locked";
500
+ goto pgm_done;
501
+ }
502
+
503
+ if (ARRAY_FIELD_EX32(s->regs, SEC_CTRL, AES_WRLK)
504
+ && bit >= EFUSE_AES_START && bit <= EFUSE_AES_END) {
505
+ errmsg = "AES key-store Write-locked";
506
+ goto pgm_done;
507
+ }
508
+
509
+ if (!xlnx_efuse_set_bit(s->efuse, bit)) {
510
+ errmsg = "Write failed";
511
+ }
512
+
513
+ pgm_done:
514
+ if (!errmsg) {
515
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_ERROR, 0);
516
+ } else {
517
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_ERROR, 1);
518
+ qemu_log_mask(LOG_GUEST_ERROR,
519
+ "%s - eFuse write error: %s; addr=0x%x\n",
520
+ object_get_canonical_path(OBJECT(s)),
521
+ errmsg, (unsigned)val64);
522
+ }
523
+
524
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_DONE, 1);
525
+ zynqmp_efuse_update_irq(s);
526
+}
527
+
528
+static void zynqmp_efuse_rd_addr_postw(RegisterInfo *reg, uint64_t val64)
529
+{
530
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
531
+
55
+
532
+ /*
56
+ /*
533
+ * Grant reads only to allowed bits; reference sources:
57
+ * TZASC
534
+ * 1/ XilSKey - XilSKey_ZynqMp_EfusePs_ReadRow()
535
+ * 2/ UG1085, v2.0, table 12-13
536
+ * (note: enumerates the masks as <first, last> per described in
537
+ * references to avoid mental translation).
538
+ */
58
+ */
539
+#define COL_MASK(L_, H_) \
59
+ create_unimplemented_device("tzasc", FSL_IMX6UL_TZASC_ADDR,
540
+ ((uint32_t)MAKE_64BIT_MASK((L_), (1 + (H_) - (L_))))
60
+ FSL_IMX6UL_TZASC_SIZE);
541
+
61
+
542
+ static const uint32_t ary0_col_mask[] = {
62
/*
543
+ /* XilSKey - XSK_ZYNQMP_EFUSEPS_TBITS_ROW */
63
* ROM memory
544
+ [0] = COL_MASK(28, 31),
64
*/
545
+
546
+ /* XilSKey - XSK_ZYNQMP_EFUSEPS_USR{0:7}_FUSE_ROW */
547
+ [8] = COL_MASK(0, 31), [9] = COL_MASK(0, 31),
548
+ [10] = COL_MASK(0, 31), [11] = COL_MASK(0, 31),
549
+ [12] = COL_MASK(0, 31), [13] = COL_MASK(0, 31),
550
+ [14] = COL_MASK(0, 31), [15] = COL_MASK(0, 31),
551
+
552
+ /* XilSKey - XSK_ZYNQMP_EFUSEPS_MISC_USR_CTRL_ROW */
553
+ [16] = COL_MASK(0, 7) | COL_MASK(10, 16),
554
+
555
+ /* XilSKey - XSK_ZYNQMP_EFUSEPS_PBR_BOOT_ERR_ROW */
556
+ [17] = COL_MASK(0, 2),
557
+
558
+ /* XilSKey - XSK_ZYNQMP_EFUSEPS_PUF_CHASH_ROW */
559
+ [20] = COL_MASK(0, 31),
560
+
561
+ /* XilSKey - XSK_ZYNQMP_EFUSEPS_PUF_AUX_ROW */
562
+ [21] = COL_MASK(0, 23) | COL_MASK(29, 31),
563
+
564
+ /* XilSKey - XSK_ZYNQMP_EFUSEPS_SEC_CTRL_ROW */
565
+ [22] = COL_MASK(0, 31),
566
+
567
+ /* XilSKey - XSK_ZYNQMP_EFUSEPS_SPK_ID_ROW */
568
+ [23] = COL_MASK(0, 31),
569
+
570
+ /* XilSKey - XSK_ZYNQMP_EFUSEPS_PPK0_START_ROW */
571
+ [40] = COL_MASK(0, 31), [41] = COL_MASK(0, 31),
572
+ [42] = COL_MASK(0, 31), [43] = COL_MASK(0, 31),
573
+ [44] = COL_MASK(0, 31), [45] = COL_MASK(0, 31),
574
+ [46] = COL_MASK(0, 31), [47] = COL_MASK(0, 31),
575
+ [48] = COL_MASK(0, 31), [49] = COL_MASK(0, 31),
576
+ [50] = COL_MASK(0, 31), [51] = COL_MASK(0, 31),
577
+
578
+ /* XilSKey - XSK_ZYNQMP_EFUSEPS_PPK1_START_ROW */
579
+ [52] = COL_MASK(0, 31), [53] = COL_MASK(0, 31),
580
+ [54] = COL_MASK(0, 31), [55] = COL_MASK(0, 31),
581
+ [56] = COL_MASK(0, 31), [57] = COL_MASK(0, 31),
582
+ [58] = COL_MASK(0, 31), [59] = COL_MASK(0, 31),
583
+ [60] = COL_MASK(0, 31), [61] = COL_MASK(0, 31),
584
+ [62] = COL_MASK(0, 31), [63] = COL_MASK(0, 31),
585
+ };
586
+
587
+ uint32_t col_mask = COL_MASK(0, 31);
588
+#undef COL_MASK
589
+
590
+ uint32_t efuse_idx = s->regs[R_EFUSE_RD_ADDR];
591
+ uint32_t efuse_ary = FIELD_EX32(efuse_idx, EFUSE_RD_ADDR, EFUSE);
592
+ uint32_t efuse_row = FIELD_EX32(efuse_idx, EFUSE_RD_ADDR, ROW);
593
+
594
+ switch (efuse_ary) {
595
+ case 0: /* Various */
596
+ if (efuse_row >= ARRAY_SIZE(ary0_col_mask)) {
597
+ goto denied;
598
+ }
599
+
600
+ col_mask = ary0_col_mask[efuse_row];
601
+ if (!col_mask) {
602
+ goto denied;
603
+ }
604
+ break;
605
+ case 2: /* PUF helper data, adjust for skipped array 1 */
606
+ case 3:
607
+ val64 = FIELD_DP32(efuse_idx, EFUSE_RD_ADDR, EFUSE, efuse_ary - 1);
608
+ break;
609
+ default:
610
+ goto denied;
611
+ }
612
+
613
+ s->regs[R_EFUSE_RD_DATA] = xlnx_efuse_get_row(s->efuse, val64) & col_mask;
614
+
615
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_ERROR, 0);
616
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_DONE, 1);
617
+ zynqmp_efuse_update_irq(s);
618
+ return;
619
+
620
+ denied:
621
+ qemu_log_mask(LOG_GUEST_ERROR,
622
+ "%s: Denied efuse read from array %u, row %u\n",
623
+ object_get_canonical_path(OBJECT(s)),
624
+ efuse_ary, efuse_row);
625
+
626
+ s->regs[R_EFUSE_RD_DATA] = 0;
627
+
628
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_ERROR, 1);
629
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_DONE, 0);
630
+ zynqmp_efuse_update_irq(s);
631
+}
632
+
633
+static void zynqmp_efuse_aes_crc_postw(RegisterInfo *reg, uint64_t val64)
634
+{
635
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
636
+ bool ok;
637
+
638
+ ok = xlnx_efuse_k256_check(s->efuse, (uint32_t)val64, EFUSE_AES_START);
639
+
640
+ ARRAY_FIELD_DP32(s->regs, STATUS, AES_CRC_PASS, (ok ? 1 : 0));
641
+ ARRAY_FIELD_DP32(s->regs, STATUS, AES_CRC_DONE, 1);
642
+
643
+ s->regs[R_EFUSE_AES_CRC] = 0; /* crc value is write-only */
644
+}
645
+
646
+static uint64_t zynqmp_efuse_cache_load_prew(RegisterInfo *reg,
647
+ uint64_t valu64)
648
+{
649
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
650
+
651
+ if (valu64 & R_EFUSE_CACHE_LOAD_LOAD_MASK) {
652
+ zynqmp_efuse_sync_cache(s, FBIT_UNKNOWN);
653
+ ARRAY_FIELD_DP32(s->regs, STATUS, CACHE_DONE, 1);
654
+ zynqmp_efuse_update_irq(s);
655
+ }
656
+
657
+ return 0;
658
+}
659
+
660
+static uint64_t zynqmp_efuse_wr_lock_prew(RegisterInfo *reg, uint64_t val)
661
+{
662
+ return val == 0xDF0D ? 0 : 1;
663
+}
664
+
665
+static RegisterAccessInfo zynqmp_efuse_regs_info[] = {
666
+ { .name = "WR_LOCK", .addr = A_WR_LOCK,
667
+ .reset = 0x1,
668
+ .pre_write = zynqmp_efuse_wr_lock_prew,
669
+ },{ .name = "CFG", .addr = A_CFG,
670
+ },{ .name = "STATUS", .addr = A_STATUS,
671
+ .rsvd = 0x8,
672
+ .ro = 0xff,
673
+ },{ .name = "EFUSE_PGM_ADDR", .addr = A_EFUSE_PGM_ADDR,
674
+ .post_write = zynqmp_efuse_pgm_addr_postw
675
+ },{ .name = "EFUSE_RD_ADDR", .addr = A_EFUSE_RD_ADDR,
676
+ .rsvd = 0x1f,
677
+ .post_write = zynqmp_efuse_rd_addr_postw,
678
+ },{ .name = "EFUSE_RD_DATA", .addr = A_EFUSE_RD_DATA,
679
+ .ro = 0xffffffff,
680
+ },{ .name = "TPGM", .addr = A_TPGM,
681
+ },{ .name = "TRD", .addr = A_TRD,
682
+ .reset = 0x1b,
683
+ },{ .name = "TSU_H_PS", .addr = A_TSU_H_PS,
684
+ .reset = 0xff,
685
+ },{ .name = "TSU_H_PS_CS", .addr = A_TSU_H_PS_CS,
686
+ .reset = 0xb,
687
+ },{ .name = "TSU_H_CS", .addr = A_TSU_H_CS,
688
+ .reset = 0x7,
689
+ },{ .name = "EFUSE_ISR", .addr = A_EFUSE_ISR,
690
+ .rsvd = 0x7fffffe0,
691
+ .w1c = 0x8000001f,
692
+ .post_write = zynqmp_efuse_isr_postw,
693
+ },{ .name = "EFUSE_IMR", .addr = A_EFUSE_IMR,
694
+ .reset = 0x8000001f,
695
+ .rsvd = 0x7fffffe0,
696
+ .ro = 0xffffffff,
697
+ },{ .name = "EFUSE_IER", .addr = A_EFUSE_IER,
698
+ .rsvd = 0x7fffffe0,
699
+ .pre_write = zynqmp_efuse_ier_prew,
700
+ },{ .name = "EFUSE_IDR", .addr = A_EFUSE_IDR,
701
+ .rsvd = 0x7fffffe0,
702
+ .pre_write = zynqmp_efuse_idr_prew,
703
+ },{ .name = "EFUSE_CACHE_LOAD", .addr = A_EFUSE_CACHE_LOAD,
704
+ .pre_write = zynqmp_efuse_cache_load_prew,
705
+ },{ .name = "EFUSE_PGM_LOCK", .addr = A_EFUSE_PGM_LOCK,
706
+ },{ .name = "EFUSE_AES_CRC", .addr = A_EFUSE_AES_CRC,
707
+ .post_write = zynqmp_efuse_aes_crc_postw,
708
+ },{ .name = "EFUSE_TBITS_PRGRMG_EN", .addr = A_EFUSE_TBITS_PRGRMG_EN,
709
+ .reset = R_EFUSE_TBITS_PRGRMG_EN_TBITS_PRGRMG_EN_MASK,
710
+ },{ .name = "DNA_0", .addr = A_DNA_0,
711
+ .ro = 0xffffffff,
712
+ },{ .name = "DNA_1", .addr = A_DNA_1,
713
+ .ro = 0xffffffff,
714
+ },{ .name = "DNA_2", .addr = A_DNA_2,
715
+ .ro = 0xffffffff,
716
+ },{ .name = "IPDISABLE", .addr = A_IPDISABLE,
717
+ .ro = 0xffffffff,
718
+ },{ .name = "SYSOSC_CTRL", .addr = A_SYSOSC_CTRL,
719
+ .ro = 0xffffffff,
720
+ },{ .name = "USER_0", .addr = A_USER_0,
721
+ .ro = 0xffffffff,
722
+ },{ .name = "USER_1", .addr = A_USER_1,
723
+ .ro = 0xffffffff,
724
+ },{ .name = "USER_2", .addr = A_USER_2,
725
+ .ro = 0xffffffff,
726
+ },{ .name = "USER_3", .addr = A_USER_3,
727
+ .ro = 0xffffffff,
728
+ },{ .name = "USER_4", .addr = A_USER_4,
729
+ .ro = 0xffffffff,
730
+ },{ .name = "USER_5", .addr = A_USER_5,
731
+ .ro = 0xffffffff,
732
+ },{ .name = "USER_6", .addr = A_USER_6,
733
+ .ro = 0xffffffff,
734
+ },{ .name = "USER_7", .addr = A_USER_7,
735
+ .ro = 0xffffffff,
736
+ },{ .name = "MISC_USER_CTRL", .addr = A_MISC_USER_CTRL,
737
+ .ro = 0xffffffff,
738
+ },{ .name = "ROM_RSVD", .addr = A_ROM_RSVD,
739
+ .ro = 0xffffffff,
740
+ },{ .name = "PUF_CHASH", .addr = A_PUF_CHASH,
741
+ .ro = 0xffffffff,
742
+ },{ .name = "PUF_MISC", .addr = A_PUF_MISC,
743
+ .ro = 0xffffffff,
744
+ },{ .name = "SEC_CTRL", .addr = A_SEC_CTRL,
745
+ .ro = 0xffffffff,
746
+ },{ .name = "SPK_ID", .addr = A_SPK_ID,
747
+ .ro = 0xffffffff,
748
+ },{ .name = "PPK0_0", .addr = A_PPK0_0,
749
+ .ro = 0xffffffff,
750
+ },{ .name = "PPK0_1", .addr = A_PPK0_1,
751
+ .ro = 0xffffffff,
752
+ },{ .name = "PPK0_2", .addr = A_PPK0_2,
753
+ .ro = 0xffffffff,
754
+ },{ .name = "PPK0_3", .addr = A_PPK0_3,
755
+ .ro = 0xffffffff,
756
+ },{ .name = "PPK0_4", .addr = A_PPK0_4,
757
+ .ro = 0xffffffff,
758
+ },{ .name = "PPK0_5", .addr = A_PPK0_5,
759
+ .ro = 0xffffffff,
760
+ },{ .name = "PPK0_6", .addr = A_PPK0_6,
761
+ .ro = 0xffffffff,
762
+ },{ .name = "PPK0_7", .addr = A_PPK0_7,
763
+ .ro = 0xffffffff,
764
+ },{ .name = "PPK0_8", .addr = A_PPK0_8,
765
+ .ro = 0xffffffff,
766
+ },{ .name = "PPK0_9", .addr = A_PPK0_9,
767
+ .ro = 0xffffffff,
768
+ },{ .name = "PPK0_10", .addr = A_PPK0_10,
769
+ .ro = 0xffffffff,
770
+ },{ .name = "PPK0_11", .addr = A_PPK0_11,
771
+ .ro = 0xffffffff,
772
+ },{ .name = "PPK1_0", .addr = A_PPK1_0,
773
+ .ro = 0xffffffff,
774
+ },{ .name = "PPK1_1", .addr = A_PPK1_1,
775
+ .ro = 0xffffffff,
776
+ },{ .name = "PPK1_2", .addr = A_PPK1_2,
777
+ .ro = 0xffffffff,
778
+ },{ .name = "PPK1_3", .addr = A_PPK1_3,
779
+ .ro = 0xffffffff,
780
+ },{ .name = "PPK1_4", .addr = A_PPK1_4,
781
+ .ro = 0xffffffff,
782
+ },{ .name = "PPK1_5", .addr = A_PPK1_5,
783
+ .ro = 0xffffffff,
784
+ },{ .name = "PPK1_6", .addr = A_PPK1_6,
785
+ .ro = 0xffffffff,
786
+ },{ .name = "PPK1_7", .addr = A_PPK1_7,
787
+ .ro = 0xffffffff,
788
+ },{ .name = "PPK1_8", .addr = A_PPK1_8,
789
+ .ro = 0xffffffff,
790
+ },{ .name = "PPK1_9", .addr = A_PPK1_9,
791
+ .ro = 0xffffffff,
792
+ },{ .name = "PPK1_10", .addr = A_PPK1_10,
793
+ .ro = 0xffffffff,
794
+ },{ .name = "PPK1_11", .addr = A_PPK1_11,
795
+ .ro = 0xffffffff,
796
+ }
797
+};
798
+
799
+static void zynqmp_efuse_reg_write(void *opaque, hwaddr addr,
800
+ uint64_t data, unsigned size)
801
+{
802
+ RegisterInfoArray *reg_array = opaque;
803
+ XlnxZynqMPEFuse *s;
804
+ Object *dev;
805
+
806
+ assert(reg_array != NULL);
807
+
808
+ dev = reg_array->mem.owner;
809
+ assert(dev);
810
+
811
+ s = XLNX_ZYNQMP_EFUSE(dev);
812
+
813
+ if (addr != A_WR_LOCK && s->regs[R_WR_LOCK]) {
814
+ qemu_log_mask(LOG_GUEST_ERROR,
815
+ "%s[reg_0x%02lx]: Attempt to write locked register.\n",
816
+ object_get_canonical_path(OBJECT(s)), (long)addr);
817
+ } else {
818
+ register_write_memory(opaque, addr, data, size);
819
+ }
820
+}
821
+
822
+static const MemoryRegionOps zynqmp_efuse_ops = {
823
+ .read = register_read_memory,
824
+ .write = zynqmp_efuse_reg_write,
825
+ .endianness = DEVICE_LITTLE_ENDIAN,
826
+ .valid = {
827
+ .min_access_size = 4,
828
+ .max_access_size = 4,
829
+ },
830
+};
831
+
832
+static void zynqmp_efuse_register_reset(RegisterInfo *reg)
833
+{
834
+ if (!reg->data || !reg->access) {
835
+ return;
836
+ }
837
+
838
+ /* Reset must not trigger some registers' writers */
839
+ switch (reg->access->addr) {
840
+ case A_EFUSE_AES_CRC:
841
+ *(uint32_t *)reg->data = reg->access->reset;
842
+ return;
843
+ }
844
+
845
+ register_reset(reg);
846
+}
847
+
848
+static void zynqmp_efuse_reset(DeviceState *dev)
849
+{
850
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(dev);
851
+ unsigned int i;
852
+
853
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
854
+ zynqmp_efuse_register_reset(&s->regs_info[i]);
855
+ }
856
+
857
+ zynqmp_efuse_sync_cache(s, FBIT_UNKNOWN);
858
+ ARRAY_FIELD_DP32(s->regs, STATUS, CACHE_DONE, 1);
859
+ zynqmp_efuse_update_irq(s);
860
+}
861
+
862
+static void zynqmp_efuse_realize(DeviceState *dev, Error **errp)
863
+{
864
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(dev);
865
+
866
+ if (!s->efuse) {
867
+ error_setg(errp, "%s.efuse: link property not connected to XLNX-EFUSE",
868
+ object_get_canonical_path(OBJECT(dev)));
869
+ return;
870
+ }
871
+
872
+ s->efuse->dev = dev;
873
+}
874
+
875
+static void zynqmp_efuse_init(Object *obj)
876
+{
877
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(obj);
878
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
879
+ RegisterInfoArray *reg_array;
880
+
881
+ reg_array =
882
+ register_init_block32(DEVICE(obj), zynqmp_efuse_regs_info,
883
+ ARRAY_SIZE(zynqmp_efuse_regs_info),
884
+ s->regs_info, s->regs,
885
+ &zynqmp_efuse_ops,
886
+ ZYNQMP_EFUSE_ERR_DEBUG,
887
+ R_MAX * 4);
888
+
889
+ sysbus_init_mmio(sbd, &reg_array->mem);
890
+ sysbus_init_irq(sbd, &s->irq);
891
+}
892
+
893
+static const VMStateDescription vmstate_efuse = {
894
+ .name = TYPE_XLNX_ZYNQMP_EFUSE,
895
+ .version_id = 1,
896
+ .minimum_version_id = 1,
897
+ .fields = (VMStateField[]) {
898
+ VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPEFuse, R_MAX),
899
+ VMSTATE_END_OF_LIST(),
900
+ }
901
+};
902
+
903
+static Property zynqmp_efuse_props[] = {
904
+ DEFINE_PROP_LINK("efuse",
905
+ XlnxZynqMPEFuse, efuse,
906
+ TYPE_XLNX_EFUSE, XlnxEFuse *),
907
+
908
+ DEFINE_PROP_END_OF_LIST(),
909
+};
910
+
911
+static void zynqmp_efuse_class_init(ObjectClass *klass, void *data)
912
+{
913
+ DeviceClass *dc = DEVICE_CLASS(klass);
914
+
915
+ dc->reset = zynqmp_efuse_reset;
916
+ dc->realize = zynqmp_efuse_realize;
917
+ dc->vmsd = &vmstate_efuse;
918
+ device_class_set_props(dc, zynqmp_efuse_props);
919
+}
920
+
921
+
922
+static const TypeInfo efuse_info = {
923
+ .name = TYPE_XLNX_ZYNQMP_EFUSE,
924
+ .parent = TYPE_SYS_BUS_DEVICE,
925
+ .instance_size = sizeof(XlnxZynqMPEFuse),
926
+ .class_init = zynqmp_efuse_class_init,
927
+ .instance_init = zynqmp_efuse_init,
928
+};
929
+
930
+static void efuse_register_types(void)
931
+{
932
+ type_register_static(&efuse_info);
933
+}
934
+
935
+type_init(efuse_register_types)
936
diff --git a/hw/nvram/Kconfig b/hw/nvram/Kconfig
937
index XXXXXXX..XXXXXXX 100644
938
--- a/hw/nvram/Kconfig
939
+++ b/hw/nvram/Kconfig
940
@@ -XXX,XX +XXX,XX @@ config XLNX_EFUSE
941
config XLNX_EFUSE_VERSAL
942
bool
943
select XLNX_EFUSE
944
+
945
+config XLNX_EFUSE_ZYNQMP
946
+ bool
947
+ select XLNX_EFUSE
948
diff --git a/hw/nvram/meson.build b/hw/nvram/meson.build
949
index XXXXXXX..XXXXXXX 100644
950
--- a/hw/nvram/meson.build
951
+++ b/hw/nvram/meson.build
952
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE', if_true: files('xlnx-efuse.c'))
953
softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE_VERSAL', if_true: files(
954
'xlnx-versal-efuse-cache.c',
955
'xlnx-versal-efuse-ctrl.c'))
956
+softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE_ZYNQMP', if_true: files(
957
+ 'xlnx-zynqmp-efuse.c'))
958
959
specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_nvram.c'))
960
--
65
--
961
2.20.1
66
2.34.1
962
67
963
68
diff view generated by jsdifflib
1
From: Tong Ho <tong.ho@xilinx.com>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
Connect the support for Versal Battery-Backed RAM (BBRAM)
3
* Add Addr and size definition for all i.MX7 devices in i.MX7 header file.
4
* Use those newly defined named constants whenever possible.
5
* Standardize the way we init a familly of unimplemented devices
6
- SAI
7
- PWM
8
- CAN
9
* Add/rework few comments
4
10
5
The command argument:
11
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
6
-drive if=pflash,index=0,...
12
Message-id: 59e195d33e4d486a8d131392acd46633c8c10ed7.1692964892.git.jcd@tribudubois.net
7
Can be used to optionally connect the bbram to a backend
8
storage, such that field-programmed values in one
9
invocation can be made available to next invocation.
10
11
The backend storage must be a seekable binary file, and
12
its size must be 36 bytes or larger. A file with all
13
binary 0's is a 'blank'.
14
15
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
16
Message-id: 20210917052400.1249094-6-tong.ho@xilinx.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
15
---
20
include/hw/arm/xlnx-versal.h | 5 +++++
16
include/hw/arm/fsl-imx7.h | 330 ++++++++++++++++++++++++++++----------
21
hw/arm/xlnx-versal-virt.c | 36 ++++++++++++++++++++++++++++++++++++
17
hw/arm/fsl-imx7.c | 130 ++++++++++-----
22
hw/arm/xlnx-versal.c | 18 ++++++++++++++++++
18
2 files changed, 335 insertions(+), 125 deletions(-)
23
hw/arm/Kconfig | 1 +
24
4 files changed, 60 insertions(+)
25
19
26
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
20
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
27
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/arm/xlnx-versal.h
22
--- a/include/hw/arm/fsl-imx7.h
29
+++ b/include/hw/arm/xlnx-versal.h
23
+++ b/include/hw/arm/fsl-imx7.h
30
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
25
#include "hw/misc/imx7_ccm.h"
26
#include "hw/misc/imx7_snvs.h"
27
#include "hw/misc/imx7_gpr.h"
28
-#include "hw/misc/imx6_src.h"
29
#include "hw/watchdog/wdt_imx2.h"
30
#include "hw/gpio/imx_gpio.h"
31
#include "hw/char/imx_serial.h"
32
@@ -XXX,XX +XXX,XX @@
33
#include "hw/usb/chipidea.h"
34
#include "cpu.h"
31
#include "qom/object.h"
35
#include "qom/object.h"
32
#include "hw/usb/xlnx-usb-subsystem.h"
36
+#include "qemu/units.h"
33
#include "hw/misc/xlnx-versal-xramc.h"
37
34
+#include "hw/nvram/xlnx-bbram.h"
38
#define TYPE_FSL_IMX7 "fsl-imx7"
35
39
OBJECT_DECLARE_SIMPLE_TYPE(FslIMX7State, FSL_IMX7)
36
#define TYPE_XLNX_VERSAL "xlnx-versal"
40
@@ -XXX,XX +XXX,XX @@ enum FslIMX7Configuration {
37
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
41
FSL_IMX7_NUM_ECSPIS = 4,
38
@@ -XXX,XX +XXX,XX @@ struct Versal {
42
FSL_IMX7_NUM_USBS = 3,
39
} iou;
43
FSL_IMX7_NUM_ADCS = 2,
40
44
+ FSL_IMX7_NUM_SAIS = 3,
41
XlnxZynqMPRTC rtc;
45
+ FSL_IMX7_NUM_CANS = 2,
42
+ XlnxBBRam bbram;
46
+ FSL_IMX7_NUM_PWMS = 4,
43
} pmc;
47
};
44
48
45
struct {
49
struct FslIMX7State {
46
@@ -XXX,XX +XXX,XX @@ struct Versal {
50
@@ -XXX,XX +XXX,XX @@ struct FslIMX7State {
47
#define VERSAL_GEM1_WAKE_IRQ_0 59
51
48
#define VERSAL_ADMA_IRQ_0 60
52
enum FslIMX7MemoryMap {
49
#define VERSAL_XRAM_IRQ_0 79
53
FSL_IMX7_MMDC_ADDR = 0x80000000,
50
+#define VERSAL_BBRAM_APB_IRQ_0 121
54
- FSL_IMX7_MMDC_SIZE = 2 * 1024 * 1024 * 1024UL,
51
#define VERSAL_RTC_APB_ERR_IRQ 121
55
+ FSL_IMX7_MMDC_SIZE = (2 * GiB),
52
#define VERSAL_SD0_IRQ_0 126
56
53
#define VERSAL_RTC_ALARM_IRQ 142
57
- FSL_IMX7_GPIO1_ADDR = 0x30200000,
54
@@ -XXX,XX +XXX,XX @@ struct Versal {
58
- FSL_IMX7_GPIO2_ADDR = 0x30210000,
55
59
- FSL_IMX7_GPIO3_ADDR = 0x30220000,
56
#define MM_PMC_SD0 0xf1040000U
60
- FSL_IMX7_GPIO4_ADDR = 0x30230000,
57
#define MM_PMC_SD0_SIZE 0x10000
61
- FSL_IMX7_GPIO5_ADDR = 0x30240000,
58
+#define MM_PMC_BBRAM_CTRL 0xf11f0000
62
- FSL_IMX7_GPIO6_ADDR = 0x30250000,
59
+#define MM_PMC_BBRAM_CTRL_SIZE 0x00050
63
- FSL_IMX7_GPIO7_ADDR = 0x30260000,
60
#define MM_PMC_CRP 0xf1260000U
64
+ FSL_IMX7_QSPI1_MEM_ADDR = 0x60000000,
61
#define MM_PMC_CRP_SIZE 0x10000
65
+ FSL_IMX7_QSPI1_MEM_SIZE = (256 * MiB),
62
#define MM_PMC_RTC 0xf12a0000
66
63
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
67
- FSL_IMX7_IOMUXC_LPSR_GPR_ADDR = 0x30270000,
68
+ FSL_IMX7_PCIE1_MEM_ADDR = 0x40000000,
69
+ FSL_IMX7_PCIE1_MEM_SIZE = (256 * MiB),
70
71
- FSL_IMX7_WDOG1_ADDR = 0x30280000,
72
- FSL_IMX7_WDOG2_ADDR = 0x30290000,
73
- FSL_IMX7_WDOG3_ADDR = 0x302A0000,
74
- FSL_IMX7_WDOG4_ADDR = 0x302B0000,
75
+ FSL_IMX7_QSPI1_RX_BUF_ADDR = 0x34000000,
76
+ FSL_IMX7_QSPI1_RX_BUF_SIZE = (32 * MiB),
77
78
- FSL_IMX7_IOMUXC_LPSR_ADDR = 0x302C0000,
79
+ /* PCIe Peripherals */
80
+ FSL_IMX7_PCIE_REG_ADDR = 0x33800000,
81
82
- FSL_IMX7_GPT1_ADDR = 0x302D0000,
83
- FSL_IMX7_GPT2_ADDR = 0x302E0000,
84
- FSL_IMX7_GPT3_ADDR = 0x302F0000,
85
- FSL_IMX7_GPT4_ADDR = 0x30300000,
86
+ /* MMAP Peripherals */
87
+ FSL_IMX7_DMA_APBH_ADDR = 0x33000000,
88
+ FSL_IMX7_DMA_APBH_SIZE = 0x8000,
89
90
- FSL_IMX7_IOMUXC_ADDR = 0x30330000,
91
- FSL_IMX7_IOMUXC_GPR_ADDR = 0x30340000,
92
- FSL_IMX7_IOMUXCn_SIZE = 0x1000,
93
+ /* GPV configuration */
94
+ FSL_IMX7_GPV6_ADDR = 0x32600000,
95
+ FSL_IMX7_GPV5_ADDR = 0x32500000,
96
+ FSL_IMX7_GPV4_ADDR = 0x32400000,
97
+ FSL_IMX7_GPV3_ADDR = 0x32300000,
98
+ FSL_IMX7_GPV2_ADDR = 0x32200000,
99
+ FSL_IMX7_GPV1_ADDR = 0x32100000,
100
+ FSL_IMX7_GPV0_ADDR = 0x32000000,
101
+ FSL_IMX7_GPVn_SIZE = (1 * MiB),
102
103
- FSL_IMX7_OCOTP_ADDR = 0x30350000,
104
- FSL_IMX7_OCOTP_SIZE = 0x10000,
105
+ /* Arm Peripherals */
106
+ FSL_IMX7_A7MPCORE_ADDR = 0x31000000,
107
108
- FSL_IMX7_ANALOG_ADDR = 0x30360000,
109
- FSL_IMX7_SNVS_ADDR = 0x30370000,
110
- FSL_IMX7_CCM_ADDR = 0x30380000,
111
+ /* AIPS-3 Begin */
112
113
- FSL_IMX7_SRC_ADDR = 0x30390000,
114
- FSL_IMX7_SRC_SIZE = 0x1000,
115
+ FSL_IMX7_ENET2_ADDR = 0x30BF0000,
116
+ FSL_IMX7_ENET1_ADDR = 0x30BE0000,
117
118
- FSL_IMX7_ADC1_ADDR = 0x30610000,
119
- FSL_IMX7_ADC2_ADDR = 0x30620000,
120
- FSL_IMX7_ADCn_SIZE = 0x1000,
121
+ FSL_IMX7_SDMA_ADDR = 0x30BD0000,
122
+ FSL_IMX7_SDMA_SIZE = (4 * KiB),
123
124
- FSL_IMX7_PWM1_ADDR = 0x30660000,
125
- FSL_IMX7_PWM2_ADDR = 0x30670000,
126
- FSL_IMX7_PWM3_ADDR = 0x30680000,
127
- FSL_IMX7_PWM4_ADDR = 0x30690000,
128
- FSL_IMX7_PWMn_SIZE = 0x10000,
129
+ FSL_IMX7_EIM_ADDR = 0x30BC0000,
130
+ FSL_IMX7_EIM_SIZE = (4 * KiB),
131
132
- FSL_IMX7_PCIE_PHY_ADDR = 0x306D0000,
133
- FSL_IMX7_PCIE_PHY_SIZE = 0x10000,
134
+ FSL_IMX7_QSPI_ADDR = 0x30BB0000,
135
+ FSL_IMX7_QSPI_SIZE = 0x8000,
136
137
- FSL_IMX7_GPC_ADDR = 0x303A0000,
138
+ FSL_IMX7_SIM2_ADDR = 0x30BA0000,
139
+ FSL_IMX7_SIM1_ADDR = 0x30B90000,
140
+ FSL_IMX7_SIMn_SIZE = (4 * KiB),
141
+
142
+ FSL_IMX7_USDHC3_ADDR = 0x30B60000,
143
+ FSL_IMX7_USDHC2_ADDR = 0x30B50000,
144
+ FSL_IMX7_USDHC1_ADDR = 0x30B40000,
145
+
146
+ FSL_IMX7_USB3_ADDR = 0x30B30000,
147
+ FSL_IMX7_USBMISC3_ADDR = 0x30B30200,
148
+ FSL_IMX7_USB2_ADDR = 0x30B20000,
149
+ FSL_IMX7_USBMISC2_ADDR = 0x30B20200,
150
+ FSL_IMX7_USB1_ADDR = 0x30B10000,
151
+ FSL_IMX7_USBMISC1_ADDR = 0x30B10200,
152
+ FSL_IMX7_USBMISCn_SIZE = 0x200,
153
+
154
+ FSL_IMX7_USB_PL301_ADDR = 0x30AD0000,
155
+ FSL_IMX7_USB_PL301_SIZE = (64 * KiB),
156
+
157
+ FSL_IMX7_SEMAPHORE_HS_ADDR = 0x30AC0000,
158
+ FSL_IMX7_SEMAPHORE_HS_SIZE = (64 * KiB),
159
+
160
+ FSL_IMX7_MUB_ADDR = 0x30AB0000,
161
+ FSL_IMX7_MUA_ADDR = 0x30AA0000,
162
+ FSL_IMX7_MUn_SIZE = (KiB),
163
+
164
+ FSL_IMX7_UART7_ADDR = 0x30A90000,
165
+ FSL_IMX7_UART6_ADDR = 0x30A80000,
166
+ FSL_IMX7_UART5_ADDR = 0x30A70000,
167
+ FSL_IMX7_UART4_ADDR = 0x30A60000,
168
+
169
+ FSL_IMX7_I2C4_ADDR = 0x30A50000,
170
+ FSL_IMX7_I2C3_ADDR = 0x30A40000,
171
+ FSL_IMX7_I2C2_ADDR = 0x30A30000,
172
+ FSL_IMX7_I2C1_ADDR = 0x30A20000,
173
+
174
+ FSL_IMX7_CAN2_ADDR = 0x30A10000,
175
+ FSL_IMX7_CAN1_ADDR = 0x30A00000,
176
+ FSL_IMX7_CANn_SIZE = (4 * KiB),
177
+
178
+ FSL_IMX7_AIPS3_CONF_ADDR = 0x309F0000,
179
+ FSL_IMX7_AIPS3_CONF_SIZE = (64 * KiB),
180
181
FSL_IMX7_CAAM_ADDR = 0x30900000,
182
- FSL_IMX7_CAAM_SIZE = 0x40000,
183
+ FSL_IMX7_CAAM_SIZE = (256 * KiB),
184
185
- FSL_IMX7_CAN1_ADDR = 0x30A00000,
186
- FSL_IMX7_CAN2_ADDR = 0x30A10000,
187
- FSL_IMX7_CANn_SIZE = 0x10000,
188
+ FSL_IMX7_SPBA_ADDR = 0x308F0000,
189
+ FSL_IMX7_SPBA_SIZE = (4 * KiB),
190
191
- FSL_IMX7_I2C1_ADDR = 0x30A20000,
192
- FSL_IMX7_I2C2_ADDR = 0x30A30000,
193
- FSL_IMX7_I2C3_ADDR = 0x30A40000,
194
- FSL_IMX7_I2C4_ADDR = 0x30A50000,
195
+ FSL_IMX7_SAI3_ADDR = 0x308C0000,
196
+ FSL_IMX7_SAI2_ADDR = 0x308B0000,
197
+ FSL_IMX7_SAI1_ADDR = 0x308A0000,
198
+ FSL_IMX7_SAIn_SIZE = (4 * KiB),
199
200
- FSL_IMX7_ECSPI1_ADDR = 0x30820000,
201
- FSL_IMX7_ECSPI2_ADDR = 0x30830000,
202
- FSL_IMX7_ECSPI3_ADDR = 0x30840000,
203
- FSL_IMX7_ECSPI4_ADDR = 0x30630000,
204
-
205
- FSL_IMX7_LCDIF_ADDR = 0x30730000,
206
- FSL_IMX7_LCDIF_SIZE = 0x1000,
207
-
208
- FSL_IMX7_UART1_ADDR = 0x30860000,
209
+ FSL_IMX7_UART3_ADDR = 0x30880000,
210
/*
211
* Some versions of the reference manual claim that UART2 is @
212
* 0x30870000, but experiments with HW + DT files in upstream
213
@@ -XXX,XX +XXX,XX @@ enum FslIMX7MemoryMap {
214
* actually located @ 0x30890000
215
*/
216
FSL_IMX7_UART2_ADDR = 0x30890000,
217
- FSL_IMX7_UART3_ADDR = 0x30880000,
218
- FSL_IMX7_UART4_ADDR = 0x30A60000,
219
- FSL_IMX7_UART5_ADDR = 0x30A70000,
220
- FSL_IMX7_UART6_ADDR = 0x30A80000,
221
- FSL_IMX7_UART7_ADDR = 0x30A90000,
222
+ FSL_IMX7_UART1_ADDR = 0x30860000,
223
224
- FSL_IMX7_SAI1_ADDR = 0x308A0000,
225
- FSL_IMX7_SAI2_ADDR = 0x308B0000,
226
- FSL_IMX7_SAI3_ADDR = 0x308C0000,
227
- FSL_IMX7_SAIn_SIZE = 0x10000,
228
+ FSL_IMX7_ECSPI3_ADDR = 0x30840000,
229
+ FSL_IMX7_ECSPI2_ADDR = 0x30830000,
230
+ FSL_IMX7_ECSPI1_ADDR = 0x30820000,
231
+ FSL_IMX7_ECSPIn_SIZE = (4 * KiB),
232
233
- FSL_IMX7_ENET1_ADDR = 0x30BE0000,
234
- FSL_IMX7_ENET2_ADDR = 0x30BF0000,
235
+ /* AIPS-3 End */
236
237
- FSL_IMX7_USB1_ADDR = 0x30B10000,
238
- FSL_IMX7_USBMISC1_ADDR = 0x30B10200,
239
- FSL_IMX7_USB2_ADDR = 0x30B20000,
240
- FSL_IMX7_USBMISC2_ADDR = 0x30B20200,
241
- FSL_IMX7_USB3_ADDR = 0x30B30000,
242
- FSL_IMX7_USBMISC3_ADDR = 0x30B30200,
243
- FSL_IMX7_USBMISCn_SIZE = 0x200,
244
+ /* AIPS-2 Begin */
245
246
- FSL_IMX7_USDHC1_ADDR = 0x30B40000,
247
- FSL_IMX7_USDHC2_ADDR = 0x30B50000,
248
- FSL_IMX7_USDHC3_ADDR = 0x30B60000,
249
+ FSL_IMX7_AXI_DEBUG_MON_ADDR = 0x307E0000,
250
+ FSL_IMX7_AXI_DEBUG_MON_SIZE = (64 * KiB),
251
252
- FSL_IMX7_SDMA_ADDR = 0x30BD0000,
253
- FSL_IMX7_SDMA_SIZE = 0x1000,
254
+ FSL_IMX7_PERFMON2_ADDR = 0x307D0000,
255
+ FSL_IMX7_PERFMON1_ADDR = 0x307C0000,
256
+ FSL_IMX7_PERFMONn_SIZE = (64 * KiB),
257
+
258
+ FSL_IMX7_DDRC_ADDR = 0x307A0000,
259
+ FSL_IMX7_DDRC_SIZE = (4 * KiB),
260
+
261
+ FSL_IMX7_DDRC_PHY_ADDR = 0x30790000,
262
+ FSL_IMX7_DDRC_PHY_SIZE = (4 * KiB),
263
+
264
+ FSL_IMX7_TZASC_ADDR = 0x30780000,
265
+ FSL_IMX7_TZASC_SIZE = (64 * KiB),
266
+
267
+ FSL_IMX7_MIPI_DSI_ADDR = 0x30760000,
268
+ FSL_IMX7_MIPI_DSI_SIZE = (4 * KiB),
269
+
270
+ FSL_IMX7_MIPI_CSI_ADDR = 0x30750000,
271
+ FSL_IMX7_MIPI_CSI_SIZE = 0x4000,
272
+
273
+ FSL_IMX7_LCDIF_ADDR = 0x30730000,
274
+ FSL_IMX7_LCDIF_SIZE = 0x8000,
275
+
276
+ FSL_IMX7_CSI_ADDR = 0x30710000,
277
+ FSL_IMX7_CSI_SIZE = (4 * KiB),
278
+
279
+ FSL_IMX7_PXP_ADDR = 0x30700000,
280
+ FSL_IMX7_PXP_SIZE = 0x4000,
281
+
282
+ FSL_IMX7_EPDC_ADDR = 0x306F0000,
283
+ FSL_IMX7_EPDC_SIZE = (4 * KiB),
284
+
285
+ FSL_IMX7_PCIE_PHY_ADDR = 0x306D0000,
286
+ FSL_IMX7_PCIE_PHY_SIZE = (4 * KiB),
287
+
288
+ FSL_IMX7_SYSCNT_CTRL_ADDR = 0x306C0000,
289
+ FSL_IMX7_SYSCNT_CMP_ADDR = 0x306B0000,
290
+ FSL_IMX7_SYSCNT_RD_ADDR = 0x306A0000,
291
+
292
+ FSL_IMX7_PWM4_ADDR = 0x30690000,
293
+ FSL_IMX7_PWM3_ADDR = 0x30680000,
294
+ FSL_IMX7_PWM2_ADDR = 0x30670000,
295
+ FSL_IMX7_PWM1_ADDR = 0x30660000,
296
+ FSL_IMX7_PWMn_SIZE = (4 * KiB),
297
+
298
+ FSL_IMX7_FlEXTIMER2_ADDR = 0x30650000,
299
+ FSL_IMX7_FlEXTIMER1_ADDR = 0x30640000,
300
+ FSL_IMX7_FLEXTIMERn_SIZE = (4 * KiB),
301
+
302
+ FSL_IMX7_ECSPI4_ADDR = 0x30630000,
303
+
304
+ FSL_IMX7_ADC2_ADDR = 0x30620000,
305
+ FSL_IMX7_ADC1_ADDR = 0x30610000,
306
+ FSL_IMX7_ADCn_SIZE = (4 * KiB),
307
+
308
+ FSL_IMX7_AIPS2_CONF_ADDR = 0x305F0000,
309
+ FSL_IMX7_AIPS2_CONF_SIZE = (64 * KiB),
310
+
311
+ /* AIPS-2 End */
312
+
313
+ /* AIPS-1 Begin */
314
+
315
+ FSL_IMX7_CSU_ADDR = 0x303E0000,
316
+ FSL_IMX7_CSU_SIZE = (64 * KiB),
317
+
318
+ FSL_IMX7_RDC_ADDR = 0x303D0000,
319
+ FSL_IMX7_RDC_SIZE = (4 * KiB),
320
+
321
+ FSL_IMX7_SEMAPHORE2_ADDR = 0x303C0000,
322
+ FSL_IMX7_SEMAPHORE1_ADDR = 0x303B0000,
323
+ FSL_IMX7_SEMAPHOREn_SIZE = (4 * KiB),
324
+
325
+ FSL_IMX7_GPC_ADDR = 0x303A0000,
326
+
327
+ FSL_IMX7_SRC_ADDR = 0x30390000,
328
+ FSL_IMX7_SRC_SIZE = (4 * KiB),
329
+
330
+ FSL_IMX7_CCM_ADDR = 0x30380000,
331
+
332
+ FSL_IMX7_SNVS_HP_ADDR = 0x30370000,
333
+
334
+ FSL_IMX7_ANALOG_ADDR = 0x30360000,
335
+
336
+ FSL_IMX7_OCOTP_ADDR = 0x30350000,
337
+ FSL_IMX7_OCOTP_SIZE = 0x10000,
338
+
339
+ FSL_IMX7_IOMUXC_GPR_ADDR = 0x30340000,
340
+ FSL_IMX7_IOMUXC_GPR_SIZE = (4 * KiB),
341
+
342
+ FSL_IMX7_IOMUXC_ADDR = 0x30330000,
343
+ FSL_IMX7_IOMUXC_SIZE = (4 * KiB),
344
+
345
+ FSL_IMX7_KPP_ADDR = 0x30320000,
346
+ FSL_IMX7_KPP_SIZE = (4 * KiB),
347
+
348
+ FSL_IMX7_ROMCP_ADDR = 0x30310000,
349
+ FSL_IMX7_ROMCP_SIZE = (4 * KiB),
350
+
351
+ FSL_IMX7_GPT4_ADDR = 0x30300000,
352
+ FSL_IMX7_GPT3_ADDR = 0x302F0000,
353
+ FSL_IMX7_GPT2_ADDR = 0x302E0000,
354
+ FSL_IMX7_GPT1_ADDR = 0x302D0000,
355
+
356
+ FSL_IMX7_IOMUXC_LPSR_ADDR = 0x302C0000,
357
+ FSL_IMX7_IOMUXC_LPSR_SIZE = (4 * KiB),
358
+
359
+ FSL_IMX7_WDOG4_ADDR = 0x302B0000,
360
+ FSL_IMX7_WDOG3_ADDR = 0x302A0000,
361
+ FSL_IMX7_WDOG2_ADDR = 0x30290000,
362
+ FSL_IMX7_WDOG1_ADDR = 0x30280000,
363
+
364
+ FSL_IMX7_IOMUXC_LPSR_GPR_ADDR = 0x30270000,
365
+
366
+ FSL_IMX7_GPIO7_ADDR = 0x30260000,
367
+ FSL_IMX7_GPIO6_ADDR = 0x30250000,
368
+ FSL_IMX7_GPIO5_ADDR = 0x30240000,
369
+ FSL_IMX7_GPIO4_ADDR = 0x30230000,
370
+ FSL_IMX7_GPIO3_ADDR = 0x30220000,
371
+ FSL_IMX7_GPIO2_ADDR = 0x30210000,
372
+ FSL_IMX7_GPIO1_ADDR = 0x30200000,
373
+
374
+ FSL_IMX7_AIPS1_CONF_ADDR = 0x301F0000,
375
+ FSL_IMX7_AIPS1_CONF_SIZE = (64 * KiB),
376
377
- FSL_IMX7_A7MPCORE_ADDR = 0x31000000,
378
FSL_IMX7_A7MPCORE_DAP_ADDR = 0x30000000,
379
+ FSL_IMX7_A7MPCORE_DAP_SIZE = (1 * MiB),
380
381
- FSL_IMX7_PCIE_REG_ADDR = 0x33800000,
382
- FSL_IMX7_PCIE_REG_SIZE = 16 * 1024,
383
+ /* AIPS-1 End */
384
385
- FSL_IMX7_GPR_ADDR = 0x30340000,
386
+ FSL_IMX7_EIM_CS0_ADDR = 0x28000000,
387
+ FSL_IMX7_EIM_CS0_SIZE = (128 * MiB),
388
389
- FSL_IMX7_DMA_APBH_ADDR = 0x33000000,
390
- FSL_IMX7_DMA_APBH_SIZE = 0x2000,
391
+ FSL_IMX7_OCRAM_PXP_ADDR = 0x00940000,
392
+ FSL_IMX7_OCRAM_PXP_SIZE = (32 * KiB),
393
+
394
+ FSL_IMX7_OCRAM_EPDC_ADDR = 0x00920000,
395
+ FSL_IMX7_OCRAM_EPDC_SIZE = (128 * KiB),
396
+
397
+ FSL_IMX7_OCRAM_MEM_ADDR = 0x00900000,
398
+ FSL_IMX7_OCRAM_MEM_SIZE = (128 * KiB),
399
+
400
+ FSL_IMX7_TCMU_ADDR = 0x00800000,
401
+ FSL_IMX7_TCMU_SIZE = (32 * KiB),
402
+
403
+ FSL_IMX7_TCML_ADDR = 0x007F8000,
404
+ FSL_IMX7_TCML_SIZE = (32 * KiB),
405
+
406
+ FSL_IMX7_OCRAM_S_ADDR = 0x00180000,
407
+ FSL_IMX7_OCRAM_S_SIZE = (32 * KiB),
408
+
409
+ FSL_IMX7_CAAM_MEM_ADDR = 0x00100000,
410
+ FSL_IMX7_CAAM_MEM_SIZE = (32 * KiB),
411
+
412
+ FSL_IMX7_ROM_ADDR = 0x00000000,
413
+ FSL_IMX7_ROM_SIZE = (96 * KiB),
414
};
415
416
enum FslIMX7IRQs {
417
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
64
index XXXXXXX..XXXXXXX 100644
418
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/arm/xlnx-versal-virt.c
419
--- a/hw/arm/fsl-imx7.c
66
+++ b/hw/arm/xlnx-versal-virt.c
420
+++ b/hw/arm/fsl-imx7.c
67
@@ -XXX,XX +XXX,XX @@ static void fdt_add_rtc_node(VersalVirt *s)
421
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
68
g_free(name);
422
char name[NAME_SIZE];
423
int i;
424
425
+ /*
426
+ * CPUs
427
+ */
428
for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX7_NUM_CPUS); i++) {
429
snprintf(name, NAME_SIZE, "cpu%d", i);
430
object_initialize_child(obj, name, &s->cpu[i],
431
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
432
TYPE_A15MPCORE_PRIV);
433
434
/*
435
- * GPIOs 1 to 7
436
+ * GPIOs
437
*/
438
for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
439
snprintf(name, NAME_SIZE, "gpio%d", i);
440
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
441
}
442
443
/*
444
- * GPT1, 2, 3, 4
445
+ * GPTs
446
*/
447
for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
448
snprintf(name, NAME_SIZE, "gpt%d", i);
449
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
450
*/
451
object_initialize_child(obj, "gpcv2", &s->gpcv2, TYPE_IMX_GPCV2);
452
453
+ /*
454
+ * ECSPIs
455
+ */
456
for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
457
snprintf(name, NAME_SIZE, "spi%d", i + 1);
458
object_initialize_child(obj, name, &s->spi[i], TYPE_IMX_SPI);
459
}
460
461
-
462
+ /*
463
+ * I2Cs
464
+ */
465
for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
466
snprintf(name, NAME_SIZE, "i2c%d", i + 1);
467
object_initialize_child(obj, name, &s->i2c[i], TYPE_IMX_I2C);
468
}
469
470
/*
471
- * UART
472
+ * UARTs
473
*/
474
for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
475
snprintf(name, NAME_SIZE, "uart%d", i);
476
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
477
}
478
479
/*
480
- * Ethernet
481
+ * Ethernets
482
*/
483
for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
484
snprintf(name, NAME_SIZE, "eth%d", i);
485
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
486
}
487
488
/*
489
- * SDHCI
490
+ * SDHCIs
491
*/
492
for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
493
snprintf(name, NAME_SIZE, "usdhc%d", i);
494
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
495
object_initialize_child(obj, "snvs", &s->snvs, TYPE_IMX7_SNVS);
496
497
/*
498
- * Watchdog
499
+ * Watchdogs
500
*/
501
for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
502
snprintf(name, NAME_SIZE, "wdt%d", i);
503
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
504
*/
505
object_initialize_child(obj, "gpr", &s->gpr, TYPE_IMX7_GPR);
506
507
+ /*
508
+ * PCIE
509
+ */
510
object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
511
512
+ /*
513
+ * USBs
514
+ */
515
for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
516
snprintf(name, NAME_SIZE, "usb%d", i);
517
object_initialize_child(obj, name, &s->usb[i], TYPE_CHIPIDEA);
518
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
519
return;
520
}
521
522
+ /*
523
+ * CPUs
524
+ */
525
for (i = 0; i < smp_cpus; i++) {
526
o = OBJECT(&s->cpu[i]);
527
528
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
529
* A7MPCORE DAP
530
*/
531
create_unimplemented_device("a7mpcore-dap", FSL_IMX7_A7MPCORE_DAP_ADDR,
532
- 0x100000);
533
+ FSL_IMX7_A7MPCORE_DAP_SIZE);
534
535
/*
536
- * GPT1, 2, 3, 4
537
+ * GPTs
538
*/
539
for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
540
static const hwaddr FSL_IMX7_GPTn_ADDR[FSL_IMX7_NUM_GPTS] = {
541
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
542
FSL_IMX7_GPTn_IRQ[i]));
543
}
544
545
+ /*
546
+ * GPIOs
547
+ */
548
for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
549
static const hwaddr FSL_IMX7_GPIOn_ADDR[FSL_IMX7_NUM_GPIOS] = {
550
FSL_IMX7_GPIO1_ADDR,
551
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
552
/*
553
* IOMUXC and IOMUXC_LPSR
554
*/
555
- for (i = 0; i < FSL_IMX7_NUM_IOMUXCS; i++) {
556
- static const hwaddr FSL_IMX7_IOMUXCn_ADDR[FSL_IMX7_NUM_IOMUXCS] = {
557
- FSL_IMX7_IOMUXC_ADDR,
558
- FSL_IMX7_IOMUXC_LPSR_ADDR,
559
- };
560
-
561
- snprintf(name, NAME_SIZE, "iomuxc%d", i);
562
- create_unimplemented_device(name, FSL_IMX7_IOMUXCn_ADDR[i],
563
- FSL_IMX7_IOMUXCn_SIZE);
564
- }
565
+ create_unimplemented_device("iomuxc", FSL_IMX7_IOMUXC_ADDR,
566
+ FSL_IMX7_IOMUXC_SIZE);
567
+ create_unimplemented_device("iomuxc_lspr", FSL_IMX7_IOMUXC_LPSR_ADDR,
568
+ FSL_IMX7_IOMUXC_LPSR_SIZE);
569
570
/*
571
* CCM
572
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
573
sysbus_realize(SYS_BUS_DEVICE(&s->gpcv2), &error_abort);
574
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX7_GPC_ADDR);
575
576
- /* Initialize all ECSPI */
577
+ /*
578
+ * ECSPIs
579
+ */
580
for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
581
static const hwaddr FSL_IMX7_SPIn_ADDR[FSL_IMX7_NUM_ECSPIS] = {
582
FSL_IMX7_ECSPI1_ADDR,
583
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
584
FSL_IMX7_SPIn_IRQ[i]));
585
}
586
587
+ /*
588
+ * I2Cs
589
+ */
590
for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
591
static const hwaddr FSL_IMX7_I2Cn_ADDR[FSL_IMX7_NUM_I2CS] = {
592
FSL_IMX7_I2C1_ADDR,
593
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
594
}
595
596
/*
597
- * UART
598
+ * UARTs
599
*/
600
for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
601
static const hwaddr FSL_IMX7_UARTn_ADDR[FSL_IMX7_NUM_UARTS] = {
602
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
603
}
604
605
/*
606
- * Ethernet
607
+ * Ethernets
608
*
609
* We must use two loops since phy_connected affects the other interface
610
* and we have to set all properties before calling sysbus_realize().
611
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
612
}
613
614
/*
615
- * USDHC
616
+ * USDHCs
617
*/
618
for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
619
static const hwaddr FSL_IMX7_USDHCn_ADDR[FSL_IMX7_NUM_USDHCS] = {
620
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
621
* SNVS
622
*/
623
sysbus_realize(SYS_BUS_DEVICE(&s->snvs), &error_abort);
624
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX7_SNVS_ADDR);
625
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX7_SNVS_HP_ADDR);
626
627
/*
628
* SRC
629
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
630
create_unimplemented_device("src", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
631
632
/*
633
- * Watchdog
634
+ * Watchdogs
635
*/
636
for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
637
static const hwaddr FSL_IMX7_WDOGn_ADDR[FSL_IMX7_NUM_WDTS] = {
638
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
639
create_unimplemented_device("caam", FSL_IMX7_CAAM_ADDR, FSL_IMX7_CAAM_SIZE);
640
641
/*
642
- * PWM
643
+ * PWMs
644
*/
645
- create_unimplemented_device("pwm1", FSL_IMX7_PWM1_ADDR, FSL_IMX7_PWMn_SIZE);
646
- create_unimplemented_device("pwm2", FSL_IMX7_PWM2_ADDR, FSL_IMX7_PWMn_SIZE);
647
- create_unimplemented_device("pwm3", FSL_IMX7_PWM3_ADDR, FSL_IMX7_PWMn_SIZE);
648
- create_unimplemented_device("pwm4", FSL_IMX7_PWM4_ADDR, FSL_IMX7_PWMn_SIZE);
649
+ for (i = 0; i < FSL_IMX7_NUM_PWMS; i++) {
650
+ static const hwaddr FSL_IMX7_PWMn_ADDR[FSL_IMX7_NUM_PWMS] = {
651
+ FSL_IMX7_PWM1_ADDR,
652
+ FSL_IMX7_PWM2_ADDR,
653
+ FSL_IMX7_PWM3_ADDR,
654
+ FSL_IMX7_PWM4_ADDR,
655
+ };
656
+
657
+ snprintf(name, NAME_SIZE, "pwm%d", i);
658
+ create_unimplemented_device(name, FSL_IMX7_PWMn_ADDR[i],
659
+ FSL_IMX7_PWMn_SIZE);
660
+ }
661
662
/*
663
- * CAN
664
+ * CANs
665
*/
666
- create_unimplemented_device("can1", FSL_IMX7_CAN1_ADDR, FSL_IMX7_CANn_SIZE);
667
- create_unimplemented_device("can2", FSL_IMX7_CAN2_ADDR, FSL_IMX7_CANn_SIZE);
668
+ for (i = 0; i < FSL_IMX7_NUM_CANS; i++) {
669
+ static const hwaddr FSL_IMX7_CANn_ADDR[FSL_IMX7_NUM_CANS] = {
670
+ FSL_IMX7_CAN1_ADDR,
671
+ FSL_IMX7_CAN2_ADDR,
672
+ };
673
+
674
+ snprintf(name, NAME_SIZE, "can%d", i);
675
+ create_unimplemented_device(name, FSL_IMX7_CANn_ADDR[i],
676
+ FSL_IMX7_CANn_SIZE);
677
+ }
678
679
/*
680
- * SAI (Audio SSI (Synchronous Serial Interface))
681
+ * SAIs (Audio SSI (Synchronous Serial Interface))
682
*/
683
- create_unimplemented_device("sai1", FSL_IMX7_SAI1_ADDR, FSL_IMX7_SAIn_SIZE);
684
- create_unimplemented_device("sai2", FSL_IMX7_SAI2_ADDR, FSL_IMX7_SAIn_SIZE);
685
- create_unimplemented_device("sai2", FSL_IMX7_SAI3_ADDR, FSL_IMX7_SAIn_SIZE);
686
+ for (i = 0; i < FSL_IMX7_NUM_SAIS; i++) {
687
+ static const hwaddr FSL_IMX7_SAIn_ADDR[FSL_IMX7_NUM_SAIS] = {
688
+ FSL_IMX7_SAI1_ADDR,
689
+ FSL_IMX7_SAI2_ADDR,
690
+ FSL_IMX7_SAI3_ADDR,
691
+ };
692
+
693
+ snprintf(name, NAME_SIZE, "sai%d", i);
694
+ create_unimplemented_device(name, FSL_IMX7_SAIn_ADDR[i],
695
+ FSL_IMX7_SAIn_SIZE);
696
+ }
697
698
/*
699
* OCOTP
700
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
701
create_unimplemented_device("ocotp", FSL_IMX7_OCOTP_ADDR,
702
FSL_IMX7_OCOTP_SIZE);
703
704
+ /*
705
+ * GPR
706
+ */
707
sysbus_realize(SYS_BUS_DEVICE(&s->gpr), &error_abort);
708
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX7_GPR_ADDR);
709
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX7_IOMUXC_GPR_ADDR);
710
711
+ /*
712
+ * PCIE
713
+ */
714
sysbus_realize(SYS_BUS_DEVICE(&s->pcie), &error_abort);
715
sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX7_PCIE_REG_ADDR);
716
717
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
718
irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTD_IRQ);
719
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq);
720
721
-
722
+ /*
723
+ * USBs
724
+ */
725
for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
726
static const hwaddr FSL_IMX7_USBMISCn_ADDR[FSL_IMX7_NUM_USBS] = {
727
FSL_IMX7_USBMISC1_ADDR,
728
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
729
*/
730
create_unimplemented_device("pcie-phy", FSL_IMX7_PCIE_PHY_ADDR,
731
FSL_IMX7_PCIE_PHY_SIZE);
732
+
69
}
733
}
70
734
71
+static void fdt_add_bbram_node(VersalVirt *s)
735
static Property fsl_imx7_properties[] = {
72
+{
73
+ const char compat[] = TYPE_XLNX_BBRAM;
74
+ const char interrupt_names[] = "bbram-error";
75
+ char *name = g_strdup_printf("/bbram@%x", MM_PMC_BBRAM_CTRL);
76
+
77
+ qemu_fdt_add_subnode(s->fdt, name);
78
+
79
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
80
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_BBRAM_APB_IRQ_0,
81
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
82
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
83
+ interrupt_names, sizeof(interrupt_names));
84
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
85
+ 2, MM_PMC_BBRAM_CTRL,
86
+ 2, MM_PMC_BBRAM_CTRL_SIZE);
87
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
88
+ g_free(name);
89
+}
90
+
91
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
92
{
93
Error *err = NULL;
94
@@ -XXX,XX +XXX,XX @@ static void create_virtio_regions(VersalVirt *s)
95
}
96
}
97
98
+static void bbram_attach_drive(XlnxBBRam *dev)
99
+{
100
+ DriveInfo *dinfo;
101
+ BlockBackend *blk;
102
+
103
+ dinfo = drive_get_by_index(IF_PFLASH, 0);
104
+ blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
105
+ if (blk) {
106
+ qdev_prop_set_drive(DEVICE(dev), "drive", blk);
107
+ }
108
+}
109
+
110
static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
111
{
112
BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
113
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
114
fdt_add_usb_xhci_nodes(s);
115
fdt_add_sd_nodes(s);
116
fdt_add_rtc_node(s);
117
+ fdt_add_bbram_node(s);
118
fdt_add_cpu_nodes(s, psci_conduit);
119
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
120
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
121
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
122
memory_region_add_subregion_overlap(get_system_memory(),
123
0, &s->soc.fpd.apu.mr, 0);
124
125
+ /* Attach bbram backend, if given */
126
+ bbram_attach_drive(&s->soc.pmc.bbram);
127
+
128
/* Plugin SD cards. */
129
for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
130
sd_plugin_card(&s->soc.pmc.iou.sd[i], drive_get_next(IF_SD));
131
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/hw/arm/xlnx-versal.c
134
+++ b/hw/arm/xlnx-versal.c
135
@@ -XXX,XX +XXX,XX @@ static void versal_create_xrams(Versal *s, qemu_irq *pic)
136
}
137
}
138
139
+static void versal_create_bbram(Versal *s, qemu_irq *pic)
140
+{
141
+ SysBusDevice *sbd;
142
+
143
+ object_initialize_child_with_props(OBJECT(s), "bbram", &s->pmc.bbram,
144
+ sizeof(s->pmc.bbram), TYPE_XLNX_BBRAM,
145
+ &error_fatal,
146
+ "crc-zpads", "0",
147
+ NULL);
148
+ sbd = SYS_BUS_DEVICE(&s->pmc.bbram);
149
+
150
+ sysbus_realize(sbd, &error_fatal);
151
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_BBRAM_CTRL,
152
+ sysbus_mmio_get_region(sbd, 0));
153
+ sysbus_connect_irq(sbd, 0, pic[VERSAL_BBRAM_APB_IRQ_0]);
154
+}
155
+
156
/* This takes the board allocated linear DDR memory and creates aliases
157
* for each split DDR range/aperture on the Versal address map.
158
*/
159
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
160
versal_create_sds(s, pic);
161
versal_create_rtc(s, pic);
162
versal_create_xrams(s, pic);
163
+ versal_create_bbram(s, pic);
164
versal_map_ddr(s);
165
versal_unimp(s);
166
167
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
168
index XXXXXXX..XXXXXXX 100644
169
--- a/hw/arm/Kconfig
170
+++ b/hw/arm/Kconfig
171
@@ -XXX,XX +XXX,XX @@ config XLNX_VERSAL
172
select XLNX_ZDMA
173
select XLNX_ZYNQMP
174
select OR_IRQ
175
+ select XLNX_BBRAM
176
177
config NPCM7XX
178
bool
179
--
736
--
180
2.20.1
737
2.34.1
181
182
diff view generated by jsdifflib
1
From: Tong Ho <tong.ho@xilinx.com>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
This implements the Xilinx Versal eFuse, an one-time
3
* Add TZASC as unimplemented device.
4
field-programmable non-volatile storage device. There is
4
- Allow bare metal application to access this (unimplemented) device
5
only one such device in the Xilinx Versal product family.
5
* Add CSU as unimplemented device.
6
- Allow bare metal application to access this (unimplemented) device
7
* Add various memory segments
8
- OCRAM
9
- OCRAM EPDC
10
- OCRAM PXP
11
- OCRAM S
12
- ROM
13
- CAAM
6
14
7
This device has two separate mmio interfaces, a controller
15
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
8
and a flatten readback.
16
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
17
Message-id: f887a3483996ba06d40bd62ffdfb0ecf68621987.1692964892.git.jcd@tribudubois.net
10
The controller provides interfaces for field-programming,
11
configuration, control, and status.
12
13
The flatten readback is a cache to provide a byte-accessible
14
read-only interface to efficiently read efuse array.
15
16
Co-authored-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
17
Co-authored-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
18
19
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
20
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
21
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
22
Message-id: 20210917052400.1249094-3-tong.ho@xilinx.com
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
---
19
---
26
include/hw/nvram/xlnx-versal-efuse.h | 68 +++
20
include/hw/arm/fsl-imx7.h | 7 +++++
27
hw/nvram/xlnx-versal-efuse-cache.c | 114 ++++
21
hw/arm/fsl-imx7.c | 63 +++++++++++++++++++++++++++++++++++++++
28
hw/nvram/xlnx-versal-efuse-ctrl.c | 783 +++++++++++++++++++++++++++
22
2 files changed, 70 insertions(+)
29
hw/nvram/Kconfig | 4 +
30
hw/nvram/meson.build | 3 +
31
5 files changed, 972 insertions(+)
32
create mode 100644 include/hw/nvram/xlnx-versal-efuse.h
33
create mode 100644 hw/nvram/xlnx-versal-efuse-cache.c
34
create mode 100644 hw/nvram/xlnx-versal-efuse-ctrl.c
35
23
36
diff --git a/include/hw/nvram/xlnx-versal-efuse.h b/include/hw/nvram/xlnx-versal-efuse.h
24
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
37
new file mode 100644
25
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX
26
--- a/include/hw/arm/fsl-imx7.h
39
--- /dev/null
27
+++ b/include/hw/arm/fsl-imx7.h
40
+++ b/include/hw/nvram/xlnx-versal-efuse.h
28
@@ -XXX,XX +XXX,XX @@ struct FslIMX7State {
41
@@ -XXX,XX +XXX,XX @@
29
IMX7GPRState gpr;
42
+/*
30
ChipideaState usb[FSL_IMX7_NUM_USBS];
43
+ * Copyright (c) 2020 Xilinx Inc.
31
DesignwarePCIEHost pcie;
44
+ *
32
+ MemoryRegion rom;
45
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
33
+ MemoryRegion caam;
46
+ * of this software and associated documentation files (the "Software"), to deal
34
+ MemoryRegion ocram;
47
+ * in the Software without restriction, including without limitation the rights
35
+ MemoryRegion ocram_epdc;
48
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36
+ MemoryRegion ocram_pxp;
49
+ * copies of the Software, and to permit persons to whom the Software is
37
+ MemoryRegion ocram_s;
50
+ * furnished to do so, subject to the following conditions:
51
+ *
52
+ * The above copyright notice and this permission notice shall be included in
53
+ * all copies or substantial portions of the Software.
54
+ *
55
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
56
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
57
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
58
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
59
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
60
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
61
+ * THE SOFTWARE.
62
+ */
63
+#ifndef XLNX_VERSAL_EFUSE_H
64
+#define XLNX_VERSAL_EFUSE_H
65
+
38
+
66
+#include "hw/irq.h"
39
uint32_t phy_num[FSL_IMX7_NUM_ETHS];
67
+#include "hw/sysbus.h"
40
bool phy_connected[FSL_IMX7_NUM_ETHS];
68
+#include "hw/register.h"
41
};
69
+#include "hw/nvram/xlnx-efuse.h"
42
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
70
+
43
index XXXXXXX..XXXXXXX 100644
71
+#define XLNX_VERSAL_EFUSE_CTRL_R_MAX ((0x100 / 4) + 1)
44
--- a/hw/arm/fsl-imx7.c
72
+
45
+++ b/hw/arm/fsl-imx7.c
73
+#define TYPE_XLNX_VERSAL_EFUSE_CTRL "xlnx,versal-efuse"
46
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
74
+#define TYPE_XLNX_VERSAL_EFUSE_CACHE "xlnx,pmc-efuse-cache"
47
create_unimplemented_device("pcie-phy", FSL_IMX7_PCIE_PHY_ADDR,
75
+
48
FSL_IMX7_PCIE_PHY_SIZE);
76
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalEFuseCtrl, XLNX_VERSAL_EFUSE_CTRL);
49
77
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalEFuseCache, XLNX_VERSAL_EFUSE_CACHE);
50
+ /*
78
+
51
+ * CSU
79
+struct XlnxVersalEFuseCtrl {
52
+ */
80
+ SysBusDevice parent_obj;
53
+ create_unimplemented_device("csu", FSL_IMX7_CSU_ADDR,
81
+ qemu_irq irq_efuse_imr;
54
+ FSL_IMX7_CSU_SIZE);
82
+
83
+ XlnxEFuse *efuse;
84
+
85
+ void *extra_pg0_lock_spec; /* Opaque property */
86
+ uint32_t extra_pg0_lock_n16;
87
+
88
+ uint32_t regs[XLNX_VERSAL_EFUSE_CTRL_R_MAX];
89
+ RegisterInfo regs_info[XLNX_VERSAL_EFUSE_CTRL_R_MAX];
90
+};
91
+
92
+struct XlnxVersalEFuseCache {
93
+ SysBusDevice parent_obj;
94
+ MemoryRegion iomem;
95
+
96
+ XlnxEFuse *efuse;
97
+};
98
+
99
+/**
100
+ * xlnx_versal_efuse_read_row:
101
+ * @s: the efuse object
102
+ * @bit: the bit-address within the 32-bit row to be read
103
+ * @denied: if non-NULL, to receive true if the row is write-only
104
+ *
105
+ * Returns: the 32-bit word containing address @bit; 0 if @denies is true
106
+ */
107
+uint32_t xlnx_versal_efuse_read_row(XlnxEFuse *s, uint32_t bit, bool *denied);
108
+
109
+#endif
110
diff --git a/hw/nvram/xlnx-versal-efuse-cache.c b/hw/nvram/xlnx-versal-efuse-cache.c
111
new file mode 100644
112
index XXXXXXX..XXXXXXX
113
--- /dev/null
114
+++ b/hw/nvram/xlnx-versal-efuse-cache.c
115
@@ -XXX,XX +XXX,XX @@
116
+/*
117
+ * QEMU model of the EFuse_Cache
118
+ *
119
+ * Copyright (c) 2017 Xilinx Inc.
120
+ *
121
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
122
+ * of this software and associated documentation files (the "Software"), to deal
123
+ * in the Software without restriction, including without limitation the rights
124
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
125
+ * copies of the Software, and to permit persons to whom the Software is
126
+ * furnished to do so, subject to the following conditions:
127
+ *
128
+ * The above copyright notice and this permission notice shall be included in
129
+ * all copies or substantial portions of the Software.
130
+ *
131
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
132
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
133
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
134
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
135
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
136
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
137
+ * THE SOFTWARE.
138
+ */
139
+
140
+#include "qemu/osdep.h"
141
+#include "hw/nvram/xlnx-versal-efuse.h"
142
+
143
+#include "qemu/log.h"
144
+#include "hw/qdev-properties.h"
145
+
146
+#define MR_SIZE 0xC00
147
+
148
+static uint64_t efuse_cache_read(void *opaque, hwaddr addr, unsigned size)
149
+{
150
+ XlnxVersalEFuseCache *s = XLNX_VERSAL_EFUSE_CACHE(opaque);
151
+ unsigned int w0 = QEMU_ALIGN_DOWN(addr * 8, 32);
152
+ unsigned int w1 = QEMU_ALIGN_DOWN((addr + size - 1) * 8, 32);
153
+
154
+ uint64_t ret;
155
+
156
+ assert(w0 == w1 || (w0 + 32) == w1);
157
+
158
+ ret = xlnx_versal_efuse_read_row(s->efuse, w1, NULL);
159
+ if (w0 < w1) {
160
+ ret <<= 32;
161
+ ret |= xlnx_versal_efuse_read_row(s->efuse, w0, NULL);
162
+ }
163
+
164
+ /* If 'addr' unaligned, the guest is always assumed to be little-endian. */
165
+ addr &= 3;
166
+ if (addr) {
167
+ ret >>= 8 * addr;
168
+ }
169
+
170
+ return ret;
171
+}
172
+
173
+static void efuse_cache_write(void *opaque, hwaddr addr, uint64_t value,
174
+ unsigned size)
175
+{
176
+ /* No Register Writes allowed */
177
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: efuse cache registers are read-only",
178
+ __func__);
179
+}
180
+
181
+static const MemoryRegionOps efuse_cache_ops = {
182
+ .read = efuse_cache_read,
183
+ .write = efuse_cache_write,
184
+ .endianness = DEVICE_LITTLE_ENDIAN,
185
+ .valid = {
186
+ .min_access_size = 1,
187
+ .max_access_size = 4,
188
+ },
189
+};
190
+
191
+static void efuse_cache_init(Object *obj)
192
+{
193
+ XlnxVersalEFuseCache *s = XLNX_VERSAL_EFUSE_CACHE(obj);
194
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
195
+
196
+ memory_region_init_io(&s->iomem, obj, &efuse_cache_ops, s,
197
+ TYPE_XLNX_VERSAL_EFUSE_CACHE, MR_SIZE);
198
+ sysbus_init_mmio(sbd, &s->iomem);
199
+}
200
+
201
+static Property efuse_cache_props[] = {
202
+ DEFINE_PROP_LINK("efuse",
203
+ XlnxVersalEFuseCache, efuse,
204
+ TYPE_XLNX_EFUSE, XlnxEFuse *),
205
+
206
+ DEFINE_PROP_END_OF_LIST(),
207
+};
208
+
209
+static void efuse_cache_class_init(ObjectClass *klass, void *data)
210
+{
211
+ DeviceClass *dc = DEVICE_CLASS(klass);
212
+
213
+ device_class_set_props(dc, efuse_cache_props);
214
+}
215
+
216
+static const TypeInfo efuse_cache_info = {
217
+ .name = TYPE_XLNX_VERSAL_EFUSE_CACHE,
218
+ .parent = TYPE_SYS_BUS_DEVICE,
219
+ .instance_size = sizeof(XlnxVersalEFuseCache),
220
+ .class_init = efuse_cache_class_init,
221
+ .instance_init = efuse_cache_init,
222
+};
223
+
224
+static void efuse_cache_register_types(void)
225
+{
226
+ type_register_static(&efuse_cache_info);
227
+}
228
+
229
+type_init(efuse_cache_register_types)
230
diff --git a/hw/nvram/xlnx-versal-efuse-ctrl.c b/hw/nvram/xlnx-versal-efuse-ctrl.c
231
new file mode 100644
232
index XXXXXXX..XXXXXXX
233
--- /dev/null
234
+++ b/hw/nvram/xlnx-versal-efuse-ctrl.c
235
@@ -XXX,XX +XXX,XX @@
236
+/*
237
+ * QEMU model of the Versal eFuse controller
238
+ *
239
+ * Copyright (c) 2020 Xilinx Inc.
240
+ *
241
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
242
+ * of this software and associated documentation files (the "Software"), to deal
243
+ * in the Software without restriction, including without limitation the rights
244
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
245
+ * copies of the Software, and to permit persons to whom the Software is
246
+ * furnished to do so, subject to the following conditions:
247
+ *
248
+ * The above copyright notice and this permission notice shall be included in
249
+ * all copies or substantial portions of the Software.
250
+ *
251
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
252
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
253
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
254
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
255
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
256
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
257
+ * THE SOFTWARE.
258
+ */
259
+
260
+#include "qemu/osdep.h"
261
+#include "hw/nvram/xlnx-versal-efuse.h"
262
+
263
+#include "qemu/log.h"
264
+#include "qapi/error.h"
265
+#include "migration/vmstate.h"
266
+#include "hw/qdev-properties.h"
267
+
268
+#ifndef XLNX_VERSAL_EFUSE_CTRL_ERR_DEBUG
269
+#define XLNX_VERSAL_EFUSE_CTRL_ERR_DEBUG 0
270
+#endif
271
+
272
+REG32(WR_LOCK, 0x0)
273
+ FIELD(WR_LOCK, LOCK, 0, 16)
274
+REG32(CFG, 0x4)
275
+ FIELD(CFG, SLVERR_ENABLE, 5, 1)
276
+ FIELD(CFG, MARGIN_RD, 2, 1)
277
+ FIELD(CFG, PGM_EN, 1, 1)
278
+REG32(STATUS, 0x8)
279
+ FIELD(STATUS, AES_USER_KEY_1_CRC_PASS, 11, 1)
280
+ FIELD(STATUS, AES_USER_KEY_1_CRC_DONE, 10, 1)
281
+ FIELD(STATUS, AES_USER_KEY_0_CRC_PASS, 9, 1)
282
+ FIELD(STATUS, AES_USER_KEY_0_CRC_DONE, 8, 1)
283
+ FIELD(STATUS, AES_CRC_PASS, 7, 1)
284
+ FIELD(STATUS, AES_CRC_DONE, 6, 1)
285
+ FIELD(STATUS, CACHE_DONE, 5, 1)
286
+ FIELD(STATUS, CACHE_LOAD, 4, 1)
287
+ FIELD(STATUS, EFUSE_2_TBIT, 2, 1)
288
+ FIELD(STATUS, EFUSE_1_TBIT, 1, 1)
289
+ FIELD(STATUS, EFUSE_0_TBIT, 0, 1)
290
+REG32(EFUSE_PGM_ADDR, 0xc)
291
+ FIELD(EFUSE_PGM_ADDR, PAGE, 13, 4)
292
+ FIELD(EFUSE_PGM_ADDR, ROW, 5, 8)
293
+ FIELD(EFUSE_PGM_ADDR, COLUMN, 0, 5)
294
+REG32(EFUSE_RD_ADDR, 0x10)
295
+ FIELD(EFUSE_RD_ADDR, PAGE, 13, 4)
296
+ FIELD(EFUSE_RD_ADDR, ROW, 5, 8)
297
+REG32(EFUSE_RD_DATA, 0x14)
298
+REG32(TPGM, 0x18)
299
+ FIELD(TPGM, VALUE, 0, 16)
300
+REG32(TRD, 0x1c)
301
+ FIELD(TRD, VALUE, 0, 8)
302
+REG32(TSU_H_PS, 0x20)
303
+ FIELD(TSU_H_PS, VALUE, 0, 8)
304
+REG32(TSU_H_PS_CS, 0x24)
305
+ FIELD(TSU_H_PS_CS, VALUE, 0, 8)
306
+REG32(TRDM, 0x28)
307
+ FIELD(TRDM, VALUE, 0, 8)
308
+REG32(TSU_H_CS, 0x2c)
309
+ FIELD(TSU_H_CS, VALUE, 0, 8)
310
+REG32(EFUSE_ISR, 0x30)
311
+ FIELD(EFUSE_ISR, APB_SLVERR, 31, 1)
312
+ FIELD(EFUSE_ISR, CACHE_PARITY_E2, 14, 1)
313
+ FIELD(EFUSE_ISR, CACHE_PARITY_E1, 13, 1)
314
+ FIELD(EFUSE_ISR, CACHE_PARITY_E0S, 12, 1)
315
+ FIELD(EFUSE_ISR, CACHE_PARITY_E0R, 11, 1)
316
+ FIELD(EFUSE_ISR, CACHE_APB_SLVERR, 10, 1)
317
+ FIELD(EFUSE_ISR, CACHE_REQ_ERROR, 9, 1)
318
+ FIELD(EFUSE_ISR, MAIN_REQ_ERROR, 8, 1)
319
+ FIELD(EFUSE_ISR, READ_ON_CACHE_LD, 7, 1)
320
+ FIELD(EFUSE_ISR, CACHE_FSM_ERROR, 6, 1)
321
+ FIELD(EFUSE_ISR, MAIN_FSM_ERROR, 5, 1)
322
+ FIELD(EFUSE_ISR, CACHE_ERROR, 4, 1)
323
+ FIELD(EFUSE_ISR, RD_ERROR, 3, 1)
324
+ FIELD(EFUSE_ISR, RD_DONE, 2, 1)
325
+ FIELD(EFUSE_ISR, PGM_ERROR, 1, 1)
326
+ FIELD(EFUSE_ISR, PGM_DONE, 0, 1)
327
+REG32(EFUSE_IMR, 0x34)
328
+ FIELD(EFUSE_IMR, APB_SLVERR, 31, 1)
329
+ FIELD(EFUSE_IMR, CACHE_PARITY_E2, 14, 1)
330
+ FIELD(EFUSE_IMR, CACHE_PARITY_E1, 13, 1)
331
+ FIELD(EFUSE_IMR, CACHE_PARITY_E0S, 12, 1)
332
+ FIELD(EFUSE_IMR, CACHE_PARITY_E0R, 11, 1)
333
+ FIELD(EFUSE_IMR, CACHE_APB_SLVERR, 10, 1)
334
+ FIELD(EFUSE_IMR, CACHE_REQ_ERROR, 9, 1)
335
+ FIELD(EFUSE_IMR, MAIN_REQ_ERROR, 8, 1)
336
+ FIELD(EFUSE_IMR, READ_ON_CACHE_LD, 7, 1)
337
+ FIELD(EFUSE_IMR, CACHE_FSM_ERROR, 6, 1)
338
+ FIELD(EFUSE_IMR, MAIN_FSM_ERROR, 5, 1)
339
+ FIELD(EFUSE_IMR, CACHE_ERROR, 4, 1)
340
+ FIELD(EFUSE_IMR, RD_ERROR, 3, 1)
341
+ FIELD(EFUSE_IMR, RD_DONE, 2, 1)
342
+ FIELD(EFUSE_IMR, PGM_ERROR, 1, 1)
343
+ FIELD(EFUSE_IMR, PGM_DONE, 0, 1)
344
+REG32(EFUSE_IER, 0x38)
345
+ FIELD(EFUSE_IER, APB_SLVERR, 31, 1)
346
+ FIELD(EFUSE_IER, CACHE_PARITY_E2, 14, 1)
347
+ FIELD(EFUSE_IER, CACHE_PARITY_E1, 13, 1)
348
+ FIELD(EFUSE_IER, CACHE_PARITY_E0S, 12, 1)
349
+ FIELD(EFUSE_IER, CACHE_PARITY_E0R, 11, 1)
350
+ FIELD(EFUSE_IER, CACHE_APB_SLVERR, 10, 1)
351
+ FIELD(EFUSE_IER, CACHE_REQ_ERROR, 9, 1)
352
+ FIELD(EFUSE_IER, MAIN_REQ_ERROR, 8, 1)
353
+ FIELD(EFUSE_IER, READ_ON_CACHE_LD, 7, 1)
354
+ FIELD(EFUSE_IER, CACHE_FSM_ERROR, 6, 1)
355
+ FIELD(EFUSE_IER, MAIN_FSM_ERROR, 5, 1)
356
+ FIELD(EFUSE_IER, CACHE_ERROR, 4, 1)
357
+ FIELD(EFUSE_IER, RD_ERROR, 3, 1)
358
+ FIELD(EFUSE_IER, RD_DONE, 2, 1)
359
+ FIELD(EFUSE_IER, PGM_ERROR, 1, 1)
360
+ FIELD(EFUSE_IER, PGM_DONE, 0, 1)
361
+REG32(EFUSE_IDR, 0x3c)
362
+ FIELD(EFUSE_IDR, APB_SLVERR, 31, 1)
363
+ FIELD(EFUSE_IDR, CACHE_PARITY_E2, 14, 1)
364
+ FIELD(EFUSE_IDR, CACHE_PARITY_E1, 13, 1)
365
+ FIELD(EFUSE_IDR, CACHE_PARITY_E0S, 12, 1)
366
+ FIELD(EFUSE_IDR, CACHE_PARITY_E0R, 11, 1)
367
+ FIELD(EFUSE_IDR, CACHE_APB_SLVERR, 10, 1)
368
+ FIELD(EFUSE_IDR, CACHE_REQ_ERROR, 9, 1)
369
+ FIELD(EFUSE_IDR, MAIN_REQ_ERROR, 8, 1)
370
+ FIELD(EFUSE_IDR, READ_ON_CACHE_LD, 7, 1)
371
+ FIELD(EFUSE_IDR, CACHE_FSM_ERROR, 6, 1)
372
+ FIELD(EFUSE_IDR, MAIN_FSM_ERROR, 5, 1)
373
+ FIELD(EFUSE_IDR, CACHE_ERROR, 4, 1)
374
+ FIELD(EFUSE_IDR, RD_ERROR, 3, 1)
375
+ FIELD(EFUSE_IDR, RD_DONE, 2, 1)
376
+ FIELD(EFUSE_IDR, PGM_ERROR, 1, 1)
377
+ FIELD(EFUSE_IDR, PGM_DONE, 0, 1)
378
+REG32(EFUSE_CACHE_LOAD, 0x40)
379
+ FIELD(EFUSE_CACHE_LOAD, LOAD, 0, 1)
380
+REG32(EFUSE_PGM_LOCK, 0x44)
381
+ FIELD(EFUSE_PGM_LOCK, SPK_ID_LOCK, 0, 1)
382
+REG32(EFUSE_AES_CRC, 0x48)
383
+REG32(EFUSE_AES_USR_KEY0_CRC, 0x4c)
384
+REG32(EFUSE_AES_USR_KEY1_CRC, 0x50)
385
+REG32(EFUSE_PD, 0x54)
386
+REG32(EFUSE_ANLG_OSC_SW_1LP, 0x60)
387
+REG32(EFUSE_TEST_CTRL, 0x100)
388
+
389
+#define R_MAX (R_EFUSE_TEST_CTRL + 1)
390
+
391
+#define R_WR_LOCK_UNLOCK_PASSCODE (0xDF0D)
392
+
393
+/*
394
+ * eFuse layout references:
395
+ * https://github.com/Xilinx/embeddedsw/blob/release-2019.2/lib/sw_services/xilnvm/src/xnvm_efuse_hw.h
396
+ */
397
+#define BIT_POS_OF(A_) \
398
+ ((uint32_t)((A_) & (R_EFUSE_PGM_ADDR_ROW_MASK | \
399
+ R_EFUSE_PGM_ADDR_COLUMN_MASK)))
400
+
401
+#define BIT_POS(R_, C_) \
402
+ ((uint32_t)((R_EFUSE_PGM_ADDR_ROW_MASK \
403
+ & ((R_) << R_EFUSE_PGM_ADDR_ROW_SHIFT)) \
404
+ | \
405
+ (R_EFUSE_PGM_ADDR_COLUMN_MASK \
406
+ & ((C_) << R_EFUSE_PGM_ADDR_COLUMN_SHIFT))))
407
+
408
+#define EFUSE_TBIT_POS(A_) (BIT_POS_OF(A_) >= BIT_POS(0, 28))
409
+
410
+#define EFUSE_ANCHOR_ROW (0)
411
+#define EFUSE_ANCHOR_3_COL (27)
412
+#define EFUSE_ANCHOR_1_COL (1)
413
+
414
+#define EFUSE_AES_KEY_START BIT_POS(12, 0)
415
+#define EFUSE_AES_KEY_END BIT_POS(19, 31)
416
+#define EFUSE_USER_KEY_0_START BIT_POS(20, 0)
417
+#define EFUSE_USER_KEY_0_END BIT_POS(27, 31)
418
+#define EFUSE_USER_KEY_1_START BIT_POS(28, 0)
419
+#define EFUSE_USER_KEY_1_END BIT_POS(35, 31)
420
+
421
+#define EFUSE_RD_BLOCKED_START EFUSE_AES_KEY_START
422
+#define EFUSE_RD_BLOCKED_END EFUSE_USER_KEY_1_END
423
+
424
+#define EFUSE_GLITCH_DET_WR_LK BIT_POS(4, 31)
425
+#define EFUSE_PPK0_WR_LK BIT_POS(43, 6)
426
+#define EFUSE_PPK1_WR_LK BIT_POS(43, 7)
427
+#define EFUSE_PPK2_WR_LK BIT_POS(43, 8)
428
+#define EFUSE_AES_WR_LK BIT_POS(43, 11)
429
+#define EFUSE_USER_KEY_0_WR_LK BIT_POS(43, 13)
430
+#define EFUSE_USER_KEY_1_WR_LK BIT_POS(43, 15)
431
+#define EFUSE_PUF_SYN_LK BIT_POS(43, 16)
432
+#define EFUSE_DNA_WR_LK BIT_POS(43, 27)
433
+#define EFUSE_BOOT_ENV_WR_LK BIT_POS(43, 28)
434
+
435
+#define EFUSE_PGM_LOCKED_START BIT_POS(44, 0)
436
+#define EFUSE_PGM_LOCKED_END BIT_POS(51, 31)
437
+
438
+#define EFUSE_PUF_PAGE (2)
439
+#define EFUSE_PUF_SYN_START BIT_POS(129, 0)
440
+#define EFUSE_PUF_SYN_END BIT_POS(255, 27)
441
+
442
+#define EFUSE_KEY_CRC_LK_ROW (43)
443
+#define EFUSE_AES_KEY_CRC_LK_MASK ((1U << 9) | (1U << 10))
444
+#define EFUSE_USER_KEY_0_CRC_LK_MASK (1U << 12)
445
+#define EFUSE_USER_KEY_1_CRC_LK_MASK (1U << 14)
446
+
447
+/*
448
+ * A handy macro to return value of an array element,
449
+ * or a specific default if given index is out of bound.
450
+ */
451
+#define ARRAY_GET(A_, I_, D_) \
452
+ ((unsigned int)(I_) < ARRAY_SIZE(A_) ? (A_)[I_] : (D_))
453
+
454
+QEMU_BUILD_BUG_ON(R_MAX != ARRAY_SIZE(((XlnxVersalEFuseCtrl *)0)->regs));
455
+
456
+typedef struct XlnxEFuseLkSpec {
457
+ uint16_t row;
458
+ uint16_t lk_bit;
459
+} XlnxEFuseLkSpec;
460
+
461
+static void efuse_imr_update_irq(XlnxVersalEFuseCtrl *s)
462
+{
463
+ bool pending = s->regs[R_EFUSE_ISR] & ~s->regs[R_EFUSE_IMR];
464
+ qemu_set_irq(s->irq_efuse_imr, pending);
465
+}
466
+
467
+static void efuse_isr_postw(RegisterInfo *reg, uint64_t val64)
468
+{
469
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
470
+ efuse_imr_update_irq(s);
471
+}
472
+
473
+static uint64_t efuse_ier_prew(RegisterInfo *reg, uint64_t val64)
474
+{
475
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
476
+ uint32_t val = val64;
477
+
478
+ s->regs[R_EFUSE_IMR] &= ~val;
479
+ efuse_imr_update_irq(s);
480
+ return 0;
481
+}
482
+
483
+static uint64_t efuse_idr_prew(RegisterInfo *reg, uint64_t val64)
484
+{
485
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
486
+ uint32_t val = val64;
487
+
488
+ s->regs[R_EFUSE_IMR] |= val;
489
+ efuse_imr_update_irq(s);
490
+ return 0;
491
+}
492
+
493
+static void efuse_status_tbits_sync(XlnxVersalEFuseCtrl *s)
494
+{
495
+ uint32_t check = xlnx_efuse_tbits_check(s->efuse);
496
+ uint32_t val = s->regs[R_STATUS];
497
+
498
+ val = FIELD_DP32(val, STATUS, EFUSE_0_TBIT, !!(check & (1 << 0)));
499
+ val = FIELD_DP32(val, STATUS, EFUSE_1_TBIT, !!(check & (1 << 1)));
500
+ val = FIELD_DP32(val, STATUS, EFUSE_2_TBIT, !!(check & (1 << 2)));
501
+
502
+ s->regs[R_STATUS] = val;
503
+}
504
+
505
+static void efuse_anchor_bits_check(XlnxVersalEFuseCtrl *s)
506
+{
507
+ unsigned page;
508
+
509
+ if (!s->efuse || !s->efuse->init_tbits) {
510
+ return;
511
+ }
512
+
513
+ for (page = 0; page < s->efuse->efuse_nr; page++) {
514
+ uint32_t row = 0, bit;
515
+
516
+ row = FIELD_DP32(row, EFUSE_PGM_ADDR, PAGE, page);
517
+ row = FIELD_DP32(row, EFUSE_PGM_ADDR, ROW, EFUSE_ANCHOR_ROW);
518
+
519
+ bit = FIELD_DP32(row, EFUSE_PGM_ADDR, COLUMN, EFUSE_ANCHOR_3_COL);
520
+ if (!xlnx_efuse_get_bit(s->efuse, bit)) {
521
+ xlnx_efuse_set_bit(s->efuse, bit);
522
+ }
523
+
524
+ bit = FIELD_DP32(row, EFUSE_PGM_ADDR, COLUMN, EFUSE_ANCHOR_1_COL);
525
+ if (!xlnx_efuse_get_bit(s->efuse, bit)) {
526
+ xlnx_efuse_set_bit(s->efuse, bit);
527
+ }
528
+ }
529
+}
530
+
531
+static void efuse_key_crc_check(RegisterInfo *reg, uint32_t crc,
532
+ uint32_t pass_mask, uint32_t done_mask,
533
+ unsigned first, uint32_t lk_mask)
534
+{
535
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
536
+ uint32_t r, lk_bits;
537
+
55
+
538
+ /*
56
+ /*
539
+ * To start, assume both DONE and PASS, and clear PASS by xor
57
+ * TZASC
540
+ * if CRC-check fails or CRC-check disabled by lock fuse.
541
+ */
58
+ */
542
+ r = s->regs[R_STATUS] | done_mask | pass_mask;
59
+ create_unimplemented_device("tzasc", FSL_IMX7_TZASC_ADDR,
543
+
60
+ FSL_IMX7_TZASC_SIZE);
544
+ lk_bits = xlnx_efuse_get_row(s->efuse, EFUSE_KEY_CRC_LK_ROW) & lk_mask;
545
+ if (lk_bits == 0 && xlnx_efuse_k256_check(s->efuse, crc, first)) {
546
+ pass_mask = 0;
547
+ }
548
+
549
+ s->regs[R_STATUS] = r ^ pass_mask;
550
+}
551
+
552
+static void efuse_data_sync(XlnxVersalEFuseCtrl *s)
553
+{
554
+ efuse_status_tbits_sync(s);
555
+}
556
+
557
+static int efuse_lk_spec_cmp(const void *a, const void *b)
558
+{
559
+ uint16_t r1 = ((const XlnxEFuseLkSpec *)a)->row;
560
+ uint16_t r2 = ((const XlnxEFuseLkSpec *)b)->row;
561
+
562
+ return (r1 > r2) - (r1 < r2);
563
+}
564
+
565
+static void efuse_lk_spec_sort(XlnxVersalEFuseCtrl *s)
566
+{
567
+ XlnxEFuseLkSpec *ary = s->extra_pg0_lock_spec;
568
+ const uint32_t n8 = s->extra_pg0_lock_n16 * 2;
569
+ const uint32_t sz = sizeof(ary[0]);
570
+ const uint32_t cnt = n8 / sz;
571
+
572
+ if (ary && cnt) {
573
+ qsort(ary, cnt, sz, efuse_lk_spec_cmp);
574
+ }
575
+}
576
+
577
+static uint32_t efuse_lk_spec_find(XlnxVersalEFuseCtrl *s, uint32_t row)
578
+{
579
+ const XlnxEFuseLkSpec *ary = s->extra_pg0_lock_spec;
580
+ const uint32_t n8 = s->extra_pg0_lock_n16 * 2;
581
+ const uint32_t sz = sizeof(ary[0]);
582
+ const uint32_t cnt = n8 / sz;
583
+ const XlnxEFuseLkSpec *item = NULL;
584
+
585
+ if (ary && cnt) {
586
+ XlnxEFuseLkSpec k = { .row = row, };
587
+
588
+ item = bsearch(&k, ary, cnt, sz, efuse_lk_spec_cmp);
589
+ }
590
+
591
+ return item ? item->lk_bit : 0;
592
+}
593
+
594
+static uint32_t efuse_bit_locked(XlnxVersalEFuseCtrl *s, uint32_t bit)
595
+{
596
+ /* Hard-coded locks */
597
+ static const uint16_t pg0_hard_lock[] = {
598
+ [4] = EFUSE_GLITCH_DET_WR_LK,
599
+ [37] = EFUSE_BOOT_ENV_WR_LK,
600
+
601
+ [8 ... 11] = EFUSE_DNA_WR_LK,
602
+ [12 ... 19] = EFUSE_AES_WR_LK,
603
+ [20 ... 27] = EFUSE_USER_KEY_0_WR_LK,
604
+ [28 ... 35] = EFUSE_USER_KEY_1_WR_LK,
605
+ [64 ... 71] = EFUSE_PPK0_WR_LK,
606
+ [72 ... 79] = EFUSE_PPK1_WR_LK,
607
+ [80 ... 87] = EFUSE_PPK2_WR_LK,
608
+ };
609
+
610
+ uint32_t row = FIELD_EX32(bit, EFUSE_PGM_ADDR, ROW);
611
+ uint32_t lk_bit = ARRAY_GET(pg0_hard_lock, row, 0);
612
+
613
+ return lk_bit ? lk_bit : efuse_lk_spec_find(s, row);
614
+}
615
+
616
+static bool efuse_pgm_locked(XlnxVersalEFuseCtrl *s, unsigned int bit)
617
+{
618
+
619
+ unsigned int lock = 1;
620
+
621
+ /* Global lock */
622
+ if (!ARRAY_FIELD_EX32(s->regs, CFG, PGM_EN)) {
623
+ goto ret_lock;
624
+ }
625
+
626
+ /* Row lock */
627
+ switch (FIELD_EX32(bit, EFUSE_PGM_ADDR, PAGE)) {
628
+ case 0:
629
+ if (ARRAY_FIELD_EX32(s->regs, EFUSE_PGM_LOCK, SPK_ID_LOCK) &&
630
+ bit >= EFUSE_PGM_LOCKED_START && bit <= EFUSE_PGM_LOCKED_END) {
631
+ goto ret_lock;
632
+ }
633
+
634
+ lock = efuse_bit_locked(s, bit);
635
+ break;
636
+ case EFUSE_PUF_PAGE:
637
+ if (bit < EFUSE_PUF_SYN_START || bit > EFUSE_PUF_SYN_END) {
638
+ lock = 0;
639
+ goto ret_lock;
640
+ }
641
+
642
+ lock = EFUSE_PUF_SYN_LK;
643
+ break;
644
+ default:
645
+ lock = 0;
646
+ goto ret_lock;
647
+ }
648
+
649
+ /* Row lock by an efuse bit */
650
+ if (lock) {
651
+ lock = xlnx_efuse_get_bit(s->efuse, lock);
652
+ }
653
+
654
+ ret_lock:
655
+ return lock != 0;
656
+}
657
+
658
+static void efuse_pgm_addr_postw(RegisterInfo *reg, uint64_t val64)
659
+{
660
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
661
+ unsigned bit = val64;
662
+ bool ok = false;
663
+
664
+ /* Always zero out PGM_ADDR because it is write-only */
665
+ s->regs[R_EFUSE_PGM_ADDR] = 0;
666
+
61
+
667
+ /*
62
+ /*
668
+ * Indicate error if bit is write-protected (or read-only
63
+ * OCRAM memory
669
+ * as guarded by efuse_set_bit()).
670
+ *
671
+ * Keep it simple by not modeling program timing.
672
+ *
673
+ * Note: model must NEVER clear the PGM_ERROR bit; it is
674
+ * up to guest to do so (or by reset).
675
+ */
64
+ */
676
+ if (efuse_pgm_locked(s, bit)) {
65
+ memory_region_init_ram(&s->ocram, NULL, "imx7.ocram",
677
+ qemu_log_mask(LOG_GUEST_ERROR,
66
+ FSL_IMX7_OCRAM_MEM_SIZE,
678
+ "%s: Denied setting of efuse<%u, %u, %u>\n",
67
+ &error_abort);
679
+ object_get_canonical_path(OBJECT(s)),
68
+ memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_MEM_ADDR,
680
+ FIELD_EX32(bit, EFUSE_PGM_ADDR, PAGE),
69
+ &s->ocram);
681
+ FIELD_EX32(bit, EFUSE_PGM_ADDR, ROW),
682
+ FIELD_EX32(bit, EFUSE_PGM_ADDR, COLUMN));
683
+ } else if (xlnx_efuse_set_bit(s->efuse, bit)) {
684
+ ok = true;
685
+ if (EFUSE_TBIT_POS(bit)) {
686
+ efuse_status_tbits_sync(s);
687
+ }
688
+ }
689
+
690
+ if (!ok) {
691
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_ERROR, 1);
692
+ }
693
+
694
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_DONE, 1);
695
+ efuse_imr_update_irq(s);
696
+}
697
+
698
+static void efuse_rd_addr_postw(RegisterInfo *reg, uint64_t val64)
699
+{
700
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
701
+ unsigned bit = val64;
702
+ bool denied;
703
+
704
+ /* Always zero out RD_ADDR because it is write-only */
705
+ s->regs[R_EFUSE_RD_ADDR] = 0;
706
+
70
+
707
+ /*
71
+ /*
708
+ * Indicate error if row is read-blocked.
72
+ * OCRAM EPDC memory
709
+ *
710
+ * Note: model must NEVER clear the RD_ERROR bit; it is
711
+ * up to guest to do so (or by reset).
712
+ */
73
+ */
713
+ s->regs[R_EFUSE_RD_DATA] = xlnx_versal_efuse_read_row(s->efuse,
74
+ memory_region_init_ram(&s->ocram_epdc, NULL, "imx7.ocram_epdc",
714
+ bit, &denied);
75
+ FSL_IMX7_OCRAM_EPDC_SIZE,
715
+ if (denied) {
76
+ &error_abort);
716
+ qemu_log_mask(LOG_GUEST_ERROR,
77
+ memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_EPDC_ADDR,
717
+ "%s: Denied reading of efuse<%u, %u>\n",
78
+ &s->ocram_epdc);
718
+ object_get_canonical_path(OBJECT(s)),
719
+ FIELD_EX32(bit, EFUSE_RD_ADDR, PAGE),
720
+ FIELD_EX32(bit, EFUSE_RD_ADDR, ROW));
721
+
79
+
722
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_ERROR, 1);
80
+ /*
723
+ }
81
+ * OCRAM PXP memory
82
+ */
83
+ memory_region_init_ram(&s->ocram_pxp, NULL, "imx7.ocram_pxp",
84
+ FSL_IMX7_OCRAM_PXP_SIZE,
85
+ &error_abort);
86
+ memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_PXP_ADDR,
87
+ &s->ocram_pxp);
724
+
88
+
725
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_DONE, 1);
89
+ /*
726
+ efuse_imr_update_irq(s);
90
+ * OCRAM_S memory
727
+ return;
91
+ */
728
+}
92
+ memory_region_init_ram(&s->ocram_s, NULL, "imx7.ocram_s",
93
+ FSL_IMX7_OCRAM_S_SIZE,
94
+ &error_abort);
95
+ memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_S_ADDR,
96
+ &s->ocram_s);
729
+
97
+
730
+static uint64_t efuse_cache_load_prew(RegisterInfo *reg, uint64_t val64)
98
+ /*
731
+{
99
+ * ROM memory
732
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
100
+ */
101
+ memory_region_init_rom(&s->rom, OBJECT(dev), "imx7.rom",
102
+ FSL_IMX7_ROM_SIZE, &error_abort);
103
+ memory_region_add_subregion(get_system_memory(), FSL_IMX7_ROM_ADDR,
104
+ &s->rom);
733
+
105
+
734
+ if (val64 & R_EFUSE_CACHE_LOAD_LOAD_MASK) {
106
+ /*
735
+ efuse_data_sync(s);
107
+ * CAAM memory
736
+
108
+ */
737
+ ARRAY_FIELD_DP32(s->regs, STATUS, CACHE_DONE, 1);
109
+ memory_region_init_rom(&s->caam, OBJECT(dev), "imx7.caam",
738
+ efuse_imr_update_irq(s);
110
+ FSL_IMX7_CAAM_MEM_SIZE, &error_abort);
739
+ }
111
+ memory_region_add_subregion(get_system_memory(), FSL_IMX7_CAAM_MEM_ADDR,
740
+
112
+ &s->caam);
741
+ return 0;
113
}
742
+}
114
743
+
115
static Property fsl_imx7_properties[] = {
744
+static uint64_t efuse_pgm_lock_prew(RegisterInfo *reg, uint64_t val64)
745
+{
746
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
747
+
748
+ /* Ignore all other bits */
749
+ val64 = FIELD_EX32(val64, EFUSE_PGM_LOCK, SPK_ID_LOCK);
750
+
751
+ /* Once the bit is written 1, only reset will clear it to 0 */
752
+ val64 |= ARRAY_FIELD_EX32(s->regs, EFUSE_PGM_LOCK, SPK_ID_LOCK);
753
+
754
+ return val64;
755
+}
756
+
757
+static void efuse_aes_crc_postw(RegisterInfo *reg, uint64_t val64)
758
+{
759
+ efuse_key_crc_check(reg, val64,
760
+ R_STATUS_AES_CRC_PASS_MASK,
761
+ R_STATUS_AES_CRC_DONE_MASK,
762
+ EFUSE_AES_KEY_START,
763
+ EFUSE_AES_KEY_CRC_LK_MASK);
764
+}
765
+
766
+static void efuse_aes_u0_crc_postw(RegisterInfo *reg, uint64_t val64)
767
+{
768
+ efuse_key_crc_check(reg, val64,
769
+ R_STATUS_AES_USER_KEY_0_CRC_PASS_MASK,
770
+ R_STATUS_AES_USER_KEY_0_CRC_DONE_MASK,
771
+ EFUSE_USER_KEY_0_START,
772
+ EFUSE_USER_KEY_0_CRC_LK_MASK);
773
+}
774
+
775
+static void efuse_aes_u1_crc_postw(RegisterInfo *reg, uint64_t val64)
776
+{
777
+ efuse_key_crc_check(reg, val64,
778
+ R_STATUS_AES_USER_KEY_1_CRC_PASS_MASK,
779
+ R_STATUS_AES_USER_KEY_1_CRC_DONE_MASK,
780
+ EFUSE_USER_KEY_1_START,
781
+ EFUSE_USER_KEY_1_CRC_LK_MASK);
782
+}
783
+
784
+static uint64_t efuse_wr_lock_prew(RegisterInfo *reg, uint64_t val)
785
+{
786
+ return val != R_WR_LOCK_UNLOCK_PASSCODE;
787
+}
788
+
789
+static const RegisterAccessInfo efuse_ctrl_regs_info[] = {
790
+ { .name = "WR_LOCK", .addr = A_WR_LOCK,
791
+ .reset = 0x1,
792
+ .pre_write = efuse_wr_lock_prew,
793
+ },{ .name = "CFG", .addr = A_CFG,
794
+ .rsvd = 0x9,
795
+ },{ .name = "STATUS", .addr = A_STATUS,
796
+ .rsvd = 0x8,
797
+ .ro = 0xfff,
798
+ },{ .name = "EFUSE_PGM_ADDR", .addr = A_EFUSE_PGM_ADDR,
799
+ .post_write = efuse_pgm_addr_postw,
800
+ },{ .name = "EFUSE_RD_ADDR", .addr = A_EFUSE_RD_ADDR,
801
+ .rsvd = 0x1f,
802
+ .post_write = efuse_rd_addr_postw,
803
+ },{ .name = "EFUSE_RD_DATA", .addr = A_EFUSE_RD_DATA,
804
+ .ro = 0xffffffff,
805
+ },{ .name = "TPGM", .addr = A_TPGM,
806
+ },{ .name = "TRD", .addr = A_TRD,
807
+ .reset = 0x19,
808
+ },{ .name = "TSU_H_PS", .addr = A_TSU_H_PS,
809
+ .reset = 0xff,
810
+ },{ .name = "TSU_H_PS_CS", .addr = A_TSU_H_PS_CS,
811
+ .reset = 0x11,
812
+ },{ .name = "TRDM", .addr = A_TRDM,
813
+ .reset = 0x3a,
814
+ },{ .name = "TSU_H_CS", .addr = A_TSU_H_CS,
815
+ .reset = 0x16,
816
+ },{ .name = "EFUSE_ISR", .addr = A_EFUSE_ISR,
817
+ .rsvd = 0x7fff8000,
818
+ .w1c = 0x80007fff,
819
+ .post_write = efuse_isr_postw,
820
+ },{ .name = "EFUSE_IMR", .addr = A_EFUSE_IMR,
821
+ .reset = 0x80007fff,
822
+ .rsvd = 0x7fff8000,
823
+ .ro = 0xffffffff,
824
+ },{ .name = "EFUSE_IER", .addr = A_EFUSE_IER,
825
+ .rsvd = 0x7fff8000,
826
+ .pre_write = efuse_ier_prew,
827
+ },{ .name = "EFUSE_IDR", .addr = A_EFUSE_IDR,
828
+ .rsvd = 0x7fff8000,
829
+ .pre_write = efuse_idr_prew,
830
+ },{ .name = "EFUSE_CACHE_LOAD", .addr = A_EFUSE_CACHE_LOAD,
831
+ .pre_write = efuse_cache_load_prew,
832
+ },{ .name = "EFUSE_PGM_LOCK", .addr = A_EFUSE_PGM_LOCK,
833
+ .pre_write = efuse_pgm_lock_prew,
834
+ },{ .name = "EFUSE_AES_CRC", .addr = A_EFUSE_AES_CRC,
835
+ .post_write = efuse_aes_crc_postw,
836
+ },{ .name = "EFUSE_AES_USR_KEY0_CRC", .addr = A_EFUSE_AES_USR_KEY0_CRC,
837
+ .post_write = efuse_aes_u0_crc_postw,
838
+ },{ .name = "EFUSE_AES_USR_KEY1_CRC", .addr = A_EFUSE_AES_USR_KEY1_CRC,
839
+ .post_write = efuse_aes_u1_crc_postw,
840
+ },{ .name = "EFUSE_PD", .addr = A_EFUSE_PD,
841
+ .ro = 0xfffffffe,
842
+ },{ .name = "EFUSE_ANLG_OSC_SW_1LP", .addr = A_EFUSE_ANLG_OSC_SW_1LP,
843
+ },{ .name = "EFUSE_TEST_CTRL", .addr = A_EFUSE_TEST_CTRL,
844
+ .reset = 0x8,
845
+ }
846
+};
847
+
848
+static void efuse_ctrl_reg_write(void *opaque, hwaddr addr,
849
+ uint64_t data, unsigned size)
850
+{
851
+ RegisterInfoArray *reg_array = opaque;
852
+ XlnxVersalEFuseCtrl *s;
853
+ Object *dev;
854
+
855
+ assert(reg_array != NULL);
856
+
857
+ dev = reg_array->mem.owner;
858
+ assert(dev);
859
+
860
+ s = XLNX_VERSAL_EFUSE_CTRL(dev);
861
+
862
+ if (addr != A_WR_LOCK && s->regs[R_WR_LOCK]) {
863
+ qemu_log_mask(LOG_GUEST_ERROR,
864
+ "%s[reg_0x%02lx]: Attempt to write locked register.\n",
865
+ object_get_canonical_path(OBJECT(s)), (long)addr);
866
+ } else {
867
+ register_write_memory(opaque, addr, data, size);
868
+ }
869
+}
870
+
871
+static void efuse_ctrl_register_reset(RegisterInfo *reg)
872
+{
873
+ if (!reg->data || !reg->access) {
874
+ return;
875
+ }
876
+
877
+ /* Reset must not trigger some registers' writers */
878
+ switch (reg->access->addr) {
879
+ case A_EFUSE_AES_CRC:
880
+ case A_EFUSE_AES_USR_KEY0_CRC:
881
+ case A_EFUSE_AES_USR_KEY1_CRC:
882
+ *(uint32_t *)reg->data = reg->access->reset;
883
+ return;
884
+ }
885
+
886
+ register_reset(reg);
887
+}
888
+
889
+static void efuse_ctrl_reset(DeviceState *dev)
890
+{
891
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(dev);
892
+ unsigned int i;
893
+
894
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
895
+ efuse_ctrl_register_reset(&s->regs_info[i]);
896
+ }
897
+
898
+ efuse_anchor_bits_check(s);
899
+ efuse_data_sync(s);
900
+ efuse_imr_update_irq(s);
901
+}
902
+
903
+static const MemoryRegionOps efuse_ctrl_ops = {
904
+ .read = register_read_memory,
905
+ .write = efuse_ctrl_reg_write,
906
+ .endianness = DEVICE_LITTLE_ENDIAN,
907
+ .valid = {
908
+ .min_access_size = 4,
909
+ .max_access_size = 4,
910
+ },
911
+};
912
+
913
+static void efuse_ctrl_realize(DeviceState *dev, Error **errp)
914
+{
915
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(dev);
916
+ const uint32_t lks_sz = sizeof(XlnxEFuseLkSpec) / 2;
917
+
918
+ if (!s->efuse) {
919
+ error_setg(errp, "%s.efuse: link property not connected to XLNX-EFUSE",
920
+ object_get_canonical_path(OBJECT(dev)));
921
+ return;
922
+ }
923
+
924
+ /* Sort property-defined pgm-locks for bsearch lookup */
925
+ if ((s->extra_pg0_lock_n16 % lks_sz) != 0) {
926
+ error_setg(errp,
927
+ "%s.pg0-lock: array property item-count not multiple of %u",
928
+ object_get_canonical_path(OBJECT(dev)), lks_sz);
929
+ return;
930
+ }
931
+
932
+ efuse_lk_spec_sort(s);
933
+}
934
+
935
+static void efuse_ctrl_init(Object *obj)
936
+{
937
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(obj);
938
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
939
+ RegisterInfoArray *reg_array;
940
+
941
+ reg_array =
942
+ register_init_block32(DEVICE(obj), efuse_ctrl_regs_info,
943
+ ARRAY_SIZE(efuse_ctrl_regs_info),
944
+ s->regs_info, s->regs,
945
+ &efuse_ctrl_ops,
946
+ XLNX_VERSAL_EFUSE_CTRL_ERR_DEBUG,
947
+ R_MAX * 4);
948
+
949
+ sysbus_init_mmio(sbd, &reg_array->mem);
950
+ sysbus_init_irq(sbd, &s->irq_efuse_imr);
951
+}
952
+
953
+static const VMStateDescription vmstate_efuse_ctrl = {
954
+ .name = TYPE_XLNX_VERSAL_EFUSE_CTRL,
955
+ .version_id = 1,
956
+ .minimum_version_id = 1,
957
+ .fields = (VMStateField[]) {
958
+ VMSTATE_UINT32_ARRAY(regs, XlnxVersalEFuseCtrl, R_MAX),
959
+ VMSTATE_END_OF_LIST(),
960
+ }
961
+};
962
+
963
+static Property efuse_ctrl_props[] = {
964
+ DEFINE_PROP_LINK("efuse",
965
+ XlnxVersalEFuseCtrl, efuse,
966
+ TYPE_XLNX_EFUSE, XlnxEFuse *),
967
+ DEFINE_PROP_ARRAY("pg0-lock",
968
+ XlnxVersalEFuseCtrl, extra_pg0_lock_n16,
969
+ extra_pg0_lock_spec, qdev_prop_uint16, uint16_t),
970
+
971
+ DEFINE_PROP_END_OF_LIST(),
972
+};
973
+
974
+static void efuse_ctrl_class_init(ObjectClass *klass, void *data)
975
+{
976
+ DeviceClass *dc = DEVICE_CLASS(klass);
977
+
978
+ dc->reset = efuse_ctrl_reset;
979
+ dc->realize = efuse_ctrl_realize;
980
+ dc->vmsd = &vmstate_efuse_ctrl;
981
+ device_class_set_props(dc, efuse_ctrl_props);
982
+}
983
+
984
+static const TypeInfo efuse_ctrl_info = {
985
+ .name = TYPE_XLNX_VERSAL_EFUSE_CTRL,
986
+ .parent = TYPE_SYS_BUS_DEVICE,
987
+ .instance_size = sizeof(XlnxVersalEFuseCtrl),
988
+ .class_init = efuse_ctrl_class_init,
989
+ .instance_init = efuse_ctrl_init,
990
+};
991
+
992
+static void efuse_ctrl_register_types(void)
993
+{
994
+ type_register_static(&efuse_ctrl_info);
995
+}
996
+
997
+type_init(efuse_ctrl_register_types)
998
+
999
+/*
1000
+ * Retrieve a row, with unreadable bits returned as 0.
1001
+ */
1002
+uint32_t xlnx_versal_efuse_read_row(XlnxEFuse *efuse,
1003
+ uint32_t bit, bool *denied)
1004
+{
1005
+ bool dummy;
1006
+
1007
+ if (!denied) {
1008
+ denied = &dummy;
1009
+ }
1010
+
1011
+ if (bit >= EFUSE_RD_BLOCKED_START && bit <= EFUSE_RD_BLOCKED_END) {
1012
+ *denied = true;
1013
+ return 0;
1014
+ }
1015
+
1016
+ *denied = false;
1017
+ return xlnx_efuse_get_row(efuse, bit);
1018
+}
1019
diff --git a/hw/nvram/Kconfig b/hw/nvram/Kconfig
1020
index XXXXXXX..XXXXXXX 100644
1021
--- a/hw/nvram/Kconfig
1022
+++ b/hw/nvram/Kconfig
1023
@@ -XXX,XX +XXX,XX @@ config XLNX_EFUSE_CRC
1024
config XLNX_EFUSE
1025
bool
1026
select XLNX_EFUSE_CRC
1027
+
1028
+config XLNX_EFUSE_VERSAL
1029
+ bool
1030
+ select XLNX_EFUSE
1031
diff --git a/hw/nvram/meson.build b/hw/nvram/meson.build
1032
index XXXXXXX..XXXXXXX 100644
1033
--- a/hw/nvram/meson.build
1034
+++ b/hw/nvram/meson.build
1035
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_otp.c'))
1036
softmmu_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_nvm.c'))
1037
softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE_CRC', if_true: files('xlnx-efuse-crc.c'))
1038
softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE', if_true: files('xlnx-efuse.c'))
1039
+softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE_VERSAL', if_true: files(
1040
+ 'xlnx-versal-efuse-cache.c',
1041
+ 'xlnx-versal-efuse-ctrl.c'))
1042
1043
specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_nvram.c'))
1044
--
116
--
1045
2.20.1
117
2.34.1
1046
118
1047
119
diff view generated by jsdifflib
1
From: Tong Ho <tong.ho@xilinx.com>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
This introduces the QOM for Xilinx eFuse, an one-time
3
The SRC device is normally used to start the secondary CPU.
4
field-programmable storage bit array.
4
5
5
When running Linux directly, QEMU is emulating a PSCI interface that UBOOT
6
The actual mmio interface to the array varies by device
6
is installing at boot time and therefore the fact that the SRC device is
7
families and will be provided in different change-sets.
7
unimplemented is hidden as Qemu respond directly to PSCI requets without
8
8
using the SRC device.
9
Co-authored-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
10
Co-authored-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
10
But if you try to run a more bare metal application (maybe uboot itself),
11
11
then it is not possible to start the secondary CPU as the SRC is an
12
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
unimplemented device.
13
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
13
14
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
14
This patch adds the ability to start the secondary CPU through the SRC
15
Message-id: 20210917052400.1249094-2-tong.ho@xilinx.com
15
device so that you can use this feature in bare metal applications.
16
17
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Message-id: ce9a0162defd2acee5dc7f8a674743de0cded569.1692964892.git.jcd@tribudubois.net
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
21
---
19
include/hw/nvram/xlnx-efuse.h | 132 ++++++++++++++++
22
include/hw/arm/fsl-imx7.h | 3 +-
20
hw/nvram/xlnx-efuse-crc.c | 119 +++++++++++++++
23
include/hw/misc/imx7_src.h | 66 +++++++++
21
hw/nvram/xlnx-efuse.c | 280 ++++++++++++++++++++++++++++++++++
24
hw/arm/fsl-imx7.c | 8 +-
22
hw/nvram/Kconfig | 7 +
25
hw/misc/imx7_src.c | 276 +++++++++++++++++++++++++++++++++++++
23
hw/nvram/meson.build | 2 +
26
hw/misc/meson.build | 1 +
24
5 files changed, 540 insertions(+)
27
hw/misc/trace-events | 4 +
25
create mode 100644 include/hw/nvram/xlnx-efuse.h
28
6 files changed, 356 insertions(+), 2 deletions(-)
26
create mode 100644 hw/nvram/xlnx-efuse-crc.c
29
create mode 100644 include/hw/misc/imx7_src.h
27
create mode 100644 hw/nvram/xlnx-efuse.c
30
create mode 100644 hw/misc/imx7_src.c
28
31
29
diff --git a/include/hw/nvram/xlnx-efuse.h b/include/hw/nvram/xlnx-efuse.h
32
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/include/hw/arm/fsl-imx7.h
35
+++ b/include/hw/arm/fsl-imx7.h
36
@@ -XXX,XX +XXX,XX @@
37
#include "hw/misc/imx7_ccm.h"
38
#include "hw/misc/imx7_snvs.h"
39
#include "hw/misc/imx7_gpr.h"
40
+#include "hw/misc/imx7_src.h"
41
#include "hw/watchdog/wdt_imx2.h"
42
#include "hw/gpio/imx_gpio.h"
43
#include "hw/char/imx_serial.h"
44
@@ -XXX,XX +XXX,XX @@ struct FslIMX7State {
45
IMX7CCMState ccm;
46
IMX7AnalogState analog;
47
IMX7SNVSState snvs;
48
+ IMX7SRCState src;
49
IMXGPCv2State gpcv2;
50
IMXSPIState spi[FSL_IMX7_NUM_ECSPIS];
51
IMXI2CState i2c[FSL_IMX7_NUM_I2CS];
52
@@ -XXX,XX +XXX,XX @@ enum FslIMX7MemoryMap {
53
FSL_IMX7_GPC_ADDR = 0x303A0000,
54
55
FSL_IMX7_SRC_ADDR = 0x30390000,
56
- FSL_IMX7_SRC_SIZE = (4 * KiB),
57
58
FSL_IMX7_CCM_ADDR = 0x30380000,
59
60
diff --git a/include/hw/misc/imx7_src.h b/include/hw/misc/imx7_src.h
30
new file mode 100644
61
new file mode 100644
31
index XXXXXXX..XXXXXXX
62
index XXXXXXX..XXXXXXX
32
--- /dev/null
63
--- /dev/null
33
+++ b/include/hw/nvram/xlnx-efuse.h
64
+++ b/include/hw/misc/imx7_src.h
34
@@ -XXX,XX +XXX,XX @@
65
@@ -XXX,XX +XXX,XX @@
35
+/*
66
+/*
36
+ * QEMU model of the Xilinx eFuse core
67
+ * IMX7 System Reset Controller
37
+ *
68
+ *
38
+ * Copyright (c) 2015 Xilinx Inc.
69
+ * Copyright (C) 2023 Jean-Christophe Dubois <jcd@tribudubois.net>
39
+ *
70
+ *
40
+ * Written by Edgar E. Iglesias <edgari@xilinx.com>
71
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
41
+ *
72
+ * See the COPYING file in the top-level directory.
42
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
43
+ * of this software and associated documentation files (the "Software"), to deal
44
+ * in the Software without restriction, including without limitation the rights
45
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
46
+ * copies of the Software, and to permit persons to whom the Software is
47
+ * furnished to do so, subject to the following conditions:
48
+ *
49
+ * The above copyright notice and this permission notice shall be included in
50
+ * all copies or substantial portions of the Software.
51
+ *
52
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
53
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
54
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
55
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
56
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
58
+ * THE SOFTWARE.
59
+ */
73
+ */
60
+
74
+
61
+#ifndef XLNX_EFUSE_H
75
+#ifndef IMX7_SRC_H
62
+#define XLNX_EFUSE_H
76
+#define IMX7_SRC_H
63
+
77
+
64
+#include "sysemu/block-backend.h"
78
+#include "hw/sysbus.h"
65
+#include "hw/qdev-core.h"
79
+#include "qemu/bitops.h"
66
+
80
+#include "qom/object.h"
67
+#define TYPE_XLNX_EFUSE "xlnx,efuse"
81
+
68
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxEFuse, XLNX_EFUSE);
82
+#define SRC_SCR 0
69
+
83
+#define SRC_A7RCR0 1
70
+struct XlnxEFuse {
84
+#define SRC_A7RCR1 2
71
+ DeviceState parent_obj;
85
+#define SRC_M4RCR 3
72
+ BlockBackend *blk;
86
+#define SRC_ERCR 5
73
+ bool blk_ro;
87
+#define SRC_HSICPHY_RCR 7
74
+ uint32_t *fuse32;
88
+#define SRC_USBOPHY1_RCR 8
75
+
89
+#define SRC_USBOPHY2_RCR 9
76
+ DeviceState *dev;
90
+#define SRC_MPIPHY_RCR 10
77
+
91
+#define SRC_PCIEPHY_RCR 11
78
+ bool init_tbits;
92
+#define SRC_SBMR1 22
79
+
93
+#define SRC_SRSR 23
80
+ uint8_t efuse_nr;
94
+#define SRC_SISR 26
81
+ uint32_t efuse_size;
95
+#define SRC_SIMR 27
82
+
96
+#define SRC_SBMR2 28
83
+ uint32_t *ro_bits;
97
+#define SRC_GPR1 29
84
+ uint32_t ro_bits_cnt;
98
+#define SRC_GPR2 30
99
+#define SRC_GPR3 31
100
+#define SRC_GPR4 32
101
+#define SRC_GPR5 33
102
+#define SRC_GPR6 34
103
+#define SRC_GPR7 35
104
+#define SRC_GPR8 36
105
+#define SRC_GPR9 37
106
+#define SRC_GPR10 38
107
+#define SRC_MAX 39
108
+
109
+/* SRC_A7SCR1 */
110
+#define R_CORE1_ENABLE_SHIFT 1
111
+#define R_CORE1_ENABLE_LENGTH 1
112
+/* SRC_A7SCR0 */
113
+#define R_CORE1_RST_SHIFT 5
114
+#define R_CORE1_RST_LENGTH 1
115
+#define R_CORE0_RST_SHIFT 4
116
+#define R_CORE0_RST_LENGTH 1
117
+
118
+#define TYPE_IMX7_SRC "imx7.src"
119
+OBJECT_DECLARE_SIMPLE_TYPE(IMX7SRCState, IMX7_SRC)
120
+
121
+struct IMX7SRCState {
122
+ /* <private> */
123
+ SysBusDevice parent_obj;
124
+
125
+ /* <public> */
126
+ MemoryRegion iomem;
127
+
128
+ uint32_t regs[SRC_MAX];
85
+};
129
+};
86
+
130
+
87
+/**
131
+#endif /* IMX7_SRC_H */
88
+ * xlnx_efuse_calc_crc:
132
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
89
+ * @data: an array of 32-bit words for which the CRC should be computed
133
index XXXXXXX..XXXXXXX 100644
90
+ * @u32_cnt: the array size in number of 32-bit words
134
--- a/hw/arm/fsl-imx7.c
91
+ * @zpads: the number of 32-bit zeros prepended to @data before computation
135
+++ b/hw/arm/fsl-imx7.c
92
+ *
136
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
93
+ * This function is used to compute the CRC for an array of 32-bit words,
137
*/
94
+ * using a Xilinx-specific data padding.
138
object_initialize_child(obj, "gpcv2", &s->gpcv2, TYPE_IMX_GPCV2);
95
+ *
139
96
+ * Returns: the computed 32-bit CRC
140
+ /*
97
+ */
141
+ * SRC
98
+uint32_t xlnx_efuse_calc_crc(const uint32_t *data, unsigned u32_cnt,
142
+ */
99
+ unsigned zpads);
143
+ object_initialize_child(obj, "src", &s->src, TYPE_IMX7_SRC);
100
+
144
+
101
+/**
145
/*
102
+ * xlnx_efuse_get_bit:
146
* ECSPIs
103
+ * @s: the efuse object
147
*/
104
+ * @bit: the efuse bit-address to read the data
148
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
105
+ *
149
/*
106
+ * Returns: the bit, 0 or 1, at @bit of object @s
150
* SRC
107
+ */
151
*/
108
+bool xlnx_efuse_get_bit(XlnxEFuse *s, unsigned int bit);
152
- create_unimplemented_device("src", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
109
+
153
+ sysbus_realize(SYS_BUS_DEVICE(&s->src), &error_abort);
110
+/**
154
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0, FSL_IMX7_SRC_ADDR);
111
+ * xlnx_efuse_set_bit:
155
112
+ * @s: the efuse object
156
/*
113
+ * @bit: the efuse bit-address to be written a value of 1
157
* Watchdogs
114
+ *
158
diff --git a/hw/misc/imx7_src.c b/hw/misc/imx7_src.c
115
+ * Returns: true on success, false on failure
116
+ */
117
+bool xlnx_efuse_set_bit(XlnxEFuse *s, unsigned int bit);
118
+
119
+/**
120
+ * xlnx_efuse_k256_check:
121
+ * @s: the efuse object
122
+ * @crc: the 32-bit CRC to be compared with
123
+ * @start: the efuse bit-address (which must be multiple of 32) of the
124
+ * start of a 256-bit array
125
+ *
126
+ * This function computes the CRC of a 256-bit array starting at @start
127
+ * then compares to the given @crc
128
+ *
129
+ * Returns: true of @crc == computed, false otherwise
130
+ */
131
+bool xlnx_efuse_k256_check(XlnxEFuse *s, uint32_t crc, unsigned start);
132
+
133
+/**
134
+ * xlnx_efuse_tbits_check:
135
+ * @s: the efuse object
136
+ *
137
+ * This function inspects a number of efuse bits at specific addresses
138
+ * to see if they match a validation pattern. Each pattern is a group
139
+ * of 4 bits, and there are 3 groups.
140
+ *
141
+ * Returns: a 3-bit mask, where a bit of '1' means the corresponding
142
+ * group has a valid pattern.
143
+ */
144
+uint32_t xlnx_efuse_tbits_check(XlnxEFuse *s);
145
+
146
+/**
147
+ * xlnx_efuse_get_row:
148
+ * @s: the efuse object
149
+ * @bit: the efuse bit address for which a 32-bit value is read
150
+ *
151
+ * Returns: the entire 32 bits of the efuse, starting at a bit
152
+ * address that is multiple of 32 and contains the bit at @bit
153
+ */
154
+static inline uint32_t xlnx_efuse_get_row(XlnxEFuse *s, unsigned int bit)
155
+{
156
+ if (!(s->fuse32)) {
157
+ return 0;
158
+ } else {
159
+ unsigned int row_idx = bit / 32;
160
+
161
+ assert(row_idx < (s->efuse_size * s->efuse_nr / 32));
162
+ return s->fuse32[row_idx];
163
+ }
164
+}
165
+
166
+#endif
167
diff --git a/hw/nvram/xlnx-efuse-crc.c b/hw/nvram/xlnx-efuse-crc.c
168
new file mode 100644
159
new file mode 100644
169
index XXXXXXX..XXXXXXX
160
index XXXXXXX..XXXXXXX
170
--- /dev/null
161
--- /dev/null
171
+++ b/hw/nvram/xlnx-efuse-crc.c
162
+++ b/hw/misc/imx7_src.c
172
@@ -XXX,XX +XXX,XX @@
163
@@ -XXX,XX +XXX,XX @@
173
+/*
164
+/*
174
+ * Xilinx eFuse/bbram CRC calculator
165
+ * IMX7 System Reset Controller
175
+ *
166
+ *
176
+ * Copyright (c) 2021 Xilinx Inc.
167
+ * Copyright (c) 2023 Jean-Christophe Dubois <jcd@tribudubois.net>
177
+ *
168
+ *
178
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
169
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
179
+ * of this software and associated documentation files (the "Software"), to deal
170
+ * See the COPYING file in the top-level directory.
180
+ * in the Software without restriction, including without limitation the rights
181
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
182
+ * copies of the Software, and to permit persons to whom the Software is
183
+ * furnished to do so, subject to the following conditions:
184
+ *
171
+ *
185
+ * The above copyright notice and this permission notice shall be included in
186
+ * all copies or substantial portions of the Software.
187
+ *
188
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
189
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
190
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
191
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
192
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
193
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
194
+ * THE SOFTWARE.
195
+ */
172
+ */
173
+
196
+#include "qemu/osdep.h"
174
+#include "qemu/osdep.h"
197
+#include "hw/nvram/xlnx-efuse.h"
175
+#include "hw/misc/imx7_src.h"
198
+
176
+#include "migration/vmstate.h"
199
+static uint32_t xlnx_efuse_u37_crc(uint32_t prev_crc, uint32_t data,
177
+#include "qemu/bitops.h"
200
+ uint32_t addr)
178
+#include "qemu/log.h"
201
+{
179
+#include "qemu/main-loop.h"
202
+ /* A table for 7-bit slicing */
180
+#include "qemu/module.h"
203
+ static const uint32_t crc_tab[128] = {
181
+#include "target/arm/arm-powerctl.h"
204
+ 0x00000000, 0xe13b70f7, 0xc79a971f, 0x26a1e7e8,
182
+#include "hw/core/cpu.h"
205
+ 0x8ad958cf, 0x6be22838, 0x4d43cfd0, 0xac78bf27,
183
+#include "hw/registerfields.h"
206
+ 0x105ec76f, 0xf165b798, 0xd7c45070, 0x36ff2087,
184
+
207
+ 0x9a879fa0, 0x7bbcef57, 0x5d1d08bf, 0xbc267848,
185
+#include "trace.h"
208
+ 0x20bd8ede, 0xc186fe29, 0xe72719c1, 0x061c6936,
186
+
209
+ 0xaa64d611, 0x4b5fa6e6, 0x6dfe410e, 0x8cc531f9,
187
+static const char *imx7_src_reg_name(uint32_t reg)
210
+ 0x30e349b1, 0xd1d83946, 0xf779deae, 0x1642ae59,
188
+{
211
+ 0xba3a117e, 0x5b016189, 0x7da08661, 0x9c9bf696,
189
+ static char unknown[20];
212
+ 0x417b1dbc, 0xa0406d4b, 0x86e18aa3, 0x67dafa54,
190
+
213
+ 0xcba24573, 0x2a993584, 0x0c38d26c, 0xed03a29b,
191
+ switch (reg) {
214
+ 0x5125dad3, 0xb01eaa24, 0x96bf4dcc, 0x77843d3b,
192
+ case SRC_SCR:
215
+ 0xdbfc821c, 0x3ac7f2eb, 0x1c661503, 0xfd5d65f4,
193
+ return "SRC_SCR";
216
+ 0x61c69362, 0x80fde395, 0xa65c047d, 0x4767748a,
194
+ case SRC_A7RCR0:
217
+ 0xeb1fcbad, 0x0a24bb5a, 0x2c855cb2, 0xcdbe2c45,
195
+ return "SRC_A7RCR0";
218
+ 0x7198540d, 0x90a324fa, 0xb602c312, 0x5739b3e5,
196
+ case SRC_A7RCR1:
219
+ 0xfb410cc2, 0x1a7a7c35, 0x3cdb9bdd, 0xdde0eb2a,
197
+ return "SRC_A7RCR1";
220
+ 0x82f63b78, 0x63cd4b8f, 0x456cac67, 0xa457dc90,
198
+ case SRC_M4RCR:
221
+ 0x082f63b7, 0xe9141340, 0xcfb5f4a8, 0x2e8e845f,
199
+ return "SRC_M4RCR";
222
+ 0x92a8fc17, 0x73938ce0, 0x55326b08, 0xb4091bff,
200
+ case SRC_ERCR:
223
+ 0x1871a4d8, 0xf94ad42f, 0xdfeb33c7, 0x3ed04330,
201
+ return "SRC_ERCR";
224
+ 0xa24bb5a6, 0x4370c551, 0x65d122b9, 0x84ea524e,
202
+ case SRC_HSICPHY_RCR:
225
+ 0x2892ed69, 0xc9a99d9e, 0xef087a76, 0x0e330a81,
203
+ return "SRC_HSICPHY_RCR";
226
+ 0xb21572c9, 0x532e023e, 0x758fe5d6, 0x94b49521,
204
+ case SRC_USBOPHY1_RCR:
227
+ 0x38cc2a06, 0xd9f75af1, 0xff56bd19, 0x1e6dcdee,
205
+ return "SRC_USBOPHY1_RCR";
228
+ 0xc38d26c4, 0x22b65633, 0x0417b1db, 0xe52cc12c,
206
+ case SRC_USBOPHY2_RCR:
229
+ 0x49547e0b, 0xa86f0efc, 0x8ecee914, 0x6ff599e3,
207
+ return "SRC_USBOPHY2_RCR";
230
+ 0xd3d3e1ab, 0x32e8915c, 0x144976b4, 0xf5720643,
208
+ case SRC_PCIEPHY_RCR:
231
+ 0x590ab964, 0xb831c993, 0x9e902e7b, 0x7fab5e8c,
209
+ return "SRC_PCIEPHY_RCR";
232
+ 0xe330a81a, 0x020bd8ed, 0x24aa3f05, 0xc5914ff2,
210
+ case SRC_SBMR1:
233
+ 0x69e9f0d5, 0x88d28022, 0xae7367ca, 0x4f48173d,
211
+ return "SRC_SBMR1";
234
+ 0xf36e6f75, 0x12551f82, 0x34f4f86a, 0xd5cf889d,
212
+ case SRC_SRSR:
235
+ 0x79b737ba, 0x988c474d, 0xbe2da0a5, 0x5f16d052
213
+ return "SRC_SRSR";
236
+ };
214
+ case SRC_SISR:
237
+
215
+ return "SRC_SISR";
238
+ /*
216
+ case SRC_SIMR:
239
+ * eFuse calculation is shown here:
217
+ return "SRC_SIMR";
240
+ * https://github.com/Xilinx/embeddedsw/blob/release-2019.2/lib/sw_services/xilskey/src/xilskey_utils.c#L1496
218
+ case SRC_SBMR2:
241
+ *
219
+ return "SRC_SBMR2";
242
+ * Each u32 word is appended a 5-bit value, for a total of 37 bits; see:
220
+ case SRC_GPR1:
243
+ * https://github.com/Xilinx/embeddedsw/blob/release-2019.2/lib/sw_services/xilskey/src/xilskey_utils.c#L1356
221
+ return "SRC_GPR1";
244
+ */
222
+ case SRC_GPR2:
245
+ uint32_t crc = prev_crc;
223
+ return "SRC_GPR2";
246
+ const unsigned rshf = 7;
224
+ case SRC_GPR3:
247
+ const uint32_t im = (1 << rshf) - 1;
225
+ return "SRC_GPR3";
248
+ const uint32_t rm = (1 << (32 - rshf)) - 1;
226
+ case SRC_GPR4:
249
+ const uint32_t i2 = (1 << 2) - 1;
227
+ return "SRC_GPR4";
250
+ const uint32_t r2 = (1 << 30) - 1;
228
+ case SRC_GPR5:
251
+
229
+ return "SRC_GPR5";
252
+ unsigned j;
230
+ case SRC_GPR6:
253
+ uint32_t i, r;
231
+ return "SRC_GPR6";
254
+ uint64_t w;
232
+ case SRC_GPR7:
255
+
233
+ return "SRC_GPR7";
256
+ w = (uint64_t)(addr) << 32;
234
+ case SRC_GPR8:
257
+ w |= data;
235
+ return "SRC_GPR8";
258
+
236
+ case SRC_GPR9:
259
+ /* Feed 35 bits, in 5 rounds, each a slice of 7 bits */
237
+ return "SRC_GPR9";
260
+ for (j = 0; j < 5; j++) {
238
+ case SRC_GPR10:
261
+ r = rm & (crc >> rshf);
239
+ return "SRC_GPR10";
262
+ i = im & (crc ^ w);
240
+ default:
263
+ crc = crc_tab[i] ^ r;
241
+ sprintf(unknown, "%u ?", reg);
264
+
242
+ return unknown;
265
+ w >>= rshf;
266
+ }
243
+ }
267
+
244
+}
268
+ /* Feed the remaining 2 bits */
245
+
269
+ r = r2 & (crc >> 2);
246
+static const VMStateDescription vmstate_imx7_src = {
270
+ i = i2 & (crc ^ w);
247
+ .name = TYPE_IMX7_SRC,
271
+ crc = crc_tab[i << (rshf - 2)] ^ r;
248
+ .version_id = 1,
272
+
249
+ .minimum_version_id = 1,
273
+ return crc;
250
+ .fields = (VMStateField[]) {
274
+}
251
+ VMSTATE_UINT32_ARRAY(regs, IMX7SRCState, SRC_MAX),
275
+
252
+ VMSTATE_END_OF_LIST()
276
+uint32_t xlnx_efuse_calc_crc(const uint32_t *data, unsigned u32_cnt,
253
+ },
277
+ unsigned zpads)
254
+};
278
+{
255
+
279
+ uint32_t crc = 0;
256
+static void imx7_src_reset(DeviceState *dev)
280
+ unsigned index;
257
+{
281
+
258
+ IMX7SRCState *s = IMX7_SRC(dev);
282
+ for (index = zpads; index; index--) {
259
+
283
+ crc = xlnx_efuse_u37_crc(crc, 0, (index + u32_cnt));
260
+ memset(s->regs, 0, sizeof(s->regs));
261
+
262
+ /* Set reset values */
263
+ s->regs[SRC_SCR] = 0xA0;
264
+ s->regs[SRC_SRSR] = 0x1;
265
+ s->regs[SRC_SIMR] = 0x1F;
266
+}
267
+
268
+static uint64_t imx7_src_read(void *opaque, hwaddr offset, unsigned size)
269
+{
270
+ uint32_t value = 0;
271
+ IMX7SRCState *s = (IMX7SRCState *)opaque;
272
+ uint32_t index = offset >> 2;
273
+
274
+ if (index < SRC_MAX) {
275
+ value = s->regs[index];
276
+ } else {
277
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
278
+ HWADDR_PRIx "\n", TYPE_IMX7_SRC, __func__, offset);
284
+ }
279
+ }
285
+
280
+
286
+ for (index = u32_cnt; index; index--) {
281
+ trace_imx7_src_read(imx7_src_reg_name(index), value);
287
+ crc = xlnx_efuse_u37_crc(crc, data[index - 1], index);
282
+
288
+ }
283
+ return value;
289
+
284
+}
290
+ return crc;
285
+
291
+}
286
+
292
diff --git a/hw/nvram/xlnx-efuse.c b/hw/nvram/xlnx-efuse.c
293
new file mode 100644
294
index XXXXXXX..XXXXXXX
295
--- /dev/null
296
+++ b/hw/nvram/xlnx-efuse.c
297
@@ -XXX,XX +XXX,XX @@
298
+/*
287
+/*
299
+ * QEMU model of the EFUSE eFuse
288
+ * The reset is asynchronous so we need to defer clearing the reset
300
+ *
289
+ * bit until the work is completed.
301
+ * Copyright (c) 2015 Xilinx Inc.
302
+ *
303
+ * Written by Edgar E. Iglesias <edgari@xilinx.com>
304
+ *
305
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
306
+ * of this software and associated documentation files (the "Software"), to deal
307
+ * in the Software without restriction, including without limitation the rights
308
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
309
+ * copies of the Software, and to permit persons to whom the Software is
310
+ * furnished to do so, subject to the following conditions:
311
+ *
312
+ * The above copyright notice and this permission notice shall be included in
313
+ * all copies or substantial portions of the Software.
314
+ *
315
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
316
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
317
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
318
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
319
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
320
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
321
+ * THE SOFTWARE.
322
+ */
290
+ */
323
+
291
+
324
+#include "qemu/osdep.h"
292
+struct SRCSCRResetInfo {
325
+#include "hw/nvram/xlnx-efuse.h"
293
+ IMX7SRCState *s;
326
+
294
+ uint32_t reset_bit;
327
+#include "qemu/error-report.h"
295
+};
328
+#include "qemu/log.h"
296
+
329
+#include "qapi/error.h"
297
+static void imx7_clear_reset_bit(CPUState *cpu, run_on_cpu_data data)
330
+#include "sysemu/blockdev.h"
298
+{
331
+#include "hw/qdev-properties.h"
299
+ struct SRCSCRResetInfo *ri = data.host_ptr;
332
+#include "hw/qdev-properties-system.h"
300
+ IMX7SRCState *s = ri->s;
333
+
301
+
334
+#define TBIT0_OFFSET 28
302
+ assert(qemu_mutex_iothread_locked());
335
+#define TBIT1_OFFSET 29
303
+
336
+#define TBIT2_OFFSET 30
304
+ s->regs[SRC_A7RCR0] = deposit32(s->regs[SRC_A7RCR0], ri->reset_bit, 1, 0);
337
+#define TBIT3_OFFSET 31
305
+
338
+#define TBITS_PATTERN (0x0AU << TBIT0_OFFSET)
306
+ trace_imx7_src_write(imx7_src_reg_name(SRC_A7RCR0), s->regs[SRC_A7RCR0]);
339
+#define TBITS_MASK (0x0FU << TBIT0_OFFSET)
307
+
340
+
308
+ g_free(ri);
341
+bool xlnx_efuse_get_bit(XlnxEFuse *s, unsigned int bit)
309
+}
342
+{
310
+
343
+ bool b = s->fuse32[bit / 32] & (1 << (bit % 32));
311
+static void imx7_defer_clear_reset_bit(uint32_t cpuid,
344
+ return b;
312
+ IMX7SRCState *s,
345
+}
313
+ uint32_t reset_shift)
346
+
314
+{
347
+static int efuse_bytes(XlnxEFuse *s)
315
+ struct SRCSCRResetInfo *ri;
348
+{
316
+ CPUState *cpu = arm_get_cpu_by_id(cpuid);
349
+ return ROUND_UP((s->efuse_nr * s->efuse_size) / 8, 4);
317
+
350
+}
318
+ if (!cpu) {
351
+
352
+static int efuse_bdrv_read(XlnxEFuse *s, Error **errp)
353
+{
354
+ uint32_t *ram = s->fuse32;
355
+ int nr = efuse_bytes(s);
356
+
357
+ if (!s->blk) {
358
+ return 0;
359
+ }
360
+
361
+ s->blk_ro = !blk_supports_write_perm(s->blk);
362
+ if (!s->blk_ro) {
363
+ int rc;
364
+
365
+ rc = blk_set_perm(s->blk,
366
+ (BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE),
367
+ BLK_PERM_ALL, NULL);
368
+ if (rc) {
369
+ s->blk_ro = true;
370
+ }
371
+ }
372
+ if (s->blk_ro) {
373
+ warn_report("%s: Skip saving updates to read-only eFUSE backstore.",
374
+ blk_name(s->blk));
375
+ }
376
+
377
+ if (blk_pread(s->blk, 0, ram, nr) < 0) {
378
+ error_setg(errp, "%s: Failed to read %u bytes from eFUSE backstore.",
379
+ blk_name(s->blk), nr);
380
+ return -1;
381
+ }
382
+
383
+ /* Convert from little-endian backstore for each 32-bit row */
384
+ nr /= 4;
385
+ while (nr--) {
386
+ ram[nr] = le32_to_cpu(ram[nr]);
387
+ }
388
+
389
+ return 0;
390
+}
391
+
392
+static void efuse_bdrv_sync(XlnxEFuse *s, unsigned int bit)
393
+{
394
+ unsigned int row_offset;
395
+ uint32_t le32;
396
+
397
+ if (!s->blk || s->blk_ro) {
398
+ return; /* Silent on read-only backend to avoid message flood */
399
+ }
400
+
401
+ /* Backstore is always in little-endian */
402
+ le32 = cpu_to_le32(xlnx_efuse_get_row(s, bit));
403
+
404
+ row_offset = (bit / 32) * 4;
405
+ if (blk_pwrite(s->blk, row_offset, &le32, 4, 0) < 0) {
406
+ error_report("%s: Failed to write offset %u of eFUSE backstore.",
407
+ blk_name(s->blk), row_offset);
408
+ }
409
+}
410
+
411
+static int efuse_ro_bits_cmp(const void *a, const void *b)
412
+{
413
+ uint32_t i = *(const uint32_t *)a;
414
+ uint32_t j = *(const uint32_t *)b;
415
+
416
+ return (i > j) - (i < j);
417
+}
418
+
419
+static void efuse_ro_bits_sort(XlnxEFuse *s)
420
+{
421
+ uint32_t *ary = s->ro_bits;
422
+ const uint32_t cnt = s->ro_bits_cnt;
423
+
424
+ if (ary && cnt > 1) {
425
+ qsort(ary, cnt, sizeof(ary[0]), efuse_ro_bits_cmp);
426
+ }
427
+}
428
+
429
+static bool efuse_ro_bits_find(XlnxEFuse *s, uint32_t k)
430
+{
431
+ const uint32_t *ary = s->ro_bits;
432
+ const uint32_t cnt = s->ro_bits_cnt;
433
+
434
+ if (!ary || !cnt) {
435
+ return false;
436
+ }
437
+
438
+ return bsearch(&k, ary, cnt, sizeof(ary[0]), efuse_ro_bits_cmp) != NULL;
439
+}
440
+
441
+bool xlnx_efuse_set_bit(XlnxEFuse *s, unsigned int bit)
442
+{
443
+ if (efuse_ro_bits_find(s, bit)) {
444
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: WARN: "
445
+ "Ignored setting of readonly efuse bit<%u,%u>!\n",
446
+ object_get_canonical_path(OBJECT(s)),
447
+ (bit / 32), (bit % 32));
448
+ return false;
449
+ }
450
+
451
+ s->fuse32[bit / 32] |= 1 << (bit % 32);
452
+ efuse_bdrv_sync(s, bit);
453
+ return true;
454
+}
455
+
456
+bool xlnx_efuse_k256_check(XlnxEFuse *s, uint32_t crc, unsigned start)
457
+{
458
+ uint32_t calc;
459
+
460
+ /* A key always occupies multiple of whole rows */
461
+ assert((start % 32) == 0);
462
+
463
+ calc = xlnx_efuse_calc_crc(&s->fuse32[start / 32], (256 / 32), 0);
464
+ return calc == crc;
465
+}
466
+
467
+uint32_t xlnx_efuse_tbits_check(XlnxEFuse *s)
468
+{
469
+ int nr;
470
+ uint32_t check = 0;
471
+
472
+ for (nr = s->efuse_nr; nr-- > 0; ) {
473
+ int efuse_start_row_num = (s->efuse_size * nr) / 32;
474
+ uint32_t data = s->fuse32[efuse_start_row_num];
475
+
476
+ /*
477
+ * If the option is on, auto-init blank T-bits.
478
+ * (non-blank will still be reported as '0' in the check, e.g.,
479
+ * for error-injection tests)
480
+ */
481
+ if ((data & TBITS_MASK) == 0 && s->init_tbits) {
482
+ data |= TBITS_PATTERN;
483
+
484
+ s->fuse32[efuse_start_row_num] = data;
485
+ efuse_bdrv_sync(s, (efuse_start_row_num * 32 + TBIT0_OFFSET));
486
+ }
487
+
488
+ check = (check << 1) | ((data & TBITS_MASK) == TBITS_PATTERN);
489
+ }
490
+
491
+ return check;
492
+}
493
+
494
+static void efuse_realize(DeviceState *dev, Error **errp)
495
+{
496
+ XlnxEFuse *s = XLNX_EFUSE(dev);
497
+
498
+ /* Sort readonly-list for bsearch lookup */
499
+ efuse_ro_bits_sort(s);
500
+
501
+ if ((s->efuse_size % 32) != 0) {
502
+ error_setg(errp,
503
+ "%s.efuse-size: %u: property value not multiple of 32.",
504
+ object_get_canonical_path(OBJECT(dev)), s->efuse_size);
505
+ return;
319
+ return;
506
+ }
320
+ }
507
+
321
+
508
+ s->fuse32 = g_malloc0(efuse_bytes(s));
322
+ ri = g_new(struct SRCSCRResetInfo, 1);
509
+ if (efuse_bdrv_read(s, errp)) {
323
+ ri->s = s;
510
+ g_free(s->fuse32);
324
+ ri->reset_bit = reset_shift;
325
+
326
+ async_run_on_cpu(cpu, imx7_clear_reset_bit, RUN_ON_CPU_HOST_PTR(ri));
327
+}
328
+
329
+
330
+static void imx7_src_write(void *opaque, hwaddr offset, uint64_t value,
331
+ unsigned size)
332
+{
333
+ IMX7SRCState *s = (IMX7SRCState *)opaque;
334
+ uint32_t index = offset >> 2;
335
+ long unsigned int change_mask;
336
+ uint32_t current_value = value;
337
+
338
+ if (index >= SRC_MAX) {
339
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
340
+ HWADDR_PRIx "\n", TYPE_IMX7_SRC, __func__, offset);
341
+ return;
511
+ }
342
+ }
512
+}
343
+
513
+
344
+ trace_imx7_src_write(imx7_src_reg_name(SRC_A7RCR0), s->regs[SRC_A7RCR0]);
514
+static void efuse_prop_set_drive(Object *obj, Visitor *v, const char *name,
345
+
515
+ void *opaque, Error **errp)
346
+ change_mask = s->regs[index] ^ (uint32_t)current_value;
516
+{
347
+
517
+ DeviceState *dev = DEVICE(obj);
348
+ switch (index) {
518
+
349
+ case SRC_A7RCR0:
519
+ qdev_prop_drive.set(obj, v, name, opaque, errp);
350
+ if (FIELD_EX32(change_mask, CORE0, RST)) {
520
+
351
+ arm_reset_cpu(0);
521
+ /* Fill initial data if backend is attached after realized */
352
+ imx7_defer_clear_reset_bit(0, s, R_CORE0_RST_SHIFT);
522
+ if (dev->realized) {
353
+ }
523
+ efuse_bdrv_read(XLNX_EFUSE(obj), errp);
354
+ if (FIELD_EX32(change_mask, CORE1, RST)) {
355
+ arm_reset_cpu(1);
356
+ imx7_defer_clear_reset_bit(1, s, R_CORE1_RST_SHIFT);
357
+ }
358
+ s->regs[index] = current_value;
359
+ break;
360
+ case SRC_A7RCR1:
361
+ /*
362
+ * On real hardware when the system reset controller starts a
363
+ * secondary CPU it runs through some boot ROM code which reads
364
+ * the SRC_GPRX registers controlling the start address and branches
365
+ * to it.
366
+ * Here we are taking a short cut and branching directly to the
367
+ * requested address (we don't want to run the boot ROM code inside
368
+ * QEMU)
369
+ */
370
+ if (FIELD_EX32(change_mask, CORE1, ENABLE)) {
371
+ if (FIELD_EX32(current_value, CORE1, ENABLE)) {
372
+ /* CORE 1 is brought up */
373
+ arm_set_cpu_on(1, s->regs[SRC_GPR3], s->regs[SRC_GPR4],
374
+ 3, false);
375
+ } else {
376
+ /* CORE 1 is shut down */
377
+ arm_set_cpu_off(1);
378
+ }
379
+ /* We clear the reset bits as the processor changed state */
380
+ imx7_defer_clear_reset_bit(1, s, R_CORE1_RST_SHIFT);
381
+ clear_bit(R_CORE1_RST_SHIFT, &change_mask);
382
+ }
383
+ s->regs[index] = current_value;
384
+ break;
385
+ default:
386
+ s->regs[index] = current_value;
387
+ break;
524
+ }
388
+ }
525
+}
389
+}
526
+
390
+
527
+static void efuse_prop_get_drive(Object *obj, Visitor *v, const char *name,
391
+static const struct MemoryRegionOps imx7_src_ops = {
528
+ void *opaque, Error **errp)
392
+ .read = imx7_src_read,
529
+{
393
+ .write = imx7_src_write,
530
+ qdev_prop_drive.get(obj, v, name, opaque, errp);
394
+ .endianness = DEVICE_NATIVE_ENDIAN,
531
+}
395
+ .valid = {
532
+
396
+ /*
533
+static void efuse_prop_release_drive(Object *obj, const char *name,
397
+ * Our device would not work correctly if the guest was doing
534
+ void *opaque)
398
+ * unaligned access. This might not be a limitation on the real
535
+{
399
+ * device but in practice there is no reason for a guest to access
536
+ qdev_prop_drive.release(obj, name, opaque);
400
+ * this device unaligned.
537
+}
401
+ */
538
+
402
+ .min_access_size = 4,
539
+static const PropertyInfo efuse_prop_drive = {
403
+ .max_access_size = 4,
540
+ .name = "str",
404
+ .unaligned = false,
541
+ .description = "Node name or ID of a block device to use as eFUSE backend",
405
+ },
542
+ .realized_set_allowed = true,
543
+ .get = efuse_prop_get_drive,
544
+ .set = efuse_prop_set_drive,
545
+ .release = efuse_prop_release_drive,
546
+};
406
+};
547
+
407
+
548
+static Property efuse_properties[] = {
408
+static void imx7_src_realize(DeviceState *dev, Error **errp)
549
+ DEFINE_PROP("drive", XlnxEFuse, blk, efuse_prop_drive, BlockBackend *),
409
+{
550
+ DEFINE_PROP_UINT8("efuse-nr", XlnxEFuse, efuse_nr, 3),
410
+ IMX7SRCState *s = IMX7_SRC(dev);
551
+ DEFINE_PROP_UINT32("efuse-size", XlnxEFuse, efuse_size, 64 * 32),
411
+
552
+ DEFINE_PROP_BOOL("init-factory-tbits", XlnxEFuse, init_tbits, true),
412
+ memory_region_init_io(&s->iomem, OBJECT(dev), &imx7_src_ops, s,
553
+ DEFINE_PROP_ARRAY("read-only", XlnxEFuse, ro_bits_cnt, ro_bits,
413
+ TYPE_IMX7_SRC, 0x1000);
554
+ qdev_prop_uint32, uint32_t),
414
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
555
+ DEFINE_PROP_END_OF_LIST(),
415
+}
416
+
417
+static void imx7_src_class_init(ObjectClass *klass, void *data)
418
+{
419
+ DeviceClass *dc = DEVICE_CLASS(klass);
420
+
421
+ dc->realize = imx7_src_realize;
422
+ dc->reset = imx7_src_reset;
423
+ dc->vmsd = &vmstate_imx7_src;
424
+ dc->desc = "i.MX6 System Reset Controller";
425
+}
426
+
427
+static const TypeInfo imx7_src_info = {
428
+ .name = TYPE_IMX7_SRC,
429
+ .parent = TYPE_SYS_BUS_DEVICE,
430
+ .instance_size = sizeof(IMX7SRCState),
431
+ .class_init = imx7_src_class_init,
556
+};
432
+};
557
+
433
+
558
+static void efuse_class_init(ObjectClass *klass, void *data)
434
+static void imx7_src_register_types(void)
559
+{
435
+{
560
+ DeviceClass *dc = DEVICE_CLASS(klass);
436
+ type_register_static(&imx7_src_info);
561
+
437
+}
562
+ dc->realize = efuse_realize;
438
+
563
+ device_class_set_props(dc, efuse_properties);
439
+type_init(imx7_src_register_types)
564
+}
440
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
565
+
566
+static const TypeInfo efuse_info = {
567
+ .name = TYPE_XLNX_EFUSE,
568
+ .parent = TYPE_DEVICE,
569
+ .instance_size = sizeof(XlnxEFuse),
570
+ .class_init = efuse_class_init,
571
+};
572
+
573
+static void efuse_register_types(void)
574
+{
575
+ type_register_static(&efuse_info);
576
+}
577
+type_init(efuse_register_types)
578
diff --git a/hw/nvram/Kconfig b/hw/nvram/Kconfig
579
index XXXXXXX..XXXXXXX 100644
441
index XXXXXXX..XXXXXXX 100644
580
--- a/hw/nvram/Kconfig
442
--- a/hw/misc/meson.build
581
+++ b/hw/nvram/Kconfig
443
+++ b/hw/misc/meson.build
582
@@ -XXX,XX +XXX,XX @@ config NMC93XX_EEPROM
444
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_IMX', if_true: files(
583
445
'imx6_src.c',
584
config CHRP_NVRAM
446
'imx6ul_ccm.c',
585
bool
447
'imx7_ccm.c',
586
+
448
+ 'imx7_src.c',
587
+config XLNX_EFUSE_CRC
449
'imx7_gpr.c',
588
+ bool
450
'imx7_snvs.c',
589
+
451
'imx_ccm.c',
590
+config XLNX_EFUSE
452
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
591
+ bool
592
+ select XLNX_EFUSE_CRC
593
diff --git a/hw/nvram/meson.build b/hw/nvram/meson.build
594
index XXXXXXX..XXXXXXX 100644
453
index XXXXXXX..XXXXXXX 100644
595
--- a/hw/nvram/meson.build
454
--- a/hw/misc/trace-events
596
+++ b/hw/nvram/meson.build
455
+++ b/hw/misc/trace-events
597
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_AT24C', if_true: files('eeprom_at24c.c'))
456
@@ -XXX,XX +XXX,XX @@ ccm_clock_freq(uint32_t clock, uint32_t freq) "(Clock = %d) = %d"
598
softmmu_ss.add(when: 'CONFIG_MAC_NVRAM', if_true: files('mac_nvram.c'))
457
ccm_read_reg(const char *reg_name, uint32_t value) "reg[%s] <= 0x%" PRIx32
599
softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_otp.c'))
458
ccm_write_reg(const char *reg_name, uint32_t value) "reg[%s] => 0x%" PRIx32
600
softmmu_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_nvm.c'))
459
601
+softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE_CRC', if_true: files('xlnx-efuse-crc.c'))
460
+# imx7_src.c
602
+softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE', if_true: files('xlnx-efuse.c'))
461
+imx7_src_read(const char *reg_name, uint32_t value) "reg[%s] => 0x%" PRIx32
603
462
+imx7_src_write(const char *reg_name, uint32_t value) "reg[%s] <= 0x%" PRIx32
604
specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_nvram.c'))
463
+
464
# iotkit-sysinfo.c
465
iotkit_sysinfo_read(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysInfo read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
466
iotkit_sysinfo_write(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysInfo write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
605
--
467
--
606
2.20.1
468
2.34.1
607
608
diff view generated by jsdifflib
1
Currently we send VFP XML which includes D0..D15 or D0..D31, plus
1
The architecture requires (R_TYTWB) that an attempt to return from EL3
2
FPSID, FPSCR and FPEXC. The upstream GDB tolerates this, but its
2
when SCR_EL3.{NSE,NS} are {1,0} is an illegal exception return. (This
3
definition of this XML feature does not include FPSID or FPEXC. In
3
enforces that the CPU can't ever be executing below EL3 with the
4
particular, for M-profile cores there are no FPSID or FPEXC
4
NSE,NS bits indicating an invalid security state.)
5
registers, so advertising those is wrong.
6
5
7
Move FPSID and FPEXC into their own bit of XML which we only send for
6
We were missing this check; add it.
8
A and R profile cores. This brings our definition of the XML
9
org.gnu.gdb.arm.vfp feature into line with GDB's own (at least for
10
non-Neon cores...) and means we don't claim to have FPSID and FPEXC
11
on M-profile.
12
13
(It seems unlikely to me that any gdbstub users really care about
14
being able to look at FPEXC and FPSID; but we've supplied them to gdb
15
for a decade and it's not hard to keep doing so.)
16
7
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210921162901.17508-5-peter.maydell@linaro.org
10
Message-id: 20230807150618.101357-1-peter.maydell@linaro.org
20
---
11
---
21
configs/targets/aarch64-softmmu.mak | 2 +-
12
target/arm/tcg/helper-a64.c | 9 +++++++++
22
configs/targets/arm-linux-user.mak | 2 +-
13
1 file changed, 9 insertions(+)
23
configs/targets/arm-softmmu.mak | 2 +-
24
configs/targets/armeb-linux-user.mak | 2 +-
25
target/arm/gdbstub.c | 56 ++++++++++++++++++++--------
26
gdb-xml/arm-neon.xml | 2 -
27
gdb-xml/arm-vfp-sysregs.xml | 17 +++++++++
28
gdb-xml/arm-vfp.xml | 2 -
29
gdb-xml/arm-vfp3.xml | 2 -
30
9 files changed, 61 insertions(+), 26 deletions(-)
31
create mode 100644 gdb-xml/arm-vfp-sysregs.xml
32
14
33
diff --git a/configs/targets/aarch64-softmmu.mak b/configs/targets/aarch64-softmmu.mak
15
diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c
34
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
35
--- a/configs/targets/aarch64-softmmu.mak
17
--- a/target/arm/tcg/helper-a64.c
36
+++ b/configs/targets/aarch64-softmmu.mak
18
+++ b/target/arm/tcg/helper-a64.c
37
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
38
TARGET_ARCH=aarch64
20
spsr &= ~PSTATE_SS;
39
TARGET_BASE_ARCH=arm
40
TARGET_SUPPORTS_MTTCG=y
41
-TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml
42
+TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml
43
TARGET_NEED_FDT=y
44
diff --git a/configs/targets/arm-linux-user.mak b/configs/targets/arm-linux-user.mak
45
index XXXXXXX..XXXXXXX 100644
46
--- a/configs/targets/arm-linux-user.mak
47
+++ b/configs/targets/arm-linux-user.mak
48
@@ -XXX,XX +XXX,XX @@
49
TARGET_ARCH=arm
50
TARGET_SYSTBL_ABI=common,oabi
51
TARGET_SYSTBL=syscall.tbl
52
-TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml
53
+TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml
54
TARGET_HAS_BFLT=y
55
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
56
diff --git a/configs/targets/arm-softmmu.mak b/configs/targets/arm-softmmu.mak
57
index XXXXXXX..XXXXXXX 100644
58
--- a/configs/targets/arm-softmmu.mak
59
+++ b/configs/targets/arm-softmmu.mak
60
@@ -XXX,XX +XXX,XX @@
61
TARGET_ARCH=arm
62
TARGET_SUPPORTS_MTTCG=y
63
-TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml
64
+TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml
65
TARGET_NEED_FDT=y
66
diff --git a/configs/targets/armeb-linux-user.mak b/configs/targets/armeb-linux-user.mak
67
index XXXXXXX..XXXXXXX 100644
68
--- a/configs/targets/armeb-linux-user.mak
69
+++ b/configs/targets/armeb-linux-user.mak
70
@@ -XXX,XX +XXX,XX @@ TARGET_ARCH=arm
71
TARGET_SYSTBL_ABI=common,oabi
72
TARGET_SYSTBL=syscall.tbl
73
TARGET_WORDS_BIGENDIAN=y
74
-TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml
75
+TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml
76
TARGET_HAS_BFLT=y
77
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
78
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/arm/gdbstub.c
81
+++ b/target/arm/gdbstub.c
82
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
83
}
21
}
84
switch (reg - nregs) {
22
85
case 0:
23
+ /*
86
- return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]);
24
+ * FEAT_RME forbids return from EL3 with an invalid security state.
87
- case 1:
25
+ * We don't need an explicit check for FEAT_RME here because we enforce
88
return gdb_get_reg32(buf, vfp_get_fpscr(env));
26
+ * in scr_write() that you can't set the NSE bit without it.
89
- case 2:
27
+ */
90
- return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]);
28
+ if (cur_el == 3 && (env->cp15.scr_el3 & (SCR_NS | SCR_NSE)) == SCR_NSE) {
91
}
29
+ goto illegal_return;
92
return 0;
93
}
94
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
95
}
96
}
97
switch (reg - nregs) {
98
+ case 0:
99
+ vfp_set_fpscr(env, ldl_p(buf));
100
+ return 4;
101
+ }
30
+ }
102
+ return 0;
103
+}
104
+
31
+
105
+static int vfp_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg)
32
new_el = el_from_spsr(spsr);
106
+{
33
if (new_el == -1) {
107
+ switch (reg) {
34
goto illegal_return;
108
+ case 0:
109
+ return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]);
110
+ case 1:
111
+ return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]);
112
+ }
113
+ return 0;
114
+}
115
+
116
+static int vfp_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg)
117
+{
118
+ switch (reg) {
119
case 0:
120
env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf);
121
return 4;
122
case 1:
123
- vfp_set_fpscr(env, ldl_p(buf));
124
- return 4;
125
- case 2:
126
env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30);
127
return 4;
128
}
129
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
130
34, "aarch64-fpu.xml", 0);
131
}
132
#endif
133
- } else if (arm_feature(env, ARM_FEATURE_NEON)) {
134
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
135
- 51, "arm-neon.xml", 0);
136
- } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
137
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
138
- 35, "arm-vfp3.xml", 0);
139
- } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
140
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
141
- 19, "arm-vfp.xml", 0);
142
+ } else {
143
+ if (arm_feature(env, ARM_FEATURE_NEON)) {
144
+ gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
145
+ 49, "arm-neon.xml", 0);
146
+ } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
147
+ gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
148
+ 33, "arm-vfp3.xml", 0);
149
+ } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
150
+ gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
151
+ 17, "arm-vfp.xml", 0);
152
+ }
153
+ if (!arm_feature(env, ARM_FEATURE_M)) {
154
+ /*
155
+ * A and R profile have FP sysregs FPEXC and FPSID that we
156
+ * expose to gdb.
157
+ */
158
+ gdb_register_coprocessor(cs, vfp_gdb_get_sysreg, vfp_gdb_set_sysreg,
159
+ 2, "arm-vfp-sysregs.xml", 0);
160
+ }
161
}
162
gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
163
arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs),
164
diff --git a/gdb-xml/arm-neon.xml b/gdb-xml/arm-neon.xml
165
index XXXXXXX..XXXXXXX 100644
166
--- a/gdb-xml/arm-neon.xml
167
+++ b/gdb-xml/arm-neon.xml
168
@@ -XXX,XX +XXX,XX @@
169
<reg name="q14" bitsize="128" type="neon_q"/>
170
<reg name="q15" bitsize="128" type="neon_q"/>
171
172
- <reg name="fpsid" bitsize="32" type="int" group="float"/>
173
<reg name="fpscr" bitsize="32" type="int" group="float"/>
174
- <reg name="fpexc" bitsize="32" type="int" group="float"/>
175
</feature>
176
diff --git a/gdb-xml/arm-vfp-sysregs.xml b/gdb-xml/arm-vfp-sysregs.xml
177
new file mode 100644
178
index XXXXXXX..XXXXXXX
179
--- /dev/null
180
+++ b/gdb-xml/arm-vfp-sysregs.xml
181
@@ -XXX,XX +XXX,XX @@
182
+<?xml version="1.0"?>
183
+<!-- Copyright (C) 2021 Linaro Ltd.
184
+
185
+ Copying and distribution of this file, with or without modification,
186
+ are permitted in any medium without royalty provided the copyright
187
+ notice and this notice are preserved.
188
+
189
+ These are A/R profile VFP system registers. Debugger users probably
190
+ don't really care about these, but because we used to (incorrectly)
191
+ provide them to gdb in the org.gnu.gdb.arm.vfp XML we continue
192
+ to do so via this separate XML.
193
+ -->
194
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
195
+<feature name="org.qemu.gdb.arm.vfp-sysregs">
196
+ <reg name="fpsid" bitsize="32" type="int" group="float"/>
197
+ <reg name="fpexc" bitsize="32" type="int" group="float"/>
198
+</feature>
199
diff --git a/gdb-xml/arm-vfp.xml b/gdb-xml/arm-vfp.xml
200
index XXXXXXX..XXXXXXX 100644
201
--- a/gdb-xml/arm-vfp.xml
202
+++ b/gdb-xml/arm-vfp.xml
203
@@ -XXX,XX +XXX,XX @@
204
<reg name="d14" bitsize="64" type="float"/>
205
<reg name="d15" bitsize="64" type="float"/>
206
207
- <reg name="fpsid" bitsize="32" type="int" group="float"/>
208
<reg name="fpscr" bitsize="32" type="int" group="float"/>
209
- <reg name="fpexc" bitsize="32" type="int" group="float"/>
210
</feature>
211
diff --git a/gdb-xml/arm-vfp3.xml b/gdb-xml/arm-vfp3.xml
212
index XXXXXXX..XXXXXXX 100644
213
--- a/gdb-xml/arm-vfp3.xml
214
+++ b/gdb-xml/arm-vfp3.xml
215
@@ -XXX,XX +XXX,XX @@
216
<reg name="d30" bitsize="64" type="float"/>
217
<reg name="d31" bitsize="64" type="float"/>
218
219
- <reg name="fpsid" bitsize="32" type="int" group="float"/>
220
<reg name="fpscr" bitsize="32" type="int" group="float"/>
221
- <reg name="fpexc" bitsize="32" type="int" group="float"/>
222
</feature>
223
--
35
--
224
2.20.1
36
2.34.1
225
226
diff view generated by jsdifflib
1
The function ide_bus_new() does an in-place initialization. Rename
1
In the m48t59 device we almost always use 64-bit arithmetic when
2
it to ide_bus_init() to follow our _init vs _new convention.
2
dealing with time_t deltas. The one exception is in set_alarm(),
3
which currently uses a plain 'int' to hold the difference between two
4
time_t values. Switch to int64_t instead to avoid any possible
5
overflow issues.
3
6
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
7
Reviewed-by: Corey Minyard <cminyard@mvista.com>
8
Reviewed-by: John Snow <jsnow@redhat.com>
9
Acked-by: John Snow <jsnow@redhat.com> (Feel free to merge.)
10
Message-id: 20210923121153.23754-7-peter.maydell@linaro.org
11
---
9
---
12
include/hw/ide/internal.h | 4 ++--
10
hw/rtc/m48t59.c | 2 +-
13
hw/ide/ahci.c | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
14
hw/ide/cmd646.c | 2 +-
15
hw/ide/isa.c | 2 +-
16
hw/ide/macio.c | 2 +-
17
hw/ide/microdrive.c | 2 +-
18
hw/ide/mmio.c | 2 +-
19
hw/ide/piix.c | 2 +-
20
hw/ide/qdev.c | 2 +-
21
hw/ide/sii3112.c | 2 +-
22
hw/ide/via.c | 2 +-
23
11 files changed, 12 insertions(+), 12 deletions(-)
24
12
25
diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
13
diff --git a/hw/rtc/m48t59.c b/hw/rtc/m48t59.c
26
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/ide/internal.h
15
--- a/hw/rtc/m48t59.c
28
+++ b/include/hw/ide/internal.h
16
+++ b/hw/rtc/m48t59.c
29
@@ -XXX,XX +XXX,XX @@ void ide_atapi_cmd(IDEState *s);
17
@@ -XXX,XX +XXX,XX @@ static void alarm_cb (void *opaque)
30
void ide_atapi_cmd_reply_end(IDEState *s);
18
31
19
static void set_alarm(M48t59State *NVRAM)
32
/* hw/ide/qdev.c */
33
-void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
34
- int bus_id, int max_units);
35
+void ide_bus_init(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
36
+ int bus_id, int max_units);
37
IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);
38
39
int ide_handle_rw_error(IDEState *s, int error, int op);
40
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/ide/ahci.c
43
+++ b/hw/ide/ahci.c
44
@@ -XXX,XX +XXX,XX @@ void ahci_realize(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports)
45
for (i = 0; i < s->ports; i++) {
46
AHCIDevice *ad = &s->dev[i];
47
48
- ide_bus_new(&ad->port, sizeof(ad->port), qdev, i, 1);
49
+ ide_bus_init(&ad->port, sizeof(ad->port), qdev, i, 1);
50
ide_init2(&ad->port, irqs[i]);
51
52
ad->hba = s;
53
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/ide/cmd646.c
56
+++ b/hw/ide/cmd646.c
57
@@ -XXX,XX +XXX,XX @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
58
59
qdev_init_gpio_in(ds, cmd646_set_irq, 2);
60
for (i = 0; i < 2; i++) {
61
- ide_bus_new(&d->bus[i], sizeof(d->bus[i]), ds, i, 2);
62
+ ide_bus_init(&d->bus[i], sizeof(d->bus[i]), ds, i, 2);
63
ide_init2(&d->bus[i], qdev_get_gpio_in(ds, i));
64
65
bmdma_init(&d->bus[i], &d->bmdma[i], d);
66
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/ide/isa.c
69
+++ b/hw/ide/isa.c
70
@@ -XXX,XX +XXX,XX @@ static void isa_ide_realizefn(DeviceState *dev, Error **errp)
71
ISADevice *isadev = ISA_DEVICE(dev);
72
ISAIDEState *s = ISA_IDE(dev);
73
74
- ide_bus_new(&s->bus, sizeof(s->bus), dev, 0, 2);
75
+ ide_bus_init(&s->bus, sizeof(s->bus), dev, 0, 2);
76
ide_init_ioport(&s->bus, isadev, s->iobase, s->iobase2);
77
isa_init_irq(isadev, &s->irq, s->isairq);
78
ide_init2(&s->bus, s->irq);
79
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/ide/macio.c
82
+++ b/hw/ide/macio.c
83
@@ -XXX,XX +XXX,XX @@ static void macio_ide_initfn(Object *obj)
84
SysBusDevice *d = SYS_BUS_DEVICE(obj);
85
MACIOIDEState *s = MACIO_IDE(obj);
86
87
- ide_bus_new(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
88
+ ide_bus_init(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
89
memory_region_init_io(&s->mem, obj, &pmac_ide_ops, s, "pmac-ide", 0x1000);
90
sysbus_init_mmio(d, &s->mem);
91
sysbus_init_irq(d, &s->real_ide_irq);
92
diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/ide/microdrive.c
95
+++ b/hw/ide/microdrive.c
96
@@ -XXX,XX +XXX,XX @@ static void microdrive_init(Object *obj)
97
{
20
{
98
MicroDriveState *md = MICRODRIVE(obj);
21
- int diff;
99
22
+ int64_t diff;
100
- ide_bus_new(&md->bus, sizeof(md->bus), DEVICE(obj), 0, 1);
23
if (NVRAM->alrm_timer != NULL) {
101
+ ide_bus_init(&md->bus, sizeof(md->bus), DEVICE(obj), 0, 1);
24
timer_del(NVRAM->alrm_timer);
102
}
25
diff = qemu_timedate_diff(&NVRAM->alarm) - NVRAM->time_offset;
103
104
static void microdrive_class_init(ObjectClass *oc, void *data)
105
diff --git a/hw/ide/mmio.c b/hw/ide/mmio.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/hw/ide/mmio.c
108
+++ b/hw/ide/mmio.c
109
@@ -XXX,XX +XXX,XX @@ static void mmio_ide_initfn(Object *obj)
110
SysBusDevice *d = SYS_BUS_DEVICE(obj);
111
MMIOState *s = MMIO_IDE(obj);
112
113
- ide_bus_new(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
114
+ ide_bus_init(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
115
sysbus_init_irq(d, &s->irq);
116
}
117
118
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
119
index XXXXXXX..XXXXXXX 100644
120
--- a/hw/ide/piix.c
121
+++ b/hw/ide/piix.c
122
@@ -XXX,XX +XXX,XX @@ static int pci_piix_init_ports(PCIIDEState *d)
123
int i, ret;
124
125
for (i = 0; i < 2; i++) {
126
- ide_bus_new(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
127
+ ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
128
ret = ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
129
port_info[i].iobase2);
130
if (ret) {
131
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/hw/ide/qdev.c
134
+++ b/hw/ide/qdev.c
135
@@ -XXX,XX +XXX,XX @@ static const TypeInfo ide_bus_info = {
136
.class_init = ide_bus_class_init,
137
};
138
139
-void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
140
+void ide_bus_init(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
141
int bus_id, int max_units)
142
{
143
qbus_init(idebus, idebus_size, TYPE_IDE_BUS, dev, NULL);
144
diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/hw/ide/sii3112.c
147
+++ b/hw/ide/sii3112.c
148
@@ -XXX,XX +XXX,XX @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
149
150
qdev_init_gpio_in(ds, sii3112_set_irq, 2);
151
for (i = 0; i < 2; i++) {
152
- ide_bus_new(&s->bus[i], sizeof(s->bus[i]), ds, i, 1);
153
+ ide_bus_init(&s->bus[i], sizeof(s->bus[i]), ds, i, 1);
154
ide_init2(&s->bus[i], qdev_get_gpio_in(ds, i));
155
156
bmdma_init(&s->bus[i], &s->bmdma[i], s);
157
diff --git a/hw/ide/via.c b/hw/ide/via.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/hw/ide/via.c
160
+++ b/hw/ide/via.c
161
@@ -XXX,XX +XXX,XX @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
162
163
qdev_init_gpio_in(ds, via_ide_set_irq, 2);
164
for (i = 0; i < 2; i++) {
165
- ide_bus_new(&d->bus[i], sizeof(d->bus[i]), ds, i, 2);
166
+ ide_bus_init(&d->bus[i], sizeof(d->bus[i]), ds, i, 2);
167
ide_init2(&d->bus[i], qdev_get_gpio_in(ds, i));
168
169
bmdma_init(&d->bus[i], &d->bmdma[i], d);
170
--
26
--
171
2.20.1
27
2.34.1
172
28
173
29
diff view generated by jsdifflib
1
Rename qbus_create_inplace() to qbus_init(); this is more in line
1
In the twl92230 device, use int64_t for the two state fields
2
with our usual naming convention for functions that in-place
2
sec_offset and alm_sec, because we set these to values that
3
initialize objects.
3
are either time_t or differences between two time_t values.
4
5
These fields aren't saved in vmstate anywhere, so we can
6
safely widen them.
4
7
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
8
Message-id: 20210923121153.23754-5-peter.maydell@linaro.org
9
---
10
---
10
include/hw/qdev-core.h | 4 ++--
11
hw/rtc/twl92230.c | 4 ++--
11
hw/audio/intel-hda.c | 2 +-
12
1 file changed, 2 insertions(+), 2 deletions(-)
12
hw/block/fdc.c | 2 +-
13
hw/block/swim.c | 3 +--
14
hw/char/virtio-serial-bus.c | 4 ++--
15
hw/core/bus.c | 11 ++++++-----
16
hw/core/sysbus.c | 10 ++++++----
17
hw/gpio/bcm2835_gpio.c | 3 +--
18
hw/ide/qdev.c | 2 +-
19
hw/ipack/ipack.c | 2 +-
20
hw/misc/mac_via.c | 4 ++--
21
hw/misc/macio/cuda.c | 4 ++--
22
hw/misc/macio/macio.c | 4 ++--
23
hw/misc/macio/pmu.c | 4 ++--
24
hw/nubus/nubus-bridge.c | 2 +-
25
hw/nvme/ctrl.c | 4 ++--
26
hw/nvme/subsys.c | 3 +--
27
hw/pci/pci.c | 2 +-
28
hw/pci/pci_bridge.c | 4 ++--
29
hw/s390x/event-facility.c | 4 ++--
30
hw/s390x/virtio-ccw.c | 3 +--
31
hw/scsi/scsi-bus.c | 2 +-
32
hw/sd/allwinner-sdhost.c | 4 ++--
33
hw/sd/bcm2835_sdhost.c | 4 ++--
34
hw/sd/pl181.c | 3 +--
35
hw/sd/pxa2xx_mmci.c | 4 ++--
36
hw/sd/sdhci.c | 3 +--
37
hw/sd/ssi-sd.c | 3 +--
38
hw/usb/bus.c | 2 +-
39
hw/usb/dev-smartcard-reader.c | 3 +--
40
hw/virtio/virtio-mmio.c | 3 +--
41
hw/virtio/virtio-pci.c | 3 +--
42
32 files changed, 54 insertions(+), 61 deletions(-)
43
13
44
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
14
diff --git a/hw/rtc/twl92230.c b/hw/rtc/twl92230.c
45
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
46
--- a/include/hw/qdev-core.h
16
--- a/hw/rtc/twl92230.c
47
+++ b/include/hw/qdev-core.h
17
+++ b/hw/rtc/twl92230.c
48
@@ -XXX,XX +XXX,XX @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id);
18
@@ -XXX,XX +XXX,XX @@ struct MenelausState {
49
typedef int (qbus_walkerfn)(BusState *bus, void *opaque);
19
struct tm tm;
50
typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque);
20
struct tm new;
51
21
struct tm alm;
52
-void qbus_create_inplace(void *bus, size_t size, const char *typename,
22
- int sec_offset;
53
- DeviceState *parent, const char *name);
23
- int alm_sec;
54
+void qbus_init(void *bus, size_t size, const char *typename,
24
+ int64_t sec_offset;
55
+ DeviceState *parent, const char *name);
25
+ int64_t alm_sec;
56
BusState *qbus_create(const char *typename, DeviceState *parent, const char *name);
26
int next_comp;
57
bool qbus_realize(BusState *bus, Error **errp);
27
} rtc;
58
void qbus_unrealize(BusState *bus);
28
uint16_t rtc_next_vmstate;
59
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/audio/intel-hda.c
62
+++ b/hw/audio/intel-hda.c
63
@@ -XXX,XX +XXX,XX @@ void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, size_t bus_size,
64
hda_codec_response_func response,
65
hda_codec_xfer_func xfer)
66
{
67
- qbus_create_inplace(bus, bus_size, TYPE_HDA_BUS, dev, NULL);
68
+ qbus_init(bus, bus_size, TYPE_HDA_BUS, dev, NULL);
69
bus->response = response;
70
bus->xfer = xfer;
71
}
72
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/block/fdc.c
75
+++ b/hw/block/fdc.c
76
@@ -XXX,XX +XXX,XX @@ static const TypeInfo floppy_bus_info = {
77
78
static void floppy_bus_create(FDCtrl *fdc, FloppyBus *bus, DeviceState *dev)
79
{
80
- qbus_create_inplace(bus, sizeof(FloppyBus), TYPE_FLOPPY_BUS, dev, NULL);
81
+ qbus_init(bus, sizeof(FloppyBus), TYPE_FLOPPY_BUS, dev, NULL);
82
bus->fdc = fdc;
83
}
84
85
diff --git a/hw/block/swim.c b/hw/block/swim.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/hw/block/swim.c
88
+++ b/hw/block/swim.c
89
@@ -XXX,XX +XXX,XX @@ static void sysbus_swim_realize(DeviceState *dev, Error **errp)
90
Swim *sys = SWIM(dev);
91
SWIMCtrl *swimctrl = &sys->ctrl;
92
93
- qbus_create_inplace(&swimctrl->bus, sizeof(SWIMBus), TYPE_SWIM_BUS, dev,
94
- NULL);
95
+ qbus_init(&swimctrl->bus, sizeof(SWIMBus), TYPE_SWIM_BUS, dev, NULL);
96
swimctrl->bus.ctrl = swimctrl;
97
}
98
99
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/hw/char/virtio-serial-bus.c
102
+++ b/hw/char/virtio-serial-bus.c
103
@@ -XXX,XX +XXX,XX @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
104
config_size);
105
106
/* Spawn a new virtio-serial bus on which the ports will ride as devices */
107
- qbus_create_inplace(&vser->bus, sizeof(vser->bus), TYPE_VIRTIO_SERIAL_BUS,
108
- dev, vdev->bus_name);
109
+ qbus_init(&vser->bus, sizeof(vser->bus), TYPE_VIRTIO_SERIAL_BUS,
110
+ dev, vdev->bus_name);
111
qbus_set_hotplug_handler(BUS(&vser->bus), OBJECT(vser));
112
vser->bus.vser = vser;
113
QTAILQ_INIT(&vser->ports);
114
diff --git a/hw/core/bus.c b/hw/core/bus.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/hw/core/bus.c
117
+++ b/hw/core/bus.c
118
@@ -XXX,XX +XXX,XX @@ static void bus_reset_child_foreach(Object *obj, ResettableChildCallback cb,
119
}
120
}
121
122
-static void qbus_init(BusState *bus, DeviceState *parent, const char *name)
123
+static void qbus_init_internal(BusState *bus, DeviceState *parent,
124
+ const char *name)
125
{
126
const char *typename = object_get_typename(OBJECT(bus));
127
BusClass *bc;
128
@@ -XXX,XX +XXX,XX @@ static void bus_unparent(Object *obj)
129
bus->parent = NULL;
130
}
131
132
-void qbus_create_inplace(void *bus, size_t size, const char *typename,
133
- DeviceState *parent, const char *name)
134
+void qbus_init(void *bus, size_t size, const char *typename,
135
+ DeviceState *parent, const char *name)
136
{
137
object_initialize(bus, size, typename);
138
- qbus_init(bus, parent, name);
139
+ qbus_init_internal(bus, parent, name);
140
}
141
142
BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
143
@@ -XXX,XX +XXX,XX @@ BusState *qbus_create(const char *typename, DeviceState *parent, const char *nam
144
BusState *bus;
145
146
bus = BUS(object_new(typename));
147
- qbus_init(bus, parent, name);
148
+ qbus_init_internal(bus, parent, name);
149
150
return bus;
151
}
152
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/hw/core/sysbus.c
155
+++ b/hw/core/sysbus.c
156
@@ -XXX,XX +XXX,XX @@ static BusState *main_system_bus;
157
158
static void main_system_bus_create(void)
159
{
160
- /* assign main_system_bus before qbus_create_inplace()
161
- * in order to make "if (bus != sysbus_get_default())" work */
162
+ /*
163
+ * assign main_system_bus before qbus_init()
164
+ * in order to make "if (bus != sysbus_get_default())" work
165
+ */
166
main_system_bus = g_malloc0(system_bus_info.instance_size);
167
- qbus_create_inplace(main_system_bus, system_bus_info.instance_size,
168
- TYPE_SYSTEM_BUS, NULL, "main-system-bus");
169
+ qbus_init(main_system_bus, system_bus_info.instance_size,
170
+ TYPE_SYSTEM_BUS, NULL, "main-system-bus");
171
OBJECT(main_system_bus)->free = g_free;
172
}
173
174
diff --git a/hw/gpio/bcm2835_gpio.c b/hw/gpio/bcm2835_gpio.c
175
index XXXXXXX..XXXXXXX 100644
176
--- a/hw/gpio/bcm2835_gpio.c
177
+++ b/hw/gpio/bcm2835_gpio.c
178
@@ -XXX,XX +XXX,XX @@ static void bcm2835_gpio_init(Object *obj)
179
DeviceState *dev = DEVICE(obj);
180
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
181
182
- qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
183
- TYPE_SD_BUS, DEVICE(s), "sd-bus");
184
+ qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_SD_BUS, DEVICE(s), "sd-bus");
185
186
memory_region_init_io(&s->iomem, obj,
187
&bcm2835_gpio_ops, s, "bcm2835_gpio", 0x1000);
188
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
189
index XXXXXXX..XXXXXXX 100644
190
--- a/hw/ide/qdev.c
191
+++ b/hw/ide/qdev.c
192
@@ -XXX,XX +XXX,XX @@ static const TypeInfo ide_bus_info = {
193
void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
194
int bus_id, int max_units)
195
{
196
- qbus_create_inplace(idebus, idebus_size, TYPE_IDE_BUS, dev, NULL);
197
+ qbus_init(idebus, idebus_size, TYPE_IDE_BUS, dev, NULL);
198
idebus->bus_id = bus_id;
199
idebus->max_units = max_units;
200
}
201
diff --git a/hw/ipack/ipack.c b/hw/ipack/ipack.c
202
index XXXXXXX..XXXXXXX 100644
203
--- a/hw/ipack/ipack.c
204
+++ b/hw/ipack/ipack.c
205
@@ -XXX,XX +XXX,XX @@ void ipack_bus_init(IPackBus *bus, size_t bus_size,
206
uint8_t n_slots,
207
qemu_irq_handler handler)
208
{
209
- qbus_create_inplace(bus, bus_size, TYPE_IPACK_BUS, parent, NULL);
210
+ qbus_init(bus, bus_size, TYPE_IPACK_BUS, parent, NULL);
211
bus->n_slots = n_slots;
212
bus->set_irq = handler;
213
}
214
diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
215
index XXXXXXX..XXXXXXX 100644
216
--- a/hw/misc/mac_via.c
217
+++ b/hw/misc/mac_via.c
218
@@ -XXX,XX +XXX,XX @@ static void mos6522_q800_via1_init(Object *obj)
219
sysbus_init_mmio(sbd, &v1s->via_mem);
220
221
/* ADB */
222
- qbus_create_inplace((BusState *)&v1s->adb_bus, sizeof(v1s->adb_bus),
223
- TYPE_ADB_BUS, DEVICE(v1s), "adb.0");
224
+ qbus_init((BusState *)&v1s->adb_bus, sizeof(v1s->adb_bus),
225
+ TYPE_ADB_BUS, DEVICE(v1s), "adb.0");
226
227
qdev_init_gpio_in(DEVICE(obj), via1_irq_request, VIA1_IRQ_NB);
228
}
229
diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
230
index XXXXXXX..XXXXXXX 100644
231
--- a/hw/misc/macio/cuda.c
232
+++ b/hw/misc/macio/cuda.c
233
@@ -XXX,XX +XXX,XX @@ static void cuda_init(Object *obj)
234
memory_region_init_io(&s->mem, obj, &mos6522_cuda_ops, s, "cuda", 0x2000);
235
sysbus_init_mmio(sbd, &s->mem);
236
237
- qbus_create_inplace(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
238
- DEVICE(obj), "adb.0");
239
+ qbus_init(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
240
+ DEVICE(obj), "adb.0");
241
}
242
243
static Property cuda_properties[] = {
244
diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
245
index XXXXXXX..XXXXXXX 100644
246
--- a/hw/misc/macio/macio.c
247
+++ b/hw/misc/macio/macio.c
248
@@ -XXX,XX +XXX,XX @@ static void macio_instance_init(Object *obj)
249
250
memory_region_init(&s->bar, obj, "macio", 0x80000);
251
252
- qbus_create_inplace(&s->macio_bus, sizeof(s->macio_bus), TYPE_MACIO_BUS,
253
- DEVICE(obj), "macio.0");
254
+ qbus_init(&s->macio_bus, sizeof(s->macio_bus), TYPE_MACIO_BUS,
255
+ DEVICE(obj), "macio.0");
256
257
object_initialize_child(OBJECT(s), "dbdma", &s->dbdma, TYPE_MAC_DBDMA);
258
259
diff --git a/hw/misc/macio/pmu.c b/hw/misc/macio/pmu.c
260
index XXXXXXX..XXXXXXX 100644
261
--- a/hw/misc/macio/pmu.c
262
+++ b/hw/misc/macio/pmu.c
263
@@ -XXX,XX +XXX,XX @@ static void pmu_realize(DeviceState *dev, Error **errp)
264
timer_mod(s->one_sec_timer, s->one_sec_target);
265
266
if (s->has_adb) {
267
- qbus_create_inplace(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
268
- dev, "adb.0");
269
+ qbus_init(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
270
+ dev, "adb.0");
271
adb_register_autopoll_callback(adb_bus, pmu_adb_poll, s);
272
}
273
}
274
diff --git a/hw/nubus/nubus-bridge.c b/hw/nubus/nubus-bridge.c
275
index XXXXXXX..XXXXXXX 100644
276
--- a/hw/nubus/nubus-bridge.c
277
+++ b/hw/nubus/nubus-bridge.c
278
@@ -XXX,XX +XXX,XX @@ static void nubus_bridge_init(Object *obj)
279
NubusBridge *s = NUBUS_BRIDGE(obj);
280
NubusBus *bus = &s->bus;
281
282
- qbus_create_inplace(bus, sizeof(s->bus), TYPE_NUBUS_BUS, DEVICE(s), NULL);
283
+ qbus_init(bus, sizeof(s->bus), TYPE_NUBUS_BUS, DEVICE(s), NULL);
284
285
qdev_init_gpio_out(DEVICE(s), bus->irqs, NUBUS_IRQS);
286
}
287
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
288
index XXXXXXX..XXXXXXX 100644
289
--- a/hw/nvme/ctrl.c
290
+++ b/hw/nvme/ctrl.c
291
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
292
return;
293
}
294
295
- qbus_create_inplace(&n->bus, sizeof(NvmeBus), TYPE_NVME_BUS,
296
- &pci_dev->qdev, n->parent_obj.qdev.id);
297
+ qbus_init(&n->bus, sizeof(NvmeBus), TYPE_NVME_BUS,
298
+ &pci_dev->qdev, n->parent_obj.qdev.id);
299
300
nvme_init_state(n);
301
if (nvme_init_pci(n, pci_dev, errp)) {
302
diff --git a/hw/nvme/subsys.c b/hw/nvme/subsys.c
303
index XXXXXXX..XXXXXXX 100644
304
--- a/hw/nvme/subsys.c
305
+++ b/hw/nvme/subsys.c
306
@@ -XXX,XX +XXX,XX @@ static void nvme_subsys_realize(DeviceState *dev, Error **errp)
307
{
308
NvmeSubsystem *subsys = NVME_SUBSYS(dev);
309
310
- qbus_create_inplace(&subsys->bus, sizeof(NvmeBus), TYPE_NVME_BUS, dev,
311
- dev->id);
312
+ qbus_init(&subsys->bus, sizeof(NvmeBus), TYPE_NVME_BUS, dev, dev->id);
313
314
nvme_subsys_setup(subsys);
315
}
316
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
317
index XXXXXXX..XXXXXXX 100644
318
--- a/hw/pci/pci.c
319
+++ b/hw/pci/pci.c
320
@@ -XXX,XX +XXX,XX @@ void pci_root_bus_init(PCIBus *bus, size_t bus_size, DeviceState *parent,
321
MemoryRegion *address_space_io,
322
uint8_t devfn_min, const char *typename)
323
{
324
- qbus_create_inplace(bus, bus_size, typename, parent, name);
325
+ qbus_init(bus, bus_size, typename, parent, name);
326
pci_root_bus_internal_init(bus, parent, address_space_mem,
327
address_space_io, devfn_min);
328
}
329
diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
330
index XXXXXXX..XXXXXXX 100644
331
--- a/hw/pci/pci_bridge.c
332
+++ b/hw/pci/pci_bridge.c
333
@@ -XXX,XX +XXX,XX @@ void pci_bridge_initfn(PCIDevice *dev, const char *typename)
334
br->bus_name = dev->qdev.id;
335
}
336
337
- qbus_create_inplace(sec_bus, sizeof(br->sec_bus), typename, DEVICE(dev),
338
- br->bus_name);
339
+ qbus_init(sec_bus, sizeof(br->sec_bus), typename, DEVICE(dev),
340
+ br->bus_name);
341
sec_bus->parent_dev = dev;
342
sec_bus->map_irq = br->map_irq ? br->map_irq : pci_swizzle_map_irq_fn;
343
sec_bus->address_space_mem = &br->address_space_mem;
344
diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
345
index XXXXXXX..XXXXXXX 100644
346
--- a/hw/s390x/event-facility.c
347
+++ b/hw/s390x/event-facility.c
348
@@ -XXX,XX +XXX,XX @@ static void init_event_facility(Object *obj)
349
sclp_event_set_allow_all_mask_sizes);
350
351
/* Spawn a new bus for SCLP events */
352
- qbus_create_inplace(&event_facility->sbus, sizeof(event_facility->sbus),
353
- TYPE_SCLP_EVENTS_BUS, sdev, NULL);
354
+ qbus_init(&event_facility->sbus, sizeof(event_facility->sbus),
355
+ TYPE_SCLP_EVENTS_BUS, sdev, NULL);
356
357
object_initialize_child(obj, TYPE_SCLP_QUIESCE,
358
&event_facility->quiesce,
359
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
360
index XXXXXXX..XXXXXXX 100644
361
--- a/hw/s390x/virtio-ccw.c
362
+++ b/hw/s390x/virtio-ccw.c
363
@@ -XXX,XX +XXX,XX @@ static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
364
DeviceState *qdev = DEVICE(dev);
365
char virtio_bus_name[] = "virtio-bus";
366
367
- qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_CCW_BUS,
368
- qdev, virtio_bus_name);
369
+ qbus_init(bus, bus_size, TYPE_VIRTIO_CCW_BUS, qdev, virtio_bus_name);
370
}
371
372
static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data)
373
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
374
index XXXXXXX..XXXXXXX 100644
375
--- a/hw/scsi/scsi-bus.c
376
+++ b/hw/scsi/scsi-bus.c
377
@@ -XXX,XX +XXX,XX @@ void scsi_device_unit_attention_reported(SCSIDevice *s)
378
void scsi_bus_init_named(SCSIBus *bus, size_t bus_size, DeviceState *host,
379
const SCSIBusInfo *info, const char *bus_name)
380
{
381
- qbus_create_inplace(bus, bus_size, TYPE_SCSI_BUS, host, bus_name);
382
+ qbus_init(bus, bus_size, TYPE_SCSI_BUS, host, bus_name);
383
bus->busnr = next_scsi_bus++;
384
bus->info = info;
385
qbus_set_bus_hotplug_handler(BUS(bus));
386
diff --git a/hw/sd/allwinner-sdhost.c b/hw/sd/allwinner-sdhost.c
387
index XXXXXXX..XXXXXXX 100644
388
--- a/hw/sd/allwinner-sdhost.c
389
+++ b/hw/sd/allwinner-sdhost.c
390
@@ -XXX,XX +XXX,XX @@ static void allwinner_sdhost_init(Object *obj)
391
{
392
AwSdHostState *s = AW_SDHOST(obj);
393
394
- qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
395
- TYPE_AW_SDHOST_BUS, DEVICE(s), "sd-bus");
396
+ qbus_init(&s->sdbus, sizeof(s->sdbus),
397
+ TYPE_AW_SDHOST_BUS, DEVICE(s), "sd-bus");
398
399
memory_region_init_io(&s->iomem, obj, &allwinner_sdhost_ops, s,
400
TYPE_AW_SDHOST, 4 * KiB);
401
diff --git a/hw/sd/bcm2835_sdhost.c b/hw/sd/bcm2835_sdhost.c
402
index XXXXXXX..XXXXXXX 100644
403
--- a/hw/sd/bcm2835_sdhost.c
404
+++ b/hw/sd/bcm2835_sdhost.c
405
@@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_init(Object *obj)
406
{
407
BCM2835SDHostState *s = BCM2835_SDHOST(obj);
408
409
- qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
410
- TYPE_BCM2835_SDHOST_BUS, DEVICE(s), "sd-bus");
411
+ qbus_init(&s->sdbus, sizeof(s->sdbus),
412
+ TYPE_BCM2835_SDHOST_BUS, DEVICE(s), "sd-bus");
413
414
memory_region_init_io(&s->iomem, obj, &bcm2835_sdhost_ops, s,
415
TYPE_BCM2835_SDHOST, 0x1000);
416
diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
417
index XXXXXXX..XXXXXXX 100644
418
--- a/hw/sd/pl181.c
419
+++ b/hw/sd/pl181.c
420
@@ -XXX,XX +XXX,XX @@ static void pl181_init(Object *obj)
421
qdev_init_gpio_out_named(dev, &s->card_readonly, "card-read-only", 1);
422
qdev_init_gpio_out_named(dev, &s->card_inserted, "card-inserted", 1);
423
424
- qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
425
- TYPE_PL181_BUS, dev, "sd-bus");
426
+ qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_PL181_BUS, dev, "sd-bus");
427
}
428
429
static void pl181_class_init(ObjectClass *klass, void *data)
430
diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c
431
index XXXXXXX..XXXXXXX 100644
432
--- a/hw/sd/pxa2xx_mmci.c
433
+++ b/hw/sd/pxa2xx_mmci.c
434
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_mmci_instance_init(Object *obj)
435
qdev_init_gpio_out_named(dev, &s->rx_dma, "rx-dma", 1);
436
qdev_init_gpio_out_named(dev, &s->tx_dma, "tx-dma", 1);
437
438
- qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
439
- TYPE_PXA2XX_MMCI_BUS, DEVICE(obj), "sd-bus");
440
+ qbus_init(&s->sdbus, sizeof(s->sdbus),
441
+ TYPE_PXA2XX_MMCI_BUS, DEVICE(obj), "sd-bus");
442
}
443
444
static void pxa2xx_mmci_class_init(ObjectClass *klass, void *data)
445
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
446
index XXXXXXX..XXXXXXX 100644
447
--- a/hw/sd/sdhci.c
448
+++ b/hw/sd/sdhci.c
449
@@ -XXX,XX +XXX,XX @@ static void sdhci_init_readonly_registers(SDHCIState *s, Error **errp)
450
451
void sdhci_initfn(SDHCIState *s)
452
{
453
- qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
454
- TYPE_SDHCI_BUS, DEVICE(s), "sd-bus");
455
+ qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_SDHCI_BUS, DEVICE(s), "sd-bus");
456
457
s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s);
458
s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, s);
459
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
460
index XXXXXXX..XXXXXXX 100644
461
--- a/hw/sd/ssi-sd.c
462
+++ b/hw/sd/ssi-sd.c
463
@@ -XXX,XX +XXX,XX @@ static void ssi_sd_realize(SSIPeripheral *d, Error **errp)
464
DeviceState *carddev;
465
DriveInfo *dinfo;
466
467
- qbus_create_inplace(&s->sdbus, sizeof(s->sdbus), TYPE_SD_BUS,
468
- DEVICE(d), "sd-bus");
469
+ qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_SD_BUS, DEVICE(d), "sd-bus");
470
471
/* Create and plug in the sd card */
472
/* FIXME use a qdev drive property instead of drive_get_next() */
473
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
474
index XXXXXXX..XXXXXXX 100644
475
--- a/hw/usb/bus.c
476
+++ b/hw/usb/bus.c
477
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_usb_device = {
478
void usb_bus_new(USBBus *bus, size_t bus_size,
479
USBBusOps *ops, DeviceState *host)
480
{
481
- qbus_create_inplace(bus, bus_size, TYPE_USB_BUS, host, NULL);
482
+ qbus_init(bus, bus_size, TYPE_USB_BUS, host, NULL);
483
qbus_set_bus_hotplug_handler(BUS(bus));
484
bus->ops = ops;
485
bus->busnr = next_usb_bus++;
486
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
487
index XXXXXXX..XXXXXXX 100644
488
--- a/hw/usb/dev-smartcard-reader.c
489
+++ b/hw/usb/dev-smartcard-reader.c
490
@@ -XXX,XX +XXX,XX @@ static void ccid_realize(USBDevice *dev, Error **errp)
491
492
usb_desc_create_serial(dev);
493
usb_desc_init(dev);
494
- qbus_create_inplace(&s->bus, sizeof(s->bus), TYPE_CCID_BUS, DEVICE(dev),
495
- NULL);
496
+ qbus_init(&s->bus, sizeof(s->bus), TYPE_CCID_BUS, DEVICE(dev), NULL);
497
qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(dev));
498
s->intr = usb_ep_get(dev, USB_TOKEN_IN, CCID_INT_IN_EP);
499
s->bulk = usb_ep_get(dev, USB_TOKEN_IN, CCID_BULK_IN_EP);
500
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
501
index XXXXXXX..XXXXXXX 100644
502
--- a/hw/virtio/virtio-mmio.c
503
+++ b/hw/virtio/virtio-mmio.c
504
@@ -XXX,XX +XXX,XX @@ static void virtio_mmio_realizefn(DeviceState *d, Error **errp)
505
VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
506
SysBusDevice *sbd = SYS_BUS_DEVICE(d);
507
508
- qbus_create_inplace(&proxy->bus, sizeof(proxy->bus), TYPE_VIRTIO_MMIO_BUS,
509
- d, NULL);
510
+ qbus_init(&proxy->bus, sizeof(proxy->bus), TYPE_VIRTIO_MMIO_BUS, d, NULL);
511
sysbus_init_irq(sbd, &proxy->irq);
512
513
if (!kvm_eventfds_enabled()) {
514
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
515
index XXXXXXX..XXXXXXX 100644
516
--- a/hw/virtio/virtio-pci.c
517
+++ b/hw/virtio/virtio-pci.c
518
@@ -XXX,XX +XXX,XX @@ static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
519
DeviceState *qdev = DEVICE(dev);
520
char virtio_bus_name[] = "virtio-bus";
521
522
- qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_PCI_BUS, qdev,
523
- virtio_bus_name);
524
+ qbus_init(bus, bus_size, TYPE_VIRTIO_PCI_BUS, qdev, virtio_bus_name);
525
}
526
527
static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
528
--
29
--
529
2.20.1
30
2.34.1
530
31
531
32
diff view generated by jsdifflib
1
The function scsi_bus_new() creates a new SCSI bus; callers can
1
In the aspeed_rtc device we store a difference between two time_t
2
either pass in a name argument to specify the name of the new bus, or
2
values in an 'int'. This is not really correct when time_t could
3
they can pass in NULL to allow the bus to be given an automatically
3
be 64 bits. Enlarge the field to 'int64_t'.
4
generated unique name. Almost all callers want to use the
5
autogenerated name; the only exception is the virtio-scsi device.
6
4
7
Taking a name argument that should almost always be NULL is an
5
This is a migration compatibility break for the aspeed boards.
8
easy-to-misuse API design -- it encourages callers to think perhaps
6
While we are changing the vmstate, remove the accidental
9
they should pass in some standard name like "scsi" or "scsi-bus". We
7
duplicate of the offset field.
10
don't do this anywhere for SCSI, but we do (incorrectly) do it for
11
other bus types such as i2c.
12
13
The function name also implies that it will return a newly allocated
14
object, when it in fact does in-place allocation. We more commonly
15
name such functions foo_init(), with foo_new() being the
16
allocate-and-return variant.
17
18
Replace all the scsi_bus_new() callsites with either:
19
* scsi_bus_init() for the usual case where the caller wants
20
an autogenerated bus name
21
* scsi_bus_init_named() for the rare case where the caller
22
needs to specify the bus name
23
24
and document that for the _named() version it's then the caller's
25
responsibility to think about uniqueness of bus names.
26
8
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Reviewed-by: Cédric Le Goater <clg@kaod.org>
29
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
30
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
31
Message-id: 20210923121153.23754-2-peter.maydell@linaro.org
32
---
11
---
33
include/hw/scsi/scsi.h | 30 ++++++++++++++++++++++++++++--
12
include/hw/rtc/aspeed_rtc.h | 2 +-
34
hw/scsi/esp-pci.c | 2 +-
13
hw/rtc/aspeed_rtc.c | 5 ++---
35
hw/scsi/esp.c | 2 +-
14
2 files changed, 3 insertions(+), 4 deletions(-)
36
hw/scsi/lsi53c895a.c | 2 +-
37
hw/scsi/megasas.c | 3 +--
38
hw/scsi/mptsas.c | 2 +-
39
hw/scsi/scsi-bus.c | 4 ++--
40
hw/scsi/spapr_vscsi.c | 3 +--
41
hw/scsi/virtio-scsi.c | 4 ++--
42
hw/scsi/vmw_pvscsi.c | 3 +--
43
hw/usb/dev-storage-bot.c | 3 +--
44
hw/usb/dev-storage-classic.c | 4 ++--
45
hw/usb/dev-uas.c | 3 +--
46
13 files changed, 43 insertions(+), 22 deletions(-)
47
15
48
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
16
diff --git a/include/hw/rtc/aspeed_rtc.h b/include/hw/rtc/aspeed_rtc.h
49
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
50
--- a/include/hw/scsi/scsi.h
18
--- a/include/hw/rtc/aspeed_rtc.h
51
+++ b/include/hw/scsi/scsi.h
19
+++ b/include/hw/rtc/aspeed_rtc.h
52
@@ -XXX,XX +XXX,XX @@ struct SCSIBus {
20
@@ -XXX,XX +XXX,XX @@ struct AspeedRtcState {
53
const SCSIBusInfo *info;
21
qemu_irq irq;
22
23
uint32_t reg[0x18];
24
- int offset;
25
+ int64_t offset;
26
54
};
27
};
55
28
56
-void scsi_bus_new(SCSIBus *bus, size_t bus_size, DeviceState *host,
29
diff --git a/hw/rtc/aspeed_rtc.c b/hw/rtc/aspeed_rtc.c
57
- const SCSIBusInfo *info, const char *bus_name);
58
+/**
59
+ * scsi_bus_init_named: Initialize a SCSI bus with the specified name
60
+ * @bus: SCSIBus object to initialize
61
+ * @bus_size: size of @bus object
62
+ * @host: Device which owns the bus (generally the SCSI controller)
63
+ * @info: structure defining callbacks etc for the controller
64
+ * @bus_name: Name to use for this bus
65
+ *
66
+ * This in-place initializes @bus as a new SCSI bus with a name
67
+ * provided by the caller. It is the caller's responsibility to make
68
+ * sure that name does not clash with the name of any other bus in the
69
+ * system. Unless you need the new bus to have a specific name, you
70
+ * should use scsi_bus_new() instead.
71
+ */
72
+void scsi_bus_init_named(SCSIBus *bus, size_t bus_size, DeviceState *host,
73
+ const SCSIBusInfo *info, const char *bus_name);
74
+
75
+/**
76
+ * scsi_bus_init: Initialize a SCSI bus
77
+ *
78
+ * This in-place-initializes @bus as a new SCSI bus and gives it
79
+ * an automatically generated unique name.
80
+ */
81
+static inline void scsi_bus_init(SCSIBus *bus, size_t bus_size,
82
+ DeviceState *host, const SCSIBusInfo *info)
83
+{
84
+ scsi_bus_init_named(bus, bus_size, host, info, NULL);
85
+}
86
87
static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
88
{
89
diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c
90
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
91
--- a/hw/scsi/esp-pci.c
31
--- a/hw/rtc/aspeed_rtc.c
92
+++ b/hw/scsi/esp-pci.c
32
+++ b/hw/rtc/aspeed_rtc.c
93
@@ -XXX,XX +XXX,XX @@ static void esp_pci_scsi_realize(PCIDevice *dev, Error **errp)
33
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_rtc_ops = {
94
pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->io);
34
95
s->irq = pci_allocate_irq(dev);
35
static const VMStateDescription vmstate_aspeed_rtc = {
96
36
.name = TYPE_ASPEED_RTC,
97
- scsi_bus_new(&s->bus, sizeof(s->bus), d, &esp_pci_scsi_info, NULL);
37
- .version_id = 1,
98
+ scsi_bus_init(&s->bus, sizeof(s->bus), d, &esp_pci_scsi_info);
38
+ .version_id = 2,
99
}
39
.fields = (VMStateField[]) {
100
40
VMSTATE_UINT32_ARRAY(reg, AspeedRtcState, 0x18),
101
static void esp_pci_scsi_exit(PCIDevice *d)
41
- VMSTATE_INT32(offset, AspeedRtcState),
102
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
42
- VMSTATE_INT32(offset, AspeedRtcState),
103
index XXXXXXX..XXXXXXX 100644
43
+ VMSTATE_INT64(offset, AspeedRtcState),
104
--- a/hw/scsi/esp.c
44
VMSTATE_END_OF_LIST()
105
+++ b/hw/scsi/esp.c
106
@@ -XXX,XX +XXX,XX @@ static void sysbus_esp_realize(DeviceState *dev, Error **errp)
107
108
qdev_init_gpio_in(dev, sysbus_esp_gpio_demux, 2);
109
110
- scsi_bus_new(&s->bus, sizeof(s->bus), dev, &esp_scsi_info, NULL);
111
+ scsi_bus_init(&s->bus, sizeof(s->bus), dev, &esp_scsi_info);
112
}
113
114
static void sysbus_esp_hard_reset(DeviceState *dev)
115
diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
116
index XXXXXXX..XXXXXXX 100644
117
--- a/hw/scsi/lsi53c895a.c
118
+++ b/hw/scsi/lsi53c895a.c
119
@@ -XXX,XX +XXX,XX @@ static void lsi_scsi_realize(PCIDevice *dev, Error **errp)
120
pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ram_io);
121
QTAILQ_INIT(&s->queue);
122
123
- scsi_bus_new(&s->bus, sizeof(s->bus), d, &lsi_scsi_info, NULL);
124
+ scsi_bus_init(&s->bus, sizeof(s->bus), d, &lsi_scsi_info);
125
}
126
127
static void lsi_scsi_exit(PCIDevice *dev)
128
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/hw/scsi/megasas.c
131
+++ b/hw/scsi/megasas.c
132
@@ -XXX,XX +XXX,XX @@ static void megasas_scsi_realize(PCIDevice *dev, Error **errp)
133
s->frames[i].state = s;
134
}
45
}
135
46
};
136
- scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
137
- &megasas_scsi_info, NULL);
138
+ scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(dev), &megasas_scsi_info);
139
}
140
141
static Property megasas_properties_gen1[] = {
142
diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c
143
index XXXXXXX..XXXXXXX 100644
144
--- a/hw/scsi/mptsas.c
145
+++ b/hw/scsi/mptsas.c
146
@@ -XXX,XX +XXX,XX @@ static void mptsas_scsi_realize(PCIDevice *dev, Error **errp)
147
148
s->request_bh = qemu_bh_new(mptsas_fetch_requests, s);
149
150
- scsi_bus_new(&s->bus, sizeof(s->bus), &dev->qdev, &mptsas_scsi_info, NULL);
151
+ scsi_bus_init(&s->bus, sizeof(s->bus), &dev->qdev, &mptsas_scsi_info);
152
}
153
154
static void mptsas_scsi_uninit(PCIDevice *dev)
155
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/hw/scsi/scsi-bus.c
158
+++ b/hw/scsi/scsi-bus.c
159
@@ -XXX,XX +XXX,XX @@ void scsi_device_unit_attention_reported(SCSIDevice *s)
160
}
161
162
/* Create a scsi bus, and attach devices to it. */
163
-void scsi_bus_new(SCSIBus *bus, size_t bus_size, DeviceState *host,
164
- const SCSIBusInfo *info, const char *bus_name)
165
+void scsi_bus_init_named(SCSIBus *bus, size_t bus_size, DeviceState *host,
166
+ const SCSIBusInfo *info, const char *bus_name)
167
{
168
qbus_create_inplace(bus, bus_size, TYPE_SCSI_BUS, host, bus_name);
169
bus->busnr = next_scsi_bus++;
170
diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
171
index XXXXXXX..XXXXXXX 100644
172
--- a/hw/scsi/spapr_vscsi.c
173
+++ b/hw/scsi/spapr_vscsi.c
174
@@ -XXX,XX +XXX,XX @@ static void spapr_vscsi_realize(SpaprVioDevice *dev, Error **errp)
175
176
dev->crq.SendFunc = vscsi_do_crq;
177
178
- scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
179
- &vscsi_scsi_info, NULL);
180
+ scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(dev), &vscsi_scsi_info);
181
182
/* ibmvscsi SCSI bus does not allow hotplug. */
183
qbus_set_hotplug_handler(BUS(&s->bus), NULL);
184
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
185
index XXXXXXX..XXXXXXX 100644
186
--- a/hw/scsi/virtio-scsi.c
187
+++ b/hw/scsi/virtio-scsi.c
188
@@ -XXX,XX +XXX,XX @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp)
189
return;
190
}
191
192
- scsi_bus_new(&s->bus, sizeof(s->bus), dev,
193
- &virtio_scsi_scsi_info, vdev->bus_name);
194
+ scsi_bus_init_named(&s->bus, sizeof(s->bus), dev,
195
+ &virtio_scsi_scsi_info, vdev->bus_name);
196
/* override default SCSI bus hotplug-handler, with virtio-scsi's one */
197
qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(dev));
198
199
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
200
index XXXXXXX..XXXXXXX 100644
201
--- a/hw/scsi/vmw_pvscsi.c
202
+++ b/hw/scsi/vmw_pvscsi.c
203
@@ -XXX,XX +XXX,XX @@ pvscsi_realizefn(PCIDevice *pci_dev, Error **errp)
204
205
s->completion_worker = qemu_bh_new(pvscsi_process_completion_queue, s);
206
207
- scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(pci_dev),
208
- &pvscsi_scsi_info, NULL);
209
+ scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(pci_dev), &pvscsi_scsi_info);
210
/* override default SCSI bus hotplug-handler, with pvscsi's one */
211
qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(s));
212
pvscsi_reset_state(s);
213
diff --git a/hw/usb/dev-storage-bot.c b/hw/usb/dev-storage-bot.c
214
index XXXXXXX..XXXXXXX 100644
215
--- a/hw/usb/dev-storage-bot.c
216
+++ b/hw/usb/dev-storage-bot.c
217
@@ -XXX,XX +XXX,XX @@ static void usb_msd_bot_realize(USBDevice *dev, Error **errp)
218
s->dev.auto_attach = 0;
219
}
220
221
- scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
222
- &usb_msd_scsi_info_bot, NULL);
223
+ scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(dev), &usb_msd_scsi_info_bot);
224
usb_msd_handle_reset(dev);
225
}
226
227
diff --git a/hw/usb/dev-storage-classic.c b/hw/usb/dev-storage-classic.c
228
index XXXXXXX..XXXXXXX 100644
229
--- a/hw/usb/dev-storage-classic.c
230
+++ b/hw/usb/dev-storage-classic.c
231
@@ -XXX,XX +XXX,XX @@ static void usb_msd_storage_realize(USBDevice *dev, Error **errp)
232
usb_desc_create_serial(dev);
233
usb_desc_init(dev);
234
dev->flags |= (1 << USB_DEV_FLAG_IS_SCSI_STORAGE);
235
- scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
236
- &usb_msd_scsi_info_storage, NULL);
237
+ scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(dev),
238
+ &usb_msd_scsi_info_storage);
239
scsi_dev = scsi_bus_legacy_add_drive(&s->bus, blk, 0, !!s->removable,
240
s->conf.bootindex, s->conf.share_rw,
241
s->conf.rerror, s->conf.werror,
242
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
243
index XXXXXXX..XXXXXXX 100644
244
--- a/hw/usb/dev-uas.c
245
+++ b/hw/usb/dev-uas.c
246
@@ -XXX,XX +XXX,XX @@ static void usb_uas_realize(USBDevice *dev, Error **errp)
247
uas->status_bh = qemu_bh_new(usb_uas_send_status_bh, uas);
248
249
dev->flags |= (1 << USB_DEV_FLAG_IS_SCSI_STORAGE);
250
- scsi_bus_new(&uas->bus, sizeof(uas->bus), DEVICE(dev),
251
- &usb_uas_scsi_info, NULL);
252
+ scsi_bus_init(&uas->bus, sizeof(uas->bus), DEVICE(dev), &usb_uas_scsi_info);
253
}
254
255
static const VMStateDescription vmstate_usb_uas = {
256
--
47
--
257
2.20.1
48
2.34.1
258
49
259
50
diff view generated by jsdifflib
1
Rename the pci_root_bus_new_inplace() function to
1
The functions qemu_get_timedate() and qemu_timedate_diff() take
2
pci_root_bus_init(); this brings the bus type in to line with a
2
and return a time offset as an integer. Coverity points out that
3
"_init for in-place init, _new for allocate-and-return" convention.
3
means that when an RTC device implementation holds an offset
4
To do this we need to rename the implementation-internal function
4
as a time_t, as the m48t59 does, the time_t will get truncated.
5
that was using the pci_root_bus_init() name to
5
(CID 1507157, 1517772).
6
pci_root_bus_internal_init().
6
7
The functions work with time_t internally, so make them use that type
8
in their APIs.
9
10
Note that this won't help any Y2038 issues where either the device
11
model itself is keeping the offset in a 32-bit integer, or where the
12
hardware under emulation has Y2038 or other rollover problems. If we
13
missed any cases of the former then hopefully Coverity will warn us
14
about them since after this patch we'd be truncating a time_t in
15
assignments from qemu_timedate_diff().)
7
16
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
11
Message-id: 20210923121153.23754-4-peter.maydell@linaro.org
12
---
19
---
13
include/hw/pci/pci.h | 10 +++++-----
20
include/sysemu/rtc.h | 4 ++--
14
hw/pci-host/raven.c | 4 ++--
21
softmmu/rtc.c | 4 ++--
15
hw/pci-host/versatile.c | 6 +++---
22
2 files changed, 4 insertions(+), 4 deletions(-)
16
hw/pci/pci.c | 26 +++++++++++++-------------
17
4 files changed, 23 insertions(+), 23 deletions(-)
18
23
19
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
24
diff --git a/include/sysemu/rtc.h b/include/sysemu/rtc.h
20
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/pci/pci.h
26
--- a/include/sysemu/rtc.h
22
+++ b/include/hw/pci/pci.h
27
+++ b/include/sysemu/rtc.h
23
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(PCIBus, PCIBusClass, PCI_BUS)
28
@@ -XXX,XX +XXX,XX @@
24
29
* The behaviour of the clock whose value this function returns will
25
bool pci_bus_is_express(PCIBus *bus);
30
* depend on the -rtc command line option passed by the user.
26
31
*/
27
-void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
32
-void qemu_get_timedate(struct tm *tm, int offset);
28
- const char *name,
33
+void qemu_get_timedate(struct tm *tm, time_t offset);
29
- MemoryRegion *address_space_mem,
34
30
- MemoryRegion *address_space_io,
35
/**
31
- uint8_t devfn_min, const char *typename);
36
* qemu_timedate_diff: Return difference between a struct tm and the RTC
32
+void pci_root_bus_init(PCIBus *bus, size_t bus_size, DeviceState *parent,
37
@@ -XXX,XX +XXX,XX @@ void qemu_get_timedate(struct tm *tm, int offset);
33
+ const char *name,
38
* a timestamp one hour further ahead than the current RTC time
34
+ MemoryRegion *address_space_mem,
39
* then this function will return 3600.
35
+ MemoryRegion *address_space_io,
40
*/
36
+ uint8_t devfn_min, const char *typename);
41
-int qemu_timedate_diff(struct tm *tm);
37
PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
42
+time_t qemu_timedate_diff(struct tm *tm);
38
MemoryRegion *address_space_mem,
43
39
MemoryRegion *address_space_io,
44
#endif
40
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
45
diff --git a/softmmu/rtc.c b/softmmu/rtc.c
41
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/pci-host/raven.c
47
--- a/softmmu/rtc.c
43
+++ b/hw/pci-host/raven.c
48
+++ b/softmmu/rtc.c
44
@@ -XXX,XX +XXX,XX @@ static void raven_pcihost_initfn(Object *obj)
49
@@ -XXX,XX +XXX,XX @@ static time_t qemu_ref_timedate(QEMUClockType clock)
45
memory_region_add_subregion_overlap(address_space_mem, PCI_IO_BASE_ADDR,
50
return value;
46
&s->pci_io_non_contiguous, 1);
47
memory_region_add_subregion(address_space_mem, 0xc0000000, &s->pci_memory);
48
- pci_root_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), NULL,
49
- &s->pci_memory, &s->pci_io, 0, TYPE_PCI_BUS);
50
+ pci_root_bus_init(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), NULL,
51
+ &s->pci_memory, &s->pci_io, 0, TYPE_PCI_BUS);
52
53
/* Bus master address space */
54
memory_region_init(&s->bm, obj, "bm-raven", 4 * GiB);
55
diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/pci-host/versatile.c
58
+++ b/hw/pci-host/versatile.c
59
@@ -XXX,XX +XXX,XX @@ static void pci_vpb_realize(DeviceState *dev, Error **errp)
60
memory_region_init(&s->pci_io_space, OBJECT(s), "pci_io", 4 * GiB);
61
memory_region_init(&s->pci_mem_space, OBJECT(s), "pci_mem", 4 * GiB);
62
63
- pci_root_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), dev, "pci",
64
- &s->pci_mem_space, &s->pci_io_space,
65
- PCI_DEVFN(11, 0), TYPE_PCI_BUS);
66
+ pci_root_bus_init(&s->pci_bus, sizeof(s->pci_bus), dev, "pci",
67
+ &s->pci_mem_space, &s->pci_io_space,
68
+ PCI_DEVFN(11, 0), TYPE_PCI_BUS);
69
h->bus = &s->pci_bus;
70
71
object_initialize(&s->pci_dev, sizeof(s->pci_dev), TYPE_VERSATILE_PCI_HOST);
72
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/pci/pci.c
75
+++ b/hw/pci/pci.c
76
@@ -XXX,XX +XXX,XX @@ bool pci_bus_bypass_iommu(PCIBus *bus)
77
return host_bridge->bypass_iommu;
78
}
51
}
79
52
80
-static void pci_root_bus_init(PCIBus *bus, DeviceState *parent,
53
-void qemu_get_timedate(struct tm *tm, int offset)
81
- MemoryRegion *address_space_mem,
54
+void qemu_get_timedate(struct tm *tm, time_t offset)
82
- MemoryRegion *address_space_io,
83
- uint8_t devfn_min)
84
+static void pci_root_bus_internal_init(PCIBus *bus, DeviceState *parent,
85
+ MemoryRegion *address_space_mem,
86
+ MemoryRegion *address_space_io,
87
+ uint8_t devfn_min)
88
{
55
{
89
assert(PCI_FUNC(devfn_min) == 0);
56
time_t ti = qemu_ref_timedate(rtc_clock);
90
bus->devfn_min = devfn_min;
57
91
@@ -XXX,XX +XXX,XX @@ bool pci_bus_is_express(PCIBus *bus)
58
@@ -XXX,XX +XXX,XX @@ void qemu_get_timedate(struct tm *tm, int offset)
92
return object_dynamic_cast(OBJECT(bus), TYPE_PCIE_BUS);
59
}
93
}
60
}
94
61
95
-void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
62
-int qemu_timedate_diff(struct tm *tm)
96
- const char *name,
63
+time_t qemu_timedate_diff(struct tm *tm)
97
- MemoryRegion *address_space_mem,
98
- MemoryRegion *address_space_io,
99
- uint8_t devfn_min, const char *typename)
100
+void pci_root_bus_init(PCIBus *bus, size_t bus_size, DeviceState *parent,
101
+ const char *name,
102
+ MemoryRegion *address_space_mem,
103
+ MemoryRegion *address_space_io,
104
+ uint8_t devfn_min, const char *typename)
105
{
64
{
106
qbus_create_inplace(bus, bus_size, typename, parent, name);
65
time_t seconds;
107
- pci_root_bus_init(bus, parent, address_space_mem, address_space_io,
108
- devfn_min);
109
+ pci_root_bus_internal_init(bus, parent, address_space_mem,
110
+ address_space_io, devfn_min);
111
}
112
113
PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
114
@@ -XXX,XX +XXX,XX @@ PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
115
PCIBus *bus;
116
117
bus = PCI_BUS(qbus_create(typename, parent, name));
118
- pci_root_bus_init(bus, parent, address_space_mem, address_space_io,
119
- devfn_min);
120
+ pci_root_bus_internal_init(bus, parent, address_space_mem,
121
+ address_space_io, devfn_min);
122
return bus;
123
}
124
66
125
--
67
--
126
2.20.1
68
2.34.1
127
69
128
70
diff view generated by jsdifflib
1
Rename ipack_bus_new_inplace() to ipack_bus_init(), to bring it in to
1
Where architecturally one ARM_FEATURE_X flag implies another
2
line with a "_init for in-place init, _new for allocate-and-return"
2
ARM_FEATURE_Y, we allow the CPU init function to only set X, and then
3
convention. Drop the 'name' argument, because the only caller does
3
set Y for it. Currently we do this in two places -- we set a few
4
not pass in a name. If a future caller does need to specify the bus
4
flags in arm_cpu_post_init() because we need them to decide which
5
name, we should create an ipack_bus_init_named() function at that
5
properties to create on the CPU object, and then we do the rest in
6
point.
6
arm_cpu_realizefn(). However, this is fragile, because it's easy to
7
add a new property and not notice that this means that an X-implies-Y
8
check now has to move from realize to post-init.
9
10
As a specific example, the pmsav7-dregion property is conditional
11
on ARM_FEATURE_PMSA && ARM_FEATURE_V7, which means it won't appear
12
on the Cortex-M33 and -M55, because they set ARM_FEATURE_V8 and
13
rely on V8-implies-V7, which doesn't happen until the realizefn.
14
15
Move all of these X-implies-Y checks into a new function, which
16
we call at the top of arm_cpu_post_init(), so the feature bits
17
are available at that point.
18
19
This does now give us the reverse issue, that if there's a feature
20
bit which is enabled or disabled by the setting of a property then
21
then X-implies-Y features that are dependent on that property need to
22
be in realize, not in this new function. But the only one of those
23
is the "EL3 implies VBAR" which is already in the right place, so
24
putting things this way round seems better to me.
7
25
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
27
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
28
Message-id: 20230724174335.2150499-2-peter.maydell@linaro.org
11
Message-id: 20210923121153.23754-3-peter.maydell@linaro.org
12
---
29
---
13
include/hw/ipack/ipack.h | 8 ++++----
30
target/arm/cpu.c | 179 +++++++++++++++++++++++++----------------------
14
hw/ipack/ipack.c | 10 +++++-----
31
1 file changed, 97 insertions(+), 82 deletions(-)
15
hw/ipack/tpci200.c | 4 ++--
32
16
3 files changed, 11 insertions(+), 11 deletions(-)
33
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
17
18
diff --git a/include/hw/ipack/ipack.h b/include/hw/ipack/ipack.h
19
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/ipack/ipack.h
35
--- a/target/arm/cpu.c
21
+++ b/include/hw/ipack/ipack.h
36
+++ b/target/arm/cpu.c
22
@@ -XXX,XX +XXX,XX @@ extern const VMStateDescription vmstate_ipack_device;
37
@@ -XXX,XX +XXX,XX @@ unsigned int gt_cntfrq_period_ns(ARMCPU *cpu)
23
VMSTATE_STRUCT(_field, _state, 1, vmstate_ipack_device, IPackDevice)
38
NANOSECONDS_PER_SECOND / cpu->gt_cntfrq_hz : 1;
24
25
IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot);
26
-void ipack_bus_new_inplace(IPackBus *bus, size_t bus_size,
27
- DeviceState *parent,
28
- const char *name, uint8_t n_slots,
29
- qemu_irq_handler handler);
30
+void ipack_bus_init(IPackBus *bus, size_t bus_size,
31
+ DeviceState *parent,
32
+ uint8_t n_slots,
33
+ qemu_irq_handler handler);
34
35
#endif
36
diff --git a/hw/ipack/ipack.c b/hw/ipack/ipack.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/ipack/ipack.c
39
+++ b/hw/ipack/ipack.c
40
@@ -XXX,XX +XXX,XX @@ IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot)
41
return NULL;
42
}
39
}
43
40
44
-void ipack_bus_new_inplace(IPackBus *bus, size_t bus_size,
41
+static void arm_cpu_propagate_feature_implications(ARMCPU *cpu)
45
- DeviceState *parent,
42
+{
46
- const char *name, uint8_t n_slots,
43
+ CPUARMState *env = &cpu->env;
47
- qemu_irq_handler handler)
44
+ bool no_aa32 = false;
48
+void ipack_bus_init(IPackBus *bus, size_t bus_size,
45
+
49
+ DeviceState *parent,
46
+ /*
50
+ uint8_t n_slots,
47
+ * Some features automatically imply others: set the feature
51
+ qemu_irq_handler handler)
48
+ * bits explicitly for these cases.
49
+ */
50
+
51
+ if (arm_feature(env, ARM_FEATURE_M)) {
52
+ set_feature(env, ARM_FEATURE_PMSA);
53
+ }
54
+
55
+ if (arm_feature(env, ARM_FEATURE_V8)) {
56
+ if (arm_feature(env, ARM_FEATURE_M)) {
57
+ set_feature(env, ARM_FEATURE_V7);
58
+ } else {
59
+ set_feature(env, ARM_FEATURE_V7VE);
60
+ }
61
+ }
62
+
63
+ /*
64
+ * There exist AArch64 cpus without AArch32 support. When KVM
65
+ * queries ID_ISAR0_EL1 on such a host, the value is UNKNOWN.
66
+ * Similarly, we cannot check ID_AA64PFR0 without AArch64 support.
67
+ * As a general principle, we also do not make ID register
68
+ * consistency checks anywhere unless using TCG, because only
69
+ * for TCG would a consistency-check failure be a QEMU bug.
70
+ */
71
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
72
+ no_aa32 = !cpu_isar_feature(aa64_aa32, cpu);
73
+ }
74
+
75
+ if (arm_feature(env, ARM_FEATURE_V7VE)) {
76
+ /*
77
+ * v7 Virtualization Extensions. In real hardware this implies
78
+ * EL2 and also the presence of the Security Extensions.
79
+ * For QEMU, for backwards-compatibility we implement some
80
+ * CPUs or CPU configs which have no actual EL2 or EL3 but do
81
+ * include the various other features that V7VE implies.
82
+ * Presence of EL2 itself is ARM_FEATURE_EL2, and of the
83
+ * Security Extensions is ARM_FEATURE_EL3.
84
+ */
85
+ assert(!tcg_enabled() || no_aa32 ||
86
+ cpu_isar_feature(aa32_arm_div, cpu));
87
+ set_feature(env, ARM_FEATURE_LPAE);
88
+ set_feature(env, ARM_FEATURE_V7);
89
+ }
90
+ if (arm_feature(env, ARM_FEATURE_V7)) {
91
+ set_feature(env, ARM_FEATURE_VAPA);
92
+ set_feature(env, ARM_FEATURE_THUMB2);
93
+ set_feature(env, ARM_FEATURE_MPIDR);
94
+ if (!arm_feature(env, ARM_FEATURE_M)) {
95
+ set_feature(env, ARM_FEATURE_V6K);
96
+ } else {
97
+ set_feature(env, ARM_FEATURE_V6);
98
+ }
99
+
100
+ /*
101
+ * Always define VBAR for V7 CPUs even if it doesn't exist in
102
+ * non-EL3 configs. This is needed by some legacy boards.
103
+ */
104
+ set_feature(env, ARM_FEATURE_VBAR);
105
+ }
106
+ if (arm_feature(env, ARM_FEATURE_V6K)) {
107
+ set_feature(env, ARM_FEATURE_V6);
108
+ set_feature(env, ARM_FEATURE_MVFR);
109
+ }
110
+ if (arm_feature(env, ARM_FEATURE_V6)) {
111
+ set_feature(env, ARM_FEATURE_V5);
112
+ if (!arm_feature(env, ARM_FEATURE_M)) {
113
+ assert(!tcg_enabled() || no_aa32 ||
114
+ cpu_isar_feature(aa32_jazelle, cpu));
115
+ set_feature(env, ARM_FEATURE_AUXCR);
116
+ }
117
+ }
118
+ if (arm_feature(env, ARM_FEATURE_V5)) {
119
+ set_feature(env, ARM_FEATURE_V4T);
120
+ }
121
+ if (arm_feature(env, ARM_FEATURE_LPAE)) {
122
+ set_feature(env, ARM_FEATURE_V7MP);
123
+ }
124
+ if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {
125
+ set_feature(env, ARM_FEATURE_CBAR);
126
+ }
127
+ if (arm_feature(env, ARM_FEATURE_THUMB2) &&
128
+ !arm_feature(env, ARM_FEATURE_M)) {
129
+ set_feature(env, ARM_FEATURE_THUMB_DSP);
130
+ }
131
+}
132
+
133
void arm_cpu_post_init(Object *obj)
52
{
134
{
53
- qbus_create_inplace(bus, bus_size, TYPE_IPACK_BUS, parent, name);
135
ARMCPU *cpu = ARM_CPU(obj);
54
+ qbus_create_inplace(bus, bus_size, TYPE_IPACK_BUS, parent, NULL);
136
55
bus->n_slots = n_slots;
137
- /* M profile implies PMSA. We have to do this here rather than
56
bus->set_irq = handler;
138
- * in realize with the other feature-implication checks because
57
}
139
- * we look at the PMSA bit to see if we should add some properties.
58
diff --git a/hw/ipack/tpci200.c b/hw/ipack/tpci200.c
140
+ /*
59
index XXXXXXX..XXXXXXX 100644
141
+ * Some features imply others. Figure this out now, because we
60
--- a/hw/ipack/tpci200.c
142
+ * are going to look at the feature bits in deciding which
61
+++ b/hw/ipack/tpci200.c
143
+ * properties to add.
62
@@ -XXX,XX +XXX,XX @@ static void tpci200_realize(PCIDevice *pci_dev, Error **errp)
144
*/
63
pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las2);
145
- if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
64
pci_register_bar(&s->dev, 5, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las3);
146
- set_feature(&cpu->env, ARM_FEATURE_PMSA);
65
147
- }
66
- ipack_bus_new_inplace(&s->bus, sizeof(s->bus), DEVICE(pci_dev), NULL,
148
+ arm_cpu_propagate_feature_implications(cpu);
67
- N_MODULES, tpci200_set_irq);
149
68
+ ipack_bus_init(&s->bus, sizeof(s->bus), DEVICE(pci_dev),
150
if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) ||
69
+ N_MODULES, tpci200_set_irq);
151
arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) {
70
}
152
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
71
153
CPUARMState *env = &cpu->env;
72
static const VMStateDescription vmstate_tpci200 = {
154
int pagebits;
155
Error *local_err = NULL;
156
- bool no_aa32 = false;
157
158
/* Use pc-relative instructions in system-mode */
159
#ifndef CONFIG_USER_ONLY
160
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
161
cpu->isar.id_isar3 = u;
162
}
163
164
- /* Some features automatically imply others: */
165
- if (arm_feature(env, ARM_FEATURE_V8)) {
166
- if (arm_feature(env, ARM_FEATURE_M)) {
167
- set_feature(env, ARM_FEATURE_V7);
168
- } else {
169
- set_feature(env, ARM_FEATURE_V7VE);
170
- }
171
- }
172
-
173
- /*
174
- * There exist AArch64 cpus without AArch32 support. When KVM
175
- * queries ID_ISAR0_EL1 on such a host, the value is UNKNOWN.
176
- * Similarly, we cannot check ID_AA64PFR0 without AArch64 support.
177
- * As a general principle, we also do not make ID register
178
- * consistency checks anywhere unless using TCG, because only
179
- * for TCG would a consistency-check failure be a QEMU bug.
180
- */
181
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
182
- no_aa32 = !cpu_isar_feature(aa64_aa32, cpu);
183
- }
184
-
185
- if (arm_feature(env, ARM_FEATURE_V7VE)) {
186
- /* v7 Virtualization Extensions. In real hardware this implies
187
- * EL2 and also the presence of the Security Extensions.
188
- * For QEMU, for backwards-compatibility we implement some
189
- * CPUs or CPU configs which have no actual EL2 or EL3 but do
190
- * include the various other features that V7VE implies.
191
- * Presence of EL2 itself is ARM_FEATURE_EL2, and of the
192
- * Security Extensions is ARM_FEATURE_EL3.
193
- */
194
- assert(!tcg_enabled() || no_aa32 ||
195
- cpu_isar_feature(aa32_arm_div, cpu));
196
- set_feature(env, ARM_FEATURE_LPAE);
197
- set_feature(env, ARM_FEATURE_V7);
198
- }
199
- if (arm_feature(env, ARM_FEATURE_V7)) {
200
- set_feature(env, ARM_FEATURE_VAPA);
201
- set_feature(env, ARM_FEATURE_THUMB2);
202
- set_feature(env, ARM_FEATURE_MPIDR);
203
- if (!arm_feature(env, ARM_FEATURE_M)) {
204
- set_feature(env, ARM_FEATURE_V6K);
205
- } else {
206
- set_feature(env, ARM_FEATURE_V6);
207
- }
208
-
209
- /* Always define VBAR for V7 CPUs even if it doesn't exist in
210
- * non-EL3 configs. This is needed by some legacy boards.
211
- */
212
- set_feature(env, ARM_FEATURE_VBAR);
213
- }
214
- if (arm_feature(env, ARM_FEATURE_V6K)) {
215
- set_feature(env, ARM_FEATURE_V6);
216
- set_feature(env, ARM_FEATURE_MVFR);
217
- }
218
- if (arm_feature(env, ARM_FEATURE_V6)) {
219
- set_feature(env, ARM_FEATURE_V5);
220
- if (!arm_feature(env, ARM_FEATURE_M)) {
221
- assert(!tcg_enabled() || no_aa32 ||
222
- cpu_isar_feature(aa32_jazelle, cpu));
223
- set_feature(env, ARM_FEATURE_AUXCR);
224
- }
225
- }
226
- if (arm_feature(env, ARM_FEATURE_V5)) {
227
- set_feature(env, ARM_FEATURE_V4T);
228
- }
229
- if (arm_feature(env, ARM_FEATURE_LPAE)) {
230
- set_feature(env, ARM_FEATURE_V7MP);
231
- }
232
- if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {
233
- set_feature(env, ARM_FEATURE_CBAR);
234
- }
235
- if (arm_feature(env, ARM_FEATURE_THUMB2) &&
236
- !arm_feature(env, ARM_FEATURE_M)) {
237
- set_feature(env, ARM_FEATURE_THUMB_DSP);
238
- }
239
240
/*
241
* We rely on no XScale CPU having VFP so we can use the same bits in the
73
--
242
--
74
2.20.1
243
2.34.1
75
76
diff view generated by jsdifflib
1
From: Tong Ho <tong.ho@xilinx.com>
1
M-profile CPUs generally allow configuration of the number of MPU
2
regions that they have. We don't currently model this, so our
3
implementations of some of the board models provide CPUs with the
4
wrong number of regions. RTOSes like Zephyr that hardcode the
5
expected number of regions may therefore not run on the model if they
6
are set up to run on real hardware.
2
7
3
This device is present in Versal and ZynqMP product
8
Add properties mpu-ns-regions and mpu-s-regions to the ARMV7M object,
4
families to store a 256-bit encryption key.
9
matching the ability of hardware to configure the number of Secure
10
and NonSecure regions separately. Our actual CPU implementation
11
doesn't currently support that, and it happens that none of the MPS
12
boards we model set the number of regions differently for Secure vs
13
NonSecure, so we provide an interface to the boards and SoCs that
14
won't need to change if we ever do add that functionality in future,
15
but make it an error to configure the two properties to different
16
values.
5
17
6
Co-authored-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
18
(The property name on the CPU is the somewhat misnamed-for-M-profile
7
Co-authored-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
19
"pmsav7-dregion", so we don't follow that naming convention for
20
the properties here. The TRM doesn't say what the CPU configuration
21
variable names are, so we pick something, and follow the lowercase
22
convention we already have for properties here.)
8
23
9
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
11
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
12
Message-id: 20210917052400.1249094-5-tong.ho@xilinx.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
26
Message-id: 20230724174335.2150499-3-peter.maydell@linaro.org
15
---
27
---
16
include/hw/nvram/xlnx-bbram.h | 54 ++++
28
include/hw/arm/armv7m.h | 8 ++++++++
17
hw/nvram/xlnx-bbram.c | 545 ++++++++++++++++++++++++++++++++++
29
hw/arm/armv7m.c | 21 +++++++++++++++++++++
18
hw/nvram/Kconfig | 4 +
30
2 files changed, 29 insertions(+)
19
hw/nvram/meson.build | 1 +
20
4 files changed, 604 insertions(+)
21
create mode 100644 include/hw/nvram/xlnx-bbram.h
22
create mode 100644 hw/nvram/xlnx-bbram.c
23
31
24
diff --git a/include/hw/nvram/xlnx-bbram.h b/include/hw/nvram/xlnx-bbram.h
32
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
25
new file mode 100644
33
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX
34
--- a/include/hw/arm/armv7m.h
27
--- /dev/null
35
+++ b/include/hw/arm/armv7m.h
28
+++ b/include/hw/nvram/xlnx-bbram.h
36
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(ARMv7MState, ARMV7M)
29
@@ -XXX,XX +XXX,XX @@
37
* + Property "vfp": enable VFP (forwarded to CPU object)
30
+/*
38
* + Property "dsp": enable DSP (forwarded to CPU object)
31
+ * QEMU model of the Xilinx BBRAM Battery Backed RAM
39
* + Property "enable-bitband": expose bitbanded IO
32
+ *
40
+ * + Property "mpu-ns-regions": number of Non-Secure MPU regions (forwarded
33
+ * Copyright (c) 2015-2021 Xilinx Inc.
41
+ * to CPU object pmsav7-dregion property; default is whatever the default
34
+ *
42
+ * for the CPU is)
35
+ * Written by Edgar E. Iglesias <edgari@xilinx.com>
43
+ * + Property "mpu-s-regions": number of Secure MPU regions (default is
36
+ *
44
+ * whatever the default for the CPU is; must currently be set to the same
37
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
45
+ * value as mpu-ns-regions if the CPU implements the Security Extension)
38
+ * of this software and associated documentation files (the "Software"), to deal
46
* + Clock input "refclk" is the external reference clock for the systick timers
39
+ * in the Software without restriction, including without limitation the rights
47
* + Clock input "cpuclk" is the main CPU clock
40
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
48
*/
41
+ * copies of the Software, and to permit persons to whom the Software is
49
@@ -XXX,XX +XXX,XX @@ struct ARMv7MState {
42
+ * furnished to do so, subject to the following conditions:
50
Object *idau;
43
+ *
51
uint32_t init_svtor;
44
+ * The above copyright notice and this permission notice shall be included in
52
uint32_t init_nsvtor;
45
+ * all copies or substantial portions of the Software.
53
+ uint32_t mpu_ns_regions;
46
+ *
54
+ uint32_t mpu_s_regions;
47
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55
bool enable_bitband;
48
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
56
bool start_powered_off;
49
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
57
bool vfp;
50
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
58
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
51
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
59
index XXXXXXX..XXXXXXX 100644
52
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
60
--- a/hw/arm/armv7m.c
53
+ * THE SOFTWARE.
61
+++ b/hw/arm/armv7m.c
54
+ */
62
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
55
+#ifndef XLNX_BBRAM_H
63
}
56
+#define XLNX_BBRAM_H
64
}
57
+
65
58
+#include "sysemu/block-backend.h"
66
+ /*
59
+#include "hw/qdev-core.h"
67
+ * Real M-profile hardware can be configured with a different number of
60
+#include "hw/irq.h"
68
+ * MPU regions for Secure vs NonSecure. QEMU's CPU implementation doesn't
61
+#include "hw/sysbus.h"
69
+ * support that yet, so catch attempts to select that.
62
+#include "hw/register.h"
70
+ */
63
+
71
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) &&
64
+#define RMAX_XLNX_BBRAM ((0x4c / 4) + 1)
72
+ s->mpu_ns_regions != s->mpu_s_regions) {
65
+
73
+ error_setg(errp,
66
+#define TYPE_XLNX_BBRAM "xlnx,bbram-ctrl"
74
+ "mpu-ns-regions and mpu-s-regions properties must have the same value");
67
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxBBRam, XLNX_BBRAM);
68
+
69
+struct XlnxBBRam {
70
+ SysBusDevice parent_obj;
71
+ qemu_irq irq_bbram;
72
+
73
+ BlockBackend *blk;
74
+
75
+ uint32_t crc_zpads;
76
+ bool bbram8_wo;
77
+ bool blk_ro;
78
+
79
+ uint32_t regs[RMAX_XLNX_BBRAM];
80
+ RegisterInfo regs_info[RMAX_XLNX_BBRAM];
81
+};
82
+
83
+#endif
84
diff --git a/hw/nvram/xlnx-bbram.c b/hw/nvram/xlnx-bbram.c
85
new file mode 100644
86
index XXXXXXX..XXXXXXX
87
--- /dev/null
88
+++ b/hw/nvram/xlnx-bbram.c
89
@@ -XXX,XX +XXX,XX @@
90
+/*
91
+ * QEMU model of the Xilinx BBRAM Battery Backed RAM
92
+ *
93
+ * Copyright (c) 2014-2021 Xilinx Inc.
94
+ *
95
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
96
+ * of this software and associated documentation files (the "Software"), to deal
97
+ * in the Software without restriction, including without limitation the rights
98
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
99
+ * copies of the Software, and to permit persons to whom the Software is
100
+ * furnished to do so, subject to the following conditions:
101
+ *
102
+ * The above copyright notice and this permission notice shall be included in
103
+ * all copies or substantial portions of the Software.
104
+ *
105
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
106
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
107
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
108
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
109
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
110
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
111
+ * THE SOFTWARE.
112
+ */
113
+
114
+#include "qemu/osdep.h"
115
+#include "hw/nvram/xlnx-bbram.h"
116
+
117
+#include "qemu/error-report.h"
118
+#include "qemu/log.h"
119
+#include "qapi/error.h"
120
+#include "sysemu/blockdev.h"
121
+#include "migration/vmstate.h"
122
+#include "hw/qdev-properties.h"
123
+#include "hw/qdev-properties-system.h"
124
+#include "hw/nvram/xlnx-efuse.h"
125
+
126
+#ifndef XLNX_BBRAM_ERR_DEBUG
127
+#define XLNX_BBRAM_ERR_DEBUG 0
128
+#endif
129
+
130
+REG32(BBRAM_STATUS, 0x0)
131
+ FIELD(BBRAM_STATUS, AES_CRC_PASS, 9, 1)
132
+ FIELD(BBRAM_STATUS, AES_CRC_DONE, 8, 1)
133
+ FIELD(BBRAM_STATUS, BBRAM_ZEROIZED, 4, 1)
134
+ FIELD(BBRAM_STATUS, PGM_MODE, 0, 1)
135
+REG32(BBRAM_CTRL, 0x4)
136
+ FIELD(BBRAM_CTRL, ZEROIZE, 0, 1)
137
+REG32(PGM_MODE, 0x8)
138
+REG32(BBRAM_AES_CRC, 0xc)
139
+REG32(BBRAM_0, 0x10)
140
+REG32(BBRAM_1, 0x14)
141
+REG32(BBRAM_2, 0x18)
142
+REG32(BBRAM_3, 0x1c)
143
+REG32(BBRAM_4, 0x20)
144
+REG32(BBRAM_5, 0x24)
145
+REG32(BBRAM_6, 0x28)
146
+REG32(BBRAM_7, 0x2c)
147
+REG32(BBRAM_8, 0x30)
148
+REG32(BBRAM_SLVERR, 0x34)
149
+ FIELD(BBRAM_SLVERR, ENABLE, 0, 1)
150
+REG32(BBRAM_ISR, 0x38)
151
+ FIELD(BBRAM_ISR, APB_SLVERR, 0, 1)
152
+REG32(BBRAM_IMR, 0x3c)
153
+ FIELD(BBRAM_IMR, APB_SLVERR, 0, 1)
154
+REG32(BBRAM_IER, 0x40)
155
+ FIELD(BBRAM_IER, APB_SLVERR, 0, 1)
156
+REG32(BBRAM_IDR, 0x44)
157
+ FIELD(BBRAM_IDR, APB_SLVERR, 0, 1)
158
+REG32(BBRAM_MSW_LOCK, 0x4c)
159
+ FIELD(BBRAM_MSW_LOCK, VAL, 0, 1)
160
+
161
+#define R_MAX (R_BBRAM_MSW_LOCK + 1)
162
+
163
+#define RAM_MAX (A_BBRAM_8 + 4 - A_BBRAM_0)
164
+
165
+#define BBRAM_PGM_MAGIC 0x757bdf0d
166
+
167
+QEMU_BUILD_BUG_ON(R_MAX != ARRAY_SIZE(((XlnxBBRam *)0)->regs));
168
+
169
+static bool bbram_msw_locked(XlnxBBRam *s)
170
+{
171
+ return ARRAY_FIELD_EX32(s->regs, BBRAM_MSW_LOCK, VAL) != 0;
172
+}
173
+
174
+static bool bbram_pgm_enabled(XlnxBBRam *s)
175
+{
176
+ return ARRAY_FIELD_EX32(s->regs, BBRAM_STATUS, PGM_MODE) != 0;
177
+}
178
+
179
+static void bbram_bdrv_error(XlnxBBRam *s, int rc, gchar *detail)
180
+{
181
+ Error *errp;
182
+
183
+ error_setg_errno(&errp, -rc, "%s: BBRAM backstore %s failed.",
184
+ blk_name(s->blk), detail);
185
+ error_report("%s", error_get_pretty(errp));
186
+ error_free(errp);
187
+
188
+ g_free(detail);
189
+}
190
+
191
+static void bbram_bdrv_read(XlnxBBRam *s, Error **errp)
192
+{
193
+ uint32_t *ram = &s->regs[R_BBRAM_0];
194
+ int nr = RAM_MAX;
195
+
196
+ if (!s->blk) {
197
+ return;
75
+ return;
198
+ }
76
+ }
199
+
77
+ if (s->mpu_ns_regions != UINT_MAX &&
200
+ s->blk_ro = !blk_supports_write_perm(s->blk);
78
+ object_property_find(OBJECT(s->cpu), "pmsav7-dregion")) {
201
+ if (!s->blk_ro) {
79
+ if (!object_property_set_uint(OBJECT(s->cpu), "pmsav7-dregion",
202
+ int rc;
80
+ s->mpu_ns_regions, errp)) {
203
+
81
+ return;
204
+ rc = blk_set_perm(s->blk,
205
+ (BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE),
206
+ BLK_PERM_ALL, NULL);
207
+ if (rc) {
208
+ s->blk_ro = true;
209
+ }
210
+ }
211
+ if (s->blk_ro) {
212
+ warn_report("%s: Skip saving updates to read-only BBRAM backstore.",
213
+ blk_name(s->blk));
214
+ }
215
+
216
+ if (blk_pread(s->blk, 0, ram, nr) < 0) {
217
+ error_setg(errp,
218
+ "%s: Failed to read %u bytes from BBRAM backstore.",
219
+ blk_name(s->blk), nr);
220
+ return;
221
+ }
222
+
223
+ /* Convert from little-endian backstore for each 32-bit word */
224
+ nr /= 4;
225
+ while (nr--) {
226
+ ram[nr] = le32_to_cpu(ram[nr]);
227
+ }
228
+}
229
+
230
+static void bbram_bdrv_sync(XlnxBBRam *s, uint64_t hwaddr)
231
+{
232
+ uint32_t le32;
233
+ unsigned offset;
234
+ int rc;
235
+
236
+ assert(A_BBRAM_0 <= hwaddr && hwaddr <= A_BBRAM_8);
237
+
238
+ /* Backstore is always in little-endian */
239
+ le32 = cpu_to_le32(s->regs[hwaddr / 4]);
240
+
241
+ /* Update zeroized flag */
242
+ if (le32 && (hwaddr != A_BBRAM_8 || s->bbram8_wo)) {
243
+ ARRAY_FIELD_DP32(s->regs, BBRAM_STATUS, BBRAM_ZEROIZED, 0);
244
+ }
245
+
246
+ if (!s->blk || s->blk_ro) {
247
+ return;
248
+ }
249
+
250
+ offset = hwaddr - A_BBRAM_0;
251
+ rc = blk_pwrite(s->blk, offset, &le32, 4, 0);
252
+ if (rc < 0) {
253
+ bbram_bdrv_error(s, rc, g_strdup_printf("write to offset %u", offset));
254
+ }
255
+}
256
+
257
+static void bbram_bdrv_zero(XlnxBBRam *s)
258
+{
259
+ int rc;
260
+
261
+ ARRAY_FIELD_DP32(s->regs, BBRAM_STATUS, BBRAM_ZEROIZED, 1);
262
+
263
+ if (!s->blk || s->blk_ro) {
264
+ return;
265
+ }
266
+
267
+ rc = blk_make_zero(s->blk, 0);
268
+ if (rc < 0) {
269
+ bbram_bdrv_error(s, rc, g_strdup("zeroizing"));
270
+ }
271
+
272
+ /* Restore bbram8 if it is non-zero */
273
+ if (s->regs[R_BBRAM_8]) {
274
+ bbram_bdrv_sync(s, A_BBRAM_8);
275
+ }
276
+}
277
+
278
+static void bbram_zeroize(XlnxBBRam *s)
279
+{
280
+ int nr = RAM_MAX - (s->bbram8_wo ? 0 : 4); /* only wo bbram8 is cleared */
281
+
282
+ memset(&s->regs[R_BBRAM_0], 0, nr);
283
+ bbram_bdrv_zero(s);
284
+}
285
+
286
+static void bbram_update_irq(XlnxBBRam *s)
287
+{
288
+ bool pending = s->regs[R_BBRAM_ISR] & ~s->regs[R_BBRAM_IMR];
289
+
290
+ qemu_set_irq(s->irq_bbram, pending);
291
+}
292
+
293
+static void bbram_ctrl_postw(RegisterInfo *reg, uint64_t val64)
294
+{
295
+ XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
296
+ uint32_t val = val64;
297
+
298
+ if (val & R_BBRAM_CTRL_ZEROIZE_MASK) {
299
+ bbram_zeroize(s);
300
+ /* The bit is self clearing */
301
+ s->regs[R_BBRAM_CTRL] &= ~R_BBRAM_CTRL_ZEROIZE_MASK;
302
+ }
303
+}
304
+
305
+static void bbram_pgm_mode_postw(RegisterInfo *reg, uint64_t val64)
306
+{
307
+ XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
308
+ uint32_t val = val64;
309
+
310
+ if (val == BBRAM_PGM_MAGIC) {
311
+ bbram_zeroize(s);
312
+
313
+ /* The status bit is cleared only by POR */
314
+ ARRAY_FIELD_DP32(s->regs, BBRAM_STATUS, PGM_MODE, 1);
315
+ }
316
+}
317
+
318
+static void bbram_aes_crc_postw(RegisterInfo *reg, uint64_t val64)
319
+{
320
+ XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
321
+ uint32_t calc_crc;
322
+
323
+ if (!bbram_pgm_enabled(s)) {
324
+ /* We are not in programming mode, don't do anything */
325
+ return;
326
+ }
327
+
328
+ /* Perform the AES integrity check */
329
+ s->regs[R_BBRAM_STATUS] |= R_BBRAM_STATUS_AES_CRC_DONE_MASK;
330
+
331
+ /*
332
+ * Set check status.
333
+ *
334
+ * ZynqMP BBRAM check has a zero-u32 prepended; see:
335
+ * https://github.com/Xilinx/embeddedsw/blob/release-2019.2/lib/sw_services/xilskey/src/xilskey_bbramps_zynqmp.c#L311
336
+ */
337
+ calc_crc = xlnx_efuse_calc_crc(&s->regs[R_BBRAM_0],
338
+ (R_BBRAM_8 - R_BBRAM_0), s->crc_zpads);
339
+
340
+ ARRAY_FIELD_DP32(s->regs, BBRAM_STATUS, AES_CRC_PASS,
341
+ (s->regs[R_BBRAM_AES_CRC] == calc_crc));
342
+}
343
+
344
+static uint64_t bbram_key_prew(RegisterInfo *reg, uint64_t val64)
345
+{
346
+ XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
347
+ uint32_t original_data = *(uint32_t *) reg->data;
348
+
349
+ if (bbram_pgm_enabled(s)) {
350
+ return val64;
351
+ } else {
352
+ /* We are not in programming mode, don't do anything */
353
+ qemu_log_mask(LOG_GUEST_ERROR,
354
+ "Not in programming mode, dropping the write\n");
355
+ return original_data;
356
+ }
357
+}
358
+
359
+static void bbram_key_postw(RegisterInfo *reg, uint64_t val64)
360
+{
361
+ XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
362
+
363
+ bbram_bdrv_sync(s, reg->access->addr);
364
+}
365
+
366
+static uint64_t bbram_wo_postr(RegisterInfo *reg, uint64_t val)
367
+{
368
+ return 0;
369
+}
370
+
371
+static uint64_t bbram_r8_postr(RegisterInfo *reg, uint64_t val)
372
+{
373
+ XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
374
+
375
+ return s->bbram8_wo ? bbram_wo_postr(reg, val) : val;
376
+}
377
+
378
+static bool bbram_r8_readonly(XlnxBBRam *s)
379
+{
380
+ return !bbram_pgm_enabled(s) || bbram_msw_locked(s);
381
+}
382
+
383
+static uint64_t bbram_r8_prew(RegisterInfo *reg, uint64_t val64)
384
+{
385
+ XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
386
+
387
+ if (bbram_r8_readonly(s)) {
388
+ val64 = *(uint32_t *)reg->data;
389
+ }
390
+
391
+ return val64;
392
+}
393
+
394
+static void bbram_r8_postw(RegisterInfo *reg, uint64_t val64)
395
+{
396
+ XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
397
+
398
+ if (!bbram_r8_readonly(s)) {
399
+ bbram_bdrv_sync(s, A_BBRAM_8);
400
+ }
401
+}
402
+
403
+static uint64_t bbram_msw_lock_prew(RegisterInfo *reg, uint64_t val64)
404
+{
405
+ XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
406
+
407
+ /* Never lock if bbram8 is wo; and, only POR can clear the lock */
408
+ if (s->bbram8_wo) {
409
+ val64 = 0;
410
+ } else {
411
+ val64 |= s->regs[R_BBRAM_MSW_LOCK];
412
+ }
413
+
414
+ return val64;
415
+}
416
+
417
+static void bbram_isr_postw(RegisterInfo *reg, uint64_t val64)
418
+{
419
+ XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
420
+
421
+ bbram_update_irq(s);
422
+}
423
+
424
+static uint64_t bbram_ier_prew(RegisterInfo *reg, uint64_t val64)
425
+{
426
+ XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
427
+ uint32_t val = val64;
428
+
429
+ s->regs[R_BBRAM_IMR] &= ~val;
430
+ bbram_update_irq(s);
431
+ return 0;
432
+}
433
+
434
+static uint64_t bbram_idr_prew(RegisterInfo *reg, uint64_t val64)
435
+{
436
+ XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
437
+ uint32_t val = val64;
438
+
439
+ s->regs[R_BBRAM_IMR] |= val;
440
+ bbram_update_irq(s);
441
+ return 0;
442
+}
443
+
444
+static RegisterAccessInfo bbram_ctrl_regs_info[] = {
445
+ { .name = "BBRAM_STATUS", .addr = A_BBRAM_STATUS,
446
+ .rsvd = 0xee,
447
+ .ro = 0x3ff,
448
+ },{ .name = "BBRAM_CTRL", .addr = A_BBRAM_CTRL,
449
+ .post_write = bbram_ctrl_postw,
450
+ },{ .name = "PGM_MODE", .addr = A_PGM_MODE,
451
+ .post_write = bbram_pgm_mode_postw,
452
+ },{ .name = "BBRAM_AES_CRC", .addr = A_BBRAM_AES_CRC,
453
+ .post_write = bbram_aes_crc_postw,
454
+ .post_read = bbram_wo_postr,
455
+ },{ .name = "BBRAM_0", .addr = A_BBRAM_0,
456
+ .pre_write = bbram_key_prew,
457
+ .post_write = bbram_key_postw,
458
+ .post_read = bbram_wo_postr,
459
+ },{ .name = "BBRAM_1", .addr = A_BBRAM_1,
460
+ .pre_write = bbram_key_prew,
461
+ .post_write = bbram_key_postw,
462
+ .post_read = bbram_wo_postr,
463
+ },{ .name = "BBRAM_2", .addr = A_BBRAM_2,
464
+ .pre_write = bbram_key_prew,
465
+ .post_write = bbram_key_postw,
466
+ .post_read = bbram_wo_postr,
467
+ },{ .name = "BBRAM_3", .addr = A_BBRAM_3,
468
+ .pre_write = bbram_key_prew,
469
+ .post_write = bbram_key_postw,
470
+ .post_read = bbram_wo_postr,
471
+ },{ .name = "BBRAM_4", .addr = A_BBRAM_4,
472
+ .pre_write = bbram_key_prew,
473
+ .post_write = bbram_key_postw,
474
+ .post_read = bbram_wo_postr,
475
+ },{ .name = "BBRAM_5", .addr = A_BBRAM_5,
476
+ .pre_write = bbram_key_prew,
477
+ .post_write = bbram_key_postw,
478
+ .post_read = bbram_wo_postr,
479
+ },{ .name = "BBRAM_6", .addr = A_BBRAM_6,
480
+ .pre_write = bbram_key_prew,
481
+ .post_write = bbram_key_postw,
482
+ .post_read = bbram_wo_postr,
483
+ },{ .name = "BBRAM_7", .addr = A_BBRAM_7,
484
+ .pre_write = bbram_key_prew,
485
+ .post_write = bbram_key_postw,
486
+ .post_read = bbram_wo_postr,
487
+ },{ .name = "BBRAM_8", .addr = A_BBRAM_8,
488
+ .pre_write = bbram_r8_prew,
489
+ .post_write = bbram_r8_postw,
490
+ .post_read = bbram_r8_postr,
491
+ },{ .name = "BBRAM_SLVERR", .addr = A_BBRAM_SLVERR,
492
+ .rsvd = ~1,
493
+ },{ .name = "BBRAM_ISR", .addr = A_BBRAM_ISR,
494
+ .w1c = 0x1,
495
+ .post_write = bbram_isr_postw,
496
+ },{ .name = "BBRAM_IMR", .addr = A_BBRAM_IMR,
497
+ .ro = 0x1,
498
+ },{ .name = "BBRAM_IER", .addr = A_BBRAM_IER,
499
+ .pre_write = bbram_ier_prew,
500
+ },{ .name = "BBRAM_IDR", .addr = A_BBRAM_IDR,
501
+ .pre_write = bbram_idr_prew,
502
+ },{ .name = "BBRAM_MSW_LOCK", .addr = A_BBRAM_MSW_LOCK,
503
+ .pre_write = bbram_msw_lock_prew,
504
+ .ro = ~R_BBRAM_MSW_LOCK_VAL_MASK,
505
+ }
506
+};
507
+
508
+static void bbram_ctrl_reset(DeviceState *dev)
509
+{
510
+ XlnxBBRam *s = XLNX_BBRAM(dev);
511
+ unsigned int i;
512
+
513
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
514
+ if (i < R_BBRAM_0 || i > R_BBRAM_8) {
515
+ register_reset(&s->regs_info[i]);
516
+ }
82
+ }
517
+ }
83
+ }
518
+
84
+
519
+ bbram_update_irq(s);
85
/*
520
+}
86
* Tell the CPU where the NVIC is; it will fail realize if it doesn't
521
+
87
* have one. Similarly, tell the NVIC where its CPU is.
522
+static const MemoryRegionOps bbram_ctrl_ops = {
88
@@ -XXX,XX +XXX,XX @@ static Property armv7m_properties[] = {
523
+ .read = register_read_memory,
89
false),
524
+ .write = register_write_memory,
90
DEFINE_PROP_BOOL("vfp", ARMv7MState, vfp, true),
525
+ .endianness = DEVICE_LITTLE_ENDIAN,
91
DEFINE_PROP_BOOL("dsp", ARMv7MState, dsp, true),
526
+ .valid = {
92
+ DEFINE_PROP_UINT32("mpu-ns-regions", ARMv7MState, mpu_ns_regions, UINT_MAX),
527
+ .min_access_size = 4,
93
+ DEFINE_PROP_UINT32("mpu-s-regions", ARMv7MState, mpu_s_regions, UINT_MAX),
528
+ .max_access_size = 4,
94
DEFINE_PROP_END_OF_LIST(),
529
+ },
95
};
530
+};
96
531
+
532
+static void bbram_ctrl_realize(DeviceState *dev, Error **errp)
533
+{
534
+ XlnxBBRam *s = XLNX_BBRAM(dev);
535
+
536
+ if (s->crc_zpads) {
537
+ s->bbram8_wo = true;
538
+ }
539
+
540
+ bbram_bdrv_read(s, errp);
541
+}
542
+
543
+static void bbram_ctrl_init(Object *obj)
544
+{
545
+ XlnxBBRam *s = XLNX_BBRAM(obj);
546
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
547
+ RegisterInfoArray *reg_array;
548
+
549
+ reg_array =
550
+ register_init_block32(DEVICE(obj), bbram_ctrl_regs_info,
551
+ ARRAY_SIZE(bbram_ctrl_regs_info),
552
+ s->regs_info, s->regs,
553
+ &bbram_ctrl_ops,
554
+ XLNX_BBRAM_ERR_DEBUG,
555
+ R_MAX * 4);
556
+
557
+ sysbus_init_mmio(sbd, &reg_array->mem);
558
+ sysbus_init_irq(sbd, &s->irq_bbram);
559
+}
560
+
561
+static void bbram_prop_set_drive(Object *obj, Visitor *v, const char *name,
562
+ void *opaque, Error **errp)
563
+{
564
+ DeviceState *dev = DEVICE(obj);
565
+
566
+ qdev_prop_drive.set(obj, v, name, opaque, errp);
567
+
568
+ /* Fill initial data if backend is attached after realized */
569
+ if (dev->realized) {
570
+ bbram_bdrv_read(XLNX_BBRAM(obj), errp);
571
+ }
572
+}
573
+
574
+static void bbram_prop_get_drive(Object *obj, Visitor *v, const char *name,
575
+ void *opaque, Error **errp)
576
+{
577
+ qdev_prop_drive.get(obj, v, name, opaque, errp);
578
+}
579
+
580
+static void bbram_prop_release_drive(Object *obj, const char *name,
581
+ void *opaque)
582
+{
583
+ qdev_prop_drive.release(obj, name, opaque);
584
+}
585
+
586
+static const PropertyInfo bbram_prop_drive = {
587
+ .name = "str",
588
+ .description = "Node name or ID of a block device to use as BBRAM backend",
589
+ .realized_set_allowed = true,
590
+ .get = bbram_prop_get_drive,
591
+ .set = bbram_prop_set_drive,
592
+ .release = bbram_prop_release_drive,
593
+};
594
+
595
+static const VMStateDescription vmstate_bbram_ctrl = {
596
+ .name = TYPE_XLNX_BBRAM,
597
+ .version_id = 1,
598
+ .minimum_version_id = 1,
599
+ .fields = (VMStateField[]) {
600
+ VMSTATE_UINT32_ARRAY(regs, XlnxBBRam, R_MAX),
601
+ VMSTATE_END_OF_LIST(),
602
+ }
603
+};
604
+
605
+static Property bbram_ctrl_props[] = {
606
+ DEFINE_PROP("drive", XlnxBBRam, blk, bbram_prop_drive, BlockBackend *),
607
+ DEFINE_PROP_UINT32("crc-zpads", XlnxBBRam, crc_zpads, 1),
608
+ DEFINE_PROP_END_OF_LIST(),
609
+};
610
+
611
+static void bbram_ctrl_class_init(ObjectClass *klass, void *data)
612
+{
613
+ DeviceClass *dc = DEVICE_CLASS(klass);
614
+
615
+ dc->reset = bbram_ctrl_reset;
616
+ dc->realize = bbram_ctrl_realize;
617
+ dc->vmsd = &vmstate_bbram_ctrl;
618
+ device_class_set_props(dc, bbram_ctrl_props);
619
+}
620
+
621
+static const TypeInfo bbram_ctrl_info = {
622
+ .name = TYPE_XLNX_BBRAM,
623
+ .parent = TYPE_SYS_BUS_DEVICE,
624
+ .instance_size = sizeof(XlnxBBRam),
625
+ .class_init = bbram_ctrl_class_init,
626
+ .instance_init = bbram_ctrl_init,
627
+};
628
+
629
+static void bbram_ctrl_register_types(void)
630
+{
631
+ type_register_static(&bbram_ctrl_info);
632
+}
633
+
634
+type_init(bbram_ctrl_register_types)
635
diff --git a/hw/nvram/Kconfig b/hw/nvram/Kconfig
636
index XXXXXXX..XXXXXXX 100644
637
--- a/hw/nvram/Kconfig
638
+++ b/hw/nvram/Kconfig
639
@@ -XXX,XX +XXX,XX @@ config XLNX_EFUSE_VERSAL
640
config XLNX_EFUSE_ZYNQMP
641
bool
642
select XLNX_EFUSE
643
+
644
+config XLNX_BBRAM
645
+ bool
646
+ select XLNX_EFUSE_CRC
647
diff --git a/hw/nvram/meson.build b/hw/nvram/meson.build
648
index XXXXXXX..XXXXXXX 100644
649
--- a/hw/nvram/meson.build
650
+++ b/hw/nvram/meson.build
651
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE_VERSAL', if_true: files(
652
'xlnx-versal-efuse-ctrl.c'))
653
softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE_ZYNQMP', if_true: files(
654
'xlnx-zynqmp-efuse.c'))
655
+softmmu_ss.add(when: 'CONFIG_XLNX_BBRAM', if_true: files('xlnx-bbram.c'))
656
657
specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_nvram.c'))
658
--
97
--
659
2.20.1
98
2.34.1
660
99
661
100
diff view generated by jsdifflib
1
The aarch64-linux QEMU usermode binaries can never run 32-bit
1
The IoTKit, SSE200 and SSE300 all default to 8 MPU regions. The
2
code, so they do not need to include the GDB XML for it.
2
MPS2/MPS3 FPGA images don't override these except in the case of
3
(arm_cpu_register_gdb_regs_for_features() will not use these
3
AN547, which uses 16 MPU regions.
4
XML files if the CPU has ARM_FEATURE_AARCH64, so we will not
4
5
advertise to gdb that we have them.)
5
Define properties on the ARMSSE object for the MPU regions (using the
6
6
same names as the documented RTL configuration settings, and
7
following the pattern we already have for this device of using
8
all-caps names as the RTL does), and set them in the board code.
9
10
We don't actually need to override the default except on AN547,
11
but it's simpler code to have the board code set them always
12
rather than tracking which board subtypes want to set them to
13
a non-default value separately from what that value is.
14
15
Tho overall effect is that for mps2-an505, mps2-an521 and mps3-an524
16
we now correctly use 8 MPU regions, while mps3-an547 stays at its
17
current 16 regions.
18
19
It's possible some guest code wrongly depended on the previous
20
incorrectly modeled number of memory regions. (Such guest code
21
should ideally check the number of regions via the MPU_TYPE
22
register.) The old behaviour can be obtained with additional
23
-global arguments to QEMU:
24
25
For mps2-an521 and mps2-an524:
26
-global sse-200.CPU0_MPU_NS=16 -global sse-200.CPU0_MPU_S=16 -global sse-200.CPU1_MPU_NS=16 -global sse-200.CPU1_MPU_S=16
27
28
For mps2-an505:
29
-global sse-200.CPU0_MPU_NS=16 -global sse-200.CPU0_MPU_S=16
30
31
NB that the way the implementation allows this use of -global
32
is slightly fragile: if the board code explicitly sets the
33
properties on the sse-200 object, this overrides the -global
34
command line option. So we rely on:
35
- the boards that need fixing all happen to use the SSE defaults
36
- we can write the board code to only set the property if it
37
is different from the default, rather than having all boards
38
explicitly set the property
39
- the board that does need to use a non-default value happens
40
to need to set it to the same value (16) we previously used
41
This works, but there are some kinds of refactoring of the
42
mps2-tz.c code that would break the support for -global here.
43
44
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1772
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
45
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
46
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210921162901.17508-2-peter.maydell@linaro.org
47
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
48
Message-id: 20230724174335.2150499-4-peter.maydell@linaro.org
10
---
49
---
11
configs/targets/aarch64-linux-user.mak | 2 +-
50
include/hw/arm/armsse.h | 5 +++++
12
configs/targets/aarch64_be-linux-user.mak | 2 +-
51
hw/arm/armsse.c | 16 ++++++++++++++++
13
2 files changed, 2 insertions(+), 2 deletions(-)
52
hw/arm/mps2-tz.c | 29 +++++++++++++++++++++++++++++
14
53
3 files changed, 50 insertions(+)
15
diff --git a/configs/targets/aarch64-linux-user.mak b/configs/targets/aarch64-linux-user.mak
54
55
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
16
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
17
--- a/configs/targets/aarch64-linux-user.mak
57
--- a/include/hw/arm/armsse.h
18
+++ b/configs/targets/aarch64-linux-user.mak
58
+++ b/include/hw/arm/armsse.h
19
@@ -XXX,XX +XXX,XX @@
59
@@ -XXX,XX +XXX,XX @@
20
TARGET_ARCH=aarch64
60
* (matching the hardware) is that for CPU0 in an IoTKit and CPU1 in an
21
TARGET_BASE_ARCH=arm
61
* SSE-200 both are present; CPU0 in an SSE-200 has neither.
22
-TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml
62
* Since the IoTKit has only one CPU, it does not have the CPU1_* properties.
23
+TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml
63
+ * + QOM properties "CPU0_MPU_NS", "CPU0_MPU_S", "CPU1_MPU_NS" and "CPU1_MPU_S"
24
TARGET_HAS_BFLT=y
64
+ * which set the number of MPU regions on the CPUs. If there is only one
25
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
65
+ * CPU the CPU1 properties are not present.
26
diff --git a/configs/targets/aarch64_be-linux-user.mak b/configs/targets/aarch64_be-linux-user.mak
66
* + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts for CPU 0,
67
* which are wired to its NVIC lines 32 .. n+32
68
* + Named GPIO inputs "EXP_CPU1_IRQ" 0..n are the expansion interrupts for
69
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
70
uint32_t exp_numirq;
71
uint32_t sram_addr_width;
72
uint32_t init_svtor;
73
+ uint32_t cpu_mpu_ns[SSE_MAX_CPUS];
74
+ uint32_t cpu_mpu_s[SSE_MAX_CPUS];
75
bool cpu_fpu[SSE_MAX_CPUS];
76
bool cpu_dsp[SSE_MAX_CPUS];
77
};
78
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
27
index XXXXXXX..XXXXXXX 100644
79
index XXXXXXX..XXXXXXX 100644
28
--- a/configs/targets/aarch64_be-linux-user.mak
80
--- a/hw/arm/armsse.c
29
+++ b/configs/targets/aarch64_be-linux-user.mak
81
+++ b/hw/arm/armsse.c
30
@@ -XXX,XX +XXX,XX @@
82
@@ -XXX,XX +XXX,XX @@ static Property iotkit_properties[] = {
31
TARGET_ARCH=aarch64
83
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
32
TARGET_BASE_ARCH=arm
84
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
33
TARGET_WORDS_BIGENDIAN=y
85
DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
34
-TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml
86
+ DEFINE_PROP_UINT32("CPU0_MPU_NS", ARMSSE, cpu_mpu_ns[0], 8),
35
+TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml
87
+ DEFINE_PROP_UINT32("CPU0_MPU_S", ARMSSE, cpu_mpu_s[0], 8),
36
TARGET_HAS_BFLT=y
88
DEFINE_PROP_END_OF_LIST()
37
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
89
};
90
91
@@ -XXX,XX +XXX,XX @@ static Property sse200_properties[] = {
92
DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], false),
93
DEFINE_PROP_BOOL("CPU1_FPU", ARMSSE, cpu_fpu[1], true),
94
DEFINE_PROP_BOOL("CPU1_DSP", ARMSSE, cpu_dsp[1], true),
95
+ DEFINE_PROP_UINT32("CPU0_MPU_NS", ARMSSE, cpu_mpu_ns[0], 8),
96
+ DEFINE_PROP_UINT32("CPU0_MPU_S", ARMSSE, cpu_mpu_s[0], 8),
97
+ DEFINE_PROP_UINT32("CPU1_MPU_NS", ARMSSE, cpu_mpu_ns[1], 8),
98
+ DEFINE_PROP_UINT32("CPU1_MPU_S", ARMSSE, cpu_mpu_s[1], 8),
99
DEFINE_PROP_END_OF_LIST()
100
};
101
102
@@ -XXX,XX +XXX,XX @@ static Property sse300_properties[] = {
103
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
104
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
105
DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
106
+ DEFINE_PROP_UINT32("CPU0_MPU_NS", ARMSSE, cpu_mpu_ns[0], 8),
107
+ DEFINE_PROP_UINT32("CPU0_MPU_S", ARMSSE, cpu_mpu_s[0], 8),
108
DEFINE_PROP_END_OF_LIST()
109
};
110
111
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
112
return;
113
}
114
}
115
+ if (!object_property_set_uint(cpuobj, "mpu-ns-regions",
116
+ s->cpu_mpu_ns[i], errp)) {
117
+ return;
118
+ }
119
+ if (!object_property_set_uint(cpuobj, "mpu-s-regions",
120
+ s->cpu_mpu_s[i], errp)) {
121
+ return;
122
+ }
123
124
if (i > 0) {
125
memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
126
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/arm/mps2-tz.c
129
+++ b/hw/arm/mps2-tz.c
130
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
131
int uart_overflow_irq; /* number of the combined UART overflow IRQ */
132
uint32_t init_svtor; /* init-svtor setting for SSE */
133
uint32_t sram_addr_width; /* SRAM_ADDR_WIDTH setting for SSE */
134
+ uint32_t cpu0_mpu_ns; /* CPU0_MPU_NS setting for SSE */
135
+ uint32_t cpu0_mpu_s; /* CPU0_MPU_S setting for SSE */
136
+ uint32_t cpu1_mpu_ns; /* CPU1_MPU_NS setting for SSE */
137
+ uint32_t cpu1_mpu_s; /* CPU1_MPU_S setting for SSE */
138
const RAMInfo *raminfo;
139
const char *armsse_type;
140
uint32_t boot_ram_size; /* size of ram at address 0; 0 == find in raminfo */
141
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
142
#define MPS3_DDR_SIZE (2 * GiB)
143
#endif
144
145
+/* For cpu{0,1}_mpu_{ns,s}, means "leave at SSE's default value" */
146
+#define MPU_REGION_DEFAULT UINT32_MAX
147
+
148
static const uint32_t an505_oscclk[] = {
149
40000000,
150
24580000,
151
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
152
OBJECT(system_memory), &error_abort);
153
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", mmc->numirq);
154
qdev_prop_set_uint32(iotkitdev, "init-svtor", mmc->init_svtor);
155
+ if (mmc->cpu0_mpu_ns != MPU_REGION_DEFAULT) {
156
+ qdev_prop_set_uint32(iotkitdev, "CPU0_MPU_NS", mmc->cpu0_mpu_ns);
157
+ }
158
+ if (mmc->cpu0_mpu_s != MPU_REGION_DEFAULT) {
159
+ qdev_prop_set_uint32(iotkitdev, "CPU0_MPU_S", mmc->cpu0_mpu_s);
160
+ }
161
+ if (object_property_find(OBJECT(iotkitdev), "CPU1_MPU_NS")) {
162
+ if (mmc->cpu1_mpu_ns != MPU_REGION_DEFAULT) {
163
+ qdev_prop_set_uint32(iotkitdev, "CPU1_MPU_NS", mmc->cpu1_mpu_ns);
164
+ }
165
+ if (mmc->cpu1_mpu_s != MPU_REGION_DEFAULT) {
166
+ qdev_prop_set_uint32(iotkitdev, "CPU1_MPU_S", mmc->cpu1_mpu_s);
167
+ }
168
+ }
169
qdev_prop_set_uint32(iotkitdev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
170
qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
171
qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
172
@@ -XXX,XX +XXX,XX @@ static void mps2tz_class_init(ObjectClass *oc, void *data)
173
{
174
MachineClass *mc = MACHINE_CLASS(oc);
175
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(oc);
176
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
177
178
mc->init = mps2tz_common_init;
179
mc->reset = mps2_machine_reset;
180
iic->check = mps2_tz_idau_check;
181
+
182
+ /* Most machines leave these at the SSE defaults */
183
+ mmc->cpu0_mpu_ns = MPU_REGION_DEFAULT;
184
+ mmc->cpu0_mpu_s = MPU_REGION_DEFAULT;
185
+ mmc->cpu1_mpu_ns = MPU_REGION_DEFAULT;
186
+ mmc->cpu1_mpu_s = MPU_REGION_DEFAULT;
187
}
188
189
static void mps2tz_set_default_ram_info(MPS2TZMachineClass *mmc)
190
@@ -XXX,XX +XXX,XX @@ static void mps3tz_an547_class_init(ObjectClass *oc, void *data)
191
mmc->numirq = 96;
192
mmc->uart_overflow_irq = 48;
193
mmc->init_svtor = 0x00000000;
194
+ mmc->cpu0_mpu_s = mmc->cpu0_mpu_ns = 16;
195
mmc->sram_addr_width = 21;
196
mmc->raminfo = an547_raminfo;
197
mmc->armsse_type = TYPE_SSE300;
38
--
198
--
39
2.20.1
199
2.34.1
40
200
41
201
diff view generated by jsdifflib