1
Arm patch queue -- these are all bug fix patches but we might
1
The following changes since commit b367db48126d4ee14579af6cf5cdbffeb9496627:
2
as well put them in to rc0...
3
2
4
thanks
3
Merge remote-tracking branch 'remotes/aperard/tags/pull-xen-20220127' into staging (2022-01-28 11:05:29 +0000)
5
-- PMM
6
7
The following changes since commit 2c8cfc0b52b5a4d123c26c0b5fdf941be24805be:
8
9
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2018-03-19 11:44:26 +0000)
10
4
11
are available in the Git repository at:
5
are available in the Git repository at:
12
6
13
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180319
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220128
14
8
15
for you to fetch changes up to ff72cb6b46b95bb530787add5277c211af3d31c6:
9
for you to fetch changes up to 2c023d3675a3ffb54fc30504dcd715bc6f6e234f:
16
10
17
hw/arm/raspi: Provide spin-loop code for AArch64 CPUs (2018-03-19 18:23:24 +0000)
11
target/arm: Use correct entrypoint for SVC taken from Hyp to Hyp (2022-01-28 14:30:36 +0000)
18
12
19
----------------------------------------------------------------
13
----------------------------------------------------------------
20
target-arm queue:
14
target-arm queue:
21
* fsl-imx6: Fix incorrect Ethernet interrupt defines
15
* Update copyright dates to 2022
22
* dump: Update correct kdump phys_base field for AArch64
16
* hw/armv7m: Fix broken VMStateDescription
23
* char: i.MX: Add support for "TX complete" interrupt
17
* hw/char/exynos4210_uart: Fix crash on trying to load VM state
24
* bcm2836/raspi: Fix various bugs resulting in panics trying
18
* rtc: Move RTC function prototypes to their own header
25
to boot a Debian Linux kernel on raspi3
19
* xlnx-versal-virt: Support PMC SLCR
20
* xlnx-versal-virt: Support OSPI flash memory controller
21
* scripts: Explain the difference between linux-headers and standard-headers
22
* target/arm: Log CPU index in 'Taking exception' log
23
* arm_gicv3_its: Various bugfixes and cleanups
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
26
27
27
----------------------------------------------------------------
28
----------------------------------------------------------------
28
Andrey Smirnov (2):
29
Andrew Baumann (1):
29
char: i.MX: Simplify imx_update()
30
MAINTAINERS: Remove myself (for raspi).
30
char: i.MX: Add support for "TX complete" interrupt
31
31
32
Guenter Roeck (1):
32
Cédric Le Goater (1):
33
fsl-imx6: Swap Ethernet interrupt defines
33
hw/arm: ast2600: Fix address mapping of second SPI controller
34
34
35
Peter Maydell (9):
35
Francisco Iglesias (10):
36
hw/arm/raspi: Don't do board-setup or secure-boot for raspi3
36
hw/misc: Add a model of Versal's PMC SLCR
37
hw/arm/boot: assert that secure_boot and secure_board_setup are false for AArch64
37
hw/arm/xlnx-versal: 'Or' the interrupts from the BBRAM and RTC models
38
hw/arm/boot: If booting a kernel in EL2, set SCR_EL3.HCE
38
hw/arm/xlnx-versal: Connect Versal's PMC SLCR
39
hw/arm/bcm2386: Fix parent type of bcm2386
39
include/hw/dma/xlnx_csu_dma: Add in missing includes in the header
40
hw/arm/bcm2836: Rename bcm2836 type/struct to bcm283x
40
hw/dma/xlnx_csu_dma: Support starting a read transfer through a class method
41
hw/arm/bcm2836: Create proper bcm2837 device
41
hw/ssi: Add a model of Xilinx Versal's OSPI flash memory controller
42
hw/arm/bcm2836: Use correct affinity values for BCM2837
42
hw/arm/xlnx-versal: Connect the OSPI flash memory controller model
43
hw/arm/bcm2836: Hardcode correct CPU type
43
hw/block/m25p80: Add support for Micron Xccela flash mt35xu01g
44
hw/arm/raspi: Provide spin-loop code for AArch64 CPUs
44
hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI
45
MAINTAINERS: Add an entry for Xilinx Versal OSPI
45
46
46
Wei Huang (1):
47
Peter Maydell (20):
47
dump: Update correct kdump phys_base field for AArch64
48
Update copyright dates to 2022
49
hw/armv7m: Fix broken VMStateDescription
50
hw/char/exynos4210_uart: Fix crash on trying to load VM state
51
rtc: Move RTC function prototypes to their own header
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
48
68
49
include/hw/arm/bcm2836.h | 31 +++++++++++++---
69
docs/conf.py | 2 +-
50
include/hw/arm/fsl-imx6.h | 4 +-
70
hw/intc/gicv3_internal.h | 43 +-
51
include/hw/char/imx_serial.h | 3 ++
71
include/hw/arm/xlnx-versal.h | 30 +-
52
dump.c | 14 +++++--
72
include/hw/dma/xlnx_csu_dma.h | 24 +-
53
hw/arm/bcm2836.c | 87 +++++++++++++++++++++++++++++++-------------
73
include/hw/intc/arm_gicv3_its_common.h | 1 -
54
hw/arm/boot.c | 12 ++++++
74
include/hw/misc/xlnx-versal-pmc-iou-slcr.h | 78 ++
55
hw/arm/raspi.c | 77 +++++++++++++++++++++++++++++++--------
75
include/hw/ssi/xlnx-versal-ospi.h | 111 ++
56
hw/char/imx_serial.c | 44 ++++++++++++++++------
76
include/qemu-common.h | 5 +-
57
hw/net/imx_fec.c | 28 +++++++++++++-
77
include/sysemu/rtc.h | 58 +
58
9 files changed, 237 insertions(+), 63 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
59
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
New patch
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
1
2
3
Add a model of Versal's PMC SLCR (system-level control registers).
4
5
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
6
Signed-off-by: Edgar E. Iglesias <edgar.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-2-francisco.iglesias@xilinx.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/misc/xlnx-versal-pmc-iou-slcr.h | 78 ++
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
18
19
diff --git a/include/hw/misc/xlnx-versal-pmc-iou-slcr.h b/include/hw/misc/xlnx-versal-pmc-iou-slcr.h
20
new file mode 100644
21
index XXXXXXX..XXXXXXX
22
--- /dev/null
23
+++ b/include/hw/misc/xlnx-versal-pmc-iou-slcr.h
24
@@ -XXX,XX +XXX,XX @@
25
+/*
26
+ * Header file for the Xilinx Versal's PMC IOU SLCR
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 = {
1481
+ .min_access_size = 4,
1482
+ .max_access_size = 4,
1483
+ },
1484
+};
1485
+
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'))
1571
--
1572
2.25.1
1573
1574
diff view generated by jsdifflib
New patch
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
1
2
3
Add an orgate and 'or' the interrupts from the BBRAM and RTC models.
4
5
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Message-id: 20220121161141.14389-3-francisco.iglesias@xilinx.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/xlnx-versal.h | 5 +++--
12
hw/arm/xlnx-versal-virt.c | 2 +-
13
hw/arm/xlnx-versal.c | 28 ++++++++++++++++++++++++++--
14
3 files changed, 30 insertions(+), 5 deletions(-)
15
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
19
+++ b/include/hw/arm/xlnx-versal.h
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)
66
}
67
}
68
69
+static void versal_create_pmc_apb_irq_orgate(Versal *s, qemu_irq *pic)
70
+{
71
+ DeviceState *orgate;
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)
89
{
90
SysBusDevice *sbd;
91
@@ -XXX,XX +XXX,XX @@ static void versal_create_rtc(Versal *s, qemu_irq *pic)
92
* TODO: Connect the ALARM and SECONDS interrupts once our RTC model
93
* supports them.
94
*/
95
- sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
96
+ sysbus_connect_irq(sbd, 1,
97
+ qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 0));
98
}
99
100
static void versal_create_xrams(Versal *s, qemu_irq *pic)
101
@@ -XXX,XX +XXX,XX @@ static void versal_create_bbram(Versal *s, qemu_irq *pic)
102
sysbus_realize(sbd, &error_fatal);
103
memory_region_add_subregion(&s->mr_ps, MM_PMC_BBRAM_CTRL,
104
sysbus_mmio_get_region(sbd, 0));
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);
119
--
120
2.25.1
121
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
New patch
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
1
2
3
Add a model of Xilinx Versal's OSPI flash memory controller.
4
5
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
6
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
Message-id: 20220121161141.14389-7-francisco.iglesias@xilinx.com
8
[PMM: fixed indent]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/ssi/xlnx-versal-ospi.h | 111 ++
12
hw/ssi/xlnx-versal-ospi.c | 1853 +++++++++++++++++++++++++++++
13
hw/ssi/meson.build | 1 +
14
3 files changed, 1965 insertions(+)
15
create mode 100644 include/hw/ssi/xlnx-versal-ospi.h
16
create mode 100644 hw/ssi/xlnx-versal-ospi.c
17
18
diff --git a/include/hw/ssi/xlnx-versal-ospi.h b/include/hw/ssi/xlnx-versal-ospi.h
19
new file mode 100644
20
index XXXXXXX..XXXXXXX
21
--- /dev/null
22
+++ b/include/hw/ssi/xlnx-versal-ospi.h
23
@@ -XXX,XX +XXX,XX @@
24
+/*
25
+ * Header file for the Xilinx Versal's OSPI controller
26
+ *
27
+ * Copyright (C) 2021 Xilinx Inc
28
+ * Written by Francisco Iglesias <francisco.iglesias@xilinx.com>
29
+ *
30
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
31
+ * of this software and associated documentation files (the "Software"), to deal
32
+ * in the Software without restriction, including without limitation the rights
33
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
34
+ * copies of the Software, and to permit persons to whom the Software is
35
+ * furnished to do so, subject to the following conditions:
36
+ *
37
+ * The above copyright notice and this permission notice shall be included in
38
+ * all copies or substantial portions of the Software.
39
+ *
40
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
43
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
44
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
45
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
46
+ * THE SOFTWARE.
47
+ */
48
+
49
+/*
50
+ * This is a model of Xilinx Versal's Octal SPI flash memory controller
51
+ * documented in Versal's Technical Reference manual [1] and the Versal ACAP
52
+ * Register reference [2].
53
+ *
54
+ * References:
55
+ *
56
+ * [1] Versal ACAP Technical Reference Manual,
57
+ * https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
58
+ *
59
+ * [2] Versal ACAP Register Reference,
60
+ * https://www.xilinx.com/html_docs/registers/am012/am012-versal-register-reference.html#mod___ospi.html
61
+ *
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
+
719
+ /*
720
+ * Below one liner is a trick that finds the rightmost zero and makes sure
721
+ * all other bits are turned to 1. It is a variant of the 'Isolate the
722
+ * rightmost 0-bit' trick found below at the time of writing:
723
+ *
724
+ * https://emre.me/computer-science/bit-manipulation-tricks/
725
+ *
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
731
+ */
732
+ return (field | ~(field + 1)) & 0xf;
733
+}
734
+
735
+static void ospi_update_cs_lines(XlnxVersalOspi *s)
736
+{
737
+ unsigned int all_cs;
738
+ int i;
739
+
740
+ if (ARRAY_FIELD_EX32(s->regs, CONFIG_REG, PERIPH_SEL_DEC_FLD)) {
741
+ all_cs = ARRAY_FIELD_EX32(s->regs, CONFIG_REG, PERIPH_CS_LINES_FLD);
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
+
1820
+ return 0;
1821
+}
1822
+
1823
+static void ospi_dac_write(void *opaque, hwaddr addr, uint64_t value,
1824
+ unsigned int size)
1825
+{
1826
+ XlnxVersalOspi *s = XILINX_VERSAL_OSPI(opaque);
1827
+
1828
+ if (ARRAY_FIELD_EX32(s->regs, CONFIG_REG, ENB_SPI_FLD)) {
1829
+ if (ospi_is_indac_active(s) &&
1830
+ !s->ind_write_disabled &&
1831
+ is_inside_indac_range(s, addr)) {
1832
+ return ospi_indac_write(s, value, size);
1833
+ }
1834
+ if (ARRAY_FIELD_EX32(s->regs, CONFIG_REG, ENB_DIR_ACC_CTLR_FLD) &&
1835
+ s->dac_enable) {
1836
+ if (ARRAY_FIELD_EX32(s->regs,
1837
+ CONFIG_REG, ENB_AHB_ADDR_REMAP_FLD)) {
1838
+ addr += s->regs[R_REMAP_ADDR_REG];
1839
+ }
1840
+ /* Check if addr is write protected */
1841
+ if (ARRAY_FIELD_EX32(s->regs, WR_PROT_CTRL_REG, ENB_FLD) &&
1842
+ ospi_is_write_protected(s, addr)) {
1843
+ set_irq(s, R_IRQ_STATUS_REG_PROT_WR_ATTEMPT_FLD_MASK);
1844
+ ospi_update_irq_line(s);
1845
+ qemu_log_mask(LOG_GUEST_ERROR,
1846
+ "OSPI writing into write protected area\n");
1847
+ return;
1848
+ }
1849
+ ospi_do_dac_write(opaque, addr, value, size);
1850
+ } else {
1851
+ qemu_log_mask(LOG_GUEST_ERROR, "OSPI AHB wr while DAC disabled\n");
1852
+ }
1853
+ } else {
1854
+ qemu_log_mask(LOG_GUEST_ERROR, "OSPI AHB wr while OSPI disabled\n");
1855
+ }
1856
+}
1857
+
1858
+static const MemoryRegionOps ospi_dac_ops = {
1859
+ .read = ospi_dac_read,
1860
+ .write = ospi_dac_write,
1861
+ .endianness = DEVICE_LITTLE_ENDIAN,
1862
+ .valid = {
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",
1928
+ .version_id = 1,
1929
+ .minimum_version_id = 1,
1930
+ .fields = (VMStateField[]) {
1931
+ VMSTATE_UINT32(flash_addr, IndOp),
1932
+ VMSTATE_UINT32(num_bytes, IndOp),
1933
+ VMSTATE_UINT32(done_bytes, IndOp),
1934
+ VMSTATE_BOOL(completed, IndOp),
1935
+ VMSTATE_END_OF_LIST()
1936
+ }
1937
+};
1938
+
1939
+static const VMStateDescription vmstate_xlnx_versal_ospi = {
1940
+ .name = TYPE_XILINX_VERSAL_OSPI,
1941
+ .version_id = 1,
1942
+ .minimum_version_id = 1,
1943
+ .minimum_version_id_old = 1,
1944
+ .fields = (VMStateField[]) {
1945
+ VMSTATE_FIFO8(rx_fifo, XlnxVersalOspi),
1946
+ VMSTATE_FIFO8(tx_fifo, XlnxVersalOspi),
1947
+ VMSTATE_FIFO8(rx_sram, XlnxVersalOspi),
1948
+ VMSTATE_FIFO8(tx_sram, XlnxVersalOspi),
1949
+ VMSTATE_BOOL(ind_write_disabled, XlnxVersalOspi),
1950
+ VMSTATE_BOOL(dac_with_indac, XlnxVersalOspi),
1951
+ VMSTATE_BOOL(dac_enable, XlnxVersalOspi),
1952
+ VMSTATE_BOOL(src_dma_inprog, XlnxVersalOspi),
1953
+ VMSTATE_STRUCT_ARRAY(rd_ind_op, XlnxVersalOspi, 2, 1,
1954
+ vmstate_ind_op, IndOp),
1955
+ VMSTATE_STRUCT_ARRAY(wr_ind_op, XlnxVersalOspi, 2, 1,
1956
+ vmstate_ind_op, IndOp),
1957
+ VMSTATE_UINT32_ARRAY(regs, XlnxVersalOspi, XILINX_VERSAL_OSPI_R_MAX),
1958
+ VMSTATE_UINT8_ARRAY(stig_membank, XlnxVersalOspi, 512),
1959
+ VMSTATE_END_OF_LIST(),
1960
+ }
1961
+};
1962
+
1963
+static Property xlnx_versal_ospi_properties[] = {
1964
+ DEFINE_PROP_BOOL("dac-with-indac", XlnxVersalOspi, dac_with_indac, false),
1965
+ DEFINE_PROP_BOOL("indac-write-disabled", XlnxVersalOspi,
1966
+ ind_write_disabled, false),
1967
+ DEFINE_PROP_END_OF_LIST(),
1968
+};
1969
+
1970
+static void xlnx_versal_ospi_class_init(ObjectClass *klass, void *data)
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'))
2005
--
2006
2.25.1
2007
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: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
2
2
3
Code of imx_update() is slightly confusing since the "flags" variable
3
Connect Micron Xccela mt35xu01g flashes to the OSPI flash memory
4
doesn't really corespond to anything in real hardware and server as a
4
controller.
5
kitchensink accumulating events normally reported via USR1 and USR2
6
registers.
7
5
8
Change the code to explicitly evaluate state of interrupts reported
6
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
9
via USR1 and USR2 against corresponding masking bits and use the to
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
detemine if IRQ line should be asserted or not.
11
12
NOTE: Check for UTS1_TXEMPTY being set has been dropped for two
13
reasons:
14
15
1. Emulation code implements a single character FIFO, so this flag
16
will always be set since characters are trasmitted as a part of
17
the code emulating "push" into the FIFO
18
19
2. imx_update() is really just a function doing ORing and maksing
20
of reported events, so checking for UTS1_TXEMPTY should happen,
21
if it's ever really needed should probably happen outside of
22
it.
23
24
Cc: qemu-devel@nongnu.org
25
Cc: qemu-arm@nongnu.org
26
Cc: Bill Paul <wpaul@windriver.com>
27
Cc: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
29
Message-id: 20180315191141.6789-1-andrew.smirnov@gmail.com
30
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20220121161141.14389-10-francisco.iglesias@xilinx.com
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
---
11
---
33
hw/char/imx_serial.c | 24 ++++++++++++++++--------
12
hw/arm/xlnx-versal-virt.c | 23 +++++++++++++++++++++++
34
1 file changed, 16 insertions(+), 8 deletions(-)
13
1 file changed, 23 insertions(+)
35
14
36
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
15
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
37
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/char/imx_serial.c
17
--- a/hw/arm/xlnx-versal-virt.c
39
+++ b/hw/char/imx_serial.c
18
+++ b/hw/arm/xlnx-versal-virt.c
40
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_serial = {
19
@@ -XXX,XX +XXX,XX @@
41
20
#define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
42
static void imx_update(IMXSerialState *s)
21
OBJECT_DECLARE_SIMPLE_TYPE(VersalVirt, XLNX_VERSAL_VIRT_MACHINE)
43
{
22
44
- uint32_t flags;
23
+#define XLNX_VERSAL_NUM_OSPI_FLASH 4
45
+ uint32_t usr1;
24
+
46
+ uint32_t usr2;
25
struct VersalVirt {
47
+ uint32_t mask;
26
MachineState parent_obj;
48
27
49
- flags = (s->usr1 & s->ucr1) & (USR1_TRDY|USR1_RRDY);
28
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
50
- if (s->ucr1 & UCR1_TXMPTYEN) {
29
exit(EXIT_FAILURE);
51
- flags |= (s->uts1 & UTS1_TXEMPTY);
30
}
52
- } else {
31
}
53
- flags &= ~USR1_TRDY;
32
+
54
- }
33
+ for (i = 0; i < XLNX_VERSAL_NUM_OSPI_FLASH; i++) {
55
+ /*
34
+ BusState *spi_bus;
56
+ * Lucky for us TRDY and RRDY has the same offset in both USR1 and
35
+ DeviceState *flash_dev;
57
+ * UCR1, so we can get away with something as simple as the
36
+ qemu_irq cs_line;
58
+ * following:
37
+ DriveInfo *dinfo = drive_get(IF_MTD, 0, i);
59
+ */
38
+
60
+ usr1 = s->usr1 & s->ucr1 & (USR1_TRDY | USR1_RRDY);
39
+ spi_bus = qdev_get_child_bus(DEVICE(&s->soc.pmc.iou.ospi), "spi0");
61
+ /*
40
+
62
+ * Bits that we want in USR2 are not as conveniently laid out,
41
+ flash_dev = qdev_new("mt35xu01g");
63
+ * unfortunately.
42
+ if (dinfo) {
64
+ */
43
+ qdev_prop_set_drive_err(flash_dev, "drive",
65
+ mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
44
+ blk_by_legacy_dinfo(dinfo), &error_fatal);
66
+ usr2 = s->usr2 & mask;
45
+ }
67
46
+ qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);
68
- qemu_set_irq(s->irq, !!flags);
47
+
69
+ qemu_set_irq(s->irq, usr1 || usr2);
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
+ }
70
}
53
}
71
54
72
static void imx_serial_reset(IMXSerialState *s)
55
static void versal_virt_machine_instance_init(Object *obj)
73
--
56
--
74
2.16.2
57
2.25.1
75
58
76
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
1
From: Wei Huang <wei@redhat.com>
1
From: Andrew Baumann <Andrew.Baumann@microsoft.com>
2
2
3
For guest kernel that supports KASLR, the load address can change every
3
Signed-off-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
4
time when guest VM runs. To find the physical base address correctly,
4
Message-id: MW4PR21MB1940E8BB52F4053C943B1FCD9E219@MW4PR21MB1940.namprd21.prod.outlook.com
5
current QEMU dump searches VMCOREINFO for the string "NUMBER(phys_base)=".
6
However this string pattern is only available on x86_64. AArch64 uses a
7
different field, called "NUMBER(PHYS_OFFSET)=". This patch makes sure
8
QEMU dump uses the correct string on AArch64.
9
10
Signed-off-by: Wei Huang <wei@redhat.com>
11
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
12
Message-id: 1520615003-20869-1-git-send-email-wei@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
6
---
15
dump.c | 14 +++++++++++---
7
MAINTAINERS | 1 -
16
1 file changed, 11 insertions(+), 3 deletions(-)
8
1 file changed, 1 deletion(-)
17
9
18
diff --git a/dump.c b/dump.c
10
diff --git a/MAINTAINERS b/MAINTAINERS
19
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
20
--- a/dump.c
12
--- a/MAINTAINERS
21
+++ b/dump.c
13
+++ b/MAINTAINERS
22
@@ -XXX,XX +XXX,XX @@ static void vmcoreinfo_update_phys_base(DumpState *s)
14
@@ -XXX,XX +XXX,XX @@ F: docs/system/arm/palm.rst
23
15
24
lines = g_strsplit((char *)vmci, "\n", -1);
16
Raspberry Pi
25
for (i = 0; lines[i]; i++) {
17
M: Peter Maydell <peter.maydell@linaro.org>
26
- if (g_str_has_prefix(lines[i], "NUMBER(phys_base)=")) {
18
-R: Andrew Baumann <Andrew.Baumann@microsoft.com>
27
- if (qemu_strtou64(lines[i] + 18, NULL, 16,
19
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
28
+ const char *prefix = NULL;
20
L: qemu-arm@nongnu.org
29
+
21
S: Odd Fixes
30
+ if (s->dump_info.d_machine == EM_X86_64) {
31
+ prefix = "NUMBER(phys_base)=";
32
+ } else if (s->dump_info.d_machine == EM_AARCH64) {
33
+ prefix = "NUMBER(PHYS_OFFSET)=";
34
+ }
35
+
36
+ if (prefix && g_str_has_prefix(lines[i], prefix)) {
37
+ if (qemu_strtou64(lines[i] + strlen(prefix), NULL, 16,
38
&phys_base) < 0) {
39
- warn_report("Failed to read NUMBER(phys_base)=");
40
+ warn_report("Failed to read %s", prefix);
41
} else {
42
s->dump_info.phys_base = phys_base;
43
}
44
--
22
--
45
2.16.2
23
2.25.1
46
24
47
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
The raspi3 has AArch64 CPUs, which means that our smpboot
1
In an SMP system it can be unclear which CPU is taking an exception;
2
code for keeping the secondary CPUs in a pen needs to have
2
add the CPU index (which is the same value used in the TCG 'Trace
3
a version for A64 as well as A32. Without this, the
3
%d:' logging) to the "Taking exception" log line to clarify it.
4
secondary CPUs go into an infinite loop of taking undefined
5
instruction exceptions.
6
4
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20180313153458.26822-10-peter.maydell@linaro.org
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220122182444.724087-2-peter.maydell@linaro.org
10
---
9
---
11
hw/arm/raspi.c | 41 ++++++++++++++++++++++++++++++++++++++++-
10
target/arm/internals.h | 2 +-
12
1 file changed, 40 insertions(+), 1 deletion(-)
11
target/arm/helper.c | 9 ++++++---
12
target/arm/m_helper.c | 2 +-
13
3 files changed, 8 insertions(+), 5 deletions(-)
13
14
14
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/raspi.c
17
--- a/target/arm/internals.h
17
+++ b/hw/arm/raspi.c
18
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
19
#define BOARDSETUP_ADDR (MVBAR_ADDR + 0x20) /* board setup code */
20
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
20
#define FIRMWARE_ADDR_2 0x8000 /* Pi 2 loads kernel.img here by default */
21
__attribute__((nonnull));
21
#define FIRMWARE_ADDR_3 0x80000 /* Pi 3 loads kernel.img here by default */
22
22
+#define SPINTABLE_ADDR 0xd8 /* Pi 3 bootloader spintable */
23
-void arm_log_exception(int idx);
23
24
+void arm_log_exception(CPUState *cs);
24
/* Table of Linux board IDs for different Pi versions */
25
25
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
26
#endif /* !CONFIG_USER_ONLY */
26
@@ -XXX,XX +XXX,XX @@ static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
27
27
info->smp_loader_start);
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;
28
}
34
}
29
35
30
+static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
36
-void arm_log_exception(int idx)
31
+{
37
+void arm_log_exception(CPUState *cs)
32
+ /* Unlike the AArch32 version we don't need to call the board setup hook.
38
{
33
+ * The mechanism for doing the spin-table is also entirely different.
39
+ int idx = cs->exception_index;
34
+ * We must have four 64-bit fields at absolute addresses
35
+ * 0xd8, 0xe0, 0xe8, 0xf0 in RAM, which are the flag variables for
36
+ * our CPUs, and which we must ensure are zero initialized before
37
+ * the primary CPU goes into the kernel. We put these variables inside
38
+ * a rom blob, so that the reset for ROM contents zeroes them for us.
39
+ */
40
+ static const uint32_t smpboot[] = {
41
+ 0xd2801b05, /* mov x5, 0xd8 */
42
+ 0xd53800a6, /* mrs x6, mpidr_el1 */
43
+ 0x924004c6, /* and x6, x6, #0x3 */
44
+ 0xd503205f, /* spin: wfe */
45
+ 0xf86678a4, /* ldr x4, [x5,x6,lsl #3] */
46
+ 0xb4ffffc4, /* cbz x4, spin */
47
+ 0xd2800000, /* mov x0, #0x0 */
48
+ 0xd2800001, /* mov x1, #0x0 */
49
+ 0xd2800002, /* mov x2, #0x0 */
50
+ 0xd2800003, /* mov x3, #0x0 */
51
+ 0xd61f0080, /* br x4 */
52
+ };
53
+
40
+
54
+ static const uint64_t spintables[] = {
41
if (qemu_loglevel_mask(CPU_LOG_INT)) {
55
+ 0, 0, 0, 0
42
const char *exc = NULL;
56
+ };
43
static const char * const excnames[] = {
57
+
44
@@ -XXX,XX +XXX,XX @@ void arm_log_exception(int idx)
58
+ rom_add_blob_fixed("raspi_smpboot", smpboot, sizeof(smpboot),
45
if (!exc) {
59
+ info->smp_loader_start);
46
exc = "unknown";
60
+ rom_add_blob_fixed("raspi_spintables", spintables, sizeof(spintables),
47
}
61
+ SPINTABLE_ADDR);
48
- qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s]\n", idx, exc);
62
+}
49
+ qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s] on CPU %d\n",
63
+
50
+ idx, exc, cs->cpu_index);
64
static void write_board_setup(ARMCPU *cpu, const struct arm_boot_info *info)
65
{
66
arm_write_secure_board_setup_dummy_smc(cpu, info, MVBAR_ADDR);
67
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
68
/* Pi2 and Pi3 requires SMP setup */
69
if (version >= 2) {
70
binfo.smp_loader_start = SMPBOOT_ADDR;
71
- binfo.write_secondary_boot = write_smpboot;
72
+ if (version == 2) {
73
+ binfo.write_secondary_boot = write_smpboot;
74
+ } else {
75
+ binfo.write_secondary_boot = write_smpboot64;
76
+ }
77
binfo.secondary_cpu_reset_hook = reset_secondary;
78
}
51
}
79
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)
63
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/m_helper.c
66
+++ b/target/arm/m_helper.c
67
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
68
uint32_t lr;
69
bool ignore_stackfaults;
70
71
- arm_log_exception(cs->exception_index);
72
+ arm_log_exception(cs);
73
74
/*
75
* For exceptions we just mark as pending on the NVIC, and let that
80
--
76
--
81
2.16.2
77
2.25.1
82
78
83
79
diff view generated by jsdifflib
1
The BCM2837 sets the Aff1 field of the MPIDR affinity values for the
1
The ITS currently has no tracepoints; add a minimal set
2
CPUs to 0, whereas the BCM2836 uses 0xf. Set this correctly, as it
2
that allows basic monitoring of guest register accesses and
3
is required for Linux to boot.
3
reading of commands from the command queue.
4
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20180313153458.26822-8-peter.maydell@linaro.org
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220122182444.724087-3-peter.maydell@linaro.org
9
---
9
---
10
hw/arm/bcm2836.c | 11 +++++++----
10
hw/intc/arm_gicv3_its.c | 11 +++++++++++
11
1 file changed, 7 insertions(+), 4 deletions(-)
11
hw/intc/trace-events | 8 ++++++++
12
2 files changed, 19 insertions(+)
12
13
13
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
14
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/bcm2836.c
16
--- a/hw/intc/arm_gicv3_its.c
16
+++ b/hw/arm/bcm2836.c
17
+++ b/hw/intc/arm_gicv3_its.c
17
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@
18
19
19
struct BCM283XInfo {
20
#include "qemu/osdep.h"
20
const char *name;
21
#include "qemu/log.h"
21
+ int clusterid;
22
+#include "trace.h"
22
};
23
#include "hw/qdev-properties.h"
23
24
#include "hw/intc/arm_gicv3_its_common.h"
24
static const BCM283XInfo bcm283x_socs[] = {
25
#include "gicv3_internal.h"
25
{
26
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
26
.name = TYPE_BCM2836,
27
27
+ .clusterid = 0xf,
28
cmd = (data & CMD_MASK);
28
},
29
29
{
30
+ trace_gicv3_its_process_command(rd_offset, cmd);
30
.name = TYPE_BCM2837,
31
+
31
+ .clusterid = 0x0,
32
switch (cmd) {
32
},
33
case GITS_CMD_INT:
33
};
34
result = process_its_cmd(s, data, cq_offset, INTERRUPT);
34
35
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset,
35
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
36
bool result = true;
36
static void bcm2836_realize(DeviceState *dev, Error **errp)
37
uint32_t devid = 0;
37
{
38
38
BCM283XState *s = BCM283X(dev);
39
+ trace_gicv3_its_translation_write(offset, data, size, attrs.requester_id);
39
+ BCM283XClass *bc = BCM283X_GET_CLASS(dev);
40
+
40
+ const BCM283XInfo *info = bc->info;
41
switch (offset) {
41
Object *obj;
42
case GITS_TRANSLATER:
42
Error *err = NULL;
43
if (s->ctlr & R_GITS_CTLR_ENABLED_MASK) {
43
int n;
44
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_read(void *opaque, hwaddr offset, uint64_t *data,
44
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
45
qemu_log_mask(LOG_GUEST_ERROR,
45
qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
46
"%s: invalid guest read at offset " TARGET_FMT_plx
46
47
"size %u\n", __func__, offset, size);
47
for (n = 0; n < BCM283X_NCPUS; n++) {
48
+ trace_gicv3_its_badread(offset, size);
48
- /* Mirror bcm2836, which has clusterid set to 0xf
49
/*
49
- * TODO: this should be converted to a property of ARM_CPU
50
* The spec requires that reserved registers are RAZ/WI;
50
- */
51
* so use false returns from leaf functions as a way to
51
- s->cpus[n].mp_affinity = 0xF00 | n;
52
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_read(void *opaque, hwaddr offset, uint64_t *data,
52
+ /* TODO: this should be converted to a property of ARM_CPU */
53
* the caller, or we'll cause a spurious guest data abort.
53
+ s->cpus[n].mp_affinity = (info->clusterid << 8) | n;
54
*/
54
55
*data = 0;
55
/* set periphbase/CBAR value for CPU-local registers */
56
+ } else {
56
object_property_set_int(OBJECT(&s->cpus[n]),
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"
57
--
96
--
58
2.16.2
97
2.25.1
59
98
60
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
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
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.
2
6
3
Add support for "TX complete"/TXDC interrupt generate by real HW since
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
it is needed to support guests other than Linux.
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(-)
5
13
6
Based on the patch by Bill Paul as found here:
14
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
7
https://bugs.launchpad.net/qemu/+bug/1753314
8
9
Cc: qemu-devel@nongnu.org
10
Cc: qemu-arm@nongnu.org
11
Cc: Bill Paul <wpaul@windriver.com>
12
Cc: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Bill Paul <wpaul@windriver.com>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
15
Message-id: 20180315191141.6789-2-andrew.smirnov@gmail.com
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
include/hw/char/imx_serial.h | 3 +++
20
hw/char/imx_serial.c | 20 +++++++++++++++++---
21
2 files changed, 20 insertions(+), 3 deletions(-)
22
23
diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h
24
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/char/imx_serial.h
16
--- a/hw/intc/arm_gicv3_its.c
26
+++ b/include/hw/char/imx_serial.h
17
+++ b/hw/intc/arm_gicv3_its.c
27
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
28
#define UCR2_RXEN (1<<1) /* Receiver enable */
19
if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
29
#define UCR2_SRST (1<<0) /* Reset complete */
20
s->cbaser = deposit64(s->cbaser, 0, 32, value);
30
21
s->creadr = 0;
31
+#define UCR4_TCEN BIT(3) /* TX complete interrupt enable */
22
- s->cwriter = s->creadr;
32
+
33
#define UTS1_TXEMPTY (1<<6)
34
#define UTS1_RXEMPTY (1<<5)
35
#define UTS1_TXFULL (1<<4)
36
@@ -XXX,XX +XXX,XX @@ typedef struct IMXSerialState {
37
uint32_t ubmr;
38
uint32_t ubrc;
39
uint32_t ucr3;
40
+ uint32_t ucr4;
41
42
qemu_irq irq;
43
CharBackend chr;
44
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/char/imx_serial.c
47
+++ b/hw/char/imx_serial.c
48
@@ -XXX,XX +XXX,XX @@
49
50
static const VMStateDescription vmstate_imx_serial = {
51
.name = TYPE_IMX_SERIAL,
52
- .version_id = 1,
53
- .minimum_version_id = 1,
54
+ .version_id = 2,
55
+ .minimum_version_id = 2,
56
.fields = (VMStateField[]) {
57
VMSTATE_INT32(readbuff, IMXSerialState),
58
VMSTATE_UINT32(usr1, IMXSerialState),
59
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_serial = {
60
VMSTATE_UINT32(ubmr, IMXSerialState),
61
VMSTATE_UINT32(ubrc, IMXSerialState),
62
VMSTATE_UINT32(ucr3, IMXSerialState),
63
+ VMSTATE_UINT32(ucr4, IMXSerialState),
64
VMSTATE_END_OF_LIST()
65
},
66
};
67
@@ -XXX,XX +XXX,XX @@ static void imx_update(IMXSerialState *s)
68
* unfortunately.
69
*/
70
mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
71
+ /*
72
+ * TCEN and TXDC are both bit 3
73
+ */
74
+ mask |= s->ucr4 & UCR4_TCEN;
75
+
76
usr2 = s->usr2 & mask;
77
78
qemu_set_irq(s->irq, usr1 || usr2);
79
@@ -XXX,XX +XXX,XX @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset,
80
return s->ucr3;
81
82
case 0x23: /* UCR4 */
83
+ return s->ucr4;
84
+
85
case 0x29: /* BRM Incremental */
86
return 0x0; /* TODO */
87
88
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
89
* qemu_chr_fe_write and background I/O callbacks */
90
qemu_chr_fe_write_all(&s->chr, &ch, 1);
91
s->usr1 &= ~USR1_TRDY;
92
+ s->usr2 &= ~USR2_TXDC;
93
imx_update(s);
94
s->usr1 |= USR1_TRDY;
95
+ s->usr2 |= USR2_TXDC;
96
imx_update(s);
97
}
23
}
98
break;
24
break;
99
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
25
case GITS_CBASER + 4:
100
s->ucr3 = value & 0xffff;
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
}
101
break;
32
break;
102
33
case GITS_CWRITER:
103
- case 0x2d: /* UTS1 */
34
@@ -XXX,XX +XXX,XX @@ static bool its_writell(GICv3ITSState *s, hwaddr offset,
104
case 0x23: /* UCR4 */
35
if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
105
+ s->ucr4 = value & 0xffff;
36
s->cbaser = value;
106
+ imx_update(s);
37
s->creadr = 0;
107
+ break;
38
- s->cwriter = s->creadr;
108
+
39
}
109
+ case 0x2d: /* UTS1 */
40
break;
110
qemu_log_mask(LOG_UNIMP, "[%s]%s: Unimplemented reg 0x%"
41
case GITS_CWRITER:
111
HWADDR_PRIx "\n", TYPE_IMX_SERIAL, __func__, offset);
112
/* TODO */
113
--
42
--
114
2.16.2
43
2.25.1
115
44
116
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
1
Add some assertions that if we're about to boot an AArch64 kernel,
1
The list of #defines for the ITS command packet numbers is neither
2
the board code has not mistakenly set either secure_boot or
2
in alphabetical nor numeric order. Sort it into numeric order.
3
secure_board_setup. It doesn't make sense to set secure_boot,
4
because all AArch64 kernels must be booted in non-secure mode.
5
6
It might in theory make sense to set secure_board_setup, but
7
we don't currently support that, because only the AArch32
8
bootloader[] code calls this hook; bootloader_aarch64[] does not.
9
Since we don't have a current need for this functionality, just
10
assert that we don't try to use it. If it's needed we'll add
11
it later.
12
3
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20180313153458.26822-3-peter.maydell@linaro.org
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220122182444.724087-8-peter.maydell@linaro.org
16
---
8
---
17
hw/arm/boot.c | 7 +++++++
9
hw/intc/gicv3_internal.h | 10 +++++-----
18
1 file changed, 7 insertions(+)
10
1 file changed, 5 insertions(+), 5 deletions(-)
19
11
20
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
12
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
21
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/boot.c
14
--- a/hw/intc/gicv3_internal.h
23
+++ b/hw/arm/boot.c
15
+++ b/hw/intc/gicv3_internal.h
24
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
16
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, CIL, 36, 1)
25
} else {
17
#define CMD_MASK 0xff
26
env->pstate = PSTATE_MODE_EL1h;
18
27
}
19
/* ITS Commands */
28
+ /* AArch64 kernels never boot in secure mode */
20
-#define GITS_CMD_CLEAR 0x04
29
+ assert(!info->secure_boot);
21
-#define GITS_CMD_DISCARD 0x0F
30
+ /* This hook is only supported for AArch32 currently:
22
#define GITS_CMD_INT 0x03
31
+ * bootloader_aarch64[] will not call the hook, and
23
-#define GITS_CMD_MAPC 0x09
32
+ * the code above has already dropped us into EL2 or EL1.
24
+#define GITS_CMD_CLEAR 0x04
33
+ */
25
+#define GITS_CMD_SYNC 0x05
34
+ assert(!info->secure_board_setup);
26
#define GITS_CMD_MAPD 0x08
35
}
27
-#define GITS_CMD_MAPI 0x0B
36
28
+#define GITS_CMD_MAPC 0x09
37
/* Set to non-secure if not a secure boot */
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
--
38
--
39
2.16.2
39
2.25.1
40
40
41
41
diff view generated by jsdifflib
New patch
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.
1
10
11
Remove the unnecessary checks.
12
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(-)
19
20
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/intc/arm_gicv3_redist.c
23
+++ b/hw/intc/arm_gicv3_redist.c
24
@@ -XXX,XX +XXX,XX @@ void gicv3_redist_update_lpi_only(GICv3CPUState *cs)
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;
32
}
33
34
@@ -XXX,XX +XXX,XX @@ void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level)
35
idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS),
36
GICD_TYPER_IDBITS);
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
}
45
46
--
47
2.25.1
48
49
diff view generated by jsdifflib
1
The TypeInfo and state struct for bcm2386 disagree about what the
1
The GICR_CTLR.CES bit is a read-only bit which is set to 1 to indicate
2
parent class is -- the TypeInfo says it's TYPE_SYS_BUS_DEVICE,
2
that the GICR_CTLR.EnableLPIs bit can be written to 0 to disable
3
but the BCM2386State struct only defines the parent_obj field
3
LPIs (as opposed to allowing LPIs to be enabled but not subsequently
4
as DeviceState. This would have caused problems if anything
4
disabled). Our implementation permits this, so advertise it
5
actually tried to treat the object as a TYPE_SYS_BUS_DEVICE.
5
by setting CES to 1.
6
Fix the TypeInfo to use TYPE_DEVICE as the parent, since we don't
7
need any of the additional functionality TYPE_SYS_BUS_DEVICE
8
provides.
9
6
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20220122182444.724087-10-peter.maydell@linaro.org
13
Message-id: 20180313153458.26822-5-peter.maydell@linaro.org
14
---
10
---
15
hw/arm/bcm2836.c | 2 +-
11
hw/intc/gicv3_internal.h | 1 +
16
1 file changed, 1 insertion(+), 1 deletion(-)
12
hw/intc/arm_gicv3_common.c | 4 ++++
13
2 files changed, 5 insertions(+)
17
14
18
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
15
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/bcm2836.c
17
--- a/hw/intc/gicv3_internal.h
21
+++ b/hw/arm/bcm2836.c
18
+++ b/hw/intc/gicv3_internal.h
22
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
19
@@ -XXX,XX +XXX,XX @@
23
20
#define GICR_NSACR (GICR_SGI_OFFSET + 0x0E00)
24
static const TypeInfo bcm2836_type_info = {
21
25
.name = TYPE_BCM2836,
22
#define GICR_CTLR_ENABLE_LPIS (1U << 0)
26
- .parent = TYPE_SYS_BUS_DEVICE,
23
+#define GICR_CTLR_CES (1U << 1)
27
+ .parent = TYPE_DEVICE,
24
#define GICR_CTLR_RWP (1U << 3)
28
.instance_size = sizeof(BCM2836State),
25
#define GICR_CTLR_DPG0 (1U << 24)
29
.instance_init = bcm2836_init,
26
#define GICR_CTLR_DPG1NS (1U << 25)
30
.class_init = bcm2836_class_init,
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;
31
--
42
--
32
2.16.2
43
2.25.1
33
44
34
45
diff view generated by jsdifflib
1
Our BCM2836 type is really a generic one that can be any of
1
The MemoryRegionOps gicv3_its_translation_ops currently provides only
2
the bcm283x family. Rename it accordingly. We change only
2
a .write_with_attrs function, because the only register in this
3
the names which are visible via the header file to the
3
region is the write-only GITS_TRANSLATER. However, if you don't
4
rest of the QEMU code, leaving private function names
4
provide a read function and the guest tries reading from this memory
5
in bcm2836.c as they are.
5
region, QEMU will crash because
6
memory_region_read_with_attrs_accessor() calls a NULL pointer.
6
7
7
This is a preliminary to making bcm283x be an abstract
8
Add a read function which always returns 0, to cover both bogus
8
parent class to specific types for the bcm2836 and bcm2837.
9
attempts to read GITS_TRANSLATER and also reads from the rest of the
10
region, which is documented to be reserved, RES0.
9
11
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20180313153458.26822-6-peter.maydell@linaro.org
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220122182444.724087-11-peter.maydell@linaro.org
14
---
16
---
15
include/hw/arm/bcm2836.h | 12 ++++++------
17
hw/intc/arm_gicv3_its.c | 13 +++++++++++++
16
hw/arm/bcm2836.c | 17 +++++++++--------
18
1 file changed, 13 insertions(+)
17
hw/arm/raspi.c | 16 ++++++++--------
18
3 files changed, 23 insertions(+), 22 deletions(-)
19
19
20
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
20
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
21
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/bcm2836.h
22
--- a/hw/intc/arm_gicv3_its.c
23
+++ b/include/hw/arm/bcm2836.h
23
+++ b/hw/intc/arm_gicv3_its.c
24
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ static void extract_cmdq_params(GICv3ITSState *s)
25
#include "hw/arm/bcm2835_peripherals.h"
25
}
26
#include "hw/intc/bcm2836_control.h"
27
28
-#define TYPE_BCM2836 "bcm2836"
29
-#define BCM2836(obj) OBJECT_CHECK(BCM2836State, (obj), TYPE_BCM2836)
30
+#define TYPE_BCM283X "bcm283x"
31
+#define BCM283X(obj) OBJECT_CHECK(BCM283XState, (obj), TYPE_BCM283X)
32
33
-#define BCM2836_NCPUS 4
34
+#define BCM283X_NCPUS 4
35
36
-typedef struct BCM2836State {
37
+typedef struct BCM283XState {
38
/*< private >*/
39
DeviceState parent_obj;
40
/*< public >*/
41
@@ -XXX,XX +XXX,XX @@ typedef struct BCM2836State {
42
char *cpu_type;
43
uint32_t enabled_cpus;
44
45
- ARMCPU cpus[BCM2836_NCPUS];
46
+ ARMCPU cpus[BCM283X_NCPUS];
47
BCM2836ControlState control;
48
BCM2835PeripheralState peripherals;
49
-} BCM2836State;
50
+} BCM283XState;
51
52
#endif /* BCM2836_H */
53
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/bcm2836.c
56
+++ b/hw/arm/bcm2836.c
57
@@ -XXX,XX +XXX,XX @@
58
59
static void bcm2836_init(Object *obj)
60
{
61
- BCM2836State *s = BCM2836(obj);
62
+ BCM283XState *s = BCM283X(obj);
63
64
object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
65
object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
66
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
67
68
static void bcm2836_realize(DeviceState *dev, Error **errp)
69
{
70
- BCM2836State *s = BCM2836(dev);
71
+ BCM283XState *s = BCM283X(dev);
72
Object *obj;
73
Error *err = NULL;
74
int n;
75
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
76
/* common peripherals from bcm2835 */
77
78
obj = OBJECT(dev);
79
- for (n = 0; n < BCM2836_NCPUS; n++) {
80
+ for (n = 0; n < BCM283X_NCPUS; n++) {
81
object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
82
s->cpu_type);
83
object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
84
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
85
sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 1,
86
qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
87
88
- for (n = 0; n < BCM2836_NCPUS; n++) {
89
+ for (n = 0; n < BCM283X_NCPUS; n++) {
90
/* Mirror bcm2836, which has clusterid set to 0xf
91
* TODO: this should be converted to a property of ARM_CPU
92
*/
93
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
94
}
26
}
95
27
96
static Property bcm2836_props[] = {
28
+static MemTxResult gicv3_its_translation_read(void *opaque, hwaddr offset,
97
- DEFINE_PROP_STRING("cpu-type", BCM2836State, cpu_type),
29
+ uint64_t *data, unsigned size,
98
- DEFINE_PROP_UINT32("enabled-cpus", BCM2836State, enabled_cpus, BCM2836_NCPUS),
30
+ MemTxAttrs attrs)
99
+ DEFINE_PROP_STRING("cpu-type", BCM283XState, cpu_type),
31
+{
100
+ DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus,
32
+ /*
101
+ BCM283X_NCPUS),
33
+ * GITS_TRANSLATER is write-only, and all other addresses
102
DEFINE_PROP_END_OF_LIST()
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 = {
103
};
44
};
104
45
105
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
46
static const MemoryRegionOps gicv3_its_translation_ops = {
106
}
47
+ .read_with_attrs = gicv3_its_translation_read,
107
48
.write_with_attrs = gicv3_its_translation_write,
108
static const TypeInfo bcm2836_type_info = {
49
.valid.min_access_size = 2,
109
- .name = TYPE_BCM2836,
50
.valid.max_access_size = 4,
110
+ .name = TYPE_BCM283X,
111
.parent = TYPE_DEVICE,
112
- .instance_size = sizeof(BCM2836State),
113
+ .instance_size = sizeof(BCM283XState),
114
.instance_init = bcm2836_init,
115
.class_init = bcm2836_class_init,
116
};
117
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/hw/arm/raspi.c
120
+++ b/hw/arm/raspi.c
121
@@ -XXX,XX +XXX,XX @@
122
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
123
124
typedef struct RasPiState {
125
- BCM2836State soc;
126
+ BCM283XState soc;
127
MemoryRegion ram;
128
} RasPiState;
129
130
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
131
BusState *bus;
132
DeviceState *carddev;
133
134
- object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM2836);
135
+ object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM283X);
136
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
137
&error_abort);
138
139
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_init(MachineClass *mc)
140
mc->no_floppy = 1;
141
mc->no_cdrom = 1;
142
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
143
- mc->max_cpus = BCM2836_NCPUS;
144
- mc->min_cpus = BCM2836_NCPUS;
145
- mc->default_cpus = BCM2836_NCPUS;
146
+ mc->max_cpus = BCM283X_NCPUS;
147
+ mc->min_cpus = BCM283X_NCPUS;
148
+ mc->default_cpus = BCM283X_NCPUS;
149
mc->default_ram_size = 1024 * 1024 * 1024;
150
mc->ignore_memory_transaction_failures = true;
151
};
152
@@ -XXX,XX +XXX,XX @@ static void raspi3_machine_init(MachineClass *mc)
153
mc->no_floppy = 1;
154
mc->no_cdrom = 1;
155
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a53");
156
- mc->max_cpus = BCM2836_NCPUS;
157
- mc->min_cpus = BCM2836_NCPUS;
158
- mc->default_cpus = BCM2836_NCPUS;
159
+ mc->max_cpus = BCM283X_NCPUS;
160
+ mc->min_cpus = BCM283X_NCPUS;
161
+ mc->default_cpus = BCM283X_NCPUS;
162
mc->default_ram_size = 1024 * 1024 * 1024;
163
}
164
DEFINE_MACHINE("raspi3", raspi3_machine_init)
165
--
51
--
166
2.16.2
52
2.25.1
167
53
168
54
diff view generated by jsdifflib
1
If we're directly booting a Linux kernel and the CPU supports both
1
The ITS has a bank of 8 GITS_BASER<n> registers, which allow the
2
EL3 and EL2, we start the kernel in EL2, as it expects. We must also
2
guest to specify the base address of various data tables. Each
3
set the SCR_EL3.HCE bit in this situation, so that the HVC
3
register has a read-only type field indicating which table it is for
4
instruction is enabled rather than UNDEFing. Otherwise at least some
4
and a read-write field where the guest can write in the base address
5
kernels will panic when trying to initialize KVM in the guest.
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.
12
13
Prevent the assertion by not allowing the guest to write to the
14
unimplemented base registers. This means their value will remain 0
15
and extract_table_params() will ignore them.
6
16
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20180313153458.26822-4-peter.maydell@linaro.org
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20220122182444.724087-12-peter.maydell@linaro.org
9
---
20
---
10
hw/arm/boot.c | 5 +++++
21
hw/intc/arm_gicv3_its.c | 8 ++++++++
11
1 file changed, 5 insertions(+)
22
1 file changed, 8 insertions(+)
12
23
13
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
24
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
14
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/boot.c
26
--- a/hw/intc/arm_gicv3_its.c
16
+++ b/hw/arm/boot.c
27
+++ b/hw/intc/arm_gicv3_its.c
17
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
28
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
18
assert(!info->secure_board_setup);
29
if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
19
}
30
index = (offset - GITS_BASER) / 8;
20
31
21
+ if (arm_feature(env, ARM_FEATURE_EL2)) {
32
+ if (s->baser[index] == 0) {
22
+ /* If we have EL2 then Linux expects the HVC insn to work */
33
+ /* Unimplemented GITS_BASERn: RAZ/WI */
23
+ env->cp15.scr_el3 |= SCR_HCE;
34
+ break;
24
+ }
35
+ }
25
+
36
if (offset & 7) {
26
/* Set to non-secure if not a secure boot */
37
value <<= 32;
27
if (!info->secure_boot &&
38
value &= ~GITS_BASER_RO_MASK;
28
(cs != first_cpu || !info->secure_board_setup)) {
39
@@ -XXX,XX +XXX,XX @@ static bool its_writell(GICv3ITSState *s, hwaddr offset,
40
*/
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);
49
}
29
--
50
--
30
2.16.2
51
2.25.1
31
52
32
53
diff view generated by jsdifflib
1
Now we have separate types for BCM2386 and BCM2387, we might as well
1
Currently when we fill in a TableDesc based on the value the guest
2
just hard-code the CPU type they use rather than having it passed
2
has written to the GITS_BASER<n> register, we calculate both:
3
through as an object property. This then lets us put the initialization
3
* num_entries : the number of entries in the table, constrained
4
of the CPU object in init rather than realize.
4
by the amount of memory the guest has given it
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)
5
8
6
Note that this change means that it's no longer possible on
9
When validating ITS commands, however, we check only num_ids,
7
the command line to use -cpu to ask for a different kind of
10
thus allowing a broken guest to specify table entries that
8
CPU than the SoC supports. This was never a supported thing to
11
index off the end of it. This will only corrupt guest memory,
9
do anyway; we were just not sanity-checking the command line.
12
but the ITS is supposed to reject such commands as invalid.
10
13
11
This does require us to only build the bcm2837 object on
14
Instead of calculating both num_entries and num_ids, set
12
TARGET_AARCH64 configs, since otherwise it won't instantiate
15
num_entries to the minimum of the two limits, and check that.
13
due to the missing cortex-a53 device and "make check" will fail.
14
16
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Message-id: 20220122182444.724087-13-peter.maydell@linaro.org
18
Message-id: 20180313153458.26822-9-peter.maydell@linaro.org
19
---
20
---
20
hw/arm/bcm2836.c | 24 +++++++++++++++---------
21
include/hw/intc/arm_gicv3_its_common.h | 1 -
21
hw/arm/raspi.c | 2 --
22
hw/intc/arm_gicv3_its.c | 18 +++++++++---------
22
2 files changed, 15 insertions(+), 11 deletions(-)
23
2 files changed, 9 insertions(+), 10 deletions(-)
23
24
24
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
25
diff --git a/include/hw/intc/arm_gicv3_its_common.h b/include/hw/intc/arm_gicv3_its_common.h
25
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/bcm2836.c
27
--- a/include/hw/intc/arm_gicv3_its_common.h
27
+++ b/hw/arm/bcm2836.c
28
+++ b/include/hw/intc/arm_gicv3_its_common.h
28
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@ typedef struct {
29
30
uint16_t entry_sz;
30
struct BCM283XInfo {
31
uint32_t page_sz;
31
const char *name;
32
uint32_t num_entries;
32
+ const char *cpu_type;
33
- uint32_t num_ids;
33
int clusterid;
34
uint64_t base_addr;
34
};
35
} TableDesc;
35
36
36
static const BCM283XInfo bcm283x_socs[] = {
37
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
37
{
38
index XXXXXXX..XXXXXXX 100644
38
.name = TYPE_BCM2836,
39
--- a/hw/intc/arm_gicv3_its.c
39
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"),
40
+++ b/hw/intc/arm_gicv3_its.c
40
.clusterid = 0xf,
41
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_its_cmd(GICv3ITSState *s, uint64_t value,
41
},
42
42
+#ifdef TARGET_AARCH64
43
eventid = (value & EVENTID_MASK);
43
{
44
44
.name = TYPE_BCM2837,
45
- if (devid >= s->dt.num_ids) {
45
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a53"),
46
+ if (devid >= s->dt.num_entries) {
46
.clusterid = 0x0,
47
qemu_log_mask(LOG_GUEST_ERROR,
47
},
48
"%s: invalid command attributes: devid %d>=%d",
48
+#endif
49
- __func__, devid, s->dt.num_ids);
49
};
50
+ __func__, devid, s->dt.num_entries);
50
51
return CMD_CONTINUE;
51
static void bcm2836_init(Object *obj)
52
}
52
{
53
53
BCM283XState *s = BCM283X(obj);
54
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_its_cmd(GICv3ITSState *s, uint64_t value,
54
+ BCM283XClass *bc = BCM283X_GET_CLASS(obj);
55
return CMD_CONTINUE;
55
+ const BCM283XInfo *info = bc->info;
56
}
56
+ int n;
57
57
+
58
- if (icid >= s->ct.num_ids) {
58
+ for (n = 0; n < BCM283X_NCPUS; n++) {
59
+ if (icid >= s->ct.num_entries) {
59
+ object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
60
qemu_log_mask(LOG_GUEST_ERROR,
60
+ info->cpu_type);
61
"%s: invalid ICID 0x%x in ITE (table corrupted?)\n",
61
+ object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
62
__func__, icid);
62
+ &error_abort);
63
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_mapti(GICv3ITSState *s, uint64_t value,
63
+ }
64
64
65
icid = value & ICID_MASK;
65
object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
66
66
object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
67
- if (devid >= s->dt.num_ids) {
67
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
68
+ if (devid >= s->dt.num_entries) {
68
69
qemu_log_mask(LOG_GUEST_ERROR,
69
/* common peripherals from bcm2835 */
70
"%s: invalid command attributes: devid %d>=%d",
70
71
- __func__, devid, s->dt.num_ids);
71
- obj = OBJECT(dev);
72
+ __func__, devid, s->dt.num_entries);
72
- for (n = 0; n < BCM283X_NCPUS; n++) {
73
return CMD_CONTINUE;
73
- object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
74
}
74
- s->cpu_type);
75
75
- object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
76
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_mapti(GICv3ITSState *s, uint64_t value,
76
- &error_abort);
77
num_eventids = 1ULL << (FIELD_EX64(dte, DTE, SIZE) + 1);
77
- }
78
num_intids = 1ULL << (GICD_TYPER_IDBITS + 1);
78
-
79
79
obj = object_property_get_link(OBJECT(dev), "ram", &err);
80
- if ((icid >= s->ct.num_ids)
80
if (obj == NULL) {
81
+ if ((icid >= s->ct.num_entries)
81
error_setg(errp, "%s: required ram link not found: %s",
82
|| !dte_valid || (eventid >= num_eventids) ||
82
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
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
}
83
}
110
}
84
111
85
static Property bcm2836_props[] = {
86
- DEFINE_PROP_STRING("cpu-type", BCM283XState, cpu_type),
87
DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus,
88
BCM283X_NCPUS),
89
DEFINE_PROP_END_OF_LIST()
90
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/hw/arm/raspi.c
93
+++ b/hw/arm/raspi.c
94
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
95
/* Setup the SOC */
96
object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
97
&error_abort);
98
- object_property_set_str(OBJECT(&s->soc), machine->cpu_type, "cpu-type",
99
- &error_abort);
100
object_property_set_int(OBJECT(&s->soc), smp_cpus, "enabled-cpus",
101
&error_abort);
102
int board_rev = version == 3 ? 0xa02082 : 0xa21041;
103
--
112
--
104
2.16.2
113
2.25.1
105
114
106
115
diff view generated by jsdifflib
1
The bcm2837 is pretty similar to the bcm2836, but it does have
1
Implement the ITS MOVALL command, which takes all the pending
2
some differences. Notably, the MPIDR affinity aff1 values it
2
interrupts on a source redistributor and makes the not-pending on
3
sets for the CPUs are 0x0, rather than the 0xf that the bcm2836
3
that source redistributor and pending on a destination redistributor.
4
uses, and if this is wrong Linux will not boot.
5
4
6
Rather than trying to have one device with properties that
5
This is a GICv3 ITS command which we forgot to implement. (It is
7
configure it differently for the two cases, create two
6
not used by Linux guests.)
8
separate QOM devices for the two SoCs. We use the same approach
9
as hw/arm/aspeed_soc.c and share code and have a data table
10
that might differ per-SoC. For the moment the two types don't
11
actually have different behaviour.
12
7
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20180313153458.26822-7-peter.maydell@linaro.org
10
Message-id: 20220122182444.724087-14-peter.maydell@linaro.org
16
---
11
---
17
include/hw/arm/bcm2836.h | 19 +++++++++++++++++++
12
hw/intc/gicv3_internal.h | 16 +++++++++++
18
hw/arm/bcm2836.c | 37 ++++++++++++++++++++++++++++++++-----
13
hw/intc/arm_gicv3_its.c | 55 ++++++++++++++++++++++++++++++++++++++
19
hw/arm/raspi.c | 3 ++-
14
hw/intc/arm_gicv3_redist.c | 54 +++++++++++++++++++++++++++++++++++++
20
3 files changed, 53 insertions(+), 6 deletions(-)
15
3 files changed, 125 insertions(+)
21
16
22
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
17
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
23
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/arm/bcm2836.h
19
--- a/hw/intc/gicv3_internal.h
25
+++ b/include/hw/arm/bcm2836.h
20
+++ b/hw/intc/gicv3_internal.h
26
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, CIL, 36, 1)
27
22
#define GITS_CMD_MAPI 0x0B
28
#define BCM283X_NCPUS 4
23
#define GITS_CMD_INV 0x0C
29
24
#define GITS_CMD_INVALL 0x0D
30
+/* These type names are for specific SoCs; other than instantiating
25
+#define GITS_CMD_MOVALL 0x0E
31
+ * them, code using these devices should always handle them via the
26
#define GITS_CMD_DISCARD 0x0F
32
+ * BCM283x base class, so they have no BCM2836(obj) etc macros.
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.
33
+ */
52
+ */
34
+#define TYPE_BCM2836 "bcm2836"
53
+void gicv3_redist_movall_lpis(GICv3CPUState *src, GICv3CPUState *dest);
35
+#define TYPE_BCM2837 "bcm2837"
36
+
54
+
37
typedef struct BCM283XState {
55
void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns);
38
/*< private >*/
56
void gicv3_init_cpuif(GICv3State *s);
39
DeviceState parent_obj;
57
40
@@ -XXX,XX +XXX,XX @@ typedef struct BCM283XState {
58
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
41
BCM2835PeripheralState peripherals;
59
index XXXXXXX..XXXXXXX 100644
42
} BCM283XState;
60
--- a/hw/intc/arm_gicv3_its.c
43
61
+++ b/hw/intc/arm_gicv3_its.c
44
+typedef struct BCM283XInfo BCM283XInfo;
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;
64
}
65
66
+static ItsCmdResult process_movall(GICv3ITSState *s, uint64_t value,
67
+ uint32_t offset)
68
+{
69
+ AddressSpace *as = &s->gicv3->dma_as;
70
+ MemTxResult res = MEMTX_OK;
71
+ uint64_t rd1, rd2;
45
+
72
+
46
+typedef struct BCM283XClass {
73
+ /* No fields in dwords 0 or 1 */
47
+ DeviceClass parent_class;
74
+ offset += NUM_BYTES_IN_DW;
48
+ const BCM283XInfo *info;
75
+ offset += NUM_BYTES_IN_DW;
49
+} BCM283XClass;
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
+ }
50
+
81
+
51
+#define BCM283X_CLASS(klass) \
82
+ rd1 = FIELD_EX64(value, MOVALL_2, RDBASE1);
52
+ OBJECT_CLASS_CHECK(BCM283XClass, (klass), TYPE_BCM283X)
83
+ if (rd1 >= s->gicv3->num_cpu) {
53
+#define BCM283X_GET_CLASS(obj) \
84
+ qemu_log_mask(LOG_GUEST_ERROR,
54
+ OBJECT_GET_CLASS(BCM283XClass, (obj), TYPE_BCM283X)
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
+ }
55
+
90
+
56
#endif /* BCM2836_H */
91
+ offset += NUM_BYTES_IN_DW;
57
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
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
58
index XXXXXXX..XXXXXXX 100644
132
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/arm/bcm2836.c
133
--- a/hw/intc/arm_gicv3_redist.c
60
+++ b/hw/arm/bcm2836.c
134
+++ b/hw/intc/arm_gicv3_redist.c
61
@@ -XXX,XX +XXX,XX @@
135
@@ -XXX,XX +XXX,XX @@ void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level)
62
/* "QA7" (Pi2) interrupt controller and mailboxes etc. */
136
gicv3_redist_lpi_pending(cs, irq, level);
63
#define BCM2836_CONTROL_BASE 0x40000000
64
65
+struct BCM283XInfo {
66
+ const char *name;
67
+};
68
+
69
+static const BCM283XInfo bcm283x_socs[] = {
70
+ {
71
+ .name = TYPE_BCM2836,
72
+ },
73
+ {
74
+ .name = TYPE_BCM2837,
75
+ },
76
+};
77
+
78
static void bcm2836_init(Object *obj)
79
{
80
BCM283XState *s = BCM283X(obj);
81
@@ -XXX,XX +XXX,XX @@ static Property bcm2836_props[] = {
82
DEFINE_PROP_END_OF_LIST()
83
};
84
85
-static void bcm2836_class_init(ObjectClass *oc, void *data)
86
+static void bcm283x_class_init(ObjectClass *oc, void *data)
87
{
88
DeviceClass *dc = DEVICE_CLASS(oc);
89
+ BCM283XClass *bc = BCM283X_CLASS(oc);
90
91
- dc->props = bcm2836_props;
92
+ bc->info = data;
93
dc->realize = bcm2836_realize;
94
+ dc->props = bcm2836_props;
95
}
137
}
96
138
97
-static const TypeInfo bcm2836_type_info = {
139
+void gicv3_redist_movall_lpis(GICv3CPUState *src, GICv3CPUState *dest)
98
+static const TypeInfo bcm283x_type_info = {
140
+{
99
.name = TYPE_BCM283X,
141
+ /*
100
.parent = TYPE_DEVICE,
142
+ * We must move all pending LPIs from the source redistributor
101
.instance_size = sizeof(BCM283XState),
143
+ * to the destination. That is, for every pending LPI X on
102
.instance_init = bcm2836_init,
144
+ * src, we must set it not-pending on src and pending on dest.
103
- .class_init = bcm2836_class_init,
145
+ * LPIs that are already pending on dest are not cleared.
104
+ .class_size = sizeof(BCM283XClass),
146
+ *
105
+ .abstract = true,
147
+ * If LPIs are disabled on dest this is CONSTRAINED UNPREDICTABLE:
106
};
148
+ * we choose to NOP. If LPIs are disabled on source there's nothing
107
149
+ * to be transferred anyway.
108
static void bcm2836_register_types(void)
150
+ */
109
{
151
+ AddressSpace *as = &src->gic->dma_as;
110
- type_register_static(&bcm2836_type_info);
152
+ uint64_t idbits;
153
+ uint32_t pendt_size;
154
+ uint64_t src_baddr, dest_baddr;
111
+ int i;
155
+ int i;
112
+
156
+
113
+ type_register_static(&bcm283x_type_info);
157
+ if (!(src->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) ||
114
+ for (i = 0; i < ARRAY_SIZE(bcm283x_socs); i++) {
158
+ !(dest->gicr_ctlr & GICR_CTLR_ENABLE_LPIS)) {
115
+ TypeInfo ti = {
159
+ return;
116
+ .name = bcm283x_socs[i].name,
117
+ .parent = TYPE_BCM283X,
118
+ .class_init = bcm283x_class_init,
119
+ .class_data = (void *) &bcm283x_socs[i],
120
+ };
121
+ type_register(&ti);
122
+ }
160
+ }
123
}
161
+
124
162
+ idbits = MIN(FIELD_EX64(src->gicr_propbaser, GICR_PROPBASER, IDBITS),
125
type_init(bcm2836_register_types)
163
+ GICD_TYPER_IDBITS);
126
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
164
+ idbits = MIN(FIELD_EX64(dest->gicr_propbaser, GICR_PROPBASER, IDBITS),
127
index XXXXXXX..XXXXXXX 100644
165
+ idbits);
128
--- a/hw/arm/raspi.c
166
+
129
+++ b/hw/arm/raspi.c
167
+ pendt_size = 1ULL << (idbits + 1);
130
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
168
+ src_baddr = src->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
131
BusState *bus;
169
+ dest_baddr = dest->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
132
DeviceState *carddev;
170
+
133
171
+ for (i = GICV3_LPI_INTID_START / 8; i < pendt_size / 8; i++) {
134
- object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM283X);
172
+ uint8_t src_pend, dest_pend;
135
+ object_initialize(&s->soc, sizeof(s->soc),
173
+
136
+ version == 3 ? TYPE_BCM2837 : TYPE_BCM2836);
174
+ address_space_read(as, src_baddr + i, MEMTXATTRS_UNSPECIFIED,
137
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
175
+ &src_pend, sizeof(src_pend));
138
&error_abort);
176
+ if (!src_pend) {
139
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);
191
+}
192
+
193
void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level)
194
{
195
/* Update redistributor state for a change in an external PPI input line */
140
--
196
--
141
2.16.2
197
2.25.1
142
198
143
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: Guenter Roeck <linux@roeck-us.net>
1
From: Cédric Le Goater <clg@kaod.org>
2
2
3
The sabrelite machine model used by qemu-system-arm is based on the
3
Address should be 0x1E631000 and not 0x1E641000 as initially introduced.
4
Freescale/NXP i.MX6Q processor. This SoC has an on-board ethernet
5
controller which is supported in QEMU using the imx_fec.c module
6
(actually called imx.enet for this model.)
7
4
8
The include/hw/arm/fsm-imx6.h file defines the interrupt vectors for the
5
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/838
9
imx.enet device like this:
6
Fixes: f25c0ae1079d ("aspeed/soc: Add AST2600 support")
10
7
Suggested-by: Troy Lee <troy_lee@aspeedtech.com>
11
#define FSL_IMX6_ENET_MAC_1588_IRQ 118
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
#define FSL_IMX6_ENET_MAC_IRQ 119
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
10
Message-id: 20220126083520.4135713-1-clg@kaod.org
14
According to https://www.nxp.com/docs/en/reference-manual/IMX6DQRM.pdf,
15
page 225, in Table 3-1. ARM Cortex A9 domain interrupt summary,
16
interrupts are as follows.
17
18
150 ENET MAC 0 IRQ
19
151 ENET MAC 0 1588 Timer interrupt
20
21
where
22
23
150 - 32 == 118
24
151 - 32 == 119
25
26
In other words, the vector definitions in the fsl-imx6.h file are reversed.
27
28
Fixing the interrupts alone causes problems with older Linux kernels:
29
The Ethernet interface will fail to probe with Linux v4.9 and earlier.
30
Linux v4.1 and earlier will crash due to a bug in Ethernet driver probe
31
error handling. This is a Linux kernel problem, not a qemu problem:
32
the Linux kernel only worked by accident since it requested both interrupts.
33
34
For backward compatibility, generate the Ethernet interrupt on both interrupt
35
lines. This was shown to work from all Linux kernel releases starting with
36
v3.16.
37
38
Link: https://bugs.launchpad.net/qemu/+bug/1753309
39
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
40
Message-id: 1520723090-22130-1-git-send-email-linux@roeck-us.net
41
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
42
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
---
12
---
44
include/hw/arm/fsl-imx6.h | 4 ++--
13
hw/arm/aspeed_ast2600.c | 2 +-
45
hw/net/imx_fec.c | 28 +++++++++++++++++++++++++++-
14
1 file changed, 1 insertion(+), 1 deletion(-)
46
2 files changed, 29 insertions(+), 3 deletions(-)
47
15
48
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
16
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
49
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
50
--- a/include/hw/arm/fsl-imx6.h
18
--- a/hw/arm/aspeed_ast2600.c
51
+++ b/include/hw/arm/fsl-imx6.h
19
+++ b/hw/arm/aspeed_ast2600.c
52
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX6State {
20
@@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
53
#define FSL_IMX6_HDMI_MASTER_IRQ 115
21
[ASPEED_DEV_PWM] = 0x1E610000,
54
#define FSL_IMX6_HDMI_CEC_IRQ 116
22
[ASPEED_DEV_FMC] = 0x1E620000,
55
#define FSL_IMX6_MLB150_LOW_IRQ 117
23
[ASPEED_DEV_SPI1] = 0x1E630000,
56
-#define FSL_IMX6_ENET_MAC_1588_IRQ 118
24
- [ASPEED_DEV_SPI2] = 0x1E641000,
57
-#define FSL_IMX6_ENET_MAC_IRQ 119
25
+ [ASPEED_DEV_SPI2] = 0x1E631000,
58
+#define FSL_IMX6_ENET_MAC_IRQ 118
26
[ASPEED_DEV_EHCI1] = 0x1E6A1000,
59
+#define FSL_IMX6_ENET_MAC_1588_IRQ 119
27
[ASPEED_DEV_EHCI2] = 0x1E6A3000,
60
#define FSL_IMX6_PCIE1_IRQ 120
28
[ASPEED_DEV_MII1] = 0x1E650000,
61
#define FSL_IMX6_PCIE2_IRQ 121
62
#define FSL_IMX6_PCIE3_IRQ 122
63
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/net/imx_fec.c
66
+++ b/hw/net/imx_fec.c
67
@@ -XXX,XX +XXX,XX @@ static void imx_enet_write_bd(IMXENETBufDesc *bd, dma_addr_t addr)
68
69
static void imx_eth_update(IMXFECState *s)
70
{
71
- if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_TS_TIMER) {
72
+ /*
73
+ * Previous versions of qemu had the ENET_INT_MAC and ENET_INT_TS_TIMER
74
+ * interrupts swapped. This worked with older versions of Linux (4.14
75
+ * and older) since Linux associated both interrupt lines with Ethernet
76
+ * MAC interrupts. Specifically,
77
+ * - Linux 4.15 and later have separate interrupt handlers for the MAC and
78
+ * timer interrupts. Those versions of Linux fail with versions of QEMU
79
+ * with swapped interrupt assignments.
80
+ * - In linux 4.14, both interrupt lines were registered with the Ethernet
81
+ * MAC interrupt handler. As a result, all versions of qemu happen to
82
+ * work, though that is accidental.
83
+ * - In Linux 4.9 and older, the timer interrupt was registered directly
84
+ * with the Ethernet MAC interrupt handler. The MAC interrupt was
85
+ * redirected to a GPIO interrupt to work around erratum ERR006687.
86
+ * This was implemented using the SOC's IOMUX block. In qemu, this GPIO
87
+ * interrupt never fired since IOMUX is currently not supported in qemu.
88
+ * Linux instead received MAC interrupts on the timer interrupt.
89
+ * As a result, qemu versions with the swapped interrupt assignment work,
90
+ * albeit accidentally, but qemu versions with the correct interrupt
91
+ * assignment fail.
92
+ *
93
+ * To ensure that all versions of Linux work, generate ENET_INT_MAC
94
+ * interrrupts on both interrupt lines. This should be changed if and when
95
+ * qemu supports IOMUX.
96
+ */
97
+ if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] &
98
+ (ENET_INT_MAC | ENET_INT_TS_TIMER)) {
99
qemu_set_irq(s->irq[1], 1);
100
} else {
101
qemu_set_irq(s->irq[1], 0);
102
--
29
--
103
2.16.2
30
2.25.1
104
31
105
32
diff view generated by jsdifflib
1
For the rpi1 and 2 we want to boot the Linux kernel via some
1
The exception caused by an SVC instruction may be taken to AArch32
2
custom setup code that makes sure that the SMC instruction
2
Hyp mode for two reasons:
3
acts as a no-op, because it's used for cache maintenance.
3
* HCR.TGE indicates that exceptions from EL0 should trap to EL2
4
The rpi3 boots AArch64 kernels, which don't need SMC for
4
* we were already in Hyp mode
5
cache maintenance and always expect to be booted non-secure.
5
6
Don't fill in the aarch32-specific parts of the binfo struct.
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
}
7
22
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
24
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20180313153458.26822-2-peter.maydell@linaro.org
26
Message-id: 20220117131953.3936137-1-peter.maydell@linaro.org
12
---
27
---
13
hw/arm/raspi.c | 17 +++++++++++++----
28
target/arm/helper.c | 4 ++--
14
1 file changed, 13 insertions(+), 4 deletions(-)
29
1 file changed, 2 insertions(+), 2 deletions(-)
15
30
16
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
31
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/raspi.c
33
--- a/target/arm/helper.c
19
+++ b/hw/arm/raspi.c
34
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
35
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
21
binfo.board_id = raspi_boardid[version];
36
* separately here.
22
binfo.ram_size = ram_size;
37
*
23
binfo.nb_cpus = smp_cpus;
38
* The vector table entry used is always the 0x14 Hyp mode entry point,
24
- binfo.board_setup_addr = BOARDSETUP_ADDR;
39
- * unless this is an UNDEF/HVC/abort taken from Hyp to Hyp.
25
- binfo.write_board_setup = write_board_setup;
40
+ * unless this is an UNDEF/SVC/HVC/abort taken from Hyp to Hyp.
26
- binfo.secure_board_setup = true;
41
* The offset applied to the preferred return address is always zero
27
- binfo.secure_boot = true;
42
* (see DDI0487C.a section G1.12.3).
28
+
43
* PSTATE A/I/F masks are set based only on the SCR.EA/IRQ/FIQ values.
29
+ if (version <= 2) {
44
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
30
+ /* The rpi1 and 2 require some custom setup code to run in Secure
45
addr = 0x04;
31
+ * mode before booting a kernel (to set up the SMC vectors so
46
break;
32
+ * that we get a no-op SMC; this is used by Linux to call the
47
case EXCP_SWI:
33
+ * firmware for some cache maintenance operations.
48
- addr = 0x14;
34
+ * The rpi3 doesn't need this.
49
+ addr = 0x08;
35
+ */
50
break;
36
+ binfo.board_setup_addr = BOARDSETUP_ADDR;
51
case EXCP_BKPT:
37
+ binfo.write_board_setup = write_board_setup;
52
/* Fall through to prefetch abort. */
38
+ binfo.secure_board_setup = true;
39
+ binfo.secure_boot = true;
40
+ }
41
42
/* Pi2 and Pi3 requires SMP setup */
43
if (version >= 2) {
44
--
53
--
45
2.16.2
54
2.25.1
46
55
47
56
diff view generated by jsdifflib