1
The following changes since commit 7e7eb9f852a46b51a71ae9d82590b2e4d28827ee:
1
Nothing too exciting in this lot :-)
2
2
3
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-01-28' into staging (2021-01-28 22:43:18 +0000)
3
The following changes since commit ba0fa56bc06e563de68d2a2bf3ddb0cfea1be4f9:
4
5
Merge remote-tracking branch 'remotes/vivier/tags/q800-for-6.2-pull-request' into staging (2021-09-29 21:20:49 +0100)
4
6
5
are available in the Git repository at:
7
are available in the Git repository at:
6
8
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210129
9
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210930
8
10
9
for you to fetch changes up to 11749122e1a86866591306d43603d2795a3dea1a:
11
for you to fetch changes up to 1f4b2ec701b9d73d3fa7bb90c8b4376bc7d3c42b:
10
12
11
hw/arm/stellaris: Remove board-creation reset of STELLARIS_SYS (2021-01-29 10:47:29 +0000)
13
hw/arm: sabrelite: Connect SPI flash CS line to GPIO3_19 (2021-09-30 13:44:13 +0100)
12
14
13
----------------------------------------------------------------
15
----------------------------------------------------------------
14
target-arm queue:
16
target-arm queue:
15
* Implement ID_PFR2
17
* allwinner-h3: Switch to SMC as PSCI conduit
16
* Conditionalize DBGDIDR
18
* arm: tcg: Adhere to SMCCC 1.3 section 5.2
17
* rename xlnx-zcu102.canbusN properties
19
* xlnx-zcu102, xlnx-versal-virt: Support BBRAM and eFUSE devices
18
* provide powerdown/reset mechanism for secure firmware on 'virt' board
20
* gdbstub related code cleanups
19
* hw/misc: Fix arith overflow in NPCM7XX PWM module
21
* Don't put FPEXC and FPSID in org.gnu.gdb.arm.vfp XML
20
* target/arm: Replace magic value by MMU_DATA_LOAD definition
22
* Use _init vs _new convention in bus creation function names
21
* configure: fix preadv errors on Catalina macOS with new XCode
23
* sabrelite: Connect SPI flash CS line to GPIO3_19
22
* Various configure and other cleanups in preparation for iOS support
23
* hvf: Add hypervisor entitlement to output binaries (needed for Big Sur)
24
* Implement pvpanic-pci device
25
* Convert the CMSDK timer devices to the Clock framework
26
24
27
----------------------------------------------------------------
25
----------------------------------------------------------------
28
Alexander Graf (1):
26
Alexander Graf (2):
29
hvf: Add hypervisor entitlement to output binaries
27
allwinner-h3: Switch to SMC as PSCI conduit
28
arm: tcg: Adhere to SMCCC 1.3 section 5.2
30
29
31
Hao Wu (1):
30
Peter Maydell (10):
32
hw/misc: Fix arith overflow in NPCM7XX PWM module
31
configs: Don't include 32-bit-only GDB XML in aarch64 linux configs
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()
33
41
34
Joelle van Dyne (7):
42
Tong Ho (9):
35
configure: cross-compiling with empty cross_prefix
43
hw/nvram: Introduce Xilinx eFuse QOM
36
osdep: build with non-working system() function
44
hw/nvram: Introduce Xilinx Versal eFuse device
37
darwin: remove redundant dependency declaration
45
hw/nvram: Introduce Xilinx ZynqMP eFuse device
38
darwin: fix cross-compiling for Darwin
46
hw/nvram: Introduce Xilinx battery-backed ram
39
configure: cross compile should use x86_64 cpu_family
47
hw/arm: xlnx-versal-virt: Add Xilinx BBRAM device
40
darwin: detect CoreAudio for build
48
hw/arm: xlnx-versal-virt: Add Xilinx eFUSE device
41
darwin: remove 64-bit build detection on 32-bit OS
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
42
52
43
Maxim Uvarov (3):
53
Xuzhou Cheng (1):
44
hw: gpio: implement gpio-pwr driver for qemu reset/poweroff
54
hw/arm: sabrelite: Connect SPI flash CS line to GPIO3_19
45
arm-virt: refactor gpios creation
46
arm-virt: add secure pl061 for reset/power down
47
55
48
Mihai Carabas (4):
56
docs/system/arm/xlnx-versal-virt.rst | 49 ++
49
hw/misc/pvpanic: split-out generic and bus dependent code
57
configs/targets/aarch64-linux-user.mak | 2 +-
50
hw/misc/pvpanic: add PCI interface support
58
configs/targets/aarch64-softmmu.mak | 2 +-
51
pvpanic : update pvpanic spec document
59
configs/targets/aarch64_be-linux-user.mak | 2 +-
52
tests/qtest: add a test case for pvpanic-pci
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
53
176
54
Paolo Bonzini (1):
55
arm: rename xlnx-zcu102.canbusN properties
56
57
Peter Maydell (26):
58
configure: Move preadv check to meson.build
59
ptimer: Add new ptimer_set_period_from_clock() function
60
clock: Add new clock_has_source() function
61
tests: Add a simple test of the CMSDK APB timer
62
tests: Add a simple test of the CMSDK APB watchdog
63
tests: Add a simple test of the CMSDK APB dual timer
64
hw/timer/cmsdk-apb-timer: Rename CMSDKAPBTIMER struct to CMSDKAPBTimer
65
hw/timer/cmsdk-apb-timer: Add Clock input
66
hw/timer/cmsdk-apb-dualtimer: Add Clock input
67
hw/watchdog/cmsdk-apb-watchdog: Add Clock input
68
hw/arm/armsse: Rename "MAINCLK" property to "MAINCLK_FRQ"
69
hw/arm/armsse: Wire up clocks
70
hw/arm/mps2: Inline CMSDK_APB_TIMER creation
71
hw/arm/mps2: Create and connect SYSCLK Clock
72
hw/arm/mps2-tz: Create and connect ARMSSE Clocks
73
hw/arm/musca: Create and connect ARMSSE Clocks
74
hw/arm/stellaris: Convert SSYS to QOM device
75
hw/arm/stellaris: Create Clock input for watchdog
76
hw/timer/cmsdk-apb-timer: Convert to use Clock input
77
hw/timer/cmsdk-apb-dualtimer: Convert to use Clock input
78
hw/watchdog/cmsdk-apb-watchdog: Convert to use Clock input
79
tests/qtest/cmsdk-apb-watchdog-test: Test clock changes
80
hw/arm/armsse: Use Clock to set system_clock_scale
81
arm: Don't set freq properties on CMSDK timer, dualtimer, watchdog, ARMSSE
82
arm: Remove frq properties on CMSDK timer, dualtimer, watchdog, ARMSSE
83
hw/arm/stellaris: Remove board-creation reset of STELLARIS_SYS
84
85
Philippe Mathieu-Daudé (1):
86
target/arm: Replace magic value by MMU_DATA_LOAD definition
87
88
Richard Henderson (2):
89
target/arm: Implement ID_PFR2
90
target/arm: Conditionalize DBGDIDR
91
92
docs/devel/clocks.rst | 16 +++
93
docs/specs/pci-ids.txt | 1 +
94
docs/specs/pvpanic.txt | 13 ++-
95
docs/system/arm/virt.rst | 2 +
96
configure | 78 ++++++++------
97
meson.build | 34 ++++++-
98
include/hw/arm/armsse.h | 14 ++-
99
include/hw/arm/virt.h | 2 +
100
include/hw/clock.h | 15 +++
101
include/hw/misc/pvpanic.h | 24 ++++-
102
include/hw/pci/pci.h | 1 +
103
include/hw/ptimer.h | 22 ++++
104
include/hw/timer/cmsdk-apb-dualtimer.h | 5 +-
105
include/hw/timer/cmsdk-apb-timer.h | 34 ++-----
106
include/hw/watchdog/cmsdk-apb-watchdog.h | 5 +-
107
include/qemu/osdep.h | 12 +++
108
include/qemu/typedefs.h | 1 +
109
target/arm/cpu.h | 1 +
110
hw/arm/armsse.c | 48 ++++++---
111
hw/arm/mps2-tz.c | 14 ++-
112
hw/arm/mps2.c | 28 ++++-
113
hw/arm/musca.c | 13 ++-
114
hw/arm/stellaris.c | 170 +++++++++++++++++++++++--------
115
hw/arm/virt.c | 111 ++++++++++++++++----
116
hw/arm/xlnx-zcu102.c | 4 +-
117
hw/core/ptimer.c | 34 +++++++
118
hw/gpio/gpio_pwr.c | 70 +++++++++++++
119
hw/misc/npcm7xx_pwm.c | 23 ++++-
120
hw/misc/pvpanic-isa.c | 94 +++++++++++++++++
121
hw/misc/pvpanic-pci.c | 94 +++++++++++++++++
122
hw/misc/pvpanic.c | 85 ++--------------
123
hw/timer/cmsdk-apb-dualtimer.c | 53 +++++++---
124
hw/timer/cmsdk-apb-timer.c | 55 +++++-----
125
hw/watchdog/cmsdk-apb-watchdog.c | 29 ++++--
126
target/arm/helper.c | 27 +++--
127
target/arm/kvm64.c | 2 +
128
tests/qtest/cmsdk-apb-dualtimer-test.c | 130 +++++++++++++++++++++++
129
tests/qtest/cmsdk-apb-timer-test.c | 75 ++++++++++++++
130
tests/qtest/cmsdk-apb-watchdog-test.c | 131 ++++++++++++++++++++++++
131
tests/qtest/npcm7xx_pwm-test.c | 4 +-
132
tests/qtest/pvpanic-pci-test.c | 94 +++++++++++++++++
133
tests/qtest/xlnx-can-test.c | 30 +++---
134
MAINTAINERS | 3 +
135
accel/hvf/entitlements.plist | 8 ++
136
hw/arm/Kconfig | 1 +
137
hw/gpio/Kconfig | 3 +
138
hw/gpio/meson.build | 1 +
139
hw/i386/Kconfig | 2 +-
140
hw/misc/Kconfig | 12 ++-
141
hw/misc/meson.build | 4 +-
142
scripts/entitlement.sh | 13 +++
143
tests/qtest/meson.build | 6 +-
144
52 files changed, 1432 insertions(+), 319 deletions(-)
145
create mode 100644 hw/gpio/gpio_pwr.c
146
create mode 100644 hw/misc/pvpanic-isa.c
147
create mode 100644 hw/misc/pvpanic-pci.c
148
create mode 100644 tests/qtest/cmsdk-apb-dualtimer-test.c
149
create mode 100644 tests/qtest/cmsdk-apb-timer-test.c
150
create mode 100644 tests/qtest/cmsdk-apb-watchdog-test.c
151
create mode 100644 tests/qtest/pvpanic-pci-test.c
152
create mode 100644 accel/hvf/entitlements.plist
153
create mode 100755 scripts/entitlement.sh
154
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This was defined at some point before ARMv8.4, and will
4
shortly be used by new processor descriptions.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210120204400.1056582-1-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/cpu.h | 1 +
12
target/arm/helper.c | 4 ++--
13
target/arm/kvm64.c | 2 ++
14
3 files changed, 5 insertions(+), 2 deletions(-)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
21
uint32_t id_mmfr4;
22
uint32_t id_pfr0;
23
uint32_t id_pfr1;
24
+ uint32_t id_pfr2;
25
uint32_t mvfr0;
26
uint32_t mvfr1;
27
uint32_t mvfr2;
28
diff --git a/target/arm/helper.c b/target/arm/helper.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/helper.c
31
+++ b/target/arm/helper.c
32
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
33
.access = PL1_R, .type = ARM_CP_CONST,
34
.accessfn = access_aa64_tid3,
35
.resetvalue = 0 },
36
- { .name = "MVFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
37
+ { .name = "ID_PFR2", .state = ARM_CP_STATE_BOTH,
38
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4,
39
.access = PL1_R, .type = ARM_CP_CONST,
40
.accessfn = access_aa64_tid3,
41
- .resetvalue = 0 },
42
+ .resetvalue = cpu->isar.id_pfr2 },
43
{ .name = "MVFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
44
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5,
45
.access = PL1_R, .type = ARM_CP_CONST,
46
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/kvm64.c
49
+++ b/target/arm/kvm64.c
50
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
51
ARM64_SYS_REG(3, 0, 0, 1, 0));
52
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr1,
53
ARM64_SYS_REG(3, 0, 0, 1, 1));
54
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr2,
55
+ ARM64_SYS_REG(3, 0, 0, 3, 4));
56
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
57
ARM64_SYS_REG(3, 0, 0, 1, 2));
58
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
59
--
60
2.20.1
61
62
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
In macOS 11, QEMU only gets access to Hypervisor.framework if it has the
3
The Allwinner H3 SoC uses Cortex-A7 cores which support virtualization.
4
respective entitlement. Add an entitlement template and automatically self
4
However, today we are configuring QEMU to use HVC as PSCI conduit.
5
sign and apply the entitlement in the build.
5
6
That means HVC calls get trapped into QEMU instead of the guest's own
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.
6
10
7
Signed-off-by: Alexander Graf <agraf@csgraf.de>
11
Signed-off-by: Alexander Graf <agraf@csgraf.de>
8
Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
12
Message-id: 20210920203931.66527-1-agraf@csgraf.de
9
Tested-by: Roman Bolshakov <r.bolshakov@yadro.com>
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>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
19
---
12
meson.build | 29 +++++++++++++++++++++++++----
20
hw/arm/allwinner-h3.c | 2 +-
13
accel/hvf/entitlements.plist | 8 ++++++++
21
1 file changed, 1 insertion(+), 1 deletion(-)
14
scripts/entitlement.sh | 13 +++++++++++++
15
3 files changed, 46 insertions(+), 4 deletions(-)
16
create mode 100644 accel/hvf/entitlements.plist
17
create mode 100755 scripts/entitlement.sh
18
22
19
diff --git a/meson.build b/meson.build
23
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
20
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
21
--- a/meson.build
25
--- a/hw/arm/allwinner-h3.c
22
+++ b/meson.build
26
+++ b/hw/arm/allwinner-h3.c
23
@@ -XXX,XX +XXX,XX @@ foreach target : target_dirs
27
@@ -XXX,XX +XXX,XX @@ static void allwinner_h3_realize(DeviceState *dev, Error **errp)
24
}]
28
25
endif
29
/* Provide Power State Coordination Interface */
26
foreach exe: execs
30
qdev_prop_set_int32(DEVICE(&s->cpus[i]), "psci-conduit",
27
- emulators += {exe['name']:
31
- QEMU_PSCI_CONDUIT_HVC);
28
- executable(exe['name'], exe['sources'],
32
+ QEMU_PSCI_CONDUIT_SMC);
29
- install: true,
33
30
+ exe_name = exe['name']
34
/* Disable secondary CPUs */
31
+ exe_sign = 'CONFIG_HVF' in config_target
35
qdev_prop_set_bit(DEVICE(&s->cpus[i]), "start-powered-off",
32
+ if exe_sign
33
+ exe_name += '-unsigned'
34
+ endif
35
+
36
+ emulator = executable(exe_name, exe['sources'],
37
+ install: not exe_sign,
38
c_args: c_args,
39
dependencies: arch_deps + deps + exe['dependencies'],
40
objects: lib.extract_all_objects(recursive: true),
41
@@ -XXX,XX +XXX,XX @@ foreach target : target_dirs
42
link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
43
link_args: link_args,
44
gui_app: exe['gui'])
45
- }
46
+
47
+ if exe_sign
48
+ emulators += {exe['name'] : custom_target(exe['name'],
49
+ install: true,
50
+ install_dir: get_option('bindir'),
51
+ depends: emulator,
52
+ output: exe['name'],
53
+ command: [
54
+ meson.current_source_dir() / 'scripts/entitlement.sh',
55
+ meson.current_build_dir() / exe_name,
56
+ meson.current_build_dir() / exe['name'],
57
+ meson.current_source_dir() / 'accel/hvf/entitlements.plist'
58
+ ])
59
+ }
60
+ else
61
+ emulators += {exe['name']: emulator}
62
+ endif
63
64
if 'CONFIG_TRACE_SYSTEMTAP' in config_host
65
foreach stp: [
66
diff --git a/accel/hvf/entitlements.plist b/accel/hvf/entitlements.plist
67
new file mode 100644
68
index XXXXXXX..XXXXXXX
69
--- /dev/null
70
+++ b/accel/hvf/entitlements.plist
71
@@ -XXX,XX +XXX,XX @@
72
+<?xml version="1.0" encoding="UTF-8"?>
73
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
74
+<plist version="1.0">
75
+<dict>
76
+ <key>com.apple.security.hypervisor</key>
77
+ <true/>
78
+</dict>
79
+</plist>
80
diff --git a/scripts/entitlement.sh b/scripts/entitlement.sh
81
new file mode 100755
82
index XXXXXXX..XXXXXXX
83
--- /dev/null
84
+++ b/scripts/entitlement.sh
85
@@ -XXX,XX +XXX,XX @@
86
+#!/bin/sh -e
87
+#
88
+# Helper script for the build process to apply entitlements
89
+
90
+SRC="$1"
91
+DST="$2"
92
+ENTITLEMENT="$3"
93
+
94
+trap 'rm "$DST.tmp"' exit
95
+cp -af "$SRC" "$DST.tmp"
96
+codesign --entitlements "$ENTITLEMENT" --force -s - "$DST.tmp"
97
+mv "$DST.tmp" "$DST"
98
+trap '' exit
99
--
36
--
100
2.20.1
37
2.20.1
101
38
102
39
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Fix potential overflow problem when calculating pwm_duty.
3
The SMCCC 1.3 spec section 5.2 says
4
1. Ensure p->cmr and p->cnr to be from [0,65535], according to the
5
hardware specification.
6
2. Changed duty to uint32_t. However, since MAX_DUTY * (p->cmr+1)
7
can excceed UINT32_MAX, we convert them to uint64_t in computation
8
and converted them back to uint32_t.
9
(duty is guaranteed to be <= MAX_DUTY so it won't overflow.)
10
4
11
Fixes: CID 1442342
5
The Unknown SMC Function Identifier is a sign-extended value of (-1)
12
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
that is returned in the R0, W0 or X0 registers. An implementation must
13
Reviewed-by: Doug Evans <dje@google.com>
7
return this error code when it receives:
14
Signed-off-by: Hao Wu <wuhaotsh@google.com>
8
15
Message-id: 20210127011142.2122790-1-wuhaotsh@google.com
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>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
---
19
hw/misc/npcm7xx_pwm.c | 23 +++++++++++++++++++----
20
target/arm/psci.c | 35 ++++++-----------------------------
20
tests/qtest/npcm7xx_pwm-test.c | 4 ++--
21
1 file changed, 6 insertions(+), 29 deletions(-)
21
2 files changed, 21 insertions(+), 6 deletions(-)
22
22
23
diff --git a/hw/misc/npcm7xx_pwm.c b/hw/misc/npcm7xx_pwm.c
23
diff --git a/target/arm/psci.c b/target/arm/psci.c
24
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/misc/npcm7xx_pwm.c
25
--- a/target/arm/psci.c
26
+++ b/hw/misc/npcm7xx_pwm.c
26
+++ b/target/arm/psci.c
27
@@ -XXX,XX +XXX,XX @@ REG32(NPCM7XX_PWM_PWDR3, 0x50);
27
@@ -XXX,XX +XXX,XX @@
28
#define NPCM7XX_CH_INV BIT(2)
28
29
#define NPCM7XX_CH_MOD BIT(3)
29
bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
30
31
+#define NPCM7XX_MAX_CMR 65535
32
+#define NPCM7XX_MAX_CNR 65535
33
+
34
/* Offset of each PWM channel's prescaler in the PPR register. */
35
static const int npcm7xx_ppr_base[] = { 0, 0, 8, 8 };
36
/* Offset of each PWM channel's clock selector in the CSR register. */
37
@@ -XXX,XX +XXX,XX @@ static uint32_t npcm7xx_pwm_calculate_freq(NPCM7xxPWM *p)
38
39
static uint32_t npcm7xx_pwm_calculate_duty(NPCM7xxPWM *p)
40
{
30
{
41
- uint64_t duty;
31
- /* Return true if the r0/x0 value indicates a PSCI call and
42
+ uint32_t duty;
32
- * the exception type matches the configured PSCI conduit. This is
43
33
- * called before the SMC/HVC instruction is executed, to decide whether
44
if (p->running) {
34
- * we should treat it as a PSCI call or with the architecturally
45
if (p->cnr == 0) {
35
+ /*
46
@@ -XXX,XX +XXX,XX @@ static uint32_t npcm7xx_pwm_calculate_duty(NPCM7xxPWM *p)
36
+ * Return true if the exception type matches the configured PSCI conduit.
47
} else if (p->cmr >= p->cnr) {
37
+ * This is called before the SMC/HVC instruction is executed, to decide
48
duty = NPCM7XX_PWM_MAX_DUTY;
38
+ * whether we should treat it as a PSCI call or with the architecturally
49
} else {
39
* defined behaviour for an SMC or HVC (which might be UNDEF or trap
50
- duty = NPCM7XX_PWM_MAX_DUTY * (p->cmr + 1) / (p->cnr + 1);
40
* to EL2 or to EL3).
51
+ duty = (uint64_t)NPCM7XX_PWM_MAX_DUTY * (p->cmr + 1) / (p->cnr + 1);
41
*/
52
}
42
- CPUARMState *env = &cpu->env;
53
} else {
43
- uint64_t param = is_a64(env) ? env->xregs[0] : env->regs[0];
54
duty = 0;
44
55
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_pwm_write(void *opaque, hwaddr offset,
45
switch (excp_type) {
56
case A_NPCM7XX_PWM_CNR2:
46
case EXCP_HVC:
57
case A_NPCM7XX_PWM_CNR3:
47
@@ -XXX,XX +XXX,XX @@ bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
58
p = &s->pwm[npcm7xx_cnr_index(offset)];
48
return false;
59
- p->cnr = value;
49
}
60
+ if (value > NPCM7XX_MAX_CNR) {
50
61
+ qemu_log_mask(LOG_GUEST_ERROR,
51
- switch (param) {
62
+ "%s: invalid cnr value: %u", __func__, value);
52
- case QEMU_PSCI_0_2_FN_PSCI_VERSION:
63
+ p->cnr = NPCM7XX_MAX_CNR;
53
- case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
64
+ } else {
54
- case QEMU_PSCI_0_2_FN_AFFINITY_INFO:
65
+ p->cnr = value;
55
- case QEMU_PSCI_0_2_FN64_AFFINITY_INFO:
66
+ }
56
- case QEMU_PSCI_0_2_FN_SYSTEM_RESET:
67
npcm7xx_pwm_update_output(p);
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;
73
}
74
75
void arm_handle_psci_call(ARMCPU *cpu)
76
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
68
break;
77
break;
69
78
case QEMU_PSCI_0_1_FN_MIGRATE:
70
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_pwm_write(void *opaque, hwaddr offset,
79
case QEMU_PSCI_0_2_FN_MIGRATE:
71
case A_NPCM7XX_PWM_CMR2:
80
+ default:
72
case A_NPCM7XX_PWM_CMR3:
81
ret = QEMU_PSCI_RET_NOT_SUPPORTED;
73
p = &s->pwm[npcm7xx_cmr_index(offset)];
74
- p->cmr = value;
75
+ if (value > NPCM7XX_MAX_CMR) {
76
+ qemu_log_mask(LOG_GUEST_ERROR,
77
+ "%s: invalid cmr value: %u", __func__, value);
78
+ p->cmr = NPCM7XX_MAX_CMR;
79
+ } else {
80
+ p->cmr = value;
81
+ }
82
npcm7xx_pwm_update_output(p);
83
break;
82
break;
84
83
- default:
85
diff --git a/tests/qtest/npcm7xx_pwm-test.c b/tests/qtest/npcm7xx_pwm-test.c
84
- g_assert_not_reached();
86
index XXXXXXX..XXXXXXX 100644
87
--- a/tests/qtest/npcm7xx_pwm-test.c
88
+++ b/tests/qtest/npcm7xx_pwm-test.c
89
@@ -XXX,XX +XXX,XX @@ static uint64_t pwm_compute_freq(QTestState *qts, uint32_t ppr, uint32_t csr,
90
91
static uint64_t pwm_compute_duty(uint32_t cnr, uint32_t cmr, bool inverted)
92
{
93
- uint64_t duty;
94
+ uint32_t duty;
95
96
if (cnr == 0) {
97
/* PWM is stopped. */
98
@@ -XXX,XX +XXX,XX @@ static uint64_t pwm_compute_duty(uint32_t cnr, uint32_t cmr, bool inverted)
99
} else if (cmr >= cnr) {
100
duty = MAX_DUTY;
101
} else {
102
- duty = MAX_DUTY * (cmr + 1) / (cnr + 1);
103
+ duty = (uint64_t)MAX_DUTY * (cmr + 1) / (cnr + 1);
104
}
85
}
105
86
106
if (inverted) {
87
err:
107
--
88
--
108
2.20.1
89
2.20.1
109
90
110
91
diff view generated by jsdifflib
1
From: Mihai Carabas <mihai.carabas@oracle.com>
1
From: Tong Ho <tong.ho@xilinx.com>
2
2
3
Add a test case for pvpanic-pci device. The scenario is the same as pvpanic
3
This introduces the QOM for Xilinx eFuse, an one-time
4
ISA device, but is using the PCI bus.
4
field-programmable storage bit array.
5
5
6
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
6
The actual mmio interface to the array varies by device
7
Acked-by: Thomas Huth <thuth@redhat.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
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
18
---
12
tests/qtest/pvpanic-pci-test.c | 94 ++++++++++++++++++++++++++++++++++
19
include/hw/nvram/xlnx-efuse.h | 132 ++++++++++++++++
13
tests/qtest/meson.build | 1 +
20
hw/nvram/xlnx-efuse-crc.c | 119 +++++++++++++++
14
2 files changed, 95 insertions(+)
21
hw/nvram/xlnx-efuse.c | 280 ++++++++++++++++++++++++++++++++++
15
create mode 100644 tests/qtest/pvpanic-pci-test.c
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
16
28
17
diff --git a/tests/qtest/pvpanic-pci-test.c b/tests/qtest/pvpanic-pci-test.c
29
diff --git a/include/hw/nvram/xlnx-efuse.h b/include/hw/nvram/xlnx-efuse.h
18
new file mode 100644
30
new file mode 100644
19
index XXXXXXX..XXXXXXX
31
index XXXXXXX..XXXXXXX
20
--- /dev/null
32
--- /dev/null
21
+++ b/tests/qtest/pvpanic-pci-test.c
33
+++ b/include/hw/nvram/xlnx-efuse.h
22
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@
23
+/*
35
+/*
24
+ * QTest testcase for PV Panic PCI device
36
+ * QEMU model of the Xilinx eFuse core
25
+ *
37
+ *
26
+ * Copyright (C) 2020 Oracle
38
+ * Copyright (c) 2015 Xilinx Inc.
27
+ *
39
+ *
28
+ * Authors:
40
+ * Written by Edgar E. Iglesias <edgari@xilinx.com>
29
+ * Mihai Carabas <mihai.carabas@oracle.com>
41
+ *
30
+ *
42
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
31
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
43
+ * of this software and associated documentation files (the "Software"), to deal
32
+ * See the COPYING file in the top-level directory.
44
+ * in the Software without restriction, including without limitation the rights
33
+ *
45
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
34
+ */
46
+ * copies of the Software, and to permit persons to whom the Software is
35
+
47
+ * furnished to do so, subject to the following conditions:
48
+ *
49
+ * The above copyright notice and this permission notice shall be included in
50
+ * all copies or substantial portions of the Software.
51
+ *
52
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
53
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
54
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
55
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
56
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
58
+ * THE SOFTWARE.
59
+ */
60
+
61
+#ifndef XLNX_EFUSE_H
62
+#define XLNX_EFUSE_H
63
+
64
+#include "sysemu/block-backend.h"
65
+#include "hw/qdev-core.h"
66
+
67
+#define TYPE_XLNX_EFUSE "xlnx,efuse"
68
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxEFuse, XLNX_EFUSE);
69
+
70
+struct XlnxEFuse {
71
+ DeviceState parent_obj;
72
+ BlockBackend *blk;
73
+ bool blk_ro;
74
+ uint32_t *fuse32;
75
+
76
+ DeviceState *dev;
77
+
78
+ bool init_tbits;
79
+
80
+ uint8_t efuse_nr;
81
+ uint32_t efuse_size;
82
+
83
+ uint32_t *ro_bits;
84
+ uint32_t ro_bits_cnt;
85
+};
86
+
87
+/**
88
+ * xlnx_efuse_calc_crc:
89
+ * @data: an array of 32-bit words for which the CRC should be computed
90
+ * @u32_cnt: the array size in number of 32-bit words
91
+ * @zpads: the number of 32-bit zeros prepended to @data before computation
92
+ *
93
+ * This function is used to compute the CRC for an array of 32-bit words,
94
+ * using a Xilinx-specific data padding.
95
+ *
96
+ * Returns: the computed 32-bit CRC
97
+ */
98
+uint32_t xlnx_efuse_calc_crc(const uint32_t *data, unsigned u32_cnt,
99
+ unsigned zpads);
100
+
101
+/**
102
+ * xlnx_efuse_get_bit:
103
+ * @s: the efuse object
104
+ * @bit: the efuse bit-address to read the data
105
+ *
106
+ * Returns: the bit, 0 or 1, at @bit of object @s
107
+ */
108
+bool xlnx_efuse_get_bit(XlnxEFuse *s, unsigned int bit);
109
+
110
+/**
111
+ * xlnx_efuse_set_bit:
112
+ * @s: the efuse object
113
+ * @bit: the efuse bit-address to be written a value of 1
114
+ *
115
+ * Returns: true on success, false on failure
116
+ */
117
+bool xlnx_efuse_set_bit(XlnxEFuse *s, unsigned int bit);
118
+
119
+/**
120
+ * xlnx_efuse_k256_check:
121
+ * @s: the efuse object
122
+ * @crc: the 32-bit CRC to be compared with
123
+ * @start: the efuse bit-address (which must be multiple of 32) of the
124
+ * start of a 256-bit array
125
+ *
126
+ * This function computes the CRC of a 256-bit array starting at @start
127
+ * then compares to the given @crc
128
+ *
129
+ * Returns: true of @crc == computed, false otherwise
130
+ */
131
+bool xlnx_efuse_k256_check(XlnxEFuse *s, uint32_t crc, unsigned start);
132
+
133
+/**
134
+ * xlnx_efuse_tbits_check:
135
+ * @s: the efuse object
136
+ *
137
+ * This function inspects a number of efuse bits at specific addresses
138
+ * to see if they match a validation pattern. Each pattern is a group
139
+ * of 4 bits, and there are 3 groups.
140
+ *
141
+ * Returns: a 3-bit mask, where a bit of '1' means the corresponding
142
+ * group has a valid pattern.
143
+ */
144
+uint32_t xlnx_efuse_tbits_check(XlnxEFuse *s);
145
+
146
+/**
147
+ * xlnx_efuse_get_row:
148
+ * @s: the efuse object
149
+ * @bit: the efuse bit address for which a 32-bit value is read
150
+ *
151
+ * Returns: the entire 32 bits of the efuse, starting at a bit
152
+ * address that is multiple of 32 and contains the bit at @bit
153
+ */
154
+static inline uint32_t xlnx_efuse_get_row(XlnxEFuse *s, unsigned int bit)
155
+{
156
+ if (!(s->fuse32)) {
157
+ return 0;
158
+ } else {
159
+ unsigned int row_idx = bit / 32;
160
+
161
+ assert(row_idx < (s->efuse_size * s->efuse_nr / 32));
162
+ return s->fuse32[row_idx];
163
+ }
164
+}
165
+
166
+#endif
167
diff --git a/hw/nvram/xlnx-efuse-crc.c b/hw/nvram/xlnx-efuse-crc.c
168
new file mode 100644
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
+ */
36
+#include "qemu/osdep.h"
196
+#include "qemu/osdep.h"
37
+#include "libqos/libqtest.h"
197
+#include "hw/nvram/xlnx-efuse.h"
38
+#include "qapi/qmp/qdict.h"
198
+
39
+#include "libqos/pci.h"
199
+static uint32_t xlnx_efuse_u37_crc(uint32_t prev_crc, uint32_t data,
40
+#include "libqos/pci-pc.h"
200
+ uint32_t addr)
41
+#include "hw/pci/pci_regs.h"
201
+{
42
+
202
+ /* A table for 7-bit slicing */
43
+static void test_panic_nopause(void)
203
+ static const uint32_t crc_tab[128] = {
44
+{
204
+ 0x00000000, 0xe13b70f7, 0xc79a971f, 0x26a1e7e8,
45
+ uint8_t val;
205
+ 0x8ad958cf, 0x6be22838, 0x4d43cfd0, 0xac78bf27,
46
+ QDict *response, *data;
206
+ 0x105ec76f, 0xf165b798, 0xd7c45070, 0x36ff2087,
47
+ QTestState *qts;
207
+ 0x9a879fa0, 0x7bbcef57, 0x5d1d08bf, 0xbc267848,
48
+ QPCIBus *pcibus;
208
+ 0x20bd8ede, 0xc186fe29, 0xe72719c1, 0x061c6936,
49
+ QPCIDevice *dev;
209
+ 0xaa64d611, 0x4b5fa6e6, 0x6dfe410e, 0x8cc531f9,
50
+ QPCIBar bar;
210
+ 0x30e349b1, 0xd1d83946, 0xf779deae, 0x1642ae59,
51
+
211
+ 0xba3a117e, 0x5b016189, 0x7da08661, 0x9c9bf696,
52
+ qts = qtest_init("-device pvpanic-pci,addr=04.0 -action panic=none");
212
+ 0x417b1dbc, 0xa0406d4b, 0x86e18aa3, 0x67dafa54,
53
+ pcibus = qpci_new_pc(qts, NULL);
213
+ 0xcba24573, 0x2a993584, 0x0c38d26c, 0xed03a29b,
54
+ dev = qpci_device_find(pcibus, QPCI_DEVFN(0x4, 0x0));
214
+ 0x5125dad3, 0xb01eaa24, 0x96bf4dcc, 0x77843d3b,
55
+ qpci_device_enable(dev);
215
+ 0xdbfc821c, 0x3ac7f2eb, 0x1c661503, 0xfd5d65f4,
56
+ bar = qpci_iomap(dev, 0, NULL);
216
+ 0x61c69362, 0x80fde395, 0xa65c047d, 0x4767748a,
57
+
217
+ 0xeb1fcbad, 0x0a24bb5a, 0x2c855cb2, 0xcdbe2c45,
58
+ qpci_memread(dev, bar, 0, &val, sizeof(val));
218
+ 0x7198540d, 0x90a324fa, 0xb602c312, 0x5739b3e5,
59
+ g_assert_cmpuint(val, ==, 3);
219
+ 0xfb410cc2, 0x1a7a7c35, 0x3cdb9bdd, 0xdde0eb2a,
60
+
220
+ 0x82f63b78, 0x63cd4b8f, 0x456cac67, 0xa457dc90,
61
+ val = 1;
221
+ 0x082f63b7, 0xe9141340, 0xcfb5f4a8, 0x2e8e845f,
62
+ qpci_memwrite(dev, bar, 0, &val, sizeof(val));
222
+ 0x92a8fc17, 0x73938ce0, 0x55326b08, 0xb4091bff,
63
+
223
+ 0x1871a4d8, 0xf94ad42f, 0xdfeb33c7, 0x3ed04330,
64
+ response = qtest_qmp_eventwait_ref(qts, "GUEST_PANICKED");
224
+ 0xa24bb5a6, 0x4370c551, 0x65d122b9, 0x84ea524e,
65
+ g_assert(qdict_haskey(response, "data"));
225
+ 0x2892ed69, 0xc9a99d9e, 0xef087a76, 0x0e330a81,
66
+ data = qdict_get_qdict(response, "data");
226
+ 0xb21572c9, 0x532e023e, 0x758fe5d6, 0x94b49521,
67
+ g_assert(qdict_haskey(data, "action"));
227
+ 0x38cc2a06, 0xd9f75af1, 0xff56bd19, 0x1e6dcdee,
68
+ g_assert_cmpstr(qdict_get_str(data, "action"), ==, "run");
228
+ 0xc38d26c4, 0x22b65633, 0x0417b1db, 0xe52cc12c,
69
+ qobject_unref(response);
229
+ 0x49547e0b, 0xa86f0efc, 0x8ecee914, 0x6ff599e3,
70
+
230
+ 0xd3d3e1ab, 0x32e8915c, 0x144976b4, 0xf5720643,
71
+ qtest_quit(qts);
231
+ 0x590ab964, 0xb831c993, 0x9e902e7b, 0x7fab5e8c,
72
+}
232
+ 0xe330a81a, 0x020bd8ed, 0x24aa3f05, 0xc5914ff2,
73
+
233
+ 0x69e9f0d5, 0x88d28022, 0xae7367ca, 0x4f48173d,
74
+static void test_panic(void)
234
+ 0xf36e6f75, 0x12551f82, 0x34f4f86a, 0xd5cf889d,
75
+{
235
+ 0x79b737ba, 0x988c474d, 0xbe2da0a5, 0x5f16d052
76
+ uint8_t val;
236
+ };
77
+ QDict *response, *data;
237
+
78
+ QTestState *qts;
238
+ /*
79
+ QPCIBus *pcibus;
239
+ * eFuse calculation is shown here:
80
+ QPCIDevice *dev;
240
+ * https://github.com/Xilinx/embeddedsw/blob/release-2019.2/lib/sw_services/xilskey/src/xilskey_utils.c#L1496
81
+ QPCIBar bar;
241
+ *
82
+
242
+ * Each u32 word is appended a 5-bit value, for a total of 37 bits; see:
83
+ qts = qtest_init("-device pvpanic-pci,addr=04.0 -action panic=pause");
243
+ * https://github.com/Xilinx/embeddedsw/blob/release-2019.2/lib/sw_services/xilskey/src/xilskey_utils.c#L1356
84
+ pcibus = qpci_new_pc(qts, NULL);
244
+ */
85
+ dev = qpci_device_find(pcibus, QPCI_DEVFN(0x4, 0x0));
245
+ uint32_t crc = prev_crc;
86
+ qpci_device_enable(dev);
246
+ const unsigned rshf = 7;
87
+ bar = qpci_iomap(dev, 0, NULL);
247
+ const uint32_t im = (1 << rshf) - 1;
88
+
248
+ const uint32_t rm = (1 << (32 - rshf)) - 1;
89
+ qpci_memread(dev, bar, 0, &val, sizeof(val));
249
+ const uint32_t i2 = (1 << 2) - 1;
90
+ g_assert_cmpuint(val, ==, 3);
250
+ const uint32_t r2 = (1 << 30) - 1;
91
+
251
+
92
+ val = 1;
252
+ unsigned j;
93
+ qpci_memwrite(dev, bar, 0, &val, sizeof(val));
253
+ uint32_t i, r;
94
+
254
+ uint64_t w;
95
+ response = qtest_qmp_eventwait_ref(qts, "GUEST_PANICKED");
255
+
96
+ g_assert(qdict_haskey(response, "data"));
256
+ w = (uint64_t)(addr) << 32;
97
+ data = qdict_get_qdict(response, "data");
257
+ w |= data;
98
+ g_assert(qdict_haskey(data, "action"));
258
+
99
+ g_assert_cmpstr(qdict_get_str(data, "action"), ==, "pause");
259
+ /* Feed 35 bits, in 5 rounds, each a slice of 7 bits */
100
+ qobject_unref(response);
260
+ for (j = 0; j < 5; j++) {
101
+
261
+ r = rm & (crc >> rshf);
102
+ qtest_quit(qts);
262
+ i = im & (crc ^ w);
103
+}
263
+ crc = crc_tab[i] ^ r;
104
+
264
+
105
+int main(int argc, char **argv)
265
+ w >>= rshf;
106
+{
266
+ }
107
+ int ret;
267
+
108
+
268
+ /* Feed the remaining 2 bits */
109
+ g_test_init(&argc, &argv, NULL);
269
+ r = r2 & (crc >> 2);
110
+ qtest_add_func("/pvpanic-pci/panic", test_panic);
270
+ i = i2 & (crc ^ w);
111
+ qtest_add_func("/pvpanic-pci/panic-nopause", test_panic_nopause);
271
+ crc = crc_tab[i << (rshf - 2)] ^ r;
112
+
272
+
113
+ ret = g_test_run();
273
+ return crc;
114
+
274
+}
115
+ return ret;
275
+
116
+}
276
+uint32_t xlnx_efuse_calc_crc(const uint32_t *data, unsigned u32_cnt,
117
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
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
118
index XXXXXXX..XXXXXXX 100644
579
index XXXXXXX..XXXXXXX 100644
119
--- a/tests/qtest/meson.build
580
--- a/hw/nvram/Kconfig
120
+++ b/tests/qtest/meson.build
581
+++ b/hw/nvram/Kconfig
121
@@ -XXX,XX +XXX,XX @@ qtests_i386 = \
582
@@ -XXX,XX +XXX,XX @@ config NMC93XX_EEPROM
122
config_all_devices.has_key('CONFIG_ISA_IPMI_BT') ? ['ipmi-bt-test'] : []) + \
583
123
(config_all_devices.has_key('CONFIG_WDT_IB700') ? ['wdt_ib700-test'] : []) + \
584
config CHRP_NVRAM
124
(config_all_devices.has_key('CONFIG_PVPANIC_ISA') ? ['pvpanic-test'] : []) + \
585
bool
125
+ (config_all_devices.has_key('CONFIG_PVPANIC_PCI') ? ['pvpanic-pci-test'] : []) + \
586
+
126
(config_all_devices.has_key('CONFIG_HDA') ? ['intel-hda-test'] : []) + \
587
+config XLNX_EFUSE_CRC
127
(config_all_devices.has_key('CONFIG_I82801B11') ? ['i82801b11-test'] : []) + \
588
+ bool
128
(config_all_devices.has_key('CONFIG_IOH3420') ? ['ioh3420-test'] : []) + \
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'))
129
--
605
--
130
2.20.1
606
2.20.1
131
607
132
608
diff view generated by jsdifflib
1
From: Mihai Carabas <mihai.carabas@oracle.com>
1
From: Tong Ho <tong.ho@xilinx.com>
2
2
3
Add PCI interface support for PVPANIC device. Create a new file pvpanic-pci.c
3
This implements the Xilinx Versal eFuse, an one-time
4
where the PCI specific routines reside and update the build system with the new
4
field-programmable non-volatile storage device. There is
5
files and config structure.
5
only one such device in the Xilinx Versal product family.
6
6
7
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
7
This device has two separate mmio interfaces, a controller
8
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
8
and a flatten readback.
9
10
The controller provides interfaces for field-programming,
11
configuration, control, and status.
12
13
The flatten readback is a cache to provide a byte-accessible
14
read-only interface to efficiently read efuse array.
15
16
Co-authored-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
17
Co-authored-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
18
19
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
20
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
21
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
22
Message-id: 20210917052400.1249094-3-tong.ho@xilinx.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
25
---
13
docs/specs/pci-ids.txt | 1 +
26
include/hw/nvram/xlnx-versal-efuse.h | 68 +++
14
include/hw/misc/pvpanic.h | 1 +
27
hw/nvram/xlnx-versal-efuse-cache.c | 114 ++++
15
include/hw/pci/pci.h | 1 +
28
hw/nvram/xlnx-versal-efuse-ctrl.c | 783 +++++++++++++++++++++++++++
16
hw/misc/pvpanic-pci.c | 94 +++++++++++++++++++++++++++++++++++++++
29
hw/nvram/Kconfig | 4 +
17
hw/misc/Kconfig | 6 +++
30
hw/nvram/meson.build | 3 +
18
hw/misc/meson.build | 1 +
31
5 files changed, 972 insertions(+)
19
6 files changed, 104 insertions(+)
32
create mode 100644 include/hw/nvram/xlnx-versal-efuse.h
20
create mode 100644 hw/misc/pvpanic-pci.c
33
create mode 100644 hw/nvram/xlnx-versal-efuse-cache.c
34
create mode 100644 hw/nvram/xlnx-versal-efuse-ctrl.c
21
35
22
diff --git a/docs/specs/pci-ids.txt b/docs/specs/pci-ids.txt
36
diff --git a/include/hw/nvram/xlnx-versal-efuse.h b/include/hw/nvram/xlnx-versal-efuse.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/docs/specs/pci-ids.txt
25
+++ b/docs/specs/pci-ids.txt
26
@@ -XXX,XX +XXX,XX @@ PCI devices (other than virtio):
27
1b36:000d PCI xhci usb host adapter
28
1b36:000f mdpy (mdev sample device), linux/samples/vfio-mdev/mdpy.c
29
1b36:0010 PCIe NVMe device (-device nvme)
30
+1b36:0011 PCI PVPanic device (-device pvpanic-pci)
31
32
All these devices are documented in docs/specs.
33
34
diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/misc/pvpanic.h
37
+++ b/include/hw/misc/pvpanic.h
38
@@ -XXX,XX +XXX,XX @@
39
#include "qom/object.h"
40
41
#define TYPE_PVPANIC_ISA_DEVICE "pvpanic"
42
+#define TYPE_PVPANIC_PCI_DEVICE "pvpanic-pci"
43
44
#define PVPANIC_IOPORT_PROP "ioport"
45
46
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/include/hw/pci/pci.h
49
+++ b/include/hw/pci/pci.h
50
@@ -XXX,XX +XXX,XX @@ extern bool pci_available;
51
#define PCI_DEVICE_ID_REDHAT_PCIE_BRIDGE 0x000e
52
#define PCI_DEVICE_ID_REDHAT_MDPY 0x000f
53
#define PCI_DEVICE_ID_REDHAT_NVME 0x0010
54
+#define PCI_DEVICE_ID_REDHAT_PVPANIC 0x0011
55
#define PCI_DEVICE_ID_REDHAT_QXL 0x0100
56
57
#define FMT_PCIBUS PRIx64
58
diff --git a/hw/misc/pvpanic-pci.c b/hw/misc/pvpanic-pci.c
59
new file mode 100644
37
new file mode 100644
60
index XXXXXXX..XXXXXXX
38
index XXXXXXX..XXXXXXX
61
--- /dev/null
39
--- /dev/null
62
+++ b/hw/misc/pvpanic-pci.c
40
+++ b/include/hw/nvram/xlnx-versal-efuse.h
63
@@ -XXX,XX +XXX,XX @@
41
@@ -XXX,XX +XXX,XX @@
64
+/*
42
+/*
65
+ * QEMU simulated PCI pvpanic device.
43
+ * Copyright (c) 2020 Xilinx Inc.
66
+ *
44
+ *
67
+ * Copyright (C) 2020 Oracle
45
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
68
+ *
46
+ * of this software and associated documentation files (the "Software"), to deal
69
+ * Authors:
47
+ * in the Software without restriction, including without limitation the rights
70
+ * Mihai Carabas <mihai.carabas@oracle.com>
48
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
71
+ *
49
+ * copies of the Software, and to permit persons to whom the Software is
72
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
50
+ * furnished to do so, subject to the following conditions:
73
+ * See the COPYING file in the top-level directory.
51
+ *
74
+ *
52
+ * The above copyright notice and this permission notice shall be included in
53
+ * all copies or substantial portions of the Software.
54
+ *
55
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
56
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
57
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
58
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
59
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
60
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
61
+ * THE SOFTWARE.
75
+ */
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
+ */
76
+
139
+
77
+#include "qemu/osdep.h"
140
+#include "qemu/osdep.h"
141
+#include "hw/nvram/xlnx-versal-efuse.h"
142
+
78
+#include "qemu/log.h"
143
+#include "qemu/log.h"
79
+#include "qemu/module.h"
80
+#include "sysemu/runstate.h"
81
+
82
+#include "hw/nvram/fw_cfg.h"
83
+#include "hw/qdev-properties.h"
144
+#include "hw/qdev-properties.h"
145
+
146
+#define MR_SIZE 0xC00
147
+
148
+static uint64_t efuse_cache_read(void *opaque, hwaddr addr, unsigned size)
149
+{
150
+ XlnxVersalEFuseCache *s = XLNX_VERSAL_EFUSE_CACHE(opaque);
151
+ unsigned int w0 = QEMU_ALIGN_DOWN(addr * 8, 32);
152
+ unsigned int w1 = QEMU_ALIGN_DOWN((addr + size - 1) * 8, 32);
153
+
154
+ uint64_t ret;
155
+
156
+ assert(w0 == w1 || (w0 + 32) == w1);
157
+
158
+ ret = xlnx_versal_efuse_read_row(s->efuse, w1, NULL);
159
+ if (w0 < w1) {
160
+ ret <<= 32;
161
+ ret |= xlnx_versal_efuse_read_row(s->efuse, w0, NULL);
162
+ }
163
+
164
+ /* If 'addr' unaligned, the guest is always assumed to be little-endian. */
165
+ addr &= 3;
166
+ if (addr) {
167
+ ret >>= 8 * addr;
168
+ }
169
+
170
+ return ret;
171
+}
172
+
173
+static void efuse_cache_write(void *opaque, hwaddr addr, uint64_t value,
174
+ unsigned size)
175
+{
176
+ /* No Register Writes allowed */
177
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: efuse cache registers are read-only",
178
+ __func__);
179
+}
180
+
181
+static const MemoryRegionOps efuse_cache_ops = {
182
+ .read = efuse_cache_read,
183
+ .write = efuse_cache_write,
184
+ .endianness = DEVICE_LITTLE_ENDIAN,
185
+ .valid = {
186
+ .min_access_size = 1,
187
+ .max_access_size = 4,
188
+ },
189
+};
190
+
191
+static void efuse_cache_init(Object *obj)
192
+{
193
+ XlnxVersalEFuseCache *s = XLNX_VERSAL_EFUSE_CACHE(obj);
194
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
195
+
196
+ memory_region_init_io(&s->iomem, obj, &efuse_cache_ops, s,
197
+ TYPE_XLNX_VERSAL_EFUSE_CACHE, MR_SIZE);
198
+ sysbus_init_mmio(sbd, &s->iomem);
199
+}
200
+
201
+static Property efuse_cache_props[] = {
202
+ DEFINE_PROP_LINK("efuse",
203
+ XlnxVersalEFuseCache, efuse,
204
+ TYPE_XLNX_EFUSE, XlnxEFuse *),
205
+
206
+ DEFINE_PROP_END_OF_LIST(),
207
+};
208
+
209
+static void efuse_cache_class_init(ObjectClass *klass, void *data)
210
+{
211
+ DeviceClass *dc = DEVICE_CLASS(klass);
212
+
213
+ device_class_set_props(dc, efuse_cache_props);
214
+}
215
+
216
+static const TypeInfo efuse_cache_info = {
217
+ .name = TYPE_XLNX_VERSAL_EFUSE_CACHE,
218
+ .parent = TYPE_SYS_BUS_DEVICE,
219
+ .instance_size = sizeof(XlnxVersalEFuseCache),
220
+ .class_init = efuse_cache_class_init,
221
+ .instance_init = efuse_cache_init,
222
+};
223
+
224
+static void efuse_cache_register_types(void)
225
+{
226
+ type_register_static(&efuse_cache_info);
227
+}
228
+
229
+type_init(efuse_cache_register_types)
230
diff --git a/hw/nvram/xlnx-versal-efuse-ctrl.c b/hw/nvram/xlnx-versal-efuse-ctrl.c
231
new file mode 100644
232
index XXXXXXX..XXXXXXX
233
--- /dev/null
234
+++ b/hw/nvram/xlnx-versal-efuse-ctrl.c
235
@@ -XXX,XX +XXX,XX @@
236
+/*
237
+ * QEMU model of the Versal eFuse controller
238
+ *
239
+ * Copyright (c) 2020 Xilinx Inc.
240
+ *
241
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
242
+ * of this software and associated documentation files (the "Software"), to deal
243
+ * in the Software without restriction, including without limitation the rights
244
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
245
+ * copies of the Software, and to permit persons to whom the Software is
246
+ * furnished to do so, subject to the following conditions:
247
+ *
248
+ * The above copyright notice and this permission notice shall be included in
249
+ * all copies or substantial portions of the Software.
250
+ *
251
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
252
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
253
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
254
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
255
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
256
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
257
+ * THE SOFTWARE.
258
+ */
259
+
260
+#include "qemu/osdep.h"
261
+#include "hw/nvram/xlnx-versal-efuse.h"
262
+
263
+#include "qemu/log.h"
264
+#include "qapi/error.h"
84
+#include "migration/vmstate.h"
265
+#include "migration/vmstate.h"
85
+#include "hw/misc/pvpanic.h"
266
+#include "hw/qdev-properties.h"
86
+#include "qom/object.h"
267
+
87
+#include "hw/pci/pci.h"
268
+#ifndef XLNX_VERSAL_EFUSE_CTRL_ERR_DEBUG
88
+
269
+#define XLNX_VERSAL_EFUSE_CTRL_ERR_DEBUG 0
89
+OBJECT_DECLARE_SIMPLE_TYPE(PVPanicPCIState, PVPANIC_PCI_DEVICE)
270
+#endif
271
+
272
+REG32(WR_LOCK, 0x0)
273
+ FIELD(WR_LOCK, LOCK, 0, 16)
274
+REG32(CFG, 0x4)
275
+ FIELD(CFG, SLVERR_ENABLE, 5, 1)
276
+ FIELD(CFG, MARGIN_RD, 2, 1)
277
+ FIELD(CFG, PGM_EN, 1, 1)
278
+REG32(STATUS, 0x8)
279
+ FIELD(STATUS, AES_USER_KEY_1_CRC_PASS, 11, 1)
280
+ FIELD(STATUS, AES_USER_KEY_1_CRC_DONE, 10, 1)
281
+ FIELD(STATUS, AES_USER_KEY_0_CRC_PASS, 9, 1)
282
+ FIELD(STATUS, AES_USER_KEY_0_CRC_DONE, 8, 1)
283
+ FIELD(STATUS, AES_CRC_PASS, 7, 1)
284
+ FIELD(STATUS, AES_CRC_DONE, 6, 1)
285
+ FIELD(STATUS, CACHE_DONE, 5, 1)
286
+ FIELD(STATUS, CACHE_LOAD, 4, 1)
287
+ FIELD(STATUS, EFUSE_2_TBIT, 2, 1)
288
+ FIELD(STATUS, EFUSE_1_TBIT, 1, 1)
289
+ FIELD(STATUS, EFUSE_0_TBIT, 0, 1)
290
+REG32(EFUSE_PGM_ADDR, 0xc)
291
+ FIELD(EFUSE_PGM_ADDR, PAGE, 13, 4)
292
+ FIELD(EFUSE_PGM_ADDR, ROW, 5, 8)
293
+ FIELD(EFUSE_PGM_ADDR, COLUMN, 0, 5)
294
+REG32(EFUSE_RD_ADDR, 0x10)
295
+ FIELD(EFUSE_RD_ADDR, PAGE, 13, 4)
296
+ FIELD(EFUSE_RD_ADDR, ROW, 5, 8)
297
+REG32(EFUSE_RD_DATA, 0x14)
298
+REG32(TPGM, 0x18)
299
+ FIELD(TPGM, VALUE, 0, 16)
300
+REG32(TRD, 0x1c)
301
+ FIELD(TRD, VALUE, 0, 8)
302
+REG32(TSU_H_PS, 0x20)
303
+ FIELD(TSU_H_PS, VALUE, 0, 8)
304
+REG32(TSU_H_PS_CS, 0x24)
305
+ FIELD(TSU_H_PS_CS, VALUE, 0, 8)
306
+REG32(TRDM, 0x28)
307
+ FIELD(TRDM, VALUE, 0, 8)
308
+REG32(TSU_H_CS, 0x2c)
309
+ FIELD(TSU_H_CS, VALUE, 0, 8)
310
+REG32(EFUSE_ISR, 0x30)
311
+ FIELD(EFUSE_ISR, APB_SLVERR, 31, 1)
312
+ FIELD(EFUSE_ISR, CACHE_PARITY_E2, 14, 1)
313
+ FIELD(EFUSE_ISR, CACHE_PARITY_E1, 13, 1)
314
+ FIELD(EFUSE_ISR, CACHE_PARITY_E0S, 12, 1)
315
+ FIELD(EFUSE_ISR, CACHE_PARITY_E0R, 11, 1)
316
+ FIELD(EFUSE_ISR, CACHE_APB_SLVERR, 10, 1)
317
+ FIELD(EFUSE_ISR, CACHE_REQ_ERROR, 9, 1)
318
+ FIELD(EFUSE_ISR, MAIN_REQ_ERROR, 8, 1)
319
+ FIELD(EFUSE_ISR, READ_ON_CACHE_LD, 7, 1)
320
+ FIELD(EFUSE_ISR, CACHE_FSM_ERROR, 6, 1)
321
+ FIELD(EFUSE_ISR, MAIN_FSM_ERROR, 5, 1)
322
+ FIELD(EFUSE_ISR, CACHE_ERROR, 4, 1)
323
+ FIELD(EFUSE_ISR, RD_ERROR, 3, 1)
324
+ FIELD(EFUSE_ISR, RD_DONE, 2, 1)
325
+ FIELD(EFUSE_ISR, PGM_ERROR, 1, 1)
326
+ FIELD(EFUSE_ISR, PGM_DONE, 0, 1)
327
+REG32(EFUSE_IMR, 0x34)
328
+ FIELD(EFUSE_IMR, APB_SLVERR, 31, 1)
329
+ FIELD(EFUSE_IMR, CACHE_PARITY_E2, 14, 1)
330
+ FIELD(EFUSE_IMR, CACHE_PARITY_E1, 13, 1)
331
+ FIELD(EFUSE_IMR, CACHE_PARITY_E0S, 12, 1)
332
+ FIELD(EFUSE_IMR, CACHE_PARITY_E0R, 11, 1)
333
+ FIELD(EFUSE_IMR, CACHE_APB_SLVERR, 10, 1)
334
+ FIELD(EFUSE_IMR, CACHE_REQ_ERROR, 9, 1)
335
+ FIELD(EFUSE_IMR, MAIN_REQ_ERROR, 8, 1)
336
+ FIELD(EFUSE_IMR, READ_ON_CACHE_LD, 7, 1)
337
+ FIELD(EFUSE_IMR, CACHE_FSM_ERROR, 6, 1)
338
+ FIELD(EFUSE_IMR, MAIN_FSM_ERROR, 5, 1)
339
+ FIELD(EFUSE_IMR, CACHE_ERROR, 4, 1)
340
+ FIELD(EFUSE_IMR, RD_ERROR, 3, 1)
341
+ FIELD(EFUSE_IMR, RD_DONE, 2, 1)
342
+ FIELD(EFUSE_IMR, PGM_ERROR, 1, 1)
343
+ FIELD(EFUSE_IMR, PGM_DONE, 0, 1)
344
+REG32(EFUSE_IER, 0x38)
345
+ FIELD(EFUSE_IER, APB_SLVERR, 31, 1)
346
+ FIELD(EFUSE_IER, CACHE_PARITY_E2, 14, 1)
347
+ FIELD(EFUSE_IER, CACHE_PARITY_E1, 13, 1)
348
+ FIELD(EFUSE_IER, CACHE_PARITY_E0S, 12, 1)
349
+ FIELD(EFUSE_IER, CACHE_PARITY_E0R, 11, 1)
350
+ FIELD(EFUSE_IER, CACHE_APB_SLVERR, 10, 1)
351
+ FIELD(EFUSE_IER, CACHE_REQ_ERROR, 9, 1)
352
+ FIELD(EFUSE_IER, MAIN_REQ_ERROR, 8, 1)
353
+ FIELD(EFUSE_IER, READ_ON_CACHE_LD, 7, 1)
354
+ FIELD(EFUSE_IER, CACHE_FSM_ERROR, 6, 1)
355
+ FIELD(EFUSE_IER, MAIN_FSM_ERROR, 5, 1)
356
+ FIELD(EFUSE_IER, CACHE_ERROR, 4, 1)
357
+ FIELD(EFUSE_IER, RD_ERROR, 3, 1)
358
+ FIELD(EFUSE_IER, RD_DONE, 2, 1)
359
+ FIELD(EFUSE_IER, PGM_ERROR, 1, 1)
360
+ FIELD(EFUSE_IER, PGM_DONE, 0, 1)
361
+REG32(EFUSE_IDR, 0x3c)
362
+ FIELD(EFUSE_IDR, APB_SLVERR, 31, 1)
363
+ FIELD(EFUSE_IDR, CACHE_PARITY_E2, 14, 1)
364
+ FIELD(EFUSE_IDR, CACHE_PARITY_E1, 13, 1)
365
+ FIELD(EFUSE_IDR, CACHE_PARITY_E0S, 12, 1)
366
+ FIELD(EFUSE_IDR, CACHE_PARITY_E0R, 11, 1)
367
+ FIELD(EFUSE_IDR, CACHE_APB_SLVERR, 10, 1)
368
+ FIELD(EFUSE_IDR, CACHE_REQ_ERROR, 9, 1)
369
+ FIELD(EFUSE_IDR, MAIN_REQ_ERROR, 8, 1)
370
+ FIELD(EFUSE_IDR, READ_ON_CACHE_LD, 7, 1)
371
+ FIELD(EFUSE_IDR, CACHE_FSM_ERROR, 6, 1)
372
+ FIELD(EFUSE_IDR, MAIN_FSM_ERROR, 5, 1)
373
+ FIELD(EFUSE_IDR, CACHE_ERROR, 4, 1)
374
+ FIELD(EFUSE_IDR, RD_ERROR, 3, 1)
375
+ FIELD(EFUSE_IDR, RD_DONE, 2, 1)
376
+ FIELD(EFUSE_IDR, PGM_ERROR, 1, 1)
377
+ FIELD(EFUSE_IDR, PGM_DONE, 0, 1)
378
+REG32(EFUSE_CACHE_LOAD, 0x40)
379
+ FIELD(EFUSE_CACHE_LOAD, LOAD, 0, 1)
380
+REG32(EFUSE_PGM_LOCK, 0x44)
381
+ FIELD(EFUSE_PGM_LOCK, SPK_ID_LOCK, 0, 1)
382
+REG32(EFUSE_AES_CRC, 0x48)
383
+REG32(EFUSE_AES_USR_KEY0_CRC, 0x4c)
384
+REG32(EFUSE_AES_USR_KEY1_CRC, 0x50)
385
+REG32(EFUSE_PD, 0x54)
386
+REG32(EFUSE_ANLG_OSC_SW_1LP, 0x60)
387
+REG32(EFUSE_TEST_CTRL, 0x100)
388
+
389
+#define R_MAX (R_EFUSE_TEST_CTRL + 1)
390
+
391
+#define R_WR_LOCK_UNLOCK_PASSCODE (0xDF0D)
90
+
392
+
91
+/*
393
+/*
92
+ * PVPanicPCIState for PCI device
394
+ * eFuse layout references:
395
+ * https://github.com/Xilinx/embeddedsw/blob/release-2019.2/lib/sw_services/xilnvm/src/xnvm_efuse_hw.h
93
+ */
396
+ */
94
+typedef struct PVPanicPCIState {
397
+#define BIT_POS_OF(A_) \
95
+ PCIDevice dev;
398
+ ((uint32_t)((A_) & (R_EFUSE_PGM_ADDR_ROW_MASK | \
96
+ PVPanicState pvpanic;
399
+ R_EFUSE_PGM_ADDR_COLUMN_MASK)))
97
+} PVPanicPCIState;
400
+
98
+
401
+#define BIT_POS(R_, C_) \
99
+static const VMStateDescription vmstate_pvpanic_pci = {
402
+ ((uint32_t)((R_EFUSE_PGM_ADDR_ROW_MASK \
100
+ .name = "pvpanic-pci",
403
+ & ((R_) << R_EFUSE_PGM_ADDR_ROW_SHIFT)) \
404
+ | \
405
+ (R_EFUSE_PGM_ADDR_COLUMN_MASK \
406
+ & ((C_) << R_EFUSE_PGM_ADDR_COLUMN_SHIFT))))
407
+
408
+#define EFUSE_TBIT_POS(A_) (BIT_POS_OF(A_) >= BIT_POS(0, 28))
409
+
410
+#define EFUSE_ANCHOR_ROW (0)
411
+#define EFUSE_ANCHOR_3_COL (27)
412
+#define EFUSE_ANCHOR_1_COL (1)
413
+
414
+#define EFUSE_AES_KEY_START BIT_POS(12, 0)
415
+#define EFUSE_AES_KEY_END BIT_POS(19, 31)
416
+#define EFUSE_USER_KEY_0_START BIT_POS(20, 0)
417
+#define EFUSE_USER_KEY_0_END BIT_POS(27, 31)
418
+#define EFUSE_USER_KEY_1_START BIT_POS(28, 0)
419
+#define EFUSE_USER_KEY_1_END BIT_POS(35, 31)
420
+
421
+#define EFUSE_RD_BLOCKED_START EFUSE_AES_KEY_START
422
+#define EFUSE_RD_BLOCKED_END EFUSE_USER_KEY_1_END
423
+
424
+#define EFUSE_GLITCH_DET_WR_LK BIT_POS(4, 31)
425
+#define EFUSE_PPK0_WR_LK BIT_POS(43, 6)
426
+#define EFUSE_PPK1_WR_LK BIT_POS(43, 7)
427
+#define EFUSE_PPK2_WR_LK BIT_POS(43, 8)
428
+#define EFUSE_AES_WR_LK BIT_POS(43, 11)
429
+#define EFUSE_USER_KEY_0_WR_LK BIT_POS(43, 13)
430
+#define EFUSE_USER_KEY_1_WR_LK BIT_POS(43, 15)
431
+#define EFUSE_PUF_SYN_LK BIT_POS(43, 16)
432
+#define EFUSE_DNA_WR_LK BIT_POS(43, 27)
433
+#define EFUSE_BOOT_ENV_WR_LK BIT_POS(43, 28)
434
+
435
+#define EFUSE_PGM_LOCKED_START BIT_POS(44, 0)
436
+#define EFUSE_PGM_LOCKED_END BIT_POS(51, 31)
437
+
438
+#define EFUSE_PUF_PAGE (2)
439
+#define EFUSE_PUF_SYN_START BIT_POS(129, 0)
440
+#define EFUSE_PUF_SYN_END BIT_POS(255, 27)
441
+
442
+#define EFUSE_KEY_CRC_LK_ROW (43)
443
+#define EFUSE_AES_KEY_CRC_LK_MASK ((1U << 9) | (1U << 10))
444
+#define EFUSE_USER_KEY_0_CRC_LK_MASK (1U << 12)
445
+#define EFUSE_USER_KEY_1_CRC_LK_MASK (1U << 14)
446
+
447
+/*
448
+ * A handy macro to return value of an array element,
449
+ * or a specific default if given index is out of bound.
450
+ */
451
+#define ARRAY_GET(A_, I_, D_) \
452
+ ((unsigned int)(I_) < ARRAY_SIZE(A_) ? (A_)[I_] : (D_))
453
+
454
+QEMU_BUILD_BUG_ON(R_MAX != ARRAY_SIZE(((XlnxVersalEFuseCtrl *)0)->regs));
455
+
456
+typedef struct XlnxEFuseLkSpec {
457
+ uint16_t row;
458
+ uint16_t lk_bit;
459
+} XlnxEFuseLkSpec;
460
+
461
+static void efuse_imr_update_irq(XlnxVersalEFuseCtrl *s)
462
+{
463
+ bool pending = s->regs[R_EFUSE_ISR] & ~s->regs[R_EFUSE_IMR];
464
+ qemu_set_irq(s->irq_efuse_imr, pending);
465
+}
466
+
467
+static void efuse_isr_postw(RegisterInfo *reg, uint64_t val64)
468
+{
469
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
470
+ efuse_imr_update_irq(s);
471
+}
472
+
473
+static uint64_t efuse_ier_prew(RegisterInfo *reg, uint64_t val64)
474
+{
475
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
476
+ uint32_t val = val64;
477
+
478
+ s->regs[R_EFUSE_IMR] &= ~val;
479
+ efuse_imr_update_irq(s);
480
+ return 0;
481
+}
482
+
483
+static uint64_t efuse_idr_prew(RegisterInfo *reg, uint64_t val64)
484
+{
485
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
486
+ uint32_t val = val64;
487
+
488
+ s->regs[R_EFUSE_IMR] |= val;
489
+ efuse_imr_update_irq(s);
490
+ return 0;
491
+}
492
+
493
+static void efuse_status_tbits_sync(XlnxVersalEFuseCtrl *s)
494
+{
495
+ uint32_t check = xlnx_efuse_tbits_check(s->efuse);
496
+ uint32_t val = s->regs[R_STATUS];
497
+
498
+ val = FIELD_DP32(val, STATUS, EFUSE_0_TBIT, !!(check & (1 << 0)));
499
+ val = FIELD_DP32(val, STATUS, EFUSE_1_TBIT, !!(check & (1 << 1)));
500
+ val = FIELD_DP32(val, STATUS, EFUSE_2_TBIT, !!(check & (1 << 2)));
501
+
502
+ s->regs[R_STATUS] = val;
503
+}
504
+
505
+static void efuse_anchor_bits_check(XlnxVersalEFuseCtrl *s)
506
+{
507
+ unsigned page;
508
+
509
+ if (!s->efuse || !s->efuse->init_tbits) {
510
+ return;
511
+ }
512
+
513
+ for (page = 0; page < s->efuse->efuse_nr; page++) {
514
+ uint32_t row = 0, bit;
515
+
516
+ row = FIELD_DP32(row, EFUSE_PGM_ADDR, PAGE, page);
517
+ row = FIELD_DP32(row, EFUSE_PGM_ADDR, ROW, EFUSE_ANCHOR_ROW);
518
+
519
+ bit = FIELD_DP32(row, EFUSE_PGM_ADDR, COLUMN, EFUSE_ANCHOR_3_COL);
520
+ if (!xlnx_efuse_get_bit(s->efuse, bit)) {
521
+ xlnx_efuse_set_bit(s->efuse, bit);
522
+ }
523
+
524
+ bit = FIELD_DP32(row, EFUSE_PGM_ADDR, COLUMN, EFUSE_ANCHOR_1_COL);
525
+ if (!xlnx_efuse_get_bit(s->efuse, bit)) {
526
+ xlnx_efuse_set_bit(s->efuse, bit);
527
+ }
528
+ }
529
+}
530
+
531
+static void efuse_key_crc_check(RegisterInfo *reg, uint32_t crc,
532
+ uint32_t pass_mask, uint32_t done_mask,
533
+ unsigned first, uint32_t lk_mask)
534
+{
535
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
536
+ uint32_t r, lk_bits;
537
+
538
+ /*
539
+ * To start, assume both DONE and PASS, and clear PASS by xor
540
+ * if CRC-check fails or CRC-check disabled by lock fuse.
541
+ */
542
+ r = s->regs[R_STATUS] | done_mask | pass_mask;
543
+
544
+ lk_bits = xlnx_efuse_get_row(s->efuse, EFUSE_KEY_CRC_LK_ROW) & lk_mask;
545
+ if (lk_bits == 0 && xlnx_efuse_k256_check(s->efuse, crc, first)) {
546
+ pass_mask = 0;
547
+ }
548
+
549
+ s->regs[R_STATUS] = r ^ pass_mask;
550
+}
551
+
552
+static void efuse_data_sync(XlnxVersalEFuseCtrl *s)
553
+{
554
+ efuse_status_tbits_sync(s);
555
+}
556
+
557
+static int efuse_lk_spec_cmp(const void *a, const void *b)
558
+{
559
+ uint16_t r1 = ((const XlnxEFuseLkSpec *)a)->row;
560
+ uint16_t r2 = ((const XlnxEFuseLkSpec *)b)->row;
561
+
562
+ return (r1 > r2) - (r1 < r2);
563
+}
564
+
565
+static void efuse_lk_spec_sort(XlnxVersalEFuseCtrl *s)
566
+{
567
+ XlnxEFuseLkSpec *ary = s->extra_pg0_lock_spec;
568
+ const uint32_t n8 = s->extra_pg0_lock_n16 * 2;
569
+ const uint32_t sz = sizeof(ary[0]);
570
+ const uint32_t cnt = n8 / sz;
571
+
572
+ if (ary && cnt) {
573
+ qsort(ary, cnt, sz, efuse_lk_spec_cmp);
574
+ }
575
+}
576
+
577
+static uint32_t efuse_lk_spec_find(XlnxVersalEFuseCtrl *s, uint32_t row)
578
+{
579
+ const XlnxEFuseLkSpec *ary = s->extra_pg0_lock_spec;
580
+ const uint32_t n8 = s->extra_pg0_lock_n16 * 2;
581
+ const uint32_t sz = sizeof(ary[0]);
582
+ const uint32_t cnt = n8 / sz;
583
+ const XlnxEFuseLkSpec *item = NULL;
584
+
585
+ if (ary && cnt) {
586
+ XlnxEFuseLkSpec k = { .row = row, };
587
+
588
+ item = bsearch(&k, ary, cnt, sz, efuse_lk_spec_cmp);
589
+ }
590
+
591
+ return item ? item->lk_bit : 0;
592
+}
593
+
594
+static uint32_t efuse_bit_locked(XlnxVersalEFuseCtrl *s, uint32_t bit)
595
+{
596
+ /* Hard-coded locks */
597
+ static const uint16_t pg0_hard_lock[] = {
598
+ [4] = EFUSE_GLITCH_DET_WR_LK,
599
+ [37] = EFUSE_BOOT_ENV_WR_LK,
600
+
601
+ [8 ... 11] = EFUSE_DNA_WR_LK,
602
+ [12 ... 19] = EFUSE_AES_WR_LK,
603
+ [20 ... 27] = EFUSE_USER_KEY_0_WR_LK,
604
+ [28 ... 35] = EFUSE_USER_KEY_1_WR_LK,
605
+ [64 ... 71] = EFUSE_PPK0_WR_LK,
606
+ [72 ... 79] = EFUSE_PPK1_WR_LK,
607
+ [80 ... 87] = EFUSE_PPK2_WR_LK,
608
+ };
609
+
610
+ uint32_t row = FIELD_EX32(bit, EFUSE_PGM_ADDR, ROW);
611
+ uint32_t lk_bit = ARRAY_GET(pg0_hard_lock, row, 0);
612
+
613
+ return lk_bit ? lk_bit : efuse_lk_spec_find(s, row);
614
+}
615
+
616
+static bool efuse_pgm_locked(XlnxVersalEFuseCtrl *s, unsigned int bit)
617
+{
618
+
619
+ unsigned int lock = 1;
620
+
621
+ /* Global lock */
622
+ if (!ARRAY_FIELD_EX32(s->regs, CFG, PGM_EN)) {
623
+ goto ret_lock;
624
+ }
625
+
626
+ /* Row lock */
627
+ switch (FIELD_EX32(bit, EFUSE_PGM_ADDR, PAGE)) {
628
+ case 0:
629
+ if (ARRAY_FIELD_EX32(s->regs, EFUSE_PGM_LOCK, SPK_ID_LOCK) &&
630
+ bit >= EFUSE_PGM_LOCKED_START && bit <= EFUSE_PGM_LOCKED_END) {
631
+ goto ret_lock;
632
+ }
633
+
634
+ lock = efuse_bit_locked(s, bit);
635
+ break;
636
+ case EFUSE_PUF_PAGE:
637
+ if (bit < EFUSE_PUF_SYN_START || bit > EFUSE_PUF_SYN_END) {
638
+ lock = 0;
639
+ goto ret_lock;
640
+ }
641
+
642
+ lock = EFUSE_PUF_SYN_LK;
643
+ break;
644
+ default:
645
+ lock = 0;
646
+ goto ret_lock;
647
+ }
648
+
649
+ /* Row lock by an efuse bit */
650
+ if (lock) {
651
+ lock = xlnx_efuse_get_bit(s->efuse, lock);
652
+ }
653
+
654
+ ret_lock:
655
+ return lock != 0;
656
+}
657
+
658
+static void efuse_pgm_addr_postw(RegisterInfo *reg, uint64_t val64)
659
+{
660
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
661
+ unsigned bit = val64;
662
+ bool ok = false;
663
+
664
+ /* Always zero out PGM_ADDR because it is write-only */
665
+ s->regs[R_EFUSE_PGM_ADDR] = 0;
666
+
667
+ /*
668
+ * Indicate error if bit is write-protected (or read-only
669
+ * as guarded by efuse_set_bit()).
670
+ *
671
+ * Keep it simple by not modeling program timing.
672
+ *
673
+ * Note: model must NEVER clear the PGM_ERROR bit; it is
674
+ * up to guest to do so (or by reset).
675
+ */
676
+ if (efuse_pgm_locked(s, bit)) {
677
+ qemu_log_mask(LOG_GUEST_ERROR,
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);
687
+ }
688
+ }
689
+
690
+ if (!ok) {
691
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_ERROR, 1);
692
+ }
693
+
694
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_DONE, 1);
695
+ efuse_imr_update_irq(s);
696
+}
697
+
698
+static void efuse_rd_addr_postw(RegisterInfo *reg, uint64_t val64)
699
+{
700
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
701
+ unsigned bit = val64;
702
+ bool denied;
703
+
704
+ /* Always zero out RD_ADDR because it is write-only */
705
+ s->regs[R_EFUSE_RD_ADDR] = 0;
706
+
707
+ /*
708
+ * Indicate error if row is read-blocked.
709
+ *
710
+ * Note: model must NEVER clear the RD_ERROR bit; it is
711
+ * up to guest to do so (or by reset).
712
+ */
713
+ s->regs[R_EFUSE_RD_DATA] = xlnx_versal_efuse_read_row(s->efuse,
714
+ bit, &denied);
715
+ if (denied) {
716
+ qemu_log_mask(LOG_GUEST_ERROR,
717
+ "%s: Denied reading of efuse<%u, %u>\n",
718
+ object_get_canonical_path(OBJECT(s)),
719
+ FIELD_EX32(bit, EFUSE_RD_ADDR, PAGE),
720
+ FIELD_EX32(bit, EFUSE_RD_ADDR, ROW));
721
+
722
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_ERROR, 1);
723
+ }
724
+
725
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_DONE, 1);
726
+ efuse_imr_update_irq(s);
727
+ return;
728
+}
729
+
730
+static uint64_t efuse_cache_load_prew(RegisterInfo *reg, uint64_t val64)
731
+{
732
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
733
+
734
+ if (val64 & R_EFUSE_CACHE_LOAD_LOAD_MASK) {
735
+ efuse_data_sync(s);
736
+
737
+ ARRAY_FIELD_DP32(s->regs, STATUS, CACHE_DONE, 1);
738
+ efuse_imr_update_irq(s);
739
+ }
740
+
741
+ return 0;
742
+}
743
+
744
+static uint64_t efuse_pgm_lock_prew(RegisterInfo *reg, uint64_t val64)
745
+{
746
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(reg->opaque);
747
+
748
+ /* Ignore all other bits */
749
+ val64 = FIELD_EX32(val64, EFUSE_PGM_LOCK, SPK_ID_LOCK);
750
+
751
+ /* Once the bit is written 1, only reset will clear it to 0 */
752
+ val64 |= ARRAY_FIELD_EX32(s->regs, EFUSE_PGM_LOCK, SPK_ID_LOCK);
753
+
754
+ return val64;
755
+}
756
+
757
+static void efuse_aes_crc_postw(RegisterInfo *reg, uint64_t val64)
758
+{
759
+ efuse_key_crc_check(reg, val64,
760
+ R_STATUS_AES_CRC_PASS_MASK,
761
+ R_STATUS_AES_CRC_DONE_MASK,
762
+ EFUSE_AES_KEY_START,
763
+ EFUSE_AES_KEY_CRC_LK_MASK);
764
+}
765
+
766
+static void efuse_aes_u0_crc_postw(RegisterInfo *reg, uint64_t val64)
767
+{
768
+ efuse_key_crc_check(reg, val64,
769
+ R_STATUS_AES_USER_KEY_0_CRC_PASS_MASK,
770
+ R_STATUS_AES_USER_KEY_0_CRC_DONE_MASK,
771
+ EFUSE_USER_KEY_0_START,
772
+ EFUSE_USER_KEY_0_CRC_LK_MASK);
773
+}
774
+
775
+static void efuse_aes_u1_crc_postw(RegisterInfo *reg, uint64_t val64)
776
+{
777
+ efuse_key_crc_check(reg, val64,
778
+ R_STATUS_AES_USER_KEY_1_CRC_PASS_MASK,
779
+ R_STATUS_AES_USER_KEY_1_CRC_DONE_MASK,
780
+ EFUSE_USER_KEY_1_START,
781
+ EFUSE_USER_KEY_1_CRC_LK_MASK);
782
+}
783
+
784
+static uint64_t efuse_wr_lock_prew(RegisterInfo *reg, uint64_t val)
785
+{
786
+ return val != R_WR_LOCK_UNLOCK_PASSCODE;
787
+}
788
+
789
+static const RegisterAccessInfo efuse_ctrl_regs_info[] = {
790
+ { .name = "WR_LOCK", .addr = A_WR_LOCK,
791
+ .reset = 0x1,
792
+ .pre_write = efuse_wr_lock_prew,
793
+ },{ .name = "CFG", .addr = A_CFG,
794
+ .rsvd = 0x9,
795
+ },{ .name = "STATUS", .addr = A_STATUS,
796
+ .rsvd = 0x8,
797
+ .ro = 0xfff,
798
+ },{ .name = "EFUSE_PGM_ADDR", .addr = A_EFUSE_PGM_ADDR,
799
+ .post_write = efuse_pgm_addr_postw,
800
+ },{ .name = "EFUSE_RD_ADDR", .addr = A_EFUSE_RD_ADDR,
801
+ .rsvd = 0x1f,
802
+ .post_write = efuse_rd_addr_postw,
803
+ },{ .name = "EFUSE_RD_DATA", .addr = A_EFUSE_RD_DATA,
804
+ .ro = 0xffffffff,
805
+ },{ .name = "TPGM", .addr = A_TPGM,
806
+ },{ .name = "TRD", .addr = A_TRD,
807
+ .reset = 0x19,
808
+ },{ .name = "TSU_H_PS", .addr = A_TSU_H_PS,
809
+ .reset = 0xff,
810
+ },{ .name = "TSU_H_PS_CS", .addr = A_TSU_H_PS_CS,
811
+ .reset = 0x11,
812
+ },{ .name = "TRDM", .addr = A_TRDM,
813
+ .reset = 0x3a,
814
+ },{ .name = "TSU_H_CS", .addr = A_TSU_H_CS,
815
+ .reset = 0x16,
816
+ },{ .name = "EFUSE_ISR", .addr = A_EFUSE_ISR,
817
+ .rsvd = 0x7fff8000,
818
+ .w1c = 0x80007fff,
819
+ .post_write = efuse_isr_postw,
820
+ },{ .name = "EFUSE_IMR", .addr = A_EFUSE_IMR,
821
+ .reset = 0x80007fff,
822
+ .rsvd = 0x7fff8000,
823
+ .ro = 0xffffffff,
824
+ },{ .name = "EFUSE_IER", .addr = A_EFUSE_IER,
825
+ .rsvd = 0x7fff8000,
826
+ .pre_write = efuse_ier_prew,
827
+ },{ .name = "EFUSE_IDR", .addr = A_EFUSE_IDR,
828
+ .rsvd = 0x7fff8000,
829
+ .pre_write = efuse_idr_prew,
830
+ },{ .name = "EFUSE_CACHE_LOAD", .addr = A_EFUSE_CACHE_LOAD,
831
+ .pre_write = efuse_cache_load_prew,
832
+ },{ .name = "EFUSE_PGM_LOCK", .addr = A_EFUSE_PGM_LOCK,
833
+ .pre_write = efuse_pgm_lock_prew,
834
+ },{ .name = "EFUSE_AES_CRC", .addr = A_EFUSE_AES_CRC,
835
+ .post_write = efuse_aes_crc_postw,
836
+ },{ .name = "EFUSE_AES_USR_KEY0_CRC", .addr = A_EFUSE_AES_USR_KEY0_CRC,
837
+ .post_write = efuse_aes_u0_crc_postw,
838
+ },{ .name = "EFUSE_AES_USR_KEY1_CRC", .addr = A_EFUSE_AES_USR_KEY1_CRC,
839
+ .post_write = efuse_aes_u1_crc_postw,
840
+ },{ .name = "EFUSE_PD", .addr = A_EFUSE_PD,
841
+ .ro = 0xfffffffe,
842
+ },{ .name = "EFUSE_ANLG_OSC_SW_1LP", .addr = A_EFUSE_ANLG_OSC_SW_1LP,
843
+ },{ .name = "EFUSE_TEST_CTRL", .addr = A_EFUSE_TEST_CTRL,
844
+ .reset = 0x8,
845
+ }
846
+};
847
+
848
+static void efuse_ctrl_reg_write(void *opaque, hwaddr addr,
849
+ uint64_t data, unsigned size)
850
+{
851
+ RegisterInfoArray *reg_array = opaque;
852
+ XlnxVersalEFuseCtrl *s;
853
+ Object *dev;
854
+
855
+ assert(reg_array != NULL);
856
+
857
+ dev = reg_array->mem.owner;
858
+ assert(dev);
859
+
860
+ s = XLNX_VERSAL_EFUSE_CTRL(dev);
861
+
862
+ if (addr != A_WR_LOCK && s->regs[R_WR_LOCK]) {
863
+ qemu_log_mask(LOG_GUEST_ERROR,
864
+ "%s[reg_0x%02lx]: Attempt to write locked register.\n",
865
+ object_get_canonical_path(OBJECT(s)), (long)addr);
866
+ } else {
867
+ register_write_memory(opaque, addr, data, size);
868
+ }
869
+}
870
+
871
+static void efuse_ctrl_register_reset(RegisterInfo *reg)
872
+{
873
+ if (!reg->data || !reg->access) {
874
+ return;
875
+ }
876
+
877
+ /* Reset must not trigger some registers' writers */
878
+ switch (reg->access->addr) {
879
+ case A_EFUSE_AES_CRC:
880
+ case A_EFUSE_AES_USR_KEY0_CRC:
881
+ case A_EFUSE_AES_USR_KEY1_CRC:
882
+ *(uint32_t *)reg->data = reg->access->reset;
883
+ return;
884
+ }
885
+
886
+ register_reset(reg);
887
+}
888
+
889
+static void efuse_ctrl_reset(DeviceState *dev)
890
+{
891
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(dev);
892
+ unsigned int i;
893
+
894
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
895
+ efuse_ctrl_register_reset(&s->regs_info[i]);
896
+ }
897
+
898
+ efuse_anchor_bits_check(s);
899
+ efuse_data_sync(s);
900
+ efuse_imr_update_irq(s);
901
+}
902
+
903
+static const MemoryRegionOps efuse_ctrl_ops = {
904
+ .read = register_read_memory,
905
+ .write = efuse_ctrl_reg_write,
906
+ .endianness = DEVICE_LITTLE_ENDIAN,
907
+ .valid = {
908
+ .min_access_size = 4,
909
+ .max_access_size = 4,
910
+ },
911
+};
912
+
913
+static void efuse_ctrl_realize(DeviceState *dev, Error **errp)
914
+{
915
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(dev);
916
+ const uint32_t lks_sz = sizeof(XlnxEFuseLkSpec) / 2;
917
+
918
+ if (!s->efuse) {
919
+ error_setg(errp, "%s.efuse: link property not connected to XLNX-EFUSE",
920
+ object_get_canonical_path(OBJECT(dev)));
921
+ return;
922
+ }
923
+
924
+ /* Sort property-defined pgm-locks for bsearch lookup */
925
+ if ((s->extra_pg0_lock_n16 % lks_sz) != 0) {
926
+ error_setg(errp,
927
+ "%s.pg0-lock: array property item-count not multiple of %u",
928
+ object_get_canonical_path(OBJECT(dev)), lks_sz);
929
+ return;
930
+ }
931
+
932
+ efuse_lk_spec_sort(s);
933
+}
934
+
935
+static void efuse_ctrl_init(Object *obj)
936
+{
937
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(obj);
938
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
939
+ RegisterInfoArray *reg_array;
940
+
941
+ reg_array =
942
+ register_init_block32(DEVICE(obj), efuse_ctrl_regs_info,
943
+ ARRAY_SIZE(efuse_ctrl_regs_info),
944
+ s->regs_info, s->regs,
945
+ &efuse_ctrl_ops,
946
+ XLNX_VERSAL_EFUSE_CTRL_ERR_DEBUG,
947
+ R_MAX * 4);
948
+
949
+ sysbus_init_mmio(sbd, &reg_array->mem);
950
+ sysbus_init_irq(sbd, &s->irq_efuse_imr);
951
+}
952
+
953
+static const VMStateDescription vmstate_efuse_ctrl = {
954
+ .name = TYPE_XLNX_VERSAL_EFUSE_CTRL,
101
+ .version_id = 1,
955
+ .version_id = 1,
102
+ .minimum_version_id = 1,
956
+ .minimum_version_id = 1,
103
+ .fields = (VMStateField[]) {
957
+ .fields = (VMStateField[]) {
104
+ VMSTATE_PCI_DEVICE(dev, PVPanicPCIState),
958
+ VMSTATE_UINT32_ARRAY(regs, XlnxVersalEFuseCtrl, R_MAX),
105
+ VMSTATE_END_OF_LIST()
959
+ VMSTATE_END_OF_LIST(),
106
+ }
960
+ }
107
+};
961
+};
108
+
962
+
109
+static void pvpanic_pci_realizefn(PCIDevice *dev, Error **errp)
963
+static Property efuse_ctrl_props[] = {
110
+{
964
+ DEFINE_PROP_LINK("efuse",
111
+ PVPanicPCIState *s = PVPANIC_PCI_DEVICE(dev);
965
+ XlnxVersalEFuseCtrl, efuse,
112
+ PVPanicState *ps = &s->pvpanic;
966
+ TYPE_XLNX_EFUSE, XlnxEFuse *),
113
+
967
+ DEFINE_PROP_ARRAY("pg0-lock",
114
+ pvpanic_setup_io(&s->pvpanic, DEVICE(s), 2);
968
+ XlnxVersalEFuseCtrl, extra_pg0_lock_n16,
115
+
969
+ extra_pg0_lock_spec, qdev_prop_uint16, uint16_t),
116
+ pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &ps->mr);
970
+
117
+}
118
+
119
+static Property pvpanic_pci_properties[] = {
120
+ DEFINE_PROP_UINT8("events", PVPanicPCIState, pvpanic.events, PVPANIC_PANICKED | PVPANIC_CRASHLOADED),
121
+ DEFINE_PROP_END_OF_LIST(),
971
+ DEFINE_PROP_END_OF_LIST(),
122
+};
972
+};
123
+
973
+
124
+static void pvpanic_pci_class_init(ObjectClass *klass, void *data)
974
+static void efuse_ctrl_class_init(ObjectClass *klass, void *data)
125
+{
975
+{
126
+ DeviceClass *dc = DEVICE_CLASS(klass);
976
+ DeviceClass *dc = DEVICE_CLASS(klass);
127
+ PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
977
+
128
+
978
+ dc->reset = efuse_ctrl_reset;
129
+ device_class_set_props(dc, pvpanic_pci_properties);
979
+ dc->realize = efuse_ctrl_realize;
130
+
980
+ dc->vmsd = &vmstate_efuse_ctrl;
131
+ pc->realize = pvpanic_pci_realizefn;
981
+ device_class_set_props(dc, efuse_ctrl_props);
132
+ pc->vendor_id = PCI_VENDOR_ID_REDHAT;
982
+}
133
+ pc->device_id = PCI_DEVICE_ID_REDHAT_PVPANIC;
983
+
134
+ pc->revision = 1;
984
+static const TypeInfo efuse_ctrl_info = {
135
+ pc->class_id = PCI_CLASS_SYSTEM_OTHER;
985
+ .name = TYPE_XLNX_VERSAL_EFUSE_CTRL,
136
+ dc->vmsd = &vmstate_pvpanic_pci;
986
+ .parent = TYPE_SYS_BUS_DEVICE,
137
+
987
+ .instance_size = sizeof(XlnxVersalEFuseCtrl),
138
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
988
+ .class_init = efuse_ctrl_class_init,
139
+}
989
+ .instance_init = efuse_ctrl_init,
140
+
141
+static TypeInfo pvpanic_pci_info = {
142
+ .name = TYPE_PVPANIC_PCI_DEVICE,
143
+ .parent = TYPE_PCI_DEVICE,
144
+ .instance_size = sizeof(PVPanicPCIState),
145
+ .class_init = pvpanic_pci_class_init,
146
+ .interfaces = (InterfaceInfo[]) {
147
+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
148
+ { }
149
+ }
150
+};
990
+};
151
+
991
+
152
+static void pvpanic_register_types(void)
992
+static void efuse_ctrl_register_types(void)
153
+{
993
+{
154
+ type_register_static(&pvpanic_pci_info);
994
+ type_register_static(&efuse_ctrl_info);
155
+}
995
+}
156
+
996
+
157
+type_init(pvpanic_register_types);
997
+type_init(efuse_ctrl_register_types)
158
diff --git a/hw/misc/Kconfig b/hw/misc/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
159
index XXXXXXX..XXXXXXX 100644
1020
index XXXXXXX..XXXXXXX 100644
160
--- a/hw/misc/Kconfig
1021
--- a/hw/nvram/Kconfig
161
+++ b/hw/misc/Kconfig
1022
+++ b/hw/nvram/Kconfig
162
@@ -XXX,XX +XXX,XX @@ config IOTKIT_SYSINFO
1023
@@ -XXX,XX +XXX,XX @@ config XLNX_EFUSE_CRC
163
config PVPANIC_COMMON
1024
config XLNX_EFUSE
164
bool
1025
bool
165
1026
select XLNX_EFUSE_CRC
166
+config PVPANIC_PCI
1027
+
1028
+config XLNX_EFUSE_VERSAL
167
+ bool
1029
+ bool
168
+ default y if PCI_DEVICES
1030
+ select XLNX_EFUSE
169
+ depends on PCI
1031
diff --git a/hw/nvram/meson.build b/hw/nvram/meson.build
170
+ select PVPANIC_COMMON
171
+
172
config PVPANIC_ISA
173
bool
174
depends on ISA_BUS
175
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
176
index XXXXXXX..XXXXXXX 100644
1032
index XXXXXXX..XXXXXXX 100644
177
--- a/hw/misc/meson.build
1033
--- a/hw/nvram/meson.build
178
+++ b/hw/misc/meson.build
1034
+++ b/hw/nvram/meson.build
179
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_ARMSSE_CPUID', if_true: files('armsse-cpuid.c'))
1035
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_otp.c'))
180
softmmu_ss.add(when: 'CONFIG_ARMSSE_MHU', if_true: files('armsse-mhu.c'))
1036
softmmu_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_nvm.c'))
181
1037
softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE_CRC', if_true: files('xlnx-efuse-crc.c'))
182
softmmu_ss.add(when: 'CONFIG_PVPANIC_ISA', if_true: files('pvpanic-isa.c'))
1038
softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE', if_true: files('xlnx-efuse.c'))
183
+softmmu_ss.add(when: 'CONFIG_PVPANIC_PCI', if_true: files('pvpanic-pci.c'))
1039
+softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE_VERSAL', if_true: files(
184
softmmu_ss.add(when: 'CONFIG_AUX', if_true: files('auxbus.c'))
1040
+ 'xlnx-versal-efuse-cache.c',
185
softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_scu.c', 'aspeed_sdmc.c', 'aspeed_xdma.c'))
1041
+ 'xlnx-versal-efuse-ctrl.c'))
186
softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-sysreg.c'))
1042
1043
specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_nvram.c'))
187
--
1044
--
188
2.20.1
1045
2.20.1
189
1046
190
1047
diff view generated by jsdifflib
1
From: Mihai Carabas <mihai.carabas@oracle.com>
1
From: Tong Ho <tong.ho@xilinx.com>
2
2
3
To ease the PCI device addition in next patches, split the code as follows:
3
This implements the Xilinx ZynqMP eFuse, an one-time
4
- generic code (read/write/setup) is being kept in pvpanic.c
4
field-programmable non-volatile storage device. There is
5
- ISA dependent code moved to pvpanic-isa.c
5
only one such device in the Xilinx ZynqMP product family.
6
6
7
Also, rename:
7
Co-authored-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
- ISA_PVPANIC_DEVICE -> PVPANIC_ISA_DEVICE.
8
Co-authored-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
9
- TYPE_PVPANIC -> TYPE_PVPANIC_ISA.
10
- MemoryRegion io -> mr.
11
- pvpanic_ioport_* in pvpanic_*.
12
9
13
Update the build system with the new files and config structure.
10
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
14
11
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
15
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
12
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
13
Message-id: 20210917052400.1249094-4-tong.ho@xilinx.com
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
16
---
19
include/hw/misc/pvpanic.h | 23 +++++++++-
17
include/hw/nvram/xlnx-zynqmp-efuse.h | 44 ++
20
hw/misc/pvpanic-isa.c | 94 +++++++++++++++++++++++++++++++++++++++
18
hw/nvram/xlnx-zynqmp-efuse.c | 855 +++++++++++++++++++++++++++
21
hw/misc/pvpanic.c | 85 +++--------------------------------
19
hw/nvram/Kconfig | 4 +
22
hw/i386/Kconfig | 2 +-
20
hw/nvram/meson.build | 2 +
23
hw/misc/Kconfig | 6 ++-
21
4 files changed, 905 insertions(+)
24
hw/misc/meson.build | 3 +-
22
create mode 100644 include/hw/nvram/xlnx-zynqmp-efuse.h
25
tests/qtest/meson.build | 2 +-
23
create mode 100644 hw/nvram/xlnx-zynqmp-efuse.c
26
7 files changed, 130 insertions(+), 85 deletions(-)
27
create mode 100644 hw/misc/pvpanic-isa.c
28
24
29
diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
25
diff --git a/include/hw/nvram/xlnx-zynqmp-efuse.h b/include/hw/nvram/xlnx-zynqmp-efuse.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/misc/pvpanic.h
32
+++ b/include/hw/misc/pvpanic.h
33
@@ -XXX,XX +XXX,XX @@
34
35
#include "qom/object.h"
36
37
-#define TYPE_PVPANIC "pvpanic"
38
+#define TYPE_PVPANIC_ISA_DEVICE "pvpanic"
39
40
#define PVPANIC_IOPORT_PROP "ioport"
41
42
+/* The bit of supported pv event, TODO: include uapi header and remove this */
43
+#define PVPANIC_F_PANICKED 0
44
+#define PVPANIC_F_CRASHLOADED 1
45
+
46
+/* The pv event value */
47
+#define PVPANIC_PANICKED (1 << PVPANIC_F_PANICKED)
48
+#define PVPANIC_CRASHLOADED (1 << PVPANIC_F_CRASHLOADED)
49
+
50
+/*
51
+ * PVPanicState for any device type
52
+ */
53
+typedef struct PVPanicState PVPanicState;
54
+struct PVPanicState {
55
+ MemoryRegion mr;
56
+ uint8_t events;
57
+};
58
+
59
+void pvpanic_setup_io(PVPanicState *s, DeviceState *dev, unsigned size);
60
+
61
static inline uint16_t pvpanic_port(void)
62
{
63
- Object *o = object_resolve_path_type("", TYPE_PVPANIC, NULL);
64
+ Object *o = object_resolve_path_type("", TYPE_PVPANIC_ISA_DEVICE, NULL);
65
if (!o) {
66
return 0;
67
}
68
diff --git a/hw/misc/pvpanic-isa.c b/hw/misc/pvpanic-isa.c
69
new file mode 100644
26
new file mode 100644
70
index XXXXXXX..XXXXXXX
27
index XXXXXXX..XXXXXXX
71
--- /dev/null
28
--- /dev/null
72
+++ b/hw/misc/pvpanic-isa.c
29
+++ b/include/hw/nvram/xlnx-zynqmp-efuse.h
73
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@
74
+/*
31
+/*
75
+ * QEMU simulated pvpanic device.
32
+ * Copyright (c) 2021 Xilinx Inc.
76
+ *
33
+ *
77
+ * Copyright Fujitsu, Corp. 2013
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:
78
+ *
40
+ *
79
+ * Authors:
41
+ * The above copyright notice and this permission notice shall be included in
80
+ * Wen Congyang <wency@cn.fujitsu.com>
42
+ * all copies or substantial portions of the Software.
81
+ * Hu Tao <hutao@cn.fujitsu.com>
82
+ *
43
+ *
83
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
44
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
84
+ * See the COPYING file in the top-level directory.
45
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
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.
51
+ */
52
+#ifndef XLNX_ZYNQMP_EFUSE_H
53
+#define XLNX_ZYNQMP_EFUSE_H
54
+
55
+#include "hw/irq.h"
56
+#include "hw/sysbus.h"
57
+#include "hw/register.h"
58
+#include "hw/nvram/xlnx-efuse.h"
59
+
60
+#define XLNX_ZYNQMP_EFUSE_R_MAX ((0x10fc / 4) + 1)
61
+
62
+#define TYPE_XLNX_ZYNQMP_EFUSE "xlnx,zynqmp-efuse"
63
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPEFuse, XLNX_ZYNQMP_EFUSE);
64
+
65
+struct XlnxZynqMPEFuse {
66
+ SysBusDevice parent_obj;
67
+ qemu_irq irq;
68
+
69
+ XlnxEFuse *efuse;
70
+ uint32_t regs[XLNX_ZYNQMP_EFUSE_R_MAX];
71
+ RegisterInfo regs_info[XLNX_ZYNQMP_EFUSE_R_MAX];
72
+};
73
+
74
+#endif
75
diff --git a/hw/nvram/xlnx-zynqmp-efuse.c b/hw/nvram/xlnx-zynqmp-efuse.c
76
new file mode 100644
77
index XXXXXXX..XXXXXXX
78
--- /dev/null
79
+++ b/hw/nvram/xlnx-zynqmp-efuse.c
80
@@ -XXX,XX +XXX,XX @@
81
+/*
82
+ * QEMU model of the ZynqMP eFuse
85
+ *
83
+ *
84
+ * Copyright (c) 2015 Xilinx Inc.
85
+ *
86
+ * Written by Edgar E. Iglesias <edgari@xilinx.com>
87
+ *
88
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
89
+ * of this software and associated documentation files (the "Software"), to deal
90
+ * in the Software without restriction, including without limitation the rights
91
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
92
+ * copies of the Software, and to permit persons to whom the Software is
93
+ * furnished to do so, subject to the following conditions:
94
+ *
95
+ * The above copyright notice and this permission notice shall be included in
96
+ * all copies or substantial portions of the Software.
97
+ *
98
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
99
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
100
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
101
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
102
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
103
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
104
+ * THE SOFTWARE.
86
+ */
105
+ */
87
+
106
+
88
+#include "qemu/osdep.h"
107
+#include "qemu/osdep.h"
108
+#include "hw/nvram/xlnx-zynqmp-efuse.h"
109
+
89
+#include "qemu/log.h"
110
+#include "qemu/log.h"
90
+#include "qemu/module.h"
111
+#include "qapi/error.h"
91
+#include "sysemu/runstate.h"
112
+#include "migration/vmstate.h"
92
+
93
+#include "hw/nvram/fw_cfg.h"
94
+#include "hw/qdev-properties.h"
113
+#include "hw/qdev-properties.h"
95
+#include "hw/misc/pvpanic.h"
114
+
96
+#include "qom/object.h"
115
+#ifndef ZYNQMP_EFUSE_ERR_DEBUG
97
+#include "hw/isa/isa.h"
116
+#define ZYNQMP_EFUSE_ERR_DEBUG 0
98
+
117
+#endif
99
+OBJECT_DECLARE_SIMPLE_TYPE(PVPanicISAState, PVPANIC_ISA_DEVICE)
118
+
119
+REG32(WR_LOCK, 0x0)
120
+ FIELD(WR_LOCK, LOCK, 0, 16)
121
+REG32(CFG, 0x4)
122
+ FIELD(CFG, SLVERR_ENABLE, 5, 1)
123
+ FIELD(CFG, MARGIN_RD, 2, 2)
124
+ FIELD(CFG, PGM_EN, 1, 1)
125
+ FIELD(CFG, EFUSE_CLK_SEL, 0, 1)
126
+REG32(STATUS, 0x8)
127
+ FIELD(STATUS, AES_CRC_PASS, 7, 1)
128
+ FIELD(STATUS, AES_CRC_DONE, 6, 1)
129
+ FIELD(STATUS, CACHE_DONE, 5, 1)
130
+ FIELD(STATUS, CACHE_LOAD, 4, 1)
131
+ FIELD(STATUS, EFUSE_3_TBIT, 2, 1)
132
+ FIELD(STATUS, EFUSE_2_TBIT, 1, 1)
133
+ FIELD(STATUS, EFUSE_0_TBIT, 0, 1)
134
+REG32(EFUSE_PGM_ADDR, 0xc)
135
+ FIELD(EFUSE_PGM_ADDR, EFUSE, 11, 2)
136
+ FIELD(EFUSE_PGM_ADDR, ROW, 5, 6)
137
+ FIELD(EFUSE_PGM_ADDR, COLUMN, 0, 5)
138
+REG32(EFUSE_RD_ADDR, 0x10)
139
+ FIELD(EFUSE_RD_ADDR, EFUSE, 11, 2)
140
+ FIELD(EFUSE_RD_ADDR, ROW, 5, 6)
141
+REG32(EFUSE_RD_DATA, 0x14)
142
+REG32(TPGM, 0x18)
143
+ FIELD(TPGM, VALUE, 0, 16)
144
+REG32(TRD, 0x1c)
145
+ FIELD(TRD, VALUE, 0, 8)
146
+REG32(TSU_H_PS, 0x20)
147
+ FIELD(TSU_H_PS, VALUE, 0, 8)
148
+REG32(TSU_H_PS_CS, 0x24)
149
+ FIELD(TSU_H_PS_CS, VALUE, 0, 8)
150
+REG32(TSU_H_CS, 0x2c)
151
+ FIELD(TSU_H_CS, VALUE, 0, 4)
152
+REG32(EFUSE_ISR, 0x30)
153
+ FIELD(EFUSE_ISR, APB_SLVERR, 31, 1)
154
+ FIELD(EFUSE_ISR, CACHE_ERROR, 4, 1)
155
+ FIELD(EFUSE_ISR, RD_ERROR, 3, 1)
156
+ FIELD(EFUSE_ISR, RD_DONE, 2, 1)
157
+ FIELD(EFUSE_ISR, PGM_ERROR, 1, 1)
158
+ FIELD(EFUSE_ISR, PGM_DONE, 0, 1)
159
+REG32(EFUSE_IMR, 0x34)
160
+ FIELD(EFUSE_IMR, APB_SLVERR, 31, 1)
161
+ FIELD(EFUSE_IMR, CACHE_ERROR, 4, 1)
162
+ FIELD(EFUSE_IMR, RD_ERROR, 3, 1)
163
+ FIELD(EFUSE_IMR, RD_DONE, 2, 1)
164
+ FIELD(EFUSE_IMR, PGM_ERROR, 1, 1)
165
+ FIELD(EFUSE_IMR, PGM_DONE, 0, 1)
166
+REG32(EFUSE_IER, 0x38)
167
+ FIELD(EFUSE_IER, APB_SLVERR, 31, 1)
168
+ FIELD(EFUSE_IER, CACHE_ERROR, 4, 1)
169
+ FIELD(EFUSE_IER, RD_ERROR, 3, 1)
170
+ FIELD(EFUSE_IER, RD_DONE, 2, 1)
171
+ FIELD(EFUSE_IER, PGM_ERROR, 1, 1)
172
+ FIELD(EFUSE_IER, PGM_DONE, 0, 1)
173
+REG32(EFUSE_IDR, 0x3c)
174
+ FIELD(EFUSE_IDR, APB_SLVERR, 31, 1)
175
+ FIELD(EFUSE_IDR, CACHE_ERROR, 4, 1)
176
+ FIELD(EFUSE_IDR, RD_ERROR, 3, 1)
177
+ FIELD(EFUSE_IDR, RD_DONE, 2, 1)
178
+ FIELD(EFUSE_IDR, PGM_ERROR, 1, 1)
179
+ FIELD(EFUSE_IDR, PGM_DONE, 0, 1)
180
+REG32(EFUSE_CACHE_LOAD, 0x40)
181
+ FIELD(EFUSE_CACHE_LOAD, LOAD, 0, 1)
182
+REG32(EFUSE_PGM_LOCK, 0x44)
183
+ FIELD(EFUSE_PGM_LOCK, SPK_ID_LOCK, 0, 1)
184
+REG32(EFUSE_AES_CRC, 0x48)
185
+REG32(EFUSE_TBITS_PRGRMG_EN, 0x100)
186
+ FIELD(EFUSE_TBITS_PRGRMG_EN, TBITS_PRGRMG_EN, 3, 1)
187
+REG32(DNA_0, 0x100c)
188
+REG32(DNA_1, 0x1010)
189
+REG32(DNA_2, 0x1014)
190
+REG32(IPDISABLE, 0x1018)
191
+ FIELD(IPDISABLE, VCU_DIS, 8, 1)
192
+ FIELD(IPDISABLE, GPU_DIS, 5, 1)
193
+ FIELD(IPDISABLE, APU3_DIS, 3, 1)
194
+ FIELD(IPDISABLE, APU2_DIS, 2, 1)
195
+ FIELD(IPDISABLE, APU1_DIS, 1, 1)
196
+ FIELD(IPDISABLE, APU0_DIS, 0, 1)
197
+REG32(SYSOSC_CTRL, 0x101c)
198
+ FIELD(SYSOSC_CTRL, SYSOSC_EN, 0, 1)
199
+REG32(USER_0, 0x1020)
200
+REG32(USER_1, 0x1024)
201
+REG32(USER_2, 0x1028)
202
+REG32(USER_3, 0x102c)
203
+REG32(USER_4, 0x1030)
204
+REG32(USER_5, 0x1034)
205
+REG32(USER_6, 0x1038)
206
+REG32(USER_7, 0x103c)
207
+REG32(MISC_USER_CTRL, 0x1040)
208
+ FIELD(MISC_USER_CTRL, FPD_SC_EN_0, 14, 1)
209
+ FIELD(MISC_USER_CTRL, LPD_SC_EN_0, 11, 1)
210
+ FIELD(MISC_USER_CTRL, LBIST_EN, 10, 1)
211
+ FIELD(MISC_USER_CTRL, USR_WRLK_7, 7, 1)
212
+ FIELD(MISC_USER_CTRL, USR_WRLK_6, 6, 1)
213
+ FIELD(MISC_USER_CTRL, USR_WRLK_5, 5, 1)
214
+ FIELD(MISC_USER_CTRL, USR_WRLK_4, 4, 1)
215
+ FIELD(MISC_USER_CTRL, USR_WRLK_3, 3, 1)
216
+ FIELD(MISC_USER_CTRL, USR_WRLK_2, 2, 1)
217
+ FIELD(MISC_USER_CTRL, USR_WRLK_1, 1, 1)
218
+ FIELD(MISC_USER_CTRL, USR_WRLK_0, 0, 1)
219
+REG32(ROM_RSVD, 0x1044)
220
+ FIELD(ROM_RSVD, PBR_BOOT_ERROR, 0, 3)
221
+REG32(PUF_CHASH, 0x1050)
222
+REG32(PUF_MISC, 0x1054)
223
+ FIELD(PUF_MISC, REGISTER_DIS, 31, 1)
224
+ FIELD(PUF_MISC, SYN_WRLK, 30, 1)
225
+ FIELD(PUF_MISC, SYN_INVLD, 29, 1)
226
+ FIELD(PUF_MISC, TEST2_DIS, 28, 1)
227
+ FIELD(PUF_MISC, UNUSED27, 27, 1)
228
+ FIELD(PUF_MISC, UNUSED26, 26, 1)
229
+ FIELD(PUF_MISC, UNUSED25, 25, 1)
230
+ FIELD(PUF_MISC, UNUSED24, 24, 1)
231
+ FIELD(PUF_MISC, AUX, 0, 24)
232
+REG32(SEC_CTRL, 0x1058)
233
+ FIELD(SEC_CTRL, PPK1_INVLD, 30, 2)
234
+ FIELD(SEC_CTRL, PPK1_WRLK, 29, 1)
235
+ FIELD(SEC_CTRL, PPK0_INVLD, 27, 2)
236
+ FIELD(SEC_CTRL, PPK0_WRLK, 26, 1)
237
+ FIELD(SEC_CTRL, RSA_EN, 11, 15)
238
+ FIELD(SEC_CTRL, SEC_LOCK, 10, 1)
239
+ FIELD(SEC_CTRL, PROG_GATE_2, 9, 1)
240
+ FIELD(SEC_CTRL, PROG_GATE_1, 8, 1)
241
+ FIELD(SEC_CTRL, PROG_GATE_0, 7, 1)
242
+ FIELD(SEC_CTRL, DFT_DIS, 6, 1)
243
+ FIELD(SEC_CTRL, JTAG_DIS, 5, 1)
244
+ FIELD(SEC_CTRL, ERROR_DIS, 4, 1)
245
+ FIELD(SEC_CTRL, BBRAM_DIS, 3, 1)
246
+ FIELD(SEC_CTRL, ENC_ONLY, 2, 1)
247
+ FIELD(SEC_CTRL, AES_WRLK, 1, 1)
248
+ FIELD(SEC_CTRL, AES_RDLK, 0, 1)
249
+REG32(SPK_ID, 0x105c)
250
+REG32(PPK0_0, 0x10a0)
251
+REG32(PPK0_1, 0x10a4)
252
+REG32(PPK0_2, 0x10a8)
253
+REG32(PPK0_3, 0x10ac)
254
+REG32(PPK0_4, 0x10b0)
255
+REG32(PPK0_5, 0x10b4)
256
+REG32(PPK0_6, 0x10b8)
257
+REG32(PPK0_7, 0x10bc)
258
+REG32(PPK0_8, 0x10c0)
259
+REG32(PPK0_9, 0x10c4)
260
+REG32(PPK0_10, 0x10c8)
261
+REG32(PPK0_11, 0x10cc)
262
+REG32(PPK1_0, 0x10d0)
263
+REG32(PPK1_1, 0x10d4)
264
+REG32(PPK1_2, 0x10d8)
265
+REG32(PPK1_3, 0x10dc)
266
+REG32(PPK1_4, 0x10e0)
267
+REG32(PPK1_5, 0x10e4)
268
+REG32(PPK1_6, 0x10e8)
269
+REG32(PPK1_7, 0x10ec)
270
+REG32(PPK1_8, 0x10f0)
271
+REG32(PPK1_9, 0x10f4)
272
+REG32(PPK1_10, 0x10f8)
273
+REG32(PPK1_11, 0x10fc)
274
+
275
+#define BIT_POS(ROW, COLUMN) (ROW * 32 + COLUMN)
276
+#define R_MAX (R_PPK1_11 + 1)
277
+
278
+/* #define EFUSE_XOSC 26 */
100
+
279
+
101
+/*
280
+/*
102
+ * PVPanicISAState for ISA device and
281
+ * eFUSE layout references:
103
+ * use ioport.
282
+ * ZynqMP: UG1085 (v2.1) August 21, 2019, p.277, Table 12-13
104
+ */
283
+ */
105
+struct PVPanicISAState {
284
+#define EFUSE_AES_RDLK BIT_POS(22, 0)
106
+ ISADevice parent_obj;
285
+#define EFUSE_AES_WRLK BIT_POS(22, 1)
107
+
286
+#define EFUSE_ENC_ONLY BIT_POS(22, 2)
108
+ uint16_t ioport;
287
+#define EFUSE_BBRAM_DIS BIT_POS(22, 3)
109
+ PVPanicState pvpanic;
288
+#define EFUSE_ERROR_DIS BIT_POS(22, 4)
289
+#define EFUSE_JTAG_DIS BIT_POS(22, 5)
290
+#define EFUSE_DFT_DIS BIT_POS(22, 6)
291
+#define EFUSE_PROG_GATE_0 BIT_POS(22, 7)
292
+#define EFUSE_PROG_GATE_1 BIT_POS(22, 7)
293
+#define EFUSE_PROG_GATE_2 BIT_POS(22, 9)
294
+#define EFUSE_SEC_LOCK BIT_POS(22, 10)
295
+#define EFUSE_RSA_EN BIT_POS(22, 11)
296
+#define EFUSE_RSA_EN14 BIT_POS(22, 25)
297
+#define EFUSE_PPK0_WRLK BIT_POS(22, 26)
298
+#define EFUSE_PPK0_INVLD BIT_POS(22, 27)
299
+#define EFUSE_PPK0_INVLD_1 BIT_POS(22, 28)
300
+#define EFUSE_PPK1_WRLK BIT_POS(22, 29)
301
+#define EFUSE_PPK1_INVLD BIT_POS(22, 30)
302
+#define EFUSE_PPK1_INVLD_1 BIT_POS(22, 31)
303
+
304
+/* Areas. */
305
+#define EFUSE_TRIM_START BIT_POS(1, 0)
306
+#define EFUSE_TRIM_END BIT_POS(1, 30)
307
+#define EFUSE_DNA_START BIT_POS(3, 0)
308
+#define EFUSE_DNA_END BIT_POS(5, 31)
309
+#define EFUSE_AES_START BIT_POS(24, 0)
310
+#define EFUSE_AES_END BIT_POS(31, 31)
311
+#define EFUSE_ROM_START BIT_POS(17, 0)
312
+#define EFUSE_ROM_END BIT_POS(17, 31)
313
+#define EFUSE_IPDIS_START BIT_POS(6, 0)
314
+#define EFUSE_IPDIS_END BIT_POS(6, 31)
315
+#define EFUSE_USER_START BIT_POS(8, 0)
316
+#define EFUSE_USER_END BIT_POS(15, 31)
317
+#define EFUSE_BISR_START BIT_POS(32, 0)
318
+#define EFUSE_BISR_END BIT_POS(39, 31)
319
+
320
+#define EFUSE_USER_CTRL_START BIT_POS(16, 0)
321
+#define EFUSE_USER_CTRL_END BIT_POS(16, 16)
322
+#define EFUSE_USER_CTRL_MASK ((uint32_t)MAKE_64BIT_MASK(0, 17))
323
+
324
+#define EFUSE_PUF_CHASH_START BIT_POS(20, 0)
325
+#define EFUSE_PUF_CHASH_END BIT_POS(20, 31)
326
+#define EFUSE_PUF_MISC_START BIT_POS(21, 0)
327
+#define EFUSE_PUF_MISC_END BIT_POS(21, 31)
328
+#define EFUSE_PUF_SYN_WRLK BIT_POS(21, 30)
329
+
330
+#define EFUSE_SPK_START BIT_POS(23, 0)
331
+#define EFUSE_SPK_END BIT_POS(23, 31)
332
+
333
+#define EFUSE_PPK0_START BIT_POS(40, 0)
334
+#define EFUSE_PPK0_END BIT_POS(51, 31)
335
+#define EFUSE_PPK1_START BIT_POS(52, 0)
336
+#define EFUSE_PPK1_END BIT_POS(63, 31)
337
+
338
+#define EFUSE_CACHE_FLD(s, reg, field) \
339
+ ARRAY_FIELD_DP32((s)->regs, reg, field, \
340
+ (xlnx_efuse_get_row((s->efuse), EFUSE_ ## field) \
341
+ >> (EFUSE_ ## field % 32)))
342
+
343
+#define EFUSE_CACHE_BIT(s, reg, field) \
344
+ ARRAY_FIELD_DP32((s)->regs, reg, field, xlnx_efuse_get_bit((s->efuse), \
345
+ EFUSE_ ## field))
346
+
347
+#define FBIT_UNKNOWN (~0)
348
+
349
+QEMU_BUILD_BUG_ON(R_MAX != ARRAY_SIZE(((XlnxZynqMPEFuse *)0)->regs));
350
+
351
+static void update_tbit_status(XlnxZynqMPEFuse *s)
352
+{
353
+ unsigned int check = xlnx_efuse_tbits_check(s->efuse);
354
+ uint32_t val = s->regs[R_STATUS];
355
+
356
+ val = FIELD_DP32(val, STATUS, EFUSE_0_TBIT, !!(check & (1 << 0)));
357
+ val = FIELD_DP32(val, STATUS, EFUSE_2_TBIT, !!(check & (1 << 1)));
358
+ val = FIELD_DP32(val, STATUS, EFUSE_3_TBIT, !!(check & (1 << 2)));
359
+
360
+ s->regs[R_STATUS] = val;
361
+}
362
+
363
+/* Update the u32 array from efuse bits. Slow but simple approach. */
364
+static void cache_sync_u32(XlnxZynqMPEFuse *s, unsigned int r_start,
365
+ unsigned int f_start, unsigned int f_end,
366
+ unsigned int f_written)
367
+{
368
+ uint32_t *u32 = &s->regs[r_start];
369
+ unsigned int fbit, wbits = 0, u32_off = 0;
370
+
371
+ /* Avoid working on bits that are not relevant. */
372
+ if (f_written != FBIT_UNKNOWN
373
+ && (f_written < f_start || f_written > f_end)) {
374
+ return;
375
+ }
376
+
377
+ for (fbit = f_start; fbit <= f_end; fbit++, wbits++) {
378
+ if (wbits == 32) {
379
+ /* Update the key offset. */
380
+ u32_off += 1;
381
+ wbits = 0;
382
+ }
383
+ u32[u32_off] |= xlnx_efuse_get_bit(s->efuse, fbit) << wbits;
384
+ }
385
+}
386
+
387
+/*
388
+ * Keep the syncs in bit order so we can bail out for the
389
+ * slower ones.
390
+ */
391
+static void zynqmp_efuse_sync_cache(XlnxZynqMPEFuse *s, unsigned int bit)
392
+{
393
+ EFUSE_CACHE_BIT(s, SEC_CTRL, AES_RDLK);
394
+ EFUSE_CACHE_BIT(s, SEC_CTRL, AES_WRLK);
395
+ EFUSE_CACHE_BIT(s, SEC_CTRL, ENC_ONLY);
396
+ EFUSE_CACHE_BIT(s, SEC_CTRL, BBRAM_DIS);
397
+ EFUSE_CACHE_BIT(s, SEC_CTRL, ERROR_DIS);
398
+ EFUSE_CACHE_BIT(s, SEC_CTRL, JTAG_DIS);
399
+ EFUSE_CACHE_BIT(s, SEC_CTRL, DFT_DIS);
400
+ EFUSE_CACHE_BIT(s, SEC_CTRL, PROG_GATE_0);
401
+ EFUSE_CACHE_BIT(s, SEC_CTRL, PROG_GATE_1);
402
+ EFUSE_CACHE_BIT(s, SEC_CTRL, PROG_GATE_2);
403
+ EFUSE_CACHE_BIT(s, SEC_CTRL, SEC_LOCK);
404
+ EFUSE_CACHE_BIT(s, SEC_CTRL, PPK0_WRLK);
405
+ EFUSE_CACHE_BIT(s, SEC_CTRL, PPK1_WRLK);
406
+
407
+ EFUSE_CACHE_FLD(s, SEC_CTRL, RSA_EN);
408
+ EFUSE_CACHE_FLD(s, SEC_CTRL, PPK0_INVLD);
409
+ EFUSE_CACHE_FLD(s, SEC_CTRL, PPK1_INVLD);
410
+
411
+ /* Update the tbits. */
412
+ update_tbit_status(s);
413
+
414
+ /* Sync the various areas. */
415
+ s->regs[R_MISC_USER_CTRL] = xlnx_efuse_get_row(s->efuse,
416
+ EFUSE_USER_CTRL_START)
417
+ & EFUSE_USER_CTRL_MASK;
418
+ s->regs[R_PUF_CHASH] = xlnx_efuse_get_row(s->efuse, EFUSE_PUF_CHASH_START);
419
+ s->regs[R_PUF_MISC] = xlnx_efuse_get_row(s->efuse, EFUSE_PUF_MISC_START);
420
+
421
+ cache_sync_u32(s, R_DNA_0, EFUSE_DNA_START, EFUSE_DNA_END, bit);
422
+
423
+ if (bit < EFUSE_AES_START) {
424
+ return;
425
+ }
426
+
427
+ cache_sync_u32(s, R_ROM_RSVD, EFUSE_ROM_START, EFUSE_ROM_END, bit);
428
+ cache_sync_u32(s, R_IPDISABLE, EFUSE_IPDIS_START, EFUSE_IPDIS_END, bit);
429
+ cache_sync_u32(s, R_USER_0, EFUSE_USER_START, EFUSE_USER_END, bit);
430
+ cache_sync_u32(s, R_SPK_ID, EFUSE_SPK_START, EFUSE_SPK_END, bit);
431
+ cache_sync_u32(s, R_PPK0_0, EFUSE_PPK0_START, EFUSE_PPK0_END, bit);
432
+ cache_sync_u32(s, R_PPK1_0, EFUSE_PPK1_START, EFUSE_PPK1_END, bit);
433
+}
434
+
435
+static void zynqmp_efuse_update_irq(XlnxZynqMPEFuse *s)
436
+{
437
+ bool pending = s->regs[R_EFUSE_ISR] & s->regs[R_EFUSE_IMR];
438
+ qemu_set_irq(s->irq, pending);
439
+}
440
+
441
+static void zynqmp_efuse_isr_postw(RegisterInfo *reg, uint64_t val64)
442
+{
443
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
444
+ zynqmp_efuse_update_irq(s);
445
+}
446
+
447
+static uint64_t zynqmp_efuse_ier_prew(RegisterInfo *reg, uint64_t val64)
448
+{
449
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
450
+ uint32_t val = val64;
451
+
452
+ s->regs[R_EFUSE_IMR] |= val;
453
+ zynqmp_efuse_update_irq(s);
454
+ return 0;
455
+}
456
+
457
+static uint64_t zynqmp_efuse_idr_prew(RegisterInfo *reg, uint64_t val64)
458
+{
459
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
460
+ uint32_t val = val64;
461
+
462
+ s->regs[R_EFUSE_IMR] &= ~val;
463
+ zynqmp_efuse_update_irq(s);
464
+ return 0;
465
+}
466
+
467
+static void zynqmp_efuse_pgm_addr_postw(RegisterInfo *reg, uint64_t val64)
468
+{
469
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
470
+ unsigned bit = val64;
471
+ unsigned page = FIELD_EX32(bit, EFUSE_PGM_ADDR, EFUSE);
472
+ bool puf_prot = false;
473
+ const char *errmsg = NULL;
474
+
475
+ /* Allow only valid array, and adjust for skipped array 1 */
476
+ switch (page) {
477
+ case 0:
478
+ break;
479
+ case 2 ... 3:
480
+ bit = FIELD_DP32(bit, EFUSE_PGM_ADDR, EFUSE, page - 1);
481
+ puf_prot = xlnx_efuse_get_bit(s->efuse, EFUSE_PUF_SYN_WRLK);
482
+ break;
483
+ default:
484
+ errmsg = "Invalid address";
485
+ goto pgm_done;
486
+ }
487
+
488
+ if (ARRAY_FIELD_EX32(s->regs, WR_LOCK, LOCK)) {
489
+ errmsg = "Array write-locked";
490
+ goto pgm_done;
491
+ }
492
+
493
+ if (!ARRAY_FIELD_EX32(s->regs, CFG, PGM_EN)) {
494
+ errmsg = "Array pgm-disabled";
495
+ goto pgm_done;
496
+ }
497
+
498
+ if (puf_prot) {
499
+ errmsg = "PUF_HD-store write-locked";
500
+ goto pgm_done;
501
+ }
502
+
503
+ if (ARRAY_FIELD_EX32(s->regs, SEC_CTRL, AES_WRLK)
504
+ && bit >= EFUSE_AES_START && bit <= EFUSE_AES_END) {
505
+ errmsg = "AES key-store Write-locked";
506
+ goto pgm_done;
507
+ }
508
+
509
+ if (!xlnx_efuse_set_bit(s->efuse, bit)) {
510
+ errmsg = "Write failed";
511
+ }
512
+
513
+ pgm_done:
514
+ if (!errmsg) {
515
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_ERROR, 0);
516
+ } else {
517
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_ERROR, 1);
518
+ qemu_log_mask(LOG_GUEST_ERROR,
519
+ "%s - eFuse write error: %s; addr=0x%x\n",
520
+ object_get_canonical_path(OBJECT(s)),
521
+ errmsg, (unsigned)val64);
522
+ }
523
+
524
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_DONE, 1);
525
+ zynqmp_efuse_update_irq(s);
526
+}
527
+
528
+static void zynqmp_efuse_rd_addr_postw(RegisterInfo *reg, uint64_t val64)
529
+{
530
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
531
+
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;
603
+ }
604
+ break;
605
+ case 2: /* PUF helper data, adjust for skipped array 1 */
606
+ case 3:
607
+ val64 = FIELD_DP32(efuse_idx, EFUSE_RD_ADDR, EFUSE, efuse_ary - 1);
608
+ break;
609
+ default:
610
+ goto denied;
611
+ }
612
+
613
+ s->regs[R_EFUSE_RD_DATA] = xlnx_efuse_get_row(s->efuse, val64) & col_mask;
614
+
615
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_ERROR, 0);
616
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_DONE, 1);
617
+ zynqmp_efuse_update_irq(s);
618
+ return;
619
+
620
+ denied:
621
+ qemu_log_mask(LOG_GUEST_ERROR,
622
+ "%s: Denied efuse read from array %u, row %u\n",
623
+ object_get_canonical_path(OBJECT(s)),
624
+ efuse_ary, efuse_row);
625
+
626
+ s->regs[R_EFUSE_RD_DATA] = 0;
627
+
628
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_ERROR, 1);
629
+ ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_DONE, 0);
630
+ zynqmp_efuse_update_irq(s);
631
+}
632
+
633
+static void zynqmp_efuse_aes_crc_postw(RegisterInfo *reg, uint64_t val64)
634
+{
635
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
636
+ bool ok;
637
+
638
+ ok = xlnx_efuse_k256_check(s->efuse, (uint32_t)val64, EFUSE_AES_START);
639
+
640
+ ARRAY_FIELD_DP32(s->regs, STATUS, AES_CRC_PASS, (ok ? 1 : 0));
641
+ ARRAY_FIELD_DP32(s->regs, STATUS, AES_CRC_DONE, 1);
642
+
643
+ s->regs[R_EFUSE_AES_CRC] = 0; /* crc value is write-only */
644
+}
645
+
646
+static uint64_t zynqmp_efuse_cache_load_prew(RegisterInfo *reg,
647
+ uint64_t valu64)
648
+{
649
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
650
+
651
+ if (valu64 & R_EFUSE_CACHE_LOAD_LOAD_MASK) {
652
+ zynqmp_efuse_sync_cache(s, FBIT_UNKNOWN);
653
+ ARRAY_FIELD_DP32(s->regs, STATUS, CACHE_DONE, 1);
654
+ zynqmp_efuse_update_irq(s);
655
+ }
656
+
657
+ return 0;
658
+}
659
+
660
+static uint64_t zynqmp_efuse_wr_lock_prew(RegisterInfo *reg, uint64_t val)
661
+{
662
+ return val == 0xDF0D ? 0 : 1;
663
+}
664
+
665
+static RegisterAccessInfo zynqmp_efuse_regs_info[] = {
666
+ { .name = "WR_LOCK", .addr = A_WR_LOCK,
667
+ .reset = 0x1,
668
+ .pre_write = zynqmp_efuse_wr_lock_prew,
669
+ },{ .name = "CFG", .addr = A_CFG,
670
+ },{ .name = "STATUS", .addr = A_STATUS,
671
+ .rsvd = 0x8,
672
+ .ro = 0xff,
673
+ },{ .name = "EFUSE_PGM_ADDR", .addr = A_EFUSE_PGM_ADDR,
674
+ .post_write = zynqmp_efuse_pgm_addr_postw
675
+ },{ .name = "EFUSE_RD_ADDR", .addr = A_EFUSE_RD_ADDR,
676
+ .rsvd = 0x1f,
677
+ .post_write = zynqmp_efuse_rd_addr_postw,
678
+ },{ .name = "EFUSE_RD_DATA", .addr = A_EFUSE_RD_DATA,
679
+ .ro = 0xffffffff,
680
+ },{ .name = "TPGM", .addr = A_TPGM,
681
+ },{ .name = "TRD", .addr = A_TRD,
682
+ .reset = 0x1b,
683
+ },{ .name = "TSU_H_PS", .addr = A_TSU_H_PS,
684
+ .reset = 0xff,
685
+ },{ .name = "TSU_H_PS_CS", .addr = A_TSU_H_PS_CS,
686
+ .reset = 0xb,
687
+ },{ .name = "TSU_H_CS", .addr = A_TSU_H_CS,
688
+ .reset = 0x7,
689
+ },{ .name = "EFUSE_ISR", .addr = A_EFUSE_ISR,
690
+ .rsvd = 0x7fffffe0,
691
+ .w1c = 0x8000001f,
692
+ .post_write = zynqmp_efuse_isr_postw,
693
+ },{ .name = "EFUSE_IMR", .addr = A_EFUSE_IMR,
694
+ .reset = 0x8000001f,
695
+ .rsvd = 0x7fffffe0,
696
+ .ro = 0xffffffff,
697
+ },{ .name = "EFUSE_IER", .addr = A_EFUSE_IER,
698
+ .rsvd = 0x7fffffe0,
699
+ .pre_write = zynqmp_efuse_ier_prew,
700
+ },{ .name = "EFUSE_IDR", .addr = A_EFUSE_IDR,
701
+ .rsvd = 0x7fffffe0,
702
+ .pre_write = zynqmp_efuse_idr_prew,
703
+ },{ .name = "EFUSE_CACHE_LOAD", .addr = A_EFUSE_CACHE_LOAD,
704
+ .pre_write = zynqmp_efuse_cache_load_prew,
705
+ },{ .name = "EFUSE_PGM_LOCK", .addr = A_EFUSE_PGM_LOCK,
706
+ },{ .name = "EFUSE_AES_CRC", .addr = A_EFUSE_AES_CRC,
707
+ .post_write = zynqmp_efuse_aes_crc_postw,
708
+ },{ .name = "EFUSE_TBITS_PRGRMG_EN", .addr = A_EFUSE_TBITS_PRGRMG_EN,
709
+ .reset = R_EFUSE_TBITS_PRGRMG_EN_TBITS_PRGRMG_EN_MASK,
710
+ },{ .name = "DNA_0", .addr = A_DNA_0,
711
+ .ro = 0xffffffff,
712
+ },{ .name = "DNA_1", .addr = A_DNA_1,
713
+ .ro = 0xffffffff,
714
+ },{ .name = "DNA_2", .addr = A_DNA_2,
715
+ .ro = 0xffffffff,
716
+ },{ .name = "IPDISABLE", .addr = A_IPDISABLE,
717
+ .ro = 0xffffffff,
718
+ },{ .name = "SYSOSC_CTRL", .addr = A_SYSOSC_CTRL,
719
+ .ro = 0xffffffff,
720
+ },{ .name = "USER_0", .addr = A_USER_0,
721
+ .ro = 0xffffffff,
722
+ },{ .name = "USER_1", .addr = A_USER_1,
723
+ .ro = 0xffffffff,
724
+ },{ .name = "USER_2", .addr = A_USER_2,
725
+ .ro = 0xffffffff,
726
+ },{ .name = "USER_3", .addr = A_USER_3,
727
+ .ro = 0xffffffff,
728
+ },{ .name = "USER_4", .addr = A_USER_4,
729
+ .ro = 0xffffffff,
730
+ },{ .name = "USER_5", .addr = A_USER_5,
731
+ .ro = 0xffffffff,
732
+ },{ .name = "USER_6", .addr = A_USER_6,
733
+ .ro = 0xffffffff,
734
+ },{ .name = "USER_7", .addr = A_USER_7,
735
+ .ro = 0xffffffff,
736
+ },{ .name = "MISC_USER_CTRL", .addr = A_MISC_USER_CTRL,
737
+ .ro = 0xffffffff,
738
+ },{ .name = "ROM_RSVD", .addr = A_ROM_RSVD,
739
+ .ro = 0xffffffff,
740
+ },{ .name = "PUF_CHASH", .addr = A_PUF_CHASH,
741
+ .ro = 0xffffffff,
742
+ },{ .name = "PUF_MISC", .addr = A_PUF_MISC,
743
+ .ro = 0xffffffff,
744
+ },{ .name = "SEC_CTRL", .addr = A_SEC_CTRL,
745
+ .ro = 0xffffffff,
746
+ },{ .name = "SPK_ID", .addr = A_SPK_ID,
747
+ .ro = 0xffffffff,
748
+ },{ .name = "PPK0_0", .addr = A_PPK0_0,
749
+ .ro = 0xffffffff,
750
+ },{ .name = "PPK0_1", .addr = A_PPK0_1,
751
+ .ro = 0xffffffff,
752
+ },{ .name = "PPK0_2", .addr = A_PPK0_2,
753
+ .ro = 0xffffffff,
754
+ },{ .name = "PPK0_3", .addr = A_PPK0_3,
755
+ .ro = 0xffffffff,
756
+ },{ .name = "PPK0_4", .addr = A_PPK0_4,
757
+ .ro = 0xffffffff,
758
+ },{ .name = "PPK0_5", .addr = A_PPK0_5,
759
+ .ro = 0xffffffff,
760
+ },{ .name = "PPK0_6", .addr = A_PPK0_6,
761
+ .ro = 0xffffffff,
762
+ },{ .name = "PPK0_7", .addr = A_PPK0_7,
763
+ .ro = 0xffffffff,
764
+ },{ .name = "PPK0_8", .addr = A_PPK0_8,
765
+ .ro = 0xffffffff,
766
+ },{ .name = "PPK0_9", .addr = A_PPK0_9,
767
+ .ro = 0xffffffff,
768
+ },{ .name = "PPK0_10", .addr = A_PPK0_10,
769
+ .ro = 0xffffffff,
770
+ },{ .name = "PPK0_11", .addr = A_PPK0_11,
771
+ .ro = 0xffffffff,
772
+ },{ .name = "PPK1_0", .addr = A_PPK1_0,
773
+ .ro = 0xffffffff,
774
+ },{ .name = "PPK1_1", .addr = A_PPK1_1,
775
+ .ro = 0xffffffff,
776
+ },{ .name = "PPK1_2", .addr = A_PPK1_2,
777
+ .ro = 0xffffffff,
778
+ },{ .name = "PPK1_3", .addr = A_PPK1_3,
779
+ .ro = 0xffffffff,
780
+ },{ .name = "PPK1_4", .addr = A_PPK1_4,
781
+ .ro = 0xffffffff,
782
+ },{ .name = "PPK1_5", .addr = A_PPK1_5,
783
+ .ro = 0xffffffff,
784
+ },{ .name = "PPK1_6", .addr = A_PPK1_6,
785
+ .ro = 0xffffffff,
786
+ },{ .name = "PPK1_7", .addr = A_PPK1_7,
787
+ .ro = 0xffffffff,
788
+ },{ .name = "PPK1_8", .addr = A_PPK1_8,
789
+ .ro = 0xffffffff,
790
+ },{ .name = "PPK1_9", .addr = A_PPK1_9,
791
+ .ro = 0xffffffff,
792
+ },{ .name = "PPK1_10", .addr = A_PPK1_10,
793
+ .ro = 0xffffffff,
794
+ },{ .name = "PPK1_11", .addr = A_PPK1_11,
795
+ .ro = 0xffffffff,
796
+ }
110
+};
797
+};
111
+
798
+
112
+static void pvpanic_isa_initfn(Object *obj)
799
+static void zynqmp_efuse_reg_write(void *opaque, hwaddr addr,
113
+{
800
+ uint64_t data, unsigned size)
114
+ PVPanicISAState *s = PVPANIC_ISA_DEVICE(obj);
801
+{
115
+
802
+ RegisterInfoArray *reg_array = opaque;
116
+ pvpanic_setup_io(&s->pvpanic, DEVICE(s), 1);
803
+ XlnxZynqMPEFuse *s;
117
+}
804
+ Object *dev;
118
+
805
+
119
+static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp)
806
+ assert(reg_array != NULL);
120
+{
807
+
121
+ ISADevice *d = ISA_DEVICE(dev);
808
+ dev = reg_array->mem.owner;
122
+ PVPanicISAState *s = PVPANIC_ISA_DEVICE(dev);
809
+ assert(dev);
123
+ PVPanicState *ps = &s->pvpanic;
810
+
124
+ FWCfgState *fw_cfg = fw_cfg_find();
811
+ s = XLNX_ZYNQMP_EFUSE(dev);
125
+ uint16_t *pvpanic_port;
812
+
126
+
813
+ if (addr != A_WR_LOCK && s->regs[R_WR_LOCK]) {
127
+ if (!fw_cfg) {
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) {
128
+ return;
835
+ return;
129
+ }
836
+ }
130
+
837
+
131
+ pvpanic_port = g_malloc(sizeof(*pvpanic_port));
838
+ /* Reset must not trigger some registers' writers */
132
+ *pvpanic_port = cpu_to_le16(s->ioport);
839
+ switch (reg->access->addr) {
133
+ fw_cfg_add_file(fw_cfg, "etc/pvpanic-port", pvpanic_port,
840
+ case A_EFUSE_AES_CRC:
134
+ sizeof(*pvpanic_port));
841
+ *(uint32_t *)reg->data = reg->access->reset;
135
+
842
+ return;
136
+ isa_register_ioport(d, &ps->mr, s->ioport);
843
+ }
137
+}
844
+
138
+
845
+ register_reset(reg);
139
+static Property pvpanic_isa_properties[] = {
846
+}
140
+ DEFINE_PROP_UINT16(PVPANIC_IOPORT_PROP, PVPanicISAState, ioport, 0x505),
847
+
141
+ DEFINE_PROP_UINT8("events", PVPanicISAState, pvpanic.events, PVPANIC_PANICKED | PVPANIC_CRASHLOADED),
848
+static void zynqmp_efuse_reset(DeviceState *dev)
849
+{
850
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(dev);
851
+ unsigned int i;
852
+
853
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
854
+ zynqmp_efuse_register_reset(&s->regs_info[i]);
855
+ }
856
+
857
+ zynqmp_efuse_sync_cache(s, FBIT_UNKNOWN);
858
+ ARRAY_FIELD_DP32(s->regs, STATUS, CACHE_DONE, 1);
859
+ zynqmp_efuse_update_irq(s);
860
+}
861
+
862
+static void zynqmp_efuse_realize(DeviceState *dev, Error **errp)
863
+{
864
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(dev);
865
+
866
+ if (!s->efuse) {
867
+ error_setg(errp, "%s.efuse: link property not connected to XLNX-EFUSE",
868
+ object_get_canonical_path(OBJECT(dev)));
869
+ return;
870
+ }
871
+
872
+ s->efuse->dev = dev;
873
+}
874
+
875
+static void zynqmp_efuse_init(Object *obj)
876
+{
877
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(obj);
878
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
879
+ RegisterInfoArray *reg_array;
880
+
881
+ reg_array =
882
+ register_init_block32(DEVICE(obj), zynqmp_efuse_regs_info,
883
+ ARRAY_SIZE(zynqmp_efuse_regs_info),
884
+ s->regs_info, s->regs,
885
+ &zynqmp_efuse_ops,
886
+ ZYNQMP_EFUSE_ERR_DEBUG,
887
+ R_MAX * 4);
888
+
889
+ sysbus_init_mmio(sbd, &reg_array->mem);
890
+ sysbus_init_irq(sbd, &s->irq);
891
+}
892
+
893
+static const VMStateDescription vmstate_efuse = {
894
+ .name = TYPE_XLNX_ZYNQMP_EFUSE,
895
+ .version_id = 1,
896
+ .minimum_version_id = 1,
897
+ .fields = (VMStateField[]) {
898
+ VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPEFuse, R_MAX),
899
+ VMSTATE_END_OF_LIST(),
900
+ }
901
+};
902
+
903
+static Property zynqmp_efuse_props[] = {
904
+ DEFINE_PROP_LINK("efuse",
905
+ XlnxZynqMPEFuse, efuse,
906
+ TYPE_XLNX_EFUSE, XlnxEFuse *),
907
+
142
+ DEFINE_PROP_END_OF_LIST(),
908
+ DEFINE_PROP_END_OF_LIST(),
143
+};
909
+};
144
+
910
+
145
+static void pvpanic_isa_class_init(ObjectClass *klass, void *data)
911
+static void zynqmp_efuse_class_init(ObjectClass *klass, void *data)
146
+{
912
+{
147
+ DeviceClass *dc = DEVICE_CLASS(klass);
913
+ DeviceClass *dc = DEVICE_CLASS(klass);
148
+
914
+
149
+ dc->realize = pvpanic_isa_realizefn;
915
+ dc->reset = zynqmp_efuse_reset;
150
+ device_class_set_props(dc, pvpanic_isa_properties);
916
+ dc->realize = zynqmp_efuse_realize;
151
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
917
+ dc->vmsd = &vmstate_efuse;
152
+}
918
+ device_class_set_props(dc, zynqmp_efuse_props);
153
+
919
+}
154
+static TypeInfo pvpanic_isa_info = {
920
+
155
+ .name = TYPE_PVPANIC_ISA_DEVICE,
921
+
156
+ .parent = TYPE_ISA_DEVICE,
922
+static const TypeInfo efuse_info = {
157
+ .instance_size = sizeof(PVPanicISAState),
923
+ .name = TYPE_XLNX_ZYNQMP_EFUSE,
158
+ .instance_init = pvpanic_isa_initfn,
924
+ .parent = TYPE_SYS_BUS_DEVICE,
159
+ .class_init = pvpanic_isa_class_init,
925
+ .instance_size = sizeof(XlnxZynqMPEFuse),
926
+ .class_init = zynqmp_efuse_class_init,
927
+ .instance_init = zynqmp_efuse_init,
160
+};
928
+};
161
+
929
+
162
+static void pvpanic_register_types(void)
930
+static void efuse_register_types(void)
163
+{
931
+{
164
+ type_register_static(&pvpanic_isa_info);
932
+ type_register_static(&efuse_info);
165
+}
933
+}
166
+
934
+
167
+type_init(pvpanic_register_types)
935
+type_init(efuse_register_types)
168
diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
936
diff --git a/hw/nvram/Kconfig b/hw/nvram/Kconfig
169
index XXXXXXX..XXXXXXX 100644
937
index XXXXXXX..XXXXXXX 100644
170
--- a/hw/misc/pvpanic.c
938
--- a/hw/nvram/Kconfig
171
+++ b/hw/misc/pvpanic.c
939
+++ b/hw/nvram/Kconfig
172
@@ -XXX,XX +XXX,XX @@
940
@@ -XXX,XX +XXX,XX @@ config XLNX_EFUSE
173
#include "hw/misc/pvpanic.h"
941
config XLNX_EFUSE_VERSAL
174
#include "qom/object.h"
942
bool
175
943
select XLNX_EFUSE
176
-/* The bit of supported pv event, TODO: include uapi header and remove this */
944
+
177
-#define PVPANIC_F_PANICKED 0
945
+config XLNX_EFUSE_ZYNQMP
178
-#define PVPANIC_F_CRASHLOADED 1
946
+ bool
179
-
947
+ select XLNX_EFUSE
180
-/* The pv event value */
948
diff --git a/hw/nvram/meson.build b/hw/nvram/meson.build
181
-#define PVPANIC_PANICKED (1 << PVPANIC_F_PANICKED)
182
-#define PVPANIC_CRASHLOADED (1 << PVPANIC_F_CRASHLOADED)
183
-
184
-typedef struct PVPanicState PVPanicState;
185
-DECLARE_INSTANCE_CHECKER(PVPanicState, ISA_PVPANIC_DEVICE,
186
- TYPE_PVPANIC)
187
-
188
static void handle_event(int event)
189
{
190
static bool logged;
191
@@ -XXX,XX +XXX,XX @@ static void handle_event(int event)
192
}
193
}
194
195
-#include "hw/isa/isa.h"
196
-
197
-struct PVPanicState {
198
- ISADevice parent_obj;
199
-
200
- MemoryRegion io;
201
- uint16_t ioport;
202
- uint8_t events;
203
-};
204
-
205
/* return supported events on read */
206
-static uint64_t pvpanic_ioport_read(void *opaque, hwaddr addr, unsigned size)
207
+static uint64_t pvpanic_read(void *opaque, hwaddr addr, unsigned size)
208
{
209
PVPanicState *pvp = opaque;
210
return pvp->events;
211
}
212
213
-static void pvpanic_ioport_write(void *opaque, hwaddr addr, uint64_t val,
214
+static void pvpanic_write(void *opaque, hwaddr addr, uint64_t val,
215
unsigned size)
216
{
217
handle_event(val);
218
}
219
220
static const MemoryRegionOps pvpanic_ops = {
221
- .read = pvpanic_ioport_read,
222
- .write = pvpanic_ioport_write,
223
+ .read = pvpanic_read,
224
+ .write = pvpanic_write,
225
.impl = {
226
.min_access_size = 1,
227
.max_access_size = 1,
228
},
229
};
230
231
-static void pvpanic_isa_initfn(Object *obj)
232
+void pvpanic_setup_io(PVPanicState *s, DeviceState *dev, unsigned size)
233
{
234
- PVPanicState *s = ISA_PVPANIC_DEVICE(obj);
235
-
236
- memory_region_init_io(&s->io, OBJECT(s), &pvpanic_ops, s, "pvpanic", 1);
237
+ memory_region_init_io(&s->mr, OBJECT(dev), &pvpanic_ops, s, "pvpanic", size);
238
}
239
-
240
-static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp)
241
-{
242
- ISADevice *d = ISA_DEVICE(dev);
243
- PVPanicState *s = ISA_PVPANIC_DEVICE(dev);
244
- FWCfgState *fw_cfg = fw_cfg_find();
245
- uint16_t *pvpanic_port;
246
-
247
- if (!fw_cfg) {
248
- return;
249
- }
250
-
251
- pvpanic_port = g_malloc(sizeof(*pvpanic_port));
252
- *pvpanic_port = cpu_to_le16(s->ioport);
253
- fw_cfg_add_file(fw_cfg, "etc/pvpanic-port", pvpanic_port,
254
- sizeof(*pvpanic_port));
255
-
256
- isa_register_ioport(d, &s->io, s->ioport);
257
-}
258
-
259
-static Property pvpanic_isa_properties[] = {
260
- DEFINE_PROP_UINT16(PVPANIC_IOPORT_PROP, PVPanicState, ioport, 0x505),
261
- DEFINE_PROP_UINT8("events", PVPanicState, events, PVPANIC_PANICKED | PVPANIC_CRASHLOADED),
262
- DEFINE_PROP_END_OF_LIST(),
263
-};
264
-
265
-static void pvpanic_isa_class_init(ObjectClass *klass, void *data)
266
-{
267
- DeviceClass *dc = DEVICE_CLASS(klass);
268
-
269
- dc->realize = pvpanic_isa_realizefn;
270
- device_class_set_props(dc, pvpanic_isa_properties);
271
- set_bit(DEVICE_CATEGORY_MISC, dc->categories);
272
-}
273
-
274
-static TypeInfo pvpanic_isa_info = {
275
- .name = TYPE_PVPANIC,
276
- .parent = TYPE_ISA_DEVICE,
277
- .instance_size = sizeof(PVPanicState),
278
- .instance_init = pvpanic_isa_initfn,
279
- .class_init = pvpanic_isa_class_init,
280
-};
281
-
282
-static void pvpanic_register_types(void)
283
-{
284
- type_register_static(&pvpanic_isa_info);
285
-}
286
-
287
-type_init(pvpanic_register_types)
288
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
289
index XXXXXXX..XXXXXXX 100644
949
index XXXXXXX..XXXXXXX 100644
290
--- a/hw/i386/Kconfig
950
--- a/hw/nvram/meson.build
291
+++ b/hw/i386/Kconfig
951
+++ b/hw/nvram/meson.build
292
@@ -XXX,XX +XXX,XX @@ config PC
952
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE', if_true: files('xlnx-efuse.c'))
293
imply ISA_DEBUG
953
softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE_VERSAL', if_true: files(
294
imply PARALLEL
954
'xlnx-versal-efuse-cache.c',
295
imply PCI_DEVICES
955
'xlnx-versal-efuse-ctrl.c'))
296
- imply PVPANIC
956
+softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE_ZYNQMP', if_true: files(
297
+ imply PVPANIC_ISA
957
+ 'xlnx-zynqmp-efuse.c'))
298
imply QXL
958
299
imply SEV
959
specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_nvram.c'))
300
imply SGA
301
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
302
index XXXXXXX..XXXXXXX 100644
303
--- a/hw/misc/Kconfig
304
+++ b/hw/misc/Kconfig
305
@@ -XXX,XX +XXX,XX @@ config IOTKIT_SYSCTL
306
config IOTKIT_SYSINFO
307
bool
308
309
-config PVPANIC
310
+config PVPANIC_COMMON
311
+ bool
312
+
313
+config PVPANIC_ISA
314
bool
315
depends on ISA_BUS
316
+ select PVPANIC_COMMON
317
318
config AUX
319
bool
320
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
321
index XXXXXXX..XXXXXXX 100644
322
--- a/hw/misc/meson.build
323
+++ b/hw/misc/meson.build
324
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_EMC141X', if_true: files('emc141x.c'))
325
softmmu_ss.add(when: 'CONFIG_UNIMP', if_true: files('unimp.c'))
326
softmmu_ss.add(when: 'CONFIG_EMPTY_SLOT', if_true: files('empty_slot.c'))
327
softmmu_ss.add(when: 'CONFIG_LED', if_true: files('led.c'))
328
+softmmu_ss.add(when: 'CONFIG_PVPANIC_COMMON', if_true: files('pvpanic.c'))
329
330
# ARM devices
331
softmmu_ss.add(when: 'CONFIG_PL310', if_true: files('arm_l2x0.c'))
332
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_IOTKIT_SYSINFO', if_true: files('iotkit-sysinfo.c')
333
softmmu_ss.add(when: 'CONFIG_ARMSSE_CPUID', if_true: files('armsse-cpuid.c'))
334
softmmu_ss.add(when: 'CONFIG_ARMSSE_MHU', if_true: files('armsse-mhu.c'))
335
336
-softmmu_ss.add(when: 'CONFIG_PVPANIC', if_true: files('pvpanic.c'))
337
+softmmu_ss.add(when: 'CONFIG_PVPANIC_ISA', if_true: files('pvpanic-isa.c'))
338
softmmu_ss.add(when: 'CONFIG_AUX', if_true: files('auxbus.c'))
339
softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_scu.c', 'aspeed_sdmc.c', 'aspeed_xdma.c'))
340
softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-sysreg.c'))
341
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
342
index XXXXXXX..XXXXXXX 100644
343
--- a/tests/qtest/meson.build
344
+++ b/tests/qtest/meson.build
345
@@ -XXX,XX +XXX,XX @@ qtests_i386 = \
346
(config_host.has_key('CONFIG_LINUX') and \
347
config_all_devices.has_key('CONFIG_ISA_IPMI_BT') ? ['ipmi-bt-test'] : []) + \
348
(config_all_devices.has_key('CONFIG_WDT_IB700') ? ['wdt_ib700-test'] : []) + \
349
- (config_all_devices.has_key('CONFIG_PVPANIC') ? ['pvpanic-test'] : []) + \
350
+ (config_all_devices.has_key('CONFIG_PVPANIC_ISA') ? ['pvpanic-test'] : []) + \
351
(config_all_devices.has_key('CONFIG_HDA') ? ['intel-hda-test'] : []) + \
352
(config_all_devices.has_key('CONFIG_I82801B11') ? ['i82801b11-test'] : []) + \
353
(config_all_devices.has_key('CONFIG_IOH3420') ? ['ioh3420-test'] : []) + \
354
--
960
--
355
2.20.1
961
2.20.1
356
962
357
963
diff view generated by jsdifflib
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
1
From: Tong Ho <tong.ho@xilinx.com>
2
2
3
Implement gpio-pwr driver to allow reboot and poweroff machine.
3
This device is present in Versal and ZynqMP product
4
This is simple driver with just 2 gpios lines. Current use case
4
families to store a 256-bit encryption key.
5
is to reboot and poweroff virt machine in secure mode. Secure
6
pl066 gpio chip is needed for that.
7
5
8
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
6
Co-authored-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Hao Wu <wuhaotsh@google.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
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
15
---
13
hw/gpio/gpio_pwr.c | 70 +++++++++++++++++++++++++++++++++++++++++++++
16
include/hw/nvram/xlnx-bbram.h | 54 ++++
14
hw/gpio/Kconfig | 3 ++
17
hw/nvram/xlnx-bbram.c | 545 ++++++++++++++++++++++++++++++++++
15
hw/gpio/meson.build | 1 +
18
hw/nvram/Kconfig | 4 +
16
3 files changed, 74 insertions(+)
19
hw/nvram/meson.build | 1 +
17
create mode 100644 hw/gpio/gpio_pwr.c
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
18
23
19
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.c
24
diff --git a/include/hw/nvram/xlnx-bbram.h b/include/hw/nvram/xlnx-bbram.h
20
new file mode 100644
25
new file mode 100644
21
index XXXXXXX..XXXXXXX
26
index XXXXXXX..XXXXXXX
22
--- /dev/null
27
--- /dev/null
23
+++ b/hw/gpio/gpio_pwr.c
28
+++ b/include/hw/nvram/xlnx-bbram.h
24
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@
25
+/*
30
+/*
26
+ * GPIO qemu power controller
31
+ * QEMU model of the Xilinx BBRAM Battery Backed RAM
27
+ *
32
+ *
28
+ * Copyright (c) 2020 Linaro Limited
33
+ * Copyright (c) 2015-2021 Xilinx Inc.
29
+ *
34
+ *
30
+ * Author: Maxim Uvarov <maxim.uvarov@linaro.org>
35
+ * Written by Edgar E. Iglesias <edgari@xilinx.com>
31
+ *
36
+ *
32
+ * Virtual gpio driver which can be used on top of pl061
37
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
33
+ * to reboot and shutdown qemu virtual machine. One of use
38
+ * of this software and associated documentation files (the "Software"), to deal
34
+ * case is gpio driver for secure world application (ARM
39
+ * in the Software without restriction, including without limitation the rights
35
+ * Trusted Firmware.).
40
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36
+ *
41
+ * copies of the Software, and to permit persons to whom the Software is
37
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
42
+ * furnished to do so, subject to the following conditions:
38
+ * See the COPYING file in the top-level directory.
43
+ *
39
+ * SPDX-License-Identifier: GPL-2.0-or-later
44
+ * The above copyright notice and this permission notice shall be included in
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.
40
+ */
54
+ */
41
+
55
+#ifndef XLNX_BBRAM_H
56
+#define XLNX_BBRAM_H
57
+
58
+#include "sysemu/block-backend.h"
59
+#include "hw/qdev-core.h"
60
+#include "hw/irq.h"
61
+#include "hw/sysbus.h"
62
+#include "hw/register.h"
63
+
64
+#define RMAX_XLNX_BBRAM ((0x4c / 4) + 1)
65
+
66
+#define TYPE_XLNX_BBRAM "xlnx,bbram-ctrl"
67
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxBBRam, XLNX_BBRAM);
68
+
69
+struct XlnxBBRam {
70
+ SysBusDevice parent_obj;
71
+ qemu_irq irq_bbram;
72
+
73
+ BlockBackend *blk;
74
+
75
+ uint32_t crc_zpads;
76
+ bool bbram8_wo;
77
+ bool blk_ro;
78
+
79
+ uint32_t regs[RMAX_XLNX_BBRAM];
80
+ RegisterInfo regs_info[RMAX_XLNX_BBRAM];
81
+};
82
+
83
+#endif
84
diff --git a/hw/nvram/xlnx-bbram.c b/hw/nvram/xlnx-bbram.c
85
new file mode 100644
86
index XXXXXXX..XXXXXXX
87
--- /dev/null
88
+++ b/hw/nvram/xlnx-bbram.c
89
@@ -XXX,XX +XXX,XX @@
42
+/*
90
+/*
43
+ * QEMU interface:
91
+ * QEMU model of the Xilinx BBRAM Battery Backed RAM
44
+ * two named input GPIO lines:
92
+ *
45
+ * 'reset' : when asserted, trigger system reset
93
+ * Copyright (c) 2014-2021 Xilinx Inc.
46
+ * 'shutdown' : when asserted, trigger system shutdown
94
+ *
95
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
96
+ * of this software and associated documentation files (the "Software"), to deal
97
+ * in the Software without restriction, including without limitation the rights
98
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
99
+ * copies of the Software, and to permit persons to whom the Software is
100
+ * furnished to do so, subject to the following conditions:
101
+ *
102
+ * The above copyright notice and this permission notice shall be included in
103
+ * all copies or substantial portions of the Software.
104
+ *
105
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
106
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
107
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
108
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
109
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
110
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
111
+ * THE SOFTWARE.
47
+ */
112
+ */
48
+
113
+
49
+#include "qemu/osdep.h"
114
+#include "qemu/osdep.h"
50
+#include "hw/sysbus.h"
115
+#include "hw/nvram/xlnx-bbram.h"
51
+#include "sysemu/runstate.h"
116
+
52
+
117
+#include "qemu/error-report.h"
53
+#define TYPE_GPIOPWR "gpio-pwr"
118
+#include "qemu/log.h"
54
+OBJECT_DECLARE_SIMPLE_TYPE(GPIO_PWR_State, GPIOPWR)
119
+#include "qapi/error.h"
55
+
120
+#include "sysemu/blockdev.h"
56
+struct GPIO_PWR_State {
121
+#include "migration/vmstate.h"
57
+ SysBusDevice parent_obj;
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
+ }
58
+};
506
+};
59
+
507
+
60
+static void gpio_pwr_reset(void *opaque, int n, int level)
508
+static void bbram_ctrl_reset(DeviceState *dev)
61
+{
509
+{
62
+ if (level) {
510
+ XlnxBBRam *s = XLNX_BBRAM(dev);
63
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
511
+ unsigned int i;
64
+ }
512
+
65
+}
513
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
66
+
514
+ if (i < R_BBRAM_0 || i > R_BBRAM_8) {
67
+static void gpio_pwr_shutdown(void *opaque, int n, int level)
515
+ register_reset(&s->regs_info[i]);
68
+{
516
+ }
69
+ if (level) {
517
+ }
70
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
518
+
71
+ }
519
+ bbram_update_irq(s);
72
+}
520
+}
73
+
521
+
74
+static void gpio_pwr_init(Object *obj)
522
+static const MemoryRegionOps bbram_ctrl_ops = {
523
+ .read = register_read_memory,
524
+ .write = register_write_memory,
525
+ .endianness = DEVICE_LITTLE_ENDIAN,
526
+ .valid = {
527
+ .min_access_size = 4,
528
+ .max_access_size = 4,
529
+ },
530
+};
531
+
532
+static void bbram_ctrl_realize(DeviceState *dev, Error **errp)
533
+{
534
+ XlnxBBRam *s = XLNX_BBRAM(dev);
535
+
536
+ if (s->crc_zpads) {
537
+ s->bbram8_wo = true;
538
+ }
539
+
540
+ bbram_bdrv_read(s, errp);
541
+}
542
+
543
+static void bbram_ctrl_init(Object *obj)
544
+{
545
+ XlnxBBRam *s = XLNX_BBRAM(obj);
546
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
547
+ RegisterInfoArray *reg_array;
548
+
549
+ reg_array =
550
+ register_init_block32(DEVICE(obj), bbram_ctrl_regs_info,
551
+ ARRAY_SIZE(bbram_ctrl_regs_info),
552
+ s->regs_info, s->regs,
553
+ &bbram_ctrl_ops,
554
+ XLNX_BBRAM_ERR_DEBUG,
555
+ R_MAX * 4);
556
+
557
+ sysbus_init_mmio(sbd, &reg_array->mem);
558
+ sysbus_init_irq(sbd, &s->irq_bbram);
559
+}
560
+
561
+static void bbram_prop_set_drive(Object *obj, Visitor *v, const char *name,
562
+ void *opaque, Error **errp)
75
+{
563
+{
76
+ DeviceState *dev = DEVICE(obj);
564
+ DeviceState *dev = DEVICE(obj);
77
+
565
+
78
+ qdev_init_gpio_in_named(dev, gpio_pwr_reset, "reset", 1);
566
+ qdev_prop_drive.set(obj, v, name, opaque, errp);
79
+ qdev_init_gpio_in_named(dev, gpio_pwr_shutdown, "shutdown", 1);
567
+
80
+}
568
+ /* Fill initial data if backend is attached after realized */
81
+
569
+ if (dev->realized) {
82
+static const TypeInfo gpio_pwr_info = {
570
+ bbram_bdrv_read(XLNX_BBRAM(obj), errp);
83
+ .name = TYPE_GPIOPWR,
571
+ }
572
+}
573
+
574
+static void bbram_prop_get_drive(Object *obj, Visitor *v, const char *name,
575
+ void *opaque, Error **errp)
576
+{
577
+ qdev_prop_drive.get(obj, v, name, opaque, errp);
578
+}
579
+
580
+static void bbram_prop_release_drive(Object *obj, const char *name,
581
+ void *opaque)
582
+{
583
+ qdev_prop_drive.release(obj, name, opaque);
584
+}
585
+
586
+static const PropertyInfo bbram_prop_drive = {
587
+ .name = "str",
588
+ .description = "Node name or ID of a block device to use as BBRAM backend",
589
+ .realized_set_allowed = true,
590
+ .get = bbram_prop_get_drive,
591
+ .set = bbram_prop_set_drive,
592
+ .release = bbram_prop_release_drive,
593
+};
594
+
595
+static const VMStateDescription vmstate_bbram_ctrl = {
596
+ .name = TYPE_XLNX_BBRAM,
597
+ .version_id = 1,
598
+ .minimum_version_id = 1,
599
+ .fields = (VMStateField[]) {
600
+ VMSTATE_UINT32_ARRAY(regs, XlnxBBRam, R_MAX),
601
+ VMSTATE_END_OF_LIST(),
602
+ }
603
+};
604
+
605
+static Property bbram_ctrl_props[] = {
606
+ DEFINE_PROP("drive", XlnxBBRam, blk, bbram_prop_drive, BlockBackend *),
607
+ DEFINE_PROP_UINT32("crc-zpads", XlnxBBRam, crc_zpads, 1),
608
+ DEFINE_PROP_END_OF_LIST(),
609
+};
610
+
611
+static void bbram_ctrl_class_init(ObjectClass *klass, void *data)
612
+{
613
+ DeviceClass *dc = DEVICE_CLASS(klass);
614
+
615
+ dc->reset = bbram_ctrl_reset;
616
+ dc->realize = bbram_ctrl_realize;
617
+ dc->vmsd = &vmstate_bbram_ctrl;
618
+ device_class_set_props(dc, bbram_ctrl_props);
619
+}
620
+
621
+static const TypeInfo bbram_ctrl_info = {
622
+ .name = TYPE_XLNX_BBRAM,
84
+ .parent = TYPE_SYS_BUS_DEVICE,
623
+ .parent = TYPE_SYS_BUS_DEVICE,
85
+ .instance_size = sizeof(GPIO_PWR_State),
624
+ .instance_size = sizeof(XlnxBBRam),
86
+ .instance_init = gpio_pwr_init,
625
+ .class_init = bbram_ctrl_class_init,
626
+ .instance_init = bbram_ctrl_init,
87
+};
627
+};
88
+
628
+
89
+static void gpio_pwr_register_types(void)
629
+static void bbram_ctrl_register_types(void)
90
+{
630
+{
91
+ type_register_static(&gpio_pwr_info);
631
+ type_register_static(&bbram_ctrl_info);
92
+}
632
+}
93
+
633
+
94
+type_init(gpio_pwr_register_types)
634
+type_init(bbram_ctrl_register_types)
95
diff --git a/hw/gpio/Kconfig b/hw/gpio/Kconfig
635
diff --git a/hw/nvram/Kconfig b/hw/nvram/Kconfig
96
index XXXXXXX..XXXXXXX 100644
636
index XXXXXXX..XXXXXXX 100644
97
--- a/hw/gpio/Kconfig
637
--- a/hw/nvram/Kconfig
98
+++ b/hw/gpio/Kconfig
638
+++ b/hw/nvram/Kconfig
99
@@ -XXX,XX +XXX,XX @@ config PL061
639
@@ -XXX,XX +XXX,XX @@ config XLNX_EFUSE_VERSAL
100
config GPIO_KEY
640
config XLNX_EFUSE_ZYNQMP
101
bool
641
bool
102
642
select XLNX_EFUSE
103
+config GPIO_PWR
643
+
644
+config XLNX_BBRAM
104
+ bool
645
+ bool
105
+
646
+ select XLNX_EFUSE_CRC
106
config SIFIVE_GPIO
647
diff --git a/hw/nvram/meson.build b/hw/nvram/meson.build
107
bool
108
diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
109
index XXXXXXX..XXXXXXX 100644
648
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/gpio/meson.build
649
--- a/hw/nvram/meson.build
111
+++ b/hw/gpio/meson.build
650
+++ b/hw/nvram/meson.build
112
@@ -XXX,XX +XXX,XX @@
651
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE_VERSAL', if_true: files(
113
softmmu_ss.add(when: 'CONFIG_E500', if_true: files('mpc8xxx.c'))
652
'xlnx-versal-efuse-ctrl.c'))
114
softmmu_ss.add(when: 'CONFIG_GPIO_KEY', if_true: files('gpio_key.c'))
653
softmmu_ss.add(when: 'CONFIG_XLNX_EFUSE_ZYNQMP', if_true: files(
115
+softmmu_ss.add(when: 'CONFIG_GPIO_PWR', if_true: files('gpio_pwr.c'))
654
'xlnx-zynqmp-efuse.c'))
116
softmmu_ss.add(when: 'CONFIG_MAX7310', if_true: files('max7310.c'))
655
+softmmu_ss.add(when: 'CONFIG_XLNX_BBRAM', if_true: files('xlnx-bbram.c'))
117
softmmu_ss.add(when: 'CONFIG_PL061', if_true: files('pl061.c'))
656
118
softmmu_ss.add(when: 'CONFIG_PUV3', if_true: files('puv3_gpio.c'))
657
specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_nvram.c'))
119
--
658
--
120
2.20.1
659
2.20.1
121
660
122
661
diff view generated by jsdifflib
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
1
From: Tong Ho <tong.ho@xilinx.com>
2
2
3
Add secure pl061 for reset/power down machine from
3
Connect the support for Versal Battery-Backed RAM (BBRAM)
4
the secure world (Arm Trusted Firmware). Connect it
5
with gpio-pwr driver.
6
4
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
5
The command argument:
8
Reviewed-by: Andrew Jones <drjones@redhat.com>
6
-drive if=pflash,index=0,...
9
[PMM: Added mention of the new device to the documentation]
7
Can be used to optionally connect the bbram to a backend
8
storage, such that field-programmed values in one
9
invocation can be made available to next invocation.
10
11
The backend storage must be a seekable binary file, and
12
its size must be 36 bytes or larger. A file with all
13
binary 0's is a 'blank'.
14
15
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
16
Message-id: 20210917052400.1249094-6-tong.ho@xilinx.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
19
---
12
docs/system/arm/virt.rst | 2 ++
20
include/hw/arm/xlnx-versal.h | 5 +++++
13
include/hw/arm/virt.h | 2 ++
21
hw/arm/xlnx-versal-virt.c | 36 ++++++++++++++++++++++++++++++++++++
14
hw/arm/virt.c | 56 +++++++++++++++++++++++++++++++++++++++-
22
hw/arm/xlnx-versal.c | 18 ++++++++++++++++++
15
hw/arm/Kconfig | 1 +
23
hw/arm/Kconfig | 1 +
16
4 files changed, 60 insertions(+), 1 deletion(-)
24
4 files changed, 60 insertions(+)
17
25
18
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
26
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
19
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
20
--- a/docs/system/arm/virt.rst
28
--- a/include/hw/arm/xlnx-versal.h
21
+++ b/docs/system/arm/virt.rst
29
+++ b/include/hw/arm/xlnx-versal.h
22
@@ -XXX,XX +XXX,XX @@ The virt board supports:
30
@@ -XXX,XX +XXX,XX @@
23
- Secure-World-only devices if the CPU has TrustZone:
31
#include "qom/object.h"
24
32
#include "hw/usb/xlnx-usb-subsystem.h"
25
- A second PL011 UART
33
#include "hw/misc/xlnx-versal-xramc.h"
26
+ - A second PL061 GPIO controller, with GPIO lines for triggering
34
+#include "hw/nvram/xlnx-bbram.h"
27
+ a system reset or system poweroff
35
28
- A secure flash memory
36
#define TYPE_XLNX_VERSAL "xlnx-versal"
29
- 16MB of secure RAM
37
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
30
38
@@ -XXX,XX +XXX,XX @@ struct Versal {
31
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
39
} iou;
40
41
XlnxZynqMPRTC rtc;
42
+ XlnxBBRam bbram;
43
} pmc;
44
45
struct {
46
@@ -XXX,XX +XXX,XX @@ struct Versal {
47
#define VERSAL_GEM1_WAKE_IRQ_0 59
48
#define VERSAL_ADMA_IRQ_0 60
49
#define VERSAL_XRAM_IRQ_0 79
50
+#define VERSAL_BBRAM_APB_IRQ_0 121
51
#define VERSAL_RTC_APB_ERR_IRQ 121
52
#define VERSAL_SD0_IRQ_0 126
53
#define VERSAL_RTC_ALARM_IRQ 142
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
32
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
33
--- a/include/hw/arm/virt.h
65
--- a/hw/arm/xlnx-versal-virt.c
34
+++ b/include/hw/arm/virt.h
66
+++ b/hw/arm/xlnx-versal-virt.c
35
@@ -XXX,XX +XXX,XX @@ enum {
67
@@ -XXX,XX +XXX,XX @@ static void fdt_add_rtc_node(VersalVirt *s)
36
VIRT_GPIO,
68
g_free(name);
37
VIRT_SECURE_UART,
38
VIRT_SECURE_MEM,
39
+ VIRT_SECURE_GPIO,
40
VIRT_PCDIMM_ACPI,
41
VIRT_ACPI_GED,
42
VIRT_NVDIMM_ACPI,
43
@@ -XXX,XX +XXX,XX @@ struct VirtMachineClass {
44
bool kvm_no_adjvtime;
45
bool no_kvm_steal_time;
46
bool acpi_expose_flash;
47
+ bool no_secure_gpio;
48
};
49
50
struct VirtMachineState {
51
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/arm/virt.c
54
+++ b/hw/arm/virt.c
55
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry base_memmap[] = {
56
[VIRT_ACPI_GED] = { 0x09080000, ACPI_GED_EVT_SEL_LEN },
57
[VIRT_NVDIMM_ACPI] = { 0x09090000, NVDIMM_ACPI_IO_LEN},
58
[VIRT_PVTIME] = { 0x090a0000, 0x00010000 },
59
+ [VIRT_SECURE_GPIO] = { 0x090b0000, 0x00001000 },
60
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
61
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
62
[VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
63
@@ -XXX,XX +XXX,XX @@ static void create_gpio_keys(const VirtMachineState *vms,
64
"gpios", phandle, 3, 0);
65
}
69
}
66
70
67
+#define SECURE_GPIO_POWEROFF 0
71
+static void fdt_add_bbram_node(VersalVirt *s)
68
+#define SECURE_GPIO_RESET 1
72
+{
73
+ const char compat[] = TYPE_XLNX_BBRAM;
74
+ const char interrupt_names[] = "bbram-error";
75
+ char *name = g_strdup_printf("/bbram@%x", MM_PMC_BBRAM_CTRL);
69
+
76
+
70
+static void create_secure_gpio_pwr(const VirtMachineState *vms,
77
+ qemu_fdt_add_subnode(s->fdt, name);
71
+ DeviceState *pl061_dev,
72
+ uint32_t phandle)
73
+{
74
+ DeviceState *gpio_pwr_dev;
75
+
78
+
76
+ /* gpio-pwr */
79
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
77
+ gpio_pwr_dev = sysbus_create_simple("gpio-pwr", -1, NULL);
80
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_BBRAM_APB_IRQ_0,
78
+
81
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
79
+ /* connect secure pl061 to gpio-pwr */
82
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
80
+ qdev_connect_gpio_out(pl061_dev, SECURE_GPIO_RESET,
83
+ interrupt_names, sizeof(interrupt_names));
81
+ qdev_get_gpio_in_named(gpio_pwr_dev, "reset", 0));
84
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
82
+ qdev_connect_gpio_out(pl061_dev, SECURE_GPIO_POWEROFF,
85
+ 2, MM_PMC_BBRAM_CTRL,
83
+ qdev_get_gpio_in_named(gpio_pwr_dev, "shutdown", 0));
86
+ 2, MM_PMC_BBRAM_CTRL_SIZE);
84
+
87
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
85
+ qemu_fdt_add_subnode(vms->fdt, "/gpio-poweroff");
88
+ g_free(name);
86
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-poweroff", "compatible",
87
+ "gpio-poweroff");
88
+ qemu_fdt_setprop_cells(vms->fdt, "/gpio-poweroff",
89
+ "gpios", phandle, SECURE_GPIO_POWEROFF, 0);
90
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-poweroff", "status", "disabled");
91
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-poweroff", "secure-status",
92
+ "okay");
93
+
94
+ qemu_fdt_add_subnode(vms->fdt, "/gpio-restart");
95
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-restart", "compatible",
96
+ "gpio-restart");
97
+ qemu_fdt_setprop_cells(vms->fdt, "/gpio-restart",
98
+ "gpios", phandle, SECURE_GPIO_RESET, 0);
99
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-restart", "status", "disabled");
100
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-restart", "secure-status",
101
+ "okay");
102
+}
89
+}
103
+
90
+
104
static void create_gpio_devices(const VirtMachineState *vms, int gpio,
91
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
105
MemoryRegion *mem)
106
{
92
{
107
@@ -XXX,XX +XXX,XX @@ static void create_gpio_devices(const VirtMachineState *vms, int gpio,
93
Error *err = NULL;
108
qemu_fdt_setprop_string(vms->fdt, nodename, "clock-names", "apb_pclk");
94
@@ -XXX,XX +XXX,XX @@ static void create_virtio_regions(VersalVirt *s)
109
qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", phandle);
95
}
110
96
}
111
+ if (gpio != VIRT_GPIO) {
97
112
+ /* Mark as not usable by the normal world */
98
+static void bbram_attach_drive(XlnxBBRam *dev)
113
+ qemu_fdt_setprop_string(vms->fdt, nodename, "status", "disabled");
99
+{
114
+ qemu_fdt_setprop_string(vms->fdt, nodename, "secure-status", "okay");
100
+ DriveInfo *dinfo;
101
+ BlockBackend *blk;
102
+
103
+ dinfo = drive_get_by_index(IF_PFLASH, 0);
104
+ blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
105
+ if (blk) {
106
+ qdev_prop_set_drive(DEVICE(dev), "drive", blk);
115
+ }
107
+ }
116
g_free(nodename);
108
+}
117
109
+
118
/* Child gpio devices */
110
static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
119
- create_gpio_keys(vms, pl061_dev, phandle);
111
{
120
+ if (gpio == VIRT_GPIO) {
112
BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
121
+ create_gpio_keys(vms, pl061_dev, phandle);
113
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
122
+ } else {
114
fdt_add_usb_xhci_nodes(s);
123
+ create_secure_gpio_pwr(vms, pl061_dev, phandle);
115
fdt_add_sd_nodes(s);
124
+ }
116
fdt_add_rtc_node(s);
117
+ fdt_add_bbram_node(s);
118
fdt_add_cpu_nodes(s, psci_conduit);
119
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
120
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
121
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
122
memory_region_add_subregion_overlap(get_system_memory(),
123
0, &s->soc.fpd.apu.mr, 0);
124
125
+ /* Attach bbram backend, if given */
126
+ bbram_attach_drive(&s->soc.pmc.bbram);
127
+
128
/* Plugin SD cards. */
129
for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
130
sd_plugin_card(&s->soc.pmc.iou.sd[i], drive_get_next(IF_SD));
131
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/hw/arm/xlnx-versal.c
134
+++ b/hw/arm/xlnx-versal.c
135
@@ -XXX,XX +XXX,XX @@ static void versal_create_xrams(Versal *s, qemu_irq *pic)
136
}
125
}
137
}
126
138
127
static void create_virtio_devices(const VirtMachineState *vms)
139
+static void versal_create_bbram(Versal *s, qemu_irq *pic)
128
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
140
+{
129
create_gpio_devices(vms, VIRT_GPIO, sysmem);
141
+ SysBusDevice *sbd;
130
}
131
132
+ if (vms->secure && !vmc->no_secure_gpio) {
133
+ create_gpio_devices(vms, VIRT_SECURE_GPIO, secure_sysmem);
134
+ }
135
+
142
+
136
/* connect powerdown request */
143
+ object_initialize_child_with_props(OBJECT(s), "bbram", &s->pmc.bbram,
137
vms->powerdown_notifier.notify = virt_powerdown_req;
144
+ sizeof(s->pmc.bbram), TYPE_XLNX_BBRAM,
138
qemu_register_powerdown_notifier(&vms->powerdown_notifier);
145
+ &error_fatal,
139
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(6, 0)
146
+ "crc-zpads", "0",
140
147
+ NULL);
141
static void virt_machine_5_2_options(MachineClass *mc)
148
+ sbd = SYS_BUS_DEVICE(&s->pmc.bbram);
142
{
143
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
144
+
149
+
145
virt_machine_6_0_options(mc);
150
+ sysbus_realize(sbd, &error_fatal);
146
compat_props_add(mc->compat_props, hw_compat_5_2, hw_compat_5_2_len);
151
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_BBRAM_CTRL,
147
+ vmc->no_secure_gpio = true;
152
+ sysbus_mmio_get_region(sbd, 0));
148
}
153
+ sysbus_connect_irq(sbd, 0, pic[VERSAL_BBRAM_APB_IRQ_0]);
149
DEFINE_VIRT_MACHINE(5, 2)
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);
150
166
151
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
167
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
152
index XXXXXXX..XXXXXXX 100644
168
index XXXXXXX..XXXXXXX 100644
153
--- a/hw/arm/Kconfig
169
--- a/hw/arm/Kconfig
154
+++ b/hw/arm/Kconfig
170
+++ b/hw/arm/Kconfig
155
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
171
@@ -XXX,XX +XXX,XX @@ config XLNX_VERSAL
156
select PL011 # UART
172
select XLNX_ZDMA
157
select PL031 # RTC
173
select XLNX_ZYNQMP
158
select PL061 # GPIO
174
select OR_IRQ
159
+ select GPIO_PWR
175
+ select XLNX_BBRAM
160
select PLATFORM_BUS
176
161
select SMBIOS
177
config NPCM7XX
162
select VIRTIO_MMIO
178
bool
163
--
179
--
164
2.20.1
180
2.20.1
165
181
166
182
diff view generated by jsdifflib
1
The ptimer API currently provides two methods for setting the period:
1
From: Tong Ho <tong.ho@xilinx.com>
2
ptimer_set_period(), which takes a period in nanoseconds, and
2
3
ptimer_set_freq(), which takes a frequency in Hz. Neither of these
3
Connect the support for Versal eFUSE one-time field-programmable
4
lines up nicely with the Clock API, because although both the Clock
4
bit array.
5
and the ptimer track the frequency using a representation of whole
5
6
and fractional nanoseconds, conversion via either period-in-ns or
6
The command argument:
7
frequency-in-Hz will introduce a rounding error.
7
-drive if=pflash,index=1,...
8
8
Can be used to optionally connect the bit array to a
9
Add a new function ptimer_set_period_from_clock() which takes the
9
backend storage, such that field-programmed values
10
Clock object directly to avoid the rounding issues. This includes a
10
in one invocation can be made available to next
11
facility for the user to specify that there is a frequency divider
11
invocation.
12
between the Clock proper and the timer, as some timer devices like
12
13
the CMSDK APB dualtimer need this.
13
The backend storage must be a seekable binary file, and
14
14
its size must be 3072 bytes or larger. A file with all
15
To avoid having to drag in clock.h from ptimer.h we add the Clock
15
binary 0's is a 'blank'.
16
type to typedefs.h.
16
17
17
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
18
Message-id: 20210917052400.1249094-7-tong.ho@xilinx.com
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Luc Michel <luc@lmichel.fr>
20
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Message-id: 20210128114145.20536-2-peter.maydell@linaro.org
23
Message-id: 20210121190622.22000-2-peter.maydell@linaro.org
24
---
21
---
25
include/hw/ptimer.h | 22 ++++++++++++++++++++++
22
include/hw/arm/xlnx-versal.h | 10 +++++++
26
include/qemu/typedefs.h | 1 +
23
hw/arm/xlnx-versal-virt.c | 52 ++++++++++++++++++++++++++++++++++++
27
hw/core/ptimer.c | 34 ++++++++++++++++++++++++++++++++++
24
hw/arm/xlnx-versal.c | 39 +++++++++++++++++++++++++++
28
3 files changed, 57 insertions(+)
25
hw/arm/Kconfig | 1 +
29
26
4 files changed, 102 insertions(+)
30
diff --git a/include/hw/ptimer.h b/include/hw/ptimer.h
27
31
index XXXXXXX..XXXXXXX 100644
28
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
32
--- a/include/hw/ptimer.h
29
index XXXXXXX..XXXXXXX 100644
33
+++ b/include/hw/ptimer.h
30
--- a/include/hw/arm/xlnx-versal.h
34
@@ -XXX,XX +XXX,XX @@ void ptimer_transaction_commit(ptimer_state *s);
31
+++ b/include/hw/arm/xlnx-versal.h
35
*/
36
void ptimer_set_period(ptimer_state *s, int64_t period);
37
38
+/**
39
+ * ptimer_set_period_from_clock - Set counter increment from a Clock
40
+ * @s: ptimer to configure
41
+ * @clk: pointer to Clock object to take period from
42
+ * @divisor: value to scale the clock frequency down by
43
+ *
44
+ * If the ptimer is being driven from a Clock, this is the preferred
45
+ * way to tell the ptimer about the period, because it avoids any
46
+ * possible rounding errors that might happen if the internal
47
+ * representation of the Clock period was converted to either a period
48
+ * in ns or a frequency in Hz.
49
+ *
50
+ * If the ptimer should run at the same frequency as the clock,
51
+ * pass 1 as the @divisor; if the ptimer should run at half the
52
+ * frequency, pass 2, and so on.
53
+ *
54
+ * This function will assert if it is called outside a
55
+ * ptimer_transaction_begin/commit block.
56
+ */
57
+void ptimer_set_period_from_clock(ptimer_state *s, const Clock *clock,
58
+ unsigned int divisor);
59
+
60
/**
61
* ptimer_set_freq - Set counter frequency in Hz
62
* @s: ptimer to configure
63
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
64
index XXXXXXX..XXXXXXX 100644
65
--- a/include/qemu/typedefs.h
66
+++ b/include/qemu/typedefs.h
67
@@ -XXX,XX +XXX,XX @@ typedef struct BlockDriverState BlockDriverState;
68
typedef struct BusClass BusClass;
69
typedef struct BusState BusState;
70
typedef struct Chardev Chardev;
71
+typedef struct Clock Clock;
72
typedef struct CompatProperty CompatProperty;
73
typedef struct CoMutex CoMutex;
74
typedef struct CPUAddressSpace CPUAddressSpace;
75
diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/core/ptimer.c
78
+++ b/hw/core/ptimer.c
79
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@
80
#include "sysemu/qtest.h"
33
#include "hw/usb/xlnx-usb-subsystem.h"
81
#include "block/aio.h"
34
#include "hw/misc/xlnx-versal-xramc.h"
82
#include "sysemu/cpus.h"
35
#include "hw/nvram/xlnx-bbram.h"
83
+#include "hw/clock.h"
36
+#include "hw/nvram/xlnx-versal-efuse.h"
84
37
85
#define DELTA_ADJUST 1
38
#define TYPE_XLNX_VERSAL "xlnx-versal"
86
#define DELTA_NO_ADJUST -1
39
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
87
@@ -XXX,XX +XXX,XX @@ void ptimer_set_period(ptimer_state *s, int64_t period)
40
@@ -XXX,XX +XXX,XX @@ struct Versal {
41
42
XlnxZynqMPRTC rtc;
43
XlnxBBRam bbram;
44
+ XlnxEFuse efuse;
45
+ XlnxVersalEFuseCtrl efuse_ctrl;
46
+ XlnxVersalEFuseCache efuse_cache;
47
} pmc;
48
49
struct {
50
@@ -XXX,XX +XXX,XX @@ struct Versal {
51
#define VERSAL_BBRAM_APB_IRQ_0 121
52
#define VERSAL_RTC_APB_ERR_IRQ 121
53
#define VERSAL_SD0_IRQ_0 126
54
+#define VERSAL_EFUSE_IRQ 139
55
#define VERSAL_RTC_ALARM_IRQ 142
56
#define VERSAL_RTC_SECONDS_IRQ 143
57
58
@@ -XXX,XX +XXX,XX @@ struct Versal {
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);
76
}
77
78
+static void fdt_add_efuse_ctrl_node(VersalVirt *s)
79
+{
80
+ const char compat[] = TYPE_XLNX_VERSAL_EFUSE_CTRL;
81
+ const char interrupt_names[] = "pmc_efuse";
82
+ char *name = g_strdup_printf("/pmc_efuse@%x", MM_PMC_EFUSE_CTRL);
83
+
84
+ qemu_fdt_add_subnode(s->fdt, name);
85
+
86
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
87
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_EFUSE_IRQ,
88
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
89
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
90
+ interrupt_names, sizeof(interrupt_names));
91
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
92
+ 2, MM_PMC_EFUSE_CTRL,
93
+ 2, MM_PMC_EFUSE_CTRL_SIZE);
94
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
95
+ g_free(name);
96
+}
97
+
98
+static void fdt_add_efuse_cache_node(VersalVirt *s)
99
+{
100
+ const char compat[] = TYPE_XLNX_VERSAL_EFUSE_CACHE;
101
+ char *name = g_strdup_printf("/xlnx_pmc_efuse_cache@%x",
102
+ MM_PMC_EFUSE_CACHE);
103
+
104
+ qemu_fdt_add_subnode(s->fdt, name);
105
+
106
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
107
+ 2, MM_PMC_EFUSE_CACHE,
108
+ 2, MM_PMC_EFUSE_CACHE_SIZE);
109
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
110
+ g_free(name);
111
+}
112
+
113
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
114
{
115
Error *err = NULL;
116
@@ -XXX,XX +XXX,XX @@ static void bbram_attach_drive(XlnxBBRam *dev)
88
}
117
}
89
}
118
}
90
119
91
+/* Set counter increment interval from a Clock */
120
+static void efuse_attach_drive(XlnxEFuse *dev)
92
+void ptimer_set_period_from_clock(ptimer_state *s, const Clock *clk,
121
+{
93
+ unsigned int divisor)
122
+ DriveInfo *dinfo;
94
+{
123
+ BlockBackend *blk;
95
+ /*
124
+
96
+ * The raw clock period is a 64-bit value in units of 2^-32 ns;
125
+ dinfo = drive_get_by_index(IF_PFLASH, 1);
97
+ * put another way it's a 32.32 fixed-point ns value. Our internal
126
+ blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
98
+ * representation of the period is 64.32 fixed point ns, so
127
+ if (blk) {
99
+ * the conversion is simple.
128
+ qdev_prop_set_drive(DEVICE(dev), "drive", blk);
100
+ */
101
+ uint64_t raw_period = clock_get(clk);
102
+ uint64_t period_frac;
103
+
104
+ assert(s->in_transaction);
105
+ s->delta = ptimer_get_count(s);
106
+ s->period = extract64(raw_period, 32, 32);
107
+ period_frac = extract64(raw_period, 0, 32);
108
+ /*
109
+ * divisor specifies a possible frequency divisor between the
110
+ * clock and the timer, so it is a multiplier on the period.
111
+ * We do the multiply after splitting the raw period out into
112
+ * period and frac to avoid having to do a 32*64->96 multiply.
113
+ */
114
+ s->period *= divisor;
115
+ period_frac *= divisor;
116
+ s->period += extract64(period_frac, 32, 32);
117
+ s->period_frac = (uint32_t)period_frac;
118
+
119
+ if (s->enabled) {
120
+ s->need_reload = true;
121
+ }
129
+ }
122
+}
130
+}
123
+
131
+
124
/* Set counter frequency in Hz. */
132
static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
125
void ptimer_set_freq(ptimer_state *s, uint32_t freq)
126
{
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
127
--
223
--
128
2.20.1
224
2.20.1
129
225
130
226
diff view generated by jsdifflib
1
Switch the CMSDK APB dualtimer device over to using its Clock input;
1
From: Tong Ho <tong.ho@xilinx.com>
2
the pclk-frq property is now ignored.
3
2
3
Connect the support for Xilinx ZynqMP Battery-Backed RAM (BBRAM)
4
5
The command argument:
6
-drive if=pflash,index=2,...
7
Can be used to optionally connect the bbram to a backend
8
storage, such that field-programmed values in one
9
invocation can be made available to next invocation.
10
11
The backend storage must be a seekable binary file, and
12
its size must be 36 bytes or larger. A file with all
13
binary 0's is a 'blank'.
14
15
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
16
Message-id: 20210917052400.1249094-8-tong.ho@xilinx.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210128114145.20536-20-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-20-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
---
19
---
12
hw/timer/cmsdk-apb-dualtimer.c | 42 ++++++++++++++++++++++++++++++----
20
include/hw/arm/xlnx-zynqmp.h | 2 ++
13
1 file changed, 37 insertions(+), 5 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(+)
14
25
15
diff --git a/hw/timer/cmsdk-apb-dualtimer.c b/hw/timer/cmsdk-apb-dualtimer.c
26
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
16
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/timer/cmsdk-apb-dualtimer.c
28
--- a/include/hw/arm/xlnx-zynqmp.h
18
+++ b/hw/timer/cmsdk-apb-dualtimer.c
29
+++ b/include/hw/arm/xlnx-zynqmp.h
19
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_update(CMSDKAPBDualTimer *s)
30
@@ -XXX,XX +XXX,XX @@
20
qemu_set_irq(s->timerintc, timintc);
31
#include "qom/object.h"
32
#include "net/can_emu.h"
33
#include "hw/dma/xlnx_csu_dma.h"
34
+#include "hw/nvram/xlnx-bbram.h"
35
36
#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
37
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
38
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
39
40
MemoryRegion *ddr_ram;
41
MemoryRegion ddr_ram_low, ddr_ram_high;
42
+ XlnxBBRam bbram;
43
44
MemoryRegion mr_unimp[XLNX_ZYNQMP_NUM_UNIMP_AREAS];
45
46
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/xlnx-zcu102.c
49
+++ b/hw/arm/xlnx-zcu102.c
50
@@ -XXX,XX +XXX,XX @@ static void zcu102_modify_dtb(const struct arm_boot_info *binfo, void *fdt)
51
}
21
}
52
}
22
53
23
+static int cmsdk_dualtimermod_divisor(CMSDKAPBDualTimerModule *m)
54
+static void bbram_attach_drive(XlnxBBRam *dev)
24
+{
55
+{
25
+ /* Return the divisor set by the current CONTROL.PRESCALE value */
56
+ DriveInfo *dinfo;
26
+ switch (FIELD_EX32(m->control, CONTROL, PRESCALE)) {
57
+ BlockBackend *blk;
27
+ case 0:
58
+
28
+ return 1;
59
+ dinfo = drive_get_by_index(IF_PFLASH, 2);
29
+ case 1:
60
+ blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
30
+ return 16;
61
+ if (blk) {
31
+ case 2:
62
+ qdev_prop_set_drive(DEVICE(dev), "drive", blk);
32
+ case 3: /* UNDEFINED, we treat like 2 (and complained when it was set) */
33
+ return 256;
34
+ default:
35
+ g_assert_not_reached();
36
+ }
63
+ }
37
+}
64
+}
38
+
65
+
39
static void cmsdk_dualtimermod_write_control(CMSDKAPBDualTimerModule *m,
66
static void xlnx_zcu102_init(MachineState *machine)
40
uint32_t newctrl)
41
{
67
{
42
@@ -XXX,XX +XXX,XX @@ static void cmsdk_dualtimermod_write_control(CMSDKAPBDualTimerModule *m,
68
XlnxZCU102 *s = ZCU102_MACHINE(machine);
43
default:
69
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_init(MachineState *machine)
44
g_assert_not_reached();
70
45
}
71
qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
46
- ptimer_set_freq(m->timer, m->parent->pclk_frq / divisor);
72
47
+ ptimer_set_period_from_clock(m->timer, m->parent->timclk, divisor);
73
+ /* Attach bbram backend, if given */
48
}
74
+ bbram_attach_drive(&s->soc.bbram);
49
75
+
50
if (changed & R_CONTROL_MODE_MASK) {
76
/* Create and plug in the SD cards */
51
@@ -XXX,XX +XXX,XX @@ static void cmsdk_dualtimermod_reset(CMSDKAPBDualTimerModule *m)
77
for (i = 0; i < XLNX_ZYNQMP_NUM_SDHCI; i++) {
52
* limit must both be set to 0xffff, so we wrap at 16 bits.
78
BusState *bus;
53
*/
79
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
54
ptimer_set_limit(m->timer, 0xffff, 1);
80
index XXXXXXX..XXXXXXX 100644
55
- ptimer_set_freq(m->timer, m->parent->pclk_frq);
81
--- a/hw/arm/xlnx-zynqmp.c
56
+ ptimer_set_period_from_clock(m->timer, m->parent->timclk,
82
+++ b/hw/arm/xlnx-zynqmp.c
57
+ cmsdk_dualtimermod_divisor(m));
83
@@ -XXX,XX +XXX,XX @@
58
ptimer_transaction_commit(m->timer);
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);
59
}
95
}
60
96
61
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_reset(DeviceState *dev)
97
+static void xlnx_zynqmp_create_bbram(XlnxZynqMPState *s, qemu_irq *gic)
62
s->timeritop = 0;
63
}
64
65
+static void cmsdk_apb_dualtimer_clk_update(void *opaque)
66
+{
98
+{
67
+ CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(opaque);
99
+ SysBusDevice *sbd;
68
+ int i;
69
+
100
+
70
+ for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
101
+ object_initialize_child_with_props(OBJECT(s), "bbram", &s->bbram,
71
+ CMSDKAPBDualTimerModule *m = &s->timermod[i];
102
+ sizeof(s->bbram), TYPE_XLNX_BBRAM,
72
+ ptimer_transaction_begin(m->timer);
103
+ &error_fatal,
73
+ ptimer_set_period_from_clock(m->timer, m->parent->timclk,
104
+ "crc-zpads", "1",
74
+ cmsdk_dualtimermod_divisor(m));
105
+ NULL);
75
+ ptimer_transaction_commit(m->timer);
106
+ sbd = SYS_BUS_DEVICE(&s->bbram);
76
+ }
107
+
108
+ sysbus_realize(sbd, &error_fatal);
109
+ sysbus_mmio_map(sbd, 0, BBRAM_ADDR);
110
+ sysbus_connect_irq(sbd, 0, gic[BBRAM_IRQ]);
77
+}
111
+}
78
+
112
+
79
static void cmsdk_apb_dualtimer_init(Object *obj)
113
static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
80
{
114
{
81
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
115
static const struct UnimpInfo {
82
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_init(Object *obj)
116
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
83
for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
117
sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, RTC_ADDR);
84
sysbus_init_irq(sbd, &s->timermod[i].timerint);
118
sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, gic_spi[RTC_IRQ]);
85
}
119
86
- s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK", NULL, NULL);
120
+ xlnx_zynqmp_create_bbram(s, gic_spi);
87
+ s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK",
121
xlnx_zynqmp_create_unimp_mmio(s);
88
+ cmsdk_apb_dualtimer_clk_update, s);
122
89
}
123
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
90
124
diff --git a/hw/Kconfig b/hw/Kconfig
91
static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
125
index XXXXXXX..XXXXXXX 100644
92
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
126
--- a/hw/Kconfig
93
CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(dev);
127
+++ b/hw/Kconfig
94
int i;
128
@@ -XXX,XX +XXX,XX @@ config XLNX_ZYNQMP
95
129
select REGISTER
96
- if (s->pclk_frq == 0) {
130
select CAN_BUS
97
- error_setg(errp, "CMSDK APB timer: pclk-frq property must be set");
131
select PTIMER
98
+ if (!clock_has_source(s->timclk)) {
132
+ select XLNX_BBRAM
99
+ error_setg(errp, "CMSDK APB dualtimer: TIMCLK clock must be connected");
100
return;
101
}
102
103
--
133
--
104
2.20.1
134
2.20.1
105
135
106
136
diff view generated by jsdifflib
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
1
From: Tong Ho <tong.ho@xilinx.com>
2
2
3
No functional change. Just refactor code to better
3
Connect the support for ZynqMP eFUSE one-time field-programmable
4
support secure and normal world gpios.
4
bit array.
5
5
6
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
6
The command argument:
7
Reviewed-by: Andrew Jones <drjones@redhat.com>
7
-drive if=pflash,index=3,...
8
Can be used to optionally connect the bit array to a
9
backend storage, such that field-programmed values
10
in one invocation can be made available to next
11
invocation.
12
13
The backend storage must be a seekable binary file, and
14
its size must be 768 bytes or larger. A file with all
15
binary 0's is a 'blank'.
16
17
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
18
Message-id: 20210917052400.1249094-9-tong.ho@xilinx.com
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
21
---
10
hw/arm/virt.c | 57 ++++++++++++++++++++++++++++++++-------------------
22
include/hw/arm/xlnx-zynqmp.h | 3 +++
11
1 file changed, 36 insertions(+), 21 deletions(-)
23
hw/arm/xlnx-zcu102.c | 15 +++++++++++++++
24
hw/arm/xlnx-zynqmp.c | 29 +++++++++++++++++++++++++++++
25
hw/Kconfig | 1 +
26
4 files changed, 48 insertions(+)
12
27
13
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
28
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
14
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/virt.c
30
--- a/include/hw/arm/xlnx-zynqmp.h
16
+++ b/hw/arm/virt.c
31
+++ b/include/hw/arm/xlnx-zynqmp.h
17
@@ -XXX,XX +XXX,XX @@ static void virt_powerdown_req(Notifier *n, void *opaque)
32
@@ -XXX,XX +XXX,XX @@
33
#include "net/can_emu.h"
34
#include "hw/dma/xlnx_csu_dma.h"
35
#include "hw/nvram/xlnx-bbram.h"
36
+#include "hw/nvram/xlnx-zynqmp-efuse.h"
37
38
#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
39
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
40
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
41
MemoryRegion *ddr_ram;
42
MemoryRegion ddr_ram_low, ddr_ram_high;
43
XlnxBBRam bbram;
44
+ XlnxEFuse efuse;
45
+ XlnxZynqMPEFuse efuse_ctrl;
46
47
MemoryRegion mr_unimp[XLNX_ZYNQMP_NUM_UNIMP_AREAS];
48
49
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/xlnx-zcu102.c
52
+++ b/hw/arm/xlnx-zcu102.c
53
@@ -XXX,XX +XXX,XX @@ static void bbram_attach_drive(XlnxBBRam *dev)
18
}
54
}
19
}
55
}
20
56
21
-static void create_gpio(const VirtMachineState *vms)
57
+static void efuse_attach_drive(XlnxEFuse *dev)
22
+static void create_gpio_keys(const VirtMachineState *vms,
23
+ DeviceState *pl061_dev,
24
+ uint32_t phandle)
25
+{
58
+{
26
+ gpio_key_dev = sysbus_create_simple("gpio-key", -1,
59
+ DriveInfo *dinfo;
27
+ qdev_get_gpio_in(pl061_dev, 3));
60
+ BlockBackend *blk;
28
+
61
+
29
+ qemu_fdt_add_subnode(vms->fdt, "/gpio-keys");
62
+ dinfo = drive_get_by_index(IF_PFLASH, 3);
30
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-keys", "compatible", "gpio-keys");
63
+ blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
31
+ qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#size-cells", 0);
64
+ if (blk) {
32
+ qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#address-cells", 1);
65
+ qdev_prop_set_drive(DEVICE(dev), "drive", blk);
33
+
66
+ }
34
+ qemu_fdt_add_subnode(vms->fdt, "/gpio-keys/poweroff");
35
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-keys/poweroff",
36
+ "label", "GPIO Key Poweroff");
37
+ qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys/poweroff", "linux,code",
38
+ KEY_POWER);
39
+ qemu_fdt_setprop_cells(vms->fdt, "/gpio-keys/poweroff",
40
+ "gpios", phandle, 3, 0);
41
+}
67
+}
42
+
68
+
43
+static void create_gpio_devices(const VirtMachineState *vms, int gpio,
69
static void xlnx_zcu102_init(MachineState *machine)
44
+ MemoryRegion *mem)
45
{
70
{
46
char *nodename;
71
XlnxZCU102 *s = ZCU102_MACHINE(machine);
47
DeviceState *pl061_dev;
72
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_init(MachineState *machine)
48
- hwaddr base = vms->memmap[VIRT_GPIO].base;
73
/* Attach bbram backend, if given */
49
- hwaddr size = vms->memmap[VIRT_GPIO].size;
74
bbram_attach_drive(&s->soc.bbram);
50
- int irq = vms->irqmap[VIRT_GPIO];
75
51
+ hwaddr base = vms->memmap[gpio].base;
76
+ /* Attach efuse backend, if given */
52
+ hwaddr size = vms->memmap[gpio].size;
77
+ efuse_attach_drive(&s->soc.efuse);
53
+ int irq = vms->irqmap[gpio];
54
const char compat[] = "arm,pl061\0arm,primecell";
55
+ SysBusDevice *s;
56
57
- pl061_dev = sysbus_create_simple("pl061", base,
58
- qdev_get_gpio_in(vms->gic, irq));
59
+ pl061_dev = qdev_new("pl061");
60
+ s = SYS_BUS_DEVICE(pl061_dev);
61
+ sysbus_realize_and_unref(s, &error_fatal);
62
+ memory_region_add_subregion(mem, base, sysbus_mmio_get_region(s, 0));
63
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(vms->gic, irq));
64
65
uint32_t phandle = qemu_fdt_alloc_phandle(vms->fdt);
66
nodename = g_strdup_printf("/pl061@%" PRIx64, base);
67
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const VirtMachineState *vms)
68
qemu_fdt_setprop_string(vms->fdt, nodename, "clock-names", "apb_pclk");
69
qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", phandle);
70
71
- gpio_key_dev = sysbus_create_simple("gpio-key", -1,
72
- qdev_get_gpio_in(pl061_dev, 3));
73
- qemu_fdt_add_subnode(vms->fdt, "/gpio-keys");
74
- qemu_fdt_setprop_string(vms->fdt, "/gpio-keys", "compatible", "gpio-keys");
75
- qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#size-cells", 0);
76
- qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#address-cells", 1);
77
-
78
- qemu_fdt_add_subnode(vms->fdt, "/gpio-keys/poweroff");
79
- qemu_fdt_setprop_string(vms->fdt, "/gpio-keys/poweroff",
80
- "label", "GPIO Key Poweroff");
81
- qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys/poweroff", "linux,code",
82
- KEY_POWER);
83
- qemu_fdt_setprop_cells(vms->fdt, "/gpio-keys/poweroff",
84
- "gpios", phandle, 3, 0);
85
g_free(nodename);
86
+
78
+
87
+ /* Child gpio devices */
79
/* Create and plug in the SD cards */
88
+ create_gpio_keys(vms, pl061_dev, phandle);
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
83
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/arm/xlnx-zynqmp.c
85
+++ b/hw/arm/xlnx-zynqmp.c
86
@@ -XXX,XX +XXX,XX @@
87
#define BBRAM_ADDR 0xffcd0000
88
#define BBRAM_IRQ 11
89
90
+#define EFUSE_ADDR 0xffcc0000
91
+#define EFUSE_IRQ 87
92
+
93
#define SDHCI_CAPABILITIES 0x280737ec6481 /* Datasheet: UG1085 (v1.7) */
94
95
static const uint64_t gem_addr[XLNX_ZYNQMP_NUM_GEMS] = {
96
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_bbram(XlnxZynqMPState *s, qemu_irq *gic)
97
sysbus_connect_irq(sbd, 0, gic[BBRAM_IRQ]);
89
}
98
}
90
99
91
static void create_virtio_devices(const VirtMachineState *vms)
100
+static void xlnx_zynqmp_create_efuse(XlnxZynqMPState *s, qemu_irq *gic)
92
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
101
+{
93
if (has_ged && aarch64 && firmware_loaded && virt_is_acpi_enabled(vms)) {
102
+ Object *bits = OBJECT(&s->efuse);
94
vms->acpi_dev = create_acpi_ged(vms);
103
+ Object *ctrl = OBJECT(&s->efuse_ctrl);
95
} else {
104
+ SysBusDevice *sbd;
96
- create_gpio(vms);
105
+
97
+ create_gpio_devices(vms, VIRT_GPIO, sysmem);
106
+ object_initialize_child(OBJECT(s), "efuse-ctrl", &s->efuse_ctrl,
98
}
107
+ TYPE_XLNX_ZYNQMP_EFUSE);
99
108
+
100
/* connect powerdown request */
109
+ object_initialize_child_with_props(ctrl, "xlnx-efuse@0", bits,
110
+ sizeof(s->efuse),
111
+ TYPE_XLNX_EFUSE, &error_abort,
112
+ "efuse-nr", "3",
113
+ "efuse-size", "2048",
114
+ NULL);
115
+
116
+ qdev_realize(DEVICE(bits), NULL, &error_abort);
117
+ object_property_set_link(ctrl, "efuse", bits, &error_abort);
118
+
119
+ sbd = SYS_BUS_DEVICE(ctrl);
120
+ sysbus_realize(sbd, &error_abort);
121
+ sysbus_mmio_map(sbd, 0, EFUSE_ADDR);
122
+ sysbus_connect_irq(sbd, 0, gic[EFUSE_IRQ]);
123
+}
124
+
125
static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
126
{
127
static const struct UnimpInfo {
128
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
129
sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, gic_spi[RTC_IRQ]);
130
131
xlnx_zynqmp_create_bbram(s, gic_spi);
132
+ xlnx_zynqmp_create_efuse(s, gic_spi);
133
xlnx_zynqmp_create_unimp_mmio(s);
134
135
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
136
diff --git a/hw/Kconfig b/hw/Kconfig
137
index XXXXXXX..XXXXXXX 100644
138
--- a/hw/Kconfig
139
+++ b/hw/Kconfig
140
@@ -XXX,XX +XXX,XX @@ config XLNX_ZYNQMP
141
select CAN_BUS
142
select PTIMER
143
select XLNX_BBRAM
144
+ select XLNX_EFUSE_ZYNQMP
101
--
145
--
102
2.20.1
146
2.20.1
103
147
104
148
diff view generated by jsdifflib
1
From: Joelle van Dyne <j@getutm.app>
1
From: Tong Ho <tong.ho@xilinx.com>
2
2
3
Build without error on hosts without a working system(). If system()
3
Add BBRAM and eFUSE usage to the Xilinx Versal Virt board
4
is called, return -1 with ENOSYS.
4
document.
5
5
6
Signed-off-by: Joelle van Dyne <j@getutm.app>
6
Signed-off-by: Tong Ho <tong.ho@xilinx.com>
7
Message-id: 20210126012457.39046-6-j@getutm.app
7
Message-id: 20210917052400.1249094-10-tong.ho@xilinx.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
meson.build | 1 +
11
docs/system/arm/xlnx-versal-virt.rst | 49 ++++++++++++++++++++++++++++
12
include/qemu/osdep.h | 12 ++++++++++++
12
1 file changed, 49 insertions(+)
13
2 files changed, 13 insertions(+)
14
13
15
diff --git a/meson.build b/meson.build
14
diff --git a/docs/system/arm/xlnx-versal-virt.rst b/docs/system/arm/xlnx-versal-virt.rst
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/meson.build
16
--- a/docs/system/arm/xlnx-versal-virt.rst
18
+++ b/meson.build
17
+++ b/docs/system/arm/xlnx-versal-virt.rst
19
@@ -XXX,XX +XXX,XX @@ config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
18
@@ -XXX,XX +XXX,XX @@ Implemented devices:
20
config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
19
- OCM (256KB of On Chip Memory)
21
config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
20
- XRAM (4MB of on chip Accelerator RAM)
22
config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
21
- DDR memory
23
+config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
22
+- BBRAM (36 bytes of Battery-backed RAM)
24
23
+- eFUSE (3072 bytes of one-time field-programmable bit array)
25
config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
24
26
25
QEMU does not yet model any other devices, including the PL and the AI Engine.
27
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
26
28
index XXXXXXX..XXXXXXX 100644
27
@@ -XXX,XX +XXX,XX @@ Run the following at the U-Boot prompt:
29
--- a/include/qemu/osdep.h
28
fdt set /chosen/dom0 reg <0x00000000 0x40000000 0x0 0x03100000>
30
+++ b/include/qemu/osdep.h
29
booti 30000000 - 20000000
31
@@ -XXX,XX +XXX,XX @@ static inline void qemu_thread_jit_write(void) {}
30
32
static inline void qemu_thread_jit_execute(void) {}
31
+BBRAM File Backend
33
#endif
32
+""""""""""""""""""
34
33
+BBRAM can have an optional file backend, which must be a seekable
35
+/**
34
+binary file with a size of 36 bytes or larger. A file with all
36
+ * Platforms which do not support system() return ENOSYS
35
+binary 0s is a 'blank'.
37
+ */
38
+#ifndef HAVE_SYSTEM_FUNCTION
39
+#define system platform_does_not_support_system
40
+static inline int platform_does_not_support_system(const char *command)
41
+{
42
+ errno = ENOSYS;
43
+ return -1;
44
+}
45
+#endif /* !HAVE_SYSTEM_FUNCTION */
46
+
36
+
47
#endif
37
+To add a file-backend for the BBRAM:
38
+
39
+.. code-block:: bash
40
+
41
+ -drive if=pflash,index=0,file=versal-bbram.bin,format=raw
42
+
43
+To use a different index value, N, from default of 0, add:
44
+
45
+.. code-block:: bash
46
+
47
+ -global xlnx,bbram-ctrl.drive-index=N
48
+
49
+eFUSE File Backend
50
+""""""""""""""""""
51
+eFUSE can have an optional file backend, which must be a seekable
52
+binary file with a size of 3072 bytes or larger. A file with all
53
+binary 0s is a 'blank'.
54
+
55
+To add a file-backend for the eFUSE:
56
+
57
+.. code-block:: bash
58
+
59
+ -drive if=pflash,index=1,file=versal-efuse.bin,format=raw
60
+
61
+To use a different index value, N, from default of 1, add:
62
+
63
+.. code-block:: bash
64
+
65
+ -global xlnx,efuse.drive-index=N
66
+
67
+.. warning::
68
+ In actual physical Versal, BBRAM and eFUSE contain sensitive data.
69
+ The QEMU device models do **not** encrypt nor obfuscate any data
70
+ when holding them in models' memory or when writing them to their
71
+ file backends.
72
+
73
+ Thus, a file backend should be used with caution, and 'format=luks'
74
+ is highly recommended (albeit with usage complexity).
75
+
76
+ Better yet, do not use actual product data when running guest image
77
+ on this Xilinx Versal Virt board.
48
--
78
--
49
2.20.1
79
2.20.1
50
80
51
81
diff view generated by jsdifflib
1
Now that the watchdog device uses its Clock input rather than being
1
The aarch64-linux QEMU usermode binaries can never run 32-bit
2
passed the value of system_clock_scale at creation time, we can
2
code, so they do not need to include the GDB XML for it.
3
remove the hack where we reset the STELLARIS_SYS at board creation
3
(arm_cpu_register_gdb_regs_for_features() will not use these
4
time to force it to set system_clock_scale. Instead it will be reset
4
XML files if the CPU has ARM_FEATURE_AARCH64, so we will not
5
at the usual point in startup and will inform the watchdog of the
5
advertise to gdb that we have them.)
6
clock frequency at that point.
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: Luc Michel <luc@lmichel.fr>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210921162901.17508-2-peter.maydell@linaro.org
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20210128114145.20536-26-peter.maydell@linaro.org
13
Message-id: 20210121190622.22000-26-peter.maydell@linaro.org
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
---
10
---
16
hw/arm/stellaris.c | 10 ----------
11
configs/targets/aarch64-linux-user.mak | 2 +-
17
1 file changed, 10 deletions(-)
12
configs/targets/aarch64_be-linux-user.mak | 2 +-
13
2 files changed, 2 insertions(+), 2 deletions(-)
18
14
19
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
15
diff --git a/configs/targets/aarch64-linux-user.mak b/configs/targets/aarch64-linux-user.mak
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/stellaris.c
17
--- a/configs/targets/aarch64-linux-user.mak
22
+++ b/hw/arm/stellaris.c
18
+++ b/configs/targets/aarch64-linux-user.mak
23
@@ -XXX,XX +XXX,XX @@ static DeviceState *stellaris_sys_init(uint32_t base, qemu_irq irq,
19
@@ -XXX,XX +XXX,XX @@
24
sysbus_mmio_map(sbd, 0, base);
20
TARGET_ARCH=aarch64
25
sysbus_connect_irq(sbd, 0, irq);
21
TARGET_BASE_ARCH=arm
26
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
27
- /*
23
+TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml
28
- * Normally we should not be resetting devices like this during
24
TARGET_HAS_BFLT=y
29
- * board creation. For the moment we need to do so, because
25
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
30
- * system_clock_scale will only get set when the STELLARIS_SYS
26
diff --git a/configs/targets/aarch64_be-linux-user.mak b/configs/targets/aarch64_be-linux-user.mak
31
- * device is reset, and we need its initial value to pass to
27
index XXXXXXX..XXXXXXX 100644
32
- * the watchdog device. This hack can be removed once the
28
--- a/configs/targets/aarch64_be-linux-user.mak
33
- * watchdog has been converted to use a Clock input instead.
29
+++ b/configs/targets/aarch64_be-linux-user.mak
34
- */
30
@@ -XXX,XX +XXX,XX @@
35
- device_cold_reset(dev);
31
TARGET_ARCH=aarch64
36
-
32
TARGET_BASE_ARCH=arm
37
return dev;
33
TARGET_WORDS_BIGENDIAN=y
38
}
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
39
35
+TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml
36
TARGET_HAS_BFLT=y
37
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
40
--
38
--
41
2.20.1
39
2.20.1
42
40
43
41
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.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
Only define the register if it exists for the cpu.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210120031656.737646-1-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210921162901.17508-3-peter.maydell@linaro.org
9
---
10
---
10
target/arm/helper.c | 21 +++++++++++++++------
11
target/arm/helper.c | 23 ++++++++++++++++-------
11
1 file changed, 15 insertions(+), 6 deletions(-)
12
1 file changed, 16 insertions(+), 7 deletions(-)
12
13
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
18
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
18
*/
19
}
19
int i;
20
}
20
int wrps, brps, ctx_cmps;
21
switch (reg - nregs) {
21
- ARMCPRegInfo dbgdidr = {
22
- case 0: return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]); break;
22
- .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
23
- case 1: return gdb_get_reg32(buf, vfp_get_fpscr(env)); break;
23
- .access = PL0_R, .accessfn = access_tda,
24
- case 2: return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]); break;
24
- .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
25
+ case 0:
25
- };
26
+ return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]);
26
+
27
+ case 1:
27
+ /*
28
+ return gdb_get_reg32(buf, vfp_get_fpscr(env));
28
+ * The Arm ARM says DBGDIDR is optional and deprecated if EL1 cannot
29
+ case 2:
29
+ * use AArch32. Given that bit 15 is RES1, if the value is 0 then
30
+ return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]);
30
+ * the register must not exist for this cpu.
31
}
31
+ */
32
return 0;
32
+ if (cpu->isar.dbgdidr != 0) {
33
}
33
+ ARMCPRegInfo dbgdidr = {
34
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
34
+ .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0,
35
}
35
+ .opc1 = 0, .opc2 = 0,
36
}
36
+ .access = PL0_R, .accessfn = access_tda,
37
switch (reg - nregs) {
37
+ .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
38
- case 0: env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); return 4;
38
+ };
39
- case 1: vfp_set_fpscr(env, ldl_p(buf)); return 4;
39
+ define_one_arm_cp_reg(cpu, &dbgdidr);
40
- case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30); return 4;
40
+ }
41
+ case 0:
41
42
+ env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf);
42
/* Note that all these register fields hold "number of Xs minus 1". */
43
+ return 4;
43
brps = arm_num_brps(cpu);
44
+ case 1:
44
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
45
+ vfp_set_fpscr(env, ldl_p(buf));
45
46
+ return 4;
46
assert(ctx_cmps <= brps);
47
+ case 2:
47
48
+ env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30);
48
- define_one_arm_cp_reg(cpu, &dbgdidr);
49
+ return 4;
49
define_arm_cp_regs(cpu, debug_cp_reginfo);
50
}
50
51
return 0;
51
if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) {
52
}
53
@@ -XXX,XX +XXX,XX @@ static int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
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));
59
default:
60
return 0;
61
}
52
--
62
--
53
2.20.1
63
2.20.1
54
64
55
65
diff view generated by jsdifflib
Deleted patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
1
3
The properties to attach a CANBUS object to the xlnx-zcu102 machine have
4
a period in them. We want to use periods in properties for compound QAPI types,
5
and besides the "xlnx-zcu102." prefix is both unnecessary and different
6
from any other machine property name. Remove it.
7
8
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
9
Message-id: 20210118162537.779542-1-pbonzini@redhat.com
10
Reviewed-by: Vikram Garhwal <fnu.vikram@xilinx.com>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/arm/xlnx-zcu102.c | 4 ++--
14
tests/qtest/xlnx-can-test.c | 30 +++++++++++++++---------------
15
2 files changed, 17 insertions(+), 17 deletions(-)
16
17
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/xlnx-zcu102.c
20
+++ b/hw/arm/xlnx-zcu102.c
21
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_machine_instance_init(Object *obj)
22
s->secure = false;
23
/* Default to virt (EL2) being disabled */
24
s->virt = false;
25
- object_property_add_link(obj, "xlnx-zcu102.canbus0", TYPE_CAN_BUS,
26
+ object_property_add_link(obj, "canbus0", TYPE_CAN_BUS,
27
(Object **)&s->canbus[0],
28
object_property_allow_set_link,
29
0);
30
31
- object_property_add_link(obj, "xlnx-zcu102.canbus1", TYPE_CAN_BUS,
32
+ object_property_add_link(obj, "canbus1", TYPE_CAN_BUS,
33
(Object **)&s->canbus[1],
34
object_property_allow_set_link,
35
0);
36
diff --git a/tests/qtest/xlnx-can-test.c b/tests/qtest/xlnx-can-test.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/tests/qtest/xlnx-can-test.c
39
+++ b/tests/qtest/xlnx-can-test.c
40
@@ -XXX,XX +XXX,XX @@ static void test_can_bus(void)
41
uint8_t can_timestamp = 1;
42
43
QTestState *qts = qtest_init("-machine xlnx-zcu102"
44
- " -object can-bus,id=canbus0"
45
- " -machine xlnx-zcu102.canbus0=canbus0"
46
- " -machine xlnx-zcu102.canbus1=canbus0"
47
+ " -object can-bus,id=canbus"
48
+ " -machine canbus0=canbus"
49
+ " -machine canbus1=canbus"
50
);
51
52
/* Configure the CAN0 and CAN1. */
53
@@ -XXX,XX +XXX,XX @@ static void test_can_loopback(void)
54
uint32_t status = 0;
55
56
QTestState *qts = qtest_init("-machine xlnx-zcu102"
57
- " -object can-bus,id=canbus0"
58
- " -machine xlnx-zcu102.canbus0=canbus0"
59
- " -machine xlnx-zcu102.canbus1=canbus0"
60
+ " -object can-bus,id=canbus"
61
+ " -machine canbus0=canbus"
62
+ " -machine canbus1=canbus"
63
);
64
65
/* Configure the CAN0 in loopback mode. */
66
@@ -XXX,XX +XXX,XX @@ static void test_can_filter(void)
67
uint8_t can_timestamp = 1;
68
69
QTestState *qts = qtest_init("-machine xlnx-zcu102"
70
- " -object can-bus,id=canbus0"
71
- " -machine xlnx-zcu102.canbus0=canbus0"
72
- " -machine xlnx-zcu102.canbus1=canbus0"
73
+ " -object can-bus,id=canbus"
74
+ " -machine canbus0=canbus"
75
+ " -machine canbus1=canbus"
76
);
77
78
/* Configure the CAN0 and CAN1. */
79
@@ -XXX,XX +XXX,XX @@ static void test_can_sleepmode(void)
80
uint8_t can_timestamp = 1;
81
82
QTestState *qts = qtest_init("-machine xlnx-zcu102"
83
- " -object can-bus,id=canbus0"
84
- " -machine xlnx-zcu102.canbus0=canbus0"
85
- " -machine xlnx-zcu102.canbus1=canbus0"
86
+ " -object can-bus,id=canbus"
87
+ " -machine canbus0=canbus"
88
+ " -machine canbus1=canbus"
89
);
90
91
/* Configure the CAN0. */
92
@@ -XXX,XX +XXX,XX @@ static void test_can_snoopmode(void)
93
uint8_t can_timestamp = 1;
94
95
QTestState *qts = qtest_init("-machine xlnx-zcu102"
96
- " -object can-bus,id=canbus0"
97
- " -machine xlnx-zcu102.canbus0=canbus0"
98
- " -machine xlnx-zcu102.canbus1=canbus0"
99
+ " -object can-bus,id=canbus"
100
+ " -machine canbus0=canbus"
101
+ " -machine canbus1=canbus"
102
);
103
104
/* Configure the CAN0. */
105
--
106
2.20.1
107
108
diff view generated by jsdifflib
1
Convert the SSYS code in the Stellaris boards (which encapsulates the
1
Currently helper.c includes some code which is part of the arm
2
system registers) to a proper QOM device. This will provide us with
2
target's gdbstub support. This code has a better home: in gdbstub.c
3
somewhere to put the output Clock whose frequency depends on the
3
and gdbstub64.c. Move it there.
4
setting of the PLL configuration registers.
5
4
6
This is a migration compatibility break for lm3s811evb, lm3s6965evb.
5
Because aarch64_fpu_gdb_get_reg() and aarch64_fpu_gdb_set_reg() move
7
6
into gdbstub64.c, this means that they're now compiled only for
8
We use 3-phase reset here because the Clock will need to propagate
7
TARGET_AARCH64 rather than always. That is the only case when they
9
its value in the hold phase.
8
would ever be used, but it does mean that the ifdef in
10
9
arm_cpu_register_gdb_regs_for_features() needs to be adjusted to
11
For the moment we reset the device during the board creation so that
10
match.
12
the system_clock_scale global gets set; this will be removed in a
13
subsequent commit.
14
11
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Luc Michel <luc@lmichel.fr>
17
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Message-id: 20210128114145.20536-17-peter.maydell@linaro.org
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20210121190622.22000-17-peter.maydell@linaro.org
15
Message-id: 20210921162901.17508-4-peter.maydell@linaro.org
21
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
---
16
---
23
hw/arm/stellaris.c | 132 ++++++++++++++++++++++++++++++++++++---------
17
target/arm/internals.h | 7 ++
24
1 file changed, 107 insertions(+), 25 deletions(-)
18
target/arm/gdbstub.c | 130 ++++++++++++++++++++
19
target/arm/gdbstub64.c | 140 +++++++++++++++++++++
20
target/arm/helper.c | 271 -----------------------------------------
21
4 files changed, 277 insertions(+), 271 deletions(-)
25
22
26
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
23
diff --git a/target/arm/internals.h b/target/arm/internals.h
27
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/stellaris.c
25
--- a/target/arm/internals.h
29
+++ b/hw/arm/stellaris.c
26
+++ b/target/arm/internals.h
30
@@ -XXX,XX +XXX,XX @@ static void stellaris_gptm_realize(DeviceState *dev, Error **errp)
27
@@ -XXX,XX +XXX,XX @@ static inline uint64_t pmu_counter_mask(CPUARMState *env)
31
28
return (1 << 31) | ((1 << pmu_num_counters(env)) - 1);
32
/* System controller. */
33
34
-typedef struct {
35
+#define TYPE_STELLARIS_SYS "stellaris-sys"
36
+OBJECT_DECLARE_SIMPLE_TYPE(ssys_state, STELLARIS_SYS)
37
+
38
+struct ssys_state {
39
+ SysBusDevice parent_obj;
40
+
41
MemoryRegion iomem;
42
uint32_t pborctl;
43
uint32_t ldopctl;
44
@@ -XXX,XX +XXX,XX @@ typedef struct {
45
uint32_t dcgc[3];
46
uint32_t clkvclr;
47
uint32_t ldoarst;
48
+ qemu_irq irq;
49
+ /* Properties (all read-only registers) */
50
uint32_t user0;
51
uint32_t user1;
52
- qemu_irq irq;
53
- stellaris_board_info *board;
54
-} ssys_state;
55
+ uint32_t did0;
56
+ uint32_t did1;
57
+ uint32_t dc0;
58
+ uint32_t dc1;
59
+ uint32_t dc2;
60
+ uint32_t dc3;
61
+ uint32_t dc4;
62
+};
63
64
static void ssys_update(ssys_state *s)
65
{
66
@@ -XXX,XX +XXX,XX @@ static uint32_t pllcfg_fury[16] = {
67
68
static int ssys_board_class(const ssys_state *s)
69
{
70
- uint32_t did0 = s->board->did0;
71
+ uint32_t did0 = s->did0;
72
switch (did0 & DID0_VER_MASK) {
73
case DID0_VER_0:
74
return DID0_CLASS_SANDSTORM;
75
@@ -XXX,XX +XXX,XX @@ static uint64_t ssys_read(void *opaque, hwaddr offset,
76
77
switch (offset) {
78
case 0x000: /* DID0 */
79
- return s->board->did0;
80
+ return s->did0;
81
case 0x004: /* DID1 */
82
- return s->board->did1;
83
+ return s->did1;
84
case 0x008: /* DC0 */
85
- return s->board->dc0;
86
+ return s->dc0;
87
case 0x010: /* DC1 */
88
- return s->board->dc1;
89
+ return s->dc1;
90
case 0x014: /* DC2 */
91
- return s->board->dc2;
92
+ return s->dc2;
93
case 0x018: /* DC3 */
94
- return s->board->dc3;
95
+ return s->dc3;
96
case 0x01c: /* DC4 */
97
- return s->board->dc4;
98
+ return s->dc4;
99
case 0x030: /* PBORCTL */
100
return s->pborctl;
101
case 0x034: /* LDOPCTL */
102
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps ssys_ops = {
103
.endianness = DEVICE_NATIVE_ENDIAN,
104
};
105
106
-static void ssys_reset(void *opaque)
107
+static void stellaris_sys_reset_enter(Object *obj, ResetType type)
108
{
109
- ssys_state *s = (ssys_state *)opaque;
110
+ ssys_state *s = STELLARIS_SYS(obj);
111
112
s->pborctl = 0x7ffd;
113
s->rcc = 0x078e3ac0;
114
@@ -XXX,XX +XXX,XX @@ static void ssys_reset(void *opaque)
115
s->rcgc[0] = 1;
116
s->scgc[0] = 1;
117
s->dcgc[0] = 1;
118
+}
119
+
120
+static void stellaris_sys_reset_hold(Object *obj)
121
+{
122
+ ssys_state *s = STELLARIS_SYS(obj);
123
+
124
ssys_calculate_system_clock(s);
125
}
29
}
126
30
127
+static void stellaris_sys_reset_exit(Object *obj)
31
+#ifdef TARGET_AARCH64
128
+{
32
+int arm_gdb_get_svereg(CPUARMState *env, GByteArray *buf, int reg);
129
+}
33
+int arm_gdb_set_svereg(CPUARMState *env, uint8_t *buf, int reg);
130
+
34
+int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg);
131
static int stellaris_sys_post_load(void *opaque, int version_id)
35
+int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg);
132
{
36
+#endif
133
ssys_state *s = opaque;
37
+
134
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_stellaris_sys = {
38
#endif
135
}
39
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
136
};
40
index XXXXXXX..XXXXXXX 100644
137
41
--- a/target/arm/gdbstub.c
138
+static Property stellaris_sys_properties[] = {
42
+++ b/target/arm/gdbstub.c
139
+ DEFINE_PROP_UINT32("user0", ssys_state, user0, 0),
43
@@ -XXX,XX +XXX,XX @@
140
+ DEFINE_PROP_UINT32("user1", ssys_state, user1, 0),
44
*/
141
+ DEFINE_PROP_UINT32("did0", ssys_state, did0, 0),
45
#include "qemu/osdep.h"
142
+ DEFINE_PROP_UINT32("did1", ssys_state, did1, 0),
46
#include "cpu.h"
143
+ DEFINE_PROP_UINT32("dc0", ssys_state, dc0, 0),
47
+#include "internals.h"
144
+ DEFINE_PROP_UINT32("dc1", ssys_state, dc1, 0),
48
#include "exec/gdbstub.h"
145
+ DEFINE_PROP_UINT32("dc2", ssys_state, dc2, 0),
49
146
+ DEFINE_PROP_UINT32("dc3", ssys_state, dc3, 0),
50
typedef struct RegisterSysregXmlParam {
147
+ DEFINE_PROP_UINT32("dc4", ssys_state, dc4, 0),
51
@@ -XXX,XX +XXX,XX @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
148
+ DEFINE_PROP_END_OF_LIST()
149
+};
150
+
151
+static void stellaris_sys_instance_init(Object *obj)
152
+{
153
+ ssys_state *s = STELLARIS_SYS(obj);
154
+ SysBusDevice *sbd = SYS_BUS_DEVICE(s);
155
+
156
+ memory_region_init_io(&s->iomem, obj, &ssys_ops, s, "ssys", 0x00001000);
157
+ sysbus_init_mmio(sbd, &s->iomem);
158
+ sysbus_init_irq(sbd, &s->irq);
159
+}
160
+
161
static int stellaris_sys_init(uint32_t base, qemu_irq irq,
162
stellaris_board_info * board,
163
uint8_t *macaddr)
164
{
165
- ssys_state *s;
166
+ DeviceState *dev = qdev_new(TYPE_STELLARIS_SYS);
167
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
168
169
- s = g_new0(ssys_state, 1);
170
- s->irq = irq;
171
- s->board = board;
172
/* Most devices come preprogrammed with a MAC address in the user data. */
173
- s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
174
- s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
175
+ qdev_prop_set_uint32(dev, "user0",
176
+ macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16));
177
+ qdev_prop_set_uint32(dev, "user1",
178
+ macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16));
179
+ qdev_prop_set_uint32(dev, "did0", board->did0);
180
+ qdev_prop_set_uint32(dev, "did1", board->did1);
181
+ qdev_prop_set_uint32(dev, "dc0", board->dc0);
182
+ qdev_prop_set_uint32(dev, "dc1", board->dc1);
183
+ qdev_prop_set_uint32(dev, "dc2", board->dc2);
184
+ qdev_prop_set_uint32(dev, "dc3", board->dc3);
185
+ qdev_prop_set_uint32(dev, "dc4", board->dc4);
186
+
187
+ sysbus_realize_and_unref(sbd, &error_fatal);
188
+ sysbus_mmio_map(sbd, 0, base);
189
+ sysbus_connect_irq(sbd, 0, irq);
190
+
191
+ /*
192
+ * Normally we should not be resetting devices like this during
193
+ * board creation. For the moment we need to do so, because
194
+ * system_clock_scale will only get set when the STELLARIS_SYS
195
+ * device is reset, and we need its initial value to pass to
196
+ * the watchdog device. This hack can be removed once the
197
+ * watchdog has been converted to use a Clock input instead.
198
+ */
199
+ device_cold_reset(dev);
200
201
- memory_region_init_io(&s->iomem, NULL, &ssys_ops, s, "ssys", 0x00001000);
202
- memory_region_add_subregion(get_system_memory(), base, &s->iomem);
203
- ssys_reset(s);
204
- vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_stellaris_sys, s);
205
return 0;
52
return 0;
206
}
53
}
207
54
208
-
55
+static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
209
/* I2C controller. */
56
+{
210
57
+ ARMCPU *cpu = env_archcpu(env);
211
#define TYPE_STELLARIS_I2C "stellaris-i2c"
58
+ int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
212
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stellaris_adc_info = {
59
+
213
.class_init = stellaris_adc_class_init,
60
+ /* VFP data registers are always little-endian. */
214
};
61
+ if (reg < nregs) {
215
62
+ return gdb_get_reg64(buf, *aa32_vfp_dreg(env, reg));
216
+static void stellaris_sys_class_init(ObjectClass *klass, void *data)
63
+ }
217
+{
64
+ if (arm_feature(env, ARM_FEATURE_NEON)) {
218
+ DeviceClass *dc = DEVICE_CLASS(klass);
65
+ /* Aliases for Q regs. */
219
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
66
+ nregs += 16;
220
+
67
+ if (reg < nregs) {
221
+ dc->vmsd = &vmstate_stellaris_sys;
68
+ uint64_t *q = aa32_vfp_qreg(env, reg - 32);
222
+ rc->phases.enter = stellaris_sys_reset_enter;
69
+ return gdb_get_reg128(buf, q[0], q[1]);
223
+ rc->phases.hold = stellaris_sys_reset_hold;
70
+ }
224
+ rc->phases.exit = stellaris_sys_reset_exit;
71
+ }
225
+ device_class_set_props(dc, stellaris_sys_properties);
72
+ switch (reg - nregs) {
226
+}
73
+ case 0:
227
+
74
+ return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]);
228
+static const TypeInfo stellaris_sys_info = {
75
+ case 1:
229
+ .name = TYPE_STELLARIS_SYS,
76
+ return gdb_get_reg32(buf, vfp_get_fpscr(env));
230
+ .parent = TYPE_SYS_BUS_DEVICE,
77
+ case 2:
231
+ .instance_size = sizeof(ssys_state),
78
+ return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]);
232
+ .instance_init = stellaris_sys_instance_init,
79
+ }
233
+ .class_init = stellaris_sys_class_init,
80
+ return 0;
234
+};
81
+}
235
+
82
+
236
static void stellaris_register_types(void)
83
+static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
84
+{
85
+ ARMCPU *cpu = env_archcpu(env);
86
+ int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
87
+
88
+ if (reg < nregs) {
89
+ *aa32_vfp_dreg(env, reg) = ldq_le_p(buf);
90
+ return 8;
91
+ }
92
+ if (arm_feature(env, ARM_FEATURE_NEON)) {
93
+ nregs += 16;
94
+ if (reg < nregs) {
95
+ uint64_t *q = aa32_vfp_qreg(env, reg - 32);
96
+ q[0] = ldq_le_p(buf);
97
+ q[1] = ldq_le_p(buf + 8);
98
+ return 16;
99
+ }
100
+ }
101
+ switch (reg - nregs) {
102
+ case 0:
103
+ env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf);
104
+ return 4;
105
+ case 1:
106
+ vfp_set_fpscr(env, ldl_p(buf));
107
+ return 4;
108
+ case 2:
109
+ env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30);
110
+ return 4;
111
+ }
112
+ return 0;
113
+}
114
+
115
+/**
116
+ * arm_get/set_gdb_*: get/set a gdb register
117
+ * @env: the CPU state
118
+ * @buf: a buffer to copy to/from
119
+ * @reg: register number (offset from start of group)
120
+ *
121
+ * We return the number of bytes copied
122
+ */
123
+
124
+static int arm_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg)
125
+{
126
+ ARMCPU *cpu = env_archcpu(env);
127
+ const ARMCPRegInfo *ri;
128
+ uint32_t key;
129
+
130
+ key = cpu->dyn_sysreg_xml.data.cpregs.keys[reg];
131
+ ri = get_arm_cp_reginfo(cpu->cp_regs, key);
132
+ if (ri) {
133
+ if (cpreg_field_is_64bit(ri)) {
134
+ return gdb_get_reg64(buf, (uint64_t)read_raw_cp_reg(env, ri));
135
+ } else {
136
+ return gdb_get_reg32(buf, (uint32_t)read_raw_cp_reg(env, ri));
137
+ }
138
+ }
139
+ return 0;
140
+}
141
+
142
+static int arm_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg)
143
+{
144
+ return 0;
145
+}
146
+
147
static void arm_gen_one_xml_sysreg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml,
148
ARMCPRegInfo *ri, uint32_t ri_key,
149
int bitsize, int regnum)
150
@@ -XXX,XX +XXX,XX @@ const char *arm_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname)
151
}
152
return NULL;
153
}
154
+
155
+void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
156
+{
157
+ CPUState *cs = CPU(cpu);
158
+ CPUARMState *env = &cpu->env;
159
+
160
+ if (arm_feature(env, ARM_FEATURE_AARCH64)) {
161
+ /*
162
+ * The lower part of each SVE register aliases to the FPU
163
+ * registers so we don't need to include both.
164
+ */
165
+#ifdef TARGET_AARCH64
166
+ if (isar_feature_aa64_sve(&cpu->isar)) {
167
+ gdb_register_coprocessor(cs, arm_gdb_get_svereg, arm_gdb_set_svereg,
168
+ arm_gen_dynamic_svereg_xml(cs, cs->gdb_num_regs),
169
+ "sve-registers.xml", 0);
170
+ } else {
171
+ gdb_register_coprocessor(cs, aarch64_fpu_gdb_get_reg,
172
+ aarch64_fpu_gdb_set_reg,
173
+ 34, "aarch64-fpu.xml", 0);
174
+ }
175
+#endif
176
+ } else if (arm_feature(env, ARM_FEATURE_NEON)) {
177
+ gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
178
+ 51, "arm-neon.xml", 0);
179
+ } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
180
+ gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
181
+ 35, "arm-vfp3.xml", 0);
182
+ } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
183
+ gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
184
+ 19, "arm-vfp.xml", 0);
185
+ }
186
+ gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
187
+ arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs),
188
+ "system-registers.xml", 0);
189
+
190
+}
191
diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c
192
index XXXXXXX..XXXXXXX 100644
193
--- a/target/arm/gdbstub64.c
194
+++ b/target/arm/gdbstub64.c
195
@@ -XXX,XX +XXX,XX @@
196
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
197
*/
198
#include "qemu/osdep.h"
199
+#include "qemu/log.h"
200
#include "cpu.h"
201
+#include "internals.h"
202
#include "exec/gdbstub.h"
203
204
int aarch64_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
205
@@ -XXX,XX +XXX,XX @@ int aarch64_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
206
/* Unknown register. */
207
return 0;
208
}
209
+
210
+int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
211
+{
212
+ switch (reg) {
213
+ case 0 ... 31:
214
+ {
215
+ /* 128 bit FP register - quads are in LE order */
216
+ uint64_t *q = aa64_vfp_qreg(env, reg);
217
+ return gdb_get_reg128(buf, q[1], q[0]);
218
+ }
219
+ case 32:
220
+ /* FPSR */
221
+ return gdb_get_reg32(buf, vfp_get_fpsr(env));
222
+ case 33:
223
+ /* FPCR */
224
+ return gdb_get_reg32(buf, vfp_get_fpcr(env));
225
+ default:
226
+ return 0;
227
+ }
228
+}
229
+
230
+int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
231
+{
232
+ switch (reg) {
233
+ case 0 ... 31:
234
+ /* 128 bit FP register */
235
+ {
236
+ uint64_t *q = aa64_vfp_qreg(env, reg);
237
+ q[0] = ldq_le_p(buf);
238
+ q[1] = ldq_le_p(buf + 8);
239
+ return 16;
240
+ }
241
+ case 32:
242
+ /* FPSR */
243
+ vfp_set_fpsr(env, ldl_p(buf));
244
+ return 4;
245
+ case 33:
246
+ /* FPCR */
247
+ vfp_set_fpcr(env, ldl_p(buf));
248
+ return 4;
249
+ default:
250
+ return 0;
251
+ }
252
+}
253
+
254
+int arm_gdb_get_svereg(CPUARMState *env, GByteArray *buf, int reg)
255
+{
256
+ ARMCPU *cpu = env_archcpu(env);
257
+
258
+ switch (reg) {
259
+ /* The first 32 registers are the zregs */
260
+ case 0 ... 31:
261
+ {
262
+ int vq, len = 0;
263
+ for (vq = 0; vq < cpu->sve_max_vq; vq++) {
264
+ len += gdb_get_reg128(buf,
265
+ env->vfp.zregs[reg].d[vq * 2 + 1],
266
+ env->vfp.zregs[reg].d[vq * 2]);
267
+ }
268
+ return len;
269
+ }
270
+ case 32:
271
+ return gdb_get_reg32(buf, vfp_get_fpsr(env));
272
+ case 33:
273
+ return gdb_get_reg32(buf, vfp_get_fpcr(env));
274
+ /* then 16 predicates and the ffr */
275
+ case 34 ... 50:
276
+ {
277
+ int preg = reg - 34;
278
+ int vq, len = 0;
279
+ for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
280
+ len += gdb_get_reg64(buf, env->vfp.pregs[preg].p[vq / 4]);
281
+ }
282
+ return len;
283
+ }
284
+ case 51:
285
+ {
286
+ /*
287
+ * We report in Vector Granules (VG) which is 64bit in a Z reg
288
+ * while the ZCR works in Vector Quads (VQ) which is 128bit chunks.
289
+ */
290
+ int vq = sve_zcr_len_for_el(env, arm_current_el(env)) + 1;
291
+ return gdb_get_reg64(buf, vq * 2);
292
+ }
293
+ default:
294
+ /* gdbstub asked for something out our range */
295
+ qemu_log_mask(LOG_UNIMP, "%s: out of range register %d", __func__, reg);
296
+ break;
297
+ }
298
+
299
+ return 0;
300
+}
301
+
302
+int arm_gdb_set_svereg(CPUARMState *env, uint8_t *buf, int reg)
303
+{
304
+ ARMCPU *cpu = env_archcpu(env);
305
+
306
+ /* The first 32 registers are the zregs */
307
+ switch (reg) {
308
+ /* The first 32 registers are the zregs */
309
+ case 0 ... 31:
310
+ {
311
+ int vq, len = 0;
312
+ uint64_t *p = (uint64_t *) buf;
313
+ for (vq = 0; vq < cpu->sve_max_vq; vq++) {
314
+ env->vfp.zregs[reg].d[vq * 2 + 1] = *p++;
315
+ env->vfp.zregs[reg].d[vq * 2] = *p++;
316
+ len += 16;
317
+ }
318
+ return len;
319
+ }
320
+ case 32:
321
+ vfp_set_fpsr(env, *(uint32_t *)buf);
322
+ return 4;
323
+ case 33:
324
+ vfp_set_fpcr(env, *(uint32_t *)buf);
325
+ return 4;
326
+ case 34 ... 50:
327
+ {
328
+ int preg = reg - 34;
329
+ int vq, len = 0;
330
+ uint64_t *p = (uint64_t *) buf;
331
+ for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
332
+ env->vfp.pregs[preg].p[vq / 4] = *p++;
333
+ len += 8;
334
+ }
335
+ return len;
336
+ }
337
+ case 51:
338
+ /* cannot set vg via gdbstub */
339
+ return 0;
340
+ default:
341
+ /* gdbstub asked for something out our range */
342
+ break;
343
+ }
344
+
345
+ return 0;
346
+}
347
diff --git a/target/arm/helper.c b/target/arm/helper.c
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)
237
{
468
{
238
type_register_static(&stellaris_i2c_info);
469
assert(ri->fieldoffset);
239
type_register_static(&stellaris_gptm_info);
470
@@ -XXX,XX +XXX,XX @@ static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
240
type_register_static(&stellaris_adc_info);
471
}
241
+ type_register_static(&stellaris_sys_info);
242
}
472
}
243
473
244
type_init(stellaris_register_types)
474
-/**
475
- * arm_get/set_gdb_*: get/set a gdb register
476
- * @env: the CPU state
477
- * @buf: a buffer to copy to/from
478
- * @reg: register number (offset from start of group)
479
- *
480
- * We return the number of bytes copied
481
- */
482
-
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));
494
- } else {
495
- return gdb_get_reg32(buf, (uint32_t)read_raw_cp_reg(env, ri));
496
- }
497
- }
498
- return 0;
499
-}
500
-
501
-static int arm_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg)
502
-{
503
- return 0;
504
-}
505
-
506
-#ifdef TARGET_AARCH64
507
-static int arm_gdb_get_svereg(CPUARMState *env, GByteArray *buf, int reg)
508
-{
509
- ARMCPU *cpu = env_archcpu(env);
510
-
511
- switch (reg) {
512
- /* The first 32 registers are the zregs */
513
- case 0 ... 31:
514
- {
515
- int vq, len = 0;
516
- for (vq = 0; vq < cpu->sve_max_vq; vq++) {
517
- len += gdb_get_reg128(buf,
518
- env->vfp.zregs[reg].d[vq * 2 + 1],
519
- env->vfp.zregs[reg].d[vq * 2]);
520
- }
521
- return len;
522
- }
523
- case 32:
524
- return gdb_get_reg32(buf, vfp_get_fpsr(env));
525
- case 33:
526
- return gdb_get_reg32(buf, vfp_get_fpcr(env));
527
- /* then 16 predicates and the ffr */
528
- case 34 ... 50:
529
- {
530
- int preg = reg - 34;
531
- int vq, len = 0;
532
- for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
533
- len += gdb_get_reg64(buf, env->vfp.pregs[preg].p[vq / 4]);
534
- }
535
- return len;
536
- }
537
- case 51:
538
- {
539
- /*
540
- * We report in Vector Granules (VG) which is 64bit in a Z reg
541
- * while the ZCR works in Vector Quads (VQ) which is 128bit chunks.
542
- */
543
- int vq = sve_zcr_len_for_el(env, arm_current_el(env)) + 1;
544
- return gdb_get_reg64(buf, vq * 2);
545
- }
546
- default:
547
- /* gdbstub asked for something out our range */
548
- qemu_log_mask(LOG_UNIMP, "%s: out of range register %d", __func__, reg);
549
- break;
550
- }
551
-
552
- return 0;
553
-}
554
-
555
-static int arm_gdb_set_svereg(CPUARMState *env, uint8_t *buf, int reg)
556
-{
557
- ARMCPU *cpu = env_archcpu(env);
558
-
559
- /* The first 32 registers are the zregs */
560
- switch (reg) {
561
- /* The first 32 registers are the zregs */
562
- case 0 ... 31:
563
- {
564
- int vq, len = 0;
565
- uint64_t *p = (uint64_t *) buf;
566
- for (vq = 0; vq < cpu->sve_max_vq; vq++) {
567
- env->vfp.zregs[reg].d[vq * 2 + 1] = *p++;
568
- env->vfp.zregs[reg].d[vq * 2] = *p++;
569
- len += 16;
570
- }
571
- return len;
572
- }
573
- case 32:
574
- vfp_set_fpsr(env, *(uint32_t *)buf);
575
- return 4;
576
- case 33:
577
- vfp_set_fpcr(env, *(uint32_t *)buf);
578
- return 4;
579
- case 34 ... 50:
580
- {
581
- int preg = reg - 34;
582
- int vq, len = 0;
583
- uint64_t *p = (uint64_t *) buf;
584
- for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
585
- env->vfp.pregs[preg].p[vq / 4] = *p++;
586
- len += 8;
587
- }
588
- return len;
589
- }
590
- case 51:
591
- /* cannot set vg via gdbstub */
592
- return 0;
593
- default:
594
- /* gdbstub asked for something out our range */
595
- break;
596
- }
597
-
598
- return 0;
599
-}
600
-#endif /* TARGET_AARCH64 */
601
-
602
static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
603
{
604
/* Return true if the regdef would cause an assertion if you called
605
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
606
#endif
607
}
608
609
-void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
610
-{
611
- CPUState *cs = CPU(cpu);
612
- CPUARMState *env = &cpu->env;
613
-
614
- if (arm_feature(env, ARM_FEATURE_AARCH64)) {
615
- /*
616
- * The lower part of each SVE register aliases to the FPU
617
- * registers so we don't need to include both.
618
- */
619
-#ifdef TARGET_AARCH64
620
- if (isar_feature_aa64_sve(&cpu->isar)) {
621
- gdb_register_coprocessor(cs, arm_gdb_get_svereg, arm_gdb_set_svereg,
622
- arm_gen_dynamic_svereg_xml(cs, cs->gdb_num_regs),
623
- "sve-registers.xml", 0);
624
- } else
625
-#endif
626
- {
627
- gdb_register_coprocessor(cs, aarch64_fpu_gdb_get_reg,
628
- aarch64_fpu_gdb_set_reg,
629
- 34, "aarch64-fpu.xml", 0);
630
- }
631
- } else if (arm_feature(env, ARM_FEATURE_NEON)) {
632
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
633
- 51, "arm-neon.xml", 0);
634
- } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
635
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
636
- 35, "arm-vfp3.xml", 0);
637
- } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
638
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
639
- 19, "arm-vfp.xml", 0);
640
- }
641
- gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
642
- arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs),
643
- "system-registers.xml", 0);
644
-
645
-}
646
-
647
/* Sort alphabetically by type name, except for "any". */
648
static gint arm_cpu_list_compare(gconstpointer a, gconstpointer b)
649
{
245
--
650
--
246
2.20.1
651
2.20.1
247
652
248
653
diff view generated by jsdifflib
1
Create and connect the Clock input for the watchdog device on the
1
Currently we send VFP XML which includes D0..D15 or D0..D31, plus
2
Stellaris boards. Because the Stellaris boards model the ability to
2
FPSID, FPSCR and FPEXC. The upstream GDB tolerates this, but its
3
change the clock rate by programming PLL registers, we have to create
3
definition of this XML feature does not include FPSID or FPEXC. In
4
an output Clock on the ssys_state device and wire it up to the
4
particular, for M-profile cores there are no FPSID or FPEXC
5
watchdog.
5
registers, so advertising those is wrong.
6
6
7
Note that the old comment on ssys_calculate_system_clock() got the
7
Move FPSID and FPEXC into their own bit of XML which we only send for
8
units wrong -- system_clock_scale is in nanoseconds, not
8
A and R profile cores. This brings our definition of the XML
9
milliseconds. Improve the commentary to clarify how we are
9
org.gnu.gdb.arm.vfp feature into line with GDB's own (at least for
10
calculating the period.
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.)
11
16
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Luc Michel <luc@lmichel.fr>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Message-id: 20210921162901.17508-5-peter.maydell@linaro.org
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20210128114145.20536-18-peter.maydell@linaro.org
17
Message-id: 20210121190622.22000-18-peter.maydell@linaro.org
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
---
20
---
20
hw/arm/stellaris.c | 43 +++++++++++++++++++++++++++++++------------
21
configs/targets/aarch64-softmmu.mak | 2 +-
21
1 file changed, 31 insertions(+), 12 deletions(-)
22
configs/targets/arm-linux-user.mak | 2 +-
22
23
configs/targets/arm-softmmu.mak | 2 +-
23
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
24
configs/targets/armeb-linux-user.mak | 2 +-
24
index XXXXXXX..XXXXXXX 100644
25
target/arm/gdbstub.c | 56 ++++++++++++++++++++--------
25
--- a/hw/arm/stellaris.c
26
gdb-xml/arm-neon.xml | 2 -
26
+++ b/hw/arm/stellaris.c
27
gdb-xml/arm-vfp-sysregs.xml | 17 +++++++++
27
@@ -XXX,XX +XXX,XX @@
28
gdb-xml/arm-vfp.xml | 2 -
28
#include "hw/watchdog/cmsdk-apb-watchdog.h"
29
gdb-xml/arm-vfp3.xml | 2 -
29
#include "migration/vmstate.h"
30
9 files changed, 61 insertions(+), 26 deletions(-)
30
#include "hw/misc/unimp.h"
31
create mode 100644 gdb-xml/arm-vfp-sysregs.xml
31
+#include "hw/qdev-clock.h"
32
32
#include "cpu.h"
33
diff --git a/configs/targets/aarch64-softmmu.mak b/configs/targets/aarch64-softmmu.mak
33
#include "qom/object.h"
34
index XXXXXXX..XXXXXXX 100644
34
35
--- a/configs/targets/aarch64-softmmu.mak
35
@@ -XXX,XX +XXX,XX @@ struct ssys_state {
36
+++ b/configs/targets/aarch64-softmmu.mak
36
uint32_t clkvclr;
37
@@ -XXX,XX +XXX,XX @@
37
uint32_t ldoarst;
38
TARGET_ARCH=aarch64
38
qemu_irq irq;
39
TARGET_BASE_ARCH=arm
39
+ Clock *sysclk;
40
TARGET_SUPPORTS_MTTCG=y
40
/* Properties (all read-only registers) */
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
41
uint32_t user0;
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
42
uint32_t user1;
43
TARGET_NEED_FDT=y
43
@@ -XXX,XX +XXX,XX @@ static bool ssys_use_rcc2(ssys_state *s)
44
diff --git a/configs/targets/arm-linux-user.mak b/configs/targets/arm-linux-user.mak
44
}
45
index XXXXXXX..XXXXXXX 100644
45
46
--- a/configs/targets/arm-linux-user.mak
46
/*
47
+++ b/configs/targets/arm-linux-user.mak
47
- * Caculate the sys. clock period in ms.
48
@@ -XXX,XX +XXX,XX @@
48
+ * Calculate the system clock period. We only want to propagate
49
TARGET_ARCH=arm
49
+ * this change to the rest of the system if we're not being called
50
TARGET_SYSTBL_ABI=common,oabi
50
+ * from migration post-load.
51
TARGET_SYSTBL=syscall.tbl
51
*/
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
52
-static void ssys_calculate_system_clock(ssys_state *s)
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
53
+static void ssys_calculate_system_clock(ssys_state *s, bool propagate_clock)
54
TARGET_HAS_BFLT=y
54
{
55
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
55
+ /*
56
diff --git a/configs/targets/arm-softmmu.mak b/configs/targets/arm-softmmu.mak
56
+ * SYSDIV field specifies divisor: 0 == /1, 1 == /2, etc. Input
57
index XXXXXXX..XXXXXXX 100644
57
+ * clock is 200MHz, which is a period of 5 ns. Dividing the clock
58
--- a/configs/targets/arm-softmmu.mak
58
+ * frequency by X is the same as multiplying the period by X.
59
+++ b/configs/targets/arm-softmmu.mak
59
+ */
60
@@ -XXX,XX +XXX,XX @@
60
if (ssys_use_rcc2(s)) {
61
TARGET_ARCH=arm
61
system_clock_scale = 5 * (((s->rcc2 >> 23) & 0x3f) + 1);
62
TARGET_SUPPORTS_MTTCG=y
62
} else {
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
63
system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
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
64
}
65
TARGET_NEED_FDT=y
65
+ clock_set_ns(s->sysclk, system_clock_scale);
66
diff --git a/configs/targets/armeb-linux-user.mak b/configs/targets/armeb-linux-user.mak
66
+ if (propagate_clock) {
67
index XXXXXXX..XXXXXXX 100644
67
+ clock_propagate(s->sysclk);
68
--- a/configs/targets/armeb-linux-user.mak
68
+ }
69
+++ b/configs/targets/armeb-linux-user.mak
69
}
70
@@ -XXX,XX +XXX,XX @@ TARGET_ARCH=arm
70
71
TARGET_SYSTBL_ABI=common,oabi
71
static void ssys_write(void *opaque, hwaddr offset,
72
TARGET_SYSTBL=syscall.tbl
72
@@ -XXX,XX +XXX,XX @@ static void ssys_write(void *opaque, hwaddr offset,
73
TARGET_WORDS_BIGENDIAN=y
73
s->int_status |= (1 << 6);
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
74
}
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
75
s->rcc = value;
76
TARGET_HAS_BFLT=y
76
- ssys_calculate_system_clock(s);
77
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
77
+ ssys_calculate_system_clock(s, true);
78
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
78
break;
79
index XXXXXXX..XXXXXXX 100644
79
case 0x070: /* RCC2 */
80
--- a/target/arm/gdbstub.c
80
if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
81
+++ b/target/arm/gdbstub.c
81
@@ -XXX,XX +XXX,XX @@ static void ssys_write(void *opaque, hwaddr offset,
82
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
82
s->int_status |= (1 << 6);
83
}
83
}
84
switch (reg - nregs) {
84
s->rcc2 = value;
85
case 0:
85
- ssys_calculate_system_clock(s);
86
- return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]);
86
+ ssys_calculate_system_clock(s, true);
87
- case 1:
87
break;
88
return gdb_get_reg32(buf, vfp_get_fpscr(env));
88
case 0x100: /* RCGC0 */
89
- case 2:
89
s->rcgc[0] = value;
90
- return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]);
90
@@ -XXX,XX +XXX,XX @@ static void stellaris_sys_reset_hold(Object *obj)
91
}
91
{
92
ssys_state *s = STELLARIS_SYS(obj);
93
94
- ssys_calculate_system_clock(s);
95
+ /* OK to propagate clocks from the hold phase */
96
+ ssys_calculate_system_clock(s, true);
97
}
98
99
static void stellaris_sys_reset_exit(Object *obj)
100
@@ -XXX,XX +XXX,XX @@ static int stellaris_sys_post_load(void *opaque, int version_id)
101
{
102
ssys_state *s = opaque;
103
104
- ssys_calculate_system_clock(s);
105
+ ssys_calculate_system_clock(s, false);
106
107
return 0;
92
return 0;
108
}
93
}
109
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_stellaris_sys = {
94
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
110
VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3),
111
VMSTATE_UINT32(clkvclr, ssys_state),
112
VMSTATE_UINT32(ldoarst, ssys_state),
113
+ /* No field for sysclk -- handled in post-load instead */
114
VMSTATE_END_OF_LIST()
115
}
116
};
117
@@ -XXX,XX +XXX,XX @@ static void stellaris_sys_instance_init(Object *obj)
118
memory_region_init_io(&s->iomem, obj, &ssys_ops, s, "ssys", 0x00001000);
119
sysbus_init_mmio(sbd, &s->iomem);
120
sysbus_init_irq(sbd, &s->irq);
121
+ s->sysclk = qdev_init_clock_out(DEVICE(s), "SYSCLK");
122
}
123
124
-static int stellaris_sys_init(uint32_t base, qemu_irq irq,
125
- stellaris_board_info * board,
126
- uint8_t *macaddr)
127
+static DeviceState *stellaris_sys_init(uint32_t base, qemu_irq irq,
128
+ stellaris_board_info *board,
129
+ uint8_t *macaddr)
130
{
131
DeviceState *dev = qdev_new(TYPE_STELLARIS_SYS);
132
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
133
@@ -XXX,XX +XXX,XX @@ static int stellaris_sys_init(uint32_t base, qemu_irq irq,
134
*/
135
device_cold_reset(dev);
136
137
- return 0;
138
+ return dev;
139
}
140
141
/* I2C controller. */
142
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
143
int flash_size;
144
I2CBus *i2c;
145
DeviceState *dev;
146
+ DeviceState *ssys_dev;
147
int i;
148
int j;
149
150
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
151
}
95
}
152
}
96
}
153
97
switch (reg - nregs) {
154
- stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
98
+ case 0:
155
- board, nd_table[0].macaddr.a);
99
+ vfp_set_fpscr(env, ldl_p(buf));
156
+ ssys_dev = stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
100
+ return 4;
157
+ board, nd_table[0].macaddr.a);
101
+ }
158
102
+ return 0;
159
103
+}
160
if (board->dc1 & (1 << 3)) { /* watchdog present */
104
+
161
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
105
+static int vfp_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg)
162
/* system_clock_scale is valid now */
106
+{
163
uint32_t mainclk = NANOSECONDS_PER_SECOND / system_clock_scale;
107
+ switch (reg) {
164
qdev_prop_set_uint32(dev, "wdogclk-frq", mainclk);
108
+ case 0:
165
+ qdev_connect_clock_in(dev, "WDOGCLK",
109
+ return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]);
166
+ qdev_get_clock_out(ssys_dev, "SYSCLK"));
110
+ case 1:
167
111
+ return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]);
168
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
112
+ }
169
sysbus_mmio_map(SYS_BUS_DEVICE(dev),
113
+ return 0;
114
+}
115
+
116
+static int vfp_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg)
117
+{
118
+ switch (reg) {
119
case 0:
120
env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf);
121
return 4;
122
case 1:
123
- vfp_set_fpscr(env, ldl_p(buf));
124
- return 4;
125
- case 2:
126
env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30);
127
return 4;
128
}
129
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
130
34, "aarch64-fpu.xml", 0);
131
}
132
#endif
133
- } else if (arm_feature(env, ARM_FEATURE_NEON)) {
134
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
135
- 51, "arm-neon.xml", 0);
136
- } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
137
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
138
- 35, "arm-vfp3.xml", 0);
139
- } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
140
- gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
141
- 19, "arm-vfp.xml", 0);
142
+ } else {
143
+ if (arm_feature(env, ARM_FEATURE_NEON)) {
144
+ gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
145
+ 49, "arm-neon.xml", 0);
146
+ } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
147
+ gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
148
+ 33, "arm-vfp3.xml", 0);
149
+ } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
150
+ gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
151
+ 17, "arm-vfp.xml", 0);
152
+ }
153
+ if (!arm_feature(env, ARM_FEATURE_M)) {
154
+ /*
155
+ * A and R profile have FP sysregs FPEXC and FPSID that we
156
+ * expose to gdb.
157
+ */
158
+ gdb_register_coprocessor(cs, vfp_gdb_get_sysreg, vfp_gdb_set_sysreg,
159
+ 2, "arm-vfp-sysregs.xml", 0);
160
+ }
161
}
162
gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
163
arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs),
164
diff --git a/gdb-xml/arm-neon.xml b/gdb-xml/arm-neon.xml
165
index XXXXXXX..XXXXXXX 100644
166
--- a/gdb-xml/arm-neon.xml
167
+++ b/gdb-xml/arm-neon.xml
168
@@ -XXX,XX +XXX,XX @@
169
<reg name="q14" bitsize="128" type="neon_q"/>
170
<reg name="q15" bitsize="128" type="neon_q"/>
171
172
- <reg name="fpsid" bitsize="32" type="int" group="float"/>
173
<reg name="fpscr" bitsize="32" type="int" group="float"/>
174
- <reg name="fpexc" bitsize="32" type="int" group="float"/>
175
</feature>
176
diff --git a/gdb-xml/arm-vfp-sysregs.xml b/gdb-xml/arm-vfp-sysregs.xml
177
new file mode 100644
178
index XXXXXXX..XXXXXXX
179
--- /dev/null
180
+++ b/gdb-xml/arm-vfp-sysregs.xml
181
@@ -XXX,XX +XXX,XX @@
182
+<?xml version="1.0"?>
183
+<!-- Copyright (C) 2021 Linaro Ltd.
184
+
185
+ Copying and distribution of this file, with or without modification,
186
+ are permitted in any medium without royalty provided the copyright
187
+ notice and this notice are preserved.
188
+
189
+ These are A/R profile VFP system registers. Debugger users probably
190
+ don't really care about these, but because we used to (incorrectly)
191
+ provide them to gdb in the org.gnu.gdb.arm.vfp XML we continue
192
+ to do so via this separate XML.
193
+ -->
194
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
195
+<feature name="org.qemu.gdb.arm.vfp-sysregs">
196
+ <reg name="fpsid" bitsize="32" type="int" group="float"/>
197
+ <reg name="fpexc" bitsize="32" type="int" group="float"/>
198
+</feature>
199
diff --git a/gdb-xml/arm-vfp.xml b/gdb-xml/arm-vfp.xml
200
index XXXXXXX..XXXXXXX 100644
201
--- a/gdb-xml/arm-vfp.xml
202
+++ b/gdb-xml/arm-vfp.xml
203
@@ -XXX,XX +XXX,XX @@
204
<reg name="d14" bitsize="64" type="float"/>
205
<reg name="d15" bitsize="64" type="float"/>
206
207
- <reg name="fpsid" bitsize="32" type="int" group="float"/>
208
<reg name="fpscr" bitsize="32" type="int" group="float"/>
209
- <reg name="fpexc" bitsize="32" type="int" group="float"/>
210
</feature>
211
diff --git a/gdb-xml/arm-vfp3.xml b/gdb-xml/arm-vfp3.xml
212
index XXXXXXX..XXXXXXX 100644
213
--- a/gdb-xml/arm-vfp3.xml
214
+++ b/gdb-xml/arm-vfp3.xml
215
@@ -XXX,XX +XXX,XX @@
216
<reg name="d30" bitsize="64" type="float"/>
217
<reg name="d31" bitsize="64" type="float"/>
218
219
- <reg name="fpsid" bitsize="32" type="int" group="float"/>
220
<reg name="fpscr" bitsize="32" type="int" group="float"/>
221
- <reg name="fpexc" bitsize="32" type="int" group="float"/>
222
</feature>
170
--
223
--
171
2.20.1
224
2.20.1
172
225
173
226
diff view generated by jsdifflib
1
While we transition the ARMSSE code from integer properties
1
The function scsi_bus_new() creates a new SCSI bus; callers can
2
specifying clock frequencies to Clock objects, we want to have the
2
either pass in a name argument to specify the name of the new bus, or
3
device provide both at once. We want the final name of the main
3
they can pass in NULL to allow the bus to be given an automatically
4
input Clock to be "MAINCLK", following the hardware name.
4
generated unique name. Almost all callers want to use the
5
Unfortunately creating an input Clock with a name X creates an
5
autogenerated name; the only exception is the virtio-scsi device.
6
under-the-hood QOM property X; for "MAINCLK" this clashes with the
6
7
existing UINT32 property of that name.
7
Taking a name argument that should almost always be NULL is an
8
8
easy-to-misuse API design -- it encourages callers to think perhaps
9
Rename the UINT32 property to MAINCLK_FRQ so it can coexist with the
9
they should pass in some standard name like "scsi" or "scsi-bus". We
10
MAINCLK Clock; once the transition is complete MAINCLK_FRQ will be
10
don't do this anywhere for SCSI, but we do (incorrectly) do it for
11
deleted.
11
other bus types such as i2c.
12
12
13
Commit created with:
13
The function name also implies that it will return a newly allocated
14
perl -p -i -e 's/MAINCLK/MAINCLK_FRQ/g' hw/arm/{armsse,mps2-tz,musca}.c include/hw/arm/armsse.h
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.
15
26
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
28
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
18
Reviewed-by: Luc Michel <luc@lmichel.fr>
29
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
19
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
30
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
20
Message-id: 20210128114145.20536-11-peter.maydell@linaro.org
31
Message-id: 20210923121153.23754-2-peter.maydell@linaro.org
21
Message-id: 20210121190622.22000-11-peter.maydell@linaro.org
22
---
32
---
23
include/hw/arm/armsse.h | 2 +-
33
include/hw/scsi/scsi.h | 30 ++++++++++++++++++++++++++++--
24
hw/arm/armsse.c | 6 +++---
34
hw/scsi/esp-pci.c | 2 +-
25
hw/arm/mps2-tz.c | 2 +-
35
hw/scsi/esp.c | 2 +-
26
hw/arm/musca.c | 2 +-
36
hw/scsi/lsi53c895a.c | 2 +-
27
4 files changed, 6 insertions(+), 6 deletions(-)
37
hw/scsi/megasas.c | 3 +--
28
38
hw/scsi/mptsas.c | 2 +-
29
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
39
hw/scsi/scsi-bus.c | 4 ++--
30
index XXXXXXX..XXXXXXX 100644
40
hw/scsi/spapr_vscsi.c | 3 +--
31
--- a/include/hw/arm/armsse.h
41
hw/scsi/virtio-scsi.c | 4 ++--
32
+++ b/include/hw/arm/armsse.h
42
hw/scsi/vmw_pvscsi.c | 3 +--
33
@@ -XXX,XX +XXX,XX @@
43
hw/usb/dev-storage-bot.c | 3 +--
34
* QEMU interface:
44
hw/usb/dev-storage-classic.c | 4 ++--
35
* + QOM property "memory" is a MemoryRegion containing the devices provided
45
hw/usb/dev-uas.c | 3 +--
36
* by the board model.
46
13 files changed, 43 insertions(+), 22 deletions(-)
37
- * + QOM property "MAINCLK" is the frequency of the main system clock
47
38
+ * + QOM property "MAINCLK_FRQ" is the frequency of the main system clock
48
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
39
* + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts.
49
index XXXXXXX..XXXXXXX 100644
40
* (In hardware, the SSE-200 permits the number of expansion interrupts
50
--- a/include/hw/scsi/scsi.h
41
* for the two CPUs to be configured separately, but we restrict it to
51
+++ b/include/hw/scsi/scsi.h
42
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
52
@@ -XXX,XX +XXX,XX @@ struct SCSIBus {
43
index XXXXXXX..XXXXXXX 100644
53
const SCSIBusInfo *info;
44
--- a/hw/arm/armsse.c
54
};
45
+++ b/hw/arm/armsse.c
55
46
@@ -XXX,XX +XXX,XX @@ static Property iotkit_properties[] = {
56
-void scsi_bus_new(SCSIBus *bus, size_t bus_size, DeviceState *host,
47
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
57
- const SCSIBusInfo *info, const char *bus_name);
48
MemoryRegion *),
58
+/**
49
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
59
+ * scsi_bus_init_named: Initialize a SCSI bus with the specified name
50
- DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
60
+ * @bus: SCSIBus object to initialize
51
+ DEFINE_PROP_UINT32("MAINCLK_FRQ", ARMSSE, mainclk_frq, 0),
61
+ * @bus_size: size of @bus object
52
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
62
+ * @host: Device which owns the bus (generally the SCSI controller)
53
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
63
+ * @info: structure defining callbacks etc for the controller
54
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
64
+ * @bus_name: Name to use for this bus
55
@@ -XXX,XX +XXX,XX @@ static Property armsse_properties[] = {
65
+ *
56
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
66
+ * This in-place initializes @bus as a new SCSI bus with a name
57
MemoryRegion *),
67
+ * provided by the caller. It is the caller's responsibility to make
58
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
68
+ * sure that name does not clash with the name of any other bus in the
59
- DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
69
+ * system. Unless you need the new bus to have a specific name, you
60
+ DEFINE_PROP_UINT32("MAINCLK_FRQ", ARMSSE, mainclk_frq, 0),
70
+ * should use scsi_bus_new() instead.
61
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
71
+ */
62
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
72
+void scsi_bus_init_named(SCSIBus *bus, size_t bus_size, DeviceState *host,
63
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
73
+ const SCSIBusInfo *info, const char *bus_name);
64
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
74
+
75
+/**
76
+ * scsi_bus_init: Initialize a SCSI bus
77
+ *
78
+ * This in-place-initializes @bus as a new SCSI bus and gives it
79
+ * an automatically generated unique name.
80
+ */
81
+static inline void scsi_bus_init(SCSIBus *bus, size_t bus_size,
82
+ DeviceState *host, const SCSIBusInfo *info)
83
+{
84
+ scsi_bus_init_named(bus, bus_size, host, info, NULL);
85
+}
86
87
static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
88
{
89
diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/hw/scsi/esp-pci.c
92
+++ b/hw/scsi/esp-pci.c
93
@@ -XXX,XX +XXX,XX @@ static void esp_pci_scsi_realize(PCIDevice *dev, Error **errp)
94
pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->io);
95
s->irq = pci_allocate_irq(dev);
96
97
- scsi_bus_new(&s->bus, sizeof(s->bus), d, &esp_pci_scsi_info, NULL);
98
+ scsi_bus_init(&s->bus, sizeof(s->bus), d, &esp_pci_scsi_info);
99
}
100
101
static void esp_pci_scsi_exit(PCIDevice *d)
102
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/hw/scsi/esp.c
105
+++ b/hw/scsi/esp.c
106
@@ -XXX,XX +XXX,XX @@ static void sysbus_esp_realize(DeviceState *dev, Error **errp)
107
108
qdev_init_gpio_in(dev, sysbus_esp_gpio_demux, 2);
109
110
- scsi_bus_new(&s->bus, sizeof(s->bus), dev, &esp_scsi_info, NULL);
111
+ scsi_bus_init(&s->bus, sizeof(s->bus), dev, &esp_scsi_info);
112
}
113
114
static void sysbus_esp_hard_reset(DeviceState *dev)
115
diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
116
index XXXXXXX..XXXXXXX 100644
117
--- a/hw/scsi/lsi53c895a.c
118
+++ b/hw/scsi/lsi53c895a.c
119
@@ -XXX,XX +XXX,XX @@ static void lsi_scsi_realize(PCIDevice *dev, Error **errp)
120
pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ram_io);
121
QTAILQ_INIT(&s->queue);
122
123
- scsi_bus_new(&s->bus, sizeof(s->bus), d, &lsi_scsi_info, NULL);
124
+ scsi_bus_init(&s->bus, sizeof(s->bus), d, &lsi_scsi_info);
125
}
126
127
static void lsi_scsi_exit(PCIDevice *dev)
128
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/hw/scsi/megasas.c
131
+++ b/hw/scsi/megasas.c
132
@@ -XXX,XX +XXX,XX @@ static void megasas_scsi_realize(PCIDevice *dev, Error **errp)
133
s->frames[i].state = s;
65
}
134
}
66
135
67
if (!s->mainclk_frq) {
136
- scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
68
- error_setg(errp, "MAINCLK property was not set");
137
- &megasas_scsi_info, NULL);
69
+ error_setg(errp, "MAINCLK_FRQ property was not set");
138
+ scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(dev), &megasas_scsi_info);
139
}
140
141
static Property megasas_properties_gen1[] = {
142
diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c
143
index XXXXXXX..XXXXXXX 100644
144
--- a/hw/scsi/mptsas.c
145
+++ b/hw/scsi/mptsas.c
146
@@ -XXX,XX +XXX,XX @@ static void mptsas_scsi_realize(PCIDevice *dev, Error **errp)
147
148
s->request_bh = qemu_bh_new(mptsas_fetch_requests, s);
149
150
- scsi_bus_new(&s->bus, sizeof(s->bus), &dev->qdev, &mptsas_scsi_info, NULL);
151
+ scsi_bus_init(&s->bus, sizeof(s->bus), &dev->qdev, &mptsas_scsi_info);
152
}
153
154
static void mptsas_scsi_uninit(PCIDevice *dev)
155
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/hw/scsi/scsi-bus.c
158
+++ b/hw/scsi/scsi-bus.c
159
@@ -XXX,XX +XXX,XX @@ void scsi_device_unit_attention_reported(SCSIDevice *s)
160
}
161
162
/* Create a scsi bus, and attach devices to it. */
163
-void scsi_bus_new(SCSIBus *bus, size_t bus_size, DeviceState *host,
164
- const SCSIBusInfo *info, const char *bus_name)
165
+void scsi_bus_init_named(SCSIBus *bus, size_t bus_size, DeviceState *host,
166
+ const SCSIBusInfo *info, const char *bus_name)
167
{
168
qbus_create_inplace(bus, bus_size, TYPE_SCSI_BUS, host, bus_name);
169
bus->busnr = next_scsi_bus++;
170
diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
171
index XXXXXXX..XXXXXXX 100644
172
--- a/hw/scsi/spapr_vscsi.c
173
+++ b/hw/scsi/spapr_vscsi.c
174
@@ -XXX,XX +XXX,XX @@ static void spapr_vscsi_realize(SpaprVioDevice *dev, Error **errp)
175
176
dev->crq.SendFunc = vscsi_do_crq;
177
178
- scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
179
- &vscsi_scsi_info, NULL);
180
+ scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(dev), &vscsi_scsi_info);
181
182
/* ibmvscsi SCSI bus does not allow hotplug. */
183
qbus_set_hotplug_handler(BUS(&s->bus), NULL);
184
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
185
index XXXXXXX..XXXXXXX 100644
186
--- a/hw/scsi/virtio-scsi.c
187
+++ b/hw/scsi/virtio-scsi.c
188
@@ -XXX,XX +XXX,XX @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp)
70
return;
189
return;
71
}
190
}
72
191
73
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
192
- scsi_bus_new(&s->bus, sizeof(s->bus), dev,
74
index XXXXXXX..XXXXXXX 100644
193
- &virtio_scsi_scsi_info, vdev->bus_name);
75
--- a/hw/arm/mps2-tz.c
194
+ scsi_bus_init_named(&s->bus, sizeof(s->bus), dev,
76
+++ b/hw/arm/mps2-tz.c
195
+ &virtio_scsi_scsi_info, vdev->bus_name);
77
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
196
/* override default SCSI bus hotplug-handler, with virtio-scsi's one */
78
object_property_set_link(OBJECT(&mms->iotkit), "memory",
197
qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(dev));
79
OBJECT(system_memory), &error_abort);
198
80
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
199
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
81
- qdev_prop_set_uint32(iotkitdev, "MAINCLK", SYSCLK_FRQ);
200
index XXXXXXX..XXXXXXX 100644
82
+ qdev_prop_set_uint32(iotkitdev, "MAINCLK_FRQ", SYSCLK_FRQ);
201
--- a/hw/scsi/vmw_pvscsi.c
83
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
202
+++ b/hw/scsi/vmw_pvscsi.c
84
203
@@ -XXX,XX +XXX,XX @@ pvscsi_realizefn(PCIDevice *pci_dev, Error **errp)
85
/*
204
86
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
205
s->completion_worker = qemu_bh_new(pvscsi_process_completion_queue, s);
87
index XXXXXXX..XXXXXXX 100644
206
88
--- a/hw/arm/musca.c
207
- scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(pci_dev),
89
+++ b/hw/arm/musca.c
208
- &pvscsi_scsi_info, NULL);
90
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
209
+ scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(pci_dev), &pvscsi_scsi_info);
91
qdev_prop_set_uint32(ssedev, "EXP_NUMIRQ", mmc->num_irqs);
210
/* override default SCSI bus hotplug-handler, with pvscsi's one */
92
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
211
qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(s));
93
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
212
pvscsi_reset_state(s);
94
- qdev_prop_set_uint32(ssedev, "MAINCLK", SYSCLK_FRQ);
213
diff --git a/hw/usb/dev-storage-bot.c b/hw/usb/dev-storage-bot.c
95
+ qdev_prop_set_uint32(ssedev, "MAINCLK_FRQ", SYSCLK_FRQ);
214
index XXXXXXX..XXXXXXX 100644
96
/*
215
--- a/hw/usb/dev-storage-bot.c
97
* Musca-A takes the default SSE-200 FPU/DSP settings (ie no for
216
+++ b/hw/usb/dev-storage-bot.c
98
* CPU0 and yes for CPU1); Musca-B1 explicitly enables them for CPU0.
217
@@ -XXX,XX +XXX,XX @@ static void usb_msd_bot_realize(USBDevice *dev, Error **errp)
218
s->dev.auto_attach = 0;
219
}
220
221
- scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
222
- &usb_msd_scsi_info_bot, NULL);
223
+ scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(dev), &usb_msd_scsi_info_bot);
224
usb_msd_handle_reset(dev);
225
}
226
227
diff --git a/hw/usb/dev-storage-classic.c b/hw/usb/dev-storage-classic.c
228
index XXXXXXX..XXXXXXX 100644
229
--- a/hw/usb/dev-storage-classic.c
230
+++ b/hw/usb/dev-storage-classic.c
231
@@ -XXX,XX +XXX,XX @@ static void usb_msd_storage_realize(USBDevice *dev, Error **errp)
232
usb_desc_create_serial(dev);
233
usb_desc_init(dev);
234
dev->flags |= (1 << USB_DEV_FLAG_IS_SCSI_STORAGE);
235
- scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
236
- &usb_msd_scsi_info_storage, NULL);
237
+ scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(dev),
238
+ &usb_msd_scsi_info_storage);
239
scsi_dev = scsi_bus_legacy_add_drive(&s->bus, blk, 0, !!s->removable,
240
s->conf.bootindex, s->conf.share_rw,
241
s->conf.rerror, s->conf.werror,
242
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
243
index XXXXXXX..XXXXXXX 100644
244
--- a/hw/usb/dev-uas.c
245
+++ b/hw/usb/dev-uas.c
246
@@ -XXX,XX +XXX,XX @@ static void usb_uas_realize(USBDevice *dev, Error **errp)
247
uas->status_bh = qemu_bh_new(usb_uas_send_status_bh, uas);
248
249
dev->flags |= (1 << USB_DEV_FLAG_IS_SCSI_STORAGE);
250
- scsi_bus_new(&uas->bus, sizeof(uas->bus), DEVICE(dev),
251
- &usb_uas_scsi_info, NULL);
252
+ scsi_bus_init(&uas->bus, sizeof(uas->bus), DEVICE(dev), &usb_uas_scsi_info);
253
}
254
255
static const VMStateDescription vmstate_usb_uas = {
99
--
256
--
100
2.20.1
257
2.20.1
101
258
102
259
diff view generated by jsdifflib
1
Switch the CMSDK APB timer device over to using its Clock input; the
1
Rename ipack_bus_new_inplace() to ipack_bus_init(), to bring it in to
2
pclk-frq property is now ignored.
2
line with a "_init for in-place init, _new for allocate-and-return"
3
convention. Drop the 'name' argument, because the only caller does
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.
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: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Luc Michel <luc@lmichel.fr>
10
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20210923121153.23754-3-peter.maydell@linaro.org
8
Message-id: 20210128114145.20536-19-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-19-peter.maydell@linaro.org
10
---
12
---
11
hw/timer/cmsdk-apb-timer.c | 18 ++++++++++++++----
13
include/hw/ipack/ipack.h | 8 ++++----
12
1 file changed, 14 insertions(+), 4 deletions(-)
14
hw/ipack/ipack.c | 10 +++++-----
15
hw/ipack/tpci200.c | 4 ++--
16
3 files changed, 11 insertions(+), 11 deletions(-)
13
17
14
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
18
diff --git a/include/hw/ipack/ipack.h b/include/hw/ipack/ipack.h
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/timer/cmsdk-apb-timer.c
20
--- a/include/hw/ipack/ipack.h
17
+++ b/hw/timer/cmsdk-apb-timer.c
21
+++ b/include/hw/ipack/ipack.h
18
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_reset(DeviceState *dev)
22
@@ -XXX,XX +XXX,XX @@ extern const VMStateDescription vmstate_ipack_device;
19
ptimer_transaction_commit(s->timer);
23
VMSTATE_STRUCT(_field, _state, 1, vmstate_ipack_device, IPackDevice)
24
25
IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot);
26
-void ipack_bus_new_inplace(IPackBus *bus, size_t bus_size,
27
- DeviceState *parent,
28
- const char *name, uint8_t n_slots,
29
- qemu_irq_handler handler);
30
+void ipack_bus_init(IPackBus *bus, size_t bus_size,
31
+ DeviceState *parent,
32
+ uint8_t n_slots,
33
+ qemu_irq_handler handler);
34
35
#endif
36
diff --git a/hw/ipack/ipack.c b/hw/ipack/ipack.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/ipack/ipack.c
39
+++ b/hw/ipack/ipack.c
40
@@ -XXX,XX +XXX,XX @@ IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot)
41
return NULL;
20
}
42
}
21
43
22
+static void cmsdk_apb_timer_clk_update(void *opaque)
44
-void ipack_bus_new_inplace(IPackBus *bus, size_t bus_size,
23
+{
45
- DeviceState *parent,
24
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(opaque);
46
- const char *name, uint8_t n_slots,
25
+
47
- qemu_irq_handler handler)
26
+ ptimer_transaction_begin(s->timer);
48
+void ipack_bus_init(IPackBus *bus, size_t bus_size,
27
+ ptimer_set_period_from_clock(s->timer, s->pclk, 1);
49
+ DeviceState *parent,
28
+ ptimer_transaction_commit(s->timer);
50
+ uint8_t n_slots,
29
+}
51
+ qemu_irq_handler handler)
30
+
31
static void cmsdk_apb_timer_init(Object *obj)
32
{
52
{
33
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
53
- qbus_create_inplace(bus, bus_size, TYPE_IPACK_BUS, parent, name);
34
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_init(Object *obj)
54
+ qbus_create_inplace(bus, bus_size, TYPE_IPACK_BUS, parent, NULL);
35
s, "cmsdk-apb-timer", 0x1000);
55
bus->n_slots = n_slots;
36
sysbus_init_mmio(sbd, &s->iomem);
56
bus->set_irq = handler;
37
sysbus_init_irq(sbd, &s->timerint);
38
- s->pclk = qdev_init_clock_in(DEVICE(s), "pclk", NULL, NULL);
39
+ s->pclk = qdev_init_clock_in(DEVICE(s), "pclk",
40
+ cmsdk_apb_timer_clk_update, s);
41
}
57
}
42
58
diff --git a/hw/ipack/tpci200.c b/hw/ipack/tpci200.c
43
static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
59
index XXXXXXX..XXXXXXX 100644
44
{
60
--- a/hw/ipack/tpci200.c
45
CMSDKAPBTimer *s = CMSDK_APB_TIMER(dev);
61
+++ b/hw/ipack/tpci200.c
46
62
@@ -XXX,XX +XXX,XX @@ static void tpci200_realize(PCIDevice *pci_dev, Error **errp)
47
- if (s->pclk_frq == 0) {
63
pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las2);
48
- error_setg(errp, "CMSDK APB timer: pclk-frq property must be set");
64
pci_register_bar(&s->dev, 5, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las3);
49
+ if (!clock_has_source(s->pclk)) {
65
50
+ error_setg(errp, "CMSDK APB timer: pclk clock must be connected");
66
- ipack_bus_new_inplace(&s->bus, sizeof(s->bus), DEVICE(pci_dev), NULL,
51
return;
67
- N_MODULES, tpci200_set_irq);
52
}
68
+ ipack_bus_init(&s->bus, sizeof(s->bus), DEVICE(pci_dev),
53
69
+ N_MODULES, tpci200_set_irq);
54
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
55
PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
56
57
ptimer_transaction_begin(s->timer);
58
- ptimer_set_freq(s->timer, s->pclk_frq);
59
+ ptimer_set_period_from_clock(s->timer, s->pclk, 1);
60
ptimer_transaction_commit(s->timer);
61
}
70
}
62
71
72
static const VMStateDescription vmstate_tpci200 = {
63
--
73
--
64
2.20.1
74
2.20.1
65
75
66
76
diff view generated by jsdifflib
1
Now no users are setting the frq properties on the CMSDK timer,
1
Rename the pci_root_bus_new_inplace() function to
2
dualtimer, watchdog or ARMSSE SoC devices, we can remove the
2
pci_root_bus_init(); this brings the bus type in to line with a
3
properties and the struct fields that back them.
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().
4
7
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
10
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
8
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20210923121153.23754-4-peter.maydell@linaro.org
9
Message-id: 20210128114145.20536-25-peter.maydell@linaro.org
10
Message-id: 20210121190622.22000-25-peter.maydell@linaro.org
11
---
12
---
12
include/hw/arm/armsse.h | 2 --
13
include/hw/pci/pci.h | 10 +++++-----
13
include/hw/timer/cmsdk-apb-dualtimer.h | 2 --
14
hw/pci-host/raven.c | 4 ++--
14
include/hw/timer/cmsdk-apb-timer.h | 2 --
15
hw/pci-host/versatile.c | 6 +++---
15
include/hw/watchdog/cmsdk-apb-watchdog.h | 2 --
16
hw/pci/pci.c | 26 +++++++++++++-------------
16
hw/arm/armsse.c | 2 --
17
4 files changed, 23 insertions(+), 23 deletions(-)
17
hw/timer/cmsdk-apb-dualtimer.c | 6 ------
18
hw/timer/cmsdk-apb-timer.c | 6 ------
19
hw/watchdog/cmsdk-apb-watchdog.c | 6 ------
20
8 files changed, 28 deletions(-)
21
18
22
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
19
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
23
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/arm/armsse.h
21
--- a/include/hw/pci/pci.h
25
+++ b/include/hw/arm/armsse.h
22
+++ b/include/hw/pci/pci.h
26
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(PCIBus, PCIBusClass, PCI_BUS)
27
* + Clock input "S32KCLK": slow 32KHz clock used for a few peripherals
24
28
* + QOM property "memory" is a MemoryRegion containing the devices provided
25
bool pci_bus_is_express(PCIBus *bus);
29
* by the board model.
26
30
- * + QOM property "MAINCLK_FRQ" is the frequency of the main system clock
27
-void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
31
* + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts.
28
- const char *name,
32
* (In hardware, the SSE-200 permits the number of expansion interrupts
29
- MemoryRegion *address_space_mem,
33
* for the two CPUs to be configured separately, but we restrict it to
30
- MemoryRegion *address_space_io,
34
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
31
- uint8_t devfn_min, const char *typename);
35
/* Properties */
32
+void pci_root_bus_init(PCIBus *bus, size_t bus_size, DeviceState *parent,
36
MemoryRegion *board_memory;
33
+ const char *name,
37
uint32_t exp_numirq;
34
+ MemoryRegion *address_space_mem,
38
- uint32_t mainclk_frq;
35
+ MemoryRegion *address_space_io,
39
uint32_t sram_addr_width;
36
+ uint8_t devfn_min, const char *typename);
40
uint32_t init_svtor;
37
PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
41
bool cpu_fpu[SSE_MAX_CPUS];
38
MemoryRegion *address_space_mem,
42
diff --git a/include/hw/timer/cmsdk-apb-dualtimer.h b/include/hw/timer/cmsdk-apb-dualtimer.h
39
MemoryRegion *address_space_io,
40
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
43
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
44
--- a/include/hw/timer/cmsdk-apb-dualtimer.h
42
--- a/hw/pci-host/raven.c
45
+++ b/include/hw/timer/cmsdk-apb-dualtimer.h
43
+++ b/hw/pci-host/raven.c
46
@@ -XXX,XX +XXX,XX @@
44
@@ -XXX,XX +XXX,XX @@ static void raven_pcihost_initfn(Object *obj)
47
* https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
45
memory_region_add_subregion_overlap(address_space_mem, PCI_IO_BASE_ADDR,
48
*
46
&s->pci_io_non_contiguous, 1);
49
* QEMU interface:
47
memory_region_add_subregion(address_space_mem, 0xc0000000, &s->pci_memory);
50
- * + QOM property "pclk-frq": frequency at which the timer is clocked
48
- pci_root_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), NULL,
51
* + Clock input "TIMCLK": clock (for both timers)
49
- &s->pci_memory, &s->pci_io, 0, TYPE_PCI_BUS);
52
* + sysbus MMIO region 0: the register bank
50
+ pci_root_bus_init(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), NULL,
53
* + sysbus IRQ 0: combined timer interrupt TIMINTC
51
+ &s->pci_memory, &s->pci_io, 0, TYPE_PCI_BUS);
54
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBDualTimer {
52
55
/*< public >*/
53
/* Bus master address space */
56
MemoryRegion iomem;
54
memory_region_init(&s->bm, obj, "bm-raven", 4 * GiB);
57
qemu_irq timerintc;
55
diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
58
- uint32_t pclk_frq;
59
Clock *timclk;
60
61
CMSDKAPBDualTimerModule timermod[CMSDK_APB_DUALTIMER_NUM_MODULES];
62
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
63
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
64
--- a/include/hw/timer/cmsdk-apb-timer.h
57
--- a/hw/pci-host/versatile.c
65
+++ b/include/hw/timer/cmsdk-apb-timer.h
58
+++ b/hw/pci-host/versatile.c
66
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(CMSDKAPBTimer, CMSDK_APB_TIMER)
59
@@ -XXX,XX +XXX,XX @@ static void pci_vpb_realize(DeviceState *dev, Error **errp)
67
60
memory_region_init(&s->pci_io_space, OBJECT(s), "pci_io", 4 * GiB);
68
/*
61
memory_region_init(&s->pci_mem_space, OBJECT(s), "pci_mem", 4 * GiB);
69
* QEMU interface:
62
70
- * + QOM property "pclk-frq": frequency at which the timer is clocked
63
- pci_root_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), dev, "pci",
71
* + Clock input "pclk": clock for the timer
64
- &s->pci_mem_space, &s->pci_io_space,
72
* + sysbus MMIO region 0: the register bank
65
- PCI_DEVFN(11, 0), TYPE_PCI_BUS);
73
* + sysbus IRQ 0: timer interrupt TIMERINT
66
+ pci_root_bus_init(&s->pci_bus, sizeof(s->pci_bus), dev, "pci",
74
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBTimer {
67
+ &s->pci_mem_space, &s->pci_io_space,
75
/*< public >*/
68
+ PCI_DEVFN(11, 0), TYPE_PCI_BUS);
76
MemoryRegion iomem;
69
h->bus = &s->pci_bus;
77
qemu_irq timerint;
70
78
- uint32_t pclk_frq;
71
object_initialize(&s->pci_dev, sizeof(s->pci_dev), TYPE_VERSATILE_PCI_HOST);
79
struct ptimer_state *timer;
72
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
80
Clock *pclk;
81
82
diff --git a/include/hw/watchdog/cmsdk-apb-watchdog.h b/include/hw/watchdog/cmsdk-apb-watchdog.h
83
index XXXXXXX..XXXXXXX 100644
73
index XXXXXXX..XXXXXXX 100644
84
--- a/include/hw/watchdog/cmsdk-apb-watchdog.h
74
--- a/hw/pci/pci.c
85
+++ b/include/hw/watchdog/cmsdk-apb-watchdog.h
75
+++ b/hw/pci/pci.c
86
@@ -XXX,XX +XXX,XX @@
76
@@ -XXX,XX +XXX,XX @@ bool pci_bus_bypass_iommu(PCIBus *bus)
87
* https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
77
return host_bridge->bypass_iommu;
88
*
78
}
89
* QEMU interface:
79
90
- * + QOM property "wdogclk-frq": frequency at which the watchdog is clocked
80
-static void pci_root_bus_init(PCIBus *bus, DeviceState *parent,
91
* + Clock input "WDOGCLK": clock for the watchdog's timer
81
- MemoryRegion *address_space_mem,
92
* + sysbus MMIO region 0: the register bank
82
- MemoryRegion *address_space_io,
93
* + sysbus IRQ 0: watchdog interrupt
83
- uint8_t devfn_min)
94
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBWatchdog {
84
+static void pci_root_bus_internal_init(PCIBus *bus, DeviceState *parent,
95
/*< public >*/
85
+ MemoryRegion *address_space_mem,
96
MemoryRegion iomem;
86
+ MemoryRegion *address_space_io,
97
qemu_irq wdogint;
87
+ uint8_t devfn_min)
98
- uint32_t wdogclk_frq;
99
bool is_luminary;
100
struct ptimer_state *timer;
101
Clock *wdogclk;
102
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/hw/arm/armsse.c
105
+++ b/hw/arm/armsse.c
106
@@ -XXX,XX +XXX,XX @@ static Property iotkit_properties[] = {
107
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
108
MemoryRegion *),
109
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
110
- DEFINE_PROP_UINT32("MAINCLK_FRQ", ARMSSE, mainclk_frq, 0),
111
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
112
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
113
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
114
@@ -XXX,XX +XXX,XX @@ static Property armsse_properties[] = {
115
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
116
MemoryRegion *),
117
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
118
- DEFINE_PROP_UINT32("MAINCLK_FRQ", ARMSSE, mainclk_frq, 0),
119
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
120
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
121
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
122
diff --git a/hw/timer/cmsdk-apb-dualtimer.c b/hw/timer/cmsdk-apb-dualtimer.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/hw/timer/cmsdk-apb-dualtimer.c
125
+++ b/hw/timer/cmsdk-apb-dualtimer.c
126
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription cmsdk_apb_dualtimer_vmstate = {
127
}
128
};
129
130
-static Property cmsdk_apb_dualtimer_properties[] = {
131
- DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBDualTimer, pclk_frq, 0),
132
- DEFINE_PROP_END_OF_LIST(),
133
-};
134
-
135
static void cmsdk_apb_dualtimer_class_init(ObjectClass *klass, void *data)
136
{
88
{
137
DeviceClass *dc = DEVICE_CLASS(klass);
89
assert(PCI_FUNC(devfn_min) == 0);
138
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_class_init(ObjectClass *klass, void *data)
90
bus->devfn_min = devfn_min;
139
dc->realize = cmsdk_apb_dualtimer_realize;
91
@@ -XXX,XX +XXX,XX @@ bool pci_bus_is_express(PCIBus *bus)
140
dc->vmsd = &cmsdk_apb_dualtimer_vmstate;
92
return object_dynamic_cast(OBJECT(bus), TYPE_PCIE_BUS);
141
dc->reset = cmsdk_apb_dualtimer_reset;
142
- device_class_set_props(dc, cmsdk_apb_dualtimer_properties);
143
}
93
}
144
94
145
static const TypeInfo cmsdk_apb_dualtimer_info = {
95
-void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
146
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
96
- const char *name,
147
index XXXXXXX..XXXXXXX 100644
97
- MemoryRegion *address_space_mem,
148
--- a/hw/timer/cmsdk-apb-timer.c
98
- MemoryRegion *address_space_io,
149
+++ b/hw/timer/cmsdk-apb-timer.c
99
- uint8_t devfn_min, const char *typename)
150
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription cmsdk_apb_timer_vmstate = {
100
+void pci_root_bus_init(PCIBus *bus, size_t bus_size, DeviceState *parent,
151
}
101
+ const char *name,
152
};
102
+ MemoryRegion *address_space_mem,
153
103
+ MemoryRegion *address_space_io,
154
-static Property cmsdk_apb_timer_properties[] = {
104
+ uint8_t devfn_min, const char *typename)
155
- DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBTimer, pclk_frq, 0),
156
- DEFINE_PROP_END_OF_LIST(),
157
-};
158
-
159
static void cmsdk_apb_timer_class_init(ObjectClass *klass, void *data)
160
{
105
{
161
DeviceClass *dc = DEVICE_CLASS(klass);
106
qbus_create_inplace(bus, bus_size, typename, parent, name);
162
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_class_init(ObjectClass *klass, void *data)
107
- pci_root_bus_init(bus, parent, address_space_mem, address_space_io,
163
dc->realize = cmsdk_apb_timer_realize;
108
- devfn_min);
164
dc->vmsd = &cmsdk_apb_timer_vmstate;
109
+ pci_root_bus_internal_init(bus, parent, address_space_mem,
165
dc->reset = cmsdk_apb_timer_reset;
110
+ address_space_io, devfn_min);
166
- device_class_set_props(dc, cmsdk_apb_timer_properties);
167
}
111
}
168
112
169
static const TypeInfo cmsdk_apb_timer_info = {
113
PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
170
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
114
@@ -XXX,XX +XXX,XX @@ PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
171
index XXXXXXX..XXXXXXX 100644
115
PCIBus *bus;
172
--- a/hw/watchdog/cmsdk-apb-watchdog.c
116
173
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
117
bus = PCI_BUS(qbus_create(typename, parent, name));
174
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription cmsdk_apb_watchdog_vmstate = {
118
- pci_root_bus_init(bus, parent, address_space_mem, address_space_io,
175
}
119
- devfn_min);
176
};
120
+ pci_root_bus_internal_init(bus, parent, address_space_mem,
177
121
+ address_space_io, devfn_min);
178
-static Property cmsdk_apb_watchdog_properties[] = {
122
return bus;
179
- DEFINE_PROP_UINT32("wdogclk-frq", CMSDKAPBWatchdog, wdogclk_frq, 0),
180
- DEFINE_PROP_END_OF_LIST(),
181
-};
182
-
183
static void cmsdk_apb_watchdog_class_init(ObjectClass *klass, void *data)
184
{
185
DeviceClass *dc = DEVICE_CLASS(klass);
186
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_class_init(ObjectClass *klass, void *data)
187
dc->realize = cmsdk_apb_watchdog_realize;
188
dc->vmsd = &cmsdk_apb_watchdog_vmstate;
189
dc->reset = cmsdk_apb_watchdog_reset;
190
- device_class_set_props(dc, cmsdk_apb_watchdog_properties);
191
}
123
}
192
124
193
static const TypeInfo cmsdk_apb_watchdog_info = {
194
--
125
--
195
2.20.1
126
2.20.1
196
127
197
128
diff view generated by jsdifflib
1
Switch the CMSDK APB watchdog device over to using its Clock input;
1
Rename qbus_create_inplace() to qbus_init(); this is more in line
2
the wdogclk_frq property is now ignored.
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: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210923121153.23754-5-peter.maydell@linaro.org
8
Message-id: 20210128114145.20536-21-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-21-peter.maydell@linaro.org
10
---
9
---
11
hw/watchdog/cmsdk-apb-watchdog.c | 18 ++++++++++++++----
10
include/hw/qdev-core.h | 4 ++--
12
1 file changed, 14 insertions(+), 4 deletions(-)
11
hw/audio/intel-hda.c | 2 +-
12
hw/block/fdc.c | 2 +-
13
hw/block/swim.c | 3 +--
14
hw/char/virtio-serial-bus.c | 4 ++--
15
hw/core/bus.c | 11 ++++++-----
16
hw/core/sysbus.c | 10 ++++++----
17
hw/gpio/bcm2835_gpio.c | 3 +--
18
hw/ide/qdev.c | 2 +-
19
hw/ipack/ipack.c | 2 +-
20
hw/misc/mac_via.c | 4 ++--
21
hw/misc/macio/cuda.c | 4 ++--
22
hw/misc/macio/macio.c | 4 ++--
23
hw/misc/macio/pmu.c | 4 ++--
24
hw/nubus/nubus-bridge.c | 2 +-
25
hw/nvme/ctrl.c | 4 ++--
26
hw/nvme/subsys.c | 3 +--
27
hw/pci/pci.c | 2 +-
28
hw/pci/pci_bridge.c | 4 ++--
29
hw/s390x/event-facility.c | 4 ++--
30
hw/s390x/virtio-ccw.c | 3 +--
31
hw/scsi/scsi-bus.c | 2 +-
32
hw/sd/allwinner-sdhost.c | 4 ++--
33
hw/sd/bcm2835_sdhost.c | 4 ++--
34
hw/sd/pl181.c | 3 +--
35
hw/sd/pxa2xx_mmci.c | 4 ++--
36
hw/sd/sdhci.c | 3 +--
37
hw/sd/ssi-sd.c | 3 +--
38
hw/usb/bus.c | 2 +-
39
hw/usb/dev-smartcard-reader.c | 3 +--
40
hw/virtio/virtio-mmio.c | 3 +--
41
hw/virtio/virtio-pci.c | 3 +--
42
32 files changed, 54 insertions(+), 61 deletions(-)
13
43
14
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
44
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
15
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/watchdog/cmsdk-apb-watchdog.c
46
--- a/include/hw/qdev-core.h
17
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
47
+++ b/include/hw/qdev-core.h
18
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_reset(DeviceState *dev)
48
@@ -XXX,XX +XXX,XX @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id);
19
ptimer_transaction_commit(s->timer);
49
typedef int (qbus_walkerfn)(BusState *bus, void *opaque);
20
}
50
typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque);
21
51
22
+static void cmsdk_apb_watchdog_clk_update(void *opaque)
52
-void qbus_create_inplace(void *bus, size_t size, const char *typename,
23
+{
53
- DeviceState *parent, const char *name);
24
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
54
+void qbus_init(void *bus, size_t size, const char *typename,
25
+
55
+ DeviceState *parent, const char *name);
26
+ ptimer_transaction_begin(s->timer);
56
BusState *qbus_create(const char *typename, DeviceState *parent, const char *name);
27
+ ptimer_set_period_from_clock(s->timer, s->wdogclk, 1);
57
bool qbus_realize(BusState *bus, Error **errp);
28
+ ptimer_transaction_commit(s->timer);
58
void qbus_unrealize(BusState *bus);
29
+}
59
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
30
+
60
index XXXXXXX..XXXXXXX 100644
31
static void cmsdk_apb_watchdog_init(Object *obj)
61
--- a/hw/audio/intel-hda.c
32
{
62
+++ b/hw/audio/intel-hda.c
63
@@ -XXX,XX +XXX,XX @@ void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, size_t bus_size,
64
hda_codec_response_func response,
65
hda_codec_xfer_func xfer)
66
{
67
- qbus_create_inplace(bus, bus_size, TYPE_HDA_BUS, dev, NULL);
68
+ qbus_init(bus, bus_size, TYPE_HDA_BUS, dev, NULL);
69
bus->response = response;
70
bus->xfer = xfer;
71
}
72
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/block/fdc.c
75
+++ b/hw/block/fdc.c
76
@@ -XXX,XX +XXX,XX @@ static const TypeInfo floppy_bus_info = {
77
78
static void floppy_bus_create(FDCtrl *fdc, FloppyBus *bus, DeviceState *dev)
79
{
80
- qbus_create_inplace(bus, sizeof(FloppyBus), TYPE_FLOPPY_BUS, dev, NULL);
81
+ qbus_init(bus, sizeof(FloppyBus), TYPE_FLOPPY_BUS, dev, NULL);
82
bus->fdc = fdc;
83
}
84
85
diff --git a/hw/block/swim.c b/hw/block/swim.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/hw/block/swim.c
88
+++ b/hw/block/swim.c
89
@@ -XXX,XX +XXX,XX @@ static void sysbus_swim_realize(DeviceState *dev, Error **errp)
90
Swim *sys = SWIM(dev);
91
SWIMCtrl *swimctrl = &sys->ctrl;
92
93
- qbus_create_inplace(&swimctrl->bus, sizeof(SWIMBus), TYPE_SWIM_BUS, dev,
94
- NULL);
95
+ qbus_init(&swimctrl->bus, sizeof(SWIMBus), TYPE_SWIM_BUS, dev, NULL);
96
swimctrl->bus.ctrl = swimctrl;
97
}
98
99
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/hw/char/virtio-serial-bus.c
102
+++ b/hw/char/virtio-serial-bus.c
103
@@ -XXX,XX +XXX,XX @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
104
config_size);
105
106
/* Spawn a new virtio-serial bus on which the ports will ride as devices */
107
- qbus_create_inplace(&vser->bus, sizeof(vser->bus), TYPE_VIRTIO_SERIAL_BUS,
108
- dev, vdev->bus_name);
109
+ qbus_init(&vser->bus, sizeof(vser->bus), TYPE_VIRTIO_SERIAL_BUS,
110
+ dev, vdev->bus_name);
111
qbus_set_hotplug_handler(BUS(&vser->bus), OBJECT(vser));
112
vser->bus.vser = vser;
113
QTAILQ_INIT(&vser->ports);
114
diff --git a/hw/core/bus.c b/hw/core/bus.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/hw/core/bus.c
117
+++ b/hw/core/bus.c
118
@@ -XXX,XX +XXX,XX @@ static void bus_reset_child_foreach(Object *obj, ResettableChildCallback cb,
119
}
120
}
121
122
-static void qbus_init(BusState *bus, DeviceState *parent, const char *name)
123
+static void qbus_init_internal(BusState *bus, DeviceState *parent,
124
+ const char *name)
125
{
126
const char *typename = object_get_typename(OBJECT(bus));
127
BusClass *bc;
128
@@ -XXX,XX +XXX,XX @@ static void bus_unparent(Object *obj)
129
bus->parent = NULL;
130
}
131
132
-void qbus_create_inplace(void *bus, size_t size, const char *typename,
133
- DeviceState *parent, const char *name)
134
+void qbus_init(void *bus, size_t size, const char *typename,
135
+ DeviceState *parent, const char *name)
136
{
137
object_initialize(bus, size, typename);
138
- qbus_init(bus, parent, name);
139
+ qbus_init_internal(bus, parent, name);
140
}
141
142
BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
143
@@ -XXX,XX +XXX,XX @@ BusState *qbus_create(const char *typename, DeviceState *parent, const char *nam
144
BusState *bus;
145
146
bus = BUS(object_new(typename));
147
- qbus_init(bus, parent, name);
148
+ qbus_init_internal(bus, parent, name);
149
150
return bus;
151
}
152
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/hw/core/sysbus.c
155
+++ b/hw/core/sysbus.c
156
@@ -XXX,XX +XXX,XX @@ static BusState *main_system_bus;
157
158
static void main_system_bus_create(void)
159
{
160
- /* assign main_system_bus before qbus_create_inplace()
161
- * in order to make "if (bus != sysbus_get_default())" work */
162
+ /*
163
+ * assign main_system_bus before qbus_init()
164
+ * in order to make "if (bus != sysbus_get_default())" work
165
+ */
166
main_system_bus = g_malloc0(system_bus_info.instance_size);
167
- qbus_create_inplace(main_system_bus, system_bus_info.instance_size,
168
- TYPE_SYSTEM_BUS, NULL, "main-system-bus");
169
+ qbus_init(main_system_bus, system_bus_info.instance_size,
170
+ TYPE_SYSTEM_BUS, NULL, "main-system-bus");
171
OBJECT(main_system_bus)->free = g_free;
172
}
173
174
diff --git a/hw/gpio/bcm2835_gpio.c b/hw/gpio/bcm2835_gpio.c
175
index XXXXXXX..XXXXXXX 100644
176
--- a/hw/gpio/bcm2835_gpio.c
177
+++ b/hw/gpio/bcm2835_gpio.c
178
@@ -XXX,XX +XXX,XX @@ static void bcm2835_gpio_init(Object *obj)
179
DeviceState *dev = DEVICE(obj);
33
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
180
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
34
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_init(Object *obj)
181
35
s, "cmsdk-apb-watchdog", 0x1000);
182
- qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
36
sysbus_init_mmio(sbd, &s->iomem);
183
- TYPE_SD_BUS, DEVICE(s), "sd-bus");
37
sysbus_init_irq(sbd, &s->wdogint);
184
+ qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_SD_BUS, DEVICE(s), "sd-bus");
38
- s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK", NULL, NULL);
185
39
+ s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK",
186
memory_region_init_io(&s->iomem, obj,
40
+ cmsdk_apb_watchdog_clk_update, s);
187
&bcm2835_gpio_ops, s, "bcm2835_gpio", 0x1000);
41
188
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
42
s->is_luminary = false;
189
index XXXXXXX..XXXXXXX 100644
43
s->id = cmsdk_apb_watchdog_id;
190
--- a/hw/ide/qdev.c
44
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
191
+++ b/hw/ide/qdev.c
45
{
192
@@ -XXX,XX +XXX,XX @@ static const TypeInfo ide_bus_info = {
46
CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(dev);
193
void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
47
194
int bus_id, int max_units)
48
- if (s->wdogclk_frq == 0) {
195
{
49
+ if (!clock_has_source(s->wdogclk)) {
196
- qbus_create_inplace(idebus, idebus_size, TYPE_IDE_BUS, dev, NULL);
50
error_setg(errp,
197
+ qbus_init(idebus, idebus_size, TYPE_IDE_BUS, dev, NULL);
51
- "CMSDK APB watchdog: wdogclk-frq property must be set");
198
idebus->bus_id = bus_id;
52
+ "CMSDK APB watchdog: WDOGCLK clock must be connected");
199
idebus->max_units = max_units;
200
}
201
diff --git a/hw/ipack/ipack.c b/hw/ipack/ipack.c
202
index XXXXXXX..XXXXXXX 100644
203
--- a/hw/ipack/ipack.c
204
+++ b/hw/ipack/ipack.c
205
@@ -XXX,XX +XXX,XX @@ void ipack_bus_init(IPackBus *bus, size_t bus_size,
206
uint8_t n_slots,
207
qemu_irq_handler handler)
208
{
209
- qbus_create_inplace(bus, bus_size, TYPE_IPACK_BUS, parent, NULL);
210
+ qbus_init(bus, bus_size, TYPE_IPACK_BUS, parent, NULL);
211
bus->n_slots = n_slots;
212
bus->set_irq = handler;
213
}
214
diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
215
index XXXXXXX..XXXXXXX 100644
216
--- a/hw/misc/mac_via.c
217
+++ b/hw/misc/mac_via.c
218
@@ -XXX,XX +XXX,XX @@ static void mos6522_q800_via1_init(Object *obj)
219
sysbus_init_mmio(sbd, &v1s->via_mem);
220
221
/* ADB */
222
- qbus_create_inplace((BusState *)&v1s->adb_bus, sizeof(v1s->adb_bus),
223
- TYPE_ADB_BUS, DEVICE(v1s), "adb.0");
224
+ qbus_init((BusState *)&v1s->adb_bus, sizeof(v1s->adb_bus),
225
+ TYPE_ADB_BUS, DEVICE(v1s), "adb.0");
226
227
qdev_init_gpio_in(DEVICE(obj), via1_irq_request, VIA1_IRQ_NB);
228
}
229
diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
230
index XXXXXXX..XXXXXXX 100644
231
--- a/hw/misc/macio/cuda.c
232
+++ b/hw/misc/macio/cuda.c
233
@@ -XXX,XX +XXX,XX @@ static void cuda_init(Object *obj)
234
memory_region_init_io(&s->mem, obj, &mos6522_cuda_ops, s, "cuda", 0x2000);
235
sysbus_init_mmio(sbd, &s->mem);
236
237
- qbus_create_inplace(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
238
- DEVICE(obj), "adb.0");
239
+ qbus_init(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
240
+ DEVICE(obj), "adb.0");
241
}
242
243
static Property cuda_properties[] = {
244
diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
245
index XXXXXXX..XXXXXXX 100644
246
--- a/hw/misc/macio/macio.c
247
+++ b/hw/misc/macio/macio.c
248
@@ -XXX,XX +XXX,XX @@ static void macio_instance_init(Object *obj)
249
250
memory_region_init(&s->bar, obj, "macio", 0x80000);
251
252
- qbus_create_inplace(&s->macio_bus, sizeof(s->macio_bus), TYPE_MACIO_BUS,
253
- DEVICE(obj), "macio.0");
254
+ qbus_init(&s->macio_bus, sizeof(s->macio_bus), TYPE_MACIO_BUS,
255
+ DEVICE(obj), "macio.0");
256
257
object_initialize_child(OBJECT(s), "dbdma", &s->dbdma, TYPE_MAC_DBDMA);
258
259
diff --git a/hw/misc/macio/pmu.c b/hw/misc/macio/pmu.c
260
index XXXXXXX..XXXXXXX 100644
261
--- a/hw/misc/macio/pmu.c
262
+++ b/hw/misc/macio/pmu.c
263
@@ -XXX,XX +XXX,XX @@ static void pmu_realize(DeviceState *dev, Error **errp)
264
timer_mod(s->one_sec_timer, s->one_sec_target);
265
266
if (s->has_adb) {
267
- qbus_create_inplace(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
268
- dev, "adb.0");
269
+ qbus_init(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
270
+ dev, "adb.0");
271
adb_register_autopoll_callback(adb_bus, pmu_adb_poll, s);
272
}
273
}
274
diff --git a/hw/nubus/nubus-bridge.c b/hw/nubus/nubus-bridge.c
275
index XXXXXXX..XXXXXXX 100644
276
--- a/hw/nubus/nubus-bridge.c
277
+++ b/hw/nubus/nubus-bridge.c
278
@@ -XXX,XX +XXX,XX @@ static void nubus_bridge_init(Object *obj)
279
NubusBridge *s = NUBUS_BRIDGE(obj);
280
NubusBus *bus = &s->bus;
281
282
- qbus_create_inplace(bus, sizeof(s->bus), TYPE_NUBUS_BUS, DEVICE(s), NULL);
283
+ qbus_init(bus, sizeof(s->bus), TYPE_NUBUS_BUS, DEVICE(s), NULL);
284
285
qdev_init_gpio_out(DEVICE(s), bus->irqs, NUBUS_IRQS);
286
}
287
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
288
index XXXXXXX..XXXXXXX 100644
289
--- a/hw/nvme/ctrl.c
290
+++ b/hw/nvme/ctrl.c
291
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
53
return;
292
return;
54
}
293
}
55
294
56
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
295
- qbus_create_inplace(&n->bus, sizeof(NvmeBus), TYPE_NVME_BUS,
57
PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
296
- &pci_dev->qdev, n->parent_obj.qdev.id);
58
297
+ qbus_init(&n->bus, sizeof(NvmeBus), TYPE_NVME_BUS,
59
ptimer_transaction_begin(s->timer);
298
+ &pci_dev->qdev, n->parent_obj.qdev.id);
60
- ptimer_set_freq(s->timer, s->wdogclk_frq);
299
61
+ ptimer_set_period_from_clock(s->timer, s->wdogclk, 1);
300
nvme_init_state(n);
62
ptimer_transaction_commit(s->timer);
301
if (nvme_init_pci(n, pci_dev, errp)) {
63
}
302
diff --git a/hw/nvme/subsys.c b/hw/nvme/subsys.c
64
303
index XXXXXXX..XXXXXXX 100644
304
--- a/hw/nvme/subsys.c
305
+++ b/hw/nvme/subsys.c
306
@@ -XXX,XX +XXX,XX @@ static void nvme_subsys_realize(DeviceState *dev, Error **errp)
307
{
308
NvmeSubsystem *subsys = NVME_SUBSYS(dev);
309
310
- qbus_create_inplace(&subsys->bus, sizeof(NvmeBus), TYPE_NVME_BUS, dev,
311
- dev->id);
312
+ qbus_init(&subsys->bus, sizeof(NvmeBus), TYPE_NVME_BUS, dev, dev->id);
313
314
nvme_subsys_setup(subsys);
315
}
316
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
317
index XXXXXXX..XXXXXXX 100644
318
--- a/hw/pci/pci.c
319
+++ b/hw/pci/pci.c
320
@@ -XXX,XX +XXX,XX @@ void pci_root_bus_init(PCIBus *bus, size_t bus_size, DeviceState *parent,
321
MemoryRegion *address_space_io,
322
uint8_t devfn_min, const char *typename)
323
{
324
- qbus_create_inplace(bus, bus_size, typename, parent, name);
325
+ qbus_init(bus, bus_size, typename, parent, name);
326
pci_root_bus_internal_init(bus, parent, address_space_mem,
327
address_space_io, devfn_min);
328
}
329
diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
330
index XXXXXXX..XXXXXXX 100644
331
--- a/hw/pci/pci_bridge.c
332
+++ b/hw/pci/pci_bridge.c
333
@@ -XXX,XX +XXX,XX @@ void pci_bridge_initfn(PCIDevice *dev, const char *typename)
334
br->bus_name = dev->qdev.id;
335
}
336
337
- qbus_create_inplace(sec_bus, sizeof(br->sec_bus), typename, DEVICE(dev),
338
- br->bus_name);
339
+ qbus_init(sec_bus, sizeof(br->sec_bus), typename, DEVICE(dev),
340
+ br->bus_name);
341
sec_bus->parent_dev = dev;
342
sec_bus->map_irq = br->map_irq ? br->map_irq : pci_swizzle_map_irq_fn;
343
sec_bus->address_space_mem = &br->address_space_mem;
344
diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
345
index XXXXXXX..XXXXXXX 100644
346
--- a/hw/s390x/event-facility.c
347
+++ b/hw/s390x/event-facility.c
348
@@ -XXX,XX +XXX,XX @@ static void init_event_facility(Object *obj)
349
sclp_event_set_allow_all_mask_sizes);
350
351
/* Spawn a new bus for SCLP events */
352
- qbus_create_inplace(&event_facility->sbus, sizeof(event_facility->sbus),
353
- TYPE_SCLP_EVENTS_BUS, sdev, NULL);
354
+ qbus_init(&event_facility->sbus, sizeof(event_facility->sbus),
355
+ TYPE_SCLP_EVENTS_BUS, sdev, NULL);
356
357
object_initialize_child(obj, TYPE_SCLP_QUIESCE,
358
&event_facility->quiesce,
359
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
360
index XXXXXXX..XXXXXXX 100644
361
--- a/hw/s390x/virtio-ccw.c
362
+++ b/hw/s390x/virtio-ccw.c
363
@@ -XXX,XX +XXX,XX @@ static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
364
DeviceState *qdev = DEVICE(dev);
365
char virtio_bus_name[] = "virtio-bus";
366
367
- qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_CCW_BUS,
368
- qdev, virtio_bus_name);
369
+ qbus_init(bus, bus_size, TYPE_VIRTIO_CCW_BUS, qdev, virtio_bus_name);
370
}
371
372
static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data)
373
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
374
index XXXXXXX..XXXXXXX 100644
375
--- a/hw/scsi/scsi-bus.c
376
+++ b/hw/scsi/scsi-bus.c
377
@@ -XXX,XX +XXX,XX @@ void scsi_device_unit_attention_reported(SCSIDevice *s)
378
void scsi_bus_init_named(SCSIBus *bus, size_t bus_size, DeviceState *host,
379
const SCSIBusInfo *info, const char *bus_name)
380
{
381
- qbus_create_inplace(bus, bus_size, TYPE_SCSI_BUS, host, bus_name);
382
+ qbus_init(bus, bus_size, TYPE_SCSI_BUS, host, bus_name);
383
bus->busnr = next_scsi_bus++;
384
bus->info = info;
385
qbus_set_bus_hotplug_handler(BUS(bus));
386
diff --git a/hw/sd/allwinner-sdhost.c b/hw/sd/allwinner-sdhost.c
387
index XXXXXXX..XXXXXXX 100644
388
--- a/hw/sd/allwinner-sdhost.c
389
+++ b/hw/sd/allwinner-sdhost.c
390
@@ -XXX,XX +XXX,XX @@ static void allwinner_sdhost_init(Object *obj)
391
{
392
AwSdHostState *s = AW_SDHOST(obj);
393
394
- qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
395
- TYPE_AW_SDHOST_BUS, DEVICE(s), "sd-bus");
396
+ qbus_init(&s->sdbus, sizeof(s->sdbus),
397
+ TYPE_AW_SDHOST_BUS, DEVICE(s), "sd-bus");
398
399
memory_region_init_io(&s->iomem, obj, &allwinner_sdhost_ops, s,
400
TYPE_AW_SDHOST, 4 * KiB);
401
diff --git a/hw/sd/bcm2835_sdhost.c b/hw/sd/bcm2835_sdhost.c
402
index XXXXXXX..XXXXXXX 100644
403
--- a/hw/sd/bcm2835_sdhost.c
404
+++ b/hw/sd/bcm2835_sdhost.c
405
@@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_init(Object *obj)
406
{
407
BCM2835SDHostState *s = BCM2835_SDHOST(obj);
408
409
- qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
410
- TYPE_BCM2835_SDHOST_BUS, DEVICE(s), "sd-bus");
411
+ qbus_init(&s->sdbus, sizeof(s->sdbus),
412
+ TYPE_BCM2835_SDHOST_BUS, DEVICE(s), "sd-bus");
413
414
memory_region_init_io(&s->iomem, obj, &bcm2835_sdhost_ops, s,
415
TYPE_BCM2835_SDHOST, 0x1000);
416
diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
417
index XXXXXXX..XXXXXXX 100644
418
--- a/hw/sd/pl181.c
419
+++ b/hw/sd/pl181.c
420
@@ -XXX,XX +XXX,XX @@ static void pl181_init(Object *obj)
421
qdev_init_gpio_out_named(dev, &s->card_readonly, "card-read-only", 1);
422
qdev_init_gpio_out_named(dev, &s->card_inserted, "card-inserted", 1);
423
424
- qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
425
- TYPE_PL181_BUS, dev, "sd-bus");
426
+ qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_PL181_BUS, dev, "sd-bus");
427
}
428
429
static void pl181_class_init(ObjectClass *klass, void *data)
430
diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c
431
index XXXXXXX..XXXXXXX 100644
432
--- a/hw/sd/pxa2xx_mmci.c
433
+++ b/hw/sd/pxa2xx_mmci.c
434
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_mmci_instance_init(Object *obj)
435
qdev_init_gpio_out_named(dev, &s->rx_dma, "rx-dma", 1);
436
qdev_init_gpio_out_named(dev, &s->tx_dma, "tx-dma", 1);
437
438
- qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
439
- TYPE_PXA2XX_MMCI_BUS, DEVICE(obj), "sd-bus");
440
+ qbus_init(&s->sdbus, sizeof(s->sdbus),
441
+ TYPE_PXA2XX_MMCI_BUS, DEVICE(obj), "sd-bus");
442
}
443
444
static void pxa2xx_mmci_class_init(ObjectClass *klass, void *data)
445
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
446
index XXXXXXX..XXXXXXX 100644
447
--- a/hw/sd/sdhci.c
448
+++ b/hw/sd/sdhci.c
449
@@ -XXX,XX +XXX,XX @@ static void sdhci_init_readonly_registers(SDHCIState *s, Error **errp)
450
451
void sdhci_initfn(SDHCIState *s)
452
{
453
- qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
454
- TYPE_SDHCI_BUS, DEVICE(s), "sd-bus");
455
+ qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_SDHCI_BUS, DEVICE(s), "sd-bus");
456
457
s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s);
458
s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, s);
459
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
460
index XXXXXXX..XXXXXXX 100644
461
--- a/hw/sd/ssi-sd.c
462
+++ b/hw/sd/ssi-sd.c
463
@@ -XXX,XX +XXX,XX @@ static void ssi_sd_realize(SSIPeripheral *d, Error **errp)
464
DeviceState *carddev;
465
DriveInfo *dinfo;
466
467
- qbus_create_inplace(&s->sdbus, sizeof(s->sdbus), TYPE_SD_BUS,
468
- DEVICE(d), "sd-bus");
469
+ qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_SD_BUS, DEVICE(d), "sd-bus");
470
471
/* Create and plug in the sd card */
472
/* FIXME use a qdev drive property instead of drive_get_next() */
473
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
474
index XXXXXXX..XXXXXXX 100644
475
--- a/hw/usb/bus.c
476
+++ b/hw/usb/bus.c
477
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_usb_device = {
478
void usb_bus_new(USBBus *bus, size_t bus_size,
479
USBBusOps *ops, DeviceState *host)
480
{
481
- qbus_create_inplace(bus, bus_size, TYPE_USB_BUS, host, NULL);
482
+ qbus_init(bus, bus_size, TYPE_USB_BUS, host, NULL);
483
qbus_set_bus_hotplug_handler(BUS(bus));
484
bus->ops = ops;
485
bus->busnr = next_usb_bus++;
486
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
487
index XXXXXXX..XXXXXXX 100644
488
--- a/hw/usb/dev-smartcard-reader.c
489
+++ b/hw/usb/dev-smartcard-reader.c
490
@@ -XXX,XX +XXX,XX @@ static void ccid_realize(USBDevice *dev, Error **errp)
491
492
usb_desc_create_serial(dev);
493
usb_desc_init(dev);
494
- qbus_create_inplace(&s->bus, sizeof(s->bus), TYPE_CCID_BUS, DEVICE(dev),
495
- NULL);
496
+ qbus_init(&s->bus, sizeof(s->bus), TYPE_CCID_BUS, DEVICE(dev), NULL);
497
qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(dev));
498
s->intr = usb_ep_get(dev, USB_TOKEN_IN, CCID_INT_IN_EP);
499
s->bulk = usb_ep_get(dev, USB_TOKEN_IN, CCID_BULK_IN_EP);
500
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
501
index XXXXXXX..XXXXXXX 100644
502
--- a/hw/virtio/virtio-mmio.c
503
+++ b/hw/virtio/virtio-mmio.c
504
@@ -XXX,XX +XXX,XX @@ static void virtio_mmio_realizefn(DeviceState *d, Error **errp)
505
VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
506
SysBusDevice *sbd = SYS_BUS_DEVICE(d);
507
508
- qbus_create_inplace(&proxy->bus, sizeof(proxy->bus), TYPE_VIRTIO_MMIO_BUS,
509
- d, NULL);
510
+ qbus_init(&proxy->bus, sizeof(proxy->bus), TYPE_VIRTIO_MMIO_BUS, d, NULL);
511
sysbus_init_irq(sbd, &proxy->irq);
512
513
if (!kvm_eventfds_enabled()) {
514
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
515
index XXXXXXX..XXXXXXX 100644
516
--- a/hw/virtio/virtio-pci.c
517
+++ b/hw/virtio/virtio-pci.c
518
@@ -XXX,XX +XXX,XX @@ static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
519
DeviceState *qdev = DEVICE(dev);
520
char virtio_bus_name[] = "virtio-bus";
521
522
- qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_PCI_BUS, qdev,
523
- virtio_bus_name);
524
+ qbus_init(bus, bus_size, TYPE_VIRTIO_PCI_BUS, qdev, virtio_bus_name);
525
}
526
527
static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
65
--
528
--
66
2.20.1
529
2.20.1
67
530
68
531
diff view generated by jsdifflib
1
Use the MAINCLK Clock input to set the system_clock_scale variable
1
Rename the "allocate and return" qbus creation function to
2
rather than using the mainclk_frq property.
2
qbus_new(), to bring it into line with our _init vs _new convention.
3
3
4
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é <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
Reviewed-by: Corey Minyard <cminyard@mvista.com>
8
Message-id: 20210128114145.20536-23-peter.maydell@linaro.org
8
Message-id: 20210923121153.23754-6-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-23-peter.maydell@linaro.org
10
---
9
---
11
hw/arm/armsse.c | 24 +++++++++++++++++++-----
10
include/hw/qdev-core.h | 2 +-
12
1 file changed, 19 insertions(+), 5 deletions(-)
11
hw/core/bus.c | 2 +-
13
12
hw/hyperv/vmbus.c | 2 +-
14
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
13
hw/i2c/core.c | 2 +-
15
index XXXXXXX..XXXXXXX 100644
14
hw/isa/isa-bus.c | 2 +-
16
--- a/hw/arm/armsse.c
15
hw/misc/auxbus.c | 2 +-
17
+++ b/hw/arm/armsse.c
16
hw/pci/pci.c | 2 +-
18
@@ -XXX,XX +XXX,XX @@ static void armsse_forward_sec_resp_cfg(ARMSSE *s)
17
hw/ppc/spapr_vio.c | 2 +-
19
qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
18
hw/s390x/ap-bridge.c | 2 +-
19
hw/s390x/css-bridge.c | 2 +-
20
hw/s390x/s390-pci-bus.c | 2 +-
21
hw/ssi/ssi.c | 2 +-
22
hw/xen/xen-bus.c | 2 +-
23
hw/xen/xen-legacy-backend.c | 2 +-
24
14 files changed, 14 insertions(+), 14 deletions(-)
25
26
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/qdev-core.h
29
+++ b/include/hw/qdev-core.h
30
@@ -XXX,XX +XXX,XX @@ typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque);
31
32
void qbus_init(void *bus, size_t size, const char *typename,
33
DeviceState *parent, const char *name);
34
-BusState *qbus_create(const char *typename, DeviceState *parent, const char *name);
35
+BusState *qbus_new(const char *typename, DeviceState *parent, const char *name);
36
bool qbus_realize(BusState *bus, Error **errp);
37
void qbus_unrealize(BusState *bus);
38
39
diff --git a/hw/core/bus.c b/hw/core/bus.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/core/bus.c
42
+++ b/hw/core/bus.c
43
@@ -XXX,XX +XXX,XX @@ void qbus_init(void *bus, size_t size, const char *typename,
44
qbus_init_internal(bus, parent, name);
20
}
45
}
21
46
22
+static void armsse_mainclk_update(void *opaque)
47
-BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
23
+{
48
+BusState *qbus_new(const char *typename, DeviceState *parent, const char *name)
24
+ ARMSSE *s = ARM_SSE(opaque);
49
{
25
+ /*
50
BusState *bus;
26
+ * Set system_clock_scale from our Clock input; this is what
51
27
+ * controls the tick rate of the CPU SysTick timer.
52
diff --git a/hw/hyperv/vmbus.c b/hw/hyperv/vmbus.c
28
+ */
53
index XXXXXXX..XXXXXXX 100644
29
+ system_clock_scale = clock_ticks_to_ns(s->mainclk, 1);
54
--- a/hw/hyperv/vmbus.c
30
+}
55
+++ b/hw/hyperv/vmbus.c
31
+
56
@@ -XXX,XX +XXX,XX @@ static void vmbus_bridge_realize(DeviceState *dev, Error **errp)
32
static void armsse_init(Object *obj)
33
{
34
ARMSSE *s = ARM_SSE(obj);
35
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
36
assert(info->sram_banks <= MAX_SRAM_BANKS);
37
assert(info->num_cpus <= SSE_MAX_CPUS);
38
39
- s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK", NULL, NULL);
40
+ s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK",
41
+ armsse_mainclk_update, s);
42
s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL);
43
44
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
45
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
46
return;
57
return;
47
}
58
}
48
59
49
- if (!s->mainclk_frq) {
60
- bridge->bus = VMBUS(qbus_create(TYPE_VMBUS, dev, "vmbus"));
50
- error_setg(errp, "MAINCLK_FRQ property was not set");
61
+ bridge->bus = VMBUS(qbus_new(TYPE_VMBUS, dev, "vmbus"));
51
- return;
62
}
52
+ if (!clock_has_source(s->mainclk)) {
63
53
+ error_setg(errp, "MAINCLK clock was not connected");
64
static char *vmbus_bridge_ofw_unit_address(const SysBusDevice *dev)
54
+ }
65
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
55
+ if (!clock_has_source(s->s32kclk)) {
66
index XXXXXXX..XXXXXXX 100644
56
+ error_setg(errp, "S32KCLK clock was not connected");
67
--- a/hw/i2c/core.c
68
+++ b/hw/i2c/core.c
69
@@ -XXX,XX +XXX,XX @@ I2CBus *i2c_init_bus(DeviceState *parent, const char *name)
70
{
71
I2CBus *bus;
72
73
- bus = I2C_BUS(qbus_create(TYPE_I2C_BUS, parent, name));
74
+ bus = I2C_BUS(qbus_new(TYPE_I2C_BUS, parent, name));
75
QLIST_INIT(&bus->current_devs);
76
vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_i2c_bus, bus);
77
return bus;
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);
57
}
84
}
58
85
59
assert(info->num_cpus <= SSE_MAX_CPUS);
86
- isabus = ISA_BUS(qbus_create(TYPE_ISA_BUS, dev, NULL));
60
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
87
+ isabus = ISA_BUS(qbus_new(TYPE_ISA_BUS, dev, NULL));
61
*/
88
isabus->address_space = address_space;
62
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
89
isabus->address_space_io = address_space_io;
63
90
return isabus;
64
- system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
91
diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c
65
+ /* Set initial system_clock_scale from MAINCLK */
92
index XXXXXXX..XXXXXXX 100644
66
+ armsse_mainclk_update(s);
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);
67
}
180
}
68
181
69
static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
182
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
183
index XXXXXXX..XXXXXXX 100644
184
--- a/hw/xen/xen-bus.c
185
+++ b/hw/xen/xen-bus.c
186
@@ -XXX,XX +XXX,XX @@ type_init(xen_register_types)
187
void xen_bus_init(void)
188
{
189
DeviceState *dev = qdev_new(TYPE_XEN_BRIDGE);
190
- BusState *bus = qbus_create(TYPE_XEN_BUS, dev, NULL);
191
+ BusState *bus = qbus_new(TYPE_XEN_BUS, dev, NULL);
192
193
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
194
qbus_set_bus_hotplug_handler(bus);
195
diff --git a/hw/xen/xen-legacy-backend.c b/hw/xen/xen-legacy-backend.c
196
index XXXXXXX..XXXXXXX 100644
197
--- a/hw/xen/xen-legacy-backend.c
198
+++ b/hw/xen/xen-legacy-backend.c
199
@@ -XXX,XX +XXX,XX @@ int xen_be_init(void)
200
201
xen_sysdev = qdev_new(TYPE_XENSYSDEV);
202
sysbus_realize_and_unref(SYS_BUS_DEVICE(xen_sysdev), &error_fatal);
203
- xen_sysbus = qbus_create(TYPE_XENSYSBUS, xen_sysdev, "xen-sysbus");
204
+ xen_sysbus = qbus_new(TYPE_XENSYSBUS, xen_sysdev, "xen-sysbus");
205
qbus_set_bus_hotplug_handler(xen_sysbus);
206
207
return 0;
70
--
208
--
71
2.20.1
209
2.20.1
72
210
73
211
diff view generated by jsdifflib
1
Now that the CMSDK APB watchdog uses its Clock input, it will
1
The function ide_bus_new() does an in-place initialization. Rename
2
correctly respond when the system clock frequency is changed using
2
it to ide_bus_init() to follow our _init vs _new convention.
3
the RCC register on in the Stellaris board system registers. Test
4
that when the RCC register is written it causes the watchdog timer to
5
change speed.
6
3
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Luc Michel <luc@lmichel.fr>
6
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
10
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Corey Minyard <cminyard@mvista.com>
11
Message-id: 20210128114145.20536-22-peter.maydell@linaro.org
8
Reviewed-by: John Snow <jsnow@redhat.com>
12
Message-id: 20210121190622.22000-22-peter.maydell@linaro.org
9
Acked-by: John Snow <jsnow@redhat.com> (Feel free to merge.)
10
Message-id: 20210923121153.23754-7-peter.maydell@linaro.org
13
---
11
---
14
tests/qtest/cmsdk-apb-watchdog-test.c | 52 +++++++++++++++++++++++++++
12
include/hw/ide/internal.h | 4 ++--
15
1 file changed, 52 insertions(+)
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(-)
16
24
17
diff --git a/tests/qtest/cmsdk-apb-watchdog-test.c b/tests/qtest/cmsdk-apb-watchdog-test.c
25
diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
18
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qtest/cmsdk-apb-watchdog-test.c
27
--- a/include/hw/ide/internal.h
20
+++ b/tests/qtest/cmsdk-apb-watchdog-test.c
28
+++ b/include/hw/ide/internal.h
21
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@ void ide_atapi_cmd(IDEState *s);
22
*/
30
void ide_atapi_cmd_reply_end(IDEState *s);
23
31
24
#include "qemu/osdep.h"
32
/* hw/ide/qdev.c */
25
+#include "qemu/bitops.h"
33
-void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
26
#include "libqtest-single.h"
34
- int bus_id, int max_units);
27
35
+void ide_bus_init(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
28
/*
36
+ int bus_id, int max_units);
29
@@ -XXX,XX +XXX,XX @@
37
IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);
30
#define WDOGMIS 0x14
38
31
#define WDOGLOCK 0xc00
39
int ide_handle_rw_error(IDEState *s, int error, int op);
32
40
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
33
+#define SSYS_BASE 0x400fe000
41
index XXXXXXX..XXXXXXX 100644
34
+#define RCC 0x60
42
--- a/hw/ide/ahci.c
35
+#define SYSDIV_SHIFT 23
43
+++ b/hw/ide/ahci.c
36
+#define SYSDIV_LENGTH 4
44
@@ -XXX,XX +XXX,XX @@ void ahci_realize(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports)
37
+
45
for (i = 0; i < s->ports; i++) {
38
static void test_watchdog(void)
46
AHCIDevice *ad = &s->dev[i];
47
48
- ide_bus_new(&ad->port, sizeof(ad->port), qdev, i, 1);
49
+ ide_bus_init(&ad->port, sizeof(ad->port), qdev, i, 1);
50
ide_init2(&ad->port, irqs[i]);
51
52
ad->hba = s;
53
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/ide/cmd646.c
56
+++ b/hw/ide/cmd646.c
57
@@ -XXX,XX +XXX,XX @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
58
59
qdev_init_gpio_in(ds, cmd646_set_irq, 2);
60
for (i = 0; i < 2; i++) {
61
- ide_bus_new(&d->bus[i], sizeof(d->bus[i]), ds, i, 2);
62
+ ide_bus_init(&d->bus[i], sizeof(d->bus[i]), ds, i, 2);
63
ide_init2(&d->bus[i], qdev_get_gpio_in(ds, i));
64
65
bmdma_init(&d->bus[i], &d->bmdma[i], d);
66
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/ide/isa.c
69
+++ b/hw/ide/isa.c
70
@@ -XXX,XX +XXX,XX @@ static void isa_ide_realizefn(DeviceState *dev, Error **errp)
71
ISADevice *isadev = ISA_DEVICE(dev);
72
ISAIDEState *s = ISA_IDE(dev);
73
74
- ide_bus_new(&s->bus, sizeof(s->bus), dev, 0, 2);
75
+ ide_bus_init(&s->bus, sizeof(s->bus), dev, 0, 2);
76
ide_init_ioport(&s->bus, isadev, s->iobase, s->iobase2);
77
isa_init_irq(isadev, &s->irq, s->isairq);
78
ide_init2(&s->bus, s->irq);
79
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/ide/macio.c
82
+++ b/hw/ide/macio.c
83
@@ -XXX,XX +XXX,XX @@ static void macio_ide_initfn(Object *obj)
84
SysBusDevice *d = SYS_BUS_DEVICE(obj);
85
MACIOIDEState *s = MACIO_IDE(obj);
86
87
- ide_bus_new(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
88
+ ide_bus_init(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
89
memory_region_init_io(&s->mem, obj, &pmac_ide_ops, s, "pmac-ide", 0x1000);
90
sysbus_init_mmio(d, &s->mem);
91
sysbus_init_irq(d, &s->real_ide_irq);
92
diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/ide/microdrive.c
95
+++ b/hw/ide/microdrive.c
96
@@ -XXX,XX +XXX,XX @@ static void microdrive_init(Object *obj)
39
{
97
{
40
g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
98
MicroDriveState *md = MICRODRIVE(obj);
41
@@ -XXX,XX +XXX,XX @@ static void test_watchdog(void)
99
42
g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
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);
43
}
102
}
44
103
45
+static void test_clock_change(void)
104
static void microdrive_class_init(ObjectClass *oc, void *data)
46
+{
105
diff --git a/hw/ide/mmio.c b/hw/ide/mmio.c
47
+ uint32_t rcc;
106
index XXXXXXX..XXXXXXX 100644
48
+
107
--- a/hw/ide/mmio.c
49
+ /*
108
+++ b/hw/ide/mmio.c
50
+ * Test that writing to the stellaris board's RCC register to
109
@@ -XXX,XX +XXX,XX @@ static void mmio_ide_initfn(Object *obj)
51
+ * change the system clock frequency causes the watchdog
110
SysBusDevice *d = SYS_BUS_DEVICE(obj);
52
+ * to change the speed it counts at.
111
MMIOState *s = MMIO_IDE(obj);
53
+ */
112
54
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
113
- ide_bus_new(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
55
+
114
+ ide_bus_init(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
56
+ writel(WDOG_BASE + WDOGCONTROL, 1);
115
sysbus_init_irq(d, &s->irq);
57
+ writel(WDOG_BASE + WDOGLOAD, 1000);
116
}
58
+
117
59
+ /* Step to just past the 500th tick */
118
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
60
+ clock_step(80 * 500 + 1);
119
index XXXXXXX..XXXXXXX 100644
61
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
120
--- a/hw/ide/piix.c
62
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 500);
121
+++ b/hw/ide/piix.c
63
+
122
@@ -XXX,XX +XXX,XX @@ static int pci_piix_init_ports(PCIIDEState *d)
64
+ /* Rewrite RCC.SYSDIV from 16 to 8, so the clock is now 40ns per tick */
123
int i, ret;
65
+ rcc = readl(SSYS_BASE + RCC);
124
66
+ g_assert_cmpuint(extract32(rcc, SYSDIV_SHIFT, SYSDIV_LENGTH), ==, 0xf);
125
for (i = 0; i < 2; i++) {
67
+ rcc = deposit32(rcc, SYSDIV_SHIFT, SYSDIV_LENGTH, 7);
126
- ide_bus_new(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
68
+ writel(SSYS_BASE + RCC, rcc);
127
+ ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
69
+
128
ret = ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
70
+ /* Just past the 1000th tick: timer should have fired */
129
port_info[i].iobase2);
71
+ clock_step(40 * 500);
130
if (ret) {
72
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 1);
131
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
73
+
132
index XXXXXXX..XXXXXXX 100644
74
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 0);
133
--- a/hw/ide/qdev.c
75
+
134
+++ b/hw/ide/qdev.c
76
+ /* VALUE reloads at following tick */
135
@@ -XXX,XX +XXX,XX @@ static const TypeInfo ide_bus_info = {
77
+ clock_step(41);
136
.class_init = ide_bus_class_init,
78
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 1000);
137
};
79
+
138
80
+ /* Writing any value to WDOGINTCLR clears the interrupt and reloads */
139
-void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
81
+ clock_step(40 * 500);
140
+void ide_bus_init(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
82
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 500);
141
int bus_id, int max_units)
83
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 1);
84
+ writel(WDOG_BASE + WDOGINTCLR, 0);
85
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 1000);
86
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
87
+}
88
+
89
int main(int argc, char **argv)
90
{
142
{
91
int r;
143
qbus_init(idebus, idebus_size, TYPE_IDE_BUS, dev, NULL);
92
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
144
diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
93
qtest_start("-machine lm3s811evb");
145
index XXXXXXX..XXXXXXX 100644
94
146
--- a/hw/ide/sii3112.c
95
qtest_add_func("/cmsdk-apb-watchdog/watchdog", test_watchdog);
147
+++ b/hw/ide/sii3112.c
96
+ qtest_add_func("/cmsdk-apb-watchdog/watchdog_clock_change",
148
@@ -XXX,XX +XXX,XX @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
97
+ test_clock_change);
149
98
150
qdev_init_gpio_in(ds, sii3112_set_irq, 2);
99
r = g_test_run();
151
for (i = 0; i < 2; i++) {
100
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);
101
--
170
--
102
2.20.1
171
2.20.1
103
172
104
173
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Xuzhou Cheng <xuzhou.cheng@windriver.com>
2
2
3
cpu_get_phys_page_debug() uses 'DATA LOAD' MMU access type.
3
The Linux spi-imx driver does not work on QEMU. The reason is that the
4
state of m25p80 loops in STATE_READING_DATA state after receiving
5
RDSR command, the new command is ignored. Before sending a new command,
6
CS line should be pulled high to make the state of m25p80 back to IDLE.
4
7
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Currently the SPI flash CS line is connected to the SPI controller, but
6
Message-id: 20210127232822.3530782-1-f4bug@amsat.org
9
on the real board, it's connected to GPIO3_19. This matches the ecspi1
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
47
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
48
---
10
target/arm/helper.c | 2 +-
49
hw/arm/sabrelite.c | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
50
1 file changed, 1 insertion(+), 1 deletion(-)
12
51
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
52
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
14
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
54
--- a/hw/arm/sabrelite.c
16
+++ b/target/arm/helper.c
55
+++ b/hw/arm/sabrelite.c
17
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
56
@@ -XXX,XX +XXX,XX @@ static void sabrelite_init(MachineState *machine)
18
57
qdev_realize_and_unref(flash_dev, BUS(spi_bus), &error_fatal);
19
*attrs = (MemTxAttrs) {};
58
20
59
cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
21
- ret = get_phys_addr(env, addr, 0, mmu_idx, &phys_addr,
60
- sysbus_connect_irq(SYS_BUS_DEVICE(spi_dev), 1, cs_line);
22
+ ret = get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &phys_addr,
61
+ qdev_connect_gpio_out(DEVICE(&s->gpio[2]), 19, cs_line);
23
attrs, &prot, &page_size, &fi, &cacheattrs);
62
}
24
63
}
25
if (ret) {
64
}
26
--
65
--
27
2.20.1
66
2.20.1
28
67
29
68
diff view generated by jsdifflib
Deleted patch
1
Move the preadv availability check to meson.build. This is what we
2
want to be doing for host-OS-feature-checks anyway, but it also fixes
3
a problem with building for macOS with the most recent XCode SDK on a
4
Catalina host.
5
1
6
On that configuration, 'preadv()' is provided as a weak symbol, so
7
that programs can be built with optional support for it and make a
8
runtime availability check to see whether the preadv() they have is a
9
working one or one which they must not call because it will
10
runtime-assert. QEMU's configure test passes (unless you're building
11
with --enable-werror) because the test program using preadv()
12
compiles, but then QEMU crashes at runtime when preadv() is called,
13
with errors like:
14
15
dyld: lazy symbol binding failed: Symbol not found: _preadv
16
Referenced from: /Users/pm215/src/qemu/./build/x86/tests/test-replication
17
Expected in: /usr/lib/libSystem.B.dylib
18
19
dyld: Symbol not found: _preadv
20
Referenced from: /Users/pm215/src/qemu/./build/x86/tests/test-replication
21
Expected in: /usr/lib/libSystem.B.dylib
22
23
Meson's own function availability check has a special case for macOS
24
which adds '-Wl,-no_weak_imports' to the compiler flags, which forces
25
the test to require the real function, not the macOS-version-too-old
26
stub.
27
28
So this commit fixes the bug where macOS builds on Catalina currently
29
require --disable-werror.
30
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
33
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
34
Message-id: 20210126155846.17109-1-peter.maydell@linaro.org
35
---
36
configure | 16 ----------------
37
meson.build | 4 +++-
38
2 files changed, 3 insertions(+), 17 deletions(-)
39
40
diff --git a/configure b/configure
41
index XXXXXXX..XXXXXXX 100755
42
--- a/configure
43
+++ b/configure
44
@@ -XXX,XX +XXX,XX @@ if compile_prog "" "" ; then
45
iovec=yes
46
fi
47
48
-##########################################
49
-# preadv probe
50
-cat > $TMPC <<EOF
51
-#include <sys/types.h>
52
-#include <sys/uio.h>
53
-#include <unistd.h>
54
-int main(void) { return preadv(0, 0, 0, 0); }
55
-EOF
56
-preadv=no
57
-if compile_prog "" "" ; then
58
- preadv=yes
59
-fi
60
-
61
##########################################
62
# fdt probe
63
64
@@ -XXX,XX +XXX,XX @@ fi
65
if test "$iovec" = "yes" ; then
66
echo "CONFIG_IOVEC=y" >> $config_host_mak
67
fi
68
-if test "$preadv" = "yes" ; then
69
- echo "CONFIG_PREADV=y" >> $config_host_mak
70
-fi
71
if test "$membarrier" = "yes" ; then
72
echo "CONFIG_MEMBARRIER=y" >> $config_host_mak
73
fi
74
diff --git a/meson.build b/meson.build
75
index XXXXXXX..XXXXXXX 100644
76
--- a/meson.build
77
+++ b/meson.build
78
@@ -XXX,XX +XXX,XX @@ config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
79
config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
80
config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
81
82
+config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
83
+
84
ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
85
arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
86
strings = ['HOST_DSOSUF', 'CONFIG_IASL']
87
@@ -XXX,XX +XXX,XX @@ summary_info += {'PIE': get_option('b_pie')}
88
summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
89
summary_info += {'malloc trim support': has_malloc_trim}
90
summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
91
-summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')}
92
+summary_info += {'preadv support': config_host_data.get('CONFIG_PREADV')}
93
summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
94
summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
95
summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
96
--
97
2.20.1
98
99
diff view generated by jsdifflib
Deleted patch
1
From: Joelle van Dyne <j@getutm.app>
2
1
3
The iOS toolchain does not use the host prefix naming convention. So we
4
need to enable cross-compile options while allowing the PREFIX to be
5
blank.
6
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Joelle van Dyne <j@getutm.app>
9
Message-id: 20210126012457.39046-3-j@getutm.app
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
configure | 6 ++++--
13
1 file changed, 4 insertions(+), 2 deletions(-)
14
15
diff --git a/configure b/configure
16
index XXXXXXX..XXXXXXX 100755
17
--- a/configure
18
+++ b/configure
19
@@ -XXX,XX +XXX,XX @@ cpu=""
20
iasl="iasl"
21
interp_prefix="/usr/gnemul/qemu-%M"
22
static="no"
23
+cross_compile="no"
24
cross_prefix=""
25
audio_drv_list=""
26
block_drv_rw_whitelist=""
27
@@ -XXX,XX +XXX,XX @@ for opt do
28
optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
29
case "$opt" in
30
--cross-prefix=*) cross_prefix="$optarg"
31
+ cross_compile="yes"
32
;;
33
--cc=*) CC="$optarg"
34
;;
35
@@ -XXX,XX +XXX,XX @@ $(echo Deprecated targets: $deprecated_targets_list | \
36
--target-list-exclude=LIST exclude a set of targets from the default target-list
37
38
Advanced options (experts only):
39
- --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]
40
+ --cross-prefix=PREFIX use PREFIX for compile tools, PREFIX can be blank [$cross_prefix]
41
--cc=CC use C compiler CC [$cc]
42
--iasl=IASL use ACPI compiler IASL [$iasl]
43
--host-cc=CC use C compiler CC [$host_cc] for code run at
44
@@ -XXX,XX +XXX,XX @@ if has $sdl2_config; then
45
fi
46
echo "strip = [$(meson_quote $strip)]" >> $cross
47
echo "windres = [$(meson_quote $windres)]" >> $cross
48
-if test -n "$cross_prefix"; then
49
+if test "$cross_compile" = "yes"; then
50
cross_arg="--cross-file config-meson.cross"
51
echo "[host_machine]" >> $cross
52
if test "$mingw32" = "yes" ; then
53
--
54
2.20.1
55
56
diff view generated by jsdifflib
Deleted patch
1
From: Joelle van Dyne <j@getutm.app>
2
1
3
Meson will find CoreFoundation, IOKit, and Cocoa as needed.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Joelle van Dyne <j@getutm.app>
7
Message-id: 20210126012457.39046-7-j@getutm.app
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
configure | 1 -
11
1 file changed, 1 deletion(-)
12
13
diff --git a/configure b/configure
14
index XXXXXXX..XXXXXXX 100755
15
--- a/configure
16
+++ b/configure
17
@@ -XXX,XX +XXX,XX @@ Darwin)
18
fi
19
audio_drv_list="coreaudio try-sdl"
20
audio_possible_drivers="coreaudio sdl"
21
- QEMU_LDFLAGS="-framework CoreFoundation -framework IOKit $QEMU_LDFLAGS"
22
# Disable attempts to use ObjectiveC features in os/object.h since they
23
# won't work when we're compiling with gcc as a C compiler.
24
QEMU_CFLAGS="-DOS_OBJECT_USE_OBJC=0 $QEMU_CFLAGS"
25
--
26
2.20.1
27
28
diff view generated by jsdifflib
Deleted patch
1
From: Joelle van Dyne <j@getutm.app>
2
1
3
Add objc to the Meson cross file as well as detection of Darwin.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Joelle van Dyne <j@getutm.app>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210126012457.39046-8-j@getutm.app
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
configure | 4 ++++
12
1 file changed, 4 insertions(+)
13
14
diff --git a/configure b/configure
15
index XXXXXXX..XXXXXXX 100755
16
--- a/configure
17
+++ b/configure
18
@@ -XXX,XX +XXX,XX @@ echo "cpp_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross
19
echo "[binaries]" >> $cross
20
echo "c = [$(meson_quote $cc)]" >> $cross
21
test -n "$cxx" && echo "cpp = [$(meson_quote $cxx)]" >> $cross
22
+test -n "$objcc" && echo "objc = [$(meson_quote $objcc)]" >> $cross
23
echo "ar = [$(meson_quote $ar)]" >> $cross
24
echo "nm = [$(meson_quote $nm)]" >> $cross
25
echo "pkgconfig = [$(meson_quote $pkg_config_exe)]" >> $cross
26
@@ -XXX,XX +XXX,XX @@ if test "$cross_compile" = "yes"; then
27
if test "$linux" = "yes" ; then
28
echo "system = 'linux'" >> $cross
29
fi
30
+ if test "$darwin" = "yes" ; then
31
+ echo "system = 'darwin'" >> $cross
32
+ fi
33
case "$ARCH" in
34
i386|x86_64)
35
echo "cpu_family = 'x86'" >> $cross
36
--
37
2.20.1
38
39
diff view generated by jsdifflib
Deleted patch
1
From: Joelle van Dyne <j@getutm.app>
2
1
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
Signed-off-by: Joelle van Dyne <j@getutm.app>
5
Message-id: 20210126012457.39046-9-j@getutm.app
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
configure | 5 ++++-
9
1 file changed, 4 insertions(+), 1 deletion(-)
10
11
diff --git a/configure b/configure
12
index XXXXXXX..XXXXXXX 100755
13
--- a/configure
14
+++ b/configure
15
@@ -XXX,XX +XXX,XX @@ if test "$cross_compile" = "yes"; then
16
echo "system = 'darwin'" >> $cross
17
fi
18
case "$ARCH" in
19
- i386|x86_64)
20
+ i386)
21
echo "cpu_family = 'x86'" >> $cross
22
;;
23
+ x86_64)
24
+ echo "cpu_family = 'x86_64'" >> $cross
25
+ ;;
26
ppc64le)
27
echo "cpu_family = 'ppc64'" >> $cross
28
;;
29
--
30
2.20.1
31
32
diff view generated by jsdifflib
Deleted patch
1
From: Joelle van Dyne <j@getutm.app>
2
1
3
On iOS there is no CoreAudio, so we should not assume Darwin always
4
has it.
5
6
Signed-off-by: Joelle van Dyne <j@getutm.app>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210126012457.39046-11-j@getutm.app
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
configure | 35 +++++++++++++++++++++++++++++++++--
12
1 file changed, 33 insertions(+), 2 deletions(-)
13
14
diff --git a/configure b/configure
15
index XXXXXXX..XXXXXXX 100755
16
--- a/configure
17
+++ b/configure
18
@@ -XXX,XX +XXX,XX @@ fdt="auto"
19
netmap="no"
20
sdl="auto"
21
sdl_image="auto"
22
+coreaudio="auto"
23
virtiofsd="auto"
24
virtfs="auto"
25
libudev="auto"
26
@@ -XXX,XX +XXX,XX @@ Darwin)
27
QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
28
QEMU_LDFLAGS="-arch x86_64 $QEMU_LDFLAGS"
29
fi
30
- audio_drv_list="coreaudio try-sdl"
31
+ audio_drv_list="try-coreaudio try-sdl"
32
audio_possible_drivers="coreaudio sdl"
33
# Disable attempts to use ObjectiveC features in os/object.h since they
34
# won't work when we're compiling with gcc as a C compiler.
35
@@ -XXX,XX +XXX,XX @@ EOF
36
fi
37
fi
38
39
+##########################################
40
+# detect CoreAudio
41
+if test "$coreaudio" != "no" ; then
42
+ coreaudio_libs="-framework CoreAudio"
43
+ cat > $TMPC << EOF
44
+#include <CoreAudio/CoreAudio.h>
45
+int main(void)
46
+{
47
+ return (int)AudioGetCurrentHostTime();
48
+}
49
+EOF
50
+ if compile_prog "" "$coreaudio_libs" ; then
51
+ coreaudio=yes
52
+ else
53
+ coreaudio=no
54
+ fi
55
+fi
56
+
57
##########################################
58
# Sound support libraries probe
59
60
@@ -XXX,XX +XXX,XX @@ for drv in $audio_drv_list; do
61
fi
62
;;
63
64
- coreaudio)
65
+ coreaudio | try-coreaudio)
66
+ if test "$coreaudio" = "no"; then
67
+ if test "$drv" = "try-coreaudio"; then
68
+ audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-coreaudio//')
69
+ else
70
+ error_exit "$drv check failed" \
71
+ "Make sure to have the $drv is available."
72
+ fi
73
+ else
74
coreaudio_libs="-framework CoreAudio"
75
+ if test "$drv" = "try-coreaudio"; then
76
+ audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-coreaudio/coreaudio/')
77
+ fi
78
+ fi
79
;;
80
81
dsound)
82
--
83
2.20.1
84
85
diff view generated by jsdifflib
Deleted patch
1
From: Joelle van Dyne <j@getutm.app>
2
1
3
A workaround added in early days of 64-bit OSX forced x86_64 if the
4
host machine had 64-bit support. This creates issues when cross-
5
compiling for ARM64. Additionally, the user can always use --cpu=* to
6
manually set the host CPU and therefore this workaround should be
7
removed.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Joelle van Dyne <j@getutm.app>
11
Message-id: 20210126012457.39046-12-j@getutm.app
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
configure | 11 -----------
15
1 file changed, 11 deletions(-)
16
17
diff --git a/configure b/configure
18
index XXXXXXX..XXXXXXX 100755
19
--- a/configure
20
+++ b/configure
21
@@ -XXX,XX +XXX,XX @@ fi
22
# the correct CPU with the --cpu option.
23
case $targetos in
24
Darwin)
25
- # on Leopard most of the system is 32-bit, so we have to ask the kernel if we can
26
- # run 64-bit userspace code.
27
- # If the user didn't specify a CPU explicitly and the kernel says this is
28
- # 64 bit hw, then assume x86_64. Otherwise fall through to the usual detection code.
29
- if test -z "$cpu" && test "$(sysctl -n hw.optional.x86_64)" = "1"; then
30
- cpu="x86_64"
31
- fi
32
HOST_DSOSUF=".dylib"
33
;;
34
SunOS)
35
@@ -XXX,XX +XXX,XX @@ OpenBSD)
36
Darwin)
37
bsd="yes"
38
darwin="yes"
39
- if [ "$cpu" = "x86_64" ] ; then
40
- QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
41
- QEMU_LDFLAGS="-arch x86_64 $QEMU_LDFLAGS"
42
- fi
43
audio_drv_list="try-coreaudio try-sdl"
44
audio_possible_drivers="coreaudio sdl"
45
# Disable attempts to use ObjectiveC features in os/object.h since they
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
Deleted patch
1
From: Mihai Carabas <mihai.carabas@oracle.com>
2
1
3
Add pvpanic PCI device support details in docs/specs/pvpanic.txt.
4
5
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
docs/specs/pvpanic.txt | 13 ++++++++++++-
10
1 file changed, 12 insertions(+), 1 deletion(-)
11
12
diff --git a/docs/specs/pvpanic.txt b/docs/specs/pvpanic.txt
13
index XXXXXXX..XXXXXXX 100644
14
--- a/docs/specs/pvpanic.txt
15
+++ b/docs/specs/pvpanic.txt
16
@@ -XXX,XX +XXX,XX @@
17
PVPANIC DEVICE
18
==============
19
20
-pvpanic device is a simulated ISA device, through which a guest panic
21
+pvpanic device is a simulated device, through which a guest panic
22
event is sent to qemu, and a QMP event is generated. This allows
23
management apps (e.g. libvirt) to be notified and respond to the event.
24
25
@@ -XXX,XX +XXX,XX @@ The management app has the option of waiting for GUEST_PANICKED events,
26
and/or polling for guest-panicked RunState, to learn when the pvpanic
27
device has fired a panic event.
28
29
+The pvpanic device can be implemented as an ISA device (using IOPORT) or as a
30
+PCI device.
31
+
32
ISA Interface
33
-------------
34
35
@@ -XXX,XX +XXX,XX @@ bit 1: a guest panic has happened and will be handled by the guest;
36
the host should record it or report it, but should not affect
37
the execution of the guest.
38
39
+PCI Interface
40
+-------------
41
+
42
+The PCI interface is similar to the ISA interface except that it uses an MMIO
43
+address space provided by its BAR0, 1 byte long. Any machine with a PCI bus
44
+can enable a pvpanic device by adding '-device pvpanic-pci' to the command
45
+line.
46
+
47
ACPI Interface
48
--------------
49
50
--
51
2.20.1
52
53
diff view generated by jsdifflib
Deleted patch
1
Add a function for checking whether a clock has a source. This is
2
useful for devices which have input clocks that must be wired up by
3
the board as it allows them to fail in realize rather than ploughing
4
on with a zero-period clock.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20210128114145.20536-3-peter.maydell@linaro.org
11
Message-id: 20210121190622.22000-3-peter.maydell@linaro.org
12
---
13
docs/devel/clocks.rst | 16 ++++++++++++++++
14
include/hw/clock.h | 15 +++++++++++++++
15
2 files changed, 31 insertions(+)
16
17
diff --git a/docs/devel/clocks.rst b/docs/devel/clocks.rst
18
index XXXXXXX..XXXXXXX 100644
19
--- a/docs/devel/clocks.rst
20
+++ b/docs/devel/clocks.rst
21
@@ -XXX,XX +XXX,XX @@ object during device instance init. For example:
22
/* set initial value to 10ns / 100MHz */
23
clock_set_ns(clk, 10);
24
25
+To enforce that the clock is wired up by the board code, you can
26
+call ``clock_has_source()`` in your device's realize method:
27
+
28
+.. code-block:: c
29
+
30
+ if (!clock_has_source(s->clk)) {
31
+ error_setg(errp, "MyDevice: clk input must be connected");
32
+ return;
33
+ }
34
+
35
+Note that this only checks that the clock has been wired up; it is
36
+still possible that the output clock connected to it is disabled
37
+or has not yet been configured, in which case the period will be
38
+zero. You should use the clock callback to find out when the clock
39
+period changes.
40
+
41
Fetching clock frequency/period
42
-------------------------------
43
44
diff --git a/include/hw/clock.h b/include/hw/clock.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/include/hw/clock.h
47
+++ b/include/hw/clock.h
48
@@ -XXX,XX +XXX,XX @@ void clock_clear_callback(Clock *clk);
49
*/
50
void clock_set_source(Clock *clk, Clock *src);
51
52
+/**
53
+ * clock_has_source:
54
+ * @clk: the clock
55
+ *
56
+ * Returns true if the clock has a source clock connected to it.
57
+ * This is useful for devices which have input clocks which must
58
+ * be connected by the board/SoC code which creates them. The
59
+ * device code can use this to check in its realize method that
60
+ * the clock has been connected.
61
+ */
62
+static inline bool clock_has_source(const Clock *clk)
63
+{
64
+ return clk->source != NULL;
65
+}
66
+
67
/**
68
* clock_set:
69
* @clk: the clock to initialize.
70
--
71
2.20.1
72
73
diff view generated by jsdifflib
Deleted patch
1
Add a simple test of the CMSDK APB timer, since we're about to do
2
some refactoring of how it is clocked.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210128114145.20536-4-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-4-peter.maydell@linaro.org
10
---
11
tests/qtest/cmsdk-apb-timer-test.c | 75 ++++++++++++++++++++++++++++++
12
MAINTAINERS | 1 +
13
tests/qtest/meson.build | 1 +
14
3 files changed, 77 insertions(+)
15
create mode 100644 tests/qtest/cmsdk-apb-timer-test.c
16
17
diff --git a/tests/qtest/cmsdk-apb-timer-test.c b/tests/qtest/cmsdk-apb-timer-test.c
18
new file mode 100644
19
index XXXXXXX..XXXXXXX
20
--- /dev/null
21
+++ b/tests/qtest/cmsdk-apb-timer-test.c
22
@@ -XXX,XX +XXX,XX @@
23
+/*
24
+ * QTest testcase for the CMSDK APB timer device
25
+ *
26
+ * Copyright (c) 2021 Linaro Limited
27
+ *
28
+ * This program is free software; you can redistribute it and/or modify it
29
+ * under the terms of the GNU General Public License as published by the
30
+ * Free Software Foundation; either version 2 of the License, or
31
+ * (at your option) any later version.
32
+ *
33
+ * This program is distributed in the hope that it will be useful, but WITHOUT
34
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36
+ * for more details.
37
+ */
38
+
39
+#include "qemu/osdep.h"
40
+#include "libqtest-single.h"
41
+
42
+/* IoTKit/ARMSSE-200 timer0; driven at 25MHz in mps2-an385, so 40ns per tick */
43
+#define TIMER_BASE 0x40000000
44
+
45
+#define CTRL 0
46
+#define VALUE 4
47
+#define RELOAD 8
48
+#define INTSTATUS 0xc
49
+
50
+static void test_timer(void)
51
+{
52
+ g_assert_true(readl(TIMER_BASE + INTSTATUS) == 0);
53
+
54
+ /* Start timer: will fire after 40 * 1000 == 40000 ns */
55
+ writel(TIMER_BASE + RELOAD, 1000);
56
+ writel(TIMER_BASE + CTRL, 9);
57
+
58
+ /* Step to just past the 500th tick and check VALUE */
59
+ clock_step(40 * 500 + 1);
60
+ g_assert_cmpuint(readl(TIMER_BASE + INTSTATUS), ==, 0);
61
+ g_assert_cmpuint(readl(TIMER_BASE + VALUE), ==, 500);
62
+
63
+ /* Just past the 1000th tick: timer should have fired */
64
+ clock_step(40 * 500);
65
+ g_assert_cmpuint(readl(TIMER_BASE + INTSTATUS), ==, 1);
66
+ g_assert_cmpuint(readl(TIMER_BASE + VALUE), ==, 0);
67
+
68
+ /* VALUE reloads at the following tick */
69
+ clock_step(40);
70
+ g_assert_cmpuint(readl(TIMER_BASE + VALUE), ==, 1000);
71
+
72
+ /* Check write-1-to-clear behaviour of INTSTATUS */
73
+ writel(TIMER_BASE + INTSTATUS, 0);
74
+ g_assert_cmpuint(readl(TIMER_BASE + INTSTATUS), ==, 1);
75
+ writel(TIMER_BASE + INTSTATUS, 1);
76
+ g_assert_cmpuint(readl(TIMER_BASE + INTSTATUS), ==, 0);
77
+
78
+ /* Turn off the timer */
79
+ writel(TIMER_BASE + CTRL, 0);
80
+}
81
+
82
+int main(int argc, char **argv)
83
+{
84
+ int r;
85
+
86
+ g_test_init(&argc, &argv, NULL);
87
+
88
+ qtest_start("-machine mps2-an385");
89
+
90
+ qtest_add_func("/cmsdk-apb-timer/timer", test_timer);
91
+
92
+ r = g_test_run();
93
+
94
+ qtest_end();
95
+
96
+ return r;
97
+}
98
diff --git a/MAINTAINERS b/MAINTAINERS
99
index XXXXXXX..XXXXXXX 100644
100
--- a/MAINTAINERS
101
+++ b/MAINTAINERS
102
@@ -XXX,XX +XXX,XX @@ F: include/hw/rtc/pl031.h
103
F: include/hw/arm/primecell.h
104
F: hw/timer/cmsdk-apb-timer.c
105
F: include/hw/timer/cmsdk-apb-timer.h
106
+F: tests/qtest/cmsdk-apb-timer-test.c
107
F: hw/timer/cmsdk-apb-dualtimer.c
108
F: include/hw/timer/cmsdk-apb-dualtimer.h
109
F: hw/char/cmsdk-apb-uart.c
110
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
111
index XXXXXXX..XXXXXXX 100644
112
--- a/tests/qtest/meson.build
113
+++ b/tests/qtest/meson.build
114
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
115
'npcm7xx_timer-test',
116
'npcm7xx_watchdog_timer-test']
117
qtests_arm = \
118
+ (config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
119
(config_all_devices.has_key('CONFIG_PFLASH_CFI02') ? ['pflash-cfi02-test'] : []) + \
120
(config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
121
['arm-cpu-features',
122
--
123
2.20.1
124
125
diff view generated by jsdifflib
Deleted patch
1
Add a simple test of the CMSDK watchdog, since we're about to do some
2
refactoring of how it is clocked.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210128114145.20536-5-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-5-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
---
12
tests/qtest/cmsdk-apb-watchdog-test.c | 79 +++++++++++++++++++++++++++
13
MAINTAINERS | 1 +
14
tests/qtest/meson.build | 1 +
15
3 files changed, 81 insertions(+)
16
create mode 100644 tests/qtest/cmsdk-apb-watchdog-test.c
17
18
diff --git a/tests/qtest/cmsdk-apb-watchdog-test.c b/tests/qtest/cmsdk-apb-watchdog-test.c
19
new file mode 100644
20
index XXXXXXX..XXXXXXX
21
--- /dev/null
22
+++ b/tests/qtest/cmsdk-apb-watchdog-test.c
23
@@ -XXX,XX +XXX,XX @@
24
+/*
25
+ * QTest testcase for the CMSDK APB watchdog device
26
+ *
27
+ * Copyright (c) 2021 Linaro Limited
28
+ *
29
+ * This program is free software; you can redistribute it and/or modify it
30
+ * under the terms of the GNU General Public License as published by the
31
+ * Free Software Foundation; either version 2 of the License, or
32
+ * (at your option) any later version.
33
+ *
34
+ * This program is distributed in the hope that it will be useful, but WITHOUT
35
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
36
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37
+ * for more details.
38
+ */
39
+
40
+#include "qemu/osdep.h"
41
+#include "libqtest-single.h"
42
+
43
+/*
44
+ * lm3s811evb watchdog; at board startup this runs at 200MHz / 16 == 12.5MHz,
45
+ * which is 80ns per tick.
46
+ */
47
+#define WDOG_BASE 0x40000000
48
+
49
+#define WDOGLOAD 0
50
+#define WDOGVALUE 4
51
+#define WDOGCONTROL 8
52
+#define WDOGINTCLR 0xc
53
+#define WDOGRIS 0x10
54
+#define WDOGMIS 0x14
55
+#define WDOGLOCK 0xc00
56
+
57
+static void test_watchdog(void)
58
+{
59
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
60
+
61
+ writel(WDOG_BASE + WDOGCONTROL, 1);
62
+ writel(WDOG_BASE + WDOGLOAD, 1000);
63
+
64
+ /* Step to just past the 500th tick */
65
+ clock_step(500 * 80 + 1);
66
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
67
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 500);
68
+
69
+ /* Just past the 1000th tick: timer should have fired */
70
+ clock_step(500 * 80);
71
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 1);
72
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 0);
73
+
74
+ /* VALUE reloads at following tick */
75
+ clock_step(80);
76
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 1000);
77
+
78
+ /* Writing any value to WDOGINTCLR clears the interrupt and reloads */
79
+ clock_step(500 * 80);
80
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 500);
81
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 1);
82
+ writel(WDOG_BASE + WDOGINTCLR, 0);
83
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 1000);
84
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
85
+}
86
+
87
+int main(int argc, char **argv)
88
+{
89
+ int r;
90
+
91
+ g_test_init(&argc, &argv, NULL);
92
+
93
+ qtest_start("-machine lm3s811evb");
94
+
95
+ qtest_add_func("/cmsdk-apb-watchdog/watchdog", test_watchdog);
96
+
97
+ r = g_test_run();
98
+
99
+ qtest_end();
100
+
101
+ return r;
102
+}
103
diff --git a/MAINTAINERS b/MAINTAINERS
104
index XXXXXXX..XXXXXXX 100644
105
--- a/MAINTAINERS
106
+++ b/MAINTAINERS
107
@@ -XXX,XX +XXX,XX @@ F: hw/char/cmsdk-apb-uart.c
108
F: include/hw/char/cmsdk-apb-uart.h
109
F: hw/watchdog/cmsdk-apb-watchdog.c
110
F: include/hw/watchdog/cmsdk-apb-watchdog.h
111
+F: tests/qtest/cmsdk-apb-watchdog-test.c
112
F: hw/misc/tz-ppc.c
113
F: include/hw/misc/tz-ppc.h
114
F: hw/misc/tz-mpc.c
115
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
116
index XXXXXXX..XXXXXXX 100644
117
--- a/tests/qtest/meson.build
118
+++ b/tests/qtest/meson.build
119
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
120
'npcm7xx_watchdog_timer-test']
121
qtests_arm = \
122
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
123
+ (config_all_devices.has_key('CONFIG_CMSDK_APB_WATCHDOG') ? ['cmsdk-apb-watchdog-test'] : []) + \
124
(config_all_devices.has_key('CONFIG_PFLASH_CFI02') ? ['pflash-cfi02-test'] : []) + \
125
(config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
126
['arm-cpu-features',
127
--
128
2.20.1
129
130
diff view generated by jsdifflib
Deleted patch
1
Add a simple test of the CMSDK dual timer, since we're about to do
2
some refactoring of how it is clocked.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Message-id: 20210128114145.20536-6-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-6-peter.maydell@linaro.org
10
---
11
tests/qtest/cmsdk-apb-dualtimer-test.c | 130 +++++++++++++++++++++++++
12
MAINTAINERS | 1 +
13
tests/qtest/meson.build | 1 +
14
3 files changed, 132 insertions(+)
15
create mode 100644 tests/qtest/cmsdk-apb-dualtimer-test.c
16
17
diff --git a/tests/qtest/cmsdk-apb-dualtimer-test.c b/tests/qtest/cmsdk-apb-dualtimer-test.c
18
new file mode 100644
19
index XXXXXXX..XXXXXXX
20
--- /dev/null
21
+++ b/tests/qtest/cmsdk-apb-dualtimer-test.c
22
@@ -XXX,XX +XXX,XX @@
23
+/*
24
+ * QTest testcase for the CMSDK APB dualtimer device
25
+ *
26
+ * Copyright (c) 2021 Linaro Limited
27
+ *
28
+ * This program is free software; you can redistribute it and/or modify it
29
+ * under the terms of the GNU General Public License as published by the
30
+ * Free Software Foundation; either version 2 of the License, or
31
+ * (at your option) any later version.
32
+ *
33
+ * This program is distributed in the hope that it will be useful, but WITHOUT
34
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36
+ * for more details.
37
+ */
38
+
39
+#include "qemu/osdep.h"
40
+#include "libqtest-single.h"
41
+
42
+/* IoTKit/ARMSSE dualtimer; driven at 25MHz in mps2-an385, so 40ns per tick */
43
+#define TIMER_BASE 0x40002000
44
+
45
+#define TIMER1LOAD 0
46
+#define TIMER1VALUE 4
47
+#define TIMER1CONTROL 8
48
+#define TIMER1INTCLR 0xc
49
+#define TIMER1RIS 0x10
50
+#define TIMER1MIS 0x14
51
+#define TIMER1BGLOAD 0x18
52
+
53
+#define TIMER2LOAD 0x20
54
+#define TIMER2VALUE 0x24
55
+#define TIMER2CONTROL 0x28
56
+#define TIMER2INTCLR 0x2c
57
+#define TIMER2RIS 0x30
58
+#define TIMER2MIS 0x34
59
+#define TIMER2BGLOAD 0x38
60
+
61
+#define CTRL_ENABLE (1 << 7)
62
+#define CTRL_PERIODIC (1 << 6)
63
+#define CTRL_INTEN (1 << 5)
64
+#define CTRL_PRESCALE_1 (0 << 2)
65
+#define CTRL_PRESCALE_16 (1 << 2)
66
+#define CTRL_PRESCALE_256 (2 << 2)
67
+#define CTRL_32BIT (1 << 1)
68
+#define CTRL_ONESHOT (1 << 0)
69
+
70
+static void test_dualtimer(void)
71
+{
72
+ g_assert_true(readl(TIMER_BASE + TIMER1RIS) == 0);
73
+
74
+ /* Start timer: will fire after 40000 ns */
75
+ writel(TIMER_BASE + TIMER1LOAD, 1000);
76
+ /* enable in free-running, wrapping, interrupt mode */
77
+ writel(TIMER_BASE + TIMER1CONTROL, CTRL_ENABLE | CTRL_INTEN);
78
+
79
+ /* Step to just past the 500th tick and check VALUE */
80
+ clock_step(500 * 40 + 1);
81
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1RIS), ==, 0);
82
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1VALUE), ==, 500);
83
+
84
+ /* Just past the 1000th tick: timer should have fired */
85
+ clock_step(500 * 40);
86
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1RIS), ==, 1);
87
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1VALUE), ==, 0);
88
+
89
+ /*
90
+ * We are in free-running wrapping 16-bit mode, so on the following
91
+ * tick VALUE should have wrapped round to 0xffff.
92
+ */
93
+ clock_step(40);
94
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1VALUE), ==, 0xffff);
95
+
96
+ /* Check that any write to INTCLR clears interrupt */
97
+ writel(TIMER_BASE + TIMER1INTCLR, 1);
98
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1RIS), ==, 0);
99
+
100
+ /* Turn off the timer */
101
+ writel(TIMER_BASE + TIMER1CONTROL, 0);
102
+}
103
+
104
+static void test_prescale(void)
105
+{
106
+ g_assert_true(readl(TIMER_BASE + TIMER2RIS) == 0);
107
+
108
+ /* Start timer: will fire after 40 * 256 * 1000 == 1024000 ns */
109
+ writel(TIMER_BASE + TIMER2LOAD, 1000);
110
+ /* enable in periodic, wrapping, interrupt mode, prescale 256 */
111
+ writel(TIMER_BASE + TIMER2CONTROL,
112
+ CTRL_ENABLE | CTRL_INTEN | CTRL_PERIODIC | CTRL_PRESCALE_256);
113
+
114
+ /* Step to just past the 500th tick and check VALUE */
115
+ clock_step(40 * 256 * 501);
116
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2RIS), ==, 0);
117
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2VALUE), ==, 500);
118
+
119
+ /* Just past the 1000th tick: timer should have fired */
120
+ clock_step(40 * 256 * 500);
121
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2RIS), ==, 1);
122
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2VALUE), ==, 0);
123
+
124
+ /* In periodic mode the tick VALUE now reloads */
125
+ clock_step(40 * 256);
126
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2VALUE), ==, 1000);
127
+
128
+ /* Check that any write to INTCLR clears interrupt */
129
+ writel(TIMER_BASE + TIMER2INTCLR, 1);
130
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2RIS), ==, 0);
131
+
132
+ /* Turn off the timer */
133
+ writel(TIMER_BASE + TIMER2CONTROL, 0);
134
+}
135
+
136
+int main(int argc, char **argv)
137
+{
138
+ int r;
139
+
140
+ g_test_init(&argc, &argv, NULL);
141
+
142
+ qtest_start("-machine mps2-an385");
143
+
144
+ qtest_add_func("/cmsdk-apb-dualtimer/dualtimer", test_dualtimer);
145
+ qtest_add_func("/cmsdk-apb-dualtimer/prescale", test_prescale);
146
+
147
+ r = g_test_run();
148
+
149
+ qtest_end();
150
+
151
+ return r;
152
+}
153
diff --git a/MAINTAINERS b/MAINTAINERS
154
index XXXXXXX..XXXXXXX 100644
155
--- a/MAINTAINERS
156
+++ b/MAINTAINERS
157
@@ -XXX,XX +XXX,XX @@ F: include/hw/timer/cmsdk-apb-timer.h
158
F: tests/qtest/cmsdk-apb-timer-test.c
159
F: hw/timer/cmsdk-apb-dualtimer.c
160
F: include/hw/timer/cmsdk-apb-dualtimer.h
161
+F: tests/qtest/cmsdk-apb-dualtimer-test.c
162
F: hw/char/cmsdk-apb-uart.c
163
F: include/hw/char/cmsdk-apb-uart.h
164
F: hw/watchdog/cmsdk-apb-watchdog.c
165
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
166
index XXXXXXX..XXXXXXX 100644
167
--- a/tests/qtest/meson.build
168
+++ b/tests/qtest/meson.build
169
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
170
'npcm7xx_timer-test',
171
'npcm7xx_watchdog_timer-test']
172
qtests_arm = \
173
+ (config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
174
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
175
(config_all_devices.has_key('CONFIG_CMSDK_APB_WATCHDOG') ? ['cmsdk-apb-watchdog-test'] : []) + \
176
(config_all_devices.has_key('CONFIG_PFLASH_CFI02') ? ['pflash-cfi02-test'] : []) + \
177
--
178
2.20.1
179
180
diff view generated by jsdifflib
Deleted patch
1
The state struct for the CMSDK APB timer device doesn't follow our
2
usual naming convention of camelcase -- "CMSDK" and "APB" are both
3
acronyms, but "TIMER" is not so should not be all-uppercase.
4
Globally rename the struct to "CMSDKAPBTimer" (bringing it into line
5
with CMSDKAPBWatchdog and CMSDKAPBDualTimer; CMSDKAPBUART remains
6
as-is because "UART" is an acronym).
7
1
8
Commit created with:
9
perl -p -i -e 's/CMSDKAPBTIMER/CMSDKAPBTimer/g' hw/timer/cmsdk-apb-timer.c include/hw/arm/armsse.h include/hw/timer/cmsdk-apb-timer.h
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Luc Michel <luc@lmichel.fr>
14
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20210128114145.20536-7-peter.maydell@linaro.org
16
Message-id: 20210121190622.22000-7-peter.maydell@linaro.org
17
---
18
include/hw/arm/armsse.h | 6 +++---
19
include/hw/timer/cmsdk-apb-timer.h | 4 ++--
20
hw/timer/cmsdk-apb-timer.c | 28 ++++++++++++++--------------
21
3 files changed, 19 insertions(+), 19 deletions(-)
22
23
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/armsse.h
26
+++ b/include/hw/arm/armsse.h
27
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
28
TZPPC apb_ppc0;
29
TZPPC apb_ppc1;
30
TZMPC mpc[IOTS_NUM_MPC];
31
- CMSDKAPBTIMER timer0;
32
- CMSDKAPBTIMER timer1;
33
- CMSDKAPBTIMER s32ktimer;
34
+ CMSDKAPBTimer timer0;
35
+ CMSDKAPBTimer timer1;
36
+ CMSDKAPBTimer s32ktimer;
37
qemu_or_irq ppc_irq_orgate;
38
SplitIRQ sec_resp_splitter;
39
SplitIRQ ppc_irq_splitter[NUM_PPCS];
40
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/include/hw/timer/cmsdk-apb-timer.h
43
+++ b/include/hw/timer/cmsdk-apb-timer.h
44
@@ -XXX,XX +XXX,XX @@
45
#include "qom/object.h"
46
47
#define TYPE_CMSDK_APB_TIMER "cmsdk-apb-timer"
48
-OBJECT_DECLARE_SIMPLE_TYPE(CMSDKAPBTIMER, CMSDK_APB_TIMER)
49
+OBJECT_DECLARE_SIMPLE_TYPE(CMSDKAPBTimer, CMSDK_APB_TIMER)
50
51
-struct CMSDKAPBTIMER {
52
+struct CMSDKAPBTimer {
53
/*< private >*/
54
SysBusDevice parent_obj;
55
56
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/timer/cmsdk-apb-timer.c
59
+++ b/hw/timer/cmsdk-apb-timer.c
60
@@ -XXX,XX +XXX,XX @@ static const int timer_id[] = {
61
0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
62
};
63
64
-static void cmsdk_apb_timer_update(CMSDKAPBTIMER *s)
65
+static void cmsdk_apb_timer_update(CMSDKAPBTimer *s)
66
{
67
qemu_set_irq(s->timerint, !!(s->intstatus & R_INTSTATUS_IRQ_MASK));
68
}
69
70
static uint64_t cmsdk_apb_timer_read(void *opaque, hwaddr offset, unsigned size)
71
{
72
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);
73
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(opaque);
74
uint64_t r;
75
76
switch (offset) {
77
@@ -XXX,XX +XXX,XX @@ static uint64_t cmsdk_apb_timer_read(void *opaque, hwaddr offset, unsigned size)
78
static void cmsdk_apb_timer_write(void *opaque, hwaddr offset, uint64_t value,
79
unsigned size)
80
{
81
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);
82
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(opaque);
83
84
trace_cmsdk_apb_timer_write(offset, value, size);
85
86
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps cmsdk_apb_timer_ops = {
87
88
static void cmsdk_apb_timer_tick(void *opaque)
89
{
90
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);
91
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(opaque);
92
93
if (s->ctrl & R_CTRL_IRQEN_MASK) {
94
s->intstatus |= R_INTSTATUS_IRQ_MASK;
95
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_tick(void *opaque)
96
97
static void cmsdk_apb_timer_reset(DeviceState *dev)
98
{
99
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(dev);
100
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(dev);
101
102
trace_cmsdk_apb_timer_reset();
103
s->ctrl = 0;
104
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_reset(DeviceState *dev)
105
static void cmsdk_apb_timer_init(Object *obj)
106
{
107
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
108
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(obj);
109
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(obj);
110
111
memory_region_init_io(&s->iomem, obj, &cmsdk_apb_timer_ops,
112
s, "cmsdk-apb-timer", 0x1000);
113
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_init(Object *obj)
114
115
static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
116
{
117
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(dev);
118
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(dev);
119
120
if (s->pclk_frq == 0) {
121
error_setg(errp, "CMSDK APB timer: pclk-frq property must be set");
122
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription cmsdk_apb_timer_vmstate = {
123
.version_id = 1,
124
.minimum_version_id = 1,
125
.fields = (VMStateField[]) {
126
- VMSTATE_PTIMER(timer, CMSDKAPBTIMER),
127
- VMSTATE_UINT32(ctrl, CMSDKAPBTIMER),
128
- VMSTATE_UINT32(value, CMSDKAPBTIMER),
129
- VMSTATE_UINT32(reload, CMSDKAPBTIMER),
130
- VMSTATE_UINT32(intstatus, CMSDKAPBTIMER),
131
+ VMSTATE_PTIMER(timer, CMSDKAPBTimer),
132
+ VMSTATE_UINT32(ctrl, CMSDKAPBTimer),
133
+ VMSTATE_UINT32(value, CMSDKAPBTimer),
134
+ VMSTATE_UINT32(reload, CMSDKAPBTimer),
135
+ VMSTATE_UINT32(intstatus, CMSDKAPBTimer),
136
VMSTATE_END_OF_LIST()
137
}
138
};
139
140
static Property cmsdk_apb_timer_properties[] = {
141
- DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBTIMER, pclk_frq, 0),
142
+ DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBTimer, pclk_frq, 0),
143
DEFINE_PROP_END_OF_LIST(),
144
};
145
146
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_class_init(ObjectClass *klass, void *data)
147
static const TypeInfo cmsdk_apb_timer_info = {
148
.name = TYPE_CMSDK_APB_TIMER,
149
.parent = TYPE_SYS_BUS_DEVICE,
150
- .instance_size = sizeof(CMSDKAPBTIMER),
151
+ .instance_size = sizeof(CMSDKAPBTimer),
152
.instance_init = cmsdk_apb_timer_init,
153
.class_init = cmsdk_apb_timer_class_init,
154
};
155
--
156
2.20.1
157
158
diff view generated by jsdifflib
Deleted patch
1
As the first step in converting the CMSDK_APB_TIMER device to the
2
Clock framework, add a Clock input. For the moment we do nothing
3
with this clock; we will change the behaviour from using the pclk-frq
4
property to using the Clock once all the users of this device have
5
been converted to wire up the Clock.
6
1
7
Since the device doesn't already have a doc comment for its "QEMU
8
interface", we add one including the new Clock.
9
10
This is a migration compatibility break for machines mps2-an505,
11
mps2-an521, musca-a, musca-b1.
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Reviewed-by: Luc Michel <luc@lmichel.fr>
16
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Message-id: 20210128114145.20536-8-peter.maydell@linaro.org
18
Message-id: 20210121190622.22000-8-peter.maydell@linaro.org
19
---
20
include/hw/timer/cmsdk-apb-timer.h | 9 +++++++++
21
hw/timer/cmsdk-apb-timer.c | 7 +++++--
22
2 files changed, 14 insertions(+), 2 deletions(-)
23
24
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/timer/cmsdk-apb-timer.h
27
+++ b/include/hw/timer/cmsdk-apb-timer.h
28
@@ -XXX,XX +XXX,XX @@
29
#include "hw/qdev-properties.h"
30
#include "hw/sysbus.h"
31
#include "hw/ptimer.h"
32
+#include "hw/clock.h"
33
#include "qom/object.h"
34
35
#define TYPE_CMSDK_APB_TIMER "cmsdk-apb-timer"
36
OBJECT_DECLARE_SIMPLE_TYPE(CMSDKAPBTimer, CMSDK_APB_TIMER)
37
38
+/*
39
+ * QEMU interface:
40
+ * + QOM property "pclk-frq": frequency at which the timer is clocked
41
+ * + Clock input "pclk": clock for the timer
42
+ * + sysbus MMIO region 0: the register bank
43
+ * + sysbus IRQ 0: timer interrupt TIMERINT
44
+ */
45
struct CMSDKAPBTimer {
46
/*< private >*/
47
SysBusDevice parent_obj;
48
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBTimer {
49
qemu_irq timerint;
50
uint32_t pclk_frq;
51
struct ptimer_state *timer;
52
+ Clock *pclk;
53
54
uint32_t ctrl;
55
uint32_t value;
56
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/timer/cmsdk-apb-timer.c
59
+++ b/hw/timer/cmsdk-apb-timer.c
60
@@ -XXX,XX +XXX,XX @@
61
#include "hw/sysbus.h"
62
#include "hw/irq.h"
63
#include "hw/registerfields.h"
64
+#include "hw/qdev-clock.h"
65
#include "hw/timer/cmsdk-apb-timer.h"
66
#include "migration/vmstate.h"
67
68
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_init(Object *obj)
69
s, "cmsdk-apb-timer", 0x1000);
70
sysbus_init_mmio(sbd, &s->iomem);
71
sysbus_init_irq(sbd, &s->timerint);
72
+ s->pclk = qdev_init_clock_in(DEVICE(s), "pclk", NULL, NULL);
73
}
74
75
static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
76
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
77
78
static const VMStateDescription cmsdk_apb_timer_vmstate = {
79
.name = "cmsdk-apb-timer",
80
- .version_id = 1,
81
- .minimum_version_id = 1,
82
+ .version_id = 2,
83
+ .minimum_version_id = 2,
84
.fields = (VMStateField[]) {
85
VMSTATE_PTIMER(timer, CMSDKAPBTimer),
86
+ VMSTATE_CLOCK(pclk, CMSDKAPBTimer),
87
VMSTATE_UINT32(ctrl, CMSDKAPBTimer),
88
VMSTATE_UINT32(value, CMSDKAPBTimer),
89
VMSTATE_UINT32(reload, CMSDKAPBTimer),
90
--
91
2.20.1
92
93
diff view generated by jsdifflib
Deleted patch
1
As the first step in converting the CMSDK_APB_DUALTIMER device to the
2
Clock framework, add a Clock input. For the moment we do nothing
3
with this clock; we will change the behaviour from using the pclk-frq
4
property to using the Clock once all the users of this device have
5
been converted to wire up the Clock.
6
1
7
We take the opportunity to correct the name of the clock input to
8
match the hardware -- the dual timer names the clock which drives the
9
timers TIMCLK. (It does also have a 'pclk' input, which is used only
10
for the register and APB bus logic; on the SSE-200 these clocks are
11
both connected together.)
12
13
This is a migration compatibility break for machines mps2-an385,
14
mps2-an386, mps2-an500, mps2-an511, mps2-an505, mps2-an521, musca-a,
15
musca-b1.
16
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Reviewed-by: Luc Michel <luc@lmichel.fr>
20
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20210128114145.20536-9-peter.maydell@linaro.org
22
Message-id: 20210121190622.22000-9-peter.maydell@linaro.org
23
---
24
include/hw/timer/cmsdk-apb-dualtimer.h | 3 +++
25
hw/timer/cmsdk-apb-dualtimer.c | 7 +++++--
26
2 files changed, 8 insertions(+), 2 deletions(-)
27
28
diff --git a/include/hw/timer/cmsdk-apb-dualtimer.h b/include/hw/timer/cmsdk-apb-dualtimer.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/timer/cmsdk-apb-dualtimer.h
31
+++ b/include/hw/timer/cmsdk-apb-dualtimer.h
32
@@ -XXX,XX +XXX,XX @@
33
*
34
* QEMU interface:
35
* + QOM property "pclk-frq": frequency at which the timer is clocked
36
+ * + Clock input "TIMCLK": clock (for both timers)
37
* + sysbus MMIO region 0: the register bank
38
* + sysbus IRQ 0: combined timer interrupt TIMINTC
39
* + sysbus IRO 1: timer block 1 interrupt TIMINT1
40
@@ -XXX,XX +XXX,XX @@
41
42
#include "hw/sysbus.h"
43
#include "hw/ptimer.h"
44
+#include "hw/clock.h"
45
#include "qom/object.h"
46
47
#define TYPE_CMSDK_APB_DUALTIMER "cmsdk-apb-dualtimer"
48
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBDualTimer {
49
MemoryRegion iomem;
50
qemu_irq timerintc;
51
uint32_t pclk_frq;
52
+ Clock *timclk;
53
54
CMSDKAPBDualTimerModule timermod[CMSDK_APB_DUALTIMER_NUM_MODULES];
55
uint32_t timeritcr;
56
diff --git a/hw/timer/cmsdk-apb-dualtimer.c b/hw/timer/cmsdk-apb-dualtimer.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/timer/cmsdk-apb-dualtimer.c
59
+++ b/hw/timer/cmsdk-apb-dualtimer.c
60
@@ -XXX,XX +XXX,XX @@
61
#include "hw/irq.h"
62
#include "hw/qdev-properties.h"
63
#include "hw/registerfields.h"
64
+#include "hw/qdev-clock.h"
65
#include "hw/timer/cmsdk-apb-dualtimer.h"
66
#include "migration/vmstate.h"
67
68
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_init(Object *obj)
69
for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
70
sysbus_init_irq(sbd, &s->timermod[i].timerint);
71
}
72
+ s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK", NULL, NULL);
73
}
74
75
static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
76
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription cmsdk_dualtimermod_vmstate = {
77
78
static const VMStateDescription cmsdk_apb_dualtimer_vmstate = {
79
.name = "cmsdk-apb-dualtimer",
80
- .version_id = 1,
81
- .minimum_version_id = 1,
82
+ .version_id = 2,
83
+ .minimum_version_id = 2,
84
.fields = (VMStateField[]) {
85
+ VMSTATE_CLOCK(timclk, CMSDKAPBDualTimer),
86
VMSTATE_STRUCT_ARRAY(timermod, CMSDKAPBDualTimer,
87
CMSDK_APB_DUALTIMER_NUM_MODULES,
88
1, cmsdk_dualtimermod_vmstate,
89
--
90
2.20.1
91
92
diff view generated by jsdifflib
Deleted patch
1
As the first step in converting the CMSDK_APB_TIMER device to the
2
Clock framework, add a Clock input. For the moment we do nothing
3
with this clock; we will change the behaviour from using the
4
wdogclk-frq property to using the Clock once all the users of this
5
device have been converted to wire up the Clock.
6
1
7
This is a migration compatibility break for machines mps2-an385,
8
mps2-an386, mps2-an500, mps2-an511, mps2-an505, mps2-an521, musca-a,
9
musca-b1, lm3s811evb, lm3s6965evb.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Luc Michel <luc@lmichel.fr>
14
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20210128114145.20536-10-peter.maydell@linaro.org
16
Message-id: 20210121190622.22000-10-peter.maydell@linaro.org
17
---
18
include/hw/watchdog/cmsdk-apb-watchdog.h | 3 +++
19
hw/watchdog/cmsdk-apb-watchdog.c | 7 +++++--
20
2 files changed, 8 insertions(+), 2 deletions(-)
21
22
diff --git a/include/hw/watchdog/cmsdk-apb-watchdog.h b/include/hw/watchdog/cmsdk-apb-watchdog.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/watchdog/cmsdk-apb-watchdog.h
25
+++ b/include/hw/watchdog/cmsdk-apb-watchdog.h
26
@@ -XXX,XX +XXX,XX @@
27
*
28
* QEMU interface:
29
* + QOM property "wdogclk-frq": frequency at which the watchdog is clocked
30
+ * + Clock input "WDOGCLK": clock for the watchdog's timer
31
* + sysbus MMIO region 0: the register bank
32
* + sysbus IRQ 0: watchdog interrupt
33
*
34
@@ -XXX,XX +XXX,XX @@
35
36
#include "hw/sysbus.h"
37
#include "hw/ptimer.h"
38
+#include "hw/clock.h"
39
#include "qom/object.h"
40
41
#define TYPE_CMSDK_APB_WATCHDOG "cmsdk-apb-watchdog"
42
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBWatchdog {
43
uint32_t wdogclk_frq;
44
bool is_luminary;
45
struct ptimer_state *timer;
46
+ Clock *wdogclk;
47
48
uint32_t control;
49
uint32_t intstatus;
50
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/watchdog/cmsdk-apb-watchdog.c
53
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
54
@@ -XXX,XX +XXX,XX @@
55
#include "hw/irq.h"
56
#include "hw/qdev-properties.h"
57
#include "hw/registerfields.h"
58
+#include "hw/qdev-clock.h"
59
#include "hw/watchdog/cmsdk-apb-watchdog.h"
60
#include "migration/vmstate.h"
61
62
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_init(Object *obj)
63
s, "cmsdk-apb-watchdog", 0x1000);
64
sysbus_init_mmio(sbd, &s->iomem);
65
sysbus_init_irq(sbd, &s->wdogint);
66
+ s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK", NULL, NULL);
67
68
s->is_luminary = false;
69
s->id = cmsdk_apb_watchdog_id;
70
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
71
72
static const VMStateDescription cmsdk_apb_watchdog_vmstate = {
73
.name = "cmsdk-apb-watchdog",
74
- .version_id = 1,
75
- .minimum_version_id = 1,
76
+ .version_id = 2,
77
+ .minimum_version_id = 2,
78
.fields = (VMStateField[]) {
79
+ VMSTATE_CLOCK(wdogclk, CMSDKAPBWatchdog),
80
VMSTATE_PTIMER(timer, CMSDKAPBWatchdog),
81
VMSTATE_UINT32(control, CMSDKAPBWatchdog),
82
VMSTATE_UINT32(intstatus, CMSDKAPBWatchdog),
83
--
84
2.20.1
85
86
diff view generated by jsdifflib
Deleted patch
1
Create two input clocks on the ARMSSE devices, one for the normal
2
MAINCLK, and one for the 32KHz S32KCLK, and wire these up to the
3
appropriate devices. The old property-based clock frequency setting
4
will remain in place until conversion is complete.
5
1
6
This is a migration compatibility break for machines mps2-an505,
7
mps2-an521, musca-a, musca-b1.
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Luc Michel <luc@lmichel.fr>
12
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20210128114145.20536-12-peter.maydell@linaro.org
14
Message-id: 20210121190622.22000-12-peter.maydell@linaro.org
15
---
16
include/hw/arm/armsse.h | 6 ++++++
17
hw/arm/armsse.c | 17 +++++++++++++++--
18
2 files changed, 21 insertions(+), 2 deletions(-)
19
20
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/armsse.h
23
+++ b/include/hw/arm/armsse.h
24
@@ -XXX,XX +XXX,XX @@
25
* per-CPU identity and control register blocks
26
*
27
* QEMU interface:
28
+ * + Clock input "MAINCLK": clock for CPUs and most peripherals
29
+ * + Clock input "S32KCLK": slow 32KHz clock used for a few peripherals
30
* + QOM property "memory" is a MemoryRegion containing the devices provided
31
* by the board model.
32
* + QOM property "MAINCLK_FRQ" is the frequency of the main system clock
33
@@ -XXX,XX +XXX,XX @@
34
#include "hw/misc/armsse-mhu.h"
35
#include "hw/misc/unimp.h"
36
#include "hw/or-irq.h"
37
+#include "hw/clock.h"
38
#include "hw/core/split-irq.h"
39
#include "hw/cpu/cluster.h"
40
#include "qom/object.h"
41
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
42
43
uint32_t nsccfg;
44
45
+ Clock *mainclk;
46
+ Clock *s32kclk;
47
+
48
/* Properties */
49
MemoryRegion *board_memory;
50
uint32_t exp_numirq;
51
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/arm/armsse.c
54
+++ b/hw/arm/armsse.c
55
@@ -XXX,XX +XXX,XX @@
56
#include "hw/arm/armsse.h"
57
#include "hw/arm/boot.h"
58
#include "hw/irq.h"
59
+#include "hw/qdev-clock.h"
60
61
/* Format of the System Information block SYS_CONFIG register */
62
typedef enum SysConfigFormat {
63
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
64
assert(info->sram_banks <= MAX_SRAM_BANKS);
65
assert(info->num_cpus <= SSE_MAX_CPUS);
66
67
+ s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK", NULL, NULL);
68
+ s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL);
69
+
70
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
71
72
for (i = 0; i < info->num_cpus; i++) {
73
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
74
* map its upstream ends to the right place in the container.
75
*/
76
qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq);
77
+ qdev_connect_clock_in(DEVICE(&s->timer0), "pclk", s->mainclk);
78
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer0), errp)) {
79
return;
80
}
81
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
82
&error_abort);
83
84
qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq);
85
+ qdev_connect_clock_in(DEVICE(&s->timer1), "pclk", s->mainclk);
86
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer1), errp)) {
87
return;
88
}
89
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
90
&error_abort);
91
92
qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
93
+ qdev_connect_clock_in(DEVICE(&s->dualtimer), "TIMCLK", s->mainclk);
94
if (!sysbus_realize(SYS_BUS_DEVICE(&s->dualtimer), errp)) {
95
return;
96
}
97
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
98
* 0x4002f000: S32K timer
99
*/
100
qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK);
101
+ qdev_connect_clock_in(DEVICE(&s->s32ktimer), "pclk", s->s32kclk);
102
if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32ktimer), errp)) {
103
return;
104
}
105
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
106
qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
107
108
qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK);
109
+ qdev_connect_clock_in(DEVICE(&s->s32kwatchdog), "WDOGCLK", s->s32kclk);
110
if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32kwatchdog), errp)) {
111
return;
112
}
113
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
114
/* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
115
116
qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
117
+ qdev_connect_clock_in(DEVICE(&s->nswatchdog), "WDOGCLK", s->mainclk);
118
if (!sysbus_realize(SYS_BUS_DEVICE(&s->nswatchdog), errp)) {
119
return;
120
}
121
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
122
sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
123
124
qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
125
+ qdev_connect_clock_in(DEVICE(&s->swatchdog), "WDOGCLK", s->mainclk);
126
if (!sysbus_realize(SYS_BUS_DEVICE(&s->swatchdog), errp)) {
127
return;
128
}
129
@@ -XXX,XX +XXX,XX @@ static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
130
131
static const VMStateDescription armsse_vmstate = {
132
.name = "iotkit",
133
- .version_id = 1,
134
- .minimum_version_id = 1,
135
+ .version_id = 2,
136
+ .minimum_version_id = 2,
137
.fields = (VMStateField[]) {
138
+ VMSTATE_CLOCK(mainclk, ARMSSE),
139
+ VMSTATE_CLOCK(s32kclk, ARMSSE),
140
VMSTATE_UINT32(nsccfg, ARMSSE),
141
VMSTATE_END_OF_LIST()
142
}
143
--
144
2.20.1
145
146
diff view generated by jsdifflib
Deleted patch
1
The old-style convenience function cmsdk_apb_timer_create() for
2
creating CMSDK_APB_TIMER objects is used in only two places in
3
mps2.c. Most of the rest of the code in that file uses the new
4
"initialize in place" coding style.
5
1
6
We want to connect up a Clock object which should be done between the
7
object creation and realization; rather than adding a Clock* argument
8
to the convenience function, convert the timer creation code in
9
mps2.c to the same style as is used already for the watchdog,
10
dualtimer and other devices, and delete the now-unused convenience
11
function.
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Reviewed-by: Luc Michel <luc@lmichel.fr>
16
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Message-id: 20210128114145.20536-13-peter.maydell@linaro.org
18
Message-id: 20210121190622.22000-13-peter.maydell@linaro.org
19
---
20
include/hw/timer/cmsdk-apb-timer.h | 21 ---------------------
21
hw/arm/mps2.c | 18 ++++++++++++++++--
22
2 files changed, 16 insertions(+), 23 deletions(-)
23
24
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/timer/cmsdk-apb-timer.h
27
+++ b/include/hw/timer/cmsdk-apb-timer.h
28
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBTimer {
29
uint32_t intstatus;
30
};
31
32
-/**
33
- * cmsdk_apb_timer_create - convenience function to create TYPE_CMSDK_APB_TIMER
34
- * @addr: location in system memory to map registers
35
- * @pclk_frq: frequency in Hz of the PCLK clock (used for calculating baud rate)
36
- */
37
-static inline DeviceState *cmsdk_apb_timer_create(hwaddr addr,
38
- qemu_irq timerint,
39
- uint32_t pclk_frq)
40
-{
41
- DeviceState *dev;
42
- SysBusDevice *s;
43
-
44
- dev = qdev_new(TYPE_CMSDK_APB_TIMER);
45
- s = SYS_BUS_DEVICE(dev);
46
- qdev_prop_set_uint32(dev, "pclk-frq", pclk_frq);
47
- sysbus_realize_and_unref(s, &error_fatal);
48
- sysbus_mmio_map(s, 0, addr);
49
- sysbus_connect_irq(s, 0, timerint);
50
- return dev;
51
-}
52
-
53
#endif
54
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/arm/mps2.c
57
+++ b/hw/arm/mps2.c
58
@@ -XXX,XX +XXX,XX @@ struct MPS2MachineState {
59
/* CMSDK APB subsystem */
60
CMSDKAPBDualTimer dualtimer;
61
CMSDKAPBWatchdog watchdog;
62
+ CMSDKAPBTimer timer[2];
63
};
64
65
#define TYPE_MPS2_MACHINE "mps2"
66
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
67
}
68
69
/* CMSDK APB subsystem */
70
- cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
71
- cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
72
+ for (i = 0; i < ARRAY_SIZE(mms->timer); i++) {
73
+ g_autofree char *name = g_strdup_printf("timer%d", i);
74
+ hwaddr base = 0x40000000 + i * 0x1000;
75
+ int irqno = 8 + i;
76
+ SysBusDevice *sbd;
77
+
78
+ object_initialize_child(OBJECT(mms), name, &mms->timer[i],
79
+ TYPE_CMSDK_APB_TIMER);
80
+ sbd = SYS_BUS_DEVICE(&mms->timer[i]);
81
+ qdev_prop_set_uint32(DEVICE(&mms->timer[i]), "pclk-frq", SYSCLK_FRQ);
82
+ sysbus_realize_and_unref(sbd, &error_fatal);
83
+ sysbus_mmio_map(sbd, 0, base);
84
+ sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(armv7m, irqno));
85
+ }
86
+
87
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
88
TYPE_CMSDK_APB_DUALTIMER);
89
qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
90
--
91
2.20.1
92
93
diff view generated by jsdifflib
Deleted patch
1
Create a fixed-frequency Clock object to be the SYSCLK, and wire it
2
up to the devices that require it.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210128114145.20536-14-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-14-peter.maydell@linaro.org
10
---
11
hw/arm/mps2.c | 9 +++++++++
12
1 file changed, 9 insertions(+)
13
14
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/mps2.c
17
+++ b/hw/arm/mps2.c
18
@@ -XXX,XX +XXX,XX @@
19
#include "hw/net/lan9118.h"
20
#include "net/net.h"
21
#include "hw/watchdog/cmsdk-apb-watchdog.h"
22
+#include "hw/qdev-clock.h"
23
#include "qom/object.h"
24
25
typedef enum MPS2FPGAType {
26
@@ -XXX,XX +XXX,XX @@ struct MPS2MachineState {
27
CMSDKAPBDualTimer dualtimer;
28
CMSDKAPBWatchdog watchdog;
29
CMSDKAPBTimer timer[2];
30
+ Clock *sysclk;
31
};
32
33
#define TYPE_MPS2_MACHINE "mps2"
34
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
35
exit(EXIT_FAILURE);
36
}
37
38
+ /* This clock doesn't need migration because it is fixed-frequency */
39
+ mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
40
+ clock_set_hz(mms->sysclk, SYSCLK_FRQ);
41
+
42
/* The FPGA images have an odd combination of different RAMs,
43
* because in hardware they are different implementations and
44
* connected to different buses, giving varying performance/size
45
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
46
TYPE_CMSDK_APB_TIMER);
47
sbd = SYS_BUS_DEVICE(&mms->timer[i]);
48
qdev_prop_set_uint32(DEVICE(&mms->timer[i]), "pclk-frq", SYSCLK_FRQ);
49
+ qdev_connect_clock_in(DEVICE(&mms->timer[i]), "pclk", mms->sysclk);
50
sysbus_realize_and_unref(sbd, &error_fatal);
51
sysbus_mmio_map(sbd, 0, base);
52
sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(armv7m, irqno));
53
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
54
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
55
TYPE_CMSDK_APB_DUALTIMER);
56
qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
57
+ qdev_connect_clock_in(DEVICE(&mms->dualtimer), "TIMCLK", mms->sysclk);
58
sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
59
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
60
qdev_get_gpio_in(armv7m, 10));
61
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
62
object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
63
TYPE_CMSDK_APB_WATCHDOG);
64
qdev_prop_set_uint32(DEVICE(&mms->watchdog), "wdogclk-frq", SYSCLK_FRQ);
65
+ qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->sysclk);
66
sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
67
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
68
qdev_get_gpio_in_named(armv7m, "NMI", 0));
69
--
70
2.20.1
71
72
diff view generated by jsdifflib
Deleted patch
1
Create and connect the two clocks needed by the ARMSSE.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210128114145.20536-15-peter.maydell@linaro.org
8
Message-id: 20210121190622.22000-15-peter.maydell@linaro.org
9
---
10
hw/arm/mps2-tz.c | 13 +++++++++++++
11
1 file changed, 13 insertions(+)
12
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
16
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@
18
#include "hw/net/lan9118.h"
19
#include "net/net.h"
20
#include "hw/core/split-irq.h"
21
+#include "hw/qdev-clock.h"
22
#include "qom/object.h"
23
24
#define MPS2TZ_NUMIRQ 92
25
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
26
qemu_or_irq uart_irq_orgate;
27
DeviceState *lan9118;
28
SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ];
29
+ Clock *sysclk;
30
+ Clock *s32kclk;
31
};
32
33
#define TYPE_MPS2TZ_MACHINE "mps2tz"
34
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
35
36
/* Main SYSCLK frequency in Hz */
37
#define SYSCLK_FRQ 20000000
38
+/* Slow 32Khz S32KCLK frequency in Hz */
39
+#define S32KCLK_FRQ (32 * 1000)
40
41
/* Create an alias of an entire original MemoryRegion @orig
42
* located at @base in the memory map.
43
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
44
exit(EXIT_FAILURE);
45
}
46
47
+ /* These clocks don't need migration because they are fixed-frequency */
48
+ mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
49
+ clock_set_hz(mms->sysclk, SYSCLK_FRQ);
50
+ mms->s32kclk = clock_new(OBJECT(machine), "S32KCLK");
51
+ clock_set_hz(mms->s32kclk, S32KCLK_FRQ);
52
+
53
object_initialize_child(OBJECT(machine), TYPE_IOTKIT, &mms->iotkit,
54
mmc->armsse_type);
55
iotkitdev = DEVICE(&mms->iotkit);
56
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
57
OBJECT(system_memory), &error_abort);
58
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
59
qdev_prop_set_uint32(iotkitdev, "MAINCLK_FRQ", SYSCLK_FRQ);
60
+ qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
61
+ qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
62
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
63
64
/*
65
--
66
2.20.1
67
68
diff view generated by jsdifflib
Deleted patch
1
Create and connect the two clocks needed by the ARMSSE.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210128114145.20536-16-peter.maydell@linaro.org
8
Message-id: 20210121190622.22000-16-peter.maydell@linaro.org
9
---
10
hw/arm/musca.c | 12 ++++++++++++
11
1 file changed, 12 insertions(+)
12
13
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/musca.c
16
+++ b/hw/arm/musca.c
17
@@ -XXX,XX +XXX,XX @@
18
#include "hw/misc/tz-ppc.h"
19
#include "hw/misc/unimp.h"
20
#include "hw/rtc/pl031.h"
21
+#include "hw/qdev-clock.h"
22
#include "qom/object.h"
23
24
#define MUSCA_NUMIRQ_MAX 96
25
@@ -XXX,XX +XXX,XX @@ struct MuscaMachineState {
26
UnimplementedDeviceState sdio;
27
UnimplementedDeviceState gpio;
28
UnimplementedDeviceState cryptoisland;
29
+ Clock *sysclk;
30
+ Clock *s32kclk;
31
};
32
33
#define TYPE_MUSCA_MACHINE "musca"
34
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(MuscaMachineState, MuscaMachineClass, MUSCA_MACHINE)
35
* don't model that in our SSE-200 model yet.
36
*/
37
#define SYSCLK_FRQ 40000000
38
+/* Slow 32Khz S32KCLK frequency in Hz */
39
+#define S32KCLK_FRQ (32 * 1000)
40
41
static qemu_irq get_sse_irq_in(MuscaMachineState *mms, int irqno)
42
{
43
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
44
exit(1);
45
}
46
47
+ mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
48
+ clock_set_hz(mms->sysclk, SYSCLK_FRQ);
49
+ mms->s32kclk = clock_new(OBJECT(machine), "S32KCLK");
50
+ clock_set_hz(mms->s32kclk, S32KCLK_FRQ);
51
+
52
object_initialize_child(OBJECT(machine), "sse-200", &mms->sse,
53
TYPE_SSE200);
54
ssedev = DEVICE(&mms->sse);
55
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
56
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
57
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
58
qdev_prop_set_uint32(ssedev, "MAINCLK_FRQ", SYSCLK_FRQ);
59
+ qdev_connect_clock_in(ssedev, "MAINCLK", mms->sysclk);
60
+ qdev_connect_clock_in(ssedev, "S32KCLK", mms->s32kclk);
61
/*
62
* Musca-A takes the default SSE-200 FPU/DSP settings (ie no for
63
* CPU0 and yes for CPU1); Musca-B1 explicitly enables them for CPU0.
64
--
65
2.20.1
66
67
diff view generated by jsdifflib
Deleted patch
1
Remove all the code that sets frequency properties on the CMSDK
2
timer, dualtimer and watchdog devices and on the ARMSSE SoC device:
3
these properties are unused now that the devices rely on their Clock
4
inputs instead.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Luc Michel <luc@lmichel.fr>
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20210128114145.20536-24-peter.maydell@linaro.org
11
Message-id: 20210121190622.22000-24-peter.maydell@linaro.org
12
---
13
hw/arm/armsse.c | 7 -------
14
hw/arm/mps2-tz.c | 1 -
15
hw/arm/mps2.c | 3 ---
16
hw/arm/musca.c | 1 -
17
hw/arm/stellaris.c | 3 ---
18
5 files changed, 15 deletions(-)
19
20
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/armsse.c
23
+++ b/hw/arm/armsse.c
24
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
25
* it to the appropriate PPC port; then we can realize the PPC and
26
* map its upstream ends to the right place in the container.
27
*/
28
- qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq);
29
qdev_connect_clock_in(DEVICE(&s->timer0), "pclk", s->mainclk);
30
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer0), errp)) {
31
return;
32
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
33
object_property_set_link(OBJECT(&s->apb_ppc0), "port[0]", OBJECT(mr),
34
&error_abort);
35
36
- qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq);
37
qdev_connect_clock_in(DEVICE(&s->timer1), "pclk", s->mainclk);
38
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer1), errp)) {
39
return;
40
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
41
object_property_set_link(OBJECT(&s->apb_ppc0), "port[1]", OBJECT(mr),
42
&error_abort);
43
44
- qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
45
qdev_connect_clock_in(DEVICE(&s->dualtimer), "TIMCLK", s->mainclk);
46
if (!sysbus_realize(SYS_BUS_DEVICE(&s->dualtimer), errp)) {
47
return;
48
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
49
/* Devices behind APB PPC1:
50
* 0x4002f000: S32K timer
51
*/
52
- qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK);
53
qdev_connect_clock_in(DEVICE(&s->s32ktimer), "pclk", s->s32kclk);
54
if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32ktimer), errp)) {
55
return;
56
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
57
qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
58
qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
59
60
- qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK);
61
qdev_connect_clock_in(DEVICE(&s->s32kwatchdog), "WDOGCLK", s->s32kclk);
62
if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32kwatchdog), errp)) {
63
return;
64
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
65
66
/* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
67
68
- qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
69
qdev_connect_clock_in(DEVICE(&s->nswatchdog), "WDOGCLK", s->mainclk);
70
if (!sysbus_realize(SYS_BUS_DEVICE(&s->nswatchdog), errp)) {
71
return;
72
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
73
armsse_get_common_irq_in(s, 1));
74
sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
75
76
- qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
77
qdev_connect_clock_in(DEVICE(&s->swatchdog), "WDOGCLK", s->mainclk);
78
if (!sysbus_realize(SYS_BUS_DEVICE(&s->swatchdog), errp)) {
79
return;
80
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/hw/arm/mps2-tz.c
83
+++ b/hw/arm/mps2-tz.c
84
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
85
object_property_set_link(OBJECT(&mms->iotkit), "memory",
86
OBJECT(system_memory), &error_abort);
87
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
88
- qdev_prop_set_uint32(iotkitdev, "MAINCLK_FRQ", SYSCLK_FRQ);
89
qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
90
qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
91
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
92
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/arm/mps2.c
95
+++ b/hw/arm/mps2.c
96
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
97
object_initialize_child(OBJECT(mms), name, &mms->timer[i],
98
TYPE_CMSDK_APB_TIMER);
99
sbd = SYS_BUS_DEVICE(&mms->timer[i]);
100
- qdev_prop_set_uint32(DEVICE(&mms->timer[i]), "pclk-frq", SYSCLK_FRQ);
101
qdev_connect_clock_in(DEVICE(&mms->timer[i]), "pclk", mms->sysclk);
102
sysbus_realize_and_unref(sbd, &error_fatal);
103
sysbus_mmio_map(sbd, 0, base);
104
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
105
106
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
107
TYPE_CMSDK_APB_DUALTIMER);
108
- qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
109
qdev_connect_clock_in(DEVICE(&mms->dualtimer), "TIMCLK", mms->sysclk);
110
sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
111
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
112
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
113
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
114
object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
115
TYPE_CMSDK_APB_WATCHDOG);
116
- qdev_prop_set_uint32(DEVICE(&mms->watchdog), "wdogclk-frq", SYSCLK_FRQ);
117
qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->sysclk);
118
sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
119
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
120
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/hw/arm/musca.c
123
+++ b/hw/arm/musca.c
124
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
125
qdev_prop_set_uint32(ssedev, "EXP_NUMIRQ", mmc->num_irqs);
126
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
127
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
128
- qdev_prop_set_uint32(ssedev, "MAINCLK_FRQ", SYSCLK_FRQ);
129
qdev_connect_clock_in(ssedev, "MAINCLK", mms->sysclk);
130
qdev_connect_clock_in(ssedev, "S32KCLK", mms->s32kclk);
131
/*
132
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/hw/arm/stellaris.c
135
+++ b/hw/arm/stellaris.c
136
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
137
if (board->dc1 & (1 << 3)) { /* watchdog present */
138
dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
139
140
- /* system_clock_scale is valid now */
141
- uint32_t mainclk = NANOSECONDS_PER_SECOND / system_clock_scale;
142
- qdev_prop_set_uint32(dev, "wdogclk-frq", mainclk);
143
qdev_connect_clock_in(dev, "WDOGCLK",
144
qdev_get_clock_out(ssys_dev, "SYSCLK"));
145
146
--
147
2.20.1
148
149
diff view generated by jsdifflib