1
Last handful of arm patches before softfreeze...
1
The following changes since commit b367db48126d4ee14579af6cf5cdbffeb9496627:
2
2
3
The following changes since commit a98135f727595382e200d04c2996e868b7925a01:
3
Merge remote-tracking branch 'remotes/aperard/tags/pull-xen-20220127' into staging (2022-01-28 11:05:29 +0000)
4
5
Merge remote-tracking branch 'remotes/kraxel/tags/vga-20200316-pull-request' into staging (2020-03-16 14:55:59 +0000)
6
4
7
are available in the Git repository at:
5
are available in the Git repository at:
8
6
9
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200317
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220128
10
8
11
for you to fetch changes up to e88d3671e3bbd59d385838a4101ea19cdcf47309:
9
for you to fetch changes up to 2c023d3675a3ffb54fc30504dcd715bc6f6e234f:
12
10
13
hw/arm/pxa2xx: Do not wire up OHCI for PXA255 (2020-03-17 11:36:48 +0000)
11
target/arm: Use correct entrypoint for SVC taken from Hyp to Hyp (2022-01-28 14:30:36 +0000)
14
12
15
----------------------------------------------------------------
13
----------------------------------------------------------------
16
target-arm:
14
target-arm queue:
17
* hw/arm/pxa2xx: Do not wire up OHCI for PXA255
15
* Update copyright dates to 2022
18
* aspeed/smc: Fix number of dummy cycles for FAST_READ_4 command
16
* hw/armv7m: Fix broken VMStateDescription
19
* m25p80: Improve command handling for Jedec and unsupported commands
17
* hw/char/exynos4210_uart: Fix crash on trying to load VM state
20
* hw/net/imx_fec: write TGSR and TCSR3 in imx_enet_write()
18
* rtc: Move RTC function prototypes to their own header
21
* hw/arm/fsl-imx6, imx6ul: Wire up USB controllers
19
* xlnx-versal-virt: Support PMC SLCR
22
* hw/arm/fsl-imx6ul: Instantiate unimplemented pwm and can devices
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
23
27
24
----------------------------------------------------------------
28
----------------------------------------------------------------
25
Chen Qun (1):
29
Andrew Baumann (1):
26
hw/net/imx_fec: write TGSR and TCSR3 in imx_enet_write()
30
MAINTAINERS: Remove myself (for raspi).
27
31
28
Guenter Roeck (10):
32
Cédric Le Goater (1):
29
hw/usb: Add basic i.MX USB Phy support
33
hw/arm: ast2600: Fix address mapping of second SPI controller
30
hw/arm/fsl-imx6ul: Fix USB interrupt numbers
31
hw/arm/fsl-imx6ul: Instantiate unimplemented pwm and can devices
32
hw/arm/fsl-imx6ul: Wire up USB controllers
33
hw/arm/fsl-imx6: Wire up USB controllers
34
m25p80: Convert to support tracing
35
m25p80: Improve command handling for Jedec commands
36
m25p80: Improve command handling for unsupported commands
37
aspeed/smc: Fix number of dummy cycles for FAST_READ_4 command
38
hw/arm/pxa2xx: Do not wire up OHCI for PXA255
39
34
40
hw/usb/Makefile.objs | 2 +
35
Francisco Iglesias (10):
41
include/hw/arm/fsl-imx6.h | 6 ++
36
hw/misc: Add a model of Versal's PMC SLCR
42
include/hw/arm/fsl-imx6ul.h | 16 ++-
37
hw/arm/xlnx-versal: 'Or' the interrupts from the BBRAM and RTC models
43
include/hw/usb/imx-usb-phy.h | 53 ++++++++++
38
hw/arm/xlnx-versal: Connect Versal's PMC SLCR
44
hw/arm/fsl-imx6.c | 36 +++++++
39
include/hw/dma/xlnx_csu_dma: Add in missing includes in the header
45
hw/arm/fsl-imx6ul.c | 49 ++++++++++
40
hw/dma/xlnx_csu_dma: Support starting a read transfer through a class method
46
hw/arm/pxa2xx.c | 3 -
41
hw/ssi: Add a model of Xilinx Versal's OSPI flash memory controller
47
hw/block/m25p80.c | 58 +++++------
42
hw/arm/xlnx-versal: Connect the OSPI flash memory controller model
48
hw/net/imx_fec.c | 6 +-
43
hw/block/m25p80: Add support for Micron Xccela flash mt35xu01g
49
hw/ssi/aspeed_smc.c | 2 +-
44
hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI
50
hw/usb/imx-usb-phy.c | 225 +++++++++++++++++++++++++++++++++++++++++++
45
MAINTAINERS: Add an entry for Xilinx Versal OSPI
51
MAINTAINERS | 2 +
52
hw/arm/Kconfig | 1 +
53
hw/block/trace-events | 16 +++
54
hw/usb/Kconfig | 5 +
55
15 files changed, 444 insertions(+), 36 deletions(-)
56
create mode 100644 include/hw/usb/imx-usb-phy.h
57
create mode 100644 hw/usb/imx-usb-phy.c
58
46
47
Peter Maydell (20):
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
68
69
docs/conf.py | 2 +-
70
hw/intc/gicv3_internal.h | 43 +-
71
include/hw/arm/xlnx-versal.h | 30 +-
72
include/hw/dma/xlnx_csu_dma.h | 24 +-
73
include/hw/intc/arm_gicv3_its_common.h | 1 -
74
include/hw/misc/xlnx-versal-pmc-iou-slcr.h | 78 ++
75
include/hw/ssi/xlnx-versal-ospi.h | 111 ++
76
include/qemu-common.h | 5 +-
77
include/sysemu/rtc.h | 58 +
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
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
1
From: Guenter Roeck <linux@roeck-us.net>
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.
2
5
3
PXA255 does not support a USB OHCI controller, so don't wire it up.
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.
4
9
5
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
10
The license for the .h file follows that of the softmmu/rtc.c
6
Message-id: 20200313160215.28155-1-linux@roeck-us.net
11
where both the functions are defined.
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
---
15
---
10
hw/arm/pxa2xx.c | 3 ---
16
include/qemu-common.h | 3 ---
11
1 file changed, 3 deletions(-)
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
12
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"
13
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
141
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
14
index XXXXXXX..XXXXXXX 100644
142
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/pxa2xx.c
143
--- a/hw/arm/pxa2xx.c
16
+++ b/hw/arm/pxa2xx.c
144
+++ b/hw/arm/pxa2xx.c
17
@@ -XXX,XX +XXX,XX @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
145
@@ -XXX,XX +XXX,XX @@
18
s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
146
*/
19
}
147
20
148
#include "qemu/osdep.h"
21
- sysbus_create_simple("sysbus-ohci", 0x4c000000,
149
-#include "qemu-common.h"
22
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1));
150
#include "qemu/error-report.h"
23
-
151
#include "qemu/module.h"
24
s->pcmcia[0] = pxa2xx_pcmcia_init(address_space, 0x20000000);
152
#include "qapi/error.h"
25
s->pcmcia[1] = pxa2xx_pcmcia_init(address_space, 0x30000000);
153
@@ -XXX,XX +XXX,XX @@
26
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,
27
--
539
--
28
2.20.1
540
2.25.1
29
541
30
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
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
2
2
3
Whenever an unsupported command is encountered, the current code
3
Add in the missing includes in the header for being able to build the DMA
4
interprets each transferred byte as new command. Most of the time, those
4
model when reusing it.
5
'commands' are interpreted as new unknown commands. However, in rare
6
cases, it may be that for example address or length information
7
passed with the original command is by itself a valid command.
8
If that happens, the state machine may get completely confused and,
9
worst case, start writing data into the flash or even erase it.
10
5
11
To avoid the problem, transition into STATE_READING_DATA and keep
6
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
12
sending a value of 0 until the chip is deselected after encountering
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
an unsupported command.
8
Reviewed-by: Luc Michel <luc@lmichel.fr>
14
9
Message-id: 20220121161141.14389-5-francisco.iglesias@xilinx.com
15
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
16
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
Reviewed-by: Cédric Le Goater <clg@kaod.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
11
---
20
hw/block/m25p80.c | 5 +++++
12
include/hw/dma/xlnx_csu_dma.h | 5 +++++
21
1 file changed, 5 insertions(+)
13
1 file changed, 5 insertions(+)
22
14
23
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
15
diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/block/m25p80.c
17
--- a/include/hw/dma/xlnx_csu_dma.h
26
+++ b/hw/block/m25p80.c
18
+++ b/include/hw/dma/xlnx_csu_dma.h
27
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
19
@@ -XXX,XX +XXX,XX @@
28
s->quad_enable = false;
20
#ifndef XLNX_CSU_DMA_H
29
break;
21
#define XLNX_CSU_DMA_H
30
default:
22
31
+ s->pos = 0;
23
+#include "hw/sysbus.h"
32
+ s->len = 1;
24
+#include "hw/register.h"
33
+ s->state = STATE_READING_DATA;
25
+#include "hw/ptimer.h"
34
+ s->data_read_loop = true;
26
+#include "hw/stream.h"
35
+ s->data[0] = 0;
27
+
36
qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Unknown cmd %x\n", value);
28
#define TYPE_XLNX_CSU_DMA "xlnx.csu_dma"
37
break;
29
38
}
30
#define XLNX_CSU_DMA_R_MAX (0x2c / 4)
39
--
31
--
40
2.20.1
32
2.25.1
41
33
42
34
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
2
2
3
Recent Linux kernels (post v4.20) crash due to accesses to flexcan
3
An option on real hardware when embedding a DMA engine into a peripheral
4
and pwm controllers. Instantiate as unimplemented devices to work
4
is to make the peripheral control the engine through a custom DMA control
5
around the problem.
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).
6
12
7
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
13
This patch adds a class 'read' method for allowing to start read transfers
8
Message-id: 20200313014551.12554-4-linux@roeck-us.net
14
from peripherals embedding and controlling the Xilinx CSU DMA engine as in
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
21
---
12
hw/arm/fsl-imx6ul.c | 14 ++++++++++++++
22
include/hw/dma/xlnx_csu_dma.h | 19 +++++++++++++++++--
13
1 file changed, 14 insertions(+)
23
hw/dma/xlnx_csu_dma.c | 17 +++++++++++++++++
24
2 files changed, 34 insertions(+), 2 deletions(-)
14
25
15
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
26
diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
16
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/fsl-imx6ul.c
28
--- a/include/hw/dma/xlnx_csu_dma.h
18
+++ b/hw/arm/fsl-imx6ul.c
29
+++ b/include/hw/dma/xlnx_csu_dma.h
19
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
30
@@ -XXX,XX +XXX,XX @@ typedef struct XlnxCSUDMA {
20
*/
31
RegisterInfo regs_info[XLNX_CSU_DMA_R_MAX];
21
create_unimplemented_device("sdma", FSL_IMX6UL_SDMA_ADDR, 0x4000);
32
} XlnxCSUDMA;
22
33
23
+ /*
34
-#define XLNX_CSU_DMA(obj) \
24
+ * PWM
35
- OBJECT_CHECK(XlnxCSUDMA, (obj), TYPE_XLNX_CSU_DMA)
25
+ */
36
+OBJECT_DECLARE_TYPE(XlnxCSUDMA, XlnxCSUDMAClass, XLNX_CSU_DMA)
26
+ create_unimplemented_device("pwm1", FSL_IMX6UL_PWM1_ADDR, 0x4000);
37
+
27
+ create_unimplemented_device("pwm2", FSL_IMX6UL_PWM2_ADDR, 0x4000);
38
+struct XlnxCSUDMAClass {
28
+ create_unimplemented_device("pwm3", FSL_IMX6UL_PWM3_ADDR, 0x4000);
39
+ SysBusDeviceClass parent_class;
29
+ create_unimplemented_device("pwm4", FSL_IMX6UL_PWM4_ADDR, 0x4000);
30
+
40
+
31
+ /*
41
+ /*
32
+ * CAN
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.
33
+ */
50
+ */
34
+ create_unimplemented_device("can1", FSL_IMX6UL_CAN1_ADDR, 0x4000);
51
+ MemTxResult (*read)(XlnxCSUDMA *s, hwaddr addr, uint32_t len);
35
+ create_unimplemented_device("can2", FSL_IMX6UL_CAN2_ADDR, 0x4000);
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);
36
+
68
+
37
/*
69
+ s->regs[R_ADDR] = addr;
38
* APHB_DMA
70
+ s->regs[R_ADDR_MSB] = (uint64_t)addr >> 32;
39
*/
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)
40
--
97
--
41
2.20.1
98
2.25.1
42
99
43
100
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
2
2
3
Add basic USB PHY support as implemented in i.MX23, i.MX28, i.MX6,
3
Add a model of Xilinx Versal's OSPI flash memory controller.
4
and i.MX7 SoCs.
5
4
6
The only support really needed - at least to boot Linux - is support
5
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
7
for soft reset, which needs to reset various registers to their initial
6
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
value. Otherwise, just record register values.
7
Message-id: 20220121161141.14389-7-francisco.iglesias@xilinx.com
9
8
[PMM: fixed indent]
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
12
Message-id: 20200313014551.12554-2-linux@roeck-us.net
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
10
---
15
hw/usb/Makefile.objs | 2 +
11
include/hw/ssi/xlnx-versal-ospi.h | 111 ++
16
include/hw/usb/imx-usb-phy.h | 53 +++++++++
12
hw/ssi/xlnx-versal-ospi.c | 1853 +++++++++++++++++++++++++++++
17
hw/usb/imx-usb-phy.c | 225 +++++++++++++++++++++++++++++++++++
13
hw/ssi/meson.build | 1 +
18
MAINTAINERS | 2 +
14
3 files changed, 1965 insertions(+)
19
hw/arm/Kconfig | 1 +
15
create mode 100644 include/hw/ssi/xlnx-versal-ospi.h
20
hw/usb/Kconfig | 5 +
16
create mode 100644 hw/ssi/xlnx-versal-ospi.c
21
6 files changed, 288 insertions(+)
22
create mode 100644 include/hw/usb/imx-usb-phy.h
23
create mode 100644 hw/usb/imx-usb-phy.c
24
17
25
diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
18
diff --git a/include/hw/ssi/xlnx-versal-ospi.h b/include/hw/ssi/xlnx-versal-ospi.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/usb/Makefile.objs
28
+++ b/hw/usb/Makefile.objs
29
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XEN) += xen-usb.o
30
xen-usb.o-cflags := $(LIBUSB_CFLAGS)
31
xen-usb.o-libs := $(LIBUSB_LIBS)
32
endif
33
+
34
+common-obj-$(CONFIG_IMX_USBPHY) += imx-usb-phy.o
35
diff --git a/include/hw/usb/imx-usb-phy.h b/include/hw/usb/imx-usb-phy.h
36
new file mode 100644
19
new file mode 100644
37
index XXXXXXX..XXXXXXX
20
index XXXXXXX..XXXXXXX
38
--- /dev/null
21
--- /dev/null
39
+++ b/include/hw/usb/imx-usb-phy.h
22
+++ b/include/hw/ssi/xlnx-versal-ospi.h
40
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
41
+#ifndef IMX_USB_PHY_H
24
+/*
42
+#define IMX_USB_PHY_H
25
+ * Header file for the Xilinx Versal's OSPI controller
43
+
26
+ *
44
+#include "hw/sysbus.h"
27
+ * Copyright (C) 2021 Xilinx Inc
45
+#include "qemu/bitops.h"
28
+ * Written by Francisco Iglesias <francisco.iglesias@xilinx.com>
46
+
29
+ *
47
+enum IMXUsbPhyRegisters {
30
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
48
+ USBPHY_PWD,
31
+ * of this software and associated documentation files (the "Software"), to deal
49
+ USBPHY_PWD_SET,
32
+ * in the Software without restriction, including without limitation the rights
50
+ USBPHY_PWD_CLR,
33
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
51
+ USBPHY_PWD_TOG,
34
+ * copies of the Software, and to permit persons to whom the Software is
52
+ USBPHY_TX,
35
+ * furnished to do so, subject to the following conditions:
53
+ USBPHY_TX_SET,
36
+ *
54
+ USBPHY_TX_CLR,
37
+ * The above copyright notice and this permission notice shall be included in
55
+ USBPHY_TX_TOG,
38
+ * all copies or substantial portions of the Software.
56
+ USBPHY_RX,
39
+ *
57
+ USBPHY_RX_SET,
40
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
58
+ USBPHY_RX_CLR,
41
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
59
+ USBPHY_RX_TOG,
42
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
60
+ USBPHY_CTRL,
43
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
61
+ USBPHY_CTRL_SET,
44
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
62
+ USBPHY_CTRL_CLR,
45
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
63
+ USBPHY_CTRL_TOG,
46
+ * THE SOFTWARE.
64
+ USBPHY_STATUS,
47
+ */
65
+ USBPHY_DEBUG = 0x14,
48
+
66
+ USBPHY_DEBUG_SET,
49
+/*
67
+ USBPHY_DEBUG_CLR,
50
+ * This is a model of Xilinx Versal's Octal SPI flash memory controller
68
+ USBPHY_DEBUG_TOG,
51
+ * documented in Versal's Technical Reference manual [1] and the Versal ACAP
69
+ USBPHY_DEBUG0_STATUS,
52
+ * Register reference [2].
70
+ USBPHY_DEBUG1 = 0x1c,
53
+ *
71
+ USBPHY_DEBUG1_SET,
54
+ * References:
72
+ USBPHY_DEBUG1_CLR,
55
+ *
73
+ USBPHY_DEBUG1_TOG,
56
+ * [1] Versal ACAP Technical Reference Manual,
74
+ USBPHY_VERSION,
57
+ * https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
75
+ USBPHY_MAX
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];
76
+};
132
+};
77
+
133
+
78
+#define USBPHY_CTRL_SFTRST BIT(31)
134
+#endif /* XILINX_VERSAL_OSPI_H */
79
+
135
diff --git a/hw/ssi/xlnx-versal-ospi.c b/hw/ssi/xlnx-versal-ospi.c
80
+#define TYPE_IMX_USBPHY "imx.usbphy"
81
+#define IMX_USBPHY(obj) OBJECT_CHECK(IMXUSBPHYState, (obj), TYPE_IMX_USBPHY)
82
+
83
+typedef struct IMXUSBPHYState {
84
+ /* <private> */
85
+ SysBusDevice parent_obj;
86
+
87
+ /* <public> */
88
+ MemoryRegion iomem;
89
+
90
+ uint32_t usbphy[USBPHY_MAX];
91
+} IMXUSBPHYState;
92
+
93
+#endif /* IMX_USB_PHY_H */
94
diff --git a/hw/usb/imx-usb-phy.c b/hw/usb/imx-usb-phy.c
95
new file mode 100644
136
new file mode 100644
96
index XXXXXXX..XXXXXXX
137
index XXXXXXX..XXXXXXX
97
--- /dev/null
138
--- /dev/null
98
+++ b/hw/usb/imx-usb-phy.c
139
+++ b/hw/ssi/xlnx-versal-ospi.c
99
@@ -XXX,XX +XXX,XX @@
140
@@ -XXX,XX +XXX,XX @@
100
+/*
141
+/*
101
+ * i.MX USB PHY
142
+ * QEMU model of Xilinx Versal's OSPI controller.
102
+ *
143
+ *
103
+ * Copyright (c) 2020 Guenter Roeck <linux@roeck-us.net>
144
+ * Copyright (c) 2021 Xilinx Inc.
145
+ * Written by Francisco Iglesias <francisco.iglesias@xilinx.com>
104
+ *
146
+ *
105
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
147
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
106
+ * See the COPYING file in the top-level directory.
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:
107
+ *
153
+ *
108
+ * We need to implement basic reset control in the PHY control register.
154
+ * The above copyright notice and this permission notice shall be included in
109
+ * For everything else, it is sufficient to set whatever is written.
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.
110
+ */
164
+ */
111
+
112
+#include "qemu/osdep.h"
165
+#include "qemu/osdep.h"
113
+#include "hw/usb/imx-usb-phy.h"
166
+#include "hw/sysbus.h"
114
+#include "migration/vmstate.h"
167
+#include "migration/vmstate.h"
168
+#include "hw/qdev-properties.h"
169
+#include "qemu/bitops.h"
115
+#include "qemu/log.h"
170
+#include "qemu/log.h"
116
+#include "qemu/module.h"
171
+#include "hw/irq.h"
117
+
172
+#include "hw/ssi/xlnx-versal-ospi.h"
118
+static const VMStateDescription vmstate_imx_usbphy = {
173
+
119
+ .name = TYPE_IMX_USBPHY,
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",
120
+ .version_id = 1,
1928
+ .version_id = 1,
121
+ .minimum_version_id = 1,
1929
+ .minimum_version_id = 1,
122
+ .fields = (VMStateField[]) {
1930
+ .fields = (VMStateField[]) {
123
+ VMSTATE_UINT32_ARRAY(usbphy, IMXUSBPHYState, USBPHY_MAX),
1931
+ VMSTATE_UINT32(flash_addr, IndOp),
1932
+ VMSTATE_UINT32(num_bytes, IndOp),
1933
+ VMSTATE_UINT32(done_bytes, IndOp),
1934
+ VMSTATE_BOOL(completed, IndOp),
124
+ VMSTATE_END_OF_LIST()
1935
+ VMSTATE_END_OF_LIST()
125
+ },
1936
+ }
126
+};
1937
+};
127
+
1938
+
128
+static void imx_usbphy_softreset(IMXUSBPHYState *s)
1939
+static const VMStateDescription vmstate_xlnx_versal_ospi = {
129
+{
1940
+ .name = TYPE_XILINX_VERSAL_OSPI,
130
+ s->usbphy[USBPHY_PWD] = 0x001e1c00;
1941
+ .version_id = 1,
131
+ s->usbphy[USBPHY_TX] = 0x10060607;
1942
+ .minimum_version_id = 1,
132
+ s->usbphy[USBPHY_RX] = 0x00000000;
1943
+ .minimum_version_id_old = 1,
133
+ s->usbphy[USBPHY_CTRL] = 0xc0200000;
1944
+ .fields = (VMStateField[]) {
134
+}
1945
+ VMSTATE_FIFO8(rx_fifo, XlnxVersalOspi),
135
+
1946
+ VMSTATE_FIFO8(tx_fifo, XlnxVersalOspi),
136
+static void imx_usbphy_reset(DeviceState *dev)
1947
+ VMSTATE_FIFO8(rx_sram, XlnxVersalOspi),
137
+{
1948
+ VMSTATE_FIFO8(tx_sram, XlnxVersalOspi),
138
+ IMXUSBPHYState *s = IMX_USBPHY(dev);
1949
+ VMSTATE_BOOL(ind_write_disabled, XlnxVersalOspi),
139
+
1950
+ VMSTATE_BOOL(dac_with_indac, XlnxVersalOspi),
140
+ s->usbphy[USBPHY_STATUS] = 0x00000000;
1951
+ VMSTATE_BOOL(dac_enable, XlnxVersalOspi),
141
+ s->usbphy[USBPHY_DEBUG] = 0x7f180000;
1952
+ VMSTATE_BOOL(src_dma_inprog, XlnxVersalOspi),
142
+ s->usbphy[USBPHY_DEBUG0_STATUS] = 0x00000000;
1953
+ VMSTATE_STRUCT_ARRAY(rd_ind_op, XlnxVersalOspi, 2, 1,
143
+ s->usbphy[USBPHY_DEBUG1] = 0x00001000;
1954
+ vmstate_ind_op, IndOp),
144
+ s->usbphy[USBPHY_VERSION] = 0x04020000;
1955
+ VMSTATE_STRUCT_ARRAY(wr_ind_op, XlnxVersalOspi, 2, 1,
145
+
1956
+ vmstate_ind_op, IndOp),
146
+ imx_usbphy_softreset(s);
1957
+ VMSTATE_UINT32_ARRAY(regs, XlnxVersalOspi, XILINX_VERSAL_OSPI_R_MAX),
147
+}
1958
+ VMSTATE_UINT8_ARRAY(stig_membank, XlnxVersalOspi, 512),
148
+
1959
+ VMSTATE_END_OF_LIST(),
149
+static uint64_t imx_usbphy_read(void *opaque, hwaddr offset, unsigned size)
1960
+ }
150
+{
151
+ IMXUSBPHYState *s = (IMXUSBPHYState *)opaque;
152
+ uint32_t index = offset >> 2;
153
+ uint32_t value;
154
+
155
+ switch (index) {
156
+ case USBPHY_PWD_SET:
157
+ case USBPHY_TX_SET:
158
+ case USBPHY_RX_SET:
159
+ case USBPHY_CTRL_SET:
160
+ case USBPHY_DEBUG_SET:
161
+ case USBPHY_DEBUG1_SET:
162
+ /*
163
+ * All REG_NAME_SET register access are in fact targeting the
164
+ * REG_NAME register.
165
+ */
166
+ value = s->usbphy[index - 1];
167
+ break;
168
+ case USBPHY_PWD_CLR:
169
+ case USBPHY_TX_CLR:
170
+ case USBPHY_RX_CLR:
171
+ case USBPHY_CTRL_CLR:
172
+ case USBPHY_DEBUG_CLR:
173
+ case USBPHY_DEBUG1_CLR:
174
+ /*
175
+ * All REG_NAME_CLR register access are in fact targeting the
176
+ * REG_NAME register.
177
+ */
178
+ value = s->usbphy[index - 2];
179
+ break;
180
+ case USBPHY_PWD_TOG:
181
+ case USBPHY_TX_TOG:
182
+ case USBPHY_RX_TOG:
183
+ case USBPHY_CTRL_TOG:
184
+ case USBPHY_DEBUG_TOG:
185
+ case USBPHY_DEBUG1_TOG:
186
+ /*
187
+ * All REG_NAME_TOG register access are in fact targeting the
188
+ * REG_NAME register.
189
+ */
190
+ value = s->usbphy[index - 3];
191
+ break;
192
+ default:
193
+ value = s->usbphy[index];
194
+ break;
195
+ }
196
+ return (uint64_t)value;
197
+}
198
+
199
+static void imx_usbphy_write(void *opaque, hwaddr offset, uint64_t value,
200
+ unsigned size)
201
+{
202
+ IMXUSBPHYState *s = (IMXUSBPHYState *)opaque;
203
+ uint32_t index = offset >> 2;
204
+
205
+ switch (index) {
206
+ case USBPHY_CTRL:
207
+ s->usbphy[index] = value;
208
+ if (value & USBPHY_CTRL_SFTRST) {
209
+ imx_usbphy_softreset(s);
210
+ }
211
+ break;
212
+ case USBPHY_PWD:
213
+ case USBPHY_TX:
214
+ case USBPHY_RX:
215
+ case USBPHY_STATUS:
216
+ case USBPHY_DEBUG:
217
+ case USBPHY_DEBUG1:
218
+ s->usbphy[index] = value;
219
+ break;
220
+ case USBPHY_CTRL_SET:
221
+ s->usbphy[index - 1] |= value;
222
+ if (value & USBPHY_CTRL_SFTRST) {
223
+ imx_usbphy_softreset(s);
224
+ }
225
+ break;
226
+ case USBPHY_PWD_SET:
227
+ case USBPHY_TX_SET:
228
+ case USBPHY_RX_SET:
229
+ case USBPHY_DEBUG_SET:
230
+ case USBPHY_DEBUG1_SET:
231
+ /*
232
+ * All REG_NAME_SET register access are in fact targeting the
233
+ * REG_NAME register. So we change the value of the REG_NAME
234
+ * register, setting bits passed in the value.
235
+ */
236
+ s->usbphy[index - 1] |= value;
237
+ break;
238
+ case USBPHY_PWD_CLR:
239
+ case USBPHY_TX_CLR:
240
+ case USBPHY_RX_CLR:
241
+ case USBPHY_CTRL_CLR:
242
+ case USBPHY_DEBUG_CLR:
243
+ case USBPHY_DEBUG1_CLR:
244
+ /*
245
+ * All REG_NAME_CLR register access are in fact targeting the
246
+ * REG_NAME register. So we change the value of the REG_NAME
247
+ * register, unsetting bits passed in the value.
248
+ */
249
+ s->usbphy[index - 2] &= ~value;
250
+ break;
251
+ case USBPHY_CTRL_TOG:
252
+ s->usbphy[index - 3] ^= value;
253
+ if ((value & USBPHY_CTRL_SFTRST) &&
254
+ (s->usbphy[index - 3] & USBPHY_CTRL_SFTRST)) {
255
+ imx_usbphy_softreset(s);
256
+ }
257
+ break;
258
+ case USBPHY_PWD_TOG:
259
+ case USBPHY_TX_TOG:
260
+ case USBPHY_RX_TOG:
261
+ case USBPHY_DEBUG_TOG:
262
+ case USBPHY_DEBUG1_TOG:
263
+ /*
264
+ * All REG_NAME_TOG register access are in fact targeting the
265
+ * REG_NAME register. So we change the value of the REG_NAME
266
+ * register, toggling bits passed in the value.
267
+ */
268
+ s->usbphy[index - 3] ^= value;
269
+ break;
270
+ default:
271
+ /* Other registers are read-only */
272
+ break;
273
+ }
274
+}
275
+
276
+static const struct MemoryRegionOps imx_usbphy_ops = {
277
+ .read = imx_usbphy_read,
278
+ .write = imx_usbphy_write,
279
+ .endianness = DEVICE_NATIVE_ENDIAN,
280
+ .valid = {
281
+ /*
282
+ * Our device would not work correctly if the guest was doing
283
+ * unaligned access. This might not be a limitation on the real
284
+ * device but in practice there is no reason for a guest to access
285
+ * this device unaligned.
286
+ */
287
+ .min_access_size = 4,
288
+ .max_access_size = 4,
289
+ .unaligned = false,
290
+ },
291
+};
1961
+};
292
+
1962
+
293
+static void imx_usbphy_realize(DeviceState *dev, Error **errp)
1963
+static Property xlnx_versal_ospi_properties[] = {
294
+{
1964
+ DEFINE_PROP_BOOL("dac-with-indac", XlnxVersalOspi, dac_with_indac, false),
295
+ IMXUSBPHYState *s = IMX_USBPHY(dev);
1965
+ DEFINE_PROP_BOOL("indac-write-disabled", XlnxVersalOspi,
296
+
1966
+ ind_write_disabled, false),
297
+ memory_region_init_io(&s->iomem, OBJECT(s), &imx_usbphy_ops, s,
1967
+ DEFINE_PROP_END_OF_LIST(),
298
+ "imx-usbphy", 0x1000);
1968
+};
299
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
1969
+
300
+}
1970
+static void xlnx_versal_ospi_class_init(ObjectClass *klass, void *data)
301
+
302
+static void imx_usbphy_class_init(ObjectClass *klass, void *data)
303
+{
1971
+{
304
+ DeviceClass *dc = DEVICE_CLASS(klass);
1972
+ DeviceClass *dc = DEVICE_CLASS(klass);
305
+
1973
+
306
+ dc->reset = imx_usbphy_reset;
1974
+ dc->reset = xlnx_versal_ospi_reset;
307
+ dc->vmsd = &vmstate_imx_usbphy;
1975
+ dc->realize = xlnx_versal_ospi_realize;
308
+ dc->desc = "i.MX USB PHY Module";
1976
+ dc->vmsd = &vmstate_xlnx_versal_ospi;
309
+ dc->realize = imx_usbphy_realize;
1977
+ device_class_set_props(dc, xlnx_versal_ospi_properties);
310
+}
1978
+}
311
+
1979
+
312
+static const TypeInfo imx_usbphy_info = {
1980
+static const TypeInfo xlnx_versal_ospi_info = {
313
+ .name = TYPE_IMX_USBPHY,
1981
+ .name = TYPE_XILINX_VERSAL_OSPI,
314
+ .parent = TYPE_SYS_BUS_DEVICE,
1982
+ .parent = TYPE_SYS_BUS_DEVICE,
315
+ .instance_size = sizeof(IMXUSBPHYState),
1983
+ .instance_size = sizeof(XlnxVersalOspi),
316
+ .class_init = imx_usbphy_class_init,
1984
+ .class_init = xlnx_versal_ospi_class_init,
1985
+ .instance_init = xlnx_versal_ospi_init,
317
+};
1986
+};
318
+
1987
+
319
+static void imx_usbphy_register_types(void)
1988
+static void xlnx_versal_ospi_register_types(void)
320
+{
1989
+{
321
+ type_register_static(&imx_usbphy_info);
1990
+ type_register_static(&xlnx_versal_ospi_info);
322
+}
1991
+}
323
+
1992
+
324
+type_init(imx_usbphy_register_types)
1993
+type_init(xlnx_versal_ospi_register_types)
325
diff --git a/MAINTAINERS b/MAINTAINERS
1994
diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
326
index XXXXXXX..XXXXXXX 100644
1995
index XXXXXXX..XXXXXXX 100644
327
--- a/MAINTAINERS
1996
--- a/hw/ssi/meson.build
328
+++ b/MAINTAINERS
1997
+++ b/hw/ssi/meson.build
329
@@ -XXX,XX +XXX,XX @@ F: hw/arm/sabrelite.c
1998
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_SSI', if_true: files('ssi.c'))
330
F: hw/arm/fsl-imx6.c
1999
softmmu_ss.add(when: 'CONFIG_STM32F2XX_SPI', if_true: files('stm32f2xx_spi.c'))
331
F: hw/misc/imx6_*.c
2000
softmmu_ss.add(when: 'CONFIG_XILINX_SPI', if_true: files('xilinx_spi.c'))
332
F: hw/ssi/imx_spi.c
2001
softmmu_ss.add(when: 'CONFIG_XILINX_SPIPS', if_true: files('xilinx_spips.c'))
333
+F: hw/usb/imx-usb-phy.c
2002
+softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-ospi.c'))
334
+F: include/hw/usb/imx-usb-phy.h
2003
softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_spi.c'))
335
F: include/hw/arm/fsl-imx6.h
2004
softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_spi.c'))
336
F: include/hw/misc/imx6_*.h
337
F: include/hw/ssi/imx_spi.h
338
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
339
index XXXXXXX..XXXXXXX 100644
340
--- a/hw/arm/Kconfig
341
+++ b/hw/arm/Kconfig
342
@@ -XXX,XX +XXX,XX @@ config FSL_IMX6
343
select IMX
344
select IMX_FEC
345
select IMX_I2C
346
+ select IMX_USBPHY
347
select SDHCI
348
349
config ASPEED_SOC
350
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
351
index XXXXXXX..XXXXXXX 100644
352
--- a/hw/usb/Kconfig
353
+++ b/hw/usb/Kconfig
354
@@ -XXX,XX +XXX,XX @@ config USB_STORAGE_MTP
355
bool
356
default y
357
depends on USB
358
+
359
+config IMX_USBPHY
360
+ bool
361
+ default y
362
+ depends on USB
363
--
2005
--
364
2.20.1
2006
2.25.1
365
2007
366
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
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
2
2
3
When requesting JEDEC data using the JEDEC_READ command, the Linux kernel
3
Add support for Micron Xccela flash mt35xu01g.
4
always requests 6 bytes. The current implementation only returns three
5
bytes, and interprets the remaining three bytes as new commands.
6
While this does not matter most of the time, it is at the very least
7
confusing. To avoid the problem, always report up to 6 bytes of JEDEC
8
data. Fill remaining data with 0.
9
4
10
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
5
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 20220121161141.14389-9-francisco.iglesias@xilinx.com
13
Reviewed-by: Cédric Le Goater <clg@kaod.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
9
---
16
hw/block/m25p80.c | 5 ++++-
10
hw/block/m25p80.c | 2 ++
17
1 file changed, 4 insertions(+), 1 deletion(-)
11
1 file changed, 2 insertions(+)
18
12
19
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
13
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/block/m25p80.c
15
--- a/hw/block/m25p80.c
22
+++ b/hw/block/m25p80.c
16
+++ b/hw/block/m25p80.c
23
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
17
@@ -XXX,XX +XXX,XX @@ static const FlashPartInfo known_devices[] = {
24
for (i = 0; i < s->pi->id_len; i++) {
18
{ INFO("n25q512a", 0x20ba20, 0, 64 << 10, 1024, ER_4K) },
25
s->data[i] = s->pi->id[i];
19
{ INFO("n25q512ax3", 0x20ba20, 0x1000, 64 << 10, 1024, ER_4K) },
26
}
20
{ INFO("mt25ql512ab", 0x20ba20, 0x1044, 64 << 10, 1024, ER_4K | ER_32K) },
27
+ for (; i < SPI_NOR_MAX_ID_LEN; i++) {
21
+ { INFO_STACKED("mt35xu01g", 0x2c5b1b, 0x104100, 128 << 10, 1024,
28
+ s->data[i] = 0;
22
+ ER_4K | ER_32K, 2) },
29
+ }
23
{ INFO_STACKED("n25q00", 0x20ba21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
30
24
{ INFO_STACKED("n25q00a", 0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
31
- s->len = s->pi->id_len;
25
{ INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
32
+ s->len = SPI_NOR_MAX_ID_LEN;
33
s->pos = 0;
34
s->state = STATE_READING_DATA;
35
break;
36
--
26
--
37
2.20.1
27
2.25.1
38
28
39
29
diff view generated by jsdifflib
New patch
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
1
2
3
Connect Micron Xccela mt35xu01g flashes to the OSPI flash memory
4
controller.
5
6
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20220121161141.14389-10-francisco.iglesias@xilinx.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/xlnx-versal-virt.c | 23 +++++++++++++++++++++++
13
1 file changed, 23 insertions(+)
14
15
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal-virt.c
18
+++ b/hw/arm/xlnx-versal-virt.c
19
@@ -XXX,XX +XXX,XX @@
20
#define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
21
OBJECT_DECLARE_SIMPLE_TYPE(VersalVirt, XLNX_VERSAL_VIRT_MACHINE)
22
23
+#define XLNX_VERSAL_NUM_OSPI_FLASH 4
24
+
25
struct VersalVirt {
26
MachineState parent_obj;
27
28
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
29
exit(EXIT_FAILURE);
30
}
31
}
32
+
33
+ for (i = 0; i < XLNX_VERSAL_NUM_OSPI_FLASH; i++) {
34
+ BusState *spi_bus;
35
+ DeviceState *flash_dev;
36
+ qemu_irq cs_line;
37
+ DriveInfo *dinfo = drive_get(IF_MTD, 0, i);
38
+
39
+ spi_bus = qdev_get_child_bus(DEVICE(&s->soc.pmc.iou.ospi), "spi0");
40
+
41
+ flash_dev = qdev_new("mt35xu01g");
42
+ if (dinfo) {
43
+ qdev_prop_set_drive_err(flash_dev, "drive",
44
+ blk_by_legacy_dinfo(dinfo), &error_fatal);
45
+ }
46
+ qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);
47
+
48
+ cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
49
+
50
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.pmc.iou.ospi),
51
+ i + 1, cs_line);
52
+ }
53
}
54
55
static void versal_virt_machine_instance_init(Object *obj)
56
--
57
2.25.1
58
59
diff view generated by jsdifflib
1
From: Chen Qun <kuhn.chenqun@huawei.com>
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
2
2
3
The current code causes clang static code analyzer generate warning:
3
List myself as maintainer for the Xilinx Versal OSPI controller.
4
hw/net/imx_fec.c:858:9: warning: Value stored to 'value' is never read
5
value = value & 0x0000000f;
6
^ ~~~~~~~~~~~~~~~~~~
7
hw/net/imx_fec.c:864:9: warning: Value stored to 'value' is never read
8
value = value & 0x000000fd;
9
^ ~~~~~~~~~~~~~~~~~~
10
4
11
According to the definition of the function, the two “value” assignments
5
Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
12
should be written to registers.
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
14
Reported-by: Euler Robot <euler.robot@huawei.com>
15
Signed-off-by: Chen Qun <kuhn.chenqun@huawei.com>
16
Message-id: 20200313123242.13236-1-kuhn.chenqun@huawei.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20220121161141.14389-11-francisco.iglesias@xilinx.com
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
10
---
20
hw/net/imx_fec.c | 6 ++++--
11
MAINTAINERS | 6 ++++++
21
1 file changed, 4 insertions(+), 2 deletions(-)
12
1 file changed, 6 insertions(+)
22
13
23
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
14
diff --git a/MAINTAINERS b/MAINTAINERS
24
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/net/imx_fec.c
16
--- a/MAINTAINERS
26
+++ b/hw/net/imx_fec.c
17
+++ b/MAINTAINERS
27
@@ -XXX,XX +XXX,XX @@ static void imx_enet_write(IMXFECState *s, uint32_t index, uint32_t value)
18
@@ -XXX,XX +XXX,XX @@ F: hw/display/dpcd.c
28
break;
19
F: include/hw/display/dpcd.h
29
case ENET_TGSR:
20
F: docs/system/arm/xlnx-versal-virt.rst
30
/* implement clear timer flag */
21
31
- value = value & 0x0000000f;
22
+Xilinx Versal OSPI
32
+ s->regs[index] &= ~(value & 0x0000000f); /* all bits W1C */
23
+M: Francisco Iglesias <francisco.iglesias@xilinx.com>
33
break;
24
+S: Maintained
34
case ENET_TCSR0:
25
+F: hw/ssi/xlnx-versal-ospi.c
35
case ENET_TCSR1:
26
+F: include/hw/ssi/xlnx-versal-ospi.h
36
case ENET_TCSR2:
27
+
37
case ENET_TCSR3:
28
ARM ACPI Subsystem
38
- value = value & 0x000000fd;
29
M: Shannon Zhao <shannon.zhaosl@gmail.com>
39
+ s->regs[index] &= ~(value & 0x00000080); /* W1C bits */
30
L: qemu-arm@nongnu.org
40
+ s->regs[index] &= ~0x0000007d; /* writable fields */
41
+ s->regs[index] |= (value & 0x0000007d);
42
break;
43
case ENET_TCCR0:
44
case ENET_TCCR1:
45
--
31
--
46
2.20.1
32
2.25.1
47
33
48
34
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: Andrew Baumann <Andrew.Baumann@microsoft.com>
2
2
3
USB1 and USB2 interrupt numbers were swapped. USB_PHY2 interrupt number
3
Signed-off-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
4
is 45. That didn't really matter up to now since the interrupts were not
4
Message-id: MW4PR21MB1940E8BB52F4053C943B1FCD9E219@MW4PR21MB1940.namprd21.prod.outlook.com
5
used, but it needs to be fixed to be able to wire up the USB controllers.
6
7
Fixes: 31cbf933f0e ("i.MX6UL: Add i.MX6UL SOC")
8
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
9
Message-id: 20200313014551.12554-3-linux@roeck-us.net
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
6
---
13
include/hw/arm/fsl-imx6ul.h | 6 +++---
7
MAINTAINERS | 1 -
14
1 file changed, 3 insertions(+), 3 deletions(-)
8
1 file changed, 1 deletion(-)
15
9
16
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
10
diff --git a/MAINTAINERS b/MAINTAINERS
17
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/fsl-imx6ul.h
12
--- a/MAINTAINERS
19
+++ b/include/hw/arm/fsl-imx6ul.h
13
+++ b/MAINTAINERS
20
@@ -XXX,XX +XXX,XX @@ enum FslIMX6ULIRQs {
14
@@ -XXX,XX +XXX,XX @@ F: docs/system/arm/palm.rst
21
FSL_IMX6UL_UART7_IRQ = 39,
15
22
FSL_IMX6UL_UART8_IRQ = 40,
16
Raspberry Pi
23
17
M: Peter Maydell <peter.maydell@linaro.org>
24
- FSL_IMX6UL_USB1_IRQ = 42,
18
-R: Andrew Baumann <Andrew.Baumann@microsoft.com>
25
- FSL_IMX6UL_USB2_IRQ = 43,
19
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
26
+ FSL_IMX6UL_USB1_IRQ = 43,
20
L: qemu-arm@nongnu.org
27
+ FSL_IMX6UL_USB2_IRQ = 42,
21
S: Odd Fixes
28
FSL_IMX6UL_USB_PHY1_IRQ = 44,
29
- FSL_IMX6UL_USB_PHY2_IRQ = 44,
30
+ FSL_IMX6UL_USB_PHY2_IRQ = 45,
31
32
FSL_IMX6UL_CAAM_JQ2_IRQ = 46,
33
FSL_IMX6UL_CAAM_ERR_IRQ = 47,
34
--
22
--
35
2.20.1
23
2.25.1
36
24
37
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
New patch
1
In an SMP system it can be unclear which CPU is taking an exception;
2
add the CPU index (which is the same value used in the TCG 'Trace
3
%d:' logging) to the "Taking exception" log line to clarify it.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220122182444.724087-2-peter.maydell@linaro.org
9
---
10
target/arm/internals.h | 2 +-
11
target/arm/helper.c | 9 ++++++---
12
target/arm/m_helper.c | 2 +-
13
3 files changed, 8 insertions(+), 5 deletions(-)
14
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/internals.h
18
+++ b/target/arm/internals.h
19
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
20
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
21
__attribute__((nonnull));
22
23
-void arm_log_exception(int idx);
24
+void arm_log_exception(CPUState *cs);
25
26
#endif /* !CONFIG_USER_ONLY */
27
28
diff --git a/target/arm/helper.c b/target/arm/helper.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/helper.c
31
+++ b/target/arm/helper.c
32
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
33
return target_el;
34
}
35
36
-void arm_log_exception(int idx)
37
+void arm_log_exception(CPUState *cs)
38
{
39
+ int idx = cs->exception_index;
40
+
41
if (qemu_loglevel_mask(CPU_LOG_INT)) {
42
const char *exc = NULL;
43
static const char * const excnames[] = {
44
@@ -XXX,XX +XXX,XX @@ void arm_log_exception(int idx)
45
if (!exc) {
46
exc = "unknown";
47
}
48
- qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s]\n", idx, exc);
49
+ qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s] on CPU %d\n",
50
+ idx, exc, cs->cpu_index);
51
}
52
}
53
54
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_interrupt(CPUState *cs)
55
56
assert(!arm_feature(env, ARM_FEATURE_M));
57
58
- arm_log_exception(cs->exception_index);
59
+ arm_log_exception(cs);
60
qemu_log_mask(CPU_LOG_INT, "...from EL%d to EL%d\n", arm_current_el(env),
61
new_el);
62
if (qemu_loglevel_mask(CPU_LOG_INT)
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
76
--
77
2.25.1
78
79
diff view generated by jsdifflib
New patch
1
The ITS currently has no tracepoints; add a minimal set
2
that allows basic monitoring of guest register accesses and
3
reading of commands from the command queue.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220122182444.724087-3-peter.maydell@linaro.org
9
---
10
hw/intc/arm_gicv3_its.c | 11 +++++++++++
11
hw/intc/trace-events | 8 ++++++++
12
2 files changed, 19 insertions(+)
13
14
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/arm_gicv3_its.c
17
+++ b/hw/intc/arm_gicv3_its.c
18
@@ -XXX,XX +XXX,XX @@
19
20
#include "qemu/osdep.h"
21
#include "qemu/log.h"
22
+#include "trace.h"
23
#include "hw/qdev-properties.h"
24
#include "hw/intc/arm_gicv3_its_common.h"
25
#include "gicv3_internal.h"
26
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
27
28
cmd = (data & CMD_MASK);
29
30
+ trace_gicv3_its_process_command(rd_offset, cmd);
31
+
32
switch (cmd) {
33
case GITS_CMD_INT:
34
result = process_its_cmd(s, data, cq_offset, INTERRUPT);
35
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset,
36
bool result = true;
37
uint32_t devid = 0;
38
39
+ trace_gicv3_its_translation_write(offset, data, size, attrs.requester_id);
40
+
41
switch (offset) {
42
case GITS_TRANSLATER:
43
if (s->ctlr & R_GITS_CTLR_ENABLED_MASK) {
44
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_read(void *opaque, hwaddr offset, uint64_t *data,
45
qemu_log_mask(LOG_GUEST_ERROR,
46
"%s: invalid guest read at offset " TARGET_FMT_plx
47
"size %u\n", __func__, offset, size);
48
+ trace_gicv3_its_badread(offset, size);
49
/*
50
* The spec requires that reserved registers are RAZ/WI;
51
* so use false returns from leaf functions as a way to
52
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_read(void *opaque, hwaddr offset, uint64_t *data,
53
* the caller, or we'll cause a spurious guest data abort.
54
*/
55
*data = 0;
56
+ } else {
57
+ trace_gicv3_its_read(offset, *data, size);
58
}
59
return MEMTX_OK;
60
}
61
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_write(void *opaque, hwaddr offset, uint64_t data,
62
qemu_log_mask(LOG_GUEST_ERROR,
63
"%s: invalid guest write at offset " TARGET_FMT_plx
64
"size %u\n", __func__, offset, size);
65
+ trace_gicv3_its_badwrite(offset, data, size);
66
/*
67
* The spec requires that reserved registers are RAZ/WI;
68
* so use false returns from leaf functions as a way to
69
* trigger the guest-error logging but don't return it to
70
* the caller, or we'll cause a spurious guest data abort.
71
*/
72
+ } else {
73
+ trace_gicv3_its_write(offset, data, size);
74
}
75
return MEMTX_OK;
76
}
77
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/intc/trace-events
80
+++ b/hw/intc/trace-events
81
@@ -XXX,XX +XXX,XX @@ gicv3_redist_badwrite(uint32_t cpu, uint64_t offset, uint64_t data, unsigned siz
82
gicv3_redist_set_irq(uint32_t cpu, int irq, int level) "GICv3 redistributor 0x%x interrupt %d level changed to %d"
83
gicv3_redist_send_sgi(uint32_t cpu, int irq) "GICv3 redistributor 0x%x pending SGI %d"
84
85
+# arm_gicv3_its.c
86
+gicv3_its_read(uint64_t offset, uint64_t data, unsigned size) "GICv3 ITS read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
87
+gicv3_its_badread(uint64_t offset, unsigned size) "GICv3 ITS read: offset 0x%" PRIx64 " size %u: error"
88
+gicv3_its_write(uint64_t offset, uint64_t data, unsigned size) "GICv3 ITS write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
89
+gicv3_its_badwrite(uint64_t offset, uint64_t data, unsigned size) "GICv3 ITS write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u: error"
90
+gicv3_its_translation_write(uint64_t offset, uint64_t data, unsigned size, uint32_t requester_id) "GICv3 ITS TRANSLATER write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u requester_id 0x%x"
91
+gicv3_its_process_command(uint32_t rd_offset, uint8_t cmd) "GICv3 ITS: processing command at offset 0x%x: 0x%x"
92
+
93
# armv7m_nvic.c
94
nvic_recompute_state(int vectpending, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d vectpending_prio %d exception_prio %d"
95
nvic_recompute_state_secure(int vectpending, bool vectpending_is_s_banked, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d is_s_banked %d vectpending_prio %d exception_prio %d"
96
--
97
2.25.1
98
99
diff view generated by jsdifflib
New patch
1
In our implementation, all ITSes connected to a GIC share a single
2
AddressSpace, which we keep in the GICv3State::dma_as field and
3
initialized based on the GIC's 'sysmem' property. The right place
4
to set it up by calling address_space_init() is therefore in the
5
GIC's realize method, not the ITS's realize.
1
6
7
This fixes a theoretical bug where QEMU hangs on startup if the board
8
model creates two ITSes connected to the same GIC -- we would call
9
address_space_init() twice on the same AddressSpace*, which creates
10
an infinite loop in the QTAILQ that softmmu/memory.c uses to store
11
its list of AddressSpaces and causes any subsequent attempt to
12
iterate through that list to loop forever. There aren't any board
13
models like that in the tree at the moment, though.
14
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20220122182444.724087-4-peter.maydell@linaro.org
18
---
19
hw/intc/arm_gicv3_common.c | 5 +++++
20
hw/intc/arm_gicv3_its.c | 3 ---
21
2 files changed, 5 insertions(+), 3 deletions(-)
22
23
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/intc/arm_gicv3_common.c
26
+++ b/hw/intc/arm_gicv3_common.c
27
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
28
return;
29
}
30
31
+ if (s->lpi_enable) {
32
+ address_space_init(&s->dma_as, s->dma,
33
+ "gicv3-its-sysmem");
34
+ }
35
+
36
s->cpu = g_new0(GICv3CPUState, s->num_cpu);
37
38
for (i = 0; i < s->num_cpu; i++) {
39
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/intc/arm_gicv3_its.c
42
+++ b/hw/intc/arm_gicv3_its.c
43
@@ -XXX,XX +XXX,XX @@ static void gicv3_arm_its_realize(DeviceState *dev, Error **errp)
44
45
gicv3_its_init_mmio(s, &gicv3_its_control_ops, &gicv3_its_translation_ops);
46
47
- address_space_init(&s->gicv3->dma_as, s->gicv3->dma,
48
- "gicv3-its-sysmem");
49
-
50
/* set the ITS default features supported */
51
s->typer = FIELD_DP64(s->typer, GITS_TYPER, PHYSICAL, 1);
52
s->typer = FIELD_DP64(s->typer, GITS_TYPER, ITT_ENTRY_SIZE,
53
--
54
2.25.1
55
56
diff view generated by jsdifflib
New patch
1
The current ITS code clears GITS_CREADR when GITS_CTLR.ENABLED is set.
2
This is not correct -- guest code can validly clear ENABLED and then
3
set it again and expect the ITS to continue processing where it left
4
off. Remove the erroneous assignment.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220122182444.724087-5-peter.maydell@linaro.org
9
---
10
hw/intc/arm_gicv3_its.c | 1 -
11
1 file changed, 1 deletion(-)
12
13
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/intc/arm_gicv3_its.c
16
+++ b/hw/intc/arm_gicv3_its.c
17
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
18
s->ctlr |= R_GITS_CTLR_ENABLED_MASK;
19
extract_table_params(s);
20
extract_cmdq_params(s);
21
- s->creadr = 0;
22
process_cmdq(s);
23
} else {
24
s->ctlr &= ~R_GITS_CTLR_ENABLED_MASK;
25
--
26
2.25.1
27
28
diff view generated by jsdifflib
New patch
1
The ITS specification says that when the guest writes to GITS_CBASER
2
this causes GITS_CREADR to be cleared. However it does not have an
3
equivalent clause for GITS_CWRITER. (This is because GITS_CREADR is
4
read-only, but GITS_CWRITER is writable and the guest can initialize
5
it.) Remove the code that clears GITS_CWRITER on GITS_CBASER writes.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220122182444.724087-6-peter.maydell@linaro.org
10
---
11
hw/intc/arm_gicv3_its.c | 3 ---
12
1 file changed, 3 deletions(-)
13
14
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/arm_gicv3_its.c
17
+++ b/hw/intc/arm_gicv3_its.c
18
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
19
if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
20
s->cbaser = deposit64(s->cbaser, 0, 32, value);
21
s->creadr = 0;
22
- s->cwriter = s->creadr;
23
}
24
break;
25
case GITS_CBASER + 4:
26
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
27
if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
28
s->cbaser = deposit64(s->cbaser, 32, 32, value);
29
s->creadr = 0;
30
- s->cwriter = s->creadr;
31
}
32
break;
33
case GITS_CWRITER:
34
@@ -XXX,XX +XXX,XX @@ static bool its_writell(GICv3ITSState *s, hwaddr offset,
35
if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
36
s->cbaser = value;
37
s->creadr = 0;
38
- s->cwriter = s->creadr;
39
}
40
break;
41
case GITS_CWRITER:
42
--
43
2.25.1
44
45
diff view generated by jsdifflib
New patch
1
The GICD_CTLR distributor register has enable bits which control
2
whether the different interrupt groups (Group 0, Non-secure Group 1
3
and Secure Group 1) are forwarded to the CPU. We get this right for
4
traditional interrupts, but forgot to account for it when adding
5
LPIs. LPIs are always Group 1 NS and if the EnableGrp1NS bit is not
6
set we must not forward them to the CPU.
1
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220122182444.724087-7-peter.maydell@linaro.org
11
---
12
hw/intc/arm_gicv3.c | 1 +
13
1 file changed, 1 insertion(+)
14
15
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/arm_gicv3.c
18
+++ b/hw/intc/arm_gicv3.c
19
@@ -XXX,XX +XXX,XX @@ static void gicv3_redist_update_noirqset(GICv3CPUState *cs)
20
}
21
22
if ((cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) && cs->gic->lpi_enable &&
23
+ (cs->gic->gicd_ctlr & GICD_CTLR_EN_GRP1NS) &&
24
(cs->hpplpi.prio != 0xff)) {
25
if (irqbetter(cs, cs->hpplpi.irq, cs->hpplpi.prio)) {
26
cs->hppi.irq = cs->hpplpi.irq;
27
--
28
2.25.1
29
30
diff view generated by jsdifflib
New patch
1
The list of #defines for the ITS command packet numbers is neither
2
in alphabetical nor numeric order. Sort it into numeric order.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220122182444.724087-8-peter.maydell@linaro.org
8
---
9
hw/intc/gicv3_internal.h | 10 +++++-----
10
1 file changed, 5 insertions(+), 5 deletions(-)
11
12
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/intc/gicv3_internal.h
15
+++ b/hw/intc/gicv3_internal.h
16
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, CIL, 36, 1)
17
#define CMD_MASK 0xff
18
19
/* ITS Commands */
20
-#define GITS_CMD_CLEAR 0x04
21
-#define GITS_CMD_DISCARD 0x0F
22
#define GITS_CMD_INT 0x03
23
-#define GITS_CMD_MAPC 0x09
24
+#define GITS_CMD_CLEAR 0x04
25
+#define GITS_CMD_SYNC 0x05
26
#define GITS_CMD_MAPD 0x08
27
-#define GITS_CMD_MAPI 0x0B
28
+#define GITS_CMD_MAPC 0x09
29
#define GITS_CMD_MAPTI 0x0A
30
+#define GITS_CMD_MAPI 0x0B
31
#define GITS_CMD_INV 0x0C
32
#define GITS_CMD_INVALL 0x0D
33
-#define GITS_CMD_SYNC 0x05
34
+#define GITS_CMD_DISCARD 0x0F
35
36
/* MAPC command fields */
37
#define ICID_LENGTH 16
38
--
39
2.25.1
40
41
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
The ITS-related parts of the redistributor code make some checks for
2
whether registers like GICR_PROPBASER and GICR_PENDBASER are zero.
3
There is no requirement in the specification for treating zeroes in
4
these address registers specially -- they contain guest physical
5
addresses and it is entirely valid (if unusual) for the guest to
6
choose to put the tables they address at guest physical address zero.
7
We use these values only to calculate guest addresses, and attempts
8
by the guest to use a bad address will be handled by the
9
address_space_* functions which we use to do the loads and stores.
2
10
3
With this patch, the USB controllers on 'sabrelite' are detected
11
Remove the unnecessary checks.
4
and can be used to boot the system.
5
12
6
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
7
Message-id: 20200313014551.12554-6-linux@roeck-us.net
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
10
---
16
---
11
include/hw/arm/fsl-imx6.h | 6 ++++++
17
hw/intc/arm_gicv3_redist.c | 8 +++-----
12
hw/arm/fsl-imx6.c | 36 ++++++++++++++++++++++++++++++++++++
18
1 file changed, 3 insertions(+), 5 deletions(-)
13
2 files changed, 42 insertions(+)
14
19
15
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
20
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/fsl-imx6.h
22
--- a/hw/intc/arm_gicv3_redist.c
18
+++ b/include/hw/arm/fsl-imx6.h
23
+++ b/hw/intc/arm_gicv3_redist.c
19
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ void gicv3_redist_update_lpi_only(GICv3CPUState *cs)
20
#include "hw/sd/sdhci.h"
25
idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS),
21
#include "hw/ssi/imx_spi.h"
26
GICD_TYPER_IDBITS);
22
#include "hw/net/imx_fec.h"
27
23
+#include "hw/usb/chipidea.h"
28
- if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser ||
24
+#include "hw/usb/imx-usb-phy.h"
29
- !cs->gicr_pendbaser) {
25
#include "exec/memory.h"
30
+ if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS)) {
26
#include "cpu.h"
31
return;
27
28
@@ -XXX,XX +XXX,XX @@
29
#define FSL_IMX6_NUM_ESDHCS 4
30
#define FSL_IMX6_NUM_ECSPIS 5
31
#define FSL_IMX6_NUM_WDTS 2
32
+#define FSL_IMX6_NUM_USB_PHYS 2
33
+#define FSL_IMX6_NUM_USBS 4
34
35
typedef struct FslIMX6State {
36
/*< private >*/
37
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX6State {
38
SDHCIState esdhc[FSL_IMX6_NUM_ESDHCS];
39
IMXSPIState spi[FSL_IMX6_NUM_ECSPIS];
40
IMX2WdtState wdt[FSL_IMX6_NUM_WDTS];
41
+ IMXUSBPHYState usbphy[FSL_IMX6_NUM_USB_PHYS];
42
+ ChipideaState usb[FSL_IMX6_NUM_USBS];
43
IMXFECState eth;
44
MemoryRegion rom;
45
MemoryRegion caam;
46
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/fsl-imx6.c
49
+++ b/hw/arm/fsl-imx6.c
50
@@ -XXX,XX +XXX,XX @@
51
#include "qemu/osdep.h"
52
#include "qapi/error.h"
53
#include "hw/arm/fsl-imx6.h"
54
+#include "hw/usb/imx-usb-phy.h"
55
#include "hw/boards.h"
56
#include "hw/qdev-properties.h"
57
#include "sysemu/sysemu.h"
58
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_init(Object *obj)
59
TYPE_IMX_USDHC);
60
}
32
}
61
33
62
+ for (i = 0; i < FSL_IMX6_NUM_USB_PHYS; i++) {
34
@@ -XXX,XX +XXX,XX @@ void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level)
63
+ snprintf(name, NAME_SIZE, "usbphy%d", i);
35
idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS),
64
+ sysbus_init_child_obj(obj, name, &s->usbphy[i], sizeof(s->usbphy[i]),
36
GICD_TYPER_IDBITS);
65
+ TYPE_IMX_USBPHY);
37
66
+ }
38
- if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser ||
67
+ for (i = 0; i < FSL_IMX6_NUM_USBS; i++) {
39
- !cs->gicr_pendbaser || (irq > (1ULL << (idbits + 1)) - 1) ||
68
+ snprintf(name, NAME_SIZE, "usb%d", i);
40
- irq < GICV3_LPI_INTID_START) {
69
+ sysbus_init_child_obj(obj, name, &s->usb[i], sizeof(s->usb[i]),
41
+ if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) ||
70
+ TYPE_CHIPIDEA);
42
+ (irq > (1ULL << (idbits + 1)) - 1) || irq < GICV3_LPI_INTID_START) {
71
+ }
43
return;
72
+
73
for (i = 0; i < FSL_IMX6_NUM_ECSPIS; i++) {
74
snprintf(name, NAME_SIZE, "spi%d", i + 1);
75
sysbus_init_child_obj(obj, name, &s->spi[i], sizeof(s->spi[i]),
76
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
77
esdhc_table[i].irq));
78
}
44
}
79
45
80
+ /* USB */
81
+ for (i = 0; i < FSL_IMX6_NUM_USB_PHYS; i++) {
82
+ object_property_set_bool(OBJECT(&s->usbphy[i]), true, "realized",
83
+ &error_abort);
84
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usbphy[i]), 0,
85
+ FSL_IMX6_USBPHY1_ADDR + i * 0x1000);
86
+ }
87
+ for (i = 0; i < FSL_IMX6_NUM_USBS; i++) {
88
+ static const int FSL_IMX6_USBn_IRQ[] = {
89
+ FSL_IMX6_USB_OTG_IRQ,
90
+ FSL_IMX6_USB_HOST1_IRQ,
91
+ FSL_IMX6_USB_HOST2_IRQ,
92
+ FSL_IMX6_USB_HOST3_IRQ,
93
+ };
94
+
95
+ object_property_set_bool(OBJECT(&s->usb[i]), true, "realized",
96
+ &error_abort);
97
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0,
98
+ FSL_IMX6_USBOH3_USB_ADDR + i * 0x200);
99
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0,
100
+ qdev_get_gpio_in(DEVICE(&s->a9mpcore),
101
+ FSL_IMX6_USBn_IRQ[i]));
102
+ }
103
+
104
/* Initialize all ECSPI */
105
for (i = 0; i < FSL_IMX6_NUM_ECSPIS; i++) {
106
static const struct {
107
--
46
--
108
2.20.1
47
2.25.1
109
48
110
49
diff view generated by jsdifflib
New patch
1
The GICR_CTLR.CES bit is a read-only bit which is set to 1 to indicate
2
that the GICR_CTLR.EnableLPIs bit can be written to 0 to disable
3
LPIs (as opposed to allowing LPIs to be enabled but not subsequently
4
disabled). Our implementation permits this, so advertise it
5
by setting CES to 1.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220122182444.724087-10-peter.maydell@linaro.org
10
---
11
hw/intc/gicv3_internal.h | 1 +
12
hw/intc/arm_gicv3_common.c | 4 ++++
13
2 files changed, 5 insertions(+)
14
15
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/gicv3_internal.h
18
+++ b/hw/intc/gicv3_internal.h
19
@@ -XXX,XX +XXX,XX @@
20
#define GICR_NSACR (GICR_SGI_OFFSET + 0x0E00)
21
22
#define GICR_CTLR_ENABLE_LPIS (1U << 0)
23
+#define GICR_CTLR_CES (1U << 1)
24
#define GICR_CTLR_RWP (1U << 3)
25
#define GICR_CTLR_DPG0 (1U << 24)
26
#define GICR_CTLR_DPG1NS (1U << 25)
27
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/intc/arm_gicv3_common.c
30
+++ b/hw/intc/arm_gicv3_common.c
31
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_reset(DeviceState *dev)
32
33
cs->level = 0;
34
cs->gicr_ctlr = 0;
35
+ if (s->lpi_enable) {
36
+ /* Our implementation supports clearing GICR_CTLR.EnableLPIs */
37
+ cs->gicr_ctlr |= GICR_CTLR_CES;
38
+ }
39
cs->gicr_statusr[GICV3_S] = 0;
40
cs->gicr_statusr[GICV3_NS] = 0;
41
cs->gicr_waker = GICR_WAKER_ProcessorSleep | GICR_WAKER_ChildrenAsleep;
42
--
43
2.25.1
44
45
diff view generated by jsdifflib
New patch
1
The MemoryRegionOps gicv3_its_translation_ops currently provides only
2
a .write_with_attrs function, because the only register in this
3
region is the write-only GITS_TRANSLATER. However, if you don't
4
provide a read function and the guest tries reading from this memory
5
region, QEMU will crash because
6
memory_region_read_with_attrs_accessor() calls a NULL pointer.
1
7
8
Add a read function which always returns 0, to cover both bogus
9
attempts to read GITS_TRANSLATER and also reads from the rest of the
10
region, which is documented to be reserved, RES0.
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220122182444.724087-11-peter.maydell@linaro.org
16
---
17
hw/intc/arm_gicv3_its.c | 13 +++++++++++++
18
1 file changed, 13 insertions(+)
19
20
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/intc/arm_gicv3_its.c
23
+++ b/hw/intc/arm_gicv3_its.c
24
@@ -XXX,XX +XXX,XX @@ static void extract_cmdq_params(GICv3ITSState *s)
25
}
26
}
27
28
+static MemTxResult gicv3_its_translation_read(void *opaque, hwaddr offset,
29
+ uint64_t *data, unsigned size,
30
+ MemTxAttrs attrs)
31
+{
32
+ /*
33
+ * GITS_TRANSLATER is write-only, and all other addresses
34
+ * in the interrupt translation space frame are RES0.
35
+ */
36
+ *data = 0;
37
+ return MEMTX_OK;
38
+}
39
+
40
static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset,
41
uint64_t data, unsigned size,
42
MemTxAttrs attrs)
43
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps gicv3_its_control_ops = {
44
};
45
46
static const MemoryRegionOps gicv3_its_translation_ops = {
47
+ .read_with_attrs = gicv3_its_translation_read,
48
.write_with_attrs = gicv3_its_translation_write,
49
.valid.min_access_size = 2,
50
.valid.max_access_size = 4,
51
--
52
2.25.1
53
54
diff view generated by jsdifflib
New patch
1
The ITS has a bank of 8 GITS_BASER<n> registers, which allow the
2
guest to specify the base address of various data tables. Each
3
register has a read-only type field indicating which table it is for
4
and a read-write field where the guest can write in the base address
5
(among other things). We currently allow the guest to write the
6
writeable fields for all eight registers, even if the type field is 0
7
indicating "Unimplemented". This means the guest can provoke QEMU
8
into asserting by writing an address into one of these unimplemented
9
base registers, which bypasses the "if (!value) continue" check in
10
extract_table_params() and lets us hit the assertion that the type
11
field is one of the permitted table types.
1
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.
16
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20220122182444.724087-12-peter.maydell@linaro.org
20
---
21
hw/intc/arm_gicv3_its.c | 8 ++++++++
22
1 file changed, 8 insertions(+)
23
24
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/intc/arm_gicv3_its.c
27
+++ b/hw/intc/arm_gicv3_its.c
28
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
29
if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
30
index = (offset - GITS_BASER) / 8;
31
32
+ if (s->baser[index] == 0) {
33
+ /* Unimplemented GITS_BASERn: RAZ/WI */
34
+ break;
35
+ }
36
if (offset & 7) {
37
value <<= 32;
38
value &= ~GITS_BASER_RO_MASK;
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
}
50
--
51
2.25.1
52
53
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
Currently when we fill in a TableDesc based on the value the guest
2
has written to the GITS_BASER<n> register, we calculate both:
3
* num_entries : the number of entries in the table, constrained
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)
2
8
3
While at it, add some trace messages to help debug problems
9
When validating ITS commands, however, we check only num_ids,
4
seen when running the latest Linux kernel.
10
thus allowing a broken guest to specify table entries that
11
index off the end of it. This will only corrupt guest memory,
12
but the ITS is supposed to reject such commands as invalid.
5
13
6
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
14
Instead of calculating both num_entries and num_ids, set
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
num_entries to the minimum of the two limits, and check that.
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
9
Reviewed-by: Cédric Le Goater <clg@kaod.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20220122182444.724087-13-peter.maydell@linaro.org
11
---
20
---
12
hw/block/m25p80.c | 48 ++++++++++++++++++++-----------------------
21
include/hw/intc/arm_gicv3_its_common.h | 1 -
13
hw/block/trace-events | 16 +++++++++++++++
22
hw/intc/arm_gicv3_its.c | 18 +++++++++---------
14
2 files changed, 38 insertions(+), 26 deletions(-)
23
2 files changed, 9 insertions(+), 10 deletions(-)
15
24
16
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
25
diff --git a/include/hw/intc/arm_gicv3_its_common.h b/include/hw/intc/arm_gicv3_its_common.h
17
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/block/m25p80.c
27
--- a/include/hw/intc/arm_gicv3_its_common.h
19
+++ b/hw/block/m25p80.c
28
+++ b/include/hw/intc/arm_gicv3_its_common.h
20
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@ typedef struct {
21
#include "qemu/module.h"
30
uint16_t entry_sz;
22
#include "qemu/error-report.h"
31
uint32_t page_sz;
23
#include "qapi/error.h"
32
uint32_t num_entries;
24
-
33
- uint32_t num_ids;
25
-#ifndef M25P80_ERR_DEBUG
34
uint64_t base_addr;
26
-#define M25P80_ERR_DEBUG 0
35
} TableDesc;
27
-#endif
36
28
-
37
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
29
-#define DB_PRINT_L(level, ...) do { \
38
index XXXXXXX..XXXXXXX 100644
30
- if (M25P80_ERR_DEBUG > (level)) { \
39
--- a/hw/intc/arm_gicv3_its.c
31
- fprintf(stderr, ": %s: ", __func__); \
40
+++ b/hw/intc/arm_gicv3_its.c
32
- fprintf(stderr, ## __VA_ARGS__); \
41
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_its_cmd(GICv3ITSState *s, uint64_t value,
33
- } \
42
34
-} while (0)
43
eventid = (value & EVENTID_MASK);
35
+#include "trace.h"
44
36
45
- if (devid >= s->dt.num_ids) {
37
/* Fields for FlashPartInfo->flags */
46
+ if (devid >= s->dt.num_entries) {
38
47
qemu_log_mask(LOG_GUEST_ERROR,
39
@@ -XXX,XX +XXX,XX @@ static void flash_erase(Flash *s, int offset, FlashCMD cmd)
48
"%s: invalid command attributes: devid %d>=%d",
40
abort();
49
- __func__, devid, s->dt.num_ids);
50
+ __func__, devid, s->dt.num_entries);
51
return CMD_CONTINUE;
41
}
52
}
42
53
43
- DB_PRINT_L(0, "offset = %#x, len = %d\n", offset, len);
54
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_its_cmd(GICv3ITSState *s, uint64_t value,
44
+ trace_m25p80_flash_erase(s, offset, len);
55
return CMD_CONTINUE;
45
+
46
if ((s->pi->flags & capa_to_assert) != capa_to_assert) {
47
qemu_log_mask(LOG_GUEST_ERROR, "M25P80: %d erase size not supported by"
48
" device\n", len);
49
@@ -XXX,XX +XXX,XX @@ void flash_write8(Flash *s, uint32_t addr, uint8_t data)
50
}
56
}
51
57
52
if ((prev ^ data) & data) {
58
- if (icid >= s->ct.num_ids) {
53
- DB_PRINT_L(1, "programming zero to one! addr=%" PRIx32 " %" PRIx8
59
+ if (icid >= s->ct.num_entries) {
54
- " -> %" PRIx8 "\n", addr, prev, data);
60
qemu_log_mask(LOG_GUEST_ERROR,
55
+ trace_m25p80_programming_zero_to_one(s, addr, prev, data);
61
"%s: invalid ICID 0x%x in ITE (table corrupted?)\n",
62
__func__, icid);
63
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_mapti(GICv3ITSState *s, uint64_t value,
64
65
icid = value & ICID_MASK;
66
67
- if (devid >= s->dt.num_ids) {
68
+ if (devid >= s->dt.num_entries) {
69
qemu_log_mask(LOG_GUEST_ERROR,
70
"%s: invalid command attributes: devid %d>=%d",
71
- __func__, devid, s->dt.num_ids);
72
+ __func__, devid, s->dt.num_entries);
73
return CMD_CONTINUE;
56
}
74
}
57
75
58
if (s->pi->flags & EEPROM) {
76
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_mapti(GICv3ITSState *s, uint64_t value,
59
@@ -XXX,XX +XXX,XX @@ static void complete_collecting_data(Flash *s)
77
num_eventids = 1ULL << (FIELD_EX64(dte, DTE, SIZE) + 1);
60
78
num_intids = 1ULL << (GICD_TYPER_IDBITS + 1);
61
s->state = STATE_IDLE;
79
62
80
- if ((icid >= s->ct.num_ids)
63
+ trace_m25p80_complete_collecting(s, s->cmd_in_progress, n, s->ear,
81
+ if ((icid >= s->ct.num_entries)
64
+ s->cur_addr);
82
|| !dte_valid || (eventid >= num_eventids) ||
65
+
83
(((pIntid < GICV3_LPI_INTID_START) || (pIntid >= num_intids)) &&
66
switch (s->cmd_in_progress) {
84
(pIntid != INTID_SPURIOUS))) {
67
case DPP:
85
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_mapc(GICv3ITSState *s, uint32_t offset)
68
case QPP:
86
69
@@ -XXX,XX +XXX,XX @@ static void reset_memory(Flash *s)
87
valid = (value & CMD_FIELD_VALID_MASK);
70
break;
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);
71
}
109
}
72
73
- DB_PRINT_L(0, "Reset done.\n");
74
+ trace_m25p80_reset_done(s);
75
}
110
}
76
111
77
static void decode_fast_read_cmd(Flash *s)
78
@@ -XXX,XX +XXX,XX @@ static void decode_qio_read_cmd(Flash *s)
79
80
static void decode_new_cmd(Flash *s, uint32_t value)
81
{
82
- s->cmd_in_progress = value;
83
int i;
84
- DB_PRINT_L(0, "decoded new command:%x\n", value);
85
+
86
+ s->cmd_in_progress = value;
87
+ trace_m25p80_command_decoded(s, value);
88
89
if (value != RESET_MEMORY) {
90
s->reset_enable = false;
91
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
92
break;
93
94
case JEDEC_READ:
95
- DB_PRINT_L(0, "populated jedec code\n");
96
+ trace_m25p80_populated_jedec(s);
97
for (i = 0; i < s->pi->id_len; i++) {
98
s->data[i] = s->pi->id[i];
99
}
100
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
101
case BULK_ERASE_60:
102
case BULK_ERASE:
103
if (s->write_enable) {
104
- DB_PRINT_L(0, "chip erase\n");
105
+ trace_m25p80_chip_erase(s);
106
flash_erase(s, 0, BULK_ERASE);
107
} else {
108
qemu_log_mask(LOG_GUEST_ERROR, "M25P80: chip erase with write "
109
@@ -XXX,XX +XXX,XX @@ static int m25p80_cs(SSISlave *ss, bool select)
110
s->data_read_loop = false;
111
}
112
113
- DB_PRINT_L(0, "%sselect\n", select ? "de" : "");
114
+ trace_m25p80_select(s, select ? "de" : "");
115
116
return 0;
117
}
118
@@ -XXX,XX +XXX,XX @@ static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
119
Flash *s = M25P80(ss);
120
uint32_t r = 0;
121
122
+ trace_m25p80_transfer(s, s->state, s->len, s->needed_bytes, s->pos,
123
+ s->cur_addr, (uint8_t)tx);
124
+
125
switch (s->state) {
126
127
case STATE_PAGE_PROGRAM:
128
- DB_PRINT_L(1, "page program cur_addr=%#" PRIx32 " data=%" PRIx8 "\n",
129
- s->cur_addr, (uint8_t)tx);
130
+ trace_m25p80_page_program(s, s->cur_addr, (uint8_t)tx);
131
flash_write8(s, s->cur_addr, (uint8_t)tx);
132
s->cur_addr = (s->cur_addr + 1) & (s->size - 1);
133
break;
134
135
case STATE_READ:
136
r = s->storage[s->cur_addr];
137
- DB_PRINT_L(1, "READ 0x%" PRIx32 "=%" PRIx8 "\n", s->cur_addr,
138
- (uint8_t)r);
139
+ trace_m25p80_read_byte(s, s->cur_addr, (uint8_t)r);
140
s->cur_addr = (s->cur_addr + 1) & (s->size - 1);
141
break;
142
143
@@ -XXX,XX +XXX,XX @@ static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
144
}
145
146
r = s->data[s->pos];
147
+ trace_m25p80_read_data(s, s->pos, (uint8_t)r);
148
s->pos++;
149
if (s->pos == s->len) {
150
s->pos = 0;
151
@@ -XXX,XX +XXX,XX @@ static void m25p80_realize(SSISlave *ss, Error **errp)
152
return;
153
}
154
155
- DB_PRINT_L(0, "Binding to IF_MTD drive\n");
156
+ trace_m25p80_binding(s);
157
s->storage = blk_blockalign(s->blk, s->size);
158
159
if (blk_pread(s->blk, 0, s->storage, s->size) != s->size) {
160
@@ -XXX,XX +XXX,XX @@ static void m25p80_realize(SSISlave *ss, Error **errp)
161
return;
162
}
163
} else {
164
- DB_PRINT_L(0, "No BDRV - binding to RAM\n");
165
+ trace_m25p80_binding_no_bdrv(s);
166
s->storage = blk_blockalign(NULL, s->size);
167
memset(s->storage, 0xFF, s->size);
168
}
169
diff --git a/hw/block/trace-events b/hw/block/trace-events
170
index XXXXXXX..XXXXXXX 100644
171
--- a/hw/block/trace-events
172
+++ b/hw/block/trace-events
173
@@ -XXX,XX +XXX,XX @@ xen_block_blockdev_add(char *str) "%s"
174
xen_block_blockdev_del(const char *node_name) "%s"
175
xen_block_device_create(unsigned int number) "%u"
176
xen_block_device_destroy(unsigned int number) "%u"
177
+
178
+# m25p80.c
179
+m25p80_flash_erase(void *s, int offset, uint32_t len) "[%p] offset = 0x%"PRIx32", len = %u"
180
+m25p80_programming_zero_to_one(void *s, uint32_t addr, uint8_t prev, uint8_t data) "[%p] programming zero to one! addr=0x%"PRIx32" 0x%"PRIx8" -> 0x%"PRIx8
181
+m25p80_reset_done(void *s) "[%p] Reset done."
182
+m25p80_command_decoded(void *s, uint32_t cmd) "[%p] new command:0x%"PRIx32
183
+m25p80_complete_collecting(void *s, uint32_t cmd, int n, uint8_t ear, uint32_t cur_addr) "[%p] decode cmd: 0x%"PRIx32" len %d ear 0x%"PRIx8" addr 0x%"PRIx32
184
+m25p80_populated_jedec(void *s) "[%p] populated jedec code"
185
+m25p80_chip_erase(void *s) "[%p] chip erase"
186
+m25p80_select(void *s, const char *what) "[%p] %sselect"
187
+m25p80_page_program(void *s, uint32_t addr, uint8_t tx) "[%p] page program cur_addr=0x%"PRIx32" data=0x%"PRIx8
188
+m25p80_transfer(void *s, uint8_t state, uint32_t len, uint8_t needed, uint32_t pos, uint32_t cur_addr, uint8_t t) "[%p] Transfer state 0x%"PRIx8" len 0x%"PRIx32" needed 0x%"PRIx8" pos 0x%"PRIx32" addr 0x%"PRIx32" tx 0x%"PRIx8
189
+m25p80_read_byte(void *s, uint32_t addr, uint8_t v) "[%p] Read byte 0x%"PRIx32"=0x%"PRIx8
190
+m25p80_read_data(void *s, uint32_t pos, uint8_t v) "[%p] Read data 0x%"PRIx32"=0x%"PRIx8
191
+m25p80_binding(void *s) "[%p] Binding to IF_MTD drive"
192
+m25p80_binding_no_bdrv(void *s) "[%p] No BDRV - binding to RAM"
193
--
112
--
194
2.20.1
113
2.25.1
195
114
196
115
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
Implement the ITS MOVALL command, which takes all the pending
2
interrupts on a source redistributor and makes the not-pending on
3
that source redistributor and pending on a destination redistributor.
2
4
3
IMX6UL USB controllers are quite similar to IMX7 USB controllers.
5
This is a GICv3 ITS command which we forgot to implement. (It is
4
Wire them up the same way.
6
not used by Linux guests.)
5
7
6
The only real difference is that wiring up phy devices is necessary
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
to avoid phy reset timeouts in the Linux kernel.
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220122182444.724087-14-peter.maydell@linaro.org
11
---
12
hw/intc/gicv3_internal.h | 16 +++++++++++
13
hw/intc/arm_gicv3_its.c | 55 ++++++++++++++++++++++++++++++++++++++
14
hw/intc/arm_gicv3_redist.c | 54 +++++++++++++++++++++++++++++++++++++
15
3 files changed, 125 insertions(+)
8
16
9
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
17
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
10
Message-id: 20200313014551.12554-5-linux@roeck-us.net
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
include/hw/arm/fsl-imx6ul.h | 10 ++++++++++
15
hw/arm/fsl-imx6ul.c | 35 +++++++++++++++++++++++++++++++++++
16
2 files changed, 45 insertions(+)
17
18
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/fsl-imx6ul.h
19
--- a/hw/intc/gicv3_internal.h
21
+++ b/include/hw/arm/fsl-imx6ul.h
20
+++ b/hw/intc/gicv3_internal.h
22
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, CIL, 36, 1)
23
#include "hw/sd/sdhci.h"
22
#define GITS_CMD_MAPI 0x0B
24
#include "hw/ssi/imx_spi.h"
23
#define GITS_CMD_INV 0x0C
25
#include "hw/net/imx_fec.h"
24
#define GITS_CMD_INVALL 0x0D
26
+#include "hw/usb/chipidea.h"
25
+#define GITS_CMD_MOVALL 0x0E
27
+#include "hw/usb/imx-usb-phy.h"
26
#define GITS_CMD_DISCARD 0x0F
28
#include "exec/memory.h"
27
29
#include "cpu.h"
28
/* MAPC command fields */
30
29
@@ -XXX,XX +XXX,XX @@ FIELD(MAPC, RDBASE, 16, 32)
31
@@ -XXX,XX +XXX,XX @@ enum FslIMX6ULConfiguration {
30
#define L2_TABLE_VALID_MASK CMD_FIELD_VALID_MASK
32
FSL_IMX6UL_NUM_I2CS = 4,
31
#define TABLE_ENTRY_VALID_MASK (1ULL << 0)
33
FSL_IMX6UL_NUM_ECSPIS = 4,
32
34
FSL_IMX6UL_NUM_ADCS = 2,
33
+/* MOVALL command fields */
35
+ FSL_IMX6UL_NUM_USB_PHYS = 2,
34
+FIELD(MOVALL_2, RDBASE1, 16, 36)
36
+ FSL_IMX6UL_NUM_USBS = 2,
35
+FIELD(MOVALL_3, RDBASE2, 16, 36)
37
};
36
+
38
37
/*
39
typedef struct FslIMX6ULState {
38
* 12 bytes Interrupt translation Table Entry size
40
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX6ULState {
39
* as per Table 5.3 in GICv3 spec
41
IMXFECState eth[FSL_IMX6UL_NUM_ETHS];
40
@@ -XXX,XX +XXX,XX @@ void gicv3_redist_update_lpi(GICv3CPUState *cs);
42
SDHCIState usdhc[FSL_IMX6UL_NUM_USDHCS];
41
* an incoming migration has loaded new state.
43
IMX2WdtState wdt[FSL_IMX6UL_NUM_WDTS];
42
*/
44
+ IMXUSBPHYState usbphy[FSL_IMX6UL_NUM_USB_PHYS];
43
void gicv3_redist_update_lpi_only(GICv3CPUState *cs);
45
+ ChipideaState usb[FSL_IMX6UL_NUM_USBS];
44
+/**
46
MemoryRegion rom;
45
+ * gicv3_redist_movall_lpis:
47
MemoryRegion caam;
46
+ * @src: source redistributor
48
MemoryRegion ocram;
47
+ * @dest: destination redistributor
49
@@ -XXX,XX +XXX,XX @@ enum FslIMX6ULMemoryMap {
48
+ *
50
FSL_IMX6UL_EPIT2_ADDR = 0x020D4000,
49
+ * Scan the LPI pending table for @src, and for each pending LPI there
51
FSL_IMX6UL_EPIT1_ADDR = 0x020D0000,
50
+ * mark it as not-pending for @src and pending for @dest, as required
52
FSL_IMX6UL_SNVS_HP_ADDR = 0x020CC000,
51
+ * by the ITS MOVALL command.
53
+ FSL_IMX6UL_USBPHY2_ADDR = 0x020CA000,
52
+ */
54
+ FSL_IMX6UL_USBPHY2_SIZE = (4 * 1024),
53
+void gicv3_redist_movall_lpis(GICv3CPUState *src, GICv3CPUState *dest);
55
+ FSL_IMX6UL_USBPHY1_ADDR = 0x020C9000,
54
+
56
+ FSL_IMX6UL_USBPHY1_SIZE = (4 * 1024),
55
void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns);
57
FSL_IMX6UL_ANALOG_ADDR = 0x020C8000,
56
void gicv3_init_cpuif(GICv3State *s);
58
FSL_IMX6UL_CCM_ADDR = 0x020C4000,
57
59
FSL_IMX6UL_WDOG2_ADDR = 0x020C0000,
58
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
60
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
61
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/arm/fsl-imx6ul.c
60
--- a/hw/intc/arm_gicv3_its.c
63
+++ b/hw/arm/fsl-imx6ul.c
61
+++ b/hw/intc/arm_gicv3_its.c
64
@@ -XXX,XX +XXX,XX @@
62
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_mapd(GICv3ITSState *s, uint64_t value,
65
#include "qapi/error.h"
63
return update_dte(s, devid, valid, size, itt_addr) ? CMD_CONTINUE : CMD_STALL;
66
#include "hw/arm/fsl-imx6ul.h"
64
}
67
#include "hw/misc/unimp.h"
65
68
+#include "hw/usb/imx-usb-phy.h"
66
+static ItsCmdResult process_movall(GICv3ITSState *s, uint64_t value,
69
#include "hw/boards.h"
67
+ uint32_t offset)
70
#include "sysemu/sysemu.h"
68
+{
71
#include "qemu/error-report.h"
69
+ AddressSpace *as = &s->gicv3->dma_as;
72
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
70
+ MemTxResult res = MEMTX_OK;
73
TYPE_IMX_ENET);
71
+ uint64_t rd1, rd2;
74
}
72
+
75
73
+ /* No fields in dwords 0 or 1 */
76
+ /* USB */
74
+ offset += NUM_BYTES_IN_DW;
77
+ for (i = 0; i < FSL_IMX6UL_NUM_USB_PHYS; i++) {
75
+ offset += NUM_BYTES_IN_DW;
78
+ snprintf(name, NAME_SIZE, "usbphy%d", i);
76
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
79
+ sysbus_init_child_obj(obj, name, &s->usbphy[i], sizeof(s->usbphy[i]),
77
+ MEMTXATTRS_UNSPECIFIED, &res);
80
+ TYPE_IMX_USBPHY);
78
+ if (res != MEMTX_OK) {
81
+ }
79
+ return CMD_STALL;
82
+ for (i = 0; i < FSL_IMX6UL_NUM_USBS; i++) {
83
+ snprintf(name, NAME_SIZE, "usb%d", i);
84
+ sysbus_init_child_obj(obj, name, &s->usb[i], sizeof(s->usb[i]),
85
+ TYPE_CHIPIDEA);
86
+ }
80
+ }
87
+
81
+
88
/*
82
+ rd1 = FIELD_EX64(value, MOVALL_2, RDBASE1);
89
* SDHCI
83
+ if (rd1 >= s->gicv3->num_cpu) {
90
*/
84
+ qemu_log_mask(LOG_GUEST_ERROR,
91
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
85
+ "%s: RDBASE1 %" PRId64
92
FSL_IMX6UL_ENETn_TIMER_IRQ[i]));
86
+ " out of range (must be less than %d)\n",
93
}
87
+ __func__, rd1, s->gicv3->num_cpu);
94
88
+ return CMD_CONTINUE;
95
+ /* USB */
96
+ for (i = 0; i < FSL_IMX6UL_NUM_USB_PHYS; i++) {
97
+ object_property_set_bool(OBJECT(&s->usbphy[i]), true, "realized",
98
+ &error_abort);
99
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usbphy[i]), 0,
100
+ FSL_IMX6UL_USBPHY1_ADDR + i * 0x1000);
101
+ }
89
+ }
102
+
90
+
103
+ for (i = 0; i < FSL_IMX6UL_NUM_USBS; i++) {
91
+ offset += NUM_BYTES_IN_DW;
104
+ static const int FSL_IMX6UL_USBn_IRQ[] = {
92
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
105
+ FSL_IMX6UL_USB1_IRQ,
93
+ MEMTXATTRS_UNSPECIFIED, &res);
106
+ FSL_IMX6UL_USB2_IRQ,
94
+ if (res != MEMTX_OK) {
107
+ };
95
+ return CMD_STALL;
108
+ object_property_set_bool(OBJECT(&s->usb[i]), true, "realized",
109
+ &error_abort);
110
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0,
111
+ FSL_IMX6UL_USBO2_USB_ADDR + i * 0x200);
112
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0,
113
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
114
+ FSL_IMX6UL_USBn_IRQ[i]));
115
+ }
96
+ }
116
+
97
+
117
/*
98
+ rd2 = FIELD_EX64(value, MOVALL_3, RDBASE2);
118
* USDHC
99
+ if (rd2 >= s->gicv3->num_cpu) {
119
*/
100
+ qemu_log_mask(LOG_GUEST_ERROR,
101
+ "%s: RDBASE2 %" PRId64
102
+ " out of range (must be less than %d)\n",
103
+ __func__, rd2, s->gicv3->num_cpu);
104
+ return CMD_CONTINUE;
105
+ }
106
+
107
+ if (rd1 == rd2) {
108
+ /* Move to same target must succeed as a no-op */
109
+ return CMD_CONTINUE;
110
+ }
111
+
112
+ /* Move all pending LPIs from redistributor 1 to redistributor 2 */
113
+ gicv3_redist_movall_lpis(&s->gicv3->cpu[rd1], &s->gicv3->cpu[rd2]);
114
+
115
+ return CMD_CONTINUE;
116
+}
117
+
118
/*
119
* Current implementation blocks until all
120
* commands are processed
121
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
122
gicv3_redist_update_lpi(&s->gicv3->cpu[i]);
123
}
124
break;
125
+ case GITS_CMD_MOVALL:
126
+ result = process_movall(s, data, cq_offset);
127
+ break;
128
default:
129
break;
130
}
131
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/hw/intc/arm_gicv3_redist.c
134
+++ b/hw/intc/arm_gicv3_redist.c
135
@@ -XXX,XX +XXX,XX @@ void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level)
136
gicv3_redist_lpi_pending(cs, irq, level);
137
}
138
139
+void gicv3_redist_movall_lpis(GICv3CPUState *src, GICv3CPUState *dest)
140
+{
141
+ /*
142
+ * We must move all pending LPIs from the source redistributor
143
+ * to the destination. That is, for every pending LPI X on
144
+ * src, we must set it not-pending on src and pending on dest.
145
+ * LPIs that are already pending on dest are not cleared.
146
+ *
147
+ * If LPIs are disabled on dest this is CONSTRAINED UNPREDICTABLE:
148
+ * we choose to NOP. If LPIs are disabled on source there's nothing
149
+ * to be transferred anyway.
150
+ */
151
+ AddressSpace *as = &src->gic->dma_as;
152
+ uint64_t idbits;
153
+ uint32_t pendt_size;
154
+ uint64_t src_baddr, dest_baddr;
155
+ int i;
156
+
157
+ if (!(src->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) ||
158
+ !(dest->gicr_ctlr & GICR_CTLR_ENABLE_LPIS)) {
159
+ return;
160
+ }
161
+
162
+ idbits = MIN(FIELD_EX64(src->gicr_propbaser, GICR_PROPBASER, IDBITS),
163
+ GICD_TYPER_IDBITS);
164
+ idbits = MIN(FIELD_EX64(dest->gicr_propbaser, GICR_PROPBASER, IDBITS),
165
+ idbits);
166
+
167
+ pendt_size = 1ULL << (idbits + 1);
168
+ src_baddr = src->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
169
+ dest_baddr = dest->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
170
+
171
+ for (i = GICV3_LPI_INTID_START / 8; i < pendt_size / 8; i++) {
172
+ uint8_t src_pend, dest_pend;
173
+
174
+ address_space_read(as, src_baddr + i, MEMTXATTRS_UNSPECIFIED,
175
+ &src_pend, sizeof(src_pend));
176
+ if (!src_pend) {
177
+ continue;
178
+ }
179
+ address_space_read(as, dest_baddr + i, MEMTXATTRS_UNSPECIFIED,
180
+ &dest_pend, sizeof(dest_pend));
181
+ dest_pend |= src_pend;
182
+ src_pend = 0;
183
+ address_space_write(as, src_baddr + i, MEMTXATTRS_UNSPECIFIED,
184
+ &src_pend, sizeof(src_pend));
185
+ address_space_write(as, dest_baddr + i, MEMTXATTRS_UNSPECIFIED,
186
+ &dest_pend, sizeof(dest_pend));
187
+ }
188
+
189
+ gicv3_redist_update_lpi(src);
190
+ gicv3_redist_update_lpi(dest);
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 */
120
--
196
--
121
2.20.1
197
2.25.1
122
198
123
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 Linux kernel recently started using FAST_READ_4 commands.
3
Address should be 0x1E631000 and not 0x1E641000 as initially introduced.
4
This results in flash read failures. At the same time, the m25p80
5
emulation is seen to read 8 more bytes than expected. Adjusting the
6
expected number of dummy cycles to match FAST_READ fixes the problem.
7
4
8
Fixes: f95c4bffdc4c ("aspeed/smc: snoop SPI transfers to fake dummy cycles")
5
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/838
9
Reviewed-by: Cédric Le Goater <clg@kaod.org>
6
Fixes: f25c0ae1079d ("aspeed/soc: Add AST2600 support")
10
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
7
Suggested-by: Troy Lee <troy_lee@aspeedtech.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20220126083520.4135713-1-clg@kaod.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
12
---
14
hw/ssi/aspeed_smc.c | 2 +-
13
hw/arm/aspeed_ast2600.c | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
16
15
17
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
16
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/ssi/aspeed_smc.c
18
--- a/hw/arm/aspeed_ast2600.c
20
+++ b/hw/ssi/aspeed_smc.c
19
+++ b/hw/arm/aspeed_ast2600.c
21
@@ -XXX,XX +XXX,XX @@ static int aspeed_smc_num_dummies(uint8_t command)
20
@@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
22
case FAST_READ:
21
[ASPEED_DEV_PWM] = 0x1E610000,
23
case DOR:
22
[ASPEED_DEV_FMC] = 0x1E620000,
24
case QOR:
23
[ASPEED_DEV_SPI1] = 0x1E630000,
25
+ case FAST_READ_4:
24
- [ASPEED_DEV_SPI2] = 0x1E641000,
26
case DOR_4:
25
+ [ASPEED_DEV_SPI2] = 0x1E631000,
27
case QOR_4:
26
[ASPEED_DEV_EHCI1] = 0x1E6A1000,
28
return 1;
27
[ASPEED_DEV_EHCI2] = 0x1E6A3000,
29
case DIOR:
28
[ASPEED_DEV_MII1] = 0x1E650000,
30
- case FAST_READ_4:
31
case DIOR_4:
32
return 2;
33
case QIOR:
34
--
29
--
35
2.20.1
30
2.25.1
36
31
37
32
diff view generated by jsdifflib
New patch
1
The exception caused by an SVC instruction may be taken to AArch32
2
Hyp mode for two reasons:
3
* HCR.TGE indicates that exceptions from EL0 should trap to EL2
4
* we were already in Hyp mode
1
5
6
The entrypoint in the vector table to be used differs in these two
7
cases: for an exception routed to Hyp mode from EL0, we enter at the
8
common 0x14 "hyp trap" entrypoint. For SVC from Hyp mode to Hyp
9
mode, we enter at the 0x08 (svc/hvc trap) entrypoint.
10
In the v8A Arm ARM pseudocode this is done in AArch32.TakeSVCException.
11
12
QEMU incorrectly routed both of these exceptions to the 0x14
13
entrypoint. Correct the entrypoint for SVC from Hyp to Hyp by making
14
use of the existing logic which handles "normal entrypoint for
15
Hyp-to-Hyp, otherwise 0x14" for traps like UNDEF and data/prefetch
16
aborts (reproduced here since it's outside the visible context
17
in the diff for this commit):
18
19
if (arm_current_el(env) != 2 && addr < 0x14) {
20
addr = 0x14;
21
}
22
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20220117131953.3936137-1-peter.maydell@linaro.org
27
---
28
target/arm/helper.c | 4 ++--
29
1 file changed, 2 insertions(+), 2 deletions(-)
30
31
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/helper.c
34
+++ b/target/arm/helper.c
35
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
36
* separately here.
37
*
38
* The vector table entry used is always the 0x14 Hyp mode entry point,
39
- * unless this is an UNDEF/HVC/abort taken from Hyp to Hyp.
40
+ * unless this is an UNDEF/SVC/HVC/abort taken from Hyp to Hyp.
41
* The offset applied to the preferred return address is always zero
42
* (see DDI0487C.a section G1.12.3).
43
* PSTATE A/I/F masks are set based only on the SCR.EA/IRQ/FIQ values.
44
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
45
addr = 0x04;
46
break;
47
case EXCP_SWI:
48
- addr = 0x14;
49
+ addr = 0x08;
50
break;
51
case EXCP_BKPT:
52
/* Fall through to prefetch abort. */
53
--
54
2.25.1
55
56
diff view generated by jsdifflib