1
target-arm queue for rc1 -- these are all bug fixes.
1
The following changes since commit b367db48126d4ee14579af6cf5cdbffeb9496627:
2
2
3
thanks
3
Merge remote-tracking branch 'remotes/aperard/tags/pull-xen-20220127' into staging (2022-01-28 11:05:29 +0000)
4
-- PMM
5
6
The following changes since commit b9404bf592e7ba74180e1a54ed7a266ec6ee67f2:
7
8
Merge remote-tracking branch 'remotes/dgilbert/tags/pull-hmp-20190715' into staging (2019-07-15 12:22:07 +0100)
9
4
10
are available in the Git repository at:
5
are available in the Git repository at:
11
6
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190715
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220128
13
8
14
for you to fetch changes up to 51c9122e92b776a3f16af0b9282f1dc5012e2a19:
9
for you to fetch changes up to 2c023d3675a3ffb54fc30504dcd715bc6f6e234f:
15
10
16
target/arm: NS BusFault on vector table fetch escalates to NS HardFault (2019-07-15 14:17:04 +0100)
11
target/arm: Use correct entrypoint for SVC taken from Hyp to Hyp (2022-01-28 14:30:36 +0000)
17
12
18
----------------------------------------------------------------
13
----------------------------------------------------------------
19
target-arm queue:
14
target-arm queue:
20
* report ARMv8-A FP support for AArch32 -cpu max
15
* Update copyright dates to 2022
21
* hw/ssi/xilinx_spips: Avoid AXI writes to the LQSPI linear memory
16
* hw/armv7m: Fix broken VMStateDescription
22
* hw/ssi/xilinx_spips: Avoid out-of-bound access to lqspi_buf[]
17
* hw/char/exynos4210_uart: Fix crash on trying to load VM state
23
* hw/ssi/mss-spi: Avoid crash when reading empty RX FIFO
18
* rtc: Move RTC function prototypes to their own header
24
* hw/display/xlnx_dp: Avoid crash when reading empty RX FIFO
19
* xlnx-versal-virt: Support PMC SLCR
25
* hw/arm/virt: Fix non-secure flash mode
20
* xlnx-versal-virt: Support OSPI flash memory controller
26
* pl031: Correctly migrate state when using -rtc clock=host
21
* scripts: Explain the difference between linux-headers and standard-headers
27
* fix regression that meant arm926 and arm1026 lost VFP
22
* target/arm: Log CPU index in 'Taking exception' log
28
double-precision support
23
* arm_gicv3_its: Various bugfixes and cleanups
29
* v8M: NS BusFault on vector table fetch escalates to NS HardFault
24
* arm_gicv3_its: Implement the missing MOVI and MOVALL commands
25
* ast2600: Fix address mapping of second SPI controller
26
* target/arm: Use correct entrypoint for SVC taken from Hyp to Hyp
30
27
31
----------------------------------------------------------------
28
----------------------------------------------------------------
32
Alex Bennée (1):
29
Andrew Baumann (1):
33
target/arm: report ARMv8-A FP support for AArch32 -cpu max
30
MAINTAINERS: Remove myself (for raspi).
34
31
35
David Engraf (1):
32
Cédric Le Goater (1):
36
hw/arm/virt: Fix non-secure flash mode
33
hw/arm: ast2600: Fix address mapping of second SPI controller
37
34
38
Peter Maydell (3):
35
Francisco Iglesias (10):
39
pl031: Correctly migrate state when using -rtc clock=host
36
hw/misc: Add a model of Versal's PMC SLCR
40
target/arm: Set VFP-related MVFR0 fields for arm926 and arm1026
37
hw/arm/xlnx-versal: 'Or' the interrupts from the BBRAM and RTC models
41
target/arm: NS BusFault on vector table fetch escalates to NS HardFault
38
hw/arm/xlnx-versal: Connect Versal's PMC SLCR
39
include/hw/dma/xlnx_csu_dma: Add in missing includes in the header
40
hw/dma/xlnx_csu_dma: Support starting a read transfer through a class method
41
hw/ssi: Add a model of Xilinx Versal's OSPI flash memory controller
42
hw/arm/xlnx-versal: Connect the OSPI flash memory controller model
43
hw/block/m25p80: Add support for Micron Xccela flash mt35xu01g
44
hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI
45
MAINTAINERS: Add an entry for Xilinx Versal OSPI
42
46
43
Philippe Mathieu-Daudé (5):
47
Peter Maydell (20):
44
hw/ssi/xilinx_spips: Convert lqspi_read() to read_with_attrs
48
Update copyright dates to 2022
45
hw/ssi/xilinx_spips: Avoid AXI writes to the LQSPI linear memory
49
hw/armv7m: Fix broken VMStateDescription
46
hw/ssi/xilinx_spips: Avoid out-of-bound access to lqspi_buf[]
50
hw/char/exynos4210_uart: Fix crash on trying to load VM state
47
hw/ssi/mss-spi: Avoid crash when reading empty RX FIFO
51
rtc: Move RTC function prototypes to their own header
48
hw/display/xlnx_dp: Avoid crash when reading empty RX FIFO
52
scripts: Explain the difference between linux-headers and standard-headers
53
target/arm: Log CPU index in 'Taking exception' log
54
hw/intc/arm_gicv3_its: Add tracepoints
55
hw/intc/arm_gicv3: Initialise dma_as in GIC, not ITS
56
hw/intc/arm_gicv3_its: Don't clear GITS_CREADR when GITS_CTLR.ENABLED is set
57
hw/intc/arm_gicv3_its: Don't clear GITS_CWRITER on writes to GITS_CBASER
58
hw/intc/arm_gicv3: Honour GICD_CTLR.EnableGrp1NS for LPIs
59
hw/intc/arm_gicv3_its: Sort ITS command list into numeric order
60
hw/intc/arm_gicv3_redist: Remove unnecessary zero checks
61
hw/intc/arm_gicv3: Set GICR_CTLR.CES if LPIs are supported
62
hw/intc/arm_gicv3_its: Provide read accessor for translation_ops
63
hw/intc/arm_gicv3_its: Make GITS_BASER<n> RAZ/WI for unimplemented registers
64
hw/intc/arm_gicv3_its: Check table bounds against correct limit
65
hw/intc/arm_gicv3_its: Implement MOVALL
66
hw/intc/arm_gicv3_its: Implement MOVI
67
target/arm: Use correct entrypoint for SVC taken from Hyp to Hyp
49
68
50
include/hw/timer/pl031.h | 2 ++
69
docs/conf.py | 2 +-
51
hw/arm/virt.c | 2 +-
70
hw/intc/gicv3_internal.h | 43 +-
52
hw/core/machine.c | 1 +
71
include/hw/arm/xlnx-versal.h | 30 +-
53
hw/display/xlnx_dp.c | 15 +++++---
72
include/hw/dma/xlnx_csu_dma.h | 24 +-
54
hw/ssi/mss-spi.c | 8 ++++-
73
include/hw/intc/arm_gicv3_its_common.h | 1 -
55
hw/ssi/xilinx_spips.c | 43 +++++++++++++++-------
74
include/hw/misc/xlnx-versal-pmc-iou-slcr.h | 78 ++
56
hw/timer/pl031.c | 92 +++++++++++++++++++++++++++++++++++++++++++++---
75
include/hw/ssi/xlnx-versal-ospi.h | 111 ++
57
target/arm/cpu.c | 16 +++++++++
76
include/qemu-common.h | 5 +-
58
target/arm/m_helper.c | 21 ++++++++---
77
include/sysemu/rtc.h | 58 +
59
9 files changed, 174 insertions(+), 26 deletions(-)
78
target/arm/internals.h | 2 +-
79
hw/arm/armv7m.c | 4 +-
80
hw/arm/aspeed_ast2600.c | 2 +-
81
hw/arm/omap1.c | 2 +-
82
hw/arm/pxa2xx.c | 2 +-
83
hw/arm/strongarm.c | 2 +-
84
hw/arm/xlnx-versal-virt.c | 25 +-
85
hw/arm/xlnx-versal.c | 190 ++-
86
hw/block/m25p80.c | 2 +
87
hw/char/exynos4210_uart.c | 2 +-
88
hw/dma/xlnx_csu_dma.c | 17 +
89
hw/intc/arm_gicv3.c | 1 +
90
hw/intc/arm_gicv3_common.c | 9 +
91
hw/intc/arm_gicv3_its.c | 258 +++-
92
hw/intc/arm_gicv3_redist.c | 115 +-
93
hw/misc/mac_via.c | 2 +-
94
hw/misc/macio/cuda.c | 2 +-
95
hw/misc/macio/pmu.c | 2 +-
96
hw/misc/xlnx-versal-pmc-iou-slcr.c | 1446 ++++++++++++++++++++++
97
hw/ppc/spapr_rtc.c | 2 +-
98
hw/rtc/allwinner-rtc.c | 2 +-
99
hw/rtc/aspeed_rtc.c | 2 +-
100
hw/rtc/ds1338.c | 2 +-
101
hw/rtc/exynos4210_rtc.c | 2 +-
102
hw/rtc/goldfish_rtc.c | 2 +-
103
hw/rtc/m41t80.c | 2 +-
104
hw/rtc/m48t59.c | 2 +-
105
hw/rtc/mc146818rtc.c | 2 +-
106
hw/rtc/pl031.c | 2 +-
107
hw/rtc/twl92230.c | 2 +-
108
hw/rtc/xlnx-zynqmp-rtc.c | 2 +-
109
hw/s390x/tod-tcg.c | 2 +-
110
hw/scsi/megasas.c | 2 +-
111
hw/ssi/xlnx-versal-ospi.c | 1853 ++++++++++++++++++++++++++++
112
net/dump.c | 2 +-
113
softmmu/rtc.c | 2 +-
114
target/arm/helper.c | 13 +-
115
target/arm/m_helper.c | 2 +-
116
MAINTAINERS | 7 +-
117
hw/intc/trace-events | 8 +
118
hw/misc/meson.build | 5 +-
119
hw/ssi/meson.build | 1 +
120
scripts/update-linux-headers.sh | 16 +
121
52 files changed, 4300 insertions(+), 74 deletions(-)
122
create mode 100644 include/hw/misc/xlnx-versal-pmc-iou-slcr.h
123
create mode 100644 include/hw/ssi/xlnx-versal-ospi.h
124
create mode 100644 include/sysemu/rtc.h
125
create mode 100644 hw/misc/xlnx-versal-pmc-iou-slcr.c
126
create mode 100644 hw/ssi/xlnx-versal-ospi.c
60
127
diff view generated by jsdifflib
New patch
1
It's a new year; update the copyright strings for our
2
help/version/about information and for our documentation.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20220120124713.288303-1-peter.maydell@linaro.org
8
---
9
docs/conf.py | 2 +-
10
include/qemu-common.h | 2 +-
11
2 files changed, 2 insertions(+), 2 deletions(-)
12
13
diff --git a/docs/conf.py b/docs/conf.py
14
index XXXXXXX..XXXXXXX 100644
15
--- a/docs/conf.py
16
+++ b/docs/conf.py
17
@@ -XXX,XX +XXX,XX @@
18
19
# General information about the project.
20
project = u'QEMU'
21
-copyright = u'2021, The QEMU Project Developers'
22
+copyright = u'2022, The QEMU Project Developers'
23
author = u'The QEMU Project Developers'
24
25
# The version info for the project you're documenting, acts as replacement for
26
diff --git a/include/qemu-common.h b/include/qemu-common.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/qemu-common.h
29
+++ b/include/qemu-common.h
30
@@ -XXX,XX +XXX,XX @@
31
#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
32
33
/* Copyright string for -version arguments, About dialogs, etc */
34
-#define QEMU_COPYRIGHT "Copyright (c) 2003-2021 " \
35
+#define QEMU_COPYRIGHT "Copyright (c) 2003-2022 " \
36
"Fabrice Bellard and the QEMU Project developers"
37
38
/* Bug reporting information for --help arguments, About dialogs, etc */
39
--
40
2.25.1
41
42
diff view generated by jsdifflib
New patch
1
In commit d5093d961585f02 we added a VMStateDescription to
2
the TYPE_ARMV7M object, to handle migration of its Clocks.
3
However a cut-and-paste error meant we used the wrong struct
4
name in the VMSTATE_CLOCK() macro arguments. The result was
5
that attempting a 'savevm' might result in an assertion
6
failure.
1
7
8
Cc: qemu-stable@nongnu.org
9
Buglink: https://gitlab.com/qemu-project/qemu/-/issues/803
10
Fixes: d5093d961585f02
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Ani Sinha <ani@anisinha.ca>
13
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20220120151609.433555-1-peter.maydell@linaro.org
16
---
17
hw/arm/armv7m.c | 4 ++--
18
1 file changed, 2 insertions(+), 2 deletions(-)
19
20
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/armv7m.c
23
+++ b/hw/arm/armv7m.c
24
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_armv7m = {
25
.version_id = 1,
26
.minimum_version_id = 1,
27
.fields = (VMStateField[]) {
28
- VMSTATE_CLOCK(refclk, SysTickState),
29
- VMSTATE_CLOCK(cpuclk, SysTickState),
30
+ VMSTATE_CLOCK(refclk, ARMv7MState),
31
+ VMSTATE_CLOCK(cpuclk, ARMv7MState),
32
VMSTATE_END_OF_LIST()
33
}
34
};
35
--
36
2.25.1
37
38
diff view generated by jsdifflib
New patch
1
The exynos4210_uart_post_load() function assumes that it is passed
2
the Exynos4210UartState, but it has been attached to the
3
VMStateDescription for the Exynos4210UartFIFO type. The result is a
4
SIGSEGV when attempting to load VM state for any machine type
5
including this device.
1
6
7
Fix the bug by attaching the post-load function to the VMSD for the
8
Exynos4210UartState. This is the logical place for it, because the
9
actions it does relate to the entire UART state, not just the FIFO.
10
11
Thanks to the bug reporter @TrungNguyen1909 for the clear bug
12
description and the suggested fix.
13
14
Fixes: c9d3396d80fe7ece9b
15
("hw/char/exynos4210_uart: Implement post_load function")
16
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/638
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
19
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Message-id: 20220120151648.433736-1-peter.maydell@linaro.org
21
---
22
hw/char/exynos4210_uart.c | 2 +-
23
1 file changed, 1 insertion(+), 1 deletion(-)
24
25
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/char/exynos4210_uart.c
28
+++ b/hw/char/exynos4210_uart.c
29
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_exynos4210_uart_fifo = {
30
.name = "exynos4210.uart.fifo",
31
.version_id = 1,
32
.minimum_version_id = 1,
33
- .post_load = exynos4210_uart_post_load,
34
.fields = (VMStateField[]) {
35
VMSTATE_UINT32(sp, Exynos4210UartFIFO),
36
VMSTATE_UINT32(rp, Exynos4210UartFIFO),
37
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_exynos4210_uart = {
38
.name = "exynos4210.uart",
39
.version_id = 1,
40
.minimum_version_id = 1,
41
+ .post_load = exynos4210_uart_post_load,
42
.fields = (VMStateField[]) {
43
VMSTATE_STRUCT(rx, Exynos4210UartState, 1,
44
vmstate_exynos4210_uart_fifo, Exynos4210UartFIFO),
45
--
46
2.25.1
47
48
diff view generated by jsdifflib
New patch
1
softmmu/rtc.c defines two public functions: qemu_get_timedate() and
2
qemu_timedate_diff(). Currently we keep the prototypes for these in
3
qemu-common.h, but most files don't need them. Move them to their
4
own header, a new include/sysemu/rtc.h.
1
5
6
Since the C files using these two functions did not need to include
7
qemu-common.h for any other reason, we can remove those include lines
8
when we add the include of the new rtc.h.
9
10
The license for the .h file follows that of the softmmu/rtc.c
11
where both the functions are defined.
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
---
16
include/qemu-common.h | 3 ---
17
include/sysemu/rtc.h | 58 ++++++++++++++++++++++++++++++++++++++++
18
hw/arm/omap1.c | 2 +-
19
hw/arm/pxa2xx.c | 2 +-
20
hw/arm/strongarm.c | 2 +-
21
hw/misc/mac_via.c | 2 +-
22
hw/misc/macio/cuda.c | 2 +-
23
hw/misc/macio/pmu.c | 2 +-
24
hw/ppc/spapr_rtc.c | 2 +-
25
hw/rtc/allwinner-rtc.c | 2 +-
26
hw/rtc/aspeed_rtc.c | 2 +-
27
hw/rtc/ds1338.c | 2 +-
28
hw/rtc/exynos4210_rtc.c | 2 +-
29
hw/rtc/goldfish_rtc.c | 2 +-
30
hw/rtc/m41t80.c | 2 +-
31
hw/rtc/m48t59.c | 2 +-
32
hw/rtc/mc146818rtc.c | 2 +-
33
hw/rtc/pl031.c | 2 +-
34
hw/rtc/twl92230.c | 2 +-
35
hw/rtc/xlnx-zynqmp-rtc.c | 2 +-
36
hw/s390x/tod-tcg.c | 2 +-
37
hw/scsi/megasas.c | 2 +-
38
net/dump.c | 2 +-
39
softmmu/rtc.c | 2 +-
40
24 files changed, 80 insertions(+), 25 deletions(-)
41
create mode 100644 include/sysemu/rtc.h
42
43
diff --git a/include/qemu-common.h b/include/qemu-common.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/include/qemu-common.h
46
+++ b/include/qemu-common.h
47
@@ -XXX,XX +XXX,XX @@
48
int qemu_main(int argc, char **argv, char **envp);
49
#endif
50
51
-void qemu_get_timedate(struct tm *tm, int offset);
52
-int qemu_timedate_diff(struct tm *tm);
53
-
54
void *qemu_oom_check(void *ptr);
55
56
ssize_t qemu_write_full(int fd, const void *buf, size_t count)
57
diff --git a/include/sysemu/rtc.h b/include/sysemu/rtc.h
58
new file mode 100644
59
index XXXXXXX..XXXXXXX
60
--- /dev/null
61
+++ b/include/sysemu/rtc.h
62
@@ -XXX,XX +XXX,XX @@
63
+/*
64
+ * RTC configuration and clock read
65
+ *
66
+ * Copyright (c) 2003-2021 QEMU contributors
67
+ *
68
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
69
+ * of this software and associated documentation files (the "Software"), to deal
70
+ * in the Software without restriction, including without limitation the rights
71
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
72
+ * copies of the Software, and to permit persons to whom the Software is
73
+ * furnished to do so, subject to the following conditions:
74
+ *
75
+ * The above copyright notice and this permission notice shall be included in
76
+ * all copies or substantial portions of the Software.
77
+ *
78
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
79
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
80
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
81
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
82
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
83
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
84
+ * THE SOFTWARE.
85
+ */
86
+
87
+#ifndef SYSEMU_RTC_H
88
+#define SYSEMU_RTC_H
89
+
90
+/**
91
+ * qemu_get_timedate: Get the current RTC time
92
+ * @tm: struct tm to fill in with RTC time
93
+ * @offset: offset in seconds to adjust the RTC time by before
94
+ * converting to struct tm format.
95
+ *
96
+ * This function fills in @tm with the current RTC time, as adjusted
97
+ * by @offset (for example, if @offset is 3600 then the returned time/date
98
+ * will be one hour further ahead than the current RTC time).
99
+ *
100
+ * The usual use is by RTC device models, which should call this function
101
+ * to find the time/date value that they should return to the guest
102
+ * when it reads the RTC registers.
103
+ *
104
+ * The behaviour of the clock whose value this function returns will
105
+ * depend on the -rtc command line option passed by the user.
106
+ */
107
+void qemu_get_timedate(struct tm *tm, int offset);
108
+
109
+/**
110
+ * qemu_timedate_diff: Return difference between a struct tm and the RTC
111
+ * @tm: struct tm containing the date/time to compare against
112
+ *
113
+ * Returns the difference in seconds between the RTC clock time
114
+ * and the date/time specified in @tm. For example, if @tm specifies
115
+ * a timestamp one hour further ahead than the current RTC time
116
+ * then this function will return 3600.
117
+ */
118
+int qemu_timedate_diff(struct tm *tm);
119
+
120
+#endif
121
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/hw/arm/omap1.c
124
+++ b/hw/arm/omap1.c
125
@@ -XXX,XX +XXX,XX @@
126
#include "qemu/error-report.h"
127
#include "qemu/main-loop.h"
128
#include "qapi/error.h"
129
-#include "qemu-common.h"
130
#include "cpu.h"
131
#include "exec/address-spaces.h"
132
#include "hw/hw.h"
133
@@ -XXX,XX +XXX,XX @@
134
#include "sysemu/qtest.h"
135
#include "sysemu/reset.h"
136
#include "sysemu/runstate.h"
137
+#include "sysemu/rtc.h"
138
#include "qemu/range.h"
139
#include "hw/sysbus.h"
140
#include "qemu/cutils.h"
141
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
142
index XXXXXXX..XXXXXXX 100644
143
--- a/hw/arm/pxa2xx.c
144
+++ b/hw/arm/pxa2xx.c
145
@@ -XXX,XX +XXX,XX @@
146
*/
147
148
#include "qemu/osdep.h"
149
-#include "qemu-common.h"
150
#include "qemu/error-report.h"
151
#include "qemu/module.h"
152
#include "qapi/error.h"
153
@@ -XXX,XX +XXX,XX @@
154
#include "chardev/char-fe.h"
155
#include "sysemu/blockdev.h"
156
#include "sysemu/qtest.h"
157
+#include "sysemu/rtc.h"
158
#include "qemu/cutils.h"
159
#include "qemu/log.h"
160
#include "qom/object.h"
161
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
162
index XXXXXXX..XXXXXXX 100644
163
--- a/hw/arm/strongarm.c
164
+++ b/hw/arm/strongarm.c
165
@@ -XXX,XX +XXX,XX @@
166
*/
167
168
#include "qemu/osdep.h"
169
-#include "qemu-common.h"
170
#include "cpu.h"
171
#include "hw/irq.h"
172
#include "hw/qdev-properties.h"
173
@@ -XXX,XX +XXX,XX @@
174
#include "chardev/char-fe.h"
175
#include "chardev/char-serial.h"
176
#include "sysemu/sysemu.h"
177
+#include "sysemu/rtc.h"
178
#include "hw/ssi/ssi.h"
179
#include "qapi/error.h"
180
#include "qemu/cutils.h"
181
diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/hw/misc/mac_via.c
184
+++ b/hw/misc/mac_via.c
185
@@ -XXX,XX +XXX,XX @@
186
*/
187
188
#include "qemu/osdep.h"
189
-#include "qemu-common.h"
190
#include "migration/vmstate.h"
191
#include "hw/sysbus.h"
192
#include "hw/irq.h"
193
@@ -XXX,XX +XXX,XX @@
194
#include "hw/qdev-properties.h"
195
#include "hw/qdev-properties-system.h"
196
#include "sysemu/block-backend.h"
197
+#include "sysemu/rtc.h"
198
#include "trace.h"
199
#include "qemu/log.h"
200
201
diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
202
index XXXXXXX..XXXXXXX 100644
203
--- a/hw/misc/macio/cuda.c
204
+++ b/hw/misc/macio/cuda.c
205
@@ -XXX,XX +XXX,XX @@
206
*/
207
208
#include "qemu/osdep.h"
209
-#include "qemu-common.h"
210
#include "hw/ppc/mac.h"
211
#include "hw/qdev-properties.h"
212
#include "migration/vmstate.h"
213
@@ -XXX,XX +XXX,XX @@
214
#include "qapi/error.h"
215
#include "qemu/timer.h"
216
#include "sysemu/runstate.h"
217
+#include "sysemu/rtc.h"
218
#include "qapi/error.h"
219
#include "qemu/cutils.h"
220
#include "qemu/log.h"
221
diff --git a/hw/misc/macio/pmu.c b/hw/misc/macio/pmu.c
222
index XXXXXXX..XXXXXXX 100644
223
--- a/hw/misc/macio/pmu.c
224
+++ b/hw/misc/macio/pmu.c
225
@@ -XXX,XX +XXX,XX @@
226
*/
227
228
#include "qemu/osdep.h"
229
-#include "qemu-common.h"
230
#include "hw/ppc/mac.h"
231
#include "hw/qdev-properties.h"
232
#include "migration/vmstate.h"
233
@@ -XXX,XX +XXX,XX @@
234
#include "qapi/error.h"
235
#include "qemu/timer.h"
236
#include "sysemu/runstate.h"
237
+#include "sysemu/rtc.h"
238
#include "qapi/error.h"
239
#include "qemu/cutils.h"
240
#include "qemu/log.h"
241
diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c
242
index XXXXXXX..XXXXXXX 100644
243
--- a/hw/ppc/spapr_rtc.c
244
+++ b/hw/ppc/spapr_rtc.c
245
@@ -XXX,XX +XXX,XX @@
246
*/
247
248
#include "qemu/osdep.h"
249
-#include "qemu-common.h"
250
#include "qemu/timer.h"
251
#include "sysemu/sysemu.h"
252
+#include "sysemu/rtc.h"
253
#include "hw/ppc/spapr.h"
254
#include "migration/vmstate.h"
255
#include "qapi/error.h"
256
diff --git a/hw/rtc/allwinner-rtc.c b/hw/rtc/allwinner-rtc.c
257
index XXXXXXX..XXXXXXX 100644
258
--- a/hw/rtc/allwinner-rtc.c
259
+++ b/hw/rtc/allwinner-rtc.c
260
@@ -XXX,XX +XXX,XX @@
261
#include "migration/vmstate.h"
262
#include "qemu/log.h"
263
#include "qemu/module.h"
264
-#include "qemu-common.h"
265
#include "hw/qdev-properties.h"
266
#include "hw/rtc/allwinner-rtc.h"
267
+#include "sysemu/rtc.h"
268
#include "trace.h"
269
270
/* RTC registers */
271
diff --git a/hw/rtc/aspeed_rtc.c b/hw/rtc/aspeed_rtc.c
272
index XXXXXXX..XXXXXXX 100644
273
--- a/hw/rtc/aspeed_rtc.c
274
+++ b/hw/rtc/aspeed_rtc.c
275
@@ -XXX,XX +XXX,XX @@
276
*/
277
278
#include "qemu/osdep.h"
279
-#include "qemu-common.h"
280
#include "hw/rtc/aspeed_rtc.h"
281
#include "migration/vmstate.h"
282
#include "qemu/log.h"
283
#include "qemu/timer.h"
284
+#include "sysemu/rtc.h"
285
286
#include "trace.h"
287
288
diff --git a/hw/rtc/ds1338.c b/hw/rtc/ds1338.c
289
index XXXXXXX..XXXXXXX 100644
290
--- a/hw/rtc/ds1338.c
291
+++ b/hw/rtc/ds1338.c
292
@@ -XXX,XX +XXX,XX @@
293
*/
294
295
#include "qemu/osdep.h"
296
-#include "qemu-common.h"
297
#include "hw/i2c/i2c.h"
298
#include "migration/vmstate.h"
299
#include "qemu/bcd.h"
300
#include "qemu/module.h"
301
#include "qom/object.h"
302
+#include "sysemu/rtc.h"
303
304
/* Size of NVRAM including both the user-accessible area and the
305
* secondary register area.
306
diff --git a/hw/rtc/exynos4210_rtc.c b/hw/rtc/exynos4210_rtc.c
307
index XXXXXXX..XXXXXXX 100644
308
--- a/hw/rtc/exynos4210_rtc.c
309
+++ b/hw/rtc/exynos4210_rtc.c
310
@@ -XXX,XX +XXX,XX @@
311
*/
312
313
#include "qemu/osdep.h"
314
-#include "qemu-common.h"
315
#include "qemu/log.h"
316
#include "qemu/module.h"
317
#include "hw/sysbus.h"
318
@@ -XXX,XX +XXX,XX @@
319
320
#include "hw/arm/exynos4210.h"
321
#include "qom/object.h"
322
+#include "sysemu/rtc.h"
323
324
#define DEBUG_RTC 0
325
326
diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
327
index XXXXXXX..XXXXXXX 100644
328
--- a/hw/rtc/goldfish_rtc.c
329
+++ b/hw/rtc/goldfish_rtc.c
330
@@ -XXX,XX +XXX,XX @@
331
*/
332
333
#include "qemu/osdep.h"
334
-#include "qemu-common.h"
335
#include "hw/rtc/goldfish_rtc.h"
336
#include "migration/vmstate.h"
337
#include "hw/irq.h"
338
@@ -XXX,XX +XXX,XX @@
339
#include "qemu/bitops.h"
340
#include "qemu/timer.h"
341
#include "sysemu/sysemu.h"
342
+#include "sysemu/rtc.h"
343
#include "qemu/cutils.h"
344
#include "qemu/log.h"
345
346
diff --git a/hw/rtc/m41t80.c b/hw/rtc/m41t80.c
347
index XXXXXXX..XXXXXXX 100644
348
--- a/hw/rtc/m41t80.c
349
+++ b/hw/rtc/m41t80.c
350
@@ -XXX,XX +XXX,XX @@
351
*/
352
353
#include "qemu/osdep.h"
354
-#include "qemu-common.h"
355
#include "qemu/log.h"
356
#include "qemu/module.h"
357
#include "qemu/timer.h"
358
#include "qemu/bcd.h"
359
#include "hw/i2c/i2c.h"
360
#include "qom/object.h"
361
+#include "sysemu/rtc.h"
362
363
#define TYPE_M41T80 "m41t80"
364
OBJECT_DECLARE_SIMPLE_TYPE(M41t80State, M41T80)
365
diff --git a/hw/rtc/m48t59.c b/hw/rtc/m48t59.c
366
index XXXXXXX..XXXXXXX 100644
367
--- a/hw/rtc/m48t59.c
368
+++ b/hw/rtc/m48t59.c
369
@@ -XXX,XX +XXX,XX @@
370
*/
371
372
#include "qemu/osdep.h"
373
-#include "qemu-common.h"
374
#include "hw/irq.h"
375
#include "hw/qdev-properties.h"
376
#include "hw/rtc/m48t59.h"
377
#include "qemu/timer.h"
378
#include "sysemu/runstate.h"
379
+#include "sysemu/rtc.h"
380
#include "sysemu/sysemu.h"
381
#include "hw/sysbus.h"
382
#include "qapi/error.h"
383
diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
384
index XXXXXXX..XXXXXXX 100644
385
--- a/hw/rtc/mc146818rtc.c
386
+++ b/hw/rtc/mc146818rtc.c
387
@@ -XXX,XX +XXX,XX @@
388
*/
389
390
#include "qemu/osdep.h"
391
-#include "qemu-common.h"
392
#include "qemu/cutils.h"
393
#include "qemu/module.h"
394
#include "qemu/bcd.h"
395
@@ -XXX,XX +XXX,XX @@
396
#include "sysemu/replay.h"
397
#include "sysemu/reset.h"
398
#include "sysemu/runstate.h"
399
+#include "sysemu/rtc.h"
400
#include "hw/rtc/mc146818rtc.h"
401
#include "hw/rtc/mc146818rtc_regs.h"
402
#include "migration/vmstate.h"
403
diff --git a/hw/rtc/pl031.c b/hw/rtc/pl031.c
404
index XXXXXXX..XXXXXXX 100644
405
--- a/hw/rtc/pl031.c
406
+++ b/hw/rtc/pl031.c
407
@@ -XXX,XX +XXX,XX @@
408
*/
409
410
#include "qemu/osdep.h"
411
-#include "qemu-common.h"
412
#include "hw/rtc/pl031.h"
413
#include "migration/vmstate.h"
414
#include "hw/irq.h"
415
@@ -XXX,XX +XXX,XX @@
416
#include "hw/sysbus.h"
417
#include "qemu/timer.h"
418
#include "sysemu/sysemu.h"
419
+#include "sysemu/rtc.h"
420
#include "qemu/cutils.h"
421
#include "qemu/log.h"
422
#include "qemu/module.h"
423
diff --git a/hw/rtc/twl92230.c b/hw/rtc/twl92230.c
424
index XXXXXXX..XXXXXXX 100644
425
--- a/hw/rtc/twl92230.c
426
+++ b/hw/rtc/twl92230.c
427
@@ -XXX,XX +XXX,XX @@
428
*/
429
430
#include "qemu/osdep.h"
431
-#include "qemu-common.h"
432
#include "qemu/timer.h"
433
#include "hw/i2c/i2c.h"
434
#include "hw/irq.h"
435
#include "migration/qemu-file-types.h"
436
#include "migration/vmstate.h"
437
#include "sysemu/sysemu.h"
438
+#include "sysemu/rtc.h"
439
#include "qemu/bcd.h"
440
#include "qemu/module.h"
441
#include "qom/object.h"
442
diff --git a/hw/rtc/xlnx-zynqmp-rtc.c b/hw/rtc/xlnx-zynqmp-rtc.c
443
index XXXXXXX..XXXXXXX 100644
444
--- a/hw/rtc/xlnx-zynqmp-rtc.c
445
+++ b/hw/rtc/xlnx-zynqmp-rtc.c
446
@@ -XXX,XX +XXX,XX @@
447
*/
448
449
#include "qemu/osdep.h"
450
-#include "qemu-common.h"
451
#include "hw/sysbus.h"
452
#include "hw/register.h"
453
#include "qemu/bitops.h"
454
@@ -XXX,XX +XXX,XX @@
455
#include "hw/irq.h"
456
#include "qemu/cutils.h"
457
#include "sysemu/sysemu.h"
458
+#include "sysemu/rtc.h"
459
#include "trace.h"
460
#include "hw/rtc/xlnx-zynqmp-rtc.h"
461
#include "migration/vmstate.h"
462
diff --git a/hw/s390x/tod-tcg.c b/hw/s390x/tod-tcg.c
463
index XXXXXXX..XXXXXXX 100644
464
--- a/hw/s390x/tod-tcg.c
465
+++ b/hw/s390x/tod-tcg.c
466
@@ -XXX,XX +XXX,XX @@
467
*/
468
469
#include "qemu/osdep.h"
470
-#include "qemu-common.h"
471
#include "qapi/error.h"
472
#include "hw/s390x/tod.h"
473
#include "qemu/timer.h"
474
@@ -XXX,XX +XXX,XX @@
475
#include "qemu/module.h"
476
#include "cpu.h"
477
#include "tcg/tcg_s390x.h"
478
+#include "sysemu/rtc.h"
479
480
static void qemu_s390_tod_get(const S390TODState *td, S390TOD *tod,
481
Error **errp)
482
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
483
index XXXXXXX..XXXXXXX 100644
484
--- a/hw/scsi/megasas.c
485
+++ b/hw/scsi/megasas.c
486
@@ -XXX,XX +XXX,XX @@
487
*/
488
489
#include "qemu/osdep.h"
490
-#include "qemu-common.h"
491
#include "hw/pci/pci.h"
492
#include "hw/qdev-properties.h"
493
#include "sysemu/dma.h"
494
#include "sysemu/block-backend.h"
495
+#include "sysemu/rtc.h"
496
#include "hw/pci/msi.h"
497
#include "hw/pci/msix.h"
498
#include "qemu/iov.h"
499
diff --git a/net/dump.c b/net/dump.c
500
index XXXXXXX..XXXXXXX 100644
501
--- a/net/dump.c
502
+++ b/net/dump.c
503
@@ -XXX,XX +XXX,XX @@
504
*/
505
506
#include "qemu/osdep.h"
507
-#include "qemu-common.h"
508
#include "clients.h"
509
#include "qapi/error.h"
510
#include "qemu/error-report.h"
511
@@ -XXX,XX +XXX,XX @@
512
#include "qapi/visitor.h"
513
#include "net/filter.h"
514
#include "qom/object.h"
515
+#include "sysemu/rtc.h"
516
517
typedef struct DumpState {
518
int64_t start_ts;
519
diff --git a/softmmu/rtc.c b/softmmu/rtc.c
520
index XXXXXXX..XXXXXXX 100644
521
--- a/softmmu/rtc.c
522
+++ b/softmmu/rtc.c
523
@@ -XXX,XX +XXX,XX @@
524
*/
525
526
#include "qemu/osdep.h"
527
-#include "qemu-common.h"
528
#include "qemu/cutils.h"
529
#include "qapi/error.h"
530
#include "qapi/qmp/qerror.h"
531
@@ -XXX,XX +XXX,XX @@
532
#include "qom/object.h"
533
#include "sysemu/replay.h"
534
#include "sysemu/sysemu.h"
535
+#include "sysemu/rtc.h"
536
537
static enum {
538
RTC_BASE_UTC,
539
--
540
2.25.1
541
542
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
2
2
3
Both lqspi_read() and lqspi_load_cache() expect a 32-bit
3
Add a model of Versal's PMC SLCR (system-level control registers).
4
aligned address.
5
4
6
>From UG1085 datasheet [*] chapter on 'Quad-SPI Controller':
5
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
7
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Transfer Size Limitations
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
8
Reviewed-by: Luc Michel <luc@lmichel.fr>
10
Because of the 32-bit wide TX, RX, and generic FIFO, all
9
Message-id: 20220121161141.14389-2-francisco.iglesias@xilinx.com
11
APB/AXI transfers must be an integer multiple of 4-bytes.
12
Shorter transfers are not possible.
13
14
Set MemoryRegionOps.impl values to force 32-bit accesses,
15
this way we are sure we do not access the lqspi_buf[] array
16
out of bound.
17
18
[*] https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf
19
20
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
21
Tested-by: Francisco Iglesias <frasse.iglesias@gmail.com>
22
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
11
---
25
hw/ssi/xilinx_spips.c | 4 ++++
12
include/hw/misc/xlnx-versal-pmc-iou-slcr.h | 78 ++
26
1 file changed, 4 insertions(+)
13
hw/misc/xlnx-versal-pmc-iou-slcr.c | 1446 ++++++++++++++++++++
14
hw/misc/meson.build | 5 +-
15
3 files changed, 1528 insertions(+), 1 deletion(-)
16
create mode 100644 include/hw/misc/xlnx-versal-pmc-iou-slcr.h
17
create mode 100644 hw/misc/xlnx-versal-pmc-iou-slcr.c
27
18
28
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
19
diff --git a/include/hw/misc/xlnx-versal-pmc-iou-slcr.h b/include/hw/misc/xlnx-versal-pmc-iou-slcr.h
29
index XXXXXXX..XXXXXXX 100644
20
new file mode 100644
30
--- a/hw/ssi/xilinx_spips.c
21
index XXXXXXX..XXXXXXX
31
+++ b/hw/ssi/xilinx_spips.c
22
--- /dev/null
32
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps lqspi_ops = {
23
+++ b/include/hw/misc/xlnx-versal-pmc-iou-slcr.h
33
.read_with_attrs = lqspi_read,
24
@@ -XXX,XX +XXX,XX @@
34
.write_with_attrs = lqspi_write,
25
+/*
35
.endianness = DEVICE_NATIVE_ENDIAN,
26
+ * Header file for the Xilinx Versal's PMC IOU SLCR
36
+ .impl = {
27
+ *
28
+ * Copyright (C) 2021 Xilinx Inc
29
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
30
+ *
31
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
32
+ * of this software and associated documentation files (the "Software"), to deal
33
+ * in the Software without restriction, including without limitation the rights
34
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35
+ * copies of the Software, and to permit persons to whom the Software is
36
+ * furnished to do so, subject to the following conditions:
37
+ *
38
+ * The above copyright notice and this permission notice shall be included in
39
+ * all copies or substantial portions of the Software.
40
+ *
41
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
44
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
47
+ * THE SOFTWARE.
48
+ */
49
+
50
+/*
51
+ * This is a model of Xilinx Versal's PMC I/O Peripheral Control and Status
52
+ * module documented in Versal's Technical Reference manual [1] and the Versal
53
+ * ACAP Register reference [2].
54
+ *
55
+ * References:
56
+ *
57
+ * [1] Versal ACAP Technical Reference Manual,
58
+ * https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
59
+ *
60
+ * [2] Versal ACAP Register Reference,
61
+ * https://www.xilinx.com/html_docs/registers/am012/am012-versal-register-reference.html#mod___pmc_iop_slcr.html
62
+ *
63
+ * QEMU interface:
64
+ * + sysbus MMIO region 0: MemoryRegion for the device's registers
65
+ * + sysbus IRQ 0: PMC (AXI and APB) parity error interrupt detected by the PMC
66
+ * I/O peripherals.
67
+ * + sysbus IRQ 1: Device interrupt.
68
+ * + Named GPIO output "sd-emmc-sel[0]": Enables 0: SD mode or 1: eMMC mode on
69
+ * SD/eMMC controller 0.
70
+ * + Named GPIO output "sd-emmc-sel[1]": Enables 0: SD mode or 1: eMMC mode on
71
+ * SD/eMMC controller 1.
72
+ * + Named GPIO output "qspi-ospi-mux-sel": Selects 0: QSPI linear region or 1:
73
+ * OSPI linear region.
74
+ * + Named GPIO output "ospi-mux-sel": Selects 0: OSPI Indirect access mode or
75
+ * 1: OSPI direct access mode.
76
+ */
77
+
78
+#ifndef XILINX_VERSAL_PMC_IOU_SLCR_H
79
+#define XILINX_VERSAL_PMC_IOU_SLCR_H
80
+
81
+#include "hw/register.h"
82
+
83
+#define TYPE_XILINX_VERSAL_PMC_IOU_SLCR "xlnx.versal-pmc-iou-slcr"
84
+
85
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalPmcIouSlcr, XILINX_VERSAL_PMC_IOU_SLCR)
86
+
87
+#define XILINX_VERSAL_PMC_IOU_SLCR_R_MAX (0x828 / 4 + 1)
88
+
89
+struct XlnxVersalPmcIouSlcr {
90
+ SysBusDevice parent_obj;
91
+ MemoryRegion iomem;
92
+ qemu_irq irq_parity_imr;
93
+ qemu_irq irq_imr;
94
+ qemu_irq sd_emmc_sel[2];
95
+ qemu_irq qspi_ospi_mux_sel;
96
+ qemu_irq ospi_mux_sel;
97
+
98
+ uint32_t regs[XILINX_VERSAL_PMC_IOU_SLCR_R_MAX];
99
+ RegisterInfo regs_info[XILINX_VERSAL_PMC_IOU_SLCR_R_MAX];
100
+};
101
+
102
+#endif /* XILINX_VERSAL_PMC_IOU_SLCR_H */
103
diff --git a/hw/misc/xlnx-versal-pmc-iou-slcr.c b/hw/misc/xlnx-versal-pmc-iou-slcr.c
104
new file mode 100644
105
index XXXXXXX..XXXXXXX
106
--- /dev/null
107
+++ b/hw/misc/xlnx-versal-pmc-iou-slcr.c
108
@@ -XXX,XX +XXX,XX @@
109
+/*
110
+ * QEMU model of Versal's PMC IOU SLCR (system level control registers)
111
+ *
112
+ * Copyright (c) 2021 Xilinx Inc.
113
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
114
+ *
115
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
116
+ * of this software and associated documentation files (the "Software"), to deal
117
+ * in the Software without restriction, including without limitation the rights
118
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
119
+ * copies of the Software, and to permit persons to whom the Software is
120
+ * furnished to do so, subject to the following conditions:
121
+ *
122
+ * The above copyright notice and this permission notice shall be included in
123
+ * all copies or substantial portions of the Software.
124
+ *
125
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
126
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
127
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
128
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
129
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
130
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
131
+ * THE SOFTWARE.
132
+ */
133
+
134
+#include "qemu/osdep.h"
135
+#include "hw/sysbus.h"
136
+#include "hw/register.h"
137
+#include "hw/irq.h"
138
+#include "qemu/bitops.h"
139
+#include "qemu/log.h"
140
+#include "migration/vmstate.h"
141
+#include "hw/qdev-properties.h"
142
+#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
143
+
144
+#ifndef XILINX_VERSAL_PMC_IOU_SLCR_ERR_DEBUG
145
+#define XILINX_VERSAL_PMC_IOU_SLCR_ERR_DEBUG 0
146
+#endif
147
+
148
+REG32(MIO_PIN_0, 0x0)
149
+ FIELD(MIO_PIN_0, L3_SEL, 7, 3)
150
+ FIELD(MIO_PIN_0, L2_SEL, 5, 2)
151
+ FIELD(MIO_PIN_0, L1_SEL, 3, 2)
152
+ FIELD(MIO_PIN_0, L0_SEL, 1, 2)
153
+REG32(MIO_PIN_1, 0x4)
154
+ FIELD(MIO_PIN_1, L3_SEL, 7, 3)
155
+ FIELD(MIO_PIN_1, L2_SEL, 5, 2)
156
+ FIELD(MIO_PIN_1, L1_SEL, 3, 2)
157
+ FIELD(MIO_PIN_1, L0_SEL, 1, 2)
158
+REG32(MIO_PIN_2, 0x8)
159
+ FIELD(MIO_PIN_2, L3_SEL, 7, 3)
160
+ FIELD(MIO_PIN_2, L2_SEL, 5, 2)
161
+ FIELD(MIO_PIN_2, L1_SEL, 3, 2)
162
+ FIELD(MIO_PIN_2, L0_SEL, 1, 2)
163
+REG32(MIO_PIN_3, 0xc)
164
+ FIELD(MIO_PIN_3, L3_SEL, 7, 3)
165
+ FIELD(MIO_PIN_3, L2_SEL, 5, 2)
166
+ FIELD(MIO_PIN_3, L1_SEL, 3, 2)
167
+ FIELD(MIO_PIN_3, L0_SEL, 1, 2)
168
+REG32(MIO_PIN_4, 0x10)
169
+ FIELD(MIO_PIN_4, L3_SEL, 7, 3)
170
+ FIELD(MIO_PIN_4, L2_SEL, 5, 2)
171
+ FIELD(MIO_PIN_4, L1_SEL, 3, 2)
172
+ FIELD(MIO_PIN_4, L0_SEL, 1, 2)
173
+REG32(MIO_PIN_5, 0x14)
174
+ FIELD(MIO_PIN_5, L3_SEL, 7, 3)
175
+ FIELD(MIO_PIN_5, L2_SEL, 5, 2)
176
+ FIELD(MIO_PIN_5, L1_SEL, 3, 2)
177
+ FIELD(MIO_PIN_5, L0_SEL, 1, 2)
178
+REG32(MIO_PIN_6, 0x18)
179
+ FIELD(MIO_PIN_6, L3_SEL, 7, 3)
180
+ FIELD(MIO_PIN_6, L2_SEL, 5, 2)
181
+ FIELD(MIO_PIN_6, L1_SEL, 3, 2)
182
+ FIELD(MIO_PIN_6, L0_SEL, 1, 2)
183
+REG32(MIO_PIN_7, 0x1c)
184
+ FIELD(MIO_PIN_7, L3_SEL, 7, 3)
185
+ FIELD(MIO_PIN_7, L2_SEL, 5, 2)
186
+ FIELD(MIO_PIN_7, L1_SEL, 3, 2)
187
+ FIELD(MIO_PIN_7, L0_SEL, 1, 2)
188
+REG32(MIO_PIN_8, 0x20)
189
+ FIELD(MIO_PIN_8, L3_SEL, 7, 3)
190
+ FIELD(MIO_PIN_8, L2_SEL, 5, 2)
191
+ FIELD(MIO_PIN_8, L1_SEL, 3, 2)
192
+ FIELD(MIO_PIN_8, L0_SEL, 1, 2)
193
+REG32(MIO_PIN_9, 0x24)
194
+ FIELD(MIO_PIN_9, L3_SEL, 7, 3)
195
+ FIELD(MIO_PIN_9, L2_SEL, 5, 2)
196
+ FIELD(MIO_PIN_9, L1_SEL, 3, 2)
197
+ FIELD(MIO_PIN_9, L0_SEL, 1, 2)
198
+REG32(MIO_PIN_10, 0x28)
199
+ FIELD(MIO_PIN_10, L3_SEL, 7, 3)
200
+ FIELD(MIO_PIN_10, L2_SEL, 5, 2)
201
+ FIELD(MIO_PIN_10, L1_SEL, 3, 2)
202
+ FIELD(MIO_PIN_10, L0_SEL, 1, 2)
203
+REG32(MIO_PIN_11, 0x2c)
204
+ FIELD(MIO_PIN_11, L3_SEL, 7, 3)
205
+ FIELD(MIO_PIN_11, L2_SEL, 5, 2)
206
+ FIELD(MIO_PIN_11, L1_SEL, 3, 2)
207
+ FIELD(MIO_PIN_11, L0_SEL, 1, 2)
208
+REG32(MIO_PIN_12, 0x30)
209
+ FIELD(MIO_PIN_12, L3_SEL, 7, 3)
210
+ FIELD(MIO_PIN_12, L2_SEL, 5, 2)
211
+ FIELD(MIO_PIN_12, L1_SEL, 3, 2)
212
+ FIELD(MIO_PIN_12, L0_SEL, 1, 2)
213
+REG32(MIO_PIN_13, 0x34)
214
+ FIELD(MIO_PIN_13, L3_SEL, 7, 3)
215
+ FIELD(MIO_PIN_13, L2_SEL, 5, 2)
216
+ FIELD(MIO_PIN_13, L1_SEL, 3, 2)
217
+ FIELD(MIO_PIN_13, L0_SEL, 1, 2)
218
+REG32(MIO_PIN_14, 0x38)
219
+ FIELD(MIO_PIN_14, L3_SEL, 7, 3)
220
+ FIELD(MIO_PIN_14, L2_SEL, 5, 2)
221
+ FIELD(MIO_PIN_14, L1_SEL, 3, 2)
222
+ FIELD(MIO_PIN_14, L0_SEL, 1, 2)
223
+REG32(MIO_PIN_15, 0x3c)
224
+ FIELD(MIO_PIN_15, L3_SEL, 7, 3)
225
+ FIELD(MIO_PIN_15, L2_SEL, 5, 2)
226
+ FIELD(MIO_PIN_15, L1_SEL, 3, 2)
227
+ FIELD(MIO_PIN_15, L0_SEL, 1, 2)
228
+REG32(MIO_PIN_16, 0x40)
229
+ FIELD(MIO_PIN_16, L3_SEL, 7, 3)
230
+ FIELD(MIO_PIN_16, L2_SEL, 5, 2)
231
+ FIELD(MIO_PIN_16, L1_SEL, 3, 2)
232
+ FIELD(MIO_PIN_16, L0_SEL, 1, 2)
233
+REG32(MIO_PIN_17, 0x44)
234
+ FIELD(MIO_PIN_17, L3_SEL, 7, 3)
235
+ FIELD(MIO_PIN_17, L2_SEL, 5, 2)
236
+ FIELD(MIO_PIN_17, L1_SEL, 3, 2)
237
+ FIELD(MIO_PIN_17, L0_SEL, 1, 2)
238
+REG32(MIO_PIN_18, 0x48)
239
+ FIELD(MIO_PIN_18, L3_SEL, 7, 3)
240
+ FIELD(MIO_PIN_18, L2_SEL, 5, 2)
241
+ FIELD(MIO_PIN_18, L1_SEL, 3, 2)
242
+ FIELD(MIO_PIN_18, L0_SEL, 1, 2)
243
+REG32(MIO_PIN_19, 0x4c)
244
+ FIELD(MIO_PIN_19, L3_SEL, 7, 3)
245
+ FIELD(MIO_PIN_19, L2_SEL, 5, 2)
246
+ FIELD(MIO_PIN_19, L1_SEL, 3, 2)
247
+ FIELD(MIO_PIN_19, L0_SEL, 1, 2)
248
+REG32(MIO_PIN_20, 0x50)
249
+ FIELD(MIO_PIN_20, L3_SEL, 7, 3)
250
+ FIELD(MIO_PIN_20, L2_SEL, 5, 2)
251
+ FIELD(MIO_PIN_20, L1_SEL, 3, 2)
252
+ FIELD(MIO_PIN_20, L0_SEL, 1, 2)
253
+REG32(MIO_PIN_21, 0x54)
254
+ FIELD(MIO_PIN_21, L3_SEL, 7, 3)
255
+ FIELD(MIO_PIN_21, L2_SEL, 5, 2)
256
+ FIELD(MIO_PIN_21, L1_SEL, 3, 2)
257
+ FIELD(MIO_PIN_21, L0_SEL, 1, 2)
258
+REG32(MIO_PIN_22, 0x58)
259
+ FIELD(MIO_PIN_22, L3_SEL, 7, 3)
260
+ FIELD(MIO_PIN_22, L2_SEL, 5, 2)
261
+ FIELD(MIO_PIN_22, L1_SEL, 3, 2)
262
+ FIELD(MIO_PIN_22, L0_SEL, 1, 2)
263
+REG32(MIO_PIN_23, 0x5c)
264
+ FIELD(MIO_PIN_23, L3_SEL, 7, 3)
265
+ FIELD(MIO_PIN_23, L2_SEL, 5, 2)
266
+ FIELD(MIO_PIN_23, L1_SEL, 3, 2)
267
+ FIELD(MIO_PIN_23, L0_SEL, 1, 2)
268
+REG32(MIO_PIN_24, 0x60)
269
+ FIELD(MIO_PIN_24, L3_SEL, 7, 3)
270
+ FIELD(MIO_PIN_24, L2_SEL, 5, 2)
271
+ FIELD(MIO_PIN_24, L1_SEL, 3, 2)
272
+ FIELD(MIO_PIN_24, L0_SEL, 1, 2)
273
+REG32(MIO_PIN_25, 0x64)
274
+ FIELD(MIO_PIN_25, L3_SEL, 7, 3)
275
+ FIELD(MIO_PIN_25, L2_SEL, 5, 2)
276
+ FIELD(MIO_PIN_25, L1_SEL, 3, 2)
277
+ FIELD(MIO_PIN_25, L0_SEL, 1, 2)
278
+REG32(MIO_PIN_26, 0x68)
279
+ FIELD(MIO_PIN_26, L3_SEL, 7, 3)
280
+ FIELD(MIO_PIN_26, L2_SEL, 5, 2)
281
+ FIELD(MIO_PIN_26, L1_SEL, 3, 2)
282
+ FIELD(MIO_PIN_26, L0_SEL, 1, 2)
283
+REG32(MIO_PIN_27, 0x6c)
284
+ FIELD(MIO_PIN_27, L3_SEL, 7, 3)
285
+ FIELD(MIO_PIN_27, L2_SEL, 5, 2)
286
+ FIELD(MIO_PIN_27, L1_SEL, 3, 2)
287
+ FIELD(MIO_PIN_27, L0_SEL, 1, 2)
288
+REG32(MIO_PIN_28, 0x70)
289
+ FIELD(MIO_PIN_28, L3_SEL, 7, 3)
290
+ FIELD(MIO_PIN_28, L2_SEL, 5, 2)
291
+ FIELD(MIO_PIN_28, L1_SEL, 3, 2)
292
+ FIELD(MIO_PIN_28, L0_SEL, 1, 2)
293
+REG32(MIO_PIN_29, 0x74)
294
+ FIELD(MIO_PIN_29, L3_SEL, 7, 3)
295
+ FIELD(MIO_PIN_29, L2_SEL, 5, 2)
296
+ FIELD(MIO_PIN_29, L1_SEL, 3, 2)
297
+ FIELD(MIO_PIN_29, L0_SEL, 1, 2)
298
+REG32(MIO_PIN_30, 0x78)
299
+ FIELD(MIO_PIN_30, L3_SEL, 7, 3)
300
+ FIELD(MIO_PIN_30, L2_SEL, 5, 2)
301
+ FIELD(MIO_PIN_30, L1_SEL, 3, 2)
302
+ FIELD(MIO_PIN_30, L0_SEL, 1, 2)
303
+REG32(MIO_PIN_31, 0x7c)
304
+ FIELD(MIO_PIN_31, L3_SEL, 7, 3)
305
+ FIELD(MIO_PIN_31, L2_SEL, 5, 2)
306
+ FIELD(MIO_PIN_31, L1_SEL, 3, 2)
307
+ FIELD(MIO_PIN_31, L0_SEL, 1, 2)
308
+REG32(MIO_PIN_32, 0x80)
309
+ FIELD(MIO_PIN_32, L3_SEL, 7, 3)
310
+ FIELD(MIO_PIN_32, L2_SEL, 5, 2)
311
+ FIELD(MIO_PIN_32, L1_SEL, 3, 2)
312
+ FIELD(MIO_PIN_32, L0_SEL, 1, 2)
313
+REG32(MIO_PIN_33, 0x84)
314
+ FIELD(MIO_PIN_33, L3_SEL, 7, 3)
315
+ FIELD(MIO_PIN_33, L2_SEL, 5, 2)
316
+ FIELD(MIO_PIN_33, L1_SEL, 3, 2)
317
+ FIELD(MIO_PIN_33, L0_SEL, 1, 2)
318
+REG32(MIO_PIN_34, 0x88)
319
+ FIELD(MIO_PIN_34, L3_SEL, 7, 3)
320
+ FIELD(MIO_PIN_34, L2_SEL, 5, 2)
321
+ FIELD(MIO_PIN_34, L1_SEL, 3, 2)
322
+ FIELD(MIO_PIN_34, L0_SEL, 1, 2)
323
+REG32(MIO_PIN_35, 0x8c)
324
+ FIELD(MIO_PIN_35, L3_SEL, 7, 3)
325
+ FIELD(MIO_PIN_35, L2_SEL, 5, 2)
326
+ FIELD(MIO_PIN_35, L1_SEL, 3, 2)
327
+ FIELD(MIO_PIN_35, L0_SEL, 1, 2)
328
+REG32(MIO_PIN_36, 0x90)
329
+ FIELD(MIO_PIN_36, L3_SEL, 7, 3)
330
+ FIELD(MIO_PIN_36, L2_SEL, 5, 2)
331
+ FIELD(MIO_PIN_36, L1_SEL, 3, 2)
332
+ FIELD(MIO_PIN_36, L0_SEL, 1, 2)
333
+REG32(MIO_PIN_37, 0x94)
334
+ FIELD(MIO_PIN_37, L3_SEL, 7, 3)
335
+ FIELD(MIO_PIN_37, L2_SEL, 5, 2)
336
+ FIELD(MIO_PIN_37, L1_SEL, 3, 2)
337
+ FIELD(MIO_PIN_37, L0_SEL, 1, 2)
338
+REG32(MIO_PIN_38, 0x98)
339
+ FIELD(MIO_PIN_38, L3_SEL, 7, 3)
340
+ FIELD(MIO_PIN_38, L2_SEL, 5, 2)
341
+ FIELD(MIO_PIN_38, L1_SEL, 3, 2)
342
+ FIELD(MIO_PIN_38, L0_SEL, 1, 2)
343
+REG32(MIO_PIN_39, 0x9c)
344
+ FIELD(MIO_PIN_39, L3_SEL, 7, 3)
345
+ FIELD(MIO_PIN_39, L2_SEL, 5, 2)
346
+ FIELD(MIO_PIN_39, L1_SEL, 3, 2)
347
+ FIELD(MIO_PIN_39, L0_SEL, 1, 2)
348
+REG32(MIO_PIN_40, 0xa0)
349
+ FIELD(MIO_PIN_40, L3_SEL, 7, 3)
350
+ FIELD(MIO_PIN_40, L2_SEL, 5, 2)
351
+ FIELD(MIO_PIN_40, L1_SEL, 3, 2)
352
+ FIELD(MIO_PIN_40, L0_SEL, 1, 2)
353
+REG32(MIO_PIN_41, 0xa4)
354
+ FIELD(MIO_PIN_41, L3_SEL, 7, 3)
355
+ FIELD(MIO_PIN_41, L2_SEL, 5, 2)
356
+ FIELD(MIO_PIN_41, L1_SEL, 3, 2)
357
+ FIELD(MIO_PIN_41, L0_SEL, 1, 2)
358
+REG32(MIO_PIN_42, 0xa8)
359
+ FIELD(MIO_PIN_42, L3_SEL, 7, 3)
360
+ FIELD(MIO_PIN_42, L2_SEL, 5, 2)
361
+ FIELD(MIO_PIN_42, L1_SEL, 3, 2)
362
+ FIELD(MIO_PIN_42, L0_SEL, 1, 2)
363
+REG32(MIO_PIN_43, 0xac)
364
+ FIELD(MIO_PIN_43, L3_SEL, 7, 3)
365
+ FIELD(MIO_PIN_43, L2_SEL, 5, 2)
366
+ FIELD(MIO_PIN_43, L1_SEL, 3, 2)
367
+ FIELD(MIO_PIN_43, L0_SEL, 1, 2)
368
+REG32(MIO_PIN_44, 0xb0)
369
+ FIELD(MIO_PIN_44, L3_SEL, 7, 3)
370
+ FIELD(MIO_PIN_44, L2_SEL, 5, 2)
371
+ FIELD(MIO_PIN_44, L1_SEL, 3, 2)
372
+ FIELD(MIO_PIN_44, L0_SEL, 1, 2)
373
+REG32(MIO_PIN_45, 0xb4)
374
+ FIELD(MIO_PIN_45, L3_SEL, 7, 3)
375
+ FIELD(MIO_PIN_45, L2_SEL, 5, 2)
376
+ FIELD(MIO_PIN_45, L1_SEL, 3, 2)
377
+ FIELD(MIO_PIN_45, L0_SEL, 1, 2)
378
+REG32(MIO_PIN_46, 0xb8)
379
+ FIELD(MIO_PIN_46, L3_SEL, 7, 3)
380
+ FIELD(MIO_PIN_46, L2_SEL, 5, 2)
381
+ FIELD(MIO_PIN_46, L1_SEL, 3, 2)
382
+ FIELD(MIO_PIN_46, L0_SEL, 1, 2)
383
+REG32(MIO_PIN_47, 0xbc)
384
+ FIELD(MIO_PIN_47, L3_SEL, 7, 3)
385
+ FIELD(MIO_PIN_47, L2_SEL, 5, 2)
386
+ FIELD(MIO_PIN_47, L1_SEL, 3, 2)
387
+ FIELD(MIO_PIN_47, L0_SEL, 1, 2)
388
+REG32(MIO_PIN_48, 0xc0)
389
+ FIELD(MIO_PIN_48, L3_SEL, 7, 3)
390
+ FIELD(MIO_PIN_48, L2_SEL, 5, 2)
391
+ FIELD(MIO_PIN_48, L1_SEL, 3, 2)
392
+ FIELD(MIO_PIN_48, L0_SEL, 1, 2)
393
+REG32(MIO_PIN_49, 0xc4)
394
+ FIELD(MIO_PIN_49, L3_SEL, 7, 3)
395
+ FIELD(MIO_PIN_49, L2_SEL, 5, 2)
396
+ FIELD(MIO_PIN_49, L1_SEL, 3, 2)
397
+ FIELD(MIO_PIN_49, L0_SEL, 1, 2)
398
+REG32(MIO_PIN_50, 0xc8)
399
+ FIELD(MIO_PIN_50, L3_SEL, 7, 3)
400
+ FIELD(MIO_PIN_50, L2_SEL, 5, 2)
401
+ FIELD(MIO_PIN_50, L1_SEL, 3, 2)
402
+ FIELD(MIO_PIN_50, L0_SEL, 1, 2)
403
+REG32(MIO_PIN_51, 0xcc)
404
+ FIELD(MIO_PIN_51, L3_SEL, 7, 3)
405
+ FIELD(MIO_PIN_51, L2_SEL, 5, 2)
406
+ FIELD(MIO_PIN_51, L1_SEL, 3, 2)
407
+ FIELD(MIO_PIN_51, L0_SEL, 1, 2)
408
+REG32(BNK0_EN_RX, 0x100)
409
+ FIELD(BNK0_EN_RX, BNK0_EN_RX, 0, 26)
410
+REG32(BNK0_SEL_RX0, 0x104)
411
+REG32(BNK0_SEL_RX1, 0x108)
412
+ FIELD(BNK0_SEL_RX1, BNK0_SEL_RX, 0, 20)
413
+REG32(BNK0_EN_RX_SCHMITT_HYST, 0x10c)
414
+ FIELD(BNK0_EN_RX_SCHMITT_HYST, BNK0_EN_RX_SCHMITT_HYST, 0, 26)
415
+REG32(BNK0_EN_WK_PD, 0x110)
416
+ FIELD(BNK0_EN_WK_PD, BNK0_EN_WK_PD, 0, 26)
417
+REG32(BNK0_EN_WK_PU, 0x114)
418
+ FIELD(BNK0_EN_WK_PU, BNK0_EN_WK_PU, 0, 26)
419
+REG32(BNK0_SEL_DRV0, 0x118)
420
+REG32(BNK0_SEL_DRV1, 0x11c)
421
+ FIELD(BNK0_SEL_DRV1, BNK0_SEL_DRV, 0, 20)
422
+REG32(BNK0_SEL_SLEW, 0x120)
423
+ FIELD(BNK0_SEL_SLEW, BNK0_SEL_SLEW, 0, 26)
424
+REG32(BNK0_EN_DFT_OPT_INV, 0x124)
425
+ FIELD(BNK0_EN_DFT_OPT_INV, BNK0_EN_DFT_OPT_INV, 0, 26)
426
+REG32(BNK0_EN_PAD2PAD_LOOPBACK, 0x128)
427
+ FIELD(BNK0_EN_PAD2PAD_LOOPBACK, BNK0_EN_PAD2PAD_LOOPBACK, 0, 13)
428
+REG32(BNK0_RX_SPARE0, 0x12c)
429
+REG32(BNK0_RX_SPARE1, 0x130)
430
+ FIELD(BNK0_RX_SPARE1, BNK0_RX_SPARE, 0, 20)
431
+REG32(BNK0_TX_SPARE0, 0x134)
432
+REG32(BNK0_TX_SPARE1, 0x138)
433
+ FIELD(BNK0_TX_SPARE1, BNK0_TX_SPARE, 0, 20)
434
+REG32(BNK0_SEL_EN1P8, 0x13c)
435
+ FIELD(BNK0_SEL_EN1P8, BNK0_SEL_EN1P8, 0, 1)
436
+REG32(BNK0_EN_B_POR_DETECT, 0x140)
437
+ FIELD(BNK0_EN_B_POR_DETECT, BNK0_EN_B_POR_DETECT, 0, 1)
438
+REG32(BNK0_LPF_BYP_POR_DETECT, 0x144)
439
+ FIELD(BNK0_LPF_BYP_POR_DETECT, BNK0_LPF_BYP_POR_DETECT, 0, 1)
440
+REG32(BNK0_EN_LATCH, 0x148)
441
+ FIELD(BNK0_EN_LATCH, BNK0_EN_LATCH, 0, 1)
442
+REG32(BNK0_VBG_LPF_BYP_B, 0x14c)
443
+ FIELD(BNK0_VBG_LPF_BYP_B, BNK0_VBG_LPF_BYP_B, 0, 1)
444
+REG32(BNK0_EN_AMP_B, 0x150)
445
+ FIELD(BNK0_EN_AMP_B, BNK0_EN_AMP_B, 0, 2)
446
+REG32(BNK0_SPARE_BIAS, 0x154)
447
+ FIELD(BNK0_SPARE_BIAS, BNK0_SPARE_BIAS, 0, 4)
448
+REG32(BNK0_DRIVER_BIAS, 0x158)
449
+ FIELD(BNK0_DRIVER_BIAS, BNK0_DRIVER_BIAS, 0, 15)
450
+REG32(BNK0_VMODE, 0x15c)
451
+ FIELD(BNK0_VMODE, BNK0_VMODE, 0, 1)
452
+REG32(BNK0_SEL_AUX_IO_RX, 0x160)
453
+ FIELD(BNK0_SEL_AUX_IO_RX, BNK0_SEL_AUX_IO_RX, 0, 26)
454
+REG32(BNK0_EN_TX_HS_MODE, 0x164)
455
+ FIELD(BNK0_EN_TX_HS_MODE, BNK0_EN_TX_HS_MODE, 0, 26)
456
+REG32(MIO_MST_TRI0, 0x200)
457
+ FIELD(MIO_MST_TRI0, PIN_25_TRI, 25, 1)
458
+ FIELD(MIO_MST_TRI0, PIN_24_TRI, 24, 1)
459
+ FIELD(MIO_MST_TRI0, PIN_23_TRI, 23, 1)
460
+ FIELD(MIO_MST_TRI0, PIN_22_TRI, 22, 1)
461
+ FIELD(MIO_MST_TRI0, PIN_21_TRI, 21, 1)
462
+ FIELD(MIO_MST_TRI0, PIN_20_TRI, 20, 1)
463
+ FIELD(MIO_MST_TRI0, PIN_19_TRI, 19, 1)
464
+ FIELD(MIO_MST_TRI0, PIN_18_TRI, 18, 1)
465
+ FIELD(MIO_MST_TRI0, PIN_17_TRI, 17, 1)
466
+ FIELD(MIO_MST_TRI0, PIN_16_TRI, 16, 1)
467
+ FIELD(MIO_MST_TRI0, PIN_15_TRI, 15, 1)
468
+ FIELD(MIO_MST_TRI0, PIN_14_TRI, 14, 1)
469
+ FIELD(MIO_MST_TRI0, PIN_13_TRI, 13, 1)
470
+ FIELD(MIO_MST_TRI0, PIN_12_TRI, 12, 1)
471
+ FIELD(MIO_MST_TRI0, PIN_11_TRI, 11, 1)
472
+ FIELD(MIO_MST_TRI0, PIN_10_TRI, 10, 1)
473
+ FIELD(MIO_MST_TRI0, PIN_09_TRI, 9, 1)
474
+ FIELD(MIO_MST_TRI0, PIN_08_TRI, 8, 1)
475
+ FIELD(MIO_MST_TRI0, PIN_07_TRI, 7, 1)
476
+ FIELD(MIO_MST_TRI0, PIN_06_TRI, 6, 1)
477
+ FIELD(MIO_MST_TRI0, PIN_05_TRI, 5, 1)
478
+ FIELD(MIO_MST_TRI0, PIN_04_TRI, 4, 1)
479
+ FIELD(MIO_MST_TRI0, PIN_03_TRI, 3, 1)
480
+ FIELD(MIO_MST_TRI0, PIN_02_TRI, 2, 1)
481
+ FIELD(MIO_MST_TRI0, PIN_01_TRI, 1, 1)
482
+ FIELD(MIO_MST_TRI0, PIN_00_TRI, 0, 1)
483
+REG32(MIO_MST_TRI1, 0x204)
484
+ FIELD(MIO_MST_TRI1, PIN_51_TRI, 25, 1)
485
+ FIELD(MIO_MST_TRI1, PIN_50_TRI, 24, 1)
486
+ FIELD(MIO_MST_TRI1, PIN_49_TRI, 23, 1)
487
+ FIELD(MIO_MST_TRI1, PIN_48_TRI, 22, 1)
488
+ FIELD(MIO_MST_TRI1, PIN_47_TRI, 21, 1)
489
+ FIELD(MIO_MST_TRI1, PIN_46_TRI, 20, 1)
490
+ FIELD(MIO_MST_TRI1, PIN_45_TRI, 19, 1)
491
+ FIELD(MIO_MST_TRI1, PIN_44_TRI, 18, 1)
492
+ FIELD(MIO_MST_TRI1, PIN_43_TRI, 17, 1)
493
+ FIELD(MIO_MST_TRI1, PIN_42_TRI, 16, 1)
494
+ FIELD(MIO_MST_TRI1, PIN_41_TRI, 15, 1)
495
+ FIELD(MIO_MST_TRI1, PIN_40_TRI, 14, 1)
496
+ FIELD(MIO_MST_TRI1, PIN_39_TRI, 13, 1)
497
+ FIELD(MIO_MST_TRI1, PIN_38_TRI, 12, 1)
498
+ FIELD(MIO_MST_TRI1, PIN_37_TRI, 11, 1)
499
+ FIELD(MIO_MST_TRI1, PIN_36_TRI, 10, 1)
500
+ FIELD(MIO_MST_TRI1, PIN_35_TRI, 9, 1)
501
+ FIELD(MIO_MST_TRI1, PIN_34_TRI, 8, 1)
502
+ FIELD(MIO_MST_TRI1, PIN_33_TRI, 7, 1)
503
+ FIELD(MIO_MST_TRI1, PIN_32_TRI, 6, 1)
504
+ FIELD(MIO_MST_TRI1, PIN_31_TRI, 5, 1)
505
+ FIELD(MIO_MST_TRI1, PIN_30_TRI, 4, 1)
506
+ FIELD(MIO_MST_TRI1, PIN_29_TRI, 3, 1)
507
+ FIELD(MIO_MST_TRI1, PIN_28_TRI, 2, 1)
508
+ FIELD(MIO_MST_TRI1, PIN_27_TRI, 1, 1)
509
+ FIELD(MIO_MST_TRI1, PIN_26_TRI, 0, 1)
510
+REG32(BNK1_EN_RX, 0x300)
511
+ FIELD(BNK1_EN_RX, BNK1_EN_RX, 0, 26)
512
+REG32(BNK1_SEL_RX0, 0x304)
513
+REG32(BNK1_SEL_RX1, 0x308)
514
+ FIELD(BNK1_SEL_RX1, BNK1_SEL_RX, 0, 20)
515
+REG32(BNK1_EN_RX_SCHMITT_HYST, 0x30c)
516
+ FIELD(BNK1_EN_RX_SCHMITT_HYST, BNK1_EN_RX_SCHMITT_HYST, 0, 26)
517
+REG32(BNK1_EN_WK_PD, 0x310)
518
+ FIELD(BNK1_EN_WK_PD, BNK1_EN_WK_PD, 0, 26)
519
+REG32(BNK1_EN_WK_PU, 0x314)
520
+ FIELD(BNK1_EN_WK_PU, BNK1_EN_WK_PU, 0, 26)
521
+REG32(BNK1_SEL_DRV0, 0x318)
522
+REG32(BNK1_SEL_DRV1, 0x31c)
523
+ FIELD(BNK1_SEL_DRV1, BNK1_SEL_DRV, 0, 20)
524
+REG32(BNK1_SEL_SLEW, 0x320)
525
+ FIELD(BNK1_SEL_SLEW, BNK1_SEL_SLEW, 0, 26)
526
+REG32(BNK1_EN_DFT_OPT_INV, 0x324)
527
+ FIELD(BNK1_EN_DFT_OPT_INV, BNK1_EN_DFT_OPT_INV, 0, 26)
528
+REG32(BNK1_EN_PAD2PAD_LOOPBACK, 0x328)
529
+ FIELD(BNK1_EN_PAD2PAD_LOOPBACK, BNK1_EN_PAD2PAD_LOOPBACK, 0, 13)
530
+REG32(BNK1_RX_SPARE0, 0x32c)
531
+REG32(BNK1_RX_SPARE1, 0x330)
532
+ FIELD(BNK1_RX_SPARE1, BNK1_RX_SPARE, 0, 20)
533
+REG32(BNK1_TX_SPARE0, 0x334)
534
+REG32(BNK1_TX_SPARE1, 0x338)
535
+ FIELD(BNK1_TX_SPARE1, BNK1_TX_SPARE, 0, 20)
536
+REG32(BNK1_SEL_EN1P8, 0x33c)
537
+ FIELD(BNK1_SEL_EN1P8, BNK1_SEL_EN1P8, 0, 1)
538
+REG32(BNK1_EN_B_POR_DETECT, 0x340)
539
+ FIELD(BNK1_EN_B_POR_DETECT, BNK1_EN_B_POR_DETECT, 0, 1)
540
+REG32(BNK1_LPF_BYP_POR_DETECT, 0x344)
541
+ FIELD(BNK1_LPF_BYP_POR_DETECT, BNK1_LPF_BYP_POR_DETECT, 0, 1)
542
+REG32(BNK1_EN_LATCH, 0x348)
543
+ FIELD(BNK1_EN_LATCH, BNK1_EN_LATCH, 0, 1)
544
+REG32(BNK1_VBG_LPF_BYP_B, 0x34c)
545
+ FIELD(BNK1_VBG_LPF_BYP_B, BNK1_VBG_LPF_BYP_B, 0, 1)
546
+REG32(BNK1_EN_AMP_B, 0x350)
547
+ FIELD(BNK1_EN_AMP_B, BNK1_EN_AMP_B, 0, 2)
548
+REG32(BNK1_SPARE_BIAS, 0x354)
549
+ FIELD(BNK1_SPARE_BIAS, BNK1_SPARE_BIAS, 0, 4)
550
+REG32(BNK1_DRIVER_BIAS, 0x358)
551
+ FIELD(BNK1_DRIVER_BIAS, BNK1_DRIVER_BIAS, 0, 15)
552
+REG32(BNK1_VMODE, 0x35c)
553
+ FIELD(BNK1_VMODE, BNK1_VMODE, 0, 1)
554
+REG32(BNK1_SEL_AUX_IO_RX, 0x360)
555
+ FIELD(BNK1_SEL_AUX_IO_RX, BNK1_SEL_AUX_IO_RX, 0, 26)
556
+REG32(BNK1_EN_TX_HS_MODE, 0x364)
557
+ FIELD(BNK1_EN_TX_HS_MODE, BNK1_EN_TX_HS_MODE, 0, 26)
558
+REG32(SD0_CLK_CTRL, 0x400)
559
+ FIELD(SD0_CLK_CTRL, SDIO0_FBCLK_SEL, 2, 1)
560
+ FIELD(SD0_CLK_CTRL, SDIO0_RX_SRC_SEL, 0, 2)
561
+REG32(SD0_CTRL_REG, 0x404)
562
+ FIELD(SD0_CTRL_REG, SD0_EMMC_SEL, 0, 1)
563
+REG32(SD0_CONFIG_REG1, 0x410)
564
+ FIELD(SD0_CONFIG_REG1, SD0_BASECLK, 7, 8)
565
+ FIELD(SD0_CONFIG_REG1, SD0_TUNIGCOUNT, 1, 6)
566
+ FIELD(SD0_CONFIG_REG1, SD0_ASYNCWKPENA, 0, 1)
567
+REG32(SD0_CONFIG_REG2, 0x414)
568
+ FIELD(SD0_CONFIG_REG2, SD0_SLOTTYPE, 12, 2)
569
+ FIELD(SD0_CONFIG_REG2, SD0_ASYCINTR, 11, 1)
570
+ FIELD(SD0_CONFIG_REG2, SD0_64BIT, 10, 1)
571
+ FIELD(SD0_CONFIG_REG2, SD0_1P8V, 9, 1)
572
+ FIELD(SD0_CONFIG_REG2, SD0_3P0V, 8, 1)
573
+ FIELD(SD0_CONFIG_REG2, SD0_3P3V, 7, 1)
574
+ FIELD(SD0_CONFIG_REG2, SD0_SUSPRES, 6, 1)
575
+ FIELD(SD0_CONFIG_REG2, SD0_SDMA, 5, 1)
576
+ FIELD(SD0_CONFIG_REG2, SD0_HIGHSPEED, 4, 1)
577
+ FIELD(SD0_CONFIG_REG2, SD0_ADMA2, 3, 1)
578
+ FIELD(SD0_CONFIG_REG2, SD0_8BIT, 2, 1)
579
+ FIELD(SD0_CONFIG_REG2, SD0_MAXBLK, 0, 2)
580
+REG32(SD0_CONFIG_REG3, 0x418)
581
+ FIELD(SD0_CONFIG_REG3, SD0_TUNINGSDR50, 10, 1)
582
+ FIELD(SD0_CONFIG_REG3, SD0_RETUNETMR, 6, 4)
583
+ FIELD(SD0_CONFIG_REG3, SD0_DDRIVER, 5, 1)
584
+ FIELD(SD0_CONFIG_REG3, SD0_CDRIVER, 4, 1)
585
+ FIELD(SD0_CONFIG_REG3, SD0_ADRIVER, 3, 1)
586
+ FIELD(SD0_CONFIG_REG3, SD0_DDR50, 2, 1)
587
+ FIELD(SD0_CONFIG_REG3, SD0_SDR104, 1, 1)
588
+ FIELD(SD0_CONFIG_REG3, SD0_SDR50, 0, 1)
589
+REG32(SD0_INITPRESET, 0x41c)
590
+ FIELD(SD0_INITPRESET, SD0_INITPRESET, 0, 13)
591
+REG32(SD0_DSPPRESET, 0x420)
592
+ FIELD(SD0_DSPPRESET, SD0_DSPPRESET, 0, 13)
593
+REG32(SD0_HSPDPRESET, 0x424)
594
+ FIELD(SD0_HSPDPRESET, SD0_HSPDPRESET, 0, 13)
595
+REG32(SD0_SDR12PRESET, 0x428)
596
+ FIELD(SD0_SDR12PRESET, SD0_SDR12PRESET, 0, 13)
597
+REG32(SD0_SDR25PRESET, 0x42c)
598
+ FIELD(SD0_SDR25PRESET, SD0_SDR25PRESET, 0, 13)
599
+REG32(SD0_SDR50PRSET, 0x430)
600
+ FIELD(SD0_SDR50PRSET, SD0_SDR50PRESET, 0, 13)
601
+REG32(SD0_SDR104PRST, 0x434)
602
+ FIELD(SD0_SDR104PRST, SD0_SDR104PRESET, 0, 13)
603
+REG32(SD0_DDR50PRESET, 0x438)
604
+ FIELD(SD0_DDR50PRESET, SD0_DDR50PRESET, 0, 13)
605
+REG32(SD0_MAXCUR1P8, 0x43c)
606
+ FIELD(SD0_MAXCUR1P8, SD0_MAXCUR1P8, 0, 8)
607
+REG32(SD0_MAXCUR3P0, 0x440)
608
+ FIELD(SD0_MAXCUR3P0, SD0_MAXCUR3P0, 0, 8)
609
+REG32(SD0_MAXCUR3P3, 0x444)
610
+ FIELD(SD0_MAXCUR3P3, SD0_MAXCUR3P3, 0, 8)
611
+REG32(SD0_DLL_CTRL, 0x448)
612
+ FIELD(SD0_DLL_CTRL, SD0_CLKSTABLE_CFG, 9, 1)
613
+ FIELD(SD0_DLL_CTRL, SD0_DLL_CFG, 5, 4)
614
+ FIELD(SD0_DLL_CTRL, SD0_DLL_PSDONE, 4, 1)
615
+ FIELD(SD0_DLL_CTRL, SD0_DLL_OVF, 3, 1)
616
+ FIELD(SD0_DLL_CTRL, SD0_DLL_RST, 2, 1)
617
+ FIELD(SD0_DLL_CTRL, SD0_DLL_TESTMODE, 1, 1)
618
+ FIELD(SD0_DLL_CTRL, SD0_DLL_LOCK, 0, 1)
619
+REG32(SD0_CDN_CTRL, 0x44c)
620
+ FIELD(SD0_CDN_CTRL, SD0_CDN_CTRL, 0, 1)
621
+REG32(SD0_DLL_TEST, 0x450)
622
+ FIELD(SD0_DLL_TEST, DLL_DIV, 16, 8)
623
+ FIELD(SD0_DLL_TEST, DLL_TX_SEL, 9, 7)
624
+ FIELD(SD0_DLL_TEST, DLL_RX_SEL, 0, 9)
625
+REG32(SD0_RX_TUNING_SEL, 0x454)
626
+ FIELD(SD0_RX_TUNING_SEL, SD0_RX_SEL, 0, 9)
627
+REG32(SD0_DLL_DIV_MAP0, 0x458)
628
+ FIELD(SD0_DLL_DIV_MAP0, DIV_3, 24, 8)
629
+ FIELD(SD0_DLL_DIV_MAP0, DIV_2, 16, 8)
630
+ FIELD(SD0_DLL_DIV_MAP0, DIV_1, 8, 8)
631
+ FIELD(SD0_DLL_DIV_MAP0, DIV_0, 0, 8)
632
+REG32(SD0_DLL_DIV_MAP1, 0x45c)
633
+ FIELD(SD0_DLL_DIV_MAP1, DIV_7, 24, 8)
634
+ FIELD(SD0_DLL_DIV_MAP1, DIV_6, 16, 8)
635
+ FIELD(SD0_DLL_DIV_MAP1, DIV_5, 8, 8)
636
+ FIELD(SD0_DLL_DIV_MAP1, DIV_4, 0, 8)
637
+REG32(SD0_IOU_COHERENT_CTRL, 0x460)
638
+ FIELD(SD0_IOU_COHERENT_CTRL, SD0_AXI_COH, 0, 4)
639
+REG32(SD0_IOU_INTERCONNECT_ROUTE, 0x464)
640
+ FIELD(SD0_IOU_INTERCONNECT_ROUTE, SD0, 0, 1)
641
+REG32(SD0_IOU_RAM, 0x468)
642
+ FIELD(SD0_IOU_RAM, EMASA0, 6, 1)
643
+ FIELD(SD0_IOU_RAM, EMAB0, 3, 3)
644
+ FIELD(SD0_IOU_RAM, EMAA0, 0, 3)
645
+REG32(SD0_IOU_INTERCONNECT_QOS, 0x46c)
646
+ FIELD(SD0_IOU_INTERCONNECT_QOS, SD0_QOS, 0, 4)
647
+REG32(SD1_CLK_CTRL, 0x480)
648
+ FIELD(SD1_CLK_CTRL, SDIO1_FBCLK_SEL, 1, 1)
649
+ FIELD(SD1_CLK_CTRL, SDIO1_RX_SRC_SEL, 0, 1)
650
+REG32(SD1_CTRL_REG, 0x484)
651
+ FIELD(SD1_CTRL_REG, SD1_EMMC_SEL, 0, 1)
652
+REG32(SD1_CONFIG_REG1, 0x490)
653
+ FIELD(SD1_CONFIG_REG1, SD1_BASECLK, 7, 8)
654
+ FIELD(SD1_CONFIG_REG1, SD1_TUNIGCOUNT, 1, 6)
655
+ FIELD(SD1_CONFIG_REG1, SD1_ASYNCWKPENA, 0, 1)
656
+REG32(SD1_CONFIG_REG2, 0x494)
657
+ FIELD(SD1_CONFIG_REG2, SD1_SLOTTYPE, 12, 2)
658
+ FIELD(SD1_CONFIG_REG2, SD1_ASYCINTR, 11, 1)
659
+ FIELD(SD1_CONFIG_REG2, SD1_64BIT, 10, 1)
660
+ FIELD(SD1_CONFIG_REG2, SD1_1P8V, 9, 1)
661
+ FIELD(SD1_CONFIG_REG2, SD1_3P0V, 8, 1)
662
+ FIELD(SD1_CONFIG_REG2, SD1_3P3V, 7, 1)
663
+ FIELD(SD1_CONFIG_REG2, SD1_SUSPRES, 6, 1)
664
+ FIELD(SD1_CONFIG_REG2, SD1_SDMA, 5, 1)
665
+ FIELD(SD1_CONFIG_REG2, SD1_HIGHSPEED, 4, 1)
666
+ FIELD(SD1_CONFIG_REG2, SD1_ADMA2, 3, 1)
667
+ FIELD(SD1_CONFIG_REG2, SD1_8BIT, 2, 1)
668
+ FIELD(SD1_CONFIG_REG2, SD1_MAXBLK, 0, 2)
669
+REG32(SD1_CONFIG_REG3, 0x498)
670
+ FIELD(SD1_CONFIG_REG3, SD1_TUNINGSDR50, 10, 1)
671
+ FIELD(SD1_CONFIG_REG3, SD1_RETUNETMR, 6, 4)
672
+ FIELD(SD1_CONFIG_REG3, SD1_DDRIVER, 5, 1)
673
+ FIELD(SD1_CONFIG_REG3, SD1_CDRIVER, 4, 1)
674
+ FIELD(SD1_CONFIG_REG3, SD1_ADRIVER, 3, 1)
675
+ FIELD(SD1_CONFIG_REG3, SD1_DDR50, 2, 1)
676
+ FIELD(SD1_CONFIG_REG3, SD1_SDR104, 1, 1)
677
+ FIELD(SD1_CONFIG_REG3, SD1_SDR50, 0, 1)
678
+REG32(SD1_INITPRESET, 0x49c)
679
+ FIELD(SD1_INITPRESET, SD1_INITPRESET, 0, 13)
680
+REG32(SD1_DSPPRESET, 0x4a0)
681
+ FIELD(SD1_DSPPRESET, SD1_DSPPRESET, 0, 13)
682
+REG32(SD1_HSPDPRESET, 0x4a4)
683
+ FIELD(SD1_HSPDPRESET, SD1_HSPDPRESET, 0, 13)
684
+REG32(SD1_SDR12PRESET, 0x4a8)
685
+ FIELD(SD1_SDR12PRESET, SD1_SDR12PRESET, 0, 13)
686
+REG32(SD1_SDR25PRESET, 0x4ac)
687
+ FIELD(SD1_SDR25PRESET, SD1_SDR25PRESET, 0, 13)
688
+REG32(SD1_SDR50PRSET, 0x4b0)
689
+ FIELD(SD1_SDR50PRSET, SD1_SDR50PRESET, 0, 13)
690
+REG32(SD1_SDR104PRST, 0x4b4)
691
+ FIELD(SD1_SDR104PRST, SD1_SDR104PRESET, 0, 13)
692
+REG32(SD1_DDR50PRESET, 0x4b8)
693
+ FIELD(SD1_DDR50PRESET, SD1_DDR50PRESET, 0, 13)
694
+REG32(SD1_MAXCUR1P8, 0x4bc)
695
+ FIELD(SD1_MAXCUR1P8, SD1_MAXCUR1P8, 0, 8)
696
+REG32(SD1_MAXCUR3P0, 0x4c0)
697
+ FIELD(SD1_MAXCUR3P0, SD1_MAXCUR3P0, 0, 8)
698
+REG32(SD1_MAXCUR3P3, 0x4c4)
699
+ FIELD(SD1_MAXCUR3P3, SD1_MAXCUR3P3, 0, 8)
700
+REG32(SD1_DLL_CTRL, 0x4c8)
701
+ FIELD(SD1_DLL_CTRL, SD1_CLKSTABLE_CFG, 9, 1)
702
+ FIELD(SD1_DLL_CTRL, SD1_DLL_CFG, 5, 4)
703
+ FIELD(SD1_DLL_CTRL, SD1_DLL_PSDONE, 4, 1)
704
+ FIELD(SD1_DLL_CTRL, SD1_DLL_OVF, 3, 1)
705
+ FIELD(SD1_DLL_CTRL, SD1_DLL_RST, 2, 1)
706
+ FIELD(SD1_DLL_CTRL, SD1_DLL_TESTMODE, 1, 1)
707
+ FIELD(SD1_DLL_CTRL, SD1_DLL_LOCK, 0, 1)
708
+REG32(SD1_CDN_CTRL, 0x4cc)
709
+ FIELD(SD1_CDN_CTRL, SD1_CDN_CTRL, 0, 1)
710
+REG32(SD1_DLL_TEST, 0x4d0)
711
+ FIELD(SD1_DLL_TEST, DLL_DIV, 16, 8)
712
+ FIELD(SD1_DLL_TEST, DLL_TX_SEL, 9, 7)
713
+ FIELD(SD1_DLL_TEST, DLL_RX_SEL, 0, 9)
714
+REG32(SD1_RX_TUNING_SEL, 0x4d4)
715
+ FIELD(SD1_RX_TUNING_SEL, SD1_RX_SEL, 0, 9)
716
+REG32(SD1_DLL_DIV_MAP0, 0x4d8)
717
+ FIELD(SD1_DLL_DIV_MAP0, DIV_3, 24, 8)
718
+ FIELD(SD1_DLL_DIV_MAP0, DIV_2, 16, 8)
719
+ FIELD(SD1_DLL_DIV_MAP0, DIV_1, 8, 8)
720
+ FIELD(SD1_DLL_DIV_MAP0, DIV_0, 0, 8)
721
+REG32(SD1_DLL_DIV_MAP1, 0x4dc)
722
+ FIELD(SD1_DLL_DIV_MAP1, DIV_7, 24, 8)
723
+ FIELD(SD1_DLL_DIV_MAP1, DIV_6, 16, 8)
724
+ FIELD(SD1_DLL_DIV_MAP1, DIV_5, 8, 8)
725
+ FIELD(SD1_DLL_DIV_MAP1, DIV_4, 0, 8)
726
+REG32(SD1_IOU_COHERENT_CTRL, 0x4e0)
727
+ FIELD(SD1_IOU_COHERENT_CTRL, SD1_AXI_COH, 0, 4)
728
+REG32(SD1_IOU_INTERCONNECT_ROUTE, 0x4e4)
729
+ FIELD(SD1_IOU_INTERCONNECT_ROUTE, SD1, 0, 1)
730
+REG32(SD1_IOU_RAM, 0x4e8)
731
+ FIELD(SD1_IOU_RAM, EMASA0, 6, 1)
732
+ FIELD(SD1_IOU_RAM, EMAB0, 3, 3)
733
+ FIELD(SD1_IOU_RAM, EMAA0, 0, 3)
734
+REG32(SD1_IOU_INTERCONNECT_QOS, 0x4ec)
735
+ FIELD(SD1_IOU_INTERCONNECT_QOS, SD1_QOS, 0, 4)
736
+REG32(OSPI_QSPI_IOU_AXI_MUX_SEL, 0x504)
737
+ FIELD(OSPI_QSPI_IOU_AXI_MUX_SEL, OSPI_MUX_SEL, 1, 1)
738
+ FIELD(OSPI_QSPI_IOU_AXI_MUX_SEL, QSPI_OSPI_MUX_SEL, 0, 1)
739
+REG32(QSPI_IOU_COHERENT_CTRL, 0x508)
740
+ FIELD(QSPI_IOU_COHERENT_CTRL, QSPI_AXI_COH, 0, 4)
741
+REG32(QSPI_IOU_INTERCONNECT_ROUTE, 0x50c)
742
+ FIELD(QSPI_IOU_INTERCONNECT_ROUTE, QSPI, 0, 1)
743
+REG32(QSPI_IOU_RAM, 0x510)
744
+ FIELD(QSPI_IOU_RAM, EMASA1, 13, 1)
745
+ FIELD(QSPI_IOU_RAM, EMAB1, 10, 3)
746
+ FIELD(QSPI_IOU_RAM, EMAA1, 7, 3)
747
+ FIELD(QSPI_IOU_RAM, EMASA0, 6, 1)
748
+ FIELD(QSPI_IOU_RAM, EMAB0, 3, 3)
749
+ FIELD(QSPI_IOU_RAM, EMAA0, 0, 3)
750
+REG32(QSPI_IOU_INTERCONNECT_QOS, 0x514)
751
+ FIELD(QSPI_IOU_INTERCONNECT_QOS, QSPI_QOS, 0, 4)
752
+REG32(OSPI_IOU_COHERENT_CTRL, 0x530)
753
+ FIELD(OSPI_IOU_COHERENT_CTRL, OSPI_AXI_COH, 0, 4)
754
+REG32(OSPI_IOU_INTERCONNECT_ROUTE, 0x534)
755
+ FIELD(OSPI_IOU_INTERCONNECT_ROUTE, OSPI, 0, 1)
756
+REG32(OSPI_IOU_RAM, 0x538)
757
+ FIELD(OSPI_IOU_RAM, EMAS0, 5, 1)
758
+ FIELD(OSPI_IOU_RAM, EMAW0, 3, 2)
759
+ FIELD(OSPI_IOU_RAM, EMA0, 0, 3)
760
+REG32(OSPI_IOU_INTERCONNECT_QOS, 0x53c)
761
+ FIELD(OSPI_IOU_INTERCONNECT_QOS, OSPI_QOS, 0, 4)
762
+REG32(OSPI_REFCLK_DLY_CTRL, 0x540)
763
+ FIELD(OSPI_REFCLK_DLY_CTRL, DLY1, 3, 2)
764
+ FIELD(OSPI_REFCLK_DLY_CTRL, DLY0, 0, 3)
765
+REG32(CUR_PWR_ST, 0x600)
766
+ FIELD(CUR_PWR_ST, U2PMU, 0, 2)
767
+REG32(CONNECT_ST, 0x604)
768
+ FIELD(CONNECT_ST, U2PMU, 0, 1)
769
+REG32(PW_STATE_REQ, 0x608)
770
+ FIELD(PW_STATE_REQ, BIT_1_0, 0, 2)
771
+REG32(HOST_U2_PORT_DISABLE, 0x60c)
772
+ FIELD(HOST_U2_PORT_DISABLE, BIT_0, 0, 1)
773
+REG32(DBG_U2PMU, 0x610)
774
+REG32(DBG_U2PMU_EXT1, 0x614)
775
+REG32(DBG_U2PMU_EXT2, 0x618)
776
+ FIELD(DBG_U2PMU_EXT2, BIT_67_64, 0, 4)
777
+REG32(PME_GEN_U2PMU, 0x61c)
778
+ FIELD(PME_GEN_U2PMU, BIT_0, 0, 1)
779
+REG32(PWR_CONFIG_USB2, 0x620)
780
+ FIELD(PWR_CONFIG_USB2, STRAP, 0, 30)
781
+REG32(PHY_HUB, 0x624)
782
+ FIELD(PHY_HUB, VBUS_CTRL, 1, 1)
783
+ FIELD(PHY_HUB, OVER_CURRENT, 0, 1)
784
+REG32(CTRL, 0x700)
785
+ FIELD(CTRL, SLVERR_ENABLE, 0, 1)
786
+REG32(ISR, 0x800)
787
+ FIELD(ISR, ADDR_DECODE_ERR, 0, 1)
788
+REG32(IMR, 0x804)
789
+ FIELD(IMR, ADDR_DECODE_ERR, 0, 1)
790
+REG32(IER, 0x808)
791
+ FIELD(IER, ADDR_DECODE_ERR, 0, 1)
792
+REG32(IDR, 0x80c)
793
+ FIELD(IDR, ADDR_DECODE_ERR, 0, 1)
794
+REG32(ITR, 0x810)
795
+ FIELD(ITR, ADDR_DECODE_ERR, 0, 1)
796
+REG32(PARITY_ISR, 0x814)
797
+ FIELD(PARITY_ISR, PERR_AXI_SD1_IOU, 12, 1)
798
+ FIELD(PARITY_ISR, PERR_AXI_SD0_IOU, 11, 1)
799
+ FIELD(PARITY_ISR, PERR_AXI_QSPI_IOU, 10, 1)
800
+ FIELD(PARITY_ISR, PERR_AXI_OSPI_IOU, 9, 1)
801
+ FIELD(PARITY_ISR, PERR_IOU_SD1, 8, 1)
802
+ FIELD(PARITY_ISR, PERR_IOU_SD0, 7, 1)
803
+ FIELD(PARITY_ISR, PERR_IOU_QSPI1, 6, 1)
804
+ FIELD(PARITY_ISR, PERR_IOUSLCR_SECURE_APB, 5, 1)
805
+ FIELD(PARITY_ISR, PERR_IOUSLCR_APB, 4, 1)
806
+ FIELD(PARITY_ISR, PERR_QSPI0_APB, 3, 1)
807
+ FIELD(PARITY_ISR, PERR_OSPI_APB, 2, 1)
808
+ FIELD(PARITY_ISR, PERR_I2C_APB, 1, 1)
809
+ FIELD(PARITY_ISR, PERR_GPIO_APB, 0, 1)
810
+REG32(PARITY_IMR, 0x818)
811
+ FIELD(PARITY_IMR, PERR_AXI_SD1_IOU, 12, 1)
812
+ FIELD(PARITY_IMR, PERR_AXI_SD0_IOU, 11, 1)
813
+ FIELD(PARITY_IMR, PERR_AXI_QSPI_IOU, 10, 1)
814
+ FIELD(PARITY_IMR, PERR_AXI_OSPI_IOU, 9, 1)
815
+ FIELD(PARITY_IMR, PERR_IOU_SD1, 8, 1)
816
+ FIELD(PARITY_IMR, PERR_IOU_SD0, 7, 1)
817
+ FIELD(PARITY_IMR, PERR_IOU_QSPI1, 6, 1)
818
+ FIELD(PARITY_IMR, PERR_IOUSLCR_SECURE_APB, 5, 1)
819
+ FIELD(PARITY_IMR, PERR_IOUSLCR_APB, 4, 1)
820
+ FIELD(PARITY_IMR, PERR_QSPI0_APB, 3, 1)
821
+ FIELD(PARITY_IMR, PERR_OSPI_APB, 2, 1)
822
+ FIELD(PARITY_IMR, PERR_I2C_APB, 1, 1)
823
+ FIELD(PARITY_IMR, PERR_GPIO_APB, 0, 1)
824
+REG32(PARITY_IER, 0x81c)
825
+ FIELD(PARITY_IER, PERR_AXI_SD1_IOU, 12, 1)
826
+ FIELD(PARITY_IER, PERR_AXI_SD0_IOU, 11, 1)
827
+ FIELD(PARITY_IER, PERR_AXI_QSPI_IOU, 10, 1)
828
+ FIELD(PARITY_IER, PERR_AXI_OSPI_IOU, 9, 1)
829
+ FIELD(PARITY_IER, PERR_IOU_SD1, 8, 1)
830
+ FIELD(PARITY_IER, PERR_IOU_SD0, 7, 1)
831
+ FIELD(PARITY_IER, PERR_IOU_QSPI1, 6, 1)
832
+ FIELD(PARITY_IER, PERR_IOUSLCR_SECURE_APB, 5, 1)
833
+ FIELD(PARITY_IER, PERR_IOUSLCR_APB, 4, 1)
834
+ FIELD(PARITY_IER, PERR_QSPI0_APB, 3, 1)
835
+ FIELD(PARITY_IER, PERR_OSPI_APB, 2, 1)
836
+ FIELD(PARITY_IER, PERR_I2C_APB, 1, 1)
837
+ FIELD(PARITY_IER, PERR_GPIO_APB, 0, 1)
838
+REG32(PARITY_IDR, 0x820)
839
+ FIELD(PARITY_IDR, PERR_AXI_SD1_IOU, 12, 1)
840
+ FIELD(PARITY_IDR, PERR_AXI_SD0_IOU, 11, 1)
841
+ FIELD(PARITY_IDR, PERR_AXI_QSPI_IOU, 10, 1)
842
+ FIELD(PARITY_IDR, PERR_AXI_OSPI_IOU, 9, 1)
843
+ FIELD(PARITY_IDR, PERR_IOU_SD1, 8, 1)
844
+ FIELD(PARITY_IDR, PERR_IOU_SD0, 7, 1)
845
+ FIELD(PARITY_IDR, PERR_IOU_QSPI1, 6, 1)
846
+ FIELD(PARITY_IDR, PERR_IOUSLCR_SECURE_APB, 5, 1)
847
+ FIELD(PARITY_IDR, PERR_IOUSLCR_APB, 4, 1)
848
+ FIELD(PARITY_IDR, PERR_QSPI0_APB, 3, 1)
849
+ FIELD(PARITY_IDR, PERR_OSPI_APB, 2, 1)
850
+ FIELD(PARITY_IDR, PERR_I2C_APB, 1, 1)
851
+ FIELD(PARITY_IDR, PERR_GPIO_APB, 0, 1)
852
+REG32(PARITY_ITR, 0x824)
853
+ FIELD(PARITY_ITR, PERR_AXI_SD1_IOU, 12, 1)
854
+ FIELD(PARITY_ITR, PERR_AXI_SD0_IOU, 11, 1)
855
+ FIELD(PARITY_ITR, PERR_AXI_QSPI_IOU, 10, 1)
856
+ FIELD(PARITY_ITR, PERR_AXI_OSPI_IOU, 9, 1)
857
+ FIELD(PARITY_ITR, PERR_IOU_SD1, 8, 1)
858
+ FIELD(PARITY_ITR, PERR_IOU_SD0, 7, 1)
859
+ FIELD(PARITY_ITR, PERR_IOU_QSPI1, 6, 1)
860
+ FIELD(PARITY_ITR, PERR_IOUSLCR_SECURE_APB, 5, 1)
861
+ FIELD(PARITY_ITR, PERR_IOUSLCR_APB, 4, 1)
862
+ FIELD(PARITY_ITR, PERR_QSPI0_APB, 3, 1)
863
+ FIELD(PARITY_ITR, PERR_OSPI_APB, 2, 1)
864
+ FIELD(PARITY_ITR, PERR_I2C_APB, 1, 1)
865
+ FIELD(PARITY_ITR, PERR_GPIO_APB, 0, 1)
866
+REG32(WPROT0, 0x828)
867
+ FIELD(WPROT0, ACTIVE, 0, 1)
868
+
869
+static void parity_imr_update_irq(XlnxVersalPmcIouSlcr *s)
870
+{
871
+ bool pending = s->regs[R_PARITY_ISR] & ~s->regs[R_PARITY_IMR];
872
+ qemu_set_irq(s->irq_parity_imr, pending);
873
+}
874
+
875
+static void parity_isr_postw(RegisterInfo *reg, uint64_t val64)
876
+{
877
+ XlnxVersalPmcIouSlcr *s = XILINX_VERSAL_PMC_IOU_SLCR(reg->opaque);
878
+ parity_imr_update_irq(s);
879
+}
880
+
881
+static uint64_t parity_ier_prew(RegisterInfo *reg, uint64_t val64)
882
+{
883
+ XlnxVersalPmcIouSlcr *s = XILINX_VERSAL_PMC_IOU_SLCR(reg->opaque);
884
+ uint32_t val = val64;
885
+
886
+ s->regs[R_PARITY_IMR] &= ~val;
887
+ parity_imr_update_irq(s);
888
+ return 0;
889
+}
890
+
891
+static uint64_t parity_idr_prew(RegisterInfo *reg, uint64_t val64)
892
+{
893
+ XlnxVersalPmcIouSlcr *s = XILINX_VERSAL_PMC_IOU_SLCR(reg->opaque);
894
+ uint32_t val = val64;
895
+
896
+ s->regs[R_PARITY_IMR] |= val;
897
+ parity_imr_update_irq(s);
898
+ return 0;
899
+}
900
+
901
+static uint64_t parity_itr_prew(RegisterInfo *reg, uint64_t val64)
902
+{
903
+ XlnxVersalPmcIouSlcr *s = XILINX_VERSAL_PMC_IOU_SLCR(reg->opaque);
904
+ uint32_t val = val64;
905
+
906
+ s->regs[R_PARITY_ISR] |= val;
907
+ parity_imr_update_irq(s);
908
+ return 0;
909
+}
910
+
911
+static void imr_update_irq(XlnxVersalPmcIouSlcr *s)
912
+{
913
+ bool pending = s->regs[R_ISR] & ~s->regs[R_IMR];
914
+ qemu_set_irq(s->irq_imr, pending);
915
+}
916
+
917
+static void isr_postw(RegisterInfo *reg, uint64_t val64)
918
+{
919
+ XlnxVersalPmcIouSlcr *s = XILINX_VERSAL_PMC_IOU_SLCR(reg->opaque);
920
+ imr_update_irq(s);
921
+}
922
+
923
+static uint64_t ier_prew(RegisterInfo *reg, uint64_t val64)
924
+{
925
+ XlnxVersalPmcIouSlcr *s = XILINX_VERSAL_PMC_IOU_SLCR(reg->opaque);
926
+ uint32_t val = val64;
927
+
928
+ s->regs[R_IMR] &= ~val;
929
+ imr_update_irq(s);
930
+ return 0;
931
+}
932
+
933
+static uint64_t idr_prew(RegisterInfo *reg, uint64_t val64)
934
+{
935
+ XlnxVersalPmcIouSlcr *s = XILINX_VERSAL_PMC_IOU_SLCR(reg->opaque);
936
+ uint32_t val = val64;
937
+
938
+ s->regs[R_IMR] |= val;
939
+ imr_update_irq(s);
940
+ return 0;
941
+}
942
+
943
+static uint64_t itr_prew(RegisterInfo *reg, uint64_t val64)
944
+{
945
+ XlnxVersalPmcIouSlcr *s = XILINX_VERSAL_PMC_IOU_SLCR(reg->opaque);
946
+ uint32_t val = val64;
947
+
948
+ s->regs[R_ISR] |= val;
949
+ imr_update_irq(s);
950
+ return 0;
951
+}
952
+
953
+static uint64_t sd0_ctrl_reg_prew(RegisterInfo *reg, uint64_t val64)
954
+{
955
+ XlnxVersalPmcIouSlcr *s = XILINX_VERSAL_PMC_IOU_SLCR(reg->opaque);
956
+ uint32_t prev = ARRAY_FIELD_EX32(s->regs, SD0_CTRL_REG, SD0_EMMC_SEL);
957
+
958
+ if (prev != (val64 & R_SD0_CTRL_REG_SD0_EMMC_SEL_MASK)) {
959
+ qemu_set_irq(s->sd_emmc_sel[0], !!val64);
960
+ }
961
+
962
+ return val64;
963
+}
964
+
965
+static uint64_t sd1_ctrl_reg_prew(RegisterInfo *reg, uint64_t val64)
966
+{
967
+ XlnxVersalPmcIouSlcr *s = XILINX_VERSAL_PMC_IOU_SLCR(reg->opaque);
968
+ uint32_t prev = ARRAY_FIELD_EX32(s->regs, SD1_CTRL_REG, SD1_EMMC_SEL);
969
+
970
+ if (prev != (val64 & R_SD1_CTRL_REG_SD1_EMMC_SEL_MASK)) {
971
+ qemu_set_irq(s->sd_emmc_sel[1], !!val64);
972
+ }
973
+
974
+ return val64;
975
+}
976
+
977
+static uint64_t ospi_qspi_iou_axi_mux_sel_prew(RegisterInfo *reg,
978
+ uint64_t val64)
979
+{
980
+ XlnxVersalPmcIouSlcr *s = XILINX_VERSAL_PMC_IOU_SLCR(reg->opaque);
981
+ uint32_t val32 = (uint32_t) val64;
982
+ uint8_t ospi_mux_sel = FIELD_EX32(val32, OSPI_QSPI_IOU_AXI_MUX_SEL,
983
+ OSPI_MUX_SEL);
984
+ uint8_t qspi_ospi_mux_sel = FIELD_EX32(val32, OSPI_QSPI_IOU_AXI_MUX_SEL,
985
+ QSPI_OSPI_MUX_SEL);
986
+
987
+ if (ospi_mux_sel !=
988
+ ARRAY_FIELD_EX32(s->regs, OSPI_QSPI_IOU_AXI_MUX_SEL, OSPI_MUX_SEL)) {
989
+ qemu_set_irq(s->ospi_mux_sel, !!ospi_mux_sel);
990
+ }
991
+
992
+ if (qspi_ospi_mux_sel !=
993
+ ARRAY_FIELD_EX32(s->regs, OSPI_QSPI_IOU_AXI_MUX_SEL,
994
+ QSPI_OSPI_MUX_SEL)) {
995
+ qemu_set_irq(s->qspi_ospi_mux_sel, !!qspi_ospi_mux_sel);
996
+ }
997
+
998
+ return val64;
999
+}
1000
+
1001
+static RegisterAccessInfo pmc_iou_slcr_regs_info[] = {
1002
+ { .name = "MIO_PIN_0", .addr = A_MIO_PIN_0,
1003
+ .rsvd = 0xfffffc01,
1004
+ },{ .name = "MIO_PIN_1", .addr = A_MIO_PIN_1,
1005
+ .rsvd = 0xfffffc01,
1006
+ },{ .name = "MIO_PIN_2", .addr = A_MIO_PIN_2,
1007
+ .rsvd = 0xfffffc01,
1008
+ },{ .name = "MIO_PIN_3", .addr = A_MIO_PIN_3,
1009
+ .rsvd = 0xfffffc01,
1010
+ },{ .name = "MIO_PIN_4", .addr = A_MIO_PIN_4,
1011
+ .rsvd = 0xfffffc01,
1012
+ },{ .name = "MIO_PIN_5", .addr = A_MIO_PIN_5,
1013
+ .rsvd = 0xfffffc01,
1014
+ },{ .name = "MIO_PIN_6", .addr = A_MIO_PIN_6,
1015
+ .rsvd = 0xfffffc01,
1016
+ },{ .name = "MIO_PIN_7", .addr = A_MIO_PIN_7,
1017
+ .rsvd = 0xfffffc01,
1018
+ },{ .name = "MIO_PIN_8", .addr = A_MIO_PIN_8,
1019
+ .rsvd = 0xfffffc01,
1020
+ },{ .name = "MIO_PIN_9", .addr = A_MIO_PIN_9,
1021
+ .rsvd = 0xfffffc01,
1022
+ },{ .name = "MIO_PIN_10", .addr = A_MIO_PIN_10,
1023
+ .rsvd = 0xfffffc01,
1024
+ },{ .name = "MIO_PIN_11", .addr = A_MIO_PIN_11,
1025
+ .rsvd = 0xfffffc01,
1026
+ },{ .name = "MIO_PIN_12", .addr = A_MIO_PIN_12,
1027
+ .rsvd = 0xfffffc01,
1028
+ },{ .name = "MIO_PIN_13", .addr = A_MIO_PIN_13,
1029
+ .rsvd = 0xfffffc01,
1030
+ },{ .name = "MIO_PIN_14", .addr = A_MIO_PIN_14,
1031
+ .rsvd = 0xfffffc01,
1032
+ },{ .name = "MIO_PIN_15", .addr = A_MIO_PIN_15,
1033
+ .rsvd = 0xfffffc01,
1034
+ },{ .name = "MIO_PIN_16", .addr = A_MIO_PIN_16,
1035
+ .rsvd = 0xfffffc01,
1036
+ },{ .name = "MIO_PIN_17", .addr = A_MIO_PIN_17,
1037
+ .rsvd = 0xfffffc01,
1038
+ },{ .name = "MIO_PIN_18", .addr = A_MIO_PIN_18,
1039
+ .rsvd = 0xfffffc01,
1040
+ },{ .name = "MIO_PIN_19", .addr = A_MIO_PIN_19,
1041
+ .rsvd = 0xfffffc01,
1042
+ },{ .name = "MIO_PIN_20", .addr = A_MIO_PIN_20,
1043
+ .rsvd = 0xfffffc01,
1044
+ },{ .name = "MIO_PIN_21", .addr = A_MIO_PIN_21,
1045
+ .rsvd = 0xfffffc01,
1046
+ },{ .name = "MIO_PIN_22", .addr = A_MIO_PIN_22,
1047
+ .rsvd = 0xfffffc01,
1048
+ },{ .name = "MIO_PIN_23", .addr = A_MIO_PIN_23,
1049
+ .rsvd = 0xfffffc01,
1050
+ },{ .name = "MIO_PIN_24", .addr = A_MIO_PIN_24,
1051
+ .rsvd = 0xfffffc01,
1052
+ },{ .name = "MIO_PIN_25", .addr = A_MIO_PIN_25,
1053
+ .rsvd = 0xfffffc01,
1054
+ },{ .name = "MIO_PIN_26", .addr = A_MIO_PIN_26,
1055
+ .rsvd = 0xfffffc01,
1056
+ },{ .name = "MIO_PIN_27", .addr = A_MIO_PIN_27,
1057
+ .rsvd = 0xfffffc01,
1058
+ },{ .name = "MIO_PIN_28", .addr = A_MIO_PIN_28,
1059
+ .rsvd = 0xfffffc01,
1060
+ },{ .name = "MIO_PIN_29", .addr = A_MIO_PIN_29,
1061
+ .rsvd = 0xfffffc01,
1062
+ },{ .name = "MIO_PIN_30", .addr = A_MIO_PIN_30,
1063
+ .rsvd = 0xfffffc01,
1064
+ },{ .name = "MIO_PIN_31", .addr = A_MIO_PIN_31,
1065
+ .rsvd = 0xfffffc01,
1066
+ },{ .name = "MIO_PIN_32", .addr = A_MIO_PIN_32,
1067
+ .rsvd = 0xfffffc01,
1068
+ },{ .name = "MIO_PIN_33", .addr = A_MIO_PIN_33,
1069
+ .rsvd = 0xfffffc01,
1070
+ },{ .name = "MIO_PIN_34", .addr = A_MIO_PIN_34,
1071
+ .rsvd = 0xfffffc01,
1072
+ },{ .name = "MIO_PIN_35", .addr = A_MIO_PIN_35,
1073
+ .rsvd = 0xfffffc01,
1074
+ },{ .name = "MIO_PIN_36", .addr = A_MIO_PIN_36,
1075
+ .rsvd = 0xfffffc01,
1076
+ },{ .name = "MIO_PIN_37", .addr = A_MIO_PIN_37,
1077
+ .rsvd = 0xfffffc01,
1078
+ },{ .name = "MIO_PIN_38", .addr = A_MIO_PIN_38,
1079
+ .rsvd = 0xfffffc01,
1080
+ },{ .name = "MIO_PIN_39", .addr = A_MIO_PIN_39,
1081
+ .rsvd = 0xfffffc01,
1082
+ },{ .name = "MIO_PIN_40", .addr = A_MIO_PIN_40,
1083
+ .rsvd = 0xfffffc01,
1084
+ },{ .name = "MIO_PIN_41", .addr = A_MIO_PIN_41,
1085
+ .rsvd = 0xfffffc01,
1086
+ },{ .name = "MIO_PIN_42", .addr = A_MIO_PIN_42,
1087
+ .rsvd = 0xfffffc01,
1088
+ },{ .name = "MIO_PIN_43", .addr = A_MIO_PIN_43,
1089
+ .rsvd = 0xfffffc01,
1090
+ },{ .name = "MIO_PIN_44", .addr = A_MIO_PIN_44,
1091
+ .rsvd = 0xfffffc01,
1092
+ },{ .name = "MIO_PIN_45", .addr = A_MIO_PIN_45,
1093
+ .rsvd = 0xfffffc01,
1094
+ },{ .name = "MIO_PIN_46", .addr = A_MIO_PIN_46,
1095
+ .rsvd = 0xfffffc01,
1096
+ },{ .name = "MIO_PIN_47", .addr = A_MIO_PIN_47,
1097
+ .rsvd = 0xfffffc01,
1098
+ },{ .name = "MIO_PIN_48", .addr = A_MIO_PIN_48,
1099
+ .rsvd = 0xfffffc01,
1100
+ },{ .name = "MIO_PIN_49", .addr = A_MIO_PIN_49,
1101
+ .rsvd = 0xfffffc01,
1102
+ },{ .name = "MIO_PIN_50", .addr = A_MIO_PIN_50,
1103
+ .rsvd = 0xfffffc01,
1104
+ },{ .name = "MIO_PIN_51", .addr = A_MIO_PIN_51,
1105
+ .rsvd = 0xfffffc01,
1106
+ },{ .name = "BNK0_EN_RX", .addr = A_BNK0_EN_RX,
1107
+ .reset = 0x3ffffff,
1108
+ .rsvd = 0xfc000000,
1109
+ },{ .name = "BNK0_SEL_RX0", .addr = A_BNK0_SEL_RX0,
1110
+ .reset = 0xffffffff,
1111
+ },{ .name = "BNK0_SEL_RX1", .addr = A_BNK0_SEL_RX1,
1112
+ .reset = 0xfffff,
1113
+ .rsvd = 0xfff00000,
1114
+ },{ .name = "BNK0_EN_RX_SCHMITT_HYST", .addr = A_BNK0_EN_RX_SCHMITT_HYST,
1115
+ .rsvd = 0xfc000000,
1116
+ },{ .name = "BNK0_EN_WK_PD", .addr = A_BNK0_EN_WK_PD,
1117
+ .rsvd = 0xfc000000,
1118
+ },{ .name = "BNK0_EN_WK_PU", .addr = A_BNK0_EN_WK_PU,
1119
+ .reset = 0x3ffffff,
1120
+ .rsvd = 0xfc000000,
1121
+ },{ .name = "BNK0_SEL_DRV0", .addr = A_BNK0_SEL_DRV0,
1122
+ .reset = 0xffffffff,
1123
+ },{ .name = "BNK0_SEL_DRV1", .addr = A_BNK0_SEL_DRV1,
1124
+ .reset = 0xfffff,
1125
+ .rsvd = 0xfff00000,
1126
+ },{ .name = "BNK0_SEL_SLEW", .addr = A_BNK0_SEL_SLEW,
1127
+ .rsvd = 0xfc000000,
1128
+ },{ .name = "BNK0_EN_DFT_OPT_INV", .addr = A_BNK0_EN_DFT_OPT_INV,
1129
+ .rsvd = 0xfc000000,
1130
+ },{ .name = "BNK0_EN_PAD2PAD_LOOPBACK",
1131
+ .addr = A_BNK0_EN_PAD2PAD_LOOPBACK,
1132
+ .rsvd = 0xffffe000,
1133
+ },{ .name = "BNK0_RX_SPARE0", .addr = A_BNK0_RX_SPARE0,
1134
+ },{ .name = "BNK0_RX_SPARE1", .addr = A_BNK0_RX_SPARE1,
1135
+ .rsvd = 0xfff00000,
1136
+ },{ .name = "BNK0_TX_SPARE0", .addr = A_BNK0_TX_SPARE0,
1137
+ },{ .name = "BNK0_TX_SPARE1", .addr = A_BNK0_TX_SPARE1,
1138
+ .rsvd = 0xfff00000,
1139
+ },{ .name = "BNK0_SEL_EN1P8", .addr = A_BNK0_SEL_EN1P8,
1140
+ .rsvd = 0xfffffffe,
1141
+ },{ .name = "BNK0_EN_B_POR_DETECT", .addr = A_BNK0_EN_B_POR_DETECT,
1142
+ .rsvd = 0xfffffffe,
1143
+ },{ .name = "BNK0_LPF_BYP_POR_DETECT", .addr = A_BNK0_LPF_BYP_POR_DETECT,
1144
+ .reset = 0x1,
1145
+ .rsvd = 0xfffffffe,
1146
+ },{ .name = "BNK0_EN_LATCH", .addr = A_BNK0_EN_LATCH,
1147
+ .rsvd = 0xfffffffe,
1148
+ },{ .name = "BNK0_VBG_LPF_BYP_B", .addr = A_BNK0_VBG_LPF_BYP_B,
1149
+ .reset = 0x1,
1150
+ .rsvd = 0xfffffffe,
1151
+ },{ .name = "BNK0_EN_AMP_B", .addr = A_BNK0_EN_AMP_B,
1152
+ .rsvd = 0xfffffffc,
1153
+ },{ .name = "BNK0_SPARE_BIAS", .addr = A_BNK0_SPARE_BIAS,
1154
+ .rsvd = 0xfffffff0,
1155
+ },{ .name = "BNK0_DRIVER_BIAS", .addr = A_BNK0_DRIVER_BIAS,
1156
+ .rsvd = 0xffff8000,
1157
+ },{ .name = "BNK0_VMODE", .addr = A_BNK0_VMODE,
1158
+ .rsvd = 0xfffffffe,
1159
+ .ro = 0x1,
1160
+ },{ .name = "BNK0_SEL_AUX_IO_RX", .addr = A_BNK0_SEL_AUX_IO_RX,
1161
+ .rsvd = 0xfc000000,
1162
+ },{ .name = "BNK0_EN_TX_HS_MODE", .addr = A_BNK0_EN_TX_HS_MODE,
1163
+ .rsvd = 0xfc000000,
1164
+ },{ .name = "MIO_MST_TRI0", .addr = A_MIO_MST_TRI0,
1165
+ .reset = 0x3ffffff,
1166
+ .rsvd = 0xfc000000,
1167
+ },{ .name = "MIO_MST_TRI1", .addr = A_MIO_MST_TRI1,
1168
+ .reset = 0x3ffffff,
1169
+ .rsvd = 0xfc000000,
1170
+ },{ .name = "BNK1_EN_RX", .addr = A_BNK1_EN_RX,
1171
+ .reset = 0x3ffffff,
1172
+ .rsvd = 0xfc000000,
1173
+ },{ .name = "BNK1_SEL_RX0", .addr = A_BNK1_SEL_RX0,
1174
+ .reset = 0xffffffff,
1175
+ },{ .name = "BNK1_SEL_RX1", .addr = A_BNK1_SEL_RX1,
1176
+ .reset = 0xfffff,
1177
+ .rsvd = 0xfff00000,
1178
+ },{ .name = "BNK1_EN_RX_SCHMITT_HYST", .addr = A_BNK1_EN_RX_SCHMITT_HYST,
1179
+ .rsvd = 0xfc000000,
1180
+ },{ .name = "BNK1_EN_WK_PD", .addr = A_BNK1_EN_WK_PD,
1181
+ .rsvd = 0xfc000000,
1182
+ },{ .name = "BNK1_EN_WK_PU", .addr = A_BNK1_EN_WK_PU,
1183
+ .reset = 0x3ffffff,
1184
+ .rsvd = 0xfc000000,
1185
+ },{ .name = "BNK1_SEL_DRV0", .addr = A_BNK1_SEL_DRV0,
1186
+ .reset = 0xffffffff,
1187
+ },{ .name = "BNK1_SEL_DRV1", .addr = A_BNK1_SEL_DRV1,
1188
+ .reset = 0xfffff,
1189
+ .rsvd = 0xfff00000,
1190
+ },{ .name = "BNK1_SEL_SLEW", .addr = A_BNK1_SEL_SLEW,
1191
+ .rsvd = 0xfc000000,
1192
+ },{ .name = "BNK1_EN_DFT_OPT_INV", .addr = A_BNK1_EN_DFT_OPT_INV,
1193
+ .rsvd = 0xfc000000,
1194
+ },{ .name = "BNK1_EN_PAD2PAD_LOOPBACK",
1195
+ .addr = A_BNK1_EN_PAD2PAD_LOOPBACK,
1196
+ .rsvd = 0xffffe000,
1197
+ },{ .name = "BNK1_RX_SPARE0", .addr = A_BNK1_RX_SPARE0,
1198
+ },{ .name = "BNK1_RX_SPARE1", .addr = A_BNK1_RX_SPARE1,
1199
+ .rsvd = 0xfff00000,
1200
+ },{ .name = "BNK1_TX_SPARE0", .addr = A_BNK1_TX_SPARE0,
1201
+ },{ .name = "BNK1_TX_SPARE1", .addr = A_BNK1_TX_SPARE1,
1202
+ .rsvd = 0xfff00000,
1203
+ },{ .name = "BNK1_SEL_EN1P8", .addr = A_BNK1_SEL_EN1P8,
1204
+ .rsvd = 0xfffffffe,
1205
+ },{ .name = "BNK1_EN_B_POR_DETECT", .addr = A_BNK1_EN_B_POR_DETECT,
1206
+ .rsvd = 0xfffffffe,
1207
+ },{ .name = "BNK1_LPF_BYP_POR_DETECT", .addr = A_BNK1_LPF_BYP_POR_DETECT,
1208
+ .reset = 0x1,
1209
+ .rsvd = 0xfffffffe,
1210
+ },{ .name = "BNK1_EN_LATCH", .addr = A_BNK1_EN_LATCH,
1211
+ .rsvd = 0xfffffffe,
1212
+ },{ .name = "BNK1_VBG_LPF_BYP_B", .addr = A_BNK1_VBG_LPF_BYP_B,
1213
+ .reset = 0x1,
1214
+ .rsvd = 0xfffffffe,
1215
+ },{ .name = "BNK1_EN_AMP_B", .addr = A_BNK1_EN_AMP_B,
1216
+ .rsvd = 0xfffffffc,
1217
+ },{ .name = "BNK1_SPARE_BIAS", .addr = A_BNK1_SPARE_BIAS,
1218
+ .rsvd = 0xfffffff0,
1219
+ },{ .name = "BNK1_DRIVER_BIAS", .addr = A_BNK1_DRIVER_BIAS,
1220
+ .rsvd = 0xffff8000,
1221
+ },{ .name = "BNK1_VMODE", .addr = A_BNK1_VMODE,
1222
+ .rsvd = 0xfffffffe,
1223
+ .ro = 0x1,
1224
+ },{ .name = "BNK1_SEL_AUX_IO_RX", .addr = A_BNK1_SEL_AUX_IO_RX,
1225
+ .rsvd = 0xfc000000,
1226
+ },{ .name = "BNK1_EN_TX_HS_MODE", .addr = A_BNK1_EN_TX_HS_MODE,
1227
+ .rsvd = 0xfc000000,
1228
+ },{ .name = "SD0_CLK_CTRL", .addr = A_SD0_CLK_CTRL,
1229
+ .rsvd = 0xfffffff8,
1230
+ },{ .name = "SD0_CTRL_REG", .addr = A_SD0_CTRL_REG,
1231
+ .rsvd = 0xfffffffe,
1232
+ .pre_write = sd0_ctrl_reg_prew,
1233
+ },{ .name = "SD0_CONFIG_REG1", .addr = A_SD0_CONFIG_REG1,
1234
+ .reset = 0x3250,
1235
+ .rsvd = 0xffff8000,
1236
+ },{ .name = "SD0_CONFIG_REG2", .addr = A_SD0_CONFIG_REG2,
1237
+ .reset = 0xffc,
1238
+ .rsvd = 0xffffc000,
1239
+ },{ .name = "SD0_CONFIG_REG3", .addr = A_SD0_CONFIG_REG3,
1240
+ .reset = 0x407,
1241
+ .rsvd = 0xfffff800,
1242
+ },{ .name = "SD0_INITPRESET", .addr = A_SD0_INITPRESET,
1243
+ .reset = 0x100,
1244
+ .rsvd = 0xffffe000,
1245
+ },{ .name = "SD0_DSPPRESET", .addr = A_SD0_DSPPRESET,
1246
+ .reset = 0x4,
1247
+ .rsvd = 0xffffe000,
1248
+ },{ .name = "SD0_HSPDPRESET", .addr = A_SD0_HSPDPRESET,
1249
+ .reset = 0x2,
1250
+ .rsvd = 0xffffe000,
1251
+ },{ .name = "SD0_SDR12PRESET", .addr = A_SD0_SDR12PRESET,
1252
+ .reset = 0x4,
1253
+ .rsvd = 0xffffe000,
1254
+ },{ .name = "SD0_SDR25PRESET", .addr = A_SD0_SDR25PRESET,
1255
+ .reset = 0x2,
1256
+ .rsvd = 0xffffe000,
1257
+ },{ .name = "SD0_SDR50PRSET", .addr = A_SD0_SDR50PRSET,
1258
+ .reset = 0x1,
1259
+ .rsvd = 0xffffe000,
1260
+ },{ .name = "SD0_SDR104PRST", .addr = A_SD0_SDR104PRST,
1261
+ .rsvd = 0xffffe000,
1262
+ },{ .name = "SD0_DDR50PRESET", .addr = A_SD0_DDR50PRESET,
1263
+ .reset = 0x2,
1264
+ .rsvd = 0xffffe000,
1265
+ },{ .name = "SD0_MAXCUR1P8", .addr = A_SD0_MAXCUR1P8,
1266
+ .rsvd = 0xffffff00,
1267
+ },{ .name = "SD0_MAXCUR3P0", .addr = A_SD0_MAXCUR3P0,
1268
+ .rsvd = 0xffffff00,
1269
+ },{ .name = "SD0_MAXCUR3P3", .addr = A_SD0_MAXCUR3P3,
1270
+ .rsvd = 0xffffff00,
1271
+ },{ .name = "SD0_DLL_CTRL", .addr = A_SD0_DLL_CTRL,
1272
+ .reset = 0x1,
1273
+ .rsvd = 0xfffffc00,
1274
+ .ro = 0x19,
1275
+ },{ .name = "SD0_CDN_CTRL", .addr = A_SD0_CDN_CTRL,
1276
+ .rsvd = 0xfffffffe,
1277
+ },{ .name = "SD0_DLL_TEST", .addr = A_SD0_DLL_TEST,
1278
+ .rsvd = 0xff000000,
1279
+ },{ .name = "SD0_RX_TUNING_SEL", .addr = A_SD0_RX_TUNING_SEL,
1280
+ .rsvd = 0xfffffe00,
1281
+ .ro = 0x1ff,
1282
+ },{ .name = "SD0_DLL_DIV_MAP0", .addr = A_SD0_DLL_DIV_MAP0,
1283
+ .reset = 0x50505050,
1284
+ },{ .name = "SD0_DLL_DIV_MAP1", .addr = A_SD0_DLL_DIV_MAP1,
1285
+ .reset = 0x50505050,
1286
+ },{ .name = "SD0_IOU_COHERENT_CTRL", .addr = A_SD0_IOU_COHERENT_CTRL,
1287
+ .rsvd = 0xfffffff0,
1288
+ },{ .name = "SD0_IOU_INTERCONNECT_ROUTE",
1289
+ .addr = A_SD0_IOU_INTERCONNECT_ROUTE,
1290
+ .rsvd = 0xfffffffe,
1291
+ },{ .name = "SD0_IOU_RAM", .addr = A_SD0_IOU_RAM,
1292
+ .reset = 0x24,
1293
+ .rsvd = 0xffffff80,
1294
+ },{ .name = "SD0_IOU_INTERCONNECT_QOS",
1295
+ .addr = A_SD0_IOU_INTERCONNECT_QOS,
1296
+ .rsvd = 0xfffffff0,
1297
+ },{ .name = "SD1_CLK_CTRL", .addr = A_SD1_CLK_CTRL,
1298
+ .rsvd = 0xfffffffc,
1299
+ },{ .name = "SD1_CTRL_REG", .addr = A_SD1_CTRL_REG,
1300
+ .rsvd = 0xfffffffe,
1301
+ .pre_write = sd1_ctrl_reg_prew,
1302
+ },{ .name = "SD1_CONFIG_REG1", .addr = A_SD1_CONFIG_REG1,
1303
+ .reset = 0x3250,
1304
+ .rsvd = 0xffff8000,
1305
+ },{ .name = "SD1_CONFIG_REG2", .addr = A_SD1_CONFIG_REG2,
1306
+ .reset = 0xffc,
1307
+ .rsvd = 0xffffc000,
1308
+ },{ .name = "SD1_CONFIG_REG3", .addr = A_SD1_CONFIG_REG3,
1309
+ .reset = 0x407,
1310
+ .rsvd = 0xfffff800,
1311
+ },{ .name = "SD1_INITPRESET", .addr = A_SD1_INITPRESET,
1312
+ .reset = 0x100,
1313
+ .rsvd = 0xffffe000,
1314
+ },{ .name = "SD1_DSPPRESET", .addr = A_SD1_DSPPRESET,
1315
+ .reset = 0x4,
1316
+ .rsvd = 0xffffe000,
1317
+ },{ .name = "SD1_HSPDPRESET", .addr = A_SD1_HSPDPRESET,
1318
+ .reset = 0x2,
1319
+ .rsvd = 0xffffe000,
1320
+ },{ .name = "SD1_SDR12PRESET", .addr = A_SD1_SDR12PRESET,
1321
+ .reset = 0x4,
1322
+ .rsvd = 0xffffe000,
1323
+ },{ .name = "SD1_SDR25PRESET", .addr = A_SD1_SDR25PRESET,
1324
+ .reset = 0x2,
1325
+ .rsvd = 0xffffe000,
1326
+ },{ .name = "SD1_SDR50PRSET", .addr = A_SD1_SDR50PRSET,
1327
+ .reset = 0x1,
1328
+ .rsvd = 0xffffe000,
1329
+ },{ .name = "SD1_SDR104PRST", .addr = A_SD1_SDR104PRST,
1330
+ .rsvd = 0xffffe000,
1331
+ },{ .name = "SD1_DDR50PRESET", .addr = A_SD1_DDR50PRESET,
1332
+ .reset = 0x2,
1333
+ .rsvd = 0xffffe000,
1334
+ },{ .name = "SD1_MAXCUR1P8", .addr = A_SD1_MAXCUR1P8,
1335
+ .rsvd = 0xffffff00,
1336
+ },{ .name = "SD1_MAXCUR3P0", .addr = A_SD1_MAXCUR3P0,
1337
+ .rsvd = 0xffffff00,
1338
+ },{ .name = "SD1_MAXCUR3P3", .addr = A_SD1_MAXCUR3P3,
1339
+ .rsvd = 0xffffff00,
1340
+ },{ .name = "SD1_DLL_CTRL", .addr = A_SD1_DLL_CTRL,
1341
+ .reset = 0x1,
1342
+ .rsvd = 0xfffffc00,
1343
+ .ro = 0x19,
1344
+ },{ .name = "SD1_CDN_CTRL", .addr = A_SD1_CDN_CTRL,
1345
+ .rsvd = 0xfffffffe,
1346
+ },{ .name = "SD1_DLL_TEST", .addr = A_SD1_DLL_TEST,
1347
+ .rsvd = 0xff000000,
1348
+ },{ .name = "SD1_RX_TUNING_SEL", .addr = A_SD1_RX_TUNING_SEL,
1349
+ .rsvd = 0xfffffe00,
1350
+ .ro = 0x1ff,
1351
+ },{ .name = "SD1_DLL_DIV_MAP0", .addr = A_SD1_DLL_DIV_MAP0,
1352
+ .reset = 0x50505050,
1353
+ },{ .name = "SD1_DLL_DIV_MAP1", .addr = A_SD1_DLL_DIV_MAP1,
1354
+ .reset = 0x50505050,
1355
+ },{ .name = "SD1_IOU_COHERENT_CTRL", .addr = A_SD1_IOU_COHERENT_CTRL,
1356
+ .rsvd = 0xfffffff0,
1357
+ },{ .name = "SD1_IOU_INTERCONNECT_ROUTE",
1358
+ .addr = A_SD1_IOU_INTERCONNECT_ROUTE,
1359
+ .rsvd = 0xfffffffe,
1360
+ },{ .name = "SD1_IOU_RAM", .addr = A_SD1_IOU_RAM,
1361
+ .reset = 0x24,
1362
+ .rsvd = 0xffffff80,
1363
+ },{ .name = "SD1_IOU_INTERCONNECT_QOS",
1364
+ .addr = A_SD1_IOU_INTERCONNECT_QOS,
1365
+ .rsvd = 0xfffffff0,
1366
+ },{ .name = "OSPI_QSPI_IOU_AXI_MUX_SEL",
1367
+ .addr = A_OSPI_QSPI_IOU_AXI_MUX_SEL,
1368
+ .reset = 0x1,
1369
+ .rsvd = 0xfffffffc,
1370
+ .pre_write = ospi_qspi_iou_axi_mux_sel_prew,
1371
+ },{ .name = "QSPI_IOU_COHERENT_CTRL", .addr = A_QSPI_IOU_COHERENT_CTRL,
1372
+ .rsvd = 0xfffffff0,
1373
+ },{ .name = "QSPI_IOU_INTERCONNECT_ROUTE",
1374
+ .addr = A_QSPI_IOU_INTERCONNECT_ROUTE,
1375
+ .rsvd = 0xfffffffe,
1376
+ },{ .name = "QSPI_IOU_RAM", .addr = A_QSPI_IOU_RAM,
1377
+ .reset = 0x1224,
1378
+ .rsvd = 0xffffc000,
1379
+ },{ .name = "QSPI_IOU_INTERCONNECT_QOS",
1380
+ .addr = A_QSPI_IOU_INTERCONNECT_QOS,
1381
+ .rsvd = 0xfffffff0,
1382
+ },{ .name = "OSPI_IOU_COHERENT_CTRL", .addr = A_OSPI_IOU_COHERENT_CTRL,
1383
+ .rsvd = 0xfffffff0,
1384
+ },{ .name = "OSPI_IOU_INTERCONNECT_ROUTE",
1385
+ .addr = A_OSPI_IOU_INTERCONNECT_ROUTE,
1386
+ .rsvd = 0xfffffffe,
1387
+ },{ .name = "OSPI_IOU_RAM", .addr = A_OSPI_IOU_RAM,
1388
+ .reset = 0xa,
1389
+ .rsvd = 0xffffffc0,
1390
+ },{ .name = "OSPI_IOU_INTERCONNECT_QOS",
1391
+ .addr = A_OSPI_IOU_INTERCONNECT_QOS,
1392
+ .rsvd = 0xfffffff0,
1393
+ },{ .name = "OSPI_REFCLK_DLY_CTRL", .addr = A_OSPI_REFCLK_DLY_CTRL,
1394
+ .reset = 0x13,
1395
+ .rsvd = 0xffffffe0,
1396
+ },{ .name = "CUR_PWR_ST", .addr = A_CUR_PWR_ST,
1397
+ .rsvd = 0xfffffffc,
1398
+ .ro = 0x3,
1399
+ },{ .name = "CONNECT_ST", .addr = A_CONNECT_ST,
1400
+ .rsvd = 0xfffffffe,
1401
+ .ro = 0x1,
1402
+ },{ .name = "PW_STATE_REQ", .addr = A_PW_STATE_REQ,
1403
+ .rsvd = 0xfffffffc,
1404
+ },{ .name = "HOST_U2_PORT_DISABLE", .addr = A_HOST_U2_PORT_DISABLE,
1405
+ .rsvd = 0xfffffffe,
1406
+ },{ .name = "DBG_U2PMU", .addr = A_DBG_U2PMU,
1407
+ .ro = 0xffffffff,
1408
+ },{ .name = "DBG_U2PMU_EXT1", .addr = A_DBG_U2PMU_EXT1,
1409
+ .ro = 0xffffffff,
1410
+ },{ .name = "DBG_U2PMU_EXT2", .addr = A_DBG_U2PMU_EXT2,
1411
+ .rsvd = 0xfffffff0,
1412
+ .ro = 0xf,
1413
+ },{ .name = "PME_GEN_U2PMU", .addr = A_PME_GEN_U2PMU,
1414
+ .rsvd = 0xfffffffe,
1415
+ .ro = 0x1,
1416
+ },{ .name = "PWR_CONFIG_USB2", .addr = A_PWR_CONFIG_USB2,
1417
+ .rsvd = 0xc0000000,
1418
+ },{ .name = "PHY_HUB", .addr = A_PHY_HUB,
1419
+ .rsvd = 0xfffffffc,
1420
+ .ro = 0x2,
1421
+ },{ .name = "CTRL", .addr = A_CTRL,
1422
+ },{ .name = "ISR", .addr = A_ISR,
1423
+ .w1c = 0x1,
1424
+ .post_write = isr_postw,
1425
+ },{ .name = "IMR", .addr = A_IMR,
1426
+ .reset = 0x1,
1427
+ .ro = 0x1,
1428
+ },{ .name = "IER", .addr = A_IER,
1429
+ .pre_write = ier_prew,
1430
+ },{ .name = "IDR", .addr = A_IDR,
1431
+ .pre_write = idr_prew,
1432
+ },{ .name = "ITR", .addr = A_ITR,
1433
+ .pre_write = itr_prew,
1434
+ },{ .name = "PARITY_ISR", .addr = A_PARITY_ISR,
1435
+ .w1c = 0x1fff,
1436
+ .post_write = parity_isr_postw,
1437
+ },{ .name = "PARITY_IMR", .addr = A_PARITY_IMR,
1438
+ .reset = 0x1fff,
1439
+ .ro = 0x1fff,
1440
+ },{ .name = "PARITY_IER", .addr = A_PARITY_IER,
1441
+ .pre_write = parity_ier_prew,
1442
+ },{ .name = "PARITY_IDR", .addr = A_PARITY_IDR,
1443
+ .pre_write = parity_idr_prew,
1444
+ },{ .name = "PARITY_ITR", .addr = A_PARITY_ITR,
1445
+ .pre_write = parity_itr_prew,
1446
+ },{ .name = "WPROT0", .addr = A_WPROT0,
1447
+ .reset = 0x1,
1448
+ }
1449
+};
1450
+
1451
+static void xlnx_versal_pmc_iou_slcr_reset_init(Object *obj, ResetType type)
1452
+{
1453
+ XlnxVersalPmcIouSlcr *s = XILINX_VERSAL_PMC_IOU_SLCR(obj);
1454
+ unsigned int i;
1455
+
1456
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
1457
+ register_reset(&s->regs_info[i]);
1458
+ }
1459
+}
1460
+
1461
+static void xlnx_versal_pmc_iou_slcr_reset_hold(Object *obj)
1462
+{
1463
+ XlnxVersalPmcIouSlcr *s = XILINX_VERSAL_PMC_IOU_SLCR(obj);
1464
+
1465
+ parity_imr_update_irq(s);
1466
+ imr_update_irq(s);
1467
+
1468
+ /*
1469
+ * Setup OSPI_QSPI mux
1470
+ * By default axi slave interface is enabled for ospi-dma
1471
+ */
1472
+ qemu_set_irq(s->ospi_mux_sel, 0);
1473
+ qemu_set_irq(s->qspi_ospi_mux_sel, 1);
1474
+}
1475
+
1476
+static const MemoryRegionOps pmc_iou_slcr_ops = {
1477
+ .read = register_read_memory,
1478
+ .write = register_write_memory,
1479
+ .endianness = DEVICE_LITTLE_ENDIAN,
1480
+ .valid = {
37
+ .min_access_size = 4,
1481
+ .min_access_size = 4,
38
+ .max_access_size = 4,
1482
+ .max_access_size = 4,
39
+ },
1483
+ },
40
.valid = {
1484
+};
41
.min_access_size = 1,
1485
+
42
.max_access_size = 4
1486
+static void xlnx_versal_pmc_iou_slcr_realize(DeviceState *dev, Error **errp)
1487
+{
1488
+ XlnxVersalPmcIouSlcr *s = XILINX_VERSAL_PMC_IOU_SLCR(dev);
1489
+
1490
+ qdev_init_gpio_out_named(dev, s->sd_emmc_sel, "sd-emmc-sel", 2);
1491
+ qdev_init_gpio_out_named(dev, &s->qspi_ospi_mux_sel,
1492
+ "qspi-ospi-mux-sel", 1);
1493
+ qdev_init_gpio_out_named(dev, &s->ospi_mux_sel, "ospi-mux-sel", 1);
1494
+}
1495
+
1496
+static void xlnx_versal_pmc_iou_slcr_init(Object *obj)
1497
+{
1498
+ XlnxVersalPmcIouSlcr *s = XILINX_VERSAL_PMC_IOU_SLCR(obj);
1499
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
1500
+ RegisterInfoArray *reg_array;
1501
+
1502
+ memory_region_init(&s->iomem, obj, TYPE_XILINX_VERSAL_PMC_IOU_SLCR,
1503
+ XILINX_VERSAL_PMC_IOU_SLCR_R_MAX * 4);
1504
+ reg_array =
1505
+ register_init_block32(DEVICE(obj), pmc_iou_slcr_regs_info,
1506
+ ARRAY_SIZE(pmc_iou_slcr_regs_info),
1507
+ s->regs_info, s->regs,
1508
+ &pmc_iou_slcr_ops,
1509
+ XILINX_VERSAL_PMC_IOU_SLCR_ERR_DEBUG,
1510
+ XILINX_VERSAL_PMC_IOU_SLCR_R_MAX * 4);
1511
+ memory_region_add_subregion(&s->iomem,
1512
+ 0x0,
1513
+ &reg_array->mem);
1514
+ sysbus_init_mmio(sbd, &s->iomem);
1515
+ sysbus_init_irq(sbd, &s->irq_parity_imr);
1516
+ sysbus_init_irq(sbd, &s->irq_imr);
1517
+}
1518
+
1519
+static const VMStateDescription vmstate_pmc_iou_slcr = {
1520
+ .name = TYPE_XILINX_VERSAL_PMC_IOU_SLCR,
1521
+ .version_id = 1,
1522
+ .minimum_version_id = 1,
1523
+ .fields = (VMStateField[]) {
1524
+ VMSTATE_UINT32_ARRAY(regs, XlnxVersalPmcIouSlcr,
1525
+ XILINX_VERSAL_PMC_IOU_SLCR_R_MAX),
1526
+ VMSTATE_END_OF_LIST(),
1527
+ }
1528
+};
1529
+
1530
+static void xlnx_versal_pmc_iou_slcr_class_init(ObjectClass *klass, void *data)
1531
+{
1532
+ DeviceClass *dc = DEVICE_CLASS(klass);
1533
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
1534
+
1535
+ dc->realize = xlnx_versal_pmc_iou_slcr_realize;
1536
+ dc->vmsd = &vmstate_pmc_iou_slcr;
1537
+ rc->phases.enter = xlnx_versal_pmc_iou_slcr_reset_init;
1538
+ rc->phases.hold = xlnx_versal_pmc_iou_slcr_reset_hold;
1539
+}
1540
+
1541
+static const TypeInfo xlnx_versal_pmc_iou_slcr_info = {
1542
+ .name = TYPE_XILINX_VERSAL_PMC_IOU_SLCR,
1543
+ .parent = TYPE_SYS_BUS_DEVICE,
1544
+ .instance_size = sizeof(XlnxVersalPmcIouSlcr),
1545
+ .class_init = xlnx_versal_pmc_iou_slcr_class_init,
1546
+ .instance_init = xlnx_versal_pmc_iou_slcr_init,
1547
+};
1548
+
1549
+static void xlnx_versal_pmc_iou_slcr_register_types(void)
1550
+{
1551
+ type_register_static(&xlnx_versal_pmc_iou_slcr_info);
1552
+}
1553
+
1554
+type_init(xlnx_versal_pmc_iou_slcr_register_types)
1555
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
1556
index XXXXXXX..XXXXXXX 100644
1557
--- a/hw/misc/meson.build
1558
+++ b/hw/misc/meson.build
1559
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
1560
))
1561
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
1562
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
1563
-softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-xramc.c'))
1564
+softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
1565
+ 'xlnx-versal-xramc.c',
1566
+ 'xlnx-versal-pmc-iou-slcr.c',
1567
+))
1568
softmmu_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: files('stm32f2xx_syscfg.c'))
1569
softmmu_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: files('stm32f4xx_syscfg.c'))
1570
softmmu_ss.add(when: 'CONFIG_STM32F4XX_EXTI', if_true: files('stm32f4xx_exti.c'))
43
--
1571
--
44
2.20.1
1572
2.25.1
45
1573
46
1574
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
2
2
3
In the next commit we will implement the write_with_attrs()
3
Add an orgate and 'or' the interrupts from the BBRAM and RTC models.
4
handler. To avoid using different APIs, convert the read()
5
handler first.
6
4
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
5
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
8
Tested-by: Francisco Iglesias <frasse.iglesias@gmail.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Message-id: 20220121161141.14389-3-francisco.iglesias@xilinx.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
hw/ssi/xilinx_spips.c | 23 +++++++++++------------
11
include/hw/arm/xlnx-versal.h | 5 +++--
13
1 file changed, 11 insertions(+), 12 deletions(-)
12
hw/arm/xlnx-versal-virt.c | 2 +-
13
hw/arm/xlnx-versal.c | 28 ++++++++++++++++++++++++++--
14
3 files changed, 30 insertions(+), 5 deletions(-)
14
15
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
18
--- a/include/hw/arm/xlnx-versal.h
18
+++ b/hw/ssi/xilinx_spips.c
19
+++ b/include/hw/arm/xlnx-versal.h
19
@@ -XXX,XX +XXX,XX @@ static void lqspi_load_cache(void *opaque, hwaddr addr)
20
@@ -XXX,XX +XXX,XX @@ struct Versal {
21
XlnxEFuse efuse;
22
XlnxVersalEFuseCtrl efuse_ctrl;
23
XlnxVersalEFuseCache efuse_cache;
24
+
25
+ qemu_or_irq apb_irq_orgate;
26
} pmc;
27
28
struct {
29
@@ -XXX,XX +XXX,XX @@ struct Versal {
30
#define VERSAL_GEM1_WAKE_IRQ_0 59
31
#define VERSAL_ADMA_IRQ_0 60
32
#define VERSAL_XRAM_IRQ_0 79
33
-#define VERSAL_BBRAM_APB_IRQ_0 121
34
-#define VERSAL_RTC_APB_ERR_IRQ 121
35
+#define VERSAL_PMC_APB_IRQ 121
36
#define VERSAL_SD0_IRQ_0 126
37
#define VERSAL_EFUSE_IRQ 139
38
#define VERSAL_RTC_ALARM_IRQ 142
39
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/arm/xlnx-versal-virt.c
42
+++ b/hw/arm/xlnx-versal-virt.c
43
@@ -XXX,XX +XXX,XX @@ static void fdt_add_bbram_node(VersalVirt *s)
44
qemu_fdt_add_subnode(s->fdt, name);
45
46
qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
47
- GIC_FDT_IRQ_TYPE_SPI, VERSAL_BBRAM_APB_IRQ_0,
48
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_PMC_APB_IRQ,
49
GIC_FDT_IRQ_FLAGS_LEVEL_HI);
50
qemu_fdt_setprop(s->fdt, name, "interrupt-names",
51
interrupt_names, sizeof(interrupt_names));
52
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/arm/xlnx-versal.c
55
+++ b/hw/arm/xlnx-versal.c
56
@@ -XXX,XX +XXX,XX @@
57
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
58
#define GEM_REVISION 0x40070106
59
60
+#define VERSAL_NUM_PMC_APB_IRQS 2
61
+
62
static void versal_create_apu_cpus(Versal *s)
63
{
64
int i;
65
@@ -XXX,XX +XXX,XX @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
20
}
66
}
21
}
67
}
22
68
23
-static uint64_t
69
+static void versal_create_pmc_apb_irq_orgate(Versal *s, qemu_irq *pic)
24
-lqspi_read(void *opaque, hwaddr addr, unsigned int size)
70
+{
25
+static MemTxResult lqspi_read(void *opaque, hwaddr addr, uint64_t *value,
71
+ DeviceState *orgate;
26
+ unsigned size, MemTxAttrs attrs)
72
+
73
+ /*
74
+ * The VERSAL_PMC_APB_IRQ is an 'or' of the interrupts from the following
75
+ * models:
76
+ * - RTC
77
+ * - BBRAM
78
+ */
79
+ object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate",
80
+ &s->pmc.apb_irq_orgate, TYPE_OR_IRQ);
81
+ orgate = DEVICE(&s->pmc.apb_irq_orgate);
82
+ object_property_set_int(OBJECT(orgate),
83
+ "num-lines", VERSAL_NUM_PMC_APB_IRQS, &error_fatal);
84
+ qdev_realize(orgate, NULL, &error_fatal);
85
+ qdev_connect_gpio_out(orgate, 0, pic[VERSAL_PMC_APB_IRQ]);
86
+}
87
+
88
static void versal_create_rtc(Versal *s, qemu_irq *pic)
27
{
89
{
28
- XilinxQSPIPS *q = opaque;
90
SysBusDevice *sbd;
29
- uint32_t ret;
91
@@ -XXX,XX +XXX,XX @@ static void versal_create_rtc(Versal *s, qemu_irq *pic)
30
+ XilinxQSPIPS *q = XILINX_QSPIPS(opaque);
92
* TODO: Connect the ALARM and SECONDS interrupts once our RTC model
31
93
* supports them.
32
if (addr >= q->lqspi_cached_addr &&
94
*/
33
addr <= q->lqspi_cached_addr + LQSPI_CACHE_SIZE - 4) {
95
- sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
34
uint8_t *retp = &q->lqspi_buf[addr - q->lqspi_cached_addr];
96
+ sysbus_connect_irq(sbd, 1,
35
- ret = cpu_to_le32(*(uint32_t *)retp);
97
+ qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 0));
36
- DB_PRINT_L(1, "addr: %08x, data: %08x\n", (unsigned)addr,
37
- (unsigned)ret);
38
- return ret;
39
- } else {
40
- lqspi_load_cache(opaque, addr);
41
- return lqspi_read(opaque, addr, size);
42
+ *value = cpu_to_le32(*(uint32_t *)retp);
43
+ DB_PRINT_L(1, "addr: %08" HWADDR_PRIx ", data: %08" PRIx64 "\n",
44
+ addr, *value);
45
+ return MEMTX_OK;
46
}
47
+
48
+ lqspi_load_cache(opaque, addr);
49
+ return lqspi_read(opaque, addr, value, size, attrs);
50
}
98
}
51
99
52
static const MemoryRegionOps lqspi_ops = {
100
static void versal_create_xrams(Versal *s, qemu_irq *pic)
53
- .read = lqspi_read,
101
@@ -XXX,XX +XXX,XX @@ static void versal_create_bbram(Versal *s, qemu_irq *pic)
54
+ .read_with_attrs = lqspi_read,
102
sysbus_realize(sbd, &error_fatal);
55
.endianness = DEVICE_NATIVE_ENDIAN,
103
memory_region_add_subregion(&s->mr_ps, MM_PMC_BBRAM_CTRL,
56
.valid = {
104
sysbus_mmio_get_region(sbd, 0));
57
.min_access_size = 1,
105
- sysbus_connect_irq(sbd, 0, pic[VERSAL_BBRAM_APB_IRQ_0]);
106
+ sysbus_connect_irq(sbd, 0,
107
+ qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 1));
108
}
109
110
static void versal_realize_efuse_part(Versal *s, Object *dev, hwaddr base)
111
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
112
versal_create_gems(s, pic);
113
versal_create_admas(s, pic);
114
versal_create_sds(s, pic);
115
+ versal_create_pmc_apb_irq_orgate(s, pic);
116
versal_create_rtc(s, pic);
117
versal_create_xrams(s, pic);
118
versal_create_bbram(s, pic);
58
--
119
--
59
2.20.1
120
2.25.1
60
121
61
122
diff view generated by jsdifflib
New patch
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
1
2
3
Connect Versal's PMC SLCR (system-level control registers) model.
4
5
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
6
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
Message-id: 20220121161141.14389-4-francisco.iglesias@xilinx.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
include/hw/arm/xlnx-versal.h | 5 +++
11
hw/arm/xlnx-versal.c | 71 +++++++++++++++++++++++++++++++++++-
12
2 files changed, 75 insertions(+), 1 deletion(-)
13
14
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/xlnx-versal.h
17
+++ b/include/hw/arm/xlnx-versal.h
18
@@ -XXX,XX +XXX,XX @@
19
#include "hw/misc/xlnx-versal-xramc.h"
20
#include "hw/nvram/xlnx-bbram.h"
21
#include "hw/nvram/xlnx-versal-efuse.h"
22
+#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
23
24
#define TYPE_XLNX_VERSAL "xlnx-versal"
25
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
26
@@ -XXX,XX +XXX,XX @@ struct Versal {
27
struct {
28
struct {
29
SDHCIState sd[XLNX_VERSAL_NR_SDS];
30
+ XlnxVersalPmcIouSlcr slcr;
31
} iou;
32
33
XlnxZynqMPRTC rtc;
34
@@ -XXX,XX +XXX,XX @@ struct Versal {
35
#define MM_FPD_FPD_APU 0xfd5c0000
36
#define MM_FPD_FPD_APU_SIZE 0x100
37
38
+#define MM_PMC_PMC_IOU_SLCR 0xf1060000
39
+#define MM_PMC_PMC_IOU_SLCR_SIZE 0x10000
40
+
41
#define MM_PMC_SD0 0xf1040000U
42
#define MM_PMC_SD0_SIZE 0x10000
43
#define MM_PMC_BBRAM_CTRL 0xf11f0000
44
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/xlnx-versal.c
47
+++ b/hw/arm/xlnx-versal.c
48
@@ -XXX,XX +XXX,XX @@
49
#include "kvm_arm.h"
50
#include "hw/misc/unimp.h"
51
#include "hw/arm/xlnx-versal.h"
52
+#include "qemu/log.h"
53
+#include "hw/sysbus.h"
54
55
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
56
#define GEM_REVISION 0x40070106
57
58
-#define VERSAL_NUM_PMC_APB_IRQS 2
59
+#define VERSAL_NUM_PMC_APB_IRQS 3
60
61
static void versal_create_apu_cpus(Versal *s)
62
{
63
@@ -XXX,XX +XXX,XX @@ static void versal_create_pmc_apb_irq_orgate(Versal *s, qemu_irq *pic)
64
* models:
65
* - RTC
66
* - BBRAM
67
+ * - PMC SLCR
68
*/
69
object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate",
70
&s->pmc.apb_irq_orgate, TYPE_OR_IRQ);
71
@@ -XXX,XX +XXX,XX @@ static void versal_create_efuse(Versal *s, qemu_irq *pic)
72
sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]);
73
}
74
75
+static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic)
76
+{
77
+ SysBusDevice *sbd;
78
+
79
+ object_initialize_child(OBJECT(s), "versal-pmc-iou-slcr", &s->pmc.iou.slcr,
80
+ TYPE_XILINX_VERSAL_PMC_IOU_SLCR);
81
+
82
+ sbd = SYS_BUS_DEVICE(&s->pmc.iou.slcr);
83
+ sysbus_realize(sbd, &error_fatal);
84
+
85
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_PMC_IOU_SLCR,
86
+ sysbus_mmio_get_region(sbd, 0));
87
+
88
+ sysbus_connect_irq(sbd, 0,
89
+ qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 2));
90
+}
91
+
92
/* This takes the board allocated linear DDR memory and creates aliases
93
* for each split DDR range/aperture on the Versal address map.
94
*/
95
@@ -XXX,XX +XXX,XX @@ static void versal_unimp_area(Versal *s, const char *name,
96
memory_region_add_subregion(mr, base, mr_dev);
97
}
98
99
+static void versal_unimp_sd_emmc_sel(void *opaque, int n, int level)
100
+{
101
+ qemu_log_mask(LOG_UNIMP,
102
+ "Selecting between enabling SD mode or eMMC mode on "
103
+ "controller %d is not yet implemented\n", n);
104
+}
105
+
106
+static void versal_unimp_qspi_ospi_mux_sel(void *opaque, int n, int level)
107
+{
108
+ qemu_log_mask(LOG_UNIMP,
109
+ "Selecting between enabling the QSPI or OSPI linear address "
110
+ "region is not yet implemented\n");
111
+}
112
+
113
+static void versal_unimp_irq_parity_imr(void *opaque, int n, int level)
114
+{
115
+ qemu_log_mask(LOG_UNIMP,
116
+ "PMC SLCR parity interrupt behaviour "
117
+ "is not yet implemented\n");
118
+}
119
+
120
static void versal_unimp(Versal *s)
121
{
122
+ qemu_irq gpio_in;
123
+
124
versal_unimp_area(s, "psm", &s->mr_ps,
125
MM_PSM_START, MM_PSM_END - MM_PSM_START);
126
versal_unimp_area(s, "crl", &s->mr_ps,
127
@@ -XXX,XX +XXX,XX @@ static void versal_unimp(Versal *s)
128
MM_IOU_SCNTR, MM_IOU_SCNTR_SIZE);
129
versal_unimp_area(s, "iou-scntr-seucre", &s->mr_ps,
130
MM_IOU_SCNTRS, MM_IOU_SCNTRS_SIZE);
131
+
132
+ qdev_init_gpio_in_named(DEVICE(s), versal_unimp_sd_emmc_sel,
133
+ "sd-emmc-sel-dummy", 2);
134
+ qdev_init_gpio_in_named(DEVICE(s), versal_unimp_qspi_ospi_mux_sel,
135
+ "qspi-ospi-mux-sel-dummy", 1);
136
+ qdev_init_gpio_in_named(DEVICE(s), versal_unimp_irq_parity_imr,
137
+ "irq-parity-imr-dummy", 1);
138
+
139
+ gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 0);
140
+ qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 0,
141
+ gpio_in);
142
+
143
+ gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 1);
144
+ qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 1,
145
+ gpio_in);
146
+
147
+ gpio_in = qdev_get_gpio_in_named(DEVICE(s), "qspi-ospi-mux-sel-dummy", 0);
148
+ qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr),
149
+ "qspi-ospi-mux-sel", 0,
150
+ gpio_in);
151
+
152
+ gpio_in = qdev_get_gpio_in_named(DEVICE(s), "irq-parity-imr-dummy", 0);
153
+ qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr),
154
+ SYSBUS_DEVICE_GPIO_IRQ, 0,
155
+ gpio_in);
156
}
157
158
static void versal_realize(DeviceState *dev, Error **errp)
159
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
160
versal_create_xrams(s, pic);
161
versal_create_bbram(s, pic);
162
versal_create_efuse(s, pic);
163
+ versal_create_pmc_iou_slcr(s, pic);
164
versal_map_ddr(s);
165
versal_unimp(s);
166
167
--
168
2.25.1
169
170
diff view generated by jsdifflib
New patch
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
1
2
3
Add in the missing includes in the header for being able to build the DMA
4
model when reusing it.
5
6
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Luc Michel <luc@lmichel.fr>
9
Message-id: 20220121161141.14389-5-francisco.iglesias@xilinx.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/dma/xlnx_csu_dma.h | 5 +++++
13
1 file changed, 5 insertions(+)
14
15
diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/dma/xlnx_csu_dma.h
18
+++ b/include/hw/dma/xlnx_csu_dma.h
19
@@ -XXX,XX +XXX,XX @@
20
#ifndef XLNX_CSU_DMA_H
21
#define XLNX_CSU_DMA_H
22
23
+#include "hw/sysbus.h"
24
+#include "hw/register.h"
25
+#include "hw/ptimer.h"
26
+#include "hw/stream.h"
27
+
28
#define TYPE_XLNX_CSU_DMA "xlnx.csu_dma"
29
30
#define XLNX_CSU_DMA_R_MAX (0x2c / 4)
31
--
32
2.25.1
33
34
diff view generated by jsdifflib
New patch
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
1
2
3
An option on real hardware when embedding a DMA engine into a peripheral
4
is to make the peripheral control the engine through a custom DMA control
5
(hardware) interface between the two. Software drivers in this scenario
6
configure and trigger DMA operations through the controlling peripheral's
7
register API (for example, writing a specific bit in a register could
8
propagate down to a transfer start signal on the DMA control interface).
9
At the same time the status, results and interrupts for the transfer might
10
still be intended to be read and caught through the DMA engine's register
11
API (and signals).
12
13
This patch adds a class 'read' method for allowing to start read transfers
14
from peripherals embedding and controlling the Xilinx CSU DMA engine as in
15
above scenario.
16
17
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
18
Reviewed-by: Luc Michel <luc@lmichel.fr>
19
Message-id: 20220121161141.14389-6-francisco.iglesias@xilinx.com
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
22
include/hw/dma/xlnx_csu_dma.h | 19 +++++++++++++++++--
23
hw/dma/xlnx_csu_dma.c | 17 +++++++++++++++++
24
2 files changed, 34 insertions(+), 2 deletions(-)
25
26
diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/dma/xlnx_csu_dma.h
29
+++ b/include/hw/dma/xlnx_csu_dma.h
30
@@ -XXX,XX +XXX,XX @@ typedef struct XlnxCSUDMA {
31
RegisterInfo regs_info[XLNX_CSU_DMA_R_MAX];
32
} XlnxCSUDMA;
33
34
-#define XLNX_CSU_DMA(obj) \
35
- OBJECT_CHECK(XlnxCSUDMA, (obj), TYPE_XLNX_CSU_DMA)
36
+OBJECT_DECLARE_TYPE(XlnxCSUDMA, XlnxCSUDMAClass, XLNX_CSU_DMA)
37
+
38
+struct XlnxCSUDMAClass {
39
+ SysBusDeviceClass parent_class;
40
+
41
+ /*
42
+ * read: Start a read transfer on a Xilinx CSU DMA engine
43
+ *
44
+ * @s: the Xilinx CSU DMA engine to start the transfer on
45
+ * @addr: the address to read
46
+ * @len: the number of bytes to read at 'addr'
47
+ *
48
+ * @return a MemTxResult indicating whether the operation succeeded ('len'
49
+ * bytes were read) or failed.
50
+ */
51
+ MemTxResult (*read)(XlnxCSUDMA *s, hwaddr addr, uint32_t len);
52
+};
53
54
#endif
55
diff --git a/hw/dma/xlnx_csu_dma.c b/hw/dma/xlnx_csu_dma.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/dma/xlnx_csu_dma.c
58
+++ b/hw/dma/xlnx_csu_dma.c
59
@@ -XXX,XX +XXX,XX @@ static uint64_t addr_msb_pre_write(RegisterInfo *reg, uint64_t val)
60
return val & R_ADDR_MSB_ADDR_MSB_MASK;
61
}
62
63
+static MemTxResult xlnx_csu_dma_class_read(XlnxCSUDMA *s, hwaddr addr,
64
+ uint32_t len)
65
+{
66
+ RegisterInfo *reg = &s->regs_info[R_SIZE];
67
+ uint64_t we = MAKE_64BIT_MASK(0, 4 * 8);
68
+
69
+ s->regs[R_ADDR] = addr;
70
+ s->regs[R_ADDR_MSB] = (uint64_t)addr >> 32;
71
+
72
+ register_write(reg, len, we, object_get_typename(OBJECT(s)), false);
73
+
74
+ return (s->regs[R_SIZE] == 0) ? MEMTX_OK : MEMTX_ERROR;
75
+}
76
+
77
static const RegisterAccessInfo *xlnx_csu_dma_regs_info[] = {
78
#define DMACH_REGINFO(NAME, snd) \
79
(const RegisterAccessInfo []) { \
80
@@ -XXX,XX +XXX,XX @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, void *data)
81
{
82
DeviceClass *dc = DEVICE_CLASS(klass);
83
StreamSinkClass *ssc = STREAM_SINK_CLASS(klass);
84
+ XlnxCSUDMAClass *xcdc = XLNX_CSU_DMA_CLASS(klass);
85
86
dc->reset = xlnx_csu_dma_reset;
87
dc->realize = xlnx_csu_dma_realize;
88
@@ -XXX,XX +XXX,XX @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, void *data)
89
90
ssc->push = xlnx_csu_dma_stream_push;
91
ssc->can_push = xlnx_csu_dma_stream_can_push;
92
+
93
+ xcdc->read = xlnx_csu_dma_class_read;
94
}
95
96
static void xlnx_csu_dma_init(Object *obj)
97
--
98
2.25.1
99
100
diff view generated by jsdifflib
1
The PL031 RTC tracks the difference between the guest RTC
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
2
and the host RTC using a tick_offset field. For migration,
3
however, we currently always migrate the offset between
4
the guest and the vm_clock, even if the RTC clock is not
5
the same as the vm_clock; this was an attempt to retain
6
migration backwards compatibility.
7
2
8
Unfortunately this results in the RTC behaving oddly across
3
Add a model of Xilinx Versal's OSPI flash memory controller.
9
a VM state save and restore -- since the VM clock stands still
10
across save-then-restore, regardless of how much real world
11
time has elapsed, the guest RTC ends up out of sync with the
12
host RTC in the restored VM.
13
4
14
Fix this by migrating the raw tick_offset. To retain migration
5
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
15
compatibility as far as possible, we have a new property
6
Reviewed-by: Luc Michel <luc@lmichel.fr>
16
migrate-tick-offset; by default this is 'true' and we will
7
Message-id: 20220121161141.14389-7-francisco.iglesias@xilinx.com
17
migrate the true tick offset in a new subsection; if the
8
[PMM: fixed indent]
18
incoming data has no subsection we fall back to the old
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
vm_clock-based offset information, so old->new migration
10
---
20
compatibility is preserved. For complete new->old migration
11
include/hw/ssi/xlnx-versal-ospi.h | 111 ++
21
compatibility, the property is set to 'false' for 4.0 and
12
hw/ssi/xlnx-versal-ospi.c | 1853 +++++++++++++++++++++++++++++
22
earlier machine types (this will only affect 'virt-4.0'
13
hw/ssi/meson.build | 1 +
23
and below, as none of the other pl031-using machines are
14
3 files changed, 1965 insertions(+)
24
versioned).
15
create mode 100644 include/hw/ssi/xlnx-versal-ospi.h
16
create mode 100644 hw/ssi/xlnx-versal-ospi.c
25
17
26
Reported-by: Russell King <rmk@armlinux.org.uk>
18
diff --git a/include/hw/ssi/xlnx-versal-ospi.h b/include/hw/ssi/xlnx-versal-ospi.h
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
new file mode 100644
28
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
20
index XXXXXXX..XXXXXXX
29
Message-id: 20190709143912.28905-1-peter.maydell@linaro.org
21
--- /dev/null
30
---
22
+++ b/include/hw/ssi/xlnx-versal-ospi.h
31
include/hw/timer/pl031.h | 2 +
23
@@ -XXX,XX +XXX,XX @@
32
hw/core/machine.c | 1 +
24
+/*
33
hw/timer/pl031.c | 92 ++++++++++++++++++++++++++++++++++++++--
25
+ * Header file for the Xilinx Versal's OSPI controller
34
3 files changed, 91 insertions(+), 4 deletions(-)
26
+ *
35
27
+ * Copyright (C) 2021 Xilinx Inc
36
diff --git a/include/hw/timer/pl031.h b/include/hw/timer/pl031.h
28
+ * Written by Francisco Iglesias <francisco.iglesias@xilinx.com>
37
index XXXXXXX..XXXXXXX 100644
29
+ *
38
--- a/include/hw/timer/pl031.h
30
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
39
+++ b/include/hw/timer/pl031.h
31
+ * of this software and associated documentation files (the "Software"), to deal
40
@@ -XXX,XX +XXX,XX @@ typedef struct PL031State {
32
+ * in the Software without restriction, including without limitation the rights
41
*/
33
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
42
uint32_t tick_offset_vmstate;
34
+ * copies of the Software, and to permit persons to whom the Software is
43
uint32_t tick_offset;
35
+ * furnished to do so, subject to the following conditions:
44
+ bool tick_offset_migrated;
36
+ *
45
+ bool migrate_tick_offset;
37
+ * The above copyright notice and this permission notice shall be included in
46
38
+ * all copies or substantial portions of the Software.
47
uint32_t mr;
39
+ *
48
uint32_t lr;
40
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
49
diff --git a/hw/core/machine.c b/hw/core/machine.c
41
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
50
index XXXXXXX..XXXXXXX 100644
42
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
51
--- a/hw/core/machine.c
43
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
52
+++ b/hw/core/machine.c
44
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
53
@@ -XXX,XX +XXX,XX @@ GlobalProperty hw_compat_4_0[] = {
45
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
54
{ "virtio-gpu-pci", "edid", "false" },
46
+ * THE SOFTWARE.
55
{ "virtio-device", "use-started", "false" },
47
+ */
56
{ "virtio-balloon-device", "qemu-4-0-config-size", "true" },
48
+
57
+ { "pl031", "migrate-tick-offset", "false" },
49
+/*
58
};
50
+ * This is a model of Xilinx Versal's Octal SPI flash memory controller
59
const size_t hw_compat_4_0_len = G_N_ELEMENTS(hw_compat_4_0);
51
+ * documented in Versal's Technical Reference manual [1] and the Versal ACAP
60
52
+ * Register reference [2].
61
diff --git a/hw/timer/pl031.c b/hw/timer/pl031.c
53
+ *
62
index XXXXXXX..XXXXXXX 100644
54
+ * References:
63
--- a/hw/timer/pl031.c
55
+ *
64
+++ b/hw/timer/pl031.c
56
+ * [1] Versal ACAP Technical Reference Manual,
65
@@ -XXX,XX +XXX,XX @@ static int pl031_pre_save(void *opaque)
57
+ * https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
66
{
58
+ *
67
PL031State *s = opaque;
59
+ * [2] Versal ACAP Register Reference,
68
60
+ * https://www.xilinx.com/html_docs/registers/am012/am012-versal-register-reference.html#mod___ospi.html
69
- /* tick_offset is base_time - rtc_clock base time. Instead, we want to
61
+ *
70
- * store the base time relative to the QEMU_CLOCK_VIRTUAL for backwards-compatibility. */
62
+ *
63
+ * QEMU interface:
64
+ * + sysbus MMIO region 0: MemoryRegion for the device's registers
65
+ * + sysbus MMIO region 1: MemoryRegion for flash memory linear address space
66
+ * (data transfer).
67
+ * + sysbus IRQ 0: Device interrupt.
68
+ * + Named GPIO input "ospi-mux-sel": 0: enables indirect access mode
69
+ * and 1: enables direct access mode.
70
+ * + Property "dac-with-indac": Allow both direct accesses and indirect
71
+ * accesses simultaneously.
72
+ * + Property "indac-write-disabled": Disable indirect access writes.
73
+ */
74
+
75
+#ifndef XILINX_VERSAL_OSPI_H
76
+#define XILINX_VERSAL_OSPI_H
77
+
78
+#include "hw/register.h"
79
+#include "hw/ssi/ssi.h"
80
+#include "qemu/fifo8.h"
81
+#include "hw/dma/xlnx_csu_dma.h"
82
+
83
+#define TYPE_XILINX_VERSAL_OSPI "xlnx.versal-ospi"
84
+
85
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalOspi, XILINX_VERSAL_OSPI)
86
+
87
+#define XILINX_VERSAL_OSPI_R_MAX (0xfc / 4 + 1)
88
+
89
+/*
90
+ * Indirect operations
91
+ */
92
+typedef struct IndOp {
93
+ uint32_t flash_addr;
94
+ uint32_t num_bytes;
95
+ uint32_t done_bytes;
96
+ bool completed;
97
+} IndOp;
98
+
99
+struct XlnxVersalOspi {
100
+ SysBusDevice parent_obj;
101
+
102
+ MemoryRegion iomem;
103
+ MemoryRegion iomem_dac;
104
+
105
+ uint8_t num_cs;
106
+ qemu_irq *cs_lines;
107
+
108
+ SSIBus *spi;
109
+
110
+ Fifo8 rx_fifo;
111
+ Fifo8 tx_fifo;
112
+
113
+ Fifo8 rx_sram;
114
+ Fifo8 tx_sram;
115
+
116
+ qemu_irq irq;
117
+
118
+ XlnxCSUDMA *dma_src;
119
+ bool ind_write_disabled;
120
+ bool dac_with_indac;
121
+ bool dac_enable;
122
+ bool src_dma_inprog;
123
+
124
+ IndOp rd_ind_op[2];
125
+ IndOp wr_ind_op[2];
126
+
127
+ uint32_t regs[XILINX_VERSAL_OSPI_R_MAX];
128
+ RegisterInfo regs_info[XILINX_VERSAL_OSPI_R_MAX];
129
+
130
+ /* Maximum inferred membank size is 512 bytes */
131
+ uint8_t stig_membank[512];
132
+};
133
+
134
+#endif /* XILINX_VERSAL_OSPI_H */
135
diff --git a/hw/ssi/xlnx-versal-ospi.c b/hw/ssi/xlnx-versal-ospi.c
136
new file mode 100644
137
index XXXXXXX..XXXXXXX
138
--- /dev/null
139
+++ b/hw/ssi/xlnx-versal-ospi.c
140
@@ -XXX,XX +XXX,XX @@
141
+/*
142
+ * QEMU model of Xilinx Versal's OSPI controller.
143
+ *
144
+ * Copyright (c) 2021 Xilinx Inc.
145
+ * Written by Francisco Iglesias <francisco.iglesias@xilinx.com>
146
+ *
147
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
148
+ * of this software and associated documentation files (the "Software"), to deal
149
+ * in the Software without restriction, including without limitation the rights
150
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
151
+ * copies of the Software, and to permit persons to whom the Software is
152
+ * furnished to do so, subject to the following conditions:
153
+ *
154
+ * The above copyright notice and this permission notice shall be included in
155
+ * all copies or substantial portions of the Software.
156
+ *
157
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
158
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
159
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
160
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
161
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
162
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
163
+ * THE SOFTWARE.
164
+ */
165
+#include "qemu/osdep.h"
166
+#include "hw/sysbus.h"
167
+#include "migration/vmstate.h"
168
+#include "hw/qdev-properties.h"
169
+#include "qemu/bitops.h"
170
+#include "qemu/log.h"
171
+#include "hw/irq.h"
172
+#include "hw/ssi/xlnx-versal-ospi.h"
173
+
174
+#ifndef XILINX_VERSAL_OSPI_ERR_DEBUG
175
+#define XILINX_VERSAL_OSPI_ERR_DEBUG 0
176
+#endif
177
+
178
+REG32(CONFIG_REG, 0x0)
179
+ FIELD(CONFIG_REG, IDLE_FLD, 31, 1)
180
+ FIELD(CONFIG_REG, DUAL_BYTE_OPCODE_EN_FLD, 30, 1)
181
+ FIELD(CONFIG_REG, CRC_ENABLE_FLD, 29, 1)
182
+ FIELD(CONFIG_REG, CONFIG_RESV2_FLD, 26, 3)
183
+ FIELD(CONFIG_REG, PIPELINE_PHY_FLD, 25, 1)
184
+ FIELD(CONFIG_REG, ENABLE_DTR_PROTOCOL_FLD, 24, 1)
185
+ FIELD(CONFIG_REG, ENABLE_AHB_DECODER_FLD, 23, 1)
186
+ FIELD(CONFIG_REG, MSTR_BAUD_DIV_FLD, 19, 4)
187
+ FIELD(CONFIG_REG, ENTER_XIP_MODE_IMM_FLD, 18, 1)
188
+ FIELD(CONFIG_REG, ENTER_XIP_MODE_FLD, 17, 1)
189
+ FIELD(CONFIG_REG, ENB_AHB_ADDR_REMAP_FLD, 16, 1)
190
+ FIELD(CONFIG_REG, ENB_DMA_IF_FLD, 15, 1)
191
+ FIELD(CONFIG_REG, WR_PROT_FLASH_FLD, 14, 1)
192
+ FIELD(CONFIG_REG, PERIPH_CS_LINES_FLD, 10, 4)
193
+ FIELD(CONFIG_REG, PERIPH_SEL_DEC_FLD, 9, 1)
194
+ FIELD(CONFIG_REG, ENB_LEGACY_IP_MODE_FLD, 8, 1)
195
+ FIELD(CONFIG_REG, ENB_DIR_ACC_CTLR_FLD, 7, 1)
196
+ FIELD(CONFIG_REG, RESET_CFG_FLD, 6, 1)
197
+ FIELD(CONFIG_REG, RESET_PIN_FLD, 5, 1)
198
+ FIELD(CONFIG_REG, HOLD_PIN_FLD, 4, 1)
199
+ FIELD(CONFIG_REG, PHY_MODE_ENABLE_FLD, 3, 1)
200
+ FIELD(CONFIG_REG, SEL_CLK_PHASE_FLD, 2, 1)
201
+ FIELD(CONFIG_REG, SEL_CLK_POL_FLD, 1, 1)
202
+ FIELD(CONFIG_REG, ENB_SPI_FLD, 0, 1)
203
+REG32(DEV_INSTR_RD_CONFIG_REG, 0x4)
204
+ FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV5_FLD, 29, 3)
205
+ FIELD(DEV_INSTR_RD_CONFIG_REG, DUMMY_RD_CLK_CYCLES_FLD, 24, 5)
206
+ FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV4_FLD, 21, 3)
207
+ FIELD(DEV_INSTR_RD_CONFIG_REG, MODE_BIT_ENABLE_FLD, 20, 1)
208
+ FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV3_FLD, 18, 2)
209
+ FIELD(DEV_INSTR_RD_CONFIG_REG, DATA_XFER_TYPE_EXT_MODE_FLD, 16, 2)
210
+ FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV2_FLD, 14, 2)
211
+ FIELD(DEV_INSTR_RD_CONFIG_REG, ADDR_XFER_TYPE_STD_MODE_FLD, 12, 2)
212
+ FIELD(DEV_INSTR_RD_CONFIG_REG, PRED_DIS_FLD, 11, 1)
213
+ FIELD(DEV_INSTR_RD_CONFIG_REG, DDR_EN_FLD, 10, 1)
214
+ FIELD(DEV_INSTR_RD_CONFIG_REG, INSTR_TYPE_FLD, 8, 2)
215
+ FIELD(DEV_INSTR_RD_CONFIG_REG, RD_OPCODE_NON_XIP_FLD, 0, 8)
216
+REG32(DEV_INSTR_WR_CONFIG_REG, 0x8)
217
+ FIELD(DEV_INSTR_WR_CONFIG_REG, WR_INSTR_RESV4_FLD, 29, 3)
218
+ FIELD(DEV_INSTR_WR_CONFIG_REG, DUMMY_WR_CLK_CYCLES_FLD, 24, 5)
219
+ FIELD(DEV_INSTR_WR_CONFIG_REG, WR_INSTR_RESV3_FLD, 18, 6)
220
+ FIELD(DEV_INSTR_WR_CONFIG_REG, DATA_XFER_TYPE_EXT_MODE_FLD, 16, 2)
221
+ FIELD(DEV_INSTR_WR_CONFIG_REG, WR_INSTR_RESV2_FLD, 14, 2)
222
+ FIELD(DEV_INSTR_WR_CONFIG_REG, ADDR_XFER_TYPE_STD_MODE_FLD, 12, 2)
223
+ FIELD(DEV_INSTR_WR_CONFIG_REG, WR_INSTR_RESV1_FLD, 9, 3)
224
+ FIELD(DEV_INSTR_WR_CONFIG_REG, WEL_DIS_FLD, 8, 1)
225
+ FIELD(DEV_INSTR_WR_CONFIG_REG, WR_OPCODE_FLD, 0, 8)
226
+REG32(DEV_DELAY_REG, 0xc)
227
+ FIELD(DEV_DELAY_REG, D_NSS_FLD, 24, 8)
228
+ FIELD(DEV_DELAY_REG, D_BTWN_FLD, 16, 8)
229
+ FIELD(DEV_DELAY_REG, D_AFTER_FLD, 8, 8)
230
+ FIELD(DEV_DELAY_REG, D_INIT_FLD, 0, 8)
231
+REG32(RD_DATA_CAPTURE_REG, 0x10)
232
+ FIELD(RD_DATA_CAPTURE_REG, RD_DATA_RESV3_FLD, 20, 12)
233
+ FIELD(RD_DATA_CAPTURE_REG, DDR_READ_DELAY_FLD, 16, 4)
234
+ FIELD(RD_DATA_CAPTURE_REG, RD_DATA_RESV2_FLD, 9, 7)
235
+ FIELD(RD_DATA_CAPTURE_REG, DQS_ENABLE_FLD, 8, 1)
236
+ FIELD(RD_DATA_CAPTURE_REG, RD_DATA_RESV1_FLD, 6, 2)
237
+ FIELD(RD_DATA_CAPTURE_REG, SAMPLE_EDGE_SEL_FLD, 5, 1)
238
+ FIELD(RD_DATA_CAPTURE_REG, DELAY_FLD, 1, 4)
239
+ FIELD(RD_DATA_CAPTURE_REG, BYPASS_FLD, 0, 1)
240
+REG32(DEV_SIZE_CONFIG_REG, 0x14)
241
+ FIELD(DEV_SIZE_CONFIG_REG, DEV_SIZE_RESV_FLD, 29, 3)
242
+ FIELD(DEV_SIZE_CONFIG_REG, MEM_SIZE_ON_CS3_FLD, 27, 2)
243
+ FIELD(DEV_SIZE_CONFIG_REG, MEM_SIZE_ON_CS2_FLD, 25, 2)
244
+ FIELD(DEV_SIZE_CONFIG_REG, MEM_SIZE_ON_CS1_FLD, 23, 2)
245
+ FIELD(DEV_SIZE_CONFIG_REG, MEM_SIZE_ON_CS0_FLD, 21, 2)
246
+ FIELD(DEV_SIZE_CONFIG_REG, BYTES_PER_SUBSECTOR_FLD, 16, 5)
247
+ FIELD(DEV_SIZE_CONFIG_REG, BYTES_PER_DEVICE_PAGE_FLD, 4, 12)
248
+ FIELD(DEV_SIZE_CONFIG_REG, NUM_ADDR_BYTES_FLD, 0, 4)
249
+REG32(SRAM_PARTITION_CFG_REG, 0x18)
250
+ FIELD(SRAM_PARTITION_CFG_REG, SRAM_PARTITION_RESV_FLD, 8, 24)
251
+ FIELD(SRAM_PARTITION_CFG_REG, ADDR_FLD, 0, 8)
252
+REG32(IND_AHB_ADDR_TRIGGER_REG, 0x1c)
253
+REG32(DMA_PERIPH_CONFIG_REG, 0x20)
254
+ FIELD(DMA_PERIPH_CONFIG_REG, DMA_PERIPH_RESV2_FLD, 12, 20)
255
+ FIELD(DMA_PERIPH_CONFIG_REG, NUM_BURST_REQ_BYTES_FLD, 8, 4)
256
+ FIELD(DMA_PERIPH_CONFIG_REG, DMA_PERIPH_RESV1_FLD, 4, 4)
257
+ FIELD(DMA_PERIPH_CONFIG_REG, NUM_SINGLE_REQ_BYTES_FLD, 0, 4)
258
+REG32(REMAP_ADDR_REG, 0x24)
259
+REG32(MODE_BIT_CONFIG_REG, 0x28)
260
+ FIELD(MODE_BIT_CONFIG_REG, RX_CRC_DATA_LOW_FLD, 24, 8)
261
+ FIELD(MODE_BIT_CONFIG_REG, RX_CRC_DATA_UP_FLD, 16, 8)
262
+ FIELD(MODE_BIT_CONFIG_REG, CRC_OUT_ENABLE_FLD, 15, 1)
263
+ FIELD(MODE_BIT_CONFIG_REG, MODE_BIT_RESV1_FLD, 11, 4)
264
+ FIELD(MODE_BIT_CONFIG_REG, CHUNK_SIZE_FLD, 8, 3)
265
+ FIELD(MODE_BIT_CONFIG_REG, MODE_FLD, 0, 8)
266
+REG32(SRAM_FILL_REG, 0x2c)
267
+ FIELD(SRAM_FILL_REG, SRAM_FILL_INDAC_WRITE_FLD, 16, 16)
268
+ FIELD(SRAM_FILL_REG, SRAM_FILL_INDAC_READ_FLD, 0, 16)
269
+REG32(TX_THRESH_REG, 0x30)
270
+ FIELD(TX_THRESH_REG, TX_THRESH_RESV_FLD, 5, 27)
271
+ FIELD(TX_THRESH_REG, LEVEL_FLD, 0, 5)
272
+REG32(RX_THRESH_REG, 0x34)
273
+ FIELD(RX_THRESH_REG, RX_THRESH_RESV_FLD, 5, 27)
274
+ FIELD(RX_THRESH_REG, LEVEL_FLD, 0, 5)
275
+REG32(WRITE_COMPLETION_CTRL_REG, 0x38)
276
+ FIELD(WRITE_COMPLETION_CTRL_REG, POLL_REP_DELAY_FLD, 24, 8)
277
+ FIELD(WRITE_COMPLETION_CTRL_REG, POLL_COUNT_FLD, 16, 8)
278
+ FIELD(WRITE_COMPLETION_CTRL_REG, ENABLE_POLLING_EXP_FLD, 15, 1)
279
+ FIELD(WRITE_COMPLETION_CTRL_REG, DISABLE_POLLING_FLD, 14, 1)
280
+ FIELD(WRITE_COMPLETION_CTRL_REG, POLLING_POLARITY_FLD, 13, 1)
281
+ FIELD(WRITE_COMPLETION_CTRL_REG, WR_COMP_CTRL_RESV1_FLD, 12, 1)
282
+ FIELD(WRITE_COMPLETION_CTRL_REG, POLLING_ADDR_EN_FLD, 11, 1)
283
+ FIELD(WRITE_COMPLETION_CTRL_REG, POLLING_BIT_INDEX_FLD, 8, 3)
284
+ FIELD(WRITE_COMPLETION_CTRL_REG, OPCODE_FLD, 0, 8)
285
+REG32(NO_OF_POLLS_BEF_EXP_REG, 0x3c)
286
+REG32(IRQ_STATUS_REG, 0x40)
287
+ FIELD(IRQ_STATUS_REG, IRQ_STAT_RESV_FLD, 20, 12)
288
+ FIELD(IRQ_STATUS_REG, ECC_FAIL_FLD, 19, 1)
289
+ FIELD(IRQ_STATUS_REG, TX_CRC_CHUNK_BRK_FLD, 18, 1)
290
+ FIELD(IRQ_STATUS_REG, RX_CRC_DATA_VAL_FLD, 17, 1)
291
+ FIELD(IRQ_STATUS_REG, RX_CRC_DATA_ERR_FLD, 16, 1)
292
+ FIELD(IRQ_STATUS_REG, IRQ_STAT_RESV1_FLD, 15, 1)
293
+ FIELD(IRQ_STATUS_REG, STIG_REQ_INT_FLD, 14, 1)
294
+ FIELD(IRQ_STATUS_REG, POLL_EXP_INT_FLD, 13, 1)
295
+ FIELD(IRQ_STATUS_REG, INDRD_SRAM_FULL_FLD, 12, 1)
296
+ FIELD(IRQ_STATUS_REG, RX_FIFO_FULL_FLD, 11, 1)
297
+ FIELD(IRQ_STATUS_REG, RX_FIFO_NOT_EMPTY_FLD, 10, 1)
298
+ FIELD(IRQ_STATUS_REG, TX_FIFO_FULL_FLD, 9, 1)
299
+ FIELD(IRQ_STATUS_REG, TX_FIFO_NOT_FULL_FLD, 8, 1)
300
+ FIELD(IRQ_STATUS_REG, RECV_OVERFLOW_FLD, 7, 1)
301
+ FIELD(IRQ_STATUS_REG, INDIRECT_XFER_LEVEL_BREACH_FLD, 6, 1)
302
+ FIELD(IRQ_STATUS_REG, ILLEGAL_ACCESS_DET_FLD, 5, 1)
303
+ FIELD(IRQ_STATUS_REG, PROT_WR_ATTEMPT_FLD, 4, 1)
304
+ FIELD(IRQ_STATUS_REG, INDIRECT_TRANSFER_REJECT_FLD, 3, 1)
305
+ FIELD(IRQ_STATUS_REG, INDIRECT_OP_DONE_FLD, 2, 1)
306
+ FIELD(IRQ_STATUS_REG, UNDERFLOW_DET_FLD, 1, 1)
307
+ FIELD(IRQ_STATUS_REG, MODE_M_FAIL_FLD, 0, 1)
308
+REG32(IRQ_MASK_REG, 0x44)
309
+ FIELD(IRQ_MASK_REG, IRQ_MASK_RESV_FLD, 20, 12)
310
+ FIELD(IRQ_MASK_REG, ECC_FAIL_MASK_FLD, 19, 1)
311
+ FIELD(IRQ_MASK_REG, TX_CRC_CHUNK_BRK_MASK_FLD, 18, 1)
312
+ FIELD(IRQ_MASK_REG, RX_CRC_DATA_VAL_MASK_FLD, 17, 1)
313
+ FIELD(IRQ_MASK_REG, RX_CRC_DATA_ERR_MASK_FLD, 16, 1)
314
+ FIELD(IRQ_MASK_REG, IRQ_MASK_RESV1_FLD, 15, 1)
315
+ FIELD(IRQ_MASK_REG, STIG_REQ_MASK_FLD, 14, 1)
316
+ FIELD(IRQ_MASK_REG, POLL_EXP_INT_MASK_FLD, 13, 1)
317
+ FIELD(IRQ_MASK_REG, INDRD_SRAM_FULL_MASK_FLD, 12, 1)
318
+ FIELD(IRQ_MASK_REG, RX_FIFO_FULL_MASK_FLD, 11, 1)
319
+ FIELD(IRQ_MASK_REG, RX_FIFO_NOT_EMPTY_MASK_FLD, 10, 1)
320
+ FIELD(IRQ_MASK_REG, TX_FIFO_FULL_MASK_FLD, 9, 1)
321
+ FIELD(IRQ_MASK_REG, TX_FIFO_NOT_FULL_MASK_FLD, 8, 1)
322
+ FIELD(IRQ_MASK_REG, RECV_OVERFLOW_MASK_FLD, 7, 1)
323
+ FIELD(IRQ_MASK_REG, INDIRECT_XFER_LEVEL_BREACH_MASK_FLD, 6, 1)
324
+ FIELD(IRQ_MASK_REG, ILLEGAL_ACCESS_DET_MASK_FLD, 5, 1)
325
+ FIELD(IRQ_MASK_REG, PROT_WR_ATTEMPT_MASK_FLD, 4, 1)
326
+ FIELD(IRQ_MASK_REG, INDIRECT_TRANSFER_REJECT_MASK_FLD, 3, 1)
327
+ FIELD(IRQ_MASK_REG, INDIRECT_OP_DONE_MASK_FLD, 2, 1)
328
+ FIELD(IRQ_MASK_REG, UNDERFLOW_DET_MASK_FLD, 1, 1)
329
+ FIELD(IRQ_MASK_REG, MODE_M_FAIL_MASK_FLD, 0, 1)
330
+REG32(LOWER_WR_PROT_REG, 0x50)
331
+REG32(UPPER_WR_PROT_REG, 0x54)
332
+REG32(WR_PROT_CTRL_REG, 0x58)
333
+ FIELD(WR_PROT_CTRL_REG, WR_PROT_CTRL_RESV_FLD, 2, 30)
334
+ FIELD(WR_PROT_CTRL_REG, ENB_FLD, 1, 1)
335
+ FIELD(WR_PROT_CTRL_REG, INV_FLD, 0, 1)
336
+REG32(INDIRECT_READ_XFER_CTRL_REG, 0x60)
337
+ FIELD(INDIRECT_READ_XFER_CTRL_REG, INDIR_RD_XFER_RESV_FLD, 8, 24)
338
+ FIELD(INDIRECT_READ_XFER_CTRL_REG, NUM_IND_OPS_DONE_FLD, 6, 2)
339
+ FIELD(INDIRECT_READ_XFER_CTRL_REG, IND_OPS_DONE_STATUS_FLD, 5, 1)
340
+ FIELD(INDIRECT_READ_XFER_CTRL_REG, RD_QUEUED_FLD, 4, 1)
341
+ FIELD(INDIRECT_READ_XFER_CTRL_REG, SRAM_FULL_FLD, 3, 1)
342
+ FIELD(INDIRECT_READ_XFER_CTRL_REG, RD_STATUS_FLD, 2, 1)
343
+ FIELD(INDIRECT_READ_XFER_CTRL_REG, CANCEL_FLD, 1, 1)
344
+ FIELD(INDIRECT_READ_XFER_CTRL_REG, START_FLD, 0, 1)
345
+REG32(INDIRECT_READ_XFER_WATERMARK_REG, 0x64)
346
+REG32(INDIRECT_READ_XFER_START_REG, 0x68)
347
+REG32(INDIRECT_READ_XFER_NUM_BYTES_REG, 0x6c)
348
+REG32(INDIRECT_WRITE_XFER_CTRL_REG, 0x70)
349
+ FIELD(INDIRECT_WRITE_XFER_CTRL_REG, INDIR_WR_XFER_RESV2_FLD, 8, 24)
350
+ FIELD(INDIRECT_WRITE_XFER_CTRL_REG, NUM_IND_OPS_DONE_FLD, 6, 2)
351
+ FIELD(INDIRECT_WRITE_XFER_CTRL_REG, IND_OPS_DONE_STATUS_FLD, 5, 1)
352
+ FIELD(INDIRECT_WRITE_XFER_CTRL_REG, WR_QUEUED_FLD, 4, 1)
353
+ FIELD(INDIRECT_WRITE_XFER_CTRL_REG, INDIR_WR_XFER_RESV1_FLD, 3, 1)
354
+ FIELD(INDIRECT_WRITE_XFER_CTRL_REG, WR_STATUS_FLD, 2, 1)
355
+ FIELD(INDIRECT_WRITE_XFER_CTRL_REG, CANCEL_FLD, 1, 1)
356
+ FIELD(INDIRECT_WRITE_XFER_CTRL_REG, START_FLD, 0, 1)
357
+REG32(INDIRECT_WRITE_XFER_WATERMARK_REG, 0x74)
358
+REG32(INDIRECT_WRITE_XFER_START_REG, 0x78)
359
+REG32(INDIRECT_WRITE_XFER_NUM_BYTES_REG, 0x7c)
360
+REG32(INDIRECT_TRIGGER_ADDR_RANGE_REG, 0x80)
361
+ FIELD(INDIRECT_TRIGGER_ADDR_RANGE_REG, IND_RANGE_RESV1_FLD, 4, 28)
362
+ FIELD(INDIRECT_TRIGGER_ADDR_RANGE_REG, IND_RANGE_WIDTH_FLD, 0, 4)
363
+REG32(FLASH_COMMAND_CTRL_MEM_REG, 0x8c)
364
+ FIELD(FLASH_COMMAND_CTRL_MEM_REG, FLASH_COMMAND_CTRL_MEM_RESV1_FLD, 29, 3)
365
+ FIELD(FLASH_COMMAND_CTRL_MEM_REG, MEM_BANK_ADDR_FLD, 20, 9)
366
+ FIELD(FLASH_COMMAND_CTRL_MEM_REG, FLASH_COMMAND_CTRL_MEM_RESV2_FLD, 19, 1)
367
+ FIELD(FLASH_COMMAND_CTRL_MEM_REG, NB_OF_STIG_READ_BYTES_FLD, 16, 3)
368
+ FIELD(FLASH_COMMAND_CTRL_MEM_REG, MEM_BANK_READ_DATA_FLD, 8, 8)
369
+ FIELD(FLASH_COMMAND_CTRL_MEM_REG, FLASH_COMMAND_CTRL_MEM_RESV3_FLD, 2, 6)
370
+ FIELD(FLASH_COMMAND_CTRL_MEM_REG, MEM_BANK_REQ_IN_PROGRESS_FLD, 1, 1)
371
+ FIELD(FLASH_COMMAND_CTRL_MEM_REG, TRIGGER_MEM_BANK_REQ_FLD, 0, 1)
372
+REG32(FLASH_CMD_CTRL_REG, 0x90)
373
+ FIELD(FLASH_CMD_CTRL_REG, CMD_OPCODE_FLD, 24, 8)
374
+ FIELD(FLASH_CMD_CTRL_REG, ENB_READ_DATA_FLD, 23, 1)
375
+ FIELD(FLASH_CMD_CTRL_REG, NUM_RD_DATA_BYTES_FLD, 20, 3)
376
+ FIELD(FLASH_CMD_CTRL_REG, ENB_COMD_ADDR_FLD, 19, 1)
377
+ FIELD(FLASH_CMD_CTRL_REG, ENB_MODE_BIT_FLD, 18, 1)
378
+ FIELD(FLASH_CMD_CTRL_REG, NUM_ADDR_BYTES_FLD, 16, 2)
379
+ FIELD(FLASH_CMD_CTRL_REG, ENB_WRITE_DATA_FLD, 15, 1)
380
+ FIELD(FLASH_CMD_CTRL_REG, NUM_WR_DATA_BYTES_FLD, 12, 3)
381
+ FIELD(FLASH_CMD_CTRL_REG, NUM_DUMMY_CYCLES_FLD, 7, 5)
382
+ FIELD(FLASH_CMD_CTRL_REG, FLASH_CMD_CTRL_RESV1_FLD, 3, 4)
383
+ FIELD(FLASH_CMD_CTRL_REG, STIG_MEM_BANK_EN_FLD, 2, 1)
384
+ FIELD(FLASH_CMD_CTRL_REG, CMD_EXEC_STATUS_FLD, 1, 1)
385
+ FIELD(FLASH_CMD_CTRL_REG, CMD_EXEC_FLD, 0, 1)
386
+REG32(FLASH_CMD_ADDR_REG, 0x94)
387
+REG32(FLASH_RD_DATA_LOWER_REG, 0xa0)
388
+REG32(FLASH_RD_DATA_UPPER_REG, 0xa4)
389
+REG32(FLASH_WR_DATA_LOWER_REG, 0xa8)
390
+REG32(FLASH_WR_DATA_UPPER_REG, 0xac)
391
+REG32(POLLING_FLASH_STATUS_REG, 0xb0)
392
+ FIELD(POLLING_FLASH_STATUS_REG, DEVICE_STATUS_RSVD_FLD2, 21, 11)
393
+ FIELD(POLLING_FLASH_STATUS_REG, DEVICE_STATUS_NB_DUMMY, 16, 5)
394
+ FIELD(POLLING_FLASH_STATUS_REG, DEVICE_STATUS_RSVD_FLD1, 9, 7)
395
+ FIELD(POLLING_FLASH_STATUS_REG, DEVICE_STATUS_VALID_FLD, 8, 1)
396
+ FIELD(POLLING_FLASH_STATUS_REG, DEVICE_STATUS_FLD, 0, 8)
397
+REG32(PHY_CONFIGURATION_REG, 0xb4)
398
+ FIELD(PHY_CONFIGURATION_REG, PHY_CONFIG_RESYNC_FLD, 31, 1)
399
+ FIELD(PHY_CONFIGURATION_REG, PHY_CONFIG_RESET_FLD, 30, 1)
400
+ FIELD(PHY_CONFIGURATION_REG, PHY_CONFIG_RX_DLL_BYPASS_FLD, 29, 1)
401
+ FIELD(PHY_CONFIGURATION_REG, PHY_CONFIG_RESV2_FLD, 23, 6)
402
+ FIELD(PHY_CONFIGURATION_REG, PHY_CONFIG_TX_DLL_DELAY_FLD, 16, 7)
403
+ FIELD(PHY_CONFIGURATION_REG, PHY_CONFIG_RESV1_FLD, 7, 9)
404
+ FIELD(PHY_CONFIGURATION_REG, PHY_CONFIG_RX_DLL_DELAY_FLD, 0, 7)
405
+REG32(PHY_MASTER_CONTROL_REG, 0xb8)
406
+ FIELD(PHY_MASTER_CONTROL_REG, PHY_MASTER_CONTROL_RESV3_FLD, 25, 7)
407
+ FIELD(PHY_MASTER_CONTROL_REG, PHY_MASTER_LOCK_MODE_FLD, 24, 1)
408
+ FIELD(PHY_MASTER_CONTROL_REG, PHY_MASTER_BYPASS_MODE_FLD, 23, 1)
409
+ FIELD(PHY_MASTER_CONTROL_REG, PHY_MASTER_PHASE_DETECT_SELECTOR_FLD, 20, 3)
410
+ FIELD(PHY_MASTER_CONTROL_REG, PHY_MASTER_CONTROL_RESV2_FLD, 19, 1)
411
+ FIELD(PHY_MASTER_CONTROL_REG, PHY_MASTER_NB_INDICATIONS_FLD, 16, 3)
412
+ FIELD(PHY_MASTER_CONTROL_REG, PHY_MASTER_CONTROL_RESV1_FLD, 7, 9)
413
+ FIELD(PHY_MASTER_CONTROL_REG, PHY_MASTER_INITIAL_DELAY_FLD, 0, 7)
414
+REG32(DLL_OBSERVABLE_LOWER_REG, 0xbc)
415
+ FIELD(DLL_OBSERVABLE_LOWER_REG,
416
+ DLL_OBSERVABLE_LOWER_DLL_LOCK_INC_FLD, 24, 8)
417
+ FIELD(DLL_OBSERVABLE_LOWER_REG,
418
+ DLL_OBSERVABLE_LOWER_DLL_LOCK_DEC_FLD, 16, 8)
419
+ FIELD(DLL_OBSERVABLE_LOWER_REG,
420
+ DLL_OBSERVABLE_LOWER_LOOPBACK_LOCK_FLD, 15, 1)
421
+ FIELD(DLL_OBSERVABLE_LOWER_REG,
422
+ DLL_OBSERVABLE_LOWER_LOCK_VALUE_FLD, 8, 7)
423
+ FIELD(DLL_OBSERVABLE_LOWER_REG,
424
+ DLL_OBSERVABLE_LOWER_UNLOCK_COUNTER_FLD, 3, 5)
425
+ FIELD(DLL_OBSERVABLE_LOWER_REG,
426
+ DLL_OBSERVABLE_LOWER_LOCK_MODE_FLD, 1, 2)
427
+ FIELD(DLL_OBSERVABLE_LOWER_REG,
428
+ DLL_OBSERVABLE_LOWER_DLL_LOCK_FLD, 0, 1)
429
+REG32(DLL_OBSERVABLE_UPPER_REG, 0xc0)
430
+ FIELD(DLL_OBSERVABLE_UPPER_REG,
431
+ DLL_OBSERVABLE_UPPER_RESV2_FLD, 23, 9)
432
+ FIELD(DLL_OBSERVABLE_UPPER_REG,
433
+ DLL_OBSERVABLE_UPPER_TX_DECODER_OUTPUT_FLD, 16, 7)
434
+ FIELD(DLL_OBSERVABLE_UPPER_REG,
435
+ DLL_OBSERVABLE_UPPER_RESV1_FLD, 7, 9)
436
+ FIELD(DLL_OBSERVABLE_UPPER_REG,
437
+ DLL_OBSERVABLE__UPPER_RX_DECODER_OUTPUT_FLD, 0, 7)
438
+REG32(OPCODE_EXT_LOWER_REG, 0xe0)
439
+ FIELD(OPCODE_EXT_LOWER_REG, EXT_READ_OPCODE_FLD, 24, 8)
440
+ FIELD(OPCODE_EXT_LOWER_REG, EXT_WRITE_OPCODE_FLD, 16, 8)
441
+ FIELD(OPCODE_EXT_LOWER_REG, EXT_POLL_OPCODE_FLD, 8, 8)
442
+ FIELD(OPCODE_EXT_LOWER_REG, EXT_STIG_OPCODE_FLD, 0, 8)
443
+REG32(OPCODE_EXT_UPPER_REG, 0xe4)
444
+ FIELD(OPCODE_EXT_UPPER_REG, WEL_OPCODE_FLD, 24, 8)
445
+ FIELD(OPCODE_EXT_UPPER_REG, EXT_WEL_OPCODE_FLD, 16, 8)
446
+ FIELD(OPCODE_EXT_UPPER_REG, OPCODE_EXT_UPPER_RESV1_FLD, 0, 16)
447
+REG32(MODULE_ID_REG, 0xfc)
448
+ FIELD(MODULE_ID_REG, FIX_PATCH_FLD, 24, 8)
449
+ FIELD(MODULE_ID_REG, MODULE_ID_FLD, 8, 16)
450
+ FIELD(MODULE_ID_REG, MODULE_ID_RESV_FLD, 2, 6)
451
+ FIELD(MODULE_ID_REG, CONF_FLD, 0, 2)
452
+
453
+#define RXFF_SZ 1024
454
+#define TXFF_SZ 1024
455
+
456
+#define MAX_RX_DEC_OUT 8
457
+
458
+#define SZ_512MBIT (512 * 1024 * 1024)
459
+#define SZ_1GBIT (1024 * 1024 * 1024)
460
+#define SZ_2GBIT (2ULL * SZ_1GBIT)
461
+#define SZ_4GBIT (4ULL * SZ_1GBIT)
462
+
463
+#define IS_IND_DMA_START(op) (op->done_bytes == 0)
464
+/*
465
+ * Bit field size of R_INDIRECT_WRITE_XFER_CTRL_REG_NUM_IND_OPS_DONE_FLD
466
+ * is 2 bits, which can record max of 3 indac operations.
467
+ */
468
+#define IND_OPS_DONE_MAX 3
469
+
470
+typedef enum {
471
+ WREN = 0x6,
472
+} FlashCMD;
473
+
474
+static unsigned int ospi_stig_addr_len(XlnxVersalOspi *s)
475
+{
476
+ /* Num address bytes is NUM_ADDR_BYTES_FLD + 1 */
477
+ return ARRAY_FIELD_EX32(s->regs,
478
+ FLASH_CMD_CTRL_REG, NUM_ADDR_BYTES_FLD) + 1;
479
+}
480
+
481
+static unsigned int ospi_stig_wr_data_len(XlnxVersalOspi *s)
482
+{
483
+ /* Num write data bytes is NUM_WR_DATA_BYTES_FLD + 1 */
484
+ return ARRAY_FIELD_EX32(s->regs,
485
+ FLASH_CMD_CTRL_REG, NUM_WR_DATA_BYTES_FLD) + 1;
486
+}
487
+
488
+static unsigned int ospi_stig_rd_data_len(XlnxVersalOspi *s)
489
+{
490
+ /* Num read data bytes is NUM_RD_DATA_BYTES_FLD + 1 */
491
+ return ARRAY_FIELD_EX32(s->regs,
492
+ FLASH_CMD_CTRL_REG, NUM_RD_DATA_BYTES_FLD) + 1;
493
+}
494
+
495
+/*
496
+ * Status bits in R_IRQ_STATUS_REG are set when the event occurs and the
497
+ * interrupt is enabled in the mask register ([1] Section 2.3.17)
498
+ */
499
+static void set_irq(XlnxVersalOspi *s, uint32_t set_mask)
500
+{
501
+ s->regs[R_IRQ_STATUS_REG] |= s->regs[R_IRQ_MASK_REG] & set_mask;
502
+}
503
+
504
+static void ospi_update_irq_line(XlnxVersalOspi *s)
505
+{
506
+ qemu_set_irq(s->irq, !!(s->regs[R_IRQ_STATUS_REG] &
507
+ s->regs[R_IRQ_MASK_REG]));
508
+}
509
+
510
+static uint8_t ospi_get_wr_opcode(XlnxVersalOspi *s)
511
+{
512
+ return ARRAY_FIELD_EX32(s->regs,
513
+ DEV_INSTR_WR_CONFIG_REG, WR_OPCODE_FLD);
514
+}
515
+
516
+static uint8_t ospi_get_rd_opcode(XlnxVersalOspi *s)
517
+{
518
+ return ARRAY_FIELD_EX32(s->regs,
519
+ DEV_INSTR_RD_CONFIG_REG, RD_OPCODE_NON_XIP_FLD);
520
+}
521
+
522
+static uint32_t ospi_get_num_addr_bytes(XlnxVersalOspi *s)
523
+{
524
+ /* Num address bytes is NUM_ADDR_BYTES_FLD + 1 */
525
+ return ARRAY_FIELD_EX32(s->regs,
526
+ DEV_SIZE_CONFIG_REG, NUM_ADDR_BYTES_FLD) + 1;
527
+}
528
+
529
+static void ospi_stig_membank_req(XlnxVersalOspi *s)
530
+{
531
+ int idx = ARRAY_FIELD_EX32(s->regs,
532
+ FLASH_COMMAND_CTRL_MEM_REG, MEM_BANK_ADDR_FLD);
533
+
534
+ ARRAY_FIELD_DP32(s->regs, FLASH_COMMAND_CTRL_MEM_REG,
535
+ MEM_BANK_READ_DATA_FLD, s->stig_membank[idx]);
536
+}
537
+
538
+static int ospi_stig_membank_rd_bytes(XlnxVersalOspi *s)
539
+{
540
+ int rd_data_fld = ARRAY_FIELD_EX32(s->regs, FLASH_COMMAND_CTRL_MEM_REG,
541
+ NB_OF_STIG_READ_BYTES_FLD);
542
+ static const int sizes[6] = { 16, 32, 64, 128, 256, 512 };
543
+ return (rd_data_fld < 6) ? sizes[rd_data_fld] : 0;
544
+}
545
+
546
+static uint32_t ospi_get_page_sz(XlnxVersalOspi *s)
547
+{
548
+ return ARRAY_FIELD_EX32(s->regs,
549
+ DEV_SIZE_CONFIG_REG, BYTES_PER_DEVICE_PAGE_FLD);
550
+}
551
+
552
+static bool ospi_ind_rd_watermark_enabled(XlnxVersalOspi *s)
553
+{
554
+ return s->regs[R_INDIRECT_READ_XFER_WATERMARK_REG];
555
+}
556
+
557
+static void ind_op_advance(IndOp *op, unsigned int len)
558
+{
559
+ op->done_bytes += len;
560
+ assert(op->done_bytes <= op->num_bytes);
561
+ if (op->done_bytes == op->num_bytes) {
562
+ op->completed = true;
563
+ }
564
+}
565
+
566
+static uint32_t ind_op_next_byte(IndOp *op)
567
+{
568
+ return op->flash_addr + op->done_bytes;
569
+}
570
+
571
+static uint32_t ind_op_end_byte(IndOp *op)
572
+{
573
+ return op->flash_addr + op->num_bytes;
574
+}
575
+
576
+static void ospi_ind_op_next(IndOp *op)
577
+{
578
+ op[0] = op[1];
579
+ op[1].completed = true;
580
+}
581
+
582
+static void ind_op_setup(IndOp *op, uint32_t flash_addr, uint32_t num_bytes)
583
+{
584
+ if (num_bytes & 0x3) {
585
+ qemu_log_mask(LOG_GUEST_ERROR,
586
+ "OSPI indirect op num bytes not word aligned\n");
587
+ }
588
+ op->flash_addr = flash_addr;
589
+ op->num_bytes = num_bytes;
590
+ op->done_bytes = 0;
591
+ op->completed = false;
592
+}
593
+
594
+static bool ospi_ind_op_completed(IndOp *op)
595
+{
596
+ return op->completed;
597
+}
598
+
599
+static bool ospi_ind_op_all_completed(XlnxVersalOspi *s)
600
+{
601
+ return s->rd_ind_op[0].completed && s->wr_ind_op[0].completed;
602
+}
603
+
604
+static void ospi_ind_op_cancel(IndOp *op)
605
+{
606
+ op[0].completed = true;
607
+ op[1].completed = true;
608
+}
609
+
610
+static bool ospi_ind_op_add(IndOp *op, Fifo8 *fifo,
611
+ uint32_t flash_addr, uint32_t num_bytes)
612
+{
613
+ /* Check if first indirect op has been completed */
614
+ if (op->completed) {
615
+ fifo8_reset(fifo);
616
+ ind_op_setup(op, flash_addr, num_bytes);
617
+ return false;
618
+ }
619
+
620
+ /* Check if second indirect op has been completed */
621
+ op++;
622
+ if (op->completed) {
623
+ ind_op_setup(op, flash_addr, num_bytes);
624
+ return false;
625
+ }
626
+ return true;
627
+}
628
+
629
+static void ospi_ind_op_queue_up_rd(XlnxVersalOspi *s)
630
+{
631
+ uint32_t num_bytes = s->regs[R_INDIRECT_READ_XFER_NUM_BYTES_REG];
632
+ uint32_t flash_addr = s->regs[R_INDIRECT_READ_XFER_START_REG];
633
+ bool failed;
634
+
635
+ failed = ospi_ind_op_add(s->rd_ind_op, &s->rx_sram, flash_addr, num_bytes);
636
+ /* If two already queued set rd reject interrupt */
637
+ if (failed) {
638
+ set_irq(s, R_IRQ_STATUS_REG_INDIRECT_TRANSFER_REJECT_FLD_MASK);
639
+ }
640
+}
641
+
642
+static void ospi_ind_op_queue_up_wr(XlnxVersalOspi *s)
643
+{
644
+ uint32_t num_bytes = s->regs[R_INDIRECT_WRITE_XFER_NUM_BYTES_REG];
645
+ uint32_t flash_addr = s->regs[R_INDIRECT_WRITE_XFER_START_REG];
646
+ bool failed;
647
+
648
+ failed = ospi_ind_op_add(s->wr_ind_op, &s->tx_sram, flash_addr, num_bytes);
649
+ /* If two already queued set rd reject interrupt */
650
+ if (failed) {
651
+ set_irq(s, R_IRQ_STATUS_REG_INDIRECT_TRANSFER_REJECT_FLD_MASK);
652
+ }
653
+}
654
+
655
+static uint64_t flash_sz(XlnxVersalOspi *s, unsigned int cs)
656
+{
657
+ /* Flash sizes in MB */
658
+ static const uint64_t sizes[4] = { SZ_512MBIT / 8, SZ_1GBIT / 8,
659
+ SZ_2GBIT / 8, SZ_4GBIT / 8 };
660
+ uint32_t v = s->regs[R_DEV_SIZE_CONFIG_REG];
661
+
662
+ v >>= cs * R_DEV_SIZE_CONFIG_REG_MEM_SIZE_ON_CS0_FLD_LENGTH;
663
+ return sizes[FIELD_EX32(v, DEV_SIZE_CONFIG_REG, MEM_SIZE_ON_CS0_FLD)];
664
+}
665
+
666
+static unsigned int ospi_get_block_sz(XlnxVersalOspi *s)
667
+{
668
+ unsigned int block_fld = ARRAY_FIELD_EX32(s->regs,
669
+ DEV_SIZE_CONFIG_REG,
670
+ BYTES_PER_SUBSECTOR_FLD);
671
+ return 1 << block_fld;
672
+}
673
+
674
+static unsigned int flash_blocks(XlnxVersalOspi *s, unsigned int cs)
675
+{
676
+ unsigned int b_sz = ospi_get_block_sz(s);
677
+ unsigned int f_sz = flash_sz(s, cs);
678
+
679
+ return f_sz / b_sz;
680
+}
681
+
682
+static int ospi_ahb_decoder_cs(XlnxVersalOspi *s, hwaddr addr)
683
+{
684
+ uint64_t end_addr = 0;
685
+ int cs;
686
+
687
+ for (cs = 0; cs < s->num_cs; cs++) {
688
+ end_addr += flash_sz(s, cs);
689
+ if (addr < end_addr) {
690
+ break;
691
+ }
692
+ }
693
+
694
+ if (cs == s->num_cs) {
695
+ /* Address is out of range */
696
+ qemu_log_mask(LOG_GUEST_ERROR,
697
+ "OSPI flash address does not fit in configuration\n");
698
+ return -1;
699
+ }
700
+ return cs;
701
+}
702
+
703
+static void ospi_ahb_decoder_enable_cs(XlnxVersalOspi *s, hwaddr addr)
704
+{
705
+ int cs = ospi_ahb_decoder_cs(s, addr);
706
+
707
+ if (cs >= 0) {
708
+ for (int i = 0; i < s->num_cs; i++) {
709
+ qemu_set_irq(s->cs_lines[i], cs != i);
710
+ }
711
+ }
712
+}
713
+
714
+static unsigned int single_cs(XlnxVersalOspi *s)
715
+{
716
+ unsigned int field = ARRAY_FIELD_EX32(s->regs,
717
+ CONFIG_REG, PERIPH_CS_LINES_FLD);
718
+
71
+ /*
719
+ /*
72
+ * The PL031 device model code uses the tick_offset field, which is
720
+ * Below one liner is a trick that finds the rightmost zero and makes sure
73
+ * the offset between what the guest RTC should read and what the
721
+ * all other bits are turned to 1. It is a variant of the 'Isolate the
74
+ * QEMU rtc_clock reads:
722
+ * rightmost 0-bit' trick found below at the time of writing:
75
+ * guest_rtc = rtc_clock + tick_offset
76
+ * and so
77
+ * tick_offset = guest_rtc - rtc_clock
78
+ *
723
+ *
79
+ * We want to migrate this offset, which sounds straightforward.
724
+ * https://emre.me/computer-science/bit-manipulation-tricks/
80
+ * Unfortunately older versions of QEMU migrated a conversion of this
81
+ * offset into an offset from the vm_clock. (This was in turn an
82
+ * attempt to be compatible with even older QEMU versions, but it
83
+ * has incorrect behaviour if the rtc_clock is not the same as the
84
+ * vm_clock.) So we put the actual tick_offset into a migration
85
+ * subsection, and the backwards-compatible time-relative-to-vm_clock
86
+ * in the main migration state.
87
+ *
725
+ *
88
+ * Calculate base time relative to QEMU_CLOCK_VIRTUAL:
726
+ * 4'bXXX0 -> 4'b1110
727
+ * 4'bXX01 -> 4'b1101
728
+ * 4'bX011 -> 4'b1011
729
+ * 4'b0111 -> 4'b0111
730
+ * 4'b1111 -> 4'b1111
89
+ */
731
+ */
90
int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
732
+ return (field | ~(field + 1)) & 0xf;
91
s->tick_offset_vmstate = s->tick_offset + delta / NANOSECONDS_PER_SECOND;
733
+}
92
734
+
93
return 0;
735
+static void ospi_update_cs_lines(XlnxVersalOspi *s)
94
}
736
+{
95
737
+ unsigned int all_cs;
96
+static int pl031_pre_load(void *opaque)
738
+ int i;
97
+{
739
+
98
+ PL031State *s = opaque;
740
+ if (ARRAY_FIELD_EX32(s->regs, CONFIG_REG, PERIPH_SEL_DEC_FLD)) {
99
+
741
+ all_cs = ARRAY_FIELD_EX32(s->regs, CONFIG_REG, PERIPH_CS_LINES_FLD);
100
+ s->tick_offset_migrated = false;
742
+ } else {
743
+ all_cs = single_cs(s);
744
+ }
745
+
746
+ for (i = 0; i < s->num_cs; i++) {
747
+ bool cs = (all_cs >> i) & 1;
748
+
749
+ qemu_set_irq(s->cs_lines[i], cs);
750
+ }
751
+}
752
+
753
+static void ospi_dac_cs(XlnxVersalOspi *s, hwaddr addr)
754
+{
755
+ if (ARRAY_FIELD_EX32(s->regs, CONFIG_REG, ENABLE_AHB_DECODER_FLD)) {
756
+ ospi_ahb_decoder_enable_cs(s, addr);
757
+ } else {
758
+ ospi_update_cs_lines(s);
759
+ }
760
+}
761
+
762
+static void ospi_disable_cs(XlnxVersalOspi *s)
763
+{
764
+ int i;
765
+
766
+ for (i = 0; i < s->num_cs; i++) {
767
+ qemu_set_irq(s->cs_lines[i], 1);
768
+ }
769
+}
770
+
771
+static void ospi_flush_txfifo(XlnxVersalOspi *s)
772
+{
773
+ while (!fifo8_is_empty(&s->tx_fifo)) {
774
+ uint32_t tx_rx = fifo8_pop(&s->tx_fifo);
775
+
776
+ tx_rx = ssi_transfer(s->spi, tx_rx);
777
+ fifo8_push(&s->rx_fifo, tx_rx);
778
+ }
779
+}
780
+
781
+static void ospi_tx_fifo_push_address_raw(XlnxVersalOspi *s,
782
+ uint32_t flash_addr,
783
+ unsigned int addr_bytes)
784
+{
785
+ /* Push write address */
786
+ if (addr_bytes == 4) {
787
+ fifo8_push(&s->tx_fifo, flash_addr >> 24);
788
+ }
789
+ if (addr_bytes >= 3) {
790
+ fifo8_push(&s->tx_fifo, flash_addr >> 16);
791
+ }
792
+ if (addr_bytes >= 2) {
793
+ fifo8_push(&s->tx_fifo, flash_addr >> 8);
794
+ }
795
+ fifo8_push(&s->tx_fifo, flash_addr);
796
+}
797
+
798
+static void ospi_tx_fifo_push_address(XlnxVersalOspi *s, uint32_t flash_addr)
799
+{
800
+ /* Push write address */
801
+ int addr_bytes = ospi_get_num_addr_bytes(s);
802
+
803
+ ospi_tx_fifo_push_address_raw(s, flash_addr, addr_bytes);
804
+}
805
+
806
+static void ospi_tx_fifo_push_stig_addr(XlnxVersalOspi *s)
807
+{
808
+ uint32_t flash_addr = s->regs[R_FLASH_CMD_ADDR_REG];
809
+ unsigned int addr_bytes = ospi_stig_addr_len(s);
810
+
811
+ ospi_tx_fifo_push_address_raw(s, flash_addr, addr_bytes);
812
+}
813
+
814
+static void ospi_tx_fifo_push_rd_op_addr(XlnxVersalOspi *s, uint32_t flash_addr)
815
+{
816
+ uint8_t inst_code = ospi_get_rd_opcode(s);
817
+
818
+ fifo8_reset(&s->tx_fifo);
819
+
820
+ /* Push read opcode */
821
+ fifo8_push(&s->tx_fifo, inst_code);
822
+
823
+ /* Push read address */
824
+ ospi_tx_fifo_push_address(s, flash_addr);
825
+}
826
+
827
+static void ospi_tx_fifo_push_stig_wr_data(XlnxVersalOspi *s)
828
+{
829
+ uint64_t data = s->regs[R_FLASH_WR_DATA_LOWER_REG];
830
+ int wr_data_len = ospi_stig_wr_data_len(s);
831
+ int i;
832
+
833
+ data |= (uint64_t) s->regs[R_FLASH_WR_DATA_UPPER_REG] << 32;
834
+ for (i = 0; i < wr_data_len; i++) {
835
+ int shift = i * 8;
836
+ fifo8_push(&s->tx_fifo, data >> shift);
837
+ }
838
+}
839
+
840
+static void ospi_tx_fifo_push_stig_rd_data(XlnxVersalOspi *s)
841
+{
842
+ int rd_data_len;
843
+ int i;
844
+
845
+ if (ARRAY_FIELD_EX32(s->regs, FLASH_CMD_CTRL_REG, STIG_MEM_BANK_EN_FLD)) {
846
+ rd_data_len = ospi_stig_membank_rd_bytes(s);
847
+ } else {
848
+ rd_data_len = ospi_stig_rd_data_len(s);
849
+ }
850
+
851
+ /* transmit second part (data) */
852
+ for (i = 0; i < rd_data_len; ++i) {
853
+ fifo8_push(&s->tx_fifo, 0);
854
+ }
855
+}
856
+
857
+static void ospi_rx_fifo_pop_stig_rd_data(XlnxVersalOspi *s)
858
+{
859
+ int size = ospi_stig_rd_data_len(s);
860
+ uint8_t bytes[8] = {};
861
+ int i;
862
+
863
+ size = MIN(fifo8_num_used(&s->rx_fifo), size);
864
+
865
+ assert(size <= 8);
866
+
867
+ for (i = 0; i < size; i++) {
868
+ bytes[i] = fifo8_pop(&s->rx_fifo);
869
+ }
870
+
871
+ s->regs[R_FLASH_RD_DATA_LOWER_REG] = ldl_le_p(bytes);
872
+ s->regs[R_FLASH_RD_DATA_UPPER_REG] = ldl_le_p(bytes + 4);
873
+}
874
+
875
+static void ospi_ind_read(XlnxVersalOspi *s, uint32_t flash_addr, uint32_t len)
876
+{
877
+ int i;
878
+
879
+ /* Create first section of read cmd */
880
+ ospi_tx_fifo_push_rd_op_addr(s, flash_addr);
881
+
882
+ /* transmit first part */
883
+ ospi_update_cs_lines(s);
884
+ ospi_flush_txfifo(s);
885
+
886
+ fifo8_reset(&s->rx_fifo);
887
+
888
+ /* transmit second part (data) */
889
+ for (i = 0; i < len; ++i) {
890
+ fifo8_push(&s->tx_fifo, 0);
891
+ }
892
+ ospi_flush_txfifo(s);
893
+
894
+ for (i = 0; i < len; ++i) {
895
+ fifo8_push(&s->rx_sram, fifo8_pop(&s->rx_fifo));
896
+ }
897
+
898
+ /* done */
899
+ ospi_disable_cs(s);
900
+}
901
+
902
+static unsigned int ospi_dma_burst_size(XlnxVersalOspi *s)
903
+{
904
+ return 1 << ARRAY_FIELD_EX32(s->regs,
905
+ DMA_PERIPH_CONFIG_REG,
906
+ NUM_BURST_REQ_BYTES_FLD);
907
+}
908
+
909
+static unsigned int ospi_dma_single_size(XlnxVersalOspi *s)
910
+{
911
+ return 1 << ARRAY_FIELD_EX32(s->regs,
912
+ DMA_PERIPH_CONFIG_REG,
913
+ NUM_SINGLE_REQ_BYTES_FLD);
914
+}
915
+
916
+static void ind_rd_inc_num_done(XlnxVersalOspi *s)
917
+{
918
+ unsigned int done = ARRAY_FIELD_EX32(s->regs,
919
+ INDIRECT_READ_XFER_CTRL_REG,
920
+ NUM_IND_OPS_DONE_FLD);
921
+ if (done < IND_OPS_DONE_MAX) {
922
+ done++;
923
+ }
924
+ done &= 0x3;
925
+ ARRAY_FIELD_DP32(s->regs, INDIRECT_READ_XFER_CTRL_REG,
926
+ NUM_IND_OPS_DONE_FLD, done);
927
+}
928
+
929
+static void ospi_ind_rd_completed(XlnxVersalOspi *s)
930
+{
931
+ ARRAY_FIELD_DP32(s->regs, INDIRECT_READ_XFER_CTRL_REG,
932
+ IND_OPS_DONE_STATUS_FLD, 1);
933
+
934
+ ind_rd_inc_num_done(s);
935
+ ospi_ind_op_next(s->rd_ind_op);
936
+ if (ospi_ind_op_all_completed(s)) {
937
+ set_irq(s, R_IRQ_STATUS_REG_INDIRECT_OP_DONE_FLD_MASK);
938
+ }
939
+}
940
+
941
+static void ospi_dma_read(XlnxVersalOspi *s)
942
+{
943
+ IndOp *op = s->rd_ind_op;
944
+ uint32_t dma_len = op->num_bytes;
945
+ uint32_t burst_sz = ospi_dma_burst_size(s);
946
+ uint32_t single_sz = ospi_dma_single_size(s);
947
+ uint32_t ind_trig_range;
948
+ uint32_t remainder;
949
+ XlnxCSUDMAClass *xcdc = XLNX_CSU_DMA_GET_CLASS(s->dma_src);
950
+
951
+ ind_trig_range = (1 << ARRAY_FIELD_EX32(s->regs,
952
+ INDIRECT_TRIGGER_ADDR_RANGE_REG,
953
+ IND_RANGE_WIDTH_FLD));
954
+ remainder = dma_len % burst_sz;
955
+ remainder = remainder % single_sz;
956
+ if (burst_sz > ind_trig_range || single_sz > ind_trig_range ||
957
+ remainder != 0) {
958
+ qemu_log_mask(LOG_GUEST_ERROR,
959
+ "OSPI DMA burst size / single size config error\n");
960
+ }
961
+
962
+ s->src_dma_inprog = true;
963
+ if (xcdc->read(s->dma_src, 0, dma_len) != MEMTX_OK) {
964
+ qemu_log_mask(LOG_GUEST_ERROR, "OSPI DMA configuration error\n");
965
+ }
966
+ s->src_dma_inprog = false;
967
+}
968
+
969
+static void ospi_do_ind_read(XlnxVersalOspi *s)
970
+{
971
+ IndOp *op = s->rd_ind_op;
972
+ uint32_t next_b;
973
+ uint32_t end_b;
974
+ uint32_t len;
975
+ bool start_dma = IS_IND_DMA_START(op) && !s->src_dma_inprog;
976
+
977
+ /* Continue to read flash until we run out of space in sram */
978
+ while (!ospi_ind_op_completed(op) &&
979
+ !fifo8_is_full(&s->rx_sram)) {
980
+ /* Read reqested number of bytes, max bytes limited to size of sram */
981
+ next_b = ind_op_next_byte(op);
982
+ end_b = next_b + fifo8_num_free(&s->rx_sram);
983
+ end_b = MIN(end_b, ind_op_end_byte(op));
984
+
985
+ len = end_b - next_b;
986
+ ospi_ind_read(s, next_b, len);
987
+ ind_op_advance(op, len);
988
+
989
+ if (ospi_ind_rd_watermark_enabled(s)) {
990
+ ARRAY_FIELD_DP32(s->regs, IRQ_STATUS_REG,
991
+ INDIRECT_XFER_LEVEL_BREACH_FLD, 1);
992
+ set_irq(s,
993
+ R_IRQ_STATUS_REG_INDIRECT_XFER_LEVEL_BREACH_FLD_MASK);
994
+ }
995
+
996
+ if (!s->src_dma_inprog &&
997
+ ARRAY_FIELD_EX32(s->regs, CONFIG_REG, ENB_DMA_IF_FLD)) {
998
+ ospi_dma_read(s);
999
+ }
1000
+ }
1001
+
1002
+ /* Set sram full */
1003
+ if (fifo8_num_used(&s->rx_sram) == RXFF_SZ) {
1004
+ ARRAY_FIELD_DP32(s->regs,
1005
+ INDIRECT_READ_XFER_CTRL_REG, SRAM_FULL_FLD, 1);
1006
+ set_irq(s, R_IRQ_STATUS_REG_INDRD_SRAM_FULL_FLD_MASK);
1007
+ }
1008
+
1009
+ /* Signal completion if done, unless inside recursion via ospi_dma_read */
1010
+ if (!ARRAY_FIELD_EX32(s->regs, CONFIG_REG, ENB_DMA_IF_FLD) || start_dma) {
1011
+ if (ospi_ind_op_completed(op)) {
1012
+ ospi_ind_rd_completed(s);
1013
+ }
1014
+ }
1015
+}
1016
+
1017
+/* Transmit write enable instruction */
1018
+static void ospi_transmit_wel(XlnxVersalOspi *s, bool ahb_decoder_cs,
1019
+ hwaddr addr)
1020
+{
1021
+ fifo8_reset(&s->tx_fifo);
1022
+ fifo8_push(&s->tx_fifo, WREN);
1023
+
1024
+ if (ahb_decoder_cs) {
1025
+ ospi_ahb_decoder_enable_cs(s, addr);
1026
+ } else {
1027
+ ospi_update_cs_lines(s);
1028
+ }
1029
+
1030
+ ospi_flush_txfifo(s);
1031
+ ospi_disable_cs(s);
1032
+
1033
+ fifo8_reset(&s->rx_fifo);
1034
+}
1035
+
1036
+static void ospi_ind_write(XlnxVersalOspi *s, uint32_t flash_addr, uint32_t len)
1037
+{
1038
+ bool ahb_decoder_cs = false;
1039
+ uint8_t inst_code;
1040
+ int i;
1041
+
1042
+ assert(fifo8_num_used(&s->tx_sram) >= len);
1043
+
1044
+ if (!ARRAY_FIELD_EX32(s->regs, DEV_INSTR_WR_CONFIG_REG, WEL_DIS_FLD)) {
1045
+ ospi_transmit_wel(s, ahb_decoder_cs, 0);
1046
+ }
1047
+
1048
+ /* reset fifos */
1049
+ fifo8_reset(&s->tx_fifo);
1050
+ fifo8_reset(&s->rx_fifo);
1051
+
1052
+ /* Push write opcode */
1053
+ inst_code = ospi_get_wr_opcode(s);
1054
+ fifo8_push(&s->tx_fifo, inst_code);
1055
+
1056
+ /* Push write address */
1057
+ ospi_tx_fifo_push_address(s, flash_addr);
1058
+
1059
+ /* data */
1060
+ for (i = 0; i < len; i++) {
1061
+ fifo8_push(&s->tx_fifo, fifo8_pop(&s->tx_sram));
1062
+ }
1063
+
1064
+ /* transmit */
1065
+ ospi_update_cs_lines(s);
1066
+ ospi_flush_txfifo(s);
1067
+
1068
+ /* done */
1069
+ ospi_disable_cs(s);
1070
+ fifo8_reset(&s->rx_fifo);
1071
+}
1072
+
1073
+static void ind_wr_inc_num_done(XlnxVersalOspi *s)
1074
+{
1075
+ unsigned int done = ARRAY_FIELD_EX32(s->regs, INDIRECT_WRITE_XFER_CTRL_REG,
1076
+ NUM_IND_OPS_DONE_FLD);
1077
+ if (done < IND_OPS_DONE_MAX) {
1078
+ done++;
1079
+ }
1080
+ done &= 0x3;
1081
+ ARRAY_FIELD_DP32(s->regs, INDIRECT_WRITE_XFER_CTRL_REG,
1082
+ NUM_IND_OPS_DONE_FLD, done);
1083
+}
1084
+
1085
+static void ospi_ind_wr_completed(XlnxVersalOspi *s)
1086
+{
1087
+ ARRAY_FIELD_DP32(s->regs, INDIRECT_WRITE_XFER_CTRL_REG,
1088
+ IND_OPS_DONE_STATUS_FLD, 1);
1089
+ ind_wr_inc_num_done(s);
1090
+ ospi_ind_op_next(s->wr_ind_op);
1091
+ /* Set indirect op done interrupt if enabled */
1092
+ if (ospi_ind_op_all_completed(s)) {
1093
+ set_irq(s, R_IRQ_STATUS_REG_INDIRECT_OP_DONE_FLD_MASK);
1094
+ }
1095
+}
1096
+
1097
+static void ospi_do_indirect_write(XlnxVersalOspi *s)
1098
+{
1099
+ uint32_t write_watermark = s->regs[R_INDIRECT_WRITE_XFER_WATERMARK_REG];
1100
+ uint32_t pagesz = ospi_get_page_sz(s);
1101
+ uint32_t page_mask = ~(pagesz - 1);
1102
+ IndOp *op = s->wr_ind_op;
1103
+ uint32_t next_b;
1104
+ uint32_t end_b;
1105
+ uint32_t len;
1106
+
1107
+ /* Write out tx_fifo in maximum page sz chunks */
1108
+ while (!ospi_ind_op_completed(op) && fifo8_num_used(&s->tx_sram) > 0) {
1109
+ next_b = ind_op_next_byte(op);
1110
+ end_b = next_b + MIN(fifo8_num_used(&s->tx_sram), pagesz);
1111
+
1112
+ /* Dont cross page boundary */
1113
+ if ((end_b & page_mask) > next_b) {
1114
+ end_b &= page_mask;
1115
+ }
1116
+
1117
+ len = end_b - next_b;
1118
+ len = MIN(len, op->num_bytes - op->done_bytes);
1119
+ ospi_ind_write(s, next_b, len);
1120
+ ind_op_advance(op, len);
1121
+ }
1122
+
1123
+ /*
1124
+ * Always set indirect transfer level breached interrupt if enabled
1125
+ * (write watermark > 0) since the tx_sram always will be emptied
1126
+ */
1127
+ if (write_watermark > 0) {
1128
+ set_irq(s, R_IRQ_STATUS_REG_INDIRECT_XFER_LEVEL_BREACH_FLD_MASK);
1129
+ }
1130
+
1131
+ /* Signal completions if done */
1132
+ if (ospi_ind_op_completed(op)) {
1133
+ ospi_ind_wr_completed(s);
1134
+ }
1135
+}
1136
+
1137
+static void ospi_stig_fill_membank(XlnxVersalOspi *s)
1138
+{
1139
+ int num_rd_bytes = ospi_stig_membank_rd_bytes(s);
1140
+ int idx = num_rd_bytes - 8; /* first of last 8 */
1141
+ int i;
1142
+
1143
+ for (i = 0; i < num_rd_bytes; i++) {
1144
+ s->stig_membank[i] = fifo8_pop(&s->rx_fifo);
1145
+ }
1146
+
1147
+ g_assert((idx + 4) < ARRAY_SIZE(s->stig_membank));
1148
+
1149
+ /* Fill in lower upper regs */
1150
+ s->regs[R_FLASH_RD_DATA_LOWER_REG] = ldl_le_p(&s->stig_membank[idx]);
1151
+ s->regs[R_FLASH_RD_DATA_UPPER_REG] = ldl_le_p(&s->stig_membank[idx + 4]);
1152
+}
1153
+
1154
+static void ospi_stig_cmd_exec(XlnxVersalOspi *s)
1155
+{
1156
+ uint8_t inst_code;
1157
+
1158
+ /* Reset fifos */
1159
+ fifo8_reset(&s->tx_fifo);
1160
+ fifo8_reset(&s->rx_fifo);
1161
+
1162
+ /* Push write opcode */
1163
+ inst_code = ARRAY_FIELD_EX32(s->regs, FLASH_CMD_CTRL_REG, CMD_OPCODE_FLD);
1164
+ fifo8_push(&s->tx_fifo, inst_code);
1165
+
1166
+ /* Push address if enabled */
1167
+ if (ARRAY_FIELD_EX32(s->regs, FLASH_CMD_CTRL_REG, ENB_COMD_ADDR_FLD)) {
1168
+ ospi_tx_fifo_push_stig_addr(s);
1169
+ }
1170
+
1171
+ /* Enable cs */
1172
+ ospi_update_cs_lines(s);
1173
+
1174
+ /* Data */
1175
+ if (ARRAY_FIELD_EX32(s->regs, FLASH_CMD_CTRL_REG, ENB_WRITE_DATA_FLD)) {
1176
+ ospi_tx_fifo_push_stig_wr_data(s);
1177
+ } else if (ARRAY_FIELD_EX32(s->regs,
1178
+ FLASH_CMD_CTRL_REG, ENB_READ_DATA_FLD)) {
1179
+ /* transmit first part */
1180
+ ospi_flush_txfifo(s);
1181
+ fifo8_reset(&s->rx_fifo);
1182
+ ospi_tx_fifo_push_stig_rd_data(s);
1183
+ }
1184
+
1185
+ /* Transmit */
1186
+ ospi_flush_txfifo(s);
1187
+ ospi_disable_cs(s);
1188
+
1189
+ if (ARRAY_FIELD_EX32(s->regs, FLASH_CMD_CTRL_REG, ENB_READ_DATA_FLD)) {
1190
+ if (ARRAY_FIELD_EX32(s->regs,
1191
+ FLASH_CMD_CTRL_REG, STIG_MEM_BANK_EN_FLD)) {
1192
+ ospi_stig_fill_membank(s);
1193
+ } else {
1194
+ ospi_rx_fifo_pop_stig_rd_data(s);
1195
+ }
1196
+ }
1197
+}
1198
+
1199
+static uint32_t ospi_block_address(XlnxVersalOspi *s, unsigned int block)
1200
+{
1201
+ unsigned int block_sz = ospi_get_block_sz(s);
1202
+ unsigned int cs = 0;
1203
+ uint32_t addr = 0;
1204
+
1205
+ while (cs < s->num_cs && block >= flash_blocks(s, cs)) {
1206
+ block -= flash_blocks(s, 0);
1207
+ addr += flash_sz(s, cs);
1208
+ }
1209
+ addr += block * block_sz;
1210
+ return addr;
1211
+}
1212
+
1213
+static uint32_t ospi_get_wr_prot_addr_low(XlnxVersalOspi *s)
1214
+{
1215
+ unsigned int block = s->regs[R_LOWER_WR_PROT_REG];
1216
+
1217
+ return ospi_block_address(s, block);
1218
+}
1219
+
1220
+static uint32_t ospi_get_wr_prot_addr_upper(XlnxVersalOspi *s)
1221
+{
1222
+ unsigned int block = s->regs[R_UPPER_WR_PROT_REG];
1223
+
1224
+ /* Get address of first block out of defined range */
1225
+ return ospi_block_address(s, block + 1);
1226
+}
1227
+
1228
+static bool ospi_is_write_protected(XlnxVersalOspi *s, hwaddr addr)
1229
+{
1230
+ uint32_t wr_prot_addr_upper = ospi_get_wr_prot_addr_upper(s);
1231
+ uint32_t wr_prot_addr_low = ospi_get_wr_prot_addr_low(s);
1232
+ bool in_range = false;
1233
+
1234
+ if (addr >= wr_prot_addr_low && addr < wr_prot_addr_upper) {
1235
+ in_range = true;
1236
+ }
1237
+
1238
+ if (ARRAY_FIELD_EX32(s->regs, WR_PROT_CTRL_REG, INV_FLD)) {
1239
+ in_range = !in_range;
1240
+ }
1241
+ return in_range;
1242
+}
1243
+
1244
+static uint64_t ospi_rx_sram_read(XlnxVersalOspi *s, unsigned int size)
1245
+{
1246
+ uint8_t bytes[8] = {};
1247
+ int i;
1248
+
1249
+ if (size < 4 && fifo8_num_used(&s->rx_sram) >= 4) {
1250
+ qemu_log_mask(LOG_GUEST_ERROR,
1251
+ "OSPI only last read of internal "
1252
+ "sram is allowed to be < 32 bits\n");
1253
+ }
1254
+
1255
+ size = MIN(fifo8_num_used(&s->rx_sram), size);
1256
+
1257
+ assert(size <= 8);
1258
+
1259
+ for (i = 0; i < size; i++) {
1260
+ bytes[i] = fifo8_pop(&s->rx_sram);
1261
+ }
1262
+
1263
+ return ldq_le_p(bytes);
1264
+}
1265
+
1266
+static void ospi_tx_sram_write(XlnxVersalOspi *s, uint64_t value,
1267
+ unsigned int size)
1268
+{
1269
+ int i;
1270
+ for (i = 0; i < size && !fifo8_is_full(&s->tx_sram); i++) {
1271
+ fifo8_push(&s->tx_sram, value >> 8 * i);
1272
+ }
1273
+}
1274
+
1275
+static uint64_t ospi_do_dac_read(void *opaque, hwaddr addr, unsigned int size)
1276
+{
1277
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(opaque);
1278
+ uint8_t bytes[8] = {};
1279
+ int i;
1280
+
1281
+ /* Create first section of read cmd */
1282
+ ospi_tx_fifo_push_rd_op_addr(s, (uint32_t) addr);
1283
+
1284
+ /* Enable cs and transmit first part */
1285
+ ospi_dac_cs(s, addr);
1286
+ ospi_flush_txfifo(s);
1287
+
1288
+ fifo8_reset(&s->rx_fifo);
1289
+
1290
+ /* transmit second part (data) */
1291
+ for (i = 0; i < size; ++i) {
1292
+ fifo8_push(&s->tx_fifo, 0);
1293
+ }
1294
+ ospi_flush_txfifo(s);
1295
+
1296
+ /* fill in result */
1297
+ size = MIN(fifo8_num_used(&s->rx_fifo), size);
1298
+
1299
+ assert(size <= 8);
1300
+
1301
+ for (i = 0; i < size; i++) {
1302
+ bytes[i] = fifo8_pop(&s->rx_fifo);
1303
+ }
1304
+
1305
+ /* done */
1306
+ ospi_disable_cs(s);
1307
+
1308
+ return ldq_le_p(bytes);
1309
+}
1310
+
1311
+static void ospi_do_dac_write(void *opaque,
1312
+ hwaddr addr,
1313
+ uint64_t value,
1314
+ unsigned int size)
1315
+{
1316
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(opaque);
1317
+ bool ahb_decoder_cs = ARRAY_FIELD_EX32(s->regs, CONFIG_REG,
1318
+ ENABLE_AHB_DECODER_FLD);
1319
+ uint8_t inst_code;
1320
+ unsigned int i;
1321
+
1322
+ if (!ARRAY_FIELD_EX32(s->regs, DEV_INSTR_WR_CONFIG_REG, WEL_DIS_FLD)) {
1323
+ ospi_transmit_wel(s, ahb_decoder_cs, addr);
1324
+ }
1325
+
1326
+ /* reset fifos */
1327
+ fifo8_reset(&s->tx_fifo);
1328
+ fifo8_reset(&s->rx_fifo);
1329
+
1330
+ /* Push write opcode */
1331
+ inst_code = ospi_get_wr_opcode(s);
1332
+ fifo8_push(&s->tx_fifo, inst_code);
1333
+
1334
+ /* Push write address */
1335
+ ospi_tx_fifo_push_address(s, addr);
1336
+
1337
+ /* data */
1338
+ for (i = 0; i < size; i++) {
1339
+ fifo8_push(&s->tx_fifo, value >> 8 * i);
1340
+ }
1341
+
1342
+ /* Enable cs and transmit */
1343
+ ospi_dac_cs(s, addr);
1344
+ ospi_flush_txfifo(s);
1345
+ ospi_disable_cs(s);
1346
+
1347
+ fifo8_reset(&s->rx_fifo);
1348
+}
1349
+
1350
+static void flash_cmd_ctrl_mem_reg_post_write(RegisterInfo *reg,
1351
+ uint64_t val)
1352
+{
1353
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(reg->opaque);
1354
+ if (ARRAY_FIELD_EX32(s->regs, CONFIG_REG, ENB_SPI_FLD)) {
1355
+ if (ARRAY_FIELD_EX32(s->regs,
1356
+ FLASH_COMMAND_CTRL_MEM_REG,
1357
+ TRIGGER_MEM_BANK_REQ_FLD)) {
1358
+ ospi_stig_membank_req(s);
1359
+ ARRAY_FIELD_DP32(s->regs, FLASH_COMMAND_CTRL_MEM_REG,
1360
+ TRIGGER_MEM_BANK_REQ_FLD, 0);
1361
+ }
1362
+ }
1363
+}
1364
+
1365
+static void flash_cmd_ctrl_reg_post_write(RegisterInfo *reg, uint64_t val)
1366
+{
1367
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(reg->opaque);
1368
+
1369
+ if (ARRAY_FIELD_EX32(s->regs, CONFIG_REG, ENB_SPI_FLD) &&
1370
+ ARRAY_FIELD_EX32(s->regs, FLASH_CMD_CTRL_REG, CMD_EXEC_FLD)) {
1371
+ ospi_stig_cmd_exec(s);
1372
+ set_irq(s, R_IRQ_STATUS_REG_STIG_REQ_INT_FLD_MASK);
1373
+ ARRAY_FIELD_DP32(s->regs, FLASH_CMD_CTRL_REG, CMD_EXEC_FLD, 0);
1374
+ }
1375
+}
1376
+
1377
+static uint64_t ind_wr_dec_num_done(XlnxVersalOspi *s, uint64_t val)
1378
+{
1379
+ unsigned int done = ARRAY_FIELD_EX32(s->regs, INDIRECT_WRITE_XFER_CTRL_REG,
1380
+ NUM_IND_OPS_DONE_FLD);
1381
+ done--;
1382
+ done &= 0x3;
1383
+ val = FIELD_DP32(val, INDIRECT_WRITE_XFER_CTRL_REG,
1384
+ NUM_IND_OPS_DONE_FLD, done);
1385
+ return val;
1386
+}
1387
+
1388
+static bool ind_wr_clearing_op_done(XlnxVersalOspi *s, uint64_t new_val)
1389
+{
1390
+ bool set_in_reg = ARRAY_FIELD_EX32(s->regs, INDIRECT_WRITE_XFER_CTRL_REG,
1391
+ IND_OPS_DONE_STATUS_FLD);
1392
+ bool set_in_new_val = FIELD_EX32(new_val, INDIRECT_WRITE_XFER_CTRL_REG,
1393
+ IND_OPS_DONE_STATUS_FLD);
1394
+ /* return true if clearing bit */
1395
+ return set_in_reg && !set_in_new_val;
1396
+}
1397
+
1398
+static uint64_t ind_wr_xfer_ctrl_reg_pre_write(RegisterInfo *reg,
1399
+ uint64_t val)
1400
+{
1401
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(reg->opaque);
1402
+
1403
+ if (ind_wr_clearing_op_done(s, val)) {
1404
+ val = ind_wr_dec_num_done(s, val);
1405
+ }
1406
+ return val;
1407
+}
1408
+
1409
+static void ind_wr_xfer_ctrl_reg_post_write(RegisterInfo *reg, uint64_t val)
1410
+{
1411
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(reg->opaque);
1412
+
1413
+ if (s->ind_write_disabled) {
1414
+ return;
1415
+ }
1416
+
1417
+ if (ARRAY_FIELD_EX32(s->regs, INDIRECT_WRITE_XFER_CTRL_REG, START_FLD)) {
1418
+ ospi_ind_op_queue_up_wr(s);
1419
+ ospi_do_indirect_write(s);
1420
+ ARRAY_FIELD_DP32(s->regs, INDIRECT_WRITE_XFER_CTRL_REG, START_FLD, 0);
1421
+ }
1422
+
1423
+ if (ARRAY_FIELD_EX32(s->regs, INDIRECT_WRITE_XFER_CTRL_REG, CANCEL_FLD)) {
1424
+ ospi_ind_op_cancel(s->wr_ind_op);
1425
+ fifo8_reset(&s->tx_sram);
1426
+ ARRAY_FIELD_DP32(s->regs, INDIRECT_WRITE_XFER_CTRL_REG, CANCEL_FLD, 0);
1427
+ }
1428
+}
1429
+
1430
+static uint64_t ind_wr_xfer_ctrl_reg_post_read(RegisterInfo *reg,
1431
+ uint64_t val)
1432
+{
1433
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(reg->opaque);
1434
+ IndOp *op = s->wr_ind_op;
1435
+
1436
+ /* Check if ind ops is ongoing */
1437
+ if (!ospi_ind_op_completed(&op[0])) {
1438
+ /* Check if two ind ops are queued */
1439
+ if (!ospi_ind_op_completed(&op[1])) {
1440
+ val = FIELD_DP32(val, INDIRECT_WRITE_XFER_CTRL_REG,
1441
+ WR_QUEUED_FLD, 1);
1442
+ }
1443
+ val = FIELD_DP32(val, INDIRECT_WRITE_XFER_CTRL_REG, WR_STATUS_FLD, 1);
1444
+ }
1445
+ return val;
1446
+}
1447
+
1448
+static uint64_t ind_rd_dec_num_done(XlnxVersalOspi *s, uint64_t val)
1449
+{
1450
+ unsigned int done = ARRAY_FIELD_EX32(s->regs, INDIRECT_READ_XFER_CTRL_REG,
1451
+ NUM_IND_OPS_DONE_FLD);
1452
+ done--;
1453
+ done &= 0x3;
1454
+ val = FIELD_DP32(val, INDIRECT_READ_XFER_CTRL_REG,
1455
+ NUM_IND_OPS_DONE_FLD, done);
1456
+ return val;
1457
+}
1458
+
1459
+static uint64_t ind_rd_xfer_ctrl_reg_pre_write(RegisterInfo *reg,
1460
+ uint64_t val)
1461
+{
1462
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(reg->opaque);
1463
+
1464
+ if (FIELD_EX32(val, INDIRECT_READ_XFER_CTRL_REG,
1465
+ IND_OPS_DONE_STATUS_FLD)) {
1466
+ val = ind_rd_dec_num_done(s, val);
1467
+ val &= ~R_INDIRECT_READ_XFER_CTRL_REG_IND_OPS_DONE_STATUS_FLD_MASK;
1468
+ }
1469
+ return val;
1470
+}
1471
+
1472
+static void ind_rd_xfer_ctrl_reg_post_write(RegisterInfo *reg, uint64_t val)
1473
+{
1474
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(reg->opaque);
1475
+
1476
+ if (ARRAY_FIELD_EX32(s->regs, INDIRECT_READ_XFER_CTRL_REG, START_FLD)) {
1477
+ ospi_ind_op_queue_up_rd(s);
1478
+ ospi_do_ind_read(s);
1479
+ ARRAY_FIELD_DP32(s->regs, INDIRECT_READ_XFER_CTRL_REG, START_FLD, 0);
1480
+ }
1481
+
1482
+ if (ARRAY_FIELD_EX32(s->regs, INDIRECT_READ_XFER_CTRL_REG, CANCEL_FLD)) {
1483
+ ospi_ind_op_cancel(s->rd_ind_op);
1484
+ fifo8_reset(&s->rx_sram);
1485
+ ARRAY_FIELD_DP32(s->regs, INDIRECT_READ_XFER_CTRL_REG, CANCEL_FLD, 0);
1486
+ }
1487
+}
1488
+
1489
+static uint64_t ind_rd_xfer_ctrl_reg_post_read(RegisterInfo *reg,
1490
+ uint64_t val)
1491
+{
1492
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(reg->opaque);
1493
+ IndOp *op = s->rd_ind_op;
1494
+
1495
+ /* Check if ind ops is ongoing */
1496
+ if (!ospi_ind_op_completed(&op[0])) {
1497
+ /* Check if two ind ops are queued */
1498
+ if (!ospi_ind_op_completed(&op[1])) {
1499
+ val = FIELD_DP32(val, INDIRECT_READ_XFER_CTRL_REG,
1500
+ RD_QUEUED_FLD, 1);
1501
+ }
1502
+ val = FIELD_DP32(val, INDIRECT_READ_XFER_CTRL_REG, RD_STATUS_FLD, 1);
1503
+ }
1504
+ return val;
1505
+}
1506
+
1507
+static uint64_t sram_fill_reg_post_read(RegisterInfo *reg, uint64_t val)
1508
+{
1509
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(reg->opaque);
1510
+ val = ((fifo8_num_used(&s->tx_sram) & 0xFFFF) << 16) |
1511
+ (fifo8_num_used(&s->rx_sram) & 0xFFFF);
1512
+ return val;
1513
+}
1514
+
1515
+static uint64_t dll_obs_upper_reg_post_read(RegisterInfo *reg, uint64_t val)
1516
+{
1517
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(reg->opaque);
1518
+ uint32_t rx_dec_out;
1519
+
1520
+ rx_dec_out = FIELD_EX32(val, DLL_OBSERVABLE_UPPER_REG,
1521
+ DLL_OBSERVABLE__UPPER_RX_DECODER_OUTPUT_FLD);
1522
+
1523
+ if (rx_dec_out < MAX_RX_DEC_OUT) {
1524
+ ARRAY_FIELD_DP32(s->regs, DLL_OBSERVABLE_UPPER_REG,
1525
+ DLL_OBSERVABLE__UPPER_RX_DECODER_OUTPUT_FLD,
1526
+ rx_dec_out + 1);
1527
+ }
1528
+
1529
+ return val;
1530
+}
1531
+
1532
+
1533
+static void xlnx_versal_ospi_reset(DeviceState *dev)
1534
+{
1535
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(dev);
1536
+ unsigned int i;
1537
+
1538
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
1539
+ register_reset(&s->regs_info[i]);
1540
+ }
1541
+
1542
+ fifo8_reset(&s->rx_fifo);
1543
+ fifo8_reset(&s->tx_fifo);
1544
+ fifo8_reset(&s->rx_sram);
1545
+ fifo8_reset(&s->tx_sram);
1546
+
1547
+ s->rd_ind_op[0].completed = true;
1548
+ s->rd_ind_op[1].completed = true;
1549
+ s->wr_ind_op[0].completed = true;
1550
+ s->wr_ind_op[1].completed = true;
1551
+ ARRAY_FIELD_DP32(s->regs, DLL_OBSERVABLE_LOWER_REG,
1552
+ DLL_OBSERVABLE_LOWER_DLL_LOCK_FLD, 1);
1553
+ ARRAY_FIELD_DP32(s->regs, DLL_OBSERVABLE_LOWER_REG,
1554
+ DLL_OBSERVABLE_LOWER_LOOPBACK_LOCK_FLD, 1);
1555
+}
1556
+
1557
+static RegisterAccessInfo ospi_regs_info[] = {
1558
+ { .name = "CONFIG_REG",
1559
+ .addr = A_CONFIG_REG,
1560
+ .reset = 0x80780081,
1561
+ .ro = 0x9c000000,
1562
+ },{ .name = "DEV_INSTR_RD_CONFIG_REG",
1563
+ .addr = A_DEV_INSTR_RD_CONFIG_REG,
1564
+ .reset = 0x3,
1565
+ .ro = 0xe0ecc800,
1566
+ },{ .name = "DEV_INSTR_WR_CONFIG_REG",
1567
+ .addr = A_DEV_INSTR_WR_CONFIG_REG,
1568
+ .reset = 0x2,
1569
+ .ro = 0xe0fcce00,
1570
+ },{ .name = "DEV_DELAY_REG",
1571
+ .addr = A_DEV_DELAY_REG,
1572
+ },{ .name = "RD_DATA_CAPTURE_REG",
1573
+ .addr = A_RD_DATA_CAPTURE_REG,
1574
+ .reset = 0x1,
1575
+ .ro = 0xfff0fec0,
1576
+ },{ .name = "DEV_SIZE_CONFIG_REG",
1577
+ .addr = A_DEV_SIZE_CONFIG_REG,
1578
+ .reset = 0x101002,
1579
+ .ro = 0xe0000000,
1580
+ },{ .name = "SRAM_PARTITION_CFG_REG",
1581
+ .addr = A_SRAM_PARTITION_CFG_REG,
1582
+ .reset = 0x80,
1583
+ .ro = 0xffffff00,
1584
+ },{ .name = "IND_AHB_ADDR_TRIGGER_REG",
1585
+ .addr = A_IND_AHB_ADDR_TRIGGER_REG,
1586
+ },{ .name = "DMA_PERIPH_CONFIG_REG",
1587
+ .addr = A_DMA_PERIPH_CONFIG_REG,
1588
+ .ro = 0xfffff0f0,
1589
+ },{ .name = "REMAP_ADDR_REG",
1590
+ .addr = A_REMAP_ADDR_REG,
1591
+ },{ .name = "MODE_BIT_CONFIG_REG",
1592
+ .addr = A_MODE_BIT_CONFIG_REG,
1593
+ .reset = 0x200,
1594
+ .ro = 0xffff7800,
1595
+ },{ .name = "SRAM_FILL_REG",
1596
+ .addr = A_SRAM_FILL_REG,
1597
+ .ro = 0xffffffff,
1598
+ .post_read = sram_fill_reg_post_read,
1599
+ },{ .name = "TX_THRESH_REG",
1600
+ .addr = A_TX_THRESH_REG,
1601
+ .reset = 0x1,
1602
+ .ro = 0xffffffe0,
1603
+ },{ .name = "RX_THRESH_REG",
1604
+ .addr = A_RX_THRESH_REG,
1605
+ .reset = 0x1,
1606
+ .ro = 0xffffffe0,
1607
+ },{ .name = "WRITE_COMPLETION_CTRL_REG",
1608
+ .addr = A_WRITE_COMPLETION_CTRL_REG,
1609
+ .reset = 0x10005,
1610
+ .ro = 0x1800,
1611
+ },{ .name = "NO_OF_POLLS_BEF_EXP_REG",
1612
+ .addr = A_NO_OF_POLLS_BEF_EXP_REG,
1613
+ .reset = 0xffffffff,
1614
+ },{ .name = "IRQ_STATUS_REG",
1615
+ .addr = A_IRQ_STATUS_REG,
1616
+ .ro = 0xfff08000,
1617
+ .w1c = 0xf7fff,
1618
+ },{ .name = "IRQ_MASK_REG",
1619
+ .addr = A_IRQ_MASK_REG,
1620
+ .ro = 0xfff08000,
1621
+ },{ .name = "LOWER_WR_PROT_REG",
1622
+ .addr = A_LOWER_WR_PROT_REG,
1623
+ },{ .name = "UPPER_WR_PROT_REG",
1624
+ .addr = A_UPPER_WR_PROT_REG,
1625
+ },{ .name = "WR_PROT_CTRL_REG",
1626
+ .addr = A_WR_PROT_CTRL_REG,
1627
+ .ro = 0xfffffffc,
1628
+ },{ .name = "INDIRECT_READ_XFER_CTRL_REG",
1629
+ .addr = A_INDIRECT_READ_XFER_CTRL_REG,
1630
+ .ro = 0xffffffd4,
1631
+ .w1c = 0x08,
1632
+ .pre_write = ind_rd_xfer_ctrl_reg_pre_write,
1633
+ .post_write = ind_rd_xfer_ctrl_reg_post_write,
1634
+ .post_read = ind_rd_xfer_ctrl_reg_post_read,
1635
+ },{ .name = "INDIRECT_READ_XFER_WATERMARK_REG",
1636
+ .addr = A_INDIRECT_READ_XFER_WATERMARK_REG,
1637
+ },{ .name = "INDIRECT_READ_XFER_START_REG",
1638
+ .addr = A_INDIRECT_READ_XFER_START_REG,
1639
+ },{ .name = "INDIRECT_READ_XFER_NUM_BYTES_REG",
1640
+ .addr = A_INDIRECT_READ_XFER_NUM_BYTES_REG,
1641
+ },{ .name = "INDIRECT_WRITE_XFER_CTRL_REG",
1642
+ .addr = A_INDIRECT_WRITE_XFER_CTRL_REG,
1643
+ .ro = 0xffffffdc,
1644
+ .w1c = 0x20,
1645
+ .pre_write = ind_wr_xfer_ctrl_reg_pre_write,
1646
+ .post_write = ind_wr_xfer_ctrl_reg_post_write,
1647
+ .post_read = ind_wr_xfer_ctrl_reg_post_read,
1648
+ },{ .name = "INDIRECT_WRITE_XFER_WATERMARK_REG",
1649
+ .addr = A_INDIRECT_WRITE_XFER_WATERMARK_REG,
1650
+ .reset = 0xffffffff,
1651
+ },{ .name = "INDIRECT_WRITE_XFER_START_REG",
1652
+ .addr = A_INDIRECT_WRITE_XFER_START_REG,
1653
+ },{ .name = "INDIRECT_WRITE_XFER_NUM_BYTES_REG",
1654
+ .addr = A_INDIRECT_WRITE_XFER_NUM_BYTES_REG,
1655
+ },{ .name = "INDIRECT_TRIGGER_ADDR_RANGE_REG",
1656
+ .addr = A_INDIRECT_TRIGGER_ADDR_RANGE_REG,
1657
+ .reset = 0x4,
1658
+ .ro = 0xfffffff0,
1659
+ },{ .name = "FLASH_COMMAND_CTRL_MEM_REG",
1660
+ .addr = A_FLASH_COMMAND_CTRL_MEM_REG,
1661
+ .ro = 0xe008fffe,
1662
+ .post_write = flash_cmd_ctrl_mem_reg_post_write,
1663
+ },{ .name = "FLASH_CMD_CTRL_REG",
1664
+ .addr = A_FLASH_CMD_CTRL_REG,
1665
+ .ro = 0x7a,
1666
+ .post_write = flash_cmd_ctrl_reg_post_write,
1667
+ },{ .name = "FLASH_CMD_ADDR_REG",
1668
+ .addr = A_FLASH_CMD_ADDR_REG,
1669
+ },{ .name = "FLASH_RD_DATA_LOWER_REG",
1670
+ .addr = A_FLASH_RD_DATA_LOWER_REG,
1671
+ .ro = 0xffffffff,
1672
+ },{ .name = "FLASH_RD_DATA_UPPER_REG",
1673
+ .addr = A_FLASH_RD_DATA_UPPER_REG,
1674
+ .ro = 0xffffffff,
1675
+ },{ .name = "FLASH_WR_DATA_LOWER_REG",
1676
+ .addr = A_FLASH_WR_DATA_LOWER_REG,
1677
+ },{ .name = "FLASH_WR_DATA_UPPER_REG",
1678
+ .addr = A_FLASH_WR_DATA_UPPER_REG,
1679
+ },{ .name = "POLLING_FLASH_STATUS_REG",
1680
+ .addr = A_POLLING_FLASH_STATUS_REG,
1681
+ .ro = 0xfff0ffff,
1682
+ },{ .name = "PHY_CONFIGURATION_REG",
1683
+ .addr = A_PHY_CONFIGURATION_REG,
1684
+ .reset = 0x40000000,
1685
+ .ro = 0x1f80ff80,
1686
+ },{ .name = "PHY_MASTER_CONTROL_REG",
1687
+ .addr = A_PHY_MASTER_CONTROL_REG,
1688
+ .reset = 0x800000,
1689
+ .ro = 0xfe08ff80,
1690
+ },{ .name = "DLL_OBSERVABLE_LOWER_REG",
1691
+ .addr = A_DLL_OBSERVABLE_LOWER_REG,
1692
+ .ro = 0xffffffff,
1693
+ },{ .name = "DLL_OBSERVABLE_UPPER_REG",
1694
+ .addr = A_DLL_OBSERVABLE_UPPER_REG,
1695
+ .ro = 0xffffffff,
1696
+ .post_read = dll_obs_upper_reg_post_read,
1697
+ },{ .name = "OPCODE_EXT_LOWER_REG",
1698
+ .addr = A_OPCODE_EXT_LOWER_REG,
1699
+ .reset = 0x13edfa00,
1700
+ },{ .name = "OPCODE_EXT_UPPER_REG",
1701
+ .addr = A_OPCODE_EXT_UPPER_REG,
1702
+ .reset = 0x6f90000,
1703
+ .ro = 0xffff,
1704
+ },{ .name = "MODULE_ID_REG",
1705
+ .addr = A_MODULE_ID_REG,
1706
+ .reset = 0x300,
1707
+ .ro = 0xffffffff,
1708
+ }
1709
+};
1710
+
1711
+/* Return dev-obj from reg-region created by register_init_block32 */
1712
+static XlnxVersalOspi *xilinx_ospi_of_mr(void *mr_accessor)
1713
+{
1714
+ RegisterInfoArray *reg_array = mr_accessor;
1715
+ Object *dev;
1716
+
1717
+ dev = reg_array->mem.owner;
1718
+ assert(dev);
1719
+
1720
+ return XILINX_VERSAL_OSPI(dev);
1721
+}
1722
+
1723
+static void ospi_write(void *opaque, hwaddr addr, uint64_t value,
1724
+ unsigned int size)
1725
+{
1726
+ XlnxVersalOspi *s = xilinx_ospi_of_mr(opaque);
1727
+
1728
+ register_write_memory(opaque, addr, value, size);
1729
+ ospi_update_irq_line(s);
1730
+}
1731
+
1732
+static const MemoryRegionOps ospi_ops = {
1733
+ .read = register_read_memory,
1734
+ .write = ospi_write,
1735
+ .endianness = DEVICE_LITTLE_ENDIAN,
1736
+ .valid = {
1737
+ .min_access_size = 4,
1738
+ .max_access_size = 4,
1739
+ },
1740
+};
1741
+
1742
+static uint64_t ospi_indac_read(void *opaque, unsigned int size)
1743
+{
1744
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(opaque);
1745
+ uint64_t ret = ospi_rx_sram_read(s, size);
1746
+
1747
+ if (!ospi_ind_op_completed(s->rd_ind_op)) {
1748
+ ospi_do_ind_read(s);
1749
+ }
1750
+ return ret;
1751
+}
1752
+
1753
+static void ospi_indac_write(void *opaque, uint64_t value, unsigned int size)
1754
+{
1755
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(opaque);
1756
+
1757
+ g_assert(!s->ind_write_disabled);
1758
+
1759
+ if (!ospi_ind_op_completed(s->wr_ind_op)) {
1760
+ ospi_tx_sram_write(s, value, size);
1761
+ ospi_do_indirect_write(s);
1762
+ } else {
1763
+ qemu_log_mask(LOG_GUEST_ERROR,
1764
+ "OSPI wr into indac area while no ongoing indac wr\n");
1765
+ }
1766
+}
1767
+
1768
+static bool is_inside_indac_range(XlnxVersalOspi *s, hwaddr addr)
1769
+{
1770
+ uint32_t range_start;
1771
+ uint32_t range_end;
1772
+
1773
+ if (ARRAY_FIELD_EX32(s->regs, CONFIG_REG, ENB_DMA_IF_FLD)) {
1774
+ return true;
1775
+ }
1776
+
1777
+ range_start = s->regs[R_IND_AHB_ADDR_TRIGGER_REG];
1778
+ range_end = range_start +
1779
+ (1 << ARRAY_FIELD_EX32(s->regs,
1780
+ INDIRECT_TRIGGER_ADDR_RANGE_REG,
1781
+ IND_RANGE_WIDTH_FLD));
1782
+
1783
+ addr += s->regs[R_IND_AHB_ADDR_TRIGGER_REG] & 0xF0000000;
1784
+
1785
+ return addr >= range_start && addr < range_end;
1786
+}
1787
+
1788
+static bool ospi_is_indac_active(XlnxVersalOspi *s)
1789
+{
1790
+ /*
1791
+ * When dac and indac cannot be active at the same time,
1792
+ * return true when dac is disabled.
1793
+ */
1794
+ return s->dac_with_indac || !s->dac_enable;
1795
+}
1796
+
1797
+static uint64_t ospi_dac_read(void *opaque, hwaddr addr, unsigned int size)
1798
+{
1799
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(opaque);
1800
+
1801
+ if (ARRAY_FIELD_EX32(s->regs, CONFIG_REG, ENB_SPI_FLD)) {
1802
+ if (ospi_is_indac_active(s) &&
1803
+ is_inside_indac_range(s, addr)) {
1804
+ return ospi_indac_read(s, size);
1805
+ }
1806
+ if (ARRAY_FIELD_EX32(s->regs, CONFIG_REG, ENB_DIR_ACC_CTLR_FLD)
1807
+ && s->dac_enable) {
1808
+ if (ARRAY_FIELD_EX32(s->regs,
1809
+ CONFIG_REG, ENB_AHB_ADDR_REMAP_FLD)) {
1810
+ addr += s->regs[R_REMAP_ADDR_REG];
1811
+ }
1812
+ return ospi_do_dac_read(opaque, addr, size);
1813
+ } else {
1814
+ qemu_log_mask(LOG_GUEST_ERROR, "OSPI AHB rd while DAC disabled\n");
1815
+ }
1816
+ } else {
1817
+ qemu_log_mask(LOG_GUEST_ERROR, "OSPI AHB rd while OSPI disabled\n");
1818
+ }
1819
+
101
+ return 0;
1820
+ return 0;
102
+}
1821
+}
103
+
1822
+
104
static int pl031_post_load(void *opaque, int version_id)
1823
+static void ospi_dac_write(void *opaque, hwaddr addr, uint64_t value,
105
{
1824
+ unsigned int size)
106
PL031State *s = opaque;
1825
+{
107
1826
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(opaque);
108
- int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
1827
+
109
- s->tick_offset = s->tick_offset_vmstate - delta / NANOSECONDS_PER_SECOND;
1828
+ if (ARRAY_FIELD_EX32(s->regs, CONFIG_REG, ENB_SPI_FLD)) {
110
+ /*
1829
+ if (ospi_is_indac_active(s) &&
111
+ * If we got the tick_offset subsection, then we can just use
1830
+ !s->ind_write_disabled &&
112
+ * the value in that. Otherwise the source is an older QEMU and
1831
+ is_inside_indac_range(s, addr)) {
113
+ * has given us the offset from the vm_clock; convert it back to
1832
+ return ospi_indac_write(s, value, size);
114
+ * an offset from the rtc_clock. This will cause time to incorrectly
1833
+ }
115
+ * go backwards compared to the host RTC, but this is unavoidable.
1834
+ if (ARRAY_FIELD_EX32(s->regs, CONFIG_REG, ENB_DIR_ACC_CTLR_FLD) &&
116
+ */
1835
+ s->dac_enable) {
117
+
1836
+ if (ARRAY_FIELD_EX32(s->regs,
118
+ if (!s->tick_offset_migrated) {
1837
+ CONFIG_REG, ENB_AHB_ADDR_REMAP_FLD)) {
119
+ int64_t delta = qemu_clock_get_ns(rtc_clock) -
1838
+ addr += s->regs[R_REMAP_ADDR_REG];
120
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
1839
+ }
121
+ s->tick_offset = s->tick_offset_vmstate -
1840
+ /* Check if addr is write protected */
122
+ delta / NANOSECONDS_PER_SECOND;
1841
+ if (ARRAY_FIELD_EX32(s->regs, WR_PROT_CTRL_REG, ENB_FLD) &&
123
+ }
1842
+ ospi_is_write_protected(s, addr)) {
124
pl031_set_alarm(s);
1843
+ set_irq(s, R_IRQ_STATUS_REG_PROT_WR_ATTEMPT_FLD_MASK);
125
return 0;
1844
+ ospi_update_irq_line(s);
126
}
1845
+ qemu_log_mask(LOG_GUEST_ERROR,
127
1846
+ "OSPI writing into write protected area\n");
128
+static int pl031_tick_offset_post_load(void *opaque, int version_id)
1847
+ return;
129
+{
1848
+ }
130
+ PL031State *s = opaque;
1849
+ ospi_do_dac_write(opaque, addr, value, size);
131
+
1850
+ } else {
132
+ s->tick_offset_migrated = true;
1851
+ qemu_log_mask(LOG_GUEST_ERROR, "OSPI AHB wr while DAC disabled\n");
133
+ return 0;
1852
+ }
134
+}
1853
+ } else {
135
+
1854
+ qemu_log_mask(LOG_GUEST_ERROR, "OSPI AHB wr while OSPI disabled\n");
136
+static bool pl031_tick_offset_needed(void *opaque)
1855
+ }
137
+{
1856
+}
138
+ PL031State *s = opaque;
1857
+
139
+
1858
+static const MemoryRegionOps ospi_dac_ops = {
140
+ return s->migrate_tick_offset;
1859
+ .read = ospi_dac_read,
141
+}
1860
+ .write = ospi_dac_write,
142
+
1861
+ .endianness = DEVICE_LITTLE_ENDIAN,
143
+static const VMStateDescription vmstate_pl031_tick_offset = {
1862
+ .valid = {
144
+ .name = "pl031/tick-offset",
1863
+ .min_access_size = 4,
1864
+ .max_access_size = 4,
1865
+ },
1866
+};
1867
+
1868
+static void ospi_update_dac_status(void *opaque, int n, int level)
1869
+{
1870
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(opaque);
1871
+
1872
+ s->dac_enable = level;
1873
+}
1874
+
1875
+static void xlnx_versal_ospi_realize(DeviceState *dev, Error **errp)
1876
+{
1877
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(dev);
1878
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
1879
+
1880
+ s->num_cs = 4;
1881
+ s->spi = ssi_create_bus(dev, "spi0");
1882
+ s->cs_lines = g_new0(qemu_irq, s->num_cs);
1883
+ for (int i = 0; i < s->num_cs; ++i) {
1884
+ sysbus_init_irq(sbd, &s->cs_lines[i]);
1885
+ }
1886
+
1887
+ fifo8_create(&s->rx_fifo, RXFF_SZ);
1888
+ fifo8_create(&s->tx_fifo, TXFF_SZ);
1889
+ fifo8_create(&s->rx_sram, RXFF_SZ);
1890
+ fifo8_create(&s->tx_sram, TXFF_SZ);
1891
+}
1892
+
1893
+static void xlnx_versal_ospi_init(Object *obj)
1894
+{
1895
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(obj);
1896
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
1897
+ DeviceState *dev = DEVICE(obj);
1898
+ RegisterInfoArray *reg_array;
1899
+
1900
+ memory_region_init(&s->iomem, obj, TYPE_XILINX_VERSAL_OSPI,
1901
+ XILINX_VERSAL_OSPI_R_MAX * 4);
1902
+ reg_array =
1903
+ register_init_block32(DEVICE(obj), ospi_regs_info,
1904
+ ARRAY_SIZE(ospi_regs_info),
1905
+ s->regs_info, s->regs,
1906
+ &ospi_ops,
1907
+ XILINX_VERSAL_OSPI_ERR_DEBUG,
1908
+ XILINX_VERSAL_OSPI_R_MAX * 4);
1909
+ memory_region_add_subregion(&s->iomem, 0x0, &reg_array->mem);
1910
+ sysbus_init_mmio(sbd, &s->iomem);
1911
+
1912
+ memory_region_init_io(&s->iomem_dac, obj, &ospi_dac_ops, s,
1913
+ TYPE_XILINX_VERSAL_OSPI "-dac", 0x20000000);
1914
+ sysbus_init_mmio(sbd, &s->iomem_dac);
1915
+
1916
+ sysbus_init_irq(sbd, &s->irq);
1917
+
1918
+ object_property_add_link(obj, "dma-src", TYPE_XLNX_CSU_DMA,
1919
+ (Object **)&s->dma_src,
1920
+ object_property_allow_set_link,
1921
+ OBJ_PROP_LINK_STRONG);
1922
+
1923
+ qdev_init_gpio_in_named(dev, ospi_update_dac_status, "ospi-mux-sel", 1);
1924
+}
1925
+
1926
+static const VMStateDescription vmstate_ind_op = {
1927
+ .name = "OSPIIndOp",
145
+ .version_id = 1,
1928
+ .version_id = 1,
146
+ .minimum_version_id = 1,
1929
+ .minimum_version_id = 1,
147
+ .needed = pl031_tick_offset_needed,
148
+ .post_load = pl031_tick_offset_post_load,
149
+ .fields = (VMStateField[]) {
1930
+ .fields = (VMStateField[]) {
150
+ VMSTATE_UINT32(tick_offset, PL031State),
1931
+ VMSTATE_UINT32(flash_addr, IndOp),
1932
+ VMSTATE_UINT32(num_bytes, IndOp),
1933
+ VMSTATE_UINT32(done_bytes, IndOp),
1934
+ VMSTATE_BOOL(completed, IndOp),
151
+ VMSTATE_END_OF_LIST()
1935
+ VMSTATE_END_OF_LIST()
152
+ }
1936
+ }
153
+};
1937
+};
154
+
1938
+
155
static const VMStateDescription vmstate_pl031 = {
1939
+static const VMStateDescription vmstate_xlnx_versal_ospi = {
156
.name = "pl031",
1940
+ .name = TYPE_XILINX_VERSAL_OSPI,
157
.version_id = 1,
1941
+ .version_id = 1,
158
.minimum_version_id = 1,
1942
+ .minimum_version_id = 1,
159
.pre_save = pl031_pre_save,
1943
+ .minimum_version_id_old = 1,
160
+ .pre_load = pl031_pre_load,
1944
+ .fields = (VMStateField[]) {
161
.post_load = pl031_post_load,
1945
+ VMSTATE_FIFO8(rx_fifo, XlnxVersalOspi),
162
.fields = (VMStateField[]) {
1946
+ VMSTATE_FIFO8(tx_fifo, XlnxVersalOspi),
163
VMSTATE_UINT32(tick_offset_vmstate, PL031State),
1947
+ VMSTATE_FIFO8(rx_sram, XlnxVersalOspi),
164
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pl031 = {
1948
+ VMSTATE_FIFO8(tx_sram, XlnxVersalOspi),
165
VMSTATE_UINT32(im, PL031State),
1949
+ VMSTATE_BOOL(ind_write_disabled, XlnxVersalOspi),
166
VMSTATE_UINT32(is, PL031State),
1950
+ VMSTATE_BOOL(dac_with_indac, XlnxVersalOspi),
167
VMSTATE_END_OF_LIST()
1951
+ VMSTATE_BOOL(dac_enable, XlnxVersalOspi),
168
+ },
1952
+ VMSTATE_BOOL(src_dma_inprog, XlnxVersalOspi),
169
+ .subsections = (const VMStateDescription*[]) {
1953
+ VMSTATE_STRUCT_ARRAY(rd_ind_op, XlnxVersalOspi, 2, 1,
170
+ &vmstate_pl031_tick_offset,
1954
+ vmstate_ind_op, IndOp),
171
+ NULL
1955
+ VMSTATE_STRUCT_ARRAY(wr_ind_op, XlnxVersalOspi, 2, 1,
172
}
1956
+ vmstate_ind_op, IndOp),
173
};
1957
+ VMSTATE_UINT32_ARRAY(regs, XlnxVersalOspi, XILINX_VERSAL_OSPI_R_MAX),
174
1958
+ VMSTATE_UINT8_ARRAY(stig_membank, XlnxVersalOspi, 512),
175
+static Property pl031_properties[] = {
1959
+ VMSTATE_END_OF_LIST(),
176
+ /*
1960
+ }
177
+ * True to correctly migrate the tick offset of the RTC. False to
178
+ * obtain backward migration compatibility with older QEMU versions,
179
+ * at the expense of the guest RTC going backwards compared with the
180
+ * host RTC when the VM is saved/restored if using -rtc host.
181
+ * (Even if set to 'true' older QEMU can migrate forward to newer QEMU;
182
+ * 'false' also permits newer QEMU to migrate to older QEMU.)
183
+ */
184
+ DEFINE_PROP_BOOL("migrate-tick-offset",
185
+ PL031State, migrate_tick_offset, true),
186
+ DEFINE_PROP_END_OF_LIST()
187
+};
1961
+};
188
+
1962
+
189
static void pl031_class_init(ObjectClass *klass, void *data)
1963
+static Property xlnx_versal_ospi_properties[] = {
190
{
1964
+ DEFINE_PROP_BOOL("dac-with-indac", XlnxVersalOspi, dac_with_indac, false),
191
DeviceClass *dc = DEVICE_CLASS(klass);
1965
+ DEFINE_PROP_BOOL("indac-write-disabled", XlnxVersalOspi,
192
1966
+ ind_write_disabled, false),
193
dc->vmsd = &vmstate_pl031;
1967
+ DEFINE_PROP_END_OF_LIST(),
194
+ dc->props = pl031_properties;
1968
+};
195
}
1969
+
196
1970
+static void xlnx_versal_ospi_class_init(ObjectClass *klass, void *data)
197
static const TypeInfo pl031_info = {
1971
+{
1972
+ DeviceClass *dc = DEVICE_CLASS(klass);
1973
+
1974
+ dc->reset = xlnx_versal_ospi_reset;
1975
+ dc->realize = xlnx_versal_ospi_realize;
1976
+ dc->vmsd = &vmstate_xlnx_versal_ospi;
1977
+ device_class_set_props(dc, xlnx_versal_ospi_properties);
1978
+}
1979
+
1980
+static const TypeInfo xlnx_versal_ospi_info = {
1981
+ .name = TYPE_XILINX_VERSAL_OSPI,
1982
+ .parent = TYPE_SYS_BUS_DEVICE,
1983
+ .instance_size = sizeof(XlnxVersalOspi),
1984
+ .class_init = xlnx_versal_ospi_class_init,
1985
+ .instance_init = xlnx_versal_ospi_init,
1986
+};
1987
+
1988
+static void xlnx_versal_ospi_register_types(void)
1989
+{
1990
+ type_register_static(&xlnx_versal_ospi_info);
1991
+}
1992
+
1993
+type_init(xlnx_versal_ospi_register_types)
1994
diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
1995
index XXXXXXX..XXXXXXX 100644
1996
--- a/hw/ssi/meson.build
1997
+++ b/hw/ssi/meson.build
1998
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_SSI', if_true: files('ssi.c'))
1999
softmmu_ss.add(when: 'CONFIG_STM32F2XX_SPI', if_true: files('stm32f2xx_spi.c'))
2000
softmmu_ss.add(when: 'CONFIG_XILINX_SPI', if_true: files('xilinx_spi.c'))
2001
softmmu_ss.add(when: 'CONFIG_XILINX_SPIPS', if_true: files('xilinx_spips.c'))
2002
+softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-ospi.c'))
2003
softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_spi.c'))
2004
softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_spi.c'))
198
--
2005
--
199
2.20.1
2006
2.25.1
200
2007
201
2008
diff view generated by jsdifflib
New patch
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
1
2
3
Connect the OSPI flash memory controller model (including the source and
4
destination DMA).
5
6
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20220121161141.14389-8-francisco.iglesias@xilinx.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/xlnx-versal.h | 20 ++++++++
12
hw/arm/xlnx-versal.c | 93 ++++++++++++++++++++++++++++++++++++
13
2 files changed, 113 insertions(+)
14
15
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/xlnx-versal.h
18
+++ b/include/hw/arm/xlnx-versal.h
19
@@ -XXX,XX +XXX,XX @@
20
#include "hw/misc/xlnx-versal-xramc.h"
21
#include "hw/nvram/xlnx-bbram.h"
22
#include "hw/nvram/xlnx-versal-efuse.h"
23
+#include "hw/ssi/xlnx-versal-ospi.h"
24
+#include "hw/dma/xlnx_csu_dma.h"
25
#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
26
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
28
@@ -XXX,XX +XXX,XX @@ struct Versal {
29
struct {
30
SDHCIState sd[XLNX_VERSAL_NR_SDS];
31
XlnxVersalPmcIouSlcr slcr;
32
+
33
+ struct {
34
+ XlnxVersalOspi ospi;
35
+ XlnxCSUDMA dma_src;
36
+ XlnxCSUDMA dma_dst;
37
+ MemoryRegion linear_mr;
38
+ qemu_or_irq irq_orgate;
39
+ } ospi;
40
} iou;
41
42
XlnxZynqMPRTC rtc;
43
@@ -XXX,XX +XXX,XX @@ struct Versal {
44
#define VERSAL_ADMA_IRQ_0 60
45
#define VERSAL_XRAM_IRQ_0 79
46
#define VERSAL_PMC_APB_IRQ 121
47
+#define VERSAL_OSPI_IRQ 124
48
#define VERSAL_SD0_IRQ_0 126
49
#define VERSAL_EFUSE_IRQ 139
50
#define VERSAL_RTC_ALARM_IRQ 142
51
@@ -XXX,XX +XXX,XX @@ struct Versal {
52
#define MM_PMC_PMC_IOU_SLCR 0xf1060000
53
#define MM_PMC_PMC_IOU_SLCR_SIZE 0x10000
54
55
+#define MM_PMC_OSPI 0xf1010000
56
+#define MM_PMC_OSPI_SIZE 0x10000
57
+
58
+#define MM_PMC_OSPI_DAC 0xc0000000
59
+#define MM_PMC_OSPI_DAC_SIZE 0x20000000
60
+
61
+#define MM_PMC_OSPI_DMA_DST 0xf1011800
62
+#define MM_PMC_OSPI_DMA_SRC 0xf1011000
63
+
64
#define MM_PMC_SD0 0xf1040000U
65
#define MM_PMC_SD0_SIZE 0x10000
66
#define MM_PMC_BBRAM_CTRL 0xf11f0000
67
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/arm/xlnx-versal.c
70
+++ b/hw/arm/xlnx-versal.c
71
@@ -XXX,XX +XXX,XX @@
72
#define GEM_REVISION 0x40070106
73
74
#define VERSAL_NUM_PMC_APB_IRQS 3
75
+#define NUM_OSPI_IRQ_LINES 3
76
77
static void versal_create_apu_cpus(Versal *s)
78
{
79
@@ -XXX,XX +XXX,XX @@ static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic)
80
qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 2));
81
}
82
83
+static void versal_create_ospi(Versal *s, qemu_irq *pic)
84
+{
85
+ SysBusDevice *sbd;
86
+ MemoryRegion *mr_dac;
87
+ qemu_irq ospi_mux_sel;
88
+ DeviceState *orgate;
89
+
90
+ memory_region_init(&s->pmc.iou.ospi.linear_mr, OBJECT(s),
91
+ "versal-ospi-linear-mr" , MM_PMC_OSPI_DAC_SIZE);
92
+
93
+ object_initialize_child(OBJECT(s), "versal-ospi", &s->pmc.iou.ospi.ospi,
94
+ TYPE_XILINX_VERSAL_OSPI);
95
+
96
+ mr_dac = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 1);
97
+ memory_region_add_subregion(&s->pmc.iou.ospi.linear_mr, 0x0, mr_dac);
98
+
99
+ /* Create the OSPI destination DMA */
100
+ object_initialize_child(OBJECT(s), "versal-ospi-dma-dst",
101
+ &s->pmc.iou.ospi.dma_dst,
102
+ TYPE_XLNX_CSU_DMA);
103
+
104
+ object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_dst),
105
+ "dma", OBJECT(get_system_memory()),
106
+ &error_abort);
107
+
108
+ sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst);
109
+ sysbus_realize(sbd, &error_fatal);
110
+
111
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_DST,
112
+ sysbus_mmio_get_region(sbd, 0));
113
+
114
+ /* Create the OSPI source DMA */
115
+ object_initialize_child(OBJECT(s), "versal-ospi-dma-src",
116
+ &s->pmc.iou.ospi.dma_src,
117
+ TYPE_XLNX_CSU_DMA);
118
+
119
+ object_property_set_bool(OBJECT(&s->pmc.iou.ospi.dma_src), "is-dst",
120
+ false, &error_abort);
121
+
122
+ object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src),
123
+ "dma", OBJECT(mr_dac), &error_abort);
124
+
125
+ object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src),
126
+ "stream-connected-dma",
127
+ OBJECT(&s->pmc.iou.ospi.dma_dst),
128
+ &error_abort);
129
+
130
+ sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src);
131
+ sysbus_realize(sbd, &error_fatal);
132
+
133
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_SRC,
134
+ sysbus_mmio_get_region(sbd, 0));
135
+
136
+ /* Realize the OSPI */
137
+ object_property_set_link(OBJECT(&s->pmc.iou.ospi.ospi), "dma-src",
138
+ OBJECT(&s->pmc.iou.ospi.dma_src), &error_abort);
139
+
140
+ sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi);
141
+ sysbus_realize(sbd, &error_fatal);
142
+
143
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI,
144
+ sysbus_mmio_get_region(sbd, 0));
145
+
146
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DAC,
147
+ &s->pmc.iou.ospi.linear_mr);
148
+
149
+ /* ospi_mux_sel */
150
+ ospi_mux_sel = qdev_get_gpio_in_named(DEVICE(&s->pmc.iou.ospi.ospi),
151
+ "ospi-mux-sel", 0);
152
+ qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "ospi-mux-sel", 0,
153
+ ospi_mux_sel);
154
+
155
+ /* OSPI irq */
156
+ object_initialize_child(OBJECT(s), "ospi-irq-orgate",
157
+ &s->pmc.iou.ospi.irq_orgate, TYPE_OR_IRQ);
158
+ object_property_set_int(OBJECT(&s->pmc.iou.ospi.irq_orgate),
159
+ "num-lines", NUM_OSPI_IRQ_LINES, &error_fatal);
160
+
161
+ orgate = DEVICE(&s->pmc.iou.ospi.irq_orgate);
162
+ qdev_realize(orgate, NULL, &error_fatal);
163
+
164
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 0,
165
+ qdev_get_gpio_in(orgate, 0));
166
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src), 0,
167
+ qdev_get_gpio_in(orgate, 1));
168
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst), 0,
169
+ qdev_get_gpio_in(orgate, 2));
170
+
171
+ qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
172
+}
173
+
174
/* This takes the board allocated linear DDR memory and creates aliases
175
* for each split DDR range/aperture on the Versal address map.
176
*/
177
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
178
versal_create_bbram(s, pic);
179
versal_create_efuse(s, pic);
180
versal_create_pmc_iou_slcr(s, pic);
181
+ versal_create_ospi(s, pic);
182
versal_map_ddr(s);
183
versal_unimp(s);
184
185
--
186
2.25.1
187
188
diff view generated by jsdifflib
New patch
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
1
2
3
Add support for Micron Xccela flash mt35xu01g.
4
5
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Message-id: 20220121161141.14389-9-francisco.iglesias@xilinx.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/block/m25p80.c | 2 ++
11
1 file changed, 2 insertions(+)
12
13
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/block/m25p80.c
16
+++ b/hw/block/m25p80.c
17
@@ -XXX,XX +XXX,XX @@ static const FlashPartInfo known_devices[] = {
18
{ INFO("n25q512a", 0x20ba20, 0, 64 << 10, 1024, ER_4K) },
19
{ INFO("n25q512ax3", 0x20ba20, 0x1000, 64 << 10, 1024, ER_4K) },
20
{ INFO("mt25ql512ab", 0x20ba20, 0x1044, 64 << 10, 1024, ER_4K | ER_32K) },
21
+ { INFO_STACKED("mt35xu01g", 0x2c5b1b, 0x104100, 128 << 10, 1024,
22
+ ER_4K | ER_32K, 2) },
23
{ INFO_STACKED("n25q00", 0x20ba21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
24
{ INFO_STACKED("n25q00a", 0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
25
{ INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
26
--
27
2.25.1
28
29
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
2
2
3
In the previous commit we fixed a crash when the guest read a
3
Connect Micron Xccela mt35xu01g flashes to the OSPI flash memory
4
register that pop from an empty FIFO.
4
controller.
5
By auditing the repository, we found another similar use with
6
an easy way to reproduce:
7
5
8
$ qemu-system-aarch64 -M xlnx-zcu102 -monitor stdio -S
6
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
9
QEMU 4.0.50 monitor - type 'help' for more information
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
(qemu) xp/b 0xfd4a0134
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Aborted (core dumped)
9
Message-id: 20220121161141.14389-10-francisco.iglesias@xilinx.com
12
13
(gdb) bt
14
#0 0x00007f6936dea57f in raise () at /lib64/libc.so.6
15
#1 0x00007f6936dd4895 in abort () at /lib64/libc.so.6
16
#2 0x0000561ad32975ec in xlnx_dp_aux_pop_rx_fifo (s=0x7f692babee70) at hw/display/xlnx_dp.c:431
17
#3 0x0000561ad3297dc0 in xlnx_dp_read (opaque=0x7f692babee70, offset=77, size=4) at hw/display/xlnx_dp.c:667
18
#4 0x0000561ad321b896 in memory_region_read_accessor (mr=0x7f692babf620, addr=308, value=0x7ffe05c1db88, size=4, shift=0, mask=4294967295, attrs=...) at memory.c:439
19
#5 0x0000561ad321bd70 in access_with_adjusted_size (addr=308, value=0x7ffe05c1db88, size=1, access_size_min=4, access_size_max=4, access_fn=0x561ad321b858 <memory_region_read_accessor>, mr=0x7f692babf620, attrs=...) at memory.c:569
20
#6 0x0000561ad321e9d5 in memory_region_dispatch_read1 (mr=0x7f692babf620, addr=308, pval=0x7ffe05c1db88, size=1, attrs=...) at memory.c:1420
21
#7 0x0000561ad321ea9d in memory_region_dispatch_read (mr=0x7f692babf620, addr=308, pval=0x7ffe05c1db88, size=1, attrs=...) at memory.c:1447
22
#8 0x0000561ad31bd742 in flatview_read_continue (fv=0x561ad69c04f0, addr=4249485620, attrs=..., buf=0x7ffe05c1dcf0 "\020\335\301\005\376\177", len=1, addr1=308, l=1, mr=0x7f692babf620) at exec.c:3385
23
#9 0x0000561ad31bd895 in flatview_read (fv=0x561ad69c04f0, addr=4249485620, attrs=..., buf=0x7ffe05c1dcf0 "\020\335\301\005\376\177", len=1) at exec.c:3423
24
#10 0x0000561ad31bd90b in address_space_read_full (as=0x561ad5bb3020, addr=4249485620, attrs=..., buf=0x7ffe05c1dcf0 "\020\335\301\005\376\177", len=1) at exec.c:3436
25
#11 0x0000561ad33b1c42 in address_space_read (len=1, buf=0x7ffe05c1dcf0 "\020\335\301\005\376\177", attrs=..., addr=4249485620, as=0x561ad5bb3020) at include/exec/memory.h:2131
26
#12 0x0000561ad33b1c42 in memory_dump (mon=0x561ad59c4530, count=1, format=120, wsize=1, addr=4249485620, is_physical=1) at monitor/misc.c:723
27
#13 0x0000561ad33b1fc1 in hmp_physical_memory_dump (mon=0x561ad59c4530, qdict=0x561ad6c6fd00) at monitor/misc.c:795
28
#14 0x0000561ad37b4a9f in handle_hmp_command (mon=0x561ad59c4530, cmdline=0x561ad59d0f22 "/b 0x00000000fd4a0134") at monitor/hmp.c:1082
29
30
Fix by checking the FIFO is not empty before popping from it.
31
32
The datasheet is not clear about the reset value of this register,
33
we choose to return '0'.
34
35
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
36
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
37
Message-id: 20190709113715.7761-4-philmd@redhat.com
38
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
39
---
11
---
40
hw/display/xlnx_dp.c | 15 +++++++++++----
12
hw/arm/xlnx-versal-virt.c | 23 +++++++++++++++++++++++
41
1 file changed, 11 insertions(+), 4 deletions(-)
13
1 file changed, 23 insertions(+)
42
14
43
diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
15
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
44
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/display/xlnx_dp.c
17
--- a/hw/arm/xlnx-versal-virt.c
46
+++ b/hw/display/xlnx_dp.c
18
+++ b/hw/arm/xlnx-versal-virt.c
47
@@ -XXX,XX +XXX,XX @@ static uint8_t xlnx_dp_aux_pop_rx_fifo(XlnxDPState *s)
19
@@ -XXX,XX +XXX,XX @@
48
uint8_t ret;
20
#define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
49
21
OBJECT_DECLARE_SIMPLE_TYPE(VersalVirt, XLNX_VERSAL_VIRT_MACHINE)
50
if (fifo8_is_empty(&s->rx_fifo)) {
22
51
- DPRINTF("rx_fifo underflow..\n");
23
+#define XLNX_VERSAL_NUM_OSPI_FLASH 4
52
- abort();
24
+
53
+ qemu_log_mask(LOG_GUEST_ERROR,
25
struct VersalVirt {
54
+ "%s: Reading empty RX_FIFO\n",
26
MachineState parent_obj;
55
+ __func__);
27
56
+ /*
28
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
57
+ * The datasheet is not clear about the reset value, it seems
29
exit(EXIT_FAILURE);
58
+ * to be unspecified. We choose to return '0'.
30
}
59
+ */
60
+ ret = 0;
61
+ } else {
62
+ ret = fifo8_pop(&s->rx_fifo);
63
+ DPRINTF("pop 0x%" PRIX8 " from rx_fifo.\n", ret);
64
}
31
}
65
- ret = fifo8_pop(&s->rx_fifo);
32
+
66
- DPRINTF("pop 0x%" PRIX8 " from rx_fifo.\n", ret);
33
+ for (i = 0; i < XLNX_VERSAL_NUM_OSPI_FLASH; i++) {
67
return ret;
34
+ BusState *spi_bus;
35
+ DeviceState *flash_dev;
36
+ qemu_irq cs_line;
37
+ DriveInfo *dinfo = drive_get(IF_MTD, 0, i);
38
+
39
+ spi_bus = qdev_get_child_bus(DEVICE(&s->soc.pmc.iou.ospi), "spi0");
40
+
41
+ flash_dev = qdev_new("mt35xu01g");
42
+ if (dinfo) {
43
+ qdev_prop_set_drive_err(flash_dev, "drive",
44
+ blk_by_legacy_dinfo(dinfo), &error_fatal);
45
+ }
46
+ qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);
47
+
48
+ cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
49
+
50
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.pmc.iou.ospi),
51
+ i + 1, cs_line);
52
+ }
68
}
53
}
69
54
55
static void versal_virt_machine_instance_init(Object *obj)
70
--
56
--
71
2.20.1
57
2.25.1
72
58
73
59
diff view generated by jsdifflib
New patch
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
1
2
3
List myself as maintainer for the Xilinx Versal OSPI controller.
4
5
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20220121161141.14389-11-francisco.iglesias@xilinx.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
MAINTAINERS | 6 ++++++
12
1 file changed, 6 insertions(+)
13
14
diff --git a/MAINTAINERS b/MAINTAINERS
15
index XXXXXXX..XXXXXXX 100644
16
--- a/MAINTAINERS
17
+++ b/MAINTAINERS
18
@@ -XXX,XX +XXX,XX @@ F: hw/display/dpcd.c
19
F: include/hw/display/dpcd.h
20
F: docs/system/arm/xlnx-versal-virt.rst
21
22
+Xilinx Versal OSPI
23
+M: Francisco Iglesias <francisco.iglesias@xilinx.com>
24
+S: Maintained
25
+F: hw/ssi/xlnx-versal-ospi.c
26
+F: include/hw/ssi/xlnx-versal-ospi.h
27
+
28
ARM ACPI Subsystem
29
M: Shannon Zhao <shannon.zhaosl@gmail.com>
30
L: qemu-arm@nongnu.org
31
--
32
2.25.1
33
34
diff view generated by jsdifflib
New patch
1
From: Andrew Baumann <Andrew.Baumann@microsoft.com>
1
2
3
Signed-off-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
4
Message-id: MW4PR21MB1940E8BB52F4053C943B1FCD9E219@MW4PR21MB1940.namprd21.prod.outlook.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
7
MAINTAINERS | 1 -
8
1 file changed, 1 deletion(-)
9
10
diff --git a/MAINTAINERS b/MAINTAINERS
11
index XXXXXXX..XXXXXXX 100644
12
--- a/MAINTAINERS
13
+++ b/MAINTAINERS
14
@@ -XXX,XX +XXX,XX @@ F: docs/system/arm/palm.rst
15
16
Raspberry Pi
17
M: Peter Maydell <peter.maydell@linaro.org>
18
-R: Andrew Baumann <Andrew.Baumann@microsoft.com>
19
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
L: qemu-arm@nongnu.org
21
S: Odd Fixes
22
--
23
2.25.1
24
25
diff view generated by jsdifflib
New patch
1
If you don't know it, it's hard to figure out the difference between
2
the linux-headers folder and the include/standard-headers folder.
3
So let's add a short explanation to clarify the difference.
1
4
5
Suggested-by: Thomas Huth <thuth@redhat.com>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
9
Reviewed-by: Thomas Huth <thuth@redhat.com>
10
---
11
scripts/update-linux-headers.sh | 16 ++++++++++++++++
12
1 file changed, 16 insertions(+)
13
14
diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
15
index XXXXXXX..XXXXXXX 100755
16
--- a/scripts/update-linux-headers.sh
17
+++ b/scripts/update-linux-headers.sh
18
@@ -XXX,XX +XXX,XX @@
19
#
20
# This work is licensed under the terms of the GNU GPL version 2.
21
# See the COPYING file in the top-level directory.
22
+#
23
+# The script will copy the headers into two target folders:
24
+#
25
+# - linux-headers/ for files that are required for compiling for a
26
+# Linux host. Generally we have these so we can use kernel structs
27
+# and defines that are more recent than the headers that might be
28
+# installed on the host system. Usually this script can do simple
29
+# file copies for these headers.
30
+#
31
+# - include/standard-headers/ for files that are used for guest
32
+# device emulation and are required on all hosts. For instance, we
33
+# get our definitions of the virtio structures from the Linux
34
+# kernel headers, but we need those definitions regardless of which
35
+# host OS we are building for. This script has to be careful to
36
+# sanitize the headers to remove any use of Linux-specifics such as
37
+# types like "__u64". This work is done in the cp_portable function.
38
39
tmpdir=$(mktemp -d)
40
linux="$1"
41
--
42
2.25.1
43
44
diff view generated by jsdifflib
1
In the M-profile architecture, when we do a vector table fetch and it
1
In an SMP system it can be unclear which CPU is taking an exception;
2
fails, we need to report a HardFault. Whether this is a Secure HF or
2
add the CPU index (which is the same value used in the TCG 'Trace
3
a NonSecure HF depends on several things. If AIRCR.BFHFNMINS is 0
3
%d:' logging) to the "Taking exception" log line to clarify it.
4
then HF is always Secure, because there is no NonSecure HardFault.
5
Otherwise, the answer depends on whether the 'underlying exception'
6
(MemManage, BusFault, SecureFault) targets Secure or NonSecure. (In
7
the pseudocode, this is handled in the Vector() function: the final
8
exc.isSecure is calculated by looking at the exc.isSecure from the
9
exception returned from the memory access, not the isSecure input
10
argument.)
11
12
We weren't doing this correctly, because we were looking at
13
the target security domain of the exception we were trying to
14
load the vector table entry for. This produces errors of two kinds:
15
* a load from the NS vector table which hits the "NS access
16
to S memory" SecureFault should end up as a Secure HardFault,
17
but we were raising an NS HardFault
18
* a load from the S vector table which causes a BusFault
19
should raise an NS HardFault if BFHFNMINS == 1 (because
20
in that case all BusFaults are NonSecure), but we were raising
21
a Secure HardFault
22
23
Correct the logic.
24
25
We also fix a comment error where we claimed that we might
26
be escalating MemManage to HardFault, and forgot about SecureFault.
27
(Vector loads can never hit MPU access faults, because they're
28
always aligned and always use the default address map.)
29
4
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Message-id: 20190705094823.28905-1-peter.maydell@linaro.org
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220122182444.724087-2-peter.maydell@linaro.org
32
---
9
---
33
target/arm/m_helper.c | 21 +++++++++++++++++----
10
target/arm/internals.h | 2 +-
34
1 file changed, 17 insertions(+), 4 deletions(-)
11
target/arm/helper.c | 9 ++++++---
12
target/arm/m_helper.c | 2 +-
13
3 files changed, 8 insertions(+), 5 deletions(-)
35
14
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/internals.h
18
+++ b/target/arm/internals.h
19
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
20
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
21
__attribute__((nonnull));
22
23
-void arm_log_exception(int idx);
24
+void arm_log_exception(CPUState *cs);
25
26
#endif /* !CONFIG_USER_ONLY */
27
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 @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
33
return target_el;
34
}
35
36
-void arm_log_exception(int idx)
37
+void arm_log_exception(CPUState *cs)
38
{
39
+ int idx = cs->exception_index;
40
+
41
if (qemu_loglevel_mask(CPU_LOG_INT)) {
42
const char *exc = NULL;
43
static const char * const excnames[] = {
44
@@ -XXX,XX +XXX,XX @@ void arm_log_exception(int idx)
45
if (!exc) {
46
exc = "unknown";
47
}
48
- qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s]\n", idx, exc);
49
+ qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s] on CPU %d\n",
50
+ idx, exc, cs->cpu_index);
51
}
52
}
53
54
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_interrupt(CPUState *cs)
55
56
assert(!arm_feature(env, ARM_FEATURE_M));
57
58
- arm_log_exception(cs->exception_index);
59
+ arm_log_exception(cs);
60
qemu_log_mask(CPU_LOG_INT, "...from EL%d to EL%d\n", arm_current_el(env),
61
new_el);
62
if (qemu_loglevel_mask(CPU_LOG_INT)
36
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
63
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
37
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/m_helper.c
65
--- a/target/arm/m_helper.c
39
+++ b/target/arm/m_helper.c
66
+++ b/target/arm/m_helper.c
40
@@ -XXX,XX +XXX,XX @@ static bool arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure,
67
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
41
if (sattrs.ns) {
68
uint32_t lr;
42
attrs.secure = false;
69
bool ignore_stackfaults;
43
} else if (!targets_secure) {
70
44
- /* NS access to S memory */
71
- arm_log_exception(cs->exception_index);
45
+ /*
72
+ arm_log_exception(cs);
46
+ * NS access to S memory: the underlying exception which we escalate
73
47
+ * to HardFault is SecureFault, which always targets Secure.
48
+ */
49
+ exc_secure = true;
50
goto load_fail;
51
}
52
}
53
@@ -XXX,XX +XXX,XX @@ static bool arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure,
54
vector_entry = address_space_ldl(arm_addressspace(cs, attrs), addr,
55
attrs, &result);
56
if (result != MEMTX_OK) {
57
+ /*
58
+ * Underlying exception is BusFault: its target security state
59
+ * depends on BFHFNMINS.
60
+ */
61
+ exc_secure = !(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK);
62
goto load_fail;
63
}
64
*pvec = vector_entry;
65
@@ -XXX,XX +XXX,XX @@ load_fail:
66
/*
74
/*
67
* All vector table fetch fails are reported as HardFault, with
75
* For exceptions we just mark as pending on the NVIC, and let that
68
* HFSR.VECTTBL and .FORCED set. (FORCED is set because
69
- * technically the underlying exception is a MemManage or BusFault
70
+ * technically the underlying exception is a SecureFault or BusFault
71
* that is escalated to HardFault.) This is a terminal exception,
72
* so we will either take the HardFault immediately or else enter
73
* lockup (the latter case is handled in armv7m_nvic_set_pending_derived()).
74
+ * The HardFault is Secure if BFHFNMINS is 0 (meaning that all HFs are
75
+ * secure); otherwise it targets the same security state as the
76
+ * underlying exception.
77
*/
78
- exc_secure = targets_secure ||
79
- !(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK);
80
+ if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
81
+ exc_secure = true;
82
+ }
83
env->v7m.hfsr |= R_V7M_HFSR_VECTTBL_MASK | R_V7M_HFSR_FORCED_MASK;
84
armv7m_nvic_set_pending_derived(env->nvic, ARMV7M_EXCP_HARD, exc_secure);
85
return false;
86
--
76
--
87
2.20.1
77
2.25.1
88
78
89
79
diff view generated by jsdifflib
New patch
1
The ITS currently has no tracepoints; add a minimal set
2
that allows basic monitoring of guest register accesses and
3
reading of commands from the command queue.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220122182444.724087-3-peter.maydell@linaro.org
9
---
10
hw/intc/arm_gicv3_its.c | 11 +++++++++++
11
hw/intc/trace-events | 8 ++++++++
12
2 files changed, 19 insertions(+)
13
14
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/arm_gicv3_its.c
17
+++ b/hw/intc/arm_gicv3_its.c
18
@@ -XXX,XX +XXX,XX @@
19
20
#include "qemu/osdep.h"
21
#include "qemu/log.h"
22
+#include "trace.h"
23
#include "hw/qdev-properties.h"
24
#include "hw/intc/arm_gicv3_its_common.h"
25
#include "gicv3_internal.h"
26
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
27
28
cmd = (data & CMD_MASK);
29
30
+ trace_gicv3_its_process_command(rd_offset, cmd);
31
+
32
switch (cmd) {
33
case GITS_CMD_INT:
34
result = process_its_cmd(s, data, cq_offset, INTERRUPT);
35
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset,
36
bool result = true;
37
uint32_t devid = 0;
38
39
+ trace_gicv3_its_translation_write(offset, data, size, attrs.requester_id);
40
+
41
switch (offset) {
42
case GITS_TRANSLATER:
43
if (s->ctlr & R_GITS_CTLR_ENABLED_MASK) {
44
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_read(void *opaque, hwaddr offset, uint64_t *data,
45
qemu_log_mask(LOG_GUEST_ERROR,
46
"%s: invalid guest read at offset " TARGET_FMT_plx
47
"size %u\n", __func__, offset, size);
48
+ trace_gicv3_its_badread(offset, size);
49
/*
50
* The spec requires that reserved registers are RAZ/WI;
51
* so use false returns from leaf functions as a way to
52
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_read(void *opaque, hwaddr offset, uint64_t *data,
53
* the caller, or we'll cause a spurious guest data abort.
54
*/
55
*data = 0;
56
+ } else {
57
+ trace_gicv3_its_read(offset, *data, size);
58
}
59
return MEMTX_OK;
60
}
61
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_write(void *opaque, hwaddr offset, uint64_t data,
62
qemu_log_mask(LOG_GUEST_ERROR,
63
"%s: invalid guest write at offset " TARGET_FMT_plx
64
"size %u\n", __func__, offset, size);
65
+ trace_gicv3_its_badwrite(offset, data, size);
66
/*
67
* The spec requires that reserved registers are RAZ/WI;
68
* so use false returns from leaf functions as a way to
69
* trigger the guest-error logging but don't return it to
70
* the caller, or we'll cause a spurious guest data abort.
71
*/
72
+ } else {
73
+ trace_gicv3_its_write(offset, data, size);
74
}
75
return MEMTX_OK;
76
}
77
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/intc/trace-events
80
+++ b/hw/intc/trace-events
81
@@ -XXX,XX +XXX,XX @@ gicv3_redist_badwrite(uint32_t cpu, uint64_t offset, uint64_t data, unsigned siz
82
gicv3_redist_set_irq(uint32_t cpu, int irq, int level) "GICv3 redistributor 0x%x interrupt %d level changed to %d"
83
gicv3_redist_send_sgi(uint32_t cpu, int irq) "GICv3 redistributor 0x%x pending SGI %d"
84
85
+# arm_gicv3_its.c
86
+gicv3_its_read(uint64_t offset, uint64_t data, unsigned size) "GICv3 ITS read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
87
+gicv3_its_badread(uint64_t offset, unsigned size) "GICv3 ITS read: offset 0x%" PRIx64 " size %u: error"
88
+gicv3_its_write(uint64_t offset, uint64_t data, unsigned size) "GICv3 ITS write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
89
+gicv3_its_badwrite(uint64_t offset, uint64_t data, unsigned size) "GICv3 ITS write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u: error"
90
+gicv3_its_translation_write(uint64_t offset, uint64_t data, unsigned size, uint32_t requester_id) "GICv3 ITS TRANSLATER write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u requester_id 0x%x"
91
+gicv3_its_process_command(uint32_t rd_offset, uint8_t cmd) "GICv3 ITS: processing command at offset 0x%x: 0x%x"
92
+
93
# armv7m_nvic.c
94
nvic_recompute_state(int vectpending, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d vectpending_prio %d exception_prio %d"
95
nvic_recompute_state_secure(int vectpending, bool vectpending_is_s_banked, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d is_s_banked %d vectpending_prio %d exception_prio %d"
96
--
97
2.25.1
98
99
diff view generated by jsdifflib
New patch
1
In our implementation, all ITSes connected to a GIC share a single
2
AddressSpace, which we keep in the GICv3State::dma_as field and
3
initialized based on the GIC's 'sysmem' property. The right place
4
to set it up by calling address_space_init() is therefore in the
5
GIC's realize method, not the ITS's realize.
1
6
7
This fixes a theoretical bug where QEMU hangs on startup if the board
8
model creates two ITSes connected to the same GIC -- we would call
9
address_space_init() twice on the same AddressSpace*, which creates
10
an infinite loop in the QTAILQ that softmmu/memory.c uses to store
11
its list of AddressSpaces and causes any subsequent attempt to
12
iterate through that list to loop forever. There aren't any board
13
models like that in the tree at the moment, though.
14
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20220122182444.724087-4-peter.maydell@linaro.org
18
---
19
hw/intc/arm_gicv3_common.c | 5 +++++
20
hw/intc/arm_gicv3_its.c | 3 ---
21
2 files changed, 5 insertions(+), 3 deletions(-)
22
23
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/intc/arm_gicv3_common.c
26
+++ b/hw/intc/arm_gicv3_common.c
27
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
28
return;
29
}
30
31
+ if (s->lpi_enable) {
32
+ address_space_init(&s->dma_as, s->dma,
33
+ "gicv3-its-sysmem");
34
+ }
35
+
36
s->cpu = g_new0(GICv3CPUState, s->num_cpu);
37
38
for (i = 0; i < s->num_cpu; i++) {
39
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/intc/arm_gicv3_its.c
42
+++ b/hw/intc/arm_gicv3_its.c
43
@@ -XXX,XX +XXX,XX @@ static void gicv3_arm_its_realize(DeviceState *dev, Error **errp)
44
45
gicv3_its_init_mmio(s, &gicv3_its_control_ops, &gicv3_its_translation_ops);
46
47
- address_space_init(&s->gicv3->dma_as, s->gicv3->dma,
48
- "gicv3-its-sysmem");
49
-
50
/* set the ITS default features supported */
51
s->typer = FIELD_DP64(s->typer, GITS_TYPER, PHYSICAL, 1);
52
s->typer = FIELD_DP64(s->typer, GITS_TYPER, ITT_ENTRY_SIZE,
53
--
54
2.25.1
55
56
diff view generated by jsdifflib
New patch
1
The current ITS code clears GITS_CREADR when GITS_CTLR.ENABLED is set.
2
This is not correct -- guest code can validly clear ENABLED and then
3
set it again and expect the ITS to continue processing where it left
4
off. Remove the erroneous assignment.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220122182444.724087-5-peter.maydell@linaro.org
9
---
10
hw/intc/arm_gicv3_its.c | 1 -
11
1 file changed, 1 deletion(-)
12
13
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/intc/arm_gicv3_its.c
16
+++ b/hw/intc/arm_gicv3_its.c
17
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
18
s->ctlr |= R_GITS_CTLR_ENABLED_MASK;
19
extract_table_params(s);
20
extract_cmdq_params(s);
21
- s->creadr = 0;
22
process_cmdq(s);
23
} else {
24
s->ctlr &= ~R_GITS_CTLR_ENABLED_MASK;
25
--
26
2.25.1
27
28
diff view generated by jsdifflib
New patch
1
The ITS specification says that when the guest writes to GITS_CBASER
2
this causes GITS_CREADR to be cleared. However it does not have an
3
equivalent clause for GITS_CWRITER. (This is because GITS_CREADR is
4
read-only, but GITS_CWRITER is writable and the guest can initialize
5
it.) Remove the code that clears GITS_CWRITER on GITS_CBASER writes.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220122182444.724087-6-peter.maydell@linaro.org
10
---
11
hw/intc/arm_gicv3_its.c | 3 ---
12
1 file changed, 3 deletions(-)
13
14
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/arm_gicv3_its.c
17
+++ b/hw/intc/arm_gicv3_its.c
18
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
19
if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
20
s->cbaser = deposit64(s->cbaser, 0, 32, value);
21
s->creadr = 0;
22
- s->cwriter = s->creadr;
23
}
24
break;
25
case GITS_CBASER + 4:
26
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
27
if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
28
s->cbaser = deposit64(s->cbaser, 32, 32, value);
29
s->creadr = 0;
30
- s->cwriter = s->creadr;
31
}
32
break;
33
case GITS_CWRITER:
34
@@ -XXX,XX +XXX,XX @@ static bool its_writell(GICv3ITSState *s, hwaddr offset,
35
if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
36
s->cbaser = value;
37
s->creadr = 0;
38
- s->cwriter = s->creadr;
39
}
40
break;
41
case GITS_CWRITER:
42
--
43
2.25.1
44
45
diff view generated by jsdifflib
New patch
1
The GICD_CTLR distributor register has enable bits which control
2
whether the different interrupt groups (Group 0, Non-secure Group 1
3
and Secure Group 1) are forwarded to the CPU. We get this right for
4
traditional interrupts, but forgot to account for it when adding
5
LPIs. LPIs are always Group 1 NS and if the EnableGrp1NS bit is not
6
set we must not forward them to the CPU.
1
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220122182444.724087-7-peter.maydell@linaro.org
11
---
12
hw/intc/arm_gicv3.c | 1 +
13
1 file changed, 1 insertion(+)
14
15
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/arm_gicv3.c
18
+++ b/hw/intc/arm_gicv3.c
19
@@ -XXX,XX +XXX,XX @@ static void gicv3_redist_update_noirqset(GICv3CPUState *cs)
20
}
21
22
if ((cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) && cs->gic->lpi_enable &&
23
+ (cs->gic->gicd_ctlr & GICD_CTLR_EN_GRP1NS) &&
24
(cs->hpplpi.prio != 0xff)) {
25
if (irqbetter(cs, cs->hpplpi.irq, cs->hpplpi.prio)) {
26
cs->hppi.irq = cs->hpplpi.irq;
27
--
28
2.25.1
29
30
diff view generated by jsdifflib
New patch
1
The list of #defines for the ITS command packet numbers is neither
2
in alphabetical nor numeric order. Sort it into numeric order.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220122182444.724087-8-peter.maydell@linaro.org
8
---
9
hw/intc/gicv3_internal.h | 10 +++++-----
10
1 file changed, 5 insertions(+), 5 deletions(-)
11
12
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/intc/gicv3_internal.h
15
+++ b/hw/intc/gicv3_internal.h
16
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, CIL, 36, 1)
17
#define CMD_MASK 0xff
18
19
/* ITS Commands */
20
-#define GITS_CMD_CLEAR 0x04
21
-#define GITS_CMD_DISCARD 0x0F
22
#define GITS_CMD_INT 0x03
23
-#define GITS_CMD_MAPC 0x09
24
+#define GITS_CMD_CLEAR 0x04
25
+#define GITS_CMD_SYNC 0x05
26
#define GITS_CMD_MAPD 0x08
27
-#define GITS_CMD_MAPI 0x0B
28
+#define GITS_CMD_MAPC 0x09
29
#define GITS_CMD_MAPTI 0x0A
30
+#define GITS_CMD_MAPI 0x0B
31
#define GITS_CMD_INV 0x0C
32
#define GITS_CMD_INVALL 0x0D
33
-#define GITS_CMD_SYNC 0x05
34
+#define GITS_CMD_DISCARD 0x0F
35
36
/* MAPC command fields */
37
#define ICID_LENGTH 16
38
--
39
2.25.1
40
41
diff view generated by jsdifflib
1
From: David Engraf <david.engraf@sysgo.com>
1
The ITS-related parts of the redistributor code make some checks for
2
whether registers like GICR_PROPBASER and GICR_PENDBASER are zero.
3
There is no requirement in the specification for treating zeroes in
4
these address registers specially -- they contain guest physical
5
addresses and it is entirely valid (if unusual) for the guest to
6
choose to put the tables they address at guest physical address zero.
7
We use these values only to calculate guest addresses, and attempts
8
by the guest to use a bad address will be handled by the
9
address_space_* functions which we use to do the loads and stores.
2
10
3
Using the whole 128 MiB flash in non-secure mode is not working because
11
Remove the unnecessary checks.
4
virt_flash_fdt() expects the same address for secure_sysmem and sysmem.
5
This is not correctly handled by caller because it forwards NULL for
6
secure_sysmem in non-secure flash mode.
7
12
8
Fixed by using sysmem when secure_sysmem is NULL.
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220122182444.724087-9-peter.maydell@linaro.org
16
---
17
hw/intc/arm_gicv3_redist.c | 8 +++-----
18
1 file changed, 3 insertions(+), 5 deletions(-)
9
19
10
Signed-off-by: David Engraf <david.engraf@sysgo.com>
20
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
11
Message-id: 20190712075002.14326-1-david.engraf@sysgo.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/arm/virt.c | 2 +-
16
1 file changed, 1 insertion(+), 1 deletion(-)
17
18
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
19
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/virt.c
22
--- a/hw/intc/arm_gicv3_redist.c
21
+++ b/hw/arm/virt.c
23
+++ b/hw/intc/arm_gicv3_redist.c
22
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
24
@@ -XXX,XX +XXX,XX @@ void gicv3_redist_update_lpi_only(GICv3CPUState *cs)
23
&machine->device_memory->mr);
25
idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS),
26
GICD_TYPER_IDBITS);
27
28
- if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser ||
29
- !cs->gicr_pendbaser) {
30
+ if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS)) {
31
return;
24
}
32
}
25
33
26
- virt_flash_fdt(vms, sysmem, secure_sysmem);
34
@@ -XXX,XX +XXX,XX @@ void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level)
27
+ virt_flash_fdt(vms, sysmem, secure_sysmem ?: sysmem);
35
idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS),
28
36
GICD_TYPER_IDBITS);
29
create_gic(vms, pic);
37
38
- if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser ||
39
- !cs->gicr_pendbaser || (irq > (1ULL << (idbits + 1)) - 1) ||
40
- irq < GICV3_LPI_INTID_START) {
41
+ if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) ||
42
+ (irq > (1ULL << (idbits + 1)) - 1) || irq < GICV3_LPI_INTID_START) {
43
return;
44
}
30
45
31
--
46
--
32
2.20.1
47
2.25.1
33
48
34
49
diff view generated by jsdifflib
New patch
1
The GICR_CTLR.CES bit is a read-only bit which is set to 1 to indicate
2
that the GICR_CTLR.EnableLPIs bit can be written to 0 to disable
3
LPIs (as opposed to allowing LPIs to be enabled but not subsequently
4
disabled). Our implementation permits this, so advertise it
5
by setting CES to 1.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220122182444.724087-10-peter.maydell@linaro.org
10
---
11
hw/intc/gicv3_internal.h | 1 +
12
hw/intc/arm_gicv3_common.c | 4 ++++
13
2 files changed, 5 insertions(+)
14
15
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/gicv3_internal.h
18
+++ b/hw/intc/gicv3_internal.h
19
@@ -XXX,XX +XXX,XX @@
20
#define GICR_NSACR (GICR_SGI_OFFSET + 0x0E00)
21
22
#define GICR_CTLR_ENABLE_LPIS (1U << 0)
23
+#define GICR_CTLR_CES (1U << 1)
24
#define GICR_CTLR_RWP (1U << 3)
25
#define GICR_CTLR_DPG0 (1U << 24)
26
#define GICR_CTLR_DPG1NS (1U << 25)
27
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/intc/arm_gicv3_common.c
30
+++ b/hw/intc/arm_gicv3_common.c
31
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_reset(DeviceState *dev)
32
33
cs->level = 0;
34
cs->gicr_ctlr = 0;
35
+ if (s->lpi_enable) {
36
+ /* Our implementation supports clearing GICR_CTLR.EnableLPIs */
37
+ cs->gicr_ctlr |= GICR_CTLR_CES;
38
+ }
39
cs->gicr_statusr[GICV3_S] = 0;
40
cs->gicr_statusr[GICV3_NS] = 0;
41
cs->gicr_waker = GICR_WAKER_ProcessorSleep | GICR_WAKER_ChildrenAsleep;
42
--
43
2.25.1
44
45
diff view generated by jsdifflib
New patch
1
The MemoryRegionOps gicv3_its_translation_ops currently provides only
2
a .write_with_attrs function, because the only register in this
3
region is the write-only GITS_TRANSLATER. However, if you don't
4
provide a read function and the guest tries reading from this memory
5
region, QEMU will crash because
6
memory_region_read_with_attrs_accessor() calls a NULL pointer.
1
7
8
Add a read function which always returns 0, to cover both bogus
9
attempts to read GITS_TRANSLATER and also reads from the rest of the
10
region, which is documented to be reserved, RES0.
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220122182444.724087-11-peter.maydell@linaro.org
16
---
17
hw/intc/arm_gicv3_its.c | 13 +++++++++++++
18
1 file changed, 13 insertions(+)
19
20
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/intc/arm_gicv3_its.c
23
+++ b/hw/intc/arm_gicv3_its.c
24
@@ -XXX,XX +XXX,XX @@ static void extract_cmdq_params(GICv3ITSState *s)
25
}
26
}
27
28
+static MemTxResult gicv3_its_translation_read(void *opaque, hwaddr offset,
29
+ uint64_t *data, unsigned size,
30
+ MemTxAttrs attrs)
31
+{
32
+ /*
33
+ * GITS_TRANSLATER is write-only, and all other addresses
34
+ * in the interrupt translation space frame are RES0.
35
+ */
36
+ *data = 0;
37
+ return MEMTX_OK;
38
+}
39
+
40
static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset,
41
uint64_t data, unsigned size,
42
MemTxAttrs attrs)
43
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps gicv3_its_control_ops = {
44
};
45
46
static const MemoryRegionOps gicv3_its_translation_ops = {
47
+ .read_with_attrs = gicv3_its_translation_read,
48
.write_with_attrs = gicv3_its_translation_write,
49
.valid.min_access_size = 2,
50
.valid.max_access_size = 4,
51
--
52
2.25.1
53
54
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
The ITS has a bank of 8 GITS_BASER<n> registers, which allow the
2
guest to specify the base address of various data tables. Each
3
register has a read-only type field indicating which table it is for
4
and a read-write field where the guest can write in the base address
5
(among other things). We currently allow the guest to write the
6
writeable fields for all eight registers, even if the type field is 0
7
indicating "Unimplemented". This means the guest can provoke QEMU
8
into asserting by writing an address into one of these unimplemented
9
base registers, which bypasses the "if (!value) continue" check in
10
extract_table_params() and lets us hit the assertion that the type
11
field is one of the permitted table types.
2
12
3
Reading the RX_DATA register when the RX_FIFO is empty triggers
13
Prevent the assertion by not allowing the guest to write to the
4
an abort. This can be easily reproduced:
14
unimplemented base registers. This means their value will remain 0
15
and extract_table_params() will ignore them.
5
16
6
$ qemu-system-arm -M emcraft-sf2 -monitor stdio -S
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
QEMU 4.0.50 monitor - type 'help' for more information
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
(qemu) x 0x40001010
19
Message-id: 20220122182444.724087-12-peter.maydell@linaro.org
9
Aborted (core dumped)
20
---
21
hw/intc/arm_gicv3_its.c | 8 ++++++++
22
1 file changed, 8 insertions(+)
10
23
11
(gdb) bt
24
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
12
#1 0x00007f035874f895 in abort () at /lib64/libc.so.6
13
#2 0x00005628686591ff in fifo8_pop (fifo=0x56286a9a4c68) at util/fifo8.c:66
14
#3 0x00005628683e0b8e in fifo32_pop (fifo=0x56286a9a4c68) at include/qemu/fifo32.h:137
15
#4 0x00005628683e0efb in spi_read (opaque=0x56286a9a4850, addr=4, size=4) at hw/ssi/mss-spi.c:168
16
#5 0x0000562867f96801 in memory_region_read_accessor (mr=0x56286a9a4b60, addr=16, value=0x7ffeecb0c5c8, size=4, shift=0, mask=4294967295, attrs=...) at memory.c:439
17
#6 0x0000562867f96cdb in access_with_adjusted_size (addr=16, value=0x7ffeecb0c5c8, size=4, access_size_min=1, access_size_max=4, access_fn=0x562867f967c3 <memory_region_read_accessor>, mr=0x56286a9a4b60, attrs=...) at memory.c:569
18
#7 0x0000562867f99940 in memory_region_dispatch_read1 (mr=0x56286a9a4b60, addr=16, pval=0x7ffeecb0c5c8, size=4, attrs=...) at memory.c:1420
19
#8 0x0000562867f99a08 in memory_region_dispatch_read (mr=0x56286a9a4b60, addr=16, pval=0x7ffeecb0c5c8, size=4, attrs=...) at memory.c:1447
20
#9 0x0000562867f38721 in flatview_read_continue (fv=0x56286aec6360, addr=1073745936, attrs=..., buf=0x7ffeecb0c7c0 "\340ǰ\354\376\177", len=4, addr1=16, l=4, mr=0x56286a9a4b60) at exec.c:3385
21
#10 0x0000562867f38874 in flatview_read (fv=0x56286aec6360, addr=1073745936, attrs=..., buf=0x7ffeecb0c7c0 "\340ǰ\354\376\177", len=4) at exec.c:3423
22
#11 0x0000562867f388ea in address_space_read_full (as=0x56286aa3e890, addr=1073745936, attrs=..., buf=0x7ffeecb0c7c0 "\340ǰ\354\376\177", len=4) at exec.c:3436
23
#12 0x0000562867f389c5 in address_space_rw (as=0x56286aa3e890, addr=1073745936, attrs=..., buf=0x7ffeecb0c7c0 "\340ǰ\354\376\177", len=4, is_write=false) at exec.c:3466
24
#13 0x0000562867f3bdd7 in cpu_memory_rw_debug (cpu=0x56286aa19d00, addr=1073745936, buf=0x7ffeecb0c7c0 "\340ǰ\354\376\177", len=4, is_write=0) at exec.c:3976
25
#14 0x000056286811ed51 in memory_dump (mon=0x56286a8c32d0, count=1, format=120, wsize=4, addr=1073745936, is_physical=0) at monitor/misc.c:730
26
#15 0x000056286811eff1 in hmp_memory_dump (mon=0x56286a8c32d0, qdict=0x56286b15c400) at monitor/misc.c:785
27
#16 0x00005628684740ee in handle_hmp_command (mon=0x56286a8c32d0, cmdline=0x56286a8caeb2 "0x40001010") at monitor/hmp.c:1082
28
29
From the datasheet "Actel SmartFusion Microcontroller Subsystem
30
User's Guide" Rev.1, Table 13-3 "SPI Register Summary", this
31
register has a reset value of 0.
32
33
Check the FIFO is not empty before accessing it, else log an
34
error message.
35
36
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
37
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
38
Message-id: 20190709113715.7761-3-philmd@redhat.com
39
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
40
---
41
hw/ssi/mss-spi.c | 8 +++++++-
42
1 file changed, 7 insertions(+), 1 deletion(-)
43
44
diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
45
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/ssi/mss-spi.c
26
--- a/hw/intc/arm_gicv3_its.c
47
+++ b/hw/ssi/mss-spi.c
27
+++ b/hw/intc/arm_gicv3_its.c
48
@@ -XXX,XX +XXX,XX @@ spi_read(void *opaque, hwaddr addr, unsigned int size)
28
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
49
case R_SPI_RX:
29
if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
50
s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
30
index = (offset - GITS_BASER) / 8;
51
s->regs[R_SPI_STATUS] &= ~S_RXCHOVRF;
31
52
- ret = fifo32_pop(&s->rx_fifo);
32
+ if (s->baser[index] == 0) {
53
+ if (fifo32_is_empty(&s->rx_fifo)) {
33
+ /* Unimplemented GITS_BASERn: RAZ/WI */
54
+ qemu_log_mask(LOG_GUEST_ERROR,
34
+ break;
55
+ "%s: Reading empty RX_FIFO\n",
35
+ }
56
+ __func__);
36
if (offset & 7) {
57
+ } else {
37
value <<= 32;
58
+ ret = fifo32_pop(&s->rx_fifo);
38
value &= ~GITS_BASER_RO_MASK;
59
+ }
39
@@ -XXX,XX +XXX,XX @@ static bool its_writell(GICv3ITSState *s, hwaddr offset,
60
if (fifo32_is_empty(&s->rx_fifo)) {
40
*/
61
s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
41
if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
42
index = (offset - GITS_BASER) / 8;
43
+ if (s->baser[index] == 0) {
44
+ /* Unimplemented GITS_BASERn: RAZ/WI */
45
+ break;
46
+ }
47
s->baser[index] &= GITS_BASER_RO_MASK;
48
s->baser[index] |= (value & ~GITS_BASER_RO_MASK);
62
}
49
}
63
--
50
--
64
2.20.1
51
2.25.1
65
52
66
53
diff view generated by jsdifflib
1
The ARMv5 architecture didn't specify detailed per-feature ID
1
Currently when we fill in a TableDesc based on the value the guest
2
registers. Now that we're using the MVFR0 register fields to
2
has written to the GITS_BASER<n> register, we calculate both:
3
gate the existence of VFP instructions, we need to set up
3
* num_entries : the number of entries in the table, constrained
4
the correct values in the cpu->isar structure so that we still
4
by the amount of memory the guest has given it
5
provide an FPU to the guest.
5
* num_ids : the number of IDs we support for this table,
6
constrained by the implementation choices and the architecture
7
(eg DeviceIDs are 16 bits, so num_ids is 1 << 16)
6
8
7
This fixes a regression in the arm926 and arm1026 CPUs, which
9
When validating ITS commands, however, we check only num_ids,
8
are the only ones that both have VFP and are ARMv5 or earlier.
10
thus allowing a broken guest to specify table entries that
9
This regression was introduced by the VFP refactoring, and more
11
index off the end of it. This will only corrupt guest memory,
10
specifically by commits 1120827fa182f0e76 and 266bd25c485597c,
12
but the ITS is supposed to reject such commands as invalid.
11
which accidentally disabled VFP short-vector support and
12
double-precision support on these CPUs.
13
13
14
Fixes: 1120827fa182f0e
14
Instead of calculating both num_entries and num_ids, set
15
Fixes: 266bd25c485597c
15
num_entries to the minimum of the two limits, and check that.
16
Fixes: https://bugs.launchpad.net/qemu/+bug/1836192
16
17
Reported-by: Christophe Lyon <christophe.lyon@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
19
Message-id: 20220122182444.724087-13-peter.maydell@linaro.org
21
Tested-by: Christophe Lyon <christophe.lyon@linaro.org>
22
Message-id: 20190711131241.22231-1-peter.maydell@linaro.org
23
---
20
---
24
target/arm/cpu.c | 12 ++++++++++++
21
include/hw/intc/arm_gicv3_its_common.h | 1 -
25
1 file changed, 12 insertions(+)
22
hw/intc/arm_gicv3_its.c | 18 +++++++++---------
23
2 files changed, 9 insertions(+), 10 deletions(-)
26
24
27
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
25
diff --git a/include/hw/intc/arm_gicv3_its_common.h b/include/hw/intc/arm_gicv3_its_common.h
28
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu.c
27
--- a/include/hw/intc/arm_gicv3_its_common.h
30
+++ b/target/arm/cpu.c
28
+++ b/include/hw/intc/arm_gicv3_its_common.h
31
@@ -XXX,XX +XXX,XX @@ static void arm926_initfn(Object *obj)
29
@@ -XXX,XX +XXX,XX @@ typedef struct {
32
* set the field to indicate Jazelle support within QEMU.
30
uint16_t entry_sz;
33
*/
31
uint32_t page_sz;
34
cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
32
uint32_t num_entries;
35
+ /*
33
- uint32_t num_ids;
36
+ * Similarly, we need to set MVFR0 fields to enable double precision
34
uint64_t base_addr;
37
+ * and short vector support even though ARMv5 doesn't have this register.
35
} TableDesc;
38
+ */
36
39
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
37
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
40
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1);
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/intc/arm_gicv3_its.c
40
+++ b/hw/intc/arm_gicv3_its.c
41
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_its_cmd(GICv3ITSState *s, uint64_t value,
42
43
eventid = (value & EVENTID_MASK);
44
45
- if (devid >= s->dt.num_ids) {
46
+ if (devid >= s->dt.num_entries) {
47
qemu_log_mask(LOG_GUEST_ERROR,
48
"%s: invalid command attributes: devid %d>=%d",
49
- __func__, devid, s->dt.num_ids);
50
+ __func__, devid, s->dt.num_entries);
51
return CMD_CONTINUE;
52
}
53
54
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_its_cmd(GICv3ITSState *s, uint64_t value,
55
return CMD_CONTINUE;
56
}
57
58
- if (icid >= s->ct.num_ids) {
59
+ if (icid >= s->ct.num_entries) {
60
qemu_log_mask(LOG_GUEST_ERROR,
61
"%s: invalid ICID 0x%x in ITE (table corrupted?)\n",
62
__func__, icid);
63
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_mapti(GICv3ITSState *s, uint64_t value,
64
65
icid = value & ICID_MASK;
66
67
- if (devid >= s->dt.num_ids) {
68
+ if (devid >= s->dt.num_entries) {
69
qemu_log_mask(LOG_GUEST_ERROR,
70
"%s: invalid command attributes: devid %d>=%d",
71
- __func__, devid, s->dt.num_ids);
72
+ __func__, devid, s->dt.num_entries);
73
return CMD_CONTINUE;
74
}
75
76
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_mapti(GICv3ITSState *s, uint64_t value,
77
num_eventids = 1ULL << (FIELD_EX64(dte, DTE, SIZE) + 1);
78
num_intids = 1ULL << (GICD_TYPER_IDBITS + 1);
79
80
- if ((icid >= s->ct.num_ids)
81
+ if ((icid >= s->ct.num_entries)
82
|| !dte_valid || (eventid >= num_eventids) ||
83
(((pIntid < GICV3_LPI_INTID_START) || (pIntid >= num_intids)) &&
84
(pIntid != INTID_SPURIOUS))) {
85
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_mapc(GICv3ITSState *s, uint32_t offset)
86
87
valid = (value & CMD_FIELD_VALID_MASK);
88
89
- if ((icid >= s->ct.num_ids) || (rdbase >= s->gicv3->num_cpu)) {
90
+ if ((icid >= s->ct.num_entries) || (rdbase >= s->gicv3->num_cpu)) {
91
qemu_log_mask(LOG_GUEST_ERROR,
92
"ITS MAPC: invalid collection table attributes "
93
"icid %d rdbase %" PRIu64 "\n", icid, rdbase);
94
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_mapd(GICv3ITSState *s, uint64_t value,
95
96
valid = (value & CMD_FIELD_VALID_MASK);
97
98
- if ((devid >= s->dt.num_ids) ||
99
+ if ((devid >= s->dt.num_entries) ||
100
(size > FIELD_EX64(s->typer, GITS_TYPER, IDBITS))) {
101
qemu_log_mask(LOG_GUEST_ERROR,
102
"ITS MAPD: invalid device table attributes "
103
@@ -XXX,XX +XXX,XX @@ static void extract_table_params(GICv3ITSState *s)
104
L1TABLE_ENTRY_SIZE) *
105
(page_sz / td->entry_sz));
106
}
107
- td->num_ids = 1ULL << idbits;
108
+ td->num_entries = MIN(td->num_entries, 1ULL << idbits);
109
}
41
}
110
}
42
111
43
static void arm946_initfn(Object *obj)
44
@@ -XXX,XX +XXX,XX @@ static void arm1026_initfn(Object *obj)
45
* set the field to indicate Jazelle support within QEMU.
46
*/
47
cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
48
+ /*
49
+ * Similarly, we need to set MVFR0 fields to enable double precision
50
+ * and short vector support even though ARMv5 doesn't have this register.
51
+ */
52
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
53
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1);
54
55
{
56
/* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */
57
--
112
--
58
2.20.1
113
2.25.1
59
114
60
115
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
Implement the ITS MOVALL command, which takes all the pending
2
interrupts on a source redistributor and makes the not-pending on
3
that source redistributor and pending on a destination redistributor.
2
4
3
Lei Sun found while auditing the code that a CPU write would
5
This is a GICv3 ITS command which we forgot to implement. (It is
4
trigger a NULL pointer dereference.
6
not used by Linux guests.)
5
7
6
>From UG1085 datasheet [*] AXI writes in this region are ignored
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
and generates an AXI Slave Error (SLVERR).
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220122182444.724087-14-peter.maydell@linaro.org
11
---
12
hw/intc/gicv3_internal.h | 16 +++++++++++
13
hw/intc/arm_gicv3_its.c | 55 ++++++++++++++++++++++++++++++++++++++
14
hw/intc/arm_gicv3_redist.c | 54 +++++++++++++++++++++++++++++++++++++
15
3 files changed, 125 insertions(+)
8
16
9
Fix by implementing the write_with_attrs() handler.
17
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
10
Return MEMTX_ERROR when the region is accessed (this error maps
11
to an AXI slave error).
12
13
[*] https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf
14
15
Reported-by: Lei Sun <slei.casper@gmail.com>
16
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
17
Tested-by: Francisco Iglesias <frasse.iglesias@gmail.com>
18
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
21
hw/ssi/xilinx_spips.c | 16 ++++++++++++++++
22
1 file changed, 16 insertions(+)
23
24
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
25
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/ssi/xilinx_spips.c
19
--- a/hw/intc/gicv3_internal.h
27
+++ b/hw/ssi/xilinx_spips.c
20
+++ b/hw/intc/gicv3_internal.h
28
@@ -XXX,XX +XXX,XX @@ static MemTxResult lqspi_read(void *opaque, hwaddr addr, uint64_t *value,
21
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, CIL, 36, 1)
29
return lqspi_read(opaque, addr, value, size, attrs);
22
#define GITS_CMD_MAPI 0x0B
23
#define GITS_CMD_INV 0x0C
24
#define GITS_CMD_INVALL 0x0D
25
+#define GITS_CMD_MOVALL 0x0E
26
#define GITS_CMD_DISCARD 0x0F
27
28
/* MAPC command fields */
29
@@ -XXX,XX +XXX,XX @@ FIELD(MAPC, RDBASE, 16, 32)
30
#define L2_TABLE_VALID_MASK CMD_FIELD_VALID_MASK
31
#define TABLE_ENTRY_VALID_MASK (1ULL << 0)
32
33
+/* MOVALL command fields */
34
+FIELD(MOVALL_2, RDBASE1, 16, 36)
35
+FIELD(MOVALL_3, RDBASE2, 16, 36)
36
+
37
/*
38
* 12 bytes Interrupt translation Table Entry size
39
* as per Table 5.3 in GICv3 spec
40
@@ -XXX,XX +XXX,XX @@ void gicv3_redist_update_lpi(GICv3CPUState *cs);
41
* an incoming migration has loaded new state.
42
*/
43
void gicv3_redist_update_lpi_only(GICv3CPUState *cs);
44
+/**
45
+ * gicv3_redist_movall_lpis:
46
+ * @src: source redistributor
47
+ * @dest: destination redistributor
48
+ *
49
+ * Scan the LPI pending table for @src, and for each pending LPI there
50
+ * mark it as not-pending for @src and pending for @dest, as required
51
+ * by the ITS MOVALL command.
52
+ */
53
+void gicv3_redist_movall_lpis(GICv3CPUState *src, GICv3CPUState *dest);
54
+
55
void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns);
56
void gicv3_init_cpuif(GICv3State *s);
57
58
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/hw/intc/arm_gicv3_its.c
61
+++ b/hw/intc/arm_gicv3_its.c
62
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_mapd(GICv3ITSState *s, uint64_t value,
63
return update_dte(s, devid, valid, size, itt_addr) ? CMD_CONTINUE : CMD_STALL;
30
}
64
}
31
65
32
+static MemTxResult lqspi_write(void *opaque, hwaddr offset, uint64_t value,
66
+static ItsCmdResult process_movall(GICv3ITSState *s, uint64_t value,
33
+ unsigned size, MemTxAttrs attrs)
67
+ uint32_t offset)
68
+{
69
+ AddressSpace *as = &s->gicv3->dma_as;
70
+ MemTxResult res = MEMTX_OK;
71
+ uint64_t rd1, rd2;
72
+
73
+ /* No fields in dwords 0 or 1 */
74
+ offset += NUM_BYTES_IN_DW;
75
+ offset += NUM_BYTES_IN_DW;
76
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
77
+ MEMTXATTRS_UNSPECIFIED, &res);
78
+ if (res != MEMTX_OK) {
79
+ return CMD_STALL;
80
+ }
81
+
82
+ rd1 = FIELD_EX64(value, MOVALL_2, RDBASE1);
83
+ if (rd1 >= s->gicv3->num_cpu) {
84
+ qemu_log_mask(LOG_GUEST_ERROR,
85
+ "%s: RDBASE1 %" PRId64
86
+ " out of range (must be less than %d)\n",
87
+ __func__, rd1, s->gicv3->num_cpu);
88
+ return CMD_CONTINUE;
89
+ }
90
+
91
+ offset += NUM_BYTES_IN_DW;
92
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
93
+ MEMTXATTRS_UNSPECIFIED, &res);
94
+ if (res != MEMTX_OK) {
95
+ return CMD_STALL;
96
+ }
97
+
98
+ rd2 = FIELD_EX64(value, MOVALL_3, RDBASE2);
99
+ if (rd2 >= s->gicv3->num_cpu) {
100
+ qemu_log_mask(LOG_GUEST_ERROR,
101
+ "%s: RDBASE2 %" PRId64
102
+ " out of range (must be less than %d)\n",
103
+ __func__, rd2, s->gicv3->num_cpu);
104
+ return CMD_CONTINUE;
105
+ }
106
+
107
+ if (rd1 == rd2) {
108
+ /* Move to same target must succeed as a no-op */
109
+ return CMD_CONTINUE;
110
+ }
111
+
112
+ /* Move all pending LPIs from redistributor 1 to redistributor 2 */
113
+ gicv3_redist_movall_lpis(&s->gicv3->cpu[rd1], &s->gicv3->cpu[rd2]);
114
+
115
+ return CMD_CONTINUE;
116
+}
117
+
118
/*
119
* Current implementation blocks until all
120
* commands are processed
121
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
122
gicv3_redist_update_lpi(&s->gicv3->cpu[i]);
123
}
124
break;
125
+ case GITS_CMD_MOVALL:
126
+ result = process_movall(s, data, cq_offset);
127
+ break;
128
default:
129
break;
130
}
131
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/hw/intc/arm_gicv3_redist.c
134
+++ b/hw/intc/arm_gicv3_redist.c
135
@@ -XXX,XX +XXX,XX @@ void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level)
136
gicv3_redist_lpi_pending(cs, irq, level);
137
}
138
139
+void gicv3_redist_movall_lpis(GICv3CPUState *src, GICv3CPUState *dest)
34
+{
140
+{
35
+ /*
141
+ /*
36
+ * From UG1085, Chapter 24 (Quad-SPI controllers):
142
+ * We must move all pending LPIs from the source redistributor
37
+ * - Writes are ignored
143
+ * to the destination. That is, for every pending LPI X on
38
+ * - AXI writes generate an external AXI slave error (SLVERR)
144
+ * src, we must set it not-pending on src and pending on dest.
145
+ * LPIs that are already pending on dest are not cleared.
146
+ *
147
+ * If LPIs are disabled on dest this is CONSTRAINED UNPREDICTABLE:
148
+ * we choose to NOP. If LPIs are disabled on source there's nothing
149
+ * to be transferred anyway.
39
+ */
150
+ */
40
+ qemu_log_mask(LOG_GUEST_ERROR, "%s Unexpected %u-bit access to 0x%" PRIx64
151
+ AddressSpace *as = &src->gic->dma_as;
41
+ " (value: 0x%" PRIx64 "\n",
152
+ uint64_t idbits;
42
+ __func__, size << 3, offset, value);
153
+ uint32_t pendt_size;
154
+ uint64_t src_baddr, dest_baddr;
155
+ int i;
43
+
156
+
44
+ return MEMTX_ERROR;
157
+ if (!(src->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) ||
158
+ !(dest->gicr_ctlr & GICR_CTLR_ENABLE_LPIS)) {
159
+ return;
160
+ }
161
+
162
+ idbits = MIN(FIELD_EX64(src->gicr_propbaser, GICR_PROPBASER, IDBITS),
163
+ GICD_TYPER_IDBITS);
164
+ idbits = MIN(FIELD_EX64(dest->gicr_propbaser, GICR_PROPBASER, IDBITS),
165
+ idbits);
166
+
167
+ pendt_size = 1ULL << (idbits + 1);
168
+ src_baddr = src->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
169
+ dest_baddr = dest->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
170
+
171
+ for (i = GICV3_LPI_INTID_START / 8; i < pendt_size / 8; i++) {
172
+ uint8_t src_pend, dest_pend;
173
+
174
+ address_space_read(as, src_baddr + i, MEMTXATTRS_UNSPECIFIED,
175
+ &src_pend, sizeof(src_pend));
176
+ if (!src_pend) {
177
+ continue;
178
+ }
179
+ address_space_read(as, dest_baddr + i, MEMTXATTRS_UNSPECIFIED,
180
+ &dest_pend, sizeof(dest_pend));
181
+ dest_pend |= src_pend;
182
+ src_pend = 0;
183
+ address_space_write(as, src_baddr + i, MEMTXATTRS_UNSPECIFIED,
184
+ &src_pend, sizeof(src_pend));
185
+ address_space_write(as, dest_baddr + i, MEMTXATTRS_UNSPECIFIED,
186
+ &dest_pend, sizeof(dest_pend));
187
+ }
188
+
189
+ gicv3_redist_update_lpi(src);
190
+ gicv3_redist_update_lpi(dest);
45
+}
191
+}
46
+
192
+
47
static const MemoryRegionOps lqspi_ops = {
193
void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level)
48
.read_with_attrs = lqspi_read,
194
{
49
+ .write_with_attrs = lqspi_write,
195
/* Update redistributor state for a change in an external PPI input line */
50
.endianness = DEVICE_NATIVE_ENDIAN,
51
.valid = {
52
.min_access_size = 1,
53
--
196
--
54
2.20.1
197
2.25.1
55
198
56
199
diff view generated by jsdifflib
New patch
1
1
Implement the ITS MOVI command. This command specifies a (physical) LPI
2
by DeviceID and EventID and provides a new ICID for it. The ITS must
3
find the interrupt translation table entry for the LPI, which will
4
tell it the old ICID. It then moves the pending state of the LPI from
5
the old redistributor to the new one and updates the ICID field in
6
the translation table entry.
7
8
This is another GICv3 ITS command that we forgot to implement. Linux
9
does use this one, but only if the guest powers off one of its CPUs.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20220122182444.724087-15-peter.maydell@linaro.org
14
---
15
hw/intc/gicv3_internal.h | 16 ++++
16
hw/intc/arm_gicv3_its.c | 146 +++++++++++++++++++++++++++++++++++++
17
hw/intc/arm_gicv3_redist.c | 53 ++++++++++++++
18
3 files changed, 215 insertions(+)
19
20
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/intc/gicv3_internal.h
23
+++ b/hw/intc/gicv3_internal.h
24
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, CIL, 36, 1)
25
#define CMD_MASK 0xff
26
27
/* ITS Commands */
28
+#define GITS_CMD_MOVI 0x01
29
#define GITS_CMD_INT 0x03
30
#define GITS_CMD_CLEAR 0x04
31
#define GITS_CMD_SYNC 0x05
32
@@ -XXX,XX +XXX,XX @@ FIELD(MAPC, RDBASE, 16, 32)
33
FIELD(MOVALL_2, RDBASE1, 16, 36)
34
FIELD(MOVALL_3, RDBASE2, 16, 36)
35
36
+/* MOVI command fields */
37
+FIELD(MOVI_0, DEVICEID, 32, 32)
38
+FIELD(MOVI_1, EVENTID, 0, 32)
39
+FIELD(MOVI_2, ICID, 0, 16)
40
+
41
/*
42
* 12 bytes Interrupt translation Table Entry size
43
* as per Table 5.3 in GICv3 spec
44
@@ -XXX,XX +XXX,XX @@ void gicv3_redist_update_lpi(GICv3CPUState *cs);
45
* an incoming migration has loaded new state.
46
*/
47
void gicv3_redist_update_lpi_only(GICv3CPUState *cs);
48
+/**
49
+ * gicv3_redist_mov_lpi:
50
+ * @src: source redistributor
51
+ * @dest: destination redistributor
52
+ * @irq: LPI to update
53
+ *
54
+ * Move the pending state of the specified LPI from @src to @dest,
55
+ * as required by the ITS MOVI command.
56
+ */
57
+void gicv3_redist_mov_lpi(GICv3CPUState *src, GICv3CPUState *dest, int irq);
58
/**
59
* gicv3_redist_movall_lpis:
60
* @src: source redistributor
61
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/intc/arm_gicv3_its.c
64
+++ b/hw/intc/arm_gicv3_its.c
65
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_movall(GICv3ITSState *s, uint64_t value,
66
return CMD_CONTINUE;
67
}
68
69
+static ItsCmdResult process_movi(GICv3ITSState *s, uint64_t value,
70
+ uint32_t offset)
71
+{
72
+ AddressSpace *as = &s->gicv3->dma_as;
73
+ MemTxResult res = MEMTX_OK;
74
+ uint32_t devid, eventid, intid;
75
+ uint16_t old_icid, new_icid;
76
+ uint64_t old_cte, new_cte;
77
+ uint64_t old_rdbase, new_rdbase;
78
+ uint64_t dte;
79
+ bool dte_valid, ite_valid, cte_valid;
80
+ uint64_t num_eventids;
81
+ IteEntry ite = {};
82
+
83
+ devid = FIELD_EX64(value, MOVI_0, DEVICEID);
84
+
85
+ offset += NUM_BYTES_IN_DW;
86
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
87
+ MEMTXATTRS_UNSPECIFIED, &res);
88
+ if (res != MEMTX_OK) {
89
+ return CMD_STALL;
90
+ }
91
+ eventid = FIELD_EX64(value, MOVI_1, EVENTID);
92
+
93
+ offset += NUM_BYTES_IN_DW;
94
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
95
+ MEMTXATTRS_UNSPECIFIED, &res);
96
+ if (res != MEMTX_OK) {
97
+ return CMD_STALL;
98
+ }
99
+ new_icid = FIELD_EX64(value, MOVI_2, ICID);
100
+
101
+ if (devid >= s->dt.num_entries) {
102
+ qemu_log_mask(LOG_GUEST_ERROR,
103
+ "%s: invalid command attributes: devid %d>=%d",
104
+ __func__, devid, s->dt.num_entries);
105
+ return CMD_CONTINUE;
106
+ }
107
+ dte = get_dte(s, devid, &res);
108
+ if (res != MEMTX_OK) {
109
+ return CMD_STALL;
110
+ }
111
+
112
+ dte_valid = FIELD_EX64(dte, DTE, VALID);
113
+ if (!dte_valid) {
114
+ qemu_log_mask(LOG_GUEST_ERROR,
115
+ "%s: invalid command attributes: "
116
+ "invalid dte: %"PRIx64" for %d\n",
117
+ __func__, dte, devid);
118
+ return CMD_CONTINUE;
119
+ }
120
+
121
+ num_eventids = 1ULL << (FIELD_EX64(dte, DTE, SIZE) + 1);
122
+ if (eventid >= num_eventids) {
123
+ qemu_log_mask(LOG_GUEST_ERROR,
124
+ "%s: invalid command attributes: eventid %d >= %"
125
+ PRId64 "\n",
126
+ __func__, eventid, num_eventids);
127
+ return CMD_CONTINUE;
128
+ }
129
+
130
+ ite_valid = get_ite(s, eventid, dte, &old_icid, &intid, &res);
131
+ if (res != MEMTX_OK) {
132
+ return CMD_STALL;
133
+ }
134
+
135
+ if (!ite_valid) {
136
+ qemu_log_mask(LOG_GUEST_ERROR,
137
+ "%s: invalid command attributes: invalid ITE\n",
138
+ __func__);
139
+ return CMD_CONTINUE;
140
+ }
141
+
142
+ if (old_icid >= s->ct.num_entries) {
143
+ qemu_log_mask(LOG_GUEST_ERROR,
144
+ "%s: invalid ICID 0x%x in ITE (table corrupted?)\n",
145
+ __func__, old_icid);
146
+ return CMD_CONTINUE;
147
+ }
148
+
149
+ if (new_icid >= s->ct.num_entries) {
150
+ qemu_log_mask(LOG_GUEST_ERROR,
151
+ "%s: invalid command attributes: ICID 0x%x\n",
152
+ __func__, new_icid);
153
+ return CMD_CONTINUE;
154
+ }
155
+
156
+ cte_valid = get_cte(s, old_icid, &old_cte, &res);
157
+ if (res != MEMTX_OK) {
158
+ return CMD_STALL;
159
+ }
160
+ if (!cte_valid) {
161
+ qemu_log_mask(LOG_GUEST_ERROR,
162
+ "%s: invalid command attributes: "
163
+ "invalid cte: %"PRIx64"\n",
164
+ __func__, old_cte);
165
+ return CMD_CONTINUE;
166
+ }
167
+
168
+ cte_valid = get_cte(s, new_icid, &new_cte, &res);
169
+ if (res != MEMTX_OK) {
170
+ return CMD_STALL;
171
+ }
172
+ if (!cte_valid) {
173
+ qemu_log_mask(LOG_GUEST_ERROR,
174
+ "%s: invalid command attributes: "
175
+ "invalid cte: %"PRIx64"\n",
176
+ __func__, new_cte);
177
+ return CMD_CONTINUE;
178
+ }
179
+
180
+ old_rdbase = FIELD_EX64(old_cte, CTE, RDBASE);
181
+ if (old_rdbase >= s->gicv3->num_cpu) {
182
+ qemu_log_mask(LOG_GUEST_ERROR,
183
+ "%s: CTE has invalid rdbase 0x%"PRIx64"\n",
184
+ __func__, old_rdbase);
185
+ return CMD_CONTINUE;
186
+ }
187
+
188
+ new_rdbase = FIELD_EX64(new_cte, CTE, RDBASE);
189
+ if (new_rdbase >= s->gicv3->num_cpu) {
190
+ qemu_log_mask(LOG_GUEST_ERROR,
191
+ "%s: CTE has invalid rdbase 0x%"PRIx64"\n",
192
+ __func__, new_rdbase);
193
+ return CMD_CONTINUE;
194
+ }
195
+
196
+ if (old_rdbase != new_rdbase) {
197
+ /* Move the LPI from the old redistributor to the new one */
198
+ gicv3_redist_mov_lpi(&s->gicv3->cpu[old_rdbase],
199
+ &s->gicv3->cpu[new_rdbase],
200
+ intid);
201
+ }
202
+
203
+ /* Update the ICID field in the interrupt translation table entry */
204
+ ite.itel = FIELD_DP64(ite.itel, ITE_L, VALID, 1);
205
+ ite.itel = FIELD_DP64(ite.itel, ITE_L, INTTYPE, ITE_INTTYPE_PHYSICAL);
206
+ ite.itel = FIELD_DP64(ite.itel, ITE_L, INTID, intid);
207
+ ite.itel = FIELD_DP64(ite.itel, ITE_L, DOORBELL, INTID_SPURIOUS);
208
+ ite.iteh = FIELD_DP32(ite.iteh, ITE_H, ICID, new_icid);
209
+ return update_ite(s, eventid, dte, ite) ? CMD_CONTINUE : CMD_STALL;
210
+}
211
+
212
/*
213
* Current implementation blocks until all
214
* commands are processed
215
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
216
gicv3_redist_update_lpi(&s->gicv3->cpu[i]);
217
}
218
break;
219
+ case GITS_CMD_MOVI:
220
+ result = process_movi(s, data, cq_offset);
221
+ break;
222
case GITS_CMD_MOVALL:
223
result = process_movall(s, data, cq_offset);
224
break;
225
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
226
index XXXXXXX..XXXXXXX 100644
227
--- a/hw/intc/arm_gicv3_redist.c
228
+++ b/hw/intc/arm_gicv3_redist.c
229
@@ -XXX,XX +XXX,XX @@ void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level)
230
gicv3_redist_lpi_pending(cs, irq, level);
231
}
232
233
+void gicv3_redist_mov_lpi(GICv3CPUState *src, GICv3CPUState *dest, int irq)
234
+{
235
+ /*
236
+ * Move the specified LPI's pending state from the source redistributor
237
+ * to the destination.
238
+ *
239
+ * If LPIs are disabled on dest this is CONSTRAINED UNPREDICTABLE:
240
+ * we choose to NOP. If LPIs are disabled on source there's nothing
241
+ * to be transferred anyway.
242
+ */
243
+ AddressSpace *as = &src->gic->dma_as;
244
+ uint64_t idbits;
245
+ uint32_t pendt_size;
246
+ uint64_t src_baddr;
247
+ uint8_t src_pend;
248
+
249
+ if (!(src->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) ||
250
+ !(dest->gicr_ctlr & GICR_CTLR_ENABLE_LPIS)) {
251
+ return;
252
+ }
253
+
254
+ idbits = MIN(FIELD_EX64(src->gicr_propbaser, GICR_PROPBASER, IDBITS),
255
+ GICD_TYPER_IDBITS);
256
+ idbits = MIN(FIELD_EX64(dest->gicr_propbaser, GICR_PROPBASER, IDBITS),
257
+ idbits);
258
+
259
+ pendt_size = 1ULL << (idbits + 1);
260
+ if ((irq / 8) >= pendt_size) {
261
+ return;
262
+ }
263
+
264
+ src_baddr = src->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
265
+
266
+ address_space_read(as, src_baddr + (irq / 8),
267
+ MEMTXATTRS_UNSPECIFIED, &src_pend, sizeof(src_pend));
268
+ if (!extract32(src_pend, irq % 8, 1)) {
269
+ /* Not pending on source, nothing to do */
270
+ return;
271
+ }
272
+ src_pend &= ~(1 << (irq % 8));
273
+ address_space_write(as, src_baddr + (irq / 8),
274
+ MEMTXATTRS_UNSPECIFIED, &src_pend, sizeof(src_pend));
275
+ if (irq == src->hpplpi.irq) {
276
+ /*
277
+ * We just made this LPI not-pending so only need to update
278
+ * if it was previously the highest priority pending LPI
279
+ */
280
+ gicv3_redist_update_lpi(src);
281
+ }
282
+ /* Mark it pending on the destination */
283
+ gicv3_redist_lpi_pending(dest, irq, 1);
284
+}
285
+
286
void gicv3_redist_movall_lpis(GICv3CPUState *src, GICv3CPUState *dest)
287
{
288
/*
289
--
290
2.25.1
291
292
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Cédric Le Goater <clg@kaod.org>
2
2
3
When we converted to using feature bits in 602f6e42cfbf we missed out
3
Address should be 0x1E631000 and not 0x1E641000 as initially introduced.
4
the fact (dp && arm_dc_feature(s, ARM_FEATURE_V8)) was supported for
5
-cpu max configurations. This caused a regression in the GCC test
6
suite. Fix this by setting the appropriate bits in mvfr1.FPHP to
7
report ARMv8-A with FP support (but not ARMv8.2-FP16).
8
4
9
Fixes: https://bugs.launchpad.net/qemu/+bug/1836078
5
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/838
10
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
Fixes: f25c0ae1079d ("aspeed/soc: Add AST2600 support")
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Suggested-by: Troy Lee <troy_lee@aspeedtech.com>
12
Message-id: 20190711103737.10017-1-alex.bennee@linaro.org
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20220126083520.4135713-1-clg@kaod.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
12
---
15
target/arm/cpu.c | 4 ++++
13
hw/arm/aspeed_ast2600.c | 2 +-
16
1 file changed, 4 insertions(+)
14
1 file changed, 1 insertion(+), 1 deletion(-)
17
15
18
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.c
18
--- a/hw/arm/aspeed_ast2600.c
21
+++ b/target/arm/cpu.c
19
+++ b/hw/arm/aspeed_ast2600.c
22
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
23
t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
21
[ASPEED_DEV_PWM] = 0x1E610000,
24
cpu->isar.id_isar6 = t;
22
[ASPEED_DEV_FMC] = 0x1E620000,
25
23
[ASPEED_DEV_SPI1] = 0x1E630000,
26
+ t = cpu->isar.mvfr1;
24
- [ASPEED_DEV_SPI2] = 0x1E641000,
27
+ t = FIELD_DP32(t, MVFR1, FPHP, 2); /* v8.0 FP support */
25
+ [ASPEED_DEV_SPI2] = 0x1E631000,
28
+ cpu->isar.mvfr1 = t;
26
[ASPEED_DEV_EHCI1] = 0x1E6A1000,
29
+
27
[ASPEED_DEV_EHCI2] = 0x1E6A3000,
30
t = cpu->isar.mvfr2;
28
[ASPEED_DEV_MII1] = 0x1E650000,
31
t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
32
t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
33
--
29
--
34
2.20.1
30
2.25.1
35
31
36
32
diff view generated by jsdifflib
New patch
1
The exception caused by an SVC instruction may be taken to AArch32
2
Hyp mode for two reasons:
3
* HCR.TGE indicates that exceptions from EL0 should trap to EL2
4
* we were already in Hyp mode
1
5
6
The entrypoint in the vector table to be used differs in these two
7
cases: for an exception routed to Hyp mode from EL0, we enter at the
8
common 0x14 "hyp trap" entrypoint. For SVC from Hyp mode to Hyp
9
mode, we enter at the 0x08 (svc/hvc trap) entrypoint.
10
In the v8A Arm ARM pseudocode this is done in AArch32.TakeSVCException.
11
12
QEMU incorrectly routed both of these exceptions to the 0x14
13
entrypoint. Correct the entrypoint for SVC from Hyp to Hyp by making
14
use of the existing logic which handles "normal entrypoint for
15
Hyp-to-Hyp, otherwise 0x14" for traps like UNDEF and data/prefetch
16
aborts (reproduced here since it's outside the visible context
17
in the diff for this commit):
18
19
if (arm_current_el(env) != 2 && addr < 0x14) {
20
addr = 0x14;
21
}
22
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20220117131953.3936137-1-peter.maydell@linaro.org
27
---
28
target/arm/helper.c | 4 ++--
29
1 file changed, 2 insertions(+), 2 deletions(-)
30
31
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/helper.c
34
+++ b/target/arm/helper.c
35
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
36
* separately here.
37
*
38
* The vector table entry used is always the 0x14 Hyp mode entry point,
39
- * unless this is an UNDEF/HVC/abort taken from Hyp to Hyp.
40
+ * unless this is an UNDEF/SVC/HVC/abort taken from Hyp to Hyp.
41
* The offset applied to the preferred return address is always zero
42
* (see DDI0487C.a section G1.12.3).
43
* PSTATE A/I/F masks are set based only on the SCR.EA/IRQ/FIQ values.
44
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
45
addr = 0x04;
46
break;
47
case EXCP_SWI:
48
- addr = 0x14;
49
+ addr = 0x08;
50
break;
51
case EXCP_BKPT:
52
/* Fall through to prefetch abort. */
53
--
54
2.25.1
55
56
diff view generated by jsdifflib