1
First arm pullreq for 7.1. The bulk of this is the qemu_split_irq
1
Hi; this is the latest target-arm queue; most of this is a refactoring
2
removal.
2
patchset from RTH for the arm page-table-walk emulation.
3
4
I have enough stuff in my to-review queue that I expect to do another
5
pullreq early next week, but 31 patches is enough to not hang on to.
6
3
7
thanks
4
thanks
8
-- PMM
5
-- PMM
9
6
10
The following changes since commit 9c125d17e9402c232c46610802e5931b3639d77b:
7
The following changes since commit f1d33f55c47dfdaf8daacd618588ad3ae4c452d1:
11
8
12
Merge tag 'pull-tcg-20220420' of https://gitlab.com/rth7680/qemu into staging (2022-04-20 16:43:11 -0700)
9
Merge tag 'pull-testing-gdbstub-plugins-gitdm-061022-3' of https://github.com/stsquad/qemu into staging (2022-10-06 07:11:56 -0400)
13
10
14
are available in the Git repository at:
11
are available in the Git repository at:
15
12
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220421
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20221010
17
14
18
for you to fetch changes up to 5b415dd61bdbf61fb4be0e9f1a7172b8bce682c6:
15
for you to fetch changes up to 915f62844cf62e428c7c178149b5ff1cbe129b07:
19
16
20
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs (2022-04-21 11:37:05 +0100)
17
docs/system/arm/emulation.rst: Report FEAT_GTG support (2022-10-10 14:52:25 +0100)
21
18
22
----------------------------------------------------------------
19
----------------------------------------------------------------
23
target-arm queue:
20
target-arm queue:
24
* hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
21
* Retry KVM_CREATE_VM call if it fails EINTR
25
* versal: Add the Cortex-R5s in the Real-Time Processing Unit (RPU) subsystem
22
* allow setting SCR_EL3.EnTP2 when FEAT_SME is implemented
26
* versal: model enough of the Clock/Reset Low-power domain (CRL) to allow control of the Cortex-R5s
23
* docs/nuvoton: Update URL for images
27
* xlnx-zynqmp: Connect 4 TTC timers
24
* refactoring of page table walk code
28
* exynos4210: Refactor GIC/combiner code to stop using qemu_split_irq
25
* hw/arm/boot: set CPTR_EL3.ESM and SCR_EL3.EnTP2 when booting Linux with EL3
29
* realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
26
* Don't allow guest to use unimplemented granule sizes
30
* stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
27
* Report FEAT_GTG support
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
28
35
----------------------------------------------------------------
29
----------------------------------------------------------------
36
Edgar E. Iglesias (6):
30
Jerome Forissier (2):
37
timer: cadence_ttc: Break out header file to allow embedding
31
target/arm: allow setting SCR_EL3.EnTP2 when FEAT_SME is implemented
38
hw/arm/xlnx-zynqmp: Connect 4 TTC timers
32
hw/arm/boot: set CPTR_EL3.ESM and SCR_EL3.EnTP2 when booting Linux with EL3
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
33
44
Hao Wu (2):
34
Joel Stanley (1):
45
hw/misc: Add PWRON STRAP bit fields in GCR module
35
docs/nuvoton: Update URL for images
46
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs
47
36
48
Heinrich Schuchardt (1):
37
Peter Maydell (4):
49
hw/arm/virt: impact of gic-version on max CPUs
38
target/arm/kvm: Retry KVM_CREATE_VM call if it fails EINTR
39
target/arm: Don't allow guest to use unimplemented granule sizes
40
target/arm: Use ARMGranuleSize in ARMVAParameters
41
docs/system/arm/emulation.rst: Report FEAT_GTG support
50
42
51
Peter Maydell (19):
43
Richard Henderson (21):
52
hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
44
target/arm: Split s2walk_secure from ipa_secure in get_phys_addr
53
hw/arm/exynos4210: Use TYPE_OR_IRQ instead of custom OR-gate device
45
target/arm: Make the final stage1+2 write to secure be unconditional
54
hw/intc/exynos4210_gic: Remove unused TYPE_EXYNOS4210_IRQ_GATE
46
target/arm: Add is_secure parameter to get_phys_addr_lpae
55
hw/arm/exynos4210: Put a9mpcore device into state struct
47
target/arm: Fix S2 disabled check in S1_ptw_translate
56
hw/arm/exynos4210: Drop int_gic_irq[] from Exynos4210Irq struct
48
target/arm: Add is_secure parameter to regime_translation_disabled
57
hw/arm/exynos4210: Coalesce board_irqs and irq_table
49
target/arm: Split out get_phys_addr_with_secure
58
hw/arm/exynos4210: Fix code style nit in combiner_grp_to_gic_id[]
50
target/arm: Add is_secure parameter to v7m_read_half_insn
59
hw/arm/exynos4210: Move exynos4210_init_board_irqs() into exynos4210.c
51
target/arm: Add TBFLAG_M32.SECURE
60
hw/arm/exynos4210: Put external GIC into state struct
52
target/arm: Merge regime_is_secure into get_phys_addr
61
hw/arm/exynos4210: Drop ext_gic_irq[] from Exynos4210Irq struct
53
target/arm: Add is_secure parameter to do_ats_write
62
hw/arm/exynos4210: Move exynos4210_combiner_get_gpioin() into exynos4210.c
54
target/arm: Fold secure and non-secure a-profile mmu indexes
63
hw/arm/exynos4210: Delete unused macro definitions
55
target/arm: Reorg regime_translation_disabled
64
hw/arm/exynos4210: Use TYPE_SPLIT_IRQ in exynos4210_init_board_irqs()
56
target/arm: Drop secure check for HCR.TGE vs SCTLR_EL1.M
65
hw/arm/exynos4210: Fill in irq_table[] for internal-combiner-only IRQ lines
57
target/arm: Introduce arm_hcr_el2_eff_secstate
66
hw/arm/exynos4210: Connect MCT_G0 and MCT_G1 to both combiners
58
target/arm: Hoist read of *is_secure in S1_ptw_translate
67
hw/arm/exynos4210: Don't connect multiple lines to external GIC inputs
59
target/arm: Remove env argument from combined_attrs_fwb
68
hw/arm/exynos4210: Fold combiner splits into exynos4210_init_board_irqs()
60
target/arm: Pass HCR to attribute subroutines.
69
hw/arm/exynos4210: Put combiners into state struct
61
target/arm: Fix ATS12NSO* from S PL1
70
hw/arm/exynos4210: Drop Exynos4210Irq struct
62
target/arm: Split out get_phys_addr_disabled
63
target/arm: Fix cacheattr in get_phys_addr_disabled
64
target/arm: Use tlb_set_page_full
71
65
72
Zongyuan Li (3):
66
docs/system/arm/emulation.rst | 1 +
73
hw/arm/realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
67
docs/system/arm/nuvoton.rst | 4 +-
74
hw/arm/stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
68
target/arm/cpu-param.h | 2 +-
75
hw/core/irq: remove unused 'qemu_irq_split' function
69
target/arm/cpu.h | 181 ++++++++------
76
70
target/arm/internals.h | 150 ++++++-----
77
docs/system/arm/virt.rst | 4 +-
71
hw/arm/boot.c | 4 +
78
include/hw/arm/exynos4210.h | 50 ++--
72
target/arm/helper.c | 332 ++++++++++++++----------
79
include/hw/arm/xlnx-versal.h | 16 ++
73
target/arm/kvm.c | 4 +-
80
include/hw/arm/xlnx-zynqmp.h | 4 +
74
target/arm/m_helper.c | 29 ++-
81
include/hw/intc/exynos4210_combiner.h | 57 +++++
75
target/arm/ptw.c | 570 ++++++++++++++++++++++--------------------
82
include/hw/intc/exynos4210_gic.h | 43 ++++
76
target/arm/tlb_helper.c | 9 +-
83
include/hw/irq.h | 5 -
77
target/arm/translate-a64.c | 8 -
84
include/hw/misc/npcm7xx_gcr.h | 30 +++
78
target/arm/translate.c | 9 +-
85
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++++
79
13 files changed, 717 insertions(+), 586 deletions(-)
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
1
The only time we use the int_combiner_irq[] and ext_combiner_irq[]
1
Occasionally the KVM_CREATE_VM ioctl can return EINTR, even though
2
arrays in the Exynos4210Irq struct is during realize of the SoC -- we
2
there is no pending signal to be taken. In commit 94ccff13382055
3
initialize them with the input IRQs of the combiner devices, and then
3
we added a retry-on-EINTR loop to the KVM_CREATE_VM call in the
4
connect those to outputs of other devices in
4
generic KVM code. Adopt the same approach for the use of the
5
exynos4210_init_board_irqs(). Now that the combiner objects are
5
ioctl in the Arm-specific KVM code (where we use it to create a
6
easily accessible as s->int_combiner and s->ext_combiner we can make
6
scratch VM for probing for various things).
7
the connections directly from one device to the other without going
8
via these arrays.
9
7
10
Since these are the only two remaining elements of Exynos4210Irq,
8
For more information, see the mailing list thread:
11
we can remove that struct entirely.
9
https://lore.kernel.org/qemu-devel/8735e0s1zw.wl-maz@kernel.org/
12
10
11
Reported-by: Vitaly Chikunov <vt@altlinux.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Vitaly Chikunov <vt@altlinux.org>
15
Message-id: 20220404154658.565020-19-peter.maydell@linaro.org
14
Reviewed-by: Eric Auger <eric.auger@redhat.com>
15
Acked-by: Marc Zyngier <maz@kernel.org>
16
Message-id: 20220930113824.1933293-1-peter.maydell@linaro.org
16
---
17
---
17
include/hw/arm/exynos4210.h | 6 ------
18
target/arm/kvm.c | 4 +++-
18
hw/arm/exynos4210.c | 34 ++++++++--------------------------
19
1 file changed, 3 insertions(+), 1 deletion(-)
19
2 files changed, 8 insertions(+), 32 deletions(-)
20
20
21
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
21
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
22
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/exynos4210.h
23
--- a/target/arm/kvm.c
24
+++ b/include/hw/arm/exynos4210.h
24
+++ b/target/arm/kvm.c
25
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
26
*/
26
if (max_vm_pa_size < 0) {
27
#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
27
max_vm_pa_size = 0;
28
29
-typedef struct Exynos4210Irq {
30
- qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
31
- qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
32
-} Exynos4210Irq;
33
-
34
struct Exynos4210State {
35
/*< private >*/
36
SysBusDevice parent_obj;
37
/*< public >*/
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
39
- Exynos4210Irq irqs;
40
qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
41
42
MemoryRegion chipid_mem;
43
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/arm/exynos4210.c
46
+++ b/hw/arm/exynos4210.c
47
@@ -XXX,XX +XXX,XX @@ static int mapline_size(const int *mapline)
48
static void exynos4210_init_board_irqs(Exynos4210State *s)
49
{
50
uint32_t grp, bit, irq_id, n;
51
- Exynos4210Irq *is = &s->irqs;
52
DeviceState *extgicdev = DEVICE(&s->ext_gic);
53
+ DeviceState *intcdev = DEVICE(&s->int_combiner);
54
+ DeviceState *extcdev = DEVICE(&s->ext_combiner);
55
int splitcount = 0;
56
DeviceState *splitter;
57
const int *mapline;
58
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
59
splitin = 0;
60
for (;;) {
61
s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
62
- qdev_connect_gpio_out(splitter, splitin, is->int_combiner_irq[in]);
63
- qdev_connect_gpio_out(splitter, splitin + 1, is->ext_combiner_irq[in]);
64
+ qdev_connect_gpio_out(splitter, splitin,
65
+ qdev_get_gpio_in(intcdev, in));
66
+ qdev_connect_gpio_out(splitter, splitin + 1,
67
+ qdev_get_gpio_in(extcdev, in));
68
splitin += 2;
69
if (!mapline) {
70
break;
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
72
qdev_realize(splitter, NULL, &error_abort);
73
splitcount++;
74
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
75
- qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
76
+ qdev_connect_gpio_out(splitter, 0, qdev_get_gpio_in(intcdev, n));
77
qdev_connect_gpio_out(splitter, 1,
78
qdev_get_gpio_in(extgicdev, irq_id - 32));
79
} else {
80
- s->irq_table[n] = is->int_combiner_irq[n];
81
+ s->irq_table[n] = qdev_get_gpio_in(intcdev, n);
82
}
83
}
28
}
84
/*
29
- vmfd = ioctl(kvmfd, KVM_CREATE_VM, max_vm_pa_size);
85
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
30
+ do {
86
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
31
+ vmfd = ioctl(kvmfd, KVM_CREATE_VM, max_vm_pa_size);
87
}
32
+ } while (vmfd == -1 && errno == EINTR);
88
33
if (vmfd < 0) {
89
-/*
34
goto err;
90
- * Get Combiner input GPIO into irqs structure
91
- */
92
-static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
93
- DeviceState *dev, int ext)
94
-{
95
- int n;
96
- int max;
97
- qemu_irq *irq;
98
-
99
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
100
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
101
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
102
-
103
- for (n = 0; n < max; n++) {
104
- irq[n] = qdev_get_gpio_in(dev, n);
105
- }
106
-}
107
-
108
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
109
0x09, 0x00, 0x00, 0x00 };
110
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
112
sysbus_connect_irq(busdev, n,
113
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
114
}
35
}
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
--
36
--
128
2.25.1
37
2.25.1
diff view generated by jsdifflib
1
Switch the creation of the combiner devices to the new-style
1
From: Jerome Forissier <jerome.forissier@linaro.org>
2
"embedded in state struct" approach, so we can easily refer
3
to the object elsewhere during realize.
4
2
3
Updates write_scr() to allow setting SCR_EL3.EnTP2 when FEAT_SME is
4
implemented. SCR_EL3 being a 64-bit register, valid_mask is changed
5
to uint64_t and the SCR_* constants in target/arm/cpu.h are extended
6
to 64-bit so that masking and bitwise not (~) behave as expected.
7
8
This enables booting Linux with Trusted Firmware-A at EL3 with
9
"-M virt,secure=on -cpu max".
10
11
Cc: qemu-stable@nongnu.org
12
Fixes: 78cb9776662a ("target/arm: Enable SME for -cpu max")
13
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
14
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20221004072354.27037-1-jerome.forissier@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
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
---
18
---
9
include/hw/arm/exynos4210.h | 3 ++
19
target/arm/cpu.h | 54 ++++++++++++++++++++++-----------------------
10
include/hw/intc/exynos4210_combiner.h | 57 +++++++++++++++++++++++++++
20
target/arm/helper.c | 5 ++++-
11
hw/arm/exynos4210.c | 20 +++++-----
21
2 files changed, 31 insertions(+), 28 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
22
16
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/exynos4210.h
25
--- a/target/arm/cpu.h
19
+++ b/include/hw/arm/exynos4210.h
26
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
21
#include "hw/sysbus.h"
28
22
#include "hw/cpu/a9mpcore.h"
29
#define HPFAR_NS (1ULL << 63)
23
#include "hw/intc/exynos4210_gic.h"
30
24
+#include "hw/intc/exynos4210_combiner.h"
31
-#define SCR_NS (1U << 0)
25
#include "hw/core/split-irq.h"
32
-#define SCR_IRQ (1U << 1)
26
#include "target/arm/cpu-qom.h"
33
-#define SCR_FIQ (1U << 2)
27
#include "qom/object.h"
34
-#define SCR_EA (1U << 3)
28
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
35
-#define SCR_FW (1U << 4)
29
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
36
-#define SCR_AW (1U << 5)
30
A9MPPrivState a9mpcore;
37
-#define SCR_NET (1U << 6)
31
Exynos4210GicState ext_gic;
38
-#define SCR_SMD (1U << 7)
32
+ Exynos4210CombinerState int_combiner;
39
-#define SCR_HCE (1U << 8)
33
+ Exynos4210CombinerState ext_combiner;
40
-#define SCR_SIF (1U << 9)
34
SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
41
-#define SCR_RW (1U << 10)
35
};
42
-#define SCR_ST (1U << 11)
36
43
-#define SCR_TWI (1U << 12)
37
diff --git a/include/hw/intc/exynos4210_combiner.h b/include/hw/intc/exynos4210_combiner.h
44
-#define SCR_TWE (1U << 13)
38
new file mode 100644
45
-#define SCR_TLOR (1U << 14)
39
index XXXXXXX..XXXXXXX
46
-#define SCR_TERR (1U << 15)
40
--- /dev/null
47
-#define SCR_APK (1U << 16)
41
+++ b/include/hw/intc/exynos4210_combiner.h
48
-#define SCR_API (1U << 17)
42
@@ -XXX,XX +XXX,XX @@
49
-#define SCR_EEL2 (1U << 18)
43
+/*
50
-#define SCR_EASE (1U << 19)
44
+ * Samsung exynos4210 Interrupt Combiner
51
-#define SCR_NMEA (1U << 20)
45
+ *
52
-#define SCR_FIEN (1U << 21)
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
53
-#define SCR_ENSCXT (1U << 25)
47
+ * All rights reserved.
54
-#define SCR_ATA (1U << 26)
48
+ *
55
-#define SCR_FGTEN (1U << 27)
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
56
-#define SCR_ECVEN (1U << 28)
50
+ *
57
-#define SCR_TWEDEN (1U << 29)
51
+ * This program is free software; you can redistribute it and/or modify it
58
+#define SCR_NS (1ULL << 0)
52
+ * under the terms of the GNU General Public License as published by the
59
+#define SCR_IRQ (1ULL << 1)
53
+ * Free Software Foundation; either version 2 of the License, or (at your
60
+#define SCR_FIQ (1ULL << 2)
54
+ * option) any later version.
61
+#define SCR_EA (1ULL << 3)
55
+ *
62
+#define SCR_FW (1ULL << 4)
56
+ * This program is distributed in the hope that it will be useful,
63
+#define SCR_AW (1ULL << 5)
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
64
+#define SCR_NET (1ULL << 6)
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
65
+#define SCR_SMD (1ULL << 7)
59
+ * See the GNU General Public License for more details.
66
+#define SCR_HCE (1ULL << 8)
60
+ *
67
+#define SCR_SIF (1ULL << 9)
61
+ * You should have received a copy of the GNU General Public License along
68
+#define SCR_RW (1ULL << 10)
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
69
+#define SCR_ST (1ULL << 11)
63
+ */
70
+#define SCR_TWI (1ULL << 12)
64
+
71
+#define SCR_TWE (1ULL << 13)
65
+#ifndef HW_INTC_EXYNOS4210_COMBINER
72
+#define SCR_TLOR (1ULL << 14)
66
+#define HW_INTC_EXYNOS4210_COMBINER
73
+#define SCR_TERR (1ULL << 15)
67
+
74
+#define SCR_APK (1ULL << 16)
68
+#include "hw/sysbus.h"
75
+#define SCR_API (1ULL << 17)
69
+
76
+#define SCR_EEL2 (1ULL << 18)
70
+/*
77
+#define SCR_EASE (1ULL << 19)
71
+ * State for each output signal of internal combiner
78
+#define SCR_NMEA (1ULL << 20)
72
+ */
79
+#define SCR_FIEN (1ULL << 21)
73
+typedef struct CombinerGroupState {
80
+#define SCR_ENSCXT (1ULL << 25)
74
+ uint8_t src_mask; /* 1 - source enabled, 0 - disabled */
81
+#define SCR_ATA (1ULL << 26)
75
+ uint8_t src_pending; /* Pending source interrupts before masking */
82
+#define SCR_FGTEN (1ULL << 27)
76
+} CombinerGroupState;
83
+#define SCR_ECVEN (1ULL << 28)
77
+
84
+#define SCR_TWEDEN (1ULL << 29)
78
+#define TYPE_EXYNOS4210_COMBINER "exynos4210.combiner"
85
#define SCR_TWEDEL MAKE_64BIT_MASK(30, 4)
79
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210CombinerState, EXYNOS4210_COMBINER)
86
#define SCR_TME (1ULL << 34)
80
+
87
#define SCR_AMVOFFEN (1ULL << 35)
81
+/* Number of groups and total number of interrupts for the internal combiner */
88
diff --git a/target/arm/helper.c b/target/arm/helper.c
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
89
index XXXXXXX..XXXXXXX 100644
102
--- a/hw/arm/exynos4210.c
90
--- a/target/arm/helper.c
103
+++ b/hw/arm/exynos4210.c
91
+++ b/target/arm/helper.c
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
92
@@ -XXX,XX +XXX,XX @@ static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
105
}
93
static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
106
94
{
107
/* Internal Interrupt Combiner */
95
/* Begin with base v8.0 state. */
108
- dev = qdev_new("exynos4210.combiner");
96
- uint32_t valid_mask = 0x3fff;
109
- busdev = SYS_BUS_DEVICE(dev);
97
+ uint64_t valid_mask = 0x3fff;
110
- sysbus_realize_and_unref(busdev, &error_fatal);
98
ARMCPU *cpu = env_archcpu(env);
111
+ busdev = SYS_BUS_DEVICE(&s->int_combiner);
99
112
+ sysbus_realize(busdev, &error_fatal);
100
/*
113
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
101
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
114
sysbus_connect_irq(busdev, n,
102
if (cpu_isar_feature(aa64_doublefault, cpu)) {
115
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
103
valid_mask |= SCR_EASE | SCR_NMEA;
116
}
104
}
117
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
105
+ if (cpu_isar_feature(aa64_sme, cpu)) {
118
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
106
+ valid_mask |= SCR_ENTP2;
119
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
107
+ }
120
108
} else {
121
/* External Interrupt Combiner */
109
valid_mask &= ~(SCR_RW | SCR_ST);
122
- dev = qdev_new("exynos4210.combiner");
110
if (cpu_isar_feature(aa32_ras, cpu)) {
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
--
111
--
199
2.25.1
112
2.25.1
diff view generated by jsdifflib
1
From: Zongyuan Li <zongyuan.li@smartx.com>
1
From: Joel Stanley <joel@jms.id.au>
2
2
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
3
openpower.xyz was retired some time ago. The OpenBMC Jenkins is where
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
images can be found these days.
5
Message-id: 20220324181557.203805-3-zongyuan.li@smartx.com
5
6
Signed-off-by: Joel Stanley <joel@jms.id.au>
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20221004050042.22681-1-joel@jms.id.au
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
12
---
8
hw/arm/stellaris.c | 15 +++++++++++++--
13
docs/system/arm/nuvoton.rst | 4 ++--
9
1 file changed, 13 insertions(+), 2 deletions(-)
14
1 file changed, 2 insertions(+), 2 deletions(-)
10
15
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
16
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/stellaris.c
18
--- a/docs/system/arm/nuvoton.rst
14
+++ b/hw/arm/stellaris.c
19
+++ b/docs/system/arm/nuvoton.rst
15
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ Boot options
16
21
17
#include "qemu/osdep.h"
22
The Nuvoton machines can boot from an OpenBMC firmware image, or directly into
18
#include "qapi/error.h"
23
a kernel using the ``-kernel`` option. OpenBMC images for ``quanta-gsj`` and
19
+#include "hw/core/split-irq.h"
24
-possibly others can be downloaded from the OpenPOWER jenkins :
20
#include "hw/sysbus.h"
25
+possibly others can be downloaded from the OpenBMC jenkins :
21
#include "hw/sd/sd.h"
26
22
#include "hw/ssi/ssi.h"
27
- https://openpower.xyz/
23
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
28
+ https://jenkins.openbmc.org/
24
DeviceState *ssddev;
29
25
DriveInfo *dinfo;
30
The firmware image should be attached as an MTD drive. Example :
26
DeviceState *carddev;
31
27
+ DeviceState *gpio_d_splitter;
28
BlockBackend *blk;
29
30
/*
31
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
32
&error_fatal);
33
34
ssddev = ssi_create_peripheral(bus, "ssd0323");
35
- gpio_out[GPIO_D][0] = qemu_irq_split(
36
- qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0),
37
+
38
+ gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
39
+ qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
40
+ qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
41
+ qdev_connect_gpio_out(
42
+ gpio_d_splitter, 0,
43
+ qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0));
44
+ qdev_connect_gpio_out(
45
+ gpio_d_splitter, 1,
46
qdev_get_gpio_in_named(ssddev, SSI_GPIO_CS, 0));
47
+ gpio_out[GPIO_D][0] = qdev_get_gpio_in(gpio_d_splitter, 0);
48
+
49
gpio_out[GPIO_C][7] = qdev_get_gpio_in(ssddev, 0);
50
51
/* Make sure the select pin is high. */
52
--
32
--
53
2.25.1
33
2.25.1
34
35
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
The starting security state comes with the translation regime,
4
not the current state of arm_is_secure_below_el3().
5
6
Create a new local variable, s2walk_secure, which does not need
7
to be written back to result->attrs.secure -- we compute that
8
value later, after the S2 walk is complete.
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-2-zongyuan.li@smartx.com
12
Message-id: 20221001162318.153420-2-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
14
---
8
hw/arm/realview.c | 33 ++++++++++++++++++++++++---------
15
target/arm/ptw.c | 18 +++++++++---------
9
1 file changed, 24 insertions(+), 9 deletions(-)
16
1 file changed, 9 insertions(+), 9 deletions(-)
10
17
11
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
18
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
12
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/realview.c
20
--- a/target/arm/ptw.c
14
+++ b/hw/arm/realview.c
21
+++ b/target/arm/ptw.c
15
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
16
#include "hw/sysbus.h"
23
hwaddr ipa;
17
#include "hw/arm/boot.h"
24
int s1_prot;
18
#include "hw/arm/primecell.h"
25
int ret;
19
+#include "hw/core/split-irq.h"
26
- bool ipa_secure;
20
#include "hw/net/lan9118.h"
27
+ bool ipa_secure, s2walk_secure;
21
#include "hw/net/smc91c111.h"
28
ARMCacheAttrs cacheattrs1;
22
#include "hw/pci/pci.h"
29
ARMMMUIdx s2_mmu_idx;
23
+#include "hw/qdev-core.h"
30
bool is_el0;
24
#include "net/net.h"
31
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
25
#include "sysemu/sysemu.h"
32
26
#include "hw/boards.h"
33
ipa = result->phys;
27
@@ -XXX,XX +XXX,XX @@ static const int realview_board_id[] = {
34
ipa_secure = result->attrs.secure;
28
0x76d
35
- if (arm_is_secure_below_el3(env)) {
29
};
36
- if (ipa_secure) {
30
37
- result->attrs.secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
31
+static void split_irq_from_named(DeviceState *src, const char* outname,
38
- } else {
32
+ qemu_irq out1, qemu_irq out2) {
39
- result->attrs.secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
33
+ DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
40
- }
34
+
41
+ if (is_secure) {
35
+ qdev_prop_set_uint32(splitter, "num-lines", 2);
42
+ /* Select TCR based on the NS bit from the S1 walk. */
36
+
43
+ s2walk_secure = !(ipa_secure
37
+ qdev_realize_and_unref(splitter, NULL, &error_fatal);
44
+ ? env->cp15.vstcr_el2 & VSTCR_SW
38
+
45
+ : env->cp15.vtcr_el2 & VTCR_NSW);
39
+ qdev_connect_gpio_out(splitter, 0, out1);
46
} else {
40
+ qdev_connect_gpio_out(splitter, 1, out2);
47
assert(!ipa_secure);
41
+ qdev_connect_gpio_out_named(src, outname, 0,
48
+ s2walk_secure = false;
42
+ qdev_get_gpio_in(splitter, 0));
49
}
43
+}
50
44
+
51
- s2_mmu_idx = (result->attrs.secure
45
static void realview_init(MachineState *machine,
52
+ s2_mmu_idx = (s2walk_secure
46
enum realview_board_type board_type)
53
? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2);
47
{
54
is_el0 = mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_SE10_0;
48
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
55
49
DeviceState *dev, *sysctl, *gpio2, *pl041;
56
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
50
SysBusDevice *busdev;
57
result->cacheattrs);
51
qemu_irq pic[64];
58
52
- qemu_irq mmc_irq[2];
59
/* Check if IPA translates to secure or non-secure PA space. */
53
PCIBus *pci_bus = NULL;
60
- if (arm_is_secure_below_el3(env)) {
54
NICInfo *nd;
61
+ if (is_secure) {
55
DriveInfo *dinfo;
62
if (ipa_secure) {
56
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
63
result->attrs.secure =
57
* and the PL061 has them the other way about. Also the card
64
!(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW));
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
--
65
--
80
2.25.1
66
2.25.1
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This patch uses the defined fields to describe PWRON STRAPs for
3
While the stage2 call to get_phys_addr_lpae should never set
4
better readability.
4
attrs.secure when given a non-secure input, it's just as easy
5
to make the final update to attrs.secure be unconditional and
6
false in the case of non-secure input.
5
7
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
8
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Patrick Venture <venture@google.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220411165842.3912945-3-wuhaotsh@google.com
10
Message-id: 20221007152159.1414065-1-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@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
hw/arm/npcm7xx_boards.c | 24 +++++++++++++++++++-----
14
target/arm/ptw.c | 21 ++++++++++-----------
13
1 file changed, 19 insertions(+), 5 deletions(-)
15
1 file changed, 10 insertions(+), 11 deletions(-)
14
16
15
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/npcm7xx_boards.c
19
--- a/target/arm/ptw.c
18
+++ b/hw/arm/npcm7xx_boards.c
20
+++ b/target/arm/ptw.c
19
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
20
#include "sysemu/sysemu.h"
22
result->cacheattrs = combine_cacheattrs(env, cacheattrs1,
21
#include "sysemu/block-backend.h"
23
result->cacheattrs);
22
24
23
-#define NPCM750_EVB_POWER_ON_STRAPS 0x00001ff7
25
- /* Check if IPA translates to secure or non-secure PA space. */
24
-#define QUANTA_GSJ_POWER_ON_STRAPS 0x00001fff
26
- if (is_secure) {
25
-#define QUANTA_GBS_POWER_ON_STRAPS 0x000017ff
27
- if (ipa_secure) {
26
-#define KUDO_BMC_POWER_ON_STRAPS 0x00001fff
28
- result->attrs.secure =
27
-#define MORI_BMC_POWER_ON_STRAPS 0x00001fff
29
- !(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW));
28
+#define NPCM7XX_POWER_ON_STRAPS_DEFAULT ( \
30
- } else {
29
+ NPCM7XX_PWRON_STRAP_SPI0F18 | \
31
- result->attrs.secure =
30
+ NPCM7XX_PWRON_STRAP_SFAB | \
32
- !((env->cp15.vtcr_el2 & (VTCR_NSA | VTCR_NSW))
31
+ NPCM7XX_PWRON_STRAP_BSPA | \
33
- || (env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW)));
32
+ NPCM7XX_PWRON_STRAP_FUP(FUP_NORM_UART2) | \
34
- }
33
+ NPCM7XX_PWRON_STRAP_SECEN | \
35
- }
34
+ NPCM7XX_PWRON_STRAP_HIZ | \
36
+ /*
35
+ NPCM7XX_PWRON_STRAP_ECC | \
37
+ * Check if IPA translates to secure or non-secure PA space.
36
+ NPCM7XX_PWRON_STRAP_RESERVE1 | \
38
+ * Note that VSTCR overrides VTCR and {N}SW overrides {N}SA.
37
+ NPCM7XX_PWRON_STRAP_J2EN | \
39
+ */
38
+ NPCM7XX_PWRON_STRAP_CKFRQ(CKFRQ_DEFAULT))
40
+ result->attrs.secure =
41
+ (is_secure
42
+ && !(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW))
43
+ && (ipa_secure
44
+ || !(env->cp15.vtcr_el2 & (VTCR_NSA | VTCR_NSW))));
39
+
45
+
40
+#define NPCM750_EVB_POWER_ON_STRAPS ( \
46
return 0;
41
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_J2EN)
47
} else {
42
+#define QUANTA_GSJ_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
48
/*
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
--
49
--
51
2.25.1
50
2.25.1
diff view generated by jsdifflib
1
The exynos4210 SoC mostly creates its child devices as if it were
1
From: Richard Henderson <richard.henderson@linaro.org>
2
board code. This includes the a9mpcore object. Switch that to a
3
new-style "embedded in the state struct" creation, because in the
4
next commit we're going to want to refer to the object again further
5
down in the exynos4210_realize() function.
6
2
3
Remove the use of regime_is_secure from get_phys_addr_lpae,
4
using the new parameter instead.
5
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20221001162318.153420-3-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
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
---
10
---
11
include/hw/arm/exynos4210.h | 2 ++
11
target/arm/ptw.c | 20 ++++++++++----------
12
hw/arm/exynos4210.c | 11 ++++++-----
12
1 file changed, 10 insertions(+), 10 deletions(-)
13
2 files changed, 8 insertions(+), 5 deletions(-)
14
13
15
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/exynos4210.h
16
--- a/target/arm/ptw.c
18
+++ b/include/hw/arm/exynos4210.h
17
+++ b/target/arm/ptw.c
19
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@
20
19
21
#include "hw/or-irq.h"
20
static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
22
#include "hw/sysbus.h"
21
MMUAccessType access_type, ARMMMUIdx mmu_idx,
23
+#include "hw/cpu/a9mpcore.h"
22
- bool s1_is_el0, GetPhysAddrResult *result,
24
#include "target/arm/cpu-qom.h"
23
- ARMMMUFaultInfo *fi)
25
#include "qom/object.h"
24
+ bool is_secure, bool s1_is_el0,
26
25
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
27
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
26
__attribute__((nonnull));
28
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
27
29
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
28
/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
30
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
29
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
31
+ A9MPPrivState a9mpcore;
30
GetPhysAddrResult s2 = {};
32
};
31
int ret;
33
32
34
#define TYPE_EXYNOS4210_SOC "exynos4210"
33
- ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx, false,
35
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
34
- &s2, fi);
36
index XXXXXXX..XXXXXXX 100644
35
+ ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx,
37
--- a/hw/arm/exynos4210.c
36
+ *is_secure, false, &s2, fi);
38
+++ b/hw/arm/exynos4210.c
37
if (ret) {
39
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
38
assert(fi->type != ARMFault_None);
39
fi->s2addr = addr;
40
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
41
*/
42
static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
43
MMUAccessType access_type, ARMMMUIdx mmu_idx,
44
- bool s1_is_el0, GetPhysAddrResult *result,
45
- ARMMMUFaultInfo *fi)
46
+ bool is_secure, bool s1_is_el0,
47
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
48
{
49
ARMCPU *cpu = env_archcpu(env);
50
/* Read an LPAE long-descriptor translation table. */
51
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
52
* remain non-secure. We implement this by just ORing in the NSTable/NS
53
* bits at each step.
54
*/
55
- tableattrs = regime_is_secure(env, mmu_idx) ? 0 : (1 << 4);
56
+ tableattrs = is_secure ? 0 : (1 << 4);
57
for (;;) {
58
uint64_t descriptor;
59
bool nstable;
60
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
61
memset(result, 0, sizeof(*result));
62
63
ret = get_phys_addr_lpae(env, ipa, access_type, s2_mmu_idx,
64
- is_el0, result, fi);
65
+ s2walk_secure, is_el0, result, fi);
66
fi->s2addr = ipa;
67
68
/* Combine the S1 and S2 perms. */
69
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
40
}
70
}
41
71
42
/* Private memory region and Internal GIC */
72
if (regime_using_lpae_format(env, mmu_idx)) {
43
- dev = qdev_new(TYPE_A9MPCORE_PRIV);
73
- return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
44
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
74
- result, fi);
45
- busdev = SYS_BUS_DEVICE(dev);
75
+ return get_phys_addr_lpae(env, address, access_type, mmu_idx,
46
- sysbus_realize_and_unref(busdev, &error_fatal);
76
+ is_secure, false, result, fi);
47
+ qdev_prop_set_uint32(DEVICE(&s->a9mpcore), "num-cpu", EXYNOS4210_NCPUS);
77
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
48
+ busdev = SYS_BUS_DEVICE(&s->a9mpcore);
78
return get_phys_addr_v6(env, address, access_type, mmu_idx,
49
+ sysbus_realize(busdev, &error_fatal);
79
is_secure, result, fi);
50
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
51
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
52
sysbus_connect_irq(busdev, n,
53
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
54
}
55
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
56
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
57
+ s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
58
}
59
60
/* Cache controller */
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
62
g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
63
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
64
}
65
+
66
+ object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
67
}
68
69
static void exynos4210_class_init(ObjectClass *klass, void *data)
70
--
80
--
71
2.25.1
81
2.25.1
82
83
diff view generated by jsdifflib
1
The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0
1
From: Richard Henderson <richard.henderson@linaro.org>
2
and EXT_GIC_ID_MCT_G1 multiple times. This means that we will
3
connect multiple IRQs up to the same external GIC input, which
4
is not permitted. We do the same thing in the code in
5
exynos4210_init_board_irqs() because the conditionals selecting
6
an irq_id in the first loop match multiple interrupt IDs.
7
2
8
Overall we do this for interrupt IDs
3
Pass the correct stage2 mmu_idx to regime_translation_disabled,
9
(1, 4), (12, 4), (35, 4), (51, 4), (53, 4) for EXT_GIC_ID_MCT_G0
4
which we computed afterward.
10
and
11
(1, 5), (12, 5), (35, 5), (51, 5), (53, 5) for EXT_GIC_ID_MCT_G1
12
5
13
These correspond to the cases for the multi-core timer that we are
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
wiring up to multiple inputs on the combiner in
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
exynos4210_combiner_get_gpioin(). That code already deals with all
8
Message-id: 20221001162318.153420-4-richard.henderson@linaro.org
16
these interrupt IDs being the same input source, so we don't need to
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
connect the external GIC interrupt for any of them except the first
10
---
18
(1, 4) and (1, 5). Remove the array entries and conditionals which
11
target/arm/ptw.c | 6 +++---
19
were incorrectly causing us to wire up extra lines.
12
1 file changed, 3 insertions(+), 3 deletions(-)
20
13
21
This bug didn't cause any visible effects, because we only connect
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
22
up a device to the "primary" ID values (1, 4) and (1, 5), so the
23
extra lines would never be set to a level.
24
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20220404154658.565020-16-peter.maydell@linaro.org
28
---
29
include/hw/arm/exynos4210.h | 2 +-
30
hw/arm/exynos4210.c | 12 +++++-------
31
2 files changed, 6 insertions(+), 8 deletions(-)
32
33
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
34
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
35
--- a/include/hw/arm/exynos4210.h
16
--- a/target/arm/ptw.c
36
+++ b/include/hw/arm/exynos4210.h
17
+++ b/target/arm/ptw.c
37
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
38
* one for every non-zero entry in combiner_grp_to_gic_id[].
19
hwaddr addr, bool *is_secure,
39
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
20
ARMMMUFaultInfo *fi)
40
*/
21
{
41
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
22
+ ARMMMUIdx s2_mmu_idx = *is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
42
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
23
+
43
24
if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
44
typedef struct Exynos4210Irq {
25
- !regime_translation_disabled(env, ARMMMUIdx_Stage2)) {
45
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
26
- ARMMMUIdx s2_mmu_idx = *is_secure ? ARMMMUIdx_Stage2_S
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
27
- : ARMMMUIdx_Stage2;
47
index XXXXXXX..XXXXXXX 100644
28
+ !regime_translation_disabled(env, s2_mmu_idx)) {
48
--- a/hw/arm/exynos4210.c
29
GetPhysAddrResult s2 = {};
49
+++ b/hw/arm/exynos4210.c
30
int ret;
50
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
31
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
--
32
--
90
2.25.1
33
2.25.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Connect the CRL (Clock Reset LPD) to the Versal SoC.
3
Remove the use of regime_is_secure from regime_translation_disabled,
4
using the new parameter instead.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
This fixes a bug in S1_ptw_translate and get_phys_addr where we had
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
7
passed ARMMMUIdx_Stage2 and not ARMMMUIdx_Stage2_S to determine if
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Stage2 is disabled, affecting FEAT_SEL2.
8
Message-id: 20220406174303.2022038-5-edgar.iglesias@xilinx.com
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20221001162318.153420-5-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
15
---
11
include/hw/arm/xlnx-versal.h | 4 +++
16
target/arm/ptw.c | 20 +++++++++++---------
12
hw/arm/xlnx-versal.c | 54 ++++++++++++++++++++++++++++++++++--
17
1 file changed, 11 insertions(+), 9 deletions(-)
13
2 files changed, 56 insertions(+), 2 deletions(-)
14
18
15
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
19
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/xlnx-versal.h
21
--- a/target/arm/ptw.c
18
+++ b/include/hw/arm/xlnx-versal.h
22
+++ b/target/arm/ptw.c
19
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ static uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx, int ttbrn)
20
#include "hw/nvram/xlnx-versal-efuse.h"
21
#include "hw/ssi/xlnx-versal-ospi.h"
22
#include "hw/dma/xlnx_csu_dma.h"
23
+#include "hw/misc/xlnx-versal-crl.h"
24
#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
25
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
27
@@ -XXX,XX +XXX,XX @@ struct Versal {
28
qemu_or_irq irq_orgate;
29
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
30
} xram;
31
+
32
+ XlnxVersalCRL crl;
33
} lpd;
34
35
/* The Platform Management Controller subsystem. */
36
@@ -XXX,XX +XXX,XX @@ struct Versal {
37
#define VERSAL_TIMER_NS_EL1_IRQ 14
38
#define VERSAL_TIMER_NS_EL2_IRQ 10
39
40
+#define VERSAL_CRL_IRQ 10
41
#define VERSAL_UART0_IRQ_0 18
42
#define VERSAL_UART1_IRQ_0 19
43
#define VERSAL_USB0_IRQ_0 22
44
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/xlnx-versal.c
47
+++ b/hw/arm/xlnx-versal.c
48
@@ -XXX,XX +XXX,XX @@ static void versal_create_ospi(Versal *s, qemu_irq *pic)
49
qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
50
}
24
}
51
25
52
+static void versal_create_crl(Versal *s, qemu_irq *pic)
26
/* Return true if the specified stage of address translation is disabled */
53
+{
27
-static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx)
54
+ SysBusDevice *sbd;
28
+static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
55
+ int i;
29
+ bool is_secure)
56
+
30
{
57
+ object_initialize_child(OBJECT(s), "crl", &s->lpd.crl,
31
uint64_t hcr_el2;
58
+ TYPE_XLNX_VERSAL_CRL);
32
59
+ sbd = SYS_BUS_DEVICE(&s->lpd.crl);
33
if (arm_feature(env, ARM_FEATURE_M)) {
60
+
34
- switch (env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)] &
61
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
35
+ switch (env->v7m.mpu_ctrl[is_secure] &
62
+ g_autofree gchar *name = g_strdup_printf("cpu_r5[%d]", i);
36
(R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) {
63
+
37
case R_V7M_MPU_CTRL_ENABLE_MASK:
64
+ object_property_set_link(OBJECT(&s->lpd.crl),
38
/* Enabled, but not for HardFault and NMI */
65
+ name, OBJECT(&s->lpd.rpu.cpu[i]),
39
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx)
66
+ &error_abort);
40
67
+ }
41
if (hcr_el2 & HCR_TGE) {
68
+
42
/* TGE means that NS EL0/1 act as if SCTLR_EL1.M is zero */
69
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
43
- if (!regime_is_secure(env, mmu_idx) && regime_el(env, mmu_idx) == 1) {
70
+ g_autofree gchar *name = g_strdup_printf("gem[%d]", i);
44
+ if (!is_secure && regime_el(env, mmu_idx) == 1) {
71
+
45
return true;
72
+ object_property_set_link(OBJECT(&s->lpd.crl),
46
}
73
+ name, OBJECT(&s->lpd.iou.gem[i]),
47
}
74
+ &error_abort);
48
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
75
+ }
49
ARMMMUIdx s2_mmu_idx = *is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
76
+
50
77
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
51
if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
78
+ g_autofree gchar *name = g_strdup_printf("adma[%d]", i);
52
- !regime_translation_disabled(env, s2_mmu_idx)) {
79
+
53
+ !regime_translation_disabled(env, s2_mmu_idx, *is_secure)) {
80
+ object_property_set_link(OBJECT(&s->lpd.crl),
54
GetPhysAddrResult s2 = {};
81
+ name, OBJECT(&s->lpd.iou.adma[i]),
55
int ret;
82
+ &error_abort);
56
83
+ }
57
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
84
+
58
uint32_t base;
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) {
59
bool is_user = regime_is_user(env, mmu_idx);
86
+ g_autofree gchar *name = g_strdup_printf("uart[%d]", i);
60
87
+
61
- if (regime_translation_disabled(env, mmu_idx)) {
88
+ object_property_set_link(OBJECT(&s->lpd.crl),
62
+ if (regime_translation_disabled(env, mmu_idx, is_secure)) {
89
+ name, OBJECT(&s->lpd.iou.uart[i]),
63
/* MPU disabled. */
90
+ &error_abort);
64
result->phys = address;
91
+ }
65
result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
92
+
66
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
93
+ object_property_set_link(OBJECT(&s->lpd.crl),
67
result->page_size = TARGET_PAGE_SIZE;
94
+ "usb", OBJECT(&s->lpd.iou.usb),
68
result->prot = 0;
95
+ &error_abort);
69
96
+
70
- if (regime_translation_disabled(env, mmu_idx) ||
97
+ sysbus_realize(sbd, &error_fatal);
71
+ if (regime_translation_disabled(env, mmu_idx, secure) ||
98
+ memory_region_add_subregion(&s->mr_ps, MM_CRL,
72
m_is_ppb_region(env, address)) {
99
+ sysbus_mmio_get_region(sbd, 0));
73
/*
100
+ sysbus_connect_irq(sbd, 0, pic[VERSAL_CRL_IRQ]);
74
* MPU disabled or M profile PPB access: use default memory map.
101
+}
75
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
102
+
76
* are done in arm_v7m_load_vector(), which always does a direct
103
/* This takes the board allocated linear DDR memory and creates aliases
77
* read using address_space_ldl(), rather than going via this function.
104
* for each split DDR range/aperture on the Versal address map.
78
*/
105
*/
79
- if (regime_translation_disabled(env, mmu_idx)) { /* MPU disabled */
106
@@ -XXX,XX +XXX,XX @@ static void versal_unimp(Versal *s)
80
+ if (regime_translation_disabled(env, mmu_idx, secure)) { /* MPU disabled */
107
81
hit = true;
108
versal_unimp_area(s, "psm", &s->mr_ps,
82
} else if (m_is_ppb_region(env, address)) {
109
MM_PSM_START, MM_PSM_END - MM_PSM_START);
83
hit = true;
110
- versal_unimp_area(s, "crl", &s->mr_ps,
84
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
111
- MM_CRL, MM_CRL_SIZE);
85
result, fi);
112
versal_unimp_area(s, "crf", &s->mr_ps,
86
113
MM_FPD_CRF, MM_FPD_CRF_SIZE);
87
/* If S1 fails or S2 is disabled, return early. */
114
versal_unimp_area(s, "apu", &s->mr_ps,
88
- if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2)) {
115
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
89
+ if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2,
116
versal_create_efuse(s, pic);
90
+ is_secure)) {
117
versal_create_pmc_iou_slcr(s, pic);
91
return ret;
118
versal_create_ospi(s, pic);
92
}
119
+ versal_create_crl(s, pic);
93
120
versal_map_ddr(s);
94
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
121
versal_unimp(s);
95
96
/* Definitely a real MMU, not an MPU */
97
98
- if (regime_translation_disabled(env, mmu_idx)) {
99
+ if (regime_translation_disabled(env, mmu_idx, is_secure)) {
100
uint64_t hcr;
101
uint8_t memattr;
122
102
123
--
103
--
124
2.25.1
104
2.25.1
105
106
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
Retain the existing get_phys_addr interface using the security
4
subsystem.
4
state derived from mmu_idx. Move the kerneldoc comments to the
5
header file where they belong.
5
6
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@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-3-edgar.iglesias@xilinx.com
9
Message-id: 20221001162318.153420-6-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 | 10 ++++++++++
12
target/arm/internals.h | 40 ++++++++++++++++++++++++++++++++++++++
12
hw/arm/xlnx-versal-virt.c | 6 +++---
13
target/arm/ptw.c | 44 ++++++++++++++----------------------------
13
hw/arm/xlnx-versal.c | 36 ++++++++++++++++++++++++++++++++++++
14
2 files changed, 55 insertions(+), 29 deletions(-)
14
3 files changed, 49 insertions(+), 3 deletions(-)
15
15
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
18
--- a/target/arm/internals.h
19
+++ b/include/hw/arm/xlnx-versal.h
19
+++ b/target/arm/internals.h
20
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ typedef struct GetPhysAddrResult {
21
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
21
ARMCacheAttrs cacheattrs;
22
22
} GetPhysAddrResult;
23
#define XLNX_VERSAL_NR_ACPUS 2
23
24
+#define XLNX_VERSAL_NR_RCPUS 2
24
+/**
25
#define XLNX_VERSAL_NR_UARTS 2
25
+ * get_phys_addr_with_secure: get the physical address for a virtual address
26
#define XLNX_VERSAL_NR_GEMS 2
26
+ * @env: CPUARMState
27
#define XLNX_VERSAL_NR_ADMAS 8
27
+ * @address: virtual address to get physical address for
28
@@ -XXX,XX +XXX,XX @@ struct Versal {
28
+ * @access_type: 0 for read, 1 for write, 2 for execute
29
VersalUsb2 usb;
29
+ * @mmu_idx: MMU index indicating required translation regime
30
} iou;
30
+ * @is_secure: security state for the access
31
31
+ * @result: set on translation success.
32
+ /* Real-time Processing Unit. */
32
+ * @fi: set to fault info if the translation fails
33
+ struct {
33
+ *
34
+ MemoryRegion mr;
34
+ * Find the physical address corresponding to the given virtual address,
35
+ MemoryRegion mr_ps_alias;
35
+ * by doing a translation table walk on MMU based systems or using the
36
+ * MPU state on MPU based systems.
37
+ *
38
+ * Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
39
+ * prot and page_size may not be filled in, and the populated fsr value provides
40
+ * information on why the translation aborted, in the format of a
41
+ * DFSR/IFSR fault register, with the following caveats:
42
+ * * we honour the short vs long DFSR format differences.
43
+ * * the WnR bit is never set (the caller must do this).
44
+ * * for PSMAv5 based systems we don't bother to return a full FSR format
45
+ * value.
46
+ */
47
+bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
48
+ MMUAccessType access_type,
49
+ ARMMMUIdx mmu_idx, bool is_secure,
50
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
51
+ __attribute__((nonnull));
36
+
52
+
37
+ CPUClusterState cluster;
53
+/**
38
+ ARMCPU cpu[XLNX_VERSAL_NR_RCPUS];
54
+ * get_phys_addr: get the physical address for a virtual address
39
+ } rpu;
55
+ * @env: CPUARMState
40
+
56
+ * @address: virtual address to get physical address for
41
struct {
57
+ * @access_type: 0 for read, 1 for write, 2 for execute
42
qemu_or_irq irq_orgate;
58
+ * @mmu_idx: MMU index indicating required translation regime
43
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
59
+ * @result: set on translation success.
44
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
60
+ * @fi: set to fault info if the translation fails
61
+ *
62
+ * Similarly, but use the security regime of @mmu_idx.
63
+ */
64
bool get_phys_addr(CPUARMState *env, target_ulong address,
65
MMUAccessType access_type, ARMMMUIdx mmu_idx,
66
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
67
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
45
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/xlnx-versal-virt.c
69
--- a/target/arm/ptw.c
47
+++ b/hw/arm/xlnx-versal-virt.c
70
+++ b/target/arm/ptw.c
48
@@ -XXX,XX +XXX,XX @@ static void versal_virt_machine_class_init(ObjectClass *oc, void *data)
71
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
49
72
return ret;
50
mc->desc = "Xilinx Versal Virtual development board";
51
mc->init = versal_virt_init;
52
- mc->min_cpus = XLNX_VERSAL_NR_ACPUS;
53
- mc->max_cpus = XLNX_VERSAL_NR_ACPUS;
54
- mc->default_cpus = XLNX_VERSAL_NR_ACPUS;
55
+ mc->min_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
56
+ mc->max_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
57
+ mc->default_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
58
mc->no_cdrom = true;
59
mc->default_ram_id = "ddr";
60
}
73
}
61
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
74
62
index XXXXXXX..XXXXXXX 100644
75
-/**
63
--- a/hw/arm/xlnx-versal.c
76
- * get_phys_addr - get the physical address for this virtual address
64
+++ b/hw/arm/xlnx-versal.c
77
- *
65
@@ -XXX,XX +XXX,XX @@
78
- * Find the physical address corresponding to the given virtual address,
66
#include "hw/sysbus.h"
79
- * by doing a translation table walk on MMU based systems or using the
67
80
- * MPU state on MPU based systems.
68
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
81
- *
69
+#define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f")
82
- * Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
70
#define GEM_REVISION 0x40070106
83
- * prot and page_size may not be filled in, and the populated fsr value provides
71
84
- * information on why the translation aborted, in the format of a
72
#define VERSAL_NUM_PMC_APB_IRQS 3
85
- * DFSR/IFSR fault register, with the following caveats:
73
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
86
- * * we honour the short vs long DFSR format differences.
87
- * * the WnR bit is never set (the caller must do this).
88
- * * for PSMAv5 based systems we don't bother to return a full FSR format
89
- * value.
90
- *
91
- * @env: CPUARMState
92
- * @address: virtual address to get physical address for
93
- * @access_type: 0 for read, 1 for write, 2 for execute
94
- * @mmu_idx: MMU index indicating required translation regime
95
- * @result: set on translation success.
96
- * @fi: set to fault info if the translation fails
97
- */
98
-bool get_phys_addr(CPUARMState *env, target_ulong address,
99
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
100
- GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
101
+bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
102
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
103
+ bool is_secure, GetPhysAddrResult *result,
104
+ ARMMMUFaultInfo *fi)
105
{
106
ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx);
107
- bool is_secure = regime_is_secure(env, mmu_idx);
108
109
if (mmu_idx != s1_mmu_idx) {
110
/*
111
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
112
ARMMMUIdx s2_mmu_idx;
113
bool is_el0;
114
115
- ret = get_phys_addr(env, address, access_type, s1_mmu_idx,
116
- result, fi);
117
+ ret = get_phys_addr_with_secure(env, address, access_type,
118
+ s1_mmu_idx, is_secure, result, fi);
119
120
/* If S1 fails or S2 is disabled, return early. */
121
if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2,
122
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
74
}
123
}
75
}
124
}
76
125
77
+static void versal_create_rpu_cpus(Versal *s)
126
+bool get_phys_addr(CPUARMState *env, target_ulong address,
127
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
128
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
78
+{
129
+{
79
+ int i;
130
+ return get_phys_addr_with_secure(env, address, access_type, mmu_idx,
80
+
131
+ regime_is_secure(env, mmu_idx),
81
+ object_initialize_child(OBJECT(s), "rpu-cluster", &s->lpd.rpu.cluster,
132
+ result, fi);
82
+ TYPE_CPU_CLUSTER);
83
+ qdev_prop_set_uint32(DEVICE(&s->lpd.rpu.cluster), "cluster-id", 1);
84
+
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
86
+ Object *obj;
87
+
88
+ object_initialize_child(OBJECT(&s->lpd.rpu.cluster),
89
+ "rpu-cpu[*]", &s->lpd.rpu.cpu[i],
90
+ XLNX_VERSAL_RCPU_TYPE);
91
+ obj = OBJECT(&s->lpd.rpu.cpu[i]);
92
+ object_property_set_bool(obj, "start-powered-off", true,
93
+ &error_abort);
94
+
95
+ object_property_set_int(obj, "mp-affinity", 0x100 | i, &error_abort);
96
+ object_property_set_int(obj, "core-count", ARRAY_SIZE(s->lpd.rpu.cpu),
97
+ &error_abort);
98
+ object_property_set_link(obj, "memory", OBJECT(&s->lpd.rpu.mr),
99
+ &error_abort);
100
+ qdev_realize(DEVICE(obj), NULL, &error_fatal);
101
+ }
102
+
103
+ qdev_realize(DEVICE(&s->lpd.rpu.cluster), NULL, &error_fatal);
104
+}
133
+}
105
+
134
+
106
static void versal_create_uarts(Versal *s, qemu_irq *pic)
135
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
136
MemTxAttrs *attrs)
107
{
137
{
108
int i;
109
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
110
111
versal_create_apu_cpus(s);
112
versal_create_apu_gic(s, pic);
113
+ versal_create_rpu_cpus(s);
114
versal_create_uarts(s, pic);
115
versal_create_usbs(s, pic);
116
versal_create_gems(s, pic);
117
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
118
119
memory_region_add_subregion_overlap(&s->mr_ps, MM_OCM, &s->lpd.mr_ocm, 0);
120
memory_region_add_subregion_overlap(&s->fpd.apu.mr, 0, &s->mr_ps, 0);
121
+ memory_region_add_subregion_overlap(&s->lpd.rpu.mr, 0,
122
+ &s->lpd.rpu.mr_ps_alias, 0);
123
}
124
125
static void versal_init(Object *obj)
126
@@ -XXX,XX +XXX,XX @@ static void versal_init(Object *obj)
127
Versal *s = XLNX_VERSAL(obj);
128
129
memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
130
+ memory_region_init(&s->lpd.rpu.mr, obj, "mr-rpu", UINT64_MAX);
131
memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX);
132
+ memory_region_init_alias(&s->lpd.rpu.mr_ps_alias, OBJECT(s),
133
+ "mr-rpu-ps-alias", &s->mr_ps, 0, UINT64_MAX);
134
}
135
136
static Property versal_properties[] = {
137
--
138
--
138
2.25.1
139
2.25.1
diff view generated by jsdifflib
1
Switch the creation of the external GIC to the new-style "embedded in
1
From: Richard Henderson <richard.henderson@linaro.org>
2
state struct" approach, so we can easily refer to the object
3
elsewhere during realize.
4
2
3
Remove the use of regime_is_secure from v7m_read_half_insn, using
4
the new parameter instead.
5
6
As it happens, both callers pass true, propagated from the argument
7
to arm_v7m_mmu_idx_for_secstate which created the mmu_idx argument,
8
but that is a detail of v7m_handle_execute_nsc we need not expose
9
to the callee.
10
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20221001162318.153420-7-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
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
---
16
---
9
include/hw/arm/exynos4210.h | 2 ++
17
target/arm/m_helper.c | 9 ++++-----
10
include/hw/intc/exynos4210_gic.h | 43 ++++++++++++++++++++++++++++++++
18
1 file changed, 4 insertions(+), 5 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
19
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
20
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
22
--- a/target/arm/m_helper.c
20
+++ b/include/hw/arm/exynos4210.h
23
+++ b/target/arm/m_helper.c
21
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ static bool do_v7m_function_return(ARMCPU *cpu)
22
#include "hw/or-irq.h"
25
return true;
23
#include "hw/sysbus.h"
26
}
24
#include "hw/cpu/a9mpcore.h"
27
25
+#include "hw/intc/exynos4210_gic.h"
28
-static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
26
#include "target/arm/cpu-qom.h"
29
+static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx, bool secure,
27
#include "qom/object.h"
30
uint32_t addr, uint16_t *insn)
28
31
{
29
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
32
/*
30
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
33
@@ -XXX,XX +XXX,XX @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
31
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
34
ARMMMUFaultInfo fi = {};
32
A9MPPrivState a9mpcore;
35
MemTxResult txres;
33
+ Exynos4210GicState ext_gic;
36
34
};
37
- v8m_security_lookup(env, addr, MMU_INST_FETCH, mmu_idx,
35
38
- regime_is_secure(env, mmu_idx), &sattrs);
36
#define TYPE_EXYNOS4210_SOC "exynos4210"
39
+ v8m_security_lookup(env, addr, MMU_INST_FETCH, mmu_idx, secure, &sattrs);
37
diff --git a/include/hw/intc/exynos4210_gic.h b/include/hw/intc/exynos4210_gic.h
40
if (!sattrs.nsc || sattrs.ns) {
38
new file mode 100644
41
/*
39
index XXXXXXX..XXXXXXX
42
* This must be the second half of the insn, and it straddles a
40
--- /dev/null
43
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
41
+++ b/include/hw/intc/exynos4210_gic.h
44
/* We want to do the MPU lookup as secure; work out what mmu_idx that is */
42
@@ -XXX,XX +XXX,XX @@
45
mmu_idx = arm_v7m_mmu_idx_for_secstate(env, true);
43
+/*
46
44
+ * Samsung exynos4210 GIC implementation. Based on hw/arm_gic.c
47
- if (!v7m_read_half_insn(cpu, mmu_idx, env->regs[15], &insn)) {
45
+ *
48
+ if (!v7m_read_half_insn(cpu, mmu_idx, true, env->regs[15], &insn)) {
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
49
return false;
47
+ * All rights reserved.
48
+ *
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
50
+ *
51
+ * This program is free software; you can redistribute it and/or modify it
52
+ * under the terms of the GNU General Public License as published by the
53
+ * Free Software Foundation; either version 2 of the License, or (at your
54
+ * option) any later version.
55
+ *
56
+ * This program is distributed in the hope that it will be useful,
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
59
+ * See the GNU General Public License for more details.
60
+ *
61
+ * You should have received a copy of the GNU General Public License along
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
63
+ */
64
+#ifndef HW_INTC_EXYNOS4210_GIC_H
65
+#define HW_INTC_EXYNOS4210_GIC_H
66
+
67
+#include "hw/sysbus.h"
68
+
69
+#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
70
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
71
+
72
+#define EXYNOS4210_GIC_NCPUS 2
73
+
74
+struct Exynos4210GicState {
75
+ SysBusDevice parent_obj;
76
+
77
+ MemoryRegion cpu_container;
78
+ MemoryRegion dist_container;
79
+ MemoryRegion cpu_alias[EXYNOS4210_GIC_NCPUS];
80
+ MemoryRegion dist_alias[EXYNOS4210_GIC_NCPUS];
81
+ uint32_t num_cpu;
82
+ DeviceState *gic;
83
+};
84
+
85
+#endif
86
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/hw/arm/exynos4210.c
89
+++ b/hw/arm/exynos4210.c
90
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
91
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
92
93
/* External GIC */
94
- dev = qdev_new("exynos4210.gic");
95
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
96
- busdev = SYS_BUS_DEVICE(dev);
97
- sysbus_realize_and_unref(busdev, &error_fatal);
98
+ qdev_prop_set_uint32(DEVICE(&s->ext_gic), "num-cpu", EXYNOS4210_NCPUS);
99
+ busdev = SYS_BUS_DEVICE(&s->ext_gic);
100
+ sysbus_realize(busdev, &error_fatal);
101
/* Map CPU interface */
102
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
103
/* Map Distributer interface */
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
105
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
106
}
50
}
107
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
51
108
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
52
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
109
+ s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
53
goto gen_invep;
110
}
54
}
111
55
112
/* Internal Interrupt Combiner */
56
- if (!v7m_read_half_insn(cpu, mmu_idx, env->regs[15] + 2, &insn)) {
113
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
57
+ if (!v7m_read_half_insn(cpu, mmu_idx, true, env->regs[15] + 2, &insn)) {
58
return false;
114
}
59
}
115
60
116
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
117
+ object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
118
}
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
--
61
--
177
2.25.1
62
2.25.1
63
64
diff view generated by jsdifflib
1
It's not possible to provide the guest with the Security extensions
1
From: Richard Henderson <richard.henderson@linaro.org>
2
(TrustZone) when using KVM or HVF, because the hardware
3
virtualization extensions don't permit running EL3 guest code.
4
However, we weren't checking for this combination, with the result
5
that QEMU would assert if you tried it:
6
2
7
$ qemu-system-aarch64 -enable-kvm -machine virt,secure=on -cpu host -display none
3
Remove the use of regime_is_secure from arm_tr_init_disas_context.
8
Unexpected error in object_property_find_err() at ../../qom/object.c:1304:
4
Instead, provide the value of v8m_secure directly from tb_flags.
9
qemu-system-aarch64: Property 'host-arm-cpu.secure-memory' not found
5
Rather than use regime_is_secure, use the env->v7m.secure directly,
10
Aborted
6
as per arm_mmu_idx_el.
11
7
12
Check for this combination of options and report an error, in the
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
same way we already do for attempts to give a KVM or HVF guest the
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Virtualization or MTE extensions. Now we will report:
10
Message-id: 20221001162318.153420-8-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/cpu.h | 2 ++
14
target/arm/helper.c | 4 ++++
15
target/arm/translate.c | 3 +--
16
3 files changed, 7 insertions(+), 2 deletions(-)
15
17
16
qemu-system-aarch64: mach-virt: KVM does not support providing Security extensions (TrustZone) to the guest CPU
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
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
19
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/virt.c
20
--- a/target/arm/cpu.h
29
+++ b/hw/arm/virt.c
21
+++ b/target/arm/cpu.h
30
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
22
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_M32, NEW_FP_CTXT_NEEDED, 3, 1) /* Not cached. */
31
exit(1);
23
FIELD(TBFLAG_M32, FPCCR_S_WRONG, 4, 1) /* Not cached. */
24
/* Set if MVE insns are definitely not predicated by VPR or LTPSIZE */
25
FIELD(TBFLAG_M32, MVE_NO_PRED, 5, 1) /* Not cached. */
26
+/* Set if in secure mode */
27
+FIELD(TBFLAG_M32, SECURE, 6, 1)
28
29
/*
30
* Bit usage when in AArch64 state
31
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/helper.c
34
+++ b/target/arm/helper.c
35
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el,
36
DP_TBFLAG_M32(flags, STACKCHECK, 1);
32
}
37
}
33
38
34
+ if (vms->secure && (kvm_enabled() || hvf_enabled())) {
39
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) && env->v7m.secure) {
35
+ error_report("mach-virt: %s does not support providing "
40
+ DP_TBFLAG_M32(flags, SECURE, 1);
36
+ "Security extensions (TrustZone) to the guest CPU",
37
+ kvm_enabled() ? "KVM" : "HVF");
38
+ exit(1);
39
+ }
41
+ }
40
+
42
+
41
if (vms->virt && (kvm_enabled() || hvf_enabled())) {
43
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
42
error_report("mach-virt: %s does not support providing "
44
}
43
"Virtualization extensions to the guest CPU",
45
46
diff --git a/target/arm/translate.c b/target/arm/translate.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate.c
49
+++ b/target/arm/translate.c
50
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
51
dc->vfp_enabled = 1;
52
dc->be_data = MO_TE;
53
dc->v7m_handler_mode = EX_TBFLAG_M32(tb_flags, HANDLER);
54
- dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
55
- regime_is_secure(env, dc->mmu_idx);
56
+ dc->v8m_secure = EX_TBFLAG_M32(tb_flags, SECURE);
57
dc->v8m_stackcheck = EX_TBFLAG_M32(tb_flags, STACKCHECK);
58
dc->v8m_fpccr_s_wrong = EX_TBFLAG_M32(tb_flags, FPCCR_S_WRONG);
59
dc->v7m_new_fp_ctxt_needed =
44
--
60
--
45
2.25.1
61
2.25.1
diff view generated by jsdifflib
1
The function exynos4210_combiner_get_gpioin() currently lives in
1
From: Richard Henderson <richard.henderson@linaro.org>
2
exynos4210_combiner.c, but it isn't really part of the combiner
3
device itself -- it is a function that implements the wiring up of
4
some interrupt sources to multiple combiner inputs. Move it to live
5
with the other SoC-level code in exynos4210.c, along with a few
6
macros previously defined in exynos4210.h which are now used only
7
in exynos4210.c.
8
2
3
This is the last use of regime_is_secure; remove it
4
entirely before changing the layout of ARMMMUIdx.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20221001162318.153420-9-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-11-peter.maydell@linaro.org
12
---
10
---
13
include/hw/arm/exynos4210.h | 11 -----
11
target/arm/internals.h | 42 ----------------------------------------
14
hw/arm/exynos4210.c | 82 +++++++++++++++++++++++++++++++++++
12
target/arm/ptw.c | 44 ++++++++++++++++++++++++++++++++++++++++--
15
hw/intc/exynos4210_combiner.c | 77 --------------------------------
13
2 files changed, 42 insertions(+), 44 deletions(-)
16
3 files changed, 82 insertions(+), 88 deletions(-)
17
14
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/exynos4210.h
17
--- a/target/arm/internals.h
21
+++ b/include/hw/arm/exynos4210.h
18
+++ b/target/arm/internals.h
22
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static inline bool regime_has_2_ranges(ARMMMUIdx mmu_idx)
23
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
20
}
24
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
25
26
-#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp)*8 + (bit))
27
-#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
28
-#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
29
- ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
30
-
31
/* IRQs number for external and internal GIC */
32
#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
33
#define EXYNOS4210_INT_GIC_NIRQ 64
34
@@ -XXX,XX +XXX,XX @@ void exynos4210_write_secondary(ARMCPU *cpu,
35
* bit - bit number inside group */
36
uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit);
37
38
-/*
39
- * Get Combiner input GPIO into irqs structure
40
- */
41
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
42
- int ext);
43
-
44
/*
45
* exynos4210 UART
46
*/
47
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/exynos4210.c
50
+++ b/hw/arm/exynos4210.c
51
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
52
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
53
};
54
55
+#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp) * 8 + (bit))
56
+#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
57
+#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
58
+ ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
59
+
60
/*
61
* Initialize board IRQs.
62
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
63
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
64
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
65
}
21
}
66
22
67
+/*
23
-/* Return true if this address translation regime is secure */
68
+ * Get Combiner input GPIO into irqs structure
24
-static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
69
+ */
70
+static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
71
+ DeviceState *dev, int ext)
72
+{
73
+ int n;
74
+ int bit;
75
+ int max;
76
+ qemu_irq *irq;
77
+
78
+ max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
79
+ EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
80
+ irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
81
+
82
+ /*
83
+ * Some IRQs of Int/External Combiner are going to two Combiners groups,
84
+ * so let split them.
85
+ */
86
+ for (n = 0; n < max; n++) {
87
+
88
+ bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
89
+
90
+ switch (n) {
91
+ /* MDNIE_LCD1 INTG1 */
92
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
93
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
94
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
95
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
96
+ continue;
97
+
98
+ /* TMU INTG3 */
99
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
100
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
101
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
102
+ continue;
103
+
104
+ /* LCD1 INTG12 */
105
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
106
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
107
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
108
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
109
+ continue;
110
+
111
+ /* Multi-Core Timer INTG12 */
112
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
113
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
114
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
115
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
116
+ continue;
117
+
118
+ /* Multi-Core Timer INTG35 */
119
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
120
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
121
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
122
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
123
+ continue;
124
+
125
+ /* Multi-Core Timer INTG51 */
126
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
127
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
128
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
129
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
130
+ continue;
131
+
132
+ /* Multi-Core Timer INTG53 */
133
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
134
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
135
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
136
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
137
+ continue;
138
+ }
139
+
140
+ irq[n] = qdev_get_gpio_in(dev, n);
141
+ }
142
+}
143
+
144
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
145
0x09, 0x00, 0x00, 0x00 };
146
147
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
148
index XXXXXXX..XXXXXXX 100644
149
--- a/hw/intc/exynos4210_combiner.c
150
+++ b/hw/intc/exynos4210_combiner.c
151
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_exynos4210_combiner = {
152
}
153
};
154
155
-/*
156
- * Get Combiner input GPIO into irqs structure
157
- */
158
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
159
- int ext)
160
-{
25
-{
161
- int n;
26
- switch (mmu_idx) {
162
- int bit;
27
- case ARMMMUIdx_E10_0:
163
- int max;
28
- case ARMMMUIdx_E10_1:
164
- qemu_irq *irq;
29
- case ARMMMUIdx_E10_1_PAN:
165
-
30
- case ARMMMUIdx_E20_0:
166
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
31
- case ARMMMUIdx_E20_2:
167
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
32
- case ARMMMUIdx_E20_2_PAN:
168
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
33
- case ARMMMUIdx_Stage1_E0:
169
-
34
- case ARMMMUIdx_Stage1_E1:
170
- /*
35
- case ARMMMUIdx_Stage1_E1_PAN:
171
- * Some IRQs of Int/External Combiner are going to two Combiners groups,
36
- case ARMMMUIdx_E2:
172
- * so let split them.
37
- case ARMMMUIdx_Stage2:
173
- */
38
- case ARMMMUIdx_MPrivNegPri:
174
- for (n = 0; n < max; n++) {
39
- case ARMMMUIdx_MUserNegPri:
175
-
40
- case ARMMMUIdx_MPriv:
176
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
41
- case ARMMMUIdx_MUser:
177
-
42
- return false;
178
- switch (n) {
43
- case ARMMMUIdx_SE3:
179
- /* MDNIE_LCD1 INTG1 */
44
- case ARMMMUIdx_SE10_0:
180
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
45
- case ARMMMUIdx_SE10_1:
181
- EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
46
- case ARMMMUIdx_SE10_1_PAN:
182
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
47
- case ARMMMUIdx_SE20_0:
183
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
48
- case ARMMMUIdx_SE20_2:
184
- continue;
49
- case ARMMMUIdx_SE20_2_PAN:
185
-
50
- case ARMMMUIdx_Stage1_SE0:
186
- /* TMU INTG3 */
51
- case ARMMMUIdx_Stage1_SE1:
187
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
52
- case ARMMMUIdx_Stage1_SE1_PAN:
188
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
53
- case ARMMMUIdx_SE2:
189
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
54
- case ARMMMUIdx_Stage2_S:
190
- continue;
55
- case ARMMMUIdx_MSPrivNegPri:
191
-
56
- case ARMMMUIdx_MSUserNegPri:
192
- /* LCD1 INTG12 */
57
- case ARMMMUIdx_MSPriv:
193
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
58
- case ARMMMUIdx_MSUser:
194
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
59
- return true;
195
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
60
- default:
196
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
61
- g_assert_not_reached();
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
- }
62
- }
230
-}
63
-}
231
-
64
-
232
static uint64_t
65
static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
233
exynos4210_combiner_read(void *opaque, hwaddr offset, unsigned size)
234
{
66
{
67
switch (mmu_idx) {
68
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/ptw.c
71
+++ b/target/arm/ptw.c
72
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
73
MMUAccessType access_type, ARMMMUIdx mmu_idx,
74
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
75
{
76
+ bool is_secure;
77
+
78
+ switch (mmu_idx) {
79
+ case ARMMMUIdx_E10_0:
80
+ case ARMMMUIdx_E10_1:
81
+ case ARMMMUIdx_E10_1_PAN:
82
+ case ARMMMUIdx_E20_0:
83
+ case ARMMMUIdx_E20_2:
84
+ case ARMMMUIdx_E20_2_PAN:
85
+ case ARMMMUIdx_Stage1_E0:
86
+ case ARMMMUIdx_Stage1_E1:
87
+ case ARMMMUIdx_Stage1_E1_PAN:
88
+ case ARMMMUIdx_E2:
89
+ case ARMMMUIdx_Stage2:
90
+ case ARMMMUIdx_MPrivNegPri:
91
+ case ARMMMUIdx_MUserNegPri:
92
+ case ARMMMUIdx_MPriv:
93
+ case ARMMMUIdx_MUser:
94
+ is_secure = false;
95
+ break;
96
+ case ARMMMUIdx_SE3:
97
+ case ARMMMUIdx_SE10_0:
98
+ case ARMMMUIdx_SE10_1:
99
+ case ARMMMUIdx_SE10_1_PAN:
100
+ case ARMMMUIdx_SE20_0:
101
+ case ARMMMUIdx_SE20_2:
102
+ case ARMMMUIdx_SE20_2_PAN:
103
+ case ARMMMUIdx_Stage1_SE0:
104
+ case ARMMMUIdx_Stage1_SE1:
105
+ case ARMMMUIdx_Stage1_SE1_PAN:
106
+ case ARMMMUIdx_SE2:
107
+ case ARMMMUIdx_Stage2_S:
108
+ case ARMMMUIdx_MSPrivNegPri:
109
+ case ARMMMUIdx_MSUserNegPri:
110
+ case ARMMMUIdx_MSPriv:
111
+ case ARMMMUIdx_MSUser:
112
+ is_secure = true;
113
+ break;
114
+ default:
115
+ g_assert_not_reached();
116
+ }
117
return get_phys_addr_with_secure(env, address, access_type, mmu_idx,
118
- regime_is_secure(env, mmu_idx),
119
- result, fi);
120
+ is_secure, result, fi);
121
}
122
123
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
235
--
124
--
236
2.25.1
125
2.25.1
diff view generated by jsdifflib
1
The Exynos4210 SoC device currently uses a custom device
1
From: Richard Henderson <richard.henderson@linaro.org>
2
"exynos4210.irq_gate" to model the OR gate that feeds each CPU's IRQ
3
line. We have a standard TYPE_OR_IRQ device for this now, so use
4
that instead.
5
2
6
(This is a migration compatibility break, but that is OK for this
3
Use get_phys_addr_with_secure directly. For a-profile, this is the
7
machine type.)
4
one place where the value of is_secure may not equal arm_is_secure(env).
8
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20221001162318.153420-10-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-2-peter.maydell@linaro.org
12
---
10
---
13
include/hw/arm/exynos4210.h | 1 +
11
target/arm/helper.c | 19 ++++++++++++++-----
14
hw/arm/exynos4210.c | 31 ++++++++++++++++---------------
12
1 file changed, 14 insertions(+), 5 deletions(-)
15
2 files changed, 17 insertions(+), 15 deletions(-)
16
13
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
16
--- a/target/arm/helper.c
20
+++ b/include/hw/arm/exynos4210.h
17
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
18
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
22
MemoryRegion bootreg_mem;
19
23
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
20
#ifdef CONFIG_TCG
24
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
21
static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
25
+ qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
22
- MMUAccessType access_type, ARMMMUIdx mmu_idx)
26
};
23
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
27
24
+ bool is_secure)
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
{
25
{
35
Exynos4210State *s = EXYNOS4210_SOC(socdev);
26
bool ret;
36
MemoryRegion *system_mem = get_system_memory();
27
uint64_t par64;
37
- qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
28
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
38
SysBusDevice *busdev;
29
ARMMMUFaultInfo fi = {};
39
DeviceState *dev, *uart[4], *pl330[3];
30
GetPhysAddrResult res = {};
40
int i, n;
31
41
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
32
- ret = get_phys_addr(env, value, access_type, mmu_idx, &res, &fi);
42
33
+ ret = get_phys_addr_with_secure(env, value, access_type, mmu_idx,
43
/* IRQ Gate */
34
+ is_secure, &res, &fi);
44
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
35
45
- dev = qdev_new("exynos4210.irq_gate");
36
/*
46
- qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
37
* ATS operations only do S1 or S1+S2 translations, so we never
47
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
38
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
48
- /* Get IRQ Gate input in gate_irq */
39
switch (el) {
49
- for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
40
case 3:
50
- gate_irq[i][n] = qdev_get_gpio_in(dev, n);
41
mmu_idx = ARMMMUIdx_SE3;
51
- }
42
+ secure = true;
52
- busdev = SYS_BUS_DEVICE(dev);
43
break;
53
-
44
case 2:
54
- /* Connect IRQ Gate output to CPU's IRQ line */
45
g_assert(!secure); /* ARMv8.4-SecEL2 is 64-bit only */
55
- sysbus_connect_irq(busdev, 0,
46
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
56
- qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
47
switch (el) {
57
+ DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
48
case 3:
58
+ object_property_set_int(OBJECT(orgate), "num-lines",
49
mmu_idx = ARMMMUIdx_SE10_0;
59
+ EXYNOS4210_IRQ_GATE_NINPUTS,
50
+ secure = true;
60
+ &error_abort);
51
break;
61
+ qdev_realize(orgate, NULL, &error_abort);
52
case 2:
62
+ qdev_connect_gpio_out(orgate, 0,
53
g_assert(!secure); /* ARMv8.4-SecEL2 is 64-bit only */
63
+ qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
54
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
55
case 4:
56
/* stage 1+2 NonSecure PL1: ATS12NSOPR, ATS12NSOPW */
57
mmu_idx = ARMMMUIdx_E10_1;
58
+ secure = false;
59
break;
60
case 6:
61
/* stage 1+2 NonSecure PL0: ATS12NSOUR, ATS12NSOUW */
62
mmu_idx = ARMMMUIdx_E10_0;
63
+ secure = false;
64
break;
65
default:
66
g_assert_not_reached();
64
}
67
}
65
68
66
/* Private memory region and Internal GIC */
69
- par64 = do_ats_write(env, value, access_type, mmu_idx);
67
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
70
+ par64 = do_ats_write(env, value, access_type, mmu_idx, secure);
68
sysbus_realize_and_unref(busdev, &error_fatal);
71
69
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
72
A32_BANKED_CURRENT_REG_SET(env, par, par64);
70
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
73
#else
71
- sysbus_connect_irq(busdev, n, gate_irq[n][0]);
74
@@ -XXX,XX +XXX,XX @@ static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri,
72
+ sysbus_connect_irq(busdev, n,
75
MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
73
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
76
uint64_t par64;
77
78
- par64 = do_ats_write(env, value, access_type, ARMMMUIdx_E2);
79
+ /* There is no SecureEL2 for AArch32. */
80
+ par64 = do_ats_write(env, value, access_type, ARMMMUIdx_E2, false);
81
82
A32_BANKED_CURRENT_REG_SET(env, par, par64);
83
#else
84
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
85
break;
86
case 6: /* AT S1E3R, AT S1E3W */
87
mmu_idx = ARMMMUIdx_SE3;
88
+ secure = true;
89
break;
90
default:
91
g_assert_not_reached();
92
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
93
g_assert_not_reached();
74
}
94
}
75
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
95
76
s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
96
- env->cp15.par_el[1] = do_ats_write(env, value, access_type, mmu_idx);
77
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
97
+ env->cp15.par_el[1] = do_ats_write(env, value, access_type,
78
/* Map Distributer interface */
98
+ mmu_idx, secure);
79
sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
99
#else
80
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
100
/* Handled by hardware accelerator. */
81
- sysbus_connect_irq(busdev, n, gate_irq[n][1]);
101
g_assert_not_reached();
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
--
102
--
100
2.25.1
103
2.25.1
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
For a-profile aarch64, which does not bank system registers, it takes
4
quite a lot of code to switch between security states. In the process,
5
registers such as TCR_EL{1,2} must be swapped, which in itself requires
6
the flushing of softmmu tlbs. Therefore it doesn't buy us anything to
7
separate tlbs by security state.
8
9
Retain the distinction between Stage2 and Stage2_S.
10
11
This will be important as we implement FEAT_RME, and do not wish to
12
add a third set of mmu indexes for Realm state.
13
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20221001162318.153420-11-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
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
---
18
---
8
hw/intc/exynos4210_gic.c | 107 ---------------------------------------
19
target/arm/cpu-param.h | 2 +-
9
1 file changed, 107 deletions(-)
20
target/arm/cpu.h | 72 +++++++------------
21
target/arm/internals.h | 31 +-------
22
target/arm/helper.c | 144 +++++++++++++------------------------
23
target/arm/ptw.c | 25 ++-----
24
target/arm/translate-a64.c | 8 ---
25
target/arm/translate.c | 6 +-
26
7 files changed, 85 insertions(+), 203 deletions(-)
10
27
11
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
28
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
12
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/intc/exynos4210_gic.c
30
--- a/target/arm/cpu-param.h
14
+++ b/hw/intc/exynos4210_gic.c
31
+++ b/target/arm/cpu-param.h
15
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_register_types(void)
32
@@ -XXX,XX +XXX,XX @@
16
}
33
# define TARGET_PAGE_BITS_MIN 10
17
34
#endif
18
type_init(exynos4210_gic_register_types)
35
19
-
36
-#define NB_MMU_MODES 15
20
-/* IRQ OR Gate struct.
37
+#define NB_MMU_MODES 8
21
- *
38
22
- * This device models an OR gate. There are n_in input qdev gpio lines and one
39
#endif
23
- * output sysbus IRQ line. The output IRQ level is formed as OR between all
40
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
- * gpio inputs.
41
index XXXXXXX..XXXXXXX 100644
25
- */
42
--- a/target/arm/cpu.h
26
-
43
+++ b/target/arm/cpu.h
27
-#define TYPE_EXYNOS4210_IRQ_GATE "exynos4210.irq_gate"
44
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
28
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210IRQGateState, EXYNOS4210_IRQ_GATE)
45
* table over and over.
29
-
46
* 6. we need separate EL1/EL2 mmu_idx for handling the Privileged Access
30
-struct Exynos4210IRQGateState {
47
* Never (PAN) bit within PSTATE.
31
- SysBusDevice parent_obj;
48
+ * 7. we fold together the secure and non-secure regimes for A-profile,
32
-
49
+ * because there are no banked system registers for aarch64, so the
33
- uint32_t n_in; /* inputs amount */
50
+ * process of switching between secure and non-secure is
34
- uint32_t *level; /* input levels */
51
+ * already heavyweight.
35
- qemu_irq out; /* output IRQ */
52
*
36
-};
53
* This gives us the following list of cases:
37
-
54
*
38
-static Property exynos4210_irq_gate_properties[] = {
55
- * NS EL0 EL1&0 stage 1+2 (aka NS PL0)
39
- DEFINE_PROP_UINT32("n_in", Exynos4210IRQGateState, n_in, 1),
56
- * NS EL1 EL1&0 stage 1+2 (aka NS PL1)
40
- DEFINE_PROP_END_OF_LIST(),
57
- * NS EL1 EL1&0 stage 1+2 +PAN
41
-};
58
- * NS EL0 EL2&0
42
-
59
- * NS EL2 EL2&0
43
-static const VMStateDescription vmstate_exynos4210_irq_gate = {
60
- * NS EL2 EL2&0 +PAN
44
- .name = "exynos4210.irq_gate",
61
- * NS EL2 (aka NS PL2)
45
- .version_id = 2,
62
- * S EL0 EL1&0 (aka S PL0)
46
- .minimum_version_id = 2,
63
- * S EL1 EL1&0 (not used if EL3 is 32 bit)
47
- .fields = (VMStateField[]) {
64
- * S EL1 EL1&0 +PAN
48
- VMSTATE_VBUFFER_UINT32(level, Exynos4210IRQGateState, 1, NULL, n_in),
65
- * S EL3 (aka S PL1)
49
- VMSTATE_END_OF_LIST()
66
+ * EL0 EL1&0 stage 1+2 (aka NS PL0)
67
+ * EL1 EL1&0 stage 1+2 (aka NS PL1)
68
+ * EL1 EL1&0 stage 1+2 +PAN
69
+ * EL0 EL2&0
70
+ * EL2 EL2&0
71
+ * EL2 EL2&0 +PAN
72
+ * EL2 (aka NS PL2)
73
+ * EL3 (aka S PL1)
74
*
75
- * for a total of 11 different mmu_idx.
76
+ * for a total of 8 different mmu_idx.
77
*
78
* R profile CPUs have an MPU, but can use the same set of MMU indexes
79
- * as A profile. They only need to distinguish NS EL0 and NS EL1 (and
80
- * NS EL2 if we ever model a Cortex-R52).
81
+ * as A profile. They only need to distinguish EL0 and EL1 (and
82
+ * EL2 if we ever model a Cortex-R52).
83
*
84
* M profile CPUs are rather different as they do not have a true MMU.
85
* They have the following different MMU indexes:
86
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
87
#define ARM_MMU_IDX_NOTLB 0x20 /* does not have a TLB */
88
#define ARM_MMU_IDX_M 0x40 /* M profile */
89
90
-/* Meanings of the bits for A profile mmu idx values */
91
-#define ARM_MMU_IDX_A_NS 0x8
92
-
93
/* Meanings of the bits for M profile mmu idx values */
94
#define ARM_MMU_IDX_M_PRIV 0x1
95
#define ARM_MMU_IDX_M_NEGPRI 0x2
96
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
97
/*
98
* A-profile.
99
*/
100
- ARMMMUIdx_SE10_0 = 0 | ARM_MMU_IDX_A,
101
- ARMMMUIdx_SE20_0 = 1 | ARM_MMU_IDX_A,
102
- ARMMMUIdx_SE10_1 = 2 | ARM_MMU_IDX_A,
103
- ARMMMUIdx_SE20_2 = 3 | ARM_MMU_IDX_A,
104
- ARMMMUIdx_SE10_1_PAN = 4 | ARM_MMU_IDX_A,
105
- ARMMMUIdx_SE20_2_PAN = 5 | ARM_MMU_IDX_A,
106
- ARMMMUIdx_SE2 = 6 | ARM_MMU_IDX_A,
107
- ARMMMUIdx_SE3 = 7 | ARM_MMU_IDX_A,
108
-
109
- ARMMMUIdx_E10_0 = ARMMMUIdx_SE10_0 | ARM_MMU_IDX_A_NS,
110
- ARMMMUIdx_E20_0 = ARMMMUIdx_SE20_0 | ARM_MMU_IDX_A_NS,
111
- ARMMMUIdx_E10_1 = ARMMMUIdx_SE10_1 | ARM_MMU_IDX_A_NS,
112
- ARMMMUIdx_E20_2 = ARMMMUIdx_SE20_2 | ARM_MMU_IDX_A_NS,
113
- ARMMMUIdx_E10_1_PAN = ARMMMUIdx_SE10_1_PAN | ARM_MMU_IDX_A_NS,
114
- ARMMMUIdx_E20_2_PAN = ARMMMUIdx_SE20_2_PAN | ARM_MMU_IDX_A_NS,
115
- ARMMMUIdx_E2 = ARMMMUIdx_SE2 | ARM_MMU_IDX_A_NS,
116
+ ARMMMUIdx_E10_0 = 0 | ARM_MMU_IDX_A,
117
+ ARMMMUIdx_E20_0 = 1 | ARM_MMU_IDX_A,
118
+ ARMMMUIdx_E10_1 = 2 | ARM_MMU_IDX_A,
119
+ ARMMMUIdx_E20_2 = 3 | ARM_MMU_IDX_A,
120
+ ARMMMUIdx_E10_1_PAN = 4 | ARM_MMU_IDX_A,
121
+ ARMMMUIdx_E20_2_PAN = 5 | ARM_MMU_IDX_A,
122
+ ARMMMUIdx_E2 = 6 | ARM_MMU_IDX_A,
123
+ ARMMMUIdx_E3 = 7 | ARM_MMU_IDX_A,
124
125
/*
126
* These are not allocated TLBs and are used only for AT system
127
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
128
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
129
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
130
ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
131
- ARMMMUIdx_Stage1_SE0 = 3 | ARM_MMU_IDX_NOTLB,
132
- ARMMMUIdx_Stage1_SE1 = 4 | ARM_MMU_IDX_NOTLB,
133
- ARMMMUIdx_Stage1_SE1_PAN = 5 | ARM_MMU_IDX_NOTLB,
134
/*
135
* Not allocated a TLB: used only for second stage of an S12 page
136
* table walk, or for descriptor loads during first stage of an S1
137
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
138
* then various TLB flush insns which currently are no-ops or flush
139
* only stage 1 MMU indexes will need to change to flush stage 2.
140
*/
141
- ARMMMUIdx_Stage2 = 6 | ARM_MMU_IDX_NOTLB,
142
- ARMMMUIdx_Stage2_S = 7 | ARM_MMU_IDX_NOTLB,
143
+ ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB,
144
+ ARMMMUIdx_Stage2_S = 4 | ARM_MMU_IDX_NOTLB,
145
146
/*
147
* M-profile.
148
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
149
TO_CORE_BIT(E2),
150
TO_CORE_BIT(E20_2),
151
TO_CORE_BIT(E20_2_PAN),
152
- TO_CORE_BIT(SE10_0),
153
- TO_CORE_BIT(SE20_0),
154
- TO_CORE_BIT(SE10_1),
155
- TO_CORE_BIT(SE20_2),
156
- TO_CORE_BIT(SE10_1_PAN),
157
- TO_CORE_BIT(SE20_2_PAN),
158
- TO_CORE_BIT(SE2),
159
- TO_CORE_BIT(SE3),
160
+ TO_CORE_BIT(E3),
161
162
TO_CORE_BIT(MUser),
163
TO_CORE_BIT(MPriv),
164
diff --git a/target/arm/internals.h b/target/arm/internals.h
165
index XXXXXXX..XXXXXXX 100644
166
--- a/target/arm/internals.h
167
+++ b/target/arm/internals.h
168
@@ -XXX,XX +XXX,XX @@ static inline bool regime_has_2_ranges(ARMMMUIdx mmu_idx)
169
case ARMMMUIdx_Stage1_E0:
170
case ARMMMUIdx_Stage1_E1:
171
case ARMMMUIdx_Stage1_E1_PAN:
172
- case ARMMMUIdx_Stage1_SE0:
173
- case ARMMMUIdx_Stage1_SE1:
174
- case ARMMMUIdx_Stage1_SE1_PAN:
175
case ARMMMUIdx_E10_0:
176
case ARMMMUIdx_E10_1:
177
case ARMMMUIdx_E10_1_PAN:
178
case ARMMMUIdx_E20_0:
179
case ARMMMUIdx_E20_2:
180
case ARMMMUIdx_E20_2_PAN:
181
- case ARMMMUIdx_SE10_0:
182
- case ARMMMUIdx_SE10_1:
183
- case ARMMMUIdx_SE10_1_PAN:
184
- case ARMMMUIdx_SE20_0:
185
- case ARMMMUIdx_SE20_2:
186
- case ARMMMUIdx_SE20_2_PAN:
187
return true;
188
default:
189
return false;
190
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
191
{
192
switch (mmu_idx) {
193
case ARMMMUIdx_Stage1_E1_PAN:
194
- case ARMMMUIdx_Stage1_SE1_PAN:
195
case ARMMMUIdx_E10_1_PAN:
196
case ARMMMUIdx_E20_2_PAN:
197
- case ARMMMUIdx_SE10_1_PAN:
198
- case ARMMMUIdx_SE20_2_PAN:
199
return true;
200
default:
201
return false;
202
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
203
static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
204
{
205
switch (mmu_idx) {
206
- case ARMMMUIdx_SE20_0:
207
- case ARMMMUIdx_SE20_2:
208
- case ARMMMUIdx_SE20_2_PAN:
209
case ARMMMUIdx_E20_0:
210
case ARMMMUIdx_E20_2:
211
case ARMMMUIdx_E20_2_PAN:
212
case ARMMMUIdx_Stage2:
213
case ARMMMUIdx_Stage2_S:
214
- case ARMMMUIdx_SE2:
215
case ARMMMUIdx_E2:
216
return 2;
217
- case ARMMMUIdx_SE3:
218
+ case ARMMMUIdx_E3:
219
return 3;
220
- case ARMMMUIdx_SE10_0:
221
- case ARMMMUIdx_Stage1_SE0:
222
- return arm_el_is_aa64(env, 3) ? 1 : 3;
223
- case ARMMMUIdx_SE10_1:
224
- case ARMMMUIdx_SE10_1_PAN:
225
+ case ARMMMUIdx_E10_0:
226
case ARMMMUIdx_Stage1_E0:
227
+ return arm_el_is_aa64(env, 3) || !arm_is_secure_below_el3(env) ? 1 : 3;
228
case ARMMMUIdx_Stage1_E1:
229
case ARMMMUIdx_Stage1_E1_PAN:
230
- case ARMMMUIdx_Stage1_SE1:
231
- case ARMMMUIdx_Stage1_SE1_PAN:
232
- case ARMMMUIdx_E10_0:
233
case ARMMMUIdx_E10_1:
234
case ARMMMUIdx_E10_1_PAN:
235
case ARMMMUIdx_MPrivNegPri:
236
@@ -XXX,XX +XXX,XX @@ static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx)
237
case ARMMMUIdx_Stage1_E0:
238
case ARMMMUIdx_Stage1_E1:
239
case ARMMMUIdx_Stage1_E1_PAN:
240
- case ARMMMUIdx_Stage1_SE0:
241
- case ARMMMUIdx_Stage1_SE1:
242
- case ARMMMUIdx_Stage1_SE1_PAN:
243
return true;
244
default:
245
return false;
246
diff --git a/target/arm/helper.c b/target/arm/helper.c
247
index XXXXXXX..XXXXXXX 100644
248
--- a/target/arm/helper.c
249
+++ b/target/arm/helper.c
250
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
251
/* Begin with base v8.0 state. */
252
uint64_t valid_mask = 0x3fff;
253
ARMCPU *cpu = env_archcpu(env);
254
+ uint64_t changed;
255
256
/*
257
* Because SCR_EL3 is the "real" cpreg and SCR is the alias, reset always
258
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
259
260
/* Clear all-context RES0 bits. */
261
value &= valid_mask;
262
- raw_write(env, ri, value);
263
+ changed = env->cp15.scr_el3 ^ value;
264
+ env->cp15.scr_el3 = value;
265
+
266
+ /*
267
+ * If SCR_EL3.NS changes, i.e. arm_is_secure_below_el3, then
268
+ * we must invalidate all TLBs below EL3.
269
+ */
270
+ if (changed & SCR_NS) {
271
+ tlb_flush_by_mmuidx(env_cpu(env), (ARMMMUIdxBit_E10_0 |
272
+ ARMMMUIdxBit_E20_0 |
273
+ ARMMMUIdxBit_E10_1 |
274
+ ARMMMUIdxBit_E20_2 |
275
+ ARMMMUIdxBit_E10_1_PAN |
276
+ ARMMMUIdxBit_E20_2_PAN |
277
+ ARMMMUIdxBit_E2));
278
+ }
279
}
280
281
static void scr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
282
@@ -XXX,XX +XXX,XX @@ static int gt_phys_redir_timeridx(CPUARMState *env)
283
case ARMMMUIdx_E20_0:
284
case ARMMMUIdx_E20_2:
285
case ARMMMUIdx_E20_2_PAN:
286
- case ARMMMUIdx_SE20_0:
287
- case ARMMMUIdx_SE20_2:
288
- case ARMMMUIdx_SE20_2_PAN:
289
return GTIMER_HYP;
290
default:
291
return GTIMER_PHYS;
292
@@ -XXX,XX +XXX,XX @@ static int gt_virt_redir_timeridx(CPUARMState *env)
293
case ARMMMUIdx_E20_0:
294
case ARMMMUIdx_E20_2:
295
case ARMMMUIdx_E20_2_PAN:
296
- case ARMMMUIdx_SE20_0:
297
- case ARMMMUIdx_SE20_2:
298
- case ARMMMUIdx_SE20_2_PAN:
299
return GTIMER_HYPVIRT;
300
default:
301
return GTIMER_VIRT;
302
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
303
/* stage 1 current state PL1: ATS1CPR, ATS1CPW, ATS1CPRP, ATS1CPWP */
304
switch (el) {
305
case 3:
306
- mmu_idx = ARMMMUIdx_SE3;
307
+ mmu_idx = ARMMMUIdx_E3;
308
secure = true;
309
break;
310
case 2:
311
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
312
/* fall through */
313
case 1:
314
if (ri->crm == 9 && (env->uncached_cpsr & CPSR_PAN)) {
315
- mmu_idx = (secure ? ARMMMUIdx_Stage1_SE1_PAN
316
- : ARMMMUIdx_Stage1_E1_PAN);
317
+ mmu_idx = ARMMMUIdx_Stage1_E1_PAN;
318
} else {
319
- mmu_idx = secure ? ARMMMUIdx_Stage1_SE1 : ARMMMUIdx_Stage1_E1;
320
+ mmu_idx = ARMMMUIdx_Stage1_E1;
321
}
322
break;
323
default:
324
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
325
/* stage 1 current state PL0: ATS1CUR, ATS1CUW */
326
switch (el) {
327
case 3:
328
- mmu_idx = ARMMMUIdx_SE10_0;
329
+ mmu_idx = ARMMMUIdx_E10_0;
330
secure = true;
331
break;
332
case 2:
333
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
334
mmu_idx = ARMMMUIdx_Stage1_E0;
335
break;
336
case 1:
337
- mmu_idx = secure ? ARMMMUIdx_Stage1_SE0 : ARMMMUIdx_Stage1_E0;
338
+ mmu_idx = ARMMMUIdx_Stage1_E0;
339
break;
340
default:
341
g_assert_not_reached();
342
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
343
switch (ri->opc1) {
344
case 0: /* AT S1E1R, AT S1E1W, AT S1E1RP, AT S1E1WP */
345
if (ri->crm == 9 && (env->pstate & PSTATE_PAN)) {
346
- mmu_idx = (secure ? ARMMMUIdx_Stage1_SE1_PAN
347
- : ARMMMUIdx_Stage1_E1_PAN);
348
+ mmu_idx = ARMMMUIdx_Stage1_E1_PAN;
349
} else {
350
- mmu_idx = secure ? ARMMMUIdx_Stage1_SE1 : ARMMMUIdx_Stage1_E1;
351
+ mmu_idx = ARMMMUIdx_Stage1_E1;
352
}
353
break;
354
case 4: /* AT S1E2R, AT S1E2W */
355
- mmu_idx = secure ? ARMMMUIdx_SE2 : ARMMMUIdx_E2;
356
+ mmu_idx = ARMMMUIdx_E2;
357
break;
358
case 6: /* AT S1E3R, AT S1E3W */
359
- mmu_idx = ARMMMUIdx_SE3;
360
+ mmu_idx = ARMMMUIdx_E3;
361
secure = true;
362
break;
363
default:
364
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
365
}
366
break;
367
case 2: /* AT S1E0R, AT S1E0W */
368
- mmu_idx = secure ? ARMMMUIdx_Stage1_SE0 : ARMMMUIdx_Stage1_E0;
369
+ mmu_idx = ARMMMUIdx_Stage1_E0;
370
break;
371
case 4: /* AT S12E1R, AT S12E1W */
372
- mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_E10_1;
373
+ mmu_idx = ARMMMUIdx_E10_1;
374
break;
375
case 6: /* AT S12E0R, AT S12E0W */
376
- mmu_idx = secure ? ARMMMUIdx_SE10_0 : ARMMMUIdx_E10_0;
377
+ mmu_idx = ARMMMUIdx_E10_0;
378
break;
379
default:
380
g_assert_not_reached();
381
@@ -XXX,XX +XXX,XX @@ static void vmsa_tcr_ttbr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
382
uint16_t mask = ARMMMUIdxBit_E20_2 |
383
ARMMMUIdxBit_E20_2_PAN |
384
ARMMMUIdxBit_E20_0;
385
-
386
- if (arm_is_secure_below_el3(env)) {
387
- mask >>= ARM_MMU_IDX_A_NS;
388
- }
389
-
390
tlb_flush_by_mmuidx(env_cpu(env), mask);
391
}
392
raw_write(env, ri, value);
393
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
394
uint16_t mask = ARMMMUIdxBit_E10_1 |
395
ARMMMUIdxBit_E10_1_PAN |
396
ARMMMUIdxBit_E10_0;
397
-
398
- if (arm_is_secure_below_el3(env)) {
399
- mask >>= ARM_MMU_IDX_A_NS;
400
- }
401
-
402
tlb_flush_by_mmuidx(cs, mask);
403
raw_write(env, ri, value);
404
}
405
@@ -XXX,XX +XXX,XX @@ static int vae1_tlbmask(CPUARMState *env)
406
ARMMMUIdxBit_E10_1_PAN |
407
ARMMMUIdxBit_E10_0;
408
}
409
-
410
- if (arm_is_secure_below_el3(env)) {
411
- mask >>= ARM_MMU_IDX_A_NS;
50
- }
412
- }
51
-};
413
-
52
-
414
return mask;
53
-/* Process a change in IRQ input. */
415
}
54
-static void exynos4210_irq_gate_handler(void *opaque, int irq, int level)
416
55
-{
417
@@ -XXX,XX +XXX,XX @@ static int vae1_tlbbits(CPUARMState *env, uint64_t addr)
56
- Exynos4210IRQGateState *s = (Exynos4210IRQGateState *)opaque;
418
mmu_idx = ARMMMUIdx_E10_0;
57
- uint32_t i;
419
}
58
-
420
59
- assert(irq < s->n_in);
421
- if (arm_is_secure_below_el3(env)) {
60
-
422
- mmu_idx &= ~ARM_MMU_IDX_A_NS;
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
- }
423
- }
69
-
424
-
70
- qemu_irq_lower(s->out);
425
return tlbbits_for_regime(env, mmu_idx, addr);
71
-}
426
}
72
-
427
73
-static void exynos4210_irq_gate_reset(DeviceState *d)
428
@@ -XXX,XX +XXX,XX @@ static int alle1_tlbmask(CPUARMState *env)
74
-{
429
* stage 2 translations, whereas most other scopes only invalidate
75
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(d);
430
* stage 1 translations.
76
-
431
*/
77
- memset(s->level, 0, s->n_in * sizeof(*s->level));
432
- if (arm_is_secure_below_el3(env)) {
78
-}
433
- return ARMMMUIdxBit_SE10_1 |
79
-
434
- ARMMMUIdxBit_SE10_1_PAN |
80
-/*
435
- ARMMMUIdxBit_SE10_0;
81
- * IRQ Gate initialization.
436
- } else {
82
- */
437
- return ARMMMUIdxBit_E10_1 |
83
-static void exynos4210_irq_gate_init(Object *obj)
438
- ARMMMUIdxBit_E10_1_PAN |
84
-{
439
- ARMMMUIdxBit_E10_0;
85
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(obj);
440
- }
86
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
441
+ return (ARMMMUIdxBit_E10_1 |
87
-
442
+ ARMMMUIdxBit_E10_1_PAN |
88
- sysbus_init_irq(sbd, &s->out);
443
+ ARMMMUIdxBit_E10_0);
89
-}
444
}
90
-
445
91
-static void exynos4210_irq_gate_realize(DeviceState *dev, Error **errp)
446
static int e2_tlbmask(CPUARMState *env)
92
-{
447
{
93
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(dev);
448
- if (arm_is_secure_below_el3(env)) {
94
-
449
- return ARMMMUIdxBit_SE20_0 |
95
- /* Allocate general purpose input signals and connect a handler to each of
450
- ARMMMUIdxBit_SE20_2 |
96
- * them */
451
- ARMMMUIdxBit_SE20_2_PAN |
97
- qdev_init_gpio_in(dev, exynos4210_irq_gate_handler, s->n_in);
452
- ARMMMUIdxBit_SE2;
98
-
453
- } else {
99
- s->level = g_malloc0(s->n_in * sizeof(*s->level));
454
- return ARMMMUIdxBit_E20_0 |
100
-}
455
- ARMMMUIdxBit_E20_2 |
101
-
456
- ARMMMUIdxBit_E20_2_PAN |
102
-static void exynos4210_irq_gate_class_init(ObjectClass *klass, void *data)
457
- ARMMMUIdxBit_E2;
103
-{
458
- }
104
- DeviceClass *dc = DEVICE_CLASS(klass);
459
+ return (ARMMMUIdxBit_E20_0 |
105
-
460
+ ARMMMUIdxBit_E20_2 |
106
- dc->reset = exynos4210_irq_gate_reset;
461
+ ARMMMUIdxBit_E20_2_PAN |
107
- dc->vmsd = &vmstate_exynos4210_irq_gate;
462
+ ARMMMUIdxBit_E2);
108
- device_class_set_props(dc, exynos4210_irq_gate_properties);
463
}
109
- dc->realize = exynos4210_irq_gate_realize;
464
110
-}
465
static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
111
-
466
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle3_write(CPUARMState *env, const ARMCPRegInfo *ri,
112
-static const TypeInfo exynos4210_irq_gate_info = {
467
ARMCPU *cpu = env_archcpu(env);
113
- .name = TYPE_EXYNOS4210_IRQ_GATE,
468
CPUState *cs = CPU(cpu);
114
- .parent = TYPE_SYS_BUS_DEVICE,
469
115
- .instance_size = sizeof(Exynos4210IRQGateState),
470
- tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_SE3);
116
- .instance_init = exynos4210_irq_gate_init,
471
+ tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_E3);
117
- .class_init = exynos4210_irq_gate_class_init,
472
}
118
-};
473
119
-
474
static void tlbi_aa64_alle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
120
-static void exynos4210_irq_gate_register_types(void)
475
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
121
-{
476
{
122
- type_register_static(&exynos4210_irq_gate_info);
477
CPUState *cs = env_cpu(env);
123
-}
478
124
-
479
- tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_SE3);
125
-type_init(exynos4210_irq_gate_register_types)
480
+ tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_E3);
481
}
482
483
static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
484
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri,
485
CPUState *cs = CPU(cpu);
486
uint64_t pageaddr = sextract64(value << 12, 0, 56);
487
488
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_SE3);
489
+ tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_E3);
490
}
491
492
static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
493
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
494
{
495
CPUState *cs = env_cpu(env);
496
uint64_t pageaddr = sextract64(value << 12, 0, 56);
497
- bool secure = arm_is_secure_below_el3(env);
498
- int mask = secure ? ARMMMUIdxBit_SE2 : ARMMMUIdxBit_E2;
499
- int bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_SE2 : ARMMMUIdx_E2,
500
- pageaddr);
501
+ int bits = tlbbits_for_regime(env, ARMMMUIdx_E2, pageaddr);
502
503
- tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
504
+ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
505
+ ARMMMUIdxBit_E2, bits);
506
}
507
508
static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
509
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
510
{
511
CPUState *cs = env_cpu(env);
512
uint64_t pageaddr = sextract64(value << 12, 0, 56);
513
- int bits = tlbbits_for_regime(env, ARMMMUIdx_SE3, pageaddr);
514
+ int bits = tlbbits_for_regime(env, ARMMMUIdx_E3, pageaddr);
515
516
tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
517
- ARMMMUIdxBit_SE3, bits);
518
+ ARMMMUIdxBit_E3, bits);
519
}
520
521
#ifdef TARGET_AARCH64
522
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_rvae1is_write(CPUARMState *env,
523
524
static int vae2_tlbmask(CPUARMState *env)
525
{
526
- return (arm_is_secure_below_el3(env)
527
- ? ARMMMUIdxBit_SE2 : ARMMMUIdxBit_E2);
528
+ return ARMMMUIdxBit_E2;
529
}
530
531
static void tlbi_aa64_rvae2_write(CPUARMState *env,
532
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_rvae3_write(CPUARMState *env,
533
* flush-last-level-only.
534
*/
535
536
- do_rvae_write(env, value, ARMMMUIdxBit_SE3,
537
- tlb_force_broadcast(env));
538
+ do_rvae_write(env, value, ARMMMUIdxBit_E3, tlb_force_broadcast(env));
539
}
540
541
static void tlbi_aa64_rvae3is_write(CPUARMState *env,
542
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_rvae3is_write(CPUARMState *env,
543
* flush-last-level-only or inner/outer specific flushes.
544
*/
545
546
- do_rvae_write(env, value, ARMMMUIdxBit_SE3, true);
547
+ do_rvae_write(env, value, ARMMMUIdxBit_E3, true);
548
}
549
#endif
550
551
@@ -XXX,XX +XXX,XX @@ uint64_t arm_sctlr(CPUARMState *env, int el)
552
/* Only EL0 needs to be adjusted for EL1&0 or EL2&0. */
553
if (el == 0) {
554
ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, 0);
555
- el = (mmu_idx == ARMMMUIdx_E20_0 || mmu_idx == ARMMMUIdx_SE20_0)
556
- ? 2 : 1;
557
+ el = mmu_idx == ARMMMUIdx_E20_0 ? 2 : 1;
558
}
559
return env->cp15.sctlr_el[el];
560
}
561
@@ -XXX,XX +XXX,XX @@ int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
562
switch (mmu_idx) {
563
case ARMMMUIdx_E10_0:
564
case ARMMMUIdx_E20_0:
565
- case ARMMMUIdx_SE10_0:
566
- case ARMMMUIdx_SE20_0:
567
return 0;
568
case ARMMMUIdx_E10_1:
569
case ARMMMUIdx_E10_1_PAN:
570
- case ARMMMUIdx_SE10_1:
571
- case ARMMMUIdx_SE10_1_PAN:
572
return 1;
573
case ARMMMUIdx_E2:
574
case ARMMMUIdx_E20_2:
575
case ARMMMUIdx_E20_2_PAN:
576
- case ARMMMUIdx_SE2:
577
- case ARMMMUIdx_SE20_2:
578
- case ARMMMUIdx_SE20_2_PAN:
579
return 2;
580
- case ARMMMUIdx_SE3:
581
+ case ARMMMUIdx_E3:
582
return 3;
583
default:
584
g_assert_not_reached();
585
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
586
}
587
break;
588
case 3:
589
- return ARMMMUIdx_SE3;
590
+ return ARMMMUIdx_E3;
591
default:
592
g_assert_not_reached();
593
}
594
595
- if (arm_is_secure_below_el3(env)) {
596
- idx &= ~ARM_MMU_IDX_A_NS;
597
- }
598
-
599
return idx;
600
}
601
602
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
603
switch (mmu_idx) {
604
case ARMMMUIdx_E10_1:
605
case ARMMMUIdx_E10_1_PAN:
606
- case ARMMMUIdx_SE10_1:
607
- case ARMMMUIdx_SE10_1_PAN:
608
/* TODO: ARMv8.3-NV */
609
DP_TBFLAG_A64(flags, UNPRIV, 1);
610
break;
611
case ARMMMUIdx_E20_2:
612
case ARMMMUIdx_E20_2_PAN:
613
- case ARMMMUIdx_SE20_2:
614
- case ARMMMUIdx_SE20_2_PAN:
615
/*
616
* Note that EL20_2 is gated by HCR_EL2.E2H == 1, but EL20_0 is
617
* gated by HCR_EL2.<E2H,TGE> == '11', and so is LDTR.
618
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
619
index XXXXXXX..XXXXXXX 100644
620
--- a/target/arm/ptw.c
621
+++ b/target/arm/ptw.c
622
@@ -XXX,XX +XXX,XX @@ unsigned int arm_pamax(ARMCPU *cpu)
623
ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx)
624
{
625
switch (mmu_idx) {
626
- case ARMMMUIdx_SE10_0:
627
- return ARMMMUIdx_Stage1_SE0;
628
- case ARMMMUIdx_SE10_1:
629
- return ARMMMUIdx_Stage1_SE1;
630
- case ARMMMUIdx_SE10_1_PAN:
631
- return ARMMMUIdx_Stage1_SE1_PAN;
632
case ARMMMUIdx_E10_0:
633
return ARMMMUIdx_Stage1_E0;
634
case ARMMMUIdx_E10_1:
635
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_big_endian(CPUARMState *env, ARMMMUIdx mmu_idx)
636
static bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
637
{
638
switch (mmu_idx) {
639
- case ARMMMUIdx_SE10_0:
640
case ARMMMUIdx_E20_0:
641
- case ARMMMUIdx_SE20_0:
642
case ARMMMUIdx_Stage1_E0:
643
- case ARMMMUIdx_Stage1_SE0:
644
case ARMMMUIdx_MUser:
645
case ARMMMUIdx_MSUser:
646
case ARMMMUIdx_MUserNegPri:
647
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
648
649
s2_mmu_idx = (s2walk_secure
650
? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2);
651
- is_el0 = mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_SE10_0;
652
+ is_el0 = mmu_idx == ARMMMUIdx_E10_0;
653
654
/*
655
* S1 is done, now do S2 translation.
656
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
657
case ARMMMUIdx_Stage1_E1:
658
case ARMMMUIdx_Stage1_E1_PAN:
659
case ARMMMUIdx_E2:
660
+ is_secure = arm_is_secure_below_el3(env);
661
+ break;
662
case ARMMMUIdx_Stage2:
663
case ARMMMUIdx_MPrivNegPri:
664
case ARMMMUIdx_MUserNegPri:
665
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
666
case ARMMMUIdx_MUser:
667
is_secure = false;
668
break;
669
- case ARMMMUIdx_SE3:
670
- case ARMMMUIdx_SE10_0:
671
- case ARMMMUIdx_SE10_1:
672
- case ARMMMUIdx_SE10_1_PAN:
673
- case ARMMMUIdx_SE20_0:
674
- case ARMMMUIdx_SE20_2:
675
- case ARMMMUIdx_SE20_2_PAN:
676
- case ARMMMUIdx_Stage1_SE0:
677
- case ARMMMUIdx_Stage1_SE1:
678
- case ARMMMUIdx_Stage1_SE1_PAN:
679
- case ARMMMUIdx_SE2:
680
+ case ARMMMUIdx_E3:
681
case ARMMMUIdx_Stage2_S:
682
case ARMMMUIdx_MSPrivNegPri:
683
case ARMMMUIdx_MSUserNegPri:
684
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
685
index XXXXXXX..XXXXXXX 100644
686
--- a/target/arm/translate-a64.c
687
+++ b/target/arm/translate-a64.c
688
@@ -XXX,XX +XXX,XX @@ static int get_a64_user_mem_index(DisasContext *s)
689
case ARMMMUIdx_E20_2_PAN:
690
useridx = ARMMMUIdx_E20_0;
691
break;
692
- case ARMMMUIdx_SE10_1:
693
- case ARMMMUIdx_SE10_1_PAN:
694
- useridx = ARMMMUIdx_SE10_0;
695
- break;
696
- case ARMMMUIdx_SE20_2:
697
- case ARMMMUIdx_SE20_2_PAN:
698
- useridx = ARMMMUIdx_SE20_0;
699
- break;
700
default:
701
g_assert_not_reached();
702
}
703
diff --git a/target/arm/translate.c b/target/arm/translate.c
704
index XXXXXXX..XXXXXXX 100644
705
--- a/target/arm/translate.c
706
+++ b/target/arm/translate.c
707
@@ -XXX,XX +XXX,XX @@ static inline int get_a32_user_mem_index(DisasContext *s)
708
* otherwise, access as if at PL0.
709
*/
710
switch (s->mmu_idx) {
711
+ case ARMMMUIdx_E3:
712
case ARMMMUIdx_E2: /* this one is UNPREDICTABLE */
713
case ARMMMUIdx_E10_0:
714
case ARMMMUIdx_E10_1:
715
case ARMMMUIdx_E10_1_PAN:
716
return arm_to_core_mmu_idx(ARMMMUIdx_E10_0);
717
- case ARMMMUIdx_SE3:
718
- case ARMMMUIdx_SE10_0:
719
- case ARMMMUIdx_SE10_1:
720
- case ARMMMUIdx_SE10_1_PAN:
721
- return arm_to_core_mmu_idx(ARMMMUIdx_SE10_0);
722
case ARMMMUIdx_MUser:
723
case ARMMMUIdx_MPriv:
724
return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
126
--
725
--
127
2.25.1
726
2.25.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
Use a switch on mmu_idx for the a-profile indexes, instead of
4
in by exynos4210_init_board_irqs() with the appropriate qemu_irqs
4
three different if's vs regime_el and arm_mmu_idx_is_stage1_of_2.
5
for each IRQ the board/SoC can assert
6
* irq_table is a set of qemu_irqs pointed to from the
7
Exynos4210State struct. It's allocated in exynos4210_init_irq,
8
and the only behaviour these irqs have is that they pass on the
9
level to the equivalent board_irqs[] irq
10
5
11
The extra indirection through irq_table is unnecessary, so coalesce
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
these into a single irq_table[] array as a direct field in
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Exynos4210State which exynos4210_init_board_irqs() fills in.
8
Message-id: 20221001162318.153420-12-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/ptw.c | 32 +++++++++++++++++++++++++-------
12
1 file changed, 25 insertions(+), 7 deletions(-)
14
13
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20220404154658.565020-6-peter.maydell@linaro.org
18
---
19
include/hw/arm/exynos4210.h | 8 ++------
20
hw/arm/exynos4210.c | 6 +-----
21
hw/intc/exynos4210_gic.c | 32 ++++++++------------------------
22
3 files changed, 11 insertions(+), 35 deletions(-)
23
24
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/arm/exynos4210.h
16
--- a/target/arm/ptw.c
27
+++ b/include/hw/arm/exynos4210.h
17
+++ b/target/arm/ptw.c
28
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210Irq {
18
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
29
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
19
30
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
20
hcr_el2 = arm_hcr_el2_eff(env);
31
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
21
32
- qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
22
- if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
33
} Exynos4210Irq;
23
+ switch (mmu_idx) {
34
24
+ case ARMMMUIdx_Stage2:
35
struct Exynos4210State {
25
+ case ARMMMUIdx_Stage2_S:
36
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
26
/* HCR.DC means HCR.VM behaves as 1 */
37
/*< public >*/
27
return (hcr_el2 & (HCR_DC | HCR_VM)) == 0;
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
28
- }
39
Exynos4210Irq irqs;
29
40
- qemu_irq *irq_table;
30
- if (hcr_el2 & HCR_TGE) {
41
+ qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
31
+ case ARMMMUIdx_E10_0:
42
32
+ case ARMMMUIdx_E10_1:
43
MemoryRegion chipid_mem;
33
+ case ARMMMUIdx_E10_1_PAN:
44
MemoryRegion iram_mem;
34
/* TGE means that NS EL0/1 act as if SCTLR_EL1.M is zero */
45
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
35
- if (!is_secure && regime_el(env, mmu_idx) == 1) {
46
void exynos4210_write_secondary(ARMCPU *cpu,
36
+ if (!is_secure && (hcr_el2 & HCR_TGE)) {
47
const struct arm_boot_info *info);
37
return true;
48
38
}
49
-/* Initialize exynos4210 IRQ subsystem stub */
39
- }
50
-qemu_irq *exynos4210_init_irq(Exynos4210Irq *env);
40
+ break;
51
-
41
52
/* Initialize board IRQs.
42
- if ((hcr_el2 & HCR_DC) && arm_mmu_idx_is_stage1_of_2(mmu_idx)) {
53
* These IRQs contain splitted Int/External Combiner and External Gic IRQs */
43
+ case ARMMMUIdx_Stage1_E0:
54
-void exynos4210_init_board_irqs(Exynos4210Irq *s);
44
+ case ARMMMUIdx_Stage1_E1:
55
+void exynos4210_init_board_irqs(Exynos4210State *s);
45
+ case ARMMMUIdx_Stage1_E1_PAN:
56
46
/* HCR.DC means SCTLR_EL1.M behaves as 0 */
57
/* Get IRQ number from exynos4210 IRQ subsystem stub.
47
- return true;
58
* To identify IRQ source use internal combiner group and bit number
48
+ if (hcr_el2 & HCR_DC) {
59
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
49
+ return true;
60
index XXXXXXX..XXXXXXX 100644
50
+ }
61
--- a/hw/arm/exynos4210.c
51
+ break;
62
+++ b/hw/arm/exynos4210.c
52
+
63
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
53
+ case ARMMMUIdx_E20_0:
64
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
54
+ case ARMMMUIdx_E20_2:
55
+ case ARMMMUIdx_E20_2_PAN:
56
+ case ARMMMUIdx_E2:
57
+ case ARMMMUIdx_E3:
58
+ break;
59
+
60
+ default:
61
+ g_assert_not_reached();
65
}
62
}
66
63
67
- /*** IRQs ***/
64
return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
68
-
69
- s->irq_table = exynos4210_init_irq(&s->irqs);
70
-
71
/* IRQ Gate */
72
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
73
DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
74
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
75
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
76
77
/* Initialize board IRQs. */
78
- exynos4210_init_board_irqs(&s->irqs);
79
+ exynos4210_init_board_irqs(s);
80
81
/*** Memory ***/
82
83
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/hw/intc/exynos4210_gic.c
86
+++ b/hw/intc/exynos4210_gic.c
87
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
88
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
89
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
90
91
-static void exynos4210_irq_handler(void *opaque, int irq, int level)
92
-{
93
- Exynos4210Irq *s = (Exynos4210Irq *)opaque;
94
-
95
- /* Bypass */
96
- qemu_set_irq(s->board_irqs[irq], level);
97
-}
98
-
99
-/*
100
- * Initialize exynos4210 IRQ subsystem stub.
101
- */
102
-qemu_irq *exynos4210_init_irq(Exynos4210Irq *s)
103
-{
104
- return qemu_allocate_irqs(exynos4210_irq_handler, s,
105
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ);
106
-}
107
-
108
/*
109
* Initialize board IRQs.
110
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
111
*/
112
-void exynos4210_init_board_irqs(Exynos4210Irq *s)
113
+void exynos4210_init_board_irqs(Exynos4210State *s)
114
{
115
uint32_t grp, bit, irq_id, n;
116
+ Exynos4210Irq *is = &s->irqs;
117
118
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
119
irq_id = 0;
120
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
121
irq_id = EXT_GIC_ID_MCT_G1;
122
}
123
if (irq_id) {
124
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
125
- s->ext_gic_irq[irq_id-32]);
126
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
127
+ is->ext_gic_irq[irq_id - 32]);
128
} else {
129
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
130
- s->ext_combiner_irq[n]);
131
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
132
+ is->ext_combiner_irq[n]);
133
}
134
}
135
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
136
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
137
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
138
139
if (irq_id) {
140
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
141
- s->ext_gic_irq[irq_id-32]);
142
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
143
+ is->ext_gic_irq[irq_id - 32]);
144
}
145
}
146
}
147
--
65
--
148
2.25.1
66
2.25.1
diff view generated by jsdifflib
1
From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Describe that the gic-version influences the maximum number of CPUs.
3
The effect of TGE does not only apply to non-secure state,
4
now that Secure EL2 exists.
4
5
5
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
6
Message-id: 20220413231456.35811-1-heinrich.schuchardt@canonical.com
7
[PMM: minor punctuation tweaks]
8
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: 20221001162318.153420-13-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
docs/system/arm/virt.rst | 4 ++--
11
target/arm/ptw.c | 4 ++--
12
1 file changed, 2 insertions(+), 2 deletions(-)
12
1 file changed, 2 insertions(+), 2 deletions(-)
13
13
14
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
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/docs/system/arm/virt.rst
16
--- a/target/arm/ptw.c
17
+++ b/docs/system/arm/virt.rst
17
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@ gic-version
18
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
19
Valid values are:
19
case ARMMMUIdx_E10_0:
20
20
case ARMMMUIdx_E10_1:
21
``2``
21
case ARMMMUIdx_E10_1_PAN:
22
- GICv2
22
- /* TGE means that NS EL0/1 act as if SCTLR_EL1.M is zero */
23
+ GICv2. Note that this limits the number of CPUs to 8.
23
- if (!is_secure && (hcr_el2 & HCR_TGE)) {
24
``3``
24
+ /* TGE means that EL0/1 act as if SCTLR_EL1.M is zero */
25
- GICv3
25
+ if (hcr_el2 & HCR_TGE) {
26
+ GICv3. This allows up to 512 CPUs.
26
return true;
27
``host``
27
}
28
Use the same GIC version the host provides, when using KVM
28
break;
29
``max``
30
--
29
--
31
2.25.1
30
2.25.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add a model of the Xilinx Versal CRL.
3
For page walking, we may require HCR for a security state
4
that is not "current".
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: 20221001162318.153420-14-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 | 20 +++++++++++++-------
12
hw/misc/xlnx-versal-crl.c | 421 ++++++++++++++++++++++++++++++
12
target/arm/helper.c | 11 ++++++++---
13
hw/misc/meson.build | 1 +
13
2 files changed, 21 insertions(+), 10 deletions(-)
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 @@ static inline bool arm_is_secure(CPUARMState *env)
23
@@ -XXX,XX +XXX,XX @@
20
* Return true if the current security state has AArch64 EL2 or AArch32 Hyp.
24
+/*
21
* This corresponds to the pseudocode EL2Enabled()
25
+ * QEMU model of the Clock-Reset-LPD (CRL).
22
*/
26
+ *
23
+static inline bool arm_is_el2_enabled_secstate(CPUARMState *env, bool secure)
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
+
35
+#include "hw/sysbus.h"
36
+#include "hw/register.h"
37
+#include "target/arm/cpu.h"
38
+
39
+#define TYPE_XLNX_VERSAL_CRL "xlnx,versal-crl"
40
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCRL, XLNX_VERSAL_CRL)
41
+
42
+REG32(ERR_CTRL, 0x0)
43
+ FIELD(ERR_CTRL, SLVERR_ENABLE, 0, 1)
44
+REG32(IR_STATUS, 0x4)
45
+ FIELD(IR_STATUS, ADDR_DECODE_ERR, 0, 1)
46
+REG32(IR_MASK, 0x8)
47
+ FIELD(IR_MASK, ADDR_DECODE_ERR, 0, 1)
48
+REG32(IR_ENABLE, 0xc)
49
+ FIELD(IR_ENABLE, ADDR_DECODE_ERR, 0, 1)
50
+REG32(IR_DISABLE, 0x10)
51
+ FIELD(IR_DISABLE, ADDR_DECODE_ERR, 0, 1)
52
+REG32(WPROT, 0x1c)
53
+ FIELD(WPROT, ACTIVE, 0, 1)
54
+REG32(PLL_CLK_OTHER_DMN, 0x20)
55
+ FIELD(PLL_CLK_OTHER_DMN, APLL_BYPASS, 0, 1)
56
+REG32(RPLL_CTRL, 0x40)
57
+ FIELD(RPLL_CTRL, POST_SRC, 24, 3)
58
+ FIELD(RPLL_CTRL, PRE_SRC, 20, 3)
59
+ FIELD(RPLL_CTRL, CLKOUTDIV, 16, 2)
60
+ FIELD(RPLL_CTRL, FBDIV, 8, 8)
61
+ FIELD(RPLL_CTRL, BYPASS, 3, 1)
62
+ FIELD(RPLL_CTRL, RESET, 0, 1)
63
+REG32(RPLL_CFG, 0x44)
64
+ FIELD(RPLL_CFG, LOCK_DLY, 25, 7)
65
+ FIELD(RPLL_CFG, LOCK_CNT, 13, 10)
66
+ FIELD(RPLL_CFG, LFHF, 10, 2)
67
+ FIELD(RPLL_CFG, CP, 5, 4)
68
+ FIELD(RPLL_CFG, RES, 0, 4)
69
+REG32(RPLL_FRAC_CFG, 0x48)
70
+ FIELD(RPLL_FRAC_CFG, ENABLED, 31, 1)
71
+ FIELD(RPLL_FRAC_CFG, SEED, 22, 3)
72
+ FIELD(RPLL_FRAC_CFG, ALGRTHM, 19, 1)
73
+ FIELD(RPLL_FRAC_CFG, ORDER, 18, 1)
74
+ FIELD(RPLL_FRAC_CFG, DATA, 0, 16)
75
+REG32(PLL_STATUS, 0x50)
76
+ FIELD(PLL_STATUS, RPLL_STABLE, 2, 1)
77
+ FIELD(PLL_STATUS, RPLL_LOCK, 0, 1)
78
+REG32(RPLL_TO_XPD_CTRL, 0x100)
79
+ FIELD(RPLL_TO_XPD_CTRL, CLKACT, 25, 1)
80
+ FIELD(RPLL_TO_XPD_CTRL, DIVISOR0, 8, 10)
81
+REG32(LPD_TOP_SWITCH_CTRL, 0x104)
82
+ FIELD(LPD_TOP_SWITCH_CTRL, CLKACT_ADMA, 26, 1)
83
+ FIELD(LPD_TOP_SWITCH_CTRL, CLKACT, 25, 1)
84
+ FIELD(LPD_TOP_SWITCH_CTRL, DIVISOR0, 8, 10)
85
+ FIELD(LPD_TOP_SWITCH_CTRL, SRCSEL, 0, 3)
86
+REG32(LPD_LSBUS_CTRL, 0x108)
87
+ FIELD(LPD_LSBUS_CTRL, CLKACT, 25, 1)
88
+ FIELD(LPD_LSBUS_CTRL, DIVISOR0, 8, 10)
89
+ FIELD(LPD_LSBUS_CTRL, SRCSEL, 0, 3)
90
+REG32(CPU_R5_CTRL, 0x10c)
91
+ FIELD(CPU_R5_CTRL, CLKACT_OCM2, 28, 1)
92
+ FIELD(CPU_R5_CTRL, CLKACT_OCM, 27, 1)
93
+ FIELD(CPU_R5_CTRL, CLKACT_CORE, 26, 1)
94
+ FIELD(CPU_R5_CTRL, CLKACT, 25, 1)
95
+ FIELD(CPU_R5_CTRL, DIVISOR0, 8, 10)
96
+ FIELD(CPU_R5_CTRL, SRCSEL, 0, 3)
97
+REG32(IOU_SWITCH_CTRL, 0x114)
98
+ FIELD(IOU_SWITCH_CTRL, CLKACT, 25, 1)
99
+ FIELD(IOU_SWITCH_CTRL, DIVISOR0, 8, 10)
100
+ FIELD(IOU_SWITCH_CTRL, SRCSEL, 0, 3)
101
+REG32(GEM0_REF_CTRL, 0x118)
102
+ FIELD(GEM0_REF_CTRL, CLKACT_RX, 27, 1)
103
+ FIELD(GEM0_REF_CTRL, CLKACT_TX, 26, 1)
104
+ FIELD(GEM0_REF_CTRL, CLKACT, 25, 1)
105
+ FIELD(GEM0_REF_CTRL, DIVISOR0, 8, 10)
106
+ FIELD(GEM0_REF_CTRL, SRCSEL, 0, 3)
107
+REG32(GEM1_REF_CTRL, 0x11c)
108
+ FIELD(GEM1_REF_CTRL, CLKACT_RX, 27, 1)
109
+ FIELD(GEM1_REF_CTRL, CLKACT_TX, 26, 1)
110
+ FIELD(GEM1_REF_CTRL, CLKACT, 25, 1)
111
+ FIELD(GEM1_REF_CTRL, DIVISOR0, 8, 10)
112
+ FIELD(GEM1_REF_CTRL, SRCSEL, 0, 3)
113
+REG32(GEM_TSU_REF_CTRL, 0x120)
114
+ FIELD(GEM_TSU_REF_CTRL, CLKACT, 25, 1)
115
+ FIELD(GEM_TSU_REF_CTRL, DIVISOR0, 8, 10)
116
+ FIELD(GEM_TSU_REF_CTRL, SRCSEL, 0, 3)
117
+REG32(USB0_BUS_REF_CTRL, 0x124)
118
+ FIELD(USB0_BUS_REF_CTRL, CLKACT, 25, 1)
119
+ FIELD(USB0_BUS_REF_CTRL, DIVISOR0, 8, 10)
120
+ FIELD(USB0_BUS_REF_CTRL, SRCSEL, 0, 3)
121
+REG32(UART0_REF_CTRL, 0x128)
122
+ FIELD(UART0_REF_CTRL, CLKACT, 25, 1)
123
+ FIELD(UART0_REF_CTRL, DIVISOR0, 8, 10)
124
+ FIELD(UART0_REF_CTRL, SRCSEL, 0, 3)
125
+REG32(UART1_REF_CTRL, 0x12c)
126
+ FIELD(UART1_REF_CTRL, CLKACT, 25, 1)
127
+ FIELD(UART1_REF_CTRL, DIVISOR0, 8, 10)
128
+ FIELD(UART1_REF_CTRL, SRCSEL, 0, 3)
129
+REG32(SPI0_REF_CTRL, 0x130)
130
+ FIELD(SPI0_REF_CTRL, CLKACT, 25, 1)
131
+ FIELD(SPI0_REF_CTRL, DIVISOR0, 8, 10)
132
+ FIELD(SPI0_REF_CTRL, SRCSEL, 0, 3)
133
+REG32(SPI1_REF_CTRL, 0x134)
134
+ FIELD(SPI1_REF_CTRL, CLKACT, 25, 1)
135
+ FIELD(SPI1_REF_CTRL, DIVISOR0, 8, 10)
136
+ FIELD(SPI1_REF_CTRL, SRCSEL, 0, 3)
137
+REG32(CAN0_REF_CTRL, 0x138)
138
+ FIELD(CAN0_REF_CTRL, CLKACT, 25, 1)
139
+ FIELD(CAN0_REF_CTRL, DIVISOR0, 8, 10)
140
+ FIELD(CAN0_REF_CTRL, SRCSEL, 0, 3)
141
+REG32(CAN1_REF_CTRL, 0x13c)
142
+ FIELD(CAN1_REF_CTRL, CLKACT, 25, 1)
143
+ FIELD(CAN1_REF_CTRL, DIVISOR0, 8, 10)
144
+ FIELD(CAN1_REF_CTRL, SRCSEL, 0, 3)
145
+REG32(I2C0_REF_CTRL, 0x140)
146
+ FIELD(I2C0_REF_CTRL, CLKACT, 25, 1)
147
+ FIELD(I2C0_REF_CTRL, DIVISOR0, 8, 10)
148
+ FIELD(I2C0_REF_CTRL, SRCSEL, 0, 3)
149
+REG32(I2C1_REF_CTRL, 0x144)
150
+ FIELD(I2C1_REF_CTRL, CLKACT, 25, 1)
151
+ FIELD(I2C1_REF_CTRL, DIVISOR0, 8, 10)
152
+ FIELD(I2C1_REF_CTRL, SRCSEL, 0, 3)
153
+REG32(DBG_LPD_CTRL, 0x148)
154
+ FIELD(DBG_LPD_CTRL, CLKACT, 25, 1)
155
+ FIELD(DBG_LPD_CTRL, DIVISOR0, 8, 10)
156
+ FIELD(DBG_LPD_CTRL, SRCSEL, 0, 3)
157
+REG32(TIMESTAMP_REF_CTRL, 0x14c)
158
+ FIELD(TIMESTAMP_REF_CTRL, CLKACT, 25, 1)
159
+ FIELD(TIMESTAMP_REF_CTRL, DIVISOR0, 8, 10)
160
+ FIELD(TIMESTAMP_REF_CTRL, SRCSEL, 0, 3)
161
+REG32(CRL_SAFETY_CHK, 0x150)
162
+REG32(PSM_REF_CTRL, 0x154)
163
+ FIELD(PSM_REF_CTRL, DIVISOR0, 8, 10)
164
+ FIELD(PSM_REF_CTRL, SRCSEL, 0, 3)
165
+REG32(DBG_TSTMP_CTRL, 0x158)
166
+ FIELD(DBG_TSTMP_CTRL, CLKACT, 25, 1)
167
+ FIELD(DBG_TSTMP_CTRL, DIVISOR0, 8, 10)
168
+ FIELD(DBG_TSTMP_CTRL, SRCSEL, 0, 3)
169
+REG32(CPM_TOPSW_REF_CTRL, 0x15c)
170
+ FIELD(CPM_TOPSW_REF_CTRL, CLKACT, 25, 1)
171
+ FIELD(CPM_TOPSW_REF_CTRL, DIVISOR0, 8, 10)
172
+ FIELD(CPM_TOPSW_REF_CTRL, SRCSEL, 0, 3)
173
+REG32(USB3_DUAL_REF_CTRL, 0x160)
174
+ FIELD(USB3_DUAL_REF_CTRL, CLKACT, 25, 1)
175
+ FIELD(USB3_DUAL_REF_CTRL, DIVISOR0, 8, 10)
176
+ FIELD(USB3_DUAL_REF_CTRL, SRCSEL, 0, 3)
177
+REG32(RST_CPU_R5, 0x300)
178
+ FIELD(RST_CPU_R5, RESET_PGE, 4, 1)
179
+ FIELD(RST_CPU_R5, RESET_AMBA, 2, 1)
180
+ FIELD(RST_CPU_R5, RESET_CPU1, 1, 1)
181
+ FIELD(RST_CPU_R5, RESET_CPU0, 0, 1)
182
+REG32(RST_ADMA, 0x304)
183
+ FIELD(RST_ADMA, RESET, 0, 1)
184
+REG32(RST_GEM0, 0x308)
185
+ FIELD(RST_GEM0, RESET, 0, 1)
186
+REG32(RST_GEM1, 0x30c)
187
+ FIELD(RST_GEM1, RESET, 0, 1)
188
+REG32(RST_SPARE, 0x310)
189
+ FIELD(RST_SPARE, RESET, 0, 1)
190
+REG32(RST_USB0, 0x314)
191
+ FIELD(RST_USB0, RESET, 0, 1)
192
+REG32(RST_UART0, 0x318)
193
+ FIELD(RST_UART0, RESET, 0, 1)
194
+REG32(RST_UART1, 0x31c)
195
+ FIELD(RST_UART1, RESET, 0, 1)
196
+REG32(RST_SPI0, 0x320)
197
+ FIELD(RST_SPI0, RESET, 0, 1)
198
+REG32(RST_SPI1, 0x324)
199
+ FIELD(RST_SPI1, RESET, 0, 1)
200
+REG32(RST_CAN0, 0x328)
201
+ FIELD(RST_CAN0, RESET, 0, 1)
202
+REG32(RST_CAN1, 0x32c)
203
+ FIELD(RST_CAN1, RESET, 0, 1)
204
+REG32(RST_I2C0, 0x330)
205
+ FIELD(RST_I2C0, RESET, 0, 1)
206
+REG32(RST_I2C1, 0x334)
207
+ FIELD(RST_I2C1, RESET, 0, 1)
208
+REG32(RST_DBG_LPD, 0x338)
209
+ FIELD(RST_DBG_LPD, RPU_DBG1_RESET, 5, 1)
210
+ FIELD(RST_DBG_LPD, RPU_DBG0_RESET, 4, 1)
211
+ FIELD(RST_DBG_LPD, RESET_HSDP, 1, 1)
212
+ FIELD(RST_DBG_LPD, RESET, 0, 1)
213
+REG32(RST_GPIO, 0x33c)
214
+ FIELD(RST_GPIO, RESET, 0, 1)
215
+REG32(RST_TTC, 0x344)
216
+ FIELD(RST_TTC, TTC3_RESET, 3, 1)
217
+ FIELD(RST_TTC, TTC2_RESET, 2, 1)
218
+ FIELD(RST_TTC, TTC1_RESET, 1, 1)
219
+ FIELD(RST_TTC, TTC0_RESET, 0, 1)
220
+REG32(RST_TIMESTAMP, 0x348)
221
+ FIELD(RST_TIMESTAMP, RESET, 0, 1)
222
+REG32(RST_SWDT, 0x34c)
223
+ FIELD(RST_SWDT, RESET, 0, 1)
224
+REG32(RST_OCM, 0x350)
225
+ FIELD(RST_OCM, RESET, 0, 1)
226
+REG32(RST_IPI, 0x354)
227
+ FIELD(RST_IPI, RESET, 0, 1)
228
+REG32(RST_SYSMON, 0x358)
229
+ FIELD(RST_SYSMON, SEQ_RST, 1, 1)
230
+ FIELD(RST_SYSMON, CFG_RST, 0, 1)
231
+REG32(RST_FPD, 0x360)
232
+ FIELD(RST_FPD, SRST, 1, 1)
233
+ FIELD(RST_FPD, POR, 0, 1)
234
+REG32(PSM_RST_MODE, 0x370)
235
+ FIELD(PSM_RST_MODE, WAKEUP, 2, 1)
236
+ FIELD(PSM_RST_MODE, RST_MODE, 0, 2)
237
+
238
+#define CRL_R_MAX (R_PSM_RST_MODE + 1)
239
+
240
+#define RPU_MAX_CPU 2
241
+
242
+struct XlnxVersalCRL {
243
+ SysBusDevice parent_obj;
244
+ qemu_irq irq;
245
+
246
+ struct {
247
+ ARMCPU *cpu_r5[RPU_MAX_CPU];
248
+ DeviceState *adma[8];
249
+ DeviceState *uart[2];
250
+ DeviceState *gem[2];
251
+ DeviceState *usb;
252
+ } cfg;
253
+
254
+ RegisterInfoArray *reg_array;
255
+ uint32_t regs[CRL_R_MAX];
256
+ RegisterInfo regs_info[CRL_R_MAX];
257
+};
258
+#endif
259
diff --git a/hw/misc/xlnx-versal-crl.c b/hw/misc/xlnx-versal-crl.c
260
new file mode 100644
261
index XXXXXXX..XXXXXXX
262
--- /dev/null
263
+++ b/hw/misc/xlnx-versal-crl.c
264
@@ -XXX,XX +XXX,XX @@
265
+/*
266
+ * QEMU model of the Clock-Reset-LPD (CRL).
267
+ *
268
+ * Copyright (c) 2022 Advanced Micro Devices, Inc.
269
+ * SPDX-License-Identifier: GPL-2.0-or-later
270
+ *
271
+ * Written by Edgar E. Iglesias <edgar.iglesias@amd.com>
272
+ */
273
+
274
+#include "qemu/osdep.h"
275
+#include "qapi/error.h"
276
+#include "qemu/log.h"
277
+#include "qemu/bitops.h"
278
+#include "migration/vmstate.h"
279
+#include "hw/qdev-properties.h"
280
+#include "hw/sysbus.h"
281
+#include "hw/irq.h"
282
+#include "hw/register.h"
283
+#include "hw/resettable.h"
284
+
285
+#include "target/arm/arm-powerctl.h"
286
+#include "hw/misc/xlnx-versal-crl.h"
287
+
288
+#ifndef XLNX_VERSAL_CRL_ERR_DEBUG
289
+#define XLNX_VERSAL_CRL_ERR_DEBUG 0
290
+#endif
291
+
292
+static void crl_update_irq(XlnxVersalCRL *s)
293
+{
24
+{
294
+ bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK];
25
+ return arm_feature(env, ARM_FEATURE_EL2)
295
+ qemu_set_irq(s->irq, pending);
26
+ && (!secure || (env->cp15.scr_el3 & SCR_EEL2));
296
+}
27
+}
297
+
28
+
298
+static void crl_status_postw(RegisterInfo *reg, uint64_t val64)
29
static inline bool arm_is_el2_enabled(CPUARMState *env)
30
{
31
- if (arm_feature(env, ARM_FEATURE_EL2)) {
32
- if (arm_is_secure_below_el3(env)) {
33
- return (env->cp15.scr_el3 & SCR_EEL2) != 0;
34
- }
35
- return true;
36
- }
37
- return false;
38
+ return arm_is_el2_enabled_secstate(env, arm_is_secure_below_el3(env));
39
}
40
41
#else
42
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_secure(CPUARMState *env)
43
return false;
44
}
45
46
+static inline bool arm_is_el2_enabled_secstate(CPUARMState *env, bool secure)
299
+{
47
+{
300
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
48
+ return false;
301
+ crl_update_irq(s);
302
+}
49
+}
303
+
50
+
304
+static uint64_t crl_enable_prew(RegisterInfo *reg, uint64_t val64)
51
static inline bool arm_is_el2_enabled(CPUARMState *env)
52
{
53
return false;
54
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_el2_enabled(CPUARMState *env)
55
* "for all purposes other than a direct read or write access of HCR_EL2."
56
* Not included here is HCR_RW.
57
*/
58
+uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, bool secure);
59
uint64_t arm_hcr_el2_eff(CPUARMState *env);
60
uint64_t arm_hcrx_el2_eff(CPUARMState *env);
61
62
diff --git a/target/arm/helper.c b/target/arm/helper.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/target/arm/helper.c
65
+++ b/target/arm/helper.c
66
@@ -XXX,XX +XXX,XX @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
67
}
68
69
/*
70
- * Return the effective value of HCR_EL2.
71
+ * Return the effective value of HCR_EL2, at the given security state.
72
* Bits that are not included here:
73
* RW (read from SCR_EL3.RW as needed)
74
*/
75
-uint64_t arm_hcr_el2_eff(CPUARMState *env)
76
+uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, bool secure)
77
{
78
uint64_t ret = env->cp15.hcr_el2;
79
80
- if (!arm_is_el2_enabled(env)) {
81
+ if (!arm_is_el2_enabled_secstate(env, secure)) {
82
/*
83
* "This register has no effect if EL2 is not enabled in the
84
* current Security state". This is ARMv8.4-SecEL2 speak for
85
@@ -XXX,XX +XXX,XX @@ uint64_t arm_hcr_el2_eff(CPUARMState *env)
86
return ret;
87
}
88
89
+uint64_t arm_hcr_el2_eff(CPUARMState *env)
305
+{
90
+{
306
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
91
+ return arm_hcr_el2_eff_secstate(env, arm_is_secure_below_el3(env));
307
+ uint32_t val = val64;
308
+
309
+ s->regs[R_IR_MASK] &= ~val;
310
+ crl_update_irq(s);
311
+ return 0;
312
+}
92
+}
313
+
93
+
314
+static uint64_t crl_disable_prew(RegisterInfo *reg, uint64_t val64)
94
/*
315
+{
95
* Corresponds to ARM pseudocode function ELIsInHost().
316
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
96
*/
317
+ uint32_t val = val64;
318
+
319
+ s->regs[R_IR_MASK] |= val;
320
+ crl_update_irq(s);
321
+ return 0;
322
+}
323
+
324
+static void crl_reset_dev(XlnxVersalCRL *s, DeviceState *dev,
325
+ bool rst_old, bool rst_new)
326
+{
327
+ device_cold_reset(dev);
328
+}
329
+
330
+static void crl_reset_cpu(XlnxVersalCRL *s, ARMCPU *armcpu,
331
+ bool rst_old, bool rst_new)
332
+{
333
+ if (rst_new) {
334
+ arm_set_cpu_off(armcpu->mp_affinity);
335
+ } else {
336
+ arm_set_cpu_on_and_reset(armcpu->mp_affinity);
337
+ }
338
+}
339
+
340
+#define REGFIELD_RESET(type, s, reg, f, new_val, dev) { \
341
+ bool old_f = ARRAY_FIELD_EX32((s)->regs, reg, f); \
342
+ bool new_f = FIELD_EX32(new_val, reg, f); \
343
+ \
344
+ /* Detect edges. */ \
345
+ if (dev && old_f != new_f) { \
346
+ crl_reset_ ## type(s, dev, old_f, new_f); \
347
+ } \
348
+}
349
+
350
+static uint64_t crl_rst_r5_prew(RegisterInfo *reg, uint64_t val64)
351
+{
352
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
353
+
354
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU0, val64, s->cfg.cpu_r5[0]);
355
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU1, val64, s->cfg.cpu_r5[1]);
356
+ return val64;
357
+}
358
+
359
+static uint64_t crl_rst_adma_prew(RegisterInfo *reg, uint64_t val64)
360
+{
361
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
362
+ int i;
363
+
364
+ /* A single register fans out to all ADMA reset inputs. */
365
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); i++) {
366
+ REGFIELD_RESET(dev, s, RST_ADMA, RESET, val64, s->cfg.adma[i]);
367
+ }
368
+ return val64;
369
+}
370
+
371
+static uint64_t crl_rst_uart0_prew(RegisterInfo *reg, uint64_t val64)
372
+{
373
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
374
+
375
+ REGFIELD_RESET(dev, s, RST_UART0, RESET, val64, s->cfg.uart[0]);
376
+ return val64;
377
+}
378
+
379
+static uint64_t crl_rst_uart1_prew(RegisterInfo *reg, uint64_t val64)
380
+{
381
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
382
+
383
+ REGFIELD_RESET(dev, s, RST_UART1, RESET, val64, s->cfg.uart[1]);
384
+ return val64;
385
+}
386
+
387
+static uint64_t crl_rst_gem0_prew(RegisterInfo *reg, uint64_t val64)
388
+{
389
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
390
+
391
+ REGFIELD_RESET(dev, s, RST_GEM0, RESET, val64, s->cfg.gem[0]);
392
+ return val64;
393
+}
394
+
395
+static uint64_t crl_rst_gem1_prew(RegisterInfo *reg, uint64_t val64)
396
+{
397
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
398
+
399
+ REGFIELD_RESET(dev, s, RST_GEM1, RESET, val64, s->cfg.gem[1]);
400
+ return val64;
401
+}
402
+
403
+static uint64_t crl_rst_usb_prew(RegisterInfo *reg, uint64_t val64)
404
+{
405
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
406
+
407
+ REGFIELD_RESET(dev, s, RST_USB0, RESET, val64, s->cfg.usb);
408
+ return val64;
409
+}
410
+
411
+static const RegisterAccessInfo crl_regs_info[] = {
412
+ { .name = "ERR_CTRL", .addr = A_ERR_CTRL,
413
+ },{ .name = "IR_STATUS", .addr = A_IR_STATUS,
414
+ .w1c = 0x1,
415
+ .post_write = crl_status_postw,
416
+ },{ .name = "IR_MASK", .addr = A_IR_MASK,
417
+ .reset = 0x1,
418
+ .ro = 0x1,
419
+ },{ .name = "IR_ENABLE", .addr = A_IR_ENABLE,
420
+ .pre_write = crl_enable_prew,
421
+ },{ .name = "IR_DISABLE", .addr = A_IR_DISABLE,
422
+ .pre_write = crl_disable_prew,
423
+ },{ .name = "WPROT", .addr = A_WPROT,
424
+ },{ .name = "PLL_CLK_OTHER_DMN", .addr = A_PLL_CLK_OTHER_DMN,
425
+ .reset = 0x1,
426
+ .rsvd = 0xe,
427
+ },{ .name = "RPLL_CTRL", .addr = A_RPLL_CTRL,
428
+ .reset = 0x24809,
429
+ .rsvd = 0xf88c00f6,
430
+ },{ .name = "RPLL_CFG", .addr = A_RPLL_CFG,
431
+ .reset = 0x2000000,
432
+ .rsvd = 0x1801210,
433
+ },{ .name = "RPLL_FRAC_CFG", .addr = A_RPLL_FRAC_CFG,
434
+ .rsvd = 0x7e330000,
435
+ },{ .name = "PLL_STATUS", .addr = A_PLL_STATUS,
436
+ .reset = R_PLL_STATUS_RPLL_STABLE_MASK |
437
+ R_PLL_STATUS_RPLL_LOCK_MASK,
438
+ .rsvd = 0xfa,
439
+ .ro = 0x5,
440
+ },{ .name = "RPLL_TO_XPD_CTRL", .addr = A_RPLL_TO_XPD_CTRL,
441
+ .reset = 0x2000100,
442
+ .rsvd = 0xfdfc00ff,
443
+ },{ .name = "LPD_TOP_SWITCH_CTRL", .addr = A_LPD_TOP_SWITCH_CTRL,
444
+ .reset = 0x6000300,
445
+ .rsvd = 0xf9fc00f8,
446
+ },{ .name = "LPD_LSBUS_CTRL", .addr = A_LPD_LSBUS_CTRL,
447
+ .reset = 0x2000800,
448
+ .rsvd = 0xfdfc00f8,
449
+ },{ .name = "CPU_R5_CTRL", .addr = A_CPU_R5_CTRL,
450
+ .reset = 0xe000300,
451
+ .rsvd = 0xe1fc00f8,
452
+ },{ .name = "IOU_SWITCH_CTRL", .addr = A_IOU_SWITCH_CTRL,
453
+ .reset = 0x2000500,
454
+ .rsvd = 0xfdfc00f8,
455
+ },{ .name = "GEM0_REF_CTRL", .addr = A_GEM0_REF_CTRL,
456
+ .reset = 0xe000a00,
457
+ .rsvd = 0xf1fc00f8,
458
+ },{ .name = "GEM1_REF_CTRL", .addr = A_GEM1_REF_CTRL,
459
+ .reset = 0xe000a00,
460
+ .rsvd = 0xf1fc00f8,
461
+ },{ .name = "GEM_TSU_REF_CTRL", .addr = A_GEM_TSU_REF_CTRL,
462
+ .reset = 0x300,
463
+ .rsvd = 0xfdfc00f8,
464
+ },{ .name = "USB0_BUS_REF_CTRL", .addr = A_USB0_BUS_REF_CTRL,
465
+ .reset = 0x2001900,
466
+ .rsvd = 0xfdfc00f8,
467
+ },{ .name = "UART0_REF_CTRL", .addr = A_UART0_REF_CTRL,
468
+ .reset = 0xc00,
469
+ .rsvd = 0xfdfc00f8,
470
+ },{ .name = "UART1_REF_CTRL", .addr = A_UART1_REF_CTRL,
471
+ .reset = 0xc00,
472
+ .rsvd = 0xfdfc00f8,
473
+ },{ .name = "SPI0_REF_CTRL", .addr = A_SPI0_REF_CTRL,
474
+ .reset = 0x600,
475
+ .rsvd = 0xfdfc00f8,
476
+ },{ .name = "SPI1_REF_CTRL", .addr = A_SPI1_REF_CTRL,
477
+ .reset = 0x600,
478
+ .rsvd = 0xfdfc00f8,
479
+ },{ .name = "CAN0_REF_CTRL", .addr = A_CAN0_REF_CTRL,
480
+ .reset = 0xc00,
481
+ .rsvd = 0xfdfc00f8,
482
+ },{ .name = "CAN1_REF_CTRL", .addr = A_CAN1_REF_CTRL,
483
+ .reset = 0xc00,
484
+ .rsvd = 0xfdfc00f8,
485
+ },{ .name = "I2C0_REF_CTRL", .addr = A_I2C0_REF_CTRL,
486
+ .reset = 0xc00,
487
+ .rsvd = 0xfdfc00f8,
488
+ },{ .name = "I2C1_REF_CTRL", .addr = A_I2C1_REF_CTRL,
489
+ .reset = 0xc00,
490
+ .rsvd = 0xfdfc00f8,
491
+ },{ .name = "DBG_LPD_CTRL", .addr = A_DBG_LPD_CTRL,
492
+ .reset = 0x300,
493
+ .rsvd = 0xfdfc00f8,
494
+ },{ .name = "TIMESTAMP_REF_CTRL", .addr = A_TIMESTAMP_REF_CTRL,
495
+ .reset = 0x2000c00,
496
+ .rsvd = 0xfdfc00f8,
497
+ },{ .name = "CRL_SAFETY_CHK", .addr = A_CRL_SAFETY_CHK,
498
+ },{ .name = "PSM_REF_CTRL", .addr = A_PSM_REF_CTRL,
499
+ .reset = 0xf04,
500
+ .rsvd = 0xfffc00f8,
501
+ },{ .name = "DBG_TSTMP_CTRL", .addr = A_DBG_TSTMP_CTRL,
502
+ .reset = 0x300,
503
+ .rsvd = 0xfdfc00f8,
504
+ },{ .name = "CPM_TOPSW_REF_CTRL", .addr = A_CPM_TOPSW_REF_CTRL,
505
+ .reset = 0x300,
506
+ .rsvd = 0xfdfc00f8,
507
+ },{ .name = "USB3_DUAL_REF_CTRL", .addr = A_USB3_DUAL_REF_CTRL,
508
+ .reset = 0x3c00,
509
+ .rsvd = 0xfdfc00f8,
510
+ },{ .name = "RST_CPU_R5", .addr = A_RST_CPU_R5,
511
+ .reset = 0x17,
512
+ .rsvd = 0x8,
513
+ .pre_write = crl_rst_r5_prew,
514
+ },{ .name = "RST_ADMA", .addr = A_RST_ADMA,
515
+ .reset = 0x1,
516
+ .pre_write = crl_rst_adma_prew,
517
+ },{ .name = "RST_GEM0", .addr = A_RST_GEM0,
518
+ .reset = 0x1,
519
+ .pre_write = crl_rst_gem0_prew,
520
+ },{ .name = "RST_GEM1", .addr = A_RST_GEM1,
521
+ .reset = 0x1,
522
+ .pre_write = crl_rst_gem1_prew,
523
+ },{ .name = "RST_SPARE", .addr = A_RST_SPARE,
524
+ .reset = 0x1,
525
+ },{ .name = "RST_USB0", .addr = A_RST_USB0,
526
+ .reset = 0x1,
527
+ .pre_write = crl_rst_usb_prew,
528
+ },{ .name = "RST_UART0", .addr = A_RST_UART0,
529
+ .reset = 0x1,
530
+ .pre_write = crl_rst_uart0_prew,
531
+ },{ .name = "RST_UART1", .addr = A_RST_UART1,
532
+ .reset = 0x1,
533
+ .pre_write = crl_rst_uart1_prew,
534
+ },{ .name = "RST_SPI0", .addr = A_RST_SPI0,
535
+ .reset = 0x1,
536
+ },{ .name = "RST_SPI1", .addr = A_RST_SPI1,
537
+ .reset = 0x1,
538
+ },{ .name = "RST_CAN0", .addr = A_RST_CAN0,
539
+ .reset = 0x1,
540
+ },{ .name = "RST_CAN1", .addr = A_RST_CAN1,
541
+ .reset = 0x1,
542
+ },{ .name = "RST_I2C0", .addr = A_RST_I2C0,
543
+ .reset = 0x1,
544
+ },{ .name = "RST_I2C1", .addr = A_RST_I2C1,
545
+ .reset = 0x1,
546
+ },{ .name = "RST_DBG_LPD", .addr = A_RST_DBG_LPD,
547
+ .reset = 0x33,
548
+ .rsvd = 0xcc,
549
+ },{ .name = "RST_GPIO", .addr = A_RST_GPIO,
550
+ .reset = 0x1,
551
+ },{ .name = "RST_TTC", .addr = A_RST_TTC,
552
+ .reset = 0xf,
553
+ },{ .name = "RST_TIMESTAMP", .addr = A_RST_TIMESTAMP,
554
+ .reset = 0x1,
555
+ },{ .name = "RST_SWDT", .addr = A_RST_SWDT,
556
+ .reset = 0x1,
557
+ },{ .name = "RST_OCM", .addr = A_RST_OCM,
558
+ },{ .name = "RST_IPI", .addr = A_RST_IPI,
559
+ },{ .name = "RST_FPD", .addr = A_RST_FPD,
560
+ .reset = 0x3,
561
+ },{ .name = "PSM_RST_MODE", .addr = A_PSM_RST_MODE,
562
+ .reset = 0x1,
563
+ .rsvd = 0xf8,
564
+ }
565
+};
566
+
567
+static void crl_reset_enter(Object *obj, ResetType type)
568
+{
569
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
570
+ unsigned int i;
571
+
572
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
573
+ register_reset(&s->regs_info[i]);
574
+ }
575
+}
576
+
577
+static void crl_reset_hold(Object *obj)
578
+{
579
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
580
+
581
+ crl_update_irq(s);
582
+}
583
+
584
+static const MemoryRegionOps crl_ops = {
585
+ .read = register_read_memory,
586
+ .write = register_write_memory,
587
+ .endianness = DEVICE_LITTLE_ENDIAN,
588
+ .valid = {
589
+ .min_access_size = 4,
590
+ .max_access_size = 4,
591
+ },
592
+};
593
+
594
+static void crl_init(Object *obj)
595
+{
596
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
597
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
598
+ int i;
599
+
600
+ s->reg_array =
601
+ register_init_block32(DEVICE(obj), crl_regs_info,
602
+ ARRAY_SIZE(crl_regs_info),
603
+ s->regs_info, s->regs,
604
+ &crl_ops,
605
+ XLNX_VERSAL_CRL_ERR_DEBUG,
606
+ CRL_R_MAX * 4);
607
+ sysbus_init_mmio(sbd, &s->reg_array->mem);
608
+ sysbus_init_irq(sbd, &s->irq);
609
+
610
+ for (i = 0; i < ARRAY_SIZE(s->cfg.cpu_r5); ++i) {
611
+ object_property_add_link(obj, "cpu_r5[*]", TYPE_ARM_CPU,
612
+ (Object **)&s->cfg.cpu_r5[i],
613
+ qdev_prop_allow_set_link_before_realize,
614
+ OBJ_PROP_LINK_STRONG);
615
+ }
616
+
617
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); ++i) {
618
+ object_property_add_link(obj, "adma[*]", TYPE_DEVICE,
619
+ (Object **)&s->cfg.adma[i],
620
+ qdev_prop_allow_set_link_before_realize,
621
+ OBJ_PROP_LINK_STRONG);
622
+ }
623
+
624
+ for (i = 0; i < ARRAY_SIZE(s->cfg.uart); ++i) {
625
+ object_property_add_link(obj, "uart[*]", TYPE_DEVICE,
626
+ (Object **)&s->cfg.uart[i],
627
+ qdev_prop_allow_set_link_before_realize,
628
+ OBJ_PROP_LINK_STRONG);
629
+ }
630
+
631
+ for (i = 0; i < ARRAY_SIZE(s->cfg.gem); ++i) {
632
+ object_property_add_link(obj, "gem[*]", TYPE_DEVICE,
633
+ (Object **)&s->cfg.gem[i],
634
+ qdev_prop_allow_set_link_before_realize,
635
+ OBJ_PROP_LINK_STRONG);
636
+ }
637
+
638
+ object_property_add_link(obj, "usb", TYPE_DEVICE,
639
+ (Object **)&s->cfg.gem[i],
640
+ qdev_prop_allow_set_link_before_realize,
641
+ OBJ_PROP_LINK_STRONG);
642
+}
643
+
644
+static void crl_finalize(Object *obj)
645
+{
646
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
647
+ register_finalize_block(s->reg_array);
648
+}
649
+
650
+static const VMStateDescription vmstate_crl = {
651
+ .name = TYPE_XLNX_VERSAL_CRL,
652
+ .version_id = 1,
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
--
97
--
699
2.25.1
98
2.25.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
Rename the argument to is_secure_ptr, and introduce a
4
local variable is_secure with the value. We only write
5
back to the pointer toward the end of the function.
12
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20221001162318.153420-15-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220404154658.565020-15-peter.maydell@linaro.org
16
---
11
---
17
hw/arm/exynos4210.c | 7 +++----
12
target/arm/ptw.c | 22 ++++++++++++----------
18
1 file changed, 3 insertions(+), 4 deletions(-)
13
1 file changed, 12 insertions(+), 10 deletions(-)
19
14
20
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/exynos4210.c
17
--- a/target/arm/ptw.c
23
+++ b/hw/arm/exynos4210.c
18
+++ b/target/arm/ptw.c
24
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
19
@@ -XXX,XX +XXX,XX @@ static bool ptw_attrs_are_device(CPUARMState *env, ARMCacheAttrs cacheattrs)
25
20
26
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
21
/* Translate a S1 pagetable walk through S2 if needed. */
27
splitter = DEVICE(&s->splitter[splitcount]);
22
static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
28
- qdev_prop_set_uint16(splitter, "num-lines", 2);
23
- hwaddr addr, bool *is_secure,
29
+ qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
24
+ hwaddr addr, bool *is_secure_ptr,
30
qdev_realize(splitter, NULL, &error_abort);
25
ARMMMUFaultInfo *fi)
31
splitcount++;
26
{
32
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
27
- ARMMMUIdx s2_mmu_idx = *is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
28
+ bool is_secure = *is_secure_ptr;
34
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
29
+ ARMMMUIdx s2_mmu_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
35
if (irq_id) {
30
36
- qdev_connect_gpio_out(splitter, 1,
31
if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
37
+ qdev_connect_gpio_out(splitter, 2,
32
- !regime_translation_disabled(env, s2_mmu_idx, *is_secure)) {
38
qdev_get_gpio_in(extgicdev, irq_id - 32));
33
+ !regime_translation_disabled(env, s2_mmu_idx, is_secure)) {
39
- } else {
34
GetPhysAddrResult s2 = {};
40
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
35
int ret;
36
37
ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx,
38
- *is_secure, false, &s2, fi);
39
+ is_secure, false, &s2, fi);
40
if (ret) {
41
assert(fi->type != ARMFault_None);
42
fi->s2addr = addr;
43
fi->stage2 = true;
44
fi->s1ptw = true;
45
- fi->s1ns = !*is_secure;
46
+ fi->s1ns = !is_secure;
47
return ~0;
41
}
48
}
42
}
49
if ((arm_hcr_el2_eff(env) & HCR_PTW) &&
43
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
50
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
51
fi->s2addr = addr;
52
fi->stage2 = true;
53
fi->s1ptw = true;
54
- fi->s1ns = !*is_secure;
55
+ fi->s1ns = !is_secure;
56
return ~0;
57
}
58
59
if (arm_is_secure_below_el3(env)) {
60
/* Check if page table walk is to secure or non-secure PA space. */
61
- if (*is_secure) {
62
- *is_secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
63
+ if (is_secure) {
64
+ is_secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
65
} else {
66
- *is_secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
67
+ is_secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
68
}
69
+ *is_secure_ptr = is_secure;
70
} else {
71
- assert(!*is_secure);
72
+ assert(!is_secure);
73
}
74
75
addr = s2.phys;
44
--
76
--
45
2.25.1
77
2.25.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Break out header file to allow embedding of the the TTC.
3
This value is unused.
4
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
Message-id: 20221001162318.153420-16-richard.henderson@linaro.org
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>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
include/hw/timer/cadence_ttc.h | 54 ++++++++++++++++++++++++++++++++++
10
target/arm/ptw.c | 5 ++---
13
hw/timer/cadence_ttc.c | 32 ++------------------
11
1 file changed, 2 insertions(+), 3 deletions(-)
14
2 files changed, 56 insertions(+), 30 deletions(-)
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/target/arm/ptw.c b/target/arm/ptw.c
18
new file mode 100644
19
index XXXXXXX..XXXXXXX
20
--- /dev/null
21
+++ b/include/hw/timer/cadence_ttc.h
22
@@ -XXX,XX +XXX,XX @@
23
+/*
24
+ * Xilinx Zynq cadence TTC model
25
+ *
26
+ * Copyright (c) 2011 Xilinx Inc.
27
+ * Copyright (c) 2012 Peter A.G. Crosthwaite (peter.crosthwaite@petalogix.com)
28
+ * Copyright (c) 2012 PetaLogix Pty Ltd.
29
+ * Written By Haibing Ma
30
+ * M. Habib
31
+ *
32
+ * This program is free software; you can redistribute it and/or
33
+ * modify it under the terms of the GNU General Public License
34
+ * as published by the Free Software Foundation; either version
35
+ * 2 of the License, or (at your option) any later version.
36
+ *
37
+ * You should have received a copy of the GNU General Public License along
38
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
39
+ */
40
+#ifndef HW_TIMER_CADENCE_TTC_H
41
+#define HW_TIMER_CADENCE_TTC_H
42
+
43
+#include "hw/sysbus.h"
44
+#include "qemu/timer.h"
45
+
46
+typedef struct {
47
+ QEMUTimer *timer;
48
+ int freq;
49
+
50
+ uint32_t reg_clock;
51
+ uint32_t reg_count;
52
+ uint32_t reg_value;
53
+ uint16_t reg_interval;
54
+ uint16_t reg_match[3];
55
+ uint32_t reg_intr;
56
+ uint32_t reg_intr_en;
57
+ uint32_t reg_event_ctrl;
58
+ uint32_t reg_event;
59
+
60
+ uint64_t cpu_time;
61
+ unsigned int cpu_time_valid;
62
+
63
+ qemu_irq irq;
64
+} CadenceTimerState;
65
+
66
+#define TYPE_CADENCE_TTC "cadence_ttc"
67
+OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
68
+
69
+struct CadenceTTCState {
70
+ SysBusDevice parent_obj;
71
+
72
+ MemoryRegion iomem;
73
+ CadenceTimerState timer[3];
74
+};
75
+
76
+#endif
77
diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c
78
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/timer/cadence_ttc.c
15
--- a/target/arm/ptw.c
80
+++ b/hw/timer/cadence_ttc.c
16
+++ b/target/arm/ptw.c
81
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static uint8_t force_cacheattr_nibble_wb(uint8_t attr)
82
#include "qemu/timer.h"
18
* s1 and s2 for the HCR_EL2.FWB == 1 case, returning the
83
#include "qom/object.h"
19
* combined attributes in MAIR_EL1 format.
84
20
*/
85
+#include "hw/timer/cadence_ttc.h"
21
-static uint8_t combined_attrs_fwb(CPUARMState *env,
86
+
22
- ARMCacheAttrs s1, ARMCacheAttrs s2)
87
#ifdef CADENCE_TTC_ERR_DEBUG
23
+static uint8_t combined_attrs_fwb(ARMCacheAttrs s1, ARMCacheAttrs s2)
88
#define DB_PRINT(...) do { \
89
fprintf(stderr, ": %s: ", __func__); \
90
@@ -XXX,XX +XXX,XX @@
91
#define CLOCK_CTRL_PS_EN 0x00000001
92
#define CLOCK_CTRL_PS_V 0x0000001e
93
94
-typedef struct {
95
- QEMUTimer *timer;
96
- int freq;
97
-
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
{
24
{
126
qemu_set_irq(s->irq, !!(s->reg_intr & s->reg_intr_en));
25
switch (s2.attrs) {
26
case 7:
27
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
28
29
/* Combine memory type and cacheability attributes */
30
if (arm_hcr_el2_eff(env) & HCR_FWB) {
31
- ret.attrs = combined_attrs_fwb(env, s1, s2);
32
+ ret.attrs = combined_attrs_fwb(s1, s2);
33
} else {
34
ret.attrs = combined_attrs_nofwb(env, s1, s2);
35
}
127
--
36
--
128
2.25.1
37
2.25.1
diff view generated by jsdifflib
1
From: Zongyuan Li <zongyuan.li@smartx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
3
These subroutines did not need ENV for anything except
4
retrieving the effective value of HCR anyway.
5
6
We have computed the effective value of HCR in the callers,
7
and this will be especially important for interpreting HCR
8
in a non-current security state.
9
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-5-zongyuan.li@smartx.com
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/811
12
Message-id: 20221001162318.153420-17-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
14
---
9
include/hw/irq.h | 5 -----
15
target/arm/ptw.c | 30 +++++++++++++++++-------------
10
hw/core/irq.c | 15 ---------------
16
1 file changed, 17 insertions(+), 13 deletions(-)
11
2 files changed, 20 deletions(-)
12
17
13
diff --git a/include/hw/irq.h b/include/hw/irq.h
18
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/irq.h
20
--- a/target/arm/ptw.c
16
+++ b/include/hw/irq.h
21
+++ b/target/arm/ptw.c
17
@@ -XXX,XX +XXX,XX @@ void qemu_free_irq(qemu_irq irq);
22
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
18
/* Returns a new IRQ with opposite polarity. */
23
return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
19
qemu_irq qemu_irq_invert(qemu_irq irq);
20
21
-/* Returns a new IRQ which feeds into both the passed IRQs.
22
- * It's probably better to use the TYPE_SPLIT_IRQ device instead.
23
- */
24
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
25
-
26
/* For internal use in qtest. Similar to qemu_irq_split, but operating
27
on an existing vector of qemu_irq. */
28
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
29
diff --git a/hw/core/irq.c b/hw/core/irq.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/core/irq.c
32
+++ b/hw/core/irq.c
33
@@ -XXX,XX +XXX,XX @@ qemu_irq qemu_irq_invert(qemu_irq irq)
34
return qemu_allocate_irq(qemu_notirq, irq, 0);
35
}
24
}
36
25
37
-static void qemu_splitirq(void *opaque, int line, int level)
26
-static bool ptw_attrs_are_device(CPUARMState *env, ARMCacheAttrs cacheattrs)
38
-{
27
+static bool ptw_attrs_are_device(uint64_t hcr, ARMCacheAttrs cacheattrs)
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
{
28
{
54
int i;
29
/*
30
* For an S1 page table walk, the stage 1 attributes are always
31
@@ -XXX,XX +XXX,XX @@ static bool ptw_attrs_are_device(CPUARMState *env, ARMCacheAttrs cacheattrs)
32
* when cacheattrs.attrs bit [2] is 0.
33
*/
34
assert(cacheattrs.is_s2_format);
35
- if (arm_hcr_el2_eff(env) & HCR_FWB) {
36
+ if (hcr & HCR_FWB) {
37
return (cacheattrs.attrs & 0x4) == 0;
38
} else {
39
return (cacheattrs.attrs & 0xc) == 0;
40
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
41
if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
42
!regime_translation_disabled(env, s2_mmu_idx, is_secure)) {
43
GetPhysAddrResult s2 = {};
44
+ uint64_t hcr;
45
int ret;
46
47
ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx,
48
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
49
fi->s1ns = !is_secure;
50
return ~0;
51
}
52
- if ((arm_hcr_el2_eff(env) & HCR_PTW) &&
53
- ptw_attrs_are_device(env, s2.cacheattrs)) {
54
+
55
+ hcr = arm_hcr_el2_eff(env);
56
+ if ((hcr & HCR_PTW) && ptw_attrs_are_device(hcr, s2.cacheattrs)) {
57
/*
58
* PTW set and S1 walk touched S2 Device memory:
59
* generate Permission fault.
60
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
61
* ref: shared/translation/attrs/S2AttrDecode()
62
* .../S2ConvertAttrsHints()
63
*/
64
-static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
65
+static uint8_t convert_stage2_attrs(uint64_t hcr, uint8_t s2attrs)
66
{
67
uint8_t hiattr = extract32(s2attrs, 2, 2);
68
uint8_t loattr = extract32(s2attrs, 0, 2);
69
uint8_t hihint = 0, lohint = 0;
70
71
if (hiattr != 0) { /* normal memory */
72
- if (arm_hcr_el2_eff(env) & HCR_CD) { /* cache disabled */
73
+ if (hcr & HCR_CD) { /* cache disabled */
74
hiattr = loattr = 1; /* non-cacheable */
75
} else {
76
if (hiattr != 1) { /* Write-through or write-back */
77
@@ -XXX,XX +XXX,XX @@ static uint8_t combine_cacheattr_nibble(uint8_t s1, uint8_t s2)
78
* s1 and s2 for the HCR_EL2.FWB == 0 case, returning the
79
* combined attributes in MAIR_EL1 format.
80
*/
81
-static uint8_t combined_attrs_nofwb(CPUARMState *env,
82
+static uint8_t combined_attrs_nofwb(uint64_t hcr,
83
ARMCacheAttrs s1, ARMCacheAttrs s2)
84
{
85
uint8_t s1lo, s2lo, s1hi, s2hi, s2_mair_attrs, ret_attrs;
86
87
- s2_mair_attrs = convert_stage2_attrs(env, s2.attrs);
88
+ s2_mair_attrs = convert_stage2_attrs(hcr, s2.attrs);
89
90
s1lo = extract32(s1.attrs, 0, 4);
91
s2lo = extract32(s2_mair_attrs, 0, 4);
92
@@ -XXX,XX +XXX,XX @@ static uint8_t combined_attrs_fwb(ARMCacheAttrs s1, ARMCacheAttrs s2)
93
* @s1: Attributes from stage 1 walk
94
* @s2: Attributes from stage 2 walk
95
*/
96
-static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
97
+static ARMCacheAttrs combine_cacheattrs(uint64_t hcr,
98
ARMCacheAttrs s1, ARMCacheAttrs s2)
99
{
100
ARMCacheAttrs ret;
101
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
102
}
103
104
/* Combine memory type and cacheability attributes */
105
- if (arm_hcr_el2_eff(env) & HCR_FWB) {
106
+ if (hcr & HCR_FWB) {
107
ret.attrs = combined_attrs_fwb(s1, s2);
108
} else {
109
- ret.attrs = combined_attrs_nofwb(env, s1, s2);
110
+ ret.attrs = combined_attrs_nofwb(hcr, s1, s2);
111
}
112
113
/*
114
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
115
ARMCacheAttrs cacheattrs1;
116
ARMMMUIdx s2_mmu_idx;
117
bool is_el0;
118
+ uint64_t hcr;
119
120
ret = get_phys_addr_with_secure(env, address, access_type,
121
s1_mmu_idx, is_secure, result, fi);
122
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
123
}
124
125
/* Combine the S1 and S2 cache attributes. */
126
- if (arm_hcr_el2_eff(env) & HCR_DC) {
127
+ hcr = arm_hcr_el2_eff(env);
128
+ if (hcr & HCR_DC) {
129
/*
130
* HCR.DC forces the first stage attributes to
131
* Normal Non-Shareable,
132
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
133
}
134
cacheattrs1.shareability = 0;
135
}
136
- result->cacheattrs = combine_cacheattrs(env, cacheattrs1,
137
+ result->cacheattrs = combine_cacheattrs(hcr, cacheattrs1,
138
result->cacheattrs);
139
140
/*
55
--
141
--
56
2.25.1
142
2.25.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
Use arm_hcr_el2_eff_secstate instead of arm_hcr_el2_eff, so
10
up one interrupt line in this category (the HDMI I2C device on
4
that we use is_secure instead of the current security state.
11
interrupt 16,1), this seems like it must be a bug in the existing
5
These AT* operations have been broken since arm_hcr_el2_eff
12
QEMU code. Fill in the irq_table[] entries where we're not splitting
6
gained a check for "el2 enabled" for Secure EL2.
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
7
17
This bug didn't have any visible guest effects because the only
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
implemented device that was affected was the HDMI I2C controller,
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
19
and we never connect any I2C devices to that bus.
10
Message-id: 20221001162318.153420-18-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/ptw.c | 8 ++++----
14
1 file changed, 4 insertions(+), 4 deletions(-)
20
15
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20220404154658.565020-14-peter.maydell@linaro.org
24
---
25
hw/arm/exynos4210.c | 2 ++
26
1 file changed, 2 insertions(+)
27
28
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
29
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/exynos4210.c
18
--- a/target/arm/ptw.c
31
+++ b/hw/arm/exynos4210.c
19
+++ b/target/arm/ptw.c
32
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
20
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
34
qdev_connect_gpio_out(splitter, 1,
35
qdev_get_gpio_in(extgicdev, irq_id - 32));
36
+ } else {
37
+ s->irq_table[n] = is->int_combiner_irq[n];
38
}
21
}
39
}
22
}
40
/*
23
24
- hcr_el2 = arm_hcr_el2_eff(env);
25
+ hcr_el2 = arm_hcr_el2_eff_secstate(env, is_secure);
26
27
switch (mmu_idx) {
28
case ARMMMUIdx_Stage2:
29
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
30
return ~0;
31
}
32
33
- hcr = arm_hcr_el2_eff(env);
34
+ hcr = arm_hcr_el2_eff_secstate(env, is_secure);
35
if ((hcr & HCR_PTW) && ptw_attrs_are_device(hcr, s2.cacheattrs)) {
36
/*
37
* PTW set and S1 walk touched S2 Device memory:
38
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
39
}
40
41
/* Combine the S1 and S2 cache attributes. */
42
- hcr = arm_hcr_el2_eff(env);
43
+ hcr = arm_hcr_el2_eff_secstate(env, is_secure);
44
if (hcr & HCR_DC) {
45
/*
46
* HCR.DC forces the first stage attributes to
47
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
48
result->page_size = TARGET_PAGE_SIZE;
49
50
/* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
51
- hcr = arm_hcr_el2_eff(env);
52
+ hcr = arm_hcr_el2_eff_secstate(env, is_secure);
53
result->cacheattrs.shareability = 0;
54
result->cacheattrs.is_s2_format = false;
55
if (hcr & HCR_DC) {
41
--
56
--
42
2.25.1
57
2.25.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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
configurable number of outputs, we can do all this in one place, by
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
making exynos4210_init_board_irqs() add extra outputs to the splitter
5
Message-id: 20221001162318.153420-19-richard.henderson@linaro.org
10
device when it must be connected to more than one input on each
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
combiner.
7
---
8
target/arm/ptw.c | 138 +++++++++++++++++++++++++----------------------
9
1 file changed, 74 insertions(+), 64 deletions(-)
12
10
13
We do this with a new data structure, the combinermap, which is an
11
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
14
array each of whose elements is a list of the interrupt IDs on the
15
combiner which must be tied together. As we loop through each
16
interrupt ID, if we find that it is the first one in one of these
17
lists, we configure the splitter device with eonugh extra outputs and
18
wire them up to the other interrupt IDs in the list.
19
20
Conveniently, for all the cases where this is necessary, the
21
lowest-numbered interrupt ID in each group is in the range of the
22
external combiner, so we only need to code for this in the first of
23
the two loops in exynos4210_init_board_irqs().
24
25
The old code in exynos4210_combiner_get_gpioin() which is being
26
deleted here had several problems which don't exist in the new code
27
in its handling of the multi-core timer interrupts:
28
(1) the case labels specified bits 4 ... 8, but bit '8' doesn't
29
exist; these should have been 4 ... 7
30
(2) it used the input irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]
31
multiple times as the input of several different splitters,
32
which isn't allowed
33
(3) in an apparent cut-and-paste error, the cases for all the
34
multi-core timer inputs used "bit + 4" even though the
35
bit range for the case was (intended to be) 4 ... 7, which
36
meant it was looking at non-existent bits 8 ... 11.
37
None of these exist in the new code.
38
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
12
index XXXXXXX..XXXXXXX 100644
49
--- a/include/hw/arm/exynos4210.h
13
--- a/target/arm/ptw.c
50
+++ b/include/hw/arm/exynos4210.h
14
+++ b/target/arm/ptw.c
51
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(uint64_t hcr,
52
16
return ret;
53
/*
17
}
54
* We need one splitter for every external combiner input, plus
55
- * one for every non-zero entry in combiner_grp_to_gic_id[].
56
+ * one for every non-zero entry in combiner_grp_to_gic_id[],
57
+ * minus one for every external combiner ID in second or later
58
+ * places in a combinermap[] line.
59
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
60
*/
61
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
62
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
63
64
typedef struct Exynos4210Irq {
65
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
66
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/exynos4210.c
69
+++ b/hw/arm/exynos4210.c
70
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
71
#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
72
((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
73
18
74
+/*
19
+/*
75
+ * Some interrupt lines go to multiple combiner inputs.
20
+ * MMU disabled. S1 addresses within aa64 translation regimes are
76
+ * This data structure defines those: each array element is
21
+ * still checked for bounds -- see AArch64.S1DisabledOutput().
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
+ */
22
+ */
82
+#define IRQNO(G, B) EXYNOS4210_COMBINER_GET_IRQ_NUM(G, B)
23
+static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
83
+#define IRQNONE 0
24
+ MMUAccessType access_type,
25
+ ARMMMUIdx mmu_idx, bool is_secure,
26
+ GetPhysAddrResult *result,
27
+ ARMMMUFaultInfo *fi)
28
+{
29
+ uint64_t hcr;
30
+ uint8_t memattr;
84
+
31
+
85
+#define COMBINERMAP_SIZE 16
32
+ if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
33
+ int r_el = regime_el(env, mmu_idx);
34
+ if (arm_el_is_aa64(env, r_el)) {
35
+ int pamax = arm_pamax(env_archcpu(env));
36
+ uint64_t tcr = env->cp15.tcr_el[r_el];
37
+ int addrtop, tbi;
86
+
38
+
87
+static const int combinermap[COMBINERMAP_SIZE][6] = {
39
+ tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
88
+ /* MDNIE_LCD1 */
40
+ if (access_type == MMU_INST_FETCH) {
89
+ { IRQNO(0, 4), IRQNO(1, 0), IRQNONE },
41
+ tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx);
90
+ { IRQNO(0, 5), IRQNO(1, 1), IRQNONE },
42
+ }
91
+ { IRQNO(0, 6), IRQNO(1, 2), IRQNONE },
43
+ tbi = (tbi >> extract64(address, 55, 1)) & 1;
92
+ { IRQNO(0, 7), IRQNO(1, 3), IRQNONE },
44
+ addrtop = (tbi ? 55 : 63);
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
+
45
+
110
+#undef IRQNO
46
+ if (extract64(address, pamax, addrtop - pamax + 1) != 0) {
47
+ fi->type = ARMFault_AddressSize;
48
+ fi->level = 0;
49
+ fi->stage2 = false;
50
+ return 1;
51
+ }
111
+
52
+
112
+static const int *combinermap_entry(int irq)
53
+ /*
113
+{
54
+ * When TBI is disabled, we've just validated that all of the
114
+ /*
55
+ * bits above PAMax are zero, so logically we only need to
115
+ * If the interrupt number passed in is the first entry in some
56
+ * clear the top byte for TBI. But it's clearer to follow
116
+ * line of the combinermap, return a pointer to that line;
57
+ * the pseudocode set of addrdesc.paddress.
117
+ * otherwise return NULL.
58
+ */
118
+ */
59
+ address = extract64(address, 0, 52);
119
+ int i;
120
+ for (i = 0; i < COMBINERMAP_SIZE; i++) {
121
+ if (combinermap[i][0] == irq) {
122
+ return combinermap[i];
123
+ }
60
+ }
124
+ }
61
+ }
125
+ return NULL;
62
+
63
+ result->phys = address;
64
+ result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
65
+ result->page_size = TARGET_PAGE_SIZE;
66
+
67
+ /* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
68
+ hcr = arm_hcr_el2_eff_secstate(env, is_secure);
69
+ result->cacheattrs.shareability = 0;
70
+ result->cacheattrs.is_s2_format = false;
71
+ if (hcr & HCR_DC) {
72
+ if (hcr & HCR_DCT) {
73
+ memattr = 0xf0; /* Tagged, Normal, WB, RWA */
74
+ } else {
75
+ memattr = 0xff; /* Normal, WB, RWA */
76
+ }
77
+ } else if (access_type == MMU_INST_FETCH) {
78
+ if (regime_sctlr(env, mmu_idx) & SCTLR_I) {
79
+ memattr = 0xee; /* Normal, WT, RA, NT */
80
+ } else {
81
+ memattr = 0x44; /* Normal, NC, No */
82
+ }
83
+ result->cacheattrs.shareability = 2; /* outer sharable */
84
+ } else {
85
+ memattr = 0x00; /* Device, nGnRnE */
86
+ }
87
+ result->cacheattrs.attrs = memattr;
88
+ return 0;
126
+}
89
+}
127
+
90
+
128
+static int mapline_size(const int *mapline)
91
bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
129
+{
92
MMUAccessType access_type, ARMMMUIdx mmu_idx,
130
+ /* Return number of entries in this mapline in total */
93
bool is_secure, GetPhysAddrResult *result,
131
+ int i = 0;
94
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
132
+
95
/* Definitely a real MMU, not an MPU */
133
+ if (!mapline) {
96
134
+ /* Not in the map? IRQ goes to exactly one combiner input */
97
if (regime_translation_disabled(env, mmu_idx, is_secure)) {
135
+ return 1;
98
- uint64_t hcr;
136
+ }
99
- uint8_t memattr;
137
+ while (*mapline != IRQNONE) {
100
-
138
+ mapline++;
101
- /*
139
+ i++;
102
- * MMU disabled. S1 addresses within aa64 translation regimes are
140
+ }
103
- * still checked for bounds -- see AArch64.TranslateAddressS1Off.
141
+ return i;
104
- */
142
+}
105
- if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
143
+
106
- int r_el = regime_el(env, mmu_idx);
144
/*
107
- if (arm_el_is_aa64(env, r_el)) {
145
* Initialize board IRQs.
108
- int pamax = arm_pamax(env_archcpu(env));
146
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
109
- uint64_t tcr = env->cp15.tcr_el[r_el];
147
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
110
- int addrtop, tbi;
148
DeviceState *extgicdev = DEVICE(&s->ext_gic);
111
-
149
int splitcount = 0;
112
- tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
150
DeviceState *splitter;
113
- if (access_type == MMU_INST_FETCH) {
151
+ const int *mapline;
114
- tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx);
152
+ int numlines, splitin, in;
115
- }
153
116
- tbi = (tbi >> extract64(address, 55, 1)) & 1;
154
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
117
- addrtop = (tbi ? 55 : 63);
155
irq_id = 0;
118
-
156
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
119
- if (extract64(address, pamax, addrtop - pamax + 1) != 0) {
157
irq_id = EXT_GIC_ID_MCT_G1;
120
- fi->type = ARMFault_AddressSize;
158
}
121
- fi->level = 0;
159
122
- fi->stage2 = false;
160
+ if (s->irq_table[n]) {
123
- return 1;
161
+ /*
124
- }
162
+ * This must be some non-first entry in a combinermap line,
125
-
163
+ * and we've already filled it in.
126
- /*
164
+ */
127
- * When TBI is disabled, we've just validated that all of the
165
+ continue;
128
- * bits above PAMax are zero, so logically we only need to
166
+ }
129
- * clear the top byte for TBI. But it's clearer to follow
167
+ mapline = combinermap_entry(n);
130
- * the pseudocode set of addrdesc.paddress.
168
+ /*
131
- */
169
+ * We need to connect the IRQ to multiple inputs on both combiners
132
- address = extract64(address, 0, 52);
170
+ * and possibly also to the external GIC.
133
- }
171
+ */
134
- }
172
+ numlines = 2 * mapline_size(mapline);
135
- result->phys = address;
173
+ if (irq_id) {
136
- result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
174
+ numlines++;
137
- result->page_size = TARGET_PAGE_SIZE;
175
+ }
138
-
176
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
139
- /* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
177
splitter = DEVICE(&s->splitter[splitcount]);
140
- hcr = arm_hcr_el2_eff_secstate(env, is_secure);
178
- qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
141
- result->cacheattrs.shareability = 0;
179
+ qdev_prop_set_uint16(splitter, "num-lines", numlines);
142
- result->cacheattrs.is_s2_format = false;
180
qdev_realize(splitter, NULL, &error_abort);
143
- if (hcr & HCR_DC) {
181
splitcount++;
144
- if (hcr & HCR_DCT) {
182
- s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
145
- memattr = 0xf0; /* Tagged, Normal, WB, RWA */
183
- qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
146
- } else {
184
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
147
- memattr = 0xff; /* Normal, WB, RWA */
185
+
148
- }
186
+ in = n;
149
- } else if (access_type == MMU_INST_FETCH) {
187
+ splitin = 0;
150
- if (regime_sctlr(env, mmu_idx) & SCTLR_I) {
188
+ for (;;) {
151
- memattr = 0xee; /* Normal, WT, RA, NT */
189
+ s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
152
- } else {
190
+ qdev_connect_gpio_out(splitter, splitin, is->int_combiner_irq[in]);
153
- memattr = 0x44; /* Normal, NC, No */
191
+ qdev_connect_gpio_out(splitter, splitin + 1, is->ext_combiner_irq[in]);
154
- }
192
+ splitin += 2;
155
- result->cacheattrs.shareability = 2; /* outer sharable */
193
+ if (!mapline) {
156
- } else {
194
+ break;
157
- memattr = 0x00; /* Device, nGnRnE */
195
+ }
158
- }
196
+ mapline++;
159
- result->cacheattrs.attrs = memattr;
197
+ in = *mapline;
160
- return 0;
198
+ if (in == IRQNONE) {
161
+ return get_phys_addr_disabled(env, address, access_type, mmu_idx,
199
+ break;
162
+ is_secure, result, fi);
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
}
163
}
208
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
209
irq_id = combiner_grp_to_gic_id[grp -
210
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
211
212
+ if (s->irq_table[n]) {
213
+ /*
214
+ * This must be some non-first entry in a combinermap line,
215
+ * and we've already filled it in.
216
+ */
217
+ continue;
218
+ }
219
+
220
if (irq_id) {
221
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
222
splitter = DEVICE(&s->splitter[splitcount]);
223
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
224
DeviceState *dev, int ext)
225
{
226
int n;
227
- int bit;
228
int max;
229
qemu_irq *irq;
230
231
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
232
EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
233
irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
234
235
- /*
236
- * Some IRQs of Int/External Combiner are going to two Combiners groups,
237
- * so let split them.
238
- */
239
for (n = 0; n < max; n++) {
240
-
164
-
241
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
165
if (regime_using_lpae_format(env, mmu_idx)) {
242
-
166
return get_phys_addr_lpae(env, address, access_type, mmu_idx,
243
- switch (n) {
167
is_secure, false, result, fi);
244
- /* MDNIE_LCD1 INTG1 */
245
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
246
- EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
247
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
248
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
249
- continue;
250
-
251
- /* TMU INTG3 */
252
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
253
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
254
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
255
- continue;
256
-
257
- /* LCD1 INTG12 */
258
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
259
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
260
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
261
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
262
- continue;
263
-
264
- /* Multi-Core Timer INTG12 */
265
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
266
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
267
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
268
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
269
- continue;
270
-
271
- /* Multi-Core Timer INTG35 */
272
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
273
- EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
274
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
275
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
276
- continue;
277
-
278
- /* Multi-Core Timer INTG51 */
279
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
280
- EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
281
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
282
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
283
- continue;
284
-
285
- /* Multi-Core Timer INTG53 */
286
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
287
- EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
288
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
289
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
290
- continue;
291
- }
292
-
293
irq[n] = qdev_get_gpio_in(dev, n);
294
}
295
}
296
--
168
--
297
2.25.1
169
2.25.1
diff view generated by jsdifflib
1
In exynos4210_init_board_irqs(), use the TYPE_SPLIT_IRQ device
1
From: Richard Henderson <richard.henderson@linaro.org>
2
instead of qemu_irq_split().
3
2
3
Do not apply memattr or shareability for Stage2 translations.
4
Make sure to apply HCR_{DC,DCT} only to Regime_EL10, per the
5
pseudocode in AArch64.S1DisabledOutput.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20221001162318.153420-20-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20220404154658.565020-13-peter.maydell@linaro.org
7
---
11
---
8
include/hw/arm/exynos4210.h | 9 ++++++++
12
target/arm/ptw.c | 48 +++++++++++++++++++++++++-----------------------
9
hw/arm/exynos4210.c | 41 +++++++++++++++++++++++++++++--------
13
1 file changed, 25 insertions(+), 23 deletions(-)
10
2 files changed, 42 insertions(+), 8 deletions(-)
11
14
12
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
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/exynos4210.h
17
--- a/target/arm/ptw.c
15
+++ b/include/hw/arm/exynos4210.h
18
+++ b/target/arm/ptw.c
16
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
17
#include "hw/sysbus.h"
20
GetPhysAddrResult *result,
18
#include "hw/cpu/a9mpcore.h"
21
ARMMMUFaultInfo *fi)
19
#include "hw/intc/exynos4210_gic.h"
22
{
20
+#include "hw/core/split-irq.h"
23
- uint64_t hcr;
21
#include "target/arm/cpu-qom.h"
24
- uint8_t memattr;
22
#include "qom/object.h"
25
+ uint8_t memattr = 0x00; /* Device nGnRnE */
23
26
+ uint8_t shareability = 0; /* non-sharable */
24
@@ -XXX,XX +XXX,XX @@
27
25
28
if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
26
#define EXYNOS4210_NUM_DMA 3
29
int r_el = regime_el(env, mmu_idx);
27
28
+/*
29
+ * We need one splitter for every external combiner input, plus
30
+ * one for every non-zero entry in combiner_grp_to_gic_id[].
31
+ * We'll assert in exynos4210_init_board_irqs() if this is wrong.
32
+ */
33
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
34
+
30
+
35
typedef struct Exynos4210Irq {
31
if (arm_el_is_aa64(env, r_el)) {
36
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
32
int pamax = arm_pamax(env_archcpu(env));
37
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
33
uint64_t tcr = env->cp15.tcr_el[r_el];
38
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
34
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
39
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
35
*/
40
A9MPPrivState a9mpcore;
36
address = extract64(address, 0, 52);
41
Exynos4210GicState ext_gic;
42
+ SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
43
};
44
45
#define TYPE_EXYNOS4210_SOC "exynos4210"
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/exynos4210.c
49
+++ b/hw/arm/exynos4210.c
50
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
51
uint32_t grp, bit, irq_id, n;
52
Exynos4210Irq *is = &s->irqs;
53
DeviceState *extgicdev = DEVICE(&s->ext_gic);
54
+ int splitcount = 0;
55
+ DeviceState *splitter;
56
57
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
58
irq_id = 0;
59
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
60
/* MCT_G1 is passed to External and GIC */
61
irq_id = EXT_GIC_ID_MCT_G1;
62
}
37
}
63
+
38
+
64
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
39
+ /* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
65
+ splitter = DEVICE(&s->splitter[splitcount]);
40
+ if (r_el == 1) {
66
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
41
+ uint64_t hcr = arm_hcr_el2_eff_secstate(env, is_secure);
67
+ qdev_realize(splitter, NULL, &error_abort);
42
+ if (hcr & HCR_DC) {
68
+ splitcount++;
43
+ if (hcr & HCR_DCT) {
69
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
44
+ memattr = 0xf0; /* Tagged, Normal, WB, RWA */
70
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
45
+ } else {
71
if (irq_id) {
46
+ memattr = 0xff; /* Normal, WB, RWA */
72
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
47
+ }
73
- qdev_get_gpio_in(extgicdev,
48
+ }
74
- irq_id - 32));
49
+ }
75
+ qdev_connect_gpio_out(splitter, 1,
50
+ if (memattr == 0 && access_type == MMU_INST_FETCH) {
76
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
51
+ if (regime_sctlr(env, mmu_idx) & SCTLR_I) {
77
} else {
52
+ memattr = 0xee; /* Normal, WT, RA, NT */
78
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
53
+ } else {
79
- is->ext_combiner_irq[n]);
54
+ memattr = 0x44; /* Normal, NC, No */
80
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
55
+ }
81
}
56
+ shareability = 2; /* outer sharable */
57
+ }
58
+ result->cacheattrs.is_s2_format = false;
82
}
59
}
83
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
60
84
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
61
result->phys = address;
85
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
62
result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
86
63
result->page_size = TARGET_PAGE_SIZE;
87
if (irq_id) {
64
-
88
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
65
- /* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
89
- qdev_get_gpio_in(extgicdev,
66
- hcr = arm_hcr_el2_eff_secstate(env, is_secure);
90
- irq_id - 32));
67
- result->cacheattrs.shareability = 0;
91
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
68
- result->cacheattrs.is_s2_format = false;
92
+ splitter = DEVICE(&s->splitter[splitcount]);
69
- if (hcr & HCR_DC) {
93
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
70
- if (hcr & HCR_DCT) {
94
+ qdev_realize(splitter, NULL, &error_abort);
71
- memattr = 0xf0; /* Tagged, Normal, WB, RWA */
95
+ splitcount++;
72
- } else {
96
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
73
- memattr = 0xff; /* Normal, WB, RWA */
97
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
74
- }
98
+ qdev_connect_gpio_out(splitter, 1,
75
- } else if (access_type == MMU_INST_FETCH) {
99
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
76
- if (regime_sctlr(env, mmu_idx) & SCTLR_I) {
100
}
77
- memattr = 0xee; /* Normal, WT, RA, NT */
101
}
78
- } else {
102
+ /*
79
- memattr = 0x44; /* Normal, NC, No */
103
+ * We check this here to avoid a more obscure assert later when
80
- }
104
+ * qdev_assert_realized_properly() checks that we realized every
81
- result->cacheattrs.shareability = 2; /* outer sharable */
105
+ * child object we initialized.
82
- } else {
106
+ */
83
- memattr = 0x00; /* Device, nGnRnE */
107
+ assert(splitcount == EXYNOS4210_NUM_SPLITTERS);
84
- }
108
}
85
+ result->cacheattrs.shareability = shareability;
109
86
result->cacheattrs.attrs = memattr;
110
/*
87
return 0;
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
}
88
}
123
--
89
--
124
2.25.1
90
2.25.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Create an APU CPU Cluster. This is in preparation to add the RPU.
3
Adjust GetPhysAddrResult to fill in CPUTLBEntryFull,
4
so that it may be passed directly to tlb_set_page_full.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
The change is large, but mostly mechanical. The major
6
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
non-mechanical change is page_size -> lg_page_size.
7
Message-id: 20220406174303.2022038-2-edgar.iglesias@xilinx.com
8
Most of the time this is obvious, and is related to
9
TARGET_PAGE_BITS.
10
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20221001162318.153420-21-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
15
---
10
include/hw/arm/xlnx-versal.h | 2 ++
16
target/arm/internals.h | 5 +-
11
hw/arm/xlnx-versal.c | 9 ++++++++-
17
target/arm/helper.c | 12 +--
12
2 files changed, 10 insertions(+), 1 deletion(-)
18
target/arm/m_helper.c | 20 ++---
19
target/arm/ptw.c | 179 ++++++++++++++++++++--------------------
20
target/arm/tlb_helper.c | 9 +-
21
5 files changed, 111 insertions(+), 114 deletions(-)
13
22
14
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
23
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/xlnx-versal.h
25
--- a/target/arm/internals.h
17
+++ b/include/hw/arm/xlnx-versal.h
26
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@ typedef struct ARMCacheAttrs {
19
28
20
#include "hw/sysbus.h"
29
/* Fields that are valid upon success. */
21
#include "hw/arm/boot.h"
30
typedef struct GetPhysAddrResult {
22
+#include "hw/cpu/cluster.h"
31
- hwaddr phys;
23
#include "hw/or-irq.h"
32
- target_ulong page_size;
24
#include "hw/sd/sdhci.h"
33
- int prot;
25
#include "hw/intc/arm_gicv3.h"
34
- MemTxAttrs attrs;
26
@@ -XXX,XX +XXX,XX @@ struct Versal {
35
+ CPUTLBEntryFull f;
27
struct {
36
ARMCacheAttrs cacheattrs;
28
struct {
37
} GetPhysAddrResult;
29
MemoryRegion mr;
38
30
+ CPUClusterState cluster;
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
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
40
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/xlnx-versal.c
41
--- a/target/arm/helper.c
37
+++ b/hw/arm/xlnx-versal.c
42
+++ b/target/arm/helper.c
38
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
43
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
44
/* Create a 64-bit PAR */
45
par64 = (1 << 11); /* LPAE bit always set */
46
if (!ret) {
47
- par64 |= res.phys & ~0xfffULL;
48
- if (!res.attrs.secure) {
49
+ par64 |= res.f.phys_addr & ~0xfffULL;
50
+ if (!res.f.attrs.secure) {
51
par64 |= (1 << 9); /* NS */
52
}
53
par64 |= (uint64_t)res.cacheattrs.attrs << 56; /* ATTR */
54
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
55
*/
56
if (!ret) {
57
/* We do not set any attribute bits in the PAR */
58
- if (res.page_size == (1 << 24)
59
+ if (res.f.lg_page_size == 24
60
&& arm_feature(env, ARM_FEATURE_V7)) {
61
- par64 = (res.phys & 0xff000000) | (1 << 1);
62
+ par64 = (res.f.phys_addr & 0xff000000) | (1 << 1);
63
} else {
64
- par64 = res.phys & 0xfffff000;
65
+ par64 = res.f.phys_addr & 0xfffff000;
66
}
67
- if (!res.attrs.secure) {
68
+ if (!res.f.attrs.secure) {
69
par64 |= (1 << 9); /* NS */
70
}
71
} else {
72
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/m_helper.c
75
+++ b/target/arm/m_helper.c
76
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
77
}
78
goto pend_fault;
79
}
80
- address_space_stl_le(arm_addressspace(cs, res.attrs), res.phys, value,
81
- res.attrs, &txres);
82
+ address_space_stl_le(arm_addressspace(cs, res.f.attrs), res.f.phys_addr,
83
+ value, res.f.attrs, &txres);
84
if (txres != MEMTX_OK) {
85
/* BusFault trying to write the data */
86
if (mode == STACK_LAZYFP) {
87
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_read(ARMCPU *cpu, uint32_t *dest, uint32_t addr,
88
goto pend_fault;
89
}
90
91
- value = address_space_ldl(arm_addressspace(cs, res.attrs), res.phys,
92
- res.attrs, &txres);
93
+ value = address_space_ldl(arm_addressspace(cs, res.f.attrs),
94
+ res.f.phys_addr, res.f.attrs, &txres);
95
if (txres != MEMTX_OK) {
96
/* BusFault trying to read the data */
97
qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.UNSTKERR\n");
98
@@ -XXX,XX +XXX,XX @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx, bool secure,
99
qemu_log_mask(CPU_LOG_INT, "...really MemManage with CFSR.IACCVIOL\n");
100
return false;
101
}
102
- *insn = address_space_lduw_le(arm_addressspace(cs, res.attrs), res.phys,
103
- res.attrs, &txres);
104
+ *insn = address_space_lduw_le(arm_addressspace(cs, res.f.attrs),
105
+ res.f.phys_addr, res.f.attrs, &txres);
106
if (txres != MEMTX_OK) {
107
env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_IBUSERR_MASK;
108
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false);
109
@@ -XXX,XX +XXX,XX @@ static bool v7m_read_sg_stack_word(ARMCPU *cpu, ARMMMUIdx mmu_idx,
110
}
111
return false;
112
}
113
- value = address_space_ldl(arm_addressspace(cs, res.attrs), res.phys,
114
- res.attrs, &txres);
115
+ value = address_space_ldl(arm_addressspace(cs, res.f.attrs),
116
+ res.f.phys_addr, res.f.attrs, &txres);
117
if (txres != MEMTX_OK) {
118
/* BusFault trying to read the data */
119
qemu_log_mask(CPU_LOG_INT,
120
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
121
} else {
122
mrvalid = true;
123
}
124
- r = res.prot & PAGE_READ;
125
- rw = res.prot & PAGE_WRITE;
126
+ r = res.f.prot & PAGE_READ;
127
+ rw = res.f.prot & PAGE_WRITE;
128
} else {
129
r = false;
130
rw = false;
131
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/arm/ptw.c
134
+++ b/target/arm/ptw.c
135
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
136
assert(!is_secure);
137
}
138
139
- addr = s2.phys;
140
+ addr = s2.f.phys_addr;
141
}
142
return addr;
143
}
144
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
145
/* 1Mb section. */
146
phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
147
ap = (desc >> 10) & 3;
148
- result->page_size = 1024 * 1024;
149
+ result->f.lg_page_size = 20; /* 1MB */
150
} else {
151
/* Lookup l2 entry. */
152
if (type == 1) {
153
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
154
case 1: /* 64k page. */
155
phys_addr = (desc & 0xffff0000) | (address & 0xffff);
156
ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
157
- result->page_size = 0x10000;
158
+ result->f.lg_page_size = 16;
159
break;
160
case 2: /* 4k page. */
161
phys_addr = (desc & 0xfffff000) | (address & 0xfff);
162
ap = (desc >> (4 + ((address >> 9) & 6))) & 3;
163
- result->page_size = 0x1000;
164
+ result->f.lg_page_size = 12;
165
break;
166
case 3: /* 1k page, or ARMv6/XScale "extended small (4k) page" */
167
if (type == 1) {
168
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
169
if (arm_feature(env, ARM_FEATURE_XSCALE)
170
|| arm_feature(env, ARM_FEATURE_V6)) {
171
phys_addr = (desc & 0xfffff000) | (address & 0xfff);
172
- result->page_size = 0x1000;
173
+ result->f.lg_page_size = 12;
174
} else {
175
/*
176
* UNPREDICTABLE in ARMv5; we choose to take a
177
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
178
}
179
} else {
180
phys_addr = (desc & 0xfffffc00) | (address & 0x3ff);
181
- result->page_size = 0x400;
182
+ result->f.lg_page_size = 10;
183
}
184
ap = (desc >> 4) & 3;
185
break;
186
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
187
g_assert_not_reached();
188
}
189
}
190
- result->prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
191
- result->prot |= result->prot ? PAGE_EXEC : 0;
192
- if (!(result->prot & (1 << access_type))) {
193
+ result->f.prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
194
+ result->f.prot |= result->f.prot ? PAGE_EXEC : 0;
195
+ if (!(result->f.prot & (1 << access_type))) {
196
/* Access permission fault. */
197
fi->type = ARMFault_Permission;
198
goto do_fault;
199
}
200
- result->phys = phys_addr;
201
+ result->f.phys_addr = phys_addr;
202
return false;
203
do_fault:
204
fi->domain = domain;
205
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
206
phys_addr = (desc & 0xff000000) | (address & 0x00ffffff);
207
phys_addr |= (uint64_t)extract32(desc, 20, 4) << 32;
208
phys_addr |= (uint64_t)extract32(desc, 5, 4) << 36;
209
- result->page_size = 0x1000000;
210
+ result->f.lg_page_size = 24; /* 16MB */
211
} else {
212
/* Section. */
213
phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
214
- result->page_size = 0x100000;
215
+ result->f.lg_page_size = 20; /* 1MB */
216
}
217
ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);
218
xn = desc & (1 << 4);
219
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
220
case 1: /* 64k page. */
221
phys_addr = (desc & 0xffff0000) | (address & 0xffff);
222
xn = desc & (1 << 15);
223
- result->page_size = 0x10000;
224
+ result->f.lg_page_size = 16;
225
break;
226
case 2: case 3: /* 4k page. */
227
phys_addr = (desc & 0xfffff000) | (address & 0xfff);
228
xn = desc & 1;
229
- result->page_size = 0x1000;
230
+ result->f.lg_page_size = 12;
231
break;
232
default:
233
/* Never happens, but compiler isn't smart enough to tell. */
234
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
235
}
236
}
237
if (domain_prot == 3) {
238
- result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
239
+ result->f.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
240
} else {
241
if (pxn && !regime_is_user(env, mmu_idx)) {
242
xn = 1;
243
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
244
fi->type = ARMFault_AccessFlag;
245
goto do_fault;
246
}
247
- result->prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1);
248
+ result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1);
249
} else {
250
- result->prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
251
+ result->f.prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
252
}
253
- if (result->prot && !xn) {
254
- result->prot |= PAGE_EXEC;
255
+ if (result->f.prot && !xn) {
256
+ result->f.prot |= PAGE_EXEC;
257
}
258
- if (!(result->prot & (1 << access_type))) {
259
+ if (!(result->f.prot & (1 << access_type))) {
260
/* Access permission fault. */
261
fi->type = ARMFault_Permission;
262
goto do_fault;
263
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
264
* the CPU doesn't support TZ or this is a non-secure translation
265
* regime, because the attribute will already be non-secure.
266
*/
267
- result->attrs.secure = false;
268
+ result->f.attrs.secure = false;
269
}
270
- result->phys = phys_addr;
271
+ result->f.phys_addr = phys_addr;
272
return false;
273
do_fault:
274
fi->domain = domain;
275
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
276
if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
277
ns = mmu_idx == ARMMMUIdx_Stage2;
278
xn = extract32(attrs, 11, 2);
279
- result->prot = get_S2prot(env, ap, xn, s1_is_el0);
280
+ result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
281
} else {
282
ns = extract32(attrs, 3, 1);
283
xn = extract32(attrs, 12, 1);
284
pxn = extract32(attrs, 11, 1);
285
- result->prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
286
+ result->f.prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
287
}
288
289
fault_type = ARMFault_Permission;
290
- if (!(result->prot & (1 << access_type))) {
291
+ if (!(result->f.prot & (1 << access_type))) {
292
goto do_fault;
293
}
294
295
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
296
* the CPU doesn't support TZ or this is a non-secure translation
297
* regime, because the attribute will already be non-secure.
298
*/
299
- result->attrs.secure = false;
300
+ result->f.attrs.secure = false;
301
}
302
/* When in aarch64 mode, and BTI is enabled, remember GP in the IOTLB. */
303
if (aarch64 && guarded && cpu_isar_feature(aa64_bti, cpu)) {
304
- arm_tlb_bti_gp(&result->attrs) = true;
305
+ arm_tlb_bti_gp(&result->f.attrs) = true;
306
}
307
308
if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
309
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
310
result->cacheattrs.shareability = extract32(attrs, 6, 2);
311
}
312
313
- result->phys = descaddr;
314
- result->page_size = page_size;
315
+ result->f.phys_addr = descaddr;
316
+ result->f.lg_page_size = ctz64(page_size);
317
return false;
318
319
do_fault:
320
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
321
322
if (regime_translation_disabled(env, mmu_idx, is_secure)) {
323
/* MPU disabled. */
324
- result->phys = address;
325
- result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
326
+ result->f.phys_addr = address;
327
+ result->f.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
328
return false;
329
}
330
331
- result->phys = address;
332
+ result->f.phys_addr = address;
333
for (n = 7; n >= 0; n--) {
334
base = env->cp15.c6_region[n];
335
if ((base & 1) == 0) {
336
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
337
fi->level = 1;
338
return true;
339
}
340
- result->prot = PAGE_READ | PAGE_WRITE;
341
+ result->f.prot = PAGE_READ | PAGE_WRITE;
342
break;
343
case 2:
344
- result->prot = PAGE_READ;
345
+ result->f.prot = PAGE_READ;
346
if (!is_user) {
347
- result->prot |= PAGE_WRITE;
348
+ result->f.prot |= PAGE_WRITE;
349
}
350
break;
351
case 3:
352
- result->prot = PAGE_READ | PAGE_WRITE;
353
+ result->f.prot = PAGE_READ | PAGE_WRITE;
354
break;
355
case 5:
356
if (is_user) {
357
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
358
fi->level = 1;
359
return true;
360
}
361
- result->prot = PAGE_READ;
362
+ result->f.prot = PAGE_READ;
363
break;
364
case 6:
365
- result->prot = PAGE_READ;
366
+ result->f.prot = PAGE_READ;
367
break;
368
default:
369
/* Bad permission. */
370
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
371
fi->level = 1;
372
return true;
373
}
374
- result->prot |= PAGE_EXEC;
375
+ result->f.prot |= PAGE_EXEC;
376
return false;
377
}
378
379
static void get_phys_addr_pmsav7_default(CPUARMState *env, ARMMMUIdx mmu_idx,
380
- int32_t address, int *prot)
381
+ int32_t address, uint8_t *prot)
39
{
382
{
40
int i;
383
if (!arm_feature(env, ARM_FEATURE_M)) {
41
384
*prot = PAGE_READ | PAGE_WRITE;
42
+ object_initialize_child(OBJECT(s), "apu-cluster", &s->fpd.apu.cluster,
385
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
43
+ TYPE_CPU_CLUSTER);
386
int n;
44
+ qdev_prop_set_uint32(DEVICE(&s->fpd.apu.cluster), "cluster-id", 0);
387
bool is_user = regime_is_user(env, mmu_idx);
45
+
388
46
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
389
- result->phys = address;
47
Object *obj;
390
- result->page_size = TARGET_PAGE_SIZE;
48
391
- result->prot = 0;
49
- object_initialize_child(OBJECT(s), "apu-cpu[*]", &s->fpd.apu.cpu[i],
392
+ result->f.phys_addr = address;
50
+ object_initialize_child(OBJECT(&s->fpd.apu.cluster),
393
+ result->f.lg_page_size = TARGET_PAGE_BITS;
51
+ "apu-cpu[*]", &s->fpd.apu.cpu[i],
394
+ result->f.prot = 0;
52
XLNX_VERSAL_ACPU_TYPE);
395
53
obj = OBJECT(&s->fpd.apu.cpu[i]);
396
if (regime_translation_disabled(env, mmu_idx, secure) ||
54
if (i) {
397
m_is_ppb_region(env, address)) {
55
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
398
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
56
&error_abort);
399
* which always does a direct read using address_space_ldl(), rather
57
qdev_realize(DEVICE(obj), NULL, &error_fatal);
400
* than going via this function, so we don't need to check that here.
58
}
401
*/
59
+
402
- get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->prot);
60
+ qdev_realize(DEVICE(&s->fpd.apu.cluster), NULL, &error_fatal);
403
+ get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->f.prot);
404
} else { /* MPU enabled */
405
for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
406
/* region search */
407
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
408
if (ranges_overlap(base, rmask,
409
address & TARGET_PAGE_MASK,
410
TARGET_PAGE_SIZE)) {
411
- result->page_size = 1;
412
+ result->f.lg_page_size = 0;
413
}
414
continue;
415
}
416
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
417
continue;
418
}
419
if (rsize < TARGET_PAGE_BITS) {
420
- result->page_size = 1 << rsize;
421
+ result->f.lg_page_size = rsize;
422
}
423
break;
424
}
425
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
426
fi->type = ARMFault_Background;
427
return true;
428
}
429
- get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->prot);
430
+ get_phys_addr_pmsav7_default(env, mmu_idx, address,
431
+ &result->f.prot);
432
} else { /* a MPU hit! */
433
uint32_t ap = extract32(env->pmsav7.dracr[n], 8, 3);
434
uint32_t xn = extract32(env->pmsav7.dracr[n], 12, 1);
435
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
436
case 5:
437
break; /* no access */
438
case 3:
439
- result->prot |= PAGE_WRITE;
440
+ result->f.prot |= PAGE_WRITE;
441
/* fall through */
442
case 2:
443
case 6:
444
- result->prot |= PAGE_READ | PAGE_EXEC;
445
+ result->f.prot |= PAGE_READ | PAGE_EXEC;
446
break;
447
case 7:
448
/* for v7M, same as 6; for R profile a reserved value */
449
if (arm_feature(env, ARM_FEATURE_M)) {
450
- result->prot |= PAGE_READ | PAGE_EXEC;
451
+ result->f.prot |= PAGE_READ | PAGE_EXEC;
452
break;
453
}
454
/* fall through */
455
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
456
case 1:
457
case 2:
458
case 3:
459
- result->prot |= PAGE_WRITE;
460
+ result->f.prot |= PAGE_WRITE;
461
/* fall through */
462
case 5:
463
case 6:
464
- result->prot |= PAGE_READ | PAGE_EXEC;
465
+ result->f.prot |= PAGE_READ | PAGE_EXEC;
466
break;
467
case 7:
468
/* for v7M, same as 6; for R profile a reserved value */
469
if (arm_feature(env, ARM_FEATURE_M)) {
470
- result->prot |= PAGE_READ | PAGE_EXEC;
471
+ result->f.prot |= PAGE_READ | PAGE_EXEC;
472
break;
473
}
474
/* fall through */
475
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
476
477
/* execute never */
478
if (xn) {
479
- result->prot &= ~PAGE_EXEC;
480
+ result->f.prot &= ~PAGE_EXEC;
481
}
482
}
483
}
484
485
fi->type = ARMFault_Permission;
486
fi->level = 1;
487
- return !(result->prot & (1 << access_type));
488
+ return !(result->f.prot & (1 << access_type));
61
}
489
}
62
490
63
static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
491
bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
492
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
493
uint32_t addr_page_base = address & TARGET_PAGE_MASK;
494
uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
495
496
- result->page_size = TARGET_PAGE_SIZE;
497
- result->phys = address;
498
- result->prot = 0;
499
+ result->f.lg_page_size = TARGET_PAGE_BITS;
500
+ result->f.phys_addr = address;
501
+ result->f.prot = 0;
502
if (mregion) {
503
*mregion = -1;
504
}
505
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
506
ranges_overlap(base, limit - base + 1,
507
addr_page_base,
508
TARGET_PAGE_SIZE)) {
509
- result->page_size = 1;
510
+ result->f.lg_page_size = 0;
511
}
512
continue;
513
}
514
515
if (base > addr_page_base || limit < addr_page_limit) {
516
- result->page_size = 1;
517
+ result->f.lg_page_size = 0;
518
}
519
520
if (matchregion != -1) {
521
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
522
523
if (matchregion == -1) {
524
/* hit using the background region */
525
- get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->prot);
526
+ get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->f.prot);
527
} else {
528
uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
529
uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
530
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
531
xn = 1;
532
}
533
534
- result->prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
535
- if (result->prot && !xn && !(pxn && !is_user)) {
536
- result->prot |= PAGE_EXEC;
537
+ result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
538
+ if (result->f.prot && !xn && !(pxn && !is_user)) {
539
+ result->f.prot |= PAGE_EXEC;
540
}
541
/*
542
* We don't need to look the attribute up in the MAIR0/MAIR1
543
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
544
545
fi->type = ARMFault_Permission;
546
fi->level = 1;
547
- return !(result->prot & (1 << access_type));
548
+ return !(result->f.prot & (1 << access_type));
549
}
550
551
static bool v8m_is_sau_exempt(CPUARMState *env,
552
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
553
} else {
554
fi->type = ARMFault_QEMU_SFault;
555
}
556
- result->page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
557
- result->phys = address;
558
- result->prot = 0;
559
+ result->f.lg_page_size = sattrs.subpage ? 0 : TARGET_PAGE_BITS;
560
+ result->f.phys_addr = address;
561
+ result->f.prot = 0;
562
return true;
563
}
564
} else {
565
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
566
* might downgrade a secure access to nonsecure.
567
*/
568
if (sattrs.ns) {
569
- result->attrs.secure = false;
570
+ result->f.attrs.secure = false;
571
} else if (!secure) {
572
/*
573
* NS access to S memory must fault.
574
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
575
* for M_FAKE_FSR_SFAULT in arm_v7m_cpu_do_interrupt().
576
*/
577
fi->type = ARMFault_QEMU_SFault;
578
- result->page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
579
- result->phys = address;
580
- result->prot = 0;
581
+ result->f.lg_page_size = sattrs.subpage ? 0 : TARGET_PAGE_BITS;
582
+ result->f.phys_addr = address;
583
+ result->f.prot = 0;
584
return true;
585
}
586
}
587
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
588
ret = pmsav8_mpu_lookup(env, address, access_type, mmu_idx, secure,
589
result, fi, NULL);
590
if (sattrs.subpage) {
591
- result->page_size = 1;
592
+ result->f.lg_page_size = 0;
593
}
594
return ret;
595
}
596
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
597
result->cacheattrs.is_s2_format = false;
598
}
599
600
- result->phys = address;
601
- result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
602
- result->page_size = TARGET_PAGE_SIZE;
603
+ result->f.phys_addr = address;
604
+ result->f.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
605
+ result->f.lg_page_size = TARGET_PAGE_BITS;
606
result->cacheattrs.shareability = shareability;
607
result->cacheattrs.attrs = memattr;
608
return 0;
609
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
610
return ret;
611
}
612
613
- ipa = result->phys;
614
- ipa_secure = result->attrs.secure;
615
+ ipa = result->f.phys_addr;
616
+ ipa_secure = result->f.attrs.secure;
617
if (is_secure) {
618
/* Select TCR based on the NS bit from the S1 walk. */
619
s2walk_secure = !(ipa_secure
620
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
621
* Save the stage1 results so that we may merge
622
* prot and cacheattrs later.
623
*/
624
- s1_prot = result->prot;
625
+ s1_prot = result->f.prot;
626
cacheattrs1 = result->cacheattrs;
627
memset(result, 0, sizeof(*result));
628
629
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
630
fi->s2addr = ipa;
631
632
/* Combine the S1 and S2 perms. */
633
- result->prot &= s1_prot;
634
+ result->f.prot &= s1_prot;
635
636
/* If S2 fails, return early. */
637
if (ret) {
638
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
639
* Check if IPA translates to secure or non-secure PA space.
640
* Note that VSTCR overrides VTCR and {N}SW overrides {N}SA.
641
*/
642
- result->attrs.secure =
643
+ result->f.attrs.secure =
644
(is_secure
645
&& !(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW))
646
&& (ipa_secure
647
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
648
* cannot upgrade an non-secure translation regime's attributes
649
* to secure.
650
*/
651
- result->attrs.secure = is_secure;
652
- result->attrs.user = regime_is_user(env, mmu_idx);
653
+ result->f.attrs.secure = is_secure;
654
+ result->f.attrs.user = regime_is_user(env, mmu_idx);
655
656
/*
657
* Fast Context Switch Extension. This doesn't exist at all in v8.
658
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
659
660
if (arm_feature(env, ARM_FEATURE_PMSA)) {
661
bool ret;
662
- result->page_size = TARGET_PAGE_SIZE;
663
+ result->f.lg_page_size = TARGET_PAGE_BITS;
664
665
if (arm_feature(env, ARM_FEATURE_V8)) {
666
/* PMSAv8 */
667
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
668
(access_type == MMU_DATA_STORE ? "writing" : "execute"),
669
(uint32_t)address, mmu_idx,
670
ret ? "Miss" : "Hit",
671
- result->prot & PAGE_READ ? 'r' : '-',
672
- result->prot & PAGE_WRITE ? 'w' : '-',
673
- result->prot & PAGE_EXEC ? 'x' : '-');
674
+ result->f.prot & PAGE_READ ? 'r' : '-',
675
+ result->f.prot & PAGE_WRITE ? 'w' : '-',
676
+ result->f.prot & PAGE_EXEC ? 'x' : '-');
677
678
return ret;
679
}
680
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
681
bool ret;
682
683
ret = get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &res, &fi);
684
- *attrs = res.attrs;
685
+ *attrs = res.f.attrs;
686
687
if (ret) {
688
return -1;
689
}
690
- return res.phys;
691
+ return res.f.phys_addr;
692
}
693
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
694
index XXXXXXX..XXXXXXX 100644
695
--- a/target/arm/tlb_helper.c
696
+++ b/target/arm/tlb_helper.c
697
@@ -XXX,XX +XXX,XX @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
698
* target page size are handled specially, so for those we
699
* pass in the exact addresses.
700
*/
701
- if (res.page_size >= TARGET_PAGE_SIZE) {
702
- res.phys &= TARGET_PAGE_MASK;
703
+ if (res.f.lg_page_size >= TARGET_PAGE_BITS) {
704
+ res.f.phys_addr &= TARGET_PAGE_MASK;
705
address &= TARGET_PAGE_MASK;
706
}
707
/* Notice and record tagged memory. */
708
if (cpu_isar_feature(aa64_mte, cpu) && res.cacheattrs.attrs == 0xf0) {
709
- arm_tlb_mte_tagged(&res.attrs) = true;
710
+ arm_tlb_mte_tagged(&res.f.attrs) = true;
711
}
712
713
- tlb_set_page_with_attrs(cs, address, res.phys, res.attrs,
714
- res.prot, mmu_idx, res.page_size);
715
+ tlb_set_page_full(cs, mmu_idx, address, &res.f);
716
return true;
717
} else if (probe) {
718
return false;
64
--
719
--
65
2.25.1
720
2.25.1
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Jerome Forissier <jerome.forissier@linaro.org>
2
2
3
Similar to the Aspeed code in include/misc/aspeed_scu.h, we define
3
According to the Linux kernel booting.rst [1], CPTR_EL3.ESM and
4
the PWRON STRAP fields in their corresponding module for NPCM7XX.
4
SCR_EL3.EnTP2 must be initialized to 1 when EL3 is present and FEAT_SME
5
is advertised. This has to be taken care of when QEMU boots directly
6
into the kernel (i.e., "-M virt,secure=on -cpu max -kernel Image").
5
7
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
8
Cc: qemu-stable@nongnu.org
7
Reviewed-by: Patrick Venture <venture@google.com>
9
Fixes: 78cb9776662a ("target/arm: Enable SME for -cpu max")
8
Message-id: 20220411165842.3912945-2-wuhaotsh@google.com
10
Link: [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/arm64/booting.rst?h=v6.0#n321
11
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
12
Message-id: 20221003145641.1921467-1-jerome.forissier@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
include/hw/misc/npcm7xx_gcr.h | 30 ++++++++++++++++++++++++++++++
16
hw/arm/boot.c | 4 ++++
13
1 file changed, 30 insertions(+)
17
1 file changed, 4 insertions(+)
14
18
15
diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h
19
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/misc/npcm7xx_gcr.h
21
--- a/hw/arm/boot.c
18
+++ b/include/hw/misc/npcm7xx_gcr.h
22
+++ b/hw/arm/boot.c
19
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
20
#include "exec/memory.h"
24
if (cpu_isar_feature(aa64_sve, cpu)) {
21
#include "hw/sysbus.h"
25
env->cp15.cptr_el[3] |= R_CPTR_EL3_EZ_MASK;
22
26
}
23
+/*
27
+ if (cpu_isar_feature(aa64_sme, cpu)) {
24
+ * NPCM7XX PWRON STRAP bit fields
28
+ env->cp15.cptr_el[3] |= R_CPTR_EL3_ESM_MASK;
25
+ * 12: SPI0 powered by VSBV3 at 1.8V
29
+ env->cp15.scr_el3 |= SCR_ENTP2;
26
+ * 11: System flash attached to BMC
30
+ }
27
+ * 10: BSP alternative pins.
31
/* AArch64 kernels never boot in secure mode */
28
+ * 9:8: Flash UART command route enabled.
32
assert(!info->secure_boot);
29
+ * 7: Security enabled.
33
/* This hook is only supported for AArch32 currently:
30
+ * 6: HI-Z state control.
31
+ * 5: ECC disabled.
32
+ * 4: Reserved
33
+ * 3: JTAG2 enabled.
34
+ * 2:0: CPU and DRAM clock frequency.
35
+ */
36
+#define NPCM7XX_PWRON_STRAP_SPI0F18 BIT(12)
37
+#define NPCM7XX_PWRON_STRAP_SFAB BIT(11)
38
+#define NPCM7XX_PWRON_STRAP_BSPA BIT(10)
39
+#define NPCM7XX_PWRON_STRAP_FUP(x) ((x) << 8)
40
+#define FUP_NORM_UART2 3
41
+#define FUP_PROG_UART3 2
42
+#define FUP_PROG_UART2 1
43
+#define FUP_NORM_UART3 0
44
+#define NPCM7XX_PWRON_STRAP_SECEN BIT(7)
45
+#define NPCM7XX_PWRON_STRAP_HIZ BIT(6)
46
+#define NPCM7XX_PWRON_STRAP_ECC BIT(5)
47
+#define NPCM7XX_PWRON_STRAP_RESERVE1 BIT(4)
48
+#define NPCM7XX_PWRON_STRAP_J2EN BIT(3)
49
+#define NPCM7XX_PWRON_STRAP_CKFRQ(x) (x)
50
+#define CKFRQ_SKIPINIT 0x000
51
+#define CKFRQ_DEFAULT 0x111
52
+
53
/*
54
* Number of registers in our device state structure. Don't change this without
55
* incrementing the version_id in the vmstate.
56
--
34
--
57
2.25.1
35
2.25.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
Arm CPUs support some subset of the granule (page) sizes 4K, 16K and
2
2
64K. The guest selects the one it wants using bits in the TCR_ELx
3
Connect the 4 TTC timers on the ZynqMP.
3
registers. If it tries to program these registers with a value that
4
4
is either reserved or which requests a size that the CPU does not
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
5
implement, the architecture requires that the CPU behaves as if the
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
field was programmed to some size that has been implemented.
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
Currently we don't implement this, and instead let the guest use any
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
granule size, even if the CPU ID register fields say it isn't
9
Message-id: 20220331222017.2914409-3-edgar.iglesias@gmail.com
9
present.
10
11
Make aa64_va_parameters() check against the supported granule size
12
and force use of a different one if it is not implemented.
13
14
(A subsequent commit will make ARMVAParameters use the new enum
15
rather than the current pair of using16k/using64k bools.)
16
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Message-id: 20221003162315.2833797-2-peter.maydell@linaro.org
11
---
20
---
12
include/hw/arm/xlnx-zynqmp.h | 4 ++++
21
target/arm/cpu.h | 33 +++++++++++++
13
hw/arm/xlnx-zynqmp.c | 22 ++++++++++++++++++++++
22
target/arm/internals.h | 9 ++++
14
2 files changed, 26 insertions(+)
23
target/arm/helper.c | 102 +++++++++++++++++++++++++++++++++++++----
15
24
3 files changed, 136 insertions(+), 8 deletions(-)
16
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
25
26
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-zynqmp.h
28
--- a/target/arm/cpu.h
19
+++ b/include/hw/arm/xlnx-zynqmp.h
29
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id)
21
#include "hw/or-irq.h"
31
return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id));
22
#include "hw/misc/xlnx-zynqmp-apu-ctrl.h"
32
}
23
#include "hw/misc/xlnx-zynqmp-crf.h"
33
24
+#include "hw/timer/cadence_ttc.h"
34
+static inline bool isar_feature_aa64_tgran4(const ARMISARegisters *id)
25
35
+{
26
#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
36
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 0;
27
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
37
+}
28
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
38
+
29
#define XLNX_ZYNQMP_MAX_RAM_SIZE (XLNX_ZYNQMP_MAX_LOW_RAM_SIZE + \
39
+static inline bool isar_feature_aa64_tgran16(const ARMISARegisters *id)
30
XLNX_ZYNQMP_MAX_HIGH_RAM_SIZE)
40
+{
31
41
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 1;
32
+#define XLNX_ZYNQMP_NUM_TTC 4
42
+}
43
+
44
+static inline bool isar_feature_aa64_tgran64(const ARMISARegisters *id)
45
+{
46
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64) >= 0;
47
+}
48
+
49
+static inline bool isar_feature_aa64_tgran4_2(const ARMISARegisters *id)
50
+{
51
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
52
+ return t >= 2 || (t == 0 && isar_feature_aa64_tgran4(id));
53
+}
54
+
55
+static inline bool isar_feature_aa64_tgran16_2(const ARMISARegisters *id)
56
+{
57
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
58
+ return t >= 2 || (t == 0 && isar_feature_aa64_tgran16(id));
59
+}
60
+
61
+static inline bool isar_feature_aa64_tgran64_2(const ARMISARegisters *id)
62
+{
63
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64_2);
64
+ return t >= 2 || (t == 0 && isar_feature_aa64_tgran64(id));
65
+}
66
+
67
static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
68
{
69
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
70
diff --git a/target/arm/internals.h b/target/arm/internals.h
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/internals.h
73
+++ b/target/arm/internals.h
74
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
75
return valid;
76
}
77
78
+/* Granule size (i.e. page size) */
79
+typedef enum ARMGranuleSize {
80
+ /* Same order as TG0 encoding */
81
+ Gran4K,
82
+ Gran64K,
83
+ Gran16K,
84
+ GranInvalid,
85
+} ARMGranuleSize;
33
+
86
+
34
/*
87
/*
35
* Unimplemented mmio regions needed to boot some images.
88
* Parameters of a given virtual address, as extracted from the
36
*/
89
* translation control register (TCR) for a given regime.
37
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
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
91
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/arm/xlnx-zynqmp.c
92
--- a/target/arm/helper.c
48
+++ b/hw/arm/xlnx-zynqmp.c
93
+++ b/target/arm/helper.c
49
@@ -XXX,XX +XXX,XX @@
94
@@ -XXX,XX +XXX,XX @@ static int aa64_va_parameter_tcma(uint64_t tcr, ARMMMUIdx mmu_idx)
50
#define APU_ADDR 0xfd5c0000
95
}
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
}
96
}
62
97
63
+static void xlnx_zynqmp_create_ttc(XlnxZynqMPState *s, qemu_irq *gic)
98
+static ARMGranuleSize tg0_to_gran_size(int tg)
64
+{
99
+{
65
+ SysBusDevice *sbd;
100
+ switch (tg) {
66
+ int i, irq;
101
+ case 0:
67
+
102
+ return Gran4K;
68
+ for (i = 0; i < XLNX_ZYNQMP_NUM_TTC; i++) {
103
+ case 1:
69
+ object_initialize_child(OBJECT(s), "ttc[*]", &s->ttc[i],
104
+ return Gran64K;
70
+ TYPE_CADENCE_TTC);
105
+ case 2:
71
+ sbd = SYS_BUS_DEVICE(&s->ttc[i]);
106
+ return Gran16K;
72
+
107
+ default:
73
+ sysbus_realize(sbd, &error_fatal);
108
+ return GranInvalid;
74
+ sysbus_mmio_map(sbd, 0, TTC0_ADDR + i * 0x10000);
109
+ }
75
+ for (irq = 0; irq < 3; irq++) {
110
+}
76
+ sysbus_connect_irq(sbd, irq, gic[TTC0_IRQ + i * 3 + irq]);
111
+
112
+static ARMGranuleSize tg1_to_gran_size(int tg)
113
+{
114
+ switch (tg) {
115
+ case 1:
116
+ return Gran16K;
117
+ case 2:
118
+ return Gran4K;
119
+ case 3:
120
+ return Gran64K;
121
+ default:
122
+ return GranInvalid;
123
+ }
124
+}
125
+
126
+static inline bool have4k(ARMCPU *cpu, bool stage2)
127
+{
128
+ return stage2 ? cpu_isar_feature(aa64_tgran4_2, cpu)
129
+ : cpu_isar_feature(aa64_tgran4, cpu);
130
+}
131
+
132
+static inline bool have16k(ARMCPU *cpu, bool stage2)
133
+{
134
+ return stage2 ? cpu_isar_feature(aa64_tgran16_2, cpu)
135
+ : cpu_isar_feature(aa64_tgran16, cpu);
136
+}
137
+
138
+static inline bool have64k(ARMCPU *cpu, bool stage2)
139
+{
140
+ return stage2 ? cpu_isar_feature(aa64_tgran64_2, cpu)
141
+ : cpu_isar_feature(aa64_tgran64, cpu);
142
+}
143
+
144
+static ARMGranuleSize sanitize_gran_size(ARMCPU *cpu, ARMGranuleSize gran,
145
+ bool stage2)
146
+{
147
+ switch (gran) {
148
+ case Gran4K:
149
+ if (have4k(cpu, stage2)) {
150
+ return gran;
77
+ }
151
+ }
78
+ }
152
+ break;
79
+}
153
+ case Gran16K:
80
+
154
+ if (have16k(cpu, stage2)) {
81
static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
155
+ return gran;
156
+ }
157
+ break;
158
+ case Gran64K:
159
+ if (have64k(cpu, stage2)) {
160
+ return gran;
161
+ }
162
+ break;
163
+ case GranInvalid:
164
+ break;
165
+ }
166
+ /*
167
+ * If the guest selects a granule size that isn't implemented,
168
+ * the architecture requires that we behave as if it selected one
169
+ * that is (with an IMPDEF choice of which one to pick). We choose
170
+ * to implement the smallest supported granule size.
171
+ */
172
+ if (have4k(cpu, stage2)) {
173
+ return Gran4K;
174
+ }
175
+ if (have16k(cpu, stage2)) {
176
+ return Gran16K;
177
+ }
178
+ assert(have64k(cpu, stage2));
179
+ return Gran64K;
180
+}
181
+
182
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
183
ARMMMUIdx mmu_idx, bool data)
82
{
184
{
83
static const struct UnimpInfo {
185
uint64_t tcr = regime_tcr(env, mmu_idx);
84
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
186
bool epd, hpd, using16k, using64k, tsz_oob, ds;
85
xlnx_zynqmp_create_efuse(s, gic_spi);
187
int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
86
xlnx_zynqmp_create_apu_ctrl(s, gic_spi);
188
+ ARMGranuleSize gran;
87
xlnx_zynqmp_create_crf(s, gic_spi);
189
ARMCPU *cpu = env_archcpu(env);
88
+ xlnx_zynqmp_create_ttc(s, gic_spi);
190
+ bool stage2 = mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S;
89
xlnx_zynqmp_create_unimp_mmio(s);
191
90
192
if (!regime_has_2_ranges(mmu_idx)) {
91
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
193
select = 0;
194
tsz = extract32(tcr, 0, 6);
195
- using64k = extract32(tcr, 14, 1);
196
- using16k = extract32(tcr, 15, 1);
197
- if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
198
+ gran = tg0_to_gran_size(extract32(tcr, 14, 2));
199
+ if (stage2) {
200
/* VTCR_EL2 */
201
hpd = false;
202
} else {
203
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
204
select = extract64(va, 55, 1);
205
if (!select) {
206
tsz = extract32(tcr, 0, 6);
207
+ gran = tg0_to_gran_size(extract32(tcr, 14, 2));
208
epd = extract32(tcr, 7, 1);
209
sh = extract32(tcr, 12, 2);
210
- using64k = extract32(tcr, 14, 1);
211
- using16k = extract32(tcr, 15, 1);
212
hpd = extract64(tcr, 41, 1);
213
} else {
214
- int tg = extract32(tcr, 30, 2);
215
- using16k = tg == 1;
216
- using64k = tg == 3;
217
tsz = extract32(tcr, 16, 6);
218
+ gran = tg1_to_gran_size(extract32(tcr, 30, 2));
219
epd = extract32(tcr, 23, 1);
220
sh = extract32(tcr, 28, 2);
221
hpd = extract64(tcr, 42, 1);
222
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
223
ds = extract64(tcr, 59, 1);
224
}
225
226
+ gran = sanitize_gran_size(cpu, gran, stage2);
227
+ using64k = gran == Gran64K;
228
+ using16k = gran == Gran16K;
229
+
230
if (cpu_isar_feature(aa64_st, cpu)) {
231
max_tsz = 48 - using64k;
232
} else {
92
--
233
--
93
2.25.1
234
2.25.1
diff view generated by jsdifflib
Deleted patch
1
The only time we use the int_gic_irq[] array in the Exynos4210Irq
2
struct is in the exynos4210_realize() function: we initialize it with
3
the GPIO inputs of the a9mpcore device, and then a bit later on we
4
connect those to the outputs of the internal combiner. Now that the
5
a9mpcore object is easily accessible as s->a9mpcore we can make the
6
connection directly from one device to the other without going via
7
this array.
8
1
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-5-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 1 -
14
hw/arm/exynos4210.c | 6 ++----
15
2 files changed, 2 insertions(+), 5 deletions(-)
16
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
20
+++ b/include/hw/arm/exynos4210.h
21
@@ -XXX,XX +XXX,XX @@
22
typedef struct Exynos4210Irq {
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
25
- qemu_irq int_gic_irq[EXYNOS4210_INT_GIC_NIRQ];
26
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
27
qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
28
} Exynos4210Irq;
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
32
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
34
sysbus_connect_irq(busdev, n,
35
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
36
}
37
- for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
38
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
39
- }
40
41
/* Cache controller */
42
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
43
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
44
busdev = SYS_BUS_DEVICE(dev);
45
sysbus_realize_and_unref(busdev, &error_fatal);
46
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
47
- sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
48
+ sysbus_connect_irq(busdev, n,
49
+ qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
50
}
51
exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
52
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
53
--
54
2.25.1
diff view generated by jsdifflib
Deleted patch
1
Fix a missing set of spaces around '-' in the definition of
2
combiner_grp_to_gic_id[]. We're about to move this code, so
3
fix the style issue first to keep checkpatch happy with the
4
code-motion patch.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220404154658.565020-7-peter.maydell@linaro.org
9
---
10
hw/intc/exynos4210_gic.c | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
12
13
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/intc/exynos4210_gic.c
16
+++ b/hw/intc/exynos4210_gic.c
17
@@ -XXX,XX +XXX,XX @@ enum ExtInt {
18
*/
19
20
static const uint32_t
21
-combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
22
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
23
/* int combiner groups 16-19 */
24
{ }, { }, { }, { },
25
/* int combiner group 20 */
26
--
27
2.25.1
diff view generated by jsdifflib
1
The function exynos4210_init_board_irqs() currently lives in
1
Now we have an enum for the granule size, use it in the
2
exynos4210_gic.c, but it isn't really part of the exynos4210.gic
2
ARMVAParameters struct instead of the using16k/using64k bools.
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
3
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-8-peter.maydell@linaro.org
6
Message-id: 20221003162315.2833797-3-peter.maydell@linaro.org
12
---
7
---
13
include/hw/arm/exynos4210.h | 4 -
8
target/arm/internals.h | 23 +++++++++++++++++++++--
14
hw/arm/exynos4210.c | 202 +++++++++++++++++++++++++++++++++++
9
target/arm/helper.c | 39 ++++++++++++++++++++++++++++-----------
15
hw/intc/exynos4210_gic.c | 204 ------------------------------------
10
target/arm/ptw.c | 8 +-------
16
3 files changed, 202 insertions(+), 208 deletions(-)
11
3 files changed, 50 insertions(+), 20 deletions(-)
17
12
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
13
diff --git a/target/arm/internals.h b/target/arm/internals.h
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/exynos4210.h
15
--- a/target/arm/internals.h
21
+++ b/include/hw/arm/exynos4210.h
16
+++ b/target/arm/internals.h
22
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
17
@@ -XXX,XX +XXX,XX @@ typedef enum ARMGranuleSize {
23
void exynos4210_write_secondary(ARMCPU *cpu,
18
GranInvalid,
24
const struct arm_boot_info *info);
19
} ARMGranuleSize;
25
20
26
-/* Initialize board IRQs.
21
+/**
27
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs */
22
+ * arm_granule_bits: Return address size of the granule in bits
28
-void exynos4210_init_board_irqs(Exynos4210State *s);
23
+ *
29
-
24
+ * Return the address size of the granule in bits. This corresponds
30
/* Get IRQ number from exynos4210 IRQ subsystem stub.
25
+ * to the pseudocode TGxGranuleBits().
31
* To identify IRQ source use internal combiner group and bit number
32
* grp - group number
33
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/exynos4210.c
36
+++ b/hw/arm/exynos4210.c
37
@@ -XXX,XX +XXX,XX @@
38
#define EXYNOS4210_PL330_BASE1_ADDR 0x12690000
39
#define EXYNOS4210_PL330_BASE2_ADDR 0x12850000
40
41
+enum ExtGicId {
42
+ EXT_GIC_ID_MDMA_LCD0 = 66,
43
+ EXT_GIC_ID_PDMA0,
44
+ EXT_GIC_ID_PDMA1,
45
+ EXT_GIC_ID_TIMER0,
46
+ EXT_GIC_ID_TIMER1,
47
+ EXT_GIC_ID_TIMER2,
48
+ EXT_GIC_ID_TIMER3,
49
+ EXT_GIC_ID_TIMER4,
50
+ EXT_GIC_ID_MCT_L0,
51
+ EXT_GIC_ID_WDT,
52
+ EXT_GIC_ID_RTC_ALARM,
53
+ EXT_GIC_ID_RTC_TIC,
54
+ EXT_GIC_ID_GPIO_XB,
55
+ EXT_GIC_ID_GPIO_XA,
56
+ EXT_GIC_ID_MCT_L1,
57
+ EXT_GIC_ID_IEM_APC,
58
+ EXT_GIC_ID_IEM_IEC,
59
+ EXT_GIC_ID_NFC,
60
+ EXT_GIC_ID_UART0,
61
+ EXT_GIC_ID_UART1,
62
+ EXT_GIC_ID_UART2,
63
+ EXT_GIC_ID_UART3,
64
+ EXT_GIC_ID_UART4,
65
+ EXT_GIC_ID_MCT_G0,
66
+ EXT_GIC_ID_I2C0,
67
+ EXT_GIC_ID_I2C1,
68
+ EXT_GIC_ID_I2C2,
69
+ EXT_GIC_ID_I2C3,
70
+ EXT_GIC_ID_I2C4,
71
+ EXT_GIC_ID_I2C5,
72
+ EXT_GIC_ID_I2C6,
73
+ EXT_GIC_ID_I2C7,
74
+ EXT_GIC_ID_SPI0,
75
+ EXT_GIC_ID_SPI1,
76
+ EXT_GIC_ID_SPI2,
77
+ EXT_GIC_ID_MCT_G1,
78
+ EXT_GIC_ID_USB_HOST,
79
+ EXT_GIC_ID_USB_DEVICE,
80
+ EXT_GIC_ID_MODEMIF,
81
+ EXT_GIC_ID_HSMMC0,
82
+ EXT_GIC_ID_HSMMC1,
83
+ EXT_GIC_ID_HSMMC2,
84
+ EXT_GIC_ID_HSMMC3,
85
+ EXT_GIC_ID_SDMMC,
86
+ EXT_GIC_ID_MIPI_CSI_4LANE,
87
+ EXT_GIC_ID_MIPI_DSI_4LANE,
88
+ EXT_GIC_ID_MIPI_CSI_2LANE,
89
+ EXT_GIC_ID_MIPI_DSI_2LANE,
90
+ EXT_GIC_ID_ONENAND_AUDI,
91
+ EXT_GIC_ID_ROTATOR,
92
+ EXT_GIC_ID_FIMC0,
93
+ EXT_GIC_ID_FIMC1,
94
+ EXT_GIC_ID_FIMC2,
95
+ EXT_GIC_ID_FIMC3,
96
+ EXT_GIC_ID_JPEG,
97
+ EXT_GIC_ID_2D,
98
+ EXT_GIC_ID_PCIe,
99
+ EXT_GIC_ID_MIXER,
100
+ EXT_GIC_ID_HDMI,
101
+ EXT_GIC_ID_HDMI_I2C,
102
+ EXT_GIC_ID_MFC,
103
+ EXT_GIC_ID_TVENC,
104
+};
105
+
106
+enum ExtInt {
107
+ EXT_GIC_ID_EXTINT0 = 48,
108
+ EXT_GIC_ID_EXTINT1,
109
+ EXT_GIC_ID_EXTINT2,
110
+ EXT_GIC_ID_EXTINT3,
111
+ EXT_GIC_ID_EXTINT4,
112
+ EXT_GIC_ID_EXTINT5,
113
+ EXT_GIC_ID_EXTINT6,
114
+ EXT_GIC_ID_EXTINT7,
115
+ EXT_GIC_ID_EXTINT8,
116
+ EXT_GIC_ID_EXTINT9,
117
+ EXT_GIC_ID_EXTINT10,
118
+ EXT_GIC_ID_EXTINT11,
119
+ EXT_GIC_ID_EXTINT12,
120
+ EXT_GIC_ID_EXTINT13,
121
+ EXT_GIC_ID_EXTINT14,
122
+ EXT_GIC_ID_EXTINT15
123
+};
124
+
125
+/*
126
+ * External GIC sources which are not from External Interrupt Combiner or
127
+ * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
128
+ * which is INTG16 in Internal Interrupt Combiner.
129
+ */
26
+ */
130
+
27
+static inline int arm_granule_bits(ARMGranuleSize gran)
131
+static const uint32_t
132
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
133
+ /* int combiner groups 16-19 */
134
+ { }, { }, { }, { },
135
+ /* int combiner group 20 */
136
+ { 0, EXT_GIC_ID_MDMA_LCD0 },
137
+ /* int combiner group 21 */
138
+ { EXT_GIC_ID_PDMA0, EXT_GIC_ID_PDMA1 },
139
+ /* int combiner group 22 */
140
+ { EXT_GIC_ID_TIMER0, EXT_GIC_ID_TIMER1, EXT_GIC_ID_TIMER2,
141
+ EXT_GIC_ID_TIMER3, EXT_GIC_ID_TIMER4 },
142
+ /* int combiner group 23 */
143
+ { EXT_GIC_ID_RTC_ALARM, EXT_GIC_ID_RTC_TIC },
144
+ /* int combiner group 24 */
145
+ { EXT_GIC_ID_GPIO_XB, EXT_GIC_ID_GPIO_XA },
146
+ /* int combiner group 25 */
147
+ { EXT_GIC_ID_IEM_APC, EXT_GIC_ID_IEM_IEC },
148
+ /* int combiner group 26 */
149
+ { EXT_GIC_ID_UART0, EXT_GIC_ID_UART1, EXT_GIC_ID_UART2, EXT_GIC_ID_UART3,
150
+ EXT_GIC_ID_UART4 },
151
+ /* int combiner group 27 */
152
+ { EXT_GIC_ID_I2C0, EXT_GIC_ID_I2C1, EXT_GIC_ID_I2C2, EXT_GIC_ID_I2C3,
153
+ EXT_GIC_ID_I2C4, EXT_GIC_ID_I2C5, EXT_GIC_ID_I2C6,
154
+ EXT_GIC_ID_I2C7 },
155
+ /* int combiner group 28 */
156
+ { EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 , EXT_GIC_ID_USB_HOST},
157
+ /* int combiner group 29 */
158
+ { EXT_GIC_ID_HSMMC0, EXT_GIC_ID_HSMMC1, EXT_GIC_ID_HSMMC2,
159
+ EXT_GIC_ID_HSMMC3, EXT_GIC_ID_SDMMC },
160
+ /* int combiner group 30 */
161
+ { EXT_GIC_ID_MIPI_CSI_4LANE, EXT_GIC_ID_MIPI_CSI_2LANE },
162
+ /* int combiner group 31 */
163
+ { EXT_GIC_ID_MIPI_DSI_4LANE, EXT_GIC_ID_MIPI_DSI_2LANE },
164
+ /* int combiner group 32 */
165
+ { EXT_GIC_ID_FIMC0, EXT_GIC_ID_FIMC1 },
166
+ /* int combiner group 33 */
167
+ { EXT_GIC_ID_FIMC2, EXT_GIC_ID_FIMC3 },
168
+ /* int combiner group 34 */
169
+ { EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
170
+ /* int combiner group 35 */
171
+ { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
172
+ /* int combiner group 36 */
173
+ { EXT_GIC_ID_MIXER },
174
+ /* int combiner group 37 */
175
+ { EXT_GIC_ID_EXTINT4, EXT_GIC_ID_EXTINT5, EXT_GIC_ID_EXTINT6,
176
+ EXT_GIC_ID_EXTINT7 },
177
+ /* groups 38-50 */
178
+ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
179
+ /* int combiner group 51 */
180
+ { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
181
+ /* group 52 */
182
+ { },
183
+ /* int combiner group 53 */
184
+ { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
185
+ /* groups 54-63 */
186
+ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
187
+};
188
+
189
+/*
190
+ * Initialize board IRQs.
191
+ * These IRQs contain splitted Int/External Combiner and External Gic IRQs.
192
+ */
193
+static void exynos4210_init_board_irqs(Exynos4210State *s)
194
+{
28
+{
195
+ uint32_t grp, bit, irq_id, n;
29
+ switch (gran) {
196
+ Exynos4210Irq *is = &s->irqs;
30
+ case Gran64K:
197
+
31
+ return 16;
198
+ for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
32
+ case Gran16K:
199
+ irq_id = 0;
33
+ return 14;
200
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
34
+ case Gran4K:
201
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
35
+ return 12;
202
+ /* MCT_G0 is passed to External GIC */
36
+ default:
203
+ irq_id = EXT_GIC_ID_MCT_G0;
37
+ g_assert_not_reached();
204
+ }
205
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
206
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
207
+ /* MCT_G1 is passed to External and GIC */
208
+ irq_id = EXT_GIC_ID_MCT_G1;
209
+ }
210
+ if (irq_id) {
211
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
212
+ is->ext_gic_irq[irq_id - 32]);
213
+ } else {
214
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
215
+ is->ext_combiner_irq[n]);
216
+ }
217
+ }
218
+ for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
219
+ /* these IDs are passed to Internal Combiner and External GIC */
220
+ grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
221
+ bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
222
+ irq_id = combiner_grp_to_gic_id[grp -
223
+ EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
224
+
225
+ if (irq_id) {
226
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
227
+ is->ext_gic_irq[irq_id - 32]);
228
+ }
229
+ }
38
+ }
230
+}
39
+}
231
+
40
+
232
+/*
41
/*
233
+ * Get IRQ number from exynos4210 IRQ subsystem stub.
42
* Parameters of a given virtual address, as extracted from the
234
+ * To identify IRQ source use internal combiner group and bit number
43
* translation control register (TCR) for a given regime.
235
+ * grp - group number
44
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
236
+ * bit - bit number inside group
45
bool tbi : 1;
237
+ */
46
bool epd : 1;
238
+uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
47
bool hpd : 1;
48
- bool using16k : 1;
49
- bool using64k : 1;
50
bool tsz_oob : 1; /* tsz has been clamped to legal range */
51
bool ds : 1;
52
+ ARMGranuleSize gran : 2;
53
} ARMVAParameters;
54
55
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
56
diff --git a/target/arm/helper.c b/target/arm/helper.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/helper.c
59
+++ b/target/arm/helper.c
60
@@ -XXX,XX +XXX,XX @@ typedef struct {
61
uint64_t length;
62
} TLBIRange;
63
64
+static ARMGranuleSize tlbi_range_tg_to_gran_size(int tg)
239
+{
65
+{
240
+ return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
66
+ /*
67
+ * Note that the TLBI range TG field encoding differs from both
68
+ * TG0 and TG1 encodings.
69
+ */
70
+ switch (tg) {
71
+ case 1:
72
+ return Gran4K;
73
+ case 2:
74
+ return Gran16K;
75
+ case 3:
76
+ return Gran64K;
77
+ default:
78
+ return GranInvalid;
79
+ }
241
+}
80
+}
242
+
81
+
243
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
82
static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
244
0x09, 0x00, 0x00, 0x00 };
83
uint64_t value)
245
84
{
246
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
85
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
86
uint64_t select = sextract64(value, 36, 1);
87
ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true);
88
TLBIRange ret = { };
89
+ ARMGranuleSize gran;
90
91
page_size_granule = extract64(value, 46, 2);
92
+ gran = tlbi_range_tg_to_gran_size(page_size_granule);
93
94
/* The granule encoded in value must match the granule in use. */
95
- if (page_size_granule != (param.using64k ? 3 : param.using16k ? 2 : 1)) {
96
+ if (gran != param.gran) {
97
qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n",
98
page_size_granule);
99
return ret;
100
}
101
102
- page_shift = (page_size_granule - 1) * 2 + 12;
103
+ page_shift = arm_granule_bits(gran);
104
num = extract64(value, 39, 5);
105
scale = extract64(value, 44, 2);
106
exponent = (5 * scale) + 1;
107
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
108
ARMMMUIdx mmu_idx, bool data)
109
{
110
uint64_t tcr = regime_tcr(env, mmu_idx);
111
- bool epd, hpd, using16k, using64k, tsz_oob, ds;
112
+ bool epd, hpd, tsz_oob, ds;
113
int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
114
ARMGranuleSize gran;
115
ARMCPU *cpu = env_archcpu(env);
116
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
117
}
118
119
gran = sanitize_gran_size(cpu, gran, stage2);
120
- using64k = gran == Gran64K;
121
- using16k = gran == Gran16K;
122
123
if (cpu_isar_feature(aa64_st, cpu)) {
124
- max_tsz = 48 - using64k;
125
+ max_tsz = 48 - (gran == Gran64K);
126
} else {
127
max_tsz = 39;
128
}
129
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
130
* adjust the effective value of DS, as documented.
131
*/
132
min_tsz = 16;
133
- if (using64k) {
134
+ if (gran == Gran64K) {
135
if (cpu_isar_feature(aa64_lva, cpu)) {
136
min_tsz = 12;
137
}
138
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
139
switch (mmu_idx) {
140
case ARMMMUIdx_Stage2:
141
case ARMMMUIdx_Stage2_S:
142
- if (using16k) {
143
+ if (gran == Gran16K) {
144
ds = cpu_isar_feature(aa64_tgran16_2_lpa2, cpu);
145
} else {
146
ds = cpu_isar_feature(aa64_tgran4_2_lpa2, cpu);
147
}
148
break;
149
default:
150
- if (using16k) {
151
+ if (gran == Gran16K) {
152
ds = cpu_isar_feature(aa64_tgran16_lpa2, cpu);
153
} else {
154
ds = cpu_isar_feature(aa64_tgran4_lpa2, cpu);
155
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
156
.tbi = tbi,
157
.epd = epd,
158
.hpd = hpd,
159
- .using16k = using16k,
160
- .using64k = using64k,
161
.tsz_oob = tsz_oob,
162
.ds = ds,
163
+ .gran = gran,
164
};
165
}
166
167
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
247
index XXXXXXX..XXXXXXX 100644
168
index XXXXXXX..XXXXXXX 100644
248
--- a/hw/intc/exynos4210_gic.c
169
--- a/target/arm/ptw.c
249
+++ b/hw/intc/exynos4210_gic.c
170
+++ b/target/arm/ptw.c
250
@@ -XXX,XX +XXX,XX @@
171
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
251
#include "hw/arm/exynos4210.h"
172
}
252
#include "qom/object.h"
173
}
253
174
254
-enum ExtGicId {
175
- if (param.using64k) {
255
- EXT_GIC_ID_MDMA_LCD0 = 66,
176
- stride = 13;
256
- EXT_GIC_ID_PDMA0,
177
- } else if (param.using16k) {
257
- EXT_GIC_ID_PDMA1,
178
- stride = 11;
258
- EXT_GIC_ID_TIMER0,
179
- } else {
259
- EXT_GIC_ID_TIMER1,
180
- stride = 9;
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
- }
181
- }
438
- for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
182
+ stride = arm_granule_bits(param.gran) - 3;
439
- /* these IDs are passed to Internal Combiner and External GIC */
183
440
- grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
184
/*
441
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
185
* Note that QEMU ignores shareability and cacheability attributes,
442
- irq_id = combiner_grp_to_gic_id[grp -
443
- EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
444
-
445
- if (irq_id) {
446
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
447
- is->ext_gic_irq[irq_id - 32]);
448
- }
449
- }
450
-}
451
-
452
-/*
453
- * Get IRQ number from exynos4210 IRQ subsystem stub.
454
- * To identify IRQ source use internal combiner group and bit number
455
- * grp - group number
456
- * bit - bit number inside group
457
- */
458
-uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
459
-{
460
- return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
461
-}
462
-
463
-/********* GIC part *********/
464
-
465
#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
466
OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
467
468
--
186
--
469
2.25.1
187
2.25.1
diff view generated by jsdifflib
Deleted patch
1
The only time we use the ext_gic_irq[] array in the Exynos4210Irq
2
struct is during realize of the SoC -- we initialize it with the
3
input IRQs of the external GIC device, and then connect those to
4
outputs of other devices further on in realize (including in the
5
exynos4210_init_board_irqs() function). Now that the ext_gic object
6
is easily accessible as s->ext_gic we can make the connections
7
directly from one device to the other without going via this array.
8
1
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-10-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 1 -
14
hw/arm/exynos4210.c | 12 ++++++------
15
2 files changed, 6 insertions(+), 7 deletions(-)
16
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
20
+++ b/include/hw/arm/exynos4210.h
21
@@ -XXX,XX +XXX,XX @@
22
typedef struct Exynos4210Irq {
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
25
- qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
26
} Exynos4210Irq;
27
28
struct Exynos4210State {
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
32
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
34
{
35
uint32_t grp, bit, irq_id, n;
36
Exynos4210Irq *is = &s->irqs;
37
+ DeviceState *extgicdev = DEVICE(&s->ext_gic);
38
39
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
40
irq_id = 0;
41
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
42
}
43
if (irq_id) {
44
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
45
- is->ext_gic_irq[irq_id - 32]);
46
+ qdev_get_gpio_in(extgicdev,
47
+ irq_id - 32));
48
} else {
49
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
50
is->ext_combiner_irq[n]);
51
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
52
53
if (irq_id) {
54
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
55
- is->ext_gic_irq[irq_id - 32]);
56
+ qdev_get_gpio_in(extgicdev,
57
+ irq_id - 32));
58
}
59
}
60
}
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
62
sysbus_connect_irq(busdev, n,
63
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
64
}
65
- for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
66
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
67
- }
68
69
/* Internal Interrupt Combiner */
70
dev = qdev_new("exynos4210.combiner");
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
72
busdev = SYS_BUS_DEVICE(dev);
73
sysbus_realize_and_unref(busdev, &error_fatal);
74
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
75
- sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]);
76
+ sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
77
}
78
exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
79
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
80
--
81
2.25.1
diff view generated by jsdifflib
1
Delete a couple of #defines which are never used.
1
FEAT_GTG is a change tho the ID register ID_AA64MMFR0_EL1 so that it
2
can report a different set of supported granule (page) sizes for
3
stage 1 and stage 2 translation tables. As of commit c20281b2a5048
4
we already report the granule sizes that way for '-cpu max', and now
5
we also correctly make attempts to use unimplemented granule sizes
6
fail, so we can report the support of the feature in the
7
documentation.
2
8
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20221003162315.2833797-4-peter.maydell@linaro.org
5
Message-id: 20220404154658.565020-12-peter.maydell@linaro.org
6
---
12
---
7
include/hw/arm/exynos4210.h | 4 ----
13
docs/system/arm/emulation.rst | 1 +
8
1 file changed, 4 deletions(-)
14
1 file changed, 1 insertion(+)
9
15
10
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
16
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
11
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
12
--- a/include/hw/arm/exynos4210.h
18
--- a/docs/system/arm/emulation.rst
13
+++ b/include/hw/arm/exynos4210.h
19
+++ b/docs/system/arm/emulation.rst
14
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
15
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
21
- FEAT_FRINTTS (Floating-point to integer instructions)
16
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
22
- FEAT_FlagM (Flag manipulation instructions v2)
17
23
- FEAT_FlagM2 (Enhancements to flag manipulation instructions)
18
-/* IRQs number for external and internal GIC */
24
+- FEAT_GTG (Guest translation granule size)
19
-#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
25
- FEAT_HCX (Support for the HCRX_EL2 register)
20
-#define EXYNOS4210_INT_GIC_NIRQ 64
26
- FEAT_HPDS (Hierarchical permission disables)
21
-
27
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
22
#define EXYNOS4210_I2C_NUMBER 9
23
24
#define EXYNOS4210_NUM_DMA 3
25
--
28
--
26
2.25.1
29
2.25.1
diff view generated by jsdifflib