1
First arm pullreq for 7.1. The bulk of this is the qemu_split_irq
1
The following changes since commit 64ada298b98a51eb2512607f6e6180cb330c47b1:
2
removal.
3
2
4
I have enough stuff in my to-review queue that I expect to do another
3
Merge remote-tracking branch 'remotes/legoater/tags/pull-ppc-20220302' into staging (2022-03-02 12:38:46 +0000)
5
pullreq early next week, but 31 patches is enough to not hang on to.
6
7
thanks
8
-- PMM
9
10
The following changes since commit 9c125d17e9402c232c46610802e5931b3639d77b:
11
12
Merge tag 'pull-tcg-20220420' of https://gitlab.com/rth7680/qemu into staging (2022-04-20 16:43:11 -0700)
13
4
14
are available in the Git repository at:
5
are available in the Git repository at:
15
6
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220421
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220302
17
8
18
for you to fetch changes up to 5b415dd61bdbf61fb4be0e9f1a7172b8bce682c6:
9
for you to fetch changes up to 268c11984e67867c22f53beb3c7f8b98900d66b2:
19
10
20
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs (2022-04-21 11:37:05 +0100)
11
ui/cocoa.m: Remove unnecessary NSAutoreleasePools (2022-03-02 19:27:37 +0000)
21
12
22
----------------------------------------------------------------
13
----------------------------------------------------------------
23
target-arm queue:
14
target-arm queue:
24
* hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
15
* mps3-an547: Add missing user ahb interfaces
25
* versal: Add the Cortex-R5s in the Real-Time Processing Unit (RPU) subsystem
16
* hw/arm/mps2-tz.c: Update AN547 documentation URL
26
* versal: model enough of the Clock/Reset Low-power domain (CRL) to allow control of the Cortex-R5s
17
* hw/input/tsc210x: Don't abort on bad SPI word widths
27
* xlnx-zynqmp: Connect 4 TTC timers
18
* hw/i2c: flatten pca954x mux device
28
* exynos4210: Refactor GIC/combiner code to stop using qemu_split_irq
19
* target/arm: Support PSCI 1.1 and SMCCC 1.0
29
* realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
20
* target/arm: Fix early free of TCG temp in handle_simd_shift_fpint_conv()
30
* stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
21
* tests/qtest: add qtests for npcm7xx sdhci
31
* hw/core/irq: remove unused 'qemu_irq_split' function
22
* Implement FEAT_LVA
32
* npcm7xx: use symbolic constants for PWRON STRAP bit fields
23
* Implement FEAT_LPA
33
* virt: document impact of gic-version on max CPUs
24
* Implement FEAT_LPA2 (but do not enable it yet)
25
* Report KVM's actual PSCI version to guest in dtb
26
* ui/cocoa.m: Fix updateUIInfo threading issues
27
* ui/cocoa.m: Remove unnecessary NSAutoreleasePools
34
28
35
----------------------------------------------------------------
29
----------------------------------------------------------------
36
Edgar E. Iglesias (6):
30
Akihiko Odaki (1):
37
timer: cadence_ttc: Break out header file to allow embedding
31
target/arm: Support PSCI 1.1 and SMCCC 1.0
38
hw/arm/xlnx-zynqmp: Connect 4 TTC timers
39
hw/arm: versal: Create an APU CPU Cluster
40
hw/arm: versal: Add the Cortex-R5Fs
41
hw/misc: Add a model of the Xilinx Versal CRL
42
hw/arm: versal: Connect the CRL
43
32
44
Hao Wu (2):
33
Jimmy Brisson (1):
45
hw/misc: Add PWRON STRAP bit fields in GCR module
34
mps3-an547: Add missing user ahb interfaces
46
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs
47
35
48
Heinrich Schuchardt (1):
36
Patrick Venture (1):
49
hw/arm/virt: impact of gic-version on max CPUs
37
hw/i2c: flatten pca954x mux device
50
38
51
Peter Maydell (19):
39
Peter Maydell (5):
52
hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
40
hw/arm/mps2-tz.c: Update AN547 documentation URL
53
hw/arm/exynos4210: Use TYPE_OR_IRQ instead of custom OR-gate device
41
hw/input/tsc210x: Don't abort on bad SPI word widths
54
hw/intc/exynos4210_gic: Remove unused TYPE_EXYNOS4210_IRQ_GATE
42
target/arm: Report KVM's actual PSCI version to guest in dtb
55
hw/arm/exynos4210: Put a9mpcore device into state struct
43
ui/cocoa.m: Fix updateUIInfo threading issues
56
hw/arm/exynos4210: Drop int_gic_irq[] from Exynos4210Irq struct
44
ui/cocoa.m: Remove unnecessary NSAutoreleasePools
57
hw/arm/exynos4210: Coalesce board_irqs and irq_table
58
hw/arm/exynos4210: Fix code style nit in combiner_grp_to_gic_id[]
59
hw/arm/exynos4210: Move exynos4210_init_board_irqs() into exynos4210.c
60
hw/arm/exynos4210: Put external GIC into state struct
61
hw/arm/exynos4210: Drop ext_gic_irq[] from Exynos4210Irq struct
62
hw/arm/exynos4210: Move exynos4210_combiner_get_gpioin() into exynos4210.c
63
hw/arm/exynos4210: Delete unused macro definitions
64
hw/arm/exynos4210: Use TYPE_SPLIT_IRQ in exynos4210_init_board_irqs()
65
hw/arm/exynos4210: Fill in irq_table[] for internal-combiner-only IRQ lines
66
hw/arm/exynos4210: Connect MCT_G0 and MCT_G1 to both combiners
67
hw/arm/exynos4210: Don't connect multiple lines to external GIC inputs
68
hw/arm/exynos4210: Fold combiner splits into exynos4210_init_board_irqs()
69
hw/arm/exynos4210: Put combiners into state struct
70
hw/arm/exynos4210: Drop Exynos4210Irq struct
71
45
72
Zongyuan Li (3):
46
Richard Henderson (16):
73
hw/arm/realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
47
hw/registerfields: Add FIELD_SEX<N> and FIELD_SDP<N>
74
hw/arm/stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
48
target/arm: Set TCR_EL1.TSZ for user-only
75
hw/core/irq: remove unused 'qemu_irq_split' function
49
target/arm: Fault on invalid TCR_ELx.TxSZ
50
target/arm: Move arm_pamax out of line
51
target/arm: Pass outputsize down to check_s2_mmu_setup
52
target/arm: Use MAKE_64BIT_MASK to compute indexmask
53
target/arm: Honor TCR_ELx.{I}PS
54
target/arm: Prepare DBGBVR and DBGWVR for FEAT_LVA
55
target/arm: Implement FEAT_LVA
56
target/arm: Implement FEAT_LPA
57
target/arm: Extend arm_fi_to_lfsc to level -1
58
target/arm: Introduce tlbi_aa64_get_range
59
target/arm: Fix TLBIRange.base for 16k and 64k pages
60
target/arm: Validate tlbi TG matches translation granule in use
61
target/arm: Advertise all page sizes for -cpu max
62
target/arm: Implement FEAT_LPA2
76
63
77
docs/system/arm/virt.rst | 4 +-
64
Shengtan Mao (1):
78
include/hw/arm/exynos4210.h | 50 ++--
65
tests/qtest: add qtests for npcm7xx sdhci
79
include/hw/arm/xlnx-versal.h | 16 ++
66
80
include/hw/arm/xlnx-zynqmp.h | 4 +
67
Wentao_Liang (1):
81
include/hw/intc/exynos4210_combiner.h | 57 +++++
68
target/arm: Fix early free of TCG temp in handle_simd_shift_fpint_conv()
82
include/hw/intc/exynos4210_gic.h | 43 ++++
69
83
include/hw/irq.h | 5 -
70
docs/system/arm/emulation.rst | 3 +
84
include/hw/misc/npcm7xx_gcr.h | 30 +++
71
include/hw/registerfields.h | 48 +++++-
85
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++++
72
target/arm/cpu-param.h | 4 +-
86
include/hw/timer/cadence_ttc.h | 54 +++++
73
target/arm/cpu.h | 27 ++++
87
hw/arm/exynos4210.c | 430 ++++++++++++++++++++++++++++++----
74
target/arm/internals.h | 58 ++++---
88
hw/arm/npcm7xx_boards.c | 24 +-
75
target/arm/kvm-consts.h | 14 +-
89
hw/arm/realview.c | 33 ++-
76
hw/arm/boot.c | 11 +-
90
hw/arm/stellaris.c | 15 +-
77
hw/arm/mps2-tz.c | 6 +-
91
hw/arm/virt.c | 7 +
78
hw/i2c/i2c_mux_pca954x.c | 77 ++-------
92
hw/arm/xlnx-versal-virt.c | 6 +-
79
hw/input/tsc210x.c | 8 +-
93
hw/arm/xlnx-versal.c | 99 +++++++-
80
target/arm/cpu.c | 8 +-
94
hw/arm/xlnx-zynqmp.c | 22 ++
81
target/arm/cpu64.c | 7 +-
95
hw/core/irq.c | 15 --
82
target/arm/helper.c | 332 ++++++++++++++++++++++++++++++---------
96
hw/intc/exynos4210_combiner.c | 108 +--------
83
target/arm/hvf/hvf.c | 27 +++-
97
hw/intc/exynos4210_gic.c | 344 +--------------------------
84
target/arm/kvm64.c | 14 +-
98
hw/misc/xlnx-versal-crl.c | 421 +++++++++++++++++++++++++++++++++
85
target/arm/psci.c | 35 ++++-
99
hw/timer/cadence_ttc.c | 32 +--
86
target/arm/translate-a64.c | 2 +-
100
MAINTAINERS | 2 +-
87
tests/qtest/npcm7xx_sdhci-test.c | 215 +++++++++++++++++++++++++
101
hw/misc/meson.build | 1 +
88
tests/qtest/meson.build | 1 +
102
25 files changed, 1457 insertions(+), 600 deletions(-)
89
ui/cocoa.m | 31 ++--
103
create mode 100644 include/hw/intc/exynos4210_combiner.h
90
20 files changed, 736 insertions(+), 192 deletions(-)
104
create mode 100644 include/hw/intc/exynos4210_gic.h
91
create mode 100644 tests/qtest/npcm7xx_sdhci-test.c
105
create mode 100644 include/hw/misc/xlnx-versal-crl.h
106
create mode 100644 include/hw/timer/cadence_ttc.h
107
create mode 100644 hw/misc/xlnx-versal-crl.c
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Jimmy Brisson <jimmy.brisson@linaro.org>
2
2
3
This patch uses the defined fields to describe PWRON STRAPs for
3
With these interfaces missing, TFM would delegate peripherals 0, 1,
4
better readability.
4
2, 3 and 8, and qemu would ignore the delegation of interface 8, as
5
it thought interface 4 was eth & USB.
5
6
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
7
This patch corrects this behavior and allows TFM to delegate the
7
Reviewed-by: Patrick Venture <venture@google.com>
8
eth & USB peripheral to NS mode.
8
Message-id: 20220411165842.3912945-3-wuhaotsh@google.com
9
10
(The old QEMU behaviour was based on revision B of the AN547
11
appnote; revision C corrects this error in the documentation,
12
and this commit brings QEMU in to line with how the FPGA
13
image really behaves.)
14
15
Signed-off-by: Jimmy Brisson <jimmy.brisson@linaro.org>
16
Message-id: 20220210210227.3203883-1-jimmy.brisson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
[PMM: added commit message note clarifying that the old behaviour
19
was a docs issue, not because there were two different versions
20
of the FPGA image]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
22
---
12
hw/arm/npcm7xx_boards.c | 24 +++++++++++++++++++-----
23
hw/arm/mps2-tz.c | 4 ++++
13
1 file changed, 19 insertions(+), 5 deletions(-)
24
1 file changed, 4 insertions(+)
14
25
15
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
26
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/npcm7xx_boards.c
28
--- a/hw/arm/mps2-tz.c
18
+++ b/hw/arm/npcm7xx_boards.c
29
+++ b/hw/arm/mps2-tz.c
19
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
20
#include "sysemu/sysemu.h"
31
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
21
#include "sysemu/block-backend.h"
32
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
22
33
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
23
-#define NPCM750_EVB_POWER_ON_STRAPS 0x00001ff7
34
+ { /* port 4 USER AHB interface 0 */ },
24
-#define QUANTA_GSJ_POWER_ON_STRAPS 0x00001fff
35
+ { /* port 5 USER AHB interface 1 */ },
25
-#define QUANTA_GBS_POWER_ON_STRAPS 0x000017ff
36
+ { /* port 6 USER AHB interface 2 */ },
26
-#define KUDO_BMC_POWER_ON_STRAPS 0x00001fff
37
+ { /* port 7 USER AHB interface 3 */ },
27
-#define MORI_BMC_POWER_ON_STRAPS 0x00001fff
38
{ "eth-usb", make_eth_usb, NULL, 0x41400000, 0x200000, { 49 } },
28
+#define NPCM7XX_POWER_ON_STRAPS_DEFAULT ( \
39
},
29
+ NPCM7XX_PWRON_STRAP_SPI0F18 | \
40
},
30
+ NPCM7XX_PWRON_STRAP_SFAB | \
31
+ NPCM7XX_PWRON_STRAP_BSPA | \
32
+ NPCM7XX_PWRON_STRAP_FUP(FUP_NORM_UART2) | \
33
+ NPCM7XX_PWRON_STRAP_SECEN | \
34
+ NPCM7XX_PWRON_STRAP_HIZ | \
35
+ NPCM7XX_PWRON_STRAP_ECC | \
36
+ NPCM7XX_PWRON_STRAP_RESERVE1 | \
37
+ NPCM7XX_PWRON_STRAP_J2EN | \
38
+ NPCM7XX_PWRON_STRAP_CKFRQ(CKFRQ_DEFAULT))
39
+
40
+#define NPCM750_EVB_POWER_ON_STRAPS ( \
41
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_J2EN)
42
+#define QUANTA_GSJ_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
43
+#define QUANTA_GBS_POWER_ON_STRAPS ( \
44
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_SFAB)
45
+#define KUDO_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
46
+#define MORI_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
47
48
static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
49
50
--
41
--
51
2.25.1
42
2.25.1
diff view generated by jsdifflib
1
Fix a missing set of spaces around '-' in the definition of
1
The AN547 application note URL has changed: update our comment
2
combiner_grp_to_gic_id[]. We're about to move this code, so
2
accordingly. (Rev B is still downloadable from the old URL,
3
fix the style issue first to keep checkpatch happy with the
3
but there is a new Rev C of the document now.)
4
code-motion patch.
5
4
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20220404154658.565020-7-peter.maydell@linaro.org
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20220221094144.426191-1-peter.maydell@linaro.org
9
---
9
---
10
hw/intc/exynos4210_gic.c | 2 +-
10
hw/arm/mps2-tz.c | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 1 insertion(+), 1 deletion(-)
12
12
13
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/intc/exynos4210_gic.c
15
--- a/hw/arm/mps2-tz.c
16
+++ b/hw/intc/exynos4210_gic.c
16
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@ enum ExtInt {
17
@@ -XXX,XX +XXX,XX @@
18
*/
18
* Application Note AN524:
19
19
* https://developer.arm.com/documentation/dai0524/latest/
20
static const uint32_t
20
* Application Note AN547:
21
-combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
21
- * https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/DAI0547B_SSE300_PLUS_U55_FPGA_for_mps3.pdf
22
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
22
+ * https://developer.arm.com/documentation/dai0547/latest/
23
/* int combiner groups 16-19 */
23
*
24
{ }, { }, { }, { },
24
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
25
/* int combiner group 20 */
25
* (ARM ECM0601256) for the details of some of the device layout:
26
--
26
--
27
2.25.1
27
2.25.1
28
29
diff view generated by jsdifflib
1
Currently for the interrupts MCT_G0 and MCT_G1 which are
1
The tsc210x doesn't support anything other than 16-bit reads on the
2
the only ones in the input range of the external combiner
2
SPI bus, but the guest can program the SPI controller to attempt
3
and which are also wired to the external GIC, we connect
3
them anyway. If this happens, don't abort QEMU, just log this as
4
them only to the internal combiner and the external GIC.
4
a guest error.
5
This seems likely to be a bug, as all other interrupts
6
which are in the input range of both combiners are
7
connected to both combiners. (The fact that the code in
8
exynos4210_combiner_get_gpioin() is also trying to wire
9
up these inputs on both combiners also suggests this.)
10
5
11
Wire these interrupts up to both combiners, like the rest.
6
This fixes our machine_arm_n8x0.py:N8x0Machine.test_n800
7
acceptance test, which hits this assertion.
12
8
9
The reason we hit the assertion is because the guest kernel thinks
10
there is a TSC2005 on this SPI bus address, not a TSC210x. (The n810
11
*does* have a TSC2005 at this address.) The TSC2005 supports the
12
24-bit accesses which the guest driver makes, and the TSC210x does
13
not (that is, our TSC210x emulation is not missing support for a word
14
width the hardware can handle). It's not clear whether the problem
15
here is that the guest kernel incorrectly thinks the n800 has the
16
same device at this SPI bus address as the n810, or that QEMU's n810
17
board model doesn't get the SPI devices right. At this late date
18
there no longer appears to be any reliable information on the web
19
about the hardware behaviour, but I am inclined to think this is a
20
guest kernel bug. In any case, we prefer not to abort QEMU for
21
guest-triggerable conditions, so logging the error is the right thing
22
to do.
23
24
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/736
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Message-id: 20220404154658.565020-15-peter.maydell@linaro.org
27
Message-id: 20220221140750.514557-1-peter.maydell@linaro.org
16
---
28
---
17
hw/arm/exynos4210.c | 7 +++----
29
hw/input/tsc210x.c | 8 ++++++--
18
1 file changed, 3 insertions(+), 4 deletions(-)
30
1 file changed, 6 insertions(+), 2 deletions(-)
19
31
20
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
32
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
21
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/exynos4210.c
34
--- a/hw/input/tsc210x.c
23
+++ b/hw/arm/exynos4210.c
35
+++ b/hw/input/tsc210x.c
24
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
36
@@ -XXX,XX +XXX,XX @@
25
37
#include "hw/hw.h"
26
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
38
#include "audio/audio.h"
27
splitter = DEVICE(&s->splitter[splitcount]);
39
#include "qemu/timer.h"
28
- qdev_prop_set_uint16(splitter, "num-lines", 2);
40
+#include "qemu/log.h"
29
+ qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
41
#include "sysemu/reset.h"
30
qdev_realize(splitter, NULL, &error_abort);
42
#include "ui/console.h"
31
splitcount++;
43
#include "hw/arm/omap.h" /* For I2SCodec */
32
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
44
@@ -XXX,XX +XXX,XX @@ uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len)
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
45
TSC210xState *s = opaque;
34
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
46
uint32_t ret = 0;
35
if (irq_id) {
47
36
- qdev_connect_gpio_out(splitter, 1,
48
- if (len != 16)
37
+ qdev_connect_gpio_out(splitter, 2,
49
- hw_error("%s: FIXME: bad SPI word width %i\n", __func__, len);
38
qdev_get_gpio_in(extgicdev, irq_id - 32));
50
+ if (len != 16) {
39
- } else {
51
+ qemu_log_mask(LOG_GUEST_ERROR,
40
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
52
+ "%s: bad SPI word width %i\n", __func__, len);
41
}
53
+ return 0;
42
}
54
+ }
43
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
55
56
/* TODO: sequential reads etc - how do we make sure the host doesn't
57
* unintentionally read out a conversion result from a register while
44
--
58
--
45
2.25.1
59
2.25.1
60
61
diff view generated by jsdifflib
1
The only time we use the int_combiner_irq[] and ext_combiner_irq[]
1
From: Patrick Venture <venture@google.com>
2
arrays in the Exynos4210Irq struct is during realize of the SoC -- we
3
initialize them with the input IRQs of the combiner devices, and then
4
connect those to outputs of other devices in
5
exynos4210_init_board_irqs(). Now that the combiner objects are
6
easily accessible as s->int_combiner and s->ext_combiner we can make
7
the connections directly from one device to the other without going
8
via these arrays.
9
2
10
Since these are the only two remaining elements of Exynos4210Irq,
3
Previously this device created N subdevices which each owned an i2c bus.
11
we can remove that struct entirely.
4
Now this device simply owns the N i2c busses directly.
12
5
6
Tested: Verified devices behind mux are still accessible via qmp and i2c
7
from within an arm32 SoC.
8
9
Reviewed-by: Hao Wu <wuhaotsh@google.com>
10
Signed-off-by: Patrick Venture <venture@google.com>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20220202164533.1283668-1-venture@google.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220404154658.565020-19-peter.maydell@linaro.org
16
---
15
---
17
include/hw/arm/exynos4210.h | 6 ------
16
hw/i2c/i2c_mux_pca954x.c | 77 +++++++---------------------------------
18
hw/arm/exynos4210.c | 34 ++++++++--------------------------
17
1 file changed, 13 insertions(+), 64 deletions(-)
19
2 files changed, 8 insertions(+), 32 deletions(-)
20
18
21
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
19
diff --git a/hw/i2c/i2c_mux_pca954x.c b/hw/i2c/i2c_mux_pca954x.c
22
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/exynos4210.h
21
--- a/hw/i2c/i2c_mux_pca954x.c
24
+++ b/include/hw/arm/exynos4210.h
22
+++ b/hw/i2c/i2c_mux_pca954x.c
25
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
26
*/
24
#define PCA9548_CHANNEL_COUNT 8
27
#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
25
#define PCA9546_CHANNEL_COUNT 4
28
26
29
-typedef struct Exynos4210Irq {
27
-/*
30
- qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
28
- * struct Pca954xChannel - The i2c mux device will have N of these states
31
- qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
29
- * that own the i2c channel bus.
32
-} Exynos4210Irq;
30
- * @bus: The owned channel bus.
31
- * @enabled: Is this channel active?
32
- */
33
-typedef struct Pca954xChannel {
34
- SysBusDevice parent;
33
-
35
-
34
struct Exynos4210State {
36
- I2CBus *bus;
35
/*< private >*/
37
-
36
SysBusDevice parent_obj;
38
- bool enabled;
37
/*< public >*/
39
-} Pca954xChannel;
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
40
-
39
- Exynos4210Irq irqs;
41
-#define TYPE_PCA954X_CHANNEL "pca954x-channel"
40
qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
42
-#define PCA954X_CHANNEL(obj) \
41
43
- OBJECT_CHECK(Pca954xChannel, (obj), TYPE_PCA954X_CHANNEL)
42
MemoryRegion chipid_mem;
44
-
43
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
45
/*
44
index XXXXXXX..XXXXXXX 100644
46
* struct Pca954xState - The pca954x state object.
45
--- a/hw/arm/exynos4210.c
47
* @control: The value written to the mux control.
46
+++ b/hw/arm/exynos4210.c
48
@@ -XXX,XX +XXX,XX @@ typedef struct Pca954xState {
47
@@ -XXX,XX +XXX,XX @@ static int mapline_size(const int *mapline)
49
48
static void exynos4210_init_board_irqs(Exynos4210State *s)
50
uint8_t control;
49
{
51
50
uint32_t grp, bit, irq_id, n;
52
- /* The channel i2c buses. */
51
- Exynos4210Irq *is = &s->irqs;
53
- Pca954xChannel channel[PCA9548_CHANNEL_COUNT];
52
DeviceState *extgicdev = DEVICE(&s->ext_gic);
54
+ bool enabled[PCA9548_CHANNEL_COUNT];
53
+ DeviceState *intcdev = DEVICE(&s->int_combiner);
55
+ I2CBus *bus[PCA9548_CHANNEL_COUNT];
54
+ DeviceState *extcdev = DEVICE(&s->ext_combiner);
56
} Pca954xState;
55
int splitcount = 0;
57
56
DeviceState *splitter;
58
/*
57
const int *mapline;
59
@@ -XXX,XX +XXX,XX @@ static bool pca954x_match(I2CSlave *candidate, uint8_t address,
58
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
60
}
59
splitin = 0;
61
60
for (;;) {
62
for (i = 0; i < mc->nchans; i++) {
61
s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
63
- if (!mux->channel[i].enabled) {
62
- qdev_connect_gpio_out(splitter, splitin, is->int_combiner_irq[in]);
64
+ if (!mux->enabled[i]) {
63
- qdev_connect_gpio_out(splitter, splitin + 1, is->ext_combiner_irq[in]);
65
continue;
64
+ qdev_connect_gpio_out(splitter, splitin,
66
}
65
+ qdev_get_gpio_in(intcdev, in));
67
66
+ qdev_connect_gpio_out(splitter, splitin + 1,
68
- if (i2c_scan_bus(mux->channel[i].bus, address, broadcast,
67
+ qdev_get_gpio_in(extcdev, in));
69
+ if (i2c_scan_bus(mux->bus[i], address, broadcast,
68
splitin += 2;
70
current_devs)) {
69
if (!mapline) {
71
if (!broadcast) {
70
break;
72
return true;
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
73
@@ -XXX,XX +XXX,XX @@ static void pca954x_enable_channel(Pca954xState *s, uint8_t enable_mask)
72
qdev_realize(splitter, NULL, &error_abort);
74
*/
73
splitcount++;
75
for (i = 0; i < mc->nchans; i++) {
74
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
76
if (enable_mask & (1 << i)) {
75
- qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
77
- s->channel[i].enabled = true;
76
+ qdev_connect_gpio_out(splitter, 0, qdev_get_gpio_in(intcdev, n));
78
+ s->enabled[i] = true;
77
qdev_connect_gpio_out(splitter, 1,
78
qdev_get_gpio_in(extgicdev, irq_id - 32));
79
} else {
79
} else {
80
- s->irq_table[n] = is->int_combiner_irq[n];
80
- s->channel[i].enabled = false;
81
+ s->irq_table[n] = qdev_get_gpio_in(intcdev, n);
81
+ s->enabled[i] = false;
82
}
82
}
83
}
83
}
84
/*
85
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
86
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
87
}
84
}
88
85
@@ -XXX,XX +XXX,XX @@ I2CBus *pca954x_i2c_get_bus(I2CSlave *mux, uint8_t channel)
89
-/*
86
Pca954xState *pca954x = PCA954X(mux);
90
- * Get Combiner input GPIO into irqs structure
87
91
- */
88
g_assert(channel < pc->nchans);
92
-static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
89
- return I2C_BUS(qdev_get_child_bus(DEVICE(&pca954x->channel[channel]),
93
- DeviceState *dev, int ext)
90
- "i2c-bus"));
91
-}
92
-
93
-static void pca954x_channel_init(Object *obj)
94
-{
94
-{
95
- int n;
95
- Pca954xChannel *s = PCA954X_CHANNEL(obj);
96
- int max;
96
- s->bus = i2c_init_bus(DEVICE(s), "i2c-bus");
97
- qemu_irq *irq;
98
-
97
-
99
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
98
- /* Start all channels as disabled. */
100
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
99
- s->enabled = false;
101
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
100
-}
102
-
101
-
103
- for (n = 0; n < max; n++) {
102
-static void pca954x_channel_class_init(ObjectClass *klass, void *data)
104
- irq[n] = qdev_get_gpio_in(dev, n);
103
-{
104
- DeviceClass *dc = DEVICE_CLASS(klass);
105
- dc->desc = "Pca954x Channel";
106
+ return pca954x->bus[channel];
107
}
108
109
static void pca9546_class_init(ObjectClass *klass, void *data)
110
@@ -XXX,XX +XXX,XX @@ static void pca9548_class_init(ObjectClass *klass, void *data)
111
s->nchans = PCA9548_CHANNEL_COUNT;
112
}
113
114
-static void pca954x_realize(DeviceState *dev, Error **errp)
115
-{
116
- Pca954xState *s = PCA954X(dev);
117
- Pca954xClass *c = PCA954X_GET_CLASS(s);
118
- int i;
119
-
120
- /* SMBus modules. Cannot fail. */
121
- for (i = 0; i < c->nchans; i++) {
122
- sysbus_realize(SYS_BUS_DEVICE(&s->channel[i]), &error_abort);
105
- }
123
- }
106
-}
124
-}
107
-
125
-
108
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
126
static void pca954x_init(Object *obj)
109
0x09, 0x00, 0x00, 0x00 };
127
{
110
128
Pca954xState *s = PCA954X(obj);
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
129
Pca954xClass *c = PCA954X_GET_CLASS(obj);
112
sysbus_connect_irq(busdev, n,
130
int i;
113
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
131
132
- /* Only initialize the children we expect. */
133
+ /* SMBus modules. Cannot fail. */
134
for (i = 0; i < c->nchans; i++) {
135
- object_initialize_child(obj, "channel[*]", &s->channel[i],
136
- TYPE_PCA954X_CHANNEL);
137
+ g_autofree gchar *bus_name = g_strdup_printf("i2c.%d", i);
138
+
139
+ /* start all channels as disabled. */
140
+ s->enabled[i] = false;
141
+ s->bus[i] = i2c_init_bus(DEVICE(s), bus_name);
114
}
142
}
115
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
143
}
116
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
144
117
145
@@ -XXX,XX +XXX,XX @@ static void pca954x_class_init(ObjectClass *klass, void *data)
118
/* External Interrupt Combiner */
146
rc->phases.enter = pca954x_enter_reset;
119
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
147
120
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
148
dc->desc = "Pca954x i2c-mux";
121
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
149
- dc->realize = pca954x_realize;
122
}
150
123
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
151
k->write_data = pca954x_write_data;
124
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
152
k->receive_byte = pca954x_read_byte;
125
153
@@ -XXX,XX +XXX,XX @@ static const TypeInfo pca954x_info[] = {
126
/* Initialize board IRQs. */
154
.parent = TYPE_PCA954X,
155
.class_init = pca9548_class_init,
156
},
157
- {
158
- .name = TYPE_PCA954X_CHANNEL,
159
- .parent = TYPE_SYS_BUS_DEVICE,
160
- .class_init = pca954x_channel_class_init,
161
- .instance_size = sizeof(Pca954xChannel),
162
- .instance_init = pca954x_channel_init,
163
- }
164
};
165
166
DEFINE_TYPES(pca954x_info)
127
--
167
--
128
2.25.1
168
2.25.1
169
170
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Akihiko Odaki <akihiko.odaki@gmail.com>
2
2
3
Connect the 4 TTC timers on the ZynqMP.
3
Support the latest PSCI on TCG and HVF. A 64-bit function called from
4
AArch32 now returns NOT_SUPPORTED, which is necessary to adhere to SMC
5
Calling Convention 1.0. It is still not compliant with SMCCC 1.3 since
6
they do not implement mandatory functions.
4
7
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
8
Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20220213035753.34577-1-akihiko.odaki@gmail.com
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
11
[PMM: update MISMATCH_CHECK checks on PSCI_VERSION macros to match]
9
Message-id: 20220331222017.2914409-3-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
include/hw/arm/xlnx-zynqmp.h | 4 ++++
14
target/arm/kvm-consts.h | 13 +++++++++----
13
hw/arm/xlnx-zynqmp.c | 22 ++++++++++++++++++++++
15
hw/arm/boot.c | 12 +++++++++---
14
2 files changed, 26 insertions(+)
16
target/arm/cpu.c | 5 +++--
17
target/arm/hvf/hvf.c | 27 ++++++++++++++++++++++++++-
18
target/arm/kvm64.c | 2 +-
19
target/arm/psci.c | 35 ++++++++++++++++++++++++++++++++---
20
6 files changed, 80 insertions(+), 14 deletions(-)
15
21
16
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
22
diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h
17
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-zynqmp.h
24
--- a/target/arm/kvm-consts.h
19
+++ b/include/hw/arm/xlnx-zynqmp.h
25
+++ b/target/arm/kvm-consts.h
20
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@ MISMATCH_CHECK(QEMU_PSCI_0_1_FN_MIGRATE, KVM_PSCI_FN_MIGRATE);
21
#include "hw/or-irq.h"
27
#define QEMU_PSCI_0_2_FN64_AFFINITY_INFO QEMU_PSCI_0_2_FN64(4)
22
#include "hw/misc/xlnx-zynqmp-apu-ctrl.h"
28
#define QEMU_PSCI_0_2_FN64_MIGRATE QEMU_PSCI_0_2_FN64(5)
23
#include "hw/misc/xlnx-zynqmp-crf.h"
29
24
+#include "hw/timer/cadence_ttc.h"
30
+#define QEMU_PSCI_1_0_FN_PSCI_FEATURES QEMU_PSCI_0_2_FN(10)
25
26
#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
27
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
28
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
29
#define XLNX_ZYNQMP_MAX_RAM_SIZE (XLNX_ZYNQMP_MAX_LOW_RAM_SIZE + \
30
XLNX_ZYNQMP_MAX_HIGH_RAM_SIZE)
31
32
+#define XLNX_ZYNQMP_NUM_TTC 4
33
+
31
+
34
/*
32
MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_SUSPEND, PSCI_0_2_FN_CPU_SUSPEND);
35
* Unimplemented mmio regions needed to boot some images.
33
MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_OFF, PSCI_0_2_FN_CPU_OFF);
36
*/
34
MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_ON, PSCI_0_2_FN_CPU_ON);
37
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
35
@@ -XXX,XX +XXX,XX @@ MISMATCH_CHECK(QEMU_PSCI_0_2_FN_MIGRATE, PSCI_0_2_FN_MIGRATE);
38
qemu_or_irq qspi_irq_orgate;
36
MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_SUSPEND, PSCI_0_2_FN64_CPU_SUSPEND);
39
XlnxZynqMPAPUCtrl apu_ctrl;
37
MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_ON, PSCI_0_2_FN64_CPU_ON);
40
XlnxZynqMPCRF crf;
38
MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_MIGRATE, PSCI_0_2_FN64_MIGRATE);
41
+ CadenceTTCState ttc[XLNX_ZYNQMP_NUM_TTC];
39
+MISMATCH_CHECK(QEMU_PSCI_1_0_FN_PSCI_FEATURES, PSCI_1_0_FN_PSCI_FEATURES);
42
40
43
char *boot_cpu;
41
/* PSCI v0.2 return values used by TCG emulation of PSCI */
44
ARMCPU *boot_cpu_ptr;
42
45
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
43
/* No Trusted OS migration to worry about when offlining CPUs */
46
index XXXXXXX..XXXXXXX 100644
44
#define QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED 2
47
--- a/hw/arm/xlnx-zynqmp.c
45
48
+++ b/hw/arm/xlnx-zynqmp.c
46
-/* We implement version 0.2 only */
49
@@ -XXX,XX +XXX,XX @@
47
-#define QEMU_PSCI_0_2_RET_VERSION_0_2 2
50
#define APU_ADDR 0xfd5c0000
48
+#define QEMU_PSCI_VERSION_0_1 0x00001
51
#define APU_IRQ 153
49
+#define QEMU_PSCI_VERSION_0_2 0x00002
52
50
+#define QEMU_PSCI_VERSION_1_1 0x10001
53
+#define TTC0_ADDR 0xFF110000
51
54
+#define TTC0_IRQ 36
52
MISMATCH_CHECK(QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED, PSCI_0_2_TOS_MP);
55
+
53
-MISMATCH_CHECK(QEMU_PSCI_0_2_RET_VERSION_0_2,
56
#define IPI_ADDR 0xFF300000
54
- (PSCI_VERSION_MAJOR(0) | PSCI_VERSION_MINOR(2)));
57
#define IPI_IRQ 64
55
+/* We don't bother to check every possible version value */
58
56
+MISMATCH_CHECK(QEMU_PSCI_VERSION_0_2, PSCI_VERSION(0, 2));
59
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_crf(XlnxZynqMPState *s, qemu_irq *gic)
57
+MISMATCH_CHECK(QEMU_PSCI_VERSION_1_1, PSCI_VERSION(1, 1));
60
sysbus_connect_irq(sbd, 0, gic[CRF_IRQ]);
58
59
/* PSCI return values (inclusive of all PSCI versions) */
60
#define QEMU_PSCI_RET_SUCCESS 0
61
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/boot.c
64
+++ b/hw/arm/boot.c
65
@@ -XXX,XX +XXX,XX @@ static void fdt_add_psci_node(void *fdt)
66
}
67
68
qemu_fdt_add_subnode(fdt, "/psci");
69
- if (armcpu->psci_version == 2) {
70
- const char comp[] = "arm,psci-0.2\0arm,psci";
71
- qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
72
+ if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2 ||
73
+ armcpu->psci_version == QEMU_PSCI_VERSION_1_1) {
74
+ if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2) {
75
+ const char comp[] = "arm,psci-0.2\0arm,psci";
76
+ qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
77
+ } else {
78
+ const char comp[] = "arm,psci-1.0\0arm,psci-0.2\0arm,psci";
79
+ qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
80
+ }
81
82
cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
83
if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) {
84
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/cpu.c
87
+++ b/target/arm/cpu.c
88
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_initfn(Object *obj)
89
* picky DTB consumer will also provide a helpful error message.
90
*/
91
cpu->dtb_compatible = "qemu,unknown";
92
- cpu->psci_version = 1; /* By default assume PSCI v0.1 */
93
+ cpu->psci_version = QEMU_PSCI_VERSION_0_1; /* By default assume PSCI v0.1 */
94
cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
95
96
if (tcg_enabled() || hvf_enabled()) {
97
- cpu->psci_version = 2; /* TCG and HVF implement PSCI 0.2 */
98
+ /* TCG and HVF implement PSCI 1.1 */
99
+ cpu->psci_version = QEMU_PSCI_VERSION_1_1;
100
}
61
}
101
}
62
102
63
+static void xlnx_zynqmp_create_ttc(XlnxZynqMPState *s, qemu_irq *gic)
103
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
64
+{
104
index XXXXXXX..XXXXXXX 100644
65
+ SysBusDevice *sbd;
105
--- a/target/arm/hvf/hvf.c
66
+ int i, irq;
106
+++ b/target/arm/hvf/hvf.c
67
+
107
@@ -XXX,XX +XXX,XX @@ static bool hvf_handle_psci_call(CPUState *cpu)
68
+ for (i = 0; i < XLNX_ZYNQMP_NUM_TTC; i++) {
108
69
+ object_initialize_child(OBJECT(s), "ttc[*]", &s->ttc[i],
109
switch (param[0]) {
70
+ TYPE_CADENCE_TTC);
110
case QEMU_PSCI_0_2_FN_PSCI_VERSION:
71
+ sbd = SYS_BUS_DEVICE(&s->ttc[i]);
111
- ret = QEMU_PSCI_0_2_RET_VERSION_0_2;
72
+
112
+ ret = QEMU_PSCI_VERSION_1_1;
73
+ sysbus_realize(sbd, &error_fatal);
113
break;
74
+ sysbus_mmio_map(sbd, 0, TTC0_ADDR + i * 0x10000);
114
case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
75
+ for (irq = 0; irq < 3; irq++) {
115
ret = QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED; /* No trusted OS */
76
+ sysbus_connect_irq(sbd, irq, gic[TTC0_IRQ + i * 3 + irq]);
116
@@ -XXX,XX +XXX,XX @@ static bool hvf_handle_psci_call(CPUState *cpu)
117
case QEMU_PSCI_0_2_FN_MIGRATE:
118
ret = QEMU_PSCI_RET_NOT_SUPPORTED;
119
break;
120
+ case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
121
+ switch (param[1]) {
122
+ case QEMU_PSCI_0_2_FN_PSCI_VERSION:
123
+ case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
124
+ case QEMU_PSCI_0_2_FN_AFFINITY_INFO:
125
+ case QEMU_PSCI_0_2_FN64_AFFINITY_INFO:
126
+ case QEMU_PSCI_0_2_FN_SYSTEM_RESET:
127
+ case QEMU_PSCI_0_2_FN_SYSTEM_OFF:
128
+ case QEMU_PSCI_0_1_FN_CPU_ON:
129
+ case QEMU_PSCI_0_2_FN_CPU_ON:
130
+ case QEMU_PSCI_0_2_FN64_CPU_ON:
131
+ case QEMU_PSCI_0_1_FN_CPU_OFF:
132
+ case QEMU_PSCI_0_2_FN_CPU_OFF:
133
+ case QEMU_PSCI_0_1_FN_CPU_SUSPEND:
134
+ case QEMU_PSCI_0_2_FN_CPU_SUSPEND:
135
+ case QEMU_PSCI_0_2_FN64_CPU_SUSPEND:
136
+ case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
137
+ ret = 0;
138
+ break;
139
+ case QEMU_PSCI_0_1_FN_MIGRATE:
140
+ case QEMU_PSCI_0_2_FN_MIGRATE:
141
+ default:
142
+ ret = QEMU_PSCI_RET_NOT_SUPPORTED;
77
+ }
143
+ }
78
+ }
144
+ break;
79
+}
145
default:
80
+
146
return false;
81
static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
147
}
148
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/target/arm/kvm64.c
151
+++ b/target/arm/kvm64.c
152
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
153
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;
154
}
155
if (kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {
156
- cpu->psci_version = 2;
157
+ cpu->psci_version = QEMU_PSCI_VERSION_0_2;
158
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PSCI_0_2;
159
}
160
if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
161
diff --git a/target/arm/psci.c b/target/arm/psci.c
162
index XXXXXXX..XXXXXXX 100644
163
--- a/target/arm/psci.c
164
+++ b/target/arm/psci.c
165
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
82
{
166
{
83
static const struct UnimpInfo {
167
/*
84
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
168
* This function partially implements the logic for dispatching Power State
85
xlnx_zynqmp_create_efuse(s, gic_spi);
169
- * Coordination Interface (PSCI) calls (as described in ARM DEN 0022B.b),
86
xlnx_zynqmp_create_apu_ctrl(s, gic_spi);
170
+ * Coordination Interface (PSCI) calls (as described in ARM DEN 0022D.b),
87
xlnx_zynqmp_create_crf(s, gic_spi);
171
* to the extent required for bringing up and taking down secondary cores,
88
+ xlnx_zynqmp_create_ttc(s, gic_spi);
172
* and for handling reset and poweroff requests.
89
xlnx_zynqmp_create_unimp_mmio(s);
173
* Additional information about the calling convention used is available in
90
174
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
91
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
175
}
176
177
if ((param[0] & QEMU_PSCI_0_2_64BIT) && !is_a64(env)) {
178
- ret = QEMU_PSCI_RET_INVALID_PARAMS;
179
+ ret = QEMU_PSCI_RET_NOT_SUPPORTED;
180
goto err;
181
}
182
183
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
184
ARMCPU *target_cpu;
185
186
case QEMU_PSCI_0_2_FN_PSCI_VERSION:
187
- ret = QEMU_PSCI_0_2_RET_VERSION_0_2;
188
+ ret = QEMU_PSCI_VERSION_1_1;
189
break;
190
case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
191
ret = QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED; /* No trusted OS */
192
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
193
}
194
helper_wfi(env, 4);
195
break;
196
+ case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
197
+ switch (param[1]) {
198
+ case QEMU_PSCI_0_2_FN_PSCI_VERSION:
199
+ case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
200
+ case QEMU_PSCI_0_2_FN_AFFINITY_INFO:
201
+ case QEMU_PSCI_0_2_FN64_AFFINITY_INFO:
202
+ case QEMU_PSCI_0_2_FN_SYSTEM_RESET:
203
+ case QEMU_PSCI_0_2_FN_SYSTEM_OFF:
204
+ case QEMU_PSCI_0_1_FN_CPU_ON:
205
+ case QEMU_PSCI_0_2_FN_CPU_ON:
206
+ case QEMU_PSCI_0_2_FN64_CPU_ON:
207
+ case QEMU_PSCI_0_1_FN_CPU_OFF:
208
+ case QEMU_PSCI_0_2_FN_CPU_OFF:
209
+ case QEMU_PSCI_0_1_FN_CPU_SUSPEND:
210
+ case QEMU_PSCI_0_2_FN_CPU_SUSPEND:
211
+ case QEMU_PSCI_0_2_FN64_CPU_SUSPEND:
212
+ case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
213
+ if (!(param[1] & QEMU_PSCI_0_2_64BIT) || is_a64(env)) {
214
+ ret = 0;
215
+ break;
216
+ }
217
+ /* fallthrough */
218
+ case QEMU_PSCI_0_1_FN_MIGRATE:
219
+ case QEMU_PSCI_0_2_FN_MIGRATE:
220
+ default:
221
+ ret = QEMU_PSCI_RET_NOT_SUPPORTED;
222
+ break;
223
+ }
224
+ break;
225
case QEMU_PSCI_0_1_FN_MIGRATE:
226
case QEMU_PSCI_0_2_FN_MIGRATE:
227
default:
92
--
228
--
93
2.25.1
229
2.25.1
diff view generated by jsdifflib
1
The Exynos4210 SoC device currently uses a custom device
1
From: Wentao_Liang <Wentao_Liang_g@163.com>
2
"exynos4210.irq_gate" to model the OR gate that feeds each CPU's IRQ
3
line. We have a standard TYPE_OR_IRQ device for this now, so use
4
that instead.
5
2
6
(This is a migration compatibility break, but that is OK for this
3
handle_simd_shift_fpint_conv() was accidentally freeing the TCG
7
machine type.)
4
temporary tcg_fpstatus too early, before the last use of it. Move
5
the free down to where it belongs.
8
6
7
Signed-off-by: Wentao_Liang <Wentao_Liang_g@163.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
[PMM: cleaned up commit message]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-2-peter.maydell@linaro.org
12
---
11
---
13
include/hw/arm/exynos4210.h | 1 +
12
target/arm/translate-a64.c | 2 +-
14
hw/arm/exynos4210.c | 31 ++++++++++++++++---------------
13
1 file changed, 1 insertion(+), 1 deletion(-)
15
2 files changed, 17 insertions(+), 15 deletions(-)
16
14
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
17
--- a/target/arm/translate-a64.c
20
+++ b/include/hw/arm/exynos4210.h
18
+++ b/target/arm/translate-a64.c
21
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
19
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
22
MemoryRegion bootreg_mem;
20
}
23
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
24
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
25
+ qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
26
};
27
28
#define TYPE_EXYNOS4210_SOC "exynos4210"
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
32
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
34
{
35
Exynos4210State *s = EXYNOS4210_SOC(socdev);
36
MemoryRegion *system_mem = get_system_memory();
37
- qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
38
SysBusDevice *busdev;
39
DeviceState *dev, *uart[4], *pl330[3];
40
int i, n;
41
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
42
43
/* IRQ Gate */
44
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
45
- dev = qdev_new("exynos4210.irq_gate");
46
- qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
47
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
48
- /* Get IRQ Gate input in gate_irq */
49
- for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
50
- gate_irq[i][n] = qdev_get_gpio_in(dev, n);
51
- }
52
- busdev = SYS_BUS_DEVICE(dev);
53
-
54
- /* Connect IRQ Gate output to CPU's IRQ line */
55
- sysbus_connect_irq(busdev, 0,
56
- qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
57
+ DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
58
+ object_property_set_int(OBJECT(orgate), "num-lines",
59
+ EXYNOS4210_IRQ_GATE_NINPUTS,
60
+ &error_abort);
61
+ qdev_realize(orgate, NULL, &error_abort);
62
+ qdev_connect_gpio_out(orgate, 0,
63
+ qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
64
}
21
}
65
22
66
/* Private memory region and Internal GIC */
23
- tcg_temp_free_ptr(tcg_fpstatus);
67
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
24
tcg_temp_free_i32(tcg_shift);
68
sysbus_realize_and_unref(busdev, &error_fatal);
25
gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
69
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
26
+ tcg_temp_free_ptr(tcg_fpstatus);
70
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
27
tcg_temp_free_i32(tcg_rmode);
71
- sysbus_connect_irq(busdev, n, gate_irq[n][0]);
72
+ sysbus_connect_irq(busdev, n,
73
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
74
}
75
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
76
s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
77
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
78
/* Map Distributer interface */
79
sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
80
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
81
- sysbus_connect_irq(busdev, n, gate_irq[n][1]);
82
+ sysbus_connect_irq(busdev, n,
83
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
84
}
85
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
86
s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
87
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
88
object_initialize_child(obj, name, orgate, TYPE_OR_IRQ);
89
g_free(name);
90
}
91
+
92
+ for (i = 0; i < ARRAY_SIZE(s->cpu_irq_orgate); i++) {
93
+ g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
94
+ object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
95
+ }
96
}
28
}
97
29
98
static void exynos4210_class_init(ObjectClass *klass, void *data)
99
--
30
--
100
2.25.1
31
2.25.1
diff view generated by jsdifflib
1
Switch the creation of the combiner devices to the new-style
1
From: Shengtan Mao <stmao@google.com>
2
"embedded in state struct" approach, so we can easily refer
3
to the object elsewhere during realize.
4
2
3
Reviewed-by: Hao Wu <wuhaotsh@google.com>
4
Reviewed-by: Chris Rauer <crauer@google.com>
5
Signed-off-by: Shengtan Mao <stmao@google.com>
6
Signed-off-by: Patrick Venture <venture@google.com>
7
Message-id: 20220225174451.192304-1-wuhaotsh@google.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220404154658.565020-18-peter.maydell@linaro.org
8
---
9
---
9
include/hw/arm/exynos4210.h | 3 ++
10
tests/qtest/npcm7xx_sdhci-test.c | 215 +++++++++++++++++++++++++++++++
10
include/hw/intc/exynos4210_combiner.h | 57 +++++++++++++++++++++++++++
11
tests/qtest/meson.build | 1 +
11
hw/arm/exynos4210.c | 20 +++++-----
12
2 files changed, 216 insertions(+)
12
hw/intc/exynos4210_combiner.c | 31 +--------------
13
create mode 100644 tests/qtest/npcm7xx_sdhci-test.c
13
4 files changed, 72 insertions(+), 39 deletions(-)
14
create mode 100644 include/hw/intc/exynos4210_combiner.h
15
14
16
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
15
diff --git a/tests/qtest/npcm7xx_sdhci-test.c b/tests/qtest/npcm7xx_sdhci-test.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/exynos4210.h
19
+++ b/include/hw/arm/exynos4210.h
20
@@ -XXX,XX +XXX,XX @@
21
#include "hw/sysbus.h"
22
#include "hw/cpu/a9mpcore.h"
23
#include "hw/intc/exynos4210_gic.h"
24
+#include "hw/intc/exynos4210_combiner.h"
25
#include "hw/core/split-irq.h"
26
#include "target/arm/cpu-qom.h"
27
#include "qom/object.h"
28
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
29
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
30
A9MPPrivState a9mpcore;
31
Exynos4210GicState ext_gic;
32
+ Exynos4210CombinerState int_combiner;
33
+ Exynos4210CombinerState ext_combiner;
34
SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
35
};
36
37
diff --git a/include/hw/intc/exynos4210_combiner.h b/include/hw/intc/exynos4210_combiner.h
38
new file mode 100644
16
new file mode 100644
39
index XXXXXXX..XXXXXXX
17
index XXXXXXX..XXXXXXX
40
--- /dev/null
18
--- /dev/null
41
+++ b/include/hw/intc/exynos4210_combiner.h
19
+++ b/tests/qtest/npcm7xx_sdhci-test.c
42
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
43
+/*
21
+/*
44
+ * Samsung exynos4210 Interrupt Combiner
22
+ * QTests for NPCM7xx SD-3.0 / MMC-4.51 Host Controller
45
+ *
23
+ *
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
24
+ * Copyright (c) 2022 Google LLC
47
+ * All rights reserved.
48
+ *
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
50
+ *
25
+ *
51
+ * This program is free software; you can redistribute it and/or modify it
26
+ * This program is free software; you can redistribute it and/or modify it
52
+ * under the terms of the GNU General Public License as published by the
27
+ * under the terms of the GNU General Public License as published by the
53
+ * Free Software Foundation; either version 2 of the License, or (at your
28
+ * Free Software Foundation; either version 2 of the License, or
54
+ * option) any later version.
29
+ * (at your option) any later version.
55
+ *
30
+ *
56
+ * This program is distributed in the hope that it will be useful,
31
+ * This program is distributed in the hope that it will be useful, but WITHOUT
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
33
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
59
+ * See the GNU General Public License for more details.
34
+ * for more details.
60
+ *
61
+ * You should have received a copy of the GNU General Public License along
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
63
+ */
35
+ */
64
+
36
+
65
+#ifndef HW_INTC_EXYNOS4210_COMBINER
37
+#include "qemu/osdep.h"
66
+#define HW_INTC_EXYNOS4210_COMBINER
38
+#include "hw/sd/npcm7xx_sdhci.h"
67
+
39
+
68
+#include "hw/sysbus.h"
40
+#include "libqos/libqtest.h"
69
+
41
+#include "libqtest-single.h"
70
+/*
42
+#include "libqos/sdhci-cmd.h"
71
+ * State for each output signal of internal combiner
43
+
72
+ */
44
+#define NPCM7XX_REG_SIZE 0x100
73
+typedef struct CombinerGroupState {
45
+#define NPCM7XX_MMC_BA 0xF0842000
74
+ uint8_t src_mask; /* 1 - source enabled, 0 - disabled */
46
+#define NPCM7XX_BLK_SIZE 512
75
+ uint8_t src_pending; /* Pending source interrupts before masking */
47
+#define NPCM7XX_TEST_IMAGE_SIZE (1 << 30)
76
+} CombinerGroupState;
48
+
77
+
49
+char *sd_path;
78
+#define TYPE_EXYNOS4210_COMBINER "exynos4210.combiner"
50
+
79
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210CombinerState, EXYNOS4210_COMBINER)
51
+static QTestState *setup_sd_card(void)
80
+
52
+{
81
+/* Number of groups and total number of interrupts for the internal combiner */
53
+ QTestState *qts = qtest_initf(
82
+#define IIC_NGRP 64
54
+ "-machine kudo-bmc "
83
+#define IIC_NIRQ (IIC_NGRP * 8)
55
+ "-device sd-card,drive=drive0 "
84
+#define IIC_REGSET_SIZE 0x41
56
+ "-drive id=drive0,if=none,file=%s,format=raw,auto-read-only=off",
85
+
57
+ sd_path);
86
+struct Exynos4210CombinerState {
58
+
87
+ SysBusDevice parent_obj;
59
+ qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_SWRST, SDHC_RESET_ALL);
88
+
60
+ qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_CLKCON,
89
+ MemoryRegion iomem;
61
+ SDHC_CLOCK_SDCLK_EN | SDHC_CLOCK_INT_STABLE |
90
+
62
+ SDHC_CLOCK_INT_EN);
91
+ struct CombinerGroupState group[IIC_NGRP];
63
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_APP_CMD);
92
+ uint32_t reg_set[IIC_REGSET_SIZE];
64
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x41200000, 0, (41 << 8));
93
+ uint32_t icipsr[2];
65
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_ALL_SEND_CID);
94
+ uint32_t external; /* 1 means that this combiner is external */
66
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_SEND_RELATIVE_ADDR);
95
+
67
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x45670000, 0,
96
+ qemu_irq output_irq[IIC_NGRP];
68
+ SDHC_SELECT_DESELECT_CARD);
97
+};
69
+
98
+
70
+ return qts;
99
+#endif
71
+}
100
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
72
+
73
+static void write_sdread(QTestState *qts, const char *msg)
74
+{
75
+ int fd, ret;
76
+ size_t len = strlen(msg);
77
+ char *rmsg = g_malloc(len);
78
+
79
+ /* write message to sd */
80
+ fd = open(sd_path, O_WRONLY);
81
+ g_assert(fd >= 0);
82
+ ret = write(fd, msg, len);
83
+ close(fd);
84
+ g_assert(ret == len);
85
+
86
+ /* read message using sdhci */
87
+ ret = sdhci_read_cmd(qts, NPCM7XX_MMC_BA, rmsg, len);
88
+ g_assert(ret == len);
89
+ g_assert(!memcmp(rmsg, msg, len));
90
+
91
+ g_free(rmsg);
92
+}
93
+
94
+/* Check MMC can read values from sd */
95
+static void test_read_sd(void)
96
+{
97
+ QTestState *qts = setup_sd_card();
98
+
99
+ write_sdread(qts, "hello world");
100
+ write_sdread(qts, "goodbye");
101
+
102
+ qtest_quit(qts);
103
+}
104
+
105
+static void sdwrite_read(QTestState *qts, const char *msg)
106
+{
107
+ int fd, ret;
108
+ size_t len = strlen(msg);
109
+ char *rmsg = g_malloc(len);
110
+
111
+ /* write message using sdhci */
112
+ sdhci_write_cmd(qts, NPCM7XX_MMC_BA, msg, len, NPCM7XX_BLK_SIZE);
113
+
114
+ /* read message from sd */
115
+ fd = open(sd_path, O_RDONLY);
116
+ g_assert(fd >= 0);
117
+ ret = read(fd, rmsg, len);
118
+ close(fd);
119
+ g_assert(ret == len);
120
+
121
+ g_assert(!memcmp(rmsg, msg, len));
122
+
123
+ g_free(rmsg);
124
+}
125
+
126
+/* Check MMC can write values to sd */
127
+static void test_write_sd(void)
128
+{
129
+ QTestState *qts = setup_sd_card();
130
+
131
+ sdwrite_read(qts, "hello world");
132
+ sdwrite_read(qts, "goodbye");
133
+
134
+ qtest_quit(qts);
135
+}
136
+
137
+/* Check SDHCI has correct default values. */
138
+static void test_reset(void)
139
+{
140
+ QTestState *qts = qtest_init("-machine kudo-bmc");
141
+ uint64_t addr = NPCM7XX_MMC_BA;
142
+ uint64_t end_addr = addr + NPCM7XX_REG_SIZE;
143
+ uint16_t prstvals_resets[] = {NPCM7XX_PRSTVALS_0_RESET,
144
+ NPCM7XX_PRSTVALS_1_RESET,
145
+ 0,
146
+ NPCM7XX_PRSTVALS_3_RESET,
147
+ 0,
148
+ 0};
149
+ int i;
150
+ uint32_t mask;
151
+
152
+ while (addr < end_addr) {
153
+ switch (addr - NPCM7XX_MMC_BA) {
154
+ case SDHC_PRNSTS:
155
+ /*
156
+ * ignores bits 20 to 24: they are changed when reading registers
157
+ */
158
+ mask = 0x1f00000;
159
+ g_assert_cmphex(qtest_readl(qts, addr) | mask, ==,
160
+ NPCM7XX_PRSNTS_RESET | mask);
161
+ addr += 4;
162
+ break;
163
+ case SDHC_BLKGAP:
164
+ g_assert_cmphex(qtest_readb(qts, addr), ==, NPCM7XX_BLKGAP_RESET);
165
+ addr += 1;
166
+ break;
167
+ case SDHC_CAPAB:
168
+ g_assert_cmphex(qtest_readq(qts, addr), ==, NPCM7XX_CAPAB_RESET);
169
+ addr += 8;
170
+ break;
171
+ case SDHC_MAXCURR:
172
+ g_assert_cmphex(qtest_readq(qts, addr), ==, NPCM7XX_MAXCURR_RESET);
173
+ addr += 8;
174
+ break;
175
+ case SDHC_HCVER:
176
+ g_assert_cmphex(qtest_readw(qts, addr), ==, NPCM7XX_HCVER_RESET);
177
+ addr += 2;
178
+ break;
179
+ case NPCM7XX_PRSTVALS:
180
+ for (i = 0; i < NPCM7XX_PRSTVALS_SIZE; ++i) {
181
+ g_assert_cmphex(qtest_readw(qts, addr + 2 * i), ==,
182
+ prstvals_resets[i]);
183
+ }
184
+ addr += NPCM7XX_PRSTVALS_SIZE * 2;
185
+ break;
186
+ default:
187
+ g_assert_cmphex(qtest_readb(qts, addr), ==, 0);
188
+ addr += 1;
189
+ }
190
+ }
191
+
192
+ qtest_quit(qts);
193
+}
194
+
195
+static void drive_destroy(void)
196
+{
197
+ unlink(sd_path);
198
+ g_free(sd_path);
199
+}
200
+
201
+static void drive_create(void)
202
+{
203
+ int fd, ret;
204
+ GError *error = NULL;
205
+
206
+ /* Create a temporary raw image */
207
+ fd = g_file_open_tmp("sdhci_XXXXXX", &sd_path, &error);
208
+ if (fd == -1) {
209
+ fprintf(stderr, "unable to create sdhci file: %s\n", error->message);
210
+ g_error_free(error);
211
+ }
212
+ g_assert(sd_path != NULL);
213
+
214
+ ret = ftruncate(fd, NPCM7XX_TEST_IMAGE_SIZE);
215
+ g_assert_cmpint(ret, ==, 0);
216
+ g_message("%s", sd_path);
217
+ close(fd);
218
+}
219
+
220
+int main(int argc, char **argv)
221
+{
222
+ int ret;
223
+
224
+ drive_create();
225
+
226
+ g_test_init(&argc, &argv, NULL);
227
+
228
+ qtest_add_func("npcm7xx_sdhci/reset", test_reset);
229
+ qtest_add_func("npcm7xx_sdhci/write_sd", test_write_sd);
230
+ qtest_add_func("npcm7xx_sdhci/read_sd", test_read_sd);
231
+
232
+ ret = g_test_run();
233
+ drive_destroy();
234
+ return ret;
235
+}
236
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
101
index XXXXXXX..XXXXXXX 100644
237
index XXXXXXX..XXXXXXX 100644
102
--- a/hw/arm/exynos4210.c
238
--- a/tests/qtest/meson.build
103
+++ b/hw/arm/exynos4210.c
239
+++ b/tests/qtest/meson.build
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
240
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
105
}
241
'npcm7xx_gpio-test',
106
242
'npcm7xx_pwm-test',
107
/* Internal Interrupt Combiner */
243
'npcm7xx_rng-test',
108
- dev = qdev_new("exynos4210.combiner");
244
+ 'npcm7xx_sdhci-test',
109
- busdev = SYS_BUS_DEVICE(dev);
245
'npcm7xx_smbus-test',
110
- sysbus_realize_and_unref(busdev, &error_fatal);
246
'npcm7xx_timer-test',
111
+ busdev = SYS_BUS_DEVICE(&s->int_combiner);
247
'npcm7xx_watchdog_timer-test'] + \
112
+ sysbus_realize(busdev, &error_fatal);
113
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
114
sysbus_connect_irq(busdev, n,
115
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
116
}
117
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
118
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
119
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
120
121
/* External Interrupt Combiner */
122
- dev = qdev_new("exynos4210.combiner");
123
- qdev_prop_set_uint32(dev, "external", 1);
124
- busdev = SYS_BUS_DEVICE(dev);
125
- sysbus_realize_and_unref(busdev, &error_fatal);
126
+ qdev_prop_set_uint32(DEVICE(&s->ext_combiner), "external", 1);
127
+ busdev = SYS_BUS_DEVICE(&s->ext_combiner);
128
+ sysbus_realize(busdev, &error_fatal);
129
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
130
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
131
}
132
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
133
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
134
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
135
136
/* Initialize board IRQs. */
137
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
138
139
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
140
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
141
+ object_initialize_child(obj, "int-combiner", &s->int_combiner,
142
+ TYPE_EXYNOS4210_COMBINER);
143
+ object_initialize_child(obj, "ext-combiner", &s->ext_combiner,
144
+ TYPE_EXYNOS4210_COMBINER);
145
}
146
147
static void exynos4210_class_init(ObjectClass *klass, void *data)
148
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/hw/intc/exynos4210_combiner.c
151
+++ b/hw/intc/exynos4210_combiner.c
152
@@ -XXX,XX +XXX,XX @@
153
#include "hw/sysbus.h"
154
#include "migration/vmstate.h"
155
#include "qemu/module.h"
156
-
157
+#include "hw/intc/exynos4210_combiner.h"
158
#include "hw/arm/exynos4210.h"
159
#include "hw/hw.h"
160
#include "hw/irq.h"
161
@@ -XXX,XX +XXX,XX @@
162
#define DPRINTF(fmt, ...) do {} while (0)
163
#endif
164
165
-#define IIC_NGRP 64 /* Internal Interrupt Combiner
166
- Groups number */
167
-#define IIC_NIRQ (IIC_NGRP * 8)/* Internal Interrupt Combiner
168
- Interrupts number */
169
#define IIC_REGION_SIZE 0x108 /* Size of memory mapped region */
170
-#define IIC_REGSET_SIZE 0x41
171
-
172
-/*
173
- * State for each output signal of internal combiner
174
- */
175
-typedef struct CombinerGroupState {
176
- uint8_t src_mask; /* 1 - source enabled, 0 - disabled */
177
- uint8_t src_pending; /* Pending source interrupts before masking */
178
-} CombinerGroupState;
179
-
180
-#define TYPE_EXYNOS4210_COMBINER "exynos4210.combiner"
181
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210CombinerState, EXYNOS4210_COMBINER)
182
-
183
-struct Exynos4210CombinerState {
184
- SysBusDevice parent_obj;
185
-
186
- MemoryRegion iomem;
187
-
188
- struct CombinerGroupState group[IIC_NGRP];
189
- uint32_t reg_set[IIC_REGSET_SIZE];
190
- uint32_t icipsr[2];
191
- uint32_t external; /* 1 means that this combiner is external */
192
-
193
- qemu_irq output_irq[IIC_NGRP];
194
-};
195
196
static const VMStateDescription vmstate_exynos4210_combiner_group_state = {
197
.name = "exynos4210.combiner.groupstate",
198
--
248
--
199
2.25.1
249
2.25.1
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Similar to the Aspeed code in include/misc/aspeed_scu.h, we define
3
Add new macros to manipulate signed fields within the register.
4
the PWRON STRAP fields in their corresponding module for NPCM7XX.
5
4
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Patrick Venture <venture@google.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220411165842.3912945-2-wuhaotsh@google.com
7
Message-id: 20220301215958.157011-2-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
include/hw/misc/npcm7xx_gcr.h | 30 ++++++++++++++++++++++++++++++
12
include/hw/registerfields.h | 48 ++++++++++++++++++++++++++++++++++++-
13
1 file changed, 30 insertions(+)
13
1 file changed, 47 insertions(+), 1 deletion(-)
14
14
15
diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h
15
diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/misc/npcm7xx_gcr.h
17
--- a/include/hw/registerfields.h
18
+++ b/include/hw/misc/npcm7xx_gcr.h
18
+++ b/include/hw/registerfields.h
19
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
20
#include "exec/memory.h"
20
extract64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
21
#include "hw/sysbus.h"
21
R_ ## reg ## _ ## field ## _LENGTH)
22
22
23
+/*
23
+#define FIELD_SEX8(storage, reg, field) \
24
+ * NPCM7XX PWRON STRAP bit fields
24
+ sextract8((storage), R_ ## reg ## _ ## field ## _SHIFT, \
25
+ * 12: SPI0 powered by VSBV3 at 1.8V
25
+ R_ ## reg ## _ ## field ## _LENGTH)
26
+ * 11: System flash attached to BMC
26
+#define FIELD_SEX16(storage, reg, field) \
27
+ * 10: BSP alternative pins.
27
+ sextract16((storage), R_ ## reg ## _ ## field ## _SHIFT, \
28
+ * 9:8: Flash UART command route enabled.
28
+ R_ ## reg ## _ ## field ## _LENGTH)
29
+ * 7: Security enabled.
29
+#define FIELD_SEX32(storage, reg, field) \
30
+ * 6: HI-Z state control.
30
+ sextract32((storage), R_ ## reg ## _ ## field ## _SHIFT, \
31
+ * 5: ECC disabled.
31
+ R_ ## reg ## _ ## field ## _LENGTH)
32
+ * 4: Reserved
32
+#define FIELD_SEX64(storage, reg, field) \
33
+ * 3: JTAG2 enabled.
33
+ sextract64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
34
+ * 2:0: CPU and DRAM clock frequency.
34
+ R_ ## reg ## _ ## field ## _LENGTH)
35
+ */
36
+#define NPCM7XX_PWRON_STRAP_SPI0F18 BIT(12)
37
+#define NPCM7XX_PWRON_STRAP_SFAB BIT(11)
38
+#define NPCM7XX_PWRON_STRAP_BSPA BIT(10)
39
+#define NPCM7XX_PWRON_STRAP_FUP(x) ((x) << 8)
40
+#define FUP_NORM_UART2 3
41
+#define FUP_PROG_UART3 2
42
+#define FUP_PROG_UART2 1
43
+#define FUP_NORM_UART3 0
44
+#define NPCM7XX_PWRON_STRAP_SECEN BIT(7)
45
+#define NPCM7XX_PWRON_STRAP_HIZ BIT(6)
46
+#define NPCM7XX_PWRON_STRAP_ECC BIT(5)
47
+#define NPCM7XX_PWRON_STRAP_RESERVE1 BIT(4)
48
+#define NPCM7XX_PWRON_STRAP_J2EN BIT(3)
49
+#define NPCM7XX_PWRON_STRAP_CKFRQ(x) (x)
50
+#define CKFRQ_SKIPINIT 0x000
51
+#define CKFRQ_DEFAULT 0x111
52
+
35
+
53
/*
36
/* Extract a field from an array of registers */
54
* Number of registers in our device state structure. Don't change this without
37
#define ARRAY_FIELD_EX32(regs, reg, field) \
55
* incrementing the version_id in the vmstate.
38
FIELD_EX32((regs)[R_ ## reg], reg, field)
39
@@ -XXX,XX +XXX,XX @@
40
_d; })
41
#define FIELD_DP64(storage, reg, field, val) ({ \
42
struct { \
43
- uint64_t v:R_ ## reg ## _ ## field ## _LENGTH; \
44
+ uint64_t v:R_ ## reg ## _ ## field ## _LENGTH; \
45
+ } _v = { .v = val }; \
46
+ uint64_t _d; \
47
+ _d = deposit64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
48
+ R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
49
+ _d; })
50
+
51
+#define FIELD_SDP8(storage, reg, field, val) ({ \
52
+ struct { \
53
+ signed int v:R_ ## reg ## _ ## field ## _LENGTH; \
54
+ } _v = { .v = val }; \
55
+ uint8_t _d; \
56
+ _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \
57
+ R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
58
+ _d; })
59
+#define FIELD_SDP16(storage, reg, field, val) ({ \
60
+ struct { \
61
+ signed int v:R_ ## reg ## _ ## field ## _LENGTH; \
62
+ } _v = { .v = val }; \
63
+ uint16_t _d; \
64
+ _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \
65
+ R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
66
+ _d; })
67
+#define FIELD_SDP32(storage, reg, field, val) ({ \
68
+ struct { \
69
+ signed int v:R_ ## reg ## _ ## field ## _LENGTH; \
70
+ } _v = { .v = val }; \
71
+ uint32_t _d; \
72
+ _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \
73
+ R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
74
+ _d; })
75
+#define FIELD_SDP64(storage, reg, field, val) ({ \
76
+ struct { \
77
+ int64_t v:R_ ## reg ## _ ## field ## _LENGTH; \
78
} _v = { .v = val }; \
79
uint64_t _d; \
80
_d = deposit64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
56
--
81
--
57
2.25.1
82
2.25.1
83
84
diff view generated by jsdifflib
1
From: Zongyuan Li <zongyuan.li@smartx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
3
Set this as the kernel would, to 48 bits, to keep the computation
4
of the address space correct for PAuth.
5
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-3-zongyuan.li@smartx.com
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220301215958.157011-3-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
hw/arm/stellaris.c | 15 +++++++++++++--
11
target/arm/cpu.c | 3 ++-
9
1 file changed, 13 insertions(+), 2 deletions(-)
12
1 file changed, 2 insertions(+), 1 deletion(-)
10
13
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/stellaris.c
16
--- a/target/arm/cpu.c
14
+++ b/hw/arm/stellaris.c
17
+++ b/target/arm/cpu.c
15
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
16
19
aarch64_sve_zcr_get_valid_len(cpu, cpu->sve_default_vq - 1);
17
#include "qemu/osdep.h"
20
}
18
#include "qapi/error.h"
21
/*
19
+#include "hw/core/split-irq.h"
22
+ * Enable 48-bit address space (TODO: take reserved_va into account).
20
#include "hw/sysbus.h"
23
* Enable TBI0 but not TBI1.
21
#include "hw/sd/sd.h"
24
* Note that this must match useronly_clean_ptr.
22
#include "hw/ssi/ssi.h"
25
*/
23
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
26
- env->cp15.tcr_el[1].raw_tcr = (1ULL << 37);
24
DeviceState *ssddev;
27
+ env->cp15.tcr_el[1].raw_tcr = 5 | (1ULL << 37);
25
DriveInfo *dinfo;
28
26
DeviceState *carddev;
29
/* Enable MTE */
27
+ DeviceState *gpio_d_splitter;
30
if (cpu_isar_feature(aa64_mte, cpu)) {
28
BlockBackend *blk;
29
30
/*
31
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
32
&error_fatal);
33
34
ssddev = ssi_create_peripheral(bus, "ssd0323");
35
- gpio_out[GPIO_D][0] = qemu_irq_split(
36
- qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0),
37
+
38
+ gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
39
+ qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
40
+ qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
41
+ qdev_connect_gpio_out(
42
+ gpio_d_splitter, 0,
43
+ qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0));
44
+ qdev_connect_gpio_out(
45
+ gpio_d_splitter, 1,
46
qdev_get_gpio_in_named(ssddev, SSI_GPIO_CS, 0));
47
+ gpio_out[GPIO_D][0] = qdev_get_gpio_in(gpio_d_splitter, 0);
48
+
49
gpio_out[GPIO_C][7] = qdev_get_gpio_in(ssddev, 0);
50
51
/* Make sure the select pin is high. */
52
--
31
--
53
2.25.1
32
2.25.1
diff view generated by jsdifflib
1
From: Zongyuan Li <zongyuan.li@smartx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
3
Without FEAT_LVA, the behaviour of programming an invalid value
4
is IMPLEMENTATION DEFINED. With FEAT_LVA, programming an invalid
5
minimum value requires a Translation fault.
6
7
It is most self-consistent to choose to generate the fault always.
8
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-5-zongyuan.li@smartx.com
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/811
11
Message-id: 20220301215958.157011-4-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
13
---
9
include/hw/irq.h | 5 -----
14
target/arm/internals.h | 1 +
10
hw/core/irq.c | 15 ---------------
15
target/arm/helper.c | 32 ++++++++++++++++++++++++++++----
11
2 files changed, 20 deletions(-)
16
2 files changed, 29 insertions(+), 4 deletions(-)
12
17
13
diff --git a/include/hw/irq.h b/include/hw/irq.h
18
diff --git a/target/arm/internals.h b/target/arm/internals.h
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/irq.h
20
--- a/target/arm/internals.h
16
+++ b/include/hw/irq.h
21
+++ b/target/arm/internals.h
17
@@ -XXX,XX +XXX,XX @@ void qemu_free_irq(qemu_irq irq);
22
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
18
/* Returns a new IRQ with opposite polarity. */
23
bool hpd : 1;
19
qemu_irq qemu_irq_invert(qemu_irq irq);
24
bool using16k : 1;
20
25
bool using64k : 1;
21
-/* Returns a new IRQ which feeds into both the passed IRQs.
26
+ bool tsz_oob : 1; /* tsz has been clamped to legal range */
22
- * It's probably better to use the TYPE_SPLIT_IRQ device instead.
27
} ARMVAParameters;
23
- */
28
24
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
29
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
25
-
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
26
/* For internal use in qtest. Similar to qemu_irq_split, but operating
27
on an existing vector of qemu_irq. */
28
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
29
diff --git a/hw/core/irq.c b/hw/core/irq.c
30
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/core/irq.c
32
--- a/target/arm/helper.c
32
+++ b/hw/core/irq.c
33
+++ b/target/arm/helper.c
33
@@ -XXX,XX +XXX,XX @@ qemu_irq qemu_irq_invert(qemu_irq irq)
34
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
34
return qemu_allocate_irq(qemu_notirq, irq, 0);
35
ARMMMUIdx mmu_idx, bool data)
36
{
37
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
38
- bool epd, hpd, using16k, using64k;
39
- int select, tsz, tbi, max_tsz;
40
+ bool epd, hpd, using16k, using64k, tsz_oob;
41
+ int select, tsz, tbi, max_tsz, min_tsz;
42
43
if (!regime_has_2_ranges(mmu_idx)) {
44
select = 0;
45
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
46
} else {
47
max_tsz = 39;
48
}
49
+ min_tsz = 16; /* TODO: ARMv8.2-LVA */
50
51
- tsz = MIN(tsz, max_tsz);
52
- tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */
53
+ if (tsz > max_tsz) {
54
+ tsz = max_tsz;
55
+ tsz_oob = true;
56
+ } else if (tsz < min_tsz) {
57
+ tsz = min_tsz;
58
+ tsz_oob = true;
59
+ } else {
60
+ tsz_oob = false;
61
+ }
62
63
/* Present TBI as a composite with TBID. */
64
tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
65
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
66
.hpd = hpd,
67
.using16k = using16k,
68
.using64k = using64k,
69
+ .tsz_oob = tsz_oob,
70
};
35
}
71
}
36
72
37
-static void qemu_splitirq(void *opaque, int line, int level)
73
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
38
-{
74
param = aa64_va_parameters(env, address, mmu_idx,
39
- struct IRQState **irq = opaque;
75
access_type != MMU_INST_FETCH);
40
- irq[0]->handler(irq[0]->opaque, irq[0]->n, level);
76
level = 0;
41
- irq[1]->handler(irq[1]->opaque, irq[1]->n, level);
77
+
42
-}
78
+ /*
43
-
79
+ * If TxSZ is programmed to a value larger than the maximum,
44
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2)
80
+ * or smaller than the effective minimum, it is IMPLEMENTATION
45
-{
81
+ * DEFINED whether we behave as if the field were programmed
46
- qemu_irq *s = g_new0(qemu_irq, 2);
82
+ * within bounds, or if a level 0 Translation fault is generated.
47
- s[0] = irq1;
83
+ *
48
- s[1] = irq2;
84
+ * With FEAT_LVA, fault on less than minimum becomes required,
49
- return qemu_allocate_irq(qemu_splitirq, s, 0);
85
+ * so our choice is to always raise the fault.
50
-}
86
+ */
51
-
87
+ if (param.tsz_oob) {
52
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
88
+ fault_type = ARMFault_Translation;
53
{
89
+ goto do_fault;
54
int i;
90
+ }
91
+
92
addrsize = 64 - 8 * param.tbi;
93
inputsize = 64 - param.tsz;
94
} else {
55
--
95
--
56
2.25.1
96
2.25.1
diff view generated by jsdifflib
1
The function exynos4210_combiner_get_gpioin() currently lives in
1
From: Richard Henderson <richard.henderson@linaro.org>
2
exynos4210_combiner.c, but it isn't really part of the combiner
3
device itself -- it is a function that implements the wiring up of
4
some interrupt sources to multiple combiner inputs. Move it to live
5
with the other SoC-level code in exynos4210.c, along with a few
6
macros previously defined in exynos4210.h which are now used only
7
in exynos4210.c.
8
2
3
We will shortly share parts of this function with other portions
4
of address translation.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220301215958.157011-5-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-11-peter.maydell@linaro.org
12
---
12
---
13
include/hw/arm/exynos4210.h | 11 -----
13
target/arm/internals.h | 19 +------------------
14
hw/arm/exynos4210.c | 82 +++++++++++++++++++++++++++++++++++
14
target/arm/helper.c | 22 ++++++++++++++++++++++
15
hw/intc/exynos4210_combiner.c | 77 --------------------------------
15
2 files changed, 23 insertions(+), 18 deletions(-)
16
3 files changed, 82 insertions(+), 88 deletions(-)
17
16
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
17
diff --git a/target/arm/internals.h b/target/arm/internals.h
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/exynos4210.h
19
--- a/target/arm/internals.h
21
+++ b/include/hw/arm/exynos4210.h
20
+++ b/target/arm/internals.h
22
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static inline void update_spsel(CPUARMState *env, uint32_t imm)
23
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
22
* Returns the implementation defined bit-width of physical addresses.
24
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
23
* The ARMv8 reference manuals refer to this as PAMax().
25
24
*/
26
-#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp)*8 + (bit))
25
-static inline unsigned int arm_pamax(ARMCPU *cpu)
27
-#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
26
-{
28
-#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
27
- static const unsigned int pamax_map[] = {
29
- ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
28
- [0] = 32,
29
- [1] = 36,
30
- [2] = 40,
31
- [3] = 42,
32
- [4] = 44,
33
- [5] = 48,
34
- };
35
- unsigned int parange =
36
- FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
30
-
37
-
31
/* IRQs number for external and internal GIC */
38
- /* id_aa64mmfr0 is a read-only register so values outside of the
32
#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
39
- * supported mappings can be considered an implementation error. */
33
#define EXYNOS4210_INT_GIC_NIRQ 64
40
- assert(parange < ARRAY_SIZE(pamax_map));
34
@@ -XXX,XX +XXX,XX @@ void exynos4210_write_secondary(ARMCPU *cpu,
41
- return pamax_map[parange];
35
* bit - bit number inside group */
42
-}
36
uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit);
43
+unsigned int arm_pamax(ARMCPU *cpu);
37
44
38
-/*
45
/* Return true if extended addresses are enabled.
39
- * Get Combiner input GPIO into irqs structure
46
* This is always the case if our translation regime is 64 bit,
40
- */
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
41
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
42
- int ext);
43
-
44
/*
45
* exynos4210 UART
46
*/
47
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
48
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/exynos4210.c
49
--- a/target/arm/helper.c
50
+++ b/hw/arm/exynos4210.c
50
+++ b/target/arm/helper.c
51
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
51
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
52
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
53
};
54
55
+#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp) * 8 + (bit))
56
+#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
57
+#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
58
+ ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
59
+
60
/*
61
* Initialize board IRQs.
62
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
63
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
64
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
65
}
52
}
66
53
#endif /* !CONFIG_USER_ONLY */
67
+/*
54
68
+ * Get Combiner input GPIO into irqs structure
55
+/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
69
+ */
56
+unsigned int arm_pamax(ARMCPU *cpu)
70
+static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
71
+ DeviceState *dev, int ext)
72
+{
57
+{
73
+ int n;
58
+ static const unsigned int pamax_map[] = {
74
+ int bit;
59
+ [0] = 32,
75
+ int max;
60
+ [1] = 36,
76
+ qemu_irq *irq;
61
+ [2] = 40,
77
+
62
+ [3] = 42,
78
+ max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
63
+ [4] = 44,
79
+ EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
64
+ [5] = 48,
80
+ irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
65
+ };
66
+ unsigned int parange =
67
+ FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
81
+
68
+
82
+ /*
69
+ /*
83
+ * Some IRQs of Int/External Combiner are going to two Combiners groups,
70
+ * id_aa64mmfr0 is a read-only register so values outside of the
84
+ * so let split them.
71
+ * supported mappings can be considered an implementation error.
85
+ */
72
+ */
86
+ for (n = 0; n < max; n++) {
73
+ assert(parange < ARRAY_SIZE(pamax_map));
87
+
74
+ return pamax_map[parange];
88
+ bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
89
+
90
+ switch (n) {
91
+ /* MDNIE_LCD1 INTG1 */
92
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
93
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
94
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
95
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
96
+ continue;
97
+
98
+ /* TMU INTG3 */
99
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
100
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
101
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
102
+ continue;
103
+
104
+ /* LCD1 INTG12 */
105
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
106
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
107
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
108
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
109
+ continue;
110
+
111
+ /* Multi-Core Timer INTG12 */
112
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
113
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
114
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
115
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
116
+ continue;
117
+
118
+ /* Multi-Core Timer INTG35 */
119
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
120
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
121
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
122
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
123
+ continue;
124
+
125
+ /* Multi-Core Timer INTG51 */
126
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
127
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
128
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
129
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
130
+ continue;
131
+
132
+ /* Multi-Core Timer INTG53 */
133
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
134
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
135
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
136
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
137
+ continue;
138
+ }
139
+
140
+ irq[n] = qdev_get_gpio_in(dev, n);
141
+ }
142
+}
75
+}
143
+
76
+
144
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
77
static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
145
0x09, 0x00, 0x00, 0x00 };
146
147
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
148
index XXXXXXX..XXXXXXX 100644
149
--- a/hw/intc/exynos4210_combiner.c
150
+++ b/hw/intc/exynos4210_combiner.c
151
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_exynos4210_combiner = {
152
}
153
};
154
155
-/*
156
- * Get Combiner input GPIO into irqs structure
157
- */
158
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
159
- int ext)
160
-{
161
- int n;
162
- int bit;
163
- int max;
164
- qemu_irq *irq;
165
-
166
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
167
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
168
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
169
-
170
- /*
171
- * Some IRQs of Int/External Combiner are going to two Combiners groups,
172
- * so let split them.
173
- */
174
- for (n = 0; n < max; n++) {
175
-
176
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
177
-
178
- switch (n) {
179
- /* MDNIE_LCD1 INTG1 */
180
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
181
- EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
182
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
183
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
184
- continue;
185
-
186
- /* TMU INTG3 */
187
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
188
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
189
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
190
- continue;
191
-
192
- /* LCD1 INTG12 */
193
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
194
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
195
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
196
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
197
- continue;
198
-
199
- /* Multi-Core Timer INTG12 */
200
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
201
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
202
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
203
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
204
- continue;
205
-
206
- /* Multi-Core Timer INTG35 */
207
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
208
- EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
209
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
210
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
211
- continue;
212
-
213
- /* Multi-Core Timer INTG51 */
214
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
215
- EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
216
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
217
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
218
- continue;
219
-
220
- /* Multi-Core Timer INTG53 */
221
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
222
- EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
223
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
224
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
225
- continue;
226
- }
227
-
228
- irq[n] = qdev_get_gpio_in(dev, n);
229
- }
230
-}
231
-
232
static uint64_t
233
exynos4210_combiner_read(void *opaque, hwaddr offset, unsigned size)
234
{
78
{
79
if (regime_has_2_ranges(mmu_idx)) {
235
--
80
--
236
2.25.1
81
2.25.1
82
83
diff view generated by jsdifflib
1
At this point, the function exynos4210_init_board_irqs() splits input
1
From: Richard Henderson <richard.henderson@linaro.org>
2
IRQ lines to connect them to the input combiner, output combiner and
3
external GIC. The function exynos4210_combiner_get_gpioin() splits
4
some of the combiner input lines further to connect them to multiple
5
different inputs on the combiner.
6
2
7
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
3
Pass down the width of the output address from translation.
8
configurable number of outputs, we can do all this in one place, by
4
For now this is still just PAMax, but a subsequent patch will
9
making exynos4210_init_board_irqs() add extra outputs to the splitter
5
compute the correct value from TCR_ELx.{I}PS.
10
device when it must be connected to more than one input on each
11
combiner.
12
6
13
We do this with a new data structure, the combinermap, which is an
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
array each of whose elements is a list of the interrupt IDs on the
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
combiner which must be tied together. As we loop through each
9
Message-id: 20220301215958.157011-6-richard.henderson@linaro.org
16
interrupt ID, if we find that it is the first one in one of these
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
lists, we configure the splitter device with eonugh extra outputs and
11
---
18
wire them up to the other interrupt IDs in the list.
12
target/arm/helper.c | 21 ++++++++++-----------
13
1 file changed, 10 insertions(+), 11 deletions(-)
19
14
20
Conveniently, for all the cases where this is necessary, the
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
lowest-numbered interrupt ID in each group is in the range of the
22
external combiner, so we only need to code for this in the first of
23
the two loops in exynos4210_init_board_irqs().
24
25
The old code in exynos4210_combiner_get_gpioin() which is being
26
deleted here had several problems which don't exist in the new code
27
in its handling of the multi-core timer interrupts:
28
(1) the case labels specified bits 4 ... 8, but bit '8' doesn't
29
exist; these should have been 4 ... 7
30
(2) it used the input irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]
31
multiple times as the input of several different splitters,
32
which isn't allowed
33
(3) in an apparent cut-and-paste error, the cases for all the
34
multi-core timer inputs used "bit + 4" even though the
35
bit range for the case was (intended to be) 4 ... 7, which
36
meant it was looking at non-existent bits 8 ... 11.
37
None of these exist in the new code.
38
39
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
40
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
41
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
42
---
43
include/hw/arm/exynos4210.h | 6 +-
44
hw/arm/exynos4210.c | 178 +++++++++++++++++++++++-------------
45
2 files changed, 119 insertions(+), 65 deletions(-)
46
47
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
48
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
49
--- a/include/hw/arm/exynos4210.h
17
--- a/target/arm/helper.c
50
+++ b/include/hw/arm/exynos4210.h
18
+++ b/target/arm/helper.c
51
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ do_fault:
52
20
* false otherwise.
53
/*
54
* We need one splitter for every external combiner input, plus
55
- * one for every non-zero entry in combiner_grp_to_gic_id[].
56
+ * one for every non-zero entry in combiner_grp_to_gic_id[],
57
+ * minus one for every external combiner ID in second or later
58
+ * places in a combinermap[] line.
59
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
60
*/
21
*/
61
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
22
static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
62
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
23
- int inputsize, int stride)
63
24
+ int inputsize, int stride, int outputsize)
64
typedef struct Exynos4210Irq {
25
{
65
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
26
const int grainsize = stride + 3;
66
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
27
int startsizecheck;
67
index XXXXXXX..XXXXXXX 100644
28
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
68
--- a/hw/arm/exynos4210.c
29
}
69
+++ b/hw/arm/exynos4210.c
30
70
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
31
if (is_aa64) {
71
#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
32
- CPUARMState *env = &cpu->env;
72
((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
33
- unsigned int pamax = arm_pamax(cpu);
73
34
-
74
+/*
35
switch (stride) {
75
+ * Some interrupt lines go to multiple combiner inputs.
36
case 13: /* 64KB Pages. */
76
+ * This data structure defines those: each array element is
37
- if (level == 0 || (level == 1 && pamax <= 42)) {
77
+ * a list of combiner inputs which are connected together;
38
+ if (level == 0 || (level == 1 && outputsize <= 42)) {
78
+ * the one with the smallest interrupt ID value must be first.
39
return false;
79
+ * As with combiner_grp_to_gic_id[], we rely on (0, 0) not being
40
}
80
+ * wired to anything so we can use 0 as a terminator.
41
break;
81
+ */
42
case 11: /* 16KB Pages. */
82
+#define IRQNO(G, B) EXYNOS4210_COMBINER_GET_IRQ_NUM(G, B)
43
- if (level == 0 || (level == 1 && pamax <= 40)) {
83
+#define IRQNONE 0
44
+ if (level == 0 || (level == 1 && outputsize <= 40)) {
84
+
45
return false;
85
+#define COMBINERMAP_SIZE 16
46
}
86
+
47
break;
87
+static const int combinermap[COMBINERMAP_SIZE][6] = {
48
case 9: /* 4KB Pages. */
88
+ /* MDNIE_LCD1 */
49
- if (level == 0 && pamax <= 42) {
89
+ { IRQNO(0, 4), IRQNO(1, 0), IRQNONE },
50
+ if (level == 0 && outputsize <= 42) {
90
+ { IRQNO(0, 5), IRQNO(1, 1), IRQNONE },
51
return false;
91
+ { IRQNO(0, 6), IRQNO(1, 2), IRQNONE },
52
}
92
+ { IRQNO(0, 7), IRQNO(1, 3), IRQNONE },
53
break;
93
+ /* TMU */
54
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
94
+ { IRQNO(2, 4), IRQNO(3, 4), IRQNONE },
95
+ { IRQNO(2, 5), IRQNO(3, 5), IRQNONE },
96
+ { IRQNO(2, 6), IRQNO(3, 6), IRQNONE },
97
+ { IRQNO(2, 7), IRQNO(3, 7), IRQNONE },
98
+ /* LCD1 */
99
+ { IRQNO(11, 4), IRQNO(12, 0), IRQNONE },
100
+ { IRQNO(11, 5), IRQNO(12, 1), IRQNONE },
101
+ { IRQNO(11, 6), IRQNO(12, 2), IRQNONE },
102
+ { IRQNO(11, 7), IRQNO(12, 3), IRQNONE },
103
+ /* Multi-core timer */
104
+ { IRQNO(1, 4), IRQNO(12, 4), IRQNO(35, 4), IRQNO(51, 4), IRQNO(53, 4), IRQNONE },
105
+ { IRQNO(1, 5), IRQNO(12, 5), IRQNO(35, 5), IRQNO(51, 5), IRQNO(53, 5), IRQNONE },
106
+ { IRQNO(1, 6), IRQNO(12, 6), IRQNO(35, 6), IRQNO(51, 6), IRQNO(53, 6), IRQNONE },
107
+ { IRQNO(1, 7), IRQNO(12, 7), IRQNO(35, 7), IRQNO(51, 7), IRQNO(53, 7), IRQNONE },
108
+};
109
+
110
+#undef IRQNO
111
+
112
+static const int *combinermap_entry(int irq)
113
+{
114
+ /*
115
+ * If the interrupt number passed in is the first entry in some
116
+ * line of the combinermap, return a pointer to that line;
117
+ * otherwise return NULL.
118
+ */
119
+ int i;
120
+ for (i = 0; i < COMBINERMAP_SIZE; i++) {
121
+ if (combinermap[i][0] == irq) {
122
+ return combinermap[i];
123
+ }
124
+ }
125
+ return NULL;
126
+}
127
+
128
+static int mapline_size(const int *mapline)
129
+{
130
+ /* Return number of entries in this mapline in total */
131
+ int i = 0;
132
+
133
+ if (!mapline) {
134
+ /* Not in the map? IRQ goes to exactly one combiner input */
135
+ return 1;
136
+ }
137
+ while (*mapline != IRQNONE) {
138
+ mapline++;
139
+ i++;
140
+ }
141
+ return i;
142
+}
143
+
144
/*
145
* Initialize board IRQs.
146
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
147
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
148
DeviceState *extgicdev = DEVICE(&s->ext_gic);
149
int splitcount = 0;
150
DeviceState *splitter;
151
+ const int *mapline;
152
+ int numlines, splitin, in;
153
154
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
155
irq_id = 0;
156
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
157
irq_id = EXT_GIC_ID_MCT_G1;
158
}
55
}
159
56
160
+ if (s->irq_table[n]) {
57
/* Inputsize checks. */
161
+ /*
58
- if (inputsize > pamax &&
162
+ * This must be some non-first entry in a combinermap line,
59
- (arm_el_is_aa64(env, 1) || inputsize > 40)) {
163
+ * and we've already filled it in.
60
+ if (inputsize > outputsize &&
164
+ */
61
+ (arm_el_is_aa64(&cpu->env, 1) || inputsize > 40)) {
165
+ continue;
62
/* This is CONSTRAINED UNPREDICTABLE and we choose to fault. */
166
+ }
63
return false;
167
+ mapline = combinermap_entry(n);
168
+ /*
169
+ * We need to connect the IRQ to multiple inputs on both combiners
170
+ * and possibly also to the external GIC.
171
+ */
172
+ numlines = 2 * mapline_size(mapline);
173
+ if (irq_id) {
174
+ numlines++;
175
+ }
176
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
177
splitter = DEVICE(&s->splitter[splitcount]);
178
- qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
179
+ qdev_prop_set_uint16(splitter, "num-lines", numlines);
180
qdev_realize(splitter, NULL, &error_abort);
181
splitcount++;
182
- s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
183
- qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
184
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
185
+
186
+ in = n;
187
+ splitin = 0;
188
+ for (;;) {
189
+ s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
190
+ qdev_connect_gpio_out(splitter, splitin, is->int_combiner_irq[in]);
191
+ qdev_connect_gpio_out(splitter, splitin + 1, is->ext_combiner_irq[in]);
192
+ splitin += 2;
193
+ if (!mapline) {
194
+ break;
195
+ }
196
+ mapline++;
197
+ in = *mapline;
198
+ if (in == IRQNONE) {
199
+ break;
200
+ }
201
+ }
202
if (irq_id) {
203
- qdev_connect_gpio_out(splitter, 2,
204
+ qdev_connect_gpio_out(splitter, splitin,
205
qdev_get_gpio_in(extgicdev, irq_id - 32));
206
}
64
}
65
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
66
target_ulong page_size;
67
uint32_t attrs;
68
int32_t stride;
69
- int addrsize, inputsize;
70
+ int addrsize, inputsize, outputsize;
71
TCR *tcr = regime_tcr(env, mmu_idx);
72
int ap, ns, xn, pxn;
73
uint32_t el = regime_el(env, mmu_idx);
74
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
75
76
addrsize = 64 - 8 * param.tbi;
77
inputsize = 64 - param.tsz;
78
+ outputsize = arm_pamax(cpu);
79
} else {
80
param = aa32_va_parameters(env, address, mmu_idx);
81
level = 1;
82
addrsize = (mmu_idx == ARMMMUIdx_Stage2 ? 40 : 32);
83
inputsize = addrsize - param.tsz;
84
+ outputsize = 40;
207
}
85
}
208
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
86
209
irq_id = combiner_grp_to_gic_id[grp -
87
/*
210
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
88
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
211
89
212
+ if (s->irq_table[n]) {
90
/* Check that the starting level is valid. */
213
+ /*
91
ok = check_s2_mmu_setup(cpu, aarch64, startlevel,
214
+ * This must be some non-first entry in a combinermap line,
92
- inputsize, stride);
215
+ * and we've already filled it in.
93
+ inputsize, stride, outputsize);
216
+ */
94
if (!ok) {
217
+ continue;
95
fault_type = ARMFault_Translation;
218
+ }
96
goto do_fault;
219
+
220
if (irq_id) {
221
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
222
splitter = DEVICE(&s->splitter[splitcount]);
223
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
224
DeviceState *dev, int ext)
225
{
226
int n;
227
- int bit;
228
int max;
229
qemu_irq *irq;
230
231
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
232
EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
233
irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
234
235
- /*
236
- * Some IRQs of Int/External Combiner are going to two Combiners groups,
237
- * so let split them.
238
- */
239
for (n = 0; n < max; n++) {
240
-
241
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
242
-
243
- switch (n) {
244
- /* MDNIE_LCD1 INTG1 */
245
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
246
- EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
247
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
248
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
249
- continue;
250
-
251
- /* TMU INTG3 */
252
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
253
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
254
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
255
- continue;
256
-
257
- /* LCD1 INTG12 */
258
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
259
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
260
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
261
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
262
- continue;
263
-
264
- /* Multi-Core Timer INTG12 */
265
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
266
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
267
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
268
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
269
- continue;
270
-
271
- /* Multi-Core Timer INTG35 */
272
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
273
- EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
274
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
275
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
276
- continue;
277
-
278
- /* Multi-Core Timer INTG51 */
279
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
280
- EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
281
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
282
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
283
- continue;
284
-
285
- /* Multi-Core Timer INTG53 */
286
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
287
- EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
288
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
289
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
290
- continue;
291
- }
292
-
293
irq[n] = qdev_get_gpio_in(dev, n);
294
}
295
}
296
--
97
--
297
2.25.1
98
2.25.1
diff view generated by jsdifflib
1
From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Describe that the gic-version influences the maximum number of CPUs.
3
The macro is a bit more readable than the inlined computation.
4
4
5
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20220413231456.35811-1-heinrich.schuchardt@canonical.com
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
[PMM: minor punctuation tweaks]
7
Message-id: 20220301215958.157011-7-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
docs/system/arm/virt.rst | 4 ++--
10
target/arm/helper.c | 4 ++--
12
1 file changed, 2 insertions(+), 2 deletions(-)
11
1 file changed, 2 insertions(+), 2 deletions(-)
13
12
14
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/virt.rst
15
--- a/target/arm/helper.c
17
+++ b/docs/system/arm/virt.rst
16
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ gic-version
17
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
19
Valid values are:
18
level = startlevel;
20
19
}
21
``2``
20
22
- GICv2
21
- indexmask_grainsize = (1ULL << (stride + 3)) - 1;
23
+ GICv2. Note that this limits the number of CPUs to 8.
22
- indexmask = (1ULL << (inputsize - (stride * (4 - level)))) - 1;
24
``3``
23
+ indexmask_grainsize = MAKE_64BIT_MASK(0, stride + 3);
25
- GICv3
24
+ indexmask = MAKE_64BIT_MASK(0, inputsize - (stride * (4 - level)));
26
+ GICv3. This allows up to 512 CPUs.
25
27
``host``
26
/* Now we can extract the actual base address from the TTBR */
28
Use the same GIC version the host provides, when using KVM
27
descaddr = extract64(ttbr, 0, 48);
29
``max``
30
--
28
--
31
2.25.1
29
2.25.1
30
31
diff view generated by jsdifflib
1
It's not possible to provide the guest with the Security extensions
1
From: Richard Henderson <richard.henderson@linaro.org>
2
(TrustZone) when using KVM or HVF, because the hardware
3
virtualization extensions don't permit running EL3 guest code.
4
However, we weren't checking for this combination, with the result
5
that QEMU would assert if you tried it:
6
2
7
$ qemu-system-aarch64 -enable-kvm -machine virt,secure=on -cpu host -display none
3
This field controls the output (intermediate) physical address size
8
Unexpected error in object_property_find_err() at ../../qom/object.c:1304:
4
of the translation process. V8 requires to raise an AddressSize
9
qemu-system-aarch64: Property 'host-arm-cpu.secure-memory' not found
5
fault if the page tables are programmed incorrectly, such that any
10
Aborted
6
intermediate descriptor address, or the final translated address,
7
is out of range.
11
8
12
Check for this combination of options and report an error, in the
9
Add a PS field to ARMVAParameters, and properly compute outputsize
13
same way we already do for attempts to give a KVM or HVF guest the
10
in get_phys_addr_lpae. Test the descaddr as extracted from TTBR
14
Virtualization or MTE extensions. Now we will report:
11
and from page table entries.
15
12
16
qemu-system-aarch64: mach-virt: KVM does not support providing Security extensions (TrustZone) to the guest CPU
13
Restrict descaddrmask so that we won't raise the fault for v7.
17
14
18
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/961
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
17
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20220301215958.157011-8-richard.henderson@linaro.org
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 20220404155301.566542-1-peter.maydell@linaro.org
22
---
20
---
23
hw/arm/virt.c | 7 +++++++
21
target/arm/internals.h | 1 +
24
1 file changed, 7 insertions(+)
22
target/arm/helper.c | 72 ++++++++++++++++++++++++++++++++----------
23
2 files changed, 57 insertions(+), 16 deletions(-)
25
24
26
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
25
diff --git a/target/arm/internals.h b/target/arm/internals.h
27
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/virt.c
27
--- a/target/arm/internals.h
29
+++ b/hw/arm/virt.c
28
+++ b/target/arm/internals.h
30
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
29
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
31
exit(1);
30
*/
31
typedef struct ARMVAParameters {
32
unsigned tsz : 8;
33
+ unsigned ps : 3;
34
unsigned select : 1;
35
bool tbi : 1;
36
bool epd : 1;
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/helper.c
40
+++ b/target/arm/helper.c
41
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
42
}
43
#endif /* !CONFIG_USER_ONLY */
44
45
+/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
46
+static const uint8_t pamax_map[] = {
47
+ [0] = 32,
48
+ [1] = 36,
49
+ [2] = 40,
50
+ [3] = 42,
51
+ [4] = 44,
52
+ [5] = 48,
53
+};
54
+
55
/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
56
unsigned int arm_pamax(ARMCPU *cpu)
57
{
58
- static const unsigned int pamax_map[] = {
59
- [0] = 32,
60
- [1] = 36,
61
- [2] = 40,
62
- [3] = 42,
63
- [4] = 44,
64
- [5] = 48,
65
- };
66
unsigned int parange =
67
FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
68
69
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
70
{
71
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
72
bool epd, hpd, using16k, using64k, tsz_oob;
73
- int select, tsz, tbi, max_tsz, min_tsz;
74
+ int select, tsz, tbi, max_tsz, min_tsz, ps;
75
76
if (!regime_has_2_ranges(mmu_idx)) {
77
select = 0;
78
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
79
hpd = extract32(tcr, 24, 1);
80
}
81
epd = false;
82
+ ps = extract32(tcr, 16, 3);
83
} else {
84
/*
85
* Bit 55 is always between the two regions, and is canonical for
86
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
87
epd = extract32(tcr, 23, 1);
88
hpd = extract64(tcr, 42, 1);
89
}
90
+ ps = extract64(tcr, 32, 3);
32
}
91
}
33
92
34
+ if (vms->secure && (kvm_enabled() || hvf_enabled())) {
93
if (cpu_isar_feature(aa64_st, env_archcpu(env))) {
35
+ error_report("mach-virt: %s does not support providing "
94
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
36
+ "Security extensions (TrustZone) to the guest CPU",
95
37
+ kvm_enabled() ? "KVM" : "HVF");
96
return (ARMVAParameters) {
38
+ exit(1);
97
.tsz = tsz,
98
+ .ps = ps,
99
.select = select,
100
.tbi = tbi,
101
.epd = epd,
102
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
103
104
/* TODO: This code does not support shareability levels. */
105
if (aarch64) {
106
+ int ps;
107
+
108
param = aa64_va_parameters(env, address, mmu_idx,
109
access_type != MMU_INST_FETCH);
110
level = 0;
111
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
112
113
addrsize = 64 - 8 * param.tbi;
114
inputsize = 64 - param.tsz;
115
- outputsize = arm_pamax(cpu);
116
+
117
+ /*
118
+ * Bound PS by PARANGE to find the effective output address size.
119
+ * ID_AA64MMFR0 is a read-only register so values outside of the
120
+ * supported mappings can be considered an implementation error.
121
+ */
122
+ ps = FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
123
+ ps = MIN(ps, param.ps);
124
+ assert(ps < ARRAY_SIZE(pamax_map));
125
+ outputsize = pamax_map[ps];
126
} else {
127
param = aa32_va_parameters(env, address, mmu_idx);
128
level = 1;
129
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
130
131
/* Now we can extract the actual base address from the TTBR */
132
descaddr = extract64(ttbr, 0, 48);
133
+
134
+ /*
135
+ * If the base address is out of range, raise AddressSizeFault.
136
+ * In the pseudocode, this is !IsZero(baseregister<47:outputsize>),
137
+ * but we've just cleared the bits above 47, so simplify the test.
138
+ */
139
+ if (descaddr >> outputsize) {
140
+ level = 0;
141
+ fault_type = ARMFault_AddressSize;
142
+ goto do_fault;
39
+ }
143
+ }
40
+
144
+
41
if (vms->virt && (kvm_enabled() || hvf_enabled())) {
145
/*
42
error_report("mach-virt: %s does not support providing "
146
* We rely on this masking to clear the RES0 bits at the bottom of the TTBR
43
"Virtualization extensions to the guest CPU",
147
* and also to mask out CnP (bit 0) which could validly be non-zero.
148
*/
149
descaddr &= ~indexmask;
150
151
- /* The address field in the descriptor goes up to bit 39 for ARMv7
152
- * but up to bit 47 for ARMv8, but we use the descaddrmask
153
- * up to bit 39 for AArch32, because we don't need other bits in that case
154
- * to construct next descriptor address (anyway they should be all zeroes).
155
+ /*
156
+ * For AArch32, the address field in the descriptor goes up to bit 39
157
+ * for both v7 and v8. However, for v8 the SBZ bits [47:40] must be 0
158
+ * or an AddressSize fault is raised. So for v8 we extract those SBZ
159
+ * bits as part of the address, which will be checked via outputsize.
160
+ * For AArch64, the address field always goes up to bit 47 (with extra
161
+ * bits for FEAT_LPA placed elsewhere). AArch64 implies v8.
162
*/
163
- descaddrmask = ((1ull << (aarch64 ? 48 : 40)) - 1) &
164
- ~indexmask_grainsize;
165
+ if (arm_feature(env, ARM_FEATURE_V8)) {
166
+ descaddrmask = MAKE_64BIT_MASK(0, 48);
167
+ } else {
168
+ descaddrmask = MAKE_64BIT_MASK(0, 40);
169
+ }
170
+ descaddrmask &= ~indexmask_grainsize;
171
172
/* Secure accesses start with the page table in secure memory and
173
* can be downgraded to non-secure at any step. Non-secure accesses
174
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
175
/* Invalid, or the Reserved level 3 encoding */
176
goto do_fault;
177
}
178
+
179
descaddr = descriptor & descaddrmask;
180
+ if (descaddr >> outputsize) {
181
+ fault_type = ARMFault_AddressSize;
182
+ goto do_fault;
183
+ }
184
185
if ((descriptor & 2) && (level < 3)) {
186
/* Table entry. The top five bits are attributes which may
44
--
187
--
45
2.25.1
188
2.25.1
189
190
diff view generated by jsdifflib
1
The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0
1
From: Richard Henderson <richard.henderson@linaro.org>
2
and EXT_GIC_ID_MCT_G1 multiple times. This means that we will
3
connect multiple IRQs up to the same external GIC input, which
4
is not permitted. We do the same thing in the code in
5
exynos4210_init_board_irqs() because the conditionals selecting
6
an irq_id in the first loop match multiple interrupt IDs.
7
2
8
Overall we do this for interrupt IDs
3
The original A.a revision of the AArch64 ARM required that we
9
(1, 4), (12, 4), (35, 4), (51, 4), (53, 4) for EXT_GIC_ID_MCT_G0
4
force-extend the addresses in these registers from 49 bits.
10
and
5
This language has been loosened via a combination of IMPLEMENTATION
11
(1, 5), (12, 5), (35, 5), (51, 5), (53, 5) for EXT_GIC_ID_MCT_G1
6
DEFINED and CONSTRAINTED UNPREDICTABLE to allow consideration of
7
the entire aligned address.
12
8
13
These correspond to the cases for the multi-core timer that we are
9
This means that we do not have to consider whether or not FEAT_LVA
14
wiring up to multiple inputs on the combiner in
10
is enabled, and decide from which bit an address might need to be
15
exynos4210_combiner_get_gpioin(). That code already deals with all
11
extended.
16
these interrupt IDs being the same input source, so we don't need to
17
connect the external GIC interrupt for any of them except the first
18
(1, 4) and (1, 5). Remove the array entries and conditionals which
19
were incorrectly causing us to wire up extra lines.
20
12
21
This bug didn't cause any visible effects, because we only connect
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
up a device to the "primary" ID values (1, 4) and (1, 5), so the
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
23
extra lines would never be set to a level.
15
Message-id: 20220301215958.157011-9-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
target/arm/helper.c | 32 ++++++++++++++++++++++++--------
19
1 file changed, 24 insertions(+), 8 deletions(-)
24
20
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20220404154658.565020-16-peter.maydell@linaro.org
28
---
29
include/hw/arm/exynos4210.h | 2 +-
30
hw/arm/exynos4210.c | 12 +++++-------
31
2 files changed, 6 insertions(+), 8 deletions(-)
32
33
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
34
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
35
--- a/include/hw/arm/exynos4210.h
23
--- a/target/arm/helper.c
36
+++ b/include/hw/arm/exynos4210.h
24
+++ b/target/arm/helper.c
37
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
38
* one for every non-zero entry in combiner_grp_to_gic_id[].
26
ARMCPU *cpu = env_archcpu(env);
39
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
27
int i = ri->crm;
40
*/
28
41
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
29
- /* Bits [63:49] are hardwired to the value of bit [48]; that is, the
42
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
30
- * register reads and behaves as if values written are sign extended.
43
31
+ /*
44
typedef struct Exynos4210Irq {
32
* Bits [1:0] are RES0.
45
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
33
+ *
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
34
+ * It is IMPLEMENTATION DEFINED whether [63:49] ([63:53] with FEAT_LVA)
47
index XXXXXXX..XXXXXXX 100644
35
+ * are hardwired to the value of bit [48] ([52] with FEAT_LVA), or if
48
--- a/hw/arm/exynos4210.c
36
+ * they contain the value written. It is CONSTRAINED UNPREDICTABLE
49
+++ b/hw/arm/exynos4210.c
37
+ * whether the RESS bits are ignored when comparing an address.
50
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
38
+ *
51
/* int combiner group 34 */
39
+ * Therefore we are allowed to compare the entire register, which lets
52
{ EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
40
+ * us avoid considering whether or not FEAT_LVA is actually enabled.
53
/* int combiner group 35 */
41
*/
54
- { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
42
- value = sextract64(value, 0, 49) & ~3ULL;
55
+ { 0, 0, 0, EXT_GIC_ID_MCT_L1 },
43
+ value &= ~3ULL;
56
/* int combiner group 36 */
44
57
{ EXT_GIC_ID_MIXER },
45
raw_write(env, ri, value);
58
/* int combiner group 37 */
46
hw_watchpoint_update(cpu, i);
59
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
47
@@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update(ARMCPU *cpu, int n)
60
/* groups 38-50 */
48
case 0: /* unlinked address match */
61
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
49
case 1: /* linked address match */
62
/* int combiner group 51 */
50
{
63
- { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
51
- /* Bits [63:49] are hardwired to the value of bit [48]; that is,
64
+ { EXT_GIC_ID_MCT_L0 },
52
- * we behave as if the register was sign extended. Bits [1:0] are
65
/* group 52 */
53
- * RES0. The BAS field is used to allow setting breakpoints on 16
66
{ },
54
- * bit wide instructions; it is CONSTRAINED UNPREDICTABLE whether
67
/* int combiner group 53 */
55
+ /*
68
- { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
56
+ * Bits [1:0] are RES0.
69
+ { EXT_GIC_ID_WDT },
57
+ *
70
/* groups 54-63 */
58
+ * It is IMPLEMENTATION DEFINED whether bits [63:49]
71
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
59
+ * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit
72
};
60
+ * of the VA field ([48] or [52] for FEAT_LVA), or whether the
73
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
61
+ * value is read as written. It is CONSTRAINED UNPREDICTABLE
74
62
+ * whether the RESS bits are ignored when comparing an address.
75
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
63
+ * Therefore we are allowed to compare the entire register, which
76
irq_id = 0;
64
+ * lets us avoid considering whether FEAT_LVA is actually enabled.
77
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
65
+ *
78
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
66
+ * The BAS field is used to allow setting breakpoints on 16-bit
79
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4)) {
67
+ * wide instructions; it is CONSTRAINED UNPREDICTABLE whether
80
/* MCT_G0 is passed to External GIC */
68
* a bp will fire if the addresses covered by the bp and the addresses
81
irq_id = EXT_GIC_ID_MCT_G0;
69
* covered by the insn overlap but the insn doesn't start at the
82
}
70
* start of the bp address range. We choose to require the insn and
83
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
71
@@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update(ARMCPU *cpu, int n)
84
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
72
* See also figure D2-3 in the v8 ARM ARM (DDI0487A.c).
85
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5)) {
73
*/
86
/* MCT_G1 is passed to External and GIC */
74
int bas = extract64(bcr, 5, 4);
87
irq_id = EXT_GIC_ID_MCT_G1;
75
- addr = sextract64(bvr, 0, 49) & ~3ULL;
76
+ addr = bvr & ~3ULL;
77
if (bas == 0) {
78
return;
88
}
79
}
89
--
80
--
90
2.25.1
81
2.25.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Connect the CRL (Clock Reset LPD) to the Versal SoC.
3
This feature is relatively small, as it applies only to
4
64k pages and thus requires no additional changes to the
5
table descriptor walking algorithm, only a change to the
6
minimum TSZ (which is the inverse of the maximum virtual
7
address space size).
4
8
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
9
Note that this feature widens VBAR_ELx, but we already
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
10
treat the register as being 64 bits wide.
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
11
8
Message-id: 20220406174303.2022038-5-edgar.iglesias@xilinx.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20220301215958.157011-10-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
16
---
11
include/hw/arm/xlnx-versal.h | 4 +++
17
docs/system/arm/emulation.rst | 1 +
12
hw/arm/xlnx-versal.c | 54 ++++++++++++++++++++++++++++++++++--
18
target/arm/cpu-param.h | 2 +-
13
2 files changed, 56 insertions(+), 2 deletions(-)
19
target/arm/cpu.h | 5 +++++
20
target/arm/cpu64.c | 1 +
21
target/arm/helper.c | 9 ++++++++-
22
5 files changed, 16 insertions(+), 2 deletions(-)
14
23
15
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
24
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
16
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/xlnx-versal.h
26
--- a/docs/system/arm/emulation.rst
18
+++ b/include/hw/arm/xlnx-versal.h
27
+++ b/docs/system/arm/emulation.rst
28
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
29
- FEAT_LRCPC (Load-acquire RCpc instructions)
30
- FEAT_LRCPC2 (Load-acquire RCpc instructions v2)
31
- FEAT_LSE (Large System Extensions)
32
+- FEAT_LVA (Large Virtual Address space)
33
- FEAT_MTE (Memory Tagging Extension)
34
- FEAT_MTE2 (Memory Tagging Extension)
35
- FEAT_MTE3 (MTE Asymmetric Fault Handling)
36
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/cpu-param.h
39
+++ b/target/arm/cpu-param.h
19
@@ -XXX,XX +XXX,XX @@
40
@@ -XXX,XX +XXX,XX @@
20
#include "hw/nvram/xlnx-versal-efuse.h"
41
#ifdef TARGET_AARCH64
21
#include "hw/ssi/xlnx-versal-ospi.h"
42
# define TARGET_LONG_BITS 64
22
#include "hw/dma/xlnx_csu_dma.h"
43
# define TARGET_PHYS_ADDR_SPACE_BITS 48
23
+#include "hw/misc/xlnx-versal-crl.h"
44
-# define TARGET_VIRT_ADDR_SPACE_BITS 48
24
#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
45
+# define TARGET_VIRT_ADDR_SPACE_BITS 52
25
46
#else
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
47
# define TARGET_LONG_BITS 32
27
@@ -XXX,XX +XXX,XX @@ struct Versal {
48
# define TARGET_PHYS_ADDR_SPACE_BITS 40
28
qemu_or_irq irq_orgate;
49
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
30
} xram;
31
+
32
+ XlnxVersalCRL crl;
33
} lpd;
34
35
/* The Platform Management Controller subsystem. */
36
@@ -XXX,XX +XXX,XX @@ struct Versal {
37
#define VERSAL_TIMER_NS_EL1_IRQ 14
38
#define VERSAL_TIMER_NS_EL2_IRQ 10
39
40
+#define VERSAL_CRL_IRQ 10
41
#define VERSAL_UART0_IRQ_0 18
42
#define VERSAL_UART1_IRQ_0 19
43
#define VERSAL_USB0_IRQ_0 22
44
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
45
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/xlnx-versal.c
51
--- a/target/arm/cpu.h
47
+++ b/hw/arm/xlnx-versal.c
52
+++ b/target/arm/cpu.h
48
@@ -XXX,XX +XXX,XX @@ static void versal_create_ospi(Versal *s, qemu_irq *pic)
53
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
49
qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
54
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
50
}
55
}
51
56
52
+static void versal_create_crl(Versal *s, qemu_irq *pic)
57
+static inline bool isar_feature_aa64_lva(const ARMISARegisters *id)
53
+{
58
+{
54
+ SysBusDevice *sbd;
59
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0;
55
+ int i;
56
+
57
+ object_initialize_child(OBJECT(s), "crl", &s->lpd.crl,
58
+ TYPE_XLNX_VERSAL_CRL);
59
+ sbd = SYS_BUS_DEVICE(&s->lpd.crl);
60
+
61
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
62
+ g_autofree gchar *name = g_strdup_printf("cpu_r5[%d]", i);
63
+
64
+ object_property_set_link(OBJECT(&s->lpd.crl),
65
+ name, OBJECT(&s->lpd.rpu.cpu[i]),
66
+ &error_abort);
67
+ }
68
+
69
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
70
+ g_autofree gchar *name = g_strdup_printf("gem[%d]", i);
71
+
72
+ object_property_set_link(OBJECT(&s->lpd.crl),
73
+ name, OBJECT(&s->lpd.iou.gem[i]),
74
+ &error_abort);
75
+ }
76
+
77
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
78
+ g_autofree gchar *name = g_strdup_printf("adma[%d]", i);
79
+
80
+ object_property_set_link(OBJECT(&s->lpd.crl),
81
+ name, OBJECT(&s->lpd.iou.adma[i]),
82
+ &error_abort);
83
+ }
84
+
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) {
86
+ g_autofree gchar *name = g_strdup_printf("uart[%d]", i);
87
+
88
+ object_property_set_link(OBJECT(&s->lpd.crl),
89
+ name, OBJECT(&s->lpd.iou.uart[i]),
90
+ &error_abort);
91
+ }
92
+
93
+ object_property_set_link(OBJECT(&s->lpd.crl),
94
+ "usb", OBJECT(&s->lpd.iou.usb),
95
+ &error_abort);
96
+
97
+ sysbus_realize(sbd, &error_fatal);
98
+ memory_region_add_subregion(&s->mr_ps, MM_CRL,
99
+ sysbus_mmio_get_region(sbd, 0));
100
+ sysbus_connect_irq(sbd, 0, pic[VERSAL_CRL_IRQ]);
101
+}
60
+}
102
+
61
+
103
/* This takes the board allocated linear DDR memory and creates aliases
62
static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
104
* for each split DDR range/aperture on the Versal address map.
63
{
105
*/
64
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
106
@@ -XXX,XX +XXX,XX @@ static void versal_unimp(Versal *s)
65
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
107
66
index XXXXXXX..XXXXXXX 100644
108
versal_unimp_area(s, "psm", &s->mr_ps,
67
--- a/target/arm/cpu64.c
109
MM_PSM_START, MM_PSM_END - MM_PSM_START);
68
+++ b/target/arm/cpu64.c
110
- versal_unimp_area(s, "crl", &s->mr_ps,
69
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
111
- MM_CRL, MM_CRL_SIZE);
70
t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1);
112
versal_unimp_area(s, "crf", &s->mr_ps,
71
t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* TTCNP */
113
MM_FPD_CRF, MM_FPD_CRF_SIZE);
72
t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* TTST */
114
versal_unimp_area(s, "apu", &s->mr_ps,
73
+ t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
115
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
74
cpu->isar.id_aa64mmfr2 = t;
116
versal_create_efuse(s, pic);
75
117
versal_create_pmc_iou_slcr(s, pic);
76
t = cpu->isar.id_aa64zfr0;
118
versal_create_ospi(s, pic);
77
diff --git a/target/arm/helper.c b/target/arm/helper.c
119
+ versal_create_crl(s, pic);
78
index XXXXXXX..XXXXXXX 100644
120
versal_map_ddr(s);
79
--- a/target/arm/helper.c
121
versal_unimp(s);
80
+++ b/target/arm/helper.c
122
81
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
82
} else {
83
max_tsz = 39;
84
}
85
- min_tsz = 16; /* TODO: ARMv8.2-LVA */
86
+
87
+ min_tsz = 16;
88
+ if (using64k) {
89
+ if (cpu_isar_feature(aa64_lva, env_archcpu(env))) {
90
+ min_tsz = 12;
91
+ }
92
+ }
93
+ /* TODO: FEAT_LPA2 */
94
95
if (tsz > max_tsz) {
96
tsz = max_tsz;
123
--
97
--
124
2.25.1
98
2.25.1
diff view generated by jsdifflib
1
The exynos4210 SoC mostly creates its child devices as if it were
1
From: Richard Henderson <richard.henderson@linaro.org>
2
board code. This includes the a9mpcore object. Switch that to a
3
new-style "embedded in the state struct" creation, because in the
4
next commit we're going to want to refer to the object again further
5
down in the exynos4210_realize() function.
6
2
3
This feature widens physical addresses (and intermediate physical
4
addresses for 2-stage translation) from 48 to 52 bits, when using
5
64k pages. The only thing left at this point is to handle the
6
extra bits in the TTBR and in the table descriptors.
7
8
Note that PAR_EL1 and HPFAR_EL2 are nominally extended, but we don't
9
mask out the high bits when writing to those registers, so no changes
10
are required there.
11
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20220301215958.157011-11-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220404154658.565020-4-peter.maydell@linaro.org
10
---
16
---
11
include/hw/arm/exynos4210.h | 2 ++
17
docs/system/arm/emulation.rst | 1 +
12
hw/arm/exynos4210.c | 11 ++++++-----
18
target/arm/cpu-param.h | 2 +-
13
2 files changed, 8 insertions(+), 5 deletions(-)
19
target/arm/cpu64.c | 2 +-
20
target/arm/helper.c | 19 ++++++++++++++++---
21
4 files changed, 19 insertions(+), 5 deletions(-)
14
22
15
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
23
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
16
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/exynos4210.h
25
--- a/docs/system/arm/emulation.rst
18
+++ b/include/hw/arm/exynos4210.h
26
+++ b/docs/system/arm/emulation.rst
27
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
28
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
29
- FEAT_JSCVT (JavaScript conversion instructions)
30
- FEAT_LOR (Limited ordering regions)
31
+- FEAT_LPA (Large Physical Address space)
32
- FEAT_LRCPC (Load-acquire RCpc instructions)
33
- FEAT_LRCPC2 (Load-acquire RCpc instructions v2)
34
- FEAT_LSE (Large System Extensions)
35
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/cpu-param.h
38
+++ b/target/arm/cpu-param.h
19
@@ -XXX,XX +XXX,XX @@
39
@@ -XXX,XX +XXX,XX @@
20
40
21
#include "hw/or-irq.h"
41
#ifdef TARGET_AARCH64
22
#include "hw/sysbus.h"
42
# define TARGET_LONG_BITS 64
23
+#include "hw/cpu/a9mpcore.h"
43
-# define TARGET_PHYS_ADDR_SPACE_BITS 48
24
#include "target/arm/cpu-qom.h"
44
+# define TARGET_PHYS_ADDR_SPACE_BITS 52
25
#include "qom/object.h"
45
# define TARGET_VIRT_ADDR_SPACE_BITS 52
26
46
#else
27
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
47
# define TARGET_LONG_BITS 32
28
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
48
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
29
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
49
index XXXXXXX..XXXXXXX 100644
30
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
50
--- a/target/arm/cpu64.c
31
+ A9MPPrivState a9mpcore;
51
+++ b/target/arm/cpu64.c
52
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
53
cpu->isar.id_aa64pfr1 = t;
54
55
t = cpu->isar.id_aa64mmfr0;
56
- t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 5); /* PARange: 48 bits */
57
+ t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */
58
cpu->isar.id_aa64mmfr0 = t;
59
60
t = cpu->isar.id_aa64mmfr1;
61
diff --git a/target/arm/helper.c b/target/arm/helper.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/helper.c
64
+++ b/target/arm/helper.c
65
@@ -XXX,XX +XXX,XX @@ static const uint8_t pamax_map[] = {
66
[3] = 42,
67
[4] = 44,
68
[5] = 48,
69
+ [6] = 52,
32
};
70
};
33
71
34
#define TYPE_EXYNOS4210_SOC "exynos4210"
72
/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
35
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
73
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
36
index XXXXXXX..XXXXXXX 100644
74
descaddr = extract64(ttbr, 0, 48);
37
--- a/hw/arm/exynos4210.c
75
38
+++ b/hw/arm/exynos4210.c
76
/*
39
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
77
- * If the base address is out of range, raise AddressSizeFault.
40
}
78
+ * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [5:2] of TTBR.
41
79
+ *
42
/* Private memory region and Internal GIC */
80
+ * Otherwise, if the base address is out of range, raise AddressSizeFault.
43
- dev = qdev_new(TYPE_A9MPCORE_PRIV);
81
* In the pseudocode, this is !IsZero(baseregister<47:outputsize>),
44
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
82
* but we've just cleared the bits above 47, so simplify the test.
45
- busdev = SYS_BUS_DEVICE(dev);
83
*/
46
- sysbus_realize_and_unref(busdev, &error_fatal);
84
- if (descaddr >> outputsize) {
47
+ qdev_prop_set_uint32(DEVICE(&s->a9mpcore), "num-cpu", EXYNOS4210_NCPUS);
85
+ if (outputsize > 48) {
48
+ busdev = SYS_BUS_DEVICE(&s->a9mpcore);
86
+ descaddr |= extract64(ttbr, 2, 4) << 48;
49
+ sysbus_realize(busdev, &error_fatal);
87
+ } else if (descaddr >> outputsize) {
50
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
88
level = 0;
51
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
89
fault_type = ARMFault_AddressSize;
52
sysbus_connect_irq(busdev, n,
90
goto do_fault;
53
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
91
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
54
}
92
}
55
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
93
56
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
94
descaddr = descriptor & descaddrmask;
57
+ s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
95
- if (descaddr >> outputsize) {
58
}
59
60
/* Cache controller */
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
62
g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
63
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
64
}
65
+
96
+
66
+ object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
97
+ /*
67
}
98
+ * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12]
68
99
+ * of descriptor. Otherwise, if descaddr is out of range, raise
69
static void exynos4210_class_init(ObjectClass *klass, void *data)
100
+ * AddressSizeFault.
101
+ */
102
+ if (outputsize > 48) {
103
+ descaddr |= extract64(descriptor, 12, 4) << 48;
104
+ } else if (descaddr >> outputsize) {
105
fault_type = ARMFault_AddressSize;
106
goto do_fault;
107
}
70
--
108
--
71
2.25.1
109
2.25.1
diff view generated by jsdifflib
1
From: Zongyuan Li <zongyuan.li@smartx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
3
With FEAT_LPA2, rather than introducing translation level 4,
4
we introduce level -1, below the current level 0. Extend
5
arm_fi_to_lfsc to handle these faults.
6
7
Assert that this new translation level does not leak into
8
fault types for which it is not defined, which allows some
9
masking of fi->level to be removed.
10
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-2-zongyuan.li@smartx.com
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20220301215958.157011-12-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
15
---
8
hw/arm/realview.c | 33 ++++++++++++++++++++++++---------
16
target/arm/internals.h | 35 +++++++++++++++++++++++++++++------
9
1 file changed, 24 insertions(+), 9 deletions(-)
17
1 file changed, 29 insertions(+), 6 deletions(-)
10
18
11
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
12
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/realview.c
21
--- a/target/arm/internals.h
14
+++ b/hw/arm/realview.c
22
+++ b/target/arm/internals.h
15
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
16
#include "hw/sysbus.h"
24
case ARMFault_None:
17
#include "hw/arm/boot.h"
25
return 0;
18
#include "hw/arm/primecell.h"
26
case ARMFault_AddressSize:
19
+#include "hw/core/split-irq.h"
27
- fsc = fi->level & 3;
20
#include "hw/net/lan9118.h"
28
+ assert(fi->level >= -1 && fi->level <= 3);
21
#include "hw/net/smc91c111.h"
29
+ if (fi->level < 0) {
22
#include "hw/pci/pci.h"
30
+ fsc = 0b101001;
23
+#include "hw/qdev-core.h"
31
+ } else {
24
#include "net/net.h"
32
+ fsc = fi->level;
25
#include "sysemu/sysemu.h"
33
+ }
26
#include "hw/boards.h"
34
break;
27
@@ -XXX,XX +XXX,XX @@ static const int realview_board_id[] = {
35
case ARMFault_AccessFlag:
28
0x76d
36
- fsc = (fi->level & 3) | (0x2 << 2);
29
};
37
+ assert(fi->level >= 0 && fi->level <= 3);
30
38
+ fsc = 0b001000 | fi->level;
31
+static void split_irq_from_named(DeviceState *src, const char* outname,
39
break;
32
+ qemu_irq out1, qemu_irq out2) {
40
case ARMFault_Permission:
33
+ DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
41
- fsc = (fi->level & 3) | (0x3 << 2);
34
+
42
+ assert(fi->level >= 0 && fi->level <= 3);
35
+ qdev_prop_set_uint32(splitter, "num-lines", 2);
43
+ fsc = 0b001100 | fi->level;
36
+
44
break;
37
+ qdev_realize_and_unref(splitter, NULL, &error_fatal);
45
case ARMFault_Translation:
38
+
46
- fsc = (fi->level & 3) | (0x1 << 2);
39
+ qdev_connect_gpio_out(splitter, 0, out1);
47
+ assert(fi->level >= -1 && fi->level <= 3);
40
+ qdev_connect_gpio_out(splitter, 1, out2);
48
+ if (fi->level < 0) {
41
+ qdev_connect_gpio_out_named(src, outname, 0,
49
+ fsc = 0b101011;
42
+ qdev_get_gpio_in(splitter, 0));
50
+ } else {
43
+}
51
+ fsc = 0b000100 | fi->level;
44
+
52
+ }
45
static void realview_init(MachineState *machine,
53
break;
46
enum realview_board_type board_type)
54
case ARMFault_SyncExternal:
47
{
55
fsc = 0x10 | (fi->ea << 12);
48
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
56
break;
49
DeviceState *dev, *sysctl, *gpio2, *pl041;
57
case ARMFault_SyncExternalOnWalk:
50
SysBusDevice *busdev;
58
- fsc = (fi->level & 3) | (0x5 << 2) | (fi->ea << 12);
51
qemu_irq pic[64];
59
+ assert(fi->level >= -1 && fi->level <= 3);
52
- qemu_irq mmc_irq[2];
60
+ if (fi->level < 0) {
53
PCIBus *pci_bus = NULL;
61
+ fsc = 0b010011;
54
NICInfo *nd;
62
+ } else {
55
DriveInfo *dinfo;
63
+ fsc = 0b010100 | fi->level;
56
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
64
+ }
57
* and the PL061 has them the other way about. Also the card
65
+ fsc |= fi->ea << 12;
58
* detect line is inverted.
66
break;
59
*/
67
case ARMFault_SyncParity:
60
- mmc_irq[0] = qemu_irq_split(
68
fsc = 0x18;
61
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
69
break;
62
- qdev_get_gpio_in(gpio2, 1));
70
case ARMFault_SyncParityOnWalk:
63
- mmc_irq[1] = qemu_irq_split(
71
- fsc = (fi->level & 3) | (0x7 << 2);
64
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
72
+ assert(fi->level >= -1 && fi->level <= 3);
65
- qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
73
+ if (fi->level < 0) {
66
- qdev_connect_gpio_out_named(dev, "card-read-only", 0, mmc_irq[0]);
74
+ fsc = 0b011011;
67
- qdev_connect_gpio_out_named(dev, "card-inserted", 0, mmc_irq[1]);
75
+ } else {
68
+ split_irq_from_named(dev, "card-read-only",
76
+ fsc = 0b011100 | fi->level;
69
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
77
+ }
70
+ qdev_get_gpio_in(gpio2, 1));
78
break;
71
+
79
case ARMFault_AsyncParity:
72
+ split_irq_from_named(dev, "card-inserted",
80
fsc = 0x19;
73
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
74
+ qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
75
+
76
dinfo = drive_get(IF_SD, 0, 0);
77
if (dinfo) {
78
DeviceState *card;
79
--
81
--
80
2.25.1
82
2.25.1
diff view generated by jsdifflib
1
Switch the creation of the external GIC to the new-style "embedded in
1
From: Richard Henderson <richard.henderson@linaro.org>
2
state struct" approach, so we can easily refer to the object
3
elsewhere during realize.
4
2
3
Merge tlbi_aa64_range_get_length and tlbi_aa64_range_get_base,
4
returning a structure containing both results. Pass in the
5
ARMMMUIdx, rather than the digested two_ranges boolean.
6
7
This is in preparation for FEAT_LPA2, where the interpretation
8
of 'value' depends on the effective value of DS for the regime.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20220301215958.157011-13-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220404154658.565020-9-peter.maydell@linaro.org
8
---
14
---
9
include/hw/arm/exynos4210.h | 2 ++
15
target/arm/helper.c | 58 +++++++++++++++++++--------------------------
10
include/hw/intc/exynos4210_gic.h | 43 ++++++++++++++++++++++++++++++++
16
1 file changed, 24 insertions(+), 34 deletions(-)
11
hw/arm/exynos4210.c | 10 ++++----
12
hw/intc/exynos4210_gic.c | 17 ++-----------
13
MAINTAINERS | 2 +-
14
5 files changed, 53 insertions(+), 21 deletions(-)
15
create mode 100644 include/hw/intc/exynos4210_gic.h
16
17
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
20
--- a/target/arm/helper.c
20
+++ b/include/hw/arm/exynos4210.h
21
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
22
#include "hw/or-irq.h"
23
}
23
#include "hw/sysbus.h"
24
24
#include "hw/cpu/a9mpcore.h"
25
#ifdef TARGET_AARCH64
25
+#include "hw/intc/exynos4210_gic.h"
26
-static uint64_t tlbi_aa64_range_get_length(CPUARMState *env,
26
#include "target/arm/cpu-qom.h"
27
- uint64_t value)
27
#include "qom/object.h"
28
-{
28
29
- unsigned int page_shift;
29
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
30
- unsigned int page_size_granule;
30
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
31
- uint64_t num;
31
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
32
- uint64_t scale;
32
A9MPPrivState a9mpcore;
33
- uint64_t exponent;
33
+ Exynos4210GicState ext_gic;
34
+typedef struct {
34
};
35
+ uint64_t base;
35
36
uint64_t length;
36
#define TYPE_EXYNOS4210_SOC "exynos4210"
37
+} TLBIRange;
37
diff --git a/include/hw/intc/exynos4210_gic.h b/include/hw/intc/exynos4210_gic.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/intc/exynos4210_gic.h
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * Samsung exynos4210 GIC implementation. Based on hw/arm_gic.c
45
+ *
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
47
+ * All rights reserved.
48
+ *
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
50
+ *
51
+ * This program is free software; you can redistribute it and/or modify it
52
+ * under the terms of the GNU General Public License as published by the
53
+ * Free Software Foundation; either version 2 of the License, or (at your
54
+ * option) any later version.
55
+ *
56
+ * This program is distributed in the hope that it will be useful,
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
59
+ * See the GNU General Public License for more details.
60
+ *
61
+ * You should have received a copy of the GNU General Public License along
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
63
+ */
64
+#ifndef HW_INTC_EXYNOS4210_GIC_H
65
+#define HW_INTC_EXYNOS4210_GIC_H
66
+
38
+
67
+#include "hw/sysbus.h"
39
+static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
68
+
40
+ uint64_t value)
69
+#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
41
+{
70
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
42
+ unsigned int page_size_granule, page_shift, num, scale, exponent;
71
+
43
+ TLBIRange ret = { };
72
+#define EXYNOS4210_GIC_NCPUS 2
44
73
+
45
- num = extract64(value, 39, 5);
74
+struct Exynos4210GicState {
46
- scale = extract64(value, 44, 2);
75
+ SysBusDevice parent_obj;
47
page_size_granule = extract64(value, 46, 2);
76
+
48
77
+ MemoryRegion cpu_container;
49
if (page_size_granule == 0) {
78
+ MemoryRegion dist_container;
50
qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
79
+ MemoryRegion cpu_alias[EXYNOS4210_GIC_NCPUS];
51
page_size_granule);
80
+ MemoryRegion dist_alias[EXYNOS4210_GIC_NCPUS];
52
- return 0;
81
+ uint32_t num_cpu;
53
+ return ret;
82
+ DeviceState *gic;
83
+};
84
+
85
+#endif
86
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/hw/arm/exynos4210.c
89
+++ b/hw/arm/exynos4210.c
90
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
91
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
92
93
/* External GIC */
94
- dev = qdev_new("exynos4210.gic");
95
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
96
- busdev = SYS_BUS_DEVICE(dev);
97
- sysbus_realize_and_unref(busdev, &error_fatal);
98
+ qdev_prop_set_uint32(DEVICE(&s->ext_gic), "num-cpu", EXYNOS4210_NCPUS);
99
+ busdev = SYS_BUS_DEVICE(&s->ext_gic);
100
+ sysbus_realize(busdev, &error_fatal);
101
/* Map CPU interface */
102
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
103
/* Map Distributer interface */
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
105
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
106
}
54
}
107
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
55
108
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
56
page_shift = (page_size_granule - 1) * 2 + 12;
109
+ s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
57
-
58
+ num = extract64(value, 39, 5);
59
+ scale = extract64(value, 44, 2);
60
exponent = (5 * scale) + 1;
61
- length = (num + 1) << (exponent + page_shift);
62
63
- return length;
64
-}
65
+ ret.length = (num + 1) << (exponent + page_shift);
66
67
-static uint64_t tlbi_aa64_range_get_base(CPUARMState *env, uint64_t value,
68
- bool two_ranges)
69
-{
70
- /* TODO: ARMv8.7 FEAT_LPA2 */
71
- uint64_t pageaddr;
72
-
73
- if (two_ranges) {
74
- pageaddr = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
75
+ if (regime_has_2_ranges(mmuidx)) {
76
+ ret.base = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
77
} else {
78
- pageaddr = extract64(value, 0, 37) << TARGET_PAGE_BITS;
79
+ ret.base = extract64(value, 0, 37) << TARGET_PAGE_BITS;
110
}
80
}
111
81
112
/* Internal Interrupt Combiner */
82
- return pageaddr;
113
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
83
+ return ret;
84
}
85
86
static void do_rvae_write(CPUARMState *env, uint64_t value,
87
int idxmap, bool synced)
88
{
89
ARMMMUIdx one_idx = ARM_MMU_IDX_A | ctz32(idxmap);
90
- bool two_ranges = regime_has_2_ranges(one_idx);
91
- uint64_t baseaddr, length;
92
+ TLBIRange range;
93
int bits;
94
95
- baseaddr = tlbi_aa64_range_get_base(env, value, two_ranges);
96
- length = tlbi_aa64_range_get_length(env, value);
97
- bits = tlbbits_for_regime(env, one_idx, baseaddr);
98
+ range = tlbi_aa64_get_range(env, one_idx, value);
99
+ bits = tlbbits_for_regime(env, one_idx, range.base);
100
101
if (synced) {
102
tlb_flush_range_by_mmuidx_all_cpus_synced(env_cpu(env),
103
- baseaddr,
104
- length,
105
+ range.base,
106
+ range.length,
107
idxmap,
108
bits);
109
} else {
110
- tlb_flush_range_by_mmuidx(env_cpu(env), baseaddr,
111
- length, idxmap, bits);
112
+ tlb_flush_range_by_mmuidx(env_cpu(env), range.base,
113
+ range.length, idxmap, bits);
114
}
114
}
115
116
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
117
+ object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
118
}
115
}
119
116
120
static void exynos4210_class_init(ObjectClass *klass, void *data)
121
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/hw/intc/exynos4210_gic.c
124
+++ b/hw/intc/exynos4210_gic.c
125
@@ -XXX,XX +XXX,XX @@
126
#include "qemu/module.h"
127
#include "hw/irq.h"
128
#include "hw/qdev-properties.h"
129
+#include "hw/intc/exynos4210_gic.h"
130
#include "hw/arm/exynos4210.h"
131
#include "qom/object.h"
132
133
@@ -XXX,XX +XXX,XX @@
134
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
135
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
136
137
-#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
138
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
139
-
140
-struct Exynos4210GicState {
141
- SysBusDevice parent_obj;
142
-
143
- MemoryRegion cpu_container;
144
- MemoryRegion dist_container;
145
- MemoryRegion cpu_alias[EXYNOS4210_NCPUS];
146
- MemoryRegion dist_alias[EXYNOS4210_NCPUS];
147
- uint32_t num_cpu;
148
- DeviceState *gic;
149
-};
150
-
151
static void exynos4210_gic_set_irq(void *opaque, int irq, int level)
152
{
153
Exynos4210GicState *s = (Exynos4210GicState *)opaque;
154
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
155
* enough room for the cpu numbers. gcc 9.2.1 on 32-bit x86
156
* doesn't figure this out, otherwise and gives spurious warnings.
157
*/
158
- assert(n <= EXYNOS4210_NCPUS);
159
+ assert(n <= EXYNOS4210_GIC_NCPUS);
160
for (i = 0; i < n; i++) {
161
/* Map CPU interface per SMP Core */
162
sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
163
diff --git a/MAINTAINERS b/MAINTAINERS
164
index XXXXXXX..XXXXXXX 100644
165
--- a/MAINTAINERS
166
+++ b/MAINTAINERS
167
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
168
L: qemu-arm@nongnu.org
169
S: Odd Fixes
170
F: hw/*/exynos*
171
-F: include/hw/arm/exynos4210.h
172
+F: include/hw/*/exynos*
173
174
Calxeda Highbank
175
M: Rob Herring <robh@kernel.org>
176
--
117
--
177
2.25.1
118
2.25.1
diff view generated by jsdifflib
1
In exynos4210_init_board_irqs(), use the TYPE_SPLIT_IRQ device
1
From: Richard Henderson <richard.henderson@linaro.org>
2
instead of qemu_irq_split().
3
2
3
The shift of the BaseADDR field depends on the translation
4
granule in use.
5
6
Fixes: 84940ed8255 ("target/arm: Add support for FEAT_TLBIRANGE")
7
Reported-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220301215958.157011-14-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20220404154658.565020-13-peter.maydell@linaro.org
7
---
12
---
8
include/hw/arm/exynos4210.h | 9 ++++++++
13
target/arm/helper.c | 5 +++--
9
hw/arm/exynos4210.c | 41 +++++++++++++++++++++++++++++--------
14
1 file changed, 3 insertions(+), 2 deletions(-)
10
2 files changed, 42 insertions(+), 8 deletions(-)
11
15
12
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/exynos4210.h
18
--- a/target/arm/helper.c
15
+++ b/include/hw/arm/exynos4210.h
19
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
17
#include "hw/sysbus.h"
21
ret.length = (num + 1) << (exponent + page_shift);
18
#include "hw/cpu/a9mpcore.h"
22
19
#include "hw/intc/exynos4210_gic.h"
23
if (regime_has_2_ranges(mmuidx)) {
20
+#include "hw/core/split-irq.h"
24
- ret.base = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
21
#include "target/arm/cpu-qom.h"
25
+ ret.base = sextract64(value, 0, 37);
22
#include "qom/object.h"
26
} else {
23
27
- ret.base = extract64(value, 0, 37) << TARGET_PAGE_BITS;
24
@@ -XXX,XX +XXX,XX @@
28
+ ret.base = extract64(value, 0, 37);
25
26
#define EXYNOS4210_NUM_DMA 3
27
28
+/*
29
+ * We need one splitter for every external combiner input, plus
30
+ * one for every non-zero entry in combiner_grp_to_gic_id[].
31
+ * We'll assert in exynos4210_init_board_irqs() if this is wrong.
32
+ */
33
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
34
+
35
typedef struct Exynos4210Irq {
36
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
37
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
38
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
39
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
40
A9MPPrivState a9mpcore;
41
Exynos4210GicState ext_gic;
42
+ SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
43
};
44
45
#define TYPE_EXYNOS4210_SOC "exynos4210"
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/exynos4210.c
49
+++ b/hw/arm/exynos4210.c
50
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
51
uint32_t grp, bit, irq_id, n;
52
Exynos4210Irq *is = &s->irqs;
53
DeviceState *extgicdev = DEVICE(&s->ext_gic);
54
+ int splitcount = 0;
55
+ DeviceState *splitter;
56
57
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
58
irq_id = 0;
59
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
60
/* MCT_G1 is passed to External and GIC */
61
irq_id = EXT_GIC_ID_MCT_G1;
62
}
63
+
64
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
65
+ splitter = DEVICE(&s->splitter[splitcount]);
66
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
67
+ qdev_realize(splitter, NULL, &error_abort);
68
+ splitcount++;
69
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
70
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
71
if (irq_id) {
72
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
73
- qdev_get_gpio_in(extgicdev,
74
- irq_id - 32));
75
+ qdev_connect_gpio_out(splitter, 1,
76
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
77
} else {
78
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
79
- is->ext_combiner_irq[n]);
80
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
81
}
82
}
29
}
83
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
30
+ ret.base <<= page_shift;
84
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
31
85
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
32
return ret;
86
87
if (irq_id) {
88
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
89
- qdev_get_gpio_in(extgicdev,
90
- irq_id - 32));
91
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
92
+ splitter = DEVICE(&s->splitter[splitcount]);
93
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
94
+ qdev_realize(splitter, NULL, &error_abort);
95
+ splitcount++;
96
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
97
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
98
+ qdev_connect_gpio_out(splitter, 1,
99
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
100
}
101
}
102
+ /*
103
+ * We check this here to avoid a more obscure assert later when
104
+ * qdev_assert_realized_properly() checks that we realized every
105
+ * child object we initialized.
106
+ */
107
+ assert(splitcount == EXYNOS4210_NUM_SPLITTERS);
108
}
109
110
/*
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
112
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
113
}
114
115
+ for (i = 0; i < ARRAY_SIZE(s->splitter); i++) {
116
+ g_autofree char *name = g_strdup_printf("irq-splitter%d", i);
117
+ object_initialize_child(obj, name, &s->splitter[i], TYPE_SPLIT_IRQ);
118
+ }
119
+
120
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
121
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
122
}
33
}
123
--
34
--
124
2.25.1
35
2.25.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Create an APU CPU Cluster. This is in preparation to add the RPU.
3
For FEAT_LPA2, we will need other ARMVAParameters, which themselves
4
depend on the translation granule in use. We might as well validate
5
that the given TG matches; the architecture "does not require that
6
the instruction invalidates any entries" if this is not true.
4
7
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220406174303.2022038-2-edgar.iglesias@xilinx.com
10
Message-id: 20220301215958.157011-15-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
12
---
10
include/hw/arm/xlnx-versal.h | 2 ++
13
target/arm/helper.c | 10 +++++++---
11
hw/arm/xlnx-versal.c | 9 ++++++++-
14
1 file changed, 7 insertions(+), 3 deletions(-)
12
2 files changed, 10 insertions(+), 1 deletion(-)
13
15
14
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/xlnx-versal.h
18
--- a/target/arm/helper.c
17
+++ b/include/hw/arm/xlnx-versal.h
19
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
19
21
uint64_t value)
20
#include "hw/sysbus.h"
21
#include "hw/arm/boot.h"
22
+#include "hw/cpu/cluster.h"
23
#include "hw/or-irq.h"
24
#include "hw/sd/sdhci.h"
25
#include "hw/intc/arm_gicv3.h"
26
@@ -XXX,XX +XXX,XX @@ struct Versal {
27
struct {
28
struct {
29
MemoryRegion mr;
30
+ CPUClusterState cluster;
31
ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
32
GICv3State gic;
33
} apu;
34
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/xlnx-versal.c
37
+++ b/hw/arm/xlnx-versal.c
38
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
39
{
22
{
40
int i;
23
unsigned int page_size_granule, page_shift, num, scale, exponent;
41
24
+ /* Extract one bit to represent the va selector in use. */
42
+ object_initialize_child(OBJECT(s), "apu-cluster", &s->fpd.apu.cluster,
25
+ uint64_t select = sextract64(value, 36, 1);
43
+ TYPE_CPU_CLUSTER);
26
+ ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true);
44
+ qdev_prop_set_uint32(DEVICE(&s->fpd.apu.cluster), "cluster-id", 0);
27
TLBIRange ret = { };
45
+
28
46
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
29
page_size_granule = extract64(value, 46, 2);
47
Object *obj;
30
48
31
- if (page_size_granule == 0) {
49
- object_initialize_child(OBJECT(s), "apu-cpu[*]", &s->fpd.apu.cpu[i],
32
- qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
50
+ object_initialize_child(OBJECT(&s->fpd.apu.cluster),
33
+ /* The granule encoded in value must match the granule in use. */
51
+ "apu-cpu[*]", &s->fpd.apu.cpu[i],
34
+ if (page_size_granule != (param.using64k ? 3 : param.using16k ? 2 : 1)) {
52
XLNX_VERSAL_ACPU_TYPE);
35
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n",
53
obj = OBJECT(&s->fpd.apu.cpu[i]);
36
page_size_granule);
54
if (i) {
37
return ret;
55
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
56
&error_abort);
57
qdev_realize(DEVICE(obj), NULL, &error_fatal);
58
}
38
}
59
+
39
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
60
+ qdev_realize(DEVICE(&s->fpd.apu.cluster), NULL, &error_fatal);
40
61
}
41
ret.length = (num + 1) << (exponent + page_shift);
62
42
63
static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
43
- if (regime_has_2_ranges(mmuidx)) {
44
+ if (param.select) {
45
ret.base = sextract64(value, 0, 37);
46
} else {
47
ret.base = extract64(value, 0, 37);
64
--
48
--
65
2.25.1
49
2.25.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Break out header file to allow embedding of the the TTC.
3
We support 16k pages, but do not advertize that in ID_AA64MMFR0.
4
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
5
The value 0 in the TGRAN*_2 fields indicates that stage2 lookups defer
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
to the same support as stage1 lookups. This setting is deprecated, so
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
indicate support for all stage2 page sizes directly.
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
9
Message-id: 20220331222017.2914409-2-edgar.iglesias@gmail.com
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20220301215958.157011-16-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
include/hw/timer/cadence_ttc.h | 54 ++++++++++++++++++++++++++++++++++
14
target/arm/cpu64.c | 4 ++++
13
hw/timer/cadence_ttc.c | 32 ++------------------
15
1 file changed, 4 insertions(+)
14
2 files changed, 56 insertions(+), 30 deletions(-)
15
create mode 100644 include/hw/timer/cadence_ttc.h
16
16
17
diff --git a/include/hw/timer/cadence_ttc.h b/include/hw/timer/cadence_ttc.h
17
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
18
new file mode 100644
19
index XXXXXXX..XXXXXXX
20
--- /dev/null
21
+++ b/include/hw/timer/cadence_ttc.h
22
@@ -XXX,XX +XXX,XX @@
23
+/*
24
+ * Xilinx Zynq cadence TTC model
25
+ *
26
+ * Copyright (c) 2011 Xilinx Inc.
27
+ * Copyright (c) 2012 Peter A.G. Crosthwaite (peter.crosthwaite@petalogix.com)
28
+ * Copyright (c) 2012 PetaLogix Pty Ltd.
29
+ * Written By Haibing Ma
30
+ * M. Habib
31
+ *
32
+ * This program is free software; you can redistribute it and/or
33
+ * modify it under the terms of the GNU General Public License
34
+ * as published by the Free Software Foundation; either version
35
+ * 2 of the License, or (at your option) any later version.
36
+ *
37
+ * You should have received a copy of the GNU General Public License along
38
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
39
+ */
40
+#ifndef HW_TIMER_CADENCE_TTC_H
41
+#define HW_TIMER_CADENCE_TTC_H
42
+
43
+#include "hw/sysbus.h"
44
+#include "qemu/timer.h"
45
+
46
+typedef struct {
47
+ QEMUTimer *timer;
48
+ int freq;
49
+
50
+ uint32_t reg_clock;
51
+ uint32_t reg_count;
52
+ uint32_t reg_value;
53
+ uint16_t reg_interval;
54
+ uint16_t reg_match[3];
55
+ uint32_t reg_intr;
56
+ uint32_t reg_intr_en;
57
+ uint32_t reg_event_ctrl;
58
+ uint32_t reg_event;
59
+
60
+ uint64_t cpu_time;
61
+ unsigned int cpu_time_valid;
62
+
63
+ qemu_irq irq;
64
+} CadenceTimerState;
65
+
66
+#define TYPE_CADENCE_TTC "cadence_ttc"
67
+OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
68
+
69
+struct CadenceTTCState {
70
+ SysBusDevice parent_obj;
71
+
72
+ MemoryRegion iomem;
73
+ CadenceTimerState timer[3];
74
+};
75
+
76
+#endif
77
diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c
78
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/timer/cadence_ttc.c
19
--- a/target/arm/cpu64.c
80
+++ b/hw/timer/cadence_ttc.c
20
+++ b/target/arm/cpu64.c
81
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
82
#include "qemu/timer.h"
22
83
#include "qom/object.h"
23
t = cpu->isar.id_aa64mmfr0;
84
24
t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */
85
+#include "hw/timer/cadence_ttc.h"
25
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 1); /* 16k pages supported */
86
+
26
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 2); /* 16k stage2 supported */
87
#ifdef CADENCE_TTC_ERR_DEBUG
27
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN64_2, 2); /* 64k stage2 supported */
88
#define DB_PRINT(...) do { \
28
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2); /* 4k stage2 supported */
89
fprintf(stderr, ": %s: ", __func__); \
29
cpu->isar.id_aa64mmfr0 = t;
90
@@ -XXX,XX +XXX,XX @@
30
91
#define CLOCK_CTRL_PS_EN 0x00000001
31
t = cpu->isar.id_aa64mmfr1;
92
#define CLOCK_CTRL_PS_V 0x0000001e
93
94
-typedef struct {
95
- QEMUTimer *timer;
96
- int freq;
97
-
98
- uint32_t reg_clock;
99
- uint32_t reg_count;
100
- uint32_t reg_value;
101
- uint16_t reg_interval;
102
- uint16_t reg_match[3];
103
- uint32_t reg_intr;
104
- uint32_t reg_intr_en;
105
- uint32_t reg_event_ctrl;
106
- uint32_t reg_event;
107
-
108
- uint64_t cpu_time;
109
- unsigned int cpu_time_valid;
110
-
111
- qemu_irq irq;
112
-} CadenceTimerState;
113
-
114
-#define TYPE_CADENCE_TTC "cadence_ttc"
115
-OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
116
-
117
-struct CadenceTTCState {
118
- SysBusDevice parent_obj;
119
-
120
- MemoryRegion iomem;
121
- CadenceTimerState timer[3];
122
-};
123
-
124
static void cadence_timer_update(CadenceTimerState *s)
125
{
126
qemu_set_irq(s->irq, !!(s->reg_intr & s->reg_intr_en));
127
--
32
--
128
2.25.1
33
2.25.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add a model of the Xilinx Versal CRL.
3
This feature widens physical addresses (and intermediate physical
4
4
addresses for 2-stage translation) from 48 to 52 bits, when using
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
5
4k or 16k pages.
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
6
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
This introduces the DS bit to TCR_ELx, which is RES0 unless the
8
Message-id: 20220406174303.2022038-4-edgar.iglesias@xilinx.com
8
page size is enabled and supports LPA2, resulting in the effective
9
value of DS for a given table walk. The DS bit changes the format
10
of the page table descriptor slightly, moving the PS field out to
11
TCR so that all pages have the same sharability and repurposing
12
those bits of the page table descriptor for the highest bits of
13
the output address.
14
15
Do not yet enable FEAT_LPA2; we need extra plumbing to avoid
16
tickling an old kernel bug.
17
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20220301215958.157011-17-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
22
---
11
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++
23
docs/system/arm/emulation.rst | 1 +
12
hw/misc/xlnx-versal-crl.c | 421 ++++++++++++++++++++++++++++++
24
target/arm/cpu.h | 22 ++++++++
13
hw/misc/meson.build | 1 +
25
target/arm/internals.h | 2 +
14
3 files changed, 657 insertions(+)
26
target/arm/helper.c | 102 +++++++++++++++++++++++++++++-----
15
create mode 100644 include/hw/misc/xlnx-versal-crl.h
27
4 files changed, 112 insertions(+), 15 deletions(-)
16
create mode 100644 hw/misc/xlnx-versal-crl.c
28
17
29
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
18
diff --git a/include/hw/misc/xlnx-versal-crl.h b/include/hw/misc/xlnx-versal-crl.h
30
index XXXXXXX..XXXXXXX 100644
19
new file mode 100644
31
--- a/docs/system/arm/emulation.rst
20
index XXXXXXX..XXXXXXX
32
+++ b/docs/system/arm/emulation.rst
21
--- /dev/null
33
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
22
+++ b/include/hw/misc/xlnx-versal-crl.h
34
- FEAT_JSCVT (JavaScript conversion instructions)
23
@@ -XXX,XX +XXX,XX @@
35
- FEAT_LOR (Limited ordering regions)
24
+/*
36
- FEAT_LPA (Large Physical Address space)
25
+ * QEMU model of the Clock-Reset-LPD (CRL).
37
+- FEAT_LPA2 (Large Physical and virtual Address space v2)
26
+ *
38
- FEAT_LRCPC (Load-acquire RCpc instructions)
27
+ * Copyright (c) 2022 Xilinx Inc.
39
- FEAT_LRCPC2 (Load-acquire RCpc instructions v2)
28
+ * SPDX-License-Identifier: GPL-2.0-or-later
40
- FEAT_LSE (Large System Extensions)
29
+ *
41
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
30
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
42
index XXXXXXX..XXXXXXX 100644
31
+ */
43
--- a/target/arm/cpu.h
32
+#ifndef HW_MISC_XLNX_VERSAL_CRL_H
44
+++ b/target/arm/cpu.h
33
+#define HW_MISC_XLNX_VERSAL_CRL_H
45
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_i8mm(const ARMISARegisters *id)
34
+
46
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, I8MM) != 0;
35
+#include "hw/sysbus.h"
47
}
36
+#include "hw/register.h"
48
37
+#include "target/arm/cpu.h"
49
+static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id)
38
+
39
+#define TYPE_XLNX_VERSAL_CRL "xlnx,versal-crl"
40
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCRL, XLNX_VERSAL_CRL)
41
+
42
+REG32(ERR_CTRL, 0x0)
43
+ FIELD(ERR_CTRL, SLVERR_ENABLE, 0, 1)
44
+REG32(IR_STATUS, 0x4)
45
+ FIELD(IR_STATUS, ADDR_DECODE_ERR, 0, 1)
46
+REG32(IR_MASK, 0x8)
47
+ FIELD(IR_MASK, ADDR_DECODE_ERR, 0, 1)
48
+REG32(IR_ENABLE, 0xc)
49
+ FIELD(IR_ENABLE, ADDR_DECODE_ERR, 0, 1)
50
+REG32(IR_DISABLE, 0x10)
51
+ FIELD(IR_DISABLE, ADDR_DECODE_ERR, 0, 1)
52
+REG32(WPROT, 0x1c)
53
+ FIELD(WPROT, ACTIVE, 0, 1)
54
+REG32(PLL_CLK_OTHER_DMN, 0x20)
55
+ FIELD(PLL_CLK_OTHER_DMN, APLL_BYPASS, 0, 1)
56
+REG32(RPLL_CTRL, 0x40)
57
+ FIELD(RPLL_CTRL, POST_SRC, 24, 3)
58
+ FIELD(RPLL_CTRL, PRE_SRC, 20, 3)
59
+ FIELD(RPLL_CTRL, CLKOUTDIV, 16, 2)
60
+ FIELD(RPLL_CTRL, FBDIV, 8, 8)
61
+ FIELD(RPLL_CTRL, BYPASS, 3, 1)
62
+ FIELD(RPLL_CTRL, RESET, 0, 1)
63
+REG32(RPLL_CFG, 0x44)
64
+ FIELD(RPLL_CFG, LOCK_DLY, 25, 7)
65
+ FIELD(RPLL_CFG, LOCK_CNT, 13, 10)
66
+ FIELD(RPLL_CFG, LFHF, 10, 2)
67
+ FIELD(RPLL_CFG, CP, 5, 4)
68
+ FIELD(RPLL_CFG, RES, 0, 4)
69
+REG32(RPLL_FRAC_CFG, 0x48)
70
+ FIELD(RPLL_FRAC_CFG, ENABLED, 31, 1)
71
+ FIELD(RPLL_FRAC_CFG, SEED, 22, 3)
72
+ FIELD(RPLL_FRAC_CFG, ALGRTHM, 19, 1)
73
+ FIELD(RPLL_FRAC_CFG, ORDER, 18, 1)
74
+ FIELD(RPLL_FRAC_CFG, DATA, 0, 16)
75
+REG32(PLL_STATUS, 0x50)
76
+ FIELD(PLL_STATUS, RPLL_STABLE, 2, 1)
77
+ FIELD(PLL_STATUS, RPLL_LOCK, 0, 1)
78
+REG32(RPLL_TO_XPD_CTRL, 0x100)
79
+ FIELD(RPLL_TO_XPD_CTRL, CLKACT, 25, 1)
80
+ FIELD(RPLL_TO_XPD_CTRL, DIVISOR0, 8, 10)
81
+REG32(LPD_TOP_SWITCH_CTRL, 0x104)
82
+ FIELD(LPD_TOP_SWITCH_CTRL, CLKACT_ADMA, 26, 1)
83
+ FIELD(LPD_TOP_SWITCH_CTRL, CLKACT, 25, 1)
84
+ FIELD(LPD_TOP_SWITCH_CTRL, DIVISOR0, 8, 10)
85
+ FIELD(LPD_TOP_SWITCH_CTRL, SRCSEL, 0, 3)
86
+REG32(LPD_LSBUS_CTRL, 0x108)
87
+ FIELD(LPD_LSBUS_CTRL, CLKACT, 25, 1)
88
+ FIELD(LPD_LSBUS_CTRL, DIVISOR0, 8, 10)
89
+ FIELD(LPD_LSBUS_CTRL, SRCSEL, 0, 3)
90
+REG32(CPU_R5_CTRL, 0x10c)
91
+ FIELD(CPU_R5_CTRL, CLKACT_OCM2, 28, 1)
92
+ FIELD(CPU_R5_CTRL, CLKACT_OCM, 27, 1)
93
+ FIELD(CPU_R5_CTRL, CLKACT_CORE, 26, 1)
94
+ FIELD(CPU_R5_CTRL, CLKACT, 25, 1)
95
+ FIELD(CPU_R5_CTRL, DIVISOR0, 8, 10)
96
+ FIELD(CPU_R5_CTRL, SRCSEL, 0, 3)
97
+REG32(IOU_SWITCH_CTRL, 0x114)
98
+ FIELD(IOU_SWITCH_CTRL, CLKACT, 25, 1)
99
+ FIELD(IOU_SWITCH_CTRL, DIVISOR0, 8, 10)
100
+ FIELD(IOU_SWITCH_CTRL, SRCSEL, 0, 3)
101
+REG32(GEM0_REF_CTRL, 0x118)
102
+ FIELD(GEM0_REF_CTRL, CLKACT_RX, 27, 1)
103
+ FIELD(GEM0_REF_CTRL, CLKACT_TX, 26, 1)
104
+ FIELD(GEM0_REF_CTRL, CLKACT, 25, 1)
105
+ FIELD(GEM0_REF_CTRL, DIVISOR0, 8, 10)
106
+ FIELD(GEM0_REF_CTRL, SRCSEL, 0, 3)
107
+REG32(GEM1_REF_CTRL, 0x11c)
108
+ FIELD(GEM1_REF_CTRL, CLKACT_RX, 27, 1)
109
+ FIELD(GEM1_REF_CTRL, CLKACT_TX, 26, 1)
110
+ FIELD(GEM1_REF_CTRL, CLKACT, 25, 1)
111
+ FIELD(GEM1_REF_CTRL, DIVISOR0, 8, 10)
112
+ FIELD(GEM1_REF_CTRL, SRCSEL, 0, 3)
113
+REG32(GEM_TSU_REF_CTRL, 0x120)
114
+ FIELD(GEM_TSU_REF_CTRL, CLKACT, 25, 1)
115
+ FIELD(GEM_TSU_REF_CTRL, DIVISOR0, 8, 10)
116
+ FIELD(GEM_TSU_REF_CTRL, SRCSEL, 0, 3)
117
+REG32(USB0_BUS_REF_CTRL, 0x124)
118
+ FIELD(USB0_BUS_REF_CTRL, CLKACT, 25, 1)
119
+ FIELD(USB0_BUS_REF_CTRL, DIVISOR0, 8, 10)
120
+ FIELD(USB0_BUS_REF_CTRL, SRCSEL, 0, 3)
121
+REG32(UART0_REF_CTRL, 0x128)
122
+ FIELD(UART0_REF_CTRL, CLKACT, 25, 1)
123
+ FIELD(UART0_REF_CTRL, DIVISOR0, 8, 10)
124
+ FIELD(UART0_REF_CTRL, SRCSEL, 0, 3)
125
+REG32(UART1_REF_CTRL, 0x12c)
126
+ FIELD(UART1_REF_CTRL, CLKACT, 25, 1)
127
+ FIELD(UART1_REF_CTRL, DIVISOR0, 8, 10)
128
+ FIELD(UART1_REF_CTRL, SRCSEL, 0, 3)
129
+REG32(SPI0_REF_CTRL, 0x130)
130
+ FIELD(SPI0_REF_CTRL, CLKACT, 25, 1)
131
+ FIELD(SPI0_REF_CTRL, DIVISOR0, 8, 10)
132
+ FIELD(SPI0_REF_CTRL, SRCSEL, 0, 3)
133
+REG32(SPI1_REF_CTRL, 0x134)
134
+ FIELD(SPI1_REF_CTRL, CLKACT, 25, 1)
135
+ FIELD(SPI1_REF_CTRL, DIVISOR0, 8, 10)
136
+ FIELD(SPI1_REF_CTRL, SRCSEL, 0, 3)
137
+REG32(CAN0_REF_CTRL, 0x138)
138
+ FIELD(CAN0_REF_CTRL, CLKACT, 25, 1)
139
+ FIELD(CAN0_REF_CTRL, DIVISOR0, 8, 10)
140
+ FIELD(CAN0_REF_CTRL, SRCSEL, 0, 3)
141
+REG32(CAN1_REF_CTRL, 0x13c)
142
+ FIELD(CAN1_REF_CTRL, CLKACT, 25, 1)
143
+ FIELD(CAN1_REF_CTRL, DIVISOR0, 8, 10)
144
+ FIELD(CAN1_REF_CTRL, SRCSEL, 0, 3)
145
+REG32(I2C0_REF_CTRL, 0x140)
146
+ FIELD(I2C0_REF_CTRL, CLKACT, 25, 1)
147
+ FIELD(I2C0_REF_CTRL, DIVISOR0, 8, 10)
148
+ FIELD(I2C0_REF_CTRL, SRCSEL, 0, 3)
149
+REG32(I2C1_REF_CTRL, 0x144)
150
+ FIELD(I2C1_REF_CTRL, CLKACT, 25, 1)
151
+ FIELD(I2C1_REF_CTRL, DIVISOR0, 8, 10)
152
+ FIELD(I2C1_REF_CTRL, SRCSEL, 0, 3)
153
+REG32(DBG_LPD_CTRL, 0x148)
154
+ FIELD(DBG_LPD_CTRL, CLKACT, 25, 1)
155
+ FIELD(DBG_LPD_CTRL, DIVISOR0, 8, 10)
156
+ FIELD(DBG_LPD_CTRL, SRCSEL, 0, 3)
157
+REG32(TIMESTAMP_REF_CTRL, 0x14c)
158
+ FIELD(TIMESTAMP_REF_CTRL, CLKACT, 25, 1)
159
+ FIELD(TIMESTAMP_REF_CTRL, DIVISOR0, 8, 10)
160
+ FIELD(TIMESTAMP_REF_CTRL, SRCSEL, 0, 3)
161
+REG32(CRL_SAFETY_CHK, 0x150)
162
+REG32(PSM_REF_CTRL, 0x154)
163
+ FIELD(PSM_REF_CTRL, DIVISOR0, 8, 10)
164
+ FIELD(PSM_REF_CTRL, SRCSEL, 0, 3)
165
+REG32(DBG_TSTMP_CTRL, 0x158)
166
+ FIELD(DBG_TSTMP_CTRL, CLKACT, 25, 1)
167
+ FIELD(DBG_TSTMP_CTRL, DIVISOR0, 8, 10)
168
+ FIELD(DBG_TSTMP_CTRL, SRCSEL, 0, 3)
169
+REG32(CPM_TOPSW_REF_CTRL, 0x15c)
170
+ FIELD(CPM_TOPSW_REF_CTRL, CLKACT, 25, 1)
171
+ FIELD(CPM_TOPSW_REF_CTRL, DIVISOR0, 8, 10)
172
+ FIELD(CPM_TOPSW_REF_CTRL, SRCSEL, 0, 3)
173
+REG32(USB3_DUAL_REF_CTRL, 0x160)
174
+ FIELD(USB3_DUAL_REF_CTRL, CLKACT, 25, 1)
175
+ FIELD(USB3_DUAL_REF_CTRL, DIVISOR0, 8, 10)
176
+ FIELD(USB3_DUAL_REF_CTRL, SRCSEL, 0, 3)
177
+REG32(RST_CPU_R5, 0x300)
178
+ FIELD(RST_CPU_R5, RESET_PGE, 4, 1)
179
+ FIELD(RST_CPU_R5, RESET_AMBA, 2, 1)
180
+ FIELD(RST_CPU_R5, RESET_CPU1, 1, 1)
181
+ FIELD(RST_CPU_R5, RESET_CPU0, 0, 1)
182
+REG32(RST_ADMA, 0x304)
183
+ FIELD(RST_ADMA, RESET, 0, 1)
184
+REG32(RST_GEM0, 0x308)
185
+ FIELD(RST_GEM0, RESET, 0, 1)
186
+REG32(RST_GEM1, 0x30c)
187
+ FIELD(RST_GEM1, RESET, 0, 1)
188
+REG32(RST_SPARE, 0x310)
189
+ FIELD(RST_SPARE, RESET, 0, 1)
190
+REG32(RST_USB0, 0x314)
191
+ FIELD(RST_USB0, RESET, 0, 1)
192
+REG32(RST_UART0, 0x318)
193
+ FIELD(RST_UART0, RESET, 0, 1)
194
+REG32(RST_UART1, 0x31c)
195
+ FIELD(RST_UART1, RESET, 0, 1)
196
+REG32(RST_SPI0, 0x320)
197
+ FIELD(RST_SPI0, RESET, 0, 1)
198
+REG32(RST_SPI1, 0x324)
199
+ FIELD(RST_SPI1, RESET, 0, 1)
200
+REG32(RST_CAN0, 0x328)
201
+ FIELD(RST_CAN0, RESET, 0, 1)
202
+REG32(RST_CAN1, 0x32c)
203
+ FIELD(RST_CAN1, RESET, 0, 1)
204
+REG32(RST_I2C0, 0x330)
205
+ FIELD(RST_I2C0, RESET, 0, 1)
206
+REG32(RST_I2C1, 0x334)
207
+ FIELD(RST_I2C1, RESET, 0, 1)
208
+REG32(RST_DBG_LPD, 0x338)
209
+ FIELD(RST_DBG_LPD, RPU_DBG1_RESET, 5, 1)
210
+ FIELD(RST_DBG_LPD, RPU_DBG0_RESET, 4, 1)
211
+ FIELD(RST_DBG_LPD, RESET_HSDP, 1, 1)
212
+ FIELD(RST_DBG_LPD, RESET, 0, 1)
213
+REG32(RST_GPIO, 0x33c)
214
+ FIELD(RST_GPIO, RESET, 0, 1)
215
+REG32(RST_TTC, 0x344)
216
+ FIELD(RST_TTC, TTC3_RESET, 3, 1)
217
+ FIELD(RST_TTC, TTC2_RESET, 2, 1)
218
+ FIELD(RST_TTC, TTC1_RESET, 1, 1)
219
+ FIELD(RST_TTC, TTC0_RESET, 0, 1)
220
+REG32(RST_TIMESTAMP, 0x348)
221
+ FIELD(RST_TIMESTAMP, RESET, 0, 1)
222
+REG32(RST_SWDT, 0x34c)
223
+ FIELD(RST_SWDT, RESET, 0, 1)
224
+REG32(RST_OCM, 0x350)
225
+ FIELD(RST_OCM, RESET, 0, 1)
226
+REG32(RST_IPI, 0x354)
227
+ FIELD(RST_IPI, RESET, 0, 1)
228
+REG32(RST_SYSMON, 0x358)
229
+ FIELD(RST_SYSMON, SEQ_RST, 1, 1)
230
+ FIELD(RST_SYSMON, CFG_RST, 0, 1)
231
+REG32(RST_FPD, 0x360)
232
+ FIELD(RST_FPD, SRST, 1, 1)
233
+ FIELD(RST_FPD, POR, 0, 1)
234
+REG32(PSM_RST_MODE, 0x370)
235
+ FIELD(PSM_RST_MODE, WAKEUP, 2, 1)
236
+ FIELD(PSM_RST_MODE, RST_MODE, 0, 2)
237
+
238
+#define CRL_R_MAX (R_PSM_RST_MODE + 1)
239
+
240
+#define RPU_MAX_CPU 2
241
+
242
+struct XlnxVersalCRL {
243
+ SysBusDevice parent_obj;
244
+ qemu_irq irq;
245
+
246
+ struct {
247
+ ARMCPU *cpu_r5[RPU_MAX_CPU];
248
+ DeviceState *adma[8];
249
+ DeviceState *uart[2];
250
+ DeviceState *gem[2];
251
+ DeviceState *usb;
252
+ } cfg;
253
+
254
+ RegisterInfoArray *reg_array;
255
+ uint32_t regs[CRL_R_MAX];
256
+ RegisterInfo regs_info[CRL_R_MAX];
257
+};
258
+#endif
259
diff --git a/hw/misc/xlnx-versal-crl.c b/hw/misc/xlnx-versal-crl.c
260
new file mode 100644
261
index XXXXXXX..XXXXXXX
262
--- /dev/null
263
+++ b/hw/misc/xlnx-versal-crl.c
264
@@ -XXX,XX +XXX,XX @@
265
+/*
266
+ * QEMU model of the Clock-Reset-LPD (CRL).
267
+ *
268
+ * Copyright (c) 2022 Advanced Micro Devices, Inc.
269
+ * SPDX-License-Identifier: GPL-2.0-or-later
270
+ *
271
+ * Written by Edgar E. Iglesias <edgar.iglesias@amd.com>
272
+ */
273
+
274
+#include "qemu/osdep.h"
275
+#include "qapi/error.h"
276
+#include "qemu/log.h"
277
+#include "qemu/bitops.h"
278
+#include "migration/vmstate.h"
279
+#include "hw/qdev-properties.h"
280
+#include "hw/sysbus.h"
281
+#include "hw/irq.h"
282
+#include "hw/register.h"
283
+#include "hw/resettable.h"
284
+
285
+#include "target/arm/arm-powerctl.h"
286
+#include "hw/misc/xlnx-versal-crl.h"
287
+
288
+#ifndef XLNX_VERSAL_CRL_ERR_DEBUG
289
+#define XLNX_VERSAL_CRL_ERR_DEBUG 0
290
+#endif
291
+
292
+static void crl_update_irq(XlnxVersalCRL *s)
293
+{
50
+{
294
+ bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK];
51
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1;
295
+ qemu_set_irq(s->irq, pending);
296
+}
52
+}
297
+
53
+
298
+static void crl_status_postw(RegisterInfo *reg, uint64_t val64)
54
+static inline bool isar_feature_aa64_tgran4_2_lpa2(const ARMISARegisters *id)
299
+{
55
+{
300
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
56
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
301
+ crl_update_irq(s);
57
+ return t >= 3 || (t == 0 && isar_feature_aa64_tgran4_lpa2(id));
302
+}
58
+}
303
+
59
+
304
+static uint64_t crl_enable_prew(RegisterInfo *reg, uint64_t val64)
60
+static inline bool isar_feature_aa64_tgran16_lpa2(const ARMISARegisters *id)
305
+{
61
+{
306
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
62
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 2;
307
+ uint32_t val = val64;
308
+
309
+ s->regs[R_IR_MASK] &= ~val;
310
+ crl_update_irq(s);
311
+ return 0;
312
+}
63
+}
313
+
64
+
314
+static uint64_t crl_disable_prew(RegisterInfo *reg, uint64_t val64)
65
+static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id)
315
+{
66
+{
316
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
67
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
317
+ uint32_t val = val64;
68
+ return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id));
318
+
319
+ s->regs[R_IR_MASK] |= val;
320
+ crl_update_irq(s);
321
+ return 0;
322
+}
69
+}
323
+
70
+
324
+static void crl_reset_dev(XlnxVersalCRL *s, DeviceState *dev,
71
static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
325
+ bool rst_old, bool rst_new)
72
{
326
+{
73
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
327
+ device_cold_reset(dev);
74
diff --git a/target/arm/internals.h b/target/arm/internals.h
328
+}
75
index XXXXXXX..XXXXXXX 100644
329
+
76
--- a/target/arm/internals.h
330
+static void crl_reset_cpu(XlnxVersalCRL *s, ARMCPU *armcpu,
77
+++ b/target/arm/internals.h
331
+ bool rst_old, bool rst_new)
78
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
332
+{
79
typedef struct ARMVAParameters {
333
+ if (rst_new) {
80
unsigned tsz : 8;
334
+ arm_set_cpu_off(armcpu->mp_affinity);
81
unsigned ps : 3;
82
+ unsigned sh : 2;
83
unsigned select : 1;
84
bool tbi : 1;
85
bool epd : 1;
86
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
87
bool using16k : 1;
88
bool using64k : 1;
89
bool tsz_oob : 1; /* tsz has been clamped to legal range */
90
+ bool ds : 1;
91
} ARMVAParameters;
92
93
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
94
diff --git a/target/arm/helper.c b/target/arm/helper.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/target/arm/helper.c
97
+++ b/target/arm/helper.c
98
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
99
} else {
100
ret.base = extract64(value, 0, 37);
101
}
102
+ if (param.ds) {
103
+ /*
104
+ * With DS=1, BaseADDR is always shifted 16 so that it is able
105
+ * to address all 52 va bits. The input address is perforce
106
+ * aligned on a 64k boundary regardless of translation granule.
107
+ */
108
+ page_shift = 16;
109
+ }
110
ret.base <<= page_shift;
111
112
return ret;
113
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
114
const int grainsize = stride + 3;
115
int startsizecheck;
116
117
- /* Negative levels are never allowed. */
118
- if (level < 0) {
119
+ /*
120
+ * Negative levels are usually not allowed...
121
+ * Except for FEAT_LPA2, 4k page table, 52-bit address space, which
122
+ * begins with level -1. Note that previous feature tests will have
123
+ * eliminated this combination if it is not enabled.
124
+ */
125
+ if (level < (inputsize == 52 && stride == 9 ? -1 : 0)) {
126
return false;
127
}
128
129
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
130
ARMMMUIdx mmu_idx, bool data)
131
{
132
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
133
- bool epd, hpd, using16k, using64k, tsz_oob;
134
- int select, tsz, tbi, max_tsz, min_tsz, ps;
135
+ bool epd, hpd, using16k, using64k, tsz_oob, ds;
136
+ int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
137
+ ARMCPU *cpu = env_archcpu(env);
138
139
if (!regime_has_2_ranges(mmu_idx)) {
140
select = 0;
141
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
142
hpd = extract32(tcr, 24, 1);
143
}
144
epd = false;
145
+ sh = extract32(tcr, 12, 2);
146
ps = extract32(tcr, 16, 3);
147
+ ds = extract64(tcr, 32, 1);
148
} else {
149
/*
150
* Bit 55 is always between the two regions, and is canonical for
151
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
152
if (!select) {
153
tsz = extract32(tcr, 0, 6);
154
epd = extract32(tcr, 7, 1);
155
+ sh = extract32(tcr, 12, 2);
156
using64k = extract32(tcr, 14, 1);
157
using16k = extract32(tcr, 15, 1);
158
hpd = extract64(tcr, 41, 1);
159
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
160
using64k = tg == 3;
161
tsz = extract32(tcr, 16, 6);
162
epd = extract32(tcr, 23, 1);
163
+ sh = extract32(tcr, 28, 2);
164
hpd = extract64(tcr, 42, 1);
165
}
166
ps = extract64(tcr, 32, 3);
167
+ ds = extract64(tcr, 59, 1);
168
}
169
170
- if (cpu_isar_feature(aa64_st, env_archcpu(env))) {
171
+ if (cpu_isar_feature(aa64_st, cpu)) {
172
max_tsz = 48 - using64k;
173
} else {
174
max_tsz = 39;
175
}
176
177
+ /*
178
+ * DS is RES0 unless FEAT_LPA2 is supported for the given page size;
179
+ * adjust the effective value of DS, as documented.
180
+ */
181
min_tsz = 16;
182
if (using64k) {
183
- if (cpu_isar_feature(aa64_lva, env_archcpu(env))) {
184
+ if (cpu_isar_feature(aa64_lva, cpu)) {
185
+ min_tsz = 12;
186
+ }
187
+ ds = false;
188
+ } else if (ds) {
189
+ switch (mmu_idx) {
190
+ case ARMMMUIdx_Stage2:
191
+ case ARMMMUIdx_Stage2_S:
192
+ if (using16k) {
193
+ ds = cpu_isar_feature(aa64_tgran16_2_lpa2, cpu);
194
+ } else {
195
+ ds = cpu_isar_feature(aa64_tgran4_2_lpa2, cpu);
196
+ }
197
+ break;
198
+ default:
199
+ if (using16k) {
200
+ ds = cpu_isar_feature(aa64_tgran16_lpa2, cpu);
201
+ } else {
202
+ ds = cpu_isar_feature(aa64_tgran4_lpa2, cpu);
203
+ }
204
+ break;
205
+ }
206
+ if (ds) {
207
min_tsz = 12;
208
}
209
}
210
- /* TODO: FEAT_LPA2 */
211
212
if (tsz > max_tsz) {
213
tsz = max_tsz;
214
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
215
return (ARMVAParameters) {
216
.tsz = tsz,
217
.ps = ps,
218
+ .sh = sh,
219
.select = select,
220
.tbi = tbi,
221
.epd = epd,
222
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
223
.using16k = using16k,
224
.using64k = using64k,
225
.tsz_oob = tsz_oob,
226
+ .ds = ds,
227
};
228
}
229
230
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
231
* VTCR_EL2.SL0 field (whose interpretation depends on the page size)
232
*/
233
uint32_t sl0 = extract32(tcr->raw_tcr, 6, 2);
234
+ uint32_t sl2 = extract64(tcr->raw_tcr, 33, 1);
235
uint32_t startlevel;
236
bool ok;
237
238
- if (!aarch64 || stride == 9) {
239
+ /* SL2 is RES0 unless DS=1 & 4kb granule. */
240
+ if (param.ds && stride == 9 && sl2) {
241
+ if (sl0 != 0) {
242
+ level = 0;
243
+ fault_type = ARMFault_Translation;
244
+ goto do_fault;
245
+ }
246
+ startlevel = -1;
247
+ } else if (!aarch64 || stride == 9) {
248
/* AArch32 or 4KB pages */
249
startlevel = 2 - sl0;
250
251
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
252
* for both v7 and v8. However, for v8 the SBZ bits [47:40] must be 0
253
* or an AddressSize fault is raised. So for v8 we extract those SBZ
254
* bits as part of the address, which will be checked via outputsize.
255
- * For AArch64, the address field always goes up to bit 47 (with extra
256
- * bits for FEAT_LPA placed elsewhere). AArch64 implies v8.
257
+ * For AArch64, the address field goes up to bit 47, or 49 with FEAT_LPA2;
258
+ * the highest bits of a 52-bit output are placed elsewhere.
259
*/
260
- if (arm_feature(env, ARM_FEATURE_V8)) {
261
+ if (param.ds) {
262
+ descaddrmask = MAKE_64BIT_MASK(0, 50);
263
+ } else if (arm_feature(env, ARM_FEATURE_V8)) {
264
descaddrmask = MAKE_64BIT_MASK(0, 48);
265
} else {
266
descaddrmask = MAKE_64BIT_MASK(0, 40);
267
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
268
269
/*
270
* For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12]
271
- * of descriptor. Otherwise, if descaddr is out of range, raise
272
- * AddressSizeFault.
273
+ * of descriptor. For FEAT_LPA2 and effective DS, bits [51:50] of
274
+ * descaddr are in [9:8]. Otherwise, if descaddr is out of range,
275
+ * raise AddressSizeFault.
276
*/
277
if (outputsize > 48) {
278
- descaddr |= extract64(descriptor, 12, 4) << 48;
279
+ if (param.ds) {
280
+ descaddr |= extract64(descriptor, 8, 2) << 50;
281
+ } else {
282
+ descaddr |= extract64(descriptor, 12, 4) << 48;
283
+ }
284
} else if (descaddr >> outputsize) {
285
fault_type = ARMFault_AddressSize;
286
goto do_fault;
287
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
288
assert(attrindx <= 7);
289
cacheattrs->attrs = extract64(mair, attrindx * 8, 8);
290
}
291
- cacheattrs->shareability = extract32(attrs, 6, 2);
292
+
293
+ /*
294
+ * For FEAT_LPA2 and effective DS, the SH field in the attributes
295
+ * was re-purposed for output address bits. The SH attribute in
296
+ * that case comes from TCR_ELx, which we extracted earlier.
297
+ */
298
+ if (param.ds) {
299
+ cacheattrs->shareability = param.sh;
335
+ } else {
300
+ } else {
336
+ arm_set_cpu_on_and_reset(armcpu->mp_affinity);
301
+ cacheattrs->shareability = extract32(attrs, 6, 2);
337
+ }
302
+ }
338
+}
303
339
+
304
*phys_ptr = descaddr;
340
+#define REGFIELD_RESET(type, s, reg, f, new_val, dev) { \
305
*page_size_ptr = page_size;
341
+ bool old_f = ARRAY_FIELD_EX32((s)->regs, reg, f); \
342
+ bool new_f = FIELD_EX32(new_val, reg, f); \
343
+ \
344
+ /* Detect edges. */ \
345
+ if (dev && old_f != new_f) { \
346
+ crl_reset_ ## type(s, dev, old_f, new_f); \
347
+ } \
348
+}
349
+
350
+static uint64_t crl_rst_r5_prew(RegisterInfo *reg, uint64_t val64)
351
+{
352
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
353
+
354
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU0, val64, s->cfg.cpu_r5[0]);
355
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU1, val64, s->cfg.cpu_r5[1]);
356
+ return val64;
357
+}
358
+
359
+static uint64_t crl_rst_adma_prew(RegisterInfo *reg, uint64_t val64)
360
+{
361
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
362
+ int i;
363
+
364
+ /* A single register fans out to all ADMA reset inputs. */
365
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); i++) {
366
+ REGFIELD_RESET(dev, s, RST_ADMA, RESET, val64, s->cfg.adma[i]);
367
+ }
368
+ return val64;
369
+}
370
+
371
+static uint64_t crl_rst_uart0_prew(RegisterInfo *reg, uint64_t val64)
372
+{
373
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
374
+
375
+ REGFIELD_RESET(dev, s, RST_UART0, RESET, val64, s->cfg.uart[0]);
376
+ return val64;
377
+}
378
+
379
+static uint64_t crl_rst_uart1_prew(RegisterInfo *reg, uint64_t val64)
380
+{
381
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
382
+
383
+ REGFIELD_RESET(dev, s, RST_UART1, RESET, val64, s->cfg.uart[1]);
384
+ return val64;
385
+}
386
+
387
+static uint64_t crl_rst_gem0_prew(RegisterInfo *reg, uint64_t val64)
388
+{
389
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
390
+
391
+ REGFIELD_RESET(dev, s, RST_GEM0, RESET, val64, s->cfg.gem[0]);
392
+ return val64;
393
+}
394
+
395
+static uint64_t crl_rst_gem1_prew(RegisterInfo *reg, uint64_t val64)
396
+{
397
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
398
+
399
+ REGFIELD_RESET(dev, s, RST_GEM1, RESET, val64, s->cfg.gem[1]);
400
+ return val64;
401
+}
402
+
403
+static uint64_t crl_rst_usb_prew(RegisterInfo *reg, uint64_t val64)
404
+{
405
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
406
+
407
+ REGFIELD_RESET(dev, s, RST_USB0, RESET, val64, s->cfg.usb);
408
+ return val64;
409
+}
410
+
411
+static const RegisterAccessInfo crl_regs_info[] = {
412
+ { .name = "ERR_CTRL", .addr = A_ERR_CTRL,
413
+ },{ .name = "IR_STATUS", .addr = A_IR_STATUS,
414
+ .w1c = 0x1,
415
+ .post_write = crl_status_postw,
416
+ },{ .name = "IR_MASK", .addr = A_IR_MASK,
417
+ .reset = 0x1,
418
+ .ro = 0x1,
419
+ },{ .name = "IR_ENABLE", .addr = A_IR_ENABLE,
420
+ .pre_write = crl_enable_prew,
421
+ },{ .name = "IR_DISABLE", .addr = A_IR_DISABLE,
422
+ .pre_write = crl_disable_prew,
423
+ },{ .name = "WPROT", .addr = A_WPROT,
424
+ },{ .name = "PLL_CLK_OTHER_DMN", .addr = A_PLL_CLK_OTHER_DMN,
425
+ .reset = 0x1,
426
+ .rsvd = 0xe,
427
+ },{ .name = "RPLL_CTRL", .addr = A_RPLL_CTRL,
428
+ .reset = 0x24809,
429
+ .rsvd = 0xf88c00f6,
430
+ },{ .name = "RPLL_CFG", .addr = A_RPLL_CFG,
431
+ .reset = 0x2000000,
432
+ .rsvd = 0x1801210,
433
+ },{ .name = "RPLL_FRAC_CFG", .addr = A_RPLL_FRAC_CFG,
434
+ .rsvd = 0x7e330000,
435
+ },{ .name = "PLL_STATUS", .addr = A_PLL_STATUS,
436
+ .reset = R_PLL_STATUS_RPLL_STABLE_MASK |
437
+ R_PLL_STATUS_RPLL_LOCK_MASK,
438
+ .rsvd = 0xfa,
439
+ .ro = 0x5,
440
+ },{ .name = "RPLL_TO_XPD_CTRL", .addr = A_RPLL_TO_XPD_CTRL,
441
+ .reset = 0x2000100,
442
+ .rsvd = 0xfdfc00ff,
443
+ },{ .name = "LPD_TOP_SWITCH_CTRL", .addr = A_LPD_TOP_SWITCH_CTRL,
444
+ .reset = 0x6000300,
445
+ .rsvd = 0xf9fc00f8,
446
+ },{ .name = "LPD_LSBUS_CTRL", .addr = A_LPD_LSBUS_CTRL,
447
+ .reset = 0x2000800,
448
+ .rsvd = 0xfdfc00f8,
449
+ },{ .name = "CPU_R5_CTRL", .addr = A_CPU_R5_CTRL,
450
+ .reset = 0xe000300,
451
+ .rsvd = 0xe1fc00f8,
452
+ },{ .name = "IOU_SWITCH_CTRL", .addr = A_IOU_SWITCH_CTRL,
453
+ .reset = 0x2000500,
454
+ .rsvd = 0xfdfc00f8,
455
+ },{ .name = "GEM0_REF_CTRL", .addr = A_GEM0_REF_CTRL,
456
+ .reset = 0xe000a00,
457
+ .rsvd = 0xf1fc00f8,
458
+ },{ .name = "GEM1_REF_CTRL", .addr = A_GEM1_REF_CTRL,
459
+ .reset = 0xe000a00,
460
+ .rsvd = 0xf1fc00f8,
461
+ },{ .name = "GEM_TSU_REF_CTRL", .addr = A_GEM_TSU_REF_CTRL,
462
+ .reset = 0x300,
463
+ .rsvd = 0xfdfc00f8,
464
+ },{ .name = "USB0_BUS_REF_CTRL", .addr = A_USB0_BUS_REF_CTRL,
465
+ .reset = 0x2001900,
466
+ .rsvd = 0xfdfc00f8,
467
+ },{ .name = "UART0_REF_CTRL", .addr = A_UART0_REF_CTRL,
468
+ .reset = 0xc00,
469
+ .rsvd = 0xfdfc00f8,
470
+ },{ .name = "UART1_REF_CTRL", .addr = A_UART1_REF_CTRL,
471
+ .reset = 0xc00,
472
+ .rsvd = 0xfdfc00f8,
473
+ },{ .name = "SPI0_REF_CTRL", .addr = A_SPI0_REF_CTRL,
474
+ .reset = 0x600,
475
+ .rsvd = 0xfdfc00f8,
476
+ },{ .name = "SPI1_REF_CTRL", .addr = A_SPI1_REF_CTRL,
477
+ .reset = 0x600,
478
+ .rsvd = 0xfdfc00f8,
479
+ },{ .name = "CAN0_REF_CTRL", .addr = A_CAN0_REF_CTRL,
480
+ .reset = 0xc00,
481
+ .rsvd = 0xfdfc00f8,
482
+ },{ .name = "CAN1_REF_CTRL", .addr = A_CAN1_REF_CTRL,
483
+ .reset = 0xc00,
484
+ .rsvd = 0xfdfc00f8,
485
+ },{ .name = "I2C0_REF_CTRL", .addr = A_I2C0_REF_CTRL,
486
+ .reset = 0xc00,
487
+ .rsvd = 0xfdfc00f8,
488
+ },{ .name = "I2C1_REF_CTRL", .addr = A_I2C1_REF_CTRL,
489
+ .reset = 0xc00,
490
+ .rsvd = 0xfdfc00f8,
491
+ },{ .name = "DBG_LPD_CTRL", .addr = A_DBG_LPD_CTRL,
492
+ .reset = 0x300,
493
+ .rsvd = 0xfdfc00f8,
494
+ },{ .name = "TIMESTAMP_REF_CTRL", .addr = A_TIMESTAMP_REF_CTRL,
495
+ .reset = 0x2000c00,
496
+ .rsvd = 0xfdfc00f8,
497
+ },{ .name = "CRL_SAFETY_CHK", .addr = A_CRL_SAFETY_CHK,
498
+ },{ .name = "PSM_REF_CTRL", .addr = A_PSM_REF_CTRL,
499
+ .reset = 0xf04,
500
+ .rsvd = 0xfffc00f8,
501
+ },{ .name = "DBG_TSTMP_CTRL", .addr = A_DBG_TSTMP_CTRL,
502
+ .reset = 0x300,
503
+ .rsvd = 0xfdfc00f8,
504
+ },{ .name = "CPM_TOPSW_REF_CTRL", .addr = A_CPM_TOPSW_REF_CTRL,
505
+ .reset = 0x300,
506
+ .rsvd = 0xfdfc00f8,
507
+ },{ .name = "USB3_DUAL_REF_CTRL", .addr = A_USB3_DUAL_REF_CTRL,
508
+ .reset = 0x3c00,
509
+ .rsvd = 0xfdfc00f8,
510
+ },{ .name = "RST_CPU_R5", .addr = A_RST_CPU_R5,
511
+ .reset = 0x17,
512
+ .rsvd = 0x8,
513
+ .pre_write = crl_rst_r5_prew,
514
+ },{ .name = "RST_ADMA", .addr = A_RST_ADMA,
515
+ .reset = 0x1,
516
+ .pre_write = crl_rst_adma_prew,
517
+ },{ .name = "RST_GEM0", .addr = A_RST_GEM0,
518
+ .reset = 0x1,
519
+ .pre_write = crl_rst_gem0_prew,
520
+ },{ .name = "RST_GEM1", .addr = A_RST_GEM1,
521
+ .reset = 0x1,
522
+ .pre_write = crl_rst_gem1_prew,
523
+ },{ .name = "RST_SPARE", .addr = A_RST_SPARE,
524
+ .reset = 0x1,
525
+ },{ .name = "RST_USB0", .addr = A_RST_USB0,
526
+ .reset = 0x1,
527
+ .pre_write = crl_rst_usb_prew,
528
+ },{ .name = "RST_UART0", .addr = A_RST_UART0,
529
+ .reset = 0x1,
530
+ .pre_write = crl_rst_uart0_prew,
531
+ },{ .name = "RST_UART1", .addr = A_RST_UART1,
532
+ .reset = 0x1,
533
+ .pre_write = crl_rst_uart1_prew,
534
+ },{ .name = "RST_SPI0", .addr = A_RST_SPI0,
535
+ .reset = 0x1,
536
+ },{ .name = "RST_SPI1", .addr = A_RST_SPI1,
537
+ .reset = 0x1,
538
+ },{ .name = "RST_CAN0", .addr = A_RST_CAN0,
539
+ .reset = 0x1,
540
+ },{ .name = "RST_CAN1", .addr = A_RST_CAN1,
541
+ .reset = 0x1,
542
+ },{ .name = "RST_I2C0", .addr = A_RST_I2C0,
543
+ .reset = 0x1,
544
+ },{ .name = "RST_I2C1", .addr = A_RST_I2C1,
545
+ .reset = 0x1,
546
+ },{ .name = "RST_DBG_LPD", .addr = A_RST_DBG_LPD,
547
+ .reset = 0x33,
548
+ .rsvd = 0xcc,
549
+ },{ .name = "RST_GPIO", .addr = A_RST_GPIO,
550
+ .reset = 0x1,
551
+ },{ .name = "RST_TTC", .addr = A_RST_TTC,
552
+ .reset = 0xf,
553
+ },{ .name = "RST_TIMESTAMP", .addr = A_RST_TIMESTAMP,
554
+ .reset = 0x1,
555
+ },{ .name = "RST_SWDT", .addr = A_RST_SWDT,
556
+ .reset = 0x1,
557
+ },{ .name = "RST_OCM", .addr = A_RST_OCM,
558
+ },{ .name = "RST_IPI", .addr = A_RST_IPI,
559
+ },{ .name = "RST_FPD", .addr = A_RST_FPD,
560
+ .reset = 0x3,
561
+ },{ .name = "PSM_RST_MODE", .addr = A_PSM_RST_MODE,
562
+ .reset = 0x1,
563
+ .rsvd = 0xf8,
564
+ }
565
+};
566
+
567
+static void crl_reset_enter(Object *obj, ResetType type)
568
+{
569
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
570
+ unsigned int i;
571
+
572
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
573
+ register_reset(&s->regs_info[i]);
574
+ }
575
+}
576
+
577
+static void crl_reset_hold(Object *obj)
578
+{
579
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
580
+
581
+ crl_update_irq(s);
582
+}
583
+
584
+static const MemoryRegionOps crl_ops = {
585
+ .read = register_read_memory,
586
+ .write = register_write_memory,
587
+ .endianness = DEVICE_LITTLE_ENDIAN,
588
+ .valid = {
589
+ .min_access_size = 4,
590
+ .max_access_size = 4,
591
+ },
592
+};
593
+
594
+static void crl_init(Object *obj)
595
+{
596
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
597
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
598
+ int i;
599
+
600
+ s->reg_array =
601
+ register_init_block32(DEVICE(obj), crl_regs_info,
602
+ ARRAY_SIZE(crl_regs_info),
603
+ s->regs_info, s->regs,
604
+ &crl_ops,
605
+ XLNX_VERSAL_CRL_ERR_DEBUG,
606
+ CRL_R_MAX * 4);
607
+ sysbus_init_mmio(sbd, &s->reg_array->mem);
608
+ sysbus_init_irq(sbd, &s->irq);
609
+
610
+ for (i = 0; i < ARRAY_SIZE(s->cfg.cpu_r5); ++i) {
611
+ object_property_add_link(obj, "cpu_r5[*]", TYPE_ARM_CPU,
612
+ (Object **)&s->cfg.cpu_r5[i],
613
+ qdev_prop_allow_set_link_before_realize,
614
+ OBJ_PROP_LINK_STRONG);
615
+ }
616
+
617
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); ++i) {
618
+ object_property_add_link(obj, "adma[*]", TYPE_DEVICE,
619
+ (Object **)&s->cfg.adma[i],
620
+ qdev_prop_allow_set_link_before_realize,
621
+ OBJ_PROP_LINK_STRONG);
622
+ }
623
+
624
+ for (i = 0; i < ARRAY_SIZE(s->cfg.uart); ++i) {
625
+ object_property_add_link(obj, "uart[*]", TYPE_DEVICE,
626
+ (Object **)&s->cfg.uart[i],
627
+ qdev_prop_allow_set_link_before_realize,
628
+ OBJ_PROP_LINK_STRONG);
629
+ }
630
+
631
+ for (i = 0; i < ARRAY_SIZE(s->cfg.gem); ++i) {
632
+ object_property_add_link(obj, "gem[*]", TYPE_DEVICE,
633
+ (Object **)&s->cfg.gem[i],
634
+ qdev_prop_allow_set_link_before_realize,
635
+ OBJ_PROP_LINK_STRONG);
636
+ }
637
+
638
+ object_property_add_link(obj, "usb", TYPE_DEVICE,
639
+ (Object **)&s->cfg.gem[i],
640
+ qdev_prop_allow_set_link_before_realize,
641
+ OBJ_PROP_LINK_STRONG);
642
+}
643
+
644
+static void crl_finalize(Object *obj)
645
+{
646
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
647
+ register_finalize_block(s->reg_array);
648
+}
649
+
650
+static const VMStateDescription vmstate_crl = {
651
+ .name = TYPE_XLNX_VERSAL_CRL,
652
+ .version_id = 1,
653
+ .minimum_version_id = 1,
654
+ .fields = (VMStateField[]) {
655
+ VMSTATE_UINT32_ARRAY(regs, XlnxVersalCRL, CRL_R_MAX),
656
+ VMSTATE_END_OF_LIST(),
657
+ }
658
+};
659
+
660
+static void crl_class_init(ObjectClass *klass, void *data)
661
+{
662
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
663
+ DeviceClass *dc = DEVICE_CLASS(klass);
664
+
665
+ dc->vmsd = &vmstate_crl;
666
+
667
+ rc->phases.enter = crl_reset_enter;
668
+ rc->phases.hold = crl_reset_hold;
669
+}
670
+
671
+static const TypeInfo crl_info = {
672
+ .name = TYPE_XLNX_VERSAL_CRL,
673
+ .parent = TYPE_SYS_BUS_DEVICE,
674
+ .instance_size = sizeof(XlnxVersalCRL),
675
+ .class_init = crl_class_init,
676
+ .instance_init = crl_init,
677
+ .instance_finalize = crl_finalize,
678
+};
679
+
680
+static void crl_register_types(void)
681
+{
682
+ type_register_static(&crl_info);
683
+}
684
+
685
+type_init(crl_register_types)
686
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
687
index XXXXXXX..XXXXXXX 100644
688
--- a/hw/misc/meson.build
689
+++ b/hw/misc/meson.build
690
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
691
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
692
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-crf.c'))
693
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-apu-ctrl.c'))
694
+specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-crl.c'))
695
softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
696
'xlnx-versal-xramc.c',
697
'xlnx-versal-pmc-iou-slcr.c',
698
--
306
--
699
2.25.1
307
2.25.1
diff view generated by jsdifflib
1
The exynos4210 code currently has two very similar arrays of IRQs:
1
When we're using KVM, the PSCI implementation is provided by the
2
kernel, but QEMU has to tell the guest about it via the device tree.
3
Currently we look at the KVM_CAP_ARM_PSCI_0_2 capability to determine
4
if the kernel is providing at least PSCI 0.2, but if the kernel
5
provides a newer version than that we will still only tell the guest
6
it has PSCI 0.2. (This is fairly harmless; it just means the guest
7
won't use newer parts of the PSCI API.)
2
8
3
* board_irqs is a field of the Exynos4210Irq struct which is filled
9
The kernel exposes the specific PSCI version it is implementing via
4
in by exynos4210_init_board_irqs() with the appropriate qemu_irqs
10
the ONE_REG API; use this to report in the dtb that the PSCI
5
for each IRQ the board/SoC can assert
11
implementation is 1.0-compatible if appropriate. (The device tree
6
* irq_table is a set of qemu_irqs pointed to from the
12
binding currently only distinguishes "pre-0.2", "0.2-compatible" and
7
Exynos4210State struct. It's allocated in exynos4210_init_irq,
13
"1.0-compatible".)
8
and the only behaviour these irqs have is that they pass on the
9
level to the equivalent board_irqs[] irq
10
11
The extra indirection through irq_table is unnecessary, so coalesce
12
these into a single irq_table[] array as a direct field in
13
Exynos4210State which exynos4210_init_board_irqs() fills in.
14
14
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Marc Zyngier <maz@kernel.org>
17
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20220404154658.565020-6-peter.maydell@linaro.org
19
Reviewed-by: Andrew Jones <drjones@redhat.com>
20
Message-id: 20220224134655.1207865-1-peter.maydell@linaro.org
18
---
21
---
19
include/hw/arm/exynos4210.h | 8 ++------
22
target/arm/kvm-consts.h | 1 +
20
hw/arm/exynos4210.c | 6 +-----
23
hw/arm/boot.c | 5 ++---
21
hw/intc/exynos4210_gic.c | 32 ++++++++------------------------
24
target/arm/kvm64.c | 12 ++++++++++++
22
3 files changed, 11 insertions(+), 35 deletions(-)
25
3 files changed, 15 insertions(+), 3 deletions(-)
23
26
24
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
27
diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h
25
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/arm/exynos4210.h
29
--- a/target/arm/kvm-consts.h
27
+++ b/include/hw/arm/exynos4210.h
30
+++ b/target/arm/kvm-consts.h
28
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210Irq {
31
@@ -XXX,XX +XXX,XX @@ MISMATCH_CHECK(QEMU_PSCI_1_0_FN_PSCI_FEATURES, PSCI_1_0_FN_PSCI_FEATURES);
29
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
32
30
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
33
#define QEMU_PSCI_VERSION_0_1 0x00001
31
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
34
#define QEMU_PSCI_VERSION_0_2 0x00002
32
- qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
35
+#define QEMU_PSCI_VERSION_1_0 0x10000
33
} Exynos4210Irq;
36
#define QEMU_PSCI_VERSION_1_1 0x10001
34
37
35
struct Exynos4210State {
38
MISMATCH_CHECK(QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED, PSCI_0_2_TOS_MP);
36
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
39
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
37
/*< public >*/
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
39
Exynos4210Irq irqs;
40
- qemu_irq *irq_table;
41
+ qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
42
43
MemoryRegion chipid_mem;
44
MemoryRegion iram_mem;
45
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
46
void exynos4210_write_secondary(ARMCPU *cpu,
47
const struct arm_boot_info *info);
48
49
-/* Initialize exynos4210 IRQ subsystem stub */
50
-qemu_irq *exynos4210_init_irq(Exynos4210Irq *env);
51
-
52
/* Initialize board IRQs.
53
* These IRQs contain splitted Int/External Combiner and External Gic IRQs */
54
-void exynos4210_init_board_irqs(Exynos4210Irq *s);
55
+void exynos4210_init_board_irqs(Exynos4210State *s);
56
57
/* Get IRQ number from exynos4210 IRQ subsystem stub.
58
* To identify IRQ source use internal combiner group and bit number
59
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
60
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/exynos4210.c
41
--- a/hw/arm/boot.c
62
+++ b/hw/arm/exynos4210.c
42
+++ b/hw/arm/boot.c
63
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
43
@@ -XXX,XX +XXX,XX @@ static void fdt_add_psci_node(void *fdt)
64
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
65
}
44
}
66
45
67
- /*** IRQs ***/
46
qemu_fdt_add_subnode(fdt, "/psci");
68
-
47
- if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2 ||
69
- s->irq_table = exynos4210_init_irq(&s->irqs);
48
- armcpu->psci_version == QEMU_PSCI_VERSION_1_1) {
70
-
49
- if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2) {
71
/* IRQ Gate */
50
+ if (armcpu->psci_version >= QEMU_PSCI_VERSION_0_2) {
72
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
51
+ if (armcpu->psci_version < QEMU_PSCI_VERSION_1_0) {
73
DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
52
const char comp[] = "arm,psci-0.2\0arm,psci";
74
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
53
qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
75
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
54
} else {
76
55
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
77
/* Initialize board IRQs. */
78
- exynos4210_init_board_irqs(&s->irqs);
79
+ exynos4210_init_board_irqs(s);
80
81
/*** Memory ***/
82
83
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
84
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
85
--- a/hw/intc/exynos4210_gic.c
57
--- a/target/arm/kvm64.c
86
+++ b/hw/intc/exynos4210_gic.c
58
+++ b/target/arm/kvm64.c
87
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
59
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
88
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
60
uint64_t mpidr;
89
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
61
ARMCPU *cpu = ARM_CPU(cs);
90
62
CPUARMState *env = &cpu->env;
91
-static void exynos4210_irq_handler(void *opaque, int irq, int level)
63
+ uint64_t psciver;
92
-{
64
93
- Exynos4210Irq *s = (Exynos4210Irq *)opaque;
65
if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE ||
94
-
66
!object_dynamic_cast(OBJECT(cpu), TYPE_AARCH64_CPU)) {
95
- /* Bypass */
67
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
96
- qemu_set_irq(s->board_irqs[irq], level);
97
-}
98
-
99
-/*
100
- * Initialize exynos4210 IRQ subsystem stub.
101
- */
102
-qemu_irq *exynos4210_init_irq(Exynos4210Irq *s)
103
-{
104
- return qemu_allocate_irqs(exynos4210_irq_handler, s,
105
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ);
106
-}
107
-
108
/*
109
* Initialize board IRQs.
110
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
111
*/
112
-void exynos4210_init_board_irqs(Exynos4210Irq *s)
113
+void exynos4210_init_board_irqs(Exynos4210State *s)
114
{
115
uint32_t grp, bit, irq_id, n;
116
+ Exynos4210Irq *is = &s->irqs;
117
118
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
119
irq_id = 0;
120
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
121
irq_id = EXT_GIC_ID_MCT_G1;
122
}
123
if (irq_id) {
124
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
125
- s->ext_gic_irq[irq_id-32]);
126
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
127
+ is->ext_gic_irq[irq_id - 32]);
128
} else {
129
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
130
- s->ext_combiner_irq[n]);
131
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
132
+ is->ext_combiner_irq[n]);
133
}
68
}
134
}
69
}
135
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
70
136
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
71
+ /*
137
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
72
+ * KVM reports the exact PSCI version it is implementing via a
138
73
+ * special sysreg. If it is present, use its contents to determine
139
if (irq_id) {
74
+ * what to report to the guest in the dtb (it is the PSCI version,
140
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
75
+ * in the same 15-bits major 16-bits minor format that PSCI_VERSION
141
- s->ext_gic_irq[irq_id-32]);
76
+ * returns).
142
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
77
+ */
143
+ is->ext_gic_irq[irq_id - 32]);
78
+ if (!kvm_get_one_reg(cs, KVM_REG_ARM_PSCI_VERSION, &psciver)) {
144
}
79
+ cpu->psci_version = psciver;
145
}
80
+ }
146
}
81
+
82
/*
83
* When KVM is in use, PSCI is emulated in-kernel and not by qemu.
84
* Currently KVM has its own idea about MPIDR assignment, so we
147
--
85
--
148
2.25.1
86
2.25.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
The updateUIInfo method makes Cocoa API calls. It also calls back
2
into QEMU functions like dpy_set_ui_info(). To do this safely, we
3
need to follow two rules:
4
* Cocoa API calls are made on the Cocoa UI thread
5
* When calling back into QEMU we must hold the iothread lock
2
6
3
Add the Cortex-R5Fs of the Versal RPU (Real-time Processing Unit)
7
Fix the places where we got this wrong, by taking the iothread lock
4
subsystem.
8
while executing updateUIInfo, and moving the call in cocoa_switch()
9
inside the dispatch_async block.
5
10
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
11
Some of the Cocoa UI methods which call updateUIInfo are invoked as
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
12
part of the initial application startup, while we're still doing the
8
Message-id: 20220406174303.2022038-3-edgar.iglesias@xilinx.com
13
little cross-thread dance described in the comment just above
14
call_qemu_main(). This meant they were calling back into the QEMU UI
15
layer before we'd actually finished initializing our display and
16
registered the DisplayChangeListener, which isn't really valid. Once
17
updateUIInfo takes the iothread lock, we no longer get away with
18
this, because during this startup phase the iothread lock is held by
19
the QEMU main-loop thread which is waiting for us to finish our
20
display initialization. So we must suppress updateUIInfo until
21
applicationDidFinishLaunching allows the QEMU main-loop thread to
22
continue.
23
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
26
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
27
Message-id: 20220224101330.967429-2-peter.maydell@linaro.org
10
---
28
---
11
include/hw/arm/xlnx-versal.h | 10 ++++++++++
29
ui/cocoa.m | 25 ++++++++++++++++++++++---
12
hw/arm/xlnx-versal-virt.c | 6 +++---
30
1 file changed, 22 insertions(+), 3 deletions(-)
13
hw/arm/xlnx-versal.c | 36 ++++++++++++++++++++++++++++++++++++
14
3 files changed, 49 insertions(+), 3 deletions(-)
15
31
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
32
diff --git a/ui/cocoa.m b/ui/cocoa.m
17
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
34
--- a/ui/cocoa.m
19
+++ b/include/hw/arm/xlnx-versal.h
35
+++ b/ui/cocoa.m
20
@@ -XXX,XX +XXX,XX @@
36
@@ -XXX,XX +XXX,XX @@ QemuCocoaView *cocoaView;
21
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
22
23
#define XLNX_VERSAL_NR_ACPUS 2
24
+#define XLNX_VERSAL_NR_RCPUS 2
25
#define XLNX_VERSAL_NR_UARTS 2
26
#define XLNX_VERSAL_NR_GEMS 2
27
#define XLNX_VERSAL_NR_ADMAS 8
28
@@ -XXX,XX +XXX,XX @@ struct Versal {
29
VersalUsb2 usb;
30
} iou;
31
32
+ /* Real-time Processing Unit. */
33
+ struct {
34
+ MemoryRegion mr;
35
+ MemoryRegion mr_ps_alias;
36
+
37
+ CPUClusterState cluster;
38
+ ARMCPU cpu[XLNX_VERSAL_NR_RCPUS];
39
+ } rpu;
40
+
41
struct {
42
qemu_or_irq irq_orgate;
43
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
44
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/xlnx-versal-virt.c
47
+++ b/hw/arm/xlnx-versal-virt.c
48
@@ -XXX,XX +XXX,XX @@ static void versal_virt_machine_class_init(ObjectClass *oc, void *data)
49
50
mc->desc = "Xilinx Versal Virtual development board";
51
mc->init = versal_virt_init;
52
- mc->min_cpus = XLNX_VERSAL_NR_ACPUS;
53
- mc->max_cpus = XLNX_VERSAL_NR_ACPUS;
54
- mc->default_cpus = XLNX_VERSAL_NR_ACPUS;
55
+ mc->min_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
56
+ mc->max_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
57
+ mc->default_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
58
mc->no_cdrom = true;
59
mc->default_ram_id = "ddr";
60
}
61
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/xlnx-versal.c
64
+++ b/hw/arm/xlnx-versal.c
65
@@ -XXX,XX +XXX,XX @@
66
#include "hw/sysbus.h"
67
68
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
69
+#define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f")
70
#define GEM_REVISION 0x40070106
71
72
#define VERSAL_NUM_PMC_APB_IRQS 3
73
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
74
}
37
}
75
}
38
}
76
39
77
+static void versal_create_rpu_cpus(Versal *s)
40
-- (void) updateUIInfo
41
+- (void) updateUIInfoLocked
42
{
43
+ /* Must be called with the iothread lock, i.e. via updateUIInfo */
44
NSSize frameSize;
45
QemuUIInfo info;
46
47
@@ -XXX,XX +XXX,XX @@ QemuCocoaView *cocoaView;
48
dpy_set_ui_info(dcl.con, &info, TRUE);
49
}
50
51
+- (void) updateUIInfo
78
+{
52
+{
79
+ int i;
53
+ if (!allow_events) {
80
+
54
+ /*
81
+ object_initialize_child(OBJECT(s), "rpu-cluster", &s->lpd.rpu.cluster,
55
+ * Don't try to tell QEMU about UI information in the application
82
+ TYPE_CPU_CLUSTER);
56
+ * startup phase -- we haven't yet registered dcl with the QEMU UI
83
+ qdev_prop_set_uint32(DEVICE(&s->lpd.rpu.cluster), "cluster-id", 1);
57
+ * layer, and also trying to take the iothread lock would deadlock.
84
+
58
+ * When cocoa_display_init() does register the dcl, the UI layer
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
59
+ * will call cocoa_switch(), which will call updateUIInfo, so
86
+ Object *obj;
60
+ * we don't lose any information here.
87
+
61
+ */
88
+ object_initialize_child(OBJECT(&s->lpd.rpu.cluster),
62
+ return;
89
+ "rpu-cpu[*]", &s->lpd.rpu.cpu[i],
90
+ XLNX_VERSAL_RCPU_TYPE);
91
+ obj = OBJECT(&s->lpd.rpu.cpu[i]);
92
+ object_property_set_bool(obj, "start-powered-off", true,
93
+ &error_abort);
94
+
95
+ object_property_set_int(obj, "mp-affinity", 0x100 | i, &error_abort);
96
+ object_property_set_int(obj, "core-count", ARRAY_SIZE(s->lpd.rpu.cpu),
97
+ &error_abort);
98
+ object_property_set_link(obj, "memory", OBJECT(&s->lpd.rpu.mr),
99
+ &error_abort);
100
+ qdev_realize(DEVICE(obj), NULL, &error_fatal);
101
+ }
63
+ }
102
+
64
+
103
+ qdev_realize(DEVICE(&s->lpd.rpu.cluster), NULL, &error_fatal);
65
+ with_iothread_lock(^{
66
+ [self updateUIInfoLocked];
67
+ });
104
+}
68
+}
105
+
69
+
106
static void versal_create_uarts(Versal *s, qemu_irq *pic)
70
- (void)viewDidMoveToWindow
107
{
71
{
108
int i;
72
[self updateUIInfo];
109
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
73
@@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl,
110
74
111
versal_create_apu_cpus(s);
75
COCOA_DEBUG("qemu_cocoa: cocoa_switch\n");
112
versal_create_apu_gic(s, pic);
76
113
+ versal_create_rpu_cpus(s);
77
- [cocoaView updateUIInfo];
114
versal_create_uarts(s, pic);
78
-
115
versal_create_usbs(s, pic);
79
// The DisplaySurface will be freed as soon as this callback returns.
116
versal_create_gems(s, pic);
80
// We take a reference to the underlying pixman image here so it does
117
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
81
// not disappear from under our feet; the switchSurface method will
118
82
@@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl,
119
memory_region_add_subregion_overlap(&s->mr_ps, MM_OCM, &s->lpd.mr_ocm, 0);
83
pixman_image_ref(image);
120
memory_region_add_subregion_overlap(&s->fpd.apu.mr, 0, &s->mr_ps, 0);
84
121
+ memory_region_add_subregion_overlap(&s->lpd.rpu.mr, 0,
85
dispatch_async(dispatch_get_main_queue(), ^{
122
+ &s->lpd.rpu.mr_ps_alias, 0);
86
+ [cocoaView updateUIInfo];
123
}
87
[cocoaView switchSurface:image];
124
88
});
125
static void versal_init(Object *obj)
89
[pool release];
126
@@ -XXX,XX +XXX,XX @@ static void versal_init(Object *obj)
127
Versal *s = XLNX_VERSAL(obj);
128
129
memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
130
+ memory_region_init(&s->lpd.rpu.mr, obj, "mr-rpu", UINT64_MAX);
131
memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX);
132
+ memory_region_init_alias(&s->lpd.rpu.mr_ps_alias, OBJECT(s),
133
+ "mr-rpu-ps-alias", &s->mr_ps, 0, UINT64_MAX);
134
}
135
136
static Property versal_properties[] = {
137
--
90
--
138
2.25.1
91
2.25.1
diff view generated by jsdifflib
1
Now we have removed the only use of TYPE_EXYNOS4210_IRQ_GATE we can
1
In commit 6e657e64cdc478 in 2013 we added some autorelease pools to
2
delete the device entirely.
2
deal with complaints from macOS when we made calls into Cocoa from
3
threads that didn't have automatically created autorelease pools.
4
Later on, macOS got stricter about forbidding cross-thread Cocoa
5
calls, and in commit 5588840ff77800e839d8 we restructured the code to
6
avoid them. This left the autorelease pool creation in several
7
functions without any purpose; delete it.
8
9
We still need the pool in cocoa_refresh() for the clipboard related
10
code which is called directly there.
3
11
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
13
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
6
Message-id: 20220404154658.565020-3-peter.maydell@linaro.org
14
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
15
Message-id: 20220224101330.967429-3-peter.maydell@linaro.org
7
---
16
---
8
hw/intc/exynos4210_gic.c | 107 ---------------------------------------
17
ui/cocoa.m | 6 ------
9
1 file changed, 107 deletions(-)
18
1 file changed, 6 deletions(-)
10
19
11
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
20
diff --git a/ui/cocoa.m b/ui/cocoa.m
12
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/intc/exynos4210_gic.c
22
--- a/ui/cocoa.m
14
+++ b/hw/intc/exynos4210_gic.c
23
+++ b/ui/cocoa.m
15
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_register_types(void)
24
@@ -XXX,XX +XXX,XX @@ int main (int argc, char **argv) {
25
static void cocoa_update(DisplayChangeListener *dcl,
26
int x, int y, int w, int h)
27
{
28
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
29
-
30
COCOA_DEBUG("qemu_cocoa: cocoa_update\n");
31
32
dispatch_async(dispatch_get_main_queue(), ^{
33
@@ -XXX,XX +XXX,XX @@ static void cocoa_update(DisplayChangeListener *dcl,
34
}
35
[cocoaView setNeedsDisplayInRect:rect];
36
});
37
-
38
- [pool release];
16
}
39
}
17
40
18
type_init(exynos4210_gic_register_types)
41
static void cocoa_switch(DisplayChangeListener *dcl,
19
-
42
DisplaySurface *surface)
20
-/* IRQ OR Gate struct.
43
{
21
- *
44
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
22
- * This device models an OR gate. There are n_in input qdev gpio lines and one
45
pixman_image_t *image = surface->image;
23
- * output sysbus IRQ line. The output IRQ level is formed as OR between all
46
24
- * gpio inputs.
47
COCOA_DEBUG("qemu_cocoa: cocoa_switch\n");
25
- */
48
@@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl,
26
-
49
[cocoaView updateUIInfo];
27
-#define TYPE_EXYNOS4210_IRQ_GATE "exynos4210.irq_gate"
50
[cocoaView switchSurface:image];
28
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210IRQGateState, EXYNOS4210_IRQ_GATE)
51
});
29
-
52
- [pool release];
30
-struct Exynos4210IRQGateState {
53
}
31
- SysBusDevice parent_obj;
54
32
-
55
static void cocoa_refresh(DisplayChangeListener *dcl)
33
- uint32_t n_in; /* inputs amount */
34
- uint32_t *level; /* input levels */
35
- qemu_irq out; /* output IRQ */
36
-};
37
-
38
-static Property exynos4210_irq_gate_properties[] = {
39
- DEFINE_PROP_UINT32("n_in", Exynos4210IRQGateState, n_in, 1),
40
- DEFINE_PROP_END_OF_LIST(),
41
-};
42
-
43
-static const VMStateDescription vmstate_exynos4210_irq_gate = {
44
- .name = "exynos4210.irq_gate",
45
- .version_id = 2,
46
- .minimum_version_id = 2,
47
- .fields = (VMStateField[]) {
48
- VMSTATE_VBUFFER_UINT32(level, Exynos4210IRQGateState, 1, NULL, n_in),
49
- VMSTATE_END_OF_LIST()
50
- }
51
-};
52
-
53
-/* Process a change in IRQ input. */
54
-static void exynos4210_irq_gate_handler(void *opaque, int irq, int level)
55
-{
56
- Exynos4210IRQGateState *s = (Exynos4210IRQGateState *)opaque;
57
- uint32_t i;
58
-
59
- assert(irq < s->n_in);
60
-
61
- s->level[irq] = level;
62
-
63
- for (i = 0; i < s->n_in; i++) {
64
- if (s->level[i] >= 1) {
65
- qemu_irq_raise(s->out);
66
- return;
67
- }
68
- }
69
-
70
- qemu_irq_lower(s->out);
71
-}
72
-
73
-static void exynos4210_irq_gate_reset(DeviceState *d)
74
-{
75
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(d);
76
-
77
- memset(s->level, 0, s->n_in * sizeof(*s->level));
78
-}
79
-
80
-/*
81
- * IRQ Gate initialization.
82
- */
83
-static void exynos4210_irq_gate_init(Object *obj)
84
-{
85
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(obj);
86
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
87
-
88
- sysbus_init_irq(sbd, &s->out);
89
-}
90
-
91
-static void exynos4210_irq_gate_realize(DeviceState *dev, Error **errp)
92
-{
93
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(dev);
94
-
95
- /* Allocate general purpose input signals and connect a handler to each of
96
- * them */
97
- qdev_init_gpio_in(dev, exynos4210_irq_gate_handler, s->n_in);
98
-
99
- s->level = g_malloc0(s->n_in * sizeof(*s->level));
100
-}
101
-
102
-static void exynos4210_irq_gate_class_init(ObjectClass *klass, void *data)
103
-{
104
- DeviceClass *dc = DEVICE_CLASS(klass);
105
-
106
- dc->reset = exynos4210_irq_gate_reset;
107
- dc->vmsd = &vmstate_exynos4210_irq_gate;
108
- device_class_set_props(dc, exynos4210_irq_gate_properties);
109
- dc->realize = exynos4210_irq_gate_realize;
110
-}
111
-
112
-static const TypeInfo exynos4210_irq_gate_info = {
113
- .name = TYPE_EXYNOS4210_IRQ_GATE,
114
- .parent = TYPE_SYS_BUS_DEVICE,
115
- .instance_size = sizeof(Exynos4210IRQGateState),
116
- .instance_init = exynos4210_irq_gate_init,
117
- .class_init = exynos4210_irq_gate_class_init,
118
-};
119
-
120
-static void exynos4210_irq_gate_register_types(void)
121
-{
122
- type_register_static(&exynos4210_irq_gate_info);
123
-}
124
-
125
-type_init(exynos4210_irq_gate_register_types)
126
--
56
--
127
2.25.1
57
2.25.1
diff view generated by jsdifflib
Deleted patch
1
The only time we use the int_gic_irq[] array in the Exynos4210Irq
2
struct is in the exynos4210_realize() function: we initialize it with
3
the GPIO inputs of the a9mpcore device, and then a bit later on we
4
connect those to the outputs of the internal combiner. Now that the
5
a9mpcore object is easily accessible as s->a9mpcore we can make the
6
connection directly from one device to the other without going via
7
this array.
8
1
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-5-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 1 -
14
hw/arm/exynos4210.c | 6 ++----
15
2 files changed, 2 insertions(+), 5 deletions(-)
16
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
20
+++ b/include/hw/arm/exynos4210.h
21
@@ -XXX,XX +XXX,XX @@
22
typedef struct Exynos4210Irq {
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
25
- qemu_irq int_gic_irq[EXYNOS4210_INT_GIC_NIRQ];
26
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
27
qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
28
} Exynos4210Irq;
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
32
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
34
sysbus_connect_irq(busdev, n,
35
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
36
}
37
- for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
38
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
39
- }
40
41
/* Cache controller */
42
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
43
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
44
busdev = SYS_BUS_DEVICE(dev);
45
sysbus_realize_and_unref(busdev, &error_fatal);
46
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
47
- sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
48
+ sysbus_connect_irq(busdev, n,
49
+ qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
50
}
51
exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
52
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
53
--
54
2.25.1
diff view generated by jsdifflib
Deleted patch
1
The function exynos4210_init_board_irqs() currently lives in
2
exynos4210_gic.c, but it isn't really part of the exynos4210.gic
3
device -- it is a function that implements (some of) the wiring up of
4
interrupts between the SoC's GIC and combiner components. This means
5
it fits better in exynos4210.c, which is the SoC-level code. Move it
6
there. Similarly, exynos4210_git_irq() is used almost only in the
7
SoC-level code, so move it too.
8
1
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-8-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 4 -
14
hw/arm/exynos4210.c | 202 +++++++++++++++++++++++++++++++++++
15
hw/intc/exynos4210_gic.c | 204 ------------------------------------
16
3 files changed, 202 insertions(+), 208 deletions(-)
17
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/exynos4210.h
21
+++ b/include/hw/arm/exynos4210.h
22
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
23
void exynos4210_write_secondary(ARMCPU *cpu,
24
const struct arm_boot_info *info);
25
26
-/* Initialize board IRQs.
27
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs */
28
-void exynos4210_init_board_irqs(Exynos4210State *s);
29
-
30
/* Get IRQ number from exynos4210 IRQ subsystem stub.
31
* To identify IRQ source use internal combiner group and bit number
32
* grp - group number
33
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/exynos4210.c
36
+++ b/hw/arm/exynos4210.c
37
@@ -XXX,XX +XXX,XX @@
38
#define EXYNOS4210_PL330_BASE1_ADDR 0x12690000
39
#define EXYNOS4210_PL330_BASE2_ADDR 0x12850000
40
41
+enum ExtGicId {
42
+ EXT_GIC_ID_MDMA_LCD0 = 66,
43
+ EXT_GIC_ID_PDMA0,
44
+ EXT_GIC_ID_PDMA1,
45
+ EXT_GIC_ID_TIMER0,
46
+ EXT_GIC_ID_TIMER1,
47
+ EXT_GIC_ID_TIMER2,
48
+ EXT_GIC_ID_TIMER3,
49
+ EXT_GIC_ID_TIMER4,
50
+ EXT_GIC_ID_MCT_L0,
51
+ EXT_GIC_ID_WDT,
52
+ EXT_GIC_ID_RTC_ALARM,
53
+ EXT_GIC_ID_RTC_TIC,
54
+ EXT_GIC_ID_GPIO_XB,
55
+ EXT_GIC_ID_GPIO_XA,
56
+ EXT_GIC_ID_MCT_L1,
57
+ EXT_GIC_ID_IEM_APC,
58
+ EXT_GIC_ID_IEM_IEC,
59
+ EXT_GIC_ID_NFC,
60
+ EXT_GIC_ID_UART0,
61
+ EXT_GIC_ID_UART1,
62
+ EXT_GIC_ID_UART2,
63
+ EXT_GIC_ID_UART3,
64
+ EXT_GIC_ID_UART4,
65
+ EXT_GIC_ID_MCT_G0,
66
+ EXT_GIC_ID_I2C0,
67
+ EXT_GIC_ID_I2C1,
68
+ EXT_GIC_ID_I2C2,
69
+ EXT_GIC_ID_I2C3,
70
+ EXT_GIC_ID_I2C4,
71
+ EXT_GIC_ID_I2C5,
72
+ EXT_GIC_ID_I2C6,
73
+ EXT_GIC_ID_I2C7,
74
+ EXT_GIC_ID_SPI0,
75
+ EXT_GIC_ID_SPI1,
76
+ EXT_GIC_ID_SPI2,
77
+ EXT_GIC_ID_MCT_G1,
78
+ EXT_GIC_ID_USB_HOST,
79
+ EXT_GIC_ID_USB_DEVICE,
80
+ EXT_GIC_ID_MODEMIF,
81
+ EXT_GIC_ID_HSMMC0,
82
+ EXT_GIC_ID_HSMMC1,
83
+ EXT_GIC_ID_HSMMC2,
84
+ EXT_GIC_ID_HSMMC3,
85
+ EXT_GIC_ID_SDMMC,
86
+ EXT_GIC_ID_MIPI_CSI_4LANE,
87
+ EXT_GIC_ID_MIPI_DSI_4LANE,
88
+ EXT_GIC_ID_MIPI_CSI_2LANE,
89
+ EXT_GIC_ID_MIPI_DSI_2LANE,
90
+ EXT_GIC_ID_ONENAND_AUDI,
91
+ EXT_GIC_ID_ROTATOR,
92
+ EXT_GIC_ID_FIMC0,
93
+ EXT_GIC_ID_FIMC1,
94
+ EXT_GIC_ID_FIMC2,
95
+ EXT_GIC_ID_FIMC3,
96
+ EXT_GIC_ID_JPEG,
97
+ EXT_GIC_ID_2D,
98
+ EXT_GIC_ID_PCIe,
99
+ EXT_GIC_ID_MIXER,
100
+ EXT_GIC_ID_HDMI,
101
+ EXT_GIC_ID_HDMI_I2C,
102
+ EXT_GIC_ID_MFC,
103
+ EXT_GIC_ID_TVENC,
104
+};
105
+
106
+enum ExtInt {
107
+ EXT_GIC_ID_EXTINT0 = 48,
108
+ EXT_GIC_ID_EXTINT1,
109
+ EXT_GIC_ID_EXTINT2,
110
+ EXT_GIC_ID_EXTINT3,
111
+ EXT_GIC_ID_EXTINT4,
112
+ EXT_GIC_ID_EXTINT5,
113
+ EXT_GIC_ID_EXTINT6,
114
+ EXT_GIC_ID_EXTINT7,
115
+ EXT_GIC_ID_EXTINT8,
116
+ EXT_GIC_ID_EXTINT9,
117
+ EXT_GIC_ID_EXTINT10,
118
+ EXT_GIC_ID_EXTINT11,
119
+ EXT_GIC_ID_EXTINT12,
120
+ EXT_GIC_ID_EXTINT13,
121
+ EXT_GIC_ID_EXTINT14,
122
+ EXT_GIC_ID_EXTINT15
123
+};
124
+
125
+/*
126
+ * External GIC sources which are not from External Interrupt Combiner or
127
+ * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
128
+ * which is INTG16 in Internal Interrupt Combiner.
129
+ */
130
+
131
+static const uint32_t
132
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
133
+ /* int combiner groups 16-19 */
134
+ { }, { }, { }, { },
135
+ /* int combiner group 20 */
136
+ { 0, EXT_GIC_ID_MDMA_LCD0 },
137
+ /* int combiner group 21 */
138
+ { EXT_GIC_ID_PDMA0, EXT_GIC_ID_PDMA1 },
139
+ /* int combiner group 22 */
140
+ { EXT_GIC_ID_TIMER0, EXT_GIC_ID_TIMER1, EXT_GIC_ID_TIMER2,
141
+ EXT_GIC_ID_TIMER3, EXT_GIC_ID_TIMER4 },
142
+ /* int combiner group 23 */
143
+ { EXT_GIC_ID_RTC_ALARM, EXT_GIC_ID_RTC_TIC },
144
+ /* int combiner group 24 */
145
+ { EXT_GIC_ID_GPIO_XB, EXT_GIC_ID_GPIO_XA },
146
+ /* int combiner group 25 */
147
+ { EXT_GIC_ID_IEM_APC, EXT_GIC_ID_IEM_IEC },
148
+ /* int combiner group 26 */
149
+ { EXT_GIC_ID_UART0, EXT_GIC_ID_UART1, EXT_GIC_ID_UART2, EXT_GIC_ID_UART3,
150
+ EXT_GIC_ID_UART4 },
151
+ /* int combiner group 27 */
152
+ { EXT_GIC_ID_I2C0, EXT_GIC_ID_I2C1, EXT_GIC_ID_I2C2, EXT_GIC_ID_I2C3,
153
+ EXT_GIC_ID_I2C4, EXT_GIC_ID_I2C5, EXT_GIC_ID_I2C6,
154
+ EXT_GIC_ID_I2C7 },
155
+ /* int combiner group 28 */
156
+ { EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 , EXT_GIC_ID_USB_HOST},
157
+ /* int combiner group 29 */
158
+ { EXT_GIC_ID_HSMMC0, EXT_GIC_ID_HSMMC1, EXT_GIC_ID_HSMMC2,
159
+ EXT_GIC_ID_HSMMC3, EXT_GIC_ID_SDMMC },
160
+ /* int combiner group 30 */
161
+ { EXT_GIC_ID_MIPI_CSI_4LANE, EXT_GIC_ID_MIPI_CSI_2LANE },
162
+ /* int combiner group 31 */
163
+ { EXT_GIC_ID_MIPI_DSI_4LANE, EXT_GIC_ID_MIPI_DSI_2LANE },
164
+ /* int combiner group 32 */
165
+ { EXT_GIC_ID_FIMC0, EXT_GIC_ID_FIMC1 },
166
+ /* int combiner group 33 */
167
+ { EXT_GIC_ID_FIMC2, EXT_GIC_ID_FIMC3 },
168
+ /* int combiner group 34 */
169
+ { EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
170
+ /* int combiner group 35 */
171
+ { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
172
+ /* int combiner group 36 */
173
+ { EXT_GIC_ID_MIXER },
174
+ /* int combiner group 37 */
175
+ { EXT_GIC_ID_EXTINT4, EXT_GIC_ID_EXTINT5, EXT_GIC_ID_EXTINT6,
176
+ EXT_GIC_ID_EXTINT7 },
177
+ /* groups 38-50 */
178
+ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
179
+ /* int combiner group 51 */
180
+ { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
181
+ /* group 52 */
182
+ { },
183
+ /* int combiner group 53 */
184
+ { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
185
+ /* groups 54-63 */
186
+ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
187
+};
188
+
189
+/*
190
+ * Initialize board IRQs.
191
+ * These IRQs contain splitted Int/External Combiner and External Gic IRQs.
192
+ */
193
+static void exynos4210_init_board_irqs(Exynos4210State *s)
194
+{
195
+ uint32_t grp, bit, irq_id, n;
196
+ Exynos4210Irq *is = &s->irqs;
197
+
198
+ for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
199
+ irq_id = 0;
200
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
201
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
202
+ /* MCT_G0 is passed to External GIC */
203
+ irq_id = EXT_GIC_ID_MCT_G0;
204
+ }
205
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
206
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
207
+ /* MCT_G1 is passed to External and GIC */
208
+ irq_id = EXT_GIC_ID_MCT_G1;
209
+ }
210
+ if (irq_id) {
211
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
212
+ is->ext_gic_irq[irq_id - 32]);
213
+ } else {
214
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
215
+ is->ext_combiner_irq[n]);
216
+ }
217
+ }
218
+ for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
219
+ /* these IDs are passed to Internal Combiner and External GIC */
220
+ grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
221
+ bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
222
+ irq_id = combiner_grp_to_gic_id[grp -
223
+ EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
224
+
225
+ if (irq_id) {
226
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
227
+ is->ext_gic_irq[irq_id - 32]);
228
+ }
229
+ }
230
+}
231
+
232
+/*
233
+ * Get IRQ number from exynos4210 IRQ subsystem stub.
234
+ * To identify IRQ source use internal combiner group and bit number
235
+ * grp - group number
236
+ * bit - bit number inside group
237
+ */
238
+uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
239
+{
240
+ return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
241
+}
242
+
243
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
244
0x09, 0x00, 0x00, 0x00 };
245
246
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
247
index XXXXXXX..XXXXXXX 100644
248
--- a/hw/intc/exynos4210_gic.c
249
+++ b/hw/intc/exynos4210_gic.c
250
@@ -XXX,XX +XXX,XX @@
251
#include "hw/arm/exynos4210.h"
252
#include "qom/object.h"
253
254
-enum ExtGicId {
255
- EXT_GIC_ID_MDMA_LCD0 = 66,
256
- EXT_GIC_ID_PDMA0,
257
- EXT_GIC_ID_PDMA1,
258
- EXT_GIC_ID_TIMER0,
259
- EXT_GIC_ID_TIMER1,
260
- EXT_GIC_ID_TIMER2,
261
- EXT_GIC_ID_TIMER3,
262
- EXT_GIC_ID_TIMER4,
263
- EXT_GIC_ID_MCT_L0,
264
- EXT_GIC_ID_WDT,
265
- EXT_GIC_ID_RTC_ALARM,
266
- EXT_GIC_ID_RTC_TIC,
267
- EXT_GIC_ID_GPIO_XB,
268
- EXT_GIC_ID_GPIO_XA,
269
- EXT_GIC_ID_MCT_L1,
270
- EXT_GIC_ID_IEM_APC,
271
- EXT_GIC_ID_IEM_IEC,
272
- EXT_GIC_ID_NFC,
273
- EXT_GIC_ID_UART0,
274
- EXT_GIC_ID_UART1,
275
- EXT_GIC_ID_UART2,
276
- EXT_GIC_ID_UART3,
277
- EXT_GIC_ID_UART4,
278
- EXT_GIC_ID_MCT_G0,
279
- EXT_GIC_ID_I2C0,
280
- EXT_GIC_ID_I2C1,
281
- EXT_GIC_ID_I2C2,
282
- EXT_GIC_ID_I2C3,
283
- EXT_GIC_ID_I2C4,
284
- EXT_GIC_ID_I2C5,
285
- EXT_GIC_ID_I2C6,
286
- EXT_GIC_ID_I2C7,
287
- EXT_GIC_ID_SPI0,
288
- EXT_GIC_ID_SPI1,
289
- EXT_GIC_ID_SPI2,
290
- EXT_GIC_ID_MCT_G1,
291
- EXT_GIC_ID_USB_HOST,
292
- EXT_GIC_ID_USB_DEVICE,
293
- EXT_GIC_ID_MODEMIF,
294
- EXT_GIC_ID_HSMMC0,
295
- EXT_GIC_ID_HSMMC1,
296
- EXT_GIC_ID_HSMMC2,
297
- EXT_GIC_ID_HSMMC3,
298
- EXT_GIC_ID_SDMMC,
299
- EXT_GIC_ID_MIPI_CSI_4LANE,
300
- EXT_GIC_ID_MIPI_DSI_4LANE,
301
- EXT_GIC_ID_MIPI_CSI_2LANE,
302
- EXT_GIC_ID_MIPI_DSI_2LANE,
303
- EXT_GIC_ID_ONENAND_AUDI,
304
- EXT_GIC_ID_ROTATOR,
305
- EXT_GIC_ID_FIMC0,
306
- EXT_GIC_ID_FIMC1,
307
- EXT_GIC_ID_FIMC2,
308
- EXT_GIC_ID_FIMC3,
309
- EXT_GIC_ID_JPEG,
310
- EXT_GIC_ID_2D,
311
- EXT_GIC_ID_PCIe,
312
- EXT_GIC_ID_MIXER,
313
- EXT_GIC_ID_HDMI,
314
- EXT_GIC_ID_HDMI_I2C,
315
- EXT_GIC_ID_MFC,
316
- EXT_GIC_ID_TVENC,
317
-};
318
-
319
-enum ExtInt {
320
- EXT_GIC_ID_EXTINT0 = 48,
321
- EXT_GIC_ID_EXTINT1,
322
- EXT_GIC_ID_EXTINT2,
323
- EXT_GIC_ID_EXTINT3,
324
- EXT_GIC_ID_EXTINT4,
325
- EXT_GIC_ID_EXTINT5,
326
- EXT_GIC_ID_EXTINT6,
327
- EXT_GIC_ID_EXTINT7,
328
- EXT_GIC_ID_EXTINT8,
329
- EXT_GIC_ID_EXTINT9,
330
- EXT_GIC_ID_EXTINT10,
331
- EXT_GIC_ID_EXTINT11,
332
- EXT_GIC_ID_EXTINT12,
333
- EXT_GIC_ID_EXTINT13,
334
- EXT_GIC_ID_EXTINT14,
335
- EXT_GIC_ID_EXTINT15
336
-};
337
-
338
-/*
339
- * External GIC sources which are not from External Interrupt Combiner or
340
- * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
341
- * which is INTG16 in Internal Interrupt Combiner.
342
- */
343
-
344
-static const uint32_t
345
-combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
346
- /* int combiner groups 16-19 */
347
- { }, { }, { }, { },
348
- /* int combiner group 20 */
349
- { 0, EXT_GIC_ID_MDMA_LCD0 },
350
- /* int combiner group 21 */
351
- { EXT_GIC_ID_PDMA0, EXT_GIC_ID_PDMA1 },
352
- /* int combiner group 22 */
353
- { EXT_GIC_ID_TIMER0, EXT_GIC_ID_TIMER1, EXT_GIC_ID_TIMER2,
354
- EXT_GIC_ID_TIMER3, EXT_GIC_ID_TIMER4 },
355
- /* int combiner group 23 */
356
- { EXT_GIC_ID_RTC_ALARM, EXT_GIC_ID_RTC_TIC },
357
- /* int combiner group 24 */
358
- { EXT_GIC_ID_GPIO_XB, EXT_GIC_ID_GPIO_XA },
359
- /* int combiner group 25 */
360
- { EXT_GIC_ID_IEM_APC, EXT_GIC_ID_IEM_IEC },
361
- /* int combiner group 26 */
362
- { EXT_GIC_ID_UART0, EXT_GIC_ID_UART1, EXT_GIC_ID_UART2, EXT_GIC_ID_UART3,
363
- EXT_GIC_ID_UART4 },
364
- /* int combiner group 27 */
365
- { EXT_GIC_ID_I2C0, EXT_GIC_ID_I2C1, EXT_GIC_ID_I2C2, EXT_GIC_ID_I2C3,
366
- EXT_GIC_ID_I2C4, EXT_GIC_ID_I2C5, EXT_GIC_ID_I2C6,
367
- EXT_GIC_ID_I2C7 },
368
- /* int combiner group 28 */
369
- { EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 , EXT_GIC_ID_USB_HOST},
370
- /* int combiner group 29 */
371
- { EXT_GIC_ID_HSMMC0, EXT_GIC_ID_HSMMC1, EXT_GIC_ID_HSMMC2,
372
- EXT_GIC_ID_HSMMC3, EXT_GIC_ID_SDMMC },
373
- /* int combiner group 30 */
374
- { EXT_GIC_ID_MIPI_CSI_4LANE, EXT_GIC_ID_MIPI_CSI_2LANE },
375
- /* int combiner group 31 */
376
- { EXT_GIC_ID_MIPI_DSI_4LANE, EXT_GIC_ID_MIPI_DSI_2LANE },
377
- /* int combiner group 32 */
378
- { EXT_GIC_ID_FIMC0, EXT_GIC_ID_FIMC1 },
379
- /* int combiner group 33 */
380
- { EXT_GIC_ID_FIMC2, EXT_GIC_ID_FIMC3 },
381
- /* int combiner group 34 */
382
- { EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
383
- /* int combiner group 35 */
384
- { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
385
- /* int combiner group 36 */
386
- { EXT_GIC_ID_MIXER },
387
- /* int combiner group 37 */
388
- { EXT_GIC_ID_EXTINT4, EXT_GIC_ID_EXTINT5, EXT_GIC_ID_EXTINT6,
389
- EXT_GIC_ID_EXTINT7 },
390
- /* groups 38-50 */
391
- { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
392
- /* int combiner group 51 */
393
- { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
394
- /* group 52 */
395
- { },
396
- /* int combiner group 53 */
397
- { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
398
- /* groups 54-63 */
399
- { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
400
-};
401
-
402
#define EXYNOS4210_GIC_NIRQ 160
403
404
#define EXYNOS4210_EXT_GIC_CPU_REGION_SIZE 0x10000
405
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
406
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
407
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
408
409
-/*
410
- * Initialize board IRQs.
411
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs.
412
- */
413
-void exynos4210_init_board_irqs(Exynos4210State *s)
414
-{
415
- uint32_t grp, bit, irq_id, n;
416
- Exynos4210Irq *is = &s->irqs;
417
-
418
- for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
419
- irq_id = 0;
420
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
421
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
422
- /* MCT_G0 is passed to External GIC */
423
- irq_id = EXT_GIC_ID_MCT_G0;
424
- }
425
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
426
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
427
- /* MCT_G1 is passed to External and GIC */
428
- irq_id = EXT_GIC_ID_MCT_G1;
429
- }
430
- if (irq_id) {
431
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
432
- is->ext_gic_irq[irq_id - 32]);
433
- } else {
434
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
435
- is->ext_combiner_irq[n]);
436
- }
437
- }
438
- for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
439
- /* these IDs are passed to Internal Combiner and External GIC */
440
- grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
441
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
442
- irq_id = combiner_grp_to_gic_id[grp -
443
- EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
444
-
445
- if (irq_id) {
446
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
447
- is->ext_gic_irq[irq_id - 32]);
448
- }
449
- }
450
-}
451
-
452
-/*
453
- * Get IRQ number from exynos4210 IRQ subsystem stub.
454
- * To identify IRQ source use internal combiner group and bit number
455
- * grp - group number
456
- * bit - bit number inside group
457
- */
458
-uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
459
-{
460
- return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
461
-}
462
-
463
-/********* GIC part *********/
464
-
465
#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
466
OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
467
468
--
469
2.25.1
diff view generated by jsdifflib
Deleted patch
1
The only time we use the ext_gic_irq[] array in the Exynos4210Irq
2
struct is during realize of the SoC -- we initialize it with the
3
input IRQs of the external GIC device, and then connect those to
4
outputs of other devices further on in realize (including in the
5
exynos4210_init_board_irqs() function). Now that the ext_gic object
6
is easily accessible as s->ext_gic we can make the connections
7
directly from one device to the other without going via this array.
8
1
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-10-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 1 -
14
hw/arm/exynos4210.c | 12 ++++++------
15
2 files changed, 6 insertions(+), 7 deletions(-)
16
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
20
+++ b/include/hw/arm/exynos4210.h
21
@@ -XXX,XX +XXX,XX @@
22
typedef struct Exynos4210Irq {
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
25
- qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
26
} Exynos4210Irq;
27
28
struct Exynos4210State {
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
32
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
34
{
35
uint32_t grp, bit, irq_id, n;
36
Exynos4210Irq *is = &s->irqs;
37
+ DeviceState *extgicdev = DEVICE(&s->ext_gic);
38
39
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
40
irq_id = 0;
41
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
42
}
43
if (irq_id) {
44
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
45
- is->ext_gic_irq[irq_id - 32]);
46
+ qdev_get_gpio_in(extgicdev,
47
+ irq_id - 32));
48
} else {
49
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
50
is->ext_combiner_irq[n]);
51
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
52
53
if (irq_id) {
54
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
55
- is->ext_gic_irq[irq_id - 32]);
56
+ qdev_get_gpio_in(extgicdev,
57
+ irq_id - 32));
58
}
59
}
60
}
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
62
sysbus_connect_irq(busdev, n,
63
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
64
}
65
- for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
66
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
67
- }
68
69
/* Internal Interrupt Combiner */
70
dev = qdev_new("exynos4210.combiner");
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
72
busdev = SYS_BUS_DEVICE(dev);
73
sysbus_realize_and_unref(busdev, &error_fatal);
74
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
75
- sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]);
76
+ sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
77
}
78
exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
79
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
80
--
81
2.25.1
diff view generated by jsdifflib
Deleted patch
1
Delete a couple of #defines which are never used.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220404154658.565020-12-peter.maydell@linaro.org
6
---
7
include/hw/arm/exynos4210.h | 4 ----
8
1 file changed, 4 deletions(-)
9
10
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
11
index XXXXXXX..XXXXXXX 100644
12
--- a/include/hw/arm/exynos4210.h
13
+++ b/include/hw/arm/exynos4210.h
14
@@ -XXX,XX +XXX,XX @@
15
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
16
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
17
18
-/* IRQs number for external and internal GIC */
19
-#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
20
-#define EXYNOS4210_INT_GIC_NIRQ 64
21
-
22
#define EXYNOS4210_I2C_NUMBER 9
23
24
#define EXYNOS4210_NUM_DMA 3
25
--
26
2.25.1
diff view generated by jsdifflib
Deleted patch
1
In exynos4210_init_board_irqs(), the loop that handles IRQ lines that
2
are in a range that applies to the internal combiner only creates a
3
splitter for those interrupts which go to both the internal combiner
4
and to the external GIC, but it does nothing at all for the
5
interrupts which don't go to the external GIC, leaving the
6
irq_table[] array element empty for those. (This will result in
7
those interrupts simply being lost, not in a QEMU crash.)
8
1
9
I don't have a reliable datasheet for this SoC, but since we do wire
10
up one interrupt line in this category (the HDMI I2C device on
11
interrupt 16,1), this seems like it must be a bug in the existing
12
QEMU code. Fill in the irq_table[] entries where we're not splitting
13
the IRQ to both the internal combiner and the external GIC with the
14
IRQ line of the internal combiner. (That is, these IRQ lines go to
15
just one device, not multiple.)
16
17
This bug didn't have any visible guest effects because the only
18
implemented device that was affected was the HDMI I2C controller,
19
and we never connect any I2C devices to that bus.
20
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20220404154658.565020-14-peter.maydell@linaro.org
24
---
25
hw/arm/exynos4210.c | 2 ++
26
1 file changed, 2 insertions(+)
27
28
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/exynos4210.c
31
+++ b/hw/arm/exynos4210.c
32
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
34
qdev_connect_gpio_out(splitter, 1,
35
qdev_get_gpio_in(extgicdev, irq_id - 32));
36
+ } else {
37
+ s->irq_table[n] = is->int_combiner_irq[n];
38
}
39
}
40
/*
41
--
42
2.25.1
diff view generated by jsdifflib