1
First arm pullreq for 7.1. The bulk of this is the qemu_split_irq
1
The following changes since commit 5767815218efd3cbfd409505ed824d5f356044ae:
2
removal.
3
2
4
I have enough stuff in my to-review queue that I expect to do another
3
Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging (2024-02-14 15:45:52 +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-20240215
17
8
18
for you to fetch changes up to 5b415dd61bdbf61fb4be0e9f1a7172b8bce682c6:
9
for you to fetch changes up to f780e63fe731b058fe52d43653600d8729a1b5f2:
19
10
20
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs (2022-04-21 11:37:05 +0100)
11
docs: Add documentation for the mps3-an536 board (2024-02-15 14:32:39 +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
* hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
25
* versal: Add the Cortex-R5s in the Real-Time Processing Unit (RPU) subsystem
16
* linux-user/aarch64: Choose SYNC as the preferred MTE mode
26
* versal: model enough of the Clock/Reset Low-power domain (CRL) to allow control of the Cortex-R5s
17
* Fix some errors in SVE/SME handling of MTE tags
27
* xlnx-zynqmp: Connect 4 TTC timers
18
* hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
28
* exynos4210: Refactor GIC/combiner code to stop using qemu_split_irq
19
* hw/block/tc58128: Don't emit deprecation warning under qtest
29
* realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
20
* tests/qtest: Fix handling of npcm7xx and GMAC tests
30
* stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
21
* hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
31
* hw/core/irq: remove unused 'qemu_irq_split' function
22
* tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
32
* npcm7xx: use symbolic constants for PWRON STRAP bit fields
23
* Don't assert on vmload/vmsave of M-profile CPUs
33
* virt: document impact of gic-version on max CPUs
24
* hw/arm/smmuv3: add support for stage 1 access fault
25
* hw/arm/stellaris: QOM cleanups
26
* Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs
27
* Improve Cortex_R52 IMPDEF sysreg modelling
28
* Allow access to SPSR_hyp from hyp mode
29
* New board model mps3-an536 (Cortex-R52)
34
30
35
----------------------------------------------------------------
31
----------------------------------------------------------------
36
Edgar E. Iglesias (6):
32
Luc Michel (1):
37
timer: cadence_ttc: Break out header file to allow embedding
33
hw/arm/smmuv3: add support for stage 1 access fault
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
34
44
Hao Wu (2):
35
Nabih Estefan (1):
45
hw/misc: Add PWRON STRAP bit fields in GCR module
36
tests/qtest: Fix GMAC test to run on a machine in upstream QEMU
46
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs
47
37
48
Heinrich Schuchardt (1):
38
Peter Maydell (22):
49
hw/arm/virt: impact of gic-version on max CPUs
39
hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
40
hw/block/tc58128: Don't emit deprecation warning under qtest
41
tests/qtest/meson.build: Don't include qtests_npcm7xx in qtests_aarch64
42
tests/qtest/bios-tables-test: Allow changes to virt GTDT
43
hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
44
tests/qtest/bios-tables-tests: Update virt golden reference
45
hw/arm/npcm7xx: Call qemu_configure_nic_device() for GMAC modules
46
tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
47
target/arm: Don't get MDCR_EL2 in pmu_counter_enabled() before checking ARM_FEATURE_PMU
48
target/arm: Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs
49
target/arm: The Cortex-R52 has a read-only CBAR
50
target/arm: Add Cortex-R52 IMPDEF sysregs
51
target/arm: Allow access to SPSR_hyp from hyp mode
52
hw/misc/mps2-scc: Fix condition for CFG3 register
53
hw/misc/mps2-scc: Factor out which-board conditionals
54
hw/misc/mps2-scc: Make changes needed for AN536 FPGA image
55
hw/arm/mps3r: Initial skeleton for mps3-an536 board
56
hw/arm/mps3r: Add CPUs, GIC, and per-CPU RAM
57
hw/arm/mps3r: Add UARTs
58
hw/arm/mps3r: Add GPIO, watchdog, dual-timer, I2C devices
59
hw/arm/mps3r: Add remaining devices
60
docs: Add documentation for the mps3-an536 board
50
61
51
Peter Maydell (19):
62
Philippe Mathieu-Daudé (5):
52
hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
63
hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
53
hw/arm/exynos4210: Use TYPE_OR_IRQ instead of custom OR-gate device
64
hw/arm/stellaris: Convert ADC controller to Resettable interface
54
hw/intc/exynos4210_gic: Remove unused TYPE_EXYNOS4210_IRQ_GATE
65
hw/arm/stellaris: Convert I2C controller to Resettable interface
55
hw/arm/exynos4210: Put a9mpcore device into state struct
66
hw/arm/stellaris: Add missing QOM 'machine' parent
56
hw/arm/exynos4210: Drop int_gic_irq[] from Exynos4210Irq struct
67
hw/arm/stellaris: Add missing QOM 'SoC' parent
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
68
72
Zongyuan Li (3):
69
Richard Henderson (6):
73
hw/arm/realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
70
linux-user/aarch64: Choose SYNC as the preferred MTE mode
74
hw/arm/stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
71
target/arm: Fix nregs computation in do_{ld,st}_zpa
75
hw/core/irq: remove unused 'qemu_irq_split' function
72
target/arm: Adjust and validate mtedesc sizem1
73
target/arm: Split out make_svemte_desc
74
target/arm: Handle mte in do_ldrq, do_ldro
75
target/arm: Fix SVE/SME gross MTE suppression checks
76
76
77
docs/system/arm/virt.rst | 4 +-
77
MAINTAINERS | 3 +-
78
include/hw/arm/exynos4210.h | 50 ++--
78
docs/system/arm/mps2.rst | 37 +-
79
include/hw/arm/xlnx-versal.h | 16 ++
79
configs/devices/arm-softmmu/default.mak | 1 +
80
include/hw/arm/xlnx-zynqmp.h | 4 +
80
hw/arm/smmuv3-internal.h | 1 +
81
include/hw/intc/exynos4210_combiner.h | 57 +++++
81
include/hw/arm/smmu-common.h | 1 +
82
include/hw/intc/exynos4210_gic.h | 43 ++++
82
include/hw/arm/virt.h | 2 +
83
include/hw/irq.h | 5 -
83
include/hw/misc/mps2-scc.h | 1 +
84
include/hw/misc/npcm7xx_gcr.h | 30 +++
84
linux-user/aarch64/target_prctl.h | 29 +-
85
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++++
85
target/arm/internals.h | 2 +-
86
include/hw/timer/cadence_ttc.h | 54 +++++
86
target/arm/tcg/translate-a64.h | 2 +
87
hw/arm/exynos4210.c | 430 ++++++++++++++++++++++++++++++----
87
hw/arm/mps3r.c | 640 ++++++++++++++++++++++++++++++++
88
hw/arm/npcm7xx_boards.c | 24 +-
88
hw/arm/npcm7xx.c | 1 +
89
hw/arm/realview.c | 33 ++-
89
hw/arm/smmu-common.c | 11 +
90
hw/arm/stellaris.c | 15 +-
90
hw/arm/smmuv3.c | 1 +
91
hw/arm/virt.c | 7 +
91
hw/arm/stellaris.c | 47 ++-
92
hw/arm/xlnx-versal-virt.c | 6 +-
92
hw/arm/virt-acpi-build.c | 20 +-
93
hw/arm/xlnx-versal.c | 99 +++++++-
93
hw/arm/virt.c | 60 ++-
94
hw/arm/xlnx-zynqmp.c | 22 ++
94
hw/arm/xilinx_zynq.c | 2 +
95
hw/core/irq.c | 15 --
95
hw/block/tc58128.c | 4 +-
96
hw/intc/exynos4210_combiner.c | 108 +--------
96
hw/misc/mps2-scc.c | 138 ++++++-
97
hw/intc/exynos4210_gic.c | 344 +--------------------------
97
hw/pci-host/raven.c | 1 +
98
hw/misc/xlnx-versal-crl.c | 421 +++++++++++++++++++++++++++++++++
98
target/arm/helper.c | 14 +-
99
hw/timer/cadence_ttc.c | 32 +--
99
target/arm/tcg/cpu32.c | 109 ++++++
100
MAINTAINERS | 2 +-
100
target/arm/tcg/op_helper.c | 43 ++-
101
hw/misc/meson.build | 1 +
101
target/arm/tcg/sme_helper.c | 8 +-
102
25 files changed, 1457 insertions(+), 600 deletions(-)
102
target/arm/tcg/sve_helper.c | 12 +-
103
create mode 100644 include/hw/intc/exynos4210_combiner.h
103
target/arm/tcg/translate-sme.c | 15 +-
104
create mode 100644 include/hw/intc/exynos4210_gic.h
104
target/arm/tcg/translate-sve.c | 83 +++--
105
create mode 100644 include/hw/misc/xlnx-versal-crl.h
105
target/arm/tcg/translate.c | 19 +-
106
create mode 100644 include/hw/timer/cadence_ttc.h
106
tests/qtest/npcm7xx_emc-test.c | 5 +-
107
create mode 100644 hw/misc/xlnx-versal-crl.c
107
tests/qtest/npcm_gmac-test.c | 84 +----
108
hw/arm/Kconfig | 5 +
109
hw/arm/meson.build | 1 +
110
tests/data/acpi/virt/FACP | Bin 276 -> 276 bytes
111
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
112
tests/qtest/meson.build | 4 +-
113
36 files changed, 1184 insertions(+), 222 deletions(-)
114
create mode 100644 hw/arm/mps3r.c
115
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Similar to the Aspeed code in include/misc/aspeed_scu.h, we define
3
Similarly to commits dadbb58f59..5ae79fe825 for other ARM boards,
4
the PWRON STRAP fields in their corresponding module for NPCM7XX.
4
connect FIQ output of the GIC CPU interfaces to the CPU.
5
5
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Patrick Venture <venture@google.com>
7
Message-id: 20240130152548.17855-1-philmd@linaro.org
8
Message-id: 20220411165842.3912945-2-wuhaotsh@google.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
include/hw/misc/npcm7xx_gcr.h | 30 ++++++++++++++++++++++++++++++
11
hw/arm/xilinx_zynq.c | 2 ++
13
1 file changed, 30 insertions(+)
12
1 file changed, 2 insertions(+)
14
13
15
diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h
14
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/misc/npcm7xx_gcr.h
16
--- a/hw/arm/xilinx_zynq.c
18
+++ b/include/hw/misc/npcm7xx_gcr.h
17
+++ b/hw/arm/xilinx_zynq.c
19
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
20
#include "exec/memory.h"
19
sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE);
21
#include "hw/sysbus.h"
20
sysbus_connect_irq(busdev, 0,
22
21
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
23
+/*
22
+ sysbus_connect_irq(busdev, 1,
24
+ * NPCM7XX PWRON STRAP bit fields
23
+ qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ));
25
+ * 12: SPI0 powered by VSBV3 at 1.8V
24
26
+ * 11: System flash attached to BMC
25
for (n = 0; n < 64; n++) {
27
+ * 10: BSP alternative pins.
26
pic[n] = qdev_get_gpio_in(dev, n);
28
+ * 9:8: Flash UART command route enabled.
29
+ * 7: Security enabled.
30
+ * 6: HI-Z state control.
31
+ * 5: ECC disabled.
32
+ * 4: Reserved
33
+ * 3: JTAG2 enabled.
34
+ * 2:0: CPU and DRAM clock frequency.
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
+
53
/*
54
* Number of registers in our device state structure. Don't change this without
55
* incrementing the version_id in the vmstate.
56
--
27
--
57
2.25.1
28
2.34.1
29
30
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The API does not generate an error for setting ASYNC | SYNC; that merely
4
constrains the selection vs the per-cpu default. For qemu linux-user,
5
choose SYNC as the default.
6
7
Cc: qemu-stable@nongnu.org
8
Reported-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
11
Message-id: 20240207025210.8837-2-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
linux-user/aarch64/target_prctl.h | 29 +++++++++++++++++------------
15
1 file changed, 17 insertions(+), 12 deletions(-)
16
17
diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/linux-user/aarch64/target_prctl.h
20
+++ b/linux-user/aarch64/target_prctl.h
21
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
22
env->tagged_addr_enable = arg2 & PR_TAGGED_ADDR_ENABLE;
23
24
if (cpu_isar_feature(aa64_mte, cpu)) {
25
- switch (arg2 & PR_MTE_TCF_MASK) {
26
- case PR_MTE_TCF_NONE:
27
- case PR_MTE_TCF_SYNC:
28
- case PR_MTE_TCF_ASYNC:
29
- break;
30
- default:
31
- return -EINVAL;
32
- }
33
-
34
/*
35
* Write PR_MTE_TCF to SCTLR_EL1[TCF0].
36
- * Note that the syscall values are consistent with hw.
37
+ *
38
+ * The kernel has a per-cpu configuration for the sysadmin,
39
+ * /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred,
40
+ * which qemu does not implement.
41
+ *
42
+ * Because there is no performance difference between the modes, and
43
+ * because SYNC is most useful for debugging MTE errors, choose SYNC
44
+ * as the preferred mode. With this preference, and the way the API
45
+ * uses only two bits, there is no way for the program to select
46
+ * ASYMM mode.
47
*/
48
- env->cp15.sctlr_el[1] =
49
- deposit64(env->cp15.sctlr_el[1], 38, 2, arg2 >> PR_MTE_TCF_SHIFT);
50
+ unsigned tcf = 0;
51
+ if (arg2 & PR_MTE_TCF_SYNC) {
52
+ tcf = 1;
53
+ } else if (arg2 & PR_MTE_TCF_ASYNC) {
54
+ tcf = 2;
55
+ }
56
+ env->cp15.sctlr_el[1] = deposit64(env->cp15.sctlr_el[1], 38, 2, tcf);
57
58
/*
59
* Write PR_MTE_TAG to GCR_EL1[Exclude].
60
--
61
2.34.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 field is encoded as [0-3], which is convenient for
4
indexing our array of function pointers, but the true
5
value is [1-4]. Adjust before calling do_mem_zpa.
4
6
5
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
7
Add an assert, and move the comment re passing ZT to
6
Message-id: 20220413231456.35811-1-heinrich.schuchardt@canonical.com
8
the helper back next to the relevant code.
7
[PMM: minor punctuation tweaks]
9
10
Cc: qemu-stable@nongnu.org
11
Fixes: 206adacfb8d ("target/arm: Add mte helpers for sve scalar + int loads")
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
14
Message-id: 20240207025210.8837-3-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
17
---
11
docs/system/arm/virt.rst | 4 ++--
18
target/arm/tcg/translate-sve.c | 16 ++++++++--------
12
1 file changed, 2 insertions(+), 2 deletions(-)
19
1 file changed, 8 insertions(+), 8 deletions(-)
13
20
14
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
21
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/virt.rst
23
--- a/target/arm/tcg/translate-sve.c
17
+++ b/docs/system/arm/virt.rst
24
+++ b/target/arm/tcg/translate-sve.c
18
@@ -XXX,XX +XXX,XX @@ gic-version
25
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
19
Valid values are:
26
TCGv_ptr t_pg;
20
27
int desc = 0;
21
``2``
28
22
- GICv2
29
- /*
23
+ GICv2. Note that this limits the number of CPUs to 8.
30
- * For e.g. LD4, there are not enough arguments to pass all 4
24
``3``
31
- * registers as pointers, so encode the regno into the data field.
25
- GICv3
32
- * For consistency, do this even for LD1.
26
+ GICv3. This allows up to 512 CPUs.
33
- */
27
``host``
34
+ assert(mte_n >= 1 && mte_n <= 4);
28
Use the same GIC version the host provides, when using KVM
35
if (s->mte_active[0]) {
29
``max``
36
int msz = dtype_msz(dtype);
37
38
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
39
addr = clean_data_tbi(s, addr);
40
}
41
42
+ /*
43
+ * For e.g. LD4, there are not enough arguments to pass all 4
44
+ * registers as pointers, so encode the regno into the data field.
45
+ * For consistency, do this even for LD1.
46
+ */
47
desc = simd_desc(vsz, vsz, zt | desc);
48
t_pg = tcg_temp_new_ptr();
49
50
@@ -XXX,XX +XXX,XX @@ static void do_ld_zpa(DisasContext *s, int zt, int pg,
51
* accessible via the instruction encoding.
52
*/
53
assert(fn != NULL);
54
- do_mem_zpa(s, zt, pg, addr, dtype, nreg, false, fn);
55
+ do_mem_zpa(s, zt, pg, addr, dtype, nreg + 1, false, fn);
56
}
57
58
static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a)
59
@@ -XXX,XX +XXX,XX @@ static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
60
if (nreg == 0) {
61
/* ST1 */
62
fn = fn_single[s->mte_active[0]][be][msz][esz];
63
- nreg = 1;
64
} else {
65
/* ST2, ST3, ST4 -- msz == esz, enforced by encoding */
66
assert(msz == esz);
67
fn = fn_multiple[s->mte_active[0]][be][nreg - 1][msz];
68
}
69
assert(fn != NULL);
70
- do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg, true, fn);
71
+ do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg + 1, true, fn);
72
}
73
74
static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a)
30
--
75
--
31
2.25.1
76
2.34.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
When we added SVE_MTEDESC_SHIFT, we effectively limited the
4
maximum size of MTEDESC. Adjust SIZEM1 to consume the remaining
5
bits (32 - 10 - 5 - 12 == 5). Assert that the data to be stored
6
fits within the field (expecting 8 * 4 - 1 == 31, exact fit).
4
7
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
8
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20220406174303.2022038-2-edgar.iglesias@xilinx.com
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
12
Message-id: 20240207025210.8837-4-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
14
---
10
include/hw/arm/xlnx-versal.h | 2 ++
15
target/arm/internals.h | 2 +-
11
hw/arm/xlnx-versal.c | 9 ++++++++-
16
target/arm/tcg/translate-sve.c | 7 ++++---
12
2 files changed, 10 insertions(+), 1 deletion(-)
17
2 files changed, 5 insertions(+), 4 deletions(-)
13
18
14
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/xlnx-versal.h
21
--- a/target/arm/internals.h
17
+++ b/include/hw/arm/xlnx-versal.h
22
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, TBI, 4, 2)
19
24
FIELD(MTEDESC, TCMA, 6, 2)
20
#include "hw/sysbus.h"
25
FIELD(MTEDESC, WRITE, 8, 1)
21
#include "hw/arm/boot.h"
26
FIELD(MTEDESC, ALIGN, 9, 3)
22
+#include "hw/cpu/cluster.h"
27
-FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - 12) /* size - 1 */
23
#include "hw/or-irq.h"
28
+FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - SVE_MTEDESC_SHIFT - 12) /* size - 1 */
24
#include "hw/sd/sdhci.h"
29
25
#include "hw/intc/arm_gicv3.h"
30
bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr);
26
@@ -XXX,XX +XXX,XX @@ struct Versal {
31
uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
27
struct {
32
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
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
33
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/xlnx-versal.c
34
--- a/target/arm/tcg/translate-sve.c
37
+++ b/hw/arm/xlnx-versal.c
35
+++ b/target/arm/tcg/translate-sve.c
38
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
36
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
39
{
37
{
40
int i;
38
unsigned vsz = vec_full_reg_size(s);
41
39
TCGv_ptr t_pg;
42
+ object_initialize_child(OBJECT(s), "apu-cluster", &s->fpd.apu.cluster,
40
+ uint32_t sizem1;
43
+ TYPE_CPU_CLUSTER);
41
int desc = 0;
44
+ qdev_prop_set_uint32(DEVICE(&s->fpd.apu.cluster), "cluster-id", 0);
42
45
+
43
assert(mte_n >= 1 && mte_n <= 4);
46
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
44
+ sizem1 = (mte_n << dtype_msz(dtype)) - 1;
47
Object *obj;
45
+ assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
48
46
if (s->mte_active[0]) {
49
- object_initialize_child(OBJECT(s), "apu-cpu[*]", &s->fpd.apu.cpu[i],
47
- int msz = dtype_msz(dtype);
50
+ object_initialize_child(OBJECT(&s->fpd.apu.cluster),
48
-
51
+ "apu-cpu[*]", &s->fpd.apu.cpu[i],
49
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
52
XLNX_VERSAL_ACPU_TYPE);
50
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
53
obj = OBJECT(&s->fpd.apu.cpu[i]);
51
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
54
if (i) {
52
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
55
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
53
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (mte_n << msz) - 1);
56
&error_abort);
54
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
57
qdev_realize(DEVICE(obj), NULL, &error_fatal);
55
desc <<= SVE_MTEDESC_SHIFT;
58
}
56
} else {
59
+
57
addr = clean_data_tbi(s, addr);
60
+ qdev_realize(DEVICE(&s->fpd.apu.cluster), NULL, &error_fatal);
61
}
62
63
static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
64
--
58
--
65
2.25.1
59
2.34.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
Share code that creates mtedesc and embeds within simd_desc.
4
5
Cc: qemu-stable@nongnu.org
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-2-zongyuan.li@smartx.com
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Message-id: 20240207025210.8837-5-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
hw/arm/realview.c | 33 ++++++++++++++++++++++++---------
12
target/arm/tcg/translate-a64.h | 2 ++
9
1 file changed, 24 insertions(+), 9 deletions(-)
13
target/arm/tcg/translate-sme.c | 15 +++--------
14
target/arm/tcg/translate-sve.c | 47 ++++++++++++++++++----------------
15
3 files changed, 31 insertions(+), 33 deletions(-)
10
16
11
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
17
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/realview.c
19
--- a/target/arm/tcg/translate-a64.h
14
+++ b/hw/arm/realview.c
20
+++ b/target/arm/tcg/translate-a64.h
15
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
16
#include "hw/sysbus.h"
22
bool sve_access_check(DisasContext *s);
17
#include "hw/arm/boot.h"
23
bool sme_enabled_check(DisasContext *s);
18
#include "hw/arm/primecell.h"
24
bool sme_enabled_check_with_svcr(DisasContext *s, unsigned);
19
+#include "hw/core/split-irq.h"
25
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
20
#include "hw/net/lan9118.h"
26
+ uint32_t msz, bool is_write, uint32_t data);
21
#include "hw/net/smc91c111.h"
27
22
#include "hw/pci/pci.h"
28
/* This function corresponds to CheckStreamingSVEEnabled. */
23
+#include "hw/qdev-core.h"
29
static inline bool sme_sm_enabled_check(DisasContext *s)
24
#include "net/net.h"
30
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
25
#include "sysemu/sysemu.h"
31
index XXXXXXX..XXXXXXX 100644
26
#include "hw/boards.h"
32
--- a/target/arm/tcg/translate-sme.c
27
@@ -XXX,XX +XXX,XX @@ static const int realview_board_id[] = {
33
+++ b/target/arm/tcg/translate-sme.c
28
0x76d
34
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
35
36
TCGv_ptr t_za, t_pg;
37
TCGv_i64 addr;
38
- int svl, desc = 0;
39
+ uint32_t desc;
40
bool be = s->be_data == MO_BE;
41
bool mte = s->mte_active[0];
42
43
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
44
tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->esz);
45
tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
46
47
- if (mte) {
48
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
49
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
50
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
51
- desc = FIELD_DP32(desc, MTEDESC, WRITE, a->st);
52
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << a->esz) - 1);
53
- desc <<= SVE_MTEDESC_SHIFT;
54
- } else {
55
+ if (!mte) {
56
addr = clean_data_tbi(s, addr);
57
}
58
- svl = streaming_vec_reg_size(s);
59
- desc = simd_desc(svl, svl, desc);
60
+
61
+ desc = make_svemte_desc(s, streaming_vec_reg_size(s), 1, a->esz, a->st, 0);
62
63
fns[a->esz][be][a->v][mte][a->st](tcg_env, t_za, t_pg, addr,
64
tcg_constant_i32(desc));
65
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/tcg/translate-sve.c
68
+++ b/target/arm/tcg/translate-sve.c
69
@@ -XXX,XX +XXX,XX @@ static const uint8_t dtype_esz[16] = {
70
3, 2, 1, 3
29
};
71
};
30
72
31
+static void split_irq_from_named(DeviceState *src, const char* outname,
73
-static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
32
+ qemu_irq out1, qemu_irq out2) {
74
- int dtype, uint32_t mte_n, bool is_write,
33
+ DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
75
- gen_helper_gvec_mem *fn)
76
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
77
+ uint32_t msz, bool is_write, uint32_t data)
78
{
79
- unsigned vsz = vec_full_reg_size(s);
80
- TCGv_ptr t_pg;
81
uint32_t sizem1;
82
- int desc = 0;
83
+ uint32_t desc = 0;
84
85
- assert(mte_n >= 1 && mte_n <= 4);
86
- sizem1 = (mte_n << dtype_msz(dtype)) - 1;
87
+ /* Assert all of the data fits, with or without MTE enabled. */
88
+ assert(nregs >= 1 && nregs <= 4);
89
+ sizem1 = (nregs << msz) - 1;
90
assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
91
+ assert(data < 1u << SVE_MTEDESC_SHIFT);
34
+
92
+
35
+ qdev_prop_set_uint32(splitter, "num-lines", 2);
93
if (s->mte_active[0]) {
36
+
94
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
37
+ qdev_realize_and_unref(splitter, NULL, &error_fatal);
95
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
38
+
96
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
39
+ qdev_connect_gpio_out(splitter, 0, out1);
97
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
40
+ qdev_connect_gpio_out(splitter, 1, out2);
98
desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
41
+ qdev_connect_gpio_out_named(src, outname, 0,
99
desc <<= SVE_MTEDESC_SHIFT;
42
+ qdev_get_gpio_in(splitter, 0));
100
- } else {
101
+ }
102
+ return simd_desc(vsz, vsz, desc | data);
43
+}
103
+}
44
+
104
+
45
static void realview_init(MachineState *machine,
105
+static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
46
enum realview_board_type board_type)
106
+ int dtype, uint32_t nregs, bool is_write,
107
+ gen_helper_gvec_mem *fn)
108
+{
109
+ TCGv_ptr t_pg;
110
+ uint32_t desc;
111
+
112
+ if (!s->mte_active[0]) {
113
addr = clean_data_tbi(s, addr);
114
}
115
116
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
117
* registers as pointers, so encode the regno into the data field.
118
* For consistency, do this even for LD1.
119
*/
120
- desc = simd_desc(vsz, vsz, zt | desc);
121
+ desc = make_svemte_desc(s, vec_full_reg_size(s), nregs,
122
+ dtype_msz(dtype), is_write, zt);
123
t_pg = tcg_temp_new_ptr();
124
125
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
126
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm,
127
int scale, TCGv_i64 scalar, int msz, bool is_write,
128
gen_helper_gvec_mem_scatter *fn)
47
{
129
{
48
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
130
- unsigned vsz = vec_full_reg_size(s);
49
DeviceState *dev, *sysctl, *gpio2, *pl041;
131
TCGv_ptr t_zm = tcg_temp_new_ptr();
50
SysBusDevice *busdev;
132
TCGv_ptr t_pg = tcg_temp_new_ptr();
51
qemu_irq pic[64];
133
TCGv_ptr t_zt = tcg_temp_new_ptr();
52
- qemu_irq mmc_irq[2];
134
- int desc = 0;
53
PCIBus *pci_bus = NULL;
135
-
54
NICInfo *nd;
136
- if (s->mte_active[0]) {
55
DriveInfo *dinfo;
137
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
56
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
138
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
57
* and the PL061 has them the other way about. Also the card
139
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
58
* detect line is inverted.
140
- desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
59
*/
141
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << msz) - 1);
60
- mmc_irq[0] = qemu_irq_split(
142
- desc <<= SVE_MTEDESC_SHIFT;
61
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
143
- }
62
- qdev_get_gpio_in(gpio2, 1));
144
- desc = simd_desc(vsz, vsz, desc | scale);
63
- mmc_irq[1] = qemu_irq_split(
145
+ uint32_t desc;
64
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
146
65
- qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
147
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
66
- qdev_connect_gpio_out_named(dev, "card-read-only", 0, mmc_irq[0]);
148
tcg_gen_addi_ptr(t_zm, tcg_env, vec_full_reg_offset(s, zm));
67
- qdev_connect_gpio_out_named(dev, "card-inserted", 0, mmc_irq[1]);
149
tcg_gen_addi_ptr(t_zt, tcg_env, vec_full_reg_offset(s, zt));
68
+ split_irq_from_named(dev, "card-read-only",
69
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
70
+ qdev_get_gpio_in(gpio2, 1));
71
+
150
+
72
+ split_irq_from_named(dev, "card-inserted",
151
+ desc = make_svemte_desc(s, vec_full_reg_size(s), 1, msz, is_write, scale);
73
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
152
fn(tcg_env, t_zt, t_pg, t_zm, scalar, tcg_constant_i32(desc));
74
+ qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
153
}
75
+
154
76
dinfo = drive_get(IF_SD, 0, 0);
77
if (dinfo) {
78
DeviceState *card;
79
--
155
--
80
2.25.1
156
2.34.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
These functions "use the standard load helpers", but
4
fail to clean_data_tbi or populate mtedesc.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220406174303.2022038-5-edgar.iglesias@xilinx.com
9
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
10
Message-id: 20240207025210.8837-6-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
---
12
---
11
include/hw/arm/xlnx-versal.h | 4 +++
13
target/arm/tcg/translate-sve.c | 15 +++++++++++++--
12
hw/arm/xlnx-versal.c | 54 ++++++++++++++++++++++++++++++++++--
14
1 file changed, 13 insertions(+), 2 deletions(-)
13
2 files changed, 56 insertions(+), 2 deletions(-)
14
15
15
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
16
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/xlnx-versal.h
18
--- a/target/arm/tcg/translate-sve.c
18
+++ b/include/hw/arm/xlnx-versal.h
19
+++ b/target/arm/tcg/translate-sve.c
19
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
20
#include "hw/nvram/xlnx-versal-efuse.h"
21
unsigned vsz = vec_full_reg_size(s);
21
#include "hw/ssi/xlnx-versal-ospi.h"
22
TCGv_ptr t_pg;
22
#include "hw/dma/xlnx_csu_dma.h"
23
int poff;
23
+#include "hw/misc/xlnx-versal-crl.h"
24
+ uint32_t desc;
24
#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
25
25
26
/* Load the first quadword using the normal predicated load helpers. */
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
27
+ if (!s->mte_active[0]) {
27
@@ -XXX,XX +XXX,XX @@ struct Versal {
28
+ addr = clean_data_tbi(s, addr);
28
qemu_or_irq irq_orgate;
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
46
--- a/hw/arm/xlnx-versal.c
47
+++ b/hw/arm/xlnx-versal.c
48
@@ -XXX,XX +XXX,XX @@ static void versal_create_ospi(Versal *s, qemu_irq *pic)
49
qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
50
}
51
52
+static void versal_create_crl(Versal *s, qemu_irq *pic)
53
+{
54
+ SysBusDevice *sbd;
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
+ }
29
+ }
68
+
30
+
69
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
31
poff = pred_full_reg_offset(s, pg);
70
+ g_autofree gchar *name = g_strdup_printf("gem[%d]", i);
32
if (vsz > 16) {
71
+
33
/*
72
+ object_property_set_link(OBJECT(&s->lpd.crl),
34
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
73
+ name, OBJECT(&s->lpd.iou.gem[i]),
35
74
+ &error_abort);
36
gen_helper_gvec_mem *fn
37
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
38
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(16, 16, zt)));
39
+ desc = make_svemte_desc(s, 16, 1, dtype_msz(dtype), false, zt);
40
+ fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
41
42
/* Replicate that first quadword. */
43
if (vsz > 16) {
44
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
45
unsigned vsz_r32;
46
TCGv_ptr t_pg;
47
int poff, doff;
48
+ uint32_t desc;
49
50
if (vsz < 32) {
51
/*
52
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
53
}
54
55
/* Load the first octaword using the normal predicated load helpers. */
56
+ if (!s->mte_active[0]) {
57
+ addr = clean_data_tbi(s, addr);
75
+ }
58
+ }
76
+
59
77
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
60
poff = pred_full_reg_offset(s, pg);
78
+ g_autofree gchar *name = g_strdup_printf("adma[%d]", i);
61
if (vsz > 32) {
79
+
62
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
80
+ object_property_set_link(OBJECT(&s->lpd.crl),
63
81
+ name, OBJECT(&s->lpd.iou.adma[i]),
64
gen_helper_gvec_mem *fn
82
+ &error_abort);
65
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
83
+ }
66
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(32, 32, zt)));
84
+
67
+ desc = make_svemte_desc(s, 32, 1, dtype_msz(dtype), false, zt);
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) {
68
+ fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
86
+ g_autofree gchar *name = g_strdup_printf("uart[%d]", i);
69
87
+
70
/*
88
+ object_property_set_link(OBJECT(&s->lpd.crl),
71
* Replicate that first octaword.
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
+}
102
+
103
/* This takes the board allocated linear DDR memory and creates aliases
104
* for each split DDR range/aperture on the Versal address map.
105
*/
106
@@ -XXX,XX +XXX,XX @@ static void versal_unimp(Versal *s)
107
108
versal_unimp_area(s, "psm", &s->mr_ps,
109
MM_PSM_START, MM_PSM_END - MM_PSM_START);
110
- versal_unimp_area(s, "crl", &s->mr_ps,
111
- MM_CRL, MM_CRL_SIZE);
112
versal_unimp_area(s, "crf", &s->mr_ps,
113
MM_FPD_CRF, MM_FPD_CRF_SIZE);
114
versal_unimp_area(s, "apu", &s->mr_ps,
115
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
116
versal_create_efuse(s, pic);
117
versal_create_pmc_iou_slcr(s, pic);
118
versal_create_ospi(s, pic);
119
+ versal_create_crl(s, pic);
120
versal_map_ddr(s);
121
versal_unimp(s);
122
123
--
72
--
124
2.25.1
73
2.34.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
The TBI and TCMA bits are located within mtedesc, not desc.
4
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Message-id: 20240207025210.8837-7-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
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
---
11
---
11
include/hw/arm/exynos4210.h | 2 ++
12
target/arm/tcg/sme_helper.c | 8 ++++----
12
hw/arm/exynos4210.c | 11 ++++++-----
13
target/arm/tcg/sve_helper.c | 12 ++++++------
13
2 files changed, 8 insertions(+), 5 deletions(-)
14
2 files changed, 10 insertions(+), 10 deletions(-)
14
15
15
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
16
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/exynos4210.h
18
--- a/target/arm/tcg/sme_helper.c
18
+++ b/include/hw/arm/exynos4210.h
19
+++ b/target/arm/tcg/sme_helper.c
19
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ void sme_ld1_mte(CPUARMState *env, void *za, uint64_t *vg,
20
21
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
21
#include "hw/or-irq.h"
22
22
#include "hw/sysbus.h"
23
/* Perform gross MTE suppression early. */
23
+#include "hw/cpu/a9mpcore.h"
24
- if (!tbi_check(desc, bit55) ||
24
#include "target/arm/cpu-qom.h"
25
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
25
#include "qom/object.h"
26
+ if (!tbi_check(mtedesc, bit55) ||
26
27
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
27
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
28
mtedesc = 0;
28
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
29
}
29
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
30
30
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
31
@@ -XXX,XX +XXX,XX @@ void sme_st1_mte(CPUARMState *env, void *za, uint64_t *vg, target_ulong addr,
31
+ A9MPPrivState a9mpcore;
32
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
32
};
33
33
34
/* Perform gross MTE suppression early. */
34
#define TYPE_EXYNOS4210_SOC "exynos4210"
35
- if (!tbi_check(desc, bit55) ||
35
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
36
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
37
+ if (!tbi_check(mtedesc, bit55) ||
38
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
39
mtedesc = 0;
40
}
41
42
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
36
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/arm/exynos4210.c
44
--- a/target/arm/tcg/sve_helper.c
38
+++ b/hw/arm/exynos4210.c
45
+++ b/target/arm/tcg/sve_helper.c
39
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
46
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
47
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
48
49
/* Perform gross MTE suppression early. */
50
- if (!tbi_check(desc, bit55) ||
51
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
52
+ if (!tbi_check(mtedesc, bit55) ||
53
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
54
mtedesc = 0;
40
}
55
}
41
56
42
/* Private memory region and Internal GIC */
57
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r_mte(CPUARMState *env, void *vg, target_ulong addr,
43
- dev = qdev_new(TYPE_A9MPCORE_PRIV);
58
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
44
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
59
45
- busdev = SYS_BUS_DEVICE(dev);
60
/* Perform gross MTE suppression early. */
46
- sysbus_realize_and_unref(busdev, &error_fatal);
61
- if (!tbi_check(desc, bit55) ||
47
+ qdev_prop_set_uint32(DEVICE(&s->a9mpcore), "num-cpu", EXYNOS4210_NCPUS);
62
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
48
+ busdev = SYS_BUS_DEVICE(&s->a9mpcore);
63
+ if (!tbi_check(mtedesc, bit55) ||
49
+ sysbus_realize(busdev, &error_fatal);
64
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
50
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
65
mtedesc = 0;
51
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
52
sysbus_connect_irq(busdev, n,
53
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
54
}
66
}
55
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
67
56
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
68
@@ -XXX,XX +XXX,XX @@ void sve_stN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
57
+ s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
69
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
70
71
/* Perform gross MTE suppression early. */
72
- if (!tbi_check(desc, bit55) ||
73
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
74
+ if (!tbi_check(mtedesc, bit55) ||
75
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
76
mtedesc = 0;
58
}
77
}
59
78
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
+
66
+ object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
67
}
68
69
static void exynos4210_class_init(ObjectClass *klass, void *data)
70
--
79
--
71
2.25.1
80
2.34.1
diff view generated by jsdifflib
New patch
1
The raven_io_ops MemoryRegionOps is the only one in the source tree
2
which sets .valid.unaligned to indicate that it should support
3
unaligned accesses and which does not also set .impl.unaligned to
4
indicate that its read and write functions can do the unaligned
5
handling themselves. This is a problem, because at the moment the
6
core memory system does not implement the support for handling
7
unaligned accesses by doing a series of aligned accesses and
8
combining them (system/memory.c:access_with_adjusted_size() has a
9
TODO comment noting this).
1
10
11
Fortunately raven_io_read() and raven_io_write() will correctly deal
12
with the case of being passed an unaligned address, so we can fix the
13
missing unaligned access support by setting .impl.unaligned in the
14
MemoryRegionOps struct.
15
16
Fixes: 9a1839164c9c8f06 ("raven: Implement non-contiguous I/O region")
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Tested-by: Cédric Le Goater <clg@redhat.com>
19
Reviewed-by: Cédric Le Goater <clg@redhat.com>
20
Message-id: 20240112134640.1775041-1-peter.maydell@linaro.org
21
---
22
hw/pci-host/raven.c | 1 +
23
1 file changed, 1 insertion(+)
24
25
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/pci-host/raven.c
28
+++ b/hw/pci-host/raven.c
29
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps raven_io_ops = {
30
.write = raven_io_write,
31
.endianness = DEVICE_LITTLE_ENDIAN,
32
.impl.max_access_size = 4,
33
+ .impl.unaligned = true,
34
.valid.unaligned = true,
35
};
36
37
--
38
2.34.1
39
40
diff view generated by jsdifflib
1
The only time we use the int_combiner_irq[] and ext_combiner_irq[]
1
Suppress the deprecation warning when we're running under qtest,
2
arrays in the Exynos4210Irq struct is during realize of the SoC -- we
2
to avoid "make check" including warning messages in its output.
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
10
Since these are the only two remaining elements of Exynos4210Irq,
11
we can remove that struct entirely.
12
3
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
Message-id: 20220404154658.565020-19-peter.maydell@linaro.org
6
Message-id: 20240206154151.155620-1-peter.maydell@linaro.org
16
---
7
---
17
include/hw/arm/exynos4210.h | 6 ------
8
hw/block/tc58128.c | 4 +++-
18
hw/arm/exynos4210.c | 34 ++++++++--------------------------
9
1 file changed, 3 insertions(+), 1 deletion(-)
19
2 files changed, 8 insertions(+), 32 deletions(-)
20
10
21
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
11
diff --git a/hw/block/tc58128.c b/hw/block/tc58128.c
22
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/exynos4210.h
13
--- a/hw/block/tc58128.c
24
+++ b/include/hw/arm/exynos4210.h
14
+++ b/hw/block/tc58128.c
25
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static sh7750_io_device tc58128 = {
26
*/
16
27
#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
17
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2)
28
29
-typedef struct Exynos4210Irq {
30
- qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
31
- qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
32
-} Exynos4210Irq;
33
-
34
struct Exynos4210State {
35
/*< private >*/
36
SysBusDevice parent_obj;
37
/*< public >*/
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
39
- Exynos4210Irq irqs;
40
qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
41
42
MemoryRegion chipid_mem;
43
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/arm/exynos4210.c
46
+++ b/hw/arm/exynos4210.c
47
@@ -XXX,XX +XXX,XX @@ static int mapline_size(const int *mapline)
48
static void exynos4210_init_board_irqs(Exynos4210State *s)
49
{
18
{
50
uint32_t grp, bit, irq_id, n;
19
- warn_report_once("The TC58128 flash device is deprecated");
51
- Exynos4210Irq *is = &s->irqs;
20
+ if (!qtest_enabled()) {
52
DeviceState *extgicdev = DEVICE(&s->ext_gic);
21
+ warn_report_once("The TC58128 flash device is deprecated");
53
+ DeviceState *intcdev = DEVICE(&s->int_combiner);
22
+ }
54
+ DeviceState *extcdev = DEVICE(&s->ext_combiner);
23
init_dev(&tc58128_devs[0], zone1);
55
int splitcount = 0;
24
init_dev(&tc58128_devs[1], zone2);
56
DeviceState *splitter;
25
return sh7750_register_io_device(s, &tc58128);
57
const int *mapline;
58
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
59
splitin = 0;
60
for (;;) {
61
s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
62
- qdev_connect_gpio_out(splitter, splitin, is->int_combiner_irq[in]);
63
- qdev_connect_gpio_out(splitter, splitin + 1, is->ext_combiner_irq[in]);
64
+ qdev_connect_gpio_out(splitter, splitin,
65
+ qdev_get_gpio_in(intcdev, in));
66
+ qdev_connect_gpio_out(splitter, splitin + 1,
67
+ qdev_get_gpio_in(extcdev, in));
68
splitin += 2;
69
if (!mapline) {
70
break;
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
72
qdev_realize(splitter, NULL, &error_abort);
73
splitcount++;
74
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
75
- qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
76
+ qdev_connect_gpio_out(splitter, 0, qdev_get_gpio_in(intcdev, n));
77
qdev_connect_gpio_out(splitter, 1,
78
qdev_get_gpio_in(extgicdev, irq_id - 32));
79
} else {
80
- s->irq_table[n] = is->int_combiner_irq[n];
81
+ s->irq_table[n] = qdev_get_gpio_in(intcdev, n);
82
}
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
}
88
89
-/*
90
- * Get Combiner input GPIO into irqs structure
91
- */
92
-static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
93
- DeviceState *dev, int ext)
94
-{
95
- int n;
96
- int max;
97
- qemu_irq *irq;
98
-
99
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
100
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
101
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
102
-
103
- for (n = 0; n < max; n++) {
104
- irq[n] = qdev_get_gpio_in(dev, n);
105
- }
106
-}
107
-
108
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
109
0x09, 0x00, 0x00, 0x00 };
110
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
112
sysbus_connect_irq(busdev, n,
113
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
114
}
115
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
116
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
117
118
/* External Interrupt Combiner */
119
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
120
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
121
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
122
}
123
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
124
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
125
126
/* Initialize board IRQs. */
127
--
26
--
128
2.25.1
27
2.34.1
28
29
diff view generated by jsdifflib
New patch
1
We deliberately don't include qtests_npcm7xx in qtests_aarch64,
2
because we already get the coverage of those tests via qtests_arm,
3
and we don't want to use extra CI minutes testing them twice.
1
4
5
In commit 327b680877b79c4b we added it to qtests_aarch64; revert
6
that change.
7
8
Fixes: 327b680877b79c4b ("tests/qtest: Creating qtest for GMAC Module")
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20240206163043.315535-1-peter.maydell@linaro.org
12
---
13
tests/qtest/meson.build | 1 -
14
1 file changed, 1 deletion(-)
15
16
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
17
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/qtest/meson.build
19
+++ b/tests/qtest/meson.build
20
@@ -XXX,XX +XXX,XX @@ qtests_aarch64 = \
21
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
22
(config_all_accel.has_key('CONFIG_TCG') and \
23
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
24
- (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
25
['arm-cpu-features',
26
'numa-test',
27
'boot-serial-test',
28
--
29
2.34.1
30
31
diff view generated by jsdifflib
1
In exynos4210_init_board_irqs(), the loop that handles IRQ lines that
1
Allow changes to the virt GTDT -- we are going to add the IRQ
2
are in a range that applies to the internal combiner only creates a
2
entry for a new timer to it.
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
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
3
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
23
Message-id: 20220404154658.565020-14-peter.maydell@linaro.org
6
Message-id: 20240122143537.233498-2-peter.maydell@linaro.org
24
---
7
---
25
hw/arm/exynos4210.c | 2 ++
8
tests/qtest/bios-tables-test-allowed-diff.h | 2 ++
26
1 file changed, 2 insertions(+)
9
1 file changed, 2 insertions(+)
27
10
28
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
11
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
29
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/exynos4210.c
13
--- a/tests/qtest/bios-tables-test-allowed-diff.h
31
+++ b/hw/arm/exynos4210.c
14
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
32
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
15
@@ -1 +1,3 @@
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
16
/* List of comma-separated changed AML files to ignore */
34
qdev_connect_gpio_out(splitter, 1,
17
+"tests/data/acpi/virt/FACP",
35
qdev_get_gpio_in(extgicdev, irq_id - 32));
18
+"tests/data/acpi/virt/GTDT",
36
+ } else {
37
+ s->irq_table[n] = is->int_combiner_irq[n];
38
}
39
}
40
/*
41
--
19
--
42
2.25.1
20
2.34.1
diff view generated by jsdifflib
1
It's not possible to provide the guest with the Security extensions
1
Armv8.1+ CPUs have the Virtual Host Extension (VHE) which adds a
2
(TrustZone) when using KVM or HVF, because the hardware
2
non-secure EL2 virtual timer. We implemented the timer itself in the
3
virtualization extensions don't permit running EL3 guest code.
3
CPU model, but never wired up its IRQ line to the GIC.
4
However, we weren't checking for this combination, with the result
4
5
that QEMU would assert if you tried it:
5
Wire up the IRQ line (this is always safe whether the CPU has the
6
6
interrupt or not, since it always creates the outbound IRQ line).
7
$ qemu-system-aarch64 -enable-kvm -machine virt,secure=on -cpu host -display none
7
Report it to the guest via dtb and ACPI if the CPU has the feature.
8
Unexpected error in object_property_find_err() at ../../qom/object.c:1304:
8
9
qemu-system-aarch64: Property 'host-arm-cpu.secure-memory' not found
9
The DTB binding is documented in the kernel's
10
Aborted
10
Documentation/devicetree/bindings/timer/arm\,arch_timer.yaml
11
11
and the ACPI table entries are documented in the ACPI specification
12
Check for this combination of options and report an error, in the
12
version 6.3 or later.
13
same way we already do for attempts to give a KVM or HVF guest the
13
14
Virtualization or MTE extensions. Now we will report:
14
Because the IRQ line ACPI binding is new in 6.3, we need to bump the
15
15
FADT table rev to show that we might be using 6.3 features.
16
qemu-system-aarch64: mach-virt: KVM does not support providing Security extensions (TrustZone) to the guest CPU
16
17
17
Note that exposing this IRQ in the DTB will trigger a bug in EDK2
18
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/961
18
versions prior to edk2-stable202311, for users who use the virt board
19
with 'virtualization=on' to enable EL2 emulation and are booting an
20
EDK2 guest BIOS, if that EDK2 has assertions enabled. The effect is
21
that EDK2 will assert on bootup:
22
23
ASSERT [ArmTimerDxe] /home/kraxel/projects/qemu/roms/edk2/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.c(72): PropSize == 36 || PropSize == 48
24
25
If you see that assertion you should do one of:
26
* update your EDK2 binaries to edk2-stable202311 or newer
27
* use the 'virt-8.2' versioned machine type
28
* not use 'virtualization=on'
29
30
(The versions shipped with QEMU itself have the fix.)
31
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
33
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
21
Message-id: 20220404155301.566542-1-peter.maydell@linaro.org
34
Message-id: 20240122143537.233498-3-peter.maydell@linaro.org
22
---
35
---
23
hw/arm/virt.c | 7 +++++++
36
include/hw/arm/virt.h | 2 ++
24
1 file changed, 7 insertions(+)
37
hw/arm/virt-acpi-build.c | 20 ++++++++++----
25
38
hw/arm/virt.c | 60 ++++++++++++++++++++++++++++++++++------
39
3 files changed, 67 insertions(+), 15 deletions(-)
40
41
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/include/hw/arm/virt.h
44
+++ b/include/hw/arm/virt.h
45
@@ -XXX,XX +XXX,XX @@ struct VirtMachineClass {
46
/* Machines < 6.2 have no support for describing cpu topology to guest */
47
bool no_cpu_topology;
48
bool no_tcg_lpa2;
49
+ bool no_ns_el2_virt_timer_irq;
50
};
51
52
struct VirtMachineState {
53
@@ -XXX,XX +XXX,XX @@ struct VirtMachineState {
54
PCIBus *bus;
55
char *oem_id;
56
char *oem_table_id;
57
+ bool ns_el2_virt_timer_irq;
58
};
59
60
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
61
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/virt-acpi-build.c
64
+++ b/hw/arm/virt-acpi-build.c
65
@@ -XXX,XX +XXX,XX @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
66
}
67
68
/*
69
- * ACPI spec, Revision 5.1
70
- * 5.2.24 Generic Timer Description Table (GTDT)
71
+ * ACPI spec, Revision 6.5
72
+ * 5.2.25 Generic Timer Description Table (GTDT)
73
*/
74
static void
75
build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
76
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
77
uint32_t irqflags = vmc->claim_edge_triggered_timers ?
78
1 : /* Interrupt is Edge triggered */
79
0; /* Interrupt is Level triggered */
80
- AcpiTable table = { .sig = "GTDT", .rev = 2, .oem_id = vms->oem_id,
81
+ AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id,
82
.oem_table_id = vms->oem_table_id };
83
84
acpi_table_begin(&table, table_data);
85
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
86
build_append_int_noprefix(table_data, 0, 4);
87
/* Platform Timer Offset */
88
build_append_int_noprefix(table_data, 0, 4);
89
-
90
+ if (vms->ns_el2_virt_timer_irq) {
91
+ /* Virtual EL2 Timer GSIV */
92
+ build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL2_VIRT_IRQ, 4);
93
+ /* Virtual EL2 Timer Flags */
94
+ build_append_int_noprefix(table_data, irqflags, 4);
95
+ } else {
96
+ build_append_int_noprefix(table_data, 0, 4);
97
+ build_append_int_noprefix(table_data, 0, 4);
98
+ }
99
acpi_table_end(linker, &table);
100
}
101
102
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
103
static void build_fadt_rev6(GArray *table_data, BIOSLinker *linker,
104
VirtMachineState *vms, unsigned dsdt_tbl_offset)
105
{
106
- /* ACPI v6.0 */
107
+ /* ACPI v6.3 */
108
AcpiFadtData fadt = {
109
.rev = 6,
110
- .minor_ver = 0,
111
+ .minor_ver = 3,
112
.flags = 1 << ACPI_FADT_F_HW_REDUCED_ACPI,
113
.xdsdt_tbl_offset = &dsdt_tbl_offset,
114
};
26
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
115
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
27
index XXXXXXX..XXXXXXX 100644
116
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/virt.c
117
--- a/hw/arm/virt.c
29
+++ b/hw/arm/virt.c
118
+++ b/hw/arm/virt.c
119
@@ -XXX,XX +XXX,XX @@ static void create_randomness(MachineState *ms, const char *node)
120
qemu_fdt_setprop(ms->fdt, node, "rng-seed", seed.rng, sizeof(seed.rng));
121
}
122
123
+/*
124
+ * The CPU object always exposes the NS EL2 virt timer IRQ line,
125
+ * but we don't want to advertise it to the guest in the dtb or ACPI
126
+ * table unless it's really going to do something.
127
+ */
128
+static bool ns_el2_virt_timer_present(void)
129
+{
130
+ ARMCPU *cpu = ARM_CPU(qemu_get_cpu(0));
131
+ CPUARMState *env = &cpu->env;
132
+
133
+ return arm_feature(env, ARM_FEATURE_AARCH64) &&
134
+ arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu);
135
+}
136
+
137
static void create_fdt(VirtMachineState *vms)
138
{
139
MachineState *ms = MACHINE(vms);
140
@@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
141
"arm,armv7-timer");
142
}
143
qemu_fdt_setprop(ms->fdt, "/timer", "always-on", NULL, 0);
144
- qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
145
- GIC_FDT_IRQ_TYPE_PPI,
146
- INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
147
- GIC_FDT_IRQ_TYPE_PPI,
148
- INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
149
- GIC_FDT_IRQ_TYPE_PPI,
150
- INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
151
- GIC_FDT_IRQ_TYPE_PPI,
152
- INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
153
+ if (vms->ns_el2_virt_timer_irq) {
154
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
155
+ GIC_FDT_IRQ_TYPE_PPI,
156
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
157
+ GIC_FDT_IRQ_TYPE_PPI,
158
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
159
+ GIC_FDT_IRQ_TYPE_PPI,
160
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
161
+ GIC_FDT_IRQ_TYPE_PPI,
162
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags,
163
+ GIC_FDT_IRQ_TYPE_PPI,
164
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_VIRT_IRQ), irqflags);
165
+ } else {
166
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
167
+ GIC_FDT_IRQ_TYPE_PPI,
168
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
169
+ GIC_FDT_IRQ_TYPE_PPI,
170
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
171
+ GIC_FDT_IRQ_TYPE_PPI,
172
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
173
+ GIC_FDT_IRQ_TYPE_PPI,
174
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
175
+ }
176
}
177
178
static void fdt_add_cpu_nodes(const VirtMachineState *vms)
179
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
180
[GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
181
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
182
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
183
+ [GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
184
};
185
186
for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
30
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
187
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
31
exit(1);
188
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
189
object_unref(cpuobj);
32
}
190
}
33
191
+
34
+ if (vms->secure && (kvm_enabled() || hvf_enabled())) {
192
+ /* Now we've created the CPUs we can see if they have the hypvirt timer */
35
+ error_report("mach-virt: %s does not support providing "
193
+ vms->ns_el2_virt_timer_irq = ns_el2_virt_timer_present() &&
36
+ "Security extensions (TrustZone) to the guest CPU",
194
+ !vmc->no_ns_el2_virt_timer_irq;
37
+ kvm_enabled() ? "KVM" : "HVF");
195
+
38
+ exit(1);
196
fdt_add_timer_nodes(vms);
39
+ }
197
fdt_add_cpu_nodes(vms);
40
+
198
41
if (vms->virt && (kvm_enabled() || hvf_enabled())) {
199
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(9, 0)
42
error_report("mach-virt: %s does not support providing "
200
43
"Virtualization extensions to the guest CPU",
201
static void virt_machine_8_2_options(MachineClass *mc)
202
{
203
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
204
+
205
virt_machine_9_0_options(mc);
206
compat_props_add(mc->compat_props, hw_compat_8_2, hw_compat_8_2_len);
207
+ /*
208
+ * Don't expose NS_EL2_VIRT timer IRQ in DTB on ACPI on 8.2 and
209
+ * earlier machines. (Exposing it tickles a bug in older EDK2
210
+ * guest BIOS binaries.)
211
+ */
212
+ vmc->no_ns_el2_virt_timer_irq = true;
213
}
214
DEFINE_VIRT_MACHINE(8, 2)
215
44
--
216
--
45
2.25.1
217
2.34.1
diff view generated by jsdifflib
1
Currently for the interrupts MCT_G0 and MCT_G1 which are
1
Update the virt golden reference files to say that the FACP is ACPI
2
the only ones in the input range of the external combiner
2
v6.3, and the GTDT table is a revision 3 table with space for the
3
and which are also wired to the external GIC, we connect
3
virtual EL2 timer.
4
them only to the internal combiner and the external GIC.
4
5
This seems likely to be a bug, as all other interrupts
5
Diffs from iasl:
6
which are in the input range of both combiners are
6
7
connected to both combiners. (The fact that the code in
7
@@ -XXX,XX +XXX,XX @@
8
exynos4210_combiner_get_gpioin() is also trying to wire
8
/*
9
up these inputs on both combiners also suggests this.)
9
* Intel ACPI Component Architecture
10
10
* AML/ASL+ Disassembler version 20200925 (64-bit version)
11
Wire these interrupts up to both combiners, like the rest.
11
* Copyright (c) 2000 - 2020 Intel Corporation
12
*
13
- * Disassembly of tests/data/acpi/virt/FACP, Mon Jan 22 13:48:40 2024
14
+ * Disassembly of /tmp/aml-W8RZH2, Mon Jan 22 13:48:40 2024
15
*
16
* ACPI Data Table [FACP]
17
*
18
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
19
*/
20
21
[000h 0000 4] Signature : "FACP" [Fixed ACPI Description Table (FADT)]
22
[004h 0004 4] Table Length : 00000114
23
[008h 0008 1] Revision : 06
24
-[009h 0009 1] Checksum : 15
25
+[009h 0009 1] Checksum : 12
26
[00Ah 0010 6] Oem ID : "BOCHS "
27
[010h 0016 8] Oem Table ID : "BXPC "
28
[018h 0024 4] Oem Revision : 00000001
29
[01Ch 0028 4] Asl Compiler ID : "BXPC"
30
[020h 0032 4] Asl Compiler Revision : 00000001
31
32
[024h 0036 4] FACS Address : 00000000
33
[028h 0040 4] DSDT Address : 00000000
34
[02Ch 0044 1] Model : 00
35
[02Dh 0045 1] PM Profile : 00 [Unspecified]
36
[02Eh 0046 2] SCI Interrupt : 0000
37
[030h 0048 4] SMI Command Port : 00000000
38
[034h 0052 1] ACPI Enable Value : 00
39
[035h 0053 1] ACPI Disable Value : 00
40
[036h 0054 1] S4BIOS Command : 00
41
[037h 0055 1] P-State Control : 00
42
@@ -XXX,XX +XXX,XX @@
43
Use APIC Physical Destination Mode (V4) : 0
44
Hardware Reduced (V5) : 1
45
Low Power S0 Idle (V5) : 0
46
47
[074h 0116 12] Reset Register : [Generic Address Structure]
48
[074h 0116 1] Space ID : 00 [SystemMemory]
49
[075h 0117 1] Bit Width : 00
50
[076h 0118 1] Bit Offset : 00
51
[077h 0119 1] Encoded Access Width : 00 [Undefined/Legacy]
52
[078h 0120 8] Address : 0000000000000000
53
54
[080h 0128 1] Value to cause reset : 00
55
[081h 0129 2] ARM Flags (decoded below) : 0003
56
PSCI Compliant : 1
57
Must use HVC for PSCI : 1
58
59
-[083h 0131 1] FADT Minor Revision : 00
60
+[083h 0131 1] FADT Minor Revision : 03
61
[084h 0132 8] FACS Address : 0000000000000000
62
[08Ch 0140 8] DSDT Address : 0000000000000000
63
[094h 0148 12] PM1A Event Block : [Generic Address Structure]
64
[094h 0148 1] Space ID : 00 [SystemMemory]
65
[095h 0149 1] Bit Width : 00
66
[096h 0150 1] Bit Offset : 00
67
[097h 0151 1] Encoded Access Width : 00 [Undefined/Legacy]
68
[098h 0152 8] Address : 0000000000000000
69
70
[0A0h 0160 12] PM1B Event Block : [Generic Address Structure]
71
[0A0h 0160 1] Space ID : 00 [SystemMemory]
72
[0A1h 0161 1] Bit Width : 00
73
[0A2h 0162 1] Bit Offset : 00
74
[0A3h 0163 1] Encoded Access Width : 00 [Undefined/Legacy]
75
[0A4h 0164 8] Address : 0000000000000000
76
77
@@ -XXX,XX +XXX,XX @@
78
[0F5h 0245 1] Bit Width : 00
79
[0F6h 0246 1] Bit Offset : 00
80
[0F7h 0247 1] Encoded Access Width : 00 [Undefined/Legacy]
81
[0F8h 0248 8] Address : 0000000000000000
82
83
[100h 0256 12] Sleep Status Register : [Generic Address Structure]
84
[100h 0256 1] Space ID : 00 [SystemMemory]
85
[101h 0257 1] Bit Width : 00
86
[102h 0258 1] Bit Offset : 00
87
[103h 0259 1] Encoded Access Width : 00 [Undefined/Legacy]
88
[104h 0260 8] Address : 0000000000000000
89
90
[10Ch 0268 8] Hypervisor ID : 00000000554D4551
91
92
Raw Table Data: Length 276 (0x114)
93
94
- 0000: 46 41 43 50 14 01 00 00 06 15 42 4F 43 48 53 20 // FACP......BOCHS
95
+ 0000: 46 41 43 50 14 01 00 00 06 12 42 4F 43 48 53 20 // FACP......BOCHS
96
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
97
0020: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
98
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
99
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
100
0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
101
0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
102
0070: 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
103
- 0080: 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
104
+ 0080: 00 03 00 03 00 00 00 00 00 00 00 00 00 00 00 00 // ................
105
0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
106
00A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
107
00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
108
00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
109
00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
110
00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
111
00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
112
0100: 00 00 00 00 00 00 00 00 00 00 00 00 51 45 4D 55 // ............QEMU
113
0110: 00 00 00 00 // ....
114
115
@@ -XXX,XX +XXX,XX @@
116
/*
117
* Intel ACPI Component Architecture
118
* AML/ASL+ Disassembler version 20200925 (64-bit version)
119
* Copyright (c) 2000 - 2020 Intel Corporation
120
*
121
- * Disassembly of tests/data/acpi/virt/GTDT, Mon Jan 22 13:48:40 2024
122
+ * Disassembly of /tmp/aml-XDSZH2, Mon Jan 22 13:48:40 2024
123
*
124
* ACPI Data Table [GTDT]
125
*
126
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
127
*/
128
129
[000h 0000 4] Signature : "GTDT" [Generic Timer Description Table]
130
-[004h 0004 4] Table Length : 00000060
131
-[008h 0008 1] Revision : 02
132
-[009h 0009 1] Checksum : 9C
133
+[004h 0004 4] Table Length : 00000068
134
+[008h 0008 1] Revision : 03
135
+[009h 0009 1] Checksum : 93
136
[00Ah 0010 6] Oem ID : "BOCHS "
137
[010h 0016 8] Oem Table ID : "BXPC "
138
[018h 0024 4] Oem Revision : 00000001
139
[01Ch 0028 4] Asl Compiler ID : "BXPC"
140
[020h 0032 4] Asl Compiler Revision : 00000001
141
142
[024h 0036 8] Counter Block Address : FFFFFFFFFFFFFFFF
143
[02Ch 0044 4] Reserved : 00000000
144
145
[030h 0048 4] Secure EL1 Interrupt : 0000001D
146
[034h 0052 4] EL1 Flags (decoded below) : 00000000
147
Trigger Mode : 0
148
Polarity : 0
149
Always On : 0
150
151
[038h 0056 4] Non-Secure EL1 Interrupt : 0000001E
152
@@ -XXX,XX +XXX,XX @@
153
154
[040h 0064 4] Virtual Timer Interrupt : 0000001B
155
[044h 0068 4] VT Flags (decoded below) : 00000000
156
Trigger Mode : 0
157
Polarity : 0
158
Always On : 0
159
160
[048h 0072 4] Non-Secure EL2 Interrupt : 0000001A
161
[04Ch 0076 4] NEL2 Flags (decoded below) : 00000000
162
Trigger Mode : 0
163
Polarity : 0
164
Always On : 0
165
[050h 0080 8] Counter Read Block Address : FFFFFFFFFFFFFFFF
166
167
[058h 0088 4] Platform Timer Count : 00000000
168
[05Ch 0092 4] Platform Timer Offset : 00000000
169
+[060h 0096 4] Virtual EL2 Timer GSIV : 00000000
170
+[064h 0100 4] Virtual EL2 Timer Flags : 00000000
171
172
-Raw Table Data: Length 96 (0x60)
173
+Raw Table Data: Length 104 (0x68)
174
175
- 0000: 47 54 44 54 60 00 00 00 02 9C 42 4F 43 48 53 20 // GTDT`.....BOCHS
176
+ 0000: 47 54 44 54 68 00 00 00 03 93 42 4F 43 48 53 20 // GTDTh.....BOCHS
177
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
178
0020: 01 00 00 00 FF FF FF FF FF FF FF FF 00 00 00 00 // ................
179
0030: 1D 00 00 00 00 00 00 00 1E 00 00 00 04 00 00 00 // ................
180
0040: 1B 00 00 00 00 00 00 00 1A 00 00 00 00 00 00 00 // ................
181
0050: FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 // ................
182
+ 0060: 00 00 00 00 00 00 00 00 // ........
12
183
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
184
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
185
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
15
Message-id: 20220404154658.565020-15-peter.maydell@linaro.org
186
Message-id: 20240122143537.233498-4-peter.maydell@linaro.org
16
---
187
---
17
hw/arm/exynos4210.c | 7 +++----
188
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
18
1 file changed, 3 insertions(+), 4 deletions(-)
189
tests/data/acpi/virt/FACP | Bin 276 -> 276 bytes
19
190
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
20
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
191
3 files changed, 2 deletions(-)
192
193
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
21
index XXXXXXX..XXXXXXX 100644
194
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/exynos4210.c
195
--- a/tests/qtest/bios-tables-test-allowed-diff.h
23
+++ b/hw/arm/exynos4210.c
196
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
24
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
197
@@ -1,3 +1 @@
25
198
/* List of comma-separated changed AML files to ignore */
26
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
199
-"tests/data/acpi/virt/FACP",
27
splitter = DEVICE(&s->splitter[splitcount]);
200
-"tests/data/acpi/virt/GTDT",
28
- qdev_prop_set_uint16(splitter, "num-lines", 2);
201
diff --git a/tests/data/acpi/virt/FACP b/tests/data/acpi/virt/FACP
29
+ qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
202
index XXXXXXX..XXXXXXX 100644
30
qdev_realize(splitter, NULL, &error_abort);
203
GIT binary patch
31
splitcount++;
204
delta 25
32
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
205
gcmbQjG=+)F&CxkPgpq-PO=u!l<;2F$$vli407<0<)c^nh
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
206
34
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
207
delta 28
35
if (irq_id) {
208
kcmbQjG=+)F&CxkPgpq-PO>`nx<-|!<6Akz$^DuG%0AAS!ssI20
36
- qdev_connect_gpio_out(splitter, 1,
209
37
+ qdev_connect_gpio_out(splitter, 2,
210
diff --git a/tests/data/acpi/virt/GTDT b/tests/data/acpi/virt/GTDT
38
qdev_get_gpio_in(extgicdev, irq_id - 32));
211
index XXXXXXX..XXXXXXX 100644
39
- } else {
212
GIT binary patch
40
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
213
delta 25
41
}
214
bcmYeu;BpUf3CUn!U|^m+kt>V?$N&QXMtB4L
42
}
215
43
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
216
delta 16
217
Xcmc~u;BpUf2}xjJU|^avkt+-UB60)u
218
44
--
219
--
45
2.25.1
220
2.34.1
diff view generated by jsdifflib
New patch
1
The patchset adding the GMAC ethernet to this SoC crossed in the
2
mail with the patchset cleaning up the NIC handling. When we
3
create the GMAC modules we must call qemu_configure_nic_device()
4
so that the user has the opportunity to use the -nic commandline
5
option to create a network backend and connect it to the GMACs.
1
6
7
Add the missing call.
8
9
Fixes: 21e5326a7c ("hw/arm: Add GMAC devices to NPCM7XX SoC")
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
12
Message-id: 20240206171231.396392-2-peter.maydell@linaro.org
13
---
14
hw/arm/npcm7xx.c | 1 +
15
1 file changed, 1 insertion(+)
16
17
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/npcm7xx.c
20
+++ b/hw/arm/npcm7xx.c
21
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
22
for (i = 0; i < ARRAY_SIZE(s->gmac); i++) {
23
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->gmac[i]);
24
25
+ qemu_configure_nic_device(DEVICE(sbd), false, NULL);
26
/*
27
* The device exists regardless of whether it's connected to a QEMU
28
* netdev backend. So always instantiate it even if there is no
29
--
30
2.34.1
diff view generated by jsdifflib
1
Delete a couple of #defines which are never used.
1
Currently QEMU will warn if there is a NIC on the board that
2
is not connected to a backend. By default the '-nic user' will
3
get used for all NICs, but if you manually connect a specific
4
NIC to a specific backend, then the other NICs on the board
5
have no backend and will be warned about:
6
7
qemu-system-arm: warning: nic npcm7xx-emc.1 has no peer
8
qemu-system-arm: warning: nic npcm-gmac.0 has no peer
9
qemu-system-arm: warning: nic npcm-gmac.1 has no peer
10
11
So suppress those warnings by manually connecting every NIC
12
on the board to some backend.
2
13
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
5
Message-id: 20220404154658.565020-12-peter.maydell@linaro.org
16
Reviewed-by: Thomas Huth <thuth@redhat.com>
17
Message-id: 20240206171231.396392-3-peter.maydell@linaro.org
6
---
18
---
7
include/hw/arm/exynos4210.h | 4 ----
19
tests/qtest/npcm7xx_emc-test.c | 5 ++++-
8
1 file changed, 4 deletions(-)
20
1 file changed, 4 insertions(+), 1 deletion(-)
9
21
10
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
22
diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c
11
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
12
--- a/include/hw/arm/exynos4210.h
24
--- a/tests/qtest/npcm7xx_emc-test.c
13
+++ b/include/hw/arm/exynos4210.h
25
+++ b/tests/qtest/npcm7xx_emc-test.c
14
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@ static int *packet_test_init(int module_num, GString *cmd_line)
15
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
27
* KISS and use -nic. The driver accepts 'emc0' and 'emc1' as aliases
16
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
28
* in the 'model' field to specify the device to match.
17
29
*/
18
-/* IRQs number for external and internal GIC */
30
- g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d ",
19
-#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
31
+ g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d "
20
-#define EXYNOS4210_INT_GIC_NIRQ 64
32
+ "-nic user,model=npcm7xx-emc "
21
-
33
+ "-nic user,model=npcm-gmac "
22
#define EXYNOS4210_I2C_NUMBER 9
34
+ "-nic user,model=npcm-gmac",
23
35
test_sockets[1], module_num);
24
#define EXYNOS4210_NUM_DMA 3
36
37
g_test_queue_destroy(packet_test_clear, test_sockets);
25
--
38
--
26
2.25.1
39
2.34.1
diff view generated by jsdifflib
1
The exynos4210 code currently has two very similar arrays of IRQs:
1
It doesn't make sense to read the value of MDCR_EL2 on a non-A-profile
2
CPU, and in fact if you try to do it we will assert:
2
3
3
* board_irqs is a field of the Exynos4210Irq struct which is filled
4
#6 0x00007ffff4b95e96 in __GI___assert_fail
4
in by exynos4210_init_board_irqs() with the appropriate qemu_irqs
5
(assertion=0x5555565a8c70 "!arm_feature(env, ARM_FEATURE_M)", file=0x5555565a6e5c "../../target/arm/helper.c", line=12600, function=0x5555565a9560 <__PRETTY_FUNCTION__.0> "arm_security_space_below_el3") at ./assert/assert.c:101
5
for each IRQ the board/SoC can assert
6
#7 0x0000555555ebf412 in arm_security_space_below_el3 (env=0x555557bc8190) at ../../target/arm/helper.c:12600
6
* irq_table is a set of qemu_irqs pointed to from the
7
#8 0x0000555555ea6f89 in arm_is_el2_enabled (env=0x555557bc8190) at ../../target/arm/cpu.h:2595
7
Exynos4210State struct. It's allocated in exynos4210_init_irq,
8
#9 0x0000555555ea942f in arm_mdcr_el2_eff (env=0x555557bc8190) at ../../target/arm/internals.h:1512
8
and the only behaviour these irqs have is that they pass on the
9
level to the equivalent board_irqs[] irq
10
9
11
The extra indirection through irq_table is unnecessary, so coalesce
10
We might call pmu_counter_enabled() on an M-profile CPU (for example
12
these into a single irq_table[] array as a direct field in
11
from the migration pre/post hooks in machine.c); this should always
13
Exynos4210State which exynos4210_init_board_irqs() fills in.
12
return false because these CPUs don't set ARM_FEATURE_PMU.
14
13
14
Avoid the assertion by not calling arm_mdcr_el2_eff() before we
15
have done the early return for "PMU not present".
16
17
This fixes an assertion failure if you try to do a loadvm or
18
savevm for an M-profile board.
19
20
Cc: qemu-stable@nongnu.org
21
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2155
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20220404154658.565020-6-peter.maydell@linaro.org
25
Message-id: 20240208153346.970021-1-peter.maydell@linaro.org
18
---
26
---
19
include/hw/arm/exynos4210.h | 8 ++------
27
target/arm/helper.c | 12 ++++++++++--
20
hw/arm/exynos4210.c | 6 +-----
28
1 file changed, 10 insertions(+), 2 deletions(-)
21
hw/intc/exynos4210_gic.c | 32 ++++++++------------------------
22
3 files changed, 11 insertions(+), 35 deletions(-)
23
29
24
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/arm/exynos4210.h
32
--- a/target/arm/helper.c
27
+++ b/include/hw/arm/exynos4210.h
33
+++ b/target/arm/helper.c
28
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210Irq {
34
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
29
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
35
bool enabled, prohibited = false, filtered;
30
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
36
bool secure = arm_is_secure(env);
31
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
37
int el = arm_current_el(env);
32
- qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
38
- uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
33
} Exynos4210Irq;
39
- uint8_t hpmn = mdcr_el2 & MDCR_HPMN;
34
40
+ uint64_t mdcr_el2;
35
struct Exynos4210State {
41
+ uint8_t hpmn;
36
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
42
37
/*< public >*/
43
+ /*
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
44
+ * We might be called for M-profile cores where MDCR_EL2 doesn't
39
Exynos4210Irq irqs;
45
+ * exist and arm_mdcr_el2_eff() will assert, so this early-exit check
40
- qemu_irq *irq_table;
46
+ * must be before we read that value.
41
+ qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
47
+ */
42
48
if (!arm_feature(env, ARM_FEATURE_PMU)) {
43
MemoryRegion chipid_mem;
49
return false;
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
61
--- a/hw/arm/exynos4210.c
62
+++ b/hw/arm/exynos4210.c
63
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
64
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
65
}
50
}
66
51
67
- /*** IRQs ***/
52
+ mdcr_el2 = arm_mdcr_el2_eff(env);
68
-
53
+ hpmn = mdcr_el2 & MDCR_HPMN;
69
- s->irq_table = exynos4210_init_irq(&s->irqs);
54
+
70
-
55
if (!arm_feature(env, ARM_FEATURE_EL2) ||
71
/* IRQ Gate */
56
(counter < hpmn || counter == 31)) {
72
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
57
e = env->cp15.c9_pmcr & PMCRE;
73
DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
74
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
75
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
76
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
85
--- a/hw/intc/exynos4210_gic.c
86
+++ b/hw/intc/exynos4210_gic.c
87
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
88
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
89
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
90
91
-static void exynos4210_irq_handler(void *opaque, int irq, int level)
92
-{
93
- Exynos4210Irq *s = (Exynos4210Irq *)opaque;
94
-
95
- /* Bypass */
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
}
134
}
135
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
136
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
137
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
138
139
if (irq_id) {
140
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
141
- s->ext_gic_irq[irq_id-32]);
142
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
143
+ is->ext_gic_irq[irq_id - 32]);
144
}
145
}
146
}
147
--
58
--
148
2.25.1
59
2.34.1
60
61
diff view generated by jsdifflib
1
From: Zongyuan Li <zongyuan.li@smartx.com>
1
From: Nabih Estefan <nabihestefan@google.com>
2
2
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
3
Fix the nocm_gmac-test.c file to run on a nuvoton 7xx machine instead
4
of 8xx. Also fix comments referencing this and values expecting 8xx.
5
6
Change-Id: Iabd0fba14910c3f1e883c4a9521350f3db9ffab8
7
Signed-Off-By: Nabih Estefan <nabihestefan@google.com>
8
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
9
Message-id: 20240208194759.2858582-2-nabihestefan@google.com
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-5-zongyuan.li@smartx.com
11
[PMM: commit message tweaks]
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/811
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
tests/qtest/npcm_gmac-test.c | 84 +-----------------------------------
10
hw/core/irq.c | 15 ---------------
15
tests/qtest/meson.build | 3 +-
11
2 files changed, 20 deletions(-)
16
2 files changed, 4 insertions(+), 83 deletions(-)
12
17
13
diff --git a/include/hw/irq.h b/include/hw/irq.h
18
diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/irq.h
20
--- a/tests/qtest/npcm_gmac-test.c
16
+++ b/include/hw/irq.h
21
+++ b/tests/qtest/npcm_gmac-test.c
17
@@ -XXX,XX +XXX,XX @@ void qemu_free_irq(qemu_irq irq);
22
@@ -XXX,XX +XXX,XX @@ typedef struct TestData {
18
/* Returns a new IRQ with opposite polarity. */
23
const GMACModule *module;
19
qemu_irq qemu_irq_invert(qemu_irq irq);
24
} TestData;
20
25
21
-/* Returns a new IRQ which feeds into both the passed IRQs.
26
-/* Values extracted from hw/arm/npcm8xx.c */
22
- * It's probably better to use the TYPE_SPLIT_IRQ device instead.
27
+/* Values extracted from hw/arm/npcm7xx.c */
23
- */
28
static const GMACModule gmac_module_list[] = {
24
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
29
{
25
-
30
.irq = 14,
26
/* For internal use in qtest. Similar to qemu_irq_split, but operating
31
@@ -XXX,XX +XXX,XX @@ static const GMACModule gmac_module_list[] = {
27
on an existing vector of qemu_irq. */
32
.irq = 15,
28
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
33
.base_addr = 0xf0804000
29
diff --git a/hw/core/irq.c b/hw/core/irq.c
34
},
30
index XXXXXXX..XXXXXXX 100644
35
- {
31
--- a/hw/core/irq.c
36
- .irq = 16,
32
+++ b/hw/core/irq.c
37
- .base_addr = 0xf0806000
33
@@ -XXX,XX +XXX,XX @@ qemu_irq qemu_irq_invert(qemu_irq irq)
38
- },
34
return qemu_allocate_irq(qemu_notirq, irq, 0);
39
- {
40
- .irq = 17,
41
- .base_addr = 0xf0808000
42
- }
43
};
44
45
/* Returns the index of the GMAC module. */
46
@@ -XXX,XX +XXX,XX @@ static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
47
return qtest_readl(qts, mod->base_addr + regno);
35
}
48
}
36
49
37
-static void qemu_splitirq(void *opaque, int line, int level)
50
-static uint16_t pcs_read(QTestState *qts, const GMACModule *mod,
51
- NPCMRegister regno)
38
-{
52
-{
39
- struct IRQState **irq = opaque;
53
- uint32_t write_value = (regno & 0x3ffe00) >> 9;
40
- irq[0]->handler(irq[0]->opaque, irq[0]->n, level);
54
- qtest_writel(qts, PCS_BASE_ADDRESS + NPCM_PCS_IND_AC_BA, write_value);
41
- irq[1]->handler(irq[1]->opaque, irq[1]->n, level);
55
- uint32_t read_offset = regno & 0x1ff;
56
- return qtest_readl(qts, PCS_BASE_ADDRESS + read_offset);
42
-}
57
-}
43
-
58
-
44
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2)
59
/* Check that GMAC registers are reset to default value */
45
-{
60
static void test_init(gconstpointer test_data)
46
- qemu_irq *s = g_new0(qemu_irq, 2);
61
{
47
- s[0] = irq1;
62
const TestData *td = test_data;
48
- s[1] = irq2;
63
const GMACModule *mod = td->module;
49
- return qemu_allocate_irq(qemu_splitirq, s, 0);
64
- QTestState *qts = qtest_init("-machine npcm845-evb");
50
-}
65
+ QTestState *qts = qtest_init("-machine npcm750-evb");
66
67
#define CHECK_REG32(regno, value) \
68
do { \
69
g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \
70
} while (0)
71
72
-#define CHECK_REG_PCS(regno, value) \
73
- do { \
74
- g_assert_cmphex(pcs_read(qts, mod, (regno)), ==, (value)); \
75
- } while (0)
51
-
76
-
52
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
77
CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100);
53
{
78
CHECK_REG32(NPCM_DMA_XMT_POLL_DEMAND, 0);
54
int i;
79
CHECK_REG32(NPCM_DMA_RCV_POLL_DEMAND, 0);
80
@@ -XXX,XX +XXX,XX @@ static void test_init(gconstpointer test_data)
81
CHECK_REG32(NPCM_GMAC_PTP_TAR, 0);
82
CHECK_REG32(NPCM_GMAC_PTP_TTSR, 0);
83
84
- /* TODO Add registers PCS */
85
- if (mod->base_addr == 0xf0802000) {
86
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID1, 0x699e);
87
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID2, 0);
88
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_STS, 0x8000);
89
-
90
- CHECK_REG_PCS(NPCM_PCS_SR_MII_CTRL, 0x1140);
91
- CHECK_REG_PCS(NPCM_PCS_SR_MII_STS, 0x0109);
92
- CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID1, 0x699e);
93
- CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID2, 0x0ced0);
94
- CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_ADV, 0x0020);
95
- CHECK_REG_PCS(NPCM_PCS_SR_MII_LP_BABL, 0);
96
- CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_EXPN, 0);
97
- CHECK_REG_PCS(NPCM_PCS_SR_MII_EXT_STS, 0xc000);
98
-
99
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_ABL, 0x0003);
100
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR, 0x0038);
101
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_UPR, 0);
102
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR, 0x0038);
103
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_UPR, 0);
104
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR, 0x0058);
105
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_UPR, 0);
106
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_LWR, 0x0048);
107
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_UPR, 0);
108
-
109
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MMD_DIG_CTRL1, 0x2400);
110
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_CTRL, 0);
111
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_INTR_STS, 0x000a);
112
- CHECK_REG_PCS(NPCM_PCS_VR_MII_TC, 0);
113
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DBG_CTRL, 0);
114
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL0, 0x899c);
115
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_TXTIMER, 0);
116
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_RXTIMER, 0);
117
- CHECK_REG_PCS(NPCM_PCS_VR_MII_LINK_TIMER_CTRL, 0);
118
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL1, 0);
119
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_STS, 0x0010);
120
- CHECK_REG_PCS(NPCM_PCS_VR_MII_ICG_ERRCNT1, 0);
121
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MISC_STS, 0);
122
- CHECK_REG_PCS(NPCM_PCS_VR_MII_RX_LSTS, 0);
123
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_BSTCTRL0, 0x00a);
124
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_LVLCTRL0, 0x007f);
125
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL0, 0x0001);
126
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL1, 0);
127
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_STS, 0);
128
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL0, 0x0100);
129
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL1, 0x1100);
130
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_LOS_CTRL0, 0x000e);
131
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL0, 0x0100);
132
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL1, 0x0032);
133
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_STS, 0x0001);
134
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL2, 0);
135
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_LVL_CTRL, 0x0019);
136
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL0, 0);
137
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL1, 0);
138
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_CTRL2, 0);
139
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_ERRCNT_SEL, 0);
140
- }
141
-
142
qtest_quit(qts);
143
}
144
145
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
146
index XXXXXXX..XXXXXXX 100644
147
--- a/tests/qtest/meson.build
148
+++ b/tests/qtest/meson.build
149
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
150
'npcm7xx_sdhci-test',
151
'npcm7xx_smbus-test',
152
'npcm7xx_timer-test',
153
- 'npcm7xx_watchdog_timer-test'] + \
154
+ 'npcm7xx_watchdog_timer-test',
155
+ 'npcm_gmac-test'] + \
156
(slirp.found() ? ['npcm7xx_emc-test'] : [])
157
qtests_aspeed = \
158
['aspeed_hace-test',
55
--
159
--
56
2.25.1
160
2.34.1
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Luc Michel <luc.michel@amd.com>
2
2
3
This patch uses the defined fields to describe PWRON STRAPs for
3
An access fault is raised when the Access Flag is not set in the
4
better readability.
4
looked-up PTE and the AFFD field is not set in the corresponding context
5
descriptor. This was already implemented for stage 2. Implement it for
6
stage 1 as well.
5
7
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
8
Signed-off-by: Luc Michel <luc.michel@amd.com>
7
Reviewed-by: Patrick Venture <venture@google.com>
9
Reviewed-by: Mostafa Saleh <smostafa@google.com>
8
Message-id: 20220411165842.3912945-3-wuhaotsh@google.com
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Tested-by: Mostafa Saleh <smostafa@google.com>
12
Message-id: 20240213082211.3330400-1-luc.michel@amd.com
13
[PMM: tweaked comment text]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
hw/arm/npcm7xx_boards.c | 24 +++++++++++++++++++-----
16
hw/arm/smmuv3-internal.h | 1 +
13
1 file changed, 19 insertions(+), 5 deletions(-)
17
include/hw/arm/smmu-common.h | 1 +
18
hw/arm/smmu-common.c | 11 +++++++++++
19
hw/arm/smmuv3.c | 1 +
20
4 files changed, 14 insertions(+)
14
21
15
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
22
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
16
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/npcm7xx_boards.c
24
--- a/hw/arm/smmuv3-internal.h
18
+++ b/hw/arm/npcm7xx_boards.c
25
+++ b/hw/arm/smmuv3-internal.h
19
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@ static inline int pa_range(STE *ste)
20
#include "sysemu/sysemu.h"
27
#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
21
#include "sysemu/block-backend.h"
28
#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
22
29
#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
23
-#define NPCM750_EVB_POWER_ON_STRAPS 0x00001ff7
30
+#define CD_AFFD(x) extract32((x)->word[1], 3 , 1)
24
-#define QUANTA_GSJ_POWER_ON_STRAPS 0x00001fff
31
#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
25
-#define QUANTA_GBS_POWER_ON_STRAPS 0x000017ff
32
#define CD_HD(x) extract32((x)->word[1], 10 , 1)
26
-#define KUDO_BMC_POWER_ON_STRAPS 0x00001fff
33
#define CD_HA(x) extract32((x)->word[1], 11 , 1)
27
-#define MORI_BMC_POWER_ON_STRAPS 0x00001fff
34
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
28
+#define NPCM7XX_POWER_ON_STRAPS_DEFAULT ( \
35
index XXXXXXX..XXXXXXX 100644
29
+ NPCM7XX_PWRON_STRAP_SPI0F18 | \
36
--- a/include/hw/arm/smmu-common.h
30
+ NPCM7XX_PWRON_STRAP_SFAB | \
37
+++ b/include/hw/arm/smmu-common.h
31
+ NPCM7XX_PWRON_STRAP_BSPA | \
38
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
32
+ NPCM7XX_PWRON_STRAP_FUP(FUP_NORM_UART2) | \
39
bool disabled; /* smmu is disabled */
33
+ NPCM7XX_PWRON_STRAP_SECEN | \
40
bool bypassed; /* translation is bypassed */
34
+ NPCM7XX_PWRON_STRAP_HIZ | \
41
bool aborted; /* translation is aborted */
35
+ NPCM7XX_PWRON_STRAP_ECC | \
42
+ bool affd; /* AF fault disable */
36
+ NPCM7XX_PWRON_STRAP_RESERVE1 | \
43
uint32_t iotlb_hits; /* counts IOTLB hits */
37
+ NPCM7XX_PWRON_STRAP_J2EN | \
44
uint32_t iotlb_misses; /* counts IOTLB misses*/
38
+ NPCM7XX_PWRON_STRAP_CKFRQ(CKFRQ_DEFAULT))
45
/* Used by stage-1 only. */
46
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/smmu-common.c
49
+++ b/hw/arm/smmu-common.c
50
@@ -XXX,XX +XXX,XX @@ static int smmu_ptw_64_s1(SMMUTransCfg *cfg,
51
pte_addr, pte, iova, gpa,
52
block_size >> 20);
53
}
39
+
54
+
40
+#define NPCM750_EVB_POWER_ON_STRAPS ( \
55
+ /*
41
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_J2EN)
56
+ * QEMU does not currently implement HTTU, so if AFFD and PTE.AF
42
+#define QUANTA_GSJ_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
57
+ * are 0 we take an Access flag fault. (5.4. Context Descriptor)
43
+#define QUANTA_GBS_POWER_ON_STRAPS ( \
58
+ * An Access flag fault takes priority over a Permission fault.
44
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_SFAB)
59
+ */
45
+#define KUDO_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
60
+ if (!PTE_AF(pte) && !cfg->affd) {
46
+#define MORI_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
61
+ info->type = SMMU_PTW_ERR_ACCESS;
47
62
+ goto error;
48
static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
63
+ }
64
+
65
ap = PTE_AP(pte);
66
if (is_permission_fault(ap, perm)) {
67
info->type = SMMU_PTW_ERR_PERMISSION;
68
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/arm/smmuv3.c
71
+++ b/hw/arm/smmuv3.c
72
@@ -XXX,XX +XXX,XX @@ static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
73
cfg->oas = MIN(oas2bits(SMMU_IDR5_OAS), cfg->oas);
74
cfg->tbi = CD_TBI(cd);
75
cfg->asid = CD_ASID(cd);
76
+ cfg->affd = CD_AFFD(cd);
77
78
trace_smmuv3_decode_cd(cfg->oas);
49
79
50
--
80
--
51
2.25.1
81
2.34.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Add the Cortex-R5Fs of the Versal RPU (Real-time Processing Unit)
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
subsystem.
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
5
Message-id: 20240213155214.13619-2-philmd@linaro.org
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Message-id: 20220406174303.2022038-3-edgar.iglesias@xilinx.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
7
---
11
include/hw/arm/xlnx-versal.h | 10 ++++++++++
8
hw/arm/stellaris.c | 6 ++++--
12
hw/arm/xlnx-versal-virt.c | 6 +++---
9
1 file changed, 4 insertions(+), 2 deletions(-)
13
hw/arm/xlnx-versal.c | 36 ++++++++++++++++++++++++++++++++++++
14
3 files changed, 49 insertions(+), 3 deletions(-)
15
10
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
17
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
13
--- a/hw/arm/stellaris.c
19
+++ b/include/hw/arm/xlnx-versal.h
14
+++ b/hw/arm/stellaris.c
20
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_trigger(void *opaque, int irq, int level)
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
}
16
}
75
}
17
}
76
18
77
+static void versal_create_rpu_cpus(Versal *s)
19
-static void stellaris_adc_reset(StellarisADCState *s)
78
+{
20
+static void stellaris_adc_reset_hold(Object *obj)
79
+ int i;
80
+
81
+ object_initialize_child(OBJECT(s), "rpu-cluster", &s->lpd.rpu.cluster,
82
+ TYPE_CPU_CLUSTER);
83
+ qdev_prop_set_uint32(DEVICE(&s->lpd.rpu.cluster), "cluster-id", 1);
84
+
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
86
+ Object *obj;
87
+
88
+ object_initialize_child(OBJECT(&s->lpd.rpu.cluster),
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
+ }
102
+
103
+ qdev_realize(DEVICE(&s->lpd.rpu.cluster), NULL, &error_fatal);
104
+}
105
+
106
static void versal_create_uarts(Versal *s, qemu_irq *pic)
107
{
21
{
108
int i;
22
+ StellarisADCState *s = STELLARIS_ADC(obj);
109
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
23
int n;
110
24
111
versal_create_apu_cpus(s);
25
for (n = 0; n < 4; n++) {
112
versal_create_apu_gic(s, pic);
26
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_init(Object *obj)
113
+ versal_create_rpu_cpus(s);
27
memory_region_init_io(&s->iomem, obj, &stellaris_adc_ops, s,
114
versal_create_uarts(s, pic);
28
"adc", 0x1000);
115
versal_create_usbs(s, pic);
29
sysbus_init_mmio(sbd, &s->iomem);
116
versal_create_gems(s, pic);
30
- stellaris_adc_reset(s);
117
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
31
qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
118
119
memory_region_add_subregion_overlap(&s->mr_ps, MM_OCM, &s->lpd.mr_ocm, 0);
120
memory_region_add_subregion_overlap(&s->fpd.apu.mr, 0, &s->mr_ps, 0);
121
+ memory_region_add_subregion_overlap(&s->lpd.rpu.mr, 0,
122
+ &s->lpd.rpu.mr_ps_alias, 0);
123
}
32
}
124
33
125
static void versal_init(Object *obj)
34
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stellaris_i2c_info = {
126
@@ -XXX,XX +XXX,XX @@ static void versal_init(Object *obj)
35
static void stellaris_adc_class_init(ObjectClass *klass, void *data)
127
Versal *s = XLNX_VERSAL(obj);
36
{
128
37
DeviceClass *dc = DEVICE_CLASS(klass);
129
memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
38
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
130
+ memory_region_init(&s->lpd.rpu.mr, obj, "mr-rpu", UINT64_MAX);
39
131
memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX);
40
+ rc->phases.hold = stellaris_adc_reset_hold;
132
+ memory_region_init_alias(&s->lpd.rpu.mr_ps_alias, OBJECT(s),
41
dc->vmsd = &vmstate_stellaris_adc;
133
+ "mr-rpu-ps-alias", &s->mr_ps, 0, UINT64_MAX);
134
}
42
}
135
43
136
static Property versal_properties[] = {
137
--
44
--
138
2.25.1
45
2.34.1
46
47
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Connect the 4 TTC timers on the ZynqMP.
3
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
4
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
5
Message-id: 20240213155214.13619-3-philmd@linaro.org
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Message-id: 20220331222017.2914409-3-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
include/hw/arm/xlnx-zynqmp.h | 4 ++++
9
hw/arm/stellaris.c | 26 ++++++++++++++++++++++----
13
hw/arm/xlnx-zynqmp.c | 22 ++++++++++++++++++++++
10
1 file changed, 22 insertions(+), 4 deletions(-)
14
2 files changed, 26 insertions(+)
15
11
16
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
12
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-zynqmp.h
14
--- a/hw/arm/stellaris.c
19
+++ b/include/hw/arm/xlnx-zynqmp.h
15
+++ b/hw/arm/stellaris.c
20
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static void stellaris_sys_instance_init(Object *obj)
21
#include "hw/or-irq.h"
17
s->sysclk = qdev_init_clock_out(DEVICE(s), "SYSCLK");
22
#include "hw/misc/xlnx-zynqmp-apu-ctrl.h"
18
}
23
#include "hw/misc/xlnx-zynqmp-crf.h"
19
24
+#include "hw/timer/cadence_ttc.h"
20
-/* I2C controller. */
25
21
+/*
26
#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
22
+ * I2C controller.
27
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
23
+ * ??? For now we only implement the master interface.
28
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
24
+ */
29
#define XLNX_ZYNQMP_MAX_RAM_SIZE (XLNX_ZYNQMP_MAX_LOW_RAM_SIZE + \
25
30
XLNX_ZYNQMP_MAX_HIGH_RAM_SIZE)
26
#define TYPE_STELLARIS_I2C "stellaris-i2c"
31
27
OBJECT_DECLARE_SIMPLE_TYPE(stellaris_i2c_state, STELLARIS_I2C)
32
+#define XLNX_ZYNQMP_NUM_TTC 4
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_write(void *opaque, hwaddr offset,
29
stellaris_i2c_update(s);
30
}
31
32
-static void stellaris_i2c_reset(stellaris_i2c_state *s)
33
+static void stellaris_i2c_reset_enter(Object *obj, ResetType type)
34
{
35
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
33
+
36
+
34
/*
37
if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
35
* Unimplemented mmio regions needed to boot some images.
38
i2c_end_transfer(s->bus);
36
*/
37
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
38
qemu_or_irq qspi_irq_orgate;
39
XlnxZynqMPAPUCtrl apu_ctrl;
40
XlnxZynqMPCRF crf;
41
+ CadenceTTCState ttc[XLNX_ZYNQMP_NUM_TTC];
42
43
char *boot_cpu;
44
ARMCPU *boot_cpu_ptr;
45
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/arm/xlnx-zynqmp.c
48
+++ b/hw/arm/xlnx-zynqmp.c
49
@@ -XXX,XX +XXX,XX @@
50
#define APU_ADDR 0xfd5c0000
51
#define APU_IRQ 153
52
53
+#define TTC0_ADDR 0xFF110000
54
+#define TTC0_IRQ 36
55
+
56
#define IPI_ADDR 0xFF300000
57
#define IPI_IRQ 64
58
59
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_crf(XlnxZynqMPState *s, qemu_irq *gic)
60
sysbus_connect_irq(sbd, 0, gic[CRF_IRQ]);
61
}
62
63
+static void xlnx_zynqmp_create_ttc(XlnxZynqMPState *s, qemu_irq *gic)
64
+{
65
+ SysBusDevice *sbd;
66
+ int i, irq;
67
+
68
+ for (i = 0; i < XLNX_ZYNQMP_NUM_TTC; i++) {
69
+ object_initialize_child(OBJECT(s), "ttc[*]", &s->ttc[i],
70
+ TYPE_CADENCE_TTC);
71
+ sbd = SYS_BUS_DEVICE(&s->ttc[i]);
72
+
73
+ sysbus_realize(sbd, &error_fatal);
74
+ sysbus_mmio_map(sbd, 0, TTC0_ADDR + i * 0x10000);
75
+ for (irq = 0; irq < 3; irq++) {
76
+ sysbus_connect_irq(sbd, irq, gic[TTC0_IRQ + i * 3 + irq]);
77
+ }
78
+ }
79
+}
39
+}
80
+
40
+
81
static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
41
+static void stellaris_i2c_reset_hold(Object *obj)
42
+{
43
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
44
45
s->msa = 0;
46
s->mcs = 0;
47
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_reset(stellaris_i2c_state *s)
48
s->mimr = 0;
49
s->mris = 0;
50
s->mcr = 0;
51
+}
52
+
53
+static void stellaris_i2c_reset_exit(Object *obj)
54
+{
55
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
56
+
57
stellaris_i2c_update(s);
58
}
59
60
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_init(Object *obj)
61
memory_region_init_io(&s->iomem, obj, &stellaris_i2c_ops, s,
62
"i2c", 0x1000);
63
sysbus_init_mmio(sbd, &s->iomem);
64
- /* ??? For now we only implement the master interface. */
65
- stellaris_i2c_reset(s);
66
}
67
68
/* Analogue to Digital Converter. This is only partially implemented,
69
@@ -XXX,XX +XXX,XX @@ type_init(stellaris_machine_init)
70
static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
82
{
71
{
83
static const struct UnimpInfo {
72
DeviceClass *dc = DEVICE_CLASS(klass);
84
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
73
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
85
xlnx_zynqmp_create_efuse(s, gic_spi);
74
86
xlnx_zynqmp_create_apu_ctrl(s, gic_spi);
75
+ rc->phases.enter = stellaris_i2c_reset_enter;
87
xlnx_zynqmp_create_crf(s, gic_spi);
76
+ rc->phases.hold = stellaris_i2c_reset_hold;
88
+ xlnx_zynqmp_create_ttc(s, gic_spi);
77
+ rc->phases.exit = stellaris_i2c_reset_exit;
89
xlnx_zynqmp_create_unimp_mmio(s);
78
dc->vmsd = &vmstate_stellaris_i2c;
90
79
}
91
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
80
92
--
81
--
93
2.25.1
82
2.34.1
83
84
diff view generated by jsdifflib
1
From: Zongyuan Li <zongyuan.li@smartx.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
3
QDev objects created with qdev_new() need to manually add
4
their parent relationship with object_property_add_child().
5
6
This commit plug the devices which aren't part of the SoC;
7
they will be plugged into a SoC container in the next one.
8
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-3-zongyuan.li@smartx.com
11
Message-id: 20240213155214.13619-4-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
13
---
8
hw/arm/stellaris.c | 15 +++++++++++++--
14
hw/arm/stellaris.c | 4 ++++
9
1 file changed, 13 insertions(+), 2 deletions(-)
15
1 file changed, 4 insertions(+)
10
16
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
17
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/stellaris.c
19
--- a/hw/arm/stellaris.c
14
+++ b/hw/arm/stellaris.c
20
+++ b/hw/arm/stellaris.c
15
@@ -XXX,XX +XXX,XX @@
16
17
#include "qemu/osdep.h"
18
#include "qapi/error.h"
19
+#include "hw/core/split-irq.h"
20
#include "hw/sysbus.h"
21
#include "hw/sd/sd.h"
22
#include "hw/ssi/ssi.h"
23
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
24
DeviceState *ssddev;
25
DriveInfo *dinfo;
26
DeviceState *carddev;
27
+ DeviceState *gpio_d_splitter;
28
BlockBackend *blk;
29
30
/*
31
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
21
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
32
&error_fatal);
22
&error_fatal);
33
23
34
ssddev = ssi_create_peripheral(bus, "ssd0323");
24
ssddev = qdev_new("ssd0323");
35
- gpio_out[GPIO_D][0] = qemu_irq_split(
25
+ object_property_add_child(OBJECT(ms), "oled", OBJECT(ssddev));
36
- qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0),
26
qdev_prop_set_uint8(ssddev, "cs", 1);
37
+
27
qdev_realize_and_unref(ssddev, bus, &error_fatal);
38
+ gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
28
39
+ qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
29
gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
40
+ qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
30
+ object_property_add_child(OBJECT(ms), "splitter",
41
+ qdev_connect_gpio_out(
31
+ OBJECT(gpio_d_splitter));
42
+ gpio_d_splitter, 0,
32
qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
43
+ qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0));
33
qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
44
+ qdev_connect_gpio_out(
34
qdev_connect_gpio_out(
45
+ gpio_d_splitter, 1,
35
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
46
qdev_get_gpio_in_named(ssddev, SSI_GPIO_CS, 0));
36
DeviceState *gpad;
47
+ gpio_out[GPIO_D][0] = qdev_get_gpio_in(gpio_d_splitter, 0);
37
48
+
38
gpad = qdev_new(TYPE_STELLARIS_GAMEPAD);
49
gpio_out[GPIO_C][7] = qdev_get_gpio_in(ssddev, 0);
39
+ object_property_add_child(OBJECT(ms), "gamepad", OBJECT(gpad));
50
40
for (i = 0; i < ARRAY_SIZE(gpad_keycode); i++) {
51
/* Make sure the select pin is high. */
41
qlist_append_int(gpad_keycode_list, gpad_keycode[i]);
42
}
52
--
43
--
53
2.25.1
44
2.34.1
45
46
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Break out header file to allow embedding of the the TTC.
3
QDev objects created with qdev_new() need to manually add
4
their parent relationship with object_property_add_child().
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Since we don't model the SoC, just use a QOM container.
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20220331222017.2914409-2-edgar.iglesias@gmail.com
10
Message-id: 20240213155214.13619-5-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
include/hw/timer/cadence_ttc.h | 54 ++++++++++++++++++++++++++++++++++
13
hw/arm/stellaris.c | 11 ++++++++++-
13
hw/timer/cadence_ttc.c | 32 ++------------------
14
1 file changed, 10 insertions(+), 1 deletion(-)
14
2 files changed, 56 insertions(+), 30 deletions(-)
15
create mode 100644 include/hw/timer/cadence_ttc.h
16
15
17
diff --git a/include/hw/timer/cadence_ttc.h b/include/hw/timer/cadence_ttc.h
16
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
18
new file mode 100644
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX
18
--- a/hw/arm/stellaris.c
20
--- /dev/null
19
+++ b/hw/arm/stellaris.c
21
+++ b/include/hw/timer/cadence_ttc.h
20
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
22
@@ -XXX,XX +XXX,XX @@
21
* 400fe000 system control
23
+/*
22
*/
24
+ * Xilinx Zynq cadence TTC model
23
25
+ *
24
+ Object *soc_container;
26
+ * Copyright (c) 2011 Xilinx Inc.
25
DeviceState *gpio_dev[7], *nvic;
27
+ * Copyright (c) 2012 Peter A.G. Crosthwaite (peter.crosthwaite@petalogix.com)
26
qemu_irq gpio_in[7][8];
28
+ * Copyright (c) 2012 PetaLogix Pty Ltd.
27
qemu_irq gpio_out[7][8];
29
+ * Written By Haibing Ma
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
30
+ * M. Habib
29
flash_size = (((board->dc0 & 0xffff) + 1) << 1) * 1024;
31
+ *
30
sram_size = ((board->dc0 >> 18) + 1) * 1024;
32
+ * This program is free software; you can redistribute it and/or
31
33
+ * modify it under the terms of the GNU General Public License
32
+ soc_container = object_new("container");
34
+ * as published by the Free Software Foundation; either version
33
+ object_property_add_child(OBJECT(ms), "soc", soc_container);
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
+
34
+
43
+#include "hw/sysbus.h"
35
/* Flash programming is done via the SCU, so pretend it is ROM. */
44
+#include "qemu/timer.h"
36
memory_region_init_rom(flash, NULL, "stellaris.flash", flash_size,
45
+
37
&error_fatal);
46
+typedef struct {
38
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
47
+ QEMUTimer *timer;
39
* need its sysclk output.
48
+ int freq;
40
*/
49
+
41
ssys_dev = qdev_new(TYPE_STELLARIS_SYS);
50
+ uint32_t reg_clock;
42
+ object_property_add_child(soc_container, "sys", OBJECT(ssys_dev));
51
+ uint32_t reg_count;
43
52
+ uint32_t reg_value;
44
/*
53
+ uint16_t reg_interval;
45
* Most devices come preprogrammed with a MAC address in the user data.
54
+ uint16_t reg_match[3];
46
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
55
+ uint32_t reg_intr;
47
sysbus_realize_and_unref(SYS_BUS_DEVICE(ssys_dev), &error_fatal);
56
+ uint32_t reg_intr_en;
48
57
+ uint32_t reg_event_ctrl;
49
nvic = qdev_new(TYPE_ARMV7M);
58
+ uint32_t reg_event;
50
+ object_property_add_child(soc_container, "v7m", OBJECT(nvic));
59
+
51
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
60
+ uint64_t cpu_time;
52
qdev_prop_set_uint8(nvic, "num-prio-bits", NUM_PRIO_BITS);
61
+ unsigned int cpu_time_valid;
53
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
62
+
54
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
63
+ qemu_irq irq;
55
64
+} CadenceTimerState;
56
dev = qdev_new(TYPE_STELLARIS_GPTM);
65
+
57
sbd = SYS_BUS_DEVICE(dev);
66
+#define TYPE_CADENCE_TTC "cadence_ttc"
58
+ object_property_add_child(soc_container, "gptm[*]", OBJECT(dev));
67
+OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
59
qdev_connect_clock_in(dev, "clk",
68
+
60
qdev_get_clock_out(ssys_dev, "SYSCLK"));
69
+struct CadenceTTCState {
61
sysbus_realize_and_unref(sbd, &error_fatal);
70
+ SysBusDevice parent_obj;
62
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
71
+
63
72
+ MemoryRegion iomem;
64
if (board->dc1 & (1 << 3)) { /* watchdog present */
73
+ CadenceTimerState timer[3];
65
dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
74
+};
75
+
76
+#endif
77
diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/timer/cadence_ttc.c
80
+++ b/hw/timer/cadence_ttc.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "qemu/timer.h"
83
#include "qom/object.h"
84
85
+#include "hw/timer/cadence_ttc.h"
86
+
87
#ifdef CADENCE_TTC_ERR_DEBUG
88
#define DB_PRINT(...) do { \
89
fprintf(stderr, ": %s: ", __func__); \
90
@@ -XXX,XX +XXX,XX @@
91
#define CLOCK_CTRL_PS_EN 0x00000001
92
#define CLOCK_CTRL_PS_V 0x0000001e
93
94
-typedef struct {
95
- QEMUTimer *timer;
96
- int freq;
97
-
66
-
98
- uint32_t reg_clock;
67
+ object_property_add_child(soc_container, "wdg", OBJECT(dev));
99
- uint32_t reg_count;
68
qdev_connect_clock_in(dev, "WDOGCLK",
100
- uint32_t reg_value;
69
qdev_get_clock_out(ssys_dev, "SYSCLK"));
101
- uint16_t reg_interval;
70
102
- uint16_t reg_match[3];
71
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
103
- uint32_t reg_intr;
72
SysBusDevice *sbd;
104
- uint32_t reg_intr_en;
73
105
- uint32_t reg_event_ctrl;
74
dev = qdev_new("pl011_luminary");
106
- uint32_t reg_event;
75
+ object_property_add_child(soc_container, "uart[*]", OBJECT(dev));
107
-
76
sbd = SYS_BUS_DEVICE(dev);
108
- uint64_t cpu_time;
77
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
109
- unsigned int cpu_time_valid;
78
sysbus_realize_and_unref(sbd, &error_fatal);
110
-
79
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
111
- qemu_irq irq;
80
DeviceState *enet;
112
-} CadenceTimerState;
81
113
-
82
enet = qdev_new("stellaris_enet");
114
-#define TYPE_CADENCE_TTC "cadence_ttc"
83
+ object_property_add_child(soc_container, "enet", OBJECT(enet));
115
-OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
84
if (nd) {
116
-
85
qdev_set_nic_properties(enet, nd);
117
-struct CadenceTTCState {
86
} else {
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
--
87
--
128
2.25.1
88
2.34.1
89
90
diff view generated by jsdifflib
1
Fix a missing set of spaces around '-' in the definition of
1
We support two different encodings for the AArch32 IMPDEF
2
combiner_grp_to_gic_id[]. We're about to move this code, so
2
CBAR register -- older cores like the Cortex A9, A7, A15
3
fix the style issue first to keep checkpatch happy with the
3
have this at 4, c15, c0, 0; newer cores like the
4
code-motion patch.
4
Cortex A35, A53, A57 and A72 have it at 1 c15 c0 0.
5
6
When we implemented this we picked which encoding to
7
use based on whether the CPU set ARM_FEATURE_AARCH64.
8
However this isn't right for three cases:
9
* the qemu-system-arm 'max' CPU, which is supposed to be
10
a variant on a Cortex-A57; it ought to use the same
11
encoding the A57 does and which the AArch64 'max'
12
exposes to AArch32 guest code
13
* the Cortex-R52, which is AArch32-only but has the CBAR
14
at the newer encoding (and where we incorrectly are
15
not yet setting ARM_FEATURE_CBAR_RO anyway)
16
* any possible future support for other v8 AArch32
17
only CPUs, or for supporting "boot the CPU into
18
AArch32 mode" on our existing cores like the A57 etc
19
20
Make the decision of the encoding be based on whether
21
the CPU implements the ARM_FEATURE_V8 flag instead.
22
23
This changes the behaviour only for the qemu-system-arm
24
'-cpu max'. We don't expect anybody to be relying on the
25
old behaviour because:
26
* it's not what the real hardware Cortex-A57 does
27
(and that's what our ID register claims we are)
28
* we don't implement the memory-mapped GICv3 support
29
which is the only thing that exists at the peripheral
30
base address pointed to by the register
5
31
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220404154658.565020-7-peter.maydell@linaro.org
34
Message-id: 20240206132931.38376-2-peter.maydell@linaro.org
9
---
35
---
10
hw/intc/exynos4210_gic.c | 2 +-
36
target/arm/helper.c | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
37
1 file changed, 1 insertion(+), 1 deletion(-)
12
38
13
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/intc/exynos4210_gic.c
41
--- a/target/arm/helper.c
16
+++ b/hw/intc/exynos4210_gic.c
42
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ enum ExtInt {
43
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
18
*/
44
* AArch64 cores we might need to add a specific feature flag
19
45
* to indicate cores with "flavour 2" CBAR.
20
static const uint32_t
46
*/
21
-combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
47
- if (arm_feature(env, ARM_FEATURE_AARCH64)) {
22
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
48
+ if (arm_feature(env, ARM_FEATURE_V8)) {
23
/* int combiner groups 16-19 */
49
/* 32 bit view is [31:18] 0...0 [43:32]. */
24
{ }, { }, { }, { },
50
uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18)
25
/* int combiner group 20 */
51
| extract64(cpu->reset_cbar, 32, 12);
26
--
52
--
27
2.25.1
53
2.34.1
diff view generated by jsdifflib
1
The only time we use the ext_gic_irq[] array in the Exynos4210Irq
1
The Cortex-R52 implements the Configuration Base Address Register
2
struct is during realize of the SoC -- we initialize it with the
2
(CBAR), as a read-only register. Add ARM_FEATURE_CBAR_RO to this CPU
3
input IRQs of the external GIC device, and then connect those to
3
type, so that our implementation provides the register and the
4
outputs of other devices further on in realize (including in the
4
associated qdev property.
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
5
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-10-peter.maydell@linaro.org
8
Message-id: 20240206132931.38376-3-peter.maydell@linaro.org
12
---
9
---
13
include/hw/arm/exynos4210.h | 1 -
10
target/arm/tcg/cpu32.c | 1 +
14
hw/arm/exynos4210.c | 12 ++++++------
11
1 file changed, 1 insertion(+)
15
2 files changed, 6 insertions(+), 7 deletions(-)
16
12
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
15
--- a/target/arm/tcg/cpu32.c
20
+++ b/include/hw/arm/exynos4210.h
16
+++ b/target/arm/tcg/cpu32.c
21
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
22
typedef struct Exynos4210Irq {
18
set_feature(&cpu->env, ARM_FEATURE_PMSA);
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
19
set_feature(&cpu->env, ARM_FEATURE_NEON);
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
20
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
25
- qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
21
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
26
} Exynos4210Irq;
22
cpu->midr = 0x411fd133; /* r1p3 */
27
23
cpu->revidr = 0x00000000;
28
struct Exynos4210State {
24
cpu->reset_fpsid = 0x41034023;
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
--
25
--
81
2.25.1
26
2.34.1
diff view generated by jsdifflib
1
Switch the creation of the external GIC to the new-style "embedded in
1
Add the Cortex-R52 IMPDEF sysregs, by defining them here and
2
state struct" approach, so we can easily refer to the object
2
also by enabling the AUXCR feature which defines the ACTLR
3
elsewhere during realize.
3
and HACTLR registers. As is our usual practice, we make these
4
simple reads-as-zero stubs for now.
4
5
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220404154658.565020-9-peter.maydell@linaro.org
8
Message-id: 20240206132931.38376-4-peter.maydell@linaro.org
8
---
9
---
9
include/hw/arm/exynos4210.h | 2 ++
10
target/arm/tcg/cpu32.c | 108 +++++++++++++++++++++++++++++++++++++++++
10
include/hw/intc/exynos4210_gic.h | 43 ++++++++++++++++++++++++++++++++
11
1 file changed, 108 insertions(+)
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
12
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
15
--- a/target/arm/tcg/cpu32.c
20
+++ b/include/hw/arm/exynos4210.h
16
+++ b/target/arm/tcg/cpu32.c
21
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
22
#include "hw/or-irq.h"
18
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
23
#include "hw/sysbus.h"
19
}
24
#include "hw/cpu/a9mpcore.h"
20
25
+#include "hw/intc/exynos4210_gic.h"
21
+static const ARMCPRegInfo cortex_r52_cp_reginfo[] = {
26
#include "target/arm/cpu-qom.h"
22
+ { .name = "CPUACTLR", .cp = 15, .opc1 = 0, .crm = 15,
27
#include "qom/object.h"
23
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
28
24
+ { .name = "IMP_ATCMREGIONR",
29
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
25
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
30
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
26
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
31
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
27
+ { .name = "IMP_BTCMREGIONR",
32
A9MPPrivState a9mpcore;
28
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
33
+ Exynos4210GicState ext_gic;
29
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
34
};
30
+ { .name = "IMP_CTCMREGIONR",
35
31
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 2,
36
#define TYPE_EXYNOS4210_SOC "exynos4210"
32
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
37
diff --git a/include/hw/intc/exynos4210_gic.h b/include/hw/intc/exynos4210_gic.h
33
+ { .name = "IMP_CSCTLR",
38
new file mode 100644
34
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 0,
39
index XXXXXXX..XXXXXXX
35
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
40
--- /dev/null
36
+ { .name = "IMP_BPCTLR",
41
+++ b/include/hw/intc/exynos4210_gic.h
37
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 1,
42
@@ -XXX,XX +XXX,XX @@
38
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
43
+/*
39
+ { .name = "IMP_MEMPROTCLR",
44
+ * Samsung exynos4210 GIC implementation. Based on hw/arm_gic.c
40
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 2,
45
+ *
41
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
42
+ { .name = "IMP_SLAVEPCTLR",
47
+ * All rights reserved.
43
+ .cp = 15, .opc1 = 0, .crn = 11, .crm = 0, .opc2 = 0,
48
+ *
44
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
45
+ { .name = "IMP_PERIPHREGIONR",
50
+ *
46
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 0,
51
+ * This program is free software; you can redistribute it and/or modify it
47
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
52
+ * under the terms of the GNU General Public License as published by the
48
+ { .name = "IMP_FLASHIFREGIONR",
53
+ * Free Software Foundation; either version 2 of the License, or (at your
49
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 1,
54
+ * option) any later version.
50
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
55
+ *
51
+ { .name = "IMP_BUILDOPTR",
56
+ * This program is distributed in the hope that it will be useful,
52
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 0,
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
53
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
54
+ { .name = "IMP_PINOPTR",
59
+ * See the GNU General Public License for more details.
55
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 7,
60
+ *
56
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
61
+ * You should have received a copy of the GNU General Public License along
57
+ { .name = "IMP_QOSR",
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
58
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 1,
63
+ */
59
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
64
+#ifndef HW_INTC_EXYNOS4210_GIC_H
60
+ { .name = "IMP_BUSTIMEOUTR",
65
+#define HW_INTC_EXYNOS4210_GIC_H
61
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 2,
66
+
62
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
67
+#include "hw/sysbus.h"
63
+ { .name = "IMP_INTMONR",
68
+
64
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 4,
69
+#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
65
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
70
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
66
+ { .name = "IMP_ICERR0",
71
+
67
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 0,
72
+#define EXYNOS4210_GIC_NCPUS 2
68
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
73
+
69
+ { .name = "IMP_ICERR1",
74
+struct Exynos4210GicState {
70
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 1,
75
+ SysBusDevice parent_obj;
71
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
76
+
72
+ { .name = "IMP_DCERR0",
77
+ MemoryRegion cpu_container;
73
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 0,
78
+ MemoryRegion dist_container;
74
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
79
+ MemoryRegion cpu_alias[EXYNOS4210_GIC_NCPUS];
75
+ { .name = "IMP_DCERR1",
80
+ MemoryRegion dist_alias[EXYNOS4210_GIC_NCPUS];
76
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 1,
81
+ uint32_t num_cpu;
77
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
82
+ DeviceState *gic;
78
+ { .name = "IMP_TCMERR0",
79
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 0,
80
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
81
+ { .name = "IMP_TCMERR1",
82
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 1,
83
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
84
+ { .name = "IMP_TCMSYNDR0",
85
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 2,
86
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
87
+ { .name = "IMP_TCMSYNDR1",
88
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 3,
89
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
90
+ { .name = "IMP_FLASHERR0",
91
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 0,
92
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
93
+ { .name = "IMP_FLASHERR1",
94
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 1,
95
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
96
+ { .name = "IMP_CDBGDR0",
97
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 0,
98
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
99
+ { .name = "IMP_CBDGBR1",
100
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 1,
101
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
102
+ { .name = "IMP_TESTR0",
103
+ .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 0,
104
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
105
+ { .name = "IMP_TESTR1",
106
+ .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 1,
107
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
108
+ { .name = "IMP_CDBGDCI",
109
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 15, .opc2 = 0,
110
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
111
+ { .name = "IMP_CDBGDCT",
112
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 0,
113
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
114
+ { .name = "IMP_CDBGICT",
115
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 1,
116
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
117
+ { .name = "IMP_CDBGDCD",
118
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 0,
119
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
120
+ { .name = "IMP_CDBGICD",
121
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 1,
122
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
83
+};
123
+};
84
+
124
+
85
+#endif
125
+
86
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
126
static void cortex_r52_initfn(Object *obj)
87
index XXXXXXX..XXXXXXX 100644
127
{
88
--- a/hw/arm/exynos4210.c
128
ARMCPU *cpu = ARM_CPU(obj);
89
+++ b/hw/arm/exynos4210.c
129
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
90
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
130
set_feature(&cpu->env, ARM_FEATURE_NEON);
91
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
131
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
92
132
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
93
/* External GIC */
133
+ set_feature(&cpu->env, ARM_FEATURE_AUXCR);
94
- dev = qdev_new("exynos4210.gic");
134
cpu->midr = 0x411fd133; /* r1p3 */
95
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
135
cpu->revidr = 0x00000000;
96
- busdev = SYS_BUS_DEVICE(dev);
136
cpu->reset_fpsid = 0x41034023;
97
- sysbus_realize_and_unref(busdev, &error_fatal);
137
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
98
+ qdev_prop_set_uint32(DEVICE(&s->ext_gic), "num-cpu", EXYNOS4210_NCPUS);
138
99
+ busdev = SYS_BUS_DEVICE(&s->ext_gic);
139
cpu->pmsav7_dregion = 16;
100
+ sysbus_realize(busdev, &error_fatal);
140
cpu->pmsav8r_hdregion = 16;
101
/* Map CPU interface */
141
+
102
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
142
+ define_arm_cp_regs(cpu, cortex_r52_cp_reginfo);
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
}
107
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
108
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
109
+ s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
110
}
111
112
/* Internal Interrupt Combiner */
113
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
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
}
143
}
119
144
120
static void exynos4210_class_init(ObjectClass *klass, void *data)
145
static void cortex_r5f_initfn(Object *obj)
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
--
146
--
177
2.25.1
147
2.34.1
diff view generated by jsdifflib
1
Now we have removed the only use of TYPE_EXYNOS4210_IRQ_GATE we can
1
Architecturally, the AArch32 MSR/MRS to/from banked register
2
delete the device entirely.
2
instructions are UNPREDICTABLE for attempts to access a banked
3
register that the guest could access in a more direct way (e.g.
4
using this insn to access r8_fiq when already in FIQ mode). QEMU has
5
chosen to UNDEF on all of these.
6
7
However, for the case of accessing SPSR_hyp from hyp mode, it turns
8
out that real hardware permits this, with the same effect as if the
9
guest had directly written to SPSR. Further, there is some
10
guest code out there that assumes it can do this, because it
11
happens to work on hardware: an example Cortex-R52 startup code
12
fragment uses this, and it got copied into various other places,
13
including Zephyr. Zephyr was fixed to not use this:
14
https://github.com/zephyrproject-rtos/zephyr/issues/47330
15
but other examples are still out there, like the selftest
16
binary for the MPS3-AN536.
17
18
For convenience of being able to run guest code, permit
19
this UNPREDICTABLE access instead of UNDEFing it.
3
20
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20220404154658.565020-3-peter.maydell@linaro.org
23
Message-id: 20240206132931.38376-5-peter.maydell@linaro.org
7
---
24
---
8
hw/intc/exynos4210_gic.c | 107 ---------------------------------------
25
target/arm/tcg/op_helper.c | 43 ++++++++++++++++++++++++++------------
9
1 file changed, 107 deletions(-)
26
target/arm/tcg/translate.c | 19 +++++++++++------
27
2 files changed, 43 insertions(+), 19 deletions(-)
10
28
11
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
29
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
12
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/intc/exynos4210_gic.c
31
--- a/target/arm/tcg/op_helper.c
14
+++ b/hw/intc/exynos4210_gic.c
32
+++ b/target/arm/tcg/op_helper.c
15
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_register_types(void)
33
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
16
}
34
*/
17
35
int curmode = env->uncached_cpsr & CPSR_M;
18
type_init(exynos4210_gic_register_types)
36
19
-
37
- if (regno == 17) {
20
-/* IRQ OR Gate struct.
38
- /* ELR_Hyp: a special case because access from tgtmode is OK */
21
- *
39
- if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
22
- * This device models an OR gate. There are n_in input qdev gpio lines and one
40
- goto undef;
23
- * output sysbus IRQ line. The output IRQ level is formed as OR between all
41
+ if (tgtmode == ARM_CPU_MODE_HYP) {
24
- * gpio inputs.
42
+ /*
25
- */
43
+ * Handle Hyp target regs first because some are special cases
26
-
44
+ * which don't want the usual "not accessible from tgtmode" check.
27
-#define TYPE_EXYNOS4210_IRQ_GATE "exynos4210.irq_gate"
45
+ */
28
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210IRQGateState, EXYNOS4210_IRQ_GATE)
46
+ switch (regno) {
29
-
47
+ case 16 ... 17: /* ELR_Hyp, SPSR_Hyp */
30
-struct Exynos4210IRQGateState {
48
+ if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
31
- SysBusDevice parent_obj;
49
+ goto undef;
32
-
50
+ }
33
- uint32_t n_in; /* inputs amount */
51
+ break;
34
- uint32_t *level; /* input levels */
52
+ case 13:
35
- qemu_irq out; /* output IRQ */
53
+ if (curmode != ARM_CPU_MODE_MON) {
36
-};
54
+ goto undef;
37
-
55
+ }
38
-static Property exynos4210_irq_gate_properties[] = {
56
+ break;
39
- DEFINE_PROP_UINT32("n_in", Exynos4210IRQGateState, n_in, 1),
57
+ default:
40
- DEFINE_PROP_END_OF_LIST(),
58
+ g_assert_not_reached();
41
-};
59
}
42
-
60
return;
43
-static const VMStateDescription vmstate_exynos4210_irq_gate = {
61
}
44
- .name = "exynos4210.irq_gate",
62
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
45
- .version_id = 2,
63
}
46
- .minimum_version_id = 2,
64
}
47
- .fields = (VMStateField[]) {
65
48
- VMSTATE_VBUFFER_UINT32(level, Exynos4210IRQGateState, 1, NULL, n_in),
66
- if (tgtmode == ARM_CPU_MODE_HYP) {
49
- VMSTATE_END_OF_LIST()
67
- /* SPSR_Hyp, r13_hyp: accessible from Monitor mode only */
50
- }
68
- if (curmode != ARM_CPU_MODE_MON) {
51
-};
69
- goto undef;
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
- }
70
- }
68
- }
71
- }
69
-
72
-
70
- qemu_irq_lower(s->out);
73
return;
71
-}
74
72
-
75
undef:
73
-static void exynos4210_irq_gate_reset(DeviceState *d)
76
@@ -XXX,XX +XXX,XX @@ void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
74
-{
77
75
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(d);
78
switch (regno) {
76
-
79
case 16: /* SPSRs */
77
- memset(s->level, 0, s->n_in * sizeof(*s->level));
80
- env->banked_spsr[bank_number(tgtmode)] = value;
78
-}
81
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
79
-
82
+ /* Only happens for SPSR_Hyp access in Hyp mode */
80
-/*
83
+ env->spsr = value;
81
- * IRQ Gate initialization.
84
+ } else {
82
- */
85
+ env->banked_spsr[bank_number(tgtmode)] = value;
83
-static void exynos4210_irq_gate_init(Object *obj)
86
+ }
84
-{
87
break;
85
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(obj);
88
case 17: /* ELR_Hyp */
86
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
89
env->elr_el[2] = value;
87
-
90
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno)
88
- sysbus_init_irq(sbd, &s->out);
91
89
-}
92
switch (regno) {
90
-
93
case 16: /* SPSRs */
91
-static void exynos4210_irq_gate_realize(DeviceState *dev, Error **errp)
94
- return env->banked_spsr[bank_number(tgtmode)];
92
-{
95
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
93
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(dev);
96
+ /* Only happens for SPSR_Hyp access in Hyp mode */
94
-
97
+ return env->spsr;
95
- /* Allocate general purpose input signals and connect a handler to each of
98
+ } else {
96
- * them */
99
+ return env->banked_spsr[bank_number(tgtmode)];
97
- qdev_init_gpio_in(dev, exynos4210_irq_gate_handler, s->n_in);
100
+ }
98
-
101
case 17: /* ELR_Hyp */
99
- s->level = g_malloc0(s->n_in * sizeof(*s->level));
102
return env->elr_el[2];
100
-}
103
case 13:
101
-
104
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
102
-static void exynos4210_irq_gate_class_init(ObjectClass *klass, void *data)
105
index XXXXXXX..XXXXXXX 100644
103
-{
106
--- a/target/arm/tcg/translate.c
104
- DeviceClass *dc = DEVICE_CLASS(klass);
107
+++ b/target/arm/tcg/translate.c
105
-
108
@@ -XXX,XX +XXX,XX @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
106
- dc->reset = exynos4210_irq_gate_reset;
109
break;
107
- dc->vmsd = &vmstate_exynos4210_irq_gate;
110
case ARM_CPU_MODE_HYP:
108
- device_class_set_props(dc, exynos4210_irq_gate_properties);
111
/*
109
- dc->realize = exynos4210_irq_gate_realize;
112
- * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
110
-}
113
- * (and so we can forbid accesses from EL2 or below). elr_hyp
111
-
114
- * can be accessed also from Hyp mode, so forbid accesses from
112
-static const TypeInfo exynos4210_irq_gate_info = {
115
- * EL0 or EL1.
113
- .name = TYPE_EXYNOS4210_IRQ_GATE,
116
+ * r13_hyp can only be accessed from Monitor mode, and so we
114
- .parent = TYPE_SYS_BUS_DEVICE,
117
+ * can forbid accesses from EL2 or below.
115
- .instance_size = sizeof(Exynos4210IRQGateState),
118
+ * elr_hyp can be accessed also from Hyp mode, so forbid
116
- .instance_init = exynos4210_irq_gate_init,
119
+ * accesses from EL0 or EL1.
117
- .class_init = exynos4210_irq_gate_class_init,
120
+ * SPSR_hyp is supposed to be in the same category as r13_hyp
118
-};
121
+ * and UNPREDICTABLE if accessed from anything except Monitor
119
-
122
+ * mode. However there is some real-world code that will do
120
-static void exynos4210_irq_gate_register_types(void)
123
+ * it because at least some hardware happens to permit the
121
-{
124
+ * access. (Notably a standard Cortex-R52 startup code fragment
122
- type_register_static(&exynos4210_irq_gate_info);
125
+ * does this.) So we permit SPSR_hyp from Hyp mode also, to allow
123
-}
126
+ * this (incorrect) guest code to run.
124
-
127
*/
125
-type_init(exynos4210_irq_gate_register_types)
128
- if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
129
- (s->current_el < 3 && *regno != 17)) {
130
+ if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2
131
+ || (s->current_el < 3 && *regno != 16 && *regno != 17)) {
132
goto undef;
133
}
134
break;
126
--
135
--
127
2.25.1
136
2.34.1
diff view generated by jsdifflib
1
The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0
1
We currently guard the CFG3 register read with
2
and EXT_GIC_ID_MCT_G1 multiple times. This means that we will
2
(scc_partno(s) == 0x524 && scc_partno(s) == 0x547)
3
connect multiple IRQs up to the same external GIC input, which
3
which is clearly wrong as it is never true.
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
4
8
Overall we do this for interrupt IDs
5
This register is present on all board types except AN524
9
(1, 4), (12, 4), (35, 4), (51, 4), (53, 4) for EXT_GIC_ID_MCT_G0
6
and AN527; correct the condition.
10
and
11
(1, 5), (12, 5), (35, 5), (51, 5), (53, 5) for EXT_GIC_ID_MCT_G1
12
7
13
These correspond to the cases for the multi-core timer that we are
8
Fixes: 6ac80818941829c0 ("hw/misc/mps2-scc: Implement changes for AN547")
14
wiring up to multiple inputs on the combiner in
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
exynos4210_combiner_get_gpioin(). That code already deals with all
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
these interrupt IDs being the same input source, so we don't need to
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
connect the external GIC interrupt for any of them except the first
12
Message-id: 20240206132931.38376-6-peter.maydell@linaro.org
18
(1, 4) and (1, 5). Remove the array entries and conditionals which
13
---
19
were incorrectly causing us to wire up extra lines.
14
hw/misc/mps2-scc.c | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
20
16
21
This bug didn't cause any visible effects, because we only connect
17
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
22
up a device to the "primary" ID values (1, 4) and (1, 5), so the
23
extra lines would never be set to a level.
24
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
18
index XXXXXXX..XXXXXXX 100644
35
--- a/include/hw/arm/exynos4210.h
19
--- a/hw/misc/mps2-scc.c
36
+++ b/include/hw/arm/exynos4210.h
20
+++ b/hw/misc/mps2-scc.c
37
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
38
* one for every non-zero entry in combiner_grp_to_gic_id[].
22
r = s->cfg2;
39
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
23
break;
40
*/
24
case A_CFG3:
41
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
25
- if (scc_partno(s) == 0x524 && scc_partno(s) == 0x547) {
42
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
26
+ if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
43
27
/* CFG3 reserved on AN524 */
44
typedef struct Exynos4210Irq {
28
goto bad_offset;
45
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
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 @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
51
/* int combiner group 34 */
52
{ EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
53
/* int combiner group 35 */
54
- { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
55
+ { 0, 0, 0, EXT_GIC_ID_MCT_L1 },
56
/* int combiner group 36 */
57
{ EXT_GIC_ID_MIXER },
58
/* int combiner group 37 */
59
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
60
/* groups 38-50 */
61
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
62
/* int combiner group 51 */
63
- { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
64
+ { EXT_GIC_ID_MCT_L0 },
65
/* group 52 */
66
{ },
67
/* int combiner group 53 */
68
- { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
69
+ { EXT_GIC_ID_WDT },
70
/* groups 54-63 */
71
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
72
};
73
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
74
75
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
76
irq_id = 0;
77
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
78
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
79
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4)) {
80
/* MCT_G0 is passed to External GIC */
81
irq_id = EXT_GIC_ID_MCT_G0;
82
}
83
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
84
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
85
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5)) {
86
/* MCT_G1 is passed to External and GIC */
87
irq_id = EXT_GIC_ID_MCT_G1;
88
}
29
}
89
--
30
--
90
2.25.1
31
2.34.1
32
33
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
The MPS SCC device has a lot of different flavours for the various
2
different MPS FPGA images, which look mostly similar but have
3
differences in how particular registers are handled. Currently we
4
deal with this with a lot of open-coded checks on scc_partno(), but
5
as we add more board types this is getting a bit hard to read.
2
6
3
Add a model of the Xilinx Versal CRL.
7
Factor out the conditions into some functions which we can
8
give more descriptive names to.
4
9
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Message-id: 20220406174303.2022038-4-edgar.iglesias@xilinx.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20240206132931.38376-7-peter.maydell@linaro.org
10
---
14
---
11
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++
15
hw/misc/mps2-scc.c | 45 +++++++++++++++++++++++++++++++--------------
12
hw/misc/xlnx-versal-crl.c | 421 ++++++++++++++++++++++++++++++
16
1 file changed, 31 insertions(+), 14 deletions(-)
13
hw/misc/meson.build | 1 +
14
3 files changed, 657 insertions(+)
15
create mode 100644 include/hw/misc/xlnx-versal-crl.h
16
create mode 100644 hw/misc/xlnx-versal-crl.c
17
17
18
diff --git a/include/hw/misc/xlnx-versal-crl.h b/include/hw/misc/xlnx-versal-crl.h
18
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
19
new file mode 100644
19
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX
20
--- a/hw/misc/mps2-scc.c
21
--- /dev/null
21
+++ b/hw/misc/mps2-scc.c
22
+++ b/include/hw/misc/xlnx-versal-crl.h
22
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
23
@@ -XXX,XX +XXX,XX @@
23
return extract32(s->id, 4, 8);
24
+/*
24
}
25
+ * QEMU model of the Clock-Reset-LPD (CRL).
25
26
+ *
26
+/* Is CFG_REG2 present? */
27
+ * Copyright (c) 2022 Xilinx Inc.
27
+static bool have_cfg2(MPS2SCC *s)
28
+ * SPDX-License-Identifier: GPL-2.0-or-later
29
+ *
30
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
31
+ */
32
+#ifndef HW_MISC_XLNX_VERSAL_CRL_H
33
+#define HW_MISC_XLNX_VERSAL_CRL_H
34
+
35
+#include "hw/sysbus.h"
36
+#include "hw/register.h"
37
+#include "target/arm/cpu.h"
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
+{
28
+{
294
+ bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK];
29
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
295
+ qemu_set_irq(s->irq, pending);
296
+}
30
+}
297
+
31
+
298
+static void crl_status_postw(RegisterInfo *reg, uint64_t val64)
32
+/* Is CFG_REG3 present? */
33
+static bool have_cfg3(MPS2SCC *s)
299
+{
34
+{
300
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
35
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
301
+ crl_update_irq(s);
302
+}
36
+}
303
+
37
+
304
+static uint64_t crl_enable_prew(RegisterInfo *reg, uint64_t val64)
38
+/* Is CFG_REG5 present? */
39
+static bool have_cfg5(MPS2SCC *s)
305
+{
40
+{
306
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
41
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
307
+ uint32_t val = val64;
308
+
309
+ s->regs[R_IR_MASK] &= ~val;
310
+ crl_update_irq(s);
311
+ return 0;
312
+}
42
+}
313
+
43
+
314
+static uint64_t crl_disable_prew(RegisterInfo *reg, uint64_t val64)
44
+/* Is CFG_REG6 present? */
45
+static bool have_cfg6(MPS2SCC *s)
315
+{
46
+{
316
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
47
+ return scc_partno(s) == 0x524;
317
+ uint32_t val = val64;
318
+
319
+ s->regs[R_IR_MASK] |= val;
320
+ crl_update_irq(s);
321
+ return 0;
322
+}
48
+}
323
+
49
+
324
+static void crl_reset_dev(XlnxVersalCRL *s, DeviceState *dev,
50
/* Handle a write via the SYS_CFG channel to the specified function/device.
325
+ bool rst_old, bool rst_new)
51
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
326
+{
52
*/
327
+ device_cold_reset(dev);
53
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
328
+}
54
r = s->cfg1;
329
+
55
break;
330
+static void crl_reset_cpu(XlnxVersalCRL *s, ARMCPU *armcpu,
56
case A_CFG2:
331
+ bool rst_old, bool rst_new)
57
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
332
+{
58
- /* CFG2 reserved on other boards */
333
+ if (rst_new) {
59
+ if (!have_cfg2(s)) {
334
+ arm_set_cpu_off(armcpu->mp_affinity);
60
goto bad_offset;
335
+ } else {
61
}
336
+ arm_set_cpu_on_and_reset(armcpu->mp_affinity);
62
r = s->cfg2;
337
+ }
63
break;
338
+}
64
case A_CFG3:
339
+
65
- if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
340
+#define REGFIELD_RESET(type, s, reg, f, new_val, dev) { \
66
- /* CFG3 reserved on AN524 */
341
+ bool old_f = ARRAY_FIELD_EX32((s)->regs, reg, f); \
67
+ if (!have_cfg3(s)) {
342
+ bool new_f = FIELD_EX32(new_val, reg, f); \
68
goto bad_offset;
343
+ \
69
}
344
+ /* Detect edges. */ \
70
/* These are user-settable DIP switches on the board. We don't
345
+ if (dev && old_f != new_f) { \
71
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
346
+ crl_reset_ ## type(s, dev, old_f, new_f); \
72
r = s->cfg4;
347
+ } \
73
break;
348
+}
74
case A_CFG5:
349
+
75
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
350
+static uint64_t crl_rst_r5_prew(RegisterInfo *reg, uint64_t val64)
76
- /* CFG5 reserved on other boards */
351
+{
77
+ if (!have_cfg5(s)) {
352
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
78
goto bad_offset;
353
+
79
}
354
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU0, val64, s->cfg.cpu_r5[0]);
80
r = s->cfg5;
355
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU1, val64, s->cfg.cpu_r5[1]);
81
break;
356
+ return val64;
82
case A_CFG6:
357
+}
83
- if (scc_partno(s) != 0x524) {
358
+
84
- /* CFG6 reserved on other boards */
359
+static uint64_t crl_rst_adma_prew(RegisterInfo *reg, uint64_t val64)
85
+ if (!have_cfg6(s)) {
360
+{
86
goto bad_offset;
361
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
87
}
362
+ int i;
88
r = s->cfg6;
363
+
89
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
364
+ /* A single register fans out to all ADMA reset inputs. */
90
}
365
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); i++) {
91
break;
366
+ REGFIELD_RESET(dev, s, RST_ADMA, RESET, val64, s->cfg.adma[i]);
92
case A_CFG2:
367
+ }
93
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
368
+ return val64;
94
- /* CFG2 reserved on other boards */
369
+}
95
+ if (!have_cfg2(s)) {
370
+
96
goto bad_offset;
371
+static uint64_t crl_rst_uart0_prew(RegisterInfo *reg, uint64_t val64)
97
}
372
+{
98
/* AN524: QSPI Select signal */
373
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
99
s->cfg2 = value;
374
+
100
break;
375
+ REGFIELD_RESET(dev, s, RST_UART0, RESET, val64, s->cfg.uart[0]);
101
case A_CFG5:
376
+ return val64;
102
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
377
+}
103
- /* CFG5 reserved on other boards */
378
+
104
+ if (!have_cfg5(s)) {
379
+static uint64_t crl_rst_uart1_prew(RegisterInfo *reg, uint64_t val64)
105
goto bad_offset;
380
+{
106
}
381
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
107
/* AN524: ACLK frequency in Hz */
382
+
108
s->cfg5 = value;
383
+ REGFIELD_RESET(dev, s, RST_UART1, RESET, val64, s->cfg.uart[1]);
109
break;
384
+ return val64;
110
case A_CFG6:
385
+}
111
- if (scc_partno(s) != 0x524) {
386
+
112
- /* CFG6 reserved on other boards */
387
+static uint64_t crl_rst_gem0_prew(RegisterInfo *reg, uint64_t val64)
113
+ if (!have_cfg6(s)) {
388
+{
114
goto bad_offset;
389
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
115
}
390
+
116
/* AN524: Clock divider for BRAM */
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
--
117
--
699
2.25.1
118
2.34.1
119
120
diff view generated by jsdifflib
1
The function exynos4210_init_board_irqs() currently lives in
1
The MPS2 SCC device is broadly the same for all FPGA images, but has
2
exynos4210_gic.c, but it isn't really part of the exynos4210.gic
2
minor differences in the behaviour of the CFG registers depending on
3
device -- it is a function that implements (some of) the wiring up of
3
the image. In many cases we don't really care about the functionality
4
interrupts between the SoC's GIC and combiner components. This means
4
controlled by these registers and a reads-as-written or similar
5
it fits better in exynos4210.c, which is the SoC-level code. Move it
5
behaviour is sufficient for the moment.
6
there. Similarly, exynos4210_git_irq() is used almost only in the
6
7
SoC-level code, so move it too.
7
For the AN536 the required behaviour is:
8
9
* A_CFG0 has CPU reset and halt bits
10
- implement as reads-as-written for the moment
11
* A_CFG1 has flash or ATCM address 0 remap handling
12
- QEMU doesn't model this; implement as reads-as-written
13
* A_CFG2 has QSPI select (like AN524)
14
- implemented (no behaviour, as with AN524)
15
* A_CFG3 is MCC_MSB_ADDR "additional MCC addressing bits"
16
- QEMU doesn't care about these, so use the existing
17
RAZ behaviour for convenience
18
* A_CFG4 is board rev (like all other images)
19
- no change needed
20
* A_CFG5 is ACLK frq in hz (like AN524)
21
- implemented as reads-as-written, as for other boards
22
* A_CFG6 is core 0 vector table base address
23
- implemented as reads-as-written for the moment
24
* A_CFG7 is core 1 vector table base address
25
- implemented as reads-as-written for the moment
26
27
Make the changes necessary for this; leave TODO comments where
28
appropriate to indicate where we might want to come back and
29
implement things like CPU reset.
30
31
The other aspects of the device specific to this FPGA image (like the
32
values of the board ID and similar registers) will be set via the
33
device's qdev properties.
8
34
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
36
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-8-peter.maydell@linaro.org
37
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
38
Message-id: 20240206132931.38376-8-peter.maydell@linaro.org
12
---
39
---
13
include/hw/arm/exynos4210.h | 4 -
40
include/hw/misc/mps2-scc.h | 1 +
14
hw/arm/exynos4210.c | 202 +++++++++++++++++++++++++++++++++++
41
hw/misc/mps2-scc.c | 101 +++++++++++++++++++++++++++++++++----
15
hw/intc/exynos4210_gic.c | 204 ------------------------------------
42
2 files changed, 92 insertions(+), 10 deletions(-)
16
3 files changed, 202 insertions(+), 208 deletions(-)
43
17
44
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
19
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/exynos4210.h
46
--- a/include/hw/misc/mps2-scc.h
21
+++ b/include/hw/arm/exynos4210.h
47
+++ b/include/hw/misc/mps2-scc.h
22
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
48
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
23
void exynos4210_write_secondary(ARMCPU *cpu,
49
uint32_t cfg4;
24
const struct arm_boot_info *info);
50
uint32_t cfg5;
25
51
uint32_t cfg6;
26
-/* Initialize board IRQs.
52
+ uint32_t cfg7;
27
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs */
53
uint32_t cfgdata_rtn;
28
-void exynos4210_init_board_irqs(Exynos4210State *s);
54
uint32_t cfgdata_out;
29
-
55
uint32_t cfgctrl;
30
/* Get IRQ number from exynos4210 IRQ subsystem stub.
56
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
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
57
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/exynos4210.c
58
--- a/hw/misc/mps2-scc.c
36
+++ b/hw/arm/exynos4210.c
59
+++ b/hw/misc/mps2-scc.c
37
@@ -XXX,XX +XXX,XX @@
60
@@ -XXX,XX +XXX,XX @@ REG32(CFG3, 0xc)
38
#define EXYNOS4210_PL330_BASE1_ADDR 0x12690000
61
REG32(CFG4, 0x10)
39
#define EXYNOS4210_PL330_BASE2_ADDR 0x12850000
62
REG32(CFG5, 0x14)
40
63
REG32(CFG6, 0x18)
41
+enum ExtGicId {
64
+REG32(CFG7, 0x1c)
42
+ EXT_GIC_ID_MDMA_LCD0 = 66,
65
REG32(CFGDATA_RTN, 0xa0)
43
+ EXT_GIC_ID_PDMA0,
66
REG32(CFGDATA_OUT, 0xa4)
44
+ EXT_GIC_ID_PDMA1,
67
REG32(CFGCTRL, 0xa8)
45
+ EXT_GIC_ID_TIMER0,
68
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
46
+ EXT_GIC_ID_TIMER1,
69
/* Is CFG_REG2 present? */
47
+ EXT_GIC_ID_TIMER2,
70
static bool have_cfg2(MPS2SCC *s)
48
+ EXT_GIC_ID_TIMER3,
71
{
49
+ EXT_GIC_ID_TIMER4,
72
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
50
+ EXT_GIC_ID_MCT_L0,
73
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
51
+ EXT_GIC_ID_WDT,
74
+ scc_partno(s) == 0x536;
52
+ EXT_GIC_ID_RTC_ALARM,
75
}
53
+ EXT_GIC_ID_RTC_TIC,
76
54
+ EXT_GIC_ID_GPIO_XB,
77
/* Is CFG_REG3 present? */
55
+ EXT_GIC_ID_GPIO_XA,
78
static bool have_cfg3(MPS2SCC *s)
56
+ EXT_GIC_ID_MCT_L1,
79
{
57
+ EXT_GIC_ID_IEM_APC,
80
- return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
58
+ EXT_GIC_ID_IEM_IEC,
81
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547 &&
59
+ EXT_GIC_ID_NFC,
82
+ scc_partno(s) != 0x536;
60
+ EXT_GIC_ID_UART0,
83
}
61
+ EXT_GIC_ID_UART1,
84
62
+ EXT_GIC_ID_UART2,
85
/* Is CFG_REG5 present? */
63
+ EXT_GIC_ID_UART3,
86
static bool have_cfg5(MPS2SCC *s)
64
+ EXT_GIC_ID_UART4,
87
{
65
+ EXT_GIC_ID_MCT_G0,
88
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
66
+ EXT_GIC_ID_I2C0,
89
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
67
+ EXT_GIC_ID_I2C1,
90
+ scc_partno(s) == 0x536;
68
+ EXT_GIC_ID_I2C2,
91
}
69
+ EXT_GIC_ID_I2C3,
92
70
+ EXT_GIC_ID_I2C4,
93
/* Is CFG_REG6 present? */
71
+ EXT_GIC_ID_I2C5,
94
static bool have_cfg6(MPS2SCC *s)
72
+ EXT_GIC_ID_I2C6,
95
{
73
+ EXT_GIC_ID_I2C7,
96
- return scc_partno(s) == 0x524;
74
+ EXT_GIC_ID_SPI0,
97
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x536;
75
+ EXT_GIC_ID_SPI1,
98
+}
76
+ EXT_GIC_ID_SPI2,
99
+
77
+ EXT_GIC_ID_MCT_G1,
100
+/* Is CFG_REG7 present? */
78
+ EXT_GIC_ID_USB_HOST,
101
+static bool have_cfg7(MPS2SCC *s)
79
+ EXT_GIC_ID_USB_DEVICE,
102
+{
80
+ EXT_GIC_ID_MODEMIF,
103
+ return scc_partno(s) == 0x536;
81
+ EXT_GIC_ID_HSMMC0,
104
+}
82
+ EXT_GIC_ID_HSMMC1,
105
+
83
+ EXT_GIC_ID_HSMMC2,
106
+/* Does CFG_REG0 drive the 'remap' GPIO output? */
84
+ EXT_GIC_ID_HSMMC3,
107
+static bool cfg0_is_remap(MPS2SCC *s)
85
+ EXT_GIC_ID_SDMMC,
108
+{
86
+ EXT_GIC_ID_MIPI_CSI_4LANE,
109
+ return scc_partno(s) != 0x536;
87
+ EXT_GIC_ID_MIPI_DSI_4LANE,
110
+}
88
+ EXT_GIC_ID_MIPI_CSI_2LANE,
111
+
89
+ EXT_GIC_ID_MIPI_DSI_2LANE,
112
+/* Is CFG_REG1 driving a set of LEDs? */
90
+ EXT_GIC_ID_ONENAND_AUDI,
113
+static bool cfg1_is_leds(MPS2SCC *s)
91
+ EXT_GIC_ID_ROTATOR,
114
+{
92
+ EXT_GIC_ID_FIMC0,
115
+ return scc_partno(s) != 0x536;
93
+ EXT_GIC_ID_FIMC1,
116
}
94
+ EXT_GIC_ID_FIMC2,
117
95
+ EXT_GIC_ID_FIMC3,
118
/* Handle a write via the SYS_CFG channel to the specified function/device.
96
+ EXT_GIC_ID_JPEG,
119
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
97
+ EXT_GIC_ID_2D,
120
if (!have_cfg3(s)) {
98
+ EXT_GIC_ID_PCIe,
121
goto bad_offset;
99
+ EXT_GIC_ID_MIXER,
122
}
100
+ EXT_GIC_ID_HDMI,
123
- /* These are user-settable DIP switches on the board. We don't
101
+ EXT_GIC_ID_HDMI_I2C,
124
+ /*
102
+ EXT_GIC_ID_MFC,
125
+ * These are user-settable DIP switches on the board. We don't
103
+ EXT_GIC_ID_TVENC,
126
* model that, so just return zeroes.
127
+ *
128
+ * TODO: for AN536 this is MCC_MSB_ADDR "additional MCC addressing
129
+ * bits". These change which part of the DDR4 the motherboard
130
+ * configuration controller can see in its memory map (see the
131
+ * appnote section 2.4). QEMU doesn't model the MCC at all, so these
132
+ * bits are not interesting to us; read-as-zero is as good as anything
133
+ * else.
134
*/
135
r = 0;
136
break;
137
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
138
}
139
r = s->cfg6;
140
break;
141
+ case A_CFG7:
142
+ if (!have_cfg7(s)) {
143
+ goto bad_offset;
144
+ }
145
+ r = s->cfg7;
146
+ break;
147
case A_CFGDATA_RTN:
148
r = s->cfgdata_rtn;
149
break;
150
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
151
* we always reflect bit 0 in the 'remap' GPIO output line,
152
* and let the board wire it up or not as it chooses.
153
* TODO on some boards bit 1 is CPU_WAIT.
154
+ *
155
+ * TODO: on the AN536 this register controls reset and halt
156
+ * for both CPUs. For the moment we don't implement this, so the
157
+ * register just reads as written.
158
*/
159
s->cfg0 = value;
160
- qemu_set_irq(s->remap, s->cfg0 & 1);
161
+ if (cfg0_is_remap(s)) {
162
+ qemu_set_irq(s->remap, s->cfg0 & 1);
163
+ }
164
break;
165
case A_CFG1:
166
s->cfg1 = value;
167
- for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
168
- led_set_state(s->led[i], extract32(value, i, 1));
169
+ /*
170
+ * On most boards this register drives LEDs.
171
+ *
172
+ * TODO: for AN536 this controls whether flash and ATCM are
173
+ * enabled or disabled on reset. QEMU doesn't model this, and
174
+ * always wires up RAM in the ATCM area and ROM in the flash area.
175
+ */
176
+ if (cfg1_is_leds(s)) {
177
+ for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
178
+ led_set_state(s->led[i], extract32(value, i, 1));
179
+ }
180
}
181
break;
182
case A_CFG2:
183
if (!have_cfg2(s)) {
184
goto bad_offset;
185
}
186
- /* AN524: QSPI Select signal */
187
+ /* AN524, AN536: QSPI Select signal */
188
s->cfg2 = value;
189
break;
190
case A_CFG5:
191
if (!have_cfg5(s)) {
192
goto bad_offset;
193
}
194
- /* AN524: ACLK frequency in Hz */
195
+ /* AN524, AN536: ACLK frequency in Hz */
196
s->cfg5 = value;
197
break;
198
case A_CFG6:
199
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
200
goto bad_offset;
201
}
202
/* AN524: Clock divider for BRAM */
203
+ /* AN536: Core 0 vector table base address */
204
+ s->cfg6 = value;
205
+ break;
206
+ case A_CFG7:
207
+ if (!have_cfg7(s)) {
208
+ goto bad_offset;
209
+ }
210
+ /* AN536: Core 1 vector table base address */
211
s->cfg6 = value;
212
break;
213
case A_CFGDATA_OUT:
214
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_finalize(Object *obj)
215
g_free(s->oscclk_reset);
216
}
217
218
+static bool cfg7_needed(void *opaque)
219
+{
220
+ MPS2SCC *s = opaque;
221
+
222
+ return have_cfg7(s);
223
+}
224
+
225
+static const VMStateDescription vmstate_cfg7 = {
226
+ .name = "mps2-scc/cfg7",
227
+ .version_id = 1,
228
+ .minimum_version_id = 1,
229
+ .needed = cfg7_needed,
230
+ .fields = (const VMStateField[]) {
231
+ VMSTATE_UINT32(cfg7, MPS2SCC),
232
+ VMSTATE_END_OF_LIST()
233
+ }
104
+};
234
+};
105
+
235
+
106
+enum ExtInt {
236
static const VMStateDescription mps2_scc_vmstate = {
107
+ EXT_GIC_ID_EXTINT0 = 48,
237
.name = "mps2-scc",
108
+ EXT_GIC_ID_EXTINT1,
238
.version_id = 3,
109
+ EXT_GIC_ID_EXTINT2,
239
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_scc_vmstate = {
110
+ EXT_GIC_ID_EXTINT3,
240
VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
111
+ EXT_GIC_ID_EXTINT4,
241
0, vmstate_info_uint32, uint32_t),
112
+ EXT_GIC_ID_EXTINT5,
242
VMSTATE_END_OF_LIST()
113
+ EXT_GIC_ID_EXTINT6,
243
+ },
114
+ EXT_GIC_ID_EXTINT7,
244
+ .subsections = (const VMStateDescription * const []) {
115
+ EXT_GIC_ID_EXTINT8,
245
+ &vmstate_cfg7,
116
+ EXT_GIC_ID_EXTINT9,
246
+ NULL
117
+ EXT_GIC_ID_EXTINT10,
247
}
118
+ EXT_GIC_ID_EXTINT11,
248
};
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
249
468
--
250
--
469
2.25.1
251
2.34.1
252
253
diff view generated by jsdifflib
1
Switch the creation of the combiner devices to the new-style
1
The AN536 is another FPGA image for the MPS3 development board. Unlike
2
"embedded in state struct" approach, so we can easily refer
2
the existing FPGA images we already model, this board uses a Cortex-R
3
to the object elsewhere during realize.
3
family CPU, and it does not use any equivalent to the M-profile
4
"Subsystem for Embedded" SoC-equivalent that we model in hw/arm/armsse.c.
5
It's therefore more convenient for us to model it as a completely
6
separate C file.
7
8
This commit adds the basic skeleton of the board model, and the
9
code to create all the RAM and ROM. We assume that we're probably
10
going to want to add more images in future, so use the same
11
base class/subclass setup that mps2-tz.c uses, even though at
12
the moment there's only a single subclass.
13
14
Following commits will add the CPUs and the peripherals.
4
15
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20220404154658.565020-18-peter.maydell@linaro.org
18
Message-id: 20240206132931.38376-9-peter.maydell@linaro.org
8
---
19
---
9
include/hw/arm/exynos4210.h | 3 ++
20
MAINTAINERS | 3 +-
10
include/hw/intc/exynos4210_combiner.h | 57 +++++++++++++++++++++++++++
21
configs/devices/arm-softmmu/default.mak | 1 +
11
hw/arm/exynos4210.c | 20 +++++-----
22
hw/arm/mps3r.c | 239 ++++++++++++++++++++++++
12
hw/intc/exynos4210_combiner.c | 31 +--------------
23
hw/arm/Kconfig | 5 +
13
4 files changed, 72 insertions(+), 39 deletions(-)
24
hw/arm/meson.build | 1 +
14
create mode 100644 include/hw/intc/exynos4210_combiner.h
25
5 files changed, 248 insertions(+), 1 deletion(-)
15
26
create mode 100644 hw/arm/mps3r.c
16
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
27
28
diff --git a/MAINTAINERS b/MAINTAINERS
17
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/exynos4210.h
30
--- a/MAINTAINERS
19
+++ b/include/hw/arm/exynos4210.h
31
+++ b/MAINTAINERS
20
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@ F: include/hw/misc/imx7_*.h
21
#include "hw/sysbus.h"
33
F: hw/pci-host/designware.c
22
#include "hw/cpu/a9mpcore.h"
34
F: include/hw/pci-host/designware.h
23
#include "hw/intc/exynos4210_gic.h"
35
24
+#include "hw/intc/exynos4210_combiner.h"
36
-MPS2
25
#include "hw/core/split-irq.h"
37
+MPS2 / MPS3
26
#include "target/arm/cpu-qom.h"
38
M: Peter Maydell <peter.maydell@linaro.org>
27
#include "qom/object.h"
39
L: qemu-arm@nongnu.org
28
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
40
S: Maintained
29
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
41
F: hw/arm/mps2.c
30
A9MPPrivState a9mpcore;
42
F: hw/arm/mps2-tz.c
31
Exynos4210GicState ext_gic;
43
+F: hw/arm/mps3r.c
32
+ Exynos4210CombinerState int_combiner;
44
F: hw/misc/mps2-*.c
33
+ Exynos4210CombinerState ext_combiner;
45
F: include/hw/misc/mps2-*.h
34
SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
46
F: hw/arm/armsse.c
35
};
47
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
36
48
index XXXXXXX..XXXXXXX 100644
37
diff --git a/include/hw/intc/exynos4210_combiner.h b/include/hw/intc/exynos4210_combiner.h
49
--- a/configs/devices/arm-softmmu/default.mak
50
+++ b/configs/devices/arm-softmmu/default.mak
51
@@ -XXX,XX +XXX,XX @@ CONFIG_ARM_VIRT=y
52
# CONFIG_INTEGRATOR=n
53
# CONFIG_FSL_IMX31=n
54
# CONFIG_MUSICPAL=n
55
+# CONFIG_MPS3R=n
56
# CONFIG_MUSCA=n
57
# CONFIG_CHEETAH=n
58
# CONFIG_SX1=n
59
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
38
new file mode 100644
60
new file mode 100644
39
index XXXXXXX..XXXXXXX
61
index XXXXXXX..XXXXXXX
40
--- /dev/null
62
--- /dev/null
41
+++ b/include/hw/intc/exynos4210_combiner.h
63
+++ b/hw/arm/mps3r.c
42
@@ -XXX,XX +XXX,XX @@
64
@@ -XXX,XX +XXX,XX @@
43
+/*
65
+/*
44
+ * Samsung exynos4210 Interrupt Combiner
66
+ * Arm MPS3 board emulation for Cortex-R-based FPGA images.
67
+ * (For M-profile images see mps2.c and mps2tz.c.)
45
+ *
68
+ *
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
69
+ * Copyright (c) 2017 Linaro Limited
47
+ * All rights reserved.
70
+ * Written by Peter Maydell
48
+ *
71
+ *
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
72
+ * This program is free software; you can redistribute it and/or modify
73
+ * it under the terms of the GNU General Public License version 2 or
74
+ * (at your option) any later version.
75
+ */
76
+
77
+/*
78
+ * The MPS3 is an FPGA based dev board. This file handles FPGA images
79
+ * which use the Cortex-R CPUs. We model these separately from the
80
+ * M-profile images, because on M-profile the FPGA image is based on
81
+ * a "Subsystem for Embedded" which is similar to an SoC, whereas
82
+ * the R-profile FPGA images don't have that abstraction layer.
50
+ *
83
+ *
51
+ * This program is free software; you can redistribute it and/or modify it
84
+ * We model the following FPGA images here:
52
+ * under the terms of the GNU General Public License as published by the
85
+ * "mps3-an536" -- dual Cortex-R52 as documented in Arm Application Note AN536
53
+ * Free Software Foundation; either version 2 of the License, or (at your
54
+ * option) any later version.
55
+ *
86
+ *
56
+ * This program is distributed in the hope that it will be useful,
87
+ * Application Note AN536:
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
88
+ * https://developer.arm.com/documentation/dai0536/latest/
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
+ */
89
+ */
64
+
90
+
65
+#ifndef HW_INTC_EXYNOS4210_COMBINER
91
+#include "qemu/osdep.h"
66
+#define HW_INTC_EXYNOS4210_COMBINER
92
+#include "qemu/units.h"
67
+
93
+#include "qapi/error.h"
68
+#include "hw/sysbus.h"
94
+#include "exec/address-spaces.h"
95
+#include "cpu.h"
96
+#include "hw/boards.h"
97
+#include "hw/arm/boot.h"
98
+
99
+/* Define the layout of RAM and ROM in a board */
100
+typedef struct RAMInfo {
101
+ const char *name;
102
+ hwaddr base;
103
+ hwaddr size;
104
+ int mrindex; /* index into rams[]; -1 for the system RAM block */
105
+ int flags;
106
+} RAMInfo;
69
+
107
+
70
+/*
108
+/*
71
+ * State for each output signal of internal combiner
109
+ * The MPS3 DDR is 3GiB, but on a 32-bit host QEMU doesn't permit
110
+ * emulation of that much guest RAM, so artificially make it smaller.
72
+ */
111
+ */
73
+typedef struct CombinerGroupState {
112
+#if HOST_LONG_BITS == 32
74
+ uint8_t src_mask; /* 1 - source enabled, 0 - disabled */
113
+#define MPS3_DDR_SIZE (1 * GiB)
75
+ uint8_t src_pending; /* Pending source interrupts before masking */
114
+#else
76
+} CombinerGroupState;
115
+#define MPS3_DDR_SIZE (3 * GiB)
77
+
116
+#endif
78
+#define TYPE_EXYNOS4210_COMBINER "exynos4210.combiner"
117
+
79
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210CombinerState, EXYNOS4210_COMBINER)
118
+/*
80
+
119
+ * Flag values:
81
+/* Number of groups and total number of interrupts for the internal combiner */
120
+ * IS_MAIN: this is the main machine RAM
82
+#define IIC_NGRP 64
121
+ * IS_ROM: this area is read-only
83
+#define IIC_NIRQ (IIC_NGRP * 8)
122
+ */
84
+#define IIC_REGSET_SIZE 0x41
123
+#define IS_MAIN 1
85
+
124
+#define IS_ROM 2
86
+struct Exynos4210CombinerState {
125
+
87
+ SysBusDevice parent_obj;
126
+#define MPS3R_RAM_MAX 9
88
+
127
+
89
+ MemoryRegion iomem;
128
+typedef enum MPS3RFPGAType {
90
+
129
+ FPGA_AN536,
91
+ struct CombinerGroupState group[IIC_NGRP];
130
+} MPS3RFPGAType;
92
+ uint32_t reg_set[IIC_REGSET_SIZE];
131
+
93
+ uint32_t icipsr[2];
132
+struct MPS3RMachineClass {
94
+ uint32_t external; /* 1 means that this combiner is external */
133
+ MachineClass parent;
95
+
134
+ MPS3RFPGAType fpga_type;
96
+ qemu_irq output_irq[IIC_NGRP];
135
+ const RAMInfo *raminfo;
97
+};
136
+};
98
+
137
+
99
+#endif
138
+struct MPS3RMachineState {
100
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
139
+ MachineState parent;
140
+ MemoryRegion ram[MPS3R_RAM_MAX];
141
+};
142
+
143
+#define TYPE_MPS3R_MACHINE "mps3r"
144
+#define TYPE_MPS3R_AN536_MACHINE MACHINE_TYPE_NAME("mps3-an536")
145
+
146
+OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE)
147
+
148
+static const RAMInfo an536_raminfo[] = {
149
+ {
150
+ .name = "ATCM",
151
+ .base = 0x00000000,
152
+ .size = 0x00008000,
153
+ .mrindex = 0,
154
+ }, {
155
+ /* We model the QSPI flash as simple ROM for now */
156
+ .name = "QSPI",
157
+ .base = 0x08000000,
158
+ .size = 0x00800000,
159
+ .flags = IS_ROM,
160
+ .mrindex = 1,
161
+ }, {
162
+ .name = "BRAM",
163
+ .base = 0x10000000,
164
+ .size = 0x00080000,
165
+ .mrindex = 2,
166
+ }, {
167
+ .name = "DDR",
168
+ .base = 0x20000000,
169
+ .size = MPS3_DDR_SIZE,
170
+ .mrindex = -1,
171
+ }, {
172
+ .name = "ATCM0",
173
+ .base = 0xee000000,
174
+ .size = 0x00008000,
175
+ .mrindex = 3,
176
+ }, {
177
+ .name = "BTCM0",
178
+ .base = 0xee100000,
179
+ .size = 0x00008000,
180
+ .mrindex = 4,
181
+ }, {
182
+ .name = "CTCM0",
183
+ .base = 0xee200000,
184
+ .size = 0x00008000,
185
+ .mrindex = 5,
186
+ }, {
187
+ .name = "ATCM1",
188
+ .base = 0xee400000,
189
+ .size = 0x00008000,
190
+ .mrindex = 6,
191
+ }, {
192
+ .name = "BTCM1",
193
+ .base = 0xee500000,
194
+ .size = 0x00008000,
195
+ .mrindex = 7,
196
+ }, {
197
+ .name = "CTCM1",
198
+ .base = 0xee600000,
199
+ .size = 0x00008000,
200
+ .mrindex = 8,
201
+ }, {
202
+ .name = NULL,
203
+ }
204
+};
205
+
206
+static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
207
+ const RAMInfo *raminfo)
208
+{
209
+ /* Return an initialized MemoryRegion for the RAMInfo. */
210
+ MemoryRegion *ram;
211
+
212
+ if (raminfo->mrindex < 0) {
213
+ /* Means this RAMInfo is for QEMU's "system memory" */
214
+ MachineState *machine = MACHINE(mms);
215
+ assert(!(raminfo->flags & IS_ROM));
216
+ return machine->ram;
217
+ }
218
+
219
+ assert(raminfo->mrindex < MPS3R_RAM_MAX);
220
+ ram = &mms->ram[raminfo->mrindex];
221
+
222
+ memory_region_init_ram(ram, NULL, raminfo->name,
223
+ raminfo->size, &error_fatal);
224
+ if (raminfo->flags & IS_ROM) {
225
+ memory_region_set_readonly(ram, true);
226
+ }
227
+ return ram;
228
+}
229
+
230
+static void mps3r_common_init(MachineState *machine)
231
+{
232
+ MPS3RMachineState *mms = MPS3R_MACHINE(machine);
233
+ MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
234
+ MemoryRegion *sysmem = get_system_memory();
235
+
236
+ for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
237
+ MemoryRegion *mr = mr_for_raminfo(mms, ri);
238
+ memory_region_add_subregion(sysmem, ri->base, mr);
239
+ }
240
+}
241
+
242
+static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
243
+{
244
+ /*
245
+ * Set mc->default_ram_size and default_ram_id from the
246
+ * information in mmc->raminfo.
247
+ */
248
+ MachineClass *mc = MACHINE_CLASS(mmc);
249
+ const RAMInfo *p;
250
+
251
+ for (p = mmc->raminfo; p->name; p++) {
252
+ if (p->mrindex < 0) {
253
+ /* Found the entry for "system memory" */
254
+ mc->default_ram_size = p->size;
255
+ mc->default_ram_id = p->name;
256
+ return;
257
+ }
258
+ }
259
+ g_assert_not_reached();
260
+}
261
+
262
+static void mps3r_class_init(ObjectClass *oc, void *data)
263
+{
264
+ MachineClass *mc = MACHINE_CLASS(oc);
265
+
266
+ mc->init = mps3r_common_init;
267
+}
268
+
269
+static void mps3r_an536_class_init(ObjectClass *oc, void *data)
270
+{
271
+ MachineClass *mc = MACHINE_CLASS(oc);
272
+ MPS3RMachineClass *mmc = MPS3R_MACHINE_CLASS(oc);
273
+ static const char * const valid_cpu_types[] = {
274
+ ARM_CPU_TYPE_NAME("cortex-r52"),
275
+ NULL
276
+ };
277
+
278
+ mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
279
+ mc->default_cpus = 2;
280
+ mc->min_cpus = mc->default_cpus;
281
+ mc->max_cpus = mc->default_cpus;
282
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
283
+ mc->valid_cpu_types = valid_cpu_types;
284
+ mmc->raminfo = an536_raminfo;
285
+ mps3r_set_default_ram_info(mmc);
286
+}
287
+
288
+static const TypeInfo mps3r_machine_types[] = {
289
+ {
290
+ .name = TYPE_MPS3R_MACHINE,
291
+ .parent = TYPE_MACHINE,
292
+ .abstract = true,
293
+ .instance_size = sizeof(MPS3RMachineState),
294
+ .class_size = sizeof(MPS3RMachineClass),
295
+ .class_init = mps3r_class_init,
296
+ }, {
297
+ .name = TYPE_MPS3R_AN536_MACHINE,
298
+ .parent = TYPE_MPS3R_MACHINE,
299
+ .class_init = mps3r_an536_class_init,
300
+ },
301
+};
302
+
303
+DEFINE_TYPES(mps3r_machine_types);
304
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
101
index XXXXXXX..XXXXXXX 100644
305
index XXXXXXX..XXXXXXX 100644
102
--- a/hw/arm/exynos4210.c
306
--- a/hw/arm/Kconfig
103
+++ b/hw/arm/exynos4210.c
307
+++ b/hw/arm/Kconfig
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
308
@@ -XXX,XX +XXX,XX @@ config MAINSTONE
105
}
309
select PFLASH_CFI01
106
310
select SMC91C111
107
/* Internal Interrupt Combiner */
311
108
- dev = qdev_new("exynos4210.combiner");
312
+config MPS3R
109
- busdev = SYS_BUS_DEVICE(dev);
313
+ bool
110
- sysbus_realize_and_unref(busdev, &error_fatal);
314
+ default y
111
+ busdev = SYS_BUS_DEVICE(&s->int_combiner);
315
+ depends on TCG && ARM
112
+ sysbus_realize(busdev, &error_fatal);
316
+
113
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
317
config MUSCA
114
sysbus_connect_irq(busdev, n,
318
bool
115
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
319
default y
116
}
320
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
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
321
index XXXXXXX..XXXXXXX 100644
150
--- a/hw/intc/exynos4210_combiner.c
322
--- a/hw/arm/meson.build
151
+++ b/hw/intc/exynos4210_combiner.c
323
+++ b/hw/arm/meson.build
152
@@ -XXX,XX +XXX,XX @@
324
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_HIGHBANK', if_true: files('highbank.c'))
153
#include "hw/sysbus.h"
325
arm_ss.add(when: 'CONFIG_INTEGRATOR', if_true: files('integratorcp.c'))
154
#include "migration/vmstate.h"
326
arm_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mainstone.c'))
155
#include "qemu/module.h"
327
arm_ss.add(when: 'CONFIG_MICROBIT', if_true: files('microbit.c'))
156
-
328
+arm_ss.add(when: 'CONFIG_MPS3R', if_true: files('mps3r.c'))
157
+#include "hw/intc/exynos4210_combiner.h"
329
arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c'))
158
#include "hw/arm/exynos4210.h"
330
arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c'))
159
#include "hw/hw.h"
331
arm_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c'))
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
--
332
--
199
2.25.1
333
2.34.1
334
335
diff view generated by jsdifflib
1
At this point, the function exynos4210_init_board_irqs() splits input
1
Create the CPUs, the GIC, and the per-CPU RAM block for
2
IRQ lines to connect them to the input combiner, output combiner and
2
the mps3-an536 board.
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
7
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
8
configurable number of outputs, we can do all this in one place, by
9
making exynos4210_init_board_irqs() add extra outputs to the splitter
10
device when it must be connected to more than one input on each
11
combiner.
12
13
We do this with a new data structure, the combinermap, which is an
14
array each of whose elements is a list of the interrupt IDs on the
15
combiner which must be tied together. As we loop through each
16
interrupt ID, if we find that it is the first one in one of these
17
lists, we configure the splitter device with eonugh extra outputs and
18
wire them up to the other interrupt IDs in the list.
19
20
Conveniently, for all the cases where this is necessary, the
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
3
39
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
40
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20240206132931.38376-10-peter.maydell@linaro.org
41
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
42
---
6
---
43
include/hw/arm/exynos4210.h | 6 +-
7
hw/arm/mps3r.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++++-
44
hw/arm/exynos4210.c | 178 +++++++++++++++++++++++-------------
8
1 file changed, 177 insertions(+), 3 deletions(-)
45
2 files changed, 119 insertions(+), 65 deletions(-)
46
9
47
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
10
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
48
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
49
--- a/include/hw/arm/exynos4210.h
12
--- a/hw/arm/mps3r.c
50
+++ b/include/hw/arm/exynos4210.h
13
+++ b/hw/arm/mps3r.c
51
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@
52
15
#include "qemu/osdep.h"
53
/*
16
#include "qemu/units.h"
54
* We need one splitter for every external combiner input, plus
17
#include "qapi/error.h"
55
- * one for every non-zero entry in combiner_grp_to_gic_id[].
18
+#include "qapi/qmp/qlist.h"
56
+ * one for every non-zero entry in combiner_grp_to_gic_id[],
19
#include "exec/address-spaces.h"
57
+ * minus one for every external combiner ID in second or later
20
#include "cpu.h"
58
+ * places in a combinermap[] line.
21
#include "hw/boards.h"
59
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
22
+#include "hw/qdev-properties.h"
60
*/
23
#include "hw/arm/boot.h"
61
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
24
+#include "hw/arm/bsa.h"
62
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
25
+#include "hw/intc/arm_gicv3.h"
63
26
64
typedef struct Exynos4210Irq {
27
/* Define the layout of RAM and ROM in a board */
65
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
28
typedef struct RAMInfo {
66
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
29
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
67
index XXXXXXX..XXXXXXX 100644
30
#define IS_ROM 2
68
--- a/hw/arm/exynos4210.c
31
69
+++ b/hw/arm/exynos4210.c
32
#define MPS3R_RAM_MAX 9
70
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
33
+#define MPS3R_CPU_MAX 2
71
#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
34
+
72
((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
35
+#define PERIPHBASE 0xf0000000
36
+#define NUM_SPIS 96
37
38
typedef enum MPS3RFPGAType {
39
FPGA_AN536,
40
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineClass {
41
MachineClass parent;
42
MPS3RFPGAType fpga_type;
43
const RAMInfo *raminfo;
44
+ hwaddr loader_start;
45
};
46
47
struct MPS3RMachineState {
48
MachineState parent;
49
+ struct arm_boot_info bootinfo;
50
MemoryRegion ram[MPS3R_RAM_MAX];
51
+ Object *cpu[MPS3R_CPU_MAX];
52
+ MemoryRegion cpu_sysmem[MPS3R_CPU_MAX];
53
+ MemoryRegion sysmem_alias[MPS3R_CPU_MAX];
54
+ MemoryRegion cpu_ram[MPS3R_CPU_MAX];
55
+ GICv3State gic;
56
};
57
58
#define TYPE_MPS3R_MACHINE "mps3r"
59
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
60
return ram;
61
}
73
62
74
+/*
63
+/*
75
+ * Some interrupt lines go to multiple combiner inputs.
64
+ * There is no defined secondary boot protocol for Linux for the AN536,
76
+ * This data structure defines those: each array element is
65
+ * because real hardware has a restriction that atomic operations between
77
+ * a list of combiner inputs which are connected together;
66
+ * the two CPUs do not function correctly, and so true SMP is not
78
+ * the one with the smallest interrupt ID value must be first.
67
+ * possible. Therefore for cases where the user is directly booting
79
+ * As with combiner_grp_to_gic_id[], we rely on (0, 0) not being
68
+ * a kernel, we treat the system as essentially uniprocessor, and
80
+ * wired to anything so we can use 0 as a terminator.
69
+ * put the secondary CPU into power-off state (as if the user on the
70
+ * real hardware had configured the secondary to be halted via the
71
+ * SCC config registers).
72
+ *
73
+ * Note that the default secondary boot code would not work here anyway
74
+ * as it assumes a GICv2, and we have a GICv3.
81
+ */
75
+ */
82
+#define IRQNO(G, B) EXYNOS4210_COMBINER_GET_IRQ_NUM(G, B)
76
+static void mps3r_write_secondary_boot(ARMCPU *cpu,
83
+#define IRQNONE 0
77
+ const struct arm_boot_info *info)
84
+
85
+#define COMBINERMAP_SIZE 16
86
+
87
+static const int combinermap[COMBINERMAP_SIZE][6] = {
88
+ /* MDNIE_LCD1 */
89
+ { IRQNO(0, 4), IRQNO(1, 0), IRQNONE },
90
+ { IRQNO(0, 5), IRQNO(1, 1), IRQNONE },
91
+ { IRQNO(0, 6), IRQNO(1, 2), IRQNONE },
92
+ { IRQNO(0, 7), IRQNO(1, 3), IRQNONE },
93
+ /* TMU */
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
+{
78
+{
114
+ /*
79
+ /*
115
+ * If the interrupt number passed in is the first entry in some
80
+ * Power the secondary CPU off. This means we don't need to write any
116
+ * line of the combinermap, return a pointer to that line;
81
+ * boot code into guest memory. Note that the 'cpu' argument to this
117
+ * otherwise return NULL.
82
+ * function is the primary CPU we passed to arm_load_kernel(), not
83
+ * the secondary. Loop around all the other CPUs, as the boot.c
84
+ * code does for the "disable secondaries if PSCI is enabled" case.
118
+ */
85
+ */
119
+ int i;
86
+ for (CPUState *cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
120
+ for (i = 0; i < COMBINERMAP_SIZE; i++) {
87
+ if (cs != first_cpu) {
121
+ if (combinermap[i][0] == irq) {
88
+ object_property_set_bool(OBJECT(cs), "start-powered-off", true,
122
+ return combinermap[i];
89
+ &error_abort);
123
+ }
90
+ }
124
+ }
91
+ }
125
+ return NULL;
126
+}
92
+}
127
+
93
+
128
+static int mapline_size(const int *mapline)
94
+static void mps3r_secondary_cpu_reset(ARMCPU *cpu,
95
+ const struct arm_boot_info *info)
129
+{
96
+{
130
+ /* Return number of entries in this mapline in total */
97
+ /* We don't need to do anything here because the CPU will be off */
131
+ int i = 0;
98
+}
132
+
99
+
133
+ if (!mapline) {
100
+static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
134
+ /* Not in the map? IRQ goes to exactly one combiner input */
101
+{
135
+ return 1;
102
+ MachineState *machine = MACHINE(mms);
103
+ DeviceState *gicdev;
104
+ QList *redist_region_count;
105
+
106
+ object_initialize_child(OBJECT(mms), "gic", &mms->gic, TYPE_ARM_GICV3);
107
+ gicdev = DEVICE(&mms->gic);
108
+ qdev_prop_set_uint32(gicdev, "num-cpu", machine->smp.cpus);
109
+ qdev_prop_set_uint32(gicdev, "num-irq", NUM_SPIS + GIC_INTERNAL);
110
+ redist_region_count = qlist_new();
111
+ qlist_append_int(redist_region_count, machine->smp.cpus);
112
+ qdev_prop_set_array(gicdev, "redist-region-count", redist_region_count);
113
+ object_property_set_link(OBJECT(&mms->gic), "sysmem",
114
+ OBJECT(sysmem), &error_fatal);
115
+ sysbus_realize(SYS_BUS_DEVICE(&mms->gic), &error_fatal);
116
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->gic), 0, PERIPHBASE);
117
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->gic), 1, PERIPHBASE + 0x100000);
118
+ /*
119
+ * Wire the outputs from each CPU's generic timer and the GICv3
120
+ * maintenance interrupt signal to the appropriate GIC PPI inputs,
121
+ * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
122
+ */
123
+ for (int i = 0; i < machine->smp.cpus; i++) {
124
+ DeviceState *cpudev = DEVICE(mms->cpu[i]);
125
+ SysBusDevice *gicsbd = SYS_BUS_DEVICE(&mms->gic);
126
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
127
+ int irq;
128
+ /*
129
+ * Mapping from the output timer irq lines from the CPU to the
130
+ * GIC PPI inputs used for this board. This isn't a BSA board,
131
+ * but it uses the standard convention for the PPI numbers.
132
+ */
133
+ const int timer_irq[] = {
134
+ [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
135
+ [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
136
+ [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
137
+ };
138
+
139
+ for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
140
+ qdev_connect_gpio_out(cpudev, irq,
141
+ qdev_get_gpio_in(gicdev,
142
+ intidbase + timer_irq[irq]));
143
+ }
144
+
145
+ qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
146
+ qdev_get_gpio_in(gicdev,
147
+ intidbase + ARCH_GIC_MAINT_IRQ));
148
+
149
+ qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
150
+ qdev_get_gpio_in(gicdev,
151
+ intidbase + VIRTUAL_PMU_IRQ));
152
+
153
+ sysbus_connect_irq(gicsbd, i,
154
+ qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
155
+ sysbus_connect_irq(gicsbd, i + machine->smp.cpus,
156
+ qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
157
+ sysbus_connect_irq(gicsbd, i + 2 * machine->smp.cpus,
158
+ qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
159
+ sysbus_connect_irq(gicsbd, i + 3 * machine->smp.cpus,
160
+ qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
136
+ }
161
+ }
137
+ while (*mapline != IRQNONE) {
162
+}
138
+ mapline++;
163
+
139
+ i++;
164
static void mps3r_common_init(MachineState *machine)
165
{
166
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
167
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
168
MemoryRegion *mr = mr_for_raminfo(mms, ri);
169
memory_region_add_subregion(sysmem, ri->base, mr);
170
}
171
+
172
+ assert(machine->smp.cpus <= MPS3R_CPU_MAX);
173
+ for (int i = 0; i < machine->smp.cpus; i++) {
174
+ g_autofree char *sysmem_name = g_strdup_printf("cpu-%d-memory", i);
175
+ g_autofree char *ramname = g_strdup_printf("cpu-%d-memory", i);
176
+ g_autofree char *alias_name = g_strdup_printf("sysmem-alias-%d", i);
177
+
178
+ /*
179
+ * Each CPU has some private RAM/peripherals, so create the container
180
+ * which will house those, with the whole-machine system memory being
181
+ * used where there's no CPU-specific device. Note that we need the
182
+ * sysmem_alias aliases because we can't put one MR (the original
183
+ * 'sysmem') into more than one other MR.
184
+ */
185
+ memory_region_init(&mms->cpu_sysmem[i], OBJECT(machine),
186
+ sysmem_name, UINT64_MAX);
187
+ memory_region_init_alias(&mms->sysmem_alias[i], OBJECT(machine),
188
+ alias_name, sysmem, 0, UINT64_MAX);
189
+ memory_region_add_subregion_overlap(&mms->cpu_sysmem[i], 0,
190
+ &mms->sysmem_alias[i], -1);
191
+
192
+ mms->cpu[i] = object_new(machine->cpu_type);
193
+ object_property_set_link(mms->cpu[i], "memory",
194
+ OBJECT(&mms->cpu_sysmem[i]), &error_abort);
195
+ object_property_set_int(mms->cpu[i], "reset-cbar",
196
+ PERIPHBASE, &error_abort);
197
+ qdev_realize(DEVICE(mms->cpu[i]), NULL, &error_fatal);
198
+ object_unref(mms->cpu[i]);
199
+
200
+ /* Per-CPU RAM */
201
+ memory_region_init_ram(&mms->cpu_ram[i], NULL, ramname,
202
+ 0x1000, &error_fatal);
203
+ memory_region_add_subregion(&mms->cpu_sysmem[i], 0xe7c01000,
204
+ &mms->cpu_ram[i]);
140
+ }
205
+ }
141
+ return i;
206
+
142
+}
207
+ create_gic(mms, sysmem);
143
+
208
+
144
/*
209
+ mms->bootinfo.ram_size = machine->ram_size;
145
* Initialize board IRQs.
210
+ mms->bootinfo.board_id = -1;
146
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
211
+ mms->bootinfo.loader_start = mmc->loader_start;
147
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
212
+ mms->bootinfo.write_secondary_boot = mps3r_write_secondary_boot;
148
DeviceState *extgicdev = DEVICE(&s->ext_gic);
213
+ mms->bootinfo.secondary_cpu_reset_hook = mps3r_secondary_cpu_reset;
149
int splitcount = 0;
214
+ arm_load_kernel(ARM_CPU(mms->cpu[0]), machine, &mms->bootinfo);
150
DeviceState *splitter;
215
}
151
+ const int *mapline;
216
152
+ int numlines, splitin, in;
217
static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
153
218
@@ -XXX,XX +XXX,XX @@ static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
154
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
219
/* Found the entry for "system memory" */
155
irq_id = 0;
220
mc->default_ram_size = p->size;
156
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
221
mc->default_ram_id = p->name;
157
irq_id = EXT_GIC_ID_MCT_G1;
222
+ mmc->loader_start = p->base;
158
}
223
return;
159
160
+ if (s->irq_table[n]) {
161
+ /*
162
+ * This must be some non-first entry in a combinermap line,
163
+ * and we've already filled it in.
164
+ */
165
+ continue;
166
+ }
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
}
224
}
207
}
225
}
208
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
226
@@ -XXX,XX +XXX,XX @@ static void mps3r_an536_class_init(ObjectClass *oc, void *data)
209
irq_id = combiner_grp_to_gic_id[grp -
227
};
210
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
228
211
229
mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
212
+ if (s->irq_table[n]) {
230
- mc->default_cpus = 2;
213
+ /*
231
- mc->min_cpus = mc->default_cpus;
214
+ * This must be some non-first entry in a combinermap line,
232
- mc->max_cpus = mc->default_cpus;
215
+ * and we've already filled it in.
233
+ /*
216
+ */
234
+ * In the real FPGA image there are always two cores, but the standard
217
+ continue;
235
+ * initial setting for the SCC SYSCON 0x000 register is 0x21, meaning
218
+ }
236
+ * that the second core is held in reset and halted. Many images built for
219
+
237
+ * the board do not expect the second core to run at startup (especially
220
if (irq_id) {
238
+ * since on the real FPGA image it is not possible to use LDREX/STREX
221
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
239
+ * in RAM between the two cores, so a true SMP setup isn't supported).
222
splitter = DEVICE(&s->splitter[splitcount]);
240
+ *
223
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
241
+ * As QEMU's equivalent of this, we support both -smp 1 and -smp 2,
224
DeviceState *dev, int ext)
242
+ * with the default being -smp 1. This seems a more intuitive UI for
225
{
243
+ * QEMU users than, for instance, having a machine property to allow
226
int n;
244
+ * the user to set the initial value of the SYSCON 0x000 register.
227
- int bit;
245
+ */
228
int max;
246
+ mc->default_cpus = 1;
229
qemu_irq *irq;
247
+ mc->min_cpus = 1;
230
248
+ mc->max_cpus = 2;
231
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
249
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
232
EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
250
mc->valid_cpu_types = valid_cpu_types;
233
irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
251
mmc->raminfo = an536_raminfo;
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
--
252
--
297
2.25.1
253
2.34.1
diff view generated by jsdifflib
1
The function exynos4210_combiner_get_gpioin() currently lives in
1
This board has a lot of UARTs: there is one UART per CPU in the
2
exynos4210_combiner.c, but it isn't really part of the combiner
2
per-CPU peripheral part of the address map, whose interrupts are
3
device itself -- it is a function that implements the wiring up of
3
connected as per-CPU interrupt lines. Then there are 4 UARTs in the
4
some interrupt sources to multiple combiner inputs. Move it to live
4
normal part of the peripheral space, whose interrupts are shared
5
with the other SoC-level code in exynos4210.c, along with a few
5
peripheral interrupts.
6
macros previously defined in exynos4210.h which are now used only
6
7
in exynos4210.c.
7
Connect and wire them all up; this involves some OR gates where
8
multiple overflow interrupts are wired into one GIC input.
8
9
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
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20220404154658.565020-11-peter.maydell@linaro.org
12
Message-id: 20240206132931.38376-11-peter.maydell@linaro.org
12
---
13
---
13
include/hw/arm/exynos4210.h | 11 -----
14
hw/arm/mps3r.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++
14
hw/arm/exynos4210.c | 82 +++++++++++++++++++++++++++++++++++
15
1 file changed, 94 insertions(+)
15
hw/intc/exynos4210_combiner.c | 77 --------------------------------
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/hw/arm/mps3r.c b/hw/arm/mps3r.c
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/exynos4210.h
19
--- a/hw/arm/mps3r.c
21
+++ b/include/hw/arm/exynos4210.h
20
+++ b/hw/arm/mps3r.c
22
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
23
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
22
#include "qapi/qmp/qlist.h"
24
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
23
#include "exec/address-spaces.h"
25
24
#include "cpu.h"
26
-#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp)*8 + (bit))
25
+#include "sysemu/sysemu.h"
27
-#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
26
#include "hw/boards.h"
28
-#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
27
+#include "hw/or-irq.h"
29
- ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
28
#include "hw/qdev-properties.h"
30
-
29
#include "hw/arm/boot.h"
31
/* IRQs number for external and internal GIC */
30
#include "hw/arm/bsa.h"
32
#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
31
+#include "hw/char/cmsdk-apb-uart.h"
33
#define EXYNOS4210_INT_GIC_NIRQ 64
32
#include "hw/intc/arm_gicv3.h"
34
@@ -XXX,XX +XXX,XX @@ void exynos4210_write_secondary(ARMCPU *cpu,
33
35
* bit - bit number inside group */
34
/* Define the layout of RAM and ROM in a board */
36
uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit);
35
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
37
36
38
-/*
37
#define MPS3R_RAM_MAX 9
39
- * Get Combiner input GPIO into irqs structure
38
#define MPS3R_CPU_MAX 2
40
- */
39
+#define MPS3R_UART_MAX 4 /* shared UART count */
41
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
40
42
- int ext);
41
#define PERIPHBASE 0xf0000000
43
-
42
#define NUM_SPIS 96
44
/*
43
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
45
* exynos4210 UART
44
MemoryRegion sysmem_alias[MPS3R_CPU_MAX];
46
*/
45
MemoryRegion cpu_ram[MPS3R_CPU_MAX];
47
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
46
GICv3State gic;
48
index XXXXXXX..XXXXXXX 100644
47
+ /* per-CPU UARTs followed by the shared UARTs */
49
--- a/hw/arm/exynos4210.c
48
+ CMSDKAPBUART uart[MPS3R_CPU_MAX + MPS3R_UART_MAX];
50
+++ b/hw/arm/exynos4210.c
49
+ OrIRQState cpu_uart_oflow[MPS3R_CPU_MAX];
51
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
50
+ OrIRQState uart_oflow;
52
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
53
};
51
};
54
52
55
+#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp) * 8 + (bit))
53
#define TYPE_MPS3R_MACHINE "mps3r"
56
+#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
54
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
57
+#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
55
58
+ ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
56
OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE)
57
58
+/*
59
+ * Main clock frequency CLK in Hz (50MHz). In the image there are also
60
+ * ACLK, MCLK, GPUCLK and PERIPHCLK at the same frequency; for our
61
+ * model we just roll them all into one.
62
+ */
63
+#define CLK_FRQ 50000000
59
+
64
+
60
/*
65
static const RAMInfo an536_raminfo[] = {
61
* Initialize board IRQs.
66
{
62
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
67
.name = "ATCM",
63
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
68
@@ -XXX,XX +XXX,XX @@ static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
64
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
69
}
65
}
70
}
66
71
67
+/*
72
+/*
68
+ * Get Combiner input GPIO into irqs structure
73
+ * Create UART uartno, and map it into the MemoryRegion mem at address baseaddr.
74
+ * The qemu_irq arguments are where we connect the various IRQs from the UART.
69
+ */
75
+ */
70
+static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
76
+static void create_uart(MPS3RMachineState *mms, int uartno, MemoryRegion *mem,
71
+ DeviceState *dev, int ext)
77
+ hwaddr baseaddr, qemu_irq txirq, qemu_irq rxirq,
78
+ qemu_irq txoverirq, qemu_irq rxoverirq,
79
+ qemu_irq combirq)
72
+{
80
+{
73
+ int n;
81
+ g_autofree char *s = g_strdup_printf("uart%d", uartno);
74
+ int bit;
82
+ SysBusDevice *sbd;
75
+ int max;
76
+ qemu_irq *irq;
77
+
83
+
78
+ max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
84
+ assert(uartno < ARRAY_SIZE(mms->uart));
79
+ EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
85
+ object_initialize_child(OBJECT(mms), s, &mms->uart[uartno],
80
+ irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
86
+ TYPE_CMSDK_APB_UART);
87
+ qdev_prop_set_uint32(DEVICE(&mms->uart[uartno]), "pclk-frq", CLK_FRQ);
88
+ qdev_prop_set_chr(DEVICE(&mms->uart[uartno]), "chardev", serial_hd(uartno));
89
+ sbd = SYS_BUS_DEVICE(&mms->uart[uartno]);
90
+ sysbus_realize(sbd, &error_fatal);
91
+ memory_region_add_subregion(mem, baseaddr,
92
+ sysbus_mmio_get_region(sbd, 0));
93
+ sysbus_connect_irq(sbd, 0, txirq);
94
+ sysbus_connect_irq(sbd, 1, rxirq);
95
+ sysbus_connect_irq(sbd, 2, txoverirq);
96
+ sysbus_connect_irq(sbd, 3, rxoverirq);
97
+ sysbus_connect_irq(sbd, 4, combirq);
98
+}
99
+
100
static void mps3r_common_init(MachineState *machine)
101
{
102
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
103
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
104
MemoryRegion *sysmem = get_system_memory();
105
+ DeviceState *gicdev;
106
107
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
108
MemoryRegion *mr = mr_for_raminfo(mms, ri);
109
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
110
}
111
112
create_gic(mms, sysmem);
113
+ gicdev = DEVICE(&mms->gic);
81
+
114
+
82
+ /*
115
+ /*
83
+ * Some IRQs of Int/External Combiner are going to two Combiners groups,
116
+ * UARTs 0 and 1 are per-CPU; their interrupts are wired to
84
+ * so let split them.
117
+ * the relevant CPU's PPI 0..3, aka INTID 16..19
85
+ */
118
+ */
86
+ for (n = 0; n < max; n++) {
119
+ for (int i = 0; i < machine->smp.cpus; i++) {
120
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
121
+ g_autofree char *s = g_strdup_printf("cpu-uart-oflow-orgate%d", i);
122
+ DeviceState *orgate;
87
+
123
+
88
+ bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
124
+ /* The two overflow IRQs from the UART are ORed together into PPI 3 */
125
+ object_initialize_child(OBJECT(mms), s, &mms->cpu_uart_oflow[i],
126
+ TYPE_OR_IRQ);
127
+ orgate = DEVICE(&mms->cpu_uart_oflow[i]);
128
+ qdev_prop_set_uint32(orgate, "num-lines", 2);
129
+ qdev_realize(orgate, NULL, &error_fatal);
130
+ qdev_connect_gpio_out(orgate, 0,
131
+ qdev_get_gpio_in(gicdev, intidbase + 19));
89
+
132
+
90
+ switch (n) {
133
+ create_uart(mms, i, &mms->cpu_sysmem[i], 0xe7c00000,
91
+ /* MDNIE_LCD1 INTG1 */
134
+ qdev_get_gpio_in(gicdev, intidbase + 17), /* tx */
92
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
135
+ qdev_get_gpio_in(gicdev, intidbase + 16), /* rx */
93
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
136
+ qdev_get_gpio_in(orgate, 0), /* txover */
94
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
137
+ qdev_get_gpio_in(orgate, 1), /* rxover */
95
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
138
+ qdev_get_gpio_in(gicdev, intidbase + 18) /* combined */);
96
+ continue;
139
+ }
140
+ /*
141
+ * UARTs 2 to 5 are whole-system; all overflow IRQs are ORed
142
+ * together into IRQ 17
143
+ */
144
+ object_initialize_child(OBJECT(mms), "uart-oflow-orgate",
145
+ &mms->uart_oflow, TYPE_OR_IRQ);
146
+ qdev_prop_set_uint32(DEVICE(&mms->uart_oflow), "num-lines",
147
+ MPS3R_UART_MAX * 2);
148
+ qdev_realize(DEVICE(&mms->uart_oflow), NULL, &error_fatal);
149
+ qdev_connect_gpio_out(DEVICE(&mms->uart_oflow), 0,
150
+ qdev_get_gpio_in(gicdev, 17));
97
+
151
+
98
+ /* TMU INTG3 */
152
+ for (int i = 0; i < MPS3R_UART_MAX; i++) {
99
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
153
+ hwaddr baseaddr = 0xe0205000 + i * 0x1000;
100
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
154
+ int rxirq = 5 + i * 2, txirq = 6 + i * 2, combirq = 13 + i;
101
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
102
+ continue;
103
+
155
+
104
+ /* LCD1 INTG12 */
156
+ create_uart(mms, i + MPS3R_CPU_MAX, sysmem, baseaddr,
105
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
157
+ qdev_get_gpio_in(gicdev, txirq),
106
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
158
+ qdev_get_gpio_in(gicdev, rxirq),
107
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
159
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2),
108
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
160
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2 + 1),
109
+ continue;
161
+ qdev_get_gpio_in(gicdev, combirq));
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
+ }
162
+ }
142
+}
163
143
+
164
mms->bootinfo.ram_size = machine->ram_size;
144
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
165
mms->bootinfo.board_id = -1;
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
{
235
--
166
--
236
2.25.1
167
2.34.1
168
169
diff view generated by jsdifflib
1
The Exynos4210 SoC device currently uses a custom device
1
Add the GPIO, watchdog, dual-timer and I2C devices to the mps3-an536
2
"exynos4210.irq_gate" to model the OR gate that feeds each CPU's IRQ
2
board. These are all simple devices that just need to be created and
3
line. We have a standard TYPE_OR_IRQ device for this now, so use
3
wired up.
4
that instead.
5
6
(This is a migration compatibility break, but that is OK for this
7
machine type.)
8
4
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20220404154658.565020-2-peter.maydell@linaro.org
7
Message-id: 20240206132931.38376-12-peter.maydell@linaro.org
12
---
8
---
13
include/hw/arm/exynos4210.h | 1 +
9
hw/arm/mps3r.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
14
hw/arm/exynos4210.c | 31 ++++++++++++++++---------------
10
1 file changed, 59 insertions(+)
15
2 files changed, 17 insertions(+), 15 deletions(-)
16
11
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
14
--- a/hw/arm/mps3r.c
20
+++ b/include/hw/arm/exynos4210.h
15
+++ b/hw/arm/mps3r.c
21
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
16
@@ -XXX,XX +XXX,XX @@
22
MemoryRegion bootreg_mem;
17
#include "sysemu/sysemu.h"
23
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
18
#include "hw/boards.h"
24
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
19
#include "hw/or-irq.h"
25
+ qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
20
+#include "hw/qdev-clock.h"
21
#include "hw/qdev-properties.h"
22
#include "hw/arm/boot.h"
23
#include "hw/arm/bsa.h"
24
#include "hw/char/cmsdk-apb-uart.h"
25
+#include "hw/i2c/arm_sbcon_i2c.h"
26
#include "hw/intc/arm_gicv3.h"
27
+#include "hw/misc/unimp.h"
28
+#include "hw/timer/cmsdk-apb-dualtimer.h"
29
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
30
31
/* Define the layout of RAM and ROM in a board */
32
typedef struct RAMInfo {
33
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
34
CMSDKAPBUART uart[MPS3R_CPU_MAX + MPS3R_UART_MAX];
35
OrIRQState cpu_uart_oflow[MPS3R_CPU_MAX];
36
OrIRQState uart_oflow;
37
+ CMSDKAPBWatchdog watchdog;
38
+ CMSDKAPBDualTimer dualtimer;
39
+ ArmSbconI2CState i2c[5];
40
+ Clock *clk;
26
};
41
};
27
42
28
#define TYPE_EXYNOS4210_SOC "exynos4210"
43
#define TYPE_MPS3R_MACHINE "mps3r"
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
44
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
30
index XXXXXXX..XXXXXXX 100644
45
MemoryRegion *sysmem = get_system_memory();
31
--- a/hw/arm/exynos4210.c
46
DeviceState *gicdev;
32
+++ b/hw/arm/exynos4210.c
47
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
48
+ mms->clk = clock_new(OBJECT(machine), "CLK");
34
{
49
+ clock_set_hz(mms->clk, CLK_FRQ);
35
Exynos4210State *s = EXYNOS4210_SOC(socdev);
50
+
36
MemoryRegion *system_mem = get_system_memory();
51
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
37
- qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
52
MemoryRegion *mr = mr_for_raminfo(mms, ri);
38
SysBusDevice *busdev;
53
memory_region_add_subregion(sysmem, ri->base, mr);
39
DeviceState *dev, *uart[4], *pl330[3];
54
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
40
int i, n;
55
qdev_get_gpio_in(gicdev, combirq));
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
}
56
}
65
57
66
/* Private memory region and Internal GIC */
58
+ for (int i = 0; i < 4; i++) {
67
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
59
+ /* CMSDK GPIO controllers */
68
sysbus_realize_and_unref(busdev, &error_fatal);
60
+ g_autofree char *s = g_strdup_printf("gpio%d", i);
69
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
61
+ create_unimplemented_device(s, 0xe0000000 + i * 0x1000, 0x1000);
70
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
62
+ }
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
+
63
+
92
+ for (i = 0; i < ARRAY_SIZE(s->cpu_irq_orgate); i++) {
64
+ object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
93
+ g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
65
+ TYPE_CMSDK_APB_WATCHDOG);
94
+ object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
66
+ qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->clk);
67
+ sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
68
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
69
+ qdev_get_gpio_in(gicdev, 0));
70
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->watchdog), 0, 0xe0100000);
71
+
72
+ object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
73
+ TYPE_CMSDK_APB_DUALTIMER);
74
+ qdev_connect_clock_in(DEVICE(&mms->dualtimer), "TIMCLK", mms->clk);
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
76
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
77
+ qdev_get_gpio_in(gicdev, 3));
78
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 1,
79
+ qdev_get_gpio_in(gicdev, 1));
80
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 2,
81
+ qdev_get_gpio_in(gicdev, 2));
82
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0xe0101000);
83
+
84
+ for (int i = 0; i < ARRAY_SIZE(mms->i2c); i++) {
85
+ static const hwaddr i2cbase[] = {0xe0102000, /* Touch */
86
+ 0xe0103000, /* Audio */
87
+ 0xe0107000, /* Shield0 */
88
+ 0xe0108000, /* Shield1 */
89
+ 0xe0109000}; /* DDR4 EEPROM */
90
+ g_autofree char *s = g_strdup_printf("i2c%d", i);
91
+
92
+ object_initialize_child(OBJECT(mms), s, &mms->i2c[i],
93
+ TYPE_ARM_SBCON_I2C);
94
+ sysbus_realize(SYS_BUS_DEVICE(&mms->i2c[i]), &error_fatal);
95
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->i2c[i]), 0, i2cbase[i]);
96
+ if (i != 2 && i != 3) {
97
+ /*
98
+ * internal-only bus: mark it full to avoid user-created
99
+ * i2c devices being plugged into it.
100
+ */
101
+ qbus_mark_full(qdev_get_child_bus(DEVICE(&mms->i2c[i]), "i2c"));
102
+ }
95
+ }
103
+ }
96
}
104
+
97
105
mms->bootinfo.ram_size = machine->ram_size;
98
static void exynos4210_class_init(ObjectClass *klass, void *data)
106
mms->bootinfo.board_id = -1;
107
mms->bootinfo.loader_start = mmc->loader_start;
99
--
108
--
100
2.25.1
109
2.34.1
110
111
diff view generated by jsdifflib
1
In exynos4210_init_board_irqs(), use the TYPE_SPLIT_IRQ device
1
Add the remaining devices (or unimplemented-device stubs) for
2
instead of qemu_irq_split().
2
this board: SPI controllers, SCC, FPGAIO, I2S, RTC, the
3
QSPI write-config block, and ethernet.
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20220404154658.565020-13-peter.maydell@linaro.org
7
Message-id: 20240206132931.38376-13-peter.maydell@linaro.org
7
---
8
---
8
include/hw/arm/exynos4210.h | 9 ++++++++
9
hw/arm/mps3r.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++
9
hw/arm/exynos4210.c | 41 +++++++++++++++++++++++++++++--------
10
1 file changed, 74 insertions(+)
10
2 files changed, 42 insertions(+), 8 deletions(-)
11
11
12
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/exynos4210.h
14
--- a/hw/arm/mps3r.c
15
+++ b/include/hw/arm/exynos4210.h
15
+++ b/hw/arm/mps3r.c
16
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
17
#include "hw/sysbus.h"
17
#include "hw/char/cmsdk-apb-uart.h"
18
#include "hw/cpu/a9mpcore.h"
18
#include "hw/i2c/arm_sbcon_i2c.h"
19
#include "hw/intc/exynos4210_gic.h"
19
#include "hw/intc/arm_gicv3.h"
20
+#include "hw/core/split-irq.h"
20
+#include "hw/misc/mps2-scc.h"
21
#include "target/arm/cpu-qom.h"
21
+#include "hw/misc/mps2-fpgaio.h"
22
#include "qom/object.h"
22
#include "hw/misc/unimp.h"
23
23
+#include "hw/net/lan9118.h"
24
@@ -XXX,XX +XXX,XX @@
24
+#include "hw/rtc/pl031.h"
25
25
+#include "hw/ssi/pl022.h"
26
#define EXYNOS4210_NUM_DMA 3
26
#include "hw/timer/cmsdk-apb-dualtimer.h"
27
27
#include "hw/watchdog/cmsdk-apb-watchdog.h"
28
+/*
28
29
+ * We need one splitter for every external combiner input, plus
29
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
30
+ * one for every non-zero entry in combiner_grp_to_gic_id[].
30
CMSDKAPBWatchdog watchdog;
31
+ * We'll assert in exynos4210_init_board_irqs() if this is wrong.
31
CMSDKAPBDualTimer dualtimer;
32
+ */
32
ArmSbconI2CState i2c[5];
33
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
33
+ PL022State spi[3];
34
+ MPS2SCC scc;
35
+ MPS2FPGAIO fpgaio;
36
+ UnimplementedDeviceState i2s_audio;
37
+ PL031State rtc;
38
Clock *clk;
39
};
40
41
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an536_raminfo[] = {
42
}
43
};
44
45
+static const int an536_oscclk[] = {
46
+ 24000000, /* 24MHz reference for RTC and timers */
47
+ 50000000, /* 50MHz ACLK */
48
+ 50000000, /* 50MHz MCLK */
49
+ 50000000, /* 50MHz GPUCLK */
50
+ 24576000, /* 24.576MHz AUDCLK */
51
+ 23750000, /* 23.75MHz HDLCDCLK */
52
+ 100000000, /* 100MHz DDR4_REF_CLK */
53
+};
34
+
54
+
35
typedef struct Exynos4210Irq {
55
static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
36
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
56
const RAMInfo *raminfo)
37
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
57
{
38
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
58
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
39
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
59
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
40
A9MPPrivState a9mpcore;
60
MemoryRegion *sysmem = get_system_memory();
41
Exynos4210GicState ext_gic;
61
DeviceState *gicdev;
42
+ SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
62
+ QList *oscclk;
43
};
63
44
64
mms->clk = clock_new(OBJECT(machine), "CLK");
45
#define TYPE_EXYNOS4210_SOC "exynos4210"
65
clock_set_hz(mms->clk, CLK_FRQ);
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
66
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
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
}
67
}
82
}
68
}
83
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
69
84
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
70
+ for (int i = 0; i < ARRAY_SIZE(mms->spi); i++) {
85
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
71
+ g_autofree char *s = g_strdup_printf("spi%d", i);
86
72
+ hwaddr baseaddr = 0xe0104000 + i * 0x1000;
87
if (irq_id) {
73
+
88
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
74
+ object_initialize_child(OBJECT(mms), s, &mms->spi[i], TYPE_PL022);
89
- qdev_get_gpio_in(extgicdev,
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->spi[i]), &error_fatal);
90
- irq_id - 32));
76
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->spi[i]), 0, baseaddr);
91
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
77
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->spi[i]), 0,
92
+ splitter = DEVICE(&s->splitter[splitcount]);
78
+ qdev_get_gpio_in(gicdev, 22 + i));
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
+ }
79
+ }
119
+
80
+
120
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
81
+ object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
121
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
82
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg0", 0);
122
}
83
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg4", 0x2);
84
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-aid", 0x00200008);
85
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-id", 0x41055360);
86
+ oscclk = qlist_new();
87
+ for (int i = 0; i < ARRAY_SIZE(an536_oscclk); i++) {
88
+ qlist_append_int(oscclk, an536_oscclk[i]);
89
+ }
90
+ qdev_prop_set_array(DEVICE(&mms->scc), "oscclk", oscclk);
91
+ sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
92
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->scc), 0, 0xe0200000);
93
+
94
+ create_unimplemented_device("i2s-audio", 0xe0201000, 0x1000);
95
+
96
+ object_initialize_child(OBJECT(mms), "fpgaio", &mms->fpgaio,
97
+ TYPE_MPS2_FPGAIO);
98
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", an536_oscclk[1]);
99
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "num-leds", 10);
100
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-switches", true);
101
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-dbgctrl", false);
102
+ sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
103
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0xe0202000);
104
+
105
+ create_unimplemented_device("clcd", 0xe0209000, 0x1000);
106
+
107
+ object_initialize_child(OBJECT(mms), "rtc", &mms->rtc, TYPE_PL031);
108
+ sysbus_realize(SYS_BUS_DEVICE(&mms->rtc), &error_fatal);
109
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->rtc), 0, 0xe020a000);
110
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->rtc), 0,
111
+ qdev_get_gpio_in(gicdev, 4));
112
+
113
+ /*
114
+ * In hardware this is a LAN9220; the LAN9118 is software compatible
115
+ * except that it doesn't support the checksum-offload feature.
116
+ */
117
+ lan9118_init(0xe0300000,
118
+ qdev_get_gpio_in(gicdev, 18));
119
+
120
+ create_unimplemented_device("usb", 0xe0301000, 0x1000);
121
+ create_unimplemented_device("qspi-write-config", 0xe0600000, 0x1000);
122
+
123
mms->bootinfo.ram_size = machine->ram_size;
124
mms->bootinfo.board_id = -1;
125
mms->bootinfo.loader_start = mmc->loader_start;
123
--
126
--
124
2.25.1
127
2.34.1
128
129
diff view generated by jsdifflib
1
The only time we use the int_gic_irq[] array in the Exynos4210Irq
1
Add documentation for the mps3-an536 board type.
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
2
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20220404154658.565020-5-peter.maydell@linaro.org
5
Message-id: 20240206132931.38376-14-peter.maydell@linaro.org
12
---
6
---
13
include/hw/arm/exynos4210.h | 1 -
7
docs/system/arm/mps2.rst | 37 ++++++++++++++++++++++++++++++++++---
14
hw/arm/exynos4210.c | 6 ++----
8
1 file changed, 34 insertions(+), 3 deletions(-)
15
2 files changed, 2 insertions(+), 5 deletions(-)
16
9
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
10
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
18
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
12
--- a/docs/system/arm/mps2.rst
20
+++ b/include/hw/arm/exynos4210.h
13
+++ b/docs/system/arm/mps2.rst
21
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@
22
typedef struct Exynos4210Irq {
15
-Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
16
-=========================================================================================================================================================
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
17
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an536``, ``mps3-an547``)
25
- qemu_irq int_gic_irq[EXYNOS4210_INT_GIC_NIRQ];
18
+=========================================================================================================================================================================
26
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
19
27
qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
20
-These board models all use Arm M-profile CPUs.
28
} Exynos4210Irq;
21
+These board models use Arm M-profile or R-profile CPUs.
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
22
30
index XXXXXXX..XXXXXXX 100644
23
The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
31
--- a/hw/arm/exynos4210.c
24
bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
32
+++ b/hw/arm/exynos4210.c
25
@@ -XXX,XX +XXX,XX @@ FPGA image.
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
26
34
sysbus_connect_irq(busdev, n,
27
QEMU models the following FPGA images:
35
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
28
36
}
29
+FPGA images using M-profile CPUs:
37
- for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
30
+
38
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
31
``mps2-an385``
39
- }
32
Cortex-M3 as documented in Arm Application Note AN385
40
33
``mps2-an386``
41
/* Cache controller */
34
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
42
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
35
``mps3-an547``
43
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
36
Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
44
busdev = SYS_BUS_DEVICE(dev);
37
45
sysbus_realize_and_unref(busdev, &error_fatal);
38
+FPGA images using R-profile CPUs:
46
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
39
+
47
- sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
40
+``mps3-an536``
48
+ sysbus_connect_irq(busdev, n,
41
+ Dual Cortex-R52 on an MPS3, as documented in Arm Application Note AN536
49
+ qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
42
+
50
}
43
Differences between QEMU and real hardware:
51
exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
44
52
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
45
- AN385/AN386 remapping of low 16K of memory to either ZBT SSRAM1 or to
46
@@ -XXX,XX +XXX,XX @@ Differences between QEMU and real hardware:
47
flash, but only as simple ROM, so attempting to rewrite the flash
48
from the guest will fail
49
- QEMU does not model the USB controller in MPS3 boards
50
+- AN536 does not support runtime control of CPU reset and halt via
51
+ the SCC CFG_REG0 register.
52
+- AN536 does not support enabling or disabling the flash and ATCM
53
+ interfaces via the SCC CFG_REG1 register.
54
+- AN536 does not support setting of the initial vector table
55
+ base address via the SCC CFG_REG6 and CFG_REG7 register config,
56
+ and does not provide a mechanism for specifying these values at
57
+ startup, so all guest images must be built to start from TCM
58
+ (i.e. to expect the interrupt vector base at 0 from reset).
59
+- AN536 defaults to only creating a single CPU; this is the equivalent
60
+ of the way the real FPGA image usually runs with the second Cortex-R52
61
+ held in halt via the initial SCC CFG_REG0 register setting. You can
62
+ create the second CPU with ``-smp 2``; both CPUs will then start
63
+ execution immediately on startup.
64
+
65
+Note that for the AN536 the first UART is accessible only by
66
+CPU0, and the second UART is accessible only by CPU1. The
67
+first UART accessible shared between both CPUs is the third
68
+UART. Guest software might therefore be built to use either
69
+the first UART or the third UART; if you don't see any output
70
+from the UART you are looking at, try one of the others.
71
+(Even if the AN536 machine is started with a single CPU and so
72
+no "CPU1-only UART", the UART numbering remains the same,
73
+with the third UART being the first of the shared ones.)
74
75
Machine-specific options
76
""""""""""""""""""""""""
53
--
77
--
54
2.25.1
78
2.34.1
79
80
diff view generated by jsdifflib