1
First arm pullreq for 7.1. The bulk of this is the qemu_split_irq
1
Hi; here's a target-arm pullreq. Mostly this is RTH's FEAT_RME
2
removal.
2
series; there are also a handful of bug fixes including some
3
3
which aren't arm-specific but which it's convenient to include
4
I have enough stuff in my to-review queue that I expect to do another
4
here.
5
pullreq early next week, but 31 patches is enough to not hang on to.
6
5
7
thanks
6
thanks
8
-- PMM
7
-- PMM
9
8
10
The following changes since commit 9c125d17e9402c232c46610802e5931b3639d77b:
9
The following changes since commit b455ce4c2f300c8ba47cba7232dd03261368a4cb:
11
10
12
Merge tag 'pull-tcg-20220420' of https://gitlab.com/rth7680/qemu into staging (2022-04-20 16:43:11 -0700)
11
Merge tag 'q800-for-8.1-pull-request' of https://github.com/vivier/qemu-m68k into staging (2023-06-22 10:18:32 +0200)
13
12
14
are available in the Git repository at:
13
are available in the Git repository at:
15
14
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220421
15
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230623
17
16
18
for you to fetch changes up to 5b415dd61bdbf61fb4be0e9f1a7172b8bce682c6:
17
for you to fetch changes up to 497fad38979c16b6412388927401e577eba43d26:
19
18
20
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs (2022-04-21 11:37:05 +0100)
19
pc-bios/keymaps: Use the official xkb name for Arabic layout, not the legacy synonym (2023-06-23 11:46:02 +0100)
21
20
22
----------------------------------------------------------------
21
----------------------------------------------------------------
23
target-arm queue:
22
target-arm queue:
24
* hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
23
* Add (experimental) support for FEAT_RME
25
* versal: Add the Cortex-R5s in the Real-Time Processing Unit (RPU) subsystem
24
* host-utils: Avoid using __builtin_subcll on buggy versions of Apple Clang
26
* versal: model enough of the Clock/Reset Low-power domain (CRL) to allow control of the Cortex-R5s
25
* target/arm: Restructure has_vfp_d32 test
27
* xlnx-zynqmp: Connect 4 TTC timers
26
* hw/arm/sbsa-ref: add ITS support in SBSA GIC
28
* exynos4210: Refactor GIC/combiner code to stop using qemu_split_irq
27
* target/arm: Fix sve predicate store, 8 <= VQ <= 15
29
* realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
28
* pc-bios/keymaps: Use the official xkb name for Arabic layout, not the legacy synonym
30
* stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
31
* hw/core/irq: remove unused 'qemu_irq_split' function
32
* npcm7xx: use symbolic constants for PWRON STRAP bit fields
33
* virt: document impact of gic-version on max CPUs
34
29
35
----------------------------------------------------------------
30
----------------------------------------------------------------
36
Edgar E. Iglesias (6):
31
Peter Maydell (2):
37
timer: cadence_ttc: Break out header file to allow embedding
32
host-utils: Avoid using __builtin_subcll on buggy versions of Apple Clang
38
hw/arm/xlnx-zynqmp: Connect 4 TTC timers
33
pc-bios/keymaps: Use the official xkb name for Arabic layout, not the legacy synonym
39
hw/arm: versal: Create an APU CPU Cluster
40
hw/arm: versal: Add the Cortex-R5Fs
41
hw/misc: Add a model of the Xilinx Versal CRL
42
hw/arm: versal: Connect the CRL
43
34
44
Hao Wu (2):
35
Richard Henderson (23):
45
hw/misc: Add PWRON STRAP bit fields in GCR module
36
target/arm: Add isar_feature_aa64_rme
46
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs
37
target/arm: Update SCR and HCR for RME
38
target/arm: SCR_EL3.NS may be RES1
39
target/arm: Add RME cpregs
40
target/arm: Introduce ARMSecuritySpace
41
include/exec/memattrs: Add two bits of space to MemTxAttrs
42
target/arm: Adjust the order of Phys and Stage2 ARMMMUIdx
43
target/arm: Introduce ARMMMUIdx_Phys_{Realm,Root}
44
target/arm: Remove __attribute__((nonnull)) from ptw.c
45
target/arm: Pipe ARMSecuritySpace through ptw.c
46
target/arm: NSTable is RES0 for the RME EL3 regime
47
target/arm: Handle Block and Page bits for security space
48
target/arm: Handle no-execute for Realm and Root regimes
49
target/arm: Use get_phys_addr_with_struct in S1_ptw_translate
50
target/arm: Move s1_is_el0 into S1Translate
51
target/arm: Use get_phys_addr_with_struct for stage2
52
target/arm: Add GPC syndrome
53
target/arm: Implement GPC exceptions
54
target/arm: Implement the granule protection check
55
target/arm: Add cpu properties for enabling FEAT_RME
56
docs/system/arm: Document FEAT_RME
57
target/arm: Restructure has_vfp_d32 test
58
target/arm: Fix sve predicate store, 8 <= VQ <= 15
47
59
48
Heinrich Schuchardt (1):
60
Shashi Mallela (1):
49
hw/arm/virt: impact of gic-version on max CPUs
61
hw/arm/sbsa-ref: add ITS support in SBSA GIC
50
62
51
Peter Maydell (19):
63
docs/system/arm/cpu-features.rst | 23 ++
52
hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
64
docs/system/arm/emulation.rst | 1 +
53
hw/arm/exynos4210: Use TYPE_OR_IRQ instead of custom OR-gate device
65
docs/system/arm/sbsa.rst | 14 +
54
hw/intc/exynos4210_gic: Remove unused TYPE_EXYNOS4210_IRQ_GATE
66
include/exec/memattrs.h | 9 +-
55
hw/arm/exynos4210: Put a9mpcore device into state struct
67
include/qemu/compiler.h | 13 +
56
hw/arm/exynos4210: Drop int_gic_irq[] from Exynos4210Irq struct
68
include/qemu/host-utils.h | 2 +-
57
hw/arm/exynos4210: Coalesce board_irqs and irq_table
69
target/arm/cpu.h | 151 ++++++++---
58
hw/arm/exynos4210: Fix code style nit in combiner_grp_to_gic_id[]
70
target/arm/internals.h | 27 ++
59
hw/arm/exynos4210: Move exynos4210_init_board_irqs() into exynos4210.c
71
target/arm/syndrome.h | 10 +
60
hw/arm/exynos4210: Put external GIC into state struct
72
hw/arm/sbsa-ref.c | 33 ++-
61
hw/arm/exynos4210: Drop ext_gic_irq[] from Exynos4210Irq struct
73
target/arm/cpu.c | 32 ++-
62
hw/arm/exynos4210: Move exynos4210_combiner_get_gpioin() into exynos4210.c
74
target/arm/helper.c | 162 ++++++++++-
63
hw/arm/exynos4210: Delete unused macro definitions
75
target/arm/ptw.c | 570 +++++++++++++++++++++++++++++++--------
64
hw/arm/exynos4210: Use TYPE_SPLIT_IRQ in exynos4210_init_board_irqs()
76
target/arm/tcg/cpu64.c | 53 ++++
65
hw/arm/exynos4210: Fill in irq_table[] for internal-combiner-only IRQ lines
77
target/arm/tcg/tlb_helper.c | 96 ++++++-
66
hw/arm/exynos4210: Connect MCT_G0 and MCT_G1 to both combiners
78
target/arm/tcg/translate-sve.c | 2 +-
67
hw/arm/exynos4210: Don't connect multiple lines to external GIC inputs
79
pc-bios/keymaps/meson.build | 2 +-
68
hw/arm/exynos4210: Fold combiner splits into exynos4210_init_board_irqs()
80
17 files changed, 1034 insertions(+), 166 deletions(-)
69
hw/arm/exynos4210: Put combiners into state struct
70
hw/arm/exynos4210: Drop Exynos4210Irq struct
71
72
Zongyuan Li (3):
73
hw/arm/realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
74
hw/arm/stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
75
hw/core/irq: remove unused 'qemu_irq_split' function
76
77
docs/system/arm/virt.rst | 4 +-
78
include/hw/arm/exynos4210.h | 50 ++--
79
include/hw/arm/xlnx-versal.h | 16 ++
80
include/hw/arm/xlnx-zynqmp.h | 4 +
81
include/hw/intc/exynos4210_combiner.h | 57 +++++
82
include/hw/intc/exynos4210_gic.h | 43 ++++
83
include/hw/irq.h | 5 -
84
include/hw/misc/npcm7xx_gcr.h | 30 +++
85
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++++
86
include/hw/timer/cadence_ttc.h | 54 +++++
87
hw/arm/exynos4210.c | 430 ++++++++++++++++++++++++++++++----
88
hw/arm/npcm7xx_boards.c | 24 +-
89
hw/arm/realview.c | 33 ++-
90
hw/arm/stellaris.c | 15 +-
91
hw/arm/virt.c | 7 +
92
hw/arm/xlnx-versal-virt.c | 6 +-
93
hw/arm/xlnx-versal.c | 99 +++++++-
94
hw/arm/xlnx-zynqmp.c | 22 ++
95
hw/core/irq.c | 15 --
96
hw/intc/exynos4210_combiner.c | 108 +--------
97
hw/intc/exynos4210_gic.c | 344 +--------------------------
98
hw/misc/xlnx-versal-crl.c | 421 +++++++++++++++++++++++++++++++++
99
hw/timer/cadence_ttc.c | 32 +--
100
MAINTAINERS | 2 +-
101
hw/misc/meson.build | 1 +
102
25 files changed, 1457 insertions(+), 600 deletions(-)
103
create mode 100644 include/hw/intc/exynos4210_combiner.h
104
create mode 100644 include/hw/intc/exynos4210_gic.h
105
create mode 100644 include/hw/misc/xlnx-versal-crl.h
106
create mode 100644 include/hw/timer/cadence_ttc.h
107
create mode 100644 hw/misc/xlnx-versal-crl.c
diff view generated by jsdifflib
Deleted patch
1
It's not possible to provide the guest with the Security extensions
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
1
7
$ qemu-system-aarch64 -enable-kvm -machine virt,secure=on -cpu host -display none
8
Unexpected error in object_property_find_err() at ../../qom/object.c:1304:
9
qemu-system-aarch64: Property 'host-arm-cpu.secure-memory' not found
10
Aborted
11
12
Check for this combination of options and report an error, in the
13
same way we already do for attempts to give a KVM or HVF guest the
14
Virtualization or MTE extensions. Now we will report:
15
16
qemu-system-aarch64: mach-virt: KVM does not support providing Security extensions (TrustZone) to the guest CPU
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
28
--- a/hw/arm/virt.c
29
+++ b/hw/arm/virt.c
30
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
31
exit(1);
32
}
33
34
+ if (vms->secure && (kvm_enabled() || hvf_enabled())) {
35
+ error_report("mach-virt: %s does not support providing "
36
+ "Security extensions (TrustZone) to the guest CPU",
37
+ kvm_enabled() ? "KVM" : "HVF");
38
+ exit(1);
39
+ }
40
+
41
if (vms->virt && (kvm_enabled() || hvf_enabled())) {
42
error_report("mach-virt: %s does not support providing "
43
"Virtualization extensions to the guest CPU",
44
--
45
2.25.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Connect the CRL (Clock Reset LPD) to the Versal SoC.
3
Add the missing field for ID_AA64PFR0, and the predicate.
4
Disable it if EL3 is forced off by the board or command-line.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220406174303.2022038-5-edgar.iglesias@xilinx.com
9
Message-id: 20230620124418.805717-2-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
include/hw/arm/xlnx-versal.h | 4 +++
12
target/arm/cpu.h | 6 ++++++
12
hw/arm/xlnx-versal.c | 54 ++++++++++++++++++++++++++++++++++--
13
target/arm/cpu.c | 4 ++++
13
2 files changed, 56 insertions(+), 2 deletions(-)
14
2 files changed, 10 insertions(+)
14
15
15
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/xlnx-versal.h
18
--- a/target/arm/cpu.h
18
+++ b/include/hw/arm/xlnx-versal.h
19
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64PFR0, SEL2, 36, 4)
20
#include "hw/nvram/xlnx-versal-efuse.h"
21
FIELD(ID_AA64PFR0, MPAM, 40, 4)
21
#include "hw/ssi/xlnx-versal-ospi.h"
22
FIELD(ID_AA64PFR0, AMU, 44, 4)
22
#include "hw/dma/xlnx_csu_dma.h"
23
FIELD(ID_AA64PFR0, DIT, 48, 4)
23
+#include "hw/misc/xlnx-versal-crl.h"
24
+FIELD(ID_AA64PFR0, RME, 52, 4)
24
#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
25
FIELD(ID_AA64PFR0, CSV2, 56, 4)
25
26
FIELD(ID_AA64PFR0, CSV3, 60, 4)
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
27
27
@@ -XXX,XX +XXX,XX @@ struct Versal {
28
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sel2(const ARMISARegisters *id)
28
qemu_or_irq irq_orgate;
29
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SEL2) != 0;
29
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
30
} xram;
31
+
32
+ XlnxVersalCRL crl;
33
} lpd;
34
35
/* The Platform Management Controller subsystem. */
36
@@ -XXX,XX +XXX,XX @@ struct Versal {
37
#define VERSAL_TIMER_NS_EL1_IRQ 14
38
#define VERSAL_TIMER_NS_EL2_IRQ 10
39
40
+#define VERSAL_CRL_IRQ 10
41
#define VERSAL_UART0_IRQ_0 18
42
#define VERSAL_UART1_IRQ_0 19
43
#define VERSAL_USB0_IRQ_0 22
44
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/xlnx-versal.c
47
+++ b/hw/arm/xlnx-versal.c
48
@@ -XXX,XX +XXX,XX @@ static void versal_create_ospi(Versal *s, qemu_irq *pic)
49
qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
50
}
30
}
51
31
52
+static void versal_create_crl(Versal *s, qemu_irq *pic)
32
+static inline bool isar_feature_aa64_rme(const ARMISARegisters *id)
53
+{
33
+{
54
+ SysBusDevice *sbd;
34
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RME) != 0;
55
+ int i;
56
+
57
+ object_initialize_child(OBJECT(s), "crl", &s->lpd.crl,
58
+ TYPE_XLNX_VERSAL_CRL);
59
+ sbd = SYS_BUS_DEVICE(&s->lpd.crl);
60
+
61
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
62
+ g_autofree gchar *name = g_strdup_printf("cpu_r5[%d]", i);
63
+
64
+ object_property_set_link(OBJECT(&s->lpd.crl),
65
+ name, OBJECT(&s->lpd.rpu.cpu[i]),
66
+ &error_abort);
67
+ }
68
+
69
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
70
+ g_autofree gchar *name = g_strdup_printf("gem[%d]", i);
71
+
72
+ object_property_set_link(OBJECT(&s->lpd.crl),
73
+ name, OBJECT(&s->lpd.iou.gem[i]),
74
+ &error_abort);
75
+ }
76
+
77
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
78
+ g_autofree gchar *name = g_strdup_printf("adma[%d]", i);
79
+
80
+ object_property_set_link(OBJECT(&s->lpd.crl),
81
+ name, OBJECT(&s->lpd.iou.adma[i]),
82
+ &error_abort);
83
+ }
84
+
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) {
86
+ g_autofree gchar *name = g_strdup_printf("uart[%d]", i);
87
+
88
+ object_property_set_link(OBJECT(&s->lpd.crl),
89
+ name, OBJECT(&s->lpd.iou.uart[i]),
90
+ &error_abort);
91
+ }
92
+
93
+ object_property_set_link(OBJECT(&s->lpd.crl),
94
+ "usb", OBJECT(&s->lpd.iou.usb),
95
+ &error_abort);
96
+
97
+ sysbus_realize(sbd, &error_fatal);
98
+ memory_region_add_subregion(&s->mr_ps, MM_CRL,
99
+ sysbus_mmio_get_region(sbd, 0));
100
+ sysbus_connect_irq(sbd, 0, pic[VERSAL_CRL_IRQ]);
101
+}
35
+}
102
+
36
+
103
/* This takes the board allocated linear DDR memory and creates aliases
37
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
104
* for each split DDR range/aperture on the Versal address map.
38
{
105
*/
39
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
106
@@ -XXX,XX +XXX,XX @@ static void versal_unimp(Versal *s)
40
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
107
41
index XXXXXXX..XXXXXXX 100644
108
versal_unimp_area(s, "psm", &s->mr_ps,
42
--- a/target/arm/cpu.c
109
MM_PSM_START, MM_PSM_END - MM_PSM_START);
43
+++ b/target/arm/cpu.c
110
- versal_unimp_area(s, "crl", &s->mr_ps,
44
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
111
- MM_CRL, MM_CRL_SIZE);
45
cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPSDBG, 0);
112
versal_unimp_area(s, "crf", &s->mr_ps,
46
cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
113
MM_FPD_CRF, MM_FPD_CRF_SIZE);
47
ID_AA64PFR0, EL3, 0);
114
versal_unimp_area(s, "apu", &s->mr_ps,
48
+
115
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
49
+ /* Disable the realm management extension, which requires EL3. */
116
versal_create_efuse(s, pic);
50
+ cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
117
versal_create_pmc_iou_slcr(s, pic);
51
+ ID_AA64PFR0, RME, 0);
118
versal_create_ospi(s, pic);
52
}
119
+ versal_create_crl(s, pic);
53
120
versal_map_ddr(s);
54
if (!cpu->has_el2) {
121
versal_unimp(s);
122
123
--
55
--
124
2.25.1
56
2.34.1
57
58
diff view generated by jsdifflib
1
Switch the creation of the combiner devices to the new-style
1
From: Richard Henderson <richard.henderson@linaro.org>
2
"embedded in state struct" approach, so we can easily refer
3
to the object elsewhere during realize.
4
2
3
Define the missing SCR and HCR bits, allow SCR_NSE and {SCR,HCR}_GPF
4
to be set, and invalidate TLBs when NSE changes.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230620124418.805717-3-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220404154658.565020-18-peter.maydell@linaro.org
8
---
10
---
9
include/hw/arm/exynos4210.h | 3 ++
11
target/arm/cpu.h | 5 +++--
10
include/hw/intc/exynos4210_combiner.h | 57 +++++++++++++++++++++++++++
12
target/arm/helper.c | 10 ++++++++--
11
hw/arm/exynos4210.c | 20 +++++-----
13
2 files changed, 11 insertions(+), 4 deletions(-)
12
hw/intc/exynos4210_combiner.c | 31 +--------------
13
4 files changed, 72 insertions(+), 39 deletions(-)
14
create mode 100644 include/hw/intc/exynos4210_combiner.h
15
14
16
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/exynos4210.h
17
--- a/target/arm/cpu.h
19
+++ b/include/hw/arm/exynos4210.h
18
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
21
#include "hw/sysbus.h"
20
#define HCR_TERR (1ULL << 36)
22
#include "hw/cpu/a9mpcore.h"
21
#define HCR_TEA (1ULL << 37)
23
#include "hw/intc/exynos4210_gic.h"
22
#define HCR_MIOCNCE (1ULL << 38)
24
+#include "hw/intc/exynos4210_combiner.h"
23
-/* RES0 bit 39 */
25
#include "hw/core/split-irq.h"
24
+#define HCR_TME (1ULL << 39)
26
#include "target/arm/cpu-qom.h"
25
#define HCR_APK (1ULL << 40)
27
#include "qom/object.h"
26
#define HCR_API (1ULL << 41)
28
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
27
#define HCR_NV (1ULL << 42)
29
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
28
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
30
A9MPPrivState a9mpcore;
29
#define HCR_NV2 (1ULL << 45)
31
Exynos4210GicState ext_gic;
30
#define HCR_FWB (1ULL << 46)
32
+ Exynos4210CombinerState int_combiner;
31
#define HCR_FIEN (1ULL << 47)
33
+ Exynos4210CombinerState ext_combiner;
32
-/* RES0 bit 48 */
34
SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
33
+#define HCR_GPF (1ULL << 48)
35
};
34
#define HCR_TID4 (1ULL << 49)
36
35
#define HCR_TICAB (1ULL << 50)
37
diff --git a/include/hw/intc/exynos4210_combiner.h b/include/hw/intc/exynos4210_combiner.h
36
#define HCR_AMVOFFEN (1ULL << 51)
38
new file mode 100644
37
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
39
index XXXXXXX..XXXXXXX
38
#define SCR_TRNDR (1ULL << 40)
40
--- /dev/null
39
#define SCR_ENTP2 (1ULL << 41)
41
+++ b/include/hw/intc/exynos4210_combiner.h
40
#define SCR_GPF (1ULL << 48)
42
@@ -XXX,XX +XXX,XX @@
41
+#define SCR_NSE (1ULL << 62)
43
+/*
42
44
+ * Samsung exynos4210 Interrupt Combiner
43
#define HSTR_TTEE (1 << 16)
45
+ *
44
#define HSTR_TJDBX (1 << 17)
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
45
diff --git a/target/arm/helper.c b/target/arm/helper.c
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
46
index XXXXXXX..XXXXXXX 100644
102
--- a/hw/arm/exynos4210.c
47
--- a/target/arm/helper.c
103
+++ b/hw/arm/exynos4210.c
48
+++ b/target/arm/helper.c
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
49
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
50
if (cpu_isar_feature(aa64_fgt, cpu)) {
51
valid_mask |= SCR_FGTEN;
52
}
53
+ if (cpu_isar_feature(aa64_rme, cpu)) {
54
+ valid_mask |= SCR_NSE | SCR_GPF;
55
+ }
56
} else {
57
valid_mask &= ~(SCR_RW | SCR_ST);
58
if (cpu_isar_feature(aa32_ras, cpu)) {
59
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
60
env->cp15.scr_el3 = value;
61
62
/*
63
- * If SCR_EL3.NS changes, i.e. arm_is_secure_below_el3, then
64
+ * If SCR_EL3.{NS,NSE} changes, i.e. change of security state,
65
* we must invalidate all TLBs below EL3.
66
*/
67
- if (changed & SCR_NS) {
68
+ if (changed & (SCR_NS | SCR_NSE)) {
69
tlb_flush_by_mmuidx(env_cpu(env), (ARMMMUIdxBit_E10_0 |
70
ARMMMUIdxBit_E20_0 |
71
ARMMMUIdxBit_E10_1 |
72
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
73
if (cpu_isar_feature(aa64_fwb, cpu)) {
74
valid_mask |= HCR_FWB;
75
}
76
+ if (cpu_isar_feature(aa64_rme, cpu)) {
77
+ valid_mask |= HCR_GPF;
78
+ }
105
}
79
}
106
80
107
/* Internal Interrupt Combiner */
81
if (cpu_isar_feature(any_evt, cpu)) {
108
- dev = qdev_new("exynos4210.combiner");
109
- busdev = SYS_BUS_DEVICE(dev);
110
- sysbus_realize_and_unref(busdev, &error_fatal);
111
+ busdev = SYS_BUS_DEVICE(&s->int_combiner);
112
+ sysbus_realize(busdev, &error_fatal);
113
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
114
sysbus_connect_irq(busdev, n,
115
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
116
}
117
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
118
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
119
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
120
121
/* External Interrupt Combiner */
122
- dev = qdev_new("exynos4210.combiner");
123
- qdev_prop_set_uint32(dev, "external", 1);
124
- busdev = SYS_BUS_DEVICE(dev);
125
- sysbus_realize_and_unref(busdev, &error_fatal);
126
+ qdev_prop_set_uint32(DEVICE(&s->ext_combiner), "external", 1);
127
+ busdev = SYS_BUS_DEVICE(&s->ext_combiner);
128
+ sysbus_realize(busdev, &error_fatal);
129
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
130
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
131
}
132
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
133
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
134
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
135
136
/* Initialize board IRQs. */
137
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
138
139
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
140
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
141
+ object_initialize_child(obj, "int-combiner", &s->int_combiner,
142
+ TYPE_EXYNOS4210_COMBINER);
143
+ object_initialize_child(obj, "ext-combiner", &s->ext_combiner,
144
+ TYPE_EXYNOS4210_COMBINER);
145
}
146
147
static void exynos4210_class_init(ObjectClass *klass, void *data)
148
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/hw/intc/exynos4210_combiner.c
151
+++ b/hw/intc/exynos4210_combiner.c
152
@@ -XXX,XX +XXX,XX @@
153
#include "hw/sysbus.h"
154
#include "migration/vmstate.h"
155
#include "qemu/module.h"
156
-
157
+#include "hw/intc/exynos4210_combiner.h"
158
#include "hw/arm/exynos4210.h"
159
#include "hw/hw.h"
160
#include "hw/irq.h"
161
@@ -XXX,XX +XXX,XX @@
162
#define DPRINTF(fmt, ...) do {} while (0)
163
#endif
164
165
-#define IIC_NGRP 64 /* Internal Interrupt Combiner
166
- Groups number */
167
-#define IIC_NIRQ (IIC_NGRP * 8)/* Internal Interrupt Combiner
168
- Interrupts number */
169
#define IIC_REGION_SIZE 0x108 /* Size of memory mapped region */
170
-#define IIC_REGSET_SIZE 0x41
171
-
172
-/*
173
- * State for each output signal of internal combiner
174
- */
175
-typedef struct CombinerGroupState {
176
- uint8_t src_mask; /* 1 - source enabled, 0 - disabled */
177
- uint8_t src_pending; /* Pending source interrupts before masking */
178
-} CombinerGroupState;
179
-
180
-#define TYPE_EXYNOS4210_COMBINER "exynos4210.combiner"
181
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210CombinerState, EXYNOS4210_COMBINER)
182
-
183
-struct Exynos4210CombinerState {
184
- SysBusDevice parent_obj;
185
-
186
- MemoryRegion iomem;
187
-
188
- struct CombinerGroupState group[IIC_NGRP];
189
- uint32_t reg_set[IIC_REGSET_SIZE];
190
- uint32_t icipsr[2];
191
- uint32_t external; /* 1 means that this combiner is external */
192
-
193
- qemu_irq output_irq[IIC_NGRP];
194
-};
195
196
static const VMStateDescription vmstate_exynos4210_combiner_group_state = {
197
.name = "exynos4210.combiner.groupstate",
198
--
82
--
199
2.25.1
83
2.34.1
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This patch uses the defined fields to describe PWRON STRAPs for
3
With RME, SEL2 must also be present to support secure state.
4
better readability.
4
The NS bit is RES1 if SEL2 is not present.
5
5
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
7
Reviewed-by: Patrick Venture <venture@google.com>
8
Message-id: 20220411165842.3912945-3-wuhaotsh@google.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230620124418.805717-4-richard.henderson@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/helper.c | 3 +++
13
1 file changed, 19 insertions(+), 5 deletions(-)
12
1 file changed, 3 insertions(+)
14
13
15
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/npcm7xx_boards.c
16
--- a/target/arm/helper.c
18
+++ b/hw/arm/npcm7xx_boards.c
17
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
20
#include "sysemu/sysemu.h"
19
}
21
#include "sysemu/block-backend.h"
20
if (cpu_isar_feature(aa64_sel2, cpu)) {
22
21
valid_mask |= SCR_EEL2;
23
-#define NPCM750_EVB_POWER_ON_STRAPS 0x00001ff7
22
+ } else if (cpu_isar_feature(aa64_rme, cpu)) {
24
-#define QUANTA_GSJ_POWER_ON_STRAPS 0x00001fff
23
+ /* With RME and without SEL2, NS is RES1 (R_GSWWH, I_DJJQJ). */
25
-#define QUANTA_GBS_POWER_ON_STRAPS 0x000017ff
24
+ value |= SCR_NS;
26
-#define KUDO_BMC_POWER_ON_STRAPS 0x00001fff
25
}
27
-#define MORI_BMC_POWER_ON_STRAPS 0x00001fff
26
if (cpu_isar_feature(aa64_mte, cpu)) {
28
+#define NPCM7XX_POWER_ON_STRAPS_DEFAULT ( \
27
valid_mask |= SCR_ATA;
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
--
28
--
51
2.25.1
29
2.34.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add a model of the Xilinx Versal CRL.
3
This includes GPCCR, GPTBR, MFAR, the TLB flush insns PAALL, PAALLOS,
4
RPALOS, RPAOS, and the cache flush insns CIPAPA and CIGDPAPA.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Message-id: 20230620124418.805717-5-richard.henderson@linaro.org
8
Message-id: 20220406174303.2022038-4-edgar.iglesias@xilinx.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++
11
target/arm/cpu.h | 19 ++++++++++
12
hw/misc/xlnx-versal-crl.c | 421 ++++++++++++++++++++++++++++++
12
target/arm/helper.c | 84 +++++++++++++++++++++++++++++++++++++++++++++
13
hw/misc/meson.build | 1 +
13
2 files changed, 103 insertions(+)
14
3 files changed, 657 insertions(+)
15
create mode 100644 include/hw/misc/xlnx-versal-crl.h
16
create mode 100644 hw/misc/xlnx-versal-crl.c
17
14
18
diff --git a/include/hw/misc/xlnx-versal-crl.h b/include/hw/misc/xlnx-versal-crl.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
new file mode 100644
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX
17
--- a/target/arm/cpu.h
21
--- /dev/null
18
+++ b/target/arm/cpu.h
22
+++ b/include/hw/misc/xlnx-versal-crl.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
23
@@ -XXX,XX +XXX,XX @@
20
uint64_t fgt_read[2]; /* HFGRTR, HDFGRTR */
24
+/*
21
uint64_t fgt_write[2]; /* HFGWTR, HDFGWTR */
25
+ * QEMU model of the Clock-Reset-LPD (CRL).
22
uint64_t fgt_exec[1]; /* HFGITR */
26
+ *
27
+ * Copyright (c) 2022 Xilinx Inc.
28
+ * SPDX-License-Identifier: GPL-2.0-or-later
29
+ *
30
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
31
+ */
32
+#ifndef HW_MISC_XLNX_VERSAL_CRL_H
33
+#define HW_MISC_XLNX_VERSAL_CRL_H
34
+
23
+
35
+#include "hw/sysbus.h"
24
+ /* RME registers */
36
+#include "hw/register.h"
25
+ uint64_t gpccr_el3;
37
+#include "target/arm/cpu.h"
26
+ uint64_t gptbr_el3;
27
+ uint64_t mfar_el3;
28
} cp15;
29
30
struct {
31
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
32
uint64_t reset_cbar;
33
uint32_t reset_auxcr;
34
bool reset_hivecs;
35
+ uint8_t reset_l0gptsz;
36
37
/*
38
* Intermediate values used during property parsing.
39
@@ -XXX,XX +XXX,XX @@ FIELD(MVFR1, SIMDFMAC, 28, 4)
40
FIELD(MVFR2, SIMDMISC, 0, 4)
41
FIELD(MVFR2, FPMISC, 4, 4)
42
43
+FIELD(GPCCR, PPS, 0, 3)
44
+FIELD(GPCCR, IRGN, 8, 2)
45
+FIELD(GPCCR, ORGN, 10, 2)
46
+FIELD(GPCCR, SH, 12, 2)
47
+FIELD(GPCCR, PGS, 14, 2)
48
+FIELD(GPCCR, GPC, 16, 1)
49
+FIELD(GPCCR, GPCP, 17, 1)
50
+FIELD(GPCCR, L0GPTSZ, 20, 4)
38
+
51
+
39
+#define TYPE_XLNX_VERSAL_CRL "xlnx,versal-crl"
52
+FIELD(MFAR, FPA, 12, 40)
40
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCRL, XLNX_VERSAL_CRL)
53
+FIELD(MFAR, NSE, 62, 1)
54
+FIELD(MFAR, NS, 63, 1)
41
+
55
+
42
+REG32(ERR_CTRL, 0x0)
56
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
43
+ FIELD(ERR_CTRL, SLVERR_ENABLE, 0, 1)
57
44
+REG32(IR_STATUS, 0x4)
58
/* If adding a feature bit which corresponds to a Linux ELF
45
+ FIELD(IR_STATUS, ADDR_DECODE_ERR, 0, 1)
59
diff --git a/target/arm/helper.c b/target/arm/helper.c
46
+REG32(IR_MASK, 0x8)
60
index XXXXXXX..XXXXXXX 100644
47
+ FIELD(IR_MASK, ADDR_DECODE_ERR, 0, 1)
61
--- a/target/arm/helper.c
48
+REG32(IR_ENABLE, 0xc)
62
+++ b/target/arm/helper.c
49
+ FIELD(IR_ENABLE, ADDR_DECODE_ERR, 0, 1)
63
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
50
+REG32(IR_DISABLE, 0x10)
64
.access = PL2_RW, .accessfn = access_esm,
51
+ FIELD(IR_DISABLE, ADDR_DECODE_ERR, 0, 1)
65
.type = ARM_CP_CONST, .resetvalue = 0 },
52
+REG32(WPROT, 0x1c)
66
};
53
+ FIELD(WPROT, ACTIVE, 0, 1)
54
+REG32(PLL_CLK_OTHER_DMN, 0x20)
55
+ FIELD(PLL_CLK_OTHER_DMN, APLL_BYPASS, 0, 1)
56
+REG32(RPLL_CTRL, 0x40)
57
+ FIELD(RPLL_CTRL, POST_SRC, 24, 3)
58
+ FIELD(RPLL_CTRL, PRE_SRC, 20, 3)
59
+ FIELD(RPLL_CTRL, CLKOUTDIV, 16, 2)
60
+ FIELD(RPLL_CTRL, FBDIV, 8, 8)
61
+ FIELD(RPLL_CTRL, BYPASS, 3, 1)
62
+ FIELD(RPLL_CTRL, RESET, 0, 1)
63
+REG32(RPLL_CFG, 0x44)
64
+ FIELD(RPLL_CFG, LOCK_DLY, 25, 7)
65
+ FIELD(RPLL_CFG, LOCK_CNT, 13, 10)
66
+ FIELD(RPLL_CFG, LFHF, 10, 2)
67
+ FIELD(RPLL_CFG, CP, 5, 4)
68
+ FIELD(RPLL_CFG, RES, 0, 4)
69
+REG32(RPLL_FRAC_CFG, 0x48)
70
+ FIELD(RPLL_FRAC_CFG, ENABLED, 31, 1)
71
+ FIELD(RPLL_FRAC_CFG, SEED, 22, 3)
72
+ FIELD(RPLL_FRAC_CFG, ALGRTHM, 19, 1)
73
+ FIELD(RPLL_FRAC_CFG, ORDER, 18, 1)
74
+ FIELD(RPLL_FRAC_CFG, DATA, 0, 16)
75
+REG32(PLL_STATUS, 0x50)
76
+ FIELD(PLL_STATUS, RPLL_STABLE, 2, 1)
77
+ FIELD(PLL_STATUS, RPLL_LOCK, 0, 1)
78
+REG32(RPLL_TO_XPD_CTRL, 0x100)
79
+ FIELD(RPLL_TO_XPD_CTRL, CLKACT, 25, 1)
80
+ FIELD(RPLL_TO_XPD_CTRL, DIVISOR0, 8, 10)
81
+REG32(LPD_TOP_SWITCH_CTRL, 0x104)
82
+ FIELD(LPD_TOP_SWITCH_CTRL, CLKACT_ADMA, 26, 1)
83
+ FIELD(LPD_TOP_SWITCH_CTRL, CLKACT, 25, 1)
84
+ FIELD(LPD_TOP_SWITCH_CTRL, DIVISOR0, 8, 10)
85
+ FIELD(LPD_TOP_SWITCH_CTRL, SRCSEL, 0, 3)
86
+REG32(LPD_LSBUS_CTRL, 0x108)
87
+ FIELD(LPD_LSBUS_CTRL, CLKACT, 25, 1)
88
+ FIELD(LPD_LSBUS_CTRL, DIVISOR0, 8, 10)
89
+ FIELD(LPD_LSBUS_CTRL, SRCSEL, 0, 3)
90
+REG32(CPU_R5_CTRL, 0x10c)
91
+ FIELD(CPU_R5_CTRL, CLKACT_OCM2, 28, 1)
92
+ FIELD(CPU_R5_CTRL, CLKACT_OCM, 27, 1)
93
+ FIELD(CPU_R5_CTRL, CLKACT_CORE, 26, 1)
94
+ FIELD(CPU_R5_CTRL, CLKACT, 25, 1)
95
+ FIELD(CPU_R5_CTRL, DIVISOR0, 8, 10)
96
+ FIELD(CPU_R5_CTRL, SRCSEL, 0, 3)
97
+REG32(IOU_SWITCH_CTRL, 0x114)
98
+ FIELD(IOU_SWITCH_CTRL, CLKACT, 25, 1)
99
+ FIELD(IOU_SWITCH_CTRL, DIVISOR0, 8, 10)
100
+ FIELD(IOU_SWITCH_CTRL, SRCSEL, 0, 3)
101
+REG32(GEM0_REF_CTRL, 0x118)
102
+ FIELD(GEM0_REF_CTRL, CLKACT_RX, 27, 1)
103
+ FIELD(GEM0_REF_CTRL, CLKACT_TX, 26, 1)
104
+ FIELD(GEM0_REF_CTRL, CLKACT, 25, 1)
105
+ FIELD(GEM0_REF_CTRL, DIVISOR0, 8, 10)
106
+ FIELD(GEM0_REF_CTRL, SRCSEL, 0, 3)
107
+REG32(GEM1_REF_CTRL, 0x11c)
108
+ FIELD(GEM1_REF_CTRL, CLKACT_RX, 27, 1)
109
+ FIELD(GEM1_REF_CTRL, CLKACT_TX, 26, 1)
110
+ FIELD(GEM1_REF_CTRL, CLKACT, 25, 1)
111
+ FIELD(GEM1_REF_CTRL, DIVISOR0, 8, 10)
112
+ FIELD(GEM1_REF_CTRL, SRCSEL, 0, 3)
113
+REG32(GEM_TSU_REF_CTRL, 0x120)
114
+ FIELD(GEM_TSU_REF_CTRL, CLKACT, 25, 1)
115
+ FIELD(GEM_TSU_REF_CTRL, DIVISOR0, 8, 10)
116
+ FIELD(GEM_TSU_REF_CTRL, SRCSEL, 0, 3)
117
+REG32(USB0_BUS_REF_CTRL, 0x124)
118
+ FIELD(USB0_BUS_REF_CTRL, CLKACT, 25, 1)
119
+ FIELD(USB0_BUS_REF_CTRL, DIVISOR0, 8, 10)
120
+ FIELD(USB0_BUS_REF_CTRL, SRCSEL, 0, 3)
121
+REG32(UART0_REF_CTRL, 0x128)
122
+ FIELD(UART0_REF_CTRL, CLKACT, 25, 1)
123
+ FIELD(UART0_REF_CTRL, DIVISOR0, 8, 10)
124
+ FIELD(UART0_REF_CTRL, SRCSEL, 0, 3)
125
+REG32(UART1_REF_CTRL, 0x12c)
126
+ FIELD(UART1_REF_CTRL, CLKACT, 25, 1)
127
+ FIELD(UART1_REF_CTRL, DIVISOR0, 8, 10)
128
+ FIELD(UART1_REF_CTRL, SRCSEL, 0, 3)
129
+REG32(SPI0_REF_CTRL, 0x130)
130
+ FIELD(SPI0_REF_CTRL, CLKACT, 25, 1)
131
+ FIELD(SPI0_REF_CTRL, DIVISOR0, 8, 10)
132
+ FIELD(SPI0_REF_CTRL, SRCSEL, 0, 3)
133
+REG32(SPI1_REF_CTRL, 0x134)
134
+ FIELD(SPI1_REF_CTRL, CLKACT, 25, 1)
135
+ FIELD(SPI1_REF_CTRL, DIVISOR0, 8, 10)
136
+ FIELD(SPI1_REF_CTRL, SRCSEL, 0, 3)
137
+REG32(CAN0_REF_CTRL, 0x138)
138
+ FIELD(CAN0_REF_CTRL, CLKACT, 25, 1)
139
+ FIELD(CAN0_REF_CTRL, DIVISOR0, 8, 10)
140
+ FIELD(CAN0_REF_CTRL, SRCSEL, 0, 3)
141
+REG32(CAN1_REF_CTRL, 0x13c)
142
+ FIELD(CAN1_REF_CTRL, CLKACT, 25, 1)
143
+ FIELD(CAN1_REF_CTRL, DIVISOR0, 8, 10)
144
+ FIELD(CAN1_REF_CTRL, SRCSEL, 0, 3)
145
+REG32(I2C0_REF_CTRL, 0x140)
146
+ FIELD(I2C0_REF_CTRL, CLKACT, 25, 1)
147
+ FIELD(I2C0_REF_CTRL, DIVISOR0, 8, 10)
148
+ FIELD(I2C0_REF_CTRL, SRCSEL, 0, 3)
149
+REG32(I2C1_REF_CTRL, 0x144)
150
+ FIELD(I2C1_REF_CTRL, CLKACT, 25, 1)
151
+ FIELD(I2C1_REF_CTRL, DIVISOR0, 8, 10)
152
+ FIELD(I2C1_REF_CTRL, SRCSEL, 0, 3)
153
+REG32(DBG_LPD_CTRL, 0x148)
154
+ FIELD(DBG_LPD_CTRL, CLKACT, 25, 1)
155
+ FIELD(DBG_LPD_CTRL, DIVISOR0, 8, 10)
156
+ FIELD(DBG_LPD_CTRL, SRCSEL, 0, 3)
157
+REG32(TIMESTAMP_REF_CTRL, 0x14c)
158
+ FIELD(TIMESTAMP_REF_CTRL, CLKACT, 25, 1)
159
+ FIELD(TIMESTAMP_REF_CTRL, DIVISOR0, 8, 10)
160
+ FIELD(TIMESTAMP_REF_CTRL, SRCSEL, 0, 3)
161
+REG32(CRL_SAFETY_CHK, 0x150)
162
+REG32(PSM_REF_CTRL, 0x154)
163
+ FIELD(PSM_REF_CTRL, DIVISOR0, 8, 10)
164
+ FIELD(PSM_REF_CTRL, SRCSEL, 0, 3)
165
+REG32(DBG_TSTMP_CTRL, 0x158)
166
+ FIELD(DBG_TSTMP_CTRL, CLKACT, 25, 1)
167
+ FIELD(DBG_TSTMP_CTRL, DIVISOR0, 8, 10)
168
+ FIELD(DBG_TSTMP_CTRL, SRCSEL, 0, 3)
169
+REG32(CPM_TOPSW_REF_CTRL, 0x15c)
170
+ FIELD(CPM_TOPSW_REF_CTRL, CLKACT, 25, 1)
171
+ FIELD(CPM_TOPSW_REF_CTRL, DIVISOR0, 8, 10)
172
+ FIELD(CPM_TOPSW_REF_CTRL, SRCSEL, 0, 3)
173
+REG32(USB3_DUAL_REF_CTRL, 0x160)
174
+ FIELD(USB3_DUAL_REF_CTRL, CLKACT, 25, 1)
175
+ FIELD(USB3_DUAL_REF_CTRL, DIVISOR0, 8, 10)
176
+ FIELD(USB3_DUAL_REF_CTRL, SRCSEL, 0, 3)
177
+REG32(RST_CPU_R5, 0x300)
178
+ FIELD(RST_CPU_R5, RESET_PGE, 4, 1)
179
+ FIELD(RST_CPU_R5, RESET_AMBA, 2, 1)
180
+ FIELD(RST_CPU_R5, RESET_CPU1, 1, 1)
181
+ FIELD(RST_CPU_R5, RESET_CPU0, 0, 1)
182
+REG32(RST_ADMA, 0x304)
183
+ FIELD(RST_ADMA, RESET, 0, 1)
184
+REG32(RST_GEM0, 0x308)
185
+ FIELD(RST_GEM0, RESET, 0, 1)
186
+REG32(RST_GEM1, 0x30c)
187
+ FIELD(RST_GEM1, RESET, 0, 1)
188
+REG32(RST_SPARE, 0x310)
189
+ FIELD(RST_SPARE, RESET, 0, 1)
190
+REG32(RST_USB0, 0x314)
191
+ FIELD(RST_USB0, RESET, 0, 1)
192
+REG32(RST_UART0, 0x318)
193
+ FIELD(RST_UART0, RESET, 0, 1)
194
+REG32(RST_UART1, 0x31c)
195
+ FIELD(RST_UART1, RESET, 0, 1)
196
+REG32(RST_SPI0, 0x320)
197
+ FIELD(RST_SPI0, RESET, 0, 1)
198
+REG32(RST_SPI1, 0x324)
199
+ FIELD(RST_SPI1, RESET, 0, 1)
200
+REG32(RST_CAN0, 0x328)
201
+ FIELD(RST_CAN0, RESET, 0, 1)
202
+REG32(RST_CAN1, 0x32c)
203
+ FIELD(RST_CAN1, RESET, 0, 1)
204
+REG32(RST_I2C0, 0x330)
205
+ FIELD(RST_I2C0, RESET, 0, 1)
206
+REG32(RST_I2C1, 0x334)
207
+ FIELD(RST_I2C1, RESET, 0, 1)
208
+REG32(RST_DBG_LPD, 0x338)
209
+ FIELD(RST_DBG_LPD, RPU_DBG1_RESET, 5, 1)
210
+ FIELD(RST_DBG_LPD, RPU_DBG0_RESET, 4, 1)
211
+ FIELD(RST_DBG_LPD, RESET_HSDP, 1, 1)
212
+ FIELD(RST_DBG_LPD, RESET, 0, 1)
213
+REG32(RST_GPIO, 0x33c)
214
+ FIELD(RST_GPIO, RESET, 0, 1)
215
+REG32(RST_TTC, 0x344)
216
+ FIELD(RST_TTC, TTC3_RESET, 3, 1)
217
+ FIELD(RST_TTC, TTC2_RESET, 2, 1)
218
+ FIELD(RST_TTC, TTC1_RESET, 1, 1)
219
+ FIELD(RST_TTC, TTC0_RESET, 0, 1)
220
+REG32(RST_TIMESTAMP, 0x348)
221
+ FIELD(RST_TIMESTAMP, RESET, 0, 1)
222
+REG32(RST_SWDT, 0x34c)
223
+ FIELD(RST_SWDT, RESET, 0, 1)
224
+REG32(RST_OCM, 0x350)
225
+ FIELD(RST_OCM, RESET, 0, 1)
226
+REG32(RST_IPI, 0x354)
227
+ FIELD(RST_IPI, RESET, 0, 1)
228
+REG32(RST_SYSMON, 0x358)
229
+ FIELD(RST_SYSMON, SEQ_RST, 1, 1)
230
+ FIELD(RST_SYSMON, CFG_RST, 0, 1)
231
+REG32(RST_FPD, 0x360)
232
+ FIELD(RST_FPD, SRST, 1, 1)
233
+ FIELD(RST_FPD, POR, 0, 1)
234
+REG32(PSM_RST_MODE, 0x370)
235
+ FIELD(PSM_RST_MODE, WAKEUP, 2, 1)
236
+ FIELD(PSM_RST_MODE, RST_MODE, 0, 2)
237
+
67
+
238
+#define CRL_R_MAX (R_PSM_RST_MODE + 1)
68
+static void tlbi_aa64_paall_write(CPUARMState *env, const ARMCPRegInfo *ri,
69
+ uint64_t value)
70
+{
71
+ CPUState *cs = env_cpu(env);
239
+
72
+
240
+#define RPU_MAX_CPU 2
73
+ tlb_flush(cs);
241
+
242
+struct XlnxVersalCRL {
243
+ SysBusDevice parent_obj;
244
+ qemu_irq irq;
245
+
246
+ struct {
247
+ ARMCPU *cpu_r5[RPU_MAX_CPU];
248
+ DeviceState *adma[8];
249
+ DeviceState *uart[2];
250
+ DeviceState *gem[2];
251
+ DeviceState *usb;
252
+ } cfg;
253
+
254
+ RegisterInfoArray *reg_array;
255
+ uint32_t regs[CRL_R_MAX];
256
+ RegisterInfo regs_info[CRL_R_MAX];
257
+};
258
+#endif
259
diff --git a/hw/misc/xlnx-versal-crl.c b/hw/misc/xlnx-versal-crl.c
260
new file mode 100644
261
index XXXXXXX..XXXXXXX
262
--- /dev/null
263
+++ b/hw/misc/xlnx-versal-crl.c
264
@@ -XXX,XX +XXX,XX @@
265
+/*
266
+ * QEMU model of the Clock-Reset-LPD (CRL).
267
+ *
268
+ * Copyright (c) 2022 Advanced Micro Devices, Inc.
269
+ * SPDX-License-Identifier: GPL-2.0-or-later
270
+ *
271
+ * Written by Edgar E. Iglesias <edgar.iglesias@amd.com>
272
+ */
273
+
274
+#include "qemu/osdep.h"
275
+#include "qapi/error.h"
276
+#include "qemu/log.h"
277
+#include "qemu/bitops.h"
278
+#include "migration/vmstate.h"
279
+#include "hw/qdev-properties.h"
280
+#include "hw/sysbus.h"
281
+#include "hw/irq.h"
282
+#include "hw/register.h"
283
+#include "hw/resettable.h"
284
+
285
+#include "target/arm/arm-powerctl.h"
286
+#include "hw/misc/xlnx-versal-crl.h"
287
+
288
+#ifndef XLNX_VERSAL_CRL_ERR_DEBUG
289
+#define XLNX_VERSAL_CRL_ERR_DEBUG 0
290
+#endif
291
+
292
+static void crl_update_irq(XlnxVersalCRL *s)
293
+{
294
+ bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK];
295
+ qemu_set_irq(s->irq, pending);
296
+}
74
+}
297
+
75
+
298
+static void crl_status_postw(RegisterInfo *reg, uint64_t val64)
76
+static void gpccr_write(CPUARMState *env, const ARMCPRegInfo *ri,
77
+ uint64_t value)
299
+{
78
+{
300
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
79
+ /* L0GPTSZ is RO; other bits not mentioned are RES0. */
301
+ crl_update_irq(s);
80
+ uint64_t rw_mask = R_GPCCR_PPS_MASK | R_GPCCR_IRGN_MASK |
81
+ R_GPCCR_ORGN_MASK | R_GPCCR_SH_MASK | R_GPCCR_PGS_MASK |
82
+ R_GPCCR_GPC_MASK | R_GPCCR_GPCP_MASK;
83
+
84
+ env->cp15.gpccr_el3 = (value & rw_mask) | (env->cp15.gpccr_el3 & ~rw_mask);
302
+}
85
+}
303
+
86
+
304
+static uint64_t crl_enable_prew(RegisterInfo *reg, uint64_t val64)
87
+static void gpccr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
305
+{
88
+{
306
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
89
+ env->cp15.gpccr_el3 = FIELD_DP64(0, GPCCR, L0GPTSZ,
307
+ uint32_t val = val64;
90
+ env_archcpu(env)->reset_l0gptsz);
308
+
309
+ s->regs[R_IR_MASK] &= ~val;
310
+ crl_update_irq(s);
311
+ return 0;
312
+}
91
+}
313
+
92
+
314
+static uint64_t crl_disable_prew(RegisterInfo *reg, uint64_t val64)
93
+static void tlbi_aa64_paallos_write(CPUARMState *env, const ARMCPRegInfo *ri,
94
+ uint64_t value)
315
+{
95
+{
316
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
96
+ CPUState *cs = env_cpu(env);
317
+ uint32_t val = val64;
318
+
97
+
319
+ s->regs[R_IR_MASK] |= val;
98
+ tlb_flush_all_cpus_synced(cs);
320
+ crl_update_irq(s);
321
+ return 0;
322
+}
99
+}
323
+
100
+
324
+static void crl_reset_dev(XlnxVersalCRL *s, DeviceState *dev,
101
+static const ARMCPRegInfo rme_reginfo[] = {
325
+ bool rst_old, bool rst_new)
102
+ { .name = "GPCCR_EL3", .state = ARM_CP_STATE_AA64,
326
+{
103
+ .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 1, .opc2 = 6,
327
+ device_cold_reset(dev);
104
+ .access = PL3_RW, .writefn = gpccr_write, .resetfn = gpccr_reset,
328
+}
105
+ .fieldoffset = offsetof(CPUARMState, cp15.gpccr_el3) },
329
+
106
+ { .name = "GPTBR_EL3", .state = ARM_CP_STATE_AA64,
330
+static void crl_reset_cpu(XlnxVersalCRL *s, ARMCPU *armcpu,
107
+ .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 1, .opc2 = 4,
331
+ bool rst_old, bool rst_new)
108
+ .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.gptbr_el3) },
332
+{
109
+ { .name = "MFAR_EL3", .state = ARM_CP_STATE_AA64,
333
+ if (rst_new) {
110
+ .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 5,
334
+ arm_set_cpu_off(armcpu->mp_affinity);
111
+ .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.mfar_el3) },
335
+ } else {
112
+ { .name = "TLBI_PAALL", .state = ARM_CP_STATE_AA64,
336
+ arm_set_cpu_on_and_reset(armcpu->mp_affinity);
113
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 4,
337
+ }
114
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
338
+}
115
+ .writefn = tlbi_aa64_paall_write },
339
+
116
+ { .name = "TLBI_PAALLOS", .state = ARM_CP_STATE_AA64,
340
+#define REGFIELD_RESET(type, s, reg, f, new_val, dev) { \
117
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 4,
341
+ bool old_f = ARRAY_FIELD_EX32((s)->regs, reg, f); \
118
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
342
+ bool new_f = FIELD_EX32(new_val, reg, f); \
119
+ .writefn = tlbi_aa64_paallos_write },
343
+ \
120
+ /*
344
+ /* Detect edges. */ \
121
+ * QEMU does not have a way to invalidate by physical address, thus
345
+ if (dev && old_f != new_f) { \
122
+ * invalidating a range of physical addresses is accomplished by
346
+ crl_reset_ ## type(s, dev, old_f, new_f); \
123
+ * flushing all tlb entries in the outer sharable domain,
347
+ } \
124
+ * just like PAALLOS.
348
+}
125
+ */
349
+
126
+ { .name = "TLBI_RPALOS", .state = ARM_CP_STATE_AA64,
350
+static uint64_t crl_rst_r5_prew(RegisterInfo *reg, uint64_t val64)
127
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 4, .opc2 = 7,
351
+{
128
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
352
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
129
+ .writefn = tlbi_aa64_paallos_write },
353
+
130
+ { .name = "TLBI_RPAOS", .state = ARM_CP_STATE_AA64,
354
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU0, val64, s->cfg.cpu_r5[0]);
131
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 4, .opc2 = 3,
355
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU1, val64, s->cfg.cpu_r5[1]);
132
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
356
+ return val64;
133
+ .writefn = tlbi_aa64_paallos_write },
357
+}
134
+ { .name = "DC_CIPAPA", .state = ARM_CP_STATE_AA64,
358
+
135
+ .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 14, .opc2 = 1,
359
+static uint64_t crl_rst_adma_prew(RegisterInfo *reg, uint64_t val64)
136
+ .access = PL3_W, .type = ARM_CP_NOP },
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
+};
137
+};
566
+
138
+
567
+static void crl_reset_enter(Object *obj, ResetType type)
139
+static const ARMCPRegInfo rme_mte_reginfo[] = {
568
+{
140
+ { .name = "DC_CIGDPAPA", .state = ARM_CP_STATE_AA64,
569
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
141
+ .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 14, .opc2 = 5,
570
+ unsigned int i;
142
+ .access = PL3_W, .type = ARM_CP_NOP },
143
+};
144
#endif /* TARGET_AARCH64 */
145
146
static void define_pmu_regs(ARMCPU *cpu)
147
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
148
if (cpu_isar_feature(aa64_fgt, cpu)) {
149
define_arm_cp_regs(cpu, fgt_reginfo);
150
}
571
+
151
+
572
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
152
+ if (cpu_isar_feature(aa64_rme, cpu)) {
573
+ register_reset(&s->regs_info[i]);
153
+ define_arm_cp_regs(cpu, rme_reginfo);
154
+ if (cpu_isar_feature(aa64_mte, cpu)) {
155
+ define_arm_cp_regs(cpu, rme_mte_reginfo);
156
+ }
574
+ }
157
+ }
575
+}
158
#endif
576
+
159
577
+static void crl_reset_hold(Object *obj)
160
if (cpu_isar_feature(any_predinv, cpu)) {
578
+{
579
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
580
+
581
+ crl_update_irq(s);
582
+}
583
+
584
+static const MemoryRegionOps crl_ops = {
585
+ .read = register_read_memory,
586
+ .write = register_write_memory,
587
+ .endianness = DEVICE_LITTLE_ENDIAN,
588
+ .valid = {
589
+ .min_access_size = 4,
590
+ .max_access_size = 4,
591
+ },
592
+};
593
+
594
+static void crl_init(Object *obj)
595
+{
596
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
597
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
598
+ int i;
599
+
600
+ s->reg_array =
601
+ register_init_block32(DEVICE(obj), crl_regs_info,
602
+ ARRAY_SIZE(crl_regs_info),
603
+ s->regs_info, s->regs,
604
+ &crl_ops,
605
+ XLNX_VERSAL_CRL_ERR_DEBUG,
606
+ CRL_R_MAX * 4);
607
+ sysbus_init_mmio(sbd, &s->reg_array->mem);
608
+ sysbus_init_irq(sbd, &s->irq);
609
+
610
+ for (i = 0; i < ARRAY_SIZE(s->cfg.cpu_r5); ++i) {
611
+ object_property_add_link(obj, "cpu_r5[*]", TYPE_ARM_CPU,
612
+ (Object **)&s->cfg.cpu_r5[i],
613
+ qdev_prop_allow_set_link_before_realize,
614
+ OBJ_PROP_LINK_STRONG);
615
+ }
616
+
617
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); ++i) {
618
+ object_property_add_link(obj, "adma[*]", TYPE_DEVICE,
619
+ (Object **)&s->cfg.adma[i],
620
+ qdev_prop_allow_set_link_before_realize,
621
+ OBJ_PROP_LINK_STRONG);
622
+ }
623
+
624
+ for (i = 0; i < ARRAY_SIZE(s->cfg.uart); ++i) {
625
+ object_property_add_link(obj, "uart[*]", TYPE_DEVICE,
626
+ (Object **)&s->cfg.uart[i],
627
+ qdev_prop_allow_set_link_before_realize,
628
+ OBJ_PROP_LINK_STRONG);
629
+ }
630
+
631
+ for (i = 0; i < ARRAY_SIZE(s->cfg.gem); ++i) {
632
+ object_property_add_link(obj, "gem[*]", TYPE_DEVICE,
633
+ (Object **)&s->cfg.gem[i],
634
+ qdev_prop_allow_set_link_before_realize,
635
+ OBJ_PROP_LINK_STRONG);
636
+ }
637
+
638
+ object_property_add_link(obj, "usb", TYPE_DEVICE,
639
+ (Object **)&s->cfg.gem[i],
640
+ qdev_prop_allow_set_link_before_realize,
641
+ OBJ_PROP_LINK_STRONG);
642
+}
643
+
644
+static void crl_finalize(Object *obj)
645
+{
646
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
647
+ register_finalize_block(s->reg_array);
648
+}
649
+
650
+static const VMStateDescription vmstate_crl = {
651
+ .name = TYPE_XLNX_VERSAL_CRL,
652
+ .version_id = 1,
653
+ .minimum_version_id = 1,
654
+ .fields = (VMStateField[]) {
655
+ VMSTATE_UINT32_ARRAY(regs, XlnxVersalCRL, CRL_R_MAX),
656
+ VMSTATE_END_OF_LIST(),
657
+ }
658
+};
659
+
660
+static void crl_class_init(ObjectClass *klass, void *data)
661
+{
662
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
663
+ DeviceClass *dc = DEVICE_CLASS(klass);
664
+
665
+ dc->vmsd = &vmstate_crl;
666
+
667
+ rc->phases.enter = crl_reset_enter;
668
+ rc->phases.hold = crl_reset_hold;
669
+}
670
+
671
+static const TypeInfo crl_info = {
672
+ .name = TYPE_XLNX_VERSAL_CRL,
673
+ .parent = TYPE_SYS_BUS_DEVICE,
674
+ .instance_size = sizeof(XlnxVersalCRL),
675
+ .class_init = crl_class_init,
676
+ .instance_init = crl_init,
677
+ .instance_finalize = crl_finalize,
678
+};
679
+
680
+static void crl_register_types(void)
681
+{
682
+ type_register_static(&crl_info);
683
+}
684
+
685
+type_init(crl_register_types)
686
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
687
index XXXXXXX..XXXXXXX 100644
688
--- a/hw/misc/meson.build
689
+++ b/hw/misc/meson.build
690
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
691
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
692
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-crf.c'))
693
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-apu-ctrl.c'))
694
+specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-crl.c'))
695
softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
696
'xlnx-versal-xramc.c',
697
'xlnx-versal-pmc-iou-slcr.c',
698
--
161
--
699
2.25.1
162
2.34.1
diff view generated by jsdifflib
1
The only time we use the ext_gic_irq[] array in the Exynos4210Irq
1
From: Richard Henderson <richard.henderson@linaro.org>
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
2
3
Introduce both the enumeration and functions to retrieve
4
the current state, and state outside of EL3.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230620124418.805717-6-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
---
10
---
13
include/hw/arm/exynos4210.h | 1 -
11
target/arm/cpu.h | 89 ++++++++++++++++++++++++++++++++++-----------
14
hw/arm/exynos4210.c | 12 ++++++------
12
target/arm/helper.c | 60 ++++++++++++++++++++++++++++++
15
2 files changed, 6 insertions(+), 7 deletions(-)
13
2 files changed, 127 insertions(+), 22 deletions(-)
16
14
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
17
--- a/target/arm/cpu.h
20
+++ b/include/hw/arm/exynos4210.h
18
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static inline int arm_feature(CPUARMState *env, int feature)
22
typedef struct Exynos4210Irq {
20
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
21
void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp);
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
22
25
- qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
23
-#if !defined(CONFIG_USER_ONLY)
26
} Exynos4210Irq;
24
/*
27
25
+ * ARM v9 security states.
28
struct Exynos4210State {
26
+ * The ordering of the enumeration corresponds to the low 2 bits
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
27
+ * of the GPI value, and (except for Root) the concat of NSE:NS.
28
+ */
29
+
30
+typedef enum ARMSecuritySpace {
31
+ ARMSS_Secure = 0,
32
+ ARMSS_NonSecure = 1,
33
+ ARMSS_Root = 2,
34
+ ARMSS_Realm = 3,
35
+} ARMSecuritySpace;
36
+
37
+/* Return true if @space is secure, in the pre-v9 sense. */
38
+static inline bool arm_space_is_secure(ARMSecuritySpace space)
39
+{
40
+ return space == ARMSS_Secure || space == ARMSS_Root;
41
+}
42
+
43
+/* Return the ARMSecuritySpace for @secure, assuming !RME or EL[0-2]. */
44
+static inline ARMSecuritySpace arm_secure_to_space(bool secure)
45
+{
46
+ return secure ? ARMSS_Secure : ARMSS_NonSecure;
47
+}
48
+
49
+#if !defined(CONFIG_USER_ONLY)
50
+/**
51
+ * arm_security_space_below_el3:
52
+ * @env: cpu context
53
+ *
54
+ * Return the security space of exception levels below EL3, following
55
+ * an exception return to those levels. Unlike arm_security_space,
56
+ * this doesn't care about the current EL.
57
+ */
58
+ARMSecuritySpace arm_security_space_below_el3(CPUARMState *env);
59
+
60
+/**
61
+ * arm_is_secure_below_el3:
62
+ * @env: cpu context
63
+ *
64
* Return true if exception levels below EL3 are in secure state,
65
- * or would be following an exception return to that level.
66
- * Unlike arm_is_secure() (which is always a question about the
67
- * _current_ state of the CPU) this doesn't care about the current
68
- * EL or mode.
69
+ * or would be following an exception return to those levels.
70
*/
71
static inline bool arm_is_secure_below_el3(CPUARMState *env)
72
{
73
- assert(!arm_feature(env, ARM_FEATURE_M));
74
- if (arm_feature(env, ARM_FEATURE_EL3)) {
75
- return !(env->cp15.scr_el3 & SCR_NS);
76
- } else {
77
- /* If EL3 is not supported then the secure state is implementation
78
- * defined, in which case QEMU defaults to non-secure.
79
- */
80
- return false;
81
- }
82
+ ARMSecuritySpace ss = arm_security_space_below_el3(env);
83
+ return ss == ARMSS_Secure;
84
}
85
86
/* Return true if the CPU is AArch64 EL3 or AArch32 Mon */
87
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_el3_or_mon(CPUARMState *env)
88
return false;
89
}
90
91
-/* Return true if the processor is in secure state */
92
+/**
93
+ * arm_security_space:
94
+ * @env: cpu context
95
+ *
96
+ * Return the current security space of the cpu.
97
+ */
98
+ARMSecuritySpace arm_security_space(CPUARMState *env);
99
+
100
+/**
101
+ * arm_is_secure:
102
+ * @env: cpu context
103
+ *
104
+ * Return true if the processor is in secure state.
105
+ */
106
static inline bool arm_is_secure(CPUARMState *env)
107
{
108
- if (arm_feature(env, ARM_FEATURE_M)) {
109
- return env->v7m.secure;
110
- }
111
- if (arm_is_el3_or_mon(env)) {
112
- return true;
113
- }
114
- return arm_is_secure_below_el3(env);
115
+ return arm_space_is_secure(arm_security_space(env));
116
}
117
118
/*
119
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_el2_enabled(CPUARMState *env)
120
}
121
122
#else
123
+static inline ARMSecuritySpace arm_security_space_below_el3(CPUARMState *env)
124
+{
125
+ return ARMSS_NonSecure;
126
+}
127
+
128
static inline bool arm_is_secure_below_el3(CPUARMState *env)
129
{
130
return false;
131
}
132
133
+static inline ARMSecuritySpace arm_security_space(CPUARMState *env)
134
+{
135
+ return ARMSS_NonSecure;
136
+}
137
+
138
static inline bool arm_is_secure(CPUARMState *env)
139
{
140
return false;
141
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
index XXXXXXX..XXXXXXX 100644
142
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
143
--- a/target/arm/helper.c
32
+++ b/hw/arm/exynos4210.c
144
+++ b/target/arm/helper.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
145
@@ -XXX,XX +XXX,XX @@ void aarch64_sve_change_el(CPUARMState *env, int old_el,
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
}
146
}
60
}
147
}
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
148
#endif
62
sysbus_connect_irq(busdev, n,
149
+
63
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
150
+#ifndef CONFIG_USER_ONLY
64
}
151
+ARMSecuritySpace arm_security_space(CPUARMState *env)
65
- for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
152
+{
66
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
153
+ if (arm_feature(env, ARM_FEATURE_M)) {
67
- }
154
+ return arm_secure_to_space(env->v7m.secure);
68
155
+ }
69
/* Internal Interrupt Combiner */
156
+
70
dev = qdev_new("exynos4210.combiner");
157
+ /*
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
158
+ * If EL3 is not supported then the secure state is implementation
72
busdev = SYS_BUS_DEVICE(dev);
159
+ * defined, in which case QEMU defaults to non-secure.
73
sysbus_realize_and_unref(busdev, &error_fatal);
160
+ */
74
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
161
+ if (!arm_feature(env, ARM_FEATURE_EL3)) {
75
- sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]);
162
+ return ARMSS_NonSecure;
76
+ sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
163
+ }
77
}
164
+
78
exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
165
+ /* Check for AArch64 EL3 or AArch32 Mon. */
79
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
166
+ if (is_a64(env)) {
167
+ if (extract32(env->pstate, 2, 2) == 3) {
168
+ if (cpu_isar_feature(aa64_rme, env_archcpu(env))) {
169
+ return ARMSS_Root;
170
+ } else {
171
+ return ARMSS_Secure;
172
+ }
173
+ }
174
+ } else {
175
+ if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
176
+ return ARMSS_Secure;
177
+ }
178
+ }
179
+
180
+ return arm_security_space_below_el3(env);
181
+}
182
+
183
+ARMSecuritySpace arm_security_space_below_el3(CPUARMState *env)
184
+{
185
+ assert(!arm_feature(env, ARM_FEATURE_M));
186
+
187
+ /*
188
+ * If EL3 is not supported then the secure state is implementation
189
+ * defined, in which case QEMU defaults to non-secure.
190
+ */
191
+ if (!arm_feature(env, ARM_FEATURE_EL3)) {
192
+ return ARMSS_NonSecure;
193
+ }
194
+
195
+ /*
196
+ * Note NSE cannot be set without RME, and NSE & !NS is Reserved.
197
+ * Ignoring NSE when !NS retains consistency without having to
198
+ * modify other predicates.
199
+ */
200
+ if (!(env->cp15.scr_el3 & SCR_NS)) {
201
+ return ARMSS_Secure;
202
+ } else if (env->cp15.scr_el3 & SCR_NSE) {
203
+ return ARMSS_Realm;
204
+ } else {
205
+ return ARMSS_NonSecure;
206
+ }
207
+}
208
+#endif /* !CONFIG_USER_ONLY */
80
--
209
--
81
2.25.1
210
2.34.1
diff view generated by jsdifflib
1
In exynos4210_init_board_irqs(), the loop that handles IRQ lines that
1
From: Richard Henderson <richard.henderson@linaro.org>
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
2
9
I don't have a reliable datasheet for this SoC, but since we do wire
3
We will need 2 bits to represent ARMSecurityState.
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
4
17
This bug didn't have any visible guest effects because the only
5
Do not attempt to replace or widen secure, even though it
18
implemented device that was affected was the HDMI I2C controller,
6
logically overlaps the new field -- there are uses within
19
and we never connect any I2C devices to that bus.
7
e.g. hw/block/pflash_cfi01.c, which don't know anything
8
specific about ARM.
20
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20230620124418.805717-7-richard.henderson@linaro.org
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
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
---
14
---
25
hw/arm/exynos4210.c | 2 ++
15
include/exec/memattrs.h | 9 ++++++++-
26
1 file changed, 2 insertions(+)
16
1 file changed, 8 insertions(+), 1 deletion(-)
27
17
28
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
18
diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
29
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/exynos4210.c
20
--- a/include/exec/memattrs.h
31
+++ b/hw/arm/exynos4210.c
21
+++ b/include/exec/memattrs.h
32
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
22
@@ -XXX,XX +XXX,XX @@ typedef struct MemTxAttrs {
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
23
* "didn't specify" if necessary.
34
qdev_connect_gpio_out(splitter, 1,
24
*/
35
qdev_get_gpio_in(extgicdev, irq_id - 32));
25
unsigned int unspecified:1;
36
+ } else {
26
- /* ARM/AMBA: TrustZone Secure access
37
+ s->irq_table[n] = is->int_combiner_irq[n];
27
+ /*
38
}
28
+ * ARM/AMBA: TrustZone Secure access
39
}
29
* x86: System Management Mode access
30
*/
31
unsigned int secure:1;
32
+ /*
33
+ * ARM: ArmSecuritySpace. This partially overlaps secure, but it is
34
+ * easier to have both fields to assist code that does not understand
35
+ * ARMv9 RME, or no specific knowledge of ARM at all (e.g. pflash).
36
+ */
37
+ unsigned int space:2;
38
/* Memory access is usermode (unprivileged) */
39
unsigned int user:1;
40
/*
40
/*
41
--
41
--
42
2.25.1
42
2.34.1
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Similar to the Aspeed code in include/misc/aspeed_scu.h, we define
3
It will be helpful to have ARMMMUIdx_Phys_* to be in the same
4
the PWRON STRAP fields in their corresponding module for NPCM7XX.
4
relative order as ARMSecuritySpace enumerators. This requires
5
the adjustment to the nstable check. While there, check for being
6
in secure state rather than rely on clearing the low bit making
7
no change to non-secure state.
5
8
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
7
Reviewed-by: Patrick Venture <venture@google.com>
8
Message-id: 20220411165842.3912945-2-wuhaotsh@google.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20230620124418.805717-8-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
include/hw/misc/npcm7xx_gcr.h | 30 ++++++++++++++++++++++++++++++
14
target/arm/cpu.h | 12 ++++++------
13
1 file changed, 30 insertions(+)
15
target/arm/ptw.c | 12 +++++-------
16
2 files changed, 11 insertions(+), 13 deletions(-)
14
17
15
diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/misc/npcm7xx_gcr.h
20
--- a/target/arm/cpu.h
18
+++ b/include/hw/misc/npcm7xx_gcr.h
21
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
20
#include "exec/memory.h"
23
ARMMMUIdx_E2 = 6 | ARM_MMU_IDX_A,
21
#include "hw/sysbus.h"
24
ARMMMUIdx_E3 = 7 | ARM_MMU_IDX_A,
22
25
23
+/*
26
- /* TLBs with 1-1 mapping to the physical address spaces. */
24
+ * NPCM7XX PWRON STRAP bit fields
27
- ARMMMUIdx_Phys_NS = 8 | ARM_MMU_IDX_A,
25
+ * 12: SPI0 powered by VSBV3 at 1.8V
28
- ARMMMUIdx_Phys_S = 9 | ARM_MMU_IDX_A,
26
+ * 11: System flash attached to BMC
29
-
27
+ * 10: BSP alternative pins.
30
/*
28
+ * 9:8: Flash UART command route enabled.
31
* Used for second stage of an S12 page table walk, or for descriptor
29
+ * 7: Security enabled.
32
* loads during first stage of an S1 page table walk. Note that both
30
+ * 6: HI-Z state control.
33
* are in use simultaneously for SecureEL2: the security state for
31
+ * 5: ECC disabled.
34
* the S2 ptw is selected by the NS bit from the S1 ptw.
32
+ * 4: Reserved
35
*/
33
+ * 3: JTAG2 enabled.
36
- ARMMMUIdx_Stage2 = 10 | ARM_MMU_IDX_A,
34
+ * 2:0: CPU and DRAM clock frequency.
37
- ARMMMUIdx_Stage2_S = 11 | ARM_MMU_IDX_A,
35
+ */
38
+ ARMMMUIdx_Stage2_S = 8 | ARM_MMU_IDX_A,
36
+#define NPCM7XX_PWRON_STRAP_SPI0F18 BIT(12)
39
+ ARMMMUIdx_Stage2 = 9 | ARM_MMU_IDX_A,
37
+#define NPCM7XX_PWRON_STRAP_SFAB BIT(11)
38
+#define NPCM7XX_PWRON_STRAP_BSPA BIT(10)
39
+#define NPCM7XX_PWRON_STRAP_FUP(x) ((x) << 8)
40
+#define FUP_NORM_UART2 3
41
+#define FUP_PROG_UART3 2
42
+#define FUP_PROG_UART2 1
43
+#define FUP_NORM_UART3 0
44
+#define NPCM7XX_PWRON_STRAP_SECEN BIT(7)
45
+#define NPCM7XX_PWRON_STRAP_HIZ BIT(6)
46
+#define NPCM7XX_PWRON_STRAP_ECC BIT(5)
47
+#define NPCM7XX_PWRON_STRAP_RESERVE1 BIT(4)
48
+#define NPCM7XX_PWRON_STRAP_J2EN BIT(3)
49
+#define NPCM7XX_PWRON_STRAP_CKFRQ(x) (x)
50
+#define CKFRQ_SKIPINIT 0x000
51
+#define CKFRQ_DEFAULT 0x111
52
+
40
+
53
/*
41
+ /* TLBs with 1-1 mapping to the physical address spaces. */
54
* Number of registers in our device state structure. Don't change this without
42
+ ARMMMUIdx_Phys_S = 10 | ARM_MMU_IDX_A,
55
* incrementing the version_id in the vmstate.
43
+ ARMMMUIdx_Phys_NS = 11 | ARM_MMU_IDX_A,
44
45
/*
46
* These are not allocated TLBs and are used only for AT system
47
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/ptw.c
50
+++ b/target/arm/ptw.c
51
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
52
descaddr |= (address >> (stride * (4 - level))) & indexmask;
53
descaddr &= ~7ULL;
54
nstable = !regime_is_stage2(mmu_idx) && extract32(tableattrs, 4, 1);
55
- if (nstable) {
56
+ if (nstable && ptw->in_secure) {
57
/*
58
* Stage2_S -> Stage2 or Phys_S -> Phys_NS
59
- * Assert that the non-secure idx are even, and relative order.
60
+ * Assert the relative order of the secure/non-secure indexes.
61
*/
62
- QEMU_BUILD_BUG_ON((ARMMMUIdx_Phys_NS & 1) != 0);
63
- QEMU_BUILD_BUG_ON((ARMMMUIdx_Stage2 & 1) != 0);
64
- QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS + 1 != ARMMMUIdx_Phys_S);
65
- QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2 + 1 != ARMMMUIdx_Stage2_S);
66
- ptw->in_ptw_idx &= ~1;
67
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_S + 1 != ARMMMUIdx_Phys_NS);
68
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2_S + 1 != ARMMMUIdx_Stage2);
69
+ ptw->in_ptw_idx += 1;
70
ptw->in_secure = false;
71
}
72
if (!S1_ptw_translate(env, ptw, descaddr, fi)) {
56
--
73
--
57
2.25.1
74
2.34.1
diff view generated by jsdifflib
1
At this point, the function exynos4210_init_board_irqs() splits input
1
From: Richard Henderson <richard.henderson@linaro.org>
2
IRQ lines to connect them to the input combiner, output combiner and
3
external GIC. The function exynos4210_combiner_get_gpioin() splits
4
some of the combiner input lines further to connect them to multiple
5
different inputs on the combiner.
6
2
7
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
3
With FEAT_RME, there are four physical address spaces.
8
configurable number of outputs, we can do all this in one place, by
4
For now, just define the symbols, and mention them in
9
making exynos4210_init_board_irqs() add extra outputs to the splitter
5
the same spots as the other Phys indexes in ptw.c.
10
device when it must be connected to more than one input on each
11
combiner.
12
6
13
We do this with a new data structure, the combinermap, which is an
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
array each of whose elements is a list of the interrupt IDs on the
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
combiner which must be tied together. As we loop through each
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
interrupt ID, if we find that it is the first one in one of these
10
Message-id: 20230620124418.805717-9-richard.henderson@linaro.org
17
lists, we configure the splitter device with eonugh extra outputs and
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
wire them up to the other interrupt IDs in the list.
12
---
13
target/arm/cpu.h | 23 +++++++++++++++++++++--
14
target/arm/ptw.c | 10 ++++++++--
15
2 files changed, 29 insertions(+), 4 deletions(-)
19
16
20
Conveniently, for all the cases where this is necessary, the
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
lowest-numbered interrupt ID in each group is in the range of the
22
external combiner, so we only need to code for this in the first of
23
the two loops in exynos4210_init_board_irqs().
24
25
The old code in exynos4210_combiner_get_gpioin() which is being
26
deleted here had several problems which don't exist in the new code
27
in its handling of the multi-core timer interrupts:
28
(1) the case labels specified bits 4 ... 8, but bit '8' doesn't
29
exist; these should have been 4 ... 7
30
(2) it used the input irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]
31
multiple times as the input of several different splitters,
32
which isn't allowed
33
(3) in an apparent cut-and-paste error, the cases for all the
34
multi-core timer inputs used "bit + 4" even though the
35
bit range for the case was (intended to be) 4 ... 7, which
36
meant it was looking at non-existent bits 8 ... 11.
37
None of these exist in the new code.
38
39
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
40
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
41
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
42
---
43
include/hw/arm/exynos4210.h | 6 +-
44
hw/arm/exynos4210.c | 178 +++++++++++++++++++++++-------------
45
2 files changed, 119 insertions(+), 65 deletions(-)
46
47
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
48
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
49
--- a/include/hw/arm/exynos4210.h
19
--- a/target/arm/cpu.h
50
+++ b/include/hw/arm/exynos4210.h
20
+++ b/target/arm/cpu.h
51
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
52
22
ARMMMUIdx_Stage2 = 9 | ARM_MMU_IDX_A,
53
/*
23
54
* We need one splitter for every external combiner input, plus
24
/* TLBs with 1-1 mapping to the physical address spaces. */
55
- * one for every non-zero entry in combiner_grp_to_gic_id[].
25
- ARMMMUIdx_Phys_S = 10 | ARM_MMU_IDX_A,
56
+ * one for every non-zero entry in combiner_grp_to_gic_id[],
26
- ARMMMUIdx_Phys_NS = 11 | ARM_MMU_IDX_A,
57
+ * minus one for every external combiner ID in second or later
27
+ ARMMMUIdx_Phys_S = 10 | ARM_MMU_IDX_A,
58
+ * places in a combinermap[] line.
28
+ ARMMMUIdx_Phys_NS = 11 | ARM_MMU_IDX_A,
59
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
29
+ ARMMMUIdx_Phys_Root = 12 | ARM_MMU_IDX_A,
60
*/
30
+ ARMMMUIdx_Phys_Realm = 13 | ARM_MMU_IDX_A,
61
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
31
62
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
32
/*
63
33
* These are not allocated TLBs and are used only for AT system
64
typedef struct Exynos4210Irq {
34
@@ -XXX,XX +XXX,XX @@ typedef enum ARMASIdx {
65
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
35
ARMASIdx_TagS = 3,
66
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
36
} ARMASIdx;
67
index XXXXXXX..XXXXXXX 100644
37
68
--- a/hw/arm/exynos4210.c
38
+static inline ARMMMUIdx arm_space_to_phys(ARMSecuritySpace space)
69
+++ b/hw/arm/exynos4210.c
39
+{
70
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
40
+ /* Assert the relative order of the physical mmu indexes. */
71
#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
41
+ QEMU_BUILD_BUG_ON(ARMSS_Secure != 0);
72
((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
42
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS != ARMMMUIdx_Phys_S + ARMSS_NonSecure);
73
43
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_Root != ARMMMUIdx_Phys_S + ARMSS_Root);
74
+/*
44
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_Realm != ARMMMUIdx_Phys_S + ARMSS_Realm);
75
+ * Some interrupt lines go to multiple combiner inputs.
76
+ * This data structure defines those: each array element is
77
+ * a list of combiner inputs which are connected together;
78
+ * the one with the smallest interrupt ID value must be first.
79
+ * As with combiner_grp_to_gic_id[], we rely on (0, 0) not being
80
+ * wired to anything so we can use 0 as a terminator.
81
+ */
82
+#define IRQNO(G, B) EXYNOS4210_COMBINER_GET_IRQ_NUM(G, B)
83
+#define IRQNONE 0
84
+
45
+
85
+#define COMBINERMAP_SIZE 16
46
+ return ARMMMUIdx_Phys_S + space;
86
+
87
+static const int combinermap[COMBINERMAP_SIZE][6] = {
88
+ /* MDNIE_LCD1 */
89
+ { IRQNO(0, 4), IRQNO(1, 0), IRQNONE },
90
+ { IRQNO(0, 5), IRQNO(1, 1), IRQNONE },
91
+ { IRQNO(0, 6), IRQNO(1, 2), IRQNONE },
92
+ { IRQNO(0, 7), IRQNO(1, 3), IRQNONE },
93
+ /* TMU */
94
+ { IRQNO(2, 4), IRQNO(3, 4), IRQNONE },
95
+ { IRQNO(2, 5), IRQNO(3, 5), IRQNONE },
96
+ { IRQNO(2, 6), IRQNO(3, 6), IRQNONE },
97
+ { IRQNO(2, 7), IRQNO(3, 7), IRQNONE },
98
+ /* LCD1 */
99
+ { IRQNO(11, 4), IRQNO(12, 0), IRQNONE },
100
+ { IRQNO(11, 5), IRQNO(12, 1), IRQNONE },
101
+ { IRQNO(11, 6), IRQNO(12, 2), IRQNONE },
102
+ { IRQNO(11, 7), IRQNO(12, 3), IRQNONE },
103
+ /* Multi-core timer */
104
+ { IRQNO(1, 4), IRQNO(12, 4), IRQNO(35, 4), IRQNO(51, 4), IRQNO(53, 4), IRQNONE },
105
+ { IRQNO(1, 5), IRQNO(12, 5), IRQNO(35, 5), IRQNO(51, 5), IRQNO(53, 5), IRQNONE },
106
+ { IRQNO(1, 6), IRQNO(12, 6), IRQNO(35, 6), IRQNO(51, 6), IRQNO(53, 6), IRQNONE },
107
+ { IRQNO(1, 7), IRQNO(12, 7), IRQNO(35, 7), IRQNO(51, 7), IRQNO(53, 7), IRQNONE },
108
+};
109
+
110
+#undef IRQNO
111
+
112
+static const int *combinermap_entry(int irq)
113
+{
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
+}
47
+}
127
+
48
+
128
+static int mapline_size(const int *mapline)
49
+static inline ARMSecuritySpace arm_phys_to_space(ARMMMUIdx idx)
129
+{
50
+{
130
+ /* Return number of entries in this mapline in total */
51
+ assert(idx >= ARMMMUIdx_Phys_S && idx <= ARMMMUIdx_Phys_Realm);
131
+ int i = 0;
52
+ return idx - ARMMMUIdx_Phys_S;
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
+}
53
+}
143
+
54
+
144
/*
55
static inline bool arm_v7m_csselr_razwi(ARMCPU *cpu)
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
{
56
{
226
int n;
57
/* If all the CLIDR.Ctypem bits are 0 there are no caches, and
227
- int bit;
58
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
228
int max;
59
index XXXXXXX..XXXXXXX 100644
229
qemu_irq *irq;
60
--- a/target/arm/ptw.c
230
61
+++ b/target/arm/ptw.c
231
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
62
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
232
EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
63
case ARMMMUIdx_E3:
233
irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
64
break;
234
65
235
- /*
66
- case ARMMMUIdx_Phys_NS:
236
- * Some IRQs of Int/External Combiner are going to two Combiners groups,
67
case ARMMMUIdx_Phys_S:
237
- * so let split them.
68
+ case ARMMMUIdx_Phys_NS:
238
- */
69
+ case ARMMMUIdx_Phys_Root:
239
for (n = 0; n < max; n++) {
70
+ case ARMMMUIdx_Phys_Realm:
240
-
71
/* No translation for physical address spaces. */
241
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
72
return true;
242
-
73
243
- switch (n) {
74
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
244
- /* MDNIE_LCD1 INTG1 */
75
switch (mmu_idx) {
245
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
76
case ARMMMUIdx_Stage2:
246
- EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
77
case ARMMMUIdx_Stage2_S:
247
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
78
- case ARMMMUIdx_Phys_NS:
248
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
79
case ARMMMUIdx_Phys_S:
249
- continue;
80
+ case ARMMMUIdx_Phys_NS:
250
-
81
+ case ARMMMUIdx_Phys_Root:
251
- /* TMU INTG3 */
82
+ case ARMMMUIdx_Phys_Realm:
252
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
83
break;
253
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
84
254
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
85
default:
255
- continue;
86
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
256
-
87
switch (mmu_idx) {
257
- /* LCD1 INTG12 */
88
case ARMMMUIdx_Phys_S:
258
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
89
case ARMMMUIdx_Phys_NS:
259
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
90
+ case ARMMMUIdx_Phys_Root:
260
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
91
+ case ARMMMUIdx_Phys_Realm:
261
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
92
/* Checking Phys early avoids special casing later vs regime_el. */
262
- continue;
93
return get_phys_addr_disabled(env, address, access_type, mmu_idx,
263
-
94
is_secure, result, fi);
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
--
95
--
297
2.25.1
96
2.34.1
97
98
diff view generated by jsdifflib
1
From: Zongyuan Li <zongyuan.li@smartx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
3
This was added in 7e98e21c098 as part of a reorg in which
4
one of the argument had been legally NULL, and this caught
5
actual instances. Now that the reorg is complete, this
6
serves little purpose.
7
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-5-zongyuan.li@smartx.com
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/811
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20230620124418.805717-10-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
13
---
9
include/hw/irq.h | 5 -----
14
target/arm/ptw.c | 6 ++----
10
hw/core/irq.c | 15 ---------------
15
1 file changed, 2 insertions(+), 4 deletions(-)
11
2 files changed, 20 deletions(-)
12
16
13
diff --git a/include/hw/irq.h b/include/hw/irq.h
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/irq.h
19
--- a/target/arm/ptw.c
16
+++ b/include/hw/irq.h
20
+++ b/target/arm/ptw.c
17
@@ -XXX,XX +XXX,XX @@ void qemu_free_irq(qemu_irq irq);
21
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
18
/* Returns a new IRQ with opposite polarity. */
22
static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
19
qemu_irq qemu_irq_invert(qemu_irq irq);
23
uint64_t address,
20
24
MMUAccessType access_type, bool s1_is_el0,
21
-/* Returns a new IRQ which feeds into both the passed IRQs.
25
- GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
22
- * It's probably better to use the TYPE_SPLIT_IRQ device instead.
26
- __attribute__((nonnull));
23
- */
27
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi);
24
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
28
25
-
29
static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
26
/* For internal use in qtest. Similar to qemu_irq_split, but operating
30
target_ulong address,
27
on an existing vector of qemu_irq. */
31
MMUAccessType access_type,
28
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
32
GetPhysAddrResult *result,
29
diff --git a/hw/core/irq.c b/hw/core/irq.c
33
- ARMMMUFaultInfo *fi)
30
index XXXXXXX..XXXXXXX 100644
34
- __attribute__((nonnull));
31
--- a/hw/core/irq.c
35
+ ARMMMUFaultInfo *fi);
32
+++ b/hw/core/irq.c
36
33
@@ -XXX,XX +XXX,XX @@ qemu_irq qemu_irq_invert(qemu_irq irq)
37
/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
34
return qemu_allocate_irq(qemu_notirq, irq, 0);
38
static const uint8_t pamax_map[] = {
35
}
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
--
39
--
56
2.25.1
40
2.34.1
41
42
diff view generated by jsdifflib
1
The only time we use the int_combiner_irq[] and ext_combiner_irq[]
1
From: Richard Henderson <richard.henderson@linaro.org>
2
arrays in the Exynos4210Irq struct is during realize of the SoC -- we
3
initialize them with the input IRQs of the combiner devices, and then
4
connect those to outputs of other devices in
5
exynos4210_init_board_irqs(). Now that the combiner objects are
6
easily accessible as s->int_combiner and s->ext_combiner we can make
7
the connections directly from one device to the other without going
8
via these arrays.
9
2
10
Since these are the only two remaining elements of Exynos4210Irq,
3
Add input and output space members to S1Translate. Set and adjust
11
we can remove that struct entirely.
4
them in S1_ptw_translate, and the various points at which we drop
5
secure state. Initialize the space in get_phys_addr; for now leave
6
get_phys_addr_with_secure considering only secure vs non-secure spaces.
12
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20230620124418.805717-11-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220404154658.565020-19-peter.maydell@linaro.org
16
---
12
---
17
include/hw/arm/exynos4210.h | 6 ------
13
target/arm/ptw.c | 86 +++++++++++++++++++++++++++++++++++++++---------
18
hw/arm/exynos4210.c | 34 ++++++++--------------------------
14
1 file changed, 71 insertions(+), 15 deletions(-)
19
2 files changed, 8 insertions(+), 32 deletions(-)
20
15
21
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
16
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
22
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/exynos4210.h
18
--- a/target/arm/ptw.c
24
+++ b/include/hw/arm/exynos4210.h
19
+++ b/target/arm/ptw.c
25
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
26
*/
21
typedef struct S1Translate {
27
#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
22
ARMMMUIdx in_mmu_idx;
28
23
ARMMMUIdx in_ptw_idx;
29
-typedef struct Exynos4210Irq {
24
+ ARMSecuritySpace in_space;
30
- qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
25
bool in_secure;
31
- qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
26
bool in_debug;
32
-} Exynos4210Irq;
27
bool out_secure;
33
-
28
bool out_rw;
34
struct Exynos4210State {
29
bool out_be;
35
/*< private >*/
30
+ ARMSecuritySpace out_space;
36
SysBusDevice parent_obj;
31
hwaddr out_virt;
37
/*< public >*/
32
hwaddr out_phys;
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
33
void *out_host;
39
- Exynos4210Irq irqs;
34
@@ -XXX,XX +XXX,XX @@ static bool S2_attrs_are_device(uint64_t hcr, uint8_t attrs)
40
qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
35
static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
41
36
hwaddr addr, ARMMMUFaultInfo *fi)
42
MemoryRegion chipid_mem;
43
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/arm/exynos4210.c
46
+++ b/hw/arm/exynos4210.c
47
@@ -XXX,XX +XXX,XX @@ static int mapline_size(const int *mapline)
48
static void exynos4210_init_board_irqs(Exynos4210State *s)
49
{
37
{
50
uint32_t grp, bit, irq_id, n;
38
+ ARMSecuritySpace space = ptw->in_space;
51
- Exynos4210Irq *is = &s->irqs;
39
bool is_secure = ptw->in_secure;
52
DeviceState *extgicdev = DEVICE(&s->ext_gic);
40
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
53
+ DeviceState *intcdev = DEVICE(&s->int_combiner);
41
ARMMMUIdx s2_mmu_idx = ptw->in_ptw_idx;
54
+ DeviceState *extcdev = DEVICE(&s->ext_combiner);
42
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
55
int splitcount = 0;
43
.in_mmu_idx = s2_mmu_idx,
56
DeviceState *splitter;
44
.in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
57
const int *mapline;
45
.in_secure = s2_mmu_idx == ARMMMUIdx_Stage2_S,
58
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
46
+ .in_space = (s2_mmu_idx == ARMMMUIdx_Stage2_S ? ARMSS_Secure
59
splitin = 0;
47
+ : space == ARMSS_Realm ? ARMSS_Realm
60
for (;;) {
48
+ : ARMSS_NonSecure),
61
s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
49
.in_debug = true,
62
- qdev_connect_gpio_out(splitter, splitin, is->int_combiner_irq[in]);
50
};
63
- qdev_connect_gpio_out(splitter, splitin + 1, is->ext_combiner_irq[in]);
51
GetPhysAddrResult s2 = { };
64
+ qdev_connect_gpio_out(splitter, splitin,
52
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
65
+ qdev_get_gpio_in(intcdev, in));
53
ptw->out_phys = s2.f.phys_addr;
66
+ qdev_connect_gpio_out(splitter, splitin + 1,
54
pte_attrs = s2.cacheattrs.attrs;
67
+ qdev_get_gpio_in(extcdev, in));
55
ptw->out_secure = s2.f.attrs.secure;
68
splitin += 2;
56
+ ptw->out_space = s2.f.attrs.space;
69
if (!mapline) {
70
break;
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
72
qdev_realize(splitter, NULL, &error_abort);
73
splitcount++;
74
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
75
- qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
76
+ qdev_connect_gpio_out(splitter, 0, qdev_get_gpio_in(intcdev, n));
77
qdev_connect_gpio_out(splitter, 1,
78
qdev_get_gpio_in(extgicdev, irq_id - 32));
79
} else {
57
} else {
80
- s->irq_table[n] = is->int_combiner_irq[n];
58
/* Regime is physical. */
81
+ s->irq_table[n] = qdev_get_gpio_in(intcdev, n);
59
ptw->out_phys = addr;
60
pte_attrs = 0;
61
ptw->out_secure = s2_mmu_idx == ARMMMUIdx_Phys_S;
62
+ ptw->out_space = (s2_mmu_idx == ARMMMUIdx_Phys_S ? ARMSS_Secure
63
+ : space == ARMSS_Realm ? ARMSS_Realm
64
+ : ARMSS_NonSecure);
82
}
65
}
83
}
66
ptw->out_host = NULL;
67
ptw->out_rw = false;
68
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
69
ptw->out_rw = full->prot & PAGE_WRITE;
70
pte_attrs = full->pte_attrs;
71
ptw->out_secure = full->attrs.secure;
72
+ ptw->out_space = full->attrs.space;
73
#else
74
g_assert_not_reached();
75
#endif
76
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw,
77
}
78
} else {
79
/* Page tables are in MMIO. */
80
- MemTxAttrs attrs = { .secure = ptw->out_secure };
81
+ MemTxAttrs attrs = {
82
+ .secure = ptw->out_secure,
83
+ .space = ptw->out_space,
84
+ };
85
AddressSpace *as = arm_addressspace(cs, attrs);
86
MemTxResult result = MEMTX_OK;
87
88
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw,
89
#endif
90
} else {
91
/* Page tables are in MMIO. */
92
- MemTxAttrs attrs = { .secure = ptw->out_secure };
93
+ MemTxAttrs attrs = {
94
+ .secure = ptw->out_secure,
95
+ .space = ptw->out_space,
96
+ };
97
AddressSpace *as = arm_addressspace(cs, attrs);
98
MemTxResult result = MEMTX_OK;
99
100
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw,
101
* regime, because the attribute will already be non-secure.
102
*/
103
result->f.attrs.secure = false;
104
+ result->f.attrs.space = ARMSS_NonSecure;
105
}
106
result->f.phys_addr = phys_addr;
107
return false;
108
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
109
* regime, because the attribute will already be non-secure.
110
*/
111
result->f.attrs.secure = false;
112
+ result->f.attrs.space = ARMSS_NonSecure;
113
}
114
115
if (regime_is_stage2(mmu_idx)) {
116
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
117
*/
118
if (sattrs.ns) {
119
result->f.attrs.secure = false;
120
+ result->f.attrs.space = ARMSS_NonSecure;
121
} else if (!secure) {
122
/*
123
* NS access to S memory must fault.
124
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
125
bool is_secure = ptw->in_secure;
126
bool ret, ipa_secure;
127
ARMCacheAttrs cacheattrs1;
128
+ ARMSecuritySpace ipa_space;
129
bool is_el0;
130
uint64_t hcr;
131
132
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
133
134
ipa = result->f.phys_addr;
135
ipa_secure = result->f.attrs.secure;
136
+ ipa_space = result->f.attrs.space;
137
138
is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
139
ptw->in_mmu_idx = ipa_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
140
ptw->in_secure = ipa_secure;
141
+ ptw->in_space = ipa_space;
142
ptw->in_ptw_idx = ptw_idx_for_stage_2(env, ptw->in_mmu_idx);
143
84
/*
144
/*
85
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
145
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
86
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
146
ARMMMUIdx s1_mmu_idx;
147
148
/*
149
- * The page table entries may downgrade secure to non-secure, but
150
- * cannot upgrade an non-secure translation regime's attributes
151
- * to secure.
152
+ * The page table entries may downgrade Secure to NonSecure, but
153
+ * cannot upgrade a NonSecure translation regime's attributes
154
+ * to Secure or Realm.
155
*/
156
result->f.attrs.secure = is_secure;
157
+ result->f.attrs.space = ptw->in_space;
158
159
switch (mmu_idx) {
160
case ARMMMUIdx_Phys_S:
161
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
162
163
default:
164
/* Single stage uses physical for ptw. */
165
- ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
166
+ ptw->in_ptw_idx = arm_space_to_phys(ptw->in_space);
167
break;
168
}
169
170
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
171
S1Translate ptw = {
172
.in_mmu_idx = mmu_idx,
173
.in_secure = is_secure,
174
+ .in_space = arm_secure_to_space(is_secure),
175
};
176
return get_phys_addr_with_struct(env, &ptw, address, access_type,
177
result, fi);
178
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
179
MMUAccessType access_type, ARMMMUIdx mmu_idx,
180
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
181
{
182
- bool is_secure;
183
+ S1Translate ptw = {
184
+ .in_mmu_idx = mmu_idx,
185
+ };
186
+ ARMSecuritySpace ss;
187
188
switch (mmu_idx) {
189
case ARMMMUIdx_E10_0:
190
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
191
case ARMMMUIdx_Stage1_E1:
192
case ARMMMUIdx_Stage1_E1_PAN:
193
case ARMMMUIdx_E2:
194
- is_secure = arm_is_secure_below_el3(env);
195
+ ss = arm_security_space_below_el3(env);
196
break;
197
case ARMMMUIdx_Stage2:
198
+ /*
199
+ * For Secure EL2, we need this index to be NonSecure;
200
+ * otherwise this will already be NonSecure or Realm.
201
+ */
202
+ ss = arm_security_space_below_el3(env);
203
+ if (ss == ARMSS_Secure) {
204
+ ss = ARMSS_NonSecure;
205
+ }
206
+ break;
207
case ARMMMUIdx_Phys_NS:
208
case ARMMMUIdx_MPrivNegPri:
209
case ARMMMUIdx_MUserNegPri:
210
case ARMMMUIdx_MPriv:
211
case ARMMMUIdx_MUser:
212
- is_secure = false;
213
+ ss = ARMSS_NonSecure;
214
break;
215
- case ARMMMUIdx_E3:
216
case ARMMMUIdx_Stage2_S:
217
case ARMMMUIdx_Phys_S:
218
case ARMMMUIdx_MSPrivNegPri:
219
case ARMMMUIdx_MSUserNegPri:
220
case ARMMMUIdx_MSPriv:
221
case ARMMMUIdx_MSUser:
222
- is_secure = true;
223
+ ss = ARMSS_Secure;
224
+ break;
225
+ case ARMMMUIdx_E3:
226
+ if (arm_feature(env, ARM_FEATURE_AARCH64) &&
227
+ cpu_isar_feature(aa64_rme, env_archcpu(env))) {
228
+ ss = ARMSS_Root;
229
+ } else {
230
+ ss = ARMSS_Secure;
231
+ }
232
+ break;
233
+ case ARMMMUIdx_Phys_Root:
234
+ ss = ARMSS_Root;
235
+ break;
236
+ case ARMMMUIdx_Phys_Realm:
237
+ ss = ARMSS_Realm;
238
break;
239
default:
240
g_assert_not_reached();
241
}
242
- return get_phys_addr_with_secure(env, address, access_type, mmu_idx,
243
- is_secure, result, fi);
244
+
245
+ ptw.in_space = ss;
246
+ ptw.in_secure = arm_space_is_secure(ss);
247
+ return get_phys_addr_with_struct(env, &ptw, address, access_type,
248
+ result, fi);
87
}
249
}
88
250
89
-/*
251
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
90
- * Get Combiner input GPIO into irqs structure
252
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
91
- */
253
{
92
-static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
254
ARMCPU *cpu = ARM_CPU(cs);
93
- DeviceState *dev, int ext)
255
CPUARMState *env = &cpu->env;
94
-{
256
+ ARMMMUIdx mmu_idx = arm_mmu_idx(env);
95
- int n;
257
+ ARMSecuritySpace ss = arm_security_space(env);
96
- int max;
258
S1Translate ptw = {
97
- qemu_irq *irq;
259
- .in_mmu_idx = arm_mmu_idx(env),
98
-
260
- .in_secure = arm_is_secure(env),
99
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
261
+ .in_mmu_idx = mmu_idx,
100
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
262
+ .in_space = ss,
101
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
263
+ .in_secure = arm_space_is_secure(ss),
102
-
264
.in_debug = true,
103
- for (n = 0; n < max; n++) {
265
};
104
- irq[n] = qdev_get_gpio_in(dev, n);
266
GetPhysAddrResult res = {};
105
- }
106
-}
107
-
108
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
109
0x09, 0x00, 0x00, 0x00 };
110
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
112
sysbus_connect_irq(busdev, n,
113
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
114
}
115
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
116
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
117
118
/* External Interrupt Combiner */
119
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
120
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
121
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
122
}
123
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
124
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
125
126
/* Initialize board IRQs. */
127
--
267
--
128
2.25.1
268
2.34.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Create an APU CPU Cluster. This is in preparation to add the RPU.
3
Test in_space instead of in_secure so that we don't
4
switch out of Root space.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220406174303.2022038-2-edgar.iglesias@xilinx.com
8
Message-id: 20230620124418.805717-12-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
include/hw/arm/xlnx-versal.h | 2 ++
11
target/arm/ptw.c | 28 ++++++++++++++--------------
11
hw/arm/xlnx-versal.c | 9 ++++++++-
12
1 file changed, 14 insertions(+), 14 deletions(-)
12
2 files changed, 10 insertions(+), 1 deletion(-)
13
13
14
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/xlnx-versal.h
16
--- a/target/arm/ptw.c
17
+++ b/include/hw/arm/xlnx-versal.h
17
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
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
{
19
{
40
int i;
20
ARMCPU *cpu = env_archcpu(env);
41
21
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
42
+ object_initialize_child(OBJECT(s), "apu-cluster", &s->fpd.apu.cluster,
22
- bool is_secure = ptw->in_secure;
43
+ TYPE_CPU_CLUSTER);
23
int32_t level;
44
+ qdev_prop_set_uint32(DEVICE(&s->fpd.apu.cluster), "cluster-id", 0);
24
ARMVAParameters param;
25
uint64_t ttbr;
26
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
27
uint64_t descaddrmask;
28
bool aarch64 = arm_el_is_aa64(env, el);
29
uint64_t descriptor, new_descriptor;
30
- bool nstable;
31
32
/* TODO: This code does not support shareability levels. */
33
if (aarch64) {
34
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
35
descaddrmask = MAKE_64BIT_MASK(0, 40);
36
}
37
descaddrmask &= ~indexmask_grainsize;
38
-
39
- /*
40
- * Secure stage 1 accesses start with the page table in secure memory and
41
- * can be downgraded to non-secure at any step. Non-secure accesses
42
- * remain non-secure. We implement this by just ORing in the NSTable/NS
43
- * bits at each step.
44
- * Stage 2 never gets this kind of downgrade.
45
- */
46
- tableattrs = is_secure ? 0 : (1 << 4);
47
+ tableattrs = 0;
48
49
next_level:
50
descaddr |= (address >> (stride * (4 - level))) & indexmask;
51
descaddr &= ~7ULL;
52
- nstable = !regime_is_stage2(mmu_idx) && extract32(tableattrs, 4, 1);
53
- if (nstable && ptw->in_secure) {
45
+
54
+
46
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
55
+ /*
47
Object *obj;
56
+ * Process the NSTable bit from the previous level. This changes
48
57
+ * the table address space and the output space from Secure to
49
- object_initialize_child(OBJECT(s), "apu-cpu[*]", &s->fpd.apu.cpu[i],
58
+ * NonSecure. With RME, the EL3 translation regime does not change
50
+ object_initialize_child(OBJECT(&s->fpd.apu.cluster),
59
+ * from Root to NonSecure.
51
+ "apu-cpu[*]", &s->fpd.apu.cpu[i],
60
+ */
52
XLNX_VERSAL_ACPU_TYPE);
61
+ if (ptw->in_space == ARMSS_Secure
53
obj = OBJECT(&s->fpd.apu.cpu[i]);
62
+ && !regime_is_stage2(mmu_idx)
54
if (i) {
63
+ && extract32(tableattrs, 4, 1)) {
55
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
64
/*
56
&error_abort);
65
* Stage2_S -> Stage2 or Phys_S -> Phys_NS
57
qdev_realize(DEVICE(obj), NULL, &error_fatal);
66
* Assert the relative order of the secure/non-secure indexes.
67
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
68
QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2_S + 1 != ARMMMUIdx_Stage2);
69
ptw->in_ptw_idx += 1;
70
ptw->in_secure = false;
71
+ ptw->in_space = ARMSS_NonSecure;
58
}
72
}
59
+
73
+
60
+ qdev_realize(DEVICE(&s->fpd.apu.cluster), NULL, &error_fatal);
74
if (!S1_ptw_translate(env, ptw, descaddr, fi)) {
61
}
75
goto do_fault;
62
76
}
63
static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
77
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
78
*/
79
attrs = new_descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14));
80
if (!regime_is_stage2(mmu_idx)) {
81
- attrs |= nstable << 5; /* NS */
82
+ attrs |= !ptw->in_secure << 5; /* NS */
83
if (!param.hpd) {
84
attrs |= extract64(tableattrs, 0, 2) << 53; /* XN, PXN */
85
/*
64
--
86
--
65
2.25.1
87
2.34.1
diff view generated by jsdifflib
1
The exynos4210 code currently has two very similar arrays of IRQs:
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
* board_irqs is a field of the Exynos4210Irq struct which is filled
3
With Realm security state, bit 55 of a block or page descriptor during
4
in by exynos4210_init_board_irqs() with the appropriate qemu_irqs
4
the stage2 walk becomes the NS bit; during the stage1 walk the bit 5
5
for each IRQ the board/SoC can assert
5
NS bit is RES0. With Root security state, bit 11 of the block or page
6
* irq_table is a set of qemu_irqs pointed to from the
6
descriptor during the stage1 walk becomes the NSE bit.
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
7
11
The extra indirection through irq_table is unnecessary, so coalesce
8
Rather than collecting an NS bit and applying it later, compute the
12
these into a single irq_table[] array as a direct field in
9
output pa space from the input pa space and unconditionally assign.
13
Exynos4210State which exynos4210_init_board_irqs() fills in.
10
This means that we no longer need to adjust the output space earlier
11
for the NSTable bit.
14
12
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20230620124418.805717-13-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
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
---
17
---
19
include/hw/arm/exynos4210.h | 8 ++------
18
target/arm/ptw.c | 89 +++++++++++++++++++++++++++++++++++++++---------
20
hw/arm/exynos4210.c | 6 +-----
19
1 file changed, 73 insertions(+), 16 deletions(-)
21
hw/intc/exynos4210_gic.c | 32 ++++++++------------------------
22
3 files changed, 11 insertions(+), 35 deletions(-)
23
20
24
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
21
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
25
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/arm/exynos4210.h
23
--- a/target/arm/ptw.c
27
+++ b/include/hw/arm/exynos4210.h
24
+++ b/target/arm/ptw.c
28
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210Irq {
25
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
29
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
26
* @mmu_idx: MMU index indicating required translation regime
30
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
27
* @is_aa64: TRUE if AArch64
31
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
28
* @ap: The 2-bit simple AP (AP[2:1])
32
- qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
29
- * @ns: NS (non-secure) bit
33
} Exynos4210Irq;
30
* @xn: XN (execute-never) bit
34
31
* @pxn: PXN (privileged execute-never) bit
35
struct Exynos4210State {
32
+ * @in_pa: The original input pa space
36
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
33
+ * @out_pa: The output pa space, modified by NSTable, NS, and NSE
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
*/
34
*/
112
-void exynos4210_init_board_irqs(Exynos4210Irq *s)
35
static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
113
+void exynos4210_init_board_irqs(Exynos4210State *s)
36
- int ap, int ns, int xn, int pxn)
37
+ int ap, int xn, int pxn,
38
+ ARMSecuritySpace in_pa, ARMSecuritySpace out_pa)
114
{
39
{
115
uint32_t grp, bit, irq_id, n;
40
ARMCPU *cpu = env_archcpu(env);
116
+ Exynos4210Irq *is = &s->irqs;
41
bool is_user = regime_is_user(env, mmu_idx);
117
42
@@ -XXX,XX +XXX,XX @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
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
}
43
}
134
}
44
}
135
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
45
136
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
46
- if (ns && arm_is_secure(env) && (env->cp15.scr_el3 & SCR_SIF)) {
137
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
47
+ if (out_pa == ARMSS_NonSecure && in_pa == ARMSS_Secure &&
138
48
+ (env->cp15.scr_el3 & SCR_SIF)) {
139
if (irq_id) {
49
return prot_rw;
140
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
50
}
141
- s->ext_gic_irq[irq_id-32]);
51
142
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
52
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
143
+ is->ext_gic_irq[irq_id - 32]);
53
int32_t stride;
54
int addrsize, inputsize, outputsize;
55
uint64_t tcr = regime_tcr(env, mmu_idx);
56
- int ap, ns, xn, pxn;
57
+ int ap, xn, pxn;
58
uint32_t el = regime_el(env, mmu_idx);
59
uint64_t descaddrmask;
60
bool aarch64 = arm_el_is_aa64(env, el);
61
uint64_t descriptor, new_descriptor;
62
+ ARMSecuritySpace out_space;
63
64
/* TODO: This code does not support shareability levels. */
65
if (aarch64) {
66
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
67
}
68
69
ap = extract32(attrs, 6, 2);
70
+ out_space = ptw->in_space;
71
if (regime_is_stage2(mmu_idx)) {
72
- ns = mmu_idx == ARMMMUIdx_Stage2;
73
+ /*
74
+ * R_GYNXY: For stage2 in Realm security state, bit 55 is NS.
75
+ * The bit remains ignored for other security states.
76
+ */
77
+ if (out_space == ARMSS_Realm && extract64(attrs, 55, 1)) {
78
+ out_space = ARMSS_NonSecure;
79
+ }
80
xn = extract64(attrs, 53, 2);
81
result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
82
} else {
83
- ns = extract32(attrs, 5, 1);
84
+ int nse, ns = extract32(attrs, 5, 1);
85
+ switch (out_space) {
86
+ case ARMSS_Root:
87
+ /*
88
+ * R_GVZML: Bit 11 becomes the NSE field in the EL3 regime.
89
+ * R_XTYPW: NSE and NS together select the output pa space.
90
+ */
91
+ nse = extract32(attrs, 11, 1);
92
+ out_space = (nse << 1) | ns;
93
+ if (out_space == ARMSS_Secure &&
94
+ !cpu_isar_feature(aa64_sel2, cpu)) {
95
+ out_space = ARMSS_NonSecure;
96
+ }
97
+ break;
98
+ case ARMSS_Secure:
99
+ if (ns) {
100
+ out_space = ARMSS_NonSecure;
101
+ }
102
+ break;
103
+ case ARMSS_Realm:
104
+ switch (mmu_idx) {
105
+ case ARMMMUIdx_Stage1_E0:
106
+ case ARMMMUIdx_Stage1_E1:
107
+ case ARMMMUIdx_Stage1_E1_PAN:
108
+ /* I_CZPRF: For Realm EL1&0 stage1, NS bit is RES0. */
109
+ break;
110
+ case ARMMMUIdx_E2:
111
+ case ARMMMUIdx_E20_0:
112
+ case ARMMMUIdx_E20_2:
113
+ case ARMMMUIdx_E20_2_PAN:
114
+ /*
115
+ * R_LYKFZ, R_WGRZN: For Realm EL2 and EL2&1,
116
+ * NS changes the output to non-secure space.
117
+ */
118
+ if (ns) {
119
+ out_space = ARMSS_NonSecure;
120
+ }
121
+ break;
122
+ default:
123
+ g_assert_not_reached();
124
+ }
125
+ break;
126
+ case ARMSS_NonSecure:
127
+ /* R_QRMFF: For NonSecure state, the NS bit is RES0. */
128
+ break;
129
+ default:
130
+ g_assert_not_reached();
131
+ }
132
xn = extract64(attrs, 54, 1);
133
pxn = extract64(attrs, 53, 1);
134
- result->f.prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
135
+
136
+ /*
137
+ * Note that we modified ptw->in_space earlier for NSTable, but
138
+ * result->f.attrs retains a copy of the original security space.
139
+ */
140
+ result->f.prot = get_S1prot(env, mmu_idx, aarch64, ap, xn, pxn,
141
+ result->f.attrs.space, out_space);
142
}
143
144
if (!(result->f.prot & (1 << access_type))) {
145
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
144
}
146
}
145
}
147
}
146
}
148
149
- if (ns) {
150
- /*
151
- * The NS bit will (as required by the architecture) have no effect if
152
- * the CPU doesn't support TZ or this is a non-secure translation
153
- * regime, because the attribute will already be non-secure.
154
- */
155
- result->f.attrs.secure = false;
156
- result->f.attrs.space = ARMSS_NonSecure;
157
- }
158
+ result->f.attrs.space = out_space;
159
+ result->f.attrs.secure = arm_space_is_secure(out_space);
160
161
if (regime_is_stage2(mmu_idx)) {
162
result->cacheattrs.is_s2_format = true;
147
--
163
--
148
2.25.1
164
2.34.1
diff view generated by jsdifflib
1
Currently for the interrupts MCT_G0 and MCT_G1 which are
1
From: Richard Henderson <richard.henderson@linaro.org>
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
2
11
Wire these interrupts up to both combiners, like the rest.
3
While Root and Realm may read and write data from other spaces,
4
neither may execute from other pa spaces.
12
5
6
This happens for Stage1 EL3, EL2, EL2&0, and Stage2 EL1&0.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20230620124418.805717-14-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
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
---
12
---
17
hw/arm/exynos4210.c | 7 +++----
13
target/arm/ptw.c | 52 ++++++++++++++++++++++++++++++++++++++++++------
18
1 file changed, 3 insertions(+), 4 deletions(-)
14
1 file changed, 46 insertions(+), 6 deletions(-)
19
15
20
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
16
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/exynos4210.c
18
--- a/target/arm/ptw.c
23
+++ b/hw/arm/exynos4210.c
19
+++ b/target/arm/ptw.c
24
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
20
@@ -XXX,XX +XXX,XX @@ do_fault:
25
21
* @xn: XN (execute-never) bits
26
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
22
* @s1_is_el0: true if this is S2 of an S1+2 walk for EL0
27
splitter = DEVICE(&s->splitter[splitcount]);
23
*/
28
- qdev_prop_set_uint16(splitter, "num-lines", 2);
24
-static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
29
+ qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
25
+static int get_S2prot_noexecute(int s2ap)
30
qdev_realize(splitter, NULL, &error_abort);
26
{
31
splitcount++;
27
int prot = 0;
32
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
28
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
29
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
34
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
30
if (s2ap & 2) {
35
if (irq_id) {
31
prot |= PAGE_WRITE;
36
- qdev_connect_gpio_out(splitter, 1,
32
}
37
+ qdev_connect_gpio_out(splitter, 2,
33
+ return prot;
38
qdev_get_gpio_in(extgicdev, irq_id - 32));
34
+}
39
- } else {
35
+
40
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
36
+static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
37
+{
38
+ int prot = get_S2prot_noexecute(s2ap);
39
40
if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
41
switch (xn) {
42
@@ -XXX,XX +XXX,XX @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
41
}
43
}
42
}
44
}
43
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
45
46
- if (out_pa == ARMSS_NonSecure && in_pa == ARMSS_Secure &&
47
- (env->cp15.scr_el3 & SCR_SIF)) {
48
- return prot_rw;
49
+ if (in_pa != out_pa) {
50
+ switch (in_pa) {
51
+ case ARMSS_Root:
52
+ /*
53
+ * R_ZWRVD: permission fault for insn fetched from non-Root,
54
+ * I_WWBFB: SIF has no effect in EL3.
55
+ */
56
+ return prot_rw;
57
+ case ARMSS_Realm:
58
+ /*
59
+ * R_PKTDS: permission fault for insn fetched from non-Realm,
60
+ * for Realm EL2 or EL2&0. The corresponding fault for EL1&0
61
+ * happens during any stage2 translation.
62
+ */
63
+ switch (mmu_idx) {
64
+ case ARMMMUIdx_E2:
65
+ case ARMMMUIdx_E20_0:
66
+ case ARMMMUIdx_E20_2:
67
+ case ARMMMUIdx_E20_2_PAN:
68
+ return prot_rw;
69
+ default:
70
+ break;
71
+ }
72
+ break;
73
+ case ARMSS_Secure:
74
+ if (env->cp15.scr_el3 & SCR_SIF) {
75
+ return prot_rw;
76
+ }
77
+ break;
78
+ default:
79
+ /* Input NonSecure must have output NonSecure. */
80
+ g_assert_not_reached();
81
+ }
82
}
83
84
/* TODO have_wxn should be replaced with
85
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
86
/*
87
* R_GYNXY: For stage2 in Realm security state, bit 55 is NS.
88
* The bit remains ignored for other security states.
89
+ * R_YMCSL: Executing an insn fetched from non-Realm causes
90
+ * a stage2 permission fault.
91
*/
92
if (out_space == ARMSS_Realm && extract64(attrs, 55, 1)) {
93
out_space = ARMSS_NonSecure;
94
+ result->f.prot = get_S2prot_noexecute(ap);
95
+ } else {
96
+ xn = extract64(attrs, 53, 2);
97
+ result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
98
}
99
- xn = extract64(attrs, 53, 2);
100
- result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
101
} else {
102
int nse, ns = extract32(attrs, 5, 1);
103
switch (out_space) {
44
--
104
--
45
2.25.1
105
2.34.1
diff view generated by jsdifflib
1
From: Zongyuan Li <zongyuan.li@smartx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
3
Do not provide a fast-path for physical addresses,
4
as those will need to be validated for GPC.
5
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-3-zongyuan.li@smartx.com
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230620124418.805717-15-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
hw/arm/stellaris.c | 15 +++++++++++++--
11
target/arm/ptw.c | 44 +++++++++++++++++---------------------------
9
1 file changed, 13 insertions(+), 2 deletions(-)
12
1 file changed, 17 insertions(+), 27 deletions(-)
10
13
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/stellaris.c
16
--- a/target/arm/ptw.c
14
+++ b/hw/arm/stellaris.c
17
+++ b/target/arm/ptw.c
15
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
16
19
* From gdbstub, do not use softmmu so that we don't modify the
17
#include "qemu/osdep.h"
20
* state of the cpu at all, including softmmu tlb contents.
18
#include "qapi/error.h"
21
*/
19
+#include "hw/core/split-irq.h"
22
- if (regime_is_stage2(s2_mmu_idx)) {
20
#include "hw/sysbus.h"
23
- S1Translate s2ptw = {
21
#include "hw/sd/sd.h"
24
- .in_mmu_idx = s2_mmu_idx,
22
#include "hw/ssi/ssi.h"
25
- .in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
23
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
26
- .in_secure = s2_mmu_idx == ARMMMUIdx_Stage2_S,
24
DeviceState *ssddev;
27
- .in_space = (s2_mmu_idx == ARMMMUIdx_Stage2_S ? ARMSS_Secure
25
DriveInfo *dinfo;
28
- : space == ARMSS_Realm ? ARMSS_Realm
26
DeviceState *carddev;
29
- : ARMSS_NonSecure),
27
+ DeviceState *gpio_d_splitter;
30
- .in_debug = true,
28
BlockBackend *blk;
31
- };
29
32
- GetPhysAddrResult s2 = { };
30
/*
33
+ S1Translate s2ptw = {
31
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
34
+ .in_mmu_idx = s2_mmu_idx,
32
&error_fatal);
35
+ .in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
33
36
+ .in_secure = s2_mmu_idx == ARMMMUIdx_Stage2_S,
34
ssddev = ssi_create_peripheral(bus, "ssd0323");
37
+ .in_space = (s2_mmu_idx == ARMMMUIdx_Stage2_S ? ARMSS_Secure
35
- gpio_out[GPIO_D][0] = qemu_irq_split(
38
+ : space == ARMSS_Realm ? ARMSS_Realm
36
- qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0),
39
+ : ARMSS_NonSecure),
37
+
40
+ .in_debug = true,
38
+ gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
41
+ };
39
+ qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
42
+ GetPhysAddrResult s2 = { };
40
+ qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
43
41
+ qdev_connect_gpio_out(
44
- if (get_phys_addr_lpae(env, &s2ptw, addr, MMU_DATA_LOAD,
42
+ gpio_d_splitter, 0,
45
- false, &s2, fi)) {
43
+ qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0));
46
- goto fail;
44
+ qdev_connect_gpio_out(
47
- }
45
+ gpio_d_splitter, 1,
48
- ptw->out_phys = s2.f.phys_addr;
46
qdev_get_gpio_in_named(ssddev, SSI_GPIO_CS, 0));
49
- pte_attrs = s2.cacheattrs.attrs;
47
+ gpio_out[GPIO_D][0] = qdev_get_gpio_in(gpio_d_splitter, 0);
50
- ptw->out_secure = s2.f.attrs.secure;
48
+
51
- ptw->out_space = s2.f.attrs.space;
49
gpio_out[GPIO_C][7] = qdev_get_gpio_in(ssddev, 0);
52
- } else {
50
53
- /* Regime is physical. */
51
/* Make sure the select pin is high. */
54
- ptw->out_phys = addr;
55
- pte_attrs = 0;
56
- ptw->out_secure = s2_mmu_idx == ARMMMUIdx_Phys_S;
57
- ptw->out_space = (s2_mmu_idx == ARMMMUIdx_Phys_S ? ARMSS_Secure
58
- : space == ARMSS_Realm ? ARMSS_Realm
59
- : ARMSS_NonSecure);
60
+ if (get_phys_addr_with_struct(env, &s2ptw, addr,
61
+ MMU_DATA_LOAD, &s2, fi)) {
62
+ goto fail;
63
}
64
+ ptw->out_phys = s2.f.phys_addr;
65
+ pte_attrs = s2.cacheattrs.attrs;
66
ptw->out_host = NULL;
67
ptw->out_rw = false;
68
+ ptw->out_secure = s2.f.attrs.secure;
69
+ ptw->out_space = s2.f.attrs.space;
70
} else {
71
#ifdef CONFIG_TCG
72
CPUTLBEntryFull *full;
52
--
73
--
53
2.25.1
74
2.34.1
diff view generated by jsdifflib
1
Switch the creation of the external GIC to the new-style "embedded in
1
From: Richard Henderson <richard.henderson@linaro.org>
2
state struct" approach, so we can easily refer to the object
3
elsewhere during realize.
4
2
3
Instead of passing this to get_phys_addr_lpae, stash it
4
in the S1Translate structure.
5
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230620124418.805717-16-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220404154658.565020-9-peter.maydell@linaro.org
8
---
11
---
9
include/hw/arm/exynos4210.h | 2 ++
12
target/arm/ptw.c | 27 ++++++++++++---------------
10
include/hw/intc/exynos4210_gic.h | 43 ++++++++++++++++++++++++++++++++
13
1 file changed, 12 insertions(+), 15 deletions(-)
11
hw/arm/exynos4210.c | 10 ++++----
12
hw/intc/exynos4210_gic.c | 17 ++-----------
13
MAINTAINERS | 2 +-
14
5 files changed, 53 insertions(+), 21 deletions(-)
15
create mode 100644 include/hw/intc/exynos4210_gic.h
16
14
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
17
--- a/target/arm/ptw.c
20
+++ b/include/hw/arm/exynos4210.h
18
+++ b/target/arm/ptw.c
21
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
22
#include "hw/or-irq.h"
20
ARMSecuritySpace in_space;
23
#include "hw/sysbus.h"
21
bool in_secure;
24
#include "hw/cpu/a9mpcore.h"
22
bool in_debug;
25
+#include "hw/intc/exynos4210_gic.h"
23
+ /*
26
#include "target/arm/cpu-qom.h"
24
+ * If this is stage 2 of a stage 1+2 page table walk, then this must
27
#include "qom/object.h"
25
+ * be true if stage 1 is an EL0 access; otherwise this is ignored.
28
26
+ * Stage 2 is indicated by in_mmu_idx set to ARMMMUIdx_Stage2{,_S}.
29
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
27
+ */
30
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
28
+ bool in_s1_is_el0;
31
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
29
bool out_secure;
32
A9MPPrivState a9mpcore;
30
bool out_rw;
33
+ Exynos4210GicState ext_gic;
31
bool out_be;
34
};
32
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
35
33
} S1Translate;
36
#define TYPE_EXYNOS4210_SOC "exynos4210"
34
37
diff --git a/include/hw/intc/exynos4210_gic.h b/include/hw/intc/exynos4210_gic.h
35
static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
38
new file mode 100644
36
- uint64_t address,
39
index XXXXXXX..XXXXXXX
37
- MMUAccessType access_type, bool s1_is_el0,
40
--- /dev/null
38
+ uint64_t address, MMUAccessType access_type,
41
+++ b/include/hw/intc/exynos4210_gic.h
39
GetPhysAddrResult *result, ARMMMUFaultInfo *fi);
42
@@ -XXX,XX +XXX,XX @@
40
43
+/*
41
static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
44
+ * Samsung exynos4210 GIC implementation. Based on hw/arm_gic.c
42
@@ -XXX,XX +XXX,XX @@ static int check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, uint64_t tcr,
45
+ *
43
* @ptw: Current and next stage parameters for the walk.
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
44
* @address: virtual address to get physical address for
47
+ * All rights reserved.
45
* @access_type: MMU_DATA_LOAD, MMU_DATA_STORE or MMU_INST_FETCH
48
+ *
46
- * @s1_is_el0: if @ptw->in_mmu_idx is ARMMMUIdx_Stage2
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
47
- * (so this is a stage 2 page table walk),
50
+ *
48
- * must be true if this is stage 2 of a stage 1+2
51
+ * This program is free software; you can redistribute it and/or modify it
49
- * walk for an EL0 access. If @mmu_idx is anything else,
52
+ * under the terms of the GNU General Public License as published by the
50
- * @s1_is_el0 is ignored.
53
+ * Free Software Foundation; either version 2 of the License, or (at your
51
* @result: set on translation success,
54
+ * option) any later version.
52
* @fi: set to fault info if the translation fails
55
+ *
53
*/
56
+ * This program is distributed in the hope that it will be useful,
54
static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
55
uint64_t address,
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
56
- MMUAccessType access_type, bool s1_is_el0,
59
+ * See the GNU General Public License for more details.
57
+ MMUAccessType access_type,
60
+ *
58
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
61
+ * You should have received a copy of the GNU General Public License along
59
{
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
60
ARMCPU *cpu = env_archcpu(env);
63
+ */
61
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
64
+#ifndef HW_INTC_EXYNOS4210_GIC_H
62
result->f.prot = get_S2prot_noexecute(ap);
65
+#define HW_INTC_EXYNOS4210_GIC_H
63
} else {
66
+
64
xn = extract64(attrs, 53, 2);
67
+#include "hw/sysbus.h"
65
- result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
68
+
66
+ result->f.prot = get_S2prot(env, ap, xn, ptw->in_s1_is_el0);
69
+#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
67
}
70
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
68
} else {
71
+
69
int nse, ns = extract32(attrs, 5, 1);
72
+#define EXYNOS4210_GIC_NCPUS 2
70
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
73
+
71
bool ret, ipa_secure;
74
+struct Exynos4210GicState {
72
ARMCacheAttrs cacheattrs1;
75
+ SysBusDevice parent_obj;
73
ARMSecuritySpace ipa_space;
76
+
74
- bool is_el0;
77
+ MemoryRegion cpu_container;
75
uint64_t hcr;
78
+ MemoryRegion dist_container;
76
79
+ MemoryRegion cpu_alias[EXYNOS4210_GIC_NCPUS];
77
ret = get_phys_addr_with_struct(env, ptw, address, access_type, result, fi);
80
+ MemoryRegion dist_alias[EXYNOS4210_GIC_NCPUS];
78
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
81
+ uint32_t num_cpu;
79
ipa_secure = result->f.attrs.secure;
82
+ DeviceState *gic;
80
ipa_space = result->f.attrs.space;
83
+};
81
84
+
82
- is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
85
+#endif
83
+ ptw->in_s1_is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
86
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
84
ptw->in_mmu_idx = ipa_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
87
index XXXXXXX..XXXXXXX 100644
85
ptw->in_secure = ipa_secure;
88
--- a/hw/arm/exynos4210.c
86
ptw->in_space = ipa_space;
89
+++ b/hw/arm/exynos4210.c
87
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
90
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
88
ret = get_phys_addr_pmsav8(env, ipa, access_type,
91
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
89
ptw->in_mmu_idx, is_secure, result, fi);
92
90
} else {
93
/* External GIC */
91
- ret = get_phys_addr_lpae(env, ptw, ipa, access_type,
94
- dev = qdev_new("exynos4210.gic");
92
- is_el0, result, fi);
95
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
93
+ ret = get_phys_addr_lpae(env, ptw, ipa, access_type, result, fi);
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
}
94
}
107
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
95
fi->s2addr = ipa;
108
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
96
109
+ s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
97
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
110
}
98
}
111
99
112
/* Internal Interrupt Combiner */
100
if (regime_using_lpae_format(env, mmu_idx)) {
113
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
101
- return get_phys_addr_lpae(env, ptw, address, access_type, false,
114
}
102
- result, fi);
115
103
+ return get_phys_addr_lpae(env, ptw, address, access_type, result, fi);
116
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
104
} else if (arm_feature(env, ARM_FEATURE_V7) ||
117
+ object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
105
regime_sctlr(env, mmu_idx) & SCTLR_XP) {
118
}
106
return get_phys_addr_v6(env, ptw, address, access_type, result, fi);
119
120
static void exynos4210_class_init(ObjectClass *klass, void *data)
121
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/hw/intc/exynos4210_gic.c
124
+++ b/hw/intc/exynos4210_gic.c
125
@@ -XXX,XX +XXX,XX @@
126
#include "qemu/module.h"
127
#include "hw/irq.h"
128
#include "hw/qdev-properties.h"
129
+#include "hw/intc/exynos4210_gic.h"
130
#include "hw/arm/exynos4210.h"
131
#include "qom/object.h"
132
133
@@ -XXX,XX +XXX,XX @@
134
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
135
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
136
137
-#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
138
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
139
-
140
-struct Exynos4210GicState {
141
- SysBusDevice parent_obj;
142
-
143
- MemoryRegion cpu_container;
144
- MemoryRegion dist_container;
145
- MemoryRegion cpu_alias[EXYNOS4210_NCPUS];
146
- MemoryRegion dist_alias[EXYNOS4210_NCPUS];
147
- uint32_t num_cpu;
148
- DeviceState *gic;
149
-};
150
-
151
static void exynos4210_gic_set_irq(void *opaque, int irq, int level)
152
{
153
Exynos4210GicState *s = (Exynos4210GicState *)opaque;
154
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
155
* enough room for the cpu numbers. gcc 9.2.1 on 32-bit x86
156
* doesn't figure this out, otherwise and gives spurious warnings.
157
*/
158
- assert(n <= EXYNOS4210_NCPUS);
159
+ assert(n <= EXYNOS4210_GIC_NCPUS);
160
for (i = 0; i < n; i++) {
161
/* Map CPU interface per SMP Core */
162
sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
163
diff --git a/MAINTAINERS b/MAINTAINERS
164
index XXXXXXX..XXXXXXX 100644
165
--- a/MAINTAINERS
166
+++ b/MAINTAINERS
167
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
168
L: qemu-arm@nongnu.org
169
S: Odd Fixes
170
F: hw/*/exynos*
171
-F: include/hw/arm/exynos4210.h
172
+F: include/hw/*/exynos*
173
174
Calxeda Highbank
175
M: Rob Herring <robh@kernel.org>
176
--
107
--
177
2.25.1
108
2.34.1
109
110
diff view generated by jsdifflib
1
From: Zongyuan Li <zongyuan.li@smartx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
3
This fixes a bug in which we failed to initialize
4
the result attributes properly after the memset.
5
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-2-zongyuan.li@smartx.com
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230620124418.805717-17-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
hw/arm/realview.c | 33 ++++++++++++++++++++++++---------
12
target/arm/ptw.c | 11 +----------
9
1 file changed, 24 insertions(+), 9 deletions(-)
13
1 file changed, 1 insertion(+), 10 deletions(-)
10
14
11
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/realview.c
17
--- a/target/arm/ptw.c
14
+++ b/hw/arm/realview.c
18
+++ b/target/arm/ptw.c
15
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
16
#include "hw/sysbus.h"
20
void *out_host;
17
#include "hw/arm/boot.h"
21
} S1Translate;
18
#include "hw/arm/primecell.h"
22
19
+#include "hw/core/split-irq.h"
23
-static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
20
#include "hw/net/lan9118.h"
24
- uint64_t address, MMUAccessType access_type,
21
#include "hw/net/smc91c111.h"
25
- GetPhysAddrResult *result, ARMMMUFaultInfo *fi);
22
#include "hw/pci/pci.h"
26
-
23
+#include "hw/qdev-core.h"
27
static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
24
#include "net/net.h"
28
target_ulong address,
25
#include "sysemu/sysemu.h"
29
MMUAccessType access_type,
26
#include "hw/boards.h"
30
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
27
@@ -XXX,XX +XXX,XX @@ static const int realview_board_id[] = {
31
cacheattrs1 = result->cacheattrs;
28
0x76d
32
memset(result, 0, sizeof(*result));
29
};
33
30
34
- if (arm_feature(env, ARM_FEATURE_PMSA)) {
31
+static void split_irq_from_named(DeviceState *src, const char* outname,
35
- ret = get_phys_addr_pmsav8(env, ipa, access_type,
32
+ qemu_irq out1, qemu_irq out2) {
36
- ptw->in_mmu_idx, is_secure, result, fi);
33
+ DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
37
- } else {
34
+
38
- ret = get_phys_addr_lpae(env, ptw, ipa, access_type, result, fi);
35
+ qdev_prop_set_uint32(splitter, "num-lines", 2);
39
- }
36
+
40
+ ret = get_phys_addr_with_struct(env, ptw, ipa, access_type, result, fi);
37
+ qdev_realize_and_unref(splitter, NULL, &error_fatal);
41
fi->s2addr = ipa;
38
+
42
39
+ qdev_connect_gpio_out(splitter, 0, out1);
43
/* Combine the S1 and S2 perms. */
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
--
44
--
80
2.25.1
45
2.34.1
46
47
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Connect the 4 TTC timers on the ZynqMP.
3
The function takes the fields as filled in by
4
the Arm ARM pseudocode for TakeGPCException.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Message-id: 20230620124418.805717-18-richard.henderson@linaro.org
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>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
include/hw/arm/xlnx-zynqmp.h | 4 ++++
11
target/arm/syndrome.h | 10 ++++++++++
13
hw/arm/xlnx-zynqmp.c | 22 ++++++++++++++++++++++
12
1 file changed, 10 insertions(+)
14
2 files changed, 26 insertions(+)
15
13
16
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
14
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-zynqmp.h
16
--- a/target/arm/syndrome.h
19
+++ b/include/hw/arm/xlnx-zynqmp.h
17
+++ b/target/arm/syndrome.h
20
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
21
#include "hw/or-irq.h"
19
EC_SVEACCESSTRAP = 0x19,
22
#include "hw/misc/xlnx-zynqmp-apu-ctrl.h"
20
EC_ERETTRAP = 0x1a,
23
#include "hw/misc/xlnx-zynqmp-crf.h"
21
EC_SMETRAP = 0x1d,
24
+#include "hw/timer/cadence_ttc.h"
22
+ EC_GPC = 0x1e,
25
23
EC_INSNABORT = 0x20,
26
#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
24
EC_INSNABORT_SAME_EL = 0x21,
27
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
25
EC_PCALIGNMENT = 0x22,
28
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
26
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_bxjtrap(int cv, int cond, int rm)
29
#define XLNX_ZYNQMP_MAX_RAM_SIZE (XLNX_ZYNQMP_MAX_LOW_RAM_SIZE + \
27
(cv << 24) | (cond << 20) | rm;
30
XLNX_ZYNQMP_MAX_HIGH_RAM_SIZE)
31
32
+#define XLNX_ZYNQMP_NUM_TTC 4
33
+
34
/*
35
* Unimplemented mmio regions needed to boot some images.
36
*/
37
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
38
qemu_or_irq qspi_irq_orgate;
39
XlnxZynqMPAPUCtrl apu_ctrl;
40
XlnxZynqMPCRF crf;
41
+ CadenceTTCState ttc[XLNX_ZYNQMP_NUM_TTC];
42
43
char *boot_cpu;
44
ARMCPU *boot_cpu_ptr;
45
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/arm/xlnx-zynqmp.c
48
+++ b/hw/arm/xlnx-zynqmp.c
49
@@ -XXX,XX +XXX,XX @@
50
#define APU_ADDR 0xfd5c0000
51
#define APU_IRQ 153
52
53
+#define TTC0_ADDR 0xFF110000
54
+#define TTC0_IRQ 36
55
+
56
#define IPI_ADDR 0xFF300000
57
#define IPI_IRQ 64
58
59
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_crf(XlnxZynqMPState *s, qemu_irq *gic)
60
sysbus_connect_irq(sbd, 0, gic[CRF_IRQ]);
61
}
28
}
62
29
63
+static void xlnx_zynqmp_create_ttc(XlnxZynqMPState *s, qemu_irq *gic)
30
+static inline uint32_t syn_gpc(int s2ptw, int ind, int gpcsc,
31
+ int cm, int s1ptw, int wnr, int fsc)
64
+{
32
+{
65
+ SysBusDevice *sbd;
33
+ /* TODO: FEAT_NV2 adds VNCR */
66
+ int i, irq;
34
+ return (EC_GPC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (s2ptw << 21)
67
+
35
+ | (ind << 20) | (gpcsc << 14) | (cm << 8) | (s1ptw << 7)
68
+ for (i = 0; i < XLNX_ZYNQMP_NUM_TTC; i++) {
36
+ | (wnr << 6) | fsc;
69
+ object_initialize_child(OBJECT(s), "ttc[*]", &s->ttc[i],
70
+ TYPE_CADENCE_TTC);
71
+ sbd = SYS_BUS_DEVICE(&s->ttc[i]);
72
+
73
+ sysbus_realize(sbd, &error_fatal);
74
+ sysbus_mmio_map(sbd, 0, TTC0_ADDR + i * 0x10000);
75
+ for (irq = 0; irq < 3; irq++) {
76
+ sysbus_connect_irq(sbd, irq, gic[TTC0_IRQ + i * 3 + irq]);
77
+ }
78
+ }
79
+}
37
+}
80
+
38
+
81
static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
39
static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
82
{
40
{
83
static const struct UnimpInfo {
41
return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
84
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
85
xlnx_zynqmp_create_efuse(s, gic_spi);
86
xlnx_zynqmp_create_apu_ctrl(s, gic_spi);
87
xlnx_zynqmp_create_crf(s, gic_spi);
88
+ xlnx_zynqmp_create_ttc(s, gic_spi);
89
xlnx_zynqmp_create_unimp_mmio(s);
90
91
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
92
--
42
--
93
2.25.1
43
2.34.1
diff view generated by jsdifflib
1
The exynos4210 SoC mostly creates its child devices as if it were
1
From: Richard Henderson <richard.henderson@linaro.org>
2
board code. This includes the a9mpcore object. Switch that to a
3
new-style "embedded in the state struct" creation, because in the
4
next commit we're going to want to refer to the object again further
5
down in the exynos4210_realize() function.
6
2
3
Handle GPC Fault types in arm_deliver_fault, reporting as
4
either a GPC exception at EL3, or falling through to insn
5
or data aborts at various exception levels.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230620124418.805717-19-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220404154658.565020-4-peter.maydell@linaro.org
10
---
11
---
11
include/hw/arm/exynos4210.h | 2 ++
12
target/arm/cpu.h | 1 +
12
hw/arm/exynos4210.c | 11 ++++++-----
13
target/arm/internals.h | 27 +++++++++++
13
2 files changed, 8 insertions(+), 5 deletions(-)
14
target/arm/helper.c | 5 ++
15
target/arm/tcg/tlb_helper.c | 96 +++++++++++++++++++++++++++++++++++--
16
4 files changed, 126 insertions(+), 3 deletions(-)
14
17
15
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/exynos4210.h
20
--- a/target/arm/cpu.h
18
+++ b/include/hw/arm/exynos4210.h
21
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
20
23
#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
21
#include "hw/or-irq.h"
24
#define EXCP_DIVBYZERO 23 /* v7M DIVBYZERO UsageFault */
22
#include "hw/sysbus.h"
25
#define EXCP_VSERR 24
23
+#include "hw/cpu/a9mpcore.h"
26
+#define EXCP_GPC 25 /* v9 Granule Protection Check Fault */
24
#include "target/arm/cpu-qom.h"
27
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
25
#include "qom/object.h"
28
26
29
#define ARMV7M_EXCP_RESET 1
27
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
30
diff --git a/target/arm/internals.h b/target/arm/internals.h
28
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
31
index XXXXXXX..XXXXXXX 100644
29
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
32
--- a/target/arm/internals.h
30
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
33
+++ b/target/arm/internals.h
31
+ A9MPPrivState a9mpcore;
34
@@ -XXX,XX +XXX,XX @@ typedef enum ARMFaultType {
32
};
35
ARMFault_ICacheMaint,
33
36
ARMFault_QEMU_NSCExec, /* v8M: NS executing in S&NSC memory */
34
#define TYPE_EXYNOS4210_SOC "exynos4210"
37
ARMFault_QEMU_SFault, /* v8M: SecureFault INVTRAN, INVEP or AUVIOL */
35
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
38
+ ARMFault_GPCFOnWalk,
36
index XXXXXXX..XXXXXXX 100644
39
+ ARMFault_GPCFOnOutput,
37
--- a/hw/arm/exynos4210.c
40
} ARMFaultType;
38
+++ b/hw/arm/exynos4210.c
41
39
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
42
+typedef enum ARMGPCF {
43
+ GPCF_None,
44
+ GPCF_AddressSize,
45
+ GPCF_Walk,
46
+ GPCF_EABT,
47
+ GPCF_Fail,
48
+} ARMGPCF;
49
+
50
/**
51
* ARMMMUFaultInfo: Information describing an ARM MMU Fault
52
* @type: Type of fault
53
+ * @gpcf: Subtype of ARMFault_GPCFOn{Walk,Output}.
54
* @level: Table walk level (for translation, access flag and permission faults)
55
* @domain: Domain of the fault address (for non-LPAE CPUs only)
56
* @s2addr: Address that caused a fault at stage 2
57
+ * @paddr: physical address that caused a fault for gpc
58
+ * @paddr_space: physical address space that caused a fault for gpc
59
* @stage2: True if we faulted at stage 2
60
* @s1ptw: True if we faulted at stage 2 while doing a stage 1 page-table walk
61
* @s1ns: True if we faulted on a non-secure IPA while in secure state
62
@@ -XXX,XX +XXX,XX @@ typedef enum ARMFaultType {
63
typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
64
struct ARMMMUFaultInfo {
65
ARMFaultType type;
66
+ ARMGPCF gpcf;
67
target_ulong s2addr;
68
+ target_ulong paddr;
69
+ ARMSecuritySpace paddr_space;
70
int level;
71
int domain;
72
bool stage2;
73
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
74
case ARMFault_Exclusive:
75
fsc = 0x35;
76
break;
77
+ case ARMFault_GPCFOnWalk:
78
+ assert(fi->level >= -1 && fi->level <= 3);
79
+ if (fi->level < 0) {
80
+ fsc = 0b100011;
81
+ } else {
82
+ fsc = 0b100100 | fi->level;
83
+ }
84
+ break;
85
+ case ARMFault_GPCFOnOutput:
86
+ fsc = 0b101000;
87
+ break;
88
default:
89
/* Other faults can't occur in a context that requires a
90
* long-format status code.
91
diff --git a/target/arm/helper.c b/target/arm/helper.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/target/arm/helper.c
94
+++ b/target/arm/helper.c
95
@@ -XXX,XX +XXX,XX @@ void arm_log_exception(CPUState *cs)
96
[EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
97
[EXCP_DIVBYZERO] = "v7M DIVBYZERO UsageFault",
98
[EXCP_VSERR] = "Virtual SERR",
99
+ [EXCP_GPC] = "Granule Protection Check",
100
};
101
102
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
103
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
40
}
104
}
41
105
42
/* Private memory region and Internal GIC */
106
switch (cs->exception_index) {
43
- dev = qdev_new(TYPE_A9MPCORE_PRIV);
107
+ case EXCP_GPC:
44
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
108
+ qemu_log_mask(CPU_LOG_INT, "...with MFAR 0x%" PRIx64 "\n",
45
- busdev = SYS_BUS_DEVICE(dev);
109
+ env->cp15.mfar_el3);
46
- sysbus_realize_and_unref(busdev, &error_fatal);
110
+ /* fall through */
47
+ qdev_prop_set_uint32(DEVICE(&s->a9mpcore), "num-cpu", EXYNOS4210_NCPUS);
111
case EXCP_PREFETCH_ABORT:
48
+ busdev = SYS_BUS_DEVICE(&s->a9mpcore);
112
case EXCP_DATA_ABORT:
49
+ sysbus_realize(busdev, &error_fatal);
113
/*
50
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
114
diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c
51
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
115
index XXXXXXX..XXXXXXX 100644
52
sysbus_connect_irq(busdev, n,
116
--- a/target/arm/tcg/tlb_helper.c
53
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
117
+++ b/target/arm/tcg/tlb_helper.c
118
@@ -XXX,XX +XXX,XX @@ static uint32_t compute_fsr_fsc(CPUARMState *env, ARMMMUFaultInfo *fi,
119
return fsr;
120
}
121
122
+static bool report_as_gpc_exception(ARMCPU *cpu, int current_el,
123
+ ARMMMUFaultInfo *fi)
124
+{
125
+ bool ret;
126
+
127
+ switch (fi->gpcf) {
128
+ case GPCF_None:
129
+ return false;
130
+ case GPCF_AddressSize:
131
+ case GPCF_Walk:
132
+ case GPCF_EABT:
133
+ /* R_PYTGX: GPT faults are reported as GPC. */
134
+ ret = true;
135
+ break;
136
+ case GPCF_Fail:
137
+ /*
138
+ * R_BLYPM: A GPF at EL3 is reported as insn or data abort.
139
+ * R_VBZMW, R_LXHQR: A GPF at EL[0-2] is reported as a GPC
140
+ * if SCR_EL3.GPF is set, otherwise an insn or data abort.
141
+ */
142
+ ret = (cpu->env.cp15.scr_el3 & SCR_GPF) && current_el != 3;
143
+ break;
144
+ default:
145
+ g_assert_not_reached();
146
+ }
147
+
148
+ assert(cpu_isar_feature(aa64_rme, cpu));
149
+ assert(fi->type == ARMFault_GPCFOnWalk ||
150
+ fi->type == ARMFault_GPCFOnOutput);
151
+ if (fi->gpcf == GPCF_AddressSize) {
152
+ assert(fi->level == 0);
153
+ } else {
154
+ assert(fi->level >= 0 && fi->level <= 1);
155
+ }
156
+
157
+ return ret;
158
+}
159
+
160
+static unsigned encode_gpcsc(ARMMMUFaultInfo *fi)
161
+{
162
+ static uint8_t const gpcsc[] = {
163
+ [GPCF_AddressSize] = 0b000000,
164
+ [GPCF_Walk] = 0b000100,
165
+ [GPCF_Fail] = 0b001100,
166
+ [GPCF_EABT] = 0b010100,
167
+ };
168
+
169
+ /* Note that we've validated fi->gpcf and fi->level above. */
170
+ return gpcsc[fi->gpcf] | fi->level;
171
+}
172
+
173
static G_NORETURN
174
void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
175
MMUAccessType access_type,
176
int mmu_idx, ARMMMUFaultInfo *fi)
177
{
178
CPUARMState *env = &cpu->env;
179
- int target_el;
180
+ int target_el = exception_target_el(env);
181
+ int current_el = arm_current_el(env);
182
bool same_el;
183
uint32_t syn, exc, fsr, fsc;
184
185
- target_el = exception_target_el(env);
186
+ if (report_as_gpc_exception(cpu, current_el, fi)) {
187
+ target_el = 3;
188
+
189
+ fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc);
190
+
191
+ syn = syn_gpc(fi->stage2 && fi->type == ARMFault_GPCFOnWalk,
192
+ access_type == MMU_INST_FETCH,
193
+ encode_gpcsc(fi), 0, fi->s1ptw,
194
+ access_type == MMU_DATA_STORE, fsc);
195
+
196
+ env->cp15.mfar_el3 = fi->paddr;
197
+ switch (fi->paddr_space) {
198
+ case ARMSS_Secure:
199
+ break;
200
+ case ARMSS_NonSecure:
201
+ env->cp15.mfar_el3 |= R_MFAR_NS_MASK;
202
+ break;
203
+ case ARMSS_Root:
204
+ env->cp15.mfar_el3 |= R_MFAR_NSE_MASK;
205
+ break;
206
+ case ARMSS_Realm:
207
+ env->cp15.mfar_el3 |= R_MFAR_NSE_MASK | R_MFAR_NS_MASK;
208
+ break;
209
+ default:
210
+ g_assert_not_reached();
211
+ }
212
+
213
+ exc = EXCP_GPC;
214
+ goto do_raise;
215
+ }
216
+
217
+ /* If SCR_EL3.GPF is unset, GPF may still be routed to EL2. */
218
+ if (fi->gpcf == GPCF_Fail && target_el < 2) {
219
+ if (arm_hcr_el2_eff(env) & HCR_GPF) {
220
+ target_el = 2;
221
+ }
222
+ }
223
+
224
if (fi->stage2) {
225
target_el = 2;
226
env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
227
@@ -XXX,XX +XXX,XX @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
228
env->cp15.hpfar_el2 |= HPFAR_NS;
229
}
54
}
230
}
55
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
231
- same_el = (arm_current_el(env) == target_el);
56
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
232
57
+ s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
233
+ same_el = current_el == target_el;
234
fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc);
235
236
if (access_type == MMU_INST_FETCH) {
237
@@ -XXX,XX +XXX,XX @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
238
exc = EXCP_DATA_ABORT;
58
}
239
}
59
240
60
/* Cache controller */
241
+ do_raise:
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
242
env->exception.vaddress = addr;
62
g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
243
env->exception.fsr = fsr;
63
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
244
raise_exception(env, exc, syn, target_el);
64
}
65
+
66
+ object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
67
}
68
69
static void exynos4210_class_init(ObjectClass *klass, void *data)
70
--
245
--
71
2.25.1
246
2.34.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add the Cortex-R5Fs of the Versal RPU (Real-time Processing Unit)
3
Place the check at the end of get_phys_addr_with_struct,
4
subsystem.
4
so that we check all physical results.
5
5
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220406174303.2022038-3-edgar.iglesias@xilinx.com
8
Message-id: 20230620124418.805717-20-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
include/hw/arm/xlnx-versal.h | 10 ++++++++++
11
target/arm/ptw.c | 249 +++++++++++++++++++++++++++++++++++++++++++----
12
hw/arm/xlnx-versal-virt.c | 6 +++---
12
1 file changed, 232 insertions(+), 17 deletions(-)
13
hw/arm/xlnx-versal.c | 36 ++++++++++++++++++++++++++++++++++++
14
3 files changed, 49 insertions(+), 3 deletions(-)
15
13
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
16
--- a/target/arm/ptw.c
19
+++ b/include/hw/arm/xlnx-versal.h
17
+++ b/target/arm/ptw.c
20
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
21
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
19
void *out_host;
22
20
} S1Translate;
23
#define XLNX_VERSAL_NR_ACPUS 2
21
24
+#define XLNX_VERSAL_NR_RCPUS 2
22
-static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
25
#define XLNX_VERSAL_NR_UARTS 2
23
- target_ulong address,
26
#define XLNX_VERSAL_NR_GEMS 2
24
- MMUAccessType access_type,
27
#define XLNX_VERSAL_NR_ADMAS 8
25
- GetPhysAddrResult *result,
28
@@ -XXX,XX +XXX,XX @@ struct Versal {
26
- ARMMMUFaultInfo *fi);
29
VersalUsb2 usb;
27
+static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
30
} iou;
28
+ target_ulong address,
31
29
+ MMUAccessType access_type,
32
+ /* Real-time Processing Unit. */
30
+ GetPhysAddrResult *result,
33
+ struct {
31
+ ARMMMUFaultInfo *fi);
34
+ MemoryRegion mr;
32
+
35
+ MemoryRegion mr_ps_alias;
33
+static bool get_phys_addr_gpc(CPUARMState *env, S1Translate *ptw,
36
+
34
+ target_ulong address,
37
+ CPUClusterState cluster;
35
+ MMUAccessType access_type,
38
+ ARMCPU cpu[XLNX_VERSAL_NR_RCPUS];
36
+ GetPhysAddrResult *result,
39
+ } rpu;
37
+ ARMMMUFaultInfo *fi);
40
+
38
41
struct {
39
/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
42
qemu_or_irq irq_orgate;
40
static const uint8_t pamax_map[] = {
43
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
41
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
44
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
42
return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
45
index XXXXXXX..XXXXXXX 100644
43
}
46
--- a/hw/arm/xlnx-versal-virt.c
44
47
+++ b/hw/arm/xlnx-versal-virt.c
45
+static bool granule_protection_check(CPUARMState *env, uint64_t paddress,
48
@@ -XXX,XX +XXX,XX @@ static void versal_virt_machine_class_init(ObjectClass *oc, void *data)
46
+ ARMSecuritySpace pspace,
49
47
+ ARMMMUFaultInfo *fi)
50
mc->desc = "Xilinx Versal Virtual development board";
48
+{
51
mc->init = versal_virt_init;
49
+ MemTxAttrs attrs = {
52
- mc->min_cpus = XLNX_VERSAL_NR_ACPUS;
50
+ .secure = true,
53
- mc->max_cpus = XLNX_VERSAL_NR_ACPUS;
51
+ .space = ARMSS_Root,
54
- mc->default_cpus = XLNX_VERSAL_NR_ACPUS;
52
+ };
55
+ mc->min_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
53
+ ARMCPU *cpu = env_archcpu(env);
56
+ mc->max_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
54
+ uint64_t gpccr = env->cp15.gpccr_el3;
57
+ mc->default_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
55
+ unsigned pps, pgs, l0gptsz, level = 0;
58
mc->no_cdrom = true;
56
+ uint64_t tableaddr, pps_mask, align, entry, index;
59
mc->default_ram_id = "ddr";
57
+ AddressSpace *as;
60
}
58
+ MemTxResult result;
61
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
59
+ int gpi;
62
index XXXXXXX..XXXXXXX 100644
60
+
63
--- a/hw/arm/xlnx-versal.c
61
+ if (!FIELD_EX64(gpccr, GPCCR, GPC)) {
64
+++ b/hw/arm/xlnx-versal.c
62
+ return true;
65
@@ -XXX,XX +XXX,XX @@
63
+ }
66
#include "hw/sysbus.h"
64
+
67
65
+ /*
68
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
66
+ * GPC Priority 1 (R_GMGRR):
69
+#define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f")
67
+ * R_JWCSM: If the configuration of GPCCR_EL3 is invalid,
70
#define GEM_REVISION 0x40070106
68
+ * the access fails as GPT walk fault at level 0.
71
69
+ */
72
#define VERSAL_NUM_PMC_APB_IRQS 3
70
+
73
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
71
+ /*
72
+ * Configuration of PPS to a value exceeding the implemented
73
+ * physical address size is invalid.
74
+ */
75
+ pps = FIELD_EX64(gpccr, GPCCR, PPS);
76
+ if (pps > FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE)) {
77
+ goto fault_walk;
78
+ }
79
+ pps = pamax_map[pps];
80
+ pps_mask = MAKE_64BIT_MASK(0, pps);
81
+
82
+ switch (FIELD_EX64(gpccr, GPCCR, SH)) {
83
+ case 0b10: /* outer shareable */
84
+ break;
85
+ case 0b00: /* non-shareable */
86
+ case 0b11: /* inner shareable */
87
+ /* Inner and Outer non-cacheable requires Outer shareable. */
88
+ if (FIELD_EX64(gpccr, GPCCR, ORGN) == 0 &&
89
+ FIELD_EX64(gpccr, GPCCR, IRGN) == 0) {
90
+ goto fault_walk;
91
+ }
92
+ break;
93
+ default: /* reserved */
94
+ goto fault_walk;
95
+ }
96
+
97
+ switch (FIELD_EX64(gpccr, GPCCR, PGS)) {
98
+ case 0b00: /* 4KB */
99
+ pgs = 12;
100
+ break;
101
+ case 0b01: /* 64KB */
102
+ pgs = 16;
103
+ break;
104
+ case 0b10: /* 16KB */
105
+ pgs = 14;
106
+ break;
107
+ default: /* reserved */
108
+ goto fault_walk;
109
+ }
110
+
111
+ /* Note this field is read-only and fixed at reset. */
112
+ l0gptsz = 30 + FIELD_EX64(gpccr, GPCCR, L0GPTSZ);
113
+
114
+ /*
115
+ * GPC Priority 2: Secure, Realm or Root address exceeds PPS.
116
+ * R_CPDSB: A NonSecure physical address input exceeding PPS
117
+ * does not experience any fault.
118
+ */
119
+ if (paddress & ~pps_mask) {
120
+ if (pspace == ARMSS_NonSecure) {
121
+ return true;
122
+ }
123
+ goto fault_size;
124
+ }
125
+
126
+ /* GPC Priority 3: the base address of GPTBR_EL3 exceeds PPS. */
127
+ tableaddr = env->cp15.gptbr_el3 << 12;
128
+ if (tableaddr & ~pps_mask) {
129
+ goto fault_size;
130
+ }
131
+
132
+ /*
133
+ * BADDR is aligned per a function of PPS and L0GPTSZ.
134
+ * These bits of GPTBR_EL3 are RES0, but are not a configuration error,
135
+ * unlike the RES0 bits of the GPT entries (R_XNKFZ).
136
+ */
137
+ align = MAX(pps - l0gptsz + 3, 12);
138
+ align = MAKE_64BIT_MASK(0, align);
139
+ tableaddr &= ~align;
140
+
141
+ as = arm_addressspace(env_cpu(env), attrs);
142
+
143
+ /* Level 0 lookup. */
144
+ index = extract64(paddress, l0gptsz, pps - l0gptsz);
145
+ tableaddr += index * 8;
146
+ entry = address_space_ldq_le(as, tableaddr, attrs, &result);
147
+ if (result != MEMTX_OK) {
148
+ goto fault_eabt;
149
+ }
150
+
151
+ switch (extract32(entry, 0, 4)) {
152
+ case 1: /* block descriptor */
153
+ if (entry >> 8) {
154
+ goto fault_walk; /* RES0 bits not 0 */
155
+ }
156
+ gpi = extract32(entry, 4, 4);
157
+ goto found;
158
+ case 3: /* table descriptor */
159
+ tableaddr = entry & ~0xf;
160
+ align = MAX(l0gptsz - pgs - 1, 12);
161
+ align = MAKE_64BIT_MASK(0, align);
162
+ if (tableaddr & (~pps_mask | align)) {
163
+ goto fault_walk; /* RES0 bits not 0 */
164
+ }
165
+ break;
166
+ default: /* invalid */
167
+ goto fault_walk;
168
+ }
169
+
170
+ /* Level 1 lookup */
171
+ level = 1;
172
+ index = extract64(paddress, pgs + 4, l0gptsz - pgs - 4);
173
+ tableaddr += index * 8;
174
+ entry = address_space_ldq_le(as, tableaddr, attrs, &result);
175
+ if (result != MEMTX_OK) {
176
+ goto fault_eabt;
177
+ }
178
+
179
+ switch (extract32(entry, 0, 4)) {
180
+ case 1: /* contiguous descriptor */
181
+ if (entry >> 10) {
182
+ goto fault_walk; /* RES0 bits not 0 */
183
+ }
184
+ /*
185
+ * Because the softmmu tlb only works on units of TARGET_PAGE_SIZE,
186
+ * and because we cannot invalidate by pa, and thus will always
187
+ * flush entire tlbs, we don't actually care about the range here
188
+ * and can simply extract the GPI as the result.
189
+ */
190
+ if (extract32(entry, 8, 2) == 0) {
191
+ goto fault_walk; /* reserved contig */
192
+ }
193
+ gpi = extract32(entry, 4, 4);
194
+ break;
195
+ default:
196
+ index = extract64(paddress, pgs, 4);
197
+ gpi = extract64(entry, index * 4, 4);
198
+ break;
199
+ }
200
+
201
+ found:
202
+ switch (gpi) {
203
+ case 0b0000: /* no access */
204
+ break;
205
+ case 0b1111: /* all access */
206
+ return true;
207
+ case 0b1000:
208
+ case 0b1001:
209
+ case 0b1010:
210
+ case 0b1011:
211
+ if (pspace == (gpi & 3)) {
212
+ return true;
213
+ }
214
+ break;
215
+ default:
216
+ goto fault_walk; /* reserved */
217
+ }
218
+
219
+ fi->gpcf = GPCF_Fail;
220
+ goto fault_common;
221
+ fault_eabt:
222
+ fi->gpcf = GPCF_EABT;
223
+ goto fault_common;
224
+ fault_size:
225
+ fi->gpcf = GPCF_AddressSize;
226
+ goto fault_common;
227
+ fault_walk:
228
+ fi->gpcf = GPCF_Walk;
229
+ fault_common:
230
+ fi->level = level;
231
+ fi->paddr = paddress;
232
+ fi->paddr_space = pspace;
233
+ return false;
234
+}
235
+
236
static bool S2_attrs_are_device(uint64_t hcr, uint8_t attrs)
237
{
238
/*
239
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
240
};
241
GetPhysAddrResult s2 = { };
242
243
- if (get_phys_addr_with_struct(env, &s2ptw, addr,
244
- MMU_DATA_LOAD, &s2, fi)) {
245
+ if (get_phys_addr_gpc(env, &s2ptw, addr, MMU_DATA_LOAD, &s2, fi)) {
246
goto fail;
247
}
248
+
249
ptw->out_phys = s2.f.phys_addr;
250
pte_attrs = s2.cacheattrs.attrs;
251
ptw->out_host = NULL;
252
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
253
254
fail:
255
assert(fi->type != ARMFault_None);
256
+ if (fi->type == ARMFault_GPCFOnOutput) {
257
+ fi->type = ARMFault_GPCFOnWalk;
258
+ }
259
fi->s2addr = addr;
260
fi->stage2 = true;
261
fi->s1ptw = true;
262
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
263
ARMMMUFaultInfo *fi)
264
{
265
uint8_t memattr = 0x00; /* Device nGnRnE */
266
- uint8_t shareability = 0; /* non-sharable */
267
+ uint8_t shareability = 0; /* non-shareable */
268
int r_el;
269
270
switch (mmu_idx) {
271
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
272
} else {
273
memattr = 0x44; /* Normal, NC, No */
274
}
275
- shareability = 2; /* outer sharable */
276
+ shareability = 2; /* outer shareable */
277
}
278
result->cacheattrs.is_s2_format = false;
279
break;
280
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
281
ARMSecuritySpace ipa_space;
282
uint64_t hcr;
283
284
- ret = get_phys_addr_with_struct(env, ptw, address, access_type, result, fi);
285
+ ret = get_phys_addr_nogpc(env, ptw, address, access_type, result, fi);
286
287
/* If S1 fails, return early. */
288
if (ret) {
289
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
290
cacheattrs1 = result->cacheattrs;
291
memset(result, 0, sizeof(*result));
292
293
- ret = get_phys_addr_with_struct(env, ptw, ipa, access_type, result, fi);
294
+ ret = get_phys_addr_nogpc(env, ptw, ipa, access_type, result, fi);
295
fi->s2addr = ipa;
296
297
/* Combine the S1 and S2 perms. */
298
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
299
return false;
300
}
301
302
-static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
303
+static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
304
target_ulong address,
305
MMUAccessType access_type,
306
GetPhysAddrResult *result,
307
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
74
}
308
}
75
}
309
}
76
310
77
+static void versal_create_rpu_cpus(Versal *s)
311
+static bool get_phys_addr_gpc(CPUARMState *env, S1Translate *ptw,
312
+ target_ulong address,
313
+ MMUAccessType access_type,
314
+ GetPhysAddrResult *result,
315
+ ARMMMUFaultInfo *fi)
78
+{
316
+{
79
+ int i;
317
+ if (get_phys_addr_nogpc(env, ptw, address, access_type, result, fi)) {
80
+
318
+ return true;
81
+ object_initialize_child(OBJECT(s), "rpu-cluster", &s->lpd.rpu.cluster,
319
+ }
82
+ TYPE_CPU_CLUSTER);
320
+ if (!granule_protection_check(env, result->f.phys_addr,
83
+ qdev_prop_set_uint32(DEVICE(&s->lpd.rpu.cluster), "cluster-id", 1);
321
+ result->f.attrs.space, fi)) {
84
+
322
+ fi->type = ARMFault_GPCFOnOutput;
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
323
+ return true;
86
+ Object *obj;
324
+ }
87
+
325
+ return false;
88
+ object_initialize_child(OBJECT(&s->lpd.rpu.cluster),
89
+ "rpu-cpu[*]", &s->lpd.rpu.cpu[i],
90
+ XLNX_VERSAL_RCPU_TYPE);
91
+ obj = OBJECT(&s->lpd.rpu.cpu[i]);
92
+ object_property_set_bool(obj, "start-powered-off", true,
93
+ &error_abort);
94
+
95
+ object_property_set_int(obj, "mp-affinity", 0x100 | i, &error_abort);
96
+ object_property_set_int(obj, "core-count", ARRAY_SIZE(s->lpd.rpu.cpu),
97
+ &error_abort);
98
+ object_property_set_link(obj, "memory", OBJECT(&s->lpd.rpu.mr),
99
+ &error_abort);
100
+ qdev_realize(DEVICE(obj), NULL, &error_fatal);
101
+ }
102
+
103
+ qdev_realize(DEVICE(&s->lpd.rpu.cluster), NULL, &error_fatal);
104
+}
326
+}
105
+
327
+
106
static void versal_create_uarts(Versal *s, qemu_irq *pic)
328
bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
107
{
329
MMUAccessType access_type, ARMMMUIdx mmu_idx,
108
int i;
330
bool is_secure, GetPhysAddrResult *result,
109
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
331
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
110
332
.in_secure = is_secure,
111
versal_create_apu_cpus(s);
333
.in_space = arm_secure_to_space(is_secure),
112
versal_create_apu_gic(s, pic);
334
};
113
+ versal_create_rpu_cpus(s);
335
- return get_phys_addr_with_struct(env, &ptw, address, access_type,
114
versal_create_uarts(s, pic);
336
- result, fi);
115
versal_create_usbs(s, pic);
337
+ return get_phys_addr_gpc(env, &ptw, address, access_type, result, fi);
116
versal_create_gems(s, pic);
338
}
117
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
339
118
340
bool get_phys_addr(CPUARMState *env, target_ulong address,
119
memory_region_add_subregion_overlap(&s->mr_ps, MM_OCM, &s->lpd.mr_ocm, 0);
341
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
120
memory_region_add_subregion_overlap(&s->fpd.apu.mr, 0, &s->mr_ps, 0);
342
121
+ memory_region_add_subregion_overlap(&s->lpd.rpu.mr, 0,
343
ptw.in_space = ss;
122
+ &s->lpd.rpu.mr_ps_alias, 0);
344
ptw.in_secure = arm_space_is_secure(ss);
123
}
345
- return get_phys_addr_with_struct(env, &ptw, address, access_type,
124
346
- result, fi);
125
static void versal_init(Object *obj)
347
+ return get_phys_addr_gpc(env, &ptw, address, access_type, result, fi);
126
@@ -XXX,XX +XXX,XX @@ static void versal_init(Object *obj)
348
}
127
Versal *s = XLNX_VERSAL(obj);
349
128
350
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
129
memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
351
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
130
+ memory_region_init(&s->lpd.rpu.mr, obj, "mr-rpu", UINT64_MAX);
352
ARMMMUFaultInfo fi = {};
131
memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX);
353
bool ret;
132
+ memory_region_init_alias(&s->lpd.rpu.mr_ps_alias, OBJECT(s),
354
133
+ "mr-rpu-ps-alias", &s->mr_ps, 0, UINT64_MAX);
355
- ret = get_phys_addr_with_struct(env, &ptw, addr, MMU_DATA_LOAD, &res, &fi);
134
}
356
+ ret = get_phys_addr_gpc(env, &ptw, addr, MMU_DATA_LOAD, &res, &fi);
135
357
*attrs = res.f.attrs;
136
static Property versal_properties[] = {
358
359
if (ret) {
137
--
360
--
138
2.25.1
361
2.34.1
diff view generated by jsdifflib
1
The function exynos4210_init_board_irqs() currently lives in
1
From: Richard Henderson <richard.henderson@linaro.org>
2
exynos4210_gic.c, but it isn't really part of the exynos4210.gic
3
device -- it is a function that implements (some of) the wiring up of
4
interrupts between the SoC's GIC and combiner components. This means
5
it fits better in exynos4210.c, which is the SoC-level code. Move it
6
there. Similarly, exynos4210_git_irq() is used almost only in the
7
SoC-level code, so move it too.
8
2
3
Add an x-rme cpu property to enable FEAT_RME.
4
Add an x-l0gptsz property to set GPCCR_EL3.L0GPTSZ,
5
for testing various possible configurations.
6
7
We're not currently completely sure whether FEAT_RME will
8
be OK to enable purely as a CPU-level property, or if it will
9
need board co-operation, so we're making these experimental
10
x- properties, so that the people developing the system
11
level software for RME can try to start using this and let
12
us know how it goes. The command line syntax for enabling
13
this will change in future, without backwards-compatibility.
14
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20230620124418.805717-21-richard.henderson@linaro.org
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-8-peter.maydell@linaro.org
12
---
19
---
13
include/hw/arm/exynos4210.h | 4 -
20
target/arm/tcg/cpu64.c | 53 ++++++++++++++++++++++++++++++++++++++++++
14
hw/arm/exynos4210.c | 202 +++++++++++++++++++++++++++++++++++
21
1 file changed, 53 insertions(+)
15
hw/intc/exynos4210_gic.c | 204 ------------------------------------
16
3 files changed, 202 insertions(+), 208 deletions(-)
17
22
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
23
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
19
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/exynos4210.h
25
--- a/target/arm/tcg/cpu64.c
21
+++ b/include/hw/arm/exynos4210.h
26
+++ b/target/arm/tcg/cpu64.c
22
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
27
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
23
void exynos4210_write_secondary(ARMCPU *cpu,
28
cpu->sve_max_vq = max_vq;
24
const struct arm_boot_info *info);
29
}
25
30
26
-/* Initialize board IRQs.
31
+static bool cpu_arm_get_rme(Object *obj, Error **errp)
27
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs */
32
+{
28
-void exynos4210_init_board_irqs(Exynos4210State *s);
33
+ ARMCPU *cpu = ARM_CPU(obj);
29
-
34
+ return cpu_isar_feature(aa64_rme, cpu);
30
/* Get IRQ number from exynos4210 IRQ subsystem stub.
35
+}
31
* To identify IRQ source use internal combiner group and bit number
32
* grp - group number
33
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/exynos4210.c
36
+++ b/hw/arm/exynos4210.c
37
@@ -XXX,XX +XXX,XX @@
38
#define EXYNOS4210_PL330_BASE1_ADDR 0x12690000
39
#define EXYNOS4210_PL330_BASE2_ADDR 0x12850000
40
41
+enum ExtGicId {
42
+ EXT_GIC_ID_MDMA_LCD0 = 66,
43
+ EXT_GIC_ID_PDMA0,
44
+ EXT_GIC_ID_PDMA1,
45
+ EXT_GIC_ID_TIMER0,
46
+ EXT_GIC_ID_TIMER1,
47
+ EXT_GIC_ID_TIMER2,
48
+ EXT_GIC_ID_TIMER3,
49
+ EXT_GIC_ID_TIMER4,
50
+ EXT_GIC_ID_MCT_L0,
51
+ EXT_GIC_ID_WDT,
52
+ EXT_GIC_ID_RTC_ALARM,
53
+ EXT_GIC_ID_RTC_TIC,
54
+ EXT_GIC_ID_GPIO_XB,
55
+ EXT_GIC_ID_GPIO_XA,
56
+ EXT_GIC_ID_MCT_L1,
57
+ EXT_GIC_ID_IEM_APC,
58
+ EXT_GIC_ID_IEM_IEC,
59
+ EXT_GIC_ID_NFC,
60
+ EXT_GIC_ID_UART0,
61
+ EXT_GIC_ID_UART1,
62
+ EXT_GIC_ID_UART2,
63
+ EXT_GIC_ID_UART3,
64
+ EXT_GIC_ID_UART4,
65
+ EXT_GIC_ID_MCT_G0,
66
+ EXT_GIC_ID_I2C0,
67
+ EXT_GIC_ID_I2C1,
68
+ EXT_GIC_ID_I2C2,
69
+ EXT_GIC_ID_I2C3,
70
+ EXT_GIC_ID_I2C4,
71
+ EXT_GIC_ID_I2C5,
72
+ EXT_GIC_ID_I2C6,
73
+ EXT_GIC_ID_I2C7,
74
+ EXT_GIC_ID_SPI0,
75
+ EXT_GIC_ID_SPI1,
76
+ EXT_GIC_ID_SPI2,
77
+ EXT_GIC_ID_MCT_G1,
78
+ EXT_GIC_ID_USB_HOST,
79
+ EXT_GIC_ID_USB_DEVICE,
80
+ EXT_GIC_ID_MODEMIF,
81
+ EXT_GIC_ID_HSMMC0,
82
+ EXT_GIC_ID_HSMMC1,
83
+ EXT_GIC_ID_HSMMC2,
84
+ EXT_GIC_ID_HSMMC3,
85
+ EXT_GIC_ID_SDMMC,
86
+ EXT_GIC_ID_MIPI_CSI_4LANE,
87
+ EXT_GIC_ID_MIPI_DSI_4LANE,
88
+ EXT_GIC_ID_MIPI_CSI_2LANE,
89
+ EXT_GIC_ID_MIPI_DSI_2LANE,
90
+ EXT_GIC_ID_ONENAND_AUDI,
91
+ EXT_GIC_ID_ROTATOR,
92
+ EXT_GIC_ID_FIMC0,
93
+ EXT_GIC_ID_FIMC1,
94
+ EXT_GIC_ID_FIMC2,
95
+ EXT_GIC_ID_FIMC3,
96
+ EXT_GIC_ID_JPEG,
97
+ EXT_GIC_ID_2D,
98
+ EXT_GIC_ID_PCIe,
99
+ EXT_GIC_ID_MIXER,
100
+ EXT_GIC_ID_HDMI,
101
+ EXT_GIC_ID_HDMI_I2C,
102
+ EXT_GIC_ID_MFC,
103
+ EXT_GIC_ID_TVENC,
104
+};
105
+
36
+
106
+enum ExtInt {
37
+static void cpu_arm_set_rme(Object *obj, bool value, Error **errp)
107
+ EXT_GIC_ID_EXTINT0 = 48,
38
+{
108
+ EXT_GIC_ID_EXTINT1,
39
+ ARMCPU *cpu = ARM_CPU(obj);
109
+ EXT_GIC_ID_EXTINT2,
40
+ uint64_t t;
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
+
41
+
125
+/*
42
+ t = cpu->isar.id_aa64pfr0;
126
+ * External GIC sources which are not from External Interrupt Combiner or
43
+ t = FIELD_DP64(t, ID_AA64PFR0, RME, value);
127
+ * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
44
+ cpu->isar.id_aa64pfr0 = t;
128
+ * which is INTG16 in Internal Interrupt Combiner.
45
+}
129
+ */
130
+
46
+
131
+static const uint32_t
47
+static void cpu_max_set_l0gptsz(Object *obj, Visitor *v, const char *name,
132
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
48
+ void *opaque, Error **errp)
133
+ /* int combiner groups 16-19 */
49
+{
134
+ { }, { }, { }, { },
50
+ ARMCPU *cpu = ARM_CPU(obj);
135
+ /* int combiner group 20 */
51
+ uint32_t value;
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
+
52
+
189
+/*
53
+ if (!visit_type_uint32(v, name, &value, errp)) {
190
+ * Initialize board IRQs.
54
+ return;
191
+ * These IRQs contain splitted Int/External Combiner and External Gic IRQs.
55
+ }
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
+
56
+
198
+ for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
57
+ /* Encode the value for the GPCCR_EL3 field. */
199
+ irq_id = 0;
58
+ switch (value) {
200
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
59
+ case 30:
201
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
60
+ case 34:
202
+ /* MCT_G0 is passed to External GIC */
61
+ case 36:
203
+ irq_id = EXT_GIC_ID_MCT_G0;
62
+ case 39:
204
+ }
63
+ cpu->reset_l0gptsz = value - 30;
205
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
64
+ break;
206
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
65
+ default:
207
+ /* MCT_G1 is passed to External and GIC */
66
+ error_setg(errp, "invalid value for l0gptsz");
208
+ irq_id = EXT_GIC_ID_MCT_G1;
67
+ error_append_hint(errp, "valid values are 30, 34, 36, 39\n");
209
+ }
68
+ break;
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
+ }
69
+ }
230
+}
70
+}
231
+
71
+
232
+/*
72
+static void cpu_max_get_l0gptsz(Object *obj, Visitor *v, const char *name,
233
+ * Get IRQ number from exynos4210 IRQ subsystem stub.
73
+ void *opaque, Error **errp)
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
+{
74
+{
240
+ return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
75
+ ARMCPU *cpu = ARM_CPU(obj);
76
+ uint32_t value = cpu->reset_l0gptsz + 30;
77
+
78
+ visit_type_uint32(v, name, &value, errp);
241
+}
79
+}
242
+
80
+
243
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
81
static Property arm_cpu_lpa2_property =
244
0x09, 0x00, 0x00, 0x00 };
82
DEFINE_PROP_BOOL("lpa2", ARMCPU, prop_lpa2, true);
245
83
246
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
84
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
247
index XXXXXXX..XXXXXXX 100644
85
aarch64_add_sme_properties(obj);
248
--- a/hw/intc/exynos4210_gic.c
86
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
249
+++ b/hw/intc/exynos4210_gic.c
87
cpu_max_set_sve_max_vq, NULL, NULL);
250
@@ -XXX,XX +XXX,XX @@
88
+ object_property_add_bool(obj, "x-rme", cpu_arm_get_rme, cpu_arm_set_rme);
251
#include "hw/arm/exynos4210.h"
89
+ object_property_add(obj, "x-l0gptsz", "uint32", cpu_max_get_l0gptsz,
252
#include "qom/object.h"
90
+ cpu_max_set_l0gptsz, NULL, NULL);
253
91
qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
254
-enum ExtGicId {
92
}
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
93
468
--
94
--
469
2.25.1
95
2.34.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Break out header file to allow embedding of the the TTC.
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
5
Message-id: 20230622143046.1578160-1-richard.henderson@linaro.org
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
[PMM: fixed typo; note experimental status in emulation.rst too]
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Message-id: 20220331222017.2914409-2-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/timer/cadence_ttc.h | 54 ++++++++++++++++++++++++++++++++++
9
docs/system/arm/cpu-features.rst | 23 +++++++++++++++++++++++
13
hw/timer/cadence_ttc.c | 32 ++------------------
10
docs/system/arm/emulation.rst | 1 +
14
2 files changed, 56 insertions(+), 30 deletions(-)
11
2 files changed, 24 insertions(+)
15
create mode 100644 include/hw/timer/cadence_ttc.h
16
12
17
diff --git a/include/hw/timer/cadence_ttc.h b/include/hw/timer/cadence_ttc.h
13
diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
18
new file mode 100644
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX
15
--- a/docs/system/arm/cpu-features.rst
20
--- /dev/null
16
+++ b/docs/system/arm/cpu-features.rst
21
+++ b/include/hw/timer/cadence_ttc.h
17
@@ -XXX,XX +XXX,XX @@ As with ``sve-default-vector-length``, if the default length is larger
22
@@ -XXX,XX +XXX,XX @@
18
than the maximum vector length enabled, the actual vector length will
23
+/*
19
be reduced. If this property is set to ``-1`` then the default vector
24
+ * Xilinx Zynq cadence TTC model
20
length is set to the maximum possible length.
25
+ *
26
+ * Copyright (c) 2011 Xilinx Inc.
27
+ * Copyright (c) 2012 Peter A.G. Crosthwaite (peter.crosthwaite@petalogix.com)
28
+ * Copyright (c) 2012 PetaLogix Pty Ltd.
29
+ * Written By Haibing Ma
30
+ * M. Habib
31
+ *
32
+ * This program is free software; you can redistribute it and/or
33
+ * modify it under the terms of the GNU General Public License
34
+ * as published by the Free Software Foundation; either version
35
+ * 2 of the License, or (at your option) any later version.
36
+ *
37
+ * You should have received a copy of the GNU General Public License along
38
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
39
+ */
40
+#ifndef HW_TIMER_CADENCE_TTC_H
41
+#define HW_TIMER_CADENCE_TTC_H
42
+
21
+
43
+#include "hw/sysbus.h"
22
+RME CPU Properties
44
+#include "qemu/timer.h"
23
+==================
45
+
24
+
46
+typedef struct {
25
+The status of RME support with QEMU is experimental. At this time we
47
+ QEMUTimer *timer;
26
+only support RME within the CPU proper, not within the SMMU or GIC.
48
+ int freq;
27
+The feature is enabled by the CPU property ``x-rme``, with the ``x-``
28
+prefix present as a reminder of the experimental status, and defaults off.
49
+
29
+
50
+ uint32_t reg_clock;
30
+The method for enabling RME will change in some future QEMU release
51
+ uint32_t reg_count;
31
+without notice or backward compatibility.
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
+
32
+
60
+ uint64_t cpu_time;
33
+RME Level 0 GPT Size Property
61
+ unsigned int cpu_time_valid;
34
+-----------------------------
62
+
35
+
63
+ qemu_irq irq;
36
+To aid firmware developers in testing different possible CPU
64
+} CadenceTimerState;
37
+configurations, ``x-l0gptsz=S`` may be used to specify the value
38
+to encode into ``GPCCR_EL3.L0GPTSZ``, a read-only field that
39
+specifies the size of the Level 0 Granule Protection Table.
40
+Legal values for ``S`` are 30, 34, 36, and 39; the default is 30.
65
+
41
+
66
+#define TYPE_CADENCE_TTC "cadence_ttc"
42
+As with ``x-rme``, the ``x-l0gptsz`` property may be renamed or
67
+OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
43
+removed in some future QEMU release.
68
+
44
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
69
+struct CadenceTTCState {
70
+ SysBusDevice parent_obj;
71
+
72
+ MemoryRegion iomem;
73
+ CadenceTimerState timer[3];
74
+};
75
+
76
+#endif
77
diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c
78
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/timer/cadence_ttc.c
46
--- a/docs/system/arm/emulation.rst
80
+++ b/hw/timer/cadence_ttc.c
47
+++ b/docs/system/arm/emulation.rst
81
@@ -XXX,XX +XXX,XX @@
48
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
82
#include "qemu/timer.h"
49
- FEAT_RAS (Reliability, availability, and serviceability)
83
#include "qom/object.h"
50
- FEAT_RASv1p1 (RAS Extension v1.1)
84
51
- FEAT_RDM (Advanced SIMD rounding double multiply accumulate instructions)
85
+#include "hw/timer/cadence_ttc.h"
52
+- FEAT_RME (Realm Management Extension) (NB: support status in QEMU is experimental)
86
+
53
- FEAT_RNG (Random number generator)
87
#ifdef CADENCE_TTC_ERR_DEBUG
54
- FEAT_S2FWB (Stage 2 forced Write-Back)
88
#define DB_PRINT(...) do { \
55
- FEAT_SB (Speculation Barrier)
89
fprintf(stderr, ": %s: ", __func__); \
90
@@ -XXX,XX +XXX,XX @@
91
#define CLOCK_CTRL_PS_EN 0x00000001
92
#define CLOCK_CTRL_PS_V 0x0000001e
93
94
-typedef struct {
95
- QEMUTimer *timer;
96
- int freq;
97
-
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
--
56
--
128
2.25.1
57
2.34.1
58
59
diff view generated by jsdifflib
Deleted patch
1
The Exynos4210 SoC device currently uses a custom device
2
"exynos4210.irq_gate" to model the OR gate that feeds each CPU's IRQ
3
line. We have a standard TYPE_OR_IRQ device for this now, so use
4
that instead.
5
1
6
(This is a migration compatibility break, but that is OK for this
7
machine type.)
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-2-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 1 +
14
hw/arm/exynos4210.c | 31 ++++++++++++++++---------------
15
2 files changed, 17 insertions(+), 15 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 @@ struct Exynos4210State {
22
MemoryRegion bootreg_mem;
23
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
24
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
25
+ qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
26
};
27
28
#define TYPE_EXYNOS4210_SOC "exynos4210"
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
32
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
34
{
35
Exynos4210State *s = EXYNOS4210_SOC(socdev);
36
MemoryRegion *system_mem = get_system_memory();
37
- qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
38
SysBusDevice *busdev;
39
DeviceState *dev, *uart[4], *pl330[3];
40
int i, n;
41
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
42
43
/* IRQ Gate */
44
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
45
- dev = qdev_new("exynos4210.irq_gate");
46
- qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
47
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
48
- /* Get IRQ Gate input in gate_irq */
49
- for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
50
- gate_irq[i][n] = qdev_get_gpio_in(dev, n);
51
- }
52
- busdev = SYS_BUS_DEVICE(dev);
53
-
54
- /* Connect IRQ Gate output to CPU's IRQ line */
55
- sysbus_connect_irq(busdev, 0,
56
- qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
57
+ DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
58
+ object_property_set_int(OBJECT(orgate), "num-lines",
59
+ EXYNOS4210_IRQ_GATE_NINPUTS,
60
+ &error_abort);
61
+ qdev_realize(orgate, NULL, &error_abort);
62
+ qdev_connect_gpio_out(orgate, 0,
63
+ qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
64
}
65
66
/* Private memory region and Internal GIC */
67
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
68
sysbus_realize_and_unref(busdev, &error_fatal);
69
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
70
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
71
- sysbus_connect_irq(busdev, n, gate_irq[n][0]);
72
+ sysbus_connect_irq(busdev, n,
73
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
74
}
75
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
76
s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
77
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
78
/* Map Distributer interface */
79
sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
80
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
81
- sysbus_connect_irq(busdev, n, gate_irq[n][1]);
82
+ sysbus_connect_irq(busdev, n,
83
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
84
}
85
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
86
s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
87
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
88
object_initialize_child(obj, name, orgate, TYPE_OR_IRQ);
89
g_free(name);
90
}
91
+
92
+ for (i = 0; i < ARRAY_SIZE(s->cpu_irq_orgate); i++) {
93
+ g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
94
+ object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
95
+ }
96
}
97
98
static void exynos4210_class_init(ObjectClass *klass, void *data)
99
--
100
2.25.1
diff view generated by jsdifflib
1
In exynos4210_init_board_irqs(), use the TYPE_SPLIT_IRQ device
1
We use __builtin_subcll() to do a 64-bit subtract with borrow-in and
2
instead of qemu_irq_split().
2
borrow-out when the host compiler supports it. Unfortunately some
3
versions of Apple Clang have a bug in their implementation of this
4
intrinsic which means it returns the wrong value. The effect is that
5
a QEMU built with the affected compiler will hang when emulating x86
6
or m68k float80 division.
3
7
8
The upstream LLVM issue is:
9
https://github.com/llvm/llvm-project/issues/55253
10
11
The commit that introduced the bug apparently never made it into an
12
upstream LLVM release without the subsequent fix
13
https://github.com/llvm/llvm-project/commit/fffb6e6afdbaba563189c1f715058ed401fbc88d
14
but unfortunately it did make it into Apple Clang 14.0, as shipped
15
in Xcode 14.3 (14.2 is reported to be OK). The Apple bug number is
16
FB12210478.
17
18
Add ifdefs to avoid use of __builtin_subcll() on Apple Clang version
19
14 or greater. There is not currently a version of Apple Clang which
20
has the bug fix -- when one appears we should be able to add an upper
21
bound to the ifdef condition so we can start using the builtin again.
22
We make the lower bound a conservative "any Apple clang with major
23
version 14 or greater" because the consequences of incorrectly
24
disabling the builtin when it would work are pretty small and the
25
consequences of not disabling it when we should are pretty bad.
26
27
Many thanks to those users who both reported this bug and also
28
did a lot of work in identifying the root cause; in particular
29
to Daniel Bertalan and osy.
30
31
Cc: qemu-stable@nongnu.org
32
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1631
33
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1659
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
35
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20220404154658.565020-13-peter.maydell@linaro.org
36
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
37
Tested-by: Daniel Bertalan <dani@danielbertalan.dev>
38
Tested-by: Tested-By: Solra Bizna <solra@bizna.name>
39
Message-id: 20230622130823.1631719-1-peter.maydell@linaro.org
7
---
40
---
8
include/hw/arm/exynos4210.h | 9 ++++++++
41
include/qemu/compiler.h | 13 +++++++++++++
9
hw/arm/exynos4210.c | 41 +++++++++++++++++++++++++++++--------
42
include/qemu/host-utils.h | 2 +-
10
2 files changed, 42 insertions(+), 8 deletions(-)
43
2 files changed, 14 insertions(+), 1 deletion(-)
11
44
12
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
45
diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
13
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/exynos4210.h
47
--- a/include/qemu/compiler.h
15
+++ b/include/hw/arm/exynos4210.h
48
+++ b/include/qemu/compiler.h
16
@@ -XXX,XX +XXX,XX @@
49
@@ -XXX,XX +XXX,XX @@
17
#include "hw/sysbus.h"
50
#define QEMU_DISABLE_CFI
18
#include "hw/cpu/a9mpcore.h"
51
#endif
19
#include "hw/intc/exynos4210_gic.h"
20
+#include "hw/core/split-irq.h"
21
#include "target/arm/cpu-qom.h"
22
#include "qom/object.h"
23
24
@@ -XXX,XX +XXX,XX @@
25
26
#define EXYNOS4210_NUM_DMA 3
27
52
28
+/*
53
+/*
29
+ * We need one splitter for every external combiner input, plus
54
+ * Apple clang version 14 has a bug in its __builtin_subcll(); define
30
+ * one for every non-zero entry in combiner_grp_to_gic_id[].
55
+ * BUILTIN_SUBCLL_BROKEN for the offending versions so we can avoid it.
31
+ * We'll assert in exynos4210_init_board_irqs() if this is wrong.
56
+ * When a version of Apple clang which has this bug fixed is released
57
+ * we can add an upper bound to this check.
58
+ * See https://gitlab.com/qemu-project/qemu/-/issues/1631
59
+ * and https://gitlab.com/qemu-project/qemu/-/issues/1659 for details.
60
+ * The bug never made it into any upstream LLVM releases, only Apple ones.
32
+ */
61
+ */
33
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
62
+#if defined(__apple_build_version__) && __clang_major__ >= 14
63
+#define BUILTIN_SUBCLL_BROKEN
64
+#endif
34
+
65
+
35
typedef struct Exynos4210Irq {
66
#endif /* COMPILER_H */
36
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
67
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
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
68
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/exynos4210.c
69
--- a/include/qemu/host-utils.h
49
+++ b/hw/arm/exynos4210.c
70
+++ b/include/qemu/host-utils.h
50
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
71
@@ -XXX,XX +XXX,XX @@ static inline uint64_t uadd64_carry(uint64_t x, uint64_t y, bool *pcarry)
51
uint32_t grp, bit, irq_id, n;
72
*/
52
Exynos4210Irq *is = &s->irqs;
73
static inline uint64_t usub64_borrow(uint64_t x, uint64_t y, bool *pborrow)
53
DeviceState *extgicdev = DEVICE(&s->ext_gic);
74
{
54
+ int splitcount = 0;
75
-#if __has_builtin(__builtin_subcll)
55
+ DeviceState *splitter;
76
+#if __has_builtin(__builtin_subcll) && !defined(BUILTIN_SUBCLL_BROKEN)
56
77
unsigned long long b = *pborrow;
57
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
78
x = __builtin_subcll(x, y, b, &b);
58
irq_id = 0;
79
*pborrow = b & 1;
59
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
60
/* MCT_G1 is passed to External and GIC */
61
irq_id = EXT_GIC_ID_MCT_G1;
62
}
63
+
64
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
65
+ splitter = DEVICE(&s->splitter[splitcount]);
66
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
67
+ qdev_realize(splitter, NULL, &error_abort);
68
+ splitcount++;
69
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
70
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
71
if (irq_id) {
72
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
73
- qdev_get_gpio_in(extgicdev,
74
- irq_id - 32));
75
+ qdev_connect_gpio_out(splitter, 1,
76
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
77
} else {
78
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
79
- is->ext_combiner_irq[n]);
80
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
81
}
82
}
83
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
84
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
85
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
86
87
if (irq_id) {
88
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
89
- qdev_get_gpio_in(extgicdev,
90
- irq_id - 32));
91
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
92
+ splitter = DEVICE(&s->splitter[splitcount]);
93
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
94
+ qdev_realize(splitter, NULL, &error_abort);
95
+ splitcount++;
96
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
97
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
98
+ qdev_connect_gpio_out(splitter, 1,
99
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
100
}
101
}
102
+ /*
103
+ * We check this here to avoid a more obscure assert later when
104
+ * qdev_assert_realized_properly() checks that we realized every
105
+ * child object we initialized.
106
+ */
107
+ assert(splitcount == EXYNOS4210_NUM_SPLITTERS);
108
}
109
110
/*
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
112
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
113
}
114
115
+ for (i = 0; i < ARRAY_SIZE(s->splitter); i++) {
116
+ g_autofree char *name = g_strdup_printf("irq-splitter%d", i);
117
+ object_initialize_child(obj, name, &s->splitter[i], TYPE_SPLIT_IRQ);
118
+ }
119
+
120
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
121
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
122
}
123
--
80
--
124
2.25.1
81
2.34.1
82
83
diff view generated by jsdifflib
1
Now we have removed the only use of TYPE_EXYNOS4210_IRQ_GATE we can
1
From: Richard Henderson <richard.henderson@linaro.org>
2
delete the device entirely.
3
2
3
One cannot test for feature aa32_simd_r32 without first
4
testing if AArch32 mode is supported at all. This leads to
5
6
qemu-system-aarch64: ARM CPUs must have both VFP-D32 and Neon or neither
7
8
for Apple M1 cpus.
9
10
We already have a check for ARMv8-A never setting vfp-d32 true,
11
so restructure the code so that AArch64 avoids the test entirely.
12
13
Reported-by: Mads Ynddal <mads@ynddal.dk>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
Tested-by: Mads Ynddal <m.ynddal@samsung.com>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
18
Reviewed-by: Cédric Le Goater <clg@kaod.org>
19
Reviewed-by: Mads Ynddal <m.ynddal@samsung.com>
20
Message-id: 20230619140216.402530-1-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
6
Message-id: 20220404154658.565020-3-peter.maydell@linaro.org
7
---
22
---
8
hw/intc/exynos4210_gic.c | 107 ---------------------------------------
23
target/arm/cpu.c | 28 +++++++++++++++-------------
9
1 file changed, 107 deletions(-)
24
1 file changed, 15 insertions(+), 13 deletions(-)
10
25
11
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
26
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
12
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/intc/exynos4210_gic.c
28
--- a/target/arm/cpu.c
14
+++ b/hw/intc/exynos4210_gic.c
29
+++ b/target/arm/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_register_types(void)
30
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
16
}
31
* KVM does not currently allow us to lie to the guest about its
17
32
* ID/feature registers, so the guest always sees what the host has.
18
type_init(exynos4210_gic_register_types)
33
*/
19
-
34
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
20
-/* IRQ OR Gate struct.
35
- ? cpu_isar_feature(aa64_fp_simd, cpu)
21
- *
36
- : cpu_isar_feature(aa32_vfp, cpu)) {
22
- * This device models an OR gate. There are n_in input qdev gpio lines and one
37
- cpu->has_vfp = true;
23
- * output sysbus IRQ line. The output IRQ level is formed as OR between all
38
- if (!kvm_enabled()) {
24
- * gpio inputs.
39
- qdev_property_add_static(DEVICE(obj), &arm_cpu_has_vfp_property);
25
- */
40
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
26
-
41
+ if (cpu_isar_feature(aa64_fp_simd, cpu)) {
27
-#define TYPE_EXYNOS4210_IRQ_GATE "exynos4210.irq_gate"
42
+ cpu->has_vfp = true;
28
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210IRQGateState, EXYNOS4210_IRQ_GATE)
43
+ cpu->has_vfp_d32 = true;
29
-
44
+ if (tcg_enabled() || qtest_enabled()) {
30
-struct Exynos4210IRQGateState {
45
+ qdev_property_add_static(DEVICE(obj),
31
- SysBusDevice parent_obj;
46
+ &arm_cpu_has_vfp_property);
32
-
47
+ }
33
- uint32_t n_in; /* inputs amount */
48
}
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
- }
49
- }
69
-
50
-
70
- qemu_irq_lower(s->out);
51
- if (cpu->has_vfp && cpu_isar_feature(aa32_simd_r32, cpu)) {
71
-}
52
- cpu->has_vfp_d32 = true;
72
-
53
- if (!kvm_enabled()) {
73
-static void exynos4210_irq_gate_reset(DeviceState *d)
54
+ } else if (cpu_isar_feature(aa32_vfp, cpu)) {
74
-{
55
+ cpu->has_vfp = true;
75
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(d);
56
+ if (cpu_isar_feature(aa32_simd_r32, cpu)) {
76
-
57
+ cpu->has_vfp_d32 = true;
77
- memset(s->level, 0, s->n_in * sizeof(*s->level));
58
/*
78
-}
59
* The permitted values of the SIMDReg bits [3:0] on
79
-
60
* Armv8-A are either 0b0000 and 0b0010. On such CPUs,
80
-/*
61
* make sure that has_vfp_d32 can not be set to false.
81
- * IRQ Gate initialization.
62
*/
82
- */
63
- if (!(arm_feature(&cpu->env, ARM_FEATURE_V8) &&
83
-static void exynos4210_irq_gate_init(Object *obj)
64
- !arm_feature(&cpu->env, ARM_FEATURE_M))) {
84
-{
65
+ if ((tcg_enabled() || qtest_enabled())
85
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(obj);
66
+ && !(arm_feature(&cpu->env, ARM_FEATURE_V8)
86
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
67
+ && !arm_feature(&cpu->env, ARM_FEATURE_M))) {
87
-
68
qdev_property_add_static(DEVICE(obj),
88
- sysbus_init_irq(sbd, &s->out);
69
&arm_cpu_has_vfp_d32_property);
89
-}
70
}
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
--
71
--
127
2.25.1
72
2.34.1
73
74
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
1
The function exynos4210_combiner_get_gpioin() currently lives in
1
From: Shashi Mallela <shashi.mallela@linaro.org>
2
exynos4210_combiner.c, but it isn't really part of the combiner
3
device itself -- it is a function that implements the wiring up of
4
some interrupt sources to multiple combiner inputs. Move it to live
5
with the other SoC-level code in exynos4210.c, along with a few
6
macros previously defined in exynos4210.h which are now used only
7
in exynos4210.c.
8
2
3
Create ITS as part of SBSA platform GIC initialization.
4
5
GIC ITS information is in DeviceTree so TF-A can pass it to EDK2.
6
7
Bumping platform version to 0.2 as this is important hardware change.
8
9
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
10
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
11
Message-id: 20230619170913.517373-2-marcin.juszkiewicz@linaro.org
12
Co-authored-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
13
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
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
---
16
---
13
include/hw/arm/exynos4210.h | 11 -----
17
docs/system/arm/sbsa.rst | 14 ++++++++++++++
14
hw/arm/exynos4210.c | 82 +++++++++++++++++++++++++++++++++++
18
hw/arm/sbsa-ref.c | 33 ++++++++++++++++++++++++++++++---
15
hw/intc/exynos4210_combiner.c | 77 --------------------------------
19
2 files changed, 44 insertions(+), 3 deletions(-)
16
3 files changed, 82 insertions(+), 88 deletions(-)
17
20
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
21
diff --git a/docs/system/arm/sbsa.rst b/docs/system/arm/sbsa.rst
19
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/exynos4210.h
23
--- a/docs/system/arm/sbsa.rst
21
+++ b/include/hw/arm/exynos4210.h
24
+++ b/docs/system/arm/sbsa.rst
22
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ to be a complete compliant DT. It currently reports:
23
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
26
- platform version
24
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
27
- GIC addresses
25
28
26
-#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp)*8 + (bit))
29
+Platform version
27
-#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
30
+''''''''''''''''
28
-#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
31
+
29
- ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
32
The platform version is only for informing platform firmware about
30
-
33
what kind of ``sbsa-ref`` board it is running on. It is neither
31
/* IRQs number for external and internal GIC */
34
a QEMU versioned machine type nor a reflection of the level of the
32
#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
35
@@ -XXX,XX +XXX,XX @@ SBSA/SystemReady SR support provided.
33
#define EXYNOS4210_INT_GIC_NIRQ 64
36
The ``machine-version-major`` value is updated when changes breaking
34
@@ -XXX,XX +XXX,XX @@ void exynos4210_write_secondary(ARMCPU *cpu,
37
fw compatibility are introduced. The ``machine-version-minor`` value
35
* bit - bit number inside group */
38
is updated when features are added that don't break fw compatibility.
36
uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit);
39
+
37
40
+Platform version changes:
38
-/*
41
+
39
- * Get Combiner input GPIO into irqs structure
42
+0.0
40
- */
43
+ Devicetree holds information about CPUs, memory and platform version.
41
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
44
+
42
- int ext);
45
+0.1
43
-
46
+ GIC information is present in devicetree.
44
/*
47
+
45
* exynos4210 UART
48
+0.2
46
*/
49
+ GIC ITS information is present in devicetree.
47
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
50
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
48
index XXXXXXX..XXXXXXX 100644
51
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/exynos4210.c
52
--- a/hw/arm/sbsa-ref.c
50
+++ b/hw/arm/exynos4210.c
53
+++ b/hw/arm/sbsa-ref.c
51
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
54
@@ -XXX,XX +XXX,XX @@ enum {
52
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
55
SBSA_CPUPERIPHS,
53
};
56
SBSA_GIC_DIST,
54
57
SBSA_GIC_REDIST,
55
+#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp) * 8 + (bit))
58
+ SBSA_GIC_ITS,
56
+#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
59
SBSA_SECURE_EC,
57
+#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
60
SBSA_GWDT_WS0,
58
+ ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
61
SBSA_GWDT_REFRESH,
62
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry sbsa_ref_memmap[] = {
63
[SBSA_CPUPERIPHS] = { 0x40000000, 0x00040000 },
64
[SBSA_GIC_DIST] = { 0x40060000, 0x00010000 },
65
[SBSA_GIC_REDIST] = { 0x40080000, 0x04000000 },
66
+ [SBSA_GIC_ITS] = { 0x44081000, 0x00020000 },
67
[SBSA_SECURE_EC] = { 0x50000000, 0x00001000 },
68
[SBSA_GWDT_REFRESH] = { 0x50010000, 0x00001000 },
69
[SBSA_GWDT_CONTROL] = { 0x50011000, 0x00001000 },
70
@@ -XXX,XX +XXX,XX @@ static void sbsa_fdt_add_gic_node(SBSAMachineState *sms)
71
2, sbsa_ref_memmap[SBSA_GIC_REDIST].base,
72
2, sbsa_ref_memmap[SBSA_GIC_REDIST].size);
73
74
+ nodename = g_strdup_printf("/intc/its");
75
+ qemu_fdt_add_subnode(sms->fdt, nodename);
76
+ qemu_fdt_setprop_sized_cells(sms->fdt, nodename, "reg",
77
+ 2, sbsa_ref_memmap[SBSA_GIC_ITS].base,
78
+ 2, sbsa_ref_memmap[SBSA_GIC_ITS].size);
79
+
80
g_free(nodename);
81
}
59
+
82
+
60
/*
83
/*
61
* Initialize board IRQs.
84
* Firmware on this machine only uses ACPI table to load OS, these limited
62
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
85
* device tree nodes are just to let firmware know the info which varies from
63
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
86
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SBSAMachineState *sms)
64
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
87
* fw compatibility.
88
*/
89
qemu_fdt_setprop_cell(fdt, "/", "machine-version-major", 0);
90
- qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 1);
91
+ qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 2);
92
93
if (ms->numa_state->have_numa_distance) {
94
int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
95
@@ -XXX,XX +XXX,XX @@ static void create_secure_ram(SBSAMachineState *sms,
96
memory_region_add_subregion(secure_sysmem, base, secram);
65
}
97
}
66
98
67
+/*
99
-static void create_gic(SBSAMachineState *sms)
68
+ * Get Combiner input GPIO into irqs structure
100
+static void create_its(SBSAMachineState *sms)
69
+ */
70
+static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
71
+ DeviceState *dev, int ext)
72
+{
101
+{
73
+ int n;
102
+ const char *itsclass = its_class_name();
74
+ int bit;
103
+ DeviceState *dev;
75
+ int max;
76
+ qemu_irq *irq;
77
+
104
+
78
+ max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
105
+ dev = qdev_new(itsclass);
79
+ EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
80
+ irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
81
+
106
+
82
+ /*
107
+ object_property_set_link(OBJECT(dev), "parent-gicv3", OBJECT(sms->gic),
83
+ * Some IRQs of Int/External Combiner are going to two Combiners groups,
108
+ &error_abort);
84
+ * so let split them.
109
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
85
+ */
110
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, sbsa_ref_memmap[SBSA_GIC_ITS].base);
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
+}
111
+}
143
+
112
+
144
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
113
+static void create_gic(SBSAMachineState *sms, MemoryRegion *mem)
145
0x09, 0x00, 0x00, 0x00 };
114
{
146
115
unsigned int smp_cpus = MACHINE(sms)->smp.cpus;
147
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
116
SysBusDevice *gicbusdev;
148
index XXXXXXX..XXXXXXX 100644
117
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms)
149
--- a/hw/intc/exynos4210_combiner.c
118
qdev_prop_set_uint32(sms->gic, "len-redist-region-count", 1);
150
+++ b/hw/intc/exynos4210_combiner.c
119
qdev_prop_set_uint32(sms->gic, "redist-region-count[0]", redist0_count);
151
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_exynos4210_combiner = {
120
121
+ object_property_set_link(OBJECT(sms->gic), "sysmem",
122
+ OBJECT(mem), &error_fatal);
123
+ qdev_prop_set_bit(sms->gic, "has-lpi", true);
124
+
125
gicbusdev = SYS_BUS_DEVICE(sms->gic);
126
sysbus_realize_and_unref(gicbusdev, &error_fatal);
127
sysbus_mmio_map(gicbusdev, 0, sbsa_ref_memmap[SBSA_GIC_DIST].base);
128
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms)
129
sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
130
qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
152
}
131
}
153
};
132
+ create_its(sms);
154
133
}
155
-/*
134
156
- * Get Combiner input GPIO into irqs structure
135
static void create_uart(const SBSAMachineState *sms, int uart,
157
- */
136
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
158
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
137
159
- int ext)
138
create_secure_ram(sms, secure_sysmem);
160
-{
139
161
- int n;
140
- create_gic(sms);
162
- int bit;
141
+ create_gic(sms, sysmem);
163
- int max;
142
164
- qemu_irq *irq;
143
create_uart(sms, SBSA_UART, sysmem, serial_hd(0));
165
-
144
create_uart(sms, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
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
--
145
--
236
2.25.1
146
2.34.1
diff view generated by jsdifflib
1
From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Describe that the gic-version influences the maximum number of CPUs.
3
Brown bag time: store instead of load results in uninitialized temp.
4
4
5
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
5
6
Message-id: 20220413231456.35811-1-heinrich.schuchardt@canonical.com
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1704
7
[PMM: minor punctuation tweaks]
7
Reported-by: Mark Rutland <mark.rutland@arm.com>
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20230620134659.817559-1-richard.henderson@linaro.org
11
Fixes: e6dd5e782be ("target/arm: Use tcg_gen_qemu_{ld, st}_i128 in gen_sve_{ld, st}r")
12
Tested-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
16
---
11
docs/system/arm/virt.rst | 4 ++--
17
target/arm/tcg/translate-sve.c | 2 +-
12
1 file changed, 2 insertions(+), 2 deletions(-)
18
1 file changed, 1 insertion(+), 1 deletion(-)
13
19
14
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
20
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/virt.rst
22
--- a/target/arm/tcg/translate-sve.c
17
+++ b/docs/system/arm/virt.rst
23
+++ b/target/arm/tcg/translate-sve.c
18
@@ -XXX,XX +XXX,XX @@ gic-version
24
@@ -XXX,XX +XXX,XX @@ void gen_sve_str(DisasContext *s, TCGv_ptr base, int vofs,
19
Valid values are:
25
/* Predicate register stores can be any multiple of 2. */
20
26
if (len_remain >= 8) {
21
``2``
27
t0 = tcg_temp_new_i64();
22
- GICv2
28
- tcg_gen_st_i64(t0, base, vofs + len_align);
23
+ GICv2. Note that this limits the number of CPUs to 8.
29
+ tcg_gen_ld_i64(t0, base, vofs + len_align);
24
``3``
30
tcg_gen_qemu_st_i64(t0, clean_addr, midx, MO_LEUQ | MO_ATOM_NONE);
25
- GICv3
31
len_remain -= 8;
26
+ GICv3. This allows up to 512 CPUs.
32
len_align += 8;
27
``host``
28
Use the same GIC version the host provides, when using KVM
29
``max``
30
--
33
--
31
2.25.1
34
2.34.1
35
36
diff view generated by jsdifflib
1
Fix a missing set of spaces around '-' in the definition of
1
The xkb official name for the Arabic keyboard layout is 'ara'.
2
combiner_grp_to_gic_id[]. We're about to move this code, so
2
However xkb has for at least the past 15 years also permitted it to
3
fix the style issue first to keep checkpatch happy with the
3
be named via the legacy synonym 'ar'. In xkeyboard-config 2.39 this
4
code-motion patch.
4
synoynm was removed, which breaks compilation of QEMU:
5
5
6
FAILED: pc-bios/keymaps/ar
7
/home/fred/qemu-git/src/qemu/build-full/qemu-keymap -f pc-bios/keymaps/ar -l ar
8
xkbcommon: ERROR: Couldn't find file "symbols/ar" in include paths
9
xkbcommon: ERROR: 1 include paths searched:
10
xkbcommon: ERROR:     /usr/share/X11/xkb
11
xkbcommon: ERROR: 3 include paths could not be added:
12
xkbcommon: ERROR:     /home/fred/.config/xkb
13
xkbcommon: ERROR:     /home/fred/.xkb
14
xkbcommon: ERROR:     /etc/xkb
15
xkbcommon: ERROR: Abandoning symbols file "(unnamed)"
16
xkbcommon: ERROR: Failed to compile xkb_symbols
17
xkbcommon: ERROR: Failed to compile keymap
18
19
The upstream xkeyboard-config change removing the compat
20
mapping is:
21
https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/commit/470ad2cd8fea84d7210377161d86b31999bb5ea6
22
23
Make QEMU always ask for the 'ara' xkb layout, which should work on
24
both older and newer xkeyboard-config. We leave the QEMU name for
25
this keyboard layout as 'ar'; it is not the only one where our name
26
for it deviates from the xkb standard name.
27
28
Cc: qemu-stable@nongnu.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220404154658.565020-7-peter.maydell@linaro.org
31
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
32
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
33
Message-id: 20230620162024.1132013-1-peter.maydell@linaro.org
34
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1709
9
---
35
---
10
hw/intc/exynos4210_gic.c | 2 +-
36
pc-bios/keymaps/meson.build | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
37
1 file changed, 1 insertion(+), 1 deletion(-)
12
38
13
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
39
diff --git a/pc-bios/keymaps/meson.build b/pc-bios/keymaps/meson.build
14
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/intc/exynos4210_gic.c
41
--- a/pc-bios/keymaps/meson.build
16
+++ b/hw/intc/exynos4210_gic.c
42
+++ b/pc-bios/keymaps/meson.build
17
@@ -XXX,XX +XXX,XX @@ enum ExtInt {
43
@@ -XXX,XX +XXX,XX @@
18
*/
44
keymaps = {
19
45
- 'ar': '-l ar',
20
static const uint32_t
46
+ 'ar': '-l ara',
21
-combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
47
'bepo': '-l fr -v dvorak',
22
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
48
'cz': '-l cz',
23
/* int combiner groups 16-19 */
49
'da': '-l dk',
24
{ }, { }, { }, { },
25
/* int combiner group 20 */
26
--
50
--
27
2.25.1
51
2.34.1
52
53
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
The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0
2
and EXT_GIC_ID_MCT_G1 multiple times. This means that we will
3
connect multiple IRQs up to the same external GIC input, which
4
is not permitted. We do the same thing in the code in
5
exynos4210_init_board_irqs() because the conditionals selecting
6
an irq_id in the first loop match multiple interrupt IDs.
7
1
8
Overall we do this for interrupt IDs
9
(1, 4), (12, 4), (35, 4), (51, 4), (53, 4) for EXT_GIC_ID_MCT_G0
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
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20220404154658.565020-16-peter.maydell@linaro.org
28
---
29
include/hw/arm/exynos4210.h | 2 +-
30
hw/arm/exynos4210.c | 12 +++++-------
31
2 files changed, 6 insertions(+), 8 deletions(-)
32
33
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/include/hw/arm/exynos4210.h
36
+++ b/include/hw/arm/exynos4210.h
37
@@ -XXX,XX +XXX,XX @@
38
* one for every non-zero entry in combiner_grp_to_gic_id[].
39
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
40
*/
41
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
42
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
43
44
typedef struct Exynos4210Irq {
45
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/exynos4210.c
49
+++ b/hw/arm/exynos4210.c
50
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
51
/* int combiner group 34 */
52
{ EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
53
/* int combiner group 35 */
54
- { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
55
+ { 0, 0, 0, EXT_GIC_ID_MCT_L1 },
56
/* int combiner group 36 */
57
{ EXT_GIC_ID_MIXER },
58
/* int combiner group 37 */
59
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
60
/* groups 38-50 */
61
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
62
/* int combiner group 51 */
63
- { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
64
+ { EXT_GIC_ID_MCT_L0 },
65
/* group 52 */
66
{ },
67
/* int combiner group 53 */
68
- { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
69
+ { EXT_GIC_ID_WDT },
70
/* groups 54-63 */
71
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
72
};
73
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
74
75
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
76
irq_id = 0;
77
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
78
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
79
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4)) {
80
/* MCT_G0 is passed to External GIC */
81
irq_id = EXT_GIC_ID_MCT_G0;
82
}
83
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
84
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
85
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5)) {
86
/* MCT_G1 is passed to External and GIC */
87
irq_id = EXT_GIC_ID_MCT_G1;
88
}
89
--
90
2.25.1
diff view generated by jsdifflib