1
Arm queue; some of the simpler stuff, things other have reviewed (thanks!), etc.
1
Nothing too exciting in this lot :-)
2
2
3
-- PMM
3
The following changes since commit ba0fa56bc06e563de68d2a2bf3ddb0cfea1be4f9:
4
4
5
The following changes since commit 5d2f557b47dfbf8f23277a5bdd8473d4607c681a:
5
Merge remote-tracking branch 'remotes/vivier/tags/q800-for-6.2-pull-request' into staging (2021-09-29 21:20:49 +0100)
6
7
Merge remote-tracking branch 'remotes/kraxel/tags/vga-20200605-pull-request' into staging (2020-06-05 13:53:05 +0100)
8
6
9
are available in the Git repository at:
7
are available in the Git repository at:
10
8
11
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200605
9
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210930
12
10
13
for you to fetch changes up to 2c35a39eda0b16c2ed85c94cec204bf5efb97812:
11
for you to fetch changes up to 1f4b2ec701b9d73d3fa7bb90c8b4376bc7d3c42b:
14
12
15
target/arm: Convert Neon one-register-and-immediate insns to decodetree (2020-06-05 17:23:10 +0100)
13
hw/arm: sabrelite: Connect SPI flash CS line to GPIO3_19 (2021-09-30 13:44:13 +0100)
16
14
17
----------------------------------------------------------------
15
----------------------------------------------------------------
18
target-arm queue:
16
target-arm queue:
19
hw/ssi/imx_spi: Handle tx burst lengths other than 8 correctly
17
* allwinner-h3: Switch to SMC as PSCI conduit
20
hw/input/pxa2xx_keypad: Replace hw_error() by qemu_log_mask()
18
* arm: tcg: Adhere to SMCCC 1.3 section 5.2
21
hw/arm/pxa2xx: Replace printf() call by qemu_log_mask()
19
* xlnx-zcu102, xlnx-versal-virt: Support BBRAM and eFUSE devices
22
target/arm: Convert crypto insns to gvec
20
* gdbstub related code cleanups
23
hw/adc/stm32f2xx_adc: Correct memory region size and access size
21
* Don't put FPEXC and FPSID in org.gnu.gdb.arm.vfp XML
24
tests/acceptance: Add a boot test for the xlnx-versal-virt machine
22
* Use _init vs _new convention in bus creation function names
25
docs/system: Document Aspeed boards
23
* sabrelite: Connect SPI flash CS line to GPIO3_19
26
raspi: Add model of the USB controller
27
target/arm: Convert 2-reg-and-shift and 1-reg-imm Neon insns to decodetree
28
24
29
----------------------------------------------------------------
25
----------------------------------------------------------------
30
Cédric Le Goater (1):
26
Alexander Graf (2):
31
docs/system: Document Aspeed boards
27
allwinner-h3: Switch to SMC as PSCI conduit
28
arm: tcg: Adhere to SMCCC 1.3 section 5.2
32
29
33
Eden Mikitas (2):
30
Peter Maydell (10):
34
hw/ssi/imx_spi: changed while statement to prevent underflow
31
configs: Don't include 32-bit-only GDB XML in aarch64 linux configs
35
hw/ssi/imx_spi: Removed unnecessary cast of rx data received from slave
32
target/arm: Fix coding style issues in gdbstub code in helper.c
33
target/arm: Move gdbstub related code out of helper.c
34
target/arm: Don't put FPEXC and FPSID in org.gnu.gdb.arm.vfp XML
35
scsi: Replace scsi_bus_new() with scsi_bus_init(), scsi_bus_init_named()
36
ipack: Rename ipack_bus_new_inplace() to ipack_bus_init()
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()
36
41
37
Paul Zimmerman (7):
42
Tong Ho (9):
38
raspi: add BCM2835 SOC MPHI emulation
43
hw/nvram: Introduce Xilinx eFuse QOM
39
dwc-hsotg (dwc2) USB host controller register definitions
44
hw/nvram: Introduce Xilinx Versal eFuse device
40
dwc-hsotg (dwc2) USB host controller state definitions
45
hw/nvram: Introduce Xilinx ZynqMP eFuse device
41
dwc-hsotg (dwc2) USB host controller emulation
46
hw/nvram: Introduce Xilinx battery-backed ram
42
usb: add short-packet handling to usb-storage driver
47
hw/arm: xlnx-versal-virt: Add Xilinx BBRAM device
43
wire in the dwc-hsotg (dwc2) USB host controller emulation
48
hw/arm: xlnx-versal-virt: Add Xilinx eFUSE device
44
raspi2 acceptance test: add test for dwc-hsotg (dwc2) USB host
49
hw/arm: xlnx-zcu102: Add Xilinx BBRAM device
50
hw/arm: xlnx-zcu102: Add Xilinx eFUSE device
51
docs/system/arm: xlnx-versal-virt: BBRAM and eFUSE Usage
45
52
46
Peter Maydell (9):
53
Xuzhou Cheng (1):
47
target/arm: Convert Neon VSHL and VSLI 2-reg-shift insn to decodetree
54
hw/arm: sabrelite: Connect SPI flash CS line to GPIO3_19
48
target/arm: Convert Neon VSHR 2-reg-shift insns to decodetree
49
target/arm: Convert Neon VSRA, VSRI, VRSHR, VRSRA 2-reg-shift insns to decodetree
50
target/arm: Convert VQSHLU, VQSHL 2-reg-shift insns to decodetree
51
target/arm: Convert Neon narrowing shifts with op==8 to decodetree
52
target/arm: Convert Neon narrowing shifts with op==9 to decodetree
53
target/arm: Convert Neon VSHLL, VMOVL to decodetree
54
target/arm: Convert VCVT fixed-point ops to decodetree
55
target/arm: Convert Neon one-register-and-immediate insns to decodetree
56
55
57
Philippe Mathieu-Daudé (3):
56
docs/system/arm/xlnx-versal-virt.rst | 49 ++
58
hw/input/pxa2xx_keypad: Replace hw_error() by qemu_log_mask()
57
configs/targets/aarch64-linux-user.mak | 2 +-
59
hw/arm/pxa2xx: Replace printf() call by qemu_log_mask()
58
configs/targets/aarch64-softmmu.mak | 2 +-
60
hw/adc/stm32f2xx_adc: Correct memory region size and access size
59
configs/targets/aarch64_be-linux-user.mak | 2 +-
60
configs/targets/arm-linux-user.mak | 2 +-
61
configs/targets/arm-softmmu.mak | 2 +-
62
configs/targets/armeb-linux-user.mak | 2 +-
63
include/hw/arm/xlnx-versal.h | 15 +
64
include/hw/arm/xlnx-zynqmp.h | 5 +
65
include/hw/ide/internal.h | 4 +-
66
include/hw/ipack/ipack.h | 8 +-
67
include/hw/nvram/xlnx-bbram.h | 54 ++
68
include/hw/nvram/xlnx-efuse.h | 132 +++++
69
include/hw/nvram/xlnx-versal-efuse.h | 68 +++
70
include/hw/nvram/xlnx-zynqmp-efuse.h | 44 ++
71
include/hw/pci/pci.h | 10 +-
72
include/hw/qdev-core.h | 6 +-
73
include/hw/scsi/scsi.h | 30 +-
74
target/arm/internals.h | 7 +
75
hw/arm/allwinner-h3.c | 2 +-
76
hw/arm/sabrelite.c | 2 +-
77
hw/arm/xlnx-versal-virt.c | 88 +++
78
hw/arm/xlnx-versal.c | 57 ++
79
hw/arm/xlnx-zcu102.c | 30 ++
80
hw/arm/xlnx-zynqmp.c | 49 ++
81
hw/audio/intel-hda.c | 2 +-
82
hw/block/fdc.c | 2 +-
83
hw/block/swim.c | 3 +-
84
hw/char/virtio-serial-bus.c | 4 +-
85
hw/core/bus.c | 13 +-
86
hw/core/sysbus.c | 10 +-
87
hw/gpio/bcm2835_gpio.c | 3 +-
88
hw/hyperv/vmbus.c | 2 +-
89
hw/i2c/core.c | 2 +-
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
61
176
62
Richard Henderson (6):
63
target/arm: Convert aes and sm4 to gvec helpers
64
target/arm: Convert rax1 to gvec helpers
65
target/arm: Convert sha512 and sm3 to gvec helpers
66
target/arm: Convert sha1 and sha256 to gvec helpers
67
target/arm: Split helper_crypto_sha1_3reg
68
target/arm: Split helper_crypto_sm3tt
69
70
Thomas Huth (1):
71
tests/acceptance: Add a boot test for the xlnx-versal-virt machine
72
73
docs/system/arm/aspeed.rst | 85 ++
74
docs/system/target-arm.rst | 1 +
75
hw/usb/hcd-dwc2.h | 190 +++++
76
include/hw/arm/bcm2835_peripherals.h | 5 +-
77
include/hw/misc/bcm2835_mphi.h | 44 +
78
include/hw/usb/dwc2-regs.h | 899 ++++++++++++++++++++
79
target/arm/helper.h | 45 +-
80
target/arm/translate-a64.h | 3 +
81
target/arm/vec_internal.h | 33 +
82
target/arm/neon-dp.decode | 214 ++++-
83
hw/adc/stm32f2xx_adc.c | 4 +-
84
hw/arm/bcm2835_peripherals.c | 38 +-
85
hw/arm/pxa2xx.c | 66 +-
86
hw/input/pxa2xx_keypad.c | 10 +-
87
hw/misc/bcm2835_mphi.c | 191 +++++
88
hw/ssi/imx_spi.c | 4 +-
89
hw/usb/dev-storage.c | 15 +-
90
hw/usb/hcd-dwc2.c | 1417 ++++++++++++++++++++++++++++++++
91
target/arm/crypto_helper.c | 267 ++++--
92
target/arm/translate-a64.c | 198 ++---
93
target/arm/translate-neon.inc.c | 796 ++++++++++++++----
94
target/arm/translate.c | 539 +-----------
95
target/arm/vec_helper.c | 12 +-
96
hw/misc/Makefile.objs | 1 +
97
hw/usb/Kconfig | 5 +
98
hw/usb/Makefile.objs | 1 +
99
hw/usb/trace-events | 50 ++
100
tests/acceptance/boot_linux_console.py | 35 +-
101
28 files changed, 4258 insertions(+), 910 deletions(-)
102
create mode 100644 docs/system/arm/aspeed.rst
103
create mode 100644 hw/usb/hcd-dwc2.h
104
create mode 100644 include/hw/misc/bcm2835_mphi.h
105
create mode 100644 include/hw/usb/dwc2-regs.h
106
create mode 100644 target/arm/vec_internal.h
107
create mode 100644 hw/misc/bcm2835_mphi.c
108
create mode 100644 hw/usb/hcd-dwc2.c
109
diff view generated by jsdifflib
1
From: Eden Mikitas <e.mikitas@gmail.com>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
When inserting the value retrieved (rx) from the spi slave, rx is pushed to
3
The Allwinner H3 SoC uses Cortex-A7 cores which support virtualization.
4
rx_fifo after being cast to uint8_t. rx_fifo is a fifo32, and the rx
4
However, today we are configuring QEMU to use HVC as PSCI conduit.
5
register the driver uses is also 32 bit. This zeroes the 24 most
6
significant bits of rx. This proved problematic with devices that expect to
7
use the whole 32 bits of the rx register.
8
5
9
Signed-off-by: Eden Mikitas <e.mikitas@gmail.com>
6
That means HVC calls get trapped into QEMU instead of the guest's own
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
emulated CPU and thus break the guest's ability to execute virtualization.
8
9
Fix this by moving to SMC as conduit, freeing up HYP completely to the VM.
10
11
Signed-off-by: Alexander Graf <agraf@csgraf.de>
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>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
19
---
13
hw/ssi/imx_spi.c | 2 +-
20
hw/arm/allwinner-h3.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
21
1 file changed, 1 insertion(+), 1 deletion(-)
15
22
16
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
23
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
17
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/ssi/imx_spi.c
25
--- a/hw/arm/allwinner-h3.c
19
+++ b/hw/ssi/imx_spi.c
26
+++ b/hw/arm/allwinner-h3.c
20
@@ -XXX,XX +XXX,XX @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
27
@@ -XXX,XX +XXX,XX @@ static void allwinner_h3_realize(DeviceState *dev, Error **errp)
21
if (fifo32_is_full(&s->rx_fifo)) {
28
22
s->regs[ECSPI_STATREG] |= ECSPI_STATREG_RO;
29
/* Provide Power State Coordination Interface */
23
} else {
30
qdev_prop_set_int32(DEVICE(&s->cpus[i]), "psci-conduit",
24
- fifo32_push(&s->rx_fifo, (uint8_t)rx);
31
- QEMU_PSCI_CONDUIT_HVC);
25
+ fifo32_push(&s->rx_fifo, rx);
32
+ QEMU_PSCI_CONDUIT_SMC);
26
}
33
27
34
/* Disable secondary CPUs */
28
if (s->burst_length <= 0) {
35
qdev_prop_set_bit(DEVICE(&s->cpus[i]), "start-powered-off",
29
--
36
--
30
2.20.1
37
2.20.1
31
38
32
39
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Rather than passing an opcode to a helper, fully decode the
3
The SMCCC 1.3 spec section 5.2 says
4
operation at translate time. Use clear_tail_16 to zap the
5
balance of the SVE register with the AdvSIMD write.
6
4
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
The Unknown SMC Function Identifier is a sign-extended value of (-1)
8
Message-id: 20200514212831.31248-7-richard.henderson@linaro.org
6
that is returned in the R0, W0 or X0 registers. An implementation must
7
return this error code when it receives:
8
9
* An SMC or HVC call with an unknown Function Identifier
10
* An SMC or HVC call for a removed Function Identifier
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>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
19
---
12
target/arm/helper.h | 5 ++++-
20
target/arm/psci.c | 35 ++++++-----------------------------
13
target/arm/crypto_helper.c | 24 ++++++++++++++++++------
21
1 file changed, 6 insertions(+), 29 deletions(-)
14
target/arm/translate-a64.c | 21 +++++----------------
15
3 files changed, 27 insertions(+), 23 deletions(-)
16
22
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
23
diff --git a/target/arm/psci.c b/target/arm/psci.c
18
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.h
25
--- a/target/arm/psci.c
20
+++ b/target/arm/helper.h
26
+++ b/target/arm/psci.c
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(crypto_sha512su0, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
27
@@ -XXX,XX +XXX,XX @@
22
DEF_HELPER_FLAGS_4(crypto_sha512su1, TCG_CALL_NO_RWG,
28
23
void, ptr, ptr, ptr, i32)
29
bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
24
30
{
25
-DEF_HELPER_FLAGS_5(crypto_sm3tt, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, i32)
31
- /* Return true if the r0/x0 value indicates a PSCI call and
26
+DEF_HELPER_FLAGS_4(crypto_sm3tt1a, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
- * the exception type matches the configured PSCI conduit. This is
27
+DEF_HELPER_FLAGS_4(crypto_sm3tt1b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
- * called before the SMC/HVC instruction is executed, to decide whether
28
+DEF_HELPER_FLAGS_4(crypto_sm3tt2a, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
- * we should treat it as a PSCI call or with the architecturally
29
+DEF_HELPER_FLAGS_4(crypto_sm3tt2b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
35
+ /*
30
DEF_HELPER_FLAGS_4(crypto_sm3partw1, TCG_CALL_NO_RWG,
36
+ * Return true if the exception type matches the configured PSCI conduit.
31
void, ptr, ptr, ptr, i32)
37
+ * This is called before the SMC/HVC instruction is executed, to decide
32
DEF_HELPER_FLAGS_4(crypto_sm3partw2, TCG_CALL_NO_RWG,
38
+ * whether we should treat it as a PSCI call or with the architecturally
33
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
39
* defined behaviour for an SMC or HVC (which might be UNDEF or trap
34
index XXXXXXX..XXXXXXX 100644
40
* to EL2 or to EL3).
35
--- a/target/arm/crypto_helper.c
41
*/
36
+++ b/target/arm/crypto_helper.c
42
- CPUARMState *env = &cpu->env;
37
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm, uint32_t desc)
43
- uint64_t param = is_a64(env) ? env->xregs[0] : env->regs[0];
38
clear_tail_16(vd, desc);
44
45
switch (excp_type) {
46
case EXCP_HVC:
47
@@ -XXX,XX +XXX,XX @@ bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
48
return false;
49
}
50
51
- switch (param) {
52
- case QEMU_PSCI_0_2_FN_PSCI_VERSION:
53
- case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
54
- case QEMU_PSCI_0_2_FN_AFFINITY_INFO:
55
- case QEMU_PSCI_0_2_FN64_AFFINITY_INFO:
56
- case QEMU_PSCI_0_2_FN_SYSTEM_RESET:
57
- case QEMU_PSCI_0_2_FN_SYSTEM_OFF:
58
- case QEMU_PSCI_0_1_FN_CPU_ON:
59
- case QEMU_PSCI_0_2_FN_CPU_ON:
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;
39
}
73
}
40
74
41
-void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
75
void arm_handle_psci_call(ARMCPU *cpu)
42
- uint32_t opcode)
76
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
43
+static inline void QEMU_ALWAYS_INLINE
77
break;
44
+crypto_sm3tt(uint64_t *rd, uint64_t *rn, uint64_t *rm,
78
case QEMU_PSCI_0_1_FN_MIGRATE:
45
+ uint32_t desc, uint32_t opcode)
79
case QEMU_PSCI_0_2_FN_MIGRATE:
46
{
80
+ default:
47
- uint64_t *rd = vd;
81
ret = QEMU_PSCI_RET_NOT_SUPPORTED;
48
- uint64_t *rn = vn;
82
break;
49
- uint64_t *rm = vm;
83
- default:
50
union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
51
union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
52
union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
53
+ uint32_t imm2 = simd_data(desc);
54
uint32_t t;
55
56
assert(imm2 < 4);
57
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
58
/* SM3TT2B */
59
t = cho(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
60
} else {
61
- g_assert_not_reached();
84
- g_assert_not_reached();
62
+ qemu_build_not_reached();
63
}
85
}
64
86
65
t += CR_ST_WORD(d, 0) + CR_ST_WORD(m, imm2);
87
err:
66
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
67
68
rd[0] = d.l[0];
69
rd[1] = d.l[1];
70
+
71
+ clear_tail_16(rd, desc);
72
}
73
74
+#define DO_SM3TT(NAME, OPCODE) \
75
+ void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
76
+ { crypto_sm3tt(vd, vn, vm, desc, OPCODE); }
77
+
78
+DO_SM3TT(crypto_sm3tt1a, 0)
79
+DO_SM3TT(crypto_sm3tt1b, 1)
80
+DO_SM3TT(crypto_sm3tt2a, 2)
81
+DO_SM3TT(crypto_sm3tt2b, 3)
82
+
83
+#undef DO_SM3TT
84
+
85
static uint8_t const sm4_sbox[] = {
86
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7,
87
0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
88
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/translate-a64.c
91
+++ b/target/arm/translate-a64.c
92
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_xar(DisasContext *s, uint32_t insn)
93
*/
94
static void disas_crypto_three_reg_imm2(DisasContext *s, uint32_t insn)
95
{
96
+ static gen_helper_gvec_3 * const fns[4] = {
97
+ gen_helper_crypto_sm3tt1a, gen_helper_crypto_sm3tt1b,
98
+ gen_helper_crypto_sm3tt2a, gen_helper_crypto_sm3tt2b,
99
+ };
100
int opcode = extract32(insn, 10, 2);
101
int imm2 = extract32(insn, 12, 2);
102
int rm = extract32(insn, 16, 5);
103
int rn = extract32(insn, 5, 5);
104
int rd = extract32(insn, 0, 5);
105
- TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
106
- TCGv_i32 tcg_imm2, tcg_opcode;
107
108
if (!dc_isar_feature(aa64_sm3, s)) {
109
unallocated_encoding(s);
110
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_imm2(DisasContext *s, uint32_t insn)
111
return;
112
}
113
114
- tcg_rd_ptr = vec_full_reg_ptr(s, rd);
115
- tcg_rn_ptr = vec_full_reg_ptr(s, rn);
116
- tcg_rm_ptr = vec_full_reg_ptr(s, rm);
117
- tcg_imm2 = tcg_const_i32(imm2);
118
- tcg_opcode = tcg_const_i32(opcode);
119
-
120
- gen_helper_crypto_sm3tt(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr, tcg_imm2,
121
- tcg_opcode);
122
-
123
- tcg_temp_free_ptr(tcg_rd_ptr);
124
- tcg_temp_free_ptr(tcg_rn_ptr);
125
- tcg_temp_free_ptr(tcg_rm_ptr);
126
- tcg_temp_free_i32(tcg_imm2);
127
- tcg_temp_free_i32(tcg_opcode);
128
+ gen_gvec_op3_ool(s, true, rd, rn, rm, imm2, fns[opcode]);
129
}
130
131
/* C3.6 Data processing - SIMD, inc Crypto
132
--
88
--
133
2.20.1
89
2.20.1
134
90
135
91
diff view generated by jsdifflib
1
From: Paul Zimmerman <pauldzim@gmail.com>
1
From: Tong Ho <tong.ho@xilinx.com>
2
2
3
Import the dwc-hsotg (dwc2) register definitions file from the
3
This introduces the QOM for Xilinx eFuse, an one-time
4
Linux kernel. This is a copy of drivers/usb/dwc2/hw.h from the
4
field-programmable storage bit array.
5
mainline Linux kernel, the only changes being to the header, and
6
two instances of 'u32' changed to 'uint32_t' to allow it to
7
compile. Checkpatch throws a boatload of errors due to the tab
8
indentation, but I would rather import it as-is than reformat it.
9
5
10
Signed-off-by: Paul Zimmerman <pauldzim@gmail.com>
6
The actual mmio interface to the array varies by device
11
Message-id: 20200520235349.21215-3-pauldzim@gmail.com
7
families and will be provided in different change-sets.
8
9
Co-authored-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Co-authored-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
11
12
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
14
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
15
Message-id: 20210917052400.1249094-2-tong.ho@xilinx.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
18
---
15
include/hw/usb/dwc2-regs.h | 899 +++++++++++++++++++++++++++++++++++++
19
include/hw/nvram/xlnx-efuse.h | 132 ++++++++++++++++
16
1 file changed, 899 insertions(+)
20
hw/nvram/xlnx-efuse-crc.c | 119 +++++++++++++++
17
create mode 100644 include/hw/usb/dwc2-regs.h
21
hw/nvram/xlnx-efuse.c | 280 ++++++++++++++++++++++++++++++++++
22
hw/nvram/Kconfig | 7 +
23
hw/nvram/meson.build | 2 +
24
5 files changed, 540 insertions(+)
25
create mode 100644 include/hw/nvram/xlnx-efuse.h
26
create mode 100644 hw/nvram/xlnx-efuse-crc.c
27
create mode 100644 hw/nvram/xlnx-efuse.c
18
28
19
diff --git a/include/hw/usb/dwc2-regs.h b/include/hw/usb/dwc2-regs.h
29
diff --git a/include/hw/nvram/xlnx-efuse.h b/include/hw/nvram/xlnx-efuse.h
20
new file mode 100644
30
new file mode 100644
21
index XXXXXXX..XXXXXXX
31
index XXXXXXX..XXXXXXX
22
--- /dev/null
32
--- /dev/null
23
+++ b/include/hw/usb/dwc2-regs.h
33
+++ b/include/hw/nvram/xlnx-efuse.h
24
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@
25
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
26
+/*
35
+/*
27
+ * Imported from the Linux kernel file drivers/usb/dwc2/hw.h, commit
36
+ * QEMU model of the Xilinx eFuse core
28
+ * a89bae709b3492b478480a2c9734e7e9393b279c ("usb: dwc2: Move
37
+ *
29
+ * UTMI_PHY_DATA defines closer")
38
+ * Copyright (c) 2015 Xilinx Inc.
30
+ *
39
+ *
31
+ * hw.h - DesignWare HS OTG Controller hardware definitions
40
+ * Written by Edgar E. Iglesias <edgari@xilinx.com>
32
+ *
41
+ *
33
+ * Copyright 2004-2013 Synopsys, Inc.
42
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
34
+ *
43
+ * of this software and associated documentation files (the "Software"), to deal
35
+ * Redistribution and use in source and binary forms, with or without
44
+ * in the Software without restriction, including without limitation the rights
36
+ * modification, are permitted provided that the following conditions
45
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
37
+ * are met:
46
+ * copies of the Software, and to permit persons to whom the Software is
38
+ * 1. Redistributions of source code must retain the above copyright
47
+ * furnished to do so, subject to the following conditions:
39
+ * notice, this list of conditions, and the following disclaimer,
48
+ *
40
+ * without modification.
49
+ * The above copyright notice and this permission notice shall be included in
41
+ * 2. Redistributions in binary form must reproduce the above copyright
50
+ * all copies or substantial portions of the Software.
42
+ * notice, this list of conditions and the following disclaimer in the
51
+ *
43
+ * documentation and/or other materials provided with the distribution.
52
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
44
+ * 3. The names of the above-listed copyright holders may not be used
53
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
45
+ * to endorse or promote products derived from this software without
54
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
46
+ * specific prior written permission.
55
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
47
+ *
56
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
48
+ * ALTERNATIVELY, this software may be distributed under the terms of the
57
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
49
+ * GNU General Public License ("GPL") as published by the Free Software
58
+ * THE SOFTWARE.
50
+ * Foundation; either version 2 of the License, or (at your option) any
59
+ */
51
+ * later version.
60
+
52
+ *
61
+#ifndef XLNX_EFUSE_H
53
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
62
+#define XLNX_EFUSE_H
54
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
63
+
55
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
64
+#include "sysemu/block-backend.h"
56
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
65
+#include "hw/qdev-core.h"
57
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
66
+
58
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
67
+#define TYPE_XLNX_EFUSE "xlnx,efuse"
59
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
68
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxEFuse, XLNX_EFUSE);
60
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
69
+
61
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
70
+struct XlnxEFuse {
62
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
71
+ DeviceState parent_obj;
63
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72
+ BlockBackend *blk;
64
+ */
73
+ bool blk_ro;
65
+
74
+ uint32_t *fuse32;
66
+#ifndef __DWC2_HW_H__
75
+
67
+#define __DWC2_HW_H__
76
+ DeviceState *dev;
68
+
77
+
69
+#define HSOTG_REG(x)    (x)
78
+ bool init_tbits;
70
+
79
+
71
+#define GOTGCTL                HSOTG_REG(0x000)
80
+ uint8_t efuse_nr;
72
+#define GOTGCTL_CHIRPEN            BIT(27)
81
+ uint32_t efuse_size;
73
+#define GOTGCTL_MULT_VALID_BC_MASK    (0x1f << 22)
82
+
74
+#define GOTGCTL_MULT_VALID_BC_SHIFT    22
83
+ uint32_t *ro_bits;
75
+#define GOTGCTL_OTGVER            BIT(20)
84
+ uint32_t ro_bits_cnt;
76
+#define GOTGCTL_BSESVLD            BIT(19)
85
+};
77
+#define GOTGCTL_ASESVLD            BIT(18)
78
+#define GOTGCTL_DBNC_SHORT        BIT(17)
79
+#define GOTGCTL_CONID_B            BIT(16)
80
+#define GOTGCTL_DBNCE_FLTR_BYPASS    BIT(15)
81
+#define GOTGCTL_DEVHNPEN        BIT(11)
82
+#define GOTGCTL_HSTSETHNPEN        BIT(10)
83
+#define GOTGCTL_HNPREQ            BIT(9)
84
+#define GOTGCTL_HSTNEGSCS        BIT(8)
85
+#define GOTGCTL_SESREQ            BIT(1)
86
+#define GOTGCTL_SESREQSCS        BIT(0)
87
+
88
+#define GOTGINT                HSOTG_REG(0x004)
89
+#define GOTGINT_DBNCE_DONE        BIT(19)
90
+#define GOTGINT_A_DEV_TOUT_CHG        BIT(18)
91
+#define GOTGINT_HST_NEG_DET        BIT(17)
92
+#define GOTGINT_HST_NEG_SUC_STS_CHNG    BIT(9)
93
+#define GOTGINT_SES_REQ_SUC_STS_CHNG    BIT(8)
94
+#define GOTGINT_SES_END_DET        BIT(2)
95
+
96
+#define GAHBCFG                HSOTG_REG(0x008)
97
+#define GAHBCFG_AHB_SINGLE        BIT(23)
98
+#define GAHBCFG_NOTI_ALL_DMA_WRIT    BIT(22)
99
+#define GAHBCFG_REM_MEM_SUPP        BIT(21)
100
+#define GAHBCFG_P_TXF_EMP_LVL        BIT(8)
101
+#define GAHBCFG_NP_TXF_EMP_LVL        BIT(7)
102
+#define GAHBCFG_DMA_EN            BIT(5)
103
+#define GAHBCFG_HBSTLEN_MASK        (0xf << 1)
104
+#define GAHBCFG_HBSTLEN_SHIFT        1
105
+#define GAHBCFG_HBSTLEN_SINGLE        0
106
+#define GAHBCFG_HBSTLEN_INCR        1
107
+#define GAHBCFG_HBSTLEN_INCR4        3
108
+#define GAHBCFG_HBSTLEN_INCR8        5
109
+#define GAHBCFG_HBSTLEN_INCR16        7
110
+#define GAHBCFG_GLBL_INTR_EN        BIT(0)
111
+#define GAHBCFG_CTRL_MASK        (GAHBCFG_P_TXF_EMP_LVL | \
112
+                     GAHBCFG_NP_TXF_EMP_LVL | \
113
+                     GAHBCFG_DMA_EN | \
114
+                     GAHBCFG_GLBL_INTR_EN)
115
+
116
+#define GUSBCFG                HSOTG_REG(0x00C)
117
+#define GUSBCFG_FORCEDEVMODE        BIT(30)
118
+#define GUSBCFG_FORCEHOSTMODE        BIT(29)
119
+#define GUSBCFG_TXENDDELAY        BIT(28)
120
+#define GUSBCFG_ICTRAFFICPULLREMOVE    BIT(27)
121
+#define GUSBCFG_ICUSBCAP        BIT(26)
122
+#define GUSBCFG_ULPI_INT_PROT_DIS    BIT(25)
123
+#define GUSBCFG_INDICATORPASSTHROUGH    BIT(24)
124
+#define GUSBCFG_INDICATORCOMPLEMENT    BIT(23)
125
+#define GUSBCFG_TERMSELDLPULSE        BIT(22)
126
+#define GUSBCFG_ULPI_INT_VBUS_IND    BIT(21)
127
+#define GUSBCFG_ULPI_EXT_VBUS_DRV    BIT(20)
128
+#define GUSBCFG_ULPI_CLK_SUSP_M        BIT(19)
129
+#define GUSBCFG_ULPI_AUTO_RES        BIT(18)
130
+#define GUSBCFG_ULPI_FS_LS        BIT(17)
131
+#define GUSBCFG_OTG_UTMI_FS_SEL        BIT(16)
132
+#define GUSBCFG_PHY_LP_CLK_SEL        BIT(15)
133
+#define GUSBCFG_USBTRDTIM_MASK        (0xf << 10)
134
+#define GUSBCFG_USBTRDTIM_SHIFT        10
135
+#define GUSBCFG_HNPCAP            BIT(9)
136
+#define GUSBCFG_SRPCAP            BIT(8)
137
+#define GUSBCFG_DDRSEL            BIT(7)
138
+#define GUSBCFG_PHYSEL            BIT(6)
139
+#define GUSBCFG_FSINTF            BIT(5)
140
+#define GUSBCFG_ULPI_UTMI_SEL        BIT(4)
141
+#define GUSBCFG_PHYIF16            BIT(3)
142
+#define GUSBCFG_PHYIF8            (0 << 3)
143
+#define GUSBCFG_TOUTCAL_MASK        (0x7 << 0)
144
+#define GUSBCFG_TOUTCAL_SHIFT        0
145
+#define GUSBCFG_TOUTCAL_LIMIT        0x7
146
+#define GUSBCFG_TOUTCAL(_x)        ((_x) << 0)
147
+
148
+#define GRSTCTL                HSOTG_REG(0x010)
149
+#define GRSTCTL_AHBIDLE            BIT(31)
150
+#define GRSTCTL_DMAREQ            BIT(30)
151
+#define GRSTCTL_TXFNUM_MASK        (0x1f << 6)
152
+#define GRSTCTL_TXFNUM_SHIFT        6
153
+#define GRSTCTL_TXFNUM_LIMIT        0x1f
154
+#define GRSTCTL_TXFNUM(_x)        ((_x) << 6)
155
+#define GRSTCTL_TXFFLSH            BIT(5)
156
+#define GRSTCTL_RXFFLSH            BIT(4)
157
+#define GRSTCTL_IN_TKNQ_FLSH        BIT(3)
158
+#define GRSTCTL_FRMCNTRRST        BIT(2)
159
+#define GRSTCTL_HSFTRST            BIT(1)
160
+#define GRSTCTL_CSFTRST            BIT(0)
161
+
162
+#define GINTSTS                HSOTG_REG(0x014)
163
+#define GINTMSK                HSOTG_REG(0x018)
164
+#define GINTSTS_WKUPINT            BIT(31)
165
+#define GINTSTS_SESSREQINT        BIT(30)
166
+#define GINTSTS_DISCONNINT        BIT(29)
167
+#define GINTSTS_CONIDSTSCHNG        BIT(28)
168
+#define GINTSTS_LPMTRANRCVD        BIT(27)
169
+#define GINTSTS_PTXFEMP            BIT(26)
170
+#define GINTSTS_HCHINT            BIT(25)
171
+#define GINTSTS_PRTINT            BIT(24)
172
+#define GINTSTS_RESETDET        BIT(23)
173
+#define GINTSTS_FET_SUSP        BIT(22)
174
+#define GINTSTS_INCOMPL_IP        BIT(21)
175
+#define GINTSTS_INCOMPL_SOOUT        BIT(21)
176
+#define GINTSTS_INCOMPL_SOIN        BIT(20)
177
+#define GINTSTS_OEPINT            BIT(19)
178
+#define GINTSTS_IEPINT            BIT(18)
179
+#define GINTSTS_EPMIS            BIT(17)
180
+#define GINTSTS_RESTOREDONE        BIT(16)
181
+#define GINTSTS_EOPF            BIT(15)
182
+#define GINTSTS_ISOUTDROP        BIT(14)
183
+#define GINTSTS_ENUMDONE        BIT(13)
184
+#define GINTSTS_USBRST            BIT(12)
185
+#define GINTSTS_USBSUSP            BIT(11)
186
+#define GINTSTS_ERLYSUSP        BIT(10)
187
+#define GINTSTS_I2CINT            BIT(9)
188
+#define GINTSTS_ULPI_CK_INT        BIT(8)
189
+#define GINTSTS_GOUTNAKEFF        BIT(7)
190
+#define GINTSTS_GINNAKEFF        BIT(6)
191
+#define GINTSTS_NPTXFEMP        BIT(5)
192
+#define GINTSTS_RXFLVL            BIT(4)
193
+#define GINTSTS_SOF            BIT(3)
194
+#define GINTSTS_OTGINT            BIT(2)
195
+#define GINTSTS_MODEMIS            BIT(1)
196
+#define GINTSTS_CURMODE_HOST        BIT(0)
197
+
198
+#define GRXSTSR                HSOTG_REG(0x01C)
199
+#define GRXSTSP                HSOTG_REG(0x020)
200
+#define GRXSTS_FN_MASK            (0x7f << 25)
201
+#define GRXSTS_FN_SHIFT            25
202
+#define GRXSTS_PKTSTS_MASK        (0xf << 17)
203
+#define GRXSTS_PKTSTS_SHIFT        17
204
+#define GRXSTS_PKTSTS_GLOBALOUTNAK    1
205
+#define GRXSTS_PKTSTS_OUTRX        2
206
+#define GRXSTS_PKTSTS_HCHIN        2
207
+#define GRXSTS_PKTSTS_OUTDONE        3
208
+#define GRXSTS_PKTSTS_HCHIN_XFER_COMP    3
209
+#define GRXSTS_PKTSTS_SETUPDONE        4
210
+#define GRXSTS_PKTSTS_DATATOGGLEERR    5
211
+#define GRXSTS_PKTSTS_SETUPRX        6
212
+#define GRXSTS_PKTSTS_HCHHALTED        7
213
+#define GRXSTS_HCHNUM_MASK        (0xf << 0)
214
+#define GRXSTS_HCHNUM_SHIFT        0
215
+#define GRXSTS_DPID_MASK        (0x3 << 15)
216
+#define GRXSTS_DPID_SHIFT        15
217
+#define GRXSTS_BYTECNT_MASK        (0x7ff << 4)
218
+#define GRXSTS_BYTECNT_SHIFT        4
219
+#define GRXSTS_EPNUM_MASK        (0xf << 0)
220
+#define GRXSTS_EPNUM_SHIFT        0
221
+
222
+#define GRXFSIZ                HSOTG_REG(0x024)
223
+#define GRXFSIZ_DEPTH_MASK        (0xffff << 0)
224
+#define GRXFSIZ_DEPTH_SHIFT        0
225
+
226
+#define GNPTXFSIZ            HSOTG_REG(0x028)
227
+/* Use FIFOSIZE_* constants to access this register */
228
+
229
+#define GNPTXSTS            HSOTG_REG(0x02C)
230
+#define GNPTXSTS_NP_TXQ_TOP_MASK        (0x7f << 24)
231
+#define GNPTXSTS_NP_TXQ_TOP_SHIFT        24
232
+#define GNPTXSTS_NP_TXQ_SPC_AVAIL_MASK        (0xff << 16)
233
+#define GNPTXSTS_NP_TXQ_SPC_AVAIL_SHIFT        16
234
+#define GNPTXSTS_NP_TXQ_SPC_AVAIL_GET(_v)    (((_v) >> 16) & 0xff)
235
+#define GNPTXSTS_NP_TXF_SPC_AVAIL_MASK        (0xffff << 0)
236
+#define GNPTXSTS_NP_TXF_SPC_AVAIL_SHIFT        0
237
+#define GNPTXSTS_NP_TXF_SPC_AVAIL_GET(_v)    (((_v) >> 0) & 0xffff)
238
+
239
+#define GI2CCTL                HSOTG_REG(0x0030)
240
+#define GI2CCTL_BSYDNE            BIT(31)
241
+#define GI2CCTL_RW            BIT(30)
242
+#define GI2CCTL_I2CDATSE0        BIT(28)
243
+#define GI2CCTL_I2CDEVADDR_MASK        (0x3 << 26)
244
+#define GI2CCTL_I2CDEVADDR_SHIFT    26
245
+#define GI2CCTL_I2CSUSPCTL        BIT(25)
246
+#define GI2CCTL_ACK            BIT(24)
247
+#define GI2CCTL_I2CEN            BIT(23)
248
+#define GI2CCTL_ADDR_MASK        (0x7f << 16)
249
+#define GI2CCTL_ADDR_SHIFT        16
250
+#define GI2CCTL_REGADDR_MASK        (0xff << 8)
251
+#define GI2CCTL_REGADDR_SHIFT        8
252
+#define GI2CCTL_RWDATA_MASK        (0xff << 0)
253
+#define GI2CCTL_RWDATA_SHIFT        0
254
+
255
+#define GPVNDCTL            HSOTG_REG(0x0034)
256
+#define GGPIO                HSOTG_REG(0x0038)
257
+#define GGPIO_STM32_OTG_GCCFG_PWRDWN    BIT(16)
258
+
259
+#define GUID                HSOTG_REG(0x003c)
260
+#define GSNPSID                HSOTG_REG(0x0040)
261
+#define GHWCFG1                HSOTG_REG(0x0044)
262
+#define GSNPSID_ID_MASK            GENMASK(31, 16)
263
+
264
+#define GHWCFG2                HSOTG_REG(0x0048)
265
+#define GHWCFG2_OTG_ENABLE_IC_USB        BIT(31)
266
+#define GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK        (0x1f << 26)
267
+#define GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT        26
268
+#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK    (0x3 << 24)
269
+#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT    24
270
+#define GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK    (0x3 << 22)
271
+#define GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT    22
272
+#define GHWCFG2_MULTI_PROC_INT            BIT(20)
273
+#define GHWCFG2_DYNAMIC_FIFO            BIT(19)
274
+#define GHWCFG2_PERIO_EP_SUPPORTED        BIT(18)
275
+#define GHWCFG2_NUM_HOST_CHAN_MASK        (0xf << 14)
276
+#define GHWCFG2_NUM_HOST_CHAN_SHIFT        14
277
+#define GHWCFG2_NUM_DEV_EP_MASK            (0xf << 10)
278
+#define GHWCFG2_NUM_DEV_EP_SHIFT        10
279
+#define GHWCFG2_FS_PHY_TYPE_MASK        (0x3 << 8)
280
+#define GHWCFG2_FS_PHY_TYPE_SHIFT        8
281
+#define GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED    0
282
+#define GHWCFG2_FS_PHY_TYPE_DEDICATED        1
283
+#define GHWCFG2_FS_PHY_TYPE_SHARED_UTMI        2
284
+#define GHWCFG2_FS_PHY_TYPE_SHARED_ULPI        3
285
+#define GHWCFG2_HS_PHY_TYPE_MASK        (0x3 << 6)
286
+#define GHWCFG2_HS_PHY_TYPE_SHIFT        6
287
+#define GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED    0
288
+#define GHWCFG2_HS_PHY_TYPE_UTMI        1
289
+#define GHWCFG2_HS_PHY_TYPE_ULPI        2
290
+#define GHWCFG2_HS_PHY_TYPE_UTMI_ULPI        3
291
+#define GHWCFG2_POINT2POINT            BIT(5)
292
+#define GHWCFG2_ARCHITECTURE_MASK        (0x3 << 3)
293
+#define GHWCFG2_ARCHITECTURE_SHIFT        3
294
+#define GHWCFG2_SLAVE_ONLY_ARCH            0
295
+#define GHWCFG2_EXT_DMA_ARCH            1
296
+#define GHWCFG2_INT_DMA_ARCH            2
297
+#define GHWCFG2_OP_MODE_MASK            (0x7 << 0)
298
+#define GHWCFG2_OP_MODE_SHIFT            0
299
+#define GHWCFG2_OP_MODE_HNP_SRP_CAPABLE        0
300
+#define GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE    1
301
+#define GHWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE    2
302
+#define GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE    3
303
+#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE    4
304
+#define GHWCFG2_OP_MODE_SRP_CAPABLE_HOST    5
305
+#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST    6
306
+#define GHWCFG2_OP_MODE_UNDEFINED        7
307
+
308
+#define GHWCFG3                HSOTG_REG(0x004c)
309
+#define GHWCFG3_DFIFO_DEPTH_MASK        (0xffff << 16)
310
+#define GHWCFG3_DFIFO_DEPTH_SHIFT        16
311
+#define GHWCFG3_OTG_LPM_EN            BIT(15)
312
+#define GHWCFG3_BC_SUPPORT            BIT(14)
313
+#define GHWCFG3_OTG_ENABLE_HSIC            BIT(13)
314
+#define GHWCFG3_ADP_SUPP            BIT(12)
315
+#define GHWCFG3_SYNCH_RESET_TYPE        BIT(11)
316
+#define GHWCFG3_OPTIONAL_FEATURES        BIT(10)
317
+#define GHWCFG3_VENDOR_CTRL_IF            BIT(9)
318
+#define GHWCFG3_I2C                BIT(8)
319
+#define GHWCFG3_OTG_FUNC            BIT(7)
320
+#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK    (0x7 << 4)
321
+#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT    4
322
+#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK    (0xf << 0)
323
+#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT    0
324
+
325
+#define GHWCFG4                HSOTG_REG(0x0050)
326
+#define GHWCFG4_DESC_DMA_DYN            BIT(31)
327
+#define GHWCFG4_DESC_DMA            BIT(30)
328
+#define GHWCFG4_NUM_IN_EPS_MASK            (0xf << 26)
329
+#define GHWCFG4_NUM_IN_EPS_SHIFT        26
330
+#define GHWCFG4_DED_FIFO_EN            BIT(25)
331
+#define GHWCFG4_DED_FIFO_SHIFT        25
332
+#define GHWCFG4_SESSION_END_FILT_EN        BIT(24)
333
+#define GHWCFG4_B_VALID_FILT_EN            BIT(23)
334
+#define GHWCFG4_A_VALID_FILT_EN            BIT(22)
335
+#define GHWCFG4_VBUS_VALID_FILT_EN        BIT(21)
336
+#define GHWCFG4_IDDIG_FILT_EN            BIT(20)
337
+#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_MASK    (0xf << 16)
338
+#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_SHIFT    16
339
+#define GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK    (0x3 << 14)
340
+#define GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT    14
341
+#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8        0
342
+#define GHWCFG4_UTMI_PHY_DATA_WIDTH_16        1
343
+#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8_OR_16    2
344
+#define GHWCFG4_ACG_SUPPORTED            BIT(12)
345
+#define GHWCFG4_IPG_ISOC_SUPPORTED        BIT(11)
346
+#define GHWCFG4_SERVICE_INTERVAL_SUPPORTED BIT(10)
347
+#define GHWCFG4_XHIBER                BIT(7)
348
+#define GHWCFG4_HIBER                BIT(6)
349
+#define GHWCFG4_MIN_AHB_FREQ            BIT(5)
350
+#define GHWCFG4_POWER_OPTIMIZ            BIT(4)
351
+#define GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK    (0xf << 0)
352
+#define GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT    0
353
+
354
+#define GLPMCFG                HSOTG_REG(0x0054)
355
+#define GLPMCFG_INVSELHSIC        BIT(31)
356
+#define GLPMCFG_HSICCON            BIT(30)
357
+#define GLPMCFG_RSTRSLPSTS        BIT(29)
358
+#define GLPMCFG_ENBESL            BIT(28)
359
+#define GLPMCFG_LPM_RETRYCNT_STS_MASK    (0x7 << 25)
360
+#define GLPMCFG_LPM_RETRYCNT_STS_SHIFT    25
361
+#define GLPMCFG_SNDLPM            BIT(24)
362
+#define GLPMCFG_RETRY_CNT_MASK        (0x7 << 21)
363
+#define GLPMCFG_RETRY_CNT_SHIFT        21
364
+#define GLPMCFG_LPM_REJECT_CTRL_CONTROL    BIT(21)
365
+#define GLPMCFG_LPM_ACCEPT_CTRL_ISOC    BIT(22)
366
+#define GLPMCFG_LPM_CHNL_INDX_MASK    (0xf << 17)
367
+#define GLPMCFG_LPM_CHNL_INDX_SHIFT    17
368
+#define GLPMCFG_L1RESUMEOK        BIT(16)
369
+#define GLPMCFG_SLPSTS            BIT(15)
370
+#define GLPMCFG_COREL1RES_MASK        (0x3 << 13)
371
+#define GLPMCFG_COREL1RES_SHIFT        13
372
+#define GLPMCFG_HIRD_THRES_MASK        (0x1f << 8)
373
+#define GLPMCFG_HIRD_THRES_SHIFT    8
374
+#define GLPMCFG_HIRD_THRES_EN        (0x10 << 8)
375
+#define GLPMCFG_ENBLSLPM        BIT(7)
376
+#define GLPMCFG_BREMOTEWAKE        BIT(6)
377
+#define GLPMCFG_HIRD_MASK        (0xf << 2)
378
+#define GLPMCFG_HIRD_SHIFT        2
379
+#define GLPMCFG_APPL1RES        BIT(1)
380
+#define GLPMCFG_LPMCAP            BIT(0)
381
+
382
+#define GPWRDN                HSOTG_REG(0x0058)
383
+#define GPWRDN_MULT_VAL_ID_BC_MASK    (0x1f << 24)
384
+#define GPWRDN_MULT_VAL_ID_BC_SHIFT    24
385
+#define GPWRDN_ADP_INT            BIT(23)
386
+#define GPWRDN_BSESSVLD            BIT(22)
387
+#define GPWRDN_IDSTS            BIT(21)
388
+#define GPWRDN_LINESTATE_MASK        (0x3 << 19)
389
+#define GPWRDN_LINESTATE_SHIFT        19
390
+#define GPWRDN_STS_CHGINT_MSK        BIT(18)
391
+#define GPWRDN_STS_CHGINT        BIT(17)
392
+#define GPWRDN_SRP_DET_MSK        BIT(16)
393
+#define GPWRDN_SRP_DET            BIT(15)
394
+#define GPWRDN_CONNECT_DET_MSK        BIT(14)
395
+#define GPWRDN_CONNECT_DET        BIT(13)
396
+#define GPWRDN_DISCONN_DET_MSK        BIT(12)
397
+#define GPWRDN_DISCONN_DET        BIT(11)
398
+#define GPWRDN_RST_DET_MSK        BIT(10)
399
+#define GPWRDN_RST_DET            BIT(9)
400
+#define GPWRDN_LNSTSCHG_MSK        BIT(8)
401
+#define GPWRDN_LNSTSCHG            BIT(7)
402
+#define GPWRDN_DIS_VBUS            BIT(6)
403
+#define GPWRDN_PWRDNSWTCH        BIT(5)
404
+#define GPWRDN_PWRDNRSTN        BIT(4)
405
+#define GPWRDN_PWRDNCLMP        BIT(3)
406
+#define GPWRDN_RESTORE            BIT(2)
407
+#define GPWRDN_PMUACTV            BIT(1)
408
+#define GPWRDN_PMUINTSEL        BIT(0)
409
+
410
+#define GDFIFOCFG            HSOTG_REG(0x005c)
411
+#define GDFIFOCFG_EPINFOBASE_MASK    (0xffff << 16)
412
+#define GDFIFOCFG_EPINFOBASE_SHIFT    16
413
+#define GDFIFOCFG_GDFIFOCFG_MASK    (0xffff << 0)
414
+#define GDFIFOCFG_GDFIFOCFG_SHIFT    0
415
+
416
+#define ADPCTL                HSOTG_REG(0x0060)
417
+#define ADPCTL_AR_MASK            (0x3 << 27)
418
+#define ADPCTL_AR_SHIFT            27
419
+#define ADPCTL_ADP_TMOUT_INT_MSK    BIT(26)
420
+#define ADPCTL_ADP_SNS_INT_MSK        BIT(25)
421
+#define ADPCTL_ADP_PRB_INT_MSK        BIT(24)
422
+#define ADPCTL_ADP_TMOUT_INT        BIT(23)
423
+#define ADPCTL_ADP_SNS_INT        BIT(22)
424
+#define ADPCTL_ADP_PRB_INT        BIT(21)
425
+#define ADPCTL_ADPENA            BIT(20)
426
+#define ADPCTL_ADPRES            BIT(19)
427
+#define ADPCTL_ENASNS            BIT(18)
428
+#define ADPCTL_ENAPRB            BIT(17)
429
+#define ADPCTL_RTIM_MASK        (0x7ff << 6)
430
+#define ADPCTL_RTIM_SHIFT        6
431
+#define ADPCTL_PRB_PER_MASK        (0x3 << 4)
432
+#define ADPCTL_PRB_PER_SHIFT        4
433
+#define ADPCTL_PRB_DELTA_MASK        (0x3 << 2)
434
+#define ADPCTL_PRB_DELTA_SHIFT        2
435
+#define ADPCTL_PRB_DSCHRG_MASK        (0x3 << 0)
436
+#define ADPCTL_PRB_DSCHRG_SHIFT        0
437
+
438
+#define GREFCLK                 HSOTG_REG(0x0064)
439
+#define GREFCLK_REFCLKPER_MASK         (0x1ffff << 15)
440
+#define GREFCLK_REFCLKPER_SHIFT         15
441
+#define GREFCLK_REF_CLK_MODE         BIT(14)
442
+#define GREFCLK_SOF_CNT_WKUP_ALERT_MASK     (0x3ff)
443
+#define GREFCLK_SOF_CNT_WKUP_ALERT_SHIFT 0
444
+
445
+#define GINTMSK2            HSOTG_REG(0x0068)
446
+#define GINTMSK2_WKUP_ALERT_INT_MSK    BIT(0)
447
+
448
+#define GINTSTS2            HSOTG_REG(0x006c)
449
+#define GINTSTS2_WKUP_ALERT_INT        BIT(0)
450
+
451
+#define HPTXFSIZ            HSOTG_REG(0x100)
452
+/* Use FIFOSIZE_* constants to access this register */
453
+
454
+#define DPTXFSIZN(_a)            HSOTG_REG(0x104 + (((_a) - 1) * 4))
455
+/* Use FIFOSIZE_* constants to access this register */
456
+
457
+/* These apply to the GNPTXFSIZ, HPTXFSIZ and DPTXFSIZN registers */
458
+#define FIFOSIZE_DEPTH_MASK        (0xffff << 16)
459
+#define FIFOSIZE_DEPTH_SHIFT        16
460
+#define FIFOSIZE_STARTADDR_MASK        (0xffff << 0)
461
+#define FIFOSIZE_STARTADDR_SHIFT    0
462
+#define FIFOSIZE_DEPTH_GET(_x)        (((_x) >> 16) & 0xffff)
463
+
464
+/* Device mode registers */
465
+
466
+#define DCFG                HSOTG_REG(0x800)
467
+#define DCFG_DESCDMA_EN            BIT(23)
468
+#define DCFG_EPMISCNT_MASK        (0x1f << 18)
469
+#define DCFG_EPMISCNT_SHIFT        18
470
+#define DCFG_EPMISCNT_LIMIT        0x1f
471
+#define DCFG_EPMISCNT(_x)        ((_x) << 18)
472
+#define DCFG_IPG_ISOC_SUPPORDED        BIT(17)
473
+#define DCFG_PERFRINT_MASK        (0x3 << 11)
474
+#define DCFG_PERFRINT_SHIFT        11
475
+#define DCFG_PERFRINT_LIMIT        0x3
476
+#define DCFG_PERFRINT(_x)        ((_x) << 11)
477
+#define DCFG_DEVADDR_MASK        (0x7f << 4)
478
+#define DCFG_DEVADDR_SHIFT        4
479
+#define DCFG_DEVADDR_LIMIT        0x7f
480
+#define DCFG_DEVADDR(_x)        ((_x) << 4)
481
+#define DCFG_NZ_STS_OUT_HSHK        BIT(2)
482
+#define DCFG_DEVSPD_MASK        (0x3 << 0)
483
+#define DCFG_DEVSPD_SHIFT        0
484
+#define DCFG_DEVSPD_HS            0
485
+#define DCFG_DEVSPD_FS            1
486
+#define DCFG_DEVSPD_LS            2
487
+#define DCFG_DEVSPD_FS48        3
488
+
489
+#define DCTL                HSOTG_REG(0x804)
490
+#define DCTL_SERVICE_INTERVAL_SUPPORTED BIT(19)
491
+#define DCTL_PWRONPRGDONE        BIT(11)
492
+#define DCTL_CGOUTNAK            BIT(10)
493
+#define DCTL_SGOUTNAK            BIT(9)
494
+#define DCTL_CGNPINNAK            BIT(8)
495
+#define DCTL_SGNPINNAK            BIT(7)
496
+#define DCTL_TSTCTL_MASK        (0x7 << 4)
497
+#define DCTL_TSTCTL_SHIFT        4
498
+#define DCTL_GOUTNAKSTS            BIT(3)
499
+#define DCTL_GNPINNAKSTS        BIT(2)
500
+#define DCTL_SFTDISCON            BIT(1)
501
+#define DCTL_RMTWKUPSIG            BIT(0)
502
+
503
+#define DSTS                HSOTG_REG(0x808)
504
+#define DSTS_SOFFN_MASK            (0x3fff << 8)
505
+#define DSTS_SOFFN_SHIFT        8
506
+#define DSTS_SOFFN_LIMIT        0x3fff
507
+#define DSTS_SOFFN(_x)            ((_x) << 8)
508
+#define DSTS_ERRATICERR            BIT(3)
509
+#define DSTS_ENUMSPD_MASK        (0x3 << 1)
510
+#define DSTS_ENUMSPD_SHIFT        1
511
+#define DSTS_ENUMSPD_HS            0
512
+#define DSTS_ENUMSPD_FS            1
513
+#define DSTS_ENUMSPD_LS            2
514
+#define DSTS_ENUMSPD_FS48        3
515
+#define DSTS_SUSPSTS            BIT(0)
516
+
517
+#define DIEPMSK                HSOTG_REG(0x810)
518
+#define DIEPMSK_NAKMSK            BIT(13)
519
+#define DIEPMSK_BNAININTRMSK        BIT(9)
520
+#define DIEPMSK_TXFIFOUNDRNMSK        BIT(8)
521
+#define DIEPMSK_TXFIFOEMPTY        BIT(7)
522
+#define DIEPMSK_INEPNAKEFFMSK        BIT(6)
523
+#define DIEPMSK_INTKNEPMISMSK        BIT(5)
524
+#define DIEPMSK_INTKNTXFEMPMSK        BIT(4)
525
+#define DIEPMSK_TIMEOUTMSK        BIT(3)
526
+#define DIEPMSK_AHBERRMSK        BIT(2)
527
+#define DIEPMSK_EPDISBLDMSK        BIT(1)
528
+#define DIEPMSK_XFERCOMPLMSK        BIT(0)
529
+
530
+#define DOEPMSK                HSOTG_REG(0x814)
531
+#define DOEPMSK_BNAMSK            BIT(9)
532
+#define DOEPMSK_BACK2BACKSETUP        BIT(6)
533
+#define DOEPMSK_STSPHSERCVDMSK        BIT(5)
534
+#define DOEPMSK_OUTTKNEPDISMSK        BIT(4)
535
+#define DOEPMSK_SETUPMSK        BIT(3)
536
+#define DOEPMSK_AHBERRMSK        BIT(2)
537
+#define DOEPMSK_EPDISBLDMSK        BIT(1)
538
+#define DOEPMSK_XFERCOMPLMSK        BIT(0)
539
+
540
+#define DAINT                HSOTG_REG(0x818)
541
+#define DAINTMSK            HSOTG_REG(0x81C)
542
+#define DAINT_OUTEP_SHIFT        16
543
+#define DAINT_OUTEP(_x)            (1 << ((_x) + 16))
544
+#define DAINT_INEP(_x)            (1 << (_x))
545
+
546
+#define DTKNQR1                HSOTG_REG(0x820)
547
+#define DTKNQR2                HSOTG_REG(0x824)
548
+#define DTKNQR3                HSOTG_REG(0x830)
549
+#define DTKNQR4                HSOTG_REG(0x834)
550
+#define DIEPEMPMSK            HSOTG_REG(0x834)
551
+
552
+#define DVBUSDIS            HSOTG_REG(0x828)
553
+#define DVBUSPULSE            HSOTG_REG(0x82C)
554
+
555
+#define DIEPCTL0            HSOTG_REG(0x900)
556
+#define DIEPCTL(_a)            HSOTG_REG(0x900 + ((_a) * 0x20))
557
+
558
+#define DOEPCTL0            HSOTG_REG(0xB00)
559
+#define DOEPCTL(_a)            HSOTG_REG(0xB00 + ((_a) * 0x20))
560
+
561
+/* EP0 specialness:
562
+ * bits[29..28] - reserved (no SetD0PID, SetD1PID)
563
+ * bits[25..22] - should always be zero, this isn't a periodic endpoint
564
+ * bits[10..0] - MPS setting different for EP0
565
+ */
566
+#define D0EPCTL_MPS_MASK        (0x3 << 0)
567
+#define D0EPCTL_MPS_SHIFT        0
568
+#define D0EPCTL_MPS_64            0
569
+#define D0EPCTL_MPS_32            1
570
+#define D0EPCTL_MPS_16            2
571
+#define D0EPCTL_MPS_8            3
572
+
573
+#define DXEPCTL_EPENA            BIT(31)
574
+#define DXEPCTL_EPDIS            BIT(30)
575
+#define DXEPCTL_SETD1PID        BIT(29)
576
+#define DXEPCTL_SETODDFR        BIT(29)
577
+#define DXEPCTL_SETD0PID        BIT(28)
578
+#define DXEPCTL_SETEVENFR        BIT(28)
579
+#define DXEPCTL_SNAK            BIT(27)
580
+#define DXEPCTL_CNAK            BIT(26)
581
+#define DXEPCTL_TXFNUM_MASK        (0xf << 22)
582
+#define DXEPCTL_TXFNUM_SHIFT        22
583
+#define DXEPCTL_TXFNUM_LIMIT        0xf
584
+#define DXEPCTL_TXFNUM(_x)        ((_x) << 22)
585
+#define DXEPCTL_STALL            BIT(21)
586
+#define DXEPCTL_SNP            BIT(20)
587
+#define DXEPCTL_EPTYPE_MASK        (0x3 << 18)
588
+#define DXEPCTL_EPTYPE_CONTROL        (0x0 << 18)
589
+#define DXEPCTL_EPTYPE_ISO        (0x1 << 18)
590
+#define DXEPCTL_EPTYPE_BULK        (0x2 << 18)
591
+#define DXEPCTL_EPTYPE_INTERRUPT    (0x3 << 18)
592
+
593
+#define DXEPCTL_NAKSTS            BIT(17)
594
+#define DXEPCTL_DPID            BIT(16)
595
+#define DXEPCTL_EOFRNUM            BIT(16)
596
+#define DXEPCTL_USBACTEP        BIT(15)
597
+#define DXEPCTL_NEXTEP_MASK        (0xf << 11)
598
+#define DXEPCTL_NEXTEP_SHIFT        11
599
+#define DXEPCTL_NEXTEP_LIMIT        0xf
600
+#define DXEPCTL_NEXTEP(_x)        ((_x) << 11)
601
+#define DXEPCTL_MPS_MASK        (0x7ff << 0)
602
+#define DXEPCTL_MPS_SHIFT        0
603
+#define DXEPCTL_MPS_LIMIT        0x7ff
604
+#define DXEPCTL_MPS(_x)            ((_x) << 0)
605
+
606
+#define DIEPINT(_a)            HSOTG_REG(0x908 + ((_a) * 0x20))
607
+#define DOEPINT(_a)            HSOTG_REG(0xB08 + ((_a) * 0x20))
608
+#define DXEPINT_SETUP_RCVD        BIT(15)
609
+#define DXEPINT_NYETINTRPT        BIT(14)
610
+#define DXEPINT_NAKINTRPT        BIT(13)
611
+#define DXEPINT_BBLEERRINTRPT        BIT(12)
612
+#define DXEPINT_PKTDRPSTS        BIT(11)
613
+#define DXEPINT_BNAINTR            BIT(9)
614
+#define DXEPINT_TXFIFOUNDRN        BIT(8)
615
+#define DXEPINT_OUTPKTERR        BIT(8)
616
+#define DXEPINT_TXFEMP            BIT(7)
617
+#define DXEPINT_INEPNAKEFF        BIT(6)
618
+#define DXEPINT_BACK2BACKSETUP        BIT(6)
619
+#define DXEPINT_INTKNEPMIS        BIT(5)
620
+#define DXEPINT_STSPHSERCVD        BIT(5)
621
+#define DXEPINT_INTKNTXFEMP        BIT(4)
622
+#define DXEPINT_OUTTKNEPDIS        BIT(4)
623
+#define DXEPINT_TIMEOUT            BIT(3)
624
+#define DXEPINT_SETUP            BIT(3)
625
+#define DXEPINT_AHBERR            BIT(2)
626
+#define DXEPINT_EPDISBLD        BIT(1)
627
+#define DXEPINT_XFERCOMPL        BIT(0)
628
+
629
+#define DIEPTSIZ0            HSOTG_REG(0x910)
630
+#define DIEPTSIZ0_PKTCNT_MASK        (0x3 << 19)
631
+#define DIEPTSIZ0_PKTCNT_SHIFT        19
632
+#define DIEPTSIZ0_PKTCNT_LIMIT        0x3
633
+#define DIEPTSIZ0_PKTCNT(_x)        ((_x) << 19)
634
+#define DIEPTSIZ0_XFERSIZE_MASK        (0x7f << 0)
635
+#define DIEPTSIZ0_XFERSIZE_SHIFT    0
636
+#define DIEPTSIZ0_XFERSIZE_LIMIT    0x7f
637
+#define DIEPTSIZ0_XFERSIZE(_x)        ((_x) << 0)
638
+
639
+#define DOEPTSIZ0            HSOTG_REG(0xB10)
640
+#define DOEPTSIZ0_SUPCNT_MASK        (0x3 << 29)
641
+#define DOEPTSIZ0_SUPCNT_SHIFT        29
642
+#define DOEPTSIZ0_SUPCNT_LIMIT        0x3
643
+#define DOEPTSIZ0_SUPCNT(_x)        ((_x) << 29)
644
+#define DOEPTSIZ0_PKTCNT        BIT(19)
645
+#define DOEPTSIZ0_XFERSIZE_MASK        (0x7f << 0)
646
+#define DOEPTSIZ0_XFERSIZE_SHIFT    0
647
+
648
+#define DIEPTSIZ(_a)            HSOTG_REG(0x910 + ((_a) * 0x20))
649
+#define DOEPTSIZ(_a)            HSOTG_REG(0xB10 + ((_a) * 0x20))
650
+#define DXEPTSIZ_MC_MASK        (0x3 << 29)
651
+#define DXEPTSIZ_MC_SHIFT        29
652
+#define DXEPTSIZ_MC_LIMIT        0x3
653
+#define DXEPTSIZ_MC(_x)            ((_x) << 29)
654
+#define DXEPTSIZ_PKTCNT_MASK        (0x3ff << 19)
655
+#define DXEPTSIZ_PKTCNT_SHIFT        19
656
+#define DXEPTSIZ_PKTCNT_LIMIT        0x3ff
657
+#define DXEPTSIZ_PKTCNT_GET(_v)        (((_v) >> 19) & 0x3ff)
658
+#define DXEPTSIZ_PKTCNT(_x)        ((_x) << 19)
659
+#define DXEPTSIZ_XFERSIZE_MASK        (0x7ffff << 0)
660
+#define DXEPTSIZ_XFERSIZE_SHIFT        0
661
+#define DXEPTSIZ_XFERSIZE_LIMIT        0x7ffff
662
+#define DXEPTSIZ_XFERSIZE_GET(_v)    (((_v) >> 0) & 0x7ffff)
663
+#define DXEPTSIZ_XFERSIZE(_x)        ((_x) << 0)
664
+
665
+#define DIEPDMA(_a)            HSOTG_REG(0x914 + ((_a) * 0x20))
666
+#define DOEPDMA(_a)            HSOTG_REG(0xB14 + ((_a) * 0x20))
667
+
668
+#define DTXFSTS(_a)            HSOTG_REG(0x918 + ((_a) * 0x20))
669
+
670
+#define PCGCTL                HSOTG_REG(0x0e00)
671
+#define PCGCTL_IF_DEV_MODE        BIT(31)
672
+#define PCGCTL_P2HD_PRT_SPD_MASK    (0x3 << 29)
673
+#define PCGCTL_P2HD_PRT_SPD_SHIFT    29
674
+#define PCGCTL_P2HD_DEV_ENUM_SPD_MASK    (0x3 << 27)
675
+#define PCGCTL_P2HD_DEV_ENUM_SPD_SHIFT    27
676
+#define PCGCTL_MAC_DEV_ADDR_MASK    (0x7f << 20)
677
+#define PCGCTL_MAC_DEV_ADDR_SHIFT    20
678
+#define PCGCTL_MAX_TERMSEL        BIT(19)
679
+#define PCGCTL_MAX_XCVRSELECT_MASK    (0x3 << 17)
680
+#define PCGCTL_MAX_XCVRSELECT_SHIFT    17
681
+#define PCGCTL_PORT_POWER        BIT(16)
682
+#define PCGCTL_PRT_CLK_SEL_MASK        (0x3 << 14)
683
+#define PCGCTL_PRT_CLK_SEL_SHIFT    14
684
+#define PCGCTL_ESS_REG_RESTORED        BIT(13)
685
+#define PCGCTL_EXTND_HIBER_SWITCH    BIT(12)
686
+#define PCGCTL_EXTND_HIBER_PWRCLMP    BIT(11)
687
+#define PCGCTL_ENBL_EXTND_HIBER        BIT(10)
688
+#define PCGCTL_RESTOREMODE        BIT(9)
689
+#define PCGCTL_RESETAFTSUSP        BIT(8)
690
+#define PCGCTL_DEEP_SLEEP        BIT(7)
691
+#define PCGCTL_PHY_IN_SLEEP        BIT(6)
692
+#define PCGCTL_ENBL_SLEEP_GATING    BIT(5)
693
+#define PCGCTL_RSTPDWNMODULE        BIT(3)
694
+#define PCGCTL_PWRCLMP            BIT(2)
695
+#define PCGCTL_GATEHCLK            BIT(1)
696
+#define PCGCTL_STOPPCLK            BIT(0)
697
+
698
+#define PCGCCTL1 HSOTG_REG(0xe04)
699
+#define PCGCCTL1_TIMER (0x3 << 1)
700
+#define PCGCCTL1_GATEEN BIT(0)
701
+
702
+#define EPFIFO(_a)            HSOTG_REG(0x1000 + ((_a) * 0x1000))
703
+
704
+/* Host Mode Registers */
705
+
706
+#define HCFG                HSOTG_REG(0x0400)
707
+#define HCFG_MODECHTIMEN        BIT(31)
708
+#define HCFG_PERSCHEDENA        BIT(26)
709
+#define HCFG_FRLISTEN_MASK        (0x3 << 24)
710
+#define HCFG_FRLISTEN_SHIFT        24
711
+#define HCFG_FRLISTEN_8                (0 << 24)
712
+#define FRLISTEN_8_SIZE                8
713
+#define HCFG_FRLISTEN_16            BIT(24)
714
+#define FRLISTEN_16_SIZE            16
715
+#define HCFG_FRLISTEN_32            (2 << 24)
716
+#define FRLISTEN_32_SIZE            32
717
+#define HCFG_FRLISTEN_64            (3 << 24)
718
+#define FRLISTEN_64_SIZE            64
719
+#define HCFG_DESCDMA            BIT(23)
720
+#define HCFG_RESVALID_MASK        (0xff << 8)
721
+#define HCFG_RESVALID_SHIFT        8
722
+#define HCFG_ENA32KHZ            BIT(7)
723
+#define HCFG_FSLSSUPP            BIT(2)
724
+#define HCFG_FSLSPCLKSEL_MASK        (0x3 << 0)
725
+#define HCFG_FSLSPCLKSEL_SHIFT        0
726
+#define HCFG_FSLSPCLKSEL_30_60_MHZ    0
727
+#define HCFG_FSLSPCLKSEL_48_MHZ        1
728
+#define HCFG_FSLSPCLKSEL_6_MHZ        2
729
+
730
+#define HFIR                HSOTG_REG(0x0404)
731
+#define HFIR_FRINT_MASK            (0xffff << 0)
732
+#define HFIR_FRINT_SHIFT        0
733
+#define HFIR_RLDCTRL            BIT(16)
734
+
735
+#define HFNUM                HSOTG_REG(0x0408)
736
+#define HFNUM_FRREM_MASK        (0xffff << 16)
737
+#define HFNUM_FRREM_SHIFT        16
738
+#define HFNUM_FRNUM_MASK        (0xffff << 0)
739
+#define HFNUM_FRNUM_SHIFT        0
740
+#define HFNUM_MAX_FRNUM            0x3fff
741
+
742
+#define HPTXSTS                HSOTG_REG(0x0410)
743
+#define TXSTS_QTOP_ODD            BIT(31)
744
+#define TXSTS_QTOP_CHNEP_MASK        (0xf << 27)
745
+#define TXSTS_QTOP_CHNEP_SHIFT        27
746
+#define TXSTS_QTOP_TOKEN_MASK        (0x3 << 25)
747
+#define TXSTS_QTOP_TOKEN_SHIFT        25
748
+#define TXSTS_QTOP_TERMINATE        BIT(24)
749
+#define TXSTS_QSPCAVAIL_MASK        (0xff << 16)
750
+#define TXSTS_QSPCAVAIL_SHIFT        16
751
+#define TXSTS_FSPCAVAIL_MASK        (0xffff << 0)
752
+#define TXSTS_FSPCAVAIL_SHIFT        0
753
+
754
+#define HAINT                HSOTG_REG(0x0414)
755
+#define HAINTMSK            HSOTG_REG(0x0418)
756
+#define HFLBADDR            HSOTG_REG(0x041c)
757
+
758
+#define HPRT0                HSOTG_REG(0x0440)
759
+#define HPRT0_SPD_MASK            (0x3 << 17)
760
+#define HPRT0_SPD_SHIFT            17
761
+#define HPRT0_SPD_HIGH_SPEED        0
762
+#define HPRT0_SPD_FULL_SPEED        1
763
+#define HPRT0_SPD_LOW_SPEED        2
764
+#define HPRT0_TSTCTL_MASK        (0xf << 13)
765
+#define HPRT0_TSTCTL_SHIFT        13
766
+#define HPRT0_PWR            BIT(12)
767
+#define HPRT0_LNSTS_MASK        (0x3 << 10)
768
+#define HPRT0_LNSTS_SHIFT        10
769
+#define HPRT0_RST            BIT(8)
770
+#define HPRT0_SUSP            BIT(7)
771
+#define HPRT0_RES            BIT(6)
772
+#define HPRT0_OVRCURRCHG        BIT(5)
773
+#define HPRT0_OVRCURRACT        BIT(4)
774
+#define HPRT0_ENACHG            BIT(3)
775
+#define HPRT0_ENA            BIT(2)
776
+#define HPRT0_CONNDET            BIT(1)
777
+#define HPRT0_CONNSTS            BIT(0)
778
+
779
+#define HCCHAR(_ch)            HSOTG_REG(0x0500 + 0x20 * (_ch))
780
+#define HCCHAR_CHENA            BIT(31)
781
+#define HCCHAR_CHDIS            BIT(30)
782
+#define HCCHAR_ODDFRM            BIT(29)
783
+#define HCCHAR_DEVADDR_MASK        (0x7f << 22)
784
+#define HCCHAR_DEVADDR_SHIFT        22
785
+#define HCCHAR_MULTICNT_MASK        (0x3 << 20)
786
+#define HCCHAR_MULTICNT_SHIFT        20
787
+#define HCCHAR_EPTYPE_MASK        (0x3 << 18)
788
+#define HCCHAR_EPTYPE_SHIFT        18
789
+#define HCCHAR_LSPDDEV            BIT(17)
790
+#define HCCHAR_EPDIR            BIT(15)
791
+#define HCCHAR_EPNUM_MASK        (0xf << 11)
792
+#define HCCHAR_EPNUM_SHIFT        11
793
+#define HCCHAR_MPS_MASK            (0x7ff << 0)
794
+#define HCCHAR_MPS_SHIFT        0
795
+
796
+#define HCSPLT(_ch)            HSOTG_REG(0x0504 + 0x20 * (_ch))
797
+#define HCSPLT_SPLTENA            BIT(31)
798
+#define HCSPLT_COMPSPLT            BIT(16)
799
+#define HCSPLT_XACTPOS_MASK        (0x3 << 14)
800
+#define HCSPLT_XACTPOS_SHIFT        14
801
+#define HCSPLT_XACTPOS_MID        0
802
+#define HCSPLT_XACTPOS_END        1
803
+#define HCSPLT_XACTPOS_BEGIN        2
804
+#define HCSPLT_XACTPOS_ALL        3
805
+#define HCSPLT_HUBADDR_MASK        (0x7f << 7)
806
+#define HCSPLT_HUBADDR_SHIFT        7
807
+#define HCSPLT_PRTADDR_MASK        (0x7f << 0)
808
+#define HCSPLT_PRTADDR_SHIFT        0
809
+
810
+#define HCINT(_ch)            HSOTG_REG(0x0508 + 0x20 * (_ch))
811
+#define HCINTMSK(_ch)            HSOTG_REG(0x050c + 0x20 * (_ch))
812
+#define HCINTMSK_RESERVED14_31        (0x3ffff << 14)
813
+#define HCINTMSK_FRM_LIST_ROLL        BIT(13)
814
+#define HCINTMSK_XCS_XACT        BIT(12)
815
+#define HCINTMSK_BNA            BIT(11)
816
+#define HCINTMSK_DATATGLERR        BIT(10)
817
+#define HCINTMSK_FRMOVRUN        BIT(9)
818
+#define HCINTMSK_BBLERR            BIT(8)
819
+#define HCINTMSK_XACTERR        BIT(7)
820
+#define HCINTMSK_NYET            BIT(6)
821
+#define HCINTMSK_ACK            BIT(5)
822
+#define HCINTMSK_NAK            BIT(4)
823
+#define HCINTMSK_STALL            BIT(3)
824
+#define HCINTMSK_AHBERR            BIT(2)
825
+#define HCINTMSK_CHHLTD            BIT(1)
826
+#define HCINTMSK_XFERCOMPL        BIT(0)
827
+
828
+#define HCTSIZ(_ch)            HSOTG_REG(0x0510 + 0x20 * (_ch))
829
+#define TSIZ_DOPNG            BIT(31)
830
+#define TSIZ_SC_MC_PID_MASK        (0x3 << 29)
831
+#define TSIZ_SC_MC_PID_SHIFT        29
832
+#define TSIZ_SC_MC_PID_DATA0        0
833
+#define TSIZ_SC_MC_PID_DATA2        1
834
+#define TSIZ_SC_MC_PID_DATA1        2
835
+#define TSIZ_SC_MC_PID_MDATA        3
836
+#define TSIZ_SC_MC_PID_SETUP        3
837
+#define TSIZ_PKTCNT_MASK        (0x3ff << 19)
838
+#define TSIZ_PKTCNT_SHIFT        19
839
+#define TSIZ_NTD_MASK            (0xff << 8)
840
+#define TSIZ_NTD_SHIFT            8
841
+#define TSIZ_SCHINFO_MASK        (0xff << 0)
842
+#define TSIZ_SCHINFO_SHIFT        0
843
+#define TSIZ_XFERSIZE_MASK        (0x7ffff << 0)
844
+#define TSIZ_XFERSIZE_SHIFT        0
845
+
846
+#define HCDMA(_ch)            HSOTG_REG(0x0514 + 0x20 * (_ch))
847
+
848
+#define HCDMAB(_ch)            HSOTG_REG(0x051c + 0x20 * (_ch))
849
+
850
+#define HCFIFO(_ch)            HSOTG_REG(0x1000 + 0x1000 * (_ch))
851
+
86
+
852
+/**
87
+/**
853
+ * struct dwc2_dma_desc - DMA descriptor structure,
88
+ * xlnx_efuse_calc_crc:
854
+ * used for both host and gadget modes
89
+ * @data: an array of 32-bit words for which the CRC should be computed
855
+ *
90
+ * @u32_cnt: the array size in number of 32-bit words
856
+ * @status: DMA descriptor status quadlet
91
+ * @zpads: the number of 32-bit zeros prepended to @data before computation
857
+ * @buf: DMA descriptor data buffer pointer
92
+ *
858
+ *
93
+ * This function is used to compute the CRC for an array of 32-bit words,
859
+ * DMA Descriptor structure contains two quadlets:
94
+ * using a Xilinx-specific data padding.
860
+ * Status quadlet and Data buffer pointer.
95
+ *
861
+ */
96
+ * Returns: the computed 32-bit CRC
862
+struct dwc2_dma_desc {
97
+ */
863
+    uint32_t status;
98
+uint32_t xlnx_efuse_calc_crc(const uint32_t *data, unsigned u32_cnt,
864
+    uint32_t buf;
99
+ unsigned zpads);
865
+} __packed;
100
+
866
+
101
+/**
867
+/* Host Mode DMA descriptor status quadlet */
102
+ * xlnx_efuse_get_bit:
868
+
103
+ * @s: the efuse object
869
+#define HOST_DMA_A            BIT(31)
104
+ * @bit: the efuse bit-address to read the data
870
+#define HOST_DMA_STS_MASK        (0x3 << 28)
105
+ *
871
+#define HOST_DMA_STS_SHIFT        28
106
+ * Returns: the bit, 0 or 1, at @bit of object @s
872
+#define HOST_DMA_STS_PKTERR        BIT(28)
107
+ */
873
+#define HOST_DMA_EOL            BIT(26)
108
+bool xlnx_efuse_get_bit(XlnxEFuse *s, unsigned int bit);
874
+#define HOST_DMA_IOC            BIT(25)
109
+
875
+#define HOST_DMA_SUP            BIT(24)
110
+/**
876
+#define HOST_DMA_ALT_QTD        BIT(23)
111
+ * xlnx_efuse_set_bit:
877
+#define HOST_DMA_QTD_OFFSET_MASK    (0x3f << 17)
112
+ * @s: the efuse object
878
+#define HOST_DMA_QTD_OFFSET_SHIFT    17
113
+ * @bit: the efuse bit-address to be written a value of 1
879
+#define HOST_DMA_ISOC_NBYTES_MASK    (0xfff << 0)
114
+ *
880
+#define HOST_DMA_ISOC_NBYTES_SHIFT    0
115
+ * Returns: true on success, false on failure
881
+#define HOST_DMA_NBYTES_MASK        (0x1ffff << 0)
116
+ */
882
+#define HOST_DMA_NBYTES_SHIFT        0
117
+bool xlnx_efuse_set_bit(XlnxEFuse *s, unsigned int bit);
883
+#define HOST_DMA_NBYTES_LIMIT        131071
118
+
884
+
119
+/**
885
+/* Device Mode DMA descriptor status quadlet */
120
+ * xlnx_efuse_k256_check:
886
+
121
+ * @s: the efuse object
887
+#define DEV_DMA_BUFF_STS_MASK        (0x3 << 30)
122
+ * @crc: the 32-bit CRC to be compared with
888
+#define DEV_DMA_BUFF_STS_SHIFT        30
123
+ * @start: the efuse bit-address (which must be multiple of 32) of the
889
+#define DEV_DMA_BUFF_STS_HREADY        0
124
+ * start of a 256-bit array
890
+#define DEV_DMA_BUFF_STS_DMABUSY    1
125
+ *
891
+#define DEV_DMA_BUFF_STS_DMADONE    2
126
+ * This function computes the CRC of a 256-bit array starting at @start
892
+#define DEV_DMA_BUFF_STS_HBUSY        3
127
+ * then compares to the given @crc
893
+#define DEV_DMA_STS_MASK        (0x3 << 28)
128
+ *
894
+#define DEV_DMA_STS_SHIFT        28
129
+ * Returns: true of @crc == computed, false otherwise
895
+#define DEV_DMA_STS_SUCC        0
130
+ */
896
+#define DEV_DMA_STS_BUFF_FLUSH        1
131
+bool xlnx_efuse_k256_check(XlnxEFuse *s, uint32_t crc, unsigned start);
897
+#define DEV_DMA_STS_BUFF_ERR        3
132
+
898
+#define DEV_DMA_L            BIT(27)
133
+/**
899
+#define DEV_DMA_SHORT            BIT(26)
134
+ * xlnx_efuse_tbits_check:
900
+#define DEV_DMA_IOC            BIT(25)
135
+ * @s: the efuse object
901
+#define DEV_DMA_SR            BIT(24)
136
+ *
902
+#define DEV_DMA_MTRF            BIT(23)
137
+ * This function inspects a number of efuse bits at specific addresses
903
+#define DEV_DMA_ISOC_PID_MASK        (0x3 << 23)
138
+ * to see if they match a validation pattern. Each pattern is a group
904
+#define DEV_DMA_ISOC_PID_SHIFT        23
139
+ * of 4 bits, and there are 3 groups.
905
+#define DEV_DMA_ISOC_PID_DATA0        0
140
+ *
906
+#define DEV_DMA_ISOC_PID_DATA2        1
141
+ * Returns: a 3-bit mask, where a bit of '1' means the corresponding
907
+#define DEV_DMA_ISOC_PID_DATA1        2
142
+ * group has a valid pattern.
908
+#define DEV_DMA_ISOC_PID_MDATA        3
143
+ */
909
+#define DEV_DMA_ISOC_FRNUM_MASK        (0x7ff << 12)
144
+uint32_t xlnx_efuse_tbits_check(XlnxEFuse *s);
910
+#define DEV_DMA_ISOC_FRNUM_SHIFT    12
145
+
911
+#define DEV_DMA_ISOC_TX_NBYTES_MASK    (0xfff << 0)
146
+/**
912
+#define DEV_DMA_ISOC_TX_NBYTES_LIMIT    0xfff
147
+ * xlnx_efuse_get_row:
913
+#define DEV_DMA_ISOC_RX_NBYTES_MASK    (0x7ff << 0)
148
+ * @s: the efuse object
914
+#define DEV_DMA_ISOC_RX_NBYTES_LIMIT    0x7ff
149
+ * @bit: the efuse bit address for which a 32-bit value is read
915
+#define DEV_DMA_ISOC_NBYTES_SHIFT    0
150
+ *
916
+#define DEV_DMA_NBYTES_MASK        (0xffff << 0)
151
+ * Returns: the entire 32 bits of the efuse, starting at a bit
917
+#define DEV_DMA_NBYTES_SHIFT        0
152
+ * address that is multiple of 32 and contains the bit at @bit
918
+#define DEV_DMA_NBYTES_LIMIT        0xffff
153
+ */
919
+
154
+static inline uint32_t xlnx_efuse_get_row(XlnxEFuse *s, unsigned int bit)
920
+#define MAX_DMA_DESC_NUM_GENERIC    64
155
+{
921
+#define MAX_DMA_DESC_NUM_HS_ISOC    256
156
+ if (!(s->fuse32)) {
922
+
157
+ return 0;
923
+#endif /* __DWC2_HW_H__ */
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
169
index XXXXXXX..XXXXXXX
170
--- /dev/null
171
+++ b/hw/nvram/xlnx-efuse-crc.c
172
@@ -XXX,XX +XXX,XX @@
173
+/*
174
+ * Xilinx eFuse/bbram CRC calculator
175
+ *
176
+ * Copyright (c) 2021 Xilinx Inc.
177
+ *
178
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
179
+ * of this software and associated documentation files (the "Software"), to deal
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
+ *
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
+ */
196
+#include "qemu/osdep.h"
197
+#include "hw/nvram/xlnx-efuse.h"
198
+
199
+static uint32_t xlnx_efuse_u37_crc(uint32_t prev_crc, uint32_t data,
200
+ uint32_t addr)
201
+{
202
+ /* A table for 7-bit slicing */
203
+ static const uint32_t crc_tab[128] = {
204
+ 0x00000000, 0xe13b70f7, 0xc79a971f, 0x26a1e7e8,
205
+ 0x8ad958cf, 0x6be22838, 0x4d43cfd0, 0xac78bf27,
206
+ 0x105ec76f, 0xf165b798, 0xd7c45070, 0x36ff2087,
207
+ 0x9a879fa0, 0x7bbcef57, 0x5d1d08bf, 0xbc267848,
208
+ 0x20bd8ede, 0xc186fe29, 0xe72719c1, 0x061c6936,
209
+ 0xaa64d611, 0x4b5fa6e6, 0x6dfe410e, 0x8cc531f9,
210
+ 0x30e349b1, 0xd1d83946, 0xf779deae, 0x1642ae59,
211
+ 0xba3a117e, 0x5b016189, 0x7da08661, 0x9c9bf696,
212
+ 0x417b1dbc, 0xa0406d4b, 0x86e18aa3, 0x67dafa54,
213
+ 0xcba24573, 0x2a993584, 0x0c38d26c, 0xed03a29b,
214
+ 0x5125dad3, 0xb01eaa24, 0x96bf4dcc, 0x77843d3b,
215
+ 0xdbfc821c, 0x3ac7f2eb, 0x1c661503, 0xfd5d65f4,
216
+ 0x61c69362, 0x80fde395, 0xa65c047d, 0x4767748a,
217
+ 0xeb1fcbad, 0x0a24bb5a, 0x2c855cb2, 0xcdbe2c45,
218
+ 0x7198540d, 0x90a324fa, 0xb602c312, 0x5739b3e5,
219
+ 0xfb410cc2, 0x1a7a7c35, 0x3cdb9bdd, 0xdde0eb2a,
220
+ 0x82f63b78, 0x63cd4b8f, 0x456cac67, 0xa457dc90,
221
+ 0x082f63b7, 0xe9141340, 0xcfb5f4a8, 0x2e8e845f,
222
+ 0x92a8fc17, 0x73938ce0, 0x55326b08, 0xb4091bff,
223
+ 0x1871a4d8, 0xf94ad42f, 0xdfeb33c7, 0x3ed04330,
224
+ 0xa24bb5a6, 0x4370c551, 0x65d122b9, 0x84ea524e,
225
+ 0x2892ed69, 0xc9a99d9e, 0xef087a76, 0x0e330a81,
226
+ 0xb21572c9, 0x532e023e, 0x758fe5d6, 0x94b49521,
227
+ 0x38cc2a06, 0xd9f75af1, 0xff56bd19, 0x1e6dcdee,
228
+ 0xc38d26c4, 0x22b65633, 0x0417b1db, 0xe52cc12c,
229
+ 0x49547e0b, 0xa86f0efc, 0x8ecee914, 0x6ff599e3,
230
+ 0xd3d3e1ab, 0x32e8915c, 0x144976b4, 0xf5720643,
231
+ 0x590ab964, 0xb831c993, 0x9e902e7b, 0x7fab5e8c,
232
+ 0xe330a81a, 0x020bd8ed, 0x24aa3f05, 0xc5914ff2,
233
+ 0x69e9f0d5, 0x88d28022, 0xae7367ca, 0x4f48173d,
234
+ 0xf36e6f75, 0x12551f82, 0x34f4f86a, 0xd5cf889d,
235
+ 0x79b737ba, 0x988c474d, 0xbe2da0a5, 0x5f16d052
236
+ };
237
+
238
+ /*
239
+ * eFuse calculation is shown here:
240
+ * https://github.com/Xilinx/embeddedsw/blob/release-2019.2/lib/sw_services/xilskey/src/xilskey_utils.c#L1496
241
+ *
242
+ * Each u32 word is appended a 5-bit value, for a total of 37 bits; see:
243
+ * https://github.com/Xilinx/embeddedsw/blob/release-2019.2/lib/sw_services/xilskey/src/xilskey_utils.c#L1356
244
+ */
245
+ uint32_t crc = prev_crc;
246
+ const unsigned rshf = 7;
247
+ const uint32_t im = (1 << rshf) - 1;
248
+ const uint32_t rm = (1 << (32 - rshf)) - 1;
249
+ const uint32_t i2 = (1 << 2) - 1;
250
+ const uint32_t r2 = (1 << 30) - 1;
251
+
252
+ unsigned j;
253
+ uint32_t i, r;
254
+ uint64_t w;
255
+
256
+ w = (uint64_t)(addr) << 32;
257
+ w |= data;
258
+
259
+ /* Feed 35 bits, in 5 rounds, each a slice of 7 bits */
260
+ for (j = 0; j < 5; j++) {
261
+ r = rm & (crc >> rshf);
262
+ i = im & (crc ^ w);
263
+ crc = crc_tab[i] ^ r;
264
+
265
+ w >>= rshf;
266
+ }
267
+
268
+ /* Feed the remaining 2 bits */
269
+ r = r2 & (crc >> 2);
270
+ i = i2 & (crc ^ w);
271
+ crc = crc_tab[i << (rshf - 2)] ^ r;
272
+
273
+ return crc;
274
+}
275
+
276
+uint32_t xlnx_efuse_calc_crc(const uint32_t *data, unsigned u32_cnt,
277
+ unsigned zpads)
278
+{
279
+ uint32_t crc = 0;
280
+ unsigned index;
281
+
282
+ for (index = zpads; index; index--) {
283
+ crc = xlnx_efuse_u37_crc(crc, 0, (index + u32_cnt));
284
+ }
285
+
286
+ for (index = u32_cnt; index; index--) {
287
+ crc = xlnx_efuse_u37_crc(crc, data[index - 1], index);
288
+ }
289
+
290
+ return crc;
291
+}
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
+/*
299
+ * QEMU model of the EFUSE eFuse
300
+ *
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
+ */
323
+
324
+#include "qemu/osdep.h"
325
+#include "hw/nvram/xlnx-efuse.h"
326
+
327
+#include "qemu/error-report.h"
328
+#include "qemu/log.h"
329
+#include "qapi/error.h"
330
+#include "sysemu/blockdev.h"
331
+#include "hw/qdev-properties.h"
332
+#include "hw/qdev-properties-system.h"
333
+
334
+#define TBIT0_OFFSET 28
335
+#define TBIT1_OFFSET 29
336
+#define TBIT2_OFFSET 30
337
+#define TBIT3_OFFSET 31
338
+#define TBITS_PATTERN (0x0AU << TBIT0_OFFSET)
339
+#define TBITS_MASK (0x0FU << TBIT0_OFFSET)
340
+
341
+bool xlnx_efuse_get_bit(XlnxEFuse *s, unsigned int bit)
342
+{
343
+ bool b = s->fuse32[bit / 32] & (1 << (bit % 32));
344
+ return b;
345
+}
346
+
347
+static int efuse_bytes(XlnxEFuse *s)
348
+{
349
+ return ROUND_UP((s->efuse_nr * s->efuse_size) / 8, 4);
350
+}
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;
506
+ }
507
+
508
+ s->fuse32 = g_malloc0(efuse_bytes(s));
509
+ if (efuse_bdrv_read(s, errp)) {
510
+ g_free(s->fuse32);
511
+ }
512
+}
513
+
514
+static void efuse_prop_set_drive(Object *obj, Visitor *v, const char *name,
515
+ void *opaque, Error **errp)
516
+{
517
+ DeviceState *dev = DEVICE(obj);
518
+
519
+ qdev_prop_drive.set(obj, v, name, opaque, errp);
520
+
521
+ /* Fill initial data if backend is attached after realized */
522
+ if (dev->realized) {
523
+ efuse_bdrv_read(XLNX_EFUSE(obj), errp);
524
+ }
525
+}
526
+
527
+static void efuse_prop_get_drive(Object *obj, Visitor *v, const char *name,
528
+ void *opaque, Error **errp)
529
+{
530
+ qdev_prop_drive.get(obj, v, name, opaque, errp);
531
+}
532
+
533
+static void efuse_prop_release_drive(Object *obj, const char *name,
534
+ void *opaque)
535
+{
536
+ qdev_prop_drive.release(obj, name, opaque);
537
+}
538
+
539
+static const PropertyInfo efuse_prop_drive = {
540
+ .name = "str",
541
+ .description = "Node name or ID of a block device to use as eFUSE backend",
542
+ .realized_set_allowed = true,
543
+ .get = efuse_prop_get_drive,
544
+ .set = efuse_prop_set_drive,
545
+ .release = efuse_prop_release_drive,
546
+};
547
+
548
+static Property efuse_properties[] = {
549
+ DEFINE_PROP("drive", XlnxEFuse, blk, efuse_prop_drive, BlockBackend *),
550
+ DEFINE_PROP_UINT8("efuse-nr", XlnxEFuse, efuse_nr, 3),
551
+ DEFINE_PROP_UINT32("efuse-size", XlnxEFuse, efuse_size, 64 * 32),
552
+ DEFINE_PROP_BOOL("init-factory-tbits", XlnxEFuse, init_tbits, true),
553
+ DEFINE_PROP_ARRAY("read-only", XlnxEFuse, ro_bits_cnt, ro_bits,
554
+ qdev_prop_uint32, uint32_t),
555
+ DEFINE_PROP_END_OF_LIST(),
556
+};
557
+
558
+static void efuse_class_init(ObjectClass *klass, void *data)
559
+{
560
+ DeviceClass *dc = DEVICE_CLASS(klass);
561
+
562
+ dc->realize = efuse_realize;
563
+ device_class_set_props(dc, efuse_properties);
564
+}
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
580
--- a/hw/nvram/Kconfig
581
+++ b/hw/nvram/Kconfig
582
@@ -XXX,XX +XXX,XX @@ config NMC93XX_EEPROM
583
584
config CHRP_NVRAM
585
bool
586
+
587
+config XLNX_EFUSE_CRC
588
+ bool
589
+
590
+config XLNX_EFUSE
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
595
--- a/hw/nvram/meson.build
596
+++ b/hw/nvram/meson.build
597
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_AT24C', if_true: files('eeprom_at24c.c'))
598
softmmu_ss.add(when: 'CONFIG_MAC_NVRAM', if_true: files('mac_nvram.c'))
599
softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_otp.c'))
600
softmmu_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_nvm.c'))
601
+softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE_CRC', if_true: files('xlnx-efuse-crc.c'))
602
+softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE', if_true: files('xlnx-efuse.c'))
603
604
specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_nvram.c'))
924
--
605
--
925
2.20.1
606
2.20.1
926
607
927
608
diff view generated by jsdifflib
1
From: Paul Zimmerman <pauldzim@gmail.com>
1
From: Tong Ho <tong.ho@xilinx.com>
2
2
3
Add the dwc-hsotg (dwc2) USB host controller emulation code.
3
This implements the Xilinx Versal eFuse, an one-time
4
Based on hw/usb/hcd-ehci.c and hw/usb/hcd-ohci.c.
4
field-programmable non-volatile storage device. There is
5
only one such device in the Xilinx Versal product family.
5
6
6
Note that to use this with the dwc-otg driver in the Raspbian
7
This device has two separate mmio interfaces, a controller
7
kernel, you must pass the option "dwc_otg.fiq_fsm_enable=0" on
8
and a flatten readback.
8
the kernel command line.
9
9
10
Emulation of slave mode and of descriptor-DMA mode has not been
10
The controller provides interfaces for field-programming,
11
implemented yet. These modes are seldom used.
11
configuration, control, and status.
12
12
13
I have used some on-line sources of information while developing
13
The flatten readback is a cache to provide a byte-accessible
14
this emulation, including:
14
read-only interface to efficiently read efuse array.
15
15
16
http://www.capital-micro.com/PDF/CME-M7_Family_User_Guide_EN.pdf
16
Co-authored-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
17
which has a pretty complete description of the controller starting
17
Co-authored-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
18
on page 370.
19
18
20
https://sourceforge.net/p/wive-ng/wive-ng-mt/ci/master/tree/docs/DataSheets/RT3050_5x_V2.0_081408_0902.pdf
19
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
21
which has a description of the controller registers starting on
20
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
22
page 130.
21
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
23
22
Message-id: 20210917052400.1249094-3-tong.ho@xilinx.com
24
Thanks to Felippe Mathieu-Daude for providing a cleaner method
25
of implementing the memory regions for the controller registers.
26
27
Signed-off-by: Paul Zimmerman <pauldzim@gmail.com>
28
Message-id: 20200520235349.21215-5-pauldzim@gmail.com
29
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
---
25
---
32
hw/usb/hcd-dwc2.c | 1417 ++++++++++++++++++++++++++++++++++++++++++
26
include/hw/nvram/xlnx-versal-efuse.h | 68 +++
33
hw/usb/Kconfig | 5 +
27
hw/nvram/xlnx-versal-efuse-cache.c | 114 ++++
34
hw/usb/Makefile.objs | 1 +
28
hw/nvram/xlnx-versal-efuse-ctrl.c | 783 +++++++++++++++++++++++++++
35
hw/usb/trace-events | 50 ++
29
hw/nvram/Kconfig | 4 +
36
4 files changed, 1473 insertions(+)
30
hw/nvram/meson.build | 3 +
37
create mode 100644 hw/usb/hcd-dwc2.c
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
38
35
39
diff --git a/hw/usb/hcd-dwc2.c b/hw/usb/hcd-dwc2.c
36
diff --git a/include/hw/nvram/xlnx-versal-efuse.h b/include/hw/nvram/xlnx-versal-efuse.h
40
new file mode 100644
37
new file mode 100644
41
index XXXXXXX..XXXXXXX
38
index XXXXXXX..XXXXXXX
42
--- /dev/null
39
--- /dev/null
43
+++ b/hw/usb/hcd-dwc2.c
40
+++ b/include/hw/nvram/xlnx-versal-efuse.h
44
@@ -XXX,XX +XXX,XX @@
41
@@ -XXX,XX +XXX,XX @@
45
+/*
42
+/*
46
+ * dwc-hsotg (dwc2) USB host controller emulation
43
+ * Copyright (c) 2020 Xilinx Inc.
47
+ *
44
+ *
48
+ * Based on hw/usb/hcd-ehci.c and hw/usb/hcd-ohci.c
45
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
49
+ *
46
+ * of this software and associated documentation files (the "Software"), to deal
50
+ * Note that to use this emulation with the dwc-otg driver in the
47
+ * in the Software without restriction, including without limitation the rights
51
+ * Raspbian kernel, you must pass the option "dwc_otg.fiq_fsm_enable=0"
48
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
52
+ * on the kernel command line.
49
+ * copies of the Software, and to permit persons to whom the Software is
53
+ *
50
+ * furnished to do so, subject to the following conditions:
54
+ * Some useful documentation used to develop this emulation can be
51
+ *
55
+ * found online (as of April 2020) at:
52
+ * The above copyright notice and this permission notice shall be included in
56
+ *
53
+ * all copies or substantial portions of the Software.
57
+ * http://www.capital-micro.com/PDF/CME-M7_Family_User_Guide_EN.pdf
54
+ *
58
+ * which has a pretty complete description of the controller starting
55
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59
+ * on page 370.
56
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60
+ *
57
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
61
+ * https://sourceforge.net/p/wive-ng/wive-ng-mt/ci/master/tree/docs/DataSheets/RT3050_5x_V2.0_081408_0902.pdf
58
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
62
+ * which has a description of the controller registers starting on
59
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
63
+ * page 130.
60
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
64
+ *
61
+ * THE SOFTWARE.
65
+ * Copyright (c) 2020 Paul Zimmerman <pauldzim@gmail.com>
66
+ *
67
+ * This program is free software; you can redistribute it and/or modify
68
+ * it under the terms of the GNU General Public License as published by
69
+ * the Free Software Foundation; either version 2 of the License, or
70
+ * (at your option) any later version.
71
+ *
72
+ * This program is distributed in the hope that it will be useful,
73
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
74
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
75
+ * GNU General Public License for more details.
76
+ */
62
+ */
63
+#ifndef XLNX_VERSAL_EFUSE_H
64
+#define XLNX_VERSAL_EFUSE_H
65
+
66
+#include "hw/irq.h"
67
+#include "hw/sysbus.h"
68
+#include "hw/register.h"
69
+#include "hw/nvram/xlnx-efuse.h"
70
+
71
+#define XLNX_VERSAL_EFUSE_CTRL_R_MAX ((0x100 / 4) + 1)
72
+
73
+#define TYPE_XLNX_VERSAL_EFUSE_CTRL "xlnx,versal-efuse"
74
+#define TYPE_XLNX_VERSAL_EFUSE_CACHE "xlnx,pmc-efuse-cache"
75
+
76
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalEFuseCtrl, XLNX_VERSAL_EFUSE_CTRL);
77
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalEFuseCache, XLNX_VERSAL_EFUSE_CACHE);
78
+
79
+struct XlnxVersalEFuseCtrl {
80
+ SysBusDevice parent_obj;
81
+ qemu_irq irq_efuse_imr;
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
+ */
77
+
139
+
78
+#include "qemu/osdep.h"
140
+#include "qemu/osdep.h"
79
+#include "qemu/units.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"
80
+#include "qapi/error.h"
264
+#include "qapi/error.h"
81
+#include "hw/usb/dwc2-regs.h"
82
+#include "hw/usb/hcd-dwc2.h"
83
+#include "migration/vmstate.h"
265
+#include "migration/vmstate.h"
84
+#include "trace.h"
85
+#include "qemu/log.h"
86
+#include "qemu/error-report.h"
87
+#include "qemu/main-loop.h"
88
+#include "hw/qdev-properties.h"
266
+#include "hw/qdev-properties.h"
89
+
267
+
90
+#define USB_HZ_FS 12000000
268
+#ifndef XLNX_VERSAL_EFUSE_CTRL_ERR_DEBUG
91
+#define USB_HZ_HS 96000000
269
+#define XLNX_VERSAL_EFUSE_CTRL_ERR_DEBUG 0
92
+#define USB_FRMINTVL 12000
270
+#endif
93
+
271
+
94
+/* nifty macros from Arnon's EHCI version */
272
+REG32(WR_LOCK, 0x0)
95
+#define get_field(data, field) \
273
+ FIELD(WR_LOCK, LOCK, 0, 16)
96
+ (((data) & field##_MASK) >> field##_SHIFT)
274
+REG32(CFG, 0x4)
97
+
275
+ FIELD(CFG, SLVERR_ENABLE, 5, 1)
98
+#define set_field(data, newval, field) do { \
276
+ FIELD(CFG, MARGIN_RD, 2, 1)
99
+ uint32_t val = *(data); \
277
+ FIELD(CFG, PGM_EN, 1, 1)
100
+ val &= ~field##_MASK; \
278
+REG32(STATUS, 0x8)
101
+ val |= ((newval) << field##_SHIFT) & field##_MASK; \
279
+ FIELD(STATUS, AES_USER_KEY_1_CRC_PASS, 11, 1)
102
+ *(data) = val; \
280
+ FIELD(STATUS, AES_USER_KEY_1_CRC_DONE, 10, 1)
103
+} while (0)
281
+ FIELD(STATUS, AES_USER_KEY_0_CRC_PASS, 9, 1)
104
+
282
+ FIELD(STATUS, AES_USER_KEY_0_CRC_DONE, 8, 1)
105
+#define get_bit(data, bitmask) \
283
+ FIELD(STATUS, AES_CRC_PASS, 7, 1)
106
+ (!!((data) & (bitmask)))
284
+ FIELD(STATUS, AES_CRC_DONE, 6, 1)
107
+
285
+ FIELD(STATUS, CACHE_DONE, 5, 1)
108
+/* update irq line */
286
+ FIELD(STATUS, CACHE_LOAD, 4, 1)
109
+static inline void dwc2_update_irq(DWC2State *s)
287
+ FIELD(STATUS, EFUSE_2_TBIT, 2, 1)
110
+{
288
+ FIELD(STATUS, EFUSE_1_TBIT, 1, 1)
111
+ static int oldlevel;
289
+ FIELD(STATUS, EFUSE_0_TBIT, 0, 1)
112
+ int level = 0;
290
+REG32(EFUSE_PGM_ADDR, 0xc)
113
+
291
+ FIELD(EFUSE_PGM_ADDR, PAGE, 13, 4)
114
+ if ((s->gintsts & s->gintmsk) && (s->gahbcfg & GAHBCFG_GLBL_INTR_EN)) {
292
+ FIELD(EFUSE_PGM_ADDR, ROW, 5, 8)
115
+ level = 1;
293
+ FIELD(EFUSE_PGM_ADDR, COLUMN, 0, 5)
116
+ }
294
+REG32(EFUSE_RD_ADDR, 0x10)
117
+ if (level != oldlevel) {
295
+ FIELD(EFUSE_RD_ADDR, PAGE, 13, 4)
118
+ oldlevel = level;
296
+ FIELD(EFUSE_RD_ADDR, ROW, 5, 8)
119
+ trace_usb_dwc2_update_irq(level);
297
+REG32(EFUSE_RD_DATA, 0x14)
120
+ qemu_set_irq(s->irq, level);
298
+REG32(TPGM, 0x18)
121
+ }
299
+ FIELD(TPGM, VALUE, 0, 16)
122
+}
300
+REG32(TRD, 0x1c)
123
+
301
+ FIELD(TRD, VALUE, 0, 8)
124
+/* flag interrupt condition */
302
+REG32(TSU_H_PS, 0x20)
125
+static inline void dwc2_raise_global_irq(DWC2State *s, uint32_t intr)
303
+ FIELD(TSU_H_PS, VALUE, 0, 8)
126
+{
304
+REG32(TSU_H_PS_CS, 0x24)
127
+ if (!(s->gintsts & intr)) {
305
+ FIELD(TSU_H_PS_CS, VALUE, 0, 8)
128
+ s->gintsts |= intr;
306
+REG32(TRDM, 0x28)
129
+ trace_usb_dwc2_raise_global_irq(intr);
307
+ FIELD(TRDM, VALUE, 0, 8)
130
+ dwc2_update_irq(s);
308
+REG32(TSU_H_CS, 0x2c)
131
+ }
309
+ FIELD(TSU_H_CS, VALUE, 0, 8)
132
+}
310
+REG32(EFUSE_ISR, 0x30)
133
+
311
+ FIELD(EFUSE_ISR, APB_SLVERR, 31, 1)
134
+static inline void dwc2_lower_global_irq(DWC2State *s, uint32_t intr)
312
+ FIELD(EFUSE_ISR, CACHE_PARITY_E2, 14, 1)
135
+{
313
+ FIELD(EFUSE_ISR, CACHE_PARITY_E1, 13, 1)
136
+ if (s->gintsts & intr) {
314
+ FIELD(EFUSE_ISR, CACHE_PARITY_E0S, 12, 1)
137
+ s->gintsts &= ~intr;
315
+ FIELD(EFUSE_ISR, CACHE_PARITY_E0R, 11, 1)
138
+ trace_usb_dwc2_lower_global_irq(intr);
316
+ FIELD(EFUSE_ISR, CACHE_APB_SLVERR, 10, 1)
139
+ dwc2_update_irq(s);
317
+ FIELD(EFUSE_ISR, CACHE_REQ_ERROR, 9, 1)
140
+ }
318
+ FIELD(EFUSE_ISR, MAIN_REQ_ERROR, 8, 1)
141
+}
319
+ FIELD(EFUSE_ISR, READ_ON_CACHE_LD, 7, 1)
142
+
320
+ FIELD(EFUSE_ISR, CACHE_FSM_ERROR, 6, 1)
143
+static inline void dwc2_raise_host_irq(DWC2State *s, uint32_t host_intr)
321
+ FIELD(EFUSE_ISR, MAIN_FSM_ERROR, 5, 1)
144
+{
322
+ FIELD(EFUSE_ISR, CACHE_ERROR, 4, 1)
145
+ if (!(s->haint & host_intr)) {
323
+ FIELD(EFUSE_ISR, RD_ERROR, 3, 1)
146
+ s->haint |= host_intr;
324
+ FIELD(EFUSE_ISR, RD_DONE, 2, 1)
147
+ s->haint &= 0xffff;
325
+ FIELD(EFUSE_ISR, PGM_ERROR, 1, 1)
148
+ trace_usb_dwc2_raise_host_irq(host_intr);
326
+ FIELD(EFUSE_ISR, PGM_DONE, 0, 1)
149
+ if (s->haint & s->haintmsk) {
327
+REG32(EFUSE_IMR, 0x34)
150
+ dwc2_raise_global_irq(s, GINTSTS_HCHINT);
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);
151
+ }
522
+ }
152
+ }
523
+
153
+}
524
+ bit = FIELD_DP32(row, EFUSE_PGM_ADDR, COLUMN, EFUSE_ANCHOR_1_COL);
154
+
525
+ if (!xlnx_efuse_get_bit(s->efuse, bit)) {
155
+static inline void dwc2_lower_host_irq(DWC2State *s, uint32_t host_intr)
526
+ xlnx_efuse_set_bit(s->efuse, bit);
156
+{
157
+ if (s->haint & host_intr) {
158
+ s->haint &= ~host_intr;
159
+ trace_usb_dwc2_lower_host_irq(host_intr);
160
+ if (!(s->haint & s->haintmsk)) {
161
+ dwc2_lower_global_irq(s, GINTSTS_HCHINT);
162
+ }
527
+ }
163
+ }
528
+ }
164
+}
529
+}
165
+
530
+
166
+static inline void dwc2_update_hc_irq(DWC2State *s, int index)
531
+static void efuse_key_crc_check(RegisterInfo *reg, uint32_t crc,
167
+{
532
+ uint32_t pass_mask, uint32_t done_mask,
168
+ uint32_t host_intr = 1 << (index >> 3);
533
+ unsigned first, uint32_t lk_mask)
169
+
534
+{
170
+ if (s->hreg1[index + 2] & s->hreg1[index + 3]) {
535
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
171
+ dwc2_raise_host_irq(s, host_intr);
536
+ uint32_t r, lk_bits;
172
+ } else {
537
+
173
+ dwc2_lower_host_irq(s, host_intr);
538
+ /*
174
+ }
539
+ * To start, assume both DONE and PASS, and clear PASS by xor
175
+}
540
+ * if CRC-check fails or CRC-check disabled by lock fuse.
176
+
541
+ */
177
+/* set a timer for EOF */
542
+ r = s->regs[R_STATUS] | done_mask | pass_mask;
178
+static void dwc2_eof_timer(DWC2State *s)
543
+
179
+{
544
+ lk_bits = xlnx_efuse_get_row(s->efuse, EFUSE_KEY_CRC_LK_ROW) & lk_mask;
180
+ timer_mod(s->eof_timer, s->sof_time + s->usb_frame_time);
545
+ if (lk_bits == 0 && xlnx_efuse_k256_check(s->efuse, crc, first)) {
181
+}
546
+ pass_mask = 0;
182
+
547
+ }
183
+/* Set a timer for EOF and generate SOF event */
548
+
184
+static void dwc2_sof(DWC2State *s)
549
+ s->regs[R_STATUS] = r ^ pass_mask;
185
+{
550
+}
186
+ s->sof_time += s->usb_frame_time;
551
+
187
+ trace_usb_dwc2_sof(s->sof_time);
552
+static void efuse_data_sync(XlnxVersalEFuseCtrl *s)
188
+ dwc2_eof_timer(s);
553
+{
189
+ dwc2_raise_global_irq(s, GINTSTS_SOF);
554
+ efuse_status_tbits_sync(s);
190
+}
555
+}
191
+
556
+
192
+/* Do frame processing on frame boundary */
557
+static int efuse_lk_spec_cmp(const void *a, const void *b)
193
+static void dwc2_frame_boundary(void *opaque)
558
+{
194
+{
559
+ uint16_t r1 = ((const XlnxEFuseLkSpec *)a)->row;
195
+ DWC2State *s = opaque;
560
+ uint16_t r2 = ((const XlnxEFuseLkSpec *)b)->row;
196
+ int64_t now;
561
+
197
+ uint16_t frcnt;
562
+ return (r1 > r2) - (r1 < r2);
198
+
563
+}
199
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
564
+
200
+
565
+static void efuse_lk_spec_sort(XlnxVersalEFuseCtrl *s)
201
+ /* Frame boundary, so do EOF stuff here */
566
+{
202
+
567
+ XlnxEFuseLkSpec *ary = s->extra_pg0_lock_spec;
203
+ /* Increment frame number */
568
+ const uint32_t n8 = s->extra_pg0_lock_n16 * 2;
204
+ frcnt = (uint16_t)((now - s->sof_time) / s->fi);
569
+ const uint32_t sz = sizeof(ary[0]);
205
+ s->frame_number = (s->frame_number + frcnt) & 0xffff;
570
+ const uint32_t cnt = n8 / sz;
206
+ s->hfnum = s->frame_number & HFNUM_MAX_FRNUM;
571
+
207
+
572
+ if (ary && cnt) {
208
+ /* Do SOF stuff here */
573
+ qsort(ary, cnt, sz, efuse_lk_spec_cmp);
209
+ dwc2_sof(s);
574
+ }
210
+}
575
+}
211
+
576
+
212
+/* Start sending SOF tokens on the USB bus */
577
+static uint32_t efuse_lk_spec_find(XlnxVersalEFuseCtrl *s, uint32_t row)
213
+static void dwc2_bus_start(DWC2State *s)
578
+{
214
+{
579
+ const XlnxEFuseLkSpec *ary = s->extra_pg0_lock_spec;
215
+ trace_usb_dwc2_bus_start();
580
+ const uint32_t n8 = s->extra_pg0_lock_n16 * 2;
216
+ s->sof_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
581
+ const uint32_t sz = sizeof(ary[0]);
217
+ dwc2_eof_timer(s);
582
+ const uint32_t cnt = n8 / sz;
218
+}
583
+ const XlnxEFuseLkSpec *item = NULL;
219
+
584
+
220
+/* Stop sending SOF tokens on the USB bus */
585
+ if (ary && cnt) {
221
+static void dwc2_bus_stop(DWC2State *s)
586
+ XlnxEFuseLkSpec k = { .row = row, };
222
+{
587
+
223
+ trace_usb_dwc2_bus_stop();
588
+ item = bsearch(&k, ary, cnt, sz, efuse_lk_spec_cmp);
224
+ timer_del(s->eof_timer);
589
+ }
225
+}
590
+
226
+
591
+ return item ? item->lk_bit : 0;
227
+static USBDevice *dwc2_find_device(DWC2State *s, uint8_t addr)
592
+}
228
+{
593
+
229
+ USBDevice *dev;
594
+static uint32_t efuse_bit_locked(XlnxVersalEFuseCtrl *s, uint32_t bit)
230
+
595
+{
231
+ trace_usb_dwc2_find_device(addr);
596
+ /* Hard-coded locks */
232
+
597
+ static const uint16_t pg0_hard_lock[] = {
233
+ if (!(s->hprt0 & HPRT0_ENA)) {
598
+ [4] = EFUSE_GLITCH_DET_WR_LK,
234
+ trace_usb_dwc2_port_disabled(0);
599
+ [37] = EFUSE_BOOT_ENV_WR_LK,
235
+ } else {
600
+
236
+ dev = usb_find_device(&s->uport, addr);
601
+ [8 ... 11] = EFUSE_DNA_WR_LK,
237
+ if (dev != NULL) {
602
+ [12 ... 19] = EFUSE_AES_WR_LK,
238
+ trace_usb_dwc2_device_found(0);
603
+ [20 ... 27] = EFUSE_USER_KEY_0_WR_LK,
239
+ return dev;
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;
240
+ }
632
+ }
241
+ }
633
+
242
+
634
+ lock = efuse_bit_locked(s, bit);
243
+ trace_usb_dwc2_device_not_found();
635
+ break;
244
+ return NULL;
636
+ case EFUSE_PUF_PAGE:
245
+}
637
+ if (bit < EFUSE_PUF_SYN_START || bit > EFUSE_PUF_SYN_END) {
246
+
638
+ lock = 0;
247
+static const char *pstatus[] = {
639
+ goto ret_lock;
248
+ "USB_RET_SUCCESS", "USB_RET_NODEV", "USB_RET_NAK", "USB_RET_STALL",
249
+ "USB_RET_BABBLE", "USB_RET_IOERROR", "USB_RET_ASYNC",
250
+ "USB_RET_ADD_TO_QUEUE", "USB_RET_REMOVE_FROM_QUEUE"
251
+};
252
+
253
+static uint32_t pintr[] = {
254
+ HCINTMSK_XFERCOMPL, HCINTMSK_XACTERR, HCINTMSK_NAK, HCINTMSK_STALL,
255
+ HCINTMSK_BBLERR, HCINTMSK_XACTERR, HCINTMSK_XACTERR, HCINTMSK_XACTERR,
256
+ HCINTMSK_XACTERR
257
+};
258
+
259
+static const char *types[] = {
260
+ "Ctrl", "Isoc", "Bulk", "Intr"
261
+};
262
+
263
+static const char *dirs[] = {
264
+ "Out", "In"
265
+};
266
+
267
+static void dwc2_handle_packet(DWC2State *s, uint32_t devadr, USBDevice *dev,
268
+ USBEndpoint *ep, uint32_t index, bool send)
269
+{
270
+ DWC2Packet *p;
271
+ uint32_t hcchar = s->hreg1[index];
272
+ uint32_t hctsiz = s->hreg1[index + 4];
273
+ uint32_t hcdma = s->hreg1[index + 5];
274
+ uint32_t chan, epnum, epdir, eptype, mps, pid, pcnt, len, tlen, intr = 0;
275
+ uint32_t tpcnt, stsidx, actual = 0;
276
+ bool do_intr = false, done = false;
277
+
278
+ epnum = get_field(hcchar, HCCHAR_EPNUM);
279
+ epdir = get_bit(hcchar, HCCHAR_EPDIR);
280
+ eptype = get_field(hcchar, HCCHAR_EPTYPE);
281
+ mps = get_field(hcchar, HCCHAR_MPS);
282
+ pid = get_field(hctsiz, TSIZ_SC_MC_PID);
283
+ pcnt = get_field(hctsiz, TSIZ_PKTCNT);
284
+ len = get_field(hctsiz, TSIZ_XFERSIZE);
285
+ assert(len <= DWC2_MAX_XFER_SIZE);
286
+ chan = index >> 3;
287
+ p = &s->packet[chan];
288
+
289
+ trace_usb_dwc2_handle_packet(chan, dev, &p->packet, epnum, types[eptype],
290
+ dirs[epdir], mps, len, pcnt);
291
+
292
+ if (eptype == USB_ENDPOINT_XFER_CONTROL && pid == TSIZ_SC_MC_PID_SETUP) {
293
+ pid = USB_TOKEN_SETUP;
294
+ } else {
295
+ pid = epdir ? USB_TOKEN_IN : USB_TOKEN_OUT;
296
+ }
297
+
298
+ if (send) {
299
+ tlen = len;
300
+ if (p->small) {
301
+ if (tlen > mps) {
302
+ tlen = mps;
303
+ }
304
+ }
640
+ }
305
+
641
+
306
+ if (pid != USB_TOKEN_IN) {
642
+ lock = EFUSE_PUF_SYN_LK;
307
+ trace_usb_dwc2_memory_read(hcdma, tlen);
308
+ if (dma_memory_read(&s->dma_as, hcdma,
309
+ s->usb_buf[chan], tlen) != MEMTX_OK) {
310
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: dma_memory_read failed\n",
311
+ __func__);
312
+ }
313
+ }
314
+
315
+ usb_packet_init(&p->packet);
316
+ usb_packet_setup(&p->packet, pid, ep, 0, hcdma,
317
+ pid != USB_TOKEN_IN, true);
318
+ usb_packet_addbuf(&p->packet, s->usb_buf[chan], tlen);
319
+ p->async = DWC2_ASYNC_NONE;
320
+ usb_handle_packet(dev, &p->packet);
321
+ } else {
322
+ tlen = p->len;
323
+ }
324
+
325
+ stsidx = -p->packet.status;
326
+ assert(stsidx < sizeof(pstatus) / sizeof(*pstatus));
327
+ actual = p->packet.actual_length;
328
+ trace_usb_dwc2_packet_status(pstatus[stsidx], actual);
329
+
330
+babble:
331
+ if (p->packet.status != USB_RET_SUCCESS &&
332
+ p->packet.status != USB_RET_NAK &&
333
+ p->packet.status != USB_RET_STALL &&
334
+ p->packet.status != USB_RET_ASYNC) {
335
+ trace_usb_dwc2_packet_error(pstatus[stsidx]);
336
+ }
337
+
338
+ if (p->packet.status == USB_RET_ASYNC) {
339
+ trace_usb_dwc2_async_packet(&p->packet, chan, dev, epnum,
340
+ dirs[epdir], tlen);
341
+ usb_device_flush_ep_queue(dev, ep);
342
+ assert(p->async != DWC2_ASYNC_INFLIGHT);
343
+ p->devadr = devadr;
344
+ p->epnum = epnum;
345
+ p->epdir = epdir;
346
+ p->mps = mps;
347
+ p->pid = pid;
348
+ p->index = index;
349
+ p->pcnt = pcnt;
350
+ p->len = tlen;
351
+ p->async = DWC2_ASYNC_INFLIGHT;
352
+ p->needs_service = false;
353
+ return;
354
+ }
355
+
356
+ if (p->packet.status == USB_RET_SUCCESS) {
357
+ if (actual > tlen) {
358
+ p->packet.status = USB_RET_BABBLE;
359
+ goto babble;
360
+ }
361
+
362
+ if (pid == USB_TOKEN_IN) {
363
+ trace_usb_dwc2_memory_write(hcdma, actual);
364
+ if (dma_memory_write(&s->dma_as, hcdma, s->usb_buf[chan],
365
+ actual) != MEMTX_OK) {
366
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: dma_memory_write failed\n",
367
+ __func__);
368
+ }
369
+ }
370
+
371
+ tpcnt = actual / mps;
372
+ if (actual % mps) {
373
+ tpcnt++;
374
+ if (pid == USB_TOKEN_IN) {
375
+ done = true;
376
+ }
377
+ }
378
+
379
+ pcnt -= tpcnt < pcnt ? tpcnt : pcnt;
380
+ set_field(&hctsiz, pcnt, TSIZ_PKTCNT);
381
+ len -= actual < len ? actual : len;
382
+ set_field(&hctsiz, len, TSIZ_XFERSIZE);
383
+ s->hreg1[index + 4] = hctsiz;
384
+ hcdma += actual;
385
+ s->hreg1[index + 5] = hcdma;
386
+
387
+ if (!pcnt || len == 0 || actual == 0) {
388
+ done = true;
389
+ }
390
+ } else {
391
+ intr |= pintr[stsidx];
392
+ if (p->packet.status == USB_RET_NAK &&
393
+ (eptype == USB_ENDPOINT_XFER_CONTROL ||
394
+ eptype == USB_ENDPOINT_XFER_BULK)) {
395
+ /*
396
+ * for ctrl/bulk, automatically retry on NAK,
397
+ * but send the interrupt anyway
398
+ */
399
+ intr &= ~HCINTMSK_RESERVED14_31;
400
+ s->hreg1[index + 2] |= intr;
401
+ do_intr = true;
402
+ } else {
403
+ intr |= HCINTMSK_CHHLTD;
404
+ done = true;
405
+ }
406
+ }
407
+
408
+ usb_packet_cleanup(&p->packet);
409
+
410
+ if (done) {
411
+ hcchar &= ~HCCHAR_CHENA;
412
+ s->hreg1[index] = hcchar;
413
+ if (!(intr & HCINTMSK_CHHLTD)) {
414
+ intr |= HCINTMSK_CHHLTD | HCINTMSK_XFERCOMPL;
415
+ }
416
+ intr &= ~HCINTMSK_RESERVED14_31;
417
+ s->hreg1[index + 2] |= intr;
418
+ p->needs_service = false;
419
+ trace_usb_dwc2_packet_done(pstatus[stsidx], actual, len, pcnt);
420
+ dwc2_update_hc_irq(s, index);
421
+ return;
422
+ }
423
+
424
+ p->devadr = devadr;
425
+ p->epnum = epnum;
426
+ p->epdir = epdir;
427
+ p->mps = mps;
428
+ p->pid = pid;
429
+ p->index = index;
430
+ p->pcnt = pcnt;
431
+ p->len = len;
432
+ p->needs_service = true;
433
+ trace_usb_dwc2_packet_next(pstatus[stsidx], len, pcnt);
434
+ if (do_intr) {
435
+ dwc2_update_hc_irq(s, index);
436
+ }
437
+}
438
+
439
+/* Attach or detach a device on root hub */
440
+
441
+static const char *speeds[] = {
442
+ "low", "full", "high"
443
+};
444
+
445
+static void dwc2_attach(USBPort *port)
446
+{
447
+ DWC2State *s = port->opaque;
448
+ int hispd = 0;
449
+
450
+ trace_usb_dwc2_attach(port);
451
+ assert(port->index == 0);
452
+
453
+ if (!port->dev || !port->dev->attached) {
454
+ return;
455
+ }
456
+
457
+ assert(port->dev->speed <= USB_SPEED_HIGH);
458
+ trace_usb_dwc2_attach_speed(speeds[port->dev->speed]);
459
+ s->hprt0 &= ~HPRT0_SPD_MASK;
460
+
461
+ switch (port->dev->speed) {
462
+ case USB_SPEED_LOW:
463
+ s->hprt0 |= HPRT0_SPD_LOW_SPEED << HPRT0_SPD_SHIFT;
464
+ break;
465
+ case USB_SPEED_FULL:
466
+ s->hprt0 |= HPRT0_SPD_FULL_SPEED << HPRT0_SPD_SHIFT;
467
+ break;
468
+ case USB_SPEED_HIGH:
469
+ s->hprt0 |= HPRT0_SPD_HIGH_SPEED << HPRT0_SPD_SHIFT;
470
+ hispd = 1;
471
+ break;
472
+ }
473
+
474
+ if (hispd) {
475
+ s->usb_frame_time = NANOSECONDS_PER_SECOND / 8000; /* 125000 */
476
+ if (NANOSECONDS_PER_SECOND >= USB_HZ_HS) {
477
+ s->usb_bit_time = NANOSECONDS_PER_SECOND / USB_HZ_HS; /* 10.4 */
478
+ } else {
479
+ s->usb_bit_time = 1;
480
+ }
481
+ } else {
482
+ s->usb_frame_time = NANOSECONDS_PER_SECOND / 1000; /* 1000000 */
483
+ if (NANOSECONDS_PER_SECOND >= USB_HZ_FS) {
484
+ s->usb_bit_time = NANOSECONDS_PER_SECOND / USB_HZ_FS; /* 83.3 */
485
+ } else {
486
+ s->usb_bit_time = 1;
487
+ }
488
+ }
489
+
490
+ s->fi = USB_FRMINTVL - 1;
491
+ s->hprt0 |= HPRT0_CONNDET | HPRT0_CONNSTS;
492
+
493
+ dwc2_bus_start(s);
494
+ dwc2_raise_global_irq(s, GINTSTS_PRTINT);
495
+}
496
+
497
+static void dwc2_detach(USBPort *port)
498
+{
499
+ DWC2State *s = port->opaque;
500
+
501
+ trace_usb_dwc2_detach(port);
502
+ assert(port->index == 0);
503
+
504
+ dwc2_bus_stop(s);
505
+
506
+ s->hprt0 &= ~(HPRT0_SPD_MASK | HPRT0_SUSP | HPRT0_ENA | HPRT0_CONNSTS);
507
+ s->hprt0 |= HPRT0_CONNDET | HPRT0_ENACHG;
508
+
509
+ dwc2_raise_global_irq(s, GINTSTS_PRTINT);
510
+}
511
+
512
+static void dwc2_child_detach(USBPort *port, USBDevice *child)
513
+{
514
+ trace_usb_dwc2_child_detach(port, child);
515
+ assert(port->index == 0);
516
+}
517
+
518
+static void dwc2_wakeup(USBPort *port)
519
+{
520
+ DWC2State *s = port->opaque;
521
+
522
+ trace_usb_dwc2_wakeup(port);
523
+ assert(port->index == 0);
524
+
525
+ if (s->hprt0 & HPRT0_SUSP) {
526
+ s->hprt0 |= HPRT0_RES;
527
+ dwc2_raise_global_irq(s, GINTSTS_PRTINT);
528
+ }
529
+
530
+ qemu_bh_schedule(s->async_bh);
531
+}
532
+
533
+static void dwc2_async_packet_complete(USBPort *port, USBPacket *packet)
534
+{
535
+ DWC2State *s = port->opaque;
536
+ DWC2Packet *p;
537
+ USBDevice *dev;
538
+ USBEndpoint *ep;
539
+
540
+ assert(port->index == 0);
541
+ p = container_of(packet, DWC2Packet, packet);
542
+ dev = dwc2_find_device(s, p->devadr);
543
+ ep = usb_ep_get(dev, p->pid, p->epnum);
544
+ trace_usb_dwc2_async_packet_complete(port, packet, p->index >> 3, dev,
545
+ p->epnum, dirs[p->epdir], p->len);
546
+ assert(p->async == DWC2_ASYNC_INFLIGHT);
547
+
548
+ if (packet->status == USB_RET_REMOVE_FROM_QUEUE) {
549
+ usb_cancel_packet(packet);
550
+ usb_packet_cleanup(packet);
551
+ return;
552
+ }
553
+
554
+ dwc2_handle_packet(s, p->devadr, dev, ep, p->index, false);
555
+
556
+ p->async = DWC2_ASYNC_FINISHED;
557
+ qemu_bh_schedule(s->async_bh);
558
+}
559
+
560
+static USBPortOps dwc2_port_ops = {
561
+ .attach = dwc2_attach,
562
+ .detach = dwc2_detach,
563
+ .child_detach = dwc2_child_detach,
564
+ .wakeup = dwc2_wakeup,
565
+ .complete = dwc2_async_packet_complete,
566
+};
567
+
568
+static uint32_t dwc2_get_frame_remaining(DWC2State *s)
569
+{
570
+ uint32_t fr = 0;
571
+ int64_t tks;
572
+
573
+ tks = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->sof_time;
574
+ if (tks < 0) {
575
+ tks = 0;
576
+ }
577
+
578
+ /* avoid muldiv if possible */
579
+ if (tks >= s->usb_frame_time) {
580
+ goto out;
581
+ }
582
+ if (tks < s->usb_bit_time) {
583
+ fr = s->fi;
584
+ goto out;
585
+ }
586
+
587
+ /* tks = number of ns since SOF, divided by 83 (fs) or 10 (hs) */
588
+ tks = tks / s->usb_bit_time;
589
+ if (tks >= (int64_t)s->fi) {
590
+ goto out;
591
+ }
592
+
593
+ /* remaining = frame interval minus tks */
594
+ fr = (uint32_t)((int64_t)s->fi - tks);
595
+
596
+out:
597
+ return fr;
598
+}
599
+
600
+static void dwc2_work_bh(void *opaque)
601
+{
602
+ DWC2State *s = opaque;
603
+ DWC2Packet *p;
604
+ USBDevice *dev;
605
+ USBEndpoint *ep;
606
+ int64_t t_now, expire_time;
607
+ int chan;
608
+ bool found = false;
609
+
610
+ trace_usb_dwc2_work_bh();
611
+ if (s->working) {
612
+ return;
613
+ }
614
+ s->working = true;
615
+
616
+ t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
617
+ chan = s->next_chan;
618
+
619
+ do {
620
+ p = &s->packet[chan];
621
+ if (p->needs_service) {
622
+ dev = dwc2_find_device(s, p->devadr);
623
+ ep = usb_ep_get(dev, p->pid, p->epnum);
624
+ trace_usb_dwc2_work_bh_service(s->next_chan, chan, dev, p->epnum);
625
+ dwc2_handle_packet(s, p->devadr, dev, ep, p->index, true);
626
+ found = true;
627
+ }
628
+ if (++chan == DWC2_NB_CHAN) {
629
+ chan = 0;
630
+ }
631
+ if (found) {
632
+ s->next_chan = chan;
633
+ trace_usb_dwc2_work_bh_next(chan);
634
+ }
635
+ } while (chan != s->next_chan);
636
+
637
+ if (found) {
638
+ expire_time = t_now + NANOSECONDS_PER_SECOND / 4000;
639
+ timer_mod(s->frame_timer, expire_time);
640
+ }
641
+ s->working = false;
642
+}
643
+
644
+static void dwc2_enable_chan(DWC2State *s, uint32_t index)
645
+{
646
+ USBDevice *dev;
647
+ USBEndpoint *ep;
648
+ uint32_t hcchar;
649
+ uint32_t hctsiz;
650
+ uint32_t devadr, epnum, epdir, eptype, pid, len;
651
+ DWC2Packet *p;
652
+
653
+ assert((index >> 3) < DWC2_NB_CHAN);
654
+ p = &s->packet[index >> 3];
655
+ hcchar = s->hreg1[index];
656
+ hctsiz = s->hreg1[index + 4];
657
+ devadr = get_field(hcchar, HCCHAR_DEVADDR);
658
+ epnum = get_field(hcchar, HCCHAR_EPNUM);
659
+ epdir = get_bit(hcchar, HCCHAR_EPDIR);
660
+ eptype = get_field(hcchar, HCCHAR_EPTYPE);
661
+ pid = get_field(hctsiz, TSIZ_SC_MC_PID);
662
+ len = get_field(hctsiz, TSIZ_XFERSIZE);
663
+
664
+ dev = dwc2_find_device(s, devadr);
665
+
666
+ trace_usb_dwc2_enable_chan(index >> 3, dev, &p->packet, epnum);
667
+ if (dev == NULL) {
668
+ return;
669
+ }
670
+
671
+ if (eptype == USB_ENDPOINT_XFER_CONTROL && pid == TSIZ_SC_MC_PID_SETUP) {
672
+ pid = USB_TOKEN_SETUP;
673
+ } else {
674
+ pid = epdir ? USB_TOKEN_IN : USB_TOKEN_OUT;
675
+ }
676
+
677
+ ep = usb_ep_get(dev, pid, epnum);
678
+
679
+ /*
680
+ * Hack: Networking doesn't like us delivering large transfers, it kind
681
+ * of works but the latency is horrible. So if the transfer is <= the mtu
682
+ * size, we take that as a hint that this might be a network transfer,
683
+ * and do the transfer packet-by-packet.
684
+ */
685
+ if (len > 1536) {
686
+ p->small = false;
687
+ } else {
688
+ p->small = true;
689
+ }
690
+
691
+ dwc2_handle_packet(s, devadr, dev, ep, index, true);
692
+ qemu_bh_schedule(s->async_bh);
693
+}
694
+
695
+static const char *glbregnm[] = {
696
+ "GOTGCTL ", "GOTGINT ", "GAHBCFG ", "GUSBCFG ", "GRSTCTL ",
697
+ "GINTSTS ", "GINTMSK ", "GRXSTSR ", "GRXSTSP ", "GRXFSIZ ",
698
+ "GNPTXFSIZ", "GNPTXSTS ", "GI2CCTL ", "GPVNDCTL ", "GGPIO ",
699
+ "GUID ", "GSNPSID ", "GHWCFG1 ", "GHWCFG2 ", "GHWCFG3 ",
700
+ "GHWCFG4 ", "GLPMCFG ", "GPWRDN ", "GDFIFOCFG", "GADPCTL ",
701
+ "GREFCLK ", "GINTMSK2 ", "GINTSTS2 "
702
+};
703
+
704
+static uint64_t dwc2_glbreg_read(void *ptr, hwaddr addr, int index,
705
+ unsigned size)
706
+{
707
+ DWC2State *s = ptr;
708
+ uint32_t val;
709
+
710
+ assert(addr <= GINTSTS2);
711
+ val = s->glbreg[index];
712
+
713
+ switch (addr) {
714
+ case GRSTCTL:
715
+ /* clear any self-clearing bits that were set */
716
+ val &= ~(GRSTCTL_TXFFLSH | GRSTCTL_RXFFLSH | GRSTCTL_IN_TKNQ_FLSH |
717
+ GRSTCTL_FRMCNTRRST | GRSTCTL_HSFTRST | GRSTCTL_CSFTRST);
718
+ s->glbreg[index] = val;
719
+ break;
643
+ break;
720
+ default:
644
+ default:
721
+ break;
645
+ lock = 0;
722
+ }
646
+ goto ret_lock;
723
+
647
+ }
724
+ trace_usb_dwc2_glbreg_read(addr, glbregnm[index], val);
648
+
725
+ return val;
649
+ /* Row lock by an efuse bit */
726
+}
650
+ if (lock) {
727
+
651
+ lock = xlnx_efuse_get_bit(s->efuse, lock);
728
+static void dwc2_glbreg_write(void *ptr, hwaddr addr, int index, uint64_t val,
652
+ }
729
+ unsigned size)
653
+
730
+{
654
+ ret_lock:
731
+ DWC2State *s = ptr;
655
+ return lock != 0;
732
+ uint64_t orig = val;
656
+}
733
+ uint32_t *mmio;
657
+
734
+ uint32_t old;
658
+static void efuse_pgm_addr_postw(RegisterInfo *reg, uint64_t val64)
735
+ int iflg = 0;
659
+{
736
+
660
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
737
+ assert(addr <= GINTSTS2);
661
+ unsigned bit = val64;
738
+ mmio = &s->glbreg[index];
662
+ bool ok = false;
739
+ old = *mmio;
663
+
740
+
664
+ /* Always zero out PGM_ADDR because it is write-only */
741
+ switch (addr) {
665
+ s->regs[R_EFUSE_PGM_ADDR] = 0;
742
+ case GOTGCTL:
666
+
743
+ /* don't allow setting of read-only bits */
667
+ /*
744
+ val &= ~(GOTGCTL_MULT_VALID_BC_MASK | GOTGCTL_BSESVLD |
668
+ * Indicate error if bit is write-protected (or read-only
745
+ GOTGCTL_ASESVLD | GOTGCTL_DBNC_SHORT | GOTGCTL_CONID_B |
669
+ * as guarded by efuse_set_bit()).
746
+ GOTGCTL_HSTNEGSCS | GOTGCTL_SESREQSCS);
670
+ *
747
+ /* don't allow clearing of read-only bits */
671
+ * Keep it simple by not modeling program timing.
748
+ val |= old & (GOTGCTL_MULT_VALID_BC_MASK | GOTGCTL_BSESVLD |
672
+ *
749
+ GOTGCTL_ASESVLD | GOTGCTL_DBNC_SHORT | GOTGCTL_CONID_B |
673
+ * Note: model must NEVER clear the PGM_ERROR bit; it is
750
+ GOTGCTL_HSTNEGSCS | GOTGCTL_SESREQSCS);
674
+ * up to guest to do so (or by reset).
751
+ break;
675
+ */
752
+ case GAHBCFG:
676
+ if (efuse_pgm_locked(s, bit)) {
753
+ if ((val & GAHBCFG_GLBL_INTR_EN) && !(old & GAHBCFG_GLBL_INTR_EN)) {
677
+ qemu_log_mask(LOG_GUEST_ERROR,
754
+ iflg = 1;
678
+ "%s: Denied setting of efuse<%u, %u, %u>\n",
679
+ object_get_canonical_path(OBJECT(s)),
680
+ FIELD_EX32(bit, EFUSE_PGM_ADDR, PAGE),
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);
755
+ }
687
+ }
756
+ break;
688
+ }
757
+ case GRSTCTL:
689
+
758
+ val |= GRSTCTL_AHBIDLE;
690
+ if (!ok) {
759
+ val &= ~GRSTCTL_DMAREQ;
691
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_ERROR, 1);
760
+ if (!(old & GRSTCTL_TXFFLSH) && (val & GRSTCTL_TXFFLSH)) {
692
+ }
761
+ /* TODO - TX fifo flush */
693
+
762
+ qemu_log_mask(LOG_UNIMP, "Tx FIFO flush not implemented\n");
694
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_DONE, 1);
763
+ }
695
+ efuse_imr_update_irq(s);
764
+ if (!(old & GRSTCTL_RXFFLSH) && (val & GRSTCTL_RXFFLSH)) {
696
+}
765
+ /* TODO - RX fifo flush */
697
+
766
+ qemu_log_mask(LOG_UNIMP, "Rx FIFO flush not implemented\n");
698
+static void efuse_rd_addr_postw(RegisterInfo *reg, uint64_t val64)
767
+ }
699
+{
768
+ if (!(old & GRSTCTL_IN_TKNQ_FLSH) && (val & GRSTCTL_IN_TKNQ_FLSH)) {
700
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
769
+ /* TODO - device IN token queue flush */
701
+ unsigned bit = val64;
770
+ qemu_log_mask(LOG_UNIMP, "Token queue flush not implemented\n");
702
+ bool denied;
771
+ }
703
+
772
+ if (!(old & GRSTCTL_FRMCNTRRST) && (val & GRSTCTL_FRMCNTRRST)) {
704
+ /* Always zero out RD_ADDR because it is write-only */
773
+ /* TODO - host frame counter reset */
705
+ s->regs[R_EFUSE_RD_ADDR] = 0;
774
+ qemu_log_mask(LOG_UNIMP, "Frame counter reset not implemented\n");
706
+
775
+ }
707
+ /*
776
+ if (!(old & GRSTCTL_HSFTRST) && (val & GRSTCTL_HSFTRST)) {
708
+ * Indicate error if row is read-blocked.
777
+ /* TODO - host soft reset */
709
+ *
778
+ qemu_log_mask(LOG_UNIMP, "Host soft reset not implemented\n");
710
+ * Note: model must NEVER clear the RD_ERROR bit; it is
779
+ }
711
+ * up to guest to do so (or by reset).
780
+ if (!(old & GRSTCTL_CSFTRST) && (val & GRSTCTL_CSFTRST)) {
712
+ */
781
+ /* TODO - core soft reset */
713
+ s->regs[R_EFUSE_RD_DATA] = xlnx_versal_efuse_read_row(s->efuse,
782
+ qemu_log_mask(LOG_UNIMP, "Core soft reset not implemented\n");
714
+ bit, &denied);
783
+ }
715
+ if (denied) {
784
+ /* don't allow clearing of self-clearing bits */
716
+ qemu_log_mask(LOG_GUEST_ERROR,
785
+ val |= old & (GRSTCTL_TXFFLSH | GRSTCTL_RXFFLSH |
717
+ "%s: Denied reading of efuse<%u, %u>\n",
786
+ GRSTCTL_IN_TKNQ_FLSH | GRSTCTL_FRMCNTRRST |
718
+ object_get_canonical_path(OBJECT(s)),
787
+ GRSTCTL_HSFTRST | GRSTCTL_CSFTRST);
719
+ FIELD_EX32(bit, EFUSE_RD_ADDR, PAGE),
788
+ break;
720
+ FIELD_EX32(bit, EFUSE_RD_ADDR, ROW));
789
+ case GINTSTS:
721
+
790
+ /* clear the write-1-to-clear bits */
722
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_ERROR, 1);
791
+ val |= ~old;
723
+ }
792
+ val = ~val;
724
+
793
+ /* don't allow clearing of read-only bits */
725
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_DONE, 1);
794
+ val |= old & (GINTSTS_PTXFEMP | GINTSTS_HCHINT | GINTSTS_PRTINT |
726
+ efuse_imr_update_irq(s);
795
+ GINTSTS_OEPINT | GINTSTS_IEPINT | GINTSTS_GOUTNAKEFF |
727
+ return;
796
+ GINTSTS_GINNAKEFF | GINTSTS_NPTXFEMP | GINTSTS_RXFLVL |
728
+}
797
+ GINTSTS_OTGINT | GINTSTS_CURMODE_HOST);
729
+
798
+ iflg = 1;
730
+static uint64_t efuse_cache_load_prew(RegisterInfo *reg, uint64_t val64)
799
+ break;
731
+{
800
+ case GINTMSK:
732
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
801
+ iflg = 1;
733
+
802
+ break;
734
+ if (val64 & R_EFUSE_CACHE_LOAD_LOAD_MASK) {
803
+ default:
735
+ efuse_data_sync(s);
804
+ break;
736
+
805
+ }
737
+ ARRAY_FIELD_DP32(s->regs, STATUS, CACHE_DONE, 1);
806
+
738
+ efuse_imr_update_irq(s);
807
+ trace_usb_dwc2_glbreg_write(addr, glbregnm[index], orig, old, val);
739
+ }
808
+ *mmio = val;
740
+
809
+
741
+ return 0;
810
+ if (iflg) {
742
+}
811
+ dwc2_update_irq(s);
743
+
812
+ }
744
+static uint64_t efuse_pgm_lock_prew(RegisterInfo *reg, uint64_t val64)
813
+}
745
+{
814
+
746
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
815
+static uint64_t dwc2_fszreg_read(void *ptr, hwaddr addr, int index,
747
+
816
+ unsigned size)
748
+ /* Ignore all other bits */
817
+{
749
+ val64 = FIELD_EX32(val64, EFUSE_PGM_LOCK, SPK_ID_LOCK);
818
+ DWC2State *s = ptr;
750
+
819
+ uint32_t val;
751
+ /* Once the bit is written 1, only reset will clear it to 0 */
820
+
752
+ val64 |= ARRAY_FIELD_EX32(s->regs, EFUSE_PGM_LOCK, SPK_ID_LOCK);
821
+ assert(addr == HPTXFSIZ);
753
+
822
+ val = s->fszreg[index];
754
+ return val64;
823
+
755
+}
824
+ trace_usb_dwc2_fszreg_read(addr, val);
756
+
825
+ return val;
757
+static void efuse_aes_crc_postw(RegisterInfo *reg, uint64_t val64)
826
+}
758
+{
827
+
759
+ efuse_key_crc_check(reg, val64,
828
+static void dwc2_fszreg_write(void *ptr, hwaddr addr, int index, uint64_t val,
760
+ R_STATUS_AES_CRC_PASS_MASK,
829
+ unsigned size)
761
+ R_STATUS_AES_CRC_DONE_MASK,
830
+{
762
+ EFUSE_AES_KEY_START,
831
+ DWC2State *s = ptr;
763
+ EFUSE_AES_KEY_CRC_LK_MASK);
832
+ uint64_t orig = val;
764
+}
833
+ uint32_t *mmio;
765
+
834
+ uint32_t old;
766
+static void efuse_aes_u0_crc_postw(RegisterInfo *reg, uint64_t val64)
835
+
767
+{
836
+ assert(addr == HPTXFSIZ);
768
+ efuse_key_crc_check(reg, val64,
837
+ mmio = &s->fszreg[index];
769
+ R_STATUS_AES_USER_KEY_0_CRC_PASS_MASK,
838
+ old = *mmio;
770
+ R_STATUS_AES_USER_KEY_0_CRC_DONE_MASK,
839
+
771
+ EFUSE_USER_KEY_0_START,
840
+ trace_usb_dwc2_fszreg_write(addr, orig, old, val);
772
+ EFUSE_USER_KEY_0_CRC_LK_MASK);
841
+ *mmio = val;
773
+}
842
+}
774
+
843
+
775
+static void efuse_aes_u1_crc_postw(RegisterInfo *reg, uint64_t val64)
844
+static const char *hreg0nm[] = {
776
+{
845
+ "HCFG ", "HFIR ", "HFNUM ", "<rsvd> ", "HPTXSTS ",
777
+ efuse_key_crc_check(reg, val64,
846
+ "HAINT ", "HAINTMSK ", "HFLBADDR ", "<rsvd> ", "<rsvd> ",
778
+ R_STATUS_AES_USER_KEY_1_CRC_PASS_MASK,
847
+ "<rsvd> ", "<rsvd> ", "<rsvd> ", "<rsvd> ", "<rsvd> ",
779
+ R_STATUS_AES_USER_KEY_1_CRC_DONE_MASK,
848
+ "<rsvd> ", "HPRT0 "
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
+ }
849
+};
846
+};
850
+
847
+
851
+static uint64_t dwc2_hreg0_read(void *ptr, hwaddr addr, int index,
848
+static void efuse_ctrl_reg_write(void *opaque, hwaddr addr,
852
+ unsigned size)
849
+ uint64_t data, unsigned size)
853
+{
850
+{
854
+ DWC2State *s = ptr;
851
+ RegisterInfoArray *reg_array = opaque;
855
+ uint32_t val;
852
+ XlnxVersalEFuseCtrl *s;
856
+
853
+ Object *dev;
857
+ assert(addr >= HCFG && addr <= HPRT0);
854
+
858
+ val = s->hreg0[index];
855
+ assert(reg_array != NULL);
859
+
856
+
860
+ switch (addr) {
857
+ dev = reg_array->mem.owner;
861
+ case HFNUM:
858
+ assert(dev);
862
+ val = (dwc2_get_frame_remaining(s) << HFNUM_FRREM_SHIFT) |
859
+
863
+ (s->hfnum << HFNUM_FRNUM_SHIFT);
860
+ s = XLNX_VERSAL_EFUSE_CTRL(dev);
864
+ break;
861
+
865
+ default:
862
+ if (addr != A_WR_LOCK && s->regs[R_WR_LOCK]) {
866
+ break;
863
+ qemu_log_mask(LOG_GUEST_ERROR,
867
+ }
864
+ "%s[reg_0x%02lx]: Attempt to write locked register.\n",
868
+
865
+ object_get_canonical_path(OBJECT(s)), (long)addr);
869
+ trace_usb_dwc2_hreg0_read(addr, hreg0nm[index], val);
866
+ } else {
870
+ return val;
867
+ register_write_memory(opaque, addr, data, size);
871
+}
868
+ }
872
+
869
+}
873
+static void dwc2_hreg0_write(void *ptr, hwaddr addr, int index, uint64_t val,
870
+
874
+ unsigned size)
871
+static void efuse_ctrl_register_reset(RegisterInfo *reg)
875
+{
872
+{
876
+ DWC2State *s = ptr;
873
+ if (!reg->data || !reg->access) {
877
+ USBDevice *dev = s->uport.dev;
878
+ uint64_t orig = val;
879
+ uint32_t *mmio;
880
+ uint32_t tval, told, old;
881
+ int prst = 0;
882
+ int iflg = 0;
883
+
884
+ assert(addr >= HCFG && addr <= HPRT0);
885
+ mmio = &s->hreg0[index];
886
+ old = *mmio;
887
+
888
+ switch (addr) {
889
+ case HFIR:
890
+ break;
891
+ case HFNUM:
892
+ case HPTXSTS:
893
+ case HAINT:
894
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: write to read-only register\n",
895
+ __func__);
896
+ return;
874
+ return;
897
+ case HAINTMSK:
875
+ }
898
+ val &= 0xffff;
876
+
899
+ break;
877
+ /* Reset must not trigger some registers' writers */
900
+ case HPRT0:
878
+ switch (reg->access->addr) {
901
+ /* don't allow clearing of read-only bits */
879
+ case A_EFUSE_AES_CRC:
902
+ val |= old & (HPRT0_SPD_MASK | HPRT0_LNSTS_MASK | HPRT0_OVRCURRACT |
880
+ case A_EFUSE_AES_USR_KEY0_CRC:
903
+ HPRT0_CONNSTS);
881
+ case A_EFUSE_AES_USR_KEY1_CRC:
904
+ /* don't allow clearing of self-clearing bits */
882
+ *(uint32_t *)reg->data = reg->access->reset;
905
+ val |= old & (HPRT0_SUSP | HPRT0_RES);
883
+ return;
906
+ /* don't allow setting of self-setting bits */
884
+ }
907
+ if (!(old & HPRT0_ENA) && (val & HPRT0_ENA)) {
885
+
908
+ val &= ~HPRT0_ENA;
886
+ register_reset(reg);
909
+ }
887
+}
910
+ /* clear the write-1-to-clear bits */
888
+
911
+ tval = val & (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA |
889
+static void efuse_ctrl_reset(DeviceState *dev)
912
+ HPRT0_CONNDET);
890
+{
913
+ told = old & (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA |
891
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(dev);
914
+ HPRT0_CONNDET);
892
+ unsigned int i;
915
+ tval |= ~told;
893
+
916
+ tval = ~tval;
894
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
917
+ tval &= (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA |
895
+ efuse_ctrl_register_reset(&s->regs_info[i]);
918
+ HPRT0_CONNDET);
896
+ }
919
+ val &= ~(HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA |
897
+
920
+ HPRT0_CONNDET);
898
+ efuse_anchor_bits_check(s);
921
+ val |= tval;
899
+ efuse_data_sync(s);
922
+ if (!(val & HPRT0_RST) && (old & HPRT0_RST)) {
900
+ efuse_imr_update_irq(s);
923
+ if (dev && dev->attached) {
901
+}
924
+ val |= HPRT0_ENA | HPRT0_ENACHG;
902
+
925
+ prst = 1;
903
+static const MemoryRegionOps efuse_ctrl_ops = {
926
+ }
904
+ .read = register_read_memory,
927
+ }
905
+ .write = efuse_ctrl_reg_write,
928
+ if (val & (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_CONNDET)) {
906
+ .endianness = DEVICE_LITTLE_ENDIAN,
929
+ iflg = 1;
907
+ .valid = {
930
+ } else {
908
+ .min_access_size = 4,
931
+ iflg = -1;
909
+ .max_access_size = 4,
932
+ }
910
+ },
933
+ break;
934
+ default:
935
+ break;
936
+ }
937
+
938
+ if (prst) {
939
+ trace_usb_dwc2_hreg0_write(addr, hreg0nm[index], orig, old,
940
+ val & ~HPRT0_CONNDET);
941
+ trace_usb_dwc2_hreg0_action("call usb_port_reset");
942
+ usb_port_reset(&s->uport);
943
+ val &= ~HPRT0_CONNDET;
944
+ } else {
945
+ trace_usb_dwc2_hreg0_write(addr, hreg0nm[index], orig, old, val);
946
+ }
947
+
948
+ *mmio = val;
949
+
950
+ if (iflg > 0) {
951
+ trace_usb_dwc2_hreg0_action("enable PRTINT");
952
+ dwc2_raise_global_irq(s, GINTSTS_PRTINT);
953
+ } else if (iflg < 0) {
954
+ trace_usb_dwc2_hreg0_action("disable PRTINT");
955
+ dwc2_lower_global_irq(s, GINTSTS_PRTINT);
956
+ }
957
+}
958
+
959
+static const char *hreg1nm[] = {
960
+ "HCCHAR ", "HCSPLT ", "HCINT ", "HCINTMSK", "HCTSIZ ", "HCDMA ",
961
+ "<rsvd> ", "HCDMAB "
962
+};
911
+};
963
+
912
+
964
+static uint64_t dwc2_hreg1_read(void *ptr, hwaddr addr, int index,
913
+static void efuse_ctrl_realize(DeviceState *dev, Error **errp)
965
+ unsigned size)
914
+{
966
+{
915
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(dev);
967
+ DWC2State *s = ptr;
916
+ const uint32_t lks_sz = sizeof(XlnxEFuseLkSpec) / 2;
968
+ uint32_t val;
917
+
969
+
918
+ if (!s->efuse) {
970
+ assert(addr >= HCCHAR(0) && addr <= HCDMAB(DWC2_NB_CHAN - 1));
919
+ error_setg(errp, "%s.efuse: link property not connected to XLNX-EFUSE",
971
+ val = s->hreg1[index];
920
+ object_get_canonical_path(OBJECT(dev)));
972
+
973
+ trace_usb_dwc2_hreg1_read(addr, hreg1nm[index & 7], addr >> 5, val);
974
+ return val;
975
+}
976
+
977
+static void dwc2_hreg1_write(void *ptr, hwaddr addr, int index, uint64_t val,
978
+ unsigned size)
979
+{
980
+ DWC2State *s = ptr;
981
+ uint64_t orig = val;
982
+ uint32_t *mmio;
983
+ uint32_t old;
984
+ int iflg = 0;
985
+ int enflg = 0;
986
+ int disflg = 0;
987
+
988
+ assert(addr >= HCCHAR(0) && addr <= HCDMAB(DWC2_NB_CHAN - 1));
989
+ mmio = &s->hreg1[index];
990
+ old = *mmio;
991
+
992
+ switch (HSOTG_REG(0x500) + (addr & 0x1c)) {
993
+ case HCCHAR(0):
994
+ if ((val & HCCHAR_CHDIS) && !(old & HCCHAR_CHDIS)) {
995
+ val &= ~(HCCHAR_CHENA | HCCHAR_CHDIS);
996
+ disflg = 1;
997
+ } else {
998
+ val |= old & HCCHAR_CHDIS;
999
+ if ((val & HCCHAR_CHENA) && !(old & HCCHAR_CHENA)) {
1000
+ val &= ~HCCHAR_CHDIS;
1001
+ enflg = 1;
1002
+ } else {
1003
+ val |= old & HCCHAR_CHENA;
1004
+ }
1005
+ }
1006
+ break;
1007
+ case HCINT(0):
1008
+ /* clear the write-1-to-clear bits */
1009
+ val |= ~old;
1010
+ val = ~val;
1011
+ val &= ~HCINTMSK_RESERVED14_31;
1012
+ iflg = 1;
1013
+ break;
1014
+ case HCINTMSK(0):
1015
+ val &= ~HCINTMSK_RESERVED14_31;
1016
+ iflg = 1;
1017
+ break;
1018
+ case HCDMAB(0):
1019
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: write to read-only register\n",
1020
+ __func__);
1021
+ return;
921
+ return;
1022
+ default:
922
+ }
1023
+ break;
923
+
1024
+ }
924
+ /* Sort property-defined pgm-locks for bsearch lookup */
1025
+
925
+ if ((s->extra_pg0_lock_n16 % lks_sz) != 0) {
1026
+ trace_usb_dwc2_hreg1_write(addr, hreg1nm[index & 7], index >> 3, orig,
926
+ error_setg(errp,
1027
+ old, val);
927
+ "%s.pg0-lock: array property item-count not multiple of %u",
1028
+ *mmio = val;
928
+ object_get_canonical_path(OBJECT(dev)), lks_sz);
1029
+
1030
+ if (disflg) {
1031
+ /* set ChHltd in HCINT */
1032
+ s->hreg1[(index & ~7) + 2] |= HCINTMSK_CHHLTD;
1033
+ iflg = 1;
1034
+ }
1035
+
1036
+ if (enflg) {
1037
+ dwc2_enable_chan(s, index & ~7);
1038
+ }
1039
+
1040
+ if (iflg) {
1041
+ dwc2_update_hc_irq(s, index & ~7);
1042
+ }
1043
+}
1044
+
1045
+static const char *pcgregnm[] = {
1046
+ "PCGCTL ", "PCGCCTL1 "
1047
+};
1048
+
1049
+static uint64_t dwc2_pcgreg_read(void *ptr, hwaddr addr, int index,
1050
+ unsigned size)
1051
+{
1052
+ DWC2State *s = ptr;
1053
+ uint32_t val;
1054
+
1055
+ assert(addr >= PCGCTL && addr <= PCGCCTL1);
1056
+ val = s->pcgreg[index];
1057
+
1058
+ trace_usb_dwc2_pcgreg_read(addr, pcgregnm[index], val);
1059
+ return val;
1060
+}
1061
+
1062
+static void dwc2_pcgreg_write(void *ptr, hwaddr addr, int index,
1063
+ uint64_t val, unsigned size)
1064
+{
1065
+ DWC2State *s = ptr;
1066
+ uint64_t orig = val;
1067
+ uint32_t *mmio;
1068
+ uint32_t old;
1069
+
1070
+ assert(addr >= PCGCTL && addr <= PCGCCTL1);
1071
+ mmio = &s->pcgreg[index];
1072
+ old = *mmio;
1073
+
1074
+ trace_usb_dwc2_pcgreg_write(addr, pcgregnm[index], orig, old, val);
1075
+ *mmio = val;
1076
+}
1077
+
1078
+static uint64_t dwc2_hsotg_read(void *ptr, hwaddr addr, unsigned size)
1079
+{
1080
+ uint64_t val;
1081
+
1082
+ switch (addr) {
1083
+ case HSOTG_REG(0x000) ... HSOTG_REG(0x0fc):
1084
+ val = dwc2_glbreg_read(ptr, addr, (addr - HSOTG_REG(0x000)) >> 2, size);
1085
+ break;
1086
+ case HSOTG_REG(0x100):
1087
+ val = dwc2_fszreg_read(ptr, addr, (addr - HSOTG_REG(0x100)) >> 2, size);
1088
+ break;
1089
+ case HSOTG_REG(0x104) ... HSOTG_REG(0x3fc):
1090
+ /* Gadget-mode registers, just return 0 for now */
1091
+ val = 0;
1092
+ break;
1093
+ case HSOTG_REG(0x400) ... HSOTG_REG(0x4fc):
1094
+ val = dwc2_hreg0_read(ptr, addr, (addr - HSOTG_REG(0x400)) >> 2, size);
1095
+ break;
1096
+ case HSOTG_REG(0x500) ... HSOTG_REG(0x7fc):
1097
+ val = dwc2_hreg1_read(ptr, addr, (addr - HSOTG_REG(0x500)) >> 2, size);
1098
+ break;
1099
+ case HSOTG_REG(0x800) ... HSOTG_REG(0xdfc):
1100
+ /* Gadget-mode registers, just return 0 for now */
1101
+ val = 0;
1102
+ break;
1103
+ case HSOTG_REG(0xe00) ... HSOTG_REG(0xffc):
1104
+ val = dwc2_pcgreg_read(ptr, addr, (addr - HSOTG_REG(0xe00)) >> 2, size);
1105
+ break;
1106
+ default:
1107
+ g_assert_not_reached();
1108
+ }
1109
+
1110
+ return val;
1111
+}
1112
+
1113
+static void dwc2_hsotg_write(void *ptr, hwaddr addr, uint64_t val,
1114
+ unsigned size)
1115
+{
1116
+ switch (addr) {
1117
+ case HSOTG_REG(0x000) ... HSOTG_REG(0x0fc):
1118
+ dwc2_glbreg_write(ptr, addr, (addr - HSOTG_REG(0x000)) >> 2, val, size);
1119
+ break;
1120
+ case HSOTG_REG(0x100):
1121
+ dwc2_fszreg_write(ptr, addr, (addr - HSOTG_REG(0x100)) >> 2, val, size);
1122
+ break;
1123
+ case HSOTG_REG(0x104) ... HSOTG_REG(0x3fc):
1124
+ /* Gadget-mode registers, do nothing for now */
1125
+ break;
1126
+ case HSOTG_REG(0x400) ... HSOTG_REG(0x4fc):
1127
+ dwc2_hreg0_write(ptr, addr, (addr - HSOTG_REG(0x400)) >> 2, val, size);
1128
+ break;
1129
+ case HSOTG_REG(0x500) ... HSOTG_REG(0x7fc):
1130
+ dwc2_hreg1_write(ptr, addr, (addr - HSOTG_REG(0x500)) >> 2, val, size);
1131
+ break;
1132
+ case HSOTG_REG(0x800) ... HSOTG_REG(0xdfc):
1133
+ /* Gadget-mode registers, do nothing for now */
1134
+ break;
1135
+ case HSOTG_REG(0xe00) ... HSOTG_REG(0xffc):
1136
+ dwc2_pcgreg_write(ptr, addr, (addr - HSOTG_REG(0xe00)) >> 2, val, size);
1137
+ break;
1138
+ default:
1139
+ g_assert_not_reached();
1140
+ }
1141
+}
1142
+
1143
+static const MemoryRegionOps dwc2_mmio_hsotg_ops = {
1144
+ .read = dwc2_hsotg_read,
1145
+ .write = dwc2_hsotg_write,
1146
+ .impl.min_access_size = 4,
1147
+ .impl.max_access_size = 4,
1148
+ .endianness = DEVICE_LITTLE_ENDIAN,
1149
+};
1150
+
1151
+static uint64_t dwc2_hreg2_read(void *ptr, hwaddr addr, unsigned size)
1152
+{
1153
+ /* TODO - implement FIFOs to support slave mode */
1154
+ trace_usb_dwc2_hreg2_read(addr, addr >> 12, 0);
1155
+ qemu_log_mask(LOG_UNIMP, "FIFO read not implemented\n");
1156
+ return 0;
1157
+}
1158
+
1159
+static void dwc2_hreg2_write(void *ptr, hwaddr addr, uint64_t val,
1160
+ unsigned size)
1161
+{
1162
+ uint64_t orig = val;
1163
+
1164
+ /* TODO - implement FIFOs to support slave mode */
1165
+ trace_usb_dwc2_hreg2_write(addr, addr >> 12, orig, 0, val);
1166
+ qemu_log_mask(LOG_UNIMP, "FIFO write not implemented\n");
1167
+}
1168
+
1169
+static const MemoryRegionOps dwc2_mmio_hreg2_ops = {
1170
+ .read = dwc2_hreg2_read,
1171
+ .write = dwc2_hreg2_write,
1172
+ .impl.min_access_size = 4,
1173
+ .impl.max_access_size = 4,
1174
+ .endianness = DEVICE_LITTLE_ENDIAN,
1175
+};
1176
+
1177
+static void dwc2_wakeup_endpoint(USBBus *bus, USBEndpoint *ep,
1178
+ unsigned int stream)
1179
+{
1180
+ DWC2State *s = container_of(bus, DWC2State, bus);
1181
+
1182
+ trace_usb_dwc2_wakeup_endpoint(ep, stream);
1183
+
1184
+ /* TODO - do something here? */
1185
+ qemu_bh_schedule(s->async_bh);
1186
+}
1187
+
1188
+static USBBusOps dwc2_bus_ops = {
1189
+ .wakeup_endpoint = dwc2_wakeup_endpoint,
1190
+};
1191
+
1192
+static void dwc2_work_timer(void *opaque)
1193
+{
1194
+ DWC2State *s = opaque;
1195
+
1196
+ trace_usb_dwc2_work_timer();
1197
+ qemu_bh_schedule(s->async_bh);
1198
+}
1199
+
1200
+static void dwc2_reset_enter(Object *obj, ResetType type)
1201
+{
1202
+ DWC2Class *c = DWC2_GET_CLASS(obj);
1203
+ DWC2State *s = DWC2_USB(obj);
1204
+ int i;
1205
+
1206
+ trace_usb_dwc2_reset_enter();
1207
+
1208
+ if (c->parent_phases.enter) {
1209
+ c->parent_phases.enter(obj, type);
1210
+ }
1211
+
1212
+ timer_del(s->frame_timer);
1213
+ qemu_bh_cancel(s->async_bh);
1214
+
1215
+ if (s->uport.dev && s->uport.dev->attached) {
1216
+ usb_detach(&s->uport);
1217
+ }
1218
+
1219
+ dwc2_bus_stop(s);
1220
+
1221
+ s->gotgctl = GOTGCTL_BSESVLD | GOTGCTL_ASESVLD | GOTGCTL_CONID_B;
1222
+ s->gotgint = 0;
1223
+ s->gahbcfg = 0;
1224
+ s->gusbcfg = 5 << GUSBCFG_USBTRDTIM_SHIFT;
1225
+ s->grstctl = GRSTCTL_AHBIDLE;
1226
+ s->gintsts = GINTSTS_CONIDSTSCHNG | GINTSTS_PTXFEMP | GINTSTS_NPTXFEMP |
1227
+ GINTSTS_CURMODE_HOST;
1228
+ s->gintmsk = 0;
1229
+ s->grxstsr = 0;
1230
+ s->grxstsp = 0;
1231
+ s->grxfsiz = 1024;
1232
+ s->gnptxfsiz = 1024 << FIFOSIZE_DEPTH_SHIFT;
1233
+ s->gnptxsts = (4 << FIFOSIZE_DEPTH_SHIFT) | 1024;
1234
+ s->gi2cctl = GI2CCTL_I2CDATSE0 | GI2CCTL_ACK;
1235
+ s->gpvndctl = 0;
1236
+ s->ggpio = 0;
1237
+ s->guid = 0;
1238
+ s->gsnpsid = 0x4f54294a;
1239
+ s->ghwcfg1 = 0;
1240
+ s->ghwcfg2 = (8 << GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT) |
1241
+ (4 << GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT) |
1242
+ (4 << GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT) |
1243
+ GHWCFG2_DYNAMIC_FIFO |
1244
+ GHWCFG2_PERIO_EP_SUPPORTED |
1245
+ ((DWC2_NB_CHAN - 1) << GHWCFG2_NUM_HOST_CHAN_SHIFT) |
1246
+ (GHWCFG2_INT_DMA_ARCH << GHWCFG2_ARCHITECTURE_SHIFT) |
1247
+ (GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST << GHWCFG2_OP_MODE_SHIFT);
1248
+ s->ghwcfg3 = (4096 << GHWCFG3_DFIFO_DEPTH_SHIFT) |
1249
+ (4 << GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT) |
1250
+ (4 << GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT);
1251
+ s->ghwcfg4 = 0;
1252
+ s->glpmcfg = 0;
1253
+ s->gpwrdn = GPWRDN_PWRDNRSTN;
1254
+ s->gdfifocfg = 0;
1255
+ s->gadpctl = 0;
1256
+ s->grefclk = 0;
1257
+ s->gintmsk2 = 0;
1258
+ s->gintsts2 = 0;
1259
+
1260
+ s->hptxfsiz = 500 << FIFOSIZE_DEPTH_SHIFT;
1261
+
1262
+ s->hcfg = 2 << HCFG_RESVALID_SHIFT;
1263
+ s->hfir = 60000;
1264
+ s->hfnum = 0x3fff;
1265
+ s->hptxsts = (16 << TXSTS_QSPCAVAIL_SHIFT) | 32768;
1266
+ s->haint = 0;
1267
+ s->haintmsk = 0;
1268
+ s->hprt0 = 0;
1269
+
1270
+ memset(s->hreg1, 0, sizeof(s->hreg1));
1271
+ memset(s->pcgreg, 0, sizeof(s->pcgreg));
1272
+
1273
+ s->sof_time = 0;
1274
+ s->frame_number = 0;
1275
+ s->fi = USB_FRMINTVL - 1;
1276
+ s->next_chan = 0;
1277
+ s->working = false;
1278
+
1279
+ for (i = 0; i < DWC2_NB_CHAN; i++) {
1280
+ s->packet[i].needs_service = false;
1281
+ }
1282
+}
1283
+
1284
+static void dwc2_reset_hold(Object *obj)
1285
+{
1286
+ DWC2Class *c = DWC2_GET_CLASS(obj);
1287
+ DWC2State *s = DWC2_USB(obj);
1288
+
1289
+ trace_usb_dwc2_reset_hold();
1290
+
1291
+ if (c->parent_phases.hold) {
1292
+ c->parent_phases.hold(obj);
1293
+ }
1294
+
1295
+ dwc2_update_irq(s);
1296
+}
1297
+
1298
+static void dwc2_reset_exit(Object *obj)
1299
+{
1300
+ DWC2Class *c = DWC2_GET_CLASS(obj);
1301
+ DWC2State *s = DWC2_USB(obj);
1302
+
1303
+ trace_usb_dwc2_reset_exit();
1304
+
1305
+ if (c->parent_phases.exit) {
1306
+ c->parent_phases.exit(obj);
1307
+ }
1308
+
1309
+ s->hprt0 = HPRT0_PWR;
1310
+ if (s->uport.dev && s->uport.dev->attached) {
1311
+ usb_attach(&s->uport);
1312
+ usb_device_reset(s->uport.dev);
1313
+ }
1314
+}
1315
+
1316
+static void dwc2_realize(DeviceState *dev, Error **errp)
1317
+{
1318
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
1319
+ DWC2State *s = DWC2_USB(dev);
1320
+ Object *obj;
1321
+ Error *err = NULL;
1322
+
1323
+ obj = object_property_get_link(OBJECT(dev), "dma-mr", &err);
1324
+ if (err) {
1325
+ error_setg(errp, "dwc2: required dma-mr link not found: %s",
1326
+ error_get_pretty(err));
1327
+ return;
929
+ return;
1328
+ }
930
+ }
1329
+ assert(obj != NULL);
931
+
1330
+
932
+ efuse_lk_spec_sort(s);
1331
+ s->dma_mr = MEMORY_REGION(obj);
933
+}
1332
+ address_space_init(&s->dma_as, s->dma_mr, "dwc2");
934
+
1333
+
935
+static void efuse_ctrl_init(Object *obj)
1334
+ usb_bus_new(&s->bus, sizeof(s->bus), &dwc2_bus_ops, dev);
936
+{
1335
+ usb_register_port(&s->bus, &s->uport, s, 0, &dwc2_port_ops,
937
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(obj);
1336
+ USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL |
1337
+ (s->usb_version == 2 ? USB_SPEED_MASK_HIGH : 0));
1338
+ s->uport.dev = 0;
1339
+
1340
+ s->usb_frame_time = NANOSECONDS_PER_SECOND / 1000; /* 1000000 */
1341
+ if (NANOSECONDS_PER_SECOND >= USB_HZ_FS) {
1342
+ s->usb_bit_time = NANOSECONDS_PER_SECOND / USB_HZ_FS; /* 83.3 */
1343
+ } else {
1344
+ s->usb_bit_time = 1;
1345
+ }
1346
+
1347
+ s->fi = USB_FRMINTVL - 1;
1348
+ s->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_frame_boundary, s);
1349
+ s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_work_timer, s);
1350
+ s->async_bh = qemu_bh_new(dwc2_work_bh, s);
1351
+
1352
+ sysbus_init_irq(sbd, &s->irq);
1353
+}
1354
+
1355
+static void dwc2_init(Object *obj)
1356
+{
1357
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
938
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
1358
+ DWC2State *s = DWC2_USB(obj);
939
+ RegisterInfoArray *reg_array;
1359
+
940
+
1360
+ memory_region_init(&s->container, obj, "dwc2", DWC2_MMIO_SIZE);
941
+ reg_array =
1361
+ sysbus_init_mmio(sbd, &s->container);
942
+ register_init_block32(DEVICE(obj), efuse_ctrl_regs_info,
1362
+
943
+ ARRAY_SIZE(efuse_ctrl_regs_info),
1363
+ memory_region_init_io(&s->hsotg, obj, &dwc2_mmio_hsotg_ops, s,
944
+ s->regs_info, s->regs,
1364
+ "dwc2-io", 4 * KiB);
945
+ &efuse_ctrl_ops,
1365
+ memory_region_add_subregion(&s->container, 0x0000, &s->hsotg);
946
+ XLNX_VERSAL_EFUSE_CTRL_ERR_DEBUG,
1366
+
947
+ R_MAX * 4);
1367
+ memory_region_init_io(&s->fifos, obj, &dwc2_mmio_hreg2_ops, s,
948
+
1368
+ "dwc2-fifo", 64 * KiB);
949
+ sysbus_init_mmio(sbd, &reg_array->mem);
1369
+ memory_region_add_subregion(&s->container, 0x1000, &s->fifos);
950
+ sysbus_init_irq(sbd, &s->irq_efuse_imr);
1370
+}
951
+}
1371
+
952
+
1372
+static const VMStateDescription vmstate_dwc2_state_packet = {
953
+static const VMStateDescription vmstate_efuse_ctrl = {
1373
+ .name = "dwc2/packet",
954
+ .name = TYPE_XLNX_VERSAL_EFUSE_CTRL,
1374
+ .version_id = 1,
955
+ .version_id = 1,
1375
+ .minimum_version_id = 1,
956
+ .minimum_version_id = 1,
1376
+ .fields = (VMStateField[]) {
957
+ .fields = (VMStateField[]) {
1377
+ VMSTATE_UINT32(devadr, DWC2Packet),
958
+ VMSTATE_UINT32_ARRAY(regs, XlnxVersalEFuseCtrl, R_MAX),
1378
+ VMSTATE_UINT32(epnum, DWC2Packet),
959
+ VMSTATE_END_OF_LIST(),
1379
+ VMSTATE_UINT32(epdir, DWC2Packet),
960
+ }
1380
+ VMSTATE_UINT32(mps, DWC2Packet),
1381
+ VMSTATE_UINT32(pid, DWC2Packet),
1382
+ VMSTATE_UINT32(index, DWC2Packet),
1383
+ VMSTATE_UINT32(pcnt, DWC2Packet),
1384
+ VMSTATE_UINT32(len, DWC2Packet),
1385
+ VMSTATE_INT32(async, DWC2Packet),
1386
+ VMSTATE_BOOL(small, DWC2Packet),
1387
+ VMSTATE_BOOL(needs_service, DWC2Packet),
1388
+ VMSTATE_END_OF_LIST()
1389
+ },
1390
+};
961
+};
1391
+
962
+
1392
+const VMStateDescription vmstate_dwc2_state = {
963
+static Property efuse_ctrl_props[] = {
1393
+ .name = "dwc2",
964
+ DEFINE_PROP_LINK("efuse",
1394
+ .version_id = 1,
965
+ XlnxVersalEFuseCtrl, efuse,
1395
+ .minimum_version_id = 1,
966
+ TYPE_XLNX_EFUSE, XlnxEFuse *),
1396
+ .fields = (VMStateField[]) {
967
+ DEFINE_PROP_ARRAY("pg0-lock",
1397
+ VMSTATE_UINT32_ARRAY(glbreg, DWC2State,
968
+ XlnxVersalEFuseCtrl, extra_pg0_lock_n16,
1398
+ DWC2_GLBREG_SIZE / sizeof(uint32_t)),
969
+ extra_pg0_lock_spec, qdev_prop_uint16, uint16_t),
1399
+ VMSTATE_UINT32_ARRAY(fszreg, DWC2State,
970
+
1400
+ DWC2_FSZREG_SIZE / sizeof(uint32_t)),
1401
+ VMSTATE_UINT32_ARRAY(hreg0, DWC2State,
1402
+ DWC2_HREG0_SIZE / sizeof(uint32_t)),
1403
+ VMSTATE_UINT32_ARRAY(hreg1, DWC2State,
1404
+ DWC2_HREG1_SIZE / sizeof(uint32_t)),
1405
+ VMSTATE_UINT32_ARRAY(pcgreg, DWC2State,
1406
+ DWC2_PCGREG_SIZE / sizeof(uint32_t)),
1407
+
1408
+ VMSTATE_TIMER_PTR(eof_timer, DWC2State),
1409
+ VMSTATE_TIMER_PTR(frame_timer, DWC2State),
1410
+ VMSTATE_INT64(sof_time, DWC2State),
1411
+ VMSTATE_INT64(usb_frame_time, DWC2State),
1412
+ VMSTATE_INT64(usb_bit_time, DWC2State),
1413
+ VMSTATE_UINT32(usb_version, DWC2State),
1414
+ VMSTATE_UINT16(frame_number, DWC2State),
1415
+ VMSTATE_UINT16(fi, DWC2State),
1416
+ VMSTATE_UINT16(next_chan, DWC2State),
1417
+ VMSTATE_BOOL(working, DWC2State),
1418
+
1419
+ VMSTATE_STRUCT_ARRAY(packet, DWC2State, DWC2_NB_CHAN, 1,
1420
+ vmstate_dwc2_state_packet, DWC2Packet),
1421
+ VMSTATE_UINT8_2DARRAY(usb_buf, DWC2State, DWC2_NB_CHAN,
1422
+ DWC2_MAX_XFER_SIZE),
1423
+
1424
+ VMSTATE_END_OF_LIST()
1425
+ }
1426
+};
1427
+
1428
+static Property dwc2_usb_properties[] = {
1429
+ DEFINE_PROP_UINT32("usb_version", DWC2State, usb_version, 2),
1430
+ DEFINE_PROP_END_OF_LIST(),
971
+ DEFINE_PROP_END_OF_LIST(),
1431
+};
972
+};
1432
+
973
+
1433
+static void dwc2_class_init(ObjectClass *klass, void *data)
974
+static void efuse_ctrl_class_init(ObjectClass *klass, void *data)
1434
+{
975
+{
1435
+ DeviceClass *dc = DEVICE_CLASS(klass);
976
+ DeviceClass *dc = DEVICE_CLASS(klass);
1436
+ DWC2Class *c = DWC2_CLASS(klass);
977
+
1437
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
978
+ dc->reset = efuse_ctrl_reset;
1438
+
979
+ dc->realize = efuse_ctrl_realize;
1439
+ dc->realize = dwc2_realize;
980
+ dc->vmsd = &vmstate_efuse_ctrl;
1440
+ dc->vmsd = &vmstate_dwc2_state;
981
+ device_class_set_props(dc, efuse_ctrl_props);
1441
+ set_bit(DEVICE_CATEGORY_USB, dc->categories);
982
+}
1442
+ device_class_set_props(dc, dwc2_usb_properties);
983
+
1443
+ resettable_class_set_parent_phases(rc, dwc2_reset_enter, dwc2_reset_hold,
984
+static const TypeInfo efuse_ctrl_info = {
1444
+ dwc2_reset_exit, &c->parent_phases);
985
+ .name = TYPE_XLNX_VERSAL_EFUSE_CTRL,
1445
+}
1446
+
1447
+static const TypeInfo dwc2_usb_type_info = {
1448
+ .name = TYPE_DWC2_USB,
1449
+ .parent = TYPE_SYS_BUS_DEVICE,
986
+ .parent = TYPE_SYS_BUS_DEVICE,
1450
+ .instance_size = sizeof(DWC2State),
987
+ .instance_size = sizeof(XlnxVersalEFuseCtrl),
1451
+ .instance_init = dwc2_init,
988
+ .class_init = efuse_ctrl_class_init,
1452
+ .class_size = sizeof(DWC2Class),
989
+ .instance_init = efuse_ctrl_init,
1453
+ .class_init = dwc2_class_init,
1454
+};
990
+};
1455
+
991
+
1456
+static void dwc2_usb_register_types(void)
992
+static void efuse_ctrl_register_types(void)
1457
+{
993
+{
1458
+ type_register_static(&dwc2_usb_type_info);
994
+ type_register_static(&efuse_ctrl_info);
1459
+}
995
+}
1460
+
996
+
1461
+type_init(dwc2_usb_register_types)
997
+type_init(efuse_ctrl_register_types)
1462
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
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
1463
index XXXXXXX..XXXXXXX 100644
1020
index XXXXXXX..XXXXXXX 100644
1464
--- a/hw/usb/Kconfig
1021
--- a/hw/nvram/Kconfig
1465
+++ b/hw/usb/Kconfig
1022
+++ b/hw/nvram/Kconfig
1466
@@ -XXX,XX +XXX,XX @@ config USB_MUSB
1023
@@ -XXX,XX +XXX,XX @@ config XLNX_EFUSE_CRC
1024
config XLNX_EFUSE
1467
bool
1025
bool
1468
select USB
1026
select XLNX_EFUSE_CRC
1469
1027
+
1470
+config USB_DWC2
1028
+config XLNX_EFUSE_VERSAL
1471
+ bool
1029
+ bool
1472
+ default y
1030
+ select XLNX_EFUSE
1473
+ select USB
1031
diff --git a/hw/nvram/meson.build b/hw/nvram/meson.build
1474
+
1475
config TUSB6010
1476
bool
1477
select USB_MUSB
1478
diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
1479
index XXXXXXX..XXXXXXX 100644
1032
index XXXXXXX..XXXXXXX 100644
1480
--- a/hw/usb/Makefile.objs
1033
--- a/hw/nvram/meson.build
1481
+++ b/hw/usb/Makefile.objs
1034
+++ b/hw/nvram/meson.build
1482
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_USB_EHCI_SYSBUS) += hcd-ehci-sysbus.o
1035
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_otp.c'))
1483
common-obj-$(CONFIG_USB_XHCI) += hcd-xhci.o
1036
softmmu_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_nvm.c'))
1484
common-obj-$(CONFIG_USB_XHCI_NEC) += hcd-xhci-nec.o
1037
softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE_CRC', if_true: files('xlnx-efuse-crc.c'))
1485
common-obj-$(CONFIG_USB_MUSB) += hcd-musb.o
1038
softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE', if_true: files('xlnx-efuse.c'))
1486
+common-obj-$(CONFIG_USB_DWC2) += hcd-dwc2.o
1039
+softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE_VERSAL', if_true: files(
1487
1040
+ 'xlnx-versal-efuse-cache.c',
1488
common-obj-$(CONFIG_TUSB6010) += tusb6010.o
1041
+ 'xlnx-versal-efuse-ctrl.c'))
1489
common-obj-$(CONFIG_IMX) += chipidea.o
1042
1490
diff --git a/hw/usb/trace-events b/hw/usb/trace-events
1043
specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_nvram.c'))
1491
index XXXXXXX..XXXXXXX 100644
1492
--- a/hw/usb/trace-events
1493
+++ b/hw/usb/trace-events
1494
@@ -XXX,XX +XXX,XX @@ usb_xhci_xfer_error(void *xfer, uint32_t ret) "%p: ret %d"
1495
usb_xhci_unimplemented(const char *item, int nr) "%s (0x%x)"
1496
usb_xhci_enforced_limit(const char *item) "%s"
1497
1498
+# hcd-dwc2.c
1499
+usb_dwc2_update_irq(uint32_t level) "level=%d"
1500
+usb_dwc2_raise_global_irq(uint32_t intr) "0x%08x"
1501
+usb_dwc2_lower_global_irq(uint32_t intr) "0x%08x"
1502
+usb_dwc2_raise_host_irq(uint32_t intr) "0x%04x"
1503
+usb_dwc2_lower_host_irq(uint32_t intr) "0x%04x"
1504
+usb_dwc2_sof(int64_t next) "next SOF %" PRId64
1505
+usb_dwc2_bus_start(void) "start SOFs"
1506
+usb_dwc2_bus_stop(void) "stop SOFs"
1507
+usb_dwc2_find_device(uint8_t addr) "%d"
1508
+usb_dwc2_port_disabled(uint32_t pnum) "port %d disabled"
1509
+usb_dwc2_device_found(uint32_t pnum) "device found on port %d"
1510
+usb_dwc2_device_not_found(void) "device not found"
1511
+usb_dwc2_handle_packet(uint32_t chan, void *dev, void *pkt, uint32_t ep, const char *type, const char *dir, uint32_t mps, uint32_t len, uint32_t pcnt) "ch %d dev %p pkt %p ep %d type %s dir %s mps %d len %d pcnt %d"
1512
+usb_dwc2_memory_read(uint32_t addr, uint32_t len) "addr %d len %d"
1513
+usb_dwc2_packet_status(const char *status, uint32_t len) "status %s len %d"
1514
+usb_dwc2_packet_error(const char *status) "ERROR %s"
1515
+usb_dwc2_async_packet(void *pkt, uint32_t chan, void *dev, uint32_t ep, const char *dir, uint32_t len) "pkt %p ch %d dev %p ep %d %s len %d"
1516
+usb_dwc2_memory_write(uint32_t addr, uint32_t len) "addr %d len %d"
1517
+usb_dwc2_packet_done(const char *status, uint32_t actual, uint32_t len, uint32_t pcnt) "status %s actual %d len %d pcnt %d"
1518
+usb_dwc2_packet_next(const char *status, uint32_t len, uint32_t pcnt) "status %s len %d pcnt %d"
1519
+usb_dwc2_attach(void *port) "port %p"
1520
+usb_dwc2_attach_speed(const char *speed) "%s-speed device attached"
1521
+usb_dwc2_detach(void *port) "port %p"
1522
+usb_dwc2_child_detach(void *port, void *child) "port %p child %p"
1523
+usb_dwc2_wakeup(void *port) "port %p"
1524
+usb_dwc2_async_packet_complete(void *port, void *pkt, uint32_t chan, void *dev, uint32_t ep, const char *dir, uint32_t len) "port %p packet %p ch %d dev %p ep %d %s len %d"
1525
+usb_dwc2_work_bh(void) ""
1526
+usb_dwc2_work_bh_service(uint32_t first, uint32_t current, void *dev, uint32_t ep) "first %d servicing %d dev %p ep %d"
1527
+usb_dwc2_work_bh_next(uint32_t chan) "next %d"
1528
+usb_dwc2_enable_chan(uint32_t chan, void *dev, void *pkt, uint32_t ep) "ch %d dev %p pkt %p ep %d"
1529
+usb_dwc2_glbreg_read(uint64_t addr, const char *reg, uint32_t val) " 0x%04" PRIx64 " %s val 0x%08x"
1530
+usb_dwc2_glbreg_write(uint64_t addr, const char *reg, uint64_t val, uint32_t old, uint64_t result) "0x%04" PRIx64 " %s val 0x%08" PRIx64 " old 0x%08x result 0x%08" PRIx64
1531
+usb_dwc2_fszreg_read(uint64_t addr, uint32_t val) " 0x%04" PRIx64 " HPTXFSIZ val 0x%08x"
1532
+usb_dwc2_fszreg_write(uint64_t addr, uint64_t val, uint32_t old, uint64_t result) "0x%04" PRIx64 " HPTXFSIZ val 0x%08" PRIx64 " old 0x%08x result 0x%08" PRIx64
1533
+usb_dwc2_hreg0_read(uint64_t addr, const char *reg, uint32_t val) " 0x%04" PRIx64 " %s val 0x%08x"
1534
+usb_dwc2_hreg0_write(uint64_t addr, const char *reg, uint64_t val, uint32_t old, uint64_t result) " 0x%04" PRIx64 " %s val 0x%08" PRIx64 " old 0x%08x result 0x%08" PRIx64
1535
+usb_dwc2_hreg1_read(uint64_t addr, const char *reg, uint64_t chan, uint32_t val) " 0x%04" PRIx64 " %s%" PRId64 " val 0x%08x"
1536
+usb_dwc2_hreg1_write(uint64_t addr, const char *reg, uint64_t chan, uint64_t val, uint32_t old, uint64_t result) " 0x%04" PRIx64 " %s%" PRId64 " val 0x%08" PRIx64 " old 0x%08x result 0x%08" PRIx64
1537
+usb_dwc2_pcgreg_read(uint64_t addr, const char *reg, uint32_t val) " 0x%04" PRIx64 " %s val 0x%08x"
1538
+usb_dwc2_pcgreg_write(uint64_t addr, const char *reg, uint64_t val, uint32_t old, uint64_t result) "0x%04" PRIx64 " %s val 0x%08" PRIx64 " old 0x%08x result 0x%08" PRIx64
1539
+usb_dwc2_hreg2_read(uint64_t addr, uint64_t fifo, uint32_t val) " 0x%04" PRIx64 " FIFO%" PRId64 " val 0x%08x"
1540
+usb_dwc2_hreg2_write(uint64_t addr, uint64_t fifo, uint64_t val, uint32_t old, uint64_t result) " 0x%04" PRIx64 " FIFO%" PRId64 " val 0x%08" PRIx64 " old 0x%08x result 0x%08" PRIx64
1541
+usb_dwc2_hreg0_action(const char *s) "%s"
1542
+usb_dwc2_wakeup_endpoint(void *ep, uint32_t stream) "endp %p stream %d"
1543
+usb_dwc2_work_timer(void) ""
1544
+usb_dwc2_reset_enter(void) "=== RESET enter ==="
1545
+usb_dwc2_reset_hold(void) "=== RESET hold ==="
1546
+usb_dwc2_reset_exit(void) "=== RESET exit ==="
1547
+
1548
# desc.c
1549
usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d"
1550
usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device qualifier, len %d, ret %d"
1551
--
1044
--
1552
2.20.1
1045
2.20.1
1553
1046
1554
1047
diff view generated by jsdifflib
1
From: Paul Zimmerman <pauldzim@gmail.com>
1
From: Tong Ho <tong.ho@xilinx.com>
2
2
3
Add BCM2835 SOC MPHI (Message-based Parallel Host Interface)
3
This implements the Xilinx ZynqMP eFuse, an one-time
4
emulation. It is very basic, only providing the FIQ interrupt
4
field-programmable non-volatile storage device. There is
5
needed to allow the dwc-otg USB host controller driver in the
5
only one such device in the Xilinx ZynqMP product family.
6
Raspbian kernel to function.
7
6
8
Signed-off-by: Paul Zimmerman <pauldzim@gmail.com>
7
Co-authored-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Acked-by: Philippe Mathieu-Daude <f4bug@amsat.org>
8
Co-authored-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
9
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
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20200520235349.21215-2-pauldzim@gmail.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
16
---
14
include/hw/arm/bcm2835_peripherals.h | 2 +
17
include/hw/nvram/xlnx-zynqmp-efuse.h | 44 ++
15
include/hw/misc/bcm2835_mphi.h | 44 ++++++
18
hw/nvram/xlnx-zynqmp-efuse.c | 855 +++++++++++++++++++++++++++
16
hw/arm/bcm2835_peripherals.c | 17 +++
19
hw/nvram/Kconfig | 4 +
17
hw/misc/bcm2835_mphi.c | 191 +++++++++++++++++++++++++++
20
hw/nvram/meson.build | 2 +
18
hw/misc/Makefile.objs | 1 +
21
4 files changed, 905 insertions(+)
19
5 files changed, 255 insertions(+)
22
create mode 100644 include/hw/nvram/xlnx-zynqmp-efuse.h
20
create mode 100644 include/hw/misc/bcm2835_mphi.h
23
create mode 100644 hw/nvram/xlnx-zynqmp-efuse.c
21
create mode 100644 hw/misc/bcm2835_mphi.c
22
24
23
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
25
diff --git a/include/hw/nvram/xlnx-zynqmp-efuse.h b/include/hw/nvram/xlnx-zynqmp-efuse.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/bcm2835_peripherals.h
26
+++ b/include/hw/arm/bcm2835_peripherals.h
27
@@ -XXX,XX +XXX,XX @@
28
#include "hw/misc/bcm2835_property.h"
29
#include "hw/misc/bcm2835_rng.h"
30
#include "hw/misc/bcm2835_mbox.h"
31
+#include "hw/misc/bcm2835_mphi.h"
32
#include "hw/misc/bcm2835_thermal.h"
33
#include "hw/sd/sdhci.h"
34
#include "hw/sd/bcm2835_sdhost.h"
35
@@ -XXX,XX +XXX,XX @@ typedef struct BCM2835PeripheralState {
36
qemu_irq irq, fiq;
37
38
BCM2835SystemTimerState systmr;
39
+ BCM2835MphiState mphi;
40
UnimplementedDeviceState armtmr;
41
UnimplementedDeviceState cprman;
42
UnimplementedDeviceState a2w;
43
diff --git a/include/hw/misc/bcm2835_mphi.h b/include/hw/misc/bcm2835_mphi.h
44
new file mode 100644
26
new file mode 100644
45
index XXXXXXX..XXXXXXX
27
index XXXXXXX..XXXXXXX
46
--- /dev/null
28
--- /dev/null
47
+++ b/include/hw/misc/bcm2835_mphi.h
29
+++ b/include/hw/nvram/xlnx-zynqmp-efuse.h
48
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@
49
+/*
31
+/*
50
+ * BCM2835 SOC MPHI state definitions
32
+ * Copyright (c) 2021 Xilinx Inc.
51
+ *
33
+ *
52
+ * Copyright (c) 2020 Paul Zimmerman <pauldzim@gmail.com>
34
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
35
+ * of this software and associated documentation files (the "Software"), to deal
36
+ * in the Software without restriction, including without limitation the rights
37
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
38
+ * copies of the Software, and to permit persons to whom the Software is
39
+ * furnished to do so, subject to the following conditions:
53
+ *
40
+ *
54
+ * This program is free software; you can redistribute it and/or modify
41
+ * The above copyright notice and this permission notice shall be included in
55
+ * it under the terms of the GNU General Public License as published by
42
+ * all copies or substantial portions of the Software.
56
+ * the Free Software Foundation; either version 2 of the License, or
57
+ * (at your option) any later version.
58
+ *
43
+ *
59
+ * This program is distributed in the hope that it will be useful,
44
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
60
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
45
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
61
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
62
+ * GNU General Public License for more details.
47
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
48
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
49
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
50
+ * THE SOFTWARE.
63
+ */
51
+ */
64
+
52
+#ifndef XLNX_ZYNQMP_EFUSE_H
65
+#ifndef HW_MISC_BCM2835_MPHI_H
53
+#define XLNX_ZYNQMP_EFUSE_H
66
+#define HW_MISC_BCM2835_MPHI_H
67
+
54
+
68
+#include "hw/irq.h"
55
+#include "hw/irq.h"
69
+#include "hw/sysbus.h"
56
+#include "hw/sysbus.h"
70
+
57
+#include "hw/register.h"
71
+#define MPHI_MMIO_SIZE 0x1000
58
+#include "hw/nvram/xlnx-efuse.h"
72
+
59
+
73
+typedef struct BCM2835MphiState BCM2835MphiState;
60
+#define XLNX_ZYNQMP_EFUSE_R_MAX ((0x10fc / 4) + 1)
74
+
61
+
75
+struct BCM2835MphiState {
62
+#define TYPE_XLNX_ZYNQMP_EFUSE "xlnx,zynqmp-efuse"
63
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPEFuse, XLNX_ZYNQMP_EFUSE);
64
+
65
+struct XlnxZynqMPEFuse {
76
+ SysBusDevice parent_obj;
66
+ SysBusDevice parent_obj;
77
+ qemu_irq irq;
67
+ qemu_irq irq;
78
+ MemoryRegion iomem;
68
+
79
+
69
+ XlnxEFuse *efuse;
80
+ uint32_t outdda;
70
+ uint32_t regs[XLNX_ZYNQMP_EFUSE_R_MAX];
81
+ uint32_t outddb;
71
+ RegisterInfo regs_info[XLNX_ZYNQMP_EFUSE_R_MAX];
82
+ uint32_t ctrl;
83
+ uint32_t intstat;
84
+ uint32_t swirq;
85
+};
72
+};
86
+
73
+
87
+#define TYPE_BCM2835_MPHI "bcm2835-mphi"
88
+
89
+#define BCM2835_MPHI(obj) \
90
+ OBJECT_CHECK(BCM2835MphiState, (obj), TYPE_BCM2835_MPHI)
91
+
92
+#endif
74
+#endif
93
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
75
diff --git a/hw/nvram/xlnx-zynqmp-efuse.c b/hw/nvram/xlnx-zynqmp-efuse.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/hw/arm/bcm2835_peripherals.c
96
+++ b/hw/arm/bcm2835_peripherals.c
97
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
98
OBJECT(&s->sdhci.sdbus));
99
object_property_add_const_link(OBJECT(&s->gpio), "sdbus-sdhost",
100
OBJECT(&s->sdhost.sdbus));
101
+
102
+ /* Mphi */
103
+ sysbus_init_child_obj(obj, "mphi", &s->mphi, sizeof(s->mphi),
104
+ TYPE_BCM2835_MPHI);
105
}
106
107
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
108
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
109
110
object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->gpio), "sd-bus");
111
112
+ /* Mphi */
113
+ object_property_set_bool(OBJECT(&s->mphi), true, "realized", &err);
114
+ if (err) {
115
+ error_propagate(errp, err);
116
+ return;
117
+ }
118
+
119
+ memory_region_add_subregion(&s->peri_mr, MPHI_OFFSET,
120
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mphi), 0));
121
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->mphi), 0,
122
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
123
+ INTERRUPT_HOSTPORT));
124
+
125
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
126
create_unimp(s, &s->cprman, "bcm2835-cprman", CPRMAN_OFFSET, 0x1000);
127
create_unimp(s, &s->a2w, "bcm2835-a2w", A2W_OFFSET, 0x1000);
128
diff --git a/hw/misc/bcm2835_mphi.c b/hw/misc/bcm2835_mphi.c
129
new file mode 100644
76
new file mode 100644
130
index XXXXXXX..XXXXXXX
77
index XXXXXXX..XXXXXXX
131
--- /dev/null
78
--- /dev/null
132
+++ b/hw/misc/bcm2835_mphi.c
79
+++ b/hw/nvram/xlnx-zynqmp-efuse.c
133
@@ -XXX,XX +XXX,XX @@
80
@@ -XXX,XX +XXX,XX @@
134
+/*
81
+/*
135
+ * BCM2835 SOC MPHI emulation
82
+ * QEMU model of the ZynqMP eFuse
136
+ *
83
+ *
137
+ * Very basic emulation, only providing the FIQ interrupt needed to
84
+ * Copyright (c) 2015 Xilinx Inc.
138
+ * allow the dwc-otg USB host controller driver in the Raspbian kernel
139
+ * to function.
140
+ *
85
+ *
141
+ * Copyright (c) 2020 Paul Zimmerman <pauldzim@gmail.com>
86
+ * Written by Edgar E. Iglesias <edgari@xilinx.com>
142
+ *
87
+ *
143
+ * This program is free software; you can redistribute it and/or modify
88
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
144
+ * it under the terms of the GNU General Public License as published by
89
+ * of this software and associated documentation files (the "Software"), to deal
145
+ * the Free Software Foundation; either version 2 of the License, or
90
+ * in the Software without restriction, including without limitation the rights
146
+ * (at your option) any later version.
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:
147
+ *
94
+ *
148
+ * This program is distributed in the hope that it will be useful,
95
+ * The above copyright notice and this permission notice shall be included in
149
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
96
+ * all copies or substantial portions of the Software.
150
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
97
+ *
151
+ * GNU General Public License for more details.
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.
152
+ */
105
+ */
153
+
106
+
154
+#include "qemu/osdep.h"
107
+#include "qemu/osdep.h"
108
+#include "hw/nvram/xlnx-zynqmp-efuse.h"
109
+
110
+#include "qemu/log.h"
155
+#include "qapi/error.h"
111
+#include "qapi/error.h"
156
+#include "hw/misc/bcm2835_mphi.h"
157
+#include "migration/vmstate.h"
112
+#include "migration/vmstate.h"
158
+#include "qemu/error-report.h"
113
+#include "hw/qdev-properties.h"
159
+#include "qemu/log.h"
114
+
160
+#include "qemu/main-loop.h"
115
+#ifndef ZYNQMP_EFUSE_ERR_DEBUG
161
+
116
+#define ZYNQMP_EFUSE_ERR_DEBUG 0
162
+static inline void mphi_raise_irq(BCM2835MphiState *s)
117
+#endif
163
+{
118
+
164
+ qemu_set_irq(s->irq, 1);
119
+REG32(WR_LOCK, 0x0)
165
+}
120
+ FIELD(WR_LOCK, LOCK, 0, 16)
166
+
121
+REG32(CFG, 0x4)
167
+static inline void mphi_lower_irq(BCM2835MphiState *s)
122
+ FIELD(CFG, SLVERR_ENABLE, 5, 1)
168
+{
123
+ FIELD(CFG, MARGIN_RD, 2, 2)
169
+ qemu_set_irq(s->irq, 0);
124
+ FIELD(CFG, PGM_EN, 1, 1)
170
+}
125
+ FIELD(CFG, EFUSE_CLK_SEL, 0, 1)
171
+
126
+REG32(STATUS, 0x8)
172
+static uint64_t mphi_reg_read(void *ptr, hwaddr addr, unsigned size)
127
+ FIELD(STATUS, AES_CRC_PASS, 7, 1)
173
+{
128
+ FIELD(STATUS, AES_CRC_DONE, 6, 1)
174
+ BCM2835MphiState *s = ptr;
129
+ FIELD(STATUS, CACHE_DONE, 5, 1)
175
+ uint32_t val = 0;
130
+ FIELD(STATUS, CACHE_LOAD, 4, 1)
176
+
131
+ FIELD(STATUS, EFUSE_3_TBIT, 2, 1)
177
+ switch (addr) {
132
+ FIELD(STATUS, EFUSE_2_TBIT, 1, 1)
178
+ case 0x28: /* outdda */
133
+ FIELD(STATUS, EFUSE_0_TBIT, 0, 1)
179
+ val = s->outdda;
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:
180
+ break;
478
+ break;
181
+ case 0x2c: /* outddb */
479
+ case 2 ... 3:
182
+ val = s->outddb;
480
+ bit = FIELD_DP32(bit, EFUSE_PGM_ADDR, EFUSE, page - 1);
183
+ break;
481
+ puf_prot = xlnx_efuse_get_bit(s->efuse, EFUSE_PUF_SYN_WRLK);
184
+ case 0x4c: /* ctrl */
185
+ val = s->ctrl;
186
+ val |= 1 << 17;
187
+ break;
188
+ case 0x50: /* intstat */
189
+ val = s->intstat;
190
+ break;
191
+ case 0x1f0: /* swirq_set */
192
+ val = s->swirq;
193
+ break;
194
+ case 0x1f4: /* swirq_clr */
195
+ val = s->swirq;
196
+ break;
482
+ break;
197
+ default:
483
+ default:
198
+ qemu_log_mask(LOG_UNIMP, "read from unknown register");
484
+ errmsg = "Invalid address";
199
+ break;
485
+ goto pgm_done;
200
+ }
486
+ }
201
+
487
+
202
+ return val;
488
+ if (ARRAY_FIELD_EX32(s->regs, WR_LOCK, LOCK)) {
203
+}
489
+ errmsg = "Array write-locked";
204
+
490
+ goto pgm_done;
205
+static void mphi_reg_write(void *ptr, hwaddr addr, uint64_t val, unsigned size)
491
+ }
206
+{
492
+
207
+ BCM2835MphiState *s = ptr;
493
+ if (!ARRAY_FIELD_EX32(s->regs, CFG, PGM_EN)) {
208
+ int do_irq = 0;
494
+ errmsg = "Array pgm-disabled";
209
+
495
+ goto pgm_done;
210
+ switch (addr) {
496
+ }
211
+ case 0x28: /* outdda */
497
+
212
+ s->outdda = val;
498
+ if (puf_prot) {
213
+ break;
499
+ errmsg = "PUF_HD-store write-locked";
214
+ case 0x2c: /* outddb */
500
+ goto pgm_done;
215
+ s->outddb = val;
501
+ }
216
+ if (val & (1 << 29)) {
502
+
217
+ do_irq = 1;
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
+
532
+ /*
533
+ * Grant reads only to allowed bits; reference sources:
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
+ */
539
+#define COL_MASK(L_, H_) \
540
+ ((uint32_t)MAKE_64BIT_MASK((L_), (1 + (H_) - (L_))))
541
+
542
+ static const uint32_t ary0_col_mask[] = {
543
+ /* XilSKey - XSK_ZYNQMP_EFUSEPS_TBITS_ROW */
544
+ [0] = COL_MASK(28, 31),
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;
218
+ }
603
+ }
219
+ break;
604
+ break;
220
+ case 0x4c: /* ctrl */
605
+ case 2: /* PUF helper data, adjust for skipped array 1 */
221
+ s->ctrl = val;
606
+ case 3:
222
+ if (val & (1 << 16)) {
607
+ val64 = FIELD_DP32(efuse_idx, EFUSE_RD_ADDR, EFUSE, efuse_ary - 1);
223
+ do_irq = -1;
224
+ }
225
+ break;
226
+ case 0x50: /* intstat */
227
+ s->intstat = val;
228
+ if (val & ((1 << 16) | (1 << 29))) {
229
+ do_irq = -1;
230
+ }
231
+ break;
232
+ case 0x1f0: /* swirq_set */
233
+ s->swirq |= val;
234
+ do_irq = 1;
235
+ break;
236
+ case 0x1f4: /* swirq_clr */
237
+ s->swirq &= ~val;
238
+ do_irq = -1;
239
+ break;
608
+ break;
240
+ default:
609
+ default:
241
+ qemu_log_mask(LOG_UNIMP, "write to unknown register");
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) {
242
+ return;
835
+ return;
243
+ }
836
+ }
244
+
837
+
245
+ if (do_irq > 0) {
838
+ /* Reset must not trigger some registers' writers */
246
+ mphi_raise_irq(s);
839
+ switch (reg->access->addr) {
247
+ } else if (do_irq < 0) {
840
+ case A_EFUSE_AES_CRC:
248
+ mphi_lower_irq(s);
841
+ *(uint32_t *)reg->data = reg->access->reset;
249
+ }
842
+ return;
250
+}
843
+ }
251
+
844
+
252
+static const MemoryRegionOps mphi_mmio_ops = {
845
+ register_reset(reg);
253
+ .read = mphi_reg_read,
846
+}
254
+ .write = mphi_reg_write,
847
+
255
+ .impl.min_access_size = 4,
848
+static void zynqmp_efuse_reset(DeviceState *dev)
256
+ .impl.max_access_size = 4,
849
+{
257
+ .endianness = DEVICE_LITTLE_ENDIAN,
850
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(dev);
258
+};
851
+ unsigned int i;
259
+
852
+
260
+static void mphi_reset(DeviceState *dev)
853
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
261
+{
854
+ zynqmp_efuse_register_reset(&s->regs_info[i]);
262
+ BCM2835MphiState *s = BCM2835_MPHI(dev);
855
+ }
263
+
856
+
264
+ s->outdda = 0;
857
+ zynqmp_efuse_sync_cache(s, FBIT_UNKNOWN);
265
+ s->outddb = 0;
858
+ ARRAY_FIELD_DP32(s->regs, STATUS, CACHE_DONE, 1);
266
+ s->ctrl = 0;
859
+ zynqmp_efuse_update_irq(s);
267
+ s->intstat = 0;
860
+}
268
+ s->swirq = 0;
861
+
269
+}
862
+static void zynqmp_efuse_realize(DeviceState *dev, Error **errp)
270
+
863
+{
271
+static void mphi_realize(DeviceState *dev, Error **errp)
864
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(dev);
272
+{
865
+
273
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
866
+ if (!s->efuse) {
274
+ BCM2835MphiState *s = BCM2835_MPHI(dev);
867
+ error_setg(errp, "%s.efuse: link property not connected to XLNX-EFUSE",
275
+
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);
276
+ sysbus_init_irq(sbd, &s->irq);
890
+ sysbus_init_irq(sbd, &s->irq);
277
+}
891
+}
278
+
892
+
279
+static void mphi_init(Object *obj)
893
+static const VMStateDescription vmstate_efuse = {
280
+{
894
+ .name = TYPE_XLNX_ZYNQMP_EFUSE,
281
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
282
+ BCM2835MphiState *s = BCM2835_MPHI(obj);
283
+
284
+ memory_region_init_io(&s->iomem, obj, &mphi_mmio_ops, s, "mphi", MPHI_MMIO_SIZE);
285
+ sysbus_init_mmio(sbd, &s->iomem);
286
+}
287
+
288
+const VMStateDescription vmstate_mphi_state = {
289
+ .name = "mphi",
290
+ .version_id = 1,
895
+ .version_id = 1,
291
+ .minimum_version_id = 1,
896
+ .minimum_version_id = 1,
292
+ .fields = (VMStateField[]) {
897
+ .fields = (VMStateField[]) {
293
+ VMSTATE_UINT32(outdda, BCM2835MphiState),
898
+ VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPEFuse, R_MAX),
294
+ VMSTATE_UINT32(outddb, BCM2835MphiState),
899
+ VMSTATE_END_OF_LIST(),
295
+ VMSTATE_UINT32(ctrl, BCM2835MphiState),
296
+ VMSTATE_UINT32(intstat, BCM2835MphiState),
297
+ VMSTATE_UINT32(swirq, BCM2835MphiState),
298
+ VMSTATE_END_OF_LIST()
299
+ }
900
+ }
300
+};
901
+};
301
+
902
+
302
+static void mphi_class_init(ObjectClass *klass, void *data)
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)
303
+{
912
+{
304
+ DeviceClass *dc = DEVICE_CLASS(klass);
913
+ DeviceClass *dc = DEVICE_CLASS(klass);
305
+
914
+
306
+ dc->realize = mphi_realize;
915
+ dc->reset = zynqmp_efuse_reset;
307
+ dc->reset = mphi_reset;
916
+ dc->realize = zynqmp_efuse_realize;
308
+ dc->vmsd = &vmstate_mphi_state;
917
+ dc->vmsd = &vmstate_efuse;
309
+}
918
+ device_class_set_props(dc, zynqmp_efuse_props);
310
+
919
+}
311
+static const TypeInfo bcm2835_mphi_type_info = {
920
+
312
+ .name = TYPE_BCM2835_MPHI,
921
+
922
+static const TypeInfo efuse_info = {
923
+ .name = TYPE_XLNX_ZYNQMP_EFUSE,
313
+ .parent = TYPE_SYS_BUS_DEVICE,
924
+ .parent = TYPE_SYS_BUS_DEVICE,
314
+ .instance_size = sizeof(BCM2835MphiState),
925
+ .instance_size = sizeof(XlnxZynqMPEFuse),
315
+ .instance_init = mphi_init,
926
+ .class_init = zynqmp_efuse_class_init,
316
+ .class_init = mphi_class_init,
927
+ .instance_init = zynqmp_efuse_init,
317
+};
928
+};
318
+
929
+
319
+static void bcm2835_mphi_register_types(void)
930
+static void efuse_register_types(void)
320
+{
931
+{
321
+ type_register_static(&bcm2835_mphi_type_info);
932
+ type_register_static(&efuse_info);
322
+}
933
+}
323
+
934
+
324
+type_init(bcm2835_mphi_register_types)
935
+type_init(efuse_register_types)
325
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
936
diff --git a/hw/nvram/Kconfig b/hw/nvram/Kconfig
326
index XXXXXXX..XXXXXXX 100644
937
index XXXXXXX..XXXXXXX 100644
327
--- a/hw/misc/Makefile.objs
938
--- a/hw/nvram/Kconfig
328
+++ b/hw/misc/Makefile.objs
939
+++ b/hw/nvram/Kconfig
329
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_OMAP) += omap_l4.o
940
@@ -XXX,XX +XXX,XX @@ config XLNX_EFUSE
330
common-obj-$(CONFIG_OMAP) += omap_sdrc.o
941
config XLNX_EFUSE_VERSAL
331
common-obj-$(CONFIG_OMAP) += omap_tap.o
942
bool
332
common-obj-$(CONFIG_RASPI) += bcm2835_mbox.o
943
select XLNX_EFUSE
333
+common-obj-$(CONFIG_RASPI) += bcm2835_mphi.o
944
+
334
common-obj-$(CONFIG_RASPI) += bcm2835_property.o
945
+config XLNX_EFUSE_ZYNQMP
335
common-obj-$(CONFIG_RASPI) += bcm2835_rng.o
946
+ bool
336
common-obj-$(CONFIG_RASPI) += bcm2835_thermal.o
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'))
337
--
960
--
338
2.20.1
961
2.20.1
339
962
340
963
diff view generated by jsdifflib
1
From: Paul Zimmerman <pauldzim@gmail.com>
1
From: Tong Ho <tong.ho@xilinx.com>
2
2
3
Add the dwc-hsotg (dwc2) USB host controller state definitions.
3
This device is present in Versal and ZynqMP product
4
Mostly based on hw/usb/hcd-ehci.h.
4
families to store a 256-bit encryption key.
5
5
6
Signed-off-by: Paul Zimmerman <pauldzim@gmail.com>
6
Co-authored-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Message-id: 20200520235349.21215-4-pauldzim@gmail.com
7
Co-authored-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
8
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
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
15
---
11
hw/usb/hcd-dwc2.h | 190 ++++++++++++++++++++++++++++++++++++++++++++++
16
include/hw/nvram/xlnx-bbram.h | 54 ++++
12
1 file changed, 190 insertions(+)
17
hw/nvram/xlnx-bbram.c | 545 ++++++++++++++++++++++++++++++++++
13
create mode 100644 hw/usb/hcd-dwc2.h
18
hw/nvram/Kconfig | 4 +
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
14
23
15
diff --git a/hw/usb/hcd-dwc2.h b/hw/usb/hcd-dwc2.h
24
diff --git a/include/hw/nvram/xlnx-bbram.h b/include/hw/nvram/xlnx-bbram.h
16
new file mode 100644
25
new file mode 100644
17
index XXXXXXX..XXXXXXX
26
index XXXXXXX..XXXXXXX
18
--- /dev/null
27
--- /dev/null
19
+++ b/hw/usb/hcd-dwc2.h
28
+++ b/include/hw/nvram/xlnx-bbram.h
20
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@
21
+/*
30
+/*
22
+ * dwc-hsotg (dwc2) USB host controller state definitions
31
+ * QEMU model of the Xilinx BBRAM Battery Backed RAM
23
+ *
32
+ *
24
+ * Based on hw/usb/hcd-ehci.h
33
+ * Copyright (c) 2015-2021 Xilinx Inc.
25
+ *
34
+ *
26
+ * Copyright (c) 2020 Paul Zimmerman <pauldzim@gmail.com>
35
+ * Written by Edgar E. Iglesias <edgari@xilinx.com>
27
+ *
36
+ *
28
+ * This program is free software; you can redistribute it and/or modify
37
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
29
+ * it under the terms of the GNU General Public License as published by
38
+ * of this software and associated documentation files (the "Software"), to deal
30
+ * the Free Software Foundation; either version 2 of the License, or
39
+ * in the Software without restriction, including without limitation the rights
31
+ * (at your option) any later version.
40
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
32
+ *
41
+ * copies of the Software, and to permit persons to whom the Software is
33
+ * This program is distributed in the hope that it will be useful,
42
+ * furnished to do so, subject to the following conditions:
34
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
43
+ *
35
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
44
+ * The above copyright notice and this permission notice shall be included in
36
+ * GNU General Public License for more details.
45
+ * all copies or substantial portions of the Software.
46
+ *
47
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
48
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
49
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
50
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
51
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
52
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
53
+ * THE SOFTWARE.
37
+ */
54
+ */
38
+
55
+#ifndef XLNX_BBRAM_H
39
+#ifndef HW_USB_DWC2_H
56
+#define XLNX_BBRAM_H
40
+#define HW_USB_DWC2_H
57
+
41
+
58
+#include "sysemu/block-backend.h"
42
+#include "qemu/timer.h"
59
+#include "hw/qdev-core.h"
43
+#include "hw/irq.h"
60
+#include "hw/irq.h"
44
+#include "hw/sysbus.h"
61
+#include "hw/sysbus.h"
45
+#include "hw/usb.h"
62
+#include "hw/register.h"
46
+#include "sysemu/dma.h"
63
+
47
+
64
+#define RMAX_XLNX_BBRAM ((0x4c / 4) + 1)
48
+#define DWC2_MMIO_SIZE 0x11000
65
+
49
+
66
+#define TYPE_XLNX_BBRAM "xlnx,bbram-ctrl"
50
+#define DWC2_NB_CHAN 8 /* Number of host channels */
67
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxBBRam, XLNX_BBRAM);
51
+#define DWC2_MAX_XFER_SIZE 65536 /* Max transfer size expected in HCTSIZ */
68
+
52
+
69
+struct XlnxBBRam {
53
+typedef struct DWC2Packet DWC2Packet;
70
+ SysBusDevice parent_obj;
54
+typedef struct DWC2State DWC2State;
71
+ qemu_irq irq_bbram;
55
+typedef struct DWC2Class DWC2Class;
72
+
56
+
73
+ BlockBackend *blk;
57
+enum async_state {
74
+
58
+ DWC2_ASYNC_NONE = 0,
75
+ uint32_t crc_zpads;
59
+ DWC2_ASYNC_INITIALIZED,
76
+ bool bbram8_wo;
60
+ DWC2_ASYNC_INFLIGHT,
77
+ bool blk_ro;
61
+ DWC2_ASYNC_FINISHED,
78
+
79
+ uint32_t regs[RMAX_XLNX_BBRAM];
80
+ RegisterInfo regs_info[RMAX_XLNX_BBRAM];
62
+};
81
+};
63
+
82
+
64
+struct DWC2Packet {
83
+#endif
65
+ USBPacket packet;
84
diff --git a/hw/nvram/xlnx-bbram.c b/hw/nvram/xlnx-bbram.c
66
+ uint32_t devadr;
85
new file mode 100644
67
+ uint32_t epnum;
86
index XXXXXXX..XXXXXXX
68
+ uint32_t epdir;
87
--- /dev/null
69
+ uint32_t mps;
88
+++ b/hw/nvram/xlnx-bbram.c
70
+ uint32_t pid;
89
@@ -XXX,XX +XXX,XX @@
71
+ uint32_t index;
90
+/*
72
+ uint32_t pcnt;
91
+ * QEMU model of the Xilinx BBRAM Battery Backed RAM
73
+ uint32_t len;
92
+ *
74
+ int32_t async;
93
+ * Copyright (c) 2014-2021 Xilinx Inc.
75
+ bool small;
94
+ *
76
+ bool needs_service;
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;
198
+ }
199
+
200
+ s->blk_ro = !blk_supports_write_perm(s->blk);
201
+ if (!s->blk_ro) {
202
+ int rc;
203
+
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
+ }
77
+};
506
+};
78
+
507
+
79
+struct DWC2State {
508
+static void bbram_ctrl_reset(DeviceState *dev)
80
+ /*< private >*/
509
+{
81
+ SysBusDevice parent_obj;
510
+ XlnxBBRam *s = XLNX_BBRAM(dev);
82
+
511
+ unsigned int i;
83
+ /*< public >*/
512
+
84
+ USBBus bus;
513
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
85
+ qemu_irq irq;
514
+ if (i < R_BBRAM_0 || i > R_BBRAM_8) {
86
+ MemoryRegion *dma_mr;
515
+ register_reset(&s->regs_info[i]);
87
+ AddressSpace dma_as;
516
+ }
88
+ MemoryRegion container;
517
+ }
89
+ MemoryRegion hsotg;
518
+
90
+ MemoryRegion fifos;
519
+ bbram_update_irq(s);
91
+
520
+}
92
+ union {
521
+
93
+#define DWC2_GLBREG_SIZE 0x70
522
+static const MemoryRegionOps bbram_ctrl_ops = {
94
+ uint32_t glbreg[DWC2_GLBREG_SIZE / sizeof(uint32_t)];
523
+ .read = register_read_memory,
95
+ struct {
524
+ .write = register_write_memory,
96
+ uint32_t gotgctl; /* 00 */
525
+ .endianness = DEVICE_LITTLE_ENDIAN,
97
+ uint32_t gotgint; /* 04 */
526
+ .valid = {
98
+ uint32_t gahbcfg; /* 08 */
527
+ .min_access_size = 4,
99
+ uint32_t gusbcfg; /* 0c */
528
+ .max_access_size = 4,
100
+ uint32_t grstctl; /* 10 */
529
+ },
101
+ uint32_t gintsts; /* 14 */
102
+ uint32_t gintmsk; /* 18 */
103
+ uint32_t grxstsr; /* 1c */
104
+ uint32_t grxstsp; /* 20 */
105
+ uint32_t grxfsiz; /* 24 */
106
+ uint32_t gnptxfsiz; /* 28 */
107
+ uint32_t gnptxsts; /* 2c */
108
+ uint32_t gi2cctl; /* 30 */
109
+ uint32_t gpvndctl; /* 34 */
110
+ uint32_t ggpio; /* 38 */
111
+ uint32_t guid; /* 3c */
112
+ uint32_t gsnpsid; /* 40 */
113
+ uint32_t ghwcfg1; /* 44 */
114
+ uint32_t ghwcfg2; /* 48 */
115
+ uint32_t ghwcfg3; /* 4c */
116
+ uint32_t ghwcfg4; /* 50 */
117
+ uint32_t glpmcfg; /* 54 */
118
+ uint32_t gpwrdn; /* 58 */
119
+ uint32_t gdfifocfg; /* 5c */
120
+ uint32_t gadpctl; /* 60 */
121
+ uint32_t grefclk; /* 64 */
122
+ uint32_t gintmsk2; /* 68 */
123
+ uint32_t gintsts2; /* 6c */
124
+ };
125
+ };
126
+
127
+ union {
128
+#define DWC2_FSZREG_SIZE 0x04
129
+ uint32_t fszreg[DWC2_FSZREG_SIZE / sizeof(uint32_t)];
130
+ struct {
131
+ uint32_t hptxfsiz; /* 100 */
132
+ };
133
+ };
134
+
135
+ union {
136
+#define DWC2_HREG0_SIZE 0x44
137
+ uint32_t hreg0[DWC2_HREG0_SIZE / sizeof(uint32_t)];
138
+ struct {
139
+ uint32_t hcfg; /* 400 */
140
+ uint32_t hfir; /* 404 */
141
+ uint32_t hfnum; /* 408 */
142
+ uint32_t rsvd0; /* 40c */
143
+ uint32_t hptxsts; /* 410 */
144
+ uint32_t haint; /* 414 */
145
+ uint32_t haintmsk; /* 418 */
146
+ uint32_t hflbaddr; /* 41c */
147
+ uint32_t rsvd1[8]; /* 420-43c */
148
+ uint32_t hprt0; /* 440 */
149
+ };
150
+ };
151
+
152
+#define DWC2_HREG1_SIZE (0x20 * DWC2_NB_CHAN)
153
+ uint32_t hreg1[DWC2_HREG1_SIZE / sizeof(uint32_t)];
154
+
155
+#define hcchar(_ch) hreg1[((_ch) << 3) + 0] /* 500, 520, ... */
156
+#define hcsplt(_ch) hreg1[((_ch) << 3) + 1] /* 504, 524, ... */
157
+#define hcint(_ch) hreg1[((_ch) << 3) + 2] /* 508, 528, ... */
158
+#define hcintmsk(_ch) hreg1[((_ch) << 3) + 3] /* 50c, 52c, ... */
159
+#define hctsiz(_ch) hreg1[((_ch) << 3) + 4] /* 510, 530, ... */
160
+#define hcdma(_ch) hreg1[((_ch) << 3) + 5] /* 514, 534, ... */
161
+#define hcdmab(_ch) hreg1[((_ch) << 3) + 7] /* 51c, 53c, ... */
162
+
163
+ union {
164
+#define DWC2_PCGREG_SIZE 0x08
165
+ uint32_t pcgreg[DWC2_PCGREG_SIZE / sizeof(uint32_t)];
166
+ struct {
167
+ uint32_t pcgctl; /* e00 */
168
+ uint32_t pcgcctl1; /* e04 */
169
+ };
170
+ };
171
+
172
+ /* TODO - implement FIFO registers for slave mode */
173
+#define DWC2_HFIFO_SIZE (0x1000 * DWC2_NB_CHAN)
174
+
175
+ /*
176
+ * Internal state
177
+ */
178
+ QEMUTimer *eof_timer;
179
+ QEMUTimer *frame_timer;
180
+ QEMUBH *async_bh;
181
+ int64_t sof_time;
182
+ int64_t usb_frame_time;
183
+ int64_t usb_bit_time;
184
+ uint32_t usb_version;
185
+ uint16_t frame_number;
186
+ uint16_t fi;
187
+ uint16_t next_chan;
188
+ bool working;
189
+ USBPort uport;
190
+ DWC2Packet packet[DWC2_NB_CHAN]; /* one packet per chan */
191
+ uint8_t usb_buf[DWC2_NB_CHAN][DWC2_MAX_XFER_SIZE]; /* one buffer per chan */
192
+};
530
+};
193
+
531
+
194
+struct DWC2Class {
532
+static void bbram_ctrl_realize(DeviceState *dev, Error **errp)
195
+ /*< private >*/
533
+{
196
+ SysBusDeviceClass parent_class;
534
+ XlnxBBRam *s = XLNX_BBRAM(dev);
197
+ ResettablePhases parent_phases;
535
+
198
+
536
+ if (s->crc_zpads) {
199
+ /*< public >*/
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,
200
+};
593
+};
201
+
594
+
202
+#define TYPE_DWC2_USB "dwc2-usb"
595
+static const VMStateDescription vmstate_bbram_ctrl = {
203
+#define DWC2_USB(obj) \
596
+ .name = TYPE_XLNX_BBRAM,
204
+ OBJECT_CHECK(DWC2State, (obj), TYPE_DWC2_USB)
597
+ .version_id = 1,
205
+#define DWC2_CLASS(klass) \
598
+ .minimum_version_id = 1,
206
+ OBJECT_CLASS_CHECK(DWC2Class, (klass), TYPE_DWC2_USB)
599
+ .fields = (VMStateField[]) {
207
+#define DWC2_GET_CLASS(obj) \
600
+ VMSTATE_UINT32_ARRAY(regs, XlnxBBRam, R_MAX),
208
+ OBJECT_GET_CLASS(DWC2Class, (obj), TYPE_DWC2_USB)
601
+ VMSTATE_END_OF_LIST(),
209
+
602
+ }
210
+#endif
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'))
211
--
658
--
212
2.20.1
659
2.20.1
213
660
214
661
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Tong Ho <tong.ho@xilinx.com>
2
2
3
Do not yet convert the helpers to loop over opr_sz, but the
3
Connect the support for Versal Battery-Backed RAM (BBRAM)
4
descriptor allows the vector tail to be cleared. Which fixes
5
an existing bug vs SVE.
6
4
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
The command argument:
8
Message-id: 20200514212831.31248-4-richard.henderson@linaro.org
6
-drive if=pflash,index=0,...
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
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
19
---
12
target/arm/helper.h | 15 +++++++-----
20
include/hw/arm/xlnx-versal.h | 5 +++++
13
target/arm/crypto_helper.c | 37 +++++++++++++++++++++++-----
21
hw/arm/xlnx-versal-virt.c | 36 ++++++++++++++++++++++++++++++++++++
14
target/arm/translate-a64.c | 50 ++++++++++++--------------------------
22
hw/arm/xlnx-versal.c | 18 ++++++++++++++++++
15
3 files changed, 55 insertions(+), 47 deletions(-)
23
hw/arm/Kconfig | 1 +
24
4 files changed, 60 insertions(+)
16
25
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
26
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.h
28
--- a/include/hw/arm/xlnx-versal.h
20
+++ b/target/arm/helper.h
29
+++ b/include/hw/arm/xlnx-versal.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(crypto_sha256h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
30
@@ -XXX,XX +XXX,XX @@
22
DEF_HELPER_FLAGS_2(crypto_sha256su0, TCG_CALL_NO_RWG, void, ptr, ptr)
31
#include "qom/object.h"
23
DEF_HELPER_FLAGS_3(crypto_sha256su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
32
#include "hw/usb/xlnx-usb-subsystem.h"
24
33
#include "hw/misc/xlnx-versal-xramc.h"
25
-DEF_HELPER_FLAGS_3(crypto_sha512h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
34
+#include "hw/nvram/xlnx-bbram.h"
26
-DEF_HELPER_FLAGS_3(crypto_sha512h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
35
27
-DEF_HELPER_FLAGS_2(crypto_sha512su0, TCG_CALL_NO_RWG, void, ptr, ptr)
36
#define TYPE_XLNX_VERSAL "xlnx-versal"
28
-DEF_HELPER_FLAGS_3(crypto_sha512su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
37
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
29
+DEF_HELPER_FLAGS_4(crypto_sha512h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
38
@@ -XXX,XX +XXX,XX @@ struct Versal {
30
+DEF_HELPER_FLAGS_4(crypto_sha512h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
39
} iou;
31
+DEF_HELPER_FLAGS_3(crypto_sha512su0, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
40
32
+DEF_HELPER_FLAGS_4(crypto_sha512su1, TCG_CALL_NO_RWG,
41
XlnxZynqMPRTC rtc;
33
+ void, ptr, ptr, ptr, i32)
42
+ XlnxBBRam bbram;
34
43
} pmc;
35
DEF_HELPER_FLAGS_5(crypto_sm3tt, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, i32)
44
36
-DEF_HELPER_FLAGS_3(crypto_sm3partw1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
45
struct {
37
-DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
46
@@ -XXX,XX +XXX,XX @@ struct Versal {
38
+DEF_HELPER_FLAGS_4(crypto_sm3partw1, TCG_CALL_NO_RWG,
47
#define VERSAL_GEM1_WAKE_IRQ_0 59
39
+ void, ptr, ptr, ptr, i32)
48
#define VERSAL_ADMA_IRQ_0 60
40
+DEF_HELPER_FLAGS_4(crypto_sm3partw2, TCG_CALL_NO_RWG,
49
#define VERSAL_XRAM_IRQ_0 79
41
+ void, ptr, ptr, ptr, i32)
50
+#define VERSAL_BBRAM_APB_IRQ_0 121
42
51
#define VERSAL_RTC_APB_ERR_IRQ 121
43
DEF_HELPER_FLAGS_4(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
52
#define VERSAL_SD0_IRQ_0 126
44
DEF_HELPER_FLAGS_4(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
53
#define VERSAL_RTC_ALARM_IRQ 142
45
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
54
@@ -XXX,XX +XXX,XX @@ struct Versal {
55
56
#define MM_PMC_SD0 0xf1040000U
57
#define MM_PMC_SD0_SIZE 0x10000
58
+#define MM_PMC_BBRAM_CTRL 0xf11f0000
59
+#define MM_PMC_BBRAM_CTRL_SIZE 0x00050
60
#define MM_PMC_CRP 0xf1260000U
61
#define MM_PMC_CRP_SIZE 0x10000
62
#define MM_PMC_RTC 0xf12a0000
63
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
46
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/crypto_helper.c
65
--- a/hw/arm/xlnx-versal-virt.c
48
+++ b/target/arm/crypto_helper.c
66
+++ b/hw/arm/xlnx-versal-virt.c
49
@@ -XXX,XX +XXX,XX @@ union CRYPTO_STATE {
67
@@ -XXX,XX +XXX,XX @@ static void fdt_add_rtc_node(VersalVirt *s)
50
#define CR_ST_WORD(state, i) (state.words[i])
68
g_free(name);
51
#endif
69
}
52
70
53
+/*
71
+static void fdt_add_bbram_node(VersalVirt *s)
54
+ * The caller has not been converted to full gvec, and so only
55
+ * modifies the low 16 bytes of the vector register.
56
+ */
57
+static void clear_tail_16(void *vd, uint32_t desc)
58
+{
72
+{
59
+ int opr_sz = simd_oprsz(desc);
73
+ const char compat[] = TYPE_XLNX_BBRAM;
60
+ int max_sz = simd_maxsz(desc);
74
+ const char interrupt_names[] = "bbram-error";
75
+ char *name = g_strdup_printf("/bbram@%x", MM_PMC_BBRAM_CTRL);
61
+
76
+
62
+ assert(opr_sz == 16);
77
+ qemu_fdt_add_subnode(s->fdt, name);
63
+ clear_tail(vd, opr_sz, max_sz);
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);
64
+}
89
+}
65
+
90
+
66
static void do_crypto_aese(uint64_t *rd, uint64_t *rn,
91
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
67
uint64_t *rm, bool decrypt)
68
{
92
{
69
@@ -XXX,XX +XXX,XX @@ static uint64_t s1_512(uint64_t x)
93
Error *err = NULL;
70
return ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6);
94
@@ -XXX,XX +XXX,XX @@ static void create_virtio_regions(VersalVirt *s)
71
}
72
73
-void HELPER(crypto_sha512h)(void *vd, void *vn, void *vm)
74
+void HELPER(crypto_sha512h)(void *vd, void *vn, void *vm, uint32_t desc)
75
{
76
uint64_t *rd = vd;
77
uint64_t *rn = vn;
78
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha512h)(void *vd, void *vn, void *vm)
79
80
rd[0] = d0;
81
rd[1] = d1;
82
+
83
+ clear_tail_16(vd, desc);
84
}
85
86
-void HELPER(crypto_sha512h2)(void *vd, void *vn, void *vm)
87
+void HELPER(crypto_sha512h2)(void *vd, void *vn, void *vm, uint32_t desc)
88
{
89
uint64_t *rd = vd;
90
uint64_t *rn = vn;
91
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha512h2)(void *vd, void *vn, void *vm)
92
93
rd[0] = d0;
94
rd[1] = d1;
95
+
96
+ clear_tail_16(vd, desc);
97
}
98
99
-void HELPER(crypto_sha512su0)(void *vd, void *vn)
100
+void HELPER(crypto_sha512su0)(void *vd, void *vn, uint32_t desc)
101
{
102
uint64_t *rd = vd;
103
uint64_t *rn = vn;
104
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha512su0)(void *vd, void *vn)
105
106
rd[0] = d0;
107
rd[1] = d1;
108
+
109
+ clear_tail_16(vd, desc);
110
}
111
112
-void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm)
113
+void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm, uint32_t desc)
114
{
115
uint64_t *rd = vd;
116
uint64_t *rn = vn;
117
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm)
118
119
rd[0] += s1_512(rn[0]) + rm[0];
120
rd[1] += s1_512(rn[1]) + rm[1];
121
+
122
+ clear_tail_16(vd, desc);
123
}
124
125
-void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm)
126
+void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm, uint32_t desc)
127
{
128
uint64_t *rd = vd;
129
uint64_t *rn = vn;
130
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm)
131
132
rd[0] = d.l[0];
133
rd[1] = d.l[1];
134
+
135
+ clear_tail_16(vd, desc);
136
}
137
138
-void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm)
139
+void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm, uint32_t desc)
140
{
141
uint64_t *rd = vd;
142
uint64_t *rn = vn;
143
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm)
144
145
rd[0] = d.l[0];
146
rd[1] = d.l[1];
147
+
148
+ clear_tail_16(vd, desc);
149
}
150
151
void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
152
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/target/arm/translate-a64.c
155
+++ b/target/arm/translate-a64.c
156
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
157
int rn = extract32(insn, 5, 5);
158
int rd = extract32(insn, 0, 5);
159
bool feature;
160
- CryptoThreeOpFn *genfn = NULL;
161
gen_helper_gvec_3 *oolfn = NULL;
162
GVecGen3Fn *gvecfn = NULL;
163
164
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
165
switch (opcode) {
166
case 0: /* SHA512H */
167
feature = dc_isar_feature(aa64_sha512, s);
168
- genfn = gen_helper_crypto_sha512h;
169
+ oolfn = gen_helper_crypto_sha512h;
170
break;
171
case 1: /* SHA512H2 */
172
feature = dc_isar_feature(aa64_sha512, s);
173
- genfn = gen_helper_crypto_sha512h2;
174
+ oolfn = gen_helper_crypto_sha512h2;
175
break;
176
case 2: /* SHA512SU1 */
177
feature = dc_isar_feature(aa64_sha512, s);
178
- genfn = gen_helper_crypto_sha512su1;
179
+ oolfn = gen_helper_crypto_sha512su1;
180
break;
181
case 3: /* RAX1 */
182
feature = dc_isar_feature(aa64_sha3, s);
183
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
184
switch (opcode) {
185
case 0: /* SM3PARTW1 */
186
feature = dc_isar_feature(aa64_sm3, s);
187
- genfn = gen_helper_crypto_sm3partw1;
188
+ oolfn = gen_helper_crypto_sm3partw1;
189
break;
190
case 1: /* SM3PARTW2 */
191
feature = dc_isar_feature(aa64_sm3, s);
192
- genfn = gen_helper_crypto_sm3partw2;
193
+ oolfn = gen_helper_crypto_sm3partw2;
194
break;
195
case 2: /* SM4EKEY */
196
feature = dc_isar_feature(aa64_sm4, s);
197
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
198
199
if (oolfn) {
200
gen_gvec_op3_ool(s, true, rd, rn, rm, 0, oolfn);
201
- } else if (gvecfn) {
202
- gen_gvec_fn3(s, true, rd, rn, rm, gvecfn, MO_64);
203
} else {
204
- TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
205
-
206
- tcg_rd_ptr = vec_full_reg_ptr(s, rd);
207
- tcg_rn_ptr = vec_full_reg_ptr(s, rn);
208
- tcg_rm_ptr = vec_full_reg_ptr(s, rm);
209
-
210
- genfn(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr);
211
-
212
- tcg_temp_free_ptr(tcg_rd_ptr);
213
- tcg_temp_free_ptr(tcg_rn_ptr);
214
- tcg_temp_free_ptr(tcg_rm_ptr);
215
+ gen_gvec_fn3(s, true, rd, rn, rm, gvecfn, MO_64);
216
}
95
}
217
}
96
}
218
97
219
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
98
+static void bbram_attach_drive(XlnxBBRam *dev)
220
int opcode = extract32(insn, 10, 2);
99
+{
221
int rn = extract32(insn, 5, 5);
100
+ DriveInfo *dinfo;
222
int rd = extract32(insn, 0, 5);
101
+ BlockBackend *blk;
223
- TCGv_ptr tcg_rd_ptr, tcg_rn_ptr;
102
+
224
bool feature;
103
+ dinfo = drive_get_by_index(IF_PFLASH, 0);
225
- CryptoTwoOpFn *genfn;
104
+ blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
226
- gen_helper_gvec_3 *oolfn = NULL;
105
+ if (blk) {
227
106
+ qdev_prop_set_drive(DEVICE(dev), "drive", blk);
228
switch (opcode) {
107
+ }
229
case 0: /* SHA512SU0 */
108
+}
230
feature = dc_isar_feature(aa64_sha512, s);
109
+
231
- genfn = gen_helper_crypto_sha512su0;
110
static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
232
break;
111
{
233
case 1: /* SM4E */
112
BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
234
feature = dc_isar_feature(aa64_sm4, s);
113
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
235
- oolfn = gen_helper_crypto_sm4e;
114
fdt_add_usb_xhci_nodes(s);
236
break;
115
fdt_add_sd_nodes(s);
237
default:
116
fdt_add_rtc_node(s);
238
unallocated_encoding(s);
117
+ fdt_add_bbram_node(s);
239
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
118
fdt_add_cpu_nodes(s, psci_conduit);
240
return;
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)
241
}
136
}
242
243
- if (oolfn) {
244
- gen_gvec_op3_ool(s, true, rd, rd, rn, 0, oolfn);
245
- return;
246
+ switch (opcode) {
247
+ case 0: /* SHA512SU0 */
248
+ gen_gvec_op2_ool(s, true, rd, rn, 0, gen_helper_crypto_sha512su0);
249
+ break;
250
+ case 1: /* SM4E */
251
+ gen_gvec_op3_ool(s, true, rd, rd, rn, 0, gen_helper_crypto_sm4e);
252
+ break;
253
+ default:
254
+ g_assert_not_reached();
255
}
256
-
257
- tcg_rd_ptr = vec_full_reg_ptr(s, rd);
258
- tcg_rn_ptr = vec_full_reg_ptr(s, rn);
259
-
260
- genfn(tcg_rd_ptr, tcg_rn_ptr);
261
-
262
- tcg_temp_free_ptr(tcg_rd_ptr);
263
- tcg_temp_free_ptr(tcg_rn_ptr);
264
}
137
}
265
138
266
/* Crypto four-register
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
267
--
179
--
268
2.20.1
180
2.20.1
269
181
270
182
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Tong Ho <tong.ho@xilinx.com>
2
2
3
With this conversion, we will be able to use the same helpers
3
Connect the support for Versal eFUSE one-time field-programmable
4
with sve. This also fixes a bug in which we failed to clear
4
bit array.
5
the high bits of the SVE register after an AdvSIMD operation.
5
6
6
The command argument:
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
-drive if=pflash,index=1,...
8
Message-id: 20200514212831.31248-3-richard.henderson@linaro.org
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
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
21
---
12
target/arm/helper.h | 2 ++
22
include/hw/arm/xlnx-versal.h | 10 +++++++
13
target/arm/translate-a64.h | 3 ++
23
hw/arm/xlnx-versal-virt.c | 52 ++++++++++++++++++++++++++++++++++++
14
target/arm/crypto_helper.c | 11 +++++++
24
hw/arm/xlnx-versal.c | 39 +++++++++++++++++++++++++++
15
target/arm/translate-a64.c | 59 ++++++++++++++++++++------------------
25
hw/arm/Kconfig | 1 +
16
4 files changed, 47 insertions(+), 28 deletions(-)
26
4 files changed, 102 insertions(+)
17
27
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
28
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
19
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.h
30
--- a/include/hw/arm/xlnx-versal.h
21
+++ b/target/arm/helper.h
31
+++ b/include/hw/arm/xlnx-versal.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
32
@@ -XXX,XX +XXX,XX @@
23
DEF_HELPER_FLAGS_4(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
#include "hw/usb/xlnx-usb-subsystem.h"
24
DEF_HELPER_FLAGS_4(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
#include "hw/misc/xlnx-versal-xramc.h"
25
35
#include "hw/nvram/xlnx-bbram.h"
26
+DEF_HELPER_FLAGS_4(crypto_rax1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
36
+#include "hw/nvram/xlnx-versal-efuse.h"
27
+
37
28
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
38
#define TYPE_XLNX_VERSAL "xlnx-versal"
29
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
39
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
30
40
@@ -XXX,XX +XXX,XX @@ struct Versal {
31
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
41
32
index XXXXXXX..XXXXXXX 100644
42
XlnxZynqMPRTC rtc;
33
--- a/target/arm/translate-a64.h
43
XlnxBBRam bbram;
34
+++ b/target/arm/translate-a64.h
44
+ XlnxEFuse efuse;
35
@@ -XXX,XX +XXX,XX @@ static inline int vec_full_reg_size(DisasContext *s)
45
+ XlnxVersalEFuseCtrl efuse_ctrl;
36
46
+ XlnxVersalEFuseCache efuse_cache;
37
bool disas_sve(DisasContext *, uint32_t);
47
} pmc;
38
48
39
+void gen_gvec_rax1(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
49
struct {
40
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
50
@@ -XXX,XX +XXX,XX @@ struct Versal {
41
+
51
#define VERSAL_BBRAM_APB_IRQ_0 121
42
#endif /* TARGET_ARM_TRANSLATE_A64_H */
52
#define VERSAL_RTC_APB_ERR_IRQ 121
43
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
53
#define VERSAL_SD0_IRQ_0 126
44
index XXXXXXX..XXXXXXX 100644
54
+#define VERSAL_EFUSE_IRQ 139
45
--- a/target/arm/crypto_helper.c
55
#define VERSAL_RTC_ALARM_IRQ 142
46
+++ b/target/arm/crypto_helper.c
56
#define VERSAL_RTC_SECONDS_IRQ 143
47
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm, uint32_t desc)
57
48
}
58
@@ -XXX,XX +XXX,XX @@ struct Versal {
49
clear_tail(vd, opr_sz, simd_maxsz(desc));
59
#define MM_PMC_SD0_SIZE 0x10000
60
#define MM_PMC_BBRAM_CTRL 0xf11f0000
61
#define MM_PMC_BBRAM_CTRL_SIZE 0x00050
62
+#define MM_PMC_EFUSE_CTRL 0xf1240000
63
+#define MM_PMC_EFUSE_CTRL_SIZE 0x00104
64
+#define MM_PMC_EFUSE_CACHE 0xf1250000
65
+#define MM_PMC_EFUSE_CACHE_SIZE 0x00C00
66
+
67
#define MM_PMC_CRP 0xf1260000U
68
#define MM_PMC_CRP_SIZE 0x10000
69
#define MM_PMC_RTC 0xf12a0000
70
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/hw/arm/xlnx-versal-virt.c
73
+++ b/hw/arm/xlnx-versal-virt.c
74
@@ -XXX,XX +XXX,XX @@ static void fdt_add_bbram_node(VersalVirt *s)
75
g_free(name);
50
}
76
}
51
+
77
52
+void HELPER(crypto_rax1)(void *vd, void *vn, void *vm, uint32_t desc)
78
+static void fdt_add_efuse_ctrl_node(VersalVirt *s)
53
+{
79
+{
54
+ intptr_t i, opr_sz = simd_oprsz(desc);
80
+ const char compat[] = TYPE_XLNX_VERSAL_EFUSE_CTRL;
55
+ uint64_t *d = vd, *n = vn, *m = vm;
81
+ const char interrupt_names[] = "pmc_efuse";
56
+
82
+ char *name = g_strdup_printf("/pmc_efuse@%x", MM_PMC_EFUSE_CTRL);
57
+ for (i = 0; i < opr_sz / 8; ++i) {
83
+
58
+ d[i] = n[i] ^ rol64(m[i], 1);
84
+ qemu_fdt_add_subnode(s->fdt, name);
59
+ }
85
+
60
+ clear_tail(vd, opr_sz, simd_maxsz(desc));
86
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
61
+}
87
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_EFUSE_IRQ,
62
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
88
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
63
index XXXXXXX..XXXXXXX 100644
89
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
64
--- a/target/arm/translate-a64.c
90
+ interrupt_names, sizeof(interrupt_names));
65
+++ b/target/arm/translate-a64.c
91
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
66
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
92
+ 2, MM_PMC_EFUSE_CTRL,
67
tcg_temp_free_ptr(tcg_rn_ptr);
93
+ 2, MM_PMC_EFUSE_CTRL_SIZE);
68
}
94
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
69
95
+ g_free(name);
70
+static void gen_rax1_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m)
96
+}
71
+{
97
+
72
+ tcg_gen_rotli_i64(d, m, 1);
98
+static void fdt_add_efuse_cache_node(VersalVirt *s)
73
+ tcg_gen_xor_i64(d, d, n);
99
+{
74
+}
100
+ const char compat[] = TYPE_XLNX_VERSAL_EFUSE_CACHE;
75
+
101
+ char *name = g_strdup_printf("/xlnx_pmc_efuse_cache@%x",
76
+static void gen_rax1_vec(unsigned vece, TCGv_vec d, TCGv_vec n, TCGv_vec m)
102
+ MM_PMC_EFUSE_CACHE);
77
+{
103
+
78
+ tcg_gen_rotli_vec(vece, d, m, 1);
104
+ qemu_fdt_add_subnode(s->fdt, name);
79
+ tcg_gen_xor_vec(vece, d, d, n);
105
+
80
+}
106
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
81
+
107
+ 2, MM_PMC_EFUSE_CACHE,
82
+void gen_gvec_rax1(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
108
+ 2, MM_PMC_EFUSE_CACHE_SIZE);
83
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
109
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
84
+{
110
+ g_free(name);
85
+ static const TCGOpcode vecop_list[] = { INDEX_op_rotli_vec, 0 };
111
+}
86
+ static const GVecGen3 op = {
112
+
87
+ .fni8 = gen_rax1_i64,
113
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
88
+ .fniv = gen_rax1_vec,
114
{
89
+ .opt_opc = vecop_list,
115
Error *err = NULL;
90
+ .fno = gen_helper_crypto_rax1,
116
@@ -XXX,XX +XXX,XX @@ static void bbram_attach_drive(XlnxBBRam *dev)
91
+ .vece = MO_64,
92
+ };
93
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &op);
94
+}
95
+
96
/* Crypto three-reg SHA512
97
* 31 21 20 16 15 14 13 12 11 10 9 5 4 0
98
* +-----------------------+------+---+---+-----+--------+------+------+
99
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
100
bool feature;
101
CryptoThreeOpFn *genfn = NULL;
102
gen_helper_gvec_3 *oolfn = NULL;
103
+ GVecGen3Fn *gvecfn = NULL;
104
105
if (o == 0) {
106
switch (opcode) {
107
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
108
break;
109
case 3: /* RAX1 */
110
feature = dc_isar_feature(aa64_sha3, s);
111
- genfn = NULL;
112
+ gvecfn = gen_gvec_rax1;
113
break;
114
default:
115
g_assert_not_reached();
116
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
117
118
if (oolfn) {
119
gen_gvec_op3_ool(s, true, rd, rn, rm, 0, oolfn);
120
- return;
121
- }
122
-
123
- if (genfn) {
124
+ } else if (gvecfn) {
125
+ gen_gvec_fn3(s, true, rd, rn, rm, gvecfn, MO_64);
126
+ } else {
127
TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
128
129
tcg_rd_ptr = vec_full_reg_ptr(s, rd);
130
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
131
tcg_temp_free_ptr(tcg_rd_ptr);
132
tcg_temp_free_ptr(tcg_rn_ptr);
133
tcg_temp_free_ptr(tcg_rm_ptr);
134
- } else {
135
- TCGv_i64 tcg_op1, tcg_op2, tcg_res[2];
136
- int pass;
137
-
138
- tcg_op1 = tcg_temp_new_i64();
139
- tcg_op2 = tcg_temp_new_i64();
140
- tcg_res[0] = tcg_temp_new_i64();
141
- tcg_res[1] = tcg_temp_new_i64();
142
-
143
- for (pass = 0; pass < 2; pass++) {
144
- read_vec_element(s, tcg_op1, rn, pass, MO_64);
145
- read_vec_element(s, tcg_op2, rm, pass, MO_64);
146
-
147
- tcg_gen_rotli_i64(tcg_res[pass], tcg_op2, 1);
148
- tcg_gen_xor_i64(tcg_res[pass], tcg_res[pass], tcg_op1);
149
- }
150
- write_vec_element(s, tcg_res[0], rd, 0, MO_64);
151
- write_vec_element(s, tcg_res[1], rd, 1, MO_64);
152
-
153
- tcg_temp_free_i64(tcg_op1);
154
- tcg_temp_free_i64(tcg_op2);
155
- tcg_temp_free_i64(tcg_res[0]);
156
- tcg_temp_free_i64(tcg_res[1]);
157
}
117
}
158
}
118
}
159
119
120
+static void efuse_attach_drive(XlnxEFuse *dev)
121
+{
122
+ DriveInfo *dinfo;
123
+ BlockBackend *blk;
124
+
125
+ dinfo = drive_get_by_index(IF_PFLASH, 1);
126
+ blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
127
+ if (blk) {
128
+ qdev_prop_set_drive(DEVICE(dev), "drive", blk);
129
+ }
130
+}
131
+
132
static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
133
{
134
BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
135
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
136
fdt_add_sd_nodes(s);
137
fdt_add_rtc_node(s);
138
fdt_add_bbram_node(s);
139
+ fdt_add_efuse_ctrl_node(s);
140
+ fdt_add_efuse_cache_node(s);
141
fdt_add_cpu_nodes(s, psci_conduit);
142
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
143
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
144
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
145
/* Attach bbram backend, if given */
146
bbram_attach_drive(&s->soc.pmc.bbram);
147
148
+ /* Attach efuse backend, if given */
149
+ efuse_attach_drive(&s->soc.pmc.efuse);
150
+
151
/* Plugin SD cards. */
152
for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
153
sd_plugin_card(&s->soc.pmc.iou.sd[i], drive_get_next(IF_SD));
154
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
155
index XXXXXXX..XXXXXXX 100644
156
--- a/hw/arm/xlnx-versal.c
157
+++ b/hw/arm/xlnx-versal.c
158
@@ -XXX,XX +XXX,XX @@ static void versal_create_bbram(Versal *s, qemu_irq *pic)
159
sysbus_connect_irq(sbd, 0, pic[VERSAL_BBRAM_APB_IRQ_0]);
160
}
161
162
+static void versal_realize_efuse_part(Versal *s, Object *dev, hwaddr base)
163
+{
164
+ SysBusDevice *part = SYS_BUS_DEVICE(dev);
165
+
166
+ object_property_set_link(OBJECT(part), "efuse",
167
+ OBJECT(&s->pmc.efuse), &error_abort);
168
+
169
+ sysbus_realize(part, &error_abort);
170
+ memory_region_add_subregion(&s->mr_ps, base,
171
+ sysbus_mmio_get_region(part, 0));
172
+}
173
+
174
+static void versal_create_efuse(Versal *s, qemu_irq *pic)
175
+{
176
+ Object *bits = OBJECT(&s->pmc.efuse);
177
+ Object *ctrl = OBJECT(&s->pmc.efuse_ctrl);
178
+ Object *cache = OBJECT(&s->pmc.efuse_cache);
179
+
180
+ object_initialize_child(OBJECT(s), "efuse-ctrl", &s->pmc.efuse_ctrl,
181
+ TYPE_XLNX_VERSAL_EFUSE_CTRL);
182
+
183
+ object_initialize_child(OBJECT(s), "efuse-cache", &s->pmc.efuse_cache,
184
+ TYPE_XLNX_VERSAL_EFUSE_CACHE);
185
+
186
+ object_initialize_child_with_props(ctrl, "xlnx-efuse@0", bits,
187
+ sizeof(s->pmc.efuse),
188
+ TYPE_XLNX_EFUSE, &error_abort,
189
+ "efuse-nr", "3",
190
+ "efuse-size", "8192",
191
+ NULL);
192
+
193
+ qdev_realize(DEVICE(bits), NULL, &error_abort);
194
+ versal_realize_efuse_part(s, ctrl, MM_PMC_EFUSE_CTRL);
195
+ versal_realize_efuse_part(s, cache, MM_PMC_EFUSE_CACHE);
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
160
--
223
--
161
2.20.1
224
2.20.1
162
225
163
226
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Tong Ho <tong.ho@xilinx.com>
2
2
3
hw_error() calls exit(). This a bit overkill when we can log
3
Connect the support for Xilinx ZynqMP Battery-Backed RAM (BBRAM)
4
the accesses as unimplemented or guest error.
5
4
6
When fuzzing the devices, we don't want the whole process to
5
The command argument:
7
exit. Replace some hw_error() calls by qemu_log_mask()
6
-drive if=pflash,index=2,...
8
(missed in commit 5a0001ec7e).
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.
9
10
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
The backend storage must be a seekable binary file, and
11
Message-id: 20200525114123.21317-2-f4bug@amsat.org
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
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
19
---
15
hw/input/pxa2xx_keypad.c | 10 +++++++---
20
include/hw/arm/xlnx-zynqmp.h | 2 ++
16
1 file changed, 7 insertions(+), 3 deletions(-)
21
hw/arm/xlnx-zcu102.c | 15 +++++++++++++++
22
hw/arm/xlnx-zynqmp.c | 20 ++++++++++++++++++++
23
hw/Kconfig | 1 +
24
4 files changed, 38 insertions(+)
17
25
18
diff --git a/hw/input/pxa2xx_keypad.c b/hw/input/pxa2xx_keypad.c
26
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
19
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/input/pxa2xx_keypad.c
28
--- a/include/hw/arm/xlnx-zynqmp.h
21
+++ b/hw/input/pxa2xx_keypad.c
29
+++ b/include/hw/arm/xlnx-zynqmp.h
22
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@
23
*/
31
#include "qom/object.h"
24
32
#include "net/can_emu.h"
25
#include "qemu/osdep.h"
33
#include "hw/dma/xlnx_csu_dma.h"
26
-#include "hw/hw.h"
34
+#include "hw/nvram/xlnx-bbram.h"
27
+#include "qemu/log.h"
35
28
#include "hw/irq.h"
36
#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
29
#include "migration/vmstate.h"
37
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
30
#include "hw/arm/pxa.h"
38
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
31
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_keypad_read(void *opaque, hwaddr offset,
39
32
return s->kpkdi;
40
MemoryRegion *ddr_ram;
33
break;
41
MemoryRegion ddr_ram_low, ddr_ram_high;
34
default:
42
+ XlnxBBRam bbram;
35
- hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset);
43
36
+ qemu_log_mask(LOG_GUEST_ERROR,
44
MemoryRegion mr_unimp[XLNX_ZYNQMP_NUM_UNIMP_AREAS];
37
+ "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
45
38
+ __func__, offset);
46
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
39
}
47
index XXXXXXX..XXXXXXX 100644
40
48
--- a/hw/arm/xlnx-zcu102.c
41
return 0;
49
+++ b/hw/arm/xlnx-zcu102.c
42
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_keypad_write(void *opaque, hwaddr offset,
50
@@ -XXX,XX +XXX,XX @@ static void zcu102_modify_dtb(const struct arm_boot_info *binfo, void *fdt)
43
break;
44
45
default:
46
- hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset);
47
+ qemu_log_mask(LOG_GUEST_ERROR,
48
+ "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
49
+ __func__, offset);
50
}
51
}
51
}
52
}
52
53
54
+static void bbram_attach_drive(XlnxBBRam *dev)
55
+{
56
+ DriveInfo *dinfo;
57
+ BlockBackend *blk;
58
+
59
+ dinfo = drive_get_by_index(IF_PFLASH, 2);
60
+ blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
61
+ if (blk) {
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
53
--
133
--
54
2.20.1
134
2.20.1
55
135
56
136
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Tong Ho <tong.ho@xilinx.com>
2
2
3
With this conversion, we will be able to use the same helpers
3
Connect the support for ZynqMP eFUSE one-time field-programmable
4
with sve. In particular, pass 3 vector parameters for the
4
bit array.
5
3-operand operations; for advsimd the destination register
6
is also an input.
7
5
8
This also fixes a bug in which we failed to clear the high bits
6
The command argument:
9
of the SVE register after an AdvSIMD operation.
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.
10
12
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
The backend storage must be a seekable binary file, and
12
Message-id: 20200514212831.31248-2-richard.henderson@linaro.org
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
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
21
---
16
target/arm/helper.h | 6 ++--
22
include/hw/arm/xlnx-zynqmp.h | 3 +++
17
target/arm/vec_internal.h | 33 +++++++++++++++++
23
hw/arm/xlnx-zcu102.c | 15 +++++++++++++++
18
target/arm/crypto_helper.c | 72 +++++++++++++++++++++++++++-----------
24
hw/arm/xlnx-zynqmp.c | 29 +++++++++++++++++++++++++++++
19
target/arm/translate-a64.c | 55 ++++++++++++++++++-----------
25
hw/Kconfig | 1 +
20
target/arm/translate.c | 27 +++++++-------
26
4 files changed, 48 insertions(+)
21
target/arm/vec_helper.c | 12 +------
22
6 files changed, 138 insertions(+), 67 deletions(-)
23
create mode 100644 target/arm/vec_internal.h
24
27
25
diff --git a/target/arm/helper.h b/target/arm/helper.h
28
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
26
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/helper.h
30
--- a/include/hw/arm/xlnx-zynqmp.h
28
+++ b/target/arm/helper.h
31
+++ b/include/hw/arm/xlnx-zynqmp.h
29
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(neon_qzip8, TCG_CALL_NO_RWG, void, ptr, ptr)
30
DEF_HELPER_FLAGS_2(neon_qzip16, TCG_CALL_NO_RWG, void, ptr, ptr)
31
DEF_HELPER_FLAGS_2(neon_qzip32, TCG_CALL_NO_RWG, void, ptr, ptr)
32
33
-DEF_HELPER_FLAGS_3(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_4(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
35
DEF_HELPER_FLAGS_3(crypto_aesmc, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
36
37
DEF_HELPER_FLAGS_4(crypto_sha1_3reg, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
38
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(crypto_sm3tt, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, i32)
39
DEF_HELPER_FLAGS_3(crypto_sm3partw1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
40
DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
41
42
-DEF_HELPER_FLAGS_2(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr)
43
-DEF_HELPER_FLAGS_3(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
44
+DEF_HELPER_FLAGS_4(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
45
+DEF_HELPER_FLAGS_4(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
46
47
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
48
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
49
diff --git a/target/arm/vec_internal.h b/target/arm/vec_internal.h
50
new file mode 100644
51
index XXXXXXX..XXXXXXX
52
--- /dev/null
53
+++ b/target/arm/vec_internal.h
54
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@
55
+/*
33
#include "net/can_emu.h"
56
+ * ARM AdvSIMD / SVE Vector Helpers
34
#include "hw/dma/xlnx_csu_dma.h"
57
+ *
35
#include "hw/nvram/xlnx-bbram.h"
58
+ * Copyright (c) 2020 Linaro
36
+#include "hw/nvram/xlnx-zynqmp-efuse.h"
59
+ *
37
60
+ * This library is free software; you can redistribute it and/or
38
#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
61
+ * modify it under the terms of the GNU Lesser General Public
39
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
62
+ * License as published by the Free Software Foundation; either
40
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
63
+ * version 2 of the License, or (at your option) any later version.
41
MemoryRegion *ddr_ram;
64
+ *
42
MemoryRegion ddr_ram_low, ddr_ram_high;
65
+ * This library is distributed in the hope that it will be useful,
43
XlnxBBRam bbram;
66
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
44
+ XlnxEFuse efuse;
67
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
45
+ XlnxZynqMPEFuse efuse_ctrl;
68
+ * Lesser General Public License for more details.
46
69
+ *
47
MemoryRegion mr_unimp[XLNX_ZYNQMP_NUM_UNIMP_AREAS];
70
+ * You should have received a copy of the GNU Lesser General Public
48
71
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
49
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
72
+ */
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
+{
59
+ DriveInfo *dinfo;
60
+ BlockBackend *blk;
73
+
61
+
74
+#ifndef TARGET_ARM_VEC_INTERNALS_H
62
+ dinfo = drive_get_by_index(IF_PFLASH, 3);
75
+#define TARGET_ARM_VEC_INTERNALS_H
63
+ blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
76
+
64
+ if (blk) {
77
+static inline void clear_tail(void *vd, uintptr_t opr_sz, uintptr_t max_sz)
65
+ qdev_prop_set_drive(DEVICE(dev), "drive", blk);
78
+{
79
+ uint64_t *d = vd + opr_sz;
80
+ uintptr_t i;
81
+
82
+ for (i = opr_sz; i < max_sz; i += 8) {
83
+ *d++ = 0;
84
+ }
66
+ }
85
+}
67
+}
86
+
68
+
87
+#endif /* TARGET_ARM_VEC_INTERNALS_H */
69
static void xlnx_zcu102_init(MachineState *machine)
88
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
70
{
71
XlnxZCU102 *s = ZCU102_MACHINE(machine);
72
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_init(MachineState *machine)
73
/* Attach bbram backend, if given */
74
bbram_attach_drive(&s->soc.bbram);
75
76
+ /* Attach efuse backend, if given */
77
+ efuse_attach_drive(&s->soc.efuse);
78
+
79
/* Create and plug in the SD cards */
80
for (i = 0; i < XLNX_ZYNQMP_NUM_SDHCI; i++) {
81
BusState *bus;
82
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
89
index XXXXXXX..XXXXXXX 100644
83
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/crypto_helper.c
84
--- a/hw/arm/xlnx-zynqmp.c
91
+++ b/target/arm/crypto_helper.c
85
+++ b/hw/arm/xlnx-zynqmp.c
92
@@ -XXX,XX +XXX,XX @@
86
@@ -XXX,XX +XXX,XX @@
93
87
#define BBRAM_ADDR 0xffcd0000
94
#include "cpu.h"
88
#define BBRAM_IRQ 11
95
#include "exec/helper-proto.h"
89
96
+#include "tcg/tcg-gvec-desc.h"
90
+#define EFUSE_ADDR 0xffcc0000
97
#include "crypto/aes.h"
91
+#define EFUSE_IRQ 87
98
+#include "vec_internal.h"
92
+
99
93
#define SDHCI_CAPABILITIES 0x280737ec6481 /* Datasheet: UG1085 (v1.7) */
100
union CRYPTO_STATE {
94
101
uint8_t bytes[16];
95
static const uint64_t gem_addr[XLNX_ZYNQMP_NUM_GEMS] = {
102
@@ -XXX,XX +XXX,XX @@ union CRYPTO_STATE {
96
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_bbram(XlnxZynqMPState *s, qemu_irq *gic)
103
#define CR_ST_WORD(state, i) (state.words[i])
97
sysbus_connect_irq(sbd, 0, gic[BBRAM_IRQ]);
104
#endif
105
106
-void HELPER(crypto_aese)(void *vd, void *vm, uint32_t decrypt)
107
+static void do_crypto_aese(uint64_t *rd, uint64_t *rn,
108
+ uint64_t *rm, bool decrypt)
109
{
110
static uint8_t const * const sbox[2] = { AES_sbox, AES_isbox };
111
static uint8_t const * const shift[2] = { AES_shifts, AES_ishifts };
112
- uint64_t *rd = vd;
113
- uint64_t *rm = vm;
114
union CRYPTO_STATE rk = { .l = { rm[0], rm[1] } };
115
- union CRYPTO_STATE st = { .l = { rd[0], rd[1] } };
116
+ union CRYPTO_STATE st = { .l = { rn[0], rn[1] } };
117
int i;
118
119
- assert(decrypt < 2);
120
-
121
/* xor state vector with round key */
122
rk.l[0] ^= st.l[0];
123
rk.l[1] ^= st.l[1];
124
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_aese)(void *vd, void *vm, uint32_t decrypt)
125
rd[1] = st.l[1];
126
}
98
}
127
99
128
-void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t decrypt)
100
+static void xlnx_zynqmp_create_efuse(XlnxZynqMPState *s, qemu_irq *gic)
129
+void HELPER(crypto_aese)(void *vd, void *vn, void *vm, uint32_t desc)
130
+{
101
+{
131
+ intptr_t i, opr_sz = simd_oprsz(desc);
102
+ Object *bits = OBJECT(&s->efuse);
132
+ bool decrypt = simd_data(desc);
103
+ Object *ctrl = OBJECT(&s->efuse_ctrl);
104
+ SysBusDevice *sbd;
133
+
105
+
134
+ for (i = 0; i < opr_sz; i += 16) {
106
+ object_initialize_child(OBJECT(s), "efuse-ctrl", &s->efuse_ctrl,
135
+ do_crypto_aese(vd + i, vn + i, vm + i, decrypt);
107
+ TYPE_XLNX_ZYNQMP_EFUSE);
136
+ }
108
+
137
+ clear_tail(vd, opr_sz, simd_maxsz(desc));
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]);
138
+}
123
+}
139
+
124
+
140
+static void do_crypto_aesmc(uint64_t *rd, uint64_t *rm, bool decrypt)
125
static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
141
{
126
{
142
static uint32_t const mc[][256] = { {
127
static const struct UnimpInfo {
143
/* MixColumns lookup table */
128
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
144
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t decrypt)
129
sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, gic_spi[RTC_IRQ]);
145
0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d,
130
146
} };
131
xlnx_zynqmp_create_bbram(s, gic_spi);
147
132
+ xlnx_zynqmp_create_efuse(s, gic_spi);
148
- uint64_t *rd = vd;
133
xlnx_zynqmp_create_unimp_mmio(s);
149
- uint64_t *rm = vm;
134
150
union CRYPTO_STATE st = { .l = { rm[0], rm[1] } };
135
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
151
int i;
136
diff --git a/hw/Kconfig b/hw/Kconfig
152
153
- assert(decrypt < 2);
154
-
155
for (i = 0; i < 16; i += 4) {
156
CR_ST_WORD(st, i >> 2) =
157
mc[decrypt][CR_ST_BYTE(st, i)] ^
158
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t decrypt)
159
rd[1] = st.l[1];
160
}
161
162
+void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t desc)
163
+{
164
+ intptr_t i, opr_sz = simd_oprsz(desc);
165
+ bool decrypt = simd_data(desc);
166
+
167
+ for (i = 0; i < opr_sz; i += 16) {
168
+ do_crypto_aesmc(vd + i, vm + i, decrypt);
169
+ }
170
+ clear_tail(vd, opr_sz, simd_maxsz(desc));
171
+}
172
+
173
/*
174
* SHA-1 logical functions
175
*/
176
@@ -XXX,XX +XXX,XX @@ static uint8_t const sm4_sbox[] = {
177
0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
178
};
179
180
-void HELPER(crypto_sm4e)(void *vd, void *vn)
181
+static void do_crypto_sm4e(uint64_t *rd, uint64_t *rn, uint64_t *rm)
182
{
183
- uint64_t *rd = vd;
184
- uint64_t *rn = vn;
185
- union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
186
- union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
187
+ union CRYPTO_STATE d = { .l = { rn[0], rn[1] } };
188
+ union CRYPTO_STATE n = { .l = { rm[0], rm[1] } };
189
uint32_t t, i;
190
191
for (i = 0; i < 4; i++) {
192
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sm4e)(void *vd, void *vn)
193
rd[1] = d.l[1];
194
}
195
196
-void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm)
197
+void HELPER(crypto_sm4e)(void *vd, void *vn, void *vm, uint32_t desc)
198
+{
199
+ intptr_t i, opr_sz = simd_oprsz(desc);
200
+
201
+ for (i = 0; i < opr_sz; i += 16) {
202
+ do_crypto_sm4e(vd + i, vn + i, vm + i);
203
+ }
204
+ clear_tail(vd, opr_sz, simd_maxsz(desc));
205
+}
206
+
207
+static void do_crypto_sm4ekey(uint64_t *rd, uint64_t *rn, uint64_t *rm)
208
{
209
- uint64_t *rd = vd;
210
- uint64_t *rn = vn;
211
- uint64_t *rm = vm;
212
union CRYPTO_STATE d;
213
union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
214
union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
215
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm)
216
rd[0] = d.l[0];
217
rd[1] = d.l[1];
218
}
219
+
220
+void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm, uint32_t desc)
221
+{
222
+ intptr_t i, opr_sz = simd_oprsz(desc);
223
+
224
+ for (i = 0; i < opr_sz; i += 16) {
225
+ do_crypto_sm4ekey(vd + i, vn + i, vm + i);
226
+ }
227
+ clear_tail(vd, opr_sz, simd_maxsz(desc));
228
+}
229
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
230
index XXXXXXX..XXXXXXX 100644
137
index XXXXXXX..XXXXXXX 100644
231
--- a/target/arm/translate-a64.c
138
--- a/hw/Kconfig
232
+++ b/target/arm/translate-a64.c
139
+++ b/hw/Kconfig
233
@@ -XXX,XX +XXX,XX @@ static void gen_gvec_fn4(DisasContext *s, bool is_q, int rd, int rn, int rm,
140
@@ -XXX,XX +XXX,XX @@ config XLNX_ZYNQMP
234
is_q ? 16 : 8, vec_full_reg_size(s));
141
select CAN_BUS
235
}
142
select PTIMER
236
143
select XLNX_BBRAM
237
+/* Expand a 2-operand operation using an out-of-line helper. */
144
+ select XLNX_EFUSE_ZYNQMP
238
+static void gen_gvec_op2_ool(DisasContext *s, bool is_q, int rd,
239
+ int rn, int data, gen_helper_gvec_2 *fn)
240
+{
241
+ tcg_gen_gvec_2_ool(vec_full_reg_offset(s, rd),
242
+ vec_full_reg_offset(s, rn),
243
+ is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
244
+}
245
+
246
/* Expand a 3-operand operation using an out-of-line helper. */
247
static void gen_gvec_op3_ool(DisasContext *s, bool is_q, int rd,
248
int rn, int rm, int data, gen_helper_gvec_3 *fn)
249
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_aes(DisasContext *s, uint32_t insn)
250
int rn = extract32(insn, 5, 5);
251
int rd = extract32(insn, 0, 5);
252
int decrypt;
253
- TCGv_ptr tcg_rd_ptr, tcg_rn_ptr;
254
- TCGv_i32 tcg_decrypt;
255
- CryptoThreeOpIntFn *genfn;
256
+ gen_helper_gvec_2 *genfn2 = NULL;
257
+ gen_helper_gvec_3 *genfn3 = NULL;
258
259
if (!dc_isar_feature(aa64_aes, s) || size != 0) {
260
unallocated_encoding(s);
261
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_aes(DisasContext *s, uint32_t insn)
262
switch (opcode) {
263
case 0x4: /* AESE */
264
decrypt = 0;
265
- genfn = gen_helper_crypto_aese;
266
+ genfn3 = gen_helper_crypto_aese;
267
break;
268
case 0x6: /* AESMC */
269
decrypt = 0;
270
- genfn = gen_helper_crypto_aesmc;
271
+ genfn2 = gen_helper_crypto_aesmc;
272
break;
273
case 0x5: /* AESD */
274
decrypt = 1;
275
- genfn = gen_helper_crypto_aese;
276
+ genfn3 = gen_helper_crypto_aese;
277
break;
278
case 0x7: /* AESIMC */
279
decrypt = 1;
280
- genfn = gen_helper_crypto_aesmc;
281
+ genfn2 = gen_helper_crypto_aesmc;
282
break;
283
default:
284
unallocated_encoding(s);
285
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_aes(DisasContext *s, uint32_t insn)
286
if (!fp_access_check(s)) {
287
return;
288
}
289
-
290
- tcg_rd_ptr = vec_full_reg_ptr(s, rd);
291
- tcg_rn_ptr = vec_full_reg_ptr(s, rn);
292
- tcg_decrypt = tcg_const_i32(decrypt);
293
-
294
- genfn(tcg_rd_ptr, tcg_rn_ptr, tcg_decrypt);
295
-
296
- tcg_temp_free_ptr(tcg_rd_ptr);
297
- tcg_temp_free_ptr(tcg_rn_ptr);
298
- tcg_temp_free_i32(tcg_decrypt);
299
+ if (genfn2) {
300
+ gen_gvec_op2_ool(s, true, rd, rn, decrypt, genfn2);
301
+ } else {
302
+ gen_gvec_op3_ool(s, true, rd, rd, rn, decrypt, genfn3);
303
+ }
304
}
305
306
/* Crypto three-reg SHA
307
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
308
int rn = extract32(insn, 5, 5);
309
int rd = extract32(insn, 0, 5);
310
bool feature;
311
- CryptoThreeOpFn *genfn;
312
+ CryptoThreeOpFn *genfn = NULL;
313
+ gen_helper_gvec_3 *oolfn = NULL;
314
315
if (o == 0) {
316
switch (opcode) {
317
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
318
break;
319
case 2: /* SM4EKEY */
320
feature = dc_isar_feature(aa64_sm4, s);
321
- genfn = gen_helper_crypto_sm4ekey;
322
+ oolfn = gen_helper_crypto_sm4ekey;
323
break;
324
default:
325
unallocated_encoding(s);
326
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
327
return;
328
}
329
330
+ if (oolfn) {
331
+ gen_gvec_op3_ool(s, true, rd, rn, rm, 0, oolfn);
332
+ return;
333
+ }
334
+
335
if (genfn) {
336
TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
337
338
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
339
TCGv_ptr tcg_rd_ptr, tcg_rn_ptr;
340
bool feature;
341
CryptoTwoOpFn *genfn;
342
+ gen_helper_gvec_3 *oolfn = NULL;
343
344
switch (opcode) {
345
case 0: /* SHA512SU0 */
346
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
347
break;
348
case 1: /* SM4E */
349
feature = dc_isar_feature(aa64_sm4, s);
350
- genfn = gen_helper_crypto_sm4e;
351
+ oolfn = gen_helper_crypto_sm4e;
352
break;
353
default:
354
unallocated_encoding(s);
355
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
356
return;
357
}
358
359
+ if (oolfn) {
360
+ gen_gvec_op3_ool(s, true, rd, rd, rn, 0, oolfn);
361
+ return;
362
+ }
363
+
364
tcg_rd_ptr = vec_full_reg_ptr(s, rd);
365
tcg_rn_ptr = vec_full_reg_ptr(s, rn);
366
367
diff --git a/target/arm/translate.c b/target/arm/translate.c
368
index XXXXXXX..XXXXXXX 100644
369
--- a/target/arm/translate.c
370
+++ b/target/arm/translate.c
371
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
372
if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
373
return 1;
374
}
375
- ptr1 = vfp_reg_ptr(true, rd);
376
- ptr2 = vfp_reg_ptr(true, rm);
377
-
378
- /* Bit 6 is the lowest opcode bit; it distinguishes between
379
- * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
380
- */
381
- tmp3 = tcg_const_i32(extract32(insn, 6, 1));
382
-
383
+ /*
384
+ * Bit 6 is the lowest opcode bit; it distinguishes
385
+ * between encryption (AESE/AESMC) and decryption
386
+ * (AESD/AESIMC).
387
+ */
388
if (op == NEON_2RM_AESE) {
389
- gen_helper_crypto_aese(ptr1, ptr2, tmp3);
390
+ tcg_gen_gvec_3_ool(vfp_reg_offset(true, rd),
391
+ vfp_reg_offset(true, rd),
392
+ vfp_reg_offset(true, rm),
393
+ 16, 16, extract32(insn, 6, 1),
394
+ gen_helper_crypto_aese);
395
} else {
396
- gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
397
+ tcg_gen_gvec_2_ool(vfp_reg_offset(true, rd),
398
+ vfp_reg_offset(true, rm),
399
+ 16, 16, extract32(insn, 6, 1),
400
+ gen_helper_crypto_aesmc);
401
}
402
- tcg_temp_free_ptr(ptr1);
403
- tcg_temp_free_ptr(ptr2);
404
- tcg_temp_free_i32(tmp3);
405
break;
406
case NEON_2RM_SHA1H:
407
if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
408
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
409
index XXXXXXX..XXXXXXX 100644
410
--- a/target/arm/vec_helper.c
411
+++ b/target/arm/vec_helper.c
412
@@ -XXX,XX +XXX,XX @@
413
#include "exec/helper-proto.h"
414
#include "tcg/tcg-gvec-desc.h"
415
#include "fpu/softfloat.h"
416
-
417
+#include "vec_internal.h"
418
419
/* Note that vector data is stored in host-endian 64-bit chunks,
420
so addressing units smaller than that needs a host-endian fixup. */
421
@@ -XXX,XX +XXX,XX @@
422
#define H4(x) (x)
423
#endif
424
425
-static void clear_tail(void *vd, uintptr_t opr_sz, uintptr_t max_sz)
426
-{
427
- uint64_t *d = vd + opr_sz;
428
- uintptr_t i;
429
-
430
- for (i = opr_sz; i < max_sz; i += 8) {
431
- *d++ = 0;
432
- }
433
-}
434
-
435
/* Signed saturating rounding doubling multiply-accumulate high half, 16-bit */
436
static int16_t inl_qrdmlah_s16(int16_t src1, int16_t src2,
437
int16_t src3, uint32_t *sat)
438
--
145
--
439
2.20.1
146
2.20.1
440
147
441
148
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Tong Ho <tong.ho@xilinx.com>
2
2
3
Signed-off-by: Cédric Le Goater <clg@kaod.org>
3
Add BBRAM and eFUSE usage to the Xilinx Versal Virt board
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
document.
5
Message-id: 20200602135050.593692-1-clg@kaod.org
5
6
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
7
Message-id: 20210917052400.1249094-10-tong.ho@xilinx.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
docs/system/arm/aspeed.rst | 85 ++++++++++++++++++++++++++++++++++++++
11
docs/system/arm/xlnx-versal-virt.rst | 49 ++++++++++++++++++++++++++++
9
docs/system/target-arm.rst | 1 +
12
1 file changed, 49 insertions(+)
10
2 files changed, 86 insertions(+)
11
create mode 100644 docs/system/arm/aspeed.rst
12
13
13
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
14
diff --git a/docs/system/arm/xlnx-versal-virt.rst b/docs/system/arm/xlnx-versal-virt.rst
14
new file mode 100644
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX
16
--- a/docs/system/arm/xlnx-versal-virt.rst
16
--- /dev/null
17
+++ b/docs/system/arm/xlnx-versal-virt.rst
17
+++ b/docs/system/arm/aspeed.rst
18
@@ -XXX,XX +XXX,XX @@ Implemented devices:
18
@@ -XXX,XX +XXX,XX @@
19
- OCM (256KB of On Chip Memory)
19
+Aspeed family boards (``*-bmc``, ``ast2500-evb``, ``ast2600-evb``)
20
- XRAM (4MB of on chip Accelerator RAM)
20
+==================================================================
21
- DDR memory
22
+- BBRAM (36 bytes of Battery-backed RAM)
23
+- eFUSE (3072 bytes of one-time field-programmable bit array)
24
25
QEMU does not yet model any other devices, including the PL and the AI Engine.
26
27
@@ -XXX,XX +XXX,XX @@ Run the following at the U-Boot prompt:
28
fdt set /chosen/dom0 reg <0x00000000 0x40000000 0x0 0x03100000>
29
booti 30000000 - 20000000
30
31
+BBRAM File Backend
32
+""""""""""""""""""
33
+BBRAM can have an optional file backend, which must be a seekable
34
+binary file with a size of 36 bytes or larger. A file with all
35
+binary 0s is a 'blank'.
21
+
36
+
22
+The QEMU Aspeed machines model BMCs of various OpenPOWER systems and
37
+To add a file-backend for the BBRAM:
23
+Aspeed evaluation boards. They are based on different releases of the
24
+Aspeed SoC : the AST2400 integrating an ARM926EJ-S CPU (400MHz), the
25
+AST2500 with an ARM1176JZS CPU (800MHz) and more recently the AST2600
26
+with dual cores ARM Cortex A7 CPUs (1.2GHz).
27
+
28
+The SoC comes with RAM, Gigabit ethernet, USB, SD/MMC, USB, SPI, I2C,
29
+etc.
30
+
31
+AST2400 SoC based machines :
32
+
33
+- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
34
+
35
+AST2500 SoC based machines :
36
+
37
+- ``ast2500-evb`` Aspeed AST2500 Evaluation board
38
+- ``romulus-bmc`` OpenPOWER Romulus POWER9 BMC
39
+- ``witherspoon-bmc`` OpenPOWER Witherspoon POWER9 BMC
40
+- ``sonorapass-bmc`` OCP SonoraPass BMC
41
+- ``swift-bmc`` OpenPOWER Swift BMC POWER9
42
+
43
+AST2600 SoC based machines :
44
+
45
+- ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex A7)
46
+- ``tacoma-bmc`` OpenPOWER Witherspoon POWER9 AST2600 BMC
47
+
48
+Supported devices
49
+-----------------
50
+
51
+ * SMP (for the AST2600 Cortex-A7)
52
+ * Interrupt Controller (VIC)
53
+ * Timer Controller
54
+ * RTC Controller
55
+ * I2C Controller
56
+ * System Control Unit (SCU)
57
+ * SRAM mapping
58
+ * X-DMA Controller (basic interface)
59
+ * Static Memory Controller (SMC or FMC) - Only SPI Flash support
60
+ * SPI Memory Controller
61
+ * USB 2.0 Controller
62
+ * SD/MMC storage controllers
63
+ * SDRAM controller (dummy interface for basic settings and training)
64
+ * Watchdog Controller
65
+ * GPIO Controller (Master only)
66
+ * UART
67
+ * Ethernet controllers
68
+
69
+
70
+Missing devices
71
+---------------
72
+
73
+ * Coprocessor support
74
+ * ADC (out of tree implementation)
75
+ * PWM and Fan Controller
76
+ * LPC Bus Controller
77
+ * Slave GPIO Controller
78
+ * Super I/O Controller
79
+ * Hash/Crypto Engine
80
+ * PCI-Express 1 Controller
81
+ * Graphic Display Controller
82
+ * PECI Controller
83
+ * MCTP Controller
84
+ * Mailbox Controller
85
+ * Virtual UART
86
+ * eSPI Controller
87
+ * I3C Controller
88
+
89
+Boot options
90
+------------
91
+
92
+The Aspeed machines can be started using the -kernel option to load a
93
+Linux kernel or from a firmare image which can be downloaded from the
94
+OpenPOWER jenkins :
95
+
96
+ https://openpower.xyz/
97
+
98
+The image should be attached as an MTD drive. Run :
99
+
38
+
100
+.. code-block:: bash
39
+.. code-block:: bash
101
+
40
+
102
+ $ qemu-system-arm -M romulus-bmc -nic user \
41
+ -drive if=pflash,index=0,file=versal-bbram.bin,format=raw
103
+    -drive file=flash-romulus,format=raw,if=mtd -nographic
42
+
104
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
43
+To use a different index value, N, from default of 0, add:
105
index XXXXXXX..XXXXXXX 100644
44
+
106
--- a/docs/system/target-arm.rst
45
+.. code-block:: bash
107
+++ b/docs/system/target-arm.rst
46
+
108
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
47
+ -global xlnx,bbram-ctrl.drive-index=N
109
arm/realview
48
+
110
arm/versatile
49
+eFUSE File Backend
111
arm/vexpress
50
+""""""""""""""""""
112
+ arm/aspeed
51
+eFUSE can have an optional file backend, which must be a seekable
113
arm/musicpal
52
+binary file with a size of 3072 bytes or larger. A file with all
114
arm/nseries
53
+binary 0s is a 'blank'.
115
arm/orangepi
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.
116
--
78
--
117
2.20.1
79
2.20.1
118
80
119
81
diff view generated by jsdifflib
1
Convert the insns in the one-register-and-immediate group to decodetree.
1
The aarch64-linux QEMU usermode binaries can never run 32-bit
2
2
code, so they do not need to include the GDB XML for it.
3
In the new decode, our asimd_imm_const() function returns a 64-bit value
3
(arm_cpu_register_gdb_regs_for_features() will not use these
4
rather than a 32-bit one, which means we don't need to treat cmode=14 op=1
4
XML files if the CPU has ARM_FEATURE_AARCH64, so we will not
5
as a special case in the decoder (it is the only encoding where the two
5
advertise to gdb that we have them.)
6
halves of the 64-bit value are different).
7
6
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200522145520.6778-10-peter.maydell@linaro.org
9
Message-id: 20210921162901.17508-2-peter.maydell@linaro.org
11
---
10
---
12
target/arm/neon-dp.decode | 22 ++++++
11
configs/targets/aarch64-linux-user.mak | 2 +-
13
target/arm/translate-neon.inc.c | 118 ++++++++++++++++++++++++++++++++
12
configs/targets/aarch64_be-linux-user.mak | 2 +-
14
target/arm/translate.c | 101 +--------------------------
13
2 files changed, 2 insertions(+), 2 deletions(-)
15
3 files changed, 142 insertions(+), 99 deletions(-)
16
14
17
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
diff --git a/configs/targets/aarch64-linux-user.mak b/configs/targets/aarch64-linux-user.mak
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/neon-dp.decode
17
--- a/configs/targets/aarch64-linux-user.mak
20
+++ b/target/arm/neon-dp.decode
18
+++ b/configs/targets/aarch64-linux-user.mak
21
@@ -XXX,XX +XXX,XX @@ VCVT_SF_2sh 1111 001 0 1 . ...... .... 1110 0 . . 1 .... @2reg_vcvt
19
@@ -XXX,XX +XXX,XX @@
22
VCVT_UF_2sh 1111 001 1 1 . ...... .... 1110 0 . . 1 .... @2reg_vcvt
20
TARGET_ARCH=aarch64
23
VCVT_FS_2sh 1111 001 0 1 . ...... .... 1111 0 . . 1 .... @2reg_vcvt
21
TARGET_BASE_ARCH=arm
24
VCVT_FU_2sh 1111 001 1 1 . ...... .... 1111 0 . . 1 .... @2reg_vcvt
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
25
+
23
+TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml
26
+######################################################################
24
TARGET_HAS_BFLT=y
27
+# 1-reg-and-modified-immediate grouping:
25
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
28
+# 1111 001 i 1 D 000 imm:3 Vd:4 cmode:4 0 Q op 1 Vm:4
26
diff --git a/configs/targets/aarch64_be-linux-user.mak b/configs/targets/aarch64_be-linux-user.mak
29
+######################################################################
30
+
31
+&1reg_imm vd q imm cmode op
32
+
33
+%asimd_imm_value 24:1 16:3 0:4
34
+
35
+@1reg_imm .... ... . . . ... ... .... .... . q:1 . . .... \
36
+ &1reg_imm imm=%asimd_imm_value vd=%vd_dp
37
+
38
+# The cmode/op bits here decode VORR/VBIC/VMOV/VMNV, but
39
+# not in a way we can conveniently represent in decodetree without
40
+# a lot of repetition:
41
+# VORR: op=0, (cmode & 1) && cmode < 12
42
+# VBIC: op=1, (cmode & 1) && cmode < 12
43
+# VMOV: everything else
44
+# So we have a single decode line and check the cmode/op in the
45
+# trans function.
46
+Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
47
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
48
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/translate-neon.inc.c
28
--- a/configs/targets/aarch64_be-linux-user.mak
50
+++ b/target/arm/translate-neon.inc.c
29
+++ b/configs/targets/aarch64_be-linux-user.mak
51
@@ -XXX,XX +XXX,XX @@ DO_FP_2SH(VCVT_SF, gen_helper_vfp_sltos)
30
@@ -XXX,XX +XXX,XX @@
52
DO_FP_2SH(VCVT_UF, gen_helper_vfp_ultos)
31
TARGET_ARCH=aarch64
53
DO_FP_2SH(VCVT_FS, gen_helper_vfp_tosls_round_to_zero)
32
TARGET_BASE_ARCH=arm
54
DO_FP_2SH(VCVT_FU, gen_helper_vfp_touls_round_to_zero)
33
TARGET_WORDS_BIGENDIAN=y
55
+
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
56
+static uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
35
+TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml
57
+{
36
TARGET_HAS_BFLT=y
58
+ /*
37
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
59
+ * Expand the encoded constant.
60
+ * Note that cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
61
+ * We choose to not special-case this and will behave as if a
62
+ * valid constant encoding of 0 had been given.
63
+ * cmode = 15 op = 1 must UNDEF; we assume decode has handled that.
64
+ */
65
+ switch (cmode) {
66
+ case 0: case 1:
67
+ /* no-op */
68
+ break;
69
+ case 2: case 3:
70
+ imm <<= 8;
71
+ break;
72
+ case 4: case 5:
73
+ imm <<= 16;
74
+ break;
75
+ case 6: case 7:
76
+ imm <<= 24;
77
+ break;
78
+ case 8: case 9:
79
+ imm |= imm << 16;
80
+ break;
81
+ case 10: case 11:
82
+ imm = (imm << 8) | (imm << 24);
83
+ break;
84
+ case 12:
85
+ imm = (imm << 8) | 0xff;
86
+ break;
87
+ case 13:
88
+ imm = (imm << 16) | 0xffff;
89
+ break;
90
+ case 14:
91
+ if (op) {
92
+ /*
93
+ * This is the only case where the top and bottom 32 bits
94
+ * of the encoded constant differ.
95
+ */
96
+ uint64_t imm64 = 0;
97
+ int n;
98
+
99
+ for (n = 0; n < 8; n++) {
100
+ if (imm & (1 << n)) {
101
+ imm64 |= (0xffULL << (n * 8));
102
+ }
103
+ }
104
+ return imm64;
105
+ }
106
+ imm |= (imm << 8) | (imm << 16) | (imm << 24);
107
+ break;
108
+ case 15:
109
+ imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
110
+ | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
111
+ break;
112
+ }
113
+ if (op) {
114
+ imm = ~imm;
115
+ }
116
+ return dup_const(MO_32, imm);
117
+}
118
+
119
+static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
120
+ GVecGen2iFn *fn)
121
+{
122
+ uint64_t imm;
123
+ int reg_ofs, vec_size;
124
+
125
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
126
+ return false;
127
+ }
128
+
129
+ /* UNDEF accesses to D16-D31 if they don't exist. */
130
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
131
+ return false;
132
+ }
133
+
134
+ if (a->vd & a->q) {
135
+ return false;
136
+ }
137
+
138
+ if (!vfp_access_check(s)) {
139
+ return true;
140
+ }
141
+
142
+ reg_ofs = neon_reg_offset(a->vd, 0);
143
+ vec_size = a->q ? 16 : 8;
144
+ imm = asimd_imm_const(a->imm, a->cmode, a->op);
145
+
146
+ fn(MO_64, reg_ofs, reg_ofs, imm, vec_size, vec_size);
147
+ return true;
148
+}
149
+
150
+static void gen_VMOV_1r(unsigned vece, uint32_t dofs, uint32_t aofs,
151
+ int64_t c, uint32_t oprsz, uint32_t maxsz)
152
+{
153
+ tcg_gen_gvec_dup_imm(MO_64, dofs, oprsz, maxsz, c);
154
+}
155
+
156
+static bool trans_Vimm_1r(DisasContext *s, arg_1reg_imm *a)
157
+{
158
+ /* Handle decode of cmode/op here between VORR/VBIC/VMOV */
159
+ GVecGen2iFn *fn;
160
+
161
+ if ((a->cmode & 1) && a->cmode < 12) {
162
+ /* for op=1, the imm will be inverted, so BIC becomes AND. */
163
+ fn = a->op ? tcg_gen_gvec_andi : tcg_gen_gvec_ori;
164
+ } else {
165
+ /* There is one unallocated cmode/op combination in this space */
166
+ if (a->cmode == 15 && a->op == 1) {
167
+ return false;
168
+ }
169
+ fn = gen_VMOV_1r;
170
+ }
171
+ return do_1reg_imm(s, a, fn);
172
+}
173
diff --git a/target/arm/translate.c b/target/arm/translate.c
174
index XXXXXXX..XXXXXXX 100644
175
--- a/target/arm/translate.c
176
+++ b/target/arm/translate.c
177
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
178
/* Three register same length: handled by decodetree */
179
return 1;
180
} else if (insn & (1 << 4)) {
181
- if ((insn & 0x00380080) != 0) {
182
- /* Two registers and shift: handled by decodetree */
183
- return 1;
184
- } else { /* (insn & 0x00380080) == 0 */
185
- int invert, reg_ofs, vec_size;
186
-
187
- if (q && (rd & 1)) {
188
- return 1;
189
- }
190
-
191
- op = (insn >> 8) & 0xf;
192
- /* One register and immediate. */
193
- imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
194
- invert = (insn & (1 << 5)) != 0;
195
- /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
196
- * We choose to not special-case this and will behave as if a
197
- * valid constant encoding of 0 had been given.
198
- */
199
- switch (op) {
200
- case 0: case 1:
201
- /* no-op */
202
- break;
203
- case 2: case 3:
204
- imm <<= 8;
205
- break;
206
- case 4: case 5:
207
- imm <<= 16;
208
- break;
209
- case 6: case 7:
210
- imm <<= 24;
211
- break;
212
- case 8: case 9:
213
- imm |= imm << 16;
214
- break;
215
- case 10: case 11:
216
- imm = (imm << 8) | (imm << 24);
217
- break;
218
- case 12:
219
- imm = (imm << 8) | 0xff;
220
- break;
221
- case 13:
222
- imm = (imm << 16) | 0xffff;
223
- break;
224
- case 14:
225
- imm |= (imm << 8) | (imm << 16) | (imm << 24);
226
- if (invert) {
227
- imm = ~imm;
228
- }
229
- break;
230
- case 15:
231
- if (invert) {
232
- return 1;
233
- }
234
- imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
235
- | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
236
- break;
237
- }
238
- if (invert) {
239
- imm = ~imm;
240
- }
241
-
242
- reg_ofs = neon_reg_offset(rd, 0);
243
- vec_size = q ? 16 : 8;
244
-
245
- if (op & 1 && op < 12) {
246
- if (invert) {
247
- /* The immediate value has already been inverted,
248
- * so BIC becomes AND.
249
- */
250
- tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
251
- vec_size, vec_size);
252
- } else {
253
- tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
254
- vec_size, vec_size);
255
- }
256
- } else {
257
- /* VMOV, VMVN. */
258
- if (op == 14 && invert) {
259
- TCGv_i64 t64 = tcg_temp_new_i64();
260
-
261
- for (pass = 0; pass <= q; ++pass) {
262
- uint64_t val = 0;
263
- int n;
264
-
265
- for (n = 0; n < 8; n++) {
266
- if (imm & (1 << (n + pass * 8))) {
267
- val |= 0xffull << (n * 8);
268
- }
269
- }
270
- tcg_gen_movi_i64(t64, val);
271
- neon_store_reg64(t64, rd + pass);
272
- }
273
- tcg_temp_free_i64(t64);
274
- } else {
275
- tcg_gen_gvec_dup_imm(MO_32, reg_ofs, vec_size,
276
- vec_size, imm);
277
- }
278
- }
279
- }
280
+ /* Two registers and shift or reg and imm: handled by decodetree */
281
+ return 1;
282
} else { /* (insn & 0x00800010 == 0x00800000) */
283
if (size != 3) {
284
op = (insn >> 8) & 0xf;
285
--
38
--
286
2.20.1
39
2.20.1
287
40
288
41
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
We're going to move this code to a different file; fix the coding
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.
2
5
3
Replace printf() calls by qemu_log_mask(), which is disabled
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
by default. This avoid flooding the terminal when fuzzing the
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
device.
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210921162901.17508-3-peter.maydell@linaro.org
10
---
11
target/arm/helper.c | 23 ++++++++++++++++-------
12
1 file changed, 16 insertions(+), 7 deletions(-)
6
13
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
8
Message-id: 20200525114123.21317-3-f4bug@amsat.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/pxa2xx.c | 66 ++++++++++++++++++++++++++++++++++++-------------
13
1 file changed, 49 insertions(+), 17 deletions(-)
14
15
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/pxa2xx.c
16
--- a/target/arm/helper.c
18
+++ b/hw/arm/pxa2xx.c
17
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
20
#include "sysemu/blockdev.h"
19
}
21
#include "sysemu/qtest.h"
20
}
22
#include "qemu/cutils.h"
21
switch (reg - nregs) {
23
+#include "qemu/log.h"
22
- case 0: return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]); break;
24
23
- case 1: return gdb_get_reg32(buf, vfp_get_fpscr(env)); break;
25
static struct {
24
- case 2: return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]); break;
26
hwaddr io_base;
25
+ case 0:
27
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_pm_read(void *opaque, hwaddr addr,
26
+ return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]);
28
return s->pm_regs[addr >> 2];
27
+ case 1:
29
default:
28
+ return gdb_get_reg32(buf, vfp_get_fpscr(env));
30
fail:
29
+ case 2:
31
- printf("%s: Bad register " REG_FMT "\n", __func__, addr);
30
+ return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]);
32
+ qemu_log_mask(LOG_GUEST_ERROR,
33
+ "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
34
+ __func__, addr);
35
break;
36
}
31
}
37
return 0;
32
return 0;
38
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_pm_write(void *opaque, hwaddr addr,
33
}
39
s->pm_regs[addr >> 2] = value;
34
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
40
break;
41
}
35
}
42
-
43
- printf("%s: Bad register " REG_FMT "\n", __func__, addr);
44
+ qemu_log_mask(LOG_GUEST_ERROR,
45
+ "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
46
+ __func__, addr);
47
break;
48
}
36
}
49
}
37
switch (reg - nregs) {
50
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_cm_read(void *opaque, hwaddr addr,
38
- case 0: env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); return 4;
51
return s->cm_regs[CCCR >> 2] | (3 << 28);
39
- case 1: vfp_set_fpscr(env, ldl_p(buf)); return 4;
52
40
- case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30); return 4;
53
default:
41
+ case 0:
54
- printf("%s: Bad register " REG_FMT "\n", __func__, addr);
42
+ env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf);
55
+ qemu_log_mask(LOG_GUEST_ERROR,
43
+ return 4;
56
+ "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
44
+ case 1:
57
+ __func__, addr);
45
+ vfp_set_fpscr(env, ldl_p(buf));
58
break;
46
+ return 4;
47
+ case 2:
48
+ env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30);
49
+ return 4;
59
}
50
}
60
return 0;
51
return 0;
61
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_cm_write(void *opaque, hwaddr addr,
52
}
62
break;
53
@@ -XXX,XX +XXX,XX @@ static int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
63
54
return gdb_get_reg32(buf, vfp_get_fpsr(env));
55
case 33:
56
/* FPCR */
57
- return gdb_get_reg32(buf,vfp_get_fpcr(env));
58
+ return gdb_get_reg32(buf, vfp_get_fpcr(env));
64
default:
59
default:
65
- printf("%s: Bad register " REG_FMT "\n", __func__, addr);
60
return 0;
66
+ qemu_log_mask(LOG_GUEST_ERROR,
67
+ "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
68
+ __func__, addr);
69
break;
70
}
61
}
71
}
72
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_mm_read(void *opaque, hwaddr addr,
73
return s->mm_regs[addr >> 2];
74
/* fall through */
75
default:
76
- printf("%s: Bad register " REG_FMT "\n", __func__, addr);
77
+ qemu_log_mask(LOG_GUEST_ERROR,
78
+ "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
79
+ __func__, addr);
80
break;
81
}
82
return 0;
83
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_mm_write(void *opaque, hwaddr addr,
84
}
85
86
default:
87
- printf("%s: Bad register " REG_FMT "\n", __func__, addr);
88
+ qemu_log_mask(LOG_GUEST_ERROR,
89
+ "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
90
+ __func__, addr);
91
break;
92
}
93
}
94
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_ssp_read(void *opaque, hwaddr addr,
95
case SSACD:
96
return s->ssacd;
97
default:
98
- printf("%s: Bad register " REG_FMT "\n", __func__, addr);
99
+ qemu_log_mask(LOG_GUEST_ERROR,
100
+ "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
101
+ __func__, addr);
102
break;
103
}
104
return 0;
105
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_ssp_write(void *opaque, hwaddr addr,
106
break;
107
108
default:
109
- printf("%s: Bad register " REG_FMT "\n", __func__, addr);
110
+ qemu_log_mask(LOG_GUEST_ERROR,
111
+ "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
112
+ __func__, addr);
113
break;
114
}
115
}
116
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_rtc_read(void *opaque, hwaddr addr,
117
else
118
return s->last_swcr;
119
default:
120
- printf("%s: Bad register " REG_FMT "\n", __func__, addr);
121
+ qemu_log_mask(LOG_GUEST_ERROR,
122
+ "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
123
+ __func__, addr);
124
break;
125
}
126
return 0;
127
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_rtc_write(void *opaque, hwaddr addr,
128
break;
129
130
default:
131
- printf("%s: Bad register " REG_FMT "\n", __func__, addr);
132
+ qemu_log_mask(LOG_GUEST_ERROR,
133
+ "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
134
+ __func__, addr);
135
}
136
}
137
138
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_i2c_read(void *opaque, hwaddr addr,
139
s->ibmr = 0;
140
return s->ibmr;
141
default:
142
- printf("%s: Bad register " REG_FMT "\n", __func__, addr);
143
+ qemu_log_mask(LOG_GUEST_ERROR,
144
+ "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
145
+ __func__, addr);
146
break;
147
}
148
return 0;
149
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_i2c_write(void *opaque, hwaddr addr,
150
break;
151
152
default:
153
- printf("%s: Bad register " REG_FMT "\n", __func__, addr);
154
+ qemu_log_mask(LOG_GUEST_ERROR,
155
+ "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
156
+ __func__, addr);
157
}
158
}
159
160
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_i2s_read(void *opaque, hwaddr addr,
161
}
162
return 0;
163
default:
164
- printf("%s: Bad register " REG_FMT "\n", __func__, addr);
165
+ qemu_log_mask(LOG_GUEST_ERROR,
166
+ "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
167
+ __func__, addr);
168
break;
169
}
170
return 0;
171
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_i2s_write(void *opaque, hwaddr addr,
172
}
173
break;
174
default:
175
- printf("%s: Bad register " REG_FMT "\n", __func__, addr);
176
+ qemu_log_mask(LOG_GUEST_ERROR,
177
+ "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
178
+ __func__, addr);
179
}
180
}
181
182
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_fir_read(void *opaque, hwaddr addr,
183
case ICFOR:
184
return s->rx_len;
185
default:
186
- printf("%s: Bad register " REG_FMT "\n", __func__, addr);
187
+ qemu_log_mask(LOG_GUEST_ERROR,
188
+ "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
189
+ __func__, addr);
190
break;
191
}
192
return 0;
193
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_fir_write(void *opaque, hwaddr addr,
194
case ICFOR:
195
break;
196
default:
197
- printf("%s: Bad register " REG_FMT "\n", __func__, addr);
198
+ qemu_log_mask(LOG_GUEST_ERROR,
199
+ "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
200
+ __func__, addr);
201
}
202
}
203
204
--
62
--
205
2.20.1
63
2.20.1
206
64
207
65
diff view generated by jsdifflib
1
Convert the remaining Neon narrowing shifts to decodetree:
1
Currently helper.c includes some code which is part of the arm
2
* VQSHRN
2
target's gdbstub support. This code has a better home: in gdbstub.c
3
* VQRSHRN
3
and gdbstub64.c. Move it there.
4
5
Because aarch64_fpu_gdb_get_reg() and aarch64_fpu_gdb_set_reg() move
6
into gdbstub64.c, this means that they're now compiled only for
7
TARGET_AARCH64 rather than always. That is the only case when they
8
would ever be used, but it does mean that the ifdef in
9
arm_cpu_register_gdb_regs_for_features() needs to be adjusted to
10
match.
4
11
5
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>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200522145520.6778-7-peter.maydell@linaro.org
15
Message-id: 20210921162901.17508-4-peter.maydell@linaro.org
8
---
16
---
9
target/arm/neon-dp.decode | 20 ++++++
17
target/arm/internals.h | 7 ++
10
target/arm/translate-neon.inc.c | 15 +++++
18
target/arm/gdbstub.c | 130 ++++++++++++++++++++
11
target/arm/translate.c | 110 +-------------------------------
19
target/arm/gdbstub64.c | 140 +++++++++++++++++++++
12
3 files changed, 37 insertions(+), 108 deletions(-)
20
target/arm/helper.c | 271 -----------------------------------------
21
4 files changed, 277 insertions(+), 271 deletions(-)
13
22
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
23
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/neon-dp.decode
25
--- a/target/arm/internals.h
17
+++ b/target/arm/neon-dp.decode
26
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ VQSHRUN_16_2sh 1111 001 1 1 . ...... .... 1000 . 0 . 1 .... @2reg_shrn_h
27
@@ -XXX,XX +XXX,XX @@ static inline uint64_t pmu_counter_mask(CPUARMState *env)
19
VQRSHRUN_64_2sh 1111 001 1 1 . ...... .... 1000 . 1 . 1 .... @2reg_shrn_d
28
return (1 << 31) | ((1 << pmu_num_counters(env)) - 1);
20
VQRSHRUN_32_2sh 1111 001 1 1 . ...... .... 1000 . 1 . 1 .... @2reg_shrn_s
29
}
21
VQRSHRUN_16_2sh 1111 001 1 1 . ...... .... 1000 . 1 . 1 .... @2reg_shrn_h
30
22
+
31
+#ifdef TARGET_AARCH64
23
+# VQSHRN with signed input
32
+int arm_gdb_get_svereg(CPUARMState *env, GByteArray *buf, int reg);
24
+VQSHRN_S64_2sh 1111 001 0 1 . ...... .... 1001 . 0 . 1 .... @2reg_shrn_d
33
+int arm_gdb_set_svereg(CPUARMState *env, uint8_t *buf, int reg);
25
+VQSHRN_S32_2sh 1111 001 0 1 . ...... .... 1001 . 0 . 1 .... @2reg_shrn_s
34
+int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg);
26
+VQSHRN_S16_2sh 1111 001 0 1 . ...... .... 1001 . 0 . 1 .... @2reg_shrn_h
35
+int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg);
27
+
36
+#endif
28
+# VQRSHRN with signed input
37
+
29
+VQRSHRN_S64_2sh 1111 001 0 1 . ...... .... 1001 . 1 . 1 .... @2reg_shrn_d
38
#endif
30
+VQRSHRN_S32_2sh 1111 001 0 1 . ...... .... 1001 . 1 . 1 .... @2reg_shrn_s
39
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
31
+VQRSHRN_S16_2sh 1111 001 0 1 . ...... .... 1001 . 1 . 1 .... @2reg_shrn_h
32
+
33
+# VQSHRN with unsigned input
34
+VQSHRN_U64_2sh 1111 001 1 1 . ...... .... 1001 . 0 . 1 .... @2reg_shrn_d
35
+VQSHRN_U32_2sh 1111 001 1 1 . ...... .... 1001 . 0 . 1 .... @2reg_shrn_s
36
+VQSHRN_U16_2sh 1111 001 1 1 . ...... .... 1001 . 0 . 1 .... @2reg_shrn_h
37
+
38
+# VQRSHRN with unsigned input
39
+VQRSHRN_U64_2sh 1111 001 1 1 . ...... .... 1001 . 1 . 1 .... @2reg_shrn_d
40
+VQRSHRN_U32_2sh 1111 001 1 1 . ...... .... 1001 . 1 . 1 .... @2reg_shrn_s
41
+VQRSHRN_U16_2sh 1111 001 1 1 . ...... .... 1001 . 1 . 1 .... @2reg_shrn_h
42
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
43
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/translate-neon.inc.c
41
--- a/target/arm/gdbstub.c
45
+++ b/target/arm/translate-neon.inc.c
42
+++ b/target/arm/gdbstub.c
46
@@ -XXX,XX +XXX,XX @@ DO_2SN_32(VQSHRUN_16, gen_helper_neon_shl_s16, gen_helper_neon_unarrow_sat8)
43
@@ -XXX,XX +XXX,XX @@
47
DO_2SN_64(VQRSHRUN_64, gen_helper_neon_rshl_s64, gen_helper_neon_unarrow_sat32)
44
*/
48
DO_2SN_32(VQRSHRUN_32, gen_helper_neon_rshl_s32, gen_helper_neon_unarrow_sat16)
45
#include "qemu/osdep.h"
49
DO_2SN_32(VQRSHRUN_16, gen_helper_neon_rshl_s16, gen_helper_neon_unarrow_sat8)
46
#include "cpu.h"
50
+DO_2SN_64(VQSHRN_S64, gen_sshl_i64, gen_helper_neon_narrow_sat_s32)
47
+#include "internals.h"
51
+DO_2SN_32(VQSHRN_S32, gen_sshl_i32, gen_helper_neon_narrow_sat_s16)
48
#include "exec/gdbstub.h"
52
+DO_2SN_32(VQSHRN_S16, gen_helper_neon_shl_s16, gen_helper_neon_narrow_sat_s8)
49
53
+
50
typedef struct RegisterSysregXmlParam {
54
+DO_2SN_64(VQRSHRN_S64, gen_helper_neon_rshl_s64, gen_helper_neon_narrow_sat_s32)
51
@@ -XXX,XX +XXX,XX @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
55
+DO_2SN_32(VQRSHRN_S32, gen_helper_neon_rshl_s32, gen_helper_neon_narrow_sat_s16)
52
return 0;
56
+DO_2SN_32(VQRSHRN_S16, gen_helper_neon_rshl_s16, gen_helper_neon_narrow_sat_s8)
53
}
57
+
54
58
+DO_2SN_64(VQSHRN_U64, gen_ushl_i64, gen_helper_neon_narrow_sat_u32)
55
+static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
59
+DO_2SN_32(VQSHRN_U32, gen_ushl_i32, gen_helper_neon_narrow_sat_u16)
56
+{
60
+DO_2SN_32(VQSHRN_U16, gen_helper_neon_shl_u16, gen_helper_neon_narrow_sat_u8)
57
+ ARMCPU *cpu = env_archcpu(env);
61
+
58
+ int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
62
+DO_2SN_64(VQRSHRN_U64, gen_helper_neon_rshl_u64, gen_helper_neon_narrow_sat_u32)
59
+
63
+DO_2SN_32(VQRSHRN_U32, gen_helper_neon_rshl_u32, gen_helper_neon_narrow_sat_u16)
60
+ /* VFP data registers are always little-endian. */
64
+DO_2SN_32(VQRSHRN_U16, gen_helper_neon_rshl_u16, gen_helper_neon_narrow_sat_u8)
61
+ if (reg < nregs) {
65
diff --git a/target/arm/translate.c b/target/arm/translate.c
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
66
index XXXXXXX..XXXXXXX 100644
192
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/translate.c
193
--- a/target/arm/gdbstub64.c
68
+++ b/target/arm/translate.c
194
+++ b/target/arm/gdbstub64.c
69
@@ -XXX,XX +XXX,XX @@ static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
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
348
index XXXXXXX..XXXXXXX 100644
349
--- a/target/arm/helper.c
350
+++ b/target/arm/helper.c
351
@@ -XXX,XX +XXX,XX @@
352
#include "trace.h"
353
#include "cpu.h"
354
#include "internals.h"
355
-#include "exec/gdbstub.h"
356
#include "exec/helper-proto.h"
357
#include "qemu/host-utils.h"
358
#include "qemu/main-loop.h"
359
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
360
static void switch_mode(CPUARMState *env, int mode);
361
static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx);
362
363
-static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
364
-{
365
- ARMCPU *cpu = env_archcpu(env);
366
- int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
367
-
368
- /* VFP data registers are always little-endian. */
369
- if (reg < nregs) {
370
- return gdb_get_reg64(buf, *aa32_vfp_dreg(env, reg));
371
- }
372
- if (arm_feature(env, ARM_FEATURE_NEON)) {
373
- /* Aliases for Q regs. */
374
- nregs += 16;
375
- if (reg < nregs) {
376
- uint64_t *q = aa32_vfp_qreg(env, reg - 32);
377
- return gdb_get_reg128(buf, q[0], q[1]);
378
- }
379
- }
380
- switch (reg - nregs) {
381
- case 0:
382
- return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]);
383
- case 1:
384
- return gdb_get_reg32(buf, vfp_get_fpscr(env));
385
- case 2:
386
- return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]);
387
- }
388
- return 0;
389
-}
390
-
391
-static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
392
-{
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,
70
}
471
}
71
}
472
}
72
473
73
-static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
474
-/**
74
- int q, int u)
475
- * arm_get/set_gdb_*: get/set a gdb register
75
-{
476
- * @env: the CPU state
76
- if (q) {
477
- * @buf: a buffer to copy to/from
77
- if (u) {
478
- * @reg: register number (offset from start of group)
78
- switch (size) {
479
- *
79
- case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
480
- * We return the number of bytes copied
80
- case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
481
- */
81
- default: abort();
482
-
82
- }
483
-static int arm_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg)
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));
83
- } else {
494
- } else {
84
- switch (size) {
495
- return gdb_get_reg32(buf, (uint32_t)read_raw_cp_reg(env, ri));
85
- case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
496
- }
86
- case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
497
- }
87
- default: abort();
498
- return 0;
88
- }
499
-}
89
- }
500
-
90
- } else {
501
-static int arm_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg)
91
- if (u) {
502
-{
92
- switch (size) {
503
- return 0;
93
- case 1: gen_helper_neon_shl_u16(var, var, shift); break;
504
-}
94
- case 2: gen_ushl_i32(var, var, shift); break;
505
-
95
- default: abort();
506
-#ifdef TARGET_AARCH64
96
- }
507
-static int arm_gdb_get_svereg(CPUARMState *env, GByteArray *buf, int reg)
97
- } else {
508
-{
98
- switch (size) {
509
- ARMCPU *cpu = env_archcpu(env);
99
- case 1: gen_helper_neon_shl_s16(var, var, shift); break;
510
-
100
- case 2: gen_sshl_i32(var, var, shift); break;
511
- switch (reg) {
101
- default: abort();
512
- /* The first 32 registers are the zregs */
102
- }
513
- case 0 ... 31:
103
- }
514
- {
104
- }
515
- int vq, len = 0;
105
-}
516
- for (vq = 0; vq < cpu->sve_max_vq; vq++) {
106
-
517
- len += gdb_get_reg128(buf,
107
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
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)
108
{
603
{
109
if (u) {
604
/* Return true if the regdef would cause an assertion if you called
110
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
605
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
111
case 6: /* VQSHLU */
606
#endif
112
case 7: /* VQSHL */
607
}
113
case 8: /* VSHRN, VRSHRN, VQSHRUN, VQRSHRUN */
608
114
+ case 9: /* VQSHRN, VQRSHRN */
609
-void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
115
return 1; /* handled by decodetree */
610
-{
116
default:
611
- CPUState *cs = CPU(cpu);
117
break;
612
- CPUARMState *env = &cpu->env;
118
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
613
-
119
size--;
614
- if (arm_feature(env, ARM_FEATURE_AARCH64)) {
120
}
615
- /*
121
shift = (insn >> 16) & ((1 << (3 + size)) - 1);
616
- * The lower part of each SVE register aliases to the FPU
122
- if (op < 10) {
617
- * registers so we don't need to include both.
123
- /* Shift by immediate and narrow:
618
- */
124
- VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
619
-#ifdef TARGET_AARCH64
125
- int input_unsigned = (op == 8) ? !u : u;
620
- if (isar_feature_aa64_sve(&cpu->isar)) {
126
- if (rm & 1) {
621
- gdb_register_coprocessor(cs, arm_gdb_get_svereg, arm_gdb_set_svereg,
127
- return 1;
622
- arm_gen_dynamic_svereg_xml(cs, cs->gdb_num_regs),
128
- }
623
- "sve-registers.xml", 0);
129
- shift = shift - (1 << (size + 3));
624
- } else
130
- size++;
625
-#endif
131
- if (size == 3) {
626
- {
132
- tmp64 = tcg_const_i64(shift);
627
- gdb_register_coprocessor(cs, aarch64_fpu_gdb_get_reg,
133
- neon_load_reg64(cpu_V0, rm);
628
- aarch64_fpu_gdb_set_reg,
134
- neon_load_reg64(cpu_V1, rm + 1);
629
- 34, "aarch64-fpu.xml", 0);
135
- for (pass = 0; pass < 2; pass++) {
630
- }
136
- TCGv_i64 in;
631
- } else if (arm_feature(env, ARM_FEATURE_NEON)) {
137
- if (pass == 0) {
632
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
138
- in = cpu_V0;
633
- 51, "arm-neon.xml", 0);
139
- } else {
634
- } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
140
- in = cpu_V1;
635
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
141
- }
636
- 35, "arm-vfp3.xml", 0);
142
- if (q) {
637
- } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
143
- if (input_unsigned) {
638
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
144
- gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
639
- 19, "arm-vfp.xml", 0);
145
- } else {
640
- }
146
- gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
641
- gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
147
- }
642
- arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs),
148
- } else {
643
- "system-registers.xml", 0);
149
- if (input_unsigned) {
644
-
150
- gen_ushl_i64(cpu_V0, in, tmp64);
645
-}
151
- } else {
646
-
152
- gen_sshl_i64(cpu_V0, in, tmp64);
647
/* Sort alphabetically by type name, except for "any". */
153
- }
648
static gint arm_cpu_list_compare(gconstpointer a, gconstpointer b)
154
- }
649
{
155
- tmp = tcg_temp_new_i32();
156
- gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
157
- neon_store_reg(rd, pass, tmp);
158
- } /* for pass */
159
- tcg_temp_free_i64(tmp64);
160
- } else {
161
- if (size == 1) {
162
- imm = (uint16_t)shift;
163
- imm |= imm << 16;
164
- } else {
165
- /* size == 2 */
166
- imm = (uint32_t)shift;
167
- }
168
- tmp2 = tcg_const_i32(imm);
169
- tmp4 = neon_load_reg(rm + 1, 0);
170
- tmp5 = neon_load_reg(rm + 1, 1);
171
- for (pass = 0; pass < 2; pass++) {
172
- if (pass == 0) {
173
- tmp = neon_load_reg(rm, 0);
174
- } else {
175
- tmp = tmp4;
176
- }
177
- gen_neon_shift_narrow(size, tmp, tmp2, q,
178
- input_unsigned);
179
- if (pass == 0) {
180
- tmp3 = neon_load_reg(rm, 1);
181
- } else {
182
- tmp3 = tmp5;
183
- }
184
- gen_neon_shift_narrow(size, tmp3, tmp2, q,
185
- input_unsigned);
186
- tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
187
- tcg_temp_free_i32(tmp);
188
- tcg_temp_free_i32(tmp3);
189
- tmp = tcg_temp_new_i32();
190
- gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
191
- neon_store_reg(rd, pass, tmp);
192
- } /* for pass */
193
- tcg_temp_free_i32(tmp2);
194
- }
195
- } else if (op == 10) {
196
+ if (op == 10) {
197
/* VSHLL, VMOVL */
198
if (q || (rd & 1)) {
199
return 1;
200
--
650
--
201
2.20.1
651
2.20.1
202
652
203
653
diff view generated by jsdifflib
1
Convert the VSHLL and VMOVL insns from the 2-reg-shift group
1
Currently we send VFP XML which includes D0..D15 or D0..D31, plus
2
to decodetree. Since the loop always has two passes, we unroll
2
FPSID, FPSCR and FPEXC. The upstream GDB tolerates this, but its
3
it to avoid the awkward reassignment of one TCGv to another.
3
definition of this XML feature does not include FPSID or FPEXC. In
4
particular, for M-profile cores there are no FPSID or FPEXC
5
registers, so advertising those is wrong.
6
7
Move FPSID and FPEXC into their own bit of XML which we only send for
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.)
4
16
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200522145520.6778-8-peter.maydell@linaro.org
19
Message-id: 20210921162901.17508-5-peter.maydell@linaro.org
8
---
20
---
9
target/arm/neon-dp.decode | 16 +++++++
21
configs/targets/aarch64-softmmu.mak | 2 +-
10
target/arm/translate-neon.inc.c | 81 +++++++++++++++++++++++++++++++++
22
configs/targets/arm-linux-user.mak | 2 +-
11
target/arm/translate.c | 46 +------------------
23
configs/targets/arm-softmmu.mak | 2 +-
12
3 files changed, 99 insertions(+), 44 deletions(-)
24
configs/targets/armeb-linux-user.mak | 2 +-
13
25
target/arm/gdbstub.c | 56 ++++++++++++++++++++--------
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
26
gdb-xml/arm-neon.xml | 2 -
15
index XXXXXXX..XXXXXXX 100644
27
gdb-xml/arm-vfp-sysregs.xml | 17 +++++++++
16
--- a/target/arm/neon-dp.decode
28
gdb-xml/arm-vfp.xml | 2 -
17
+++ b/target/arm/neon-dp.decode
29
gdb-xml/arm-vfp3.xml | 2 -
18
@@ -XXX,XX +XXX,XX @@ VMINNM_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 1 .... @3same_fp
30
9 files changed, 61 insertions(+), 26 deletions(-)
19
&2reg_shift vm=%vm_dp vd=%vd_dp size=1 q=0 \
31
create mode 100644 gdb-xml/arm-vfp-sysregs.xml
20
shift=%neon_rshift_i3
32
21
33
diff --git a/configs/targets/aarch64-softmmu.mak b/configs/targets/aarch64-softmmu.mak
22
+# Long left shifts: again Q is part of opcode decode
34
index XXXXXXX..XXXXXXX 100644
23
+@2reg_shll_s .... ... . . . 1 shift:5 .... .... 0 . . . .... \
35
--- a/configs/targets/aarch64-softmmu.mak
24
+ &2reg_shift vm=%vm_dp vd=%vd_dp size=2 q=0
36
+++ b/configs/targets/aarch64-softmmu.mak
25
+@2reg_shll_h .... ... . . . 01 shift:4 .... .... 0 . . . .... \
37
@@ -XXX,XX +XXX,XX @@
26
+ &2reg_shift vm=%vm_dp vd=%vd_dp size=1 q=0
38
TARGET_ARCH=aarch64
27
+@2reg_shll_b .... ... . . . 001 shift:3 .... .... 0 . . . .... \
39
TARGET_BASE_ARCH=arm
28
+ &2reg_shift vm=%vm_dp vd=%vd_dp size=0 q=0
40
TARGET_SUPPORTS_MTTCG=y
29
+
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
30
VSHR_S_2sh 1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_d
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
31
VSHR_S_2sh 1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_s
43
TARGET_NEED_FDT=y
32
VSHR_S_2sh 1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_h
44
diff --git a/configs/targets/arm-linux-user.mak b/configs/targets/arm-linux-user.mak
33
@@ -XXX,XX +XXX,XX @@ VQSHRN_U16_2sh 1111 001 1 1 . ...... .... 1001 . 0 . 1 .... @2reg_shrn_h
45
index XXXXXXX..XXXXXXX 100644
34
VQRSHRN_U64_2sh 1111 001 1 1 . ...... .... 1001 . 1 . 1 .... @2reg_shrn_d
46
--- a/configs/targets/arm-linux-user.mak
35
VQRSHRN_U32_2sh 1111 001 1 1 . ...... .... 1001 . 1 . 1 .... @2reg_shrn_s
47
+++ b/configs/targets/arm-linux-user.mak
36
VQRSHRN_U16_2sh 1111 001 1 1 . ...... .... 1001 . 1 . 1 .... @2reg_shrn_h
48
@@ -XXX,XX +XXX,XX @@
37
+
49
TARGET_ARCH=arm
38
+VSHLL_S_2sh 1111 001 0 1 . ...... .... 1010 . 0 . 1 .... @2reg_shll_s
50
TARGET_SYSTBL_ABI=common,oabi
39
+VSHLL_S_2sh 1111 001 0 1 . ...... .... 1010 . 0 . 1 .... @2reg_shll_h
51
TARGET_SYSTBL=syscall.tbl
40
+VSHLL_S_2sh 1111 001 0 1 . ...... .... 1010 . 0 . 1 .... @2reg_shll_b
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
41
+
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
42
+VSHLL_U_2sh 1111 001 1 1 . ...... .... 1010 . 0 . 1 .... @2reg_shll_s
54
TARGET_HAS_BFLT=y
43
+VSHLL_U_2sh 1111 001 1 1 . ...... .... 1010 . 0 . 1 .... @2reg_shll_h
55
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
44
+VSHLL_U_2sh 1111 001 1 1 . ...... .... 1010 . 0 . 1 .... @2reg_shll_b
56
diff --git a/configs/targets/arm-softmmu.mak b/configs/targets/arm-softmmu.mak
45
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
57
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
58
--- a/configs/targets/arm-softmmu.mak
47
--- a/target/arm/translate-neon.inc.c
59
+++ b/configs/targets/arm-softmmu.mak
48
+++ b/target/arm/translate-neon.inc.c
60
@@ -XXX,XX +XXX,XX @@
49
@@ -XXX,XX +XXX,XX @@ DO_2SN_32(VQSHRN_U16, gen_helper_neon_shl_u16, gen_helper_neon_narrow_sat_u8)
61
TARGET_ARCH=arm
50
DO_2SN_64(VQRSHRN_U64, gen_helper_neon_rshl_u64, gen_helper_neon_narrow_sat_u32)
62
TARGET_SUPPORTS_MTTCG=y
51
DO_2SN_32(VQRSHRN_U32, gen_helper_neon_rshl_u32, gen_helper_neon_narrow_sat_u16)
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
52
DO_2SN_32(VQRSHRN_U16, gen_helper_neon_rshl_u16, gen_helper_neon_narrow_sat_u8)
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
53
+
65
TARGET_NEED_FDT=y
54
+static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
66
diff --git a/configs/targets/armeb-linux-user.mak b/configs/targets/armeb-linux-user.mak
55
+ NeonGenWidenFn *widenfn, bool u)
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
}
84
switch (reg - nregs) {
85
case 0:
86
- return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]);
87
- case 1:
88
return gdb_get_reg32(buf, vfp_get_fpscr(env));
89
- case 2:
90
- return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]);
91
}
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
+ }
102
+ return 0;
103
+}
104
+
105
+static int vfp_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg)
56
+{
106
+{
57
+ TCGv_i64 tmp;
107
+ switch (reg) {
58
+ TCGv_i32 rm0, rm1;
108
+ case 0:
59
+ uint64_t widen_mask = 0;
109
+ return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]);
60
+
110
+ case 1:
61
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
111
+ return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]);
62
+ return false;
63
+ }
112
+ }
64
+
113
+ return 0;
65
+ /* UNDEF accesses to D16-D31 if they don't exist. */
66
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
67
+ ((a->vd | a->vm) & 0x10)) {
68
+ return false;
69
+ }
70
+
71
+ if (a->vd & 1) {
72
+ return false;
73
+ }
74
+
75
+ if (!vfp_access_check(s)) {
76
+ return true;
77
+ }
78
+
79
+ /*
80
+ * This is a widen-and-shift operation. The shift is always less
81
+ * than the width of the source type, so after widening the input
82
+ * vector we can simply shift the whole 64-bit widened register,
83
+ * and then clear the potential overflow bits resulting from left
84
+ * bits of the narrow input appearing as right bits of the left
85
+ * neighbour narrow input. Calculate a mask of bits to clear.
86
+ */
87
+ if ((a->shift != 0) && (a->size < 2 || u)) {
88
+ int esize = 8 << a->size;
89
+ widen_mask = MAKE_64BIT_MASK(0, esize);
90
+ widen_mask >>= esize - a->shift;
91
+ widen_mask = dup_const(a->size + 1, widen_mask);
92
+ }
93
+
94
+ rm0 = neon_load_reg(a->vm, 0);
95
+ rm1 = neon_load_reg(a->vm, 1);
96
+ tmp = tcg_temp_new_i64();
97
+
98
+ widenfn(tmp, rm0);
99
+ if (a->shift != 0) {
100
+ tcg_gen_shli_i64(tmp, tmp, a->shift);
101
+ tcg_gen_andi_i64(tmp, tmp, ~widen_mask);
102
+ }
103
+ neon_store_reg64(tmp, a->vd);
104
+
105
+ widenfn(tmp, rm1);
106
+ if (a->shift != 0) {
107
+ tcg_gen_shli_i64(tmp, tmp, a->shift);
108
+ tcg_gen_andi_i64(tmp, tmp, ~widen_mask);
109
+ }
110
+ neon_store_reg64(tmp, a->vd + 1);
111
+ tcg_temp_free_i64(tmp);
112
+ return true;
113
+}
114
+}
114
+
115
+
115
+static bool trans_VSHLL_S_2sh(DisasContext *s, arg_2reg_shift *a)
116
+static int vfp_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg)
116
+{
117
+{
117
+ NeonGenWidenFn *widenfn[] = {
118
+ switch (reg) {
118
+ gen_helper_neon_widen_s8,
119
case 0:
119
+ gen_helper_neon_widen_s16,
120
env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf);
120
+ tcg_gen_ext_i32_i64,
121
return 4;
121
+ };
122
case 1:
122
+ return do_vshll_2sh(s, a, widenfn[a->size], false);
123
- vfp_set_fpscr(env, ldl_p(buf));
123
+}
124
- return 4;
124
+
125
- case 2:
125
+static bool trans_VSHLL_U_2sh(DisasContext *s, arg_2reg_shift *a)
126
env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30);
126
+{
127
return 4;
127
+ NeonGenWidenFn *widenfn[] = {
128
}
128
+ gen_helper_neon_widen_u8,
129
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
129
+ gen_helper_neon_widen_u16,
130
34, "aarch64-fpu.xml", 0);
130
+ tcg_gen_extu_i32_i64,
131
}
131
+ };
132
#endif
132
+ return do_vshll_2sh(s, a, widenfn[a->size], true);
133
- } else if (arm_feature(env, ARM_FEATURE_NEON)) {
133
+}
134
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
134
diff --git a/target/arm/translate.c b/target/arm/translate.c
135
- 51, "arm-neon.xml", 0);
135
index XXXXXXX..XXXXXXX 100644
136
- } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
136
--- a/target/arm/translate.c
137
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
137
+++ b/target/arm/translate.c
138
- 35, "arm-vfp3.xml", 0);
138
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
139
- } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
139
case 7: /* VQSHL */
140
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
140
case 8: /* VSHRN, VRSHRN, VQSHRUN, VQRSHRUN */
141
- 19, "arm-vfp.xml", 0);
141
case 9: /* VQSHRN, VQRSHRN */
142
+ } else {
142
+ case 10: /* VSHLL, including VMOVL */
143
+ if (arm_feature(env, ARM_FEATURE_NEON)) {
143
return 1; /* handled by decodetree */
144
+ gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
144
default:
145
+ 49, "arm-neon.xml", 0);
145
break;
146
+ } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
146
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
147
+ gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
147
size--;
148
+ 33, "arm-vfp3.xml", 0);
148
}
149
+ } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
149
shift = (insn >> 16) & ((1 << (3 + size)) - 1);
150
+ gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
150
- if (op == 10) {
151
+ 17, "arm-vfp.xml", 0);
151
- /* VSHLL, VMOVL */
152
+ }
152
- if (q || (rd & 1)) {
153
+ if (!arm_feature(env, ARM_FEATURE_M)) {
153
- return 1;
154
+ /*
154
- }
155
+ * A and R profile have FP sysregs FPEXC and FPSID that we
155
- tmp = neon_load_reg(rm, 0);
156
+ * expose to gdb.
156
- tmp2 = neon_load_reg(rm, 1);
157
+ */
157
- for (pass = 0; pass < 2; pass++) {
158
+ gdb_register_coprocessor(cs, vfp_gdb_get_sysreg, vfp_gdb_set_sysreg,
158
- if (pass == 1)
159
+ 2, "arm-vfp-sysregs.xml", 0);
159
- tmp = tmp2;
160
+ }
160
-
161
}
161
- gen_neon_widen(cpu_V0, tmp, size, u);
162
gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
162
-
163
arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs),
163
- if (shift != 0) {
164
diff --git a/gdb-xml/arm-neon.xml b/gdb-xml/arm-neon.xml
164
- /* The shift is less than the width of the source
165
index XXXXXXX..XXXXXXX 100644
165
- type, so we can just shift the whole register. */
166
--- a/gdb-xml/arm-neon.xml
166
- tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
167
+++ b/gdb-xml/arm-neon.xml
167
- /* Widen the result of shift: we need to clear
168
@@ -XXX,XX +XXX,XX @@
168
- * the potential overflow bits resulting from
169
<reg name="q14" bitsize="128" type="neon_q"/>
169
- * left bits of the narrow input appearing as
170
<reg name="q15" bitsize="128" type="neon_q"/>
170
- * right bits of left the neighbour narrow
171
171
- * input. */
172
- <reg name="fpsid" bitsize="32" type="int" group="float"/>
172
- if (size < 2 || !u) {
173
<reg name="fpscr" bitsize="32" type="int" group="float"/>
173
- uint64_t imm64;
174
- <reg name="fpexc" bitsize="32" type="int" group="float"/>
174
- if (size == 0) {
175
</feature>
175
- imm = (0xffu >> (8 - shift));
176
diff --git a/gdb-xml/arm-vfp-sysregs.xml b/gdb-xml/arm-vfp-sysregs.xml
176
- imm |= imm << 16;
177
new file mode 100644
177
- } else if (size == 1) {
178
index XXXXXXX..XXXXXXX
178
- imm = 0xffff >> (16 - shift);
179
--- /dev/null
179
- } else {
180
+++ b/gdb-xml/arm-vfp-sysregs.xml
180
- /* size == 2 */
181
@@ -XXX,XX +XXX,XX @@
181
- imm = 0xffffffff >> (32 - shift);
182
+<?xml version="1.0"?>
182
- }
183
+<!-- Copyright (C) 2021 Linaro Ltd.
183
- if (size < 2) {
184
+
184
- imm64 = imm | (((uint64_t)imm) << 32);
185
+ Copying and distribution of this file, with or without modification,
185
- } else {
186
+ are permitted in any medium without royalty provided the copyright
186
- imm64 = imm;
187
+ notice and this notice are preserved.
187
- }
188
+
188
- tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
189
+ These are A/R profile VFP system registers. Debugger users probably
189
- }
190
+ don't really care about these, but because we used to (incorrectly)
190
- }
191
+ provide them to gdb in the org.gnu.gdb.arm.vfp XML we continue
191
- neon_store_reg64(cpu_V0, rd + pass);
192
+ to do so via this separate XML.
192
- }
193
+ -->
193
- } else if (op >= 14) {
194
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
194
+ if (op >= 14) {
195
+<feature name="org.qemu.gdb.arm.vfp-sysregs">
195
/* VCVT fixed-point. */
196
+ <reg name="fpsid" bitsize="32" type="int" group="float"/>
196
TCGv_ptr fpst;
197
+ <reg name="fpexc" bitsize="32" type="int" group="float"/>
197
TCGv_i32 shiftv;
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>
198
--
223
--
199
2.20.1
224
2.20.1
200
225
201
226
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The function scsi_bus_new() creates a new SCSI bus; callers can
2
2
either pass in a name argument to specify the name of the new bus, or
3
Rather than passing an opcode to a helper, fully decode the
3
they can pass in NULL to allow the bus to be given an automatically
4
operation at translate time. Use clear_tail_16 to zap the
4
generated unique name. Almost all callers want to use the
5
balance of the SVE register with the AdvSIMD write.
5
autogenerated name; the only exception is the virtio-scsi device.
6
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Taking a name argument that should almost always be NULL is an
8
Message-id: 20200514212831.31248-6-richard.henderson@linaro.org
8
easy-to-misuse API design -- it encourages callers to think perhaps
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
they should pass in some standard name like "scsi" or "scsi-bus". We
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
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
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
11
---
32
---
12
target/arm/helper.h | 5 +-
33
include/hw/scsi/scsi.h | 30 ++++++++++++++++++++++++++++--
13
target/arm/neon-dp.decode | 6 +-
34
hw/scsi/esp-pci.c | 2 +-
14
target/arm/crypto_helper.c | 99 +++++++++++++++++++++------------
35
hw/scsi/esp.c | 2 +-
15
target/arm/translate-a64.c | 29 ++++------
36
hw/scsi/lsi53c895a.c | 2 +-
16
target/arm/translate-neon.inc.c | 46 ++++-----------
37
hw/scsi/megasas.c | 3 +--
17
5 files changed, 93 insertions(+), 92 deletions(-)
38
hw/scsi/mptsas.c | 2 +-
18
39
hw/scsi/scsi-bus.c | 4 ++--
19
diff --git a/target/arm/helper.h b/target/arm/helper.h
40
hw/scsi/spapr_vscsi.c | 3 +--
20
index XXXXXXX..XXXXXXX 100644
41
hw/scsi/virtio-scsi.c | 4 ++--
21
--- a/target/arm/helper.h
42
hw/scsi/vmw_pvscsi.c | 3 +--
22
+++ b/target/arm/helper.h
43
hw/usb/dev-storage-bot.c | 3 +--
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(neon_qzip32, TCG_CALL_NO_RWG, void, ptr, ptr)
44
hw/usb/dev-storage-classic.c | 4 ++--
24
DEF_HELPER_FLAGS_4(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
45
hw/usb/dev-uas.c | 3 +--
25
DEF_HELPER_FLAGS_3(crypto_aesmc, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
46
13 files changed, 43 insertions(+), 22 deletions(-)
26
47
27
-DEF_HELPER_FLAGS_4(crypto_sha1_3reg, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
48
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
28
+DEF_HELPER_FLAGS_4(crypto_sha1su0, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
49
index XXXXXXX..XXXXXXX 100644
29
+DEF_HELPER_FLAGS_4(crypto_sha1c, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
50
--- a/include/hw/scsi/scsi.h
30
+DEF_HELPER_FLAGS_4(crypto_sha1p, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
51
+++ b/include/hw/scsi/scsi.h
31
+DEF_HELPER_FLAGS_4(crypto_sha1m, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
52
@@ -XXX,XX +XXX,XX @@ struct SCSIBus {
32
DEF_HELPER_FLAGS_3(crypto_sha1h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
53
const SCSIBusInfo *info;
33
DEF_HELPER_FLAGS_3(crypto_sha1su1, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
34
35
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/neon-dp.decode
38
+++ b/target/arm/neon-dp.decode
39
@@ -XXX,XX +XXX,XX @@ VQRDMLAH_3s 1111 001 1 0 . .. .... .... 1011 ... 1 .... @3same
40
@3same_crypto .... .... .... .... .... .... .... .... \
41
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0 q=1
42
43
-SHA1_3s 1111 001 0 0 . optype:2 .... .... 1100 . 1 . 0 .... \
44
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
45
+SHA1C_3s 1111 001 0 0 . 00 .... .... 1100 . 1 . 0 .... @3same_crypto
46
+SHA1P_3s 1111 001 0 0 . 01 .... .... 1100 . 1 . 0 .... @3same_crypto
47
+SHA1M_3s 1111 001 0 0 . 10 .... .... 1100 . 1 . 0 .... @3same_crypto
48
+SHA1SU0_3s 1111 001 0 0 . 11 .... .... 1100 . 1 . 0 .... @3same_crypto
49
SHA256H_3s 1111 001 1 0 . 00 .... .... 1100 . 1 . 0 .... @3same_crypto
50
SHA256H2_3s 1111 001 1 0 . 01 .... .... 1100 . 1 . 0 .... @3same_crypto
51
SHA256SU1_3s 1111 001 1 0 . 10 .... .... 1100 . 1 . 0 .... @3same_crypto
52
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/crypto_helper.c
55
+++ b/target/arm/crypto_helper.c
56
@@ -XXX,XX +XXX,XX @@ union CRYPTO_STATE {
57
};
54
};
58
55
59
#ifdef HOST_WORDS_BIGENDIAN
56
-void scsi_bus_new(SCSIBus *bus, size_t bus_size, DeviceState *host,
60
-#define CR_ST_BYTE(state, i) (state.bytes[(15 - (i)) ^ 8])
57
- const SCSIBusInfo *info, const char *bus_name);
61
-#define CR_ST_WORD(state, i) (state.words[(3 - (i)) ^ 2])
58
+/**
62
+#define CR_ST_BYTE(state, i) ((state).bytes[(15 - (i)) ^ 8])
59
+ * scsi_bus_init_named: Initialize a SCSI bus with the specified name
63
+#define CR_ST_WORD(state, i) ((state).words[(3 - (i)) ^ 2])
60
+ * @bus: SCSIBus object to initialize
64
#else
61
+ * @bus_size: size of @bus object
65
-#define CR_ST_BYTE(state, i) (state.bytes[i])
62
+ * @host: Device which owns the bus (generally the SCSI controller)
66
-#define CR_ST_WORD(state, i) (state.words[i])
63
+ * @info: structure defining callbacks etc for the controller
67
+#define CR_ST_BYTE(state, i) ((state).bytes[i])
64
+ * @bus_name: Name to use for this bus
68
+#define CR_ST_WORD(state, i) ((state).words[i])
65
+ *
69
#endif
66
+ * This in-place initializes @bus as a new SCSI bus with a name
70
67
+ * provided by the caller. It is the caller's responsibility to make
71
/*
68
+ * sure that name does not clash with the name of any other bus in the
72
@@ -XXX,XX +XXX,XX @@ static uint32_t maj(uint32_t x, uint32_t y, uint32_t z)
69
+ * system. Unless you need the new bus to have a specific name, you
73
return (x & y) | ((x | y) & z);
70
+ * should use scsi_bus_new() instead.
74
}
71
+ */
75
72
+void scsi_bus_init_named(SCSIBus *bus, size_t bus_size, DeviceState *host,
76
-void HELPER(crypto_sha1_3reg)(void *vd, void *vn, void *vm, uint32_t op)
73
+ const SCSIBusInfo *info, const char *bus_name);
77
+void HELPER(crypto_sha1su0)(void *vd, void *vn, void *vm, uint32_t desc)
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)
78
+{
83
+{
79
+ uint64_t *d = vd, *n = vn, *m = vm;
84
+ scsi_bus_init_named(bus, bus_size, host, info, NULL);
80
+ uint64_t d0, d1;
81
+
82
+ d0 = d[1] ^ d[0] ^ m[0];
83
+ d1 = n[0] ^ d[1] ^ m[1];
84
+ d[0] = d0;
85
+ d[1] = d1;
86
+
87
+ clear_tail_16(vd, desc);
88
+}
85
+}
89
+
86
90
+static inline void crypto_sha1_3reg(uint64_t *rd, uint64_t *rn,
87
static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
91
+ uint64_t *rm, uint32_t desc,
92
+ uint32_t (*fn)(union CRYPTO_STATE *d))
93
{
88
{
94
- uint64_t *rd = vd;
89
diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c
95
- uint64_t *rn = vn;
90
index XXXXXXX..XXXXXXX 100644
96
- uint64_t *rm = vm;
91
--- a/hw/scsi/esp-pci.c
97
union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
92
+++ b/hw/scsi/esp-pci.c
98
union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
93
@@ -XXX,XX +XXX,XX @@ static void esp_pci_scsi_realize(PCIDevice *dev, Error **errp)
99
union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
94
pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->io);
100
+ int i;
95
s->irq = pci_allocate_irq(dev);
101
96
102
- if (op == 3) { /* sha1su0 */
97
- scsi_bus_new(&s->bus, sizeof(s->bus), d, &esp_pci_scsi_info, NULL);
103
- d.l[0] ^= d.l[1] ^ m.l[0];
98
+ scsi_bus_init(&s->bus, sizeof(s->bus), d, &esp_pci_scsi_info);
104
- d.l[1] ^= n.l[0] ^ m.l[1];
99
}
105
- } else {
100
106
- int i;
101
static void esp_pci_scsi_exit(PCIDevice *d)
107
+ for (i = 0; i < 4; i++) {
102
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
108
+ uint32_t t = fn(&d);
103
index XXXXXXX..XXXXXXX 100644
109
104
--- a/hw/scsi/esp.c
110
- for (i = 0; i < 4; i++) {
105
+++ b/hw/scsi/esp.c
111
- uint32_t t;
106
@@ -XXX,XX +XXX,XX @@ static void sysbus_esp_realize(DeviceState *dev, Error **errp)
112
+ t += rol32(CR_ST_WORD(d, 0), 5) + CR_ST_WORD(n, 0)
107
113
+ + CR_ST_WORD(m, i);
108
qdev_init_gpio_in(dev, sysbus_esp_gpio_demux, 2);
114
109
115
- switch (op) {
110
- scsi_bus_new(&s->bus, sizeof(s->bus), dev, &esp_scsi_info, NULL);
116
- case 0: /* sha1c */
111
+ scsi_bus_init(&s->bus, sizeof(s->bus), dev, &esp_scsi_info);
117
- t = cho(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
112
}
118
- break;
113
119
- case 1: /* sha1p */
114
static void sysbus_esp_hard_reset(DeviceState *dev)
120
- t = par(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
115
diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
121
- break;
116
index XXXXXXX..XXXXXXX 100644
122
- case 2: /* sha1m */
117
--- a/hw/scsi/lsi53c895a.c
123
- t = maj(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
118
+++ b/hw/scsi/lsi53c895a.c
124
- break;
119
@@ -XXX,XX +XXX,XX @@ static void lsi_scsi_realize(PCIDevice *dev, Error **errp)
125
- default:
120
pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ram_io);
126
- g_assert_not_reached();
121
QTAILQ_INIT(&s->queue);
127
- }
122
128
- t += rol32(CR_ST_WORD(d, 0), 5) + CR_ST_WORD(n, 0)
123
- scsi_bus_new(&s->bus, sizeof(s->bus), d, &lsi_scsi_info, NULL);
129
- + CR_ST_WORD(m, i);
124
+ scsi_bus_init(&s->bus, sizeof(s->bus), d, &lsi_scsi_info);
130
-
125
}
131
- CR_ST_WORD(n, 0) = CR_ST_WORD(d, 3);
126
132
- CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2);
127
static void lsi_scsi_exit(PCIDevice *dev)
133
- CR_ST_WORD(d, 2) = ror32(CR_ST_WORD(d, 1), 2);
128
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
134
- CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0);
129
index XXXXXXX..XXXXXXX 100644
135
- CR_ST_WORD(d, 0) = t;
130
--- a/hw/scsi/megasas.c
136
- }
131
+++ b/hw/scsi/megasas.c
137
+ CR_ST_WORD(n, 0) = CR_ST_WORD(d, 3);
132
@@ -XXX,XX +XXX,XX @@ static void megasas_scsi_realize(PCIDevice *dev, Error **errp)
138
+ CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2);
133
s->frames[i].state = s;
139
+ CR_ST_WORD(d, 2) = ror32(CR_ST_WORD(d, 1), 2);
140
+ CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0);
141
+ CR_ST_WORD(d, 0) = t;
142
}
134
}
143
rd[0] = d.l[0];
135
144
rd[1] = d.l[1];
136
- scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
145
+
137
- &megasas_scsi_info, NULL);
146
+ clear_tail_16(rd, desc);
138
+ scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(dev), &megasas_scsi_info);
147
+}
139
}
148
+
140
149
+static uint32_t do_sha1c(union CRYPTO_STATE *d)
141
static Property megasas_properties_gen1[] = {
150
+{
142
diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c
151
+ return cho(CR_ST_WORD(*d, 1), CR_ST_WORD(*d, 2), CR_ST_WORD(*d, 3));
143
index XXXXXXX..XXXXXXX 100644
152
+}
144
--- a/hw/scsi/mptsas.c
153
+
145
+++ b/hw/scsi/mptsas.c
154
+void HELPER(crypto_sha1c)(void *vd, void *vn, void *vm, uint32_t desc)
146
@@ -XXX,XX +XXX,XX @@ static void mptsas_scsi_realize(PCIDevice *dev, Error **errp)
155
+{
147
156
+ crypto_sha1_3reg(vd, vn, vm, desc, do_sha1c);
148
s->request_bh = qemu_bh_new(mptsas_fetch_requests, s);
157
+}
149
158
+
150
- scsi_bus_new(&s->bus, sizeof(s->bus), &dev->qdev, &mptsas_scsi_info, NULL);
159
+static uint32_t do_sha1p(union CRYPTO_STATE *d)
151
+ scsi_bus_init(&s->bus, sizeof(s->bus), &dev->qdev, &mptsas_scsi_info);
160
+{
152
}
161
+ return par(CR_ST_WORD(*d, 1), CR_ST_WORD(*d, 2), CR_ST_WORD(*d, 3));
153
162
+}
154
static void mptsas_scsi_uninit(PCIDevice *dev)
163
+
155
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
164
+void HELPER(crypto_sha1p)(void *vd, void *vn, void *vm, uint32_t desc)
156
index XXXXXXX..XXXXXXX 100644
165
+{
157
--- a/hw/scsi/scsi-bus.c
166
+ crypto_sha1_3reg(vd, vn, vm, desc, do_sha1p);
158
+++ b/hw/scsi/scsi-bus.c
167
+}
159
@@ -XXX,XX +XXX,XX @@ void scsi_device_unit_attention_reported(SCSIDevice *s)
168
+
160
}
169
+static uint32_t do_sha1m(union CRYPTO_STATE *d)
161
170
+{
162
/* Create a scsi bus, and attach devices to it. */
171
+ return maj(CR_ST_WORD(*d, 1), CR_ST_WORD(*d, 2), CR_ST_WORD(*d, 3));
163
-void scsi_bus_new(SCSIBus *bus, size_t bus_size, DeviceState *host,
172
+}
164
- const SCSIBusInfo *info, const char *bus_name)
173
+
165
+void scsi_bus_init_named(SCSIBus *bus, size_t bus_size, DeviceState *host,
174
+void HELPER(crypto_sha1m)(void *vd, void *vn, void *vm, uint32_t desc)
166
+ const SCSIBusInfo *info, const char *bus_name)
175
+{
167
{
176
+ crypto_sha1_3reg(vd, vn, vm, desc, do_sha1m);
168
qbus_create_inplace(bus, bus_size, TYPE_SCSI_BUS, host, bus_name);
177
}
169
bus->busnr = next_scsi_bus++;
178
170
diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
179
void HELPER(crypto_sha1h)(void *vd, void *vm, uint32_t desc)
171
index XXXXXXX..XXXXXXX 100644
180
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
172
--- a/hw/scsi/spapr_vscsi.c
181
index XXXXXXX..XXXXXXX 100644
173
+++ b/hw/scsi/spapr_vscsi.c
182
--- a/target/arm/translate-a64.c
174
@@ -XXX,XX +XXX,XX @@ static void spapr_vscsi_realize(SpaprVioDevice *dev, Error **errp)
183
+++ b/target/arm/translate-a64.c
175
184
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
176
dev->crq.SendFunc = vscsi_do_crq;
185
177
186
switch (opcode) {
178
- scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
187
case 0: /* SHA1C */
179
- &vscsi_scsi_info, NULL);
188
+ genfn = gen_helper_crypto_sha1c;
180
+ scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(dev), &vscsi_scsi_info);
189
+ feature = dc_isar_feature(aa64_sha1, s);
181
190
+ break;
182
/* ibmvscsi SCSI bus does not allow hotplug. */
191
case 1: /* SHA1P */
183
qbus_set_hotplug_handler(BUS(&s->bus), NULL);
192
+ genfn = gen_helper_crypto_sha1p;
184
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
193
+ feature = dc_isar_feature(aa64_sha1, s);
185
index XXXXXXX..XXXXXXX 100644
194
+ break;
186
--- a/hw/scsi/virtio-scsi.c
195
case 2: /* SHA1M */
187
+++ b/hw/scsi/virtio-scsi.c
196
+ genfn = gen_helper_crypto_sha1m;
188
@@ -XXX,XX +XXX,XX @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp)
197
+ feature = dc_isar_feature(aa64_sha1, s);
198
+ break;
199
case 3: /* SHA1SU0 */
200
- genfn = NULL;
201
+ genfn = gen_helper_crypto_sha1su0;
202
feature = dc_isar_feature(aa64_sha1, s);
203
break;
204
case 4: /* SHA256H */
205
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
206
if (!fp_access_check(s)) {
207
return;
189
return;
208
}
190
}
209
-
191
210
- if (genfn) {
192
- scsi_bus_new(&s->bus, sizeof(s->bus), dev,
211
- gen_gvec_op3_ool(s, true, rd, rn, rm, 0, genfn);
193
- &virtio_scsi_scsi_info, vdev->bus_name);
212
- } else {
194
+ scsi_bus_init_named(&s->bus, sizeof(s->bus), dev,
213
- TCGv_i32 tcg_opcode = tcg_const_i32(opcode);
195
+ &virtio_scsi_scsi_info, vdev->bus_name);
214
- TCGv_ptr tcg_rd_ptr = vec_full_reg_ptr(s, rd);
196
/* override default SCSI bus hotplug-handler, with virtio-scsi's one */
215
- TCGv_ptr tcg_rn_ptr = vec_full_reg_ptr(s, rn);
197
qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(dev));
216
- TCGv_ptr tcg_rm_ptr = vec_full_reg_ptr(s, rm);
198
217
-
199
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
218
- gen_helper_crypto_sha1_3reg(tcg_rd_ptr, tcg_rn_ptr,
200
index XXXXXXX..XXXXXXX 100644
219
- tcg_rm_ptr, tcg_opcode);
201
--- a/hw/scsi/vmw_pvscsi.c
220
-
202
+++ b/hw/scsi/vmw_pvscsi.c
221
- tcg_temp_free_i32(tcg_opcode);
203
@@ -XXX,XX +XXX,XX @@ pvscsi_realizefn(PCIDevice *pci_dev, Error **errp)
222
- tcg_temp_free_ptr(tcg_rd_ptr);
204
223
- tcg_temp_free_ptr(tcg_rn_ptr);
205
s->completion_worker = qemu_bh_new(pvscsi_process_completion_queue, s);
224
- tcg_temp_free_ptr(tcg_rm_ptr);
206
225
- }
207
- scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(pci_dev),
226
+ gen_gvec_op3_ool(s, true, rd, rn, rm, 0, genfn);
208
- &pvscsi_scsi_info, NULL);
227
}
209
+ scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(pci_dev), &pvscsi_scsi_info);
228
210
/* override default SCSI bus hotplug-handler, with pvscsi's one */
229
/* Crypto two-reg SHA
211
qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(s));
230
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
212
pvscsi_reset_state(s);
231
index XXXXXXX..XXXXXXX 100644
213
diff --git a/hw/usb/dev-storage-bot.c b/hw/usb/dev-storage-bot.c
232
--- a/target/arm/translate-neon.inc.c
214
index XXXXXXX..XXXXXXX 100644
233
+++ b/target/arm/translate-neon.inc.c
215
--- a/hw/usb/dev-storage-bot.c
234
@@ -XXX,XX +XXX,XX @@ static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
216
+++ b/hw/usb/dev-storage-bot.c
235
DO_VQRDMLAH(VQRDMLAH, gen_gvec_sqrdmlah_qc)
217
@@ -XXX,XX +XXX,XX @@ static void usb_msd_bot_realize(USBDevice *dev, Error **errp)
236
DO_VQRDMLAH(VQRDMLSH, gen_gvec_sqrdmlsh_qc)
218
s->dev.auto_attach = 0;
237
238
-static bool trans_SHA1_3s(DisasContext *s, arg_SHA1_3s *a)
239
-{
240
- TCGv_ptr ptr1, ptr2, ptr3;
241
- TCGv_i32 tmp;
242
-
243
- if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
244
- !dc_isar_feature(aa32_sha1, s)) {
245
- return false;
246
+#define DO_SHA1(NAME, FUNC) \
247
+ WRAP_OOL_FN(gen_##NAME##_3s, FUNC) \
248
+ static bool trans_##NAME##_3s(DisasContext *s, arg_3same *a) \
249
+ { \
250
+ if (!dc_isar_feature(aa32_sha1, s)) { \
251
+ return false; \
252
+ } \
253
+ return do_3same(s, a, gen_##NAME##_3s); \
254
}
219
}
255
220
256
- /* UNDEF accesses to D16-D31 if they don't exist. */
221
- scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
257
- if (!dc_isar_feature(aa32_simd_r32, s) &&
222
- &usb_msd_scsi_info_bot, NULL);
258
- ((a->vd | a->vn | a->vm) & 0x10)) {
223
+ scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(dev), &usb_msd_scsi_info_bot);
259
- return false;
224
usb_msd_handle_reset(dev);
260
- }
225
}
261
-
226
262
- if ((a->vn | a->vm | a->vd) & 1) {
227
diff --git a/hw/usb/dev-storage-classic.c b/hw/usb/dev-storage-classic.c
263
- return false;
228
index XXXXXXX..XXXXXXX 100644
264
- }
229
--- a/hw/usb/dev-storage-classic.c
265
-
230
+++ b/hw/usb/dev-storage-classic.c
266
- if (!vfp_access_check(s)) {
231
@@ -XXX,XX +XXX,XX @@ static void usb_msd_storage_realize(USBDevice *dev, Error **errp)
267
- return true;
232
usb_desc_create_serial(dev);
268
- }
233
usb_desc_init(dev);
269
-
234
dev->flags |= (1 << USB_DEV_FLAG_IS_SCSI_STORAGE);
270
- ptr1 = vfp_reg_ptr(true, a->vd);
235
- scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
271
- ptr2 = vfp_reg_ptr(true, a->vn);
236
- &usb_msd_scsi_info_storage, NULL);
272
- ptr3 = vfp_reg_ptr(true, a->vm);
237
+ scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(dev),
273
- tmp = tcg_const_i32(a->optype);
238
+ &usb_msd_scsi_info_storage);
274
- gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp);
239
scsi_dev = scsi_bus_legacy_add_drive(&s->bus, blk, 0, !!s->removable,
275
- tcg_temp_free_i32(tmp);
240
s->conf.bootindex, s->conf.share_rw,
276
- tcg_temp_free_ptr(ptr1);
241
s->conf.rerror, s->conf.werror,
277
- tcg_temp_free_ptr(ptr2);
242
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
278
- tcg_temp_free_ptr(ptr3);
243
index XXXXXXX..XXXXXXX 100644
279
-
244
--- a/hw/usb/dev-uas.c
280
- return true;
245
+++ b/hw/usb/dev-uas.c
281
-}
246
@@ -XXX,XX +XXX,XX @@ static void usb_uas_realize(USBDevice *dev, Error **errp)
282
+DO_SHA1(SHA1C, gen_helper_crypto_sha1c)
247
uas->status_bh = qemu_bh_new(usb_uas_send_status_bh, uas);
283
+DO_SHA1(SHA1P, gen_helper_crypto_sha1p)
248
284
+DO_SHA1(SHA1M, gen_helper_crypto_sha1m)
249
dev->flags |= (1 << USB_DEV_FLAG_IS_SCSI_STORAGE);
285
+DO_SHA1(SHA1SU0, gen_helper_crypto_sha1su0)
250
- scsi_bus_new(&uas->bus, sizeof(uas->bus), DEVICE(dev),
286
251
- &usb_uas_scsi_info, NULL);
287
#define DO_SHA2(NAME, FUNC) \
252
+ scsi_bus_init(&uas->bus, sizeof(uas->bus), DEVICE(dev), &usb_uas_scsi_info);
288
WRAP_OOL_FN(gen_##NAME##_3s, FUNC) \
253
}
254
255
static const VMStateDescription vmstate_usb_uas = {
289
--
256
--
290
2.20.1
257
2.20.1
291
258
292
259
diff view generated by jsdifflib
1
Convert the VSHR 2-reg-shift insns to decodetree.
1
Rename ipack_bus_new_inplace() to ipack_bus_init(), to bring it in to
2
2
line with a "_init for in-place init, _new for allocate-and-return"
3
Note that unlike the legacy decoder, we present the right shift
3
convention. Drop the 'name' argument, because the only caller does
4
amount to the trans_ function as a positive integer.
4
not pass in a name. If a future caller does need to specify the bus
5
name, we should create an ipack_bus_init_named() function at that
6
point.
5
7
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20200522145520.6778-3-peter.maydell@linaro.org
10
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
11
Message-id: 20210923121153.23754-3-peter.maydell@linaro.org
9
---
12
---
10
target/arm/neon-dp.decode | 25 ++++++++++++++++++++
13
include/hw/ipack/ipack.h | 8 ++++----
11
target/arm/translate-neon.inc.c | 41 +++++++++++++++++++++++++++++++++
14
hw/ipack/ipack.c | 10 +++++-----
12
target/arm/translate.c | 21 +----------------
15
hw/ipack/tpci200.c | 4 ++--
13
3 files changed, 67 insertions(+), 20 deletions(-)
16
3 files changed, 11 insertions(+), 11 deletions(-)
14
17
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
18
diff --git a/include/hw/ipack/ipack.h b/include/hw/ipack/ipack.h
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/neon-dp.decode
20
--- a/include/hw/ipack/ipack.h
18
+++ b/target/arm/neon-dp.decode
21
+++ b/include/hw/ipack/ipack.h
19
@@ -XXX,XX +XXX,XX @@ VMINNM_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 1 .... @3same_fp
22
@@ -XXX,XX +XXX,XX @@ extern const VMStateDescription vmstate_ipack_device;
20
######################################################################
23
VMSTATE_STRUCT(_field, _state, 1, vmstate_ipack_device, IPackDevice)
21
&2reg_shift vm vd q shift size
24
22
25
IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot);
23
+# Right shifts are encoded as N - shift, where N is the element size in bits.
26
-void ipack_bus_new_inplace(IPackBus *bus, size_t bus_size,
24
+%neon_rshift_i6 16:6 !function=rsub_64
27
- DeviceState *parent,
25
+%neon_rshift_i5 16:5 !function=rsub_32
28
- const char *name, uint8_t n_slots,
26
+%neon_rshift_i4 16:4 !function=rsub_16
29
- qemu_irq_handler handler);
27
+%neon_rshift_i3 16:3 !function=rsub_8
30
+void ipack_bus_init(IPackBus *bus, size_t bus_size,
28
+
31
+ DeviceState *parent,
29
+@2reg_shr_d .... ... . . . ...... .... .... 1 q:1 . . .... \
32
+ uint8_t n_slots,
30
+ &2reg_shift vm=%vm_dp vd=%vd_dp size=3 shift=%neon_rshift_i6
33
+ qemu_irq_handler handler);
31
+@2reg_shr_s .... ... . . . 1 ..... .... .... 0 q:1 . . .... \
34
32
+ &2reg_shift vm=%vm_dp vd=%vd_dp size=2 shift=%neon_rshift_i5
35
#endif
33
+@2reg_shr_h .... ... . . . 01 .... .... .... 0 q:1 . . .... \
36
diff --git a/hw/ipack/ipack.c b/hw/ipack/ipack.c
34
+ &2reg_shift vm=%vm_dp vd=%vd_dp size=1 shift=%neon_rshift_i4
35
+@2reg_shr_b .... ... . . . 001 ... .... .... 0 q:1 . . .... \
36
+ &2reg_shift vm=%vm_dp vd=%vd_dp size=0 shift=%neon_rshift_i3
37
+
38
@2reg_shl_d .... ... . . . shift:6 .... .... 1 q:1 . . .... \
39
&2reg_shift vm=%vm_dp vd=%vd_dp size=3
40
@2reg_shl_s .... ... . . . 1 shift:5 .... .... 0 q:1 . . .... \
41
@@ -XXX,XX +XXX,XX @@ VMINNM_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 1 .... @3same_fp
42
@2reg_shl_b .... ... . . . 001 shift:3 .... .... 0 q:1 . . .... \
43
&2reg_shift vm=%vm_dp vd=%vd_dp size=0
44
45
+VSHR_S_2sh 1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_d
46
+VSHR_S_2sh 1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_s
47
+VSHR_S_2sh 1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_h
48
+VSHR_S_2sh 1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_b
49
+
50
+VSHR_U_2sh 1111 001 1 1 . ...... .... 0000 . . . 1 .... @2reg_shr_d
51
+VSHR_U_2sh 1111 001 1 1 . ...... .... 0000 . . . 1 .... @2reg_shr_s
52
+VSHR_U_2sh 1111 001 1 1 . ...... .... 0000 . . . 1 .... @2reg_shr_h
53
+VSHR_U_2sh 1111 001 1 1 . ...... .... 0000 . . . 1 .... @2reg_shr_b
54
+
55
VSHL_2sh 1111 001 0 1 . ...... .... 0101 . . . 1 .... @2reg_shl_d
56
VSHL_2sh 1111 001 0 1 . ...... .... 0101 . . . 1 .... @2reg_shl_s
57
VSHL_2sh 1111 001 0 1 . ...... .... 0101 . . . 1 .... @2reg_shl_h
58
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
59
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/translate-neon.inc.c
38
--- a/hw/ipack/ipack.c
61
+++ b/target/arm/translate-neon.inc.c
39
+++ b/hw/ipack/ipack.c
62
@@ -XXX,XX +XXX,XX @@ static inline int plus1(DisasContext *s, int x)
40
@@ -XXX,XX +XXX,XX @@ IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot)
63
return x + 1;
41
return NULL;
64
}
42
}
65
43
66
+static inline int rsub_64(DisasContext *s, int x)
44
-void ipack_bus_new_inplace(IPackBus *bus, size_t bus_size,
67
+{
45
- DeviceState *parent,
68
+ return 64 - x;
46
- const char *name, uint8_t n_slots,
69
+}
47
- qemu_irq_handler handler)
70
+
48
+void ipack_bus_init(IPackBus *bus, size_t bus_size,
71
+static inline int rsub_32(DisasContext *s, int x)
49
+ DeviceState *parent,
72
+{
50
+ uint8_t n_slots,
73
+ return 32 - x;
51
+ qemu_irq_handler handler)
74
+}
52
{
75
+static inline int rsub_16(DisasContext *s, int x)
53
- qbus_create_inplace(bus, bus_size, TYPE_IPACK_BUS, parent, name);
76
+{
54
+ qbus_create_inplace(bus, bus_size, TYPE_IPACK_BUS, parent, NULL);
77
+ return 16 - x;
55
bus->n_slots = n_slots;
78
+}
56
bus->set_irq = handler;
79
+static inline int rsub_8(DisasContext *s, int x)
57
}
80
+{
58
diff --git a/hw/ipack/tpci200.c b/hw/ipack/tpci200.c
81
+ return 8 - x;
82
+}
83
+
84
/* Include the generated Neon decoder */
85
#include "decode-neon-dp.inc.c"
86
#include "decode-neon-ls.inc.c"
87
@@ -XXX,XX +XXX,XX @@ static bool do_vector_2sh(DisasContext *s, arg_2reg_shift *a, GVecGen2iFn *fn)
88
89
DO_2SH(VSHL, tcg_gen_gvec_shli)
90
DO_2SH(VSLI, gen_gvec_sli)
91
+
92
+static bool trans_VSHR_S_2sh(DisasContext *s, arg_2reg_shift *a)
93
+{
94
+ /* Signed shift out of range results in all-sign-bits */
95
+ a->shift = MIN(a->shift, (8 << a->size) - 1);
96
+ return do_vector_2sh(s, a, tcg_gen_gvec_sari);
97
+}
98
+
99
+static void gen_zero_rd_2sh(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
100
+ int64_t shift, uint32_t oprsz, uint32_t maxsz)
101
+{
102
+ tcg_gen_gvec_dup_imm(vece, rd_ofs, oprsz, maxsz, 0);
103
+}
104
+
105
+static bool trans_VSHR_U_2sh(DisasContext *s, arg_2reg_shift *a)
106
+{
107
+ /* Shift out of range is architecturally valid and results in zero. */
108
+ if (a->shift >= (8 << a->size)) {
109
+ return do_vector_2sh(s, a, gen_zero_rd_2sh);
110
+ } else {
111
+ return do_vector_2sh(s, a, tcg_gen_gvec_shri);
112
+ }
113
+}
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
115
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/translate.c
60
--- a/hw/ipack/tpci200.c
117
+++ b/target/arm/translate.c
61
+++ b/hw/ipack/tpci200.c
118
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
62
@@ -XXX,XX +XXX,XX @@ static void tpci200_realize(PCIDevice *pci_dev, Error **errp)
119
op = (insn >> 8) & 0xf;
63
pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las2);
120
64
pci_register_bar(&s->dev, 5, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las3);
121
switch (op) {
65
122
+ case 0: /* VSHR */
66
- ipack_bus_new_inplace(&s->bus, sizeof(s->bus), DEVICE(pci_dev), NULL,
123
case 5: /* VSHL, VSLI */
67
- N_MODULES, tpci200_set_irq);
124
return 1; /* handled by decodetree */
68
+ ipack_bus_init(&s->bus, sizeof(s->bus), DEVICE(pci_dev),
125
default:
69
+ N_MODULES, tpci200_set_irq);
126
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
70
}
127
}
71
128
72
static const VMStateDescription vmstate_tpci200 = {
129
switch (op) {
130
- case 0: /* VSHR */
131
- /* Right shift comes here negative. */
132
- shift = -shift;
133
- /* Shifts larger than the element size are architecturally
134
- * valid. Unsigned results in all zeros; signed results
135
- * in all sign bits.
136
- */
137
- if (!u) {
138
- tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
139
- MIN(shift, (8 << size) - 1),
140
- vec_size, vec_size);
141
- } else if (shift >= 8 << size) {
142
- tcg_gen_gvec_dup_imm(MO_8, rd_ofs, vec_size,
143
- vec_size, 0);
144
- } else {
145
- tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
146
- vec_size, vec_size);
147
- }
148
- return 0;
149
-
150
case 1: /* VSRA */
151
/* Right shift comes here negative. */
152
shift = -shift;
153
--
73
--
154
2.20.1
74
2.20.1
155
75
156
76
diff view generated by jsdifflib
1
Convert the VCVT fixed-point conversion operations in the
1
Rename the pci_root_bus_new_inplace() function to
2
Neon 2-regs-and-shift group to decodetree.
2
pci_root_bus_init(); this brings the bus type in to line with a
3
"_init for in-place init, _new for allocate-and-return" convention.
4
To do this we need to rename the implementation-internal function
5
that was using the pci_root_bus_init() name to
6
pci_root_bus_internal_init().
3
7
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20200522145520.6778-9-peter.maydell@linaro.org
10
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
11
Message-id: 20210923121153.23754-4-peter.maydell@linaro.org
7
---
12
---
8
target/arm/neon-dp.decode | 11 +++++
13
include/hw/pci/pci.h | 10 +++++-----
9
target/arm/translate-neon.inc.c | 49 +++++++++++++++++++++
14
hw/pci-host/raven.c | 4 ++--
10
target/arm/translate.c | 75 +--------------------------------
15
hw/pci-host/versatile.c | 6 +++---
11
3 files changed, 62 insertions(+), 73 deletions(-)
16
hw/pci/pci.c | 26 +++++++++++++-------------
17
4 files changed, 23 insertions(+), 23 deletions(-)
12
18
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
19
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
21
--- a/include/hw/pci/pci.h
16
+++ b/target/arm/neon-dp.decode
22
+++ b/include/hw/pci/pci.h
17
@@ -XXX,XX +XXX,XX @@ VMINNM_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 1 .... @3same_fp
23
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(PCIBus, PCIBusClass, PCI_BUS)
18
@2reg_shll_b .... ... . . . 001 shift:3 .... .... 0 . . . .... \
24
19
&2reg_shift vm=%vm_dp vd=%vd_dp size=0 q=0
25
bool pci_bus_is_express(PCIBus *bus);
20
26
21
+# We use size=0 for fp32 and size=1 for fp16 to match the 3-same encodings.
27
-void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
22
+@2reg_vcvt .... ... . . . 1 ..... .... .... . q:1 . . .... \
28
- const char *name,
23
+ &2reg_shift vm=%vm_dp vd=%vd_dp size=0 shift=%neon_rshift_i5
29
- MemoryRegion *address_space_mem,
24
+
30
- MemoryRegion *address_space_io,
25
VSHR_S_2sh 1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_d
31
- uint8_t devfn_min, const char *typename);
26
VSHR_S_2sh 1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_s
32
+void pci_root_bus_init(PCIBus *bus, size_t bus_size, DeviceState *parent,
27
VSHR_S_2sh 1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_h
33
+ const char *name,
28
@@ -XXX,XX +XXX,XX @@ VSHLL_S_2sh 1111 001 0 1 . ...... .... 1010 . 0 . 1 .... @2reg_shll_b
34
+ MemoryRegion *address_space_mem,
29
VSHLL_U_2sh 1111 001 1 1 . ...... .... 1010 . 0 . 1 .... @2reg_shll_s
35
+ MemoryRegion *address_space_io,
30
VSHLL_U_2sh 1111 001 1 1 . ...... .... 1010 . 0 . 1 .... @2reg_shll_h
36
+ uint8_t devfn_min, const char *typename);
31
VSHLL_U_2sh 1111 001 1 1 . ...... .... 1010 . 0 . 1 .... @2reg_shll_b
37
PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
32
+
38
MemoryRegion *address_space_mem,
33
+# VCVT fixed<->float conversions
39
MemoryRegion *address_space_io,
34
+# TODO: FP16 fixed<->float conversions are opc==0b1100 and 0b1101
40
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
35
+VCVT_SF_2sh 1111 001 0 1 . ...... .... 1110 0 . . 1 .... @2reg_vcvt
36
+VCVT_UF_2sh 1111 001 1 1 . ...... .... 1110 0 . . 1 .... @2reg_vcvt
37
+VCVT_FS_2sh 1111 001 0 1 . ...... .... 1111 0 . . 1 .... @2reg_vcvt
38
+VCVT_FU_2sh 1111 001 1 1 . ...... .... 1111 0 . . 1 .... @2reg_vcvt
39
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
40
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/translate-neon.inc.c
42
--- a/hw/pci-host/raven.c
42
+++ b/target/arm/translate-neon.inc.c
43
+++ b/hw/pci-host/raven.c
43
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL_U_2sh(DisasContext *s, arg_2reg_shift *a)
44
@@ -XXX,XX +XXX,XX @@ static void raven_pcihost_initfn(Object *obj)
44
};
45
memory_region_add_subregion_overlap(address_space_mem, PCI_IO_BASE_ADDR,
45
return do_vshll_2sh(s, a, widenfn[a->size], true);
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;
46
}
78
}
47
+
79
48
+static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a,
80
-static void pci_root_bus_init(PCIBus *bus, DeviceState *parent,
49
+ NeonGenTwoSingleOPFn *fn)
81
- MemoryRegion *address_space_mem,
50
+{
82
- MemoryRegion *address_space_io,
51
+ /* FP operations in 2-reg-and-shift group */
83
- uint8_t devfn_min)
52
+ TCGv_i32 tmp, shiftv;
84
+static void pci_root_bus_internal_init(PCIBus *bus, DeviceState *parent,
53
+ TCGv_ptr fpstatus;
85
+ MemoryRegion *address_space_mem,
54
+ int pass;
86
+ MemoryRegion *address_space_io,
55
+
87
+ uint8_t devfn_min)
56
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
88
{
57
+ return false;
89
assert(PCI_FUNC(devfn_min) == 0);
58
+ }
90
bus->devfn_min = devfn_min;
59
+
91
@@ -XXX,XX +XXX,XX @@ bool pci_bus_is_express(PCIBus *bus)
60
+ /* UNDEF accesses to D16-D31 if they don't exist. */
92
return object_dynamic_cast(OBJECT(bus), TYPE_PCIE_BUS);
61
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
93
}
62
+ ((a->vd | a->vm) & 0x10)) {
94
63
+ return false;
95
-void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
64
+ }
96
- const char *name,
65
+
97
- MemoryRegion *address_space_mem,
66
+ if ((a->vm | a->vd) & a->q) {
98
- MemoryRegion *address_space_io,
67
+ return false;
99
- uint8_t devfn_min, const char *typename)
68
+ }
100
+void pci_root_bus_init(PCIBus *bus, size_t bus_size, DeviceState *parent,
69
+
101
+ const char *name,
70
+ if (!vfp_access_check(s)) {
102
+ MemoryRegion *address_space_mem,
71
+ return true;
103
+ MemoryRegion *address_space_io,
72
+ }
104
+ uint8_t devfn_min, const char *typename)
73
+
105
{
74
+ fpstatus = get_fpstatus_ptr(1);
106
qbus_create_inplace(bus, bus_size, typename, parent, name);
75
+ shiftv = tcg_const_i32(a->shift);
107
- pci_root_bus_init(bus, parent, address_space_mem, address_space_io,
76
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
108
- devfn_min);
77
+ tmp = neon_load_reg(a->vm, pass);
109
+ pci_root_bus_internal_init(bus, parent, address_space_mem,
78
+ fn(tmp, tmp, shiftv, fpstatus);
110
+ address_space_io, devfn_min);
79
+ neon_store_reg(a->vd, pass, tmp);
111
}
80
+ }
112
81
+ tcg_temp_free_ptr(fpstatus);
113
PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
82
+ tcg_temp_free_i32(shiftv);
114
@@ -XXX,XX +XXX,XX @@ PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
83
+ return true;
115
PCIBus *bus;
84
+}
116
85
+
117
bus = PCI_BUS(qbus_create(typename, parent, name));
86
+#define DO_FP_2SH(INSN, FUNC) \
118
- pci_root_bus_init(bus, parent, address_space_mem, address_space_io,
87
+ static bool trans_##INSN##_2sh(DisasContext *s, arg_2reg_shift *a) \
119
- devfn_min);
88
+ { \
120
+ pci_root_bus_internal_init(bus, parent, address_space_mem,
89
+ return do_fp_2sh(s, a, FUNC); \
121
+ address_space_io, devfn_min);
90
+ }
122
return bus;
91
+
123
}
92
+DO_FP_2SH(VCVT_SF, gen_helper_vfp_sltos)
93
+DO_FP_2SH(VCVT_UF, gen_helper_vfp_ultos)
94
+DO_FP_2SH(VCVT_FS, gen_helper_vfp_tosls_round_to_zero)
95
+DO_FP_2SH(VCVT_FU, gen_helper_vfp_touls_round_to_zero)
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
101
int q;
102
int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
103
int size;
104
- int shift;
105
int pass;
106
int u;
107
int vec_size;
108
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
109
return 1;
110
} else if (insn & (1 << 4)) {
111
if ((insn & 0x00380080) != 0) {
112
- /* Two registers and shift. */
113
- op = (insn >> 8) & 0xf;
114
-
115
- switch (op) {
116
- case 0: /* VSHR */
117
- case 1: /* VSRA */
118
- case 2: /* VRSHR */
119
- case 3: /* VRSRA */
120
- case 4: /* VSRI */
121
- case 5: /* VSHL, VSLI */
122
- case 6: /* VQSHLU */
123
- case 7: /* VQSHL */
124
- case 8: /* VSHRN, VRSHRN, VQSHRUN, VQRSHRUN */
125
- case 9: /* VQSHRN, VQRSHRN */
126
- case 10: /* VSHLL, including VMOVL */
127
- return 1; /* handled by decodetree */
128
- default:
129
- break;
130
- }
131
-
132
- if (insn & (1 << 7)) {
133
- /* 64-bit shift. */
134
- if (op > 7) {
135
- return 1;
136
- }
137
- size = 3;
138
- } else {
139
- size = 2;
140
- while ((insn & (1 << (size + 19))) == 0)
141
- size--;
142
- }
143
- shift = (insn >> 16) & ((1 << (3 + size)) - 1);
144
- if (op >= 14) {
145
- /* VCVT fixed-point. */
146
- TCGv_ptr fpst;
147
- TCGv_i32 shiftv;
148
- VFPGenFixPointFn *fn;
149
-
150
- if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
151
- return 1;
152
- }
153
-
154
- if (!(op & 1)) {
155
- if (u) {
156
- fn = gen_helper_vfp_ultos;
157
- } else {
158
- fn = gen_helper_vfp_sltos;
159
- }
160
- } else {
161
- if (u) {
162
- fn = gen_helper_vfp_touls_round_to_zero;
163
- } else {
164
- fn = gen_helper_vfp_tosls_round_to_zero;
165
- }
166
- }
167
-
168
- /* We have already masked out the must-be-1 top bit of imm6,
169
- * hence this 32-shift where the ARM ARM has 64-imm6.
170
- */
171
- shift = 32 - shift;
172
- fpst = get_fpstatus_ptr(1);
173
- shiftv = tcg_const_i32(shift);
174
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
175
- TCGv_i32 tmpf = neon_load_reg(rm, pass);
176
- fn(tmpf, tmpf, shiftv, fpst);
177
- neon_store_reg(rd, pass, tmpf);
178
- }
179
- tcg_temp_free_ptr(fpst);
180
- tcg_temp_free_i32(shiftv);
181
- } else {
182
- return 1;
183
- }
184
+ /* Two registers and shift: handled by decodetree */
185
+ return 1;
186
} else { /* (insn & 0x00380080) == 0 */
187
int invert, reg_ofs, vec_size;
188
124
189
--
125
--
190
2.20.1
126
2.20.1
191
127
192
128
diff view generated by jsdifflib
1
Convert the VQSHLU and QVSHL 2-reg-shift insns to decodetree.
1
Rename qbus_create_inplace() to qbus_init(); this is more in line
2
These are the last of the simple shift-by-immediate insns.
2
with our usual naming convention for functions that in-place
3
initialize objects.
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20200522145520.6778-5-peter.maydell@linaro.org
7
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
8
Message-id: 20210923121153.23754-5-peter.maydell@linaro.org
7
---
9
---
8
target/arm/neon-dp.decode | 15 +++++
10
include/hw/qdev-core.h | 4 ++--
9
target/arm/translate-neon.inc.c | 108 +++++++++++++++++++++++++++++++
11
hw/audio/intel-hda.c | 2 +-
10
target/arm/translate.c | 110 +-------------------------------
12
hw/block/fdc.c | 2 +-
11
3 files changed, 126 insertions(+), 107 deletions(-)
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(-)
12
43
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
44
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
14
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
46
--- a/include/hw/qdev-core.h
16
+++ b/target/arm/neon-dp.decode
47
+++ b/include/hw/qdev-core.h
17
@@ -XXX,XX +XXX,XX @@ VSLI_2sh 1111 001 1 1 . ...... .... 0101 . . . 1 .... @2reg_shl_d
48
@@ -XXX,XX +XXX,XX @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id);
18
VSLI_2sh 1111 001 1 1 . ...... .... 0101 . . . 1 .... @2reg_shl_s
49
typedef int (qbus_walkerfn)(BusState *bus, void *opaque);
19
VSLI_2sh 1111 001 1 1 . ...... .... 0101 . . . 1 .... @2reg_shl_h
50
typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque);
20
VSLI_2sh 1111 001 1 1 . ...... .... 0101 . . . 1 .... @2reg_shl_b
51
21
+
52
-void qbus_create_inplace(void *bus, size_t size, const char *typename,
22
+VQSHLU_64_2sh 1111 001 1 1 . ...... .... 0110 . . . 1 .... @2reg_shl_d
53
- DeviceState *parent, const char *name);
23
+VQSHLU_2sh 1111 001 1 1 . ...... .... 0110 . . . 1 .... @2reg_shl_s
54
+void qbus_init(void *bus, size_t size, const char *typename,
24
+VQSHLU_2sh 1111 001 1 1 . ...... .... 0110 . . . 1 .... @2reg_shl_h
55
+ DeviceState *parent, const char *name);
25
+VQSHLU_2sh 1111 001 1 1 . ...... .... 0110 . . . 1 .... @2reg_shl_b
56
BusState *qbus_create(const char *typename, DeviceState *parent, const char *name);
26
+
57
bool qbus_realize(BusState *bus, Error **errp);
27
+VQSHL_S_64_2sh 1111 001 0 1 . ...... .... 0111 . . . 1 .... @2reg_shl_d
58
void qbus_unrealize(BusState *bus);
28
+VQSHL_S_2sh 1111 001 0 1 . ...... .... 0111 . . . 1 .... @2reg_shl_s
59
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
29
+VQSHL_S_2sh 1111 001 0 1 . ...... .... 0111 . . . 1 .... @2reg_shl_h
60
index XXXXXXX..XXXXXXX 100644
30
+VQSHL_S_2sh 1111 001 0 1 . ...... .... 0111 . . . 1 .... @2reg_shl_b
61
--- a/hw/audio/intel-hda.c
31
+
62
+++ b/hw/audio/intel-hda.c
32
+VQSHL_U_64_2sh 1111 001 1 1 . ...... .... 0111 . . . 1 .... @2reg_shl_d
63
@@ -XXX,XX +XXX,XX @@ void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, size_t bus_size,
33
+VQSHL_U_2sh 1111 001 1 1 . ...... .... 0111 . . . 1 .... @2reg_shl_s
64
hda_codec_response_func response,
34
+VQSHL_U_2sh 1111 001 1 1 . ...... .... 0111 . . . 1 .... @2reg_shl_h
65
hda_codec_xfer_func xfer)
35
+VQSHL_U_2sh 1111 001 1 1 . ...... .... 0111 . . . 1 .... @2reg_shl_b
66
{
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
67
- qbus_create_inplace(bus, bus_size, TYPE_HDA_BUS, dev, NULL);
37
index XXXXXXX..XXXXXXX 100644
68
+ qbus_init(bus, bus_size, TYPE_HDA_BUS, dev, NULL);
38
--- a/target/arm/translate-neon.inc.c
69
bus->response = response;
39
+++ b/target/arm/translate-neon.inc.c
70
bus->xfer = xfer;
40
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHR_U_2sh(DisasContext *s, arg_2reg_shift *a)
71
}
41
return do_vector_2sh(s, a, tcg_gen_gvec_shri);
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,
42
}
119
}
43
}
120
}
44
+
121
45
+static bool do_2shift_env_64(DisasContext *s, arg_2reg_shift *a,
122
-static void qbus_init(BusState *bus, DeviceState *parent, const char *name)
46
+ NeonGenTwo64OpEnvFn *fn)
123
+static void qbus_init_internal(BusState *bus, DeviceState *parent,
47
+{
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 */
48
+ /*
162
+ /*
49
+ * 2-reg-and-shift operations, size == 3 case, where the
163
+ * assign main_system_bus before qbus_init()
50
+ * function needs to be passed cpu_env.
164
+ * in order to make "if (bus != sysbus_get_default())" work
51
+ */
165
+ */
52
+ TCGv_i64 constimm;
166
main_system_bus = g_malloc0(system_bus_info.instance_size);
53
+ int pass;
167
- qbus_create_inplace(main_system_bus, system_bus_info.instance_size,
54
+
168
- TYPE_SYSTEM_BUS, NULL, "main-system-bus");
55
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
169
+ qbus_init(main_system_bus, system_bus_info.instance_size,
56
+ return false;
170
+ TYPE_SYSTEM_BUS, NULL, "main-system-bus");
57
+ }
171
OBJECT(main_system_bus)->free = g_free;
58
+
172
}
59
+ /* UNDEF accesses to D16-D31 if they don't exist. */
173
60
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
174
diff --git a/hw/gpio/bcm2835_gpio.c b/hw/gpio/bcm2835_gpio.c
61
+ ((a->vd | a->vm) & 0x10)) {
175
index XXXXXXX..XXXXXXX 100644
62
+ return false;
176
--- a/hw/gpio/bcm2835_gpio.c
63
+ }
177
+++ b/hw/gpio/bcm2835_gpio.c
64
+
178
@@ -XXX,XX +XXX,XX @@ static void bcm2835_gpio_init(Object *obj)
65
+ if ((a->vm | a->vd) & a->q) {
179
DeviceState *dev = DEVICE(obj);
66
+ return false;
180
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
67
+ }
181
68
+
182
- qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
69
+ if (!vfp_access_check(s)) {
183
- TYPE_SD_BUS, DEVICE(s), "sd-bus");
70
+ return true;
184
+ qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_SD_BUS, DEVICE(s), "sd-bus");
71
+ }
185
72
+
186
memory_region_init_io(&s->iomem, obj,
73
+ /*
187
&bcm2835_gpio_ops, s, "bcm2835_gpio", 0x1000);
74
+ * To avoid excessive duplication of ops we implement shift
188
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
75
+ * by immediate using the variable shift operations.
189
index XXXXXXX..XXXXXXX 100644
76
+ */
190
--- a/hw/ide/qdev.c
77
+ constimm = tcg_const_i64(dup_const(a->size, a->shift));
191
+++ b/hw/ide/qdev.c
78
+
192
@@ -XXX,XX +XXX,XX @@ static const TypeInfo ide_bus_info = {
79
+ for (pass = 0; pass < a->q + 1; pass++) {
193
void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
80
+ TCGv_i64 tmp = tcg_temp_new_i64();
194
int bus_id, int max_units)
81
+
195
{
82
+ neon_load_reg64(tmp, a->vm + pass);
196
- qbus_create_inplace(idebus, idebus_size, TYPE_IDE_BUS, dev, NULL);
83
+ fn(tmp, cpu_env, tmp, constimm);
197
+ qbus_init(idebus, idebus_size, TYPE_IDE_BUS, dev, NULL);
84
+ neon_store_reg64(tmp, a->vd + pass);
198
idebus->bus_id = bus_id;
85
+ }
199
idebus->max_units = max_units;
86
+ tcg_temp_free_i64(constimm);
200
}
87
+ return true;
201
diff --git a/hw/ipack/ipack.c b/hw/ipack/ipack.c
88
+}
202
index XXXXXXX..XXXXXXX 100644
89
+
203
--- a/hw/ipack/ipack.c
90
+static bool do_2shift_env_32(DisasContext *s, arg_2reg_shift *a,
204
+++ b/hw/ipack/ipack.c
91
+ NeonGenTwoOpEnvFn *fn)
205
@@ -XXX,XX +XXX,XX @@ void ipack_bus_init(IPackBus *bus, size_t bus_size,
92
+{
206
uint8_t n_slots,
93
+ /*
207
qemu_irq_handler handler)
94
+ * 2-reg-and-shift operations, size < 3 case, where the
208
{
95
+ * helper needs to be passed cpu_env.
209
- qbus_create_inplace(bus, bus_size, TYPE_IPACK_BUS, parent, NULL);
96
+ */
210
+ qbus_init(bus, bus_size, TYPE_IPACK_BUS, parent, NULL);
97
+ TCGv_i32 constimm;
211
bus->n_slots = n_slots;
98
+ int pass;
212
bus->set_irq = handler;
99
+
213
}
100
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
214
diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
101
+ return false;
215
index XXXXXXX..XXXXXXX 100644
102
+ }
216
--- a/hw/misc/mac_via.c
103
+
217
+++ b/hw/misc/mac_via.c
104
+ /* UNDEF accesses to D16-D31 if they don't exist. */
218
@@ -XXX,XX +XXX,XX @@ static void mos6522_q800_via1_init(Object *obj)
105
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
219
sysbus_init_mmio(sbd, &v1s->via_mem);
106
+ ((a->vd | a->vm) & 0x10)) {
220
107
+ return false;
221
/* ADB */
108
+ }
222
- qbus_create_inplace((BusState *)&v1s->adb_bus, sizeof(v1s->adb_bus),
109
+
223
- TYPE_ADB_BUS, DEVICE(v1s), "adb.0");
110
+ if ((a->vm | a->vd) & a->q) {
224
+ qbus_init((BusState *)&v1s->adb_bus, sizeof(v1s->adb_bus),
111
+ return false;
225
+ TYPE_ADB_BUS, DEVICE(v1s), "adb.0");
112
+ }
226
113
+
227
qdev_init_gpio_in(DEVICE(obj), via1_irq_request, VIA1_IRQ_NB);
114
+ if (!vfp_access_check(s)) {
228
}
115
+ return true;
229
diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
116
+ }
230
index XXXXXXX..XXXXXXX 100644
117
+
231
--- a/hw/misc/macio/cuda.c
118
+ /*
232
+++ b/hw/misc/macio/cuda.c
119
+ * To avoid excessive duplication of ops we implement shift
233
@@ -XXX,XX +XXX,XX @@ static void cuda_init(Object *obj)
120
+ * by immediate using the variable shift operations.
234
memory_region_init_io(&s->mem, obj, &mos6522_cuda_ops, s, "cuda", 0x2000);
121
+ */
235
sysbus_init_mmio(sbd, &s->mem);
122
+ constimm = tcg_const_i32(dup_const(a->size, a->shift));
236
123
+
237
- qbus_create_inplace(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
124
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
238
- DEVICE(obj), "adb.0");
125
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
239
+ qbus_init(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
126
+ fn(tmp, cpu_env, tmp, constimm);
240
+ DEVICE(obj), "adb.0");
127
+ neon_store_reg(a->vd, pass, tmp);
241
}
128
+ }
242
129
+ tcg_temp_free_i32(constimm);
243
static Property cuda_properties[] = {
130
+ return true;
244
diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
131
+}
245
index XXXXXXX..XXXXXXX 100644
132
+
246
--- a/hw/misc/macio/macio.c
133
+#define DO_2SHIFT_ENV(INSN, FUNC) \
247
+++ b/hw/misc/macio/macio.c
134
+ static bool trans_##INSN##_64_2sh(DisasContext *s, arg_2reg_shift *a) \
248
@@ -XXX,XX +XXX,XX @@ static void macio_instance_init(Object *obj)
135
+ { \
249
136
+ return do_2shift_env_64(s, a, gen_helper_neon_##FUNC##64); \
250
memory_region_init(&s->bar, obj, "macio", 0x80000);
137
+ } \
251
138
+ static bool trans_##INSN##_2sh(DisasContext *s, arg_2reg_shift *a) \
252
- qbus_create_inplace(&s->macio_bus, sizeof(s->macio_bus), TYPE_MACIO_BUS,
139
+ { \
253
- DEVICE(obj), "macio.0");
140
+ static NeonGenTwoOpEnvFn * const fns[] = { \
254
+ qbus_init(&s->macio_bus, sizeof(s->macio_bus), TYPE_MACIO_BUS,
141
+ gen_helper_neon_##FUNC##8, \
255
+ DEVICE(obj), "macio.0");
142
+ gen_helper_neon_##FUNC##16, \
256
143
+ gen_helper_neon_##FUNC##32, \
257
object_initialize_child(OBJECT(s), "dbdma", &s->dbdma, TYPE_MAC_DBDMA);
144
+ }; \
258
145
+ assert(a->size < ARRAY_SIZE(fns)); \
259
diff --git a/hw/misc/macio/pmu.c b/hw/misc/macio/pmu.c
146
+ return do_2shift_env_32(s, a, fns[a->size]); \
260
index XXXXXXX..XXXXXXX 100644
147
+ }
261
--- a/hw/misc/macio/pmu.c
148
+
262
+++ b/hw/misc/macio/pmu.c
149
+DO_2SHIFT_ENV(VQSHLU, qshlu_s)
263
@@ -XXX,XX +XXX,XX @@ static void pmu_realize(DeviceState *dev, Error **errp)
150
+DO_2SHIFT_ENV(VQSHL_U, qshl_u)
264
timer_mod(s->one_sec_timer, s->one_sec_target);
151
+DO_2SHIFT_ENV(VQSHL_S, qshl_s)
265
152
diff --git a/target/arm/translate.c b/target/arm/translate.c
266
if (s->has_adb) {
153
index XXXXXXX..XXXXXXX 100644
267
- qbus_create_inplace(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
154
--- a/target/arm/translate.c
268
- dev, "adb.0");
155
+++ b/target/arm/translate.c
269
+ qbus_init(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
156
@@ -XXX,XX +XXX,XX @@ static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
270
+ dev, "adb.0");
271
adb_register_autopoll_callback(adb_bus, pmu_adb_poll, s);
157
}
272
}
158
}
273
}
159
274
diff --git a/hw/nubus/nubus-bridge.c b/hw/nubus/nubus-bridge.c
160
-#define GEN_NEON_INTEGER_OP_ENV(name) do { \
275
index XXXXXXX..XXXXXXX 100644
161
- switch ((size << 1) | u) { \
276
--- a/hw/nubus/nubus-bridge.c
162
- case 0: \
277
+++ b/hw/nubus/nubus-bridge.c
163
- gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
278
@@ -XXX,XX +XXX,XX @@ static void nubus_bridge_init(Object *obj)
164
- break; \
279
NubusBridge *s = NUBUS_BRIDGE(obj);
165
- case 1: \
280
NubusBus *bus = &s->bus;
166
- gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
281
167
- break; \
282
- qbus_create_inplace(bus, sizeof(s->bus), TYPE_NUBUS_BUS, DEVICE(s), NULL);
168
- case 2: \
283
+ qbus_init(bus, sizeof(s->bus), TYPE_NUBUS_BUS, DEVICE(s), NULL);
169
- gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
284
170
- break; \
285
qdev_init_gpio_out(DEVICE(s), bus->irqs, NUBUS_IRQS);
171
- case 3: \
286
}
172
- gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
287
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
173
- break; \
288
index XXXXXXX..XXXXXXX 100644
174
- case 4: \
289
--- a/hw/nvme/ctrl.c
175
- gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
290
+++ b/hw/nvme/ctrl.c
176
- break; \
291
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
177
- case 5: \
292
return;
178
- gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
293
}
179
- break; \
294
180
- default: return 1; \
295
- qbus_create_inplace(&n->bus, sizeof(NvmeBus), TYPE_NVME_BUS,
181
- }} while (0)
296
- &pci_dev->qdev, n->parent_obj.qdev.id);
182
-
297
+ qbus_init(&n->bus, sizeof(NvmeBus), TYPE_NVME_BUS,
183
static TCGv_i32 neon_load_scratch(int scratch)
298
+ &pci_dev->qdev, n->parent_obj.qdev.id);
184
{
299
185
TCGv_i32 tmp = tcg_temp_new_i32();
300
nvme_init_state(n);
186
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
301
if (nvme_init_pci(n, pci_dev, errp)) {
187
int size;
302
diff --git a/hw/nvme/subsys.c b/hw/nvme/subsys.c
188
int shift;
303
index XXXXXXX..XXXXXXX 100644
189
int pass;
304
--- a/hw/nvme/subsys.c
190
- int count;
305
+++ b/hw/nvme/subsys.c
191
int u;
306
@@ -XXX,XX +XXX,XX @@ static void nvme_subsys_realize(DeviceState *dev, Error **errp)
192
int vec_size;
307
{
193
uint32_t imm;
308
NvmeSubsystem *subsys = NVME_SUBSYS(dev);
194
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
309
195
case 3: /* VRSRA */
310
- qbus_create_inplace(&subsys->bus, sizeof(NvmeBus), TYPE_NVME_BUS, dev,
196
case 4: /* VSRI */
311
- dev->id);
197
case 5: /* VSHL, VSLI */
312
+ qbus_init(&subsys->bus, sizeof(NvmeBus), TYPE_NVME_BUS, dev, dev->id);
198
+ case 6: /* VQSHLU */
313
199
+ case 7: /* VQSHL */
314
nvme_subsys_setup(subsys);
200
return 1; /* handled by decodetree */
315
}
201
default:
316
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
202
break;
317
index XXXXXXX..XXXXXXX 100644
203
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
318
--- a/hw/pci/pci.c
204
size--;
319
+++ b/hw/pci/pci.c
205
}
320
@@ -XXX,XX +XXX,XX @@ void pci_root_bus_init(PCIBus *bus, size_t bus_size, DeviceState *parent,
206
shift = (insn >> 16) & ((1 << (3 + size)) - 1);
321
MemoryRegion *address_space_io,
207
- if (op < 8) {
322
uint8_t devfn_min, const char *typename)
208
- /* Shift by immediate:
323
{
209
- VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
324
- qbus_create_inplace(bus, bus_size, typename, parent, name);
210
- if (q && ((rd | rm) & 1)) {
325
+ qbus_init(bus, bus_size, typename, parent, name);
211
- return 1;
326
pci_root_bus_internal_init(bus, parent, address_space_mem,
212
- }
327
address_space_io, devfn_min);
213
- if (!u && (op == 4 || op == 6)) {
328
}
214
- return 1;
329
diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
215
- }
330
index XXXXXXX..XXXXXXX 100644
216
- /* Right shifts are encoded as N - shift, where N is the
331
--- a/hw/pci/pci_bridge.c
217
- element size in bits. */
332
+++ b/hw/pci/pci_bridge.c
218
- if (op <= 4) {
333
@@ -XXX,XX +XXX,XX @@ void pci_bridge_initfn(PCIDevice *dev, const char *typename)
219
- shift = shift - (1 << (size + 3));
334
br->bus_name = dev->qdev.id;
220
- }
335
}
221
-
336
222
- if (size == 3) {
337
- qbus_create_inplace(sec_bus, sizeof(br->sec_bus), typename, DEVICE(dev),
223
- count = q + 1;
338
- br->bus_name);
224
- } else {
339
+ qbus_init(sec_bus, sizeof(br->sec_bus), typename, DEVICE(dev),
225
- count = q ? 4: 2;
340
+ br->bus_name);
226
- }
341
sec_bus->parent_dev = dev;
227
-
342
sec_bus->map_irq = br->map_irq ? br->map_irq : pci_swizzle_map_irq_fn;
228
- /* To avoid excessive duplication of ops we implement shift
343
sec_bus->address_space_mem = &br->address_space_mem;
229
- * by immediate using the variable shift operations.
344
diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
230
- */
345
index XXXXXXX..XXXXXXX 100644
231
- imm = dup_const(size, shift);
346
--- a/hw/s390x/event-facility.c
232
-
347
+++ b/hw/s390x/event-facility.c
233
- for (pass = 0; pass < count; pass++) {
348
@@ -XXX,XX +XXX,XX @@ static void init_event_facility(Object *obj)
234
- if (size == 3) {
349
sclp_event_set_allow_all_mask_sizes);
235
- neon_load_reg64(cpu_V0, rm + pass);
350
236
- tcg_gen_movi_i64(cpu_V1, imm);
351
/* Spawn a new bus for SCLP events */
237
- switch (op) {
352
- qbus_create_inplace(&event_facility->sbus, sizeof(event_facility->sbus),
238
- case 6: /* VQSHLU */
353
- TYPE_SCLP_EVENTS_BUS, sdev, NULL);
239
- gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
354
+ qbus_init(&event_facility->sbus, sizeof(event_facility->sbus),
240
- cpu_V0, cpu_V1);
355
+ TYPE_SCLP_EVENTS_BUS, sdev, NULL);
241
- break;
356
242
- case 7: /* VQSHL */
357
object_initialize_child(obj, TYPE_SCLP_QUIESCE,
243
- if (u) {
358
&event_facility->quiesce,
244
- gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
359
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
245
- cpu_V0, cpu_V1);
360
index XXXXXXX..XXXXXXX 100644
246
- } else {
361
--- a/hw/s390x/virtio-ccw.c
247
- gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
362
+++ b/hw/s390x/virtio-ccw.c
248
- cpu_V0, cpu_V1);
363
@@ -XXX,XX +XXX,XX @@ static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
249
- }
364
DeviceState *qdev = DEVICE(dev);
250
- break;
365
char virtio_bus_name[] = "virtio-bus";
251
- default:
366
252
- g_assert_not_reached();
367
- qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_CCW_BUS,
253
- }
368
- qdev, virtio_bus_name);
254
- neon_store_reg64(cpu_V0, rd + pass);
369
+ qbus_init(bus, bus_size, TYPE_VIRTIO_CCW_BUS, qdev, virtio_bus_name);
255
- } else { /* size < 3 */
370
}
256
- /* Operands in T0 and T1. */
371
257
- tmp = neon_load_reg(rm, pass);
372
static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data)
258
- tmp2 = tcg_temp_new_i32();
373
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
259
- tcg_gen_movi_i32(tmp2, imm);
374
index XXXXXXX..XXXXXXX 100644
260
- switch (op) {
375
--- a/hw/scsi/scsi-bus.c
261
- case 6: /* VQSHLU */
376
+++ b/hw/scsi/scsi-bus.c
262
- switch (size) {
377
@@ -XXX,XX +XXX,XX @@ void scsi_device_unit_attention_reported(SCSIDevice *s)
263
- case 0:
378
void scsi_bus_init_named(SCSIBus *bus, size_t bus_size, DeviceState *host,
264
- gen_helper_neon_qshlu_s8(tmp, cpu_env,
379
const SCSIBusInfo *info, const char *bus_name)
265
- tmp, tmp2);
380
{
266
- break;
381
- qbus_create_inplace(bus, bus_size, TYPE_SCSI_BUS, host, bus_name);
267
- case 1:
382
+ qbus_init(bus, bus_size, TYPE_SCSI_BUS, host, bus_name);
268
- gen_helper_neon_qshlu_s16(tmp, cpu_env,
383
bus->busnr = next_scsi_bus++;
269
- tmp, tmp2);
384
bus->info = info;
270
- break;
385
qbus_set_bus_hotplug_handler(BUS(bus));
271
- case 2:
386
diff --git a/hw/sd/allwinner-sdhost.c b/hw/sd/allwinner-sdhost.c
272
- gen_helper_neon_qshlu_s32(tmp, cpu_env,
387
index XXXXXXX..XXXXXXX 100644
273
- tmp, tmp2);
388
--- a/hw/sd/allwinner-sdhost.c
274
- break;
389
+++ b/hw/sd/allwinner-sdhost.c
275
- default:
390
@@ -XXX,XX +XXX,XX @@ static void allwinner_sdhost_init(Object *obj)
276
- abort();
391
{
277
- }
392
AwSdHostState *s = AW_SDHOST(obj);
278
- break;
393
279
- case 7: /* VQSHL */
394
- qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
280
- GEN_NEON_INTEGER_OP_ENV(qshl);
395
- TYPE_AW_SDHOST_BUS, DEVICE(s), "sd-bus");
281
- break;
396
+ qbus_init(&s->sdbus, sizeof(s->sdbus),
282
- default:
397
+ TYPE_AW_SDHOST_BUS, DEVICE(s), "sd-bus");
283
- g_assert_not_reached();
398
284
- }
399
memory_region_init_io(&s->iomem, obj, &allwinner_sdhost_ops, s,
285
- tcg_temp_free_i32(tmp2);
400
TYPE_AW_SDHOST, 4 * KiB);
286
- neon_store_reg(rd, pass, tmp);
401
diff --git a/hw/sd/bcm2835_sdhost.c b/hw/sd/bcm2835_sdhost.c
287
- }
402
index XXXXXXX..XXXXXXX 100644
288
- } /* for pass */
403
--- a/hw/sd/bcm2835_sdhost.c
289
- } else if (op < 10) {
404
+++ b/hw/sd/bcm2835_sdhost.c
290
+ if (op < 10) {
405
@@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_init(Object *obj)
291
/* Shift by immediate and narrow:
406
{
292
VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
407
BCM2835SDHostState *s = BCM2835_SDHOST(obj);
293
int input_unsigned = (op == 8) ? !u : u;
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)
294
--
528
--
295
2.20.1
529
2.20.1
296
530
297
531
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Rename the "allocate and return" qbus creation function to
2
2
qbus_new(), to bring it into line with our _init vs _new convention.
3
Do not yet convert the helpers to loop over opr_sz, but the
3
4
descriptor allows the vector tail to be cleared. Which fixes
5
an existing bug vs SVE.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200514212831.31248-5-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
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
11
---
9
---
12
target/arm/helper.h | 12 ++--
10
include/hw/qdev-core.h | 2 +-
13
target/arm/neon-dp.decode | 12 ++--
11
hw/core/bus.c | 2 +-
14
target/arm/crypto_helper.c | 24 +++++--
12
hw/hyperv/vmbus.c | 2 +-
15
target/arm/translate-a64.c | 34 ++++-----
13
hw/i2c/core.c | 2 +-
16
target/arm/translate-neon.inc.c | 124 +++++---------------------------
14
hw/isa/isa-bus.c | 2 +-
17
target/arm/translate.c | 24 ++-----
15
hw/misc/auxbus.c | 2 +-
18
6 files changed, 67 insertions(+), 163 deletions(-)
16
hw/pci/pci.c | 2 +-
19
17
hw/ppc/spapr_vio.c | 2 +-
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
18
hw/s390x/ap-bridge.c | 2 +-
21
index XXXXXXX..XXXXXXX 100644
19
hw/s390x/css-bridge.c | 2 +-
22
--- a/target/arm/helper.h
20
hw/s390x/s390-pci-bus.c | 2 +-
23
+++ b/target/arm/helper.h
21
hw/ssi/ssi.c | 2 +-
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
22
hw/xen/xen-bus.c | 2 +-
25
DEF_HELPER_FLAGS_3(crypto_aesmc, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
23
hw/xen/xen-legacy-backend.c | 2 +-
26
24
14 files changed, 14 insertions(+), 14 deletions(-)
27
DEF_HELPER_FLAGS_4(crypto_sha1_3reg, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
28
-DEF_HELPER_FLAGS_2(crypto_sha1h, TCG_CALL_NO_RWG, void, ptr, ptr)
26
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
29
-DEF_HELPER_FLAGS_2(crypto_sha1su1, TCG_CALL_NO_RWG, void, ptr, ptr)
27
index XXXXXXX..XXXXXXX 100644
30
+DEF_HELPER_FLAGS_3(crypto_sha1h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
28
--- a/include/hw/qdev-core.h
31
+DEF_HELPER_FLAGS_3(crypto_sha1su1, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
29
+++ b/include/hw/qdev-core.h
32
30
@@ -XXX,XX +XXX,XX @@ typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque);
33
-DEF_HELPER_FLAGS_3(crypto_sha256h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
31
34
-DEF_HELPER_FLAGS_3(crypto_sha256h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
32
void qbus_init(void *bus, size_t size, const char *typename,
35
-DEF_HELPER_FLAGS_2(crypto_sha256su0, TCG_CALL_NO_RWG, void, ptr, ptr)
33
DeviceState *parent, const char *name);
36
-DEF_HELPER_FLAGS_3(crypto_sha256su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
34
-BusState *qbus_create(const char *typename, DeviceState *parent, const char *name);
37
+DEF_HELPER_FLAGS_4(crypto_sha256h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
35
+BusState *qbus_new(const char *typename, DeviceState *parent, const char *name);
38
+DEF_HELPER_FLAGS_4(crypto_sha256h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
36
bool qbus_realize(BusState *bus, Error **errp);
39
+DEF_HELPER_FLAGS_3(crypto_sha256su0, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
37
void qbus_unrealize(BusState *bus);
40
+DEF_HELPER_FLAGS_4(crypto_sha256su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
38
41
39
diff --git a/hw/core/bus.c b/hw/core/bus.c
42
DEF_HELPER_FLAGS_4(crypto_sha512h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
40
index XXXXXXX..XXXXXXX 100644
43
DEF_HELPER_FLAGS_4(crypto_sha512h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
41
--- a/hw/core/bus.c
44
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
42
+++ b/hw/core/bus.c
45
index XXXXXXX..XXXXXXX 100644
43
@@ -XXX,XX +XXX,XX @@ void qbus_init(void *bus, size_t size, const char *typename,
46
--- a/target/arm/neon-dp.decode
44
qbus_init_internal(bus, parent, name);
47
+++ b/target/arm/neon-dp.decode
48
@@ -XXX,XX +XXX,XX @@ VPADD_3s 1111 001 0 0 . .. .... .... 1011 . . . 1 .... @3same_q0
49
50
VQRDMLAH_3s 1111 001 1 0 . .. .... .... 1011 ... 1 .... @3same
51
52
+@3same_crypto .... .... .... .... .... .... .... .... \
53
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0 q=1
54
+
55
SHA1_3s 1111 001 0 0 . optype:2 .... .... 1100 . 1 . 0 .... \
56
vm=%vm_dp vn=%vn_dp vd=%vd_dp
57
-SHA256H_3s 1111 001 1 0 . 00 .... .... 1100 . 1 . 0 .... \
58
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
59
-SHA256H2_3s 1111 001 1 0 . 01 .... .... 1100 . 1 . 0 .... \
60
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
61
-SHA256SU1_3s 1111 001 1 0 . 10 .... .... 1100 . 1 . 0 .... \
62
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
63
+SHA256H_3s 1111 001 1 0 . 00 .... .... 1100 . 1 . 0 .... @3same_crypto
64
+SHA256H2_3s 1111 001 1 0 . 01 .... .... 1100 . 1 . 0 .... @3same_crypto
65
+SHA256SU1_3s 1111 001 1 0 . 10 .... .... 1100 . 1 . 0 .... @3same_crypto
66
67
VFMA_fp_3s 1111 001 0 0 . 0 . .... .... 1100 ... 1 .... @3same_fp
68
VFMS_fp_3s 1111 001 0 0 . 1 . .... .... 1100 ... 1 .... @3same_fp
69
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/crypto_helper.c
72
+++ b/target/arm/crypto_helper.c
73
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha1_3reg)(void *vd, void *vn, void *vm, uint32_t op)
74
rd[1] = d.l[1];
75
}
45
}
76
46
77
-void HELPER(crypto_sha1h)(void *vd, void *vm)
47
-BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
78
+void HELPER(crypto_sha1h)(void *vd, void *vm, uint32_t desc)
48
+BusState *qbus_new(const char *typename, DeviceState *parent, const char *name)
79
{
49
{
80
uint64_t *rd = vd;
50
BusState *bus;
81
uint64_t *rm = vm;
51
82
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha1h)(void *vd, void *vm)
52
diff --git a/hw/hyperv/vmbus.c b/hw/hyperv/vmbus.c
83
53
index XXXXXXX..XXXXXXX 100644
84
rd[0] = m.l[0];
54
--- a/hw/hyperv/vmbus.c
85
rd[1] = m.l[1];
55
+++ b/hw/hyperv/vmbus.c
86
+
56
@@ -XXX,XX +XXX,XX @@ static void vmbus_bridge_realize(DeviceState *dev, Error **errp)
87
+ clear_tail_16(vd, desc);
88
}
89
90
-void HELPER(crypto_sha1su1)(void *vd, void *vm)
91
+void HELPER(crypto_sha1su1)(void *vd, void *vm, uint32_t desc)
92
{
93
uint64_t *rd = vd;
94
uint64_t *rm = vm;
95
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha1su1)(void *vd, void *vm)
96
97
rd[0] = d.l[0];
98
rd[1] = d.l[1];
99
+
100
+ clear_tail_16(vd, desc);
101
}
102
103
/*
104
@@ -XXX,XX +XXX,XX @@ static uint32_t s1(uint32_t x)
105
return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10);
106
}
107
108
-void HELPER(crypto_sha256h)(void *vd, void *vn, void *vm)
109
+void HELPER(crypto_sha256h)(void *vd, void *vn, void *vm, uint32_t desc)
110
{
111
uint64_t *rd = vd;
112
uint64_t *rn = vn;
113
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha256h)(void *vd, void *vn, void *vm)
114
115
rd[0] = d.l[0];
116
rd[1] = d.l[1];
117
+
118
+ clear_tail_16(vd, desc);
119
}
120
121
-void HELPER(crypto_sha256h2)(void *vd, void *vn, void *vm)
122
+void HELPER(crypto_sha256h2)(void *vd, void *vn, void *vm, uint32_t desc)
123
{
124
uint64_t *rd = vd;
125
uint64_t *rn = vn;
126
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha256h2)(void *vd, void *vn, void *vm)
127
128
rd[0] = d.l[0];
129
rd[1] = d.l[1];
130
+
131
+ clear_tail_16(vd, desc);
132
}
133
134
-void HELPER(crypto_sha256su0)(void *vd, void *vm)
135
+void HELPER(crypto_sha256su0)(void *vd, void *vm, uint32_t desc)
136
{
137
uint64_t *rd = vd;
138
uint64_t *rm = vm;
139
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha256su0)(void *vd, void *vm)
140
141
rd[0] = d.l[0];
142
rd[1] = d.l[1];
143
+
144
+ clear_tail_16(vd, desc);
145
}
146
147
-void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm)
148
+void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm, uint32_t desc)
149
{
150
uint64_t *rd = vd;
151
uint64_t *rn = vn;
152
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm)
153
154
rd[0] = d.l[0];
155
rd[1] = d.l[1];
156
+
157
+ clear_tail_16(vd, desc);
158
}
159
160
/*
161
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
162
index XXXXXXX..XXXXXXX 100644
163
--- a/target/arm/translate-a64.c
164
+++ b/target/arm/translate-a64.c
165
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
166
int rm = extract32(insn, 16, 5);
167
int rn = extract32(insn, 5, 5);
168
int rd = extract32(insn, 0, 5);
169
- CryptoThreeOpFn *genfn;
170
- TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
171
+ gen_helper_gvec_3 *genfn;
172
bool feature;
173
174
if (size != 0) {
175
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
176
return;
57
return;
177
}
58
}
178
59
179
- tcg_rd_ptr = vec_full_reg_ptr(s, rd);
60
- bridge->bus = VMBUS(qbus_create(TYPE_VMBUS, dev, "vmbus"));
180
- tcg_rn_ptr = vec_full_reg_ptr(s, rn);
61
+ bridge->bus = VMBUS(qbus_new(TYPE_VMBUS, dev, "vmbus"));
181
- tcg_rm_ptr = vec_full_reg_ptr(s, rm);
182
-
183
if (genfn) {
184
- genfn(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr);
185
+ gen_gvec_op3_ool(s, true, rd, rn, rm, 0, genfn);
186
} else {
187
TCGv_i32 tcg_opcode = tcg_const_i32(opcode);
188
+ TCGv_ptr tcg_rd_ptr = vec_full_reg_ptr(s, rd);
189
+ TCGv_ptr tcg_rn_ptr = vec_full_reg_ptr(s, rn);
190
+ TCGv_ptr tcg_rm_ptr = vec_full_reg_ptr(s, rm);
191
192
gen_helper_crypto_sha1_3reg(tcg_rd_ptr, tcg_rn_ptr,
193
tcg_rm_ptr, tcg_opcode);
194
- tcg_temp_free_i32(tcg_opcode);
195
- }
196
197
- tcg_temp_free_ptr(tcg_rd_ptr);
198
- tcg_temp_free_ptr(tcg_rn_ptr);
199
- tcg_temp_free_ptr(tcg_rm_ptr);
200
+ tcg_temp_free_i32(tcg_opcode);
201
+ tcg_temp_free_ptr(tcg_rd_ptr);
202
+ tcg_temp_free_ptr(tcg_rn_ptr);
203
+ tcg_temp_free_ptr(tcg_rm_ptr);
204
+ }
205
}
62
}
206
63
207
/* Crypto two-reg SHA
64
static char *vmbus_bridge_ofw_unit_address(const SysBusDevice *dev)
208
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
65
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
209
int opcode = extract32(insn, 12, 5);
66
index XXXXXXX..XXXXXXX 100644
210
int rn = extract32(insn, 5, 5);
67
--- a/hw/i2c/core.c
211
int rd = extract32(insn, 0, 5);
68
+++ b/hw/i2c/core.c
212
- CryptoTwoOpFn *genfn;
69
@@ -XXX,XX +XXX,XX @@ I2CBus *i2c_init_bus(DeviceState *parent, const char *name)
213
+ gen_helper_gvec_2 *genfn;
70
{
214
bool feature;
71
I2CBus *bus;
215
- TCGv_ptr tcg_rd_ptr, tcg_rn_ptr;
72
216
73
- bus = I2C_BUS(qbus_create(TYPE_I2C_BUS, parent, name));
217
if (size != 0) {
74
+ bus = I2C_BUS(qbus_new(TYPE_I2C_BUS, parent, name));
218
unallocated_encoding(s);
75
QLIST_INIT(&bus->current_devs);
219
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
76
vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_i2c_bus, bus);
220
if (!fp_access_check(s)) {
77
return bus;
221
return;
78
diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/hw/isa/isa-bus.c
81
+++ b/hw/isa/isa-bus.c
82
@@ -XXX,XX +XXX,XX @@ ISABus *isa_bus_new(DeviceState *dev, MemoryRegion* address_space,
83
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
222
}
84
}
223
-
85
224
- tcg_rd_ptr = vec_full_reg_ptr(s, rd);
86
- isabus = ISA_BUS(qbus_create(TYPE_ISA_BUS, dev, NULL));
225
- tcg_rn_ptr = vec_full_reg_ptr(s, rn);
87
+ isabus = ISA_BUS(qbus_new(TYPE_ISA_BUS, dev, NULL));
226
-
88
isabus->address_space = address_space;
227
- genfn(tcg_rd_ptr, tcg_rn_ptr);
89
isabus->address_space_io = address_space_io;
228
-
90
return isabus;
229
- tcg_temp_free_ptr(tcg_rd_ptr);
91
diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c
230
- tcg_temp_free_ptr(tcg_rn_ptr);
92
index XXXXXXX..XXXXXXX 100644
231
+ gen_gvec_op2_ool(s, true, rd, rn, 0, genfn);
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);
232
}
180
}
233
181
234
static void gen_rax1_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m)
182
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
235
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
183
index XXXXXXX..XXXXXXX 100644
236
index XXXXXXX..XXXXXXX 100644
184
--- a/hw/xen/xen-bus.c
237
--- a/target/arm/translate-neon.inc.c
185
+++ b/hw/xen/xen-bus.c
238
+++ b/target/arm/translate-neon.inc.c
186
@@ -XXX,XX +XXX,XX @@ type_init(xen_register_types)
239
@@ -XXX,XX +XXX,XX @@ DO_3SAME_CMP(VCGE_S, TCG_COND_GE)
187
void xen_bus_init(void)
240
DO_3SAME_CMP(VCGE_U, TCG_COND_GEU)
188
{
241
DO_3SAME_CMP(VCEQ, TCG_COND_EQ)
189
DeviceState *dev = qdev_new(TYPE_XEN_BRIDGE);
242
190
- BusState *bus = qbus_create(TYPE_XEN_BUS, dev, NULL);
243
-static void gen_VMUL_p_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
191
+ BusState *bus = qbus_new(TYPE_XEN_BUS, dev, NULL);
244
- uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
192
245
-{
193
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
246
- tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz,
194
qbus_set_bus_hotplug_handler(bus);
247
- 0, gen_helper_gvec_pmul_b);
195
diff --git a/hw/xen/xen-legacy-backend.c b/hw/xen/xen-legacy-backend.c
248
-}
196
index XXXXXXX..XXXXXXX 100644
249
+#define WRAP_OOL_FN(WRAPNAME, FUNC) \
197
--- a/hw/xen/xen-legacy-backend.c
250
+ static void WRAPNAME(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, \
198
+++ b/hw/xen/xen-legacy-backend.c
251
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz) \
199
@@ -XXX,XX +XXX,XX @@ int xen_be_init(void)
252
+ { \
200
253
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, 0, FUNC); \
201
xen_sysdev = qdev_new(TYPE_XENSYSDEV);
254
+ }
202
sysbus_realize_and_unref(SYS_BUS_DEVICE(xen_sysdev), &error_fatal);
255
+
203
- xen_sysbus = qbus_create(TYPE_XENSYSBUS, xen_sysdev, "xen-sysbus");
256
+WRAP_OOL_FN(gen_VMUL_p_3s, gen_helper_gvec_pmul_b)
204
+ xen_sysbus = qbus_new(TYPE_XENSYSBUS, xen_sysdev, "xen-sysbus");
257
205
qbus_set_bus_hotplug_handler(xen_sysbus);
258
static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
206
259
{
207
return 0;
260
@@ -XXX,XX +XXX,XX @@ static bool trans_SHA1_3s(DisasContext *s, arg_SHA1_3s *a)
261
return true;
262
}
263
264
-static bool trans_SHA256H_3s(DisasContext *s, arg_SHA256H_3s *a)
265
-{
266
- TCGv_ptr ptr1, ptr2, ptr3;
267
-
268
- if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
269
- !dc_isar_feature(aa32_sha2, s)) {
270
- return false;
271
+#define DO_SHA2(NAME, FUNC) \
272
+ WRAP_OOL_FN(gen_##NAME##_3s, FUNC) \
273
+ static bool trans_##NAME##_3s(DisasContext *s, arg_3same *a) \
274
+ { \
275
+ if (!dc_isar_feature(aa32_sha2, s)) { \
276
+ return false; \
277
+ } \
278
+ return do_3same(s, a, gen_##NAME##_3s); \
279
}
280
281
- /* UNDEF accesses to D16-D31 if they don't exist. */
282
- if (!dc_isar_feature(aa32_simd_r32, s) &&
283
- ((a->vd | a->vn | a->vm) & 0x10)) {
284
- return false;
285
- }
286
-
287
- if ((a->vn | a->vm | a->vd) & 1) {
288
- return false;
289
- }
290
-
291
- if (!vfp_access_check(s)) {
292
- return true;
293
- }
294
-
295
- ptr1 = vfp_reg_ptr(true, a->vd);
296
- ptr2 = vfp_reg_ptr(true, a->vn);
297
- ptr3 = vfp_reg_ptr(true, a->vm);
298
- gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
299
- tcg_temp_free_ptr(ptr1);
300
- tcg_temp_free_ptr(ptr2);
301
- tcg_temp_free_ptr(ptr3);
302
-
303
- return true;
304
-}
305
-
306
-static bool trans_SHA256H2_3s(DisasContext *s, arg_SHA256H2_3s *a)
307
-{
308
- TCGv_ptr ptr1, ptr2, ptr3;
309
-
310
- if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
311
- !dc_isar_feature(aa32_sha2, s)) {
312
- return false;
313
- }
314
-
315
- /* UNDEF accesses to D16-D31 if they don't exist. */
316
- if (!dc_isar_feature(aa32_simd_r32, s) &&
317
- ((a->vd | a->vn | a->vm) & 0x10)) {
318
- return false;
319
- }
320
-
321
- if ((a->vn | a->vm | a->vd) & 1) {
322
- return false;
323
- }
324
-
325
- if (!vfp_access_check(s)) {
326
- return true;
327
- }
328
-
329
- ptr1 = vfp_reg_ptr(true, a->vd);
330
- ptr2 = vfp_reg_ptr(true, a->vn);
331
- ptr3 = vfp_reg_ptr(true, a->vm);
332
- gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
333
- tcg_temp_free_ptr(ptr1);
334
- tcg_temp_free_ptr(ptr2);
335
- tcg_temp_free_ptr(ptr3);
336
-
337
- return true;
338
-}
339
-
340
-static bool trans_SHA256SU1_3s(DisasContext *s, arg_SHA256SU1_3s *a)
341
-{
342
- TCGv_ptr ptr1, ptr2, ptr3;
343
-
344
- if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
345
- !dc_isar_feature(aa32_sha2, s)) {
346
- return false;
347
- }
348
-
349
- /* UNDEF accesses to D16-D31 if they don't exist. */
350
- if (!dc_isar_feature(aa32_simd_r32, s) &&
351
- ((a->vd | a->vn | a->vm) & 0x10)) {
352
- return false;
353
- }
354
-
355
- if ((a->vn | a->vm | a->vd) & 1) {
356
- return false;
357
- }
358
-
359
- if (!vfp_access_check(s)) {
360
- return true;
361
- }
362
-
363
- ptr1 = vfp_reg_ptr(true, a->vd);
364
- ptr2 = vfp_reg_ptr(true, a->vn);
365
- ptr3 = vfp_reg_ptr(true, a->vm);
366
- gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
367
- tcg_temp_free_ptr(ptr1);
368
- tcg_temp_free_ptr(ptr2);
369
- tcg_temp_free_ptr(ptr3);
370
-
371
- return true;
372
-}
373
+DO_SHA2(SHA256H, gen_helper_crypto_sha256h)
374
+DO_SHA2(SHA256H2, gen_helper_crypto_sha256h2)
375
+DO_SHA2(SHA256SU1, gen_helper_crypto_sha256su1)
376
377
#define DO_3SAME_64(INSN, FUNC) \
378
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
379
diff --git a/target/arm/translate.c b/target/arm/translate.c
380
index XXXXXXX..XXXXXXX 100644
381
--- a/target/arm/translate.c
382
+++ b/target/arm/translate.c
383
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
384
int vec_size;
385
uint32_t imm;
386
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
387
- TCGv_ptr ptr1, ptr2;
388
+ TCGv_ptr ptr1;
389
TCGv_i64 tmp64;
390
391
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
392
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
393
if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
394
return 1;
395
}
396
- ptr1 = vfp_reg_ptr(true, rd);
397
- ptr2 = vfp_reg_ptr(true, rm);
398
-
399
- gen_helper_crypto_sha1h(ptr1, ptr2);
400
-
401
- tcg_temp_free_ptr(ptr1);
402
- tcg_temp_free_ptr(ptr2);
403
+ tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, 16, 16, 0,
404
+ gen_helper_crypto_sha1h);
405
break;
406
case NEON_2RM_SHA1SU1:
407
if ((rm | rd) & 1) {
408
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
409
} else if (!dc_isar_feature(aa32_sha1, s)) {
410
return 1;
411
}
412
- ptr1 = vfp_reg_ptr(true, rd);
413
- ptr2 = vfp_reg_ptr(true, rm);
414
- if (q) {
415
- gen_helper_crypto_sha256su0(ptr1, ptr2);
416
- } else {
417
- gen_helper_crypto_sha1su1(ptr1, ptr2);
418
- }
419
- tcg_temp_free_ptr(ptr1);
420
- tcg_temp_free_ptr(ptr2);
421
+ tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, 16, 16, 0,
422
+ q ? gen_helper_crypto_sha256su0
423
+ : gen_helper_crypto_sha1su1);
424
break;
425
-
426
case NEON_2RM_VMVN:
427
tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
428
break;
429
--
208
--
430
2.20.1
209
2.20.1
431
210
432
211
diff view generated by jsdifflib
1
From: Paul Zimmerman <pauldzim@gmail.com>
1
The function ide_bus_new() does an in-place initialization. Rename
2
it to ide_bus_init() to follow our _init vs _new convention.
2
3
3
Wire the dwc-hsotg (dwc2) emulation into Qemu
4
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
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
---
12
include/hw/ide/internal.h | 4 ++--
13
hw/ide/ahci.c | 2 +-
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(-)
4
24
5
Signed-off-by: Paul Zimmerman <pauldzim@gmail.com>
25
diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
6
Reviewed-by: Philippe Mathieu-Daude <f4bug@amsat.org>
7
Message-id: 20200520235349.21215-7-pauldzim@gmail.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
include/hw/arm/bcm2835_peripherals.h | 3 ++-
11
hw/arm/bcm2835_peripherals.c | 21 ++++++++++++++++++++-
12
2 files changed, 22 insertions(+), 2 deletions(-)
13
14
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
15
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/bcm2835_peripherals.h
27
--- a/include/hw/ide/internal.h
17
+++ b/include/hw/arm/bcm2835_peripherals.h
28
+++ b/include/hw/ide/internal.h
18
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@ void ide_atapi_cmd(IDEState *s);
19
#include "hw/sd/bcm2835_sdhost.h"
30
void ide_atapi_cmd_reply_end(IDEState *s);
20
#include "hw/gpio/bcm2835_gpio.h"
31
21
#include "hw/timer/bcm2835_systmr.h"
32
/* hw/ide/qdev.c */
22
+#include "hw/usb/hcd-dwc2.h"
33
-void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
23
#include "hw/misc/unimp.h"
34
- int bus_id, int max_units);
24
35
+void ide_bus_init(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
25
#define TYPE_BCM2835_PERIPHERALS "bcm2835-peripherals"
36
+ int bus_id, int max_units);
26
@@ -XXX,XX +XXX,XX @@ typedef struct BCM2835PeripheralState {
37
IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);
27
UnimplementedDeviceState ave0;
38
28
UnimplementedDeviceState bscsl;
39
int ide_handle_rw_error(IDEState *s, int error, int op);
29
UnimplementedDeviceState smi;
40
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
30
- UnimplementedDeviceState dwc2;
31
+ DWC2State dwc2;
32
UnimplementedDeviceState sdramc;
33
} BCM2835PeripheralState;
34
35
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
36
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/arm/bcm2835_peripherals.c
42
--- a/hw/ide/ahci.c
38
+++ b/hw/arm/bcm2835_peripherals.c
43
+++ b/hw/ide/ahci.c
39
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
44
@@ -XXX,XX +XXX,XX @@ void ahci_realize(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports)
40
/* Mphi */
45
for (i = 0; i < s->ports; i++) {
41
sysbus_init_child_obj(obj, "mphi", &s->mphi, sizeof(s->mphi),
46
AHCIDevice *ad = &s->dev[i];
42
TYPE_BCM2835_MPHI);
47
43
+
48
- ide_bus_new(&ad->port, sizeof(ad->port), qdev, i, 1);
44
+ /* DWC2 */
49
+ ide_bus_init(&ad->port, sizeof(ad->port), qdev, i, 1);
45
+ sysbus_init_child_obj(obj, "dwc2", &s->dwc2, sizeof(s->dwc2),
50
ide_init2(&ad->port, irqs[i]);
46
+ TYPE_DWC2_USB);
51
47
+
52
ad->hba = s;
48
+ object_property_add_const_link(OBJECT(&s->dwc2), "dma-mr",
53
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
49
+ OBJECT(&s->gpu_bus_mr));
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
{
98
MicroDriveState *md = MICRODRIVE(obj);
99
100
- ide_bus_new(&md->bus, sizeof(md->bus), DEVICE(obj), 0, 1);
101
+ ide_bus_init(&md->bus, sizeof(md->bus), DEVICE(obj), 0, 1);
50
}
102
}
51
103
52
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
104
static void microdrive_class_init(ObjectClass *oc, void *data)
53
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
105
diff --git a/hw/ide/mmio.c b/hw/ide/mmio.c
54
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
106
index XXXXXXX..XXXXXXX 100644
55
INTERRUPT_HOSTPORT));
107
--- a/hw/ide/mmio.c
56
108
+++ b/hw/ide/mmio.c
57
+ /* DWC2 */
109
@@ -XXX,XX +XXX,XX @@ static void mmio_ide_initfn(Object *obj)
58
+ object_property_set_bool(OBJECT(&s->dwc2), true, "realized", &err);
110
SysBusDevice *d = SYS_BUS_DEVICE(obj);
59
+ if (err) {
111
MMIOState *s = MMIO_IDE(obj);
60
+ error_propagate(errp, err);
112
61
+ return;
113
- ide_bus_new(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
62
+ }
114
+ ide_bus_init(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
63
+
115
sysbus_init_irq(d, &s->irq);
64
+ memory_region_add_subregion(&s->peri_mr, USB_OTG_OFFSET,
65
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dwc2), 0));
66
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->dwc2), 0,
67
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
68
+ INTERRUPT_USB));
69
+
70
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
71
create_unimp(s, &s->cprman, "bcm2835-cprman", CPRMAN_OFFSET, 0x1000);
72
create_unimp(s, &s->a2w, "bcm2835-a2w", A2W_OFFSET, 0x1000);
73
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
74
create_unimp(s, &s->otp, "bcm2835-otp", OTP_OFFSET, 0x80);
75
create_unimp(s, &s->dbus, "bcm2835-dbus", DBUS_OFFSET, 0x8000);
76
create_unimp(s, &s->ave0, "bcm2835-ave0", AVE0_OFFSET, 0x8000);
77
- create_unimp(s, &s->dwc2, "dwc-usb2", USB_OTG_OFFSET, 0x1000);
78
create_unimp(s, &s->sdramc, "bcm2835-sdramc", SDRAMC_OFFSET, 0x100);
79
}
116
}
80
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);
81
--
170
--
82
2.20.1
171
2.20.1
83
172
84
173
diff view generated by jsdifflib
1
From: Eden Mikitas <e.mikitas@gmail.com>
1
From: Xuzhou Cheng <xuzhou.cheng@windriver.com>
2
2
3
The while statement in question only checked if tx_burst is not 0.
3
The Linux spi-imx driver does not work on QEMU. The reason is that the
4
tx_burst is a signed int, which is assigned the value put by the
4
state of m25p80 loops in STATE_READING_DATA state after receiving
5
guest driver in ECSPI_CONREG. The burst length can be anywhere
5
RDSR command, the new command is ignored. Before sending a new command,
6
between 1 and 4096, and since tx_burst is always decremented by 8
6
CS line should be pulled high to make the state of m25p80 back to IDLE.
7
it could possibly underflow, causing an infinite loop.
8
7
9
Signed-off-by: Eden Mikitas <e.mikitas@gmail.com>
8
Currently the SPI flash CS line is connected to the SPI controller, but
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
on the real board, it's connected to GPIO3_19. This matches the ecspi1
10
device node in the board dts.
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
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
47
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
48
---
13
hw/ssi/imx_spi.c | 2 +-
49
hw/arm/sabrelite.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
50
1 file changed, 1 insertion(+), 1 deletion(-)
15
51
16
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
52
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
17
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/ssi/imx_spi.c
54
--- a/hw/arm/sabrelite.c
19
+++ b/hw/ssi/imx_spi.c
55
+++ b/hw/arm/sabrelite.c
20
@@ -XXX,XX +XXX,XX @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
56
@@ -XXX,XX +XXX,XX @@ static void sabrelite_init(MachineState *machine)
21
57
qdev_realize_and_unref(flash_dev, BUS(spi_bus), &error_fatal);
22
rx = 0;
58
23
59
cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
24
- while (tx_burst) {
60
- sysbus_connect_irq(SYS_BUS_DEVICE(spi_dev), 1, cs_line);
25
+ while (tx_burst > 0) {
61
+ qdev_connect_gpio_out(DEVICE(&s->gpio[2]), 19, cs_line);
26
uint8_t byte = tx & 0xff;
62
}
27
63
}
28
DPRINTF("writing 0x%02x\n", (uint32_t)byte);
64
}
29
--
65
--
30
2.20.1
66
2.20.1
31
67
32
68
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
The ADC region size is 256B, split as:
4
- [0x00 - 0x4f] defined
5
- [0x50 - 0xff] reserved
6
7
All registers are 32-bit (thus when the datasheet mentions the
8
last defined register is 0x4c, it means its address range is
9
0x4c .. 0x4f.
10
11
This model implementation is also 32-bit. Set MemoryRegionOps
12
'impl' fields.
13
14
See:
15
'RM0033 Reference manual Rev 8', Table 10.13.18 "ADC register map".
16
17
Reported-by: Seth Kintigh <skintigh@gmail.com>
18
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
19
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Message-id: 20200603055915.17678-1-f4bug@amsat.org
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
23
hw/adc/stm32f2xx_adc.c | 4 +++-
24
1 file changed, 3 insertions(+), 1 deletion(-)
25
26
diff --git a/hw/adc/stm32f2xx_adc.c b/hw/adc/stm32f2xx_adc.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/adc/stm32f2xx_adc.c
29
+++ b/hw/adc/stm32f2xx_adc.c
30
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps stm32f2xx_adc_ops = {
31
.read = stm32f2xx_adc_read,
32
.write = stm32f2xx_adc_write,
33
.endianness = DEVICE_NATIVE_ENDIAN,
34
+ .impl.min_access_size = 4,
35
+ .impl.max_access_size = 4,
36
};
37
38
static const VMStateDescription vmstate_stm32f2xx_adc = {
39
@@ -XXX,XX +XXX,XX @@ static void stm32f2xx_adc_init(Object *obj)
40
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
41
42
memory_region_init_io(&s->mmio, obj, &stm32f2xx_adc_ops, s,
43
- TYPE_STM32F2XX_ADC, 0xFF);
44
+ TYPE_STM32F2XX_ADC, 0x100);
45
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
46
}
47
48
--
49
2.20.1
50
51
diff view generated by jsdifflib
Deleted patch
1
From: Thomas Huth <thuth@redhat.com>
2
1
3
As described by Edgar here:
4
5
https://www.mail-archive.com/qemu-devel@nongnu.org/msg605124.html
6
7
we can use the Ubuntu kernel for testing the xlnx-versal-virt machine.
8
So let's add a boot test for this now.
9
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Signed-off-by: Thomas Huth <thuth@redhat.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
15
Message-id: 20200525141237.15243-1-thuth@redhat.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
tests/acceptance/boot_linux_console.py | 26 ++++++++++++++++++++++++++
19
1 file changed, 26 insertions(+)
20
21
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
22
index XXXXXXX..XXXXXXX 100644
23
--- a/tests/acceptance/boot_linux_console.py
24
+++ b/tests/acceptance/boot_linux_console.py
25
@@ -XXX,XX +XXX,XX @@ class BootLinuxConsole(LinuxKernelTest):
26
console_pattern = 'Kernel command line: %s' % kernel_command_line
27
self.wait_for_console_pattern(console_pattern)
28
29
+ def test_aarch64_xlnx_versal_virt(self):
30
+ """
31
+ :avocado: tags=arch:aarch64
32
+ :avocado: tags=machine:xlnx-versal-virt
33
+ :avocado: tags=device:pl011
34
+ :avocado: tags=device:arm_gicv3
35
+ """
36
+ kernel_url = ('http://ports.ubuntu.com/ubuntu-ports/dists/'
37
+ 'bionic-updates/main/installer-arm64/current/images/'
38
+ 'netboot/ubuntu-installer/arm64/linux')
39
+ kernel_hash = '5bfc54cf7ed8157d93f6e5b0241e727b6dc22c50'
40
+ kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
41
+
42
+ initrd_url = ('http://ports.ubuntu.com/ubuntu-ports/dists/'
43
+ 'bionic-updates/main/installer-arm64/current/images/'
44
+ 'netboot/ubuntu-installer/arm64/initrd.gz')
45
+ initrd_hash = 'd385d3e88d53e2004c5d43cbe668b458a094f772'
46
+ initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
47
+
48
+ self.vm.set_console()
49
+ self.vm.add_args('-m', '2G',
50
+ '-kernel', kernel_path,
51
+ '-initrd', initrd_path)
52
+ self.vm.launch()
53
+ self.wait_for_console_pattern('Checked W+X mappings: passed')
54
+
55
def test_arm_virt(self):
56
"""
57
:avocado: tags=arch:arm
58
--
59
2.20.1
60
61
diff view generated by jsdifflib
Deleted patch
1
From: Paul Zimmerman <pauldzim@gmail.com>
2
1
3
The dwc-hsotg (dwc2) USB host depends on a short packet to
4
indicate the end of an IN transfer. The usb-storage driver
5
currently doesn't provide this, so fix it.
6
7
I have tested this change rather extensively using a PC
8
emulation with xhci, ehci, and uhci controllers, and have
9
not observed any regressions.
10
11
Signed-off-by: Paul Zimmerman <pauldzim@gmail.com>
12
Message-id: 20200520235349.21215-6-pauldzim@gmail.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/usb/dev-storage.c | 15 ++++++++++++++-
16
1 file changed, 14 insertions(+), 1 deletion(-)
17
18
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/usb/dev-storage.c
21
+++ b/hw/usb/dev-storage.c
22
@@ -XXX,XX +XXX,XX @@ static void usb_msd_copy_data(MSDState *s, USBPacket *p)
23
usb_packet_copy(p, scsi_req_get_buf(s->req) + s->scsi_off, len);
24
s->scsi_len -= len;
25
s->scsi_off += len;
26
+ if (len > s->data_len) {
27
+ len = s->data_len;
28
+ }
29
s->data_len -= len;
30
if (s->scsi_len == 0 || s->data_len == 0) {
31
scsi_req_continue(s->req);
32
@@ -XXX,XX +XXX,XX @@ static void usb_msd_command_complete(SCSIRequest *req, uint32_t status, size_t r
33
if (s->data_len) {
34
int len = (p->iov.size - p->actual_length);
35
usb_packet_skip(p, len);
36
+ if (len > s->data_len) {
37
+ len = s->data_len;
38
+ }
39
s->data_len -= len;
40
}
41
if (s->data_len == 0) {
42
@@ -XXX,XX +XXX,XX @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
43
int len = p->iov.size - p->actual_length;
44
if (len) {
45
usb_packet_skip(p, len);
46
+ if (len > s->data_len) {
47
+ len = s->data_len;
48
+ }
49
s->data_len -= len;
50
if (s->data_len == 0) {
51
s->mode = USB_MSDM_CSW;
52
@@ -XXX,XX +XXX,XX @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
53
int len = p->iov.size - p->actual_length;
54
if (len) {
55
usb_packet_skip(p, len);
56
+ if (len > s->data_len) {
57
+ len = s->data_len;
58
+ }
59
s->data_len -= len;
60
if (s->data_len == 0) {
61
s->mode = USB_MSDM_CSW;
62
}
63
}
64
}
65
- if (p->actual_length < p->iov.size) {
66
+ if (p->actual_length < p->iov.size && (p->short_not_ok ||
67
+ s->scsi_len >= p->ep->max_packet_size)) {
68
DPRINTF("Deferring packet %p [wait data-in]\n", p);
69
s->packet = p;
70
p->status = USB_RET_ASYNC;
71
--
72
2.20.1
73
74
diff view generated by jsdifflib
Deleted patch
1
From: Paul Zimmerman <pauldzim@gmail.com>
2
1
3
Add a check for functional dwc-hsotg (dwc2) USB host emulation to
4
the Raspi 2 acceptance test
5
6
Signed-off-by: Paul Zimmerman <pauldzim@gmail.com>
7
Reviewed-by: Philippe Mathieu-Daude <f4bug@amsat.org>
8
Message-id: 20200520235349.21215-8-pauldzim@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
tests/acceptance/boot_linux_console.py | 9 +++++++--
12
1 file changed, 7 insertions(+), 2 deletions(-)
13
14
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/acceptance/boot_linux_console.py
17
+++ b/tests/acceptance/boot_linux_console.py
18
@@ -XXX,XX +XXX,XX @@ class BootLinuxConsole(LinuxKernelTest):
19
20
self.vm.set_console()
21
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
22
- serial_kernel_cmdline[uart_id])
23
+ serial_kernel_cmdline[uart_id] +
24
+ ' root=/dev/mmcblk0p2 rootwait ' +
25
+ 'dwc_otg.fiq_fsm_enable=0')
26
self.vm.add_args('-kernel', kernel_path,
27
'-dtb', dtb_path,
28
- '-append', kernel_command_line)
29
+ '-append', kernel_command_line,
30
+ '-device', 'usb-kbd')
31
self.vm.launch()
32
console_pattern = 'Kernel command line: %s' % kernel_command_line
33
self.wait_for_console_pattern(console_pattern)
34
+ console_pattern = 'Product: QEMU USB Keyboard'
35
+ self.wait_for_console_pattern(console_pattern)
36
37
def test_arm_raspi2_uart0(self):
38
"""
39
--
40
2.20.1
41
42
diff view generated by jsdifflib
Deleted patch
1
Convert the VSHL and VSLI insns from the Neon 2-registers-and-a-shift
2
group to decodetree.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200522145520.6778-2-peter.maydell@linaro.org
7
---
8
target/arm/neon-dp.decode | 25 ++++++++++++++++++++++
9
target/arm/translate-neon.inc.c | 38 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 18 +++++++---------
11
3 files changed, 71 insertions(+), 10 deletions(-)
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ VRECPS_fp_3s 1111 001 0 0 . 0 . .... .... 1111 ... 1 .... @3same_fp
18
VRSQRTS_fp_3s 1111 001 0 0 . 1 . .... .... 1111 ... 1 .... @3same_fp
19
VMAXNM_fp_3s 1111 001 1 0 . 0 . .... .... 1111 ... 1 .... @3same_fp
20
VMINNM_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 1 .... @3same_fp
21
+
22
+######################################################################
23
+# 2-reg-and-shift grouping:
24
+# 1111 001 U 1 D immH:3 immL:3 Vd:4 opc:4 L Q M 1 Vm:4
25
+######################################################################
26
+&2reg_shift vm vd q shift size
27
+
28
+@2reg_shl_d .... ... . . . shift:6 .... .... 1 q:1 . . .... \
29
+ &2reg_shift vm=%vm_dp vd=%vd_dp size=3
30
+@2reg_shl_s .... ... . . . 1 shift:5 .... .... 0 q:1 . . .... \
31
+ &2reg_shift vm=%vm_dp vd=%vd_dp size=2
32
+@2reg_shl_h .... ... . . . 01 shift:4 .... .... 0 q:1 . . .... \
33
+ &2reg_shift vm=%vm_dp vd=%vd_dp size=1
34
+@2reg_shl_b .... ... . . . 001 shift:3 .... .... 0 q:1 . . .... \
35
+ &2reg_shift vm=%vm_dp vd=%vd_dp size=0
36
+
37
+VSHL_2sh 1111 001 0 1 . ...... .... 0101 . . . 1 .... @2reg_shl_d
38
+VSHL_2sh 1111 001 0 1 . ...... .... 0101 . . . 1 .... @2reg_shl_s
39
+VSHL_2sh 1111 001 0 1 . ...... .... 0101 . . . 1 .... @2reg_shl_h
40
+VSHL_2sh 1111 001 0 1 . ...... .... 0101 . . . 1 .... @2reg_shl_b
41
+
42
+VSLI_2sh 1111 001 1 1 . ...... .... 0101 . . . 1 .... @2reg_shl_d
43
+VSLI_2sh 1111 001 1 1 . ...... .... 0101 . . . 1 .... @2reg_shl_s
44
+VSLI_2sh 1111 001 1 1 . ...... .... 0101 . . . 1 .... @2reg_shl_h
45
+VSLI_2sh 1111 001 1 1 . ...... .... 0101 . . . 1 .... @2reg_shl_b
46
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate-neon.inc.c
49
+++ b/target/arm/translate-neon.inc.c
50
@@ -XXX,XX +XXX,XX @@ static bool do_3same_fp_pair(DisasContext *s, arg_3same *a, VFPGen3OpSPFn *fn)
51
DO_3S_FP_PAIR(VPADD, gen_helper_vfp_adds)
52
DO_3S_FP_PAIR(VPMAX, gen_helper_vfp_maxs)
53
DO_3S_FP_PAIR(VPMIN, gen_helper_vfp_mins)
54
+
55
+static bool do_vector_2sh(DisasContext *s, arg_2reg_shift *a, GVecGen2iFn *fn)
56
+{
57
+ /* Handle a 2-reg-shift insn which can be vectorized. */
58
+ int vec_size = a->q ? 16 : 8;
59
+ int rd_ofs = neon_reg_offset(a->vd, 0);
60
+ int rm_ofs = neon_reg_offset(a->vm, 0);
61
+
62
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
63
+ return false;
64
+ }
65
+
66
+ /* UNDEF accesses to D16-D31 if they don't exist. */
67
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
68
+ ((a->vd | a->vm) & 0x10)) {
69
+ return false;
70
+ }
71
+
72
+ if ((a->vm | a->vd) & a->q) {
73
+ return false;
74
+ }
75
+
76
+ if (!vfp_access_check(s)) {
77
+ return true;
78
+ }
79
+
80
+ fn(a->size, rd_ofs, rm_ofs, a->shift, vec_size, vec_size);
81
+ return true;
82
+}
83
+
84
+#define DO_2SH(INSN, FUNC) \
85
+ static bool trans_##INSN##_2sh(DisasContext *s, arg_2reg_shift *a) \
86
+ { \
87
+ return do_vector_2sh(s, a, FUNC); \
88
+ } \
89
+
90
+DO_2SH(VSHL, tcg_gen_gvec_shli)
91
+DO_2SH(VSLI, gen_gvec_sli)
92
diff --git a/target/arm/translate.c b/target/arm/translate.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/target/arm/translate.c
95
+++ b/target/arm/translate.c
96
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
97
if ((insn & 0x00380080) != 0) {
98
/* Two registers and shift. */
99
op = (insn >> 8) & 0xf;
100
+
101
+ switch (op) {
102
+ case 5: /* VSHL, VSLI */
103
+ return 1; /* handled by decodetree */
104
+ default:
105
+ break;
106
+ }
107
+
108
if (insn & (1 << 7)) {
109
/* 64-bit shift. */
110
if (op > 7) {
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
112
gen_gvec_sri(size, rd_ofs, rm_ofs, shift,
113
vec_size, vec_size);
114
return 0;
115
-
116
- case 5: /* VSHL, VSLI */
117
- if (u) { /* VSLI */
118
- gen_gvec_sli(size, rd_ofs, rm_ofs, shift,
119
- vec_size, vec_size);
120
- } else { /* VSHL */
121
- tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
122
- vec_size, vec_size);
123
- }
124
- return 0;
125
}
126
127
if (size == 3) {
128
--
129
2.20.1
130
131
diff view generated by jsdifflib
Deleted patch
1
Convert the VSRA, VSRI, VRSHR, VRSRA 2-reg-shift insns to decodetree.
2
(These are the last instructions in the group that are vectorized;
3
the rest all require looping over each element.)
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200522145520.6778-4-peter.maydell@linaro.org
8
---
9
target/arm/neon-dp.decode | 35 ++++++++++++++++++++++
10
target/arm/translate-neon.inc.c | 7 +++++
11
target/arm/translate.c | 52 +++------------------------------
12
3 files changed, 46 insertions(+), 48 deletions(-)
13
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/neon-dp.decode
17
+++ b/target/arm/neon-dp.decode
18
@@ -XXX,XX +XXX,XX @@ VSHR_U_2sh 1111 001 1 1 . ...... .... 0000 . . . 1 .... @2reg_shr_s
19
VSHR_U_2sh 1111 001 1 1 . ...... .... 0000 . . . 1 .... @2reg_shr_h
20
VSHR_U_2sh 1111 001 1 1 . ...... .... 0000 . . . 1 .... @2reg_shr_b
21
22
+VSRA_S_2sh 1111 001 0 1 . ...... .... 0001 . . . 1 .... @2reg_shr_d
23
+VSRA_S_2sh 1111 001 0 1 . ...... .... 0001 . . . 1 .... @2reg_shr_s
24
+VSRA_S_2sh 1111 001 0 1 . ...... .... 0001 . . . 1 .... @2reg_shr_h
25
+VSRA_S_2sh 1111 001 0 1 . ...... .... 0001 . . . 1 .... @2reg_shr_b
26
+
27
+VSRA_U_2sh 1111 001 1 1 . ...... .... 0001 . . . 1 .... @2reg_shr_d
28
+VSRA_U_2sh 1111 001 1 1 . ...... .... 0001 . . . 1 .... @2reg_shr_s
29
+VSRA_U_2sh 1111 001 1 1 . ...... .... 0001 . . . 1 .... @2reg_shr_h
30
+VSRA_U_2sh 1111 001 1 1 . ...... .... 0001 . . . 1 .... @2reg_shr_b
31
+
32
+VRSHR_S_2sh 1111 001 0 1 . ...... .... 0010 . . . 1 .... @2reg_shr_d
33
+VRSHR_S_2sh 1111 001 0 1 . ...... .... 0010 . . . 1 .... @2reg_shr_s
34
+VRSHR_S_2sh 1111 001 0 1 . ...... .... 0010 . . . 1 .... @2reg_shr_h
35
+VRSHR_S_2sh 1111 001 0 1 . ...... .... 0010 . . . 1 .... @2reg_shr_b
36
+
37
+VRSHR_U_2sh 1111 001 1 1 . ...... .... 0010 . . . 1 .... @2reg_shr_d
38
+VRSHR_U_2sh 1111 001 1 1 . ...... .... 0010 . . . 1 .... @2reg_shr_s
39
+VRSHR_U_2sh 1111 001 1 1 . ...... .... 0010 . . . 1 .... @2reg_shr_h
40
+VRSHR_U_2sh 1111 001 1 1 . ...... .... 0010 . . . 1 .... @2reg_shr_b
41
+
42
+VRSRA_S_2sh 1111 001 0 1 . ...... .... 0011 . . . 1 .... @2reg_shr_d
43
+VRSRA_S_2sh 1111 001 0 1 . ...... .... 0011 . . . 1 .... @2reg_shr_s
44
+VRSRA_S_2sh 1111 001 0 1 . ...... .... 0011 . . . 1 .... @2reg_shr_h
45
+VRSRA_S_2sh 1111 001 0 1 . ...... .... 0011 . . . 1 .... @2reg_shr_b
46
+
47
+VRSRA_U_2sh 1111 001 1 1 . ...... .... 0011 . . . 1 .... @2reg_shr_d
48
+VRSRA_U_2sh 1111 001 1 1 . ...... .... 0011 . . . 1 .... @2reg_shr_s
49
+VRSRA_U_2sh 1111 001 1 1 . ...... .... 0011 . . . 1 .... @2reg_shr_h
50
+VRSRA_U_2sh 1111 001 1 1 . ...... .... 0011 . . . 1 .... @2reg_shr_b
51
+
52
+VSRI_2sh 1111 001 1 1 . ...... .... 0100 . . . 1 .... @2reg_shr_d
53
+VSRI_2sh 1111 001 1 1 . ...... .... 0100 . . . 1 .... @2reg_shr_s
54
+VSRI_2sh 1111 001 1 1 . ...... .... 0100 . . . 1 .... @2reg_shr_h
55
+VSRI_2sh 1111 001 1 1 . ...... .... 0100 . . . 1 .... @2reg_shr_b
56
+
57
VSHL_2sh 1111 001 0 1 . ...... .... 0101 . . . 1 .... @2reg_shl_d
58
VSHL_2sh 1111 001 0 1 . ...... .... 0101 . . . 1 .... @2reg_shl_s
59
VSHL_2sh 1111 001 0 1 . ...... .... 0101 . . . 1 .... @2reg_shl_h
60
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/translate-neon.inc.c
63
+++ b/target/arm/translate-neon.inc.c
64
@@ -XXX,XX +XXX,XX @@ static bool do_vector_2sh(DisasContext *s, arg_2reg_shift *a, GVecGen2iFn *fn)
65
66
DO_2SH(VSHL, tcg_gen_gvec_shli)
67
DO_2SH(VSLI, gen_gvec_sli)
68
+DO_2SH(VSRI, gen_gvec_sri)
69
+DO_2SH(VSRA_S, gen_gvec_ssra)
70
+DO_2SH(VSRA_U, gen_gvec_usra)
71
+DO_2SH(VRSHR_S, gen_gvec_srshr)
72
+DO_2SH(VRSHR_U, gen_gvec_urshr)
73
+DO_2SH(VRSRA_S, gen_gvec_srsra)
74
+DO_2SH(VRSRA_U, gen_gvec_ursra)
75
76
static bool trans_VSHR_S_2sh(DisasContext *s, arg_2reg_shift *a)
77
{
78
diff --git a/target/arm/translate.c b/target/arm/translate.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/arm/translate.c
81
+++ b/target/arm/translate.c
82
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
83
84
switch (op) {
85
case 0: /* VSHR */
86
+ case 1: /* VSRA */
87
+ case 2: /* VRSHR */
88
+ case 3: /* VRSRA */
89
+ case 4: /* VSRI */
90
case 5: /* VSHL, VSLI */
91
return 1; /* handled by decodetree */
92
default:
93
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
94
shift = shift - (1 << (size + 3));
95
}
96
97
- switch (op) {
98
- case 1: /* VSRA */
99
- /* Right shift comes here negative. */
100
- shift = -shift;
101
- if (u) {
102
- gen_gvec_usra(size, rd_ofs, rm_ofs, shift,
103
- vec_size, vec_size);
104
- } else {
105
- gen_gvec_ssra(size, rd_ofs, rm_ofs, shift,
106
- vec_size, vec_size);
107
- }
108
- return 0;
109
-
110
- case 2: /* VRSHR */
111
- /* Right shift comes here negative. */
112
- shift = -shift;
113
- if (u) {
114
- gen_gvec_urshr(size, rd_ofs, rm_ofs, shift,
115
- vec_size, vec_size);
116
- } else {
117
- gen_gvec_srshr(size, rd_ofs, rm_ofs, shift,
118
- vec_size, vec_size);
119
- }
120
- return 0;
121
-
122
- case 3: /* VRSRA */
123
- /* Right shift comes here negative. */
124
- shift = -shift;
125
- if (u) {
126
- gen_gvec_ursra(size, rd_ofs, rm_ofs, shift,
127
- vec_size, vec_size);
128
- } else {
129
- gen_gvec_srsra(size, rd_ofs, rm_ofs, shift,
130
- vec_size, vec_size);
131
- }
132
- return 0;
133
-
134
- case 4: /* VSRI */
135
- if (!u) {
136
- return 1;
137
- }
138
- /* Right shift comes here negative. */
139
- shift = -shift;
140
- gen_gvec_sri(size, rd_ofs, rm_ofs, shift,
141
- vec_size, vec_size);
142
- return 0;
143
- }
144
-
145
if (size == 3) {
146
count = q + 1;
147
} else {
148
--
149
2.20.1
150
151
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon narrowing shifts where op==8 to decodetree:
2
* VSHRN
3
* VRSHRN
4
* VQSHRUN
5
* VQRSHRUN
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200522145520.6778-6-peter.maydell@linaro.org
10
---
11
target/arm/neon-dp.decode | 27 ++++++
12
target/arm/translate-neon.inc.c | 167 ++++++++++++++++++++++++++++++++
13
target/arm/translate.c | 1 +
14
3 files changed, 195 insertions(+)
15
16
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/neon-dp.decode
19
+++ b/target/arm/neon-dp.decode
20
@@ -XXX,XX +XXX,XX @@ VMINNM_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 1 .... @3same_fp
21
@2reg_shl_b .... ... . . . 001 shift:3 .... .... 0 q:1 . . .... \
22
&2reg_shift vm=%vm_dp vd=%vd_dp size=0
23
24
+# Narrowing right shifts: here the Q bit is part of the opcode decode
25
+@2reg_shrn_d .... ... . . . 1 ..... .... .... 0 . . . .... \
26
+ &2reg_shift vm=%vm_dp vd=%vd_dp size=3 q=0 \
27
+ shift=%neon_rshift_i5
28
+@2reg_shrn_s .... ... . . . 01 .... .... .... 0 . . . .... \
29
+ &2reg_shift vm=%vm_dp vd=%vd_dp size=2 q=0 \
30
+ shift=%neon_rshift_i4
31
+@2reg_shrn_h .... ... . . . 001 ... .... .... 0 . . . .... \
32
+ &2reg_shift vm=%vm_dp vd=%vd_dp size=1 q=0 \
33
+ shift=%neon_rshift_i3
34
+
35
VSHR_S_2sh 1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_d
36
VSHR_S_2sh 1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_s
37
VSHR_S_2sh 1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_h
38
@@ -XXX,XX +XXX,XX @@ VQSHL_U_64_2sh 1111 001 1 1 . ...... .... 0111 . . . 1 .... @2reg_shl_d
39
VQSHL_U_2sh 1111 001 1 1 . ...... .... 0111 . . . 1 .... @2reg_shl_s
40
VQSHL_U_2sh 1111 001 1 1 . ...... .... 0111 . . . 1 .... @2reg_shl_h
41
VQSHL_U_2sh 1111 001 1 1 . ...... .... 0111 . . . 1 .... @2reg_shl_b
42
+
43
+VSHRN_64_2sh 1111 001 0 1 . ...... .... 1000 . 0 . 1 .... @2reg_shrn_d
44
+VSHRN_32_2sh 1111 001 0 1 . ...... .... 1000 . 0 . 1 .... @2reg_shrn_s
45
+VSHRN_16_2sh 1111 001 0 1 . ...... .... 1000 . 0 . 1 .... @2reg_shrn_h
46
+
47
+VRSHRN_64_2sh 1111 001 0 1 . ...... .... 1000 . 1 . 1 .... @2reg_shrn_d
48
+VRSHRN_32_2sh 1111 001 0 1 . ...... .... 1000 . 1 . 1 .... @2reg_shrn_s
49
+VRSHRN_16_2sh 1111 001 0 1 . ...... .... 1000 . 1 . 1 .... @2reg_shrn_h
50
+
51
+VQSHRUN_64_2sh 1111 001 1 1 . ...... .... 1000 . 0 . 1 .... @2reg_shrn_d
52
+VQSHRUN_32_2sh 1111 001 1 1 . ...... .... 1000 . 0 . 1 .... @2reg_shrn_s
53
+VQSHRUN_16_2sh 1111 001 1 1 . ...... .... 1000 . 0 . 1 .... @2reg_shrn_h
54
+
55
+VQRSHRUN_64_2sh 1111 001 1 1 . ...... .... 1000 . 1 . 1 .... @2reg_shrn_d
56
+VQRSHRUN_32_2sh 1111 001 1 1 . ...... .... 1000 . 1 . 1 .... @2reg_shrn_s
57
+VQRSHRUN_16_2sh 1111 001 1 1 . ...... .... 1000 . 1 . 1 .... @2reg_shrn_h
58
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/translate-neon.inc.c
61
+++ b/target/arm/translate-neon.inc.c
62
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_32(DisasContext *s, arg_2reg_shift *a,
63
DO_2SHIFT_ENV(VQSHLU, qshlu_s)
64
DO_2SHIFT_ENV(VQSHL_U, qshl_u)
65
DO_2SHIFT_ENV(VQSHL_S, qshl_s)
66
+
67
+static bool do_2shift_narrow_64(DisasContext *s, arg_2reg_shift *a,
68
+ NeonGenTwo64OpFn *shiftfn,
69
+ NeonGenNarrowEnvFn *narrowfn)
70
+{
71
+ /* 2-reg-and-shift narrowing-shift operations, size == 3 case */
72
+ TCGv_i64 constimm, rm1, rm2;
73
+ TCGv_i32 rd;
74
+
75
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
76
+ return false;
77
+ }
78
+
79
+ /* UNDEF accesses to D16-D31 if they don't exist. */
80
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
81
+ ((a->vd | a->vm) & 0x10)) {
82
+ return false;
83
+ }
84
+
85
+ if (a->vm & 1) {
86
+ return false;
87
+ }
88
+
89
+ if (!vfp_access_check(s)) {
90
+ return true;
91
+ }
92
+
93
+ /*
94
+ * This is always a right shift, and the shiftfn is always a
95
+ * left-shift helper, which thus needs the negated shift count.
96
+ */
97
+ constimm = tcg_const_i64(-a->shift);
98
+ rm1 = tcg_temp_new_i64();
99
+ rm2 = tcg_temp_new_i64();
100
+
101
+ /* Load both inputs first to avoid potential overwrite if rm == rd */
102
+ neon_load_reg64(rm1, a->vm);
103
+ neon_load_reg64(rm2, a->vm + 1);
104
+
105
+ shiftfn(rm1, rm1, constimm);
106
+ rd = tcg_temp_new_i32();
107
+ narrowfn(rd, cpu_env, rm1);
108
+ neon_store_reg(a->vd, 0, rd);
109
+
110
+ shiftfn(rm2, rm2, constimm);
111
+ rd = tcg_temp_new_i32();
112
+ narrowfn(rd, cpu_env, rm2);
113
+ neon_store_reg(a->vd, 1, rd);
114
+
115
+ tcg_temp_free_i64(rm1);
116
+ tcg_temp_free_i64(rm2);
117
+ tcg_temp_free_i64(constimm);
118
+
119
+ return true;
120
+}
121
+
122
+static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
123
+ NeonGenTwoOpFn *shiftfn,
124
+ NeonGenNarrowEnvFn *narrowfn)
125
+{
126
+ /* 2-reg-and-shift narrowing-shift operations, size < 3 case */
127
+ TCGv_i32 constimm, rm1, rm2, rm3, rm4;
128
+ TCGv_i64 rtmp;
129
+ uint32_t imm;
130
+
131
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
132
+ return false;
133
+ }
134
+
135
+ /* UNDEF accesses to D16-D31 if they don't exist. */
136
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
137
+ ((a->vd | a->vm) & 0x10)) {
138
+ return false;
139
+ }
140
+
141
+ if (a->vm & 1) {
142
+ return false;
143
+ }
144
+
145
+ if (!vfp_access_check(s)) {
146
+ return true;
147
+ }
148
+
149
+ /*
150
+ * This is always a right shift, and the shiftfn is always a
151
+ * left-shift helper, which thus needs the negated shift count
152
+ * duplicated into each lane of the immediate value.
153
+ */
154
+ if (a->size == 1) {
155
+ imm = (uint16_t)(-a->shift);
156
+ imm |= imm << 16;
157
+ } else {
158
+ /* size == 2 */
159
+ imm = -a->shift;
160
+ }
161
+ constimm = tcg_const_i32(imm);
162
+
163
+ /* Load all inputs first to avoid potential overwrite */
164
+ rm1 = neon_load_reg(a->vm, 0);
165
+ rm2 = neon_load_reg(a->vm, 1);
166
+ rm3 = neon_load_reg(a->vm + 1, 0);
167
+ rm4 = neon_load_reg(a->vm + 1, 1);
168
+ rtmp = tcg_temp_new_i64();
169
+
170
+ shiftfn(rm1, rm1, constimm);
171
+ shiftfn(rm2, rm2, constimm);
172
+
173
+ tcg_gen_concat_i32_i64(rtmp, rm1, rm2);
174
+ tcg_temp_free_i32(rm2);
175
+
176
+ narrowfn(rm1, cpu_env, rtmp);
177
+ neon_store_reg(a->vd, 0, rm1);
178
+
179
+ shiftfn(rm3, rm3, constimm);
180
+ shiftfn(rm4, rm4, constimm);
181
+ tcg_temp_free_i32(constimm);
182
+
183
+ tcg_gen_concat_i32_i64(rtmp, rm3, rm4);
184
+ tcg_temp_free_i32(rm4);
185
+
186
+ narrowfn(rm3, cpu_env, rtmp);
187
+ tcg_temp_free_i64(rtmp);
188
+ neon_store_reg(a->vd, 1, rm3);
189
+ return true;
190
+}
191
+
192
+#define DO_2SN_64(INSN, FUNC, NARROWFUNC) \
193
+ static bool trans_##INSN##_2sh(DisasContext *s, arg_2reg_shift *a) \
194
+ { \
195
+ return do_2shift_narrow_64(s, a, FUNC, NARROWFUNC); \
196
+ }
197
+#define DO_2SN_32(INSN, FUNC, NARROWFUNC) \
198
+ static bool trans_##INSN##_2sh(DisasContext *s, arg_2reg_shift *a) \
199
+ { \
200
+ return do_2shift_narrow_32(s, a, FUNC, NARROWFUNC); \
201
+ }
202
+
203
+static void gen_neon_narrow_u32(TCGv_i32 dest, TCGv_ptr env, TCGv_i64 src)
204
+{
205
+ tcg_gen_extrl_i64_i32(dest, src);
206
+}
207
+
208
+static void gen_neon_narrow_u16(TCGv_i32 dest, TCGv_ptr env, TCGv_i64 src)
209
+{
210
+ gen_helper_neon_narrow_u16(dest, src);
211
+}
212
+
213
+static void gen_neon_narrow_u8(TCGv_i32 dest, TCGv_ptr env, TCGv_i64 src)
214
+{
215
+ gen_helper_neon_narrow_u8(dest, src);
216
+}
217
+
218
+DO_2SN_64(VSHRN_64, gen_ushl_i64, gen_neon_narrow_u32)
219
+DO_2SN_32(VSHRN_32, gen_ushl_i32, gen_neon_narrow_u16)
220
+DO_2SN_32(VSHRN_16, gen_helper_neon_shl_u16, gen_neon_narrow_u8)
221
+
222
+DO_2SN_64(VRSHRN_64, gen_helper_neon_rshl_u64, gen_neon_narrow_u32)
223
+DO_2SN_32(VRSHRN_32, gen_helper_neon_rshl_u32, gen_neon_narrow_u16)
224
+DO_2SN_32(VRSHRN_16, gen_helper_neon_rshl_u16, gen_neon_narrow_u8)
225
+
226
+DO_2SN_64(VQSHRUN_64, gen_sshl_i64, gen_helper_neon_unarrow_sat32)
227
+DO_2SN_32(VQSHRUN_32, gen_sshl_i32, gen_helper_neon_unarrow_sat16)
228
+DO_2SN_32(VQSHRUN_16, gen_helper_neon_shl_s16, gen_helper_neon_unarrow_sat8)
229
+
230
+DO_2SN_64(VQRSHRUN_64, gen_helper_neon_rshl_s64, gen_helper_neon_unarrow_sat32)
231
+DO_2SN_32(VQRSHRUN_32, gen_helper_neon_rshl_s32, gen_helper_neon_unarrow_sat16)
232
+DO_2SN_32(VQRSHRUN_16, gen_helper_neon_rshl_s16, gen_helper_neon_unarrow_sat8)
233
diff --git a/target/arm/translate.c b/target/arm/translate.c
234
index XXXXXXX..XXXXXXX 100644
235
--- a/target/arm/translate.c
236
+++ b/target/arm/translate.c
237
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
238
case 5: /* VSHL, VSLI */
239
case 6: /* VQSHLU */
240
case 7: /* VQSHL */
241
+ case 8: /* VSHRN, VRSHRN, VQSHRUN, VQRSHRUN */
242
return 1; /* handled by decodetree */
243
default:
244
break;
245
--
246
2.20.1
247
248
diff view generated by jsdifflib