1
First arm pullreq for 7.1. The bulk of this is the qemu_split_irq
1
Here's another arm pullreq; nothing too exciting in here I think.
2
removal.
3
4
I have enough stuff in my to-review queue that I expect to do another
5
pullreq early next week, but 31 patches is enough to not hang on to.
6
2
7
thanks
3
thanks
8
-- PMM
4
-- PMM
9
5
10
The following changes since commit 9c125d17e9402c232c46610802e5931b3639d77b:
6
The following changes since commit 5fee33d97a7f2e95716417bd164f2f5264acd976:
11
7
12
Merge tag 'pull-tcg-20220420' of https://gitlab.com/rth7680/qemu into staging (2022-04-20 16:43:11 -0700)
8
Merge tag 'samuel-thibault' of https://people.debian.org/~sthibault/qemu into staging (2024-04-29 14:34:25 -0700)
13
9
14
are available in the Git repository at:
10
are available in the Git repository at:
15
11
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220421
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240430
17
13
18
for you to fetch changes up to 5b415dd61bdbf61fb4be0e9f1a7172b8bce682c6:
14
for you to fetch changes up to a0c325c4b05cf7815739d6a84e567b95c8c5be7e:
19
15
20
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs (2022-04-21 11:37:05 +0100)
16
tests/qtest : Add testcase for DM163 (2024-04-30 16:05:08 +0100)
21
17
22
----------------------------------------------------------------
18
----------------------------------------------------------------
23
target-arm queue:
19
target-arm queue:
24
* hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
20
* hw/core/clock: allow clock_propagate on child clocks
25
* versal: Add the Cortex-R5s in the Real-Time Processing Unit (RPU) subsystem
21
* hvf: arm: Remove unused PL1_WRITE_MASK define
26
* versal: model enough of the Clock/Reset Low-power domain (CRL) to allow control of the Cortex-R5s
22
* target/arm: Restrict translation disabled alignment check to VMSA
27
* xlnx-zynqmp: Connect 4 TTC timers
23
* docs/system/arm/emulation.rst: Add missing implemented features
28
* exynos4210: Refactor GIC/combiner code to stop using qemu_split_irq
24
* target/arm: Enable FEAT_CSV2_3, FEAT_ETS2, FEAT_Spec_FPACC for 'max'
29
* realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
25
* tests/avocado: update sunxi kernel from armbian to 6.6.16
30
* stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
26
* target/arm: Make new CPUs default to 1GHz generic timer
31
* hw/core/irq: remove unused 'qemu_irq_split' function
27
* hw/dmax/xlnx_dpdma: fix handling of address_extension descriptor fields
32
* npcm7xx: use symbolic constants for PWRON STRAP bit fields
28
* hw/char/stm32l4x5_usart: Fix memory corruption by adding correct class_size
33
* virt: document impact of gic-version on max CPUs
29
* hw/arm/npcm7xx: Store derivative OTP fuse key in little endian
30
* hw/arm: Add DM163 display to B-L475E-IOT01A board
34
31
35
----------------------------------------------------------------
32
----------------------------------------------------------------
36
Edgar E. Iglesias (6):
33
Alexandra Diupina (1):
37
timer: cadence_ttc: Break out header file to allow embedding
34
hw/dmax/xlnx_dpdma: fix handling of address_extension descriptor fields
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
35
44
Hao Wu (2):
36
Inès Varhol (5):
45
hw/misc: Add PWRON STRAP bit fields in GCR module
37
hw/display : Add device DM163
46
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs
38
hw/arm : Pass STM32L4x5 SYSCFG gpios to STM32L4x5 SoC
39
hw/arm : Create Bl475eMachineState
40
hw/arm : Connect DM163 to B-L475E-IOT01A
41
tests/qtest : Add testcase for DM163
47
42
48
Heinrich Schuchardt (1):
43
Peter Maydell (10):
49
hw/arm/virt: impact of gic-version on max CPUs
44
docs/system/arm/emulation.rst: Add missing implemented features
45
target/arm: Enable FEAT_CSV2_3 for -cpu max
46
target/arm: Enable FEAT_ETS2 for -cpu max
47
target/arm: Implement ID_AA64MMFR3_EL1
48
target/arm: Enable FEAT_Spec_FPACC for -cpu max
49
tests/avocado: update sunxi kernel from armbian to 6.6.16
50
target/arm: Refactor default generic timer frequency handling
51
hw/arm/sbsa-ref: Force CPU generic timer to 62.5MHz
52
hw/watchdog/sbsa_gwdt: Make watchdog timer frequency a QOM property
53
target/arm: Default to 1GHz cntfrq for 'max' and new CPUs
50
54
51
Peter Maydell (19):
55
Philippe Mathieu-Daudé (1):
52
hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
56
hw/arm/npcm7xx: Store derivative OTP fuse key in little endian
53
hw/arm/exynos4210: Use TYPE_OR_IRQ instead of custom OR-gate device
54
hw/intc/exynos4210_gic: Remove unused TYPE_EXYNOS4210_IRQ_GATE
55
hw/arm/exynos4210: Put a9mpcore device into state struct
56
hw/arm/exynos4210: Drop int_gic_irq[] from Exynos4210Irq struct
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
57
72
Zongyuan Li (3):
58
Raphael Poggi (1):
73
hw/arm/realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
59
hw/core/clock: allow clock_propagate on child clocks
74
hw/arm/stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
75
hw/core/irq: remove unused 'qemu_irq_split' function
76
60
77
docs/system/arm/virt.rst | 4 +-
61
Richard Henderson (1):
78
include/hw/arm/exynos4210.h | 50 ++--
62
target/arm: Restrict translation disabled alignment check to VMSA
79
include/hw/arm/xlnx-versal.h | 16 ++
63
80
include/hw/arm/xlnx-zynqmp.h | 4 +
64
Thomas Huth (1):
81
include/hw/intc/exynos4210_combiner.h | 57 +++++
65
hw/char/stm32l4x5_usart: Fix memory corruption by adding correct class_size
82
include/hw/intc/exynos4210_gic.h | 43 ++++
66
83
include/hw/irq.h | 5 -
67
Zenghui Yu (1):
84
include/hw/misc/npcm7xx_gcr.h | 30 +++
68
hvf: arm: Remove PL1_WRITE_MASK
85
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++++
69
86
include/hw/timer/cadence_ttc.h | 54 +++++
70
docs/system/arm/b-l475e-iot01a.rst | 3 +-
87
hw/arm/exynos4210.c | 430 ++++++++++++++++++++++++++++++----
71
docs/system/arm/emulation.rst | 42 ++++-
88
hw/arm/npcm7xx_boards.c | 24 +-
72
include/hw/display/dm163.h | 59 ++++++
89
hw/arm/realview.c | 33 ++-
73
include/hw/watchdog/sbsa_gwdt.h | 3 +-
90
hw/arm/stellaris.c | 15 +-
74
target/arm/cpu.h | 28 +++
91
hw/arm/virt.c | 7 +
75
target/arm/internals.h | 15 +-
92
hw/arm/xlnx-versal-virt.c | 6 +-
76
hw/arm/b-l475e-iot01a.c | 105 +++++++++--
93
hw/arm/xlnx-versal.c | 99 +++++++-
77
hw/arm/npcm7xx.c | 3 +-
94
hw/arm/xlnx-zynqmp.c | 22 ++
78
hw/arm/sbsa-ref.c | 16 ++
95
hw/core/irq.c | 15 --
79
hw/arm/stm32l4x5_soc.c | 6 +-
96
hw/intc/exynos4210_combiner.c | 108 +--------
80
hw/char/stm32l4x5_usart.c | 1 +
97
hw/intc/exynos4210_gic.c | 344 +--------------------------
81
hw/core/clock.c | 1 -
98
hw/misc/xlnx-versal-crl.c | 421 +++++++++++++++++++++++++++++++++
82
hw/core/machine.c | 4 +-
99
hw/timer/cadence_ttc.c | 32 +--
83
hw/display/dm163.c | 349 ++++++++++++++++++++++++++++++++++++
100
MAINTAINERS | 2 +-
84
hw/dma/xlnx_dpdma.c | 20 +--
101
hw/misc/meson.build | 1 +
85
hw/watchdog/sbsa_gwdt.c | 15 +-
102
25 files changed, 1457 insertions(+), 600 deletions(-)
86
target/arm/cpu.c | 42 +++--
103
create mode 100644 include/hw/intc/exynos4210_combiner.h
87
target/arm/cpu64.c | 2 +
104
create mode 100644 include/hw/intc/exynos4210_gic.h
88
target/arm/helper.c | 22 +--
105
create mode 100644 include/hw/misc/xlnx-versal-crl.h
89
target/arm/hvf/hvf.c | 3 +-
106
create mode 100644 include/hw/timer/cadence_ttc.h
90
target/arm/kvm.c | 2 +
107
create mode 100644 hw/misc/xlnx-versal-crl.c
91
target/arm/tcg/cpu32.c | 6 +-
92
target/arm/tcg/cpu64.c | 28 ++-
93
target/arm/tcg/hflags.c | 12 +-
94
tests/qtest/dm163-test.c | 194 ++++++++++++++++++++
95
tests/qtest/stm32l4x5_gpio-test.c | 13 +-
96
tests/qtest/stm32l4x5_syscfg-test.c | 17 +-
97
hw/arm/Kconfig | 1 +
98
hw/display/Kconfig | 3 +
99
hw/display/meson.build | 1 +
100
hw/display/trace-events | 14 ++
101
tests/avocado/boot_linux_console.py | 70 ++++----
102
tests/avocado/replay_kernel.py | 8 +-
103
tests/qtest/meson.build | 2 +
104
34 files changed, 987 insertions(+), 123 deletions(-)
105
create mode 100644 include/hw/display/dm163.h
106
create mode 100644 hw/display/dm163.c
107
create mode 100644 tests/qtest/dm163-test.c
108
diff view generated by jsdifflib
1
From: Zongyuan Li <zongyuan.li@smartx.com>
1
From: Raphael Poggi <raphael.poggi@lynxleap.co.uk>
2
2
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
3
clock_propagate() has an assert that clk->source is NULL, i.e. that
4
you are calling it on a clock which has no source clock. This made
5
sense in the original design where the only way for a clock's
6
frequency to change if it had a source clock was when that source
7
clock changed. However, we subsequently added multiplier/divider
8
support, but didn't look at what that meant for propagation.
9
10
If a clock-management device changes the multiplier or divider value
11
on a clock, it needs to propagate that change down to child clocks,
12
even if the clock has a source clock set. So the assertion is now
13
incorrect.
14
15
Remove the assertion.
16
17
Signed-off-by: Raphael Poggi <raphael.poggi@lynxleap.co.uk>
18
Message-id: 20240419162951.23558-1-raphael.poggi@lynxleap.co.uk
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-5-zongyuan.li@smartx.com
20
[PMM: Rewrote the commit message]
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/811
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
22
---
9
include/hw/irq.h | 5 -----
23
hw/core/clock.c | 1 -
10
hw/core/irq.c | 15 ---------------
24
1 file changed, 1 deletion(-)
11
2 files changed, 20 deletions(-)
12
25
13
diff --git a/include/hw/irq.h b/include/hw/irq.h
26
diff --git a/hw/core/clock.c b/hw/core/clock.c
14
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/irq.h
28
--- a/hw/core/clock.c
16
+++ b/include/hw/irq.h
29
+++ b/hw/core/clock.c
17
@@ -XXX,XX +XXX,XX @@ void qemu_free_irq(qemu_irq irq);
30
@@ -XXX,XX +XXX,XX @@ static void clock_propagate_period(Clock *clk, bool call_callbacks)
18
/* Returns a new IRQ with opposite polarity. */
31
19
qemu_irq qemu_irq_invert(qemu_irq irq);
32
void clock_propagate(Clock *clk)
20
33
{
21
-/* Returns a new IRQ which feeds into both the passed IRQs.
34
- assert(clk->source == NULL);
22
- * It's probably better to use the TYPE_SPLIT_IRQ device instead.
35
trace_clock_propagate(CLOCK_PATH(clk));
23
- */
36
clock_propagate_period(clk, true);
24
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
25
-
26
/* For internal use in qtest. Similar to qemu_irq_split, but operating
27
on an existing vector of qemu_irq. */
28
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
29
diff --git a/hw/core/irq.c b/hw/core/irq.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/core/irq.c
32
+++ b/hw/core/irq.c
33
@@ -XXX,XX +XXX,XX @@ qemu_irq qemu_irq_invert(qemu_irq irq)
34
return qemu_allocate_irq(qemu_notirq, irq, 0);
35
}
37
}
36
37
-static void qemu_splitirq(void *opaque, int line, int level)
38
-{
39
- struct IRQState **irq = opaque;
40
- irq[0]->handler(irq[0]->opaque, irq[0]->n, level);
41
- irq[1]->handler(irq[1]->opaque, irq[1]->n, level);
42
-}
43
-
44
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2)
45
-{
46
- qemu_irq *s = g_new0(qemu_irq, 2);
47
- s[0] = irq1;
48
- s[1] = irq2;
49
- return qemu_allocate_irq(qemu_splitirq, s, 0);
50
-}
51
-
52
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
53
{
54
int i;
55
--
38
--
56
2.25.1
39
2.34.1
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Zenghui Yu <zenghui.yu@linux.dev>
2
2
3
This patch uses the defined fields to describe PWRON STRAPs for
3
As it had never been used since the first commit a1477da3ddeb ("hvf: Add
4
better readability.
4
Apple Silicon support").
5
5
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
6
Signed-off-by: Zenghui Yu <zenghui.yu@linux.dev>
7
Reviewed-by: Patrick Venture <venture@google.com>
7
Message-id: 20240422092715.71973-1-zenghui.yu@linux.dev
8
Message-id: 20220411165842.3912945-3-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
hw/arm/npcm7xx_boards.c | 24 +++++++++++++++++++-----
11
target/arm/hvf/hvf.c | 1 -
13
1 file changed, 19 insertions(+), 5 deletions(-)
12
1 file changed, 1 deletion(-)
14
13
15
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
14
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/npcm7xx_boards.c
16
--- a/target/arm/hvf/hvf.c
18
+++ b/hw/arm/npcm7xx_boards.c
17
+++ b/target/arm/hvf/hvf.c
19
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ void hvf_arm_init_debug(void)
20
#include "sysemu/sysemu.h"
19
21
#include "sysemu/block-backend.h"
20
#define HVF_SYSREG(crn, crm, op0, op1, op2) \
22
21
ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP, crn, crm, op0, op1, op2)
23
-#define NPCM750_EVB_POWER_ON_STRAPS 0x00001ff7
22
-#define PL1_WRITE_MASK 0x4
24
-#define QUANTA_GSJ_POWER_ON_STRAPS 0x00001fff
23
25
-#define QUANTA_GBS_POWER_ON_STRAPS 0x000017ff
24
#define SYSREG_OP0_SHIFT 20
26
-#define KUDO_BMC_POWER_ON_STRAPS 0x00001fff
25
#define SYSREG_OP0_MASK 0x3
27
-#define MORI_BMC_POWER_ON_STRAPS 0x00001fff
28
+#define NPCM7XX_POWER_ON_STRAPS_DEFAULT ( \
29
+ NPCM7XX_PWRON_STRAP_SPI0F18 | \
30
+ NPCM7XX_PWRON_STRAP_SFAB | \
31
+ NPCM7XX_PWRON_STRAP_BSPA | \
32
+ NPCM7XX_PWRON_STRAP_FUP(FUP_NORM_UART2) | \
33
+ NPCM7XX_PWRON_STRAP_SECEN | \
34
+ NPCM7XX_PWRON_STRAP_HIZ | \
35
+ NPCM7XX_PWRON_STRAP_ECC | \
36
+ NPCM7XX_PWRON_STRAP_RESERVE1 | \
37
+ NPCM7XX_PWRON_STRAP_J2EN | \
38
+ NPCM7XX_PWRON_STRAP_CKFRQ(CKFRQ_DEFAULT))
39
+
40
+#define NPCM750_EVB_POWER_ON_STRAPS ( \
41
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_J2EN)
42
+#define QUANTA_GSJ_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
43
+#define QUANTA_GBS_POWER_ON_STRAPS ( \
44
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_SFAB)
45
+#define KUDO_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
46
+#define MORI_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
47
48
static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
49
50
--
26
--
51
2.25.1
27
2.34.1
diff view generated by jsdifflib
1
It's not possible to provide the guest with the Security extensions
1
From: Richard Henderson <richard.henderson@linaro.org>
2
(TrustZone) when using KVM or HVF, because the hardware
3
virtualization extensions don't permit running EL3 guest code.
4
However, we weren't checking for this combination, with the result
5
that QEMU would assert if you tried it:
6
2
7
$ qemu-system-aarch64 -enable-kvm -machine virt,secure=on -cpu host -display none
3
For cpus using PMSA, when the MPU is disabled, the default memory
8
Unexpected error in object_property_find_err() at ../../qom/object.c:1304:
4
type is Normal, Non-cachable. This means that it should not
9
qemu-system-aarch64: Property 'host-arm-cpu.secure-memory' not found
5
have alignment restrictions enforced.
10
Aborted
11
6
12
Check for this combination of options and report an error, in the
7
Cc: qemu-stable@nongnu.org
13
same way we already do for attempts to give a KVM or HVF guest the
8
Fixes: 59754f85ed3 ("target/arm: Do memory type alignment check when translation disabled")
14
Virtualization or MTE extensions. Now we will report:
9
Reported-by: Clément Chigot <chigot@adacore.com>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Tested-by: Clément Chigot <chigot@adacore.com>
13
Message-id: 20240422170722.117409-1-richard.henderson@linaro.org
14
[PMM: trivial comment, commit message tweaks]
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/tcg/hflags.c | 12 ++++++++++--
18
1 file changed, 10 insertions(+), 2 deletions(-)
15
19
16
qemu-system-aarch64: mach-virt: KVM does not support providing Security extensions (TrustZone) to the guest CPU
20
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
17
18
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/961
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 20220404155301.566542-1-peter.maydell@linaro.org
22
---
23
hw/arm/virt.c | 7 +++++++
24
1 file changed, 7 insertions(+)
25
26
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
27
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/virt.c
22
--- a/target/arm/tcg/hflags.c
29
+++ b/hw/arm/virt.c
23
+++ b/target/arm/tcg/hflags.c
30
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
24
@@ -XXX,XX +XXX,XX @@ static bool aprofile_require_alignment(CPUARMState *env, int el, uint64_t sctlr)
31
exit(1);
32
}
25
}
33
26
34
+ if (vms->secure && (kvm_enabled() || hvf_enabled())) {
27
/*
35
+ error_report("mach-virt: %s does not support providing "
28
- * If translation is disabled, then the default memory type is
36
+ "Security extensions (TrustZone) to the guest CPU",
29
- * Device(-nGnRnE) instead of Normal, which requires that alignment
37
+ kvm_enabled() ? "KVM" : "HVF");
30
+ * With PMSA, when the MPU is disabled, all memory types in the
38
+ exit(1);
31
+ * default map are Normal, so don't need aligment enforcing.
32
+ */
33
+ if (arm_feature(env, ARM_FEATURE_PMSA)) {
34
+ return false;
39
+ }
35
+ }
40
+
36
+
41
if (vms->virt && (kvm_enabled() || hvf_enabled())) {
37
+ /*
42
error_report("mach-virt: %s does not support providing "
38
+ * With VMSA, if translation is disabled, then the default memory type
43
"Virtualization extensions to the guest CPU",
39
+ * is Device(-nGnRnE) instead of Normal, which requires that alignment
40
* be enforced. Since this affects all ram, it is most efficient
41
* to handle this during translation.
42
*/
44
--
43
--
45
2.25.1
44
2.34.1
45
46
diff view generated by jsdifflib
1
The only time we use the int_combiner_irq[] and ext_combiner_irq[]
1
As of version DDI0487K.a of the Arm ARM, some architectural features
2
arrays in the Exynos4210Irq struct is during realize of the SoC -- we
2
which previously didn't have official names have been named. Add
3
initialize them with the input IRQs of the combiner devices, and then
3
these to the list of features which QEMU's TCG emulation supports.
4
connect those to outputs of other devices in
4
Mostly these are features which we thought of as part of baseline 8.0
5
exynos4210_init_board_irqs(). Now that the combiner objects are
5
support. For SVE and SVE2, the names have been brought into line
6
easily accessible as s->int_combiner and s->ext_combiner we can make
6
with the FEAT_* naming convention of other extensions, and some
7
the connections directly from one device to the other without going
7
sub-components split into separate FEAT_ items. In a few cases (eg
8
via these arrays.
8
FEAT_CCIDX, FEAT_DPB2) the omission from our list was just an oversight.
9
10
Since these are the only two remaining elements of Exynos4210Irq,
11
we can remove that struct entirely.
12
9
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220404154658.565020-19-peter.maydell@linaro.org
12
Message-id: 20240418152004.2106516-2-peter.maydell@linaro.org
16
---
13
---
17
include/hw/arm/exynos4210.h | 6 ------
14
docs/system/arm/emulation.rst | 38 +++++++++++++++++++++++++++++++++--
18
hw/arm/exynos4210.c | 34 ++++++++--------------------------
15
1 file changed, 36 insertions(+), 2 deletions(-)
19
2 files changed, 8 insertions(+), 32 deletions(-)
20
16
21
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
17
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
22
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/exynos4210.h
19
--- a/docs/system/arm/emulation.rst
24
+++ b/include/hw/arm/exynos4210.h
20
+++ b/docs/system/arm/emulation.rst
25
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ Armv8 versions of the A-profile architecture. It also has support for
26
*/
22
the following architecture extensions:
27
#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
23
28
24
- FEAT_AA32BF16 (AArch32 BFloat16 instructions)
29
-typedef struct Exynos4210Irq {
25
+- FEAT_AA32EL0 (Support for AArch32 at EL0)
30
- qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
26
+- FEAT_AA32EL1 (Support for AArch32 at EL1)
31
- qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
27
+- FEAT_AA32EL2 (Support for AArch32 at EL2)
32
-} Exynos4210Irq;
28
+- FEAT_AA32EL3 (Support for AArch32 at EL3)
33
-
29
- FEAT_AA32HPD (AArch32 hierarchical permission disables)
34
struct Exynos4210State {
30
- FEAT_AA32I8MM (AArch32 Int8 matrix multiplication instructions)
35
/*< private >*/
31
+- FEAT_AA64EL0 (Support for AArch64 at EL0)
36
SysBusDevice parent_obj;
32
+- FEAT_AA64EL1 (Support for AArch64 at EL1)
37
/*< public >*/
33
+- FEAT_AA64EL2 (Support for AArch64 at EL2)
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
34
+- FEAT_AA64EL3 (Support for AArch64 at EL3)
39
- Exynos4210Irq irqs;
35
+- FEAT_AdvSIMD (Advanced SIMD Extension)
40
qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
36
- FEAT_AES (AESD and AESE instructions)
41
37
+- FEAT_Armv9_Crypto (Armv9 Cryptographic Extension)
42
MemoryRegion chipid_mem;
38
+- FEAT_ASID16 (16 bit ASID)
43
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
39
- FEAT_BBM at level 2 (Translation table break-before-make levels)
44
index XXXXXXX..XXXXXXX 100644
40
- FEAT_BF16 (AArch64 BFloat16 instructions)
45
--- a/hw/arm/exynos4210.c
41
- FEAT_BTI (Branch Target Identification)
46
+++ b/hw/arm/exynos4210.c
42
+- FEAT_CCIDX (Extended cache index)
47
@@ -XXX,XX +XXX,XX @@ static int mapline_size(const int *mapline)
43
- FEAT_CRC32 (CRC32 instructions)
48
static void exynos4210_init_board_irqs(Exynos4210State *s)
44
+- FEAT_Crypto (Cryptographic Extension)
49
{
45
- FEAT_CSV2 (Cache speculation variant 2)
50
uint32_t grp, bit, irq_id, n;
46
- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
51
- Exynos4210Irq *is = &s->irqs;
47
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
52
DeviceState *extgicdev = DEVICE(&s->ext_gic);
48
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
53
+ DeviceState *intcdev = DEVICE(&s->int_combiner);
49
- FEAT_DGH (Data gathering hint)
54
+ DeviceState *extcdev = DEVICE(&s->ext_combiner);
50
- FEAT_DIT (Data Independent Timing instructions)
55
int splitcount = 0;
51
- FEAT_DPB (DC CVAP instruction)
56
DeviceState *splitter;
52
+- FEAT_DPB2 (DC CVADP instruction)
57
const int *mapline;
53
+- FEAT_Debugv8p1 (Debug with VHE)
58
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
54
- FEAT_Debugv8p2 (Debug changes for v8.2)
59
splitin = 0;
55
- FEAT_Debugv8p4 (Debug changes for v8.4)
60
for (;;) {
56
- FEAT_DotProd (Advanced SIMD dot product instructions)
61
s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
57
- FEAT_DoubleFault (Double Fault Extension)
62
- qdev_connect_gpio_out(splitter, splitin, is->int_combiner_irq[in]);
58
- FEAT_E0PD (Preventing EL0 access to halves of address maps)
63
- qdev_connect_gpio_out(splitter, splitin + 1, is->ext_combiner_irq[in]);
59
- FEAT_ECV (Enhanced Counter Virtualization)
64
+ qdev_connect_gpio_out(splitter, splitin,
60
+- FEAT_EL0 (Support for execution at EL0)
65
+ qdev_get_gpio_in(intcdev, in));
61
+- FEAT_EL1 (Support for execution at EL1)
66
+ qdev_connect_gpio_out(splitter, splitin + 1,
62
+- FEAT_EL2 (Support for execution at EL2)
67
+ qdev_get_gpio_in(extcdev, in));
63
+- FEAT_EL3 (Support for execution at EL3)
68
splitin += 2;
64
- FEAT_EPAC (Enhanced pointer authentication)
69
if (!mapline) {
65
- FEAT_ETS (Enhanced Translation Synchronization)
70
break;
66
- FEAT_EVT (Enhanced Virtualization Traps)
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
67
+- FEAT_F32MM (Single-precision Matrix Multiplication)
72
qdev_realize(splitter, NULL, &error_abort);
68
+- FEAT_F64MM (Double-precision Matrix Multiplication)
73
splitcount++;
69
- FEAT_FCMA (Floating-point complex number instructions)
74
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
70
- FEAT_FGT (Fine-Grained Traps)
75
- qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
71
- FEAT_FHM (Floating-point half-precision multiplication instructions)
76
+ qdev_connect_gpio_out(splitter, 0, qdev_get_gpio_in(intcdev, n));
72
+- FEAT_FP (Floating Point extensions)
77
qdev_connect_gpio_out(splitter, 1,
73
- FEAT_FP16 (Half-precision floating-point data processing)
78
qdev_get_gpio_in(extgicdev, irq_id - 32));
74
- FEAT_FPAC (Faulting on AUT* instructions)
79
} else {
75
- FEAT_FPACCOMBINE (Faulting on combined pointer authentication instructions)
80
- s->irq_table[n] = is->int_combiner_irq[n];
76
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
81
+ s->irq_table[n] = qdev_get_gpio_in(intcdev, n);
77
- FEAT_LSE (Large System Extensions)
82
}
78
- FEAT_LSE2 (Large System Extensions v2)
83
}
79
- FEAT_LVA (Large Virtual Address space)
84
/*
80
+- FEAT_MixedEnd (Mixed-endian support)
85
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
81
+- FEAT_MixdEndEL0 (Mixed-endian support at EL0)
86
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
82
- FEAT_MOPS (Standardization of memory operations)
87
}
83
- FEAT_MTE (Memory Tagging Extension)
88
84
- FEAT_MTE2 (Memory Tagging Extension)
89
-/*
85
- FEAT_MTE3 (MTE Asymmetric Fault Handling)
90
- * Get Combiner input GPIO into irqs structure
86
+- FEAT_MTE_ASYM_FAULT (Memory tagging asymmetric faults)
91
- */
87
- FEAT_NMI (Non-maskable Interrupt)
92
-static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
88
- FEAT_NV (Nested Virtualization)
93
- DeviceState *dev, int ext)
89
- FEAT_NV2 (Enhanced nested virtualization support)
94
-{
90
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
95
- int n;
91
- FEAT_PAuth (Pointer authentication)
96
- int max;
92
- FEAT_PAuth2 (Enhancements to pointer authentication)
97
- qemu_irq *irq;
93
- FEAT_PMULL (PMULL, PMULL2 instructions)
98
-
94
+- FEAT_PMUv3 (PMU extension version 3)
99
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
95
- FEAT_PMUv3p1 (PMU Extensions v3.1)
100
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
96
- FEAT_PMUv3p4 (PMU Extensions v3.4)
101
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
97
- FEAT_PMUv3p5 (PMU Extensions v3.5)
102
-
98
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
103
- for (n = 0; n < max; n++) {
99
- FEAT_SME_FA64 (Full A64 instruction set in Streaming SVE mode)
104
- irq[n] = qdev_get_gpio_in(dev, n);
100
- FEAT_SME_F64F64 (Double-precision floating-point outer product instructions)
105
- }
101
- FEAT_SME_I16I64 (16-bit to 64-bit integer widening outer product instructions)
106
-}
102
+- FEAT_SVE (Scalable Vector Extension)
107
-
103
+- FEAT_SVE_AES (Scalable Vector AES instructions)
108
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
104
+- FEAT_SVE_BitPerm (Scalable Vector Bit Permutes instructions)
109
0x09, 0x00, 0x00, 0x00 };
105
+- FEAT_SVE_PMULL128 (Scalable Vector PMULL instructions)
110
106
+- FEAT_SVE_SHA3 (Scalable Vector SHA3 instructions)
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
107
+- FEAT_SVE_SM4 (Scalable Vector SM4 instructions)
112
sysbus_connect_irq(busdev, n,
108
+- FEAT_SVE2 (Scalable Vector Extension version 2)
113
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
109
- FEAT_SPECRES (Speculation restriction instructions)
114
}
110
- FEAT_SSBS (Speculative Store Bypass Safe)
115
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
111
+- FEAT_TGran16K (Support for 16KB memory translation granule size at stage 1)
116
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
112
+- FEAT_TGran4K (Support for 4KB memory translation granule size at stage 1)
117
113
+- FEAT_TGran64K (Support for 64KB memory translation granule size at stage 1)
118
/* External Interrupt Combiner */
114
- FEAT_TIDCP1 (EL0 use of IMPLEMENTATION DEFINED functionality)
119
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
115
- FEAT_TLBIOS (TLB invalidate instructions in Outer Shareable domain)
120
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
116
- FEAT_TLBIRANGE (TLB invalidate range instructions)
121
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
117
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
122
}
118
- FEAT_VHE (Virtualization Host Extensions)
123
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
119
- FEAT_VMID16 (16-bit VMID)
124
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
120
- FEAT_XNX (Translation table stage 2 Unprivileged Execute-never)
125
121
-- SVE (The Scalable Vector Extension)
126
/* Initialize board IRQs. */
122
-- SVE2 (The Scalable Vector Extension v2)
123
124
For information on the specifics of these extensions, please refer
125
to the `Armv8-A Arm Architecture Reference Manual
127
--
126
--
128
2.25.1
127
2.34.1
diff view generated by jsdifflib
1
The function exynos4210_init_board_irqs() currently lives in
1
FEAT_CSV2_3 adds a mechanism to identify if hardware cannot disclose
2
exynos4210_gic.c, but it isn't really part of the exynos4210.gic
2
information about whether branch targets and branch history trained
3
device -- it is a function that implements (some of) the wiring up of
3
in one hardware described context can control speculative execution
4
interrupts between the SoC's GIC and combiner components. This means
4
in a different hardware context.
5
it fits better in exynos4210.c, which is the SoC-level code. Move it
5
6
there. Similarly, exynos4210_git_irq() is used almost only in the
6
There is no branch prediction in TCG, so we don't need to do anything
7
SoC-level code, so move it too.
7
to be compliant with this. Upadte the '-cpu max' ID registers to
8
advertise the feature.
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: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-8-peter.maydell@linaro.org
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Message-id: 20240418152004.2106516-3-peter.maydell@linaro.org
12
---
14
---
13
include/hw/arm/exynos4210.h | 4 -
15
docs/system/arm/emulation.rst | 1 +
14
hw/arm/exynos4210.c | 202 +++++++++++++++++++++++++++++++++++
16
target/arm/tcg/cpu64.c | 4 ++--
15
hw/intc/exynos4210_gic.c | 204 ------------------------------------
17
2 files changed, 3 insertions(+), 2 deletions(-)
16
3 files changed, 202 insertions(+), 208 deletions(-)
17
18
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
19
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
19
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/exynos4210.h
21
--- a/docs/system/arm/emulation.rst
21
+++ b/include/hw/arm/exynos4210.h
22
+++ b/docs/system/arm/emulation.rst
22
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
23
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
23
void exynos4210_write_secondary(ARMCPU *cpu,
24
- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
24
const struct arm_boot_info *info);
25
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
25
26
- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
26
-/* Initialize board IRQs.
27
+- FEAT_CSV2_3 (Cache speculation variant 2, version 3)
27
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs */
28
- FEAT_CSV3 (Cache speculation variant 3)
28
-void exynos4210_init_board_irqs(Exynos4210State *s);
29
- FEAT_DGH (Data gathering hint)
29
-
30
- FEAT_DIT (Data Independent Timing instructions)
30
/* Get IRQ number from exynos4210 IRQ subsystem stub.
31
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.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
32
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/exynos4210.c
33
--- a/target/arm/tcg/cpu64.c
36
+++ b/hw/arm/exynos4210.c
34
+++ b/target/arm/tcg/cpu64.c
37
@@ -XXX,XX +XXX,XX @@
35
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
38
#define EXYNOS4210_PL330_BASE1_ADDR 0x12690000
36
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
39
#define EXYNOS4210_PL330_BASE2_ADDR 0x12850000
37
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
40
38
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
41
+enum ExtGicId {
39
- t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 2); /* FEAT_CSV2_2 */
42
+ EXT_GIC_ID_MDMA_LCD0 = 66,
40
+ t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 3); /* FEAT_CSV2_3 */
43
+ EXT_GIC_ID_PDMA0,
41
t = FIELD_DP64(t, ID_AA64PFR0, CSV3, 1); /* FEAT_CSV3 */
44
+ EXT_GIC_ID_PDMA1,
42
cpu->isar.id_aa64pfr0 = t;
45
+ EXT_GIC_ID_TIMER0,
43
46
+ EXT_GIC_ID_TIMER1,
44
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
47
+ EXT_GIC_ID_TIMER2,
45
t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3); /* FEAT_MTE3 */
48
+ EXT_GIC_ID_TIMER3,
46
t = FIELD_DP64(t, ID_AA64PFR1, RAS_FRAC, 0); /* FEAT_RASv1p1 + FEAT_DoubleFault */
49
+ EXT_GIC_ID_TIMER4,
47
t = FIELD_DP64(t, ID_AA64PFR1, SME, 1); /* FEAT_SME */
50
+ EXT_GIC_ID_MCT_L0,
48
- t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_2 */
51
+ EXT_GIC_ID_WDT,
49
+ t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_3 */
52
+ EXT_GIC_ID_RTC_ALARM,
50
t = FIELD_DP64(t, ID_AA64PFR1, NMI, 1); /* FEAT_NMI */
53
+ EXT_GIC_ID_RTC_TIC,
51
cpu->isar.id_aa64pfr1 = t;
54
+ EXT_GIC_ID_GPIO_XB,
55
+ EXT_GIC_ID_GPIO_XA,
56
+ EXT_GIC_ID_MCT_L1,
57
+ EXT_GIC_ID_IEM_APC,
58
+ EXT_GIC_ID_IEM_IEC,
59
+ EXT_GIC_ID_NFC,
60
+ EXT_GIC_ID_UART0,
61
+ EXT_GIC_ID_UART1,
62
+ EXT_GIC_ID_UART2,
63
+ EXT_GIC_ID_UART3,
64
+ EXT_GIC_ID_UART4,
65
+ EXT_GIC_ID_MCT_G0,
66
+ EXT_GIC_ID_I2C0,
67
+ EXT_GIC_ID_I2C1,
68
+ EXT_GIC_ID_I2C2,
69
+ EXT_GIC_ID_I2C3,
70
+ EXT_GIC_ID_I2C4,
71
+ EXT_GIC_ID_I2C5,
72
+ EXT_GIC_ID_I2C6,
73
+ EXT_GIC_ID_I2C7,
74
+ EXT_GIC_ID_SPI0,
75
+ EXT_GIC_ID_SPI1,
76
+ EXT_GIC_ID_SPI2,
77
+ EXT_GIC_ID_MCT_G1,
78
+ EXT_GIC_ID_USB_HOST,
79
+ EXT_GIC_ID_USB_DEVICE,
80
+ EXT_GIC_ID_MODEMIF,
81
+ EXT_GIC_ID_HSMMC0,
82
+ EXT_GIC_ID_HSMMC1,
83
+ EXT_GIC_ID_HSMMC2,
84
+ EXT_GIC_ID_HSMMC3,
85
+ EXT_GIC_ID_SDMMC,
86
+ EXT_GIC_ID_MIPI_CSI_4LANE,
87
+ EXT_GIC_ID_MIPI_DSI_4LANE,
88
+ EXT_GIC_ID_MIPI_CSI_2LANE,
89
+ EXT_GIC_ID_MIPI_DSI_2LANE,
90
+ EXT_GIC_ID_ONENAND_AUDI,
91
+ EXT_GIC_ID_ROTATOR,
92
+ EXT_GIC_ID_FIMC0,
93
+ EXT_GIC_ID_FIMC1,
94
+ EXT_GIC_ID_FIMC2,
95
+ EXT_GIC_ID_FIMC3,
96
+ EXT_GIC_ID_JPEG,
97
+ EXT_GIC_ID_2D,
98
+ EXT_GIC_ID_PCIe,
99
+ EXT_GIC_ID_MIXER,
100
+ EXT_GIC_ID_HDMI,
101
+ EXT_GIC_ID_HDMI_I2C,
102
+ EXT_GIC_ID_MFC,
103
+ EXT_GIC_ID_TVENC,
104
+};
105
+
106
+enum ExtInt {
107
+ EXT_GIC_ID_EXTINT0 = 48,
108
+ EXT_GIC_ID_EXTINT1,
109
+ EXT_GIC_ID_EXTINT2,
110
+ EXT_GIC_ID_EXTINT3,
111
+ EXT_GIC_ID_EXTINT4,
112
+ EXT_GIC_ID_EXTINT5,
113
+ EXT_GIC_ID_EXTINT6,
114
+ EXT_GIC_ID_EXTINT7,
115
+ EXT_GIC_ID_EXTINT8,
116
+ EXT_GIC_ID_EXTINT9,
117
+ EXT_GIC_ID_EXTINT10,
118
+ EXT_GIC_ID_EXTINT11,
119
+ EXT_GIC_ID_EXTINT12,
120
+ EXT_GIC_ID_EXTINT13,
121
+ EXT_GIC_ID_EXTINT14,
122
+ EXT_GIC_ID_EXTINT15
123
+};
124
+
125
+/*
126
+ * External GIC sources which are not from External Interrupt Combiner or
127
+ * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
128
+ * which is INTG16 in Internal Interrupt Combiner.
129
+ */
130
+
131
+static const uint32_t
132
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
133
+ /* int combiner groups 16-19 */
134
+ { }, { }, { }, { },
135
+ /* int combiner group 20 */
136
+ { 0, EXT_GIC_ID_MDMA_LCD0 },
137
+ /* int combiner group 21 */
138
+ { EXT_GIC_ID_PDMA0, EXT_GIC_ID_PDMA1 },
139
+ /* int combiner group 22 */
140
+ { EXT_GIC_ID_TIMER0, EXT_GIC_ID_TIMER1, EXT_GIC_ID_TIMER2,
141
+ EXT_GIC_ID_TIMER3, EXT_GIC_ID_TIMER4 },
142
+ /* int combiner group 23 */
143
+ { EXT_GIC_ID_RTC_ALARM, EXT_GIC_ID_RTC_TIC },
144
+ /* int combiner group 24 */
145
+ { EXT_GIC_ID_GPIO_XB, EXT_GIC_ID_GPIO_XA },
146
+ /* int combiner group 25 */
147
+ { EXT_GIC_ID_IEM_APC, EXT_GIC_ID_IEM_IEC },
148
+ /* int combiner group 26 */
149
+ { EXT_GIC_ID_UART0, EXT_GIC_ID_UART1, EXT_GIC_ID_UART2, EXT_GIC_ID_UART3,
150
+ EXT_GIC_ID_UART4 },
151
+ /* int combiner group 27 */
152
+ { EXT_GIC_ID_I2C0, EXT_GIC_ID_I2C1, EXT_GIC_ID_I2C2, EXT_GIC_ID_I2C3,
153
+ EXT_GIC_ID_I2C4, EXT_GIC_ID_I2C5, EXT_GIC_ID_I2C6,
154
+ EXT_GIC_ID_I2C7 },
155
+ /* int combiner group 28 */
156
+ { EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 , EXT_GIC_ID_USB_HOST},
157
+ /* int combiner group 29 */
158
+ { EXT_GIC_ID_HSMMC0, EXT_GIC_ID_HSMMC1, EXT_GIC_ID_HSMMC2,
159
+ EXT_GIC_ID_HSMMC3, EXT_GIC_ID_SDMMC },
160
+ /* int combiner group 30 */
161
+ { EXT_GIC_ID_MIPI_CSI_4LANE, EXT_GIC_ID_MIPI_CSI_2LANE },
162
+ /* int combiner group 31 */
163
+ { EXT_GIC_ID_MIPI_DSI_4LANE, EXT_GIC_ID_MIPI_DSI_2LANE },
164
+ /* int combiner group 32 */
165
+ { EXT_GIC_ID_FIMC0, EXT_GIC_ID_FIMC1 },
166
+ /* int combiner group 33 */
167
+ { EXT_GIC_ID_FIMC2, EXT_GIC_ID_FIMC3 },
168
+ /* int combiner group 34 */
169
+ { EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
170
+ /* int combiner group 35 */
171
+ { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
172
+ /* int combiner group 36 */
173
+ { EXT_GIC_ID_MIXER },
174
+ /* int combiner group 37 */
175
+ { EXT_GIC_ID_EXTINT4, EXT_GIC_ID_EXTINT5, EXT_GIC_ID_EXTINT6,
176
+ EXT_GIC_ID_EXTINT7 },
177
+ /* groups 38-50 */
178
+ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
179
+ /* int combiner group 51 */
180
+ { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
181
+ /* group 52 */
182
+ { },
183
+ /* int combiner group 53 */
184
+ { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
185
+ /* groups 54-63 */
186
+ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
187
+};
188
+
189
+/*
190
+ * Initialize board IRQs.
191
+ * These IRQs contain splitted Int/External Combiner and External Gic IRQs.
192
+ */
193
+static void exynos4210_init_board_irqs(Exynos4210State *s)
194
+{
195
+ uint32_t grp, bit, irq_id, n;
196
+ Exynos4210Irq *is = &s->irqs;
197
+
198
+ for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
199
+ irq_id = 0;
200
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
201
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
202
+ /* MCT_G0 is passed to External GIC */
203
+ irq_id = EXT_GIC_ID_MCT_G0;
204
+ }
205
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
206
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
207
+ /* MCT_G1 is passed to External and GIC */
208
+ irq_id = EXT_GIC_ID_MCT_G1;
209
+ }
210
+ if (irq_id) {
211
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
212
+ is->ext_gic_irq[irq_id - 32]);
213
+ } else {
214
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
215
+ is->ext_combiner_irq[n]);
216
+ }
217
+ }
218
+ for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
219
+ /* these IDs are passed to Internal Combiner and External GIC */
220
+ grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
221
+ bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
222
+ irq_id = combiner_grp_to_gic_id[grp -
223
+ EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
224
+
225
+ if (irq_id) {
226
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
227
+ is->ext_gic_irq[irq_id - 32]);
228
+ }
229
+ }
230
+}
231
+
232
+/*
233
+ * Get IRQ number from exynos4210 IRQ subsystem stub.
234
+ * To identify IRQ source use internal combiner group and bit number
235
+ * grp - group number
236
+ * bit - bit number inside group
237
+ */
238
+uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
239
+{
240
+ return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
241
+}
242
+
243
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
244
0x09, 0x00, 0x00, 0x00 };
245
246
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
247
index XXXXXXX..XXXXXXX 100644
248
--- a/hw/intc/exynos4210_gic.c
249
+++ b/hw/intc/exynos4210_gic.c
250
@@ -XXX,XX +XXX,XX @@
251
#include "hw/arm/exynos4210.h"
252
#include "qom/object.h"
253
254
-enum ExtGicId {
255
- EXT_GIC_ID_MDMA_LCD0 = 66,
256
- EXT_GIC_ID_PDMA0,
257
- EXT_GIC_ID_PDMA1,
258
- EXT_GIC_ID_TIMER0,
259
- EXT_GIC_ID_TIMER1,
260
- EXT_GIC_ID_TIMER2,
261
- EXT_GIC_ID_TIMER3,
262
- EXT_GIC_ID_TIMER4,
263
- EXT_GIC_ID_MCT_L0,
264
- EXT_GIC_ID_WDT,
265
- EXT_GIC_ID_RTC_ALARM,
266
- EXT_GIC_ID_RTC_TIC,
267
- EXT_GIC_ID_GPIO_XB,
268
- EXT_GIC_ID_GPIO_XA,
269
- EXT_GIC_ID_MCT_L1,
270
- EXT_GIC_ID_IEM_APC,
271
- EXT_GIC_ID_IEM_IEC,
272
- EXT_GIC_ID_NFC,
273
- EXT_GIC_ID_UART0,
274
- EXT_GIC_ID_UART1,
275
- EXT_GIC_ID_UART2,
276
- EXT_GIC_ID_UART3,
277
- EXT_GIC_ID_UART4,
278
- EXT_GIC_ID_MCT_G0,
279
- EXT_GIC_ID_I2C0,
280
- EXT_GIC_ID_I2C1,
281
- EXT_GIC_ID_I2C2,
282
- EXT_GIC_ID_I2C3,
283
- EXT_GIC_ID_I2C4,
284
- EXT_GIC_ID_I2C5,
285
- EXT_GIC_ID_I2C6,
286
- EXT_GIC_ID_I2C7,
287
- EXT_GIC_ID_SPI0,
288
- EXT_GIC_ID_SPI1,
289
- EXT_GIC_ID_SPI2,
290
- EXT_GIC_ID_MCT_G1,
291
- EXT_GIC_ID_USB_HOST,
292
- EXT_GIC_ID_USB_DEVICE,
293
- EXT_GIC_ID_MODEMIF,
294
- EXT_GIC_ID_HSMMC0,
295
- EXT_GIC_ID_HSMMC1,
296
- EXT_GIC_ID_HSMMC2,
297
- EXT_GIC_ID_HSMMC3,
298
- EXT_GIC_ID_SDMMC,
299
- EXT_GIC_ID_MIPI_CSI_4LANE,
300
- EXT_GIC_ID_MIPI_DSI_4LANE,
301
- EXT_GIC_ID_MIPI_CSI_2LANE,
302
- EXT_GIC_ID_MIPI_DSI_2LANE,
303
- EXT_GIC_ID_ONENAND_AUDI,
304
- EXT_GIC_ID_ROTATOR,
305
- EXT_GIC_ID_FIMC0,
306
- EXT_GIC_ID_FIMC1,
307
- EXT_GIC_ID_FIMC2,
308
- EXT_GIC_ID_FIMC3,
309
- EXT_GIC_ID_JPEG,
310
- EXT_GIC_ID_2D,
311
- EXT_GIC_ID_PCIe,
312
- EXT_GIC_ID_MIXER,
313
- EXT_GIC_ID_HDMI,
314
- EXT_GIC_ID_HDMI_I2C,
315
- EXT_GIC_ID_MFC,
316
- EXT_GIC_ID_TVENC,
317
-};
318
-
319
-enum ExtInt {
320
- EXT_GIC_ID_EXTINT0 = 48,
321
- EXT_GIC_ID_EXTINT1,
322
- EXT_GIC_ID_EXTINT2,
323
- EXT_GIC_ID_EXTINT3,
324
- EXT_GIC_ID_EXTINT4,
325
- EXT_GIC_ID_EXTINT5,
326
- EXT_GIC_ID_EXTINT6,
327
- EXT_GIC_ID_EXTINT7,
328
- EXT_GIC_ID_EXTINT8,
329
- EXT_GIC_ID_EXTINT9,
330
- EXT_GIC_ID_EXTINT10,
331
- EXT_GIC_ID_EXTINT11,
332
- EXT_GIC_ID_EXTINT12,
333
- EXT_GIC_ID_EXTINT13,
334
- EXT_GIC_ID_EXTINT14,
335
- EXT_GIC_ID_EXTINT15
336
-};
337
-
338
-/*
339
- * External GIC sources which are not from External Interrupt Combiner or
340
- * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
341
- * which is INTG16 in Internal Interrupt Combiner.
342
- */
343
-
344
-static const uint32_t
345
-combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
346
- /* int combiner groups 16-19 */
347
- { }, { }, { }, { },
348
- /* int combiner group 20 */
349
- { 0, EXT_GIC_ID_MDMA_LCD0 },
350
- /* int combiner group 21 */
351
- { EXT_GIC_ID_PDMA0, EXT_GIC_ID_PDMA1 },
352
- /* int combiner group 22 */
353
- { EXT_GIC_ID_TIMER0, EXT_GIC_ID_TIMER1, EXT_GIC_ID_TIMER2,
354
- EXT_GIC_ID_TIMER3, EXT_GIC_ID_TIMER4 },
355
- /* int combiner group 23 */
356
- { EXT_GIC_ID_RTC_ALARM, EXT_GIC_ID_RTC_TIC },
357
- /* int combiner group 24 */
358
- { EXT_GIC_ID_GPIO_XB, EXT_GIC_ID_GPIO_XA },
359
- /* int combiner group 25 */
360
- { EXT_GIC_ID_IEM_APC, EXT_GIC_ID_IEM_IEC },
361
- /* int combiner group 26 */
362
- { EXT_GIC_ID_UART0, EXT_GIC_ID_UART1, EXT_GIC_ID_UART2, EXT_GIC_ID_UART3,
363
- EXT_GIC_ID_UART4 },
364
- /* int combiner group 27 */
365
- { EXT_GIC_ID_I2C0, EXT_GIC_ID_I2C1, EXT_GIC_ID_I2C2, EXT_GIC_ID_I2C3,
366
- EXT_GIC_ID_I2C4, EXT_GIC_ID_I2C5, EXT_GIC_ID_I2C6,
367
- EXT_GIC_ID_I2C7 },
368
- /* int combiner group 28 */
369
- { EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 , EXT_GIC_ID_USB_HOST},
370
- /* int combiner group 29 */
371
- { EXT_GIC_ID_HSMMC0, EXT_GIC_ID_HSMMC1, EXT_GIC_ID_HSMMC2,
372
- EXT_GIC_ID_HSMMC3, EXT_GIC_ID_SDMMC },
373
- /* int combiner group 30 */
374
- { EXT_GIC_ID_MIPI_CSI_4LANE, EXT_GIC_ID_MIPI_CSI_2LANE },
375
- /* int combiner group 31 */
376
- { EXT_GIC_ID_MIPI_DSI_4LANE, EXT_GIC_ID_MIPI_DSI_2LANE },
377
- /* int combiner group 32 */
378
- { EXT_GIC_ID_FIMC0, EXT_GIC_ID_FIMC1 },
379
- /* int combiner group 33 */
380
- { EXT_GIC_ID_FIMC2, EXT_GIC_ID_FIMC3 },
381
- /* int combiner group 34 */
382
- { EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
383
- /* int combiner group 35 */
384
- { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
385
- /* int combiner group 36 */
386
- { EXT_GIC_ID_MIXER },
387
- /* int combiner group 37 */
388
- { EXT_GIC_ID_EXTINT4, EXT_GIC_ID_EXTINT5, EXT_GIC_ID_EXTINT6,
389
- EXT_GIC_ID_EXTINT7 },
390
- /* groups 38-50 */
391
- { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
392
- /* int combiner group 51 */
393
- { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
394
- /* group 52 */
395
- { },
396
- /* int combiner group 53 */
397
- { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
398
- /* groups 54-63 */
399
- { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
400
-};
401
-
402
#define EXYNOS4210_GIC_NIRQ 160
403
404
#define EXYNOS4210_EXT_GIC_CPU_REGION_SIZE 0x10000
405
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
406
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
407
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
408
409
-/*
410
- * Initialize board IRQs.
411
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs.
412
- */
413
-void exynos4210_init_board_irqs(Exynos4210State *s)
414
-{
415
- uint32_t grp, bit, irq_id, n;
416
- Exynos4210Irq *is = &s->irqs;
417
-
418
- for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
419
- irq_id = 0;
420
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
421
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
422
- /* MCT_G0 is passed to External GIC */
423
- irq_id = EXT_GIC_ID_MCT_G0;
424
- }
425
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
426
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
427
- /* MCT_G1 is passed to External and GIC */
428
- irq_id = EXT_GIC_ID_MCT_G1;
429
- }
430
- if (irq_id) {
431
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
432
- is->ext_gic_irq[irq_id - 32]);
433
- } else {
434
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
435
- is->ext_combiner_irq[n]);
436
- }
437
- }
438
- for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
439
- /* these IDs are passed to Internal Combiner and External GIC */
440
- grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
441
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
442
- irq_id = combiner_grp_to_gic_id[grp -
443
- EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
444
-
445
- if (irq_id) {
446
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
447
- is->ext_gic_irq[irq_id - 32]);
448
- }
449
- }
450
-}
451
-
452
-/*
453
- * Get IRQ number from exynos4210 IRQ subsystem stub.
454
- * To identify IRQ source use internal combiner group and bit number
455
- * grp - group number
456
- * bit - bit number inside group
457
- */
458
-uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
459
-{
460
- return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
461
-}
462
-
463
-/********* GIC part *********/
464
-
465
#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
466
OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
467
52
468
--
53
--
469
2.25.1
54
2.34.1
55
56
diff view generated by jsdifflib
1
Switch the creation of the combiner devices to the new-style
1
FEAT_ETS2 is a tighter set of guarantees about memory ordering
2
"embedded in state struct" approach, so we can easily refer
2
involving translation table walks than the old FEAT_ETS; FEAT_ETS has
3
to the object elsewhere during realize.
3
been retired from the Arm ARM and the old ID_AA64MMFR1.ETS == 1
4
now gives no greater guarantees than ETS == 0.
5
6
FEAT_ETS2 requires:
7
* the virtual address of a load or store that appears in program
8
order after a DSB cannot be translated until after the DSB
9
completes (section B2.10.9)
10
* TLB maintenance operations that only affect translations without
11
execute permission are guaranteed complete after a DSB
12
(R_BLDZX)
13
* if a memory access RW2 is ordered-before memory access RW2,
14
then RW1 is also ordered-before any translation table walk
15
generated by RW2 that generates a Translation, Address size
16
or Access flag fault (R_NNFPF, I_CLGHP)
17
18
As with FEAT_ETS, QEMU is already compliant, because we do not
19
reorder translation table walk memory accesses relative to other
20
memory accesses, and we always guarantee to have finished TLB
21
maintenance as soon as the TLB op is done.
22
23
Update the documentation to list FEAT_ETS2 instead of the
24
no-longer-existent FEAT_ETS, and update the 'max' CPU ID registers.
4
25
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220404154658.565020-18-peter.maydell@linaro.org
28
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
29
Message-id: 20240418152004.2106516-4-peter.maydell@linaro.org
8
---
30
---
9
include/hw/arm/exynos4210.h | 3 ++
31
docs/system/arm/emulation.rst | 2 +-
10
include/hw/intc/exynos4210_combiner.h | 57 +++++++++++++++++++++++++++
32
target/arm/tcg/cpu32.c | 2 +-
11
hw/arm/exynos4210.c | 20 +++++-----
33
target/arm/tcg/cpu64.c | 2 +-
12
hw/intc/exynos4210_combiner.c | 31 +--------------
34
3 files changed, 3 insertions(+), 3 deletions(-)
13
4 files changed, 72 insertions(+), 39 deletions(-)
14
create mode 100644 include/hw/intc/exynos4210_combiner.h
15
35
16
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
36
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
17
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/exynos4210.h
38
--- a/docs/system/arm/emulation.rst
19
+++ b/include/hw/arm/exynos4210.h
39
+++ b/docs/system/arm/emulation.rst
20
@@ -XXX,XX +XXX,XX @@
40
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
21
#include "hw/sysbus.h"
41
- FEAT_EL2 (Support for execution at EL2)
22
#include "hw/cpu/a9mpcore.h"
42
- FEAT_EL3 (Support for execution at EL3)
23
#include "hw/intc/exynos4210_gic.h"
43
- FEAT_EPAC (Enhanced pointer authentication)
24
+#include "hw/intc/exynos4210_combiner.h"
44
-- FEAT_ETS (Enhanced Translation Synchronization)
25
#include "hw/core/split-irq.h"
45
+- FEAT_ETS2 (Enhanced Translation Synchronization)
26
#include "target/arm/cpu-qom.h"
46
- FEAT_EVT (Enhanced Virtualization Traps)
27
#include "qom/object.h"
47
- FEAT_F32MM (Single-precision Matrix Multiplication)
28
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
48
- FEAT_F64MM (Double-precision Matrix Multiplication)
29
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
49
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
30
A9MPPrivState a9mpcore;
31
Exynos4210GicState ext_gic;
32
+ Exynos4210CombinerState int_combiner;
33
+ Exynos4210CombinerState ext_combiner;
34
SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
35
};
36
37
diff --git a/include/hw/intc/exynos4210_combiner.h b/include/hw/intc/exynos4210_combiner.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/intc/exynos4210_combiner.h
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * Samsung exynos4210 Interrupt Combiner
45
+ *
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
47
+ * All rights reserved.
48
+ *
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
50
+ *
51
+ * This program is free software; you can redistribute it and/or modify it
52
+ * under the terms of the GNU General Public License as published by the
53
+ * Free Software Foundation; either version 2 of the License, or (at your
54
+ * option) any later version.
55
+ *
56
+ * This program is distributed in the hope that it will be useful,
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
59
+ * See the GNU General Public License for more details.
60
+ *
61
+ * You should have received a copy of the GNU General Public License along
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
63
+ */
64
+
65
+#ifndef HW_INTC_EXYNOS4210_COMBINER
66
+#define HW_INTC_EXYNOS4210_COMBINER
67
+
68
+#include "hw/sysbus.h"
69
+
70
+/*
71
+ * State for each output signal of internal combiner
72
+ */
73
+typedef struct CombinerGroupState {
74
+ uint8_t src_mask; /* 1 - source enabled, 0 - disabled */
75
+ uint8_t src_pending; /* Pending source interrupts before masking */
76
+} CombinerGroupState;
77
+
78
+#define TYPE_EXYNOS4210_COMBINER "exynos4210.combiner"
79
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210CombinerState, EXYNOS4210_COMBINER)
80
+
81
+/* Number of groups and total number of interrupts for the internal combiner */
82
+#define IIC_NGRP 64
83
+#define IIC_NIRQ (IIC_NGRP * 8)
84
+#define IIC_REGSET_SIZE 0x41
85
+
86
+struct Exynos4210CombinerState {
87
+ SysBusDevice parent_obj;
88
+
89
+ MemoryRegion iomem;
90
+
91
+ struct CombinerGroupState group[IIC_NGRP];
92
+ uint32_t reg_set[IIC_REGSET_SIZE];
93
+ uint32_t icipsr[2];
94
+ uint32_t external; /* 1 means that this combiner is external */
95
+
96
+ qemu_irq output_irq[IIC_NGRP];
97
+};
98
+
99
+#endif
100
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
101
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
102
--- a/hw/arm/exynos4210.c
51
--- a/target/arm/tcg/cpu32.c
103
+++ b/hw/arm/exynos4210.c
52
+++ b/target/arm/tcg/cpu32.c
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
53
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
105
}
54
cpu->isar.id_mmfr4 = t;
106
55
107
/* Internal Interrupt Combiner */
56
t = cpu->isar.id_mmfr5;
108
- dev = qdev_new("exynos4210.combiner");
57
- t = FIELD_DP32(t, ID_MMFR5, ETS, 1); /* FEAT_ETS */
109
- busdev = SYS_BUS_DEVICE(dev);
58
+ t = FIELD_DP32(t, ID_MMFR5, ETS, 2); /* FEAT_ETS2 */
110
- sysbus_realize_and_unref(busdev, &error_fatal);
59
cpu->isar.id_mmfr5 = t;
111
+ busdev = SYS_BUS_DEVICE(&s->int_combiner);
60
112
+ sysbus_realize(busdev, &error_fatal);
61
t = cpu->isar.id_pfr0;
113
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
62
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
114
sysbus_connect_irq(busdev, n,
115
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
116
}
117
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
118
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
119
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
120
121
/* External Interrupt Combiner */
122
- dev = qdev_new("exynos4210.combiner");
123
- qdev_prop_set_uint32(dev, "external", 1);
124
- busdev = SYS_BUS_DEVICE(dev);
125
- sysbus_realize_and_unref(busdev, &error_fatal);
126
+ qdev_prop_set_uint32(DEVICE(&s->ext_combiner), "external", 1);
127
+ busdev = SYS_BUS_DEVICE(&s->ext_combiner);
128
+ sysbus_realize(busdev, &error_fatal);
129
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
130
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
131
}
132
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
133
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
134
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
135
136
/* Initialize board IRQs. */
137
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
138
139
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
140
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
141
+ object_initialize_child(obj, "int-combiner", &s->int_combiner,
142
+ TYPE_EXYNOS4210_COMBINER);
143
+ object_initialize_child(obj, "ext-combiner", &s->ext_combiner,
144
+ TYPE_EXYNOS4210_COMBINER);
145
}
146
147
static void exynos4210_class_init(ObjectClass *klass, void *data)
148
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
149
index XXXXXXX..XXXXXXX 100644
63
index XXXXXXX..XXXXXXX 100644
150
--- a/hw/intc/exynos4210_combiner.c
64
--- a/target/arm/tcg/cpu64.c
151
+++ b/hw/intc/exynos4210_combiner.c
65
+++ b/target/arm/tcg/cpu64.c
152
@@ -XXX,XX +XXX,XX @@
66
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
153
#include "hw/sysbus.h"
67
t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); /* FEAT_LOR */
154
#include "migration/vmstate.h"
68
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 3); /* FEAT_PAN3 */
155
#include "qemu/module.h"
69
t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* FEAT_XNX */
156
-
70
- t = FIELD_DP64(t, ID_AA64MMFR1, ETS, 1); /* FEAT_ETS */
157
+#include "hw/intc/exynos4210_combiner.h"
71
+ t = FIELD_DP64(t, ID_AA64MMFR1, ETS, 2); /* FEAT_ETS2 */
158
#include "hw/arm/exynos4210.h"
72
t = FIELD_DP64(t, ID_AA64MMFR1, HCX, 1); /* FEAT_HCX */
159
#include "hw/hw.h"
73
t = FIELD_DP64(t, ID_AA64MMFR1, TIDCP1, 1); /* FEAT_TIDCP1 */
160
#include "hw/irq.h"
74
cpu->isar.id_aa64mmfr1 = t;
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
--
75
--
199
2.25.1
76
2.34.1
77
78
diff view generated by jsdifflib
1
The exynos4210 SoC mostly creates its child devices as if it were
1
Newer versions of the Arm ARM (e.g. rev K.a) now define fields for
2
board code. This includes the a9mpcore object. Switch that to a
2
ID_AA64MMFR3_EL1. Implement this register, so that we can set the
3
new-style "embedded in the state struct" creation, because in the
3
fields if we need to. There's no behaviour change here since we
4
next commit we're going to want to refer to the object again further
4
don't currently set the register value to non-zero.
5
down in the exynos4210_realize() function.
6
5
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220404154658.565020-4-peter.maydell@linaro.org
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20240418152004.2106516-5-peter.maydell@linaro.org
10
---
10
---
11
include/hw/arm/exynos4210.h | 2 ++
11
target/arm/cpu.h | 17 +++++++++++++++++
12
hw/arm/exynos4210.c | 11 ++++++-----
12
target/arm/helper.c | 6 ++++--
13
2 files changed, 8 insertions(+), 5 deletions(-)
13
target/arm/hvf/hvf.c | 2 ++
14
target/arm/kvm.c | 2 ++
15
4 files changed, 25 insertions(+), 2 deletions(-)
14
16
15
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/exynos4210.h
19
--- a/target/arm/cpu.h
18
+++ b/include/hw/arm/exynos4210.h
20
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
20
22
uint64_t id_aa64mmfr0;
21
#include "hw/or-irq.h"
23
uint64_t id_aa64mmfr1;
22
#include "hw/sysbus.h"
24
uint64_t id_aa64mmfr2;
23
+#include "hw/cpu/a9mpcore.h"
25
+ uint64_t id_aa64mmfr3;
24
#include "target/arm/cpu-qom.h"
26
uint64_t id_aa64dfr0;
25
#include "qom/object.h"
27
uint64_t id_aa64dfr1;
26
28
uint64_t id_aa64zfr0;
27
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
29
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64MMFR2, BBM, 52, 4)
28
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
30
FIELD(ID_AA64MMFR2, EVT, 56, 4)
29
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
31
FIELD(ID_AA64MMFR2, E0PD, 60, 4)
30
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
32
31
+ A9MPPrivState a9mpcore;
33
+FIELD(ID_AA64MMFR3, TCRX, 0, 4)
32
};
34
+FIELD(ID_AA64MMFR3, SCTLRX, 4, 4)
33
35
+FIELD(ID_AA64MMFR3, S1PIE, 8, 4)
34
#define TYPE_EXYNOS4210_SOC "exynos4210"
36
+FIELD(ID_AA64MMFR3, S2PIE, 12, 4)
35
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
37
+FIELD(ID_AA64MMFR3, S1POE, 16, 4)
38
+FIELD(ID_AA64MMFR3, S2POE, 20, 4)
39
+FIELD(ID_AA64MMFR3, AIE, 24, 4)
40
+FIELD(ID_AA64MMFR3, MEC, 28, 4)
41
+FIELD(ID_AA64MMFR3, D128, 32, 4)
42
+FIELD(ID_AA64MMFR3, D128_2, 36, 4)
43
+FIELD(ID_AA64MMFR3, SNERR, 40, 4)
44
+FIELD(ID_AA64MMFR3, ANERR, 44, 4)
45
+FIELD(ID_AA64MMFR3, SDERR, 52, 4)
46
+FIELD(ID_AA64MMFR3, ADERR, 56, 4)
47
+FIELD(ID_AA64MMFR3, SPEC_FPACC, 60, 4)
48
+
49
FIELD(ID_AA64DFR0, DEBUGVER, 0, 4)
50
FIELD(ID_AA64DFR0, TRACEVER, 4, 4)
51
FIELD(ID_AA64DFR0, PMUVER, 8, 4)
52
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/arm/exynos4210.c
54
--- a/target/arm/helper.c
38
+++ b/hw/arm/exynos4210.c
55
+++ b/target/arm/helper.c
39
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
56
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
40
}
57
.access = PL1_R, .type = ARM_CP_CONST,
41
58
.accessfn = access_aa64_tid3,
42
/* Private memory region and Internal GIC */
59
.resetvalue = cpu->isar.id_aa64mmfr2 },
43
- dev = qdev_new(TYPE_A9MPCORE_PRIV);
60
- { .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
44
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
61
+ { .name = "ID_AA64MMFR3_EL1", .state = ARM_CP_STATE_AA64,
45
- busdev = SYS_BUS_DEVICE(dev);
62
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3,
46
- sysbus_realize_and_unref(busdev, &error_fatal);
63
.access = PL1_R, .type = ARM_CP_CONST,
47
+ qdev_prop_set_uint32(DEVICE(&s->a9mpcore), "num-cpu", EXYNOS4210_NCPUS);
64
.accessfn = access_aa64_tid3,
48
+ busdev = SYS_BUS_DEVICE(&s->a9mpcore);
65
- .resetvalue = 0 },
49
+ sysbus_realize(busdev, &error_fatal);
66
+ .resetvalue = cpu->isar.id_aa64mmfr3 },
50
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
67
{ .name = "ID_AA64MMFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
51
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
68
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 4,
52
sysbus_connect_irq(busdev, n,
69
.access = PL1_R, .type = ARM_CP_CONST,
53
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
70
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
54
}
71
.exported_bits = R_ID_AA64MMFR1_AFP_MASK },
55
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
72
{ .name = "ID_AA64MMFR2_EL1",
56
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
73
.exported_bits = R_ID_AA64MMFR2_AT_MASK },
57
+ s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
74
+ { .name = "ID_AA64MMFR3_EL1",
58
}
75
+ .exported_bits = 0 },
59
76
{ .name = "ID_AA64MMFR*_EL1_RESERVED",
60
/* Cache controller */
77
.is_glob = true },
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
78
{ .name = "ID_AA64DFR0_EL1",
62
g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
79
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
63
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
80
index XXXXXXX..XXXXXXX 100644
64
}
81
--- a/target/arm/hvf/hvf.c
65
+
82
+++ b/target/arm/hvf/hvf.c
66
+ object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
83
@@ -XXX,XX +XXX,XX @@ static struct hvf_sreg_match hvf_sreg_match[] = {
67
}
84
#endif
68
85
{ HV_SYS_REG_ID_AA64MMFR1_EL1, HVF_SYSREG(0, 7, 3, 0, 1) },
69
static void exynos4210_class_init(ObjectClass *klass, void *data)
86
{ HV_SYS_REG_ID_AA64MMFR2_EL1, HVF_SYSREG(0, 7, 3, 0, 2) },
87
+ /* Add ID_AA64MMFR3_EL1 here when HVF supports it */
88
89
{ HV_SYS_REG_MDSCR_EL1, HVF_SYSREG(0, 2, 2, 0, 2) },
90
{ HV_SYS_REG_SCTLR_EL1, HVF_SYSREG(1, 0, 3, 0, 0) },
91
@@ -XXX,XX +XXX,XX @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
92
{ HV_SYS_REG_ID_AA64MMFR0_EL1, &host_isar.id_aa64mmfr0 },
93
{ HV_SYS_REG_ID_AA64MMFR1_EL1, &host_isar.id_aa64mmfr1 },
94
{ HV_SYS_REG_ID_AA64MMFR2_EL1, &host_isar.id_aa64mmfr2 },
95
+ /* Add ID_AA64MMFR3_EL1 here when HVF supports it */
96
};
97
hv_vcpu_t fd;
98
hv_return_t r = HV_SUCCESS;
99
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/target/arm/kvm.c
102
+++ b/target/arm/kvm.c
103
@@ -XXX,XX +XXX,XX @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
104
ARM64_SYS_REG(3, 0, 0, 7, 1));
105
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr2,
106
ARM64_SYS_REG(3, 0, 0, 7, 2));
107
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr3,
108
+ ARM64_SYS_REG(3, 0, 0, 7, 3));
109
110
/*
111
* Note that if AArch32 support is not present in the host,
70
--
112
--
71
2.25.1
113
2.34.1
114
115
diff view generated by jsdifflib
1
The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0
1
FEAT_Spec_FPACC is a feature describing speculative behaviour in the
2
and EXT_GIC_ID_MCT_G1 multiple times. This means that we will
2
event of a PAC authontication failure when FEAT_FPACCOMBINE is
3
connect multiple IRQs up to the same external GIC input, which
3
implemented. FEAT_Spec_FPACC means that the speculative use of
4
is not permitted. We do the same thing in the code in
4
pointers processed by a PAC Authentication is not materially
5
exynos4210_init_board_irqs() because the conditionals selecting
5
different in terms of the impact on cached microarchitectural state
6
an irq_id in the first loop match multiple interrupt IDs.
6
(caches, TLBs, etc) between passing and failing of the PAC
7
Authentication.
7
8
8
Overall we do this for interrupt IDs
9
QEMU doesn't do speculative execution, so we can advertise
9
(1, 4), (12, 4), (35, 4), (51, 4), (53, 4) for EXT_GIC_ID_MCT_G0
10
this feature.
10
and
11
(1, 5), (12, 5), (35, 5), (51, 5), (53, 5) for EXT_GIC_ID_MCT_G1
12
13
These correspond to the cases for the multi-core timer that we are
14
wiring up to multiple inputs on the combiner in
15
exynos4210_combiner_get_gpioin(). That code already deals with all
16
these interrupt IDs being the same input source, so we don't need to
17
connect the external GIC interrupt for any of them except the first
18
(1, 4) and (1, 5). Remove the array entries and conditionals which
19
were incorrectly causing us to wire up extra lines.
20
21
This bug didn't cause any visible effects, because we only connect
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
11
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20220404154658.565020-16-peter.maydell@linaro.org
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
Message-id: 20240418152004.2106516-6-peter.maydell@linaro.org
28
---
16
---
29
include/hw/arm/exynos4210.h | 2 +-
17
docs/system/arm/emulation.rst | 1 +
30
hw/arm/exynos4210.c | 12 +++++-------
18
target/arm/tcg/cpu64.c | 4 ++++
31
2 files changed, 6 insertions(+), 8 deletions(-)
19
2 files changed, 5 insertions(+)
32
20
33
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
21
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
34
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
35
--- a/include/hw/arm/exynos4210.h
23
--- a/docs/system/arm/emulation.rst
36
+++ b/include/hw/arm/exynos4210.h
24
+++ b/docs/system/arm/emulation.rst
37
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
38
* one for every non-zero entry in combiner_grp_to_gic_id[].
26
- FEAT_FP16 (Half-precision floating-point data processing)
39
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
27
- FEAT_FPAC (Faulting on AUT* instructions)
40
*/
28
- FEAT_FPACCOMBINE (Faulting on combined pointer authentication instructions)
41
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
29
+- FEAT_FPACC_SPEC (Speculative behavior of combined pointer authentication instructions)
42
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
30
- FEAT_FRINTTS (Floating-point to integer instructions)
43
31
- FEAT_FlagM (Flag manipulation instructions v2)
44
typedef struct Exynos4210Irq {
32
- FEAT_FlagM2 (Enhancements to flag manipulation instructions)
45
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
33
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
47
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/exynos4210.c
35
--- a/target/arm/tcg/cpu64.c
49
+++ b/hw/arm/exynos4210.c
36
+++ b/target/arm/tcg/cpu64.c
50
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
37
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
51
/* int combiner group 34 */
38
t = FIELD_DP64(t, ID_AA64MMFR2, E0PD, 1); /* FEAT_E0PD */
52
{ EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
39
cpu->isar.id_aa64mmfr2 = t;
53
/* int combiner group 35 */
40
54
- { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
41
+ t = cpu->isar.id_aa64mmfr3;
55
+ { 0, 0, 0, EXT_GIC_ID_MCT_L1 },
42
+ t = FIELD_DP64(t, ID_AA64MMFR3, SPEC_FPACC, 1); /* FEAT_FPACC_SPEC */
56
/* int combiner group 36 */
43
+ cpu->isar.id_aa64mmfr3 = t;
57
{ EXT_GIC_ID_MIXER },
44
+
58
/* int combiner group 37 */
45
t = cpu->isar.id_aa64zfr0;
59
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
46
t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1);
60
/* groups 38-50 */
47
t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* FEAT_SVE_PMULL128 */
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
}
89
--
48
--
90
2.25.1
49
2.34.1
50
51
diff view generated by jsdifflib
1
From: Zongyuan Li <zongyuan.li@smartx.com>
1
The Linux kernel 5.10.16 binary for sunxi has been removed from
2
apt.armbian.com. This means that the avocado tests for these machines
3
will be skipped (status CANCEL) if the old binary isn't present in
4
the avocado cache.
2
5
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
6
Update to 6.6.16, in the same way we did in commit e384db41d8661
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
when we moved to 5.10.16 in 2021.
5
Message-id: 20220324181557.203805-3-zongyuan.li@smartx.com
8
9
Cc: qemu-stable@nongnu.org
10
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2284
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
13
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
14
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
15
Message-id: 20240415151845.1564201-1-peter.maydell@linaro.org
7
---
16
---
8
hw/arm/stellaris.c | 15 +++++++++++++--
17
tests/avocado/boot_linux_console.py | 70 ++++++++++++++---------------
9
1 file changed, 13 insertions(+), 2 deletions(-)
18
tests/avocado/replay_kernel.py | 8 ++--
19
2 files changed, 39 insertions(+), 39 deletions(-)
10
20
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
21
diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py
12
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/stellaris.c
23
--- a/tests/avocado/boot_linux_console.py
14
+++ b/hw/arm/stellaris.c
24
+++ b/tests/avocado/boot_linux_console.py
15
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_initrd(self):
16
26
:avocado: tags=accel:tcg
17
#include "qemu/osdep.h"
27
"""
18
#include "qapi/error.h"
28
deb_url = ('https://apt.armbian.com/pool/main/l/'
19
+#include "hw/core/split-irq.h"
29
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
20
#include "hw/sysbus.h"
30
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
21
#include "hw/sd/sd.h"
31
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
22
#include "hw/ssi/ssi.h"
32
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
23
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
33
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
24
DeviceState *ssddev;
34
kernel_path = self.extract_from_deb(deb_path,
25
DriveInfo *dinfo;
35
- '/boot/vmlinuz-5.10.16-sunxi')
26
DeviceState *carddev;
36
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
27
+ DeviceState *gpio_d_splitter;
37
+ '/boot/vmlinuz-6.6.16-current-sunxi')
28
BlockBackend *blk;
38
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb'
29
39
dtb_path = self.extract_from_deb(deb_path, dtb_path)
30
/*
40
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
31
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
41
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
32
&error_fatal);
42
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_sata(self):
33
43
:avocado: tags=accel:tcg
34
ssddev = ssi_create_peripheral(bus, "ssd0323");
44
"""
35
- gpio_out[GPIO_D][0] = qemu_irq_split(
45
deb_url = ('https://apt.armbian.com/pool/main/l/'
36
- qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0),
46
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
37
+
47
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
38
+ gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
48
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
39
+ qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
49
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
40
+ qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
50
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
41
+ qdev_connect_gpio_out(
51
kernel_path = self.extract_from_deb(deb_path,
42
+ gpio_d_splitter, 0,
52
- '/boot/vmlinuz-5.10.16-sunxi')
43
+ qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0));
53
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
44
+ qdev_connect_gpio_out(
54
+ '/boot/vmlinuz-6.6.16-current-sunxi')
45
+ gpio_d_splitter, 1,
55
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb'
46
qdev_get_gpio_in_named(ssddev, SSI_GPIO_CS, 0));
56
dtb_path = self.extract_from_deb(deb_path, dtb_path)
47
+ gpio_out[GPIO_D][0] = qdev_get_gpio_in(gpio_d_splitter, 0);
57
rootfs_url = ('https://github.com/groeck/linux-build-test/raw/'
48
+
58
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
49
gpio_out[GPIO_C][7] = qdev_get_gpio_in(ssddev, 0);
59
@@ -XXX,XX +XXX,XX @@ def test_arm_bpim2u(self):
50
60
:avocado: tags=machine:bpim2u
51
/* Make sure the select pin is high. */
61
:avocado: tags=accel:tcg
62
"""
63
- deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/'
64
- 'linux-image-current-sunxi_21.02.2_armhf.deb')
65
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
66
+ deb_url = ('https://apt.armbian.com/pool/main/l/'
67
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
68
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
69
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
70
kernel_path = self.extract_from_deb(deb_path,
71
- '/boot/vmlinuz-5.10.16-sunxi')
72
- dtb_path = ('/usr/lib/linux-image-current-sunxi/'
73
+ '/boot/vmlinuz-6.6.16-current-sunxi')
74
+ dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/'
75
'sun8i-r40-bananapi-m2-ultra.dtb')
76
dtb_path = self.extract_from_deb(deb_path, dtb_path)
77
78
@@ -XXX,XX +XXX,XX @@ def test_arm_bpim2u_initrd(self):
79
:avocado: tags=accel:tcg
80
:avocado: tags=machine:bpim2u
81
"""
82
- deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/'
83
- 'linux-image-current-sunxi_21.02.2_armhf.deb')
84
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
85
+ deb_url = ('https://apt.armbian.com/pool/main/l/'
86
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
87
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
88
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
89
kernel_path = self.extract_from_deb(deb_path,
90
- '/boot/vmlinuz-5.10.16-sunxi')
91
- dtb_path = ('/usr/lib/linux-image-current-sunxi/'
92
+ '/boot/vmlinuz-6.6.16-current-sunxi')
93
+ dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/'
94
'sun8i-r40-bananapi-m2-ultra.dtb')
95
dtb_path = self.extract_from_deb(deb_path, dtb_path)
96
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
97
@@ -XXX,XX +XXX,XX @@ def test_arm_bpim2u_gmac(self):
98
"""
99
self.require_netdev('user')
100
101
- deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/'
102
- 'linux-image-current-sunxi_21.02.2_armhf.deb')
103
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
104
+ deb_url = ('https://apt.armbian.com/pool/main/l/'
105
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
106
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
107
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
108
kernel_path = self.extract_from_deb(deb_path,
109
- '/boot/vmlinuz-5.10.16-sunxi')
110
- dtb_path = ('/usr/lib/linux-image-current-sunxi/'
111
+ '/boot/vmlinuz-6.6.16-current-sunxi')
112
+ dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/'
113
'sun8i-r40-bananapi-m2-ultra.dtb')
114
dtb_path = self.extract_from_deb(deb_path, dtb_path)
115
rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/'
116
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi(self):
117
:avocado: tags=accel:tcg
118
"""
119
deb_url = ('https://apt.armbian.com/pool/main/l/'
120
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
121
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
122
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
123
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
124
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
125
kernel_path = self.extract_from_deb(deb_path,
126
- '/boot/vmlinuz-5.10.16-sunxi')
127
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
128
+ '/boot/vmlinuz-6.6.16-current-sunxi')
129
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb'
130
dtb_path = self.extract_from_deb(deb_path, dtb_path)
131
132
self.vm.set_console()
133
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_initrd(self):
134
:avocado: tags=machine:orangepi-pc
135
"""
136
deb_url = ('https://apt.armbian.com/pool/main/l/'
137
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
138
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
139
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
140
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
141
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
142
kernel_path = self.extract_from_deb(deb_path,
143
- '/boot/vmlinuz-5.10.16-sunxi')
144
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
145
+ '/boot/vmlinuz-6.6.16-current-sunxi')
146
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb'
147
dtb_path = self.extract_from_deb(deb_path, dtb_path)
148
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
149
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
150
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_sd(self):
151
self.require_netdev('user')
152
153
deb_url = ('https://apt.armbian.com/pool/main/l/'
154
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
155
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
156
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
157
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
158
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
159
kernel_path = self.extract_from_deb(deb_path,
160
- '/boot/vmlinuz-5.10.16-sunxi')
161
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
162
+ '/boot/vmlinuz-6.6.16-current-sunxi')
163
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb'
164
dtb_path = self.extract_from_deb(deb_path, dtb_path)
165
rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/'
166
'buildroot-baseline/20221116.0/armel/rootfs.ext2.xz')
167
diff --git a/tests/avocado/replay_kernel.py b/tests/avocado/replay_kernel.py
168
index XXXXXXX..XXXXXXX 100644
169
--- a/tests/avocado/replay_kernel.py
170
+++ b/tests/avocado/replay_kernel.py
171
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_initrd(self):
172
:avocado: tags=machine:cubieboard
173
"""
174
deb_url = ('https://apt.armbian.com/pool/main/l/'
175
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
176
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
177
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
178
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
179
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
180
kernel_path = self.extract_from_deb(deb_path,
181
- '/boot/vmlinuz-5.10.16-sunxi')
182
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
183
+ '/boot/vmlinuz-6.6.16-current-sunxi')
184
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb'
185
dtb_path = self.extract_from_deb(deb_path, dtb_path)
186
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
187
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
52
--
188
--
53
2.25.1
189
2.34.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
The generic timer frequency is settable by board code via a QOM
2
property "cntfrq", but otherwise defaults to 62.5MHz. The way this
3
is done includes some complication resulting from how this was
4
originally a fixed value with no QOM property. Clean it up:
2
5
3
Add the Cortex-R5Fs of the Versal RPU (Real-time Processing Unit)
6
* always set cpu->gt_cntfrq_hz to some sensible value, whether
4
subsystem.
7
the CPU has the generic timer or not, and whether it's system
8
or user-only emulation
9
* this means we can always use gt_cntfrq_hz, and never need
10
the old GTIMER_SCALE define
11
* set the default value in exactly one place, in the realize fn
5
12
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
13
The aim here is to pave the way for handling the ARMv8.6 requirement
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
14
that the generic timer frequency is always 1GHz. We're going to do
8
Message-id: 20220406174303.2022038-3-edgar.iglesias@xilinx.com
15
that by having old CPU types keep their legacy-in-QEMU behaviour and
16
having the default for any new CPU types be a 1GHz rather han 62.5MHz
17
cntfrq, so we want the point where the default is decided to be in
18
one place, and in code, not in a DEFINE_PROP_UINT64() initializer.
19
20
This commit should have no behavioural changes.
21
9
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>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20240426122913.3427983-2-peter.maydell@linaro.org
10
---
26
---
11
include/hw/arm/xlnx-versal.h | 10 ++++++++++
27
target/arm/internals.h | 7 ++++---
12
hw/arm/xlnx-versal-virt.c | 6 +++---
28
target/arm/cpu.c | 31 +++++++++++++++++--------------
13
hw/arm/xlnx-versal.c | 36 ++++++++++++++++++++++++++++++++++++
29
target/arm/helper.c | 16 ++++++++--------
14
3 files changed, 49 insertions(+), 3 deletions(-)
30
3 files changed, 29 insertions(+), 25 deletions(-)
15
31
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
32
diff --git a/target/arm/internals.h b/target/arm/internals.h
17
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
34
--- a/target/arm/internals.h
19
+++ b/include/hw/arm/xlnx-versal.h
35
+++ b/target/arm/internals.h
20
@@ -XXX,XX +XXX,XX @@
36
@@ -XXX,XX +XXX,XX @@ static inline bool excp_is_internal(int excp)
21
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
37
|| excp == EXCP_SEMIHOST;
22
38
}
23
#define XLNX_VERSAL_NR_ACPUS 2
39
24
+#define XLNX_VERSAL_NR_RCPUS 2
40
-/* Scale factor for generic timers, ie number of ns per tick.
25
#define XLNX_VERSAL_NR_UARTS 2
41
- * This gives a 62.5MHz timer.
26
#define XLNX_VERSAL_NR_GEMS 2
42
+/*
27
#define XLNX_VERSAL_NR_ADMAS 8
43
+ * Default frequency for the generic timer, in Hz.
28
@@ -XXX,XX +XXX,XX @@ struct Versal {
44
+ * This is 62.5MHz, which gives a 16 ns tick period.
29
VersalUsb2 usb;
45
*/
30
} iou;
46
-#define GTIMER_SCALE 16
31
47
+#define GTIMER_DEFAULT_HZ 62500000
32
+ /* Real-time Processing Unit. */
48
33
+ struct {
49
/* Bit definitions for the v7M CONTROL register */
34
+ MemoryRegion mr;
50
FIELD(V7M_CONTROL, NPRIV, 0, 1)
35
+ MemoryRegion mr_ps_alias;
51
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
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
52
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/xlnx-versal-virt.c
53
--- a/target/arm/cpu.c
47
+++ b/hw/arm/xlnx-versal-virt.c
54
+++ b/target/arm/cpu.c
48
@@ -XXX,XX +XXX,XX @@ static void versal_virt_machine_class_init(ObjectClass *oc, void *data)
55
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_initfn(Object *obj)
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
}
56
}
75
}
57
}
76
58
77
+static void versal_create_rpu_cpus(Versal *s)
59
+/*
78
+{
60
+ * 0 means "unset, use the default value". That default might vary depending
79
+ int i;
61
+ * on the CPU type, and is set in the realize fn.
80
+
62
+ */
81
+ object_initialize_child(OBJECT(s), "rpu-cluster", &s->lpd.rpu.cluster,
63
static Property arm_cpu_gt_cntfrq_property =
82
+ TYPE_CPU_CLUSTER);
64
- DEFINE_PROP_UINT64("cntfrq", ARMCPU, gt_cntfrq_hz,
83
+ qdev_prop_set_uint32(DEVICE(&s->lpd.rpu.cluster), "cluster-id", 1);
65
- NANOSECONDS_PER_SECOND / GTIMER_SCALE);
84
+
66
+ DEFINE_PROP_UINT64("cntfrq", ARMCPU, gt_cntfrq_hz, 0);
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
67
86
+ Object *obj;
68
static Property arm_cpu_reset_cbar_property =
87
+
69
DEFINE_PROP_UINT64("reset-cbar", ARMCPU, reset_cbar, 0);
88
+ object_initialize_child(OBJECT(&s->lpd.rpu.cluster),
70
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
89
+ "rpu-cpu[*]", &s->lpd.rpu.cpu[i],
71
return;
90
+ XLNX_VERSAL_RCPU_TYPE);
72
}
91
+ obj = OBJECT(&s->lpd.rpu.cpu[i]);
73
92
+ object_property_set_bool(obj, "start-powered-off", true,
74
+ if (!cpu->gt_cntfrq_hz) {
93
+ &error_abort);
75
+ /*
94
+
76
+ * 0 means "the board didn't set a value, use the default".
95
+ object_property_set_int(obj, "mp-affinity", 0x100 | i, &error_abort);
77
+ * The default value of the generic timer frequency (as seen in
96
+ object_property_set_int(obj, "core-count", ARRAY_SIZE(s->lpd.rpu.cpu),
78
+ * CNTFRQ_EL0) is 62.5MHz, which corresponds to a period of 16ns.
97
+ &error_abort);
79
+ * This is what you get (a) for a CONFIG_USER_ONLY CPU (b) if the
98
+ object_property_set_link(obj, "memory", OBJECT(&s->lpd.rpu.mr),
80
+ * board doesn't set it.
99
+ &error_abort);
81
+ */
100
+ qdev_realize(DEVICE(obj), NULL, &error_fatal);
82
+ cpu->gt_cntfrq_hz = GTIMER_DEFAULT_HZ;
101
+ }
83
+ }
102
+
84
+
103
+ qdev_realize(DEVICE(&s->lpd.rpu.cluster), NULL, &error_fatal);
85
#ifndef CONFIG_USER_ONLY
86
/* The NVIC and M-profile CPU are two halves of a single piece of
87
* hardware; trying to use one without the other is a command line
88
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
89
}
90
91
{
92
- uint64_t scale;
93
-
94
- if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
95
- if (!cpu->gt_cntfrq_hz) {
96
- error_setg(errp, "Invalid CNTFRQ: %"PRId64"Hz",
97
- cpu->gt_cntfrq_hz);
98
- return;
99
- }
100
- scale = gt_cntfrq_period_ns(cpu);
101
- } else {
102
- scale = GTIMER_SCALE;
103
- }
104
+ uint64_t scale = gt_cntfrq_period_ns(cpu);
105
106
cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
107
arm_gt_ptimer_cb, cpu);
108
diff --git a/target/arm/helper.c b/target/arm/helper.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/target/arm/helper.c
111
+++ b/target/arm/helper.c
112
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
113
.resetvalue = 0 },
114
};
115
116
+static void arm_gt_cntfrq_reset(CPUARMState *env, const ARMCPRegInfo *opaque)
117
+{
118
+ ARMCPU *cpu = env_archcpu(env);
119
+
120
+ cpu->env.cp15.c14_cntfrq = cpu->gt_cntfrq_hz;
104
+}
121
+}
105
+
122
+
106
static void versal_create_uarts(Versal *s, qemu_irq *pic)
123
#ifndef CONFIG_USER_ONLY
107
{
124
108
int i;
125
static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri,
109
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
126
@@ -XXX,XX +XXX,XX @@ void arm_gt_hvtimer_cb(void *opaque)
110
127
gt_recalc_timer(cpu, GTIMER_HYPVIRT);
111
versal_create_apu_cpus(s);
112
versal_create_apu_gic(s, pic);
113
+ versal_create_rpu_cpus(s);
114
versal_create_uarts(s, pic);
115
versal_create_usbs(s, pic);
116
versal_create_gems(s, pic);
117
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
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
}
128
}
124
129
125
static void versal_init(Object *obj)
130
-static void arm_gt_cntfrq_reset(CPUARMState *env, const ARMCPRegInfo *opaque)
126
@@ -XXX,XX +XXX,XX @@ static void versal_init(Object *obj)
131
-{
127
Versal *s = XLNX_VERSAL(obj);
132
- ARMCPU *cpu = env_archcpu(env);
128
133
-
129
memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
134
- cpu->env.cp15.c14_cntfrq = cpu->gt_cntfrq_hz;
130
+ memory_region_init(&s->lpd.rpu.mr, obj, "mr-rpu", UINT64_MAX);
135
-}
131
memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX);
136
-
132
+ memory_region_init_alias(&s->lpd.rpu.mr_ps_alias, OBJECT(s),
137
static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
133
+ "mr-rpu-ps-alias", &s->mr_ps, 0, UINT64_MAX);
138
/*
134
}
139
* Note that CNTFRQ is purely reads-as-written for the benefit
135
140
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
136
static Property versal_properties[] = {
141
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0,
142
.type = ARM_CP_CONST, .access = PL0_R /* no PL1_RW in linux-user */,
143
.fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
144
- .resetvalue = NANOSECONDS_PER_SECOND / GTIMER_SCALE,
145
+ .resetfn = arm_gt_cntfrq_reset,
146
},
147
{ .name = "CNTVCT_EL0", .state = ARM_CP_STATE_AA64,
148
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 2,
137
--
149
--
138
2.25.1
150
2.34.1
151
152
diff view generated by jsdifflib
1
At this point, the function exynos4210_init_board_irqs() splits input
1
Currently QEMU CPUs always run with a generic timer counter frequency
2
IRQ lines to connect them to the input combiner, output combiner and
2
of 62.5MHz, but ARMv8.6 CPUs will run at 1GHz. For older versions of
3
external GIC. The function exynos4210_combiner_get_gpioin() splits
3
the TF-A firmware that sbsa-ref runs, the frequency of the generic
4
some of the combiner input lines further to connect them to multiple
4
timer is hardcoded into the firmware, and so if the CPU actually has
5
different inputs on the combiner.
5
a different frequency then timers in the guest will be set
6
incorrectly.
6
7
7
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
8
The default frequency used by the 'max' CPU is about to change, so
8
configurable number of outputs, we can do all this in one place, by
9
make the sbsa-ref board force the CPU frequency to the value which
9
making exynos4210_init_board_irqs() add extra outputs to the splitter
10
the firmware expects.
10
device when it must be connected to more than one input on each
11
combiner.
12
11
13
We do this with a new data structure, the combinermap, which is an
12
Newer versions of TF-A will read the frequency from the CPU's
14
array each of whose elements is a list of the interrupt IDs on the
13
CNTFRQ_EL0 register:
15
combiner which must be tied together. As we loop through each
14
https://github.com/ARM-software/arm-trusted-firmware/commit/4c77fac98dac0bebc63798aae9101ac865b87148
16
interrupt ID, if we find that it is the first one in one of these
15
so in the longer term we could make this board use the 1GHz
17
lists, we configure the splitter device with eonugh extra outputs and
16
frequency. We will need to make sure we update the binaries used
18
wire them up to the other interrupt IDs in the list.
17
by our avocado test
19
18
Aarch64SbsarefMachine.test_sbsaref_alpine_linux_max_pauth_impdef
20
Conveniently, for all the cases where this is necessary, the
19
before we can do that.
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
20
39
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
40
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
41
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
23
Reviewed-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
24
Message-id: 20240426122913.3427983-3-peter.maydell@linaro.org
42
---
25
---
43
include/hw/arm/exynos4210.h | 6 +-
26
hw/arm/sbsa-ref.c | 15 +++++++++++++++
44
hw/arm/exynos4210.c | 178 +++++++++++++++++++++++-------------
27
1 file changed, 15 insertions(+)
45
2 files changed, 119 insertions(+), 65 deletions(-)
46
28
47
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
29
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
48
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
49
--- a/include/hw/arm/exynos4210.h
31
--- a/hw/arm/sbsa-ref.c
50
+++ b/include/hw/arm/exynos4210.h
32
+++ b/hw/arm/sbsa-ref.c
51
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@
52
34
#define NUM_SMMU_IRQS 4
53
/*
35
#define NUM_SATA_PORTS 6
54
* We need one splitter for every external combiner input, plus
55
- * one for every non-zero entry in combiner_grp_to_gic_id[].
56
+ * one for every non-zero entry in combiner_grp_to_gic_id[],
57
+ * minus one for every external combiner ID in second or later
58
+ * places in a combinermap[] line.
59
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
60
*/
61
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
62
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
63
64
typedef struct Exynos4210Irq {
65
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
66
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/exynos4210.c
69
+++ b/hw/arm/exynos4210.c
70
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
71
#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
72
((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
73
36
74
+/*
37
+/*
75
+ * Some interrupt lines go to multiple combiner inputs.
38
+ * Generic timer frequency in Hz (which drives both the CPU generic timers
76
+ * This data structure defines those: each array element is
39
+ * and the SBSA watchdog-timer). Older versions of the TF-A firmware
77
+ * a list of combiner inputs which are connected together;
40
+ * typically used with sbsa-ref (including the binaries in our Avocado test
78
+ * the one with the smallest interrupt ID value must be first.
41
+ * Aarch64SbsarefMachine.test_sbsaref_alpine_linux_max_pauth_impdef
79
+ * As with combiner_grp_to_gic_id[], we rely on (0, 0) not being
42
+ * assume it is this value.
80
+ * wired to anything so we can use 0 as a terminator.
43
+ *
44
+ * TODO: this value is not architecturally correct for an Armv8.6 or
45
+ * better CPU, so we should move to 1GHz once the TF-A fix above has
46
+ * made it into a release and into our Avocado test.
81
+ */
47
+ */
82
+#define IRQNO(G, B) EXYNOS4210_COMBINER_GET_IRQ_NUM(G, B)
48
+#define SBSA_GTIMER_HZ 62500000
83
+#define IRQNONE 0
84
+
49
+
85
+#define COMBINERMAP_SIZE 16
50
enum {
51
SBSA_FLASH,
52
SBSA_MEM,
53
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
54
&error_abort);
55
}
56
57
+ object_property_set_int(cpuobj, "cntfrq", SBSA_GTIMER_HZ, &error_abort);
86
+
58
+
87
+static const int combinermap[COMBINERMAP_SIZE][6] = {
59
object_property_set_link(cpuobj, "memory", OBJECT(sysmem),
88
+ /* MDNIE_LCD1 */
60
&error_abort);
89
+ { IRQNO(0, 4), IRQNO(1, 0), IRQNONE },
61
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
+{
114
+ /*
115
+ * If the interrupt number passed in is the first entry in some
116
+ * line of the combinermap, return a pointer to that line;
117
+ * otherwise return NULL.
118
+ */
119
+ int i;
120
+ for (i = 0; i < COMBINERMAP_SIZE; i++) {
121
+ if (combinermap[i][0] == irq) {
122
+ return combinermap[i];
123
+ }
124
+ }
125
+ return NULL;
126
+}
127
+
128
+static int mapline_size(const int *mapline)
129
+{
130
+ /* Return number of entries in this mapline in total */
131
+ int i = 0;
132
+
133
+ if (!mapline) {
134
+ /* Not in the map? IRQ goes to exactly one combiner input */
135
+ return 1;
136
+ }
137
+ while (*mapline != IRQNONE) {
138
+ mapline++;
139
+ i++;
140
+ }
141
+ return i;
142
+}
143
+
144
/*
145
* Initialize board IRQs.
146
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
147
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
148
DeviceState *extgicdev = DEVICE(&s->ext_gic);
149
int splitcount = 0;
150
DeviceState *splitter;
151
+ const int *mapline;
152
+ int numlines, splitin, in;
153
154
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
155
irq_id = 0;
156
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
157
irq_id = EXT_GIC_ID_MCT_G1;
158
}
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
}
207
}
208
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
209
irq_id = combiner_grp_to_gic_id[grp -
210
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
211
212
+ if (s->irq_table[n]) {
213
+ /*
214
+ * This must be some non-first entry in a combinermap line,
215
+ * and we've already filled it in.
216
+ */
217
+ continue;
218
+ }
219
+
220
if (irq_id) {
221
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
222
splitter = DEVICE(&s->splitter[splitcount]);
223
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
224
DeviceState *dev, int ext)
225
{
226
int n;
227
- int bit;
228
int max;
229
qemu_irq *irq;
230
231
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
232
EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
233
irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
234
235
- /*
236
- * Some IRQs of Int/External Combiner are going to two Combiners groups,
237
- * so let split them.
238
- */
239
for (n = 0; n < max; n++) {
240
-
241
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
242
-
243
- switch (n) {
244
- /* MDNIE_LCD1 INTG1 */
245
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
246
- EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
247
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
248
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
249
- continue;
250
-
251
- /* TMU INTG3 */
252
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
253
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
254
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
255
- continue;
256
-
257
- /* LCD1 INTG12 */
258
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
259
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
260
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
261
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
262
- continue;
263
-
264
- /* Multi-Core Timer INTG12 */
265
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
266
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
267
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
268
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
269
- continue;
270
-
271
- /* Multi-Core Timer INTG35 */
272
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
273
- EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
274
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
275
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
276
- continue;
277
-
278
- /* Multi-Core Timer INTG51 */
279
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
280
- EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
281
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
282
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
283
- continue;
284
-
285
- /* Multi-Core Timer INTG53 */
286
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
287
- EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
288
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
289
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
290
- continue;
291
- }
292
-
293
irq[n] = qdev_get_gpio_in(dev, n);
294
}
295
}
296
--
62
--
297
2.25.1
63
2.34.1
64
65
diff view generated by jsdifflib
1
Switch the creation of the external GIC to the new-style "embedded in
1
Currently the sbsa_gdwt watchdog device hardcodes its frequency at
2
state struct" approach, so we can easily refer to the object
2
62.5MHz. In real hardware, this watchdog is supposed to be driven
3
elsewhere during realize.
3
from the system counter, which also drives the CPU generic timers.
4
Newer CPU types (in particular from Armv8.6) should have a CPU
5
generic timer frequency of 1GHz, so we can't leave the watchdog
6
on the old QEMU default of 62.5GHz.
7
8
Make the frequency a QOM property so it can be set by the board,
9
and have our only board that uses this device set that frequency
10
to the same value it sets the CPU frequency.
4
11
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20220404154658.565020-9-peter.maydell@linaro.org
14
Message-id: 20240426122913.3427983-4-peter.maydell@linaro.org
8
---
15
---
9
include/hw/arm/exynos4210.h | 2 ++
16
include/hw/watchdog/sbsa_gwdt.h | 3 +--
10
include/hw/intc/exynos4210_gic.h | 43 ++++++++++++++++++++++++++++++++
17
hw/arm/sbsa-ref.c | 1 +
11
hw/arm/exynos4210.c | 10 ++++----
18
hw/watchdog/sbsa_gwdt.c | 15 ++++++++++++++-
12
hw/intc/exynos4210_gic.c | 17 ++-----------
19
3 files changed, 16 insertions(+), 3 deletions(-)
13
MAINTAINERS | 2 +-
14
5 files changed, 53 insertions(+), 21 deletions(-)
15
create mode 100644 include/hw/intc/exynos4210_gic.h
16
20
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
21
diff --git a/include/hw/watchdog/sbsa_gwdt.h b/include/hw/watchdog/sbsa_gwdt.h
18
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
23
--- a/include/hw/watchdog/sbsa_gwdt.h
20
+++ b/include/hw/arm/exynos4210.h
24
+++ b/include/hw/watchdog/sbsa_gwdt.h
21
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@
22
#include "hw/or-irq.h"
26
#define SBSA_GWDT_RMMIO_SIZE 0x1000
23
#include "hw/sysbus.h"
27
#define SBSA_GWDT_CMMIO_SIZE 0x1000
24
#include "hw/cpu/a9mpcore.h"
28
25
+#include "hw/intc/exynos4210_gic.h"
29
-#define SBSA_TIMER_FREQ 62500000 /* Hz */
26
#include "target/arm/cpu-qom.h"
30
-
27
#include "qom/object.h"
31
typedef struct SBSA_GWDTState {
28
32
/* <private> */
29
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
33
SysBusDevice parent_obj;
30
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
34
@@ -XXX,XX +XXX,XX @@ typedef struct SBSA_GWDTState {
31
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
35
qemu_irq irq;
32
A9MPPrivState a9mpcore;
36
33
+ Exynos4210GicState ext_gic;
37
QEMUTimer *timer;
34
};
38
+ uint64_t freq;
35
39
36
#define TYPE_EXYNOS4210_SOC "exynos4210"
40
uint32_t id;
37
diff --git a/include/hw/intc/exynos4210_gic.h b/include/hw/intc/exynos4210_gic.h
41
uint32_t wcs;
38
new file mode 100644
42
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
39
index XXXXXXX..XXXXXXX
43
index XXXXXXX..XXXXXXX 100644
40
--- /dev/null
44
--- a/hw/arm/sbsa-ref.c
41
+++ b/include/hw/intc/exynos4210_gic.h
45
+++ b/hw/arm/sbsa-ref.c
46
@@ -XXX,XX +XXX,XX @@ static void create_wdt(const SBSAMachineState *sms)
47
SysBusDevice *s = SYS_BUS_DEVICE(dev);
48
int irq = sbsa_ref_irqmap[SBSA_GWDT_WS0];
49
50
+ qdev_prop_set_uint64(dev, "clock-frequency", SBSA_GTIMER_HZ);
51
sysbus_realize_and_unref(s, &error_fatal);
52
sysbus_mmio_map(s, 0, rbase);
53
sysbus_mmio_map(s, 1, cbase);
54
diff --git a/hw/watchdog/sbsa_gwdt.c b/hw/watchdog/sbsa_gwdt.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/watchdog/sbsa_gwdt.c
57
+++ b/hw/watchdog/sbsa_gwdt.c
42
@@ -XXX,XX +XXX,XX @@
58
@@ -XXX,XX +XXX,XX @@
43
+/*
59
#include "qemu/osdep.h"
44
+ * Samsung exynos4210 GIC implementation. Based on hw/arm_gic.c
60
#include "sysemu/reset.h"
45
+ *
61
#include "sysemu/watchdog.h"
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
62
+#include "hw/qdev-properties.h"
47
+ * All rights reserved.
63
#include "hw/watchdog/sbsa_gwdt.h"
48
+ *
64
#include "qemu/timer.h"
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
65
#include "migration/vmstate.h"
50
+ *
66
@@ -XXX,XX +XXX,XX @@ static void sbsa_gwdt_update_timer(SBSA_GWDTState *s, WdtRefreshType rtype)
51
+ * This program is free software; you can redistribute it and/or modify it
67
timeout = s->woru;
52
+ * under the terms of the GNU General Public License as published by the
68
timeout <<= 32;
53
+ * Free Software Foundation; either version 2 of the License, or (at your
69
timeout |= s->worl;
54
+ * option) any later version.
70
- timeout = muldiv64(timeout, NANOSECONDS_PER_SECOND, SBSA_TIMER_FREQ);
55
+ *
71
+ timeout = muldiv64(timeout, NANOSECONDS_PER_SECOND, s->freq);
56
+ * This program is distributed in the hope that it will be useful,
72
timeout += qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
73
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
74
if ((rtype == EXPLICIT_REFRESH) || ((rtype == TIMEOUT_REFRESH) &&
59
+ * See the GNU General Public License for more details.
75
@@ -XXX,XX +XXX,XX @@ static void wdt_sbsa_gwdt_realize(DeviceState *dev, Error **errp)
60
+ *
76
dev);
61
+ * You should have received a copy of the GNU General Public License along
77
}
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
78
63
+ */
79
+static Property wdt_sbsa_gwdt_props[] = {
64
+#ifndef HW_INTC_EXYNOS4210_GIC_H
80
+ /*
65
+#define HW_INTC_EXYNOS4210_GIC_H
81
+ * Timer frequency in Hz. This must match the frequency used by
66
+
82
+ * the CPU's generic timer. Default 62.5Hz matches QEMU's legacy
67
+#include "hw/sysbus.h"
83
+ * CPU timer frequency default.
68
+
84
+ */
69
+#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
85
+ DEFINE_PROP_UINT64("clock-frequency", struct SBSA_GWDTState, freq,
70
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
86
+ 62500000),
71
+
87
+ DEFINE_PROP_END_OF_LIST(),
72
+#define EXYNOS4210_GIC_NCPUS 2
73
+
74
+struct Exynos4210GicState {
75
+ SysBusDevice parent_obj;
76
+
77
+ MemoryRegion cpu_container;
78
+ MemoryRegion dist_container;
79
+ MemoryRegion cpu_alias[EXYNOS4210_GIC_NCPUS];
80
+ MemoryRegion dist_alias[EXYNOS4210_GIC_NCPUS];
81
+ uint32_t num_cpu;
82
+ DeviceState *gic;
83
+};
88
+};
84
+
89
+
85
+#endif
90
static void wdt_sbsa_gwdt_class_init(ObjectClass *klass, void *data)
86
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
91
{
87
index XXXXXXX..XXXXXXX 100644
92
DeviceClass *dc = DEVICE_CLASS(klass);
88
--- a/hw/arm/exynos4210.c
93
@@ -XXX,XX +XXX,XX @@ static void wdt_sbsa_gwdt_class_init(ObjectClass *klass, void *data)
89
+++ b/hw/arm/exynos4210.c
94
set_bit(DEVICE_CATEGORY_WATCHDOG, dc->categories);
90
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
95
dc->vmsd = &vmstate_sbsa_gwdt;
91
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
96
dc->desc = "SBSA-compliant generic watchdog device";
92
97
+ device_class_set_props(dc, wdt_sbsa_gwdt_props);
93
/* External GIC */
94
- dev = qdev_new("exynos4210.gic");
95
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
96
- busdev = SYS_BUS_DEVICE(dev);
97
- sysbus_realize_and_unref(busdev, &error_fatal);
98
+ qdev_prop_set_uint32(DEVICE(&s->ext_gic), "num-cpu", EXYNOS4210_NCPUS);
99
+ busdev = SYS_BUS_DEVICE(&s->ext_gic);
100
+ sysbus_realize(busdev, &error_fatal);
101
/* Map CPU interface */
102
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
103
/* Map Distributer interface */
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
105
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
106
}
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
}
98
}
119
99
120
static void exynos4210_class_init(ObjectClass *klass, void *data)
100
static const TypeInfo wdt_sbsa_gwdt_info = {
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
--
101
--
177
2.25.1
102
2.34.1
103
104
diff view generated by jsdifflib
1
The Exynos4210 SoC device currently uses a custom device
1
In previous versions of the Arm architecture, the frequency of the
2
"exynos4210.irq_gate" to model the OR gate that feeds each CPU's IRQ
2
generic timers as reported in CNTFRQ_EL0 could be any IMPDEF value,
3
line. We have a standard TYPE_OR_IRQ device for this now, so use
3
and for QEMU we picked 62.5MHz, giving a timer tick period of 16ns.
4
that instead.
4
In Armv8.6, the architecture standardized this frequency to 1GHz.
5
5
6
(This is a migration compatibility break, but that is OK for this
6
Because there is no ID register feature field that indicates whether
7
machine type.)
7
a CPU is v8.6 or that it ought to have this counter frequency, we
8
implement this by changing our default CNTFRQ value for all CPUs,
9
with exceptions for backwards compatibility:
10
11
* CPU types which we already implement will retain the old
12
default value. None of these are v8.6 CPUs, so this is
13
architecturally OK.
14
* CPUs used in versioned machine types with a version of 9.0
15
or earlier will retain the old default value.
16
17
The upshot is that the only CPU type that changes is 'max'; but any
18
new type we add in future (whether v8.6 or not) will also get the new
19
1GHz default.
20
21
It remains the case that the machine model can override the default
22
value via the 'cntfrq' QOM property (regardless of the CPU type).
8
23
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-2-peter.maydell@linaro.org
26
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
27
Message-id: 20240426122913.3427983-5-peter.maydell@linaro.org
12
---
28
---
13
include/hw/arm/exynos4210.h | 1 +
29
target/arm/cpu.h | 11 +++++++++++
14
hw/arm/exynos4210.c | 31 ++++++++++++++++---------------
30
target/arm/internals.h | 12 ++++++++++--
15
2 files changed, 17 insertions(+), 15 deletions(-)
31
hw/core/machine.c | 4 +++-
16
32
target/arm/cpu.c | 23 +++++++++++++++++------
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
33
target/arm/cpu64.c | 2 ++
18
index XXXXXXX..XXXXXXX 100644
34
target/arm/tcg/cpu32.c | 4 ++++
19
--- a/include/hw/arm/exynos4210.h
35
target/arm/tcg/cpu64.c | 18 ++++++++++++++++++
20
+++ b/include/hw/arm/exynos4210.h
36
7 files changed, 65 insertions(+), 9 deletions(-)
21
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
37
22
MemoryRegion bootreg_mem;
38
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
39
index XXXXXXX..XXXXXXX 100644
24
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
40
--- a/target/arm/cpu.h
25
+ qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
41
+++ b/target/arm/cpu.h
42
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
43
*/
44
bool host_cpu_probe_failed;
45
46
+ /* QOM property to indicate we should use the back-compat CNTFRQ default */
47
+ bool backcompat_cntfrq;
48
+
49
/* Specify the number of cores in this CPU cluster. Used for the L2CTLR
50
* register.
51
*/
52
@@ -XXX,XX +XXX,XX @@ enum arm_features {
53
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
54
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
55
ARM_FEATURE_V8_1M, /* M profile extras only in v8.1M and later */
56
+ /*
57
+ * ARM_FEATURE_BACKCOMPAT_CNTFRQ makes the CPU default cntfrq be 62.5MHz
58
+ * if the board doesn't set a value, instead of 1GHz. It is for backwards
59
+ * compatibility and used only with CPU definitions that were already
60
+ * in QEMU before we changed the default. It should not be set on any
61
+ * CPU types added in future.
62
+ */
63
+ ARM_FEATURE_BACKCOMPAT_CNTFRQ, /* 62.5MHz timer default */
26
};
64
};
27
65
28
#define TYPE_EXYNOS4210_SOC "exynos4210"
66
static inline int arm_feature(CPUARMState *env, int feature)
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
67
diff --git a/target/arm/internals.h b/target/arm/internals.h
30
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
69
--- a/target/arm/internals.h
32
+++ b/hw/arm/exynos4210.c
70
+++ b/target/arm/internals.h
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
71
@@ -XXX,XX +XXX,XX @@ static inline bool excp_is_internal(int excp)
34
{
72
35
Exynos4210State *s = EXYNOS4210_SOC(socdev);
73
/*
36
MemoryRegion *system_mem = get_system_memory();
74
* Default frequency for the generic timer, in Hz.
37
- qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
75
- * This is 62.5MHz, which gives a 16 ns tick period.
38
SysBusDevice *busdev;
76
+ * ARMv8.6 and later CPUs architecturally must use a 1GHz timer; before
39
DeviceState *dev, *uart[4], *pl330[3];
77
+ * that it was an IMPDEF choice, and QEMU initially picked 62.5MHz,
40
int i, n;
78
+ * which gives a 16ns tick period.
41
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
79
+ *
42
80
+ * We will use the back-compat value:
43
/* IRQ Gate */
81
+ * - for QEMU CPU types added before we standardized on 1GHz
44
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
82
+ * - for versioned machine types with a version of 9.0 or earlier
45
- dev = qdev_new("exynos4210.irq_gate");
83
+ * In any case, the machine model may override via the cntfrq property.
46
- qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
84
*/
47
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
85
-#define GTIMER_DEFAULT_HZ 62500000
48
- /* Get IRQ Gate input in gate_irq */
86
+#define GTIMER_DEFAULT_HZ 1000000000
49
- for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
87
+#define GTIMER_BACKCOMPAT_HZ 62500000
50
- gate_irq[i][n] = qdev_get_gpio_in(dev, n);
88
51
- }
89
/* Bit definitions for the v7M CONTROL register */
52
- busdev = SYS_BUS_DEVICE(dev);
90
FIELD(V7M_CONTROL, NPRIV, 0, 1)
53
-
91
diff --git a/hw/core/machine.c b/hw/core/machine.c
54
- /* Connect IRQ Gate output to CPU's IRQ line */
92
index XXXXXXX..XXXXXXX 100644
55
- sysbus_connect_irq(busdev, 0,
93
--- a/hw/core/machine.c
56
- qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
94
+++ b/hw/core/machine.c
57
+ DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
95
@@ -XXX,XX +XXX,XX @@
58
+ object_property_set_int(OBJECT(orgate), "num-lines",
96
#include "hw/virtio/virtio-iommu.h"
59
+ EXYNOS4210_IRQ_GATE_NINPUTS,
97
#include "audio/audio.h"
60
+ &error_abort);
98
61
+ qdev_realize(orgate, NULL, &error_abort);
99
-GlobalProperty hw_compat_9_0[] = {};
62
+ qdev_connect_gpio_out(orgate, 0,
100
+GlobalProperty hw_compat_9_0[] = {
63
+ qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
101
+ {"arm-cpu", "backcompat-cntfrq", "true" },
102
+};
103
const size_t hw_compat_9_0_len = G_N_ELEMENTS(hw_compat_9_0);
104
105
GlobalProperty hw_compat_8_2[] = {
106
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/cpu.c
109
+++ b/target/arm/cpu.c
110
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
111
112
if (!cpu->gt_cntfrq_hz) {
113
/*
114
- * 0 means "the board didn't set a value, use the default".
115
- * The default value of the generic timer frequency (as seen in
116
- * CNTFRQ_EL0) is 62.5MHz, which corresponds to a period of 16ns.
117
- * This is what you get (a) for a CONFIG_USER_ONLY CPU (b) if the
118
- * board doesn't set it.
119
+ * 0 means "the board didn't set a value, use the default". (We also
120
+ * get here for the CONFIG_USER_ONLY case.)
121
+ * ARMv8.6 and later CPUs architecturally must use a 1GHz timer; before
122
+ * that it was an IMPDEF choice, and QEMU initially picked 62.5MHz,
123
+ * which gives a 16ns tick period.
124
+ *
125
+ * We will use the back-compat value:
126
+ * - for QEMU CPU types added before we standardized on 1GHz
127
+ * - for versioned machine types with a version of 9.0 or earlier
128
*/
129
- cpu->gt_cntfrq_hz = GTIMER_DEFAULT_HZ;
130
+ if (arm_feature(env, ARM_FEATURE_BACKCOMPAT_CNTFRQ) ||
131
+ cpu->backcompat_cntfrq) {
132
+ cpu->gt_cntfrq_hz = GTIMER_BACKCOMPAT_HZ;
133
+ } else {
134
+ cpu->gt_cntfrq_hz = GTIMER_DEFAULT_HZ;
135
+ }
64
}
136
}
65
137
66
/* Private memory region and Internal GIC */
138
#ifndef CONFIG_USER_ONLY
67
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
139
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_properties[] = {
68
sysbus_realize_and_unref(busdev, &error_fatal);
140
mp_affinity, ARM64_AFFINITY_INVALID),
69
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
141
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
70
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
142
DEFINE_PROP_INT32("core-count", ARMCPU, core_count, -1),
71
- sysbus_connect_irq(busdev, n, gate_irq[n][0]);
143
+ /* True to default to the backward-compat old CNTFRQ rather than 1Ghz */
72
+ sysbus_connect_irq(busdev, n,
144
+ DEFINE_PROP_BOOL("backcompat-cntfrq", ARMCPU, backcompat_cntfrq, false),
73
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
145
DEFINE_PROP_END_OF_LIST()
74
}
146
};
75
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
147
76
s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
148
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
77
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
149
index XXXXXXX..XXXXXXX 100644
78
/* Map Distributer interface */
150
--- a/target/arm/cpu64.c
79
sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
151
+++ b/target/arm/cpu64.c
80
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
152
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
81
- sysbus_connect_irq(busdev, n, gate_irq[n][1]);
153
set_feature(&cpu->env, ARM_FEATURE_V8);
82
+ sysbus_connect_irq(busdev, n,
154
set_feature(&cpu->env, ARM_FEATURE_NEON);
83
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
155
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
84
}
156
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
85
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
157
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
86
s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
158
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
87
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
159
set_feature(&cpu->env, ARM_FEATURE_EL2);
88
object_initialize_child(obj, name, orgate, TYPE_OR_IRQ);
160
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
89
g_free(name);
161
set_feature(&cpu->env, ARM_FEATURE_V8);
90
}
162
set_feature(&cpu->env, ARM_FEATURE_NEON);
163
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
164
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
165
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
166
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
167
set_feature(&cpu->env, ARM_FEATURE_EL2);
168
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
169
index XXXXXXX..XXXXXXX 100644
170
--- a/target/arm/tcg/cpu32.c
171
+++ b/target/arm/tcg/cpu32.c
172
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
173
set_feature(&cpu->env, ARM_FEATURE_NEON);
174
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
175
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
176
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
177
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
178
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
179
set_feature(&cpu->env, ARM_FEATURE_EL2);
180
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
181
set_feature(&cpu->env, ARM_FEATURE_NEON);
182
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
183
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
184
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
185
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
186
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
187
set_feature(&cpu->env, ARM_FEATURE_EL2);
188
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
189
set_feature(&cpu->env, ARM_FEATURE_PMSA);
190
set_feature(&cpu->env, ARM_FEATURE_NEON);
191
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
192
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
193
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
194
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
195
cpu->midr = 0x411fd133; /* r1p3 */
196
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
197
set_feature(&cpu->env, ARM_FEATURE_V8);
198
set_feature(&cpu->env, ARM_FEATURE_NEON);
199
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
200
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
201
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
202
set_feature(&cpu->env, ARM_FEATURE_EL2);
203
set_feature(&cpu->env, ARM_FEATURE_EL3);
204
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
205
index XXXXXXX..XXXXXXX 100644
206
--- a/target/arm/tcg/cpu64.c
207
+++ b/target/arm/tcg/cpu64.c
208
@@ -XXX,XX +XXX,XX @@ static void aarch64_a35_initfn(Object *obj)
209
set_feature(&cpu->env, ARM_FEATURE_V8);
210
set_feature(&cpu->env, ARM_FEATURE_NEON);
211
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
212
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
213
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
214
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
215
set_feature(&cpu->env, ARM_FEATURE_EL2);
216
@@ -XXX,XX +XXX,XX @@ static void aarch64_a55_initfn(Object *obj)
217
set_feature(&cpu->env, ARM_FEATURE_V8);
218
set_feature(&cpu->env, ARM_FEATURE_NEON);
219
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
220
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
221
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
222
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
223
set_feature(&cpu->env, ARM_FEATURE_EL2);
224
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
225
set_feature(&cpu->env, ARM_FEATURE_V8);
226
set_feature(&cpu->env, ARM_FEATURE_NEON);
227
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
228
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
229
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
230
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
231
set_feature(&cpu->env, ARM_FEATURE_EL2);
232
@@ -XXX,XX +XXX,XX @@ static void aarch64_a76_initfn(Object *obj)
233
set_feature(&cpu->env, ARM_FEATURE_V8);
234
set_feature(&cpu->env, ARM_FEATURE_NEON);
235
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
236
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
237
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
238
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
239
set_feature(&cpu->env, ARM_FEATURE_EL2);
240
@@ -XXX,XX +XXX,XX @@ static void aarch64_a64fx_initfn(Object *obj)
241
set_feature(&cpu->env, ARM_FEATURE_V8);
242
set_feature(&cpu->env, ARM_FEATURE_NEON);
243
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
244
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
245
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
246
set_feature(&cpu->env, ARM_FEATURE_EL2);
247
set_feature(&cpu->env, ARM_FEATURE_EL3);
248
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_n1_initfn(Object *obj)
249
set_feature(&cpu->env, ARM_FEATURE_V8);
250
set_feature(&cpu->env, ARM_FEATURE_NEON);
251
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
252
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
253
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
254
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
255
set_feature(&cpu->env, ARM_FEATURE_EL2);
256
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_v1_initfn(Object *obj)
257
set_feature(&cpu->env, ARM_FEATURE_V8);
258
set_feature(&cpu->env, ARM_FEATURE_NEON);
259
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
260
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
261
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
262
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
263
set_feature(&cpu->env, ARM_FEATURE_EL2);
264
@@ -XXX,XX +XXX,XX @@ static void aarch64_a710_initfn(Object *obj)
265
set_feature(&cpu->env, ARM_FEATURE_V8);
266
set_feature(&cpu->env, ARM_FEATURE_NEON);
267
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
268
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
269
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
270
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
271
set_feature(&cpu->env, ARM_FEATURE_EL2);
272
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_n2_initfn(Object *obj)
273
set_feature(&cpu->env, ARM_FEATURE_V8);
274
set_feature(&cpu->env, ARM_FEATURE_NEON);
275
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
276
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
277
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
278
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
279
set_feature(&cpu->env, ARM_FEATURE_EL2);
280
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
281
uint64_t t;
282
uint32_t u;
283
284
+ /*
285
+ * Unset ARM_FEATURE_BACKCOMPAT_CNTFRQ, which we would otherwise default
286
+ * to because we started with aarch64_a57_initfn(). A 'max' CPU might
287
+ * be a v8.6-or-later one, in which case the cntfrq must be 1GHz; and
288
+ * because it is our "may change" CPU type we are OK with it not being
289
+ * backwards-compatible with how it worked in old QEMU.
290
+ */
291
+ unset_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
91
+
292
+
92
+ for (i = 0; i < ARRAY_SIZE(s->cpu_irq_orgate); i++) {
293
/*
93
+ g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
294
* Reset MIDR so the guest doesn't mistake our 'max' CPU type for a real
94
+ object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
295
* one and try to apply errata workarounds or use impdef features we
95
+ }
96
}
97
98
static void exynos4210_class_init(ObjectClass *klass, void *data)
99
--
296
--
100
2.25.1
297
2.34.1
298
299
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Alexandra Diupina <adiupina@astralinux.ru>
2
2
3
Similar to the Aspeed code in include/misc/aspeed_scu.h, we define
3
The DMA descriptor structures for this device have
4
the PWRON STRAP fields in their corresponding module for NPCM7XX.
4
a set of "address extension" fields which extend the 32
5
bit source addresses with an extra 16 bits to give a
6
48 bit address:
7
https://docs.amd.com/r/en-US/ug1085-zynq-ultrascale-trm/ADDR_EXT-Field
5
8
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
9
However, we misimplemented this address extension in several ways:
7
Reviewed-by: Patrick Venture <venture@google.com>
10
* we only extracted 12 bits of the extension fields, not 16
8
Message-id: 20220411165842.3912945-2-wuhaotsh@google.com
11
* we didn't shift the extension field up far enough
12
* we accidentally did the shift as 32-bit arithmetic, which
13
meant that we would have an overflow instead of setting
14
bits [47:32] of the resulting 64-bit address
15
16
Add a type cast and use extract64() instead of extract32()
17
to avoid integer overflow on addition. Fix bit fields
18
extraction according to documentation.
19
20
Found by Linux Verification Center (linuxtesting.org) with SVACE.
21
22
Cc: qemu-stable@nongnu.org
23
Fixes: d3c6369a96 ("introduce xlnx-dpdma")
24
Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>
25
Message-id: 20240428181131.23801-1-adiupina@astralinux.ru
26
[PMM: adjusted commit message]
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
27
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
29
---
12
include/hw/misc/npcm7xx_gcr.h | 30 ++++++++++++++++++++++++++++++
30
hw/dma/xlnx_dpdma.c | 20 ++++++++++----------
13
1 file changed, 30 insertions(+)
31
1 file changed, 10 insertions(+), 10 deletions(-)
14
32
15
diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h
33
diff --git a/hw/dma/xlnx_dpdma.c b/hw/dma/xlnx_dpdma.c
16
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/misc/npcm7xx_gcr.h
35
--- a/hw/dma/xlnx_dpdma.c
18
+++ b/include/hw/misc/npcm7xx_gcr.h
36
+++ b/hw/dma/xlnx_dpdma.c
19
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@ static uint64_t xlnx_dpdma_desc_get_source_address(DPDMADescriptor *desc,
20
#include "exec/memory.h"
38
21
#include "hw/sysbus.h"
39
switch (frag) {
22
40
case 0:
23
+/*
41
- addr = desc->source_address
24
+ * NPCM7XX PWRON STRAP bit fields
42
- + (extract32(desc->address_extension, 16, 12) << 20);
25
+ * 12: SPI0 powered by VSBV3 at 1.8V
43
+ addr = (uint64_t)desc->source_address
26
+ * 11: System flash attached to BMC
44
+ + (extract64(desc->address_extension, 16, 16) << 32);
27
+ * 10: BSP alternative pins.
45
break;
28
+ * 9:8: Flash UART command route enabled.
46
case 1:
29
+ * 7: Security enabled.
47
- addr = desc->source_address2
30
+ * 6: HI-Z state control.
48
- + (extract32(desc->address_extension_23, 0, 12) << 8);
31
+ * 5: ECC disabled.
49
+ addr = (uint64_t)desc->source_address2
32
+ * 4: Reserved
50
+ + (extract64(desc->address_extension_23, 0, 16) << 32);
33
+ * 3: JTAG2 enabled.
51
break;
34
+ * 2:0: CPU and DRAM clock frequency.
52
case 2:
35
+ */
53
- addr = desc->source_address3
36
+#define NPCM7XX_PWRON_STRAP_SPI0F18 BIT(12)
54
- + (extract32(desc->address_extension_23, 16, 12) << 20);
37
+#define NPCM7XX_PWRON_STRAP_SFAB BIT(11)
55
+ addr = (uint64_t)desc->source_address3
38
+#define NPCM7XX_PWRON_STRAP_BSPA BIT(10)
56
+ + (extract64(desc->address_extension_23, 16, 16) << 32);
39
+#define NPCM7XX_PWRON_STRAP_FUP(x) ((x) << 8)
57
break;
40
+#define FUP_NORM_UART2 3
58
case 3:
41
+#define FUP_PROG_UART3 2
59
- addr = desc->source_address4
42
+#define FUP_PROG_UART2 1
60
- + (extract32(desc->address_extension_45, 0, 12) << 8);
43
+#define FUP_NORM_UART3 0
61
+ addr = (uint64_t)desc->source_address4
44
+#define NPCM7XX_PWRON_STRAP_SECEN BIT(7)
62
+ + (extract64(desc->address_extension_45, 0, 16) << 32);
45
+#define NPCM7XX_PWRON_STRAP_HIZ BIT(6)
63
break;
46
+#define NPCM7XX_PWRON_STRAP_ECC BIT(5)
64
case 4:
47
+#define NPCM7XX_PWRON_STRAP_RESERVE1 BIT(4)
65
- addr = desc->source_address5
48
+#define NPCM7XX_PWRON_STRAP_J2EN BIT(3)
66
- + (extract32(desc->address_extension_45, 16, 12) << 20);
49
+#define NPCM7XX_PWRON_STRAP_CKFRQ(x) (x)
67
+ addr = (uint64_t)desc->source_address5
50
+#define CKFRQ_SKIPINIT 0x000
68
+ + (extract64(desc->address_extension_45, 16, 16) << 32);
51
+#define CKFRQ_DEFAULT 0x111
69
break;
52
+
70
default:
53
/*
71
addr = 0;
54
* Number of registers in our device state structure. Don't change this without
55
* incrementing the version_id in the vmstate.
56
--
72
--
57
2.25.1
73
2.34.1
diff view generated by jsdifflib
1
From: Zongyuan Li <zongyuan.li@smartx.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
3
"make check-qtest-aarch64" recently started failing on FreeBSD builds,
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
and valgrind on Linux also detected that there is something fishy with
5
Message-id: 20220324181557.203805-2-zongyuan.li@smartx.com
5
the new stm32l4x5-usart: The code forgot to set the correct class_size
6
here, so the various class_init functions in this file wrote beyond
7
the allocated buffer when setting the subc->type field.
8
9
Fixes: 4fb37aea7e ("hw/char: Implement STM32L4x5 USART skeleton")
10
Signed-off-by: Thomas Huth <thuth@redhat.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20240429075908.36302-1-thuth@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
14
---
8
hw/arm/realview.c | 33 ++++++++++++++++++++++++---------
15
hw/char/stm32l4x5_usart.c | 1 +
9
1 file changed, 24 insertions(+), 9 deletions(-)
16
1 file changed, 1 insertion(+)
10
17
11
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
18
diff --git a/hw/char/stm32l4x5_usart.c b/hw/char/stm32l4x5_usart.c
12
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/realview.c
20
--- a/hw/char/stm32l4x5_usart.c
14
+++ b/hw/arm/realview.c
21
+++ b/hw/char/stm32l4x5_usart.c
15
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stm32l4x5_usart_types[] = {
16
#include "hw/sysbus.h"
23
.parent = TYPE_SYS_BUS_DEVICE,
17
#include "hw/arm/boot.h"
24
.instance_size = sizeof(Stm32l4x5UsartBaseState),
18
#include "hw/arm/primecell.h"
25
.instance_init = stm32l4x5_usart_base_init,
19
+#include "hw/core/split-irq.h"
26
+ .class_size = sizeof(Stm32l4x5UsartBaseClass),
20
#include "hw/net/lan9118.h"
27
.class_init = stm32l4x5_usart_base_class_init,
21
#include "hw/net/smc91c111.h"
28
.abstract = true,
22
#include "hw/pci/pci.h"
29
}, {
23
+#include "hw/qdev-core.h"
24
#include "net/net.h"
25
#include "sysemu/sysemu.h"
26
#include "hw/boards.h"
27
@@ -XXX,XX +XXX,XX @@ static const int realview_board_id[] = {
28
0x76d
29
};
30
31
+static void split_irq_from_named(DeviceState *src, const char* outname,
32
+ qemu_irq out1, qemu_irq out2) {
33
+ DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
34
+
35
+ qdev_prop_set_uint32(splitter, "num-lines", 2);
36
+
37
+ qdev_realize_and_unref(splitter, NULL, &error_fatal);
38
+
39
+ qdev_connect_gpio_out(splitter, 0, out1);
40
+ qdev_connect_gpio_out(splitter, 1, out2);
41
+ qdev_connect_gpio_out_named(src, outname, 0,
42
+ qdev_get_gpio_in(splitter, 0));
43
+}
44
+
45
static void realview_init(MachineState *machine,
46
enum realview_board_type board_type)
47
{
48
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
49
DeviceState *dev, *sysctl, *gpio2, *pl041;
50
SysBusDevice *busdev;
51
qemu_irq pic[64];
52
- qemu_irq mmc_irq[2];
53
PCIBus *pci_bus = NULL;
54
NICInfo *nd;
55
DriveInfo *dinfo;
56
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
57
* and the PL061 has them the other way about. Also the card
58
* detect line is inverted.
59
*/
60
- mmc_irq[0] = qemu_irq_split(
61
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
62
- qdev_get_gpio_in(gpio2, 1));
63
- mmc_irq[1] = qemu_irq_split(
64
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
65
- qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
66
- qdev_connect_gpio_out_named(dev, "card-read-only", 0, mmc_irq[0]);
67
- qdev_connect_gpio_out_named(dev, "card-inserted", 0, mmc_irq[1]);
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
+
72
+ split_irq_from_named(dev, "card-inserted",
73
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
74
+ qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
75
+
76
dinfo = drive_get(IF_SD, 0, 0);
77
if (dinfo) {
78
DeviceState *card;
79
--
30
--
80
2.25.1
31
2.34.1
32
33
diff view generated by jsdifflib
1
From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Describe that the gic-version influences the maximum number of CPUs.
3
Use little endian for derivative OTP fuse key.
4
4
5
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
5
Cc: qemu-stable@nongnu.org
6
Message-id: 20220413231456.35811-1-heinrich.schuchardt@canonical.com
6
Fixes: c752bb079b ("hw/nvram: NPCM7xx OTP device model")
7
[PMM: minor punctuation tweaks]
7
Suggested-by: Avi Fishman <Avi.Fishman@nuvoton.com>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20240422125813.1403-1-philmd@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@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
docs/system/arm/virt.rst | 4 ++--
13
hw/arm/npcm7xx.c | 3 ++-
12
1 file changed, 2 insertions(+), 2 deletions(-)
14
1 file changed, 2 insertions(+), 1 deletion(-)
13
15
14
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
16
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/virt.rst
18
--- a/hw/arm/npcm7xx.c
17
+++ b/docs/system/arm/virt.rst
19
+++ b/hw/arm/npcm7xx.c
18
@@ -XXX,XX +XXX,XX @@ gic-version
20
@@ -XXX,XX +XXX,XX @@
19
Valid values are:
21
#include "hw/qdev-clock.h"
20
22
#include "hw/qdev-properties.h"
21
``2``
23
#include "qapi/error.h"
22
- GICv2
24
+#include "qemu/bswap.h"
23
+ GICv2. Note that this limits the number of CPUs to 8.
25
#include "qemu/units.h"
24
``3``
26
#include "sysemu/sysemu.h"
25
- GICv3
27
#include "target/arm/cpu-qom.h"
26
+ GICv3. This allows up to 512 CPUs.
28
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_init_fuses(NPCM7xxState *s)
27
``host``
29
* The initial mask of disabled modules indicates the chip derivative (e.g.
28
Use the same GIC version the host provides, when using KVM
30
* NPCM750 or NPCM730).
29
``max``
31
*/
32
- value = tswap32(nc->disabled_modules);
33
+ value = cpu_to_le32(nc->disabled_modules);
34
npcm7xx_otp_array_write(&s->fuse_array, &value, NPCM7XX_FUSE_DERIVATIVE,
35
sizeof(value));
36
}
30
--
37
--
31
2.25.1
38
2.34.1
39
40
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Add a model of the Xilinx Versal CRL.
3
This device implements the IM120417002 colors shield v1.1 for Arduino
4
(which relies on the DM163 8x3-channel led driving logic) and features
5
a simple display of an 8x8 RGB matrix. The columns of the matrix are
6
driven by the DM163 and the rows are driven externally.
4
7
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
9
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
10
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
8
Message-id: 20220406174303.2022038-4-edgar.iglesias@xilinx.com
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20240424200929.240921-2-ines.varhol@telecom-paris.fr
13
[PMM: updated to new reset hold method prototype]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
15
---
11
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++
16
docs/system/arm/b-l475e-iot01a.rst | 3 +-
12
hw/misc/xlnx-versal-crl.c | 421 ++++++++++++++++++++++++++++++
17
include/hw/display/dm163.h | 59 +++++
13
hw/misc/meson.build | 1 +
18
hw/display/dm163.c | 349 +++++++++++++++++++++++++++++
14
3 files changed, 657 insertions(+)
19
hw/display/Kconfig | 3 +
15
create mode 100644 include/hw/misc/xlnx-versal-crl.h
20
hw/display/meson.build | 1 +
16
create mode 100644 hw/misc/xlnx-versal-crl.c
21
hw/display/trace-events | 14 ++
22
6 files changed, 428 insertions(+), 1 deletion(-)
23
create mode 100644 include/hw/display/dm163.h
24
create mode 100644 hw/display/dm163.c
17
25
18
diff --git a/include/hw/misc/xlnx-versal-crl.h b/include/hw/misc/xlnx-versal-crl.h
26
diff --git a/docs/system/arm/b-l475e-iot01a.rst b/docs/system/arm/b-l475e-iot01a.rst
27
index XXXXXXX..XXXXXXX 100644
28
--- a/docs/system/arm/b-l475e-iot01a.rst
29
+++ b/docs/system/arm/b-l475e-iot01a.rst
30
@@ -XXX,XX +XXX,XX @@ USART, I2C, SPI, CAN and USB OTG, as well as a variety of sensors.
31
Supported devices
32
"""""""""""""""""
33
34
-Currently B-L475E-IOT01A machine's only supports the following devices:
35
+Currently B-L475E-IOT01A machines support the following devices:
36
37
- Cortex-M4F based STM32L4x5 SoC
38
- STM32L4x5 EXTI (Extended interrupts and events controller)
39
@@ -XXX,XX +XXX,XX @@ Currently B-L475E-IOT01A machine's only supports the following devices:
40
- STM32L4x5 RCC (Reset and clock control)
41
- STM32L4x5 GPIOs (General-purpose I/Os)
42
- STM32L4x5 USARTs, UARTs and LPUART (Serial ports)
43
+- optional 8x8 led display (based on DM163 driver)
44
45
Missing devices
46
"""""""""""""""
47
diff --git a/include/hw/display/dm163.h b/include/hw/display/dm163.h
19
new file mode 100644
48
new file mode 100644
20
index XXXXXXX..XXXXXXX
49
index XXXXXXX..XXXXXXX
21
--- /dev/null
50
--- /dev/null
22
+++ b/include/hw/misc/xlnx-versal-crl.h
51
+++ b/include/hw/display/dm163.h
23
@@ -XXX,XX +XXX,XX @@
52
@@ -XXX,XX +XXX,XX @@
24
+/*
53
+/*
25
+ * QEMU model of the Clock-Reset-LPD (CRL).
54
+ * QEMU DM163 8x3-channel constant current led driver
55
+ * driving columns of associated 8x8 RGB matrix.
26
+ *
56
+ *
27
+ * Copyright (c) 2022 Xilinx Inc.
57
+ * Copyright (C) 2024 Samuel Tardieu <sam@rfc1149.net>
58
+ * Copyright (C) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
59
+ * Copyright (C) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
60
+ *
28
+ * SPDX-License-Identifier: GPL-2.0-or-later
61
+ * SPDX-License-Identifier: GPL-2.0-or-later
29
+ *
30
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
31
+ */
62
+ */
32
+#ifndef HW_MISC_XLNX_VERSAL_CRL_H
63
+
33
+#define HW_MISC_XLNX_VERSAL_CRL_H
64
+#ifndef HW_DISPLAY_DM163_H
34
+
65
+#define HW_DISPLAY_DM163_H
35
+#include "hw/sysbus.h"
66
+
36
+#include "hw/register.h"
67
+#include "qom/object.h"
37
+#include "target/arm/cpu.h"
68
+#include "hw/qdev-core.h"
38
+
69
+
39
+#define TYPE_XLNX_VERSAL_CRL "xlnx,versal-crl"
70
+#define TYPE_DM163 "dm163"
40
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCRL, XLNX_VERSAL_CRL)
71
+OBJECT_DECLARE_SIMPLE_TYPE(DM163State, DM163);
41
+
72
+
42
+REG32(ERR_CTRL, 0x0)
73
+#define RGB_MATRIX_NUM_ROWS 8
43
+ FIELD(ERR_CTRL, SLVERR_ENABLE, 0, 1)
74
+#define RGB_MATRIX_NUM_COLS 8
44
+REG32(IR_STATUS, 0x4)
75
+#define DM163_NUM_LEDS (RGB_MATRIX_NUM_COLS * 3)
45
+ FIELD(IR_STATUS, ADDR_DECODE_ERR, 0, 1)
76
+/* The last row is filled with 0 (turned off row) */
46
+REG32(IR_MASK, 0x8)
77
+#define COLOR_BUFFER_SIZE (RGB_MATRIX_NUM_ROWS + 1)
47
+ FIELD(IR_MASK, ADDR_DECODE_ERR, 0, 1)
78
+
48
+REG32(IR_ENABLE, 0xc)
79
+typedef struct DM163State {
49
+ FIELD(IR_ENABLE, ADDR_DECODE_ERR, 0, 1)
80
+ DeviceState parent_obj;
50
+REG32(IR_DISABLE, 0x10)
81
+
51
+ FIELD(IR_DISABLE, ADDR_DECODE_ERR, 0, 1)
82
+ /* DM163 driver */
52
+REG32(WPROT, 0x1c)
83
+ uint64_t bank0_shift_register[3];
53
+ FIELD(WPROT, ACTIVE, 0, 1)
84
+ uint64_t bank1_shift_register[3];
54
+REG32(PLL_CLK_OTHER_DMN, 0x20)
85
+ uint16_t latched_outputs[DM163_NUM_LEDS];
55
+ FIELD(PLL_CLK_OTHER_DMN, APLL_BYPASS, 0, 1)
86
+ uint16_t outputs[DM163_NUM_LEDS];
56
+REG32(RPLL_CTRL, 0x40)
87
+ qemu_irq sout;
57
+ FIELD(RPLL_CTRL, POST_SRC, 24, 3)
88
+
58
+ FIELD(RPLL_CTRL, PRE_SRC, 20, 3)
89
+ uint8_t sin;
59
+ FIELD(RPLL_CTRL, CLKOUTDIV, 16, 2)
90
+ uint8_t dck;
60
+ FIELD(RPLL_CTRL, FBDIV, 8, 8)
91
+ uint8_t rst_b;
61
+ FIELD(RPLL_CTRL, BYPASS, 3, 1)
92
+ uint8_t lat_b;
62
+ FIELD(RPLL_CTRL, RESET, 0, 1)
93
+ uint8_t selbk;
63
+REG32(RPLL_CFG, 0x44)
94
+ uint8_t en_b;
64
+ FIELD(RPLL_CFG, LOCK_DLY, 25, 7)
95
+
65
+ FIELD(RPLL_CFG, LOCK_CNT, 13, 10)
96
+ /* IM120417002 colors shield */
66
+ FIELD(RPLL_CFG, LFHF, 10, 2)
97
+ uint8_t activated_rows;
67
+ FIELD(RPLL_CFG, CP, 5, 4)
98
+
68
+ FIELD(RPLL_CFG, RES, 0, 4)
99
+ /* 8x8 RGB matrix */
69
+REG32(RPLL_FRAC_CFG, 0x48)
100
+ QemuConsole *console;
70
+ FIELD(RPLL_FRAC_CFG, ENABLED, 31, 1)
101
+ uint8_t redraw;
71
+ FIELD(RPLL_FRAC_CFG, SEED, 22, 3)
102
+ /* Rows currently being displayed on the matrix. */
72
+ FIELD(RPLL_FRAC_CFG, ALGRTHM, 19, 1)
103
+ /* The last row is filled with 0 (turned off row) */
73
+ FIELD(RPLL_FRAC_CFG, ORDER, 18, 1)
104
+ uint32_t buffer[COLOR_BUFFER_SIZE][RGB_MATRIX_NUM_COLS];
74
+ FIELD(RPLL_FRAC_CFG, DATA, 0, 16)
105
+ uint8_t last_buffer_idx;
75
+REG32(PLL_STATUS, 0x50)
106
+ uint8_t buffer_idx_of_row[RGB_MATRIX_NUM_ROWS];
76
+ FIELD(PLL_STATUS, RPLL_STABLE, 2, 1)
107
+ /* Used to simulate retinal persistence of rows */
77
+ FIELD(PLL_STATUS, RPLL_LOCK, 0, 1)
108
+ uint8_t row_persistence_delay[RGB_MATRIX_NUM_ROWS];
78
+REG32(RPLL_TO_XPD_CTRL, 0x100)
109
+} DM163State;
79
+ FIELD(RPLL_TO_XPD_CTRL, CLKACT, 25, 1)
110
+
80
+ FIELD(RPLL_TO_XPD_CTRL, DIVISOR0, 8, 10)
111
+#endif /* HW_DISPLAY_DM163_H */
81
+REG32(LPD_TOP_SWITCH_CTRL, 0x104)
112
diff --git a/hw/display/dm163.c b/hw/display/dm163.c
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
113
new file mode 100644
261
index XXXXXXX..XXXXXXX
114
index XXXXXXX..XXXXXXX
262
--- /dev/null
115
--- /dev/null
263
+++ b/hw/misc/xlnx-versal-crl.c
116
+++ b/hw/display/dm163.c
264
@@ -XXX,XX +XXX,XX @@
117
@@ -XXX,XX +XXX,XX @@
265
+/*
118
+/*
266
+ * QEMU model of the Clock-Reset-LPD (CRL).
119
+ * QEMU DM163 8x3-channel constant current led driver
120
+ * driving columns of associated 8x8 RGB matrix.
267
+ *
121
+ *
268
+ * Copyright (c) 2022 Advanced Micro Devices, Inc.
122
+ * Copyright (C) 2024 Samuel Tardieu <sam@rfc1149.net>
123
+ * Copyright (C) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
124
+ * Copyright (C) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
125
+ *
269
+ * SPDX-License-Identifier: GPL-2.0-or-later
126
+ * SPDX-License-Identifier: GPL-2.0-or-later
270
+ *
127
+ */
271
+ * Written by Edgar E. Iglesias <edgar.iglesias@amd.com>
128
+
129
+/*
130
+ * The reference used for the DM163 is the following :
131
+ * http://www.siti.com.tw/product/spec/LED/DM163.pdf
272
+ */
132
+ */
273
+
133
+
274
+#include "qemu/osdep.h"
134
+#include "qemu/osdep.h"
275
+#include "qapi/error.h"
135
+#include "qapi/error.h"
276
+#include "qemu/log.h"
277
+#include "qemu/bitops.h"
278
+#include "migration/vmstate.h"
136
+#include "migration/vmstate.h"
137
+#include "hw/irq.h"
279
+#include "hw/qdev-properties.h"
138
+#include "hw/qdev-properties.h"
280
+#include "hw/sysbus.h"
139
+#include "hw/display/dm163.h"
281
+#include "hw/irq.h"
140
+#include "ui/console.h"
282
+#include "hw/register.h"
141
+#include "trace.h"
283
+#include "hw/resettable.h"
142
+
284
+
143
+#define LED_SQUARE_SIZE 100
285
+#include "target/arm/arm-powerctl.h"
144
+/* Number of frames a row stays visible after being turned off. */
286
+#include "hw/misc/xlnx-versal-crl.h"
145
+#define ROW_PERSISTENCE 3
287
+
146
+#define TURNED_OFF_ROW (COLOR_BUFFER_SIZE - 1)
288
+#ifndef XLNX_VERSAL_CRL_ERR_DEBUG
147
+
289
+#define XLNX_VERSAL_CRL_ERR_DEBUG 0
148
+static const VMStateDescription vmstate_dm163 = {
290
+#endif
149
+ .name = TYPE_DM163,
291
+
292
+static void crl_update_irq(XlnxVersalCRL *s)
293
+{
294
+ bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK];
295
+ qemu_set_irq(s->irq, pending);
296
+}
297
+
298
+static void crl_status_postw(RegisterInfo *reg, uint64_t val64)
299
+{
300
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
301
+ crl_update_irq(s);
302
+}
303
+
304
+static uint64_t crl_enable_prew(RegisterInfo *reg, uint64_t val64)
305
+{
306
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
307
+ uint32_t val = val64;
308
+
309
+ s->regs[R_IR_MASK] &= ~val;
310
+ crl_update_irq(s);
311
+ return 0;
312
+}
313
+
314
+static uint64_t crl_disable_prew(RegisterInfo *reg, uint64_t val64)
315
+{
316
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
317
+ uint32_t val = val64;
318
+
319
+ s->regs[R_IR_MASK] |= val;
320
+ crl_update_irq(s);
321
+ return 0;
322
+}
323
+
324
+static void crl_reset_dev(XlnxVersalCRL *s, DeviceState *dev,
325
+ bool rst_old, bool rst_new)
326
+{
327
+ device_cold_reset(dev);
328
+}
329
+
330
+static void crl_reset_cpu(XlnxVersalCRL *s, ARMCPU *armcpu,
331
+ bool rst_old, bool rst_new)
332
+{
333
+ if (rst_new) {
334
+ arm_set_cpu_off(armcpu->mp_affinity);
335
+ } else {
336
+ arm_set_cpu_on_and_reset(armcpu->mp_affinity);
337
+ }
338
+}
339
+
340
+#define REGFIELD_RESET(type, s, reg, f, new_val, dev) { \
341
+ bool old_f = ARRAY_FIELD_EX32((s)->regs, reg, f); \
342
+ bool new_f = FIELD_EX32(new_val, reg, f); \
343
+ \
344
+ /* Detect edges. */ \
345
+ if (dev && old_f != new_f) { \
346
+ crl_reset_ ## type(s, dev, old_f, new_f); \
347
+ } \
348
+}
349
+
350
+static uint64_t crl_rst_r5_prew(RegisterInfo *reg, uint64_t val64)
351
+{
352
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
353
+
354
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU0, val64, s->cfg.cpu_r5[0]);
355
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU1, val64, s->cfg.cpu_r5[1]);
356
+ return val64;
357
+}
358
+
359
+static uint64_t crl_rst_adma_prew(RegisterInfo *reg, uint64_t val64)
360
+{
361
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
362
+ int i;
363
+
364
+ /* A single register fans out to all ADMA reset inputs. */
365
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); i++) {
366
+ REGFIELD_RESET(dev, s, RST_ADMA, RESET, val64, s->cfg.adma[i]);
367
+ }
368
+ return val64;
369
+}
370
+
371
+static uint64_t crl_rst_uart0_prew(RegisterInfo *reg, uint64_t val64)
372
+{
373
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
374
+
375
+ REGFIELD_RESET(dev, s, RST_UART0, RESET, val64, s->cfg.uart[0]);
376
+ return val64;
377
+}
378
+
379
+static uint64_t crl_rst_uart1_prew(RegisterInfo *reg, uint64_t val64)
380
+{
381
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
382
+
383
+ REGFIELD_RESET(dev, s, RST_UART1, RESET, val64, s->cfg.uart[1]);
384
+ return val64;
385
+}
386
+
387
+static uint64_t crl_rst_gem0_prew(RegisterInfo *reg, uint64_t val64)
388
+{
389
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
390
+
391
+ REGFIELD_RESET(dev, s, RST_GEM0, RESET, val64, s->cfg.gem[0]);
392
+ return val64;
393
+}
394
+
395
+static uint64_t crl_rst_gem1_prew(RegisterInfo *reg, uint64_t val64)
396
+{
397
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
398
+
399
+ REGFIELD_RESET(dev, s, RST_GEM1, RESET, val64, s->cfg.gem[1]);
400
+ return val64;
401
+}
402
+
403
+static uint64_t crl_rst_usb_prew(RegisterInfo *reg, uint64_t val64)
404
+{
405
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
406
+
407
+ REGFIELD_RESET(dev, s, RST_USB0, RESET, val64, s->cfg.usb);
408
+ return val64;
409
+}
410
+
411
+static const RegisterAccessInfo crl_regs_info[] = {
412
+ { .name = "ERR_CTRL", .addr = A_ERR_CTRL,
413
+ },{ .name = "IR_STATUS", .addr = A_IR_STATUS,
414
+ .w1c = 0x1,
415
+ .post_write = crl_status_postw,
416
+ },{ .name = "IR_MASK", .addr = A_IR_MASK,
417
+ .reset = 0x1,
418
+ .ro = 0x1,
419
+ },{ .name = "IR_ENABLE", .addr = A_IR_ENABLE,
420
+ .pre_write = crl_enable_prew,
421
+ },{ .name = "IR_DISABLE", .addr = A_IR_DISABLE,
422
+ .pre_write = crl_disable_prew,
423
+ },{ .name = "WPROT", .addr = A_WPROT,
424
+ },{ .name = "PLL_CLK_OTHER_DMN", .addr = A_PLL_CLK_OTHER_DMN,
425
+ .reset = 0x1,
426
+ .rsvd = 0xe,
427
+ },{ .name = "RPLL_CTRL", .addr = A_RPLL_CTRL,
428
+ .reset = 0x24809,
429
+ .rsvd = 0xf88c00f6,
430
+ },{ .name = "RPLL_CFG", .addr = A_RPLL_CFG,
431
+ .reset = 0x2000000,
432
+ .rsvd = 0x1801210,
433
+ },{ .name = "RPLL_FRAC_CFG", .addr = A_RPLL_FRAC_CFG,
434
+ .rsvd = 0x7e330000,
435
+ },{ .name = "PLL_STATUS", .addr = A_PLL_STATUS,
436
+ .reset = R_PLL_STATUS_RPLL_STABLE_MASK |
437
+ R_PLL_STATUS_RPLL_LOCK_MASK,
438
+ .rsvd = 0xfa,
439
+ .ro = 0x5,
440
+ },{ .name = "RPLL_TO_XPD_CTRL", .addr = A_RPLL_TO_XPD_CTRL,
441
+ .reset = 0x2000100,
442
+ .rsvd = 0xfdfc00ff,
443
+ },{ .name = "LPD_TOP_SWITCH_CTRL", .addr = A_LPD_TOP_SWITCH_CTRL,
444
+ .reset = 0x6000300,
445
+ .rsvd = 0xf9fc00f8,
446
+ },{ .name = "LPD_LSBUS_CTRL", .addr = A_LPD_LSBUS_CTRL,
447
+ .reset = 0x2000800,
448
+ .rsvd = 0xfdfc00f8,
449
+ },{ .name = "CPU_R5_CTRL", .addr = A_CPU_R5_CTRL,
450
+ .reset = 0xe000300,
451
+ .rsvd = 0xe1fc00f8,
452
+ },{ .name = "IOU_SWITCH_CTRL", .addr = A_IOU_SWITCH_CTRL,
453
+ .reset = 0x2000500,
454
+ .rsvd = 0xfdfc00f8,
455
+ },{ .name = "GEM0_REF_CTRL", .addr = A_GEM0_REF_CTRL,
456
+ .reset = 0xe000a00,
457
+ .rsvd = 0xf1fc00f8,
458
+ },{ .name = "GEM1_REF_CTRL", .addr = A_GEM1_REF_CTRL,
459
+ .reset = 0xe000a00,
460
+ .rsvd = 0xf1fc00f8,
461
+ },{ .name = "GEM_TSU_REF_CTRL", .addr = A_GEM_TSU_REF_CTRL,
462
+ .reset = 0x300,
463
+ .rsvd = 0xfdfc00f8,
464
+ },{ .name = "USB0_BUS_REF_CTRL", .addr = A_USB0_BUS_REF_CTRL,
465
+ .reset = 0x2001900,
466
+ .rsvd = 0xfdfc00f8,
467
+ },{ .name = "UART0_REF_CTRL", .addr = A_UART0_REF_CTRL,
468
+ .reset = 0xc00,
469
+ .rsvd = 0xfdfc00f8,
470
+ },{ .name = "UART1_REF_CTRL", .addr = A_UART1_REF_CTRL,
471
+ .reset = 0xc00,
472
+ .rsvd = 0xfdfc00f8,
473
+ },{ .name = "SPI0_REF_CTRL", .addr = A_SPI0_REF_CTRL,
474
+ .reset = 0x600,
475
+ .rsvd = 0xfdfc00f8,
476
+ },{ .name = "SPI1_REF_CTRL", .addr = A_SPI1_REF_CTRL,
477
+ .reset = 0x600,
478
+ .rsvd = 0xfdfc00f8,
479
+ },{ .name = "CAN0_REF_CTRL", .addr = A_CAN0_REF_CTRL,
480
+ .reset = 0xc00,
481
+ .rsvd = 0xfdfc00f8,
482
+ },{ .name = "CAN1_REF_CTRL", .addr = A_CAN1_REF_CTRL,
483
+ .reset = 0xc00,
484
+ .rsvd = 0xfdfc00f8,
485
+ },{ .name = "I2C0_REF_CTRL", .addr = A_I2C0_REF_CTRL,
486
+ .reset = 0xc00,
487
+ .rsvd = 0xfdfc00f8,
488
+ },{ .name = "I2C1_REF_CTRL", .addr = A_I2C1_REF_CTRL,
489
+ .reset = 0xc00,
490
+ .rsvd = 0xfdfc00f8,
491
+ },{ .name = "DBG_LPD_CTRL", .addr = A_DBG_LPD_CTRL,
492
+ .reset = 0x300,
493
+ .rsvd = 0xfdfc00f8,
494
+ },{ .name = "TIMESTAMP_REF_CTRL", .addr = A_TIMESTAMP_REF_CTRL,
495
+ .reset = 0x2000c00,
496
+ .rsvd = 0xfdfc00f8,
497
+ },{ .name = "CRL_SAFETY_CHK", .addr = A_CRL_SAFETY_CHK,
498
+ },{ .name = "PSM_REF_CTRL", .addr = A_PSM_REF_CTRL,
499
+ .reset = 0xf04,
500
+ .rsvd = 0xfffc00f8,
501
+ },{ .name = "DBG_TSTMP_CTRL", .addr = A_DBG_TSTMP_CTRL,
502
+ .reset = 0x300,
503
+ .rsvd = 0xfdfc00f8,
504
+ },{ .name = "CPM_TOPSW_REF_CTRL", .addr = A_CPM_TOPSW_REF_CTRL,
505
+ .reset = 0x300,
506
+ .rsvd = 0xfdfc00f8,
507
+ },{ .name = "USB3_DUAL_REF_CTRL", .addr = A_USB3_DUAL_REF_CTRL,
508
+ .reset = 0x3c00,
509
+ .rsvd = 0xfdfc00f8,
510
+ },{ .name = "RST_CPU_R5", .addr = A_RST_CPU_R5,
511
+ .reset = 0x17,
512
+ .rsvd = 0x8,
513
+ .pre_write = crl_rst_r5_prew,
514
+ },{ .name = "RST_ADMA", .addr = A_RST_ADMA,
515
+ .reset = 0x1,
516
+ .pre_write = crl_rst_adma_prew,
517
+ },{ .name = "RST_GEM0", .addr = A_RST_GEM0,
518
+ .reset = 0x1,
519
+ .pre_write = crl_rst_gem0_prew,
520
+ },{ .name = "RST_GEM1", .addr = A_RST_GEM1,
521
+ .reset = 0x1,
522
+ .pre_write = crl_rst_gem1_prew,
523
+ },{ .name = "RST_SPARE", .addr = A_RST_SPARE,
524
+ .reset = 0x1,
525
+ },{ .name = "RST_USB0", .addr = A_RST_USB0,
526
+ .reset = 0x1,
527
+ .pre_write = crl_rst_usb_prew,
528
+ },{ .name = "RST_UART0", .addr = A_RST_UART0,
529
+ .reset = 0x1,
530
+ .pre_write = crl_rst_uart0_prew,
531
+ },{ .name = "RST_UART1", .addr = A_RST_UART1,
532
+ .reset = 0x1,
533
+ .pre_write = crl_rst_uart1_prew,
534
+ },{ .name = "RST_SPI0", .addr = A_RST_SPI0,
535
+ .reset = 0x1,
536
+ },{ .name = "RST_SPI1", .addr = A_RST_SPI1,
537
+ .reset = 0x1,
538
+ },{ .name = "RST_CAN0", .addr = A_RST_CAN0,
539
+ .reset = 0x1,
540
+ },{ .name = "RST_CAN1", .addr = A_RST_CAN1,
541
+ .reset = 0x1,
542
+ },{ .name = "RST_I2C0", .addr = A_RST_I2C0,
543
+ .reset = 0x1,
544
+ },{ .name = "RST_I2C1", .addr = A_RST_I2C1,
545
+ .reset = 0x1,
546
+ },{ .name = "RST_DBG_LPD", .addr = A_RST_DBG_LPD,
547
+ .reset = 0x33,
548
+ .rsvd = 0xcc,
549
+ },{ .name = "RST_GPIO", .addr = A_RST_GPIO,
550
+ .reset = 0x1,
551
+ },{ .name = "RST_TTC", .addr = A_RST_TTC,
552
+ .reset = 0xf,
553
+ },{ .name = "RST_TIMESTAMP", .addr = A_RST_TIMESTAMP,
554
+ .reset = 0x1,
555
+ },{ .name = "RST_SWDT", .addr = A_RST_SWDT,
556
+ .reset = 0x1,
557
+ },{ .name = "RST_OCM", .addr = A_RST_OCM,
558
+ },{ .name = "RST_IPI", .addr = A_RST_IPI,
559
+ },{ .name = "RST_FPD", .addr = A_RST_FPD,
560
+ .reset = 0x3,
561
+ },{ .name = "PSM_RST_MODE", .addr = A_PSM_RST_MODE,
562
+ .reset = 0x1,
563
+ .rsvd = 0xf8,
564
+ }
565
+};
566
+
567
+static void crl_reset_enter(Object *obj, ResetType type)
568
+{
569
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
570
+ unsigned int i;
571
+
572
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
573
+ register_reset(&s->regs_info[i]);
574
+ }
575
+}
576
+
577
+static void crl_reset_hold(Object *obj)
578
+{
579
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
580
+
581
+ crl_update_irq(s);
582
+}
583
+
584
+static const MemoryRegionOps crl_ops = {
585
+ .read = register_read_memory,
586
+ .write = register_write_memory,
587
+ .endianness = DEVICE_LITTLE_ENDIAN,
588
+ .valid = {
589
+ .min_access_size = 4,
590
+ .max_access_size = 4,
591
+ },
592
+};
593
+
594
+static void crl_init(Object *obj)
595
+{
596
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
597
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
598
+ int i;
599
+
600
+ s->reg_array =
601
+ register_init_block32(DEVICE(obj), crl_regs_info,
602
+ ARRAY_SIZE(crl_regs_info),
603
+ s->regs_info, s->regs,
604
+ &crl_ops,
605
+ XLNX_VERSAL_CRL_ERR_DEBUG,
606
+ CRL_R_MAX * 4);
607
+ sysbus_init_mmio(sbd, &s->reg_array->mem);
608
+ sysbus_init_irq(sbd, &s->irq);
609
+
610
+ for (i = 0; i < ARRAY_SIZE(s->cfg.cpu_r5); ++i) {
611
+ object_property_add_link(obj, "cpu_r5[*]", TYPE_ARM_CPU,
612
+ (Object **)&s->cfg.cpu_r5[i],
613
+ qdev_prop_allow_set_link_before_realize,
614
+ OBJ_PROP_LINK_STRONG);
615
+ }
616
+
617
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); ++i) {
618
+ object_property_add_link(obj, "adma[*]", TYPE_DEVICE,
619
+ (Object **)&s->cfg.adma[i],
620
+ qdev_prop_allow_set_link_before_realize,
621
+ OBJ_PROP_LINK_STRONG);
622
+ }
623
+
624
+ for (i = 0; i < ARRAY_SIZE(s->cfg.uart); ++i) {
625
+ object_property_add_link(obj, "uart[*]", TYPE_DEVICE,
626
+ (Object **)&s->cfg.uart[i],
627
+ qdev_prop_allow_set_link_before_realize,
628
+ OBJ_PROP_LINK_STRONG);
629
+ }
630
+
631
+ for (i = 0; i < ARRAY_SIZE(s->cfg.gem); ++i) {
632
+ object_property_add_link(obj, "gem[*]", TYPE_DEVICE,
633
+ (Object **)&s->cfg.gem[i],
634
+ qdev_prop_allow_set_link_before_realize,
635
+ OBJ_PROP_LINK_STRONG);
636
+ }
637
+
638
+ object_property_add_link(obj, "usb", TYPE_DEVICE,
639
+ (Object **)&s->cfg.gem[i],
640
+ qdev_prop_allow_set_link_before_realize,
641
+ OBJ_PROP_LINK_STRONG);
642
+}
643
+
644
+static void crl_finalize(Object *obj)
645
+{
646
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
647
+ register_finalize_block(s->reg_array);
648
+}
649
+
650
+static const VMStateDescription vmstate_crl = {
651
+ .name = TYPE_XLNX_VERSAL_CRL,
652
+ .version_id = 1,
150
+ .version_id = 1,
653
+ .minimum_version_id = 1,
151
+ .minimum_version_id = 1,
654
+ .fields = (VMStateField[]) {
152
+ .fields = (const VMStateField[]) {
655
+ VMSTATE_UINT32_ARRAY(regs, XlnxVersalCRL, CRL_R_MAX),
153
+ VMSTATE_UINT64_ARRAY(bank0_shift_register, DM163State, 3),
656
+ VMSTATE_END_OF_LIST(),
154
+ VMSTATE_UINT64_ARRAY(bank1_shift_register, DM163State, 3),
155
+ VMSTATE_UINT16_ARRAY(latched_outputs, DM163State, DM163_NUM_LEDS),
156
+ VMSTATE_UINT16_ARRAY(outputs, DM163State, DM163_NUM_LEDS),
157
+ VMSTATE_UINT8(dck, DM163State),
158
+ VMSTATE_UINT8(en_b, DM163State),
159
+ VMSTATE_UINT8(lat_b, DM163State),
160
+ VMSTATE_UINT8(rst_b, DM163State),
161
+ VMSTATE_UINT8(selbk, DM163State),
162
+ VMSTATE_UINT8(sin, DM163State),
163
+ VMSTATE_UINT8(activated_rows, DM163State),
164
+ VMSTATE_UINT32_2DARRAY(buffer, DM163State, COLOR_BUFFER_SIZE,
165
+ RGB_MATRIX_NUM_COLS),
166
+ VMSTATE_UINT8(last_buffer_idx, DM163State),
167
+ VMSTATE_UINT8_ARRAY(buffer_idx_of_row, DM163State, RGB_MATRIX_NUM_ROWS),
168
+ VMSTATE_UINT8_ARRAY(row_persistence_delay, DM163State,
169
+ RGB_MATRIX_NUM_ROWS),
170
+ VMSTATE_END_OF_LIST()
657
+ }
171
+ }
658
+};
172
+};
659
+
173
+
660
+static void crl_class_init(ObjectClass *klass, void *data)
174
+static void dm163_reset_hold(Object *obj, ResetType type)
661
+{
175
+{
176
+ DM163State *s = DM163(obj);
177
+
178
+ s->sin = 0;
179
+ s->dck = 0;
180
+ s->rst_b = 0;
181
+ /* Ensuring the first falling edge of lat_b isn't missed */
182
+ s->lat_b = 1;
183
+ s->selbk = 0;
184
+ s->en_b = 0;
185
+ /* Reset stops the PWM, not the shift and latched registers. */
186
+ memset(s->outputs, 0, sizeof(s->outputs));
187
+
188
+ s->activated_rows = 0;
189
+ s->redraw = 0;
190
+ trace_dm163_redraw(s->redraw);
191
+ for (unsigned i = 0; i < COLOR_BUFFER_SIZE; i++) {
192
+ memset(s->buffer[i], 0, sizeof(s->buffer[0]));
193
+ }
194
+ s->last_buffer_idx = 0;
195
+ memset(s->buffer_idx_of_row, TURNED_OFF_ROW, sizeof(s->buffer_idx_of_row));
196
+ memset(s->row_persistence_delay, 0, sizeof(s->row_persistence_delay));
197
+}
198
+
199
+static void dm163_dck_gpio_handler(void *opaque, int line, int new_state)
200
+{
201
+ DM163State *s = opaque;
202
+
203
+ if (new_state && !s->dck) {
204
+ /*
205
+ * On raising dck, sample selbk to get the bank to use, and
206
+ * sample sin for the bit to enter into the bank shift buffer.
207
+ */
208
+ uint64_t *sb =
209
+ s->selbk ? s->bank1_shift_register : s->bank0_shift_register;
210
+ /* Output the outgoing bit on sout */
211
+ const bool sout = (s->selbk ? sb[2] & MAKE_64BIT_MASK(63, 1) :
212
+ sb[2] & MAKE_64BIT_MASK(15, 1)) != 0;
213
+ qemu_set_irq(s->sout, sout);
214
+ /* Enter sin into the shift buffer */
215
+ sb[2] = (sb[2] << 1) | ((sb[1] >> 63) & 1);
216
+ sb[1] = (sb[1] << 1) | ((sb[0] >> 63) & 1);
217
+ sb[0] = (sb[0] << 1) | s->sin;
218
+ }
219
+
220
+ s->dck = new_state;
221
+ trace_dm163_dck(new_state);
222
+}
223
+
224
+static void dm163_propagate_outputs(DM163State *s)
225
+{
226
+ s->last_buffer_idx = (s->last_buffer_idx + 1) % RGB_MATRIX_NUM_ROWS;
227
+ /* Values are output when reset is high and enable is low. */
228
+ if (s->rst_b && !s->en_b) {
229
+ memcpy(s->outputs, s->latched_outputs, sizeof(s->outputs));
230
+ } else {
231
+ memset(s->outputs, 0, sizeof(s->outputs));
232
+ }
233
+ for (unsigned x = 0; x < RGB_MATRIX_NUM_COLS; x++) {
234
+ /* Grouping the 3 RGB channels in a pixel value */
235
+ const uint16_t b = extract16(s->outputs[3 * x + 0], 6, 8);
236
+ const uint16_t g = extract16(s->outputs[3 * x + 1], 6, 8);
237
+ const uint16_t r = extract16(s->outputs[3 * x + 2], 6, 8);
238
+ uint32_t rgba = 0;
239
+
240
+ trace_dm163_channels(3 * x + 2, r);
241
+ trace_dm163_channels(3 * x + 1, g);
242
+ trace_dm163_channels(3 * x + 0, b);
243
+
244
+ rgba = deposit32(rgba, 0, 8, r);
245
+ rgba = deposit32(rgba, 8, 8, g);
246
+ rgba = deposit32(rgba, 16, 8, b);
247
+
248
+ /* Led values are sent from the last one to the first one */
249
+ s->buffer[s->last_buffer_idx][RGB_MATRIX_NUM_COLS - x - 1] = rgba;
250
+ }
251
+ for (unsigned row = 0; row < RGB_MATRIX_NUM_ROWS; row++) {
252
+ if (s->activated_rows & (1 << row)) {
253
+ s->buffer_idx_of_row[row] = s->last_buffer_idx;
254
+ s->redraw |= (1 << row);
255
+ trace_dm163_redraw(s->redraw);
256
+ }
257
+ }
258
+}
259
+
260
+static void dm163_en_b_gpio_handler(void *opaque, int line, int new_state)
261
+{
262
+ DM163State *s = opaque;
263
+
264
+ s->en_b = new_state;
265
+ dm163_propagate_outputs(s);
266
+ trace_dm163_en_b(new_state);
267
+}
268
+
269
+static uint8_t dm163_bank0(const DM163State *s, uint8_t led)
270
+{
271
+ /*
272
+ * Bank 0 uses 6 bits per led, so a value may be stored accross
273
+ * two uint64_t entries.
274
+ */
275
+ const uint8_t low_bit = 6 * led;
276
+ const uint8_t low_word = low_bit / 64;
277
+ const uint8_t high_word = (low_bit + 5) / 64;
278
+ const uint8_t low_shift = low_bit % 64;
279
+
280
+ if (low_word == high_word) {
281
+ /* Simple case: the value belongs to one entry. */
282
+ return extract64(s->bank0_shift_register[low_word], low_shift, 6);
283
+ }
284
+
285
+ const uint8_t nb_bits_in_low_word = 64 - low_shift;
286
+ const uint8_t nb_bits_in_high_word = 6 - nb_bits_in_low_word;
287
+
288
+ const uint64_t bits_in_low_word = \
289
+ extract64(s->bank0_shift_register[low_word], low_shift,
290
+ nb_bits_in_low_word);
291
+ const uint64_t bits_in_high_word = \
292
+ extract64(s->bank0_shift_register[high_word], 0,
293
+ nb_bits_in_high_word);
294
+ uint8_t val = 0;
295
+
296
+ val = deposit32(val, 0, nb_bits_in_low_word, bits_in_low_word);
297
+ val = deposit32(val, nb_bits_in_low_word, nb_bits_in_high_word,
298
+ bits_in_high_word);
299
+
300
+ return val;
301
+}
302
+
303
+static uint8_t dm163_bank1(const DM163State *s, uint8_t led)
304
+{
305
+ const uint64_t entry = s->bank1_shift_register[led / RGB_MATRIX_NUM_COLS];
306
+ return extract64(entry, 8 * (led % RGB_MATRIX_NUM_COLS), 8);
307
+}
308
+
309
+static void dm163_lat_b_gpio_handler(void *opaque, int line, int new_state)
310
+{
311
+ DM163State *s = opaque;
312
+
313
+ if (s->lat_b && !new_state) {
314
+ for (int led = 0; led < DM163_NUM_LEDS; led++) {
315
+ s->latched_outputs[led] = dm163_bank0(s, led) * dm163_bank1(s, led);
316
+ }
317
+ dm163_propagate_outputs(s);
318
+ }
319
+
320
+ s->lat_b = new_state;
321
+ trace_dm163_lat_b(new_state);
322
+}
323
+
324
+static void dm163_rst_b_gpio_handler(void *opaque, int line, int new_state)
325
+{
326
+ DM163State *s = opaque;
327
+
328
+ s->rst_b = new_state;
329
+ dm163_propagate_outputs(s);
330
+ trace_dm163_rst_b(new_state);
331
+}
332
+
333
+static void dm163_selbk_gpio_handler(void *opaque, int line, int new_state)
334
+{
335
+ DM163State *s = opaque;
336
+
337
+ s->selbk = new_state;
338
+ trace_dm163_selbk(new_state);
339
+}
340
+
341
+static void dm163_sin_gpio_handler(void *opaque, int line, int new_state)
342
+{
343
+ DM163State *s = opaque;
344
+
345
+ s->sin = new_state;
346
+ trace_dm163_sin(new_state);
347
+}
348
+
349
+static void dm163_rows_gpio_handler(void *opaque, int line, int new_state)
350
+{
351
+ DM163State *s = opaque;
352
+
353
+ if (new_state) {
354
+ s->activated_rows |= (1 << line);
355
+ s->buffer_idx_of_row[line] = s->last_buffer_idx;
356
+ s->redraw |= (1 << line);
357
+ trace_dm163_redraw(s->redraw);
358
+ } else {
359
+ s->activated_rows &= ~(1 << line);
360
+ s->row_persistence_delay[line] = ROW_PERSISTENCE;
361
+ }
362
+ trace_dm163_activated_rows(s->activated_rows);
363
+}
364
+
365
+static void dm163_invalidate_display(void *opaque)
366
+{
367
+ DM163State *s = (DM163State *)opaque;
368
+ s->redraw = 0xFF;
369
+ trace_dm163_redraw(s->redraw);
370
+}
371
+
372
+static void update_row_persistence_delay(DM163State *s, unsigned row)
373
+{
374
+ if (s->row_persistence_delay[row]) {
375
+ s->row_persistence_delay[row]--;
376
+ } else {
377
+ /*
378
+ * If the ROW_PERSISTENCE delay is up,
379
+ * the row is turned off.
380
+ */
381
+ s->buffer_idx_of_row[row] = TURNED_OFF_ROW;
382
+ s->redraw |= (1 << row);
383
+ trace_dm163_redraw(s->redraw);
384
+ }
385
+}
386
+
387
+static uint32_t *update_display_of_row(DM163State *s, uint32_t *dest,
388
+ unsigned row)
389
+{
390
+ for (unsigned _ = 0; _ < LED_SQUARE_SIZE; _++) {
391
+ for (int x = 0; x < RGB_MATRIX_NUM_COLS * LED_SQUARE_SIZE; x++) {
392
+ /* UI layer guarantees that there's 32 bits per pixel (Mar 2024) */
393
+ *dest++ = s->buffer[s->buffer_idx_of_row[row]][x / LED_SQUARE_SIZE];
394
+ }
395
+ }
396
+
397
+ dpy_gfx_update(s->console, 0, LED_SQUARE_SIZE * row,
398
+ RGB_MATRIX_NUM_COLS * LED_SQUARE_SIZE, LED_SQUARE_SIZE);
399
+ s->redraw &= ~(1 << row);
400
+ trace_dm163_redraw(s->redraw);
401
+
402
+ return dest;
403
+}
404
+
405
+static void dm163_update_display(void *opaque)
406
+{
407
+ DM163State *s = (DM163State *)opaque;
408
+ DisplaySurface *surface = qemu_console_surface(s->console);
409
+ uint32_t *dest;
410
+
411
+ dest = surface_data(surface);
412
+ for (unsigned row = 0; row < RGB_MATRIX_NUM_ROWS; row++) {
413
+ update_row_persistence_delay(s, row);
414
+ if (!extract8(s->redraw, row, 1)) {
415
+ dest += LED_SQUARE_SIZE * LED_SQUARE_SIZE * RGB_MATRIX_NUM_COLS;
416
+ continue;
417
+ }
418
+ dest = update_display_of_row(s, dest, row);
419
+ }
420
+}
421
+
422
+static const GraphicHwOps dm163_ops = {
423
+ .invalidate = dm163_invalidate_display,
424
+ .gfx_update = dm163_update_display,
425
+};
426
+
427
+static void dm163_realize(DeviceState *dev, Error **errp)
428
+{
429
+ DM163State *s = DM163(dev);
430
+
431
+ qdev_init_gpio_in(dev, dm163_rows_gpio_handler, RGB_MATRIX_NUM_ROWS);
432
+ qdev_init_gpio_in(dev, dm163_sin_gpio_handler, 1);
433
+ qdev_init_gpio_in(dev, dm163_dck_gpio_handler, 1);
434
+ qdev_init_gpio_in(dev, dm163_rst_b_gpio_handler, 1);
435
+ qdev_init_gpio_in(dev, dm163_lat_b_gpio_handler, 1);
436
+ qdev_init_gpio_in(dev, dm163_selbk_gpio_handler, 1);
437
+ qdev_init_gpio_in(dev, dm163_en_b_gpio_handler, 1);
438
+ qdev_init_gpio_out_named(dev, &s->sout, "sout", 1);
439
+
440
+ s->console = graphic_console_init(dev, 0, &dm163_ops, s);
441
+ qemu_console_resize(s->console, RGB_MATRIX_NUM_COLS * LED_SQUARE_SIZE,
442
+ RGB_MATRIX_NUM_ROWS * LED_SQUARE_SIZE);
443
+}
444
+
445
+static void dm163_class_init(ObjectClass *klass, void *data)
446
+{
447
+ DeviceClass *dc = DEVICE_CLASS(klass);
662
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
448
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
663
+ DeviceClass *dc = DEVICE_CLASS(klass);
449
+
664
+
450
+ dc->desc = "DM163";
665
+ dc->vmsd = &vmstate_crl;
451
+ dc->vmsd = &vmstate_dm163;
666
+
452
+ dc->realize = dm163_realize;
667
+ rc->phases.enter = crl_reset_enter;
453
+ rc->phases.hold = dm163_reset_hold;
668
+ rc->phases.hold = crl_reset_hold;
454
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
669
+}
455
+}
670
+
456
+
671
+static const TypeInfo crl_info = {
457
+static const TypeInfo dm163_types[] = {
672
+ .name = TYPE_XLNX_VERSAL_CRL,
458
+ {
673
+ .parent = TYPE_SYS_BUS_DEVICE,
459
+ .name = TYPE_DM163,
674
+ .instance_size = sizeof(XlnxVersalCRL),
460
+ .parent = TYPE_DEVICE,
675
+ .class_init = crl_class_init,
461
+ .instance_size = sizeof(DM163State),
676
+ .instance_init = crl_init,
462
+ .class_init = dm163_class_init
677
+ .instance_finalize = crl_finalize,
463
+ }
678
+};
464
+};
679
+
465
+
680
+static void crl_register_types(void)
466
+DEFINE_TYPES(dm163_types)
681
+{
467
diff --git a/hw/display/Kconfig b/hw/display/Kconfig
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
468
index XXXXXXX..XXXXXXX 100644
688
--- a/hw/misc/meson.build
469
--- a/hw/display/Kconfig
689
+++ b/hw/misc/meson.build
470
+++ b/hw/display/Kconfig
690
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
471
@@ -XXX,XX +XXX,XX @@ config XLNX_DISPLAYPORT
691
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
472
bool
692
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-crf.c'))
473
# defaults to "N", enabled by specific boards
693
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-apu-ctrl.c'))
474
depends on PIXMAN
694
+specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-crl.c'))
475
+
695
softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
476
+config DM163
696
'xlnx-versal-xramc.c',
477
+ bool
697
'xlnx-versal-pmc-iou-slcr.c',
478
diff --git a/hw/display/meson.build b/hw/display/meson.build
479
index XXXXXXX..XXXXXXX 100644
480
--- a/hw/display/meson.build
481
+++ b/hw/display/meson.build
482
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_NEXTCUBE', if_true: files('next-fb.c'))
483
484
system_ss.add(when: 'CONFIG_VGA', if_true: files('vga.c'))
485
system_ss.add(when: 'CONFIG_VIRTIO', if_true: files('virtio-dmabuf.c'))
486
+system_ss.add(when: 'CONFIG_DM163', if_true: files('dm163.c'))
487
488
if (config_all_devices.has_key('CONFIG_VGA_CIRRUS') or
489
config_all_devices.has_key('CONFIG_VGA_PCI') or
490
diff --git a/hw/display/trace-events b/hw/display/trace-events
491
index XXXXXXX..XXXXXXX 100644
492
--- a/hw/display/trace-events
493
+++ b/hw/display/trace-events
494
@@ -XXX,XX +XXX,XX @@ macfb_ctrl_write(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%"PRI
495
macfb_sense_read(uint32_t value) "video sense: 0x%"PRIx32
496
macfb_sense_write(uint32_t value) "video sense: 0x%"PRIx32
497
macfb_update_mode(uint32_t width, uint32_t height, uint8_t depth) "setting mode to width %"PRId32 " height %"PRId32 " size %d"
498
+
499
+# dm163.c
500
+dm163_redraw(uint8_t redraw) "0x%02x"
501
+dm163_dck(unsigned new_state) "dck : %u"
502
+dm163_en_b(unsigned new_state) "en_b : %u"
503
+dm163_rst_b(unsigned new_state) "rst_b : %u"
504
+dm163_lat_b(unsigned new_state) "lat_b : %u"
505
+dm163_sin(unsigned new_state) "sin : %u"
506
+dm163_selbk(unsigned new_state) "selbk : %u"
507
+dm163_activated_rows(int new_state) "Activated rows : 0x%" PRIx32 ""
508
+dm163_bits_ppi(unsigned dest_width) "dest_width : %u"
509
+dm163_leds(int led, uint32_t value) "led %d: 0x%x"
510
+dm163_channels(int channel, uint8_t value) "channel %d: 0x%x"
511
+dm163_refresh_rate(uint32_t rr) "refresh rate %d"
698
--
512
--
699
2.25.1
513
2.34.1
514
515
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Connect the CRL (Clock Reset LPD) to the Versal SoC.
3
Exposing SYSCFG inputs to the SoC is practical in order to wire the SoC
4
to the optional DM163 display from the board code (GPIOs outputs need
5
to be connected to both SYSCFG inputs and DM163 inputs).
4
6
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
7
STM32L4x5 SYSCFG in-irq interception needed to be changed accordingly.
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
8
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
9
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
8
Message-id: 20220406174303.2022038-5-edgar.iglesias@xilinx.com
10
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20240424200929.240921-3-ines.varhol@telecom-paris.fr
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
include/hw/arm/xlnx-versal.h | 4 +++
15
hw/arm/stm32l4x5_soc.c | 6 ++++--
12
hw/arm/xlnx-versal.c | 54 ++++++++++++++++++++++++++++++++++--
16
tests/qtest/stm32l4x5_gpio-test.c | 13 ++++++++-----
13
2 files changed, 56 insertions(+), 2 deletions(-)
17
tests/qtest/stm32l4x5_syscfg-test.c | 17 ++++++++++-------
18
3 files changed, 22 insertions(+), 14 deletions(-)
14
19
15
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
20
diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/xlnx-versal.h
22
--- a/hw/arm/stm32l4x5_soc.c
18
+++ b/include/hw/arm/xlnx-versal.h
23
+++ b/hw/arm/stm32l4x5_soc.c
19
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
20
#include "hw/nvram/xlnx-versal-efuse.h"
25
/*
21
#include "hw/ssi/xlnx-versal-ospi.h"
26
* STM32L4x5 SoC family
22
#include "hw/dma/xlnx_csu_dma.h"
27
*
23
+#include "hw/misc/xlnx-versal-crl.h"
28
- * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
24
#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
29
- * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
25
30
+ * Copyright (c) 2023-2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
31
+ * Copyright (c) 2023-2024 Inès Varhol <ines.varhol@telecom-paris.fr>
27
@@ -XXX,XX +XXX,XX @@ struct Versal {
32
*
28
qemu_or_irq irq_orgate;
33
* SPDX-License-Identifier: GPL-2.0-or-later
29
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
34
*
30
} xram;
35
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
36
}
37
}
38
39
+ qdev_pass_gpios(DEVICE(&s->syscfg), dev_soc, NULL);
31
+
40
+
32
+ XlnxVersalCRL crl;
41
/* EXTI device */
33
} lpd;
42
busdev = SYS_BUS_DEVICE(&s->exti);
34
43
if (!sysbus_realize(busdev, errp)) {
35
/* The Platform Management Controller subsystem. */
44
diff --git a/tests/qtest/stm32l4x5_gpio-test.c b/tests/qtest/stm32l4x5_gpio-test.c
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
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/xlnx-versal.c
46
--- a/tests/qtest/stm32l4x5_gpio-test.c
47
+++ b/hw/arm/xlnx-versal.c
47
+++ b/tests/qtest/stm32l4x5_gpio-test.c
48
@@ -XXX,XX +XXX,XX @@ static void versal_create_ospi(Versal *s, qemu_irq *pic)
48
@@ -XXX,XX +XXX,XX @@
49
qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
49
#define OTYPER_PUSH_PULL 0
50
#define OTYPER_OPEN_DRAIN 1
51
52
+/* SoC forwards GPIOs to SysCfg */
53
+#define SYSCFG "/machine/soc"
54
+
55
const uint32_t moder_reset[NUM_GPIOS] = {
56
0xABFFFFFF,
57
0xFFFFFEBF,
58
@@ -XXX,XX +XXX,XX @@ static void test_gpio_output_mode(const void *data)
59
uint32_t gpio = test_gpio_addr(data);
60
unsigned int gpio_id = get_gpio_id(gpio);
61
62
- qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
63
+ qtest_irq_intercept_in(global_qtest, SYSCFG);
64
65
/* Set a bit in ODR and check nothing happens */
66
gpio_set_bit(gpio, ODR, pin, 1);
67
@@ -XXX,XX +XXX,XX @@ static void test_gpio_input_mode(const void *data)
68
uint32_t gpio = test_gpio_addr(data);
69
unsigned int gpio_id = get_gpio_id(gpio);
70
71
- qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
72
+ qtest_irq_intercept_in(global_qtest, SYSCFG);
73
74
/* Configure a line as input, raise it, and check that the pin is high */
75
gpio_set_2bits(gpio, MODER, pin, MODER_INPUT);
76
@@ -XXX,XX +XXX,XX @@ static void test_pull_up_pull_down(const void *data)
77
uint32_t gpio = test_gpio_addr(data);
78
unsigned int gpio_id = get_gpio_id(gpio);
79
80
- qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
81
+ qtest_irq_intercept_in(global_qtest, SYSCFG);
82
83
/* Configure a line as input with pull-up, check the line is set high */
84
gpio_set_2bits(gpio, MODER, pin, MODER_INPUT);
85
@@ -XXX,XX +XXX,XX @@ static void test_push_pull(const void *data)
86
uint32_t gpio = test_gpio_addr(data);
87
uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio);
88
89
- qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
90
+ qtest_irq_intercept_in(global_qtest, SYSCFG);
91
92
/* Setting a line high externally, configuring it in push-pull output */
93
/* And checking the pin was disconnected */
94
@@ -XXX,XX +XXX,XX @@ static void test_open_drain(const void *data)
95
uint32_t gpio = test_gpio_addr(data);
96
uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio);
97
98
- qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
99
+ qtest_irq_intercept_in(global_qtest, SYSCFG);
100
101
/* Setting a line high externally, configuring it in open-drain output */
102
/* And checking the pin was disconnected */
103
diff --git a/tests/qtest/stm32l4x5_syscfg-test.c b/tests/qtest/stm32l4x5_syscfg-test.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/tests/qtest/stm32l4x5_syscfg-test.c
106
+++ b/tests/qtest/stm32l4x5_syscfg-test.c
107
@@ -XXX,XX +XXX,XX @@
108
/*
109
* QTest testcase for STM32L4x5_SYSCFG
110
*
111
- * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
112
- * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
113
+ * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
114
+ * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
115
*
116
* This work is licensed under the terms of the GNU GPL, version 2 or later.
117
* See the COPYING file in the top-level directory.
118
@@ -XXX,XX +XXX,XX @@
119
#define SYSCFG_SWPR2 0x28
120
#define INVALID_ADDR 0x2C
121
122
+/* SoC forwards GPIOs to SysCfg */
123
+#define SYSCFG "/machine/soc"
124
+#define EXTI "/machine/soc/exti"
125
+
126
static void syscfg_writel(unsigned int offset, uint32_t value)
127
{
128
writel(SYSCFG_BASE_ADDR + offset, value);
129
@@ -XXX,XX +XXX,XX @@ static uint32_t syscfg_readl(unsigned int offset)
130
131
static void syscfg_set_irq(int num, int level)
132
{
133
- qtest_set_irq_in(global_qtest, "/machine/soc/syscfg",
134
- NULL, num, level);
135
+ qtest_set_irq_in(global_qtest, SYSCFG, NULL, num, level);
50
}
136
}
51
137
52
+static void versal_create_crl(Versal *s, qemu_irq *pic)
138
static void system_reset(void)
53
+{
139
@@ -XXX,XX +XXX,XX @@ static void test_interrupt(void)
54
+ SysBusDevice *sbd;
140
* Test that GPIO rising lines result in an irq
55
+ int i;
141
* with the right configuration
56
+
142
*/
57
+ object_initialize_child(OBJECT(s), "crl", &s->lpd.crl,
143
- qtest_irq_intercept_in(global_qtest, "/machine/soc/exti");
58
+ TYPE_XLNX_VERSAL_CRL);
144
+ qtest_irq_intercept_in(global_qtest, EXTI);
59
+ sbd = SYS_BUS_DEVICE(&s->lpd.crl);
145
60
+
146
/* GPIOA is the default source for EXTI lines 0 to 15 */
61
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
147
62
+ g_autofree gchar *name = g_strdup_printf("cpu_r5[%d]", i);
148
@@ -XXX,XX +XXX,XX @@ static void test_irq_pin_multiplexer(void)
63
+
149
* Test that syscfg irq sets the right exti irq
64
+ object_property_set_link(OBJECT(&s->lpd.crl),
150
*/
65
+ name, OBJECT(&s->lpd.rpu.cpu[i]),
151
66
+ &error_abort);
152
- qtest_irq_intercept_in(global_qtest, "/machine/soc/exti");
67
+ }
153
+ qtest_irq_intercept_in(global_qtest, EXTI);
68
+
154
69
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
155
syscfg_set_irq(0, 1);
70
+ g_autofree gchar *name = g_strdup_printf("gem[%d]", i);
156
71
+
157
@@ -XXX,XX +XXX,XX @@ static void test_irq_gpio_multiplexer(void)
72
+ object_property_set_link(OBJECT(&s->lpd.crl),
158
* Test that an irq is generated only by the right GPIO
73
+ name, OBJECT(&s->lpd.iou.gem[i]),
159
*/
74
+ &error_abort);
160
75
+ }
161
- qtest_irq_intercept_in(global_qtest, "/machine/soc/exti");
76
+
162
+ qtest_irq_intercept_in(global_qtest, EXTI);
77
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
163
78
+ g_autofree gchar *name = g_strdup_printf("adma[%d]", i);
164
/* GPIOA is the default source for EXTI lines 0 to 15 */
79
+
80
+ object_property_set_link(OBJECT(&s->lpd.crl),
81
+ name, OBJECT(&s->lpd.iou.adma[i]),
82
+ &error_abort);
83
+ }
84
+
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) {
86
+ g_autofree gchar *name = g_strdup_printf("uart[%d]", i);
87
+
88
+ object_property_set_link(OBJECT(&s->lpd.crl),
89
+ name, OBJECT(&s->lpd.iou.uart[i]),
90
+ &error_abort);
91
+ }
92
+
93
+ object_property_set_link(OBJECT(&s->lpd.crl),
94
+ "usb", OBJECT(&s->lpd.iou.usb),
95
+ &error_abort);
96
+
97
+ sysbus_realize(sbd, &error_fatal);
98
+ memory_region_add_subregion(&s->mr_ps, MM_CRL,
99
+ sysbus_mmio_get_region(sbd, 0));
100
+ sysbus_connect_irq(sbd, 0, pic[VERSAL_CRL_IRQ]);
101
+}
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
165
123
--
166
--
124
2.25.1
167
2.34.1
168
169
diff view generated by jsdifflib
1
In exynos4210_init_board_irqs(), use the TYPE_SPLIT_IRQ device
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
instead of qemu_irq_split().
3
2
3
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
4
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20240424200929.240921-4-ines.varhol@telecom-paris.fr
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20220404154658.565020-13-peter.maydell@linaro.org
7
---
8
---
8
include/hw/arm/exynos4210.h | 9 ++++++++
9
hw/arm/b-l475e-iot01a.c | 46 ++++++++++++++++++++++++++++-------------
9
hw/arm/exynos4210.c | 41 +++++++++++++++++++++++++++++--------
10
1 file changed, 32 insertions(+), 14 deletions(-)
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/b-l475e-iot01a.c b/hw/arm/b-l475e-iot01a.c
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/exynos4210.h
14
--- a/hw/arm/b-l475e-iot01a.c
15
+++ b/include/hw/arm/exynos4210.h
15
+++ b/hw/arm/b-l475e-iot01a.c
16
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
17
#include "hw/sysbus.h"
17
* B-L475E-IOT01A Discovery Kit machine
18
#include "hw/cpu/a9mpcore.h"
18
* (B-L475E-IOT01A IoT Node)
19
#include "hw/intc/exynos4210_gic.h"
19
*
20
+#include "hw/core/split-irq.h"
20
- * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
21
#include "target/arm/cpu-qom.h"
21
- * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
22
#include "qom/object.h"
22
+ * Copyright (c) 2023-2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
23
23
+ * Copyright (c) 2023-2024 Inès Varhol <ines.varhol@telecom-paris.fr>
24
*
25
* SPDX-License-Identifier: GPL-2.0-or-later
26
*
24
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@
25
28
26
#define EXYNOS4210_NUM_DMA 3
29
/* B-L475E-IOT01A implementation is derived from netduinoplus2 */
27
30
28
+/*
31
-static void b_l475e_iot01a_init(MachineState *machine)
29
+ * We need one splitter for every external combiner input, plus
32
+#define TYPE_B_L475E_IOT01A MACHINE_TYPE_NAME("b-l475e-iot01a")
30
+ * one for every non-zero entry in combiner_grp_to_gic_id[].
33
+OBJECT_DECLARE_SIMPLE_TYPE(Bl475eMachineState, B_L475E_IOT01A)
31
+ * We'll assert in exynos4210_init_board_irqs() if this is wrong.
32
+ */
33
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
34
+
34
+
35
typedef struct Exynos4210Irq {
35
+typedef struct Bl475eMachineState {
36
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
36
+ MachineState parent_obj;
37
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
38
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
39
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
40
A9MPPrivState a9mpcore;
41
Exynos4210GicState ext_gic;
42
+ SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
43
};
44
45
#define TYPE_EXYNOS4210_SOC "exynos4210"
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/exynos4210.c
49
+++ b/hw/arm/exynos4210.c
50
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
51
uint32_t grp, bit, irq_id, n;
52
Exynos4210Irq *is = &s->irqs;
53
DeviceState *extgicdev = DEVICE(&s->ext_gic);
54
+ int splitcount = 0;
55
+ DeviceState *splitter;
56
57
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
58
irq_id = 0;
59
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
60
/* MCT_G1 is passed to External and GIC */
61
irq_id = EXT_GIC_ID_MCT_G1;
62
}
63
+
37
+
64
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
38
+ Stm32l4x5SocState soc;
65
+ splitter = DEVICE(&s->splitter[splitcount]);
39
+} Bl475eMachineState;
66
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
40
+
67
+ qdev_realize(splitter, NULL, &error_abort);
41
+static void bl475e_init(MachineState *machine)
68
+ splitcount++;
42
{
69
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
43
+ Bl475eMachineState *s = B_L475E_IOT01A(machine);
70
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
44
const Stm32l4x5SocClass *sc;
71
if (irq_id) {
45
- DeviceState *dev;
72
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
46
73
- qdev_get_gpio_in(extgicdev,
47
- dev = qdev_new(TYPE_STM32L4X5XG_SOC);
74
- irq_id - 32));
48
- object_property_add_child(OBJECT(machine), "soc", OBJECT(dev));
75
+ qdev_connect_gpio_out(splitter, 1,
49
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
76
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
50
+ object_initialize_child(OBJECT(machine), "soc", &s->soc,
77
} else {
51
+ TYPE_STM32L4X5XG_SOC);
78
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
52
+ sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_fatal);
79
- is->ext_combiner_irq[n]);
53
80
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
54
- sc = STM32L4X5_SOC_GET_CLASS(dev);
81
}
55
- armv7m_load_kernel(ARM_CPU(first_cpu),
82
}
56
- machine->kernel_filename,
83
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
57
- 0, sc->flash_size);
84
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
58
+ sc = STM32L4X5_SOC_GET_CLASS(&s->soc);
85
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
59
+ armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0,
86
60
+ sc->flash_size);
87
if (irq_id) {
88
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
89
- qdev_get_gpio_in(extgicdev,
90
- irq_id - 32));
91
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
92
+ splitter = DEVICE(&s->splitter[splitcount]);
93
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
94
+ qdev_realize(splitter, NULL, &error_abort);
95
+ splitcount++;
96
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
97
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
98
+ qdev_connect_gpio_out(splitter, 1,
99
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
100
}
101
}
102
+ /*
103
+ * We check this here to avoid a more obscure assert later when
104
+ * qdev_assert_realized_properly() checks that we realized every
105
+ * child object we initialized.
106
+ */
107
+ assert(splitcount == EXYNOS4210_NUM_SPLITTERS);
108
}
61
}
109
62
110
/*
63
-static void b_l475e_iot01a_machine_init(MachineClass *mc)
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
64
+static void bl475e_machine_init(ObjectClass *oc, void *data)
112
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
65
{
113
}
66
+ MachineClass *mc = MACHINE_CLASS(oc);
114
67
static const char *machine_valid_cpu_types[] = {
115
+ for (i = 0; i < ARRAY_SIZE(s->splitter); i++) {
68
ARM_CPU_TYPE_NAME("cortex-m4"),
116
+ g_autofree char *name = g_strdup_printf("irq-splitter%d", i);
69
NULL
117
+ object_initialize_child(obj, name, &s->splitter[i], TYPE_SPLIT_IRQ);
70
};
71
mc->desc = "B-L475E-IOT01A Discovery Kit (Cortex-M4)";
72
- mc->init = b_l475e_iot01a_init;
73
+ mc->init = bl475e_init;
74
mc->valid_cpu_types = machine_valid_cpu_types;
75
76
/* SRAM pre-allocated as part of the SoC instantiation */
77
mc->default_ram_size = 0;
78
}
79
80
-DEFINE_MACHINE("b-l475e-iot01a", b_l475e_iot01a_machine_init)
81
+static const TypeInfo bl475e_machine_type[] = {
82
+ {
83
+ .name = TYPE_B_L475E_IOT01A,
84
+ .parent = TYPE_MACHINE,
85
+ .instance_size = sizeof(Bl475eMachineState),
86
+ .class_init = bl475e_machine_init,
118
+ }
87
+ }
88
+};
119
+
89
+
120
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
90
+DEFINE_TYPES(bl475e_machine_type)
121
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
122
}
123
--
91
--
124
2.25.1
92
2.34.1
93
94
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Connect the 4 TTC timers on the ZynqMP.
3
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
4
4
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Message-id: 20240424200929.240921-5-ines.varhol@telecom-paris.fr
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/b-l475e-iot01a.c | 59 +++++++++++++++++++++++++++++++++++++++--
13
hw/arm/xlnx-zynqmp.c | 22 ++++++++++++++++++++++
10
hw/arm/Kconfig | 1 +
14
2 files changed, 26 insertions(+)
11
2 files changed, 58 insertions(+), 2 deletions(-)
15
12
16
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
13
diff --git a/hw/arm/b-l475e-iot01a.c b/hw/arm/b-l475e-iot01a.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-zynqmp.h
15
--- a/hw/arm/b-l475e-iot01a.c
19
+++ b/include/hw/arm/xlnx-zynqmp.h
16
+++ b/hw/arm/b-l475e-iot01a.c
20
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@
21
#include "hw/or-irq.h"
18
#include "hw/boards.h"
22
#include "hw/misc/xlnx-zynqmp-apu-ctrl.h"
19
#include "hw/qdev-properties.h"
23
#include "hw/misc/xlnx-zynqmp-crf.h"
20
#include "qemu/error-report.h"
24
+#include "hw/timer/cadence_ttc.h"
21
-#include "hw/arm/stm32l4x5_soc.h"
25
22
#include "hw/arm/boot.h"
26
#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
23
+#include "hw/core/split-irq.h"
27
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
24
+#include "hw/arm/stm32l4x5_soc.h"
28
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
25
+#include "hw/gpio/stm32l4x5_gpio.h"
29
#define XLNX_ZYNQMP_MAX_RAM_SIZE (XLNX_ZYNQMP_MAX_LOW_RAM_SIZE + \
26
+#include "hw/display/dm163.h"
30
XLNX_ZYNQMP_MAX_HIGH_RAM_SIZE)
27
31
28
-/* B-L475E-IOT01A implementation is derived from netduinoplus2 */
32
+#define XLNX_ZYNQMP_NUM_TTC 4
29
+/* B-L475E-IOT01A implementation is inspired from netduinoplus2 and arduino */
33
+
30
+
34
/*
31
+/*
35
* Unimplemented mmio regions needed to boot some images.
32
+ * There are actually 14 input pins in the DM163 device.
36
*/
33
+ * Here the DM163 input pin EN isn't connected to the STM32L4x5
37
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
34
+ * GPIOs as the IM120417002 colors shield doesn't actually use
38
qemu_or_irq qspi_irq_orgate;
35
+ * this pin to drive the RGB matrix.
39
XlnxZynqMPAPUCtrl apu_ctrl;
36
+ */
40
XlnxZynqMPCRF crf;
37
+#define NUM_DM163_INPUTS 13
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
+
38
+
56
#define IPI_ADDR 0xFF300000
39
+static const unsigned dm163_input[NUM_DM163_INPUTS] = {
57
#define IPI_IRQ 64
40
+ 1 * GPIO_NUM_PINS + 2, /* ROW0 PB2 */
58
41
+ 0 * GPIO_NUM_PINS + 15, /* ROW1 PA15 */
59
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_crf(XlnxZynqMPState *s, qemu_irq *gic)
42
+ 0 * GPIO_NUM_PINS + 2, /* ROW2 PA2 */
60
sysbus_connect_irq(sbd, 0, gic[CRF_IRQ]);
43
+ 0 * GPIO_NUM_PINS + 7, /* ROW3 PA7 */
61
}
44
+ 0 * GPIO_NUM_PINS + 6, /* ROW4 PA6 */
62
45
+ 0 * GPIO_NUM_PINS + 5, /* ROW5 PA5 */
63
+static void xlnx_zynqmp_create_ttc(XlnxZynqMPState *s, qemu_irq *gic)
46
+ 1 * GPIO_NUM_PINS + 0, /* ROW6 PB0 */
64
+{
47
+ 0 * GPIO_NUM_PINS + 3, /* ROW7 PA3 */
65
+ SysBusDevice *sbd;
48
+ 0 * GPIO_NUM_PINS + 4, /* SIN (SDA) PA4 */
66
+ int i, irq;
49
+ 1 * GPIO_NUM_PINS + 1, /* DCK (SCK) PB1 */
50
+ 2 * GPIO_NUM_PINS + 3, /* RST_B (RST) PC3 */
51
+ 2 * GPIO_NUM_PINS + 4, /* LAT_B (LAT) PC4 */
52
+ 2 * GPIO_NUM_PINS + 5, /* SELBK (SB) PC5 */
53
+};
54
55
#define TYPE_B_L475E_IOT01A MACHINE_TYPE_NAME("b-l475e-iot01a")
56
OBJECT_DECLARE_SIMPLE_TYPE(Bl475eMachineState, B_L475E_IOT01A)
57
@@ -XXX,XX +XXX,XX @@ typedef struct Bl475eMachineState {
58
MachineState parent_obj;
59
60
Stm32l4x5SocState soc;
61
+ SplitIRQ gpio_splitters[NUM_DM163_INPUTS];
62
+ DM163State dm163;
63
} Bl475eMachineState;
64
65
static void bl475e_init(MachineState *machine)
66
{
67
Bl475eMachineState *s = B_L475E_IOT01A(machine);
68
const Stm32l4x5SocClass *sc;
69
+ DeviceState *dev, *gpio_out_splitter;
70
+ unsigned gpio, pin;
71
72
object_initialize_child(OBJECT(machine), "soc", &s->soc,
73
TYPE_STM32L4X5XG_SOC);
74
@@ -XXX,XX +XXX,XX @@ static void bl475e_init(MachineState *machine)
75
sc = STM32L4X5_SOC_GET_CLASS(&s->soc);
76
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0,
77
sc->flash_size);
67
+
78
+
68
+ for (i = 0; i < XLNX_ZYNQMP_NUM_TTC; i++) {
79
+ if (object_class_by_name(TYPE_DM163)) {
69
+ object_initialize_child(OBJECT(s), "ttc[*]", &s->ttc[i],
80
+ object_initialize_child(OBJECT(machine), "dm163",
70
+ TYPE_CADENCE_TTC);
81
+ &s->dm163, TYPE_DM163);
71
+ sbd = SYS_BUS_DEVICE(&s->ttc[i]);
82
+ dev = DEVICE(&s->dm163);
83
+ qdev_realize(dev, NULL, &error_abort);
72
+
84
+
73
+ sysbus_realize(sbd, &error_fatal);
85
+ for (unsigned i = 0; i < NUM_DM163_INPUTS; i++) {
74
+ sysbus_mmio_map(sbd, 0, TTC0_ADDR + i * 0x10000);
86
+ object_initialize_child(OBJECT(machine), "gpio-out-splitters[*]",
75
+ for (irq = 0; irq < 3; irq++) {
87
+ &s->gpio_splitters[i], TYPE_SPLIT_IRQ);
76
+ sysbus_connect_irq(sbd, irq, gic[TTC0_IRQ + i * 3 + irq]);
88
+ gpio_out_splitter = DEVICE(&s->gpio_splitters[i]);
89
+ qdev_prop_set_uint32(gpio_out_splitter, "num-lines", 2);
90
+ qdev_realize(gpio_out_splitter, NULL, &error_fatal);
91
+
92
+ qdev_connect_gpio_out(gpio_out_splitter, 0,
93
+ qdev_get_gpio_in(DEVICE(&s->soc), dm163_input[i]));
94
+ qdev_connect_gpio_out(gpio_out_splitter, 1,
95
+ qdev_get_gpio_in(dev, i));
96
+ gpio = dm163_input[i] / GPIO_NUM_PINS;
97
+ pin = dm163_input[i] % GPIO_NUM_PINS;
98
+ qdev_connect_gpio_out(DEVICE(&s->soc.gpio[gpio]), pin,
99
+ qdev_get_gpio_in(DEVICE(gpio_out_splitter), 0));
77
+ }
100
+ }
78
+ }
101
+ }
79
+}
102
}
80
+
103
81
static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
104
static void bl475e_machine_init(ObjectClass *oc, void *data)
82
{
105
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
83
static const struct UnimpInfo {
106
index XXXXXXX..XXXXXXX 100644
84
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
107
--- a/hw/arm/Kconfig
85
xlnx_zynqmp_create_efuse(s, gic_spi);
108
+++ b/hw/arm/Kconfig
86
xlnx_zynqmp_create_apu_ctrl(s, gic_spi);
109
@@ -XXX,XX +XXX,XX @@ config B_L475E_IOT01A
87
xlnx_zynqmp_create_crf(s, gic_spi);
110
default y
88
+ xlnx_zynqmp_create_ttc(s, gic_spi);
111
depends on TCG && ARM
89
xlnx_zynqmp_create_unimp_mmio(s);
112
select STM32L4X5_SOC
90
113
+ imply DM163
91
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
114
115
config STM32L4X5_SOC
116
bool
92
--
117
--
93
2.25.1
118
2.34.1
119
120
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Break out header file to allow embedding of the the TTC.
3
`test_dm163_bank()`
4
4
Checks that the pin "sout" of the DM163 led driver outputs the values
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
5
received on pin "sin" with the expected latency (depending on the bank).
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
`test_dm163_gpio_connection()`
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
Check that changes to relevant STM32L4x5 GPIO pins are propagated to the
9
Message-id: 20220331222017.2914409-2-edgar.iglesias@gmail.com
9
DM163 device.
10
11
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
12
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
13
Acked-by: Thomas Huth <thuth@redhat.com>
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
Message-id: 20240424200929.240921-6-ines.varhol@telecom-paris.fr
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
17
---
12
include/hw/timer/cadence_ttc.h | 54 ++++++++++++++++++++++++++++++++++
18
tests/qtest/dm163-test.c | 194 +++++++++++++++++++++++++++++++++++++++
13
hw/timer/cadence_ttc.c | 32 ++------------------
19
tests/qtest/meson.build | 2 +
14
2 files changed, 56 insertions(+), 30 deletions(-)
20
2 files changed, 196 insertions(+)
15
create mode 100644 include/hw/timer/cadence_ttc.h
21
create mode 100644 tests/qtest/dm163-test.c
16
22
17
diff --git a/include/hw/timer/cadence_ttc.h b/include/hw/timer/cadence_ttc.h
23
diff --git a/tests/qtest/dm163-test.c b/tests/qtest/dm163-test.c
18
new file mode 100644
24
new file mode 100644
19
index XXXXXXX..XXXXXXX
25
index XXXXXXX..XXXXXXX
20
--- /dev/null
26
--- /dev/null
21
+++ b/include/hw/timer/cadence_ttc.h
27
+++ b/tests/qtest/dm163-test.c
22
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
23
+/*
29
+/*
24
+ * Xilinx Zynq cadence TTC model
30
+ * QTest testcase for DM163
25
+ *
31
+ *
26
+ * Copyright (c) 2011 Xilinx Inc.
32
+ * Copyright (C) 2024 Samuel Tardieu <sam@rfc1149.net>
27
+ * Copyright (c) 2012 Peter A.G. Crosthwaite (peter.crosthwaite@petalogix.com)
33
+ * Copyright (C) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
28
+ * Copyright (c) 2012 PetaLogix Pty Ltd.
34
+ * Copyright (C) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
29
+ * Written By Haibing Ma
30
+ * M. Habib
31
+ *
35
+ *
32
+ * This program is free software; you can redistribute it and/or
36
+ * SPDX-License-Identifier: GPL-2.0-or-later
33
+ * modify it under the terms of the GNU General Public License
34
+ * as published by the Free Software Foundation; either version
35
+ * 2 of the License, or (at your option) any later version.
36
+ *
37
+ * You should have received a copy of the GNU General Public License along
38
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
39
+ */
37
+ */
40
+#ifndef HW_TIMER_CADENCE_TTC_H
38
+
41
+#define HW_TIMER_CADENCE_TTC_H
39
+#include "qemu/osdep.h"
42
+
40
+#include "libqtest.h"
43
+#include "hw/sysbus.h"
41
+
44
+#include "qemu/timer.h"
42
+enum DM163_INPUTS {
45
+
43
+ SIN = 8,
46
+typedef struct {
44
+ DCK = 9,
47
+ QEMUTimer *timer;
45
+ RST_B = 10,
48
+ int freq;
46
+ LAT_B = 11,
49
+
47
+ SELBK = 12,
50
+ uint32_t reg_clock;
48
+ EN_B = 13
51
+ uint32_t reg_count;
52
+ uint32_t reg_value;
53
+ uint16_t reg_interval;
54
+ uint16_t reg_match[3];
55
+ uint32_t reg_intr;
56
+ uint32_t reg_intr_en;
57
+ uint32_t reg_event_ctrl;
58
+ uint32_t reg_event;
59
+
60
+ uint64_t cpu_time;
61
+ unsigned int cpu_time_valid;
62
+
63
+ qemu_irq irq;
64
+} CadenceTimerState;
65
+
66
+#define TYPE_CADENCE_TTC "cadence_ttc"
67
+OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
68
+
69
+struct CadenceTTCState {
70
+ SysBusDevice parent_obj;
71
+
72
+ MemoryRegion iomem;
73
+ CadenceTimerState timer[3];
74
+};
49
+};
75
+
50
+
76
+#endif
51
+#define DEVICE_NAME "/machine/dm163"
77
diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c
52
+#define GPIO_OUT(name, value) qtest_set_irq_in(qts, DEVICE_NAME, NULL, name, \
53
+ value)
54
+#define GPIO_PULSE(name) \
55
+ do { \
56
+ GPIO_OUT(name, 1); \
57
+ GPIO_OUT(name, 0); \
58
+ } while (0)
59
+
60
+
61
+static void rise_gpio_pin_dck(QTestState *qts)
62
+{
63
+ /* Configure output mode for pin PB1 */
64
+ qtest_writel(qts, 0x48000400, 0xFFFFFEB7);
65
+ /* Write 1 in ODR for PB1 */
66
+ qtest_writel(qts, 0x48000414, 0x00000002);
67
+}
68
+
69
+static void lower_gpio_pin_dck(QTestState *qts)
70
+{
71
+ /* Configure output mode for pin PB1 */
72
+ qtest_writel(qts, 0x48000400, 0xFFFFFEB7);
73
+ /* Write 0 in ODR for PB1 */
74
+ qtest_writel(qts, 0x48000414, 0x00000000);
75
+}
76
+
77
+static void rise_gpio_pin_selbk(QTestState *qts)
78
+{
79
+ /* Configure output mode for pin PC5 */
80
+ qtest_writel(qts, 0x48000800, 0xFFFFF7FF);
81
+ /* Write 1 in ODR for PC5 */
82
+ qtest_writel(qts, 0x48000814, 0x00000020);
83
+}
84
+
85
+static void lower_gpio_pin_selbk(QTestState *qts)
86
+{
87
+ /* Configure output mode for pin PC5 */
88
+ qtest_writel(qts, 0x48000800, 0xFFFFF7FF);
89
+ /* Write 0 in ODR for PC5 */
90
+ qtest_writel(qts, 0x48000814, 0x00000000);
91
+}
92
+
93
+static void rise_gpio_pin_lat_b(QTestState *qts)
94
+{
95
+ /* Configure output mode for pin PC4 */
96
+ qtest_writel(qts, 0x48000800, 0xFFFFFDFF);
97
+ /* Write 1 in ODR for PC4 */
98
+ qtest_writel(qts, 0x48000814, 0x00000010);
99
+}
100
+
101
+static void lower_gpio_pin_lat_b(QTestState *qts)
102
+{
103
+ /* Configure output mode for pin PC4 */
104
+ qtest_writel(qts, 0x48000800, 0xFFFFFDFF);
105
+ /* Write 0 in ODR for PC4 */
106
+ qtest_writel(qts, 0x48000814, 0x00000000);
107
+}
108
+
109
+static void rise_gpio_pin_rst_b(QTestState *qts)
110
+{
111
+ /* Configure output mode for pin PC3 */
112
+ qtest_writel(qts, 0x48000800, 0xFFFFFF7F);
113
+ /* Write 1 in ODR for PC3 */
114
+ qtest_writel(qts, 0x48000814, 0x00000008);
115
+}
116
+
117
+static void lower_gpio_pin_rst_b(QTestState *qts)
118
+{
119
+ /* Configure output mode for pin PC3 */
120
+ qtest_writel(qts, 0x48000800, 0xFFFFFF7F);
121
+ /* Write 0 in ODR for PC3 */
122
+ qtest_writel(qts, 0x48000814, 0x00000000);
123
+}
124
+
125
+static void rise_gpio_pin_sin(QTestState *qts)
126
+{
127
+ /* Configure output mode for pin PA4 */
128
+ qtest_writel(qts, 0x48000000, 0xFFFFFDFF);
129
+ /* Write 1 in ODR for PA4 */
130
+ qtest_writel(qts, 0x48000014, 0x00000010);
131
+}
132
+
133
+static void lower_gpio_pin_sin(QTestState *qts)
134
+{
135
+ /* Configure output mode for pin PA4 */
136
+ qtest_writel(qts, 0x48000000, 0xFFFFFDFF);
137
+ /* Write 0 in ODR for PA4 */
138
+ qtest_writel(qts, 0x48000014, 0x00000000);
139
+}
140
+
141
+static void test_dm163_bank(const void *opaque)
142
+{
143
+ const unsigned bank = (uintptr_t) opaque;
144
+ const int width = bank ? 192 : 144;
145
+
146
+ QTestState *qts = qtest_initf("-M b-l475e-iot01a");
147
+ qtest_irq_intercept_out_named(qts, DEVICE_NAME, "sout");
148
+ GPIO_OUT(RST_B, 1);
149
+ GPIO_OUT(EN_B, 0);
150
+ GPIO_OUT(DCK, 0);
151
+ GPIO_OUT(SELBK, bank);
152
+ GPIO_OUT(LAT_B, 1);
153
+
154
+ /* Fill bank with zeroes */
155
+ GPIO_OUT(SIN, 0);
156
+ for (int i = 0; i < width; i++) {
157
+ GPIO_PULSE(DCK);
158
+ }
159
+ /* Fill bank with ones, check that we get the previous zeroes */
160
+ GPIO_OUT(SIN, 1);
161
+ for (int i = 0; i < width; i++) {
162
+ GPIO_PULSE(DCK);
163
+ g_assert(!qtest_get_irq(qts, 0));
164
+ }
165
+
166
+ /* Pulse one more bit in the bank, check that we get a one */
167
+ GPIO_PULSE(DCK);
168
+ g_assert(qtest_get_irq(qts, 0));
169
+
170
+ qtest_quit(qts);
171
+}
172
+
173
+static void test_dm163_gpio_connection(void)
174
+{
175
+ QTestState *qts = qtest_init("-M b-l475e-iot01a");
176
+ qtest_irq_intercept_in(qts, DEVICE_NAME);
177
+
178
+ g_assert_false(qtest_get_irq(qts, SIN));
179
+ g_assert_false(qtest_get_irq(qts, DCK));
180
+ g_assert_false(qtest_get_irq(qts, RST_B));
181
+ g_assert_false(qtest_get_irq(qts, LAT_B));
182
+ g_assert_false(qtest_get_irq(qts, SELBK));
183
+
184
+ rise_gpio_pin_dck(qts);
185
+ g_assert_true(qtest_get_irq(qts, DCK));
186
+ lower_gpio_pin_dck(qts);
187
+ g_assert_false(qtest_get_irq(qts, DCK));
188
+
189
+ rise_gpio_pin_lat_b(qts);
190
+ g_assert_true(qtest_get_irq(qts, LAT_B));
191
+ lower_gpio_pin_lat_b(qts);
192
+ g_assert_false(qtest_get_irq(qts, LAT_B));
193
+
194
+ rise_gpio_pin_selbk(qts);
195
+ g_assert_true(qtest_get_irq(qts, SELBK));
196
+ lower_gpio_pin_selbk(qts);
197
+ g_assert_false(qtest_get_irq(qts, SELBK));
198
+
199
+ rise_gpio_pin_rst_b(qts);
200
+ g_assert_true(qtest_get_irq(qts, RST_B));
201
+ lower_gpio_pin_rst_b(qts);
202
+ g_assert_false(qtest_get_irq(qts, RST_B));
203
+
204
+ rise_gpio_pin_sin(qts);
205
+ g_assert_true(qtest_get_irq(qts, SIN));
206
+ lower_gpio_pin_sin(qts);
207
+ g_assert_false(qtest_get_irq(qts, SIN));
208
+
209
+ g_assert_false(qtest_get_irq(qts, DCK));
210
+ g_assert_false(qtest_get_irq(qts, LAT_B));
211
+ g_assert_false(qtest_get_irq(qts, SELBK));
212
+ g_assert_false(qtest_get_irq(qts, RST_B));
213
+}
214
+
215
+int main(int argc, char **argv)
216
+{
217
+ g_test_init(&argc, &argv, NULL);
218
+ qtest_add_data_func("/dm163/bank0", (void *)0, test_dm163_bank);
219
+ qtest_add_data_func("/dm163/bank1", (void *)1, test_dm163_bank);
220
+ qtest_add_func("/dm163/gpio_connection", test_dm163_gpio_connection);
221
+ return g_test_run();
222
+}
223
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
78
index XXXXXXX..XXXXXXX 100644
224
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/timer/cadence_ttc.c
225
--- a/tests/qtest/meson.build
80
+++ b/hw/timer/cadence_ttc.c
226
+++ b/tests/qtest/meson.build
81
@@ -XXX,XX +XXX,XX @@
227
@@ -XXX,XX +XXX,XX @@ qtests_arm = \
82
#include "qemu/timer.h"
228
(config_all_devices.has_key('CONFIG_MICROBIT') ? ['microbit-test'] : []) + \
83
#include "qom/object.h"
229
(config_all_devices.has_key('CONFIG_STM32L4X5_SOC') ? qtests_stm32l4x5 : []) + \
84
230
(config_all_devices.has_key('CONFIG_FSI_APB2OPB_ASPEED') ? ['aspeed_fsi-test'] : []) + \
85
+#include "hw/timer/cadence_ttc.h"
231
+ (config_all_devices.has_key('CONFIG_STM32L4X5_SOC') and
86
+
232
+ config_all_devices.has_key('CONFIG_DM163')? ['dm163-test'] : []) + \
87
#ifdef CADENCE_TTC_ERR_DEBUG
233
['arm-cpu-features',
88
#define DB_PRINT(...) do { \
234
'boot-serial-test']
89
fprintf(stderr, ": %s: ", __func__); \
235
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
-
98
- uint32_t reg_clock;
99
- uint32_t reg_count;
100
- uint32_t reg_value;
101
- uint16_t reg_interval;
102
- uint16_t reg_match[3];
103
- uint32_t reg_intr;
104
- uint32_t reg_intr_en;
105
- uint32_t reg_event_ctrl;
106
- uint32_t reg_event;
107
-
108
- uint64_t cpu_time;
109
- unsigned int cpu_time_valid;
110
-
111
- qemu_irq irq;
112
-} CadenceTimerState;
113
-
114
-#define TYPE_CADENCE_TTC "cadence_ttc"
115
-OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
116
-
117
-struct CadenceTTCState {
118
- SysBusDevice parent_obj;
119
-
120
- MemoryRegion iomem;
121
- CadenceTimerState timer[3];
122
-};
123
-
124
static void cadence_timer_update(CadenceTimerState *s)
125
{
126
qemu_set_irq(s->irq, !!(s->reg_intr & s->reg_intr_en));
127
--
236
--
128
2.25.1
237
2.34.1
238
239
diff view generated by jsdifflib
Deleted patch
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
1
3
Create an APU CPU Cluster. This is in preparation to add the RPU.
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
Message-id: 20220406174303.2022038-2-edgar.iglesias@xilinx.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
include/hw/arm/xlnx-versal.h | 2 ++
11
hw/arm/xlnx-versal.c | 9 ++++++++-
12
2 files changed, 10 insertions(+), 1 deletion(-)
13
14
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/xlnx-versal.h
17
+++ b/include/hw/arm/xlnx-versal.h
18
@@ -XXX,XX +XXX,XX @@
19
20
#include "hw/sysbus.h"
21
#include "hw/arm/boot.h"
22
+#include "hw/cpu/cluster.h"
23
#include "hw/or-irq.h"
24
#include "hw/sd/sdhci.h"
25
#include "hw/intc/arm_gicv3.h"
26
@@ -XXX,XX +XXX,XX @@ struct Versal {
27
struct {
28
struct {
29
MemoryRegion mr;
30
+ CPUClusterState cluster;
31
ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
32
GICv3State gic;
33
} apu;
34
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/xlnx-versal.c
37
+++ b/hw/arm/xlnx-versal.c
38
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
39
{
40
int i;
41
42
+ object_initialize_child(OBJECT(s), "apu-cluster", &s->fpd.apu.cluster,
43
+ TYPE_CPU_CLUSTER);
44
+ qdev_prop_set_uint32(DEVICE(&s->fpd.apu.cluster), "cluster-id", 0);
45
+
46
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
47
Object *obj;
48
49
- object_initialize_child(OBJECT(s), "apu-cpu[*]", &s->fpd.apu.cpu[i],
50
+ object_initialize_child(OBJECT(&s->fpd.apu.cluster),
51
+ "apu-cpu[*]", &s->fpd.apu.cpu[i],
52
XLNX_VERSAL_ACPU_TYPE);
53
obj = OBJECT(&s->fpd.apu.cpu[i]);
54
if (i) {
55
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
56
&error_abort);
57
qdev_realize(DEVICE(obj), NULL, &error_fatal);
58
}
59
+
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
--
65
2.25.1
diff view generated by jsdifflib
Deleted patch
1
Now we have removed the only use of TYPE_EXYNOS4210_IRQ_GATE we can
2
delete the device entirely.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
6
Message-id: 20220404154658.565020-3-peter.maydell@linaro.org
7
---
8
hw/intc/exynos4210_gic.c | 107 ---------------------------------------
9
1 file changed, 107 deletions(-)
10
11
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/intc/exynos4210_gic.c
14
+++ b/hw/intc/exynos4210_gic.c
15
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_register_types(void)
16
}
17
18
type_init(exynos4210_gic_register_types)
19
-
20
-/* IRQ OR Gate struct.
21
- *
22
- * This device models an OR gate. There are n_in input qdev gpio lines and one
23
- * output sysbus IRQ line. The output IRQ level is formed as OR between all
24
- * gpio inputs.
25
- */
26
-
27
-#define TYPE_EXYNOS4210_IRQ_GATE "exynos4210.irq_gate"
28
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210IRQGateState, EXYNOS4210_IRQ_GATE)
29
-
30
-struct Exynos4210IRQGateState {
31
- SysBusDevice parent_obj;
32
-
33
- uint32_t n_in; /* inputs amount */
34
- uint32_t *level; /* input levels */
35
- qemu_irq out; /* output IRQ */
36
-};
37
-
38
-static Property exynos4210_irq_gate_properties[] = {
39
- DEFINE_PROP_UINT32("n_in", Exynos4210IRQGateState, n_in, 1),
40
- DEFINE_PROP_END_OF_LIST(),
41
-};
42
-
43
-static const VMStateDescription vmstate_exynos4210_irq_gate = {
44
- .name = "exynos4210.irq_gate",
45
- .version_id = 2,
46
- .minimum_version_id = 2,
47
- .fields = (VMStateField[]) {
48
- VMSTATE_VBUFFER_UINT32(level, Exynos4210IRQGateState, 1, NULL, n_in),
49
- VMSTATE_END_OF_LIST()
50
- }
51
-};
52
-
53
-/* Process a change in IRQ input. */
54
-static void exynos4210_irq_gate_handler(void *opaque, int irq, int level)
55
-{
56
- Exynos4210IRQGateState *s = (Exynos4210IRQGateState *)opaque;
57
- uint32_t i;
58
-
59
- assert(irq < s->n_in);
60
-
61
- s->level[irq] = level;
62
-
63
- for (i = 0; i < s->n_in; i++) {
64
- if (s->level[i] >= 1) {
65
- qemu_irq_raise(s->out);
66
- return;
67
- }
68
- }
69
-
70
- qemu_irq_lower(s->out);
71
-}
72
-
73
-static void exynos4210_irq_gate_reset(DeviceState *d)
74
-{
75
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(d);
76
-
77
- memset(s->level, 0, s->n_in * sizeof(*s->level));
78
-}
79
-
80
-/*
81
- * IRQ Gate initialization.
82
- */
83
-static void exynos4210_irq_gate_init(Object *obj)
84
-{
85
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(obj);
86
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
87
-
88
- sysbus_init_irq(sbd, &s->out);
89
-}
90
-
91
-static void exynos4210_irq_gate_realize(DeviceState *dev, Error **errp)
92
-{
93
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(dev);
94
-
95
- /* Allocate general purpose input signals and connect a handler to each of
96
- * them */
97
- qdev_init_gpio_in(dev, exynos4210_irq_gate_handler, s->n_in);
98
-
99
- s->level = g_malloc0(s->n_in * sizeof(*s->level));
100
-}
101
-
102
-static void exynos4210_irq_gate_class_init(ObjectClass *klass, void *data)
103
-{
104
- DeviceClass *dc = DEVICE_CLASS(klass);
105
-
106
- dc->reset = exynos4210_irq_gate_reset;
107
- dc->vmsd = &vmstate_exynos4210_irq_gate;
108
- device_class_set_props(dc, exynos4210_irq_gate_properties);
109
- dc->realize = exynos4210_irq_gate_realize;
110
-}
111
-
112
-static const TypeInfo exynos4210_irq_gate_info = {
113
- .name = TYPE_EXYNOS4210_IRQ_GATE,
114
- .parent = TYPE_SYS_BUS_DEVICE,
115
- .instance_size = sizeof(Exynos4210IRQGateState),
116
- .instance_init = exynos4210_irq_gate_init,
117
- .class_init = exynos4210_irq_gate_class_init,
118
-};
119
-
120
-static void exynos4210_irq_gate_register_types(void)
121
-{
122
- type_register_static(&exynos4210_irq_gate_info);
123
-}
124
-
125
-type_init(exynos4210_irq_gate_register_types)
126
--
127
2.25.1
diff view generated by jsdifflib
Deleted patch
1
The only time we use the int_gic_irq[] array in the Exynos4210Irq
2
struct is in the exynos4210_realize() function: we initialize it with
3
the GPIO inputs of the a9mpcore device, and then a bit later on we
4
connect those to the outputs of the internal combiner. Now that the
5
a9mpcore object is easily accessible as s->a9mpcore we can make the
6
connection directly from one device to the other without going via
7
this array.
8
1
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-5-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 1 -
14
hw/arm/exynos4210.c | 6 ++----
15
2 files changed, 2 insertions(+), 5 deletions(-)
16
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
20
+++ b/include/hw/arm/exynos4210.h
21
@@ -XXX,XX +XXX,XX @@
22
typedef struct Exynos4210Irq {
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
25
- qemu_irq int_gic_irq[EXYNOS4210_INT_GIC_NIRQ];
26
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
27
qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
28
} Exynos4210Irq;
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
32
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
34
sysbus_connect_irq(busdev, n,
35
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
36
}
37
- for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
38
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
39
- }
40
41
/* Cache controller */
42
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
43
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
44
busdev = SYS_BUS_DEVICE(dev);
45
sysbus_realize_and_unref(busdev, &error_fatal);
46
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
47
- sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
48
+ sysbus_connect_irq(busdev, n,
49
+ qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
50
}
51
exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
52
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
53
--
54
2.25.1
diff view generated by jsdifflib
Deleted patch
1
The exynos4210 code currently has two very similar arrays of IRQs:
2
1
3
* board_irqs is a field of the Exynos4210Irq struct which is filled
4
in by exynos4210_init_board_irqs() with the appropriate qemu_irqs
5
for each IRQ the board/SoC can assert
6
* irq_table is a set of qemu_irqs pointed to from the
7
Exynos4210State struct. It's allocated in exynos4210_init_irq,
8
and the only behaviour these irqs have is that they pass on the
9
level to the equivalent board_irqs[] irq
10
11
The extra indirection through irq_table is unnecessary, so coalesce
12
these into a single irq_table[] array as a direct field in
13
Exynos4210State which exynos4210_init_board_irqs() fills in.
14
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20220404154658.565020-6-peter.maydell@linaro.org
18
---
19
include/hw/arm/exynos4210.h | 8 ++------
20
hw/arm/exynos4210.c | 6 +-----
21
hw/intc/exynos4210_gic.c | 32 ++++++++------------------------
22
3 files changed, 11 insertions(+), 35 deletions(-)
23
24
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/arm/exynos4210.h
27
+++ b/include/hw/arm/exynos4210.h
28
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210Irq {
29
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
30
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
31
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
32
- qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
33
} Exynos4210Irq;
34
35
struct Exynos4210State {
36
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
37
/*< public >*/
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
39
Exynos4210Irq irqs;
40
- qemu_irq *irq_table;
41
+ qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
42
43
MemoryRegion chipid_mem;
44
MemoryRegion iram_mem;
45
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
46
void exynos4210_write_secondary(ARMCPU *cpu,
47
const struct arm_boot_info *info);
48
49
-/* Initialize exynos4210 IRQ subsystem stub */
50
-qemu_irq *exynos4210_init_irq(Exynos4210Irq *env);
51
-
52
/* Initialize board IRQs.
53
* These IRQs contain splitted Int/External Combiner and External Gic IRQs */
54
-void exynos4210_init_board_irqs(Exynos4210Irq *s);
55
+void exynos4210_init_board_irqs(Exynos4210State *s);
56
57
/* Get IRQ number from exynos4210 IRQ subsystem stub.
58
* To identify IRQ source use internal combiner group and bit number
59
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
60
index XXXXXXX..XXXXXXX 100644
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
}
66
67
- /*** IRQs ***/
68
-
69
- s->irq_table = exynos4210_init_irq(&s->irqs);
70
-
71
/* IRQ Gate */
72
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
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
--
148
2.25.1
diff view generated by jsdifflib
Deleted patch
1
Fix a missing set of spaces around '-' in the definition of
2
combiner_grp_to_gic_id[]. We're about to move this code, so
3
fix the style issue first to keep checkpatch happy with the
4
code-motion patch.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220404154658.565020-7-peter.maydell@linaro.org
9
---
10
hw/intc/exynos4210_gic.c | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
12
13
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/intc/exynos4210_gic.c
16
+++ b/hw/intc/exynos4210_gic.c
17
@@ -XXX,XX +XXX,XX @@ enum ExtInt {
18
*/
19
20
static const uint32_t
21
-combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
22
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
23
/* int combiner groups 16-19 */
24
{ }, { }, { }, { },
25
/* int combiner group 20 */
26
--
27
2.25.1
diff view generated by jsdifflib
Deleted patch
1
The only time we use the ext_gic_irq[] array in the Exynos4210Irq
2
struct is during realize of the SoC -- we initialize it with the
3
input IRQs of the external GIC device, and then connect those to
4
outputs of other devices further on in realize (including in the
5
exynos4210_init_board_irqs() function). Now that the ext_gic object
6
is easily accessible as s->ext_gic we can make the connections
7
directly from one device to the other without going via this array.
8
1
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-10-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 1 -
14
hw/arm/exynos4210.c | 12 ++++++------
15
2 files changed, 6 insertions(+), 7 deletions(-)
16
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
20
+++ b/include/hw/arm/exynos4210.h
21
@@ -XXX,XX +XXX,XX @@
22
typedef struct Exynos4210Irq {
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
25
- qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
26
} Exynos4210Irq;
27
28
struct Exynos4210State {
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
32
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
34
{
35
uint32_t grp, bit, irq_id, n;
36
Exynos4210Irq *is = &s->irqs;
37
+ DeviceState *extgicdev = DEVICE(&s->ext_gic);
38
39
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
40
irq_id = 0;
41
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
42
}
43
if (irq_id) {
44
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
45
- is->ext_gic_irq[irq_id - 32]);
46
+ qdev_get_gpio_in(extgicdev,
47
+ irq_id - 32));
48
} else {
49
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
50
is->ext_combiner_irq[n]);
51
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
52
53
if (irq_id) {
54
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
55
- is->ext_gic_irq[irq_id - 32]);
56
+ qdev_get_gpio_in(extgicdev,
57
+ irq_id - 32));
58
}
59
}
60
}
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
62
sysbus_connect_irq(busdev, n,
63
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
64
}
65
- for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
66
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
67
- }
68
69
/* Internal Interrupt Combiner */
70
dev = qdev_new("exynos4210.combiner");
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
72
busdev = SYS_BUS_DEVICE(dev);
73
sysbus_realize_and_unref(busdev, &error_fatal);
74
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
75
- sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]);
76
+ sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
77
}
78
exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
79
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
80
--
81
2.25.1
diff view generated by jsdifflib
Deleted patch
1
The function exynos4210_combiner_get_gpioin() currently lives in
2
exynos4210_combiner.c, but it isn't really part of the combiner
3
device itself -- it is a function that implements the wiring up of
4
some interrupt sources to multiple combiner inputs. Move it to live
5
with the other SoC-level code in exynos4210.c, along with a few
6
macros previously defined in exynos4210.h which are now used only
7
in exynos4210.c.
8
1
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-11-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 11 -----
14
hw/arm/exynos4210.c | 82 +++++++++++++++++++++++++++++++++++
15
hw/intc/exynos4210_combiner.c | 77 --------------------------------
16
3 files changed, 82 insertions(+), 88 deletions(-)
17
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/exynos4210.h
21
+++ b/include/hw/arm/exynos4210.h
22
@@ -XXX,XX +XXX,XX @@
23
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
24
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
25
26
-#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp)*8 + (bit))
27
-#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
28
-#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
29
- ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
30
-
31
/* IRQs number for external and internal GIC */
32
#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
33
#define EXYNOS4210_INT_GIC_NIRQ 64
34
@@ -XXX,XX +XXX,XX @@ void exynos4210_write_secondary(ARMCPU *cpu,
35
* bit - bit number inside group */
36
uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit);
37
38
-/*
39
- * Get Combiner input GPIO into irqs structure
40
- */
41
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
42
- int ext);
43
-
44
/*
45
* exynos4210 UART
46
*/
47
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/exynos4210.c
50
+++ b/hw/arm/exynos4210.c
51
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
52
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
53
};
54
55
+#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp) * 8 + (bit))
56
+#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
57
+#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
58
+ ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
59
+
60
/*
61
* Initialize board IRQs.
62
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
63
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
64
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
65
}
66
67
+/*
68
+ * Get Combiner input GPIO into irqs structure
69
+ */
70
+static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
71
+ DeviceState *dev, int ext)
72
+{
73
+ int n;
74
+ int bit;
75
+ int max;
76
+ qemu_irq *irq;
77
+
78
+ max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
79
+ EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
80
+ irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
81
+
82
+ /*
83
+ * Some IRQs of Int/External Combiner are going to two Combiners groups,
84
+ * so let split them.
85
+ */
86
+ for (n = 0; n < max; n++) {
87
+
88
+ bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
89
+
90
+ switch (n) {
91
+ /* MDNIE_LCD1 INTG1 */
92
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
93
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
94
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
95
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
96
+ continue;
97
+
98
+ /* TMU INTG3 */
99
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
100
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
101
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
102
+ continue;
103
+
104
+ /* LCD1 INTG12 */
105
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
106
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
107
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
108
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
109
+ continue;
110
+
111
+ /* Multi-Core Timer INTG12 */
112
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
113
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
114
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
115
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
116
+ continue;
117
+
118
+ /* Multi-Core Timer INTG35 */
119
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
120
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
121
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
122
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
123
+ continue;
124
+
125
+ /* Multi-Core Timer INTG51 */
126
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
127
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
128
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
129
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
130
+ continue;
131
+
132
+ /* Multi-Core Timer INTG53 */
133
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
134
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
135
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
136
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
137
+ continue;
138
+ }
139
+
140
+ irq[n] = qdev_get_gpio_in(dev, n);
141
+ }
142
+}
143
+
144
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
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
--
236
2.25.1
diff view generated by jsdifflib
Deleted patch
1
Delete a couple of #defines which are never used.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220404154658.565020-12-peter.maydell@linaro.org
6
---
7
include/hw/arm/exynos4210.h | 4 ----
8
1 file changed, 4 deletions(-)
9
10
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
11
index XXXXXXX..XXXXXXX 100644
12
--- a/include/hw/arm/exynos4210.h
13
+++ b/include/hw/arm/exynos4210.h
14
@@ -XXX,XX +XXX,XX @@
15
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
16
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
17
18
-/* IRQs number for external and internal GIC */
19
-#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
20
-#define EXYNOS4210_INT_GIC_NIRQ 64
21
-
22
#define EXYNOS4210_I2C_NUMBER 9
23
24
#define EXYNOS4210_NUM_DMA 3
25
--
26
2.25.1
diff view generated by jsdifflib
Deleted patch
1
In exynos4210_init_board_irqs(), the loop that handles IRQ lines that
2
are in a range that applies to the internal combiner only creates a
3
splitter for those interrupts which go to both the internal combiner
4
and to the external GIC, but it does nothing at all for the
5
interrupts which don't go to the external GIC, leaving the
6
irq_table[] array element empty for those. (This will result in
7
those interrupts simply being lost, not in a QEMU crash.)
8
1
9
I don't have a reliable datasheet for this SoC, but since we do wire
10
up one interrupt line in this category (the HDMI I2C device on
11
interrupt 16,1), this seems like it must be a bug in the existing
12
QEMU code. Fill in the irq_table[] entries where we're not splitting
13
the IRQ to both the internal combiner and the external GIC with the
14
IRQ line of the internal combiner. (That is, these IRQ lines go to
15
just one device, not multiple.)
16
17
This bug didn't have any visible guest effects because the only
18
implemented device that was affected was the HDMI I2C controller,
19
and we never connect any I2C devices to that bus.
20
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20220404154658.565020-14-peter.maydell@linaro.org
24
---
25
hw/arm/exynos4210.c | 2 ++
26
1 file changed, 2 insertions(+)
27
28
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/exynos4210.c
31
+++ b/hw/arm/exynos4210.c
32
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
34
qdev_connect_gpio_out(splitter, 1,
35
qdev_get_gpio_in(extgicdev, irq_id - 32));
36
+ } else {
37
+ s->irq_table[n] = is->int_combiner_irq[n];
38
}
39
}
40
/*
41
--
42
2.25.1
diff view generated by jsdifflib
Deleted patch
1
Currently for the interrupts MCT_G0 and MCT_G1 which are
2
the only ones in the input range of the external combiner
3
and which are also wired to the external GIC, we connect
4
them only to the internal combiner and the external GIC.
5
This seems likely to be a bug, as all other interrupts
6
which are in the input range of both combiners are
7
connected to both combiners. (The fact that the code in
8
exynos4210_combiner_get_gpioin() is also trying to wire
9
up these inputs on both combiners also suggests this.)
10
1
11
Wire these interrupts up to both combiners, like the rest.
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220404154658.565020-15-peter.maydell@linaro.org
16
---
17
hw/arm/exynos4210.c | 7 +++----
18
1 file changed, 3 insertions(+), 4 deletions(-)
19
20
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/exynos4210.c
23
+++ b/hw/arm/exynos4210.c
24
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
25
26
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
27
splitter = DEVICE(&s->splitter[splitcount]);
28
- qdev_prop_set_uint16(splitter, "num-lines", 2);
29
+ qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
30
qdev_realize(splitter, NULL, &error_abort);
31
splitcount++;
32
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
34
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
35
if (irq_id) {
36
- qdev_connect_gpio_out(splitter, 1,
37
+ qdev_connect_gpio_out(splitter, 2,
38
qdev_get_gpio_in(extgicdev, irq_id - 32));
39
- } else {
40
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
41
}
42
}
43
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
44
--
45
2.25.1
diff view generated by jsdifflib